Previous 199869 Revisions Next

r33755 Tuesday 9th December, 2014 at 02:16:47 UTC by hap
added tmc0270_cpu_device, preliminary
[src/emu/cpu/tms0980]tms0980.c tms0980.h

trunk/src/emu/cpu/tms0980/tms0980.c
r242266r242267
9191#define M_STSL              0x00080000 /* STATUS to Status Latch */
9292#define M_YTP               0x00100000 /* Y to +ALU */
9393
94#define M_RSTR              0x00200000 /* -> F_RSTR */
95
9496/* Standard/fixed instructions - these are documented more in their specific handlers below */
9597#define F_BR                0x00000001
9698#define F_CALL              0x00000002
r242266r242267
115117
116118
117119// supported types:
118// note: dice information assumes the orientation is pictured with RAM at the bottom-left
120// note: dice information assumes the orientation is pictured with RAM at the bottom-left, except where noted
119121
120122// TMS1000
121123// - 64x4bit RAM array at the bottom-left
r242266r242267
127129// - 20-term output PLA(opla) at the top-left
128130// - the ALU is between the opla and mpla
129131const device_type TMS1000 = &device_creator<tms1000_cpu_device>; // 28-pin DIP, 11 R pins
132const device_type TMS1070 = &device_creator<tms1070_cpu_device>; // same as tms1000, just supports higher voltage
130133const device_type TMS1200 = &device_creator<tms1200_cpu_device>; // 40-pin DIP, 13 R pins
131const device_type TMS1070 = &device_creator<tms1070_cpu_device>; // same as tms1000, just supports higher voltage
132134// TMS1270 has 10 O pins, how does that work?
133135
134136// TMS1100 is nearly the same as TMS1000, some different opcodes, and with double the RAM and ROM
r242266r242267
140142// - 2048x9bit ROM array at the bottom-left
141143// - main instructions PLA at the top half, to the right of the midline
142144// - 64-term microinstructions PLA between the RAM and ROM, supporting 20 microinstructions
143// - 16-term output PLA and segment PLA above the RAM
144const device_type TMS0980 = &device_creator<tms0980_cpu_device>; // 28-pin DIP, 9 R pins
145// - 16-term output PLA and segment PLA above the RAM (rotate opla 90 degrees)
146const device_type TMS0980 = &device_creator<tms0980_cpu_device>; // 28-pin DIP, 9 R pins, 5 K pins
145147
146148// TMS0970 is a stripped-down version of the TMS0980, itself acting more like a TMS1000
147// - 64x4bit RAM array at the bottom-left
148// - 1024x8bit ROM array at the bottom-right
149// - RAM and ROM is exactly the same as TMS1000
149150// - main instructions PLA at the top half, to the right of the midline
150151// - 32-term microinstructions PLA between the RAM and ROM, supporting 15 microinstructions
151// - 16-term output PLA and segment PLA above the RAM
152// - 16-term output PLA and segment PLA above the RAM (rotate opla 90 degrees)
152153const device_type TMS0970 = &device_creator<tms0970_cpu_device>; // 28-pin DIP, 11 R pins
153154
155// TMC0270 on the other hand, is a TMS0980 with earrings and a new hat. The new changes look like a quick afterthought, almost hacky
156// - RAM, ROM, and main instructions PLA is exactly the same as TMS0980
157// - 64-term microinstructions PLA between the RAM and ROM, supporting 20 microinstructions plus optional separate lines for custom opcode handling
158// - 48-term output PLA above the RAM (rotate opla 90 degrees)
159const device_type TMC0270 = &device_creator<tmc0270_cpu_device>; // 40-pin DIP, 16 O pins, 8 R pins (the other R pins are internally hooked up to support more I/O)
160// TMC0260 is same? except opla is 32 instead of 48 terms
154161
162
155163static ADDRESS_MAP_START(program_11bit_9, AS_PROGRAM, 16, tms1xxx_cpu_device)
156164   AM_RANGE(0x000, 0xfff) AM_ROM
157165ADDRESS_MAP_END
r242266r242267
232240{
233241}
234242
243tms0980_cpu_device::tms0980_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 k_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source)
244   : tms0970_cpu_device(mconfig, type, name, tag, owner, clock, o_pins, r_pins, k_pins, pc_bits, byte_bits, x_bits, prgwidth, program, datawidth, data, shortname, source)
245{
246}
235247
236248
249tmc0270_cpu_device::tmc0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
250   : tms0980_cpu_device(mconfig, TMC0270, "TMC0270", tag, owner, clock, 16, 8, 4, 7, 9, 4, 12, ADDRESS_MAP_NAME(program_11bit_9), 8, ADDRESS_MAP_NAME(data_64x9_as4), "tmc0270", __FILE__)
251{
252}
253
254
255
237256static MACHINE_CONFIG_FRAGMENT(tms1000)
238257   
239258   // microinstructions PLA, output PLA
r242266r242267
287306}
288307
289308
309static MACHINE_CONFIG_FRAGMENT(tmc0270)
290310
311   // main opcodes PLA, microinstructions PLA, output PLA
312   MCFG_PLA_ADD("ipla", 9, 22, 24)
313   MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
314   MCFG_PLA_ADD("mpla", 6, 21, 64)
315   MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
316   MCFG_PLA_ADD("opla", 6, 16, 48)
317   MCFG_PLA_FILEFORMAT(PLA_FMT_BERKELEY)
318MACHINE_CONFIG_END
319
320machine_config_constructor tmc0270_cpu_device::device_mconfig_additions() const
321{
322   return MACHINE_CONFIG_NAME(tmc0270);
323}
324
325
326
291327offs_t tms1000_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
292328{
293329   extern CPU_DISASSEMBLE(tms1000);
r242266r242267
357393   m_cs = 0;
358394   m_r = 0;
359395   m_o = 0;
396   m_o_latch = 0;
360397   m_cki_bus = 0;
361398   m_c4 = 0;
362399   m_p = 0;
r242266r242267
370407   m_clatch = 0;
371408   m_add = 0;
372409   m_bl = 0;
373
410   
374411   m_ram_in = 0;
375412   m_dam_in = 0;
376413   m_ram_out = 0;
r242266r242267
381418   m_micro = 0;
382419   m_subcycle = 0;
383420
421   m_a_prev = m_a;
422   m_r_prev = m_r;
423   m_o_prev = m_o;
424
384425   // register for savestates
385426   save_item(NAME(m_pc));
386427   save_item(NAME(m_sr));
r242266r242267
394435   save_item(NAME(m_cs));
395436   save_item(NAME(m_r));
396437   save_item(NAME(m_o));
438   save_item(NAME(m_o_latch));
397439   save_item(NAME(m_cki_bus));
398440   save_item(NAME(m_c4));
399441   save_item(NAME(m_p));
r242266r242267
418460   save_item(NAME(m_micro));
419461   save_item(NAME(m_subcycle));
420462
463   save_item(NAME(m_a_prev));
464   save_item(NAME(m_r_prev));
465   save_item(NAME(m_o_prev));
466
421467   // register state for debugger
422468   state_add(TMS0980_PC,     "PC",     m_pc    ).formatstr("%02X");
423469   state_add(TMS0980_SR,     "SR",     m_sr    ).formatstr("%01X");
r242266r242267
570616   sel = BITSWAP8(sel,7,6,0,1,2,3,4,5); // lines are reversed
571617   UINT32 mask = m_mpla->read(sel);
572618   mask ^= 0x43fc3; // invert active-negative
573
619   
620   // note: M_RSTR is specific to TMC02x0, it redirects to F_RSTR
574621   //                      _______  ______                                _____  _____  _____  _____  ______  _____  ______  _____                            _____
575   const UINT32 md[20] = { M_NDMTP, M_DMTP, M_AUTY, M_AUTA, M_CKM, M_SSE, M_CKP, M_YTP, M_MTP, M_ATN, M_NATN, M_MTN, M_15TN, M_CKN, M_NE, M_C8, M_SSS, M_CME, M_CIN, M_STO };
622   const UINT32 md[21] = { M_NDMTP, M_DMTP, M_AUTY, M_AUTA, M_CKM, M_SSE, M_CKP, M_YTP, M_MTP, M_ATN, M_NATN, M_MTN, M_15TN, M_CKN, M_NE, M_C8, M_SSS, M_CME, M_CIN, M_STO, M_RSTR };
576623   
577   for (int bit = 0; bit < 20; bit++)
624   for (int bit = 0; bit < 21 && bit < m_mpla->outputs(); bit++)
578625      if (mask & (1 << bit))
579626         decode |= md[bit];
580627   
r242266r242267
619666
620667
621668
669//-------------------------------------------------
670//  program counter/opcode decode
671//-------------------------------------------------
622672
623
624673void tms1xxx_cpu_device::next_pc()
625674{
626675   // The program counter is a LFSR. To put it simply, the feedback bit is a XOR of the two highest bits,
r242266r242267
666715   next_pc();
667716}
668717
718void tmc0270_cpu_device::read_opcode()
719{
720   tms0980_cpu_device::read_opcode();
721   
722   // RSTR is on the mpla
723   if (m_micro & M_RSTR)
724      m_fixed |= F_RSTR;
725}
669726
727
728
729//-------------------------------------------------
730//  i/o handling
731//-------------------------------------------------
732
670733void tms1xxx_cpu_device::write_o_output(UINT8 data)
671734{
672735   // a hardcoded table is supported if the output pla is unknown
r242266r242267
684747   m_write_o(0, m_o & m_o_mask, 0xffff);
685748}
686749
750
751void tmc0270_cpu_device::dynamic_output()
752{
753   // TODO..
754   
755   m_a_prev = m_a;
756   m_r_prev = m_r;
757   m_o_prev = m_o;
758}
759
760
687761UINT8 tms1xxx_cpu_device::read_k_input()
688762{
689763   // K1,2,4,8,3 (KC test pin is not emulated)
r242266r242267
692766   return (k & 0xf) | k3;
693767}
694768
769UINT8 tmc0270_cpu_device::read_k_input()
770{
771   // TODO..
772   
773   return tms1xxx_cpu_device::read_k_input();
774}
695775
776
696777void tms1xxx_cpu_device::set_cki_bus()
697778{
698779   switch (m_opcode & 0xf8)
r242266r242267
746827}
747828
748829
749// fixed opcode set
750830
831//-------------------------------------------------
832//  fixed opcode set
833//-------------------------------------------------
834
751835// TMS1000/common:
752836
753837void tms1xxx_cpu_device::op_sbit()
r242266r242267
841925}
842926
843927
844// TMS09x0-specific
928// TMS0970-specific (and possibly child classes)
845929void tms0970_cpu_device::op_setr()
846930{
847931   // SETR: set output register
r242266r242267
858942}
859943
860944
861// TMS0980-specific
945// TMS0980-specific (and possibly child classes)
862946void tms0980_cpu_device::op_comx()
863947{
864948   // COMX: complement X register, but not the MSB
r242266r242267
904988}
905989
906990
907void tms1xxx_cpu_device::execute_fixed_opcode()
991// TMC0270-specific
992void tmc0270_cpu_device::op_tdo()
908993{
909   switch (m_fixed)
910   {
911      case F_SBIT: op_sbit(); break;
912      case F_RBIT: op_rbit(); break;
913      case F_SETR: op_setr(); break;
914      case F_RSTR: op_rstr(); break;
915      case F_TDO:  op_tdo();  break;
916      case F_CLO:  op_clo();  break;
917      case F_LDX:  op_ldx();  break;
918      case F_COMX: op_comx(); break;
919      case F_COMX8:op_comx8();break;
920      case F_LDP:  op_ldp();  break;
921      case F_COMC: op_comc(); break;
922      case F_OFF:  op_off();  break;
923      case F_SEAC: op_seac(); break;
924      case F_REAC: op_reac(); break;
925      case F_SAL:  op_sal();  break;
926      case F_SBL:  op_sbl();  break;
927      case F_XDA:  op_xda();  break;
928     
929      default:
930         // BR, CALL, RETN are handled in execute_run
931         if (m_fixed & ~(F_BR | F_CALL | F_RETN))
932            fatalerror("%s unsupported fixed opcode %03X %04X!\n", tag(), m_opcode, m_fixed);
933         break;
934   }
994   // TDO: transfer data out
995   if (m_status)
996      m_o_latch = m_a;
997   else
998      m_o = m_o_latch | (m_a << 4 & 0x30);
999   
1000   // handled further in dynamic_output
9351001}
9361002
9371003
9381004
1005//-------------------------------------------------
1006//  execute_run
1007//-------------------------------------------------
1008
9391009void tms1xxx_cpu_device::execute_run()
9401010{
9411011   do
r242266r242267
9951065
9961066         // execute: k input valid, read ram, clear alu inputs
9971067         set_cki_bus();
1068         dynamic_output();
9981069         m_ram_in = m_data->read_byte(m_ram_address) & 0xf;
9991070         m_dam_in = m_data->read_byte(m_ram_address | (0x10 << (m_x_bits-1))) & 0xf;
10001071         m_ram_out = -1;
r242266r242267
10561127         if (m_micro & M_STO || (m_micro & M_CME && m_eac == m_add))
10571128            m_ram_out = m_a;
10581129
1059         // handle the fixed opcodes here
1060         execute_fixed_opcode();
1130         // handle the other fixed opcodes here
1131         if (m_fixed & F_SBIT)  op_sbit();
1132         if (m_fixed & F_RBIT)  op_rbit();
1133         if (m_fixed & F_SETR)  op_setr();
1134         if (m_fixed & F_RSTR)  op_rstr();
1135         if (m_fixed & F_TDO)   op_tdo();
1136         if (m_fixed & F_CLO)   op_clo();
1137         if (m_fixed & F_LDX)   op_ldx();
1138         if (m_fixed & F_COMX)  op_comx();
1139         if (m_fixed & F_COMX8) op_comx8();
1140         if (m_fixed & F_LDP)   op_ldp();
1141         if (m_fixed & F_COMC)  op_comc();
1142         if (m_fixed & F_OFF)   op_off();
1143         if (m_fixed & F_SEAC)  op_seac();
1144         if (m_fixed & F_REAC)  op_reac();
1145         if (m_fixed & F_SAL)   op_sal();
1146         if (m_fixed & F_SBL)   op_sbl();
1147         if (m_fixed & F_XDA)   op_xda();
10611148
10621149         // execute: write ram
10631150         if (m_ram_out != -1)
trunk/src/emu/cpu/tms0980/tms0980.h
r242266r242267
8383   void state_string_export(const device_state_entry &entry, astring &string);
8484
8585   void next_pc();
86   void execute_fixed_opcode();
87   
86
8887   virtual void write_o_output(UINT8 data);
8988   virtual UINT8 read_k_input();
9089   virtual void set_cki_bus();
90   virtual void dynamic_output() { ; } // not used by default
9191   virtual void read_opcode();
9292
9393   virtual void op_sbit();
r242266r242267
122122   UINT8   m_pa;        // 4-bit page address register
123123   UINT8   m_pb;        // 4-bit page buffer register
124124   UINT8   m_a;         // 4-bit accumulator
125   UINT8   m_a_prev;
125126   UINT8   m_x;         // 2,3,or 4-bit RAM X register
126127   UINT8   m_y;         // 4-bit RAM Y register
127128   UINT8   m_ca;        // chapter address bit
128129   UINT8   m_cb;        // chapter buffer bit
129130   UINT8   m_cs;        // chapter subroutine bit
130131   UINT16  m_r;
132   UINT16  m_r_prev;
131133   UINT16  m_o;
134   UINT16  m_o_prev;
135   UINT16  m_o_latch;   // TMC0270 hold latch
132136   UINT8   m_cki_bus;
133137   UINT8   m_c4;
134138   UINT8   m_p;         // 4-bit adder p(lus)-input
r242266r242267
258262{
259263public:
260264   tms0980_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
265   tms0980_cpu_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, UINT8 o_pins, UINT8 r_pins, UINT8 k_pins, UINT8 pc_bits, UINT8 byte_bits, UINT8 x_bits, int prgwidth, address_map_constructor program, int datawidth, address_map_constructor data, const char *shortname, const char *source);
261266
262267protected:
263268   // overrides
r242266r242267
273278   virtual void read_opcode();
274279   
275280   virtual void op_comx();
276private:
281
277282   UINT32 decode_micro(UINT8 sel);
278283};
279284
280285
286class tmc0270_cpu_device : public tms0980_cpu_device
287{
288public:
289   tmc0270_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
281290
291protected:
292   // overrides
293   virtual machine_config_constructor device_mconfig_additions() const;
294
295   virtual void write_o_output(UINT8 data) { tms1xxx_cpu_device::write_o_output(data); }
296   virtual UINT8 read_k_input();
297   virtual void dynamic_output();
298   virtual void read_opcode();
299   
300   virtual void op_setr() { tms1xxx_cpu_device::op_setr(); }
301   virtual void op_rstr() { tms1xxx_cpu_device::op_rstr(); }
302   virtual void op_tdo();
303};
304
305
306
282307extern const device_type TMS1000;
283308extern const device_type TMS1070;
284309extern const device_type TMS1200;
r242266r242267
286311extern const device_type TMS1300;
287312extern const device_type TMS0970;
288313extern const device_type TMS0980;
314extern const device_type TMC0270;
289315
290316
291317#endif /* _TMS0980_H_ */


Previous 199869 Revisions Next


© 1997-2024 The MAME Team