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 / PROGRAMS / BKGRONDR / BGK84SCR.LBR / K84SCRN.AZM / K84SCRN.ASM
Assembly Source File  |  2000-06-30  |  26KB  |  1,438 lines

  1.     .title    "K84SCRN.ASM Kaypro '83 screen driver 11/8/86"
  2.     .sbttl    "Copyright (c) 1986  Plu*Perfect Systems"
  3.  
  4. noatt = 1        ;nul return-attribute function to save space
  5.  
  6. DEBUG =    0
  7.  
  8. .remark \==
  9. Source code for CDL/TDL Z80 assembler (AZM.COM).
  10.  
  11. ; production by:
  12. ;
  13. AZM k84scrn
  14. ZLINK
  15. *k84.com=k84scrn.rel
  16. */locate .prog.=3f80;
  17. *q
  18. ZSID k84.com
  19. m3f80 4500 100
  20. ^C
  21. SAVE 5 k84scrn.drv
  22.  
  23. ==\
  24. ; revision history:
  25. ;
  26. ; v 1.0: no scroll on line 24 in cut
  27. ;      id imbedded in string 
  28. ;     most data put in-line to save bytes
  29.  
  30. .XLIST
  31.  
  32. .ifg DEBUG, [
  33.     bios =\  'Base of bios = ?'
  34.     ]
  35.  
  36. .remark \===
  37.  
  38. The first sections of code are generic (except for some terminal equates);
  39. beginning at 'STMRKS' it is terminal-specific.
  40.  
  41. Particular features of Kaypro '84 code:
  42.  
  43. 1. Video ram must be accessed via video controller.
  44. 2. We store screen attributes as nybbles.
  45. 3. Cursor-movement sequences are all single-byte control characters.
  46.  
  47. Space is very tight; in-line data used extensively.
  48.  
  49. ===\
  50.  
  51. .ifg    DEBUG, [
  52. codloc    =    100h
  53. .phex
  54. .psym
  55. .pabs
  56. consta    =    bios +06h
  57. conin    =    bios +09h
  58. conout    =    bios +0ch
  59.     ]
  60. ;
  61.     [
  62. .prel
  63. .ident    SCRK84
  64.  
  65. consta    =    0
  66. conin    =    0
  67. conout    =    0
  68. outch    =    0
  69. puts    =    0
  70. bwrch    =    0
  71. bflush    =    0
  72.     ]
  73.  
  74. .xsym
  75. .sall
  76. ;
  77.  
  78. ; ascii equates
  79. ;
  80. NUL    =    00h
  81. BELL    =    07h
  82. BS    =    08h
  83. CR    =    0dh
  84. LF    =    0ah
  85. ESC    =    1bh
  86. SPACE    =    20h
  87. DEL    =    7fh
  88. ;
  89. ; CUT command characters
  90. ;
  91. HOME    =    'H'        ;home the cursor
  92. LOHOME    =    'h'
  93. MARK    =    'X'        ;set a mark
  94. LOMARK    =    'x'
  95. PASTE    =    'P'-'@'        ;paste region at cursor
  96. CANCEL    =    'C'-'@'        ;cancel cut command
  97. ;
  98. ;
  99. ; TERMINAL-SPECIFIC EQUATES
  100. ;
  101. ; kaypro cursor controls
  102. ;
  103. LEFT    =    08H
  104. RIGHT    =    'L'-'@'
  105. UP    =    'K'-'@'
  106. DOWN    =    0AH
  107. ;
  108. LEFT8    =    82h        ;kaypro raw keypad arrow values...
  109. RIGHT8    =    83h
  110. UP8    =    80h
  111. DOWN8    =    81h
  112. ;
  113. HOMEC    =    1eh        ;home cursor
  114. ;
  115.  
  116. ; Kaypro '84 screen parameters
  117. ;
  118. NCOLS    =    80
  119. NROWS    =    25
  120. NROW24    =    24        ;# rows excluding status line
  121. ;
  122. SCRSIZ    =    NCOLS*NROWS
  123. ;
  124. ; Kaypro '84 controller ports
  125. ;
  126. vcbase    =    1ch
  127. vccmd    =    vcbase
  128. vcstat    =    vcbase
  129. vcrdat    =    vcbase+1
  130. vcdata    =    vcbase+3
  131. ;
  132. ; controller register numbers
  133. ;
  134. cstart    =    10        ;cursor start
  135. cstop    =    11        ;cursor stop
  136. hiadd    =    18        ;hi address byte - update register
  137. loadd    =    19        ;lo ""
  138. ;
  139. scrcmd    =    12        ;"scroll" set home addr
  140. curcmd    =    14        ;place cursor
  141. rwcmd    =    18        ;read/write
  142. strcmd    =    31        ;strobe
  143. ;
  144. ;=========================
  145.  
  146. .ifg DEBUG, [
  147.     .loc    codloc
  148.     ]
  149. ;
  150.     [
  151.     .loc    .PROG.
  152.     ]
  153. ;
  154. ;------------------------------------------------------------
  155. ;
  156. ; id sector - nul-terminated string - at 3f80h
  157. ;
  158. sdid:    .ascii    "Kaypro '84 driver v 1.0"
  159.     db    0            ;NUL terminator
  160. idlen = . - sdid
  161.     ds    80h-idlen        ;total of 80h bytes
  162.  
  163. ;
  164. START:
  165. ;
  166. ;
  167. ; Start of Screen Module.  Assemble to run at 4000h.
  168. ;
  169. ;***** MODULE ENTRY HEADER
  170. ;
  171. ; EXTERNAL ADDRESSES, supplied by loader
  172. ;
  173. jjcons:    jmp    consta        ;bios constat
  174. jjconi:    jmp    conin        ;bios conin
  175. jjouta:    jmp    outch        ;A to conout, preserving bc,de,hl
  176. jjputs:    jmp    puts        ;hl-string to conout, NUL/bit-7 term.
  177.                 ; preserving bc,de,hl
  178. jjbrdc:    jmp    0000        ;buffered read char from cut-swp
  179. jjbwrc:    jmp    bwrch        ;buffered write char to cut-swp
  180. jjbflu:    jmp    bflush        ;flush (write) buffer
  181. ;
  182. ; INTERNAL ENTRY POINTS
  183. ;
  184. savscr:    jmp    savpag        ;save screen 
  185. resscr:    jmp    respag        ;restore saved screen
  186. lastnb:    jmp    lstnbl        ;last non-blank char in rows 1-24
  187. dmpchr:    jmp    retnch        ;return next screen char
  188. dmpcur:    jmp    retncu        ;return buffer cursor
  189. dmpatt:    jmp    retnat        ;return next screen attribute
  190. setmrk:    jmp    stmrks        ;set region marks, move cursor
  191. cutrg:    jmp    docut        ;cut region
  192. pastrg:    jmp    dopast        ;paste region
  193. ininpd:    jmp    ininot        ;initialize notepad
  194. putnpd:    jmp    putnch        ;put char to notepad
  195. ;
  196. ;========================================
  197. ; generic
  198. ;
  199. ININOT:
  200. ;
  201. ; Initiate Notepad - clear screen, print banner.
  202. ;
  203.     lxi    h,Zbanner
  204.     jr    jjputs
  205. ;
  206. ;========================================
  207. ; generic
  208. ;
  209. PUTNCH:
  210. ;
  211. ; Put char in A  to notepad (screen)
  212. ; Convert CR to CRLF, DEL to rubout.
  213. ;
  214.     cpi    CR
  215.     lxi    h,Zcrlf        ;convert CR to CR,LF
  216.     jrz    jjputs
  217.     cpi    DEL
  218.     lxi    h,Zrub
  219.     jrz    jjputs
  220.     jr    jjouta
  221.  
  222. ;========================================
  223. ; generic
  224. ;
  225. RETNCU:
  226. ;
  227. ; Return buffer cursor as row/col.
  228. ;
  229. ; ret: D = binary row, E= binary col
  230. ;      L =  ascii row, H = ascii col (for shld ...)
  231. ;
  232.     lhld    bcursor
  233. ;
  234. ; Convert offset to col/row.
  235. ; exit: D = binary row, E = binary col
  236. ;    H = ascii col,  L = ascii row <-- NOTE ORDER
  237. ;
  238. off2cr:    mvi    b,0        ;convert to row,col
  239.     lxi    d,-NCOLS
  240. ..1:    dad    d
  241.     jrnc    ..2
  242.     inr    b        ;row count++
  243.     jr    ..1
  244. ..2:    lxi    d,NCOLS
  245.     dad    d
  246.     mov    a,l        ;col
  247.     mov    e,a        ;binary col in E
  248.     mov    d,b        ;binary row in D
  249.     adi    SPACE        ; + bias
  250.     mov    h,a        ;H = ascii col
  251.     mov    a,b        ;row
  252.     adi    SPACE        ; +bias
  253.     mov    l,a        ;L = ascii row
  254.     ret
  255. ;
  256. ;========================================
  257. ; generic
  258. ;
  259. DOPASTE:
  260. ;
  261. ; Paste the last-cut region onto active screen at the current cursor.
  262. ;
  263. ; 1. Get previously-cut region from external routine
  264. ; 2. Send chars to screen, avoiding boundary overflows. 
  265. ;
  266. ; 'savpag' not needed if terminal supports 'send cursor address'
  267. ;;--    call    savpag        ;get current screen,
  268.                 ;in order to find cursor
  269.     mvi    b,4        ;read 4 data bytes
  270. ..0:    push    b
  271.     call    jjbrdc
  272.     pop    b
  273.     djnz    ..0
  274. ;
  275.     mov    b,a        ;4th byte is # rows
  276.     push    b
  277.     call    crs2hl        ;current cursor's row/col to hl
  278.     pop    b
  279. ;
  280. ; loop over rows
  281. ;
  282. ..rowlp:push    b
  283.     push    h
  284.     mov    e,l        ;e = col no.
  285.     push    d
  286.     call    stcrshl        ;set cursor at h,l
  287. ..collp:call    jjbrdc        ;read char from cut-swp
  288.     cpi    CR
  289.     jrz    ..rend
  290.     mov    c,a        ;save char
  291.     pop    d        ;check for off screen
  292.     mov    a,e
  293.     cpi    NCOLS
  294.     inr    e
  295.     push    d        ;row/col to stack
  296.     cc    sendc        ;to conout, unless off edge
  297.     jr    ..collp
  298. ;
  299. ..rend:    pop    d        ;clear row/col
  300.     pop    h
  301.     pop    b
  302.     inr    h        ;bump row
  303.     mov    a,h        ;check for off bottom of screen
  304.     cpi    NROWS
  305.     jrnc    ..xit
  306.     djnz    ..rowlp
  307. ..xit:    xra    a
  308.     ret
  309. ;
  310. ;========================================
  311. ; generic
  312. ;
  313. DOCUT:
  314. ;
  315. ; Cut rectangular region defined by keypresses.
  316. ; 1. Parse keypresses to move cursor and mark corners.
  317. ;    Highlight region as cursor is moved.
  318. ; 2. Send the marked region, row-wise to external routine.
  319. ;    Append CR after each row.
  320. ;
  321. ; Data structure is:
  322. ;    size (word)
  323. ;    # columns (byte)
  324. ;    # rows (byte)
  325. ;    row 1
  326. ;    CR
  327. ;    row 2
  328. ;    CR
  329. ;    ....
  330. ;
  331. .ifg DEBUG, [
  332. ;for debugging, use cutbuf for output
  333.     lxi    h,cutbuf    ;set ptr
  334.     shld    dbgptr
  335.     ]
  336. ;
  337.     xra    a
  338.     sta    mrkcnt        ;init for next time
  339. ;
  340. ;
  341. ; set ctcols = # cols, ctrows = # rows
  342. ; (assumes mark2 is SE of mark1)
  343. ;
  344. mark1 = .+1
  345. mark1r = .+2
  346. corners:lxi    d,0000    ;binary col, then row of upperleft mark
  347. ;
  348. mark2 = .+1
  349. mark2r = .+2
  350.     lxi    h,0000            ;lower right mark
  351.     mov    a,h    ;# rows = 1 + mark2row -mark1row    
  352.     inr    a
  353.     sub    d
  354.     mov    h,a
  355.     mov    a,l    ;# cols = 1 + mark2col -mark1col
  356.     inr    a
  357.     sub    e
  358.     mov    l,a
  359.     shld    ctcols
  360. ;
  361. ; cut rectangle [mark1...mark2]  & copy to buffer
  362. ; append CR at end of each row
  363. ;
  364.     xchg
  365.     push    h        ;mark1
  366.     call    wrpara        ;write parameters
  367.     pop    h        ;mark1
  368.     call    rc2off        ;convert to scr addr
  369.     lda    ctrows        ;get # rows
  370.     mov    b,a
  371. ;
  372. ; write the cut region to external buffer
  373. ;
  374. ..rowlp:push    b        ;(+1
  375.     push    h        ;(+2
  376.     lxi    d,buf        ;fetch from screen buffer
  377.     dad    d
  378. ;
  379. ; write 1 row of cut region to external buffer
  380. ;
  381.     lda    ctcols
  382.     mov    b,a        ;b = # cols
  383. ;
  384. ; buffered write B chars at hl, ascii only
  385. ;
  386. ..bwrt:    push    b
  387.     push    h
  388.     mov    a,m
  389.     cpi    DEL
  390.     jrnc    ..mksp
  391.     cpi    SPACE        ;convert graphics
  392.     jrnc    ..1
  393. ..mksp:    mvi    a,SPACE        ; to space
  394. ..1:    mov    c,a
  395.     call    jjbwrch
  396.     pop    h
  397.     pop    b
  398.     inx    h
  399.     djnz    ..bwrt
  400. ;
  401.     mvi    c,CR        ;append CR to each row
  402.     call    jjbwrch
  403.     pop    h        ;(+1
  404.     pop    b        ;(+0
  405.     lxi    d,NCOLS        ;bump to next row
  406.     dad    d
  407.     djnz    ..rowlp        ; and loop
  408.     jmp    jjbflu        ;flush the write buffer
  409. ;
  410. ;
  411. ; write parameters: size, # cols, # rows to swp file
  412. ; de = ctcols
  413. ;
  414. wrpara:    mov    b,d        ;# rows
  415.     mvi    d,0
  416.     inr    e        ;+1 for CR
  417.     lxi    h,0        ;accum.
  418. ..0:    dad    d
  419.     djnz    ..0
  420.     call    bwhl        ;write word
  421. ctcols = .+1
  422. ctrows = .+2
  423.     lxi    h,0000        ;now #cols, # rows
  424. ;
  425. bwhl:    push    h
  426.     mov    c,l
  427.     call    jjbwrch
  428.     pop    h
  429.     mov    c,h
  430.     jmp    jjbwrch
  431.  
  432. ;========================================
  433. ; generic
  434. ;
  435. LSTNBL:
  436. ;
  437. ; Find last non-blank line (1-24 only) in current scr buffer.
  438. ; Graphics and 8-bit characters are considered blanks.
  439. ; If B=0ff, save screen first.
  440. ;
  441. ; ret:    H=row, L=col of last non-blank char in rows 1-24
  442. ;
  443.     inr    b
  444.     cz    savpag
  445.     lxi    b,NROW24*100h + NCOLS    ;b=# rows, c=# cols
  446.     lxi    d,buf
  447.     lxi    h,0
  448. ..lp:    ldax    d
  449.     cpi    SPACE+1        ;don't count cntl chars or SPACE
  450.     jrc    ..1
  451.     cpi    DEL        ; or DEL or graphics 8-bit
  452.     jrnc    ..1
  453.     shld    savrc
  454. ..1:    inx    d
  455.     inr    l
  456.     dcr    c
  457.     jrnz    ..lp        ;loop over cols
  458.     inr    h
  459.     mov    l,c        ;0
  460.     mvi    c,NCOLS
  461.     djnz    ..lp        ;loop over rows
  462. savrc = .+1
  463.     lxi    h,0000        ;hl = last non-blank
  464.     ret        
  465.  
  466. ;----------------------------------------
  467. ;
  468. xring:    mvi    c,BELL
  469. ;
  470. ; send C to screen, exit Z, no CY
  471. ;
  472. sendc:    mov    a,c
  473.  
  474. ; send A to screen, exit Z, no CY
  475. ; (this will scroll, however!)
  476. ;
  477. send:    call    jjouta
  478.     xra    a        ;Z, no CY
  479.     ret
  480. ;========================================
  481. ;
  482. ; end of generic code
  483. ;
  484. ;========================================
  485. ; specific
  486. ;
  487. ; bump row/col  var that tracks actual cursor
  488. ; if mark not yet, send cntl char
  489. ; ret NZ if mark is set
  490. ;
  491. inrsnd:    inr    m        ;next row/col
  492.     call    anymrk
  493.     cz    sendc
  494. ;
  495. ; nz if a mark has been set
  496. ;
  497. mrkcnt = .+1
  498. anymrk:    mvi    a,00
  499.     ora    a
  500.     ret
  501. ;
  502. STMRKS:
  503. ;
  504. ; Move cursor and set marks. Return CY clear until exit.
  505. ;
  506. ; 1. move cursor, until:
  507. ; 2. 'X' = set 1st mark
  508. ;    turn on hiliting, set mark, keep cursor at mark
  509. ; 3. move cursor right/down only
  510. ; 4. 'X' = set 2nd mark
  511. ;    turn off hiliting, set 2nd mark
  512. ;    exit CY (done)
  513. ; 5. cntl-C = CANCEL. 
  514. ;    turn off hilighting, set CY, exit
  515. ;
  516. ;
  517.     lxi    h,bincol    ;load ptr to actual col/row
  518.     cpi    CANCEL
  519.     jrz    abort
  520.     cpi    LEFT
  521.     jrz    jjlef8        ;;jz    golef8
  522.     cpi    LEFT8
  523. jjlef8:    jz    golef8
  524. ;
  525.     cpi    UP
  526.     jrz    jjup8        ;;jz    goup
  527.     cpi    UP8
  528. jjup8:    jz    goup8
  529. ;
  530.     cpi    RIGHT
  531.     jrz    jjrt8        ;;jz    gort
  532.     cpi    RIGHT8
  533. jjrt8:    jz    gort8
  534. ;
  535.     cpi    DOWN
  536.     jrz    jjdn8        ;;jz    godn
  537.     cpi    DOWN8
  538. jjdn8:    jz    godn8
  539. ;
  540.     cpi    CR
  541.     jrz    ..mrk
  542. ;
  543.     ani    5fh        ;convert rest to uppercase
  544.     cpi    HOME
  545.     jrz    gohome
  546. ;
  547.     cpi    MARK
  548.     jrz    ..mrk
  549.     xra    a        ;no action
  550.     ret
  551. ..mrk:    lxi    h,mrkcnt    ;if no mark yet set
  552.     mov    a,m
  553.     ora    a
  554.     mvi    m,1
  555.     jrz    mk1        ;..set mark1
  556.     call    mk2        ;else set mark2
  557. mrkxit:    xra    a
  558.     sta    mrkcnt        ;init for next time
  559.     stc            ;CY = all done
  560.     ret
  561. ;
  562. abort:    call    normal        ;restore normal video
  563.     jr    mrkxit
  564.  
  565. ;-------------------------------------------
  566. ;
  567. ; set 1st mark, turn on rev. video, don't move cursor
  568. ;
  569. mk1:    call    crs2hl
  570.     shld    mark1
  571.     shld    mark2               
  572.     shld    curcol        ;L->curcol,H->currow
  573.     push    h
  574.     call    reverse        ;reverse video on
  575. ;
  576. ; Hilite the marked char.
  577. ;
  578.     pop    h        ;mark1
  579.     mvi    a,1        ;blink 1 char
  580.     sta    colct
  581.     sta    rowct
  582.     call    showro
  583.     jmp    sendbs
  584. ;
  585. ; set 2nd mark, restore normal video, set CY
  586. ;
  587. mk2:    call    normal        ;dummy - restore normal video
  588.     stc            ;CY = all done
  589.     ret
  590. ;
  591. ;======================
  592. ; for H19, etc that use ESC sequences,
  593. ; change these routines to send ESC, then the byte.
  594. ;
  595. gohome:    mvi    c,HOMEC        ;convert to video driver's cntl char
  596.     call    anymrk        ;if mark set,
  597.     jnz    xring        ;..error
  598.     mov    h,a        ;set row=col=0
  599.     mov    l,a
  600.     shld    bincol
  601. jjsndc:    jmp    sendc
  602. ;
  603. ; cursor left and cursor up:
  604. ;    send if not at top or left margin
  605. ;
  606. golef8:    mvi    a,LEFT        ;convert to 7-bit char
  607. ;
  608. goleft:                ;hl = bincol
  609. ;
  610. zck:    mov    c,a        ;save char in c
  611.     call    anymrk
  612.     rnz
  613.     cmp    m        ;ck col/row == 0
  614.     jz    xring        ;..error
  615.     dcr    m        ;dcr col/row
  616.     jr    jjsndc
  617. ;
  618. goup8:    mvi    a,UP        ;7-bit code
  619. goup:    inx    h        ;binrow
  620.     jr    zck        ;ck for top row and send
  621. ;
  622. ; cursor right and cursor down:
  623. ;    if mark is not set, move cursor
  624. ;    if mark is set, expand region and highlight
  625. ;    keep track of cursor location in both cases
  626. ;    don't move if it would scroll
  627. ;
  628. ; move cursor right
  629. ;
  630. gort8:    mvi    a,RIGHT        ;convert to 7-bit code
  631. ;
  632. gort:    mov    c,a        ;save in c
  633.     mvi    a,NCOLS-2
  634.     cmp    m
  635. jcxrng:    jc    xring
  636.     call    inrsnd        ;bump col & send if mrk not set
  637.     rz            ;rtn if mark not yet set
  638. ;
  639. ;  hilite marked column
  640. ;
  641. gort1:    lxi    h,mark2
  642.     inr    m        ;bump 2nd mark-row
  643.     lxi    h,curcol    ;bump col
  644.     inr    m
  645.     mov    l,m
  646.     lda    mark1r        ;top row
  647.     mov    h,a        ;h=row, l=col for col to hilite
  648. rowct = .+1
  649.     mvi    b,00
  650. ;
  651. ; loop over each row in cut region
  652. ..rlp:    push    b
  653.     push    h        ;save binary row/col
  654.     mvi    a,1        ;display 1 char in each row
  655.     call    showhi
  656.     pop    h
  657.     pop    b
  658.     inr    h        ;next row
  659.     djnz    ..rlp
  660.     lxi    h,colct        ;prepare to bump col cnt & exit
  661.     jr    inrmbs
  662. ;
  663. ; move cursor down
  664. ;
  665. godn8:    mvi    a,DOWN        ;7bit code
  666. godn:    mov    c,a        ;save char
  667.     inx    h        ;binrow
  668.     mvi    a,NROW24-2    ;ck if already on bottom row
  669.     cmp    m
  670.     jc    jcxrng
  671.     call    inrsnd         ;bump row & send
  672.     rz            ;rtn if mark not yet set
  673. ;
  674. ;  hilite marked row
  675. ;
  676. godn1:    lxi    h,mark2r    ;row
  677.     inr    m        ;bump 2nd mark-col
  678.     lxi    h,currow    ;bump row
  679.     inr    m
  680.     mov    h,m
  681.     lda    mark1        ;left col
  682.     mov    l,a        ;h=row, l=col for row to hilite
  683.     call    showro        ;display 1 cut row
  684.     lxi    h,rowct        ;bump row cnt
  685. inrmbs:    inr    m        ; and exit
  686. sendbs:    mvi    a,BS        ;back up cursor
  687.     jmp    send
  688. ;
  689. .remark \====
  690. For Kaypro '84,  use bios conout.
  691.  
  692. if down:    set cur at next row, left col
  693.         send partial row
  694.         rowcnt++
  695.         BS (back up 1)
  696.  
  697. if right:    set cur at toprow, next col
  698.         send partial column
  699.         colcnt++
  700. ====\
  701. ;
  702. ; enter: H = binary row, L= binary col 
  703. ;
  704. showro:
  705. colct = .+1
  706.     mvi    a,00
  707. ;
  708. ; Fetch A chars at H=binary row, L=binary col from buffer.
  709. ; Put chars to screen, setting BLINK attribute.
  710. ;
  711. showhi:    push    psw
  712.     push    h
  713.     call    stcrshl        ;set cursor at h,l
  714.     pop    h
  715.     call    rc2off
  716.     lxi    d,buf        ;fetch from screen buffer
  717.     dad    d    
  718.     pop    psw        ;#chars
  719.     mov    b,a
  720. ..lp:    mov    a,m
  721.     inx    h
  722.     call    jjouta
  723.     djnz    ..lp
  724.     ora    a
  725.     ret
  726. ;
  727. ;========================================
  728. ;
  729. RETNCH:    
  730. ;
  731. ; Return next screen char.
  732. ;
  733. ; enter:
  734. ;    d = row, e = col
  735. ;    b = FF ==> read screen
  736. ;    c = FF ==> set bufptr
  737. ; exit:
  738. ;    A = char, CY set if good
  739. ;    DE -> row,col of next char, HL -> buf of next char
  740. ;    CY clear if out of range
  741. ;
  742.     xra    a
  743.     call    stdump
  744.     rnc
  745.     mov    a,m        ;get char
  746.     inx    h        ;bump bufptr
  747.     ret
  748. ;
  749. ;========================================
  750. ;
  751. .slist
  752. .list
  753. RETNAT:
  754. ;
  755. .ifg noatt, [
  756. ; save space with a NUL FUNCTION
  757.     xra    a        ;clear CY
  758.     ret
  759.     ]
  760.     [
  761. ;
  762. ;--------------------
  763. ; Return next screen attribute.
  764. ;
  765. ; enter:
  766. ;    d = row, e = col
  767. ;    b = FF ==> read screen
  768. ;    c = FF ==> set bufptr
  769. ; exit:
  770. ;    A = attr, CY set if good
  771. ;    DE -> row,col of next char, HL -> buf of next char
  772. ;    CY clear if out of range
  773. ;
  774.     mvi    a,0ffh
  775.     call    stdump
  776.     rnc
  777. ;
  778. ; fetch attr from buffer, advance hl every 2 
  779. ;
  780.     mov    a,m        ;fetch attr byte from buffer
  781.     bit    0,e
  782.     jrnz    ..podd        ;DE here is CHAR addr, not attr +1
  783.     rar
  784.     rar
  785.     rar
  786.     rar
  787.     jr    ..done
  788. ..podd:    inx    h        ;bump hl
  789. ..done:    ani    0fh
  790.     ret
  791. ;
  792.     ]
  793. .rlist
  794. ;--------------------
  795. ;
  796. ; ret: NC if out of range
  797. ;
  798. stdump:    sta    attflg
  799.     inr    b
  800.     jrnz    ..0
  801.     push    b
  802.     push    d
  803.     call    savpag
  804.     pop    d
  805.     pop    b
  806. ..0:    inr    c
  807.     jrnz    ..1
  808.     call    conv
  809.     rnc            ;out of range
  810. ..1:    inx    d        ;col++
  811.     mov    a,e
  812.     cpi    NCOLS
  813.     rc
  814.     mvi    e,0        ;col = 0
  815.     inr    d        ;row++
  816.     mov    a,d    
  817.     cpi    NROWS
  818.     ret            ;NC if out of range
  819. ;
  820. ; enter: d = row, e = col
  821. ; exit: hl -> buffer address, cy set
  822. ;    de preserved
  823. ;    CY clear if  error (off screen)
  824. ;
  825. conv:    mov    a,d
  826.     cpi    NROWS
  827.     jrnc    cnvbad
  828.     mov    a,e
  829.     cpi    NCOLS
  830.     jrnc    cnvbad
  831.     lxi    h,buf
  832.     mov    a,d
  833.     lxi    b,NCOLS        ;row*(cols per row)
  834.     inr    a
  835. ..lp:    dcr    a
  836.     jrz    ..2
  837.     dad    b
  838.     jr    ..lp
  839. ..2:    mvi    d,0        ;+ col #
  840.     dad    d
  841. attflg    = .+1
  842.     mvi    a,00
  843.     ora    a
  844.     stc
  845.     rz
  846.     lxi    b,SCRSIZ    ;bump ptr to attributes
  847.     dad    b
  848.     stc
  849.     ret
  850. cnvbad:    xra    a
  851.     ret
  852. ;
  853. ;========================================
  854. ;
  855. SAVPAG:
  856. ;
  857. ; Save screen to buffer.
  858. ;
  859.     xra    a
  860.     call    iscr
  861.     call    crs2off        ;find screen cursor
  862.     shld    bcursor
  863.     push    h
  864.     push    d
  865.     call    off2cr
  866.     sded    bincol        ;save binary col/row
  867.     pop    d
  868.     pop    h
  869. ;
  870. ;--------------------
  871. ;
  872. doscr:    lxi    b,SCRSIZ
  873.     push    b        ;save count
  874.     push    d        ;save addr
  875. ;
  876. ; first the characters
  877. ;
  878. ..0:    call    datadr        ;set  addr
  879.     call    vch        ;r/w char
  880.     inx    d
  881.     dcx    b
  882.     mov    a,b
  883.     ora    c
  884.     jrnz    ..0
  885.     pop    d        ;addr
  886.     pop    b        ;count
  887. ;
  888. ; now the attributes
  889. ;
  890.     inx    d        ;attributes lead 1 byte
  891. ..2:    call    attadr
  892.     call    vat
  893.     inx    d
  894.     dcx    b
  895.     mov    a,b
  896.     ora    c
  897.     jrnz    ..2
  898.     ret
  899. ;
  900. ;========================================
  901. ;
  902. RESPAG:
  903. ;
  904. ; Restore saved screen from buffer.
  905. ;
  906. ; First, set any attribute so we undo the effect of a clearscreen.
  907. ; This ensures that the restored screen, if it has
  908. ; attributes set, will get cleared by a clearscreen or ^X or whatever.
  909. ;
  910. ;put1att:
  911.     call    svcrsor
  912.     lxi    h,Zoneat
  913.     call    jjputs
  914.     call    cursbak
  915. ;
  916.     mvi    a,0ffh
  917.     call    iscr
  918.     call    gethome        ;get current top of screen
  919.     xchg            ; to de
  920.     call    doscr        ;put buffer to screen
  921.     lhld    bcursor        ;and set the cursor
  922. ;
  923. ; Set cursor on screen by direct cursor addressing.
  924. ; enter: HL = cursor offset relative to 0000
  925. ;    
  926. stcrs:    call    off2cr        ;convert from offset to ascii col/row
  927. stcoro:    shld    colrow        ;put ascii col/row into string
  928.     lxi    h,Zcurs        ;send set-cursor string
  929.     jmp    jjputs
  930. ;
  931. ; Set cursor on screen.
  932. ; enter: H=binary row, L = binary col
  933. ;
  934. stcrshl:call    rc2off
  935.     jr    stcrs
  936. ;
  937. ;--------------------
  938. ;
  939. ; CONVERSION ROUTINES
  940. ;
  941. ; Get current cursor position to H=binary row, L=binary col
  942. ;
  943. crs2hl:    call    crs2off        ;get cursor by ...84 method
  944.     call    off2cr        ;returns binary in de
  945.     xchg
  946.     ret
  947. ;
  948. ; convert H=binary row, L=binary col to hl= offset
  949. ; (hl =  row*NCOLS + col)
  950. ; uses bc,de,hl
  951. ;
  952. rc2off:    mov    b,h        ;b=row
  953.     mov    c,l        ;c=col
  954.     lxi    h,0
  955.     inr    b
  956.     lxi    d,NCOLS
  957.     jr    ..bot
  958. ..0:    dad    d        ;rows*NCOLS
  959. ..bot:    djnz    ..0
  960.     dad    b        ;+ col
  961.     ret
  962. ;
  963. ; get raw relative cursor to HL
  964. ;
  965. crs2off:
  966.     call    gethome        ;get top of scr addr
  967.     xchg            ;keep in de
  968.     call    gcur        ;get cursor addr
  969. ;
  970. mod800:    ora    a
  971.     dsbc    d
  972. mod8ck:    rnc
  973.     lxi    d,800h
  974.     dad    d
  975.     ret
  976. ;
  977. ;--------------------
  978. ;initialize for screen
  979. ;
  980. iscr:    sta    putflg        ;0=save, 0ff=restore
  981.     lxi    h,buf        ;init char ptr
  982.     jr    shcptr
  983. ;
  984. ;
  985. ; read/write 1 char from video controller, to/from buffer
  986. ; status must already be checked and ok
  987. ;
  988. vch:    lhld    cptr
  989.     lda    putflg
  990.     ora    a
  991.     jrnz    vchput
  992.     in    vcdata        ;get char from screen
  993.     mov    m,a        ; & put into buffer
  994. inxcpt:    inx    h
  995. shcptr:    shld    cptr
  996.     ret
  997. ;
  998. vchput:    mov    a,m        ;fetch char from buffer
  999.     call    inxcpt
  1000.     out    vcdata        ; & put to screen
  1001.     ret
  1002. ;
  1003. ; read/write 1 attribute nybble to/from buffer
  1004. ; stored: upper nybble = 00, lower nybble = 01, upper = 02,...
  1005. ;
  1006. cptr = .+ 1
  1007. vat:    lxi    h,0000        ;char ptr
  1008. ;
  1009. putflg = .+1
  1010.     mvi    a,00        ;NZ to restore(put) screen from buf
  1011.     ora    a
  1012.     jrnz    ..put
  1013. ;
  1014. ; get attribute from screen, store in buffer
  1015. ;
  1016. ..get:    bit    0,e        ;test for even col (de leads 1 )
  1017.     jrz    ..odd
  1018.     rld            ;a->lo, lo->hi
  1019.     in    vcdata        ;get char from screen
  1020.     rrd            ;a->hi, hi back to lo    
  1021.     ret
  1022. ..odd:    rrd            ;do low nybble, a->hi, hi->lo
  1023.     in    vcdata
  1024.     rld
  1025.     jr    inxcpt        ;and bump ptr
  1026. ;
  1027. ; fetch attr from buffer, advance hl every 2, put to screen
  1028. ;
  1029. ..put:    mov    a,m        ;fetch attr byte from buffer
  1030.     bit    0,e
  1031.     jrz    ..podd        ;DE leads 1 
  1032.     rar
  1033.     rar
  1034.     rar
  1035.     rar
  1036.     jr    ..done
  1037. ..podd:    inx    h        ;bump hl
  1038.     shld    cptr
  1039. ..done:    ani    0fh
  1040.     out    vcdata        ; & put to screen
  1041.     ret
  1042. ;
  1043. ;
  1044. gethome:call    svcrsor        ;save cursor in bios rom
  1045.     mvi    a,HOMEC        ;home it
  1046.     call    jjouta
  1047.     call    gcur
  1048. ;
  1049. cursbak:push    h
  1050.     lxi    h,Zrestc    ;restore bios copy of cursor addr
  1051.     call    jjputs
  1052.     pop    h        ;ret home addr in hl
  1053. ;
  1054. ; v 1.4a FIX turborom v2.6.  Restore cursor calls ldcursor
  1055. ; w/o waiting for good status. The next controller read cause
  1056. ; cursor-type byte to be written to screen.
  1057. ;---
  1058. fixtrb:    push    h
  1059.     lxi    d,SCRSIZ
  1060.     dad    d        ;point at 1st char in gap
  1061.     xchg
  1062.     call    datadr        ;set  addr
  1063.     in    vcdata        ;read the controller to flush
  1064.     pop    h        ;the cursor-type byte.
  1065. ;---
  1066.     ret
  1067. ;
  1068. ; HL = raw cursor read from video controller
  1069. ; uses h,l,a
  1070. ;
  1071. gcur:    mvi    a,curcmd
  1072.     out    vccmd        ;to get scrolling address
  1073.     call    vwait        ; may be unnecessary ??
  1074.     in    vcrdat
  1075.     mov    h,a
  1076.     mvi    a,curcmd+1    ;get low byte
  1077.     out    vccmd
  1078.     call    vwait
  1079.     in    vcrdat
  1080.     mov    l,a
  1081.     ret
  1082. ;
  1083. ;--------------------
  1084. ;
  1085. ; wait, set DE attribute addr, stroke
  1086. ;
  1087. attadr:    mov    a,d        ;qualify D for attribute space
  1088.     ani    07h
  1089.     ori    08h
  1090.     jr    xadr1
  1091. ;
  1092. ; wait, set DE data address, stroke
  1093. ;
  1094. datadr:    mov    a,d        ;qualify DE for data space
  1095.     ani    07h
  1096. xadr1:    mov    d,a
  1097. xadr2:    in    vcstat
  1098.     ral
  1099.     jrnc    xadr2
  1100. ;
  1101. ;send DE to reg A, A+1, stroke & wait
  1102. ;
  1103. ;setrw:
  1104.     mvi    a,hiadd
  1105.     out    vccmd
  1106.     mov    a,d
  1107.     out    vcrdat
  1108.     mvi    a,loadd
  1109.     out    vccmd
  1110.     mov    a,e
  1111.     out    vcrdat
  1112.     mvi    a,strcmd    ;stroke chip
  1113.     out    vccmd
  1114. vwait:    in    vcstat
  1115.     ral
  1116.     jrnc    vwait
  1117.     ret
  1118.  
  1119. ;----------------------------------------
  1120. ;
  1121. ; DATA AREA
  1122.  
  1123. bincol:    db    0    ;pair
  1124. binrow:    db    0
  1125. ;
  1126. curcol:    db    0
  1127. currow:    db    0
  1128. ;
  1129. Zrub:    db    BS,SPACE,BS+80H    ;rub-out previous char
  1130. ;
  1131. ;****************************************
  1132. ;
  1133. ;  TERMINAL-SPECIFIC data
  1134. ;
  1135. svcrsor:lxi    h,Zsavec    ;save cursor & push state in bios rom
  1136.     jr    jputs
  1137. ;
  1138. ; turn on normal video
  1139. ;
  1140. normal:    lxi    h,Znorm
  1141. jputs:    call    jjputs
  1142.     ora    a        ;clr CY
  1143.     ret
  1144. ;
  1145. ; turn on reverse video
  1146. ;
  1147. reverse:lxi    h,Zrev
  1148.     jr    jputs
  1149. ;
  1150.  
  1151. ; Kaypro '84 video strings
  1152. ;
  1153. Zsavec:    .ascis    [1bh]'B6'    ;save cursor location
  1154. Zrestc:    .ascis    [1bh]'C6'    ;restore it
  1155. ;
  1156. Zcurs:    .ascii    [1bh]'='    ;set cursor to
  1157. colrow:    db    SPACE,SPACE    ; row,col - modified in-line
  1158.     db    NUL        ;must have following NUL
  1159. ;
  1160. Zrev:    .ascii    [1bh]'B0'    ; reverse video
  1161.     .ascis    [1bh]'B1'    ; with 1/2 intensity
  1162. Znorm:    .ascii    [1bh]'C0'    ; normal video
  1163.     .ascis    [1bh]'C1'    ; with full intensity
  1164. ;
  1165. ; !! this causes momentary flashing, can we do it elsewhere?
  1166. ;
  1167. Zoneat:    .ascii    [1bh]'B3 '
  1168.     .ascis    [1bh]'C3'
  1169. ;
  1170. .ifg DEBUG, [ 
  1171. Zclr:    db    1Ah,NUL        ;kaypro
  1172.     ]
  1173. ;
  1174. ;
  1175. ;================================
  1176. ;
  1177. ; JOTPAD BANNER - just 2 lines' worth
  1178. ;
  1179. ; 1. Clear screen.
  1180. ; 2. Remind user of usage, to extent space is available.
  1181. ;    The editing keys are those supported by the terminal itself.
  1182. ;
  1183. Zbanner:
  1184.     db    1ah        ;clear screen KAYPRO-SPECIFIC
  1185. ;
  1186. .ascii    'JOT: <SUSPEND>=exit, ^Paste'
  1187.     db    CR,LF
  1188. .ascii    'ESC E/ESC R=ins/del line'
  1189.  
  1190. ; NO ROOM FOR THIS !
  1191. ; if turborom-->
  1192. ;.ascii    'Cntl-A = insert char.  Cntl-B = delete char.         '
  1193. ;
  1194. Zcrlf:    db    CR,LF+80h
  1195.  
  1196. ;
  1197. .slist
  1198. .list
  1199. codlen = .-start        ;length of code
  1200. .rlist
  1201. ;
  1202. ;++++++++++++++++++++++++++++++
  1203. .remark \==
  1204. Debugging stragegy:
  1205.     Assemble screendriver at 100h.
  1206.     Load with Z80 debugger.
  1207.     Clear ram buffers.
  1208.     Set breakpoints as needed.
  1209.     Call these test routines and inspect buffers.
  1210. ==\
  1211.  
  1212. .ifg DEBUG, [
  1213. dbg0 = .
  1214. ;
  1215. ; these emulate the external BGii routines
  1216. ; using ram buffers for debugging
  1217. ;
  1218. bwrch:    push    h
  1219.     lhld    dbgptr        ;put to debug cut buffer
  1220.     mov    m,c
  1221.     inx    h
  1222.     shld    dbgptr
  1223.     pop    h
  1224.     ret
  1225. ;
  1226. bflush:    ret
  1227. ;
  1228.  
  1229. ;bios display-a-string
  1230. ;    nul/8-bit terminated string at hl
  1231. ;    preserves bc,de,hl
  1232. ;
  1233. puts:    push    h    ;save hl, outch save bc,de
  1234. ..0:    mov    a,m
  1235.     rlc
  1236.     srlr    a    ;shift right logical (register) A
  1237.     inx    h
  1238.     jrz    ..1
  1239.     push    psw
  1240.     call    outch
  1241.     pop    psw
  1242.     jrnc    ..0
  1243. ..1:    pop    h
  1244.     ret
  1245. ;
  1246. ; char in A to conout, preserve bc,de,hl 
  1247. ;
  1248.  
  1249. outch:    push    b
  1250.     push    d
  1251.     push    h
  1252.     mov    c,a
  1253.     call    conout
  1254.     pop    h
  1255.     pop    d
  1256.     pop    b
  1257.     ret
  1258. ;
  1259. ; Various routines for debugging in ram.
  1260. ;
  1261. TSTACK = 05000h        ;test stack, above bank-switching
  1262.  
  1263. tdump:    lxi    b,0ffffh    ;fetch scr, set ptr
  1264.     lxi    d,0        ;from row 0,col 0
  1265.     call    dmpchr
  1266. ;
  1267. tdump2:    lxi    b,0
  1268.     call    dmpchr
  1269. ;
  1270. tdump3:    lxi    d,100h + 0
  1271.     lxi    b,00ffh
  1272.     call    dmpchr
  1273. ;
  1274. tdump4:    lxi    d,3000h        ;out of range test
  1275.     lxi    b,00ffh
  1276.     call    dmpchr
  1277.     rst    7
  1278. ;
  1279. ;
  1280. clear:    lxi    h,Zclr        ;clear screen
  1281.     call    jjputs
  1282.     rst    7
  1283. ;
  1284. flood:    lxi    h,Zflood    ;write to screen
  1285.     call    jjputs
  1286.     rst    7
  1287. Zflood:    .ascii    '=======TESTING======='
  1288.     db    0
  1289. ;
  1290. tsave:    lxi    sp,TSTACK    ;save screen
  1291.     call    savscr
  1292.     rst    7
  1293.  
  1294. trest:    lxi    sp,TSTACK    ;restore screen
  1295.     call    resscr
  1296.     rst    7
  1297.  
  1298. tmark:    lxi    sp,TSTACK    ;set a mark
  1299.     call    savscr
  1300.     call    sttop        ;so debugger doesn't scroll screen
  1301. ..0:    call    conin
  1302.     call    setmrk
  1303.     jnc    ..0
  1304. ;    rst    7
  1305.     nop
  1306. ;
  1307. tcut:    lxi    h,cutbuf        ;clear buffer
  1308.     mvi    m,0
  1309.     lxi    d,cutbuf+1
  1310.     lxi    b,2*80h
  1311.     ldir
  1312.     call    cutrg            ;cut region
  1313.     call    setbot            ;put cursor out of way
  1314.     rst    7
  1315.  
  1316. ; place cursor nerar bottom or top
  1317. ;
  1318. setbot:    lxi    h,100h*(20h+18) +20h
  1319.     jr    sttop1
  1320. sttop:    lxi    h,2020h
  1321. sttop1:    shld    colrow
  1322.     lxi    h,Zcurs        ;send set-cursor string
  1323.     jmp    jjputs
  1324. ;
  1325. dbgptr:    dw    0
  1326. .slist
  1327. .list
  1328. dbglen = . - dbg0
  1329. .rlist
  1330.     ]
  1331. ;++++++++++++++++++++++++++++++
  1332. ;
  1333. .list
  1334.  
  1335. ; SCREEN BUFFER STRUCTURE
  1336. ;
  1337. ; The rest of the 4K block is available
  1338. ; for the screen image and other data.
  1339.  
  1340. xbreq    = 2 + NROWS*NCOLS + (NROWS*NCOLS)/2    ;required space
  1341. ;
  1342.  
  1343. .ifg    DEBUG, [
  1344. ;
  1345. ; put buffer on even byte ( for attributes)
  1346. bstart    =    start + 800h    ;make some room
  1347.     ]
  1348. ;
  1349.     [
  1350. ; put buffer at end of 4K area, to just fit
  1351. bstart    =    (start + 400h) + (3*400h-xbreq)
  1352.  
  1353. short =    start+codlen-bstart
  1354. xfree = - short
  1355.  
  1356. .ifg (short), [
  1357.     .prntx    '[07]Code overflows buffer!'
  1358.     ]
  1359.  
  1360.     ]
  1361.  
  1362. ;
  1363. ; addresses:
  1364. ;
  1365. bcursor =    bstart        ;cursor location in saved screen
  1366. buf    =    bcursor+2    ;start of screen buffer
  1367. ;
  1368. ;buffer uses (25 lines x 80 chars) + 1/2 that for attributes
  1369. ;
  1370. bufend    =    buf + 25*80 + (25*80)/2    
  1371.                     
  1372. ;
  1373. .ifg DEBUG, [
  1374. ;
  1375. ; put cutbuffer in ram for debugging
  1376. ;
  1377. datcut    =    bstart+10h+3*400h
  1378. cutbuf    =    datcut
  1379.     ]
  1380.  
  1381. .xlist
  1382. .remark \======================
  1383.  
  1384. This routine is needed to calculate locations of mark1, mark2
  1385. if cursor movements are not restricted to DOWN and RIGHT after
  1386. 1st mark is set.  Not used in current implementation.
  1387. ; Code for minimum calc::
  1388. ;
  1389. ; stored row, col
  1390. ; set    mark1(row,col) = min row,min col
  1391. ;    mark2(row,col) = max row,max col
  1392. ;    ctcols = #cols, ctrows = # rows
  1393. ;
  1394. corners:lxi    d,mark1
  1395.     lxi    h,mark2
  1396.     ldax    d        ;col 1 = min(col1,col2)
  1397.     mov    b,m
  1398.     cmp    b
  1399.     jrc    ..1        ;cy if 1 < 2
  1400.     mov    m,a        ;exchange
  1401.     mov    a,b
  1402.     stax    d
  1403. ..1:    inx    h        ;row 1...
  1404.     inx    d
  1405.     ldax    d        ;row 1 = min(row1,row2)
  1406.     mov    b,m
  1407.     cmp    b
  1408.     jrc    ..2
  1409.     mov    m,a
  1410.     mov    a,b
  1411.     stax    d
  1412. ..2:    ldax    d        ;row1
  1413.     sub    m        ; - row2
  1414.     cma            ; gives (row2 - row1 - 1)
  1415.     inr    a
  1416.     inr    a
  1417.     sta    ctrows
  1418.     dcx    h
  1419.     dcx    d
  1420.     ldax    d
  1421.     sub    m
  1422.     cma
  1423.     inr    a
  1424.     inr    a
  1425.     sta    ctcols
  1426.     ret
  1427. ;
  1428. =========================\
  1429.  
  1430.     .end    jjcons
  1431. 0 + (25*80)/2    
  1432.                     
  1433. ;
  1434. .ifg DEBUG, [
  1435. ;
  1436. ; put c