// Parallel Computing // // Processor // // Author Matthew Caryl // Created 2.2.97 // // HOW TO DO THE INTERUPT SECTION package Parallel; import java.awt.Graphics; import java.awt.Color; import java.io.InputStream; import java.net.URL; import ADT.Random; public class Processor { // // Public interface // public static boolean initialiseRom(Assembler A) { assembler = A; return assembler.compile(rom); } public Processor(byte X, byte Y, Random R) { x = X; y = Y; random = R; power = new Power[4]; power_outlets = new Power[4]; in_comm = new CommunicationQueue[5]; out_comm = new CommunicationQueue[5]; for (int i = 5 - 1; i >= 0; i--) out_comm[i] = new CommunicationQueue(); in_comm_signal = new Wire[5]; out_comm_signal = new Wire[5]; for (int i = 5 - 1; i >= 0; i--) out_comm_signal[i] = new Wire(); state(ON); register[PROGRAM_COUNTER] = ROM_START; } public void setPower(int d, Power p) { Power old = power[d]; power[d] = p; for (int i = power_outlets.length - 1; i >= 0; i--) if (power_outlets[i] == old) { power_outlets[i] = p; return; } } public Power getPower(int d) { return power[d]; } public CommunicationQueue getOutComm(int d) { return out_comm[d]; } public Wire getOutCommSignal(int d) { return out_comm_signal[d]; } public CommunicationQueue getInComm(int d) { return in_comm[d]; } public Wire getInCommSignal(int d) { return in_comm_signal[d]; } public void setInComm(int d, CommunicationQueue q) { in_comm[d] = q; } public void setInCommSignal(int d, Wire w) { in_comm_signal[d] = w; } public void tick(int c) { int p = collectPower(); if (p == 0) { if (!stacking) stack(); return; } else if (stacking) unstack(); timer -= c; if (timer > 0) return; c = -timer; timer = 0; for (int i = c; i > 0; i--) tick(); distributePower(p); } public void update(Graphics g, int left, int top, int width, int height) { if (old_state != color_state) { draw(g, left, top, width, height); old_state = color_state; } } public void draw(Graphics g, int left, int top, int width, int height) { int edgeEW = width / 4; int gapEW = width / 8; int edgeNS = height / 4; int gapNS = width / 8; g.setColor(color_state); g.fillRect(left + edgeEW, top + edgeNS, width - 2 * edgeEW, height - 2 * edgeNS); if (edgeEW >= 8 && edgeNS >= 8) { g.setColor(Color.white); g.drawLine(left + edgeEW + gapEW, top, left + edgeEW + gapEW, top + edgeNS - 1); g.drawLine(left + width, top + edgeNS + gapNS, left + width - edgeEW, top + edgeNS + gapNS); g.drawLine(left + width - edgeEW - gapEW, top + height, left + width - edgeEW - gapEW, top + height - edgeNS); g.drawLine(left, top + height - edgeNS - gapNS, left + edgeEW - 1, top + height - edgeNS - gapNS); g.setColor(Color.white); g.drawLine(left + width - edgeEW - gapEW, top, left + width - edgeEW - gapEW, top + edgeNS - 1); g.drawLine(left + width, top + height - edgeNS - gapNS, left + width - edgeEW, top + height - edgeNS - gapNS); g.drawLine(left + edgeEW + gapEW, top + height, left + edgeEW + gapEW, top + height - edgeNS); g.drawLine(left, top + edgeNS + gapNS, left + edgeEW - 1, top + edgeNS + gapNS); g.setColor(Color.white); g.drawLine(left + 2 * edgeEW, top, left + 2 * edgeEW, top + edgeNS - 1); g.drawLine(left + width, top + 2 * edgeNS, left + width - edgeEW, top + 2 * edgeNS); g.drawLine(left + 2 * edgeEW, top + height, left + 2 * edgeEW, top + height - edgeNS); g.drawLine(left, top + 2 * edgeNS, left + edgeEW - 1, top + 2 * edgeNS); } } public boolean mouseDown(int left, int top, int width, int height, int x, int y) { return false; } public int maxWidth() { return 512; } public int maxHeight() { return 512; } public int minWidth() { return 1; } public int minHeight() { return 1; } // // Private interface - meta-processor // private static final Color OFF = Color.black; private static final Color ON = Color.gray; private Color color_state = OFF; private Color old_state; private boolean stacking = false; private Color stacked_state; private short processor_color; private short x, y; private int timer = 0; private void state(Color c) { color_state = c; } private void stack() { stacked_state = color_state; color_state = OFF; stacking = true; } private void unstack() { color_state = stacked_state; stacking = false; } // // Private interface - main processor // // connections private Power[] power; private byte internal_power = 0; private Power[] power_outlets; private CommunicationQueue[] out_comm; private Wire[] out_comm_signal; private CommunicationQueue[] in_comm; private Wire[] in_comm_signal; private Random random; // registers private static final short PROGRAM_COUNTER = 7; private short[] register = new short[8]; private boolean zero_flag; private boolean carry_flag; // instruction set private static final short MOV_SOURCE_CONDITIONAL = 0; private static final short MOV_IMMEDIATE = -16; private static final short LDR_SOURCE_CONDITIONAL = 1; private static final short LDR_IMMEDIATE = -15; private static final short STR_SOURCE_CONDITIONAL = 2; private static final short STR_IMMEDIATE = -14; private static final short AND_SOURCE_CONDITIONAL = 3; private static final short AND_IMMEDIATE = -13; private static final short ORR_SOURCE_CONDITIONAL = 4; private static final short ORR_IMMEDIATE = -12; private static final short EOR_SOURCE_CONDITIONAL = 5; private static final short EOR_IMMEDIATE = -11; private static final short ADD_SOURCE_CONDITIONAL = 6; private static final short ADD_IMMEDIATE = -10; private static final short ADC_SOURCE_CONDITIONAL = 7; private static final short ADC_IMMEDIATE = -9; private static final short SUB_SOURCE_CONDITIONAL = 8; private static final short SUB_IMMEDIATE = -8; private static final short SBC_SOURCE_CONDITIONAL = 9; private static final short SBC_IMMEDIATE = -7; private static final short MLT_SOURCE_CONDITIONAL = 10; private static final short MLT_IMMEDIATE = -6; private static final short SHL_SOURCE_CONDITIONAL = 11; private static final short SHL_IMMEDIATE = -5; private static final short SHR_SOURCE_CONDITIONAL = 12; private static final short SHR_IMMEDIATE = -4; private static final short ROL_SOURCE_CONDITIONAL = 13; private static final short ROL_IMMEDIATE = -3; private static final short ROR_SOURCE_CONDITIONAL = 14; private static final short ROR_IMMEDIATE = -2; private static final short ADD_IMMEDIATE_CONDITIONAL = 15; private static final short SUB_IMMEDIATE_CONDITIONAL = -1; private boolean usingPower(Power p) { for (int i = power_outlets.length - 1; i >= 0; i--) if (power_outlets[i] == p) return true; return false; } private void usePower(Power p, boolean toUse) { if (toUse) { if (!usingPower(p)) { Power[] ps = new Power[power_outlets.length + 1]; for (int i = power_outlets.length - 1; i >= 0; i--) ps[i] = power_outlets[i]; ps[power_outlets.length] = p; power_outlets = ps; } } else { if (usingPower(p)) { Power[] ps = new Power[power_outlets.length - 1]; for (int i = power_outlets.length - 1, j = 0; i >= 0; i--) if (power_outlets[i] != p) ps[j++] = power_outlets[i]; power_outlets = ps; } } } private int collectPower() { return internal_power + power[0].drain() + power[1].drain() + power[2].drain() + power[3].drain(); } private void distributePower(int p) { int a = p / power_outlets.length; switch (power_outlets.length) { case 4: power_outlets[3].charge((byte) a); case 3: power_outlets[2].charge((byte) a); case 2: power_outlets[1].charge((byte) a); case 1: power_outlets[0].charge((byte) a); case 0: break; default: System.err.println("report to programmer - distribute power"); break; } internal_power = (byte) (p - power_outlets.length * a); } // processor cycle private void tick() { // read instruction and break into components short instruction = read(register[PROGRAM_COUNTER]); short conditional = (short) (instruction & 15); short positional8 = (short) (instruction & 255); instruction >>= 4; short positional4 = (short) (instruction & 15); short bit = (short) (instruction & 1); instruction >>= 1; short secondary = (short) (instruction & 7); instruction >>= 3; short dominant = (short) (instruction & 7); instruction >>= 3; short opcode = instruction; short old_value; register[PROGRAM_COUNTER]++; if ((opcode & (1 << 4)) == 0) { if (opcode == ADD_IMMEDIATE_CONDITIONAL) { old_value = register[dominant]; register[dominant] &= positional4; carry_flag = register[dominant] < old_value; } else { // source conditional addressing mode switch (opcode) { case MOV_SOURCE_CONDITIONAL: register[dominant] = register[secondary]; carry_flag = false; break; case LDR_SOURCE_CONDITIONAL: register[dominant] = read(register[secondary]); carry_flag = false; break; case STR_SOURCE_CONDITIONAL: write(register[secondary], register[dominant]); carry_flag = false; break; case AND_SOURCE_CONDITIONAL: register[dominant] &= register[secondary]; carry_flag = false; break; case ORR_SOURCE_CONDITIONAL: register[dominant] |= register[secondary]; carry_flag = false; break; case EOR_SOURCE_CONDITIONAL: register[dominant] ^= register[secondary]; carry_flag = false; break; case ADD_SOURCE_CONDITIONAL: old_value = register[dominant]; register[dominant] += register[secondary]; carry_flag = register[dominant] < old_value; break; case ADC_SOURCE_CONDITIONAL: old_value = register[dominant]; register[dominant] += register[secondary] + (carry_flag ? 1 : 0); carry_flag = register[dominant] < old_value; break; case SUB_SOURCE_CONDITIONAL: old_value = register[dominant]; register[dominant] -= register[secondary]; carry_flag = register[dominant] > old_value; break; case SBC_SOURCE_CONDITIONAL: old_value = register[dominant]; register[dominant] -= register[secondary] + (carry_flag ? 1 : 0); carry_flag = register[dominant] > old_value; break; case MLT_SOURCE_CONDITIONAL: register[dominant] *= register[secondary]; carry_flag = false; break; case SHL_SOURCE_CONDITIONAL: if (positional8 > 0 && positional8 <= 16) carry_flag = (register[dominant] & (1 << (16 - positional8))) != 0; else carry_flag = false; register[dominant] <<= register[secondary]; break; case SHR_SOURCE_CONDITIONAL: if (positional8 > 0 && positional8 <= 16) carry_flag = (register[dominant] & (1 << (positional8 - 1))) != 0; else carry_flag = false; register[dominant] >>= register[secondary]; break; case ROL_SOURCE_CONDITIONAL: register[dominant] = (short) (register[dominant] << (register[secondary] & 15) | register[dominant] >> 16 - (register[secondary] & 15)); carry_flag = false; break; case ROR_SOURCE_CONDITIONAL: register[dominant] = (short) (register[dominant] >> (register[secondary] & 15) | register[dominant] << 16 - (register[secondary] & 15)); carry_flag = false; break; } zero_flag = (register[dominant] == 0); } } else { if (opcode == SUB_IMMEDIATE_CONDITIONAL) { old_value = register[dominant]; register[dominant] -= positional8; carry_flag = register[dominant] > old_value; zero_flag = (register[dominant] == 0); } else { // immediate addressing mode switch (opcode) { case MOV_IMMEDIATE: register[dominant] = positional8; carry_flag = false; break; case LDR_IMMEDIATE: register[dominant] = read(positional8); carry_flag = false; break; case STR_IMMEDIATE: write(positional8, register[dominant]); carry_flag = false; break; case AND_IMMEDIATE: register[dominant] &= positional8; carry_flag = false; break; case ORR_IMMEDIATE: register[dominant] |= positional8; carry_flag = false; break; case EOR_IMMEDIATE: register[dominant] ^= positional8; carry_flag = false; break; case ADD_IMMEDIATE: old_value = register[dominant]; register[dominant] += positional8; carry_flag = register[dominant] < old_value; break; case ADC_IMMEDIATE: old_value = register[dominant]; register[dominant] += positional8 + (carry_flag ? 1 : 0); carry_flag = register[dominant] < old_value; break; case SUB_IMMEDIATE: old_value = register[dominant]; register[dominant] -= positional8; carry_flag = register[dominant] > old_value; break; case SBC_IMMEDIATE: old_value = register[dominant]; register[dominant] -= positional8 + (carry_flag ? 1 : 0); carry_flag = register[dominant] > old_value; break; case MLT_IMMEDIATE: register[dominant] *= positional8; break; case SHL_IMMEDIATE: if (positional8 > 0 && positional8 <= 16) carry_flag = (register[dominant] & (1 << (16 - positional8))) != 0; else carry_flag = false; register[dominant] <<= positional8; break; case SHR_IMMEDIATE: if (positional8 > 0 && positional8 <= 16) carry_flag = (register[dominant] & (1 << (positional8 - 1))) != 0; else carry_flag = false; register[dominant] >>= positional8; break; case ROL_IMMEDIATE: register[dominant] = (short) (register[dominant] << (positional8 & 15) | register[dominant] >> 16 - (positional8 & 15)); carry_flag = false; break; case ROR_IMMEDIATE: register[dominant] = (short) (register[dominant] >> (positional8 & 15) | register[dominant] << 16 - (positional8 & 15)); carry_flag = false; break; } zero_flag = (register[dominant] == 0); } } } // // Private interface - memory system and mapped io // // assebler private static Assembler assembler; // memory sizes private static final short ROM_SIZE = 512; private static final short RAM_SIZE = 1536; private static final short ROM_BASE = 0; private static final short RAM_BASE = (short) (ROM_BASE + ROM_SIZE); private static final short ROM_TOP = (short) (RAM_BASE - 1); private static final short RAM_TOP = (short) (RAM_BASE + RAM_SIZE - 1); // memory allocation private static short[] rom = new short[ROM_SIZE]; private short[] ram = new short[RAM_SIZE]; // io variables private static final Color[] color_table = new Color[64]; private static final Color[] gray_table = new Color[64]; private static final short COLOR_MASK = 63; private static final short COLOR_GRAY_MASK = 64; // mapped io addresses private static final short COLOR_IO = 0; private static final short X_POSITION_IO = 1; private static final short Y_POSITION_IO = 2; private static final short RANDOM_GENERATOR_IO = 3; private static final short POWER_NORTH_IN_IO = 4; private static final short POWER_EAST_IN_IO = 5; private static final short POWER_SOUTH_IN_IO = 6; private static final short POWER_WEST_IN_IO = 7; private static final short POWER_NORTH_OUT_IO = 8; private static final short POWER_EAST_OUT_IO = 9; private static final short POWER_SOUTH_OUT_IO = 10; private static final short POWER_WEST_OUT_IO = 11; private static final short POWER_INTERNAL_IO = 12; private static final short COMM_OUT_NORTH_IO = 13; private static final short COMM_OUT_EAST_IO = 14; private static final short COMM_OUT_SOUTH_IO = 15; private static final short COMM_OUT_WEST_IO = 16; private static final short COMM_OUT_UP_IO = 17; private static final short COMM_OUT_FREE_NORTH_IO = 18; private static final short COMM_OUT_FREE_EAST_IO = 19; private static final short COMM_OUT_FREE_SOUTH_IO = 20; private static final short COMM_OUT_FREE_WEST_IO = 21; private static final short COMM_OUT_FREE_UP_IO = 22; private static final short COMM_SIGNAL_OUT_NORTH_IO = 23; private static final short COMM_SIGNAL_OUT_EAST_IO = 24; private static final short COMM_SIGNAL_OUT_SOUTH_IO = 25; private static final short COMM_SIGNAL_OUT_WEST_IO = 26; private static final short COMM_SIGNAL_OUT_UP_IO = 27; private static final short COMM_IN_NORTH_IO = 28; private static final short COMM_IN_EAST_IO = 29; private static final short COMM_IN_SOUTH_IO = 30; private static final short COMM_IN_WEST_IO = 31; private static final short COMM_IN_UP_IO = 32; private static final short COMM_IN_USED_NORTH_IO = 33; private static final short COMM_IN_USED_EAST_IO = 34; private static final short COMM_IN_USED_SOUTH_IO = 35; private static final short COMM_IN_USED_WEST_IO = 36; private static final short COMM_IN_USED_UP_IO = 37; private static final short COMM_SIGNAL_IN_NORTH_IO = 38; private static final short COMM_SIGNAL_IN_EAST_IO = 39; private static final short COMM_SIGNAL_IN_SOUTH_IO = 40; private static final short COMM_SIGNAL_IN_WEST_IO = 41; private static final short COMM_SIGNAL_IN_UP_IO = 42; private static final short TIMER_IO = 43; private static final short INTERUPT_IO = 44; private static final short REGISTER_A_IO = 45; private static final short REGISTER_B_IO = 46; private static final short REGISTER_C_IO = 47; private static final short REGISTER_D_IO = 48; private static final short REGISTER_JK_IO = 49; private static final short REGISTER_RT_IO = 50; private static final short REGISTER_SP_IO = 51; private static final short REGISTER_PC_IO = 52; private static final short CARRY_FLAG_IO = 53; private static final short ZERO_FLAG_IO = 54; private static final short OS_REGISTER_A_IO = 55; private static final short OS_REGISTER_B_IO = 56; private static final short OS_REGISTER_C_IO = 57; private static final short OS_REGISTER_D_IO = 58; private static final short OS_REGISTER_JK_IO = 59; private static final short OS_REGISTER_RT_IO = 60; private static final short OS_REGISTER_SP_IO = 61; private static final short OS_REGISTER_PC_IO = 62; private static final short OS_CARRY_FLAG_IO = 63; private static final short OS_ZERO_FLAG_IO = 64; private static final short ROM_START = 65; // read memory location private short read(int l) { l &= RAM_TOP; if (l < RAM_BASE) { if (l >= ROM_START) return rom[l]; else { switch (l) { case COLOR_IO: return processor_color; case X_POSITION_IO: return x; case Y_POSITION_IO: return y; case RANDOM_GENERATOR_IO: return (short) random.range(65536); case POWER_NORTH_IN_IO: return power[0].check(); case POWER_EAST_IN_IO: return power[1].check(); case POWER_SOUTH_IN_IO: return power[2].check(); case POWER_WEST_IN_IO: return power[3].check(); case POWER_NORTH_OUT_IO: return (short) (usingPower(power[0]) ? 1 : 0); case POWER_EAST_OUT_IO: return (short) (usingPower(power[1]) ? 1 : 0); case POWER_SOUTH_OUT_IO: return (short) (usingPower(power[2]) ? 1 : 0); case POWER_WEST_OUT_IO: return (short) (usingPower(power[3]) ? 1 : 0); case POWER_INTERNAL_IO: return internal_power; case COMM_OUT_NORTH_IO: return 0; case COMM_OUT_EAST_IO: return 0; case COMM_OUT_SOUTH_IO: return 0; case COMM_OUT_WEST_IO: return 0; case COMM_OUT_UP_IO: return 0; case COMM_OUT_FREE_NORTH_IO: return out_comm[0].freeSpace(); case COMM_OUT_FREE_EAST_IO: return out_comm[1].freeSpace(); case COMM_OUT_FREE_SOUTH_IO: return out_comm[2].freeSpace(); case COMM_OUT_FREE_WEST_IO: return out_comm[3].freeSpace(); case COMM_OUT_FREE_UP_IO: return out_comm[4].freeSpace(); case COMM_SIGNAL_OUT_NORTH_IO: return (short) (out_comm_signal[0].read() ? 1 : 0); case COMM_SIGNAL_OUT_EAST_IO: return (short) (out_comm_signal[1].read() ? 1 : 0); case COMM_SIGNAL_OUT_SOUTH_IO: return (short) (out_comm_signal[2].read() ? 1 : 0); case COMM_SIGNAL_OUT_WEST_IO: return (short) (out_comm_signal[3].read() ? 1 : 0); case COMM_SIGNAL_OUT_UP_IO: return (short) (out_comm_signal[4].read() ? 1 : 0); case COMM_IN_NORTH_IO: return in_comm[0].dequeue(); case COMM_IN_EAST_IO: return in_comm[1].dequeue(); case COMM_IN_SOUTH_IO: return in_comm[2].dequeue(); case COMM_IN_WEST_IO: return in_comm[3].dequeue(); case COMM_IN_UP_IO: return in_comm[4].dequeue(); case COMM_IN_USED_NORTH_IO: return in_comm[0].usedSpace(); case COMM_IN_USED_EAST_IO: return in_comm[1].usedSpace(); case COMM_IN_USED_SOUTH_IO: return in_comm[2].usedSpace(); case COMM_IN_USED_WEST_IO: return in_comm[3].usedSpace(); case COMM_IN_USED_UP_IO: return in_comm[4].usedSpace(); case COMM_SIGNAL_IN_NORTH_IO: return (short) (in_comm_signal[0].read() ? 1 : 0); case COMM_SIGNAL_IN_EAST_IO: return (short) (in_comm_signal[1].read() ? 1 : 0); case COMM_SIGNAL_IN_SOUTH_IO: return (short) (in_comm_signal[2].read() ? 1 : 0); case COMM_SIGNAL_IN_WEST_IO: return (short) (in_comm_signal[3].read() ? 1 : 0); case COMM_SIGNAL_IN_UP_IO: return (short) (in_comm_signal[4].read() ? 1 : 0); default: System.err.println("report to programmer - read"); return 0; } } } else return ram[l - RAM_BASE]; } // write memory location private void write(int l, short v) { l &= RAM_TOP; if (l < RAM_BASE) { if (l >= ROM_START) return; // only memory mapped io can be written to else { switch (l) { case COLOR_IO: processor_color = v; if ((processor_color & COLOR_GRAY_MASK) == 0) state(color_table[(short) (processor_color & COLOR_MASK)]); else state(gray_table[(short) (processor_color & COLOR_MASK)]); return; case X_POSITION_IO: System.err.println("assembly code error X_POSITION_IO"); return; case Y_POSITION_IO: System.err.println("assembly code error Y_POSITION_IO"); return; case RANDOM_GENERATOR_IO: System.err.println("assembly code error RANDOM_GENERATOR_IO"); return; case POWER_NORTH_IN_IO: System.err.println("assembly code error POWER_NORTH_IN_IO"); return; case POWER_EAST_IN_IO: System.err.println("assembly code error POWER_EAST_IN_IO"); return; case POWER_SOUTH_IN_IO: System.err.println("assembly code error POWER_SOUTH_IN_IO"); return; case POWER_WEST_IN_IO: System.err.println("assembly code error POWER_WEST_IN_IO"); return; case POWER_NORTH_OUT_IO: usePower(power[0], v != 0); return; case POWER_EAST_OUT_IO: usePower(power[1], v != 0); return; case POWER_SOUTH_OUT_IO: usePower(power[2], v != 0); return; case POWER_WEST_OUT_IO: usePower(power[3], v != 0); return; case POWER_INTERNAL_IO: return; case COMM_OUT_NORTH_IO: out_comm[0].enqueue(v); return; case COMM_OUT_EAST_IO: out_comm[1].enqueue(v); return; case COMM_OUT_SOUTH_IO: out_comm[2].enqueue(v); return; case COMM_OUT_WEST_IO: out_comm[3].enqueue(v); return; case COMM_OUT_UP_IO: out_comm[4].enqueue(v); return; case COMM_OUT_FREE_NORTH_IO: System.err.println("assembly code error COMM_OUT_FREE_NORTH_IO"); return; case COMM_OUT_FREE_EAST_IO: System.err.println("assembly code error COMM_OUT_FREE_EAST_IO"); return; case COMM_OUT_FREE_SOUTH_IO: System.err.println("assembly code error COMM_OUT_FREE_SOUTH_IO"); return; case COMM_OUT_FREE_WEST_IO: System.err.println("assembly code error COMM_OUT_FREE_WEST_IO"); return; case COMM_OUT_FREE_UP_IO: System.err.println("assembly code error COMM_OUT_FREE_UP_IO"); return; case COMM_SIGNAL_OUT_NORTH_IO: out_comm_signal[0].write(v != 0); case COMM_SIGNAL_OUT_EAST_IO: out_comm_signal[1].write(v != 0); case COMM_SIGNAL_OUT_SOUTH_IO: out_comm_signal[2].write(v != 0); case COMM_SIGNAL_OUT_WEST_IO: out_comm_signal[3].write(v != 0); case COMM_SIGNAL_OUT_UP_IO: out_comm_signal[4].write(v != 0); case COMM_IN_NORTH_IO: System.err.println("assembly code error COMM_IN_NORTH_IO"); return; case COMM_IN_EAST_IO: System.err.println("assembly code error COMM_IN_EAST_IO"); return; case COMM_IN_SOUTH_IO: System.err.println("assembly code error COMM_IN_SOUTH_IO"); return; case COMM_IN_WEST_IO: System.err.println("assembly code error COMM_IN_WEST_IO"); return; case COMM_IN_UP_IO: System.err.println("assembly code error COMM_IN_UP_IO"); return; case COMM_IN_USED_NORTH_IO: System.err.println("assembly code error COMM_IN_USED_NORTH_IO"); return; case COMM_IN_USED_EAST_IO: System.err.println("assembly code error COMM_IN_USED_EAST_IO"); return; case COMM_IN_USED_SOUTH_IO: System.err.println("assembly code error COMM_IN_USED_SOUTH_IO"); return; case COMM_IN_USED_WEST_IO: System.err.println("assembly code error COMM_IN_USED_WEST_IO"); return; case COMM_IN_USED_UP_IO: System.err.println("assembly code error COMM_IN_USED_UP_IO"); return; case COMM_SIGNAL_IN_NORTH_IO: in_comm_signal[0].write(v != 0); case COMM_SIGNAL_IN_EAST_IO: in_comm_signal[1].write(v != 0); case COMM_SIGNAL_IN_SOUTH_IO: in_comm_signal[2].write(v != 0); case COMM_SIGNAL_IN_WEST_IO: in_comm_signal[3].write(v != 0); case COMM_SIGNAL_IN_UP_IO: in_comm_signal[4].write(v != 0); default: System.err.println("report to programmer - read"); return; } } } else ram[l - RAM_BASE] = v; } // initialise rom static { for (int red = 3, c = 63; red >= 0; red--) for (int green = 3; green >= 0; green--) for (int blue = 3; blue >= 0; blue--) color_table[c--] = new Color(64 * red, 64 * green, 64 * blue); for (int gray = 63; gray >= 0; gray--) gray_table[gray] = new Color(4 * gray, 4 * gray, 4 * gray); } }