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 / BGIIDRV.LBR / H19SCRND.ZQ0 / H19SCRND.Z80
Text File  |  2000-06-30  |  25KB  |  1,167 lines

  1. ;    Screen driver for Heath-19
  2. ;    by Harold F. Bower and Bridger Mitchell
  3. ;    26 September 1986
  4. ;
  5.     .title    'H19SCRN bg ii Screen Driver'
  6. ;
  7. ;    M80 or ZAS Z80 assembler.
  8. ;
  9. FALSE    equ    0
  10. TRUE    equ    NOT FALSE
  11. ;
  12. ;.....
  13. ;Particular features of    Heath-19 code:
  14. ;
  15. ; H19 sends a stream consisting of successive chars, with ESC sequences
  16. ; preceeding any change in reverse/normal video and graphics/normal
  17. ; character set.  Several upgrade modes support a "native" mode with
  18. ; the 2-character ESC - char sequence replaced by 1 8-bit character.
  19. ; This code automatically detects and supports both modes FROM the
  20. ; terminal, and always sends in 7-bit mode TO the terminal, for complete
  21. ; compatibility.
  22. ;
  23. Consta    equ    0
  24. Conin    equ    0
  25. Conout    equ    0
  26. Outch    equ    0
  27. Puts    equ    0
  28. Bwrch    equ    0
  29. Bflush    equ    0
  30. ;
  31. ; ascii    equates
  32. ;
  33. BELL    EQU    07H
  34. BS    EQU    08H
  35. CR    EQU    0DH
  36. LF    EQU    0AH
  37. ESC    EQU    1BH
  38. SPACE    EQU    20H
  39. DEL    EQU    7FH
  40. ;
  41. ; CUT command characters
  42. ;
  43. HOME    EQU    'H'        ;home the cursor
  44. MARK    EQU    'X'        ;set a mark
  45. PASTE    EQU    'P'-40H        ;paste region at cursor
  46. CANCEL    EQU    'C'-40H        ;cancel cut command
  47. ;
  48. ; TERMINAL-SPECIFIC EQUATES
  49. ;
  50. ;
  51. ; Cursor movement controls for Heath-19/89
  52. ;-----------------------------------------
  53. ;=== WordStar-like
  54. ;
  55. WSLFT    EQU    'S'-40H
  56. WSRIT    EQU    'D'-40H
  57. WSUP    EQU    'E'-40H
  58. WSDWN    EQU    'X'-40H
  59. WSINS    EQU    'V'-40H
  60. WSDEL    EQU    'Y'-40H
  61. ;
  62. ;=== ESCape sequence arguments
  63. ;
  64. LEFT    EQU    'D'
  65. RIGHT    EQU    'C'
  66. UP    EQU    'A'
  67. DOWN    EQU    'B'
  68. INSERT    EQU    'L'
  69. DELETE    EQU    'M'
  70. ;
  71. ;
  72. ; Heath-19 screen parameters
  73. ;
  74. NCOLS    EQU    80
  75. NROWS    EQU    25
  76. NROW24    EQU    24        ;# rows    excluding status line
  77. ;
  78. SCRSIZ    EQU    NCOLS*NROWS
  79. CRBIAS    equ    20H        ; Bias for cursor positioning
  80. ;
  81. ; Heath-19 Escape argument characters
  82. ;
  83. CLRSCR    equ    'E'        ; Clear screen & Home cursor
  84. GRON    equ    'F'        ; Graphics mode on
  85. GROFF    equ    'G'        ; Graphics mode off
  86. REVON    equ    'p'        ; Reverse video mode on
  87. REVOF    equ    'q'        ; Reverse video mode off
  88. SNDPAG    equ    '#'        ; Send lines 1-24 from screen
  89. SND25    equ    ']'        ; Send line 25 from screen
  90. SNDCUR    equ    'n'        ; Send Cursor position as <ESC Y r c>
  91. ;
  92. ; Flag bits in status register
  93. ;
  94. TOSCR$    equ    0        ; Send to screen
  95. GRAPH$    equ    1        ; Graphics sequence active
  96. REV$    equ    2        ; Reverse video sequence active
  97. ESCMOD    equ    3        ; ESCape sequence
  98. ;
  99. ;=========================
  100. ;
  101.     org    3F80H        ; Module name sector
  102. ;
  103. ;
  104.     db    'Heath 19/89  26 Sept 86',0
  105. ;
  106. ;-------------------------
  107. ;
  108.     org    4000H
  109. ;
  110. ;------------------------------------------------------------
  111. ;
  112. Start:
  113. ;
  114. ; Start    of Screen Module.  Assemble to run at 4000h.
  115. ;
  116. ;***** MODULE ENTRY HEADER
  117. ;
  118. ; EXTERNAL ADDRESSES, supplied by loader
  119. ;
  120. JJcons:    jp    Consta        ; BIOS constat
  121. JJconi:    jp    Conin        ; BIOS conin
  122. JJouta:    jp    Outch        ; A to conout, preserving BC,DE,HL
  123. JJputs:    jp    Puts        ; HL-string to conout, NUL/bit-7 term.
  124.                 ;   preserving BC,DE,HL
  125. JJbrdc:    jp    0000        ; Buffered read char from cut-swp
  126. JJbwrc:    jp    Bwrch        ; Buffered write char to cut-swp
  127. JJbflu:    jp    Bflush        ; Flush (write) buffer
  128. ;
  129. ; INTERNAL ENTRY POINTS
  130. ;
  131. Savscr:    jp    Savpag        ; Save screen 
  132. Resscr:    jp    Respag        ; Restore saved screen
  133. Lastnb:    jp    Lstnbl        ; Last non-blank char in rows 1-24
  134. Dmpchr:    jp    Retnch        ; Return next screen char
  135. Dmpcur:    jp    Retncu        ; Return buffer cursor
  136. Dmpatt:    jp    Retnat        ; Return next screen attribute
  137. Setmrk:    jp    Stmrks        ; Set region marks, move cursor
  138. Cutrg:    jp    Docut        ; Cut region
  139. Pastrg:    jp    Dopaste        ; Paste region
  140. Ininpd:    jp    Ininot        ; Initialize jotpad
  141. Putnpd:    jp    Putnch        ; Put char to jotpad
  142. ;
  143. ;========================================
  144. ;
  145. Ininot:                ; << Generic >>
  146. ;
  147. ; Initiate Jotpad - clear screen, print banner.
  148. ;
  149.     ld    hl,zbanner
  150.     jr    JJputs
  151. ;
  152. ;========================================
  153. ;
  154. Retncu:                ; << Generic >>
  155. ;
  156. ;  Return buffer cursor as row/col.
  157. ;
  158. ; RET: D = binary row, E= binary col
  159. ;      L =  ascii row, H = ascii col (for shld ...)
  160. ;
  161.     ld    hl,(bcursor)
  162. ;
  163. ; Convert offset to col/row.
  164. ; EXIT:    D = binary row,    E = binary col
  165. ;    H = ascii col,    L = ascii row        <-- NOTE ORDER
  166. ;
  167. Off2cr:    ld    b,0        ; Convert to row,col
  168.     ld    de,-NCOLS
  169. Off2c1:    add    hl,de
  170.     jr    nc,Off2c2
  171.     inc    b        ; Increment row count
  172.     jr    Off2c1
  173. Off2c2:    ld    de,NCOLS
  174.     add    hl,de
  175.     ld    a,l        ; Col
  176.     ld    e,a        ; Binary col in E
  177.     ld    d,b        ; Binary row in D
  178.     add    a,CRBIAS    ;  + bias
  179.     ld    h,a        ; H = ascii col
  180.     ld    a,b        ; Row
  181.     add    a,CRBIAS    ;  + bias
  182.     ld    l,a        ; L = ascii row
  183.     ret
  184. ;
  185. ;========================================
  186. ;
  187. Dopaste:            ; <<Generic >>
  188. ;
  189. ; Paste    the last-cut region onto active    screen at the current cursor.
  190. ;   For H-19, only use lines 1-24 due to scroll problem in line 25,
  191. ;   and to not paste to the last character position in line 24 for the
  192. ;   same reason.
  193. ;
  194. ; 1. Get previously-cut    region from external routine
  195. ; 2. Send chars    to screen, avoiding boundary overflows.    
  196. ;
  197. ; 'savpag' not needed if terminal supports 'send cursor address'
  198. ;
  199. ;    call    Savpag        ; Get current screen,
  200.                 ; in order to find cursor
  201.     ld    b,4        ; Read 4 data bytes
  202. Dopas0:    push    bc
  203.     call    JJbrdc
  204.     pop    bc
  205.     djnz    Dopas0
  206. ;
  207.     ld    b,a        ; 4th byte is # rows
  208.     push    bc
  209.     call    Crs2hl        ; current cursor's row/col to hl
  210.     pop    bc
  211. ;
  212. ;  Loop over rows
  213. ;
  214. Prowlp:    push    bc
  215.     push    hl
  216.     ld    e,l        ; E = col no.
  217.     push    de
  218.     call    Stcrshl        ; Set cursor at H,L
  219. Pcollp:    call    JJbrdc        ; Read char from cut-swp
  220.     cp    CR
  221.     jr    z,Prend
  222.     ld    c,a        ; Save char
  223.     pop    de        ; Check for off screen
  224.     ld    a,e
  225.     cp    NCOLS
  226.     inc    e
  227.     push    de        ; row/col to stack
  228.     call    c,Sendc        ; to conout, unless off edge
  229.     jr    Pcollp
  230. ;
  231. Prend:    pop    de        ; Clear row/col
  232.     pop    hl
  233.     pop    bc
  234.     inc    h        ; Bump row
  235.     ld    a,h        ; Check for off bottom of screen
  236.     cp    NROW24        ; Use NROWS if 25th line scrolls
  237.     jr    nc,Pxit
  238.     djnz    Prowlp
  239. Pxit:    xor    a
  240.     ret
  241. ;
  242. ;========================================
  243. ;
  244. Docut:                ; << Generic >>
  245. ;
  246. ; Cut rectangular region defined by keypresses.
  247. ; 1. Parse keypresses to move cursor and mark corners.
  248. ;    Highlight region as cursor is moved.
  249. ;
  250. ;    NOTE: The last char in row 24 of the Heath-19 is not
  251. ;          marked due to scroll effects if line wrap is ON.
  252. ;
  253. ; 2. Send the marked region, row-wise to external routine.
  254. ;    Append CR after    each row.
  255. ;
  256. ; Data structure is:
  257. ;    size (word)
  258. ;    # columns (byte)
  259. ;    # rows (byte)
  260. ;    row 1
  261. ;    CR
  262. ;    row 2
  263. ;    CR
  264. ;    ....
  265. ;
  266.     xor    a
  267.     ld    (mrkcnt),a    ;init for next time
  268. ;
  269. ; Set ctcols = # cols, ctrows = # rows
  270. ; (assumes mark2 is SE of mark1)
  271. ;
  272. Cornrs:    ld    de,(mark1)
  273.     ld    hl,(mark2)
  274.     ld    a,h        ; # rows = 1 + mark2row - mark1row    
  275.     inc    a
  276.     sub    d
  277.     ld    h,a
  278.     ld    a,l        ; # cols = 1 + mark2col -mark1col
  279.     inc    a
  280.     sub    e
  281.     ld    l,a
  282.     ld    (ctcols),hl
  283. ;
  284. ; Cut rectangle [mark1...mark2] & copy    to buffer
  285. ; Append CR at end of each row
  286. ;
  287.     ex    de,hl
  288.     push    hl        ; Mark1
  289.     call    Wrpara        ; Write parameters
  290.     pop    hl        ; Mark1
  291.     call    Rc2off        ; Convert to screen addr
  292.     ld    a,(ctrows)    ; Get # rows
  293.     ld    b,a
  294. ;
  295. ; write    the cut    region to external buffer
  296. ;
  297. DCrwlp:    push    bc        ; (+1
  298.     push    hl        ; (+2
  299.     ld    de,buf        ; Fetch from screen buffer
  300.     add    hl,de
  301. ;
  302. ; write    1 row of cut region to external    buffer
  303. ;
  304.     ld    a,(ctcols)
  305.     ld    b,a        ; B = # cols
  306.     call    Bwrthl
  307.     ld    c,CR        ; Append CR to each row
  308.     call    JJbwrc
  309. ;
  310.     pop    hl        ; (+1
  311.     pop    bc        ; (+0
  312.     ld    de,NCOLS    ; Bump to next row
  313.     add    hl,de
  314.     djnz    DCrwlp        ;  and loop
  315.     jp    JJbflu        ; Flush the write buffer
  316. ;
  317. ;  Write parameters: size, # cols, # rows to swp file
  318. ;    DE contains CTCOLS on entry
  319. ;
  320. Wrpara:    ld    b,d        ; # rows
  321.     ld    d,0
  322.     inc    e        ; +1 for CR
  323.     ld    hl,0        ; accum.
  324. Wrpar0:    add    hl,de
  325.     djnz    Wrpar0
  326.     ld    (ctsize),hl
  327.     ld    b,4        ; Write 4 bytes of parameters
  328.     ld    hl,ctsize
  329. ;
  330. ;  Buffered write B chars at HL
  331. ;
  332. Bwrthl:    push    bc
  333.     push    hl
  334.     ld    c,(hl)
  335.     call    JJbwrc
  336.     pop    hl
  337.     pop    bc
  338.     inc    hl
  339.     djnz    Bwrthl
  340.     ret
  341. ;
  342. ;========================================
  343. ;
  344. Lstnbl:                ; << Generic >>
  345. ;
  346. ; Find last non-blank line (1-24 only) in current scr buffer.
  347. ;   Graphics characters are considered blanks.  8-bit values
  348. ;   (reverse video) are masked to see if they are valid chars. 
  349. ; If B = 0FF, save screen first.
  350. ;
  351. ; RETURN: H = row, L = col of last non-blank char in rows 1-24
  352. ;
  353.     inc    b
  354.     call    z,Savpag
  355.     ld    bc,NROW24*100H+NCOLS    ; B=# rows, C=# cols
  356.     ld    de,buf
  357.     ld    hl,0
  358. Lstlp:    ld    a,(de)
  359.     and    7FH        ; Turn off any reverse video
  360.     cp    SPACE+1        ; Don't count cntl chars or SPACE
  361.     jr    c,Lst1
  362.     cp    DEL        ;  or DEL or graphics 8-bit
  363.     jr    nc,Lst1
  364.     ld    (savrc),hl
  365. Lst1:    inc    de
  366.     inc    l
  367.     dec    c
  368.     jr    nz,Lstlp    ; Loop over cols
  369.     inc    h
  370.     ld    l,c        ; 0
  371.     ld    c,NCOLS
  372.     djnz    Lstlp        ; Loop over rows
  373. savrc equ  $+1
  374.     ld    hl,0000        ; HL = last non-blank
  375.     ret        
  376. ;
  377. ;------------- Generic Support Routines --------------
  378. ;
  379. Xring:    ld    c,BELL
  380. ;
  381. ; send C to screen, exit Z, no CY
  382. ;
  383. Sendc:    ld    a,c
  384.  
  385. ; send A to screen, exit Z, no CY
  386. ; (this    will scroll, however!)
  387. ;
  388. Send:    call    JJouta
  389.     xor    a        ; Z, no CY
  390.     ret
  391. ;
  392. ;============================================
  393. ;  E N D    O F    G E N E R I C    C O D E
  394. ;============================================
  395. ;
  396. Putnch:                ; << Specific >>
  397. ;        (Was generic til cursor controls added)
  398. ;
  399. ; Put char in A     to jotpad (screen)
  400. ; Convert CR to    CRLF, DEL to rubout, 8-bit codes
  401. ;  to ESC-n sequences.
  402. ;
  403.     cp    CR
  404.     ld    hl,zcrlf    ; Convert CR to CR,LF
  405.     jp    z,JJputs
  406.     cp    DEL
  407.     ld    hl,zrub
  408.     jp    z,JJputs
  409.     bit    7,a        ; 8-bit code?
  410.     jr    nz,Wrt8th
  411. ;
  412.     cp    WSLFT        ; Use WS-like commands?
  413.     jr    z,Wrtlef
  414.     cp    WSRIT
  415.     jr    z,Wrtrit
  416.     cp    WSUP
  417.     jr    z,Wrtup
  418.     cp    WSDWN
  419.     jr    z,Wrtdwn
  420.     cp    WSDEL
  421.     jr    z,Wrtdel
  422.     cp    WSINS
  423.     jp    nz,JJouta
  424. ;            ...fall thru
  425.     ld    a,'L'        ; ESC code for Insert line
  426.     jr    DoWrt
  427. ;
  428. Wrtlef:    ld    a,'D'        ; ESC code for Left curs
  429.     jr    DoWrt
  430. ;
  431. Wrtrit:    ld    a,'C'        ; ESC code for Right curs
  432.     jr    DoWrt
  433. ;
  434. Wrtdwn:    ld    a,'B'        ; ESC code for Down curs
  435.     jr    DoWrt
  436. ;
  437. Wrtup:    ld    a,'A'        ; ESC code for Up curs
  438.     jr    DoWrt
  439. ;
  440. Wrtdel:    ld    a,'M'        ; ESC code for Delete line
  441. ;            ...and fall thru...
  442. Wrt8th:    and    7FH        ; Mask 8th bit and send as ESC-n
  443. DoWrt:    jp    Jptesc
  444. ;
  445. ;===========================================
  446. ;
  447. Stmrks:                ; << Specific >>
  448. ;
  449. ; Move cursor and set marks. Return CY clear until exit.
  450. ;    NOTE:    For Heath-19, the last character in line 24 is
  451. ;        NOT highlighted since that causes the entire
  452. ;        screen to scroll if Line Wrap is ON.
  453. ;
  454. ; 1. move cursor, until:
  455. ; 2. 'X' = set 1st mark
  456. ;    turn on    hiliting, set mark, keep cursor    at mark
  457. ; 3. move cursor right/down only
  458. ; 4. 'X' = set 2nd mark
  459. ;    turn off hiliting, set 2nd mark
  460. ;    exit CY    (done)
  461. ; 5. cntl-C = CANCEL. 
  462. ;    turn off hilighting, set CY, exit
  463. ;
  464. ;
  465.     cp    ESC
  466.     jr    nz,Stmrk0    ; Continue if not Escape
  467.     ld    a,0FFH        ; ..else set flag
  468.     ld    (mrkesc),a
  469.     xor    a        ; Return for next char
  470.     ret
  471. ;
  472. Stmrk0:    bit    7,a        ; Is it an 8-bit command?
  473.     jr    nz,Stmrk1    ; ..do short jump if so.
  474.     push    af
  475.     ld    a,(mrkesc)    ; Is this ESC argument?
  476.     or    a
  477.     ld    a,0        ; (always reset flag)
  478.     ld    (mrkesc),a
  479.     jr    z,Stmrk2    ; Jump if not ESC argument
  480.     pop    af
  481. Stmrk1:    and    7FH        ; Mask MSB in case 8-bit code
  482.     cp    LEFT        ; ..process argument characters
  483.     jp    z,Goleft
  484.     cp    UP
  485.     jp    z,Goup
  486.     cp    RIGHT
  487.     jp    z,Gort
  488.     cp    DOWN
  489.     jp    z,Godn
  490.     xor    a        ; Clear for next char..
  491.     ret            ; ..if not one of these
  492. ;
  493. Stmrk2:    pop    af
  494.     cp    CANCEL
  495.     jr    z,Abort
  496.     cp    WSLFT
  497.     jp    z,Goleft
  498.     cp    WSUP
  499.     jp    z,Goup
  500.     cp    WSRIT
  501.     jp    z,Gort
  502.     cp    WSDWN
  503.     jp    z,Godn
  504.     cp    CR
  505.     jr    z,StmrkA
  506.     and    5FH        ; Convert to Ucase
  507.     cp    MARK
  508.     jr    z,StmrkA
  509.     cp    HOME
  510.     jr    z,Gohome
  511.     xor    a        ;no action
  512.     ret
  513. ;
  514. StmrkA:    ld    hl,mrkcnt    ;if no mark yet    set
  515.     ld    a,(hl)
  516.     or    a
  517.     ld    (hl),1
  518.     jr    z,Mk1        ;..set mark1
  519.     call    Mk2        ;else set mark2
  520. Mrkxit:    xor    a
  521.     ld    (mrkcnt),a    ;init for next time
  522.     scf            ;CY = all done
  523.     ret
  524. ;
  525. abort:    call    Normal        ;restore normal    video
  526.     ld    a,CANCEL
  527.     jr    Mrkxit
  528. ;
  529. ;-------------------------------------------
  530. ;
  531. ;  Set 1st mark, turn on rev. video, don't move cursor
  532. ;
  533. Mk1:    call    Crs2hl
  534.     ld    (mark1),hl
  535.     ld    (mark2),hl
  536.     ld    (curcol),hl    ; L -> curcol, H -> currow
  537.     push    hl
  538.     call    Revers        ; Reverse video on
  539. ;
  540. ;  Set single character under cursor to reverse video
  541. ;
  542.     pop    hl        ; Mark1
  543.     ld    a,1        ; Reverse 1 char
  544.     ld    (colct),a
  545.     ld    (rowct),a
  546.     push    hl
  547.     call    Showro
  548.     pop    hl
  549.     jp    Stcrshl        ; Set cursor to start
  550. ;
  551. ;  Set 2nd mark, restore normal video, set CY
  552. ;
  553. Mk2:    call    Crs2hl
  554.     ld    (mark2),hl
  555.     call    Normal        ; Restore normal video
  556.     scf            ; CY = all done
  557.     ret
  558. ;
  559. ;--------------------------------------------
  560. ;  Home cursor if no mark yet set
  561. ;
  562. Gohome:    ld    c,'H'        ; Convert to video driver's cntl char
  563.     jr    Ckmcnt
  564. ;
  565. ;  Move cursor up one line if no mark yet set
  566. ;
  567. Goup:    ld    c,'A'        ; 7-bit code for UP
  568.     jr    Ckmcnt
  569. ;
  570. ;  Move cursor left if no mark yet set
  571. ;
  572. Goleft:    ld    a,'D'        ; 7-bit code for LEFT
  573. Mvcurs:    ld    c,a
  574. Ckmcnt:    ld    a,(mrkcnt)    ; Send cursor-move char
  575.     or    a
  576.     ret    nz        ; ..unless mark1 already set
  577.     ld    a,c
  578.     jp    Jptesc        ; ..else send ESC then char in A
  579. ;
  580. ;  Move cursor right setting reverse video if mark already set
  581. ;
  582. Gort:    ld    a,'C'        ; 7-bit code for RIGHT
  583.     call    Jptesc        ; Position cursor
  584.     ld    a,(mrkcnt)
  585.     or    a        ; Quit here if no mark set
  586.     ret    z
  587. ;
  588. ; Hilite marked column if not already at right limit
  589. ;            Set cur at toprow, next col
  590. ;            Send partial column
  591. ;            colcnt++
  592. ;
  593. Gort1:    ld    hl,mark2
  594.     ld    a,NCOLS-2
  595.     cp    (hl)        ; Ring bell if already in last column
  596. Jcring:    jp    c,Xring
  597.     inc    (hl)        ; Bump 2nd mark-row
  598.     ld    hl,curcol
  599.     inc    (hl)        ; Bump column
  600.     ld    l,(hl)
  601.     ld    a,(mark1+1)    ; Top row
  602.     ld    h,a        ; H = row, L = col to hilite
  603. rowct equ  $+1
  604.     ld    b,00
  605. ;
  606. ;  Loop over each row in cut region
  607. Gorlp:    push    bc
  608.     push    hl        ; Save binary row/col
  609.     ld    a,1        ; Display 1 char in each row
  610.     call    Showhi
  611.     pop    hl
  612.     pop    bc
  613.     inc    h        ; Next row
  614.     djnz    Gorlp
  615.     ld    hl,colct    ; Prepare to bump col cnt & exit
  616.     jr    Inrmbs
  617. ;
  618. ;  Move cursor down setting reverse video if mark set
  619. ;
  620. Godn:    ld    a,'B'        ; 7-bit code for DOWN
  621.     call    Jptesc        ; Move cursor down
  622.     ld    a,(mrkcnt)
  623.     or    a
  624.     ret    z        ; quit here if no marks
  625. ;
  626. ;  Set reverse video on marked row if not already at bottom
  627. ;            set cur    at next    row, left col
  628. ;            send partial row
  629. ;            rowcnt++
  630. ;
  631. Godn1:    ld    hl,mark2+1    ; Row
  632.     ld    a,NROWS-2
  633.     cp    (hl)        ; Ring bell if on bottom line
  634.     jr    c,Jcring
  635.     inc    (hl)        ; Bump 2nd mark-col
  636.     ld    hl,currow    ; Bump row
  637.     inc    (hl)
  638.     ld    h,(hl)
  639.     ld    a,(mark1)    ; Left col
  640.     ld    l,a        ; H = row, L = col for row to hilite
  641.     call    Showro        ; Display 1 cut row
  642.     ld    hl,rowct    ; Bump row cnt
  643. Inrmbs:    inc    (hl)        ;   and exit
  644.     ld    hl,(curcol)
  645.     jp    Stcrshl
  646. ;
  647. ;--------------
  648. ; Fetch    A chars    at H=binary row, L=binary col from buffer.
  649. ; Put chars to screen, setting REVERSE VIDEO attribute.
  650. ; All registers used.
  651. ;
  652. ;    ENTER: H = binary row, L= binary col
  653. ;    EXIT:  CY flag clear
  654. ;
  655. Showro:
  656. colct equ  $+1
  657.     ld    a,00
  658. ;
  659. Showhi:    push    af
  660.     ld    a,h        ; Are we on bottom line?
  661.     cp    NROWS-2
  662.     jr    nz,Show1    ; ..jump if not
  663.     pop    af
  664.     push    af        ; Restore char count
  665.     add    a,l        ; ..add to start column
  666.     cp    NCOLS        ; Will it end in last column?
  667.     jr    c,Show1        ; ..jump if not
  668.     pop    af
  669.     dec    a        ; Else let it end in next-to-last
  670.     jr    z,Show2        ; ..Quit if char cnt = 0
  671.     push    af
  672. Show1:    push    hl
  673.     call    Stcrshl        ; Set cursor to start marked area
  674.     pop    hl
  675.     call    Rc2off        ; Convert cursor to offset
  676.     ld    de,buf        ; ..add buffer start address
  677.     add    hl,de    
  678.     pop    af        ; # chars
  679.     ld    b,a
  680. Showlp:    ld    c,(hl)        ; Fetch char from buffer
  681.     push    hl
  682.     push    bc
  683.     call    Sendc        ; Put to screen
  684.     pop    bc
  685.     pop    hl
  686.     inc    hl
  687.     djnz    Showlp
  688. Show2:    or    a        ; Clear CY
  689.     ret
  690. ;
  691. ;========================================
  692. ;
  693. Retnch:                ; << Specific >>
  694. ;
  695. ; Return next screen char from buffer.
  696. ;
  697. ; ENTER: D = row, E = col
  698. ;        B = FF     ==>    read screen
  699. ;        C = FF     ==>    set bufptr
  700. ; EXIT:    A = char, CY set if good
  701. ;    DE -> row,col of next char, HL -> buf of next char
  702. ;    CY clear if out    of range
  703. ;
  704. ; This routine can be called to    get successive chars from
  705. ; buffer as long as caller preserves hl,de and sets b=c=0.
  706. ;
  707.     xor    a
  708.     call    Stdump
  709.     ret    nc
  710.     ld    a,(hl)        ; Get char
  711.     inc    hl        ; bump bufptr
  712.     ret
  713. ;
  714. ;--------------------
  715. ;
  716. ; ret:    NC if out of range
  717. ;    else hl-> buffer char
  718. ;
  719. Stdump:    inc    b
  720.     jr    nz,Stdum0
  721.     push    bc        ; B = FF  ==> Read screen
  722.     push    de
  723.     push    hl
  724.     call    Savpag
  725.     pop    hl
  726.     pop    de
  727.     pop    bc
  728. Stdum0:    inc    c
  729.     jr    nz,Conv4
  730. ;
  731. ; ENTER: D = row, E = col
  732. ;    SET: HL -> buffer address, CY set, preserve DE
  733. ; RETURN: CY clear if error (off screen)
  734. ;
  735.     ld    a,d        ; C = FF  ==> set bufptr    
  736.     cp    NROWS
  737.     jr    nc,ConBAD
  738.     ld    a,e
  739.     cp    NCOLS
  740.     jr    c,ConvOK
  741. ConBAD:    xor    a        ; Out of range, ret NC
  742.     ret
  743. ;
  744. ConvOK:    push    de        ; Preserve col/row
  745.     ex    de,hl
  746.     call    Rc2off        ; Convert to Offset in HL
  747.     ld    de,buf        ; ..from buffer base
  748.     add    hl,de
  749.     pop    de        ; ..restore col/row
  750.             ; ..fall thru..
  751. Conv4:    inc    de        ; Bump col
  752.     ld    a,e
  753.     cp    NCOLS
  754.     ret    c
  755.     ld    e,0        ; End of row, set col = 0
  756.     inc    d        ;   and bump row
  757.     ld    a,d    
  758.     cp    NROWS
  759.     ret            ; NC if out of range
  760. ;
  761. ;========================================
  762. ;
  763. Retnat:                ; << Specific >>
  764. ;
  765. ; Return next screen attribute from buffer.
  766. ; NUL FUNCTION for Heath-19.
  767. ;
  768. ; ENTER: D = row, E = col
  769. ;        B = FF ==> read    screen
  770. ;        C = FF ==> set bufptr
  771. ; EXIT: A = attr, CY set if good
  772. ;        DE -> row,col of next char, HL -> buf of next char
  773. ; RETURN: CY clear if out of range
  774. ;
  775.     xor    a        ; Clear CY
  776.     ret
  777. ;
  778. ;========================================
  779. ;
  780. Savpag:                ; << Specific >>
  781. ;
  782. ; Save screen to buffer.
  783. ;
  784. ;;    ld    hl,Zheath    ; If needed, put in ANSI mode
  785. ;;    call    JJputs
  786.     call    Getcu        ; Get ASCII row/col cursor
  787.     ld    (colrow),hl
  788.     call    Get124
  789.     jr    Get25
  790. ;
  791. ; Get lines 1-24
  792. ;
  793. Get124:    ld    a,SNDPAG    ; Tell terminal to send 1-24
  794.     call    Jptesc
  795.     ld    hl,buf
  796.     call    Getrgn
  797.     ld    (ptr25),hl
  798.     ret
  799. ;
  800. ; Get 25th line
  801. ;
  802. Get25:    ld    hl,z25on    ; Turn on status line
  803.     call    JJputs
  804.     ld    a,SND25        ; Tell terminal to send row 25
  805.     call    Jptesc
  806.     ld    hl,(ptr25)
  807. ;            ...fall thru...
  808. ;
  809. ; Get region to the HL buffer
  810. ;
  811. Getrgn:    ld    c,0
  812. Getplp:    push    hl
  813.     push    bc
  814.     call    JJconi        ; Get a char
  815.     pop    bc
  816.     pop    hl
  817.     cp    ESC        ; Is this an escape?
  818.     jr    z,Getpl1
  819.     cp    CR        ; Is this the end?
  820.     ret    z
  821.     bit    ESCMOD,c    ; Was last char=ESC?
  822.     jr    nz,Getpl2    ; ..jump if so
  823.     bit    GRAPH$,c
  824.     jr    z,Getplr    ; Jump if not graphic
  825.     sub    5FH        ; make binary
  826.     res    7,a        ; 5E-->7FH
  827.     ld    (hl),a
  828. ;
  829. Getplr:    bit    REV$,c
  830.     jr    z,Getpl0    ; Jump if not reverse video
  831.     set    7,a
  832. Getpl0:    ld    (hl),a
  833.     inc    hl        ; Bump ptr..
  834.     jr    Getplp        ; ..loop
  835. ;
  836. Getpl1:    set    ESCMOD,c    ; Flag next as argument
  837.     jr    Getplp
  838. ;
  839. Getpl2:    cp    REVON
  840.     jr    z,Ron
  841.     cp    REVOF
  842.     jr    z,Roff
  843.     cp    GRON
  844.     jr    z,Gon
  845.     cp    GROFF
  846.     jr    nz,Getpl3    ; Reset esc & loop
  847.     res    GRAPH$,c
  848.     jr    Getpl3
  849. ;
  850. Ron:    set    REV$,c
  851.     jr    Getpl3
  852. ;
  853. Roff:    res    REV$,c
  854.     jr    Getpl3
  855. ;
  856. Gon:    set    GRAPH$,c
  857. Getpl3:    res    ESCMOD,c
  858.     jr    Getplp
  859. ;
  860. ;========================================
  861. ;
  862. Respag:                ; << Specific >>
  863. ;
  864. ;  Restore saved screen from buffer.
  865. ;       NOTE:    For the Heath-19, the last position in row 24
  866. ;        is NOT restored since that causes the entire
  867. ;        screen to scroll if Line Wrap is ON.
  868. ;
  869.     ld    a,CLRSCR    ; Clear screen
  870.     call    Jptesc
  871.     call    put124        ; Restore rows 1 thru 24..
  872.     call    put25        ; ..and 25
  873.     ld    hl,zcurs    ; Restore cursor
  874.     call    JJputs
  875.     call    Nogrph        ; Finish with graphics OFF..
  876.     jp    Normal        ; ..and return to normal video
  877. ;
  878. ; To screen, line 25
  879. ;
  880. Put25:    ld    hl,y0row    ; Set cursor position for..
  881.     ld    (hl),NROWS-1+CRBIAS    ; ..row 25, col 0
  882.     dec    hl        ; Point to string start
  883.     dec    hl
  884.     call    JJputs        ; Position cursor
  885.     ld    a,1        ; Send 1 line
  886.     ld    hl,(ptr25)
  887.     jr    Putsc1
  888. ;
  889. ; To screen, lines 1-24
  890. ;
  891. Put124:    ld    hl,y0row    ; Set cursor position for..
  892.     ld    (hl),1-1+CRBIAS    ; ..First row, col 0
  893.     dec    hl        ; Point to string start
  894.     dec    hl
  895.     call    JJputs        ; Position cursor
  896.     ld    hl,buf
  897.     ld    a,24        ; Send 24 lines
  898. Putsc1:    ld    c,0        ; Normal video, no graphics
  899. ;
  900. Putlp:    ld    (lincnt),a    ; Store number of lines left
  901.     ld    b,NCOLS        ; ..set # of chars per line
  902.     ld    a,(y0row)
  903.     cp    NROW24-1+CRBIAS    ; If this is line 24...
  904.     jr    nz,Putlp0
  905.     dec    b        ; ..don't write in last position
  906. Putlp0:    push    hl        ; Save buffer address
  907.     call    Sndprc        ; Send processed char..
  908.     call    Send        ; ..to screen
  909.     pop    hl
  910.     inc    hl
  911.     djnz    Putlp0        ; Loop on line
  912.     push    hl
  913.     ld    hl,y0curs    ; Return to left col at each line end
  914.     call    JJputs
  915.     pop    hl
  916.     ld    a,(lincnt)
  917.     dec    a        ; Any more lines?
  918.     jr    z,PutlpZ    ; ..jump if not
  919.     push    af
  920.     push    hl
  921.     ld    hl,y0row    ; Position to next line down
  922.     inc    (hl)        ; ..by bumping cursor address
  923.     dec    hl        ; Back to string start
  924.     dec    hl
  925.     call    JJputs        ; ..and position
  926.     pop    hl
  927.     pop    af
  928.     jr    Putlp
  929. ;
  930. PutlpZ:    ld    (ptr25),hl
  931.     call    Ptgrof
  932.     jp    Normal        ; Set screen to normal
  933. ;
  934. ; Process character sending appropriate ESCape sequences
  935. ; and setting flags.
  936. ;
  937. Sndprc:    ld    a,(hl)
  938.     push    af
  939.     bit    7,a        ; Check for reverse video
  940.     jr    z,Sndpr0    ; ..jump if not
  941.     call    Putrev
  942.     pop    af
  943.     and    7FH        ; Restore char masking MSB
  944.     push    af
  945.     jr    Sndpr1
  946. ;
  947. Sndpr0:    bit    REV$,c        ; See of flag on..
  948.     call    nz,Ptroff    ; ..and reset if so
  949.     pop    af
  950.     push    af
  951. ;
  952. Sndpr1:    cp    ' '
  953.     jr    c,Putgph    ; Jump if graphic
  954.     cp    DEL        ; 7FH is also graphic
  955.     jr    z,Putgph
  956.     bit    GRAPH$,c
  957.     call    nz,Ptgrof
  958.     pop    af
  959.     ret
  960. ;
  961. Putgph:    bit    GRAPH$,c
  962.     call    z,Ptgron
  963.     pop    af
  964.     add    a,5FH        ; Make printable char
  965.     and    7FH        ; ..mask off MSB
  966.     ret
  967. ;
  968. ; Set to reverse video mode if necessary
  969. ;
  970. Putrev:    bit    REV$,c
  971.     ret    nz        ; ..already there, return
  972. ;            ..else fall thru..
  973. ;
  974. ; Update the flag
  975. ;
  976. Putron:    set    REV$,c
  977. Revers:    ld    a,REVON        ; Turn on reverse video
  978.     jr    Jptesc
  979. ;
  980. Ptroff:    res    REV$,c
  981. Normal:    ld    a,REVOF        ; Turn off reverse vidso
  982.     jr    Jptesc
  983. ;
  984. Ptgron:    set    GRAPH$,c
  985.     ld    a,GRON        ; Turn on graphics
  986.     jr    Jptesc
  987. ;
  988. Ptgrof:    res    GRAPH$,c
  989. Nogrph:    ld    a,GROFF        ; Turn off graphics
  990. Jptesc:    push    af        ; Send ESCape followed by char in A
  991.     ld    a,ESC
  992.     call    Send
  993.     pop    af
  994.     jp    Send
  995. ;
  996. ;---------- Cursor Conversion Routines ----------
  997. ;
  998. ; Convert binary row/col to relative offset
  999. ;    Enter:    H=binary row, L=binary col
  1000. ;    Exit:   HL = Binary offset    (HL =  row * NCOLS + col)
  1001. ;    Uses:   BC, DE, HL
  1002. ;
  1003. Rc2off:    ld    b,h        ; B = row
  1004.     ld    c,l        ; C = col
  1005.     ld    hl,0
  1006.     inc    b
  1007.     ld    de,NCOLS
  1008.     jr    Rc2bot
  1009. Rc2of0:    add    hl,de        ; Rows * NCOLS
  1010. Rc2bot:    djnz    Rc2of0
  1011.     add    hl,bc        ; Add col
  1012.     ret
  1013. ;
  1014. ;============ Cursor Positioning Routines ==============
  1015. ;
  1016. ; Set cursor on    screen.
  1017. ;    Enter: H=binary row, L = binary col
  1018. ;
  1019. Stcrshl: call    Rc2off
  1020. ;            ...fall thru...
  1021. ;
  1022. ; Set cursor on    screen by direct cursor    addressing.
  1023. ;    Enter: HL = cursor offset relative to 0000
  1024. ;    
  1025. Stcrs:    call    Off2cr        ; Convert from offset to ascii col/row
  1026.     ld    (colrow),hl    ; Put ascii col/row into string
  1027.     ld    hl,zcurs    ; Send set-cursor string
  1028.     jp    JJputs
  1029. ;
  1030. ;-------------
  1031. ;
  1032. ; Get current cursor position.
  1033. ;    Exit: H=binary row, L=binary col
  1034. ;    Uses: A, HL
  1035. ;
  1036. Crs2hl:    call    Getcu        ; Get cursor by querying terminal
  1037.     ld    a,h        ; Convert ASCII to binary..
  1038.     ld    h,l        ; ..and reverse order
  1039.     sub    CRBIAS
  1040.     ld    l,a
  1041.     ld    a,h
  1042.     sub    CRBIAS
  1043.     ld    h,a
  1044.     ld    (bcursor),hl    ; Save it
  1045.     ret
  1046. ;
  1047. ;-------------
  1048. ;
  1049. ; Get cursor position, checking for 8-bit mode
  1050. ;    Exit: HL Contains ASCII H=col, L=row
  1051. ;    Uses: A, HL
  1052. ;
  1053. Getcu:    ld    a,SNDCUR
  1054.     call    Jptesc
  1055.     call    JJconi
  1056.     bit    7,a        ; If 8-bit mode, skip
  1057.     call    z,JJconi
  1058.     call    JJconi        ; Get row
  1059.     ld    l,a
  1060.     push    hl
  1061.     call    JJconi        ; Get col
  1062.     pop    hl
  1063.     ld    h,a
  1064.     ret
  1065. ;
  1066. ;******************************************
  1067. ;
  1068. ; DATA AREA
  1069. ;
  1070. ; cut-region data
  1071. ;
  1072. ctsize: dw    0    ; (# cols + 1) * (# rows)
  1073. ;
  1074. ctcols: db    0    ; # cols in cut region (excl. CR), A PAIR
  1075. ctrows: db    0    ; # rows
  1076. ;
  1077. ptr25:    dw    00    ; Pointer to 25th line
  1078. lincnt:    db    0    ; Line counter for put-page
  1079. ;
  1080. ; mark-region data
  1081. ;
  1082. mrkcnt:    db    0
  1083. ;
  1084. curcol:    db    0    ; A PAIR
  1085. currow:    db    0
  1086. ;
  1087. mark1:    dw    0    ; Binary row,col of upperleft mark
  1088. mark2:    dw    0    ; Lower right mark
  1089. ;
  1090. mrkesc:    db    0    ; Flag for ESC sensing
  1091. ;
  1092. ZRUB:    DB    BS,SPACE,BS+80H        ; Rub-out previous char
  1093. ;
  1094. ;****************************************
  1095. ;
  1096. ;  TERMINAL-SPECIFIC data
  1097. ;    Heath-19
  1098. ;
  1099. ; ...Cursor lead-in and command strings
  1100. ;
  1101. zcurs:    db    ESC,'Y'        ; Set cursor to..
  1102. colrow:    db    '  '        ;   row,col - modified in-line
  1103.     db    0        ; Must have following NUL
  1104. ;
  1105. y0curs:    db    ESC,'Y'        ; Working positioning sequence
  1106. y0row:    db    20H,20H!80H    ; Cursor at line nn, col 0
  1107. ;
  1108. z25on:    db    ESC,'x','1'!80H        ; enable 25th line
  1109. ;
  1110. ; ...Other sequences for Heath-19
  1111. ;
  1112. ;z8bits: db    ESC,'e','C'!80H        ; UNUSED.  Put in 8-bit mode
  1113. ;
  1114. zheath:    db    ESC,'[','?','2','h'    ; Enter Heath mode
  1115. ;
  1116. ;================================
  1117. ;
  1118. ; NOTEPAD BANNER
  1119. ;
  1120. ; 1. Clear screen.
  1121. ; 2. Remind user of usage, to extent space is available.
  1122. ;
  1123. zbanner: db    ESC,CLRSCR        ; Clear screen HEATH-19-SPECIFIC
  1124. ;
  1125.     db    'JOT:   <SUSPEND> = exit,  '
  1126.     db    '^V = ins line,  ^Y = del line',CR,LF
  1127.     db    '        ^E - up, ^X - down, '
  1128.     db    '^S - left, ^D - right'
  1129. ;
  1130. zcrlf:    db    CR,LF!80H
  1131. ;
  1132. codlen equ $-start        ; Length of code
  1133. ;
  1134. ;++++++++++++++++++++++++++++++
  1135. ;
  1136. ; SCREEN BUFFER    STRUCTURE
  1137. ;
  1138. ; The rest of the 4K block is available    for the    screen image and other data.
  1139. ;
  1140. xbreq    equ    2 + nrows*ncols
  1141. ;
  1142. ; put buffer at    end of 4K area,    to just    fit
  1143. ;
  1144. bstart    equ    [start + 400H] + [3*400h-xbreq]
  1145. ;
  1146. short equ    start+codlen-bstart
  1147. xfree equ    - short
  1148. ;
  1149.     IF [SHORT]
  1150.     defb    '[07]Code overflows buffer!'
  1151.     ENDIF
  1152. ;
  1153. ; addresses:
  1154. ;
  1155. bcursor    equ    bstart        ; Cursor location in saved screen
  1156. buf    equ    bcursor+2    ; Start of screen buffer
  1157. ;
  1158. ;  Buffer uses (25 lines x 80 chars)
  1159. ;
  1160. bufend    equ    buf+NROWS*NCOLS
  1161. ;
  1162. ;
  1163.     end    JJcons
  1164. eath mode
  1165. ;
  1166. ;============================