Refactored the CDP1802 CPU core to use the new memory functions.

This commit is contained in:
Curt Coder 2008-11-19 17:46:39 +00:00
parent fff915b5e5
commit e0d6d1323d
2 changed files with 145 additions and 93 deletions

View File

@ -1,3 +1,5 @@
#define NO_LEGACY_MEMORY_HANDLERS 1
#include "driver.h"
#include "debugger.h"
#include "cdp1802.h"
@ -9,7 +11,8 @@
#define CDP1802_CYCLES_DMA 8
#define CDP1802_CYCLES_INTERRUPT 8
enum
typedef enum _cdp1802_cpu_state cdp1802_cpu_state;
enum _cdp1802_cpu_state
{
CDP1802_STATE_0_FETCH,
CDP1802_STATE_1_RESET,
@ -25,20 +28,42 @@ struct _cdp1802_state
{
const cdp1802_interface *intf;
UINT8 p, x, d, b, t;
UINT16 r[16];
UINT8 df, ie, q, n, i;
const address_space *program;
const address_space *io;
int state;
int prevmode, mode;
int irq, dmain, dmaout;
int ef;
/* registers */
UINT8 d; /* data register (accumulator) */
UINT8 df; /* data flag (ALU carry) */
UINT8 b; /* auxiliary holding register */
UINT16 r[16]; /* scratchpad registers */
UINT8 p; /* designates which register is Program Counter */
UINT8 x; /* designates which register is Data Pointer */
UINT8 n; /* low-order instruction digit */
UINT8 i; /* high-order instruction digit */
UINT8 t; /* temporary register */
int ie; /* interrupt enable */
int q; /* output flip-flop */
int icount;
/* cpu state */
cdp1802_cpu_state state; /* processor state */
cdp1802_control_mode mode; /* control mode */
cdp1802_control_mode prevmode; /* previous control mode */
/* input lines */
int irq; /* interrupt request */
int dmain; /* DMA input request */
int dmaout; /* DMA output request */
int ef; /* external flags */
/* execution logic */
int icount; /* instruction counter */
};
#define M program_read_byte
#define MW program_write_byte
#define OPCODE_R(addr) memory_decrypted_read_byte(cdp1802->program, addr)
#define RAM_R(addr) memory_read_byte_8le(cdp1802->program, addr)
#define RAM_W(addr, data) memory_write_byte_8le(cdp1802->program, addr, data)
#define IO_R(addr) memory_read_byte_8le(cdp1802->io, addr)
#define IO_W(addr, data) memory_write_byte_8le(cdp1802->io, addr, data)
#define P cdp1802->p
#define X cdp1802->x
@ -52,46 +77,6 @@ struct _cdp1802_state
#define N cdp1802->n
#define I cdp1802->i
static CPU_GET_CONTEXT( cdp1802 )
{
}
static CPU_SET_CONTEXT( cdp1802 )
{
}
static CPU_INIT( cdp1802 )
{
cdp1802_state *cdp1802 = device->token;
cdp1802->intf = (cdp1802_interface *) device->static_config;
cdp1802->mode = CDP1802_MODE_RESET;
cdp1802->prevmode = cdp1802->mode;
cdp1802->irq = CLEAR_LINE;
cdp1802->dmain = CLEAR_LINE;
cdp1802->dmaout = CLEAR_LINE;
state_save_register_item("cdp1802", device->tag, 0, cdp1802->p);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->x);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->d);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->b);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->t);
state_save_register_item_array("cdp1802", device->tag, 0, cdp1802->r);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->df);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->ie);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->q);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->n);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->i);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->state);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->prevmode);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->mode);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->irq);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->dmain);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->dmaout);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->ef);
}
INLINE void cdp1802_add(cdp1802_state *cdp1802, int left, int right)
{
int result = left + right;
@ -126,7 +111,7 @@ INLINE void cdp1802_short_branch(cdp1802_state *cdp1802, int taken)
{
if (taken)
{
R[P] = (R[P] & 0xff00) | program_decrypted_read_byte(R[P]);
R[P] = (R[P] & 0xff00) | OPCODE_R(R[P]);
}
else
{
@ -140,12 +125,12 @@ INLINE void cdp1802_long_branch(cdp1802_state *cdp1802, int taken)
{
// S1#1
B = program_decrypted_read_byte(R[P]);
B = OPCODE_R(R[P]);
R[P] = R[P] + 1;
// S1#2
R[P] = (B << 8) | program_decrypted_read_byte(R[P]);
R[P] = (B << 8) | OPCODE_R(R[P]);
}
else
{
@ -202,6 +187,8 @@ static void cdp1802_output_state_code(const device_config *device)
break;
case CDP1802_STATE_1_EXECUTE:
case CDP1802_STATE_1_RESET:
case CDP1802_STATE_1_INIT:
state_code = CDP1802_STATE_CODE_S1_EXECUTE;
break;
@ -267,7 +254,7 @@ static void cdp1802_run(const device_config *device)
case CDP1802_STATE_0_FETCH:
{
UINT8 opcode = program_decrypted_read_byte(R[P]);
UINT8 opcode = OPCODE_R(R[P]);
I = opcode >> 4;
N = opcode & 0x0f;
@ -288,7 +275,7 @@ static void cdp1802_run(const device_config *device)
case 0:
if (N > 0)
{
D = M(R[N]);
D = RAM_R(R[N]);
}
break;
@ -370,12 +357,12 @@ static void cdp1802_run(const device_config *device)
break;
case 4:
D = M(R[N]);
D = RAM_R(R[N]);
R[N] = R[N] + 1;
break;
case 5:
MW(R[N], D);
RAM_W(R[N], D);
break;
case 6:
@ -392,7 +379,7 @@ static void cdp1802_run(const device_config *device)
case 5:
case 6:
case 7:
io_write_byte(N, M(R[X]));
IO_W(N, RAM_R(R[X]));
R[X] = R[X] + 1;
break;
@ -423,8 +410,8 @@ static void cdp1802_run(const device_config *device)
case 0xe:
case 0xf:
{
UINT8 data = io_read_byte(N & 0x07);
MW(R[X], data);
UINT8 data = IO_R(N & 0x07);
RAM_W(R[X], data);
D = data;
}
break;
@ -436,7 +423,7 @@ static void cdp1802_run(const device_config *device)
{
case 0:
{
UINT8 data = M(R[X]);
UINT8 data = RAM_R(R[X]);
R[X] = R[X] + 1;
P = data & 0xf;
X = data >> 4;
@ -446,7 +433,7 @@ static void cdp1802_run(const device_config *device)
case 1:
{
UINT8 data = M(R[X]);
UINT8 data = RAM_R(R[X]);
R[X] = R[X] + 1;
P = data & 0xf;
X = data >> 4;
@ -455,21 +442,21 @@ static void cdp1802_run(const device_config *device)
break;
case 2:
D = M(R[X]);
D = RAM_R(R[X]);
R[X] = R[X] + 1;
break;
case 3:
MW(R[X], D);
RAM_W(R[X], D);
R[X] = R[X] - 1;
break;
case 4:
cdp1802_add_carry(cdp1802, M(R[X]), D);
cdp1802_add_carry(cdp1802, RAM_R(R[X]), D);
break;
case 5:
cdp1802_sub_carry(cdp1802, M(R[X]), D);
cdp1802_sub_carry(cdp1802, RAM_R(R[X]), D);
break;
case 6:
@ -482,18 +469,18 @@ static void cdp1802_run(const device_config *device)
break;
case 7:
cdp1802_sub_carry(cdp1802, D, M(R[X]));
cdp1802_sub_carry(cdp1802, D, RAM_R(R[X]));
break;
case 8:
MW(R[X], T);
RAM_W(R[X], T);
break;
case 9:
{
UINT8 result = (X << 4) | P;
T = result;
MW(R[2], result);
RAM_W(R[2], result);
X = P;
R[2] = R[2] - 1;
}
@ -518,12 +505,12 @@ static void cdp1802_run(const device_config *device)
break;
case 0xc:
cdp1802_add_carry(cdp1802, M(R[P]), D);
cdp1802_add_carry(cdp1802, RAM_R(R[P]), D);
R[P] = R[P] + 1;
break;
case 0xd:
cdp1802_sub_carry(cdp1802, M(R[P]), D);
cdp1802_sub_carry(cdp1802, RAM_R(R[P]), D);
R[P] = R[P] + 1;
break;
@ -537,7 +524,7 @@ static void cdp1802_run(const device_config *device)
break;
case 0xf:
cdp1802_sub_carry(cdp1802, D, M(R[P]));
cdp1802_sub_carry(cdp1802, D, RAM_R(R[P]));
R[P] = R[P] + 1;
break;
}
@ -644,27 +631,27 @@ static void cdp1802_run(const device_config *device)
switch (N)
{
case 0:
D = M(R[X]);
D = RAM_R(R[X]);
break;
case 1:
D = M(R[X]) | D;
D = RAM_R(R[X]) | D;
break;
case 2:
D = M(R[X]) & D;
D = RAM_R(R[X]) & D;
break;
case 3:
D = M(R[X]) ^ D;
D = RAM_R(R[X]) ^ D;
break;
case 4:
cdp1802_add(cdp1802, M(R[X]), D);
cdp1802_add(cdp1802, RAM_R(R[X]), D);
break;
case 5:
cdp1802_sub(cdp1802, M(R[X]), D);
cdp1802_sub(cdp1802, RAM_R(R[X]), D);
break;
case 6:
@ -673,36 +660,36 @@ static void cdp1802_run(const device_config *device)
break;
case 7:
cdp1802_sub(cdp1802, D, M(R[X]));
cdp1802_sub(cdp1802, D, RAM_R(R[X]));
break;
case 8:
D = M(R[P]);
D = RAM_R(R[P]);
R[P] = R[P] + 1;
break;
case 9:
D = M(R[P]) | D;
D = RAM_R(R[P]) | D;
R[P] = R[P] + 1;
break;
case 0xa:
D = M(R[P]) & D;
D = RAM_R(R[P]) & D;
R[P] = R[P] + 1;
break;
case 0xb:
D = M(R[P]) ^ D;
D = RAM_R(R[P]) ^ D;
R[P] = R[P] + 1;
break;
case 0xc:
cdp1802_add(cdp1802, M(R[P]), D);
cdp1802_add(cdp1802, RAM_R(R[P]), D);
R[P] = R[P] + 1;
break;
case 0xd:
cdp1802_sub(cdp1802, M(R[P]), D);
cdp1802_sub(cdp1802, RAM_R(R[P]), D);
R[P] = R[P] + 1;
break;
@ -712,7 +699,7 @@ static void cdp1802_run(const device_config *device)
break;
case 0xf:
cdp1802_sub(cdp1802, D, M(R[P]));
cdp1802_sub(cdp1802, D, RAM_R(R[P]));
R[P] = R[P] + 1;
break;
}
@ -746,7 +733,7 @@ static void cdp1802_run(const device_config *device)
if (cdp1802->intf->dma_r)
{
MW(R[0], cdp1802->intf->dma_r(device, R[0]));
RAM_W(R[0], cdp1802->intf->dma_r(device, R[0]));
}
R[0] = R[0] + 1;
@ -779,7 +766,7 @@ static void cdp1802_run(const device_config *device)
if (cdp1802->intf->dma_w)
{
cdp1802->intf->dma_w(device, R[0], M(R[0]));
cdp1802->intf->dma_w(device, R[0], RAM_R(R[0]));
}
R[0] = R[0] + 1;
@ -900,6 +887,55 @@ static CPU_RESET( cdp1802 )
cdp1802->mode = CDP1802_MODE_RESET;
}
static CPU_INIT( cdp1802 )
{
cdp1802_state *cdp1802 = device->token;
cdp1802->intf = (cdp1802_interface *) device->static_config;
/* get address spaces */
cdp1802->program = cpu_get_address_space(device, ADDRESS_SPACE_PROGRAM);
cdp1802->io = cpu_get_address_space(device, ADDRESS_SPACE_IO);
/* set initial values */
cdp1802->mode = CDP1802_MODE_RESET;
cdp1802->prevmode = cdp1802->mode;
cdp1802->irq = CLEAR_LINE;
cdp1802->dmain = CLEAR_LINE;
cdp1802->dmaout = CLEAR_LINE;
/* register for state saving */
state_save_register_item("cdp1802", device->tag, 0, cdp1802->p);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->x);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->d);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->b);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->t);
state_save_register_item_array("cdp1802", device->tag, 0, cdp1802->r);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->df);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->ie);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->q);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->n);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->i);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->state);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->prevmode);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->mode);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->irq);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->dmain);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->dmaout);
state_save_register_item("cdp1802", device->tag, 0, cdp1802->ef);
}
static CPU_GET_CONTEXT( cdp1802 )
{
}
static CPU_SET_CONTEXT( cdp1802 )
{
}
/**************************************************************************
* Generic set_info
**************************************************************************/
@ -1010,7 +1046,7 @@ CPU_GET_INFO( cdp1802 )
case CPUINFO_INT_REGISTER + CDP1802_N: info->i = cdp1802->n; break;
case CPUINFO_INT_REGISTER + CDP1802_I: info->i = cdp1802->i; break;
case CPUINFO_INT_PC:
case CPUINFO_INT_REGISTER + CDP1802_PC: info->i = cdp1802->r[cdp1802->p]; break;
case CPUINFO_INT_REGISTER + CDP1802_PC: info->i = cdp1802->r[cdp1802->p]; break;
/* --- the following bits of info are returned as pointers to data or functions --- */
case CPUINFO_PTR_SET_INFO: info->setinfo = CPU_SET_INFO_NAME(cdp1802); break;

