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