diff options
Diffstat (limited to 'src/devices/cpu/tx0/tx0.cpp')
-rw-r--r-- | src/devices/cpu/tx0/tx0.cpp | 258 |
1 files changed, 247 insertions, 11 deletions
diff --git a/src/devices/cpu/tx0/tx0.cpp b/src/devices/cpu/tx0/tx0.cpp index 51bc1ba6c6b..54d31301b04 100644 --- a/src/devices/cpu/tx0/tx0.cpp +++ b/src/devices/cpu/tx0/tx0.cpp @@ -16,7 +16,7 @@ #include "debugger.h" #define LOG_RIM (1 << 1U) -//#define VERBOSE (LOG_RIM) +#define VERBOSE (LOG_RIM) #include "logmacro.h" @@ -42,8 +42,9 @@ #define INCREMENT_PC_8KW (PC = (PC+1) & ADDRESS_MASK_8KW) -DEFINE_DEVICE_TYPE(TX0_8KW, tx0_8kw_device, "tx0_8kw_cpu", "MIT Lincoln Laboratory TX-0 8KW") -DEFINE_DEVICE_TYPE(TX0_64KW, tx0_64kw_device, "tx0_64kw_cpu", "MIT Lincoln Laboratory TX-0 64KW") +DEFINE_DEVICE_TYPE(TX0_8KW, tx0_8kw_device, "tx0_8kw_cpu", "MIT Lincoln Laboratory TX-0 8KW (new)") +DEFINE_DEVICE_TYPE(TX0_8KW_OLD, tx0_8kwo_device, "tx0_8kwo_cpu", "MIT Lincoln Laboratory TX-0 8KW (old)") +DEFINE_DEVICE_TYPE(TX0_64KW, tx0_64kw_device, "tx0_64kw_cpu", "MIT Lincoln Laboratory TX-0 64KW") tx0_device::tx0_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, int addr_bits, int address_mask, int ir_mask) @@ -66,8 +67,18 @@ tx0_device::tx0_device(const machine_config &mconfig, device_type type, const ch m_program_config.m_is_octal = true; } +tx0_8kw_device::tx0_8kw_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : tx0_device(mconfig, type, tag, owner, clock, 13, ADDRESS_MASK_8KW, 037) +{ +} + tx0_8kw_device::tx0_8kw_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : tx0_device(mconfig, TX0_8KW, tag, owner, clock, 13, ADDRESS_MASK_8KW, 037) + : tx0_8kw_device(mconfig, TX0_8KW, tag, owner, clock) +{ +} + +tx0_8kwo_device::tx0_8kwo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : tx0_8kw_device(mconfig, TX0_8KW_OLD, tag, owner, clock) { } @@ -583,6 +594,221 @@ void tx0_64kw_device::execute_instruction_64kw() /* (1.2) TBR = Store the contents of the TBR in the MBR. */ MBR |= m_tbr; + if ((MAR & 0000003) == 2 && ((MAR & 0000600) >> 7) == 1) + /* LMB and MBL used simultaneously interchange LR and MBR */ + std::swap(LR, MBR); + else if ((MAR & 0000003) == 2) + /* (1.3) LMB = Store the contents of the LR in the MBR. */ + MBR = LR; + else if (((MAR & 0000600) >> 7) == 1) + /* (1.3) MLR = Store the contents of the MBR (memory buffer + register) in the live reg. */ + LR = MBR; + + if (((MAR & 0000600) >> 7) == 2) + /* (1.4) SHR = Shift the AC right one place, i.e. multiply the AC + by 2^-1 */ + AC >>= 1; + + if (((MAR & 0000600) >> 7) == 3) + /* (1.4) CYR = Cycle the AC right one digital position (AC(17) will + become AC(0)) */ + AC = (AC >> 1) | ((AC & 1) << 17); + + if (MAR & 0000020) + /* (1.4) PAD = Partial add AC to MBR, that is, for every digital + position of the MBR that contains a one, complement the digit + in the corresponding digital position of the AC. This is also + called a half add. */ + AC ^= MBR; + + if (MAR & 0000010) + { /* (1.7) CRY = Partial add the 18 digits of the AC to the + corresponding 18 digits of the carry. + + To determine what the 18 digits of the carry are, use the + following rule: + + "Grouping the AC and MBR digits into pairs and proceeding from + right to left, assign the carry digit of the next pair to a one + if in the present pair MBR = 1 and AC = 0 or if in the present + pair AC = 1 and carry 1. + + (Note: the 0th digit pair determines the 17th pair's carry + digit)" */ + AC ^= MBR; + + AC = AC + MBR; + AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */ + } + + if (((MAR & 0030000) >> 12) == 3) + /* (1.8) Hlt = Halt the computer */ + m_run = 0; + + break; + } + } +} + +/* execute one instruction */ +void tx0_8kwo_device::execute_instruction_8kw() +{ + if (! m_cycle) + { + m_cycle = 1; /* most frequent case */ + switch (IR) + { + case 0: /* STOre */ + case 4: /* Store LR */ + case 8: /* ADD */ + case 12: /* Load LR */ + break; + + case 16: /* TRansfer on Negative */ + if (AC & 0400000) + { + PC = MAR & 0017777; + m_cycle = 0; /* instruction only takes one cycle if branch + is taken */ + } + break; + + case 20: /* TRAnsfer */ + PC = MAR & 0017777; + m_cycle = 0; /* instruction only takes one cycle if branch + is taken */ + break; + + case 24: /* OPeRate */ + case 25: + case 26: + case 27: + case 28: + case 29: + case 30: + case 31: + if (IR & 004) + /* (0.8) CLL = Clear the left nine digital positions of the AC */ + AC &= 0000777; + + if (IR & 002) + /* (0.8) CLR = Clear the right nine digital positions of the AC */ + AC &= 0777000; + + if (((IR & 001) == 01) && ((MAR & 010000) == 000000)) + { + /* (0.8) IOS In-Out Stop = Stop machine so that an In-Out command + (specified by digits 6 7 8 of MAR) may be executed */ + /* ((MAR & 0007000) >> 9) is device ID */ + /* 7: */ + /* (0.8) P7H = Punch holes 1-6 in flexo tape specified by AC + digital positions 2, 5, 8, 11, 14, and 17. Also punches a 7th + hole on tape. */ + /* 6: */ + /* (0.8) P6H = Same as P7H but no seventh hole */ + /* 4: */ + /* (0.8) PNT = Print one flexowriter character specified by AC + digits 2, 5, 8, 11, 14, and 17. */ + /* 1: */ + /* (0.8) R1C = Read one line of flexo tape so that tape positions + 1, 2, 3, 4, 5, and 6 will be put in the AC digital positions 0, + 3, 6, 9, 12 and 15. */ + /* 3: */ + /* (0.8) R3C = Read one line of flexo tape into AC digits 0, 3, 6, + 9, 12 and 15. Then cycle the AC one digital position; read the + next line on tape into AC digits 0, 3, 6, 9, 12 and 15, cycle + the AC right one digital position and read the third and last + line into AC digits 0, 3, 6, 9, 12 and 15. (This command is + equal to a triple CYR-R1C.) */ + /* 2: */ + /* (0.8) DIS = Intensify a point on the scope with x and y + coordinates where x is specified by AC digits 0-8 with digit 0 + being used as the sign and y is specified by AC digits 9-17 + with digit 9 being used as the sign for y. The complement + system is in effect when the signs are negative. */ + /* (5 is undefined) */ + int index = (MAR & 0007000) >> 9; + + m_ios = 0; + call_io_handler(index); + m_ioh = 1; + } + + if (((IR & 001) == 00) && ((MAR & 010000) == 010000)) + { /* (IOS) EX0 through EX7 = operate user's EXternal equipment. */ + switch ((MAR & 0007000) >> 9) + { + /* ... */ + } + } + break; + } + } + else + { + m_cycle = 0; /* always true */ + switch (IR) + { + case 0: /* STOre */ + tx0_write(MAR, (MBR = AC)); + break; + + case 4: /* Store LR */ + tx0_write(MAR, (MBR = LR)); + break; + + case 8: /* ADD */ + MBR = tx0_read(MAR); + + AC = AC + MBR; + AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */ + + break; + + case 12: /* Load LR */ + LR = MBR = tx0_read(MAR); + break; + + case 16: /* TRansfer on Negative */ + case 20: /* TRAnsfer */ + break; + + case 24: /* OPeRate */ + case 25: + case 26: + case 27: + case 28: + case 29: + case 30: + case 31: + MBR = 0; + + if ((MAR & 0000104) == 0000100) + /* (1.1) PEN = Read the light pen flip-flops 1 and 2 into AC(0) and + AC(1). */ + /*...*/{ } + + if ((MAR & 0000104) == 0000004) + /* (1.1) TAC = Insert a one in each digital position of the AC + wherever there is a one in the corresponding digital position + of the TAC. */ + AC |= m_tac; + + if ((MAR & 0000003) == 1) + /* (1.2) AMB = Store the contents of the AC in the MBR. */ + MBR = AC; + + if (MAR & 0000040) + /* (1.2) COM = Complement every digit in the accumulator */ + AC ^= 0777777; + + if ((MAR & 0000003) == 3) + /* (1.2) TBR = Store the contents of the TBR in the MBR. */ + MBR |= m_tbr; + + uint32_t tmp = MBR; + if ((MAR & 0000003) == 2) /* (1.3) LMB = Store the contents of the LR in the MBR. */ MBR = LR; @@ -590,7 +816,15 @@ void tx0_64kw_device::execute_instruction_64kw() if (((MAR & 0000600) >> 7) == 1) /* (1.3) MLR = Store the contents of the MBR (memory buffer register) in the live reg. */ - LR = MBR; + LR = tmp; + + if ((MAR & 0000704) == 0000104) + /* (1.3) ORL = Inclusive or MBR into LR. */ + LR |= tmp; + + if ((MAR & 0000704) == 0000304) + /* (1.3) ANL = And MBR into LR. */ + LR &= tmp; if (((MAR & 0000600) >> 7) == 2) /* (1.4) SHR = Shift the AC right one place, i.e. multiply the AC @@ -629,7 +863,7 @@ void tx0_64kw_device::execute_instruction_64kw() AC = (AC + (AC >> 18)) & 0777777; /* propagate carry around */ } - if (((MAR & 0030000) >> 12) == 3) + if (((IR & 001) == 01) && ((MAR & 017000) == 010000)) /* (1.8) Hlt = Halt the computer */ m_run = 0; @@ -969,11 +1203,8 @@ void tx0_8kw_device::execute_instruction_8kw() } if (((! (MAR & 0000400)) && (MAR & 0000200)) && ((! (MAR & 0000004)) && (MAR & 0000002))) - { /* LMB and MBL used simultaneously interchange LR and MBR */ - int tmp = MBR; - MBR = LR; - LR = tmp; - } + /* LMB and MBL used simultaneously interchange LR and MBR */ + std::swap(LR, MBR); else if ((! (MAR & 0000400)) && (MAR & 0000200)) /* (1.4) MBL = Transfer MBR contents to LR */ LR = MBR; @@ -1073,6 +1304,11 @@ std::unique_ptr<util::disasm_interface> tx0_8kw_device::create_disassembler() return std::make_unique<tx0_8kw_disassembler>(); } +std::unique_ptr<util::disasm_interface> tx0_8kwo_device::create_disassembler() +{ + return std::make_unique<tx0_8kwo_disassembler>(); +} + std::unique_ptr<util::disasm_interface> tx0_64kw_device::create_disassembler() { return std::make_unique<tx0_64kw_disassembler>(); |