home *** CD-ROM | disk | FTP | other *** search
- (* ------------------------------------------------------ *)
- (* DCAEND.PAS *)
- (* Verbesserungen zum Didaktischen Computer *)
- (* aus PASCAL 12/88. *)
- (* (c) 1988 by Bernd Möller und PASCAL International *)
- (* ------------------------------------------------------ *)
-
- (* In DC.PAS muß die Typendeklaration wie folgt geändert *)
- (* werden: *)
-
- TYPE
- dc_word = STRING[word_size]; op_str = STRING[op_end];
- mnem_str = STRING[mnem_size]; one_line = STRING[80];
- lines = STRING[max_length]; string2 = STRING[2];
- errors = (illcmd, illadd, illlab, illcod, illarg,
- illcon, loops, ovf, illfil, illhlp, break);
- mem_area = ARRAY [0..mem_size] OF record
- speicherwort: dc_word;
- NoCommand: boolean;
- end;
-
- (* Folgende Prozeduren sind zu ändern: *)
-
- PROCEDURE Init;
- VAR i: INTEGER; temp: dc_word;
- BEGIN
- esc := Chr(27); RevOff; CrsOff; ClrScr; Init_Sys;
- pl := '+'; mi := '-'; sp1 := ' '; sp2 := ' ';
- ipc := '+1'; dpc := '-1'; rd := 'rd'; wr := 'wr';
- mode := nowait;
- mnems[0] := 'LDA'; mnems[1] := 'STA';
- mnems[2] := 'ADD'; mnems[3] := 'SUB';
- mnems[4] := 'JMP'; mnems[5] := 'JMS';
- mnems[6] := 'JSR'; mnems[7] := 'RTN';
- mnems[8] := 'JPL';
- FOR i := 9 TO 15 DO mnems[i] := '???';
- temp := zero; sp := zero;
- FOR i := 0 TO instructions DO BEGIN
- Int_to_Bin(i,op_start,op_end,temp);
- op_codes[i] := Copy(temp,op_start,op_end);
- END;
- Print_Display; Print_Computer; Clear;
- GotoXY(2,25); revon; Write(' <H> fuer Information');
- RevOff; row := winymin; GotoXY(1,row);
- END;
-
- PROCEDURE Load_Constant (address: INTEGER);
- (* Konstante in Speicher laden *)
- VAR value, err: INTEGER;
- BEGIN
- Val(item[3],value,err);
- IF (err = null) AND (value > (-1 * Succ(sign_val)))
- AND (value < sign_val) THEN BEGIN
- Load_Int(value,memory[address].speicherwort);
- memory[address].NoCommand := true;
- print_cell(address, memory[address].NoCommand);
- END
- ELSE Error(illcon); (* Illegal constant *)
- END;
-
- PROCEDURE Load_Instruction (address: INTEGER;
- op_code: op_str);
- VAR arg, i: INTEGER; Mem: dc_word;
- BEGIN
- IF item[2] = 'RTN' THEN item[3] := '0';
- Val(item[3],arg,i); Mem := zero;
- IF (i = null) AND Legal(arg) THEN BEGIN
- Int_to_Bin(arg,addr_start,addr_end,Mem);
- FOR i := op_start TO op_end DO Mem[i] := op_code[i];
- memory[address].speicherwort := Mem;
- memory[address].NoCommand := false;
- print_cell(address, memory[address].NoCommand);
- END
- ELSE Error(illarg); (* Illegal argument *)
- END;
-
- PROCEDURE Read_Line; (* Kommando-Zeile einlesen *)
- VAR st: lines; i: INTEGER;
- BEGIN
- Invert_Cell(counter); CrsOn; GotoXY(1,row); Bell;
- Write('> '); ReadLn(Line); st := Line;
- FOR i := 1 TO max_length - Length(Line) DO
- st := Concat(st,' ');
- CrsOff; w_write(st); Erase_Error;
- print_cell(counter, memory[counter].NoCommand);
- END;
-
- (* 2 Änderungen in DCKONV.PAS lauten: *)
-
- FUNCTION is_Minus (VAR reg: dc_word): BOOLEAN;
- BEGIN is_Minus := reg[sign_bit] = '1'; END;
-
- FUNCTION Int_Val (VAR reg: dc_word): INTEGER;
- VAR value: INTEGER;
- BEGIN
- Bin_to_Int(reg,Succ(sign_bit),word_size,value);
- IF is_Minus(reg) THEN
- Int_Val := - value ELSE Int_Val := value;
- END;
-
- (* Die Änderungen für DCout.PAS sind: *)
-
- PROCEDURE Dasm (VAR reg: dc_word; VAR arg: INTEGER);
- BEGIN
- Bin_to_Int (reg, op_start + 1, addr_end, arg);
- IF reg [sign_bit] = '1' THEN arg := arg - sign_val;
- END;
-
- PROCEDURE Print_Register (x, y: INTEGER; VAR reg: dc_word);
- BEGIN GotoXY(x,y); Write(reg); END;
-
- PROCEDURE Out_Cell (adr: INTEGER; NoCommand: BOOLEAN);
- VAR arg, y: INTEGER; mnem: mnem_str;
- BEGIN
- IF NoCommand THEN BEGIN
- Dasm (memory[adr].speicherwort, arg);
- mnem := 'DEF'; END
- ELSE Disassemble(memory[adr].speicherwort,mnem,arg);
- y := (adr MOD 25) + 1;
- GotoXY(59,y); Write(adr:2,mnem:4,arg:3);
- GotoXY(69,y); Write(memory[adr].speicherwort,' ');
- END;
-
- PROCEDURE Print_MemPage (adr: INTEGER);
- VAR i, from_cell, to_cell, arg, y: INTEGER;
- BEGIN
- i := adr DIV screen_lines; RevOn;
- IF i <> mempage THEN BEGIN
- mempage := i; y := 0;
- from_cell := i*screen_lines;
- to_cell := from_cell+Pred(screen_lines);
- IF to_cell > mem_size THEN to_cell := mem_size;
- FOR i := from_cell TO to_cell DO BEGIN
- Out_Cell(i, memory[i].NoCommand);
- y := Succ(y);
- END;
- WHILE y < screen_lines DO BEGIN
- y := Succ(y);
- GotoXY(59,y); Write(' ':9); GotoXY(69,y);
- Write(' ':Succ(word_size));
- END;
- END;
- RevOff;
- END;
-
- PROCEDURE Print_Cell (i: INTEGER; NoCommand: BOOLEAN);
- (* Inhalt einer Speicherzelle anzeigen *)
- BEGIN
- IF (i DIV screen_lines)=mempage THEN BEGIN
- RevOn; Out_Cell(i, NoCommand); RevOff;
- END;
- END;
-
- PROCEDURE Invert_Cell (i: INTEGER);
- BEGIN
- Print_MemPage(i); RevOff;
- Out_Cell(i, memory[i].NoCommand);
- END;
-
- PROCEDURE Print_Cycle (Str: lines);
- (* Maschinen-Zyklus anzeigen *)
- BEGIN
- IF out_cycle THEN BEGIN
- RevOn; GotoXY(6,25); Write(Str); RevOff;
- END;
- END;
-
- PROCEDURE Print_Display; (* das Drumherum zeichnen *)
- VAR i: INTEGER;
- BEGIN
- FOR i := 1 TO 25 DO BEGIN
- GotoXY(58,i); Write(vd);
- GotoXY(68,i); Write(vd);
- END;
- GotoXY(1,winymin-1);
- RevOn; Write(' DC v1.3 (c) 1987 PASCAL INT. ');
- Write(' Register: Mnem: '); RevOff;
- FOR i := winymin-1 TO winymax+1 DO BEGIN
- GotoXY(33,i); Write(vd);
- GotoXY(47,i); Write(vd);
- END;
- GotoXY(34,24); RevOn; Write(' Bpt: none ');
- GotoXY(34,25); Write(' Int: none ');
- GotoXY(1,25); Write(' ':32);
- GotoXY(48,18); Write(' LDA JPL ');
- GotoXY(48,19); Write(' STA ??? ');
- GotoXY(48,20); Write(' ADD ??? ');
- GotoXY(48,21); Write(' SUB ??? ');
- GotoXY(48,22); Write(' JMP ??? ');
- GotoXY(48,23); Write(' JMS ??? ');
- GotoXY(48,24); Write(' JSR ??? ');
- GotoXY(48,25); Write(' RTN DEF ');
- RevOff; GotoXY(34,18); Write('AC');
- GotoXY(34,19); Write('DR');
- GotoXY(34,20); Write('AR');
- GotoXY(34,21); Write('IR');
- GotoXY(34,22); Write('PC');
- GotoXY(34,23); Write('SP');
- END;
-
- (* Die Änderungen in DCEXE.PAS sind: *)
-
- PROCEDURE Memory_Read;
- BEGIN
- Memory_Cycle;
- dr := memory[address].speicherwort;
- Read_Cycle;
- END;
-
- PROCEDURE Memory_Write;
- BEGIN
- Memory_Cycle;
- memory[address].speicherwort := dr;
- Write_Cycle;
- END;
-
- PROCEDURE Memory_Push;
- BEGIN
- ar := sp; Transfer_SP_AR;
- memory[s_ptr].speicherwort := dr; Write_Cycle;
- decrement(s_ptr);
- Int_to_Bin(s_ptr,addr_start,addr_end,sp); Dec_SP;
- END;
-
- PROCEDURE Memory_Pop;
- BEGIN
- increment(s_ptr);
- Int_to_Bin(s_ptr,addr_start,addr_end,sp); Inc_SP;
- ar := sp; Transfer_SP_AR;
- dr := memory[s_ptr].speicherwort; Read_Cycle;
- END;
-
- PROCEDURE Jump_if_Plus;
- BEGIN
- IF is_Plus(ac) THEN Jump;
- END;
-
- PROCEDURE Fetch_Instruction;
- BEGIN
- ar := pc; Transfer_PC_AR;
- Bin_to_Int(ar,addr_start,addr_end,address);
- dr := memory[address].speicherwort;
- Read_Cycle; increment(counter);
- Int_to_Bin(counter,addr_start,addr_end,pc);
- Inc_PC;
- ir := dr; Transfer_DR_IR;
- Bin_to_Int(ir,op_start,op_end,op_code);
- Bin_to_Int(ir,addr_start,addr_end,address);
- END;
-
- PROCEDURE Execute_Instruction;
- VAR old_pc: INTEGER; ch: CHAR;
- BEGIN
- end_of_program := FALSE; old_pc := counter;
- Invert_Cell(old_pc);
- Fetch_Instruction;
- CASE op_code OF
- 0: Load; 1: Store; 2: Add;
- 3: Subtract; 4: Jump; 5: Jump_if_Minus;
- 6: Jump_to_Subroutine; 7: Return;
- 8: Jump_if_Plus;
- END;
- IF out_cycle THEN Print_Registers;
- check_Interrupt; check_Breakpoint;
- IF KeyEntered THEN
- IF ReadKeyboard = esc THEN BEGIN
- Stop; error(break);
- END;
- print_cell(old_pc, memory[old_pc].NoCommand);
- END;
-
- PROCEDURE Clear; (* Computer zuruecksetzen: RESET *)
- VAR i: INTEGER;
- BEGIN
- FOR i := 0 TO mem_size DO BEGIN
- memory[i].speicherwort := zero;
- memory[i].NoCommand := false;
- END;
- ac := zero; ar := zero; pc := zero; dr := zero;
- ir := zero;
- counter := 0; address := 0; s_ptr := mem_size;
- Int_to_Bin(s_ptr,addr_start,addr_end,sp);
- mempage := -1; Print_MemPage(0); out_cycle := TRUE;
- display_status; items := 1; breakpoint; interrupt;
- END;
-
- (* die Äderungen für DCTRAN.PAS: *)
-
- PROCEDURE Write_Cycle; (* der Schreib-Zyklus *)
- BEGIN
- Print_Cycle('DR -> MEMORY'); Gate(wr,43,9,TRUE);
- Print_Cell(address, memory[address].NoCommand);
- Wait; Gate(sp2,43,9,FALSE);
- END;
- (* ------------------------------------------------------ *)
- (* Ende von DCAEND.PAS *)