title B360K, a larger disk format for CP/M on the CPC ; Copyright 1986 by Andreas Ki~linger ; Version 1.4 28. April 1987 ; Will assemble with ZMAC as follows: ; ; >ZMAC b360k=b360k.zsm ; >ZLINK b360k=b360k ; ; the program realises if a 62K-CP/M ($OSC.SYS) by VORTEX is active ; and patches its automatic format log-in in a way, that only drive A ; is logged in automaticly. Otherwise you would have drive access with ; every disk-select, as Vortex-CP/M tries to readjust the format new ; each time and the Login routine cannot be switches off by a flag. ; The program will also work in CP/M 3.0 and the B360K-Format ; may be toggled off by the command B360K OFF. base = 0000h wboot = base bdos = base+5 stdfcb1 = base+5ch stdfcb2 = base+6ch ccpline = base+80h tpa = base+100h strout = 9 ; issues a string to the Console cpmver = 12 ; gets the CP/M-Version dskreset= 13 ; resets the disk system seldisk = 14 ; selects the Disk drive curdisk = 25 ; gets the selected drive getdpb = 31 ; gets the address of the Diskparameterblock cr = 0dh ; Carriage Return lf = 0ah ; Line Feed blank = ' ' ; strende = '$' ; String end no44kbios = 0e000h ; End of tiny TPA BIOS start: ld hl,ccpline ; address parameter line ld a,(hl) ; count of chars or a ; no parameter? jr z,dob360kon ; ==> valid parameter config. ld b,a ; Number of chars to B delblanks: ; skip TAB's and blanks inc hl ; next char address ld a,(hl) ; get next char cp blank ; is it a blank? jr nz,isparam ; no, then parameter djnz delblanks ; else repeat (number of chars) times jr dob360kon ; if only blanks ==> same as no param. isparam: ; Now test for parameter cp 'O' ; first char = 'O'? jr nz,paramerr ; no, then parameter error inc hl ; address second char ld a,(hl) ; get second char cp 'N' ; is 'ON' reached? jr z,dob360kon ; yes, install B360k cp 'F' ; is it an 'F'? jr nz,paramerr ; no, then parameter error inc hl ; else address third char ld a,(hl) ; get third char cp 'F' ; is 'OFF' reached? jr z,dob360koff ; yes, then B360K off paramerr: ; wrong parameter ld de,perrmsg ; address of errormessage ld c,strout ; prepare BDOS string out routine call bdos ; call it ret ; back to CCP dob360kon: ; continue her if no parameter or 'ON' ld de,mesg1 ; address of installation message ld c,strout ; prepare BDOS string out routine call bdos ; call it call getcpmversion ; CP/M-Version cp 22h ; not CP/M 2.2? jr nz,cpm30a ; then skip CP/M 2.2 part call checkoscsys ; check for VORTEX $OSC.SYS-BIOS jr nc,novortex ; No Carry ==> not $OSC.SYS ; else patch $OSC-BIOS call getpatchadr ; get patchaddress jr nz,novortex ; NZ ==> no patch possible! ld (hl),1 ; don't login B! inc hl ; next Byte previously RET Z ld (hl),0d0h ; now RET NC novortex: cpm30a: call getbdpb ; get DPB address of B ex de,hl ; swap address from DE to HL ld hl,new22dpb ; address of new CP/M 2.2 DPB ld bc,dpb22ende-new22dpb ; DPB length in BC ld a,(version) ; CP/M-Version number cp 22h ; is it CP/M 2.2? jr z,doldir ; then substitute DPB ld hl,new30dpb ; address of new CP/M 3.0 DPB ld bc,dpb30ende-new30dpb ; DPB length in BC doldir: ; now to move DPB ldir ; substitute old one call diskreset ; reset disk system ret ; back to CCP dob360koff: ; toggle B360K format off ld de,mesg2 ; address of removal message ld c,strout ; prepare BDOS string out routine call bdos ; put string to Console call getcpmversion ; CP/M-Version cp 22h ; is it CP/M 2.2? jr nz,cpm30b ; no, then for CP/M 3.0 routine call checkoscsys ; else test for $OSC-BIOS jr nc,isamstrad ; NC ==> 44K CP/M 2.2 call getpatchadr ; else get patch address jr nz,exitoscpatch ; NZ ==> no patch address ld (hl),2 ; else login upto drive B exitoscpatch: ; Ende of patches for $OSC-BIOS jr exitnob360k ; leave B360K OFF routine isamstrad: ; continue here for standard Amstrad BIOS cpm30b: call getbdpb ; DPB-address for B ld de,dpb22ende-new22dpb-1 ; last DPB-Byte in CP/M 2.2 ld a,(version) ; get Version number of CP/M cp 22h ; is it CP/M 2.2? jr z,doadd ; then set address of freeze flag ld de,dpb30ende-new30dpb-1 ; last DPB-Byte in CP/M 3.0 doadd: add hl,de ; Freeze Flag is being addressed ld (hl),0 ; allow automatic format detect exitnob360k: ; End of B360K OFF routine call diskreset ; reset disk system ret ; back to CCP getcpmversion: ; CP/M-Version ld c,cpmver ; BDOS get CP/M-Version call bdos ; call BDOS ld a,l ; load CP/M Version ld (version),a ; save CP/M-Version ret ; back to caller checkoscsys: ; $OSC.SYS-BIOS test ld de,(wboot+1) ; Warmboot address in DE ld b,2 ; maximal zweimal weitergeleitet checklp: ; Schleife zur Pr}fung ob 62K CP/M ld hl,no44kbios-1 ; unter dem Ende of the 44K-BIOS or a ; Carry l|schen sbc hl,de ; ist the Zieladdress gr|~er als 56K? jr c,is62kcpm ; then Flag for Bank-BIOS setzen ex de,hl ; else wieder address in HL inc hl ; address eines Sprungs addressieren ld e,(hl) ; Lowbyte holen inc hl ; Highbyte addressieren ld d,(hl) ; Highbyte holen djnz checklp ; n{chste Sprungaddress is62kcpm: ; Carry ==> 62K CP/M, NoCarry ==> kein $OSC ret ; back to Aufrufer getpatchadr: ; Patchaddress for $OSC-BIOS bestimmen ld hl,(wboot+1) ; WBOOT-address in HL holen ld de,19h ; Offset zur Adr. of the SELECT DISC Eintrags add hl,de ; Diskselektion wird nun addressiert ld a,(hl) ; Lowbyte der address holen inc hl ; Highbyte addressieren 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 of the addressparameters in A holen inc hl ; Highbyte of theselben addressieren 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,error ; no, then error inc hl ; n{chstes Byte addressieren ld a,(hl) ; Byte in A holen inc hl ; Highbyte of the Operanden addressieren or a ; war 16 Bit Operand 0? jr nz,error ; no, then error ld de,13h ; Offset zum CP-Befehl add hl,de ; CP nologindisk wird addressiert ld a,(hl) ; CP-Befehl sollte nun in A sein cp 0feh ; war es wirklich ein CP? jr nz,error ; no, then error inc hl ; else Operand von CP .. addressieren ret ; and R}ckkehr mit Z-Flag error: ld de,verrmsg ; Vortex-Anpassungserror ld c,strout ; prepare BDOS string out routine call bdos ; errormessage ausgeben or 0ffh ; Z-Flag zur}cksetzen ret ; bei error mit NZ zur}ckkehren getbdpb: ; DPB-address von drive B holen ld c,curdisk ; aktuelles call bdos ; Laufw. holen push af ; and sichern ld c,seldisk ; drive B ld e,01h ; selektieren call bdos ld c,getdpb ; DiskParam.Block call bdos ; dazu holen pop af ; vorheriges drive holen push hl ; DPB-address retten ld e,a ; in E als parameter for BDOS ld c,seldisk ; BDOS-Funktion drive w{hlen call bdos ; drive selektieren pop hl ; DPB-address holen ret ; back to Aufrufer diskreset: ; Diskettenverwaltung zur}cksetzen ld c,dskreset ; BDOS-Funktion Diskreset laden call bdos ; Diskettenverwaltung zur}cksetzen ret ; back to Aufrufer mesg1: db 'Das "B360K"-Format fuer 80 Spur-drivee ' db 'wird nun installiert!',cr,lf,strende mesg2: db 'Das "B360K"-Format fuer 80 Spur-drivee ' 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 only 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 and 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 for FDC) db 4 ; 4 Records pro Sektor db 79 ; Puffer for aktuelle Spur (jetzt maximal) db 79 ; maximale Spurnummer (bei Vortex) db 42h ; Flagbyte for Vortex-BIOS dpb22ende = $ ; Endaddress of the neuen DPB for 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 of the ersten Sektors dw 512 ; Sektorl{nge ist 512 Byte db 2ah ; L{nge von GAP 3 zum Lesen and Schreiben db 52h ; L{nge von GAP 3 zum Formatieren db 60h ; Modus = MFM and Skip Deleted Data db 0ffh ; kein neuer Formatlogin dpb30ende = $ version: db 0 ; Platz for CP/M-Version end ; Ende of the Assemblertextes