Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
pSIMPLETRON 1.0 - LMS.pas

LMS.pas

Caricato da: NOVA99
Scarica il programma completo

  1. (*
  2. *       pSIMPLETRON 1.0
  3. *
  4. *   COMPLETATO IL 07/09/2014
  5. *
  6. *          BY NOVA99
  7. *)
  8.  
  9. unit LMS;
  10.  
  11. interface
  12.  
  13. uses crt;
  14.  
  15. var (*MEMORIE DI SISTEMA*)
  16.     InstructionReg:Array[0..100] of integer; //MEMORIA DEL PROGRAMMA
  17.     InstructionMem:Array[0..100] of integer; //CRONOLOGIA DELLE ISTRUZIONI ESEGUITE
  18.     Memory:Array[0..100] of real; //MEMORIA VARIABILI
  19.  
  20.  
  21.     (*REGISTRI*)
  22.     numI:byte; //CONTATORE ISTRUZIONI
  23.     operationCode:integer; //IDENTIFICATORE DELL'OPERAZIONE DA ESEGUIRE
  24.     operand:integer; //IDENTIFICATORE DELLA POSZIONE DELLA VARIABILE IN USO
  25.     accumulator:real; //ACCUMULATORE ARITMETICO
  26.     aux_accumulator:real; //ACCUMULATORE AUSILIARIO
  27.     exit_correct:string[12]='SUCCESSFUL'; //REGISTRO DEL TIPO DI USCITA
  28.    
  29.     cont:byte=00; //VARIABILE DI SERVIZIO
  30.  
  31. const (*OPERAZIONI DI I/O*)
  32.       CIN        = 10; //INPUT
  33.       COUT       = 11; //OUTPUT
  34.      
  35.       (*OPERAZIONI DI GESTIONE DELLA MEMORIA (x = Memory[ x ]) *)
  36.       LOAD       = 20; //CARICA NELL'ACCUMULATORE
  37.       STORE      = 21; //SALVA IN x
  38.       DELETE     = 22; //RESETTA x
  39.       RESET      = 23; //RESETTA LA MEMORIA
  40.       RESETINSTR = 24; //RESETTA LA CRONOLOGIA DELLE ISTRUZIONI
  41.       LOADAUX    = 25; //CARICA x NELL'ACCUMULATORE AUSILIARIO
  42.      
  43.       (*OPERAZIONI MATEMATICHE FONDAMENTALI (x = Memory[ x ]) *)
  44.       ADD        = 30; //AGGIUNGE x ALL'ACCUMULATORE
  45.       SUBTR      = 31; //SOTTRAE  x  "      "
  46.       DIVIS      = 32; //DIVIDE   L'ACCUMULATORE PER x
  47.       MULT       = 33; //MOLTIPLICA   L'ACCUMULATORE PER x
  48.       QUOZ       = 34; //QUOTA    L'ACCUMULATORE PER x
  49.       RES        = 35; //CALCOLA IL RESTO DELL'OP. PRECEDENTE
  50.       ROOF       = 36; //ARROTONDA x ALL'INTERO MINORE PIU' VICINO
  51.       CEIL       = 37; //    "     "  "    "  MAGGIORE PIU' VICINO
  52.       FROUND     = 38; //ARROTONDA x
  53.       FABS       = 39; //CALCOLA IL VALORE ASSOLUTO DI x
  54.          
  55.       (*OPERAZIONI DI CONTROLLO (x = Memory[ x ], y = InstructionReg[ y ]) *)
  56.       BRANCH     = 40; //SALTA A y
  57.       BRANCHNEG  = 41; //  "    "      "      " SE L'ACCUMULATORE E' NEGATIVO
  58.       BRANCHZERO = 42; //  "    "      "      "  "        "       "  ZERO
  59.       BRANCHPOS  = 43; //  "    "      "      "  "        "       "  POSITIVO
  60.       HALT       = 44; //INTERROMPE L'ESECUZIONE
  61.       PAUSE      = 45; //METTE IN PAUSA L'ESECUZIONE E CHIEDE UN INPUT PER CONTINUARE
  62.       RETARD     = 46; //RITARDA L'ESECUZIONE PER x SECONDI
  63.       BRANCHMORE = 47; //SALTA A y SE ACCUMULATORE > ACCUMULATORE_AUSLIARIO
  64.       BRANCHEQL  = 48; //  "   " "  "     "        =            "  
  65.       BRANCHLESS = 49; //  "   " "  "     "        <            "
  66.      
  67.       (*OPERAZIONI MATEMATICHE AVANZATE (x = Memory[ x ]) *)
  68.       FSQRT      = 50; //CALCOLA LA RADICE DI x              |
  69.       FSQR       = 51; //   "    IL QUADRATO DI x            |
  70.       FEXP       = 52; //   "    L'ESPONENZIALE DI x         > SALVA IN X
  71.       FLOG       = 53; //   "    IL LOGARITMO DECIMALE DI x |
  72.       FLN        = 54; //   "     "    "      NATURALE "  "
  73.       POW        = 55; //   "    ACCUMULATORE ^ x
  74.       ROOT       = 56; //   "    x-esima RADICE DELL'ACCUMULATORE
  75.       FSIN       = 57; //   "    IL SENO DI x       |
  76.       FCOS       = 58; //   "     " COSENO DI x      > SALVA IN X
  77.       FTAN       = 59; //   "    LA TANGENTE DI x   |
  78.      
  79.       (*OPERAZIONE AUSILIARIA*)
  80.       STOPLOAD   = 9999; //INTERROMPE L'INSERIMENTO DEL PROGRAMMA
  81.      
  82.       CodeMem : SET OF byte = [CIN, COUT, LOAD..LOADAUX, ADD..FABS, BRANCH..BRANCHLESS, FSQRT..FTAN, 99]; //MEMORIA DELLE FUNZIONI UTILIZZABILI
  83.      
  84. procedure Caption; //VISUALIZZA A VIDEO L'INTESTAZIONE
  85. procedure GetInstr; //ACQUISISCE LE ISTRUZIONI
  86. function InstrOK:boolean; //CONTROLLA IL CODICE INSERITO
  87. procedure ExeInstr; //ESEGUE IL PROGRAMMA
  88. procedure ViewDump; //VISUALIZZA IL DUMP DI MEMORIA
  89.  
  90. implementation
  91.  
  92. procedure Caption;
  93. begin
  94.  
  95.      clrscr;
  96.      
  97.      writeln('*** WELCOME TO SIMPLETRON! ***');
  98.      writeln('*** PLEASE ENTER YOUR PROGRAM ONE INSTRUCTION ***');
  99.      writeln('*** (OR DATA WORD) AT A TIME. I WILL TYPE THE ***');
  100.      writeln('*** LOCATION NUMBER AND A QUESTION MARK (?).  ***');
  101.      writeln('*** YOU THEN TYPE THE WORD FOR THAT LOCATION. ***');
  102.      writeln('*** TYPE THE SENTINEL 9999 TO STOP ENTERING   ***');
  103.      writeln('*** YOUR PROGRAM ***');
  104.      writeln;writeln;
  105.  
  106. end;
  107.  
  108. procedure GetInstr;
  109. begin
  110.  
  111.      numI:=0;
  112.      
  113.      repeat
  114.      begin
  115.  
  116.        write(numI, ' ? ');
  117.        readln( InstructionReg[ numI ] );
  118.        numI += 1;
  119.  
  120.      end;
  121.      until InstructionReg[ numI-1 ] = STOPLOAD;
  122.  
  123.      writeln;writeln;
  124.      write('*** PROGRAM LOADING COMPLETE ***');
  125.      writeln;writeln;
  126.      write('*** START PROGRAM CONTROL... ***');
  127.      writeln;writeln;
  128.  
  129. end;
  130.  
  131. function InstrOK:boolean;
  132.  
  133. var err_num:byte = 0;
  134.     warn_num:byte = 0;
  135.     halt_flag:boolean=false;
  136.  
  137. begin
  138.  
  139.      numI:=00;
  140.      
  141.      if (InstructionReg[ 0 ] = 9999) then //SE L'UNICA ISTRUZIONE PRESENTE E' STOPLOAD IL PROGRAMMA NON PUO' (OVVIAMENTE) ESSERE ESEGUITO
  142.      begin
  143.      
  144.                writeln;
  145.                writeln('*** ERROR FOUND IN LINE N°0: ***');
  146.                writeln('*** NO INSTRUCTION BEFORE STOPLOAD (9999)  ***');
  147.                writeln;
  148.            
  149.                err_num:=1;
  150.      end
  151.      else
  152.      begin
  153.          repeat
  154.                
  155.                //CONTROLLA SE L'ISTRUZIONE E' COMPRESA TRA STOPLOAD (9999) E L'INPUT ALLA VARIABILE 0 (1000)
  156.                 if  NOT( InstructionReg[ numI ] = STOPLOAD) AND NOT( (InstructionReg[ numI ] < 6000) AND (InstructionReg[ numI ] > 999) ) then
  157.                 begin
  158.  
  159.                     err_num+=1;
  160.                
  161.                     writeln;
  162.                     writeln('*** ERROR FOUND IN LINE N°', numI, ': ***');
  163.                     writeln('*** INSTRUCTION ''', InstructionReg[ numI ], ''' IS OUT OF THE ALLOWED RANGE  ***');
  164.                     writeln;
  165.  
  166.                 end;
  167.            
  168.                 operationCode:=InstructionReg[ numI ] div 100;
  169.                 operand:=InstructionReg[ numI ] mod 100;    
  170.        
  171.                 //CONTROLLA CHE IL CODICE DELL'OPERAZIONE ESISTA IN MEMORIA
  172.                 if NOT(  operationCode in CodeMem ) then
  173.                 begin
  174.  
  175.                     err_num+=1;
  176.  
  177.                     writeln;
  178.                     writeln('*** ERROR FOUND IN LINE N°', numI:2, ':  ***');
  179.                     writeln('*** INSTRUCTION CODE ''', operationCode, ''' NOT FOUND ***');
  180.                     writeln;
  181.  
  182.                 end
  183.                 else
  184.                 begin
  185.          
  186.                      if ( operand > 1) AND ( operationCode = PAUSE) then //LA FUNZIONE PAUSE ACCETTA COME ARGOMENTI  0 O 1
  187.                      begin
  188.        
  189.                           err_num+=1;
  190.  
  191.                           writeln;
  192.                           writeln('*** ERROR FOUND IN LINE N°', numI:2, ':  ***');
  193.                           writeln('*** INVALID ARGUMENT (''', operand ,''') FOR PAUSE FUNCTION ***');
  194.                           writeln;
  195.        
  196.                      end;
  197.                      
  198.                      //LE FUNZIONI RESET, RESETINSTR E HALT NON RICHIEDONO ARGOMENTI. SE QUESTI VENGONO INSERITI SONO IGNORATI
  199.                      if ((operationCode = RESET) OR (operationCode = RESETINSTR) OR (operationCode = HALT)) AND (operand > 0) then
  200.                      begin
  201.            
  202.                           writeln;
  203.                           writeln('*** WARNING IN LINE N°', numI:2, ':  ***');
  204.                           writeln('*** THIS FUNCTION DOESN''T USE AN ARGUMENT. ***');
  205.                           writeln('*** YOUR ARGUMENT (''', operand ,''') WILL BE IGNORED  ***');
  206.                           writeln;
  207.                        
  208.                           warn_num+=1;  
  209.        
  210.                      end;
  211.  
  212.            
  213.                 end;                
  214.                
  215.                 numI+=1;
  216.        
  217.                 if operationCode=HALT then halt_flag:=true; //CONTROLLA CHE VI SIA UNA ISTRUZIONE HALT
  218.  
  219.           until InstructionReg[ numI-1 ] = STOPLOAD;
  220.      
  221.       end;
  222.      
  223.      
  224.       if err_num>0 then
  225.       begin
  226.  
  227.            writeln;
  228.            writeln('*** ', err_num, ' ERROR(S) FOUND ***');
  229.            if warn_num>0 then writeln('*** ', warn_num:2, ' WARNING(S) GENERATED ***');
  230.            writeln('*** PROGRAM CAN''T BE EXECUTED ***');
  231.            writeln;
  232.  
  233.            InstrOK:=false;
  234.  
  235.       end
  236.       else
  237.       begin
  238.  
  239.            //SE NON VI SONO HALT IL PROGRAMMA POTREBBE COMPORTARSI IN MODO IMPREVEDIBILE
  240.            if halt_flag=false then
  241.            begin
  242.        
  243.                 writeln;
  244.                 writeln('*** WARNING: NO HALT FUNCTIONS FOUND ***');
  245.                 writeln('*** EXECUTION WON''T STOP TILL A STOPLOAD  ***');
  246.                 writeln('*** PROGRAM''S BEAHVIOR COULD BE UNDEFINED ***');
  247.                 writeln;
  248.        
  249.                 warn_num+=1;
  250.        
  251.            end;
  252.                  
  253.            writeln;
  254.            writeln('*** NO ERRORS FOUND ***');
  255.            if warn_num>0 then writeln('*** ', warn_num:2, ' WARNING(S) GENERATED ***');
  256.            writeln('*** PROGRAM CAN BE EXECUTED ***');
  257.            writeln;
  258.  
  259.            InstrOK:=true;
  260.  
  261.       end;
  262.  
  263. end;
  264.  
  265. procedure ExeInstr;
  266.  
  267. var cont2, cont3:byte;
  268.     instruction:integer;
  269.     delay_factor:integer;
  270.  
  271. begin
  272.  
  273.      cont3:=00;
  274.      numI:=0;
  275.  
  276.      repeat
  277.      begin
  278.  
  279.             instruction:=InstructionReg[ numI ];
  280.  
  281.             operationCode:=instruction div 100;
  282.             operand      :=instruction mod 100;
  283.            
  284.             //SE LA FUNZIONE ATTUALE PRODUCE UN OUTPUT A VIDEO, SI SCRIVE L'INIZIO DI UNA NUOVA RIGA A VIDEO
  285.             if ( ( operationCode = CIN ) OR ( operationCode = COUT ) OR ( operationCode = PAUSE ) ) then
  286.             begin
  287.        
  288.                 write(cont, ' > ');
  289.        
  290.             end;
  291.            
  292.             case operationCode of
  293.  
  294.                 CIN:  readln(Memory[ operand ]);
  295.                 COUT: writeln(Memory[ operand ]:6:4);
  296.  
  297.                 LOAD:       accumulator:=Memory[ operand ];
  298.                 STORE:      Memory[ operand ]:=accumulator;
  299.                 DELETE:     Memory[ operand ]:=0;
  300.                 RESET:      for cont2:=0 to 100 do Memory[ cont2 ]:=0;
  301.                 RESETINSTR: begin
  302.                                 for cont2:=0 to 100 do InstructionMem[ cont2 ]:=0;
  303.                                 cont3:=0;
  304.                             end;
  305.                 LOADAUX:    aux_accumulator:=Memory[ operand ];
  306.  
  307.                 ADD:    accumulator+=Memory[ operand ];
  308.                 SUBTR:  accumulator-=Memory[ operand ];
  309.                 DIVIS:  begin
  310.  
  311.                              //SE SI STA TENTANDO DI DIVIDERE 0/0 O <NUMERO NATURALE>/0 SI PRODUCE UN ERRORE
  312.                              if ( ( Memory[ operand ]= 0)AND(accumulator = 0) ) OR ( ( Memory[ operand ]= 0)AND(accumulator <> 0) ) then
  313.                              begin
  314.                                
  315.                                  writeln;
  316.                                
  317.                                  if ( Memory[ operand ]= 0)AND(accumulator = 0) then
  318.                                  begin
  319.                                          writeln('*** ATTEMPT TO DIVIDE 0 BY 0. UNDEFINED RESULT ***');
  320.                                          writeln('*** SIMPLETRON EXECUTON ABNORMALLY TERMINATED ***');
  321.                                  end
  322.                                  else
  323.                                  begin
  324.                                         if ( Memory[ operand ]= 0)AND(accumulator <> 0) then writeln('*** ATTEMPT TO DIVIDE BY 0. IMPOSSIBLE OPERATION ***');
  325.                                         writeln('*** SIMPLETRON EXECUTION ABNORMALLY TERMINATED   ***');
  326.                                  end;
  327.                                
  328.                                  exit_correct:='FAILURE';
  329.                                  break;
  330.                
  331.                              end
  332.                              else accumulator /= Memory[ operand ];
  333.                
  334.                         end;
  335.                 MULT:   accumulator *= Memory[ operand ];
  336.                 QUOZ:   accumulator := trunc(accumulator) div trunc( Memory[ operand ] );
  337.                 RES:    accumulator := trunc(accumulator) mod trunc( Memory[ operand ] );
  338.                 ROOF:   Memory[ operand ] := trunc(Memory[ operand ]);
  339.                 CEIL:   Memory[ operand ] := trunc(Memory[ operand ]) + 1;
  340.                 FROUND: Memory[ operand ] := round(Memory[ operand ]);
  341.                 FABS:   Memory[ operand ] := abs(Memory[ operand ]);
  342.  
  343.                 BRANCH:     numI:=operand;
  344.                 BRANCHNEG:  if(accumulator<0)then numI:=operand else numI+=1;
  345.                 BRANCHZERO: if(accumulator=0)then numI:=operand else numI+=1;
  346.                 BRANCHPOS:  if(accumulator>0)then numI:=operand else numI+=1;
  347.                 HALT:       begin
  348.                                 writeln;
  349.                                 writeln('*** SIMPLETRON EXECUTION TERMINATED ***');
  350.                                 break;
  351.                             end;
  352.                 PAUSE:      begin
  353.                                 if operand=1 then write('  *** PRESS A KEY TO PROCEED... ***');
  354.                                 readkey;
  355.                                 writeln;
  356.                             end;
  357.                 RETARD:     begin
  358.                                 write('*** DELAYING EXECUTION... ***');
  359.                                 delay_factor := trunc(Memory[ operand ]) * 1000;
  360.                                 delay(delay_factor);
  361.                                 gotoXY( 1, WhereY-1);
  362.                                 ClrEOL;
  363.                             end;
  364.                 BRANCHMORE:if(accumulator>aux_accumulator)then numI:=operand else numI+=1;
  365.                 BRANCHEQL: if(accumulator=aux_accumulator)then numI:=operand else numI+=1;
  366.                 BRANCHLESS:if(accumulator<aux_accumulator)then numI:=operand else numI+=1;
  367.                                
  368.                        //COM'E' NOTO, CALCOLARE UNA RADICE PARI DI UN NUMERO NEGATIVO PRODUCE UN ERRORE
  369.                 FSQRT: if (Memory[ operand ]>=0) then accumulator := SQRT(Memory[ operand ])
  370.                        else
  371.                        begin
  372.                
  373.                             writeln;
  374.                             writeln('*** ATTEMPT TO CALCULATE THE SQUARE ROOT OF A NEGATIVE NUMBER ***');
  375.                             writeln('*** SIMPLETRON EXECUTION ABNORMALLY TERMINATED ***');
  376.                             exit_correct:='FAILURE';
  377.                             break;
  378.                
  379.                         end;
  380.                 FSQR : Memory[ operand ] := SQR(Memory[ operand ]);
  381.                 FEXP : Memory[ operand ] := EXP(Memory[ operand ]);
  382.                 FLOG : Memory[ operand ] := LN(Memory[ operand ]) / LN(10);
  383.                 FLN  : Memory[ operand ] := LN(Memory[ operand ]);
  384.                 POW  : accumulator := EXP( LN(accumulator) * Memory[ operand ] );
  385.                 ROOT : begin
  386.        
  387.                            if (accumulator>=0) then accumulator := EXP( LN(accumulator) / Memory[ operand ] )
  388.                            else
  389.                            begin
  390.                                 if ( trunc(Memory[ operand ]) mod 2 ) <> 0 then
  391.                                 begin
  392.                    
  393.                                     writeln;
  394.                                     writeln('*** ATTEMPT TO CALCULATE AN EVEN ROOT OF A NEGATIVE NUMBER ***');
  395.                                     writeln('*** SIMPLETRON EXECUTION ABNORMALLY TERMINATED ***');
  396.                                     exit_correct:='FAILURE';
  397.                                     break;
  398.                                    
  399.                                  end
  400.                                  else accumulator := EXP( LN(accumulator) / Memory[ operand ] );
  401.                      
  402.                             end;
  403.                
  404.                         end;
  405.                 FSIN : Memory[ operand ] := SIN(Memory[ operand ]);
  406.                 FCOS : Memory[ operand ] := COS(Memory[ operand ]);
  407.                 FTAN : Memory[ operand ] := SIN(Memory[ operand ])/COS(Memory[ operand ]);
  408.  
  409.            end;
  410.  
  411.            InstructionMem[ cont3 ]:=instruction;
  412.            cont3+=1;
  413.            
  414.            
  415.            //SE NON SONO STATI ESEGUITI SALTI IL CONTATORE VIENE INCREMENTATO NORMALMENTE
  416.            if NOT( (operationCode>=BRANCH) AND (operationCode<=BRANCHPOS) ) then
  417.            begin
  418.  
  419.                 numI+=1;
  420.  
  421.            end;
  422.        
  423.            if ( ( operationCode = CIN ) OR ( operationCode = COUT ) OR ( operationCode = PAUSE ) OR ( operationCode = RETARD ) ) then cont+=1;
  424.        
  425.      end;
  426.      until (instruction=HALT) OR (instruction=STOPLOAD); //NORMALMENTE
  427.      
  428.      ViewDump;
  429.  
  430. end;
  431.  
  432. procedure ViewDump;
  433.  
  434. var sn:char;
  435.     cont2:byte=00;
  436.  
  437. begin
  438.  
  439.     writeln;writeln;writeln;
  440.     writeln('*** PRESS ''1'' TO SEE THE MEMORY DUMP ***');
  441.    
  442.     sn:=readkey;
  443.    
  444.     gotoXY( 1, WhereY-1);
  445.     ClrEOL;
  446.    
  447.     cont := 0;
  448.    
  449.     if sn='1' then
  450.     begin
  451.    
  452.         writeln('******** SYSTEM REGISTERS:');
  453.         writeln('*');
  454.         writeln('*  ACCUMULATOR          = ', accumulator:5:2);
  455.         writeln('*');
  456.         writeln('*  AUXILIAR ACCUMULATOR = ', aux_accumulator:5:2);
  457.         writeln('*');
  458.         writeln('*  OPERATION CODE       = ', operationCode);
  459.         writeln('*');
  460.         writeln('*  OPERAND              = ', operand);
  461.         writeln('*');
  462.         writeln('*  INSTRUCTION COUNTER  = ', numI);
  463.         writeln('*');
  464.         writeln('*  EXIT TYPE            = ', exit_correct );
  465.         writeln('*');
  466.    
  467.         writeln;writeln;
  468.    
  469.         writeln('******** VARIABLES MEMORY');
  470.         writeln('*');
  471.         writeln('*       0      1      2      3      4      5      6      7      8      9');
  472.         writeln('*');
  473.         write('* ', cont,'   ');
  474.    
  475.         while (cont<100) do
  476.         begin
  477.            
  478.             for cont2:=0 to 9 do write(Memory[ cont + cont2 ]:5:2,'  ');
  479.  
  480.             if (cont<100) then writeln;writeln('*');
  481.  
  482.             cont+=10;
  483.  
  484.             if (cont<100) then write('* ', cont,'  ');
  485.  
  486.         end;
  487.    
  488.         cont:=00;
  489.    
  490.         writeln;writeln;
  491.    
  492.         //LA CRONOLOGIA DELLE ISTRUZIONI VIENE VISUALIZZATA (E REGISTRATA) PER RENDERE CONTO DI COME E' STATO ESEGUITO IL PROGRAMMA
  493.         writeln('******** INSTRUCTIONS TIMELINE:');
  494.         writeln('*');
  495.         writeln('*        0     1     2     3     4     5     6     7     8     9');
  496.         writeln('*');
  497.         write('* ', cont,'   ');
  498.    
  499.         while (cont<100) do
  500.         begin
  501.            
  502.             for cont2:=0 to 9 do write(InstructionMem[ cont + cont2 ]:4,'  ');
  503.  
  504.             if (cont<100) then writeln;writeln('*');
  505.  
  506.             cont+=10;
  507.  
  508.             if (cont<100) then write('* ', cont,'  ');
  509.  
  510.         end;
  511.    
  512.     end;
  513.  
  514. end;
  515.  
  516. end.