www.pudn.com > commutil.zip > BASCII.ASM
page 55,132
title "BASCII - ASCII Protocol Module"
; ---------------------------------------------------------------------
;
; Maintenance Log
;
; Version Date Description Who
; ------- ------- ---------------------------------- ----------------
; 1.0 08Feb91 Initial version complete Flanders/Holmes
;
; ---------------------------------------------------------------------
protocol segment para public 'code' ; Ascii module
assume cs:protocol
FARRET macro ; far return macro
db 0cbh
endm
; ---------------------------------------------------------------------
; protocol header
; ---------------------------------------------------------------------
start: jmp bpmascii ; jump to start
db "BD" ; backdown protocol ID
db 1 ; nbr of protocols
db "A" ; invocation letter
db "Ascii V1.0 ", 0 ; name to display
db 1 ; protocol nbr
; ---------------------------------------------------------------------
; local stack
; ---------------------------------------------------------------------
even
bpmstack db 32 dup ("St") ; local stack area
bpmstackend db "Es" ; End of local stack
stackoffset dw offset bpmstackend ; New stack pointer
; ---------------------------------------------------------------------
; data areas
; ---------------------------------------------------------------------
state dw -1 ; current state
ticks dw ? ; entry nbr ticks
jmptab dw init ; 0: initialization call
dw fncok ; 2: last function ok
dw fncfail ; 4: last function failed
dw commchar ; 6: character received
dw kbdchar ; 8: keystroke encountered
MAXCODE equ 8 ; maximum entry code
TIMEOUT equ ((182*30)/10) ; 30 seconds in ticks
DSPTIMEOUT equ (TIMEOUT-5) ; 29.7 seconds left
filename db 65 dup (0) ; space for filename
writebuf db 0 ; address for write buf
dispbuf db 82 dup (?) ; buffer for display chars
oldds dw ? ; caller's ds
oldsp dw ? ; caller's sp
oldss dw ? ; caller's ss
init2x db 13, 'ASCII: Init called twice', 13, 0
badfnc db 13, 'ASCII: Bad function code', 13, 0
openerr db 13, 'ASCII: Unable to open that file..'
fileprompt db 13, 'ASCII: Enter filename, to exit: ', 0
nofile db 13, 'ASCII: No filename, protocol aborted', 13, 0
fileopened db 13, 'ASCII: File opened.. starting capture', 13
db 13, ' Press "End" to stop capturing', 13, 0
timedout db 13, 'ASCII: No chars seen for 30 seconds, '
db 'protocol ended', 13, 0
notinited db 13, 'ASCII: BD did not call init first', 13, 0
donebyreq db 13, 'ASCII: Download complete', 13, 0
writerr db 13, 'ASCII: Write error.. protocol aborted', 13, 0
staterr0 db 13, 'ASCII: State error 0', 13, 0
staterr1 db 13, 'ASCII: State error 1', 13, 0
; ---------------------------------------------------------------------
; protocol mainline
; ---------------------------------------------------------------------
bpmascii proc
push es ; save caller's regs
push ds
mov cs:oldds, ds ; keep copy of caller's ds
mov cs:oldss, ss ; save caller's stack
mov cs:oldsp, sp
mov cs:ticks, ax ; save entry ticks
mov ax, cs ; ax -> our segment
mov ds, ax ; ds -> our segment
mov es, ax ; es -> our segment
cli ; no interrupts ..
mov ss, ax ; ss -> our segment
mov sp, stackoffset ; sp -> end of stack
sti ; .. allow ints again
cmp di, MAXCODE ; q. is code ok?
ja bpmascii90 ; a. no .. return "done"
test di, 1 ; q. is code even
jnz bpmascii90 ; a. no .. return "done"
jmp jmptab[di] ; .. call requested routine
bpmascii90: lea bx, badfnc ; bx -> bad function code
jmp proto_err ; issue error and leave
bpmascii endp
; ---------------------------------------------------------------------
; init - initialization call
;
; entry: ds:bx -> operands (filename)
; ---------------------------------------------------------------------
init proc
cmp state, -1 ; q. already init'd?
je init00 ; a. no .. continue
lea bx, init2x ; bx -> error message
jmp proto_err ; .. kill the protocol
init00: mov ds, oldds ; ds -> callers segment
cmp byte ptr [bx], 0 ; q. any filename given?
je init10 ; a. no .. get the file name
lea di, filename ; di -> area for filename
mov si, bx ; si -> input filename
cld ; .. move upward
init05: movsb ; move in a byte
cmp di, offset filename+64 ; q. end of area?
je init20 ; a. yes .. continue
cmp byte ptr [si-1],0 ; q. end of string?
jne init05 ; a. no .. continue
push cs ; save our segment
pop ds ; .. ds -> our segment
jmp short init20 ; .. open the file
init10: lea bx, fileprompt ; bx -> filename prompt
init15: mov di, 12 ; di = display ASCIIZ
call callback ; .. ask bd to display
lea bx, filename ; bx -> filename
mov di, 16 ; di = get a line
call callback ; .. ask bd to get it
cmp filename, ' ' ; q. first char non-blank?
ja init20 ; a. yes .. continue
lea bx, nofile ; bx = no file given
jmp proto_err ; .. kill the protocol
init20: lea bx, filename ; bx -> filename
mov di, 2 ; di = open file
call callback ; q. file open ok?
jnc init25 ; a. yes .. continue
lea bx, openerr ; bx -> open error
jmp init15 ; Tell user .. ask for next
init25: lea bx, fileopened ; bx -> file opened msg
mov di, 12 ; di = display string
call callback ; .. ask bd to do it
mov dispbuf, 0 ; .. zero out display buffer
mov bx, TIMEOUT ; bx = ticks for 30 seconds
mov di, 22 ; di = set tick downcounter
call callback ; .. set the down counter
mov bl, 0dh ; bl = char to send
mov di, 20 ; di = send char
call callback ; .. send the character
jmp proto_ok ; .. and init is done
init endp
; ---------------------------------------------------------------------
; fncok - last function executed ok -or- simple dispatch
;
; state = 0: simple dispatch
; state = 1: state return
; -- Carry is cleared
; ---------------------------------------------------------------------
fncok proc
cmp state, -1 ; q. init'd yet?
jne fncok05 ; a. yes .. continue
lea bx, notinited ; bx -> not init'd msg
jmp proto_err ; .. kill the protocol
fncok05: cmp state, 0 ; q. simple dispatch?
je fncok10 ; a. yes.. run around
clc ; show function
ret ; .. rtn to callback caller
fncok10: cmp ticks, 0 ; q. timeout?
jnl fncok20 ; a. no .. check if display
lea bx, timedout ; bx -> timeout message
jmp proto_err ; .. we are done!
fncok20: cmp ticks, DSPTIMEOUT ; q. display timeout?
ja fncok90 ; a. no .. tell 'em all is ok
cmp dispbuf, 0 ; q. anything to display?
je fncok90 ; a. no .. exit
call dsp_n_wrt ; q. display & write it ok?
jnc fncok90 ; a. yes .. return ok
lea bx, writerr ; bx -> write error message
jmp proto_err ; .. kill the protocol
fncok90: jmp proto_ok ; .. return all is ok
fncok endp
; ---------------------------------------------------------------------
; fncfail - previous function failed
;
; Carry = failure
; ---------------------------------------------------------------------
fncfail proc ; last function failed
cmp state, 1 ; q. waiting on return
je fncfail10 ; a. yes .. continue
lea bx, staterr1 ; bx -> state error msg
jmp proto_err ; .. tell user & die
fncfail10: stc ; set carry to show fail
ret ; return to callback caller
fncfail endp
; ---------------------------------------------------------------------
; commchar - process communications character
;
; entry: dl = character
; ---------------------------------------------------------------------
commchar proc
cmp state, 0 ; q. no function requested?
je commchar10 ; a. yes .. continue
lea bx, staterr0 ; bx -> state error msg
jmp proto_err ; .. tell user & die
commchar10: or dl, dl ; q. nul character?
jz commchar90 ; a. yes .. exit
inc dispbuf ; increment buffer cnt
xor dh, dh ; dh = 0
mov bl, dispbuf ; bl = display buffer len
xor bh, bh ; .. upper bits off
mov word ptr dispbuf[bx], dx; save char & ASCIIZ
mov bx, TIMEOUT ; bx = timeout count
mov di, 22 ; di = set tick downcounter
call callback ; .. ask BD to do it
cmp dispbuf, 80 ; q. buffer full?
jb commchar90 ; a. no .. exit
call dsp_n_wrt ; q. display & write ok?
jnc commchar90 ; a. yes .. done for now
lea bx, writerr ; bx -> write error message
jmp short proto_err ; .. kill the protocol
commchar90: jmp short proto_ok ; function worked ok
commchar endp
; ---------------------------------------------------------------------
; kbdchar - process keyboard character
;
; entry: dl = character
; ---------------------------------------------------------------------
kbdchar proc
cmp state, 0 ; q. no function requested?
je kbdchar00 ; a. yes .. continue
lea bx, staterr0 ; bx -> state error msg
jmp short proto_err ; .. tell user & die
kbdchar00: or dl, dl ; q. special key?
jnz kbdchar20 ; a. no .. send it out
cmp dh, 4fh ; q. END key?
jne kbdchar90 ; a. no .. ignore it
cmp dispbuf, 0 ; q. any chars in buffer?
je kbdchar10 ; a. no .. end now
call dsp_n_wrt ; else display & write
kbdchar10: lea bx, donebyreq ; bx -> done by request
jmp short proto_err ; .. end the protocol
kbdchar20: mov di, 20 ; di = send one char
mov bl, dl ; bl = character to send
call callback ; .. send it out
kbdchar90: jmp short proto_ok ; .. done for now
kbdchar endp
; ---------------------------------------------------------------------
; dsp_n_wrt - dispay and write out buffer
; ---------------------------------------------------------------------
dsp_n_wrt proc
lea bx, dispbuf+1 ; bx -> chars to display
mov di, 24 ; di = display ASCIIZ
call callback ; .. ask BD to do it
mov ax, word ptr writebuf ; ax = littlendian value
xchg ah, al ; .. make it intel format
mov word ptr writebuf, ax ; .. and save it
lea bx, writebuf ; bx -> buffer to write
mov di, 4 ; di = write the buffer
call callback ; q. BD write it ok?
jnc dsp_n_wrt90 ; a. yes .. clean up & exit
lea bx, writerr ; bx -> write error msg
jmp short proto_err ; .. write note & die
dsp_n_wrt90:mov writebuf, 0 ; Zero first byte of wbuf
mov word ptr dispbuf, 0 ; .. and len, first of dsp
ret ; return to caller
dsp_n_wrt endp
; ---------------------------------------------------------------------
; callback - setup to "call" backdown
;
; entry: di = return code
; ---------------------------------------------------------------------
callback proc
mov state, 1 ; show were in callback mode
jmp short proto_exit ; return to caller
callback endp
; ---------------------------------------------------------------------
; proto_err - display error, return done
;
; entry: bx -> string
; ---------------------------------------------------------------------
proto_err proc
mov di, 12 ; di = display string
call callback ; .. display it
jmp short proto_done ; tell bd we are done
proto_err endp
; ---------------------------------------------------------------------
; proto_done - protocol done - leave forever
; ---------------------------------------------------------------------
proto_done proc
mov di, 10 ; di = done code
jmp short proto_exit ; ..and return to caller
proto_done endp
; ---------------------------------------------------------------------
; proto_ok - exit with the OK code
; ---------------------------------------------------------------------
proto_ok proc
mov state, 0 ; zero out the state
mov di, 0 ; di = ok return code
jmp short proto_exit ; restore regs & exit
proto_ok endp
; ---------------------------------------------------------------------
; proto_exit - protcol exit routine
; ---------------------------------------------------------------------
proto_exit proc
mov stackoffset, sp ; save our stack offset
cli ; no interrupts
mov ss, oldss ; ..restore callers ss
mov sp, oldsp ; ..and sp
sti ; ints ok again
pop ds ; restore caller's regs
pop es
FARRET ; return to caller
proto_exit endp
protocol ends
end start