{ CHG.PAS of JUGPDS Vol.11 by M. Miyao (No.78) } program disk_parameter_change(input, output ); const TARGETDRV = 1; { 0:A 1:B 2:C 3:D 4:E 5:F } DPBADR = $40; { $40 ~ $51 : work area } RSFLAG = $4F; SAVEADRL = $50; SAVEADRH = $51; CHANGE = 1; UNCHANGE = 14; { these pattern may not in initial memory data } SORCEDISK = 3; { Turbo Pascal source drive number } type dsktype = ( reset, pcsingle, pcdouble, pc88, pc98, if8, fm8, fm7, mz, pasopia, qc10, yours{ Change this to your system type if there is not, or add new target system type, procedures printtable and initdpb also must be rewritten, if add more than 2 then rewrite nans range }); dpbmem = ( sectl, secth, blkshf, blkmsk, extmsk, dksm1l, dksm1h, dirm1l, dirm1h, dirblkh, dirblkl, cksd4l, cksd4h, ofsl, ofsh ); dpb = array [sectl..ofsh] of byte; var alvcsvover : boolean; { ALV,CSV area overflow OK? } ans : char; dskno : integer; dpbtable : array[dsktype] of dpb; mydsktype, targetdsk : dsktype; nans : 0..11; { change range when you add more than 2 types } function peek( adr : integer ) : byte; begin peek := mem[adr]; end; procedure poke( adr : integer; data : byte ); begin mem[adr] := data; end; function getdphadr( dsk : integer ) : integer; begin getdphadr := bioshl( 8 {seldisk}, dsk ); end; function getdpbadr( dsk : integer ) : integer; var dphadr : integer; begin dphadr := getdphadr( dsk ); getdpbadr := peek(dphadr+10)+256*peek(dphadr+11); end; procedure printtable; begin writeln('* CHG: Change Disk Format *'); writeln('Specify target disk type.'); writeln(' Reset to org. disk: 0 or'); writeln(' PC-8001(single side): 1'); writeln(' PC-8001(double side): 2'); writeln(' PC-8801, FP-1100: 3'); writeln(' PC-9801: 4'); writeln(' if800: 5'); writeln(' FM-8: 6'); writeln(' FM-7: 7'); writeln(' Sharp MZ: 8'); writeln(' TOSHIBA Pasopia: 9'); writeln(' QC-10: 10'); { writeln(' : 11'); add here new disk } write (' Which disk? Select one: '); end; procedure setmydsktype; { Define here your working system type, then you must change this procedure for your system } begin alvcsvover:= true; { if ALV, CSV area overflow OK then true } mydsktype := qc10; { Change your own system type } dskno := TARGETDRV; { A:0, B:1, C:2, D:3, E:4, F:5 } end; procedure initdpb( dtype : dsktype ); { Set up data is following ---------------------------------------------------------------------------- System type | PC-8001 | PC8801 | | | | | -------------|-------------| FM-7 | PC9801 | MZ | if800 |Pasopia| QC-10 Parameter | 1D | 2D | FM-8 | | | | | -------------|-------------------------------------------------------------- Sectors(l) | 20 | 40 | 40 | 40 | 40 | 40 | 40 | 40 (h) | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 -------------|------|------|--------|--------|------|-------|-------|------- blkshft | 03 | 04 | 04 | 04 | 04 | 04 | 04 | 04 -------------|------|------|--------|--------|------|-------|-------|------- blkmask | 07 | 0F | 0F | 0F | 0F | 0F | 0F | 0F -------------|------|------|--------|--------|------|-------|-------|------- extmask | 00 | 01 | 01 | 01 | 01 | 01 | 01 | 01 -------------|------|------|--------|--------|------|-------|-------|------- dsksize-1(l)| 83 | 97 | 97 | 9B | 7F | 7F | 93 | 8B (h)| 00 | 00 | 00 | 00 | 00 | 00 | 00 | -------------|------|------|--------|--------|------|-------|-------|------- dirnum.-1(l)| 3F | 7F/3F| 7F/3F | 7F/3F | 3F | 7F/3F | 3F | 3F (h)| 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 -------------|------|------|--------|--------|------|-------|-------|------- dirblok(h) | C0 | C0/80| C0/80 | C0/80 | 80 | C0/80 | 80 | 80 -------------|------|------|--------|--------|------|-------|-------|------- dirblok(l) | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 -------------|------|------|--------|--------|------|-------|-------|------- check/4(l) | 10 | 20/10| 20/10 | 20/10 | 10 | 20/10 | 10 | 10 check/4(h) | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 -------------|------|------|--------|--------|------|-------|-------|------- offset(l) | 02 | 02 | 02 | 01 | 02 | 03 | 03 | 04 (h) | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 dirnum.-1,dirblok(h),check/4 : 128dir/64dir } var p : dsktype; begin for p := pcsingle to qc10 { here add your system } do begin { set standard (pc88) data } dpbtable[ p, sectl ] := $40; { sectors } dpbtable[ p, secth ] := $00; dpbtable[ p, blkshf ] := $04; { blkshft } dpbtable[ p, blkmsk ] := $0F; { blkmask } dpbtable[ p, extmsk ] := $01; { extmask } dpbtable[ p, dksm1l ] := $97; { dsk - 1 } dpbtable[ p, dksm1h ] := $00; { If your system has only 64 directory entries, the area of CSV and ALV will overflow when reading the disk sytem with 128 directory entries, then you must set DPB as 64 and you cannot write files more than 64. } dpbtable[ p, dirm1l ] := $7F; { dir - 1 }; dpbtable[ p, dirblkh ] := $C0; { dirblk(h) } dpbtable[ p, cksd4l ] := $20; { cks/4 } dpbtable[ p, dirm1h ] := $00; dpbtable[ p, dirblkl ] := $00; { dirblk(l) } dpbtable[ p, cksd4h ] := $00; dpbtable[ p, ofsl ] := $02; { ofset } dpbtable[ p, ofsh ] := $00; { Set different byte for suitable to the system } case p of pcsingle : begin dpbtable[ p, sectl ] := $20; { sectors } dpbtable[ p, blkshf ] := $03; { blkshft } dpbtable[ p, blkmsk ] := $07; { blkmask } dpbtable[ p, extmsk ] := $00; { extmask } dpbtable[ p, dksm1l ] := $83; { dsk - 1 } dpbtable[ p, dirm1l ] := $3F; { dir - 1 }; dpbtable[ p, dirblkh] := $C0; { dirblk(h) } dpbtable[ p, cksd4l ] := $10; { cks/4 } end; pcdouble, pc88, fm8, fm7 : {do nothing}; pc98 : begin dpbtable[ p, dksm1l ] := $9B; { dsk - 1 } dpbtable[ p, ofsl ] := $01; { ofset } end; if8 : begin dpbtable[ p, dksm1l ] := $7F; { dsk - 1 } dpbtable[ p, ofsl ] := $03; { ofset } end; mz : begin dpbtable[ p, dksm1l ] := $7F; { dsk - 1 } dpbtable[ p, dirm1l ] := $3F; { dir - 1 }; dpbtable[ p, dirblkh] := $80; { dirblk(h) } dpbtable[ p, cksd4l ] := $10; { cks/4 } end; pasopia : begin dpbtable[ p, dksm1l ] := $93; { dsk - 1 } dpbtable[ p, ofsl ] := $03; { ofset } dpbtable[ p, dirm1l ] := $3F; { dir - 1 }; dpbtable[ p, dirblkh] := $80; { dirblk(h) } dpbtable[ p, cksd4l ] := $10; { cks/4 } end; qc10 : begin dpbtable[ p, dksm1l ] := $8B; { dsk - 1 } dpbtable[ p, ofsl ] := $04; { ofset } dpbtable[ p, dirm1l ] := $3F; { dir - 1 }; dpbtable[ p, dirblkh] := $80; { dirblk(h) } dpbtable[ p, cksd4l ] := $10; { cks/4 } end; { here adds your new system data which differ from standard data } end; end; if not alvcsvover then for p := pcsingle to qc10 { here add your system } do begin if dpbtable[ mydsktype, dksm1l ] < dpbtable[ p, dksm1l ] then dpbtable[ p, dksm1l ] := dpbtable[ mydsktype, dksm1l ]; if dpbtable[ mydsktype, dirm1l ] < dpbtable[ p, dirm1l ] then dpbtable[ p, dirm1l ]:= dpbtable[ mydsktype, dirm1l ]; if dpbtable[ mydsktype, dirblkh] < dpbtable[ p, dirblkh ] then dpbtable[ p, dirblkh ]:= dpbtable[ mydsktype, dirblkh]; if dpbtable[ mydsktype, cksd4l ] < dpbtable[ p, cksd4l ] then dpbtable[ p, cksd4l ]:= dpbtable[ mydsktype, cksd4l ]; { limit the maximum target disk size to your system } end; end; procedure savedpbadr; var address : integer; begin address := getdpbadr( dskno ); poke( SAVEADRL, lo(address)); poke( SAVEADRH, hi(address)); end; { ------------ -------- getdphadr(disk#) | sector(l) | 40 DPBADR -----. | XLTTBL | ------------ | -------- | sector(h) | 41 | | 0000 | ------------ | -------- : | | 0000 | : | -------- ------------ | | 0000 | | offset(h) | 4E | -------- ------------ | | DIRBUF | | set/res flg| 4F RSFLAG | -------- ------------ '--> | DPBADR | -. | save old | 50 SAVEADRL -------- | ------------ <-- | CSV n | | | DPB addr. | 51 SAVEADRH | -------- | ------------ | | ALV n | | | -------- | usage address | | ------------------ } procedure setdpb( dtype : dsktype ); var i : 0..14; begin if peek( RSFLAG ) <> CHANGE then savedpbadr; for i:= 0 to 14 do poke( DPBADR + i, dpbtable[ dtype, dpbmem(i)]); poke( getdphadr( dskno ) +10 {lo byte of DPB address}, DPBADR ); poke( getdphadr( dskno ) +11 {hi byte of DPB address}, $00 ); poke( RSFLAG, CHANGE ); end; procedure resetdsk; { Set Disk Parameter Block address at the Disk Parameter Header to the original address which are saved into SAVEADRH/L and change RSFLAG to UNCHANGE } begin poke( getdphadr( dskno ) +10 {lo byte of DPB address}, peek(SAVEADRL)); poke( getdphadr( dskno ) +11 {hi byte of DPB address}, peek(SAVEADRH)); poke ( RSFLAG, UNCHANGE ); end; begin { MAIN program } setmydsktype; { set up working disk/machine type } initdpb( mydsktype ); { set up all target disk type table } printtable; { select target disk type } repeat readln( nans ) ; until (nans>=0) and (nans<11{change if add new type}); case nans of { define target disk type } 0 : targetdsk := reset; 1 : targetdsk := pcsingle; 2 : targetdsk := pcdouble; 3 : targetdsk := pc88; 4 : targetdsk := pc98; 5 : targetdsk := if8; 6 : targetdsk := fm8; 7 : targetdsk := fm7; 8 : targetdsk := mz; 9 : targetdsk := pasopia; 10: targetdsk := qc10; { 11: targetdsk := added new disk type } end; if targetdsk = reset then begin if peek( RSFLAG ) = CHANGE then resetdsk end else setdpb( targetdsk ); dskno := getdphadr(SORCEDISK); { reset bdos state to A drive } end. .