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 / KAYPRO / KPNUROM.LBR / KVIDEO.ZQ0 / KVIDEO.Z80
Text File  |  2000-06-30  |  17KB  |  701 lines

  1. title    'Revised screen handler for Kaypro 4-83 85/6/13'
  2. ; Requires z80asm to handle the external byte variables?
  3.     .z80
  4. ;
  5. ; Access to this module
  6.     entry    vidinit;    initialize
  7.     entry    vidout;        output (c) to screen
  8. ;
  9. ; System constants
  10.     extrn    bitport;    bank switching, Kaypro
  11.     extrn    bankbit;    how to bank switch
  12. ;
  13. ; Connection to other areas
  14.     extrn    .kbdout;    (c) to keyboard, for bells
  15. ;
  16. ; Connection to the actual video memory
  17.     extrn    scrnbas;    3000h, address of 1st screen line
  18.     extrn    oneline;    128, storage used per line
  19.     extrn    maxln;        24, lines on screen available
  20. ;
  21. ; Computed from above, must be external for assembler
  22.     extrn    endline;    address of last screen line
  23. ;                scrnbas + (maxln-1) * oneline
  24.     extrn    line25;        base address past screen shr 8
  25. ;                (endline + oneline) shr 8
  26.     extrn    colmask;    oneline - 1
  27. ;
  28. ; This emulates the original Kaypro/ADM3A protocol, with some
  29. ; additions and refinements.  The video RAM is organized as
  30. ; 24 lines of 128 chars, but chars past column 80 must not be
  31. ; written. The control and escape sequences are an amalgamation
  32. ; of those in the original Kaypro, those used with SWP's CoPower
  33. ; 88 on the Kaypro, and extensions.  The characteristics of some
  34. ; control sequences are altered, e.g. control of column position,
  35. ; line wrap only occurs when a character is output past column
  36. ; 80, etc.  Characters with high order bits set are used directly
  37. ; for display, not as controls.
  38. ;     Copyright (c) 85/6/13 by C.B. Falconer
  39. ;
  40. ; 85/6/18. vidout now returns current cursor position in hl
  41. ;
  42. ; Control Char usage ( * all not mentioned are normally ignored)
  43. ;    bel   ^G    Ring bell
  44. ;    bs    ^H    cursor left (not past start of line)
  45. ; *  tab   ^I    cursor right to tab pt (not past end of line)
  46. ;    lf       ^J   cursor down.  Scroll at bottom, keep column
  47. ;    vt    ^K    cursor up. Scroll at top, keep column
  48. ;    ff       ^L   cursor right one (not past end of line)
  49. ;    cr       ^M   cursor to left of current line
  50. ;    etb   ^W    Clear from cursor to end of screen inclusive
  51. ;    can   ^X    clear cursor to end of line inclusive
  52. ;    sub   ^Z    clear screen and home cursor
  53. ;    esc   ^[    SEE BELOW
  54. ;    rs    ^6    Home cursor to top left.  Do not clear
  55. ; *  us       ^-    Next single char not a control, display only
  56. ;
  57. ; Escape sequences, all begin with esc (01bh)
  58. ; *  C       following char used as cursor marker, flashing. Useful
  59. ;              ones on Kaypro are DEL, US (=^-), and _. Any allowed
  60. ; *  D       following char used as cursor, not flashing. See above
  61. ;    E       Insert cursor line, scrolling all below down. Keep column
  62. ;    R       Delete cursor line, scrolling all below up. Keep column
  63. ; *  e       Insert blank at cursor posn. Chars off end of line lost
  64. ; *  r       Delete char. at cursor posn. Line closes up
  65. ; *  (       Set attribute to flash.  Further chars. to screen flash
  66. ; *  )       Set attribute no flash.  Further chars do not flash
  67. ;    =       Next two chars position cursor, as before and ADM3
  68. ; * other  The esc is discarded, and the char. used as normal. 
  69. ;
  70. ;    ( * marks usage not available in original Kaypro    )
  71. ;    ( The esc ( and esc ) sequences are reversed from the    )
  72. ;    ( usage on the CoPower88. The original esc A and esc G    )
  73. ;    ( have been deleted.  Use the ^- operation instead.    )
  74. ;       (  esc C, esc D, esc e, and esc r are totally new. The    )
  75. ;    ( tab is also new, and has stops every 8 columns. The    )
  76. ;    ( scroll action on ^J, ^K at screen ends is different,    )
  77. ;    ( as is the wrap around action at column 80.        )
  78. ;
  79. true    equ    -1
  80. false    equ    not true
  81. ;
  82. bell    equ    07h
  83. bs    equ    08h
  84. tab    equ    09h
  85. lf    equ    0ah
  86. vt    equ    0bh
  87. ff    equ    0ch
  88. cr    equ    0dh
  89. etb    equ    17h
  90. can    equ    18h
  91. subs    equ    1ah
  92. esc    equ    1bh
  93. rs    equ    1eh
  94. us    equ    1fh
  95. del    equ    7fh
  96. ;
  97. maxcol    equ    80
  98. ;
  99. flash    equ    080h;        video bit causes flashing
  100. ;
  101. initcur    equ    del + flash;    for light block.
  102. ;        us + flash;    for solid block
  103. ;        '_' + flash;    for original
  104. ;                remove "+ flash" for steady
  105. ;
  106. ; Case table entry
  107. table    macro    ch, where
  108.     db    ch
  109.     dw    where
  110.     endm
  111. ;
  112. ; -----------------------------------------
  113. ;
  114. ;    dseg
  115. ;
  116.     extrn    vstate, cursor
  117.     extrn    row, cchar, cmark, attrib
  118. ;
  119. ; data area.  The Kaypro Screen memory has 128 bytes of unused
  120. ; space, in 8 blocks of 16 (peculiar addressing).  This storage
  121. ; should eventually be placed there for privacy.
  122. ;vstate: ds    2;    init to vnorm
  123. ;cursor: ds    2;    location of cursor on screen
  124. ;row:     ds    1;    1st arg in "esc=yx" sequence
  125. ;cchar:     ds    1;    char for cursor locn
  126. ;cmark:     ds    1;    cursor char for screen for blank
  127. ;attrib: ds    1;    Video attrib for new chars, 80h for flash
  128. ;
  129. ; ------------------------------------
  130. ;
  131.     cseg
  132. ;
  133. ; Output (c) to screen;
  134. ; Return hl as suitable chars for cursor positioning sequence
  135. ; i.e. <esc>'=',h,l will restore the cursor to present posn.
  136. ; any non executed chars (e.g. esc) will return the present
  137. ; cursor without moving it.  Thus the value returned at the
  138. ; start of a cursor sequence can be used for restoration.
  139. ; a := c, f, h,l
  140. vidout:    push    bc
  141.     push    de
  142.     ld    hl,(vstate)
  143.     call    xpchl;        execute per current state
  144.     ld    hl,(cursor);    return current cursor posn
  145.     ld    de,-scrnbas
  146.     add    hl,de
  147.     ld    a,l
  148.     and    colmask
  149.     cp    maxcol
  150.     ccf;            so carry if = maxcol
  151.     sbc    a,0;        If past eol lie, put at eol
  152.     add    a,' ';         so that a restore is reasonable
  153.     ld    e,a;        x position character
  154.     add    hl,hl
  155.     ld    a,h
  156.     add    a,' '
  157.     ld    d,a
  158.     ex    de,hl;        one off if past end of line
  159.     pop    de
  160.     pop    bc
  161.     ld    a,c
  162.     ret
  163. ;
  164. ; for executing "call (hl)"
  165. xpchl:    jp    (hl)
  166. ;
  167. ; -------- NORMAL processing.  Everything else is frills --------
  168. ;
  169. ; output the char in (c) to the screen.  8th bits mean display
  170. ; the character without interpreting as a control code, etc.
  171. ; The video RAM itself uses the 8th bit as a "flash" attribute.
  172. ; The system never wraps a line unless there is really more data
  173. ; to be placed on the new line.  Cursor is user-settable.  A
  174. ; line feed (or down arrow) on the bottom line preserves the
  175. ; column location, while scrolling.  Planned window scrolling.
  176. ; a,f,b,c,d,e,h,l
  177. vnorm:    ld    a,c
  178.     or    a
  179.     jp    p,vnorm1;    no, hi bit, normal use
  180.     and    07fh;        remove hi bit
  181.     ld    c,a
  182.     jp    vdirkt;        and use as is
  183. vnorm1:    inc    a
  184.     and    07fh;        map rub into controls
  185.     cp    ' '+1
  186.     jp    c,vctrl;    implement control chars
  187. ;    "    "
  188. ; Output char. directly.  No control implemention
  189. ; a,f,b,d,e,h,l
  190. vdirkt:    ld    hl,vnorm
  191.     ld    (vstate),hl;    always reverts to normal
  192.     call    clrcur;        no carry if line must wrap, set hl
  193.     call    nc,lnwrap;    clears carry if no scroll needed
  194.     call    nc,scroll;    only called when off page bottom
  195. ;    "    "
  196. ; set character (c) into location (hl), setting cursor at next
  197. ; location.  If next is past eol then set cursor at eol.  At
  198. ; entry hl must NOT be outside the range 0..79, i.e. in line
  199. ; a,f,h,l
  200. putc:    ld    a,(attrib)
  201.     or    c;        set current attribute
  202.     ld    (hl),a;        put char on screen
  203. ;    "    "
  204. ; Advance cursor hl to next position.  Mark screen etc.
  205. ; a,f,h,l
  206. advcur:    inc    hl
  207. ;    "    "
  208. ; put cursor to location hl.  Range may be 0..80 (i.e. off eol)
  209. ; a,f,h,l
  210. putcur:    ld    (cursor),hl;    save for next use
  211.     ld    a,l;         (col = 80 signals off screen) 
  212.     and    colmask
  213.     cp    maxcol
  214.     jp    c,setcur;    next is not off screen
  215.     dec    hl
  216. ;    "    "
  217. ; set cursor at location (hl), known to be on screen
  218. ; a,f
  219. setcur:    ld    a,(hl)
  220.     ld    (cchar),a
  221.     or    flash;        mark as a cursor
  222.     cp    ' ' + flash
  223.     jp    nz,setc1
  224.     ld    a,(cmark)
  225. setc1:    ld    (hl),a;        put it in screen display
  226.     ret
  227. ;
  228. ; --------------- CONTROL Char. Processing ----------------
  229. ;
  230. ; Control char input
  231. vctrl:    ld    hl,ctbl;    dont optimise, because we
  232.     call    case;        need this level on stack
  233.     ret;            if not found, ignore the char
  234. ;
  235. ; Control char case tabel
  236. ctbl:    table    bell, dobell
  237.     table    bs,   goleft
  238.     table    tab,  dotab
  239.     table    lf,   down
  240.     table    vt,   up
  241.     table    ff,   right
  242.     table    cr,   docr
  243.     table    etb,  clreos
  244.     table    can,  clreol
  245.     table    subs, clrscrn
  246.     table    rs,   home
  247.     table    us,   exact
  248.     table    esc,  escape
  249.     db    0ffh;        end marker
  250. ;
  251. ; <esc> found in input
  252. escape:    ld    hl,esc1
  253. ;    "    "
  254. ; Set state for next input character
  255. next:    ld    (vstate),hl
  256.     ret
  257. ;
  258. ; Accept next character as is, never a control
  259. ; h,l
  260. exact:    ld    hl,vdirkt
  261.     jp    next
  262. ;
  263. ; initialize system
  264. ; a,f,h,l
  265. vidinit:
  266.     ld    hl,vnorm
  267.     ld    (vstate),hl
  268.     ld    hl,scrnbas
  269.     ld    (cursor),hl
  270.     ld    a,' '
  271.     ld    (cchar),a
  272.     ld    a,initcur
  273.     ld    (cmark),a
  274.     xor    a
  275.     ld    (attrib),a
  276. ;    "    "
  277. ; clear screen.  Put cursor at line 0 column 0
  278. ; a,f,h,l
  279. clrscrn:
  280.     call    clrcur
  281.     ld    hl,scrnbas
  282.     push    hl
  283. clrsc1:    call    clrln
  284.     call    nxtln
  285.     jp    c,clrsc1;    not done yet
  286. clrsc2:    pop    hl;            << *** Entry from clreos **
  287.     jp    putcur
  288. ;
  289. ; home cursor
  290. home:    call    clrcur
  291.     ld    hl,scrnbas
  292.     jp    putcur
  293. ;
  294. ; clear from cursor to end of screen, inclusive
  295. clreos:    call    clrcur
  296.     push    hl
  297.     call    c,clrel;    Not at eol, clear rest if line
  298. clres1:    call    nxtln
  299.     jp    nc,clrsc2;    done remainder
  300.     call    clrln
  301.     jp    clres1;        and check next
  302. ;
  303. ; clear to end of line, from and including current cursor posn
  304. ; a,f,h,l
  305. clreol:    call    clrcur
  306.     jp    nc,advcur;    at eol already, no work
  307.     push    hl;        save cursor for later setting
  308.     call    clrel
  309.     pop    hl
  310.     jp    putcur;        and install the marker    
  311. ;
  312. ; Move cursor right
  313. ; a,f,h,l
  314. right:    call    clrcur
  315.     jp    advcur
  316. ;
  317. ; move cursor left, unless at line start
  318. ; a,f,h,l
  319. goleft:    ld    hl,(cursor)
  320.     ld    a,l
  321.     and    colmask
  322.     ret    z;        at line left, hang
  323.     call    clrcur
  324.     jp    nc,putcur;    was past eol, just put it back
  325.     dec    hl
  326.     jp    putcur
  327. ;
  328. ; move cursor up, maintaining column.  May scroll screen down
  329. ; a,f,b,c,d,e,h,l
  330. up:    call    clrcur;        and ignore line wraps
  331.     call    prvln
  332.     call    nc,scrldn;    at screen top. hl points to ln -1
  333.     jp    putcur;        put it back
  334. ;
  335. ; move cursor down, maintaining column.  May scroll screen up
  336. ; a,f,b,c,d,e,h,l
  337. down:    call    clrcur;        but ignore line wraps
  338.     call    nxtln
  339.     call    nc,scroll;    now must scroll, maintaining column
  340.     jp    putcur
  341. ;
  342. ; put cursor at line left
  343. ; a,f,h,l
  344. docr:    call    clrcur
  345.     ld    a,l
  346.     and    not colmask;    set to column 0
  347.     ld    l,a
  348.     jp    putcur
  349. ;
  350. ; Tab to column modulo 8
  351. ; a,f,h,l
  352. dotab:    call    clrcur
  353.     jp    nc,advcur;    was at eol, dont change
  354.     inc    hl;        at least one space
  355.     ld    a,l
  356.     add    a,7;        max result 87, no carry
  357.     and    not 7;        must be <= 80
  358.     ld    l,a
  359.     jp    putcur
  360. ;
  361. ; -------------- ESCAPE Sequence processing -----------------
  362. ;    
  363. ; 1st char after <esc> is in c
  364. esc1:    ld    hl,vnorm
  365.     ld    (vstate),hl;    default, unless long sequence
  366.     ld    hl,etbl
  367.     call    case;        If not found then
  368.     jp    vnorm;        discard esc, output char
  369. ;
  370. ; Escape sequence initial char table
  371. etbl:    table    'R', deline
  372.     table    'r', delch
  373.     table    'E', insline
  374.     table    'e', insch
  375.     table    '(', setflash
  376.     table    ')', clrflash
  377.     table    'C', escC
  378.     table    'D', escD
  379.     table    '=', escEQ
  380.     db    0ffh;        end marker
  381. ;
  382. ; Cursor with flash.  Next char is cursor char
  383. escC:    ld    hl,esc2c
  384.     jp    next
  385. ;
  386. ; Cursor with no flash.  Next char is cursor char
  387. escD:    ld    hl,esc2d
  388.     jp    next
  389. ;
  390. ; Cursor setting coming. Next char is row
  391. escEQ:    ld    hl,esc2
  392.     jp    next
  393. ;
  394. ; Insert blank at cursor position
  395. insch:    call    clrcur
  396.     jp    nc,advcur;    already past eol, put it back
  397.     push    hl
  398.     ld    b,(hl)
  399. insch1:    inc    hl
  400.     ld    a,l
  401.     and    colmask
  402.     cp    maxcol
  403.     jp    nc,inschx;    done line move
  404.     ld    a,(hl)
  405.     ld    (hl),b
  406.     ld    b,a
  407.     jp    insch1;        continue
  408. inschx:    pop    hl
  409.     ld    (hl),' '
  410.     jp    putcur
  411. ;
  412. ; Delete char at cursor position
  413. delch:    call    clrcur
  414.     jp    nc,putcur;    was past eol, back to end
  415.     push    hl
  416.     ld    d,h
  417.     ld    e,l
  418. delch1:    inc    hl
  419.     ld    a,l
  420.     and    colmask
  421.     cp    maxcol
  422.     jp    nc,delchx;    done
  423.     ld    a,(hl)
  424.     ld    (de),a
  425.     inc    de
  426.     jp    delch1
  427. delchx:    ex    de,hl
  428.     ld    (hl),' '
  429.     pop    hl
  430.     jp    putcur
  431. ;
  432. ; insert line at current cursor position. Scroll below down
  433. ; a,f,b,c,d,e,h,l
  434. insline:
  435.     call    clrcur
  436.     push    hl;        save for final cursor setting
  437.     call    dnscrl
  438.     pop    hl
  439.     jp    putcur
  440. ;
  441. ; delete line at current cursor position. Scroll below up
  442. ; a,f,b,c,d,e,h,l
  443. deline:    call    clrcur
  444.     push    hl;        save for final cursor setting
  445.     ld    b,endline shr 7;    end pointer
  446.     call    mvlns
  447.     ex    de,hl
  448.     call    clrln;        clear the bottom line
  449.     pop    hl
  450.     jp    putcur
  451. ;
  452. ; Setting attribute for flashing
  453. ; a
  454. setflash:
  455.     ld    a,flash
  456.     ld    (attrib),a
  457.     ret
  458. ;
  459. ; Setting attribute for no flashing
  460. ; a
  461. clrflash:
  462.     xor    a
  463.     ld    (attrib),a
  464.     ret
  465. ;
  466. ; setting cursor on esc C (flash)
  467. ; a,f,h,l
  468. esc2c:    ld    a,c
  469.     or    flash
  470. esc2x:    ld    (cmark),a
  471.     call    clrcur
  472.     jp    c,esc2xa;    not past eol
  473.     inc    hl
  474. esc2xa:    call    putcur;        update the cursor style
  475.     ld    hl,vnorm
  476.     jp    next
  477. ;
  478. ; setting cursor on esc D (no flash)
  479. ; a,f,h,l
  480. esc2d:    ld    a,c
  481.     and    not flash
  482.     jp    esc2x
  483. ;
  484. ; First char after "esc =" recognized.
  485. ; a,f,h,l
  486. esc2:    ld    a,c
  487.     ld    (row),a;    Save for next char.
  488.     ld    hl,esc3
  489.     jp    next
  490. ;
  491. ; Position cursor to column (c), row (row).
  492. ; a,f,c,h,l
  493. esc3:    ld    hl,vnorm
  494.     ld    (vstate),hl
  495.     call    clrcur
  496.     ld    a,c
  497.     sub    ' '
  498. esc3a:    sub    maxcol
  499.     jp    nc,esc3a;    col modulo maxcol
  500.     add    a,maxcol
  501.     rla;            compensate for later rra
  502.     ld    c,a
  503.     ld    a,(row)
  504.     sub    ' '
  505. esc3b:    sub    maxln
  506.     jp    nc,esc3b;    row modulo maxln
  507.     add    a,maxln + scrnbas shr 7
  508.     or    a
  509.     rra;            position, save rh bit
  510.     ld    h,a
  511.     ld    a,c;        which goes into col byte
  512.     rra
  513.     ld    l,a
  514.     jp    putcur
  515. ;
  516. ; ------------------ SUBROUTINES ------------------
  517. ;
  518. ; clear current cursor marker. Return hl = cursor posn
  519. ; Return no carry if past eol, when hl is decremented
  520. ; a,f,h,l
  521. clrcur:    ld    hl,(cursor)
  522.     ld    a,l
  523.     and    colmask
  524.     cp    maxcol
  525.     jp    c,clrc1;    Normal, no line end
  526.     dec    hl
  527. clrc1:    ld    a,(cchar)
  528.     ld    (hl),a;        Restore actual char at cursor
  529.     ret
  530. ;
  531. ; Wrap cursor hl to start of next line.
  532. ; a,f,h,l
  533. lnwrap:    ld    a,l
  534.     and    not colmask
  535.     ld    l,a;        point to line start
  536. ;    "    "
  537. ; advance to next line, same col.  No carry for off screen
  538. ; a,f,h,l
  539. nxtln:    ld    a,oneline
  540.     add    a,l
  541.     ld    l,a
  542.     adc    a,h
  543.     sub    l
  544.     ld    h,a
  545.     cp    line25
  546.     ret;            with carry unless off screen
  547. ;
  548. ; advance BACKwards to previous line.  No carry for off screen
  549. ; a,f,h,l
  550. prvln:    ld    a,l
  551.     sub    oneline
  552.     ld    l,a
  553.     ccf;            so similar to nxtln
  554.     ret    c;        not off screen, no cy into h
  555.     dec    h;        depends on page aligned screen
  556.     ld    a,h
  557.     cp    scrnbas shr 8;    carry if too far back
  558.     ccf;            now no carry means off screen
  559.     ret
  560. ;
  561. ; PROCEDURE movelines(endline, objective);
  562. ;
  563. ;   WHILE endline <> objective DO BEGIN               (* h <> b *)
  564. ;     destination := endline;                 (* de := hl *)
  565. ;     IF destination < objective THEN        (* normal scroll *)
  566. ;       endline := destination + oneline        (* screen up *)
  567. ;     ELSE endline := destination - oneline;      (* screen down *)
  568. ;     moveline(endline, destination); END;
  569. ;
  570. ; The entry hl and b values are the high bytes of the cursor for
  571. ; the respective lines, i.e. actual RAM addresses.  At entry:
  572. ;   hl^ is the farthest line to alter (destination).
  573. ;   b is the line to empty, left shifted to hold lsb. (objective)
  574. ; returns de = start of destination line, h = d.
  575. ; a,f,d,e,h,l             (*** ENTRY IN MIDDLE ***)
  576. mvlns2:    ld    a,e;        h > b
  577.     sub    oneline
  578.     ld    l,a;        hl := hl - oneline
  579.     jp    nc,mvlns3;    no borrow
  580.     dec    h
  581. mvlns3:    push    bc
  582.     ld    bc,maxcol
  583.     ldir;            do the actual move
  584.     pop    bc
  585. ;    "    "
  586. mvlns:    ld    a,l;            **** ENTRY POINT **** <<
  587.     and    not colmask
  588.     ld    e,a
  589.     ld    d,h;        de := hl masked to line start
  590.     rla
  591.     ld    a,h
  592.     rla
  593.     cp    b
  594.     ret    z;        h = b; exit move
  595.     jp    nc,mvlns2;    h > b
  596.     ld    a,e;        h < b
  597.     add    a,oneline
  598.     ld    l,a;        hl := hl + oneline
  599.     adc    a,h
  600.     sub    l
  601.     ld    h,a
  602.     jp    mvlns3
  603. ;
  604. ; scroll complete screen down, clear first line,
  605. ; At entry from normal scroll operation, (c) is char yet
  606. ; to be placed, hl points to the start of the non-existent
  607. ; line -1.  Set cursor for unchanged column on first line.
  608. ; a,f,b,c,d,e,h,l
  609. scrldn:    call    nxtln
  610. ;    "    "
  611. ; As scrldn, except input cursor is on the final line
  612. ; a,f,b,c,d,e,h,l
  613. dnscrl:    ld    a,l
  614.     push    af;        save final column
  615.     ld    a,l
  616.     rla
  617.     ld    a,h
  618.     rla
  619.     ld    b,a;        set destination line
  620.     ld    hl,endline;    1st to modify
  621.     call    mvlns
  622.     ex    de,hl;        point to last (garbage) line
  623.     call    clrln    
  624.     pop    af
  625.     ld    l,a;        set final column
  626.     ret
  627. ;
  628. ; scroll complete screen up, clear last line,
  629. ; At entry from normal scroll operation, (c) is char yet
  630. ; to be placed, hl points to the start of the non-existent
  631. ; line 25.  Set cursor for unchanged column on last line.
  632. ; a,f,b,c,d,e,h,l
  633. scroll:    call    prvln
  634. ;    "    "
  635. ; As scroll, except input cursor is on the final line
  636. ; a,f,b,c,d,e,h,l
  637. upscrl:    ld    a,l
  638.     push    af;        save final column
  639.     ld    a,l
  640.     rla
  641.     ld    a,h
  642.     rla
  643.     ld    b,a;        set destination line
  644.     ld    hl,scrnbas;    1st line to modify is 0
  645.     call    mvlns
  646.     ex    de,hl;        point to last (garbage) line
  647.     call    clrln    
  648.     pop    af
  649.     ld    l,a;        set final column
  650.     ret
  651. ;
  652. ; clear one line
  653. ; a,f,h,l
  654. clrln:    ld    a,l
  655.     and    not colmask
  656.     ld    l,a
  657. ;    "    "
  658. ; clear from cursor (in hl) inclusive to end of line
  659. ; a,f,h,l
  660. clrel:    ld    a,l
  661.     and    not colmask
  662.     add    a,maxcol
  663. ;    "    "
  664. ; clear from cursor (in hl) to point marked by (a)
  665. ; f,h,l
  666. clr:    ld    (hl),' '
  667.     inc    hl
  668.     cp    l
  669.     jp    nz,clr
  670.     ret
  671. ;
  672. ; Ring the bell
  673. ; a,f,c
  674. dobell:    ld    c,04h
  675.     jp    .kbdout
  676. ;
  677. ; case jump via table hl^ and char in c.
  678. ; Returns only if no entry found, else return address purged.
  679. ; Therefore do NOT jump to this (will omit purgable address)
  680. ; Table structure is byte, address.  Byte = 0ffh for end marker.
  681. ; a,f,h,l            *** ENTRY IN MIDDLE ***
  682. case1:    inc    hl
  683.     inc    hl
  684. case:    ld    a,(hl);            <<< ** ENTRY HERE ** <<<
  685.     inc    a
  686.     ret    z;        table end, no entry
  687.     dec    a
  688.     cp    c
  689.     inc    hl;        to low byte of address
  690.     jp    nz,case1;    not this entry
  691.     ld    a,(hl)
  692.     inc    hl
  693.     ld    h,(hl)
  694.     ld    l,a
  695.     ex    (sp),hl;    purge return, stack exu point
  696.     ret
  697. ;
  698. ; -------------- END of Screen Control System ---------------
  699. ;
  700.     end
  701.