Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1078 lines
28 KiB

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