jmpif macro #j,#k ;SHORT JUMP cp #j JR z,#k endm ; LJMPIF macro #j,#k ;LONG JUMP cp #j jp z,#k endm colcp macro #x ld a,l and .NOT.(colum-1) cp #x endm ascii equ 7FH ; ascii mask greek equ 1FH ; greek character set mask base equ 03000H ;start of video ram linlen equ 80 ;logical line length colum equ 128 ;physical line length lines equ 24 ;lines per display line1 equ base ;start of first line line2 equ base+colum ;start of second line nlast1 equ base+(lines-2)*colum ;start of next to last line last1 equ base+(lines-1)*colum ;start of last line last equ (base+lines*colum)-1 ;last char of display bitport equ 1CH ;system bit port frsesc equ '@' ; first charater used in esc start ESCLEN equ $+BIAS DB 0 ; expected length of esc string ESCSTR equ $+BIAS DS 10 ; esc string storage (w/o esc) ESCPTR equ $+BIAS DW escstr ; pointer into string for storage CURSOR equ $+BIAS DW LINE1 ; address of cursor LEADFLG equ $+BIAS DB 0 ; counter to position in esc string CHRMSK equ $+BIAS DB 0 ; ascii/greek mask CURCHR equ $+BIAS DB (9fh) ; cursor character when on blank OLDCHR equ $+BIAS DS 1 ; storage for character under cursor KBDST EQU 7 KBDDAT EQU 5 TBE EQU 4 KBDOUT equ $+BIAS IN A,(KBDST) AND TBE JP Z,KBDOUT LD A,C OUT (KBDDAT),A RET vidinit equ $+BIAS call clear ; clear screen and home cursor xor a ld (leadflg),a ; no leadin sequence ld a,ascii ; set ascii mask ld (chrmsk),a ret vidrst equ $+BIAS call clrcur in a,bitport res 7,a out bitport,a ; video bank ret ; all done ; this routine is entered with the character to print in reg c vidout equ $+BIAS ld a,c and 7fH ; make 7 bit ld c,a ld a,(leadflg) ; processing a lead-in sequence? or a jp nz,leadin ld a,c cp space jp c,docont ; if char < space then is control cp DEL jp nc,noprnt ; if char >= DEL then don't do it jp doprnt ; printable ascii docont equ $+BIAS cp bell ; ring bell no display JP nz,nobell ld c,04H ; kbd bell code jp kbdout ; ring bell nobell equ $+BIAS ld a,c ; char to print LJMPIF lf,lfcd ; line feed (down arrow) LJMPIF cr,return ; return ljmpif bs,back ; back space (left arrow) LJMPIF esc,doesc ; lead-in LJMPIF tab,dotab noprnt equ $+BIAS ret doprnt equ $+BIAS cp 60H ; lower case? JP c,vout ld a,(chrmsk) ; if lower do we print greek chr set? and c vout equ $+BIAS push af call clrcur ; clear (remove) cursor pop af ld (hl),a ; display character inc hl ; inc cursor position ld a,l ; off end of line? and colum-1 cp linlen ; logical line length jp c,finsh ; not past colum-1 dec hl ; move back (don't wrap) jp finsh ; handle tabs as every 8 columns or end of line ; dotab equ $+BIAS call clrcur ld a,l and 0f8H ; get column no mod 8 add a,8 ; add 8 (for tab) ld l,a and colum-1 cp linlen jp c,finsh ; if not past eol then done ld a,l and colum ; begin of line or linlen-1 ; end of line ld l,a jp finsh ; ; process a line feed (cursor down) ; lfcd equ $+BIAS call clrcur ; clear (remove) cursor push hl ; save current position ld de,colum ; move down one line add hl,de push hl ; save new cursor position or a ; clear carry ld de,last+1 ; last char of display + 1 sbc hl,de ; if carry not set we are off display pop hl ; hl = new pos pop de ; de = old pos jp c,finsh ex de,hl push hl ; save old position call scrlup ; scroll the screen up pop hl ; restore old position jp finsh scrlup equ $+BIAS ld b,lines-1 ; number of lines to scroll ld hl,line2 ld de,line1 upscr1 equ $+BIAS push bc ; save line count ld bc,linlen ; logical line length ldir ; scroll one line ld bc,colum-linlen ; to beginning of next line add hl,bc ex de,hl add hl,bc ex de,hl pop bc ; line count djnz upscr1-BIAS ; do another line ld hl,last1 ; to last line of display jp cleols ; clear it scrldn equ $+BIAS ld b,lines-1 ; number of lines to scroll ld hl,nlast1 ld de,last1 dnscr1 equ $+BIAS push bc ; save line count ld bc,linlen ; logical line length ldir ; scroll one line ld bc,-colum-linlen ; to beginning of prev line or a ; clear carry flag add hl,bc ex de,hl or a add hl,bc ex de,hl pop bc ; line count djnz dnscr1-BIAS ; do another line ld hl,line1 ; to first line of display jp cleols ; clear it ; ; back space the cursor ; back equ $+BIAS call clrcur ; clear (remove) cursor ld a,l ; is column # 0? and .LOW..NOT.colum jp z,finsh ; at beginning of line dec hl ; back space jp finsh ; ; move cursor foward ; fowrd equ $+BIAS call clrcur ; clear (remove) cursor ld a,l ; right most column? and colum-1 cp linlen-1 jp nc,finsh inc hl ; bump cursor address jp finsh ; ; move cursor up one line ; up equ $+BIAS call clrcur ; clear (remove) cursor push hl ; save current position ld de,-colum ; move up one line add hl,de push hl ; save new cursor position or a ; clear carry ld de,line1 ; first char of display sbc hl,de ; if carry set we are off display pop hl ; hl = new pos pop de ; de = old pos jp nc,finsh ex de,hl jp finsh ; ; process a cursor down ; dn equ $+BIAS call clrcur ; clear (remove) cursor ld de,colum ; to next line, same column add hl,de ld de,last ; off display memory? ld a,d cp h jp c,sty ld a,e cp l jp nc,finsh sty equ $+BIAS ld de,colum or a sbc hl,de jp finsh ; ; reverse line feed ; rlf equ $+BIAS call clrcur ; clear (remove) cursor push hl ; save current position ld de,-colum ; move up one line add hl,de push hl ; save new cursor position or a ; clear carry ld de,line1 ; first char of display sbc hl,de ; if carry set we are off display pop hl ; hl = new pos pop de ; de = old pos jp nc,finsh ex de,hl push hl ; save old position call scrldn ; scroll the screen down pop hl ; restore old position jp finsh ; ; clear screen ; clear equ $+BIAS call clrcur ; clear (remove) cursor push hl ld hl,line1 ; clear screen ld de,line1+1 ld bc,last-base ld (hl),space ldir pop hl jp finsh ; ; home cursor ; hmcsr equ $+BIAS call clrcur ; clear (remove) cursor ld hl,line1 ; line one of display jp finsh ; ; clear to end of screen ; cleos equ $+BIAS call clrcur ; clear (remove) cursor push hl ;save current position call cleols ld de,colum ld a,l and colum ;begining of this line ld l,a add hl,de ;begining of next line ld a,03CH ;after last line now ? cp h ;h holds page (3B) is last line JP z,cleos1 ;yes so no more to blank get out ; ld e,l ; copy hl to de ld d,h or a ; clear carry ld hl,last ; last pos of screen sbc hl,de ; last-current position ld c,l ; move count to bc ld b,h ld h,d ; move current position into hl ld l,e inc de ld (hl),space ldir ; cleos1 equ $+BIAS pop hl ; restore cursor position jp finsh ; ; clear to end of line ; cleol equ $+BIAS ; call clrcur ; clear (remove) cursor push hl call cleols pop hl jp finsh cleols equ $+bias ld a,l and colum-1 ; get col number cp linlen-1 JP c,cleol1 ld (hl),space ret cleol1 equ $+BIAS ; ; push hl ; save current position ld a,l ; find beginning of line and .LOW..NOT.(colum-1) ld l,a ld de,linlen-1 ; add hl,de ; hl points to end of line pop de ; current position in de push de or a ; clear carry sbc hl,de ; hl=# of bytes to clear ld c,l ; move count into bc ld b,h pop hl ; current position ld e,l ; copy to de ld d,h inc de ld (hl),space ldir ret clrcur equ $+BIAS in a,bitport set 7,a out bitport,a ; video bank ld hl,(cursor) ; get cursor location ld a,(oldchr) ; get what was there ld (hl),a ; and put it back ret ; ; process a return ; return equ $+BIAS call clrcur ; clear (remove) cursor ld a,l and .LOW..NOT.(colum-1) ld l,a jp finsh ; ; escape lead-in sequence start up ; doesc equ $+BIAS ld a,1 ; leadflg is a counter of chars processed ld (leadflg),a ld hl,escstr ld (escptr),hl ret ; ; process second, third and fourth characters of lead-in sequence ; leadin equ $+BIAS ld a,(leadflg) add a,1 ld (leadflg),a ld hl,(escptr) ld (hl),c ; save character inc hl ld (escptr),hl ; update pointer cp 2 jp nz,tstdn ld a,c sbc a,frsesc cp elnln ; length of table jp c,gdesc ; ok ld a,0 ld (leadflg),a ; bad - quit escape ret gdesc equ $+BIAS ld hl,escln ld c,a ld a,0 ld b,a add hl,bc ld a,(hl) ; get escape string length ld (esclen),a ; and store tstdn equ $+BIAS ld a,(leadflg) ld b,a ld a,(esclen) cp b ret nz ; not done yet ;here we are done ld a,(escstr) ; get first character sbc a,frsesc cp elocln call c,escdo ld a,0 ld (leadflg),a ret ; not a valid string escdo equ $+BIAS ld hl,escloc ld c,a ld a,0 ld b,a add hl,bc add hl,bc ; add twice (since word table) ld c,(hl) inc hl ld b,(hl) ; get escape routine address ld h,b ld l,c jp (hl) ; vector to routine escloc equ $+BIAS dw dospec dw up dw dn dw fowrd dw back dw null dw dogreek dw doascii dw hmcsr dw rlf dw cleos dw cleol dw null dw null dw null dw null dw null dw null dw null dw null dw null dw null dw null dw null dw null dw curpos elocln equ ($+BIAS-escloc)/2 escln equ $+BIAS db 3 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 2 db 4 elnln equ $+BIAS-escln null equ $+BIAS ret dospec equ $+BIAS ld a,(escstr+1) ; get terminating character cp '1' jp z,inch cp '2' jp z,delch cp '3' jp z,doinst cp '4' jp z,dodel ret ; if none of them curpos equ $+BIAS call clrcur ; remove cursor then move it ld hl,line1 ; process col # ld a,(escstr+2) sub space ; remove ascii space bias ; l3 equ $+BIAS sub linlen ; JP nc,l3 add a,linlen ld l,a ld a,(escstr+1) ; process row # sub space ; remove ascii space bias l4 equ $+BIAS sub lines ; range 0 - lines JP nc,l4 add a,lines ld de,colum ; add column to cursor pos till l5 equ $+BIAS jp z,finsh ; # lines = 0 add hl,de dec a JP l5 ; FINSH equ $+BIAS LD A,(HL) ; get character at cursor position ld (oldchr),a ; and save it CP SPACE ; SPACE JP NZ,FIN1 ; IF SO THEN SPECIAL CURSOR CHAR LD A,(CURCHR) ; get special cursor char ld (hl),a ; and put it there JP VEXIT FIN1 equ $+BIAS SET 7,a ; make character blink ld (hl),a ; and put it back VEXIT equ $+BIAS ld (cursor),hl ; save location in a,bitport res 7,a out bitport,a ; video bank ret ; all done ; ; switch from ascii to greek ; dogreek equ $+BIAS ld a,greek ; greek char mask ld (chrmsk),a ret ; ; switch from greek to ascii ; doascii equ $+BIAS ld a,ascii ; ascii mask ld (chrmsk),a ret ; ; delete line, scroll up to current line, blank 24'th line ; dodel equ $+BIAS call clrcur ; clear (remove) cursor call setup ; setup cpu regs for ldir push de ; current line JP z,delscr ; if setup set Z flag no scroll ldir delscr equ $+BIAS ld hl,last1 ; blank last line call cleols pop hl ; current line JP finsh ; ; insert a blank line at current row address, 24'th line lost ; doinst equ $+BIAS call clrcur ; clear (remove) cursor call setup push de ; current line JP z,inscr ; no scroll ld de,last1+127 ld hl,last1-1 lddr inscr equ $+BIAS pop hl ; current line push hl call cleols ; clear it pop hl ; current row JP finsh setup equ $+BIAS ld a,l and colum ld l,a ; begining of current line push hl ; save current position ex de,hl ; compute amount to move ld hl,last1 ; last line of display or a sbc hl,de ld b,h ; bc=length ld c,l pop hl ; current pos push hl ld de,128 ; set a pointer to beginning of next line add hl,de ; hl=current+128 (next line) pop de ; de=current ld a,b ; is bc zero or c ret inch equ $+BIAS call clrcur ; clear (remove) cursor push hl ld d,h ld e,l ld a,e and colum ; begin of line or linlen-1 ; end of line ld e,a ex de,hl ; hl =eol, de =cur push hl ; save eol or a ; clear carry sbc hl,de ; get # of characters ld b,h ld c,l pop hl ; get eol ld a,b or c jp z,eoins ; if no characters to insert ld d,h ld e,l dec hl ; eol - 1 lddr eoins equ $+BIAS pop hl ld (hl),space jp finsh delch equ $+BIAS call clrcur ; clear (remove) cursor push hl ld d,h ld e,l ld a,e and colum ; begin of line or linlen-1 ; eol ld e,a ; de = eol or a ; clear carry ex de,hl ; hl =eol, de = cur push hl ; save eol sbc hl,de ; hl = count ex de,hl ; de = count, hl = cur ld a,d or e jp z,eodel ; none to move ld b,d ld c,e ; bc = count ld d,h ; de,hl =cur ld e,l inc hl ldir eodel equ $+BIAS pop hl ; hl =eol ld (hl),space ; always have to kill last char pop hl ; cur position jp finsh print equ $+BIAS ex (sp),hl ; pop return address, points to text to print ld a,(hl) ; get a byte of text, stop on zero byte inc hl ex (sp),hl ; save new return address or a ; is it a zero byte? ret z ld c,a ; no, so print it call vidout JP print