page ;*********************************************************************** ; ; (C) Copyright 1992 Trantor Systems, Ltd. ; All Rights Reserved. ; ; This program is an unpublished copyrighted work which is proprietary ; to Trantor Systems, Ltd. and contains confidential information that ; is not to be reproduced or disclosed to any other person or entity ; without prior written consent from Trantor Systems, Ltd. in each ; and every instance. ; ; WARNING: Unauthorized reproduction of this program as well as ; unauthorized preparation of derivative works based upon the ; program or distribution of copies by sale, rental, lease or ; lending are violations of federal copyright laws and state trade ; secret laws, punishable by civil and criminal penalties. ; ;*********************************************************************** title EP3C2.ASM ;----------------------------------------------------------------------- ; ; EP3C2.ASM ; ; FIFO I/O Routines for the EP3C chip. ; Assembly coded for speed. These are only some of the routines ; needed for the EP3C. The rest are in EP3C.C. ; ; History ; ------- ; 05-17-93 JAP First, from ep3c.c ; ;----------------------------------------------------------------------- ;----------------------------------------------------------------------- ; stack frame equates ;----------------------------------------------------------------------- ep3c_param2 equ 12 ep3c_param1 equ 8 ep3c_retAdrs equ 4 ep3c_bp equ 0 ep3c_pbytes equ ep3c_param2 ep3c_baseIoAddress equ ep3c_param1 ;----------------------------------------------------------------------- ; Macros ;----------------------------------------------------------------------- ;----------------------------------------------------------------------- ; get_params ; ; Puts parameters into registers: ; edx -> baseIoAddress ; ds:[edi] -> pbytes ;----------------------------------------------------------------------- get_params macro ifdef MODE_32BIT mov edi, dword ptr [ebp].ep3c_pbytes mov edx, dword ptr [ebp].ep3c_baseIoAddress else mov edi, word ptr ss:[bp].ep3c_pbytes mov ds, word ptr ss:[bp].ep3c_pbytes+2 mov edx, word ptr ss:[bp].ep3c_baseIoAddress endif ;MODE_32BIT endm ;----------------------------------------------------------------------- ; Routines ;----------------------------------------------------------------------- ;----------------------------------------------------------------------- ; EP3CReadFifoUniDir ; ; VOID EP3CReadFifoUniDir (PBASE_REGISTER baseIoAddress, PUCHAR pbytes) ; ; Reads bytes for uni-directional parallel port from the 53c400 ; 128 byte buffer. The register must already be set the the ; 53c400 buffer register. ; ;----------------------------------------------------------------------- EP3CReadFifoUniDir proc far push ds push edi get_params mov ecx, 128 loop0: mov al, 0x80 out dx, al ;select high nibble jmp delay0 delay0: add edx,2 ;DX -> ctl reg mov al,P_AFX ;assert bufen and afx out dx,al ;assert dreg read jmp delay1 delay1: dec edx ;DX -> stat reg in al,dx ;read high nibble jmp delay2 delay2: mov ah,al shl ah,1 and ah,0f0h ;AH -> adj high nibble dec edx ;DX -> data reg sub al,al out dx,al ;select low nibble jmp delay3 delay3: inc edx ;DX -> stat reg in al,dx ;read low nibble shr al,1 shr al,1 shr al,1 and al,0fh ;AL = adj low nibble or al,ah ;AL = recombined byte mov [edi],al ;store inc edi ;bump buf ptr inc edx ;DX -> ctl reg xor al,al ;negate afx (bufen stays asserted) out dx,al ;end read jmp delay4 delay4: sub edx,2 ;DX -> data reg dec ecx jnz loop0 pop edi pop ds ret EP3CReadFifoUniDir endp ;----------------------------------------------------------------------- ; ; EP3CReadFifoUniDirSlow ; ; VOID EP3CReadFifoUniDirSlow (PBASE_REGISTER baseIoAddress, PUCHAR pbytes) ; ; Reads bytes for uni-directional parallel port from the 53c400 ; 128 byte buffer. The register must already be set the the ; 53c400 buffer register. ; ; USES FULL HANDSHAKING ; ;----------------------------------------------------------------------- EP3CReadFifoUniDirSlow proc far push ds push edi get_params inc edx // edx - status register mov ecx, 128 loop0: dec edx // edx - data register mov al, 0x80 out dx,al // select high nibble jmp delay0 delay0: add edx, 2 // DX -> ctl reg mov al, P_AFX // assert bufen and afx out dx, al // assert dreg read ; wait till ready, P_BUSY asserted dec edx // edx - status register loop1: in al,dx test al, P_BUSY jnz loop1 ; delay to make sure we get high nibble in jmp delay01 delay01: in al,dx mov ah,al shl ah,1 and ah,0f0h // AH -> adj high nibble dec edx // DX -> data reg sub al,al out dx,al // select low nibble jmp delay3 delay3: inc edx // DX -> stat reg in al,dx // read low nibble shr al,1 shr al,1 shr al,1 and al,0fh // AL = adj low nibble or al,ah // AL = recombined byte mov [edi],al // store inc edi // bump buf ptr inc edx // DX -> ctl reg xor al,al // negate afx (bufen stays asserted) out dx,al // end read dec edx // DX -> status register ; wait for P_BUSY deasserted loop2: in al,dx test al, P_BUSY jz loop2 dec ecx jnz loop0 pop edi pop ds ret EP3CReadFifoUniDirSlow endp //---------------------------------------------------------------------- // // VOID EP3CReadFifoBiDir // // Reads bytes for bi-directional parallel port from the 53c400 // 128 byte buffer. The register must already be set the the // 53c400 buffer register. // //---------------------------------------------------------------------- VOID EP3CReadFifoBiDir(PBASE_REGISTER baseIoAddress, PUCHAR pbytes) { _asm { push ds push edi #ifdef MODE_32BIT mov edi,pbytes mov edx, baseIoAddress #else mov edi, word ptr pbytes mov ds, word ptr pbytes+2 mov edx, word ptr baseIoAddress #endif // MODE_32BIT mov ecx, 128 add edx, 2 // edx - control register loop0: mov al, P_BUFEN + P_AFX out dx, al jmp delay0 delay0: sub edx,2 // edx - data register in al,dx mov [edi], al inc edi add edx,2 // edx - control register mov al, P_BUFEN out dx, al jmp delay1 // is this needed, there is a loop? delay1: dec ecx jnz loop0 xor al,al // leave control regiser 0'd out dx, al pop edi pop ds } } //---------------------------------------------------------------------- // // VOID EP3CReadFifoBiDirSlow // // Reads bytes for bi-directional parallel port from the 53c400 // 128 byte buffer. The register must already be set the the // 53c400 buffer register. // // USES FULL HANDSHAKING // //---------------------------------------------------------------------- VOID EP3CReadFifoBiDirSlow(PBASE_REGISTER baseIoAddress, PUCHAR pbytes) { _asm { push ds push edi #ifdef MODE_32BIT mov edi,pbytes mov edx, baseIoAddress #else mov edi, word ptr pbytes mov ds, word ptr pbytes+2 mov edx, word ptr baseIoAddress #endif // MODE_32BIT mov ecx, 128 add edx, 0x02 // edx - control register // wait for data to be ready, P_BUSY asserted loop0: mov al, P_BUFEN + P_AFX out dx, al dec edx // edx - status register loop1: in al,dx test al, P_BUSY jnz loop1 dec edx // edx - data register in al,dx mov [edi], al inc edi add edx,2 // edx - control register // end data read cycle mov al, P_BUFEN out dx, al dec edx // edx - status register // wait for P_BUSY deasserted loop2: in al,dx test al, P_BUSY jz loop2 inc edx // edx - control register dec ecx jnz loop0 xor al,al // leave control regiser 0'd out dx, al pop edi pop ds } } //---------------------------------------------------------------------- // // VOID EP3CWriteFifoUniDir // // Writes bytes thru uni-directional parallel port to the 53c400 // 128 byte buffer. The register must already be set the the // 53c400 buffer register. // //---------------------------------------------------------------------- VOID EP3CWriteFifoUniDir(PBASE_REGISTER baseIoAddress, PUCHAR pbytes) { _asm { push ds push edi #ifdef MODE_32BIT mov edi,pbytes mov edx, baseIoAddress #else mov edi, word ptr pbytes mov ds, word ptr pbytes+2 mov edx, word ptr baseIoAddress #endif // MODE_32BIT mov ecx, 128 loop0: mov al,[edi] out dx,al inc edi add edx,2 ;DX -> ctl reg mov al,P_STB ;assert bufen, stb out dx,al or al,P_AFX ;assert dreg write out dx,al jmp delay0 delay0: ;leave bufen asserted mov al,0 ; and negate afx, stb out dx,al ;end write jmp delay1 delay1: sub edx,2 ;DX -> data reg dec ecx jnz loop0 // let's leave control register 0'd for all these fifo routines... // add edx,2 ;DX -> ctl reg // or al,P_BUFEN ;negate bufen // out dx,al jmp delay2 delay2: pop edi pop ds } } //---------------------------------------------------------------------- // // VOID EP3CWriteFifoUniDirSlow // // Writes bytes thru uni-directional parallel port to the 53c400 // 128 byte buffer. The register must already be set the the // 53c400 buffer register. // // USES FULL HANDSHAKING // //---------------------------------------------------------------------- VOID EP3CWriteFifoUniDirSlow(PBASE_REGISTER baseIoAddress, PUCHAR pbytes) { _asm { push ds push edi #ifdef MODE_32BIT mov edi,pbytes mov edx, baseIoAddress #else mov edi, word ptr pbytes mov ds, word ptr pbytes+2 mov edx, word ptr baseIoAddress #endif // MODE_32BIT mov ecx, 128 loop0: mov al,[edi] out dx,al inc edi add edx,2 ;DX -> ctl reg mov al,P_STB ;assert bufen, stb out dx,al or al,P_AFX ;assert dreg write out dx,al // wait till ready, P_BUSY asserted dec edx // edx - status register loop1: in al,dx test al, P_BUSY jnz loop1 inc edx // edx - control register ;leave bufen asserted mov al,0 ; and negate afx, stb out dx,al ;end write dec edx // edx - status register // wait for P_BUSY deasserted loop2: in al,dx test al, P_BUSY jz loop2 dec edx // edx - data register dec ecx jnz loop0 // let's leave control register 0'd for all these fifo routines... // add edx,2 ;DX -> ctl reg // or al,P_BUFEN ;negate bufen // out dx,al pop edi pop ds } }