Previous 199869 Revisions Next

r26749 Wednesday 25th December, 2013 at 12:00:22 UTC by Wilbert Pol
tx0.c: Modernized cpu core.  [Wilbert Pol]

Out of whatsnew:
Also copied over the support for octal in
debugger state from the alto2 branch.
[src/emu]distate.c
[src/emu/cpu/pdp1]tx0.c tx0.h
[src/mess/drivers]tx0.c
[src/mess/includes]tx0.h

trunk/src/emu/distate.c
r26748r26749
248248            reset = true;
249249            break;
250250
251         // O outputs as octal
252         case 'O':
253            if (width == 0)
254               throw emu_fatalerror("Width required for %%O formats\n");
255            hitnonzero = false;
256            while (leadzero && width > 22)
257            {
258               dest.cat(" ");
259               width--;
260            }
261            for (int digitnum = 21; digitnum >= 0; digitnum--)
262            {
263               int digit = (result >> (3 * digitnum)) & 07;
264               if (digit != 0)
265               {
266                  static const char octchars[] = "01234567";
267                  dest.cat(&octchars[digit], 1);
268                  hitnonzero = true;
269               }
270               else if (hitnonzero || (leadzero && digitnum < width) || digitnum == 0)
271                  dest.cat("0");
272            }
273            reset = true;
274            break;
275
251276         // d outputs as signed decimal
252277         case 'd':
253278            if (width == 0)
trunk/src/emu/cpu/pdp1/tx0.c
r26748r26749
1515#define LOG 0
1616#define LOG_EXTRA 0
1717
18static void execute_instruction_64kw(device_t *device);
19static void execute_instruction_8kw(device_t *device);
20static void pulse_reset(device_t *device);
2118
19#define READ_TX0_18BIT(A) ((signed)m_program->read_dword((A)<<2))
20#define WRITE_TX0_18BIT(A,V) (m_program->write_dword((A)<<2,(V)))
2221
23/* TX-0 Registers */
24struct tx0_state
25{
26   const tx0_reset_param_t *iface;
2722
28   /* processor registers */
29   int mbr;        /* memory buffer register (18 bits) */
30   int ac;         /* accumulator (18 bits) */
31   int mar;        /* memory address register (16 (64kW) or 13 (8kW) bits) */
32   int pc;         /* program counter (16 (64kW) or 13 (8kW) bits) */
33   int ir;         /* instruction register (2 (64kW) or 5 (8kW) bits) */
34   int lr;         /* live register (18 bits) */
35   int xr;         /* index register (14 bits) (8kW only) */
36   int pf;         /* program flags (6 bits expandable to 10) (8kW only) */
23#define io_handler_rim 3
3724
38   /* operator panel switches */
39   int tbr;        /* toggle switch buffer register (18 bits) */
40   int tac;        /* toggle switch accumulator (18 bits) */
41   int tss[16];    /* toggle switch storage (18 bits * 16) */
42   unsigned int cm_sel : 16;   /* individual cm select (1 bit * 16) */
43   unsigned int lr_sel : 16;   /* individual lr select (1 bit * 16) */
44   unsigned int gbl_cm_sel : 1;/* global cm select (1 bit) */
45   unsigned int stop_cyc0 : 1; /* stop on cycle 0 */
46   unsigned int stop_cyc1 : 1; /* stop on cycle 1 */
25#define PC      m_pc
26#define IR      m_ir
27#define MBR     m_mbr
28#define MAR     m_mar
29#define AC      m_ac
30#define LR      m_lr
31#define XR      m_xr
32#define PF      m_pf
4733
48   /* processor state flip-flops */
49   unsigned int run : 1;       /* processor is running */
50   unsigned int rim : 1;       /* processor is in read-in mode */
51   unsigned int cycle : 2;     /* 0 -> fetch */
52                        /* 1 -> execute (except for taken branches) */
53                        /* 2 -> extra execute cycle for SXA and ADO */
34#define ADDRESS_MASK_64KW   0177777
35#define ADDRESS_MASK_8KW    0017777
5436
55   unsigned int ioh : 1;       /* i-o halt: processor is executing an Input-Output Transfer wait */
56   unsigned int ios : 1;       /* i-o synchronizer: set on i-o operation completion */
37#define INCREMENT_PC_64KW   (PC = (PC+1) & ADDRESS_MASK_64KW)
38#define INCREMENT_PC_8KW    (PC = (PC+1) & ADDRESS_MASK_8KW)
5739
58   /* additional emulator state variables */
59   int rim_step;           /* current step in rim execution */
6040
61   int address_mask;       /* address mask */
62   int ir_mask;            /* IR mask */
41const device_type TX0_8KW  = &device_creator<tx0_8kw_device>;
42const device_type TX0_64KW = &device_creator<tx0_64kw_device>;
6343
64   int icount;
6544
66   legacy_cpu_device *device;
67   address_space *program;
68};
45tx0_device::tx0_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source, int addr_bits, int address_mask, int ir_mask)
46   : cpu_device(mconfig, type, name, tag, owner, clock, shortname, source)
47   , m_program_config("program", ENDIANNESS_BIG, 32, addr_bits , -2)
48   , m_address_mask(address_mask)
49   , m_ir_mask(ir_mask)
50   , m_cpy_handler(*this)
51   , m_r1l_handler(*this)
52   , m_dis_handler(*this)
53   , m_r3l_handler(*this)
54   , m_prt_handler(*this)
55   , m_rsv_handler(*this)
56   , m_p6h_handler(*this)
57   , m_p7h_handler(*this)
58   , m_sel_handler(*this)
59   , m_io_reset_callback(*this)
60{
61   m_is_octal = true;
62}
6963
70INLINE tx0_state *get_safe_token(device_t *device)
64tx0_8kw_device::tx0_8kw_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
65   : tx0_device(mconfig, TX0_8KW, "TX-0 8KW", tag, owner, clock, "tx0_8w_cpu", __FILE__, 13, ADDRESS_MASK_8KW, 037)
7166{
72   assert(device != NULL);
73   assert(device->type() == TX0_64KW ||
74         device->type() == TX0_8KW);
75   return (tx0_state *)downcast<legacy_cpu_device *>(device)->token();
7667}
7768
78#define READ_TX0_18BIT(A) ((signed)cpustate->program->read_dword((A)<<2))
79#define WRITE_TX0_18BIT(A,V) (cpustate->program->write_dword((A)<<2,(V)))
8069
70tx0_64kw_device::tx0_64kw_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
71   : tx0_device(mconfig, TX0_64KW, "TX-0 64KW", tag, owner, clock, "tx0_64kw_cpu", __FILE__, 16, ADDRESS_MASK_64KW, 03)
72{
73}
8174
82#define io_handler_rim 3
8375
84#define PC      cpustate->pc
85#define IR      cpustate->ir
86#define MBR     cpustate->mbr
87#define MAR     cpustate->mar
88#define AC      cpustate->ac
89#define LR      cpustate->lr
90#define XR      cpustate->xr
91#define PF      cpustate->pf
92
93#define ADDRESS_MASK_64KW   0177777
94#define ADDRESS_MASK_8KW    0017777
95
96#define INCREMENT_PC_64KW   (PC = (PC+1) & ADDRESS_MASK_64KW)
97#define INCREMENT_PC_8KW    (PC = (PC+1) & ADDRESS_MASK_8KW)
98
99
100static int tx0_read(tx0_state *cpustate, offs_t address)
76int tx0_device::tx0_read(offs_t address)
10177{
102   if ((address >= 16) || (cpustate->gbl_cm_sel) || ((cpustate->cm_sel >> address) & 1))
78   if ((address >= 16) || (m_gbl_cm_sel) || ((m_cm_sel >> address) & 1))
10379      /* core memory (CM) */
10480      return READ_TX0_18BIT(address);
105   else if ((cpustate->lr_sel >> address) & 1)
81   else if ((m_lr_sel >> address) & 1)
10682      /* live register (LR) */
10783      return LR;
10884
10985   /* toggle switch storage (TSS) */
110   return cpustate->tss[address];
86   return m_tss[address];
11187}
11288
113static void tx0_write(tx0_state *cpustate, offs_t address, int data)
89void tx0_device::tx0_write(offs_t address, int data)
11490{
115   if ((address >= 16) || (cpustate->gbl_cm_sel) || ((cpustate->cm_sel >> address) & 1))
91   if ((address >= 16) || (m_gbl_cm_sel) || ((m_cm_sel >> address) & 1))
11692      /* core memory (CM) */
11793      WRITE_TX0_18BIT(address, data);
118   else if ((cpustate->lr_sel >> address) & 1)
94   else if ((m_lr_sel >> address) & 1)
11995      /* live register (LR) */
12096      LR = data;
12197   else
r26748r26749
124100      ;
125101}
126102
127static void tx0_init_common(legacy_cpu_device *device, device_irq_acknowledge_callback irqcallback, int is_64kw)
103
104void tx0_device::device_start()
128105{
129   tx0_state *cpustate = get_safe_token(device);
106   m_mbr = 0;
107   m_ac = 0;
108   m_mar = 0;
109   m_lr = 0;
110   m_xr = 0;
111   m_pf = 0;
112   m_tbr = 0;
113   m_tac = 0;
114   for ( int i = 0; i < 16; i++ )
115   {
116      m_tss[i] = 0;
117   }
118   m_cm_sel = 0;
119   m_lr_sel = 0;
120   m_gbl_cm_sel = 0;
121   m_stop_cyc0 = 0;
122   m_stop_cyc1 = 0;
123   m_cycle = 0;
130124
131   /* clean-up */
132   cpustate->iface = (const tx0_reset_param_t *)device->static_config();
125   // Resolve callbacks
126   m_cpy_handler.resolve();
127   m_r1l_handler.resolve();
128   m_dis_handler.resolve();
129   m_r3l_handler.resolve();
130   m_prt_handler.resolve();
131   m_rsv_handler.resolve();
132   m_p6h_handler.resolve();
133   m_p7h_handler.resolve();
134   m_sel_handler.resolve();
135   m_io_reset_callback.resolve();
133136
134   cpustate->address_mask = is_64kw ? ADDRESS_MASK_64KW : ADDRESS_MASK_8KW;
135   cpustate->ir_mask = is_64kw ? 03 : 037;
137   m_program = &space(AS_PROGRAM);
136138
137   cpustate->device = device;
138   cpustate->program = &device->space(AS_PROGRAM);
139}
139   save_item(NAME(m_mbr));
140   save_item(NAME(m_ac));
141   save_item(NAME(m_mar));
142   save_item(NAME(m_pc));
143   save_item(NAME(m_ir));
144   save_item(NAME(m_lr));
145   save_item(NAME(m_xr));
146   save_item(NAME(m_pf));
147   save_item(NAME(m_tbr));
148   save_item(NAME(m_tac));
149   save_item(NAME(m_tss));
150   save_item(NAME(m_cm_sel));
151   save_item(NAME(m_lr_sel));
152   save_item(NAME(m_gbl_cm_sel));
153   save_item(NAME(m_stop_cyc0));
154   save_item(NAME(m_stop_cyc1));
155   save_item(NAME(m_run));
156   save_item(NAME(m_rim));
157   save_item(NAME(m_cycle));
158   save_item(NAME(m_ioh));
159   save_item(NAME(m_ios));
160   save_item(NAME(m_rim_step));
140161
141static CPU_INIT( tx0_64kw )
142{
143   tx0_init_common(device, irqcallback, 1);
144}
162   // Register state for debugger
163   state_add( TX0_PC,         "PC",       m_pc         ).mask(m_address_mask).formatstr("0%06O");
164   state_add( TX0_IR,         "IR",       m_ir         ).mask(m_ir_mask)     .formatstr("0%02O");
165   state_add( TX0_MBR,        "MBR",      m_mbr        ).mask(0777777)       .formatstr("0%06O");
166   state_add( TX0_MAR,        "MAR",      m_mar        ).mask(m_address_mask).formatstr("0%06O");
167   state_add( TX0_AC,         "AC",       m_ac         ).mask(0777777)       .formatstr("0%06O");
168   state_add( TX0_LR,         "LR",       m_lr         ).mask(0777777)       .formatstr("0%06O");
169   state_add( TX0_XR,         "XR",       m_xr         ).mask(0037777)       .formatstr("0%05O");
170   state_add( TX0_PF,         "PF",       m_pf         ).mask(077)           .formatstr("0%02O");
171   state_add( TX0_TBR,        "TBR",      m_tbr        ).mask(0777777)       .formatstr("0%06O");
172   state_add( TX0_TAC,        "TAC",      m_tac        ).mask(0777777)       .formatstr("0%06O");
173   state_add( TX0_TSS00,      "TSS00",    m_tss[000]   ).mask(0777777)       .formatstr("0%06O");
174   state_add( TX0_TSS01,      "TSS01",    m_tss[001]   ).mask(0777777)       .formatstr("0%06O");
175   state_add( TX0_TSS02,      "TSS02",    m_tss[002]   ).mask(0777777)       .formatstr("0%06O");
176   state_add( TX0_TSS03,      "TSS03",    m_tss[003]   ).mask(0777777)       .formatstr("0%06O");
177   state_add( TX0_TSS04,      "TSS04",    m_tss[004]   ).mask(0777777)       .formatstr("0%06O");
178   state_add( TX0_TSS05,      "TSS05",    m_tss[005]   ).mask(0777777)       .formatstr("0%06O");
179   state_add( TX0_TSS06,      "TSS06",    m_tss[006]   ).mask(0777777)       .formatstr("0%06O");
180   state_add( TX0_TSS07,      "TSS07",    m_tss[007]   ).mask(0777777)       .formatstr("0%06O");
181   state_add( TX0_TSS10,      "TSS10",    m_tss[010]   ).mask(0777777)       .formatstr("0%06O");
182   state_add( TX0_TSS11,      "TSS11",    m_tss[011]   ).mask(0777777)       .formatstr("0%06O");
183   state_add( TX0_TSS12,      "TSS12",    m_tss[012]   ).mask(0777777)       .formatstr("0%06O");
184   state_add( TX0_TSS13,      "TSS13",    m_tss[013]   ).mask(0777777)       .formatstr("0%06O");
185   state_add( TX0_TSS14,      "TSS14",    m_tss[014]   ).mask(0777777)       .formatstr("0%06O");
186   state_add( TX0_TSS15,      "TSS15",    m_tss[015]   ).mask(0777777)       .formatstr("0%06O");
187   state_add( TX0_TSS16,      "TSS16",    m_tss[016]   ).mask(0777777)       .formatstr("0%06O");
188   state_add( TX0_TSS17,      "TSS17",    m_tss[017]   ).mask(0777777)       .formatstr("0%06O");
189   state_add( TX0_CM_SEL,     "CMSEL",    m_cm_sel     ).mask(0177777)       .formatstr("0%06O");
190   state_add( TX0_LR_SEL,     "LRSEL",    m_lr_sel     ).mask(0177777)       .formatstr("0%06O");
191   state_add( TX0_GBL_CM_SEL, "GBLCMSEL", m_gbl_cm_sel ).mask(1)             .formatstr("%1X");
192   state_add( TX0_STOP_CYC0,  "STOPCYC0", m_stop_cyc0  ).mask(1)             .formatstr("%1X");
193   state_add( TX0_STOP_CYC1,  "STOPCYC1", m_stop_cyc1  ).mask(1)             .formatstr("%1X");
194   state_add( TX0_RUN,        "RUN",      m_run        ).mask(1)             .formatstr("%1X");
195   state_add( TX0_RIM,        "RIM",      m_rim        ).mask(1)             .formatstr("%1X");
196   state_add( TX0_CYCLE,      "CYCLE",    m_cycle      )                     .formatstr("%1X");
197   state_add( TX0_IOH,        "IOH",      m_ioh        )                     .formatstr("%1X");
198   state_add( TX0_IOS,        "IOS",      m_ios        ).mask(1)             .formatstr("%1X");
145199
146static CPU_INIT( tx0_8kw)
147{
148   tx0_init_common(device, irqcallback, 0);
200   state_add(STATE_GENPC, "GENPC", m_pc).formatstr("0%06O").noshow();
201   state_add(STATE_GENFLAGS, "GENFLAGS",  m_ir).noshow();
202
203   m_icountptr = &m_icount;
149204}
150205
151static CPU_RESET( tx0 )
152{
153   tx0_state *cpustate = get_safe_token(device);
154206
207void tx0_device::device_reset()
208{
155209   /* reset CPU flip-flops */
156   pulse_reset(device);
210   pulse_reset();
157211
158   cpustate->gbl_cm_sel = 1;   /* HACK */
212   m_gbl_cm_sel = 1;   /* HACK */
159213}
160214
161/* execute instructions on this CPU until icount expires */
162static CPU_EXECUTE( tx0_64kw )
215
216void tx0_device::call_io_handler(int io_handler)
163217{
164   tx0_state *cpustate = get_safe_token(device);
218   /* data will be transferred to AC */
219   switch (io_handler)
220   {
221      case 0: m_cpy_handler(ASSERT_LINE); break;
222      case 1: m_r1l_handler(ASSERT_LINE); break;
223      case 2: m_dis_handler(ASSERT_LINE); break;
224      case 3: m_r3l_handler(ASSERT_LINE); break;
225      case 4: m_prt_handler(ASSERT_LINE); break;
226      case 5: m_rsv_handler(ASSERT_LINE); break;
227      case 6: m_p6h_handler(ASSERT_LINE); break;
228      case 7: m_p7h_handler(ASSERT_LINE); break;
229   }
230}
165231
232
233/* execute instructions on this CPU until icount expires */
234void tx0_64kw_device::execute_run()
235{
166236   do
167237   {
168      debugger_instruction_hook(device, PC);
238      debugger_instruction_hook(this, PC);
169239
170240
171      if (cpustate->ioh && cpustate->ios)
241      if (m_ioh && m_ios)
172242      {
173         cpustate->ioh = 0;
243         m_ioh = 0;
174244      }
175245
176246
177      if ((! cpustate->run) && (! cpustate->rim))
178         cpustate->icount = 0;   /* if processor is stopped, just burn cycles */
179      else if (cpustate->rim)
247      if ((! m_run) && (! m_rim))
248         m_icount = 0;   /* if processor is stopped, just burn cycles */
249      else if (m_rim)
180250      {
181         switch (cpustate->rim_step)
251         switch (m_rim_step)
182252         {
183253         case 0:
184254            /* read first word as instruction */
185255            AC = 0;
186            if (cpustate->iface->io_handlers[io_handler_rim])
187               (*cpustate->iface->io_handlers[io_handler_rim])(device);    /* data will be transferred to AC */
188            cpustate->rim_step = 1;
189            cpustate->ios = 0;
256            call_io_handler(io_handler_rim);
257            m_rim_step = 1;
258            m_ios = 0;
190259            break;
191260
192261         case 1:
193            if (! cpustate->ios)
262            if (! m_ios)
194263            {   /* transfer incomplete: wait some more */
195               cpustate->icount = 0;
264               m_icount = 0;
196265            }
197266            else
198267            {   /* data transfer complete */
199               cpustate->ios = 0;
268               m_ios = 0;
200269
201270               MBR = AC;
202271               IR = MBR >> 16;     /* basic opcode */
203272               if ((IR == 2) || (IR == 1))     /* trn or add instruction? */
204273               {
205274                  PC = MBR & ADDRESS_MASK_64KW;
206                  cpustate->rim = 0;  /* exit read-in mode */
207                  cpustate->run = (IR == 2) ? 1 : 0;  /* stop if add instruction */
208                  cpustate->rim_step = 0;
275                  m_rim = 0;  /* exit read-in mode */
276                  m_run = (IR == 2) ? 1 : 0;  /* stop if add instruction */
277                  m_rim_step = 0;
209278               }
210279               else if ((IR == 0) || (IR == 3))    /* sto or opr instruction? */
211280               {
212281                  MAR = MBR & ADDRESS_MASK_64KW;
213                  cpustate->rim_step = 2;
282                  m_rim_step = 2;
214283               }
215284            }
216285            break;
r26748r26749
218287         case 2:
219288            /* read second word as data */
220289            AC = 0;
221            if (cpustate->iface->io_handlers[io_handler_rim])
222               (*cpustate->iface->io_handlers[io_handler_rim])(device);    /* data will be transferred to AC */
223            cpustate->rim_step = 3;
224            cpustate->ios = 0;
290            call_io_handler(io_handler_rim);
291            m_rim_step = 3;
292            m_ios = 0;
225293            break;
226294
227295         case 3:
228            if (! cpustate->ios)
296            if (! m_ios)
229297            {   /* transfer incomplete: wait some more */
230               cpustate->icount = 0;
298               m_icount = 0;
231299            }
232300            else
233301            {   /* data transfer complete */
234               cpustate->ios = 0;
302               m_ios = 0;
235303
236               tx0_write(cpustate, MAR, MBR = AC);
304               tx0_write(MAR, MBR = AC);
237305
238               cpustate->rim_step = 0;
306               m_rim_step = 0;
239307            }
240308            break;
241309         }
242310      }
243311      else
244312      {
245         if (cpustate->cycle == 0)
313         if (m_cycle == 0)
246314         {   /* fetch new instruction */
247            MBR = tx0_read(cpustate, MAR = PC);
315            MBR = tx0_read(MAR = PC);
248316            INCREMENT_PC_64KW;
249317            IR = MBR >> 16;     /* basic opcode */
250318            MAR = MBR & ADDRESS_MASK_64KW;
251319         }
252320
253         if (! cpustate->ioh)
321         if (! m_ioh)
254322         {
255            if ((cpustate->stop_cyc0 && (cpustate->cycle == 0))
256               || (cpustate->stop_cyc1 && (cpustate->cycle == 1)))
257               cpustate->run = 0;
323            if ((m_stop_cyc0 && (m_cycle == 0))
324               || (m_stop_cyc1 && (m_cycle == 1)))
325               m_run = 0;
258326
259            execute_instruction_64kw(device);   /* execute instruction */
327            execute_instruction_64kw();
260328         }
261329
262         cpustate->icount --;
330         m_icount --;
263331      }
264332   }
265   while (cpustate->icount > 0);
333   while (m_icount > 0);
266334}
267335
268336/* execute instructions on this CPU until icount expires */
269static CPU_EXECUTE( tx0_8kw )
337void tx0_8kw_device::execute_run()
270338{
271   tx0_state *cpustate = get_safe_token(device);
272
273339   do
274340   {
275      debugger_instruction_hook(device, PC);
341      debugger_instruction_hook(this, PC);
276342
277343
278      if (cpustate->ioh && cpustate->ios)
344      if (m_ioh && m_ios)
279345      {
280         cpustate->ioh = 0;
346         m_ioh = 0;
281347      }
282348
283349
284      if ((! cpustate->run) && (! cpustate->rim))
285         cpustate->icount = 0;   /* if processor is stopped, just burn cycles */
286      else if (cpustate->rim)
350      if ((! m_run) && (! m_rim))
351         m_icount = 0;   /* if processor is stopped, just burn cycles */
352      else if (m_rim)
287353      {
288         switch (cpustate->rim_step)
354         switch (m_rim_step)
289355         {
290356         case 0:
291357            /* read first word as instruction */
292358            AC = 0;
293            if (cpustate->iface->io_handlers[io_handler_rim])
294               (*cpustate->iface->io_handlers[io_handler_rim])(device);    /* data will be transferred to AC */
295            cpustate->rim_step = 1;
296            cpustate->ios = 0;
359            call_io_handler(io_handler_rim);
360            m_rim_step = 1;
361            m_ios = 0;
297362            break;
298363
299364         case 1:
300            if (! cpustate->ios)
365            if (! m_ios)
301366            {   /* transfer incomplete: wait some more */
302               cpustate->icount = 0;
367               m_icount = 0;
303368            }
304369            else
305370            {   /* data transfer complete */
306               cpustate->ios = 0;
371               m_ios = 0;
307372
308373               MBR = AC;
309374               IR = MBR >> 13;     /* basic opcode */
310375               if ((IR == 16) || (IR == 8))    /* trn or add instruction? */
311376               {
312377                  PC = MBR & ADDRESS_MASK_8KW;
313                  cpustate->rim = 0;  /* exit read-in mode */
314                  cpustate->run = (IR == 16) ? 1 : 0; /* stop if add instruction */
315                  cpustate->rim_step = 0;
378                  m_rim = 0;  /* exit read-in mode */
379                  m_run = (IR == 16) ? 1 : 0; /* stop if add instruction */
380                  m_rim_step = 0;
316381               }
317382               else if ((IR == 0) || (IR == 24))   /* sto or opr instruction? */
318383               {
319384                  MAR = MBR & ADDRESS_MASK_8KW;
320                  cpustate->rim_step = 2;
385                  m_rim_step = 2;
321386               }
322387            }
323388            break;
r26748r26749
325390         case 2:
326391            /* read second word as data */
327392            AC = 0;
328            if (cpustate->iface->io_handlers[io_handler_rim])
329               (*cpustate->iface->io_handlers[io_handler_rim])(device);    /* data will be transferred to AC */
330            cpustate->rim_step = 3;
331            cpustate->ios = 0;
393            call_io_handler(io_handler_rim);
394            m_rim_step = 3;
395            m_ios = 0;
332396            break;
333397
334398         case 3:
335            if (! cpustate->ios)
399            if (! m_ios)
336400            {   /* transfer incomplete: wait some more */
337               cpustate->icount = 0;
401               m_icount = 0;
338402            }
339403            else
340404            {   /* data transfer complete */
341               cpustate->ios = 0;
405               m_ios = 0;
342406
343               tx0_write(cpustate, MAR, MBR = AC);
407               tx0_write(MAR, MBR = AC);
344408
345               cpustate->rim_step = 0;
409               m_rim_step = 0;
346410            }
347411            break;
348412         }
349413      }
350414      else
351415      {
352         if (cpustate->cycle == 0)
416         if (m_cycle == 0)
353417         {   /* fetch new instruction */
354            MBR = tx0_read(cpustate, MAR = PC);
418            MBR = tx0_read(MAR = PC);
355419            INCREMENT_PC_8KW;
356420            IR = MBR >> 13;     /* basic opcode */
357421            MAR = MBR & ADDRESS_MASK_8KW;
358422         }
359423
360         if (! cpustate->ioh)
424         if (! m_ioh)
361425         {
362            if ((cpustate->stop_cyc0 && (cpustate->cycle == 0))
363               || (cpustate->stop_cyc1 && (cpustate->cycle == 1)))
364               cpustate->run = 0;
426            if ((m_stop_cyc0 && (m_cycle == 0))
427               || (m_stop_cyc1 && (m_cycle == 1)))
428               m_run = 0;
365429
366            execute_instruction_8kw(device);    /* execute instruction */
430            execute_instruction_8kw();
367431         }
368432
369         cpustate->icount -= 1;
433         m_icount -= 1;
370434      }
371435   }
372   while (cpustate->icount > 0);
436   while (m_icount > 0);
373437}
374438
375439
376static CPU_SET_INFO( tx0 )
377{
378   tx0_state *cpustate = get_safe_token(device);
379
380   switch (state)
381   {
382   /* --- the following bits of info are set as 64-bit signed integers --- */
383   case CPUINFO_INT_SP:                        (void) info->i; /* no SP */                         break;
384   case CPUINFO_INT_PC:
385   case CPUINFO_INT_REGISTER + TX0_PC:         PC = info->i & cpustate->address_mask;              break;
386   case CPUINFO_INT_REGISTER + TX0_IR:         IR = info->i & cpustate->ir_mask; /* weird idea */  break;
387   case CPUINFO_INT_REGISTER + TX0_MBR:        MBR = info->i & 0777777;                            break;
388   case CPUINFO_INT_REGISTER + TX0_MAR:        MAR = info->i & cpustate->address_mask;             break;
389   case CPUINFO_INT_REGISTER + TX0_AC:         AC = info->i & 0777777;                             break;
390   case CPUINFO_INT_REGISTER + TX0_LR:         LR = info->i & 0777777;                             break;
391   case CPUINFO_INT_REGISTER + TX0_XR:         XR = info->i & 0037777;                             break;
392   case CPUINFO_INT_REGISTER + TX0_PF:         PF = info->i & 077;                                 break;
393   case CPUINFO_INT_REGISTER + TX0_TBR:        cpustate->tbr = info->i & 0777777;                  break;
394   case CPUINFO_INT_REGISTER + TX0_TAC:        cpustate->tac = info->i & 0777777;                  break;
395   case CPUINFO_INT_REGISTER + TX0_TSS00:
396   case CPUINFO_INT_REGISTER + TX0_TSS01:
397   case CPUINFO_INT_REGISTER + TX0_TSS02:
398   case CPUINFO_INT_REGISTER + TX0_TSS03:
399   case CPUINFO_INT_REGISTER + TX0_TSS04:
400   case CPUINFO_INT_REGISTER + TX0_TSS05:
401   case CPUINFO_INT_REGISTER + TX0_TSS06:
402   case CPUINFO_INT_REGISTER + TX0_TSS07:
403   case CPUINFO_INT_REGISTER + TX0_TSS10:
404   case CPUINFO_INT_REGISTER + TX0_TSS11:
405   case CPUINFO_INT_REGISTER + TX0_TSS12:
406   case CPUINFO_INT_REGISTER + TX0_TSS13:
407   case CPUINFO_INT_REGISTER + TX0_TSS14:
408   case CPUINFO_INT_REGISTER + TX0_TSS15:
409   case CPUINFO_INT_REGISTER + TX0_TSS16:
410   case CPUINFO_INT_REGISTER + TX0_TSS17:      cpustate->tss[state-(CPUINFO_INT_REGISTER + TX0_TSS00)] = info->i & 0777777;    break;
411   case CPUINFO_INT_REGISTER + TX0_CM_SEL:     cpustate->cm_sel = info->i & 0177777;               break;
412   case CPUINFO_INT_REGISTER + TX0_LR_SEL:     cpustate->lr_sel = info->i & 0177777;               break;
413   case CPUINFO_INT_REGISTER + TX0_GBL_CM_SEL: cpustate->gbl_cm_sel = info->i ? 1 : 0;             break;
414   case CPUINFO_INT_REGISTER + TX0_STOP_CYC0:  cpustate->stop_cyc0 = info->i ? 1 : 0;              break;
415   case CPUINFO_INT_REGISTER + TX0_STOP_CYC1:  cpustate->stop_cyc1 = info->i ? 1 : 0;              break;
416   case CPUINFO_INT_REGISTER + TX0_RUN:        cpustate->run = info->i ? 1 : 0;                    break;
417   case CPUINFO_INT_REGISTER + TX0_RIM:        cpustate->rim = info->i ? 1 : 0;                    break;
418   case CPUINFO_INT_REGISTER + TX0_CYCLE:      if (LOG) logerror("tx0_set_reg to cycle counter ignored\n");/* no way!*/ break;
419   case CPUINFO_INT_REGISTER + TX0_IOH:        if (LOG) logerror("tx0_set_reg to ioh flip-flop ignored\n");/* no way!*/ break;
420   case CPUINFO_INT_REGISTER + TX0_IOS:        cpustate->ios = info->i ? 1 : 0; break;
421   case CPUINFO_INT_REGISTER + TX0_RESET:      pulse_reset(device);                                break;
422   case CPUINFO_INT_REGISTER + TX0_IO_COMPLETE:cpustate->ios = 1;                                  break;
423   }
424}
425
426
427CPU_GET_INFO( tx0_64kw )
428{
429   tx0_state *cpustate = ( device != NULL && device->token() != NULL ) ? get_safe_token(device) : NULL;
430
431   switch (state)
432   {
433   /* --- the following bits of info are returned as 64-bit signed integers --- */
434   case CPUINFO_INT_CONTEXT_SIZE:                  info->i = sizeof(tx0_state);                    break;
435   case CPUINFO_INT_INPUT_LINES:                   info->i = 0;                                    break;
436   case CPUINFO_INT_DEFAULT_IRQ_VECTOR:            info->i = 0;                                    break;
437   case CPUINFO_INT_ENDIANNESS:                    info->i = ENDIANNESS_BIG;   /*don't care*/      break;
438   case CPUINFO_INT_CLOCK_MULTIPLIER:              info->i = 1;                                    break;
439   case CPUINFO_INT_CLOCK_DIVIDER:                 info->i = 1;                                    break;
440   case CPUINFO_INT_MIN_INSTRUCTION_BYTES:         info->i = 4;                                    break;
441   case CPUINFO_INT_MAX_INSTRUCTION_BYTES:         info->i = 4;                                    break;
442   case CPUINFO_INT_MIN_CYCLES:                    info->i = 1;                                    break;
443   case CPUINFO_INT_MAX_CYCLES:                    info->i = 3;                                    break;
444
445   case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM:    info->i = 32;                           break;
446   case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 16;                          break;
447   case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = -2;                          break;
448   case CPUINFO_INT_DATABUS_WIDTH + AS_DATA:   info->i = 0;                            break;
449   case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA:   info->i = 0;                            break;
450   case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA:   info->i = 0;                            break;
451   case CPUINFO_INT_DATABUS_WIDTH + AS_IO:     info->i = 0;                            break;
452   case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO:     info->i = 0;                            break;
453   case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO:     info->i = 0;                            break;
454
455   case CPUINFO_INT_SP:                            info->i = 0;    /* no SP */                     break;
456   case CPUINFO_INT_PC:                            info->i = PC;                                   break;
457   case CPUINFO_INT_PREVIOUSPC:                    info->i = 0;    /* TODO??? */                   break;
458
459   case CPUINFO_INT_REGISTER + TX0_PC:             info->i = PC;                                   break;
460   case CPUINFO_INT_REGISTER + TX0_IR:             info->i = IR;                                   break;
461   case CPUINFO_INT_REGISTER + TX0_MBR:            info->i = MBR;                                  break;
462   case CPUINFO_INT_REGISTER + TX0_MAR:            info->i = MAR;                                  break;
463   case CPUINFO_INT_REGISTER + TX0_AC:             info->i = AC;                                   break;
464   case CPUINFO_INT_REGISTER + TX0_LR:             info->i = LR;                                   break;
465   case CPUINFO_INT_REGISTER + TX0_XR:             info->i = XR;                                   break;
466   case CPUINFO_INT_REGISTER + TX0_PF:             info->i = PF;                                   break;
467   case CPUINFO_INT_REGISTER + TX0_TBR:            info->i = cpustate->tbr;                        break;
468   case CPUINFO_INT_REGISTER + TX0_TAC:            info->i = cpustate->tac;                        break;
469   case CPUINFO_INT_REGISTER + TX0_TSS00:
470   case CPUINFO_INT_REGISTER + TX0_TSS01:
471   case CPUINFO_INT_REGISTER + TX0_TSS02:
472   case CPUINFO_INT_REGISTER + TX0_TSS03:
473   case CPUINFO_INT_REGISTER + TX0_TSS04:
474   case CPUINFO_INT_REGISTER + TX0_TSS05:
475   case CPUINFO_INT_REGISTER + TX0_TSS06:
476   case CPUINFO_INT_REGISTER + TX0_TSS07:
477   case CPUINFO_INT_REGISTER + TX0_TSS10:
478   case CPUINFO_INT_REGISTER + TX0_TSS11:
479   case CPUINFO_INT_REGISTER + TX0_TSS12:
480   case CPUINFO_INT_REGISTER + TX0_TSS13:
481   case CPUINFO_INT_REGISTER + TX0_TSS14:
482   case CPUINFO_INT_REGISTER + TX0_TSS15:
483   case CPUINFO_INT_REGISTER + TX0_TSS16:
484   case CPUINFO_INT_REGISTER + TX0_TSS17:          info->i = cpustate->tss[state-(CPUINFO_INT_REGISTER + TX0_TSS00)]; break;
485   case CPUINFO_INT_REGISTER + TX0_CM_SEL:         info->i = cpustate->cm_sel;                     break;
486   case CPUINFO_INT_REGISTER + TX0_LR_SEL:         info->i = cpustate->lr_sel;                     break;
487   case CPUINFO_INT_REGISTER + TX0_GBL_CM_SEL:     info->i = cpustate->gbl_cm_sel;                 break;
488   case CPUINFO_INT_REGISTER + TX0_STOP_CYC0:      info->i = cpustate->stop_cyc0;                  break;
489   case CPUINFO_INT_REGISTER + TX0_STOP_CYC1:      info->i = cpustate->stop_cyc1;                  break;
490   case CPUINFO_INT_REGISTER + TX0_RUN:            info->i = cpustate->run;                        break;
491   case CPUINFO_INT_REGISTER + TX0_RIM:            info->i = cpustate->rim;                        break;
492   case CPUINFO_INT_REGISTER + TX0_CYCLE:          info->i = cpustate->cycle;                      break;
493   case CPUINFO_INT_REGISTER + TX0_IOH:            info->i = cpustate->ioh;                        break;
494   case CPUINFO_INT_REGISTER + TX0_IOS:            info->i = cpustate->ios;                        break;
495
496   /* --- the following bits of info are returned as pointers to data or functions --- */
497   case CPUINFO_FCT_SET_INFO:                      info->setinfo = CPU_SET_INFO_NAME(tx0);         break;
498   case CPUINFO_FCT_INIT:                          info->init = CPU_INIT_NAME(tx0_64kw);           break;
499   case CPUINFO_FCT_RESET:                         info->reset = CPU_RESET_NAME(tx0);              break;
500   case CPUINFO_FCT_EXECUTE:                       info->execute = CPU_EXECUTE_NAME(tx0_64kw);     break;
501   case CPUINFO_FCT_BURN:                          info->burn = NULL;                              break;
502   case CPUINFO_FCT_DISASSEMBLE:                   info->disassemble = CPU_DISASSEMBLE_NAME(tx0_64kw);     break;
503   case CPUINFO_PTR_INSTRUCTION_COUNTER:           info->icount = &cpustate->icount;                       break;
504
505   /* --- the following bits of info are returned as NULL-terminated strings --- */
506   case CPUINFO_STR_NAME:                          strcpy(info->s, "TX-0");                        break;
507   case CPUINFO_STR_SHORTNAME:                     strcpy(info->s, "tx0_64kw_cpu");                        break;
508   case CPUINFO_STR_FAMILY:                    strcpy(info->s, "TX-0");                        break;
509   case CPUINFO_STR_VERSION:                   strcpy(info->s, "1.0");                         break;
510   case CPUINFO_STR_SOURCE_FILE:                       strcpy(info->s, __FILE__);                      break;
511   case CPUINFO_STR_CREDITS:                   strcpy(info->s, "Raphael Nabet");               break;
512
513   case CPUINFO_STR_FLAGS:                         strcpy(info->s, "");                            break;
514
515   case CPUINFO_STR_REGISTER + TX0_PC:             sprintf(info->s, "PC:0%06o", PC);               break;
516   case CPUINFO_STR_REGISTER + TX0_IR:             sprintf(info->s, "IR:0%02o", IR);               break;
517   case CPUINFO_STR_REGISTER + TX0_MBR:            sprintf(info->s, "MBR:0%06o", MBR);             break;
518   case CPUINFO_STR_REGISTER + TX0_MAR:            sprintf(info->s, "MAR:0%06o", MAR);             break;
519   case CPUINFO_STR_REGISTER + TX0_AC:             sprintf(info->s, "AC:0%06o", AC);               break;
520   case CPUINFO_STR_REGISTER + TX0_LR:             sprintf(info->s, "LR:0%06o", LR);               break;
521   case CPUINFO_STR_REGISTER + TX0_XR:             sprintf(info->s, "XR:0%05o", XR);               break;
522   case CPUINFO_STR_REGISTER + TX0_PF:             sprintf(info->s, "PF:0%02o", PF);               break;
523   case CPUINFO_STR_REGISTER + TX0_TBR:            sprintf(info->s, "TBR:0%06o", cpustate->tbr);   break;
524   case CPUINFO_STR_REGISTER + TX0_TAC:            sprintf(info->s, "TAC:0%06o", cpustate->tac);   break;
525   case CPUINFO_STR_REGISTER + TX0_TSS00:
526   case CPUINFO_STR_REGISTER + TX0_TSS01:
527   case CPUINFO_STR_REGISTER + TX0_TSS02:
528   case CPUINFO_STR_REGISTER + TX0_TSS03:
529   case CPUINFO_STR_REGISTER + TX0_TSS04:
530   case CPUINFO_STR_REGISTER + TX0_TSS05:
531   case CPUINFO_STR_REGISTER + TX0_TSS06:
532   case CPUINFO_STR_REGISTER + TX0_TSS07:
533   case CPUINFO_STR_REGISTER + TX0_TSS10:
534   case CPUINFO_STR_REGISTER + TX0_TSS11:
535   case CPUINFO_STR_REGISTER + TX0_TSS12:
536   case CPUINFO_STR_REGISTER + TX0_TSS13:
537   case CPUINFO_STR_REGISTER + TX0_TSS14:
538   case CPUINFO_STR_REGISTER + TX0_TSS15:
539   case CPUINFO_STR_REGISTER + TX0_TSS16:
540   case CPUINFO_STR_REGISTER + TX0_TSS17:          sprintf(info->s, "TSS%02o:0%06o", state-(CPUINFO_STR_REGISTER + TX0_TSS00), cpustate->tss[state-(CPUINFO_STR_REGISTER + TX0_TSS00)]); break;
541   case CPUINFO_STR_REGISTER + TX0_CM_SEL:         sprintf(info->s, "CMSEL:0%06o", cpustate->cm_sel); break;
542   case CPUINFO_STR_REGISTER + TX0_LR_SEL:         sprintf(info->s, "LRSEL:0%06o", cpustate->lr_sel); break;
543   case CPUINFO_STR_REGISTER + TX0_GBL_CM_SEL:     sprintf(info->s, "GBLCMSEL:%X", cpustate->gbl_cm_sel); break;
544   case CPUINFO_STR_REGISTER + TX0_STOP_CYC0:      sprintf(info->s, "STOPCYC0:%X", cpustate->stop_cyc0); break;
545   case CPUINFO_STR_REGISTER + TX0_STOP_CYC1:      sprintf(info->s, "STOPCYC1:%X", cpustate->stop_cyc1); break;
546   case CPUINFO_STR_REGISTER + TX0_RUN:            sprintf(info->s, "RUN:%X", cpustate->run); break;
547   case CPUINFO_STR_REGISTER + TX0_RIM:            sprintf(info->s, "RIM:%X", cpustate->rim); break;
548   case CPUINFO_STR_REGISTER + TX0_CYCLE:          sprintf(info->s, "CYCLE:%X", cpustate->cycle); break;
549   case CPUINFO_STR_REGISTER + TX0_IOH:            sprintf(info->s, "IOH:%X", cpustate->ioh); break;
550   case CPUINFO_STR_REGISTER + TX0_IOS:            sprintf(info->s, "IOS:%X", cpustate->ios); break;
551   case CPUINFO_IS_OCTAL:                          info->i = true;                         break;
552   }
553}
554
555CPU_GET_INFO( tx0_8kw )
556{
557   tx0_state *cpustate = ( device != NULL && device->token() != NULL ) ? get_safe_token(device) : NULL;
558
559   switch (state)
560   {
561   /* --- the following bits of info are returned as 64-bit signed integers --- */
562   case CPUINFO_INT_CONTEXT_SIZE:                  info->i = sizeof(tx0_state);                    break;
563   case CPUINFO_INT_INPUT_LINES:                   info->i = 0;                            break;
564   case CPUINFO_INT_DEFAULT_IRQ_VECTOR:            info->i = 0;                            break;
565   case CPUINFO_INT_ENDIANNESS:                    info->i = ENDIANNESS_BIG;   /*don't care*/  break;
566   case CPUINFO_INT_CLOCK_MULTIPLIER:              info->i = 1;                            break;
567   case CPUINFO_INT_CLOCK_DIVIDER:                 info->i = 1;                            break;
568   case CPUINFO_INT_MIN_INSTRUCTION_BYTES:         info->i = 4;                            break;
569   case CPUINFO_INT_MAX_INSTRUCTION_BYTES:         info->i = 4;                            break;
570   case CPUINFO_INT_MIN_CYCLES:                    info->i = 1;                            break;
571   case CPUINFO_INT_MAX_CYCLES:                    info->i = 3;                            break;
572
573   case CPUINFO_INT_DATABUS_WIDTH + AS_PROGRAM:    info->i = 32;                   break;
574   case CPUINFO_INT_ADDRBUS_WIDTH + AS_PROGRAM: info->i = 13;                  break;
575   case CPUINFO_INT_ADDRBUS_SHIFT + AS_PROGRAM: info->i = -2;                  break;
576   case CPUINFO_INT_DATABUS_WIDTH + AS_DATA:   info->i = 0;                    break;
577   case CPUINFO_INT_ADDRBUS_WIDTH + AS_DATA:   info->i = 0;                    break;
578   case CPUINFO_INT_ADDRBUS_SHIFT + AS_DATA:   info->i = 0;                    break;
579   case CPUINFO_INT_DATABUS_WIDTH + AS_IO:     info->i = 0;                    break;
580   case CPUINFO_INT_ADDRBUS_WIDTH + AS_IO:     info->i = 0;                    break;
581   case CPUINFO_INT_ADDRBUS_SHIFT + AS_IO:     info->i = 0;                    break;
582
583   case CPUINFO_INT_SP:                            info->i = 0;    /* no SP */             break;
584   case CPUINFO_INT_PC:                            info->i = PC;                           break;
585   case CPUINFO_INT_PREVIOUSPC:                    info->i = 0;    /* TODO??? */           break;
586
587   case CPUINFO_INT_REGISTER + TX0_PC:             info->i = PC;                           break;
588   case CPUINFO_INT_REGISTER + TX0_IR:             info->i = IR;                           break;
589   case CPUINFO_INT_REGISTER + TX0_MBR:            info->i = MBR;                          break;
590   case CPUINFO_INT_REGISTER + TX0_MAR:            info->i = MAR;                          break;
591   case CPUINFO_INT_REGISTER + TX0_AC:             info->i = AC;                           break;
592   case CPUINFO_INT_REGISTER + TX0_LR:             info->i = LR;                           break;
593   case CPUINFO_INT_REGISTER + TX0_XR:             info->i = XR;                           break;
594   case CPUINFO_INT_REGISTER + TX0_PF:             info->i = PF;                           break;
595   case CPUINFO_INT_REGISTER + TX0_TBR:            info->i = cpustate->tbr;                        break;
596   case CPUINFO_INT_REGISTER + TX0_TAC:            info->i = cpustate->tac;                        break;
597   case CPUINFO_INT_REGISTER + TX0_TSS00:
598   case CPUINFO_INT_REGISTER + TX0_TSS01:
599   case CPUINFO_INT_REGISTER + TX0_TSS02:
600   case CPUINFO_INT_REGISTER + TX0_TSS03:
601   case CPUINFO_INT_REGISTER + TX0_TSS04:
602   case CPUINFO_INT_REGISTER + TX0_TSS05:
603   case CPUINFO_INT_REGISTER + TX0_TSS06:
604   case CPUINFO_INT_REGISTER + TX0_TSS07:
605   case CPUINFO_INT_REGISTER + TX0_TSS10:
606   case CPUINFO_INT_REGISTER + TX0_TSS11:
607   case CPUINFO_INT_REGISTER + TX0_TSS12:
608   case CPUINFO_INT_REGISTER + TX0_TSS13:
609   case CPUINFO_INT_REGISTER + TX0_TSS14:
610   case CPUINFO_INT_REGISTER + TX0_TSS15:
611   case CPUINFO_INT_REGISTER + TX0_TSS16:
612   case CPUINFO_INT_REGISTER + TX0_TSS17:          info->i = cpustate->tss[state-(CPUINFO_INT_REGISTER + TX0_TSS00)]; break;
613   case CPUINFO_INT_REGISTER + TX0_CM_SEL:         info->i = cpustate->cm_sel;                 break;
614   case CPUINFO_INT_REGISTER + TX0_LR_SEL:         info->i = cpustate->lr_sel;                 break;
615   case CPUINFO_INT_REGISTER + TX0_GBL_CM_SEL:     info->i = cpustate->gbl_cm_sel;             break;
616   case CPUINFO_INT_REGISTER + TX0_STOP_CYC0:      info->i = cpustate->stop_cyc0;              break;
617   case CPUINFO_INT_REGISTER + TX0_STOP_CYC1:      info->i = cpustate->stop_cyc1;              break;
618   case CPUINFO_INT_REGISTER + TX0_RUN:            info->i = cpustate->run;                        break;
619   case CPUINFO_INT_REGISTER + TX0_RIM:            info->i = cpustate->rim;                        break;
620   case CPUINFO_INT_REGISTER + TX0_CYCLE:          info->i = cpustate->cycle;                  break;
621   case CPUINFO_INT_REGISTER + TX0_IOH:            info->i = cpustate->ioh;                        break;
622   case CPUINFO_INT_REGISTER + TX0_IOS:            info->i = cpustate->ios;                        break;
623
624   /* --- the following bits of info are returned as pointers to data or functions --- */
625   case CPUINFO_FCT_SET_INFO:                      info->setinfo = CPU_SET_INFO_NAME(tx0);         break;
626   case CPUINFO_FCT_INIT:                          info->init = CPU_INIT_NAME(tx0_8kw);    break;
627   case CPUINFO_FCT_RESET:                         info->reset = CPU_RESET_NAME(tx0);      break;
628   case CPUINFO_FCT_EXECUTE:                       info->execute = CPU_EXECUTE_NAME(tx0_8kw);  break;
629   case CPUINFO_FCT_BURN:                          info->burn = NULL;                      break;
630   case CPUINFO_FCT_DISASSEMBLE:                   info->disassemble = CPU_DISASSEMBLE_NAME(tx0_8kw);      break;
631   case CPUINFO_PTR_INSTRUCTION_COUNTER:           info->icount = &cpustate->icount;               break;
632
633   /* --- the following bits of info are returned as NULL-terminated strings --- */
634   case CPUINFO_STR_NAME:                          strcpy(info->s, "TX-0");    break;
635   case CPUINFO_STR_SHORTNAME:                     strcpy(info->s, "tx0_8kw_cpu");                        break;
636   case CPUINFO_STR_FAMILY:                    strcpy(info->s, "TX-0");    break;
637   case CPUINFO_STR_VERSION:                   strcpy(info->s, "1.0"); break;
638   case CPUINFO_STR_SOURCE_FILE:                       strcpy(info->s, __FILE__);  break;
639   case CPUINFO_STR_CREDITS:                   strcpy(info->s, "Raphael Nabet");   break;
640
641   case CPUINFO_STR_FLAGS:                         strcpy(info->s, "");    break;
642
643   case CPUINFO_STR_REGISTER + TX0_PC:             sprintf(info->s, "PC:0%06o", PC); break;
644   case CPUINFO_STR_REGISTER + TX0_IR:             sprintf(info->s, "IR:0%02o", IR); break;
645   case CPUINFO_STR_REGISTER + TX0_MBR:            sprintf(info->s, "MBR:0%06o", MBR); break;
646   case CPUINFO_STR_REGISTER + TX0_MAR:            sprintf(info->s, "MAR:0%06o", MAR); break;
647   case CPUINFO_STR_REGISTER + TX0_AC:             sprintf(info->s, "AC:0%06o", AC); break;
648   case CPUINFO_STR_REGISTER + TX0_LR:             sprintf(info->s, "LR:0%06o", LR); break;
649   case CPUINFO_STR_REGISTER + TX0_XR:             sprintf(info->s, "XR:0%05o", XR); break;
650   case CPUINFO_STR_REGISTER + TX0_PF:             sprintf(info->s, "PF:0%02o", PF); break;
651   case CPUINFO_STR_REGISTER + TX0_TBR:            sprintf(info->s, "TBR:0%06o", cpustate->tbr); break;
652   case CPUINFO_STR_REGISTER + TX0_TAC:            sprintf(info->s, "TAC:0%06o", cpustate->tac); break;
653   case CPUINFO_STR_REGISTER + TX0_TSS00:
654   case CPUINFO_STR_REGISTER + TX0_TSS01:
655   case CPUINFO_STR_REGISTER + TX0_TSS02:
656   case CPUINFO_STR_REGISTER + TX0_TSS03:
657   case CPUINFO_STR_REGISTER + TX0_TSS04:
658   case CPUINFO_STR_REGISTER + TX0_TSS05:
659   case CPUINFO_STR_REGISTER + TX0_TSS06:
660   case CPUINFO_STR_REGISTER + TX0_TSS07:
661   case CPUINFO_STR_REGISTER + TX0_TSS10:
662   case CPUINFO_STR_REGISTER + TX0_TSS11:
663   case CPUINFO_STR_REGISTER + TX0_TSS12:
664   case CPUINFO_STR_REGISTER + TX0_TSS13:
665   case CPUINFO_STR_REGISTER + TX0_TSS14:
666   case CPUINFO_STR_REGISTER + TX0_TSS15:
667   case CPUINFO_STR_REGISTER + TX0_TSS16:
668   case CPUINFO_STR_REGISTER + TX0_TSS17:          sprintf(info->s, "TSS%02o:0%06o", state-(CPUINFO_STR_REGISTER + TX0_TSS00), cpustate->tss[state-(CPUINFO_STR_REGISTER + TX0_TSS00)]); break;
669   case CPUINFO_STR_REGISTER + TX0_CM_SEL:         sprintf(info->s, "CMSEL:0%06o", cpustate->cm_sel); break;
670   case CPUINFO_STR_REGISTER + TX0_LR_SEL:         sprintf(info->s, "LRSEL:0%06o", cpustate->lr_sel); break;
671   case CPUINFO_STR_REGISTER + TX0_GBL_CM_SEL:     sprintf(info->s, "GBLCMSEL:%X", cpustate->gbl_cm_sel); break;
672   case CPUINFO_STR_REGISTER + TX0_STOP_CYC0:      sprintf(info->s, "STOPCYC0:%X", cpustate->stop_cyc0); break;
673   case CPUINFO_STR_REGISTER + TX0_STOP_CYC1:      sprintf(info->s, "STOPCYC1:%X", cpustate->stop_cyc1); break;
674   case CPUINFO_STR_REGISTER + TX0_RUN:            sprintf(info->s, "RUN:%X", cpustate->run); break;
675   case CPUINFO_STR_REGISTER + TX0_RIM:            sprintf(info->s, "RIM:%X", cpustate->rim); break;
676   case CPUINFO_STR_REGISTER + TX0_CYCLE:          sprintf(info->s, "CYCLE:%X", cpustate->cycle); break;
677   case CPUINFO_STR_REGISTER + TX0_IOH:            sprintf(info->s, "IOH:%X", cpustate->ioh); break;
678   case CPUINFO_STR_REGISTER + TX0_IOS:            sprintf(info->s, "IOS:%X", cpustate->ios); break;
679   case CPUINFO_IS_OCTAL:                          info->i = true;                         break;
680   }
681}
682
683
684440/* execute one instruction */
685static void execute_instruction_64kw(device_t *device)
441void tx0_64kw_device::execute_instruction_64kw()
686442{
687   tx0_state *cpustate = get_safe_token(device);
688
689   if (! cpustate->cycle)
443   if (! m_cycle)
690444   {
691      cpustate->cycle = 1;    /* most frequent case */
445      m_cycle = 1;    /* most frequent case */
692446      switch (IR)
693447      {
694448      case 0:         /* STOre */
r26748r26749
699453         if (AC & 0400000)
700454         {
701455            PC = MAR & ADDRESS_MASK_64KW;
702            cpustate->cycle = 0;    /* instruction only takes one cycle if branch
456            m_cycle = 0;    /* instruction only takes one cycle if branch
703457                                    is taken */
704458         }
705459         break;
r26748r26749
716470         if (((MAR & 0030000) >> 12) == 1)
717471            /* (0.8) IOS In-Out Stop = Stop machine so that an In-Out command
718472                (specified by digits 6 7 8 of MAR) may be executed */
719            cpustate->ioh = 1;
473            m_ioh = 1;
720474
721475         if (((MAR & 0007000) >> 9) != 0)
722476         {
r26748r26749
750504            /* (5 is undefined) */
751505            int index = (MAR & 0007000) >> 9;
752506
753            if (cpustate->iface->io_handlers[index])
754               (*cpustate->iface->io_handlers[index])(device);
755            cpustate->ioh = 1;
507            call_io_handler(index);
508            m_ioh = 1;
756509         }
757510         break;
758511      }
759512   }
760513   else
761514   {
762      cpustate->cycle = 0;    /* always true */
515      m_cycle = 0;    /* always true */
763516      switch (IR)
764517      {
765518      case 0:         /* STOre */
766         tx0_write(cpustate, MAR, (MBR = AC));
519         tx0_write(MAR, (MBR = AC));
767520         break;
768521
769522      case 1:         /* ADD */
770         MBR = tx0_read(cpustate, MAR);
523         MBR = tx0_read(MAR);
771524
772525         AC = AC + MBR;
773526         AC = (AC + (AC >> 18)) & 0777777;   /* propagate carry around */
r26748r26749
855608
856609         if (((MAR & 0030000) >> 12) == 3)
857610            /* (1.8) Hlt = Halt the computer */
858            cpustate->run = 0;
611            m_run = 0;
859612
860613         break;
861614      }
862615   }
863616}
864617
865static void indexed_address_eval(tx0_state *cpustate)
618void tx0_device::indexed_address_eval()
866619{
867620   MAR = MAR + XR;
868621   MAR = (MAR + (MAR >> 14)) & 0037777;    /* propagate carry around */
r26748r26749
873626}
874627
875628/* execute one instruction */
876static void execute_instruction_8kw(device_t *device)
629void tx0_8kw_device::execute_instruction_8kw()
877630{
878   tx0_state *cpustate = get_safe_token(device);
879
880   if (! cpustate->cycle)
631   if (! m_cycle)
881632   {
882      cpustate->cycle = 1;    /* most frequent case */
633      m_cycle = 1;    /* most frequent case */
883634      switch (IR)
884635      {
885636      case 0:     /* STOre */
r26748r26749
903654         if (AC & 0400000)
904655         {
905656            PC = MAR & 0017777;
906            cpustate->cycle = 0;    /* instruction only takes one cycle if branch
657            m_cycle = 0;    /* instruction only takes one cycle if branch
907658                                    is taken */
908659         }
909660         break;
r26748r26749
912663         if ((AC == 0000000) || (AC == 0777777))
913664         {
914665            PC = MAR & 0017777;
915            cpustate->cycle = 0;    /* instruction only takes one cycle if branch
666            m_cycle = 0;    /* instruction only takes one cycle if branch
916667                                    is taken */
917668         }
918669         break;
r26748r26749
920671      case 18:    /* Transfer and Set indeX */
921672         XR = PC;
922673         PC = MAR & 0017777;
923         cpustate->cycle = 0;    /* instruction only takes one cycle if branch
674         m_cycle = 0;    /* instruction only takes one cycle if branch
924675                                is taken */
925676         break;
926677
r26748r26749
932683            else
933684               XR--;
934685            PC = MAR & 0017777;
935            cpustate->cycle = 0;    /* instruction only takes one cycle if branch
686            m_cycle = 0;    /* instruction only takes one cycle if branch
936687                                    is taken */
937688         }
938689         break;
939690
940691      case 21:    /* TRansfer indeXed */
941         indexed_address_eval(cpustate);
692         indexed_address_eval();
942693      case 20:    /* TRAnsfer */
943694         PC = MAR & 0017777;
944         cpustate->cycle = 0;    /* instruction only takes one cycle if branch
695         m_cycle = 0;    /* instruction only takes one cycle if branch
945696                                is taken */
946697         break;
947698
r26748r26749
949700         /*if (...)
950701         {
951702             PC = MAR & 0017777;
952             cpustate->cycle = 0;*/  /* instruction only takes one cycle if branch
703             m_cycle = 0;*/  /* instruction only takes one cycle if branch
953704                                    is taken */
954705         /*}*/
955706         break;
r26748r26749
969720               AC = 0;
970721
971722            /* (IOS???) SEL = SELect */
972            if (cpustate->iface->sel_handler)
973               (*cpustate->iface->sel_handler)(device);
723            m_sel_handler(ASSERT_LINE);
974724         }
975725         else
976726         {   /* Normal operate class instruction */
r26748r26749
1020770               /* (5 is undefined) */
1021771               int index = (MAR & 0007000) >> 9;
1022772
1023               if (cpustate->iface->io_handlers[index])
1024                  (*cpustate->iface->io_handlers[index])(device);
1025               cpustate->ioh = 1;
773               call_io_handler(index);
774               m_ioh = 1;
1026775            }
1027776
1028777            if (((IR & 001) == 00) && ((MAR & 010000) == 010000))
r26748r26749
1038787   }
1039788   else
1040789   {
1041      if (((IR != 2) && (IR != 3)) || (cpustate->cycle == 2))
1042         cpustate->cycle = 0;
790      if (((IR != 2) && (IR != 3)) || (m_cycle == 2))
791         m_cycle = 0;
1043792      else
1044         cpustate->cycle = 2;    /* SXA and ADO have an extra cycle 2 */
793         m_cycle = 2;    /* SXA and ADO have an extra cycle 2 */
1045794      switch (IR)
1046795      {
1047796      case 1:     /* STore indeXed */
1048         indexed_address_eval(cpustate);
797         indexed_address_eval();
1049798      case 0:     /* STOre */
1050         tx0_write(cpustate, MAR, (MBR = AC));
799         tx0_write(MAR, (MBR = AC));
1051800         break;
1052801
1053802      case 2:     /* Store indeX in Address */
1054         if (cpustate->cycle)
803         if (m_cycle)
1055804         {   /* cycle 1 */
1056            MBR = tx0_read(cpustate, MAR);
805            MBR = tx0_read(MAR);
1057806            MBR = (MBR & 0760000) | (XR & 0017777);
1058807         }
1059808         else
1060809         {   /* cycle 2 */
1061            tx0_write(cpustate, MAR, MBR);
810            tx0_write(MAR, MBR);
1062811         }
1063812         break;
1064813
1065814      case 3:     /* ADd One */
1066         if (cpustate->cycle)
815         if (m_cycle)
1067816         {   /* cycle 1 */
1068            AC = tx0_read(cpustate, MAR) + 1;
817            AC = tx0_read(MAR) + 1;
1069818
1070819            #if 0
1071820               AC = (AC + (AC >> 18)) & 0777777;   /* propagate carry around */
r26748r26749
1078827         }
1079828         else
1080829         {   /* cycle 2 */
1081            tx0_write(cpustate, MAR, (MBR = AC));
830            tx0_write(MAR, (MBR = AC));
1082831         }
1083832         break;
1084833
1085834      case 5:     /* Store Lr indeXed */
1086         indexed_address_eval(cpustate);
835         indexed_address_eval();
1087836      case 4:     /* Store LR */
1088         tx0_write(cpustate, MAR, (MBR = LR));
837         tx0_write(MAR, (MBR = LR));
1089838         break;
1090839
1091840      case 6:     /* STore Zero */
1092         tx0_write(cpustate, MAR, (MBR = 0));
841         tx0_write(MAR, (MBR = 0));
1093842         break;
1094843
1095844      case 9:     /* ADd indeXed */
1096         indexed_address_eval(cpustate);
845         indexed_address_eval();
1097846      case 8:     /* ADD */
1098         MBR = tx0_read(cpustate, MAR);
847         MBR = tx0_read(MAR);
1099848
1100849         AC = AC + MBR;
1101850         AC = (AC + (AC >> 18)) & 0777777;   /* propagate carry around */
r26748r26749
1105854         break;
1106855
1107856      case 10:    /* LoaD indeX */
1108         MBR = tx0_read(cpustate, MAR);
857         MBR = tx0_read(MAR);
1109858         XR = (MBR & 0017777) | ((MBR >> 4) & 0020000);
1110859         break;
1111860
1112861      case 11:    /* AUgment indeX */
1113         MBR = tx0_read(cpustate, MAR);
862         MBR = tx0_read(MAR);
1114863
1115864         XR = XR + ((MBR & 0017777) | ((MBR >> 4) & 0020000));
1116865         XR = (XR + (XR >> 14)) & 0037777;   /* propagate carry around */
r26748r26749
1120869         break;
1121870
1122871      case 13:    /* Load Lr indeXed */
1123         indexed_address_eval(cpustate);
872         indexed_address_eval();
1124873      case 12:    /* Load LR */
1125         LR = MBR = tx0_read(cpustate, MAR);
874         LR = MBR = tx0_read(MAR);
1126875         break;
1127876
1128877      case 15:    /* Load Ac indeXed */
1129         indexed_address_eval(cpustate);
878         indexed_address_eval();
1130879      case 14:    /* LoaD Ac */
1131         AC = MBR = tx0_read(cpustate, MAR);
880         AC = MBR = tx0_read(MAR);
1132881         break;
1133882
1134883      case 16:    /* TRansfer on Negative */
r26748r26749
1163912
1164913            if (((IR & 001) == 00) && ((MAR & 017000) == 001000))
1165914               /* (1.1) TAC = transfer TAC into ac (inclusive or) */
1166               AC |= cpustate->tac;
915               AC |= m_tac;
1167916
1168917            if (((IR & 001) == 00) && ((MAR & 017000) == 002000))
1169918               /* (1.2) TBR = transfer TBR into mbr (inclusive or) */
1170               MBR |= cpustate->tbr;
919               MBR |= m_tbr;
1171920
1172921            if (((IR & 001) == 00) && ((MAR & 017000) == 006000))
1173922               /* (1.2) RPF = Read Program Flag register into mbr (inclusive or) */
r26748r26749
12631012
12641013            if (((IR & 001) == 01) && ((MAR & 017000) == 010000))
12651014               /* (1.8) HLT = HaLT the computer and sound chime */
1266               cpustate->run = 0;
1015               m_run = 0;
12671016         }
12681017         break;
12691018
r26748r26749
12791028    reset most registers and flip-flops, and initialize a few emulator state
12801029    variables.
12811030*/
1282static void pulse_reset(device_t *device)
1031void tx0_device::pulse_reset()
12831032{
1284   tx0_state *cpustate = get_safe_token(device);
1285
12861033   /* processor registers */
12871034   PC = 0;         /* ??? */
12881035   IR = 0;         /* ??? */
r26748r26749
12921039   /*LR = 0;*/     /* ??? */
12931040
12941041   /* processor state flip-flops */
1295   cpustate->run = 0;      /* ??? */
1296   cpustate->rim = 0;      /* ??? */
1297   cpustate->ioh = 0;      /* ??? */
1298   cpustate->ios = 0;      /* ??? */
1042   m_run = 0;      /* ??? */
1043   m_rim = 0;      /* ??? */
1044   m_ioh = 0;      /* ??? */
1045   m_ios = 0;      /* ??? */
12991046
1300   cpustate->rim_step = 0;
1047   m_rim_step = 0;
13011048
13021049   /* now, we kindly ask IO devices to reset, too */
1303   if (cpustate->iface->io_reset_callback)
1304      (*cpustate->iface->io_reset_callback)(device);
1050   m_io_reset_callback(ASSERT_LINE);
13051051}
13061052
1307DEFINE_LEGACY_CPU_DEVICE(TX0_64KW, tx0_64kw);
1308DEFINE_LEGACY_CPU_DEVICE(TX0_8KW, tx0_8kw);
1053void tx0_device::io_complete()
1054{
1055   m_ios = 1;
1056}
1057
1058
1059offs_t tx0_8kw_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
1060{
1061   extern CPU_DISASSEMBLE( tx0_8kw );
1062   return CPU_DISASSEMBLE_NAME(tx0_8kw)(this, buffer, pc, oprom, opram, options);
1063}
1064
1065
1066offs_t tx0_64kw_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
1067{
1068   extern CPU_DISASSEMBLE( tx0_64kw );
1069   return CPU_DISASSEMBLE_NAME(tx0_64kw)(this, buffer, pc, oprom, opram, options);
1070}
1071
trunk/src/emu/cpu/pdp1/tx0.h
r26748r26749
1515   TX0_CM_SEL, TX0_LR_SEL, TX0_GBL_CM_SEL,
1616   TX0_STOP_CYC0, TX0_STOP_CYC1,
1717   TX0_RUN, TX0_RIM,
18   TX0_CYCLE, TX0_IOH, TX0_IOS,
19   TX0_RESET,          /* hack, do not use directly, use tx0_pulse_reset instead */
20   TX0_IO_COMPLETE     /* hack, do not use directly, use tx0_pulse_io_complete instead */
18   TX0_CYCLE, TX0_IOH, TX0_IOS
2119};
2220
2321
24struct tx0_reset_param_t
22#define MCFG_TX0_CONFIG(_cpy_devcb, _r1l_devcb, _dis_devcb, _r3l_devcb, _prt_devcb, _rsv_devcb, _p6h_devcb, _p7h_devcb, _sel_devcb, _res_devcb) \
23   tx0_device::set_cpy_cb(*device, DEVCB2_##_cpy_devcb); \
24   tx0_device::set_r1l_cb(*device, DEVCB2_##_r1l_devcb); \
25   tx0_device::set_dis_cb(*device, DEVCB2_##_dis_devcb); \
26   tx0_device::set_r3l_cb(*device, DEVCB2_##_r3l_devcb); \
27   tx0_device::set_prt_cb(*device, DEVCB2_##_prt_devcb); \
28   tx0_device::set_rsv_cb(*device, DEVCB2_##_rsv_devcb); \
29   tx0_device::set_p6h_cb(*device, DEVCB2_##_p6h_devcb); \
30   tx0_device::set_p7h_cb(*device, DEVCB2_##_p7h_devcb); \
31   tx0_device::set_sel_cb(*device, DEVCB2_##_sel_devcb); \
32   tx0_device::set_res_cb(*device, DEVCB2_##_res_devcb);
33
34
35class tx0_device : public cpu_device
2536{
37public:
38   // construction/destruction
39   tx0_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source, int addr_bits, int address_mask, int ir_mask);
40
41   // static configuration helpers
42   template<class _Object> static devcb2_base &set_cpy_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_cpy_handler.set_callback(object); }
43   template<class _Object> static devcb2_base &set_r1l_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_r1l_handler.set_callback(object); }
44   template<class _Object> static devcb2_base &set_dis_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_dis_handler.set_callback(object); }
45   template<class _Object> static devcb2_base &set_r3l_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_r3l_handler.set_callback(object); }
46   template<class _Object> static devcb2_base &set_prt_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_prt_handler.set_callback(object); }
47   template<class _Object> static devcb2_base &set_rsv_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_rsv_handler.set_callback(object); }
48   template<class _Object> static devcb2_base &set_p6h_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_p6h_handler.set_callback(object); }
49   template<class _Object> static devcb2_base &set_p7h_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_p7h_handler.set_callback(object); }
50   template<class _Object> static devcb2_base &set_sel_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_sel_handler.set_callback(object); }
51   template<class _Object> static devcb2_base &set_res_cb(device_t &device, _Object object) { return downcast<tx0_device &>(device).m_io_reset_callback.set_callback(object); }
52
53   void pulse_reset();
54   void io_complete();
55
56protected:
57   // device-level overrides
58   virtual void device_start();
59   virtual void device_reset();
60
61   // device_execute_interface overrides
62   virtual UINT32 execute_min_cycles() const { return 1; }
63   virtual UINT32 execute_max_cycles() const { return 3; }
64
65   // device_memory_interface overrides
66   virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_PROGRAM) ? &m_program_config : NULL; }
67
68   // device_disasm_interface overrides
69   virtual UINT32 disasm_min_opcode_bytes() const { return 4; }
70   virtual UINT32 disasm_max_opcode_bytes() const { return 4; }
71
72protected:
73   address_space_config m_program_config;
74
75   /* processor registers */
76   int m_mbr;        /* memory buffer register (18 bits) */
77   int m_ac;         /* accumulator (18 bits) */
78   int m_mar;        /* memory address register (16 (64kW) or 13 (8kW) bits) */
79   int m_pc;         /* program counter (16 (64kW) or 13 (8kW) bits) */
80   int m_ir;         /* instruction register (2 (64kW) or 5 (8kW) bits) */
81   int m_lr;         /* live register (18 bits) */
82   int m_xr;         /* index register (14 bits) (8kW only) */
83   int m_pf;         /* program flags (6 bits expandable to 10) (8kW only) */
84
85   /* operator panel switches */
86   int m_tbr;        /* toggle switch buffer register (18 bits) */
87   int m_tac;        /* toggle switch accumulator (18 bits) */
88   int m_tss[16];    /* toggle switch storage (18 bits * 16) */
89   UINT16 m_cm_sel;   /* individual cm select (1 bit * 16) */
90   UINT16 m_lr_sel;   /* individual lr select (1 bit * 16) */
91   unsigned int m_gbl_cm_sel;/* global cm select (1 bit) */
92   unsigned int m_stop_cyc0; /* stop on cycle 0 */
93   unsigned int m_stop_cyc1; /* stop on cycle 1 */
94
95   /* processor state flip-flops */
96   unsigned int m_run;       /* processor is running */
97   unsigned int m_rim;       /* processor is in read-in mode */
98   unsigned int m_cycle;     /* 0 -> fetch */
99                             /* 1 -> execute (except for taken branches) */
100                             /* 2 -> extra execute cycle for SXA and ADO */
101
102   unsigned int m_ioh;       /* i-o halt: processor is executing an Input-Output Transfer wait */
103   unsigned int m_ios;       /* i-o synchronizer: set on i-o operation completion */
104
105   /* additional emulator state variables */
106   int m_rim_step;           /* current step in rim execution */
107
108   int m_address_mask;       /* address mask */
109   int m_ir_mask;            /* IR mask */
110
111   int m_icount;
112
113   address_space *m_program;
114
26115   /* 8 standard I/O handlers:
27116       0: cpy (8kW only)
28117       1: r1l
r26748r26749
32121       5: reserved (for unimplemented typ instruction?)
33122       6: p6h
34123       7: p7h */
35   void (*io_handlers[8])(device_t *device);
124   devcb2_write_line m_cpy_handler;
125   devcb2_write_line m_r1l_handler;
126   devcb2_write_line m_dis_handler;
127   devcb2_write_line m_r3l_handler;
128   devcb2_write_line m_prt_handler;
129   devcb2_write_line m_rsv_handler;
130   devcb2_write_line m_p6h_handler;
131   devcb2_write_line m_p7h_handler;
36132   /* select instruction handler */
37   void (*sel_handler)(device_t *device);
133   devcb2_write_line m_sel_handler;
38134   /* callback called when reset line is pulsed: IO devices should reset */
39   void (*io_reset_callback)(device_t *device);
135   devcb2_write_line m_io_reset_callback;
136
137   int tx0_read(offs_t address);
138   void tx0_write(offs_t address, int data);
139   void call_io_handler(int io_handler);
140   void indexed_address_eval();
40141};
41142
42/* PUBLIC FUNCTIONS */
43DECLARE_LEGACY_CPU_DEVICE(TX0_64KW, tx0_64kw);
44DECLARE_LEGACY_CPU_DEVICE(TX0_8KW, tx0_8kw);
45143
46CPU_DISASSEMBLE( tx0_64kw );
47CPU_DISASSEMBLE( tx0_8kw );
144class tx0_8kw_device : public tx0_device
145{
146public:
147   // construction/destruction
148   tx0_8kw_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
48149
150protected:
151   virtual void execute_run();
152   virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
153
154private:
155   void execute_instruction_8kw();
156};
157
158
159class tx0_64kw_device : public tx0_device
160{
161public:
162   // construction/destruction
163   tx0_64kw_device(const machine_config &mconfig, const char *_tag, device_t *_owner, UINT32 _clock);
164
165protected:
166   virtual void execute_run();
167   virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
168
169private:
170   void execute_instruction_64kw();
171};
172
173
174extern const device_type TX0_64KW;
175extern const device_type TX0_8KW;
176
49177#endif /* __TX0_H__ */
trunk/src/mess/drivers/tx0.c
r26748r26749
301301      colortable_entry_set_value(machine().colortable, total_colors_needed + i, tx0_palette[i]);
302302}
303303
304static void tx0_io_cpy(device_t *device);
305static void tx0_io_r1l(device_t *device);
306static void tx0_io_r3l(device_t *device);
307static void tx0_io_p6h(device_t *device);
308static void tx0_io_p7h(device_t *device);
309static void tx0_io_prt(device_t *device);
310static void tx0_io_dis(device_t *device);
311static void tx0_sel(device_t *device);
312static void tx0_io_reset_callback(device_t *device);
313304
314static const tx0_reset_param_t tx0_reset_param =
315{
316   {
317      tx0_io_cpy,
318      tx0_io_r1l,
319      tx0_io_dis,
320      tx0_io_r3l,
321      tx0_io_prt,
322      /*tx0_io_typ*/NULL,
323      tx0_io_p6h,
324      tx0_io_p7h
325   },
326   tx0_sel,
327   tx0_io_reset_callback
328};
329
330305static const crt_interface tx0_crt_interface =
331306{
332307   pen_crt_num_levels,
r26748r26749
705680/*
706681    Initiate read of a 6-bit word from tape
707682*/
708static void tx0_io_r1l(device_t *device)
683WRITE_LINE_MEMBER( tx0_state::tx0_io_r1l )
709684{
710   tx0_state *state = device->machine().driver_data<tx0_state>();
711   state->begin_tape_read( 0);
685   begin_tape_read( 0);
712686}
713687
714688/*
715689    Initiate read of a 18-bit word from tape (used in read-in mode)
716690*/
717static void tx0_io_r3l(device_t *device)
691WRITE_LINE_MEMBER( tx0_state::tx0_io_r3l )
718692{
719   tx0_state *state = device->machine().driver_data<tx0_state>();
720   state->begin_tape_read(1);
693   begin_tape_read(1);
721694}
722695
723696/*
724697    Write a 7-bit word to tape (7th bit clear)
725698*/
726static void tx0_io_p6h(device_t *device)
699WRITE_LINE_MEMBER( tx0_state::tx0_io_p6h )
727700{
728   tx0_state *state = device->machine().driver_data<tx0_state>();
729701   int ac;
730702
731703   /* read current AC */
732   ac = device->state().state_int(TX0_AC);
704   ac = m_maincpu->state_int(TX0_AC);
733705   /* shuffle and punch 6-bit word */
734   state->tape_write(((ac & 0100000) >> 15) | ((ac & 0010000) >> 11) | ((ac & 0001000) >> 7) | ((ac & 0000100) >> 3) | ((ac & 0000010) << 1) | ((ac & 0000001) << 5));
706   tape_write(((ac & 0100000) >> 15) | ((ac & 0010000) >> 11) | ((ac & 0001000) >> 7) | ((ac & 0000100) >> 3) | ((ac & 0000010) << 1) | ((ac & 0000001) << 5));
735707
736   state->m_tape_puncher.timer->adjust(attotime::from_usec(15800));
708   m_tape_puncher.timer->adjust(attotime::from_usec(15800));
737709}
738710
739711/*
740712    Write a 7-bit word to tape (7th bit set)
741713*/
742static void tx0_io_p7h(device_t *device)
714WRITE_LINE_MEMBER( tx0_state::tx0_io_p7h )
743715{
744   tx0_state *state = device->machine().driver_data<tx0_state>();
745716   int ac;
746717
747718   /* read current AC */
748   ac = device->state().state_int(TX0_AC);
719   ac = m_maincpu->state_int(TX0_AC);
749720   /* shuffle and punch 6-bit word */
750   state->tape_write(((ac & 0100000) >> 15) | ((ac & 0010000) >> 11) | ((ac & 0001000) >> 7) | ((ac & 0000100) >> 3) | ((ac & 0000010) << 1) | ((ac & 0000001) << 5) | 0100);
721   tape_write(((ac & 0100000) >> 15) | ((ac & 0010000) >> 11) | ((ac & 0001000) >> 7) | ((ac & 0000100) >> 3) | ((ac & 0000010) << 1) | ((ac & 0000001) << 5) | 0100);
751722
752   state->m_tape_puncher.timer->adjust(attotime::from_usec(15800));
723   m_tape_puncher.timer->adjust(attotime::from_usec(15800));
753724}
754725
755726
r26748r26749
793764*/
794765TIMER_CALLBACK_MEMBER(tx0_state::prt_callback)
795766{
796   m_maincpu->set_state_int(TX0_IOS,1);
767   m_maincpu->io_complete();
797768}
798769
799770/*
800771    prt io callback
801772*/
802static void tx0_io_prt(device_t *device)
773WRITE_LINE_MEMBER( tx0_state::tx0_io_prt )
803774{
804   tx0_state *state = device->machine().driver_data<tx0_state>();
805775   int ac;
806776   int ch;
807777
808778   /* read current AC */
809   ac = device->state().state_int(TX0_AC);
779   ac = m_maincpu->state_int(TX0_AC);
810780   /* shuffle and print 6-bit word */
811781   ch = ((ac & 0100000) >> 15) | ((ac & 0010000) >> 11) | ((ac & 0001000) >> 7) | ((ac & 0000100) >> 3) | ((ac & 0000010) << 1) | ((ac & 0000001) << 5);
812   state->typewriter_out(ch);
782   typewriter_out(ch);
813783
814   state->m_typewriter.prt_timer->adjust(attotime::from_msec(100));
784   m_typewriter.prt_timer->adjust(attotime::from_msec(100));
815785}
816786
817787
r26748r26749
820790*/
821791TIMER_CALLBACK_MEMBER(tx0_state::dis_callback)
822792{
823   m_maincpu->set_state_int(TX0_IOS,1);
793   m_maincpu->io_complete();
824794}
825795
826796/*
827797    Plot one point on crt
828798*/
829static void tx0_io_dis(device_t *device)
799WRITE_LINE_MEMBER( tx0_state::tx0_io_dis )
830800{
831   tx0_state *state = device->machine().driver_data<tx0_state>();
832801   int ac;
833802   int x;
834803   int y;
835804
836   ac = device->state().state_int(TX0_AC);
805   ac = m_maincpu->state_int(TX0_AC);
837806   x = ac >> 9;
838807   y = ac & 0777;
839   state->tx0_plot(x, y);
808   tx0_plot(x, y);
840809
841   state->m_dis_timer->adjust(attotime::from_usec(50));
810   m_dis_timer->adjust(attotime::from_usec(50));
842811}
843812
844813
r26748r26749
944913   }
945914}
946915
947static void magtape_callback(device_t *device)
916void tx0_state::magtape_callback()
948917{
949   tx0_state *state = device->machine().driver_data<tx0_state>();
950918   UINT8 buf = 0;
951919   int lr;
952920
953   switch (state->m_magtape.state)
921   switch (m_magtape.state)
954922   {
955923   case MTS_UNSELECTING:
956      state->m_magtape.state = MTS_UNSELECTED;
924      m_magtape.state = MTS_UNSELECTED;
957925
958926   case MTS_UNSELECTED:
959      if (state->m_magtape.sel_pending)
927      if (m_magtape.sel_pending)
960928      {
961929         int mar;
962930
963         mar = device->state().state_int(TX0_MAR);
931         mar = m_maincpu->state_int(TX0_MAR);
964932
965933         if ((mar & 03) != 1)
966934         {   /* unimplemented device: remain in unselected state and set rwc
967935                flag? */
968            device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_RWC);
936            m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_RWC);
969937         }
970938         else
971939         {
972            state->m_magtape.state = MTS_SELECTING;
940            m_magtape.state = MTS_SELECTING;
973941
974            state->m_magtape.command = (mar & 014 >> 2);
942            m_magtape.command = (mar & 014 >> 2);
975943
976            state->m_magtape.binary_flag = (mar & 020 >> 4);
944            m_magtape.binary_flag = (mar & 020 >> 4);
977945
978            if (state->m_magtape.img)
979               state->schedule_select();
946            if (m_magtape.img)
947               schedule_select();
980948         }
981949
982         state->m_magtape.sel_pending = FALSE;
983         device->state().set_state_int(TX0_IOS,1);
950         m_magtape.sel_pending = FALSE;
951         m_maincpu->io_complete();
984952      }
985953      break;
986954
987955   case MTS_SELECTING:
988      state->m_magtape.state = MTS_SELECTED;
989      switch (state->m_magtape.command)
956      m_magtape.state = MTS_SELECTED;
957      switch (m_magtape.command)
990958      {
991959      case 0: /* backspace */
992         state->m_magtape.long_parity = 0177;
993         state->m_magtape.u.backspace_state = MTBSS_STATE0;
960         m_magtape.long_parity = 0177;
961         m_magtape.u.backspace_state = MTBSS_STATE0;
994962         break;
995963      case 1: /* read */
996         state->m_magtape.long_parity = 0177;
997         state->m_magtape.u.read.state = MTRDS_STATE0;
964         m_magtape.long_parity = 0177;
965         m_magtape.u.read.state = MTRDS_STATE0;
998966         break;
999967      case 2: /* rewind */
1000968         break;
1001969      case 3: /* write */
1002         state->m_magtape.long_parity = 0177;
1003         state->m_magtape.u.write.state = MTWTS_STATE0;
1004         switch (state->m_magtape.irg_pos)
970         m_magtape.long_parity = 0177;
971         m_magtape.u.write.state = MTWTS_STATE0;
972         switch (m_magtape.irg_pos)
1005973         {
1006974         case MTIRGP_START:
1007            state->m_magtape.u.write.counter = 150;
975            m_magtape.u.write.counter = 150;
1008976            break;
1009977         case MTIRGP_ENDMINUS1:
1010            state->m_magtape.u.write.counter = 1;
978            m_magtape.u.write.counter = 1;
1011979            break;
1012980         case MTIRGP_END:
1013            state->m_magtape.u.write.counter = 0;
981            m_magtape.u.write.counter = 0;
1014982            break;
1015983         }
1016984         break;
1017985      }
1018986
1019987   case MTS_SELECTED:
1020      switch (state->m_magtape.command)
988      switch (m_magtape.command)
1021989      {
1022990      case 0: /* backspace */
1023         if (state->m_magtape.img->ftell() == 0)
991         if (m_magtape.img->ftell() == 0)
1024992         {   /* tape at ldp */
1025            state->m_magtape.state = MTS_UNSELECTING;
1026            device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_RWC);
1027            state->schedule_unselect();
993            m_magtape.state = MTS_UNSELECTING;
994            m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_RWC);
995            schedule_unselect();
1028996         }
1029         else if (state->m_magtape.img->fseek( -1, SEEK_CUR))
997         else if (m_magtape.img->fseek( -1, SEEK_CUR))
1030998         {   /* eject tape */
1031            state->m_magtape.img->unload();
999            m_magtape.img->unload();
10321000         }
1033         else if (state->m_magtape.img->fread(&buf, 1) != 1)
1001         else if (m_magtape.img->fread(&buf, 1) != 1)
10341002         {   /* eject tape */
1035            state->m_magtape.img->unload();
1003            m_magtape.img->unload();
10361004         }
1037         else if (state->m_magtape.img->fseek( -1, SEEK_CUR))
1005         else if (m_magtape.img->fseek( -1, SEEK_CUR))
10381006         {   /* eject tape */
1039            state->m_magtape.img->unload();
1007            m_magtape.img->unload();
10401008         }
10411009         else
10421010         {
10431011            buf &= 0x7f;    /* 7-bit tape, ignore 8th bit */
1044            state->m_magtape.long_parity ^= buf;
1045            switch (state->m_magtape.u.backspace_state)
1012            m_magtape.long_parity ^= buf;
1013            switch (m_magtape.u.backspace_state)
10461014            {
10471015            case MTBSS_STATE0:
10481016               /* STATE0 -> initial interrecord gap, longitudinal parity;
10491017               if longitudinal parity was all 0s, gap between longitudinal
10501018               parity and data, first byte of data */
10511019               if (buf != 0)
1052                  state->m_magtape.u.backspace_state = MTBSS_STATE1;
1020                  m_magtape.u.backspace_state = MTBSS_STATE1;
10531021               break;
10541022            case MTBSS_STATE1:
10551023               /* STATE1 -> first byte of gap between longitudinal parity and
10561024               data, second byte of data */
10571025               if (buf == 0)
1058                  state->m_magtape.u.backspace_state = MTBSS_STATE2;
1026                  m_magtape.u.backspace_state = MTBSS_STATE2;
10591027               else
1060                  state->m_magtape.u.backspace_state = MTBSS_STATE5;
1028                  m_magtape.u.backspace_state = MTBSS_STATE5;
10611029               break;
10621030            case MTBSS_STATE2:
10631031               /* STATE2 -> second byte of gap between longitudinal parity and
10641032               data */
10651033               if (buf == 0)
1066                  state->m_magtape.u.backspace_state = MTBSS_STATE3;
1034                  m_magtape.u.backspace_state = MTBSS_STATE3;
10671035               else
10681036               {
10691037                  logerror("tape seems to be corrupt\n");
10701038                  /* eject tape */
1071                  state->m_magtape.img->unload();
1039                  m_magtape.img->unload();
10721040               }
10731041               break;
10741042            case MTBSS_STATE3:
10751043               /* STATE3 -> third byte of gap between longitudinal parity and
10761044               data */
10771045               if (buf == 0)
1078                  state->m_magtape.u.backspace_state = MTBSS_STATE4;
1046                  m_magtape.u.backspace_state = MTBSS_STATE4;
10791047               else
10801048               {
10811049                  logerror("tape seems to be corrupt\n");
10821050                  /* eject tape */
1083                  state->m_magtape.img->unload();
1051                  m_magtape.img->unload();
10841052               }
10851053               break;
10861054            case MTBSS_STATE4:
r26748r26749
10881056               interrecord gap after data */
10891057               if (buf == 0)
10901058               {
1091                  if (state->m_magtape.long_parity)
1059                  if (m_magtape.long_parity)
10921060                     logerror("invalid longitudinal parity\n");
10931061                  /* set EOR and unselect... */
1094                  state->m_magtape.state = MTS_UNSELECTING;
1095                  device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_EOR);
1096                  state->schedule_unselect();
1097                  state->m_magtape.irg_pos = MTIRGP_ENDMINUS1;
1062                  m_magtape.state = MTS_UNSELECTING;
1063                  m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_EOR);
1064                  schedule_unselect();
1065                  m_magtape.irg_pos = MTIRGP_ENDMINUS1;
10981066               }
10991067               else
1100                  state->m_magtape.u.backspace_state = MTBSS_STATE5;
1068                  m_magtape.u.backspace_state = MTBSS_STATE5;
11011069               break;
11021070            case MTBSS_STATE5:
11031071               /* STATE5 -> second byte of data word */
r26748r26749
11051073               {
11061074                  logerror("tape seems to be corrupt\n");
11071075                  /* eject tape */
1108                  state->m_magtape.img->unload();
1076                  m_magtape.img->unload();
11091077               }
11101078               else
1111                  state->m_magtape.u.backspace_state = MTBSS_STATE6;
1079                  m_magtape.u.backspace_state = MTBSS_STATE6;
11121080               break;
11131081            case MTBSS_STATE6:
11141082               /* STATE6 -> third byte of data word */
r26748r26749
11161084               {
11171085                  logerror("tape seems to be corrupt\n");
11181086                  /* eject tape */
1119                  state->m_magtape.img->unload();
1087                  m_magtape.img->unload();
11201088               }
11211089               else
1122                  state->m_magtape.u.backspace_state = MTBSS_STATE6;
1090                  m_magtape.u.backspace_state = MTBSS_STATE6;
11231091               break;
11241092            }
1125            if (state->m_magtape.state != MTS_UNSELECTING)
1126               state->m_magtape.timer->adjust(attotime::from_usec(66));
1093            if (m_magtape.state != MTS_UNSELECTING)
1094               m_magtape.timer->adjust(attotime::from_usec(66));
11271095         }
11281096         break;
11291097
11301098      case 1: /* read */
1131         if (state->m_magtape.img->fread(&buf, 1) != 1)
1099         if (m_magtape.img->fread(&buf, 1) != 1)
11321100         {   /* I/O error or EOF? */
11331101            /* The MAME fileio layer makes it very hard to make the
11341102            difference...  MAME seems to assume that I/O errors never
11351103            happen, whereas it is really easy to cause one by
11361104            deconnecting an external drive the image is located on!!! */
11371105            UINT64 offs;
1138            offs = state->m_magtape.img->ftell();
1139            if (state->m_magtape.img->fseek( 0, SEEK_END) || (offs != state->m_magtape.img->ftell()))
1106            offs = m_magtape.img->ftell();
1107            if (m_magtape.img->fseek( 0, SEEK_END) || (offs != m_magtape.img->ftell()))
11401108            {   /* I/O error */
11411109               /* eject tape */
1142               state->m_magtape.img->unload();
1110               m_magtape.img->unload();
11431111            }
11441112            else
11451113            {   /* end of tape -> ??? */
11461114               /* maybe we run past end of tape, so that tape is ejected from
11471115               upper reel and unit becomes unavailable??? */
1148               /*state->m_magtape.img->unload();*/
1116               /*m_magtape.img->unload();*/
11491117               /* Or do we stop at EOT mark??? */
1150               state->m_magtape.state = MTS_UNSELECTING;
1151               device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_EOT);
1152               state->schedule_unselect();
1118               m_magtape.state = MTS_UNSELECTING;
1119               m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_EOT);
1120               schedule_unselect();
11531121            }
11541122         }
11551123         else
11561124         {
11571125            buf &= 0x7f;    /* 7-bit tape, ignore 8th bit */
1158            state->m_magtape.long_parity ^= buf;
1159            switch (state->m_magtape.u.read.state)
1126            m_magtape.long_parity ^= buf;
1127            switch (m_magtape.u.read.state)
11601128            {
11611129            case MTRDS_STATE0:
11621130               /* STATE0 -> interrecord blank or first byte of data */
11631131               if (buf != 0)
11641132               {
1165                  if (state->m_magtape.cpy_pending)
1133                  if (m_magtape.cpy_pending)
11661134                  {   /* read command */
1167                     state->m_magtape.u.read.space_flag = FALSE;
1168                     device->state().set_state_int(TX0_IOS,1);
1169                     device->state().set_state_int(TX0_LR, ((device->state().state_int(TX0_LR) >> 1) & 0333333)
1135                     m_magtape.u.read.space_flag = FALSE;
1136                     m_maincpu->set_state_int(TX0_IOS,1);
1137                     m_maincpu->set_state_int(TX0_LR, ((m_maincpu->state_int(TX0_LR) >> 1) & 0333333)
11701138                                          | ((buf & 040) << 12) | ((buf & 020) << 10) | ((buf & 010) << 8) | ((buf & 004) << 6) | ((buf & 002) << 4) | ((buf & 001) << 2));
11711139                     /* check parity */
1172                     if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ state->m_magtape.binary_flag))
1173                        device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_PC);
1140                     if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ m_magtape.binary_flag))
1141                        m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_PC);
11741142                  }
11751143                  else
11761144                  {   /* space command */
1177                     state->m_magtape.u.read.space_flag = TRUE;
1145                     m_magtape.u.read.space_flag = TRUE;
11781146                  }
1179                  state->m_magtape.u.read.state = MTRDS_STATE1;
1147                  m_magtape.u.read.state = MTRDS_STATE1;
11801148               }
11811149               break;
11821150            case MTRDS_STATE1:
r26748r26749
11851153               {
11861154                  logerror("tape seems to be corrupt\n");
11871155                  /* eject tape */
1188                  state->m_magtape.img->unload();
1156                  m_magtape.img->unload();
11891157               }
1190               if (!state->m_magtape.u.read.space_flag)
1158               if (!m_magtape.u.read.space_flag)
11911159               {
1192                  device->state().set_state_int(TX0_LR, ((device->state().state_int(TX0_LR) >> 1) & 0333333)
1160                  m_maincpu->set_state_int(TX0_LR, ((m_maincpu->state_int(TX0_LR) >> 1) & 0333333)
11931161                                       | ((buf & 040) << 12) | ((buf & 020) << 10) | ((buf & 010) << 8) | ((buf & 004) << 6) | ((buf & 002) << 4) | ((buf & 001) << 2));
11941162                  /* check parity */
1195                  if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ state->m_magtape.binary_flag))
1196                     device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_PC);
1163                  if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ m_magtape.binary_flag))
1164                     m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_PC);
11971165               }
1198               state->m_magtape.u.read.state = MTRDS_STATE2;
1166               m_magtape.u.read.state = MTRDS_STATE2;
11991167               break;
12001168            case MTRDS_STATE2:
12011169               /* STATE2 -> third byte of data word */
r26748r26749
12031171               {
12041172                  logerror("tape seems to be corrupt\n");
12051173                  /* eject tape */
1206                  state->m_magtape.img->unload();
1174                  m_magtape.img->unload();
12071175               }
1208               if (!state->m_magtape.u.read.space_flag)
1176               if (!m_magtape.u.read.space_flag)
12091177               {
1210                  device->state().set_state_int(TX0_LR, ((device->state().state_int(TX0_LR) >> 1) & 0333333)
1178                  m_maincpu->set_state_int(TX0_LR, ((m_maincpu->state_int(TX0_LR) >> 1) & 0333333)
12111179                                       | ((buf & 040) << 12) | ((buf & 020) << 10) | ((buf & 010) << 8) | ((buf & 004) << 6) | ((buf & 002) << 4) | ((buf & 001) << 2));
12121180                  /* check parity */
1213                  if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ state->m_magtape.binary_flag))
1214                     device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_PC);
1181                  if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ m_magtape.binary_flag))
1182                     m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_PC);
12151183                  /* synchronize with cpy instruction */
1216                  if (state->m_magtape.cpy_pending)
1217                     device->state().set_state_int(TX0_IOS,1);
1184                  if (m_magtape.cpy_pending)
1185                     m_maincpu->set_state_int(TX0_IOS,1);
12181186                  else
1219                     device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_RWC);
1187                     m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_RWC);
12201188               }
1221               state->m_magtape.u.read.state = MTRDS_STATE3;
1189               m_magtape.u.read.state = MTRDS_STATE3;
12221190               break;
12231191            case MTRDS_STATE3:
12241192               /* STATE3 -> first byte of new word of data, or first byte
12251193               of gap between data and longitudinal parity */
12261194               if (buf != 0)
12271195               {
1228                  state->m_magtape.u.read.state = MTRDS_STATE1;
1229                  if (!state->m_magtape.u.read.space_flag)
1196                  m_magtape.u.read.state = MTRDS_STATE1;
1197                  if (!m_magtape.u.read.space_flag)
12301198                  {
1231                     device->state().set_state_int(TX0_LR, ((device->state().state_int(TX0_LR) >> 1) & 0333333)
1199                     m_maincpu->set_state_int(TX0_LR, ((m_maincpu->state_int(TX0_LR) >> 1) & 0333333)
12321200                                          | ((buf & 040) << 12) | ((buf & 020) << 10) | ((buf & 010) << 8) | ((buf & 004) << 6) | ((buf & 002) << 4) | ((buf & 001) << 2));
12331201                     /* check parity */
1234                     if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ state->m_magtape.binary_flag))
1235                        device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_PC);
1202                     if (! (((buf ^ (buf >> 1) ^ (buf >> 2) ^ (buf >> 3) ^ (buf >> 4) ^ (buf >> 5) ^ (buf >> 6) ^ (buf >> 7)) & 1) ^ m_magtape.binary_flag))
1203                        m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_PC);
12361204                  }
12371205               }
12381206               else
1239                  state->m_magtape.u.read.state = MTRDS_STATE4;
1207                  m_magtape.u.read.state = MTRDS_STATE4;
12401208               break;
12411209            case MTRDS_STATE4:
12421210               /* STATE4 -> second byte of gap between data and
r26748r26749
12451213               {
12461214                  logerror("tape seems to be corrupt\n");
12471215                  /* eject tape */
1248                  state->m_magtape.img->unload();
1216                  m_magtape.img->unload();
12491217               }
12501218               else
1251                  state->m_magtape.u.read.state = MTRDS_STATE5;
1219                  m_magtape.u.read.state = MTRDS_STATE5;
12521220               break;
12531221
12541222            case MTRDS_STATE5:
r26748r26749
12581226               {
12591227                  logerror("tape seems to be corrupt\n");
12601228                  /* eject tape */
1261                  state->m_magtape.img->unload();
1229                  m_magtape.img->unload();
12621230               }
12631231               else
1264                  state->m_magtape.u.read.state = MTRDS_STATE6;
1232                  m_magtape.u.read.state = MTRDS_STATE6;
12651233               break;
12661234
12671235            case MTRDS_STATE6:
12681236               /* STATE6 -> longitudinal parity */
12691237               /* check parity */
1270               if (state->m_magtape.long_parity)
1238               if (m_magtape.long_parity)
12711239               {
12721240                  logerror("invalid longitudinal parity\n");
12731241                  /* no idea if the original tx-0 magtape controller
12741242                  checks parity, but can't harm if we do */
1275                  device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_PC);
1243                  m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_PC);
12761244               }
12771245               /* set EOR and unselect... */
1278               state->m_magtape.state = MTS_UNSELECTING;
1279               device->state().set_state_int(TX0_PF, device->state().state_int(TX0_PF) | PF_EOR);
1280               state->schedule_unselect();
1281               state->m_magtape.irg_pos = MTIRGP_START;
1246               m_magtape.state = MTS_UNSELECTING;
1247               m_maincpu->set_state_int(TX0_PF, m_maincpu->state_int(TX0_PF) | PF_EOR);
1248               schedule_unselect();
1249               m_magtape.irg_pos = MTIRGP_START;
12821250               break;
12831251            }
1284            if (state->m_magtape.state != MTS_UNSELECTING)
1285               state->m_magtape.timer->adjust(attotime::from_usec(66));
1252            if (m_magtape.state != MTS_UNSELECTING)
1253               m_magtape.timer->adjust(attotime::from_usec(66));
12861254         }
12871255         break;
12881256
12891257      case 2: /* rewind */
1290         state->m_magtape.state = MTS_UNSELECTING;
1258         m_magtape.state = MTS_UNSELECTING;
12911259         /* we rewind at 10*read speed (I don't know the real value) */
1292         state->m_magtape.timer->adjust((attotime::from_nsec(6600) * state->m_magtape.img->ftell()));
1260         m_magtape.timer->adjust((attotime::from_nsec(6600) * m_magtape.img->ftell()));
12931261         //schedule_unselect(state);
1294         state->m_magtape.img->fseek( 0, SEEK_END);
1295         state->m_magtape.irg_pos = MTIRGP_END;
1262         m_magtape.img->fseek( 0, SEEK_END);
1263         m_magtape.irg_pos = MTIRGP_END;
12961264         break;
12971265
12981266      case 3: /* write */
1299         switch (state->m_magtape.u.write.state)
1267         switch (m_magtape.u.write.state)
13001268         {
13011269         case MTWTS_STATE0:
1302            if (state->m_magtape.u.write.counter != 0)
1270            if (m_magtape.u.write.counter != 0)
13031271            {
1304               state->m_magtape.u.write.counter--;
1272               m_magtape.u.write.counter--;
13051273               buf = 0;
13061274               break;
13071275            }
13081276            else
13091277            {
1310               state->m_magtape.u.write.state = MTWTS_STATE1;
1278               m_magtape.u.write.state = MTWTS_STATE1;
13111279            }
13121280
13131281         case MTWTS_STATE1:
1314            if (state->m_magtape.u.write.counter)
1282            if (m_magtape.u.write.counter)
13151283            {
1316               state->m_magtape.u.write.counter--;
1317               lr = device->state().state_int(TX0_LR);
1284               m_magtape.u.write.counter--;
1285               lr = m_maincpu->state_int(TX0_LR);
13181286               buf = ((lr >> 10) & 040) | ((lr >> 8) & 020) | ((lr >> 6) & 010) | ((lr >> 4) & 004) | ((lr >> 2) & 002) | (lr & 001);
1319               buf |= ((buf << 1) ^ (buf << 2) ^ (buf << 3) ^ (buf << 4) ^ (buf << 5) ^ (buf << 6) ^ ((!state->m_magtape.binary_flag) << 6)) & 0100;
1320               device->state().set_state_int(TX0_LR, lr >> 1);
1287               buf |= ((buf << 1) ^ (buf << 2) ^ (buf << 3) ^ (buf << 4) ^ (buf << 5) ^ (buf << 6) ^ ((!m_magtape.binary_flag) << 6)) & 0100;
1288               m_maincpu->set_state_int(TX0_LR, lr >> 1);
13211289            }
13221290            else
13231291            {
1324               if (state->m_magtape.cpy_pending)
1292               if (m_magtape.cpy_pending)
13251293               {
1326                  device->state().set_state_int(TX0_IOS,1);
1327                  lr = device->state().state_int(TX0_LR);
1294                  m_maincpu->set_state_int(TX0_IOS,1);
1295                  lr = m_maincpu->state_int(TX0_LR);
13281296                  buf = ((lr >> 10) & 040) | ((lr >> 8) & 020) | ((lr >> 6) & 010) | ((lr >> 4) & 004) | ((lr >> 2) & 002) | (lr & 001);
1329                  buf |= ((buf << 1) ^ (buf << 2) ^ (buf << 3) ^ (buf << 4) ^ (buf << 5) ^ (buf << 6) ^ ((!state->m_magtape.binary_flag) << 6)) & 0100;
1330                  device->state().set_state_int(TX0_LR, lr >> 1);
1331                  state->m_magtape.u.write.counter = 2;
1297                  buf |= ((buf << 1) ^ (buf << 2) ^ (buf << 3) ^ (buf << 4) ^ (buf << 5) ^ (buf << 6) ^ ((!m_magtape.binary_flag) << 6)) & 0100;
1298                  m_maincpu->set_state_int(TX0_LR, lr >> 1);
1299                  m_magtape.u.write.counter = 2;
13321300                  break;
13331301               }
13341302               else
13351303               {
1336                  state->m_magtape.u.write.state = MTWTS_STATE2;
1337                  state->m_magtape.u.write.counter = 3;
1304                  m_magtape.u.write.state = MTWTS_STATE2;
1305                  m_magtape.u.write.counter = 3;
13381306               }
13391307            }
13401308
13411309         case MTWTS_STATE2:
1342            if (state->m_magtape.u.write.counter != 0)
1310            if (m_magtape.u.write.counter != 0)
13431311            {
1344               state->m_magtape.u.write.counter--;
1312               m_magtape.u.write.counter--;
13451313               buf = 0;
13461314               break;
13471315            }
13481316            else
13491317            {
1350               buf = state->m_magtape.long_parity;
1351               state->m_magtape.state = (state_t)MTWTS_STATE3;
1352               state->m_magtape.u.write.counter = 150;
1318               buf = m_magtape.long_parity;
1319               m_magtape.state = (state_t)MTWTS_STATE3;
1320               m_magtape.u.write.counter = 150;
13531321            }
13541322            break;
13551323
13561324         case MTWTS_STATE3:
1357            if (state->m_magtape.u.write.counter != 0)
1325            if (m_magtape.u.write.counter != 0)
13581326            {
1359               state->m_magtape.u.write.counter--;
1327               m_magtape.u.write.counter--;
13601328               buf = 0;
13611329               break;
13621330            }
13631331            else
13641332            {
1365               state->m_magtape.state = MTS_UNSELECTING;
1366               state->schedule_unselect();
1367               state->m_magtape.irg_pos = MTIRGP_END;
1333               m_magtape.state = MTS_UNSELECTING;
1334               schedule_unselect();
1335               m_magtape.irg_pos = MTIRGP_END;
13681336            }
13691337            break;
13701338         }
1371         if (state->m_magtape.state != MTS_UNSELECTING)
1339         if (m_magtape.state != MTS_UNSELECTING)
13721340         {   /* write data word */
1373            state->m_magtape.long_parity ^= buf;
1374            if (state->m_magtape.img->fwrite(&buf, 1) != 1)
1341            m_magtape.long_parity ^= buf;
1342            if (m_magtape.img->fwrite(&buf, 1) != 1)
13751343            {   /* I/O error */
13761344               /* eject tape */
1377               state->m_magtape.img->unload();
1345               m_magtape.img->unload();
13781346            }
13791347            else
1380               state->m_magtape.timer->adjust(attotime::from_usec(66));
1348               m_magtape.timer->adjust(attotime::from_usec(66));
13811349         }
13821350         break;
13831351      }
r26748r26749
13851353   }
13861354}
13871355
1388static void tx0_sel(device_t *device)
1356WRITE_LINE_MEMBER( tx0_state::tx0_sel )
13891357{
1390   tx0_state *state = device->machine().driver_data<tx0_state>();
1391   state->m_magtape.sel_pending = TRUE;
1358   m_magtape.sel_pending = TRUE;
13921359
1393   if (state->m_magtape.state == MTS_UNSELECTED)
1360   if (m_magtape.state == MTS_UNSELECTED)
13941361   {
13951362      if (0)
1396         magtape_callback(device);
1397      state->m_magtape.timer->adjust(attotime::zero);
1363         magtape_callback();
1364      m_magtape.timer->adjust(attotime::zero);
13981365   }
13991366}
14001367
1401static void tx0_io_cpy(device_t *device)
1368WRITE_LINE_MEMBER( tx0_state::tx0_io_cpy )
14021369{
1403   tx0_state *state = device->machine().driver_data<tx0_state>();
1404   switch (state->m_magtape.state)
1370   switch (m_magtape.state)
14051371   {
14061372   case MTS_UNSELECTED:
14071373   case MTS_UNSELECTING:
14081374      /* ignore instruction and set rwc flag? */
1409      device->state().set_state_int(TX0_IOS,1);
1375      m_maincpu->io_complete();
14101376      break;
14111377
14121378   case MTS_SELECTING:
14131379   case MTS_SELECTED:
1414      switch (state->m_magtape.command)
1380      switch (m_magtape.command)
14151381      {
14161382      case 0: /* backspace */
14171383      case 2: /* rewind */
14181384         /* ignore instruction and set rwc flag? */
1419         device->state().set_state_int(TX0_IOS,1);
1385         m_maincpu->io_complete();
14201386         break;
14211387      case 1: /* read */
14221388      case 3: /* write */
1423         state->m_magtape.cpy_pending = TRUE;
1389         m_magtape.cpy_pending = TRUE;
14241390         break;
14251391      }
14261392      break;
r26748r26749
14331399
14341400    IO devices should reset
14351401*/
1436static void tx0_io_reset_callback(device_t *device)
1402WRITE_LINE_MEMBER( tx0_state::tx0_io_reset_callback )
14371403{
1438   tx0_state *state = device->machine().driver_data<tx0_state>();
1439   state->m_tape_reader.rcl = state->m_tape_reader.rc = 0;
1440   if (state->m_tape_reader.timer)
1441      state->m_tape_reader.timer->enable(0);
1404   m_tape_reader.rcl = m_tape_reader.rc = 0;
1405   if (m_tape_reader.timer)
1406      m_tape_reader.timer->enable(0);
14421407
1443   if (state->m_tape_puncher.timer)
1444      state->m_tape_puncher.timer->enable(0);
1408   if (m_tape_puncher.timer)
1409      m_tape_puncher.timer->enable(0);
14451410
1446   if (state->m_typewriter.prt_timer)
1447      state->m_typewriter.prt_timer->enable(0);
1411   if (m_typewriter.prt_timer)
1412      m_typewriter.prt_timer->enable(0);
14481413
1449   if (state->m_dis_timer)
1450      state->m_dis_timer->enable(0);
1414   if (m_dis_timer)
1415      m_dis_timer->enable(0);
14511416}
14521417
14531418
r26748r26749
15371502      }
15381503      if (control_transitions & tx0_read_in)
15391504      {   /* set cpu to read instructions from perforated tape */
1540         m_maincpu->set_state_int(TX0_RESET, (UINT64)0);
1505         m_maincpu->pulse_reset();
15411506         m_maincpu->set_state_int(TX0_RUN, (UINT64)0);
15421507         m_maincpu->set_state_int(TX0_RIM, 1);
15431508      }
r26748r26749
16001565   /* basic machine hardware */
16011566   /* TX0 CPU @ approx. 167 kHz (no master clock, but the memory cycle time is approximately 6usec) */
16021567   MCFG_CPU_ADD("maincpu", TX0_64KW, 166667)
1603   MCFG_CPU_CONFIG(tx0_reset_param)
1568   MCFG_TX0_CONFIG(
1569      WRITELINE( tx0_state, tx0_io_cpy ),
1570      WRITELINE( tx0_state, tx0_io_r1l ),
1571      WRITELINE( tx0_state, tx0_io_dis ),
1572      WRITELINE( tx0_state, tx0_io_r3l ),
1573      WRITELINE( tx0_state, tx0_io_prt ),
1574      NULL,
1575      WRITELINE( tx0_state, tx0_io_p6h ),
1576      WRITELINE( tx0_state, tx0_io_p7h ),
1577      WRITELINE( tx0_state, tx0_sel ),
1578      WRITELINE( tx0_state, tx0_io_reset_callback )
1579   )
16041580   MCFG_CPU_PROGRAM_MAP(tx0_64kw_map)
16051581   /* dummy interrupt: handles input */
16061582   MCFG_CPU_VBLANK_INT_DRIVER("screen", tx0_state,  tx0_interrupt)
r26748r26749
16321608   /* TX0 CPU @ approx. 167 kHz (no master clock, but the memory cycle time is
16331609   approximately 6usec) */
16341610   MCFG_CPU_MODIFY("maincpu")
1635   MCFG_CPU_CONFIG(tx0_reset_param)
16361611   MCFG_CPU_PROGRAM_MAP(tx0_8kw_map)
16371612   /*MCFG_CPU_PORTS(readport, writeport)*/
16381613MACHINE_CONFIG_END
trunk/src/mess/includes/tx0.h
r26748r26749
88#define TX0_H_
99
1010#include "video/crt.h"
11#include "cpu/pdp1/tx0.h"
1112
1213enum state_t
1314{
r26748r26749
161162   TIMER_CALLBACK_MEMBER(prt_callback);
162163   TIMER_CALLBACK_MEMBER(dis_callback);
163164   void tx0_machine_stop();
164   required_device<cpu_device> m_maincpu;
165   required_device<tx0_device> m_maincpu;
165166   inline void tx0_plot_pixel(bitmap_ind16 &bitmap, int x, int y, UINT32 color);
166167   void tx0_plot(int x, int y);
167168   void tx0_draw_led(bitmap_ind16 &bitmap, int x, int y, int state);
r26748r26749
183184   void schedule_select();
184185   void schedule_unselect();
185186   void tx0_keyboard();
187   DECLARE_WRITE_LINE_MEMBER(tx0_io_cpy);
188   DECLARE_WRITE_LINE_MEMBER(tx0_io_r1l);
189   DECLARE_WRITE_LINE_MEMBER(tx0_io_r3l);
190   DECLARE_WRITE_LINE_MEMBER(tx0_io_p6h);
191   DECLARE_WRITE_LINE_MEMBER(tx0_io_p7h);
192   DECLARE_WRITE_LINE_MEMBER(tx0_io_prt);
193   DECLARE_WRITE_LINE_MEMBER(tx0_io_dis);
194   DECLARE_WRITE_LINE_MEMBER(tx0_sel);
195   DECLARE_WRITE_LINE_MEMBER(tx0_io_reset_callback);
196   void magtape_callback();
186197};
187198
188199/* defines for each bit and mask in input port "CSW" */

Previous 199869 Revisions Next


© 1997-2024 The MAME Team