public void write_word(int offset) { FileStream fs = File.OpenWrite(AGC_file); if (is_ErType) { fs.Seek(b_adress + offset, SeekOrigin.Begin); temp = new sWord(MEM_ARRAY[offset]); byte[] tmp = temp.getWord(); Array.Reverse(tmp); fs.Write(tmp, 0, 16); } fs.Close(); fs.Dispose(); }
/// <summary> /// <para>Constructor for BANK.</para> /// <para>size : number of words in the bank.</para> /// <para>E-B is 256 - F-B is 1024</para> /// </summary> /// <param name="type">1-ERASABLE 0-FIXED</param> /// <param name="id">Register bank ID</param> /// <param name="SB">FEB value if applicable</param> /// <param name="file">The binary file to read/write.</param> public BANK(bool type, short id, int SB, String file) { is_ErType = type; AGC_file = file; FEB = SB; bank_id = id; byte[] bytestr = new byte[16]; FileStream fs = File.Open (AGC_file, FileMode.OpenOrCreate); if (is_ErType) { size = 256; } else { size = 1024; } base_address (); MEM_ARRAY = new short[size]; int j = 0; for (int i = 0; i < size; i++) { if (b_adress + j + 16 <= fs.Length) { fs.Seek (b_adress + j, SeekOrigin.Begin); fs.Read (bytestr, 0, 16); Array.Reverse (bytestr); //reversing the array so it's in good order temp = new sWord (bytestr); MEM_ARRAY [i] = temp.getHex (); j += 16; } else { //if memory emplacement is empty in file (shouldn't), replace by zero. MEM_ARRAY [i] = 0x0; } } if (fs != null) { fs.Close (); fs.Dispose (); } }
public int set_sword(short offset_index, sWord word) { if (is_ErType | compiling) { MEM_ARRAY[offset_index] = word.getHex(); return 0; } else { return 1; } }
//file operation /// <summary> /// write the bank to the binary output file /// </summary> public void write_bank() { if (is_ErType | compiling) { //only erasable bank is writable FileStream fs = File.OpenWrite (AGC_file); int j = 0; for (int i = 0; i < size; i++) { fs.Seek (b_adress + j, SeekOrigin.Begin); temp = new sWord (MEM_ARRAY [i]); byte[] tmp = temp.getWord (); Array.Reverse (tmp); fs.Write (tmp, 0, 16); j += 16; } fs.Close (); fs.Dispose (); } }
/// <summary> /// Compute the operand from the line /// </summary> /// <param name="item">the current line</param> /// <returns>error index</returns> private int ResolveOperand(String[] item) { short adress = 0; int modifier = 0; try { adress = (short)Int16.Parse(item[2], System.Globalization.NumberStyles.HexNumber); } catch { int val = 0; if (labels.TryGetValue(item[2], out val)) { sWord adr = new sWord(); if (val >= 0x1000) { adress = (short)(val - 0x1000 + 0x400); } else { if (val >= 0x400 && val <= 0x7FF) { adr = new sWord((short)val); adress = (short)(adr.getVal(0, 7) + 0x300); } else { adress = (short)val; } } } else if (fixedValue.registers.TryGetValue(item[2], out val)) { adress = (short)val; } else if(Int32.TryParse(item[2], out modifier)) { adress = (short)(bank_index + modifier); } else { return -2; } } return (short)testModifier((int)adress, item); }
/// <summary> /// Process the 2FCADR Pre-processor word /// </summary> /// <param name="item">the current line</param> /// <returns>error index</returns> private int toFCADR(string[] item, bool mode) { sWord adr = null; try { adr = new sWord((short)Int16.Parse(item[2], System.Globalization.NumberStyles.HexNumber)); } catch { int val = 0; if (labels.TryGetValue(item[2], out val)) { adr = new sWord((short)val); } else { bank_index += 2; unresolvedFCAdrCount += 1; return -6; } } if (mode) { int tad = adr.getVal(10, 14); if (tad < 4) { Bank.set_hex((short)bank_index, (short)(adr.getVal(10, 14))); } else { Bank.set_hex((short)bank_index, (short)(adr.getVal(10, 14) - 4)); } bank_index++; Bank.set_hex((short)bank_index, (short)(adr.getVal(0, 9))); bank_index++; } if (unresolvedFCAdrCount > 0) { return -6; } return 0; }
private void MCT() { while (running) { clock.c_start(); cycle_count = 0; int prev_cycle = 0; exec_opc(false); B = b.get_word(Z.getHex()); B.setWord(B.hexToByte()); Z.setHex((ushort)(Z.getHex() + 1)); while (cycle_count < 13) { cycle_count += clock.get_cycle(); if (cycle_count != prev_cycle) { Console.WriteLine("Cycle n° : {0}", cycle_count); } prev_cycle = cycle_count; } } Console.WriteLine("AGC halted"); }
public int resolve_opcode(String[] items) { ushort opcode = 0; ushort adress = 0; ushort QC = 0; switch(items[1]) { case "TC": opcode = 0x0 * 4096;break; case "AD": opcode = 0x6 * 4096;break; case "MASK": opcode = 0x7 * 4096; break; default: return 0; } adress = (ushort)Int16.Parse(items[2], System.Globalization.NumberStyles.HexNumber); sWord ad = new sWord((ushort)(opcode + adress), true); B.set_sword((ushort)bank_index, ad); B.write_bank(); bank_index += 1; return 0; }
/// <summary> /// AGC builder placeholder /// </summary> public AGC(String file) { A = new sWord(0x0, false); Z = new sWord(0x0, false); Q = new sWord(0x0, false); L = new sWord(0x0, false); G = new sWord(0x0, false); X = new sWord(0x0, false); Y = new sWord(0x0, false); U = new sWord(0x0, false); B = new sWord(0x0, false); FEB = new sWord(0x0, false); FB = 0; EB = 0; S = 0; SQ = 0; running = false; clock = new CLOCK(); b = null; cycle_count = 0; AGC_File = file; }
/// <summary> /// start (run) a previous AGC intialized (powered up) /// </summary> public void start() { if(!running) { clock.c_start(); cycle_count = 0; running = true; b = new BANK(false, FB, FEB.getHex(), AGC_File); Console.WriteLine("AGC Started"); B = b.get_word(Z.getHex()); B.setWord(B.hexToByte()); Z.setHex((ushort)(Z.getHex() + 1)); MCT(); } else { Console.WriteLine("AGC Halted."); } }
private void stOpcode(sWord S) { int val = 0; if (fFixed) { val = fFixed_switch(S.getInt()); } else { val = S.getInt(); } switch (RegBank.get_word(11)) { case 0: if (val > 6 | PB.getId()!=0 | PB.isErasable()==false) { TC(val + index); Console.WriteLine("TC {0:X4}", val + index); } else { switch (val) { case 0: Console.WriteLine("XXALQ"); break; case 1: Console.WriteLine("XLQ"); break; case 2: Console.WriteLine("RETURN"); break; case 3: Console.WriteLine("RELINT"); break; case 4: Console.WriteLine("INHINT"); break; case 5: TC(val + index); Console.WriteLine("TC {0:X4}", val + index); break; case 6: extra = true; Console.WriteLine("EXTEND"); break; } } index = 0; break; case 1: if (QC == 0) { Console.WriteLine("CCS {0:X4}", val+index); index = 0; break; } else { Console.WriteLine("TCF {0:X4}", val + index); index = 0; break; } case 2: switch (QC) { case 0: if (val == 0) { Console.WriteLine("DDOUBL"); break; } Console.WriteLine("DAS {0:X4}", val + index); break; case 1: if(val==6) { Console.WriteLine("ZL"); break; } Console.WriteLine("LXCH {0:X4}", val + index); break; case 2: Console.WriteLine("INCR {0:X4}", val + index); INCR(val + index); break; case 3: Console.WriteLine("ADS {0:X4}", val + index); break; } index = 0; break; case 3: Console.WriteLine("CA {0:X4}", val + index); CA(val + index); index = 0; break; case 4: if(val==0) { Console.WriteLine("COM"); break; } Console.WriteLine("CS {0:X4}", val + index); index = 0; break; case 5: switch (QC) { case 0: if(val==17) { Console.WriteLine("RESUME"); } Console.WriteLine("INDEX {0:X4}", val + index); index = PB.get_word((short)(val + index)); break; case 1: switch(val) { case 4: Console.WriteLine("DTCF"); break; case 5: Console.WriteLine("DTCB"); break; default: Console.WriteLine("DXCH {0:X4}", val + index); break; } index = 0; break; case 2: switch (val) { case 4: Console.WriteLine("OVSK"); break; case 5: Console.WriteLine("TCAA"); break; default: Console.WriteLine("TS {0:X4}", val + index); TS(val+index); break; } Console.WriteLine("TS {0:X4}", val + index); TS(val+index); index = 0; break; case 3: Console.WriteLine("XCH {0:X4}", val + index); index = 0; break; } break; case 6: if (val != 0) { Console.WriteLine("AD {0:X4}", val + index); AD(val + index); } else { Console.WriteLine("DOUBLE"); } index = 0; break; case 7: if (fFixed) { val = fFixed_switch(S.getInt()); } else { val = S.getInt(); } Console.WriteLine("MASK {0:X4}", val + index); running = false; index = 0; break; } }
private void extraCodes(sWord S) { int val = 0; if (fFixed) { val = fFixed_switch(S.getInt()); } else { val = S.getInt(); } switch (RegBank.get_word(11)) { case 0: val = S.getVal(0, 8); switch(PC) { case 0: Console.WriteLine("READ {0:X4}", val+index); break; case 1: Console.WriteLine("WRITE {0:X4}", val+index); write_chan(val, RegBank.get_word(0)); break; case 2: Console.WriteLine("RAND {0:X4}", val+index); break; case 3: Console.WriteLine("WAND {0:X4}", val+index); break; case 4: Console.WriteLine("ROR {0:X4}", val+index); break; case 5: Console.WriteLine("WOR {0:X4}", val+index); break; case 6: Console.WriteLine("RXOR {0:X4}", val+index); break; case 7: Console.WriteLine("WXOR {0:X4}", val+index); break; } index = 0; extra = false; break; case 1: if(QC==0) { Console.WriteLine("DV {0:X4}", val + index); } else { Console.WriteLine("BZF {0:X4}", val + index); } index = 0; extra = false; break; case 2: switch(QC) { case 1: Console.WriteLine("MSU {0:X4}", val + index); break; case 2: if (val == 7) { Console.WriteLine("ZQ"); } else { Console.WriteLine("QXCH {0:X4}", val + index); } break; case 3: Console.WriteLine("AUG {0:X4}", val + index); break; case 4: Console.WriteLine("DIM {0:X4}", val + index); break; } index = 0; extra = false; break; case 3: if (val == 0) { Console.WriteLine("DCOM"); } else { Console.WriteLine("DCA {0:X4}", val + index); } index = 0; extra = false; break; case 4: Console.WriteLine("DCS {0:X4}", val + index); index = 0; extra = false; break; case 5: Console.WriteLine("INDEX {0:X4}", val + index); index = PB.get_word((short)(val + index)); extra = true; break; case 6: if(QC==0) { Console.WriteLine("SU {0:X4}", val + index); } else { Console.WriteLine("BZMF {0:X4}", val + index); } index = 0; extra = false; break; case 7: if (val == 0) { Console.WriteLine("SQUARE"); } else { Console.WriteLine("MP {0:X4}", val + index); } index = 0; extra = false; break; } }
public int fFixed_switch(int adr) { tEr = PB.isErasable(); tId = (short)PB.getId(); tFEB = PB.getFEB(); sWord s = new sWord((short)adr); if (s.getVal(10, 11) == 0) { if ((short)s.getVal(8, 9) == 0) { PB = RegBank; } else { PB = new BANK(true, (short)s.getVal(8, 9), 0, AGC_File); } adr = s.getVal(0, 7); e_mem = true; } else { PB = new BANK(false, (short)s.getVal(10, 11), 0, AGC_File); adr = s.getVal(0, 9); e_mem = false; } return adr; }
public void CCS(int adress) { CA(adress); if(PB.get_word((short)adress)>0) {} else if(PB.get_word((short)adress)==0) {} else if(PB.get_word((short)adress)>16384) {sWord wd = new sWord(PB.get_word((short)(adress))); RegBank.set_hex(0,1);} else{RegBank.set_hex(0,0); } }
//Execution /// <summary> /// <para>edit adress registry (FB/EB/FEB/S) based on the bits 12-1 of the current instruction</para> /// <para>detect usage of FB/EB register</para> /// <para>if not needed, will set them accordingly to the bank to load</para> /// </summary> /// <param name="adress">byte[] : 16b adress word</param> /// <returns>bool : type (true : erasable, false : fixed)</returns> public bool build_adress_reg(sWord adress) { short S = 0; bool erasable = false; if (extra && adress.getVal(12, 14) == 0)//IO Code detection { S = adress.getVal(0, 8); PC = adress.getVal(9, 11); erasable = true; fFixed = false; } else if (adress.getVal(10,11) == 0) { if ((adress.getVal(9, 9) != 1) | (adress.getVal(8,8) != 1)) { S = adress.getVal(0, 11); fFixed = true; } else { S = (short)(adress.getVal(0, 7)); fFixed = false; } erasable = true; } else if (adress.getVal(10,11) == 2 | adress.getVal(10,11)==3) { S = adress.getVal(0, 10); erasable = false; fFixed = true; } else { S = (short)(adress.getVal(0, 9)); erasable = false; fFixed = false; } RegBank.set_hex(12, S); //set S reg to operand value return erasable; }