home *** CD-ROM | disk | FTP | other *** search
- (* ----------------------------------------------------------------------- *)
- (* DCEXE.PAS *)
- (* hier arbeitet der didaktische Computer *)
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Stop; (* nach Programmende bei "RUN" und "GO" alles anzeigen *)
- BEGIN
- IF command <> step THEN BEGIN Print_MemPage(counter); display_status; END;
- end_of_program := TRUE;
- END;
-
- PROCEDURE End_Condition; (* Programm in Endlos-Schleife ? *)
- BEGIN
- IF (ar = pc) AND ((command = run) OR (command = go)) THEN
- BEGIN Stop; error(loops); END;
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Load_Accu (value: INTEGER);
- BEGIN
- IF (value > (-1 * Succ(sign_val))) AND (value < sign_val) THEN
- BEGIN Load_Int(value,ac); Transfer_DR_ALU; END
- ELSE BEGIN Stop; error(ovf); END; (* Overflow *)
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Memory_Cycle;
- BEGIN Copy_Bits(ir,ar,addr_start,addr_end); Transfer_AD_AR; END;
-
- PROCEDURE Memory_Read;
- BEGIN Memory_Cycle; dr := memory[address]; Read_Cycle; END;
-
- PROCEDURE Memory_Write;
- BEGIN Memory_Cycle; memory[address] := dr; Write_Cycle; END;
-
- PROCEDURE Memory_Push;
- BEGIN
- ar := sp; Transfer_SP_AR; memory[s_ptr] := 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]; Read_Cycle;
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Load;
- BEGIN Memory_Read; ac := dr; Transfer_DR_ALU; END;
-
- PROCEDURE Store;
- BEGIN dr := ac; Transfer_AC_DR; Memory_Write; END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Add;
- BEGIN
- Memory_Read; Gate(pl,28,12,TRUE);
- Load_Accu(Int_Val(ac)+Int_Val(dr)); Gate(sp1,28,12,FALSE);
- END;
-
- PROCEDURE Subtract;
- BEGIN
- Memory_Read; Gate(mi,28,12,TRUE);
- Load_Accu(Int_Val(ac)-Int_Val(dr)); Gate(sp1,28,12,FALSE);
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Jump;
- BEGIN
- Copy_Bits(ir,pc,addr_start,addr_end); Transfer_AD_PC;
- counter := address; End_Condition;
- END;
-
- PROCEDURE Jump_if_Minus;
- BEGIN IF is_Minus(ac) THEN Jump; END;
-
- PROCEDURE Jump_to_Subroutine;
- BEGIN
- dr := pc; Transfer_PC_DR; Memory_Push;
- Copy_Bits(ir,pc,addr_start,addr_end); Transfer_AD_PC;
- Int_to_Bin(address,addr_start,addr_end,pc); counter := address;
- END;
-
- PROCEDURE Return;
- BEGIN
- Memory_Pop; pc := dr; Transfer_DR_PC;
- Bin_to_Int(pc,addr_start,addr_end,counter); End_Condition;
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Fetch_Instruction;
- BEGIN
- ar := pc; Transfer_PC_AR; Bin_to_Int(ar,addr_start,addr_end,address);
- dr := memory[address]; 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 do_Interrupt; (* Unterbrechung ausfuehren *)
- BEGIN
- dr := pc; Transfer_PC_DR; Memory_Push; counter := int_addr;
- Int_to_Bin(int_addr,addr_start,addr_end,pc); Transfer_IA_PC;
- END;
-
- PROCEDURE check_Interrupt; (* Unterbrechung aufgetreten ? *)
- VAR ch: CHAR;
- BEGIN
- IF Legal(int_addr) THEN
- IF KeyEntered AND ((command = run) OR (command = go)) THEN BEGIN
- GotoXY(2,25); RevOn; Write(' Interrupt wird ausgefuehrt ');
- RevOff; Bell; Delay(2 * time); ch := ReadKeyboard;
- Erase_Error; do_Interrupt;
- IF ch = esc THEN BEGIN Stop; error(break); END;
- END
- ELSE IF command = step THEN BEGIN
- GotoXY(2,25); RevOn; Write('<ESC>: Interrupt ausfuehren'); RevOff;
- ch := ReadKeyboard; Erase_Error;
- IF ch = esc THEN do_Interrupt;
- END;
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE check_Breakpoint;
- BEGIN
- IF (counter = break_addr)
- AND ((command = run) OR (command = go)) THEN BEGIN
- Stop; GotoXY(2,25); RevOn; Write('Stop: Breakpoint erreicht'); RevOff;
- END
- 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;
- 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);
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Execute_Program;
- BEGIN
- blink_num := 0; blink_time := 0; out_cycle := mode = delaying;
- IF out_cycle THEN blink_num := 2;
- REPEAT Execute_Instruction; UNTIL end_of_program; END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Go_From;
- VAR err: INTEGER;
- BEGIN
- Val(item[2],counter,err);
- IF (err = null) AND Legal(counter) THEN
- BEGIN Int_to_Bin(counter,addr_start,addr_end,pc); Execute_Program; END
- ELSE error(illadd); (* Illegal address *)
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Single_Step;
- BEGIN
- blink_num := 2; blink_time := time DIV 2;
- out_cycle := TRUE; Execute_Instruction;
- END;
- (* ----------------------------------------------------------------------- *)
- PROCEDURE Clear; (* Computer zuruecksetzen: RESET *)
- VAR i: INTEGER;
- BEGIN
- FOR i := 0 TO mem_size DO memory[i] := zero;
- 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;
- (* ----------------------------------------------------------------------- *)
- (* DCEXE.PAS *)
-