mirror of
https://github.com/SEPPDROID/DR-DOS-OpenDOS.git
synced 2025-10-22 07:54:28 +00:00
333 lines
9.1 KiB
NASM
333 lines
9.1 KiB
NASM
; File : $Workfile: SERPAR.ASM$
|
|
;
|
|
; Description :
|
|
;
|
|
; Original Author : DIGITAL RESEARCH
|
|
;
|
|
; Last Edited By : $CALDERA$
|
|
;
|
|
;-----------------------------------------------------------------------;
|
|
; Copyright Work of Caldera, Inc. All Rights Reserved.
|
|
;
|
|
; THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
|
|
; PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
|
|
; ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
|
|
; WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
|
|
; THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
|
|
; HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
|
|
; AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
|
|
; AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
|
|
; COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
|
|
; CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
|
|
; TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
|
|
; CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
|
|
; AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
|
|
; CIVIL LIABILITY.
|
|
;-----------------------------------------------------------------------;
|
|
;
|
|
; *** Current Edit History ***
|
|
; *** End of Current Edit History ***
|
|
;
|
|
; $Log$
|
|
; SERPAR.ASM 1.7 93/07/22 19:44:27
|
|
; switch over to REQUEST.EQU
|
|
; SERPAR.ASM 1.6 93/07/19 18:57:59
|
|
; Add header
|
|
;
|
|
; ENDLOG
|
|
|
|
include BIOSGRPS.EQU
|
|
include DRMACROS.EQU ; standard DR macros
|
|
include IBMROS.EQU ; ROM BIOS equates
|
|
include REQUEST.EQU ; request header equates
|
|
include DRIVER.EQU ; device driver equates
|
|
|
|
page
|
|
CGROUP group CODE, RCODE, ICODE
|
|
|
|
CG equ offset CGROUP
|
|
|
|
Assume CS:CGROUP, DS:CGROUP, ES:CGROUP, SS:CGROUP
|
|
|
|
CODE segment 'CODE'
|
|
|
|
extrn endbios:word ; for device driver INIT function
|
|
extrn serparFlag:byte
|
|
extrn serparChar:byte
|
|
|
|
CODE ends
|
|
|
|
RCODE segment 'RCODE'
|
|
|
|
Public SerParCommonTable
|
|
|
|
SerParCommonTable:
|
|
db 19 ; Last supported function
|
|
dw CG:dd_init ; 0-initialize driver
|
|
dw CG:dd_error ; 1-media change check (disks only)
|
|
dw CG:dd_error ; 2-build BPB (disks only)
|
|
dw CG:dd_error ; 3-IOCTL string input
|
|
dw CG:dd_input ; 4-input
|
|
dw CG:dd_poll ; 5-nondestructive input (char only)
|
|
dw CG:dd_instat ; 6-input status (char only)
|
|
dw CG:dd_inflush ; 7-input flush
|
|
dw CG:dd_output ; 8-output
|
|
dw CG:dd_output ; 9-output with verify
|
|
dw CG:dd_outstat ; 10-output status (char only)
|
|
dw CG:dd_outflush ; 11-output flush (char only)
|
|
dw CG:dd_error ; 12-IOCTL string output
|
|
dw CG:dd_open ; 13-device open
|
|
dw CG:dd_close ; 14-device close
|
|
dw CG:dd_error ; 15-removable media check (disks only)
|
|
dw CG:dd_error ; 16-n/a
|
|
dw CG:dd_error ; 17-n/a
|
|
dw CG:dd_error ; 18-n/a
|
|
dw CG:dd_genioctl ; 19-generic IOCTL
|
|
|
|
|
|
Assume DS:CGROUP, ES:Nothing, SS:Nothing
|
|
|
|
page
|
|
driver proc near
|
|
|
|
dd_error: ; used for all unsupported driver functions
|
|
;--------
|
|
mov ax,RHS_ERROR+3 ; "invalid command" error
|
|
ret
|
|
|
|
page
|
|
|
|
poll_char:
|
|
;---------
|
|
; exit: ZF = 1 => no character ready
|
|
; ZF = 0 => AL = character
|
|
|
|
cmp serparFlag[si],TRUE ; do we have local character?
|
|
jne poll_c2 ; skip if not
|
|
mov al,serparChar[si] ; get the local charcater
|
|
jmps poll_c4 ; and return it
|
|
poll_c2: ; need to check ROS keyboard status
|
|
mov ah,3 ; get serial status status
|
|
int ASYNC_INT ; read serial status
|
|
test ah,1 ; test "received data" bit
|
|
jz poll_c9 ; skip if no character there
|
|
mov ah,2 ; read the character
|
|
int ASYNC_INT ; character returned in AL
|
|
mov serparChar[si],al ; save it for look ahead
|
|
mov serparFlag[si],TRUE ; we've got a local character
|
|
poll_c4: ; return the character in AL
|
|
or ah,TRUE ; indicate "ready" status
|
|
ret
|
|
poll_c9:
|
|
sub ax,ax ; indicate "not-ready" status
|
|
ret ; (driver is busy)
|
|
|
|
|
|
char_read:
|
|
;---------
|
|
xor ax,ax
|
|
cmp serparFlag[si],TRUE ; do we have local character?
|
|
jne rdchr1
|
|
mov serparFlag[si],FALSE ; tell them buffer is invalid
|
|
mov al,serparChar[si] ; get the local character
|
|
ret ; and return it
|
|
rdchr1:
|
|
mov ah,2 ; read character from serial port
|
|
int ASYNC_INT ; call the ROM BIOS
|
|
and ah,0eh ; only worry about these error bits
|
|
ret ; and return the character
|
|
|
|
page
|
|
dd_input: ; 4-input
|
|
;--------
|
|
push es ; save ES (-> request header!)
|
|
mov cx,es:RH4_COUNT[bx] ; get # of characters to output
|
|
jcxz input9 ; return if nothing to input
|
|
sub dx,3 ; convert to serial port #
|
|
jb input9 ; return none read if parallel port
|
|
mov si,dx ; SI = serial port index
|
|
les di,es:RH4_BUFFER[bx] ; get address of string to input
|
|
input2:
|
|
call char_read ; read 8-bit character
|
|
test ah,ah ; did we read OK ?
|
|
jnz input9 ; if we have an error stop now
|
|
stosb ; store it in input buffer
|
|
loop input2 ; repeat for all characters
|
|
input9:
|
|
pop es
|
|
sub es:RH4_COUNT[bx],cx ; update to actual number xfered
|
|
sub ax,ax
|
|
ret
|
|
|
|
dd_poll: ; 5-nondestructive input (console only)
|
|
;-------
|
|
cmp dx,3 ; check if a parallel port
|
|
jb poll_busy ; they are never ready
|
|
sub dx,3
|
|
mov si,dx ; SI = serial port index
|
|
call poll_char ; check keyboard status
|
|
jz poll_busy
|
|
mov es:RH5_CHAR[bx],al ; return the character
|
|
sub ax,ax
|
|
ret
|
|
poll_busy:
|
|
mov ax,RHS_BUSY ; indicate no character waiting
|
|
ret
|
|
|
|
dd_instat: ; 6-input status (char only)
|
|
;---------
|
|
cmp dx,3 ; check if a parallel port
|
|
jb poll_busy ; if so it's always busy
|
|
sub dx,3
|
|
mov si,dx ; SI = serial port index
|
|
call poll_char ; check keyboard status
|
|
jz poll_busy
|
|
sub ax,ax ; indicate "not ready" status
|
|
ret
|
|
|
|
dd_inflush: ; 7-input flush
|
|
;---------
|
|
cmp dx,3 ; check if a parallel port
|
|
jae inflsh1 ; skip if serial port
|
|
mov ax,RHS_ERROR+11 ; return "read error" if attempting
|
|
ret ; to read from the parallel port
|
|
inflsh1:
|
|
sub dx,3
|
|
mov si,dx ; SI = serial port index
|
|
inflsh2:
|
|
call poll_char ; check keyboard status
|
|
jz inflsh_ret ; skip if not ready
|
|
call char_read ; else read next character
|
|
jmps inflsh2 ; repeat until buffer empty
|
|
inflsh_ret: ; keyboard buffer empty
|
|
sub ax,ax ; return success
|
|
ret
|
|
|
|
dd_output: ; 8-output
|
|
;---------
|
|
mov cx,es:RH4_COUNT[bx] ; get # of characters to output
|
|
jcxz output5 ; return if nothing to output
|
|
push es ; save ES (-> request header!)
|
|
les si,es:RH4_BUFFER[bx] ; get address of string to output
|
|
sub dx,3 ; test if parallel port
|
|
jae output2 ; skip if serial port
|
|
add dx,3 ; back to parallel port number
|
|
output1:
|
|
lods es:byte ptr [si] ; get next character to output
|
|
mov ah,0 ; output AL to parallel port
|
|
int PRINTER_INT ; output to parallel port
|
|
mov al,2 ; "not ready" error
|
|
test ah,PRN_TIMEOUT ; printer not ready?
|
|
jnz output4 ; yes, return error
|
|
mov al,9 ; "printer out of paper" error
|
|
test ah,PRN_PAPER ; printer out paper?
|
|
jnz output4 ; yes, return error
|
|
inc ax ; "write fault" error
|
|
test ah,PRN_ERROR ; test if other errors
|
|
jnz output4 ; skip if any errors occurred
|
|
loop output1 ; else repeat for all characters
|
|
jmps output4 ; return successfully when done
|
|
|
|
output2: ; output is for serial port
|
|
lods es:byte ptr [si] ; get next character to output
|
|
mov ah,1 ; output AL to serial port
|
|
int ASYNC_INT ; output to serial port
|
|
mov al,2 ; "not ready" error
|
|
test ah,AUX_ERROR ; test if time out etc.
|
|
jnz output4 ; skip if any errors occurred
|
|
loop output2 ; else repeat for all characters
|
|
output4:
|
|
mov ah,RHS_ERROR shr 8 ; assume an error code
|
|
pop es
|
|
sub es:RH4_COUNT[bx],cx ; update to actual number xfered
|
|
jz output6 ; none xfered is an error
|
|
output5:
|
|
sub ax,ax ; return successfully when done
|
|
output6:
|
|
ret
|
|
|
|
|
|
|
|
dd_outstat: ; 10-output status (char only)
|
|
;----------
|
|
cmp dx,3 ; test if parallel port
|
|
jae outstat1
|
|
mov ah,2 ; read parallel port status
|
|
int PRINTER_INT ; call the ROM BIOS
|
|
test ah,80h ; test "not busy" bit
|
|
jnz outstat_ready ; if not busy then ready for output
|
|
jmps outstat_busy ; else we must be still busy
|
|
outstat1:
|
|
sub dx,3
|
|
mov ah,3 ; get status for serial port
|
|
int ASYNC_INT
|
|
test ah,20h ; transmit buffer register emmpty?
|
|
jz outstat_busy
|
|
test al,20h ; data set ready?
|
|
jz outstat_busy
|
|
outstat_ready:
|
|
sub ax,ax ; always ready, return no busy
|
|
ret
|
|
outstat_busy:
|
|
mov ax,RHS_BUSY
|
|
ret
|
|
|
|
dd_outflush: ; 11-output flush (char only)
|
|
;-----------
|
|
sub ax,ax ; unbuffered, perform no operation
|
|
ret
|
|
|
|
|
|
page
|
|
dd_open: ; 13-device open
|
|
;-------
|
|
sub ax,ax ; no operation
|
|
ret
|
|
|
|
|
|
dd_close: ; 14-device close
|
|
;--------
|
|
sub ax,ax ; no operation
|
|
ret
|
|
|
|
|
|
page
|
|
dd_genioctl: ; 19-generic IOCTL
|
|
;-----------
|
|
sub ax,ax
|
|
ret
|
|
|
|
driver endp
|
|
|
|
RCODE ends ; end of device driver code
|
|
|
|
page
|
|
|
|
ICODE segment 'ICODE' ; initialization code
|
|
|
|
dd_init: ; 0-initialize driver
|
|
;-------
|
|
cmp dx,3 ; check if serial or parallel
|
|
jae init1 ; skip if serial port setup
|
|
mov ah,1 ; initialize parallel port
|
|
int PRINTER_INT ; call the ROM BIOS
|
|
jmps init2
|
|
init1:
|
|
sub dx,3
|
|
mov ah,0 ; initialize serial port
|
|
mov al,0A3h ; 2400 Bd, no parity, 8 data, 1 stop
|
|
int ASYNC_INT ; call the ROM BIOS
|
|
init2:
|
|
les bx,REQUEST[bp] ; ES:BX -> request header
|
|
|
|
mov ax,endbios
|
|
mov es:RH0_RESIDENT[bx],ax ; set end of device driver
|
|
mov es:RH0_RESIDENT+2[bx],ds
|
|
|
|
sub ax,ax ; initialization succeeded
|
|
ret ; (BIOS init always does...)
|
|
|
|
ICODE ends
|
|
|
|
end
|