;TVBIOS v1.0--add terminal emulation to C64 CP/M ; ; 28 September 1984 ; ; Author: Ross A.Alford ; ...{decvax, akgua, ihnp4}!mcnc!ecsvax!alford ; Compuserve 75475,1404 ; ; Department of Zoology ; Duke University ; Durham, NC 27706 ; ; This program is copyrighted 1984 by ; Ross A. Alford. Permission is ; hereby granted for unlimited nonprofit ; distribution, provided this notice is ; included. Permission for any ; commercial use must be obtained from ; the author. ; ; Adds to the C64 BIOS an emulation of ; the Televideo 920 terminal (in ; 40 columns). ; ; Takes up the space reserved for 6502 ; BIOS functions 7,8, and 9 at Z80 ; addresses 0fe00h through 0ffffh. ; ; Also adds auto key repeat after ; a short delay. ; ; Using the insert and delete line ; functions sometimes makes a few ; characters turn odd colors after they ; move. This appears to be due to ; some sort of a timing problem with ; the 2114 used for color RAM, and I ; haven't been able to get around it. ; I'd like to hear of any solution ; anyone comes up with. ; ; This program works with the version ; of C64 CP/M that I own. There may ; be other versions in existance. If ; it doesn't work on your system, ; look up the BIOS locations in your ; manual and see if they match. ; ; I make no warranty of this program's ; usefulness, and assume no liability ; for any damages it may cause ; directly or indirectly. ; ; ; Supports the following commands: ; ; decimal sequence function ; ; 26 home and clear ; 27,82 delete line ; 27,69 insert line ; 27,84 erase to end of line ; 27,85 erase to end of screen ; 27,41 inverse video on ; 27,40 inverse video off ; 27,61,row+32,col+32 position cursor ; at row, col ; ; ;define true and false ; true equ 0ffh false equ 00h ; ; ;assemble for 44k or 48k? ; forty8 equ true forty4 equ false ; ;conditional equates ; if forty8 lastky equ 0ba63h j9 equ 0bbd5h const1 equ 0bbd7h const2 equ 0bbdch conout equ 0bc76h j20 equ 0bc7ch cout1 equ 0bc89h cout5 equ 0bcaah endif ; if forty4 lastky equ 0aa63h j9 equ 0abd5h const1 equ 0abd7h const2 equ 0abdch conout equ 0ac76h j20 equ 0ac7ch cout1 equ 0ac89h cout5 equ 0acaah endif ; ;global equates ; cr equ 00dh lf equ 00ah offset equ 0fb00h iotype equ 0fcffh chrst equ 0f400h colst equ 0c800h chrend equ 0f7bfh colend equ 0cbbfh color equ 0f286h row6502 equ 0f0d6h col6502 equ 0f0d3h bdos equ 0005h prtstr equ 009h data6502 equ 0f901h rvs6502 equ 0f0c7h; jrnz equ 020h ; ;routine that relocates the ; tvbios routines into the ; extra 512 bytes at 0fe00h ; and patches conout in the ; bios to jump to tvbios ; org 0100h lxi d,msg1 mvi c,prtstr call bdos lxi b,tvbios lxi h,scend-tvbios lxi d,0fe00h call movup lxi b,bpatch lxi d,conout lxi h,0003h call movup lxi b,bpatch2 lxi d,j9-1 lxi h,0003h call movup lxi b,bpatch3 lxi d,cout5 lxi h,0003h call movup ret movup: ldax b stax d inx b inx d dcx h xra a cmp h jnz movup cmp l jnz movup ret ; ; ;jump to tvbios to patch into ; bios80 at conout start ; ; bpatch jmp 0fe00h ; ; ;patch to jump for keyboard ; auto repeat. inserted into ; BIOS80 at j9-1, which should ; be CMP M ; ; bpatch2: jmp rptpat+offset ; ; ;jump to routine to check and ; correct inverse/normal video ; status. inserted into the ; BIOS at location cout5 ; ; bpatch3: jmp invpat+offset ; ; ;startup messages ; msg1 db cr,lf,'TVBIOS v1.0 for C64 CP/M',cr,lf db 'Emulates the TVI 920 in 40 columns',cr,lf,cr,lf db 'Copyright 1984 by Ross A. Alford',cr,lf db 'All commercial rights reserved',cr,lf,cr,lf,'$' ; ; ;main TVBIOS interpreter ; ; org 0300h tvbios lda flag+offset db 0cbh,07fh ; bit 7,a jnz esced+offset db 0cbh,047h ; bit 0,a jnz curdo+offset mov a,c cpi 01bh ;esc? jnz ccz+offset mvi a,true sta flag+offset ret ccz: cpi 01ah jnz endscop+offset mvi a,0ch mov c,a endscop: lda iotype ani 010h mov a,c jnz cout5 jmp j20+02h esced: xra a sta flag+offset mov a,c cpi 052h jz delrow+offset cpi 045h jz insrow+offset cpi 054h jz clreol+offset cpi 055h jz clreos+offset cpi 029h jz invon+offset cpi 028h jz invoff+offset cpi 03dh rnz mvi a,01h sta flag+offset ret curdo: db 0cbh,04fh ; bit 1,a jnz curcol+offset mov a,c sui 020h sta row+offset mvi a,03h sta flag+offset ret curcol: xra a sta flag+offset mov a,c sui 020h sta col+offset jmp curpos+offset ; ;subroutine insrow: insert a blank ; line at the row given by row ; insrow: call stindl+offset push h lxi b,chrend lxi d,chrend+028h call lddr+offset pop h lxi b,colend lxi d,colend+028h call lddr+offset mvi a,028h sta ntoblk+offset ; ;subroutine blank: change 'ntoblk' ; positions to blank starting at ; current chradr, coladr ; blank: mvi b,020h lda ntoblk+offset lhld chradr+offset blank1: mov m,b inx h dcr a ora a jnz blank1+offset mvi b,0f6h lda ntoblk+offset lhld coladr+offset blank2: mov m,b inx h dcr a ora a jnz blank2+offset ret ; ; ;subroutine saverc: moves row ; and col numbers from 6502 ; locs to tvbios locs ; ; saverc: lda col6502 sta col+offset lda row6502 sta row+offset ret ; ;subroutine calcstnd: calculate ; addresses for start of color ; and char memory given a row # ; row passed in 'row', addresses ; returned in coladr, chradr ; calcstnd: lda row+offset ani 07fh lxi h,0000h lxi b,0000h ora a jz caend+offset lxi b,0028h calclp: ora a jz caend+offset dad b dcr a jmp calclp+offset caend: push h lxi b,chrst dad b shld chradr+offset pop h lxi b,colst dad b shld coladr+offset ret ; ; ;subroutine lddr: simulate the ; lddr instruction, sort of ; pass from in bc, to in de, ; number in hl ; this is used rather than the ; real thing because lddr is ; apparently too fast for ; the color memory ; ; lddr: ldax b push h ;delay pop h ;delay stax d dcx b dcx d dcx h xra a cmp h lddr1: db jrnz,(lddr-lddr1-2) and 0ffh cmp l lddr2: db jrnz,(lddr-lddr2-2) and 0ffh ret ; ;subroutine ldir: move byte ; pointed to by bc to loc ; pointed to by de, inc bc, de ; repeat hl times ; ldir ldax b push h ;delay pop h ;delay stax d inx b inx d dcx h xra a cmp h ldir1: db jrnz,(ldir-ldir1-2) and 0ffh cmp l ldir2: db jrnz,(ldir-ldir2-2) and 0ffh ret ; ; ;subroutine clreol:clear to end ; of current screen line ; ; clreol: call saverc+offset ceol2: call calcstnd+offset lxi h,col+offset mvi a,028h sub m sta ntoblk+offset mvi b,0 lda col+offset mov c,a lhld chradr+offset dad b shld chradr+offset lhld coladr+offset dad b shld coladr+offset call blank+offset ret ; ; ;subroutine clreos:clear from ; cursor to end of page ; ; clreos: call clreol+offset xra a sta col+offset ceop2: lxi h,row+offset inr m mvi a,018h cmp m jc ceopnd+offset call ceol2+offset jmp ceop2+offset ceopnd: ret ; ; ;subroutine curpos: position ; cursor on coords passed in ; locations row and col ; ; curpos: lda row+offset ani 07fh cpi 019h rnc dcr a sta row6502 mvi a,0dh call cout5 lda col+offset ani 07fh cpi 028h rnc sta col6502 ret ; ; ;subroutine invon:start inverse ; ; invon: mvi a,01h sta invflg+offset ret ; ; ;subroutine invoff: end inverse ; ; invoff: xra a sta invflg+offset ret ; ;subroutine delrow: delete the ; row pointed to by row ; delrow: call stindl+offset push h push h lxi h,0028h dad d mov b,h mov c,l pop h call ldir+offset lhld coladr+offset mov d,h mov e,l lxi h,0028h dad d mov b,h mov c,l pop h call ldir+offset lastrw: xra a sta col+offset mvi a,018h sta row+offset call ceol2+offset ret ; ;subroutine stindl: startup ; for insert/delete a row ; routines. exit with chradr ; in d,e and chrend-chradr in ; hl ; stindl: call saverc+offset ani 07fh cpi 018h jc stin2+offset pop h ;last return address jmp lastrw+offset stin2: call calcstnd+offset xra a lhld chradr+offset mov d,h mov e,l lxi h,chrend db 0edh,052h ; sbc hl,de inx h ret ; ; ;rptpat routine: a jump to this ; is inserted at j9-1 in the ; BIOS. This repeats any ; keypress after a delay ; ; rptpat: mov b,a cpi 040h jnz rpp1+offset sta lastky jmp const1 rpp1: cmp m jz rpp2+offset mvi a,080h sta delay+offset mov a,b jmp const2 rpp2: lxi h,delay+offset dcr m jnz const1 mvi a,018h mov m,a mov a,b jmp const2 ; ; ;routine invpat is jumped to ; by the modified BIOS from ; location COUT5. it fixes ; the inverse/normal status, ; then continues as normal ; ; invpat: mov b,a lda invflg+offset sta rvs6502 mov a,b sta data6502 jmp cout5+3 ; ;storage locations ; row db 0 col db 0 chradr db 0,0 coladr db 0,0 ntoblk db 0 flag db 0 delay db 080h invflg db 0 ; scend end