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
/
ENTERPRS
/
CPM
/
UTILS
/
A
/
BIOS-R62.LZH
/
CXKEY.ASM
< prev
next >
Wrap
Assembly Source File
|
2000-06-30
|
17KB
|
1,063 lines
; All functions relating to 40 col operation has been removed.
;
; A Screendump function has been added, it selects the printer
; based on the values of LOVEC, first it tests for ?pt$o$1,
; if that printer is selected (via the device command or predefined
; during system initialization in CXIO.ASM) the screen dump will
; be directed there, if ?pt$o$1 is not selected then it testes for
; ?pt$o$2 and directs the screen dump there if that printer is selected
; If niether printer is selected the routine mereley returnes without
; doing anything.
;
; User assumes _ALL_ liability for use of this module. Original
; copyright is maintained by Commodore.
;
; screen$dump routine copyright April 26 1987 by James W. Waltrip IV
;
;-------------------------------------------------------------------------
; * ADDITIONS by Randy Winchester, 5/3/89
;
; Added drive D: to MFM unlock routine.
;
;-------------------------------------------------------------------------
;
title 'C128 keyboard handler 3 May 89'
maclib cxequ
maclib z80
public ?get$key,?int$cia,?kyscn
public Fx$V$tbl
extrn ?stat,?save,?recov
extrn ?di$int
extrn cmdsk0,cmdsk1,cmdsk2,cmdsk3
extrn @pageM
extrn ?pt$o$2
extrn ?pt$o$1,@lovec
page
DSEG
;
;
;
?int$cia:
lxi b,key$row ; point to CIA 1st register
mvi a,0ffh
outp a
inr c
inr c
outp a
inr c
xra a
sta commodore$mode ; clear commodore shift mode
outp a
lxi h,key$scan$tbl ; init key scan tbl pointer
mov m,l ; ..to the begining
;
; initialize keyboard buffer and pointers
;
lxi h,key$buffer
shld key$get$ptr
shld key$put$ptr
mvi m,0ffh
lxi d,key$buffer+1
lxi b,key$buf$size-1
ldir
ret
page
;==========================================================
; KEYBOARD SCANNING FUNCTION
;==========================================================
;
;
;
;
?get$key:
lhld msgptr
mov a,h
ora l
jrnz mess$cont
;
;
;
re$scan:
call scan$keys
push psw
mov a,c
ani special
cpi special ; control and rt. shift key
jrnz not$special
mov a,b ; get the matrix position
cpi rt$arrow
jz prog$fun
cpi lf$arrow
jz prog$key
cpi alt$key
jz toggle$plain$keys
;
;
;
not$special:
pop psw
mov d,a
lda stat$enable
ani 80h ; mask off plain keys bit
mov a,d ; recover input character
rnz ; return if plain keys bit is set
page
;
;
;
test$function:
cpi 080h ; check for MSB set
rc ; return if not
cpi 0A0h ; 80-9F are function keys
jrnc not$8x
;
;
find$mess:
ani 1fh ; 32 messages
mov b,a ; place Function # in B for search
call get$fun$adr
;
;
mess$cont:
mov b,m ; get char to B
inx h
mov a,m
ora a
jrnz more$mess
lxi h,0
more$mess:
shld msg$ptr
mov a,b
mvi c,0 ; no control keys
mvi b,0f0h ; tell user this is a function key
ora a ; check character (maybe 1st is 0)
jrz re$scan ; scan keys (no valid function key)
jrnz test$function ; test for local function
page
;
;
;
get$fun$adr:
lhld fun$tbl ; get adr of msg table
dcx h
; lxi h,msgtbl-1 ; point to start of funtions (less one)
inr b ; adjust function # (to test for 0)
xra a ; get a zero in A
check$fun$num:
inx h ; advance pointer to point at text
shld msg$ptr ; save message adr for caller
dcr b ; requested function ?
rz ; yes, exit with HL=string adr
find$end$marker:
cmp m ; end of text marker ? (0=EOTM)
jrz check$fun$num ; yes, go see if required fun #
inx h ; advance to next char
jr find$end$marker ; go find EOTM
page
;
; A0-AF Set char color (80 col)
; B0-B1 Set background color (80 col)
;
not$8x:
cpi 0C0h ;
jrnc not$80col$color
sui 0A0h-20h ; remove key bias
mov b,a
RCALL FR$color
jr ?get$key
;
; C0-CF Set char color (40 col)
; D0-DF Set background color (40 col)
; E0-EF Set border color (40 col)
;
not$80col$color:
cpi 0F0h
jrnc must$be$Fx
;
;
;
sui 0C0h-20h ; remove key bias
mov b,a
RCALL FR$color+FR$40
jr ?get$key
page
;
; F0-FF special code functions
;
must$be$Fx:
lxi h,?get$key
push h ; save as the return adr
ani 0fh
add a ; double
lhld key$FX$function
mov e,a
mvi d,0
dad d ; HL points to the function
mov e,m
inx h
mov d,m
xchg
pchl
;
;
;
FX$V$tbl:
dw screen$dump ; F0
dw display$pause ; F1
dw empty ; F2
dw empty ; F3
dw empty ; F4
dw reset$mfm ; F5
dw empty ; F6
dw empty ; F7
dw empty ; F8
dw empty ; F9
dw empty ; FA
dw empty ; FB
dw empty ; FC
dw empty ; FD
dw empty ; FE
dw 0 ; FF go restart the C128 BASIC
; mode (or C64)
page
;
; Function F0
;
; screen dump for the 80 col chip
;
;screen$dump:
; lxi h,2000
; mvi a,80
; sta width
;;
; lxi b,0D600h ; 80 col cmd register
; mvi a,18
; outp a
;lx1:
; inp a ; get status
; jp lx1 ; loop until status good
; inx b ; increment to data reg
; mvi a,0
; outp a
;;
; dcx b ; decrement to command reg
; mvi a,019
; outp a
;lx2:
; inp a
; jp lx2 ; loop til status good
; inx b ; increment to data reg
; mvi a,0
; outp a
; dcx b ; decrement to command reg
;rpt:
; inp a ; get status
; jp rpt ; loop until good
; mvi a,31
; outp a
;lx3:
; inp a
; jp lx3
; inx b ; increment to data reg
; inp a
; dcx b
; call convert
;;
; push b
; push h
; mov c,a
; call ?pt$o$2
;;
;; call ?pt$o$1
;;
; pop h
; pop b
;;
; lda width
; dcr a
; sta width
; cz cr$lf
; dcx h ; counter for screen (2000 locations)
; mov a,l
; cpi 0
; jnz over
; mov a,h
; cpi 0
; jz cr$lf ; return when HL = 0000
;over:
; jmp rpt
;cr$lf:
; push b
; push h
; mvi c,13
;; call ?pt$o$2
;;
;; call ?pt$o$1
;;
; mvi c,10
; call ?pt$o$2
;;
;; call ?pt$o$1
;;
; mvi a,80
; sta width
; pop h
; pop b
; ret
;convert:
; cpi 32
; jc set$space
; cpi 128
; jnc set$space
; ret
;set$space:
; mvi a,32
; ret
;;
;width: ds 1
;;
;
;
; Function F0
;
; screen dump for the 80 col chip
screen$dump:
lda @lovec + 1
bit 4,a
jnz next
bit 3,a
rz
jr ova
next:
lxi h,?pt$o$1
shld prt$ad
;
;
;
ova:
lxi h,2000
mvi a,80
sta width
;
lxi b,0D600h ; 80 col cmd register
mvi a,18
outp a
lx1:
inp a ; get status
jp lx1 ; loop until status good
inx b ; increment to data reg
mvi a,0
outp a
;
dcx b ; decrement to command reg
mvi a,019
outp a
lx2:
inp a
jp lx2 ; loop til status good
inx b ; increment to data reg
mvi a,0
outp a
dcx b ; decrement to command reg
rpt:
inp a ; get status
jp rpt ; loop until good
mvi a,31
outp a
lx3:
inp a
jp lx3
inx b ; increment to data reg
inp a
dcx b
call convert
lda width
dcr a
sta width
cz cr$lf
dcx h ; counter for screen (2000 locations)
mov a,l
cpi 0
jnz rpt
mov a,h
cpi 0
jnz rpt
cr$lf:
mvi a,13
call printer
mvi a,10
call printer
mvi a,80
sta width
ret
convert:
cpi 32
jc set$space
cpi 128
jc printer
set$space:
mvi a,32
;
printer:
push h
push b
mov c,a
;
prt$ad equ $+1
call ?pt$o$2
pop b
pop h
ret
;
width: ds 1
;
;
;
;
;
;
; Function F1
;
display$pause:
mvi a,-1
sta cur$pos ; move cursor out of window
lxi b,buff$small*256+buff$pos ; B=size C=pos
call ?save
mvi a,buff$pos+1
sta offset
mvi b,5
lxi h,pause$MSG
pause$disp$loop:
mov a,m
push h
push b
call disp$status
pop b
pop h
inx h
djnz pause$disp$loop
pause$loop:
call scan$keys
jrz pause$loop
cpi 0F1h ; pause key function code
jrnz pause$loop
jr recov$small
pause$MSG:
db 'Pause'
empty:
ret
page
;
; Function F2
;
; empty
;
; Function F3
;
;empty
;
; Function F4
;
; empty
;
; Function F5
;
; Unlock MFM selection for ALL drives in the system
;
reset$mfm:
lda cmdsk0+42 ; 42 is the offset from drive pointer
ani 7fh ; MSB cleared to unlock the drive
sta cmdsk0+42 ; unlock drive A
lda cmdsk1+42
ani 7fh
sta cmdsk1+42 ; unlock drive B
lda cmdsk2+42
ani 7fh
sta cmdsk2+42 ; unlock drive C
lda cmdsk3+42
ani 7fh
sta cmdsk3+42 ; unlock drive D
ret
page
;
; A zero in the MSB of the STAT$ENABLE byte will allow
; special keyboard function. (codes above 80h)
; A one will force the key value to be returned without
; any special functions being executed.
;
toggle$plain$keys:
pop psw ; remove garbage
lda stat$enable
xri 80h
sta stat$enable
jmp re$scan
page
;
;
;
prog$key:
pop psw ; remove garbage
lxi b,buff$small*256+buff$pos ; B=size, C=position
call ?save
mvi a,buff$pos+1
sta offset
call read$key ; get key to re-program
push h ; save key's address
mov a,m
call disp$hex$byte
mvi a,buff$pos+4
sta offset
call get$byte
pop h
jrc restore$buf$small
mov m,a
;
;
restore$buf$small:
call delay
recov$small:
lxi b,buff$small*256+buff$pos ; B=size, C=position
jmp ?recov
page
;
;
;
prog$fun:
pop psw ; remove garbage
lxi b,buff$large*256+buff$pos ; b=size, c=pos
call ?save
call read$key ; get function key to program
cpi 80h
jrc restore$buf$large ; error, exit
cpi 0A0h
jrnc restore$buf$large
ani 1fh ; 32 keys defined
mov b,a
call get$fun$adr ; get pointer to function code
xra a
sta string$index ; start at start of string
call edit$fun
lxi h,0
shld msg$ptr ; clear message pointer
restore$buf$large:
call delay
lxi b,buff$large*256+buff$pos ; B=size, C=position
jmp ?recov
page
;
;
;
delay:
lxi h,0
delay$loop:
dcx h
mov a,h
ora l
jrnz delay$loop
ret
;
;
;
edit$fun:
lxi h,edit$fun
push h ; set return to here
call disp$fun$key
call read$key ; B=matrix position
mov d,a ; save ASCII char in D
mov a,c ; get attr (C=cntr codes)
ani special
cpi special ; check for cntr shift
jnz not$cntr$shift
;
;
;
check$exit:
mov a,b ; get matrix position
cpi SF$exit
jrnz check$delete
pop h ; remover return adr
ret ; go back to normal keyboard fun
page
;
;
;
check$delete:
cpi SF$delete
jrnz check$insert
;
; delete the character at current cursor position
;
call compute$adr ; HL= current position
rz ; don't want to delete end markers
xchg ; save in DE
lhld key$tbl ; get next table adr (keytbl)
dcx h
; lxi h,msgtbl$end-1 ; end adr
xra a ; clear the carry flag
dsbc DE ; compute number of bytes to move
mov b,h
mov c,l ; place count in BC
mov h,d
mov l,e ; HL=DE
inx h ;
ldir
dcx h ; point to insert point
mvi m,-1 ; fill table end with -1
ret
page
;
;
;
check$insert:
cpi SF$insert
jrnz check$right
;
; insert a space into string
;
call compute$adr
;
; HL=address to insert a space at
; value of HL is the same on return
;
insert$space:
xchg
lhld key$tbl ; get start of next table
dcx h ; point to end of msg table
; lxi h,msgtbl$end-1
xra a
cmp m ; last char=0 (end of string)
rz ; yes, don't insert
xra a ; clear the carry flag
dsbc DE ; compute number of bytes to move
mov b,h
mov c,l ; place count in BC
lhld key$tbl
dcx h
mov d,h
mov e,l
; lxi d,msgtbl$end-1 ; dest adr
dcx h
; lxi h,msgtbl$end-2 ; source adr
lddr ; move the data
inx h ; point to insert point
adi ' ' ; A was equ to zero, add a space to
mov m,a ; ..clear the zero flag
ret ; insert a space at the new location
page
;
;
;
check$right
cpi SF$right
jrnz check$left
;
; move cursor right
; if past right end go back to left end
;
call compute$adr
lda string$index
jrnz move$rt
mvi a,-1
move$rt:
inr a
sta string$index
ret
;
;
;
check$left:
cpi SF$left
rnz
;
; move cursor left
; if past left end go to right end
;
lda string$index
ora a
jrz at$left$end
dcr a
sta string$index
ret
page
;
;
;
at$left$end:
call compute$adr
rz ; return if at right end
lda string$index
inr a
sta string$index ; move right one position
jr at$left$end ;
;
;
;
not$cntr$shift:
call compute$adr ; HL=function adr (A=0 if string end)
jrnz no$insert
push d ; save char to insert
call insert$space
pop d ; recover character
rz ; no room if zero flag set
no$insert:
mov m,d ; install key's value
lda string$index
inr a
sta string$index
ret
page
;
;
;
compute$adr:
lhld msg$ptr ; get start of memory pointer
lda string$index ; get current offset
add l
mov l,a
mov a,h
aci 0
mov h,a ; point to update location
mov a,m
ora a
ret
;
;
;
disp$fun$key:
mvi a,buff$pos
sta offset
mvi a,'>' ; display start prompt '>'
call disp$status
lhld msg$ptr
lda string$index
try$again:
cpi buff$large-2
jrc parameters$ok
inx h
dcr a
jr try$again
page
;
;
;
parameters$ok:
adi buff$pos+1
sta cur$pos
disp$fun$loop:
mov a,m
ora a
inx h ; advance function pointer
jrz disp$fun$end
push h
call disp$status ; display on status line
pop h
lda offset ; get current cursor position
cpi buff$pos+buff$large-1 ; to end of window?
jrnz disp$fun$loop ; no, display next character
disp$fun$end:
mvi a,'<' ; display end prompt '<'
disp$space$fill:
call disp$status
lda offset ; get current cursor position
cpi buff$pos+buff$large ; to end of window?
rz
mvi a,' ' ; fill to the end with spaces
jr disp$space$fill
page
;
;
;
disp$hex$byte:
push psw
rar
rar
rar
rar
call disp$hex$nibble
pop psw
disp$hex$nibble:
ani 0fh
adi '0'
cpi '9'+1
jrc disp$status
adi 7
disp$status:
mov b,a
lda offset
mov c,a
inr a
sta offset
lda cur$pos
cmp c
mvi a,01000000b ; set reverse video attributes
jrnz not$cur$pos
mvi a,00010000b ; set normal video and blink
not$cur$pos:
jmp ?stat
page
;
;
;
get$byte:
mvi e,0
call read$nibble
rc
add a
add a
add a
add a
mov e,a
read$nibble:
push d
call read$key
mov a,b ; get matrix position
lxi h,hex$key$tbl
lxi b,16
ccir
mov a,c
pop d
stc
rnz
add e
push d
push psw
call disp$hex$nibble
pop psw
pop d
stc
cmc
ret
;
;
;
read$key:
call scan$keys
inr b
jrz read$key ; no, wait for one
dcr b
ret
page
;
;
;
do$alpha$toggle:
mvi m,0ffh ; mark buffer position free
lda commodore$mode
xri 00100001b
ani 00100001b
sta commodore$mode
;
; output:
; B=FF if no key pressed
; A=00 if no key code assigned
; else A=ASCII key code
; B=matrix position (0-57)
; C=control code (bits 1,0)
; 00=lower case (lowest)
; 01=upper case
; 10=shift
; 11=control (highest)
; (bit 2) control key
; (bit 4) rt. shift key
; (bit 5) commodore key
; (bit 7) lf. shift key
;
; HL= address of ASCII key location
;
?kyscn:
scan$keys:
lhld key$get$ptr
mov a,m ; M=-1 if buffer empty
mov b,a ; B=-1 if no character
inr a
rz ; return if no key is pressed
;
; there is a character in the buffer,
; advance key$get$ptr to next character.
;
mov a,l
adi 2
cpi low(key$buffer+key$buf$size)
jrnz not$buf$end
mvi a,low(key$buffer)
not$buf$end:
sta key$get$ptr ; update low byte of pointer
page
;
; test for commodore key, if found toggle commodore mode
;
mov a,b ; get buffered matrix position to A
cpi alpha$toggle
jrz do$alpha$toggle
;
; if normal mode(00), or in commodore mode bit
;
inr l ; point to control byte
lda commodore$mode
ani 00100000b ; save commodore key set bit
ora m ; get rest of control byte
mov c,a
ani 3
mov a,c
jrnz is$control$or$shift
lda commodore$mode
ora c
is$control$or$shift:
dcr l
mvi m,0ffh ; mark buffer position free
mov l,b ; save matrix position in HL
mvi h,0
dad h
dad h ; mult. matrix position by 4
mov c,a ; save the control code in C for caller
ani 3
add l ; add the offset
mov l,a ; update the pointer
xchg
lhld key$tbl ; get the start of the ASCII table
dad d ; HL now points to the ASCII value
mov a,m ; for the input key.
ora a ; set zero flag if A=0
ret
page
;
; used to convert a keyboard matrix position into it's HEX
; value (keys caps labelled with 0 to 9 and A to F)
;
hex$key$tbl:
db 15h ; F
db 0eh ; E
db 12h ; D
db 14h ; C
db 1ch ; B
db 0ah ; A
db 20h ; 9
db 1bh ; 8
db 18h ; 7
db 13h ; 6
db 10h ; 5
db 0bh ; 4
db 08h ; 3
db 3bh ; 2
db 38h ; 1
db 23h ; 0