Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cpuinstr/add.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ static void add(struct cpu *cpu, WORD op)
}

if(op & 0x100) {
ea_begin_modify(cpu, op, r, 0, long_ops(op), 0, 0);
ea_begin_modify_ugly(cpu, op, r, 0, long_ops(op), 0, 0);
cpu_set_flags_add(cpu, cpu->d[reg]&m, operand&m, r&m, r);
} else {
cpu_set_flags_add(cpu, operand&m, cpu->d[reg]&m, r&m, r);
Expand Down
57 changes: 23 additions & 34 deletions cpuinstr/clr.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@
#include "cpu.h"
#include "cprint.h"
#include "ea.h"

#define CLR_READ 1
#define CLR_PREFETCH 2
#define CLR_WRITE 3
#include "ucode.h"

/*
* --------------------------------------------------------------------
Expand All @@ -32,41 +29,33 @@
* (xxx).W | 12(1/2) 12(3/0) | np nR nr | np nw nW
* (xxx).L | 12(1/2) 16(4/0) | np np nR nr | np nw nW
*/
static void clr(struct cpu *cpu, WORD op)

static void clr_compute(struct cpu *cpu, WORD op)
{
LONG operand;
ENTER;
ea_set_data(0);
cpu_set_flags_clr(cpu);

switch(cpu->instr_state) {
case INSTR_STATE_NONE:
ea_begin_read(cpu, op);
cpu->instr_state = CLR_READ;
// Fall through.
case CLR_READ:
if(!ea_done(&operand)) {
ADD_CYCLE(2);
break;
} else {
cpu->instr_state = CLR_PREFETCH;
}
// Fall through.
case CLR_PREFETCH:
ADD_CYCLE(4);
cpu_prefetch();
cpu->instr_state = CLR_WRITE;
ea_begin_modify(cpu, op, 0, 0, 2, 0, 0);
break;
case CLR_WRITE:
if(ea_done(&operand)) {
cpu->instr_state = INSTR_STATE_FINISHED;
} else {
ADD_CYCLE(2);
}
cpu_set_flags_clr(cpu);
break;
if((op & 0xc38) == 0x800) {
ujump(nop_uops, 1);
} else {
ujump(0, 0);
}
}

static u_sequence clr_seq[] =
{
ea_begin_read,
u_prefetch,
clr_compute,
ea_begin_modify,
u_end_sequence
};

static void clr(struct cpu *cpu, WORD op)
{
u_start_sequence(clr_seq, cpu, op);
}

static struct cprint *clr_print(LONG addr, WORD op)
{
struct cprint *ret;
Expand Down
14 changes: 12 additions & 2 deletions cpuinstr/ea.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,13 +247,18 @@ void ea_begin_read(struct cpu *cpu, WORD op)
}
}

void ea_begin_modify(struct cpu *cpu, WORD op)
{
ea_begin_modify_ugly(cpu, op, ea_data, 0, 0, 0, 0);
}

static uop_t write_reg_uops[] = { n, n, n };
static uop_t write_mem_uops[] = { w, n, w, n };

// dw, dl, aw, al are the number of additional microcycles needed to
// write a data or address register with a word or a long.
void ea_begin_modify(struct cpu *cpu, WORD op, LONG data,
int dw, int dl, int aw, int al)
void ea_begin_modify_ugly(struct cpu *cpu, WORD op, LONG data,
int dw, int dl, int aw, int al)
{
// Byte/Word Long
// Dn, An, Mem Dn, An, Mem
Expand Down Expand Up @@ -339,6 +344,11 @@ int ea_done(LONG *operand)
return 0;
}

void ea_set_data(LONG data)
{
ea_data = data;
}

LONG ea_get_address(void)
{
return ea_address;
Expand Down
5 changes: 4 additions & 1 deletion cpuinstr/ea.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,11 @@ void ea_clear_prefetch_before_write();
void ea_begin_address(struct cpu *cpu, WORD op);
void ea_begin_read(struct cpu *cpu, WORD op);
void ea_begin_write(struct cpu *cpu, WORD op);
void ea_begin_modify(struct cpu *cpu, WORD op, LONG data, int, int, int, int);
void ea_begin_modify(struct cpu *cpu, WORD op);
int ea_done(LONG *);
void ea_begin_modify_ugly(struct cpu *cpu, WORD op, LONG data, int, int, int, int);
int ea_done(LONG *);
void ea_set_data(LONG data);
LONG ea_get_address(void);

#endif
66 changes: 33 additions & 33 deletions cpuinstr/exg.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
#include "common.h"
#include "cpu.h"
#include "cprint.h"

#define EXG_IN_PROGRESS 1
#include "ucode.h"

/*
* --------------------------------------------------------------------
Expand All @@ -14,43 +13,44 @@
* Ax,Ay | 6(1/0) | np n
* Dx,Ay | 6(1/0) | np n
*/
static void exg(struct cpu *cpu, WORD op)
static void exg_compute(struct cpu *cpu, WORD op)
{
int rx, ry;
LONG t;
int rx,ry;

ENTER;

switch(cpu->instr_state) {
case INSTR_STATE_NONE:
ADD_CYCLE(4);
cpu->instr_state = EXG_IN_PROGRESS;
cpu_prefetch();
rx = (op&0xe00)>>9;
ry = (op&7);
switch(op&0xf8) {
case 0x40: /* Dx,Dy */
t = cpu->d[rx];
cpu->d[rx] = cpu->d[ry];
cpu->d[ry] = t;
break;
case EXG_IN_PROGRESS:
rx = (op&0xe00)>>9;
ry = (op&7);
switch(op&0xf8) {
case 0x40: /* Dx,Dy */
t = cpu->d[rx];
cpu->d[rx] = cpu->d[ry];
cpu->d[ry] = t;
break;
case 0x48:/* Ax,Ay */
t = cpu->a[rx];
cpu->a[rx] = cpu->a[ry];
cpu->a[ry] = t;
break;
case 0x88:/* Dx,Ay */
t = cpu->d[rx];
cpu->d[rx] = cpu->a[ry];
cpu->a[ry] = t;
break;
}
ADD_CYCLE(2);
cpu->instr_state = INSTR_STATE_FINISHED;
case 0x48:/* Ax,Ay */
t = cpu->a[rx];
cpu->a[rx] = cpu->a[ry];
cpu->a[ry] = t;
break;
case 0x88:/* Dx,Ay */
t = cpu->d[rx];
cpu->d[rx] = cpu->a[ry];
cpu->a[ry] = t;
break;
}

ujump(nop_uops, 1);
}

static u_sequence exg_seq[] =
{
u_prefetch,
exg_compute,
u_end_sequence
};

static void exg(struct cpu *cpu, WORD op)
{
u_start_sequence(exg_seq, cpu, op);
}

static struct cprint *exg_print(LONG addr, WORD op)
Expand Down
2 changes: 1 addition & 1 deletion cpuinstr/neg.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static void neg(struct cpu *cpu, WORD op)
cpu_prefetch();
cpu->instr_state = NEG_WRITE;
r = -operand;
ea_begin_modify(cpu, op, r, 0, 2, 0, 0);
ea_begin_modify_ugly(cpu, op, r, 0, 2, 0, 0);

switch((op&0xc0)>>6) {
case 0: m = 0x80; r &= 0xff; break;
Expand Down
2 changes: 1 addition & 1 deletion cpuinstr/negx.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ static void negx(struct cpu *cpu, WORD op)
if(CHKX) {
r--;
}
ea_begin_modify(cpu, op, r, 0, 2, 0, 0);
ea_begin_modify_ugly(cpu, op, r, 0, 2, 0, 0);

switch((op&0xc0)>>6) {
case 0: m = 0x80; r &= 0xff; break;
Expand Down
8 changes: 4 additions & 4 deletions cpuinstr/not.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
*/
static void not(struct cpu *cpu, WORD op)
{
LONG operand, r, m = 0;
LONG operand, m = 0;
ENTER;

switch(cpu->instr_state) {
Expand All @@ -54,11 +54,11 @@ static void not(struct cpu *cpu, WORD op)
ADD_CYCLE(4);
cpu_prefetch();
cpu->instr_state = NOT_WRITE;
ea_begin_modify(cpu, op, ~operand, 0, 2, 0, 0);
ea_begin_modify_ugly(cpu, op, ~operand, 0, 2, 0, 0);

switch((op&0xc0)>>6) {
case 0: m = 0x80; r &= 0xff; break;
case 1: m = 0x8000; r &= 0xffff; break;
case 0: m = 0x80; break;
case 1: m = 0x8000; break;
case 2: m = 0x80000000; break;
}
cpu_set_flags_move(cpu, operand & m, operand);
Expand Down
2 changes: 1 addition & 1 deletion cpuinstr/sub.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ static void sub(struct cpu *cpu, WORD op)

if(op & 0x100) {
r = operand - cpu->d[reg];
ea_begin_modify(cpu, op, r, 0, long_ops(op), 0, 0);
ea_begin_modify_ugly(cpu, op, r, 0, long_ops(op), 0, 0);
cpu_set_flags_sub(cpu, cpu->d[reg]&m1, operand&m1, r&m1, r&m2);
} else {
r = cpu->d[reg] - operand;
Expand Down
48 changes: 48 additions & 0 deletions cpuinstr/ucode.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#include "common.h"
#include "ucode.h"

#define INSTR_STATE_RUNNING 1

static u_sequence *seq_pointer;

static int ucycles;
static uop_t *upc;

Expand All @@ -20,3 +25,46 @@ int ustep(void)

return 0;
}

void u_start_sequence(u_sequence *seq, struct cpu *cpu, WORD op)
{
if(cpu->instr_state == INSTR_STATE_NONE) {
cpu->instr_state = INSTR_STATE_RUNNING;
seq_pointer = seq;
ujump(0, 0);
}

while(ustep()) {
(*seq_pointer)(cpu, op);
seq_pointer++;
if(cpu->instr_state == INSTR_STATE_FINISHED)
break;
else
ADD_CYCLE(2);
}
}

void u_end_sequence(struct cpu *cpu, WORD op)
{
cpu->instr_state = INSTR_STATE_FINISHED;
ujump(0, 0);
}

// Do nothing.
static void u_nop(void)
{
}

// Fetch from program.
static void u_pf(void)
{
cpu_prefetch();
}

uop_t nop_uops[] = { u_nop, u_nop };
static uop_t prefetch_uops[] = { u_pf, u_nop };

void u_prefetch(struct cpu *cpu, WORD op)
{
ujump(prefetch_uops, 2);
}
7 changes: 7 additions & 0 deletions cpuinstr/ucode.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
#ifndef UCODE_H
#define UCODE_H

typedef void (*u_sequence)(struct cpu *cpu, WORD op);
extern void u_start_sequence(u_sequence *, struct cpu *, WORD);
extern void u_end_sequence(struct cpu *, WORD);
extern void u_prefetch(struct cpu *, WORD);

typedef void (*uop_t)(void);
extern void ujump(uop_t *, int);
extern int ustep(void);

extern uop_t nop_uops[];

#endif /* UCODE_H */