From 23b32d7835e44b5c9c84d6ba7961a1ce39809069 Mon Sep 17 00:00:00 2001 From: CrazyEttin <> Date: Fri, 23 Sep 2022 13:25:08 +0300 Subject: [PATCH] Add disc formatting and deal with disc sectors with an unset sync bit --- emulator.pas | 96 ++++++++++++++++++++++++++++++++++++++++++++++------ readme.md | 19 ++++++----- 2 files changed, 96 insertions(+), 19 deletions(-) diff --git a/emulator.pas b/emulator.pas index 652353d..cb07615 100644 --- a/emulator.pas +++ b/emulator.pas @@ -289,15 +289,15 @@ begin if B <= $4c then begin if DiscDrive = 0 then begin {$ifndef fast} - if Disc0Track > B then wait (((Disc0Track - B) * 10) + 45 ) - else if B > Disc0Track then wait (((B - Disc0Track) * 10) + 45 ); + if Disc0Track > B then wait (((Disc0Track - B) * 10) + 45) + else if B > Disc0Track then wait (((B - Disc0Track) * 10) + 45); {$endif} Disc0Track := B; end else begin {$ifndef fast} - if Disc1Track > B then wait (((Disc1Track - B) * 10) + 45 ) - else if B > Disc1Track then wait (((B - Disc1Track) * 10) + 45 ); + if Disc1Track > B then wait (((Disc1Track - B) * 10) + 45) + else if B > Disc1Track then wait (((B - Disc1Track) * 10) + 45); {$endif} Disc1Track := B; end; @@ -316,7 +316,11 @@ begin else if W = $fffb then begin B := B and $f; //Reset the system - if B and $c = 0 then begin + if B and $e = 0 then begin + {$ifndef fast} + if ((Disc0Track * 10) + 45 ) > ((Disc1Track * 10) + 45 ) then wait ((Disc0Track * 10) + 45) + else wait ((Disc1Track * 10) + 45); + {$endif} Disc0Track := 0; Disc1Track := 0; Disc0Sect := 0; @@ -328,6 +332,72 @@ begin for DiscSBP := 0 to $88 do DiscSB [DiscSBP] := 0; DiscSBP := 0; end + //Format the disc + else if B and $e = 2 then begin + if DiscRead = false then if DiscWrite = false then if DiscTrackSet = false then if DiscSectSet = false then begin + {$ifndef fast} + wait (30000); + {$endif} + assign (Discs, ExpandFileName ('~/.thingamajig/discs')); + //Check the system state + if FileExists (ExpandFileName ('~/.thingamajig/discs')) then begin + try + reset (Discs); + read (Discs, Disc0Path); + read (Discs, Disc1Path); + close (Discs); + except + end; + end; + //Set the drive + if B and 1 = 0 then DiscPath := Disc0Path + else DiscPath := Disc1Path; + if DiscPath <> '' then begin + assign (Disc, DiscPath); + //Write + try + reset (Disc); + if FileSize (Disc) = $526a0 then begin + if B and 1 = 0 then begin + for Disc0Track := 0 to $4c do begin + for Disc0Sect := 0 to $1f do begin + for DiscSBP := 0 to $88 do begin + seek (Disc, (Disc0Track * $1120) + (Disc0Sect * $89) + DiscSBP); + if DiscSBP = 0 then write (Disc, $80) + else write (Disc, 0); + end; + end; + end; + end + else begin + for Disc1Track := 0 to $4c do begin + for Disc1Sect := 0 to $1f do begin + for DiscSBP := 0 to $88 do begin + seek (Disc, (Disc1Track * $1120) + (Disc1Sect * $89) + DiscSBP); + if DiscSBP = 0 then write (Disc, $80) + else write (Disc, 0); + end; + end; + end; + end; + close (Disc); + Disc0Track := 0; + Disc1Track := 0; + Disc0Sect := 0; + Disc1Sect := 0; + DiscRead := false; + DiscWrite := false; + DiscTrackSet := false; + DiscSectSet := false; + for DiscSBP := 0 to $88 do DiscSB [DiscSBP] := 0; + DiscSBP := 0; + end + else close (Disc); + except + end; + end; + end; + end //Read a sector from the buffer to the computer else if B and $e = 4 then begin if DiscWrite = false then if DiscTrackSet = false then if DiscSectSet = false then begin @@ -382,11 +452,17 @@ begin try reset (Disc); if FileSize (Disc) = $526a0 then begin - for DiscSBP := 0 to $88 do begin - if B and 1 = 0 then seek (Disc, (Disc0Track * $1120) + (Disc0Sect * $89) + DiscSBP) - else seek (Disc, (Disc1Track * $1120) + (Disc1Sect * $89) + DiscSBP); - read (Disc, DiscSB [DiscSBP]); - end; + if B and 1 = 0 then seek (Disc, (Disc0Track * $1120) + (Disc0Sect * $89)) + else seek (Disc, (Disc1Track * $1120) + (Disc1Sect * $89)); + read (Disc, DiscSB [0]); + if DiscSB [0] and $80 = $80 then begin + for DiscSBP := 1 to $88 do begin + if B and 1 = 0 then seek (Disc, (Disc0Track * $1120) + (Disc0Sect * $89) + DiscSBP) + else seek (Disc, (Disc1Track * $1120) + (Disc1Sect * $89) + DiscSBP); + read (Disc, DiscSB [DiscSBP]); + end; + end + else for DiscSBP := 0 to $88 do DiscSB [DiscSBP] := 0; close (Disc) end else begin diff --git a/readme.md b/readme.md index 0edb0ea..949b72b 100644 --- a/readme.md +++ b/readme.md @@ -125,28 +125,29 @@ punch to FFFD, and the disc system to FFFB and FFFC. The printer prints into /dev/usb/lp0. The tape files read from and punched to are (re)set using the program tapectl with the arguments -r and -p respectively and the disc files in drives 0 and 1 using the program floppyctl with the -arguments -0 and -1 respectively. The disc system uses single-sided -discs with 77 tracks of 32 sectors of 137 bytes, or 337568 bytes in -total: the disc files must be of this size. +arguments -0 and -1 respectively. The disc system uses hard sectored +single-sided discs with 77 tracks of 32 sectors of 137 bytes, or 337568 +bytes in total: the disc files must be of this size. The floppy disc system uses two ports: command at FFFB and data at FFFC. Only the low nibble of the command port is used, consisting of a three-bit command followed by a one-bit drive number used as an argument -by instructions 4-7. The track or sector to be accessed is input to and -the buffer accessed sequentially through the data port after the +by instructions 1 and 4-7. The track or sector to be accessed is input +to and the buffer accessed sequentially through the data port after the relevant command is input to the command port. New commands other than resetting the system are ignored until the current command is fully -executed. +executed. Note that each sector begins with a synchronisation bit that +must always be set. The commands for the disc system are: 0: Reset the system. - 1: " + 1: Format a disc. 2: Read a sector from the buffer to the computer. 3: Write a sector from the computer to the buffer. 4: Set the track to be accessed. 5: Set the sector to be accessed. - 6: Read a sector from the disc to the buffer. - 7: Write a sector from the buffer to the disc. + 6: Read a sector from a disc to the buffer. + 7: Write a sector from the buffer to a disc. The IPL loads the program specified as an argument when running the emulator.