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
/
BGH19SCR.LBR
/
H19SCRND.ZZ0
/
H19SCRND.Z80
Wrap
Text File
|
2000-06-30
|
25KB
|
1,167 lines
; Screen driver for Heath-19
; by Harold F. Bower and Bridger Mitchell
; 26 September 1986
;
.title 'H19SCRN bg ii Screen Driver'
;
; M80 or ZAS Z80 assembler.
;
FALSE equ 0
TRUE equ NOT FALSE
;
;.....
;Particular features of Heath-19 code:
;
; H19 sends a stream consisting of successive chars, with ESC sequences
; preceeding any change in reverse/normal video and graphics/normal
; character set. Several upgrade modes support a "native" mode with
; the 2-character ESC - char sequence replaced by 1 8-bit character.
; This code automatically detects and supports both modes FROM the
; terminal, and always sends in 7-bit mode TO the terminal, for complete
; compatibility.
;
Consta equ 0
Conin equ 0
Conout equ 0
Outch equ 0
Puts equ 0
Bwrch equ 0
Bflush equ 0
;
; ascii equates
;
BELL EQU 07H
BS EQU 08H
CR EQU 0DH
LF EQU 0AH
ESC EQU 1BH
SPACE EQU 20H
DEL EQU 7FH
;
; CUT command characters
;
HOME EQU 'H' ;home the cursor
MARK EQU 'X' ;set a mark
PASTE EQU 'P'-40H ;paste region at cursor
CANCEL EQU 'C'-40H ;cancel cut command
;
; TERMINAL-SPECIFIC EQUATES
;
;
; Cursor movement controls for Heath-19/89
;-----------------------------------------
;=== WordStar-like
;
WSLFT EQU 'S'-40H
WSRIT EQU 'D'-40H
WSUP EQU 'E'-40H
WSDWN EQU 'X'-40H
WSINS EQU 'V'-40H
WSDEL EQU 'Y'-40H
;
;=== ESCape sequence arguments
;
LEFT EQU 'D'
RIGHT EQU 'C'
UP EQU 'A'
DOWN EQU 'B'
INSERT EQU 'L'
DELETE EQU 'M'
;
;
; Heath-19 screen parameters
;
NCOLS EQU 80
NROWS EQU 25
NROW24 EQU 24 ;# rows excluding status line
;
SCRSIZ EQU NCOLS*NROWS
CRBIAS equ 20H ; Bias for cursor positioning
;
; Heath-19 Escape argument characters
;
CLRSCR equ 'E' ; Clear screen & Home cursor
GRON equ 'F' ; Graphics mode on
GROFF equ 'G' ; Graphics mode off
REVON equ 'p' ; Reverse video mode on
REVOF equ 'q' ; Reverse video mode off
SNDPAG equ '#' ; Send lines 1-24 from screen
SND25 equ ']' ; Send line 25 from screen
SNDCUR equ 'n' ; Send Cursor position as <ESC Y r c>
;
; Flag bits in status register
;
TOSCR$ equ 0 ; Send to screen
GRAPH$ equ 1 ; Graphics sequence active
REV$ equ 2 ; Reverse video sequence active
ESCMOD equ 3 ; ESCape sequence
;
;=========================
;
org 3F80H ; Module name sector
;
;
db 'Heath 19/89 26 Sept 86',0
;
;-------------------------
;
org 4000H
;
;------------------------------------------------------------
;
Start:
;
; Start of Screen Module. Assemble to run at 4000h.
;
;***** MODULE ENTRY HEADER
;
; EXTERNAL ADDRESSES, supplied by loader
;
JJcons: jp Consta ; BIOS constat
JJconi: jp Conin ; BIOS conin
JJouta: jp Outch ; A to conout, preserving BC,DE,HL
JJputs: jp Puts ; HL-string to conout, NUL/bit-7 term.
; preserving BC,DE,HL
JJbrdc: jp 0000 ; Buffered read char from cut-swp
JJbwrc: jp Bwrch ; Buffered write char to cut-swp
JJbflu: jp Bflush ; Flush (write) buffer
;
; INTERNAL ENTRY POINTS
;
Savscr: jp Savpag ; Save screen
Resscr: jp Respag ; Restore saved screen
Lastnb: jp Lstnbl ; Last non-blank char in rows 1-24
Dmpchr: jp Retnch ; Return next screen char
Dmpcur: jp Retncu ; Return buffer cursor
Dmpatt: jp Retnat ; Return next screen attribute
Setmrk: jp Stmrks ; Set region marks, move cursor
Cutrg: jp Docut ; Cut region
Pastrg: jp Dopaste ; Paste region
Ininpd: jp Ininot ; Initialize jotpad
Putnpd: jp Putnch ; Put char to jotpad
;
;========================================
;
Ininot: ; << Generic >>
;
; Initiate Jotpad - clear screen, print banner.
;
ld hl,zbanner
jr JJputs
;
;========================================
;
Retncu: ; << Generic >>
;
; Return buffer cursor as row/col.
;
; RET: D = binary row, E= binary col
; L = ascii row, H = ascii col (for shld ...)
;
ld hl,(bcursor)
;
; Convert offset to col/row.
; EXIT: D = binary row, E = binary col
; H = ascii col, L = ascii row <-- NOTE ORDER
;
Off2cr: ld b,0 ; Convert to row,col
ld de,-NCOLS
Off2c1: add hl,de
jr nc,Off2c2
inc b ; Increment row count
jr Off2c1
Off2c2: ld de,NCOLS
add hl,de
ld a,l ; Col
ld e,a ; Binary col in E
ld d,b ; Binary row in D
add a,CRBIAS ; + bias
ld h,a ; H = ascii col
ld a,b ; Row
add a,CRBIAS ; + bias
ld l,a ; L = ascii row
ret
;
;========================================
;
Dopaste: ; <<Generic >>
;
; Paste the last-cut region onto active screen at the current cursor.
; For H-19, only use lines 1-24 due to scroll problem in line 25,
; and to not paste to the last character position in line 24 for the
; same reason.
;
; 1. Get previously-cut region from external routine
; 2. Send chars to screen, avoiding boundary overflows.
;
; 'savpag' not needed if terminal supports 'send cursor address'
;
; call Savpag ; Get current screen,
; in order to find cursor
ld b,4 ; Read 4 data bytes
Dopas0: push bc
call JJbrdc
pop bc
djnz Dopas0
;
ld b,a ; 4th byte is # rows
push bc
call Crs2hl ; current cursor's row/col to hl
pop bc
;
; Loop over rows
;
Prowlp: push bc
push hl
ld e,l ; E = col no.
push de
call Stcrshl ; Set cursor at H,L
Pcollp: call JJbrdc ; Read char from cut-swp
cp CR
jr z,Prend
ld c,a ; Save char
pop de ; Check for off screen
ld a,e
cp NCOLS
inc e
push de ; row/col to stack
call c,Sendc ; to conout, unless off edge
jr Pcollp
;
Prend: pop de ; Clear row/col
pop hl
pop bc
inc h ; Bump row
ld a,h ; Check for off bottom of screen
cp NROW24 ; Use NROWS if 25th line scrolls
jr nc,Pxit
djnz Prowlp
Pxit: xor a
ret
;
;========================================
;
Docut: ; << Generic >>
;
; Cut rectangular region defined by keypresses.
; 1. Parse keypresses to move cursor and mark corners.
; Highlight region as cursor is moved.
;
; NOTE: The last char in row 24 of the Heath-19 is not
; marked due to scroll effects if line wrap is ON.
;
; 2. Send the marked region, row-wise to external routine.
; Append CR after each row.
;
; Data structure is:
; size (word)
; # columns (byte)
; # rows (byte)
; row 1
; CR
; row 2
; CR
; ....
;
xor a
ld (mrkcnt),a ;init for next time
;
; Set ctcols = # cols, ctrows = # rows
; (assumes mark2 is SE of mark1)
;
Cornrs: ld de,(mark1)
ld hl,(mark2)
ld a,h ; # rows = 1 + mark2row - mark1row
inc a
sub d
ld h,a
ld a,l ; # cols = 1 + mark2col -mark1col
inc a
sub e
ld l,a
ld (ctcols),hl
;
; Cut rectangle [mark1...mark2] & copy to buffer
; Append CR at end of each row
;
ex de,hl
push hl ; Mark1
call Wrpara ; Write parameters
pop hl ; Mark1
call Rc2off ; Convert to screen addr
ld a,(ctrows) ; Get # rows
ld b,a
;
; write the cut region to external buffer
;
DCrwlp: push bc ; (+1
push hl ; (+2
ld de,buf ; Fetch from screen buffer
add hl,de
;
; write 1 row of cut region to external buffer
;
ld a,(ctcols)
ld b,a ; B = # cols
call Bwrthl
ld c,CR ; Append CR to each row
call JJbwrc
;
pop hl ; (+1
pop bc ; (+0
ld de,NCOLS ; Bump to next row
add hl,de
djnz DCrwlp ; and loop
jp JJbflu ; Flush the write buffer
;
; Write parameters: size, # cols, # rows to swp file
; DE contains CTCOLS on entry
;
Wrpara: ld b,d ; # rows
ld d,0
inc e ; +1 for CR
ld hl,0 ; accum.
Wrpar0: add hl,de
djnz Wrpar0
ld (ctsize),hl
ld b,4 ; Write 4 bytes of parameters
ld hl,ctsize
;
; Buffered write B chars at HL
;
Bwrthl: push bc
push hl
ld c,(hl)
call JJbwrc
pop hl
pop bc
inc hl
djnz Bwrthl
ret
;
;========================================
;
Lstnbl: ; << Generic >>
;
; Find last non-blank line (1-24 only) in current scr buffer.
; Graphics characters are considered blanks. 8-bit values
; (reverse video) are masked to see if they are valid chars.
; If B = 0FF, save screen first.
;
; RETURN: H = row, L = col of last non-blank char in rows 1-24
;
inc b
call z,Savpag
ld bc,NROW24*100H+NCOLS ; B=# rows, C=# cols
ld de,buf
ld hl,0
Lstlp: ld a,(de)
and 7FH ; Turn off any reverse video
cp SPACE+1 ; Don't count cntl chars or SPACE
jr c,Lst1
cp DEL ; or DEL or graphics 8-bit
jr nc,Lst1
ld (savrc),hl
Lst1: inc de
inc l
dec c
jr nz,Lstlp ; Loop over cols
inc h
ld l,c ; 0
ld c,NCOLS
djnz Lstlp ; Loop over rows
savrc equ $+1
ld hl,0000 ; HL = last non-blank
ret
;
;------------- Generic Support Routines --------------
;
Xring: ld c,BELL
;
; send C to screen, exit Z, no CY
;
Sendc: ld a,c
; send A to screen, exit Z, no CY
; (this will scroll, however!)
;
Send: call JJouta
xor a ; Z, no CY
ret
;
;============================================
; E N D O F G E N E R I C C O D E
;============================================
;
Putnch: ; << Specific >>
; (Was generic til cursor controls added)
;
; Put char in A to jotpad (screen)
; Convert CR to CRLF, DEL to rubout, 8-bit codes
; to ESC-n sequences.
;
cp CR
ld hl,zcrlf ; Convert CR to CR,LF
jp z,JJputs
cp DEL
ld hl,zrub
jp z,JJputs
bit 7,a ; 8-bit code?
jr nz,Wrt8th
;
cp WSLFT ; Use WS-like commands?
jr z,Wrtlef
cp WSRIT
jr z,Wrtrit
cp WSUP
jr z,Wrtup
cp WSDWN
jr z,Wrtdwn
cp WSDEL
jr z,Wrtdel
cp WSINS
jp nz,JJouta
; ...fall thru
ld a,'L' ; ESC code for Insert line
jr DoWrt
;
Wrtlef: ld a,'D' ; ESC code for Left curs
jr DoWrt
;
Wrtrit: ld a,'C' ; ESC code for Right curs
jr DoWrt
;
Wrtdwn: ld a,'B' ; ESC code for Down curs
jr DoWrt
;
Wrtup: ld a,'A' ; ESC code for Up curs
jr DoWrt
;
Wrtdel: ld a,'M' ; ESC code for Delete line
; ...and fall thru...
Wrt8th: and 7FH ; Mask 8th bit and send as ESC-n
DoWrt: jp Jptesc
;
;===========================================
;
Stmrks: ; << Specific >>
;
; Move cursor and set marks. Return CY clear until exit.
; NOTE: For Heath-19, the last character in line 24 is
; NOT highlighted since that causes the entire
; screen to scroll if Line Wrap is ON.
;
; 1. move cursor, until:
; 2. 'X' = set 1st mark
; turn on hiliting, set mark, keep cursor at mark
; 3. move cursor right/down only
; 4. 'X' = set 2nd mark
; turn off hiliting, set 2nd mark
; exit CY (done)
; 5. cntl-C = CANCEL.
; turn off hilighting, set CY, exit
;
;
cp ESC
jr nz,Stmrk0 ; Continue if not Escape
ld a,0FFH ; ..else set flag
ld (mrkesc),a
xor a ; Return for next char
ret
;
Stmrk0: bit 7,a ; Is it an 8-bit command?
jr nz,Stmrk1 ; ..do short jump if so.
push af
ld a,(mrkesc) ; Is this ESC argument?
or a
ld a,0 ; (always reset flag)
ld (mrkesc),a
jr z,Stmrk2 ; Jump if not ESC argument
pop af
Stmrk1: and 7FH ; Mask MSB in case 8-bit code
cp LEFT ; ..process argument characters
jp z,Goleft
cp UP
jp z,Goup
cp RIGHT
jp z,Gort
cp DOWN
jp z,Godn
xor a ; Clear for next char..
ret ; ..if not one of these
;
Stmrk2: pop af
cp CANCEL
jr z,Abort
cp WSLFT
jp z,Goleft
cp WSUP
jp z,Goup
cp WSRIT
jp z,Gort
cp WSDWN
jp z,Godn
cp CR
jr z,StmrkA
and 5FH ; Convert to Ucase
cp MARK
jr z,StmrkA
cp HOME
jr z,Gohome
xor a ;no action
ret
;
StmrkA: ld hl,mrkcnt ;if no mark yet set
ld a,(hl)
or a
ld (hl),1
jr z,Mk1 ;..set mark1
call Mk2 ;else set mark2
Mrkxit: xor a
ld (mrkcnt),a ;init for next time
scf ;CY = all done
ret
;
abort: call Normal ;restore normal video
ld a,CANCEL
jr Mrkxit
;
;-------------------------------------------
;
; Set 1st mark, turn on rev. video, don't move cursor
;
Mk1: call Crs2hl
ld (mark1),hl
ld (mark2),hl
ld (curcol),hl ; L -> curcol, H -> currow
push hl
call Revers ; Reverse video on
;
; Set single character under cursor to reverse video
;
pop hl ; Mark1
ld a,1 ; Reverse 1 char
ld (colct),a
ld (rowct),a
push hl
call Showro
pop hl
jp Stcrshl ; Set cursor to start
;
; Set 2nd mark, restore normal video, set CY
;
Mk2: call Crs2hl
ld (mark2),hl
call Normal ; Restore normal video
scf ; CY = all done
ret
;
;--------------------------------------------
; Home cursor if no mark yet set
;
Gohome: ld c,'H' ; Convert to video driver's cntl char
jr Ckmcnt
;
; Move cursor up one line if no mark yet set
;
Goup: ld c,'A' ; 7-bit code for UP
jr Ckmcnt
;
; Move cursor left if no mark yet set
;
Goleft: ld a,'D' ; 7-bit code for LEFT
Mvcurs: ld c,a
Ckmcnt: ld a,(mrkcnt) ; Send cursor-move char
or a
ret nz ; ..unless mark1 already set
ld a,c
jp Jptesc ; ..else send ESC then char in A
;
; Move cursor right setting reverse video if mark already set
;
Gort: ld a,'C' ; 7-bit code for RIGHT
call Jptesc ; Position cursor
ld a,(mrkcnt)
or a ; Quit here if no mark set
ret z
;
; Hilite marked column if not already at right limit
; Set cur at toprow, next col
; Send partial column
; colcnt++
;
Gort1: ld hl,mark2
ld a,NCOLS-2
cp (hl) ; Ring bell if already in last column
Jcring: jp c,Xring
inc (hl) ; Bump 2nd mark-row
ld hl,curcol
inc (hl) ; Bump column
ld l,(hl)
ld a,(mark1+1) ; Top row
ld h,a ; H = row, L = col to hilite
rowct equ $+1
ld b,00
;
; Loop over each row in cut region
;
Gorlp: push bc
push hl ; Save binary row/col
ld a,1 ; Display 1 char in each row
call Showhi
pop hl
pop bc
inc h ; Next row
djnz Gorlp
ld hl,colct ; Prepare to bump col cnt & exit
jr Inrmbs
;
; Move cursor down setting reverse video if mark set
;
Godn: ld a,'B' ; 7-bit code for DOWN
call Jptesc ; Move cursor down
ld a,(mrkcnt)
or a
ret z ; quit here if no marks
;
; Set reverse video on marked row if not already at bottom
; set cur at next row, left col
; send partial row
; rowcnt++
;
Godn1: ld hl,mark2+1 ; Row
ld a,NROWS-2
cp (hl) ; Ring bell if on bottom line
jr c,Jcring
inc (hl) ; Bump 2nd mark-col
ld hl,currow ; Bump row
inc (hl)
ld h,(hl)
ld a,(mark1) ; Left col
ld l,a ; H = row, L = col for row to hilite
call Showro ; Display 1 cut row
ld hl,rowct ; Bump row cnt
Inrmbs: inc (hl) ; and exit
ld hl,(curcol)
jp Stcrshl
;
;--------------
; Fetch A chars at H=binary row, L=binary col from buffer.
; Put chars to screen, setting REVERSE VIDEO attribute.
; All registers used.
;
; ENTER: H = binary row, L= binary col
; EXIT: CY flag clear
;
Showro:
colct equ $+1
ld a,00
;
Showhi: push af
ld a,h ; Are we on bottom line?
cp NROWS-2
jr nz,Show1 ; ..jump if not
pop af
push af ; Restore char count
add a,l ; ..add to start column
cp NCOLS ; Will it end in last column?
jr c,Show1 ; ..jump if not
pop af
dec a ; Else let it end in next-to-last
jr z,Show2 ; ..Quit if char cnt = 0
push af
Show1: push hl
call Stcrshl ; Set cursor to start marked area
pop hl
call Rc2off ; Convert cursor to offset
ld de,buf ; ..add buffer start address
add hl,de
pop af ; # chars
ld b,a
Showlp: ld c,(hl) ; Fetch char from buffer
push hl
push bc
call Sendc ; Put to screen
pop bc
pop hl
inc hl
djnz Showlp
Show2: or a ; Clear CY
ret
;
;========================================
;
Retnch: ; << Specific >>
;
; Return next screen char from buffer.
;
; ENTER: D = row, E = col
; B = FF ==> read screen
; C = FF ==> set bufptr
; EXIT: A = char, CY set if good
; DE -> row,col of next char, HL -> buf of next char
; CY clear if out of range
;
; This routine can be called to get successive chars from
; buffer as long as caller preserves hl,de and sets b=c=0.
;
xor a
call Stdump
ret nc
ld a,(hl) ; Get char
inc hl ; bump bufptr
ret
;
;--------------------
;
; ret: NC if out of range
; else hl-> buffer char
;
Stdump: inc b
jr nz,Stdum0
push bc ; B = FF ==> Read screen
push de
push hl
call Savpag
pop hl
pop de
pop bc
Stdum0: inc c
jr nz,Conv4
;
; ENTER: D = row, E = col
; SET: HL -> buffer address, CY set, preserve DE
; RETURN: CY clear if error (off screen)
;
ld a,d ; C = FF ==> set bufptr
cp NROWS
jr nc,ConBAD
ld a,e
cp NCOLS
jr c,ConvOK
ConBAD: xor a ; Out of range, ret NC
ret
;
ConvOK: push de ; Preserve col/row
ex de,hl
call Rc2off ; Convert to Offset in HL
ld de,buf ; ..from buffer base
add hl,de
pop de ; ..restore col/row
; ..fall thru..
Conv4: inc de ; Bump col
ld a,e
cp NCOLS
ret c
ld e,0 ; End of row, set col = 0
inc d ; and bump row
ld a,d
cp NROWS
ret ; NC if out of range
;
;========================================
;
Retnat: ; << Specific >>
;
; Return next screen attribute from buffer.
; NUL FUNCTION for Heath-19.
;
; ENTER: D = row, E = col
; B = FF ==> read screen
; C = FF ==> set bufptr
; EXIT: A = attr, CY set if good
; DE -> row,col of next char, HL -> buf of next char
; RETURN: CY clear if out of range
;
xor a ; Clear CY
ret
;
;========================================
;
Savpag: ; << Specific >>
;
; Save screen to buffer.
;
;; ld hl,Zheath ; If needed, put in ANSI mode
;; call JJputs
call Getcu ; Get ASCII row/col cursor
ld (colrow),hl
call Get124
jr Get25
;
; Get lines 1-24
;
Get124: ld a,SNDPAG ; Tell terminal to send 1-24
call Jptesc
ld hl,buf
call Getrgn
ld (ptr25),hl
ret
;
; Get 25th line
;
Get25: ld hl,z25on ; Turn on status line
call JJputs
ld a,SND25 ; Tell terminal to send row 25
call Jptesc
ld hl,(ptr25)
; ...fall thru...
;
; Get region to the HL buffer
;
Getrgn: ld c,0
Getplp: push hl
push bc
call JJconi ; Get a char
pop bc
pop hl
cp ESC ; Is this an escape?
jr z,Getpl1
cp CR ; Is this the end?
ret z
bit ESCMOD,c ; Was last char=ESC?
jr nz,Getpl2 ; ..jump if so
bit GRAPH$,c
jr z,Getplr ; Jump if not graphic
sub 5FH ; make binary
res 7,a ; 5E-->7FH
ld (hl),a
;
Getplr: bit REV$,c
jr z,Getpl0 ; Jump if not reverse video
set 7,a
Getpl0: ld (hl),a
inc hl ; Bump ptr..
jr Getplp ; ..loop
;
Getpl1: set ESCMOD,c ; Flag next as argument
jr Getplp
;
Getpl2: cp REVON
jr z,Ron
cp REVOF
jr z,Roff
cp GRON
jr z,Gon
cp GROFF
jr nz,Getpl3 ; Reset esc & loop
res GRAPH$,c
jr Getpl3
;
Ron: set REV$,c
jr Getpl3
;
Roff: res REV$,c
jr Getpl3
;
Gon: set GRAPH$,c
Getpl3: res ESCMOD,c
jr Getplp
;
;========================================
;
Respag: ; << Specific >>
;
; Restore saved screen from buffer.
; NOTE: For the Heath-19, the last position in row 24
; is NOT restored since that causes the entire
; screen to scroll if Line Wrap is ON.
;
ld a,CLRSCR ; Clear screen
call Jptesc
call put124 ; Restore rows 1 thru 24..
call put25 ; ..and 25
ld hl,zcurs ; Restore cursor
call JJputs
call Nogrph ; Finish with graphics OFF..
jp Normal ; ..and return to normal video
;
; To screen, line 25
;
Put25: ld hl,y0row ; Set cursor position for..
ld (hl),NROWS-1+CRBIAS ; ..row 25, col 0
dec hl ; Point to string start
dec hl
call JJputs ; Position cursor
ld a,1 ; Send 1 line
ld hl,(ptr25)
jr Putsc1
;
; To screen, lines 1-24
;
Put124: ld hl,y0row ; Set cursor position for..
ld (hl),1-1+CRBIAS ; ..First row, col 0
dec hl ; Point to string start
dec hl
call JJputs ; Position cursor
ld hl,buf
ld a,24 ; Send 24 lines
Putsc1: ld c,0 ; Normal video, no graphics
;
Putlp: ld (lincnt),a ; Store number of lines left
ld b,NCOLS ; ..set # of chars per line
ld a,(y0row)
cp NROW24-1+CRBIAS ; If this is line 24...
jr nz,Putlp0
dec b ; ..don't write in last position
Putlp0: push hl ; Save buffer address
call Sndprc ; Send processed char..
call Send ; ..to screen
pop hl
inc hl
djnz Putlp0 ; Loop on line
push hl
ld hl,y0curs ; Return to left col at each line end
call JJputs
pop hl
ld a,(lincnt)
dec a ; Any more lines?
jr z,PutlpZ ; ..jump if not
push af
push hl
ld hl,y0row ; Position to next line down
inc (hl) ; ..by bumping cursor address
dec hl ; Back to string start
dec hl
call JJputs ; ..and position
pop hl
pop af
jr Putlp
;
PutlpZ: ld (ptr25),hl
call Ptgrof
jp Normal ; Set screen to normal
;
; Process character sending appropriate ESCape sequences
; and setting flags.
;
Sndprc: ld a,(hl)
push af
bit 7,a ; Check for reverse video
jr z,Sndpr0 ; ..jump if not
call Putrev
pop af
and 7FH ; Restore char masking MSB
push af
jr Sndpr1
;
Sndpr0: bit REV$,c ; See of flag on..
call nz,Ptroff ; ..and reset if so
pop af
push af
;
Sndpr1: cp ' '
jr c,Putgph ; Jump if graphic
cp DEL ; 7FH is also graphic
jr z,Putgph
bit GRAPH$,c
call nz,Ptgrof
pop af
ret
;
Putgph: bit GRAPH$,c
call z,Ptgron
pop af
add a,5FH ; Make printable char
and 7FH ; ..mask off MSB
ret
;
; Set to reverse video mode if necessary
;
Putrev: bit REV$,c
ret nz ; ..already there, return
; ..else fall thru..
;
; Update the flag
;
Putron: set REV$,c
Revers: ld a,REVON ; Turn on reverse video
jr Jptesc
;
Ptroff: res REV$,c
Normal: ld a,REVOF ; Turn off reverse vidso
jr Jptesc
;
Ptgron: set GRAPH$,c
ld a,GRON ; Turn on graphics
jr Jptesc
;
Ptgrof: res GRAPH$,c
Nogrph: ld a,GROFF ; Turn off graphics
Jptesc: push af ; Send ESCape followed by char in A
ld a,ESC
call Send
pop af
jp Send
;
;---------- Cursor Conversion Routines ----------
;
; Convert binary row/col to relative offset
; Enter: H=binary row, L=binary col
; Exit: HL = Binary offset (HL = row * NCOLS + col)
; Uses: BC, DE, HL
;
Rc2off: ld b,h ; B = row
ld c,l ; C = col
ld hl,0
inc b
ld de,NCOLS
jr Rc2bot
Rc2of0: add hl,de ; Rows * NCOLS
Rc2bot: djnz Rc2of0
add hl,bc ; Add col
ret
;
;============ Cursor Positioning Routines ==============
;
; Set cursor on screen.
; Enter: H=binary row, L = binary col
;
Stcrshl: call Rc2off
; ...fall thru...
;
; Set cursor on screen by direct cursor addressing.
; Enter: HL = cursor offset relative to 0000
;
Stcrs: call Off2cr ; Convert from offset to ascii col/row
ld (colrow),hl ; Put ascii col/row into string
ld hl,zcurs ; Send set-cursor string
jp JJputs
;
;-------------
;
; Get current cursor position.
; Exit: H=binary row, L=binary col
; Uses: A, HL
;
Crs2hl: call Getcu ; Get cursor by querying terminal
ld a,h ; Convert ASCII to binary..
ld h,l ; ..and reverse order
sub CRBIAS
ld l,a
ld a,h
sub CRBIAS
ld h,a
ld (bcursor),hl ; Save it
ret
;
;-------------
;
; Get cursor position, checking for 8-bit mode
; Exit: HL Contains ASCII H=col, L=row
; Uses: A, HL
;
Getcu: ld a,SNDCUR
call Jptesc
call JJconi
bit 7,a ; If 8-bit mode, skip
call z,JJconi
call JJconi ; Get row
ld l,a
push hl
call JJconi ; Get col
pop hl
ld h,a
ret
;
;******************************************
;
; DATA AREA
;
; cut-region data
;
ctsize: dw 0 ; (# cols + 1) * (# rows)
;
ctcols: db 0 ; # cols in cut region (excl. CR), A PAIR
ctrows: db 0 ; # rows
;
ptr25: dw 00 ; Pointer to 25th line
lincnt: db 0 ; Line counter for put-page
;
; mark-region data
;
mrkcnt: db 0
;
curcol: db 0 ; A PAIR
currow: db 0
;
mark1: dw 0 ; Binary row,col of upperleft mark
mark2: dw 0 ; Lower right mark
;
mrkesc: db 0 ; Flag for ESC sensing
;
ZRUB: DB BS,SPACE,BS+80H ; Rub-out previous char
;
;****************************************
;
; TERMINAL-SPECIFIC data
; Heath-19
;
; ...Cursor lead-in and command strings
;
zcurs: db ESC,'Y' ; Set cursor to..
colrow: db ' ' ; row,col - modified in-line
db 0 ; Must have following NUL
;
y0curs: db ESC,'Y' ; Working positioning sequence
y0row: db 20H,20H!80H ; Cursor at line nn, col 0
;
z25on: db ESC,'x','1'!80H ; enable 25th line
;
; ...Other sequences for Heath-19
;
;z8bits: db ESC,'e','C'!80H ; UNUSED. Put in 8-bit mode
;
zheath: db ESC,'[','?','2','h' ; Enter Heath mode
;
;================================
;
; NOTEPAD BANNER
;
; 1. Clear screen.
; 2. Remind user of usage, to extent space is available.
;
zbanner: db ESC,CLRSCR ; Clear screen HEATH-19-SPECIFIC
;
db 'JOT: <SUSPEND> = exit, '
db '^V = ins line, ^Y = del line',CR,LF
db ' ^E - up, ^X - down, '
db '^S - left, ^D - right'
;
zcrlf: db CR,LF!80H
;
codlen equ $-start ; Length of code
;
;++++++++++++++++++++++++++++++
;
; SCREEN BUFFER STRUCTURE
;
; The rest of the 4K block is available for the screen image and other data.
;
xbreq equ 2 + nrows*ncols
;
; put buffer at end of 4K area, to just fit
;
bstart equ [start + 400H] + [3*400h-xbreq]
;
short equ start+codlen-bstart
xfree equ - short
;
IF [SHORT]
defb '[07]Code overflows buffer!'
ENDIF
;
; addresses:
;
bcursor equ bstart ; Cursor location in saved screen
buf equ bcursor+2 ; Start of screen buffer
;
; Buffer uses (25 lines x 80 chars)
;
bufend equ buf+NROWS*NCOLS
;
;
end JJcons
eath mode
;
;============================