; 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 ; ; title 'C128 keyboard handler 26 April 87' 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 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 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