summaryrefslogtreecommitdiff
path: root/old/spc700/spcgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'old/spc700/spcgen.c')
-rw-r--r--old/spc700/spcgen.c2164
1 files changed, 0 insertions, 2164 deletions
diff --git a/old/spc700/spcgen.c b/old/spc700/spcgen.c
deleted file mode 100644
index 3ac06d6..0000000
--- a/old/spc700/spcgen.c
+++ /dev/null
@@ -1,2164 +0,0 @@
-// notaz's SPC700 Emulator
-// (c) Copyright 2006 notaz, All rights reserved.
-//
-// Added some modifications by Bitrider 2010-2011.
-//
-// this is a rewrite of spc700.cpp in ARM asm, inspired by other asm CPU cores like
-// Cyclone and DrZ80. It is meant to be used in Snes9x emulator ports for ARM platforms.
-//
-// notes:
-// "Shutdown" mechanism is not supported, so undefine SPC700_SHUTDOWN in your port.h
-// code branches backwards over start of memory are not supported
-// (never seen any game doing that)
-//
-// license:
-// the code is released under Snes9x license. It would be nice if the word "notaz"
-// would appear somewhere in your documentation or your program's "about" screen
-// if you use this :)
-
-/*
- * Permission to use, copy, modify and distribute Snes9x in both binary and
- * source form, for non-commercial purposes, is hereby granted without fee,
- * providing that this license information and copyright notice appear with
- * all copies and any derived work.
- *
- * This software is provided 'as-is', without any express or implied
- * warranty. In no event shall the authors be held liable for any damages
- * arising from the use of this software.
- *
- * Snes9x is freeware for PERSONAL USE only. Commercial users should
- * seek permission of the copyright holders first. Commercial use includes
- * charging money for Snes9x or software derived from Snes9x.
- *
- * The copyright holders request that bug fixes and improvements to the code
- * should be forwarded to them so everyone can benefit from the modifications
- * in future versions.
- *
- * Super NES and Super Nintendo Entertainment System are trademarks of
- * Nintendo Co., Limited and its subsidiary companies.
- */
-
-int one_apu_cycle[] = {13, 14, 15, 21};
-int current_cycles;
-
-
-// settings
-#define VERSION "0.12"
-#define APU_EXECUTING_OFF 124
-//#define SPC_DEBUG
-
-
-// includes
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <stdlib.h>
-
-
-// timings
-int S9xAPUCycles [256] =
-{
- /* 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, a, b, c, d, e, f, */
- /* 00 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 6, 8,
- /* 10 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 4, 6,
- /* 20 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 4, 5, 4,
- /* 30 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 6, 5, 2, 2, 3, 8,
- /* 40 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 6, 6,
- /* 50 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 4, 5, 2, 2, 4, 3,
- /* 60 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 4, 5, 5,
- /* 70 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 6,
- /* 80 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 6, 5, 4, 5, 2, 4, 5,
- /* 90 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2,12, 5,
- /* a0 */ 3, 8, 4, 5, 3, 4, 3, 6, 2, 6, 4, 4, 5, 2, 4, 4,
- /* b0 */ 2, 8, 4, 5, 4, 5, 5, 6, 5, 5, 5, 5, 2, 2, 3, 4,
- /* c0 */ 3, 8, 4, 5, 4, 5, 4, 7, 2, 5, 6, 4, 5, 2, 4, 9,
- /* d0 */ 2, 8, 4, 5, 5, 6, 6, 7, 4, 5, 4, 5, 2, 2, 6, 3,
- /* e0 */ 2, 8, 4, 5, 3, 4, 3, 6, 2, 4, 5, 3, 4, 3, 4, 3,
- /* f0 */ 2, 8, 4, 5, 4, 5, 5, 6, 3, 4, 5, 4, 2, 2, 4, 3
-};
-
-
-// stuff
-static FILE *AsmFile=NULL;
-static int opcode=0; // 0-0xff
-static int ibuffer = 0;
-static char buff[1024];
-
-
-void ot(char *format, ...)
-{
- va_list valist;
- int i, len;
-
- // notaz: stop me from leaving newlines in the middle of format string
- // and generating bad code
- for(i=0, len=strlen(format); i < len && format[i] != '\n'; i++);
- if(i < len-1 && format[len-1] != '\n') printf("\nWARNING: possible improper newline placement:\n%s\n", format);
-
- va_start(valist,format);
- if (AsmFile) vfprintf(AsmFile,format,valist);
- va_end(valist);
-}
-
-// ot buffered
-void otb(char *format, ...)
-{
- va_list valist;
- int i, len;
-
- // notaz: stop me from leaving newlines in the middle of format string
- // and generating bad code
- for(i=0, len=strlen(format); i < len && format[i] != '\n'; i++);
- if(i < len-1 && format[len-1] != '\n') printf(buff, "\nWARNING: possible improper newline placement:\n%s\n", format);
-
- va_start(valist,format);
- if (AsmFile) vsprintf(buff,format,valist);
- ibuffer = 1;
- va_end(valist);
-}
-
-void flush_buffer() {
- if (ibuffer != 0) {
- ot(buff);
- ibuffer = 0;
- }
-}
-
-// trashes: r0, r1, r2
-// return: r0
-// exit at label "2"
-static void GetAPUDSP() {
- ot("GetAPUDSP: \n");
- ot(" ldrb r1, [spc_ram, #0xf2] \n");
- // r1 = IAPU.RAM [0xf2]
-
- ot(" mov r0, #0\n");
- ot(" and r2, r1, #0X0f \n");
- // switch (reg & 0xf) {
- ot(" cmp r2, #0x08\n");
- ot(" bxeq lr\n"); // APU_ENVX = 8
- // r1 = IAPU.RAM [0xf2] & 0x7f;
-
- ot(" cmp r2, #0x09\n");
- // return APU.DSP [reg];
- ot(" ldrne r2, .APU_DSP\n");
- ot(" and r1, r1, #0X7f \n"); // r1 = IAPU.RAM[0xf2] & 0x7f
- ot(" ldrneb r0, [r2, r1] \n");
- ot(" bxne lr \n");
-
- // APU_OUTX = 9
- // if (SoundData.channels [reg >> 4].state == SOUND_SILENT) return 0;
- // return ((SoundData.channels [reg >> 4].sample >> 8) | (SoundData.channels [reg >> 4].sample & 0x
- ot(" ldr r2, .SOUNDDATA_CHANNELS\n");
- ot(" mov r1, r1, lsr #4 \n");
- //ot(" add r1, r2, r1, asl #8\n");
- //ot(" ldr r0, [r1, #0x0] \n"); // r0 = SoundData.channels[reg >> 4].state
- ot(" ldr r0, [r2, r1, asl #8] \n");
- ot(" add r1, r2, r1, asl #8\n");
- ot(" cmp r0, #0 \n"); // SOUND_SILENT = 0
- ot(" ldrneh r1, [r1, #0x48] \n"); // r1 = SoundData.channels[reg >> 4].sample
- ot(" bxeq lr \n");
-
- ot(" and r0, r1, #0xff\n");
- ot(" orr r0, r0, r1, lsr #8\n");
- ot(" bx lr \n");
-
- ot(".APU_DSP:\n");
- ot(" .long APU + 0x0b\n"); // &APU.DSP
- ot(".SOUNDDATA_CHANNELS:\n");
- ot(" .long SoundData + 0x30\n"); // &SoundData.channels[0]
-}
-
-
-// bitrider
-// macros
-static void GetByte() {
- ot(" mov r1, r0\n");
-
- ot(" ldrb r0, [spc_ram, r1] \n");
-
- ot(" cmp r1, #0x0ff\n");
- ot(" bhi 1f \n");
-
- ot(" cmp r1, #0xf3 \n");
- ot(" addeq lr, pc, #12 \n"); // lr = &ExitPoint
- ot(" beq GetAPUDSP \n");
-
- ot(" cmp r1, #0xfd \n");
- ot(" movhs r2, #0 \n");
- ot(" strhsb r2, [spc_ram, r1] \n");
- ot("1:\n");
-
-
-}
-
-// trashes: r0, r1, r14
-static void GetByteZ() {
- ot(" mov r1, r0\n");
-
- ot(" cmp r1, #0xf3 \n");
- ot(" addeq lr, pc, #20 \n"); // lr = &ExitPoint
- ot(" beq GetAPUDSP \n");
-
- ot(" ldr r14, [context, #iapu_directpage]\n");
- ot(" cmp r1, #0xfd \n");
- ot(" ldrb r0, [r14, r1] \n");
- ot(" movhs r2, #0 \n");
- ot(" strhsb r2, [r14, r1] \n");
-}
-
-static void SetByte(int restore) {
- // Still should check for ShowRom
- ot(" add r2, r1, #40 \n");
- ot(" tst r2, #0x10000 \n");
- ot(" bne 1f \n");
-
- ot(" bic r2, r1, #0x0f\n");
- ot(" cmp r2, #0xf0\n");
- ot(" strneb r0, [spc_ram, r1] \n");
- ot(" bne 3f\n");
-
- ot(" add lr, pc, #20\n");
-
- ot(" cmp r1, #0xf1 \n");
- ot(" beq S9xSetAPUControl \n");
-
- ot(" cmp r1, #0xf3 \n"); // pc + 4
- ot(" beq S9xSetAPUDSP \n"); // pc + 8
- ot(" b S9xAPUSetByteFFtoF0 \n"); // pc + 12
-
- ot("1: \n");
- ot(" bl S9xAPUSetByteFFC0 \n");
- ot(" ldr spc_ram, [context, #iapu_ram] \n");
- ot("3: \n");
-
-}
-
-static void SetByteZ(int restore) {
- ot(" ldr r2, [context, #iapu_directpage] \n");
- ot(" cmp r2, spc_ram \n");
- ot(" bne 2f \n");
-
- ot(" cmp r1, #0xf0 \n");
- ot(" blo 2f \n");
-
- ot(" cmp r1, #0xfe \n");
- ot(" bhs 1f \n");
-
- if (restore) ot(" add lr, pc, #16\n");
- else ot(" add lr, pc, #20\n");
-
- ot(" cmp r1, #0xf1 \n");
- ot(" beq S9xSetAPUControl \n");
-
- ot(" cmp r1, #0xf3 \n"); // pc + 4
- ot(" beq S9xSetAPUDSP \n"); // pc + 8
- ot(" b S9xAPUSetByteFFtoF0 \n"); // pc + 12
- //ot("6: \n"); // pc + 16
- if (restore) {
- ot(" ldr spc_ram, [context, #iapu_ram] \n");
- ot(" b 1f \n");
- }
- ot("2: \n");
- ot(" strb r0, [r2, r1] \n");
- ot("1: \n");
-}
-
-
-// r0-2: Temporary registers
-// r3 : current opcode or temp
-// r4 : Cycles remaining
-// r5 : Pointer to IAPU structure
-// r6 : Pointer to Opcode Jump table
-// r7 : Current PC
-// r8 : YA
-// r9 : P (nzzzzzzz ........ ........ NODBHIZC; nzzzzzzz - NZ flag in use (for a little speedup)
-
-// r10 : X
-// r11 : S
-// r14 : temp
-// lr : RAM pointer
-
-static void PrintFramework()
-{
-
-
-#ifndef SPC_DEBUG
- ot(" .extern IAPU\n");
-#else
- ot(" .extern IAPU2\n");
-#endif
- ot(" .extern CPU @ for STOP and SLEEP\n");
- ot(" .extern S9xAPUGetByte\n");
- ot(" .extern S9xAPUSetByte\n");
- ot(" .extern S9xAPUGetByteZ\n");
- ot(" .extern S9xAPUSetByteZ\n\n");
-
- // bitrider
- ot(" .extern S9xGetAPUDSP\n");
- ot(" .extern S9xSetAPUDSP\n");
- ot(" .extern S9xSetAPUControl\n");
- ot(" .extern S9xAPUSetByteFFC0\n");
- ot(" .extern S9xAPUSetByteFFtoF0\n");
-
- ot(" .global spc700_execute @ int cycles\n");
- //ot(" .global Spc700JumpTab\n\n");
- for (current_cycles=0; current_cycles < (sizeof(one_apu_cycle) / sizeof(int)); current_cycles++)
- ot(" .global Spc700JumpTab_%i\n", one_apu_cycle[current_cycles]);
- ot("\n");
-
-
- ot(" opcode .req r3\n");
- ot(" cycles .req r4\n");
- ot(" context .req r5\n");
- ot(" opcodes .req r6\n");
- ot(" spc_pc .req r7\n");
- ot(" spc_ya .req r8\n");
- ot(" spc_p .req r9\n");
- ot(" spc_x .req r10\n");
- ot(" spc_s .req r11\n");
- ot(" spc_ram .req r12\n\n");
-
- ot(" .equ iapu_directpage, 0x00\n");
- ot(" .equ iapu_ram, 0x44\n");
- ot(" .equ iapu_extraram, 0x48\n");
- ot(" .equ iapu_allregs_load, 0x30\n");
- ot(" .equ iapu_allregs_save, 0x34\n\n");
-
- ot(" .equ flag_c, 0x01\n");
- ot(" .equ flag_z, 0x02\n");
- ot(" .equ flag_i, 0x04\n");
- ot(" .equ flag_h, 0x08\n");
- ot(" .equ flag_b, 0x10\n");
- ot(" .equ flag_d, 0x20\n");
- ot(" .equ flag_o, 0x40\n");
- ot(" .equ flag_n, 0x80\n\n");
-
- ot(" .equ cpu_apu_executing, %i \n\n", APU_EXECUTING_OFF);
- // tmp
-// ot(" .equ iapu_carry, 0x24\n");
-// ot(" .equ iapu_overflow, 0x26\n\n");
-
- ot("@ --------------------------- Framework --------------------------\n");
- ot(" .align 4\n");
- ot("spc700_execute: @ int cycles\n");
-
- ot(" stmfd sp!,{r4-r11,lr}\n");
-
-#ifndef SPC_DEBUG
- ot(" ldr context,=IAPU @ Pointer to SIAPU struct\n");
-#else
- ot(" ldr context,=IAPU2 @ Pointer to SIAPU struct\n");
-#endif
- ot(" mov cycles,r0 @ Cycles\n");
- ot(" add r0,context,#iapu_allregs_load\n");
- ot(" ldmia r0,{opcodes,spc_pc,spc_ya,spc_p,spc_x,spc_ram}\n");
-
- ot(" ldrb opcode,[spc_pc],#1 @ Fetch first opcode\n");
- ot(" mov spc_s,spc_x,lsr #8\n");
- ot(" and spc_x,spc_x,#0xff\n");
- ot("\n");
-
- ot(" ldr pc,[opcodes,opcode,lsl #2] @ Jump to opcode handler\n");
- ot("\n\n");
-
-
- ot("@ We come back here after execution\n");
- ot("spc700End:\n");
- ot(" orr spc_x,spc_x,spc_s,lsl #8\n");
- ot(" add r0,context,#iapu_allregs_save\n");
- ot(" stmia r0,{spc_pc,spc_ya,spc_p,spc_x}\n");
- ot(" mov r0,cycles\n");
- ot(" ldmfd sp!,{r4-r11,pc}\n");
- ot("\n");
-
- ot(" .ltorg\n");
- ot("\n");
-
- GetAPUDSP();
-}
-
-
-// ---------------------------------------------------------------------------
-
-// Trashes r0-r3
-static void MemHandler(int set, int z, int save)
-{
- //if(set) ot(" bl S9xAPUSetByte%s\n", z ? "Z" : "");
- //else ot(" bl S9xAPUGetByte%s\n", z ? "Z" : "");
-
- //if(set) ot(" asm_S9xAPUSetByte%s\n", z ? "Z" : "");
- //else ot(" asm_S9xAPUGetByte%s\n", z ? "Z" : "");
- if(set) {
- if (z) SetByteZ(save);
- else SetByte(save);
- } else {
- if (z) GetByteZ();
- else GetByte();
- }
-
- //if(save) ot(" ldr spc_ram,[context,#iapu_ram]\n");
-}
-
-// pushes reg, trashes r1
-static void Push(char *reg)
-{
- ot(" add r1,spc_ram,spc_s\n");
- ot(" strb %s,[r1,#0x100]\n", reg);
- ot(" sub spc_s,spc_s,#1\n");
-}
-
-// pushes r0, trashes r0,r1
-static void PushW()
-{
- ot(" add r1,spc_ram,spc_s\n");
- ot(" sub spc_s,spc_s,#2\n");
- ot(" strb r0,[r1,#0xff]\n");
- ot(" mov r0,r0,lsr #8\n");
- ot(" strb r0,[r1,#0x100]\n");
-}
-
-// pops to reg
-static void Pop(char *reg)
-{
- ot(" add %s,spc_ram,spc_s\n", reg);
- ot(" ldrb %s,[%s,#(0x100 + 1)]\n", reg, reg);
- ot(" add spc_s,spc_s,#1\n");
-}
-
-// pops to r0, trashes r1
-static void PopW()
-{
- ot(" add r1,spc_ram,spc_s\n");
- ot(" ldrb r0,[r1,#(0xff + 2)]\n");
- ot(" ldrb r1,[r1,#(0x100 + 2)]\n");
- ot(" add spc_s,spc_s,#2\n");
- ot(" orr r0,r0,r1,lsl #8\n");
-}
-
-// // rr <- absolute, trashes r14
-// rr <- absolute
-
-static void AbsoluteAdd(int r, char *rAdd)
-{
- ot(" ldrb r%i,[spc_pc],#1\n", r);
- ot(" ldrb r14,[spc_pc],#1\n");
- if (rAdd) ot(" add r%i,r%i,%s\n", r, r, rAdd);
- ot(" add r%i,r%i,r14,lsl #8\n", r, r);
-}
-
-// // rr <- absolute, trashes r14
-// rr <- absolute
-static void Absolute(int r)
-{
- //ot(" ldrb r%i,[spc_pc],#1\n", r);
- //ot(" ldrb r14,[spc_pc],#1\n");
- //ot(" orr r%i,r%i,r14,lsl #8\n", r, r);
- AbsoluteAdd(r, NULL);
-}
-
-
-// rr <- absoluteX, trashes r14
-static void AbsoluteX(int r)
-{
- //Absolute(r);
- //ot(" ldrb r%i,[spc_pc],#1\n", r);
- //ot(" ldrb r14,[spc_pc],#1\n");
- //ot(" add r%i,r%i,spc_x\n", r, r);
- //ot(" add r%i,r%i,r14,lsl #8\n", r, r);
- AbsoluteAdd(r, "spc_x");
-}
-
-// r0 <- absoluteY, trashes r1
-static void AbsoluteY(int r)
-{
- //Absolute(r);
- //ot(" ldrb r%i,[spc_pc],#1\n", r);
- //ot(" ldrb r14,[spc_pc],#1\n");
- //ot(" add r%i,r%i,spc_ya,lsr #8\n", r, r);
- //ot(" add r%i,r%i,r14,lsl #8\n", r, r);
- AbsoluteAdd(r, "spc_ya, lsr #8");
-}
-
-// rr <- IndirectIndexedY, trashes r14
-static void IndirectIndexedY(int r)
-{
- ot(" ldrb r%i,[spc_pc],#1\n", r);
- ot(" ldr r14,[context,#iapu_directpage]\n");
- ot(" ldrb r%i,[r14,r%i]!\n", r, r);
- ot(" ldrb r14,[r14,#1]\n");
- //ot(" orr r%i,r%i,r14,lsl #8\n", r, r);
- ot(" add r%i,r%i,spc_ya,lsr #8\n", r, r);
- ot(" add r%i,r%i,r14,lsl #8\n", r, r);
-}
-
-// rr <- address, trashes r14
-static void IndexedXIndirect(int r)
-{
- ot(" ldrb r%i,[spc_pc],#1\n", r);
- ot(" ldr r14,[context,#iapu_directpage]\n"); // again, interlocks are bad
- ot(" add r%i,r%i,spc_x\n", r, r);
- ot(" and r%i,r%i,#0xff\n", r, r);
- ot(" ldrb r%i,[r14,r%i]!\n", r, r);
- ot(" ldrb r14,[r14,#1]\n");
- ot(" orr r%i,r%i,r14,lsl #8\n", r, r);
-}
-
-// sets ZN for reg in *reg, not suitable for Y
-static void SetZN8(char *reg)
-{
- ot(" and spc_p,spc_p,#0xff\n");
- ot(" orr spc_p,spc_p,%s,lsl #24\n", reg);
-}
-
-// sets ZN for reg in *reg
-static void SetZN16(char *reg)
-{
- ot(" and spc_p,spc_p,#0xff\n");
- ot(" orr spc_p,spc_p,%s,lsl #16\n", reg);
- ot(" tst %s,#0xff\n", reg);
- ot(" orrne spc_p,spc_p,#0x01000000\n");
-}
-
-// does ROL on r0, sets flags
-static void Rol()
-{
- ot(" mov r0,r0,lsl #1\n");
- ot(" tst spc_p,#flag_c\n");
- ot(" orrne r0,r0,#1\n");
- ot(" tst r0,#0x100\n");
- ot(" orrne spc_p,spc_p,#flag_c\n");
- ot(" biceq spc_p,spc_p,#flag_c\n");
- SetZN8("r0");
-}
-
-// does ROR on r0, sets flags
-static void Ror()
-{
- ot(" tst spc_p,#flag_c\n");
- ot(" orrne r0,r0,#0x100\n");
- ot(" movs r0,r0,lsr #1\n");
- ot(" orrcs spc_p,spc_p,#flag_c\n");
- ot(" biccc spc_p,spc_p,#flag_c\n");
- SetZN8("r0");
-}
-
-// does ASL on r0, sets flags but doesn't cut the shifted bits
-static void Asl()
-{
- ot(" tst r0,#0x80\n");
- ot(" orrne spc_p,spc_p,#flag_c\n");
- ot(" biceq spc_p,spc_p,#flag_c\n");
- ot(" mov r0,r0,lsl #1\n");
- SetZN8("r0");
-}
-
-// does LSR on r0, sets flags
-static void Lsr()
-{
- ot(" tst r0,#0x01\n");
- ot(" orrne spc_p,spc_p,#flag_c\n");
- ot(" biceq spc_p,spc_p,#flag_c\n");
- ot(" mov r0,r0,lsr #1\n");
- SetZN8("r0");
-}
-
-// CMP rr0,rr1; trashes r14
-static void Cmp(char *r0, char *r1, int and_r0)
-{
- char *lop = r0;
-
- if(and_r0) { ot(" and r14,%s,#0xff\n", r0); lop = "r14"; }
- ot(" subs r14,%s,%s\n", lop, r1);
- //ot(" orrge spc_p,spc_p,#flag_c\n");
- //ot(" biclt spc_p,spc_p,#flag_c\n");
- ot(" orrcs spc_p,spc_p,#flag_c\n");
- ot(" biccc spc_p,spc_p,#flag_c\n");
- SetZN8("r14");
-}
-
-// ADC rr0,rr1 -> rr0, trashes r2,r14, does not mask to byte
-static void Adc(char *r0, char *r1)
-{
- ot(" eor r2,%s,%s\n", r0, r1); // r3=(a) ^ (b)
- ot(" movs r14, spc_p, lsr #1\n");
- ot(" adc %s, %s, %s\n", r0, r0, r1);
- //ot(" add %s,%s,%s\n", r0, r0, r1);
- //ot(" tst spc_p,#flag_c\n");
- //ot(" addne %s,%s,#1\n", r0, r0);
- ot(" movs r14,%s,lsr #8\n", r0);
- ot(" orrne spc_p,spc_p,#flag_c\n");
- ot(" biceq spc_p,spc_p,#flag_c\n");
- ot(" eor r14,%s,%s\n", r0, r1); // r14=(b) ^ Work16
- ot(" bic r14,r14,r2\n"); // ((b) ^ Work16) & ~((a) ^ (b))
- ot(" tst r14,#0x80\n");
- ot(" orrne spc_p,spc_p,#flag_o\n");
- ot(" biceq spc_p,spc_p,#flag_o\n");
- ot(" eor r14,r2,%s\n", r0);
- ot(" tst r14,#0x10\n");
- ot(" orrne spc_p,spc_p,#flag_h\n");
- ot(" biceq spc_p,spc_p,#flag_h\n");
-}
-
-// SBC rr0,rr1 -> rr0, trashes r2,r3,r14, does not mask to byte
-static void Sbc(char *r0, char *r1)
-{
- ot(" movs r14,spc_p,lsr #1\n");
- ot(" sbcs r2,%s,%s\n", r0, r1);
- ot(" orrge spc_p,spc_p,#flag_c\n");
- ot(" biclt spc_p,spc_p,#flag_c\n");
- ot(" eor r14,%s,r2\n", r0); // r14=(a) ^ Int16
- ot(" eor r3,%s,%s\n", r0, r1); // r3=(a) ^ (b)
- ot(" and r14,r14,r3\n"); // ((a) ^ Work16) & ((a) ^ (b))
- ot(" tst r14,#0x80\n");
- ot(" orrne spc_p,spc_p,#flag_o\n");
- ot(" biceq spc_p,spc_p,#flag_o\n");
- ot(" eor r14,r3,r2\n");
- ot(" tst r14,#0x10\n");
- ot(" orreq spc_p,spc_p,#flag_h\n");
- ot(" bicne spc_p,spc_p,#flag_h\n");
- ot(" mov %s,r2\n", r0);
-}
-
-
-//
-static void TCall()
-{
- ot(" sub r0,spc_pc,spc_ram\n");
- PushW();
- ot(" ldr r0,[context,#iapu_extraram]\n");
- ot(" ldrh r0,[r0,#0x%x]\n", (15-(opcode>>4))<<1);
- ot(" add spc_pc,spc_ram,r0\n");
-}
-
-//
-static void SetClr1()
-{
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- ot(" %s r0,r0,#0x%02x\n", opcode & 0x10 ? "bic" : "orr", 1<<(opcode>>5));
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
-}
-
-//
-static void BssBbc()
-{
- ot(" ldrb r0,[spc_pc],#1\n");
- MemHandler(0, 1, 1);
- ot(" tst r0,#0x%02x\n", 1<<(opcode>>5));
- ot(" add%s spc_pc,spc_pc,#1\n", opcode & 0x10 ? "ne" : "eq");
- ot(" ldr%ssb r0,[spc_pc],#1\n", opcode & 0x10 ? "eq" : "ne");
- ot(" sub%s cycles,cycles,#%i\n",opcode & 0x10 ? "eq" : "ne", one_apu_cycle[current_cycles]*2);
- ot(" add%s spc_pc,spc_pc,r0\n", opcode & 0x10 ? "eq" : "ne");
-}
-
-//
-static void Membit()
-{
- ot(" ldrb r0,[spc_pc], #1\n");
- ot(" ldrb r3,[spc_pc], #1\n");
- //ot(" orr spc_x,spc_x,r1,lsl #(29-5)
- ot(" add r3,r0,r3,lsl #8\n"); //@ store membit where it can survive memhandler call\n"); // saving bit 12 ?
- //ot(" mov r1,r1,lsr #5\n");
- //ot(" mov r0,r0,lsl #19\n");
- //ot(" mov r0,r0,lsr #19\n");
- //if((opcode >> 4) >= 0xC) ot(" mov r3, r0\n"); //ot(" stmfd sp!,{r0}\n"); // membit
- ot(" bic r0, r3, #0xe000\n"); // Clear bits 15, 14 & 13 => r0 = r0 & 0x1fff
- MemHandler(0, 0, 0);
- //ot(" mov r1,spc_x,lsr #29\n");
- //ot(" and spc_x,spc_x,#0xff\n");
- ot(" mov r1, r3, lsr #13\n"); // membit = bits[15:13] of memory address
- if((opcode >> 4) < 0xC) {
- ot(" mov r0,r0,lsr r1\n");
- ot(" tst r0,#1\n");
- switch(opcode >> 4) {
- case 0x0: ot(" orrne spc_p,spc_p,#flag_c\n"); break; // OR1 C,membit
- case 0x2: ot(" orreq spc_p,spc_p,#flag_c\n"); break; // OR1 C,not membit
- case 0x4: ot(" biceq spc_p,spc_p,#flag_c\n"); break; // AND1 C,membit
- case 0x6: ot(" bicne spc_p,spc_p,#flag_c\n"); break; // AND1 C, not membit
- case 0x8: ot(" eorne spc_p,spc_p,#flag_c\n"); break; // EOR1 C, membit
- case 0xA: ot(" orrne spc_p,spc_p,#flag_c\n"); // MOV1 C,membit
- ot(" biceq spc_p,spc_p,#flag_c\n"); break;
- }
- } else {
- ot(" mov r2,#1\n");
- ot(" mov r2,r2,lsl r1\n");
- if((opcode >> 4) == 0xC) { // MOV1 membit,C
- ot(" tst spc_p,#flag_c\n");
- ot(" orrne r0,r0,r2\n");
- ot(" biceq r0,r0,r2\n");
- } else { // NOT1 membit
- ot(" eor r0,r0,r2\n");
- }
- //ot(" ldmfd sp!,{r1}\n");
- ot(" bic r1, r3, #0xe000\n"); // Clear bits 15, 14 & 13 => r0 = r0 & 0x1fff
- MemHandler(1, 0, 0);
- }
- //ot(" ldr spc_ram,[context,#iapu_ram] @ restore what memhandler(s) messed up\n");
-}
-
-//
-static void CBranch()
-{
- int tests[] = { 0x80000000, 0x40, 0x01, 0xff000000 }; // NOCZ
- char *eq = "eq";
- char *ne = "ne";
-
- if((opcode>>6) == 3) { // zero test inverts everything
- eq = "ne";
- ne = "eq";
- }
-
- ot(" tst spc_p,#0x%08X\n", tests[opcode>>6]);
- ot(" add%s spc_pc,spc_pc,#1\n", opcode & 0x20 ? eq : ne);
-/*
- ot(" b%s Apu%02X\n", opcode & 0x20 ? eq : ne, opcode);
- ot(" sub r0,spc_pc,spc_ram\n");
- ot(" ldrsb r1,[spc_pc],#1\n");
- ot(" add r0,r0,r1\n");
- ot(" mov r0,r0,lsl #16\n");
- ot(" add spc_pc,spc_ram,r0,lsr #16\n");
-*/
- ot(" ldr%ssb r0,[spc_pc],#1\n", opcode & 0x20 ? ne : eq);
-
- ot(" sub%s cycles,cycles,#%i\n", opcode & 0x20 ? ne : eq, one_apu_cycle[current_cycles]*2);
- ot(" add%s spc_pc,spc_pc,r0\n", opcode & 0x20 ? ne : eq);
-// ot("Apu%02X:\n", opcode);
-}
-
-// NeededOperation spc_ya,r0 -> spc_ya
-static void ArithOpToA()
-{
- // special A pre-processing
- if((opcode>>5) == 4 || (opcode>>5) == 5) {
- ot(" and r1,spc_ya,#0xff00\n");
- ot(" and spc_ya,spc_ya,#0xff\n");
- }
-
- switch(opcode>>5) {
- case 0: ot(" orr spc_ya,spc_ya,r0\n"); break; // OR
- case 1: ot(" orr r0,r0,#0xff00\n");
- ot(" and spc_ya,spc_ya,r0\n"); break; // AND
- case 2: ot(" eor spc_ya,spc_ya,r0\n"); break; // EOR
- case 3: Cmp("spc_ya", "r0", 1); break; // CMP
- case 4: Adc("spc_ya", "r0"); break; // ADC
- case 5: Sbc("spc_ya", "r0"); break; // SBC
- case 6: printf("MOV (reversed)!?\n"); break; // MOV (reversed)
- case 7: ot(" and spc_ya,spc_ya,#0xff00\n");
- ot(" orr spc_ya,spc_ya,r0\n"); break; // MOV
- }
-
- if((opcode>>5) != 3) SetZN8("spc_ya"); // only if not Cmp
-
- // special A post-processing
- if((opcode>>5) == 4 || (opcode>>5) == 5) {
- ot(" and spc_ya,spc_ya,#0xff\n");
- ot(" orr spc_ya,spc_ya,r1\n");
- }
-}
-
-//
-static void ArithmeticToA()
-{
- switch(opcode&0x1f) {
- case 0x04: // OP A,dp
- ot(" ldrb r0,[spc_pc],#1\n");
- MemHandler(0, 1, 1);
- ArithOpToA();
- break;
-
- case 0x05: // OP A,abs
- Absolute(0);
- MemHandler(0, 0, 1);
- ArithOpToA();
- break;
-
- case 0x06: // OP A,(X)
- ot(" mov r0,spc_x\n");
- MemHandler(0, 1, 1);
- ArithOpToA();
- break;
-
- case 0x07: // OP A,(dp+X)
- IndexedXIndirect(0);
- MemHandler(0, 0, 1);
- ArithOpToA();
- break;
-
- case 0x08: // OP A,#00
- ot(" ldrb r0,[spc_pc],#1\n");
- ArithOpToA();
- break;
-
- case 0x14: // OP A,dp+X
- ot(" ldrb r0,[spc_pc],#1\n");
- ot(" add r0,r0,spc_x\n");
- MemHandler(0, 1, 1);
- ArithOpToA();
- break;
-
- case 0x15: // OP A,abs+X
- AbsoluteX(0);
- MemHandler(0, 0, 1);
- ArithOpToA();
- break;
-
- case 0x16: // OP A,abs+Y
- AbsoluteY(0);
- MemHandler(0, 0, 1);
- ArithOpToA();
- break;
-
- case 0x17: // OP A,(dp)+Y
- IndirectIndexedY(0);
- MemHandler(0, 0, 1);
- ArithOpToA();
- break;
-
- default:
- printf("Op %02X - arithmetic??\n", opcode);
- }
-}
-
-void printOpcodes(int apu_cycles) {
- for(opcode = 0; opcode < 0x100; opcode++) {
- printf("%02X", opcode);
-
- ot("\n\n");
- //tmp_prologue();
- ot("Apu%02X_%i:\n", opcode, apu_cycles);
-
- if((opcode & 0x1f) == 0x10) CBranch(); // BXX
- if((opcode & 0x0f) == 0x01) TCall(); // TCALL X
- if((opcode & 0x0f) == 0x02) SetClr1(); // SET1/CLR1 direct page bit X
- if((opcode & 0x0f) == 0x03) BssBbc(); // BBS/BBC direct page bit X
- if((opcode & 0x1f) == 0x0A) Membit(); // membit ops
- if((opcode & 0x0f) >= 0x04 && (opcode & 0x0f) <= 0x08 && (opcode & 0x1f) != 0x18 && (opcode >> 5) != 6)
- ArithmeticToA();
-
-
- switch(opcode) {
- case 0x00: // NOP
- break;
-
- case 0x3F: // CALL absolute
- Absolute(2);
- ot(" sub r0,spc_pc,spc_ram\n");
- PushW();
- ot(" add spc_pc,spc_ram,r2\n");
- break;
-
- case 0x4F: // PCALL $XX
- ot(" ldrb r2,[spc_pc],#1\n");
- ot(" sub r0,spc_pc,spc_ram\n");
- PushW();
- ot(" add spc_pc,spc_ram,r2\n");
- ot(" add spc_pc,spc_pc,#0xff00\n");
- break;
-
- case 0x09: // OR dp(dest),dp(src)
- ot(" ldrb r0,[spc_pc],#1\n");
- MemHandler(0, 1, 0);
- //ot(" orr spc_x,spc_x,r0,lsl #24 @ save from harm\n");
- ot(" mov r3, r0\n");
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- ot(" orr r0, r0, r3\n");
- //ot(" orr r0,r0,spc_x,lsr #24\n");
- //ot(" and spc_x,spc_x,#0xff\n");
- SetZN8("r0");
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x18: // OR dp,#00
- ot(" ldrb r0,[spc_pc,#1]\n");
- MemHandler(0, 1, 0);
- ot(" ldrb r1,[spc_pc],#1\n");
- ot(" orr r0,r0,r1\n");
- SetZN8("r0");
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x19: // OR (X),(Y)
- ot(" mov r0,spc_x\n");
- MemHandler(0, 1, 0);
- //ot(" orr spc_x,spc_x,r0,lsl #24\n");
- ot(" mov r3, r0\n");
- ot(" mov r0,spc_ya,lsr #8\n");
- MemHandler(0, 1, 0);
- ot(" orr r0, r3, r0\n");
- //ot(" orr r0,r0,spc_x,lsr #24\n");
- //ot(" and spc_x,spc_x,#0xff\n");
- SetZN8("r0");
- ot(" mov r1,spc_x\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x0B: // ASL dp
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- Asl();
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x0C: // ASL abs
- Absolute(0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- MemHandler(0, 0, 0);
- Asl();
- //ot(" ldmfd sp!,{r1}\n");
- ot(" mov r1, r3\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0x1B: // ASL dp+X
- ot(" ldrb r0,[spc_pc],#1\n");
- ot(" add r0,r0,spc_x\n");
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- MemHandler(0, 1, 0);
- Asl();
- //ot(" ldmfd sp!,{r1}\n");
- ot(" mov r1, r3\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x1C: // ASL A
- ot(" tst spc_ya,#0x80\n");
- ot(" orrne spc_p,spc_p,#flag_c\n");
- ot(" biceq spc_p,spc_p,#flag_c\n");
- ot(" and r0,spc_ya,#0x7f\n");
- ot(" and spc_ya,spc_ya,#0xff00\n");
- ot(" orr spc_ya,spc_ya,r0,lsl #1\n");
- SetZN8("spc_ya");
- break;
-
- case 0x0D: // PUSH PSW
- ot(" mov r0,spc_p,lsr #24\n");
- ot(" and r1,r0,#0x80\n");
- ot(" tst r0,r0\n");
- ot(" orreq r1,r1,#flag_z\n");
- ot(" and spc_p,spc_p,#0x7d @ clear N & Z\n");
- ot(" orr spc_p,spc_p,r1\n");
- Push("spc_p");
- otb(" orr spc_p,spc_p,r0,lsl #24\n");
- break;
-
- case 0x2D: // PUSH A
- Push("spc_ya");
- break;
-
- case 0x4D: // PUSH X
- Push("spc_x");
- break;
-
- case 0x6D: // PUSH Y
- ot(" mov r0,spc_ya,lsr #8\n");
- Push("r0");
- break;
-
- case 0x8E: // POP PSW
- Pop("spc_p");
- ot(" and r0,spc_p,#(flag_z|flag_n)\n");
- ot(" eor r0,r0,#flag_z\n");
- ot(" orr spc_p,spc_p,r0,lsl #24\n");
- ot(" tst spc_p,#flag_d\n");
- ot(" addne r0,spc_ram,#0x100\n");
- ot(" moveq r0,spc_ram\n");
- otb(" str r0,[context,#iapu_directpage]\n");
- break;
-
- case 0xAE: // POP A
- Pop("r0");
- ot(" and spc_ya,spc_ya,#0xff00\n");
- otb(" orr spc_ya,spc_ya,r0\n");
- break;
-
- case 0xCE: // POP X
- Pop("spc_x");
- break;
-
- case 0xEE: // POP X
- Pop("r0");
- ot(" and spc_ya,spc_ya,#0xff\n");
- otb(" orr spc_ya,spc_ya,r0,lsl #8\n");
- break;
-
- case 0x0E: // TSET1 abs
- Absolute(0);
- ot(" mov r3, r0\n");
- //ot(" orr spc_x,spc_x,r0,lsl #16 @ save from memhandler\n");
- MemHandler(0, 0, 0);
- ot(" and r2,r0,spc_ya\n");
- SetZN8("r2");
- ot(" orr r0,r0,spc_ya\n");
- ot(" mov r1, r3\n");
- //ot(" mov r1,spc_x,lsr #16\n");
- //ot(" and spc_x,spc_x,#0xff\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0x4E: // TCLR1 abs
- Absolute(0);
- ot(" mov r3, r0\n");
- //ot(" orr spc_x,spc_x,r0,lsl #16 @ save from memhandler\n");
- MemHandler(0, 0, 0);
- ot(" and r2,r0,spc_ya\n");
- SetZN8("r2");
- ot(" bic r0,r0,spc_ya\n");
- ot(" mov r1, r3\n");
- //ot(" mov r1,spc_x,lsr #16\n");
- //ot(" and spc_x,spc_x,#0xff\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0x0F: // BRK
- ot(" sub r0,spc_pc,spc_ram\n");
- PushW();
- ot(" mov r0,spc_p,lsr #24\n");
- ot(" and r1,r0,#0x80\n");
- ot(" tst r0,r0\n");
- ot(" orrne r1,r1,#flag_z\n");
- ot(" and spc_p,spc_p,#0x7d @ clear N & Z\n");
- ot(" orr spc_p,spc_p,r1\n");
- Push("spc_p");
- ot(" orr spc_p,spc_p,#flag_b\n");
- ot(" bic spc_p,spc_p,#flag_i\n");
- ot(" ldr r0,[context,#iapu_extraram]\n");
- ot(" ldrh r0,[r0,#0x20]\n");
- ot(" add spc_pc,spc_ram,r0\n");
- break;
-
- case 0xEF: // SLEEP
- case 0xFF: // STOP: this is to be compatible with yoyofr's code
- //ot(" ldr r0,=CPU\n");
- ot(" ldr r0, 5001f\n", apu_cycles);
- ot(" mov r1,#0\n");
- //otb(" strb r1,[r0,#122]\n");
- otb(" str r1,[r0,#cpu_apu_executing]\n");
- //tmp_epilogue();
- ot(" subs cycles,cycles,#%i\n", S9xAPUCycles[opcode] * one_apu_cycle[current_cycles]);
- ot(" ldrgeb opcode,[spc_pc],#1\n");
- flush_buffer();
- ot(" ldrge pc,[opcodes,opcode,lsl #2]\n");
- ot(" b spc700End\n");
- // don't let code flow until here
- ot("5001:\n", apu_cycles);
- ot(" .long CPU \n");
- break;
-
- case 0x2F: // BRA
- ot(" ldrsb r0,[spc_pc],#1\n");
- ot(" add spc_pc,spc_pc,r0\n");
- break;
-
- case 0x80: // SETC
- otb(" orr spc_p,spc_p,#flag_c\n");
- break;
-
- case 0xED: // NOTC
- otb(" eor spc_p,spc_p,#flag_c\n");
- break;
-
- case 0x40: // SETP
- ot(" orr spc_p,spc_p,#flag_d\n");
- ot(" add r0,spc_ram,#0x100\n");
- otb(" str r0,[context,#iapu_directpage]\n");
- break;
-
- case 0x1A: // DECW dp
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- ot(" ldrb r0,[spc_pc]\n");
- ot(" add r0,r0,#1\n");
- MemHandler(0, 1, 0);
- //ot(" ldmfd sp!,{r1}\n");
- ot(" orr r1,r3,r0,lsl #8\n");
- ot(" sub r0,r1,#1\n");
- SetZN16("r0");
- ot(" stmfd sp!,{r0}\n");
- ot(" ldrb r1,[spc_pc]\n");
- MemHandler(1, 1, 0);
- ot(" ldmfd sp!,{r0}\n");
- ot(" mov r0,r0,lsr #8\n");
- ot(" ldrb r1,[spc_pc],#1\n");
-
- ot(" add r1,r1,#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x5A: // CMPW YA,dp
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- ot(" ldrb r0,[spc_pc],#1\n");
- ot(" add r0,r0,#1\n");
- MemHandler(0, 1, 1);
- //ot(" ldmfd sp!,{r1}\n");
- ot(" orr r1,r3,r0,lsl #8\n");
- ot(" subs r0,spc_ya,r1\n");
- ot(" orrge spc_p,spc_p,#flag_c\n");
- ot(" biclt spc_p,spc_p,#flag_c\n");
- SetZN16("r0");
- break;
-
- case 0x3A: // INCW dp
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- ot(" ldrb r0,[spc_pc]\n");
- ot(" add r0,r0,#1\n");
- MemHandler(0, 1, 0);
- //ot(" ldmfd sp!,{r1}\n");
- ot(" orr r1,r3,r0,lsl #8\n");
- ot(" add r0,r1,#1\n");
- SetZN16("r0");
- ot(" stmfd sp!,{r0}\n");
- ot(" ldrb r1,[spc_pc]\n");
- MemHandler(1, 1, 0);
- ot(" ldmfd sp!,{r0}\n");
- ot(" mov r0,r0,lsr #8\n");
- ot(" ldrb r1,[spc_pc],#1\n");
- ot(" add r1,r1,#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x7A: // ADDW YA,dp
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- ot(" ldrb r0,[spc_pc],#1\n");
- ot(" add r0,r0,#1\n");
- MemHandler(0, 1, 1);
- //ot(" ldmfd sp!,{r1}\n");
- ot(" orr r1,r3,r0,lsl #8\n");
- ot(" add r0,spc_ya,r1\n");
- ot(" movs r2,r0,lsr #16\n");
- ot(" orrne spc_p,spc_p,#flag_c\n");
- ot(" biceq spc_p,spc_p,#flag_c\n");
- ot(" bic r2,r0,#0x00ff0000\n");
- ot(" eor r3,r1,r2\n"); // Work16 ^ (uint16) Work32
- ot(" eor r14,spc_ya,r1\n");
- ot(" mvn r14,r14\n"); // ~(pIAPU->YA.W ^ Work16)
- ot(" and r14,r14,r3\n");
- ot(" tst r14,#0x8000\n");
- ot(" orrne spc_p,spc_p,#flag_o\n");
- ot(" biceq spc_p,spc_p,#flag_o\n");
- ot(" eor r14,r3,spc_ya\n");
- ot(" tst r14,#0x10\n");
- ot(" orrne spc_p,spc_p,#flag_h\n");
- ot(" biceq spc_p,spc_p,#flag_h\n");
- ot(" mov spc_ya,r2\n");
- SetZN16("spc_ya");
-
- break;
-
- case 0x9A: // SUBW YA,dp
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- ot(" ldrb r0,[spc_pc],#1\n");
- ot(" add r0,r0,#1\n");
- MemHandler(0, 1, 1);
- //ot(" ldmfd sp!,{r1}\n");
- ot(" orr r1,r3,r0,lsl #8\n");
- ot(" subs r0,spc_ya,r1\n");
- ot(" orrge spc_p,spc_p,#flag_c\n");
- ot(" biclt spc_p,spc_p,#flag_c\n");
- ot(" mov r2,r0,lsl #16\n");
- ot(" mov r2,r2,lsr #16\n"); // r2=(uint16) Int32
- ot(" eor r3,spc_ya,r2\n"); // r3=pIAPU->YA.W ^ (uint16) Int32
- ot(" eor r14,spc_ya,r1\n");
- ot(" and r14,r14,r3\n");
- ot(" tst r14,#0x8000\n");
- ot(" orrne spc_p,spc_p,#flag_o\n");
- ot(" biceq spc_p,spc_p,#flag_o\n");
- ot(" eor r14,r3,r1\n");
- ot(" tst r14,#0x10\n");
- ot(" bicne spc_p,spc_p,#flag_h\n");
- ot(" orreq spc_p,spc_p,#flag_h\n");
- ot(" mov spc_ya,r2\n");
- SetZN16("spc_ya");
- break;
-
- case 0xBA: // MOVW YA,dp
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- ot(" ldrb r1, [spc_pc],#1\n");
- ot(" mov spc_ya, r0\n"); // avoiding inter-locks
- ot(" add r0, r1, #1\n");
- MemHandler(0, 1, 1);
- ot(" orr spc_ya,spc_ya,r0,lsl #8\n");
- SetZN16("spc_ya");
- break;
-
- case 0xDA: // MOVW dp,YA
- ot(" ldrb r1,[spc_pc]\n");
- ot(" mov r0,spc_ya\n");
- MemHandler(1, 1, 0);
- ot(" ldrb r1,[spc_pc],#1\n");
- ot(" mov r0,spc_ya,lsr #8\n"); // avoiding inter-locks
- ot(" add r1,r1,#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x69: // CMP dp(dest), dp(src)
- ot(" ldrb r0,[spc_pc],#1\n");
- MemHandler(0, 1, 0);
- ot(" orr spc_x,spc_x,r0,lsl #24\n");
- ot(" ldrb r0,[spc_pc],#1\n");
- MemHandler(0, 1, 1);
- ot(" mov r1,spc_x,lsr #24\n");
- Cmp("r0", "r1", 0);
- otb(" and spc_x,spc_x,#0xff\n");
- break;
-
- case 0x78: // CMP dp,#00
- ot(" ldrb r0,[spc_pc,#1]\n");
- MemHandler(0, 1, 1);
- ot(" ldrb r1,[spc_pc],#2\n");
- Cmp("r0", "r1", 0);
- break;
-
- case 0x79: // CMP (X),(Y)
- ot(" mov r0,spc_x\n");
- MemHandler(0, 1, 0);
- ot(" orr spc_x,spc_x,r0,lsl #24\n");
- ot(" mov r0,spc_ya,lsr #8\n");
- MemHandler(0, 1, 1);
- ot(" mov r1,spc_x,lsr #24\n");
- Cmp("r1", "r0", 0);
- otb(" and spc_x,spc_x,#0xff\n");
- break;
-
- case 0x1E: // CMP X,abs
- Absolute(0);
- MemHandler(0, 0, 1);
- Cmp("spc_x", "r0", 0);
- break;
-
- case 0x3E: // CMP X,dp
- ot(" ldrb r0,[spc_pc],#1\n");
-
- MemHandler(0, 1, 1);
- Cmp("spc_x", "r0", 0);
- break;
-
- case 0xC8: // CMP X,#00
- ot(" ldrb r0,[spc_pc],#1\n");
- Cmp("spc_x", "r0", 0);
- break;
-
- case 0x5E: // CMP Y,abs
- Absolute(0);
- MemHandler(0, 0, 1);
- ot(" mov r1,spc_ya,lsr #8\n");
- Cmp("r1", "r0", 0);
- break;
-
- case 0x7E: // CMP Y,dp
- ot(" ldrb r0,[spc_pc],#1\n");
- MemHandler(0, 1, 1);
- ot(" mov r1,spc_ya,lsr #8\n");
- Cmp("r1", "r0", 0);
- break;
-
- case 0xAD: // CMP Y,#00
- ot(" ldrb r0,[spc_pc],#1\n");
- ot(" mov r1,spc_ya,lsr #8\n");
- Cmp("r1", "r0", 0);
- break;
-
- case 0x1F: // JMP (abs+X)
- AbsoluteX(0);
- ot(" sub sp,sp,#8\n");
- ot(" str r0,[sp,#4]\n");
- MemHandler(0, 0, 0);
- ot(" str r0,[sp]\n");
- ot(" ldr r0,[sp,#4]\n");
- ot(" add r0,r0,#1\n");
- MemHandler(0, 0, 1);
- ot(" ldr r1,[sp],#8\n");
- ot(" orr r0,r1,r0,lsl #8\n");
- ot(" add spc_pc,spc_ram,r0\n");
- break;
-
- case 0x5F: // JMP abs
- //Absolute(0);
- //ot(" add spc_pc,spc_ram,r0\n");
- ot(" ldrb r0, [spc_pc], #1\n");
- ot(" ldrb r14, [spc_pc], #1\n");
- ot(" add spc_pc, r0, spc_ram\n");
- ot(" add spc_pc, spc_pc, r14, lsl #8\n");
- break;
-
- case 0x20: // CLRP
- ot(" bic spc_p,spc_p,#flag_d\n");
- otb(" str spc_ram,[context,#iapu_directpage]\n");
- break;
-
- case 0x60: // CLRC
- otb(" bic spc_p,spc_p,#flag_c\n");
- break;
-
- case 0xE0: // CLRV
- otb(" bic spc_p,spc_p,#(flag_o|flag_h)\n");
- break;
-
- case 0x29: // AND dp(dest), dp(src)
- ot(" ldrb r0,[spc_pc],#1\n");
- MemHandler(0, 1, 0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- //ot(" ldmfd sp!,{r1}\n");
- ot(" and r0,r0,r3\n");
- SetZN8("r0");
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x38: // AND dp,#00
- ot(" ldrb r0,[spc_pc,#1]\n");
- MemHandler(0, 1, 0);
- ot(" ldrb r1,[spc_pc],#2\n");
- ot(" and r0,r0,r1\n");
- SetZN8("r0");
- ot(" ldrb r1,[spc_pc,#-1]\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x39: // AND (X),(Y)
- ot(" mov r0,spc_x\n");
- MemHandler(0, 1, 0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- ot(" mov r0,spc_ya,lsr #8\n");
- MemHandler(0, 1, 0);
- //ot(" ldmfd sp!,{r1}\n");
- ot(" and r0,r0,r3\n");
- SetZN8("r0");
- ot(" mov r1,spc_x\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x2B: // ROL dp
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- Rol();
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x2C: // ROL abs
- Absolute(0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- MemHandler(0, 0, 0);
- Rol();
- //ot(" ldmfd sp!,{r1}\n");
- ot(" mov r1, r3\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0x3B: // ROL dp+X
- ot(" ldrb r0,[spc_pc]\n");
- ot(" add r0,r0,spc_x\n");
- MemHandler(0, 1, 0);
- Rol();
- ot(" ldrb r1,[spc_pc],#1\n");
- ot(" add r1,r1,spc_x\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x3C: // ROL A
- ot(" and r0,spc_ya,#0xff\n");
- Rol();
- ot(" and r0,r0,#0xff\n");
- ot(" mov spc_ya,spc_ya,lsr #8\n");
- otb(" orr spc_ya,r0,spc_ya,lsl #8\n");
- break;
-
- case 0x2E: // CBNE dp,rel
- ot(" ldrb r0,[spc_pc],#1\n");
- MemHandler(0, 1, 1);
- ot(" and r1,spc_ya,#0xff\n");
- ot(" cmp r0,r1\n");
- ot(" addeq spc_pc,spc_pc,#1\n");
- ot(" ldrnesb r0,[spc_pc],#1\n");
- ot(" subne cycles,cycles,#%i\n", one_apu_cycle[current_cycles]*2);
- ot(" addne spc_pc,spc_pc,r0\n");
- break;
-
- case 0xDE: // CBNE dp+X,rel
- ot(" ldrb r0,[spc_pc],#1\n");
- ot(" add r0,r0,spc_x\n");
- MemHandler(0, 1, 1);
- ot(" and r1,spc_ya,#0xff\n");
- ot(" cmp r0,r1\n");
- ot(" addeq spc_pc,spc_pc,#1\n");
- ot(" ldrnesb r0,[spc_pc],#1\n");
- ot(" addne spc_pc,spc_pc,r0\n");
- ot(" subne cycles,cycles,#%i\n", one_apu_cycle[current_cycles]*2);
- break;
-
- case 0x3D: // INC X
- ot(" add spc_x,spc_x,#1\n");
- ot(" and spc_x,spc_x,#0xff\n");
- SetZN8("spc_x");
- break;
-
- case 0xFC: // INC Y
- ot(" mov r0,spc_ya,lsr #8\n");
- ot(" add r0,r0,#1\n");
- ot(" and r0,r0,#0xff\n");
- SetZN8("r0");
- ot(" and spc_ya,spc_ya,#0xff\n");
- otb(" orr spc_ya,spc_ya,r0,lsl #8\n");
- break;
-
- case 0x1D: // DEC X
- ot(" sub spc_x,spc_x,#1\n");
- ot(" and spc_x,spc_x,#0xff\n");
- SetZN8("spc_x");
- break;
-
- case 0xDC: // DEC Y
- ot(" mov r0,spc_ya,lsr #8\n");
- ot(" sub r0,r0,#1\n");
- ot(" and r0,r0,#0xff\n");
- SetZN8("r0");
- ot(" and spc_ya,spc_ya,#0xff\n");
- otb(" orr spc_ya,spc_ya,r0,lsl #8\n");
- break;
-
- case 0xAB: // INC dp
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- ot(" add r0,r0,#1\n");
- SetZN8("r0");
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0xAC: // INC abs
- Absolute(0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- MemHandler(0, 0, 0);
- ot(" add r0,r0,#1\n");
- SetZN8("r0");
- //ot(" ldmfd sp!,{r1}\n");
- ot(" mov r1, r3\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0xBB: // INC dp+X
- ot(" ldrb r0,[spc_pc]\n");
- ot(" add r0,r0,spc_x\n");
- MemHandler(0, 1, 0);
- ot(" add r0,r0,#1\n");
- SetZN8("r0");
- ot(" ldrb r1,[spc_pc],#1\n");
- ot(" add r1,r1,spc_x\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0xBC: // INC A
- ot(" and r0,spc_ya,#0xff\n");
- ot(" add r0,r0,#1\n");
- SetZN8("r0");
- ot(" and r0,r0,#0xff\n");
- ot(" mov spc_ya,spc_ya,lsr #8\n");
- otb(" orr spc_ya,r0,spc_ya,lsl #8\n");
- break;
-
- case 0x8B: // DEC dp
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- ot(" sub r0,r0,#1\n");
- SetZN8("r0");
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x8C: // DEC abs
- Absolute(0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- MemHandler(0, 0, 0);
- ot(" sub r0,r0,#1\n");
- SetZN8("r0");
- //ot(" ldmfd sp!,{r1}\n");
- ot(" mov r1, r3\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0x9B: // DEC dp+X
- ot(" ldrb r0,[spc_pc]\n");
- ot(" add r0,r0,spc_x\n");
- MemHandler(0, 1, 0);
- ot(" sub r0,r0,#1\n");
- SetZN8("r0");
- ot(" ldrb r1,[spc_pc],#1\n");
-
- ot(" add r1,r1,spc_x\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x9C: // DEC A
- ot(" and r0,spc_ya,#0xff\n");
- ot(" sub r0,r0,#1\n");
- SetZN8("r0");
- ot(" and r0,r0,#0xff\n");
- ot(" mov spc_ya,spc_ya,lsr #8\n");
- otb(" orr spc_ya,r0,spc_ya,lsl #8\n");
- break;
-
- case 0x49: // EOR dp(dest), dp(src)
- ot(" ldrb r0,[spc_pc],#1\n");
- MemHandler(0, 1, 0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- //ot(" ldmfd sp!,{r1}\n");
- ot(" eor r0,r0,r3\n");
- SetZN8("r0");
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x58: // EOR dp,#00
- ot(" ldrb r0,[spc_pc,#1]\n");
- MemHandler(0, 1, 0);
- ot(" ldrb r1,[spc_pc],#2\n");
- ot(" eor r0,r0,r1\n");
- SetZN8("r0");
- ot(" ldrb r1,[spc_pc,#-1]\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x59: // EOR (X),(Y)
- ot(" mov r0,spc_x\n");
- MemHandler(0, 1, 0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- ot(" mov r0,spc_ya,lsr #8\n");
- MemHandler(0, 1, 0);
- //ot(" ldmfd sp!,{r1}\n");
- ot(" eor r0,r0,r3\n");
- SetZN8("r0");
- ot(" mov r1,spc_x\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x4B: // LSR dp
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- Lsr();
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x4C: // LSR abs
- Absolute(0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- MemHandler(0, 0, 0);
- Lsr();
- //ot(" ldmfd sp!,{r1}\n");
- ot(" mov r1, r3\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0x5B: // LSR dp+X
- ot(" ldrb r0,[spc_pc]\n");
- ot(" add r0,r0,spc_x\n");
- MemHandler(0, 1, 0);
- Lsr();
- ot(" ldrb r1,[spc_pc],#1\n");
- ot(" add r1,r1,spc_x\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x5C: // LSR A
- ot(" and r0,spc_ya,#0xff\n");
- Lsr();
- ot(" mov spc_ya,spc_ya,lsr #8\n");
- otb(" orr spc_ya,r0,spc_ya,lsl #8\n");
- break;
-
- case 0x7D: // MOV A,X
- ot(" and spc_ya,spc_ya,#0xff00\n");
- ot(" orr spc_ya,spc_ya,spc_x\n");
- SetZN8("spc_ya");
- break;
-
- case 0xDD: // MOV A,Y
- ot(" and spc_ya,spc_ya,#0xff00\n");
- ot(" orr spc_ya,spc_ya,spc_ya,lsr #8\n");
- SetZN8("spc_ya");
- break;
-
- case 0x5D: // MOV X,A
- ot(" and spc_x,spc_ya,#0xff\n");
- SetZN8("spc_x");
- break;
-
- case 0xFD: // MOV Y,A
- ot(" and spc_ya,spc_ya,#0xff\n");
- ot(" orr spc_ya,spc_ya,spc_ya,lsl #8\n");
- SetZN8("spc_ya");
- break;
-
- case 0x9D: // MOV X,SP
- ot(" mov spc_x,spc_s\n");
- SetZN8("spc_x");
- break;
-
- case 0xBD: // SP,X
- otb(" mov spc_s,spc_x\n");
- break;
-
- case 0x6B: // ROR dp
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- Ror();
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x6C: // ROR abs
- Absolute(0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- MemHandler(0, 0, 0);
- Ror();
- ot(" mov r1, r3\n");
- //ot(" ldmfd sp!,{r1}\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0x7B: // ROR dp+X
- ot(" ldrb r0,[spc_pc]\n");
- ot(" add r0,r0,spc_x\n");
- MemHandler(0, 1, 0);
- Ror();
- ot(" ldrb r1,[spc_pc],#1\n");
- ot(" add r1,r1,spc_x\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x7C: // ROR A
- ot(" and r0,spc_ya,#0xff\n");
- Ror();
- ot(" mov spc_ya,spc_ya,lsr #8\n");
- otb(" orr spc_ya,r0,spc_ya,lsl #8\n");
- break;
-
- case 0x6E: // DBNZ dp,rel
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- ot(" ldrb r1,[spc_pc],#1\n");
- ot(" sub r0,r0,#1\n");
- ot(" tst r0,r0\n");
- ot(" addeq spc_pc,spc_pc,#1\n");
- ot(" ldrnesb r2,[spc_pc],#1\n");
- ot(" addne spc_pc,spc_pc,r2\n");
- ot(" subne cycles,cycles,#%i\n", one_apu_cycle[current_cycles]*2);
- MemHandler(1, 1, 1);
- break;
-
- case 0xFE: // DBNZ Y,rel
- ot(" sub spc_ya,spc_ya,#0x100\n");
- ot(" mov spc_ya,spc_ya,lsl #16\n");
- ot(" mov spc_ya,spc_ya,lsr #16\n");
- ot(" movs r0,spc_ya,lsr #8\n");
- ot(" addeq spc_pc,spc_pc,#1\n");
- ot(" ldrnesb r0,[spc_pc],#1\n");
- ot(" addne spc_pc,spc_pc,r0\n");
- ot(" subne cycles,cycles,#%i\n", one_apu_cycle[current_cycles]*2);
- break;
-
- case 0x6F: // RET
- PopW();
- ot(" add spc_pc,spc_ram,r0\n");
- break;
-
- case 0x7F: // RETI
- Pop("spc_p");
- ot(" and r0,spc_p,#(flag_z|flag_n)\n");
- ot(" eor r0,r0,#flag_z\n");
- ot(" orr spc_p,spc_p,r0,lsl #24\n");
- ot(" tst spc_p,#flag_d\n");
- ot(" addne r0,spc_ram,#0x100\n");
- ot(" moveq r0,spc_ram\n");
- ot(" str r0,[context,#iapu_directpage]\n");
- PopW();
- ot(" add spc_pc,spc_ram,r0\n");
- break;
-
- case 0x89: // ADC dp(dest), dp(src)
- ot(" ldrb r0,[spc_pc],#1\n");
- MemHandler(0, 1, 0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- //ot(" ldmfd sp!,{r1}\n");
- //ot(" mov r1, r3\n");
- Adc("r0", "r3");
- SetZN8("r0");
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x98: // ADC dp,#00
- ot(" ldrb r0,[spc_pc,#1]\n");
- MemHandler(0, 1, 0);
- ot(" ldrb r1,[spc_pc],#2\n");
- Adc("r0", "r1");
- SetZN8("r0");
- ot(" ldrb r1,[spc_pc,#-1]\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x99: // ADC (X),(Y)
- ot(" mov r0,spc_x\n");
- MemHandler(0, 1, 0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- ot(" mov r0,spc_ya,lsr #8\n");
- MemHandler(0, 1, 0);
- //ot(" ldmfd sp!,{r1}\n");
- //ot(" mov r1, r3\n");
- Adc("r0", "r3");
- SetZN8("r0");
- ot(" mov r1,spc_x\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x8D: // MOV Y,#00 //-REVISAR
- ot(" ldrb r0,[spc_pc],#1\n");
- ot(" and spc_ya,spc_ya,#0xff\n");
- ot(" orr spc_ya,spc_ya,r0,lsl #8\n");
- SetZN8("r0");
- break;
-
- case 0x8F: // MOV dp,#00 //-REVISAR
- ot(" ldrb r0,[spc_pc],#1\n");
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0x9E: // DIV YA,X
- ot(" tst spc_x,spc_x @ div by 0?\n");
- ot(" orreq spc_ya,spc_ya,#0xff00\n");
- ot(" orreq spc_ya,spc_ya,#0x00ff\n");
- ot(" orreq spc_p,spc_p,#flag_o\n");
- ot(" beq 1002f\n");
- ot(" bic spc_p,spc_p,#flag_o\n");
-
- // division algo from Cyclone (result in r3, remainder instead of divident)
- ot("@ Divide spc_ya by spc_x\n");
- ot(" mov r3,#0\n");
- ot(" mov r1,spc_x\n");
- ot("\n");
-
- //
- /*ot("@ Shift up divisor till it's just less than numerator\n");
- ot("divshift:\n");
- ot(" cmp r1,spc_ya,lsr #1\n");
- ot(" movls r1,r1,lsl #1\n");
- ot(" bcc divshift\n");
- ot("\n");*/
-
- //optimised version of code provided by William Blair
- ot("@ Shift up divisor till it's just less than numerator\n");
- ot("cmp spc_ya,r1,lsl #8\n");
- ot("movge r1,r1,lsl #8\n");
- ot("cmp spc_ya,r1,lsl #4\n");
- ot("movge r1,r1,lsl #4\n");
- ot("cmp spc_ya,r1,lsl #2\n");
- ot("movge r1,r1,lsl #2\n");
- ot("cmp spc_ya,r1,lsl #1\n");
- ot("movge r1,r1,lsl #1\n");
-
- ot("1001:\n");
- ot(" cmp spc_ya,r1\n");
- ot(" adc r3,r3,r3 ;@ Double r3 and add 1 if carry set\n");
- ot(" subcs spc_ya,spc_ya,r1\n");
- ot(" teq r1,spc_x\n");
- ot(" movne r1,r1,lsr #1\n");
- ot(" bne 1001b\n");
- ot("\n");
-
- ot(" and spc_ya,spc_ya,#0xff\n");
- ot(" and r3,r3,#0xff\n");
- ot(" orr spc_ya,r3,spc_ya,lsl #8\n");
-
- ot("1002:\n");
- SetZN8("spc_ya");
- break;
-
- case 0x9F: // XCN A
- ot(" and r0,spc_ya,#0xff\n");
- ot(" mov r1,r0,lsl #28\n");
- ot(" orr r0,r1,r0,lsl #20\n");
- ot(" and spc_ya,spc_ya,#0xff00\n");
- ot(" orr spc_ya,spc_ya,r0,lsr #24\n");
- SetZN8("spc_ya");
- break;
-
- case 0xA9: // SBC dp(dest), dp(src)
- ot(" ldrb r0,[spc_pc],#1\n");
- MemHandler(0, 1, 0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- ot(" ldrb r0,[spc_pc]\n");
- MemHandler(0, 1, 0);
- //ot(" ldmfd sp!,{r1}\n");
- //ot(" mov r1, r3\n");
- Sbc("r0", "r3");
- SetZN8("r0");
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0xB8: // SBC dp,#00
- ot(" ldrb r0,[spc_pc,#1]\n");
- MemHandler(0, 1, 0);
- ot(" ldrb r1,[spc_pc],#2\n");
- Sbc("r0", "r1");
- SetZN8("r0");
- ot(" ldrb r1,[spc_pc,#-1]\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0xB9: // SBC (X),(Y)
- ot(" mov r0,spc_x\n");
- MemHandler(0, 1, 0);
- //ot(" stmfd sp!,{r0}\n");
- ot(" mov r3, r0\n");
- ot(" mov r0,spc_ya,lsr #8\n");
- MemHandler(0, 1, 0);
- //ot(" ldmfd sp!,{r1}\n");
- //ot(" mov r1, r3\n");
- Sbc("r0", "r3");
- SetZN8("r0");
- ot(" mov r1,spc_x\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0xAF: // MOV (X)+, A
- ot(" mov r0,spc_ya\n");
- ot(" mov r1,spc_x\n");
- MemHandler(1, 1, 1);
- ot(" add spc_x,spc_x,#1\n");
- otb(" and spc_x,spc_x,#0xff\n");
- break;
-
- case 0xBE: // DAS
- ot(" and r0,spc_ya,#0xff\n");
- ot(" and r1,spc_ya,#0x0f\n");
- ot(" cmp r1,#9\n");
- ot(" subhi r0,r0,#6\n");
- ot(" tstls spc_p,#flag_h\n");
- ot(" subeq r0,r0,#6\n");
- ot(" cmp r0,#0x9f\n");
- ot(" bhi 2001f\n");
- ot(" tst spc_p,#flag_c\n");
- ot(" beq 2001f\n");
- ot(" orr spc_p,spc_p,#flag_c\n");
- ot(" b 2002f\n");
- ot("2001:\n"); // tens
- ot(" sub r0,r0,#0x60\n");
- ot(" bic spc_p,spc_p,#flag_c\n");
-
- ot("2002:\n"); // end
- ot(" and spc_ya,spc_ya,#0xff00\n");
- ot(" orr spc_ya,spc_ya,r0\n");
- SetZN8("spc_ya");
- break;
-
- case 0xBF: // MOV A,(X)+
- ot(" mov r0,spc_x\n");
- MemHandler(0, 1, 1);
- ot(" and spc_ya,spc_ya,#0xff00\n");
- ot(" orr spc_ya,spc_ya,r0\n");
- ot(" add spc_x,spc_x,#1\n");
- ot(" and spc_x,spc_x,#0xff\n");
- SetZN8("spc_ya");
- break;
-
- case 0xC0: // DI
- otb(" bic spc_p,spc_p,#flag_i\n");
- break;
-
- case 0xA0: // EI
- otb(" orr spc_p,spc_p,#flag_i\n");
- break;
-
- case 0xC4: // MOV dp,A
- ot(" ldrb r1,[spc_pc],#1\n");
- ot(" mov r0,spc_ya\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0xC5: // MOV abs,A
- Absolute(1);
- ot(" mov r0,spc_ya\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0xC6: // MOV (X),A
- ot(" mov r0,spc_ya\n");
- ot(" mov r1,spc_x\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0xC7: // MOV (dp+X),A
- IndexedXIndirect(1);
- ot(" mov r0,spc_ya\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0xC9: // MOV abs,X
- Absolute(1);
- ot(" mov r0,spc_x\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0xCB: // MOV dp,Y
- ot(" ldrb r1,[spc_pc],#1\n");
- ot(" mov r0,spc_ya,lsr #8\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0xCC: // MOV abs,Y
-
- Absolute(1);
- ot(" mov r0,spc_ya,lsr #8\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0xCD: // MOV X,#00
- ot(" ldrb spc_x,[spc_pc],#1\n");
- SetZN8("spc_x");
- break;
-
- case 0xCF: // MUL YA
- ot(" mov r0,spc_ya,lsr #8\n");
- ot(" and spc_ya,spc_ya,#0xff\n");
- ot(" mul spc_ya,r0,spc_ya\n");
- SetZN16("spc_ya");
- break;
-
- case 0xD4: // MOV dp+X, A
- ot(" ldrb r1,[spc_pc],#1\n");
- ot(" mov r0,spc_ya\n");
- ot(" add r1,r1,spc_x\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0xD5: // MOV abs+X,A
- AbsoluteX(1);
- ot(" mov r0,spc_ya\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0xD6: // MOV abs+Y,A
- AbsoluteY(1);
- ot(" mov r0,spc_ya\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0xD7: // MOV (dp)+Y,A
- IndirectIndexedY(1);
- ot(" mov r0,spc_ya\n");
- MemHandler(1, 0, 1);
- break;
-
- case 0xD8: // MOV dp,X
- ot(" ldrb r1,[spc_pc],#1\n");
- ot(" mov r0,spc_x\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0xD9: // MOV dp+Y,X
- ot(" ldrb r1,[spc_pc],#1\n");
- ot(" mov r0,spc_x\n");
- ot(" add r1,r1,spc_ya,lsr #8\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0xDB: // MOV dp+X,Y
- ot(" ldrb r1,[spc_pc],#1\n");
- ot(" mov r0,spc_ya,lsr #8\n");
- ot(" add r1,r1,spc_x\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0xDF: // DAA
- ot(" and r0,spc_ya,#0xff\n");
- ot(" and r1,spc_ya,#0x0f\n");
- ot(" cmp r1,#9\n");
- ot(" addhi r0,r0,#6\n");
- ot(" bls 3001f\n");
- ot(" cmphi r0,#0xf0\n");
- ot(" orrhi spc_p,spc_p,#flag_c\n");
- ot(" b 3002f\n");
- ot("3001:\n"); // testHc
- ot(" tst spc_p,#flag_h\n");
- ot(" addne r0,r0,#6\n");
- ot(" beq 3002f\n");
- ot(" cmp r0,#0xf0\n");
- ot(" orrhi spc_p,spc_p,#flag_c\n");
- ot("3002:\n"); // test2
- ot(" tst spc_p,#flag_c\n");
- ot(" addne r0,r0,#0x60\n");
- ot(" bne 3003f\n");
- ot(" cmp r0,#0x9f\n");
- ot(" addhi r0,r0,#0x60\n");
- ot(" orrhi spc_p,spc_p,#flag_c\n");
- ot(" bicls spc_p,spc_p,#flag_c\n");
- ot("3003:\n"); // end
- ot(" and spc_ya,spc_ya,#0xff00\n");
- ot(" orr spc_ya,spc_ya,r0\n");
- SetZN8("spc_ya");
- break;
-
- case 0xE9: // MOV X, abs
- Absolute(0);
- MemHandler(0, 0, 1);
- ot(" mov spc_x,r0\n");
- SetZN8("spc_x");
- break;
-
- case 0xEB: // MOV Y,dp
- ot(" ldrb r0,[spc_pc],#1\n");
- MemHandler(0, 1, 1);
- ot(" and spc_ya,spc_ya,#0xff\n");
- ot(" orr spc_ya,spc_ya,r0,lsl #8\n");
- SetZN8("r0");
- break;
-
- case 0xEC: // MOV Y,abs
- Absolute(0);
- MemHandler(0, 0, 1);
- ot(" and spc_ya,spc_ya,#0xff\n");
- ot(" orr spc_ya,spc_ya,r0,lsl #8\n");
- SetZN8("r0");
- break;
-
- case 0xF8: // MOV X,dp
- ot(" ldrb r0,[spc_pc],#1\n");
- MemHandler(0, 1, 1);
- ot(" mov spc_x,r0\n");
- SetZN8("spc_x");
- break;
-
- case 0xF9: // MOV X,dp+Y
- ot(" ldrb r0,[spc_pc],#1\n");
- ot(" add r0,r0,spc_ya,lsr #8\n");
- MemHandler(0, 1, 1);
- ot(" mov spc_x,r0\n");
- SetZN8("spc_x");
- break;
-
- case 0xFA: // MOV dp(dest),dp(src)
- ot(" ldrb r0,[spc_pc],#1\n");
- MemHandler(0, 1, 0);
- ot(" ldrb r1,[spc_pc],#1\n");
- MemHandler(1, 1, 1);
- break;
-
- case 0xFB: // MOV Y,dp+X
- ot(" ldrb r0,[spc_pc],#1\n");
- ot(" add r0,r0,spc_x\n");
- MemHandler(0, 1, 1);
- ot(" and spc_ya,spc_ya,#0xff\n");
- ot(" orr spc_ya,spc_ya,r0,lsl #8\n");
- SetZN8("r0");
- break;
- }
-
- //tmp_epilogue();
- ot(" subs cycles,cycles,#%i\n", S9xAPUCycles[opcode] * one_apu_cycle[current_cycles]);
- ot(" ldrgeb opcode,[spc_pc],#1\n");
- flush_buffer();
- ot(" ldrge pc,[opcodes,opcode,lsl #2]\n");
- ot(" b spc700End\n");
-
- printf("\b\b");
- }
-
-
- ot("\n\n");
-
-}
-
-
-void printJumpTable(int apu_cycles) {
- int i;
- ot("@ -------------------------- Jump Table %i --------------------------\n", apu_cycles);
- ot("Spc700JumpTab_%i:\n", apu_cycles);
-
- for (i=0; i < 0x100; i++)
- {
- if ((i&7)==0) ot(" .long ");
-
- ot("Apu%02X_%i", i, apu_cycles);
-
- if ((i&7)==7) ot(" @ %02x\n",i-7);
- else if (i+1 < 0x100) ot(", ");
- }
-
-}
-
-int main()
-{
- printf("\n notaz's SPC700 Emulator v%s - Core Creator\n\n", VERSION);
-
- // Open the assembly file
- AsmFile=fopen("spc700a.s", "wt"); if (AsmFile==NULL) return 1;
-
- ot("@ notaz's SPC700 Emulator v%s - Assembler Output\n\n", VERSION);
- ot("@ (c) Copyright 2006 notaz, All rights reserved.\n\n");
- ot("@ Modified by bitrider 2010 - 2011\n\n");
- ot("@ this is a rewrite of spc700.cpp in ARM asm, inspired by other asm CPU cores like\n");
- ot("@ Cyclone and DrZ80. It is meant to be used in Snes9x emulator ports for ARM platforms.\n\n");
- ot("@ the code is released under Snes9x license. See spcgen.c or any other source file\n@ from Snes9x source tree.\n\n\n");
-
- PrintFramework();
-
- ot(" .align 4\n");
-
- for (current_cycles=0; current_cycles < (sizeof(one_apu_cycle) / sizeof(int)); current_cycles++) {
- printOpcodes(one_apu_cycle[current_cycles]);
- printJumpTable(one_apu_cycle[current_cycles]);
- }
-
-
- fclose(AsmFile); AsmFile=NULL;
-
- printf("Assembling...\n");
- // Assemble the file
- //system("as -marmv4t -mthumb-interwork -o spc700a.o spc700a.S");
- printf("Done!\n\n");
-
- return 0;
-}