title B360K, ein gr|~eres Diskettenformat f}r CP/M auf dem CPC ; Copyright 1986 by Andreas Ki~linger ; Version 1.4 vom 28.04.1987 ; Diese Datei ist dem ZMAC angepasst. Zum Assemblieren ; mu~ man die folgende Befehlssequenz eingeben: ; ; >ZMAC b360k=b360k.zsm ; >ZLINK b360k=b360k ; ; Das Programm erkennt, ob ein 62K-CP/M ($OSC.SYS) aktiv ; ist und patcht den automatischen Formateinlogger von ; Vortex so, da~ nur noch das Laufwerk A automatisch ; eingeloggt wird. Ansonsten w}rde bei jedem Disk-Select ; ein Zugriff erfolgen, da Vortex jedesmal das Format neu ; bestimmt und die Einlogroutine sich nicht mit einem Flag ; (wie bei Amstrad) abstellen l{~t. Weiterhin arbeitet ; dieses Programm auch unter CP/M 3.0 und das B360K-Format ; l{~t sich durch den Aufruf von B360K OFF wieder abschalten. base = 0000h wboot = base bdos = base+5 stdfcb1 = base+5ch stdfcb2 = base+6ch ccpline = base+80h tpa = base+100h strout = 9 ; gibt einen String auf der Console aus cpmver = 12 ; holt die aktuelle CP/M-Versionsnummer dskreset= 13 ; setzt die Diskverwaltung zur}ck seldisk = 14 ; w{hlt das gew}nschte Diskettenlaufwerk aus curdisk = 25 ; holt das aktuell gew{hlte Laufwerk getdpb = 31 ; holt die Adresse des Diskparameterblocks cr = 0dh ; Wagenr}cklauf lf = 0ah ; Zeilenvorschub blank = ' ' ; Leerzeichen strende = '$' ; Stringendekennzeichen no44kbios = 0e000h ; Ende des kleinen BIOS start: ld hl,ccpline ; Parameterzeile adressieren ld a,(hl) ; Anzahl der Zeichen holen or a ; keine Parameter? jr z,dob360kon ; ==> g}ltige Parameterkonfig. ld b,a ; Anzahl der Zeichen in B laden delblanks: ; ]berlesen von TAB's und Blanks inc hl ; n{chstes Zeichen adr. ld a,(hl) ; n{chstes Zeichen holen cp blank ; ist es ein Blank? jr nz,isparam ; nein, dann Parameter djnz delblanks ; sonst sooft wie Anzahl Zeichen wdh. jr dob360kon ; wenn nur Blanks ==> wie ohne Param. isparam: ; Nun kann auf Parameter getestet werden cp 'O' ; erstes Zeichen = 'O'? jr nz,paramerr ; nein, dann Parameterfehler inc hl ; zweites Zeichen adressieren ld a,(hl) ; zweites Zeichen holen cp 'N' ; ist es 'ON' erreicht? jr z,dob360kon ; ja, dann B360k installieren cp 'F' ; ist es ein 'F'? jr nz,paramerr ; nein, dann Parameterfehler inc hl ; sonst drittes Zeichen adr. ld a,(hl) ; drittes Zeichen holen cp 'F' ; ist 'OFF' erreicht? jr z,dob360koff ; ja, dann B360K ausschalten paramerr: ; falscher Parameter angegeben ld de,perrmsg ; Fehlermeldung adressieren ld c,strout ; BDOS-Stringausgabe call bdos ; einleiten ret ; R}ckkehr zum CCP dob360kon: ; Hier weiter, wenn ohne Parameter oder 'ON' ld de,mesg1 ; Installierungsmeldung adressieren ld c,strout ; zum Meldungen ausgeben call bdos ; und ausgeben call getcpmversion ; CP/M-Version abfragen cp 22h ; ist es nicht CP/M 2.2? jr nz,cpm30a ; dann Teil f}r CP/M 2.2 }berspringen call checkoscsys ; $OSC.SYS-BIOS abpr}fen jr nc,novortex ; No Carry ==> kein $OSC.SYS ; sonst $OSC-BIOS patchen call getpatchadr ; Patchadresse holen jr nz,novortex ; NZ ==> kein Patch m|glich! ld (hl),1 ; B soll nicht mehr eingeloggt werden! inc hl ; n{chstes Byte ist vorher ein RET Z ld (hl),0d0h ; nun ist es ein RET NC novortex: cpm30a: call getbdpb ; DPB-Adresse von B holen ex de,hl ; Adresse in DE holen ld hl,new22dpb ; Adresse des neuen 2.2 DPB ld bc,dpb22ende-new22dpb ; DPB-L{nge in BC ld a,(version) ; CP/M-Versionsnummer holen cp 22h ; ist es CP/M 2.2? jr z,doldir ; dann DPB ersetzen ld hl,new30dpb ; Adresse des neuen 3.0 DPB ld bc,dpb30ende-new30dpb ; DPB-L{nge in BC doldir: ; jetzt zum Verschieben des DPB ldir ; alten ersetzen call diskreset ; Diskverwaltung zur}cksetzen ret ; zum CCP zur}ckkehren dob360koff: ; B360K-Format wieder abschalten ld de,mesg2 ; Abschaltungsmeldung adressieren ld c,strout ; BDOS-Stringausgabefunktion call bdos ; String auf Console ausgeben call getcpmversion ; CP/M-Version bestimmen cp 22h ; ist es CP/M 2.2? jr nz,cpm30b ; nein, dann f}r CP/M 3.0 weiter call checkoscsys ; sonst auf $OSC-BIOS testen jr nc,isamstrad ; NC ==> 44K CP/M 2.2 call getpatchadr ; sonst Patchadresse betimmen jr nz,exitoscpatch ; NZ ==> keine Patchadresse ld (hl),2 ; sonst bis Laufwerk B einloggen exitoscpatch: ; Ende des Patches f}r $OSC-BIOS jr exitnob360k ; B360K OFF verlassen isamstrad: ; Hier weiter f}r Amstrad BIOS cpm30b: call getbdpb ; DPB-Adresse f}r B holen ld de,dpb22ende-new22dpb-1 ; letztes DPB-Byte in CP/M 2.2 ld a,(version) ; Versionsnummer CP/M holen cp 22h ; ist es CP/M 2.2? jr z,doadd ; dann Freezeflagadresse bestimmen ld de,dpb30ende-new30dpb-1 ; letztes DPB-Byte in CP/M 3.0 doadd: add hl,de ; Freeze-Flag wird adressiert ld (hl),0 ; automatische Formaterkennung zulassen exitnob360k: ; Ende von B360K OFF call diskreset ; Diskverwaltung zur}cksetzen ret ; R}ckkehr zum CCP getcpmversion: ; CP/M-Version holen ld c,cpmver ; BDOS-CP/M-Version holen call bdos ; BDOS aufrufen ld a,l ; CP/M Version in Akku laden ld (version),a ; aktuelle CP/M-Version speichern ret ; R}ckkehr zum Aufrufer checkoscsys: ; $OSC.SYS-BIOS testen ld de,(wboot+1) ; Warmbootadresse in DE holen ld b,2 ; maximal zweimal weitergeleitet checklp: ; Schleife zur Pr}fung ob 62K CP/M ld hl,no44kbios-1 ; unter dem Ende des 44K-BIOS or a ; Carry l|schen sbc hl,de ; ist die Zieladresse gr|~er als 56K? jr c,is62kcpm ; dann Flag f}r Bank-BIOS setzen ex de,hl ; sonst wieder Adresse in HL inc hl ; Adresse eines Sprungs adressieren ld e,(hl) ; Lowbyte holen inc hl ; Highbyte adressieren ld d,(hl) ; Highbyte holen djnz checklp ; n{chste Sprungadresse is62kcpm: ; Carry ==> 62K CP/M, NoCarry ==> kein $OSC ret ; R}ckkehr zum Aufrufer getpatchadr: ; Patchadresse f}r $OSC-BIOS bestimmen ld hl,(wboot+1) ; WBOOT-Adresse in HL holen ld de,19h ; Offset zur Adr. des SELECT DISC Eintrags add hl,de ; Diskselektion wird nun adressiert ld a,(hl) ; Lowbyte der Adresse holen inc hl ; Highbyte adressieren ld h,(hl) ; Highbyte in H holen ld l,a ; Lowbyte von A nach L holen inc hl ; CALL-Befehl }berlesen inc hl inc hl ld a,(hl) ; Lowbyte des Adressparameters in A holen inc hl ; Highbyte desselben adressieren ld h,(hl) ; Highbyte in H holen ld l,a ; Lowbyte von A nach L holen ; Jetzt sind wir bei der Diskselektion ld a,(hl) ; erstes Byte der Routine holen cp 21h ; ist es der LD HL,... Befehl? jr nz,fehler ; nein, dann Fehler inc hl ; n{chstes Byte adressieren ld a,(hl) ; Byte in A holen inc hl ; Highbyte des Operanden adressieren or a ; war 16 Bit Operand 0? jr nz,fehler ; nein, dann Fehler ld de,13h ; Offset zum CP-Befehl add hl,de ; CP nologindisk wird adressiert ld a,(hl) ; CP-Befehl sollte nun in A sein cp 0feh ; war es wirklich ein CP? jr nz,fehler ; nein, dann Fehler inc hl ; sonst Operand von CP .. adressieren ret ; und R}ckkehr mit Z-Flag fehler: ld de,verrmsg ; Vortex-Anpassungsfehler ld c,strout ; BDOS-Stringausgabe vorbereiten call bdos ; Fehlermeldung ausgeben or 0ffh ; Z-Flag zur}cksetzen ret ; bei Fehler mit NZ zur}ckkehren getbdpb: ; DPB-Adresse von laufwerk B holen ld c,curdisk ; aktuelles call bdos ; Laufw. holen push af ; und sichern ld c,seldisk ; Laufwerk B ld e,01h ; selektieren call bdos ld c,getdpb ; DiskParam.Block call bdos ; dazu holen pop af ; vorheriges Laufwerk holen push hl ; DPB-Adresse retten ld e,a ; in E als Parameter f}r BDOS ld c,seldisk ; BDOS-Funktion Laufwerk w{hlen call bdos ; Laufwerk selektieren pop hl ; DPB-Adresse holen ret ; R}ckkehr zum Aufrufer diskreset: ; Diskettenverwaltung zur}cksetzen ld c,dskreset ; BDOS-Funktion Diskreset laden call bdos ; Diskettenverwaltung zur}cksetzen ret ; R}ckkehr zum Aufrufer mesg1: db 'Das "B360K"-Format fuer 80 Spur-Laufwerke ' db 'wird nun installiert!',cr,lf,strende mesg2: db 'Das "B360K"-Format fuer 80 Spur-Laufwerke ' db 'wird nun abgeschaltet!',cr,lf,strende verrmsg: db 'Vortex Disklogin kann nicht automatisch gepatched ' db 'werden!',cr,lf,'B360K (vermutlich) so nicht ' db 'korrekt lauffaehig!',cr,lf,strende perrmsg: db 'B360K darf nur mit ON oder OFF oder ganz ohne ' db 'Parameter',cr,lf,'aufgerufen werden. Ein Aufruf ' db 'ohne Parameter wirkt wie B360K ON!',cr,lf,strende new22dpb: dw 36 ; 36 Records pro Spur db 4 ; Blockshift := 4 ( 2^4=16 Records/Block) db 15 ; Blockmask := 15 (15+1=16 Records/Block) db 1 ; Extentmask := 1 (2 Extents/Direntry) dw 174 ; Maxblock := 174 (gr|~te Blocknummer) dw 63 ; Maxdir := 63 (gr|~ter Direntry) db 80h,00h ; 1 Directoryblock (Bitmap) dw 16 ; 64 gepr}fte Direintr{ge (64/4=16) dw 2 ; 2 reservierte Spuren ; bis hierher wars Standard, jetzt kommt Amstrad/Vortex db 41h ; erster physikalischer Sektor db 9 ; 9 physikalische Sektoren pro Spur db 2ah ; L{nge von GAP 3 zum Lesen und Schreiben db 52h ; L{nge von GAP 3 zum Formatieren db 0e5h ; F}llbyte zum Formatieren db 2 ; 2^2=4 Records pro Sektor (Wert f}r FDC) db 4 ; 4 Records pro Sektor db 79 ; Puffer f}r aktuelle Spur (jetzt maximal) db 79 ; maximale Spurnummer (bei Vortex) db 42h ; Flagbyte f}r Vortex-BIOS dpb22ende = $ ; Endadresse des neuen DPB f}r 2.2 new30dpb: dw 36 ; 36 Records pro Spur db 4 ; Blockshift := 4 ( 2^4=16 Records/Block) db 15 ; Blockmask := 15 (15+1=16 Records/Block) db 1 ; Extentmask := 1 (2 Extents/Direntry) dw 174 ; Maxblock := 174 (gr|~te Blocknummer) dw 63 ; Maxdir := 63 (gr|~ter Direntry) db 80h,00h ; 1 Directoryblock (Bitmap) dw 16 ; 64 gepr}fte Direintr{ge (64/4=16) dw 2 ; 2 reservierte Spuren db 2 ; 2^2=4 Records pro Sektor (PSH) db 3 ; max. Recordnr. im Sektor (PHM) ; Bis hierher wars CP/M 3.X Standard, jetzt kommt Amstrad dran db 0 ; Seitenstruktur db 80 ; 80 Spuren pro Seite db 9 ; 9 physikalische Sektoren pro Spur db 41h ; Nummer des ersten Sektors dw 512 ; Sektorl{nge ist 512 Byte db 2ah ; L{nge von GAP 3 zum Lesen und Schreiben db 52h ; L{nge von GAP 3 zum Formatieren db 60h ; Modus = MFM und Skip Deleted Data db 0ffh ; kein neuer Formatlogin dpb30ende = $ version: db 0 ; Platz f}r CP/M-Version end ; Ende des Assemblertextes