jsos

college code for operating system fundamentals in js

git clone https://9o.is/git/jsos.git

cpu.js

(4553B)


      1 /* ------------  
      2    CPU.js
      3 
      4    Requires global.js.
      5    
      6    Routines for the host CPU simulation, NOT for the OS itself.  
      7    In this manner, it's A LITTLE BIT like a hypervisor,
      8    in that the Document envorinment inside a browser is the "bare metal" (so to speak) for which we write code
      9    that hosts our client OS. But that analogy only goes so far, and the lines are blurred, because we are using
     10    JavaScript in both the host and client environments.
     11 
     12    This code references page numbers in the text book: 
     13    Operating System Concepts 8th editiion by Silberschatz, Galvin, and Gagne.  ISBN 978-0-470-12872-5
     14    ------------ */
     15 
     16 /* 
     17  * The cpu that contains the program counter (PC), 
     18  * accumulator (ACC), X register (X), 
     19  * Y register (Y), Z-ero flag (Z).
     20  */
     21 function cpu() {
     22   this.PC    = 0;
     23   this.ACC   = 0;
     24   this.X     = 0;
     25   this.Y     = 0;
     26   this.Z     = 0;
     27     
     28   this.init = function() {
     29     this.output(); 
     30   }
     31   
     32   /* Executes a CPU cycle. */ 
     33   this.cycle = function() {
     34     krnTrace("CPU cycle");
     35     this.execute();
     36     this.output();
     37 
     38     _KernelCPUScheduler.running.bursts += 1;
     39   }
     40 
     41   /* 
     42    * Executes the byte in location PC.
     43    */
     44   this.execute = function() {
     45     var operator = _Memory.getByte(this.PC++);
     46     switch(operator) {
     47       // LDA: Load the accumulator with a constant
     48       case 0xA9:  
     49         this.ACC = this.immediateOperand();
     50         break;
     51 
     52       // LDA: Load the accumulator from memory
     53       case 0xAD: 
     54         this.ACC = this.directOperand();
     55         break;
     56 
     57       // STA: Store the accumulator in memory
     58       case 0x8D: 
     59         _Memory.setByte(this.ACC, this.immediateOperand() + this.base());
     60         this.PC += 1;
     61         break;
     62 
     63       // ADC: Add with carry
     64       case 0x6D: 
     65         this.ACC += this.directOperand();
     66         break;
     67 
     68       // LDX: Load the X register with a constant
     69       case 0xA2: 
     70         this.X = this.immediateOperand();
     71         break; 
     72 
     73       // LDX: Load the X register from memory 
     74       case 0xAE: 
     75         this.X = this.directOperand();
     76         break;
     77 
     78       // LDY: Load the Y register with a constant
     79       case 0xA0: 
     80         this.Y = this.immediateOperand();
     81         break;
     82 
     83       // LDY: Load the Y register from memory
     84       case 0xAC:  
     85         this.Y = this.directOperand();
     86         break;
     87 
     88       // NOP: No operation
     89       case 0xEA: 
     90         break;
     91 
     92       // BRK: Break (Terminate) 
     93       case 0x00: 
     94         krnInterrupt(SYSCALL_IRQ, 0x00);
     95         break;
     96 
     97       // CPX: Compare a byte in memory to the X reg 
     98       // Sets the Z (zero) flag if equal
     99       case 0xEC: 
    100         this.Z = this.directOperand() == this.X ? 1 : 0;
    101         break;
    102 
    103       // BNE: Branch X bytes if Z flag = 0 
    104       case 0xD0: 
    105         if(this.Z == 0) {
    106           this.PC += this.immediateOperand()+1;
    107           if(this.PC > this.limit()) {
    108             this.PC -= this.limit()+1;
    109             this.PC += this.base();
    110           }
    111         } 
    112         else
    113           this.PC += 1;
    114         break;
    115 
    116       // INC: Increment the value of a byte 
    117       case 0xEE: 
    118         var location = _Memory.getByte(this.PC) + this.base();
    119         _Memory.setByte(this.directOperand() + 1, location);
    120         break;
    121 
    122       // SYS: System Call
    123       case 0xFF: 
    124         krnInterrupt(SYSCALL_IRQ, 0xFF);
    125         break;
    126 
    127     }
    128   }
    129 
    130   /* 
    131    * Gets operand from memory in location PC.
    132    */
    133   this.directOperand = function() {
    134     var location = _Memory.getByte(this.PC) + this.base();
    135     var value = _Memory.getByte(location);
    136     this.PC += 2;
    137     return value;
    138   }
    139 
    140   /* 
    141    * Gets operand as a constant in location PC
    142    */
    143   this.immediateOperand = function() {
    144     var value = _Memory.getByte(this.PC);
    145     this.PC += 1;
    146     return value;
    147   }
    148 
    149   /* Base is the lowest value PC can be. */
    150   this.base = function() {
    151     return _KernelCPUScheduler.running.base;
    152   }
    153 
    154   /* Limit is the highest value PC can be. */
    155   this.limit = function() {
    156     return _KernelCPUScheduler.running.limit;
    157   }
    158 
    159   /* 
    160    * Displays register values in interface.
    161    */
    162   this.output = function() {
    163     document.getElementById("pc_register").innerHTML = 
    164         pad(this.PC.toString(16),4).toUpperCase();
    165 
    166     document.getElementById("acc_register").innerHTML = 
    167         pad(this.ACC.toString(16),2).toUpperCase();
    168 
    169     document.getElementById("x_register").innerHTML = 
    170         pad(this.X.toString(16),2).toUpperCase();
    171 
    172     document.getElementById("y_register").innerHTML = 
    173         pad(this.Y.toString(16),2).toUpperCase();
    174 
    175     document.getElementById("z_register").innerHTML = 
    176         this.Z.toString(16);
    177   }
    178 }