;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; R56 Developers Toolkit 1995 ;; R56.ASM ;; This module contains routines that aid in programming the ;; #5010 R56 Adapter. All routines are C callable. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TITLE R56 ifdef LMOD .MODEL LARGE elseifdef MMOD .MODEL MEDIUM elseifdef TMOD .MODEL TINY else .MODEL SMALL endif include R56_IO.INC IFDEF FAST IO_SPEED equ ZERO_WS ELSEIFDEF SLOW IO_SPEED equ NO_ZERO_WS ELSE IO_SPEED equ ZERO_WS ENDIF TestBytes PROTO C, bSOURCE1:BYTE, bSOURCE2:BYTE, bSOURCE3:BYTE DecodeMemory PROTO C , fpMEM:DWORD DecodeIRQ PROTO C , bIRQ:BYTE .DATA ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; DATA Segment ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .CODE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ChangeR56Page PROC C PUBLIC USES AX DX SI DS, fpWANINFO:DWORD, bPAGE:BYTE lds si, fpWANINFO mov dx, pt.wIOAddress; Get I/O base in al, dx ; Read I/O register to preserve other bits IO_Pause and al, 0f0h ; Reset image of current page value mov dl, bPAGE ; Get the new page and dl, 0fh ; To be safe, only use low 4 bits or al, dl ; Now make new byte to write to I/O reg mov dx, pt.wIOAddress ; Get I/O base out dx, al ; Write to the I/O port IO_Pause ret ChangeR56Page ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; VerifyR56 : distance MODEL dependant ;; This routine will verify the I/O presence of the MP-WAN adapter ;; Passes: wIOBASE - I/O base address of the MP-WAN ;; Returns: 0 - Address verified ;; -1 - Address NOT verified ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; VerifyR56 PROC C PUBLIC USES SI DS DX, fpWANINFO:DWORD lds si, fpWANINFO mov dx, pt.wIOAddress; Get I/O base in al, dx ; Read Base Address of I/O Registers IO_Pause cmp al, 0FFh ; Is there anything there? je @f ; Jump if board not found xor ax, ax ; Return OK ret @@: mov ax, -1 ret ; Return error code VerifyR56 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IUSCoutb PROC C USES DS ES BX DX SI AX, fpWANINFO:DWORD, bREG:BYTE, bVALUE:BYTE lds si, fpWANINFO les bx, pt.MemoryBase add bl, bREG mov dx, pt.wIOAddress in al, dx push ax IO_Pause or al, MEM_WIN_ON ; Turn Memory Window ON and al, NOT IUSC_DISABLE ; Enable IUSC access out dx, al IO_Pause mov al, bVALUE mov byte ptr es:[bx], al pop ax out dx, al IO_Pause ret IUSCoutb ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IUSCinb PROC C USES DS ES DX BX SI, fpWANINFO:DWORD, bREG:BYTE lds si, fpWANINFO les bx, pt.MemoryBase add bl, bREG mov dx, pt.wIOAddress in al, dx push ax IO_Pause or al, MEM_WIN_ON ; Turn Memory Window ON and al, NOT IUSC_DISABLE ; Enable IUSC access out dx, al IO_Pause mov bl, byte ptr es:[bx] pop ax out dx, al IO_Pause mov ax, bx ret IUSCinb ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IUSCout PROC C USES DS ES BX DX SI AX, fpWANINFO:DWORD, bREG:BYTE, wVALUE:WORD lds si, fpWANINFO les bx, pt.MemoryBase add bl, bREG mov dx, pt.wIOAddress in al, dx push ax IO_Pause or al, MEM_WIN_ON ; Turn Memory Window ON and al, NOT IUSC_DISABLE ; Enable IUSC access out dx, al IO_Pause mov ax, wVALUE mov word ptr es:[bx], ax pop ax out dx, al IO_Pause ret IUSCout ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; IUSCin PROC C USES DS ES DX BX SI, fpWANINFO:DWORD, bREG:BYTE lds si, fpWANINFO les bx, pt.MemoryBase mov bl, bREG mov dx, pt.wIOAddress in al, dx push ax IO_Pause or al, MEM_WIN_ON ; Turn Memory Window ON and al, NOT IUSC_DISABLE ; Enable IUSC access out dx, al IO_Pause mov bx, word ptr es:[bx] pop ax out dx, al IO_Pause mov ax, bx ret IUSCin ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; DecodeIRQ : ;; Passes: bIRQ - IRQ ;; Returns: AL = value to OR with other bits to determine ;; IRQ of 5010 adapter. ;; Valid IRQs: 3,4,9,10,11,12,15 ;; This method was choosed to try to avoid a DATA Segemet in this ;; Module. It may change at a later date. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DecodeIRQ PROC C PUBLIC USES BX DI, bIRQ:BYTE mov al, bIRQ cmp al, 3 jnz @f mov al, SEL_IRQ_3 ret @@: cmp al, 4 jnz @f mov al, SEL_IRQ_4 ret @@: cmp al, 9 jnz @f mov al, SEL_IRQ_9 ret @@: cmp al, 10 jnz @f mov al, SEL_IRQ_10 ret @@: cmp al, 11 jnz @f mov al, SEL_IRQ_11 ret @@: cmp al, 12 jnz @f mov al, SEL_IRQ_12 ret @@: cmp al, 15 jnz @f mov al, SEL_IRQ_15 ret @@: mov ax, 0 ; For Now this wil ret 0 on error ; In the future it should pass the error ; of an invalid IRQ thorough InitIUSC to application ret DecodeIRQ ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; DecodeMemory : ;; Passes: fpMEM - Memory address ;; Returns: AL = value to OR with other bits to determine ;; Memory Address of 5010 adapter. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DecodeMemory PROC C PUBLIC USES DX CX ES DI, fpMEM:DWORD les di, fpMEM mov ax, es mov cx, 0Ah ; NOTE: Real Mode only operation shr ax, cl ; This MUST me done differently in Windows and ax, 1Fh ret DecodeMemory ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; InitIUSC : distance MODEL dependant ;; Passes: fpWANINFO - Far pointer to Card Struct ;; Returns: AX - Zero if Init OK ;; AX - Array Register value of resiger that error occured ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; InitIUSC PROC C PUBLIC USES BX CX DX DI SI ES DS, fpWANINFO:DWORD LOCAL wTemp:WORD lds si, fpWANINFO mov dx, pt.wIOAddress mov wTemp, dx in al, dx ; Base + 0 IO_Pause and al, NOT MEM_WIN_ON ; Disable Memory Window out dx, al ; Base + 0 IO_Pause add dx, 2 ; Base + 2 mov al,LOADD OR EN_16_BIT OR IO_SPEED OR ISA_IRQ ;EN0W8+EN16+EDGEY out dx, al ; make it go fast and set low address mode IO_Pause dec dx INVOKE DecodeMemory, pt.MemoryBase push ax INVOKE DecodeIRQ, pt.IUSCIRQ pop bx or al, bl out dx, al ; Base + 1 IO_Pause dec dx ; Base + 0 in al, dx ; Read Value at 1st I/O location IO_Pause or al, MEM_WIN_ON and al, NOT IUSC_DISABLE out dx, al ; Turn memory window ON and point to first page IO_Pause ;dec dx ; back to Base I/O address les di, pt.MemoryBase ;NOTE: After this point DS:SI points to the Init Array, ; NOT the far pointer to the Card Struct lds si, pt.InitArray; Set souce (array) to DS:SI TopIni: mov cx, [si] ; Get IUSC Register cmp cx, -1 ; Are we done with the array jnz @f ; Jump if we are not done mov dx, wTemp mov al, MEM_WIN_OFF OR MEM_PAGE_FIRST out dx, al IO_Pause xor ax, ax ret @@: inc si ; point to value inc si mov dx, [si] ; Get value to write/check to/from register xor bx, bx mov bl, cl INVOKE TestBytes, ch, writeW /100h, writeW /100h cmp ax, 0 jnz @f mov word ptr es:[di+bx],dx ; write word jmp RdIni @@: INVOKE TestBytes,ch, writeW /100h, writeH /100h cmp ax, 0 jnz @f mov byte ptr es:[di+bx+1],dh ; write high byte jmp RdIni @@: INVOKE TestBytes,ch, writeW /100h, writeL /100h cmp ax, 0 jnz @f mov byte ptr es:[di+bx],dl ; write low byte RdIni: INVOKE TestBytes,ch, checkH /100h, checkH /100h cmp ax, 0 jnz @f INVOKE TestBytes, dh, 0FFh, byte ptr es:[di+bx+1] cmp ax, 0 jz @f jmp EndErr @@: INVOKE TestBytes,ch, checkL /100h, checkL /100h cmp ax, 0 jnz EndIni INVOKE TestBytes, dl, 0FFh, byte ptr es:[di+bx] cmp ax, 0 jz EndIni jmp EndErr EndIni: inc si inc si jmp TopIni ret EndErr: dec si dec si mov dx, wTemp in al, dx IO_Pause and al, IUSC_DISABLE OR MEM_WIN_ON out dx, al IO_Pause mov word ptr ax, [si] ret InitIUSC ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ResetIUSC : distance MODEL dependant ;; Passes: wIOBASE - Base I/O address of R56 ;; Returns: LOWORD (AX) Error Code ;; ER_BADRESET (1) - Reset already (always) ON ;; ER_RESETTO (2) - Reset TimeOut (pending on timeout) ;; HIWORD (DX) Number of I/O Writes until Reset obtained. ;; Notes: This routine assumes that the I/O address has been ;; verified by VerifyR56(). Also note that HIWORD is only ;; valid if LOWORD = NULL (0). ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ResetIUSC PROC C PUBLIC USES BX CX SI DI DS, fpWANINFO:DWORD lds si, fpWANINFO mov dx, pt.wIOAddress add dx, 3 ; Point to Base+3 Reset Port in al, dx IO_Pause test al, NOT_RESET ; Is Reset already aserted? jnz @f ; Jump if NO mov ax, ER_BADRESET ret @@: xor cx, cx ; Clear reset counter inc cx @@: out dx, al ; No I/O delay due to time critical RESET in al, dx ; Read Base+3 test al, NOT_RESET ; jz @f ; Jump if reset now OK inc cx jnz @b ; Try for 64K times mov ax, ER_RESETTO ret @@: out dx, al ; Just to be sure out dx, al out dx, al IO_Pause xor ax, ax ; Return NO error mov dx, cx call Delay5010 ; Wait for Reset to clear call Delay5010 call Delay5010 call Delay5010 call Delay5010 ret ResetIUSC ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; TestBytes PROC C USES BX, bSOURCE1:BYTE, bSOURCE2:BYTE,bSOURCE3:BYTE mov al, bSOURCE1 and al, bSOURCE2 cmp al, bSOURCE3 jz @f mov ah, 1 ret @@: xor ax, ax ret TestBytes ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Delay5010 PROC near push cx mov cx, 0FFFeh @@: loop @b pop cx ret Delay5010 ENDP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END