;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