Commodore 128 CP/M v3.0
40/80 column drivers
title 'CX40 & CX80 40 and 80 column drivers 18 Feb 86'
maclib cxequ
maclib z80
lines equ 24
; public ?fundir ; function direct
public ?int40,?int80
public ?stat,?save,?recov,@st40
extrn ADM31,setadm
; extrn setvt
page
;
;**
;** This is the entry point to get to the function module
;**
;
;
; This code will perform the functions that the emulation
; code will need to do to complete function.
;
;
;
;
; enable cursor, then set foreground and background colors
;
DSEG
?int80:
call setadm
lhld key$tbl ; logical color assignments at end of
lxi d,11*4*8 ; ..key$table, (key$tbl size=11*4*8)
dad d
shld color$tbl$ptr ; setup color table ptr
mvi a,80h
sta current$atr
;
; program the 8563 for full flashing cursor
;
mvi a,10 ; point to cursor start line#
call R$wait ; and mode register
mvi a,40h ; start at line zero, cursor 1/16
outp a
mvi a,11 ; point to cursor end line#
call R$wait
mvi a,7
outp a
ret
page
;
;
;
DSEG
?int40:
lxi h,screen$40
shld char$adr$40
mvi a,24
sta paint$size ; set 40 column repaint to 24 lines
lxi b,VIC+18h ; point to address register
mvi a,vic$screen*4/256+6 ; upper and lower case set (+6)
outp a ; move screen
ret
;**
;** The following code is used to maintain the status line on
;** both the 80 and 40 column displays
;**
;
; save characters on the status line (80 column only) to buffer
; reverse video the data area cleared (40 and 80 column screens)
;
; C=start column # B=number of characters to save
;
DSEG
?save:
mov a,c
cpi 40
jrnc do$save$80
push b
;;;***
mov a,b
lxi h,stat$line$40
mvi b,0
dad b
clear$loop$40:
mvi m,' '+80h ; set reverse video
inx h
dcr a
jrnz clear$loop$40
call paint$40$status
;;;***
pop b
do$save$80:
mov a,b
lxi h,lines*80 ; point to status line
lxi d,buffer$80$col ; point to save buffer
mvi b,0 ; zero MSB
dad b ; point to char position to save
save$loop:
push psw ; save count
push d ; save buffer address
call R$read$memory ; read char(B) and attribute(A)
pop d ; recover buffer pointer
stax d ; save character
inx d ; advance buffer
mov a,b ; get atrb to A
stax d ; save atrb
inx d ; advance buffer
push d
mvi a,01000000b ; reverse video only
call get$atr$color ; returned in A
mvi d,' ' ; get character
call R$write$memory
pop d
pop psw ; recover count
inx h
dcr a ; adjust count
jrnz save$loop ; loop if not done
ret
page
;
; recover characters to the status line (80 column only)
; for the 40 column screen just clear status line (with spaces)
;
; C=start column # B=number of characters to restore
;
DSEG
?recov:
mov a,c
cpi 40
jrnc recove$80 ; skip 40 column if C>40
push b
;;;***
lxi h,stat$line$40
mov a,b
mvi b,0
dad b
mov b,a
recov$40$loop:
mvi m,' '
inx h
djnz recov$40$loop
call paint$40$status
;;;***
pop b
recove$80:
mov a,b
lxi h,lines*80 ; point to status line
lxi d,buffer$80$col ; point to save buffer
mvi b,0 ; zero MSB
dad b ; point to char position to save
recov$80$loop:
push psw ; save count
ldax d ; get attribute
inx d ; advance pointer
mov b,a ; save attribute in B
ldax d ; get character in A
inx d ; advance pointer
push d ; save buffer address
mov d,a ; move character to D
mov a,b ; move attribute to A
call R$write$memory ; write char(D) and attribute(A)
pop d ; recover buffer pointer
pop psw ; recover count
inx h
dcr a ; adjust count
jrnz recov$80$loop ; loop if not done
ret
page
;
; Places data on the system status line
;
; for the 80 column screen a number of character attributes
; are available: flash, underline, reverse video
;
; for the 40 column screen only reverse video is available
;
; INPUT:
; A=attribute (7654 3210)
; 6-reverse video
; 5-underline
; 4-blink
; B=character to write (ASCII)
; C=column number to write
; (>40 does nothing to 40 column screen)
;
DSEG
?stat:
push psw
push b ; save for 80 column display
mov e,a ; save attribute in E
mov a,c
cpi 40
jrnc not$40$col$wr
;;;***
;
; display on 40 column display 1st
;
RCALL FR$ASCII$to$pet ; char to convert is in B
; returned in A
mov b,a
mov a,e ; get attribute byte
ani 01000000b ; check for reverse video
mov a,b ; get pet ascii character
jrz char$not$rev
ori 80h ; set MSB for reverse video
char$not$rev:
mvi b,0
lxi h,stat$line$40
dad b ; point to status position
mov m,a
call paint$40$status
;;;***
;
; display on 80 column display now
;
not$40$col$wr:
pop d ; D=character E=position
pop psw ; get new attribute
call get$atr$color
mov b,d ; save character to write in B
lxi h,lines*80
mvi d,0
dad d ; point to character location
mov d,b ; place character to write in D
jmp R$write$memory
;
; using attribute in A add color to it and return in A
;
; destroys BC
;
DSEG
get$atr$color:
push h
push psw
lda bg$color$80
mov c,a
mvi b,0
lxi h,status$color$tbl
dad b ; point to status color
pop psw
ani 01110000b ; limit good attr
mov b,a ; save in E
mov a,m ; get status color
ani 0fh ; only want 80 column status color
ora b ; merge with new attr
ori 80h ; select alternate character set
pop h
ret
;
;
;
DSEG
paint$40$status:
lxi h,stat$line$40
lxi d,vic$screen+24*40
lxi b,40
ldir
lda bg$color$40
mov c,a
mvi b,0
lxi h,status$color$tbl
dad b
mov a,m
rrc
rrc ; move status color to LSB
rrc ; no need to mask it
rrc ; color RAM only 4 bits wide
lxi h,vic$color+24*40
lxi d,vic$color+24*40+1
lxi b,40
jmp paint$common
;
;
;
CSEG
paint$common:
sta io$0
mov m,a
ldir
sta bank$0
ret
page
;
;
;
@st40:
stat$line$40:
; 12345678901234567890 character locations
db ' '
db ' '
;
; MSB is 40 column status color, LSB is 80 column status color
;
status$color$tbl:
db 05eh ; status color #1
db 0f6h ; status color #2
db 0a6h ; status color #3
db 0b7h ; status color #4
db 0d7h ; status color #5
db 0d4h ; status color #6
db 0e7h ; status color #7
db 083h ; status color #8
db 097h ; status color #9
db 0a8h ; status color #10
db 09eh ; status color #11
db 0ffh ; status color #12
db 0bdh ; status color #13
db 058h ; status color #14
db 06fh ; status color #15
db 0ceh ; status color #16