home *** CD-ROM | disk | FTP | other *** search
- ; Z-19.ASM Z-19 emulator for the SSM VB3 video card
- ;
- ; Version 1.0 Released 82.4.18
- ; Copyleft (L) Scott W. Layson. All rights reversed.
- ; This code is in the public domain.
- ;
- ; This code performs approximate (but usually adequate) emulation
- ; of the Heath/Zenith Z-19 terminal on the SSM VB3 video card. It
- ; supports most of the Z-19 features required for normal text editing.
- ; About the only useful thing missing is the special 25th line (49th?).
- ;
- ; Things to note about this code:
- ; -- The indentation in this file looks so strange because I edit with
- ; five-column instead of eight-column tabs.
- ; -- Sections of this code, especially the relatively low-level routines,
- ; are not well commented. Sorry 'bout that.
- ; -- The code uses Intel mnemonics, but there are a couple of Z-80
- ; block moves inserted with `db's. If you don't have a Z-80, you'll
- ; have to replace these with 8080 loops that do the same thing.
- ; -- This file requires MAC for assembly as it stands, though it might
- ; not be very hard to make it ASM-compatible.
- ; -- It assumes that the video controller has already been initialized
- ; (to 48 lines, but you can change this in the block of code below).
- ; -- There's no keyboard I/O code in this file.
- ; -- I have to turn the lower 48K of my main memory off, because my
- ; ExpandoRam II doesn't respond to PHANTOM* on write. You will
- ; presumably have to change or remove this code; it's all right
- ; near the beginning.
- ; -- This code uses a fair amount of stack space; I don't know exactly
- ; how much. Because of this and because I'm turning most of main
- ; memory off, I use a private stack at the top of memory. I recommend
- ; you do likewise if possible.
- ; -- I normally use this code in "roll mode" rather than "scroll mode":
- ; after the last line on the screen is printed, the cursor is placed
- ; on the top line, which is then cleared. The screen is never scrolled.
- ; I find this more comfortable on a P39 monitor, where scrolling leaves
- ; "trails". The Z-19, of course, supports only "scroll mode". The
- ; defaults for this and other modes are set in the `db's at the end
- ; of the file.
- ; -- The behavior of this code when it gets an insert- or delete- line
- ; command is a little weird. Instead of doing the insertion or
- ; deletion immediately, it counts the number of successive insertions
- ; or deletions and only executes them when it gets some other kind
- ; of command. Sometimes this means that when you give an insert-line
- ; or delete-line command to your editor, nothing happens until you
- ; type another character. The insert-n-lines and delete-n-lines
- ; commands, on the other hand, are executed immediately.
- ; -- Consider: when you put a terminal into inverse video mode and give
- ; it a clear command of some sort (clear-to-end-of-line, home-and-clear-
- ; screen), should it clear to inverse or normal spaces? The Z-19 clears
- ; to normal spaces; this code, like most other "smart" terminals these
- ; days, clears to inverse spaces. Likewise for the other video
- ; attributes it supports.
- ; -- The "graphics" mode accesses the user-definable font ROM. Obviously,
- ; for emulation of Z-19 graphics mode, you must burn a ROM with that
- ; character set.
- ;
- ; Here is a list of control characters and escape sequences the code
- ; currently supports. A `*' marks sequences the Z-19 doesn't have.
- ;
- ; BS
- ; TAB
- ; CR
- ; LF
- ; Esc @ Enter insert-char mode
- ; Esc A Cursor up
- ; Esc B Cursor down
- ; Esc C Cursor forward
- ; Esc D Cursor backward
- ; Esc E Home and clear
- ; Esc F Enter graphics mode
- ; Esc G Exit graphics mode
- ; Esc H Home
- ; Esc J Clear to end of screen
- ; Esc K Clear to end of line
- ; Esc L Insert line
- ; Esc M Delete line
- ; Esc N Delete char
- ; Esc O Exit insert-char mode
- ; Esc Y <r> <c> Cursor pos
- ; *Esc l <n> Insert n lines
- ; *Esc m <n> Delete n lines
- ; Esc p Enter inverse video
- ; Esc q Exit inverse video
- ; Esc x/y 5 Turn cursor off/on
- ; *Esc x/y * Enter/exit scroll mode
- ; *Esc x/y A Enter/exit inverse video
- ; *Esc x/y B Enter/exit hide-char mode
- ; *Esc x/y C Enter/exit underline mode
- ; *Esc x/y D Enter/exit blink mode
- ; *Esc x/y E Enter/exit strike-thru mode
- ; *Esc x/y F Enter/exit dim mode
- ; *Esc x/y @ Set/clear all video modes
- ; Esc v Wrap mode on
- ; Esc w Wrap mode off
- ;
-
- ; And now the code itself.
-
- vnormal equ 3 ; standard character attribute code
- vinverse equ 4 ; inverse video bit
- bs equ 08h
- tab equ 09h
- lf equ 0ah
- cr equ 0dh
- esc equ 1Bh
- vkbstat equ 0e0h ; video keyboard status port
- vkbdata equ 0e1h ; video keyboard data port
- vc equ 0d0h ; video controller registers:
- vhcount equ vc + 0 ; char times per scan
- vhsync equ vc + 1 ; interlace(1), hsp(4), hbp(3)
- vchars equ vc + 2 ; 0(1), scans/char(4), chars/line(3)
- vlines equ vc + 3 ; lines/frame
- vscans equ vc + 4 ; scans/frame
- vvsync equ vc + 5 ; vertical scan delay
- vscrol equ vc + 6 ; scroll register
- vcolin equ vc + 9 ; cursor column in
- vcolout equ vc + 12 ; cursor column out
- vrowin equ vc + 8 ; cursor row in
- vrowout equ vc + 13 ; cursor row out
- vncols equ 80 ; number of cols
- vnrows equ 48 ; number of rows
- vvideo equ 2000h ; address of video memory
- voffset equ 1000h ; offset to attributes
- ramcard equ 0FFh ; ExpandoRam bank-switch port
- ramoff equ 1 ; to turn main memory off
- ramon equ 0 ; to turn memory back on
-
-
- org 0F810h
-
- ; Main entry point. The character is in C.
-
- h19 push h ; save registers
- push d
- push b
- lxi h, 0
- dad sp ; get stack pointer
- lxi sp, 0 ; move stack to high memory
- push h ; save old SP
- mvi a, ramoff ; turn main memory off
- out ramcard
- out vkbstat ; enable VB3
- call curoff ; turn cursor off
- call process ; process char
- call curon ; cursor back on
- out vkbdata ; disable VB3
- mvi a, ramon ; turn main memory back on
- out ramcard
- pop h ; recover old SP
- sphl ; and put the stack back where it was
- pop b ; restore registers
- pop d
- pop h
- ret ; and done!
-
- process lda escmode ; are we in an escape sequence?
- ora a
- jnz escseq ; yes: go interpret this char
- mov a, c
- cpi esc ; test for esc before checking insdelcnt
- jz doesc ; in case we're getting another ins or del
-
- lda insdelcnt ; any saved line insertions or deletions to do?
- ora a
- cnz doinsdel ; yes: do them first
-
- mov a, c ; check for the known control chars
- cpi cr ; (others are displayed)
- jz docr
- cpi lf
- jz dolf
- cpi bs
- jz dobs
- cpi tab
- jz dotab
-
- ; we have a displayable character.
- display lda insmode ; are we in insert-char mode?
- ora a
- cnz inschar ; yes: move rest of line over first
- lda attrib ; get current attribute byte
- mov b, a ; set up for putchar
- call putchar
- call right ; move cursor right
- rnz ; done if no wrap
- lda wrapp ; are we in wrap mode?
- ora a
- rz ; no: return
- jmp nextline ; wrap occurred
-
- ; write the char in c, attribute in b, to the video memory.
- putchar push h
- call addr ; get memory address of char
- mov m, c ; store char
- lxi d, voffset
- dad d ; address of attribute
- mov m, b ; store attribute
- pop h
- ret
-
- nextline mvi l, 0 ; move to col. 0
-
- ; move the cursor down one line. Clear the new line
- ; if the cursor was on the last logical line. Scroll the screen
- ; if in scroll mode.
-
- dolf lda scrollp ; are we in scroll mode?
- ora a
- jnz dolfscr ; yes: go do the right thing
- dolfnscr lda lastlrow ; do lf in non-scroll mode:
- cmp h ; are we moving off the last logical row?
- push psw ; save the answer to that question
- call down ; move down
- jnz dolf3
- mvi h, 0 ; wrap to top of screen
- dolf3 pop psw ; are we moving off the last row?
- rnz ; no: done
- call nextlrow ; increment last-logical-row
- jmp dolf2
-
- dolfscr call down ; do lf in scroll mode
- rnz ; not moving off bottom: done
- call nextlrow ; increment last-logical-row
- out vscrol ; scroll screen
- sta lastprow ; set last-physical-row
-
- dolf2 push h
- mvi l, 0
- call cleol ; clear the new line
- pop h
- ret
-
- nextlrow lda lastlrow ; increment last-logical-row
- inr a
- cpi vnrows ; modulo vnrows
- jnz nextl1
- xra a
- nextl1 sta lastlrow ; store result
- ret
-
- docr mvi l, 0 ; CR: set col to 0
- ret
-
- dobs jmp left ; BS: move cursor left
-
- dotab mov a, l ; TAB: move to current col...
- ani 0F8h ; ... modulo 8 ...
- adi 8 ; ... plus 8
- cpi vncols
- jz right ; except near edge of screen
- mov l, a
- ret
-
- ; turn the cursor off. Returns logical cursor address in HL.
- curoff lhld curaddr ; get logical cursor address
- mvi a, 0FFh
- out vcolout ; move cursor off screen
- ret
-
- ; turn the cursor on. Called with logical cursor address in HL.
- curon shld curaddr ; save logical cursor address
- lda curoffp
- ora a
- rnz ; if cursor turned off, leave it off screen
- mov a, l ; set column
- out vcolout
- lda lastprow ; set row relative to last physical row
- inr a
- add h
- cpi vnrows
- jc curon1
- sui vnrows
- curon1 out vrowout
- ret
-
- ; move the cursor left, if possible. Returns Z iff at left edge.
- left mov a, l ; get col
- dcr l
- ora a
- rnz ; R(not at left edge)
- mov l, a ; force col. 0
- ret
-
- ; move the cursor right, if possible. Returns Z iff at right edge.
- right inr l
- mvi a, vncols
- cmp l
- rnz ; R(not at right edge)
- mvi l, vncols - 1 ; can't just dcr, cuz it clears Z!
- ret
-
- ; move the cursor down, if possible. Returns Z iff at bottom.
- down inr h
- mvi a, vnrows
- cmp h
- rnz ; R(not at bottom)
- mvi h, vnrows - 1 ; can't just dcr, cuz it clears Z!
- ret
-
- ; move the cursor up, if possible. Returns Z iff at top.
- up mov a, h
- dcr h
- ora a
- rnz
- mov h, a
- ret
-
- ; clear to end of line.
- cleol mov d, h ; set de to end of line
- mvi e, vncols - 1
- mvi c, ' ' ; space character in c
- lda attrib ; current attribute in b
- mov b, a
- jmp fills ; and do it!
-
- ; home and clear.
- hcl call home
- jmp cleow
-
-
- ; cursor home.
- home lxi h, 0
- ret
-
- ; clear to end of window (screen).
- cleow lda lastprow
- sta lastlrow ; set lastlrow to bottom of screen
- mvi d, vnrows - 1 ; set de to end of screen
- mvi e, vncols - 1
- mvi c, ' ' ; space char in c
- lda attrib ; current attribute in b
- mov b, a
- jmp fills ; and do it!
-
- ; insert a character at the cursor.
- inschar push b
- push h
- mvi a, vncols - 1 ; how many chars to move?
- sub l
- jz insch1 ; none: skip
- mov c, a
- mvi b, 0 ; # chars in bc
- push b ; and save it
- mvi l, vncols - 1 ; set hl to end of line
- call addr ; get starting address of move
- push h
- mov d, h ; dest in de
- mov e, l
- dcx h ; source in hl
- ; lddr ; and move!
- db 0EDh, 0B8h ; Z80 instruction
- pop h ; address
- pop b ; byte count
- lxi d, voffset ; now do attributes
- dad d
- mov d, h ; just like before
- mov e, l
- dcx h
- ; lddr
- db 0EDh, 0B8h ; another Z80 instruction
- insch1 pop h
- pop b
- ret
-
- ; delete a character at the cursor.
- delchar push b
- push h
- mvi a, vncols - 1 ; get # of chars to move
- sub l
- jz delch1 ; none: skip
- mov c, a
- mvi b, 0 ; # chars in bc
- push b
- call addr ; get starting address
- push h
- mov d, h ; de = dest
- mov e, l
- inx h ; hl = source
- ; ldir ; and move!
- db 0EDh, 0B0h ; Z80 instruction
- pop h ; address
- pop b ; byte count
- lxi d, voffset ; now do attributes
- dad d
- mov d, h ; just like before
- mov e, l
- inx h
- ; ldir ; and move!
- db 0EDh, 0B0h ; Z80 instruction
- delch1 pop h ; get current row, col back
- push h
- mvi l, vncols - 1 ; set up to clear last char in line
- mvi c, ' '
- lda attrib
- mov b, a
- call putchar ; do it
- pop h
- pop b
- ret
-
- ; delete the line containing the cursor.
- delline mvi c, 1 ; and fall through
-
- ; delete <n> lines, starting with the one containing the cursor.
- ; <n> is in C.
- delnlines push h
- mov a, h
- add c ; other end of region to be deleted
- cpi vnrows
- jm deln1
- mvi a, vnrows
- deln1 mov l, a ; h = first dest, l = first source
- mvi a, vnrows
- sub l
- mov b, a ; b = no. of lines to move
- call moveblk
- mvi a, vnrows
- sub c ; c = no. of lines to clear
- mov h, a ; h = first row to clear
- call clrblk
- pop h
- mvi l, 0 ; move to beginning of line
- ret
-
- ; insert a line where the cursor is.
- insline mvi c, 1 ; and fall through
-
- ; insert <n> lines before the line containing the cursor.
- ; <n> is in C.
- insnlines push h
- mov a, h
- mov l, h
- add c ; other end of region to be inserted
- cpi vnrows
- jm insn1
- mvi a, vnrows
- insn1 mov h, a ; h = first dest, l = first source
- mvi a, vnrows
- sub h
- mov b, a ; b = no. of lines to move
- call moveblk
- mov h, l ; h = first row to clear
- call clrblk ; c = no. of lines to clear
- pop h
- mvi l, 0 ; move to beginning of line
- ret
-
- ; move a block of B lines from row L to row H.
- moveblk push h
- push d
- push b
- mov a, l
- cmp h
- jm movbrev
- movbfwd mov d, h
- mov h, l
- movbfwd1 mov a, b
- ora a
- jz movbret
- dcr b
- call movelin
- inr h
- inr d
- jmp movbfwd1
-
- movbrev mov a, h
- add b
- mov d, a ; d = h + b
- mov a, l
- add b
- mov h, a ; h = l + b
- movbrev1 mov a, b
- ora a
- jz movbret
- dcr b
- dcr h
- dcr d
- call movelin
- jmp movbrev1
-
- movbret pop b
- pop d
- pop h
- ret
-
-
- ; clear C lines starting at H.
- clrblk push h
- push d
- push b
- mvi l, 0
- clrblk1 mov a, c
- ora a
- jz clrblk2
- push b
- call cleol
- pop b
- inr h
- dcr c
- jmp clrblk1
- clrblk2 pop b
- pop d
- pop h
- ret
-
- ; move a line from row H to row D.
- movelin push h
- push d
- push b
- mvi l, 0
- mov e, l
- lxi b, voffset
- call addr
- push h
- dad b
- xchg
- call addr
- push h
- dad b
- xchg
- lxi b, vncols
- ; ldir
- db 0EDh, 0B0h ; Z80 instruction
- pop d
- pop h
- lxi b, vncols
- ; ldir
- db 0EDh, 0B0h ; Z80 instruction
- pop b
- pop d
- pop h
- ret
-
-
- ; get physical address from logical address.
-
- addr push b
- lda lastprow
- inr a
- add h
- cpi vnrows
- jc addr1
- sui vnrows
- addr1 mov c, a
- mvi b, 0
- mov a, l ; save col
- lxi h, rowtab
- dad b
- dad b
- mov c, a ; get col back
- mov a, m ; look row up in table
- inx h
- mov h, m
- mov l, a
- dad b ; add col
- pop b
- ret
-
- rowtab
- j set vncols
- i set 0
- rept vnrows
- dw vvideo + j * i
- i set i + 1
- endm
-
-
- ; fill the screen with the data in C, the attribute in B
- ; from x, y location HL through DE.
- fills push h
- call addr
- xchg
- call addr
- mov a, h
- cmp d
- jnz fills1a
- mov a, l
- cmp e
- fills1a xchg
- jnc fills1 ; J(area to fill doesn't wrap)
- push d
- push b
- lxi d, vvideo + vnrows * vncols - 1
- call fills2
- pop b
- pop d
- lxi h, vvideo
- fills1 call fills2
- pop h
- ret
-
- fills2 push b
- push h
- push d
- call fill ; fill in the data
- pop h
- pop d
- lxi b, voffset
- dad b
- xchg
- dad b
- pop b
- mov c, b
- call fill ; fill in the attributes
- ret
-
- fill mov m, c ; put down first copy
- mov a, e
- sub l
- mov c, a
- mov a, d
- sbb h
- mov b, a ; bc = de - hl = no. bytes to move
- ora c
- rz ; R(nothing to do -- only one byte to fill)
- mov d, h ; hl = source
- mov e, l
- inx d ; de = dest
- ; ldir
- db 0EDh, 0B0h ; Z80 instruction
- ret
-
-
- ; turn on escape mode.
- doesc mvi a, stesc
- sta escmode
- ret
-
-
- ;
- ; These are the various escape-states we can be in. They indicate
- ; what part of an escape sequence we've seen already.
- stesc equ 1 ; Esc
- stcprow equ 2 ; Esc Y
- stcpcol equ 3 ; Esc Y <row>
- stsetmode equ 4 ; Esc x
- stclrmode equ 5 ; Esc y
- stinsn equ 6 ; Esc l
- stdeln equ 7 ; Esc m
-
- ; We get here if we're in the middle of an escape sequence.
- ; escmode is in A.
-
- escseq push psw
- xra a
- sta escmode ; clear escape mode here, for convenience
- pop psw
-
- cpi stcprow ; row byte?
- jz docprow
- cpi stcpcol ; col byte?
- jz docpcol
- cpi stsetmode ; set-mode byte?
- jz dosetmode
- cpi stclrmode ; clear-mode byte?
- jz doclrmode
- cpi stinsn ; insert-n-lines byte?
- jz doinsn
- cpi stdeln ; delete-n-lines byte?
- jz dodeln
-
- mov a, c
- cpi 'L' ; insert (1) line?
- jz doinslin
- cpi 'M' ; delete (1) line?
- jz dodellin
-
- lda insdelcnt ; for anything else: do any saved
- ora a ; insertions/deletions first
- cnz doinsdel
-
- mov a, c
- cpi 'Y' ; cursor pos?
- jz docp
- cpi 'K' ; clear to end of line?
- jz docleol
- cpi 'E' ; home and clear screen?
- jz dohcl
- cpi 'H' ; home?
- jz dohome
- cpi 'J' ; clear to end of screen?
- jz docleow
- cpi 'A' ; cursor up?
- jz doup
- cpi 'B' ; cursor down?
- jz dodown
- cpi 'C' ; cursor right?
- jz doright
- cpi 'D' ; cursor left?
- jz doleft
- cpi '@' ; set char-insert mode?
- jz inschon
- cpi 'O' ; clear char-insert mode?
- jz inschoff
- cpi 'N' ; delete char?
- jz dodelchar
- cpi 'l' ; insert n lines?
- jz doinsnlins
- cpi 'm' ; delete n lines?
- jz dodelnlins
- cpi 'p' ; set inverse video?
- jz doinvon
- cpi 'q' ; clear inverse video?
- jz doinvoff
- cpi 'x' ; set mode?
- jz setmode
- cpi 'y' ; clear mode?
- jz clrmode
- cpi 'v' ; set wrap mode?
- jz dowrapon
- cpi 'w' ; clear wrap mode?
- jz dowrapoff
- cpi 'F' ; set graphics mode?
- jz dografon
- cpi 'G' ; clear graphics mode?
- jz dografoff
-
- escfail push b ; not any recognized command. display
- mvi c, esc ; sequence literally so user can see what
- call display ; happened
- pop b
- call display
- ret
-
- docp mvi a, stcprow ; cursor pos command: set esc mode
- sta escmode
- ret
-
- docprow mov a, c ; get row byte
- sui 32 ; subtract bias
- mov h, a
- mvi a, stcpcol ; set new esc mode
- sta escmode
- lda curoffp
- inr a ; cursor off during CP
- sta curoffp
- ret
-
- docpcol mov a, c ; get col byte
- sui 32 ; subtract bias
- mov l, a
- lda curoffp
- dcr a ; cursor back on (unless it was already off)
- sta curoffp
- ret
-
- docleol equ cleol
-
- dohcl equ hcl
-
- dohome equ home
-
- docleow equ cleow
-
- doup equ up
-
- dodown equ down
-
- doright equ right
-
- doleft equ left
-
- inschon mvi a, 1 ; set insert-char mode
- sta insmode
- ret
-
- inschoff xra a ; clear insert-char mode
- sta insmode
- ret
-
- dodelchar equ delchar
-
- doinslin lda insdelcnt ; accumulate insertions
- ora a
- push psw
- cm doinsdel ; do any saved deletions first
- pop psw
- inr a ; then increment insdelcnt
- sta insdelcnt
- ret
-
- dodellin lda insdelcnt ; accumulate deletions
- dcr a
- push psw
- cp doinsdel ; do any saved insertions first
- pop psw
- sta insdelcnt
- ret
-
- doinsnlins mvi a, stinsn ; set escmode to expect no. of insertions
- sta escmode
- ret
-
- dodelnlins mvi a, stdeln ; set escmode to expect no. of deletions
- sta escmode
- ret
-
- doinsn equ insnlines
-
- dodeln equ delnlines
-
- doinsdel lda insdelcnt ; do saved insertions/deletions
- ora a ; any to do?
- rz ; no: done
- push b
- jm doinsdel1 ; pos: insertions; neg: deletions
- mov c, a ; insertion was saved
- call insnlines ; do it
- jmp doinsdel2
- doinsdel1 cma
- inr a
- mov c, a ; deletion was saved
- call delnlines ; do it
- doinsdel2 pop b
- xra a
- sta insdelcnt ; clear saved count
- ret
-
- doinvon lda attrib ; inverse video on
- ori vinverse
- sta attrib
- ret
-
- doinvoff lda attrib ; inverse video off
- cma
- ori vinverse
- cma
- sta attrib
- ret
-
- setmode mvi a, stsetmode ; set escmode to expect mode to set
- sta escmode
- ret
-
- clrmode mvi a, stclrmode ; set escmode to expect mode to clear
- sta escmode
- ret
-
- ; come here with a mode to set in C
- dosetmode mov a, c
- cpi '5'
- jz setcuroff ; turn cursor off
- cpi '@'
- jnc setattr ; set display attributes
- cpi '*'
- jz setscrol ; set scroll mode
- push b
- mvi c, esc ; display unimplemented sequence, so
- call display ; user can see what happened
- mvi c, 'x'
- call display
- pop b
- call display
- ret
-
- setcuroff mvi a, 1 ; turn cursor off
- sta curoffp
- ret
-
- setattr call attrbit ; get bit for this attribute
- lda attrib ; or it into current attribute byte
- ora e
- sta attrib
- ret
-
- setscrol lda scrollp ; set scroll (Z-19 normal) mode
- ora a
- rnz ; already on
- mvi a, 1
- sta scrollp
- mvi h, vnrows - 1
- lda lastlrow ; get last logical row
- out vscrol ; make it last physical row
- sta lastprow
- ret
-
- ; come here with a mode to clear in C
- doclrmode mov a, c
- cpi '5'
- jz clrcuroff ; turn cursor back on
- cpi '@'
- jnc clrattr ; clear an attribute
- cpi '*'
- jz clrscrol ; turn roll mode back on
- push b
- mvi c, esc ; display unimplemented sequence
- call display ; so the user can see what happened
- mvi c, 'y'
- call display
- pop b
- call display
- ret
-
- clrcuroff xra a ; turn cursor back on
- sta curoffp
- ret
-
- clrattr call attrbit ; get bit for attribute
- lda attrib
- cma
- ora e ; clear it in current attr. byte
- cma
- sta attrib
- ret
-
- clrscrol lda scrollp ; set "roll" mode: no scrolling
- ora a
- rz ; scroll mode already off
- xra a
- sta scrollp
- lda lastlrow
- mov h, a
- mvi a, vnrows - 1 ; return screen to 0-origin
- out vscrol
- sta lastprow
- ret
-
- ; given command char in A, leaves attribute bit set in E
- attrbit sbi '@'
- jz attrbit1
- mov e, a
- mvi a, 2 ; start with 2
- attrbit2 rlc ; rotate left
- dcr e ; the right number of times
- jnz attrbit2
- mov e, a
- ret
- attrbit1 mvi e, 0FCh ; '@': all attributes
- ret
-
- dowrapon mvi a, 1 ; turn wrap mode (end-of-line wrapping) on
- sta wrapp
- ret
-
- dowrapoff xra a ; turn wrap mode (end-of-line wrapping) off
- sta wrapp
- ret
-
- dografon lda attrib ; turn graphics mode on (enable ROM)
- ani 0FDh
- sta attrib
- ret
-
- dografoff lda attrib ; turn graphics mode off (disable ROM)
- ori 2
- sta attrib
- ret
-
-
-
- ;
- ; Data section. If you want to change the default modes (e.g., to
- ; wrapping and scrolling), this is the place to do it. (Just change
- ; wrapp and scrollp.)
- ;
-
- curaddr dw 0 ; logical address of cursor
- lastprow db vnrows - 1 ; physical last row
- lastlrow db vnrows - 1 ; logical last row
- attrib db 3 ; character attribute byte
- escmode db 0 ; escape-sequence mode
- wrapp db 0 ; wrap at end of line?
- insmode db 0 ; insert-character mode
- scrollp db 0 ; scroll mode
- curoffp db 0 ; cursor-off mode
- insdelcnt db 0 ; insert/delete line count
-
- ; End of Z-19.ASM -- Z-19 Emulator for SSM VB3