home *** CD-ROM | disk | FTP | other *** search
- title 'XUTIL.ASM'
- ;************************************************
- ;* *
- ;* XUTIL.ASM *
- ;* *
- ;* General purpose utility routines for X.25 *
- ;* protocol interface program *
- ;* *
- ;* rev 0.16 08/21/84 E. Elizondo *
- ;* *
- ;* (c) 1984 E. Elizondo - all rights reserved. *
- ;* *
- ;* This program may be used freely for non- *
- ;* commercial applications. It may not be sold *
- ;* or used for commercial applications without *
- ;* written permission of the author. *
- ;* *
- ;************************************************
- ;
-
- maclib Z80 ;DR Z80 macro library
-
-
- ; subroutine entry points
-
- public ilprt ;in-line print routine
- public ctype ;output char to console and printer
- public cview ;output char to console only
- public move ;move block of data
- public decbin ;convert decimal ASCII to binary
- public hexbin ;convert hex ASCII digit to binary
- public pdec ;print binary number in ASCII decimal
- public pbin ;print byte in binary
- public phex ;print byte in hex
- public phex1 ;print nibble in hex
- public disptch ;dispatch routine
- public instr ;input string from console
- public poll ;poll console & printer
- public delay ;wait a bit
-
- ; address hooks
- public inbuf ;console input buffer
- public prnflg ;printer ena/dis flag
-
- ; external subroutines
-
- extrn putbuf ;put byte into a fifo buffer
- extrn getbuf ;get byte from a fifo buffer
-
- ; external addresses
-
- extrn cibcb ;A(console input buffer)
- extrn cobcb ;A(console output buffer)
- extrn pobcb ;A(printer buffer)
-
-
- ; standard ASCII equates
-
- bell equ 07h
- tab equ 09h
- cr equ 0dh
- lf equ 0ah
- esc equ 1bh
-
- ; CP/M BDOS function equates
-
- conotf equ 2 ;console output function
- listf equ 5 ;list output function
- diriof equ 6 ;direct console I/O
- frcbuf equ 10 ;read edited input line
-
- ; CP/M address equates:
-
- fcb equ 005ch ;default file control block
- bdos equ 0005h ;BDOS entry address
-
- cseg ;code section
-
- ; in-line print routine
- ; on entry: text to be printed follows call
- ; to this routine, and is
- ; terminated by a 0
- ; on exit: <a>, flags clobbered
- ; all other registers unchanged
- ; routine returns to instruction
- ; immediately following message
- ;
-
- ilprt: xthl ;point to first byte of msg
- ilplp: mov a,m ;get byte
- ora a ;terminator?
- jz ilpret ;yes, exit
- ;
- call ctype ;else output character
- inx h ;bump pointer
- jmp ilplp ;and go back for more
- ;
- ilpret: inx h ;bump past terminator
- xthl ;put next address on stack
- ret ;and go there
-
-
-
- ; output character in <a> to console buffer
- ; and to printer buffer if printer enabled
- ; on entry: <a>= character
- ; on exit: all flags, regs unchanged
- ;
- ctype: push psw ;save regs
- push h ; /
- push d ; /
- push b ; /
- mov b,a ;save char in <b>
- lxi h,cobcb ;point to console output buffer
- call putbuf ;and write it there
- lda prnflg ;get print flag
- ora a ;printer enabled?
- jz ctyexi ;no, exit
- ;
- mov a,b ;get back byte
- lxi h,pobcb ;point to printer output buffer
- call putbuf ;write char there
- ;
- ; common exit
- ctyexi: call copol ;poll crt output
- pop b ;restore regs
- pop d ; /
- pop h ; /
- pop psw ; /
- ret
-
-
-
- ; output character in <a> to console buffer (only)
- ; (used for clearing crt screen, end of line, etc)
- ; on entry: <a>= character
- ; on exit: all flags, regs unchanged
- ;
- cview: push psw ;save regs
- push h ; /
- push d ; /
- push b ; /
- lxi h,cobcb ;point to console output buffer
- call putbuf ;and write it there
- call copol ;poll crt output
- pop b ;restore regs
- pop d ; /
- pop h ; /
- pop psw ; /
- ret
-
-
-
- ; general purpose move routine
- ; (internally and externally called)
- ; on entry: <hl>=source address
- ; <de>=destination address
- ; <bc>=number of bytes to move
- ; on exit: <hl>=last source address+1
- ; <de>=last dest address+1
- ; <bc>=0
-
- move:
- ldir
- ret
-
-
-
- ; dispatch routine
- ; on entry: <a>=offset into table (0-127)
- ; table of addresses follows calling routine
- ; on exit: <a>,flags clobbered
- ; all other regs unchanged
- ;
- disptch:
- rlc ;double the offset bits
- xthl ;save hl, get adress of table
- push d ;save de
- mov e,a ;put doubled code in e
- mvi d,0 ;and clear d
- dad d ;offset into table
- mov a,m ;get low byte of destination
- inx h ;and now high byte
- mov h,m ;high byte into h
- mov l,a ;and low byte into l
- pop d ;restore de
- xthl ;put dest address on stack, restore hl
- ret ;dispatch to destination
-
-
-
-
- ; get edited console string
- ; on entry: no parameters
- ; on exit: all regs unchanged
- ; console string is in inbuf
-
- instr:
- push b
- push d
- push h
- mvi c,frcbuf
- lxi d,inbuf
- call bdos
- pop h
- pop d
- pop b
- ret
-
-
-
- ; convert ASCII decimal number in input buffer to binary
- ; on entry: no parameters
- ; on exit: <de>=binary number
- ; carry set if conversion error
- ;
- decbin: push h ;save regs
- push b ; /
- lxi d,0 ;clear binary number
- lxi h,inbuf+1 ;<hl>=A(# of input characters)
- mov b,m ;<b>,<a>=# of input characters
- mov a,b ; /
- ora a ;no input?
- jz addexi ;yes, return with <de>=0
- ;
- dbloop: inx h ;get a digit
- mov a,m ; /
- sui '0' ;convert to binary
- jc addexi ;return with carry if <0
- ;
- cpi 10 ;or if >9
- cmc ; /
- jc addexi ; /
- ;
- ora a ;=0?
- jz nxtdig ;yes, get next digit
- ;
- adddig: inx d ;else add digit in <a> to <de>
- dcr a ; /
- jnz adddig ; /
- ;
- nxtdig: dcr b ;last digit?
- jz addexi ;yes, normal exit
- ;
- push h ;else save <hl>
- lxi h,0 ;clear <hl>
- mvi c,10 ;and multiply <de> by 10
- mult10: dad d ; /
- dcr c ; /
- jnz mult10 ; /
- ;
- xchg ;restore number to <de>
- pop h ;restore <hl>
- jmp dbloop ;and get next digit
- ;
- addexi: pop b ;restore regs
- pop h ; /
- ret
-
-
- ; convert ASCII hex digit to binary
- ; (externally called)
- ; on entry: <a>= hex digit
- ; on exit: <a>= binary equivalent
- ; carry set if conversion error
- ; other flags clobbered
- ; all other regs unchanged
- hexbin:
- sui '0' ;subtract ASCII bias
- rc ;error if <0
- ;
- cpi 10 ;is it <10?
- cmc ;yes, return with value
- rnc ; /
- ;
- ani 0101$1111b ;convert to upper case
- cpi 'G'-'0' ;is it >F?
- cmc ;yes, return with carry
- rc ; /
- ;
- sui 'A'-'9'-1 ;else adjust A-F
- cpi 10 ;set carry if not >10
- ret
-
-
-
- ; print binary number in ASCII
- ; on entry: <hl>=binary number
- ; on exit: <a>,flags clobbered
- ; all other regs unchanged
-
- pdec:
- push h ;save regs
- push d ; /
- push b ; /
- lxi d,numbuf ;point to number buffer
- call bindec ;convert # to ASCII
- lxi h,numbuf ;point to number buffer
- mvi b,4 ;max # of leading zeros
- mvi a,'0' ;blank leading zeros
- blnklp: cmp m ;is char a zero?
- jnz pdec1 ;no, all finished
- ;
- mvi m,' ' ;yes, blank it
- inx h ;bump pointer
- dcr b ;last leading zero?
- jnz blnklp ;no, keep going
- ;
- pdec1: call ilprt ;print it
- numbuf: db '00000',0
- pop b ;restore regs
- pop d ; /
- pop h ; /
- ret
-
-
-
-
- ; convert binary number 0-65535 to decimal ASCII
- ; (internally called)
- ; on entry: <hl>=binary number
- ; <de>=address of buffer to put ASCII digits
- ; on exit: buffer contains ASCII number
- ; terminated by binary 0
- ; regs, flags clobbered
-
- bindec: lxi b,-10000 ;digit value
- call cdigit ;convert first digit
- lxi b,-1000 ;convert next digit
- call cdigit ; /
- lxi b,-100 ;convert next digit
- call cdigit ; /
- lxi b,-10 ;convert next digit
- call cdigit ; /
- lxi b,-1 ;convert last digit
- call cdigit ; /
- mvi a,0 ;put terminator in buffer
- stax d ; /
- ret
-
-
- ; convert a digit
- cdigit: mvi a,'0'-1 ;initialize ASCII value
- push d ;save buffer pointer
- cdloop: mov e,l ;save last iteration
- mov d,h ; /
- inr a ;increment ASCII digit
- dad b ;subtract value
- jc cdloop ;repeat till underflow
- ;
- mov l,e ;get previous iteration
- mov h,d ; /
- pop d ;restore buffer pointer
- stax d ;store byte in buffer
- inx d ;bump pointer
- ret
-
-
-
-
- ; print byte in binary '1''s and '0''s
- ; (clever routine adapted from TDL)
- ; on entry: <a>=byte
- ; on exit: <a>,flags clobbered
- ; all other regs unchanged
- pbin:
- push b ;save <bc>
- mvi b,8 ;# of bits to output
- pbit: ral ;move msb to carry
- push psw ;sabe byte
- mvi a,'0'/2 ;make '0' or '1'
- adc a ; /
- call ctype ;output char
- pop psw ;restore byte
- dcr b ;last bit?
- jnz pbit ;no, keep going
- ;
- pop b ;else restore <bc>
- ret
-
-
- ; print byte in ASCII hex format (phex)
- ; print nibble in ASCII hex format (phex1)
- ; (externally and internally called)
- ; on entry: <a>=byte
- ; on exit: <a>,flags clobbered
- ; all other regs unchanged
-
- phex: push psw ;save byte
- rrc ;move upper nibble down
- rrc ; /
- rrc ; /
- rrc ; /
- call phex1 ;output it
- pop psw ;restore byte
- phex1: ani 0fh ;strip lower nibble
- adi 90h ;convert to ASCII character
- daa ; /
- aci 40h ; /
- daa ; /
- call ctype ;output hex digit
- ret
-
-
-
- ; poll console and printer
- ; (externally and internally called)
- ; on entry: no parameters
- ; on exit: all registers unchanged
-
- poll: push psw ;save all registers & flags
- push b ; /
- push d ; /
- push h ; /
- call cipol ;poll console input
- call copol ;poll console output
- call popol ;poll printer output
- pop h ;restore registers & flags
- pop d ; /
- pop b ; /
- pop psw ; /
- ret
-
-
- ;--> poll console input
-
- cipol: mvi c,diriof ;direct I/O function
- mvi e,0ffh ;console request
- call bdos ;do it
- ora a ;console input ready?
- rz ;no, return
- ;
- lxi h,cibcb ;else put byte in queue buffer
- call putbuf ; /
- rnc ;return if all ok
- ;
- call ilprt ;else display error message
- db cr,lf,'L4: console input buffer overflow',cr,lf,bell,0
- ret
-
-
- ;--> output byte to console if available
-
- copol: lxi h,cobcb ;get byte from queue buffer
- call getbuf ; /
- rc ;return if no byte available
- ;
- mvi c,diriof ;direct I/O function
- mov e,a ;else, output byte
- call bdos
- ret
-
-
- ;--> poll printer output
-
- popol: lhld 0001h ;get start of bios vector table
- lxi d,2dh-3h ;offset to list status entry point
- dad d ; /
- call go ;get list device status
- ora a ;ready?
- rz ;no, return
- ;
- lxi h,pobcb ;get byte from queue buffer
- call getbuf ; /
- rc ;return if no byte available
- ;
- mov e,a ;else, output byte
- mvi c,listf ;list output function
- call bdos ;and do it
- ret
-
- go: pchl ;dispatch to <hl>
-
-
-
- ; wait a little bit
- ; on entry: no parameters
- ; on exit: all regs, flags unchanged
-
- delay: push psw ;save regs
- push h ; /
- push d ; /
- push b ; /
- lxi d,0 ;<de>= outer loop
- lxi h,0 ;<hl>= inner loop
- dloop: dcx d ;bump <de>
- dloop1: dcx h ;bump <hl>
- mov a,h ;all counted out?
- cmp l ; /
- jnz dloop1 ;no, keep counting
- ;
- mov a,d ;outer loop counted out?
- cmp e ; /
- jnz dloop ;no, keep counting
- ;
- pop b ;restore regs
- pop d ; /
- pop h ; /
- pop psw ; /
- ret
-
-
-
-
- ; *****************
- ; * data area *
- ; *****************
-
-
- dseg ;data segment
-
- prnflg db 0 ;print on/off flag
- inbuf: db 128,0,0 ;initialized console input buffer
- ds 127 ;console input buffer area
-
-
-
-
-
-
-
-