old-computer-simulator

godot game
git clone git://git.evenfri.xyz/old-computer-simulator.git
Log | Files | Refs

computer_interface.cs (5119B)


      1 using Godot;
      2 using System;
      3 using static emulator;
      4 
      5 public partial class computer_interface : Node {
      6 
      7 const int INDEXES_BUTTON_DATA = 7;
      8 const int INDEXES_BUTTON_ADDR = 15;
      9 
     10 [Export] public Button[] buttons;
     11 [Export] public Sprite2D[] lamp_current_instruction;
     12 [Export] public Sprite2D[] lamp_addr;
     13 
     14 [Export] public Color lamp_on = Colors.Red;
     15 [Export] public Color lamp_off = Colors.DarkGray;
     16 
     17 [Export] public Button button_off_on;
     18 [Export] public Button button_stop;
     19 [Export] public Button button_run;
     20 [Export] public Button button_single_step;
     21 [Export] public Button button_examine;
     22 [Export] public Button button_examine_next;
     23 [Export] public Button button_deposit;
     24 [Export] public Button button_deposit_next;
     25 [Export] public Button button_reset;
     26 [Export] public Button button_clear;
     27 
     28 IntPtr _emu;
     29 ushort curr_addr;
     30 byte curr_instr;
     31 bool worked = false;
     32 
     33 public override void _Ready() {
     34   _emu = emu_create();
     35   
     36   int r = emu_load_program(_emu, "altair.bin");
     37   if (r != 0) {
     38     GD.Print("error to load program: altair.bin");
     39   }
     40   
     41 
     42   if (button_run != null) button_run.Pressed += run_pressed;
     43   if (button_stop != null) button_stop.Pressed += stop_pressed;
     44   if (button_single_step != null) button_single_step.Pressed += single_step_pressed;
     45   if (button_examine != null) button_examine.Pressed += examine_pressed;
     46   if (button_examine_next != null) button_examine_next.Pressed += examine_next_pressed;
     47   if (button_deposit != null) button_deposit.Pressed += deposit_pressed;
     48   if (button_deposit_next != null) button_deposit_next.Pressed += deposit_next_pressed;
     49   if (button_reset != null) button_reset.Pressed += reset_pressed;
     50   if (button_clear != null) button_clear.Pressed += clear_pressed;
     51 
     52   if (buttons != null) {
     53     for (int i = 0; i < buttons.Length; i++) {
     54       if (buttons[i] != null) {
     55         buttons[i].Pressed += bit_button_pressed;
     56       }
     57     }
     58   }
     59 
     60   update_lamps();
     61 }
     62 
     63 public override void _Notification(int what) {
     64   if (what == NotificationPredelete) {
     65     emu_destroy(_emu);
     66   }
     67 }
     68 
     69 public override void _Process(double delta) {
     70   if (!worked) return;
     71 
     72   int r = emu_step(_emu);
     73   if (r > 0) {
     74     worked = false;
     75     return;
     76   }
     77 
     78   curr_addr = (ushort)emu_get_pc(_emu);
     79   curr_instr = emu_mem_read(_emu, curr_addr);
     80 
     81   update_lamps();
     82 
     83   byte reg_a = emu_get_reg(_emu, 0b111);
     84   byte reg_b = emu_get_reg(_emu, 0b000);
     85   byte reg_c = emu_get_reg(_emu, 0b001);
     86   byte reg_d = emu_get_reg(_emu, 0b010);
     87   GD.Print($"opcode=0x{curr_instr:X2}; pc=0x{curr_addr:X4}; a=0x{reg_a:X2}; b=0x{reg_b:X2}; c=0x{reg_c:X2}; d=0x{reg_d:X2}");
     88 }
     89 
     90 void update_lamps() {
     91   update_data_lamps(curr_instr);
     92   update_addr_lamps(curr_addr);
     93 }
     94 
     95 ushort read_switches_addr() {
     96   byte b0 = assem_byte(buttons, 0, 8);
     97   byte b1 = assem_byte(buttons, 8, 8);
     98   return (ushort)((b1 << 8) | b0);
     99 }
    100 
    101 byte read_switches_data() {
    102   return assem_byte(buttons, 0, INDEXES_BUTTON_DATA + 1);
    103 }
    104 
    105 void bit_button_pressed() {
    106   update_lamps();
    107 }
    108 
    109 void run_pressed() {
    110   worked = true;
    111 }
    112 
    113 void stop_pressed() {
    114   worked = false;
    115 }
    116 
    117 void single_step_pressed() {
    118   worked = false;
    119   emu_step(_emu);
    120   curr_addr = (ushort)emu_get_pc(_emu);
    121   curr_instr = emu_mem_read(_emu, curr_addr);
    122   update_lamps();
    123 }
    124 
    125 void examine_pressed() {
    126   worked = false;
    127   curr_addr = read_switches_addr();
    128   emu_set_pc(_emu, curr_addr);
    129   curr_instr = emu_mem_read(_emu, curr_addr);
    130   update_lamps();
    131 
    132   GD.Print($"Examine at 0x{curr_addr:X4}: 0x{curr_instr:X2}");
    133 }
    134 
    135 void examine_next_pressed() {
    136   worked = false;
    137   curr_addr++;
    138   emu_set_pc(_emu, curr_addr);
    139   curr_instr = emu_mem_read(_emu, curr_addr);
    140   update_lamps();
    141 
    142   GD.Print($"Examine Next at 0x{curr_addr:X4}: 0x{curr_instr:X2}");
    143 }
    144 
    145 void deposit_pressed() {
    146   worked = false;
    147   byte val = read_switches_data();
    148   
    149   emu_mem_write(_emu, curr_addr, val);
    150   curr_instr = val;
    151   update_lamps();
    152 
    153   GD.Print($"Deposit 0x{val:X2} at 0x{curr_addr:X4}");
    154 }
    155 
    156 void deposit_next_pressed() {
    157   worked = false;
    158   
    159   curr_addr++;
    160   emu_set_pc(_emu, curr_addr);
    161   
    162   byte val = read_switches_data();
    163   emu_mem_write(_emu, curr_addr, val);
    164   curr_instr = val;
    165   update_lamps();
    166 
    167   GD.Print($"Deposit Next 0x{val:X2} at 0x{curr_addr:X4}");
    168 }
    169 
    170 void reset_pressed() {
    171   worked = false;
    172   emu_set_pc(_emu, 0);
    173   curr_addr = 0;
    174   curr_instr = emu_mem_read(_emu, curr_addr);
    175   update_lamps();
    176 }
    177 
    178 void clear_pressed() {
    179   update_lamps();
    180 }
    181 
    182 void update_data_lamps(byte value) {
    183   for (int i = 0; i < 8 && i < lamp_current_instruction.Length; i++) {
    184     bool is_bit_set = (value & (1 << i)) != 0;
    185     lamp_current_instruction[i].SelfModulate = is_bit_set ? lamp_on : lamp_off;
    186   }
    187 }
    188 
    189 void update_addr_lamps(ushort value) {
    190   for (int i = 0; i < 16 && i < lamp_addr.Length; i++) {
    191     bool is_bit_set = (value & (1 << i)) != 0;
    192     lamp_addr[i].SelfModulate = is_bit_set ? lamp_on : lamp_off;
    193   }
    194 }
    195 
    196 byte assem_byte(Button[] btns, int offset, int count = 8) {
    197   byte r = 0;
    198   if (btns == null) return r;
    199 
    200   for (int i = 0; i < count && i < 8; i++) {
    201     int index = offset + i;
    202     if (index < btns.Length && btns[index] != null && btns[index].ButtonPressed) {
    203       r |= (byte)(1 << i);
    204     }
    205   }
    206   return r;
    207 }
    208 
    209 }