home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / MODEMS / MODEM / X25.ARK / XUTIL.ASM < prev   
Assembly Source File  |  1986-07-28  |  11KB  |  523 lines

  1. title 'XUTIL.ASM'
  2. ;************************************************
  3. ;*                        *
  4. ;*        XUTIL.ASM            *
  5. ;*                        *
  6. ;*  General purpose utility routines for X.25    *
  7. ;*  protocol interface program            *
  8. ;*                        *
  9. ;*  rev 0.16    08/21/84    E. Elizondo    *
  10. ;*                        *
  11. ;*  (c) 1984 E. Elizondo - all rights reserved. *
  12. ;*                        *
  13. ;*    This program may be used freely for non-  *
  14. ;*  commercial applications. It may not be sold *
  15. ;*  or used for commercial applications without *
  16. ;*  written permission of the author.           *
  17. ;*                         *
  18. ;************************************************
  19. ;    
  20.     
  21.     maclib    Z80        ;DR Z80 macro library
  22.  
  23.  
  24. ;    subroutine entry points
  25.  
  26.     public    ilprt        ;in-line print routine
  27.     public    ctype        ;output char to console and printer
  28.     public    cview        ;output char to console only
  29.     public    move        ;move block of data
  30.     public    decbin        ;convert decimal ASCII to binary
  31.     public    hexbin        ;convert hex ASCII digit to binary
  32.     public    pdec        ;print binary number in ASCII decimal
  33.     public    pbin        ;print byte in binary
  34.     public    phex        ;print byte in hex
  35.     public    phex1        ;print nibble in hex
  36.     public    disptch        ;dispatch routine
  37.     public    instr        ;input string from console
  38.     public    poll        ;poll console & printer
  39.     public    delay        ;wait a bit
  40.  
  41. ;    address hooks
  42.     public    inbuf        ;console input buffer
  43.     public    prnflg        ;printer ena/dis flag
  44.  
  45. ;    external subroutines
  46.  
  47.     extrn    putbuf        ;put byte into a fifo buffer
  48.     extrn    getbuf        ;get byte from a fifo buffer
  49.  
  50. ;    external addresses
  51.  
  52.     extrn    cibcb        ;A(console input buffer)
  53.     extrn    cobcb        ;A(console output buffer)
  54.     extrn    pobcb        ;A(printer buffer)
  55.  
  56.  
  57. ;    standard ASCII equates
  58.  
  59. bell    equ    07h
  60. tab    equ    09h
  61. cr    equ    0dh
  62. lf    equ    0ah
  63. esc    equ    1bh
  64.  
  65. ;    CP/M BDOS function equates
  66.  
  67. conotf    equ    2        ;console output function
  68. listf    equ    5        ;list output function
  69. diriof    equ    6        ;direct console I/O
  70. frcbuf    equ    10        ;read edited input line
  71.     
  72. ;    CP/M address equates:
  73.  
  74. fcb    equ    005ch        ;default file control block
  75. bdos    equ    0005h        ;BDOS entry address
  76.  
  77.     cseg            ;code section
  78.  
  79. ;    in-line print routine
  80. ;    on entry:    text to be printed follows call
  81. ;            to this routine, and is
  82. ;            terminated by a 0
  83. ;    on exit:    <a>, flags clobbered
  84. ;            all other registers unchanged
  85. ;            routine returns to instruction 
  86. ;            immediately following message
  87. ;
  88.  
  89. ilprt:    xthl            ;point to first byte of msg
  90. ilplp:    mov    a,m        ;get byte
  91.     ora    a        ;terminator?
  92.     jz    ilpret        ;yes, exit
  93. ;
  94.     call    ctype        ;else output character
  95.     inx    h        ;bump pointer
  96.     jmp    ilplp        ;and go back for more
  97. ;
  98. ilpret:    inx    h        ;bump past terminator
  99.     xthl            ;put next address on stack
  100.     ret            ;and go there
  101.  
  102.  
  103.  
  104. ;    output character in <a> to console buffer
  105. ;    and to printer buffer if printer enabled
  106. ;    on entry:    <a>= character
  107. ;    on exit:    all flags, regs unchanged
  108. ;
  109. ctype:    push    psw        ;save regs
  110.     push    h        ;    /
  111.     push    d        ;      /
  112.     push    b        ;     /
  113.     mov    b,a        ;save char in <b>
  114.     lxi    h,cobcb        ;point to console output buffer
  115.     call    putbuf        ;and write it there
  116.     lda    prnflg        ;get print flag
  117.     ora    a        ;printer enabled?
  118.     jz    ctyexi        ;no, exit
  119. ;
  120.     mov    a,b        ;get back byte
  121.     lxi    h,pobcb        ;point to printer output buffer
  122.     call    putbuf        ;write char there
  123. ;
  124. ;    common exit
  125. ctyexi:    call    copol        ;poll crt output
  126.     pop    b        ;restore regs
  127.     pop    d        ;    /  
  128.     pop    h        ;      /
  129.     pop    psw        ;     /
  130.     ret
  131.  
  132.  
  133.  
  134. ;    output character in <a> to console buffer (only)
  135. ;    (used for clearing crt screen, end of line, etc)
  136. ;    on entry:    <a>= character
  137. ;    on exit:    all flags, regs unchanged
  138. ;
  139. cview:    push    psw        ;save regs
  140.     push    h        ;    /
  141.     push    d        ;      /
  142.     push    b        ;     /
  143.     lxi    h,cobcb        ;point to console output buffer
  144.     call    putbuf        ;and write it there
  145.     call    copol        ;poll crt output
  146.     pop    b        ;restore regs
  147.     pop    d        ;    /  
  148.     pop    h        ;      /
  149.     pop    psw        ;     /
  150.     ret
  151.  
  152.  
  153.  
  154. ;    general purpose move routine
  155. ;    (internally and externally called)
  156. ;    on entry:    <hl>=source address
  157. ;            <de>=destination address
  158. ;            <bc>=number of bytes to move
  159. ;    on exit:    <hl>=last source address+1
  160. ;            <de>=last dest address+1
  161. ;            <bc>=0
  162.  
  163. move:    
  164.     ldir
  165.     ret
  166.  
  167.  
  168.  
  169. ;    dispatch routine
  170. ;    on entry:    <a>=offset into table (0-127)
  171. ;            table of addresses follows calling routine
  172. ;    on exit:    <a>,flags clobbered
  173. ;            all other regs unchanged
  174. ;
  175. disptch:
  176.     rlc        ;double the offset bits
  177.     xthl        ;save hl, get adress of table
  178.     push    d    ;save de
  179.     mov    e,a    ;put doubled code in e
  180.     mvi    d,0    ;and clear d
  181.     dad    d    ;offset into table
  182.     mov    a,m    ;get low byte of destination
  183.     inx    h    ;and now high byte
  184.     mov    h,m    ;high byte into h
  185.     mov    l,a    ;and low byte into l
  186.     pop    d    ;restore de
  187.     xthl        ;put dest address on stack, restore hl
  188.     ret        ;dispatch to destination
  189.  
  190.  
  191.  
  192.  
  193. ;    get edited console string
  194. ;    on entry:    no parameters
  195. ;    on exit:    all regs unchanged
  196. ;            console string is in inbuf
  197.  
  198. instr:
  199.     push    b
  200.     push    d
  201.     push    h
  202.     mvi    c,frcbuf
  203.     lxi    d,inbuf
  204.     call    bdos
  205.     pop    h
  206.     pop    d
  207.     pop    b
  208.     ret
  209.  
  210.  
  211.  
  212. ;    convert ASCII decimal number in input buffer to binary
  213. ;    on entry:    no parameters
  214. ;    on exit:    <de>=binary number
  215. ;            carry set if conversion error
  216. ;
  217. decbin:    push    h    ;save regs
  218.     push    b    ;    /
  219.     lxi    d,0    ;clear binary number
  220.     lxi    h,inbuf+1    ;<hl>=A(# of input characters)
  221.     mov    b,m    ;<b>,<a>=# of input characters
  222.     mov    a,b    ;    /
  223.     ora    a    ;no input?
  224.     jz    addexi    ;yes, return with <de>=0
  225. ;
  226. dbloop:    inx    h    ;get a digit
  227.     mov    a,m    ;    /
  228.     sui    '0'    ;convert to binary
  229.     jc    addexi    ;return with carry if <0
  230. ;
  231.     cpi    10    ;or if >9
  232.     cmc        ;    /
  233.     jc    addexi    ;      /
  234. ;
  235.     ora    a    ;=0?
  236.     jz    nxtdig    ;yes, get next digit
  237. ;
  238. adddig:    inx    d    ;else add digit in <a> to <de>
  239.     dcr    a    ;    /
  240.     jnz    adddig    ;      /
  241. ;
  242. nxtdig:    dcr    b    ;last digit?
  243.     jz    addexi    ;yes, normal exit
  244. ;
  245.     push    h    ;else save <hl>
  246.     lxi    h,0    ;clear <hl>
  247.     mvi    c,10    ;and multiply <de> by 10
  248. mult10:    dad    d    ;    /
  249.     dcr    c    ;      /
  250.     jnz    mult10    ;     /
  251. ;
  252.     xchg        ;restore number to <de>
  253.     pop    h    ;restore <hl>
  254.     jmp    dbloop    ;and get next digit
  255. ;
  256. addexi:    pop    b    ;restore regs
  257.     pop    h    ;    /
  258.     ret
  259.  
  260.  
  261. ;    convert ASCII hex digit to binary
  262. ;    (externally called)
  263. ;    on entry:    <a>= hex digit
  264. ;    on exit:    <a>= binary equivalent
  265. ;            carry set if conversion error
  266. ;            other flags clobbered
  267. ;            all other regs unchanged
  268. hexbin:
  269.     sui    '0'    ;subtract ASCII bias
  270.     rc        ;error if <0
  271. ;
  272.     cpi    10    ;is it <10?
  273.     cmc        ;yes, return with value
  274.     rnc        ;    /
  275. ;
  276.     ani    0101$1111b    ;convert to upper case
  277.     cpi    'G'-'0'    ;is it >F?
  278.     cmc        ;yes, return with carry
  279.     rc        ;    /
  280. ;
  281.     sui    'A'-'9'-1    ;else adjust A-F
  282.     cpi    10    ;set carry if not >10
  283.     ret            
  284.  
  285.  
  286.  
  287. ;    print binary number in ASCII
  288. ;    on entry:    <hl>=binary number
  289. ;    on exit:    <a>,flags clobbered
  290. ;            all other regs unchanged
  291.  
  292. pdec:    
  293.     push    h        ;save regs
  294.     push    d        ;    /
  295.     push    b        ;      /
  296.     lxi    d,numbuf    ;point to number buffer
  297.     call    bindec        ;convert # to ASCII
  298.     lxi    h,numbuf    ;point to number buffer
  299.     mvi    b,4        ;max # of leading zeros
  300.     mvi    a,'0'        ;blank leading zeros
  301. blnklp:    cmp    m        ;is char a zero?
  302.     jnz    pdec1        ;no, all finished
  303. ;
  304.     mvi    m,' '        ;yes, blank it
  305.     inx    h        ;bump pointer
  306.     dcr    b        ;last leading zero?
  307.     jnz    blnklp        ;no, keep going
  308. ;
  309. pdec1:    call    ilprt        ;print it
  310. numbuf:    db    '00000',0
  311.     pop    b        ;restore regs
  312.     pop    d        ;    /
  313.     pop    h        ;      /
  314.     ret
  315.  
  316.  
  317.  
  318.  
  319. ;    convert binary number 0-65535 to decimal ASCII
  320. ;    (internally called)
  321. ;    on entry:    <hl>=binary number
  322. ;            <de>=address of buffer to put ASCII digits
  323. ;    on exit:    buffer contains ASCII number 
  324. ;            terminated by binary 0
  325. ;            regs, flags clobbered
  326.  
  327. bindec:    lxi    b,-10000    ;digit value
  328.     call    cdigit        ;convert first digit
  329.     lxi    b,-1000        ;convert next digit
  330.     call    cdigit        ;    /
  331.     lxi    b,-100        ;convert next digit
  332.     call    cdigit        ;    /
  333.     lxi    b,-10        ;convert next digit
  334.     call    cdigit        ;    /
  335.     lxi    b,-1        ;convert last digit
  336.     call    cdigit        ;    /
  337.     mvi    a,0        ;put terminator in buffer
  338.     stax    d        ;    /
  339.     ret
  340.     
  341.  
  342. ;    convert a digit
  343. cdigit:    mvi    a,'0'-1        ;initialize ASCII value
  344.     push    d        ;save buffer pointer
  345. cdloop:    mov    e,l        ;save last iteration
  346.     mov    d,h        ;    /
  347.     inr    a        ;increment ASCII digit
  348.     dad    b        ;subtract value
  349.     jc    cdloop        ;repeat till underflow
  350. ;
  351.     mov    l,e        ;get previous iteration
  352.     mov    h,d        ;    /
  353.     pop    d        ;restore buffer pointer
  354.     stax    d        ;store byte in buffer
  355.     inx    d        ;bump pointer
  356.     ret    
  357.  
  358.  
  359.  
  360.  
  361. ;    print byte in binary '1''s and '0''s
  362. ;    (clever routine adapted from TDL)
  363. ;    on entry:    <a>=byte
  364. ;    on exit:    <a>,flags clobbered
  365. ;            all other regs unchanged
  366. pbin:
  367.     push    b        ;save <bc>
  368.     mvi    b,8        ;# of bits to output
  369. pbit:    ral            ;move msb to carry
  370.     push    psw        ;sabe byte
  371.     mvi    a,'0'/2        ;make '0' or '1'
  372.     adc    a        ;    /
  373.     call    ctype        ;output char
  374.     pop    psw        ;restore byte
  375.     dcr    b        ;last bit?
  376.     jnz    pbit        ;no, keep going
  377. ;
  378.     pop    b        ;else restore <bc>
  379.     ret
  380.  
  381.  
  382. ;    print byte in ASCII hex format (phex)
  383. ;    print nibble in ASCII hex format (phex1)
  384. ;    (externally and internally called)
  385. ;    on entry:    <a>=byte
  386. ;    on exit:    <a>,flags clobbered
  387. ;            all other regs unchanged
  388.  
  389. phex:    push    psw        ;save byte
  390.     rrc            ;move upper nibble down
  391.     rrc            ;    /
  392.     rrc            ;      /
  393.     rrc            ;     /
  394.     call    phex1        ;output it
  395.     pop    psw        ;restore byte
  396. phex1:    ani    0fh        ;strip lower nibble
  397.     adi    90h        ;convert to ASCII character
  398.     daa            ;    /
  399.     aci    40h        ;      /
  400.     daa            ;     /
  401.     call    ctype        ;output hex digit
  402.     ret
  403.  
  404.  
  405.  
  406. ;    poll console and printer
  407. ;    (externally and internally called)
  408. ;    on entry:    no parameters
  409. ;    on exit:    all registers unchanged
  410.  
  411. poll:    push    psw        ;save all registers & flags
  412.     push    b        ;    /
  413.     push    d        ;      /
  414.     push    h        ;     /
  415.     call    cipol        ;poll console input
  416.     call    copol        ;poll console output
  417.     call    popol        ;poll printer output
  418.     pop    h        ;restore registers & flags
  419.     pop    d        ;    /
  420.     pop    b        ;      /
  421.     pop    psw        ;     /
  422.     ret    
  423.  
  424.  
  425. ;--> poll console input
  426.  
  427. cipol:    mvi    c,diriof    ;direct I/O function
  428.     mvi    e,0ffh        ;console request
  429.     call    bdos        ;do it
  430.     ora    a        ;console input ready?
  431.     rz            ;no, return
  432. ;
  433.     lxi    h,cibcb        ;else put byte in queue buffer
  434.     call    putbuf        ;    /
  435.     rnc            ;return if all ok
  436. ;
  437.     call    ilprt        ;else display error message
  438.     db    cr,lf,'L4: console input buffer overflow',cr,lf,bell,0
  439.     ret
  440.  
  441.  
  442. ;--> output byte to console if available
  443.  
  444. copol:    lxi    h,cobcb        ;get byte from queue buffer
  445.     call    getbuf        ;    /
  446.     rc            ;return if no byte available
  447. ;
  448.     mvi    c,diriof    ;direct I/O function
  449.     mov    e,a        ;else, output byte
  450.     call    bdos
  451.     ret
  452.  
  453.  
  454. ;--> poll printer output
  455.  
  456. popol:    lhld    0001h        ;get start of bios vector table
  457.     lxi    d,2dh-3h    ;offset to list status entry point
  458.     dad    d        ;    /
  459.     call    go        ;get list device status
  460.     ora    a        ;ready?
  461.     rz            ;no, return
  462. ;
  463.     lxi    h,pobcb        ;get byte from queue buffer
  464.     call    getbuf        ;    /
  465.     rc            ;return if no byte available
  466. ;
  467.     mov    e,a        ;else, output byte
  468.     mvi    c,listf        ;list output function
  469.     call    bdos        ;and do it
  470.     ret
  471.  
  472. go:    pchl            ;dispatch to <hl>
  473.  
  474.  
  475.  
  476. ;    wait a little bit
  477. ;    on entry:    no parameters
  478. ;    on exit:    all regs, flags unchanged
  479.  
  480. delay:    push    psw        ;save regs
  481.     push    h        ;    /
  482.     push    d        ;      /
  483.     push    b        ;     /
  484.     lxi    d,0        ;<de>= outer loop
  485.     lxi    h,0        ;<hl>= inner loop
  486. dloop:    dcx    d        ;bump <de>
  487. dloop1:    dcx    h        ;bump <hl>
  488.     mov    a,h        ;all counted out?
  489.     cmp    l        ;    /
  490.     jnz    dloop1        ;no, keep counting
  491. ;
  492.     mov    a,d        ;outer loop counted out?
  493.     cmp    e        ;    /
  494.     jnz    dloop        ;no, keep counting
  495. ;
  496.     pop    b        ;restore regs
  497.     pop    d        ;    /
  498.     pop    h        ;      /
  499.     pop    psw        ;     /
  500.     ret
  501.  
  502.  
  503.  
  504.  
  505. ;    *****************
  506. ;    *  data area    *
  507. ;    *****************
  508.  
  509.  
  510.     dseg            ;data segment
  511.  
  512. prnflg    db    0        ;print on/off flag
  513. inbuf:    db    128,0,0        ;initialized console input buffer
  514.     ds    127        ;console input buffer area
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.  
  523.