home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / 1988 / 08_09 / dcaend.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1988-05-17  |  9.0 KB  |  297 lines

  1. (* ------------------------------------------------------ *)
  2. (*                     DCAEND.PAS                         *)
  3. (*       Verbesserungen zum Didaktischen Computer         *)
  4. (*                aus  PASCAL 12/88.                      *)
  5. (*    (c) 1988 by Bernd Möller und PASCAL International   *)
  6. (* ------------------------------------------------------ *)
  7.  
  8. (* In DC.PAS muß die Typendeklaration wie folgt geändert  *)
  9. (* werden:                                                *)
  10.  
  11. TYPE
  12.   dc_word  = STRING[word_size];  op_str   = STRING[op_end];
  13.   mnem_str = STRING[mnem_size];  one_line = STRING[80];
  14.   lines    = STRING[max_length]; string2  = STRING[2];
  15.   errors   = (illcmd, illadd, illlab, illcod, illarg,
  16.               illcon, loops, ovf, illfil, illhlp, break);
  17.   mem_area = ARRAY [0..mem_size] OF record
  18.                                     speicherwort: dc_word;
  19.                                     NoCommand: boolean;
  20.                                     end;
  21.  
  22. (* Folgende Prozeduren sind zu ändern:                    *)
  23.  
  24. PROCEDURE Init;
  25. VAR i: INTEGER;  temp: dc_word;
  26. BEGIN
  27.   esc := Chr(27); RevOff; CrsOff; ClrScr; Init_Sys;
  28.   pl := '+'; mi := '-'; sp1 := ' '; sp2 := '  ';
  29.   ipc := '+1'; dpc := '-1'; rd := 'rd'; wr := 'wr';
  30.   mode := nowait;
  31.   mnems[0]  := 'LDA';  mnems[1]  := 'STA';
  32.   mnems[2]  := 'ADD';  mnems[3]  := 'SUB';
  33.   mnems[4]  := 'JMP';  mnems[5]  := 'JMS';
  34.   mnems[6]  := 'JSR';  mnems[7]  := 'RTN';
  35.   mnems[8]  := 'JPL';
  36.   FOR i := 9 TO 15 DO mnems[i] := '???';
  37.   temp := zero;  sp := zero;
  38.   FOR i := 0 TO instructions DO BEGIN
  39.     Int_to_Bin(i,op_start,op_end,temp);
  40.     op_codes[i] := Copy(temp,op_start,op_end);
  41.   END;
  42.   Print_Display;  Print_Computer;  Clear;
  43.   GotoXY(2,25);  revon;  Write(' <H> fuer Information');
  44.   RevOff; row := winymin;  GotoXY(1,row);
  45. END;
  46.  
  47. PROCEDURE Load_Constant (address: INTEGER);
  48.                            (* Konstante in Speicher laden *)
  49. VAR  value, err: INTEGER;
  50. BEGIN
  51.   Val(item[3],value,err);
  52.   IF (err = null) AND (value > (-1 * Succ(sign_val)))
  53.     AND (value < sign_val) THEN BEGIN
  54.       Load_Int(value,memory[address].speicherwort);
  55.       memory[address].NoCommand := true;
  56.       print_cell(address, memory[address].NoCommand);
  57.     END
  58.   ELSE  Error(illcon);                (* Illegal constant *)
  59. END;
  60.  
  61. PROCEDURE Load_Instruction (address: INTEGER;
  62.                             op_code: op_str);
  63. VAR  arg, i: INTEGER;  Mem: dc_word;
  64. BEGIN
  65.   IF item[2] = 'RTN' THEN item[3] := '0';
  66.   Val(item[3],arg,i);  Mem := zero;
  67.   IF (i = null) AND Legal(arg) THEN BEGIN
  68.     Int_to_Bin(arg,addr_start,addr_end,Mem);
  69.     FOR i := op_start TO op_end DO Mem[i] := op_code[i];
  70.     memory[address].speicherwort := Mem;
  71.     memory[address].NoCommand := false;
  72.     print_cell(address, memory[address].NoCommand);
  73.   END
  74.   ELSE  Error(illarg);                (* Illegal argument *)
  75. END;
  76.  
  77. PROCEDURE Read_Line;           (* Kommando-Zeile einlesen *)
  78. VAR  st: lines;  i: INTEGER;
  79. BEGIN
  80.   Invert_Cell(counter);  CrsOn;  GotoXY(1,row);  Bell;
  81.   Write('> ');  ReadLn(Line);  st := Line;
  82.   FOR i := 1 TO max_length - Length(Line) DO
  83.                                       st := Concat(st,' ');
  84.   CrsOff;  w_write(st);  Erase_Error;
  85.   print_cell(counter, memory[counter].NoCommand);
  86. END;
  87.  
  88. (*    2 Änderungen in DCKONV.PAS lauten:                  *)
  89.  
  90. FUNCTION is_Minus (VAR reg: dc_word): BOOLEAN;
  91. BEGIN  is_Minus := reg[sign_bit] = '1';  END;
  92.  
  93. FUNCTION Int_Val (VAR reg: dc_word): INTEGER;
  94. VAR  value: INTEGER;
  95. BEGIN
  96.   Bin_to_Int(reg,Succ(sign_bit),word_size,value);
  97.   IF is_Minus(reg) THEN
  98.     Int_Val := - value ELSE  Int_Val := value;
  99. END;
  100.  
  101. (*    Die Änderungen für DCout.PAS sind:                  *)
  102.  
  103. PROCEDURE Dasm (VAR reg: dc_word; VAR arg: INTEGER);
  104. BEGIN
  105.   Bin_to_Int (reg, op_start + 1, addr_end, arg);
  106.   IF reg [sign_bit] = '1' THEN arg := arg - sign_val;
  107. END;
  108.  
  109. PROCEDURE Print_Register (x, y: INTEGER; VAR reg: dc_word);
  110. BEGIN  GotoXY(x,y);  Write(reg);  END;
  111.  
  112. PROCEDURE Out_Cell (adr: INTEGER; NoCommand: BOOLEAN);
  113. VAR arg, y: INTEGER;  mnem: mnem_str;
  114. BEGIN
  115.   IF NoCommand THEN BEGIN
  116.     Dasm (memory[adr].speicherwort, arg);
  117.     mnem := 'DEF';  END
  118.   ELSE  Disassemble(memory[adr].speicherwort,mnem,arg);
  119.   y := (adr MOD 25) + 1;
  120.   GotoXY(59,y);  Write(adr:2,mnem:4,arg:3);
  121.   GotoXY(69,y);  Write(memory[adr].speicherwort,' ');
  122. END;
  123.  
  124. PROCEDURE Print_MemPage (adr: INTEGER);
  125. VAR i, from_cell, to_cell, arg, y: INTEGER;
  126. BEGIN
  127.   i := adr DIV screen_lines;  RevOn;
  128.   IF i <> mempage THEN BEGIN
  129.     mempage := i;  y := 0;
  130.     from_cell := i*screen_lines;
  131.     to_cell := from_cell+Pred(screen_lines);
  132.     IF to_cell > mem_size THEN to_cell := mem_size;
  133.     FOR i := from_cell TO to_cell DO BEGIN
  134.       Out_Cell(i, memory[i].NoCommand);
  135.       y := Succ(y);
  136.     END;
  137.     WHILE y < screen_lines DO BEGIN
  138.       y := Succ(y);
  139.       GotoXY(59,y); Write(' ':9); GotoXY(69,y);
  140.       Write(' ':Succ(word_size));
  141.     END;
  142.   END;
  143.   RevOff;
  144. END;
  145.  
  146. PROCEDURE Print_Cell (i: INTEGER; NoCommand: BOOLEAN);
  147.                    (* Inhalt einer Speicherzelle anzeigen *)
  148. BEGIN
  149.   IF (i DIV screen_lines)=mempage THEN BEGIN
  150.     RevOn; Out_Cell(i, NoCommand); RevOff;
  151.   END;
  152. END;
  153.  
  154. PROCEDURE Invert_Cell (i: INTEGER);
  155. BEGIN
  156.   Print_MemPage(i);  RevOff;
  157.   Out_Cell(i, memory[i].NoCommand);
  158. END;
  159.  
  160. PROCEDURE Print_Cycle (Str: lines);
  161.                              (* Maschinen-Zyklus anzeigen *)
  162. BEGIN
  163.   IF out_cycle THEN BEGIN
  164.     RevOn; GotoXY(6,25);  Write(Str);  RevOff;
  165.   END;
  166. END;
  167.  
  168. PROCEDURE Print_Display;        (* das Drumherum zeichnen *)
  169. VAR  i: INTEGER;
  170. BEGIN
  171.   FOR i := 1 TO 25 DO BEGIN
  172.     GotoXY(58,i); Write(vd);
  173.     GotoXY(68,i); Write(vd);
  174.   END;
  175.   GotoXY(1,winymin-1);
  176.   RevOn;  Write('  DC v1.3 (c) 1987  PASCAL INT.  ');
  177.   Write('  Register:      Mnem:  ');  RevOff;
  178.   FOR i := winymin-1 TO winymax+1 DO BEGIN
  179.     GotoXY(33,i); Write(vd);
  180.     GotoXY(47,i);  Write(vd);
  181.   END;
  182.   GotoXY(34,24); RevOn; Write('  Bpt: none  ');
  183.   GotoXY(34,25);        Write('  Int: none  ');
  184.   GotoXY(1,25);  Write(' ':32);
  185.   GotoXY(48,18); Write(' LDA  JPL ');
  186.   GotoXY(48,19); Write(' STA  ??? ');
  187.   GotoXY(48,20); Write(' ADD  ??? ');
  188.   GotoXY(48,21); Write(' SUB  ??? ');
  189.   GotoXY(48,22); Write(' JMP  ??? ');
  190.   GotoXY(48,23); Write(' JMS  ??? ');
  191.   GotoXY(48,24); Write(' JSR  ??? ');
  192.   GotoXY(48,25); Write(' RTN  DEF ');
  193.   RevOff;  GotoXY(34,18); Write('AC');
  194.   GotoXY(34,19);  Write('DR');
  195.   GotoXY(34,20); Write('AR');
  196.   GotoXY(34,21); Write('IR');
  197.   GotoXY(34,22); Write('PC');
  198.   GotoXY(34,23); Write('SP');
  199. END;
  200.  
  201. (*  Die Änderungen in DCEXE.PAS sind:                     *)
  202.  
  203. PROCEDURE Memory_Read;
  204. BEGIN
  205.   Memory_Cycle;
  206.   dr := memory[address].speicherwort;
  207.   Read_Cycle;
  208. END;
  209.  
  210. PROCEDURE Memory_Write;
  211. BEGIN
  212.   Memory_Cycle;
  213.   memory[address].speicherwort := dr;
  214.   Write_Cycle;
  215. END;
  216.  
  217. PROCEDURE Memory_Push;
  218. BEGIN
  219.   ar := sp;  Transfer_SP_AR;
  220.   memory[s_ptr].speicherwort := dr;  Write_Cycle;
  221.   decrement(s_ptr);
  222.   Int_to_Bin(s_ptr,addr_start,addr_end,sp);  Dec_SP;
  223. END;
  224.  
  225. PROCEDURE Memory_Pop;
  226. BEGIN
  227.   increment(s_ptr);
  228.   Int_to_Bin(s_ptr,addr_start,addr_end,sp);  Inc_SP;
  229.   ar := sp;  Transfer_SP_AR;
  230.   dr := memory[s_ptr].speicherwort;  Read_Cycle;
  231. END;
  232.  
  233. PROCEDURE Jump_if_Plus;
  234. BEGIN
  235.   IF is_Plus(ac) THEN Jump;
  236. END;
  237.  
  238. PROCEDURE Fetch_Instruction;
  239. BEGIN
  240.   ar := pc;  Transfer_PC_AR;
  241.   Bin_to_Int(ar,addr_start,addr_end,address);
  242.   dr := memory[address].speicherwort;
  243.   Read_Cycle;  increment(counter);
  244.   Int_to_Bin(counter,addr_start,addr_end,pc);
  245.   Inc_PC;
  246.   ir := dr;  Transfer_DR_IR;
  247.   Bin_to_Int(ir,op_start,op_end,op_code);
  248.   Bin_to_Int(ir,addr_start,addr_end,address);
  249. END;
  250.  
  251. PROCEDURE Execute_Instruction;
  252. VAR old_pc: INTEGER;  ch: CHAR;
  253. BEGIN
  254.   end_of_program := FALSE;  old_pc := counter;
  255.   Invert_Cell(old_pc);
  256.   Fetch_Instruction;
  257.   CASE op_code OF
  258.      0: Load;     1: Store;  2: Add;
  259.      3: Subtract; 4: Jump;   5: Jump_if_Minus;
  260.      6: Jump_to_Subroutine;  7: Return;
  261.      8: Jump_if_Plus;
  262.   END;
  263.   IF out_cycle THEN Print_Registers;
  264.   check_Interrupt;  check_Breakpoint;
  265.   IF KeyEntered THEN
  266.     IF ReadKeyboard = esc THEN BEGIN
  267.       Stop; error(break);
  268.     END;
  269.   print_cell(old_pc, memory[old_pc].NoCommand);
  270. END;
  271.  
  272. PROCEDURE Clear;         (* Computer zuruecksetzen: RESET *)
  273. VAR  i: INTEGER;
  274. BEGIN
  275.   FOR i := 0 TO mem_size DO BEGIN
  276.     memory[i].speicherwort := zero;
  277.     memory[i].NoCommand := false;
  278.   END;
  279.   ac := zero;  ar := zero;  pc := zero;  dr := zero;
  280.   ir := zero;
  281.   counter := 0;    address := 0;  s_ptr := mem_size;
  282.   Int_to_Bin(s_ptr,addr_start,addr_end,sp);
  283.   mempage := -1;   Print_MemPage(0);  out_cycle := TRUE;
  284.   display_status;  items := 1;  breakpoint;  interrupt;
  285. END;
  286.  
  287. (*   die Äderungen für DCTRAN.PAS:                        *)
  288.  
  289. PROCEDURE Write_Cycle;              (* der Schreib-Zyklus *)
  290. BEGIN
  291.   Print_Cycle('DR -> MEMORY');  Gate(wr,43,9,TRUE);
  292.   Print_Cell(address, memory[address].NoCommand);
  293.   Wait;  Gate(sp2,43,9,FALSE);
  294. END;
  295. (* ------------------------------------------------------ *)
  296. (*                Ende von DCAEND.PAS                     *)
  297.