Program MADM_Prototype_Simulator(input,output);
{ Desc : Non-Graphics Based MADM Mk-I Prototype Simulator Program }
{ Written for Turbo Pascal V6.0 }
Uses
CRT;
Const
Trace = False; {True;} {False}
Type
LineType = LongInt;
StoreType = array[0..31] of LineType;
Var
A : LineType; { Accumulator Tube }
CI : LineType; { Control Tube - Current Instruction Line }
PI : LineType; { Control Tube - Program Instruction Line }
S : StoreType; { Store Tube - 32 x 32 bits }
Run : boolean;
Procedure ClearStore(var S : StoreType);
{ Desc : Zeros out Store Tube }
var
i : integer;
begin {ClearStore}
for i := 0 to 31 do
S[i] := 0;
end; {ClearStore}
Procedure Execute(var A, CI, PI : LineType;
var S : StoreType;
var Run : Boolean);
{ Desc : Executes One Madm Mk I Instruction
CI := CI + 1;
PI := S[CI]
Instruction PI is executed }
var
Fcn,
Line : LongInt;
begin { Execute }
CI := (CI + 1) Mod 32; { Increment CI }
PI := S[CI]; { Fetch current instruction}
Fcn := (PI AND $0000E000) SHR 13; { Extract Opcode }
Line := (PI AND $0000001F); { Extract Operand }
Case Fcn of { Execute }
0 : CI := S[Line]; { Jump }
1 : CI := CI + S[Line]; { Jump relative }
2 : A := -S[Line]; { Load Negative }
3 : S[Line] := A; { Store }
4 : A := A - S[line]; { Subtract }
5 : A := A - S[Line]; { " }
6 : If A < 0 Then { Skip if A < 0 }
CI := (CI + 1) AND $0000001F;
7 : Run := False; { Halt }
end ; (* case *)
end; { Execute }
Function Assemble(Op : String; Line : Integer):LongInt;
{ Desc : Assembler Utility to Generate Madm Mk I Code. Converts
the string 'JMP', 'JMR', 'LDN', 'STO', 'SUB', 'SKN',
and 'HLT' to corresponding Madm Mk I codes. Line is
operand address from 0 to 31 }
Begin {Assemble}
if Op = 'JMP' then
Assemble := $0000 + Line Mod 32
else if OP = 'JMR' then
Assemble := $2000 + Line Mod 32
else if OP = 'LDN' then
Assemble := $4000 + Line Mod 32
else if OP = 'STO' then
Assemble := $6000 + Line Mod 32
else if OP = 'SUB' then
Assemble := $8000 + Line Mod 32
else if OP = 'SKN' then
Assemble := $C000 + Line Mod 32
else if OP = 'HLT' then
Assemble := $E000 + Line Mod 32
end; {Assemble}
Procedure TextDisplayStore(A, CI, PI : LineType;
var S : StoreType);
{ Desc : Displays A, C, and Store Tubes }
var
i : integer;
procedure WriteLineType(var L : LineType);
var
j : LongInt;
begin
for j := 0 to 31 do
if L AND (1 SHL j) <> 0 then
write(output,'1')
else
write(output,'0');
end;
Begin {TextDisplayStore}
CRT.ClrScr;
CRT.GotoXY(1,3);
write(output,'A ');
WriteLineType(A);
CRT.GotoXY(42,3);
write(output,'CI ');
WriteLineType(CI);
CRT.GotoXY(42,4);
write(output,'PI ');
WriteLineType(PI);
for i := 0 to 15 do
begin
CRT.GotoXY(1, 6+i);
write(output,'S' + chr(i DIV 10 + 48) + chr(i MOD 10 + 48)+' ');
WriteLineType(S[i]);
end;
for i := 16 to 31 do
begin
CRT.GotoXY(42, i - 10);
write(output,'S' + chr(i DIV 10 + 48) + chr(i MOD 10 + 48)+' ');
WriteLineType(S[i]);
end;
CRT.GotoXY(1,25);
End;{TextDisplayStore}
Procedure Multiply(var S : StoreType);
{ Desc : Assembles Multiplication Routine for Madm Mk I
S[31] := S[30] * S[29] }
begin
S[1] := Assemble('LDN',30);
S[2] := Assemble('SKN',0);
S[3] := Assemble('JMP',27);
S[4] := Assemble('SUB',28);
S[5] := Assemble('STO',30);
S[6] := Assemble('LDN',30);
S[7] := Assemble('STO',30);
S[8] := Assemble('LDN',31);
S[9] := Assemble('SUB',29);
S[10] := Assemble('STO',31);
S[11] := Assemble('LDN',31);
S[12] := Assemble('STO',31);
S[13] := Assemble('JMP',0);
S[14] := Assemble('HLT',0);
S[27] := 13;
S[28] := -1;
S[29] := 16;
S[30] := 16;
S[31] := 0;
end;
Procedure FreezeDisplay;
{ Desc : Freezes Display until Key Pressed }
var
ch : char;
begin {FreezeDisplay}
CRT.GotoXY(28,25);
write(output,'Hit Any Key to Continue');
While Not CRT.KeyPressed do;
ch := CRT.ReadKey;
end; {FreezeDisplay}
Begin { Main Code Sequence }
{ Zero Out A, C, and Store Tubes }
A := 0;
CI := 0;
PI := 0;
ClearStore(S);
{ Enter Program Instructions Here }
Multiply(S);
{ Execute Program }
Run := True;
While Run Do
begin
if Trace then
begin
TextDisplayStore(A, CI, PI, S);
FreezeDisplay;
end;
Execute(A, CI, PI, S, Run);
end;
{ Signal End and Display Store }
CRT.Sound(250);
CRT.Delay(400);
CRT.NoSound;
TextDisplayStore(A, CI, PI, S);
{ Pause Display }
FreezeDisplay;
End.