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 / QTERM / QT43SRC.LBR / TERMIO.ZY / TERMIO.ZY
Text File  |  2000-06-30  |  10KB  |  512 lines

  1. ; termio.z - subroutines for doing the terminal i/o part of qterm
  2.  
  3. .incl    "c:termcap"
  4. .incl    "c:vars"
  5.  
  6. .macro    table    byte,addr
  7.     dw    addr
  8.     db    byte
  9. .endm
  10.  
  11. .extern    procch
  12. procch:    call    kbdcc        ; get a char if it's waiting
  13.     or    a
  14.     jr    z,lstmod    ; skip if no character
  15.     cp    'x' & 0x1f    ; ctl x?
  16.     jp    z,canscr    ; quit if so
  17.     ld    e,a        ; save char in e
  18.     ld    a,(escval)    ; get the escape value
  19.     ld    hl,pccs
  20.     inc    (hl)
  21.     dec    (hl)        ; what state?
  22.     jr    z,pccs0        ; state zero - look for escape
  23.     dec    (hl)        ; reset to 0
  24.     cp    e        ; escape twice?
  25.     jr    z,pccop        ; yes - send one to modem
  26.     ld    a,e        ; get char back
  27.     cp    ','        ; was it a ','?
  28.     call    z,hangup    ; hang up if so
  29.     cp    '.'        ; or a '.'
  30.     call    z,break        ; do a break
  31.     jr    lstmod
  32.  
  33. ; This is here for branch length reasons
  34.  
  35. .extern    modop
  36. modop:                ; send a character to the modem, respecting
  37.                 ; half duplex etc.
  38.     push    af
  39.     call    modopc        ; send it to the modem first
  40.     pop    hl
  41.     ld    a,(wflg)    ; window mode?
  42.     or    a
  43.     ld    a,h        ; get character back
  44.     jr    z,nowin
  45.     push    hl
  46.     call    winsnd        ; go give it to window input code
  47.     pop    af        ; char back
  48.     cp    '\r'
  49.     ret    nz        ; returns get special processing
  50.     ld    a,(eflg)    ; echo mode?
  51.     or    a
  52.     ret    z        ; return if not
  53.     ld    a,'\n'        ; throw a linefeed into the system
  54.     jr    modop
  55. nowin:    ld    a,(hflg)    ; half duplex?
  56.     or    a
  57.     ret    z
  58.     ld    a,h        ; get character again
  59.     cp    '\r'
  60.     jr    nz,ipchar    ; pass non-return chars straight in
  61.     ld    a,(eflg)    ; echo mode too?
  62.     or    a
  63.     ld    a,h        ; get the '\r' back
  64.     jr    z,ipchar    ; no echo mode, don't expand it
  65.     call    ipchar        ; go send return to receive code
  66.     ld    a,'\n'
  67.     jr    ipmchr        ; throw a newline into system as well
  68.  
  69. pccs0:    cp    e        ; did we see an escape?
  70.     jr    z,setesc    ; yes, set the flag
  71.     ld    a,e
  72. pccop:    call    modop        ; send char to modem
  73.     db    0x3e        ; ld a,xx opcode
  74. setesc:    inc    (hl)
  75.  
  76. .extern    lstmod
  77. lstmod:
  78.     call    wrtscn        ; keep the printer going and check if a
  79.                 ; character is waiting at the modem port.
  80.     ret    c        ; return if nothing arrived
  81.  
  82.     ld    hl,ecval    ; echo check needed?
  83.     dec    (hl)
  84.     inc    (hl)
  85.     jr    z,noec        ; jump if not
  86.     cp    (hl)        ; did we match?
  87.     jr    nz,noec        ; no - leave value in place
  88.     ld    (hl),1        ; reset to say we got it
  89. noec:    ld    hl,bmask
  90.     and    (hl)        ; mask if 7 bit mode
  91.     scf
  92.     ret    z        ; return on nulls as well
  93.     ld    hl,cscqfl
  94.     inc    (hl)
  95.     dec    (hl)        ; ^S ^Q spotting enabled?
  96.     jr    z,nocscq
  97.     bit    0,(hl)
  98.     jr    nz,nocs        ; waiting for a ^Q?
  99.     cp    's' & 0x1f    ; ^S ?
  100.     jr    nz,nocscq    ; nope, check status now
  101.     set    0,(hl)        ; flag that a ^S arrived
  102.     scf
  103.     ret
  104. nocs:    cp    'q' & 0x1f    ; was it a ^Q
  105.     jr    z,wascq
  106.     cp    's' & 0x1f    ; also let a second ^S toggle
  107.     jr    nz,nocscq    ; not yet - pass this character
  108. wascq:    res    0,(hl)        ; clear the flag
  109.     scf
  110.     ret
  111. nocscq:    ld    hl,eflg
  112.     inc    (hl)
  113.     dec    (hl)        ; echo mode?
  114. zipch:    jr    z,ipchar    ; no, hand straight to input code
  115.     cp    '\r'        ; return?
  116.     jr    nz,ipmchr    ; no, echo and hand to input code
  117.     call    ipmchr        ; otherwise process,
  118.     ld    a,'\n'        ; and send a newline into the system as well
  119.  
  120. ipmchr:    push    af
  121.     call    modopc        ; send character to modem to echo it
  122.     pop    af
  123.  
  124. .extern    ipchar            ; needed for sendcs in chat
  125. ipchar:    ld    c,a        ; save char in c
  126.     ld    a,(jflg)
  127.     or    a        ; junking control characters?
  128.     ld    a,c
  129.     call    nz,limitb    ; if so it gets tested
  130.     ret    c        ; and thrown if bad
  131.     push    af        ; save the character
  132.     call    opchar
  133.     pop    af
  134.     call    oplst        ; output to printer
  135.     or    a        ; clear the carry
  136.     ld    hl,cflg
  137.     bit    0,(hl)        ; catch mode enabled
  138.     ret    z        ; no - return
  139.     ld    hl,(cptr)
  140.     ld    (hl),a        ; save char away
  141.     inc    hl
  142.     ld    (cptr),hl    ; update pointer
  143.     ld    de,(endcbf)
  144.     or    a
  145.     sbc    hl,de        ; buffer full?
  146.     scf
  147.     ccf            ; clear carry w/o affecting zero
  148.     ret    nz        ; no - keep going
  149.     push    af
  150.     call    flushc        ; go flush data in catch buffer
  151.     call    ctlq
  152.     pop    af
  153.     ret
  154.  
  155. .extern    savrng
  156. savrng:                ; get a char and save in ring buffer
  157.     call    modist        ; char available?
  158.     ret    z        ; no.
  159.     call    modin        ; get it
  160.     ld    de,(ringpw)    ; pick up indices
  161.     ld    hl,(ringpr)
  162.     inc    de        ; move write index
  163.     res    2,d
  164.     or    a
  165.     sbc    hl,de        ; buffer full?
  166.     ret    z        ; return if so
  167.     ld    (ringpw),de    ; save revised index
  168.     ld    hl,ring
  169.     add    hl,de
  170.     ld    (hl),a
  171.     ret
  172.  
  173. wrtscn:    call    wrtlst        ; keep printer output rolling
  174.     call    savrng        ; get any incoming characters
  175.     ld    de,(ringpr)
  176.     ld    hl,(ringpw)
  177.     xor    a
  178.     sbc    hl,de        ; anything in the ring?
  179.     scf
  180.     ret    z        ; nope
  181.     inc    de
  182.     res    2,d
  183.     ld    (ringpr),de    ; save new index
  184.     ld    hl,ring
  185.     add    hl,de        ; index into buffer
  186.     ld    a,(hl)        ; get the char
  187.     ret            ; and return it
  188.  
  189. .extern    oplst            ; put a character in the list ring buffer
  190. oplst:
  191.     ld    hl,oflg        ; are we saving?
  192.     bit    0,(hl)
  193.     ret    z        ; return if not
  194.     push    bc        ; save bc
  195.     ld    hl,(lstpr)
  196.     ld    de,(lstpw)    ; get the list ring buffer indices
  197.     inc    de        ; move the write pointer
  198.     res    2,d        ; wrap if it hits 1K
  199.     or    a
  200.     sbc    hl,de        ; check for buffer full
  201.     jr    nz,notful
  202.     push    af        ; save the character
  203.     call    ctls        ; send an xoff and wait for things to cool
  204. mtloop:    call    wrtlst        ; write a character if we can
  205.     jr    nc,mtloop    ; keep writing if we're not done
  206.     call    ctlq        ; OK - you can wake up again
  207.     pop    af        ; restore char again
  208. notful:    ld    hl,(lstpw)
  209.     inc    hl
  210.     res    2,h
  211.     ld    (lstpw),hl    ; save the revised write pointer
  212.     ld    de,lstbuf    ; address the list buffer
  213.     add    hl,de
  214.     ld    (hl),a        ; and save the character
  215.     pop    bc        ; get bc back.
  216.     ret
  217.  
  218. wrtlst:    ld    de,(lstpr)    ; see if we can send a character to the lst
  219.     ld    hl,(lstpw)    ; get the ring buffer indices
  220.     or    a
  221.     sbc    hl,de        ; anything in the buffer
  222.     scf            ; set carry to say we're done
  223.     ret    z        ; nope - nothing to do
  224.     push    de
  225.     ld    a,0x2d
  226.     call    cbios        ; call to list status
  227.     pop    de        ; get read pointer back
  228.     or    a
  229.     ret    z        ; can't write - return now
  230.     ld    hl,lstbuf
  231.     add    hl,de        ; index into buffer
  232.     inc    de
  233.     res    2,d        ; wrap if over 1K
  234.     ld    (lstpr),de    ; save new index
  235.     ld    c,(hl)
  236.  
  237. .extern    lstout
  238. lstout:    ld    a,0x0f
  239.     call    cbios
  240.     or    a        ; clear the carry
  241.     ret
  242.  
  243. .extern    ctlq
  244. ctlq:
  245.     ld    a,(lxoff)    ; get local xon / xoff status
  246.     or    a
  247.     ret    z        ; send nothing if xoff sent from keyboard
  248.     ld    a,(cqchr)
  249.  
  250. .extern    modopc
  251. modopc:    push    af        ; save character on stack
  252. modopl:    call    modost        ; check if we can send
  253.     jr    z,modopl    ; can't send - loop back
  254.     pop    af        ; char back to a
  255.     jp    modout        ; and away it goes
  256.  
  257. .extern    limitb
  258. limitb:                ; like limitc, but includes backspace
  259.     cp    '\b'
  260.     ret    z
  261.  
  262. .extern    limitc
  263. limitc:
  264.     cp    0x7f        ; del or greater
  265.     ccf
  266.     ret    c        ; are invalid
  267.  
  268. .extern    iswa
  269. iswa:
  270.     cp    ' '        ; space to '~'
  271.     ret    nc        ; are valid
  272.     cp    '\r'
  273.     ret    z        ; return is valid
  274.     cp    '\n'
  275.     ret    z        ; newline also
  276.     cp    '\t'
  277.     ret    z        ; and tab
  278.     scf            ; rest are bad
  279.     ret
  280.  
  281. .var    #where    0
  282. .var    #bot    1
  283. .var    #top    2
  284. .var    #col    6
  285. .var    #row    7
  286. .var    #lff    8
  287.  
  288. nocndo:    call    ilprt        ; and finish the message
  289.     db    '\r\nW ignored - insufficient terminal capabilities\r\n\0'
  290.     ret
  291.  
  292. wend:    ld    hl,23 << 8
  293.     jp    moveto
  294.  
  295. .extern    witog
  296. witog:    ld    a,(tcbits)    ; check what terminal abilities we have
  297.     cpl
  298.     and    b_delln    | b_insln
  299.     ld    (wtflag),a    ; save window type value
  300.     jr    z,cando        ; got insert and delete - away we go
  301.     ld    a,(tcbits)
  302.     and    b_cleol        ; alternatively check for clear to end-of-line
  303.     jr    z,nocndo    ; missing it as well - can't do this
  304.  
  305. cando:    ld    hl,wflg
  306.     call    togflg        ; toggle the flag first of all
  307.     jr    z,wend        ; disabled - so return & do nothing
  308.     dec    (hl)        ; temporarily turn mode back off so prompt
  309.     push    hl        ; works right
  310.     call    prompt
  311.     db    'Window size (b / s)? \0'
  312.     pop    hl
  313.     inc    (hl)        ; turn flag back on
  314.     ld    hl,ipbuf
  315.     call    byp
  316.     or    0x20
  317.     xor    's'        ; did they say 's'?
  318.  
  319. ; we could probably optimise this even more, only two numbers actually change
  320.  
  321.     ld    hl,sdat        ; get small window data
  322.     jr    z,gotdat    ; jump if so
  323.     ld    hl,bdat        ; otherwise large window data
  324. gotdat:    ld    de,wrdat
  325.     ld    bc,6
  326.     ldir            ; go install it
  327.     ld    h,d
  328.     ld    l,e
  329.     inc    de
  330.     ld    c,5
  331.     ld    (hl),b        ; clear the rest of the information
  332.     ldir
  333.     ld    a,(wtflag)
  334.     or    a        ; what sort of windowing
  335.     jr    nz,setrol    ; rolling w/ clear to eol
  336.     ld    hl,(rbot)    ; normal - get bottom row
  337.     ld    a,(sbot)    ; and the other
  338.     jr    wsetsc        ; and install them
  339. setrol:    ld    hl,(rtop)    ; get top row
  340.     ld    a,(stop)    ; and the other
  341. wsetsc:    ld    (srow),a    ; save send window current row
  342.     ld    a,l
  343.     ld    (rrow),a    ; and receive window
  344.     ld    (where),a    ; and set where so we'll do a moveto
  345.     call    clear
  346.     ld    hl,(rtop - 1)    ; get top of receive window
  347.     dec    h        ; - 1 to move up a line
  348.     ld    l,0        ; and the first positon
  349.     call    moveto        ; go there
  350.     call    dim        ; dim mode
  351.     ld    bc,[80 << 8] + '-'
  352. dashes:    push    bc
  353.     call    scrout        ; spit out 80 dashes
  354.     pop    bc
  355.     djnz    dashes
  356.     jp    bright        ; set bright mode and we're done
  357.  
  358. istab:    ld    c,' '
  359.     call    opwc
  360.     ld    a,(iy + #col)
  361.     and    7
  362.     jr    nz,istab
  363.     ret
  364.  
  365. trybs:    cp    '\b'
  366.     jr    nz,trytab
  367.     ld    a,(iy + #col)
  368.     or    a
  369.     ret    z
  370.     dec    (iy + #col)
  371.     call    opbs
  372.     ld    c,' '
  373.     call    scrout
  374. opbs:    ld    c,'\b'
  375.     jp    scrout
  376.  
  377. trytab:    cp    '\t'
  378.     jr    z,istab
  379.  
  380. nobs:    cp    '~' + 1
  381.     ret    nc
  382.     cp    ' '
  383.     ret    c
  384. opwc:    push    hl
  385.     call    scrout
  386.     pop    hl
  387.     ld    (iy + #lff),0
  388.     inc    (iy + #col)
  389.     ld    a,(iy + #col)
  390.     xor    80
  391.     jr    z,scrl
  392.     ret
  393.  
  394. .extern    winrec
  395. winrec:    ld    iy,wrdat
  396.     jr    winpc
  397.  
  398. winsnd:    ld    iy,wsdat
  399.     ld    c,a
  400.  
  401. winpc:    ld    hl,where
  402.     ld    a,(iy + #where)
  403.     cp    (hl)
  404.     jr    z,posok
  405.     ld    (hl),a
  406.     push    hl
  407.     push    bc
  408.     ld    l,(iy + #col)
  409.     ld    h,(iy + #row)
  410.     call    moveto
  411.     pop    bc
  412.     pop    hl
  413. posok:    ld    a,c
  414.     cp    '\n'
  415.     jr    z,scrl
  416.     cp    '\r'
  417.     jr    nz,trybs
  418. scrl:    xor    a
  419.     cp    (iy + #lff)
  420.     ret    nz
  421.     ld    (iy + #col),a
  422.     ld    (hl),h
  423.     ld    (iy + #lff),h
  424.     ld    a,(wtflag)
  425.     or    a
  426.     jr    nz,roll
  427.     ld    a,(iy + #top)
  428.     ld    h,(iy + #bot)
  429.     ld    l,22
  430.  
  431. ; rollit - scroll a region on the screen - this is made external so the VT100
  432. ; code can get at it
  433.  
  434. .extern    rollit
  435. rollit:    or    a
  436.     push    hl
  437.     jr    nz,dell
  438.     ld    hl,23 << 8
  439.     call    moveto
  440.     ld    c,'\n'
  441.     call    scrout
  442.     jr    dontop
  443. dell:    ld    l,0
  444.     ld    h,a
  445.     call    moveto
  446.     call    dellin
  447. dontop:    pop    hl
  448.     ld    a,h
  449.     cp    l
  450.     ret    z
  451.     ld    l,0
  452.     call    moveto
  453.     jp    inslin
  454.  
  455. roll:    ld    a,(iy + #row)
  456.     call    incrow
  457.     ld    (iy + #row),a
  458.     call    incrow
  459.     ld    h,a
  460.     ld    l,0
  461.     call    moveto
  462.     jp    cleol
  463.  
  464. incrow:    cp    (iy + #bot)
  465.     jr    z,reload
  466.     inc    a
  467.     ret
  468. reload:    ld    a,(iy + #top)
  469.     ret
  470.  
  471. .dseg
  472. .extern    pccs
  473. pccs:    db    0
  474. ringpr:    dw    0
  475. ringpw:    dw    0
  476. lstpr:    dw    0
  477. lstpw:    dw    0
  478.  
  479. .useg
  480. ring:    ds    1024
  481. lstbuf:    ds    1024
  482.  
  483. wrdat:
  484. rwhere:    ds    1
  485. rbot:    ds    1
  486. rtop:    ds    1
  487.  
  488. wsdat:
  489. swhere:    ds    1
  490. sbot:    ds    1
  491. stop:    ds    1
  492.  
  493. rcol:    ds    1
  494. rrow:    ds    1
  495. rlff:    ds    1
  496.  
  497. scol:    ds    1
  498. srow:    ds    1
  499. slff:    ds    1
  500.  
  501. .extern    where
  502. where:    ds    1
  503. wtflag:    ds    1
  504.  
  505. .dseg
  506.  
  507. sdat:    db    0,22,12
  508.     db    1,10,0
  509.  
  510. bdat:    db    0,22,5
  511.     db    1,3,0
  512.