Add a floppy disc system option and tweak the timings to make them more accurate
This commit is contained in:
parent
0b07a2b214
commit
bf36aab7a4
232
emulator.pas
232
emulator.pas
|
@ -31,20 +31,31 @@ const
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
var
|
var
|
||||||
Hlt, Echo: boolean; //Halt and echo flags
|
Hlt, Echo{$ifdef floppy}, DiscRead, DiscWrite, DiscTrackSet, DiscSectSet{$endif}: boolean; //Halt and echo flags and disc system flags
|
||||||
Op, Regs: 0 .. $f; //Opcode
|
Op, Regs: 0 .. $f; //Opcode
|
||||||
X, Y: 0 .. 3; //Register arguments
|
X, Y: 0 .. 3; //Register arguments
|
||||||
Addr, IP, RP: word; //Immediate or address argument and instruction and return pointers
|
Addr, IP, RP: word; //Immediate or address argument and instruction and return pointers
|
||||||
R: array [0 .. 3] of byte; //General-purpose registers
|
R: array [0 .. 3] of byte; //General-purpose registers
|
||||||
Mem: array [0 .. LastRAM] of byte; //Random access memory
|
Mem: array [0 .. LastRAM] of byte; //Random access memory
|
||||||
Prog{$ifdef printer}, Prn{$endif}{$ifdef tape}, TapeIn, TapeOut{$endif}: file of byte; //Program file, line printer, and tape reader and punch tapes
|
{$ifdef floppy}
|
||||||
|
DiscSB: array [0 .. $88] of byte; //Sector buffer for the disc system
|
||||||
|
DiscSBP: 0 .. $88; //Sector buffer pointer
|
||||||
|
{$endif}
|
||||||
|
Prog{$ifdef printer}, Prn{$endif}{$ifdef tape}, TapeIn, TapeOut{$endif}{$ifdef floppy}, Disc{$endif}: file of byte; //Program file, line printer, tape reader and punch tapes, and current disc
|
||||||
{$ifdef tape}
|
{$ifdef tape}
|
||||||
Reader, Punch: Tape; //States of the tape reader and punch
|
Reader, Punch: Tape; //States of the tape reader and punch
|
||||||
Tapes: file of Tape; //File storing the states of the tape reader and punch
|
Tapes: file of Tape; //File storing the states of the tape reader and punch
|
||||||
{$endif}
|
{$endif}
|
||||||
|
{$ifdef floppy}
|
||||||
|
Disc0Path, Disc1Path, DiscPath: shortstring; //Paths of the discs in the drives and the current disc
|
||||||
|
Discs: file of shortstring; //File storing the state of the disc system
|
||||||
|
{$endif}
|
||||||
Ch, Scan: ansichar; //Character for input and output and scancode for non-ASCII keys
|
Ch, Scan: ansichar; //Character for input and output and scancode for non-ASCII keys
|
||||||
Verbose, IC, LFX: integer; //Verbose flag, instruction counter for CPU speed, and line feed position marker
|
Verbose, IC, LFX: integer; //Verbose flag, instruction counter for CPU speed, and line feed position marker
|
||||||
Fetched: byte; //Fetched byte
|
Fetched{$ifdef floppy}, Disc0Track, Disc1Track, Disc0Sect, Disc1Sect{$endif}: byte; //Fetched byte, and disc drive locations
|
||||||
|
{$ifdef floppy}
|
||||||
|
DiscDrive: 0 .. 1; //Current disc drive number
|
||||||
|
{$endif}
|
||||||
|
|
||||||
//Terminal output
|
//Terminal output
|
||||||
procedure Output;
|
procedure Output;
|
||||||
|
@ -68,9 +79,9 @@ end;
|
||||||
|
|
||||||
{$ifndef fast}
|
{$ifndef fast}
|
||||||
//Wait to emulate CPU speed of roughly 500 KIPS
|
//Wait to emulate CPU speed of roughly 500 KIPS
|
||||||
procedure wait;
|
procedure wait (I: integer);
|
||||||
begin
|
begin
|
||||||
if IC div 500 = 0 then sleep (1)
|
if IC div 500 < I then sleep (I)
|
||||||
else begin
|
else begin
|
||||||
sleep (IC div 500);
|
sleep (IC div 500);
|
||||||
if IC mod 500 >= 250 then sleep (1);
|
if IC mod 500 >= 250 then sleep (1);
|
||||||
|
@ -87,7 +98,7 @@ begin
|
||||||
//Terminal input
|
//Terminal input
|
||||||
if W = $ffff then begin
|
if W = $ffff then begin
|
||||||
{$ifndef fast}
|
{$ifndef fast}
|
||||||
wait;
|
wait (1);
|
||||||
{$endif}
|
{$endif}
|
||||||
//Read a keypress
|
//Read a keypress
|
||||||
Ch := ReadKey;
|
Ch := ReadKey;
|
||||||
|
@ -116,8 +127,7 @@ begin
|
||||||
//Tape reader
|
//Tape reader
|
||||||
else if W = $fffd then begin
|
else if W = $fffd then begin
|
||||||
{$ifndef fast}
|
{$ifndef fast}
|
||||||
wait;
|
wait (2);
|
||||||
sleep (1);
|
|
||||||
{$endif}
|
{$endif}
|
||||||
assign (Tapes, ExpandFileName ('~/.thingamajig/tapes'));
|
assign (Tapes, ExpandFileName ('~/.thingamajig/tapes'));
|
||||||
//Check the reader state
|
//Check the reader state
|
||||||
|
@ -153,6 +163,21 @@ begin
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
{$endif}
|
{$endif}
|
||||||
|
{$ifdef floppy}
|
||||||
|
//Floppy disc drive system
|
||||||
|
//Data
|
||||||
|
else if W = $fffc then begin
|
||||||
|
if DiscRead then begin
|
||||||
|
B := DiscSB [DiscSBP];
|
||||||
|
if DiscSBP < $88 then DiscSBP := DiscSBP + 1
|
||||||
|
else begin
|
||||||
|
DiscSBP := 0;
|
||||||
|
DiscRead := false;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else B := 0;
|
||||||
|
end
|
||||||
|
{$endif}
|
||||||
//Unused addresses
|
//Unused addresses
|
||||||
else if W > LastRAM then B := 0
|
else if W > LastRAM then B := 0
|
||||||
//Regular load
|
//Regular load
|
||||||
|
@ -166,7 +191,7 @@ begin
|
||||||
//Terminal output
|
//Terminal output
|
||||||
if W = $ffff then begin
|
if W = $ffff then begin
|
||||||
{$ifndef fast}
|
{$ifndef fast}
|
||||||
wait;
|
wait (1);
|
||||||
{$endif}
|
{$endif}
|
||||||
Ch := ansichar (B);
|
Ch := ansichar (B);
|
||||||
Output;
|
Output;
|
||||||
|
@ -176,6 +201,9 @@ begin
|
||||||
{$ifdef printer}
|
{$ifdef printer}
|
||||||
//Printer
|
//Printer
|
||||||
else if W = $fffe then begin
|
else if W = $fffe then begin
|
||||||
|
{$ifndef fast}
|
||||||
|
wait (1);
|
||||||
|
{$endif}
|
||||||
assign (Prn, '/dev/usb/lp0');
|
assign (Prn, '/dev/usb/lp0');
|
||||||
try
|
try
|
||||||
rewrite (Prn);
|
rewrite (Prn);
|
||||||
|
@ -189,8 +217,7 @@ begin
|
||||||
//Tape punch
|
//Tape punch
|
||||||
else if W = $fffd then begin
|
else if W = $fffd then begin
|
||||||
{$ifndef fast}
|
{$ifndef fast}
|
||||||
wait;
|
wait (20);
|
||||||
sleep (19);
|
|
||||||
{$endif}
|
{$endif}
|
||||||
assign (Tapes, ExpandFileName ('~/.thingamajig/tapes'));
|
assign (Tapes, ExpandFileName ('~/.thingamajig/tapes'));
|
||||||
//Check the punch state
|
//Check the punch state
|
||||||
|
@ -246,6 +273,172 @@ begin
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
{$endif}
|
{$endif}
|
||||||
|
{$ifdef floppy}
|
||||||
|
//Floppy disc drive system
|
||||||
|
//Data
|
||||||
|
else if W = $fffc then begin
|
||||||
|
if DiscWrite then begin
|
||||||
|
DiscSB [DiscSBP] := B;
|
||||||
|
if DiscSBP < $88 then DiscSBP := DiscSBP + 1
|
||||||
|
else begin
|
||||||
|
DiscSBP := 0;
|
||||||
|
DiscWrite := false;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else if DiscTrackSet then 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 );
|
||||||
|
{$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 );
|
||||||
|
{$endif}
|
||||||
|
Disc1Track := B;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
DiscTrackSet := false;
|
||||||
|
end
|
||||||
|
else if DiscSectSet then begin
|
||||||
|
if B <= $1f then begin
|
||||||
|
if DiscDrive = 0 then Disc0Sect := B
|
||||||
|
else Disc1Sect := B;
|
||||||
|
end;
|
||||||
|
DiscSectSet := false;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
//Command
|
||||||
|
else if W = $fffb then begin
|
||||||
|
B := B and $f;
|
||||||
|
//Reset the system
|
||||||
|
if B and $c = 0 then begin
|
||||||
|
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
|
||||||
|
//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
|
||||||
|
DiscRead := true;
|
||||||
|
DiscSBP := 0;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
//Write a sector from the computer to the buffer
|
||||||
|
else if B and $e = 6 then begin
|
||||||
|
if DiscRead = false then if DiscTrackSet = false then if DiscSectSet = false then begin
|
||||||
|
DiscWrite := true;
|
||||||
|
for DiscSBP := 0 to $88 do DiscSB [DiscSBP] := 0;
|
||||||
|
DiscSBP := 0;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
//Set the track to be accessed
|
||||||
|
else if B and $e = 8 then begin
|
||||||
|
if DiscRead = false then if DiscWrite = false then if DiscSectSet = false then begin
|
||||||
|
DiscDrive := B and 1;
|
||||||
|
DiscTrackSet := true;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
//Set the sector to be accessed
|
||||||
|
else if B and $e = $a then begin
|
||||||
|
if DiscRead = false then if DiscWrite = false then if DiscTrackSet = false then begin
|
||||||
|
DiscDrive := B and 1;
|
||||||
|
DiscSectSet := true;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
//Read a sector from the disc to the buffer
|
||||||
|
else if B and $e = $c then begin
|
||||||
|
if DiscRead = false then if DiscWrite = false then if DiscTrackSet = false then if DiscSectSet = false then begin
|
||||||
|
{$ifndef fast}
|
||||||
|
wait (5);
|
||||||
|
{$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;
|
||||||
|
assign (Disc, DiscPath);
|
||||||
|
//Read
|
||||||
|
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;
|
||||||
|
close (Disc)
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
close (Disc);
|
||||||
|
for DiscSBP := 0 to $88 do DiscSB [DiscSBP] := 0;
|
||||||
|
end;
|
||||||
|
except
|
||||||
|
for DiscSBP := 0 to $88 do DiscSB [DiscSBP] := 0;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
//Write a sector from the buffer to the disc
|
||||||
|
else if B and $e = $e then begin
|
||||||
|
if DiscRead = false then if DiscWrite = false then if DiscTrackSet = false then if DiscSectSet = false then begin
|
||||||
|
{$ifndef fast}
|
||||||
|
wait (5);
|
||||||
|
{$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
|
||||||
|
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);
|
||||||
|
write (Disc, DiscSB [DiscSBP]);
|
||||||
|
end;
|
||||||
|
close (Disc);
|
||||||
|
end
|
||||||
|
else close (Disc);
|
||||||
|
except
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
{$endif}
|
||||||
//Regular store
|
//Regular store
|
||||||
else if W <= LastRAM then Mem [W] := B;
|
else if W <= LastRAM then Mem [W] := B;
|
||||||
end;
|
end;
|
||||||
|
@ -281,6 +474,21 @@ begin
|
||||||
Punch.Pos := 0;
|
Punch.Pos := 0;
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
{$ifdef floppy}
|
||||||
|
//Initialise the disc system
|
||||||
|
Disc0Path := '';
|
||||||
|
Disc1Path := '';
|
||||||
|
DiscRead := false;
|
||||||
|
DiscWrite := false;
|
||||||
|
DiscTrackSet := false;
|
||||||
|
DiscSectSet := false;
|
||||||
|
DiscSBP := 0;
|
||||||
|
Disc0Track := 0;
|
||||||
|
Disc1Track := 0;
|
||||||
|
Disc0Sect := 0;
|
||||||
|
Disc1Sect := 0;
|
||||||
|
{$endif}
|
||||||
|
|
||||||
//Check the arguments
|
//Check the arguments
|
||||||
if ParamCount = 0 then begin
|
if ParamCount = 0 then begin
|
||||||
writeln ('Usage: emulator (-v) program (2> verbose_output)');
|
writeln ('Usage: emulator (-v) program (2> verbose_output)');
|
||||||
|
@ -443,7 +651,7 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{$ifndef fast}
|
{$ifndef fast}
|
||||||
wait;
|
wait (1);
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
program FloppyCtl;
|
||||||
|
|
||||||
|
{$MODE OBJFPC}
|
||||||
|
|
||||||
|
uses SysUtils;
|
||||||
|
|
||||||
|
var
|
||||||
|
Disc0, Disc1: shortstring; //States of the floppy discs
|
||||||
|
State: file of shortstring; //File storing the states of the floppy discs
|
||||||
|
Set0, Set1: integer; //Whether to (re)set the discs
|
||||||
|
|
||||||
|
begin
|
||||||
|
|
||||||
|
//Check the arguments
|
||||||
|
if ParamCount > 4 then begin
|
||||||
|
writeln ('Usage: floppyctl (-0 disc) (-1 disc)');
|
||||||
|
halt (1);
|
||||||
|
end
|
||||||
|
else if ParamCount mod 2 <> 0 then begin
|
||||||
|
writeln ('Usage: floppyctl (-0 disc) (-1 disc)');
|
||||||
|
halt (1);
|
||||||
|
end;
|
||||||
|
if ParamStr (1) = '-0' then begin
|
||||||
|
Set0 := 2;
|
||||||
|
Set1 := 0;
|
||||||
|
if ParamStr (3) = '-1' then begin
|
||||||
|
Set1 := 4;
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else if ParamStr (1) = '-1' then begin
|
||||||
|
Set0 := 0;
|
||||||
|
Set1 := 2;
|
||||||
|
if ParamStr (3) = '-0' then Set0 := 4;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
writeln ('Usage: floppyctl (-0 disc) (-1 disc)');
|
||||||
|
halt (1);
|
||||||
|
end;
|
||||||
|
|
||||||
|
//Assign the state file
|
||||||
|
assign (State, ExpandFileName ('~/.thingamajig/discs'));
|
||||||
|
|
||||||
|
//Read existing state if any
|
||||||
|
if FileExists (ExpandFileName ('~/.thingamajig/discs')) then begin
|
||||||
|
try
|
||||||
|
reset (State);
|
||||||
|
read (State, Disc0);
|
||||||
|
read (State, Disc1);
|
||||||
|
close (State);
|
||||||
|
except
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
//Or else assign a default state
|
||||||
|
else begin
|
||||||
|
Disc0 := '';
|
||||||
|
Disc1 := '';
|
||||||
|
end;
|
||||||
|
|
||||||
|
//Get the files
|
||||||
|
if Set0 <> 0 then Disc0 := ExpandFileName (ParamStr (Set0));
|
||||||
|
if Set1 <> 0 then Disc1 := ExpandFileName (ParamStr (Set1));
|
||||||
|
|
||||||
|
//Write the state
|
||||||
|
try
|
||||||
|
rewrite (State);
|
||||||
|
write (State, Disc0);
|
||||||
|
write (State, Disc1);
|
||||||
|
close (State);
|
||||||
|
except
|
||||||
|
writeln ('Error: could not set the disc(s)');
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
50
readme.md
50
readme.md
|
@ -8,11 +8,10 @@ https://ahti.space/git/crazyettin/Thingamajig.
|
||||||
Included Software
|
Included Software
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
The repository includes an emulator implementation of Thingamajig with a
|
The repository includes an emulator implementation of Thingamajig with
|
||||||
control program for the emulated paper tape reader and punch, and an
|
storage device control programs, and an assembler and a disassembler,
|
||||||
assembler and a disassembler, all written in FreePascal. It also
|
all written in FreePascal. It also includes couple of simple example
|
||||||
includes couple of simple example programs for Thingamajig written in
|
programs for Thingamajig written in assembly.
|
||||||
assembly.
|
|
||||||
|
|
||||||
Registers and Memory
|
Registers and Memory
|
||||||
--------------------
|
--------------------
|
||||||
|
@ -92,12 +91,13 @@ implementation has a front panel the IPL is optional. The instruction
|
||||||
and return pointers are initialised as 0 and the first address after RAM
|
and return pointers are initialised as 0 and the first address after RAM
|
||||||
respectively, while other registers and RAM are uninitialised.
|
respectively, while other registers and RAM are uninitialised.
|
||||||
|
|
||||||
Emulator and Tapectl
|
Emulator and Storage Device Control Programs
|
||||||
--------------------
|
--------------------------------------------
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
* emulator (-v) program (2> verbose_output)
|
* emulator (-v) program (2> verbose_output)
|
||||||
* tapectl (-r tape) (-p tape)
|
* tapectl (-r tape) (-p tape)
|
||||||
|
* floppyctl (-0 disc) (-1 disc)
|
||||||
|
|
||||||
By default the emulator runs at roughly 500 KIPS and has 2 KiB of RAM.
|
By default the emulator runs at roughly 500 KIPS and has 2 KiB of RAM.
|
||||||
The arguments -dRAM4, -dRAM8, -dRAM16, -dRAM32, and -dRAM64 can be used
|
The arguments -dRAM4, -dRAM8, -dRAM16, -dRAM32, and -dRAM64 can be used
|
||||||
|
@ -117,12 +117,36 @@ standard uses. The backspace and delete keys input their respective
|
||||||
characters and non-character keys null.
|
characters and non-character keys null.
|
||||||
|
|
||||||
In Linux the emulator can be compiled with support for a character
|
In Linux the emulator can be compiled with support for a character
|
||||||
printer and an emulated high speed (roughly 500 CPS in and 50 CPS out)
|
printer, an emulated high speed (roughly 500 CPS in and 50 CPS out)
|
||||||
8-bit paper tape reader and punch with the arguments -dprinter and
|
8-bit paper tape reader and punch, and an emulated two-drive 8" floppy
|
||||||
-dtape respectively. The printer is mapped to address FFFE and the tape
|
disc system with the arguments -dprinter, -dtape, and -dfloppy
|
||||||
reader and punch to FFFD. The printer prints into /dev/usb/lp0 and the
|
respectively. The printer is mapped to address FFFE, the tape reader and
|
||||||
tape files read from and punched to are (re)set using the program
|
punch to FFFD, and the disc system to FFFB and FFFC. The printer prints
|
||||||
tapectl with the arguments -r and -p respectively.
|
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.
|
||||||
|
|
||||||
|
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
|
||||||
|
relevant command is input to the command port. New commands other than
|
||||||
|
resetting the system are ignored until the current command is fully
|
||||||
|
executed.
|
||||||
|
|
||||||
|
The commands for the disc system are:
|
||||||
|
0: Reset the system.
|
||||||
|
1: "
|
||||||
|
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.
|
||||||
|
|
||||||
The IPL loads the program specified as an argument when running the
|
The IPL loads the program specified as an argument when running the
|
||||||
emulator.
|
emulator.
|
||||||
|
|
Loading…
Reference in New Issue