View File

@ -3,6 +3,20 @@
#ifndef __CDP1802_H__
#define __CDP1802_H__
/*
RCA COSMAC Series Microprocessors
Type Internal ROM Internal RAM Timer
-----------------------------------------------------
CDP1802 none none no
CDP1803 ? ? ?
CDP1804 2 KB 64 bytes yes
CDP1805 none 64 bytes yes
CDP1806 none none yes
*/
#include "cpuintrf.h"
enum
@ -21,7 +35,8 @@ enum
};
typedef enum _cdp1802_control_mode cdp1802_control_mode;
enum _cdp1802_control_mode {
enum _cdp1802_control_mode
{
CDP1802_MODE_LOAD,
CDP1802_MODE_RESET,
CDP1802_MODE_PAUSE,
@ -29,7 +44,8 @@ enum _cdp1802_control_mode {
};
typedef enum _cdp1802_state_code cdp1802_state_code;
enum _cdp1802_state_code {
enum _cdp1802_state_code
{
CDP1802_STATE_CODE_S0_FETCH,
CDP1802_STATE_CODE_S1_EXECUTE,
CDP1802_STATE_CODE_S2_DMA,
@ -48,7 +64,7 @@ enum
CDP1802_T, // Holds old X, P after Interrupt (X is high nibble)
CDP1802_R0, // Scratchpad Register 0
CDP1802_R1,
CDP1802_R1,
CDP1802_R2,
CDP1802_R3,
CDP1802_R4,