; ; outfast.asm - some optimized comms stuff for VPX ; ; outveryfast ; ; eax = pointer to data ; edx = link adapter base register ; ebx = no of bytes to send ; .PROT assume cs:_text _text segment public outveryfast_ public outsw_ public wmemcpy_ ;{{{ outveryfast_ proc outveryfast_ proc push ecx push esi cld ; clear decrement flag, i assume mov esi,eax ; save away for pump mov ecx,ebx add dx, 3 ; output status #next_byte_reset: xor ebx,ebx ; clear error count #next_byte: in al,dx and al, 1 jz #loop_check ; output reg has cleared... #loop_ready: xor dx, 2 ; move to data register outsb ; output data in [esi++] to dx xor dx, 2 ; move to status register loop #next_byte_reset #exit_ok: mov ax,1 pop esi pop ecx ret #loop_check: ; output reg has cleared... inc ebx xor ebx,256000 jnz #next_byte #exit_err: mov ax,0 pop esi pop ecx ret outveryfast_ endp ;}}} ; outsw - fifo transmit, followed by length word wown LA ; ; eax = length word ; edx = link adapter base register ; ebx = address of data to send ; ecx = no of bytes to send ; ; ;{{{ outsw_ proc outsw_ proc push esi add ecx, 3 ; make n_bytes be a multiple of and ecx, -4 ; 4 bytes shr ecx, 1 ; convert to shorts ; now do the fifo output mov esi,ebx ; set up data base pointer xor dx, 4 ; point at fifo read/write port rep outsw ; do the transfer xor dx, 7 ; move to output status and eax, -1 jz #outsw_exitok ; now do the link adapter 32-bit length-word output mov ecx, eax ; push length word into cx call output_byte shr ecx, 8 call output_byte shr ecx, 8 call output_byte shr ecx, 8 call output_byte #outsw_exitok: pop esi mov eax, 1 ret ; return to caller outsw_ endp ; ; local function to output a single byte down LA ; ; dx = output status reg, ecx = byte to output ; ; on failure to output, returns to outsw caller ; output_byte proc xor ebx,ebx ; do byte 0 #byte_loop: in al,dx and al, 1 jnz #byte_doit ; output reg has cleared... inc ebx xor ebx,256000 jnz #byte_loop jmp #byte_exiterr #byte_doit: mov eax,ecx xor dx, 2 ; move to data register out dx, al ; output data in [esi++] to dx xor dx, 2 ; move to status register ret #byte_exiterr: pop esi ; trash return address to outsw pop esi ; real esi mov eax, 0 ; put error code into eax for return ret ; and return to outsw caller output_byte endp ;}}} ; eax = dest ; edx = src ; ebx = no of bytes to send ; ;{{{ wmemcpy_ proc wmemcpy_ proc push ecx push esi push edi mov ecx,ebx shr ecx,2 mov esi,edx mov edi,eax rep movsd pop edi pop esi pop ecx ret wmemcpy_ endp ;}}} _text ends end