home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol238 / buffers.aqm / BUFFERS.ASM
Assembly Source File  |  1986-02-10  |  27KB  |  1,105 lines

  1. title 'BUFFERS.ASM'
  2. ;************************************************
  3. ;*                        *
  4. ;*            buffers.asm            *
  5. ;*                        *
  6. ;* data buffers and buffer service routines    *
  7. ;* for X.25 protocol interface.            *
  8. ;*                        *
  9. ;* rev 1.44    08/15/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.     maclib    Z80        ;DR Z80 macro library
  21.  
  22. ;    design parameters
  23.  
  24. pdsize:    equ    128        ;max packet user data field length
  25. numrxb:    equ    16        ;number of receive buffers
  26. ;    dteclr and dtebus values must be positive and less
  27. ;    than numrxb, and dtebus must be less than dteclr
  28. dteclr:    equ    10        ;# of free buffers for DTE clear
  29. dtebus:    equ    4        ;# of free buffers for DTE busy
  30. ;
  31. numtxb:    equ    8        ;number of transmit buffers
  32. cbsize:    equ    256        ;console buffer size
  33. pbsize:    equ    1024        ;printer buffer size
  34.  
  35. ;    do not change this:
  36. fbsize:    equ    pdsize+6    ;frame buffer size
  37.  
  38. ;    hooks for other modules
  39.  
  40. ;    suboutine entry points
  41.     public    putbuf        ;write byte to end of buffer
  42.     public    topbuf        ;write byte to beginning of buffer
  43.     public    getbuf        ;read byte from buffer
  44.     public    bpoint        ;point to buffer bcb
  45.     public    inibuf        ;initialize buffer parameters
  46.     public    rlsrxb        ;release rx buffer to pool
  47.     public    newrxb        ;get new rx buffer for use
  48.     public    clrbuf        ;clear (any) buffer for new use
  49.     public    clrtxb        ;clear all tx buffers for new use
  50.     public    getbct        ;get buffer count
  51.     public    dcrbuf        ;decrement buffer count
  52.     public    getrdy        ;get state of buffer ready flag
  53.     public    setrdy        ;set buffer ready flag
  54.     public    clrrdy        ;clear buffer ready flag
  55.     public    savbcb        ;save bcb
  56.     public    resbcb        ;restore bcb
  57.  
  58. ;    buffer control block (bcb) adresses
  59.     public    cibcb        ;A(bcb for console input)
  60.     public    cobcb        ;A(bcb for console output)
  61.     public    ctbcb        ;A(bcb for console transmit)
  62.     public    crbcb        ;A(bcb for consore receive)
  63.     public    pobcb        ;A(bcb for printer output)
  64.     public    rxbtab        ;A(table of rx bcb pointers)
  65.     public    txbtab        ;A(table of tx bcb pointers)
  66.     public    rxfree        ;A(bcb for #'s of free rx buffers)
  67.     public    rxflst        ;A(bcb for #'s of rx frame buffers)
  68.     public    rxplst        ;A(bcb for #'s if rx packet #'s)
  69.     public    txubcb        ;A(bcb for rx U type frame)
  70.  
  71. ;    other addresses
  72.     public    rxbact        ;active rx buffer #
  73.     public    rxbcbp        ;active rx bcb address
  74.     public    txbcbp        ;active tx bcb address
  75.  
  76. ;    
  77.  
  78.  
  79. ;    external addresses
  80.     extrn    l3stat        ;level 3 flow status word
  81.     extrn    lkstat        ;level 2 status word
  82.     extrn    rxstat        ;level 1 rx status word
  83.     extrn    dtemod        ;level 2 mode flag
  84.  
  85. ;    *****************
  86. ;    *  subroutines    *
  87. ;    *****************
  88.  
  89.  
  90. ;      write a byte to end of buffer
  91. ;    (externally called, re-entrant)
  92. ;    on entry:    <hl>=A(buffer control block)
  93. ;             <a>=byte
  94. ;    on exit:    carry set if buffer overflow
  95. ;            other flags clobbered
  96. ;            all regs unchanged
  97.  
  98. putbuf:    push    h        ;save registers
  99.     push    d        ;    /
  100.     push    b        ;      /
  101.     mov    b,a        ;move byte to <b>
  102.     push    b        ;and save byte
  103.     mov    e,m        ;<de>= count
  104.     inx    h        ;    /
  105.     mov    d,m        ;      /
  106.     inx    d        ;increment count
  107.     inx    h        ;<bc>= max count
  108.     mov    c,m        ;    /
  109.     inx    h        ;      /
  110.     mov    b,m        ;     /
  111.     call    bcmde        ;buffer overflow?
  112.     pop    b        ;restore byte to <a>
  113.     mov    a,b        ;    /
  114.     push    b        ;and save byte again
  115.     jc    putexi        ;yes, return with carry set
  116. ;
  117.     dcx    h        ;else point again to count
  118.     dcx    h        ;    /
  119.     mov    m,d        ;and save new count
  120.     dcx    h        ;    /
  121.     mov    m,e        ;      /
  122.     lxi    d,4        ;<hl>= A(write pointer)
  123.     dad    d        ;    /
  124.     push    h        ;save A(write pointer)
  125.     mov    e,m        ;<de>= write pointer
  126.     inx    h        ;    /
  127.     mov    d,m        ;      /
  128.     stax    d        ;store byte in buffer
  129.     inx    d        ;bump pointer
  130.     inx    h        ;<hl>=A(pointer max value)
  131.     mov    c,m        ;<bc>=pointer max value
  132.     inx    h        ;    /
  133.     mov    b,m        ;      /
  134.     call    bcmde        ;pointer overflow?
  135.     jnc    putptr        ;no, save pointer
  136. ;
  137.     inx    h        ;else, <hl>=A(pointer min value)
  138.     mov    e,m        ;<de>=pointer min value
  139.     inx    h        ;    /
  140.     mov    d,m        ;      /
  141. ;
  142. putptr:    pop    h        ;<hl>=A(write pointer)
  143.     mov    m,e        ;update pointer
  144.     inx    h        ;    /
  145.     mov    m,d        ;      /
  146.     stc            ;and reset carry
  147.     cmc            ;    /
  148. ;
  149. putexi:    pop    b        ;restore byte in <a>
  150.     mov    a,b        ;    /
  151.     pop    b        ;restore registers and exit
  152.     pop    d        ;    /
  153.     pop    h        ;      /
  154.     ret            ;     /
  155.  
  156.  
  157. ;      write a byte to beginning of buffer
  158. ;    (externally called)
  159. ;    on entry:    <hl>=A(buffer control block)
  160. ;             <a>=byte
  161. ;    on exit:    carry set if buffer overflow
  162. ;            a,other flags clobbered
  163. ;            all other regs unchanged
  164.  
  165. topbuf:    push    h        ;save registers
  166.     push    d        ;    /
  167.     push    b        ;      /
  168.     sta    topbyte        ;save byte
  169.     mov    e,m        ;<de>= count
  170.     inx    h        ;    /
  171.     mov    d,m        ;      /
  172.     inx    d        ;increment count
  173.     inx    h        ;<bc>= max count
  174.     mov    c,m        ;    /
  175.     inx    h        ;      /
  176.     mov    b,m        ;     /
  177.     call    bcmde        ;buffer overflow?
  178.     jc    topexi        ;yes, return with carry set
  179. ;
  180.     dcx    h        ;else point again to count
  181.     dcx    h        ;    /
  182.     mov    m,d        ;and save new count
  183.     dcx    h        ;    /
  184.     mov    m,e        ;      /
  185.     lxi    d,8        ;<hl>= A(pointer min value)
  186.     dad    d        ;    /
  187.     mov    e,m        ;<de>= pointer min value
  188.     inx    h        ;    /
  189.     mov    d,m        ;      /
  190.     inx    h        ;<bc>=read pointer
  191.     mov    c,m        ;    /
  192.     inx    h        ;      /
  193.     mov    b,m        ;     /
  194.     dcx    b        ;back up read pointer
  195.     push    b        ;save new pointer value
  196.     call    bcmde        ;pointer underflow?
  197.     pop    b        ;restore new pointer value
  198.     jnc    topptr        ;no, keep going
  199. ;
  200.     push    h        ;save read pointer
  201.     dcx    h        ;and point to max value
  202.     dcx    h        ;    /
  203.     dcx    h        ;      /
  204.     dcx    h        ;     /
  205.     mov    b,m        ;set <bc>=pointer max value
  206.     dcx    h        ;    /
  207.     mov    c,m        ;      /
  208.     pop    h        ;restore read pointer
  209.  
  210. topptr:    lda    topbyte        ;get back byte
  211.     stax    b        ;store byte in buffer
  212.     mov    m,b        ;update read pointer
  213.     dcx    h        ;    /
  214.     mov    m,c        ;      /
  215.     stc            ;and reset carry
  216.     cmc            ;    /
  217. ;
  218. topexi:    pop    b        ;restore registers and exit
  219.     pop    d        ;    /
  220.     pop    h        ;      /
  221.     ret            ;     /
  222.  
  223. topbyte:db    0        ;temporary storage for byte
  224.  
  225.  
  226.  
  227. ;      read a byte from buffer
  228. ;    (externally called, re-entrant)
  229. ;    on entry:    <hl>=A(buffer control block)
  230. ;    on exit:    carry set if no byte available
  231. ;            <a>= byte (if available)
  232. ;                 0 if no byte available
  233. ;            other flags clobbered
  234. ;            all other regs unchanged
  235.  
  236. getbuf:    push    h        ;save registers
  237.     push    d        ;    /
  238.     push    b        ;      /
  239.     mov    e,m        ;<de>=count
  240.     inx    h        ;    /
  241.     mov    d,m        ;      /
  242.     mov    a,d        ;buffer empty?
  243.     ora    e        ;    /
  244.     stc            ;yes, set carry flag
  245.     jz     getexi        ;and return
  246. ;
  247.     dcx    d        ;else decrement count
  248.     mov    m,d        ;and save updated count
  249.     dcx    h        ;    /
  250.     mov    m,e        ;      /
  251.     lxi    d,6        ;<hl>=A(pointer max value)
  252.     dad    d        ;    /
  253.     mov    c,m        ;<bc>=pointer max value
  254.     inx    h        ;    /
  255.     mov    b,m        ;      /
  256.     lxi    d,3        ;<hl>=A(read pointer)
  257.     dad    d        ;    /
  258.     push    h        ;save A(read pointer)
  259.     mov    e,m        ;<de>=read pointer
  260.     inx    h        ;    /
  261.     mov    d,m        ;      /
  262.     ldax    d        ;get byte
  263.     push    psw        ;and save it
  264.     inx    d        ;bump pointer
  265.     call    bcmde        ;pointer overflow?
  266.     jnc    getptr        ;no, update pointer
  267. ;
  268.     dcx    h        ;<hl>=A(pointer min value)
  269.     dcx    h        ;    /
  270.     mov    d,m        ;<de>=pointer min value
  271.     dcx    h        ;    /
  272.     mov    e,m        ;      /
  273. ;
  274. getptr:    pop    psw        ;get byte
  275.     pop    h        ;<hl>=A(read pointer)
  276.     mov    m,e        ;update pointer    
  277.     inx    h        ;    /
  278.     mov    m,d        ;      /
  279.     stc            ;reset carry flag
  280.     cmc            ;    /
  281. ;
  282. getexi:    pop    b        ;restore registers and return
  283.     pop    d        ;    /
  284.     pop    h        ;      /
  285.     ret            ;     /
  286.  
  287.  
  288. ;    get buffer count
  289. ;    (externally called)
  290. ;    on entry:    <hl>=A(bcb)
  291. ;    on exit:    <de>=buffer count
  292. ;            zero flag set if count=0
  293. ;            other flags clobbered
  294. ;            all other regs unchanged
  295. getbct:    push    h        ;save regs
  296.     push    b        ;      /
  297.     mov    b,a        ;save <a>
  298.     mov    e,m        ;get count lsb
  299.     inx    h        ;get count msb
  300.     mov    d,m        ;    /
  301.     mov    a,d        ;set zero flag if count=0
  302.     ora    e        ;    /
  303.     mov    a,b        ;restore <a>
  304.     pop    b        ;restore regs
  305.     pop    h        ;      /
  306.     ret
  307.  
  308.  
  309. ;      decrement buffer (discard last written byte)
  310. ;    (externally called)
  311. ;    on entry:    <hl>=A(buffer control block)
  312. ;    on exit:    carry set if no byte available
  313. ;            <a>, other flags clobbered
  314. ;            all other regs unchanged
  315.  
  316. dcrbuf:    push    h        ;save registers
  317.     push    d        ;    /
  318.     push    b        ;      /
  319.     mov    e,m        ;<de>=count
  320.     inx    h        ;    /
  321.     mov    d,m        ;      /
  322.     mov    a,d        ;buffer empty?
  323.     ora    e        ;    /
  324.     stc            ;yes, set carry flag
  325.     jz     dcrexi        ;and return
  326. ;
  327.     dcx    d        ;else decrement count
  328.     mov    m,d        ;and save updated count
  329.     dcx    h        ;    /
  330.     mov    m,e        ;      /
  331.     lxi    d,4        ;<hl>=A(write pointer)
  332.     dad    d        ;    /
  333.     push    h        ;save A(write pointer)
  334.     mov    c,m        ;<bc>=write pointer
  335.     inx    h        ;    /
  336.     mov    b,m        ;      /
  337.     lxi    d,3        ;<hl>=A(min value for pointers)
  338.     dad    d        ;    /
  339.     mov    e,m        ;<de>=min value for pointers
  340.     inx    h        ;    /
  341.     mov    d,m        ;      /
  342.     pop    h        ;restore A(write pointer)
  343.     dcx    b        ;decrement write pointer
  344.     mov    m,c        ;and update pointer
  345.     inx    h        ;    /
  346.     mov    m,b        ;      /
  347.     call    bcmde        ;pointer underflow?
  348.     jnc    dcrexi        ;no, exit
  349. ;
  350.     push    h        ;else save write pointer
  351.     inx    h        ;set <de>=max value for pointers
  352.     mov    e,m        ;    /
  353.     inx    h        ;      /
  354.     mov    d,m        ;     /
  355.     pop    h        ;restore write pointer
  356.     mov    m,d        ;set write pointer = max value
  357.     dcx    h        ;    /
  358.     mov    m,e        ;      /
  359.     stc            ;reset carry flag
  360.     cmc            ;    /
  361. ;
  362. dcrexi:    pop    b        ;restore registers and return
  363.     pop    d        ;    /
  364.     pop    h        ;      /
  365.     ret            ;     /
  366.  
  367.  
  368. ;    calculate <bc>=<bc>-<de>
  369. ;    (internally and externally called)
  370. ;    on entry:    <bc>,<de> input values
  371. ;    on exit:    <bc>=result
  372. ;            carry set if <de>.gt.<bc>
  373. ;            <a>,other flags clobbered
  374. ;            all other registers unchanged
  375.  
  376. bcmde:    mov    a,c
  377.     sub    e
  378.     mov    c,a
  379.     mov    a,b
  380.     sbb    d
  381.     mov    b,a
  382.     ret
  383.  
  384.  
  385. ;    release rx buffer for new use and clear level 3 DTE
  386. ;    busy flag if enough free buffers are avalable
  387. ;    (externally called)
  388. ;    on entry:    <a>=rx buffer #
  389. ;    on exit:    all regs, flags unchanged
  390. ;            dte busy flag in level 3 cleared
  391. ;             if # free buffers >= dteclr
  392.  
  393. rlsrxb:
  394.     push    psw        ;save regs & flags
  395.     push    h        ;    /
  396.     push    d        ;      /
  397.     push    b        ;     /
  398.     lxi    h,rxfree    ;point to bcb of list of free buffers
  399.     mov    b,a        ;save buffer # in <b>
  400.     call    putbuf        ;add this buffer # to list
  401.     call    getbct        ;<a>= # of free buffers
  402.     mov    a,e        ;    /
  403.     cpi    dteclr        ;less than dteclr?
  404.     jnc    rls1        ;no, keep going
  405. ;
  406.     lxi    h,l3stat    ;else reset level 3 DTE busy flag
  407.     res    0,m        ;    /
  408. ;
  409. rls1:    mov    a,b        ;restore buffer #
  410.     lxi    h,rxbtab    ;now point to its bcb address
  411.     call    bpoint        ;    /
  412.     call    clrbuf        ;and initialize bcb
  413.     lxi    h,rxstat    ;clear no rx buffers avail flag
  414.     res    5,m        ;    /
  415.     lxi    h,lkstat    ;clear level 2 DTE busy flag
  416.     res    4,m        ;    /
  417.     lda    dtemod        ;get level 2 mode flag
  418.     cpi    3        ;self test mode?
  419.     jnz    rls2        ;no, keep going
  420. ;
  421.     res    3,m        ;else clear level 2 DCE busy flag
  422. ;
  423. rls2:    pop    b        ;restore regs & flags
  424.     pop    d        ;    /
  425.     pop    h        ;      /
  426.     pop    psw        ;     /
  427.     ret
  428.  
  429.  
  430.  
  431. ;    clear (any) buffer for new use
  432. ;    (externally and internally called)
  433. ;    on entry:    <hl>=address of buffer bcb
  434. ;    on exit:    all flags, regs unchanged
  435.  
  436. clrbuf:
  437.     push    psw        ;save regs and flags
  438.     push    b        ;    /
  439.     push    d        ;      /
  440.     push    h        ;     /
  441.     xra    a        ;clear buffer count
  442.     mov    m,a        ;    /
  443.     inx    h        ;      /
  444.     mov    m,a        ;     /
  445.     lxi    d,7        ;point to min value for pointers
  446.     dad    d        ;    /
  447.     mov    c,m        ;<bc>=min value for pointers
  448.     inx    h        ;    /
  449.     mov    b,m        ;      /
  450.     inx    h        ;initialize read pointer
  451.     mov    m,c        ;    /
  452.     inx    h        ;      /
  453.     mov    m,b        ;     /
  454.     inx    h        ;point to ready flag
  455.     mov    m,a        ;and initialize it
  456.     pop    h        ;point to write pointer
  457.     push    h        ;
  458.     lxi    d,4        ;    /
  459.     dad    d        ;      /
  460.     mov    m,c        ;initialize write pointer
  461.     inx    h        ;    /
  462.     mov    m,b        ;      /
  463.     pop    h        ;restore regs and flags
  464.     pop    d        ;    /
  465.     pop    b        ;      /
  466.     pop    psw        ;     /
  467.     ret
  468.  
  469.  
  470. ;    get new receive buffer and set level 3 DTE busy
  471. ;    flag if we are running out of rx buffers
  472. ;    (externally called)
  473. ;    on entry:    no parameters
  474. ;    on exit:    carry set if no buffer available
  475. ;            <a>, flags clobbered
  476. ;            all other regs unchanged
  477. ;            rxbact has active rx buffer #
  478. ;            rxbcbp has address of active rx bcb
  479. ;            L1 no rx buff avail flag set if none free
  480. ;            L3 DTE busy flag set if # of buffers<dtebus
  481.  
  482.  
  483. newrxb:    push    h        ;save regs
  484.     push    d        ;    /
  485.     push    b        ;      /
  486.     lxi    h,rxfree    ;point to list of free buffers
  487.     call    getbuf        ;get one
  488.     jnc    newb1        ;keep going if available
  489. ;
  490. ;    no buffer available
  491.     lxi    h,rxstat    ;set no buffer avail flag
  492.     setb    5,m        ;    /
  493.     lxi    h,lkstat    ;set level 2 DTE busy flag
  494.     setb    4,m        ;    /
  495.     jmp    newexi        ;and exit with carry set
  496. ;
  497. ;    buffer is available
  498. newb1:    sta    rxbact        ;make buffer # active
  499.     mov    b,a        ;and save buffer # in <b>
  500.     call    getbct        ;now get # of free buffers left
  501.     mov    a,e        ;    /
  502.     cpi    dtebus+1    ;less than dtebus?
  503.     jnc    newb2        ;no, keep going
  504. ;
  505. ;    number of buffers left is below threshold
  506.     lxi    h,l3stat    ;set DTE busy flag in level 3
  507.     setb    0,m
  508. ;
  509. ;    get buffer bcb address
  510. newb2:    mov    a,b        ;restore buffer # to a
  511.     lxi    h,rxbtab    ;point to address table
  512.     call    bpoint        ;get address of new bcb
  513.     shld    rxbcbp        ;and make it active
  514.     stc            ;and clear carry flag
  515.     cmc            ;    /
  516. ;
  517. ;    common exit
  518. newexi:    pop    b        ;restore regs
  519.     pop    d        ;    /
  520.     pop    h        ;      /
  521.     ret
  522.  
  523.  
  524. ;    get state of buffer ready flag
  525. ;    (externally called)
  526. ;    on entry:    <hl>=bcb address
  527. ;    on exit:    zero flag set if not ready
  528. ;            all regs unchanged
  529.  
  530. getrdy:    push    h        ;save regs
  531.     push    d        ;    /
  532.     push    b        ;      /
  533.     mov    b,a        ;save <a>
  534.     lxi    d,12        ;point to ready flag
  535.     dad    d        ;    /
  536.     mov    a,m        ;get ready flag
  537.     ora    a        ;set flags
  538.     mov    a,b        ;restore <a>
  539.     pop    b        ;restore regs
  540.     pop    d        ;    /
  541.     pop    h        ;      /
  542.     ret
  543.  
  544.  
  545. ;    set buffer ready flag
  546. ;    (externally called)
  547. ;    on entry:    <hl>=bcb address
  548. ;    on exit:    all regs unchanged
  549.  
  550.  
  551. setrdy:    push    h        ;save regs
  552.     push    d        ;    /
  553.     lxi    d,12        ;point to ready flag
  554.     dad    d        ;    /
  555.     mvi    m,0ffh        ;set ready flag
  556.     pop    d        ;restore regs
  557.     pop    h        ;    /
  558.     ret
  559.  
  560.  
  561. ;    clear buffer ready flag
  562. ;    (externally called)
  563. ;    on entry:    <hl>=bcb address
  564. ;    on exit:    all regs unchanged
  565.  
  566.  
  567. clrrdy:    push    h        ;save regs
  568.     push    d        ;    /
  569.     lxi    d,12        ;point to ready flag
  570.     dad    d        ;    /
  571.     mvi    m,0        ;clear ready flag
  572.     pop    d        ;restore regs
  573.     pop    h        ;    /
  574.     ret
  575.  
  576.  
  577. ;    save bcb for reuse in re-transmission
  578. ;    (externally called)
  579. ;    on entry:    <hl>=bcb address
  580. ;    on exit:    all regs, flags unchanged
  581.  
  582. savbcb:    push    h        ;save registers
  583.     push    d        ;    /
  584.     push    b        ;      /
  585.     lxi    d,tempbcb    ;<de>=A(save area)
  586.     lxi    b,13        ;# of bytes in bcb
  587.     ldir            ;move them
  588.     pop    b        ;restore registers
  589.     pop    d        ;    /
  590.     pop    h        ;      /
  591.     ret
  592.  
  593.  
  594.  
  595. ;    restore bcb for reuse in re-transmission
  596. ;    (externally called)
  597. ;    on entry:    <hl>=bcb address
  598. ;    on exit:    all regs, flags unchanged
  599.  
  600. resbcb:    push    h        ;save registers
  601.     push    d        ;    /
  602.     push    b        ;      /
  603.     xchg            ;<de>=A(bcb)
  604.     lxi    h,tempbcb    ;<hl>=A(save area)
  605.     lxi    b,13        ;# of bytes in bcb
  606.     ldir            ;move them
  607.     pop    b        ;restore registers
  608.     pop    d        ;    /
  609.     pop    h        ;      /
  610.     ret
  611.  
  612.  
  613.  
  614. ;    initialize buffer pointers
  615. ;    (externally called)
  616. ;    on entry:    no parameters
  617. ;    on exit:    all flags, registers clobbered
  618.  
  619. inibuf:
  620.     lxi    h,rxfree    ;clear free rx buffer queue
  621.     call    clrbuf        ;    /
  622.     lxi    h,rxflst    ;clear rx frame buffer # queue
  623.     call    clrbuf        ;    /
  624.     lxi    h,rxplst    ;clear rx packet buffer # queue
  625.     call    clrbuf        ;    /
  626.     lxi    h,ctbcb        ;clear console tx buffer
  627.     call    clrbuf        ;    /
  628.     lxi    h,crbcb        ;clear console rx buffer
  629.     call    clrbuf        ;    /
  630.     lxi    h,txubcb    ;clear tx FRMR/CMDR I tx buffer
  631.     call    clrbuf
  632. ;
  633.     call    clrtxb        ;clear all tx I frame buffers
  634. ;
  635. ;    clear all rx buffers
  636.     mvi    b,numrxb    ;<b>=number of rx buffers
  637.     mvi    c,0        ;<c>= first buffer #
  638.     lxi    d,rxfree    ;<de> points to free buffer list
  639. rxclp:    lxi    h,rxbtab    ;point to bcb table
  640.     mov    a,c        ;get buffer #
  641.     call    bpoint        ;point to buffer
  642.     call    clrbuf        ;clear buffer
  643.     xchg            ;point to free buffer list
  644.     mov    a,c        ;get buffer #
  645.     call    putbuf        ;put buffer # on list
  646.     xchg            ;now point back to bcb
  647.     inr    c        ;bump buffer #
  648.     dcr    b        ;last buffer?
  649.     jnz    rxclp        ;no, keep going
  650. ;
  651. ;    now make first buffer active
  652.     call    newrxb        ;make new buffer active
  653.     ret    
  654.  
  655.  
  656.  
  657. ;    clear all tx buffers
  658. ;    (externally and internally called)
  659. ;    on entry:    no parameters
  660. ;    on exit:    all flags, regs unchanged
  661. ;            active tx pointer initialized to buffer 0
  662.  
  663. clrtxb:
  664.     push    psw        ;save <a>,flags
  665.     push    h        ;save regs
  666.     push    b        ;    /
  667.     mvi    b,numtxb    ;<b>= number of tx buffers
  668.     mvi    a,numtxb-1    ;<a>= highest tx buffer #
  669. clrtx1:    lxi    h,txbtab    ;point to bcb table
  670.     call    bpoint        ;point to a buffer
  671.     call    clrbuf        ;clear buffer
  672.     dcr    a        ;bump buffer #
  673.     dcr    b        ;last buffer?
  674.     jnz    clrtx1        ;no, keep going
  675.     shld    txbcbp        ;initialize active tx pointer
  676.     pop    b        ;restore regs
  677.     pop    h        ;    /
  678.     pop    psw        ;restore <a>,flags
  679.     ret
  680.  
  681.  
  682.  
  683. ;    point to buffer control block
  684. ;    (externally and internally called)
  685. ;    on entry:    <a>=buffer # (1-127)
  686. ;            <hl>=bcb address table
  687. ;    on exit:    <hl>=buffer bcb address
  688. ;            all other registers & flags unchanged
  689.  
  690. bpoint:    push    psw        ;save <a> & flags
  691.     push    d        ;save <de>
  692.     ani    07Fh        ;allow only up to 127
  693.     rlc            ;double buffer #
  694.     mov    e,a        ;and put doubled code in <de>
  695.     mvi    d,0    
  696.     dad    d        ;now point to address in table
  697.     mov    a,m        ;get low byte of address
  698.     inx    h        ;point to high byte
  699.     mov    h,m        ;high byte into h
  700.     mov    l,a        ;and low byte into l
  701.     pop    d        ;restore <de>
  702.     pop    psw        ;and <a> and flags
  703.     ret
  704.  
  705.  
  706. ;    *****************
  707. ;    *  data area     *
  708. ;    *****************
  709.  
  710.     dseg            ;data area
  711.  
  712. ;    *************************
  713. ;    * global variables    *
  714. ;    *************************
  715.  
  716. rxbact    db    0    ;number of active rx buffer
  717. rxbcbp    dw    0    ;pointer to active rx bcb
  718. txbcbp    dw    0    ;pointer to active tx bcb
  719.  
  720. rxbtab:            ;table of addresses for rx bcb's
  721.     dw    rxbcb0    
  722.     dw    rxbcb1
  723.     dw    rxbcb2
  724.     dw    rxbcb3
  725.     dw    rxbcb4
  726.     dw    rxbcb5
  727.     dw    rxbcb6
  728.     dw    rxbcb7
  729.     dw    rxbcb8
  730.     dw    rxbcb9
  731.     dw    rxbcba
  732.     dw    rxbcbb
  733.     dw    rxbcbc
  734.     dw    rxbcbd
  735.     dw    rxbcbe
  736.     dw    rxbcbf
  737.  
  738. txbtab:            ;table of addresses for tx bcb's
  739.     dw    txbcb0    
  740.     dw    txbcb1
  741.     dw    txbcb2
  742.     dw    txbcb3
  743.     dw    txbcb4
  744.     dw    txbcb5
  745.     dw    txbcb6
  746.     dw    txbcb7
  747.  
  748.  
  749. ;    *************************
  750. ;    * buffer control blocks    *
  751. ;    *************************
  752.  
  753. ; ---> rx buffer control blocks
  754.  
  755. rxbcb0:    dw    0        ;count
  756.     dw    fbsize        ;max value for count
  757.     dw    rxbuf0        ;write pointer
  758.     dw    rxbuf0+fbsize-1    ;max value for pointers
  759.     dw    rxbuf0        ;min value for pointers
  760.     dw    rxbuf0        ;read pointer
  761.     db    0        ;ready flag (not used)
  762.  
  763. rxbcb1:    dw    0        ;count
  764.     dw    fbsize        ;max value for count
  765.     dw    rxbuf1        ;write pointer
  766.     dw    rxbuf1+fbsize-1    ;max value for pointers
  767.     dw    rxbuf1        ;min value for pointers
  768.     dw    rxbuf1        ;read pointer
  769.     db    0        ;ready flag (not used)
  770.  
  771. rxbcb2:    dw    0        ;count
  772.     dw    fbsize        ;max value for count
  773.     dw    rxbuf2        ;write pointer
  774.     dw    rxbuf2+fbsize-1    ;max value for pointers
  775.     dw    rxbuf2        ;min value for pointers
  776.     dw    rxbuf2        ;read pointer
  777.     db    0        ;ready flag (not used)
  778.  
  779. rxbcb3:    dw    0        ;count
  780.     dw    fbsize        ;max value for count
  781.     dw    rxbuf3        ;write pointer
  782.     dw    rxbuf3+fbsize-1    ;max value for pointers
  783.     dw    rxbuf3        ;min value for pointers
  784.     dw    rxbuf3        ;read pointer
  785.     db    0        ;ready flag (not used)
  786.  
  787. rxbcb4:    dw    0        ;count
  788.     dw    fbsize        ;max value for count
  789.     dw    rxbuf4        ;write pointer
  790.     dw    rxbuf4+fbsize-1    ;max value for pointers
  791.     dw    rxbuf4        ;min value for pointers
  792.     dw    rxbuf4        ;read pointer
  793.     db    0        ;ready flag (not used)
  794.  
  795. rxbcb5:    dw    0        ;count
  796.     dw    fbsize        ;max value for count
  797.     dw    rxbuf5        ;write pointer
  798.     dw    rxbuf5+fbsize-1    ;max value for pointers
  799.     dw    rxbuf5        ;min value for pointers
  800.     dw    rxbuf5        ;read pointer
  801.     db    0        ;ready flag (not used)
  802.  
  803. rxbcb6:    dw    0        ;count
  804.     dw    fbsize        ;max value for count
  805.     dw    rxbuf6        ;write pointer
  806.     dw    rxbuf6+fbsize-1    ;max value for pointers
  807.     dw    rxbuf6        ;min value for pointers
  808.     dw    rxbuf6        ;read pointer
  809.     db    0        ;ready flag (not used)
  810.  
  811. rxbcb7:    dw    0        ;count
  812.     dw    fbsize        ;max value for count
  813.     dw    rxbuf7        ;write pointer
  814.     dw    rxbuf7+fbsize-1    ;max value for pointers
  815.     dw    rxbuf7        ;min value for pointers
  816.     dw    rxbuf7        ;read pointer
  817.     db    0        ;ready flag (not used)
  818.  
  819. rxbcb8:    dw    0        ;count
  820.     dw    fbsize        ;max value for count
  821.     dw    rxbuf8        ;write pointer
  822.     dw    rxbuf8+fbsize-1    ;max value for pointers
  823.     dw    rxbuf8        ;min value for pointers
  824.     dw    rxbuf8        ;read pointer
  825.     db    0        ;ready flag (not used)
  826.  
  827. rxbcb9:    dw    0        ;count
  828.     dw    fbsize        ;max value for count
  829.     dw    rxbuf9        ;write pointer
  830.     dw    rxbuf9+fbsize-1    ;max value for pointers
  831.     dw    rxbuf9        ;min value for pointers
  832.     dw    rxbuf9        ;read pointer
  833.     db    0        ;ready flag (not used)
  834.  
  835. rxbcba:    dw    0        ;count
  836.     dw    fbsize        ;max value for count
  837.     dw    rxbufa        ;write pointer
  838.     dw    rxbufa+fbsize-1    ;max value for pointers
  839.     dw    rxbufa        ;min value for pointers
  840.     dw    rxbufa        ;read pointer
  841.     db    0        ;ready flag (not used)
  842.  
  843. rxbcbb:    dw    0        ;count
  844.     dw    fbsize        ;max value for count
  845.     dw    rxbufb        ;write pointer
  846.     dw    rxbufb+fbsize-1    ;max value for pointers
  847.     dw    rxbufb        ;min value for pointers
  848.     dw    rxbufb        ;read pointer
  849.     db    0        ;ready flag (not used)
  850.  
  851. rxbcbc:    dw    0        ;count
  852.     dw    fbsize        ;max value for count
  853.     dw    rxbufc        ;write pointer
  854.     dw    rxbufc+fbsize-1    ;max value for pointers
  855.     dw    rxbufc        ;min value for pointers
  856.     dw    rxbufc        ;read pointer
  857.     db    0        ;ready flag (not used)
  858.  
  859. rxbcbd:    dw    0        ;count
  860.     dw    fbsize        ;max value for count
  861.     dw    rxbufd        ;write pointer
  862.     dw    rxbufd+fbsize-1    ;max value for pointers
  863.     dw    rxbufd        ;min value for pointers
  864.     dw    rxbufd        ;read pointer
  865.     db    0        ;ready flag (not used)
  866.  
  867. rxbcbe:    dw    0        ;count
  868.     dw    fbsize        ;max value for count
  869.     dw    rxbufe        ;write pointer
  870.     dw    rxbufe+fbsize-1    ;max value for pointers
  871.     dw    rxbufe        ;min value for pointers
  872.     dw    rxbufe        ;read pointer
  873.     db    0        ;ready flag (not used)
  874.  
  875. rxbcbf:    dw    0        ;count
  876.     dw    fbsize        ;max value for count
  877.     dw    rxbuff        ;write pointer
  878.     dw    rxbuff+fbsize-1    ;max value for pointers
  879.     dw    rxbuff        ;min value for pointers
  880.     dw    rxbuff        ;read pointer
  881.     db    0        ;ready flag (not used)
  882.  
  883.  
  884. ;*****************************************************
  885.  
  886. ; ---> tx buffer control blocks
  887.  
  888. txbcb0:    dw    0        ;count
  889.     dw    fbsize        ;max value for count
  890.     dw    txbuf0        ;write pointer
  891.     dw    txbuf0+fbsize-1    ;max value for pointers
  892.     dw    txbuf0        ;min value for pointers
  893.     dw    txbuf0        ;read pointer
  894.     db    0        ;ready flag (0=not ready)
  895.  
  896. txbcb1:    dw    0        ;count
  897.     dw    fbsize        ;max value for count
  898.     dw    txbuf1        ;write pointer
  899.     dw    txbuf1+fbsize-1    ;max value for pointers
  900.     dw    txbuf1        ;min value for pointers
  901.     dw    txbuf1        ;read pointer
  902.     db    0        ;ready flag (0=not ready)
  903.  
  904. txbcb2:    dw    0        ;count
  905.     dw    fbsize        ;max value for count
  906.     dw    txbuf2        ;write pointer
  907.     dw    txbuf2+fbsize-1    ;max value for pointers
  908.     dw    txbuf2        ;min value for pointers
  909.     dw    txbuf2        ;read pointer
  910.     db    0        ;ready flag (0=not ready)
  911.  
  912. txbcb3:    dw    0        ;count
  913.     dw    fbsize        ;max value for count
  914.     dw    txbuf3        ;write pointer
  915.     dw    txbuf3+fbsize-1    ;max value for pointers
  916.     dw    txbuf3        ;min value for pointers
  917.     dw    txbuf3        ;read pointer
  918.     db    0        ;ready flag (0=not ready)
  919.  
  920. txbcb4:    dw    0        ;count
  921.     dw    fbsize        ;max value for count
  922.     dw    txbuf4        ;write pointer
  923.     dw    txbuf4+fbsize-1    ;max value for pointers
  924.     dw    txbuf4        ;min value for pointers
  925.     dw    txbuf4        ;read pointer
  926.     db    0        ;ready flag (0=not ready)
  927.  
  928. txbcb5:    dw    0        ;count
  929.     dw    fbsize        ;max value for count
  930.     dw    txbuf5        ;write pointer
  931.     dw    txbuf5+fbsize-1    ;max value for pointers
  932.     dw    txbuf5        ;min value for pointers
  933.     dw    txbuf5        ;read pointer
  934.     db    0        ;ready flag (0=not ready)
  935.  
  936. txbcb6:    dw    0        ;count
  937.     dw    fbsize        ;max value for count
  938.     dw    txbuf6        ;write pointer
  939.     dw    txbuf6+fbsize-1    ;max value for pointers
  940.     dw    txbuf6        ;min value for pointers
  941.     dw    txbuf6        ;read pointer
  942.     db    0        ;ready flag (0=not ready)
  943.  
  944. txbcb7:    dw    0        ;count
  945.     dw    fbsize        ;max value for count
  946.     dw    txbuf7        ;write pointer
  947.     dw    txbuf7+fbsize-1    ;max value for pointers
  948.     dw    txbuf7        ;min value for pointers
  949.     dw    txbuf7        ;read pointer
  950.     db    0        ;ready flag (0=not ready)
  951.  
  952. txubcb:    dw    0        ;count
  953.     dw    fbsize        ;max value for count
  954.     dw    txbufu        ;write pointer
  955.     dw    txbufu+fbsize-1    ;max value for pointers
  956.     dw    txbufu        ;min value for pointers
  957.     dw    txbufu        ;read pointer
  958.     db    0        ;ready flag (0=not ready)
  959.  
  960. tempbcb    ds    13        ;save area for bcb
  961.  
  962. ;***********************************************************
  963.  
  964.  
  965. ; ---> buffer control block for list of free rx buffer #'s
  966.  
  967. rxfree:    dw    0        ;count
  968.     dw    numrxb        ;max value for count
  969.     dw    lrxfree        ;write pointer
  970.     dw    lrxfree+numrxb-1;max value for pointers
  971.     dw    lrxfree        ;min value for pointers
  972.     dw    lrxfree        ;read pointer
  973.     db    0        ;ready flag (not used)
  974.  
  975.  
  976. ; ---> buffer control block for list of rx frame buffer #'s
  977.  
  978. rxflst:    dw    0        ;count
  979.     dw    numrxb        ;max value for count
  980.     dw    lrxfrm        ;write pointer
  981.     dw    lrxfrm+numrxb-1    ;max value for pointers
  982.     dw    lrxfrm        ;min value for pointers
  983.     dw    lrxfrm        ;read pointer
  984.     db    0        ;ready flag (not used)
  985.  
  986.  
  987. ; ---> buffer control block for list of rx packet buffer #'s
  988.  
  989. rxplst:    dw    0        ;count
  990.     dw    numrxb        ;max value for count
  991.     dw    lrxpkt        ;write pointer
  992.     dw    lrxpkt+numrxb-1    ;max value for pointers
  993.     dw    lrxpkt        ;min value for pointers
  994.     dw    lrxpkt        ;read pointer
  995.     db    0        ;ready flag (not used)
  996.  
  997.  
  998. ;************************************************************
  999.  
  1000. ; ---> console input buffer control block
  1001.  
  1002. cibcb:    dw    0        ;count
  1003.     dw    cbsize        ;max value for count
  1004.     dw    cibuff        ;write pointer
  1005.     dw    cibuff+cbsize-1    ;max value for pointers
  1006.     dw    cibuff        ;min value for pointers
  1007.     dw    cibuff        ;read pointer
  1008.     db    0        ;ready flag (not used)
  1009.  
  1010. ; ---> console output buffer control block
  1011.  
  1012. cobcb:    dw    0        ;count
  1013.     dw    cbsize        ;max value for count
  1014.     dw    cobuff        ;write pointer
  1015.     dw    cobuff+cbsize-1    ;max value for pointers
  1016.     dw    cobuff        ;min value for pointers
  1017.     dw    cobuff        ;read pointer
  1018.     db    0        ;ready flag (not used)
  1019.  
  1020. ; ---> console transmit buffer control block
  1021.  
  1022. ctbcb:    dw    0        ;count
  1023.     dw    cbsize        ;max value for count
  1024.     dw    ctbuff        ;write pointer
  1025.     dw    ctbuff+cbsize-1    ;max value for pointers
  1026.     dw    ctbuff        ;min value for pointers
  1027.     dw    ctbuff        ;read pointer
  1028.     db    0        ;ready flag (not used)
  1029.  
  1030. ; ---> console receive buffer control block
  1031.  
  1032. crbcb:    dw    0        ;count
  1033.     dw    cbsize        ;max value for count
  1034.     dw    crbuff        ;write pointer
  1035.     dw    crbuff+cbsize-1    ;max value for pointers
  1036.     dw    crbuff        ;min value for pointers
  1037.     dw    crbuff        ;read pointer
  1038.     db    0        ;ready flag (not used)
  1039.  
  1040. ; ---> printer output buffer control block
  1041.  
  1042. pobcb:    dw    0        ;count
  1043.     dw    pbsize        ;max value for count
  1044.     dw    pobuff        ;write pointer
  1045.     dw    pobuff+pbsize-1    ;max value for pointers
  1046.     dw    pobuff        ;min value for pointers
  1047.     dw    pobuff        ;read pointer
  1048.     db    0        ;ready flag (not used)
  1049.  
  1050.  
  1051.  
  1052. ;    *****************
  1053. ;    *  buffers    *
  1054. ;    *****************
  1055.     
  1056.  
  1057. ;    queues of buffer #'s
  1058. lrxfree    ds    numrxb        ;free rx buffer #'s
  1059. lrxfrm    ds    numrxb        ;rx frame buffer #'s
  1060. lrxpkt    ds    numrxb        ;rx packet buffer #'s
  1061.     
  1062. ;    received frame buffers
  1063. rxbuf0:    ds    fbsize
  1064. rxbuf1:    ds    fbsize
  1065. rxbuf2:    ds    fbsize
  1066. rxbuf3:    ds    fbsize
  1067. rxbuf4:    ds    fbsize
  1068. rxbuf5:    ds    fbsize
  1069. rxbuf6:    ds    fbsize
  1070. rxbuf7:    ds    fbsize
  1071. rxbuf8:    ds    fbsize
  1072. rxbuf9:    ds    fbsize
  1073. rxbufa:    ds    fbsize
  1074. rxbufb:    ds    fbsize
  1075. rxbufc:    ds    fbsize
  1076. rxbufd:    ds    fbsize
  1077. rxbufe:    ds    fbsize
  1078. rxbuff:    ds    fbsize
  1079.  
  1080. ;    transmitted frame buffers
  1081. txbuf0:    ds    fbsize
  1082. txbuf1:    ds    fbsize
  1083. txbuf2:    ds    fbsize
  1084. txbuf3:    ds    fbsize
  1085. txbuf4:    ds    fbsize
  1086. txbuf5:    ds    fbsize
  1087. txbuf6:    ds    fbsize
  1088. txbuf7:    ds    fbsize
  1089. txbufu:    ds    fbsize
  1090.  
  1091. ;    I/O hardware queue buffers
  1092. cibuff:    ds    cbsize    ;console input buffer
  1093. cobuff:    ds    cbsize    ;console output buffer
  1094. ctbuff:    ds    cbsize    ;console transmit buffer
  1095. crbuff:    ds    cbsize    ;console receive buffer
  1096. pobuff:    ds    pbsize    ;printer buffer
  1097.  
  1098.  
  1099.  
  1100.  
  1101.  
  1102.  
  1103.  
  1104.  
  1105.