1079 lines
27 KiB
NASM
1079 lines
27 KiB
NASM
page ,160
|
|
title mschar - character and clock devices
|
|
;
|
|
;----------------------------------------------------------------------------
|
|
;
|
|
;
|
|
; 26-Feb-1991 sudeepb Ported for NT DOSEm
|
|
;
|
|
;----------------------------------------------------------------------------
|
|
;
|
|
|
|
.xlist
|
|
|
|
include version.inc ; set build flags
|
|
include biosseg.inc ; establish bios segment structure
|
|
|
|
include msequ.inc
|
|
include devsym.inc
|
|
include ioctl.inc
|
|
include vint.inc
|
|
|
|
break macro
|
|
endm
|
|
|
|
include biosbop.inc
|
|
|
|
include error.inc
|
|
.list
|
|
|
|
include msgroup.inc ; define Bios_Data segment
|
|
|
|
|
|
extrn ptrsav:dword
|
|
|
|
extrn altah:byte
|
|
extrn keyrd_func:byte
|
|
extrn keysts_func:byte
|
|
|
|
extrn auxnum:word
|
|
extrn auxbuf:byte
|
|
|
|
extrn wait_count:word
|
|
extrn printdev:byte
|
|
extrn Old10:dword
|
|
extrn spc_mse_int10:dword
|
|
extrn int29Perf:dword
|
|
|
|
|
|
; close Bios_Data and open Bios_Code segment
|
|
|
|
tocode
|
|
|
|
extrn bc_cmderr:near
|
|
extrn bc_err_cnt:near
|
|
|
|
MODE_CTRLBRK equ 0ffh ; M013
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* device driver dispatch tables *
|
|
;* *
|
|
;* each table starts with a byte which lists the number of *
|
|
;* legal functions, followed by that number of words. Each *
|
|
;* word represents an offset of a routine in Bios_Code which *
|
|
;* handles the function. The functions are terminated with *
|
|
;* a near return. If carry is reset, a 'done' code is returned *
|
|
;* to the caller. If carry is set, the ah/al registers are *
|
|
;* returned as abnormal completion status. Notice that ds *
|
|
;* is assumed to point to the Bios_Data segment throughout. *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
public con_table
|
|
con_table:
|
|
db (((offset con_table_end) - (offset con_table) - 1)/2)
|
|
dw bc_exvec ; 00 init
|
|
dw bc_exvec ; 01
|
|
dw bc_exvec ; 02
|
|
dw bc_cmderr ; 03
|
|
dw con_read ; 04
|
|
dw con_rdnd ; 05
|
|
dw bc_exvec ; 06
|
|
dw con_flush ; 07
|
|
dw con_writ ; 08
|
|
dw con_writ ; 09
|
|
dw bc_exvec ; 0a
|
|
con_table_end:
|
|
|
|
public prn_table
|
|
prn_table label byte
|
|
db (((offset prn_table_end) - (offset prn_table) -1)/2)
|
|
dw bc_exvec ; 00 init
|
|
dw bc_exvec ; 01
|
|
dw bc_exvec ; 02
|
|
dw bc_cmderr ; 03
|
|
dw prn_input ; 04 indicate zero chars read
|
|
dw z_bus_exit ; 05 read non-destructive
|
|
dw bc_exvec ; 06
|
|
dw bc_exvec ; 07
|
|
dw prn_writ ; 08
|
|
dw prn_writ ; 09
|
|
dw prn_stat ; 0a
|
|
dw bc_exvec ; 0b
|
|
dw bc_exvec ; 0c
|
|
dw prn_open ; 0d
|
|
dw prn_close ; 0e
|
|
dw bc_exvec ; 0f
|
|
dw prn_tilbusy ; 10
|
|
dw bc_exvec ; 11
|
|
dw bc_exvec ; 12
|
|
dw prn_genioctl ; 13
|
|
dw bc_exvec ; 14
|
|
dw bc_exvec ; 15
|
|
dw bc_exvec ; 16
|
|
dw bc_exvec ; 17
|
|
dw bc_exvec ; 18
|
|
dw prn_ioctl_query ; 19
|
|
prn_table_end:
|
|
|
|
|
|
|
|
public aux_table
|
|
aux_table label byte
|
|
db (((offset aux_table_end) - (offset aux_table) -1)/2)
|
|
|
|
dw bc_exvec ; 00 - init
|
|
dw bc_exvec ; 01
|
|
dw bc_exvec ; 02
|
|
dw bc_cmderr ; 03
|
|
dw aux_read ; 04 - read
|
|
dw aux_rdnd ; 05 - read non-destructive
|
|
dw bc_exvec ; 06
|
|
dw aux_flsh ; 07
|
|
dw aux_writ ; 08
|
|
dw aux_writ ; 09
|
|
dw aux_wrst ; 0a
|
|
aux_table_end:
|
|
|
|
|
|
public tim_table
|
|
tim_table label byte
|
|
db (((offset tim_table_end) - (offset tim_table) -1)/2)
|
|
dw bc_exvec ; 00
|
|
dw bc_exvec ; 01
|
|
dw bc_exvec ; 02
|
|
dw bc_cmderr ; 03
|
|
dw bc_cmderr ; 04
|
|
dw z_bus_exit ; 05
|
|
dw bc_exvec ; 06
|
|
dw bc_exvec ; 07
|
|
dw bc_cmderr ; 08
|
|
dw bc_cmderr ; 09
|
|
tim_table_end:
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* con_read - read cx bytes from keyboard into buffer at es:di *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
con_read proc near
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
jcxz con_exit
|
|
|
|
con_loop:
|
|
call chrin ;get char in al
|
|
stosb ;store char at es:di
|
|
loop con_loop
|
|
|
|
con_exit:
|
|
clc
|
|
ret
|
|
con_read endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* chrin - input single char from keyboard into al *
|
|
;* *
|
|
;* we are going to issue extended keyboard function, if *
|
|
;* supported. the returning value of the extended keystroke *
|
|
;* of the extended keyboard function uses 0e0h in al *
|
|
;* instead of 00 as in the conventional keyboard function. *
|
|
;* this creates a conflict when the user entered real *
|
|
;* greek alpha charater (= 0e0h) to distinguish the extended *
|
|
;* keystroke and the greek alpha. this case will be handled *
|
|
;* in the following manner: *
|
|
;* *
|
|
;* ah = 16h *
|
|
;* int 16h *
|
|
;* if al == 0, then extended code (in ah) *
|
|
;* else if al == 0e0h, then *
|
|
;* if ah <> 0, then extended code (in ah) *
|
|
;* else greek_alpha character. *
|
|
;* *
|
|
;* also, for compatibility reason, if an extended code is *
|
|
;* detected, then we are going to change the value in al *
|
|
;* from 0e0h to 00h. *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
|
|
chrin proc near
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
mov ah,keyrd_func ; set by msinit. 0 or 10h
|
|
xor al,al
|
|
xchg al,altah ;get character & zero altah
|
|
|
|
or al,al
|
|
jnz keyret
|
|
|
|
int 16h ; do rom bios keyrd function
|
|
|
|
alt10:
|
|
or ax,ax ;check for non-key after break
|
|
jz chrin
|
|
|
|
cmp ax,7200h ;check for ctrl-prtsc
|
|
jnz alt_ext_chk
|
|
|
|
mov al,16
|
|
jmp short keyret
|
|
|
|
alt_ext_chk:
|
|
|
|
;**************************************************************
|
|
; if operation was extended function (i.e. keyrd_func != 0) then
|
|
; if character read was 0e0h then
|
|
; if extended byte was zero (i.e. ah == 0) then
|
|
; goto keyret
|
|
; else
|
|
; set al to zero
|
|
; goto alt_save
|
|
; endif
|
|
; endif
|
|
; endif
|
|
|
|
cmp byte ptr keyrd_func,0
|
|
jz not_ext
|
|
cmp al,0e0h
|
|
jnz not_ext
|
|
|
|
or ah,ah
|
|
jz keyret
|
|
ifdef DBCS
|
|
ifdef KOREA ; Keyl 1990/11/5
|
|
cmp ah, 0f0h ; If hangeul code range then
|
|
jb EngCodeRange1 ; do not modify any value.
|
|
cmp ah, 0f2h
|
|
jbe not_ext
|
|
EngCodeRange1:
|
|
endif ; KOREA
|
|
endif ; DBCS
|
|
xor al,al
|
|
jmp short alt_save
|
|
|
|
not_ext:
|
|
|
|
or al,al ;special case?
|
|
jnz keyret
|
|
|
|
alt_save:
|
|
mov altah,ah ;store special key
|
|
keyret:
|
|
ret
|
|
chrin endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* con_rdnd - keyboard non destructive read, no wait *
|
|
;* *
|
|
;* pc-convertible-type machine: if bit 10 is set by the dos *
|
|
;* in the status word of the request packet, and there is no *
|
|
;* character in the input buffer, the driver issues a system *
|
|
;* wait request to the rom. on return from the rom, it returns *
|
|
;* a 'char-not-found' to the dos. *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
con_rdnd proc near
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
mov al,[altah]
|
|
or al,al
|
|
jnz rdexit
|
|
|
|
mov ah,keysts_func ; keyboard i/o interrupt - get
|
|
int 16h ; keystroke status (keysts_func)
|
|
jnz gotchr
|
|
|
|
;
|
|
; pc-convertible checking is not needed on NTVDM
|
|
; if no key in buff return immediatly with busy status
|
|
;04-Aug-1992 Jonle
|
|
;
|
|
; cmp fhavek09,0
|
|
; jz z_bus_exit ; return with busy status if not k09
|
|
;
|
|
; les bx,[ptrsav]
|
|
; assume es:nothing
|
|
; test es:[bx].status,0400h ; system wait enabled?
|
|
; jz z_bus_exit ; return with busy status if not
|
|
;
|
|
; need to wait for ibm response to request for code
|
|
; on how to use the system wait call.
|
|
;
|
|
; mov ax,4100h ; wait on an external event
|
|
; xor bl,bl ; M055; wait for any event
|
|
; int 15h ; call rom for system wait
|
|
|
|
z_bus_exit:
|
|
stc
|
|
mov ah,3 ; indicate busy status
|
|
ret
|
|
|
|
gotchr:
|
|
or ax,ax
|
|
jnz notbrk ;check for null after break
|
|
|
|
mov ah,keyrd_func ; issue keyboard read function
|
|
int 16h
|
|
jmp con_rdnd ;and get a real status
|
|
|
|
notbrk:
|
|
cmp ax,7200h ;check for ctrl-prtsc
|
|
jnz rd_ext_chk
|
|
|
|
mov al,'P' and 1fh ; return control p
|
|
jmp short rdexit
|
|
|
|
rd_ext_chk:
|
|
cmp keyrd_func,0 ; extended keyboard function?
|
|
jz rdexit ; no. normal exit.
|
|
|
|
cmp al,0e0h ; extended key value or greek alpha?
|
|
jne rdexit
|
|
|
|
ifdef DBCS
|
|
ifdef KOREA
|
|
cmp ah, 0f0h ; If hangeul code range then
|
|
jb EngCodeRange ; do not modify any value.
|
|
cmp ah, 0f2h
|
|
jbe rdexit ; Keyl 90/11/5
|
|
EngCodeRange:
|
|
endif ; KOREA
|
|
endif ; DBCS
|
|
|
|
cmp ah,0 ; scan code exist?
|
|
jz rdexit ; yes. greek alpha char.
|
|
mov al,0 ; no. extended key stroke.
|
|
; change it for compatibility
|
|
|
|
rdexit:
|
|
les bx,[ptrsav]
|
|
assume es:nothing
|
|
mov es:[bx].media,al ; *** return keyboard character here
|
|
|
|
bc_exvec:
|
|
clc ; indicate normal termination
|
|
ret
|
|
|
|
con_rdnd endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* con_write - console write routine *
|
|
;* *
|
|
;* entry: es:di -> buffer *
|
|
;* cx = count *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
con_writ proc near
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
jcxz bc_exvec
|
|
|
|
push es
|
|
|
|
mov bx,word ptr [int29Perf]
|
|
mov dx,word ptr [int29Perf+2] ;DX:BX is original INT 29h vector
|
|
sub ax,ax
|
|
mov es,ax
|
|
cmp BX,es:[29h*4+0]
|
|
jne con_lp1 ; if not the same do single int10s
|
|
cmp DX,es:[29h*4+2]
|
|
jne con_lp1 ; if not the same do single int10s
|
|
mov bx,word ptr [spc_mse_int10]
|
|
mov dx,word ptr [spc_mse_int10+2] ;DX:BX is original INT 10h vector
|
|
cmp BX,es:[10h*4+0]
|
|
jne con_lp1 ; if not the same do single int10s
|
|
cmp DX,es:[10h*4+2]
|
|
jne con_lp1 ; if not the same do single int10s
|
|
|
|
pop es
|
|
|
|
; Sudeepb 21-Jul-1992: We know that no one has hooked in10 so we
|
|
; can optimize it by calling a private in1t10h which takes a full
|
|
; string, displays it with the same attribute as present on the
|
|
; screen and moves the cursor to the end.
|
|
|
|
mov ax,46h ; sounds like a good flag value
|
|
push ax ; make an iret frame
|
|
push cs
|
|
mov ax, offset ret_adr
|
|
push ax
|
|
push dx ; dx:bx is pointing to softpc int10 handler
|
|
push bx ; make the retf frame
|
|
mov ax,13FFh ; AH = WRITESTRING, AL = subfunction
|
|
retf
|
|
ret_adr:
|
|
jmp short cc_ret
|
|
|
|
con_lp1:
|
|
pop es
|
|
|
|
con_lp:
|
|
mov al,es:[di] ;get char
|
|
inc di
|
|
int chrout ;output char
|
|
loop con_lp ;repeat until all through
|
|
|
|
cc_ret:
|
|
clc
|
|
ret
|
|
con_writ endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* con_flush - flush out keyboard queue *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
public con_flush ; called from msbio2.asm for floppy swapping
|
|
con_flush proc near
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
|
|
mov [altah],0 ;clear out holding buffer
|
|
|
|
; while (charavail()) charread();
|
|
|
|
flloop:
|
|
mov ah,1 ; command code for check status
|
|
int 16h ; call rom-bios keyboard routine
|
|
jz cc_ret ; return carry clear if none
|
|
|
|
xor ah,ah ; if zf is nof set, get character
|
|
int 16h ; call rom-bios to get character
|
|
jmp flloop
|
|
|
|
con_flush endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* some equates for rom bios printer i/o *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
; ibm rom status bits (i don't trust them, neither should you)
|
|
; warning!!! the ibm rom does not return just one bit. it returns a
|
|
; whole slew of bits, only one of which is correct.
|
|
|
|
|
|
notbusystatus = 10000000b ; not busy
|
|
nopaperstatus = 00100000b ; no more paper
|
|
prnselected = 00010000b ; printer selected
|
|
ioerrstatus = 00001000b ; some kinda error
|
|
timeoutstatus = 00000001b ; time out.
|
|
|
|
noprinter = 00110000b ; no printer attached
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* prn_input - return with no error but zero chars read *
|
|
;* *
|
|
;* enter with cx = number of characters requested *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
prn_input proc near
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
call bc_err_cnt ; reset count to zero (sub reqpkt.count,cx)
|
|
clc ; but return with carry reset for no error
|
|
ret
|
|
|
|
prn_input endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* prn_writ - write cx bytes from es:di to printer device *
|
|
;* *
|
|
;* auxnum has printer number *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
prn_writ proc near
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
jcxz prn_done ;no chars to output
|
|
|
|
prn_loop:
|
|
mov bx,2 ;retry count
|
|
|
|
prn_out:
|
|
call prnstat ; get status
|
|
jnz TestPrnError ; error
|
|
|
|
mov al,es:[di] ; get character to print
|
|
xor ah,ah
|
|
call prnop ; print to printer
|
|
jz prn_con ; no error - continue
|
|
|
|
cmp ah, MODE_CTRLBRK ; M013
|
|
jne @f ; M013
|
|
mov al, error_I24_gen_failure ; M013
|
|
mov altah, 0 ; M013
|
|
jmp short pmessg ; M013
|
|
@@:
|
|
test ah,timeoutstatus
|
|
jz prn_con ; not time out - continue
|
|
|
|
TestPrnError:
|
|
dec bx ;retry until count is exhausted.
|
|
jnz prn_out
|
|
|
|
pmessg:
|
|
jmp bc_err_cnt ; return with error
|
|
|
|
; next character
|
|
|
|
prn_con:
|
|
inc di ;point to next char and continue
|
|
loop prn_loop
|
|
|
|
prn_done:
|
|
clc
|
|
ret
|
|
prn_writ endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* prn_stat - device driver entry to return printer status *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
prn_stat proc near
|
|
|
|
call prnstat ;device in dx
|
|
jnz pmessg ; other errors were found
|
|
test ah,notbusystatus
|
|
jnz prn_done ;no error. exit
|
|
jmp z_bus_exit ; return busy status
|
|
prn_stat endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* prnstat - utilty function to call ROM BIOS to check *
|
|
;* printer status. Return meaningful error code *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
prnstat proc near
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
mov ah, 2 ; set command for get status
|
|
prnstat endp ; fall into prnop
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* prnop - call ROM BIOS printer function in ah *
|
|
;* return zero true if no error *
|
|
;* return zero false if error, al = error code *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
prnop proc near
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
mov dx,[auxnum] ; get printer number
|
|
int 17h ; call rom-bios printer routine
|
|
|
|
; This check was added to see if this is a case of no
|
|
; printer being installed. This tests checks to be sure
|
|
; the error is noprinter (30h)
|
|
|
|
push ax ; M044
|
|
and ah, noprinter ; M044
|
|
cmp AH,noprinter ; Chk for no printer
|
|
pop ax ; M044
|
|
|
|
jne NextTest
|
|
and AH,NOT nopaperstatus
|
|
or AH,ioerrstatus
|
|
|
|
; examine the status bits to see if an error occurred. unfortunately, several
|
|
; of the bits are set so we have to pick and choose. we must be extremely
|
|
; careful about breaking basic.
|
|
|
|
NextTest:
|
|
test ah,(ioerrstatus+nopaperstatus) ; i/o error?
|
|
jz checknotready ; no, try not ready
|
|
|
|
; at this point, we know we have an error. the converse is not true.
|
|
|
|
mov al,error_I24_out_of_paper
|
|
; first, assume out of paper
|
|
test ah,nopaperstatus ; out of paper set?
|
|
jnz ret1 ; yes, error is set
|
|
inc al ; return al=10 (i/o error)
|
|
ret1:
|
|
ret ; return with error
|
|
|
|
checknotready:
|
|
mov al,2 ; assume not-ready
|
|
test ah,timeoutstatus ; is time-out set?
|
|
ret ; if nz then error, else ok
|
|
prnop endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* prn_open - send bop to disable auto-close, and wait for *
|
|
;* a DOS close *
|
|
;* *
|
|
;* inputs: *
|
|
;* outputs: BOP has been issued *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
prn_open proc near
|
|
push si
|
|
push dx
|
|
push ds
|
|
mov dx,40h
|
|
mov ds,dx
|
|
test word ptr ds:[FIXED_NTVDMSTATE_REL40], EXEC_BIT_MASK
|
|
pop ds
|
|
jnz po_nobop
|
|
xor dh, dh
|
|
mov dl, [printdev]
|
|
or dl, dl
|
|
jz @f
|
|
dec dl
|
|
@@:
|
|
mov si,PRNIO_OPEN
|
|
bop %BIOS_PRINTER_IO
|
|
po_nobop:
|
|
pop dx
|
|
pop si
|
|
ret
|
|
prn_open endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* prn_close - send bop to close actual printer, and re-enable *
|
|
;* autoclose *
|
|
;* *
|
|
;* inputs: *
|
|
;* outputs: BOP has been issued *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
prn_close proc near
|
|
push si
|
|
push dx
|
|
push ds
|
|
mov dx,40h
|
|
mov ds,dx
|
|
test word ptr ds:[FIXED_NTVDMSTATE_REL40], EXEC_BIT_MASK
|
|
pop ds
|
|
jnz pc_nobop
|
|
xor dh, dh
|
|
mov dl, [printdev]
|
|
or dl, dl
|
|
jz @f
|
|
dec dl
|
|
@@:
|
|
mov si,PRNIO_CLOSE
|
|
bop %BIOS_PRINTER_IO
|
|
pc_nobop:
|
|
pop dx
|
|
pop si
|
|
ret
|
|
prn_close endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* prn_tilbusy - output until busy. Used by print spooler. *
|
|
;* this entry point should never block waiting for *
|
|
;* device to come ready. *
|
|
;* *
|
|
;* inputs: cx = count, es:di -> buffer *
|
|
;* outputs: set the number of bytes transferred in the *
|
|
;* device driver request packet *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
prn_tilbusy proc near
|
|
|
|
mov si,di ; everything is set for lodsb
|
|
|
|
prn_tilbloop:
|
|
push cx
|
|
|
|
push bx
|
|
xor bh,bh
|
|
mov bl,[printdev]
|
|
shl bx,1
|
|
mov cx,wait_count[bx] ; wait count times to come ready
|
|
pop bx
|
|
|
|
prn_getstat:
|
|
call prnstat ; get status
|
|
jnz prn_bperr ; error
|
|
test ah,10000000b ; ready yet?
|
|
loopz prn_getstat ; no, go for more
|
|
|
|
pop cx ; get original count
|
|
jz prn_berr ; still not ready => done
|
|
|
|
lods es:byte ptr [si]
|
|
xor ah,ah
|
|
call prnop
|
|
jnz prn_berr ; error
|
|
|
|
loop prn_tilbloop ; go for more
|
|
|
|
clc ; normal no-error return
|
|
ret ; from device driver
|
|
|
|
prn_bperr:
|
|
pop cx ; restore transfer count from stack
|
|
|
|
prn_berr:
|
|
jmp bc_err_cnt
|
|
prn_tilbusy endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* prn_genioctl - get/set printer retry count *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
prn_genioctl proc near
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
les di,[ptrsav]
|
|
cmp es:[di].majorfunction,ioc_pc
|
|
jz prnfunc_ok
|
|
|
|
prnfuncerr:
|
|
jmp bc_cmderr
|
|
|
|
prnfunc_ok:
|
|
mov al,es:[di].minorfunction
|
|
les di,es:[di].genericioctl_packet
|
|
xor bh,bh
|
|
mov bl,[printdev] ; get index into retry counts
|
|
shl bx,1
|
|
mov cx,wait_count[bx] ; pull out retry count for device
|
|
|
|
cmp al,get_retry_count
|
|
jz prngetcount
|
|
|
|
cmp al,set_retry_count
|
|
jnz prnfuncerr
|
|
|
|
mov cx,es:[di].rc_count
|
|
prngetcount:
|
|
mov wait_count[bx],cx ; place "new" retry count
|
|
mov es:[di].rc_count,cx ; return current retry count
|
|
clc
|
|
ret
|
|
prn_genioctl endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* prn_ioctl_query *
|
|
;* *
|
|
;* Added for 5.00 *
|
|
;************************************************************************
|
|
|
|
prn_ioctl_query PROC NEAR
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
les di,[ptrsav]
|
|
cmp es:[di].majorfunction,ioc_pc
|
|
jne prn_query_err
|
|
|
|
mov al,es:[di].minorfunction
|
|
cmp al,get_retry_count
|
|
je IOCtlSupported
|
|
cmp al,set_retry_count
|
|
jne prn_query_err
|
|
|
|
IOCtlSupported:
|
|
clc
|
|
ret
|
|
|
|
prn_query_err:
|
|
stc
|
|
jmp BC_CmdErr
|
|
|
|
prn_ioctl_query ENDP
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* aux port driver code -- "aux" == "com1" *
|
|
;* *
|
|
;* the device driver entry/dispatch code sets up auxnum to *
|
|
;* give the com port number to use (0=com1, 1=com2, 2=com3...) *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
; values in ah, requesting function of int 14h in rom bios
|
|
|
|
auxfunc_send equ 1 ;transmit
|
|
auxfunc_receive equ 2 ;read
|
|
auxfunc_status equ 3 ;request status
|
|
|
|
; error flags, reported by int 14h, reported in ah:
|
|
|
|
flag_data_ready equ 01h ;data ready
|
|
flag_overrun equ 02h ;overrun error
|
|
flag_parity equ 04h ;parity error
|
|
flag_frame equ 08h ;framing error
|
|
flag_break equ 10h ;break detect
|
|
flag_tranhol_emp equ 20h ;transmit holding register empty
|
|
flag_timeout equ 80h ;timeout
|
|
|
|
; these flags reported in al:
|
|
|
|
flag_cts equ 10h ;clear to send
|
|
flag_dsr equ 20h ;data set ready
|
|
flag_rec_sig equ 80h ;receive line signal detect
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* aux_read - read cx bytes from [auxnum] aux port to buffer *
|
|
;* at es:di *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
aux_read proc near
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
jcxz exvec2 ; if no characters, get out
|
|
|
|
call getbx ; put address of auxbuf in bx
|
|
xor al,al ; clear al register
|
|
xchg al,[bx] ; get character , if any, from
|
|
; buffer and clear buffer
|
|
or al,al ; if al is nonzero there was a
|
|
; character in the buffer
|
|
jnz aux2 ; if so skip first auxin call
|
|
|
|
aux1:
|
|
call auxin ; get character from port
|
|
; ^^^^^ won't return if error
|
|
aux2:
|
|
stosb ; store character
|
|
loop aux1 ; if more characters, go around again
|
|
|
|
exvec2:
|
|
clc ; all done, successful exit
|
|
ret
|
|
|
|
aux_read endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* auxin - call rom bios to read character from aux port *
|
|
;* if error occurs, map the error and return one *
|
|
;* level up to device driver exit code, setting *
|
|
;* the number of bytes transferred appropriately *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
;
|
|
; M026 - BEGIN
|
|
;
|
|
auxin proc near
|
|
mov ah,auxfunc_receive
|
|
call auxop ;check for frame, parity, or overrun errors
|
|
;warning: these error bits are unpredictable
|
|
; if timeout (bit 7) is set
|
|
test ah, flag_frame or flag_parity or flag_overrun
|
|
jnz arbad ; skip if any error bits set
|
|
ret ; normal completion, ah=stat, al=char
|
|
|
|
; error getting character
|
|
|
|
arbad:
|
|
pop ax ; remove return address (near call)
|
|
xor al,al
|
|
or al,flag_rec_sig or flag_dsr or flag_cts
|
|
jmp bc_err_cnt
|
|
|
|
auxin endp
|
|
|
|
IFDEF COMMENTEDOUT
|
|
auxin proc near
|
|
push cx
|
|
mov cx, 20 ; number of retries on time out errors
|
|
@@:
|
|
mov ah,auxfunc_receive
|
|
call auxop ;check for frame, parity, or overrun errors
|
|
;warning: these error bits are unpredictable
|
|
; if timeout (bit 7) is set
|
|
test ah, flag_timeout
|
|
jz no_timeout
|
|
loop @b
|
|
no_timeout:
|
|
pop cx
|
|
test ah, flag_timeout or flag_frame or flag_parity or flag_overrun
|
|
jnz arbad ; skip if any error bits set
|
|
ret ; normal completion, ah=stat, al=char
|
|
|
|
; error getting character
|
|
|
|
arbad:
|
|
pop ax ; remove return address (near call)
|
|
xor al,al
|
|
or al,flag_rec_sig or flag_dsr or flag_cts
|
|
jmp bc_err_cnt
|
|
|
|
auxin endp
|
|
ENDIF
|
|
|
|
;
|
|
; M026 - END
|
|
;
|
|
;************************************************************************
|
|
;* *
|
|
;* aux_rdnd - non-destructive aux port read *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
aux_rdnd proc near
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
call getbx ; have bx point to auxbuf
|
|
mov al,[bx] ; copy contents of buffer to al
|
|
or al,al ; if al is non-zero (char in buffer)
|
|
jnz auxrdx ; then return character
|
|
|
|
call auxstat ; if not, get status of aux device
|
|
test ah,flag_data_ready ; test data ready
|
|
jz auxbus ; then device is busy (not ready)
|
|
|
|
test al,flag_dsr ;test data set ready
|
|
jz auxbus ; then device is busy (not ready)
|
|
|
|
call auxin ; else aux is ready, get character
|
|
mov [bx],al ; save character in buffer
|
|
|
|
auxrdx:
|
|
jmp rdexit ; return al in [packet.media]
|
|
|
|
auxbus:
|
|
jmp z_bus_exit ; return busy status
|
|
aux_rdnd endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* aux_wrst - return aux port write status *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
aux_wrst proc near
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
call auxstat ; get status of aux in ax
|
|
test al,flag_dsr ; test data set ready
|
|
jz auxbus ; then device is busy (not ready)
|
|
test ah,flag_tranhol_emp ;test transmit hold reg empty
|
|
jz auxbus ; then device is busy (not ready)
|
|
clc
|
|
ret
|
|
aux_wrst endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* auxstat - call rom bios to determine aux port status *
|
|
;* *
|
|
;* exit: ax = status *
|
|
;* dx = [auxnum] *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
auxstat proc near
|
|
mov ah,auxfunc_status
|
|
auxstat endp ; fall into auxop
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* auxop - perform rom-biox aux port interrupt *
|
|
;* *
|
|
;* entry: ah = int 14h function number *
|
|
;* exit: ax = results *
|
|
;* dx = [auxnum] *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
auxop proc near
|
|
;ah=function code
|
|
;0=init, 1=send, 2=receive, 3=status
|
|
mov dx,[auxnum] ; get port number
|
|
int 14h ; call rom-bios for status
|
|
ret
|
|
auxop endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* aux_flsh - flush aux input buffer - set contents of *
|
|
;* auxbuf [auxnum] to zero *
|
|
;* *
|
|
;* cas - shouldn't this code call the rom bios input function *
|
|
;* repeatedly until it isn't ready? to flush out any *
|
|
;* pending serial input queue if there's a tsr like MODE *
|
|
;* which is providing interrupt-buffering of aux port? *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
aux_flsh proc near
|
|
call getbx ; get bx to point to auxbuf
|
|
mov byte ptr [bx],0 ; zero out buffer
|
|
clc ; all done, successful return
|
|
ret
|
|
aux_flsh endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* aux_writ - write to aux device *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
aux_writ proc near
|
|
assume ds:Bios_Data ; set by aux device driver entry routine
|
|
jcxz exvec2 ; if cx is zero, no characters
|
|
; to be written, jump to exit
|
|
aux_loop:
|
|
mov al,es:[di] ; get character to be written
|
|
inc di ; move di pointer to next character
|
|
mov ah,auxfunc_send ;value=1, indicates a write
|
|
call auxop ;send character over aux port
|
|
|
|
test ah,flag_timeout ;check for error
|
|
jz awok ; then no error
|
|
mov al,10 ; else indicate write fault
|
|
jmp bc_err_cnt ; call error routines
|
|
|
|
; if cx is non-zero, still more
|
|
awok:
|
|
loop aux_loop ; more characrter to print
|
|
clc ; all done, successful return
|
|
ret
|
|
aux_writ endp
|
|
|
|
;************************************************************************
|
|
;* *
|
|
;* getbx - return bx -> single byte input buffer for *
|
|
;* selected aux port ([auxnum]) *
|
|
;* *
|
|
;************************************************************************
|
|
|
|
getbx proc near
|
|
assume ds:Bios_Data,es:nothing
|
|
|
|
mov bx,[auxnum]
|
|
add bx,offset auxbuf
|
|
ret
|
|
getbx endp
|
|
|
|
Bios_Code ends
|
|
end
|