title PCW-Tastataturanalysator name ('KEY') ; ; Ausgabe des Zustandes der PCW-Tasten ; OS equ 0000h BDOS equ 0005h .conout equ 2 .string equ 9 lf equ 0ah cr equ 0dh eot equ '$' COT equ 4 SELMEM equ 27 USERF equ 30 KT_SET equ 00d7h KT_GET equ 00dah CR_KEY equ 18 ENT_KEY equ 78 _KEYS equ 81 ; Anzahl Tasten COMRAM equ 0c000h ; Start des COMMON Speichers _JP equ 0c3h ; Z80 Opcode ld sp,(BDOS+1) ; Stackadresse holen call setBIOS ; BIOS Vektoren laden call setXLATE ; Zeichentabelle bestimmen ld de,$RULE call string KLOOP: call _USERF ; Tastaturstatus holen dw KT_GET jr nc,KLOOP ; Warten bis Taste betaetigt ld a,c ld de,$CR_KEY cp CR_KEY ; Test ob Ende jr z,comstr ld de,$ENT_KEY cp ENT_KEY jr z,comstr call Display ; Test Anzeige jr z,KLOOP ; Nein push bc push bc push bc call decnum ; Ausgabe der Tastaturnummer ld de,$DELIM call string pop bc call bitnum ; Ausgabe des Tastaturstatus pop bc call bitchar ld de,$CHAR call string pop bc call chrXLAT ; Zeichen aus Tabelle holen ld de,$CRLF call string jr KLOOP ; Naechster Versuch comstr: call string ; Meldung ausgeben jp OS ; Und Programm beenden ; ; Test ob Taste im Akku angezeigt werden soll ; Display: push bc push hl ld hl,NoDisp ; Tabelle laden ld bc,NoDlen cpir ; Test ob in Tabelle pop hl pop bc ret ; ; Meldung in ^DE auf Konsole ausgeben ; string: ld c,.string call BDOS ; Ausgabe ret ; ; Zahl im Akku dezimal ausgeben - max ist 82 ; decnum: ld b,'0'-1 ; Zaehler fuer 10er setzen div10: inc b sub 10 ; Durch 10 teilen jr nc,div10 add a,10+'0' push af ld a,b ; Test ob < 10 cp '0' jr nz,gotten ; Nein ld a,' ' ; Sonst Leerzeichen gotten: call conout ; Auf Konsole ausgeben pop af conout: push bc ld e,a ld c,.conout call BDOS ; Auf Konsole ausgeben pop bc ret ; ; Bitstatus aus Register B ausgeben ; bitnum: ld c,b ; Byte umladen ld b,8 ; Schleife setzen BLOOP: ld a,'0' ; Bit einrichten rlc c ; Carry holen adc a,0 ; Als 0 oder 1 call conout djnz BLOOP ret ; ; Text initialisieren ; clrStat: exx ld hl,$STAT ld b,SLen ; Schleife setzen blank: ld (hl),' ' ; Zeile setzen inc hl djnz blank exx ret ; ; Ausgabe des Status im Klartext ; bitchar: call clrStat ; Text initialisieren ld ix,$STAT ld (ix),'N' inc c dec c ; Test ob Bit gesetzt jr z,nobit ld de,0 ; Index setzen ld c,b ; Byte umladen ld b,7 ; Schleife setzen CLOOP: rlc c ; Bit holen jr nc,notset ; Nicht gesetzt ld hl,$SCHAR add hl,de ; Zeichen holen ld a,(hl) ld (ix),a inc ix bit 0,b ; Test LOCK jr nz,nolock ld (ix),'L' inc ix nolock: ld (ix),'+' inc ix notset: inc de djnz CLOOP ld a,(ix-1) cp '+' jr nz,nobit ld (ix-1),' ' nobit: ld de,$STATXT call string ret ; ; Zeichen aus Tabelle holen ; chrXLAT: ld a,b ; Bits holen call XLATE ; Und umsetzen ld b,0 ld hl,XTAB add hl,de ; Zeichenebene bestimmen add hl,bc ; Index bestimmen ld a,(hl) call CIO ; Zeichen via BIOS ausgeben ret ; ; Bitmuster in Akku umsetzen in Offset in E ; ; N : 00000000; 0 -> 0*81= 0 -> 0x00 ; S : 00100000; 32 -> 1*81= 81 -> 0x51 ; A : 10000000; 128 -> 2*81=162 -> 0xA2 ; S+A : 10100000; 160 -> 3*81=243 -> 0xF3 ; E : 00000010; 2 -> 4*81=324 -> 1x44 ; S+E : 00100010; 34 -> 4*81=324 -> 1x44 ; XLATE: ld de,0*_KEYS or a ret z ld de,4*_KEYS bit 1,a ret nz ld de,2*_KEYS add a,a ret z ld de,3*_KEYS ret c ld de,1*_KEYS ret ; ; Zeichen via BIOS laden und ausgeben ; CIO: cp ' ' ; Bereich testen jr c,C00.1F cp '~'+1 jr nc,C7F.FF COUT: ld c,a ; Zeichen umpacken call _COT ; Und ausgeben ret C00.1F: push af ld a,'^' call COUT ; Kontrollzeichen anzeigen pop af add a,'@' jr COUT C7F.FF: push af push af ld a,'#' call COUT ; Spezial anzeigen pop af rrca ; Obere Bits wandeln rrca rrca rrca call ascnib pop af ascnib: and 00001111b ; Bits maskieren add a,090h ; Und wandeln daa adc a,'0'+16 daa call COUT ret ; ; BIOS Vektoren laden ; setBIOS: ld hl,SelCode ld de,COMRAM ld bc,SelLen ldir ; Routine in Common Memory schieben ld de,(OS+1) ; BIOS Basisadresse laden ld hl,3*(USERF-1) add hl,de ; Adresse fuer USERF berechnen ld (_USERF+1),hl ; Und abspeichern ld hl,3*(COT-1) add hl,de ; Dann Adresse fuer Konsolausgabe ld (_COT+1),hl ld hl,3*(SELMEM-1) add hl,de ; Und fuer Speicherbank ld (_SELMEM+1),hl ret SelCode equ $ .phase COMRAM ; ; Zeichentabelle bestimmen ; ; Dies ist der Teil, der stark von der Version des XBIOS bestimmt wird. ; Es geht darum, die Adresse der Zeichentabelle im XBIOS zu finden. ; ; Der hier angewandte Trick geht ueber die XBIOS Funktion 00D7h - KM SET KEY ; setXLATE: call SelTab ; Adresse der Tabelle ermitteln ret nc ld de,$ILLTAB call string ; Fehlerausgabe jp OS ; ; Ermittelt Adresse der Tabell in Register HL. ; Falls Carry gesetzt, ist das nicht gelungen. ; ; Wegen der Bankumschaltung muss die Routine im Common Memory laufen ; SelTab: ld a,0 call _SELMEM ; XBIOS Bank waehlen ld ix,KT_SET ; Setzen der Basisadresse call getCHN ; Adresse holen jr c,exTab ; Ungueltig push de pop ix call getCHN ; Naechste Adresse holen call nc,valcode ; Erwarteten Code pruefen exTab: push af ld a,1 call _SELMEM ; TPA Bank waehlen pop af ret ; ; Erwarteten Code in ^DE pruefen ; valcode: ld hl,refcode ld b,reflen VLOOP: ld a,(de) ; Wert holen cp (hl) ; Vergleich scf ret nz ; Fehler inc hl inc de djnz VLOOP ld a,(de) ; Adresse der Tabelle laden ld l,a inc de ld a,(de) ld h,a ld de,XTAB ld bc,5*_KEYS ; Fuenf Ebenen, 81 Tasten ldir or a ret ; ; Der Code fuer die Funktion KM SET KEY sieht exemplarisch wie folgt aus: ; .comment | 4485 LD A,C 4486 CP 51 4488 RET NC 4489 LD A,D 448A LD E,C 448B LD D,00 448D LD HL,477E 4490 CALL 44A8 4493 LD HL,47CF 4496 CALL 44A8 4499 LD HL,4820 449C CALL 44A8 449F LD HL,4871 44A2 CALL 44A8 44A5 LD HL,48C2 44A8 RRA 44A9 RET NC 44AA ADD HL,DE 44AB LD (HL),B 44AC RET | ; ; Getestet werden die ersten Bytes. ; refcode: db 079h,0feh,051h,0d0h,07ah,059h,016h,000h,021h reflen equ $-refcode ; ; Chain-adresse holen. ; Register IX zeigt auf Code JP LO HI ; getCHN: ld a,(ix+0) ; Testen, ob Wert legal cp _JP scf ret nz ; Nein ld e,(ix+1) ; Adresse laden ld d,(ix+2) or a ret ; _COT: jp $-$ _SELMEM: jp $-$ _USERF: jp $-$ ; XTAB equ $ .dephase SelLen equ $-SelCode ; ; Tabelle nicht anzuzeigender Tasten ; NoDisp: db 70 ; SHIFT LOCK db 21 ; SHIFT db 80 ; ALT db 74 ; EXTRA NoDlen equ $-NoDisp $RULE: db 'Das Programm zeigt den Tasten-Kode des PCW CP/M Computers' db cr,lf db 'Es zeigt einfach die Tastennummer und den Status an' db cr,lf db '(Nummer dezimal, Status als Bit-Pattern)' db cr,lf,lf db 'Start mit beliebiger Taste, Ende mit RETURN oder ENTRY' db cr,lf,eot $CR_KEY: db 'RETURN-Taste gefunden',eot $ENT_KEY: db 'ENTRY-Taste gefunden',eot $DELIM: db ' ist Nummer, Status ist ',eot $CHAR: db ', Zeichen ist ',eot $CRLF: db cr,lf,eot $ILLTAB: db 'Keine Zeichentabelle gefunden',cr,lf,eot $STATXT: db ' : ' $STAT: db 'A+SL+S+NL+R+CL+E' SLen equ $-$STAT db eot $SCHAR: db 'ASSNRCE' end