LDRIVER.ASM
资源名称:ertos.rar [点击查看]
上传用户:sunrenlu
上传日期:2022-06-13
资源大小:1419k
文件大小:28k
源码类别:
操作系统开发
开发平台:
DOS
- page 65,132
- title DRIVER.ASM Multi I/O Board Driver for Flashlite 386Ex
- subttl Copyright JK microsystems 1998
- ;************************************************************************;
- ;* *;
- ;* Copyright JK microsystems 1998 - All Rights Reserved *;
- ;* *;
- ;* This software is NOT shareware, freeware, or public domain. *;
- ;* It is the property of JK microsystems. *;
- ;* *;
- ;* Customers of JK microsystems may modify the source code *;
- ;* and/or distribute the binary image of this software without *;
- ;* additional costs provided it is run only on hardware *;
- ;* manufactured by JK microsystems. All other use is expressly *;
- ;* prohibited. *;
- ;* *;
- ;* Update Log *;
- ;* *;
- ;* Version Date Comments Progammer *;
- ;* ------- ------- ------------------------------- ---------- *;
- ;* 1.0 10-20-98 First release jds *;
- ;* 1.1 04-01-99 Fixed A/D chan 0 command byte jds *;
- ;* 2.0 04-07-99 Fixed A/D for Rev C boards jds *;
- ;* *;
- ;************************************************************************;
- .model large
- .code
- ;-------------------------------------------------------------------------
- ;
- ; The following routines are the C and Quickbasic entry points for
- ; the actual routines. C entry points are prefaced with an under-
- ; score. At the entry point, the arguments are moved around so that
- ; a common routine can be called. Also, a new stack is set up before
- ; entry and the old stack is restored on exit.
- ;
- ; For information on the routines, see the _asm routine that is
- ; called.
- ;
- public _GetVersion
- _GetVersion proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call GetVersion_asm
- call old_stack
- pop bp
- ret
- _GetVersion endp
- public GetVersion ; Qbasic routine
- GetVersion proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call GetVersion_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- GetVersion endp
- public _GetA2D
- _GetA2D proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call GetA2D_asm
- call old_stack
- pop bp
- ret
- _GetA2D endp
- public GetA2D ; Qbasic routine
- GetA2D proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call GetA2D_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- GetA2D endp
- public _PutA2DChannel
- _PutA2DChannel proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call PutA2DChannel_asm
- call old_stack
- pop bp
- ret
- _PutA2DChannel endp
- public PutA2DChannel ; Qbasic routine
- PutA2DChannel proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call PutA2DChannel_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- PutA2DChannel endp
- public _PutD2A
- _PutD2A proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call PutD2A_asm
- call old_stack
- pop bp
- ret
- _PutD2A endp
- public PutD2A ; Qbasic routine
- PutD2A proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call PutD2A_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- PutD2A endp
- public _PutD2AChannel
- _PutD2AChannel proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call PutD2AChannel_asm
- call old_stack
- pop bp
- ret
- _PutD2AChannel endp
- public PutD2AChannel ; Qbasic routine
- PutD2AChannel proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call PutD2AChannel_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- PutD2AChannel endp
- public _PutDriver
- _PutDriver proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call PutDriver_asm
- call old_stack
- pop bp
- ret
- _PutDriver endp
- public PutDriver ; Qbasic routine
- PutDriver proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call PutDriver_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- PutDriver endp
- public _PutDriverChannel
- _PutDriverChannel proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call PutDriverChannel_asm
- call old_stack
- pop bp
- ret
- _PutDriverChannel endp
- public PutDriverChannel ; Qbasic routine
- PutDriverChannel proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call PutDriverChannel_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- PutDriverChannel endp
- public _GetUARTChar
- _GetUARTChar proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call GetUARTChar_asm
- call old_stack
- pop bp
- ret
- _GetUARTChar endp
- public GetUARTChar ; Qbasic routine
- GetUARTChar proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call GetUARTChar_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- GetUARTChar endp
- public _PutUARTChannel
- _PutUARTChannel proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call PutUARTChannel_asm
- call old_stack
- pop bp
- ret
- _PutUARTChannel endp
- public PutUARTChannel ; Qbasic routine
- PutUARTChannel proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call PutUARTChannel_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- PutUARTChannel endp
- public _PutUARTChar
- _PutUARTChar proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call PutUARTChar_asm
- call old_stack
- pop bp
- ret
- _PutUARTChar endp
- public PutUARTChar ; Qbasic routine
- PutUARTChar proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call PutUARTChar_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- PutUARTChar endp
- public _PutUARTBaud
- _PutUARTBaud proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call PutUARTBaud_asm
- call old_stack
- pop bp
- ret
- _PutUARTBaud endp
- public PutUARTBaud ; Qbasic routine
- PutUARTBaud proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call PutUARTBaud_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- PutUARTBaud endp
- public _GetUARTRxStatus
- _GetUARTRxStatus proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call GetUARTRxStatus_asm
- call old_stack
- pop bp
- ret
- _GetUARTRxStatus endp
- public GetUARTRxStatus ; Qbasic routine
- GetUARTRxStatus proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call GetUARTRxStatus_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- GetUARTRxStatus endp
- public _GetUARTTxStatus
- _GetUARTTxStatus proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call GetUARTTxStatus_asm
- call old_stack
- pop bp
- ret
- _GetUARTTxStatus endp
- public GetUARTTxStatus ; Qbasic routine
- GetUARTTxStatus proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call GetUARTTxStatus_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- GetUARTTxStatus endp
- public _PutUARTWC
- _PutUARTWC proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call PutUARTWC_asm
- call old_stack
- pop bp
- ret
- _PutUARTWC endp
- public PutUARTWC ; Qbasic routine
- PutUARTWC proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call PutUARTWC_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- PutUARTWC endp
- public _PutUARTWD
- _PutUARTWD proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call PutUARTWD_asm
- call old_stack
- pop bp
- ret
- _PutUARTWD endp
- public PutUARTWD ; Qbasic routine
- PutUARTWD proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call PutUARTWD_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- PutUARTWD endp
- public _GetUARTRC
- _GetUARTRC proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call GetUARTRC_asm
- call old_stack
- pop bp
- ret
- _GetUARTRC endp
- public GetUARTRC ; Qbasic routine
- GetUARTRC proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call GetUARTRC_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- GetUARTRC endp
- public _GetUARTRD
- _GetUARTRD proc ; C routine
- push bp
- mov bp,sp
- mov ax,[bp+6]
- call new_stack
- call GetUARTRD_asm
- call old_stack
- pop bp
- ret
- _GetUARTRD endp
- public GetUARTRD ; Qbasic routine
- GetUARTRD proc
- push bp
- mov bp,sp
- mov bx,ss:[bp+6]
- mov ax,[bx]
- call new_stack
- call GetUARTRD_asm
- call old_stack
- mov [bx],ax
- pop bp
- retf 2
- GetUARTRD endp
- ;-------------------------------------------------------------------------
- ;
- ; Data structures
- ;
- VersionNo dw 10 ; driver version number
- ad_board db 0 ; last A2D channel settings
- ad_side db 0
- ad_chan db 0
- da_board db 0 ; last D2A channel settings
- da_side db 0
- da_chip db 3
- da_bit db 0
- driver_board db 0 ; last driver channel settings
- driver_side db 0
- driver_chip db 5
- driver_bit db 0
- driver_bits db 16 dup(0) ; status of all the driver bits
- driver_bit_ptr dw offset driver_bits
- uart_board db 0 ; last uart channel settings
- uart_side db 0
- uart_chip db 2
- uart_cmd dw 16 dup(0E00Bh) ; default 9600,N82
- uart_cmd_ptr dw offset uart_cmd
- ; Read A/D channel #0 single-ended command string
- RD_0:
- db 50h,70h ; 1 Start
- db 40h,60h ; 0 A2
- db 40h,60h ; 0 A1
- db 50h,70h ; 1 A0
- db 40h,60h ; 0 Mode
- db 50h,70h ; 1 Single - Diff/
- db 50h,70h ; 1 PD1
- db 50h,70h ; 1 PD0
- db 40h,60h ; one extra clock
- db 40h ; idle the bus, data is high
- db 0 ; null terminator
- ; Read A/D channel #1 single-ended
- RD_1:
- db 50h,70h ; 1 Start
- db 50h,70h ; 1 A2
- db 40h,60h ; 0 A1
- db 50h,70h ; 1 A0
- db 40h,60h ; 0 Mode
- db 50h,70h ; 1 Single - Diff/
- db 50h,70h ; 1 PD1
- db 50h,70h ; 1 PD0
- db 40h,60h ; one extra clock
- db 40h ; idle the bus, data is high
- db 0 ; null terminator
- ; Read A/D channel #2 single-ended
- RD_2:
- db 50h,70h ; 1 Start
- db 40h,60h ; 0 A2
- db 50h,70h ; 1 A1
- db 40h,60h ; 0 A0
- db 40h,60h ; 0 Mode
- db 50h,70h ; 1 Single - Diff/
- db 50h,70h ; 1 PD1
- db 50h,70h ; 1 PD0
- db 40h,60h ; one extra clock
- db 40h ; idle the bus, data is high
- db 0 ; null terminator
- ; Read A/D channel #3 single-ended
- RD_3:
- db 50h,70h ; 1 Start
- db 50h,70h ; 1 A2
- db 50h,70h ; 1 A1
- db 40h,60h ; 0 A0
- db 40h,60h ; 0 Mode
- db 50h,70h ; 1 Single - Diff/
- db 50h,70h ; 1 PD1
- db 50h,70h ; 1 PD0
- db 40h,60h ; one extra clock
- db 40h ; idle the bus, data is high
- db 0 ; null terminator
- baud_table:
- dw 230 ,0 ; 230.4k baud
- dw 115 ,1 ; 115.2k baud
- dw 57 ,2 ; 57.6k baud
- dw 38 ,9 ; 38.4k baud
- dw 19 ,10 ; 19.2k baud
- dw 9600 ,11 ; 9600 baud
- dw 4800 ,12 ; 4800 baud
- dw 2400 ,13 ; 2400 baud
- dw 1200 ,14 ; 1200 baud
- dw 600 ,15 ; 600 baud
- dw 0 ,0 ; list end
- select_table:
- S0 db 70h,50h,60h,40h,60h,40h,60h,40h
- S1 db 70h,50h,60h,40h,60h,40h,70h,50h
- S2 db 70h,50h,60h,40h,70h,50h,60h,40h
- S3 db 70h,50h,60h,40h,70h,50h,70h,50h
- S4 db 70h,50h,70h,50h,60h,40h,60h,40h
- S5 db 70h,50h,70h,50h,60h,40h,70h,50h
- S6 db 70h,50h,70h,50h,70h,50h,60h,40h
- S7 db 70h,50h,70h,50h,70h,50h,70h,50h
- ;-------------------------------------------------------------------------
- ;
- ; GetVersion_asm - Returns the driver version number. The least
- ; significant decimal digit is the minor revision, the most
- ; significant decimal digits are the major revision.
- ;
- GetVersion_asm:
- mov ax,[VersionNo]
- ret
- ;-------------------------------------------------------------------------
- ;
- ; GetA2DChannel_asm - Do one A/D conversion and return 12 bit
- ; value right justified in AX
- ;
- GetA2D_asm:
- mov al,byte ptr [ad_chan]
- mov bh,byte ptr [ad_board]
- mov bl,byte ptr [ad_side]
- push bx
- mov bl,20 ; calculate pointer to channel data
- mul bl
- mov ah,0
- mov si,offset RD_0
- add si,ax
- pop bx
- push bx
- mov dx,0F862h ; point to output port
- mov al,40h ; drop all but cs/
- out dx,al
- mov al,0 ; set CS0/ for write
- call select
- mov dx,0F864h ; configure all Port F pins for
- mov al,0 ; output
- out dx,al
- mov dx,0F862h ; point to output port
- cmd_loop:
- mov al,cs:[si] ; get a byte
- cmp al,0 ; done?
- je cmd_done ; yes, leave
- out dx,al ; no, send it
- inc si ; bump pointer
- jmp cmd_loop ; and loop
- cmd_done:
- mov dx,0F864h ; configure data line for read
- mov al,10h
- out dx,al
- mov cx,16 ; 16 bits to get
- mov bx,0 ; result goes here
- mov ah,0
- in_loop:
- mov dx,0F860h
- in al,dx ; data is in bit 4
- rcl al,1 ; rotate it into carry
- rcl al,1
- rcl al,1
- rcl al,1
- rcl bx,1 ; rotate it from carry to bx
- mov dx,0F862h ; point to output port
- mov al,70h ; set the clock high
- out dx,al
- mov al,50h
- out dx,al
- loop in_loop
- shr bx,1 ; last 3 bits are zeros, shift
- shr bx,1 ; 12 bit value over
- shr bx,1
- shr bx,1
- and bx,0FFFh
- mov dx,0F862h ; idle the bus
- mov al,40h
- out dx,al
- mov ax,bx
- call bus_reset
- pop bx
- sti
- ret
- ;-------------------------------------------------------------------------
- ;
- ; PutA2DChannel_asm gets the extended channel from the caller and
- ; converts it to board, side, and channel numbers and stores
- ; the result.
- ;
- PutA2DChannel_asm:
- push ax
- mov ah,al ; make 2 copies
- mov bl,al
- and al,3 ; channel
- mov byte ptr [ad_chan],al ; store it
- and ah,4 ; board
- shr ah,1
- shr ah,1
- mov byte ptr [ad_side],ah ; store it
- and bl,0F8h
- shr bl,1
- shr bl,1
- shr bl,1
- mov byte ptr [ad_board],bl
- pop ax
- ret
- ;-------------------------------------------------------------------------
- ;
- ; PutD2AChannel_asm converts AL into a chip, side, and board select
- ; and stores them for PutD2A_asm.
- ;
- PutD2AChannel_asm:
- push ax
- push bx
- and al,1Fh ; 8 boards max
- mov bh,al ; make 2 copies
- mov bl,al
- and al,1 ; al is chip select
- add al,3
- shr bl,1 ; bl is side
- and bl,1
- shr bh,1 ; bh is board
- shr bh,1
- and bh,7 ; 8 boards max
- mov byte ptr [da_chip],al
- mov byte ptr [da_side],bl
- mov byte ptr [da_board],bh
- pop bx
- pop ax
- ret
- ;-------------------------------------------------------------------------
- ;
- ; PutD2A_asm sends the lower 12 bits in ax to the selected D2A
- ;
- PutD2A_asm:
- push ax
- push ax
- mov al,byte ptr [da_chip]
- mov bl,byte ptr [da_side]
- mov bh,byte ptr [da_board]
- call select
- pop bx
- and bx,0FFFh
- mov al,40h ; set data low
- mov dx,0F862h
- out dx,al
- mov dx,0F864h ; configure all pins as outputs
- mov al,0 ;
- out dx,al
- mov cl,16 ; loop counter
- rcl bx,1 ; get the first data bit in carry
- mov dx,0F862h ; output port
- da_shift_loop:
- mov al,60h ; clk hi with data zero
- jnc da_data_low ; all done if carry is 0
- mov al,70h ; clk hi with data one
- da_data_low:
- out dx,al ; do it
- and al,0D0h ; lower clk
- out dx,al ; send it
- rcl bx,1 ; rotate
- dec cl
- jnz da_shift_loop
- call bus_reset
- pop ax
- ret
- ;-------------------------------------------------------------------------
- ;
- ; PutDriverChannel_asm takes an integer in the range of 0-63 in
- ; ax and converts it into a board number, side number and an index
- ; into the array of previous driver bit states.
- ;
- PutDriverChannel_asm:
- push ax ; save ax for caller
- and al,3fh ; only look at lower 6 bits
- mov bh,al ; make 3 copies
- mov bl,al
- mov ah,al
- shr bl,1 ; form the side
- shr bl,1
- and bl,1
- mov [driver_side],bl
- shr bh,1 ; form the board
- shr bh,1
- shr bh,1
- and bh,7
- mov [driver_board],bh
- and ah,3
- mov [driver_bit],ah
- mov ah,0
- shr al,1 ; form the pointer to the bitfield
- shr al,1
- and al,0Fh
- mov si,offset driver_bits ; point to array
- add si,ax ; index into it
- mov [driver_bit_ptr],si ; store the pointer
- pop ax
- ret
- ;-------------------------------------------------------------------------
- ;
- ; PutDriver_asm sets or cleared the relay driver channel selected
- ; by PutDriver_Channel. It has to pull up the previous 4 bits of
- ; the channel group, set or clear the specified channel bit, store
- ; the updated nibble and shift it out to the drivers.
- ;
- PutDriver_asm:
- push ax
- cmp al,0 ; convert al to one or zero
- je zero
- mov al,00000001B ; OR mask for one
- mov ah,11111111B ; AND mask for one
- jmp one
- zero:
- mov al,00000000B ; OR mask for zero
- mov ah,11111110B ; AND mask for zero
- one:
- mov cl,[driver_bit] ; get bit position
- bit_shift:
- cmp cl,0 ; done?
- je done_shifting
- rol al,1
- rol ah,1
- dec cl
- jmp bit_shift ; now our bit is in the same position
- ; as in the nibble we will shift out
- done_shifting:
- mov si,[driver_bit_ptr] ; get pointer to our nibble
- mov bl,[si] ; get our nibble
- or bl,al ; do the OR
- and bl,ah ; do the AND
- mov [si],bl ; store the updated nibble
- push bx
- mov bh,[driver_board] ; select the 4 bit group
- mov bl,[driver_side] ; from the channel specified
- mov al,[driver_chip] ; by PutDriverChannel
- call select
- pop bx
- shl bl,1 ; left justify the data
- shl bl,1
- shl bl,1
- shl bl,1
- and bl,0F0h ; get rid of any garbage
- mov al,40h ; set data low
- mov dx,0F862h
- out dx,al
- mov dx,0F864h ; configure all pins as outputs
- mov al,0 ;
- out dx,al
- mov cl,5 ; loop counter
- rcl bl,1 ; get the first data bit in carry
- mov dx,0F862h ; output port
- shift_loop:
- mov al,60h ; clk hi with data zero
- jnc data_low ; all done if carry is 0
- mov al,70h ; clk hi with data one
- data_low:
- out dx,al ; do it
- and al,0D0h ; lower clk
- out dx,al ; send it
- rcl bl,1 ; rotate
- dec cl
- jnz shift_loop
- call bus_reset
- pop ax ; restore caller's value
- ret
- ;-------------------------------------------------------------------------
- ;
- ; PutUARTChannel_asm - Selects the current UART, 0-15
- ;
- PutUARTChannel_asm:
- push ax ; save a copy for caller
- mov ah,al ; and another copy for here
- and al,00001111B ; 16 max
- mov bl,al ; form side number
- and al,00000001B
- mov [uart_side],al
- mov bh,ah ; form board number
- shr bh,1
- and bh,00000111B
- mov [uart_board],bh
- pop ax ; set pointer to write config word
- push ax
- mov si,offset uart_cmd
- shl ax,1
- and ax,01Eh ; 16 entries max
- add si,ax
- mov [uart_cmd_ptr],si
- pop ax
- ret
- ;-------------------------------------------------------------------------
- ;
- ; PutUARTChar_asm - Sends the char in al out the current UART - blocking
- ;
- PutUARTChar_asm:
- push ax
- call send_char_wait
- pop ax
- ret
- ;-------------------------------------------------------------------------
- ;
- ; PutUARTBaud_asm - Sets the baud rate for the current UART
- ;
- PutUARTBaud_asm:
- push ax
- mov si,offset baud_table ; point to the baud rate translation
- baud_loop: ; table
- cmp ax,[si] ; get entry
- je found_baud ; match?
- cmp [si],word ptr 0 ; no, last entry?
- je baud_not_found ; yes, all done
- add si,4 ; no, index to next entry
- jmp baud_loop ; and back through
- found_baud: ; we have a match
- add si,2 ; point to uart baud code
- mov bx,[si] ; get it
- mov si,[uart_cmd_ptr] ; point to the previous uart command
- mov ax,[si] ; get it
- and ax,0FFF0h ; clear the baud bits
- or ax,bx ; OR in the selected baud
- mov [si],ax ; store it
- call set_uart ; and send it
- baud_not_found:
- pop ax
- ret
- ;-------------------------------------------------------------------------
- ;
- ; GetUARTRxStatus - Get Rx status bit in AX, 1 equals char waiting
- ;
- GetUARTRxStatus_asm:
- call GetUARTRC_asm
- rol ax,1
- and ax,1
- ret
- ;-------------------------------------------------------------------------
- ;
- ; GetUARTTxStatus - Get TX status bit in AX, 1 equals ok to send
- ;
- GetUARTTxStatus_asm:
- call GetUARTRC_asm
- rol ax,1
- rol ax,1
- and ax,1
- ret
- ;-------------------------------------------------------------------------
- ;
- ; GetUARTChar_asm - Gets a char from the current UART - blocking
- ;
- GetUARTChar_asm:
- call get_char_status ; char available?
- jnc GetUARTChar_asm ; no, loop checking
- call get_char ; yes, get it
- mov ah,0
- ret
- ;-------------------------------------------------------------------------
- ;
- ; PutUARTWC_asm - Writes AX to the write configuration reg of the
- ; current UART
- ;
- PutUARTWC_asm:
- mov bx,ax
- or bl,11000000b ; make sure top 2 bits are set
- mov [uart_cmd_ptr],bx ; store it for next time
- call uart
- mov ax,bx
- ret
- ;-------------------------------------------------------------------------
- ;
- ; PutUARTWD_asm - Writes AX to the Write Data reg of the current UART
- ;
- PutUARTWD_asm:
- mov bx,ax
- or bl,10000000b ; make sure bit 15 is set
- and bl,10111111b ; and bit 14 is cleared
- call uart
- mov ax,bx
- ret
- ;-------------------------------------------------------------------------
- ;
- ; GetUARTRC_asm - Returns the read configuration register in AX from
- ; the current UART
- ;
- GetUARTRC_asm:
- mov bx,4000h
- call uart
- mov ax,bx
- ret
- ;-------------------------------------------------------------------------
- ;
- ; GetUARTRD_asm - Returns the read data register in AX from the
- ; current UART
- ;
- GetUARTRD_asm:
- mov bx,0
- call uart
- mov ax,bx
- ret
- ;-------------------------------------------------------------------------
- ;
- ; Send_Char_Wait - Checks to see if it's ok to send a char, if it
- ; is, sends the char in AL. If not, waits til ok
- ; then sends char in AL.
- ;
- send_char_wait:
- call send_char_status ; ok to send?
- jnc send_char_wait ; no, loop checking
- call send_char ; yes, send it
- ret
- ;-------------------------------------------------------------------------
- ;
- ; Send_Char_Status - Returns with carry set if ok to send char
- ;
- send_char_status:
- push ax
- push bx ; needed for uart command
- mov bx,4000h ; read data register cmd
- call uart ; do it
- shl bh,1 ; get the T bit
- shl bh,1 ; in carry
- pop bx ; restore bx
- pop ax
- ret
- ;-------------------------------------------------------------------------
- ;
- ; Send_Char - Unconditionally sends char in AL
- ;
- send_char:
- push ax ; save AX
- mov bl,al ; move the char to BL
- mov bh,80h ; send command
- call uart ; send it
- pop ax
- ret
- ;-------------------------------------------------------------------------
- ;
- ; Get_Char_Status - Returns with carry flag set if char available
- ;
- get_char_status:
- push bx ; needed for uart command
- mov bx,4000 ; read data register cmd
- call uart ; do it
- shl bh,1 ; get the R bit
- pop bx ; restore bx
- ret
- ;-------------------------------------------------------------------------
- ;
- ; Get_Char - Gets a char from UART without testing. Char returned
- ; in AL.
- ;
- get_char:
- push bx ; needed for uart command
- mov bx,0 ; read data register cmd
- call uart ; do it
- mov al,bl ; we have data, move to al
- pop bx ; restore bx
- ret
- ;-------------------------------------------------------------------------
- ;
- ; Set_UART - Sends AX to the UART write config reg
- ;
- set_uart:
- push ax ; data is passed to uart in bx
- mov bx,ax
- call uart
- pop ax
- ret
- ;-------------------------------------------------------------------------
- ;
- ; Uart - Simultaneously shift in and out the 16 bit value in BX
- ;
- uart:
- push ax
- push cx
- push dx
- push bx
- mov bh,byte ptr [uart_board] ; get board, side and chip from mem
- mov bl,byte ptr [uart_side]
- mov al,byte ptr [uart_chip]
- call select
- mov al,40h ; set data low
- mov dx,0F862h
- out dx,al
- mov dx,0F864h ; configure data as open-drain
- mov al,10h ; CLK, RESET, and CS as comp. out
- out dx,al
- pop bx
- mov cl,16 ; loop counter
- rcl bx,1 ; get the first data bit in carry
- u_shift_loop:
- mov al,40h ; low clock, data 0
- jnc u_data_low ; all done if carry is 0
- mov al,50h ; no, make data 1
- u_data_low:
- mov dx,0F862h ; drive it out
- out dx,al
- mov al,70h ; raise clk and data
- out dx,al ; drive it out
- mov dx,0F860h
- in al,dx ; get our data
- rcl al,1
- rcl al,1
- rcl al,1
- rcl al,1
- rcl bx,1 ; rotate
- dec cl
- jnz u_shift_loop
- call bus_reset
- pop dx
- pop cx
- pop ax
- ret
- ;-------------------------------------------------------------------------
- ;
- ; Select - Activates the chip select for the proper device
- ; BH = Board to select, 0 - 8
- ; BL = Side to select, 0 - 1
- ; AL = Chip Select, 0 - 5
- ;
- select:
- call bus_reset ; reset the bus to start
- push ax ; save the chip select
- mov cl,bh ; get board in cl
- board_select_loop:
- cmp cl,0 ; any to do
- je side_select ; no, do the side
- mov al,7 ; select next board
- call bus_channel ; do it
- dec cl ; decrement board count
- jmp board_select_loop ; and loop
- side_select:
- cmp bl,0 ; if zero, don't do anything
- je chip_select
- mov al,6 ; select side 1
- call bus_channel
- chip_select:
- pop ax ; get the chip select
- call bus_channel ; and do it
- ret
- ;-------------------------------------------------------------------------
- ;
- ; Reset - send a reset pulse to all of the decoders on the bus
- ;
- bus_reset:
- push ax
- push dx
- mov dx,0F862h ; put a zero in the output ports
- mov al,0
- out dx,al
- mov dx,0F864h ; select all outputs
- out dx,al
- mov dx,0F862h
- mov al,40h ; lift reset
- out dx,al
- pop dx
- pop ax
- ret
- ;-------------------------------------------------------------------------
- ;
- ; Select selects the channel passed in AL
- ;
- bus_channel:
- push bx
- push si ; going to need some registers
- push dx
- push ax
- mov bl,al ; channel needs to go into bl
- mov bh,0
- shl bl,1 ; multiply bl times 8 for proper
- shl bl,1 ; table offset
- shl bl,1
- mov si,offset select_table ; point to first entry
- add si,bx ; add in offset
- mov bx,8 ; loop counter now
- mov dx,0F862h ; point to port
- send_loop:
- mov al,cs:[si] ; get the byte
- out dx,al ; send it
- inc si ; bump pointer
- dec bx ; unbump counter
- jnz send_loop ; done?
- mov al,050h ; idle the bus
- out dx,al
- pop ax
- pop dx
- pop si
- pop bx
- ret
- ;-----------------------------------------------------------------------------
- ;
- ; New_stack sets up a new stack and saves all of the caller's
- ; registers except AX. DS and ES are set to the same code
- ; segment as CS.
- ;
- new_stack:
- mov cs:[old_ax],ax ; preserve ax
- mov cs:[old_bx],bx ; and bx
- pop bx ; get our return in bx
- cli ; interrupts off while changing stack
- mov ax,ss ; get stack seg
- mov cs:[old_ss],ax ; store it
- mov cs:[old_sp],sp ; store old stack pointer
- mov ax,cs ; get our code seg
- mov ss,ax ; set our stack seg to it
- mov sp,offset top_stack ; point to our stack
- sti
- push cx ; save caller's registers
- push dx
- push si
- push di
- push bp
- push ds
- push es
- push bx ; push caller's return adddress
- mov ds,ax ; set small model ds and es
- mov es,ax
- mov ax,cs:[old_ax] ; restore ax
- mov bx,cs:[old_bx] ; and bx
- ret ; and return to caller
- ;-----------------------------------------------------------------------------
- ;
- ; Old_stack restores the old stack and the caller's registers
- ; except AX.
- ;
- old_stack:
- mov cs:[old_ax],ax ; preserve ax
- pop bx ; get our return in bx
- pop es ; restore caller's registers
- pop ds
- pop bp
- pop di
- pop si
- pop dx
- pop cx
- cli ; interrupts off while changing stack
- mov sp,cs:[old_sp] ; get old stack pointer
- mov ax,cs:[old_ss] ; get old stack seg
- mov ss,ax ; install it
- sti
- push bx ; push caller's return address
- mov ax,cs:[old_ax] ; restore ax
- mov bx,cs:[old_bx] ; and bx
- ret ; and return to caller
- old_ax dw 0 ; temp register storage for
- old_bx dw 0 ; new_stack and old_stack
- old_sp dw 0
- old_ss dw 0
- dw 200h dup(0) ; new stack
- top_stack:
- end