forked from len0rd/rockbox
Added dynarec(under construction) and outline for lcd modes
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@6119 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
708e357a63
commit
3921e1aa69
10 changed files with 921 additions and 29 deletions
|
|
@ -21,10 +21,15 @@ DEPFILE = $(OBJDIR)/dep-rockboy
|
||||||
SRC = cpu.c emu.c events.c exports.c fastmem.c hw.c lcd.c lcdc.c loader.c \
|
SRC = cpu.c emu.c events.c exports.c fastmem.c hw.c lcd.c lcdc.c loader.c \
|
||||||
main.c mem.c nosound.c rccmds.c rcvars.c rtc.c save.c sound.c split.c \
|
main.c mem.c nosound.c rccmds.c rcvars.c rtc.c save.c sound.c split.c \
|
||||||
sys_rockbox.c rockboy.c
|
sys_rockbox.c rockboy.c
|
||||||
|
|
||||||
|
#CFLAGS += -DDYNAREC
|
||||||
|
#SRC += dynarec.c
|
||||||
|
|
||||||
SOURCES = $(SRC)
|
SOURCES = $(SRC)
|
||||||
OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
|
OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
|
||||||
DIRS = .
|
DIRS = .
|
||||||
|
|
||||||
|
|
||||||
ifndef SIMVER
|
ifndef SIMVER
|
||||||
ifneq (,$(findstring RECORDER,$(TARGET))) ## Archos recorder targets
|
ifneq (,$(findstring RECORDER,$(TARGET))) ## Archos recorder targets
|
||||||
LDS := archos.lds
|
LDS := archos.lds
|
||||||
|
|
|
||||||
|
|
@ -237,11 +237,23 @@ label: op(b); break;
|
||||||
#define PRE_INT ( DI, PUSH(PC) )
|
#define PRE_INT ( DI, PUSH(PC) )
|
||||||
#define THROW_INT(n) ( (IF &= ~(1<<(n))), (PC = 0x40+((n)<<3)) )
|
#define THROW_INT(n) ( (IF &= ~(1<<(n))), (PC = 0x40+((n)<<3)) )
|
||||||
|
|
||||||
|
#ifdef DYNAREC
|
||||||
|
un32 reg_backup[16];
|
||||||
|
struct dynarec_block *address_map[1<<HASH_SIGNIFICANT_LOWER_BITS];
|
||||||
|
extern void *dynapointer;
|
||||||
|
int blockcount;
|
||||||
|
#define MAXBLOCK 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cpu_reset(void)
|
void cpu_reset(void)
|
||||||
{
|
{
|
||||||
|
union reg acc;
|
||||||
|
#ifdef DYNAREC
|
||||||
|
int i;
|
||||||
|
dynapointer=0;
|
||||||
|
#endif
|
||||||
cpu.speed = 0;
|
cpu.speed = 0;
|
||||||
cpu.halt = 0;
|
cpu.halt = 0;
|
||||||
cpu.div = 0;
|
cpu.div = 0;
|
||||||
|
|
@ -253,13 +265,23 @@ void cpu_reset(void)
|
||||||
|
|
||||||
PC = 0x0100;
|
PC = 0x0100;
|
||||||
SP = 0xFFFE;
|
SP = 0xFFFE;
|
||||||
AF = 0x01B0;
|
W(acc) = 0x01B0;
|
||||||
BC = 0x0013;
|
A=HB(acc);
|
||||||
DE = 0x00D8;
|
F=LB(acc);
|
||||||
|
W(acc) = 0x0013;
|
||||||
|
B=HB(acc);
|
||||||
|
C=LB(acc);
|
||||||
|
W(acc) = 0x00D8;
|
||||||
|
D=HB(acc);
|
||||||
|
E=LB(acc);
|
||||||
HL = 0x014D;
|
HL = 0x014D;
|
||||||
|
|
||||||
if (hw.cgb) A = 0x11;
|
if (hw.cgb) A = 0x11;
|
||||||
if (hw.gba) B = 0x01;
|
if (hw.gba) B = 0x01;
|
||||||
|
#ifdef DYNAREC
|
||||||
|
for(i=0;i<(1<<HASH_SIGNIFICANT_LOWER_BITS);i++)
|
||||||
|
address_map[i]=0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -365,6 +387,10 @@ int cpu_emulate(int cycles)
|
||||||
|
|
||||||
i = cycles;
|
i = cycles;
|
||||||
next:
|
next:
|
||||||
|
#ifdef DYNAREC
|
||||||
|
if(shut)
|
||||||
|
return cycles-i;
|
||||||
|
#endif
|
||||||
if ((clen = cpu_idle(i)))
|
if ((clen = cpu_idle(i)))
|
||||||
{
|
{
|
||||||
i -= clen;
|
i -= clen;
|
||||||
|
|
@ -395,8 +421,10 @@ next:
|
||||||
}
|
}
|
||||||
IME = IMA;
|
IME = IMA;
|
||||||
|
|
||||||
// if (debug_trace) debug_disassemble(PC, 1);
|
/* if (debug_trace) debug_disassemble(PC, 1); */
|
||||||
|
#ifdef DYNAREC
|
||||||
|
if(PC&0x8000) {
|
||||||
|
#endif
|
||||||
op = FETCH;
|
op = FETCH;
|
||||||
clen = cycles_table[op];
|
clen = cycles_table[op];
|
||||||
|
|
||||||
|
|
@ -536,9 +564,25 @@ next:
|
||||||
A = readb(xHL); break;
|
A = readb(xHL); break;
|
||||||
|
|
||||||
case 0x01: /* LD BC,imm */
|
case 0x01: /* LD BC,imm */
|
||||||
BC = readw(xPC); PC += 2; break;
|
#ifdef DYNAREC
|
||||||
|
W(acc) = readw(xPC);
|
||||||
|
B=HB(acc);
|
||||||
|
C=LB(acc);
|
||||||
|
#else
|
||||||
|
BC = readw(xPC);
|
||||||
|
#endif
|
||||||
|
PC += 2;
|
||||||
|
break;
|
||||||
case 0x11: /* LD DE,imm */
|
case 0x11: /* LD DE,imm */
|
||||||
DE = readw(xPC); PC += 2; break;
|
#ifdef DYNAREC
|
||||||
|
W(acc) = readw(xPC);
|
||||||
|
D=HB(acc);
|
||||||
|
E=LB(acc);
|
||||||
|
#else
|
||||||
|
DE = readw(xPC);
|
||||||
|
#endif
|
||||||
|
PC += 2;
|
||||||
|
break;
|
||||||
case 0x21: /* LD HL,imm */
|
case 0x21: /* LD HL,imm */
|
||||||
HL = readw(xPC); PC += 2; break;
|
HL = readw(xPC); PC += 2; break;
|
||||||
case 0x31: /* LD SP,imm */
|
case 0x31: /* LD SP,imm */
|
||||||
|
|
@ -643,9 +687,23 @@ next:
|
||||||
INC(A); break;
|
INC(A); break;
|
||||||
|
|
||||||
case 0x03: /* INC BC */
|
case 0x03: /* INC BC */
|
||||||
INCW(BC); break;
|
#ifdef DYNAREC
|
||||||
|
W(acc)=((B<<8)|C)+1;
|
||||||
|
B=HB(acc);
|
||||||
|
C=LB(acc);
|
||||||
|
#else
|
||||||
|
INCW(BC);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case 0x13: /* INC DE */
|
case 0x13: /* INC DE */
|
||||||
INCW(DE); break;
|
#ifdef DYNAREC
|
||||||
|
W(acc)=((D<<8)|E)+1;
|
||||||
|
D=HB(acc);
|
||||||
|
E=LB(acc);
|
||||||
|
#else
|
||||||
|
INCW(DE);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case 0x23: /* INC HL */
|
case 0x23: /* INC HL */
|
||||||
INCW(HL); break;
|
INCW(HL); break;
|
||||||
case 0x33: /* INC SP */
|
case 0x33: /* INC SP */
|
||||||
|
|
@ -672,9 +730,23 @@ next:
|
||||||
DEC(A); break;
|
DEC(A); break;
|
||||||
|
|
||||||
case 0x0B: /* DEC BC */
|
case 0x0B: /* DEC BC */
|
||||||
DECW(BC); break;
|
#ifdef DYNAREC
|
||||||
|
W(acc)=((B<<8)|C)-1;
|
||||||
|
B=HB(acc);
|
||||||
|
C=LB(acc);
|
||||||
|
#else
|
||||||
|
DECW(BC);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case 0x1B: /* DEC DE */
|
case 0x1B: /* DEC DE */
|
||||||
DECW(DE); break;
|
#ifdef DYNAREC
|
||||||
|
W(acc)=((D<<8)|E)-1;
|
||||||
|
D=HB(acc);
|
||||||
|
E=LB(acc);
|
||||||
|
#else
|
||||||
|
DECW(DE);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case 0x2B: /* DEC HL */
|
case 0x2B: /* DEC HL */
|
||||||
DECW(HL); break;
|
DECW(HL); break;
|
||||||
case 0x3B: /* DEC SP */
|
case 0x3B: /* DEC SP */
|
||||||
|
|
@ -766,11 +838,25 @@ next:
|
||||||
RST(b); break;
|
RST(b); break;
|
||||||
|
|
||||||
case 0xC1: /* POP BC */
|
case 0xC1: /* POP BC */
|
||||||
POP(BC); break;
|
#ifdef DYNAREC
|
||||||
|
POP(W(acc));
|
||||||
|
B=HB(acc);
|
||||||
|
C=LB(acc);
|
||||||
|
#else
|
||||||
|
POP(BC);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case 0xC5: /* PUSH BC */
|
case 0xC5: /* PUSH BC */
|
||||||
PUSH(BC); break;
|
PUSH(BC); break;
|
||||||
case 0xD1: /* POP DE */
|
case 0xD1: /* POP DE */
|
||||||
POP(DE); break;
|
#ifdef DYNAREC
|
||||||
|
POP(W(acc));
|
||||||
|
D=HB(acc);
|
||||||
|
E=LB(acc);
|
||||||
|
#else
|
||||||
|
POP(DE);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
case 0xD5: /* PUSH DE */
|
case 0xD5: /* PUSH DE */
|
||||||
PUSH(DE); break;
|
PUSH(DE); break;
|
||||||
case 0xE1: /* POP HL */
|
case 0xE1: /* POP HL */
|
||||||
|
|
@ -778,7 +864,14 @@ next:
|
||||||
case 0xE5: /* PUSH HL */
|
case 0xE5: /* PUSH HL */
|
||||||
PUSH(HL); break;
|
PUSH(HL); break;
|
||||||
case 0xF1: /* POP AF */
|
case 0xF1: /* POP AF */
|
||||||
POP(AF); break;
|
#ifdef DYNAREC
|
||||||
|
POP(W(acc));
|
||||||
|
A=HB(acc);
|
||||||
|
F=LB(acc);
|
||||||
|
#else
|
||||||
|
POP(AF);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
case 0xF5: /* PUSH AF */
|
case 0xF5: /* PUSH AF */
|
||||||
PUSH(AF); break;
|
PUSH(AF); break;
|
||||||
|
|
||||||
|
|
@ -840,6 +933,64 @@ next:
|
||||||
op, (PC-1) & 0xffff, mbc.rombank);
|
op, (PC-1) & 0xffff, mbc.rombank);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifdef DYNAREC
|
||||||
|
} else { // ROM, dynarec.
|
||||||
|
struct dynarec_block *p=0,*b=address_map[PC&HASH_BITMASK];
|
||||||
|
char meow[500];
|
||||||
|
byte *ptr=mbc.rmap[PC>>12];
|
||||||
|
snprintf(meow,499,"PC: 0x%x 0x%x a: 0x%x\n",
|
||||||
|
ptr,PC, b ? b->address.d : 0);
|
||||||
|
rb->splash(HZ*2,true,meow);
|
||||||
|
while(b&&b->address.d!=(ptr+PC)) {
|
||||||
|
p=b;
|
||||||
|
snprintf(meow,499,"next: 0x%x",b->next ? b->next->address.d : 0);
|
||||||
|
rb->splash(HZ*2,true,meow);
|
||||||
|
b=b->next;
|
||||||
|
}
|
||||||
|
if(b) { // call block
|
||||||
|
int fd;
|
||||||
|
blockcount++;
|
||||||
|
snprintf(meow,499,"/dyna_0x%x.rb",PC);
|
||||||
|
fd=open(meow,O_WRONLY|O_CREAT);
|
||||||
|
if(fd>=0) {
|
||||||
|
fdprintf(fd,"Block 0x%x\n",PC);
|
||||||
|
write(fd,b->block,b->length);
|
||||||
|
fdprintf(fd,"before: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
|
||||||
|
cpu.a,cpu.b,cpu.c,cpu.d,cpu.e,cpu.hl,cpu.f,cpu.sp,cpu.pc,
|
||||||
|
cpu.ime);
|
||||||
|
if(blockcount<MAXBLOCK) {
|
||||||
|
asm volatile ("movem.l (%0),%%d1-%%d7/%%a0-%%a1\n\t"
|
||||||
|
"jsr (%1)\n\t"
|
||||||
|
"movem.l %%d1-%%d7/%%a0-%%a1,(%0)\n\t"
|
||||||
|
:
|
||||||
|
: "a" (&cpu.a), "a" (b->block)
|
||||||
|
: "d0", "d1", "d2", "d3", "d4", "d5", "d6",
|
||||||
|
"d7", "a0","a1", "a2","a3","a4");
|
||||||
|
clen=blockclen;
|
||||||
|
fdprintf(fd,"after: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n",
|
||||||
|
cpu.a,cpu.b,cpu.c,cpu.d,cpu.e,cpu.hl,cpu.f,cpu.sp,
|
||||||
|
cpu.pc,cpu.ime);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
die("end");
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else { // Hash miss -> not found -> recompile block and add it
|
||||||
|
struct dynarec_block *newblock;
|
||||||
|
newblock=malloc(sizeof(struct dynarec_block));
|
||||||
|
memset(newblock,0,sizeof(struct dynarec_block));
|
||||||
|
newblock->address.d=ptr+PC;
|
||||||
|
dynamic_recompile(newblock);
|
||||||
|
if(p)
|
||||||
|
p->next=newblock;
|
||||||
|
else
|
||||||
|
address_map[PC&HASH_BITMASK]=newblock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
clen <<= 1;
|
clen <<= 1;
|
||||||
div_advance(clen);
|
div_advance(clen);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,11 @@ union reg
|
||||||
|
|
||||||
struct cpu
|
struct cpu
|
||||||
{
|
{
|
||||||
|
#ifdef DYNAREC
|
||||||
|
union reg a,b,c,d,e,hl,f,sp,pc;
|
||||||
|
#else
|
||||||
union reg pc, sp, bc, de, hl, af;
|
union reg pc, sp, bc, de, hl, af;
|
||||||
|
#endif
|
||||||
int ime, ima;
|
int ime, ima;
|
||||||
int speed;
|
int speed;
|
||||||
int halt;
|
int halt;
|
||||||
|
|
@ -28,6 +32,20 @@ struct cpu
|
||||||
|
|
||||||
extern struct cpu cpu;
|
extern struct cpu cpu;
|
||||||
|
|
||||||
|
#ifdef DYNAREC
|
||||||
|
struct dynarec_block {
|
||||||
|
union reg address;
|
||||||
|
void *block;
|
||||||
|
int length;
|
||||||
|
struct dynarec_block *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define HASH_SIGNIFICANT_LOWER_BITS 8
|
||||||
|
#define HASH_BITMASK ((1<<HASH_SIGNIFICANT_LOWER_BITS)-1)
|
||||||
|
|
||||||
|
extern struct dynarec_block *address_map[1<<HASH_SIGNIFICANT_LOWER_BITS];
|
||||||
|
extern int blockclen;
|
||||||
|
#endif
|
||||||
|
|
||||||
void cpu_reset(void);
|
void cpu_reset(void);
|
||||||
void div_advance(int cnt);
|
void div_advance(int cnt);
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,27 @@
|
||||||
#define W(r) ((r).w[LO])
|
#define W(r) ((r).w[LO])
|
||||||
#define DW(r) ((r).d)
|
#define DW(r) ((r).d)
|
||||||
|
|
||||||
|
#ifdef DYNAREC
|
||||||
|
#define A LB(cpu.a)
|
||||||
|
#define B LB(cpu.b)
|
||||||
|
#define C LB(cpu.c)
|
||||||
|
#define D LB(cpu.d)
|
||||||
|
#define E LB(cpu.e)
|
||||||
|
#define F LB(cpu.f)
|
||||||
|
#define H HB(cpu.hl)
|
||||||
|
#define L LB(cpu.hl)
|
||||||
|
|
||||||
|
#define xAF ((A<<8)|F)
|
||||||
|
#define xBC ((B<<8)|C)
|
||||||
|
#define xDE ((D<<8)|E)
|
||||||
|
#define AF ((A<<8)|F)
|
||||||
|
#define BC ((B<<8)|C)
|
||||||
|
#define DE ((D<<8)|E)
|
||||||
|
|
||||||
|
#define HL W(cpu.hl)
|
||||||
|
#define xHL DW(cpu.hl)
|
||||||
|
|
||||||
|
#else
|
||||||
#define A HB(cpu.af)
|
#define A HB(cpu.af)
|
||||||
#define F LB(cpu.af)
|
#define F LB(cpu.af)
|
||||||
#define B HB(cpu.bc)
|
#define B HB(cpu.bc)
|
||||||
|
|
@ -27,15 +48,15 @@
|
||||||
#define BC W(cpu.bc)
|
#define BC W(cpu.bc)
|
||||||
#define DE W(cpu.de)
|
#define DE W(cpu.de)
|
||||||
#define HL W(cpu.hl)
|
#define HL W(cpu.hl)
|
||||||
|
|
||||||
#define PC W(cpu.pc)
|
|
||||||
#define SP W(cpu.sp)
|
|
||||||
|
|
||||||
#define xAF DW(cpu.af)
|
#define xAF DW(cpu.af)
|
||||||
#define xBC DW(cpu.bc)
|
#define xBC DW(cpu.bc)
|
||||||
#define xDE DW(cpu.de)
|
#define xDE DW(cpu.de)
|
||||||
#define xHL DW(cpu.hl)
|
#define xHL DW(cpu.hl)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#define PC W(cpu.pc)
|
||||||
|
#define SP W(cpu.sp)
|
||||||
|
|
||||||
#define xPC DW(cpu.pc)
|
#define xPC DW(cpu.pc)
|
||||||
#define xSP DW(cpu.sp)
|
#define xSP DW(cpu.sp)
|
||||||
|
|
||||||
|
|
|
||||||
685
apps/plugins/rockboy/dynarec.c
Normal file
685
apps/plugins/rockboy/dynarec.c
Normal file
|
|
@ -0,0 +1,685 @@
|
||||||
|
#ifdef DYNAREC
|
||||||
|
#include <system.h>
|
||||||
|
#include "rockmacros.h"
|
||||||
|
#include "defs.h"
|
||||||
|
#include "regs.h"
|
||||||
|
#include "hw.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "lcdc.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include "fastmem.h"
|
||||||
|
#include "cpuregs.h"
|
||||||
|
#include "cpucore.h"
|
||||||
|
|
||||||
|
void *dynapointer,*branchp[10];
|
||||||
|
int blockclen;
|
||||||
|
|
||||||
|
#define DWRITEB(a) *((unsigned char *) dynapointer)=(a); dynapointer+=1
|
||||||
|
#define DWRITEW(a) *((unsigned short *) dynapointer)=(a); dynapointer+=2
|
||||||
|
#define DWRITEL(a) *((unsigned long *) dynapointer)=(a); dynapointer+=4
|
||||||
|
#define FETCH (readb(PC++))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dest=0xFF00;
|
||||||
|
* dest&=src;
|
||||||
|
* dest=dest>>8;
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define GETUPPER(src,dest) \
|
||||||
|
DYNA_MOVE_l_i_to_r(0xFF00,(dest)); \
|
||||||
|
DYNA_AND_l_r_to_r((src),(dest)); \
|
||||||
|
DYNA_ASHIFT_l(0,(dest),0,0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* dest&=0xFF;
|
||||||
|
* src&=0xFF;
|
||||||
|
* src=src<<8;
|
||||||
|
* dest|=src;
|
||||||
|
*/
|
||||||
|
#define PUTUPPER(src,dest) \
|
||||||
|
DYNA_AND_l_i_to_r(0xFF,(dest)); \
|
||||||
|
DYNA_AND_l_i_to_r(0xFF,(src)); \
|
||||||
|
DYNA_ASHIFT_l(0,(src),1,0); \
|
||||||
|
DYNA_OR_l_r_to_r((src),(dest))
|
||||||
|
/*
|
||||||
|
* movea.l &cpu.a, %a3
|
||||||
|
* movem.l d1-d7/a0-a1 , (%a3)
|
||||||
|
* jsr (n)
|
||||||
|
* movea.l &cpu.a, %a3
|
||||||
|
* movem.l (%a3), d1-d7/a0-a1
|
||||||
|
*/
|
||||||
|
#define CALL_NATIVE(n) \
|
||||||
|
DYNA_MOVEA_l_i_to_r(&cpu.a,3); \
|
||||||
|
DYNA_MOVEM(3,0x3FE,0); \
|
||||||
|
DYNA_JSR(&writehi); \
|
||||||
|
DYNA_MOVEA_l_i_to_r(&cpu.a,3); \
|
||||||
|
DYNA_MOVEM(3,0x3FE,1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SUBQ 2, %a0 // decrease gb sp
|
||||||
|
* PEA #(n) // push n
|
||||||
|
* PUSH %a0 // push gb sp
|
||||||
|
* call_native writew(SP, (n)
|
||||||
|
* ADDQ 8, %a7
|
||||||
|
*/
|
||||||
|
#define PUSH(n) \
|
||||||
|
DYNA_SUBQ_l_i_to_r(2,0,1); \
|
||||||
|
DYNA_PEA_w_i((n)); \
|
||||||
|
DYNA_PUSH_l_r(0,1); \
|
||||||
|
CALL_NATIVE(&writew); \
|
||||||
|
DYNA_ADDQ_l_i_to_r(0,7,1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PUSH %a0 // push gb sp
|
||||||
|
* call_native readw(SP);
|
||||||
|
* addq 4, a7
|
||||||
|
* addq 2, a0
|
||||||
|
* movea.w %d0, (n)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define POPA(n) \
|
||||||
|
DYNA_PUSH_l_r(0,1); \
|
||||||
|
CALL_NATIVE(&readw); \
|
||||||
|
DYNA_ADDQ_l_i_to_r(4,7,1); \
|
||||||
|
DYNA_ADDQ_l_i_to_r(2,0,1); \
|
||||||
|
DYNA_MOVEA_w_r_to_r(0,(n),0);
|
||||||
|
|
||||||
|
#define ADD(n) \
|
||||||
|
DYNA_MOVEQ_l_i_to_r(0x0,7); \
|
||||||
|
DYNA_MOVE_l_r_to_r(1,0,0); \
|
||||||
|
DYNA_ADD_l_r_to_r((n),1); \
|
||||||
|
DYNA_XOR_l_r_to_r(1,0); \
|
||||||
|
DYNA_XOR_l_r_to_r((n),0); \
|
||||||
|
DYNA_LSHIFT_l(1,0,1,0); \
|
||||||
|
DYNA_AND_l_i_to_r(0x20,0); \
|
||||||
|
DYNA_OR_l_r_to_r(0,7); \
|
||||||
|
DYNA_TST_b_r(1,0); \
|
||||||
|
DYNA_SET_b_r(0,0x7); \
|
||||||
|
DYNA_AND_l_i_to_r(0x80,0); \
|
||||||
|
DYNA_OR_l_r_to_r(0,7); \
|
||||||
|
DYNA_MOVE_l_r_to_r(1,0,0); \
|
||||||
|
DYNA_LSHIFT_l(4,0,0,0); \
|
||||||
|
DYNA_ANDI_l_i_to_r(0x10,0); \
|
||||||
|
DYNA_OR_l_r_to_r(0,7); \
|
||||||
|
DYNA_AND_l_i_to_r(0xFF,1);
|
||||||
|
|
||||||
|
#define SUBTRACT(n) \
|
||||||
|
DYNA_MOVEQ_l_i_to_r(0x40,7); \
|
||||||
|
DYNA_MOVE_l_r_to_r(1,0,0); \
|
||||||
|
DYNA_SUB_l_r_to_r((n),1,0); \
|
||||||
|
DYNA_XOR_l_r_to_r(1,0); \
|
||||||
|
DYNA_XOR_l_r_to_r((n),0); \
|
||||||
|
DYNA_LSHIFT_l(1,0,1,0); \
|
||||||
|
DYNA_AND_l_i_to_r(0x20,0); \
|
||||||
|
DYNA_OR_l_r_to_r(0,7); \
|
||||||
|
DYNA_TST_b_r(1,0); \
|
||||||
|
DYNA_SET_b_r(0,0x7); \
|
||||||
|
DYNA_AND_l_i_to_r(0x80,0); \
|
||||||
|
DYNA_OR_l_r_to_r(0,7); \
|
||||||
|
DYNA_MOVE_l_r_to_r(1,0,0); \
|
||||||
|
DYNA_LSHIFT_l(4,0,0,0); \
|
||||||
|
DYNA_AND_l_i_to_r(0x10,0); \
|
||||||
|
DYNA_OR_l_r_to_r(0,7);
|
||||||
|
|
||||||
|
#define CMP(n) \
|
||||||
|
DYNA_MOVEA_l_r_to_r(1,3,0); \
|
||||||
|
SUBTRACT((n)); \
|
||||||
|
DYNA_MOVE_l_r_to_r(3,1,1);
|
||||||
|
|
||||||
|
#define SUB(n) \
|
||||||
|
SUBTRACT((n)); \
|
||||||
|
DYNA_ANDI_l_i_to_r(0xFF,1);
|
||||||
|
|
||||||
|
|
||||||
|
void DYNA_MOVE_b_r_to_r(un8 src,un8 dest) {
|
||||||
|
DWRITEW(0x1000|(src&0x7)|(dest&0x7)<<9);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_ASHIFT_l(un8 src, un8 dest, int left, int src_is_reg) {
|
||||||
|
unsigned short opcode;
|
||||||
|
opcode=(0xE080)|((src&0x7)<<9)|(dest&0x7);
|
||||||
|
if(left)
|
||||||
|
opcode|=0x100;
|
||||||
|
if(src_is_reg)
|
||||||
|
opcode|=0x20;
|
||||||
|
DWRITEW(opcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_LSHIFT_l(un8 src, un8 dest, int left, int src_is_reg) {
|
||||||
|
unsigned short opcode=0xE088|((src&0x7)<<9)|(dest&0x7);
|
||||||
|
if(left)
|
||||||
|
opcode|=0x100;
|
||||||
|
if(src_is_reg)
|
||||||
|
opcode|=0x20;
|
||||||
|
DWRITEW(opcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_MOVE_l_i_to_r(un32 imm, un8 dest) {
|
||||||
|
DWRITEW(0x203C|(dest&0x7)<<9);
|
||||||
|
DWRITEL(imm); // endianness?
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_MOVE_l_i_to_m(un32 imm, un8 dest_a) {
|
||||||
|
DWRITEW(0x20FC|((dest_a&0x7)<<9));
|
||||||
|
DWRITEL(imm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_MOVE_l_r_to_m(un8 src,un8 dest_a) {
|
||||||
|
DWRITEW(0x2080|(dest_a&0x7)<<9|(src&0x7));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_MOVE_l_r_to_r(un8 src, un8 dest, int src_is_areg) {
|
||||||
|
unsigned short opcode=0x2000|((dest&0x7)<<9)|(src&0x7);
|
||||||
|
if(src_is_areg)
|
||||||
|
opcode|=0x8;
|
||||||
|
DWRITEW(opcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_MOVE_w_r_to_r(un8 src, un8 dest, int src_is_areg) {
|
||||||
|
unsigned short opcode=0x3000|((dest&0x7)<<9)|(src&0x7);
|
||||||
|
if(src_is_areg)
|
||||||
|
opcode|=0x8;
|
||||||
|
DWRITEW(opcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_MOVEQ_l_i_to_r(un8 imm, un8 dest) {
|
||||||
|
DWRITEW(0x7000|((dest&0x7)<<9)|imm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_PEA_w_i(un16 imm) {
|
||||||
|
DWRITEW(0x4878);
|
||||||
|
DWRITEW(imm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_PUSH_l_r(un8 reg,int src_is_areg) {
|
||||||
|
unsigned short value= 0x2F00|(reg&0x7);
|
||||||
|
if(src_is_areg)
|
||||||
|
value|=0x8;
|
||||||
|
DWRITEW(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_MOVEA_l_i_to_r(un32 imm, un8 dest) {
|
||||||
|
DWRITEW(0x207C|(dest&0x7)<<9);
|
||||||
|
DWRITEL(imm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_MOVEA_w_r_to_r(un8 src, un8 dest, int src_is_areg) {
|
||||||
|
unsigned short value=0x3040|((dest&0x7)<<9)|(src&0x7);
|
||||||
|
if(src_is_areg)
|
||||||
|
value|=0x8;
|
||||||
|
DWRITEW(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_MOVEA_l_r_to_r(un8 src, un8 dest, int src_is_areg) {
|
||||||
|
unsigned short value=0x2040|((dest&0x7)<<9)|(src&0x7);
|
||||||
|
if(src_is_areg)
|
||||||
|
value|=0x8;
|
||||||
|
DWRITEW(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DYNA_RET() {
|
||||||
|
DWRITEW(0x4E75);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_AND_l_i_to_r(un32 imm, un8 dest) {
|
||||||
|
DWRITEW(0x0280|(dest&0x7));
|
||||||
|
DWRITEL(imm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_AND_l_r_to_r(un8 src,un8 dest) {
|
||||||
|
DWRITEW(0xC080|((dest&0x7)<<9)|(src&0x7));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_OR_l_r_to_r(un8 src,un8 dest) {
|
||||||
|
DWRITEW(0x8080|((dest&0x7)<<9)|(src&0x7));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_OR_l_i_to_r(un32 imm,un8 dest) {
|
||||||
|
DWRITEW(0x0080|(dest&0x7));
|
||||||
|
DWRITEL(imm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_CLR_l_m(un32 addr) {
|
||||||
|
DWRITEW(0x42B9);
|
||||||
|
DWRITEL(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_CLR_l_r(un8 reg) {
|
||||||
|
DWRITEW(0x4280|(reg&0x7));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_CLR_w_r(un8 reg) {
|
||||||
|
DWRITEW(0x42C0|(reg&0x7));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DYNA_CLR_b_r(un8 reg) {
|
||||||
|
DWRITEW(0x4200|(reg&0x7));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DYNA_ADDQ_l_i_to_r(un8 imm, un8 reg, int dest_is_a) {
|
||||||
|
unsigned short value=0x5080|(imm&0x7)<<9|(reg&0x7);
|
||||||
|
if(dest_is_a)
|
||||||
|
value|=0x8;
|
||||||
|
DWRITEW(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_ADD_l_r_to_r(un8 src, un8 dest, int src_is_areg) {
|
||||||
|
unsigned short value=0xD080|((dest&0x7)<<9)|(src&0x7);
|
||||||
|
if(src_is_areg)
|
||||||
|
value|=0x8;
|
||||||
|
DWRITEW(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_JSR(void *addr) {
|
||||||
|
DWRITEW(0x4EB9);
|
||||||
|
DWRITEL(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_MOVEM(un8 areg,un16 mask, int frommem) {
|
||||||
|
unsigned short value=0x48D0|(areg&0x7);
|
||||||
|
if(frommem)
|
||||||
|
value|=0x400;
|
||||||
|
DWRITEW(value);
|
||||||
|
DWRITEW(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_SUBQ_l_i_to_r(un8 imm, un8 reg, int addr_reg) {
|
||||||
|
unsigned short value=0x5180|(reg&0x7)|((imm&0x7)<<9);
|
||||||
|
if(addr_reg)
|
||||||
|
value|=0x8;
|
||||||
|
DWRITEW(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_SUB_l_r_to_r(un8 src, un8 dest, int is_areg) {
|
||||||
|
unsigned short value=0x9080|((dest&0x7)<<9)|(src&0x7);
|
||||||
|
if(is_areg)
|
||||||
|
value|=0x8;
|
||||||
|
DWRITEW(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_EXT_l(un8 reg) {
|
||||||
|
DWRITEW(0x48C0|(reg&0x7));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_BCC_c(un8 cond, int size,int i) {
|
||||||
|
un32 displace=dynapointer-branchp[i];
|
||||||
|
if(!branchp[i]) {
|
||||||
|
die("Dynarec error! BCC trying to write branch without dummy");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if((size==2&&displace>0x7f) || (size==4 && displace>0x7FFF))
|
||||||
|
die("Dynarec error! BCC invalid displacement");
|
||||||
|
else if(displace>0&&displace<0x7F)
|
||||||
|
*( (unsigned short *) branchp[i])=0x6000|((cond&0xF)<<8)|(displace&0xFF);
|
||||||
|
else if(displace>0x7F&&displace<0x7FFF) {
|
||||||
|
*( (unsigned short *) branchp[i])=0x6000|((cond&0xF)<<8);
|
||||||
|
branchp[i]+=2;
|
||||||
|
*( (unsigned short *) branchp[i])=displace;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
die("Dynarec error! BCC invalid displacement");
|
||||||
|
|
||||||
|
branchp[i]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_DUMMYBRANCH(int size,int i) {
|
||||||
|
branchp[i]=dynapointer;
|
||||||
|
dynapointer+=size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_TST_l_r(un8 reg,int is_areg) {
|
||||||
|
unsigned short opcode=0x4A80|(reg&0x7);
|
||||||
|
if(is_areg)
|
||||||
|
opcode|=0x8;
|
||||||
|
DWRITEW(opcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_TST_b_r(un8 reg,int is_areg) {
|
||||||
|
unsigned short opcode=0x4A00|(reg&0x7);
|
||||||
|
if(is_areg)
|
||||||
|
opcode|=0x8;
|
||||||
|
DWRITEW(opcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DYNA_BTST_l_r(un8 bit, un8 reg) {
|
||||||
|
DWRITEW(0x0800|(reg&0x7));
|
||||||
|
DWRITEW(bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_NEG_l(un8 reg) {
|
||||||
|
DWRITEW(0x4480|(reg&0x7));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_XOR_l_r_to_r(un8 src, un8 dest) {
|
||||||
|
DWRITEW(0xB180|((dest&0x7)<<9)|(src&0x7));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DYNA_SET_b_r(un8 src, un8 cond) {
|
||||||
|
DWRITEW(0x50C0|((cond)&0xF)<<8|(src&0x7));
|
||||||
|
}
|
||||||
|
|
||||||
|
void dynamic_recompile (struct dynarec_block *newblock) {
|
||||||
|
int done=0;
|
||||||
|
byte op;
|
||||||
|
unsigned int oldpc=PC;
|
||||||
|
unsigned short temp;
|
||||||
|
unsigned int tclen=0,clen;
|
||||||
|
char meow[500];
|
||||||
|
dynapointer=malloc(512);
|
||||||
|
newblock->block=dynapointer;
|
||||||
|
|
||||||
|
snprintf(meow,499,"Recompiling 0x%x",oldpc);
|
||||||
|
rb->splash(HZ*3,1,meow);
|
||||||
|
while(!done) {
|
||||||
|
op=FETCH;
|
||||||
|
clen = cycles_table[op];
|
||||||
|
tclen+=clen;
|
||||||
|
switch(op) {
|
||||||
|
case 0x00: /* NOP */
|
||||||
|
case 0x40: /* LD B,B */
|
||||||
|
case 0x49: /* LD C,C */
|
||||||
|
case 0x52: /* LD D,D */
|
||||||
|
case 0x5B: /* LD E,E */
|
||||||
|
case 0x64: /* LD H,H */
|
||||||
|
case 0x6D: /* LD L,L */
|
||||||
|
case 0x7F: /* LD A,A */
|
||||||
|
break;
|
||||||
|
case 0x41: /* LD B,C */
|
||||||
|
DYNA_MOVE_b_r_to_r(3,2);
|
||||||
|
break;
|
||||||
|
case 0x42: /* LD B,D */
|
||||||
|
DYNA_MOVE_b_r_to_r(4,2);
|
||||||
|
break;
|
||||||
|
case 0x43: /* LD B,E */
|
||||||
|
DYNA_MOVE_b_r_to_r(5,2);
|
||||||
|
break;
|
||||||
|
case 0x44: /* LD B,H */
|
||||||
|
GETUPPER(6,0);
|
||||||
|
DYNA_MOVE_b_r_to_r(0,2);
|
||||||
|
break;
|
||||||
|
case 0x45: /* LD B,L */
|
||||||
|
DYNA_MOVE_b_r_to_r(6,2);
|
||||||
|
break;
|
||||||
|
case 0x47: /* LD B,A */
|
||||||
|
DYNA_MOVE_b_r_to_r(1,2);
|
||||||
|
break;
|
||||||
|
case 0x48: /* LD C,B */
|
||||||
|
DYNA_MOVE_b_r_to_r(2,3);
|
||||||
|
break;
|
||||||
|
case 0x4A: /* LD C,D */
|
||||||
|
DYNA_MOVE_b_r_to_r(4,3);
|
||||||
|
break;
|
||||||
|
case 0x4B: /* LD C,E */
|
||||||
|
DYNA_MOVE_b_r_to_r(5,3);
|
||||||
|
break;
|
||||||
|
case 0x4C: /* LD C,H */
|
||||||
|
GETUPPER(6,0);
|
||||||
|
DYNA_MOVE_b_r_to_r(0,3);
|
||||||
|
break;
|
||||||
|
case 0x4D: /* LD C,L */
|
||||||
|
DYNA_MOVE_b_r_to_r(6,3);
|
||||||
|
break;
|
||||||
|
case 0x4F: /* LD C,A */
|
||||||
|
DYNA_MOVE_b_r_to_r(1,3);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x50: /* LD D,B */
|
||||||
|
DYNA_MOVE_b_r_to_r(2,4);
|
||||||
|
break;
|
||||||
|
case 0x51: /* LD D,C */
|
||||||
|
DYNA_MOVE_b_r_to_r(3,4);
|
||||||
|
break;
|
||||||
|
case 0x53: /* LD D,E */
|
||||||
|
DYNA_MOVE_b_r_to_r(5,4);
|
||||||
|
break;
|
||||||
|
case 0x54: /* LD D,H */
|
||||||
|
GETUPPER(6,0);
|
||||||
|
DYNA_MOVE_b_r_to_r(0,4);
|
||||||
|
break;
|
||||||
|
case 0x55: /* LD D,L */
|
||||||
|
DYNA_MOVE_b_r_to_r(6,4);
|
||||||
|
break;
|
||||||
|
case 0x57: /* LD D,A */
|
||||||
|
DYNA_MOVE_b_r_to_r(1,4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x58: /* LD E,B */
|
||||||
|
DYNA_MOVE_b_r_to_r(2,5);
|
||||||
|
break;
|
||||||
|
case 0x59: /* LD E,C */
|
||||||
|
DYNA_MOVE_b_r_to_r(3,5);
|
||||||
|
break;
|
||||||
|
case 0x5A: /* LD E,D */
|
||||||
|
DYNA_MOVE_b_r_to_r(4,5);
|
||||||
|
break;
|
||||||
|
case 0x5C: /* LD E,H */
|
||||||
|
GETUPPER(6,0);
|
||||||
|
DYNA_MOVE_b_r_to_r(0,5);
|
||||||
|
break;
|
||||||
|
case 0x5D: /* LD E,L */
|
||||||
|
DYNA_MOVE_b_r_to_r(6,5);
|
||||||
|
break;
|
||||||
|
case 0x5F: /* LD E,A */
|
||||||
|
DYNA_MOVE_b_r_to_r(1,5);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x60: /* LD H,B */
|
||||||
|
DYNA_MOVE_b_r_to_r(2,0);
|
||||||
|
PUTUPPER(0,6);
|
||||||
|
break;
|
||||||
|
case 0x61: /* LD H,C */
|
||||||
|
DYNA_MOVE_b_r_to_r(3,0);
|
||||||
|
PUTUPPER(0,6);
|
||||||
|
break;
|
||||||
|
case 0x62: /* LD H,D */
|
||||||
|
DYNA_MOVE_b_r_to_r(4,0);
|
||||||
|
PUTUPPER(0,6);
|
||||||
|
break;
|
||||||
|
case 0x63: /* LD H,E */
|
||||||
|
DYNA_MOVE_b_r_to_r(5,0);
|
||||||
|
PUTUPPER(0,6);
|
||||||
|
break;
|
||||||
|
case 0x65: /* LD H,L */
|
||||||
|
DYNA_MOVE_b_r_to_r(6,0);
|
||||||
|
PUTUPPER(0,6);
|
||||||
|
break;
|
||||||
|
case 0x67: /* LD H,A */
|
||||||
|
DYNA_MOVE_b_r_to_r(1,0);
|
||||||
|
PUTUPPER(0,6);
|
||||||
|
break;
|
||||||
|
case 0x68: /* LD L,B */
|
||||||
|
DYNA_MOVE_b_r_to_r(2,6);
|
||||||
|
break;
|
||||||
|
case 0x69: /* LD L,C */
|
||||||
|
DYNA_MOVE_b_r_to_r(3,6);
|
||||||
|
break;
|
||||||
|
case 0x6A: /* LD L,D */
|
||||||
|
DYNA_MOVE_b_r_to_r(4,6);
|
||||||
|
break;
|
||||||
|
case 0x6B: /* LD L,E */
|
||||||
|
DYNA_MOVE_b_r_to_r(5,6);
|
||||||
|
break;
|
||||||
|
case 0x6C: /* LD L,H */
|
||||||
|
GETUPPER(6,0);
|
||||||
|
DYNA_MOVE_b_r_to_r(0,6);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x78: /* LD A,B */
|
||||||
|
DYNA_MOVE_b_r_to_r(2,1);
|
||||||
|
break;
|
||||||
|
case 0x79: /* LD A,C */
|
||||||
|
DYNA_MOVE_b_r_to_r(3,1);
|
||||||
|
break;
|
||||||
|
case 0x7A: /* LD A,D */
|
||||||
|
DYNA_MOVE_b_r_to_r(4,1);
|
||||||
|
break;
|
||||||
|
case 0x7B: /* LD A,E */
|
||||||
|
DYNA_MOVE_b_r_to_r(5,1);
|
||||||
|
break;
|
||||||
|
case 0x7C: /* LD A,H */
|
||||||
|
GETUPPER(5,0);
|
||||||
|
DYNA_MOVE_b_r_to_r(0,1);
|
||||||
|
break;
|
||||||
|
case 0x7D: /* LD A,L */
|
||||||
|
DYNA_MOVE_b_r_to_r(5,1);
|
||||||
|
break;
|
||||||
|
case 0x01: /* LD BC,imm */
|
||||||
|
{ /* warning (do we have endianness right?) */
|
||||||
|
temp=readw(xPC);
|
||||||
|
DYNA_MOVEQ_l_i_to_r((temp&0xFF00)>>8,2);
|
||||||
|
DYNA_MOVEQ_l_i_to_r(temp&0xFF,3);
|
||||||
|
PC+=2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x11: /* LD DE,imm */
|
||||||
|
{ temp=readw(xPC);
|
||||||
|
DYNA_MOVEQ_l_i_to_r((temp&0xFF00)>>8,4);
|
||||||
|
DYNA_MOVEQ_l_i_to_r(temp&0xFF,5);
|
||||||
|
PC += 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x21: /* LD HL,imm */
|
||||||
|
{
|
||||||
|
DYNA_MOVE_l_i_to_r(readw(xPC),6);
|
||||||
|
PC += 2;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x31: /* LD SP,imm */
|
||||||
|
DYNA_MOVEA_l_i_to_r(readw(xPC),0);
|
||||||
|
PC += 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x06: /* LD B,imm */
|
||||||
|
DYNA_MOVEQ_l_i_to_r(FETCH,2);
|
||||||
|
break;
|
||||||
|
case 0x0E: /* LD C,imm */
|
||||||
|
DYNA_MOVEQ_l_i_to_r(FETCH,3);
|
||||||
|
break;
|
||||||
|
case 0x16: /* LD D,imm */
|
||||||
|
DYNA_MOVEQ_l_i_to_r(FETCH,4);
|
||||||
|
break;
|
||||||
|
case 0x1E: /* LD E,imm */
|
||||||
|
DYNA_MOVEQ_l_i_to_r(FETCH,5);
|
||||||
|
break;
|
||||||
|
case 0x26: /* LD H,imm */
|
||||||
|
DYNA_AND_l_i_to_r(0xFF,6);
|
||||||
|
DYNA_OR_l_i_to_r(FETCH<<8,6);
|
||||||
|
break;
|
||||||
|
case 0x2E: /* LD L,imm */
|
||||||
|
DYNA_AND_l_i_to_r(0xFF00,6);
|
||||||
|
DYNA_OR_l_i_to_r(FETCH,6);
|
||||||
|
break;
|
||||||
|
case 0x3E: /* LD A,imm */
|
||||||
|
DYNA_MOVEQ_l_i_to_r(FETCH,1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xF9: /* LD SP,HL */
|
||||||
|
DYNA_MOVEA_w_r_to_r(6,0,0);
|
||||||
|
break;
|
||||||
|
case 0xF3: /* DI */
|
||||||
|
DYNA_CLR_l_m(&cpu.ime);
|
||||||
|
DYNA_CLR_l_m(&cpu.ima);
|
||||||
|
DYNA_CLR_l_m(&cpu.halt);
|
||||||
|
/* cpu.halt = cpu.ima = cpu.ime = 0; */
|
||||||
|
break;
|
||||||
|
case 0xFB: /* EI */
|
||||||
|
DYNA_MOVEQ_l_i_to_r(1,0);
|
||||||
|
DYNA_MOVEA_l_i_to_r(&cpu.ima,3);
|
||||||
|
DYNA_MOVE_l_r_to_m(0,3);
|
||||||
|
/*cpu.ima=1; */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xE0: /* LDH (imm),A */
|
||||||
|
DYNA_PUSH_l_r(1,0);
|
||||||
|
DYNA_PEA_w_i(FETCH);
|
||||||
|
CALL_NATIVE(&writehi);
|
||||||
|
DYNA_ADDQ_l_i_to_r(0,7,1);
|
||||||
|
/*writehi(FETCH, A); */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xC3: /* JP (imm) PC = readw(PC) */
|
||||||
|
PC=readw(PC);
|
||||||
|
done=1;
|
||||||
|
break;
|
||||||
|
case 0xCD: /* CALL (imm) PUSH(PC+2) PC=readw(PC); */
|
||||||
|
PUSH(PC+2);
|
||||||
|
PC=readw(PC);
|
||||||
|
done=1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x97: /* SUB A (halfcarry ?) */
|
||||||
|
DYNA_CLR_l_r(1);
|
||||||
|
DYNA_MOVEQ_l_i_to_r(0xC0,7);
|
||||||
|
break;
|
||||||
|
case 0xF0:
|
||||||
|
DYNA_PEA_w_i(FETCH);
|
||||||
|
CALL_NATIVE(&readhi);
|
||||||
|
DYNA_ADDQ_l_i_to_r(4,7,1);
|
||||||
|
DYNA_MOVE_b_r_to_r(0,1);
|
||||||
|
/*A = readhi(FETCH)*/
|
||||||
|
break;
|
||||||
|
case 0x87: // ADD A,A
|
||||||
|
/* code taken from gcc -O3 output by compiling;
|
||||||
|
* c=(2*b)&0xFF;
|
||||||
|
* a=(c) ? 0 : 0x80 | // zero flag
|
||||||
|
* (0x20 & (c) << 1) | // halfcarry
|
||||||
|
* ((2*b)&0x100)>>4; // carry
|
||||||
|
*/
|
||||||
|
DYNA_MOVE_l_r_to_r(1,0,0); /* move.l d1, d0 */
|
||||||
|
DYNA_ADD_l_r_to_r(0,0,0); /* add.l d0, d0 */
|
||||||
|
DYNA_AND_l_i_to_r(510,0); /* and.l #510, d0 */
|
||||||
|
DYNA_MOVEA_l_r_to_r(0,3,0); /* movea.l d0,a3 */
|
||||||
|
DYNA_CLR_b_r(7); /* clr.b d7 */
|
||||||
|
DYNA_TST_b_r(0,0); /* tst.b d0 */
|
||||||
|
DYNA_DUMMYBRANCH(2,0);
|
||||||
|
DYNA_MOVE_l_r_to_r(1,0,0); /* move.l d1,d0 */
|
||||||
|
DYNA_LSHIFT_l(3,0,0,0); /* lsr.l #3, d0 */
|
||||||
|
DYNA_MOVEQ_l_i_to_r(16,1); /* moveq #16,d1 */
|
||||||
|
DYNA_AND_l_r_to_r(1,0); /* and.l d1 d0 */
|
||||||
|
DYNA_MOVEQ_l_i_to_r(0x80,7); /* moveq #0x80,d7 */
|
||||||
|
DYNA_OR_l_r_to_r(0,7); /* or.l d0, d7 */
|
||||||
|
DYNA_BCC_c(0x6,2,0); /* branch not equal, here */
|
||||||
|
DYNA_MOVE_l_r_to_r(3,1,1); /* move.l a3,d1 */
|
||||||
|
DYNA_AND_l_i_to_r(0xFE,1); /* and.l #0xFE,d1 */
|
||||||
|
DYNA_AND_l_i_to_r(0xB0,7); /* and.l #0xB0,d7 */
|
||||||
|
break;
|
||||||
|
case 0xD0: /* RET NC */
|
||||||
|
DYNA_BTST_l_r(5,7); /* btst #5,d7 */
|
||||||
|
DYNA_DUMMYBRANCH(2,0);
|
||||||
|
POPA(1); /* POP %a1 */
|
||||||
|
DYNA_MOVEA_l_i_to_r(&blockclen,3);
|
||||||
|
DYNA_MOVE_l_i_to_m(tclen,3);
|
||||||
|
DYNA_RET();
|
||||||
|
DYNA_BCC_c(0x6,2,0); /* jump here if not zero (not zero = C) */
|
||||||
|
tclen-=3;
|
||||||
|
break;
|
||||||
|
case 0xFE: /* CMP #<imm> TODO: can be (much) more efficient.*/
|
||||||
|
DYNA_MOVEA_l_r_to_r(2,3,0); /* movea.l %d2, %a3 */
|
||||||
|
DYNA_MOVEQ_l_i_to_r(FETCH,2); /* moveq.l #<FETCH>,%d2 */
|
||||||
|
CMP(2);
|
||||||
|
DYNA_MOVE_l_r_to_r(3,2,1); /* move.l %a3, %d2 */
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
snprintf(meow,499,"unimplemented opcode %d / 0x%x",op,op);
|
||||||
|
die(meow);
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snprintf(meow,499,"end of block, pc:0x%x",PC);
|
||||||
|
rb->splash(HZ*2,true,meow);
|
||||||
|
DYNA_MOVEA_l_i_to_r(&blockclen,3);
|
||||||
|
DYNA_MOVE_l_i_to_m(tclen,3);
|
||||||
|
DYNA_MOVEA_l_i_to_r(PC,1);
|
||||||
|
DYNA_RET();
|
||||||
|
PC=oldpc;
|
||||||
|
setmallocpos(dynapointer);
|
||||||
|
newblock->length=dynapointer-newblock->block;
|
||||||
|
invalidate_icache();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
@ -22,6 +22,7 @@ struct fb
|
||||||
int yuv;
|
int yuv;
|
||||||
int enabled;
|
int enabled;
|
||||||
int dirty;
|
int dirty;
|
||||||
|
int mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -740,9 +740,11 @@ void lcd_refreshline(void)
|
||||||
return; /* should not happen... */
|
return; /* should not happen... */
|
||||||
|
|
||||||
#if LCD_HEIGHT == 64
|
#if LCD_HEIGHT == 64
|
||||||
if (R_LY >= 128 || R_LY & 1) /* calculate only even lines */
|
if ( ((fb.mode==0)&&(R_LY >= 128 || R_LY & 1)) ||
|
||||||
|
((fb.mode==1)&&(R_LY < 16 || R_LY & 1))) /* calculate only even lines */
|
||||||
#else
|
#else
|
||||||
if (R_LY >= 128)
|
if ( ((fb.mode==0)&&(R_LY >= 128)) ||
|
||||||
|
((fb.mode==1)&&(R_LY < 16)))
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -93,6 +93,6 @@ void ev_poll(void);
|
||||||
#define atoi(a) rb->atoi((a))
|
#define atoi(a) rb->atoi((a))
|
||||||
#define strcat(a,b) rb->strcat((a),(b))
|
#define strcat(a,b) rb->strcat((a),(b))
|
||||||
#define snprintf(...) rb->snprintf(__VA_ARGS__)
|
#define snprintf(...) rb->snprintf(__VA_ARGS__)
|
||||||
#define fprintf(...) rb->fdprintf(__VA_ARGS__)
|
#define fdprintf(...) rb->fdprintf(__VA_ARGS__)
|
||||||
#define tolower(_A_) (isupper(_A_) ? (_A_ - 'A' + 'a') : _A_)
|
#define tolower(_A_) (isupper(_A_) ? (_A_ - 'A' + 'a') : _A_)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,11 +45,19 @@ struct svar svars[] =
|
||||||
|
|
||||||
I2("PC ", &PC),
|
I2("PC ", &PC),
|
||||||
I2("SP ", &SP),
|
I2("SP ", &SP),
|
||||||
|
I2("HL ", &HL),
|
||||||
|
#ifdef DYNAREC
|
||||||
|
I1("A ", &A),
|
||||||
|
I1("B ", &A),
|
||||||
|
I1("C ", &A),
|
||||||
|
I1("D ", &A),
|
||||||
|
I1("E ", &A),
|
||||||
|
I1("F ", &A),
|
||||||
|
#else
|
||||||
I2("BC ", &BC),
|
I2("BC ", &BC),
|
||||||
I2("DE ", &DE),
|
I2("DE ", &DE),
|
||||||
I2("HL ", &HL),
|
|
||||||
I2("AF ", &AF),
|
I2("AF ", &AF),
|
||||||
|
#endif
|
||||||
I4("IME ", &cpu.ime),
|
I4("IME ", &cpu.ime),
|
||||||
I4("ima ", &cpu.ima),
|
I4("ima ", &cpu.ima),
|
||||||
I4("spd ", &cpu.speed),
|
I4("spd ", &cpu.speed),
|
||||||
|
|
|
||||||
|
|
@ -81,7 +81,7 @@ void ev_poll(void)
|
||||||
released = ~newbuttonstate & oldbuttonstate;
|
released = ~newbuttonstate & oldbuttonstate;
|
||||||
pressed = newbuttonstate & ~oldbuttonstate;
|
pressed = newbuttonstate & ~oldbuttonstate;
|
||||||
oldbuttonstate = newbuttonstate;
|
oldbuttonstate = newbuttonstate;
|
||||||
|
fb.mode=rb->button_hold();
|
||||||
if(released) {
|
if(released) {
|
||||||
ev.type = EV_RELEASE;
|
ev.type = EV_RELEASE;
|
||||||
if(released & BUTTON_LEFT) { ev.code=PAD_LEFT; ev_postevent(&ev); }
|
if(released & BUTTON_LEFT) { ev.code=PAD_LEFT; ev_postevent(&ev); }
|
||||||
|
|
@ -144,6 +144,7 @@ void vid_begin(void)
|
||||||
fb.enabled=1;
|
fb.enabled=1;
|
||||||
fb.dirty=0;
|
fb.dirty=0;
|
||||||
video_base_buf=fb.ptr=(byte *)frameb;
|
video_base_buf=fb.ptr=(byte *)frameb;
|
||||||
|
fb.mode=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void vid_update(int scanline)
|
void vid_update(int scanline)
|
||||||
|
|
@ -152,8 +153,8 @@ void vid_update(int scanline)
|
||||||
byte *frameb;
|
byte *frameb;
|
||||||
#if LCD_HEIGHT == 64 /* Archos */
|
#if LCD_HEIGHT == 64 /* Archos */
|
||||||
int balance = 0;
|
int balance = 0;
|
||||||
if (scanline >= 128)
|
if (fb.mode==1)
|
||||||
return;
|
scanline-=16;
|
||||||
scanline_remapped = scanline / 16;
|
scanline_remapped = scanline / 16;
|
||||||
frameb = rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH;
|
frameb = rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH;
|
||||||
while (cnt < 160) {
|
while (cnt < 160) {
|
||||||
|
|
@ -225,8 +226,8 @@ void vid_update(int scanline)
|
||||||
}
|
}
|
||||||
rb->lcd_update_rect(0, (scanline/2) & ~7, LCD_WIDTH, 8);
|
rb->lcd_update_rect(0, (scanline/2) & ~7, LCD_WIDTH, 8);
|
||||||
#else /* LCD_HEIGHT != 64, iRiver */
|
#else /* LCD_HEIGHT != 64, iRiver */
|
||||||
if (scanline >= 128)
|
if (fb.mode==1)
|
||||||
return;
|
scanline-=16;
|
||||||
scanline_remapped = scanline / 8;
|
scanline_remapped = scanline / 8;
|
||||||
frameb = rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH;
|
frameb = rb->lcd_framebuffer + scanline_remapped * LCD_WIDTH;
|
||||||
while (cnt < 160) {
|
while (cnt < 160) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue