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 / TERM / Z19.ASM < prev   
Assembly Source File  |  2000-06-30  |  23KB  |  970 lines

  1. ; Z-19.ASM    Z-19 emulator for the SSM VB3 video card
  2. ;        Version 1.0  Released 82.4.18
  3. ;        Copyleft (L) Scott W. Layson.  All rights reversed.
  4. ;        This code is in the public domain.
  5. ;
  6. ;    This code performs approximate (but usually adequate) emulation
  7. ;    of the Heath/Zenith Z-19 terminal on the SSM VB3 video card.  It
  8. ;    supports most of the Z-19 features required for normal text editing.
  9. ;    About the only useful thing missing is the special 25th line (49th?).
  10. ;
  11. ;    Things to note about this code:
  12. ;    -- The indentation in this file looks so strange because I edit with
  13. ;       five-column instead of eight-column tabs.
  14. ;    -- Sections of this code, especially the relatively low-level routines,
  15. ;       are not well commented.  Sorry 'bout that.
  16. ;    -- The code uses Intel mnemonics, but there are a couple of Z-80
  17. ;       block moves inserted with `db's.  If you don't have a Z-80, you'll
  18. ;       have to replace these with 8080 loops that do the same thing.
  19. ;    -- This file requires MAC for assembly as it stands, though it might
  20. ;       not be very hard to make it ASM-compatible.
  21. ;    -- It assumes that the video controller has already been initialized
  22. ;       (to 48 lines, but you can change this in the block of code below).
  23. ;    -- There's no keyboard I/O code in this file.
  24. ;    -- I have to turn the lower 48K of my main memory off, because my
  25. ;       ExpandoRam II doesn't respond to PHANTOM* on write.  You will
  26. ;       presumably have to change or remove this code; it's all right
  27. ;       near the beginning.
  28. ;    -- This code uses a fair amount of stack space; I don't know exactly
  29. ;       how much.  Because of this and because I'm turning most of main
  30. ;       memory off, I use a private stack at the top of memory.  I recommend
  31. ;       you do likewise if possible.
  32. ;    -- I normally use this code in "roll mode" rather than "scroll mode":
  33. ;       after the last line on the screen is printed, the cursor is placed
  34. ;       on the top line, which is then cleared.  The screen is never scrolled.
  35. ;       I find this more comfortable on a P39 monitor, where scrolling leaves
  36. ;       "trails".  The Z-19, of course, supports only "scroll mode".  The
  37. ;       defaults for this and other modes are set in the `db's at the end
  38. ;       of the file.
  39. ;    -- The behavior of this code when it gets an insert- or delete- line
  40. ;       command is a little weird.  Instead of doing the insertion or
  41. ;       deletion immediately, it counts the number of successive insertions
  42. ;       or deletions and only executes them when it gets some other kind
  43. ;       of command.  Sometimes this means that when you give an insert-line
  44. ;       or delete-line command to your editor, nothing happens until you
  45. ;       type another character.  The insert-n-lines and delete-n-lines
  46. ;       commands, on the other hand, are executed immediately.
  47. ;    -- Consider: when you put a terminal into inverse video mode and give
  48. ;       it a clear command of some sort (clear-to-end-of-line, home-and-clear-
  49. ;       screen), should it clear to inverse or normal spaces?  The Z-19 clears
  50. ;       to normal spaces; this code, like most other "smart" terminals these
  51. ;       days, clears to inverse spaces.  Likewise for the other video
  52. ;       attributes it supports.
  53. ;    -- The "graphics" mode accesses the user-definable font ROM.  Obviously,
  54. ;       for emulation of Z-19 graphics mode, you must burn a ROM with that
  55. ;       character set.
  56. ;
  57. ; Here is a list of control characters and escape sequences the code
  58. ; currently supports.  A `*' marks sequences the Z-19 doesn't have.
  59. ;
  60. ;  BS
  61. ;  TAB
  62. ;  CR
  63. ;  LF
  64. ;  Esc @            Enter insert-char mode
  65. ;  Esc A            Cursor up
  66. ;  Esc B            Cursor down
  67. ;  Esc C            Cursor forward
  68. ;  Esc D            Cursor backward
  69. ;  Esc E            Home and clear
  70. ;  Esc F            Enter graphics mode
  71. ;  Esc G            Exit graphics mode
  72. ;  Esc H            Home
  73. ;  Esc J            Clear to end of screen
  74. ;  Esc K            Clear to end of line
  75. ;  Esc L            Insert line
  76. ;  Esc M            Delete line
  77. ;  Esc N            Delete char
  78. ;  Esc O            Exit insert-char mode
  79. ;  Esc Y <r> <c>    Cursor pos
  80. ; *Esc l <n>        Insert n lines
  81. ; *Esc m <n>        Delete n lines
  82. ;  Esc p            Enter inverse video
  83. ;  Esc q            Exit inverse video
  84. ;  Esc x/y 5        Turn cursor off/on
  85. ; *Esc x/y *        Enter/exit scroll mode
  86. ; *Esc x/y A        Enter/exit inverse video
  87. ; *Esc x/y B        Enter/exit hide-char mode
  88. ; *Esc x/y C        Enter/exit underline mode
  89. ; *Esc x/y D        Enter/exit blink mode
  90. ; *Esc x/y E        Enter/exit strike-thru mode
  91. ; *Esc x/y F        Enter/exit dim mode
  92. ; *Esc x/y @        Set/clear all video modes
  93. ;  Esc v            Wrap mode on
  94. ;  Esc w            Wrap mode off
  95. ;
  96.  
  97. ; And now the code itself.
  98.  
  99. vnormal    equ 3            ; standard character attribute code
  100. vinverse    equ 4            ; inverse video bit
  101. bs        equ 08h
  102. tab        equ 09h
  103. lf        equ 0ah
  104. cr        equ 0dh
  105. esc        equ 1Bh
  106. vkbstat    equ 0e0h            ; video keyboard status port
  107. vkbdata    equ 0e1h            ; video keyboard data port
  108. vc        equ 0d0h            ; video controller registers:
  109. vhcount    equ vc + 0        ;    char times per scan
  110. vhsync    equ vc + 1        ;    interlace(1), hsp(4), hbp(3)
  111. vchars    equ vc + 2        ;    0(1), scans/char(4), chars/line(3)
  112. vlines    equ vc + 3        ;    lines/frame
  113. vscans    equ vc + 4        ;    scans/frame
  114. vvsync    equ vc + 5        ;    vertical scan delay
  115. vscrol    equ vc + 6        ;    scroll register
  116. vcolin    equ vc + 9        ;    cursor column in
  117. vcolout    equ vc + 12        ;    cursor column out
  118. vrowin    equ vc + 8        ;    cursor row in
  119. vrowout    equ vc + 13        ;    cursor row out
  120. vncols    equ 80            ; number of cols
  121. vnrows    equ 48            ; number of rows
  122. vvideo    equ 2000h            ; address of video memory
  123. voffset    equ 1000h            ; offset to attributes
  124. ramcard    equ 0FFh            ; ExpandoRam bank-switch port
  125. ramoff    equ 1            ; to turn main memory off
  126. ramon    equ 0            ; to turn memory back on
  127.  
  128.  
  129.         org 0F810h
  130.  
  131. ; Main entry point.  The character is in C.
  132.  
  133. h19        push h            ; save registers
  134.         push d
  135.         push b
  136.         lxi h, 0
  137.         dad sp            ; get stack pointer
  138.         lxi sp, 0            ; move stack to high memory
  139.         push h            ; save old SP
  140.         mvi a, ramoff        ; turn main memory off
  141.         out ramcard
  142.         out vkbstat        ; enable VB3
  143.         call curoff        ; turn cursor off
  144.         call process        ; process char
  145.         call curon        ; cursor back on
  146.         out vkbdata        ; disable VB3
  147.         mvi a, ramon        ; turn main memory back on
  148.         out ramcard
  149.         pop h            ; recover old SP
  150.         sphl                ; and put the stack back where it was
  151.         pop b            ; restore registers
  152.         pop d
  153.         pop h
  154.         ret                ; and done!
  155.  
  156. process    lda escmode        ; are we in an escape sequence?
  157.         ora a
  158.         jnz escseq        ; yes: go interpret this char
  159.         mov a, c
  160.         cpi esc            ; test for esc before checking insdelcnt
  161.         jz doesc            ; in case we're getting another ins or del
  162.         
  163.         lda insdelcnt        ; any saved line insertions or deletions to do?
  164.         ora a
  165.         cnz doinsdel        ; yes: do them first
  166.         
  167.         mov a, c            ; check for the known control chars
  168.         cpi cr            ; (others are displayed)
  169.         jz docr
  170.         cpi lf
  171.         jz dolf
  172.         cpi bs
  173.         jz dobs
  174.         cpi tab
  175.         jz dotab
  176.         
  177. ; we have a displayable character.
  178. display    lda insmode        ; are we in insert-char mode?
  179.         ora a
  180.         cnz inschar        ; yes: move rest of line over first
  181.         lda attrib        ; get current attribute byte
  182.         mov b, a            ; set up for putchar
  183.         call putchar
  184.         call right        ; move cursor right
  185.         rnz                ; done if no wrap
  186.         lda wrapp            ; are we in wrap mode?
  187.         ora a
  188.         rz                ; no: return
  189.         jmp nextline        ; wrap occurred
  190.  
  191. ; write the char in c, attribute in b, to the video memory.
  192. putchar    push h
  193.         call addr            ; get memory address of char
  194.         mov m, c            ; store char
  195.         lxi d, voffset
  196.         dad d            ; address of attribute
  197.         mov m, b            ; store attribute
  198.         pop h
  199.         ret
  200.  
  201. nextline    mvi l, 0            ; move to col. 0
  202.  
  203. ; move the cursor down one line.  Clear the new line
  204. ; if the cursor was on the last logical line.  Scroll the screen
  205. ; if in scroll mode.
  206.  
  207. dolf        lda scrollp        ; are we in scroll mode?
  208.         ora a
  209.         jnz dolfscr        ; yes: go do the right thing
  210. dolfnscr    lda lastlrow        ; do lf in non-scroll mode:
  211.         cmp h            ; are we moving off the last logical row?
  212.         push psw            ; save the answer to that question
  213.         call down            ; move down
  214.         jnz dolf3
  215.         mvi h, 0            ; wrap to top of screen
  216. dolf3    pop psw            ; are we moving off the last row?
  217.         rnz                ; no: done
  218.         call nextlrow        ; increment last-logical-row
  219.         jmp dolf2
  220.  
  221. dolfscr    call down            ; do lf in scroll mode
  222.         rnz                ; not moving off bottom: done
  223.         call nextlrow        ; increment last-logical-row
  224.         out vscrol        ; scroll screen
  225.         sta lastprow        ; set last-physical-row
  226.  
  227. dolf2    push h
  228.         mvi l, 0
  229.         call cleol        ; clear the new line
  230.         pop h
  231.         ret
  232.  
  233. nextlrow    lda lastlrow        ; increment last-logical-row
  234.         inr a
  235.         cpi vnrows        ; modulo vnrows
  236.         jnz nextl1
  237.         xra a
  238. nextl1    sta lastlrow        ; store result
  239.         ret
  240.  
  241. docr        mvi l, 0            ; CR: set col to 0
  242.         ret
  243.  
  244. dobs        jmp left            ; BS: move cursor left
  245.  
  246. dotab    mov a, l            ; TAB: move to current col...
  247.         ani 0F8h            ; ... modulo 8 ...
  248.         adi 8            ; ... plus 8
  249.         cpi vncols
  250.         jz right            ; except near edge of screen
  251.         mov l, a
  252.         ret
  253.  
  254. ; turn the cursor off.  Returns logical cursor address in HL.
  255. curoff    lhld curaddr        ; get logical cursor address
  256.         mvi a, 0FFh
  257.         out vcolout        ; move cursor off screen
  258.         ret
  259.  
  260. ; turn the cursor on.  Called with logical cursor address in HL.
  261. curon    shld curaddr        ; save logical cursor address
  262.         lda curoffp
  263.         ora a
  264.         rnz                ; if cursor turned off, leave it off screen
  265.         mov a, l            ; set column
  266.         out vcolout
  267.         lda lastprow        ; set row relative to last physical row
  268.         inr a
  269.         add h
  270.         cpi vnrows
  271.         jc curon1
  272.         sui vnrows
  273. curon1    out vrowout
  274.         ret
  275.  
  276. ; move the cursor left, if possible.  Returns Z iff at left edge.
  277. left        mov a, l            ; get col
  278.         dcr l
  279.         ora a
  280.         rnz                ; R(not at left edge)
  281.         mov l, a            ; force col. 0
  282.         ret
  283.  
  284. ; move the cursor right, if possible.  Returns Z iff at right edge.
  285. right    inr l
  286.         mvi a, vncols
  287.         cmp l
  288.         rnz                ; R(not at right edge)
  289.         mvi l, vncols - 1    ; can't just dcr, cuz it clears Z!
  290.         ret
  291.  
  292. ; move the cursor down, if possible.  Returns Z iff at bottom.
  293. down        inr h
  294.         mvi a, vnrows
  295.         cmp h
  296.         rnz                ; R(not at bottom)
  297.         mvi h, vnrows - 1    ; can't just dcr, cuz it clears Z!
  298.         ret
  299.  
  300. ; move the cursor up, if possible.  Returns Z iff at top.
  301. up        mov a, h
  302.         dcr h
  303.         ora a
  304.         rnz
  305.         mov h, a
  306.         ret
  307.  
  308. ; clear to end of line.
  309. cleol    mov d, h            ; set de to end of line
  310.         mvi e, vncols - 1
  311.         mvi c, ' '        ; space character in c
  312.         lda attrib        ; current attribute in b
  313.         mov b, a
  314.         jmp fills            ; and do it!
  315.  
  316. ; home and clear.
  317. hcl        call home
  318.         jmp cleow
  319.  
  320.  
  321. ; cursor home.
  322. home        lxi h, 0
  323.         ret
  324.  
  325. ; clear to end of window (screen).
  326. cleow    lda lastprow
  327.         sta lastlrow        ; set lastlrow to bottom of screen
  328.         mvi d, vnrows - 1    ; set de to end of screen
  329.         mvi e, vncols - 1
  330.         mvi c, ' '        ; space char in c
  331.         lda attrib        ; current attribute in b
  332.         mov b, a
  333.         jmp fills            ; and do it!
  334.  
  335. ; insert a character at the cursor.
  336. inschar    push b
  337.         push h
  338.         mvi a, vncols - 1    ; how many chars to move?
  339.         sub l
  340.         jz insch1            ; none: skip
  341.         mov c, a
  342.         mvi b, 0            ; # chars in bc
  343.         push b            ; and save it
  344.         mvi l, vncols - 1    ; set hl to end of line
  345.         call addr            ; get starting address of move
  346.         push h
  347.         mov d, h            ; dest in de
  348.         mov e, l
  349.         dcx h            ; source in hl
  350. ;        lddr                ; and move!
  351.         db 0EDh, 0B8h        ; Z80 instruction
  352.         pop h            ; address
  353.         pop b            ; byte count
  354.         lxi d, voffset        ; now do attributes
  355.         dad d
  356.         mov d, h            ; just like before
  357.         mov e, l
  358.         dcx h
  359. ;        lddr
  360.         db 0EDh, 0B8h        ; another Z80 instruction
  361. insch1    pop h
  362.         pop b
  363.         ret
  364.  
  365. ; delete a character at the cursor.
  366. delchar    push b
  367.         push h
  368.         mvi a, vncols - 1    ; get # of chars to move
  369.         sub l
  370.         jz delch1            ; none: skip
  371.         mov c, a
  372.         mvi b, 0            ; # chars in bc
  373.         push b
  374.         call addr            ; get starting address
  375.         push h
  376.         mov d, h            ; de = dest
  377.         mov e, l
  378.         inx h            ; hl = source
  379. ;        ldir                ; and move!
  380.         db 0EDh, 0B0h        ; Z80 instruction
  381.         pop h            ; address
  382.         pop b            ; byte count
  383.         lxi d, voffset        ; now do attributes
  384.         dad d
  385.         mov d, h            ; just like before
  386.         mov e, l
  387.         inx h
  388. ;        ldir                ; and move!
  389.         db 0EDh, 0B0h        ; Z80 instruction
  390. delch1    pop h            ; get current row, col back
  391.         push h
  392.         mvi l, vncols - 1    ; set up to clear last char in line
  393.         mvi c, ' '
  394.         lda attrib
  395.         mov b, a
  396.         call putchar        ; do it
  397.         pop h
  398.         pop b
  399.         ret
  400.  
  401. ; delete the line containing the cursor.
  402. delline    mvi c, 1            ; and fall through
  403.  
  404. ; delete <n> lines, starting with the one containing the cursor.
  405. ; <n> is in C.
  406. delnlines    push h
  407.         mov a, h
  408.         add c            ; other end of region to be deleted
  409.         cpi vnrows
  410.         jm deln1
  411.         mvi a, vnrows
  412. deln1    mov l, a            ; h = first dest, l = first source
  413.         mvi a, vnrows
  414.         sub l
  415.         mov b, a            ; b = no. of lines to move
  416.         call moveblk
  417.         mvi a, vnrows
  418.         sub c            ; c = no. of lines to clear
  419.         mov h, a            ; h = first row to clear
  420.         call clrblk
  421.         pop h
  422.         mvi l, 0            ; move to beginning of line
  423.         ret
  424.  
  425. ; insert a line where the cursor is.
  426. insline    mvi c, 1            ; and fall through
  427.  
  428. ; insert <n> lines before the line containing the cursor.
  429. ; <n> is in C.
  430. insnlines    push h
  431.         mov a, h
  432.         mov l, h
  433.         add c            ; other end of region to be inserted
  434.         cpi vnrows
  435.         jm insn1
  436.         mvi a, vnrows
  437. insn1    mov h, a            ; h = first dest, l = first source
  438.         mvi a, vnrows
  439.         sub h
  440.         mov b, a            ; b = no. of lines to move
  441.         call moveblk
  442.         mov h, l            ; h = first row to clear
  443.         call clrblk        ; c = no. of lines to clear
  444.         pop h
  445.         mvi l, 0            ; move to beginning of line
  446.         ret
  447.  
  448. ; move a block of B lines from row L to row H.
  449. moveblk    push h
  450.         push d
  451.         push b
  452.         mov a, l
  453.         cmp h
  454.         jm movbrev
  455. movbfwd    mov d, h
  456.         mov h, l
  457. movbfwd1    mov a, b
  458.         ora a
  459.         jz movbret
  460.         dcr b
  461.         call movelin
  462.         inr h
  463.         inr d
  464.         jmp movbfwd1
  465.  
  466. movbrev    mov a, h
  467.         add b
  468.         mov d, a            ; d = h + b
  469.         mov a, l
  470.         add b
  471.         mov h, a            ; h = l + b
  472. movbrev1    mov a, b
  473.         ora a
  474.         jz movbret
  475.         dcr b
  476.         dcr h
  477.         dcr d
  478.         call movelin
  479.         jmp movbrev1
  480.  
  481. movbret    pop b
  482.         pop d
  483.         pop h
  484.         ret
  485.  
  486.  
  487. ; clear C lines starting at H.
  488. clrblk    push h
  489.         push d
  490.         push b
  491.         mvi l, 0
  492. clrblk1    mov a, c
  493.         ora a
  494.         jz clrblk2
  495.         push b
  496.         call cleol
  497.         pop b
  498.         inr h
  499.         dcr c
  500.         jmp clrblk1
  501. clrblk2    pop b
  502.         pop d
  503.         pop h
  504.         ret
  505.  
  506. ; move a line from row H to row D.
  507. movelin    push h
  508.         push d
  509.         push b
  510.         mvi l, 0
  511.         mov e, l
  512.         lxi b, voffset
  513.         call addr
  514.         push h
  515.         dad b
  516.         xchg
  517.         call addr
  518.         push h
  519.         dad b
  520.         xchg
  521.         lxi b, vncols
  522. ;        ldir
  523.         db 0EDh, 0B0h        ; Z80 instruction
  524.         pop d
  525.         pop h
  526.         lxi b, vncols
  527. ;        ldir
  528.         db 0EDh, 0B0h        ; Z80 instruction
  529.         pop b
  530.         pop d
  531.         pop h
  532.         ret
  533.  
  534.  
  535. ; get physical address from logical address.
  536.  
  537. addr        push b
  538.         lda lastprow
  539.         inr a
  540.         add h
  541.         cpi vnrows
  542.         jc addr1
  543.         sui vnrows
  544. addr1    mov c, a
  545.         mvi b, 0
  546.         mov a, l            ; save col
  547.         lxi h, rowtab
  548.         dad b
  549.         dad b
  550.         mov c, a            ; get col back
  551.         mov a, m            ; look row up in table
  552.         inx h
  553.         mov h, m
  554.         mov l, a
  555.         dad b            ; add col
  556.         pop b
  557.         ret
  558.  
  559. rowtab
  560. j        set vncols
  561. i        set 0
  562.         rept vnrows
  563.         dw vvideo + j * i
  564. i        set i + 1
  565.         endm
  566.  
  567.  
  568. ; fill the screen with the data in C, the attribute in B
  569. ; from x, y location HL through DE.
  570. fills    push h
  571.         call addr
  572.         xchg
  573.         call addr
  574.         mov a, h
  575.         cmp d
  576.         jnz fills1a
  577.         mov a, l
  578.         cmp e
  579. fills1a    xchg
  580.         jnc fills1        ; J(area to fill doesn't wrap)
  581.         push d
  582.         push b
  583.         lxi d, vvideo + vnrows * vncols - 1
  584.         call fills2
  585.         pop b
  586.         pop d
  587.         lxi h, vvideo
  588. fills1    call fills2
  589.         pop h
  590.         ret
  591.  
  592. fills2    push b
  593.         push h
  594.         push d
  595.         call fill            ; fill in the data
  596.         pop h
  597.         pop d
  598.         lxi b, voffset
  599.         dad b
  600.         xchg
  601.         dad b
  602.         pop b
  603.         mov c, b
  604.         call fill            ; fill in the attributes
  605.         ret
  606.  
  607. fill        mov m, c            ; put down first copy
  608.         mov a, e
  609.         sub l
  610.         mov c, a
  611.         mov a, d
  612.         sbb h
  613.         mov b, a            ; bc = de - hl = no. bytes to move
  614.         ora c
  615.         rz                ; R(nothing to do -- only one byte to fill)
  616.         mov d, h            ; hl = source
  617.         mov e, l
  618.         inx d            ; de = dest
  619. ;        ldir
  620.         db 0EDh, 0B0h        ; Z80 instruction
  621.         ret
  622.  
  623.  
  624. ; turn on escape mode.
  625. doesc    mvi a, stesc
  626.         sta escmode
  627.         ret
  628.  
  629.  
  630. ;
  631. ; These are the various escape-states we can be in.  They indicate
  632. ; what part of an escape sequence we've seen already.
  633. stesc    equ 1            ; Esc
  634. stcprow    equ 2            ; Esc Y
  635. stcpcol    equ 3            ; Esc Y <row>
  636. stsetmode    equ 4            ; Esc x
  637. stclrmode equ 5            ; Esc y
  638. stinsn    equ 6            ; Esc l
  639. stdeln    equ 7            ; Esc m
  640.  
  641. ; We get here if we're in the middle of an escape sequence.
  642. ; escmode is in A.
  643.  
  644. escseq    push psw
  645.         xra a
  646.         sta escmode        ; clear escape mode here, for convenience
  647.         pop psw
  648.         
  649.         cpi stcprow        ; row byte?
  650.         jz docprow
  651.         cpi stcpcol        ; col byte?
  652.         jz docpcol
  653.         cpi stsetmode        ; set-mode byte?
  654.         jz dosetmode
  655.         cpi stclrmode        ; clear-mode byte?
  656.         jz doclrmode
  657.         cpi stinsn        ; insert-n-lines byte?
  658.         jz doinsn
  659.         cpi stdeln        ; delete-n-lines byte?
  660.         jz dodeln
  661.         
  662.         mov a, c
  663.         cpi 'L'            ; insert (1) line?
  664.         jz doinslin
  665.         cpi 'M'            ; delete (1) line?
  666.         jz dodellin
  667.         
  668.         lda insdelcnt        ; for anything else: do any saved
  669.         ora a            ; insertions/deletions first
  670.         cnz doinsdel
  671.         
  672.         mov a, c
  673.         cpi 'Y'            ; cursor pos?
  674.         jz docp
  675.         cpi 'K'            ; clear to end of line?
  676.         jz docleol
  677.         cpi 'E'            ; home and clear screen?
  678.         jz dohcl
  679.         cpi 'H'            ; home?
  680.         jz dohome
  681.         cpi 'J'            ; clear to end of screen?
  682.         jz docleow
  683.         cpi 'A'            ; cursor up?
  684.         jz doup
  685.         cpi 'B'            ; cursor down?
  686.         jz dodown
  687.         cpi 'C'            ; cursor right?
  688.         jz doright
  689.         cpi 'D'            ; cursor left?
  690.         jz doleft
  691.         cpi '@'            ; set char-insert mode?
  692.         jz inschon
  693.         cpi 'O'            ; clear char-insert mode?
  694.         jz inschoff
  695.         cpi 'N'            ; delete char?
  696.         jz dodelchar
  697.         cpi 'l'            ; insert n lines?
  698.         jz doinsnlins
  699.         cpi 'm'            ; delete n lines?
  700.         jz dodelnlins
  701.         cpi 'p'            ; set inverse video?
  702.         jz doinvon
  703.         cpi 'q'            ; clear inverse video?
  704.         jz doinvoff
  705.         cpi 'x'            ; set mode?
  706.         jz setmode
  707.         cpi 'y'            ; clear mode?
  708.         jz clrmode
  709.         cpi 'v'            ; set wrap mode?
  710.         jz dowrapon
  711.         cpi 'w'            ; clear wrap mode?
  712.         jz dowrapoff
  713.         cpi 'F'            ; set graphics mode?
  714.         jz dografon
  715.         cpi 'G'            ; clear graphics mode?
  716.         jz dografoff
  717.  
  718. escfail    push b            ; not any recognized command.  display
  719.         mvi c, esc        ; sequence literally so user can see what
  720.         call display        ; happened
  721.         pop b
  722.         call display
  723.         ret
  724.  
  725. docp        mvi a, stcprow        ; cursor pos command: set esc mode
  726.         sta escmode
  727.         ret
  728.  
  729. docprow    mov a, c            ; get row byte
  730.         sui 32            ; subtract bias
  731.         mov h, a
  732.         mvi a, stcpcol        ; set new esc mode
  733.         sta escmode
  734.         lda curoffp
  735.         inr a            ; cursor off during CP
  736.         sta curoffp
  737.         ret
  738.  
  739. docpcol    mov a, c            ; get col byte
  740.         sui 32            ; subtract bias
  741.         mov l, a
  742.         lda curoffp
  743.         dcr a            ; cursor back on (unless it was already off)
  744.         sta curoffp
  745.         ret
  746.  
  747. docleol    equ cleol
  748.  
  749. dohcl    equ hcl
  750.  
  751. dohome    equ home
  752.  
  753. docleow    equ cleow
  754.  
  755. doup        equ up
  756.  
  757. dodown    equ down
  758.  
  759. doright    equ right
  760.  
  761. doleft    equ left
  762.  
  763. inschon    mvi a, 1            ; set insert-char mode
  764.         sta insmode
  765.         ret
  766.  
  767. inschoff    xra a            ; clear insert-char mode
  768.         sta insmode
  769.         ret
  770.  
  771. dodelchar    equ delchar
  772.  
  773. doinslin    lda insdelcnt        ; accumulate insertions
  774.         ora a
  775.         push psw
  776.         cm doinsdel        ; do any saved deletions first
  777.         pop psw
  778.         inr a            ; then increment insdelcnt
  779.         sta insdelcnt
  780.         ret
  781.  
  782. dodellin    lda insdelcnt        ; accumulate deletions
  783.         dcr a
  784.         push psw
  785.         cp doinsdel        ; do any saved insertions first
  786.         pop psw
  787.         sta insdelcnt
  788.         ret
  789.  
  790. doinsnlins mvi a, stinsn        ; set escmode to expect no. of insertions
  791.         sta escmode
  792.         ret
  793.  
  794. dodelnlins mvi a, stdeln        ; set escmode to expect no. of deletions
  795.         sta escmode
  796.         ret
  797.  
  798. doinsn    equ insnlines
  799.  
  800. dodeln    equ delnlines
  801.  
  802. doinsdel    lda insdelcnt        ; do saved insertions/deletions
  803.         ora a            ; any to do?
  804.         rz                ; no: done
  805.         push b
  806.         jm doinsdel1        ; pos: insertions; neg: deletions
  807.         mov c, a            ; insertion was saved
  808.         call insnlines        ; do it
  809.         jmp doinsdel2
  810. doinsdel1    cma
  811.         inr a
  812.         mov c, a            ; deletion was saved
  813.         call delnlines        ; do it
  814. doinsdel2    pop b
  815.         xra a
  816.         sta insdelcnt        ; clear saved count
  817.         ret
  818.  
  819. doinvon    lda attrib        ; inverse video on
  820.         ori vinverse
  821.         sta attrib
  822.         ret
  823.  
  824. doinvoff    lda attrib        ; inverse video off
  825.         cma
  826.         ori vinverse
  827.         cma
  828.         sta attrib
  829.         ret
  830.  
  831. setmode    mvi a, stsetmode    ; set escmode to expect mode to set
  832.         sta escmode
  833.         ret
  834.  
  835. clrmode    mvi a, stclrmode    ; set escmode to expect mode to clear
  836.         sta escmode
  837.         ret
  838.  
  839. ; come here with a mode to set in C
  840. dosetmode    mov a, c
  841.         cpi '5'
  842.         jz setcuroff        ; turn cursor off
  843.         cpi '@'
  844.         jnc setattr        ; set display attributes
  845.         cpi '*'
  846.         jz setscrol        ; set scroll mode
  847.         push b
  848.         mvi c, esc        ; display unimplemented sequence, so
  849.         call display        ; user can see what happened
  850.         mvi c, 'x'
  851.         call display
  852.         pop b
  853.         call display
  854.         ret
  855.  
  856. setcuroff    mvi a, 1            ; turn cursor off
  857.         sta curoffp
  858.         ret
  859.  
  860. setattr    call attrbit        ; get bit for this attribute
  861.         lda attrib        ; or it into current attribute byte
  862.         ora e
  863.         sta attrib
  864.         ret
  865.  
  866. setscrol    lda scrollp        ; set scroll (Z-19 normal) mode
  867.         ora a
  868.         rnz                ; already on
  869.         mvi a, 1
  870.         sta scrollp
  871.         mvi h, vnrows - 1
  872.         lda lastlrow        ; get last logical row
  873.         out vscrol        ; make it last physical row
  874.         sta lastprow
  875.         ret
  876.  
  877. ; come here with a mode to clear in C
  878. doclrmode    mov a, c
  879.         cpi '5'
  880.         jz clrcuroff        ; turn cursor back on
  881.         cpi '@'
  882.         jnc clrattr        ; clear an attribute
  883.         cpi '*'
  884.         jz clrscrol        ; turn roll mode back on
  885.         push b
  886.         mvi c, esc        ; display unimplemented sequence
  887.         call display        ; so the user can see what happened
  888.         mvi c, 'y'
  889.         call display
  890.         pop b
  891.         call display
  892.         ret
  893.  
  894. clrcuroff    xra a            ; turn cursor back on
  895.         sta curoffp
  896.         ret
  897.  
  898. clrattr    call attrbit        ; get bit for attribute
  899.         lda attrib
  900.         cma
  901.         ora e            ; clear it in current attr. byte
  902.         cma
  903.         sta attrib
  904.         ret
  905.  
  906. clrscrol    lda scrollp        ; set "roll" mode: no scrolling
  907.         ora a
  908.         rz                 ; scroll mode already off
  909.         xra a
  910.         sta scrollp
  911.         lda lastlrow
  912.         mov h, a
  913.         mvi a, vnrows - 1    ; return screen to 0-origin
  914.         out vscrol
  915.         sta lastprow
  916.         ret
  917.  
  918. ; given command char in A, leaves attribute bit set in E
  919. attrbit    sbi '@'
  920.         jz attrbit1
  921.         mov e, a
  922.         mvi a, 2            ; start with 2
  923. attrbit2    rlc                ; rotate left
  924.         dcr e            ; the right number of times
  925.         jnz attrbit2
  926.         mov e, a
  927.         ret
  928. attrbit1    mvi e, 0FCh        ; '@': all attributes
  929.         ret
  930.  
  931. dowrapon    mvi a, 1            ; turn wrap mode (end-of-line wrapping) on
  932.         sta wrapp
  933.         ret
  934.  
  935. dowrapoff    xra a            ; turn wrap mode (end-of-line wrapping) off
  936.         sta wrapp
  937.         ret
  938.  
  939. dografon    lda attrib        ; turn graphics mode on (enable ROM)
  940.         ani 0FDh
  941.         sta attrib
  942.         ret
  943.  
  944. dografoff    lda attrib        ; turn graphics mode off (disable ROM)
  945.         ori 2
  946.         sta attrib
  947.         ret
  948.  
  949.  
  950.  
  951. ;
  952. ; Data section.  If you want to change the default modes (e.g., to
  953. ; wrapping and scrolling), this is the place to do it.  (Just change
  954. ; wrapp and scrollp.)
  955. ;
  956.  
  957. curaddr    dw 0                ; logical address of cursor
  958. lastprow    db vnrows - 1        ; physical last row
  959. lastlrow    db vnrows - 1        ; logical last row
  960. attrib    db 3                ; character attribute byte
  961. escmode    db 0                ; escape-sequence mode
  962. wrapp    db 0                ; wrap at end of line?
  963. insmode    db 0                ; insert-character mode
  964. scrollp    db 0                ; scroll mode
  965. curoffp    db 0                ; cursor-off mode
  966. insdelcnt    db 0                ; insert/delete line count
  967.  
  968. ; End of Z-19.ASM -- Z-19 Emulator for SSM VB3
  969.