Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d321e66be1 | ||
|
|
6abb99ddeb |
No files matched your search
+13
-143
@@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2026. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; AMD PCnet driver for KolibriOS ;;
|
||||
@@ -31,11 +31,6 @@ entry START
|
||||
TX_RING_SIZE = 32 ; Number of packets in send ring buffer
|
||||
RX_RING_SIZE = 32 ; Number of packets in receive ring buffer
|
||||
|
||||
; pending transmit queue, used when frames arrive while hardware is busy
|
||||
PENDING_TX_MAX = 8 ; Maximum number of frames in the queue
|
||||
PENDING_TX_LOWAT = 0 ; Low-water mark for the number of frames in the queue, before resetting the NET_TX_BLOCKED flag
|
||||
|
||||
|
||||
; end configureable area
|
||||
|
||||
section '.flat' readable writable executable
|
||||
@@ -321,11 +316,6 @@ struct device ETH_DEVICE
|
||||
cur_tx dd ?
|
||||
last_tx dd ?
|
||||
|
||||
; pending transmit queue: linked list of frames that arrived while the hardware was busy
|
||||
pend_tx_head dd ? ; pointer to oldest queued NET_BUFF, 0 if empty
|
||||
pend_tx_tail dd ? ; pointer to newest queued NET_BUFF, 0 if empty
|
||||
pend_tx_count dd ? ; 0..PENDING_TX_MAX
|
||||
|
||||
options dd ?
|
||||
full_duplex db ?
|
||||
chip_version dw ?
|
||||
@@ -1010,21 +1000,6 @@ init_ring:
|
||||
mov [ebx + device.last_tx], 0
|
||||
mov [ebx + device.cur_rx], 0
|
||||
|
||||
mov esi, [ebx + device.pend_tx_head]
|
||||
.drain_pending:
|
||||
test esi, esi
|
||||
jz .pending_drained
|
||||
mov eax, [esi + NET_BUFF.NextPtr]
|
||||
push eax
|
||||
invoke NetFree, esi
|
||||
pop eax
|
||||
mov esi, eax
|
||||
jmp .drain_pending
|
||||
.pending_drained:
|
||||
mov dword [ebx + device.pend_tx_head], 0
|
||||
mov dword [ebx + device.pend_tx_tail], 0
|
||||
mov dword [ebx + device.pend_tx_count], 0
|
||||
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
@@ -1070,9 +1045,6 @@ proc transmit stdcall bufferptr
|
||||
|
||||
test [edi + descriptor.status], TXCTL_OWN
|
||||
jnz .overrun
|
||||
cmp [edi + descriptor.virtual], 0 ; Make sure int handler has performed cleanup already
|
||||
jne .desc_busy
|
||||
.desc_free:
|
||||
; descriptor is free, use it
|
||||
mov [edi + descriptor.virtual], esi
|
||||
mov eax, esi
|
||||
@@ -1086,12 +1058,6 @@ proc transmit stdcall bufferptr
|
||||
; put to transfer queue
|
||||
mov [edi + descriptor.status], TXCTL_OWN + TXCTL_STP + TXCTL_ENP
|
||||
|
||||
; Update stats
|
||||
inc [ebx + device.packets_tx]
|
||||
mov eax, [esi + NET_BUFF.length]
|
||||
add dword[ebx + device.bytes_tx], eax
|
||||
adc dword[ebx + device.bytes_tx + 4], 0
|
||||
|
||||
; trigger an immediate send
|
||||
mov edx, [ebx + device.io_addr]
|
||||
xor ecx, ecx ; CSR0
|
||||
@@ -1103,16 +1069,16 @@ proc transmit stdcall bufferptr
|
||||
inc [ebx + device.cur_tx]
|
||||
and [ebx + device.cur_tx], TX_RING_SIZE - 1
|
||||
|
||||
; Update stats
|
||||
inc [ebx + device.packets_tx]
|
||||
mov eax, [esi + NET_BUFF.length]
|
||||
add dword[ebx + device.bytes_tx], eax
|
||||
adc dword[ebx + device.bytes_tx + 4], 0
|
||||
|
||||
spin_unlock_irqrestore
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.desc_busy:
|
||||
pusha ; TODO CHECKME
|
||||
invoke NetFree, [edi + descriptor.virtual]
|
||||
popa
|
||||
jmp .desc_free
|
||||
|
||||
.error:
|
||||
DEBUGF 2, "TX packet error\n"
|
||||
inc [ebx + device.packets_tx_err]
|
||||
@@ -1123,40 +1089,12 @@ proc transmit stdcall bufferptr
|
||||
ret
|
||||
|
||||
.overrun:
|
||||
; Hardware ring is full.
|
||||
DEBUGF 1, "High water\n"
|
||||
or [ebx + device.state], NET_TX_BLOCKED
|
||||
|
||||
; Try the pending tx queue as a last resort
|
||||
cmp [ebx + device.pend_tx_count], PENDING_TX_MAX
|
||||
jae .queue_full
|
||||
|
||||
mov dword [esi + NET_BUFF.NextPtr], 0
|
||||
mov dword [esi + NET_BUFF.PrevPtr], 0
|
||||
mov eax, [ebx + device.pend_tx_tail]
|
||||
mov [ebx + device.pend_tx_tail], esi
|
||||
test eax, eax
|
||||
jz @f
|
||||
mov [eax + NET_BUFF.NextPtr], esi
|
||||
jmp .list_linked
|
||||
@@:
|
||||
mov [ebx + device.pend_tx_head], esi
|
||||
.list_linked:
|
||||
inc [ebx + device.pend_tx_count]
|
||||
DEBUGF 1, "Pending TX: %u\n", [ebx + device.pend_tx_count]
|
||||
|
||||
spin_unlock_irqrestore
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
.queue_full:
|
||||
DEBUGF 2, "TX overrun\n"
|
||||
inc [ebx + device.packets_tx_ovr]
|
||||
invoke NetFree, [bufferptr]
|
||||
|
||||
spin_unlock_irqrestore
|
||||
or eax, -1
|
||||
dec eax
|
||||
ret
|
||||
|
||||
endp
|
||||
@@ -1287,20 +1225,20 @@ int_handler:
|
||||
jz .not_transmit
|
||||
|
||||
.tx_loop:
|
||||
mov eax, [ebx + device.last_tx]
|
||||
|
||||
lea edi, [ebx + device.tx_ring]
|
||||
mov eax, [ebx + device.last_tx]
|
||||
shl eax, 4
|
||||
add edi, eax
|
||||
|
||||
test [edi + descriptor.status], TXCTL_OWN
|
||||
jnz .tx_done ; still busy
|
||||
jnz .not_transmit
|
||||
|
||||
mov eax, [edi + descriptor.virtual]
|
||||
test eax, eax
|
||||
jz .tx_done ; never filled, or already reclaimed
|
||||
jz .not_transmit
|
||||
|
||||
mov [edi + descriptor.virtual], 0
|
||||
|
||||
DEBUGF 1,"Removing packet %x from memory\n", eax
|
||||
|
||||
invoke NetFree, eax
|
||||
@@ -1309,10 +1247,6 @@ int_handler:
|
||||
and [ebx + device.last_tx], TX_RING_SIZE - 1
|
||||
jmp .tx_loop
|
||||
|
||||
.tx_done:
|
||||
cmp [ebx + device.pend_tx_count], 0
|
||||
jne .refill_loop
|
||||
|
||||
.not_transmit:
|
||||
pop edi esi ebx
|
||||
xor eax, eax
|
||||
@@ -1320,70 +1254,6 @@ int_handler:
|
||||
|
||||
ret
|
||||
|
||||
.refill_loop:
|
||||
mov ecx, [ebx + device.cur_tx]
|
||||
shl ecx, 4
|
||||
lea edi, [ebx + device.tx_ring]
|
||||
add edi, ecx
|
||||
|
||||
test [edi + descriptor.status], TXCTL_OWN
|
||||
jnz .refill_done ; not actually free after all - stop
|
||||
|
||||
cmp [edi + descriptor.virtual], 0
|
||||
je @f
|
||||
pusha
|
||||
invoke NetFree, [edi + descriptor.virtual]
|
||||
popa
|
||||
@@:
|
||||
|
||||
mov esi, [ebx + device.pend_tx_head]
|
||||
mov eax, [esi + NET_BUFF.NextPtr]
|
||||
mov [ebx + device.pend_tx_head], eax
|
||||
|
||||
mov [edi + descriptor.virtual], esi
|
||||
mov eax, esi
|
||||
add eax, [eax + NET_BUFF.offset]
|
||||
invoke GetPhysAddr
|
||||
mov [edi + descriptor.base], eax
|
||||
|
||||
mov eax, [esi + NET_BUFF.length]
|
||||
neg eax
|
||||
mov [edi + descriptor.length], ax
|
||||
|
||||
mov [edi + descriptor.status], TXCTL_OWN + TXCTL_STP + TXCTL_ENP
|
||||
|
||||
inc [ebx + device.packets_tx]
|
||||
mov eax, [esi + NET_BUFF.length]
|
||||
add dword[ebx + device.bytes_tx], eax
|
||||
adc dword[ebx + device.bytes_tx + 4], 0
|
||||
|
||||
inc [ebx + device.cur_tx]
|
||||
and [ebx + device.cur_tx], TX_RING_SIZE - 1
|
||||
|
||||
dec [ebx + device.pend_tx_count]
|
||||
jnz .refill_loop
|
||||
|
||||
mov dword [ebx + device.pend_tx_tail], 0
|
||||
|
||||
.refill_done:
|
||||
DEBUGF 1, "Pending TX: %u\n", [ebx + device.pend_tx_count]
|
||||
|
||||
mov edx, [ebx + device.io_addr]
|
||||
xor ecx, ecx ; CSR0
|
||||
call [ebx + device.read_csr]
|
||||
or eax, CSR_TX
|
||||
call [ebx + device.write_csr]
|
||||
|
||||
cmp [ebx + device.pend_tx_count], PENDING_TX_LOWAT
|
||||
ja @f
|
||||
and [ebx + device.state], not NET_TX_BLOCKED
|
||||
DEBUGF 1, "Low water\n"
|
||||
@@:
|
||||
pop edi esi ebx
|
||||
xor eax, eax
|
||||
inc eax
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
@@ -1725,7 +1595,7 @@ proc check_media_mii stdcall dev:dword
|
||||
mov ecx, eax
|
||||
and eax, BMSR_LSTATUS
|
||||
shr eax, 2
|
||||
cmp ax, word[ebx + device.state] ; lazy masking of NET_TX_BLOCKED
|
||||
cmp eax, [ebx + device.state]
|
||||
jne .changed
|
||||
|
||||
spin_unlock_irqrestore
|
||||
@@ -1773,7 +1643,7 @@ proc check_media_mii stdcall dev:dword
|
||||
mov eax, ETH_LINK_UNKNOWN
|
||||
|
||||
.update:
|
||||
mov word[ebx + device.state], ax ; lazy masking of NET_TX_BLOCKED
|
||||
mov [ebx + device.state], eax
|
||||
invoke NetLinkChanged
|
||||
|
||||
|
||||
|
||||
+154
-158
@@ -1,158 +1,154 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2021. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||
;; Version 2, June 1991 ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; This macro will prepend driver name to all debug output through DEBUGF macro
|
||||
; The driver name is taken from my_service label
|
||||
|
||||
if defined my_service
|
||||
|
||||
macro DEBUGF _level,_format, [args] {
|
||||
common DEBUGF _level, "%s: " # _format, my_service, args
|
||||
}
|
||||
|
||||
end if
|
||||
|
||||
include 'pci.inc'
|
||||
include 'mii.inc'
|
||||
|
||||
; Kernel variables
|
||||
|
||||
PAGESIZE = 4096
|
||||
|
||||
; Network driver types
|
||||
|
||||
NET_TYPE_ETH = 1
|
||||
NET_TYPE_SLIP = 2
|
||||
|
||||
; Link state
|
||||
|
||||
ETH_LINK_DOWN = 0 ; Link is down
|
||||
ETH_LINK_UNKNOWN = 1b ; Link is up, but speed might be unknown
|
||||
ETH_LINK_FULL_DUPLEX = 10b ; full duplex flag
|
||||
|
||||
ETH_LINK_SPEED_10M = 100b ; 10 Mbit
|
||||
ETH_LINK_SPEED_100M = 1000b ; 100 Mbit
|
||||
ETH_LINK_SPEED_1G = 1100b ; Gigabit
|
||||
|
||||
ETH_LINK_SPEED_MASK = 1100b
|
||||
|
||||
; Hardware state
|
||||
|
||||
NET_TX_BLOCKED = 1 shl 31 ; Transmit queue is full, if you call transmit again, driver might drop your frame
|
||||
|
||||
; Macro to easily set i/o addresses to access device.
|
||||
; In the beginning of a procedure (or ofter edx may have been destroyed),
|
||||
; always use set_io with offset 0 to reset the variables.
|
||||
|
||||
LAST_IO = 0
|
||||
|
||||
macro set_io baseaddr, offset {
|
||||
|
||||
if offset = 0
|
||||
mov edx, baseaddr
|
||||
else if offset = LAST_IO
|
||||
else
|
||||
add edx, offset - LAST_IO
|
||||
end if
|
||||
|
||||
LAST_IO = offset
|
||||
}
|
||||
|
||||
; Macro to allocate a contiguous buffer in memory
|
||||
; And initialise it to all zeros
|
||||
|
||||
; This macro will destroy eax, ecx and edi !
|
||||
|
||||
macro allocate_and_clear dest, size, err {
|
||||
|
||||
; We need to allocate at least 8 pages, if we want a contiguous area in ram
|
||||
push edx
|
||||
if (size < 8*4096) & (size > 4096)
|
||||
invoke KernelAlloc, 8*4096
|
||||
else
|
||||
invoke KernelAlloc, size
|
||||
end if
|
||||
pop edx
|
||||
|
||||
test eax, eax
|
||||
jz err
|
||||
mov dest, eax
|
||||
mov edi, eax ; look at last part of code!
|
||||
|
||||
; Release the unused pages (if any)
|
||||
if (size < 8*4096) & (size > 4096)
|
||||
add eax, (size/4096+1)*4096
|
||||
mov ecx, 8-(size/4096+1)
|
||||
push edx
|
||||
invoke ReleasePages
|
||||
pop edx
|
||||
end if
|
||||
|
||||
; Clear the allocated buffer
|
||||
mov ecx, size/4 ; divide by 4 because of DWORD
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
|
||||
if (size - size/4*4)
|
||||
mov ecx, size - size/4*4
|
||||
rep stosb
|
||||
end if
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct NET_DEVICE
|
||||
|
||||
type dd ? ; Type field
|
||||
mtu dd ? ; Maximal Transmission Unit
|
||||
name dd ? ; Ptr to 0 terminated string
|
||||
|
||||
unload dd ? ; Ptrs to driver functions
|
||||
reset dd ? ;
|
||||
transmit dd ? ;
|
||||
|
||||
state dd ? ; link state (0 = no link)
|
||||
hwacc dd ? ; bitmask stating enabled HW accelerations (offload engines)
|
||||
|
||||
bytes_tx dq ? ; Statistics, updated by the driver
|
||||
bytes_rx dq ? ;
|
||||
|
||||
packets_tx dd ? ;
|
||||
packets_tx_err dd ? ; CRC errors, too long or too short frames
|
||||
packets_tx_drop dd ? ;
|
||||
packets_tx_ovr dd ? ; FIFO overrun
|
||||
|
||||
packets_rx dd ? ;
|
||||
packets_rx_err dd ? ; CRC errors, too long or too short frames
|
||||
packets_rx_drop dd ? ;
|
||||
packets_rx_ovr dd ? ; FIFO overrun
|
||||
|
||||
ends
|
||||
|
||||
|
||||
struct NET_BUFF
|
||||
|
||||
NextPtr dd ? ; pointer to next frame in list
|
||||
PrevPtr dd ? ; pointer to previous frame in list
|
||||
device dd ? ; ptr to NET_DEVICE structure
|
||||
type dd ? ; data type (e.g. Ethernet)
|
||||
length dd ? ; data length
|
||||
offset dd ? ; offset to actual data (24 bytes for default frame)
|
||||
data rb 0
|
||||
|
||||
ends
|
||||
|
||||
|
||||
struct ETH_DEVICE NET_DEVICE
|
||||
|
||||
mac dp ?
|
||||
dw ? ; qword alignment
|
||||
|
||||
ends
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2021. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; GNU GENERAL PUBLIC LICENSE ;;
|
||||
;; Version 2, June 1991 ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
; This macro will prepend driver name to all debug output through DEBUGF macro
|
||||
; The driver name is taken from my_service label
|
||||
|
||||
if defined my_service
|
||||
|
||||
macro DEBUGF _level,_format, [args] {
|
||||
common DEBUGF _level, "%s: " # _format, my_service, args
|
||||
}
|
||||
|
||||
end if
|
||||
|
||||
include 'pci.inc'
|
||||
include 'mii.inc'
|
||||
|
||||
; Kernel variables
|
||||
|
||||
PAGESIZE = 4096
|
||||
|
||||
; Network driver types
|
||||
|
||||
NET_TYPE_ETH = 1
|
||||
NET_TYPE_SLIP = 2
|
||||
|
||||
; Link state
|
||||
|
||||
ETH_LINK_DOWN = 0 ; Link is down
|
||||
ETH_LINK_UNKNOWN = 1b ; There could be an active link
|
||||
ETH_LINK_FULL_DUPLEX = 10b ; full duplex flag
|
||||
|
||||
ETH_LINK_SPEED_10M = 100b ; 10 Mbit
|
||||
ETH_LINK_SPEED_100M = 1000b ; 100 Mbit
|
||||
ETH_LINK_SPEED_1G = 1100b ; Gigabit
|
||||
|
||||
ETH_LINK_SPEED_MASK = 1100b
|
||||
|
||||
; Macro to easily set i/o addresses to access device.
|
||||
; In the beginning of a procedure (or ofter edx may have been destroyed),
|
||||
; always use set_io with offset 0 to reset the variables.
|
||||
|
||||
LAST_IO = 0
|
||||
|
||||
macro set_io baseaddr, offset {
|
||||
|
||||
if offset = 0
|
||||
mov edx, baseaddr
|
||||
else if offset = LAST_IO
|
||||
else
|
||||
add edx, offset - LAST_IO
|
||||
end if
|
||||
|
||||
LAST_IO = offset
|
||||
}
|
||||
|
||||
; Macro to allocate a contiguous buffer in memory
|
||||
; And initialise it to all zeros
|
||||
|
||||
; This macro will destroy eax, ecx and edi !
|
||||
|
||||
macro allocate_and_clear dest, size, err {
|
||||
|
||||
; We need to allocate at least 8 pages, if we want a contiguous area in ram
|
||||
push edx
|
||||
if (size < 8*4096) & (size > 4096)
|
||||
invoke KernelAlloc, 8*4096
|
||||
else
|
||||
invoke KernelAlloc, size
|
||||
end if
|
||||
pop edx
|
||||
|
||||
test eax, eax
|
||||
jz err
|
||||
mov dest, eax
|
||||
mov edi, eax ; look at last part of code!
|
||||
|
||||
; Release the unused pages (if any)
|
||||
if (size < 8*4096) & (size > 4096)
|
||||
add eax, (size/4096+1)*4096
|
||||
mov ecx, 8-(size/4096+1)
|
||||
push edx
|
||||
invoke ReleasePages
|
||||
pop edx
|
||||
end if
|
||||
|
||||
; Clear the allocated buffer
|
||||
mov ecx, size/4 ; divide by 4 because of DWORD
|
||||
xor eax, eax
|
||||
rep stosd
|
||||
|
||||
if (size - size/4*4)
|
||||
mov ecx, size - size/4*4
|
||||
rep stosb
|
||||
end if
|
||||
|
||||
}
|
||||
|
||||
|
||||
struct NET_DEVICE
|
||||
|
||||
type dd ? ; Type field
|
||||
mtu dd ? ; Maximal Transmission Unit
|
||||
name dd ? ; Ptr to 0 terminated string
|
||||
|
||||
unload dd ? ; Ptrs to driver functions
|
||||
reset dd ? ;
|
||||
transmit dd ? ;
|
||||
|
||||
state dd ? ; link state (0 = no link)
|
||||
hwacc dd ? ; bitmask stating enabled HW accelerations (offload engines)
|
||||
|
||||
bytes_tx dq ? ; Statistics, updated by the driver
|
||||
bytes_rx dq ? ;
|
||||
|
||||
packets_tx dd ? ;
|
||||
packets_tx_err dd ? ; CRC errors, too long or too short frames
|
||||
packets_tx_drop dd ? ;
|
||||
packets_tx_ovr dd ? ; FIFO overrun
|
||||
|
||||
packets_rx dd ? ;
|
||||
packets_rx_err dd ? ; CRC errors, too long or too short frames
|
||||
packets_rx_drop dd ? ;
|
||||
packets_rx_ovr dd ? ; FIFO overrun
|
||||
|
||||
ends
|
||||
|
||||
|
||||
struct NET_BUFF
|
||||
|
||||
NextPtr dd ? ; pointer to next frame in list
|
||||
PrevPtr dd ? ; pointer to previous frame in list
|
||||
device dd ? ; ptr to NET_DEVICE structure
|
||||
type dd ? ; data type (e.g. Ethernet)
|
||||
length dd ? ; data length
|
||||
offset dd ? ; offset to actual data (24 bytes for default frame)
|
||||
data rb 0
|
||||
|
||||
ends
|
||||
|
||||
|
||||
struct ETH_DEVICE NET_DEVICE
|
||||
|
||||
mac dp ?
|
||||
dw ? ; qword alignment
|
||||
|
||||
ends
|
||||
@@ -12,13 +12,6 @@
|
||||
; Source code author - Kulakov Vladimir Gennadievich.
|
||||
; Adaptation and improvement - Mario79.
|
||||
|
||||
give_back_application_data_1:
|
||||
mov esi, FDD_BUFF;FDD_DataBuffer ;0x40000
|
||||
mov ecx, 128
|
||||
cld
|
||||
rep movsd
|
||||
ret
|
||||
|
||||
take_data_from_application_1:
|
||||
mov edi, FDD_BUFF;FDD_DataBuffer ;0x40000
|
||||
mov ecx, 128
|
||||
@@ -717,18 +710,38 @@ endg
|
||||
; This function is called in boot process.
|
||||
; It creates filesystems /fd and/or /fd2, if the system has one/two floppy drives.
|
||||
proc floppy_init
|
||||
; search for FDDs and add them to the list of disks
|
||||
; author - Mario79
|
||||
mov al, 0x10
|
||||
out 0x70, al
|
||||
mov cx, 0xff
|
||||
.wait_cmos:
|
||||
dec cx
|
||||
test cx, cx
|
||||
jnz .wait_cmos
|
||||
in al, 0x71
|
||||
test al, al
|
||||
jz .no_fdd
|
||||
|
||||
push eax ; b[esp]=al [esp+1..3]- ??
|
||||
|
||||
stdcall attach_int_handler, 6, FDCInterrupt, 0
|
||||
DEBUGF 1, "K : Set Floppy IRQ6 return code %x\n", eax
|
||||
|
||||
mov ecx, floppy_mutex
|
||||
call mutex_init
|
||||
; First floppy is present if [DRIVE_DATA] and 0xF0 is nonzero.
|
||||
test byte [DRIVE_DATA], 0xF0
|
||||
; First floppy is present if [esp] and 0xF0 is nonzero.
|
||||
test byte [esp], 0xF0
|
||||
jz .no1
|
||||
stdcall disk_add, floppy_functions, floppy1_name, 1, DISK_NO_INSERT_NOTIFICATION
|
||||
.no1:
|
||||
; Second floppy is present if [DRIVE_DATA] and 0x0F is nonzero.
|
||||
test byte [DRIVE_DATA], 0x0F
|
||||
; Second floppy is present if [esp] and 0x0F is nonzero.
|
||||
test byte [esp], 0x0F
|
||||
jz .no2
|
||||
stdcall disk_add, floppy_functions, floppy2_name, 2, DISK_NO_INSERT_NOTIFICATION
|
||||
.no2:
|
||||
add esp, 4
|
||||
.no_fdd:
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
@@ -878,37 +878,6 @@ struct PCIDEV
|
||||
owner dd ? ; pointer to SRV or 0
|
||||
ends
|
||||
|
||||
struct IDE_DATA
|
||||
ProgrammingInterface dd ?
|
||||
Interrupt dw ?
|
||||
RegsBaseAddres dw ?
|
||||
BAR0_val dw ?
|
||||
BAR1_val dw ?
|
||||
BAR2_val dw ?
|
||||
BAR3_val dw ?
|
||||
dma_hdd_channel_1 db ?
|
||||
dma_hdd_channel_2 db ?
|
||||
pcidev dd ? ; pointer to corresponding PCIDEV structure
|
||||
ends
|
||||
|
||||
struct IDE_CACHE
|
||||
pointer dd ?
|
||||
size dd ? ; not use
|
||||
data_pointer dd ?
|
||||
system_data_size dd ? ; not use
|
||||
appl_data_size dd ? ; not use
|
||||
system_data dd ?
|
||||
appl_data dd ?
|
||||
system_sad_size dd ?
|
||||
appl_sad_size dd ?
|
||||
search_start dd ?
|
||||
appl_search_start dd ?
|
||||
ends
|
||||
|
||||
struct IDE_DEVICE
|
||||
UDMA_possible_modes db ?
|
||||
UDMA_set_mode db ?
|
||||
ends
|
||||
|
||||
; The following macro assume that we are on uniprocessor machine.
|
||||
; Serious work is needed for multiprocessor machines.
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
;***************************************************
|
||||
; clear the DRIVE_DATA table,
|
||||
; search for FDDs and add them into the table
|
||||
; author - Mario79
|
||||
;***************************************************
|
||||
xor eax, eax
|
||||
mov edi, DRIVE_DATA
|
||||
mov ecx, DRIVE_DATA_SIZE/4
|
||||
cld
|
||||
rep stosd
|
||||
|
||||
mov al, 0x10
|
||||
out 0x70, al
|
||||
mov cx, 0xff
|
||||
wait_cmos:
|
||||
dec cx
|
||||
test cx, cx
|
||||
jnz wait_cmos
|
||||
in al, 0x71
|
||||
mov [DRIVE_DATA], al
|
||||
test al, al
|
||||
jz @f
|
||||
|
||||
stdcall attach_int_handler, 6, FDCInterrupt, 0
|
||||
DEBUGF 1, "K : Set IDE IRQ6 return code %x\n", eax
|
||||
call floppy_init
|
||||
@@:
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
|
||||
include 'dev_fd.inc'
|
||||
include 'dev_hdcd.inc'
|
||||
include 'getcache.inc'
|
||||
include 'sear_par.inc'
|
||||
|
||||
+690
-335
File diff suppressed because it is too large.
Load diff
@@ -754,7 +754,7 @@ end if
|
||||
;-----------------------------------------------------------------------------
|
||||
mov esi, boot_detectfloppy
|
||||
call boot_log
|
||||
include 'detect/dev_fd.inc'
|
||||
call floppy_init
|
||||
;-----------------------------------------------------------------------------
|
||||
; create pci-devices list
|
||||
;-----------------------------------------------------------------------------
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2026. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; Part of the TCP/IP network stack for KolibriOS ;;
|
||||
@@ -1034,9 +1034,6 @@ socket_send:
|
||||
test eax, eax
|
||||
jz .invalid
|
||||
|
||||
test esi, esi
|
||||
jz .zero_length
|
||||
|
||||
stdcall is_region_userspace, edx, esi
|
||||
jnz .invalid
|
||||
|
||||
@@ -1050,10 +1047,6 @@ socket_send:
|
||||
mov dword[esp + SYSCALL_STACK.eax], -1
|
||||
ret
|
||||
|
||||
.zero_length:
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "SOCKET_send: data length = 0\n"
|
||||
mov dword[esp + SYSCALL_STACK.eax], 0
|
||||
ret
|
||||
|
||||
align 4
|
||||
socket_send_udp:
|
||||
@@ -1077,15 +1070,11 @@ socket_send_tcp:
|
||||
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: TCP\n"
|
||||
|
||||
.loop:
|
||||
push eax
|
||||
add eax, STREAM_SOCKET.snd
|
||||
call socket_ring_write
|
||||
pop eax
|
||||
|
||||
test ecx, ecx
|
||||
jz .block
|
||||
|
||||
mov [esp + SYSCALL_STACK.eax], ecx
|
||||
mov [eax + SOCKET.errorcode], 0
|
||||
push eax
|
||||
@@ -1095,22 +1084,6 @@ socket_send_tcp:
|
||||
mov [esp + SYSCALL_STACK.ebx], eax
|
||||
ret
|
||||
|
||||
.block:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: TCP is blocked\n"
|
||||
test [eax + SOCKET.options], SO_NONBLOCK
|
||||
jnz .wouldblock
|
||||
|
||||
call socket_block
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "SOCKET_send: TCP is unblocked\n"
|
||||
mov ecx, dword[esp + SYSCALL_STACK.esi]
|
||||
jmp .loop
|
||||
|
||||
.wouldblock:
|
||||
mov dword[esp + SYSCALL_STACK.ebx], EWOULDBLOCK
|
||||
mov dword[esp + SYSCALL_STACK.eax], -1
|
||||
pop esi edx
|
||||
ret
|
||||
|
||||
|
||||
align 4
|
||||
socket_send_ip:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2026. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; STACK.INC ;;
|
||||
@@ -168,9 +168,6 @@ NET_HWACC_TCP_IPv4_OUT = 1 shl 1
|
||||
NET_BUFF_LOOPBACK = 0
|
||||
NET_BUFF_ETH = 1
|
||||
|
||||
; Hardware state (inside link_state)
|
||||
NET_TX_BLOCKED = 1 shl 31 ; Transmit queue is full, if you call transmit again, driver might drop your frame
|
||||
|
||||
struct NET_DEVICE
|
||||
|
||||
device_type dd ? ; Type field
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2026. All rights reserved. ;;
|
||||
;; Copyright (C) KolibriOS team 2004-2024. All rights reserved. ;;
|
||||
;; Distributed under terms of the GNU General Public License ;;
|
||||
;; ;;
|
||||
;; Part of the TCP/IP network stack for KolibriOS ;;
|
||||
@@ -554,14 +554,6 @@ endl
|
||||
|
||||
mov ecx, esi
|
||||
mov ebx, [eax + IP_SOCKET.device]
|
||||
test ebx, ebx
|
||||
jz @f
|
||||
|
||||
; Check if the output path is blocked, dont generate output frames if so.
|
||||
test [ebx + NET_DEVICE.link_state], NET_TX_BLOCKED
|
||||
jnz .output_blocked
|
||||
@@:
|
||||
|
||||
mov edx, [eax + IP_SOCKET.LocalIP] ; source ip
|
||||
mov edi, [eax + IP_SOCKET.RemoteIP] ; dest ip
|
||||
mov al, [eax + IP_SOCKET.ttl]
|
||||
@@ -744,23 +736,6 @@ endl
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
.output_blocked:
|
||||
DEBUGF DEBUG_NETWORK_VERBOSE, "TCP_send: output path blocked, aborting\n"
|
||||
|
||||
pop ecx
|
||||
add esp, ecx
|
||||
add esp, 4
|
||||
pop eax
|
||||
|
||||
mov [eax + TCP_SOCKET.timer_retransmission], TCP_time_re_min
|
||||
or [eax + TCP_SOCKET.timer_flags], timer_flag_retransmission
|
||||
|
||||
lea ecx, [eax + SOCKET.mutex]
|
||||
call mutex_unlock
|
||||
|
||||
or eax, -1
|
||||
ret
|
||||
|
||||
|
||||
.send_error:
|
||||
add esp, 4
|
||||
@@ -771,8 +746,8 @@ endl
|
||||
|
||||
DEBUGF DEBUG_NETWORK_ERROR, "TCP_send: sending failed\n"
|
||||
|
||||
or eax, -1
|
||||
dec eax
|
||||
or eax, -2
|
||||
ret
|
||||
|
||||
|
||||
endp
|
||||
@@ -320,12 +320,12 @@ tcp_respond:
|
||||
stosb
|
||||
mov eax, SOCKET_BUFFER_SIZE
|
||||
sub eax, [esi + STREAM_SOCKET.rcv.size]
|
||||
mov cl, [esi + TCP_SOCKET.RCV_SCALE]
|
||||
shr eax, cl ; scale first, then clamp to the
|
||||
cmp eax, TCP_max_win ; 16-bit field maximum
|
||||
cmp eax, TCP_max_win
|
||||
jbe .lessthanmax
|
||||
mov eax, TCP_max_win
|
||||
.lessthanmax:
|
||||
mov cl, [esi + TCP_SOCKET.RCV_SCALE]
|
||||
shr eax, cl
|
||||
|
||||
xchg al, ah
|
||||
stosw ; window
|
||||
|
||||
@@ -1,480 +0,0 @@
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; ;;
|
||||
;; kperf.asm - simple iperf-style TCP throughput tester ;;
|
||||
;; for KolibriOS ;;
|
||||
;; ;;
|
||||
;; Usage: ;;
|
||||
;; kperf -c <ip> connect to a server and blast data ;;
|
||||
;; kperf -s listen, accept, and receive data ;;
|
||||
;; ;;
|
||||
;; Compatible with real iperf2 in "-C" (compatibility) mode: ;;
|
||||
;; Linux side, receive test: iperf -s -p 5001 -i 1 ;;
|
||||
;; Linux side, send test: iperf -c <kolibri-ip> -p 5001 \ ;;
|
||||
;; -C -i 1 ;;
|
||||
;; No iperf header is sent or expected in either direction - it's ;;
|
||||
;; a raw byte-count throughput test, matching -C behaviour. ;;
|
||||
;; ;;
|
||||
;; Socket API and command-line parsing patterns verified against ;;
|
||||
;; tcpserv.asm and telnet.asm (KolibriOS team, hidnplayr). ;;
|
||||
;; The interval/summary reporting math below is new code and has ;;
|
||||
;; not been run - sanity check the numbers on first use. ;;
|
||||
;; ;;
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
format binary as ""
|
||||
|
||||
PORT = 5001 ; classic iperf2 default port
|
||||
SENDBUFSIZE = 32768
|
||||
RECVBUFSIZE = 32768
|
||||
DURATION_CS = 1000 ; client test duration: 10.00 sec (centiseconds)
|
||||
REPORT_CS = 100 ; report interval: 1.00 sec (centiseconds)
|
||||
|
||||
use32
|
||||
; standard header
|
||||
db 'MENUET01' ; signature
|
||||
dd 1 ; header version
|
||||
dd start ; entry point
|
||||
dd i_end ; initialized size
|
||||
dd mem+4096 ; required memory
|
||||
dd mem+4096 ; stack pointer
|
||||
dd cmdline ; parameters - kernel writes ASCIIZ args here
|
||||
dd 0 ; path
|
||||
|
||||
include '../../macros.inc'
|
||||
purge mov,add,sub
|
||||
include '../../proc32.inc'
|
||||
include '../../dll.inc'
|
||||
include '../../network.inc'
|
||||
|
||||
; ======================================================================
|
||||
; entry point
|
||||
; ======================================================================
|
||||
start:
|
||||
stdcall dll.Load, @IMPORT
|
||||
test eax, eax
|
||||
jnz exit
|
||||
|
||||
invoke con_start, 1
|
||||
invoke con_init, 80, 25, 80, 25, title
|
||||
|
||||
mcall 40, EVM_STACK
|
||||
|
||||
cmp byte[cmdline], 0
|
||||
jne .have_args
|
||||
invoke con_write_asciiz, str_usage
|
||||
jmp done
|
||||
.have_args:
|
||||
|
||||
mov esi, cmdline
|
||||
cmp byte[esi], '-'
|
||||
jne .modechar
|
||||
inc esi
|
||||
.modechar:
|
||||
lodsb
|
||||
cmp al, 's'
|
||||
je server_mode
|
||||
cmp al, 'c'
|
||||
je client_prep
|
||||
invoke con_write_asciiz, str_usage
|
||||
jmp done
|
||||
|
||||
; ======================================================================
|
||||
; client mode - parse IP, connect, blast data
|
||||
; ======================================================================
|
||||
client_prep:
|
||||
.skipsp:
|
||||
cmp byte[esi], ' '
|
||||
jne .gotip
|
||||
inc esi
|
||||
jmp .skipsp
|
||||
.gotip:
|
||||
push esp
|
||||
invoke getaddrinfo, esi, 0, 0, esp
|
||||
pop edi
|
||||
test eax, eax
|
||||
jnz dns_err
|
||||
|
||||
mov eax, [edi+addrinfo.ai_addr]
|
||||
mov eax, [eax+sockaddr_in.sin_addr]
|
||||
mov [sockaddr1.ip], eax
|
||||
invoke freeaddrinfo, edi
|
||||
|
||||
invoke con_write_asciiz, str_connecting
|
||||
invoke inet_ntoa, [sockaddr1.ip]
|
||||
invoke con_write_asciiz, eax
|
||||
invoke con_write_asciiz, str_nl
|
||||
|
||||
mov ax, PORT
|
||||
xchg al, ah ; host->network byte order
|
||||
mov [sockaddr1.port], ax
|
||||
|
||||
mcall socket, AF_INET4, SOCK_STREAM, 0
|
||||
cmp eax, -1
|
||||
je socket_err
|
||||
mov [socketnum], eax
|
||||
|
||||
mcall connect, [socketnum], sockaddr1, 18
|
||||
test eax, eax
|
||||
jnz socket_err
|
||||
|
||||
invoke con_write_asciiz, str_connected
|
||||
|
||||
; --- timing setup ---
|
||||
mcall 26, 9
|
||||
mov [start_time], eax
|
||||
mov [last_report], eax
|
||||
mov dword[interval_bytes], 0
|
||||
mov dword[total_bytes], 0
|
||||
|
||||
.sendloop:
|
||||
invoke con_get_flags
|
||||
test eax, 0x200
|
||||
jnz .client_closed
|
||||
|
||||
mcall send, [socketnum], sendbuf, SENDBUFSIZE, 0
|
||||
cmp eax, -1
|
||||
je .client_closed
|
||||
;cmp eax, 0 ; 0 means buffer is full
|
||||
;je .client_closed
|
||||
|
||||
add [interval_bytes], eax
|
||||
add [total_bytes], eax
|
||||
|
||||
mcall 26, 9
|
||||
mov ecx, eax ; ecx = now
|
||||
mov ebx, ecx
|
||||
sub ebx, [last_report] ; ebx = elapsed since last report
|
||||
cmp ebx, REPORT_CS
|
||||
jl .check_dur
|
||||
|
||||
mov edx, [last_report]
|
||||
sub edx, [start_time] ; edx = interval start (rel. to test start)
|
||||
stdcall print_interval, [interval_bytes], ebx, edx, ecx
|
||||
mov [last_report], ecx
|
||||
mov dword[interval_bytes], 0
|
||||
|
||||
.check_dur:
|
||||
mcall 26, 9
|
||||
mov ebx, eax
|
||||
sub ebx, [start_time]
|
||||
cmp ebx, DURATION_CS
|
||||
jl .sendloop
|
||||
|
||||
mcall 26, 9
|
||||
mov ebx, eax
|
||||
sub ebx, [start_time]
|
||||
stdcall print_summary, [total_bytes], ebx
|
||||
jmp .client_done
|
||||
|
||||
.client_closed:
|
||||
invoke con_write_asciiz, str_conn_closed
|
||||
mov ebx, [last_report]
|
||||
sub ebx, [start_time]
|
||||
stdcall print_summary, [total_bytes], ebx
|
||||
|
||||
.client_done:
|
||||
mcall close, [socketnum]
|
||||
jmp done
|
||||
|
||||
; ======================================================================
|
||||
; server mode - listen, accept, receive data
|
||||
; ======================================================================
|
||||
server_mode:
|
||||
mcall socket, AF_INET4, SOCK_STREAM, 0
|
||||
cmp eax, -1
|
||||
je socket_err
|
||||
mov [socketnum], eax
|
||||
|
||||
mov ax, PORT
|
||||
xchg al, ah
|
||||
mov [sockaddr1.port], ax
|
||||
mov dword[sockaddr1.ip], 0
|
||||
|
||||
mcall bind, [socketnum], sockaddr1, 18
|
||||
cmp eax, -1
|
||||
je socket_err
|
||||
|
||||
mcall listen, [socketnum], 1
|
||||
cmp eax, -1
|
||||
je socket_err
|
||||
|
||||
invoke con_write_asciiz, str_listening
|
||||
|
||||
mcall accept, [socketnum], sockaddr1, 18
|
||||
cmp eax, -1
|
||||
je socket_err
|
||||
mov [socketnum2], eax
|
||||
|
||||
invoke con_write_asciiz, str_accepted
|
||||
invoke inet_ntoa, [sockaddr1.ip]
|
||||
invoke con_write_asciiz, eax
|
||||
invoke con_write_asciiz, str_nl
|
||||
|
||||
mcall 26, 9
|
||||
mov [start_time], eax
|
||||
mov [last_report], eax
|
||||
mov dword[interval_bytes], 0
|
||||
mov dword[total_bytes], 0
|
||||
|
||||
.recvloop:
|
||||
invoke con_get_flags
|
||||
test eax, 0x200
|
||||
jnz .server_closed
|
||||
|
||||
mcall recv, [socketnum2], recvbuf, RECVBUFSIZE, 0
|
||||
cmp eax, -1
|
||||
je .server_closed
|
||||
cmp eax, 0
|
||||
je .server_closed
|
||||
|
||||
add [interval_bytes], eax
|
||||
add [total_bytes], eax
|
||||
|
||||
mcall 26, 9
|
||||
mov ecx, eax
|
||||
mov ebx, ecx
|
||||
sub ebx, [last_report]
|
||||
cmp ebx, REPORT_CS
|
||||
jl .recvloop
|
||||
|
||||
mov edx, [last_report]
|
||||
sub edx, [start_time]
|
||||
stdcall print_interval, [interval_bytes], ebx, edx, ecx
|
||||
mov [last_report], ecx
|
||||
mov dword[interval_bytes], 0
|
||||
jmp .recvloop
|
||||
|
||||
.server_closed:
|
||||
invoke con_write_asciiz, str_conn_closed
|
||||
mcall 26, 9
|
||||
mov ebx, eax
|
||||
sub ebx, [start_time]
|
||||
stdcall print_summary, [total_bytes], ebx
|
||||
|
||||
mcall close, [socketnum2]
|
||||
jmp done
|
||||
|
||||
; ======================================================================
|
||||
; error handlers
|
||||
; ======================================================================
|
||||
socket_err:
|
||||
invoke con_write_asciiz, str_sockerr
|
||||
jmp done
|
||||
|
||||
dns_err:
|
||||
invoke con_write_asciiz, str_dnserr
|
||||
jmp done
|
||||
|
||||
done:
|
||||
invoke con_getch2
|
||||
invoke con_exit, 1
|
||||
exit:
|
||||
mcall -1
|
||||
|
||||
|
||||
; ======================================================================
|
||||
; print_interval: bytes, interval_cs, range_start_cs, range_end_cs
|
||||
; Prints "S.CC-S.CC sec X.XX Mbits/sec"
|
||||
; ======================================================================
|
||||
proc print_interval uses eax ebx ecx edx, pbytes, pinterval, prange_start, prange_end
|
||||
stdcall fmt_cs, [prange_start]
|
||||
invoke con_write_asciiz, linebuf
|
||||
invoke con_write_asciiz, str_dash
|
||||
stdcall fmt_cs, [prange_end]
|
||||
invoke con_write_asciiz, linebuf
|
||||
invoke con_write_asciiz, str_sec_tab
|
||||
|
||||
stdcall fmt_mbps, [pbytes], [pinterval]
|
||||
invoke con_write_asciiz, linebuf
|
||||
invoke con_write_asciiz, str_mbits_nl
|
||||
ret
|
||||
endp
|
||||
|
||||
; ======================================================================
|
||||
; print_summary: bytes, total_cs
|
||||
; Prints "0.00-S.CC sec (total) X.XX Mbits/sec"
|
||||
; ======================================================================
|
||||
proc print_summary uses eax ebx ecx edx, pbytes, pinterval
|
||||
invoke con_write_asciiz, str_zero
|
||||
invoke con_write_asciiz, str_dash
|
||||
stdcall fmt_cs, [pinterval]
|
||||
invoke con_write_asciiz, linebuf
|
||||
invoke con_write_asciiz, str_sec_total
|
||||
|
||||
stdcall fmt_mbps, [pbytes], [pinterval]
|
||||
invoke con_write_asciiz, linebuf
|
||||
invoke con_write_asciiz, str_mbits_nl
|
||||
ret
|
||||
endp
|
||||
|
||||
; ======================================================================
|
||||
; fmt_cs: format a centisecond dword value as "S.CC" into linebuf
|
||||
; ======================================================================
|
||||
proc fmt_cs uses eax ebx edx edi, pcs
|
||||
mov eax, [pcs]
|
||||
mov ebx, 100
|
||||
xor edx, edx
|
||||
div ebx ; eax = whole seconds, edx = centiseconds
|
||||
push edx ; save centiseconds
|
||||
mov edi, linebuf
|
||||
stdcall itoa, eax, edi
|
||||
mov edi, eax ; itoa returns pointer to end of written digits
|
||||
mov byte[edi], '.'
|
||||
inc edi
|
||||
pop eax ; eax = centiseconds (0-99)
|
||||
mov ebx, 10
|
||||
xor edx, edx
|
||||
div ebx ; eax = tens digit, edx = ones digit
|
||||
add al, '0'
|
||||
mov [edi], al
|
||||
inc edi
|
||||
add dl, '0'
|
||||
mov [edi], dl
|
||||
inc edi
|
||||
mov byte[edi], 0
|
||||
ret
|
||||
endp
|
||||
|
||||
; ======================================================================
|
||||
; fmt_mbps: format (bytes, interval_cs) as "X.XX" Mbits/sec into linebuf
|
||||
; Mbps*100 = (bytes * 8) / (interval_cs * 100)
|
||||
; ======================================================================
|
||||
proc fmt_mbps uses ebx ecx edx edi, pbytes, pinterval
|
||||
mov eax, [pbytes]
|
||||
cmp eax, 0x1FFFFFFF ; guard against *8 overflow at extreme rates
|
||||
jb .noshift
|
||||
shr eax, 4 ; scale down bytes and interval together
|
||||
mov ecx, [pinterval]
|
||||
shr ecx, 0 ; (kept for clarity; no shift on interval)
|
||||
jmp .have_scaled
|
||||
.noshift:
|
||||
mov ecx, [pinterval]
|
||||
.have_scaled:
|
||||
mov ebx, 8
|
||||
mul ebx ; edx:eax = bytes*8
|
||||
mov ebx, ecx
|
||||
imul ebx, 100 ; ebx = interval_cs * 100
|
||||
cmp ebx, 0
|
||||
jnz .divok
|
||||
mov ebx, 1 ; avoid div-by-zero on a zero-length interval
|
||||
.divok:
|
||||
div ebx ; eax = Mbps*100
|
||||
|
||||
mov edi, linebuf
|
||||
mov ebx, 100
|
||||
xor edx, edx
|
||||
div ebx ; eax = whole Mbps, edx = fractional (0-99)
|
||||
push edx
|
||||
stdcall itoa, eax, edi
|
||||
mov edi, eax
|
||||
mov byte[edi], '.'
|
||||
inc edi
|
||||
pop eax
|
||||
mov ebx, 10
|
||||
xor edx, edx
|
||||
div ebx
|
||||
add al, '0'
|
||||
mov [edi], al
|
||||
inc edi
|
||||
add dl, '0'
|
||||
mov [edi], dl
|
||||
inc edi
|
||||
mov byte[edi], 0
|
||||
ret
|
||||
endp
|
||||
|
||||
; ======================================================================
|
||||
; itoa: unsigned dword -> decimal ASCII, no leading zeros ("0" for zero)
|
||||
; in: value, dest buffer pointer
|
||||
; out: eax = pointer to the byte AFTER the last digit written
|
||||
; (buffer is NOT null-terminated by this routine)
|
||||
; ======================================================================
|
||||
proc itoa uses ebx ecx edx esi, value, dest
|
||||
mov eax, [value]
|
||||
mov edi, [dest]
|
||||
mov ecx, 0 ; digit count
|
||||
mov ebx, 10
|
||||
test eax, eax
|
||||
jnz .divloop
|
||||
mov byte[edi], '0'
|
||||
inc edi
|
||||
mov eax, edi
|
||||
ret
|
||||
.divloop:
|
||||
xor edx, edx
|
||||
div ebx
|
||||
push edx
|
||||
inc ecx
|
||||
test eax, eax
|
||||
jnz .divloop
|
||||
.popl:
|
||||
pop edx
|
||||
add dl, '0'
|
||||
mov [edi], dl
|
||||
inc edi
|
||||
loop .popl
|
||||
mov eax, edi
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
; data
|
||||
title db 'kperf',0
|
||||
|
||||
str_usage db 'Usage: kperf -c <ip> (client)',10,\
|
||||
' kperf -s (server)',10,10,0
|
||||
|
||||
str_connecting db 'Connecting to ',0
|
||||
str_connected db 'Connected. Starting test...',10,10,0
|
||||
str_listening db 'Listening on port 5001...',10,0
|
||||
str_accepted db 'Accepted connection from ',0
|
||||
str_conn_closed db 10,'Connection closed.',10,0
|
||||
str_sockerr db 'Socket error.',10,10,0
|
||||
str_dnserr db 'Could not parse address.',10,10,0
|
||||
str_nl db 10,0
|
||||
str_dash db '-',0
|
||||
str_zero db '0.00',0
|
||||
str_sec_tab db ' sec ',0
|
||||
str_sec_total db ' sec (total) ',0
|
||||
str_mbits_nl db ' Mbits/sec',10,0
|
||||
|
||||
sockaddr1:
|
||||
dw AF_INET4
|
||||
.port dw 0
|
||||
.ip dd 0
|
||||
rb 10
|
||||
|
||||
align 4
|
||||
@IMPORT:
|
||||
|
||||
library network, 'network.obj', console, 'console.obj'
|
||||
import network, \
|
||||
getaddrinfo, 'getaddrinfo', \
|
||||
freeaddrinfo, 'freeaddrinfo', \
|
||||
inet_ntoa, 'inet_ntoa'
|
||||
import console, \
|
||||
con_start, 'START', \
|
||||
con_init, 'con_init', \
|
||||
con_write_asciiz, 'con_write_asciiz', \
|
||||
con_exit, 'con_exit', \
|
||||
con_getch2, 'con_getch2', \
|
||||
con_get_flags, 'con_get_flags'
|
||||
|
||||
i_end:
|
||||
|
||||
socketnum dd ?
|
||||
socketnum2 dd ?
|
||||
start_time dd ?
|
||||
last_report dd ?
|
||||
interval_bytes dd ?
|
||||
total_bytes dd ?
|
||||
|
||||
linebuf rb 32
|
||||
cmdline rb 256
|
||||
|
||||
sendbuf rb SENDBUFSIZE
|
||||
recvbuf rb RECVBUFSIZE
|
||||
|
||||
align 4
|
||||
rb 4096 ; stack
|
||||
mem:
|
||||
Reference in new issue
Block a user