home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Between Heaven & Hell 2
/
BetweenHeavenHell.cdr
/
300
/
257
/
msxz100.asm
< prev
next >
Wrap
Assembly Source File
|
1984-12-18
|
15KB
|
612 lines
; Kermit system dependent module for Heath/Zenith Z100
; (2.27) Save DI in getbaud.
public serini, serrst, clrbuf, outchr, coms, vts, dodel,
public ctlu, cmblnk, locate, prtchr, dobaud, clearl,
public dodisk, getbaud, beep,
public count, xofsnt, puthlp, putmod, clrmod, poscur
public sendbr, machnam, setktab, setkhlp, lclini, showkey
include msdefs.h
false equ 0
true equ 1
mntrgh equ bufsiz*3/4 ; High point = 3/4 of buffer full.
; constants used by serial port handler
BRKBIT EQU 048H ; Send-break bit.
MDMCOM1 EQU 00EFH ; Address of modem port command. [19b]
; external variables used:
; drives - # of disk drives on system
; flags - global flags as per flginfo structure defined in pcdefs
; trans - global transmission parameters, trinfo struct defined in pcdefs
; portval - pointer to current portinfo structure (currently either port1
; or port2)
; port1, port2 - portinfo structures for the corresponding ports
; global variables defined in this module:
; xofsnt, xofrcv - tell whether we saw or sent an xoff.
; setktab - keyword table for redefining keys (should contain a 0 if
; not implemented)
; setkhlp - help for setktab.
BIOS_SEG SEGMENT AT 40H ; Define segment where BIOS really is
ORG 6*3
BIOS_AUXOUT LABEL FAR ; AUX output routine
ORG 26*3
BIOS_AUXFUNC LABEL FAR ; AUX: function
ORG 27*3
BIOS_CONFUNC LABEL FAR ; CON: function
BIOS_SEG ENDS
; Function codes for BIOS_xxxFUNC
CHR_WRITE EQU 0 ; Write character
CHR_READ EQU 1 ; Read character
CHR_STATUS EQU 2 ; Get status
CHR_SFGS EQU 0 ; Get status subfunction
CHR_SFGC EQU 1 ; Get config subfunction
CHR_CONTROL EQU 3 ; Control function
CHR_CFSU EQU 0 ; Set new configuration parameters
CHR_CFCI EQU 1 ; Clear input buffer
datas segment public 'datas'
extrn drives:byte, flags:byte, trans:byte
extrn portval:word, port1:byte, port2:byte
setktab db 13
mkeyw 'F0',96h
mkeyw 'F1',97h
mkeyw 'F2',98h
mkeyw 'F3',99h
mkeyw 'F4',9ah
mkeyw 'F5',9bh
mkeyw 'F6',9ch
mkeyw 'F7',9dh
mkeyw 'F8',9eh
mkeyw 'F9',9fh
mkeyw 'F10',0a0h
mkeyw 'F11',0a1h
mkeyw 'SCAN',-1
setkhlp db cr,lf,'Keyname: f0, ... f11, "HELP" or "SCAN" follwed by '
db 'decimal scan code$'
brkval db 0 ; What to send for a break.
brkadr dw 0 ; Where to send it.
badbd db cr,lf,'Unimplemented baud rate$'
noimp db cr,lf,'Not implemented$'
machnam db 'Heath-Zenith Z-100$'
crlf db cr,lf,'$'
delstr db BS,' ',BS,'$' ; Delete string. [21d]
home db ESC,'H$'
eeolstr db ESC,'K$' ; Erase to end of line
clrstr db ESC,'E$' ; Erase entire display
enamod db ESC,'x1$' ; Enable 25th line
dismod db ESC,'y1$' ; Disable 25th line
enascan db ESC,'y?$' ; Enable scan codes
disscan db ESC,'x?$' ; Disable scan codes
begrev db ESC,'p$' ; Enter reverse video
endrev db ESC,'q$' ; Exit reverse video
lin25 db ESC,'Y8 $' ; Column 1 row 25
savcur db ESC,'j$' ; Save current cursor position
precur db ESC,'k$' ; Restore cursor to previous position
clrlin db cr,'$' ; Clear line (just the cr part).
xofsnt db 0 ; Say if we sent an XOFF.
xofrcv db 0 ; Say if we received an XOFF.
tmp db ?,'$'
temp1 dw ? ; Temporary storage.
ontab db 02H ; Two entries.
db 03H,'OFF$' ; Should be alphabetized. [19a]
dw 00H
db 02H,'ON$'
dw 01H
; this table is indexed by the baud rate definitions given in
; pcdefs. Unsupported baud rates should contain FF.
bddat label word
dw 0 ; 45.5 baud
dw 1 ; 50 baud
dw 2 ; 75 baud
dw 3 ; 110 baud
dw 4 ; 134.5 baud
dw 5 ; 150 baud
dw 6 ; 300 baud
dw 7 ; 600 baud
dw 8 ; 1200 baud
dw 9 ; 1800 baud
dw 10 ; 2000 baud
dw 11 ; 2400 baud
dw 12 ; 4800 baud
dw 13 ; 9600 baud
dw 14 ; 19200 baud
dw 15 ; 38400 baud
; storage for port configuration
cfginfo struc
cfclass db 0
cfattr db 0
cfport dw 0
cfbaud db 0
cfhshk db 0
cfbctl db 0
cfecnt db 0
cfncnt db 0
cfnchr db 0
cfres db 6 dup(?)
cfsize db 0
cfginfo ends
auxconf cfginfo <>
; variables for serial interrupt handler
count dw 0 ; Number of chars in int buffer.
ourarg termarg <>
shkbuf db 300 dup (?) ; room for definition
shkmsg db ' Scan code: '
shkmln equ $-shkmsg
shkms1 db cr,lf,' Definition: '
shkm1ln equ $-shkms1
datas ends
code segment public
extrn comnd:near, dopar:near, defkey:near
assume cs:code,ds:datas
; local initialization
lclini proc near
mov brkval,BRKBIT ; What to send for a break.
mov brkadr,MDMCOM1
mov flags.vtflg,0 ; Turn off true Heath mode (allows key macros)
ret
lclini endp
; this is called by Kermit initialization. It checks the
; number of disks on the system, sets the drives variable
; appropriately. Returns normally.
DODISK PROC NEAR
mov ah,gcurdsk ; Current disk value to AL.
int dos
mov dl,al ; Put current disk in DL.
mov ah,seldsk ; Select current disk.
int dos
mov drives,al
ret
DODISK ENDP
; show the definition of a key. The terminal argument block (which contains
; the address and length of the definition tables) is passed in ax.
; Returns a string to print in AX, length of same in CX.
; Returns normally.
showkey proc near
push es
push ax ; save the ptr
mov bx,ds
mov es,bx ; address data segment
cld
showk1: mov ah,prstr
mov dx,offset enascan ; enable scan codes
int dos
mov ah,0ch ; char input with buffer flush
mov al,7
int dos
; mov ah,chr_control
; mov al,chr_cfci ; clear input
; call bios_confunc
; mov ah,chr_read
; call bios_confunc ; read a char
push ax
mov ah,prstr
mov dx,offset disscan ; disable scan codes
int dos
pop ax
; push ax ; save the character
; call gss ; get shift state
; pop bx
mov ah,0 ; shift state to ah
; mov al,bh ; scan code to al
push ax ; remember scan code
mov di,offset shkbuf
mov si,offset shkmsg
mov cx,shkmln
rep movsb ; copy in initial message
call nout ; write out scan code
mov si,offset shkms1
mov cx,shkm1ln ; second message
rep movsb
pop ax ; get scan code back
pop bx ; and terminal arg block
mov cx,[bx].klen ; and length
jcxz showk2 ; no table, not defined
push di ; remember output ptr
mov di,[bx].ktab ; get key table
repne scasw ; search for a definition for this
mov si,di ; remember result ptr
pop di ; get output ptr back
jne showk2 ; not defined, forget it
sub si,[bx].ktab ; compute offset from beginning
sub si,2 ; minus 2 for pre-increment
add si,[bx].krpl ; get index into replacement table
mov si,[si] ; pick up replacement
mov cl,[si] ; get length
mov ch,0
inc si
rep movsb ; copy into buffer
showk2: mov ax,offset shkbuf ; this is buffer
mov cx,di
sub cx,ax ; length
pop es
ret ; and return
showkey endp
; Clear the input buffer. This throws away all the characters in the
; serial interrupt buffer. This is particularly important when
; talking to servers, since NAKs can accumulate in the buffer.
; Returns normally.
CLRBUF PROC NEAR
cli
mov ah,chr_control
mov al,chr_cfci
call bios_auxfunc
mov count,0
sti
ret
CLRBUF ENDP
; Clear to the end of the current line. Returns normally.
CLEARL PROC NEAR
mov ah,prstr
mov dx,offset eeolstr ; Erase to end of line
int dos
ret
CLEARL ENDP
; Put the char in AH to the serial port. This assumes the
; port has been initialized. Should honor xon/xoff. Skip returns on
; success, returns normally if the character cannot be written.
outchr: mov bp,portval
cmp ds:[bp].floflg,0 ; Are we doing flow control.
je outch2 ; No, just continue.
xor cx,cx ; clear counter
outch1: cmp xofrcv,true ; Are we being held?
jne outch2 ; No - it's OK to go on.
loop outch1 ; held, try for a while
mov xofrcv,false ; timed out, force it off and fall thru.
outch2: push dx ; Save register.
mov al,ah ; Parity routine works on AL.
call dopar ; Set parity appropriately.
call bios_auxout
pop dx
jmp rskp
; This routine blanks the screen. Returns normally.
CMBLNK PROC NEAR
mov ah,prstr
mov dx,offset clrstr
int dos
ret
CMBLNK ENDP
; Locate: homes the cursor. Returns normally.
LOCATE PROC NEAR
mov ah,prstr
mov dx,offset home ; Go to top left corner of screen.
int dos
LOCATE ENDP
; write a line in inverse video at the bottom of the screen...
; the line is passed in dx, terminated by a $. Returns normally.
putmod proc near
push dx ; preserve message
mov ah,prstr
mov dx,offset savcur
int dos
mov dx,offset enamod
int dos
mov dx,offset lin25
int dos
mov dx,offset begrev
int dos
pop dx ; get message back
int dos ; write it out
mov dx,offset endrev
int dos
mov dx,offset precur
int dos
ret ; and return
putmod endp
; clear the mode line written by putmod. Returns normally.
clrmod proc near
mov ah,prstr
mov dx,offset dismod
int dos
ret
clrmod endp
BEEP PROC NEAR
mov dl,07 ; ASCII BEL
mov ah,dconio
int dos ; Ring it
ret
BEEP ENDP
; put a help message on the screen. This one uses reverse video...
; pass the message in ax, terminated by a null. Returns normally.
puthlp proc near
push ax ; preserve this
mov ah,prstr
mov dx,offset crlf
int dos
pop si ; point to string again
puthl3: lodsb ; get a byte
cmp al,0 ; end of string?
je puthl4 ; yes, stop
mov dl,al
mov ah,dconio
int dos
jmp puthl3 ; and keep going
puthl4: mov ah,prstr
mov dx,offset crlf
int dos
ret
puthlp endp
; Set the baud rate for the current port, based on the value
; in the portinfo structure. Returns normally.
DOBAUD PROC NEAR
mov bp,portval
mov temp1,ax ; Don't overwrite previous rate. [25]
mov ax,ds:[bp].baud ; Check if new rate is valid. [25]
mov tmp,2
mul tmp ; Get index into baud table.
mov bx,offset bddat ; Start of table.
add bx,ax
mov ax,[bx] ; The data to output to port.
cmp ax,0FFH ; Unimplemented baud rate.
jne dobd0
mov ax,temp1 ; Get back orginal value.
mov ds:[bp].baud,ax ; Leave baud rate as is.
mov ah,prstr
mov dx,offset badbd ; Give an error message.
int dos
ret
dobd0: push ax ; Save it
mov bx,ds ; Set up pointer to config info
mov es,bx ; . . .
mov bx,offset auxconf ; . . .
mov ah,chr_status
mov al,chr_sfgc ; get current config info
call bios_auxfunc
pop ax ; get baud back
mov auxconf.cfbaud,al
mov ah,chr_control ; Function is control
mov al,chr_cfsu ; Subfunction is set new config
call bios_auxfunc ; Set the configuration
ret
DOBAUD ENDP
; Get the current baud rate from the serial card and set it
; in the portinfo structure for the current port. Returns normally.
; This is used during initialization.
GETBAUD PROC NEAR
mov bx,ds
mov es,bx
mov bx,offset auxconf
mov ah,chr_status
mov al,chr_sfgc ; Status function get config info
call bios_auxfunc
mov ch,0
mov cl,auxconf.cfbaud
mov bp,portval
mov ds:[bp].baud,cx
ret
GETBAUD ENDP
; skip returns if no character available at port,
; otherwise returns with char in al, # of chars in buffer in dx.
PRTCHR PROC NEAR
call chkxon ; see if we need to xon
push bx
mov ah,chr_status
mov al,chr_sfgs ; Status function get status
call bios_auxfunc
cmp bl,0
jnz prtch2
pop bx
jmp rskp ; No data - check console.
prtch2: mov dh,0
mov dl,bl ; Place # of chars in dx
mov ah,chr_read
call bios_auxfunc
dec dl ; Decrement number of chars
mov count,dx ; Save count for posterity
pop bx
ret
PRTCHR ENDP
; local routine to see if we have to transmit an xon
chkxon proc near
push bx
mov bx,portval
cmp [bx].floflg,0 ; doing flow control?
je chkxo1 ; no, skip all this
cmp xofsnt,false ; have we sent an xoff?
je chkxo1 ; no, forget it
cmp count,mntrgh ; below trigger?
jae chkxo1 ; no, forget it
mov ax,[bx].flowc ; ah gets xon
call outchr ; send it
nop
nop
nop ; in case it skips
mov xofsnt,false ; remember we've sent the xon.
chkxo1: pop bx ; restore register
ret ; and return
chkxon endp
; Send a break out the current serial port. Returns normally.
SENDBR PROC NEAR
push cx
push dx
push ax
xor cx,cx ; Clear loop counter.
mov dx,brkadr ; Port address. [19b]
in al,dx ; Get current setting.
or al,brkval ; Set send-break bit(s).
out dx,al ; Start the break.
pause: loop pause ; Wait a while.
xor al,brkval ; Clear send-break bit(s).
out dx,al ; Stop the break.
pop ax
pop dx
pop cx
ret ; And return.
SENDBR ENDP
; Position the cursor according to contents of DX:
; DH contains row, DL contains column. Returns normally.
POSCUR PROC NEAR
push dx
mov ah,CONOUT
mov dl,ESC
int dos
mov dl,'Y'
int dos
pop dx
push dx
mov dl,dh
add dl,' '
int dos
pop dx
add dl,' '
int dos
ret
POSCUR ENDP
; Delete a character from the terminal. This works by printing
; backspaces and spaces. Returns normally.
DODEL PROC NEAR
mov ah,prstr
mov dx,offset delstr ; Erase weird character.
int dos
ret
DODEL ENDP
; Move the cursor to the left margin, then clear to end of line.
; Returns normally.
CTLU PROC NEAR
mov ah,prstr
mov dx,offset clrlin
int dos
call clearl
ret
CTLU ENDP
; set the current port.
COMS PROC NEAR
jmp notimp
COMS ENDP
; Set heath emulation on/off.
VTS PROC NEAR
mov dx,offset ontab
mov bx,0
mov ah,cmkey
call comnd
jmp r
push bx
mov ah,cmcfm
call comnd ; Get a confirm.
jmp vt0 ; didn't get a confirm.
nop
pop bx
mov flags.vtflg,bl ; Set the Heath emulation flag
ret
vt0: pop bx
ret
VTS ENDP
notimp: mov ah,prstr
mov dx,offset noimp
int dos
jmp rskp
; initialization for using serial port. This routine performs
; any initialization necessary for using the serial port, including
; setting up interrupt routines, setting buffer pointers, etc.
; Doing this twice in a row should be harmless (this version checks
; a flag and returns if initialization has already been done).
; SERRST below should restore any interrupt vectors that this changes.
; Returns normally.
SERINI PROC NEAR
ret ; We're done.
SERINI ENDP
; Reset the serial port. This is the opposite of serini. Calling
; this twice without intervening calls to serini should be harmless.
; Returns normally.
SERRST PROC NEAR
ret ; All done.
SERRST ENDP
; put the number in ax into the buffer pointed to by di. Di is updated
nout proc near
mov dx,0 ; high order is always 0.
mov bx,10
div bx ; divide to get digit
push dx ; save remainder digit
or ax,ax ; test quotient
jz nout1 ; zero, no more of number
call nout ; else call for rest of number
nout1: pop ax ; get digit back
add al,'0' ; make printable
stosb ; drop it off
ret ; and return
nout endp
; Jumping to this location is like retskp. It assumes the instruction
; after the call is a jmp addr.
RSKP PROC NEAR
pop bp
add bp,3
push bp
ret
RSKP ENDP
; Jumping here is the same as a ret.
R PROC NEAR
ret
R ENDP
code ends
end