Previous 199869 Revisions Next

r33654 Wednesday 3rd December, 2014 at 17:32:20 UTC by Jürgen Buchmüller
Rewrote Rockwell PPS-4 CPU core based on bitsavers.org documents
[src/emu/cpu/pps4]pps4.c pps4.h pps4dasm.c

trunk/src/emu/cpu/pps4/pps4.c
r242165r242166
11// license:BSD-3-Clause
2// copyright-holders:Miodrag Milanovic
2// copyright-holders:Juergen Buchmueller <pullmoll@t-online.de>
3
34/*****************************************************************************
45 *
56 *   pps4.c
r242165r242166
3132#include "debugger.h"
3233#include "pps4.h"
3334
34#define VERBOSE 0
3535
36#define LOG(x) do { if (VERBOSE) logerror x; } while (0)
36#define VERBOSE 0       //!< set to 1 to log certain instruction conditions
3737
38#if VERBOSE
39#define LOG(x) logerror x
40#else
41#define LOG(x)
42#endif
3843
3944const device_type PPS4 = &device_creator<pps4_device>;
4045
41
4246pps4_device::pps4_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
43   : cpu_device(mconfig, PPS4, "PPS4", tag, owner, clock, "pps4", __FILE__ )
44   , m_program_config("program", ENDIANNESS_LITTLE, 8, 12)
45   , m_data_config("data", ENDIANNESS_LITTLE, 8, 12)  // 4bit RAM
46   , m_io_config("io", ENDIANNESS_LITTLE, 8, 8)  // 4bit IO
47    : cpu_device(mconfig, PPS4, "PPS4", tag, owner, clock, "pps4", __FILE__ )
48    , m_program_config("program", ENDIANNESS_LITTLE, 8, 12)
49    , m_data_config("data", ENDIANNESS_LITTLE, 8, 12)  // 4bit RAM
50    , m_io_config("io", ENDIANNESS_LITTLE, 8, 8)  // 4bit IO
4751{
4852}
4953
54/**
55 * @brief pps4_device::M Return the memory at address B
56 * @return ROM/RAM(B)
57 */
58UINT8 pps4_device::M()
59{
60    UINT8 ret = m_data->read_byte(m_B & ~m_SAG);
61    m_SAG = 0;
62    return ret;
63}
5064
65
66/**
67 * @brief pps4_device::W Write to the memory address at B
68 * @return ROM/RAM(B)
69 */
70void pps4_device::W(UINT8 data)
71{
72    m_data->write_byte(m_B & ~m_SAG, data);
73    m_SAG = 0;
74}
75
5176offs_t pps4_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options)
5277{
53   extern CPU_DISASSEMBLE( pps4 );
54   return CPU_DISASSEMBLE_NAME(pps4)(this, buffer, pc, oprom, opram, options);
78    extern CPU_DISASSEMBLE( pps4 );
79    return CPU_DISASSEMBLE_NAME(pps4)(this, buffer, pc, oprom, opram, options);
5580}
5681
57
82/**
83 * @brief pps4_device::ROP Read the next opcode (instruction)
84 * @return m_I
85 */
5886inline UINT8 pps4_device::ROP()
5987{
60   UINT8 retVal = m_direct->read_decrypted_byte(m_P.w.l);
61   m_P.w.l = (m_P.w.l + 1) & 0x0fff;
62   return retVal;
88    m_Ip = m_I & 0xf0;      // set previous opcode mask
89    m_I = m_direct->read_decrypted_byte(m_P & 0xFFF);
90    m_P = (m_P + 1) & 0xFFF;
91    m_icount -= 1;
92    return m_I;
6393}
6494
95/**
96 * @brief pps4_device::ARG Read the next argument (instrunction 2)
97 * @return m_I2
98 */
6599inline UINT8 pps4_device::ARG()
66100{
67   UINT8 retVal = m_direct->read_raw_byte(m_P.w.l);
68   m_P.w.l = (m_P.w.l + 1) & 0x0fff;
69   return retVal;
101    m_I2 = m_direct->read_raw_byte(m_P & 0xFFF);
102    m_P = (m_P + 1) & 0xFFF;
103    m_icount -= 1;
104    return m_I2;
70105}
71106
72inline void pps4_device::DO_SKIP()
107/**
108 * @brief Note3
109 *
110 * Instructions ADI, LD, EX, EXD, LDI, LB and LBL have a numeric
111 * value coded as part of the instruction in the immediate field.
112 * This numeric value must be in complementary form on the bus.
113 * All of these immediate fields which are inverted are shown
114 * in brackets.
115 * For example: ADI 1, as written by the programmer who wishes
116 * to add one to the value in the accumulator, is converted to
117 * 0x6E = 01001 [1110]; the bracketed binary value is the value
118 * as seen on the data bus.
119 * If the programmer is using the Rockwell Assembler he does not
120 * have to manually determine the proper inverted value as the
121 * assembler does this for him.
122 *
123 * [And we do in MAME as well :-]
124 */
125
126/**
127 * @brief pps4_device::iAD Add
128 * OPCODE     cycles  mnemonic
129 * -----------------------------
130 * 0000 1011  1 cyc   AD
131 *
132 * Symbolic equation
133 * -----------------------------
134 * C, A <- A + M
135 *
136 * The result of the binary addition of contents of accumulator
137 * and 4-bit contents of RAM currently addressed by B register,
138 * replaces the contents of the accumulator. The resulting
139 * carry-out is loaded into C flip-flop.
140 */
141void pps4_device::iAD()
73142{
74   m_P.w.l = (m_P.w.l + 1) & 0x0fff;
143    m_A = m_A + M();
144    m_C = m_A >> 4;
145    m_A = m_A & 15;
75146}
76147
77void pps4_device::execute_one(int opcode)
148/**
149 * @brief pps4_device::iADC Add with carry-in
150 * OPCODE     cycles  mnemonic
151 * -----------------------------
152 * 0000 1010  1 cyc   ADC
153 *
154 * Symbolic equation
155 * -----------------------------
156 * C, A <- A + M + C
157 *
158 * Same as AD except the C flip-flop serves as a carry-in
159 * to the adder.
160 */
161void pps4_device::iADC()
78162{
79   m_icount -= 1;
80   switch (opcode)
81   {
82      // Arithmetic instructions
83      case 0x0b:  // AD
84               break;
85      case 0x0a:  // ADC
86               break;
87      case 0x09:  // ADSK
88               break;
89      case 0x08:  // ADCSK
90               break;
91      case 0x60:  case 0x61:  case 0x62:  case 0x63:
92      case 0x64:  case 0x66:  case 0x67:  case 0x68:
93      case 0x69:  case 0x6a:  case 0x6b:  case 0x6c:
94      case 0x6d:  case 0x6e:
95               // ADI
96               break;
97      case 0x65:  //DC
98               m_A = (m_A + 10) & 0x0f;
99               break;
100      // Logical instructions
101      case 0x0d:  // AND
102               break;
103      case 0x0f:  // OR
104               break;
105      case 0x0c:  // EOR
106               break;
107      case 0x0e:  // COMP
108               m_A ^= 0x0f;
109               break;
110      // Data transfer instructions
111      case 0x20:  // SC
112               m_C = 1;
113               break;
114      case 0x24:  //RC
115               m_C = 0;
116               break;
117      case 0x22:  // SF1
118               m_FF1 = 1;
119               break;
120      case 0x26:  // RF1
121               m_FF1 = 0;
122               break;
123      case 0x21:  // SF2
124               m_FF2 = 1;
125               break;
126      case 0x25:  // RF2
127               m_FF2 = 0;
128               break;
129      case 0x30:  case 0x31:  case 0x32:  case 0x33:
130      case 0x34:  case 0x35:  case 0x36:  case 0x37:
131               // LD
132               break;
133      case 0x38:  case 0x39:  case 0x3a:  case 0x3b:
134      case 0x3c:  case 0x3d:  case 0x3e:  case 0x3f:
135               // EX
136               break;
137      case 0x28:  case 0x29:  case 0x2a:  case 0x2b:
138      case 0x2c:  case 0x2d:  case 0x2e:  case 0x2f:
139               // EXD
140               break;
141      case 0x70:  case 0x71:  case 0x72:  case 0x73:
142      case 0x74:  case 0x75:  case 0x76:  case 0x77:
143      case 0x78:  case 0x79:  case 0x7a:  case 0x7b:
144      case 0x7c:  case 0x7d:  case 0x7e:  case 0x7f:
145               // LDI
146               m_A = opcode & 0x0f;
147               break;
148      case 0x12:  // LAX
149               m_A = m_X;
150               break;
151      case 0x1b:  // LXA
152               m_X = m_A;
153               break;
154      case 0x11:  // LABL
155               m_A = m_B.w.l & 0x00f;
156               break;
157      case 0x10:  // LBMX
158               m_B.w.l &= 0xf0f;
159               m_B.w.l |= (m_X << 4);
160               break;
161      case 0x04:  // LBUA
162               break;
163      case 0x19:  // XABL
164               {
165                  UINT8 tmp = m_B.w.l & 0x00f;
166                  m_B.w.l &= 0xff0;
167                  m_B.w.l |= m_A;
168                  m_A = tmp;
169               }
170               break;
171      case 0x18:  // XBMX
172               {
173                  UINT8 tmp = (m_B.w.l & 0x0f0) >> 4;
174                  m_B.w.l &= 0xf0f;
175                  m_B.w.l |= (m_X << 4);
176                  m_X = tmp;
177               }
178               break;
179      case 0x1a:  // XAX
180               {
181                  UINT8 tmp = m_A;
182                  m_A = m_X;
183                  m_X = tmp;
184               }
185               break;
186      case 0x06:  // XS
187               {
188                  PAIR tmp = m_SA;
189                  m_SA = m_SB;
190                  m_SB = tmp;
191               }
192               break;
193      case 0x6f:  // CYS
194               break;
195      case 0xc0:  case 0xc1:  case 0xc2:  case 0xc3:
196      case 0xc4:  case 0xc5:  case 0xc6:  case 0xc7:
197      case 0xc8:  case 0xc9:  case 0xca:  case 0xcb:
198      case 0xcc:  case 0xcd:  case 0xce:  case 0xcf:
199               // LB
200               {
201                  //UINT8 tmp = ARG();
202                  m_icount -= 1;
203               }
204               break;
205      case 0x00:  // LBL
206               {
207                  UINT8 tmp = ARG();
208                  m_icount -= 1;
209                  m_B.w.l = tmp;
210               }
211               break;
212      case 0x17:  // INCB
213               if ((m_B.w.l & 0x0f) == 0x0f) {
214                  m_B.w.l &= 0xff0;
215                  DO_SKIP();
216               } else {
217                  m_B.w.l += 1;
218               }
219               break;
220      case 0x1f:  // DECB
221               if ((m_B.w.l & 0x0f) == 0x00) {
222                  m_B.w.l |= 0x00f;
223                  DO_SKIP();
224               } else {
225                  m_B.w.l -= 1;
226               }
227               break;
228      // Control transfer instructions
229      case 0x80:  case 0x81:  case 0x82:  case 0x83:
230      case 0x84:  case 0x85:  case 0x86:  case 0x87:
231      case 0x88:  case 0x89:  case 0x8a:  case 0x8b:
232      case 0x8c:  case 0x8d:  case 0x8e:  case 0x8f:
233      case 0x90:  case 0x91:  case 0x92:  case 0x93:
234      case 0x94:  case 0x95:  case 0x96:  case 0x97:
235      case 0x98:  case 0x99:  case 0x9a:  case 0x9b:
236      case 0x9c:  case 0x9d:  case 0x9e:  case 0x9f:
237      case 0xa0:  case 0xa1:  case 0xa2:  case 0xa3:
238      case 0xa4:  case 0xa5:  case 0xa6:  case 0xa7:
239      case 0xa8:  case 0xa9:  case 0xaa:  case 0xab:
240      case 0xac:  case 0xad:  case 0xae:  case 0xaf:
241      case 0xb0:  case 0xb1:  case 0xb2:  case 0xb3:
242      case 0xb4:  case 0xb5:  case 0xb6:  case 0xb7:
243      case 0xb8:  case 0xb9:  case 0xba:  case 0xbb:
244      case 0xbc:  case 0xbd:  case 0xbe:  case 0xbf:
245               // T
246               m_P.w.l = (m_P.w.l & 0xfc0) | (opcode & 0x3f);
247               break;
248      case 0xd0:  case 0xd1:  case 0xd2:  case 0xd3:
249      case 0xd4:  case 0xd5:  case 0xd6:  case 0xd7:
250      case 0xd8:  case 0xd9:  case 0xda:  case 0xdb:
251      case 0xdc:  case 0xdd:  case 0xde:  case 0xdf:
252      case 0xe0:  case 0xe1:  case 0xe2:  case 0xe3:
253      case 0xe4:  case 0xe5:  case 0xe6:  case 0xe7:
254      case 0xe8:  case 0xe9:  case 0xea:  case 0xeb:
255      case 0xec:  case 0xed:  case 0xee:  case 0xef:
256      case 0xf0:  case 0xf1:  case 0xf2:  case 0xf3:
257      case 0xf4:  case 0xf5:  case 0xf6:  case 0xf7:
258      case 0xf8:  case 0xf9:  case 0xfa:  case 0xfb:
259      case 0xfc:  case 0xfd:  case 0xfe:  case 0xff:
260               // TM
261               break;
262      case 0x50:  case 0x51:  case 0x52:  case 0x53:
263      case 0x54:  case 0x55:  case 0x56:  case 0x57:
264      case 0x58:  case 0x59:  case 0x5a:  case 0x5b:
265      case 0x5c:  case 0x5d:  case 0x5e:  case 0x5f:
266               // TL
267               {
268                  //UINT8 tmp = ARG();
269                  m_icount -= 1;
270               }
271               break;
272      case 0x01:  case 0x02:  case 0x03:
273               // TML
274               {
275                  //UINT8 tmp = ARG();
276                  m_icount -= 1;
277               }
278               break;
279      case 0x15:  // SKC
280               break;
281      case 0x1e:  // SKZ
282               break;
283      case 0x40:  case 0x41:  case 0x42:  case 0x43:
284      case 0x44:  case 0x45:  case 0x46:  case 0x47:
285      case 0x48:  case 0x49:  case 0x4a:  case 0x4b:
286      case 0x4c:  case 0x4d:  case 0x4e:  case 0x4f:
287               // SKBI
288               break;
289      case 0x16:  // SKF1
290               break;
291      case 0x14:  // SKF2
292               break;
293      case 0x05:  // RTN
294               break;
295      case 0x07:  // RTNSK
296               break;
297      // Input/Output instructions
298      case 0x1c:  // IOL
299               {
300                  //UINT8 tmp = ARG();
301                  m_icount -= 1;
302               }
303               break;
304      case 0x27:  // DIA
305               break;
306      case 0x23:  // DIB
307               break;
308      case 0x1d:  // DOA
309               break;
310      // Special instructions
311      case 0x13:  // SAG
312               break;
313   }
163    m_A = m_A + M() + m_C;
164    m_C = m_A >> 4;
165    m_A = m_A & 15;
314166}
315167
168/**
169 * @brief pps4_device::iADSK Add and skip if carry-out
170 * OPCODE     cycles  mnemonic
171 * -----------------------------
172 * 0000 1001  1 cyc   ADSK
173 *
174 * Symbolic equation
175 * -----------------------------
176 * C, A <- A + M
177 * Skip if C = 1
178 *
179 * Same as AD except the next ROM word will be
180 * skipped (ignored) if a carry-out is generated.
181 */
182void pps4_device::iADSK()
183{
184    m_A = m_A + M();
185    m_C = m_A >> 4;
186    m_A = m_A & 15;
187    m_P = (m_P + m_C) & 0xFFF;
188}
316189
190/**
191 * @brief pps4_device::iADCSK Add with carry-in and skip if carry-out
192 * OPCODE     cycles  mnemonic
193 * -----------------------------
194 * 0000 1000  1 cyc   ADCSK
195 *
196 * Symbolic equation
197 * -----------------------------
198 * C, A <- A + M + C
199 * Skip if C = 1
200 *
201 * Same as ADC except the next ROM word will be
202 * skipped (ignored) if a carry-out is generated.
203 */
204void pps4_device::iADCSK()
205{
206    m_A = m_A + M() + m_C;
207    m_C = m_A >> 4;
208    m_A = m_A & 15;
209    m_P = (m_P + m_C) & 0xFFF;
210}
211
212/**
213 * @brief pps4_device::iAND Logical AND
214 * OPCODE     cycles  mnemonic
215 * -----------------------------
216 * 0000 1101  1 cyc   AND
217 *
218 * Symbolic equation
219 * -----------------------------
220 * A <- A & M
221 *
222 * The result of logical AND of accumulator and
223 * 4-bit contents of RAM currently addressed by
224 * B register replaces contents of accumulator.
225 */
226void pps4_device::iAND()
227{
228    m_A = m_A & M();
229}
230
231/**
232 * @brief pps4_device::iADI Add immediate
233 * OPCODE     cycles  mnemonic
234 * -----------------------------
235 * 0110 xxxx  1 cyc   ADI #x
236 *
237 * Symbolic equation
238 * -----------------------------
239 * A <- A + [I(4:1)]
240 *
241 * The result of the binary addition of contents of
242 * accumulator and 4-bit immediate field of instruction
243 * word replaces the contents of accumulator.
244 * The next ROM word will be skipped (ignored) if a
245 * carry-out is generated.
246 * __ The instruction does not use or change the C flip-flop. __
247 * The immediate field I(4:1) of this instruction may not
248 * be equal to binary 0 (CYS) or 0101 (DC)
249 *
250 * See %Note3
251 */
252void pps4_device::iADI()
253{
254    const UINT8 imm = ~m_I & 15;
255    m_A = m_A + imm;
256    m_P = m_P + (m_A > 15) ? 1 : 0;
257    m_A = m_A & 15;
258    m_P = m_P & 0xFFF;
259}
260
261/**
262 * @brief pps4_device::iDC Decimal correction
263 * OPCODE     cycles  mnemonic
264 * -----------------------------
265 * 0110 0110  1 cyc   DC
266 *
267 * Symbolic equation
268 * -----------------------------
269 * A <- A + 1010b
270 *
271 * Decimal correction of accumulator.
272 * Binary 1010 is added to the contents of the accumulator.
273 * Result is stored in accumulator. Instruction does not
274 * use or change carry flip-flop or skip.
275 */
276void pps4_device::iDC()
277{
278    m_A = m_A + 10;
279}
280
281/**
282 * @brief pps4_device::iOR Logical OR
283 * OPCODE     cycles  mnemonic
284 * -----------------------------
285 * 0000 1111  1 cyc   OR
286 *
287 * Symbolic equation
288 * -----------------------------
289 * A <- A | M
290 *
291 * The result of logical OIR of accumulator and
292 * 4-bit contents of RAM currently addressed by
293 * B register replaces contents of accumulator.
294 */
295void pps4_device::iOR()
296{
297    m_A = m_A | M();
298}
299
300/**
301 * @brief pps4_device::iEOR Logical exclusive-OR
302 * OPCODE     cycles  mnemonic
303 * -----------------------------
304 * 0000 1100  1 cyc   EOR
305 *
306 * Symbolic equation
307 * -----------------------------
308 * A <- A ^ M
309 *
310 * The result of logical exclusive-OR of
311 * accumulator and 4-bit contents of RAM
312 * currently addressed by B register
313 * replaces contents of accumulator.
314 */
315void pps4_device::iEOR()
316{
317    m_A = m_A ^ M();
318}
319
320/**
321 * @brief pps4_device::iCOMP Complement
322 * OPCODE     cycles  mnemonic
323 * -----------------------------
324 * 0000 1110  1 cyc   COMP
325 *
326 * Symbolic equation
327 * -----------------------------
328 * A <- ~A
329 *
330 * Each bit of the accumulator is logically
331 * complemented and placed in accumulator.
332 */
333void pps4_device::iCOMP()
334{
335    m_A = ~m_A & 15;
336}
337
338/**
339 * @brief pps4_device::iSC Set carry flip-flop
340 * OPCODE     cycles  mnemonic
341 * -----------------------------
342 * 0010 0000  1 cyc   SC
343 *
344 * Symbolic equation
345 * -----------------------------
346 * C <- 1
347 *
348 * The C flip-flop is set to 1.
349 */
350void pps4_device::iSC()
351{
352    m_C = 1;
353}
354
355/**
356 * @brief pps4_device::iRC Reset carry flip-flop
357 * OPCODE     cycles  mnemonic
358 * -----------------------------
359 * 0010 0100  1 cyc   RC
360 *
361 * Symbolic equation
362 * -----------------------------
363 * C <- 0
364 *
365 * The C flip-flop is set to 0.
366 */
367void pps4_device::iRC()
368{
369    m_C = 0;
370}
371
372/**
373 * @brief pps4_device::iSF1 Set flip-flop FF1
374 * OPCODE     cycles  mnemonic
375 * -----------------------------
376 * 0010 0010  1 cyc   SF1
377 *
378 * Symbolic equation
379 * -----------------------------
380 * FF1 <- 1
381 *
382 * The Flip-flop FF1 is set to 1.
383 */
384void pps4_device::iSF1()
385{
386    m_FF1 = 1;
387}
388
389/**
390 * @brief pps4_device::iRF1 Reset flip-flop FF1
391 * OPCODE     cycles  mnemonic
392 * -----------------------------
393 * 0010 0100  1 cyc   RF1
394 *
395 * Symbolic equation
396 * -----------------------------
397 * FF1 <- 0
398 *
399 * The Flip-flop FF1 is set to 0.
400 */
401void pps4_device::iRF1()
402{
403    m_FF1 = 0;
404}
405
406/**
407 * @brief pps4_device::iSF2 Set flip-flop FF2
408 * OPCODE     cycles  mnemonic
409 * -----------------------------
410 * 0010 0001  1 cyc   SF2
411 *
412 * Symbolic equation
413 * -----------------------------
414 * FF2 <- 1
415 *
416 * The Flip-flop FF2 is set to 1.
417 */
418void pps4_device::iSF2()
419{
420    m_FF2 = 1;
421}
422
423/**
424 * @brief pps4_device::iRF2 Reset flip-flop FF2
425 * OPCODE     cycles  mnemonic
426 * -----------------------------
427 * 0010 0101  1 cyc   RF2
428 *
429 * Symbolic equation
430 * -----------------------------
431 * FF2 <- 0
432 *
433 * The flip-flop FF2 is set to 0.
434 */
435void pps4_device::iRF2()
436{
437    m_FF2 = 0;
438}
439
440/**
441 * @brief pps4_device::iLD Load accumulator from memory
442 * OPCODE     cycles  mnemonic
443 * -----------------------------
444 * 0011 0xxx  1 cyc   LDx
445 *
446 * Symbolic equation
447 * -----------------------------
448 * A <- M
449 * B(7:5) <- B(7:5) ^ [I(3:1)]
450 *
451 * The 4-bit contents of RAM currently addressed
452 * by B register are placed in the accumulator.
453 * The RAM address in the B register is then
454 * modified by the result of an exclusive-OR of
455 * the 3-b it immediate field I(3:1) and B(7:5)
456 *
457 * See %Note3
458 */
459void pps4_device::iLD()
460{
461    const UINT16 imm = ~m_I & 7;
462    m_A = M();
463    m_B = m_B ^ (imm << 4);
464}
465
466/**
467 * @brief pps4_device::iEX Exchange accumulator and memory
468 * OPCODE     cycles  mnemonic
469 * -----------------------------
470 * 0011 1xxx  1 cyc   EXx
471 *
472 * Symbolic equation
473 * -----------------------------
474 * A <-> M
475 * B(7:5) <- B(7:5) ^ [I(3:1)]
476 *
477 * The same as LD except the contents of accumulator
478 * are also placed in currently addressed RAM location.
479 *
480 * See %Note3
481 */
482void pps4_device::iEX()
483{
484    const UINT16 imm = ~m_I & 7;
485    const UINT8 mem = M();
486    W(m_A);
487    m_A = mem;
488    m_B = m_B ^ (imm << 4);
489}
490
491/**
492 * @brief pps4_device::iEXD Exchange accumulator and memory and decrement BL
493 * OPCODE     cycles  mnemonic
494 * -----------------------------
495 * 0010 1xxx  1 cyc   EXD x
496 *
497 * Symbolic equation
498 * -----------------------------
499 * A <-> M
500 * B(7:5) <- B(7:5) ^ [I(3:1)]
501 * BL <- BL - 1
502 * Skip on BL = 1111b
503 *
504 * The same as EX except RAM address in B register
505 * is further modified by decrementing BL by 1.
506 * If the new contents of BL is 1111, the next
507 * ROM word will be ignored.
508 *
509 * See %Note3
510 */
511void pps4_device::iEXD()
512{
513    const UINT8 imm = ~m_I & 7;
514    const UINT8 mem = M();
515    UINT8 bl = m_B & 15;
516    W(m_A);
517    m_A = mem;
518    m_B = m_B ^ (imm << 4);
519    if (0 == bl) {
520        // decrement BL wraps to 1111b
521        bl = 15;
522        m_P = (m_P + 1) & 0xFFF;
523    } else {
524        // decrement BL
525        bl = bl - 1;
526    }
527    m_B = (m_B & ~15) | bl;
528}
529
530/**
531 * @brief pps4_device::iLDI Load accumualtor immediate
532 * OPCODE     cycles  mnemonic
533 * -----------------------------
534 * 0111 xxxx  1 cyc   LDI x
535 *
536 * Symbolic equation
537 * -----------------------------
538 * A <- [I(4:1)]
539 *
540 * The 4-bit contents, immediate field I(4:1),
541 * of the instruction are placed in the accumulator.
542 *
543 * Note: Only the first occurence of an LDI in a consecutive
544 * string of LDIs will be executed. The program will ignore
545 * remaining LDIs and execute next valid instruction.
546 *
547 * See %Note3
548 */
549void pps4_device::iLDI()
550{
551    // previous LDI instruction?
552    if (0x70 == m_Ip) {
553        LOG(("%s: skip prev:%02x\n", __FUNCTION__, m_Ip));
554        return;
555    }
556    m_A = ~m_I & 15;
557}
558
559/**
560 * @brief pps4_device::iLAX
561 * OPCODE     cycles  mnemonic
562 * -----------------------------
563 * 0001 0010  1 cyc   LAX
564 *
565 * Symbolic equation
566 * -----------------------------
567 * A <- X
568 *
569 * The 4-bit contents of the X register are
570 * placed in the accumulator.
571 */
572void pps4_device::iLAX()
573{
574    m_A = m_X;
575}
576
577/**
578 * @brief pps4_device::iLXA
579 * OPCODE     cycles  mnemonic
580 * -----------------------------
581 * 0001 1011  1 cyc   LAX
582 *
583 * Symbolic equation
584 * -----------------------------
585 * X <- A
586 *
587 * The contents of the accumulator are
588 * tansferred to the X register.
589 */
590void pps4_device::iLXA()
591{
592    m_X = m_A;
593}
594
595/**
596 * @brief pps4_device::iLABL
597 * OPCODE     cycles  mnemonic
598 * -----------------------------
599 * 0001 0001  1 cyc   LABL
600 *
601 * Symbolic equation
602 * -----------------------------
603 * A <- BL
604 *
605 * The contents of BL register are
606 * tansferred to the accumulator.
607 */
608void pps4_device::iLABL()
609{
610    m_A = m_B & 15;
611}
612
613/**
614 * @brief pps4_device::iLBMX
615 * OPCODE     cycles  mnemonic
616 * -----------------------------
617 * 0001 0000  1 cyc   LBMX
618 *
619 * Symbolic equation
620 * -----------------------------
621 * BM <- X
622 *
623 * The contents of X register are
624 * tansferred to BM register.
625 */
626void pps4_device::iLBMX()
627{
628    m_B = (m_B & ~(15 << 4)) | (m_X << 4);
629}
630
631/**
632 * @brief pps4_device::iLBUA
633 * OPCODE     cycles  mnemonic
634 * -----------------------------
635 * 0001 0000  1 cyc   LBUA
636 *
637 * Symbolic equation
638 * -----------------------------
639 * BU <- A
640 * A <- M
641 *
642 * The contents of accumulator are tansferred to
643 * BU register. Also, the contents of the currently
644 * addressed RAM are transferred to accumulator.
645 */
646void pps4_device::iLBUA()
647{
648    m_B = (m_B & ~(15 << 8)) | (m_A << 8);
649    m_A = M();
650}
651
652/**
653 * @brief pps4_device::iXABL
654 * OPCODE     cycles  mnemonic
655 * -----------------------------
656 * 0001 1001  1 cyc   XABL
657 *
658 * Symbolic equation
659 * -----------------------------
660 * A <-> BL
661 *
662 * The contents of accumulator and BL register
663 * are exchanged.
664 */
665void pps4_device::iXABL()
666{
667    // swap A and BL
668    UINT8 bl = m_B & 15;
669    m_B = (m_B & ~15) | m_A;
670    m_A = bl;
671}
672
673/**
674 * @brief pps4_device::iXMBX
675 * OPCODE     cycles  mnemonic
676 * -----------------------------
677 * 0001 1000  1 cyc   XMBX
678 *
679 * Symbolic equation
680 * -----------------------------
681 * X <-> BM
682 *
683 * The contents of accumulator and BL register
684 * are exchanged.
685 */
686void pps4_device::iXBMX()
687{
688    // swap X and BM
689    UINT8 bm = (m_B >> 4) & 15;
690    m_B = (m_B & ~(15 << 4)) | (m_X << 4);
691    m_X = bm;
692}
693
694/**
695 * @brief pps4_device::iXAX
696 * OPCODE     cycles  mnemonic
697 * -----------------------------
698 * 0001 1010  1 cyc   XAX
699 *
700 * Symbolic equation
701 * -----------------------------
702 * A <-> X
703 *
704 * The contents of accumulator and X register
705 * are exchanged.
706 */
707void pps4_device::iXAX()
708{
709    // swap A and X
710    m_A ^= m_X;
711    m_X ^= m_A;
712    m_A ^= m_X;
713}
714
715/**
716 * @brief pps4_device::iXS
717 * OPCODE     cycles  mnemonic
718 * -----------------------------
719 * 0000 0110  1 cyc   XS
720 *
721 * Symbolic equation
722 * -----------------------------
723 * SA <-> SB
724 *
725 * The 12-bit contents of SA and SB register
726 * are exchanged.
727 */
728void pps4_device::iXS()
729{
730    // swap SA and SB
731    m_SA ^= m_SB;
732    m_SB ^= m_SA;
733    m_SA ^= m_SB;
734}
735
736/**
737 * @brief pps4_device::iCYS
738 * OPCODE     cycles  mnemonic
739 * -----------------------------
740 * 0110 1111  1 cyc    CYS
741 *
742 * Symbolic equation
743 * -----------------------------
744 * A <- SA(4:1)
745 * SA(4:1) <- SA(8:5)
746 * SA(8:5) <- SA(12:9)
747 * SA(12:9) <- A
748 *
749 * A 4-bit right shift of the SA register takes place
750 * with the four bits which are shifted off the end
751 * of SA being transferred into the accumulator.
752 * The contents of the accumulator are placed in the
753 * left end of the SA register
754 *
755 */
756void pps4_device::iCYS()
757{
758    const UINT16 sa = (m_SA >> 4) | (m_A << 12);
759    m_A = m_SA & 15;
760    m_SA = sa;
761}
762
763/**
764 * @brief pps4_device::iLB
765 * OPCODE     cycles  mnemonic
766 * -----------------------------
767 * 1100 0000  2 cyc    LB
768 *
769 * Symbolic equation
770 * -----------------------------
771 * SB <- SA, SA <- P
772 * P(12:5) <- 0000 1100
773 * P(4:1) <- I(4:1)
774 *
775 * BU <- 0000
776 * B(8:1) <- [I2(8:1)]
777 * P <- SA, SA <-> SB
778 *
779 * Sixteen consecutive locations on ROM page 3 (I2) contain
780 * data which can be loaded into the eight least significant
781 * bits of the B register by use of any LB instruction.
782 * The four most significant bits of B register will be loaded
783 * with zeros. The contents of the SB register will be destroyed.
784 * This instruction takes two cycles to execute but occupies
785 * only one ROM word. (Automatic return)
786 *
787 * Only the first occurence of an LB or LBL instruction in a
788 * consecutive string of LB or LBL will be executed. The
789 * program will ignore the remaining LB or LBL and execute
790 * the next valid instruction. Within subroutines the LB
791 * instruction must be used with caution because the contents
792 * of SB have been modified.
793 *
794 * See %Note3 and %Note4
795 */
796void pps4_device::iLB()
797{
798    // previous LB or LBL instruction?
799    if (0xc0 == m_Ip|| 0x00 == m_Ip) {
800        LOG(("%s: skip prev:%02X\n", __FUNCTION__, m_Ip));
801        return;
802    }
803    m_SB = m_SA;
804    m_SA = (m_P + 1) & 0xFFF;
805    m_P = (3 << 8) | (m_I & 15);
806    m_B = ~ARG() & 255;
807    m_P = m_SA;
808    // swap SA and SB
809    m_SA ^= m_SB;
810    m_SB ^= m_SA;
811    m_SA ^= m_SB;
812}
813
814/**
815 * @brief pps4_device::iLBL
816 * OPCODE     cycles  mnemonic
817 * -----------------------------
818 * 0000 0000  2 cyc    LBL
819 *
820 * Symbolic equation
821 * -----------------------------
822 * BU <- 0000
823 * B(8:1) <- [I2(8:1)]
824 *
825 * This instruction occupies two ROM words, the second of
826 * which will be loaded into the eight least significant
827 * bits of the B register. The four most significant bits
828 * of B (BU) will be loaded with zeroes.
829 *
830 * Only the first occurence of an LB or LBL instruction in a
831 * consecutive string of LB or LBL will be executed. The
832 * program will ignore the remaining LB or LBL and execute
833 * the next valid instruction.
834 *
835 * See %Note3
836 */
837void pps4_device::iLBL()
838{
839    // previous LB or LBL instruction?
840    if (0xc0 == m_Ip || 0x00 == m_Ip) {
841        LOG(("%s: skip prev:%02X\n", __FUNCTION__, m_Ip));
842        return;
843    }
844    m_B = ~ARG() & 255;
845}
846
847/**
848 * @brief pps4_device::INCB
849 * OPCODE     cycles  mnemonic
850 * -----------------------------
851 * 0001 0111  1 cyc    INCB
852 *
853 * Symbolic equation
854 * -----------------------------
855 * BL <- BL + 1
856 * Skip on BL = 0000
857 *
858 * BL register (least significant four bits of B register)
859 * is incremented by 1. If the new contents of BL is 0000b,
860 * then the next ROM word will be ignored.
861 */
862void pps4_device::iINCB()
863{
864    UINT8 bl = m_B & 15;
865    bl = (bl + 1) & 15;
866    if (0 == bl) {
867        LOG(("%s: skip BL=%x\n", __FUNCTION__, bl));
868        m_P = (m_P + 1) & 0xFFF;
869    }
870    m_B = (m_B & ~15) | bl;
871}
872
873/**
874 * @brief pps4_device::iDECB
875 * OPCODE     cycles  mnemonic
876 * -----------------------------
877 * 0001 1111  1 cyc    DECB
878 *
879 * Symbolic equation
880 * -----------------------------
881 * BL <- BL - 1
882 * Skip on BL = 1111
883 *
884 * BL register is decremented by 1. If the new
885 * contents of BL is 1111b, then the next ROM
886 * word will be ignored.
887 */
888void pps4_device::iDECB()
889{
890    UINT8 bl = m_B & 15;
891    bl = (bl - 1) & 15;
892    if (15 == bl) {
893        LOG(("%s: skip BL=%x\n", __FUNCTION__, bl));
894        m_P = (m_P + 1) & 0xFFF;
895    }
896    m_B = (m_B & ~15) | bl;
897}
898
899/**
900 * @brief pps4_device::iT Transfer
901 * OPCODE     cycles  mnemonic
902 * -----------------------------
903 * 10xx xxxx  1 cyc    T *
904 *
905 * Symbolic equation
906 * -----------------------------
907 * P(6:1) <- I(6:1)
908 *
909 * An unconditional transfer to a ROM word on the current
910 * page takes place. The least significant 6-bits of P
911 * register P(6:1) are replaced by six bit immediate
912 * field I(6:1)
913 */
914void pps4_device::iT()
915{
916    const UINT16 p = (m_P & ~63) | (m_I & 63);
917    LOG(("%s: P=%03x I=%02x -> P=%03x\n", __FUNCTION__, m_P, m_I, p));
918    m_P = p;
919}
920
921/**
922 * @brief pps4_device::iTM Transfer and mark indirect
923 * OPCODE     cycles  mnemonic
924 * -----------------------------
925 * 11xx xxxx  2 cyc    TM *
926 * yyyy yyyy  from page 3
927 *
928 * Symbolic equation
929 * -----------------------------
930 * SB <- SA, SA <- P
931 * P(12:7) <- 000011
932 * P(6:1) <- I1(6:1)
933 *
934 * P(12:9) <- 0001
935 * P(8:1) <- I2(8:1)
936 *
937 * 48 consecutive locations on ROM page 3 contains pointer data
938 * which indentify subroutine entry addresses. These subroutine
939 * entry addresses are limited to pages 4 through 7. This TM
940 * instruction will save the address of the next ROM word in
941 * the SA register after loading the original contents of SA
942 * into SB. A transfer then occurs to one of the subroutine
943 * entry addresses. This instruction occupies one ROM word
944 * but takes two cycles for execution.
945 */
946void pps4_device::iTM()
947{
948    m_SB = m_SA;
949    m_SA = m_P;
950    m_P = 3 << 6;
951    m_P = m_P | (m_I & 63);
952    ARG();
953    m_P = 1 << 8;
954    m_P |= m_I2;
955}
956
957/**
958 * @brief pps4_device::iTL Transfer long
959 * OPCODE     cycles  mnemonic
960 * -----------------------------
961 * 0101 xxxx  2 cyc    TL *
962 * yyyy yyyy
963 *
964 * Symbolic equation
965 * -----------------------------
966 * P(12:9) <- I1(4:1)
967 * P(8:1) <- I2(8:1)
968 *
969 * The instruction executes a transfer to any ROM word on any
970 * page. It occupies two ROM words an requires two cycles for
971 * execution. The first byte loads P(12:9) with field I1(4:1)
972 * and then the second byte I2(8:1) is placed in P(8:1).
973 */
974void pps4_device::iTL()
975{
976    ARG();
977    m_P = (m_I & 15) << 8;
978    m_P = m_P | m_I2;
979}
980
981/**
982 * @brief pps4_device::iTML Transfer and mark long
983 * OPCODE     cycles  mnemonic
984 * -----------------------------
985 * 0101 xxxx  2 cyc    TML *
986 * yyyy yyyy
987 *
988 * Symbolic equation
989 * -----------------------------
990 * SB <- SA, SA <- P
991 * P(12:9) <- I1(4:1)
992 * P(8:1) <- I2(8:1)
993 *
994 * Note I1(2:1) != 00
995 *
996 * This instruction executes a transfer and mark to any
997 * location on ROM pages 4 through 15. It occupies two
998 * ROM words and requires two cycle times for execution.
999 */
1000void pps4_device::iTML()
1001{
1002    ARG();
1003    m_SB = m_SA;
1004    m_SA = m_P;
1005    m_P = (m_I & 15) << 8;
1006    m_P = m_P | m_I2;
1007}
1008
1009/**
1010 * @brief pps4_device::iSKC Skip on carry flip-flop
1011 * OPCODE     cycles  mnemonic
1012 * -----------------------------
1013 * 0001 0101  1 cyc    SKC
1014 *
1015 * Symbolic equation
1016 * -----------------------------
1017 * Skip if C = 1
1018 *
1019 * The next ROM word will be ignored if C flip-flop is 1.
1020 */
1021void pps4_device::iSKC()
1022{
1023    m_P = m_P + m_C;
1024    m_P = m_P & 0xFFF;
1025}
1026
1027/**
1028 * @brief pps4_device::iSKC Skip on carry flip-flop
1029 * OPCODE     cycles  mnemonic
1030 * -----------------------------
1031 * 0001 1110  1 cyc    SKZ
1032 *
1033 * Symbolic equation
1034 * -----------------------------
1035 * Skip if A = 0
1036 *
1037 * The next ROM word will be ignored if C flip-flop is 1.
1038 */
1039void pps4_device::iSKZ()
1040{
1041    m_P = m_P + (0 == m_A) ? 1 : 0;
1042    m_P = m_P & 0xFFF;
1043}
1044
1045/**
1046 * @brief pps4_device::iSKBI Skip if BL equal to immediate
1047 * OPCODE     cycles  mnemonic
1048 * -----------------------------
1049 * 0100 xxxx  1 cyc    SKBI x
1050 *
1051 * Symbolic equation
1052 * -----------------------------
1053 * Skip if BL = I(4:1)
1054 *
1055 * The next ROM word will be ignored if the least significant
1056 * four bits of B register (BL) is equal to the 4-bit immediate
1057 * field I(4:1) of instruction.
1058 */
1059void pps4_device::iSKBI()
1060{
1061    const unsigned imm = m_I & 15;
1062    m_P = m_P + (imm == (m_B & 15)) ? 1 : 0;
1063    m_P = m_P & 0xFFF;
1064}
1065
1066/**
1067 * @brief pps4_device::iSKF1 Skip if FF1 equals 1
1068 * OPCODE     cycles  mnemonic
1069 * -----------------------------
1070 * 0001 0110  1 cyc    SKF1
1071 *
1072 * Symbolic equation
1073 * -----------------------------
1074 * Skip if FF1 = 1
1075 */
1076void pps4_device::iSKF1()
1077{
1078    m_P = m_P + m_FF1;
1079    m_P = m_P & 0xFFF;
1080}
1081
1082/**
1083 * @brief pps4_device::iSKF2 Skip if FF2 equals 1
1084 * OPCODE     cycles  mnemonic
1085 * -----------------------------
1086 * 0001 0100  1 cyc    SKF2
1087 *
1088 * Symbolic equation
1089 * -----------------------------
1090 * Skip if FF2 = 1
1091 */
1092void pps4_device::iSKF2()
1093{
1094    m_P = m_P + m_FF2;
1095    m_P = m_P & 0xFFF;
1096}
1097
1098/**
1099 * @brief pps4_device::iRTN Return
1100 * OPCODE     cycles  mnemonic
1101 * -----------------------------
1102 * 0000 0101  1 cyc    RET
1103 *
1104 * Symbolic equation
1105 * -----------------------------
1106 * P <- SA, SA <-> SB
1107 *
1108 * This instruction executes a return from subroutine
1109 * by loading contents of SA register into P register
1110 * and interchanges the SB and SA registers.
1111 */
1112void pps4_device::iRTN()
1113{
1114    m_P = m_SA;
1115    // swap SA and SB
1116    m_SA ^= m_SB;
1117    m_SB ^= m_SA;
1118    m_SA ^= m_SB;
1119}
1120
1121/**
1122 * @brief pps4_device::iRTN Return
1123 * OPCODE     cycles  mnemonic
1124 * -----------------------------
1125 * 0000 0111  1 cyc    RETSK
1126 *
1127 * Symbolic equation
1128 * -----------------------------
1129 * P <- SA, SA <-> SB
1130 * P <- P + 1
1131 *
1132 * Same as RTN expect the first ROM word encountered
1133 * after the return from subroutine is skipped.
1134 */
1135void pps4_device::iRTNSK()
1136{
1137    m_P = m_SA;
1138    ROP();      // ignored
1139    m_I = 0;    // avoid LB/LBL or LDI skipping
1140    // swap SA and SB
1141    m_SA ^= m_SB;
1142    m_SB ^= m_SA;
1143    m_SA ^= m_SB;
1144    m_P = m_P & 0xFFF;
1145}
1146
1147/**
1148 * @brief pps4_device::IOL
1149 * OPCODE     cycles  mnemonic
1150 * -----------------------------
1151 * 0001 1100  2 cyc    IOL
1152 * yyyy yyyy
1153 *
1154 * Symbolic equation
1155 * -----------------------------
1156 * ~A -> Data Bus
1157 * A <- ~Data Bus
1158 * I2 -> I/O device
1159 *
1160 * This instruction occupies two ROM words and requires two
1161 * cycles for execution. The first ROM word is received by
1162 * the CPU and sets up the I/O enable signal. The second
1163 * ROM word is then received by the I/O devices and decoded
1164 * for address and command. The contents of the accumulator
1165 * inverted are placed on the data lines for acceptance by
1166 * the I/O. At the same time, input data received by the I/O
1167 * device is transferred to the accumulator inverted.
1168 */
1169void pps4_device::iIOL()
1170{
1171    const unsigned a = ~m_A & 15;
1172    ARG();
1173    LOG(("%s: port:%X <- %02X\n", __FUNCTION__, m_I2, a));
1174    m_io->write_byte(m_I2, a);
1175    m_A = ~m_io->read_byte(m_I2) & 15;
1176    LOG(("%s: port:%X -> %02X\n", __FUNCTION__, m_I2, m_A));
1177}
1178
1179/**
1180 * @brief pps4_device::iDIA Discrete input group A
1181 * OPCODE     cycles  mnemonic
1182 * -----------------------------
1183 * 0010 0111  1 cyc    DIA
1184 *
1185 * Symbolic equation
1186 * -----------------------------
1187 * A <- DIA
1188 *
1189 * Data at the inputs to discrete group A is
1190 * transferred to the accumulator.
1191 */
1192void pps4_device::iDIA()
1193{
1194    m_A = m_io->read_byte(PPS4_PORT_A);
1195}
1196
1197/**
1198 * @brief pps4_device::iDIB Discrete input group B
1199 * OPCODE     cycles  mnemonic
1200 * -----------------------------
1201 * 0010 0011  1 cyc    DIB
1202 *
1203 * Symbolic equation
1204 * -----------------------------
1205 * A <- DIB
1206 *
1207 * Data at the inputs to discrete group B is
1208 * transferred to the accumulator.
1209 */
1210void pps4_device::iDIB()
1211{
1212    m_A = m_io->read_byte(PPS4_PORT_B);
1213}
1214
1215/**
1216 * @brief pps4_device::iDIA Discrete input group A
1217 * OPCODE     cycles  mnemonic
1218 * -----------------------------
1219 * 0010 1101  1 cyc    DOA
1220 *
1221 * Symbolic equation
1222 * -----------------------------
1223 * DOA <- A
1224 *
1225 * The contents of the accumulator are transferred
1226 * to the discrete output register.
1227 */
1228void pps4_device::iDOA()
1229{
1230    m_io->write_byte(PPS4_PORT_A, m_A);
1231}
1232
1233/**
1234 * @brief pps4_device::iSAG Special address generation
1235 * OPCODE     cycles  mnemonic
1236 * -----------------------------
1237 * 0010 1101  1 cyc    SAG
1238 *
1239 * Symbolic equation
1240 * -----------------------------
1241 * A/B Bus (12:5) <- 0000 0000
1242 * A/B Bus (4:1) <- BL(4:1)
1243 * Contents of B remains unchanged
1244 *
1245 * The instruction causes the eight most significant bits
1246 * of the RAM address output to be zeroed during the next
1247 * cycle only. Note that this instruction does not alter
1248 * the contents of the B register.
1249 */
1250void pps4_device::iSAG()
1251{
1252    // mask bits 12:5
1253    m_SAG = 0xff0;
1254}
1255
3171256/***************************************************************************
3181257    COMMON EXECUTION
3191258***************************************************************************/
1259void pps4_device::execute_one()
1260{
1261    m_I = ROP();
1262    switch (m_I) {
1263    case 0x00:
1264        iLBL();
1265        break;
1266    case 0x01:
1267        iTML();
1268        break;
1269    case 0x02:
1270        iTML();
1271        break;
1272    case 0x03:
1273        iTML();
1274        break;
1275    case 0x04:
1276        iLBUA();
1277        break;
1278    case 0x05:
1279        iRTN();
1280        break;
1281    case 0x06:
1282        iXS();
1283        break;
1284    case 0x07:
1285        iRTNSK();
1286        break;
1287    case 0x08:
1288        iADCSK();
1289        break;
1290    case 0x09:
1291        iADSK();
1292        break;
1293    case 0x0a:
1294        iADC();
1295        break;
1296    case 0x0b:
1297        iAD();
1298        break;
1299    case 0x0c:
1300        iEOR();
1301        break;
1302    case 0x0d:
1303        iAND();
1304        break;
1305    case 0x0e:
1306        iCOMP();
1307        break;
1308    case 0x0f:
1309        iOR();
1310        break;
1311
1312    case 0x10:
1313        iLBMX();
1314        break;
1315    case 0x11:
1316        iLABL();
1317        break;
1318    case 0x12:
1319        iLAX();
1320        break;
1321    case 0x13:
1322        iSAG();
1323        break;
1324    case 0x14:
1325        iSKF2();
1326        break;
1327    case 0x15:
1328        iSKC();
1329        break;
1330    case 0x16:
1331        iSKF1();
1332        break;
1333    case 0x17:
1334        iINCB();
1335        break;
1336    case 0x18:
1337        iXBMX();
1338        break;
1339    case 0x19:
1340        iXABL();
1341        break;
1342    case 0x1a:
1343        iXAX();
1344        break;
1345    case 0x1b:
1346        iLXA();
1347        break;
1348    case 0x1c:
1349        iIOL();
1350        break;
1351    case 0x1d:
1352        iDOA();
1353        break;
1354    case 0x1e:
1355        iSKZ();
1356        break;
1357    case 0x1f:
1358        iDECB();
1359        break;
1360
1361    case 0x20:
1362        iSC();
1363        break;
1364    case 0x21:
1365        iSF2();
1366        break;
1367    case 0x22:
1368        iSF1();
1369        break;
1370    case 0x23:
1371        iDIB();
1372        break;
1373    case 0x24:
1374        iRC();
1375        break;
1376    case 0x25:
1377        iRF2();
1378        break;
1379    case 0x26:
1380        iRF1();
1381        break;
1382    case 0x27:
1383        iDIA();
1384        break;
1385
1386    case 0x28: case 0x29: case 0x2a: case 0x2b:
1387    case 0x2c: case 0x2d: case 0x2e: case 0x2f:
1388        iEXD();
1389        break;
1390
1391    case 0x30: case 0x31: case 0x32: case 0x33:
1392    case 0x34: case 0x35: case 0x36: case 0x37:
1393        iLD();
1394        break;
1395
1396    case 0x38: case 0x39: case 0x3a: case 0x3b:
1397    case 0x3c: case 0x3d: case 0x3e: case 0x3f:
1398        iEX();
1399        break;
1400
1401    case 0x40: case 0x41: case 0x42: case 0x43:
1402    case 0x44: case 0x45: case 0x46: case 0x47:
1403    case 0x48: case 0x49: case 0x4a: case 0x4b:
1404    case 0x4c: case 0x4d: case 0x4e: case 0x4f:
1405        iSKBI();
1406        break;
1407
1408    case 0x50: case 0x51: case 0x52: case 0x53:
1409    case 0x54: case 0x55: case 0x56: case 0x57:
1410    case 0x58: case 0x59: case 0x5a: case 0x5b:
1411    case 0x5c: case 0x5d: case 0x5e: case 0x5f:
1412        iTL();
1413        break;
1414
1415    case 0x65:
1416        iDC();
1417        break;
1418
1419    case 0x60: case 0x61: case 0x62: case 0x63:
1420    case 0x64:            case 0x66: case 0x67:
1421    case 0x68: case 0x69: case 0x6a: case 0x6b:
1422    case 0x6c: case 0x6d: case 0x6e:
1423        iADI();
1424        break;
1425
1426    case 0x6f:
1427        iCYS();
1428        break;
1429
1430    case 0x70: case 0x71: case 0x72: case 0x73:
1431    case 0x74: case 0x75: case 0x76: case 0x77:
1432    case 0x78: case 0x79: case 0x7a: case 0x7b:
1433    case 0x7c: case 0x7d: case 0x7e: case 0x7f:
1434        iLDI();
1435        break;
1436
1437    case 0x80: case 0x81: case 0x82: case 0x83:
1438    case 0x84: case 0x85: case 0x86: case 0x87:
1439    case 0x88: case 0x89: case 0x8a: case 0x8b:
1440    case 0x8c: case 0x8d: case 0x8e: case 0x8f:
1441    case 0x90: case 0x91: case 0x92: case 0x93:
1442    case 0x94: case 0x95: case 0x96: case 0x97:
1443    case 0x98: case 0x99: case 0x9a: case 0x9b:
1444    case 0x9c: case 0x9d: case 0x9e: case 0x9f:
1445    case 0xa0: case 0xa1: case 0xa2: case 0xa3:
1446    case 0xa4: case 0xa5: case 0xa6: case 0xa7:
1447    case 0xa8: case 0xa9: case 0xaa: case 0xab:
1448    case 0xac: case 0xad: case 0xae: case 0xaf:
1449    case 0xb0: case 0xb1: case 0xb2: case 0xb3:
1450    case 0xb4: case 0xb5: case 0xb6: case 0xb7:
1451    case 0xb8: case 0xb9: case 0xba: case 0xbb:
1452    case 0xbc: case 0xbd: case 0xbe: case 0xbf:
1453        iT();
1454        break;
1455
1456
1457    case 0xc0: case 0xc1: case 0xc2: case 0xc3:
1458    case 0xc4: case 0xc5: case 0xc6: case 0xc7:
1459    case 0xc8: case 0xc9: case 0xca: case 0xcb:
1460    case 0xcc: case 0xcd: case 0xce: case 0xcf:
1461        iLB();
1462        break;
1463
1464    default:
1465        iTM();
1466    }
1467}
1468
3201469void pps4_device::execute_run()
3211470{
322   do
323   {
324      debugger_instruction_hook(this, m_P.d);
325      execute_one(ROP());
1471    do
1472    {
1473        debugger_instruction_hook(this, m_P);
1474        execute_one();
3261475
327   } while (m_icount > 0);
1476    } while (m_icount > 0);
3281477}
3291478
3301479/***************************************************************************
r242165r242166
3331482
3341483void pps4_device::device_start()
3351484{
336   m_program = &space(AS_PROGRAM);
337   m_direct = &m_program->direct();
338   m_data = &space(AS_DATA);
339   m_io = &space(AS_IO);
1485    m_program = &space(AS_PROGRAM);
1486    m_direct = &m_program->direct();
1487    m_data = &space(AS_DATA);
1488    m_io = &space(AS_IO);
3401489
341   save_item(NAME(m_A));
342   save_item(NAME(m_X));
343   save_item(NAME(m_P));
344   save_item(NAME(m_SA));
345   save_item(NAME(m_SB));
346   save_item(NAME(m_B));
347   save_item(NAME(m_C));
348   save_item(NAME(m_FF1));
349   save_item(NAME(m_FF2));
1490    save_item(NAME(m_A));
1491    save_item(NAME(m_X));
1492    save_item(NAME(m_P));
1493    save_item(NAME(m_SA));
1494    save_item(NAME(m_SB));
1495    save_item(NAME(m_SAG));
1496    save_item(NAME(m_B));
1497    save_item(NAME(m_C));
1498    save_item(NAME(m_FF1));
1499    save_item(NAME(m_FF2));
1500    save_item(NAME(m_I));
1501    save_item(NAME(m_I2));
1502    save_item(NAME(m_Ip));
3501503
351   state_add( PPS4_PC, "PC", m_P.d ).mask(0xfff).formatstr("%03X");
352   state_add( PPS4_A,  "A",  m_A ).formatstr("%02X");  // TODO: size?
353   state_add( PPS4_X,  "X",  m_X ).formatstr("%02X");  // TODO: size?
354   state_add( PPS4_SA, "SA", m_SA.d ).formatstr("%04X");  // TODO: size?
355   state_add( PPS4_SB, "SB", m_SB.d ).formatstr("%04X");  // TODO: size?
356   state_add( PPS4_B,  "B",  m_B.d ).formatstr("%04X"); // TODO: size?
357   state_add( STATE_GENPC, "GENPC", m_P.d ).noshow();
358   state_add( STATE_GENFLAGS, "GENFLAGS", m_C ).formatstr("%3s").noshow();
1504    state_add( PPS4_PC, "PC", m_P ).mask(0xFFF).formatstr("%03X");
1505    state_add( PPS4_A,  "A",  m_A ).formatstr("%01X");
1506    state_add( PPS4_X,  "X",  m_X ).formatstr("%01X");
1507    state_add( PPS4_SA, "SA", m_SA ).formatstr("%03X");
1508    state_add( PPS4_SB, "SB", m_SB ).formatstr("%03X");
1509    state_add( PPS4_B,  "B",  m_B ).formatstr("%03X");
1510    state_add( PPS4_SAG,  "SAG",  m_SAG ).formatstr("%03X");
1511    state_add( PPS4_I2,  "I2",  m_I2 ).formatstr("%02X").noshow();
1512    state_add( PPS4_Ip,  "Ip",  m_Ip ).formatstr("%02X").noshow();
1513    state_add( STATE_GENPC, "GENPC", m_P ).noshow();
1514    state_add( STATE_GENFLAGS, "GENFLAGS", m_C).formatstr("%3s").noshow();
3591515
360   m_icountptr = &m_icount;
1516    m_icountptr = &m_icount;
3611517}
3621518
3631519void pps4_device::state_string_export(const device_state_entry &entry, astring &string)
3641520{
365   switch (entry.index())
366   {
367      case STATE_GENFLAGS:
368         string.printf("%c%c%c",
369            m_C ? 'C':'.',
370            m_FF1 ? '1':'.',
371            m_FF2 ? '2':'.');
372         break;
373   }
1521    switch (entry.index())
1522    {
1523        case STATE_GENFLAGS:
1524            string.printf("%c%c%c",
1525                m_C ? 'C':'.',
1526                m_FF1 ? '1':'.',
1527                m_FF2 ? '2':'.');
1528            break;
1529    }
3741530}
3751531
3761532/***************************************************************************
r242165r242166
3791535
3801536void pps4_device::device_reset()
3811537{
382   m_A = m_X = 0;
383   m_C = m_FF1 = m_FF2 = 0;
384
385   m_P.d = 0;
386   m_SA.d = 0;
387   m_SB.d = 0;
388   m_B.d = 0;
1538    m_A = 0;        // Accumulator A(4:1)
1539    m_X = 0;        // X register X(4:1)
1540    m_P = 0;        // program counter P(12:1)
1541    m_SA = 0;       // Shift register SA(12:1)
1542    m_SB = 0;       // Shift register SB(12:1)
1543    m_SAG = 0;      // Special address generation mask
1544    m_B = 0;        // B address register B(12:1) (BL, BM and BU)
1545    m_C = 0;        // Carry flip-flop
1546    m_FF1 = 0;      // Flip-flop 1
1547    m_FF2 = 0;      // Flip-flop 2
1548    m_I = 0;        // Most recent instruction I(8:1)
1549    m_I2 = 0;       // Most recent parameter I2(8:1)
1550    m_Ip = 0;       // Previous instruction I(8:1)
3891551}
trunk/src/emu/cpu/pps4/pps4.h
r242165r242166
11// license:BSD-3-Clause
2// copyright-holders:Miodrag Milanovic
2// copyright-holders:Juergen Buchmueller <pullmoll@t-online.de>
33#ifndef __PPS4_H__
44#define __PPS4_H__
55
r242165r242166
99***************************************************************************/
1010enum
1111{
12   PPS4_PC,
13   PPS4_A,PPS4_X,PPS4_SA,PPS4_SB,PPS4_B,
14   PPS4_GENPC = STATE_GENPC,
15   PPS4_GENSP = STATE_GENSP,
16   PPS4_GENPCBASE = STATE_GENPCBASE
12    PPS4_PC,
13    PPS4_A,
14    PPS4_X,
15    PPS4_SA,
16    PPS4_SB,
17    PPS4_B,
18    PPS4_SAG,
19    PPS4_I2,
20    PPS4_Ip,
21    PPS4_GENPC = STATE_GENPC,
22    PPS4_GENSP = STATE_GENSP,
23    PPS4_GENPCBASE = STATE_GENPCBASE,
24    PPS4_PORT_A = 256,
25    PPS4_PORT_B = 257
1726};
1827
1928/***************************************************************************
r242165r242166
2635
2736extern const device_type PPS4;
2837
29
3038class pps4_device : public cpu_device
3139{
3240public:
33   // construction/destruction
34   pps4_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
41    // construction/destruction
42    pps4_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
3543
3644protected:
37   // device-level overrides
38   virtual void device_start();
39   virtual void device_reset();
45    // device-level overrides
46    virtual void device_start();
47    virtual void device_reset();
4048
41   // device_execute_interface overrides
42   virtual UINT32 execute_min_cycles() const { return 1; }
43   virtual UINT32 execute_max_cycles() const { return 2; }
44   virtual UINT32 execute_input_lines() const { return 0; }
45   virtual UINT32 execute_default_irq_vector() const { return 0; }
46   virtual void execute_run();
49    // device_execute_interface overrides
50    virtual UINT32 execute_min_cycles() const { return 1; }
51    virtual UINT32 execute_max_cycles() const { return 3; }
52    virtual UINT32 execute_input_lines() const { return 0; }
53    virtual UINT32 execute_default_irq_vector() const { return 0; }
54    virtual void execute_run();
4755
48   // device_memory_interface overrides
49   virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const
50   {
51      return (spacenum == AS_PROGRAM) ? &m_program_config : ( (spacenum == AS_IO) ? &m_io_config : ( (spacenum == AS_DATA) ? &m_data_config : NULL ) );
52   }
56    // device_memory_interface overrides
57    virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const
58    {
59        return (spacenum == AS_PROGRAM) ? &m_program_config : ( (spacenum == AS_IO) ? &m_io_config : ( (spacenum == AS_DATA) ? &m_data_config : NULL ) );
60    }
5361
54   // device_state_interface overrides
55   void state_string_export(const device_state_entry &entry, astring &string);
62    // device_state_interface overrides
63    void state_string_export(const device_state_entry &entry, astring &string);
5664
57   // device_disasm_interface overrides
58   virtual UINT32 disasm_min_opcode_bytes() const { return 1; }
59   virtual UINT32 disasm_max_opcode_bytes() const { return 2; }
60   virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
65    // device_disasm_interface overrides
66    virtual UINT32 disasm_min_opcode_bytes() const { return 1; }
67    virtual UINT32 disasm_max_opcode_bytes() const { return 2; }
68    virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options);
6169
6270private:
63   address_space_config m_program_config;
64   address_space_config m_data_config;
65   address_space_config m_io_config;
71    address_space_config m_program_config;
72    address_space_config m_data_config;
73    address_space_config m_io_config;
6674
67   UINT8   m_A; // Accumulator
68   UINT8   m_X;
75    address_space *m_program;
76    direct_read_data *m_direct;
77    address_space *m_data;
78    address_space *m_io;
79    int     m_icount;
6980
70   PAIR    m_P;
71   PAIR    m_SA;
72   PAIR    m_SB;
73   PAIR    m_B; // BU + BM + BL
81    UINT8   m_A;        //!< Accumulator A(4:1)
82    UINT8   m_X;        //!< X register X(4:1)
83    UINT16  m_P;        //!< program counter P(12:1)
84    UINT16  m_SA;       //!< Shift register SA(12:1)
85    UINT16  m_SB;       //!< Shift register SB(12:1)
86    UINT16  m_SAG;      //!< Special address generation mask
87    UINT16  m_B;        //!< B register B(12:1) (BL, BM and BH)
88    UINT8   m_C;        //!< Carry flip-flop
89    UINT8   m_FF1;      //!< Flip-flop 1
90    UINT8   m_FF2;      //!< Flip-flop 2
91    UINT8   m_I;        //!< Most recent instruction I(8:1)
92    UINT8   m_I2;       //!< Most recent parameter I2(8:1)
93    UINT8   m_Ip;       //!< Previous instruction I(8:1)
7494
75   UINT8   m_C; // Carry flag
76   UINT8   m_FF1; // Flip-flop 1
77   UINT8   m_FF2; // Flip-flop 2
95    //! return the contents of B register (made of BU, BM and BL)
96    inline UINT16 B() const;
7897
79   address_space *m_program;
80   direct_read_data *m_direct;
81   address_space *m_data;
82   address_space *m_io;
98    //! return memory at address B(12:1)
99    inline UINT8 M();
83100
84   int                 m_icount;
101    //! write to memory at address B(12:1)
102    inline void W(UINT8 data);
85103
86   inline UINT8 ROP();
87   inline UINT8 ARG();
88   inline void DO_SKIP();
89   void execute_one(int opcode);
104    //! return the next opcode (also in m_I)
105    inline UINT8 ROP();
90106
107    //! return the next argument (also in m_I2)
108    inline UINT8 ARG();
109
110    void iAD();          //!< Add
111    void iADC();         //!< Add with carry-in
112    void iADSK();        //!< Add and skip on carry-out
113    void iADCSK();       //!< Add with carry-in and skip on carry-out
114    void iADI();         //!< Add immediate
115    void iDC();          //!< Decimal correction
116    void iAND();         //!< Logical AND
117    void iOR();          //!< Logical OR
118    void iEOR();         //!< Logical Exclusive-OR
119    void iCOMP();        //!< Complement
120    void iSC();          //!< Set Carry flip-flop
121    void iRC();          //!< Reset Carry flip-flop
122    void iSF1();         //!< Set FF1
123    void iRF1();         //!< Reset FF1
124    void iSF2();         //!< Set FF2
125    void iRF2();         //!< Reset FF2
126    void iLD();          //!< Load accumulator from memory
127    void iEX();          //!< Exchange accumulator and memory
128    void iEXD();         //!< Exchange accumulator and memory and decrement BL
129    void iLDI();         //!< Load accumulator immediate
130    void iLAX();         //!< Load accumulator from X register
131    void iLXA();         //!< Load X register from accumulator
132    void iLABL();        //!< Load accumulator with BL
133    void iLBMX();        //!< Load BM with X
134    void iLBUA();        //!< Load BU with A
135    void iXABL();        //!< Exchange accumulator and BL
136    void iXBMX();        //!< Exchange BM and X registers
137    void iXAX();         //!< Exchange accumulator and X
138    void iXS();          //!< Eychange SA and SB registers
139    void iCYS();         //!< Cycle SA register and accumulaor
140    void iLB();          //!< Load B indirect
141    void iLBL();         //!< Load B long
142    void iINCB();        //!< Increment BL
143    void iDECB();        //!< Decrement BL
144    void iT();           //!< Transfer
145    void iTM();          //!< Transfer and mark indirect
146    void iTL();          //!< Transfer long
147    void iTML();         //!< Transfer and mark long
148    void iSKC();         //!< Skip on carry flip-flop
149    void iSKZ();         //!< Skip on accumulator zero
150    void iSKBI();        //!< Skip if BL equal to immediate
151    void iSKF1();        //!< Skip if FF1 equals 1
152    void iSKF2();        //!< Skip if FF2 equals 1
153    void iRTN();         //!< Return
154    void iRTNSK();       //!< Return and skip
155    void iIOL();         //!< Input/Output long
156    void iDIA();         //!< Discrete input group A
157    void iDIB();         //!< Discrete input group B
158    void iDOA();         //!< Discrete output group A
159    void iSAG();         //!< Special address generation
160
161    void execute_one(); //!< execute one instruction
91162};
92163
93
94#endif
164#endif  // __PPS4_H__
trunk/src/emu/cpu/pps4/pps4dasm.c
r242165r242166
11// license:BSD-3-Clause
2// copyright-holders:Miodrag Milanovic
2// copyright-holders:Juergen Buchmueller <pullmoll@t-online.de>
33/*****************************************************************************
44 *
55 *   pps4dasm.c
66 *
77 *   Rockwell PPS-4 CPU Disassembly
88 *
9 *
10 * TODO: double verify all opcodes with t_Ixx flags
11 *
912 *****************************************************************************/
10
1113#include "emu.h"
1214
1315#define OP(A)   oprom[(A) - PC]
1416#define ARG(A)  opram[(A) - PC]
1517
18typedef enum pps4_token_e {
19    t_AD,       t_ADC,      t_ADSK,     t_ADCSK,    t_ADI,
20    t_DC,       t_AND,      t_OR,       t_EOR,      t_COMP,
21    t_SC,       t_RC,       t_SF1,      t_RF1,      t_SF2,
22    t_RF2,      t_LD,       t_EX,       t_EXD,      t_LDI,
23    t_LAX,      t_LXA,      t_LABL,     t_LBMX,     t_LBUA,
24    t_XABL,     t_XBMX,     t_XAX,      t_XS,       t_CYS,
25    t_LB,       t_LBL,      t_INCB,     t_DECB,     t_T,
26    t_TM,       t_TL,       t_TML,      t_SKC,      t_SKZ,
27    t_SKBI,     t_SKF1,     t_SKF2,     t_RTN,      t_RTNSK,
28    t_IOL,      t_DIA,      t_DIB,      t_DOA,      t_SAG,
29    t_COUNT,
30    t_MASK = (1 << 6) - 1,
31    t_I3c = 1 << 6,   /* immediate 3 bit constant, complemented */
32    t_I4  = 1 << 7,   /* immediate 4 bit constant */
33    t_I4c = 1 << 8,   /* immediate 4 bit constant, complemented */
34    t_I4p = 1 << 9,   /* immediate 4 bit offset into page 3 */
35    t_I6p = 1 << 10,  /* immediate 6 bit constant; address in current page */
36    t_I8  = 1 << 11,  /* immediate 8 bit constant (I/O port number) */
37    t_I8c = 1 << 12,  /* immediate 8 bit constant inverted */
38}   pps4_token_e;
39
40static const char *token_str[t_COUNT] = {
41    "ad",           /* add */
42    "adc",          /* add with carry-in */
43    "adsk",         /* add and skip on carry-out */
44    "adcsk",        /* add with carry-in and skip on carry-out */
45    "adi",          /* add immediate */
46    "dc",           /* decimal correction */
47    "and",          /* logical and */
48    "or",           /* logical or */
49    "eor",          /* logical exclusive-orf */
50    "comp",         /* complement */
51    "sc",           /* set C flip-flop */
52    "rc",           /* reset C flip-flop */
53    "sf1",          /* set FF1 flip-flop */
54    "rf1",          /* reset FF1 flip-flop */
55    "sf2",          /* set FF2 flip-flop */
56    "rf2",          /* reset FF2 flip-flop */
57    "ld",           /* load accumulator from memory */
58    "ex",           /* exchange accumulator and memory */
59    "exd",          /* exchange accumulator and memory and decrement BL */
60    "ldi",          /* load accumulator immediate */
61    "lax",          /* load accumulator from X register */
62    "lxa",          /* load X register from accumulator */
63    "labl",         /* load accumulator with BL */
64    "lbmx",         /* load BM with X */
65    "lbua",         /* load BU with A */
66    "xabl",         /* exchange accumulator and BL */
67    "xbmx",         /* exchange BM and X */
68    "xax",          /* exchange accumulator and X */
69    "xs",           /* exchange SA and SB */
70    "cys",          /* cycle SA register and accumulator */
71    "lb",           /* load B indirect */
72    "lbl",          /* load B long */
73    "incb",         /* increment BL */
74    "decb",         /* decrement BL */
75    "t",            /* transfer */
76    "tm",           /* transfer and mark indirect */
77    "tl",           /* transfer long */
78    "tml",          /* transfer and mark long */
79    "skc",          /* skip on C flip-flop equals 1 */
80    "skz",          /* skip on accumulator zero */
81    "skbi",         /* skip on BL equal to immediate */
82    "skf1",         /* skip on FF1 flip-flop equals 1 */
83    "skf2",         /* skip on FF2 flip-flop equals 1 */
84    "rtn",          /* return */
85    "rtnsk",        /* return and skip */
86    "iol",          /* input/output long */
87    "dia",          /* discrete input group A */
88    "dib",          /* discrete input group B */
89    "doa",          /* discrete output */
90    "sag"           /* special address generation */
91};
92
93static const UINT16 table[] = {
94    t_LBL | t_I8c,       /* 00 */
95    t_TML | t_I4 | t_I8, /* 01 */
96    t_TML | t_I4 | t_I8, /* 02 */
97    t_TML | t_I4 | t_I8, /* 03 */
98    t_LBUA,              /* 04 */
99    t_RTN,               /* 05 */
100    t_XS,                /* 06 */
101    t_RTNSK,             /* 07 */
102    t_ADCSK,             /* 08 */
103    t_ADSK,              /* 09 */
104    t_ADC,               /* 0a */
105    t_AD,                /* 0b */
106    t_EOR,               /* 0c */
107    t_AND,               /* 0d */
108    t_COMP,              /* 0e */
109    t_OR,                /* 0f */
110
111    t_LBMX,              /* 10 */
112    t_LABL,              /* 11 */
113    t_LAX,               /* 12 */
114    t_SAG,               /* 13 */
115    t_SKF2,              /* 14 */
116    t_SKC,               /* 15 */
117    t_SKF1,              /* 16 */
118    t_INCB,              /* 17 */
119    t_XBMX,              /* 18 */
120    t_XABL,              /* 19 */
121    t_XAX,               /* 1a */
122    t_LXA,               /* 1b */
123    t_IOL | t_I8,        /* 1c */
124    t_DOA,               /* 1d */
125    t_SKZ,               /* 1e */
126    t_DECB,              /* 1f */
127
128    t_SC,                /* 20 */
129    t_SF2,               /* 21 */
130    t_SF1,               /* 22 */
131    t_DIB,               /* 23 */
132    t_RC,                /* 24 */
133    t_RF2,               /* 25 */
134    t_RF1,               /* 26 */
135    t_DIA,               /* 27 */
136    t_EXD | t_I3c,       /* 28 */
137    t_EXD | t_I3c,       /* 29 */
138    t_EXD | t_I3c,       /* 2a */
139    t_EXD | t_I3c,       /* 2b */
140    t_EXD | t_I3c,       /* 2c */
141    t_EXD | t_I3c,       /* 2d */
142    t_EXD | t_I3c,       /* 2e */
143    t_EXD | t_I3c,       /* 2f */
144
145    t_LD | t_I3c,        /* 30 */
146    t_LD | t_I3c,        /* 31 */
147    t_LD | t_I3c,        /* 32 */
148    t_LD | t_I3c,        /* 33 */
149    t_LD | t_I3c,        /* 34 */
150    t_LD | t_I3c,        /* 35 */
151    t_LD | t_I3c,        /* 36 */
152    t_LD | t_I3c,        /* 37 */
153    t_EX | t_I3c,        /* 38 */
154    t_EX | t_I3c,        /* 39 */
155    t_EX | t_I3c,        /* 3a */
156    t_EX | t_I3c,        /* 3b */
157    t_EX | t_I3c,        /* 3c */
158    t_EX | t_I3c,        /* 3d */
159    t_EX | t_I3c,        /* 3e */
160    t_EX | t_I3c,        /* 3f */
161
162    t_SKBI | t_I4,       /* 40 */
163    t_SKBI | t_I4,       /* 41 */
164    t_SKBI | t_I4,       /* 42 */
165    t_SKBI | t_I4,       /* 43 */
166    t_SKBI | t_I4,       /* 44 */
167    t_SKBI | t_I4,       /* 45 */
168    t_SKBI | t_I4,       /* 46 */
169    t_SKBI | t_I4,       /* 47 */
170    t_SKBI | t_I4,       /* 48 */
171    t_SKBI | t_I4,       /* 49 */
172    t_SKBI | t_I4,       /* 4a */
173    t_SKBI | t_I4,       /* 4b */
174    t_SKBI | t_I4,       /* 4c */
175    t_SKBI | t_I4,       /* 4d */
176    t_SKBI | t_I4,       /* 4e */
177    t_SKBI | t_I4,       /* 4f */
178
179    t_TL | t_I4 | t_I8,  /* 50 */
180    t_TL | t_I4 | t_I8,  /* 51 */
181    t_TL | t_I4 | t_I8,  /* 52 */
182    t_TL | t_I4 | t_I8,  /* 53 */
183    t_TL | t_I4 | t_I8,  /* 54 */
184    t_TL | t_I4 | t_I8,  /* 55 */
185    t_TL | t_I4 | t_I8,  /* 56 */
186    t_TL | t_I4 | t_I8,  /* 57 */
187    t_TL | t_I4 | t_I8,  /* 58 */
188    t_TL | t_I4 | t_I8,  /* 59 */
189    t_TL | t_I4 | t_I8,  /* 5a */
190    t_TL | t_I4 | t_I8,  /* 5b */
191    t_TL | t_I4 | t_I8,  /* 5c */
192    t_TL | t_I4 | t_I8,  /* 5d */
193    t_TL | t_I4 | t_I8,  /* 5e */
194    t_TL | t_I4 | t_I8,  /* 5f */
195
196    t_ADI | t_I4c,       /* 60 */
197    t_ADI | t_I4c,       /* 61 */
198    t_ADI | t_I4c,       /* 62 */
199    t_ADI | t_I4c,       /* 63 */
200    t_ADI | t_I4c,       /* 64 */
201    t_DC,                /* 65 */
202    t_ADI | t_I4c,       /* 66 */
203    t_ADI | t_I4c,       /* 67 */
204    t_ADI | t_I4c,       /* 68 */
205    t_ADI | t_I4c,       /* 69 */
206    t_ADI | t_I4c,       /* 6a */
207    t_ADI | t_I4c,       /* 6b */
208    t_ADI | t_I4c,       /* 6c */
209    t_ADI | t_I4c,       /* 6d */
210    t_ADI | t_I4c,       /* 6e */
211    t_CYS,               /* 6f */
212
213    t_LDI | t_I4c,       /* 70 */
214    t_LDI | t_I4c,       /* 71 */
215    t_LDI | t_I4c,       /* 72 */
216    t_LDI | t_I4c,       /* 73 */
217    t_LDI | t_I4c,       /* 74 */
218    t_LDI | t_I4c,       /* 75 */
219    t_LDI | t_I4c,       /* 76 */
220    t_LDI | t_I4c,       /* 77 */
221    t_LDI | t_I4c,       /* 78 */
222    t_LDI | t_I4c,       /* 79 */
223    t_LDI | t_I4c,       /* 7a */
224    t_LDI | t_I4c,       /* 7b */
225    t_LDI | t_I4c,       /* 7c */
226    t_LDI | t_I4c,       /* 7d */
227    t_LDI | t_I4c,       /* 7e */
228    t_LDI | t_I4c,       /* 7f */
229
230    t_T | t_I6p,         /* 80 */
231    t_T | t_I6p,         /* 81 */
232    t_T | t_I6p,         /* 82 */
233    t_T | t_I6p,         /* 83 */
234    t_T | t_I6p,         /* 84 */
235    t_T | t_I6p,         /* 85 */
236    t_T | t_I6p,         /* 86 */
237    t_T | t_I6p,         /* 87 */
238    t_T | t_I6p,         /* 88 */
239    t_T | t_I6p,         /* 89 */
240    t_T | t_I6p,         /* 8a */
241    t_T | t_I6p,         /* 8b */
242    t_T | t_I6p,         /* 8c */
243    t_T | t_I6p,         /* 8d */
244    t_T | t_I6p,         /* 8e */
245    t_T | t_I6p,         /* 8f */
246
247    t_T | t_I6p,         /* 90 */
248    t_T | t_I6p,         /* 91 */
249    t_T | t_I6p,         /* 92 */
250    t_T | t_I6p,         /* 93 */
251    t_T | t_I6p,         /* 94 */
252    t_T | t_I6p,         /* 95 */
253    t_T | t_I6p,         /* 96 */
254    t_T | t_I6p,         /* 97 */
255    t_T | t_I6p,         /* 98 */
256    t_T | t_I6p,         /* 99 */
257    t_T | t_I6p,         /* 9a */
258    t_T | t_I6p,         /* 9b */
259    t_T | t_I6p,         /* 9c */
260    t_T | t_I6p,         /* 9d */
261    t_T | t_I6p,         /* 9e */
262    t_T | t_I6p,         /* 9f */
263
264    t_T | t_I6p,         /* a0 */
265    t_T | t_I6p,         /* a1 */
266    t_T | t_I6p,         /* a2 */
267    t_T | t_I6p,         /* a3 */
268    t_T | t_I6p,         /* a4 */
269    t_T | t_I6p,         /* a5 */
270    t_T | t_I6p,         /* a6 */
271    t_T | t_I6p,         /* a7 */
272    t_T | t_I6p,         /* a8 */
273    t_T | t_I6p,         /* a9 */
274    t_T | t_I6p,         /* aa */
275    t_T | t_I6p,         /* ab */
276    t_T | t_I6p,         /* ac */
277    t_T | t_I6p,         /* ad */
278    t_T | t_I6p,         /* ae */
279    t_T | t_I6p,         /* af */
280
281    t_T | t_I6p,         /* b0 */
282    t_T | t_I6p,         /* b1 */
283    t_T | t_I6p,         /* b2 */
284    t_T | t_I6p,         /* b3 */
285    t_T | t_I6p,         /* b4 */
286    t_T | t_I6p,         /* b5 */
287    t_T | t_I6p,         /* b6 */
288    t_T | t_I6p,         /* b7 */
289    t_T | t_I6p,         /* b8 */
290    t_T | t_I6p,         /* b9 */
291    t_T | t_I6p,         /* ba */
292    t_T | t_I6p,         /* bb */
293    t_T | t_I6p,         /* bc */
294    t_T | t_I6p,         /* bd */
295    t_T | t_I6p,         /* be */
296    t_T | t_I6p,         /* bf */
297
298    t_LB | t_I4p,        /* c0 */
299    t_LB | t_I4p,        /* c1 */
300    t_LB | t_I4p,        /* c2 */
301    t_LB | t_I4p,        /* c3 */
302    t_LB | t_I4p,        /* c4 */
303    t_LB | t_I4p,        /* c5 */
304    t_LB | t_I4p,        /* c6 */
305    t_LB | t_I4p,        /* c7 */
306    t_LB | t_I4p,        /* c8 */
307    t_LB | t_I4p,        /* c9 */
308    t_LB | t_I4p,        /* ca */
309    t_LB | t_I4p,        /* cb */
310    t_LB | t_I4p,        /* cc */
311    t_LB | t_I4p,        /* cd */
312    t_LB | t_I4p,        /* ce */
313    t_LB | t_I4p,        /* cf */
314
315    t_TM | t_I6p,        /* d0 */
316    t_TM | t_I6p,        /* d1 */
317    t_TM | t_I6p,        /* d2 */
318    t_TM | t_I6p,        /* d3 */
319    t_TM | t_I6p,        /* d4 */
320    t_TM | t_I6p,        /* d5 */
321    t_TM | t_I6p,        /* d6 */
322    t_TM | t_I6p,        /* d7 */
323    t_TM | t_I6p,        /* d8 */
324    t_TM | t_I6p,        /* d9 */
325    t_TM | t_I6p,        /* da */
326    t_TM | t_I6p,        /* db */
327    t_TM | t_I6p,        /* dc */
328    t_TM | t_I6p,        /* dd */
329    t_TM | t_I6p,        /* de */
330    t_TM | t_I6p,        /* df */
331
332    t_TM | t_I6p,        /* e0 */
333    t_TM | t_I6p,        /* e1 */
334    t_TM | t_I6p,        /* e2 */
335    t_TM | t_I6p,        /* e3 */
336    t_TM | t_I6p,        /* e4 */
337    t_TM | t_I6p,        /* e5 */
338    t_TM | t_I6p,        /* e6 */
339    t_TM | t_I6p,        /* e7 */
340    t_TM | t_I6p,        /* e8 */
341    t_TM | t_I6p,        /* e9 */
342    t_TM | t_I6p,        /* ea */
343    t_TM | t_I6p,        /* eb */
344    t_TM | t_I6p,        /* ec */
345    t_TM | t_I6p,        /* ed */
346    t_TM | t_I6p,        /* ee */
347    t_TM | t_I6p,        /* ef */
348
349    t_TM | t_I6p,        /* f0 */
350    t_TM | t_I6p,        /* f1 */
351    t_TM | t_I6p,        /* f2 */
352    t_TM | t_I6p,        /* f3 */
353    t_TM | t_I6p,        /* f4 */
354    t_TM | t_I6p,        /* f5 */
355    t_TM | t_I6p,        /* f6 */
356    t_TM | t_I6p,        /* f7 */
357    t_TM | t_I6p,        /* f8 */
358    t_TM | t_I6p,        /* f9 */
359    t_TM | t_I6p,        /* fa */
360    t_TM | t_I6p,        /* fb */
361    t_TM | t_I6p,        /* fc */
362    t_TM | t_I6p,        /* fd */
363    t_TM | t_I6p,        /* fe */
364    t_TM | t_I6p,        /* ff */
365};
366
16367CPU_DISASSEMBLE( pps4 )
17368{
18   UINT32 flags = 0;
19   unsigned PC = pc;
20   UINT8 op;
21   switch (op = OP(pc++))
22   {
23      // Arithmetic instructions
24      case 0x0b:  sprintf (buffer,"ad");  break;
25      case 0x0a:  sprintf (buffer,"adc"); break;
26      case 0x09:  sprintf (buffer,"adsk");    break;
27      case 0x08:  sprintf (buffer,"adcsk");   break;
28      case 0x60:  case 0x61:  case 0x62:  case 0x63:
29      case 0x64:  case 0x66:  case 0x67:  case 0x68:
30      case 0x69:  case 0x6a:  case 0x6b:  case 0x6c:
31      case 0x6d:  case 0x6e:
32               sprintf (buffer,"adi %01x",(op & 0x0f));    break;
33      case 0x65:  sprintf (buffer,"dc");  break;
34      // Logical instructions
35      case 0x0d:  sprintf (buffer,"and"); break;
36      case 0x0f:  sprintf (buffer,"or");  break;
37      case 0x0c:  sprintf (buffer,"eor"); break;
38      case 0x0e:  sprintf (buffer,"comp");    break;
39      // Data transfer instructions
40      case 0x20:  sprintf (buffer,"sc");  break;
41      case 0x24:  sprintf (buffer,"rc");  break;
42      case 0x22:  sprintf (buffer,"sf1"); break;
43      case 0x26:  sprintf (buffer,"rf1"); break;
44      case 0x21:  sprintf (buffer,"sf2"); break;
45      case 0x25:  sprintf (buffer,"rf2"); break;
46      case 0x30:  case 0x31:  case 0x32:  case 0x33:
47      case 0x34:  case 0x35:  case 0x36:  case 0x37:
48               sprintf (buffer,"ld %01x",(op & 0x07)); break;
49      case 0x38:  case 0x39:  case 0x3a:  case 0x3b:
50      case 0x3c:  case 0x3d:  case 0x3e:  case 0x3f:
51               sprintf (buffer,"ex %01x",(op & 0x07)); break;
52      case 0x28:  case 0x29:  case 0x2a:  case 0x2b:
53      case 0x2c:  case 0x2d:  case 0x2e:  case 0x2f:
54               sprintf (buffer,"exd %01x",(op & 0x07));    break;
55      case 0x70:  case 0x71:  case 0x72:  case 0x73:
56      case 0x74:  case 0x75:  case 0x76:  case 0x77:
57               sprintf (buffer,"ldi %01x",(op & 0x0f));    break;
58      case 0x12:  sprintf (buffer,"lax"); break;
59      case 0x1b:  sprintf (buffer,"lxa"); break;
60      case 0x11:  sprintf (buffer,"labl");    break;
61      case 0x10:  sprintf (buffer,"lbmx");    break;
62      case 0x04:  sprintf (buffer,"lbua");    break;
63      case 0x19:  sprintf (buffer,"xabl");    break;
64      case 0x18:  sprintf (buffer,"xbmx");    break;
65      case 0x1a:  sprintf (buffer,"xax"); break;
66      case 0x06:  sprintf (buffer,"xs");  break;
67      case 0x6f:  sprintf (buffer,"cys"); break;
68      case 0xc0:  case 0xc1:  case 0xc2:  case 0xc3:
69      case 0xc4:  case 0xc5:  case 0xc6:  case 0xc7:
70      case 0xc8:  case 0xc9:  case 0xca:  case 0xcb:
71      case 0xcc:  case 0xcd:  case 0xce:  case 0xcf:
72               sprintf (buffer,"lb %02x",ARG(pc)); pc++;   break;
73      case 0x00:  sprintf (buffer,"lbl %02x",ARG(pc)); pc++;  break;
74      case 0x17:  sprintf (buffer,"incb");    break;
75      case 0x1f:  sprintf (buffer,"decb");    break;
76      // Control transfer instructions
77      case 0x80:  case 0x81:  case 0x82:  case 0x83:
78      case 0x84:  case 0x85:  case 0x86:  case 0x87:
79      case 0x88:  case 0x89:  case 0x8a:  case 0x8b:
80      case 0x8c:  case 0x8d:  case 0x8e:  case 0x8f:
81      case 0x90:  case 0x91:  case 0x92:  case 0x93:
82      case 0x94:  case 0x95:  case 0x96:  case 0x97:
83      case 0x98:  case 0x99:  case 0x9a:  case 0x9b:
84      case 0x9c:  case 0x9d:  case 0x9e:  case 0x9f:
85      case 0xa0:  case 0xa1:  case 0xa2:  case 0xa3:
86      case 0xa4:  case 0xa5:  case 0xa6:  case 0xa7:
87      case 0xa8:  case 0xa9:  case 0xaa:  case 0xab:
88      case 0xac:  case 0xad:  case 0xae:  case 0xaf:
89      case 0xb0:  case 0xb1:  case 0xb2:  case 0xb3:
90      case 0xb4:  case 0xb5:  case 0xb6:  case 0xb7:
91      case 0xb8:  case 0xb9:  case 0xba:  case 0xbb:
92      case 0xbc:  case 0xbd:  case 0xbe:  case 0xbf:
93               sprintf (buffer,"t %02x",(op & 0x3f));  break;
94      case 0xd0:  case 0xd1:  case 0xd2:  case 0xd3:
95      case 0xd4:  case 0xd5:  case 0xd6:  case 0xd7:
96      case 0xd8:  case 0xd9:  case 0xda:  case 0xdb:
97      case 0xdc:  case 0xdd:  case 0xde:  case 0xdf:
98      case 0xe0:  case 0xe1:  case 0xe2:  case 0xe3:
99      case 0xe4:  case 0xe5:  case 0xe6:  case 0xe7:
100      case 0xe8:  case 0xe9:  case 0xea:  case 0xeb:
101      case 0xec:  case 0xed:  case 0xee:  case 0xef:
102      case 0xf0:  case 0xf1:  case 0xf2:  case 0xf3:
103      case 0xf4:  case 0xf5:  case 0xf6:  case 0xf7:
104      case 0xf8:  case 0xf9:  case 0xfa:  case 0xfb:
105      case 0xfc:  case 0xfd:  case 0xfe:  case 0xff:
106               sprintf (buffer,"tm %02x %02x",(op & 0x3f),ARG(pc)); pc++;  break;
107      case 0x50:  case 0x51:  case 0x52:  case 0x53:
108      case 0x54:  case 0x55:  case 0x56:  case 0x57:
109      case 0x58:  case 0x59:  case 0x5a:  case 0x5b:
110      case 0x5c:  case 0x5d:  case 0x5e:  case 0x5f:
111               sprintf (buffer,"tl %01x %02x",(op & 0x0f),ARG(pc)); pc++;  break;
112      case 0x01:  case 0x02:  case 0x03:
113               sprintf (buffer,"tml %02x",ARG(pc)); pc++;  break;
114      case 0x15:  sprintf (buffer,"skc"); break;
115      case 0x1e:  sprintf (buffer,"skz"); break;
116      case 0x40:  case 0x41:  case 0x42:  case 0x43:
117      case 0x44:  case 0x45:  case 0x46:  case 0x47:
118      case 0x48:  case 0x49:  case 0x4a:  case 0x4b:
119      case 0x4c:  case 0x4d:  case 0x4e:  case 0x4f:
120               sprintf (buffer,"skbi %01x",(op & 0x0f));   break;
121      case 0x16:  sprintf (buffer,"skf1");    break;
122      case 0x14:  sprintf (buffer,"skf2");    break;
123      case 0x05:  sprintf (buffer,"rtn"); break;
124      case 0x07:  sprintf (buffer,"rtnsk");   break;
125      // Input/Output instructions
126      case 0x1c:  sprintf (buffer,"iol %02x",ARG(pc)); pc++;  break;
127      case 0x27:  sprintf (buffer,"dia"); break;
128      case 0x23:  sprintf (buffer,"dib"); break;
129      case 0x1d:  sprintf (buffer,"doa"); break;
130      // Special instructions
131      case 0x13:  sprintf (buffer,"sag"); break;
132   }
369    UINT32 flags = 0;
370    unsigned PC = pc;
371    UINT8 op = OP(pc++);
372    UINT32 tok = table[op];
373    char *dst = 0;
133374
134   return (pc - PC) | flags | DASMFLAG_SUPPORTED;
375    if (0 == (tok & t_MASK))
376        sprintf(buffer, "%s", token_str[tok & t_MASK]);
377    else
378        dst = buffer + sprintf(buffer, "%-7s", token_str[tok & t_MASK]);
379
380    if (tok & t_I3c) {
381        // 3 bit immediate, complemented
382        UINT8 i = ~op & 7;
383        dst += sprintf(dst, "%x", i);
384    }
385
386    if (tok & t_I4) {
387        // 4 bit immediate
388        UINT8 i = op & 15;
389        dst += sprintf(dst, "%x", i);
390    }
391
392    if (tok & t_I4c) {
393        // 4 bit immediate, complemented
394        UINT8 i = ~op & 15;
395        dst += sprintf(dst, "%x", i);
396    }
397
398    if (tok & t_I4p) {
399        // 4 bit immediate offset into page 3
400        UINT8 i = op & 15;
401        dst += sprintf(dst, "[%x]", 0x0c0 | i);
402    }
403
404    if (tok & t_I6p) {
405        // 6 bit immediate offset into current page
406        UINT8 i = op & 63;
407        dst += sprintf(dst, "%x", (PC & ~63) | i);
408    }
409
410    if (tok & t_I8) {
411        // 8 bit immediate I/O port address
412        UINT8 arg = ARG(pc++);
413        dst += sprintf(dst, "%02x", arg);
414    }
415
416    if (tok & t_I8c) {
417        // 8 bit immediate offset into page
418        UINT16 arg = ~ARG(pc++) & 255;
419        dst += sprintf(dst, "%03x", arg);
420    }
421
422    if (0x05 == op || 0x07 == op)   // RTN or RTNSK
423            flags |= DASMFLAG_STEP_OUT;
424
425    return (pc - PC) | flags | DASMFLAG_SUPPORTED;
135426}


Previous 199869 Revisions Next


© 1997-2024 The MAME Team