title Lade-/Speicherroutine fuer PCW-Tastenbelegung maclib base80 ; Datei : KEYPCW.MAC ; Dieses Programm speichert die aktuelle PCW-Tastenbelegung ; in eine Datei oder laedt eine Tabelle aus einer Datei. ; ACHTUNG DIES IST EIN PCW-PROGRAMM, DAS NICHT AUF ANDEREN ; CP/M-RECHNERN LAEUFT!!! ; ES MACHT NEBEN DEN EXTENDED BIOS FUNKTION (XBIOS) ; GEBRAUCH VON MASCHINENINTERNEN TABELLEN. ; Aufruf mit: ; KEYPCW -S Speichert die Tastenbelegung ; in die Datei KEY.@@@ ; KEYPCW -S DATEI Speichert die Tastenbelegung ; in die Datei DATEI ; KEYPCW -L Laedt die Tastenbelegung ; aus der Datei KEY.@@@ ; KEYPCW -L DATEI Laedt die Tastenbelegung ; aus der Datei DATEI ; Copyright (C) Werner Cirsovius Hohe Weide 44 ; D-20253 Hamburg ; +49 40 4223247 ; ; Version 1.0, Juni 1994 entry $memry,@error ext String,CmdArg,Parse,Filnam,Crlf ext Creatd,Open,Close,Delete,Dskwrt,Dskred ext SetDMA,MulSec .tblen equ 81 ; Gueltige Anzahl Tasten .states equ 5 ; Anzahl Tastenkombination .krecs equ 1 + .tblen*.states / reclng .argc equ 2 ; Maximale Argumente CPM3 equ 30h ; OS Version _USERF equ 30 ; ; XBIOS-Funktionen des PCW ; _KM.SET equ 00d7h ; Taste belegen _CD.VER equ 00e3h ; Version des PCW holen _SCREEN equ 00e9h ; User function ; ; Unterstuetzte BIOS-Versionen ; BIosmaj equ 1 ; BIOS major 1.x BIOSmna equ 4 ; BIOS 1.4 BIOSmnb equ 8 ; BIOS 1.8 BIOSmnc equ 12 ; BIOS 1.12 _PCW equ 1 @COMMON equ 0c000h ; Start des COMMON-Speichers .CPUerr equ 0 .OSerr equ .CPUerr+2 .MCHerr equ .OSerr+2 .BIOSer equ .MCHerr+2 .ARGerr equ .BIOSer+2 .OPTerr equ .ARGerr+2 .PARSer equ .OPTerr+2 .COMerr equ .PARSer+2 .MEMerr equ .COMerr+2 dseg $memry: dw 0 @ARGC: db 0 @ARGV: ds 2*.argc @MCH: dw 0 @opt@: db 0 @XLATE: ds 2 FCB@@@: db 0,'KEY @@@' P.PB: dw 0,FCB ; ; Adresstabelle mit den Basisadressen der Tastentabellen ; SYS$ADR: dw 1780h ; BIOS 1.4 dw 4948h ; BIOS 1.8 dw 477eh ; BIOS 1.12 ErrTab: dw $CPUerr,$OSerr,$MCHerr,$BIOSer,$ARGerr,$OPTerr dw $COMerr,$MEMerr $CPUerr: db 'Z80 CPU ist notwendig',eot $OSerr: db 'CP/M 3.x ist notwendig',eot $MCHerr: db 'Zum Programm ist ein AMSTRAD PCW 8xxx n|tig',eot $BIOSer: db 'Unterst}tzt nur BIOS 1.4, 1.8 und 1.12',eot $ARGerr: db 'Dieses Programm speichert einfach den den aktuellen Zustand der Zeichentabelle',cr,lf db 'in eine Datei oder l{dt eine Tabelle ais einer Datei.',cr,lf db 'ACHTUNG',tab,'DIES IST EIN PCW-PROGRAMM, DAS NICHT AUF ANDEREN',cr,lf db tab,'CP/M-RECHNERN LAEUFT!!!',cr,lf db tab,'ES MACHT NEBEN DEN EXTENDED BIOS FUNKTION (XBIOS)',cr,lf db tab,'GEBRAUCH VON MASCHINENINTERNEN TABELLEN.',cr,lf,lf db 'Aufruf mit:',cr,lf db tab,'KEYPCW -S',tab,'Speichert die Tastenbelegung',cr,lf db tab,tab,tab,'in die Datei KEY.@@@',cr,lf db tab,'KEYPCW -S DATEI',tab,'Speichert die Tastenbelegung',cr,lf db tab,tab,tab,'in die Datei DATEI',cr,lf db tab,'KEYPCW -L',tab,'L{dt die Tastenbelegung',cr,lf db tab,tab,tab,'aus der Datei KEY.@@@',cr,lf db tab,'KEYPCW -L DATEI',tab,'Laedt die Tastenbelegung',cr,lf db tab,tab,tab,'aus der Datei DATEI',eot $OPTerr: db 'Ung}ltige Option - entwederr -L oder -S',eot $COMerr: db 'H|chste verf}gbare Adresse liegt unter COMMON',eot $MEMerr: db 'Nicht genug Speicher f}r Tasten-Tabelle',eot $FETCH: db 'Laden der Tasten-Tabelle ...',cr,lf,eot $READ: db 'Lesen der Tasten-Tabelle ...',cr,lf,eot $WRT.TAB: db 'Schreiben der Tasten-Tabelle ...',cr,lf,eot $NO.CREC: db 'FEHLER: Anlegefehler der Datei ',eot $WR.ERR: db 'FEHLER: Schreibfehler der Datei ',eot $RD.ERR: db 'FEHLER: Lesefehler der Datei ',eot $NO.CLOS: db 'FEHLER: Schliessfehler der Datei ',eot $NO.OPEN: db 'FEHLER: Datei nicht gefunden ',eot $DONE: db 'Fertig, Tastenbelegung geschrieben in Datei ',eot $READY: db 'Fertig, neue Tasten definiert',eot ; ds 2*32 LocStk: cseg ; ; ** Pseudosymbol ** Fehlerroutine - Umgehung in der Library ; @error: ret ; ; Aufruf zur eXtended BIOS Routine ; XBIOS: jp $-$ ; ; Fehlermeldung durch Index ausgeben ; EIN Register HL haelt Tabellenindex ; _ERRidx: ld de,ErrTab add hl,de ; Zeiger ermitteln ld e,(hl) ; .. Adresse holen inc hl ld d,(hl) call String ; .. Ausgabe jp OS ; .. Ende ; ; Test der korrekten Umgebung ; _env_:: ld hl,_ERRidx push hl ; .. Fehlerroutine setzen ld hl,.CPUerr sub a ; Schritt 1 : Verifizieren der Z80 CPU ret pe ; .. sollte sein ld c,.vers call BDOS ; Schritt 2 : Test richtiges Betriebssystem ld a,l cp CPM3 ld hl,.OSerr ret c ; . . sollte sein ld hl,(OS+1) ; XBIOS Vektor ermitteln ld bc,3*(_USERF-1) add hl,bc ld (XBIOS+1),hl call XBIOS ; Schritt 3 : Maschine holen dw _CD.VER ld hl,.MCHerr cp _PCW ; Die richtige Maschine testen ret nz ; .. sollte sein ld hl,.BIOSer ld a,b cp BIOSmaj ret nz ; .. ebenfalls ld a,c cp BIOSmna jr z,MCHok cp BIOSmnb jr z,MCHok cp BIOSmnc ret nz MCHok: srl a ; .. Wert durch 2 teilen ld (@MCH),a ; .. Typ speichern pop af ; .. Stack zuruecksetzen ret ; ; Option holen ; _opt_:: ld hl,_ERRidx ; .. Fehlerroutine setzen push hl ld hl,@ARGV ld de,CCPlen ld b,.argc call CmdArg ; .. Argumente holen ld hl,.ARGerr ret c ; .. Fehler ld (@ARGC),a ; Anzahl speichern ld ix,(@ARGV+0) ; Erstes Argument holen ld a,(ix+0) ; Muss Option sein cp '-' ret nz pop iy ld hl,.OPTerr ld a,(ix+1) ; Option holen ld (@opt@),a ; .. speichern cp 'L' ; Auswahl ueberpruefen ret z cp 'S' ret z jp (iy) ; .. Fehler ; ; Dateiumgebung vorbereiten ; _file_:: ld de,($memry) call SetDMA ; Diskettenpuffer setzen ld a,.krecs call MulSec ; Anzahl Sektoren festlegen ld de,FCB ld hl,FCB@@@ ld bc,.fdrv+.fext+.fname ldir ; Voreinstellung laden ld a,(@ARGC) ; Anzahl holen dec a ret z ; .. das war es ld hl,(@ARGV+2) ; Dateizeiger laden ld (P.PB),hl ; .. ablegen ld de,P.PB call Parse ; .. wandeln in FCB ret nc ld hl,.PARSer jp _ERRidx ; .. Fehler ; ; Test ob genug Speicher vorhanden ist ; EIN Register DE haelt die hoechste Speicheradresse ; AUS Carry gesetzt falls genug ; Sonst haelt Register HL Fehlerindex ; _mem.free:: ld hl,($memry) ; Erste freie Adresse laden ld bc,.krecs*reclng add hl,bc ; .. hoechste Adresse berechnen or a sbc hl,de ; .. test ob Platz ist ld hl,.MEMerr ret ; ; ############################## ; ### TASTENSTATUS SPEICHERN ### ; ############################## ; KEY.SAV:: call _iniCOMM ; COMMON Speicher setzen ld de,$FETCH call String ; Laden anzeigen ld hl,($memry) ; Oberen Speicher laden ld b,.tblen ; .. und Hauptzaehler ld c,0 ; .. und aktuelle Tastennummer SAV.loop: push bc ld d,00000001b ; Tastenmake setzen ld b,.states ; .. und Zustandszaehler SAV.state: push bc push de push hl ld e,c ; Get key # ld bc,(@XLATE) ; Adresse holen call XBIOS ; Hex in Register B holen dw _SCREEN pop hl ld (hl),b ; Diesen Wert speichern inc hl pop de sla d ; Naechster Zustand pop bc djnz SAV.state pop bc inc c ; Naechste Taste djnz SAV.loop ld de,$WRT.TAB call String ; Speichern anzeigen ld de,FCB ; Datei vorbereiten call Creatd ; Datei anlegen ld de,$NO.CREC jr c,comerr ; .. Fehler ld de,FCB call Dskwrt ; .. komplette Tabelle in Datei schreiben ld de,$WR.ERR jr c,comerr ; .. Fehler ld de,FCB ; Datei schliessen call Close ld de,$NO.CLOS jr c,comerr ; .. Fehler ld de,$DONE comstr:: call String ; .. Ergebnis mitteilen ld de,FCB+.fdrv call Filnam ; Dateinamen ausgeben call Crlf jp OS comerr:: push de ld de,FCB ; Bei Fehler Datei loeschen call Delete pop de jr comstr ; ; COMMON Speicher setzen ; _iniCOMM:: ld hl,(@MCH) ; Index aus Version holen ld de,SYS$ADR-2 add hl,de ; .. Zeiger auf Tabelle ld e,(hl) ; .. Adresse holen inc hl ld d,(hl) ex de,hl ld bc,.tblen ld (@T1+1),hl ; .. Adresse ablegen add hl,bc ld (@T2+1),hl add hl,bc ld (@T3+1),hl add hl,bc ld (@T4+1),hl add hl,bc ld (@T5+1),hl ld hl,_ERRidx ; Fehler setzen push hl ld hl,(BDOS+1) ; Hoechste Speicheradresse laden dec hl ld bc,-CLen.1-CLen.2 add hl,bc ; Basisadresse berechnen ld de,@COMMON or a sbc hl,de ; Test ob im COMMON ld hl,.COMerr ret c ; .. nicht genug Speicher ld hl,@CODE.1 ld bc,CLen.1 ldir ; .. Teil 1 umkopieren ld (@XLATE),de ; .. speichern der Adresse zum Teil 2 ld bc,CLen.2 ldir ; .. Teil 2 umkopieren ld de,@COMMON call _mem.free ; .. Test ob genug Speicher ret nc ; .. nein pop af ret ; ; !!!!!!!!!! DER FOLGENDE CODE WIRD IN DEN COMMON SPEICHER VERSCHOBEN !!!!!!!!!! ; ; Ermitteln der Adresse des Tastaturzustands ; EIN Akku haelt Bit Maske ; Register HL haelt Start der Tabelle ; AUS Register B haelt Hex-Wert bei gesetzter LSB der Maske ; Akku ein Bit rechts verschoben ; @CODE.1: rra ; Test ob Bit gesetzt ret nc ; .. ignorieren wenn nicht add hl,de ; Sonst Adresse berechnen ld b,(hl) ; .. und Inhalt holen ret CLen.1 equ $-@CODE.1 ; ; Holen des Tatenwertes ; EIN Register E haelt Tastennummer ; Register D haelt Zustands-Bit ; AUS Register B haelt Tastenwert ; @CODE.2: ld a,e ; Test ob Tastennummer gueltig cp .tblen ret nc ld a,d ; Maske holen ld d,0 ; Tastennummer auf 16 Bit ausweiten @T1: ld hl,$-$ ; Dann Tastenwert holen call @COMMON @T2: ld hl,$-$ call @COMMON @T3: ld hl,$-$ call @COMMON @T4: ld hl,$-$ call @COMMON @T5: ld hl,$-$ call @COMMON ret CLen.2 equ $-@CODE.2 ; ; !!!!!!!!!! ENDE DER VERSCHIEBUNG IN DEN COMMON SPEICHER !!!!!!!!!! ; ; ########################## ; ### TASTENSTATUS LADEN ### ; ########################## ; KEY.LOD:: ld de,(BDOS+1) call _mem.free ; Test ob genug Speicher jp nc,_ERRidx ; .. nein ld de,$READ call String ; Lesen anzeigen ld de,FCB ; Datei vorbereiten call Open ld de,$NO.OPEN jp c,comstr ; .. Datei nicht gefunden ld de,FCB call Dskred ; .. komplette Tabelle von Datei lesen ld de,$RD.ERR jp c,comstr ; .. Fehler ld de,$FETCH call String ; Laden anzeigen ld hl,($memry) ; Oberen Speicher laden ld b,.tblen ; .. und Hauptzaehler ld c,0 ; .. und aktuelle Tastennummer LOD.loop: push bc ld d,00000001b ; Tastenmake setzen ld b,.states ; .. und Zustandszaehler LOD.state: push bc push de push hl ld b,(hl) ; Tastenwert holen call XBIOS ; In Tabelle eintragen dw _KM.SET pop hl inc hl pop de sla d ; Naechster Zustand pop bc djnz LOD.state pop bc inc c ; Naechste Taste djnz LOD.loop ld de,$READY call String ; .. anzeigen wenn fertig call crlf jp OS ; ; %%%%%%%%%%%%%%%%%%%%% ; %%% HAUPTPROGRAMM %%% ; %%%%%%%%%%%%%%%%%%%%% ; KEYPCW:: ld sp,LocStk ; Lokalen Stack laden call _env_ ; Richtige Umgebung testen call _opt_ ; Option holen call _file_ ; Datei holen ld a,(@opt@) ; Option laden cp 'S' ; Test 'S'peichern push af call z,KEY.SAV ; .. speichern pop af call nz,KEY.LOD ; .. laden jp OS end KEYPCW