+Program ASC (Input,Output); {A Simple Computer}
+{----------------(ASC Simulation)---------------}
+ ACC : Longint; {ACCumulator}
+ MBR : Longint; {Memory Buffer Register}
+ MAR : Word; {Memory Address Register}
+ IR : Word; {Instruction Register}
+ PC : Word; {Program Counter}
+ IR1 : Word; {Index Register 1}
+ IR2 : Word; {Index Register 2}
+ IR3 : Word; {Index Register 3}
+ RAM : Array[1..1000] of Longint; {1Kb RAM}
+ memoryAddr : Integer; {IR bits 7-15} {0-511}
+ idx : Integer; {IR bits 0-1} {0-3}
+ indirect : Integer; {IT bit 2} {0-1}
+ opcode : Integer; {IR bits 3-6} {0-15}
+{-----------------------------------------------}
+{-----------------------------------------------}
+var key : Char; {Stores users menu choice}
+{-----------------------------------------------}
+{-----------------------------------------------}
+procedure PrintHex( X : Word);
+ const s : array[0..15] of char = '0123456789ABCDEF';
+ Write( s[$000F and (X shr(i*4))]);
+ {taken from PASCAL Programers Phasebook}
+ {by Ian A. Clari, Sigma Press, 1992}
+{-----------------------------------------------}
+ WriteLn('+============================================================================+');
+ Write('+============================================================================+');
+ GotoXY(9,3); Write('ACCumalator:'); GotoXY(44,3); Write('Instruction Register:');
+ GotoXY(9,4); Write('Program Counter:'); GotoXY(44,4); Write('Index Register 1:');
+ GotoXY(9,5); Write('Memory Buffer Register:'); GotoXY(44,5); Write('Index Register 2:');
+ GotoXY(9,6); Write('Memory Address Register:'); GotoXY(44,6); Write('Index Register 3:');
+ GotoXY(34,3); PrintHex(ACC); GotoXY(66,3); PrintHex(IR);
+ GotoXY(34,4); PrintHex(PC); GotoXY(66,4); PrintHex(IR1);
+ GotoXY(34,5); PrintHex(MBR); GotoXY(66,5); PrintHex(IR2);
+ GotoXY(34,6); PrintHex(MAR); GotoXY(66,6); PrintHex(IR3);
+ WriteLn('+============================================================================+');
+ Write('+============================================================================+');
+ Write('A Simple Computer simulator - T.McDonnell, SYS-1C22,UEA,1999');
+ GotoXY(17,3); Write('1.....Load progam to ASC RAM');
+ GotoXY(17,4); Write('2.....Start ASC simulation using program in ASC RAM');
+ GotoXY(17,5); Write('3.....Step through a running ASC Simulation');
+ GotoXY(17,6); Write('4.....Show map of ASC RAM');
+ GotoXY(17,7); Write('5.....Edit contents of a ASC CPU register');
+ GotoXY(17,8); Write('6.....Edit contents of a ASC RAM address');
+ GotoXY(17,9); Write('7.....Set program break points');
+ GotoXY(17,11); Write('C.....Clear registers');
+ GotoXY(17,13); Write('X.....Exit ASC simulator');
+ WriteLn('+======================================+');
+ Write('+======================================+');
+ GotoXY(10,2); Write('A Simple Computer');
+ GotoXY(9,6); Write('T. McDonnell, 1999');
+ TextColor(lightred+blink);
+ GotoXY(10,4); Write('S I M U L A T O R');
+ repeat until KeyPressed;
+ Dialog; GotoXY(6,4); Write('Address: ');
+ GotoXY(6,2); Write('Enter in either Hex or Dec');
+ GotoXY(6,6); Write('Use $ for Hex values');
+ GotoXY(15,4); TextBackground(lightgray); Write(' ');
+ GotoXY(15,4); TextColor(white); ReadLn(address);
+ Dialog; GotoXY(6,4); Write('Value: ');
+ GotoXY(6,2); Write('Enter in either Hex or Dec');
+ GotoXY(6,6); Write('Use $ for Hex values');
+ GotoXY(15,4); TextBackground(lightgray); Write(' ');
+ GotoXY(15,4); TextColor(white); ReadLn(value);
+ WriteLn('+---------------------------------------------------------+');
+ Write('+---------------------------------------------------------+');
+ GotoXY(3,3); Write('Enter Data: ');
+ TextBackground(lightgray); TextColor(white);
+ Write(' '); GotoXY(15,3);
+procedure UserOut(data:Word);
+ WriteLn('+---------------------------------------------------------+');
+ Write('+---------------------------------------------------------+');
+ memoryAddr := 0; idx := 0; indirect := 0; opcode := 0;
+ {--------------------------------------}
+ {calculate which index register, if any, is used}
+ if memoryAddr >= $0000 then
+ memoryAddr := memoryAddr - $0000;
+ else if memoryAddr >=$8000 then
+ memoryAddr := memoryAddr - $8000;
+ else if memoryAddr >=$4000 then
+ memoryAddr := memoryAddr - $8000;
+ {--------------------------------------}
+ {check for indirect addressing mode}
+ if memoryAddr >= $2000 then
+ memoryAddr := memoryAddr - $2000;
+ {--------------------------------------}
+ if memoryAddr >= $1E00 then
+ opcode := $F; {TDX I,x}
+ memoryAddr := memoryAddr - $1E00;
+ else if memoryAddr >= $1C00 then
+ opcode := $E; {TIX I,x}
+ memoryAddr := memoryAddr - $1C00;
+ else if memoryAddr >= $1A00 then
+ opcode := $D; {STX I,x}
+ memoryAddr := memoryAddr - $1A00;
+ else if memoryAddr >= $1800 then
+ opcode := $C; {LDX, I,x}
+ memoryAddr := memoryAddr - $1800;
+ else if memoryAddr >= $1600 then
+ memoryAddr := memoryAddr - $1600;
+ else if memoryAddr >= $1400 then
+ memoryAddr := memoryAddr - $1400;
+ else if memoryAddr >= $1200 then
+ memoryAddr := memoryAddr - $1200;
+ else if memoryAddr >= $1000 then
+ memoryAddr := memoryAddr - $1000;
+ else if memoryAddr >= $0E00 then
+ memoryAddr := memoryAddr - $0E00;
+ else if memoryAddr >= $0C00 then
+ memoryAddr := memoryAddr - $0C00;
+ else if memoryAddr >= $0A00 then
+ memoryAddr := memoryAddr - $0A00;
+ else if memoryAddr >= $0800 then
+ memoryAddr := memoryAddr - $0800;
+ else if memoryAddr >= $0600 then
+ memoryAddr := memoryAddr - $0600;
+ else if memoryAddr >= $0400 then
+ memoryAddr := memoryAddr - $0400;
+ else if memoryAddr >= $0200 then
+ memoryAddr := memoryAddr - $0200;
+ else if memoryAddr >= $0000 then
+ memoryAddr := memoryAddr - $0000;
+ {------------------------------}
+ if idx = 1 then MBR := RAM[MAR + IR1];
+ if idx = 2 then MBR := RAM[MAR + IR2];
+ if idx = 3 then MBR := RAM[MAR + IR3];
+ if idx = 1 then MBR := RAM[MAR + IR1];
+ if idx = 2 then MBR := RAM[MAR + IR2];
+ if idx = 3 then MBR := RAM[MAR + IR3];
+ if opcode = $D then MAR := memoryAddr;
+ if opcode = $E then MAR := memoryAddr;
+ if opcode = $F then MAR := memoryAddr;
+ if opcode = $0 then ACC := MBR;
+ if opcode = $2 then ACC := ACC + MBR;
+ if opcode = $3 then ACC := 0 - ACC;
+ if opcode = $5 then PC := MAR;
+ if opcode = $6 then if ACC > 0 then PC := MAR;
+ if opcode = $7 then if ACC < 0 then PC := MAR;
+ if opcode = $8 then ACC := UserIn;
+ if opcode = $9 then UserOut(ACC);
+ if opcode = $A then ACC := ACC * 2;
+ if opcode = $B then ACC := ACC DIV 2;
+ if idx = 1 then IR1 := MBR;
+ if idx = 2 then IR2 := MBR;
+ if idx = 3 then IR3 := MBR;
+ if idx = 1 then MBR := IR1;
+ if idx = 2 then MBR := IR2;
+ if idx = 3 then MBR := IR3;
+ if IR1 = 0 then PC := MAR;
+ if IR2 = 0 then PC := MAR;
+ if IR3 = 0 then PC := MAR;
+ if not(IR1 = 0) then PC := MAR;
+ if not(IR2 = 0) then PC := MAR;
+ if not(IR3 = 0) then PC := MAR;
+ {---------------------------------------}
+ GotoXY(3,2); Write('Load ASC machine code from...');
+ GotoXY(3,5); Write('Do not enter DOS extension (.asc)');
+ GotoXY(5,4); Write('File: ');
+ Textbackground(lightgray); TextColor(white); Write(' ');
+ GotoXY(11,4); ReadLn(userfile);
+ until not(userfile='');
+ userfile := userfile + '.asc';
+ TextColor(lightred+blink); GotoXY(11,4); Write('Processing ',userfile);
+ FindFirst(userfile, AnyFile, SRec);
+ Dialog; GotoXY(6,4); TextColor(lightred);
+ Write('ERROR - File does not exist');
+ repeat until KeyPressed;
+ {---------------------}
+ TextColor(lightred+blink);
+ GotoXY(11,4); Write('Processing ',userfile);
+ {---------------------}
+ Assign(f,userfile); Reset(f);
+ Dialog; GotoXY(6,4); TextColor(lightred);
+ Write('FATAL ERROR - ASC out of RAM');
+ repeat until KeyPressed;
+ address := address + 1;
+ Dialog; TextColor(lightred+blink);
+ GotoXY(11,4); Write('Processing...');
+ GotoXY(6,3); Write('[S] - Step');
+ GotoXY(6,5); Write('[X] - Exit');
+ repeat until KeyPressed;
+ if step = 'X' then charcheck := 1;
+ if step = 's' then charcheck := 1;
+ if step = 'S' then charcheck := 1;
+ if opcode = $4 then step := 'X';
+ Dialog; GotoXY(6,3); Write('Start Addr: ');
+ GotoXY(6,5); Write('End Addr: ');
+ GotoXY(6,2); Write('Enter in either Hex or Dec');
+ GotoXY(6,6); Write('Use $ for Hex values');
+ TextBackground(lightgray);
+ GotoXY(18,3); Write(' ');
+ GotoXY(18,5); Write(' ');
+ CursorOn; TextColor(white);
+ GotoXY(18,3); ReadLn(startAddr);
+ GotoXY(18,5); ReadLn(endAddr);
+ {---------------------------}
+ WriteLn('+----------------------------------------------------------------------------+');
+ Write('+----------------------------------------------------------------------------+');
+ GotoXY(4,2); Write('Address Contents');
+ GotoXY(19,3); Write('Hex Decimal');
+ {-------------------------------}
+ for address := startAddr to endAddr do
+ TextColor(yellow); PrintHex(address);
+ TextColor(white); Write(' '); PrintHex(RAM[address]);
+ WriteLn(' ',RAM[address]);
+ repeat until KeyPressed;
+ GotoXY(3,2); Write('Enter Register code');
+ GotoXY(3,6); Write('Capital letters in register window');
+ GotoXY(6,4); Write('Register: ');
+ TextBackground(lightgray); TextColor(white);
+ GotoXY(16,4); Write(' ');
+ GotoXY(16,4); ReadLn(reg);
+ if reg='ACC' then ACC := Val;
+ if reg='acc' then ACC := Val;
+ if reg='PC' then PC := Val;
+ if reg='pc' then PC := Val;
+ if reg='MBR' then MBR := Val;
+ if reg='mbr' then MBR := Val;
+ if reg='MAR' then MAR := Val;
+ if reg='mar' then MAR := Val;
+ if reg='IR' then IR := Val;
+ if reg='ir' then IR := Val;
+ if reg='IR1' then IR1 := Val;
+ if reg='ir1' then IR1 := Val;
+ if reg='IR2' then IR2 := Val;
+ if reg='ir2' then IR2 := Val;
+ if reg='IR3' then IR3 := Val;
+ if reg='ir3' then IR3 := Val;
+{-------------------------------------------------}