home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpmug / cpmug047.ark / CYBER.ASM < prev    next >
Encoding:
Assembly Source File  |  1984-04-29  |  17.9 KB  |  816 lines

  1. ;
  2. ; TITLE        CYBER communications uitilty
  3. ; FILENAME    CYBER.ASM
  4. ; AUTHOR    Robert A. Van Valzah   01/22/80
  5. ; LAST REVISOR    R.A.V.   01/30/80
  6. ; REASON    add sherwood light display of buffer status
  7. ;
  8. vdm    equ    0    ;buffer status to vdm upper right corner
  9. shrwood    equ    0ffffh    ;buffer status to sherwood digits
  10. ;
  11. ;
  12. ; This code performs on-line communications with a time sharing
  13. ; system using a modem.  Additionally, recieved characters may
  14. ; be printed.  Buffering is provided so that the printer may
  15. ; run slower than the modem without loosing characters.  It is
  16. ; assumed that the modem can keep up with input from the
  17. ; console.
  18. ;
  19. ;
  20. ; Several I/O devices are used in this program and they are
  21. ; refered to by three letter mnemonic names as follows:
  22. ; con    opperators console
  23. ; mod    modem
  24. ; prn    physical printer
  25. ; prq    logical printer (this is a queue)
  26. ; dsk    disk file
  27. ;
  28. ;
  29. ; data flow diagrams
  30. ;
  31. ; when conist=ready    conin -> modout
  32. ;
  33. ; when modist=ready    modin -> conout
  34. ;   if prnt=true    modin -> prqout
  35. ;
  36. ; when prqist=ready and prnost=ready
  37. ;            prqin -> prnout
  38. ;
  39. ; when modost=ready
  40. ;   if trns=true    dskin -> modout
  41. ;
  42. ;
  43. ;    cp/m interface equates
  44. ;
  45. ifcb    equ    5ch
  46. bdos    equ    5
  47. print    equ    9
  48. open    equ    15
  49. readrec    equ    20
  50. setdma    equ    26
  51. ;
  52. ;
  53.     org    100h
  54. entry:
  55.     jmp    main    ;jump around subroutines to main line
  56. ;
  57. ; print signon message
  58. ;
  59. signon:
  60.     call    sing1
  61.     db    'CYBER communications utility 01/25/80'
  62.     db    13,10,'$'
  63. sing1:
  64.     pop    d    ;get address of message
  65.     mvi    c,print
  66.     call    bdos
  67.     ret
  68. ;
  69. ; initialize the modem for communications
  70. ;
  71. modinit:
  72.     mvi    a,3    ;magic bytes for 300 baud
  73.     out    4
  74.     mvi    a,51h
  75.     out    4
  76.     ret
  77. ;
  78. ; get modem output status
  79. ; reg a=0h if not ready, 0ffh if ready
  80. ;
  81. modost:
  82.     in    4
  83.     ani    2
  84.     rz
  85.     mvi    a,0ffh
  86.     ret
  87. ;
  88. ; send character from reg c to modem
  89. ;
  90. modout:
  91.     call    modost
  92.     ora    a
  93.     jz    modout
  94.     mov    a,c
  95.     out    5
  96.     ret
  97. ;
  98. ; get modem input status 
  99. ; reg a = 0ffh if ready, 0h if not
  100. ;
  101. modist:
  102.     in    4
  103.     rar
  104.     sbb    a    ;hack
  105.     ret
  106. ;
  107. ; modem input charcter from line to reg a
  108. ;
  109. modin:
  110.     call    modist
  111.     ora    a
  112.     jz    modin
  113.     in    5
  114.     ani    7fh
  115.     ret
  116. ;
  117. ;    printer port i/o number equates
  118. ;
  119. base    equ    0f4h
  120. datal    equ    base
  121. datah    equ    base+1
  122. cmand    equ    base+2
  123. stats    equ    base
  124. ;
  125. ;    print formatting equates
  126. ;
  127. ncols    equ    120    ;max number of cols/line (must be <=126)
  128. ;
  129. ;    command bits
  130. ;
  131. restr    equ    1    ;restore carriage
  132. chstb    equ    2    ;character strobe
  133. xstb    equ    4    ;carriage strobe
  134. ystb    equ    8    ;paper feed strobe
  135. selpr    equ    10h    ;select printer
  136. selry    equ    20h    ;select ready
  137. rblft    equ    40h    ;ribbon lift
  138. ;
  139. ;    status bits
  140. ;
  141. chrdy    equ    8    ;character ready
  142. xrdy    equ    10h    ;carriage ready
  143. yrdy    equ    20h    ;paper feed ready
  144. ;
  145. ;
  146. ; print character in reg c
  147. ;
  148. prnout:
  149.     mov    a,c    ;get char to print to reg a
  150.     ani    7fh    ;strip parity
  151.     mov    c,a
  152.     lhld    nbufad    ;and pointer to next buffer address
  153.     cpi    13    ;test for special characters
  154.     rz        ;ignore carriage return
  155.     cpi    10
  156.     jz    plf    ;line feed
  157.     cpi    12
  158.     jz    pff    ;form feed
  159.     inr    m    ;assume a space
  160.     cpi    ' '
  161.     rz        ;was a space, all done
  162.     dcr    m    ;un-do assumption
  163.     rc        ;was some other control char, ignore
  164.     ;must be a printable character
  165.     mov    a,l    ;see if buffer is about overflow
  166.     cpi    low(buf+ncols-2)
  167.     rz
  168.     cpi    low(buf) ;see if this is first character
  169.     mov    a,m    ;get amt to move before printing
  170.     jz    gotamt    ;jump if first character
  171.     cpi    81h
  172.     jz    noblank    ;no blanks between last & this char
  173.     sui    80h    ;subtract flag value
  174. gotamt:    ;amount to move in reg a
  175.     inx    h    ;move over number of blanks
  176.     db    11h    ;lxi trick to skip following mvi a
  177. noblank:
  178.     mvi    a,1    ;like one blank between character
  179.     mov    m,c    ;store the character comming in
  180.     inx    h    ;point to next buffer location
  181.     mvi    m,81h    ;init to one blank to next char
  182.     shld    nbufad    ;update buffer pointer
  183.     lxi    h,reolpos ;update right end of line position
  184.     add    m
  185.     mov    m,a
  186.     ret
  187. ;
  188. ; print line feed
  189. ;
  190. plf:
  191.     mov    a,l    ;see if nbufad = buf
  192.     cpi    low(buf) ;if = then blank line
  193.     jz    prndone    ;=, so don't print anything
  194.     lda    leolpos    ;get left end of line position
  195.     mov    b,a    ;save it in reg b
  196.     lda    reolpos    ;get right end of line position
  197.     add    b    ;add leolpos to reolpos
  198.     rar        ;divide by two to find midpoint
  199.     mov    b,a    ;save line center point in reg b
  200.     lda    hpos    ;get current head position
  201.     sub    b    ;hpos-(leolpos+reolpos)/2
  202.     jc    forward    ;middle > hpos
  203. ;
  204. ; print the buffer backward
  205. ;
  206. backward:
  207.     mvi    a,80h    ;put end of buffer marker at left end
  208.     sta    buf
  209.     lda    reolpos    ;get absolute position of right eol
  210.     lxi    h,hpos    ;compute amount to move to get there
  211.     sub    m    ;reolpos-hpos
  212.     lhld    nbufad    ;get rightmost char to print
  213.     dcx    h
  214.     call    movprt    ;move and print rightmost
  215.     dcx    h    ;point to next char to print
  216.     shld    pbufad    ;store pointer to next amt or char
  217.     mvi    a,2    ;set backward printing flag
  218.     sta    dirf
  219.     ret
  220. ;
  221. ; print buffer forwards
  222. ;
  223. forward:
  224.     mvi    m,80h    ;put in eob mark (also ignores trailing blanks)
  225.     lxi    h,buf    ;pointer into buffer
  226.     mov    a,m    ;absolute pos of leftmost char to reg a
  227.     inx    h    ;point to first printable character
  228.     push    h    ;save buffer pointer
  229.     lxi    h,hpos    ;compute amount to move to get to leolpos
  230.     sub    m    ;leolpos-hpos
  231.     pop    h    ;restore buffer pointer
  232.     call    movprt    ;move to and print leftmost char
  233.     inx    h    ;point to next
  234.     shld    pbufad    ;store pointer to next amt or char
  235.     mvi    a,1    ;set printing forward flag
  236.     sta    dirf
  237.     ret
  238. ;
  239. ; print a form feed
  240. ;
  241. pff:
  242.     lda    lpp    ;get lines per page
  243.     lxi    h,lonp    ;subtract lines printed on this page
  244.     sub    m    ;leaving lines left on this page
  245.     sta    lfstodo    ;which is the number of lfs to do
  246.     ret
  247. ;
  248. ; service printer
  249. ;
  250. prnserv:
  251.     in    stats    ;is printer ready for another char?
  252.     ani    chrdy+xrdy+yrdy
  253.     rnz        ;no - can't service it now
  254.     lda    dirf    ;printing?
  255.     ora    a
  256.     rz        ;no - no servicing to do
  257.     cpi    1    ;set z if printing forward
  258.     lhld    pbufad    ;pointer to next amt to move
  259.     mov    a,m    ;amt to move to reg a
  260.     jz    fwd1
  261. bkwd1:
  262.     ;signed distance to move is now in reg a
  263.     sui    80h    ;test for eob mark
  264.     jz    prndone    ;found eob
  265.     dcx    h    ;assume this is a movement
  266.     cma        ;two's comp for leftward movement
  267.     inr    a
  268.     jnc    bkwd2    ;it was, reg a has amount to move
  269.     inx    h    ;it wasn't, fix buffer pointer
  270.     mvi    a,0ffh    ;move one space to the left
  271. bkwd2:
  272.     call    movprt    ;print the character
  273.     dcx    h    ;point to next movement or chr
  274.     shld    pbufad
  275.     ret
  276. fwd1:
  277.     sui    80h    ;test for end of line
  278.     jz    prndone    ;hit end of line
  279.     inx    h    ;point to character
  280.     jnc    fwd2    ;was a movement, reg a has distance
  281.     dcx    h    ;was a character, backup pointer
  282.     mvi    a,1    ;and set amount to move to 1
  283. fwd2:
  284.     call    movprt    ;print character
  285.     inx    h    ;point to next movement or chr
  286.     shld    pbufad
  287.     ret
  288. ;
  289. ; common finish up routine for printer service
  290. ;
  291. prndone:
  292.     lxi    h,lfstodo ;add one to line feeds to do before
  293.     inr    m    ;printing next line
  294.     xra    a    ;reset printer status to not printing
  295.     sta    dirf
  296.     jmp    init1    ;reset pointers
  297. ;
  298. ; move the number of character positions in reg a (taken as a
  299. ; signed number, + to the right, - to the left) and
  300. ; print the character pointed to by reg hl.
  301. ;
  302. movprt:
  303.     mov    c,m    ;get character to print
  304.     push    h    ;save while printing
  305.     mov    e,a    ;save amount to move in reg e
  306.     lxi    h,hpos    ;update the head position byte
  307.     mov    a,e
  308.     add    m    ;add amount we are moving
  309.     mov    m,a
  310.     mvi    b,xstb    ;ready x strobe for movstb
  311.     lda    chwid    ;load up character muliplicaton factor
  312.     call    movstb    ;send necessary x movement
  313.     lda    lpp    ;lines per page to reg b
  314.     mov    b,a
  315.     lxi    h,lfstodo ;number of pending line feeds
  316.     mov    a,m    ;skip movement if zero
  317.     ora    a
  318.     jz    noymov    ;no y movement
  319.     mov    e,a    ;movement to reg e for movstb
  320.     mvi    m,0    ;there will be none to do now
  321.     lxi    h,lonp    ;keep track of line on page
  322.     add    m
  323.     mov    m,a
  324.     sub    b    ;see if started new page
  325.     jc    samepage ;nope
  326.     mov    m,a    ;yes - take lonp mod lpp
  327. samepage:
  328.     lda    linhgt    ;load up line multiplicaton factor
  329.     mvi    b,ystb    ;ready y strobe for movstb
  330.     call    movstb    ;send necessary y movement
  331. noymov:
  332.     mov    e,c    ;send character
  333.     mvi    b,chstb    ;send character strobe
  334.     mvi    a,1    ;dummy multiplication factor
  335.     call    movstb
  336.     pop    h
  337.     ret
  338. ;
  339. ; move the signed amount in reg e using value in reg a as
  340. ; a mulitplication factor to get the number of increments
  341. ; then send strobe in reg b.
  342. ;
  343. movstb:
  344.     push    psw    ;save multiplication factor
  345.     mov    a,e    ;form a 16 bit amount to move in reg de
  346.     ral        ;sign of movement into carry
  347.     sbb    a    ;generate sign extention
  348.     mov    d,a    ;16-bit signed movement now in reg de
  349.     pop    psw    ;get multiplication factor
  350.     lxi    h,0    ;initialize product
  351. mulbyw:            ;multiply
  352.     dad    d
  353.     dcr    a
  354.     jnz    mulbyw    ;keep multiplying
  355.     mov    a,h    ;is this leftward movement?
  356.     ora    a
  357.     jp    posmov    ;no - distance is ok
  358.     xra    a    ;yes - negate distance
  359.     sub    l    ;reg a = 0 - low order
  360.     mov    l,a    ;which is low order compliment
  361.     sbb    h    ;now subtract out high order and
  362.     sub    l    ;subtract out excess low order
  363.     ;complimented distance now in reg a and reg l
  364.     ori    4    ;and set negative motion bit
  365. posmov:
  366.     cma        ;high order data is active low
  367.     out    datah    ;send high order data
  368.     mov    a,l    ;get low order data
  369.     cma        ;it too is active low
  370.     out    datal    ;send low  order data
  371.             ;fall thru to strobe
  372. ;
  373. ; pulse strobe in reg b
  374. ;
  375. strobe:
  376.     xra    a    ;delay a while for data set-up time
  377. dlay:
  378.     dcr    a
  379.     jnz    dlay
  380.     mvi    a,0ffh-selpr-rblft-selry
  381.     push    psw    ;save bits which are allways high
  382.     sub    b    ;lower appropriate strobe bit
  383.     out    cmand    ;send strobe bit low
  384.     pop    psw    ;and send it high
  385.     out    cmand
  386.     ret
  387. ;
  388. ; printer output status
  389. ; return reg a = 0h if not ready, 0ffh if ready
  390. ;
  391. prnost:
  392.     lda    dirf    ;printing from buffer now?
  393.     ora    a
  394.     mvi    a,0ffh    ;prepare no
  395.     rz        ;no - therefore ready for more
  396.     cma        ;yes
  397.     ret
  398. ;
  399. ; init for printing
  400. ;
  401. prninit:
  402.     mvi    b,restr    ;pulse restore line to
  403.     call    strobe    ;reset printer
  404.     xra    a    ;set software head position to zero
  405.     sta    hpos
  406.     sta    lonp    ;reset line counter to top of page
  407.     sta    lfstodo    ;zero out number of line feeds to do
  408. init1:    ;empty buffer entry point
  409.     xra    a    ;reset right end of line position
  410.     sta    reolpos
  411.     lxi    h,buf    ;next buffer address pointer
  412.     shld    nbufad
  413.     mov    m,a    ;inits left end of line position
  414.     ret
  415. ;
  416. ;
  417. ; initialize jump vectors to CBIOS
  418. ;
  419. initjmp:
  420.     lhld    1
  421.     lxi    d,3    ;length of jmp inst
  422.     dad    d
  423.     shld    const+1
  424.     dad    d
  425.     shld    conin+1
  426.     dad    d
  427.     shld    conout+1
  428.     ret
  429. ;
  430. ; initialize ram
  431. ;
  432. initram:
  433.     xra    a
  434.     sta    exitflg    ;reset exit flag
  435.     sta    prntflg    ;reset echo to printer flag
  436.     sta    trnsflg    ;reset transmit disk file flag
  437.     sta    dirf    ;set printer status to idle
  438.     ret
  439.     if    shrwood
  440. ;
  441. ; divide reg hl by negaive amount in reg bc,
  442. ; remainder (8-bits) in reg a, qoutient in reg hl
  443. ;
  444. div:
  445.     mvi    a,-1    ;init remainder
  446. submor:
  447.     dad    b
  448.     inr    a    ;inc remainder
  449.     jc    submor    ;still positive
  450.     push    psw    ;save remainder
  451.     mov a,b!cma!mov b,a!mov a,c!cma!mov c,a!inx b ;two's comp
  452.     dad    b
  453.     pop    psw
  454.     ret
  455. ;
  456. ; contents of register hl to sherwood digits
  457. ;
  458. litout:
  459.     lxi    b,-100    ;set for hundreds digit
  460.     call    div    ;get most sig digit to reg a
  461.     rlc ! rlc    ;rotate into position
  462.     mov    e,a    ;save it in reg e
  463.     lxi    b,-10    ;set for tens digit
  464.     call    div    ;next sig digit to reg a
  465.     push    psw    ;save it
  466.     rar ! rar ! ani 3 ;get 2 ms bits
  467.     ora    e    ;or in ms digit
  468.     out    0c5h
  469.     pop    psw    ;get middle digit again
  470.     ani 3 ! rlc ! rlc ! rlc ! rlc
  471.     mov    e,a    ;save 2 ls bits of middle
  472.     lxi    b,-1    ;set for units digit
  473.     call    div    ;get ls digit
  474.     ora    e    ;or in middle digit
  475.     out    0c7h
  476.     ret
  477. ;
  478. ; initialize digits on sherwood front pannel
  479. ;
  480. initlit:
  481.     xra    a    ;set both pia's to control mode
  482.     out    0c4h
  483.     out    0c6h
  484.     cma        ;set all bits to output mode
  485.     out    0c5h
  486.     out    0c7h
  487.     mvi    a,4    ;set both pia's back to data mode
  488.     out    0c4h
  489.     out    0c6h
  490.     ret
  491.     endif        ;end of if shrwood
  492. ;
  493. ; compare register hl to de
  494. ;
  495. cmpr:
  496.     mov    a,h
  497.     cmp    d
  498.     rnz
  499.     mov    a,l
  500.     cmp    e
  501.     ret
  502. ;
  503. ; initialize printer queue
  504. ;
  505. prqinit:
  506.     lxi    h,qlow
  507.     shld    qiptr
  508.     shld    qoptr
  509.     ret
  510. ;
  511. ; get printer queue input status
  512. ; return reg a = 0ffh if ready, 0h if not
  513. ;
  514. prqist:
  515.     lhld    qoptr    ;is next full byte
  516.     xchg
  517.     lhld    qiptr    ;equal to next empty byte?
  518.     call    cmpr
  519.     mvi    a,0
  520.     rz        ;yes - queue is empty
  521.     cma
  522.     ret
  523. ;
  524. ; test for queue pointer in reg hl wrapping memory and
  525. ; reset if so
  526. ;
  527. wrapq:
  528.     xchg        ;save new ptr
  529.     lhld    qhigh    ;upper limit
  530.     xchg
  531.     call    cmpr
  532.     rnz        ;new ptr is ok
  533.     lxi    h,qlow    ;have to wrap back to start
  534.     ret
  535. ;
  536. ; show queue fullness status
  537. ;
  538. showqst:
  539.     lhld    qoptr
  540.     xchg
  541.     lhld    qiptr
  542.     call    cmpr
  543.     jnc    noswap    ;qiptr>qoptr
  544.     xchg
  545. noswap:
  546.     ;16-bit subtract hl=hl-de
  547.     mov a,l!sub e!mov l,a!mov a,h!sbb d!mov h,a
  548.     ;number of character in buffer now in reg hl
  549.     if    shrwood
  550.       call    litout    ;send to lights
  551.     endif
  552.     if    vdm
  553.       mov    a,l
  554.       sta    0cc3fh    ;upper right hand corner of screen
  555.     endif
  556.     ret
  557. ;
  558. ; get a character from printer queue to reg a
  559. ; assumes that the queue is not empty
  560. ;
  561. prqin:
  562.     lhld    qoptr    ;pointer to next full byte
  563.     mov    a,m    ;get a character
  564.     push    psw    ;and save it
  565.     inx    h    ;point to next full byte
  566.     call    wrapq    ;reset pointer when memory wraps
  567.     shld    qoptr    ;store new pointer
  568.     call    showqst    ;show queue fullness status
  569.     pop    psw    ;restore charcter from queue
  570.     ret
  571. ;
  572. ; send character from reg c to printer queue 
  573. ;
  574. prqout:
  575.     lhld    qiptr    ;is queue empty?
  576.     ;******overflow test goes here
  577.     mov    m,c    ;put it in place
  578.     inx    h    ;point to next byte to fill
  579.     call    wrapq    ;fix pointer if wrapping memory
  580.     shld    qiptr
  581.     call    showqst    ;display queue fullness
  582.     ret
  583. ;
  584. ; dskinit sets diflg to 0ffh (true) if input filename is
  585. ; prestent and open is successfull
  586. ;
  587. dskinit:
  588.     lda    5dh    ;first name byte of fcb1
  589.     mvi    b,0    ;prepare diflg value
  590.     cpi    ' '    ;blank means no name present
  591.     jz    set1
  592.     cpi    '?'    ;? means not present too
  593.     jz    set1
  594.     dcr    b    ;reg b = 0ffh
  595. set1:
  596.     mov    a,b    ;get diflg value
  597.     sta    diflg    ;store it
  598.     ora    a    ;was a name provided?
  599.     rz        ;no - skip open stuff
  600.     xra    a    ;zap fcbnr
  601.     sta    ifcb+32
  602.     lxi    d,ifcb
  603.     mvi    c,open
  604.     call    bdos
  605.     inr    a
  606.     jz    dskerr    ;not found
  607.     lxi    h,ibuf+80h ;init input buffer pointer
  608.     shld    iptr
  609.     ret
  610. dskerr:
  611.     lxi    d,errmsg
  612.     mvi    c,print
  613.     call    bdos
  614.     jmp    0
  615. errmsg    db    'file not found',13,10,'$'
  616. ;
  617. ; get disk input status
  618. ; return reg a = 0ffh if ready, 0h if not
  619. ;
  620. dskist:
  621.     lda    diflg    ;was a filename present?
  622.     ret
  623. ;
  624. ; get a character from the disk input file
  625. ; return char in reg a
  626. ;
  627. dskin:
  628.     lhld    iptr
  629.     mov    a,l
  630.     cpi    low(ibuf+80h)
  631.     jnz    noread    ;dont have to read record
  632.     lxi    d,ibuf
  633.     mvi    c,setdma
  634.     call    bdos
  635.     mvi    c,readrec
  636.     lxi    d,ifcb
  637.     call    bdos
  638.     ora    a
  639.     jz    readok    ;got good data
  640.     cpi    1    ;read past eof?
  641.     jnz    dskerr    ;no - all that leaves is error
  642.     lxi    h,ibuf    ;yes - fake eof with control z
  643.     mvi    m,26
  644. readok:
  645.     lxi    d,80h    ;restore dma address
  646.     mvi    c,setdma
  647.     call    bdos
  648.     lxi    h,ibuf
  649. noread:
  650.     mov    a,m    ;get character
  651.     inx    h
  652.     shld    iptr    ;update pointer
  653.     cpi    26    ;was eof just read?
  654.     rnz        ;no - just return with char
  655.     xra    a    ;yes - reset di flag
  656.     sta    diflg
  657.     sta    trnsflg    ;and transmit file flag
  658.     lxi    d,eofmsg ;send eof message
  659.     mvi    c,9
  660.     call    bdos
  661.     mvi    a,26    ;restore eof char
  662.     ret
  663. ;
  664. eofmsg    db    13, 10, 'Transmission complete.', 13, 10, '$'
  665. ;
  666. ; service disk input
  667. ;
  668. dskserv:
  669.     lda    trnsflg    ;are we transmitting a file?
  670.     ora    a
  671.     rz        ;no - no servicing to do
  672.     call    dskist    ;is disk input ready?
  673.     ora    a
  674.     rz        ;return if not
  675.     call    modost    ;is modem ready for another?
  676.     ora    a
  677.     rz        ;return if not
  678.     call    dskin    ;is ready - go get character
  679.     mov    c,a    ;pass to modout
  680.     call    modout
  681.     ret
  682. ;
  683. ; service printer queue
  684. ;
  685. prqserv:
  686.     call    prqist    ;does queue have any characters?
  687.     ora    a
  688.     rz        ;no - can't service it
  689.     call    prnost    ;yes - is printer ready for more?
  690.     ora    a
  691.     rz        ;no - leave chars in queue
  692.     call    prqin    ;yes - get character from queue
  693.     mov    c,a    ;and send it to priner
  694.     call    prnout
  695.     ret
  696. ;
  697. ; decode control characters entered from console
  698. ; return z flag set if control char was found
  699. ;
  700. decode:
  701.     cpi 5 !    lxi h,exitflg !    jz compflg
  702.     cpi 16!    lxi h,prntflg ! jz compflg
  703.     cpi 20! lxi h,trnsflg ! jz compflg
  704.     ret        ;none of the above
  705. compflg:
  706.     mov    a,m    ;get present flag value
  707.     cma        ;compliment
  708.     mov    m,a    ;and put back complimented
  709.     xra    a    ;set z flag
  710.     ret
  711. ;
  712. ; service console
  713. ;
  714. conserv:
  715.     call    const    ;any character waiting?
  716.     ora    a
  717.     rz        ;no - no serving to do
  718.     call    conin    ;yes - go get it
  719.     mov    c,a    ;save charater for echo
  720.     call    decode    ;set flags from control chars
  721.     rz        ;don't send if local control char
  722.     call    modout    ;send char to CYBER
  723.     ret
  724. ;
  725. ; service modem
  726. ;
  727. modserv:
  728.     call    modist    ;any character waiting?
  729.     ora    a
  730.     rz        ;no - no serving to do
  731.     call    modin    ;yes - go get it and . . .
  732.     mov    c,a    ;send it to the console
  733.     push    b    ;save it for the printer
  734.     call    conout
  735.     pop    b    ;get character back
  736.     lda    prntflg    ;are we echoing to printer?
  737.     ora    a
  738.     rz        ;no - all done here
  739.     call    prqout    ;yes - send to the printer queue
  740.     ret
  741. ;
  742. ; main line code
  743. ;
  744. main:    
  745.     lxi    sp,stack
  746.     call    signon    ;print signon message
  747.     call    initram    ;initialize ram
  748.     call    initjmp    ;initialize jump vectors to CBIOS
  749.     if shrwood!call initlit!endif
  750.     call    modinit    ;initialize modem
  751.     call    prqinit    ;initialize printer queue to empty
  752.     call    prninit    ;initialize printer
  753.     call    dskinit    ;initialize disk
  754. work:
  755.     call    conserv    ;service console
  756.     call    modserv    ;service modem
  757.     call    prnserv    ;service printer
  758.     call    prqserv    ;service printer queue
  759.     call    dskserv    ;service disk
  760.     lda    exitflg    ;until exit is true
  761.     ora    a
  762.     jz    work    ;keep working
  763.     jmp    0    ;reboot CP/M
  764. ;
  765. ; initialized ram areas
  766. ;
  767. ;    CBIOS jmp vectors
  768. ;
  769. const    jmp    $-$    ;will be filled in by initjmp
  770. conin    jmp    $-$
  771. conout    jmp    $-$
  772. ;
  773. ;    ram parameter area
  774. ;
  775. linhgt    db    8    ;line height in increments
  776. chwid    db    6    ;character width in increments
  777. lpp    db    66    ;lines per page
  778. ;
  779. qhigh    dw    1000h    ;pointer to start of printer queue
  780. ;
  781. ; uninitialized ram areas
  782. ;
  783. lonp    ds    1    ;current line on page, 0 = first line
  784. lfstodo    ds    1    ;line feeds to do before printing
  785. hpos    ds    1
  786. reolpos    ds    1
  787. nbufad    ds    2
  788. buf:
  789. leolpos:        ;address of byte containing left eol
  790.     ds    1
  791. lmostch:        ;address of left most character
  792.     ds    ncols
  793. ;
  794. exitflg    ds    1    ;nonzero when time to return to CP/M
  795. prntflg    ds    1    ;nonzero when echoing to printer
  796. trnsflg    ds    1    ;nonzero when transmitting a disk file
  797. ;
  798. dirf    ds    1    ;0=idle, 1=printing forward, 2=backward
  799. ;
  800. diflg    ds    1    ;nonzero if disk input file present
  801. ;
  802. iptr    ds    2    ;pointer to next char to read from ibuf
  803. ibuf    ds    128    ;disk input buffer
  804. ;
  805. pbufad    ds    2    ;next address to print from buffer
  806. ;
  807. qiptr    ds    2    ;pointer to next empty byte in queue
  808. qoptr    ds    2    ;pointer to oldest full byte in queue
  809. ;
  810.     ds    30    ;stack space
  811. stack:
  812. ;
  813. qlow:        ;start of printer queue
  814. ;
  815.     end    entry
  816.