mirror of
https://github.com/ares-emulator/ares.git
synced 2026-11-08 01:08:24 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9fd379613a | ||
|
|
aabf52d678 | ||
|
|
c9ca01fe20 | ||
|
|
becf122aaa | ||
|
|
1e130d7872 | ||
|
|
c57c733d7d | ||
|
|
e41aa25887 | ||
|
|
435f7d4371 | ||
|
|
a1980fab09 | ||
|
|
ebb234ba5f | ||
|
|
2cc7fe30b4 | ||
|
|
5c3c872b78 | ||
|
|
36bf915244 | ||
|
|
045a0f7e79 | ||
|
|
a209e6ffbe | ||
|
|
3bf672dd97 | ||
|
|
157ddf3e8f | ||
|
|
ea23bf53ae | ||
|
|
d4598e1d01 | ||
|
|
f9a8564af0 | ||
|
|
6d66b1136d | ||
|
|
b01f18c34c | ||
|
|
1ebdb69516 | ||
|
|
add0f74387 | ||
|
|
b20f70f333 | ||
|
|
9aebf7bc6b | ||
|
|
a7bf219d5d | ||
|
|
04118be59a | ||
|
|
f24d17859f | ||
|
|
35fd80bde7 | ||
|
|
ccf1c00b58 | ||
|
|
f4520d41ec | ||
|
|
e308cf4275 | ||
|
|
192e53bb87 | ||
|
|
0ed9edfcdb | ||
|
|
764fe1974a | ||
|
|
a55d640459 | ||
|
|
6010bffe5d | ||
|
|
e492268025 | ||
|
|
a36c26c997 | ||
|
|
a3945e5772 | ||
|
|
6b6233b3af | ||
|
|
9f63cb1b99 | ||
|
|
49c39e0e4d | ||
|
|
7dec0b2a3c | ||
|
|
f288280ceb | ||
|
|
c6c5f4669c | ||
|
|
397b9c4505 | ||
|
|
7e2cfb6d40 | ||
|
|
970dcea0ac | ||
|
|
402c146a53 | ||
|
|
a471c150c9 |
No files matched your search
@@ -1,21 +0,0 @@
|
||||
#[bsnes v0.007a configuration file]
|
||||
|
||||
#[video mode]
|
||||
# 0: 256x224w
|
||||
# 1: 512x448w
|
||||
# 2: 960x720w
|
||||
video.mode = 1
|
||||
|
||||
#[video memory type]
|
||||
# true: video ram (VRAM)
|
||||
# false: system ram (SRAM)
|
||||
#
|
||||
# VRAM results in the image being stretched in hardware,
|
||||
# which is generally much faster, and automatically adds
|
||||
# bilinear filtering (if the card supports it).
|
||||
#
|
||||
# However, some video cards end up taking a major speed
|
||||
# loss when this option is enabled. It is also the only
|
||||
# way to guarantee that the output image will not be
|
||||
# filtered.
|
||||
video.use_vram = true
|
||||
Binary file not shown.
+62
-9
@@ -1,10 +1,63 @@
|
||||
bsnes Licensing Agreement:
|
||||
bsnes (TM) Open Source Reference License
|
||||
Copyright (C) 2004 - 2007 byuu
|
||||
All rights reserved
|
||||
|
||||
You are free to redistribute this software, and its source code; provided
|
||||
there is no charge for the software, nor any charge for the medium used to
|
||||
distribute the software. You are also free to use and modify the source code
|
||||
as you desire for personal use only. No publically-released derivative works
|
||||
of this source code are permitted without my permission. You must also abide
|
||||
by the terms of any additional source code licenses contained within my code.
|
||||
At present, this only includes the mode7 renderer, which was derived from the
|
||||
snes9x mode7 renderer.
|
||||
1. Definitions
|
||||
|
||||
The terms "reproduce", "reproduction", "distribute" and "distribution" have the
|
||||
same meaning here as under U.S. copyright law.
|
||||
|
||||
"The software" means this software package as a whole, including, but not
|
||||
limited to, this license, binaries, source code, documentation, and data.
|
||||
|
||||
"You" means the licensee of the software.
|
||||
|
||||
"The licensor" means the copyright holder of the software, byuu.
|
||||
|
||||
2. Grant of Rights
|
||||
|
||||
Subject to the terms of this license, the licensor grants you a
|
||||
non-transferable, non-exclusive, worldwide, royalty-free copyright license to
|
||||
reproduce the software for non-commercial use only, provided the software
|
||||
remains unmodified, and there is no charge for the software itself, its' use,
|
||||
nor for the medium upon which the software is distributed. The reproduction of
|
||||
modified or derivative works of the software is strictly prohibited, except when
|
||||
transmitted solely to the licensor.
|
||||
|
||||
3. Limitations
|
||||
|
||||
This license does not grant you any rights to use the licensor's name, logo or
|
||||
trademarks.
|
||||
|
||||
The software is provided "as is", and any express or implied warranties,
|
||||
including, but not limited to, the implied warranties of merchantability and
|
||||
fitness for a particular purpose are disclaimed. In no event shall the licensor
|
||||
be liable for any direct, indirect, incidental, special, exemplary, or
|
||||
consequential damages (including, but not limited to, procurement of substitute
|
||||
goods or services; loss of use, data, or profits; or business interruption)
|
||||
however caused and on any theory of liability, whether in contract, strict
|
||||
liability, or tort (including negligence or otherwise) arising in any way out of
|
||||
the use of the software, even if advised of the possibility of such damage.
|
||||
|
||||
In the event that this license is determined to be invalid or unenforceable, the
|
||||
Grant of Rights will become null and void, and no rights shall be granted to the
|
||||
licensee, within the scope of U.S. copyright law.
|
||||
|
||||
4. Exemptions
|
||||
|
||||
The software includes the work of other copyright holders, which is licensed
|
||||
under different agreements, and exempt from this license. Below is a complete
|
||||
list of all such software, and their respective copyright holders and licenses.
|
||||
Further, respective source code files are labeled with their correct licensing
|
||||
information in the header. The lack of such a header indicates said file falls
|
||||
under the bsnes license.
|
||||
|
||||
HQ2x Filter, author: MaxST, license: LGPL
|
||||
JMA, author: NSRT Team, license: GPL (*)
|
||||
libco, author: byuu, license: public domain
|
||||
libui, author: byuu, license: public domain
|
||||
NTSC Filter, author: blargg, license: LGPL
|
||||
S-DD1, author: Andreas Naive, license: public domain
|
||||
zlib, license: zlib license
|
||||
|
||||
(*) bsnes has received an exemption from the copyright holder to use this work.
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
bsnes
|
||||
Version 0.024
|
||||
Author: byuu
|
||||
|
||||
--------
|
||||
General:
|
||||
--------
|
||||
bsnes is a Super Nintendo / Super Famicom emulator that began on
|
||||
October 14th, 2004.
|
||||
|
||||
The latest version can be downloaded from:
|
||||
http://byuu.org/
|
||||
|
||||
Please see license.txt for important licensing information.
|
||||
|
||||
--------------
|
||||
Shortcut Keys:
|
||||
--------------
|
||||
Esc - Toggle menubar visibility
|
||||
F11 - Toggle fullscreen
|
||||
|
||||
------------------
|
||||
Known Limitations:
|
||||
------------------
|
||||
S-CPU
|
||||
- Invalid DMA / HDMA transfers not fully emulated
|
||||
- Multiply / Divide register delays not implemented
|
||||
|
||||
S-PPU
|
||||
- Uses scanline-based renderer. This is very inaccurate, but few (if any)
|
||||
games rely on mid-scanline writes to function correctly
|
||||
- Does not support FirstSprite+Y priority
|
||||
- OAM / CGRAM accesses during active display not supported correctly
|
||||
- RTO flags are not calculated on frames that are skipped when frameskipping
|
||||
is enabled. This provides a major speedup, however it will cause in issues
|
||||
in games that test these flags, eg the SNES Test Program Electronics Test.
|
||||
Turning frameskipping off will allow RTO flag calculation on every frame
|
||||
|
||||
Hardware Bugs
|
||||
- S-CPU.r1 HDMA crashing bug not emulated
|
||||
- S-CPU<>S-SMP communication bus conflicts not emulated
|
||||
|
||||
---------------------
|
||||
Unsupported Hardware:
|
||||
---------------------
|
||||
SA-1
|
||||
Coprocessor used in many popular games, including:
|
||||
- Dragon Ball Z Hyper Dimension
|
||||
- Kirby Super Star
|
||||
- Kirby's Dreamland 3
|
||||
- Marvelous
|
||||
- SD Gundam G-NEXT
|
||||
- Super Mario RPG
|
||||
|
||||
Super FX
|
||||
Coprocessor used in many popular games, including:
|
||||
- Doom
|
||||
- Star Fox
|
||||
- Star Fox 2 (unreleased beta)
|
||||
- Super Mario World 2: Yoshi's Island
|
||||
|
||||
SPC7110
|
||||
Coprocessor used only by the following games:
|
||||
- Far East of Eden Zero
|
||||
- Far East of Eden Zero: Shounen Jump no Shou
|
||||
- Momotarou Densetsu Happy
|
||||
- Super Power League 4
|
||||
|
||||
DSP-3
|
||||
Coprocessor used only by SD Gundam GX
|
||||
|
||||
DSP-4
|
||||
Coprocessor used only by Top Gear 3000
|
||||
|
||||
ST011
|
||||
SETA DSP used only by Quick-move Shogi Match with Nidan Rank-holder Morita
|
||||
|
||||
ST018
|
||||
SETA RISC CPU used only by Quick-move Shogi Match with Nidan Rank-holder Morita 2
|
||||
|
||||
BS-X (Broadcast Satellite)
|
||||
Add-on unit sold only in Japan that played specially-made games that were
|
||||
downloaded via satellite
|
||||
|
||||
BS-X Flashcart
|
||||
Flash cartridge used by BS-X, as well as some standalone games by Asciisoft
|
||||
|
||||
Super Gameboy
|
||||
Cartridge passthrough used for playing Gameboy games
|
||||
|
||||
------------------------
|
||||
Unsupported Controllers:
|
||||
------------------------
|
||||
Mouse
|
||||
Super Scope
|
||||
Justifier
|
||||
Multitap (4-port and 5-port)
|
||||
+312
@@ -0,0 +1,312 @@
|
||||
######################
|
||||
### bsnes makefile ###
|
||||
######################
|
||||
|
||||
ifeq ($(PLATFORM),)
|
||||
_null_: help
|
||||
endif
|
||||
|
||||
##################################
|
||||
### platform-specific settings ###
|
||||
##################################
|
||||
|
||||
ifeq ($(PLATFORM),x-gcc-lui)
|
||||
OS = unix
|
||||
CC = gcc
|
||||
CFLAGS = -O3 -fomit-frame-pointer -DPLATFORM_X -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_LUI `pkg-config --cflags gtk+-2.0`
|
||||
AS = nasm
|
||||
ASFLAGS = -f elf
|
||||
LIBS = `pkg-config --libs gtk+-2.0` -lXv -lao
|
||||
LIBCO = libco_x86
|
||||
LIBUI = libui_gtk
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),x-gcc-lui-x64)
|
||||
OS = unix
|
||||
CC = gcc
|
||||
CFLAGS = -O3 -fomit-frame-pointer -DPLATFORM_X -DCOMPILER_GCC -DPROCESSOR_X86_64 -DUI_LUI `pkg-config --cflags gtk+-2.0`
|
||||
AS = yasm
|
||||
ASFLAGS = -f elf64
|
||||
LIBS = `pkg-config --libs gtk+-2.0` -lXv -lao
|
||||
LIBCO = libco_x86_64
|
||||
LIBUI = libui_gtk
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),win-visualc-lui)
|
||||
OS = win
|
||||
CC = cl
|
||||
CFLAGS = /nologo /wd4996 /O2 /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_LUI
|
||||
AS = nasm
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib kernel32.lib user32.lib gdi32.lib shell32.lib winmm.lib comdlg32.lib comctl32.lib
|
||||
LIBCO = libco_x86
|
||||
LIBUI = libui_win
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),win-visualc-lui-pgi)
|
||||
OS = win
|
||||
CC = cl
|
||||
CFLAGS = /nologo /wd4996 /O2 /GL /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_LUI
|
||||
AS = nasm
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib kernel32.lib user32.lib gdi32.lib shell32.lib winmm.lib comdlg32.lib comctl32.lib
|
||||
LINK = /link /PGD:bsnes.pgd /LTCG:PGINSTRUMENT
|
||||
LIBCO = libco_x86
|
||||
LIBUI = libui_win
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),win-visualc-lui-pgo)
|
||||
OS = win
|
||||
CC = cl
|
||||
CFLAGS = /nologo /wd4996 /O2 /GL /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_LUI
|
||||
AS = nasm
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib kernel32.lib user32.lib gdi32.lib shell32.lib winmm.lib comdlg32.lib comctl32.lib
|
||||
LINK = /link /PGD:bsnes.pgd /LTCG:PGOPTIMIZE
|
||||
LIBCO = libco_x86
|
||||
LIBUI = libui_win
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),win-mingw-lui)
|
||||
OS = win
|
||||
CC = mingw32-gcc
|
||||
CFLAGS = -mwindows -O3 -fomit-frame-pointer -DPLATFORM_WIN -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_LUI
|
||||
AS = nasm
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = -ld3d9 -lddraw -ldsound -ldinput8 -ldxguid -luuid -lkernel32 -luser32 -lgdi32 -lshell32 -lwinmm -lcomdlg32 -lcomctl32
|
||||
LIBCO = libco_x86
|
||||
LIBUI = libui_win
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),win-mingw4-lui)
|
||||
OS = win
|
||||
CC = mingw32-gcc-sjlj
|
||||
CFLAGS = -mwindows -O3 -fomit-frame-pointer -DPLATFORM_WIN -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_LUI
|
||||
AS = nasm
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = -ld3d9 -lddraw -ldsound -ldinput8 -ldxguid -luuid -lkernel32 -luser32 -lgdi32 -lshell32 -lwinmm -lcomdlg32 -lcomctl32
|
||||
LIBCO = libco_x86
|
||||
LIBUI = libui_win
|
||||
endif
|
||||
|
||||
#####################################
|
||||
### compiler / assembler switches ###
|
||||
#####################################
|
||||
|
||||
ifeq ($(CC),gcc)
|
||||
OUT = -obsnes
|
||||
CPP = g++
|
||||
OBJ = o
|
||||
CARGS = -c $< -o $@
|
||||
DEFINE = -D
|
||||
endif
|
||||
|
||||
ifeq ($(CC),mingw32-gcc)
|
||||
OUT = -obsnes
|
||||
CPP = mingw32-g++
|
||||
OBJ = o
|
||||
CARGS = -c $< -o $@
|
||||
DEFINE = -D
|
||||
endif
|
||||
|
||||
ifeq ($(CC),mingw32-gcc-sjlj)
|
||||
OUT = -obsnes
|
||||
CPP = mingw32-g++-sjlj
|
||||
OBJ = o
|
||||
CARGS = -c $< -o $@
|
||||
DEFINE = -D
|
||||
endif
|
||||
|
||||
ifeq ($(CC),cl)
|
||||
OUT = /Febsnes
|
||||
CPP = cl
|
||||
OBJ = obj
|
||||
CARGS = /c $< /Fo$@
|
||||
DEFINE = /D
|
||||
endif
|
||||
|
||||
ifeq ($(AS),nasm)
|
||||
ASARGS = $< -o $@
|
||||
endif
|
||||
|
||||
ifeq ($(AS),yasm)
|
||||
ASARGS = $< -o $@
|
||||
endif
|
||||
|
||||
###################
|
||||
### OS switches ###
|
||||
###################
|
||||
|
||||
ifeq ($(OS),unix)
|
||||
RM = rm -f
|
||||
endif
|
||||
|
||||
ifeq ($(OS),win)
|
||||
OUT := $(OUT).exe
|
||||
RM = del
|
||||
endif
|
||||
|
||||
####################################
|
||||
### main target and dependencies ###
|
||||
####################################
|
||||
|
||||
OBJECTS = main.$(OBJ) $(LIBCO).$(OBJ) $(LIBUI).$(OBJ) \
|
||||
libstring.$(OBJ) \
|
||||
reader.$(OBJ) cart.$(OBJ) cheat.$(OBJ) memory.$(OBJ) bmemory.$(OBJ) \
|
||||
cpu.$(OBJ) scpu.$(OBJ) smp.$(OBJ) ssmp.$(OBJ) bdsp.$(OBJ) ppu.$(OBJ) \
|
||||
bppu.$(OBJ) snes.$(OBJ) srtc.$(OBJ) sdd1.$(OBJ) c4.$(OBJ) dsp1.$(OBJ) \
|
||||
dsp2.$(OBJ) obc1.$(OBJ) st010.$(OBJ)
|
||||
|
||||
ifeq ($(GZIP_SUPPORT),true)
|
||||
OBJECTS += adler32.$(OBJ) compress.$(OBJ) crc32.$(OBJ) deflate.$(OBJ) \
|
||||
gzio.$(OBJ) inffast.$(OBJ) inflate.$(OBJ) inftrees.$(OBJ) ioapi.$(OBJ) \
|
||||
trees.$(OBJ) unzip.$(OBJ) zip.$(OBJ) zutil.$(OBJ)
|
||||
CFLAGS += $(DEFINE)GZIP_SUPPORT
|
||||
endif
|
||||
|
||||
ifeq ($(JMA_SUPPORT),true)
|
||||
OBJECTS += jma.$(OBJ) jcrc32.$(OBJ) lzmadec.$(OBJ) 7zlzma.$(OBJ) \
|
||||
iiostrm.$(OBJ) inbyte.$(OBJ) lzma.$(OBJ) winout.$(OBJ)
|
||||
CFLAGS += $(DEFINE)JMA_SUPPORT
|
||||
endif
|
||||
|
||||
ifeq ($(OS),win)
|
||||
ifeq ($(CC),cl)
|
||||
OBJECTS += bsnes.res
|
||||
endif
|
||||
endif
|
||||
|
||||
all: $(OBJECTS)
|
||||
$(CPP) $(OUT) $(CFLAGS) $(OBJECTS) $(LIBS) $(LINK)
|
||||
# mt -nologo -manifest bsnes.exe.manifest -outputresource:bsnes.exe;1
|
||||
|
||||
######################
|
||||
### implicit rules ###
|
||||
######################
|
||||
|
||||
%.$(OBJ): $<
|
||||
$(if $(filter %.asm,$<),$(AS) $(ASFLAGS) $(ASARGS))
|
||||
$(if $(filter %.c,$<),$(CC) $(CFLAGS) $(CARGS))
|
||||
$(if $(filter %.cpp,$<),$(CPP) $(CFLAGS) $(CARGS))
|
||||
|
||||
#########################
|
||||
### platform-specific ###
|
||||
#########################
|
||||
main.$(OBJ): ui/main.cpp config/* ui/* ui/video/* ui/audio/* ui/input/* \
|
||||
ui/lui/* ui/lui/settings/* \
|
||||
ui/win/* ui/win/settings/* ui/win/debugger/*
|
||||
bsnes.res : ui/bsnes.rc ; rc /r /fobsnes.res ui/bsnes.rc
|
||||
|
||||
#############
|
||||
### libco ###
|
||||
#############
|
||||
libco_x86.$(OBJ) : lib/libco_x86.asm lib/*
|
||||
libco_x86_64.$(OBJ): lib/libco_x86_64.asm lib/*
|
||||
|
||||
#############
|
||||
### libui ###
|
||||
#############
|
||||
libui_gtk.$(OBJ): lib/libui_gtk.cpp lib/*
|
||||
libui_win.$(OBJ): lib/libui_win.cpp lib/*
|
||||
|
||||
#################
|
||||
### libraries ###
|
||||
#################
|
||||
libstring.$(OBJ): lib/libstring.cpp lib/*
|
||||
|
||||
#################
|
||||
### utilities ###
|
||||
#################
|
||||
reader.$(OBJ): reader/reader.cpp reader/*
|
||||
cart.$(OBJ) : cart/cart.cpp cart/*
|
||||
cheat.$(OBJ) : cheat/cheat.cpp cheat/*
|
||||
|
||||
##############
|
||||
### memory ###
|
||||
##############
|
||||
memory.$(OBJ) : memory/memory.cpp memory/*
|
||||
bmemory.$(OBJ): memory/bmemory/bmemory.cpp memory/bmemory/* memory/bmemory/mapper/*
|
||||
|
||||
###########
|
||||
### cpu ###
|
||||
###########
|
||||
cpu.$(OBJ) : cpu/cpu.cpp cpu/*
|
||||
scpu.$(OBJ): cpu/scpu/scpu.cpp cpu/scpu/* cpu/scpu/core/* cpu/scpu/dma/* cpu/scpu/memory/* cpu/scpu/mmio/* cpu/scpu/timing/*
|
||||
|
||||
###########
|
||||
### smp ###
|
||||
###########
|
||||
smp.$(OBJ) : smp/smp.cpp smp/*
|
||||
ssmp.$(OBJ): smp/ssmp/ssmp.cpp smp/ssmp/* smp/ssmp/core/* smp/ssmp/memory/* smp/ssmp/timing/*
|
||||
|
||||
###########
|
||||
### dsp ###
|
||||
###########
|
||||
adsp.$(OBJ): dsp/adsp/adsp.cpp dsp/adsp/*
|
||||
bdsp.$(OBJ): dsp/bdsp/bdsp.cpp dsp/bdsp/*
|
||||
|
||||
###########
|
||||
### ppu ###
|
||||
###########
|
||||
ppu.$(OBJ) : ppu/ppu.cpp ppu/*
|
||||
bppu.$(OBJ): ppu/bppu/bppu.cpp ppu/bppu/*
|
||||
|
||||
############
|
||||
### snes ###
|
||||
############
|
||||
snes.$(OBJ): snes/snes.cpp snes/* snes/scheduler/* snes/video/* snes/audio/* snes/input/*
|
||||
|
||||
#####################
|
||||
### special chips ###
|
||||
#####################
|
||||
srtc.$(OBJ) : chip/srtc/srtc.cpp chip/srtc/*
|
||||
sdd1.$(OBJ) : chip/sdd1/sdd1.cpp chip/sdd1/*
|
||||
c4.$(OBJ) : chip/c4/c4.cpp chip/c4/*
|
||||
dsp1.$(OBJ) : chip/dsp1/dsp1.cpp chip/dsp1/*
|
||||
dsp2.$(OBJ) : chip/dsp2/dsp2.cpp chip/dsp2/*
|
||||
obc1.$(OBJ) : chip/obc1/obc1.cpp chip/obc1/*
|
||||
st010.$(OBJ): chip/st010/st010.cpp chip/st010/*
|
||||
|
||||
############
|
||||
### zlib ###
|
||||
############
|
||||
adler32.$(OBJ) : reader/zlib/adler32.c reader/zlib/*
|
||||
compress.$(OBJ): reader/zlib/compress.c reader/zlib/*
|
||||
crc32.$(OBJ) : reader/zlib/crc32.c reader/zlib/*
|
||||
deflate.$(OBJ) : reader/zlib/deflate.c reader/zlib/*
|
||||
gzio.$(OBJ) : reader/zlib/gzio.c reader/zlib/*
|
||||
inffast.$(OBJ) : reader/zlib/inffast.c reader/zlib/*
|
||||
inflate.$(OBJ) : reader/zlib/inflate.c reader/zlib/*
|
||||
inftrees.$(OBJ): reader/zlib/inftrees.c reader/zlib/*
|
||||
ioapi.$(OBJ) : reader/zlib/ioapi.c reader/zlib/*
|
||||
trees.$(OBJ) : reader/zlib/trees.c reader/zlib/*
|
||||
unzip.$(OBJ) : reader/zlib/unzip.c reader/zlib/*
|
||||
zip.$(OBJ) : reader/zlib/zip.c reader/zlib/*
|
||||
zutil.$(OBJ) : reader/zlib/zutil.c reader/zlib/*
|
||||
|
||||
###########
|
||||
### jma ###
|
||||
###########
|
||||
jma.$(OBJ) : reader/jma/jma.cpp reader/jma/*
|
||||
jcrc32.$(OBJ) : reader/jma/jcrc32.cpp reader/jma/*
|
||||
lzmadec.$(OBJ): reader/jma/lzmadec.cpp reader/jma/*
|
||||
7zlzma.$(OBJ) : reader/jma/7zlzma.cpp reader/jma/*
|
||||
iiostrm.$(OBJ): reader/jma/iiostrm.cpp reader/jma/*
|
||||
inbyte.$(OBJ) : reader/jma/inbyte.cpp reader/jma/*
|
||||
lzma.$(OBJ) : reader/jma/lzma.cpp reader/jma/*
|
||||
winout.$(OBJ) : reader/jma/winout.cpp reader/jma/*
|
||||
|
||||
####################
|
||||
### misc targets ###
|
||||
####################
|
||||
clean:
|
||||
-@$(RM) *.$(OBJ)
|
||||
-@$(RM) *.res
|
||||
-@$(RM) *.pgd
|
||||
-@$(RM) *.pgc
|
||||
-@$(RM) *.ilk
|
||||
-@$(RM) *.pdb
|
||||
-@$(RM) *.manifest
|
||||
|
||||
help:
|
||||
@echo Please specify which platform to compile for with PLATFORM=platform_name
|
||||
+52
-9
@@ -1,16 +1,59 @@
|
||||
#define BSNES_VERSION "0.024"
|
||||
#define BSNES_TITLE "bsnes v" BSNES_VERSION
|
||||
|
||||
#define MEMCORE bMemBus
|
||||
#define CPUCORE sCPU
|
||||
#define SMPCORE sSMP
|
||||
#define DSPCORE bDSP
|
||||
#define PPUCORE bPPU
|
||||
|
||||
//#define FAVOR_ACCURACY
|
||||
#define FAVOR_SPEED
|
||||
|
||||
//game genie + pro action replay code support (~1-3% speed hit)
|
||||
#define CHEAT_SYSTEM
|
||||
|
||||
//snes core polymorphism
|
||||
//(allow runtime cpu/smp/dsp/ppu/bus selection, ~10% speed hit)
|
||||
//#define POLYMORPHISM
|
||||
|
||||
#include "lib/libbase.h"
|
||||
|
||||
//structs
|
||||
typedef struct {
|
||||
uint8 *data;
|
||||
uint32 size;
|
||||
}lfile;
|
||||
#if defined(PROCESSOR_X86)
|
||||
#define ARCH_LSB
|
||||
#include "lib/libco_x86.h"
|
||||
#elif defined(PROCESSOR_X86_64)
|
||||
#define ARCH_LSB
|
||||
#include "lib/libco_x86_64.h"
|
||||
#elif defined(PROCESSOR_G5)
|
||||
#define ARCH_MSB
|
||||
#else
|
||||
#error "unsupported processor"
|
||||
#endif
|
||||
|
||||
#include "lib/libfunctor.h"
|
||||
#include "lib/libsort.h"
|
||||
#include "lib/libarray.h"
|
||||
#include "lib/libvector.h"
|
||||
#include "lib/libstring.h"
|
||||
#include "lib/libconfig.h"
|
||||
|
||||
//platform-specific global functions
|
||||
void *memalloc(uint32 size, char *name = 0, ...);
|
||||
void memfree(void *mem, char *name = 0, ...);
|
||||
void alert(char *s, ...);
|
||||
void dprintf(char *s, ...);
|
||||
void alert(const char*, ...);
|
||||
void dprintf(const char*, ...);
|
||||
void dprintf(uint, const char*, ...);
|
||||
|
||||
namespace source {
|
||||
enum {
|
||||
none = 0,
|
||||
debug,
|
||||
cpu,
|
||||
ppu,
|
||||
smp,
|
||||
dsp,
|
||||
bus,
|
||||
};
|
||||
};
|
||||
|
||||
//various class interfaces
|
||||
#include "interface.h"
|
||||
Binary file not shown.
@@ -0,0 +1,157 @@
|
||||
#include "../base.h"
|
||||
#include "database.cpp"
|
||||
|
||||
#include "cart_normal.cpp"
|
||||
#include "cart_st.cpp"
|
||||
#include "cart_stdual.cpp"
|
||||
|
||||
#include "cart_file.cpp"
|
||||
#include "cart_header.cpp"
|
||||
|
||||
Cartridge cartridge;
|
||||
|
||||
void Cartridge::load_begin(uint cart_type) {
|
||||
if(loaded() == true)return;
|
||||
|
||||
info.type = cart_type;
|
||||
|
||||
info.srtc = false;
|
||||
info.sdd1 = false;
|
||||
info.c4 = false;
|
||||
info.dsp1 = false;
|
||||
info.dsp2 = false;
|
||||
info.obc1 = false;
|
||||
info.st010 = false;
|
||||
|
||||
info.dsp1_mapper = 0;
|
||||
|
||||
info.header_index = 0xffc0;
|
||||
info.mapper = PCB;
|
||||
strcpy(info.name, "");
|
||||
strcpy(info.pcb, "");
|
||||
info.region = NTSC;
|
||||
info.cart_mmio = false;
|
||||
|
||||
info.rom_size = 0;
|
||||
info.ram_size = 0;
|
||||
|
||||
file.count = 0;
|
||||
for(int i = 0; i < 8; i++) {
|
||||
strcpy(file.rom_name[i], "");
|
||||
strcpy(file.ram_name[i], "");
|
||||
file.rom_size[i] = 0;
|
||||
file.ram_size[i] = 0;
|
||||
file.rom_data[i] = 0;
|
||||
file.ram_data[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::load(const char *rom_fn) {
|
||||
if(!rom_fn || !*rom_fn)return;
|
||||
|
||||
char fn[4096], ram_fn[4096];
|
||||
strcpy(fn, rom_fn);
|
||||
//correct folder slashes
|
||||
for(int i = strlen(fn) - 1; i >= 0; i--) {
|
||||
if(fn[i] == '\\')fn[i] = '/';
|
||||
}
|
||||
|
||||
uint i = file.count++;
|
||||
strcpy(file.rom_name[i], fn);
|
||||
|
||||
strcpy(fn, rom_fn);
|
||||
//remove ROM extension
|
||||
for(int i = strlen(fn) - 1; i >= 0; i--) {
|
||||
if(fn[i] == '.') {
|
||||
fn[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(i == 0) {
|
||||
strcpy(file.patch_name, fn);
|
||||
strcat(file.patch_name, ".ups");
|
||||
}
|
||||
strcpy(fn, strptr(config::file_updatepath(fn, config::path.save)));
|
||||
if(i == 0) {
|
||||
strcpy(file.cheat_name, fn);
|
||||
strcat(file.cheat_name, ".cht");
|
||||
}
|
||||
strcpy(file.ram_name[i], fn);
|
||||
strcat(file.ram_name[i], ".");
|
||||
strcat(file.ram_name[i], config::path.save_ext);
|
||||
}
|
||||
|
||||
bool Cartridge::load_end() {
|
||||
for(int i = 0; i < file.count; i++) {
|
||||
load_file(file.rom_name[i], file.rom_data[i], file.rom_size[i]);
|
||||
}
|
||||
|
||||
if(fexists(file.cheat_name) == true) {
|
||||
cheat.clear();
|
||||
cheat.load(file.cheat_name);
|
||||
}
|
||||
|
||||
switch(info.type) {
|
||||
case CART_NORMAL: {
|
||||
load_rom_normal();
|
||||
load_ram_normal();
|
||||
} break;
|
||||
case CART_ST: {
|
||||
load_rom_st();
|
||||
load_ram_st();
|
||||
} break;
|
||||
case CART_STDUAL: {
|
||||
load_rom_stdual();
|
||||
load_ram_stdual();
|
||||
} break;
|
||||
}
|
||||
|
||||
cart_loaded = true;
|
||||
r_mem->load_cart();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cartridge::unload() {
|
||||
if(cart_loaded == false)return false;
|
||||
|
||||
r_mem->unload_cart();
|
||||
|
||||
switch(info.type) {
|
||||
case CART_NORMAL: {
|
||||
save_ram_normal();
|
||||
} break;
|
||||
case CART_ST: {
|
||||
save_ram_st();
|
||||
} break;
|
||||
case CART_STDUAL: {
|
||||
save_ram_stdual();
|
||||
} break;
|
||||
}
|
||||
|
||||
safe_free(rom);
|
||||
safe_free(ram);
|
||||
|
||||
if(cheat.count() > 0 || fexists(file.cheat_name) == true) {
|
||||
cheat.save(file.cheat_name);
|
||||
cheat.clear();
|
||||
}
|
||||
|
||||
cart_loaded = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Cartridge::Cartridge() {
|
||||
load_database();
|
||||
|
||||
cart_loaded = false;
|
||||
|
||||
rom = 0;
|
||||
ram = 0;
|
||||
}
|
||||
|
||||
Cartridge::~Cartridge() {
|
||||
if(cart_loaded == true) {
|
||||
unload();
|
||||
}
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
class Cartridge {
|
||||
public:
|
||||
|
||||
/*****
|
||||
* cart database
|
||||
*****/
|
||||
|
||||
#include "db/db.h"
|
||||
db_item dbi;
|
||||
uint8 *database;
|
||||
uint database_size;
|
||||
uint database_blocksize;
|
||||
void load_database();
|
||||
bool read_database();
|
||||
|
||||
//
|
||||
|
||||
enum {
|
||||
CART_NORMAL,
|
||||
CART_ST,
|
||||
CART_STDUAL,
|
||||
};
|
||||
|
||||
bool cart_loaded;
|
||||
|
||||
uint8 rom_header[512], *rom, *ram;
|
||||
|
||||
enum {
|
||||
//header fields
|
||||
CART_NAME = 0x00,
|
||||
MAPPER = 0x15,
|
||||
ROM_TYPE = 0x16,
|
||||
ROM_SIZE = 0x17,
|
||||
RAM_SIZE = 0x18,
|
||||
REGION = 0x19,
|
||||
LICENSE = 0x1a,
|
||||
VERSION = 0x1b,
|
||||
ICKSUM = 0x1c,
|
||||
CKSUM = 0x1e,
|
||||
RESL = 0x3c,
|
||||
RESH = 0x3d,
|
||||
|
||||
//regions
|
||||
NTSC = 0,
|
||||
PAL = 1,
|
||||
|
||||
//memory mappers
|
||||
PCB = 0x00,
|
||||
LOROM = 0x20,
|
||||
HIROM = 0x21,
|
||||
EXLOROM = 0x22,
|
||||
EXHIROM = 0x25,
|
||||
|
||||
//special chip memory mappers
|
||||
DSP1_LOROM_1MB = 1,
|
||||
DSP1_LOROM_2MB = 2,
|
||||
DSP1_HIROM = 3,
|
||||
};
|
||||
|
||||
struct {
|
||||
uint count;
|
||||
char cheat_name[4096], patch_name[4096];
|
||||
char rom_name[8][4096], ram_name[8][4096];
|
||||
uint rom_size[8], ram_size[8];
|
||||
uint8 *rom_data[8], *ram_data[8];
|
||||
} file;
|
||||
|
||||
struct {
|
||||
uint type;
|
||||
|
||||
//cart information
|
||||
uint32 crc32;
|
||||
char name[128];
|
||||
char pcb[32];
|
||||
|
||||
uint region;
|
||||
uint mapper;
|
||||
uint rom_size;
|
||||
uint ram_size;
|
||||
|
||||
//set to true for games that need cart MMIO mapping (c4, dsp-n, ...),
|
||||
//for games that map outside the standard MMIO range of $2000-$5fff
|
||||
bool cart_mmio;
|
||||
bool srtc;
|
||||
bool sdd1;
|
||||
bool c4;
|
||||
bool dsp1;
|
||||
bool dsp2;
|
||||
bool obc1;
|
||||
bool st010;
|
||||
|
||||
uint dsp1_mapper;
|
||||
|
||||
//HiROM / LoROM specific code
|
||||
uint header_index;
|
||||
} info;
|
||||
|
||||
bool load_file(const char *fn, uint8 *&data, uint &size);
|
||||
bool save_file(const char *fn, uint8 *data, uint size);
|
||||
|
||||
void load_rom_normal();
|
||||
void load_ram_normal();
|
||||
void save_ram_normal();
|
||||
|
||||
void load_rom_st();
|
||||
void load_ram_st();
|
||||
void save_ram_st();
|
||||
|
||||
void load_rom_stdual();
|
||||
void load_ram_stdual();
|
||||
void save_ram_stdual();
|
||||
|
||||
void find_header();
|
||||
void read_header();
|
||||
|
||||
bool loaded() { return cart_loaded; }
|
||||
void load_begin(uint cart_type);
|
||||
void load(const char *rom_fn);
|
||||
bool load_end();
|
||||
bool unload();
|
||||
|
||||
Cartridge();
|
||||
~Cartridge();
|
||||
};
|
||||
|
||||
extern Cartridge cartridge;
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "../reader/filereader.h"
|
||||
|
||||
#if defined(GZIP_SUPPORT)
|
||||
#include "../reader/gzreader.h"
|
||||
#include "../reader/zipreader.h"
|
||||
#endif
|
||||
|
||||
#if defined(JMA_SUPPORT)
|
||||
#include "../reader/jmareader.h"
|
||||
#endif
|
||||
|
||||
bool Cartridge::load_file(const char *fn, uint8 *&data, uint &size) {
|
||||
dprintf("* Loading \"%s\"...", fn);
|
||||
|
||||
if(fexists(fn) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(Reader::detect(fn)) {
|
||||
|
||||
case Reader::RF_NORMAL: {
|
||||
FileReader ff(fn);
|
||||
if(!ff.ready()) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
size = ff.size();
|
||||
data = ff.read();
|
||||
} break;
|
||||
|
||||
#ifdef GZIP_SUPPORT
|
||||
case Reader::RF_GZ: {
|
||||
GZReader gf(fn);
|
||||
if(!gf.ready()) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
size = gf.size();
|
||||
data = gf.read();
|
||||
} break;
|
||||
|
||||
case Reader::RF_ZIP: {
|
||||
ZipReader zf(fn);
|
||||
size = zf.size();
|
||||
data = zf.read();
|
||||
} break;
|
||||
#endif
|
||||
|
||||
#ifdef JMA_SUPPORT
|
||||
case Reader::RF_JMA: {
|
||||
try {
|
||||
JMAReader jf(fn);
|
||||
size = jf.size();
|
||||
data = jf.read();
|
||||
} catch(JMA::jma_errors jma_error) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
} break;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cartridge::save_file(const char *fn, uint8 *data, uint size) {
|
||||
FileWriter ff(fn);
|
||||
if(!ff.ready())return false;
|
||||
ff.write(data, size);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
void Cartridge::read_header() {
|
||||
info.srtc = false;
|
||||
info.sdd1 = false;
|
||||
info.c4 = false;
|
||||
info.dsp1 = false;
|
||||
info.dsp2 = false;
|
||||
info.obc1 = false;
|
||||
|
||||
info.dsp1_mapper = 0;
|
||||
|
||||
if(info.header_index == 0x7fc0 && info.rom_size >= 0x401000) {
|
||||
info.mapper = EXLOROM;
|
||||
strcpy(info.pcb, "UNL-EXLOROM");
|
||||
} else if(info.header_index == 0x7fc0 && rom[info.header_index + MAPPER] == 0x32) {
|
||||
info.mapper = EXLOROM;
|
||||
strcpy(info.pcb, "UNL-EXLOROM");
|
||||
} else if(info.header_index == 0x7fc0) {
|
||||
info.mapper = LOROM;
|
||||
strcpy(info.pcb, "UNL-LOROM");
|
||||
} else if(info.header_index == 0xffc0) {
|
||||
info.mapper = HIROM;
|
||||
strcpy(info.pcb, "UNL-HIROM");
|
||||
} else { //info.header_index == 0x40ffc0
|
||||
info.mapper = EXHIROM;
|
||||
strcpy(info.pcb, "UNL-EXHIROM");
|
||||
}
|
||||
|
||||
uint8 mapper = rom[info.header_index + MAPPER];
|
||||
uint8 rom_type = rom[info.header_index + ROM_TYPE];
|
||||
if(mapper == 0x35 && rom_type == 0x55) {
|
||||
info.srtc = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x32 && (rom_type == 0x43 || rom_type == 0x45)) {
|
||||
info.sdd1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x20 && rom_type == 0xf3) {
|
||||
info.c4 = true;
|
||||
}
|
||||
|
||||
if((mapper == 0x20 || mapper == 0x21) && rom_type == 0x03) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x05) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x31 && (rom_type == 0x03 || rom_type == 0x05)) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(info.dsp1 == true) {
|
||||
if((mapper & 0x2f) == 0x20 && info.rom_size <= 0x100000) {
|
||||
info.dsp1_mapper = DSP1_LOROM_1MB;
|
||||
} else if((mapper & 0x2f) == 0x20) {
|
||||
info.dsp1_mapper = DSP1_LOROM_2MB;
|
||||
} else if((mapper & 0x2f) == 0x21) {
|
||||
info.dsp1_mapper = DSP1_HIROM;
|
||||
}
|
||||
}
|
||||
|
||||
if(mapper == 0x20 && rom_type == 0x05) {
|
||||
info.dsp2 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x25) {
|
||||
info.obc1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0xf6) {
|
||||
info.st010 = true;
|
||||
}
|
||||
|
||||
info.cart_mmio = info.c4 | info.dsp1 | info.dsp2 | info.obc1;
|
||||
|
||||
if(rom[info.header_index + RAM_SIZE] & 7) {
|
||||
info.ram_size = 1024 << (rom[info.header_index + RAM_SIZE] & 7);
|
||||
} else {
|
||||
info.ram_size = 0;
|
||||
}
|
||||
|
||||
memcpy(&info.name, &rom[info.header_index + CART_NAME], 21);
|
||||
info.name[21] = 0;
|
||||
|
||||
for(int i = 0; i < 22; i++) {
|
||||
if(info.name[i] & 0x80) {
|
||||
info.name[i] = '?';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::find_header() {
|
||||
int32 score_lo = 0,
|
||||
score_hi = 0,
|
||||
score_ex = 0;
|
||||
|
||||
if(info.rom_size < 0x010000) {
|
||||
//cart too small to be anything but lorom
|
||||
info.header_index = 0x007fc0;
|
||||
return;
|
||||
}
|
||||
|
||||
if((rom[0x7fc0 + MAPPER] & ~0x10) == 0x20)score_lo++;
|
||||
if((rom[0xffc0 + MAPPER] & ~0x10) == 0x21)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + ROM_TYPE] < 0x08)score_lo++;
|
||||
if(rom[0xffc0 + ROM_TYPE] < 0x08)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + ROM_SIZE] < 0x10)score_lo++;
|
||||
if(rom[0xffc0 + ROM_SIZE] < 0x10)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + RAM_SIZE] < 0x08)score_lo++;
|
||||
if(rom[0xffc0 + RAM_SIZE] < 0x08)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + REGION] < 14)score_lo++;
|
||||
if(rom[0xffc0 + REGION] < 14)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + LICENSE] < 3)score_lo++;
|
||||
if(rom[0xffc0 + LICENSE] < 3)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + RESH] & 0x80)score_lo += 2;
|
||||
if(rom[0xffc0 + RESH] & 0x80)score_hi += 2;
|
||||
|
||||
uint16 cksum, icksum;
|
||||
cksum = rom[0x7fc0 + CKSUM] | (rom[0x7fc0 + CKSUM + 1] << 8);
|
||||
icksum = rom[0x7fc0 + ICKSUM] | (rom[0x7fc0 + ICKSUM + 1] << 8);
|
||||
if((cksum + icksum) == 0xffff && (cksum != 0) && (icksum != 0)) {
|
||||
score_lo += 8;
|
||||
}
|
||||
|
||||
cksum = rom[0xffc0 + CKSUM] | (rom[0xffc0 + CKSUM + 1] << 8);
|
||||
icksum = rom[0xffc0 + ICKSUM] | (rom[0xffc0 + ICKSUM + 1] << 8);
|
||||
if((cksum + icksum) == 0xffff && (cksum != 0) && (icksum != 0)) {
|
||||
score_hi += 8;
|
||||
}
|
||||
|
||||
if(info.rom_size < 0x401000) {
|
||||
score_ex = 0;
|
||||
} else {
|
||||
if(rom[0x7fc0 + MAPPER] == 0x32)score_lo++;
|
||||
else score_ex += 16;
|
||||
}
|
||||
|
||||
if(score_lo >= score_hi && score_lo >= score_ex) {
|
||||
info.header_index = 0x007fc0;
|
||||
} else if(score_hi >= score_ex) {
|
||||
info.header_index = 0x00ffc0;
|
||||
} else {
|
||||
info.header_index = 0x40ffc0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
void Cartridge::load_rom_normal() {
|
||||
uint size = 0;
|
||||
for(int i = 0; i < file.count; i++) {
|
||||
size += file.rom_size[i] - (((file.rom_size[i] & 0x7fff) == 512) ? 512 : 0);
|
||||
}
|
||||
|
||||
info.rom_size = size;
|
||||
rom = (uint8*)malloc(info.rom_size);
|
||||
memset(rom, 0, info.rom_size);
|
||||
|
||||
uint offset = 0;
|
||||
for(int i = 0; i < file.count; i++) {
|
||||
uint8 *data = file.rom_data[i] + (((file.rom_size[i] & 0x7fff) == 512) ? 512 : 0);
|
||||
uint size = file.rom_size[i] - (((file.rom_size[i] & 0x7fff) == 512) ? 512 : 0);
|
||||
memcpy(rom + offset, data, size);
|
||||
offset += size;
|
||||
safe_free(file.rom_data[i]);
|
||||
}
|
||||
|
||||
info.crc32 = crc32_calculate(rom, info.rom_size);
|
||||
|
||||
if(read_database() == true) {
|
||||
info.srtc = false;
|
||||
info.sdd1 = false;
|
||||
info.c4 = false;
|
||||
info.dsp1 = false;
|
||||
info.dsp2 = false;
|
||||
info.obc1 = false;
|
||||
|
||||
info.dsp1_mapper = 0;
|
||||
|
||||
info.header_index = 0xffc0;
|
||||
info.mapper = PCB;
|
||||
strcpy(info.name, dbi.name);
|
||||
strcpy(info.pcb, dbi.pcb);
|
||||
info.region = NTSC;
|
||||
info.cart_mmio = false;
|
||||
|
||||
info.rom_size = dbi.rom;
|
||||
info.ram_size = dbi.ram;
|
||||
} else {
|
||||
find_header();
|
||||
read_header();
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::load_ram_normal() {
|
||||
if(info.ram_size == 0) {
|
||||
ram = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
ram = (uint8*)malloc(info.ram_size);
|
||||
memset(ram, 0xff, info.ram_size);
|
||||
|
||||
if(load_file(file.ram_name[0], file.ram_data[0], file.ram_size[0]) == true) {
|
||||
memcpy(ram, file.ram_data[0], min(info.ram_size, file.ram_size[0]));
|
||||
safe_free(file.ram_data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::save_ram_normal() {
|
||||
if(info.ram_size == 0)return;
|
||||
|
||||
save_file(file.ram_name[0], ram, info.ram_size);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
void Cartridge::load_rom_st() {
|
||||
uint8 *data;
|
||||
uint size;
|
||||
string bios = config::file_updatepath("stbios.bin", config::path.bios);
|
||||
info.rom_size = 0x200000;
|
||||
rom = (uint8*)malloc(info.rom_size);
|
||||
memset(rom, 0, info.rom_size);
|
||||
|
||||
load_file(strptr(bios), data, size);
|
||||
memcpy(rom, data, min(size, 0x040000));
|
||||
safe_free(data);
|
||||
|
||||
memcpy(rom + 0x100000, file.rom_data[0], min(file.rom_size[0], 0x100000));
|
||||
safe_free(file.rom_data[0]);
|
||||
|
||||
//
|
||||
strcpy(info.name, "???");
|
||||
strcpy(info.pcb, "STC-SOLO");
|
||||
|
||||
info.mapper = PCB;
|
||||
info.region = NTSC;
|
||||
|
||||
info.rom_size = 0x200000;
|
||||
info.ram_size = 0x020000;
|
||||
//
|
||||
|
||||
info.crc32 = crc32_calculate(rom + 0x100000, file.rom_size[0]);
|
||||
if(read_database() == true) {
|
||||
strcpy(info.name, dbi.name);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::load_ram_st() {
|
||||
ram = (uint8*)malloc(info.ram_size);
|
||||
memset(ram, 0xff, info.ram_size);
|
||||
|
||||
if(load_file(file.ram_name[0], file.ram_data[0], file.ram_size[0]) == true) {
|
||||
memcpy(ram, file.ram_data[0], min(file.ram_size[0], 0x020000));
|
||||
safe_free(file.ram_data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::save_ram_st() {
|
||||
save_file(file.ram_name[0], ram, 0x020000);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
void Cartridge::load_rom_stdual() {
|
||||
uint8 *data;
|
||||
uint size;
|
||||
string bios = config::file_updatepath("stbios.bin", config::path.bios);
|
||||
info.rom_size = 0x300000;
|
||||
rom = (uint8*)malloc(info.rom_size);
|
||||
memset(rom, 0, info.rom_size);
|
||||
|
||||
load_file(strptr(bios), data, size);
|
||||
memcpy(rom, data, min(size, 0x040000));
|
||||
safe_free(data);
|
||||
|
||||
memcpy(rom + 0x100000, file.rom_data[0], min(file.rom_size[0], 0x100000));
|
||||
safe_free(file.rom_data[0]);
|
||||
|
||||
memcpy(rom + 0x200000, file.rom_data[1], min(file.rom_size[1], 0x100000));
|
||||
safe_free(file.rom_data[1]);
|
||||
|
||||
char name_a[4096], name_b[4096];
|
||||
strcpy(name_a, "???");
|
||||
strcpy(name_b, "???");
|
||||
//
|
||||
info.mapper = PCB;
|
||||
info.region = NTSC;
|
||||
|
||||
info.rom_size = 0x300000;
|
||||
info.ram_size = 0x040000;
|
||||
//
|
||||
|
||||
info.crc32 = crc32_calculate(rom + 0x100000, file.rom_size[0]);
|
||||
if(read_database() == true) {
|
||||
strcpy(name_a, dbi.name);
|
||||
}
|
||||
|
||||
info.crc32 = crc32_calculate(rom + 0x200000, file.rom_size[1]);
|
||||
if(read_database() == true) {
|
||||
strcpy(name_b, dbi.name);
|
||||
}
|
||||
|
||||
//
|
||||
info.crc32 = 0;
|
||||
strcpy(info.name, name_a);
|
||||
strcat(info.name, " + ");
|
||||
strcat(info.name, name_b);
|
||||
strcpy(info.pcb, "STC-DUAL");
|
||||
}
|
||||
|
||||
void Cartridge::load_ram_stdual() {
|
||||
ram = (uint8*)malloc(info.ram_size);
|
||||
memset(ram, 0xff, info.ram_size);
|
||||
|
||||
if(load_file(file.ram_name[0], file.ram_data[0], file.ram_size[0]) == true) {
|
||||
memcpy(ram + 0x000000, file.ram_data[0], min(file.ram_size[0], 0x020000));
|
||||
safe_free(file.ram_data[0]);
|
||||
}
|
||||
|
||||
if(load_file(file.ram_name[1], file.ram_data[1], file.ram_size[1]) == true) {
|
||||
memcpy(ram + 0x020000, file.ram_data[1], min(file.ram_size[1], 0x020000));
|
||||
safe_free(file.ram_data[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::save_ram_stdual() {
|
||||
save_file(file.ram_name[0], ram + 0x000000, 0x020000);
|
||||
save_file(file.ram_name[1], ram + 0x020000, 0x020000);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
void Cartridge::load_database() {
|
||||
database = 0;
|
||||
database_size = 0;
|
||||
|
||||
FILE *fp;
|
||||
fp = fopen("cart.db", "rb");
|
||||
if(!fp)return;
|
||||
|
||||
uint size = fsize(fp);
|
||||
if(size < 8) {
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
database = (uint8*)malloc(size);
|
||||
fread(database, 1, size, fp);
|
||||
fclose(fp);
|
||||
|
||||
database_blocksize = (database[6] << 0) | (database[7] << 8);
|
||||
database_size = (size - 8) / database_blocksize;
|
||||
}
|
||||
|
||||
bool Cartridge::read_database() {
|
||||
uint i, crc32;
|
||||
for(i = 0; i < database_size; i++) {
|
||||
uint8 *p = database + 8 + (i * database_blocksize);
|
||||
crc32 = *(p++) << 0;
|
||||
crc32 |= *(p++) << 8;
|
||||
crc32 |= *(p++) << 16;
|
||||
crc32 |= *(p++) << 24;
|
||||
if(crc32 == cartridge.info.crc32)break;
|
||||
}
|
||||
if(i >= database_size)return false;
|
||||
|
||||
db_read(dbi, database + 8 + (i * database_blocksize));
|
||||
return true;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,113 @@
|
||||
[0xbb5c4238]
|
||||
name = "Bishoujo Senshi Sailor Moon Sailor Stars - Fuwa Fuwa Panic 2 (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 8mbit
|
||||
ram = 32kbit
|
||||
|
||||
[0x8eb753f3]
|
||||
name = "Crayon Shin-chan - Nagagutsu Dobon!! (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0x7aedd703]
|
||||
name = "Der Langrisser (Japan) [!]"
|
||||
pcb = "SHVC-1A3M-30"
|
||||
rom = 16mbit
|
||||
ram = 64kbit
|
||||
|
||||
[0x19bdcb19]
|
||||
name = "Derby Stallion '96 (Japan) [!]"
|
||||
pcb = "BSC-1A5M-01"
|
||||
rom = 24mbit
|
||||
ram = 256kbit
|
||||
|
||||
[0x4296500d]
|
||||
name = "Gegege no Kitarou - Youkai Donjara (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 16kbit
|
||||
|
||||
[0x14c66fca]
|
||||
name = "Gekisou Sentai Car Rangers (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0x32b2b3dd]
|
||||
name = "Poi Poi Ninja World (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0x9684526d]
|
||||
name = "Romancing SaGa (Japan) (V1.1) [!]"
|
||||
pcb = "SHVC-1A3B-12"
|
||||
rom = 8mbit
|
||||
ram = 64kbit
|
||||
|
||||
[0xafd74dcb]
|
||||
name = "SD Gundam Generation A - Ichinen Sensouki (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0x48ecae44]
|
||||
name = "SD Gundam Generation B - Grips Senki (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0x72b4235f]
|
||||
name = "SD Gundam Generation C - Axis Senki (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0x792d884c]
|
||||
name = "SD Gundam Generation D - Babylonia Kenkoku Senki (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0xefd3a865]
|
||||
name = "SD Gundam Generation E - Zanskar Senki (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0xc5dfa8fd]
|
||||
name = "SD Gundam Generation F - Colony Kakutouki (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0x43ad5a45]
|
||||
name = "SD Ultra Battle - Seven Densetsu (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0x04939d14]
|
||||
name = "SD Ultra Battle - Ultra Densetsu (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0xa5c0045e]
|
||||
name = "Secret of Evermore (USA) [!]"
|
||||
pcb = "SHVC-1J3M-20"
|
||||
rom = 32mbit
|
||||
ram = 64kbit
|
||||
|
||||
[0x5ebf7246]
|
||||
name = "Sound Novel Tsukuru (Japan) [!]"
|
||||
pcb = "BSC-1A7M-10"
|
||||
rom = 24mbit
|
||||
ram = 512kbit
|
||||
|
||||
[0x64a91e64]
|
||||
name = "Wanderers from Ys (USA) [!]"
|
||||
pcb = "SHVC-1A3B-12"
|
||||
rom = 8mbit
|
||||
ram = 64kbit
|
||||
@@ -0,0 +1,3 @@
|
||||
cl /nologo /O2 dbcreate.cpp
|
||||
@pause
|
||||
@del *.obj
|
||||
@@ -0,0 +1 @@
|
||||
@del *.exe
|
||||
@@ -0,0 +1,2 @@
|
||||
dbcreate
|
||||
@copy cart.db ..\..\..\cart.db
|
||||
@@ -0,0 +1,47 @@
|
||||
struct db_item {
|
||||
uint32 crc32;
|
||||
char name[128];
|
||||
char pcb [32];
|
||||
uint32 rom;
|
||||
uint32 ram;
|
||||
};
|
||||
|
||||
void db_write(FILE *fp, db_item &dbi) {
|
||||
fputc(dbi.crc32 >> 0, fp);
|
||||
fputc(dbi.crc32 >> 8, fp);
|
||||
fputc(dbi.crc32 >> 16, fp);
|
||||
fputc(dbi.crc32 >> 24, fp);
|
||||
|
||||
fwrite(dbi.name, 1, 128, fp);
|
||||
fwrite(dbi.pcb, 1, 32, fp);
|
||||
|
||||
fputc(dbi.rom >> 0, fp);
|
||||
fputc(dbi.rom >> 8, fp);
|
||||
fputc(dbi.rom >> 16, fp);
|
||||
fputc(dbi.rom >> 24, fp);
|
||||
|
||||
fputc(dbi.ram >> 0, fp);
|
||||
fputc(dbi.ram >> 8, fp);
|
||||
fputc(dbi.ram >> 16, fp);
|
||||
fputc(dbi.ram >> 24, fp);
|
||||
}
|
||||
|
||||
void db_read(db_item &dbi, uint8 *data) {
|
||||
dbi.crc32 = (*data++) << 0;
|
||||
dbi.crc32 |= (*data++) << 8;
|
||||
dbi.crc32 |= (*data++) << 16;
|
||||
dbi.crc32 |= (*data++) << 24;
|
||||
|
||||
memcpy(dbi.name, data, 128); dbi.name[127] = 0; data += 128;
|
||||
memcpy(dbi.pcb, data, 32); dbi.pcb [ 31] = 0; data += 32;
|
||||
|
||||
dbi.rom = (*data++) << 0;
|
||||
dbi.rom |= (*data++) << 8;
|
||||
dbi.rom |= (*data++) << 16;
|
||||
dbi.rom |= (*data++) << 24;
|
||||
|
||||
dbi.ram = (*data++) << 0;
|
||||
dbi.ram |= (*data++) << 8;
|
||||
dbi.ram |= (*data++) << 16;
|
||||
dbi.ram |= (*data++) << 24;
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
#include "../../lib/libbase.h"
|
||||
#include "../../lib/libvector.h"
|
||||
#include "../../lib/libstring.h"
|
||||
|
||||
#include "../../lib/libstring.cpp"
|
||||
|
||||
#include "db.h"
|
||||
|
||||
FILE *fp;
|
||||
|
||||
uint decode_size(string &str) {
|
||||
//hex encoding
|
||||
if(strbegin(str, "0x")) {
|
||||
strltrim(str, "0x");
|
||||
return strhex(str);
|
||||
}
|
||||
|
||||
//mbit encoding
|
||||
if(strend(str, "mbit")) {
|
||||
strrtrim(str, "mbit");
|
||||
return strdec(str) * 1024 * 1024 / 8;
|
||||
}
|
||||
|
||||
//kbit encoding
|
||||
if(strend(str, "kbit")) {
|
||||
strrtrim(str, "kbit");
|
||||
return strdec(str) * 1024 / 8;
|
||||
}
|
||||
|
||||
//decimal encoding
|
||||
return strdec(str);
|
||||
}
|
||||
|
||||
void build_block(string &block) {
|
||||
stringarray line, hashpart, part;
|
||||
split(line, "\n", block);
|
||||
|
||||
if(strbegin(line[0], "[") == false) {
|
||||
printf("error: invalid block detected: '%s'\n", strptr(line[0]));
|
||||
return;
|
||||
}
|
||||
|
||||
strltrim(line[0], "[");
|
||||
strrtrim(line[0], "]");
|
||||
replace(line[0], "0x", "");
|
||||
split(hashpart, ",", line[0]);
|
||||
|
||||
db_item dbi;
|
||||
dbi.crc32 = 0;
|
||||
*dbi.name = 0;
|
||||
*dbi.pcb = 0;
|
||||
dbi.rom = 0;
|
||||
dbi.ram = 0;
|
||||
|
||||
for(int i = 1; i < count(line); i++) {
|
||||
uint pos;
|
||||
if(strpos(line[i], ";", pos) == true) {
|
||||
strset(line[i], pos, 0);
|
||||
}
|
||||
|
||||
if(line[i] == "")continue;
|
||||
|
||||
split(part, "=", line[i]);
|
||||
strunquote(part[1]);
|
||||
|
||||
if(part[0] == "name") {
|
||||
strncpy(dbi.name, strptr(part[1]), 128);
|
||||
dbi.name[128] = 0;
|
||||
}
|
||||
|
||||
if(part[0] == "pcb") {
|
||||
strncpy(dbi.pcb, strptr(part[1]), 32);
|
||||
dbi.pcb[31] = 0;
|
||||
}
|
||||
|
||||
if(part[0] == "rom") {
|
||||
dbi.rom = decode_size(part[1]);
|
||||
}
|
||||
|
||||
if(part[0] == "ram") {
|
||||
dbi.ram = decode_size(part[1]);
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < count(hashpart); i++) {
|
||||
dbi.crc32 = strhex(hashpart[i]);
|
||||
db_write(fp, dbi);
|
||||
}
|
||||
}
|
||||
|
||||
void build_database() {
|
||||
stringarray data, block;
|
||||
if(strfread(data, "cartdb.txt") == false)return;
|
||||
|
||||
fp = fopen("cart.db", "wb");
|
||||
fprintf(fp, "SNESDB");
|
||||
|
||||
uint blocksize = 4 + 128 + 32 + 4 + 4;
|
||||
fputc(blocksize >> 0, fp);
|
||||
fputc(blocksize >> 8, fp);
|
||||
|
||||
replace (data, "\r", "");
|
||||
qreplace(data, " ", "");
|
||||
qreplace(data, "\t", "");
|
||||
split(block, "\n\n", data);
|
||||
|
||||
for(int i = 0; i < count(block); i++) {
|
||||
build_block(block[i]);
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
int main() {
|
||||
build_database();
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
::@make -r PLATFORM=win-visualc-lui
|
||||
@make -r PLATFORM=win-visualc-lui GZIP_SUPPORT=true JMA_SUPPORT=true
|
||||
@move bsnes.exe ../bsnes.exe>nul
|
||||
@pause
|
||||
@@ -0,0 +1,339 @@
|
||||
#include "../base.h"
|
||||
#include "../reader/filereader.h"
|
||||
|
||||
Cheat cheat;
|
||||
|
||||
/*****
|
||||
* string <> binary code translation routines
|
||||
* decode() "7e1234:56" -> 0x7e123456
|
||||
* encode() 0x7e123456 -> "7e1234:56"
|
||||
*****/
|
||||
|
||||
bool Cheat::decode(char *str, uint32 &addr, uint8 &data, uint8 &type) {
|
||||
stringarray t, part;
|
||||
strcpy(t, str);
|
||||
strlower(t);
|
||||
if(strlen(t) == 8 || (strlen(t) == 9 && strptr(t)[6] == ':')) {
|
||||
type = CT_PRO_ACTION_REPLAY;
|
||||
replace(t, ":", "");
|
||||
uint32 r = strhex(t);
|
||||
addr = r >> 8;
|
||||
data = r & 0xff;
|
||||
return true;
|
||||
} else if(strlen(t) == 9 && strptr(t)[4] == '-') {
|
||||
type = CT_GAME_GENIE;
|
||||
replace(t, "-", "");
|
||||
strtr(t, "df4709156bc8a23e", "0123456789abcdef");
|
||||
uint32 r = strhex(t);
|
||||
//8421 8421 8421 8421 8421 8421
|
||||
//abcd efgh ijkl mnop qrst uvwx
|
||||
//ijkl qrst opab cduv wxef ghmn
|
||||
addr = (!!(r & 0x002000) << 23) | (!!(r & 0x001000) << 22) |
|
||||
(!!(r & 0x000800) << 21) | (!!(r & 0x000400) << 20) |
|
||||
(!!(r & 0x000020) << 19) | (!!(r & 0x000010) << 18) |
|
||||
(!!(r & 0x000008) << 17) | (!!(r & 0x000004) << 16) |
|
||||
(!!(r & 0x800000) << 15) | (!!(r & 0x400000) << 14) |
|
||||
(!!(r & 0x200000) << 13) | (!!(r & 0x100000) << 12) |
|
||||
(!!(r & 0x000002) << 11) | (!!(r & 0x000001) << 10) |
|
||||
(!!(r & 0x008000) << 9) | (!!(r & 0x004000) << 8) |
|
||||
(!!(r & 0x080000) << 7) | (!!(r & 0x040000) << 6) |
|
||||
(!!(r & 0x020000) << 5) | (!!(r & 0x010000) << 4) |
|
||||
(!!(r & 0x000200) << 3) | (!!(r & 0x000100) << 2) |
|
||||
(!!(r & 0x000080) << 1) | (!!(r & 0x000040) << 0);
|
||||
data = r >> 24;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Cheat::encode(char *str, uint32 addr, uint8 data, uint8 type) {
|
||||
if(type == CT_PRO_ACTION_REPLAY) {
|
||||
sprintf(str, "%0.6x:%0.2x", addr, data);
|
||||
return true;
|
||||
} else if(type == CT_GAME_GENIE) {
|
||||
uint32 r = addr;
|
||||
addr = (!!(r & 0x008000) << 23) | (!!(r & 0x004000) << 22) |
|
||||
(!!(r & 0x002000) << 21) | (!!(r & 0x001000) << 20) |
|
||||
(!!(r & 0x000080) << 19) | (!!(r & 0x000040) << 18) |
|
||||
(!!(r & 0x000020) << 17) | (!!(r & 0x000010) << 16) |
|
||||
(!!(r & 0x000200) << 15) | (!!(r & 0x000100) << 14) |
|
||||
(!!(r & 0x800000) << 13) | (!!(r & 0x400000) << 12) |
|
||||
(!!(r & 0x200000) << 11) | (!!(r & 0x100000) << 10) |
|
||||
(!!(r & 0x000008) << 9) | (!!(r & 0x000004) << 8) |
|
||||
(!!(r & 0x000002) << 7) | (!!(r & 0x000001) << 6) |
|
||||
(!!(r & 0x080000) << 5) | (!!(r & 0x040000) << 4) |
|
||||
(!!(r & 0x020000) << 3) | (!!(r & 0x010000) << 2) |
|
||||
(!!(r & 0x000800) << 1) | (!!(r & 0x000400) << 0);
|
||||
sprintf(str, "%0.2x%0.2x-%0.4x", data, addr >> 16, addr & 0xffff);
|
||||
strtr(str, "0123456789abcdef", "df4709156bc8a23e");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*****
|
||||
* address lookup table manipulation and mirroring
|
||||
* mirror_address() 0x000000 -> 0x7e0000
|
||||
* set() enable specified address, mirror accordingly
|
||||
* clear() disable specified address, mirror accordingly
|
||||
*****/
|
||||
|
||||
uint Cheat::mirror_address(uint addr) {
|
||||
if((addr & 0x40e000) != 0x0000)return addr;
|
||||
//8k WRAM mirror
|
||||
//$[00-3f|80-bf]:[0000-1fff] -> $7e:[0000-1fff]
|
||||
return (0x7e0000 + (addr & 0x1fff));
|
||||
}
|
||||
|
||||
void Cheat::set(uint32 addr) {
|
||||
addr = mirror_address(addr);
|
||||
|
||||
mask[addr >> 3] |= 1 << (addr & 7);
|
||||
if((addr & 0xffe000) == 0x7e0000) {
|
||||
//mirror $7e:[0000-1fff] to $[00-3f|80-bf]:[0000-1fff]
|
||||
uint mirror;
|
||||
for(int x = 0; x <= 0x3f; x++) {
|
||||
mirror = ((0x00 + x) << 16) + (addr & 0x1fff);
|
||||
mask[mirror >> 3] |= 1 << (mirror & 7);
|
||||
mirror = ((0x80 + x) << 16) + (addr & 0x1fff);
|
||||
mask[mirror >> 3] |= 1 << (mirror & 7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cheat::clear(uint32 addr) {
|
||||
addr = mirror_address(addr);
|
||||
|
||||
//is there more than one cheat code using the same address
|
||||
//(and likely a different override value) that is enabled?
|
||||
//if so, do not clear code lookup table entry for this address.
|
||||
uint8 r;
|
||||
if(read(addr, r) == true)return;
|
||||
|
||||
mask[addr >> 3] &= ~(1 << (addr & 7));
|
||||
if((addr & 0xffe000) == 0x7e0000) {
|
||||
//mirror $7e:[0000-1fff] to $[00-3f|80-bf]:[0000-1fff]
|
||||
uint mirror;
|
||||
for(int x = 0; x <= 0x3f; x++) {
|
||||
mirror = ((0x00 + x) << 16) + (addr & 0x1fff);
|
||||
mask[mirror >> 3] &= ~(1 << (mirror & 7));
|
||||
mirror = ((0x80 + x) << 16) + (addr & 0x1fff);
|
||||
mask[mirror >> 3] &= ~(1 << (mirror & 7));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****
|
||||
* read() is used by MemBus::read() if Cheat::enabled(addr)
|
||||
* returns true to look up cheat code.
|
||||
* returns true if cheat code was found, false if it was not.
|
||||
* when true, cheat code substitution value is stored in data.
|
||||
*****/
|
||||
|
||||
bool Cheat::read(uint32 addr, uint8 &data) {
|
||||
addr = mirror_address(addr);
|
||||
for(int i = 0; i < cheat_count; i++) {
|
||||
if(enabled(i) == false)continue;
|
||||
if(addr == mirror_address(index[i].addr)) {
|
||||
data = index[i].data;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
//code not found, or code is disabled
|
||||
return false;
|
||||
}
|
||||
|
||||
/*****
|
||||
* update_cheat_status() will scan to see if any codes are
|
||||
* enabled. if any are, make sure the cheat system is on.
|
||||
* otherwise, turn cheat system off to speed up emulation.
|
||||
*****/
|
||||
void Cheat::update_cheat_status() {
|
||||
for(int i = 0; i < cheat_count; i++) {
|
||||
if(index[i].enabled) {
|
||||
cheat_enabled = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
cheat_enabled = false;
|
||||
}
|
||||
|
||||
/*****
|
||||
* cheat list manipulation routines
|
||||
*****/
|
||||
|
||||
bool Cheat::add(bool enable, char *code, char *desc) {
|
||||
if(cheat_count >= CHEAT_LIMIT)return false;
|
||||
|
||||
uint32 addr, len;
|
||||
uint8 data, type;
|
||||
if(decode(code, addr, data, type) == false)return false;
|
||||
|
||||
index[cheat_count].enabled = enable;
|
||||
index[cheat_count].addr = addr;
|
||||
index[cheat_count].data = data;
|
||||
len = strlen(code);
|
||||
len = len > 16 ? 16 : len;
|
||||
memcpy(index[cheat_count].code, code, len);
|
||||
index[cheat_count].code[len] = 0;
|
||||
len = strlen(desc);
|
||||
len = len > 128 ? 128 : len;
|
||||
memcpy(index[cheat_count].desc, desc, len);
|
||||
index[cheat_count].desc[len] = 0;
|
||||
cheat_count++;
|
||||
(enable) ? set(addr) : clear(addr);
|
||||
|
||||
update_cheat_status();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cheat::edit(uint32 n, bool enable, char *code, char *desc) {
|
||||
if(n >= cheat_count)return false;
|
||||
|
||||
uint32 addr, len;
|
||||
uint8 data, type;
|
||||
if(decode(code, addr, data, type) == false)return false;
|
||||
|
||||
//disable current code and clear from code lookup table
|
||||
index[n].enabled = false;
|
||||
clear(index[n].addr);
|
||||
|
||||
//update code and enable in code lookup table
|
||||
index[n].enabled = enable;
|
||||
index[n].addr = addr;
|
||||
index[n].data = data;
|
||||
len = strlen(code);
|
||||
len = len > 16 ? 16 : len;
|
||||
memcpy(index[n].code, code, len);
|
||||
index[n].code[len] = 0;
|
||||
len = strlen(desc);
|
||||
len = len > 128 ? 128 : len;
|
||||
memcpy(index[n].desc, desc, len);
|
||||
index[n].desc[len] = 0;
|
||||
set(addr);
|
||||
|
||||
update_cheat_status();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cheat::remove(uint32 n) {
|
||||
if(n >= cheat_count)return false;
|
||||
|
||||
for(int i = n; i < cheat_count; i++) {
|
||||
index[i].enabled = index[i + 1].enabled;
|
||||
index[i].addr = index[i + 1].addr;
|
||||
index[i].data = index[i + 1].data;
|
||||
strcpy(index[i].desc, index[i + 1].desc);
|
||||
}
|
||||
|
||||
cheat_count--;
|
||||
|
||||
update_cheat_status();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cheat::get(uint32 n, bool &enable, uint32 &addr, uint8 &data, char *code, char *desc) {
|
||||
if(n >= cheat_count)return false;
|
||||
enable = index[n].enabled;
|
||||
addr = index[n].addr;
|
||||
data = index[n].data;
|
||||
strcpy(code, index[n].code);
|
||||
strcpy(desc, index[n].desc);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*****
|
||||
* code status modifier routines
|
||||
*****/
|
||||
|
||||
bool Cheat::enabled(uint32 n) {
|
||||
if(n >= cheat_count)return false;
|
||||
return index[n].enabled;
|
||||
}
|
||||
|
||||
void Cheat::enable(uint32 n) {
|
||||
if(n >= cheat_count)return;
|
||||
index[n].enabled = true;
|
||||
set(index[n].addr);
|
||||
update_cheat_status();
|
||||
}
|
||||
|
||||
void Cheat::disable(uint32 n) {
|
||||
if(n >= cheat_count)return;
|
||||
index[n].enabled = false;
|
||||
clear(index[n].addr);
|
||||
update_cheat_status();
|
||||
}
|
||||
|
||||
/*****
|
||||
* cheat file manipulation routines
|
||||
*****/
|
||||
|
||||
bool Cheat::load(const char *fn) {
|
||||
FileReader rf(fn);
|
||||
if(!rf.ready())return false;
|
||||
|
||||
uint8 *raw_data = rf.read();
|
||||
stringarray data, line;
|
||||
raw_data[rf.size()] = 0;
|
||||
strcpy(data, (char*)raw_data);
|
||||
safe_free(raw_data);
|
||||
replace(data, "\r\n", "\n");
|
||||
|
||||
split(line, "\n", data);
|
||||
for(int i = 0; i < ::count(line); i++) {
|
||||
stringarray part;
|
||||
uint8 en = *(strptr(line[i]));
|
||||
if(en == '+') {
|
||||
strltrim(line[i], "+");
|
||||
} else if(en == '-') {
|
||||
strltrim(line[i], "-");
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
qreplace(line[i], " ", "");
|
||||
qsplit(part, ",", line[i]);
|
||||
if(::count(part) != 2)continue;
|
||||
strunquote(part[1]);
|
||||
add(en == '+', strptr(part[0]), strptr(part[1]));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cheat::save(const char *fn) {
|
||||
FileWriter wf(fn);
|
||||
if(!wf.ready())return false;
|
||||
|
||||
string data;
|
||||
char t[4096];
|
||||
strcpy(data, "");
|
||||
for(int i = 0; i < cheat_count; i++) {
|
||||
sprintf(t, "%c%s, \"%s\"\r\n", index[i].enabled ? '+' : '-', index[i].code, index[i].desc);
|
||||
strcat(data, t);
|
||||
}
|
||||
|
||||
wf.write((uint8*)strptr(data), strlen(data));
|
||||
return true;
|
||||
}
|
||||
|
||||
/*****
|
||||
* initialization routines
|
||||
*****/
|
||||
|
||||
void Cheat::clear() {
|
||||
cheat_enabled = false;
|
||||
cheat_count = 0;
|
||||
memset(mask, 0, 0x200000);
|
||||
for(int i = 0; i < CHEAT_LIMIT + 1; i++) {
|
||||
index[i].enabled = false;
|
||||
index[i].addr = 0x000000;
|
||||
index[i].data = 0x00;
|
||||
strcpy(index[i].code, "");
|
||||
strcpy(index[i].desc, "");
|
||||
}
|
||||
}
|
||||
|
||||
Cheat::Cheat() {
|
||||
clear();
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#define CHEAT_LIMIT 1024
|
||||
|
||||
class Cheat {
|
||||
public:
|
||||
enum { CT_PRO_ACTION_REPLAY, CT_GAME_GENIE };
|
||||
|
||||
struct CheatIndex {
|
||||
bool enabled;
|
||||
uint32 addr;
|
||||
uint8 data;
|
||||
char code[ 16 + 1];
|
||||
char desc[128 + 1];
|
||||
} index[CHEAT_LIMIT + 1];
|
||||
bool cheat_enabled;
|
||||
uint32 cheat_count;
|
||||
uint8 mask[0x200000];
|
||||
|
||||
inline bool enabled() { return cheat_enabled; }
|
||||
inline uint count() { return cheat_count; }
|
||||
inline bool exists(uint32 addr) { return bool(mask[addr >> 3] & 1 << (addr & 7)); }
|
||||
|
||||
bool decode(char *str, uint32 &addr, uint8 &data, uint8 &type);
|
||||
bool encode(char *str, uint32 addr, uint8 data, uint8 type);
|
||||
|
||||
private:
|
||||
uint mirror_address(uint addr);
|
||||
void set(uint32 addr);
|
||||
void clear(uint32 addr);
|
||||
public:
|
||||
|
||||
bool read(uint32 addr, uint8 &data);
|
||||
|
||||
void update_cheat_status();
|
||||
bool add(bool enable, char *code, char *desc);
|
||||
bool edit(uint32 n, bool enable, char *code, char *desc);
|
||||
bool get(uint32 n, bool &enable, uint32 &addr, uint8 &data, char *code, char *desc);
|
||||
bool remove (uint32 n);
|
||||
bool enabled(uint32 n);
|
||||
void enable (uint32 n);
|
||||
void disable(uint32 n);
|
||||
bool load(const char *fn);
|
||||
bool save(const char *fn);
|
||||
void clear();
|
||||
|
||||
Cheat();
|
||||
};
|
||||
|
||||
extern Cheat cheat;
|
||||
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
C4 emulation
|
||||
|
||||
Used in Rockman X2/X3 (Megaman X2/X3)
|
||||
Portions (c) anomie, Overload, zsKnight, Nach, byuu
|
||||
*/
|
||||
|
||||
#include "../../base.h"
|
||||
|
||||
C4 *c4;
|
||||
|
||||
#include "c4data.cpp"
|
||||
#include "c4fn.cpp"
|
||||
#include "c4oam.cpp"
|
||||
#include "c4ops.cpp"
|
||||
|
||||
void C4::init() {}
|
||||
void C4::enable() {}
|
||||
|
||||
uint32 C4::ldr(uint8 r) {
|
||||
uint16 addr = 0x0080 + (r * 3);
|
||||
return (reg[addr]) | (reg[addr + 1] << 8) | (reg[addr + 2] << 16);
|
||||
}
|
||||
|
||||
void C4::str(uint8 r, uint32 data) {
|
||||
uint16 addr = 0x0080 + (r * 3);
|
||||
reg[addr ] = (data);
|
||||
reg[addr + 1] = (data >> 8);
|
||||
reg[addr + 2] = (data >> 16);
|
||||
}
|
||||
|
||||
void C4::mul(uint32 x, uint32 y, uint32 &rl, uint32 &rh) {
|
||||
int64 rx = x & 0xffffff;
|
||||
int64 ry = y & 0xffffff;
|
||||
if(rx & 0x800000)rx |= ~0x7fffff;
|
||||
if(ry & 0x800000)ry |= ~0x7fffff;
|
||||
|
||||
rx *= ry;
|
||||
|
||||
rl = (rx) & 0xffffff;
|
||||
rh = (rx >> 24) & 0xffffff;
|
||||
}
|
||||
|
||||
uint32 C4::sin(uint32 rx) {
|
||||
r0 = rx & 0x1ff;
|
||||
if(r0 & 0x100)r0 ^= 0x1ff;
|
||||
if(r0 & 0x080)r0 ^= 0x0ff;
|
||||
if(rx & 0x100) {
|
||||
return sin_table[r0 + 0x80];
|
||||
} else {
|
||||
return sin_table[r0];
|
||||
}
|
||||
}
|
||||
|
||||
uint32 C4::cos(uint32 rx) {
|
||||
return sin(rx + 0x080);
|
||||
}
|
||||
|
||||
void C4::immediate_reg(uint32 start) {
|
||||
r0 = ldr(0);
|
||||
for(uint32 i=start;i<48;i++) {
|
||||
if((r0 & 0x0fff) < 0x0c00) {
|
||||
ram[r0 & 0x0fff] = immediate_data[i];
|
||||
}
|
||||
r0++;
|
||||
}
|
||||
str(0, r0);
|
||||
}
|
||||
|
||||
void C4::transfer_data() {
|
||||
uint32 src;
|
||||
uint16 dest, count;
|
||||
src = (reg[0x40]) | (reg[0x41] << 8) | (reg[0x42] << 16);
|
||||
count = (reg[0x43]) | (reg[0x44] << 8);
|
||||
dest = (reg[0x45]) | (reg[0x46] << 8);
|
||||
|
||||
for(uint32 i=0;i<count;i++) {
|
||||
write(dest++, r_mem->read(src++));
|
||||
}
|
||||
}
|
||||
|
||||
void C4::write(uint16 addr, uint8 data) {
|
||||
addr &= 0x1fff;
|
||||
|
||||
if(addr < 0x0c00) {
|
||||
//ram
|
||||
ram[addr] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr < 0x1f00) {
|
||||
//unmapped
|
||||
return;
|
||||
}
|
||||
|
||||
//command register
|
||||
reg[addr & 0xff] = data;
|
||||
|
||||
if(addr == 0x1f47) {
|
||||
//memory transfer
|
||||
transfer_data();
|
||||
return;
|
||||
}
|
||||
|
||||
if(addr == 0x1f4f) {
|
||||
//c4 command
|
||||
if(reg[0x4d] == 0x0e && !(data & 0xc3)) {
|
||||
//c4 test command
|
||||
reg[0x80] = data >> 2;
|
||||
return;
|
||||
}
|
||||
|
||||
switch(data) {
|
||||
case 0x00:op00();break;
|
||||
case 0x01:op01();break;
|
||||
case 0x05:op05();break;
|
||||
case 0x0d:op0d();break;
|
||||
case 0x10:op10();break;
|
||||
case 0x13:op13();break;
|
||||
case 0x15:op15();break;
|
||||
case 0x1f:op1f();break;
|
||||
case 0x22:op22();break;
|
||||
case 0x25:op25();break;
|
||||
case 0x2d:op2d();break;
|
||||
case 0x40:op40();break;
|
||||
case 0x54:op54();break;
|
||||
case 0x5c:op5c();break;
|
||||
case 0x5e:op5e();break;
|
||||
case 0x60:op60();break;
|
||||
case 0x62:op62();break;
|
||||
case 0x64:op64();break;
|
||||
case 0x66:op66();break;
|
||||
case 0x68:op68();break;
|
||||
case 0x6a:op6a();break;
|
||||
case 0x6c:op6c();break;
|
||||
case 0x6e:op6e();break;
|
||||
case 0x70:op70();break;
|
||||
case 0x72:op72();break;
|
||||
case 0x74:op74();break;
|
||||
case 0x76:op76();break;
|
||||
case 0x78:op78();break;
|
||||
case 0x7a:op7a();break;
|
||||
case 0x7c:op7c();break;
|
||||
case 0x89:op89();break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void C4::writeb(uint16 addr, uint8 data) {
|
||||
write(addr, data);
|
||||
}
|
||||
|
||||
void C4::writew(uint16 addr, uint16 data) {
|
||||
write(addr, data);
|
||||
write(addr + 1, data >> 8);
|
||||
}
|
||||
|
||||
void C4::writel(uint16 addr, uint32 data) {
|
||||
write(addr, data);
|
||||
write(addr + 1, data >> 8);
|
||||
write(addr + 2, data >> 16);
|
||||
}
|
||||
|
||||
uint8 C4::read(uint16 addr) {
|
||||
addr &= 0x1fff;
|
||||
|
||||
if(addr < 0x0c00) {
|
||||
return ram[addr];
|
||||
}
|
||||
|
||||
if(addr >= 0x1f00) {
|
||||
return reg[addr & 0xff];
|
||||
}
|
||||
|
||||
return r_cpu->regs.mdr;
|
||||
}
|
||||
|
||||
uint8 C4::readb(uint16 addr) {
|
||||
return read(addr);
|
||||
}
|
||||
|
||||
uint16 C4::readw(uint16 addr) {
|
||||
return read(addr) | (read(addr + 1) << 8);
|
||||
}
|
||||
|
||||
uint32 C4::readl(uint16 addr) {
|
||||
return read(addr) | (read(addr + 1) << 8) + (read(addr + 2) << 16);
|
||||
}
|
||||
|
||||
void C4::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void C4::reset() {
|
||||
memset(ram, 0, 0x0c00);
|
||||
memset(reg, 0, 0x0100);
|
||||
}
|
||||
|
||||
C4::C4() {}
|
||||
@@ -0,0 +1,96 @@
|
||||
class C4 {
|
||||
private:
|
||||
uint8 ram[0x0c00];
|
||||
uint8 reg[0x0100];
|
||||
uint32 r0, r1, r2, r3, r4, r5, r6, r7,
|
||||
r8, r9, r10, r11, r12, r13, r14, r15;
|
||||
|
||||
static const uint8 immediate_data[48];
|
||||
static const uint16 wave_data[40];
|
||||
static const uint32 sin_table[256];
|
||||
|
||||
static const int16 SinTable[512];
|
||||
static const int16 CosTable[512];
|
||||
|
||||
int16 C4WFXVal, C4WFYVal, C4WFZVal, C4WFX2Val, C4WFY2Val, C4WFDist, C4WFScale;
|
||||
int16 C41FXVal, C41FYVal, C41FAngleRes, C41FDist, C41FDistVal;
|
||||
|
||||
double tanval;
|
||||
double c4x,c4y,c4z, c4x2,c4y2,c4z2;
|
||||
|
||||
void C4TransfWireFrame();
|
||||
void C4TransfWireFrame2();
|
||||
void C4CalcWireFrame();
|
||||
void C4DrawLine(int32 X1, int32 Y1, int16 Z1, int32 X2, int32 Y2, int16 Z2, uint8 Color);
|
||||
void C4DrawWireFrame();
|
||||
void C4DoScaleRotate(int row_padding);
|
||||
|
||||
public:
|
||||
uint32 ldr(uint8 r);
|
||||
void str(uint8 r, uint32 data);
|
||||
void mul(uint32 x, uint32 y, uint32 &rl, uint32 &rh);
|
||||
uint32 sin(uint32 rx);
|
||||
uint32 cos(uint32 rx);
|
||||
|
||||
void transfer_data();
|
||||
void immediate_reg(uint32 num);
|
||||
|
||||
void op00_00();
|
||||
void op00_03();
|
||||
void op00_05();
|
||||
void op00_07();
|
||||
void op00_08();
|
||||
void op00_0b();
|
||||
void op00_0c();
|
||||
|
||||
void op00();
|
||||
void op01();
|
||||
void op05();
|
||||
void op0d();
|
||||
void op10();
|
||||
void op13();
|
||||
void op15();
|
||||
void op1f();
|
||||
void op22();
|
||||
void op25();
|
||||
void op2d();
|
||||
void op40();
|
||||
void op54();
|
||||
void op5c();
|
||||
void op5e();
|
||||
void op60();
|
||||
void op62();
|
||||
void op64();
|
||||
void op66();
|
||||
void op68();
|
||||
void op6a();
|
||||
void op6c();
|
||||
void op6e();
|
||||
void op70();
|
||||
void op72();
|
||||
void op74();
|
||||
void op76();
|
||||
void op78();
|
||||
void op7a();
|
||||
void op7c();
|
||||
void op89();
|
||||
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
void write (uint16 addr, uint8 data);
|
||||
void writeb(uint16 addr, uint8 data);
|
||||
void writew(uint16 addr, uint16 data);
|
||||
void writel(uint16 addr, uint32 data);
|
||||
|
||||
uint8 read (uint16 addr);
|
||||
uint8 readb(uint16 addr);
|
||||
uint16 readw(uint16 addr);
|
||||
uint32 readl(uint16 addr);
|
||||
|
||||
C4();
|
||||
};
|
||||
|
||||
extern C4 *c4;
|
||||
@@ -0,0 +1,183 @@
|
||||
const uint8 C4::immediate_data[48] = {
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x80, 0xff, 0xff, 0x7f,
|
||||
0x00, 0x80, 0x00, 0xff, 0x7f, 0x00, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0xff,
|
||||
0x00, 0x00, 0x01, 0xff, 0xff, 0xfe, 0x00, 0x01, 0x00, 0xff, 0xfe, 0x00
|
||||
};
|
||||
|
||||
const uint16 C4::wave_data[40] = {
|
||||
0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000a, 0x000c, 0x000e,
|
||||
0x0200, 0x0202, 0x0204, 0x0206, 0x0208, 0x020a, 0x020c, 0x020e,
|
||||
0x0400, 0x0402, 0x0404, 0x0406, 0x0408, 0x040a, 0x040c, 0x040e,
|
||||
0x0600, 0x0602, 0x0604, 0x0606, 0x0608, 0x060a, 0x060c, 0x060e,
|
||||
0x0800, 0x0802, 0x0804, 0x0806, 0x0808, 0x080a, 0x080c, 0x080e
|
||||
};
|
||||
|
||||
const uint32 C4::sin_table[256] = {
|
||||
0x000000, 0x000324, 0x000648, 0x00096c, 0x000c8f, 0x000fb2, 0x0012d5, 0x0015f6,
|
||||
0x001917, 0x001c37, 0x001f56, 0x002273, 0x002590, 0x0028aa, 0x002bc4, 0x002edb,
|
||||
0x0031f1, 0x003505, 0x003817, 0x003b26, 0x003e33, 0x00413e, 0x004447, 0x00474d,
|
||||
0x004a50, 0x004d50, 0x00504d, 0x005347, 0x00563e, 0x005931, 0x005c22, 0x005f0e,
|
||||
0x0061f7, 0x0064dc, 0x0067bd, 0x006a9b, 0x006d74, 0x007049, 0x007319, 0x0075e5,
|
||||
0x0078ad, 0x007b70, 0x007e2e, 0x0080e7, 0x00839c, 0x00864b, 0x0088f5, 0x008b9a,
|
||||
0x008e39, 0x0090d3, 0x009368, 0x0095f6, 0x00987f, 0x009b02, 0x009d7f, 0x009ff6,
|
||||
0x00a267, 0x00a4d2, 0x00a736, 0x00a994, 0x00abeb, 0x00ae3b, 0x00b085, 0x00b2c8,
|
||||
0x00b504, 0x00b73a, 0x00b968, 0x00bb8f, 0x00bdae, 0x00bfc7, 0x00c1d8, 0x00c3e2,
|
||||
0x00c5e4, 0x00c7de, 0x00c9d1, 0x00cbbb, 0x00cd9f, 0x00cf7a, 0x00d14d, 0x00d318,
|
||||
0x00d4db, 0x00d695, 0x00d848, 0x00d9f2, 0x00db94, 0x00dd2d, 0x00debe, 0x00e046,
|
||||
0x00e1c5, 0x00e33c, 0x00e4aa, 0x00e60f, 0x00e76b, 0x00e8bf, 0x00ea09, 0x00eb4b,
|
||||
0x00ec83, 0x00edb2, 0x00eed8, 0x00eff5, 0x00f109, 0x00f213, 0x00f314, 0x00f40b,
|
||||
0x00f4fa, 0x00f5de, 0x00f6ba, 0x00f78b, 0x00f853, 0x00f912, 0x00f9c7, 0x00fa73,
|
||||
0x00fb14, 0x00fbac, 0x00fc3b, 0x00fcbf, 0x00fd3a, 0x00fdab, 0x00fe13, 0x00fe70,
|
||||
0x00fec4, 0x00ff0e, 0x00ff4e, 0x00ff84, 0x00ffb1, 0x00ffd3, 0x00ffec, 0x00fffb,
|
||||
0x000000, 0xfffcdb, 0xfff9b7, 0xfff693, 0xfff370, 0xfff04d, 0xffed2a, 0xffea09,
|
||||
0xffe6e8, 0xffe3c8, 0xffe0a9, 0xffdd8c, 0xffda6f, 0xffd755, 0xffd43b, 0xffd124,
|
||||
0xffce0e, 0xffcafa, 0xffc7e8, 0xffc4d9, 0xffc1cc, 0xffbec1, 0xffbbb8, 0xffb8b2,
|
||||
0xffb5af, 0xffb2af, 0xffafb2, 0xffacb8, 0xffa9c1, 0xffa6ce, 0xffa3dd, 0xffa0f1,
|
||||
0xff9e08, 0xff9b23, 0xff9842, 0xff9564, 0xff928b, 0xff8fb6, 0xff8ce6, 0xff8a1a,
|
||||
0xff8752, 0xff848f, 0xff81d1, 0xff7f18, 0xff7c63, 0xff79b4, 0xff770a, 0xff7465,
|
||||
0xff71c6, 0xff6f2c, 0xff6c97, 0xff6a09, 0xff6780, 0xff64fd, 0xff6280, 0xff6009,
|
||||
0xff5d98, 0xff5b2d, 0xff58c9, 0xff566b, 0xff5414, 0xff51c4, 0xff4f7a, 0xff4d37,
|
||||
0xff4afb, 0xff48c5, 0xff4697, 0xff4470, 0xff4251, 0xff4038, 0xff3e27, 0xff3c1e,
|
||||
0xff3a1b, 0xff3821, 0xff362e, 0xff3444, 0xff3260, 0xff3085, 0xff2eb2, 0xff2ce7,
|
||||
0xff2b24, 0xff296a, 0xff27b7, 0xff260d, 0xff246b, 0xff22d2, 0xff2141, 0xff1fb9,
|
||||
0xff1e3a, 0xff1cc3, 0xff1b55, 0xff19f0, 0xff1894, 0xff1740, 0xff15f6, 0xff14b4,
|
||||
0xff137c, 0xff124d, 0xff1127, 0xff100a, 0xff0ef6, 0xff0dec, 0xff0ceb, 0xff0bf4,
|
||||
0xff0b05, 0xff0a21, 0xff0945, 0xff0874, 0xff07ac, 0xff06ed, 0xff0638, 0xff058d,
|
||||
0xff04eb, 0xff0453, 0xff03c4, 0xff0340, 0xff02c5, 0xff0254, 0xff01ec, 0xff018f,
|
||||
0xff013b, 0xff00f1, 0xff00b1, 0xff007b, 0xff004e, 0xff002c, 0xff0013, 0xff0004
|
||||
};
|
||||
|
||||
const int16 C4::SinTable[512] = {
|
||||
0, 402, 804, 1206, 1607, 2009, 2410, 2811,
|
||||
3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997,
|
||||
6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126,
|
||||
9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167,
|
||||
12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090,
|
||||
15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869,
|
||||
18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475,
|
||||
20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884,
|
||||
23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073,
|
||||
25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020,
|
||||
27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707,
|
||||
28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117,
|
||||
30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237,
|
||||
31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057,
|
||||
32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568,
|
||||
32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765,
|
||||
32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647,
|
||||
32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214,
|
||||
32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471,
|
||||
31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425,
|
||||
30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086,
|
||||
28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466,
|
||||
27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583,
|
||||
25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453,
|
||||
23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097,
|
||||
20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537,
|
||||
18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800,
|
||||
15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910,
|
||||
12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896,
|
||||
9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786,
|
||||
6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611,
|
||||
3211, 2811, 2410, 2009, 1607, 1206, 804, 402,
|
||||
0, -402, -804, -1206, -1607, -2009, -2410, -2811,
|
||||
-3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997,
|
||||
-6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126,
|
||||
-9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167,
|
||||
-12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090,
|
||||
-15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869,
|
||||
-18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475,
|
||||
-20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884,
|
||||
-23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073,
|
||||
-25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020,
|
||||
-27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707,
|
||||
-28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117,
|
||||
-30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237,
|
||||
-31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057,
|
||||
-32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568,
|
||||
-32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765,
|
||||
-32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647,
|
||||
-32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214,
|
||||
-32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471,
|
||||
-31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425,
|
||||
-30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086,
|
||||
-28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466,
|
||||
-27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583,
|
||||
-25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453,
|
||||
-23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097,
|
||||
-20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537,
|
||||
-18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800,
|
||||
-15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910,
|
||||
-12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896,
|
||||
-9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786,
|
||||
-6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611,
|
||||
-3211, -2811, -2410, -2009, -1607, -1206, -804, -402
|
||||
};
|
||||
|
||||
const int16 C4::CosTable[512] = {
|
||||
32767, 32765, 32758, 32745, 32728, 32706, 32679, 32647,
|
||||
32610, 32568, 32521, 32469, 32413, 32351, 32285, 32214,
|
||||
32138, 32057, 31971, 31881, 31785, 31685, 31581, 31471,
|
||||
31357, 31237, 31114, 30985, 30852, 30714, 30572, 30425,
|
||||
30273, 30117, 29956, 29791, 29621, 29447, 29269, 29086,
|
||||
28898, 28707, 28511, 28310, 28106, 27897, 27684, 27466,
|
||||
27245, 27020, 26790, 26557, 26319, 26077, 25832, 25583,
|
||||
25330, 25073, 24812, 24547, 24279, 24007, 23732, 23453,
|
||||
23170, 22884, 22594, 22301, 22005, 21706, 21403, 21097,
|
||||
20787, 20475, 20159, 19841, 19519, 19195, 18868, 18537,
|
||||
18204, 17869, 17530, 17189, 16846, 16499, 16151, 15800,
|
||||
15446, 15090, 14732, 14372, 14010, 13645, 13278, 12910,
|
||||
12539, 12167, 11793, 11416, 11039, 10659, 10278, 9896,
|
||||
9512, 9126, 8739, 8351, 7961, 7571, 7179, 6786,
|
||||
6392, 5997, 5602, 5205, 4808, 4409, 4011, 3611,
|
||||
3211, 2811, 2410, 2009, 1607, 1206, 804, 402,
|
||||
0, -402, -804, -1206, -1607, -2009, -2410, -2811,
|
||||
-3211, -3611, -4011, -4409, -4808, -5205, -5602, -5997,
|
||||
-6392, -6786, -7179, -7571, -7961, -8351, -8739, -9126,
|
||||
-9512, -9896, -10278, -10659, -11039, -11416, -11793, -12167,
|
||||
-12539, -12910, -13278, -13645, -14010, -14372, -14732, -15090,
|
||||
-15446, -15800, -16151, -16499, -16846, -17189, -17530, -17869,
|
||||
-18204, -18537, -18868, -19195, -19519, -19841, -20159, -20475,
|
||||
-20787, -21097, -21403, -21706, -22005, -22301, -22594, -22884,
|
||||
-23170, -23453, -23732, -24007, -24279, -24547, -24812, -25073,
|
||||
-25330, -25583, -25832, -26077, -26319, -26557, -26790, -27020,
|
||||
-27245, -27466, -27684, -27897, -28106, -28310, -28511, -28707,
|
||||
-28898, -29086, -29269, -29447, -29621, -29791, -29956, -30117,
|
||||
-30273, -30425, -30572, -30714, -30852, -30985, -31114, -31237,
|
||||
-31357, -31471, -31581, -31685, -31785, -31881, -31971, -32057,
|
||||
-32138, -32214, -32285, -32351, -32413, -32469, -32521, -32568,
|
||||
-32610, -32647, -32679, -32706, -32728, -32745, -32758, -32765,
|
||||
-32767, -32765, -32758, -32745, -32728, -32706, -32679, -32647,
|
||||
-32610, -32568, -32521, -32469, -32413, -32351, -32285, -32214,
|
||||
-32138, -32057, -31971, -31881, -31785, -31685, -31581, -31471,
|
||||
-31357, -31237, -31114, -30985, -30852, -30714, -30572, -30425,
|
||||
-30273, -30117, -29956, -29791, -29621, -29447, -29269, -29086,
|
||||
-28898, -28707, -28511, -28310, -28106, -27897, -27684, -27466,
|
||||
-27245, -27020, -26790, -26557, -26319, -26077, -25832, -25583,
|
||||
-25330, -25073, -24812, -24547, -24279, -24007, -23732, -23453,
|
||||
-23170, -22884, -22594, -22301, -22005, -21706, -21403, -21097,
|
||||
-20787, -20475, -20159, -19841, -19519, -19195, -18868, -18537,
|
||||
-18204, -17869, -17530, -17189, -16846, -16499, -16151, -15800,
|
||||
-15446, -15090, -14732, -14372, -14010, -13645, -13278, -12910,
|
||||
-12539, -12167, -11793, -11416, -11039, -10659, -10278, -9896,
|
||||
-9512, -9126, -8739, -8351, -7961, -7571, -7179, -6786,
|
||||
-6392, -5997, -5602, -5205, -4808, -4409, -4011, -3611,
|
||||
-3211, -2811, -2410, -2009, -1607, -1206, -804, -402,
|
||||
0, 402, 804, 1206, 1607, 2009, 2410, 2811,
|
||||
3211, 3611, 4011, 4409, 4808, 5205, 5602, 5997,
|
||||
6392, 6786, 7179, 7571, 7961, 8351, 8739, 9126,
|
||||
9512, 9896, 10278, 10659, 11039, 11416, 11793, 12167,
|
||||
12539, 12910, 13278, 13645, 14010, 14372, 14732, 15090,
|
||||
15446, 15800, 16151, 16499, 16846, 17189, 17530, 17869,
|
||||
18204, 18537, 18868, 19195, 19519, 19841, 20159, 20475,
|
||||
20787, 21097, 21403, 21706, 22005, 22301, 22594, 22884,
|
||||
23170, 23453, 23732, 24007, 24279, 24547, 24812, 25073,
|
||||
25330, 25583, 25832, 26077, 26319, 26557, 26790, 27020,
|
||||
27245, 27466, 27684, 27897, 28106, 28310, 28511, 28707,
|
||||
28898, 29086, 29269, 29447, 29621, 29791, 29956, 30117,
|
||||
30273, 30425, 30572, 30714, 30852, 30985, 31114, 31237,
|
||||
31357, 31471, 31581, 31685, 31785, 31881, 31971, 32057,
|
||||
32138, 32214, 32285, 32351, 32413, 32469, 32521, 32568,
|
||||
32610, 32647, 32679, 32706, 32728, 32745, 32758, 32765
|
||||
};
|
||||
@@ -0,0 +1,242 @@
|
||||
#include <math.h>
|
||||
#define Tan(a) (CosTable[a] ? ((((int32)SinTable[a]) << 16) / CosTable[a]) : 0x80000000)
|
||||
#define sar(b, n) ((b) >> (n))
|
||||
#ifdef PI
|
||||
#undef PI
|
||||
#endif
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
|
||||
//Wireframe Helpers
|
||||
void C4::C4TransfWireFrame() {
|
||||
c4x = (double)C4WFXVal;
|
||||
c4y = (double)C4WFYVal;
|
||||
c4z = (double)C4WFZVal - 0x95;
|
||||
|
||||
//Rotate X
|
||||
tanval = -(double)C4WFX2Val * PI * 2 / 128;
|
||||
c4y2 = c4y * ::cos(tanval) - c4z * ::sin(tanval);
|
||||
c4z2 = c4y * ::sin(tanval) + c4z * ::cos(tanval);
|
||||
|
||||
//Rotate Y
|
||||
tanval = -(double)C4WFY2Val * PI * 2 / 128;
|
||||
c4x2 = c4x * ::cos(tanval) + c4z2 * ::sin(tanval);
|
||||
c4z = c4x * -::sin(tanval) + c4z2 * ::cos(tanval);
|
||||
|
||||
//Rotate Z
|
||||
tanval = -(double)C4WFDist * PI * 2 / 128;
|
||||
c4x = c4x2 * ::cos(tanval) - c4y2 * ::sin(tanval);
|
||||
c4y = c4x2 * ::sin(tanval) + c4y2 * ::cos(tanval);
|
||||
|
||||
//Scale
|
||||
C4WFXVal = (int16)(c4x * C4WFScale / (0x90 * (c4z + 0x95)) * 0x95);
|
||||
C4WFYVal = (int16)(c4y * C4WFScale / (0x90 * (c4z + 0x95)) * 0x95);
|
||||
}
|
||||
|
||||
void C4::C4CalcWireFrame() {
|
||||
C4WFXVal = C4WFX2Val - C4WFXVal;
|
||||
C4WFYVal = C4WFY2Val - C4WFYVal;
|
||||
|
||||
if(abs(C4WFXVal) > abs(C4WFYVal)) {
|
||||
C4WFDist = abs(C4WFXVal) + 1;
|
||||
C4WFYVal = (256 * (long)C4WFYVal) / abs(C4WFXVal);
|
||||
C4WFXVal = (C4WFXVal < 0) ? -256 : 256;
|
||||
} else if(C4WFYVal != 0) {
|
||||
C4WFDist = abs(C4WFYVal) + 1;
|
||||
C4WFXVal = (256 * (long)C4WFXVal) / abs(C4WFYVal);
|
||||
C4WFYVal = (C4WFYVal < 0) ? -256 : 256;
|
||||
} else {
|
||||
C4WFDist = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void C4::C4TransfWireFrame2() {
|
||||
c4x = (double)C4WFXVal;
|
||||
c4y = (double)C4WFYVal;
|
||||
c4z = (double)C4WFZVal;
|
||||
|
||||
//Rotate X
|
||||
tanval = -(double)C4WFX2Val * PI * 2 / 128;
|
||||
c4y2 = c4y * ::cos(tanval) - c4z * ::sin(tanval);
|
||||
c4z2 = c4y * ::sin(tanval) + c4z * ::cos(tanval);
|
||||
|
||||
//Rotate Y
|
||||
tanval = -(double)C4WFY2Val * PI * 2 / 128;
|
||||
c4x2 = c4x * ::cos(tanval) + c4z2 * ::sin(tanval);
|
||||
c4z = c4x * -::sin(tanval) + c4z2 * ::cos(tanval);
|
||||
|
||||
//Rotate Z
|
||||
tanval = -(double)C4WFDist * PI * 2 / 128;
|
||||
c4x = c4x2 * ::cos(tanval) - c4y2 * ::sin(tanval);
|
||||
c4y = c4x2 * ::sin(tanval) + c4y2 * ::cos(tanval);
|
||||
|
||||
//Scale
|
||||
C4WFXVal = (int16)(c4x * C4WFScale / 0x100);
|
||||
C4WFYVal = (int16)(c4y * C4WFScale / 0x100);
|
||||
}
|
||||
|
||||
void C4::C4DrawWireFrame() {
|
||||
uint32 line = readl(0x1f80);
|
||||
uint32 point1, point2;
|
||||
int16 X1, Y1, Z1;
|
||||
int16 X2, Y2, Z2;
|
||||
uint8 Color;
|
||||
for(int32 i = ram[0x0295]; i > 0; i--, line += 5) {
|
||||
if(r_mem->read(line) == 0xff && r_mem->read(line + 1) == 0xff) {
|
||||
int32 tmp = line - 5;
|
||||
while(r_mem->read(tmp + 2) == 0xff && r_mem->read(tmp + 3) == 0xff && (tmp + 2) >= 0) { tmp -= 5; }
|
||||
point1 = (read(0x1f82) << 16) | (r_mem->read(tmp + 2) << 8) | r_mem->read(tmp + 3);
|
||||
} else {
|
||||
point1 = (read(0x1f82) << 16) | (r_mem->read(line) << 8) | r_mem->read(line + 1);
|
||||
}
|
||||
point2 = (read(0x1f82) << 16) | (r_mem->read(line + 2) << 8) | r_mem->read(line + 3);
|
||||
|
||||
X1=(r_mem->read(point1 + 0) << 8) | r_mem->read(point1 + 1);
|
||||
Y1=(r_mem->read(point1 + 2) << 8) | r_mem->read(point1 + 3);
|
||||
Z1=(r_mem->read(point1 + 4) << 8) | r_mem->read(point1 + 5);
|
||||
X2=(r_mem->read(point2 + 0) << 8) | r_mem->read(point2 + 1);
|
||||
Y2=(r_mem->read(point2 + 2) << 8) | r_mem->read(point2 + 3);
|
||||
Z2=(r_mem->read(point2 + 4) << 8) | r_mem->read(point2 + 5);
|
||||
Color = r_mem->read(line + 4);
|
||||
C4DrawLine(X1, Y1, Z1, X2, Y2, Z2, Color);
|
||||
}
|
||||
}
|
||||
|
||||
void C4::C4DrawLine(int32 X1, int32 Y1, int16 Z1, int32 X2, int32 Y2, int16 Z2, uint8 Color) {
|
||||
//Transform coordinates
|
||||
C4WFXVal = (int16)X1;
|
||||
C4WFYVal = (int16)Y1;
|
||||
C4WFZVal = Z1;
|
||||
C4WFScale = read(0x1f90);
|
||||
C4WFX2Val = read(0x1f86);
|
||||
C4WFY2Val = read(0x1f87);
|
||||
C4WFDist = read(0x1f88);
|
||||
C4TransfWireFrame2();
|
||||
X1 = (C4WFXVal + 48) << 8;
|
||||
Y1 = (C4WFYVal + 48) << 8;
|
||||
|
||||
C4WFXVal = (int16)X2;
|
||||
C4WFYVal = (int16)Y2;
|
||||
C4WFZVal = Z2;
|
||||
C4TransfWireFrame2();
|
||||
X2 = (C4WFXVal + 48) << 8;
|
||||
Y2 = (C4WFYVal + 48) << 8;
|
||||
|
||||
//Get line info
|
||||
C4WFXVal = (int16)(X1 >> 8);
|
||||
C4WFYVal = (int16)(Y1 >> 8);
|
||||
C4WFX2Val = (int16)(X2 >> 8);
|
||||
C4WFY2Val = (int16)(Y2 >> 8);
|
||||
C4CalcWireFrame();
|
||||
X2 = (int16)C4WFXVal;
|
||||
Y2 = (int16)C4WFYVal;
|
||||
|
||||
//Render line
|
||||
for(int32 i = C4WFDist ? C4WFDist : 1; i > 0; i--) {
|
||||
if(X1 > 0xff && Y1 > 0xff && X1 < 0x6000 && Y1 < 0x6000) {
|
||||
uint16 addr = (((Y1 >> 8) >> 3) << 8) - (((Y1 >> 8) >> 3) << 6) + (((X1 >> 8) >> 3) << 4) + ((Y1 >> 8) & 7) * 2;
|
||||
uint8 bit = 0x80 >> ((X1 >> 8) & 7);
|
||||
ram[addr + 0x300] &= ~bit;
|
||||
ram[addr + 0x301] &= ~bit;
|
||||
if(Color & 1) { ram[addr + 0x300] |= bit; }
|
||||
if(Color & 2) { ram[addr + 0x301] |= bit; }
|
||||
}
|
||||
X1 += X2;
|
||||
Y1 += Y2;
|
||||
}
|
||||
}
|
||||
|
||||
void C4::C4DoScaleRotate(int row_padding) {
|
||||
int16 A, B, C, D;
|
||||
|
||||
//Calculate matrix
|
||||
int32 XScale = readw(0x1f8f);
|
||||
int32 YScale = readw(0x1f92);
|
||||
if(XScale & 0x8000)XScale = 0x7fff;
|
||||
if(YScale & 0x8000)YScale = 0x7fff;
|
||||
|
||||
if(readw(0x1f80) == 0) { //no rotation
|
||||
A = (int16)XScale;
|
||||
B = 0;
|
||||
C = 0;
|
||||
D = (int16)YScale;
|
||||
} else if(readw(0x1f80) == 128) { //90 degree rotation
|
||||
A = 0;
|
||||
B = (int16)(-YScale);
|
||||
C = (int16)XScale;
|
||||
D = 0;
|
||||
} else if(readw(0x1f80) == 256) { //180 degree rotation
|
||||
A = (int16)(-XScale);
|
||||
B = 0;
|
||||
C = 0;
|
||||
D = (int16)(-YScale);
|
||||
} else if(readw(0x1f80) == 384) { //270 degree rotation
|
||||
A = 0;
|
||||
B = (int16)YScale;
|
||||
C = (int16)(-XScale);
|
||||
D = 0;
|
||||
} else {
|
||||
A = (int16) sar(CosTable[readw(0x1f80) & 0x1ff] * XScale, 15);
|
||||
B = (int16)(-sar(SinTable[readw(0x1f80) & 0x1ff] * YScale, 15));
|
||||
C = (int16) sar(SinTable[readw(0x1f80) & 0x1ff] * XScale, 15);
|
||||
D = (int16) sar(CosTable[readw(0x1f80) & 0x1ff] * YScale, 15);
|
||||
}
|
||||
|
||||
//Calculate Pixel Resolution
|
||||
uint8 w = read(0x1f89) & ~7;
|
||||
uint8 h = read(0x1f8c) & ~7;
|
||||
|
||||
//Clear the output RAM
|
||||
memset(ram, 0, (w + row_padding / 4) * h / 2);
|
||||
|
||||
int32 Cx = (int16)readw(0x1f83);
|
||||
int32 Cy = (int16)readw(0x1f86);
|
||||
|
||||
//Calculate start position (i.e. (Ox, Oy) = (0, 0))
|
||||
//The low 12 bits are fractional, so (Cx<<12) gives us the Cx we want in
|
||||
//the function. We do Cx*A etc normally because the matrix parameters
|
||||
//already have the fractional parts.
|
||||
int32 LineX = (Cx << 12) - Cx * A - Cx * B;
|
||||
int32 LineY = (Cy << 12) - Cy * C - Cy * D;
|
||||
|
||||
//Start loop
|
||||
uint32 X, Y;
|
||||
uint8 byte;
|
||||
int32 outidx = 0;
|
||||
uint8 bit = 0x80;
|
||||
for(int32 y = 0; y < h; y++) {
|
||||
X = LineX;
|
||||
Y = LineY;
|
||||
for(int32 x = 0; x < w; x++) {
|
||||
if((X >> 12) >= w || (Y >> 12) >= h) {
|
||||
byte = 0;
|
||||
} else {
|
||||
uint32 addr = (Y >> 12) * w + (X >> 12);
|
||||
byte = read(0x600 + (addr >> 1));
|
||||
if(addr & 1) { byte >>= 4; }
|
||||
}
|
||||
|
||||
//De-bitplanify
|
||||
if(byte & 1) { ram[outidx ] |= bit; }
|
||||
if(byte & 2) { ram[outidx + 1] |= bit; }
|
||||
if(byte & 4) { ram[outidx + 16] |= bit; }
|
||||
if(byte & 8) { ram[outidx + 17] |= bit; }
|
||||
|
||||
bit >>= 1;
|
||||
if(!bit) {
|
||||
bit = 0x80;
|
||||
outidx += 32;
|
||||
}
|
||||
|
||||
X += A; //Add 1 to output x => add an A and a C
|
||||
Y += C;
|
||||
}
|
||||
outidx += 2 + row_padding;
|
||||
if(outidx & 0x10) {
|
||||
outidx &= ~0x10;
|
||||
} else {
|
||||
outidx -= w * 4 + row_padding;
|
||||
}
|
||||
LineX += B; //Add 1 to output y => add a B and a D
|
||||
LineY += D;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,219 @@
|
||||
//Build OAM
|
||||
void C4::op00_00() {
|
||||
uint32 oamptr = ram[0x626] << 2;
|
||||
for(int32 i = 0x1fd; i > oamptr && i >= 0; i -= 4) {
|
||||
//clear oam-to-be
|
||||
if(i >= 0)ram[i] = 0xe0;
|
||||
}
|
||||
|
||||
uint16 globalx, globaly;
|
||||
uint32 oamptr2;
|
||||
int16 sprx, spry;
|
||||
uint8 sprname, sprattr;
|
||||
uint8 sprcount;
|
||||
globalx = readw(0x621);
|
||||
globaly = readw(0x623);
|
||||
oamptr2 = 0x200 + (ram[0x626] >> 2);
|
||||
|
||||
if(!ram[0x620])return;
|
||||
|
||||
sprcount = 128 - ram[0x626];
|
||||
uint8 offset = (ram[0x626] & 3) * 2;
|
||||
uint32 srcptr = 0x220;
|
||||
for(int i = ram[0x620]; i > 0 && sprcount > 0; i--, srcptr += 16) {
|
||||
sprx = readw(srcptr) - globalx;
|
||||
spry = readw(srcptr + 2) - globaly;
|
||||
sprname = ram[srcptr + 5];
|
||||
sprattr = ram[srcptr + 4] | ram[srcptr + 6];
|
||||
|
||||
uint32 spraddr = readl(srcptr + 7);
|
||||
if(r_mem->read(spraddr)) {
|
||||
int16 x, y;
|
||||
for(int sprcnt = r_mem->read(spraddr++); sprcnt > 0 && sprcount > 0; sprcnt--, spraddr += 4) {
|
||||
x = (int8)r_mem->read(spraddr + 1);
|
||||
if(sprattr & 0x40) {
|
||||
x = -x - ((r_mem->read(spraddr) & 0x20) ? 16 : 8);
|
||||
}
|
||||
x += sprx;
|
||||
if(x >= -16 && x <= 272) {
|
||||
y = (int8)r_mem->read(spraddr + 2);
|
||||
if(sprattr & 0x80) {
|
||||
y = -y - ((r_mem->read(spraddr) & 0x20) ? 16 : 8);
|
||||
}
|
||||
y += spry;
|
||||
if(y >= -16 && y <= 224) {
|
||||
ram[oamptr ] = (uint8)x;
|
||||
ram[oamptr + 1] = (uint8)y;
|
||||
ram[oamptr + 2] = sprname + r_mem->read(spraddr + 3);
|
||||
ram[oamptr + 3] = sprattr ^ (r_mem->read(spraddr) & 0xc0);
|
||||
ram[oamptr2] &= ~(3 << offset);
|
||||
if(x & 0x100)ram[oamptr2] |= 1 << offset;
|
||||
if(r_mem->read(spraddr) & 0x20)ram[oamptr2] |= 2 << offset;
|
||||
oamptr += 4;
|
||||
sprcount--;
|
||||
offset = (offset + 2) & 6;
|
||||
if(!offset)oamptr2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if(sprcount > 0) {
|
||||
ram[oamptr ] = (uint8)sprx;
|
||||
ram[oamptr + 1] = (uint8)spry;
|
||||
ram[oamptr + 2] = sprname;
|
||||
ram[oamptr + 3] = sprattr;
|
||||
ram[oamptr2] &= ~(3 << offset);
|
||||
if(sprx & 0x100)ram[oamptr2] |= 3 << offset;
|
||||
else ram[oamptr2] |= 2 << offset;
|
||||
oamptr += 4;
|
||||
sprcount--;
|
||||
offset = (offset + 2) & 6;
|
||||
if(!offset)oamptr2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Scale and Rotate
|
||||
void C4::op00_03() {
|
||||
C4DoScaleRotate(0);
|
||||
}
|
||||
|
||||
//Transform Lines
|
||||
void C4::op00_05() {
|
||||
C4WFX2Val = read(0x1f83);
|
||||
C4WFY2Val = read(0x1f86);
|
||||
C4WFDist = read(0x1f89);
|
||||
C4WFScale = read(0x1f8c);
|
||||
|
||||
//Transform Vertices
|
||||
uint32 ptr = 0;
|
||||
for(int32 i = readw(0x1f80); i > 0; i--, ptr += 0x10) {
|
||||
C4WFXVal = readw(ptr + 1);
|
||||
C4WFYVal = readw(ptr + 5);
|
||||
C4WFZVal = readw(ptr + 9);
|
||||
C4TransfWireFrame();
|
||||
|
||||
//Displace
|
||||
writew(ptr + 1, C4WFXVal + 0x80);
|
||||
writew(ptr + 5, C4WFYVal + 0x50);
|
||||
}
|
||||
|
||||
writew(0x600, 23);
|
||||
writew(0x602, 0x60);
|
||||
writew(0x605, 0x40);
|
||||
writew(0x600 + 8, 23);
|
||||
writew(0x602 + 8, 0x60);
|
||||
writew(0x605 + 8, 0x40);
|
||||
|
||||
ptr = 0xb02;
|
||||
uint32 ptr2 = 0;
|
||||
for(int32 i = readw(0xb00); i > 0; i--, ptr += 2, ptr2 += 8) {
|
||||
C4WFXVal = readw((read(ptr + 0) << 4) + 1);
|
||||
C4WFYVal = readw((read(ptr + 0) << 4) + 5);
|
||||
C4WFX2Val = readw((read(ptr + 1) << 4) + 1);
|
||||
C4WFY2Val = readw((read(ptr + 1) << 4) + 5);
|
||||
C4CalcWireFrame();
|
||||
writew(ptr2 + 0x600, C4WFDist ? C4WFDist : 1);
|
||||
writew(ptr2 + 0x602, C4WFXVal);
|
||||
writew(ptr2 + 0x605, C4WFYVal);
|
||||
}
|
||||
}
|
||||
|
||||
//Scale and Rotate
|
||||
void C4::op00_07() {
|
||||
C4DoScaleRotate(64);
|
||||
}
|
||||
|
||||
//Draw Wireframe
|
||||
void C4::op00_08() {
|
||||
C4DrawWireFrame();
|
||||
}
|
||||
|
||||
//Disintegrate
|
||||
void C4::op00_0b() {
|
||||
uint8 width, height;
|
||||
uint32 startx, starty;
|
||||
uint32 srcptr;
|
||||
uint32 x, y;
|
||||
int32 scalex, scaley;
|
||||
int32 cx, cy;
|
||||
int32 i, j;
|
||||
width = read(0x1f89);
|
||||
height = read(0x1f8c);
|
||||
cx = readw(0x1f80);
|
||||
cy = readw(0x1f83);
|
||||
|
||||
scalex = (int16)readw(0x1f86);
|
||||
scaley = (int16)readw(0x1f8f);
|
||||
startx = -cx * scalex + (cx << 8);
|
||||
starty = -cy * scaley + (cy << 8);
|
||||
srcptr = 0x600;
|
||||
|
||||
for(i = 0; i < (width * height) >> 1; i++) {
|
||||
write(i, 0);
|
||||
}
|
||||
|
||||
for(y = starty, i = 0;i < height; i++, y += scaley) {
|
||||
for(x = startx, j = 0;j < width; j++, x += scalex) {
|
||||
if((x >> 8) < width && (y >> 8) < height && (y >> 8) * width + (x >> 8) < 0x2000) {
|
||||
uint8 pixel = (j & 1) ? (ram[srcptr] >> 4) : (ram[srcptr]);
|
||||
int32 index = (y >> 11) * width * 4 + (x >> 11) * 32 + ((y >> 8) & 7) * 2;
|
||||
uint8 mask = 0x80 >> ((x >> 8) & 7);
|
||||
if(pixel & 1)ram[index ] |= mask;
|
||||
if(pixel & 2)ram[index + 1] |= mask;
|
||||
if(pixel & 4)ram[index + 16] |= mask;
|
||||
if(pixel & 8)ram[index + 17] |= mask;
|
||||
}
|
||||
if(j & 1)srcptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Bitplane Wave
|
||||
void C4::op00_0c() {
|
||||
uint32 destptr = 0;
|
||||
uint32 waveptr = read(0x1f83);
|
||||
uint16 mask1 = 0xc0c0;
|
||||
uint16 mask2 = 0x3f3f;
|
||||
|
||||
for(int j = 0; j < 0x10; j++) {
|
||||
do {
|
||||
int16 height = -((int8)read(waveptr + 0xb00)) - 16;
|
||||
for(int i = 0; i < 40; i++) {
|
||||
uint16 temp = readw(destptr + wave_data[i]) & mask2;
|
||||
if(height >= 0) {
|
||||
if(height < 8) {
|
||||
temp |= mask1 & readw(0xa00 + height * 2);
|
||||
} else {
|
||||
temp |= mask1 & 0xff00;
|
||||
}
|
||||
}
|
||||
writew(destptr + wave_data[i], temp);
|
||||
height++;
|
||||
}
|
||||
waveptr = (waveptr + 1) & 0x7f;
|
||||
mask1 = (mask1 >> 2) | (mask1 << 6);
|
||||
mask2 = (mask2 >> 2) | (mask2 << 6);
|
||||
} while(mask1 != 0xc0c0);
|
||||
destptr += 16;
|
||||
|
||||
do {
|
||||
int16 height = -((int8)read(waveptr + 0xb00)) - 16;
|
||||
for(int i = 0; i < 40; i++) {
|
||||
uint16 temp = readw(destptr + wave_data[i]) & mask2;
|
||||
if(height >= 0) {
|
||||
if(height < 8) {
|
||||
temp |= mask1 & readw(0xa10 + height * 2);
|
||||
} else {
|
||||
temp |= mask1 & 0xff00;
|
||||
}
|
||||
}
|
||||
writew(destptr + wave_data[i], temp);
|
||||
height++;
|
||||
}
|
||||
waveptr = (waveptr + 1) & 0x7f;
|
||||
mask1 = (mask1 >> 2) | (mask1 << 6);
|
||||
mask2 = (mask2 >> 2) | (mask2 << 6);
|
||||
} while(mask1 != 0xc0c0);
|
||||
destptr += 16;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
//Sprite Functions
|
||||
void C4::op00() {
|
||||
switch(reg[0x4d]) {
|
||||
case 0x00:op00_00();break;
|
||||
case 0x03:op00_03();break;
|
||||
case 0x05:op00_05();break;
|
||||
case 0x07:op00_07();break;
|
||||
case 0x08:op00_08();break;
|
||||
case 0x0b:op00_0b();break;
|
||||
case 0x0c:op00_0c();break;
|
||||
}
|
||||
}
|
||||
|
||||
//Draw Wireframe
|
||||
void C4::op01() {
|
||||
memset(ram + 0x300, 0, 2304);
|
||||
C4DrawWireFrame();
|
||||
}
|
||||
|
||||
//Propulsion
|
||||
void C4::op05() {
|
||||
int32 temp = 0x10000;
|
||||
if(readw(0x1f83)) {
|
||||
temp = sar((temp / readw(0x1f83)) * readw(0x1f81), 8);
|
||||
}
|
||||
writew(0x1f80, temp);
|
||||
}
|
||||
|
||||
//Set Vector length
|
||||
void C4::op0d() {
|
||||
C41FXVal = readw(0x1f80);
|
||||
C41FYVal = readw(0x1f83);
|
||||
C41FDistVal = readw(0x1f86);
|
||||
tanval = sqrt(((double)C41FYVal) * ((double)C41FYVal) + ((double)C41FXVal) * ((double)C41FXVal));
|
||||
tanval = (double)C41FDistVal / tanval;
|
||||
C41FYVal = (int16)(((double)C41FYVal * tanval) * 0.99);
|
||||
C41FXVal = (int16)(((double)C41FXVal * tanval) * 0.98);
|
||||
writew(0x1f89, C41FXVal);
|
||||
writew(0x1f8c, C41FYVal);
|
||||
}
|
||||
|
||||
//Triangle
|
||||
void C4::op10() {
|
||||
r0 = ldr(0);
|
||||
r1 = ldr(1);
|
||||
|
||||
r4 = r0 & 0x1ff;
|
||||
if(r1 & 0x8000)r1 |= ~0x7fff;
|
||||
|
||||
mul(cos(r4), r1, r5, r2);
|
||||
r5 = (r5 >> 16) & 0xff;
|
||||
r2 = (r2 << 8) + r5;
|
||||
|
||||
mul(sin(r4), r1, r5, r3);
|
||||
r5 = (r5 >> 16) & 0xff;
|
||||
r3 = (r3 << 8) + r5;
|
||||
|
||||
str(0, r0);
|
||||
str(1, r1);
|
||||
str(2, r2);
|
||||
str(3, r3);
|
||||
str(4, r4);
|
||||
str(5, r5);
|
||||
}
|
||||
|
||||
//Triangle
|
||||
void C4::op13() {
|
||||
r0 = ldr(0);
|
||||
r1 = ldr(1);
|
||||
|
||||
r4 = r0 & 0x1ff;
|
||||
|
||||
mul(cos(r4), r1, r5, r2);
|
||||
r5 = (r5 >> 8) & 0xffff;
|
||||
r2 = (r2 << 16) + r5;
|
||||
|
||||
mul(sin(r4), r1, r5, r3);
|
||||
r5 = (r5 >> 8) & 0xffff;
|
||||
r3 = (r3 << 16) + r5;
|
||||
|
||||
str(0, r0);
|
||||
str(1, r1);
|
||||
str(2, r2);
|
||||
str(3, r3);
|
||||
str(4, r4);
|
||||
str(5, r5);
|
||||
}
|
||||
|
||||
//Pythagorean
|
||||
void C4::op15() {
|
||||
C41FXVal = readw(0x1f80);
|
||||
C41FYVal = readw(0x1f83);
|
||||
C41FDist = (int16)sqrt((double)C41FXVal * (double)C41FXVal + (double)C41FYVal * (double)C41FYVal);
|
||||
writew(0x1f80, C41FDist);
|
||||
}
|
||||
|
||||
//Calculate distance
|
||||
void C4::op1f() {
|
||||
C41FXVal = readw(0x1f80);
|
||||
C41FYVal = readw(0x1f83);
|
||||
if(!C41FXVal) {
|
||||
C41FAngleRes = (C41FYVal > 0) ? 0x080 : 0x180;
|
||||
} else {
|
||||
tanval = ((double)C41FYVal) / ((double)C41FXVal);
|
||||
C41FAngleRes = (short)(atan(tanval) / (PI * 2) * 512);
|
||||
C41FAngleRes = C41FAngleRes;
|
||||
if(C41FXVal < 0) {
|
||||
C41FAngleRes += 0x100;
|
||||
}
|
||||
C41FAngleRes &= 0x1ff;
|
||||
}
|
||||
writew(0x1f86, C41FAngleRes);
|
||||
}
|
||||
|
||||
//Trapezoid
|
||||
void C4::op22() {
|
||||
int16 angle1 = readw(0x1f8c) & 0x1ff;
|
||||
int16 angle2 = readw(0x1f8f) & 0x1ff;
|
||||
int32 tan1 = Tan(angle1);
|
||||
int32 tan2 = Tan(angle2);
|
||||
int16 y = readw(0x1f83) - readw(0x1f89);
|
||||
int16 left, right;
|
||||
for(int32 j = 0; j < 225; j++, y++) {
|
||||
if(y >= 0) {
|
||||
left = sar((int32)tan1 * y, 16) - readw(0x1f80) + readw(0x1f86);
|
||||
right = sar((int32)tan2 * y, 16) - readw(0x1f80) + readw(0x1f86) + readw(0x1f93);
|
||||
|
||||
if(left < 0 && right < 0) {
|
||||
left = 1;
|
||||
right = 0;
|
||||
} else if(left < 0) {
|
||||
left = 0;
|
||||
} else if(right < 0) {
|
||||
right = 0;
|
||||
}
|
||||
|
||||
if(left > 255 && right > 255) {
|
||||
left = 255;
|
||||
right = 254;
|
||||
} else if(left > 255) {
|
||||
left = 255;
|
||||
} else if(right > 255) {
|
||||
right = 255;
|
||||
}
|
||||
} else {
|
||||
left = 1;
|
||||
right = 0;
|
||||
}
|
||||
ram[j + 0x800] = (uint8)left;
|
||||
ram[j + 0x900] = (uint8)right;
|
||||
}
|
||||
}
|
||||
|
||||
//Multiply
|
||||
void C4::op25() {
|
||||
r0 = ldr(0);
|
||||
r1 = ldr(1);
|
||||
mul(r0, r1, r0, r1);
|
||||
str(0, r0);
|
||||
str(1, r1);
|
||||
}
|
||||
|
||||
//Transform Coords
|
||||
void C4::op2d() {
|
||||
C4WFXVal = readw(0x1f81);
|
||||
C4WFYVal = readw(0x1f84);
|
||||
C4WFZVal = readw(0x1f87);
|
||||
C4WFX2Val = read (0x1f89);
|
||||
C4WFY2Val = read (0x1f8a);
|
||||
C4WFDist = read (0x1f8b);
|
||||
C4WFScale = readw(0x1f90);
|
||||
C4TransfWireFrame2();
|
||||
writew(0x1f80, C4WFXVal);
|
||||
writew(0x1f83, C4WFYVal);
|
||||
}
|
||||
|
||||
//Sum
|
||||
void C4::op40() {
|
||||
r0 = 0;
|
||||
for(uint32 i=0;i<0x800;i++) {
|
||||
r0 += ram[i];
|
||||
}
|
||||
str(0, r0);
|
||||
}
|
||||
|
||||
//Square
|
||||
void C4::op54() {
|
||||
r0 = ldr(0);
|
||||
mul(r0, r0, r1, r2);
|
||||
str(1, r1);
|
||||
str(2, r2);
|
||||
}
|
||||
|
||||
//Immediate Register
|
||||
void C4::op5c() {
|
||||
str(0, 0x000000);
|
||||
immediate_reg(0);
|
||||
}
|
||||
|
||||
//Immediate Register (Multiple)
|
||||
void C4::op5e() { immediate_reg( 0); }
|
||||
void C4::op60() { immediate_reg( 3); }
|
||||
void C4::op62() { immediate_reg( 6); }
|
||||
void C4::op64() { immediate_reg( 9); }
|
||||
void C4::op66() { immediate_reg(12); }
|
||||
void C4::op68() { immediate_reg(15); }
|
||||
void C4::op6a() { immediate_reg(18); }
|
||||
void C4::op6c() { immediate_reg(21); }
|
||||
void C4::op6e() { immediate_reg(24); }
|
||||
void C4::op70() { immediate_reg(27); }
|
||||
void C4::op72() { immediate_reg(30); }
|
||||
void C4::op74() { immediate_reg(33); }
|
||||
void C4::op76() { immediate_reg(36); }
|
||||
void C4::op78() { immediate_reg(39); }
|
||||
void C4::op7a() { immediate_reg(42); }
|
||||
void C4::op7c() { immediate_reg(45); }
|
||||
|
||||
//Immediate ROM
|
||||
void C4::op89() {
|
||||
str(0, 0x054336);
|
||||
str(1, 0xffffff);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "../../base.h"
|
||||
|
||||
DSP1 *dsp1;
|
||||
|
||||
#include "dsp1emu.cpp"
|
||||
|
||||
void DSP1::init() {}
|
||||
void DSP1::enable() {}
|
||||
|
||||
void DSP1::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void DSP1::reset() {
|
||||
dsp1.reset();
|
||||
}
|
||||
|
||||
/*****
|
||||
* addr_decode()
|
||||
* determine whether address is accessing
|
||||
* data register (DR) or status register (SR)
|
||||
* -- 0 (false) = DR
|
||||
* -- 1 (true ) = SR
|
||||
*
|
||||
* note: there is no need to bounds check addresses,
|
||||
* as memory mapper will not allow DSP1 accesses outside
|
||||
* of expected ranges
|
||||
*****/
|
||||
bool DSP1::addr_decode(uint16 addr) {
|
||||
switch(cartridge.info.dsp1_mapper) {
|
||||
|
||||
case Cartridge::DSP1_LOROM_1MB:
|
||||
//$[20-3f]:[8000-bfff] = DR, $[20-3f]:[c000-ffff] = SR
|
||||
return (addr >= 0xc000);
|
||||
|
||||
case Cartridge::DSP1_LOROM_2MB:
|
||||
//$[60-6f]:[0000-3fff] = DR, $[60-6f]:[4000-7fff] = SR
|
||||
return (addr >= 0x4000);
|
||||
|
||||
case Cartridge::DSP1_HIROM:
|
||||
//$[00-1f]:[6000-6fff] = DR, $[00-1f]:[7000-7fff] = SR
|
||||
return (addr >= 0x7000);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 DSP1::read(uint16 addr) {
|
||||
return (addr_decode(addr) == 0) ? dsp1.getDr() : dsp1.getSr();
|
||||
}
|
||||
|
||||
void DSP1::write(uint16 addr, uint8 data) {
|
||||
if(addr_decode(addr) == 0) {
|
||||
dsp1.setDr(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "dsp1emu.h"
|
||||
|
||||
class DSP1 {
|
||||
private:
|
||||
Dsp1 dsp1;
|
||||
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
bool addr_decode(uint16 addr);
|
||||
uint8 read (uint16 addr);
|
||||
void write(uint16 addr, uint8 data);
|
||||
};
|
||||
|
||||
extern DSP1 *dsp1;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,127 @@
|
||||
// DSP-1's emulation code
|
||||
//
|
||||
// Based on research by Overload, The Dumper, Neviksti and Andreas Naive
|
||||
// Date: June 2006
|
||||
|
||||
#ifndef __DSP1EMUL_H
|
||||
#define __DSP1EMUL_H
|
||||
|
||||
#define DSP1_VERSION 0x0102
|
||||
|
||||
class Dsp1
|
||||
{
|
||||
public:
|
||||
// The DSP-1 status register has 16 bits, but only
|
||||
// the upper 8 bits can be accessed from an external device, so all these
|
||||
// positions are referred to the upper byte (bits D8 to D15)
|
||||
enum SrFlags {DRC=0x04, DRS=0x10, RQM=0x80};
|
||||
|
||||
// According to Overload's docs, these are the meanings of the flags:
|
||||
// DRC: The Data Register Control (DRC) bit specifies the data transfer length to and from the host CPU.
|
||||
// 0: Data transfer to and from the DSP-1 is 16 bits.
|
||||
// 1: Data transfer to and from the DSP-1 is 8 bits.
|
||||
// DRS: The Data Register Status (DRS) bit indicates the data transfer status in the case of transfering 16-bit data.
|
||||
// 0: Data transfer has terminated.
|
||||
// 1: Data transfer in progress.
|
||||
// RQM: The Request for Master (RQM) indicates that the DSP1 is requesting host CPU for data read/write.
|
||||
// 0: Internal Data Register Transfer.
|
||||
// 1: External Data Register Transfer.
|
||||
|
||||
Dsp1();
|
||||
uint8 getSr(); // return the status register's high byte
|
||||
uint8 getDr();
|
||||
void setDr(uint8 iDr);
|
||||
void reset();
|
||||
|
||||
private:
|
||||
enum FsmMajorState {WAIT_COMMAND, READ_DATA, WRITE_DATA};
|
||||
enum MaxDataAccesses {MAX_READS=7, MAX_WRITES=1024};
|
||||
|
||||
struct Command {
|
||||
void (Dsp1::*callback)(int16 *, int16 *);
|
||||
unsigned int reads;
|
||||
unsigned int writes;
|
||||
};
|
||||
|
||||
static const Command mCommandTable[];
|
||||
static const int16 MaxAZS_Exp[16];
|
||||
static const int16 SinTable[];
|
||||
static const int16 MulTable[];
|
||||
static const uint16 DataRom[];
|
||||
|
||||
struct SharedData { // some RAM variables shared between commands
|
||||
int16 MatrixA[3][3]; // attitude matrix A
|
||||
int16 MatrixB[3][3];
|
||||
int16 MatrixC[3][3];
|
||||
int16 CentreX, CentreY, CentreZ; // center of projection
|
||||
int16 CentreZ_C, CentreZ_E;
|
||||
int16 VOffset; // vertical offset of the screen with regard to the centre of projection
|
||||
int16 Les, C_Les, E_Les;
|
||||
int16 SinAas, CosAas;
|
||||
int16 SinAzs, CosAzs;
|
||||
int16 SinAZS, CosAZS;
|
||||
int16 SecAZS_C1, SecAZS_E1;
|
||||
int16 SecAZS_C2, SecAZS_E2;
|
||||
int16 Nx, Ny, Nz; // normal vector to the screen (norm 1, points toward the center of projection)
|
||||
int16 Gx, Gy, Gz; // center of the screen (global coordinates)
|
||||
int16 Hx, Hy; // horizontal vector of the screen (Hz=0, norm 1, points toward the right of the screen)
|
||||
int16 Vx, Vy, Vz; // vertical vector of the screen (norm 1, points toward the top of the screen)
|
||||
|
||||
} shared;
|
||||
|
||||
uint8 mSr; // status register
|
||||
int mSrLowByteAccess;
|
||||
uint16 mDr; // "internal" representation of the data register
|
||||
FsmMajorState mFsmMajorState; // current major state of the FSM
|
||||
uint8 mCommand; // current command processed by the FSM
|
||||
uint8 mDataCounter; // #uint16 read/writes counter used by the FSM
|
||||
int16 mReadBuffer[MAX_READS];
|
||||
int16 mWriteBuffer[MAX_WRITES];
|
||||
bool mFreeze; // need explanation? ;)
|
||||
|
||||
void fsmStep(bool read, uint8 &data); // FSM logic
|
||||
|
||||
// commands
|
||||
void memoryTest(int16 *input, int16 *output);
|
||||
void memoryDump(int16 *input, int16 *output);
|
||||
void memorySize(int16 *input, int16 *output);
|
||||
void multiply(int16* input, int16* output);
|
||||
void multiply2(int16* input, int16* output);
|
||||
void inverse(int16 *input, int16 *output);
|
||||
void triangle(int16 *input, int16 *output);
|
||||
void radius(int16 *input, int16 *output);
|
||||
void range(int16 *input, int16 *output);
|
||||
void range2(int16 *input, int16 *output);
|
||||
void distance(int16 *input, int16 *output);
|
||||
void rotate(int16 *input, int16 *output);
|
||||
void polar(int16 *input, int16 *output);
|
||||
void attitudeA(int16 *input, int16 *output);
|
||||
void attitudeB(int16 *input, int16 *output);
|
||||
void attitudeC(int16 *input, int16 *output);
|
||||
void objectiveA(int16 *input, int16 *output);
|
||||
void objectiveB(int16 *input, int16 *output);
|
||||
void objectiveC(int16 *input, int16 *output);
|
||||
void subjectiveA(int16 *input, int16 *output);
|
||||
void subjectiveB(int16 *input, int16 *output);
|
||||
void subjectiveC(int16 *input, int16 *output);
|
||||
void scalarA(int16 *input, int16 *output);
|
||||
void scalarB(int16 *input, int16 *output);
|
||||
void scalarC(int16 *input, int16 *output);
|
||||
void gyrate(int16 *input, int16 *output);
|
||||
void parameter(int16 *input, int16 *output);
|
||||
void raster(int16 *input, int16 *output);
|
||||
void target(int16 *input, int16 *output);
|
||||
void project(int16 *input, int16 *output);
|
||||
|
||||
// auxiliar functions
|
||||
int16 sin(int16 Angle);
|
||||
int16 cos(int16 Angle);
|
||||
void inverse(int16 Coefficient, int16 Exponent, int16 &iCoefficient, int16 &iExponent);
|
||||
int16 denormalizeAndClip(int16 C, int16 E);
|
||||
void normalize(int16 m, int16 &Coefficient, int16 &Exponent);
|
||||
void normalizeDouble(int32 Product, int16 &Coefficient, int16 &Exponent);
|
||||
int16 shiftR(int16 C, int16 E);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,136 @@
|
||||
#include "../../base.h"
|
||||
|
||||
DSP2 *dsp2;
|
||||
|
||||
#include "dsp2_op.cpp"
|
||||
|
||||
void DSP2::init() {}
|
||||
void DSP2::enable() {}
|
||||
|
||||
void DSP2::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void DSP2::reset() {
|
||||
status.waiting_for_command = true;
|
||||
status.in_count = 0;
|
||||
status.in_index = 0;
|
||||
status.out_count = 0;
|
||||
status.out_index = 0;
|
||||
|
||||
status.op05transparent = 0;
|
||||
status.op05haslen = false;
|
||||
status.op05len = 0;
|
||||
status.op06haslen = false;
|
||||
status.op06len = 0;
|
||||
status.op09word1 = 0;
|
||||
status.op09word2 = 0;
|
||||
status.op0dhaslen = false;
|
||||
status.op0doutlen = 0;
|
||||
status.op0dinlen = 0;
|
||||
}
|
||||
|
||||
uint8 DSP2::read(uint16 addr) {
|
||||
uint8 r = 0xff;
|
||||
if(status.out_count) {
|
||||
r = status.output[status.out_index++];
|
||||
status.out_index &= 511;
|
||||
if(status.out_count == status.out_index) {
|
||||
status.out_count = 0;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void DSP2::write(uint16 addr, uint8 data) {
|
||||
if(status.waiting_for_command) {
|
||||
status.command = data;
|
||||
status.in_index = 0;
|
||||
status.waiting_for_command = false;
|
||||
|
||||
switch(data) {
|
||||
case 0x01: status.in_count = 32; break;
|
||||
case 0x03: status.in_count = 1; break;
|
||||
case 0x05: status.in_count = 1; break;
|
||||
case 0x06: status.in_count = 1; break;
|
||||
case 0x07: break;
|
||||
case 0x08: break;
|
||||
case 0x09: status.in_count = 4; break;
|
||||
case 0x0d: status.in_count = 2; break;
|
||||
case 0x0f: status.in_count = 0; break;
|
||||
}
|
||||
} else {
|
||||
status.parameters[status.in_index++] = data;
|
||||
status.in_index &= 511;
|
||||
}
|
||||
|
||||
if(status.in_count == status.in_index) {
|
||||
status.waiting_for_command = true;
|
||||
status.out_index = 0;
|
||||
switch(status.command) {
|
||||
case 0x01: {
|
||||
status.out_count = 32;
|
||||
op01();
|
||||
} break;
|
||||
|
||||
case 0x03: {
|
||||
op03();
|
||||
} break;
|
||||
|
||||
case 0x05: {
|
||||
if(status.op05haslen) {
|
||||
status.op05haslen = false;
|
||||
status.out_count = status.op05len;
|
||||
op05();
|
||||
} else {
|
||||
status.op05len = status.parameters[0];
|
||||
status.in_index = 0;
|
||||
status.in_count = status.op05len * 2;
|
||||
status.op05haslen = true;
|
||||
if(data)status.waiting_for_command = false;
|
||||
}
|
||||
} break;
|
||||
|
||||
case 0x06: {
|
||||
if(status.op06haslen) {
|
||||
status.op06haslen = false;
|
||||
status.out_count = status.op06len;
|
||||
op06();
|
||||
} else {
|
||||
status.op06len = status.parameters[0];
|
||||
status.in_index = 0;
|
||||
status.in_count = status.op06len;
|
||||
status.op06haslen = true;
|
||||
if(data)status.waiting_for_command = false;
|
||||
}
|
||||
} break;
|
||||
|
||||
case 0x07: break;
|
||||
case 0x08: break;
|
||||
|
||||
case 0x09: {
|
||||
op09();
|
||||
} break;
|
||||
|
||||
case 0x0d: {
|
||||
if(status.op0dhaslen) {
|
||||
status.op0dhaslen = false;
|
||||
status.out_count = status.op0doutlen;
|
||||
op0d();
|
||||
} else {
|
||||
status.op0dinlen = status.parameters[0];
|
||||
status.op0doutlen = status.parameters[1];
|
||||
status.in_index = 0;
|
||||
status.in_count = (status.op0dinlen + 1) >> 1;
|
||||
status.op0dhaslen = true;
|
||||
if(data)status.waiting_for_command = false;
|
||||
}
|
||||
} break;
|
||||
|
||||
case 0x0f: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DSP2::DSP2() {}
|
||||
DSP2::~DSP2() {}
|
||||
@@ -0,0 +1,43 @@
|
||||
class DSP2 {
|
||||
public:
|
||||
struct {
|
||||
bool waiting_for_command;
|
||||
uint command;
|
||||
uint in_count, in_index;
|
||||
uint out_count, out_index;
|
||||
|
||||
uint8 parameters[512];
|
||||
uint8 output[512];
|
||||
|
||||
uint8 op05transparent;
|
||||
bool op05haslen;
|
||||
int op05len;
|
||||
bool op06haslen;
|
||||
int op06len;
|
||||
uint16 op09word1;
|
||||
uint16 op09word2;
|
||||
bool op0dhaslen;
|
||||
int op0doutlen;
|
||||
int op0dinlen;
|
||||
} status;
|
||||
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
void op01();
|
||||
void op03();
|
||||
void op05();
|
||||
void op06();
|
||||
void op09();
|
||||
void op0d();
|
||||
|
||||
uint8 read (uint16 addr);
|
||||
void write(uint16 addr, uint8 data);
|
||||
|
||||
DSP2();
|
||||
~DSP2();
|
||||
};
|
||||
|
||||
extern DSP2 *dsp2;
|
||||
@@ -0,0 +1,173 @@
|
||||
//convert bitmap to bitplane tile
|
||||
void DSP2::op01() {
|
||||
//op01 size is always 32 bytes input and output
|
||||
//the hardware does strange things if you vary the size
|
||||
|
||||
unsigned char c0, c1, c2, c3;
|
||||
unsigned char *p1 = status.parameters;
|
||||
unsigned char *p2a = status.output;
|
||||
unsigned char *p2b = status.output + 16; //halfway
|
||||
|
||||
//process 8 blocks of 4 bytes each
|
||||
for(int j = 0; j < 8; j++) {
|
||||
c0 = *p1++;
|
||||
c1 = *p1++;
|
||||
c2 = *p1++;
|
||||
c3 = *p1++;
|
||||
|
||||
*p2a++ = (c0 & 0x10) << 3 |
|
||||
(c0 & 0x01) << 6 |
|
||||
(c1 & 0x10) << 1 |
|
||||
(c1 & 0x01) << 4 |
|
||||
(c2 & 0x10) >> 1 |
|
||||
(c2 & 0x01) << 2 |
|
||||
(c3 & 0x10) >> 3 |
|
||||
(c3 & 0x01);
|
||||
|
||||
*p2a++ = (c0 & 0x20) << 2 |
|
||||
(c0 & 0x02) << 5 |
|
||||
(c1 & 0x20) |
|
||||
(c1 & 0x02) << 3 |
|
||||
(c2 & 0x20) >> 2 |
|
||||
(c2 & 0x02) << 1 |
|
||||
(c3 & 0x20) >> 4 |
|
||||
(c3 & 0x02) >> 1;
|
||||
|
||||
*p2b++ = (c0 & 0x40) << 1 |
|
||||
(c0 & 0x04) << 4 |
|
||||
(c1 & 0x40) >> 1 |
|
||||
(c1 & 0x04) << 2 |
|
||||
(c2 & 0x40) >> 3 |
|
||||
(c2 & 0x04) |
|
||||
(c3 & 0x40) >> 5 |
|
||||
(c3 & 0x04) >> 2;
|
||||
|
||||
*p2b++ = (c0 & 0x80) |
|
||||
(c0 & 0x08) << 3 |
|
||||
(c1 & 0x80) >> 2 |
|
||||
(c1 & 0x08) << 1 |
|
||||
(c2 & 0x80) >> 4 |
|
||||
(c2 & 0x08) >> 1 |
|
||||
(c3 & 0x80) >> 6 |
|
||||
(c3 & 0x08) >> 3;
|
||||
}
|
||||
}
|
||||
|
||||
//set transparent color
|
||||
void DSP2::op03() {
|
||||
status.op05transparent = status.parameters[0];
|
||||
}
|
||||
|
||||
//replace bitmap using transparent color
|
||||
void DSP2::op05() {
|
||||
uint8 color;
|
||||
// Overlay bitmap with transparency.
|
||||
// Input:
|
||||
//
|
||||
// Bitmap 1: i[0] <=> i[size-1]
|
||||
// Bitmap 2: i[size] <=> i[2*size-1]
|
||||
//
|
||||
// Output:
|
||||
//
|
||||
// Bitmap 3: o[0] <=> o[size-1]
|
||||
//
|
||||
// Processing:
|
||||
//
|
||||
// Process all 4-bit pixels (nibbles) in the bitmap
|
||||
//
|
||||
// if ( BM2_pixel == transparent_color )
|
||||
// pixelout = BM1_pixel
|
||||
// else
|
||||
// pixelout = BM2_pixel
|
||||
|
||||
// The max size bitmap is limited to 255 because the size parameter is a byte
|
||||
// I think size=0 is an error. The behavior of the chip on size=0 is to
|
||||
// return the last value written to DR if you read DR on Op05 with
|
||||
// size = 0. I don't think it's worth implementing this quirk unless it's
|
||||
// proven necessary.
|
||||
|
||||
unsigned char c1, c2;
|
||||
unsigned char *p1 = status.parameters;
|
||||
unsigned char *p2 = status.parameters + status.op05len;
|
||||
unsigned char *p3 = status.output;
|
||||
|
||||
color = status.op05transparent & 0x0f;
|
||||
|
||||
for(int n = 0; n < status.op05len; n++) {
|
||||
c1 = *p1++;
|
||||
c2 = *p2++;
|
||||
*p3++ = ( ((c2 >> 4) == color ) ? c1 & 0xf0 : c2 & 0xf0 ) |
|
||||
( ((c2 & 0x0f) == color ) ? c1 & 0x0f : c2 & 0x0f );
|
||||
}
|
||||
}
|
||||
|
||||
//reverse bitmap
|
||||
void DSP2::op06() {
|
||||
// Input:
|
||||
// size
|
||||
// bitmap
|
||||
|
||||
int i, j;
|
||||
for(i = 0, j = status.op06len - 1; i < status.op06len; i++, j--) {
|
||||
status.output[j] = (status.parameters[i] << 4) | (status.parameters[i] >> 4);
|
||||
}
|
||||
}
|
||||
|
||||
//multiply
|
||||
void DSP2::op09() {
|
||||
status.out_count = 4;
|
||||
|
||||
status.op09word1 = status.parameters[0] | (status.parameters[1] << 8);
|
||||
status.op09word2 = status.parameters[2] | (status.parameters[3] << 8);
|
||||
|
||||
uint32 r;
|
||||
r = status.op09word1 * status.op09word2;
|
||||
status.output[0] = r;
|
||||
status.output[1] = r >> 8;
|
||||
status.output[2] = r >> 16;
|
||||
status.output[3] = r >> 24;
|
||||
}
|
||||
|
||||
//scale bitmap
|
||||
void DSP2::op0d() {
|
||||
// Bit accurate hardware algorithm - uses fixed point math
|
||||
// This should match the DSP2 Op0D output exactly
|
||||
// I wouldn't recommend using this unless you're doing hardware debug.
|
||||
// In some situations it has small visual artifacts that
|
||||
// are not readily apparent on a TV screen but show up clearly
|
||||
// on a monitor. Use Overload's scaling instead.
|
||||
// This is for hardware verification testing.
|
||||
//
|
||||
// One note: the HW can do odd byte scaling but since we divide
|
||||
// by two to get the count of bytes this won't work well for
|
||||
// odd byte scaling (in any of the current algorithm implementations).
|
||||
// So far I haven't seen Dungeon Master use it.
|
||||
// If it does we can adjust the parameters and code to work with it
|
||||
|
||||
uint32 multiplier; // Any size int >= 32-bits
|
||||
uint32 pixloc; // match size of multiplier
|
||||
int i, j;
|
||||
uint8 pixelarray[512];
|
||||
if(status.op0dinlen <= status.op0doutlen) {
|
||||
multiplier = 0x10000; // In our self defined fixed point 0x10000 == 1
|
||||
} else {
|
||||
multiplier = (status.op0dinlen << 17) / ((status.op0doutlen << 1) + 1);
|
||||
}
|
||||
|
||||
pixloc = 0;
|
||||
for(i = 0; i < status.op0doutlen * 2; i++) {
|
||||
j = pixloc >> 16;
|
||||
|
||||
if(j & 1) {
|
||||
pixelarray[i] = (status.parameters[j >> 1] & 0x0f);
|
||||
} else {
|
||||
pixelarray[i] = (status.parameters[j >> 1] & 0xf0) >> 4;
|
||||
}
|
||||
|
||||
pixloc += multiplier;
|
||||
}
|
||||
|
||||
for(i = 0; i < status.op0doutlen; i++) {
|
||||
status.output[i] = (pixelarray[i << 1] << 4) | pixelarray[(i << 1) + 1];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
#include "../../base.h"
|
||||
|
||||
OBC1 *obc1;
|
||||
|
||||
void OBC1::init() {}
|
||||
void OBC1::enable() {}
|
||||
|
||||
void OBC1::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void OBC1::reset() {
|
||||
memset(cartridge.ram, 0xff, 0x2000);
|
||||
status.baseptr = (cartridge.ram[0x1ff5] & 1) ? 0x1800 : 0x1c00;
|
||||
status.address = (cartridge.ram[0x1ff6] & 0x7f);
|
||||
status.shift = (cartridge.ram[0x1ff6] & 3) << 1;
|
||||
}
|
||||
|
||||
uint8 OBC1::read(uint16 addr) {
|
||||
addr &= 0x1fff;
|
||||
|
||||
if((addr & 0x1ff8) != 0x1ff0) {
|
||||
return cartridge.ram[addr];
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x1ff0:
|
||||
return cartridge.ram[status.baseptr + (status.address << 2) + 0];
|
||||
case 0x1ff1:
|
||||
return cartridge.ram[status.baseptr + (status.address << 2) + 1];
|
||||
case 0x1ff2:
|
||||
return cartridge.ram[status.baseptr + (status.address << 2) + 2];
|
||||
case 0x1ff3:
|
||||
return cartridge.ram[status.baseptr + (status.address << 2) + 3];
|
||||
case 0x1ff4:
|
||||
return cartridge.ram[status.baseptr + (status.address >> 2) + 0x200];
|
||||
case 0x1ff5:
|
||||
case 0x1ff6:
|
||||
case 0x1ff7:
|
||||
return cartridge.ram[addr];
|
||||
}
|
||||
|
||||
//never used, blocks compiler warning
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void OBC1::write(uint16 addr, uint8 data) {
|
||||
addr &= 0x1fff;
|
||||
|
||||
if((addr & 0x1ff8) != 0x1ff0) {
|
||||
cartridge.ram[addr] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x1ff0:
|
||||
cartridge.ram[status.baseptr + (status.address << 2) + 0] = data;
|
||||
break;
|
||||
case 0x1ff1:
|
||||
cartridge.ram[status.baseptr + (status.address << 2) + 1] = data;
|
||||
break;
|
||||
case 0x1ff2:
|
||||
cartridge.ram[status.baseptr + (status.address << 2) + 2] = data;
|
||||
break;
|
||||
case 0x1ff3:
|
||||
cartridge.ram[status.baseptr + (status.address << 2) + 3] = data;
|
||||
break;
|
||||
case 0x1ff4: {
|
||||
uint8 temp;
|
||||
temp = cartridge.ram[status.baseptr + (status.address >> 2) + 0x200];
|
||||
temp = (temp & ~(3 << status.shift)) | ((data & 3) << status.shift);
|
||||
cartridge.ram[status.baseptr + (status.address >> 2) + 0x200] = temp;
|
||||
} break;
|
||||
case 0x1ff5:
|
||||
status.baseptr = (data & 1) ? 0x1800 : 0x1c00;
|
||||
cartridge.ram[addr] = data;
|
||||
break;
|
||||
case 0x1ff6:
|
||||
status.address = (data & 0x7f);
|
||||
status.shift = (data & 3) << 1;
|
||||
cartridge.ram[addr] = data;
|
||||
break;
|
||||
case 0x1ff7:
|
||||
cartridge.ram[addr] = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OBC1::OBC1() {}
|
||||
OBC1::~OBC1() {}
|
||||
@@ -0,0 +1,20 @@
|
||||
class OBC1 {
|
||||
public:
|
||||
struct {
|
||||
uint16 address;
|
||||
uint16 baseptr;
|
||||
uint16 shift;
|
||||
} status;
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 read (uint16 addr);
|
||||
void write(uint16 addr, uint8 data);
|
||||
|
||||
OBC1();
|
||||
~OBC1();
|
||||
};
|
||||
|
||||
extern OBC1 *obc1;
|
||||
@@ -0,0 +1,94 @@
|
||||
#include "../../base.h"
|
||||
|
||||
SDD1 *sdd1;
|
||||
|
||||
#include "sdd1emu.cpp"
|
||||
|
||||
void SDD1::init() {}
|
||||
|
||||
void SDD1::enable() {
|
||||
for(int i = 0x4800; i <= 0x4807; i++) {
|
||||
r_mem->set_mmio_mapper(i, this);
|
||||
}
|
||||
}
|
||||
|
||||
void SDD1::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void SDD1::reset() {
|
||||
sdd1.index[0] = 0x000000;
|
||||
sdd1.index[1] = 0x100000;
|
||||
sdd1.index[2] = 0x200000;
|
||||
sdd1.index[3] = 0x300000;
|
||||
|
||||
for(int i=0;i<8;i++) {
|
||||
sdd1.active[i] = false;
|
||||
}
|
||||
|
||||
sdd1.dma_active = false;
|
||||
}
|
||||
|
||||
uint32 SDD1::offset(uint32 addr) {
|
||||
uint8 b = (addr >> 16) & 0xff;
|
||||
if(b <= 0xbf)return 0;
|
||||
|
||||
b -= 0xc0; //b = 0x00-0x3f
|
||||
b >>= 4; //b = 0-3
|
||||
b &= 3; //bitmask
|
||||
|
||||
return sdd1.index[b] + (addr & 0x0fffff);
|
||||
}
|
||||
|
||||
uint8 SDD1::mmio_read(uint16 addr) {
|
||||
switch(addr) {
|
||||
//>>20 == 0x100000 == 1mb
|
||||
case 0x4804: return (sdd1.index[0] >> 20) & 7;
|
||||
case 0x4805: return (sdd1.index[1] >> 20) & 7;
|
||||
case 0x4806: return (sdd1.index[2] >> 20) & 7;
|
||||
case 0x4807: return (sdd1.index[3] >> 20) & 7;
|
||||
}
|
||||
|
||||
return r_cpu->regs.mdr;
|
||||
}
|
||||
|
||||
void SDD1::mmio_write(uint16 addr, uint8 data) {
|
||||
switch(addr) {
|
||||
case 0x4801:
|
||||
for(int i = 0; i < 8; i++) {
|
||||
sdd1.active[i] = !!(data & (1 << i));
|
||||
}
|
||||
break;
|
||||
//<<20 == 0x100000 == 1mb
|
||||
case 0x4804: sdd1.index[0] = (data & 7) << 20; break;
|
||||
case 0x4805: sdd1.index[1] = (data & 7) << 20; break;
|
||||
case 0x4806: sdd1.index[2] = (data & 7) << 20; break;
|
||||
case 0x4807: sdd1.index[3] = (data & 7) << 20; break;
|
||||
}
|
||||
}
|
||||
|
||||
void SDD1::dma_begin(uint8 channel, uint32 addr, uint16 length) {
|
||||
if(sdd1.active[channel] == true) {
|
||||
sdd1.active[channel] = false;
|
||||
sdd1.dma_active = true;
|
||||
sdd1.buffer_index = 0;
|
||||
sdd1.buffer_size = length;
|
||||
sdd1emu.decompress(addr, (length) ? length : 65536, sdd1.buffer);
|
||||
}
|
||||
}
|
||||
|
||||
bool SDD1::dma_active() {
|
||||
return sdd1.dma_active;
|
||||
}
|
||||
|
||||
uint8 SDD1::dma_read() {
|
||||
if(--sdd1.buffer_size == 0) {
|
||||
sdd1.dma_active = false;
|
||||
}
|
||||
|
||||
//sdd1.buffer[] is 65536 bytes, and sdd1.buffer_index
|
||||
//is of type uint16, so no buffer overflow is possible
|
||||
return sdd1.buffer[sdd1.buffer_index++];
|
||||
}
|
||||
|
||||
SDD1::SDD1() {}
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "sdd1emu.h"
|
||||
|
||||
class SDD1 : public MMIO {
|
||||
public:
|
||||
SDD1emu sdd1emu;
|
||||
|
||||
struct {
|
||||
uint32 index[4]; //memory mapping registers
|
||||
uint8 buffer[65536]; //pointer to decompressed S-DD1 data,
|
||||
//max. DMA length is 65536
|
||||
uint16 buffer_index; //DMA read index into S-DD1 decompression buffer
|
||||
uint16 buffer_size;
|
||||
bool active[8]; //true when DMA channel should pass through S-DD1
|
||||
bool dma_active;
|
||||
} sdd1;
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
uint32 offset(uint32 addr);
|
||||
|
||||
void dma_begin(uint8 channel, uint32 addr, uint16 length);
|
||||
bool dma_active();
|
||||
uint8 dma_read();
|
||||
|
||||
uint8 mmio_read (uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
|
||||
SDD1();
|
||||
};
|
||||
|
||||
extern SDD1 *sdd1;
|
||||
@@ -0,0 +1,447 @@
|
||||
/************************************************************************
|
||||
|
||||
S-DD1'algorithm emulation code
|
||||
------------------------------
|
||||
|
||||
Author: Andreas Naive
|
||||
Date: August 2003
|
||||
Last update: October 2004
|
||||
|
||||
This code is Public Domain. There is no copyright holded by the author.
|
||||
Said this, the author wish to explicitly emphasize his inalienable moral rights
|
||||
over this piece of intelectual work and the previous research that made it
|
||||
possible, as recognized by most of the copyright laws around the world.
|
||||
|
||||
This code is provided 'as-is', with no warranty, expressed or implied.
|
||||
No responsability is assumed by the author in connection with it.
|
||||
|
||||
The author is greatly indebted with The Dumper, without whose help and
|
||||
patience providing him with real S-DD1 data the research would have never been
|
||||
possible. He also wish to note that in the very beggining of his research,
|
||||
Neviksti had done some steps in the right direction. By last, the author is
|
||||
indirectly indebted to all the people that worked and contributed in the
|
||||
S-DD1 issue in the past.
|
||||
|
||||
An algorithm's documentation is available as a separate document.
|
||||
The implementation is obvious when the algorithm is
|
||||
understood.
|
||||
|
||||
************************************************************************/
|
||||
|
||||
#define SDD1_read(__addr) (r_mem->read(__addr))
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void SDD1_IM::prepareDecomp(uint32 in_buf) {
|
||||
|
||||
byte_ptr=in_buf;
|
||||
bit_count=4;
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
|
||||
uint8 SDD1_IM::getCodeword(uint8 code_len) {
|
||||
|
||||
uint8 codeword;
|
||||
uint8 comp_count;
|
||||
|
||||
codeword = (SDD1_read(byte_ptr))<<bit_count;
|
||||
|
||||
++bit_count;
|
||||
|
||||
if (codeword & 0x80) {
|
||||
codeword |= SDD1_read(byte_ptr+1)>>(9-bit_count);
|
||||
bit_count+=code_len;
|
||||
}
|
||||
|
||||
if (bit_count & 0x08) {
|
||||
byte_ptr++;
|
||||
bit_count&=0x07;
|
||||
}
|
||||
|
||||
return codeword;
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
|
||||
SDD1_GCD::SDD1_GCD(SDD1_IM *associatedIM) :
|
||||
IM(associatedIM)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void SDD1_GCD::getRunCount(uint8 code_num, uint8 *MPScount, bool8 *LPSind) {
|
||||
|
||||
const uint8 run_count[] = {
|
||||
0x00, 0x00, 0x01, 0x00, 0x03, 0x01, 0x02, 0x00,
|
||||
0x07, 0x03, 0x05, 0x01, 0x06, 0x02, 0x04, 0x00,
|
||||
0x0f, 0x07, 0x0b, 0x03, 0x0d, 0x05, 0x09, 0x01,
|
||||
0x0e, 0x06, 0x0a, 0x02, 0x0c, 0x04, 0x08, 0x00,
|
||||
0x1f, 0x0f, 0x17, 0x07, 0x1b, 0x0b, 0x13, 0x03,
|
||||
0x1d, 0x0d, 0x15, 0x05, 0x19, 0x09, 0x11, 0x01,
|
||||
0x1e, 0x0e, 0x16, 0x06, 0x1a, 0x0a, 0x12, 0x02,
|
||||
0x1c, 0x0c, 0x14, 0x04, 0x18, 0x08, 0x10, 0x00,
|
||||
0x3f, 0x1f, 0x2f, 0x0f, 0x37, 0x17, 0x27, 0x07,
|
||||
0x3b, 0x1b, 0x2b, 0x0b, 0x33, 0x13, 0x23, 0x03,
|
||||
0x3d, 0x1d, 0x2d, 0x0d, 0x35, 0x15, 0x25, 0x05,
|
||||
0x39, 0x19, 0x29, 0x09, 0x31, 0x11, 0x21, 0x01,
|
||||
0x3e, 0x1e, 0x2e, 0x0e, 0x36, 0x16, 0x26, 0x06,
|
||||
0x3a, 0x1a, 0x2a, 0x0a, 0x32, 0x12, 0x22, 0x02,
|
||||
0x3c, 0x1c, 0x2c, 0x0c, 0x34, 0x14, 0x24, 0x04,
|
||||
0x38, 0x18, 0x28, 0x08, 0x30, 0x10, 0x20, 0x00,
|
||||
0x7f, 0x3f, 0x5f, 0x1f, 0x6f, 0x2f, 0x4f, 0x0f,
|
||||
0x77, 0x37, 0x57, 0x17, 0x67, 0x27, 0x47, 0x07,
|
||||
0x7b, 0x3b, 0x5b, 0x1b, 0x6b, 0x2b, 0x4b, 0x0b,
|
||||
0x73, 0x33, 0x53, 0x13, 0x63, 0x23, 0x43, 0x03,
|
||||
0x7d, 0x3d, 0x5d, 0x1d, 0x6d, 0x2d, 0x4d, 0x0d,
|
||||
0x75, 0x35, 0x55, 0x15, 0x65, 0x25, 0x45, 0x05,
|
||||
0x79, 0x39, 0x59, 0x19, 0x69, 0x29, 0x49, 0x09,
|
||||
0x71, 0x31, 0x51, 0x11, 0x61, 0x21, 0x41, 0x01,
|
||||
0x7e, 0x3e, 0x5e, 0x1e, 0x6e, 0x2e, 0x4e, 0x0e,
|
||||
0x76, 0x36, 0x56, 0x16, 0x66, 0x26, 0x46, 0x06,
|
||||
0x7a, 0x3a, 0x5a, 0x1a, 0x6a, 0x2a, 0x4a, 0x0a,
|
||||
0x72, 0x32, 0x52, 0x12, 0x62, 0x22, 0x42, 0x02,
|
||||
0x7c, 0x3c, 0x5c, 0x1c, 0x6c, 0x2c, 0x4c, 0x0c,
|
||||
0x74, 0x34, 0x54, 0x14, 0x64, 0x24, 0x44, 0x04,
|
||||
0x78, 0x38, 0x58, 0x18, 0x68, 0x28, 0x48, 0x08,
|
||||
0x70, 0x30, 0x50, 0x10, 0x60, 0x20, 0x40, 0x00,
|
||||
};
|
||||
|
||||
uint8 codeword=IM->getCodeword(code_num);
|
||||
|
||||
if (codeword & 0x80) {
|
||||
*LPSind=1;
|
||||
*MPScount=run_count[codeword>>(code_num^0x07)];
|
||||
}
|
||||
else {
|
||||
*MPScount=(1<<code_num);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
SDD1_BG::SDD1_BG(SDD1_GCD *associatedGCD, uint8 code) :
|
||||
GCD(associatedGCD), code_num(code)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
|
||||
void SDD1_BG::prepareDecomp(void) {
|
||||
|
||||
MPScount=0;
|
||||
LPSind=0;
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
||||
|
||||
uint8 SDD1_BG::getBit(bool8 *endOfRun) {
|
||||
|
||||
uint8 bit;
|
||||
|
||||
if (!(MPScount || LPSind)) GCD->getRunCount(code_num, &MPScount, &LPSind);
|
||||
|
||||
if (MPScount) {
|
||||
bit=0;
|
||||
MPScount--;
|
||||
}
|
||||
else {
|
||||
bit=1;
|
||||
LPSind=0;
|
||||
}
|
||||
|
||||
if (MPScount || LPSind) (*endOfRun)=0;
|
||||
else (*endOfRun)=1;
|
||||
|
||||
return bit;
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
|
||||
SDD1_PEM::SDD1_PEM(SDD1_BG *associatedBG0, SDD1_BG *associatedBG1,
|
||||
SDD1_BG *associatedBG2, SDD1_BG *associatedBG3,
|
||||
SDD1_BG *associatedBG4, SDD1_BG *associatedBG5,
|
||||
SDD1_BG *associatedBG6, SDD1_BG *associatedBG7) {
|
||||
|
||||
BG[0]=associatedBG0;
|
||||
BG[1]=associatedBG1;
|
||||
BG[2]=associatedBG2;
|
||||
BG[3]=associatedBG3;
|
||||
BG[4]=associatedBG4;
|
||||
BG[5]=associatedBG5;
|
||||
BG[6]=associatedBG6;
|
||||
BG[7]=associatedBG7;
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
const SDD1_PEM::state SDD1_PEM::evolution_table[]={
|
||||
{ 0,25,25},
|
||||
{ 0, 2, 1},
|
||||
{ 0, 3, 1},
|
||||
{ 0, 4, 2},
|
||||
{ 0, 5, 3},
|
||||
{ 1, 6, 4},
|
||||
{ 1, 7, 5},
|
||||
{ 1, 8, 6},
|
||||
{ 1, 9, 7},
|
||||
{ 2,10, 8},
|
||||
{ 2,11, 9},
|
||||
{ 2,12,10},
|
||||
{ 2,13,11},
|
||||
{ 3,14,12},
|
||||
{ 3,15,13},
|
||||
{ 3,16,14},
|
||||
{ 3,17,15},
|
||||
{ 4,18,16},
|
||||
{ 4,19,17},
|
||||
{ 5,20,18},
|
||||
{ 5,21,19},
|
||||
{ 6,22,20},
|
||||
{ 6,23,21},
|
||||
{ 7,24,22},
|
||||
{ 7,24,23},
|
||||
{ 0,26, 1},
|
||||
{ 1,27, 2},
|
||||
{ 2,28, 4},
|
||||
{ 3,29, 8},
|
||||
{ 4,30,12},
|
||||
{ 5,31,16},
|
||||
{ 6,32,18},
|
||||
{ 7,24,22}
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void SDD1_PEM::prepareDecomp(void) {
|
||||
|
||||
for (uint8 i=0; i<32; i++) {
|
||||
contextInfo[i].status=0;
|
||||
contextInfo[i].MPS=0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
uint8 SDD1_PEM::getBit(uint8 context) {
|
||||
|
||||
bool8 endOfRun;
|
||||
uint8 bit;
|
||||
|
||||
SDD1_ContextInfo *pContInfo=&contextInfo[context];
|
||||
uint8 currStatus = pContInfo->status;
|
||||
const state *pState=&SDD1_PEM::evolution_table[currStatus];
|
||||
uint8 currentMPS=pContInfo->MPS;
|
||||
|
||||
bit=(BG[pState->code_num])->getBit(&endOfRun);
|
||||
|
||||
if (endOfRun)
|
||||
if (bit) {
|
||||
if (!(currStatus & 0xfe)) (pContInfo->MPS)^=0x01;
|
||||
(pContInfo->status)=pState->nextIfLPS;
|
||||
}
|
||||
else
|
||||
(pContInfo->status)=pState->nextIfMPS;
|
||||
|
||||
return bit^currentMPS;
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
SDD1_CM::SDD1_CM(SDD1_PEM *associatedPEM) :
|
||||
PEM(associatedPEM)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void SDD1_CM::prepareDecomp(uint32 first_byte) {
|
||||
|
||||
bitplanesInfo = SDD1_read(first_byte) & 0xc0;
|
||||
contextBitsInfo = SDD1_read(first_byte) & 0x30;
|
||||
bit_number=0;
|
||||
for (int i=0; i<8; i++) prevBitplaneBits[i]=0;
|
||||
switch (bitplanesInfo) {
|
||||
case 0x00:
|
||||
currBitplane = 1;
|
||||
break;
|
||||
case 0x40:
|
||||
currBitplane = 7;
|
||||
break;
|
||||
case 0x80:
|
||||
currBitplane = 3;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
uint8 SDD1_CM::getBit(void) {
|
||||
|
||||
uint8 currContext;
|
||||
uint16 *context_bits;
|
||||
|
||||
switch (bitplanesInfo) {
|
||||
case 0x00:
|
||||
currBitplane ^= 0x01;
|
||||
break;
|
||||
case 0x40:
|
||||
currBitplane ^= 0x01;
|
||||
if (!(bit_number & 0x7f)) currBitplane = ((currBitplane+2) & 0x07);
|
||||
break;
|
||||
case 0x80:
|
||||
currBitplane ^= 0x01;
|
||||
if (!(bit_number & 0x7f)) currBitplane ^= 0x02;
|
||||
break;
|
||||
case 0xc0:
|
||||
currBitplane = bit_number & 0x07;
|
||||
}
|
||||
|
||||
context_bits = &prevBitplaneBits[currBitplane];
|
||||
|
||||
currContext=(currBitplane & 0x01)<<4;
|
||||
switch (contextBitsInfo) {
|
||||
case 0x00:
|
||||
currContext|=((*context_bits & 0x01c0)>>5)|(*context_bits & 0x0001);
|
||||
break;
|
||||
case 0x10:
|
||||
currContext|=((*context_bits & 0x0180)>>5)|(*context_bits & 0x0001);
|
||||
break;
|
||||
case 0x20:
|
||||
currContext|=((*context_bits & 0x00c0)>>5)|(*context_bits & 0x0001);
|
||||
break;
|
||||
case 0x30:
|
||||
currContext|=((*context_bits & 0x0180)>>5)|(*context_bits & 0x0003);
|
||||
}
|
||||
|
||||
uint8 bit=PEM->getBit(currContext);
|
||||
|
||||
*context_bits <<= 1;
|
||||
*context_bits |= bit;
|
||||
|
||||
bit_number++;
|
||||
|
||||
return bit;
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
|
||||
SDD1_OL::SDD1_OL(SDD1_CM *associatedCM) :
|
||||
CM(associatedCM)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
|
||||
void SDD1_OL::prepareDecomp(uint32 first_byte, uint16 out_len, uint8 *out_buf) {
|
||||
|
||||
bitplanesInfo = SDD1_read(first_byte) & 0xc0;
|
||||
length=out_len;
|
||||
buffer=out_buf;
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
|
||||
void SDD1_OL::launch(void) {
|
||||
|
||||
uint8 i;
|
||||
uint8 register1, register2;
|
||||
|
||||
switch (bitplanesInfo) {
|
||||
case 0x00:
|
||||
case 0x40:
|
||||
case 0x80:
|
||||
i=1;
|
||||
do { //if length==0, we output 2^16 bytes
|
||||
if (!i) {
|
||||
*(buffer++)=register2;
|
||||
i=~i;
|
||||
}
|
||||
else {
|
||||
for (register1=register2=0, i=0x80; i; i>>=1) {
|
||||
if (CM->getBit()) register1 |= i;
|
||||
if (CM->getBit()) register2 |= i;
|
||||
}
|
||||
*(buffer++)=register1;
|
||||
}
|
||||
} while (--length);
|
||||
break;
|
||||
case 0xc0:
|
||||
do {
|
||||
for (register1=0, i=0x01; i; i<<=1) {
|
||||
if (CM->getBit()) register1 |= i;
|
||||
}
|
||||
*(buffer++)=register1;
|
||||
} while (--length);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void SDD1emu::decompress(uint32 in_buf, uint16 out_len, uint8 *out_buf) {
|
||||
|
||||
IM.prepareDecomp(in_buf);
|
||||
BG0.prepareDecomp();
|
||||
BG1.prepareDecomp();
|
||||
BG2.prepareDecomp();
|
||||
BG3.prepareDecomp();
|
||||
BG4.prepareDecomp();
|
||||
BG5.prepareDecomp();
|
||||
BG6.prepareDecomp();
|
||||
BG7.prepareDecomp();
|
||||
PEM.prepareDecomp();
|
||||
CM.prepareDecomp(in_buf);
|
||||
OL.prepareDecomp(in_buf, out_len, out_buf);
|
||||
|
||||
OL.launch();
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
SDD1emu::SDD1emu() :
|
||||
GCD(&IM),
|
||||
BG0(&GCD, 0), BG1(&GCD, 1), BG2(&GCD, 2), BG3(&GCD, 3),
|
||||
BG4(&GCD, 4), BG5(&GCD, 5), BG6(&GCD, 6), BG7(&GCD, 7),
|
||||
PEM(&BG0, &BG1, &BG2, &BG3, &BG4, &BG5, &BG6, &BG7),
|
||||
CM(&PEM),
|
||||
OL(&CM)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
@@ -0,0 +1,162 @@
|
||||
/************************************************************************
|
||||
|
||||
S-DD1'algorithm emulation code
|
||||
------------------------------
|
||||
|
||||
Author: Andreas Naive
|
||||
Date: August 2003
|
||||
Last update: October 2004
|
||||
|
||||
This code is Public Domain. There is no copyright holded by the author.
|
||||
Said this, the author wish to explicitly emphasize his inalienable moral rights
|
||||
over this piece of intelectual work and the previous research that made it
|
||||
possible, as recognized by most of the copyright laws around the world.
|
||||
|
||||
This code is provided 'as-is', with no warranty, expressed or implied.
|
||||
No responsability is assumed by the author in connection with it.
|
||||
|
||||
The author is greatly indebted with The Dumper, without whose help and
|
||||
patience providing him with real S-DD1 data the research would have never been
|
||||
possible. He also wish to note that in the very beggining of his research,
|
||||
Neviksti had done some steps in the right direction. By last, the author is
|
||||
indirectly indebted to all the people that worked and contributed in the
|
||||
S-DD1 issue in the past.
|
||||
|
||||
An algorithm's documentation is available as a separate document.
|
||||
The implementation is obvious when the algorithm is
|
||||
understood.
|
||||
|
||||
************************************************************************/
|
||||
|
||||
typedef uint8_t bool8;
|
||||
|
||||
class SDD1_IM { //Input Manager
|
||||
|
||||
public:
|
||||
SDD1_IM(void) {}
|
||||
void prepareDecomp(uint32 in_buf);
|
||||
uint8 getCodeword(const uint8 code_len);
|
||||
|
||||
private:
|
||||
uint32 byte_ptr;
|
||||
uint8 bit_count;
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class SDD1_GCD { //Golomb-Code Decoder
|
||||
|
||||
public:
|
||||
SDD1_GCD(SDD1_IM *associatedIM);
|
||||
void getRunCount(uint8 code_num, uint8 *MPScount, bool8 *LPSind);
|
||||
|
||||
private:
|
||||
SDD1_IM *const IM;
|
||||
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class SDD1_BG { // Bits Generator
|
||||
|
||||
public:
|
||||
SDD1_BG(SDD1_GCD *associatedGCD, uint8 code);
|
||||
void prepareDecomp(void);
|
||||
uint8 getBit(bool8 *endOfRun);
|
||||
|
||||
private:
|
||||
const uint8 code_num;
|
||||
uint8 MPScount;
|
||||
bool8 LPSind;
|
||||
SDD1_GCD *const GCD;
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////
|
||||
|
||||
|
||||
class SDD1_PEM { //Probability Estimation Module
|
||||
|
||||
public:
|
||||
SDD1_PEM(SDD1_BG *associatedBG0, SDD1_BG *associatedBG1,
|
||||
SDD1_BG *associatedBG2, SDD1_BG *associatedBG3,
|
||||
SDD1_BG *associatedBG4, SDD1_BG *associatedBG5,
|
||||
SDD1_BG *associatedBG6, SDD1_BG *associatedBG7);
|
||||
void prepareDecomp(void);
|
||||
uint8 getBit(uint8 context);
|
||||
|
||||
private:
|
||||
struct state {
|
||||
uint8 code_num;
|
||||
uint8 nextIfMPS;
|
||||
uint8 nextIfLPS;
|
||||
};
|
||||
static const state evolution_table[];
|
||||
struct SDD1_ContextInfo {
|
||||
uint8 status;
|
||||
uint8 MPS;
|
||||
} contextInfo[32];
|
||||
SDD1_BG * BG[8];
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
|
||||
class SDD1_CM { //Context Model
|
||||
|
||||
public:
|
||||
SDD1_CM(SDD1_PEM *associatedPEM);
|
||||
void prepareDecomp(uint32 first_byte);
|
||||
uint8 getBit(void);
|
||||
|
||||
private:
|
||||
uint8 bitplanesInfo;
|
||||
uint8 contextBitsInfo;
|
||||
uint8 bit_number;
|
||||
uint8 currBitplane;
|
||||
uint16 prevBitplaneBits[8];
|
||||
SDD1_PEM *const PEM;
|
||||
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
|
||||
class SDD1_OL { //Output Logic
|
||||
|
||||
public:
|
||||
SDD1_OL(SDD1_CM *associatedCM);
|
||||
void prepareDecomp(uint32 first_byte, uint16 out_len, uint8 *out_buf);
|
||||
void launch(void);
|
||||
|
||||
private:
|
||||
uint8 bitplanesInfo;
|
||||
uint16 length;
|
||||
uint8 *buffer;
|
||||
SDD1_CM *const CM;
|
||||
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class SDD1emu {
|
||||
|
||||
public:
|
||||
SDD1emu(void);
|
||||
void decompress(uint32 in_buf, uint16 out_len, uint8 *out_buf);
|
||||
|
||||
private:
|
||||
SDD1_IM IM;
|
||||
SDD1_GCD GCD;
|
||||
SDD1_BG BG0; SDD1_BG BG1; SDD1_BG BG2; SDD1_BG BG3;
|
||||
SDD1_BG BG4; SDD1_BG BG5; SDD1_BG BG6; SDD1_BG BG7;
|
||||
SDD1_PEM PEM;
|
||||
SDD1_CM CM;
|
||||
SDD1_OL OL;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
S-RTC chip emulation
|
||||
Used by Hudson Soft in Dai Kaijuu Monogatari II and Far East of Eden Zero.
|
||||
Currently, only the former is supported by bsnes.
|
||||
|
||||
Original S-RTC emulation code via John Weidman/SNES9x
|
||||
Rewritten for compatibility with bsnes via byuu
|
||||
|
||||
The S-RTC is a real-time clock chip that was added to the above two carts
|
||||
to allow the games to maintain the current time, even when the game was not
|
||||
powered on. Thus allowing special events at certain times, and on certain
|
||||
dates. Hudson Soft called this the PLG (Player's Life Gameplay System).
|
||||
|
||||
This chip is a special case to the term 'emulation' itself.
|
||||
There are a few different ways to go about emulating this chip, and each
|
||||
result in a different style of emulation.
|
||||
|
||||
The first is to simply return the current PC system time when the S-RTC is
|
||||
read from. This emulates the original S-RTC in the sense that it always
|
||||
returns the true current time, ignoring the speed that the SNES itself is
|
||||
running at. The downside to this method is that you lose the ability to set
|
||||
the time to whatever you choose inside the game itself. It will always return
|
||||
the true time, regardless. This can be overcome by changing the PC system time,
|
||||
which actually adds a greater degree of control over event timing, very useful
|
||||
for emulation. It also has a timeshifting flaw discussed below.
|
||||
|
||||
The second is to run the S-RTC relative to the SNES speed. This means that
|
||||
if the emulator is sped up (via fast forward key, frameskipping, etc), or
|
||||
slowed down (via slowdown key, system bottlenecking, etc); the time increments
|
||||
slower, thus ~60 frames on the SNES equal one second. Without this, timeshifting
|
||||
will occur between the S-RTC and the real SNES.
|
||||
|
||||
The third and final method is to save a copy of the local system time when the
|
||||
S-RTC is initially set, and compare the current system time against this value
|
||||
when setting the S-RTC time. This overcomes the first methods' shortcoming of
|
||||
not allowing the player to set the time in-game, however a new problem arises.
|
||||
You now have to save the time when the RTC was initially set to both savestates
|
||||
and to save-game data. This would require an extra file, or the breaking of
|
||||
perhaps the only standard format (.srm savegame backups) in the entire SNES
|
||||
emulation scene. You also give up the control of being able to override the
|
||||
RTC clock at will via the PC system time outside of emulation.
|
||||
The first method has another advantage over the third: Dai Kaijuu Monogatari II
|
||||
only allows dates in the range of the years 1996-2199. The first method gets
|
||||
around this limitation. But who knows, maybe it will break something in the
|
||||
game if the date exceeds 2199... I guess we'll worry about that in two hundred
|
||||
years from now.
|
||||
|
||||
For my implementation, I chose to go with the first method. Both for simplicity
|
||||
and because I did not wish to create a new method for saving the system time
|
||||
whenever the RTC is set.
|
||||
*/
|
||||
|
||||
#include "../../base.h"
|
||||
|
||||
SRTC *srtc;
|
||||
|
||||
void SRTC::set_time() {
|
||||
time_t rawtime;
|
||||
tm *t;
|
||||
::time(&rawtime);
|
||||
t = localtime(&rawtime);
|
||||
|
||||
//see srtc.h for format of srtc.data[]
|
||||
srtc.data[0] = t->tm_sec % 10;
|
||||
srtc.data[1] = t->tm_sec / 10;
|
||||
srtc.data[2] = t->tm_min % 10;
|
||||
srtc.data[3] = t->tm_min / 10;
|
||||
srtc.data[4] = t->tm_hour % 10;
|
||||
srtc.data[5] = t->tm_hour / 10;
|
||||
srtc.data[6] = t->tm_mday % 10;
|
||||
srtc.data[7] = t->tm_mday / 10;
|
||||
srtc.data[8] = t->tm_mon + 1;
|
||||
srtc.data[9] = t->tm_year % 10;
|
||||
srtc.data[10] = (t->tm_year / 10) % 10;
|
||||
srtc.data[11] = 9 + (t->tm_year / 100);
|
||||
srtc.data[12] = t->tm_wday;
|
||||
}
|
||||
|
||||
void SRTC::init() {}
|
||||
|
||||
void SRTC::enable() {
|
||||
r_mem->set_mmio_mapper(0x2800, this);
|
||||
r_mem->set_mmio_mapper(0x2801, this);
|
||||
}
|
||||
|
||||
void SRTC::power() {
|
||||
memset(&srtc, 0, sizeof(srtc));
|
||||
reset();
|
||||
}
|
||||
|
||||
void SRTC::reset() {
|
||||
srtc.index = -1;
|
||||
srtc.mode = SRTC_READ;
|
||||
}
|
||||
|
||||
uint8 SRTC::mmio_read(uint16 addr) {
|
||||
switch(addr) {
|
||||
|
||||
case 0x2800: {
|
||||
if(srtc.mode == SRTC_READ) {
|
||||
if(srtc.index < 0) {
|
||||
set_time();
|
||||
srtc.index++;
|
||||
return 0x0f; //send start message
|
||||
} else if(srtc.index > MAX_SRTC_INDEX) {
|
||||
srtc.index = -1;
|
||||
return 0x0f; //send finished message
|
||||
} else {
|
||||
return srtc.data[srtc.index++];
|
||||
}
|
||||
} else {
|
||||
return 0x00;
|
||||
}
|
||||
} break;
|
||||
|
||||
case 0x2801: {
|
||||
} break;
|
||||
|
||||
}
|
||||
|
||||
return r_cpu->regs.mdr;
|
||||
}
|
||||
|
||||
//Please see notes above about the implementation of the S-RTC
|
||||
//Writes are stored the srtc.data[] array, but they are ignored
|
||||
//as reads will refresh the data array with the current system
|
||||
//time. The write method is only here for the sake of faux
|
||||
//emulation of the real hardware.
|
||||
void SRTC::mmio_write(uint16 addr, uint8 data) {
|
||||
switch(addr) {
|
||||
|
||||
case 0x2800: {
|
||||
} break;
|
||||
|
||||
case 0x2801: {
|
||||
data &= 0x0f; //only the low four bits are used
|
||||
|
||||
if(data >= 0x0d) {
|
||||
switch(data) {
|
||||
case 0x0d:
|
||||
srtc.mode = SRTC_READ;
|
||||
srtc.index = -1;
|
||||
break;
|
||||
case 0x0e:
|
||||
srtc.mode = SRTC_COMMAND;
|
||||
break;
|
||||
case 0x0f:
|
||||
//unknown behaviour
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(srtc.mode == SRTC_WRITE) {
|
||||
if(srtc.index >= 0 && srtc.index < MAX_SRTC_INDEX) {
|
||||
srtc.data[srtc.index++] = data;
|
||||
|
||||
if(srtc.index == MAX_SRTC_INDEX) {
|
||||
//all S-RTC data has been loaded by program
|
||||
srtc.data[srtc.index++] = 0x00; //day_of_week
|
||||
}
|
||||
}
|
||||
} else if(srtc.mode == SRTC_COMMAND) {
|
||||
switch(data) {
|
||||
case SRTC_COMMAND_CLEAR:
|
||||
memset(srtc.data, 0, MAX_SRTC_INDEX + 1);
|
||||
srtc.index = -1;
|
||||
srtc.mode = SRTC_READY;
|
||||
break;
|
||||
case SRTC_COMMAND_WRITE:
|
||||
srtc.index = 0;
|
||||
srtc.mode = SRTC_WRITE;
|
||||
break;
|
||||
default:
|
||||
//unknown behaviour
|
||||
srtc.mode = SRTC_READY;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if(srtc.mode == SRTC_READ) {
|
||||
//ignore writes while in read mode
|
||||
} else if(srtc.mode == SRTC_READY) {
|
||||
//unknown behaviour
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
SRTC::SRTC() {}
|
||||
@@ -0,0 +1,52 @@
|
||||
class SRTC : public MMIO {
|
||||
public:
|
||||
enum { MAX_SRTC_INDEX = 0x0c };
|
||||
|
||||
enum {
|
||||
SRTC_READ = 0,
|
||||
SRTC_WRITE,
|
||||
SRTC_COMMAND,
|
||||
SRTC_READY
|
||||
};
|
||||
|
||||
enum {
|
||||
SRTC_COMMAND_WRITE = 0,
|
||||
SRTC_COMMAND_CLEAR = 4
|
||||
};
|
||||
|
||||
/******************************
|
||||
[srtc.data structure]
|
||||
Index Description Range
|
||||
----- ----------- -----
|
||||
0 Seconds low 0-9
|
||||
1 Seconds high 0-5
|
||||
2 Minutes low 0-9
|
||||
3 Minutes high 0-5
|
||||
4 Hour low 0-9
|
||||
5 Hour high 0-2
|
||||
6 Day low 0-9
|
||||
7 Day high 0-3
|
||||
8 Month 1-12
|
||||
9 Year ones 0-9
|
||||
10 Year tens 0-9
|
||||
11 Year hundreds 9-11 (9=19xx, 10=20xx, 11=21xx)
|
||||
12 Day of week 0-6 (0=Sunday, ...)
|
||||
******************************/
|
||||
struct {
|
||||
int8 index;
|
||||
uint8 mode;
|
||||
uint8 data[MAX_SRTC_INDEX + 1];
|
||||
} srtc;
|
||||
void set_time();
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 mmio_read (uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
|
||||
SRTC();
|
||||
};
|
||||
|
||||
extern SRTC *srtc;
|
||||
@@ -0,0 +1,86 @@
|
||||
#include "../../base.h"
|
||||
#include "st010_data.h"
|
||||
#include "st010_op.cpp"
|
||||
|
||||
ST010 *st010;
|
||||
|
||||
int16 ST010::sin(int16 theta) {
|
||||
return sin_table[(theta >> 8) & 0xff];
|
||||
}
|
||||
|
||||
int16 ST010::cos(int16 theta) {
|
||||
return sin_table[((theta + 0x4000) >> 8) & 0xff];
|
||||
}
|
||||
|
||||
uint8 ST010::readb(uint16 addr) {
|
||||
return ram[addr & 0xfff];
|
||||
}
|
||||
|
||||
uint16 ST010::readw(uint16 addr) {
|
||||
return (readb(addr + 0) << 0) |
|
||||
(readb(addr + 1) << 8);
|
||||
}
|
||||
|
||||
uint32 ST010::readd(uint16 addr) {
|
||||
return (readb(addr + 0) << 0) |
|
||||
(readb(addr + 1) << 8) |
|
||||
(readb(addr + 2) << 16) |
|
||||
(readb(addr + 3) << 24);
|
||||
}
|
||||
|
||||
void ST010::writeb(uint16 addr, uint8 data) {
|
||||
ram[addr & 0xfff] = data;
|
||||
}
|
||||
|
||||
void ST010::writew(uint16 addr, uint16 data) {
|
||||
writeb(addr + 0, data);
|
||||
writeb(addr + 1, data >> 8);
|
||||
}
|
||||
|
||||
void ST010::writed(uint16 addr, uint32 data) {
|
||||
writeb(addr + 0, data);
|
||||
writeb(addr + 1, data >> 8);
|
||||
writeb(addr + 2, data >> 16);
|
||||
writeb(addr + 3, data >> 24);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void ST010::init() {
|
||||
}
|
||||
|
||||
void ST010::enable() {
|
||||
}
|
||||
|
||||
void ST010::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void ST010::reset() {
|
||||
memset(ram, 0x00, sizeof ram);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
uint8 ST010::read(uint16 addr) {
|
||||
return readb(addr);
|
||||
}
|
||||
|
||||
void ST010::write(uint16 addr, uint8 data) {
|
||||
writeb(addr, data);
|
||||
|
||||
if(addr == 0x0021 && data & 0x80) {
|
||||
switch(ram[0x0020]) {
|
||||
case 0x01: op_01(); break;
|
||||
case 0x02: op_02(); break;
|
||||
case 0x03: op_03(); break;
|
||||
case 0x04: op_04(); break;
|
||||
case 0x05: op_05(); break;
|
||||
case 0x06: op_06(); break;
|
||||
case 0x07: op_07(); break;
|
||||
case 0x08: op_08(); break;
|
||||
}
|
||||
|
||||
ram[0x0021] &= ~0x80;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
class ST010 { public:
|
||||
uint8 ram[0x1000];
|
||||
static const int16 sin_table[256];
|
||||
static const int16 mode7_scale[176];
|
||||
static const uint8 arctan[32][32];
|
||||
//interfaces to sin table
|
||||
int16 sin(int16 theta);
|
||||
int16 cos(int16 theta);
|
||||
|
||||
//interfaces to ram buffer
|
||||
uint8 readb (uint16 addr);
|
||||
uint16 readw (uint16 addr);
|
||||
uint32 readd (uint16 addr);
|
||||
void writeb(uint16 addr, uint8 data);
|
||||
void writew(uint16 addr, uint16 data);
|
||||
void writed(uint16 addr, uint32 data);
|
||||
|
||||
//opcodes
|
||||
void op_01();
|
||||
void op_02();
|
||||
void op_03();
|
||||
void op_04();
|
||||
void op_05();
|
||||
void op_06();
|
||||
void op_07();
|
||||
void op_08();
|
||||
|
||||
void op_01(int16 x0, int16 y0, int16 &x1, int16 &y1, int16 &quadrant, int16 &theta);
|
||||
|
||||
//base
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 read (uint16 addr);
|
||||
void write(uint16 addr, uint8 data);
|
||||
};
|
||||
|
||||
extern ST010 *st010;
|
||||
@@ -0,0 +1,126 @@
|
||||
const int16 ST010::sin_table[256] = {
|
||||
0x0000, 0x0324, 0x0648, 0x096a, 0x0c8c, 0x0fab, 0x12c8, 0x15e2,
|
||||
0x18f9, 0x1c0b, 0x1f1a, 0x2223, 0x2528, 0x2826, 0x2b1f, 0x2e11,
|
||||
0x30fb, 0x33df, 0x36ba, 0x398c, 0x3c56, 0x3f17, 0x41ce, 0x447a,
|
||||
0x471c, 0x49b4, 0x4c3f, 0x4ebf, 0x5133, 0x539b, 0x55f5, 0x5842,
|
||||
0x5a82, 0x5cb3, 0x5ed7, 0x60eb, 0x62f1, 0x64e8, 0x66cf, 0x68a6,
|
||||
0x6a6d, 0x6c23, 0x6dc9, 0x6f5e, 0x70e2, 0x7254, 0x73b5, 0x7504,
|
||||
0x7641, 0x776b, 0x7884, 0x7989, 0x7a7c, 0x7b5c, 0x7c29, 0x7ce3,
|
||||
0x7d89, 0x7e1d, 0x7e9c, 0x7f09, 0x7f61, 0x7fa6, 0x7fd8, 0x7ff5,
|
||||
0x7fff, 0x7ff5, 0x7fd8, 0x7fa6, 0x7f61, 0x7f09, 0x7e9c, 0x7e1d,
|
||||
0x7d89, 0x7ce3, 0x7c29, 0x7b5c, 0x7a7c, 0x7989, 0x7884, 0x776b,
|
||||
0x7641, 0x7504, 0x73b5, 0x7254, 0x70e2, 0x6f5e, 0x6dc9, 0x6c23,
|
||||
0x6a6d, 0x68a6, 0x66cf, 0x64e8, 0x62f1, 0x60eb, 0x5ed7, 0x5cb3,
|
||||
0x5a82, 0x5842, 0x55f5, 0x539b, 0x5133, 0x4ebf, 0x4c3f, 0x49b4,
|
||||
0x471c, 0x447a, 0x41ce, 0x3f17, 0x3c56, 0x398c, 0x36ba, 0x33df,
|
||||
0x30fb, 0x2e11, 0x2b1f, 0x2826, 0x2528, 0x2223, 0x1f1a, 0x1c0b,
|
||||
0x18f8, 0x15e2, 0x12c8, 0x0fab, 0x0c8c, 0x096a, 0x0648, 0x0324,
|
||||
0x0000, -0x0324, -0x0648, -0x096b, -0x0c8c, -0x0fab, -0x12c8, -0x15e2,
|
||||
-0x18f9, -0x1c0b, -0x1f1a, -0x2223, -0x2528, -0x2826, -0x2b1f, -0x2e11,
|
||||
-0x30fb, -0x33df, -0x36ba, -0x398d, -0x3c56, -0x3f17, -0x41ce, -0x447a,
|
||||
-0x471c, -0x49b4, -0x4c3f, -0x4ebf, -0x5133, -0x539b, -0x55f5, -0x5842,
|
||||
-0x5a82, -0x5cb3, -0x5ed7, -0x60ec, -0x62f1, -0x64e8, -0x66cf, -0x68a6,
|
||||
-0x6a6d, -0x6c23, -0x6dc9, -0x6f5e, -0x70e2, -0x7254, -0x73b5, -0x7504,
|
||||
-0x7641, -0x776b, -0x7884, -0x7989, -0x7a7c, -0x7b5c, -0x7c29, -0x7ce3,
|
||||
-0x7d89, -0x7e1d, -0x7e9c, -0x7f09, -0x7f61, -0x7fa6, -0x7fd8, -0x7ff5,
|
||||
-0x7fff, -0x7ff5, -0x7fd8, -0x7fa6, -0x7f61, -0x7f09, -0x7e9c, -0x7e1d,
|
||||
-0x7d89, -0x7ce3, -0x7c29, -0x7b5c, -0x7a7c, -0x7989, -0x7883, -0x776b,
|
||||
-0x7641, -0x7504, -0x73b5, -0x7254, -0x70e2, -0x6f5e, -0x6dc9, -0x6c23,
|
||||
-0x6a6d, -0x68a6, -0x66cf, -0x64e8, -0x62f1, -0x60eb, -0x5ed7, -0x5cb3,
|
||||
-0x5a82, -0x5842, -0x55f5, -0x539a, -0x5133, -0x4ebf, -0x4c3f, -0x49b3,
|
||||
-0x471c, -0x447a, -0x41cd, -0x3f17, -0x3c56, -0x398c, -0x36b9, -0x33de,
|
||||
-0x30fb, -0x2e10, -0x2b1f, -0x2826, -0x2527, -0x2223, -0x1f19, -0x1c0b,
|
||||
-0x18f8, -0x15e2, -0x12c8, -0x0fab, -0x0c8b, -0x096a, -0x0647, -0x0324
|
||||
};
|
||||
|
||||
const int16 ST010::mode7_scale[176] = {
|
||||
0x0380, 0x0325, 0x02da, 0x029c, 0x0268, 0x023b, 0x0215, 0x01f3,
|
||||
0x01d5, 0x01bb, 0x01a3, 0x018e, 0x017b, 0x016a, 0x015a, 0x014b,
|
||||
0x013e, 0x0132, 0x0126, 0x011c, 0x0112, 0x0109, 0x0100, 0x00f8,
|
||||
0x00f0, 0x00e9, 0x00e3, 0x00dc, 0x00d6, 0x00d1, 0x00cb, 0x00c6,
|
||||
0x00c1, 0x00bd, 0x00b8, 0x00b4, 0x00b0, 0x00ac, 0x00a8, 0x00a5,
|
||||
0x00a2, 0x009e, 0x009b, 0x0098, 0x0095, 0x0093, 0x0090, 0x008d,
|
||||
0x008b, 0x0088, 0x0086, 0x0084, 0x0082, 0x0080, 0x007e, 0x007c,
|
||||
0x007a, 0x0078, 0x0076, 0x0074, 0x0073, 0x0071, 0x006f, 0x006e,
|
||||
0x006c, 0x006b, 0x0069, 0x0068, 0x0067, 0x0065, 0x0064, 0x0063,
|
||||
0x0062, 0x0060, 0x005f, 0x005e, 0x005d, 0x005c, 0x005b, 0x005a,
|
||||
0x0059, 0x0058, 0x0057, 0x0056, 0x0055, 0x0054, 0x0053, 0x0052,
|
||||
0x0051, 0x0051, 0x0050, 0x004f, 0x004e, 0x004d, 0x004d, 0x004c,
|
||||
0x004b, 0x004b, 0x004a, 0x0049, 0x0048, 0x0048, 0x0047, 0x0047,
|
||||
0x0046, 0x0045, 0x0045, 0x0044, 0x0044, 0x0043, 0x0042, 0x0042,
|
||||
0x0041, 0x0041, 0x0040, 0x0040, 0x003f, 0x003f, 0x003e, 0x003e,
|
||||
0x003d, 0x003d, 0x003c, 0x003c, 0x003b, 0x003b, 0x003a, 0x003a,
|
||||
0x003a, 0x0039, 0x0039, 0x0038, 0x0038, 0x0038, 0x0037, 0x0037,
|
||||
0x0036, 0x0036, 0x0036, 0x0035, 0x0035, 0x0035, 0x0034, 0x0034,
|
||||
0x0034, 0x0033, 0x0033, 0x0033, 0x0032, 0x0032, 0x0032, 0x0031,
|
||||
0x0031, 0x0031, 0x0030, 0x0030, 0x0030, 0x0030, 0x002f, 0x002f,
|
||||
0x002f, 0x002e, 0x002e, 0x002e, 0x002e, 0x002d, 0x002d, 0x002d,
|
||||
0x002d, 0x002c, 0x002c, 0x002c, 0x002c, 0x002b, 0x002b, 0x002b
|
||||
};
|
||||
|
||||
const uint8 ST010::arctan[32][32] = {
|
||||
{ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 },
|
||||
{ 0x80, 0xa0, 0xad, 0xb3, 0xb6, 0xb8, 0xb9, 0xba, 0xbb, 0xbb, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd,
|
||||
0xbd, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbf, 0xbf, 0xbf, 0xbf },
|
||||
{ 0x80, 0x93, 0xa0, 0xa8, 0xad, 0xb0, 0xb3, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xbb,
|
||||
0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd },
|
||||
{ 0x80, 0x8d, 0x98, 0xa0, 0xa6, 0xaa, 0xad, 0xb0, 0xb1, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb7, 0xb8,
|
||||
0xb8, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbc, 0xbc, 0xbc, 0xbc },
|
||||
{ 0x80, 0x8a, 0x93, 0x9a, 0xa0, 0xa5, 0xa8, 0xab, 0xad, 0xaf, 0xb0, 0xb2, 0xb3, 0xb4, 0xb5, 0xb5,
|
||||
0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xba, 0xba, 0xba, 0xba, 0xba, 0xbb, 0xbb },
|
||||
{ 0x80, 0x88, 0x90, 0x96, 0x9b, 0xa0, 0xa4, 0xa7, 0xa9, 0xab, 0xad, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
|
||||
0xb4, 0xb4, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9 },
|
||||
{ 0x80, 0x87, 0x8d, 0x93, 0x98, 0x9c, 0xa0, 0xa3, 0xa6, 0xa8, 0xaa, 0xac, 0xad, 0xae, 0xb0, 0xb0,
|
||||
0xb1, 0xb2, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7, 0xb7, 0xb8, 0xb8, 0xb8 },
|
||||
{ 0x80, 0x86, 0x8b, 0x90, 0x95, 0x99, 0x9d, 0xa0, 0xa3, 0xa5, 0xa7, 0xa9, 0xaa, 0xac, 0xad, 0xae,
|
||||
0xaf, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb6, 0xb6, 0xb6, 0xb7, 0xb7 },
|
||||
{ 0x80, 0x85, 0x8a, 0x8f, 0x93, 0x97, 0x9a, 0x9d, 0xa0, 0xa2, 0xa5, 0xa6, 0xa8, 0xaa, 0xab, 0xac,
|
||||
0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb5, 0xb5, 0xb5, 0xb5 },
|
||||
{ 0x80, 0x85, 0x89, 0x8d, 0x91, 0x95, 0x98, 0x9b, 0x9e, 0xa0, 0xa0, 0xa4, 0xa6, 0xa7, 0xa9, 0xaa,
|
||||
0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2, 0xb3, 0xb3, 0xb4, 0xb4, 0xb4 },
|
||||
{ 0x80, 0x84, 0x88, 0x8c, 0x90, 0x93, 0x96, 0x99, 0x9b, 0x9e, 0xa0, 0xa2, 0xa4, 0xa5, 0xa7, 0xa8,
|
||||
0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xaf, 0xb0, 0xb0, 0xb1, 0xb2, 0xb2, 0xb2, 0xb3, 0xb3 },
|
||||
{ 0x80, 0x84, 0x87, 0x8b, 0x8e, 0x91, 0x94, 0x97, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5, 0xa6,
|
||||
0xa7, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb1, 0xb1, 0xb2, 0xb2 },
|
||||
{ 0x80, 0x83, 0x87, 0x8a, 0x8d, 0x90, 0x93, 0x96, 0x98, 0x9a, 0x9c, 0x9e, 0xa0, 0xa2, 0xa3, 0xa5,
|
||||
0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xb0, 0xb0, 0xb0, 0xb1 },
|
||||
{ 0x80, 0x83, 0x86, 0x89, 0x8c, 0x8f, 0x92, 0x94, 0x96, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa2, 0xa3,
|
||||
0xa4, 0xa5, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab, 0xac, 0xac, 0xad, 0xae, 0xae, 0xaf, 0xaf, 0xb0 },
|
||||
{ 0x80, 0x83, 0x86, 0x89, 0x8b, 0x8e, 0x90, 0x93, 0x95, 0x97, 0x99, 0x9b, 0x9d, 0x9e, 0xa0, 0xa1,
|
||||
0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac, 0xad, 0xad, 0xae, 0xae, 0xaf },
|
||||
{ 0x80, 0x83, 0x85, 0x88, 0x8b, 0x8d, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9b, 0x9d, 0x9f, 0xa0,
|
||||
0xa1, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xab, 0xab, 0xac, 0xad, 0xad, 0xae },
|
||||
{ 0x80, 0x83, 0x85, 0x88, 0x8a, 0x8c, 0x8f, 0x91, 0x93, 0x95, 0x97, 0x99, 0x9a, 0x9c, 0x9d, 0x9f,
|
||||
0xa0, 0xa1, 0xa2, 0xa3, 0xa5, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xab, 0xac, 0xad },
|
||||
{ 0x80, 0x82, 0x85, 0x87, 0x89, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x97, 0x99, 0x9b, 0x9c, 0x9d,
|
||||
0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa, 0xaa, 0xab, 0xac },
|
||||
{ 0x80, 0x82, 0x85, 0x87, 0x89, 0x8b, 0x8d, 0x8f, 0x91, 0x93, 0x95, 0x96, 0x98, 0x99, 0x9b, 0x9c,
|
||||
0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9, 0xa9, 0xaa, 0xab },
|
||||
{ 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x9a, 0x9b,
|
||||
0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8, 0xa8, 0xa9, 0xaa },
|
||||
{ 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x99, 0x9a,
|
||||
0x9b, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6, 0xa7, 0xa7, 0xa8, 0xa9 },
|
||||
{ 0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8f, 0x90, 0x92, 0x94, 0x95, 0x97, 0x98, 0x99,
|
||||
0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7, 0xa8 },
|
||||
{ 0x80, 0x82, 0x84, 0x86, 0x87, 0x89, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x93, 0x94, 0x96, 0x97, 0x98,
|
||||
0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa3, 0xa4, 0xa5, 0xa6, 0xa6, 0xa7 },
|
||||
{ 0x80, 0x82, 0x84, 0x85, 0x87, 0x89, 0x8a, 0x8c, 0x8e, 0x8f, 0x91, 0x92, 0x94, 0x95, 0x96, 0x98,
|
||||
0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5, 0xa6 },
|
||||
{ 0x80, 0x82, 0x83, 0x85, 0x87, 0x88, 0x8a, 0x8c, 0x8d, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x96, 0x97,
|
||||
0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa5, 0xa5 },
|
||||
{ 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x8a, 0x8b, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x94, 0x95, 0x96,
|
||||
0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4, 0xa4 },
|
||||
{ 0x80, 0x82, 0x83, 0x85, 0x86, 0x88, 0x89, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94, 0x95,
|
||||
0x96, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa2, 0xa3, 0xa4 },
|
||||
{ 0x80, 0x82, 0x83, 0x85, 0x86, 0x87, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93, 0x95,
|
||||
0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2, 0xa3 },
|
||||
{ 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x89, 0x8a, 0x8b, 0x8d, 0x8e, 0x8f, 0x90, 0x92, 0x93, 0x94,
|
||||
0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9e, 0x9f, 0xa0, 0xa1, 0xa1, 0xa2 },
|
||||
{ 0x80, 0x81, 0x83, 0x84, 0x86, 0x87, 0x88, 0x8a, 0x8b, 0x8c, 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93,
|
||||
0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1, 0xa1 },
|
||||
{ 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8b, 0x8c, 0x8d, 0x8e, 0x90, 0x91, 0x92, 0x93,
|
||||
0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0, 0xa1 },
|
||||
{ 0x80, 0x81, 0x83, 0x84, 0x85, 0x87, 0x88, 0x89, 0x8a, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, 0x92,
|
||||
0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9c, 0x9d, 0x9e, 0x9f, 0x9f, 0xa0 }
|
||||
};
|
||||
@@ -0,0 +1,257 @@
|
||||
//ST-010 emulation code - Copyright (C) 2003 The Dumper, Matthew Kendora, Overload, Feather
|
||||
//bsnes port - Copyright (C) 2007 byuu
|
||||
|
||||
void ST010::op_01(int16 x0, int16 y0, int16 &x1, int16 &y1, int16 &quadrant, int16 &theta) {
|
||||
if((x0 < 0) && (y0 < 0)) {
|
||||
x1 = -x0;
|
||||
y1 = -y0;
|
||||
quadrant = -0x8000;
|
||||
} else if(x0 < 0) {
|
||||
x1 = y0;
|
||||
y1 = -x0;
|
||||
quadrant = -0x4000;
|
||||
} else if(y0 < 0) {
|
||||
x1 = -y0;
|
||||
y1 = x0;
|
||||
quadrant = 0x4000;
|
||||
} else {
|
||||
x1 = x0;
|
||||
y1 = y0;
|
||||
quadrant = 0x0000;
|
||||
}
|
||||
|
||||
while((x1 > 0x1f) || (y1 > 0x1f)) {
|
||||
if(x1 > 1) { x1 >>= 1; }
|
||||
if(y1 > 1) { y1 >>= 1; }
|
||||
}
|
||||
|
||||
if(y1 == 0) { quadrant += 0x4000; }
|
||||
|
||||
theta = (arctan[y1][x1] << 8) ^ quadrant;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
void ST010::op_01() {
|
||||
int16 x0 = readw(0x0000);
|
||||
int16 y0 = readw(0x0002);
|
||||
int16 x1, y1, quadrant, theta;
|
||||
|
||||
op_01(x0, y0, x1, y1, quadrant, theta);
|
||||
|
||||
writew(0x0000, x1);
|
||||
writew(0x0002, y1);
|
||||
writew(0x0004, quadrant);
|
||||
//writew(0x0006, y0); //Overload's docs note this write occurs, SNES9x disagrees
|
||||
writew(0x0010, theta);
|
||||
}
|
||||
|
||||
void ST010::op_02() {
|
||||
int16 positions = readw(0x0024);
|
||||
uint16 *places = (uint16*)(ram + 0x0040);
|
||||
uint16 *drivers = (uint16*)(ram + 0x0080);
|
||||
|
||||
bool sorted;
|
||||
uint16 temp;
|
||||
if(positions > 1) {
|
||||
do {
|
||||
sorted = true;
|
||||
for(int i = 0; i < positions - 1; i++) {
|
||||
if(places[i] < places[i + 1]) {
|
||||
temp = places[i + 1];
|
||||
places[i + 1] = places[i];
|
||||
places[i] = temp;
|
||||
|
||||
temp = drivers[i + 1];
|
||||
drivers[i + 1] = drivers[i];
|
||||
drivers[i] = temp;
|
||||
|
||||
sorted = false;
|
||||
}
|
||||
}
|
||||
positions--;
|
||||
} while(!sorted);
|
||||
}
|
||||
}
|
||||
|
||||
void ST010::op_03() {
|
||||
int16 x0 = readw(0x0000);
|
||||
int16 y0 = readw(0x0002);
|
||||
int16 multiplier = readw(0x0004);
|
||||
int32 x1, y1;
|
||||
|
||||
x1 = x0 * multiplier << 1;
|
||||
y1 = y0 * multiplier << 1;
|
||||
|
||||
writed(0x0010, x1);
|
||||
writed(0x0014, y1);
|
||||
}
|
||||
|
||||
void ST010::op_04() {
|
||||
int16 x = readw(0x0000);
|
||||
int16 y = readw(0x0002);
|
||||
int16 square;
|
||||
//calculate the vector length of (x,y)
|
||||
square = (int16)sqrt((double)(y * y + x * x));
|
||||
|
||||
writew(0x0010, square);
|
||||
}
|
||||
|
||||
void ST010::op_05() {
|
||||
int32 dx, dy;
|
||||
int16 a1, b1, c1;
|
||||
uint16 o1;
|
||||
bool wrap = false;
|
||||
|
||||
//target (x,y) coordinates
|
||||
int16 ypos_max = readw(0x00c0);
|
||||
int16 xpos_max = readw(0x00c2);
|
||||
|
||||
//current coordinates and direction
|
||||
int32 ypos = readd(0x00c4);
|
||||
int32 xpos = readd(0x00c8);
|
||||
uint16 rot = readw(0x00cc);
|
||||
|
||||
//physics
|
||||
uint16 speed = readw(0x00d4);
|
||||
uint16 accel = readw(0x00d6);
|
||||
uint16 speed_max = readw(0x00d8);
|
||||
|
||||
//special condition acknowledgement
|
||||
int16 system = readw(0x00da);
|
||||
int16 flags = readw(0x00dc);
|
||||
|
||||
//new target coordinates
|
||||
int16 ypos_new = readw(0x00de);
|
||||
int16 xpos_new = readw(0x00e0);
|
||||
|
||||
//mask upper bit
|
||||
xpos_new &= 0x7fff;
|
||||
|
||||
//get the current distance
|
||||
dx = xpos_max - (xpos >> 16);
|
||||
dy = ypos_max - (ypos >> 16);
|
||||
|
||||
//quirk: clear and move in9
|
||||
writew(0x00d2, 0xffff);
|
||||
writew(0x00da, 0x0000);
|
||||
|
||||
//grab the target angle
|
||||
op_01(dy, dx, a1, b1, c1, (int16&)o1);
|
||||
|
||||
//check for wrapping
|
||||
if(abs(o1 - rot) > 0x8000) {
|
||||
o1 += 0x8000;
|
||||
rot += 0x8000;
|
||||
wrap = true;
|
||||
}
|
||||
|
||||
uint16 old_speed = speed;
|
||||
|
||||
//special case
|
||||
if(abs(o1 - rot) == 0x8000) {
|
||||
speed = 0x100;
|
||||
}
|
||||
|
||||
//slow down for sharp curves
|
||||
else if(abs(o1 - rot) >= 0x1000) {
|
||||
uint32 slow = abs(o1 - rot);
|
||||
slow >>= 4; //scaling
|
||||
speed -= slow;
|
||||
}
|
||||
|
||||
//otherwise accelerate
|
||||
else {
|
||||
speed += accel;
|
||||
if(speed > speed_max) {
|
||||
speed = speed_max; //clip speed
|
||||
}
|
||||
}
|
||||
|
||||
//prevent negative/positive overflow
|
||||
if(abs(old_speed - speed) > 0x8000) {
|
||||
if(old_speed < speed) { speed = 0; }
|
||||
else speed = 0xff00;
|
||||
}
|
||||
|
||||
//adjust direction by so many degrees
|
||||
//be careful of negative adjustments
|
||||
if((o1 > rot && (o1 - rot) > 0x80) || (o1 < rot && (rot - o1) >= 0x80)) {
|
||||
if(o1 < rot) { rot -= 0x280; }
|
||||
else if(o1 > rot) { rot += 0x280; }
|
||||
}
|
||||
|
||||
//turn of wrapping
|
||||
if(wrap) { rot -= 0x8000; }
|
||||
|
||||
//now check the distances (store for later)
|
||||
dx = (xpos_max << 16) - xpos;
|
||||
dy = (ypos_max << 16) - ypos;
|
||||
dx >>= 16;
|
||||
dy >>= 16;
|
||||
|
||||
//if we're in so many units of the target, signal it
|
||||
if((system && (dy <= 6 && dy >= -8) && (dx <= 126 && dx >= -128)) || (!system && (dx <= 6 && dx >= -8) && (dy <= 126 && dy >= -128))) {
|
||||
//announce our new destination and flag it
|
||||
xpos_max = xpos_new & 0x7fff;
|
||||
ypos_max = ypos_new;
|
||||
flags |= 0x08;
|
||||
}
|
||||
|
||||
//update position
|
||||
xpos -= (cos(rot) * 0x400 >> 15) * (speed >> 8) << 1;
|
||||
ypos -= (sin(rot) * 0x400 >> 15) * (speed >> 8) << 1;
|
||||
|
||||
//quirk: mask upper byte
|
||||
xpos &= 0x1fffffff;
|
||||
ypos &= 0x1fffffff;
|
||||
|
||||
writew(0x00c0, ypos_max);
|
||||
writew(0x00c2, xpos_max);
|
||||
writed(0x00c4, ypos);
|
||||
writed(0x00c8, xpos);
|
||||
writew(0x00cc, rot);
|
||||
writew(0x00d4, speed);
|
||||
writew(0x00dc, flags);
|
||||
}
|
||||
|
||||
void ST010::op_06() {
|
||||
int16 multiplicand = readw(0x0000);
|
||||
int16 multiplier = readw(0x0002);
|
||||
int32 product;
|
||||
|
||||
product = multiplicand * multiplier << 1;
|
||||
|
||||
writed(0x0010, product);
|
||||
}
|
||||
|
||||
void ST010::op_07() {
|
||||
int16 theta = readw(0x0000);
|
||||
|
||||
int16 data;
|
||||
for(int i = 0, offset = 0; i < 176; i++) {
|
||||
data = mode7_scale[i] * cos(theta) >> 15;
|
||||
writew(0x00f0 + offset, data);
|
||||
writew(0x0510 + offset, data);
|
||||
|
||||
data = mode7_scale[i] * sin(theta) >> 15;
|
||||
writew(0x0250 + offset, data);
|
||||
if(data) { data = ~data; }
|
||||
writew(0x03b0 + offset, data);
|
||||
|
||||
offset += 2;
|
||||
}
|
||||
}
|
||||
|
||||
void ST010::op_08() {
|
||||
int16 x0 = readw(0x0000);
|
||||
int16 y0 = readw(0x0002);
|
||||
int16 theta = readw(0x0004);
|
||||
int16 x1, y1;
|
||||
|
||||
x1 = (y0 * sin(theta) >> 15) + (x0 * cos(theta) >> 15);
|
||||
y1 = (y0 * cos(theta) >> 15) - (x0 * sin(theta) >> 15);
|
||||
|
||||
writew(0x0010, x1);
|
||||
writew(0x0012, y1);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
@make PLATFORM=win-visualc-lui clean
|
||||
@@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
make PLATFORM=x-gcc-lui clean
|
||||
@@ -1,201 +0,0 @@
|
||||
#include "../../base.h"
|
||||
|
||||
void bClock::frameskip_update_status() {
|
||||
if(frameskip.changed == true) {
|
||||
frameskip.changed = false;
|
||||
frameskip.count = frameskip.new_count;
|
||||
frameskip.pos = 0;
|
||||
} else {
|
||||
frameskip.pos++;
|
||||
frameskip.pos %= (frameskip.count + 1);
|
||||
}
|
||||
|
||||
frameskip.notify_ppu = (frameskip.pos == 0)?true:false;
|
||||
}
|
||||
|
||||
void bClock::dram_refresh_test() {
|
||||
if(cc1.dram_refreshed == false && status.hcycles >= cc1.dram_refresh_pos) {
|
||||
cc1.dram_refreshed = true;
|
||||
|
||||
if(status.interlace != false || status.interlace_field != 1 || status.vcounter != 240) {
|
||||
if(cc1.dram_refresh_pos == 534) {
|
||||
cc1.dram_refresh_pos = 538;
|
||||
} else { //cc1.dram_refresh_pos == 538
|
||||
cc1.dram_refresh_pos = 534;
|
||||
}
|
||||
}
|
||||
|
||||
cc1.pos += 40;
|
||||
cc1.frame_pos += 40;
|
||||
status.hcycles += 40;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
all scanlines are 1364 cycles long, except scanline 240
|
||||
on non-interlace odd-frames, which is 1360 cycles long.
|
||||
interlace mode has 525 scanlines: 263 on the even frame,
|
||||
and 262 on the odd.
|
||||
non-interlace mode has 524 scanlines: 262 scanlines on
|
||||
both even and odd frames.
|
||||
|
||||
cycles per frame:
|
||||
263 * 1364 = 358732
|
||||
262 * 1364 = 357368
|
||||
262 * 1364 - 4 = 357364
|
||||
*/
|
||||
void bClock::inc_vcounter() {
|
||||
status.hcycles -= cc1.line_cycles;
|
||||
|
||||
status.vcounter++;
|
||||
if(status.vcounter >= cc1.frame_lines) {
|
||||
frameskip_update_status();
|
||||
|
||||
cc1.frame_pos -= cc1.frame_cycles;
|
||||
status.vcounter = 0;
|
||||
status.interlace_field ^= 1;
|
||||
if(status.interlace == true) {
|
||||
if(status.interlace_field == 0) {
|
||||
cc1.frame_cycles = 263 * 1364;
|
||||
cc1.frame_lines = 263;
|
||||
} else {
|
||||
cc1.frame_cycles = 262 * 1364;
|
||||
cc1.frame_lines = 262;
|
||||
}
|
||||
} else {
|
||||
if(status.interlace_field == 0) {
|
||||
cc1.frame_cycles = 262 * 1364;
|
||||
cc1.frame_lines = 262;
|
||||
} else {
|
||||
cc1.frame_cycles = (262 * 1364) - 4;
|
||||
cc1.frame_lines = 262;
|
||||
}
|
||||
}
|
||||
signal_frame = true;
|
||||
}
|
||||
|
||||
if(status.interlace == false && status.interlace_field == 1 && status.vcounter == 240) {
|
||||
cc1.line_cycles = 1360;
|
||||
} else {
|
||||
cc1.line_cycles = 1364;
|
||||
}
|
||||
|
||||
cc1.dram_refreshed = false;
|
||||
signal_scanline = true;
|
||||
}
|
||||
|
||||
/*
|
||||
all dots are 4 cycles long, except dots 322 and 326. dots 322 and 326
|
||||
are 6 cycles long. this holds true for all scanlines except scanline
|
||||
240 on non-interlace odd frames. the reason for this is because this
|
||||
scanline is only 1360 cycles long, instead of 1364 like all other
|
||||
scanlines.
|
||||
this makes the effective range of hscan_pos 0-339 at all times.
|
||||
dot 322 range = { 1288, 1290, 1292 }
|
||||
dot 326 range = { 1306, 1308, 1310 }
|
||||
*/
|
||||
void bClock::sync() {
|
||||
uint32 new_cycles, cycles;
|
||||
new_cycles = cc1.pos - cc1.last_pos;
|
||||
while(new_cycles) {
|
||||
if(new_cycles > 40) {
|
||||
cycles = 40;
|
||||
new_cycles -= 40;
|
||||
} else {
|
||||
cycles = new_cycles;
|
||||
new_cycles = 0;
|
||||
}
|
||||
|
||||
status.hcycles += cycles;
|
||||
cc1.frame_pos += cycles;
|
||||
dram_refresh_test();
|
||||
if(status.hcycles >= cc1.line_cycles) {
|
||||
inc_vcounter();
|
||||
}
|
||||
}
|
||||
|
||||
if(status.interlace == false && status.interlace_field == 1 && status.vcounter == 240) {
|
||||
status.hcounter = status.hcycles >> 2;
|
||||
} else {
|
||||
//1288 = 322 * 4, 1306 = 326 * 4 + 2
|
||||
status.hcounter = (status.hcycles - ((status.hcycles > 1288) << 1) - ((status.hcycles > 1306) << 1)) >> 2;
|
||||
}
|
||||
|
||||
cc1.last_pos = cc1.pos;
|
||||
if(cc1.pos > cc1.frequency) {
|
||||
cc1.pos -= cc1.frequency;
|
||||
cc1.last_pos -= cc1.frequency;
|
||||
}
|
||||
}
|
||||
|
||||
void bClock::set_frameskip(uint8 fs) {
|
||||
frameskip.changed = true;
|
||||
frameskip.new_count = fs;
|
||||
}
|
||||
|
||||
void bClock::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void bClock::reset() {
|
||||
//upon SNES reset, start at scanline 0 non-interlace
|
||||
cc1.frame_cycles = 262 * 1364;
|
||||
cc1.frame_lines = 262;
|
||||
cc1.line_cycles = 1364;
|
||||
|
||||
/*
|
||||
Initial latch values for $213c/$213d
|
||||
0035:0000 (53.0 -> 212) [lda $2137]
|
||||
0038:0000 (56.5 -> 226) [nop : lda $2137]
|
||||
*/
|
||||
cc1.pos = 188;
|
||||
cc1.last_pos = 0;
|
||||
cc1.frame_pos = 0;
|
||||
status.vcounter = 0;
|
||||
status.hcounter = 0;
|
||||
status.hcycles = 0;
|
||||
|
||||
cc1.dram_refresh_pos = 538;
|
||||
cc1.dram_refreshed = false;
|
||||
|
||||
cc2.pos = 0;
|
||||
|
||||
signal_scanline = false;
|
||||
signal_frame = false;
|
||||
sync();
|
||||
}
|
||||
|
||||
void bClock::run() {
|
||||
cpu->run();
|
||||
if(frameskip.notify_ppu == true)ppu->run();
|
||||
sync();
|
||||
|
||||
if(signal_frame == true) {
|
||||
signal_frame = false;
|
||||
cpu->frame();
|
||||
if(frameskip.notify_ppu == true)ppu->frame();
|
||||
}
|
||||
|
||||
if(signal_scanline == true) {
|
||||
signal_scanline = false;
|
||||
cpu->scanline();
|
||||
if(frameskip.notify_ppu == true)ppu->scanline();
|
||||
}
|
||||
}
|
||||
|
||||
void bClock::add_cc1_cycles(uint32 cycles) {
|
||||
cc1.pos += cycles;
|
||||
}
|
||||
|
||||
void bClock::add_cc2_cycles(uint32 cycles) {
|
||||
cc2.pos += cycles;
|
||||
}
|
||||
|
||||
bClock::bClock() {
|
||||
cc1.frequency = 21477272;
|
||||
cc2.frequency = 24576000;
|
||||
|
||||
frameskip.changed = false;
|
||||
frameskip.count = 0;
|
||||
frameskip.pos = 0;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
class bClock : public Clock {
|
||||
private:
|
||||
struct {
|
||||
bool changed, notify_ppu;
|
||||
uint8 count, new_count, pos;
|
||||
}frameskip;
|
||||
bool signal_scanline, signal_frame;
|
||||
void frameskip_update_status();
|
||||
void inc_vcounter();
|
||||
void dram_refresh_test();
|
||||
|
||||
public:
|
||||
struct {
|
||||
uint32 frequency;
|
||||
uint32 pos, last_pos;
|
||||
uint32 frame_cycles, frame_lines, frame_pos;
|
||||
uint16 line_cycles;
|
||||
bool dram_refreshed; //whether or not dram has been refreshed on this line
|
||||
uint16 dram_refresh_pos;
|
||||
}cc1;
|
||||
struct {
|
||||
uint32 frequency;
|
||||
uint32 pos, last_pos;
|
||||
}cc2;
|
||||
|
||||
void set_frameskip(uint8 fs);
|
||||
|
||||
void add_cc1_cycles(uint32 cycles);
|
||||
void add_cc2_cycles(uint32 cycles);
|
||||
void sync();
|
||||
void run();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
bClock();
|
||||
~bClock();
|
||||
};
|
||||
@@ -1,49 +0,0 @@
|
||||
#include "../base.h"
|
||||
|
||||
void Clock::enable_overscan(bool n) {
|
||||
status.overscan = n;
|
||||
}
|
||||
|
||||
void Clock::enable_interlace(bool n) {
|
||||
status.interlace = n;
|
||||
}
|
||||
|
||||
bool Clock::overscan() {
|
||||
return status.overscan;
|
||||
}
|
||||
|
||||
bool Clock::interlace() {
|
||||
return status.interlace;
|
||||
}
|
||||
|
||||
bool Clock::interlace_field() {
|
||||
return status.interlace_field;
|
||||
}
|
||||
|
||||
uint16 Clock::vcounter() {
|
||||
return status.vcounter;
|
||||
}
|
||||
|
||||
uint16 Clock::hcounter() {
|
||||
return status.hcounter;
|
||||
}
|
||||
|
||||
uint16 Clock::hcycles() {
|
||||
return status.hcycles;
|
||||
}
|
||||
|
||||
uint16 Clock::visible_scanlines() {
|
||||
return (status.overscan)?239:224;
|
||||
}
|
||||
|
||||
void Clock::set_frameskip(uint8 fs) {}
|
||||
|
||||
Clock::Clock() {
|
||||
status.overscan = false;
|
||||
status.interlace = false;
|
||||
status.interlace_field = 0;
|
||||
|
||||
status.vcounter = 0;
|
||||
status.hcounter = 0;
|
||||
status.hcycles = 0;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
class Clock {
|
||||
private:
|
||||
struct {
|
||||
bool overscan;
|
||||
bool interlace;
|
||||
bool interlace_field;
|
||||
|
||||
uint16 vcounter;
|
||||
uint16 hcounter;
|
||||
uint16 hcycles;
|
||||
}status;
|
||||
|
||||
public:
|
||||
virtual void enable_overscan(bool n);
|
||||
virtual void enable_interlace(bool n);
|
||||
virtual bool overscan();
|
||||
virtual bool interlace();
|
||||
virtual bool interlace_field();
|
||||
virtual uint16 vcounter();
|
||||
virtual uint16 hcounter();
|
||||
virtual uint16 hcycles();
|
||||
virtual uint16 visible_scanlines();
|
||||
|
||||
virtual void set_frameskip(uint8 fs);
|
||||
|
||||
virtual void add_cc1_cycles(uint32 cycles) = 0;
|
||||
virtual void add_cc2_cycles(uint32 cycles) = 0;
|
||||
virtual void sync() = 0;
|
||||
virtual void run() = 0;
|
||||
virtual void power() = 0;
|
||||
virtual void reset() = 0;
|
||||
|
||||
Clock();
|
||||
|
||||
friend class bClock;
|
||||
};
|
||||
@@ -0,0 +1,125 @@
|
||||
namespace config {
|
||||
|
||||
Config& config() {
|
||||
static Config config;
|
||||
return config;
|
||||
}
|
||||
|
||||
string file_updatepath(const char *req_file, const char *req_path) {
|
||||
string file(req_file);
|
||||
replace(file, "\\", "/");
|
||||
if(!req_path || strlen(req_path) == 0) { return file; }
|
||||
|
||||
string path(req_path);
|
||||
replace(path, "\\", "/");
|
||||
if(!strend(path, "/")) { strcat(path, "/"); }
|
||||
|
||||
if(strbegin(path, "./")) {
|
||||
strltrim(path, "./");
|
||||
string temp;
|
||||
strcpy(temp, config::path.base);
|
||||
strcat(temp, path);
|
||||
strcpy(path, temp);
|
||||
}
|
||||
|
||||
stringarray part;
|
||||
split(part, "/", file);
|
||||
strcat(path, part[count(part) - 1]);
|
||||
return path;
|
||||
}
|
||||
|
||||
StringSetting Path::base(0, "fs.base_path",
|
||||
"Path that bsnes resides in", "");
|
||||
StringSetting Path::rom(&config(), "path.rom",
|
||||
"Default path to look for ROM files in (\"\" = use default directory)", "");
|
||||
StringSetting Path::save(&config(), "path.save",
|
||||
"Default path for all save RAM and cheat files (\"\" = use current directory)", "");
|
||||
StringSetting Path::bios(&config(), "path.bios",
|
||||
"Path where BIOS file(s) are located\n"
|
||||
"Supported BIOS files:\n"
|
||||
"stbios.bin - Bandai Sufami Turbo"
|
||||
"", "./bios");
|
||||
|
||||
StringSetting Path::save_ext(&config(), "path.save_ext",
|
||||
"Extension to be used for all save RAM files", "srm");
|
||||
|
||||
IntegerSetting SNES::gamma_ramp(&config(), "snes.colorfilter.gamma_ramp",
|
||||
"Use precalculated TV-style gamma ramp", IntegerSetting::Boolean, true);
|
||||
IntegerSetting SNES::sepia(&config(), "snes.colorfilter.sepia",
|
||||
"Convert color to sepia tone", IntegerSetting::Boolean, false);
|
||||
IntegerSetting SNES::grayscale(&config(), "snes.colorfilter.grayscale",
|
||||
"Convert color to grayscale tone", IntegerSetting::Boolean, false);
|
||||
IntegerSetting SNES::invert(&config(), "snes.colorfilter.invert",
|
||||
"Invert output image colors", IntegerSetting::Boolean, false);
|
||||
IntegerSetting SNES::contrast(&config(), "snes.colorfilter.contrast",
|
||||
"Contrast", IntegerSetting::Decimal, 0);
|
||||
IntegerSetting SNES::brightness(&config(), "snes.colorfilter.brightness",
|
||||
"Brightness", IntegerSetting::Decimal, 0);
|
||||
IntegerSetting SNES::gamma(&config(), "snes.colorfilter.gamma",
|
||||
"Gamma", IntegerSetting::Decimal, 80);
|
||||
|
||||
IntegerSetting SNES::ntsc_merge_fields(&config(), "snes.ntsc_merge_fields",
|
||||
"Merge fields in NTSC video filter\n"
|
||||
"Set to true if using filter at any refresh rate other than 60hz\n"
|
||||
"", IntegerSetting::Boolean, true);
|
||||
|
||||
IntegerSetting SNES::mute(&config(), "snes.mute", "Mutes SNES audio output when enabled",
|
||||
IntegerSetting::Boolean, false);
|
||||
|
||||
IntegerSetting SNES::controller_port0(&config(), "snes.controller_port_1",
|
||||
"Controller attached to SNES port 1", IntegerSetting::Decimal, ::SNES::DEVICEID_JOYPAD1);
|
||||
IntegerSetting SNES::controller_port1(&config(), "snes.controller_port_2",
|
||||
"Controller attached to SNES port 2", IntegerSetting::Decimal, ::SNES::DEVICEID_JOYPAD2);
|
||||
|
||||
IntegerSetting CPU::ntsc_clock_rate(&config(), "cpu.ntsc_clock_rate",
|
||||
"NTSC S-CPU clock rate (in hz)", IntegerSetting::Decimal, 21477272);
|
||||
IntegerSetting CPU::pal_clock_rate(&config(), "cpu.pal_clock_rate",
|
||||
"PAL S-CPU clock rate (in hz)", IntegerSetting::Decimal, 21281370);
|
||||
|
||||
IntegerSetting CPU::hdma_enable(0, "cpu.hdma_enable",
|
||||
"Enable HDMA effects", IntegerSetting::Boolean, true);
|
||||
|
||||
IntegerSetting SMP::ntsc_clock_rate(&config(), "smp.ntsc_clock_rate",
|
||||
"NTSC S-SMP clock rate (in hz)", IntegerSetting::Decimal, 24606720);
|
||||
IntegerSetting SMP::pal_clock_rate(&config(), "smp.pal_clock_rate",
|
||||
"PAL S-SMP clock rate (in hz)", IntegerSetting::Decimal, 24606720);
|
||||
|
||||
IntegerSetting PPU::Hack::render_scanline_position(&config(), "ppu.hack.render_scanline_position",
|
||||
"Approximate HCLOCK position to render at for scanline-based renderers",
|
||||
IntegerSetting::Decimal, 512);
|
||||
IntegerSetting PPU::Hack::obj_cache(&config(), "ppu.hack.obj_cache",
|
||||
"Cache OAM OBJ attributes one scanline before rendering\n"
|
||||
"This is technically closer to the actual operation of the SNES,\n"
|
||||
"but can cause problems in some games if enabled",
|
||||
IntegerSetting::Boolean, false);
|
||||
IntegerSetting PPU::Hack::oam_address_invalidation(&config(), "ppu.hack.oam_address_invalidation",
|
||||
"OAM access address changes during active display, as the S-PPU reads\n"
|
||||
"data to render the display. Thusly, the address retrieved when accessing\n"
|
||||
"OAM during active display is unpredictable. Unfortunately, the exact\n"
|
||||
"algorithm for this is completely unknown at this time. It is more hardware\n"
|
||||
"accurate to enable this setting, but one must *not* rely on the actual\n"
|
||||
"address to match hardware under emulation.",
|
||||
IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::Hack::cgram_address_invalidation(&config(), "ppu.hack.cgram_address_invalidation",
|
||||
"CGRAM access address changes during active display (excluding hblank), as\n"
|
||||
"the S-PPU reads data to render the display. Thusly, as with OAM, the access\n"
|
||||
"address is unpredictable. Again, enabling this setting is more hardware\n"
|
||||
"accurate, but one must *not* rely on the actual address to match hardware\n"
|
||||
"under emulation.",
|
||||
IntegerSetting::Boolean, true);
|
||||
|
||||
IntegerSetting PPU::opt_enable(0, "ppu.opt_enable", "Enable offset-per-tile effects", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg1_pri0_enable(0, "ppu.bg1_pri0_enable", "Enable BG1 Priority 0", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg1_pri1_enable(0, "ppu.bg1_pri1_enable", "Enable BG1 Priority 1", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg2_pri0_enable(0, "ppu.bg2_pri0_enable", "Enable BG2 Priority 0", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg2_pri1_enable(0, "ppu.bg2_pri1_enable", "Enable BG2 Priority 1", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg3_pri0_enable(0, "ppu.bg3_pri0_enable", "Enable BG3 Priority 0", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg3_pri1_enable(0, "ppu.bg3_pri1_enable", "Enable BG3 Priority 1", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg4_pri0_enable(0, "ppu.bg4_pri0_enable", "Enable BG4 Priority 0", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg4_pri1_enable(0, "ppu.bg4_pri1_enable", "Enable BG4 Priority 1", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::oam_pri0_enable(0, "ppu.oam_pri0_enable", "Enable OAM Priority 0", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::oam_pri1_enable(0, "ppu.oam_pri1_enable", "Enable OAM Priority 1", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::oam_pri2_enable(0, "ppu.oam_pri2_enable", "Enable OAM Priority 2", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::oam_pri3_enable(0, "ppu.oam_pri3_enable", "Enable OAM Priority 3", IntegerSetting::Boolean, true);
|
||||
|
||||
};
|
||||
@@ -0,0 +1,46 @@
|
||||
namespace config {
|
||||
|
||||
extern Config& config();
|
||||
|
||||
string file_updatepath(const char *, const char *);
|
||||
|
||||
extern struct Path {
|
||||
static StringSetting base, rom, save, bios;
|
||||
static StringSetting save_ext;
|
||||
} path;
|
||||
|
||||
extern struct SNES {
|
||||
static IntegerSetting gamma_ramp, sepia, grayscale, invert, contrast, brightness, gamma;
|
||||
static IntegerSetting ntsc_merge_fields;
|
||||
static IntegerSetting mute;
|
||||
static IntegerSetting controller_port0;
|
||||
static IntegerSetting controller_port1;
|
||||
} snes;
|
||||
|
||||
extern struct CPU {
|
||||
static IntegerSetting ntsc_clock_rate, pal_clock_rate;
|
||||
static IntegerSetting hdma_enable;
|
||||
} cpu;
|
||||
|
||||
extern struct SMP {
|
||||
static IntegerSetting ntsc_clock_rate, pal_clock_rate;
|
||||
} smp;
|
||||
|
||||
extern struct PPU {
|
||||
struct Hack {
|
||||
static IntegerSetting render_scanline_position;
|
||||
static IntegerSetting obj_cache;
|
||||
static IntegerSetting oam_address_invalidation;
|
||||
static IntegerSetting cgram_address_invalidation;
|
||||
} hack;
|
||||
|
||||
static IntegerSetting opt_enable;
|
||||
static IntegerSetting bg1_pri0_enable, bg1_pri1_enable;
|
||||
static IntegerSetting bg2_pri0_enable, bg2_pri1_enable;
|
||||
static IntegerSetting bg3_pri0_enable, bg3_pri1_enable;
|
||||
static IntegerSetting bg4_pri0_enable, bg4_pri1_enable;
|
||||
static IntegerSetting oam_pri0_enable, oam_pri1_enable;
|
||||
static IntegerSetting oam_pri2_enable, oam_pri3_enable;
|
||||
} ppu;
|
||||
|
||||
};
|
||||
@@ -1,316 +0,0 @@
|
||||
#include "../../base.h"
|
||||
|
||||
#include "bcpu_op_adc.cpp"
|
||||
#include "bcpu_op_and.cpp"
|
||||
#include "bcpu_op_cmp.cpp"
|
||||
#include "bcpu_op_eor.cpp"
|
||||
#include "bcpu_op_incdec.cpp"
|
||||
#include "bcpu_op_lda.cpp"
|
||||
#include "bcpu_op_misc.cpp"
|
||||
#include "bcpu_op_ora.cpp"
|
||||
#include "bcpu_op_pc.cpp"
|
||||
#include "bcpu_op_sbc.cpp"
|
||||
#include "bcpu_op_shift.cpp"
|
||||
#include "bcpu_op_sta.cpp"
|
||||
#include "bcpu_op_stack.cpp"
|
||||
#include "bcpu_exec.cpp"
|
||||
#include "bcpu_mmio.cpp"
|
||||
|
||||
uint8 bCPU::pio_status() {
|
||||
return status.pio;
|
||||
}
|
||||
|
||||
/***********
|
||||
*** IRQ ***
|
||||
***********
|
||||
cycles:
|
||||
[1] pbr,pc ; io
|
||||
[2] pbr,pc ; io
|
||||
[3] 0,s ; pbr
|
||||
[4] 0,s-1 ; pch
|
||||
[5] 0,s-2 ; pcl
|
||||
[6] 0,s-3 ; p
|
||||
[7] 0,va ; aavl
|
||||
[8] 0,va+1 ; aavh
|
||||
*/
|
||||
void bCPU::irq(uint16 addr) {
|
||||
if(cpustate == CPUSTATE_WAI) {
|
||||
regs.pc.w++;
|
||||
cpustate = CPUSTATE_RUN;
|
||||
}
|
||||
|
||||
clock->add_cc1_cycles(mem_bus->speed(regs.pc)); //1
|
||||
clock->add_cc1_cycles(6); //2
|
||||
stack_write(regs.pc.b); //3
|
||||
stack_write(regs.pc.h); //4
|
||||
stack_write(regs.pc.l); //5
|
||||
stack_write(regs.p); //6
|
||||
rd.l = op_read(OPMODE_ADDR, addr); //7
|
||||
rd.h = op_read(OPMODE_ADDR, addr + 1); //8
|
||||
regs.pc.b = 0x00;
|
||||
regs.pc.w = rd.w;
|
||||
|
||||
regs.p.d = 0;
|
||||
regs.p.i = 1;
|
||||
|
||||
snes->notify(SNES::CPU_EXEC_OPCODE);
|
||||
}
|
||||
|
||||
void bCPU::run() {
|
||||
uint16 v, h, hc, vs;
|
||||
v = clock->vcounter();
|
||||
h = clock->hcounter();
|
||||
hc = clock->hcycles();
|
||||
vs = clock->visible_scanlines();
|
||||
|
||||
//HDMA test
|
||||
if(v < vs && h >= 278) {
|
||||
if(status.hdma_triggered == false) {
|
||||
status.hdma_triggered = true;
|
||||
dma->hdma_run();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch(cpustate) {
|
||||
case CPUSTATE_RUN:
|
||||
case CPUSTATE_WAI:
|
||||
//NMI test
|
||||
if(v >= (vs + 1) && status.nmi_triggered == false) {
|
||||
if((v == (vs + 1) && hc >= 12) || (v > (vs + 1))) {
|
||||
status.nmi_triggered = true;
|
||||
status.nmi_pin = 0;
|
||||
if(status.nmi_enabled == true) {
|
||||
irq(0xffea);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//IRQ test
|
||||
if(!regs.p.i) {
|
||||
if(status.virq_enabled == true && status.virq_enabled == true) {
|
||||
if(v == status.virq_pos && h >= status.hirq_pos && status.irq_pin == 1) {
|
||||
status.irq_triggered = true;
|
||||
status.irq_pin = 0;
|
||||
irq(0xffee);
|
||||
return;
|
||||
}
|
||||
} else if(status.virq_enabled == true) {
|
||||
if(v == status.virq_pos && status.irq_pin == 1) {
|
||||
status.irq_triggered = true;
|
||||
status.irq_pin = 0;
|
||||
irq(0xffee);
|
||||
return;
|
||||
}
|
||||
} else if(status.hirq_enabled == true) {
|
||||
if(h >= status.hirq_pos && status.irq_pin == 1) {
|
||||
status.irq_triggered = true;
|
||||
status.irq_pin = 0;
|
||||
irq(0xffee);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exec_opcode();
|
||||
break;
|
||||
case CPUSTATE_DMA:
|
||||
dma->run();
|
||||
break;
|
||||
case CPUSTATE_STP:
|
||||
exec_opcode();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::scanline() {
|
||||
uint16 v = clock->vcounter();
|
||||
status.hdma_triggered = false;
|
||||
|
||||
if(v == 225 && status.auto_joypad_poll == true) {
|
||||
snes->poll_input();
|
||||
//When the SNES auto-polls the joypads, it writes 1, then 0 to
|
||||
//$4016, then reads from each 16 times to get the joypad state
|
||||
//information. As a result, the joypad read positions are set
|
||||
//to 16 after such a poll. Position 16 is the controller
|
||||
//connected status bit.
|
||||
status.joypad1_read_pos = 16;
|
||||
}
|
||||
if(status.virq_enabled == false) {
|
||||
status.irq_pin = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::frame() {
|
||||
status.hdma_triggered = false;
|
||||
|
||||
status.nmi_triggered = false;
|
||||
status.r4210_read = false;
|
||||
|
||||
status.irq_pin = 1;
|
||||
|
||||
dma->hdma_initialize();
|
||||
}
|
||||
|
||||
void bCPU::power() {
|
||||
regs.a = regs.x = regs.y = 0x0000;
|
||||
regs.s = 0x01ff;
|
||||
reset();
|
||||
}
|
||||
|
||||
void bCPU::reset() {
|
||||
/* reset vector location */
|
||||
regs.pc = mem_bus->read(0xfffc) | (mem_bus->read(0xfffd) << 8);
|
||||
|
||||
/* registers are not fully reset by SNES */
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
regs.s.h = 0x01;
|
||||
regs.d = 0x0000;
|
||||
regs.db = 0x00;
|
||||
regs.p = 0x34;
|
||||
regs.e = 1;
|
||||
|
||||
cpustate = CPUSTATE_RUN;
|
||||
|
||||
dma->reset();
|
||||
mmio_reset();
|
||||
|
||||
optbl = optbl_e;
|
||||
|
||||
status.hdma_triggered = false;
|
||||
|
||||
status.nmi_triggered = false;
|
||||
status.nmi_pin = 1;
|
||||
status.r4210_read = false;
|
||||
|
||||
status.irq_triggered = false;
|
||||
status.irq_pin = 1;
|
||||
}
|
||||
|
||||
void bCPU::cpu_c2() {
|
||||
if(regs.d.l != 0x00) {
|
||||
clock->add_cc1_cycles(6);
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::cpu_c4(uint16 a, uint16 b) {
|
||||
if(((a & 0xff00) != (b & 0xff00)) || !regs.p.x) {
|
||||
clock->add_cc1_cycles(6);
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::cpu_c6(uint16 a) {
|
||||
if(regs.e) {
|
||||
if((regs.pc.w & 0xff00) != (a & 0xff00)) {
|
||||
clock->add_cc1_cycles(6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::cpu_io() {
|
||||
clock->add_cc1_cycles(6);
|
||||
}
|
||||
|
||||
uint8 bCPU::op_read() {
|
||||
uint8 r;
|
||||
r = mem_bus->read(regs.pc);
|
||||
clock->add_cc1_cycles(mem_bus->speed(regs.pc));
|
||||
regs.pc.w++;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint8 bCPU::op_read(uint8 mode, uint32 addr) {
|
||||
uint8 r;
|
||||
switch(mode) {
|
||||
case OPMODE_ADDR:
|
||||
addr &= 0xffff;
|
||||
break;
|
||||
case OPMODE_LONG:
|
||||
addr &= 0xffffff;
|
||||
break;
|
||||
case OPMODE_DBR:
|
||||
addr &= 0xffffff;
|
||||
addr = (regs.db << 16) + addr;
|
||||
break;
|
||||
case OPMODE_PBR:
|
||||
addr &= 0xffff;
|
||||
addr = (regs.pc.b << 16) | addr;
|
||||
break;
|
||||
case OPMODE_DP:
|
||||
addr &= 0xffff;
|
||||
addr = (regs.d + addr) & 0xffff;
|
||||
break;
|
||||
case OPMODE_SP:
|
||||
addr &= 0xffff;
|
||||
addr = (regs.s + addr) & 0xffff;
|
||||
break;
|
||||
}
|
||||
r = mem_bus->read(addr);
|
||||
clock->add_cc1_cycles(mem_bus->speed(addr));
|
||||
return r;
|
||||
}
|
||||
|
||||
void bCPU::op_write(uint8 mode, uint32 addr, uint8 value) {
|
||||
switch(mode) {
|
||||
case OPMODE_ADDR:
|
||||
addr &= 0xffff;
|
||||
break;
|
||||
case OPMODE_LONG:
|
||||
addr &= 0xffffff;
|
||||
break;
|
||||
case OPMODE_DBR:
|
||||
addr &= 0xffffff;
|
||||
addr = (regs.db << 16) + addr;
|
||||
break;
|
||||
case OPMODE_PBR:
|
||||
addr &= 0xffff;
|
||||
addr = (regs.pc.b << 16) | addr;
|
||||
break;
|
||||
case OPMODE_DP:
|
||||
addr &= 0xffff;
|
||||
addr = (regs.d + addr) & 0xffff;
|
||||
break;
|
||||
case OPMODE_SP:
|
||||
addr &= 0xffff;
|
||||
addr = (regs.s + addr) & 0xffff;
|
||||
break;
|
||||
}
|
||||
mem_bus->write(addr, value);
|
||||
clock->add_cc1_cycles(mem_bus->speed(addr));
|
||||
}
|
||||
|
||||
uint8 bCPU::stack_read() {
|
||||
byte r;
|
||||
if(regs.e) {
|
||||
regs.s.l++;
|
||||
} else {
|
||||
regs.s.w++;
|
||||
}
|
||||
r = mem_bus->read(regs.s);
|
||||
clock->add_cc1_cycles(mem_bus->speed(regs.s));
|
||||
return r;
|
||||
}
|
||||
|
||||
void bCPU::stack_write(uint8 value) {
|
||||
mem_bus->write(regs.s, value);
|
||||
clock->add_cc1_cycles(mem_bus->speed(regs.s));
|
||||
if(regs.e) {
|
||||
regs.s.l--;
|
||||
} else {
|
||||
regs.s.w--;
|
||||
}
|
||||
}
|
||||
|
||||
bCPU::bCPU() {
|
||||
dma = new bDMA(this);
|
||||
mmio = new bCPUMMIO(this);
|
||||
|
||||
init_op_tables();
|
||||
}
|
||||
|
||||
bCPU::~bCPU() {
|
||||
delete(mmio);
|
||||
delete(dma);
|
||||
}
|
||||
@@ -1,684 +0,0 @@
|
||||
class bCPU;
|
||||
|
||||
class bDMA {
|
||||
public:
|
||||
bCPU *cpu;
|
||||
struct {
|
||||
//$420b
|
||||
bool active;
|
||||
//$420c
|
||||
bool hdma_active;
|
||||
//$43x0
|
||||
bool direction;
|
||||
bool hdma_indirect;
|
||||
int8 incmode;
|
||||
bool fixedxfer;
|
||||
uint8 xfermode;
|
||||
//$43x1
|
||||
uint8 destaddr;
|
||||
//$43x2-$43x4
|
||||
uint32 srcaddr;
|
||||
//$43x5-$43x6
|
||||
uint16 xfersize;
|
||||
//$43x7
|
||||
uint8 hdma_indirect_bank;
|
||||
|
||||
//hdma-specific
|
||||
bool hdma_first_line;
|
||||
bool hdma_repeat;
|
||||
uint16 hdma_line_counter;
|
||||
uint32 hdma_address, hdma_iaddress;
|
||||
bool hdma_completed;
|
||||
}channel[8];
|
||||
void hdma_write(uint8 i, uint8 l, uint8 x);
|
||||
void hdma_run();
|
||||
void hdma_initialize();
|
||||
void run();
|
||||
void reset();
|
||||
uint16 dma_cputommio(uint8 i, uint8 index);
|
||||
uint16 dma_mmiotocpu(uint8 i, uint8 index);
|
||||
void dma_xfer_type0(uint8 i);
|
||||
void dma_xfer_type1(uint8 i);
|
||||
void dma_xfer_type2(uint8 i);
|
||||
void dma_xfer_type3(uint8 i);
|
||||
void dma_xfer_type4(uint8 i);
|
||||
void dma_xfer_type5(uint8 i);
|
||||
|
||||
bDMA(bCPU *_cpu);
|
||||
};
|
||||
|
||||
class bCPUMMIO : public MMIO {
|
||||
public:
|
||||
bCPU *cpu;
|
||||
uint8 read (uint32 addr);
|
||||
void write(uint32 addr, uint8 value);
|
||||
bCPUMMIO(bCPU *_cpu);
|
||||
};
|
||||
|
||||
class bCPU : public CPU {
|
||||
private:
|
||||
typedef void (bCPU::*op)();
|
||||
op *optbl, optbl_e[256], optbl_MX[256], optbl_Mx[256], optbl_mX[256], optbl_mx[256];
|
||||
|
||||
public:
|
||||
enum { CPUSTATE_RUN = 0, CPUSTATE_DMA, CPUSTATE_WAI, CPUSTATE_STP };
|
||||
uint8 cpustate;
|
||||
|
||||
bDMA *dma;
|
||||
enum {
|
||||
OPMODE_ADDR = 1, OPMODE_LONG = 2,
|
||||
OPMODE_DBR = 3, OPMODE_PBR = 4,
|
||||
OPMODE_DP = 5, OPMODE_SP = 6
|
||||
};
|
||||
CPUReg24 aa, rd;
|
||||
uint8 dp, sp;
|
||||
|
||||
struct {
|
||||
bool hdma_triggered;
|
||||
|
||||
bool nmi_triggered;
|
||||
bool nmi_pin;
|
||||
bool r4210_read;
|
||||
|
||||
bool irq_triggered;
|
||||
bool irq_pin;
|
||||
|
||||
//$2181-$2183
|
||||
uint32 wram_addr;
|
||||
|
||||
//$4016
|
||||
uint8 joypad1_strobe_value;
|
||||
uint8 joypad1_read_pos;
|
||||
|
||||
//$4200
|
||||
bool nmi_enabled;
|
||||
bool hirq_enabled, virq_enabled;
|
||||
bool auto_joypad_poll;
|
||||
|
||||
//$4201
|
||||
uint8 pio;
|
||||
|
||||
//$4202-$4203
|
||||
uint8 mul_a, mul_b;
|
||||
|
||||
//$4204-$4206
|
||||
uint16 div_a;
|
||||
uint8 div_b;
|
||||
|
||||
//$4207-$420a
|
||||
uint16 hirq_pos, virq_pos;
|
||||
|
||||
//$4214-$4216
|
||||
uint16 r4214;
|
||||
uint16 r4216;
|
||||
}status;
|
||||
|
||||
uint8 pio_status();
|
||||
void irq(uint16 addr);
|
||||
void run();
|
||||
void scanline();
|
||||
void frame();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
//mmio commands
|
||||
void mmio_reset();
|
||||
uint8 mmio_r2180();
|
||||
uint8 mmio_r21c2();
|
||||
uint8 mmio_r21c3();
|
||||
uint8 mmio_r4016();
|
||||
uint8 mmio_r4210();
|
||||
uint8 mmio_r4211();
|
||||
uint8 mmio_r4212();
|
||||
uint8 mmio_r4213();
|
||||
uint8 mmio_r4214();
|
||||
uint8 mmio_r4215();
|
||||
uint8 mmio_r4216();
|
||||
uint8 mmio_r4217();
|
||||
uint8 mmio_r4218();
|
||||
uint8 mmio_r4219();
|
||||
void mmio_w2180(uint8 value);
|
||||
void mmio_w2181(uint8 value);
|
||||
void mmio_w2182(uint8 value);
|
||||
void mmio_w2183(uint8 value);
|
||||
void mmio_w4016(uint8 value);
|
||||
void mmio_w4200(uint8 value);
|
||||
void mmio_w4201(uint8 value);
|
||||
void mmio_w4202(uint8 value);
|
||||
void mmio_w4203(uint8 value);
|
||||
void mmio_w4204(uint8 value);
|
||||
void mmio_w4205(uint8 value);
|
||||
void mmio_w4206(uint8 value);
|
||||
void mmio_w4207(uint8 value);
|
||||
void mmio_w4208(uint8 value);
|
||||
void mmio_w4209(uint8 value);
|
||||
void mmio_w420a(uint8 value);
|
||||
void mmio_w420b(uint8 value);
|
||||
void mmio_w420c(uint8 value);
|
||||
void mmio_w420d(uint8 value);
|
||||
void mmio_w43x0(uint8 value, uint8 i);
|
||||
void mmio_w43x1(uint8 value, uint8 i);
|
||||
void mmio_w43x2(uint8 value, uint8 i);
|
||||
void mmio_w43x3(uint8 value, uint8 i);
|
||||
void mmio_w43x4(uint8 value, uint8 i);
|
||||
void mmio_w43x5(uint8 value, uint8 i);
|
||||
void mmio_w43x6(uint8 value, uint8 i);
|
||||
void mmio_w43x7(uint8 value, uint8 i);
|
||||
|
||||
void exec_opcode();
|
||||
|
||||
uint8 op_read ();
|
||||
uint8 op_read (uint8 mode, uint32 addr);
|
||||
void op_write(uint8 mode, uint32 addr, uint8 value);
|
||||
uint8 stack_read ();
|
||||
void stack_write(uint8 value);
|
||||
|
||||
//cpu extra-cycle conditions
|
||||
void cpu_c2();
|
||||
void cpu_c4(uint16 a, uint16 b);
|
||||
void cpu_c6(uint16 a);
|
||||
void cpu_io();
|
||||
|
||||
//opcode functions
|
||||
void init_op_tables();
|
||||
|
||||
//op_adc
|
||||
inline void flags_adc_b();
|
||||
inline void flags_adc_w();
|
||||
void op_adc_constb();
|
||||
void op_adc_constw();
|
||||
void op_adc_addrb();
|
||||
void op_adc_addrw();
|
||||
void op_adc_addrxb();
|
||||
void op_adc_addrxw();
|
||||
void op_adc_dpb();
|
||||
void op_adc_dpw();
|
||||
void op_adc_idpb();
|
||||
void op_adc_idpw();
|
||||
void op_adc_ildpb();
|
||||
void op_adc_ildpw();
|
||||
void op_adc_longb();
|
||||
void op_adc_longw();
|
||||
void op_adc_longxb();
|
||||
void op_adc_longxw();
|
||||
void op_adc_addryb();
|
||||
void op_adc_addryw();
|
||||
void op_adc_dpxb();
|
||||
void op_adc_dpxw();
|
||||
void op_adc_idpxb();
|
||||
void op_adc_idpxw();
|
||||
void op_adc_idpyb();
|
||||
void op_adc_idpyw();
|
||||
void op_adc_ildpyb();
|
||||
void op_adc_ildpyw();
|
||||
void op_adc_srb();
|
||||
void op_adc_srw();
|
||||
void op_adc_isryb();
|
||||
void op_adc_isryw();
|
||||
//op_and
|
||||
inline void flags_and_b();
|
||||
inline void flags_and_w();
|
||||
void op_and_constb();
|
||||
void op_and_constw();
|
||||
void op_and_addrb();
|
||||
void op_and_addrw();
|
||||
void op_and_addrxb();
|
||||
void op_and_addrxw();
|
||||
void op_and_dpb();
|
||||
void op_and_dpw();
|
||||
void op_and_idpb();
|
||||
void op_and_idpw();
|
||||
void op_and_ildpb();
|
||||
void op_and_ildpw();
|
||||
void op_and_longb();
|
||||
void op_and_longw();
|
||||
void op_and_longxb();
|
||||
void op_and_longxw();
|
||||
void op_and_addryb();
|
||||
void op_and_addryw();
|
||||
void op_and_dpxb();
|
||||
void op_and_dpxw();
|
||||
void op_and_idpxb();
|
||||
void op_and_idpxw();
|
||||
void op_and_idpyb();
|
||||
void op_and_idpyw();
|
||||
void op_and_ildpyb();
|
||||
void op_and_ildpyw();
|
||||
void op_and_srb();
|
||||
void op_and_srw();
|
||||
void op_and_isryb();
|
||||
void op_and_isryw();
|
||||
//op_cmp
|
||||
inline void flags_cmp_b();
|
||||
inline void flags_cmp_w();
|
||||
void op_cmp_constb();
|
||||
void op_cmp_constw();
|
||||
void op_cmp_addrb();
|
||||
void op_cmp_addrw();
|
||||
void op_cmp_addrxb();
|
||||
void op_cmp_addrxw();
|
||||
void op_cmp_dpb();
|
||||
void op_cmp_dpw();
|
||||
void op_cmp_idpb();
|
||||
void op_cmp_idpw();
|
||||
void op_cmp_ildpb();
|
||||
void op_cmp_ildpw();
|
||||
void op_cmp_longb();
|
||||
void op_cmp_longw();
|
||||
void op_cmp_longxb();
|
||||
void op_cmp_longxw();
|
||||
void op_cmp_addryb();
|
||||
void op_cmp_addryw();
|
||||
void op_cmp_dpxb();
|
||||
void op_cmp_dpxw();
|
||||
void op_cmp_idpxb();
|
||||
void op_cmp_idpxw();
|
||||
void op_cmp_idpyb();
|
||||
void op_cmp_idpyw();
|
||||
void op_cmp_ildpyb();
|
||||
void op_cmp_ildpyw();
|
||||
void op_cmp_srb();
|
||||
void op_cmp_srw();
|
||||
void op_cmp_isryb();
|
||||
void op_cmp_isryw();
|
||||
//op_eor
|
||||
inline void flags_eor_b();
|
||||
inline void flags_eor_w();
|
||||
void op_eor_constb();
|
||||
void op_eor_constw();
|
||||
void op_eor_addrb();
|
||||
void op_eor_addrw();
|
||||
void op_eor_addrxb();
|
||||
void op_eor_addrxw();
|
||||
void op_eor_dpb();
|
||||
void op_eor_dpw();
|
||||
void op_eor_idpb();
|
||||
void op_eor_idpw();
|
||||
void op_eor_ildpb();
|
||||
void op_eor_ildpw();
|
||||
void op_eor_longb();
|
||||
void op_eor_longw();
|
||||
void op_eor_longxb();
|
||||
void op_eor_longxw();
|
||||
void op_eor_addryb();
|
||||
void op_eor_addryw();
|
||||
void op_eor_dpxb();
|
||||
void op_eor_dpxw();
|
||||
void op_eor_idpxb();
|
||||
void op_eor_idpxw();
|
||||
void op_eor_idpyb();
|
||||
void op_eor_idpyw();
|
||||
void op_eor_ildpyb();
|
||||
void op_eor_ildpyw();
|
||||
void op_eor_srb();
|
||||
void op_eor_srw();
|
||||
void op_eor_isryb();
|
||||
void op_eor_isryw();
|
||||
//op_incdec
|
||||
void op_incb();
|
||||
void op_incw();
|
||||
void op_inc_addrb();
|
||||
void op_inc_addrw();
|
||||
void op_inc_addrxb();
|
||||
void op_inc_addrxw();
|
||||
void op_inc_dpb();
|
||||
void op_inc_dpw();
|
||||
void op_inc_dpxb();
|
||||
void op_inc_dpxw();
|
||||
void op_inxb();
|
||||
void op_inxw();
|
||||
void op_inyb();
|
||||
void op_inyw();
|
||||
void op_decb();
|
||||
void op_decw();
|
||||
void op_dec_addrb();
|
||||
void op_dec_addrw();
|
||||
void op_dec_addrxb();
|
||||
void op_dec_addrxw();
|
||||
void op_dec_dpb();
|
||||
void op_dec_dpw();
|
||||
void op_dec_dpxb();
|
||||
void op_dec_dpxw();
|
||||
void op_dexb();
|
||||
void op_dexw();
|
||||
void op_deyb();
|
||||
void op_deyw();
|
||||
//op_lda
|
||||
inline void flags_lda_b();
|
||||
inline void flags_lda_w();
|
||||
void op_lda_constb();
|
||||
void op_lda_constw();
|
||||
void op_lda_addrb();
|
||||
void op_lda_addrw();
|
||||
void op_lda_addrxb();
|
||||
void op_lda_addrxw();
|
||||
void op_lda_dpb();
|
||||
void op_lda_dpw();
|
||||
void op_lda_idpb();
|
||||
void op_lda_idpw();
|
||||
void op_lda_ildpb();
|
||||
void op_lda_ildpw();
|
||||
void op_lda_longb();
|
||||
void op_lda_longw();
|
||||
void op_lda_longxb();
|
||||
void op_lda_longxw();
|
||||
void op_lda_addryb();
|
||||
void op_lda_addryw();
|
||||
void op_lda_dpxb();
|
||||
void op_lda_dpxw();
|
||||
void op_lda_idpxb();
|
||||
void op_lda_idpxw();
|
||||
void op_lda_idpyb();
|
||||
void op_lda_idpyw();
|
||||
void op_lda_ildpyb();
|
||||
void op_lda_ildpyw();
|
||||
void op_lda_srb();
|
||||
void op_lda_srw();
|
||||
void op_lda_isryb();
|
||||
void op_lda_isryw();
|
||||
//op_misc
|
||||
inline void flags_bit_b();
|
||||
inline void flags_bit_w();
|
||||
void op_bit_constb();
|
||||
void op_bit_constw();
|
||||
void op_bit_addrb();
|
||||
void op_bit_addrw();
|
||||
void op_bit_addrxb();
|
||||
void op_bit_addrxw();
|
||||
void op_bit_dpb();
|
||||
void op_bit_dpw();
|
||||
void op_bit_dpxb();
|
||||
void op_bit_dpxw();
|
||||
inline void flags_cpx_b();
|
||||
inline void flags_cpx_w();
|
||||
void op_cpx_constb();
|
||||
void op_cpx_constw();
|
||||
void op_cpx_addrb();
|
||||
void op_cpx_addrw();
|
||||
void op_cpx_dpb();
|
||||
void op_cpx_dpw();
|
||||
inline void flags_cpy_b();
|
||||
inline void flags_cpy_w();
|
||||
void op_cpy_constb();
|
||||
void op_cpy_constw();
|
||||
void op_cpy_addrb();
|
||||
void op_cpy_addrw();
|
||||
void op_cpy_dpb();
|
||||
void op_cpy_dpw();
|
||||
inline void flags_ldx_b();
|
||||
inline void flags_ldx_w();
|
||||
void op_ldx_constb();
|
||||
void op_ldx_constw();
|
||||
void op_ldx_addrb();
|
||||
void op_ldx_addrw();
|
||||
void op_ldx_addryb();
|
||||
void op_ldx_addryw();
|
||||
void op_ldx_dpb();
|
||||
void op_ldx_dpw();
|
||||
void op_ldx_dpyb();
|
||||
void op_ldx_dpyw();
|
||||
inline void flags_ldy_b();
|
||||
inline void flags_ldy_w();
|
||||
void op_ldy_constb();
|
||||
void op_ldy_constw();
|
||||
void op_ldy_addrb();
|
||||
void op_ldy_addrw();
|
||||
void op_ldy_addrxb();
|
||||
void op_ldy_addrxw();
|
||||
void op_ldy_dpb();
|
||||
void op_ldy_dpw();
|
||||
void op_ldy_dpxb();
|
||||
void op_ldy_dpxw();
|
||||
void op_stx_addrb();
|
||||
void op_stx_addrw();
|
||||
void op_stx_dpb();
|
||||
void op_stx_dpw();
|
||||
void op_stx_dpyb();
|
||||
void op_stx_dpyw();
|
||||
void op_sty_addrb();
|
||||
void op_sty_addrw();
|
||||
void op_sty_dpb();
|
||||
void op_sty_dpw();
|
||||
void op_sty_dpxb();
|
||||
void op_sty_dpxw();
|
||||
void op_stz_addrb();
|
||||
void op_stz_addrw();
|
||||
void op_stz_addrxb();
|
||||
void op_stz_addrxw();
|
||||
void op_stz_dpb();
|
||||
void op_stz_dpw();
|
||||
void op_stz_dpxb();
|
||||
void op_stz_dpxw();
|
||||
void op_xba();
|
||||
void op_trb_addrb();
|
||||
void op_trb_addrw();
|
||||
void op_trb_dpb();
|
||||
void op_trb_dpw();
|
||||
void op_tsb_addrb();
|
||||
void op_tsb_addrw();
|
||||
void op_tsb_dpb();
|
||||
void op_tsb_dpw();
|
||||
void op_mvn();
|
||||
void op_mvp();
|
||||
void op_brk();
|
||||
void op_cop();
|
||||
void op_stp();
|
||||
void op_wai();
|
||||
void op_xce();
|
||||
void op_nop();
|
||||
void op_wdm();
|
||||
void op_clc();
|
||||
void op_cld();
|
||||
void op_cli();
|
||||
void op_clv();
|
||||
void op_sec();
|
||||
void op_sed();
|
||||
void op_sei();
|
||||
void op_rep();
|
||||
void op_sep();
|
||||
void op_taxb();
|
||||
void op_taxw();
|
||||
void op_tayb();
|
||||
void op_tayw();
|
||||
void op_tcd();
|
||||
void op_tcs();
|
||||
void op_tdc();
|
||||
void op_tsc();
|
||||
void op_tsxb();
|
||||
void op_tsxw();
|
||||
void op_txab();
|
||||
void op_txaw();
|
||||
void op_txsb();
|
||||
void op_txsw();
|
||||
void op_txyb();
|
||||
void op_txyw();
|
||||
void op_tyab();
|
||||
void op_tyaw();
|
||||
void op_tyxb();
|
||||
void op_tyxw();
|
||||
//op_ora
|
||||
inline void flags_ora_b();
|
||||
inline void flags_ora_w();
|
||||
void op_ora_constb();
|
||||
void op_ora_constw();
|
||||
void op_ora_addrb();
|
||||
void op_ora_addrw();
|
||||
void op_ora_addrxb();
|
||||
void op_ora_addrxw();
|
||||
void op_ora_dpb();
|
||||
void op_ora_dpw();
|
||||
void op_ora_idpb();
|
||||
void op_ora_idpw();
|
||||
void op_ora_ildpb();
|
||||
void op_ora_ildpw();
|
||||
void op_ora_longb();
|
||||
void op_ora_longw();
|
||||
void op_ora_longxb();
|
||||
void op_ora_longxw();
|
||||
void op_ora_addryb();
|
||||
void op_ora_addryw();
|
||||
void op_ora_dpxb();
|
||||
void op_ora_dpxw();
|
||||
void op_ora_idpxb();
|
||||
void op_ora_idpxw();
|
||||
void op_ora_idpyb();
|
||||
void op_ora_idpyw();
|
||||
void op_ora_ildpyb();
|
||||
void op_ora_ildpyw();
|
||||
void op_ora_srb();
|
||||
void op_ora_srw();
|
||||
void op_ora_isryb();
|
||||
void op_ora_isryw();
|
||||
//op_pc
|
||||
void op_jmp_addr();
|
||||
void op_jmp_long();
|
||||
void op_jmp_iaddr();
|
||||
void op_jmp_iaddrx();
|
||||
void op_jmp_iladdr();
|
||||
void op_jsr_addr();
|
||||
void op_jsr_long();
|
||||
void op_jsr_iaddrx();
|
||||
void op_rtie();
|
||||
void op_rtin();
|
||||
void op_rts();
|
||||
void op_rtl();
|
||||
void op_bra();
|
||||
void op_brl();
|
||||
void op_bcc();
|
||||
void op_bcs();
|
||||
void op_bne();
|
||||
void op_beq();
|
||||
void op_bpl();
|
||||
void op_bmi();
|
||||
void op_bvc();
|
||||
void op_bvs();
|
||||
//op_sbc
|
||||
inline void flags_sbc_b();
|
||||
inline void flags_sbc_w();
|
||||
void op_sbc_constb();
|
||||
void op_sbc_constw();
|
||||
void op_sbc_addrb();
|
||||
void op_sbc_addrw();
|
||||
void op_sbc_addrxb();
|
||||
void op_sbc_addrxw();
|
||||
void op_sbc_dpb();
|
||||
void op_sbc_dpw();
|
||||
void op_sbc_idpb();
|
||||
void op_sbc_idpw();
|
||||
void op_sbc_ildpb();
|
||||
void op_sbc_ildpw();
|
||||
void op_sbc_longb();
|
||||
void op_sbc_longw();
|
||||
void op_sbc_longxb();
|
||||
void op_sbc_longxw();
|
||||
void op_sbc_addryb();
|
||||
void op_sbc_addryw();
|
||||
void op_sbc_dpxb();
|
||||
void op_sbc_dpxw();
|
||||
void op_sbc_idpxb();
|
||||
void op_sbc_idpxw();
|
||||
void op_sbc_idpyb();
|
||||
void op_sbc_idpyw();
|
||||
void op_sbc_ildpyb();
|
||||
void op_sbc_ildpyw();
|
||||
void op_sbc_srb();
|
||||
void op_sbc_srw();
|
||||
void op_sbc_isryb();
|
||||
void op_sbc_isryw();
|
||||
//op_shift
|
||||
void op_aslb();
|
||||
void op_aslw();
|
||||
void op_asl_addrb();
|
||||
void op_asl_addrw();
|
||||
void op_asl_addrxb();
|
||||
void op_asl_addrxw();
|
||||
void op_asl_dpb();
|
||||
void op_asl_dpw();
|
||||
void op_asl_dpxb();
|
||||
void op_asl_dpxw();
|
||||
void op_lsrb();
|
||||
void op_lsrw();
|
||||
void op_lsr_addrb();
|
||||
void op_lsr_addrw();
|
||||
void op_lsr_addrxb();
|
||||
void op_lsr_addrxw();
|
||||
void op_lsr_dpb();
|
||||
void op_lsr_dpw();
|
||||
void op_lsr_dpxb();
|
||||
void op_lsr_dpxw();
|
||||
void op_rolb();
|
||||
void op_rolw();
|
||||
void op_rol_addrb();
|
||||
void op_rol_addrw();
|
||||
void op_rol_addrxb();
|
||||
void op_rol_addrxw();
|
||||
void op_rol_dpb();
|
||||
void op_rol_dpw();
|
||||
void op_rol_dpxb();
|
||||
void op_rol_dpxw();
|
||||
void op_rorb();
|
||||
void op_rorw();
|
||||
void op_ror_addrb();
|
||||
void op_ror_addrw();
|
||||
void op_ror_addrxb();
|
||||
void op_ror_addrxw();
|
||||
void op_ror_dpb();
|
||||
void op_ror_dpw();
|
||||
void op_ror_dpxb();
|
||||
void op_ror_dpxw();
|
||||
//op_sta
|
||||
void op_sta_addrb();
|
||||
void op_sta_addrw();
|
||||
void op_sta_addrxb();
|
||||
void op_sta_addrxw();
|
||||
void op_sta_dpb();
|
||||
void op_sta_dpw();
|
||||
void op_sta_idpb();
|
||||
void op_sta_idpw();
|
||||
void op_sta_ildpb();
|
||||
void op_sta_ildpw();
|
||||
void op_sta_longb();
|
||||
void op_sta_longw();
|
||||
void op_sta_longxb();
|
||||
void op_sta_longxw();
|
||||
void op_sta_addryb();
|
||||
void op_sta_addryw();
|
||||
void op_sta_dpxb();
|
||||
void op_sta_dpxw();
|
||||
void op_sta_idpxb();
|
||||
void op_sta_idpxw();
|
||||
void op_sta_idpyb();
|
||||
void op_sta_idpyw();
|
||||
void op_sta_ildpyb();
|
||||
void op_sta_ildpyw();
|
||||
void op_sta_srb();
|
||||
void op_sta_srw();
|
||||
void op_sta_isryb();
|
||||
void op_sta_isryw();
|
||||
//op_stack
|
||||
void op_phab();
|
||||
void op_phaw();
|
||||
void op_phb();
|
||||
void op_phd();
|
||||
void op_phk();
|
||||
void op_php();
|
||||
void op_phxb();
|
||||
void op_phxw();
|
||||
void op_phyb();
|
||||
void op_phyw();
|
||||
void op_plab();
|
||||
void op_plaw();
|
||||
void op_plb();
|
||||
void op_pld();
|
||||
void op_plp();
|
||||
void op_plxb();
|
||||
void op_plxw();
|
||||
void op_plyb();
|
||||
void op_plyw();
|
||||
void op_pea();
|
||||
void op_pei();
|
||||
void op_per();
|
||||
|
||||
bCPU();
|
||||
~bCPU();
|
||||
};
|
||||
@@ -1,519 +0,0 @@
|
||||
void bCPU::exec_opcode() {
|
||||
(this->*optbl[op_read()])();
|
||||
snes->notify(SNES::CPU_EXEC_OPCODE);
|
||||
}
|
||||
|
||||
void bCPU::init_op_tables() {
|
||||
optbl = optbl_e;
|
||||
|
||||
/* 0x */
|
||||
optbl[0x00] = op_brk;
|
||||
optbl[0x01] = op_ora_idpxb;
|
||||
optbl[0x02] = op_cop;
|
||||
optbl[0x03] = op_ora_srb;
|
||||
optbl[0x04] = op_tsb_dpb;
|
||||
optbl[0x05] = op_ora_dpb;
|
||||
optbl[0x06] = op_asl_dpb;
|
||||
optbl[0x07] = op_ora_ildpb;
|
||||
optbl[0x08] = op_php;
|
||||
optbl[0x09] = op_ora_constb;
|
||||
optbl[0x0a] = op_aslb;
|
||||
optbl[0x0b] = op_phd;
|
||||
optbl[0x0c] = op_tsb_addrb;
|
||||
optbl[0x0d] = op_ora_addrb;
|
||||
optbl[0x0e] = op_asl_addrb;
|
||||
optbl[0x0f] = op_ora_longb;
|
||||
/* 1x */
|
||||
optbl[0x10] = op_bpl;
|
||||
optbl[0x11] = op_ora_idpyb;
|
||||
optbl[0x12] = op_ora_idpb;
|
||||
optbl[0x13] = op_ora_isryb;
|
||||
optbl[0x14] = op_trb_dpb;
|
||||
optbl[0x15] = op_ora_dpxb;
|
||||
optbl[0x16] = op_asl_dpxb;
|
||||
optbl[0x17] = op_ora_ildpyb;
|
||||
optbl[0x18] = op_clc;
|
||||
optbl[0x19] = op_ora_addryb;
|
||||
optbl[0x1a] = op_incb;
|
||||
optbl[0x1b] = op_tcs;
|
||||
optbl[0x1c] = op_trb_addrb;
|
||||
optbl[0x1d] = op_ora_addrxb;
|
||||
optbl[0x1e] = op_asl_addrxb;
|
||||
optbl[0x1f] = op_ora_longxb;
|
||||
/* 2x */
|
||||
optbl[0x20] = op_jsr_addr;
|
||||
optbl[0x21] = op_and_idpxb;
|
||||
optbl[0x22] = op_jsr_long;
|
||||
optbl[0x23] = op_and_srb;
|
||||
optbl[0x24] = op_bit_dpb;
|
||||
optbl[0x25] = op_and_dpb;
|
||||
optbl[0x26] = op_rol_dpb;
|
||||
optbl[0x27] = op_and_ildpb;
|
||||
optbl[0x28] = op_plp;
|
||||
optbl[0x29] = op_and_constb;
|
||||
optbl[0x2a] = op_rolb;
|
||||
optbl[0x2b] = op_pld;
|
||||
optbl[0x2c] = op_bit_addrb;
|
||||
optbl[0x2d] = op_and_addrb;
|
||||
optbl[0x2e] = op_rol_addrb;
|
||||
optbl[0x2f] = op_and_longb;
|
||||
/* 3x */
|
||||
optbl[0x30] = op_bmi;
|
||||
optbl[0x31] = op_and_idpyb;
|
||||
optbl[0x32] = op_and_idpb;
|
||||
optbl[0x33] = op_and_isryb;
|
||||
optbl[0x34] = op_bit_dpxb;
|
||||
optbl[0x35] = op_and_dpxb;
|
||||
optbl[0x36] = op_rol_dpxb;
|
||||
optbl[0x37] = op_and_ildpyb;
|
||||
optbl[0x38] = op_sec;
|
||||
optbl[0x39] = op_and_addryb;
|
||||
optbl[0x3a] = op_decb;
|
||||
optbl[0x3b] = op_tsc;
|
||||
optbl[0x3c] = op_bit_addrxb;
|
||||
optbl[0x3d] = op_and_addrxb;
|
||||
optbl[0x3e] = op_rol_addrxb;
|
||||
optbl[0x3f] = op_and_longxb;
|
||||
/* 4x */
|
||||
optbl[0x40] = op_rtie;
|
||||
optbl[0x41] = op_eor_idpxb;
|
||||
optbl[0x42] = op_wdm;
|
||||
optbl[0x43] = op_eor_srb;
|
||||
optbl[0x44] = op_mvp;
|
||||
optbl[0x45] = op_eor_dpb;
|
||||
optbl[0x46] = op_lsr_dpb;
|
||||
optbl[0x47] = op_eor_ildpb;
|
||||
optbl[0x48] = op_phab;
|
||||
optbl[0x49] = op_eor_constb;
|
||||
optbl[0x4a] = op_lsrb;
|
||||
optbl[0x4b] = op_phk;
|
||||
optbl[0x4c] = op_jmp_addr;
|
||||
optbl[0x4d] = op_eor_addrb;
|
||||
optbl[0x4e] = op_lsr_addrb;
|
||||
optbl[0x4f] = op_eor_longb;
|
||||
/* 5x */
|
||||
optbl[0x50] = op_bvc;
|
||||
optbl[0x51] = op_eor_idpyb;
|
||||
optbl[0x52] = op_eor_idpb;
|
||||
optbl[0x53] = op_eor_isryb;
|
||||
optbl[0x54] = op_mvn;
|
||||
optbl[0x55] = op_eor_dpxb;
|
||||
optbl[0x56] = op_lsr_dpxb;
|
||||
optbl[0x57] = op_eor_ildpyb;
|
||||
optbl[0x58] = op_cli;
|
||||
optbl[0x59] = op_eor_addryb;
|
||||
optbl[0x5a] = op_phyb;
|
||||
optbl[0x5b] = op_tcd;
|
||||
optbl[0x5c] = op_jmp_long;
|
||||
optbl[0x5d] = op_eor_addrxb;
|
||||
optbl[0x5e] = op_lsr_addrxb;
|
||||
optbl[0x5f] = op_eor_longxb;
|
||||
/* 6x */
|
||||
optbl[0x60] = op_rts;
|
||||
optbl[0x61] = op_adc_idpxb;
|
||||
optbl[0x62] = op_per;
|
||||
optbl[0x63] = op_adc_srb;
|
||||
optbl[0x64] = op_stz_dpb;
|
||||
optbl[0x65] = op_adc_dpb;
|
||||
optbl[0x66] = op_ror_dpb;
|
||||
optbl[0x67] = op_adc_ildpb;
|
||||
optbl[0x68] = op_plab;
|
||||
optbl[0x69] = op_adc_constb;
|
||||
optbl[0x6a] = op_rorb;
|
||||
optbl[0x6b] = op_rtl;
|
||||
optbl[0x6c] = op_jmp_iaddr;
|
||||
optbl[0x6d] = op_adc_addrb;
|
||||
optbl[0x6e] = op_ror_addrb;
|
||||
optbl[0x6f] = op_adc_longb;
|
||||
/* 7x */
|
||||
optbl[0x70] = op_bvs;
|
||||
optbl[0x71] = op_adc_idpyb;
|
||||
optbl[0x72] = op_adc_idpb;
|
||||
optbl[0x73] = op_adc_isryb;
|
||||
optbl[0x74] = op_stz_dpxb;
|
||||
optbl[0x75] = op_adc_dpxb;
|
||||
optbl[0x76] = op_ror_dpxb;
|
||||
optbl[0x77] = op_adc_ildpyb;
|
||||
optbl[0x78] = op_sei;
|
||||
optbl[0x79] = op_adc_addryb;
|
||||
optbl[0x7a] = op_plyb;
|
||||
optbl[0x7b] = op_tdc;
|
||||
optbl[0x7c] = op_jmp_iaddrx;
|
||||
optbl[0x7d] = op_adc_addrxb;
|
||||
optbl[0x7e] = op_ror_addrxb;
|
||||
optbl[0x7f] = op_adc_longxb;
|
||||
/* 8x */
|
||||
optbl[0x80] = op_bra;
|
||||
optbl[0x81] = op_sta_idpxb;
|
||||
optbl[0x82] = op_brl;
|
||||
optbl[0x83] = op_sta_srb;
|
||||
optbl[0x84] = op_sty_dpb;
|
||||
optbl[0x85] = op_sta_dpb;
|
||||
optbl[0x86] = op_stx_dpb;
|
||||
optbl[0x87] = op_sta_ildpb;
|
||||
optbl[0x88] = op_deyb;
|
||||
optbl[0x89] = op_bit_constb;
|
||||
optbl[0x8a] = op_txab;
|
||||
optbl[0x8b] = op_phb;
|
||||
optbl[0x8c] = op_sty_addrb;
|
||||
optbl[0x8d] = op_sta_addrb;
|
||||
optbl[0x8e] = op_stx_addrb;
|
||||
optbl[0x8f] = op_sta_longb;
|
||||
/* 9x */
|
||||
optbl[0x90] = op_bcc;
|
||||
optbl[0x91] = op_sta_idpyb;
|
||||
optbl[0x92] = op_sta_idpb;
|
||||
optbl[0x93] = op_sta_isryb;
|
||||
optbl[0x94] = op_sty_dpxb;
|
||||
optbl[0x95] = op_sta_dpxb;
|
||||
optbl[0x96] = op_stx_dpyb;
|
||||
optbl[0x97] = op_sta_ildpyb;
|
||||
optbl[0x98] = op_tyab;
|
||||
optbl[0x99] = op_sta_addryb;
|
||||
optbl[0x9a] = op_txsb;
|
||||
optbl[0x9b] = op_txyb;
|
||||
optbl[0x9c] = op_stz_addrb;
|
||||
optbl[0x9d] = op_sta_addrxb;
|
||||
optbl[0x9e] = op_stz_addrxb;
|
||||
optbl[0x9f] = op_sta_longxb;
|
||||
/* ax */
|
||||
optbl[0xa0] = op_ldy_constb;
|
||||
optbl[0xa1] = op_lda_idpxb;
|
||||
optbl[0xa2] = op_ldx_constb;
|
||||
optbl[0xa3] = op_lda_srb;
|
||||
optbl[0xa4] = op_ldy_dpb;
|
||||
optbl[0xa5] = op_lda_dpb;
|
||||
optbl[0xa6] = op_ldx_dpb;
|
||||
optbl[0xa7] = op_lda_ildpb;
|
||||
optbl[0xa8] = op_tayb;
|
||||
optbl[0xa9] = op_lda_constb;
|
||||
optbl[0xaa] = op_taxb;
|
||||
optbl[0xab] = op_plb;
|
||||
optbl[0xac] = op_ldy_addrb;
|
||||
optbl[0xad] = op_lda_addrb;
|
||||
optbl[0xae] = op_ldx_addrb;
|
||||
optbl[0xaf] = op_lda_longb;
|
||||
/* bx */
|
||||
optbl[0xb0] = op_bcs;
|
||||
optbl[0xb1] = op_lda_idpyb;
|
||||
optbl[0xb2] = op_lda_idpb;
|
||||
optbl[0xb3] = op_lda_isryb;
|
||||
optbl[0xb4] = op_ldy_dpxb;
|
||||
optbl[0xb5] = op_lda_dpxb;
|
||||
optbl[0xb6] = op_ldx_dpyb;
|
||||
optbl[0xb7] = op_lda_ildpyb;
|
||||
optbl[0xb8] = op_clv;
|
||||
optbl[0xb9] = op_lda_addryb;
|
||||
optbl[0xba] = op_tsxb;
|
||||
optbl[0xbb] = op_tyxb;
|
||||
optbl[0xbc] = op_ldy_addrxb;
|
||||
optbl[0xbd] = op_lda_addrxb;
|
||||
optbl[0xbe] = op_ldx_addryb;
|
||||
optbl[0xbf] = op_lda_longxb;
|
||||
/* cx */
|
||||
optbl[0xc0] = op_cpy_constb;
|
||||
optbl[0xc1] = op_cmp_idpxb;
|
||||
optbl[0xc2] = op_rep;
|
||||
optbl[0xc3] = op_cmp_srb;
|
||||
optbl[0xc4] = op_cpy_dpb;
|
||||
optbl[0xc5] = op_cmp_dpb;
|
||||
optbl[0xc6] = op_dec_dpb;
|
||||
optbl[0xc7] = op_cmp_ildpb;
|
||||
optbl[0xc8] = op_inyb;
|
||||
optbl[0xc9] = op_cmp_constb;
|
||||
optbl[0xca] = op_dexb;
|
||||
optbl[0xcb] = op_wai;
|
||||
optbl[0xcc] = op_cpy_addrb;
|
||||
optbl[0xcd] = op_cmp_addrb;
|
||||
optbl[0xce] = op_dec_addrb;
|
||||
optbl[0xcf] = op_cmp_longb;
|
||||
/* dx */
|
||||
optbl[0xd0] = op_bne;
|
||||
optbl[0xd1] = op_cmp_idpyb;
|
||||
optbl[0xd2] = op_cmp_idpb;
|
||||
optbl[0xd3] = op_cmp_isryb;
|
||||
optbl[0xd4] = op_pei;
|
||||
optbl[0xd5] = op_cmp_dpxb;
|
||||
optbl[0xd6] = op_dec_dpxb;
|
||||
optbl[0xd7] = op_cmp_ildpyb;
|
||||
optbl[0xd8] = op_cld;
|
||||
optbl[0xd9] = op_cmp_addryb;
|
||||
optbl[0xda] = op_phxb;
|
||||
optbl[0xdb] = op_stp;
|
||||
optbl[0xdc] = op_jmp_iladdr;
|
||||
optbl[0xdd] = op_cmp_addrxb;
|
||||
optbl[0xde] = op_dec_addrxb;
|
||||
optbl[0xdf] = op_cmp_longxb;
|
||||
/* ex */
|
||||
optbl[0xe0] = op_cpx_constb;
|
||||
optbl[0xe1] = op_sbc_idpxb;
|
||||
optbl[0xe2] = op_sep;
|
||||
optbl[0xe3] = op_sbc_srb;
|
||||
optbl[0xe4] = op_cpx_dpb;
|
||||
optbl[0xe5] = op_sbc_dpb;
|
||||
optbl[0xe6] = op_inc_dpb;
|
||||
optbl[0xe7] = op_sbc_ildpb;
|
||||
optbl[0xe8] = op_inxb;
|
||||
optbl[0xe9] = op_sbc_constb;
|
||||
optbl[0xea] = op_nop;
|
||||
optbl[0xeb] = op_xba;
|
||||
optbl[0xec] = op_cpx_addrb;
|
||||
optbl[0xed] = op_sbc_addrb;
|
||||
optbl[0xee] = op_inc_addrb;
|
||||
optbl[0xef] = op_sbc_longb;
|
||||
/* fx */
|
||||
optbl[0xf0] = op_beq;
|
||||
optbl[0xf1] = op_sbc_idpyb;
|
||||
optbl[0xf2] = op_sbc_idpb;
|
||||
optbl[0xf3] = op_sbc_isryb;
|
||||
optbl[0xf4] = op_pea;
|
||||
optbl[0xf5] = op_sbc_dpxb;
|
||||
optbl[0xf6] = op_inc_dpxb;
|
||||
optbl[0xf7] = op_sbc_ildpyb;
|
||||
optbl[0xf8] = op_sed;
|
||||
optbl[0xf9] = op_sbc_addryb;
|
||||
optbl[0xfa] = op_plxb;
|
||||
optbl[0xfb] = op_xce;
|
||||
optbl[0xfc] = op_jsr_iaddrx;
|
||||
optbl[0xfd] = op_sbc_addrxb;
|
||||
optbl[0xfe] = op_inc_addrxb;
|
||||
optbl[0xff] = op_sbc_longxb;
|
||||
|
||||
memcpy(optbl_MX, optbl_e, sizeof(optbl_e));
|
||||
memcpy(optbl_Mx, optbl_e, sizeof(optbl_e));
|
||||
memcpy(optbl_mX, optbl_e, sizeof(optbl_e));
|
||||
memcpy(optbl_mx, optbl_e, sizeof(optbl_e));
|
||||
|
||||
/* adc */
|
||||
optbl_mX[0x69] = optbl_mx[0x69] = op_adc_constw;
|
||||
optbl_mX[0x6d] = optbl_mx[0x6d] = op_adc_addrw;
|
||||
optbl_mX[0x7d] = optbl_mx[0x7d] = op_adc_addrxw;
|
||||
optbl_mX[0x65] = optbl_mx[0x65] = op_adc_dpw;
|
||||
optbl_mX[0x72] = optbl_mx[0x72] = op_adc_idpw;
|
||||
optbl_mX[0x67] = optbl_mx[0x67] = op_adc_ildpw;
|
||||
optbl_mX[0x6f] = optbl_mx[0x6f] = op_adc_longw;
|
||||
optbl_mX[0x7f] = optbl_mx[0x7f] = op_adc_longxw;
|
||||
optbl_mX[0x79] = optbl_mx[0x79] = op_adc_addryw;
|
||||
optbl_mX[0x75] = optbl_mx[0x75] = op_adc_dpxw;
|
||||
optbl_mX[0x61] = optbl_mx[0x61] = op_adc_idpxw;
|
||||
optbl_mX[0x71] = optbl_mx[0x71] = op_adc_idpyw;
|
||||
optbl_mX[0x77] = optbl_mx[0x77] = op_adc_ildpyw;
|
||||
optbl_mX[0x63] = optbl_mx[0x63] = op_adc_srw;
|
||||
optbl_mX[0x73] = optbl_mx[0x73] = op_adc_isryw;
|
||||
|
||||
/* and */
|
||||
optbl_mX[0x29] = optbl_mx[0x29] = op_and_constw;
|
||||
optbl_mX[0x2d] = optbl_mx[0x2d] = op_and_addrw;
|
||||
optbl_mX[0x3d] = optbl_mx[0x3d] = op_and_addrxw;
|
||||
optbl_mX[0x25] = optbl_mx[0x25] = op_and_dpw;
|
||||
optbl_mX[0x32] = optbl_mx[0x32] = op_and_idpw;
|
||||
optbl_mX[0x27] = optbl_mx[0x27] = op_and_ildpw;
|
||||
optbl_mX[0x2f] = optbl_mx[0x2f] = op_and_longw;
|
||||
optbl_mX[0x3f] = optbl_mx[0x3f] = op_and_longxw;
|
||||
optbl_mX[0x39] = optbl_mx[0x39] = op_and_addryw;
|
||||
optbl_mX[0x35] = optbl_mx[0x35] = op_and_dpxw;
|
||||
optbl_mX[0x21] = optbl_mx[0x21] = op_and_idpxw;
|
||||
optbl_mX[0x31] = optbl_mx[0x31] = op_and_idpyw;
|
||||
optbl_mX[0x37] = optbl_mx[0x37] = op_and_ildpyw;
|
||||
optbl_mX[0x23] = optbl_mx[0x23] = op_and_srw;
|
||||
optbl_mX[0x33] = optbl_mx[0x33] = op_and_isryw;
|
||||
|
||||
/* cmp */
|
||||
optbl_mX[0xc9] = optbl_mx[0xc9] = op_cmp_constw;
|
||||
optbl_mX[0xcd] = optbl_mx[0xcd] = op_cmp_addrw;
|
||||
optbl_mX[0xdd] = optbl_mx[0xdd] = op_cmp_addrxw;
|
||||
optbl_mX[0xc5] = optbl_mx[0xc5] = op_cmp_dpw;
|
||||
optbl_mX[0xd2] = optbl_mx[0xd2] = op_cmp_idpw;
|
||||
optbl_mX[0xc7] = optbl_mx[0xc7] = op_cmp_ildpw;
|
||||
optbl_mX[0xcf] = optbl_mx[0xcf] = op_cmp_longw;
|
||||
optbl_mX[0xdf] = optbl_mx[0xdf] = op_cmp_longxw;
|
||||
optbl_mX[0xd9] = optbl_mx[0xd9] = op_cmp_addryw;
|
||||
optbl_mX[0xd5] = optbl_mx[0xd5] = op_cmp_dpxw;
|
||||
optbl_mX[0xc1] = optbl_mx[0xc1] = op_cmp_idpxw;
|
||||
optbl_mX[0xd1] = optbl_mx[0xd1] = op_cmp_idpyw;
|
||||
optbl_mX[0xd7] = optbl_mx[0xd7] = op_cmp_ildpyw;
|
||||
optbl_mX[0xc3] = optbl_mx[0xc3] = op_cmp_srw;
|
||||
optbl_mX[0xd3] = optbl_mx[0xd3] = op_cmp_isryw;
|
||||
|
||||
/* eor */
|
||||
optbl_mX[0x49] = optbl_mx[0x49] = op_eor_constw;
|
||||
optbl_mX[0x4d] = optbl_mx[0x4d] = op_eor_addrw;
|
||||
optbl_mX[0x5d] = optbl_mx[0x5d] = op_eor_addrxw;
|
||||
optbl_mX[0x45] = optbl_mx[0x45] = op_eor_dpw;
|
||||
optbl_mX[0x52] = optbl_mx[0x52] = op_eor_idpw;
|
||||
optbl_mX[0x47] = optbl_mx[0x47] = op_eor_ildpw;
|
||||
optbl_mX[0x4f] = optbl_mx[0x4f] = op_eor_longw;
|
||||
optbl_mX[0x5f] = optbl_mx[0x5f] = op_eor_longxw;
|
||||
optbl_mX[0x59] = optbl_mx[0x59] = op_eor_addryw;
|
||||
optbl_mX[0x55] = optbl_mx[0x55] = op_eor_dpxw;
|
||||
optbl_mX[0x41] = optbl_mx[0x41] = op_eor_idpxw;
|
||||
optbl_mX[0x51] = optbl_mx[0x51] = op_eor_idpyw;
|
||||
optbl_mX[0x57] = optbl_mx[0x57] = op_eor_ildpyw;
|
||||
optbl_mX[0x43] = optbl_mx[0x43] = op_eor_srw;
|
||||
optbl_mX[0x53] = optbl_mx[0x53] = op_eor_isryw;
|
||||
|
||||
/* lda */
|
||||
optbl_mX[0xa9] = optbl_mx[0xa9] = op_lda_constw;
|
||||
optbl_mX[0xad] = optbl_mx[0xad] = op_lda_addrw;
|
||||
optbl_mX[0xbd] = optbl_mx[0xbd] = op_lda_addrxw;
|
||||
optbl_mX[0xa5] = optbl_mx[0xa5] = op_lda_dpw;
|
||||
optbl_mX[0xb2] = optbl_mx[0xb2] = op_lda_idpw;
|
||||
optbl_mX[0xa7] = optbl_mx[0xa7] = op_lda_ildpw;
|
||||
optbl_mX[0xaf] = optbl_mx[0xaf] = op_lda_longw;
|
||||
optbl_mX[0xbf] = optbl_mx[0xbf] = op_lda_longxw;
|
||||
optbl_mX[0xb9] = optbl_mx[0xb9] = op_lda_addryw;
|
||||
optbl_mX[0xb5] = optbl_mx[0xb5] = op_lda_dpxw;
|
||||
optbl_mX[0xa1] = optbl_mx[0xa1] = op_lda_idpxw;
|
||||
optbl_mX[0xb1] = optbl_mx[0xb1] = op_lda_idpyw;
|
||||
optbl_mX[0xb7] = optbl_mx[0xb7] = op_lda_ildpyw;
|
||||
optbl_mX[0xa3] = optbl_mx[0xa3] = op_lda_srw;
|
||||
optbl_mX[0xb3] = optbl_mx[0xb3] = op_lda_isryw;
|
||||
|
||||
/* ora */
|
||||
optbl_mX[0x09] = optbl_mx[0x09] = op_ora_constw;
|
||||
optbl_mX[0x0d] = optbl_mx[0x0d] = op_ora_addrw;
|
||||
optbl_mX[0x1d] = optbl_mx[0x1d] = op_ora_addrxw;
|
||||
optbl_mX[0x05] = optbl_mx[0x05] = op_ora_dpw;
|
||||
optbl_mX[0x12] = optbl_mx[0x12] = op_ora_idpw;
|
||||
optbl_mX[0x07] = optbl_mx[0x07] = op_ora_ildpw;
|
||||
optbl_mX[0x0f] = optbl_mx[0x0f] = op_ora_longw;
|
||||
optbl_mX[0x1f] = optbl_mx[0x1f] = op_ora_longxw;
|
||||
optbl_mX[0x19] = optbl_mx[0x19] = op_ora_addryw;
|
||||
optbl_mX[0x15] = optbl_mx[0x15] = op_ora_dpxw;
|
||||
optbl_mX[0x01] = optbl_mx[0x01] = op_ora_idpxw;
|
||||
optbl_mX[0x11] = optbl_mx[0x11] = op_ora_idpyw;
|
||||
optbl_mX[0x17] = optbl_mx[0x17] = op_ora_ildpyw;
|
||||
optbl_mX[0x03] = optbl_mx[0x03] = op_ora_srw;
|
||||
optbl_mX[0x13] = optbl_mx[0x13] = op_ora_isryw;
|
||||
|
||||
/* sbc */
|
||||
optbl_mX[0xe9] = optbl_mx[0xe9] = op_sbc_constw;
|
||||
optbl_mX[0xed] = optbl_mx[0xed] = op_sbc_addrw;
|
||||
optbl_mX[0xfd] = optbl_mx[0xfd] = op_sbc_addrxw;
|
||||
optbl_mX[0xe5] = optbl_mx[0xe5] = op_sbc_dpw;
|
||||
optbl_mX[0xf2] = optbl_mx[0xf2] = op_sbc_idpw;
|
||||
optbl_mX[0xe7] = optbl_mx[0xe7] = op_sbc_ildpw;
|
||||
optbl_mX[0xef] = optbl_mx[0xef] = op_sbc_longw;
|
||||
optbl_mX[0xff] = optbl_mx[0xff] = op_sbc_longxw;
|
||||
optbl_mX[0xf9] = optbl_mx[0xf9] = op_sbc_addryw;
|
||||
optbl_mX[0xf5] = optbl_mx[0xf5] = op_sbc_dpxw;
|
||||
optbl_mX[0xe1] = optbl_mx[0xe1] = op_sbc_idpxw;
|
||||
optbl_mX[0xf1] = optbl_mx[0xf1] = op_sbc_idpyw;
|
||||
optbl_mX[0xf7] = optbl_mx[0xf7] = op_sbc_ildpyw;
|
||||
optbl_mX[0xe3] = optbl_mx[0xe3] = op_sbc_srw;
|
||||
optbl_mX[0xf3] = optbl_mx[0xf3] = op_sbc_isryw;
|
||||
|
||||
/* sta */
|
||||
optbl_mX[0x8d] = optbl_mx[0x8d] = op_sta_addrw;
|
||||
optbl_mX[0x9d] = optbl_mx[0x9d] = op_sta_addrxw;
|
||||
optbl_mX[0x85] = optbl_mx[0x85] = op_sta_dpw;
|
||||
optbl_mX[0x92] = optbl_mx[0x92] = op_sta_idpw;
|
||||
optbl_mX[0x87] = optbl_mx[0x87] = op_sta_ildpw;
|
||||
optbl_mX[0x8f] = optbl_mx[0x8f] = op_sta_longw;
|
||||
optbl_mX[0x9f] = optbl_mx[0x9f] = op_sta_longxw;
|
||||
optbl_mX[0x99] = optbl_mx[0x99] = op_sta_addryw;
|
||||
optbl_mX[0x95] = optbl_mx[0x95] = op_sta_dpxw;
|
||||
optbl_mX[0x81] = optbl_mx[0x81] = op_sta_idpxw;
|
||||
optbl_mX[0x91] = optbl_mx[0x91] = op_sta_idpyw;
|
||||
optbl_mX[0x97] = optbl_mx[0x97] = op_sta_ildpyw;
|
||||
optbl_mX[0x83] = optbl_mx[0x83] = op_sta_srw;
|
||||
optbl_mX[0x93] = optbl_mx[0x93] = op_sta_isryw;
|
||||
|
||||
/* incdec */
|
||||
optbl_mX[0x1a] = optbl_mx[0x1a] = op_incw;
|
||||
optbl_mX[0xee] = optbl_mx[0xee] = op_inc_addrw;
|
||||
optbl_mX[0xfe] = optbl_mx[0xfe] = op_inc_addrxw;
|
||||
optbl_mX[0xe6] = optbl_mx[0xe6] = op_inc_dpw;
|
||||
optbl_mX[0xf6] = optbl_mx[0xf6] = op_inc_dpxw;
|
||||
optbl_mX[0x3a] = optbl_mx[0x3a] = op_decw;
|
||||
optbl_mX[0xce] = optbl_mx[0xce] = op_dec_addrw;
|
||||
optbl_mX[0xde] = optbl_mx[0xde] = op_dec_addrxw;
|
||||
optbl_mX[0xc6] = optbl_mx[0xc6] = op_dec_dpw;
|
||||
optbl_mX[0xd6] = optbl_mx[0xd6] = op_dec_dpxw;
|
||||
|
||||
optbl_Mx[0xe8] = optbl_mx[0xe8] = op_inxw;
|
||||
optbl_Mx[0xc8] = optbl_mx[0xc8] = op_inyw;
|
||||
optbl_Mx[0xca] = optbl_mx[0xca] = op_dexw;
|
||||
optbl_Mx[0x88] = optbl_mx[0x88] = op_deyw;
|
||||
|
||||
/* misc */
|
||||
optbl_mX[0x89] = optbl_mx[0x89] = op_bit_constw;
|
||||
optbl_mX[0x2c] = optbl_mx[0x2c] = op_bit_addrw;
|
||||
optbl_mX[0x3c] = optbl_mx[0x3c] = op_bit_addrxw;
|
||||
optbl_mX[0x24] = optbl_mx[0x24] = op_bit_dpw;
|
||||
optbl_mX[0x34] = optbl_mx[0x34] = op_bit_dpxw;
|
||||
optbl_mX[0x9c] = optbl_mx[0x9c] = op_stz_addrw;
|
||||
optbl_mX[0x9e] = optbl_mx[0x9e] = op_stz_addrxw;
|
||||
optbl_mX[0x64] = optbl_mx[0x64] = op_stz_dpw;
|
||||
optbl_mX[0x74] = optbl_mx[0x74] = op_stz_dpxw;
|
||||
optbl_mX[0x1c] = optbl_mx[0x1c] = op_trb_addrw;
|
||||
optbl_mX[0x14] = optbl_mx[0x14] = op_trb_dpw;
|
||||
optbl_mX[0x0c] = optbl_mx[0x0c] = op_tsb_addrw;
|
||||
optbl_mX[0x04] = optbl_mx[0x04] = op_tsb_dpw;
|
||||
optbl_mX[0x8a] = optbl_mx[0x8a] = op_txaw;
|
||||
optbl_mX[0x98] = optbl_mx[0x98] = op_tyaw;
|
||||
|
||||
optbl_Mx[0xe0] = optbl_mx[0xe0] = op_cpx_constw;
|
||||
optbl_Mx[0xec] = optbl_mx[0xec] = op_cpx_addrw;
|
||||
optbl_Mx[0xe4] = optbl_mx[0xe4] = op_cpx_dpw;
|
||||
optbl_Mx[0xc0] = optbl_mx[0xc0] = op_cpy_constw;
|
||||
optbl_Mx[0xcc] = optbl_mx[0xcc] = op_cpy_addrw;
|
||||
optbl_Mx[0xc4] = optbl_mx[0xc4] = op_cpy_dpw;
|
||||
optbl_Mx[0xa2] = optbl_mx[0xa2] = op_ldx_constw;
|
||||
optbl_Mx[0xae] = optbl_mx[0xae] = op_ldx_addrw;
|
||||
optbl_Mx[0xbe] = optbl_mx[0xbe] = op_ldx_addryw;
|
||||
optbl_Mx[0xa6] = optbl_mx[0xa6] = op_ldx_dpw;
|
||||
optbl_Mx[0xb6] = optbl_mx[0xb6] = op_ldx_dpyw;
|
||||
optbl_Mx[0xa0] = optbl_mx[0xa0] = op_ldy_constw;
|
||||
optbl_Mx[0xac] = optbl_mx[0xac] = op_ldy_addrw;
|
||||
optbl_Mx[0xbc] = optbl_mx[0xbc] = op_ldy_addrxw;
|
||||
optbl_Mx[0xa4] = optbl_mx[0xa4] = op_ldy_dpw;
|
||||
optbl_Mx[0xb4] = optbl_mx[0xb4] = op_ldy_dpxw;
|
||||
optbl_Mx[0x8e] = optbl_mx[0x8e] = op_stx_addrw;
|
||||
optbl_Mx[0x86] = optbl_mx[0x86] = op_stx_dpw;
|
||||
optbl_Mx[0x96] = optbl_mx[0x96] = op_stx_dpyw;
|
||||
optbl_Mx[0x8c] = optbl_mx[0x8c] = op_sty_addrw;
|
||||
optbl_Mx[0x84] = optbl_mx[0x84] = op_sty_dpw;
|
||||
optbl_Mx[0x94] = optbl_mx[0x94] = op_sty_dpxw;
|
||||
optbl_Mx[0xaa] = optbl_mx[0xaa] = op_taxw;
|
||||
optbl_Mx[0xa8] = optbl_mx[0xa8] = op_tayw;
|
||||
optbl_Mx[0xba] = optbl_mx[0xba] = op_tsxw;
|
||||
optbl_Mx[0x9a] = optbl_mx[0x9a] = op_txsw;
|
||||
optbl_Mx[0x9b] = optbl_mx[0x9b] = op_txyw;
|
||||
optbl_Mx[0xbb] = optbl_mx[0xbb] = op_tyxw;
|
||||
|
||||
/* pc */
|
||||
optbl_MX[0x40] = optbl_Mx[0x40] = op_rtin;
|
||||
optbl_mX[0x40] = optbl_mx[0x40] = op_rtin;
|
||||
|
||||
/* shift */
|
||||
optbl_mX[0x0a] = optbl_mx[0x0a] = op_aslw;
|
||||
optbl_mX[0x0e] = optbl_mx[0x0e] = op_asl_addrw;
|
||||
optbl_mX[0x1e] = optbl_mx[0x1e] = op_asl_addrxw;
|
||||
optbl_mX[0x06] = optbl_mx[0x06] = op_asl_dpw;
|
||||
optbl_mX[0x16] = optbl_mx[0x16] = op_asl_dpxw;
|
||||
optbl_mX[0x4a] = optbl_mx[0x4a] = op_lsrw;
|
||||
optbl_mX[0x4e] = optbl_mx[0x4e] = op_lsr_addrw;
|
||||
optbl_mX[0x5e] = optbl_mx[0x5e] = op_lsr_addrxw;
|
||||
optbl_mX[0x46] = optbl_mx[0x46] = op_lsr_dpw;
|
||||
optbl_mX[0x56] = optbl_mx[0x56] = op_lsr_dpxw;
|
||||
optbl_mX[0x2a] = optbl_mx[0x2a] = op_rolw;
|
||||
optbl_mX[0x2e] = optbl_mx[0x2e] = op_rol_addrw;
|
||||
optbl_mX[0x3e] = optbl_mx[0x3e] = op_rol_addrxw;
|
||||
optbl_mX[0x26] = optbl_mx[0x26] = op_rol_dpw;
|
||||
optbl_mX[0x36] = optbl_mx[0x36] = op_rol_dpxw;
|
||||
optbl_mX[0x6a] = optbl_mx[0x6a] = op_rorw;
|
||||
optbl_mX[0x6e] = optbl_mx[0x6e] = op_ror_addrw;
|
||||
optbl_mX[0x7e] = optbl_mx[0x7e] = op_ror_addrxw;
|
||||
optbl_mX[0x66] = optbl_mx[0x66] = op_ror_dpw;
|
||||
optbl_mX[0x76] = optbl_mx[0x76] = op_ror_dpxw;
|
||||
|
||||
/* stack */
|
||||
optbl_mX[0x48] = optbl_mx[0x48] = op_phaw;
|
||||
optbl_mX[0x68] = optbl_mx[0x68] = op_plaw;
|
||||
|
||||
optbl_Mx[0xda] = optbl_mx[0xda] = op_phxw;
|
||||
optbl_Mx[0x5a] = optbl_mx[0x5a] = op_phyw;
|
||||
optbl_Mx[0xfa] = optbl_mx[0xfa] = op_plxw;
|
||||
optbl_Mx[0x7a] = optbl_mx[0x7a] = op_plyw;
|
||||
}
|
||||
@@ -1,702 +0,0 @@
|
||||
void bCPU::mmio_reset() {
|
||||
//$2181-$2183
|
||||
status.wram_addr = 0x000000;
|
||||
|
||||
//$4016
|
||||
status.joypad1_strobe_value = 0x00;
|
||||
status.joypad1_read_pos = 0;
|
||||
|
||||
//$4200
|
||||
status.nmi_enabled = false;
|
||||
status.hirq_enabled = false;
|
||||
status.virq_enabled = false;
|
||||
status.auto_joypad_poll = false;
|
||||
|
||||
//$4201
|
||||
status.pio = 0xff;
|
||||
|
||||
//$4202-$4203
|
||||
status.mul_a = 0x00;
|
||||
status.mul_b = 0x00;
|
||||
|
||||
//$4204-$4206
|
||||
status.div_a = 0x0000;
|
||||
status.div_b = 0x00;
|
||||
|
||||
//$4207-$420a
|
||||
status.hirq_pos = 0;
|
||||
status.virq_pos = 0;
|
||||
|
||||
//$4214-$4217
|
||||
status.r4214 = 0x0000;
|
||||
status.r4216 = 0x0000;
|
||||
}
|
||||
|
||||
//WMDATA
|
||||
uint8 bCPU::mmio_r2180() {
|
||||
uint8 r;
|
||||
r = mem_bus->read(0x7e0000 | status.wram_addr);
|
||||
status.wram_addr++;
|
||||
status.wram_addr &= 0x01ffff;
|
||||
return r;
|
||||
}
|
||||
|
||||
//???
|
||||
uint8 bCPU::mmio_r21c2() {
|
||||
return 0x20;
|
||||
}
|
||||
|
||||
//???
|
||||
uint8 bCPU::mmio_r21c3() {
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
/*
|
||||
The joypad contains a small bit shifter that has 16 bits.
|
||||
Reading from 4016 reads one bit from this buffer, then moves
|
||||
the buffer left one, and adds a '1' to the rightmost bit.
|
||||
Writing a one to $4016 will fill the buffer with the current
|
||||
joypad button states, and lock the bit shifter at position
|
||||
zero. All reads will be the first buffer state, or 'B'.
|
||||
A zero must be written back to $4016 to unlock the buffer,
|
||||
so that reads will increment the bit shifting position.
|
||||
*/
|
||||
//JOYSER0
|
||||
uint8 bCPU::mmio_r4016() {
|
||||
uint8 r = 0x00;
|
||||
if(status.joypad1_strobe_value == 1) {
|
||||
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_B);
|
||||
} else {
|
||||
switch(status.joypad1_read_pos) {
|
||||
case 0:r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_B); break;
|
||||
case 1:r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_Y); break;
|
||||
case 2:r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_SELECT);break;
|
||||
case 3:r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_START); break;
|
||||
case 4:r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_UP); break;
|
||||
case 5:r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_DOWN); break;
|
||||
case 6:r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_LEFT); break;
|
||||
case 7:r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_RIGHT); break;
|
||||
case 8:r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_A); break;
|
||||
case 9:r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_X); break;
|
||||
case 10:r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_L); break;
|
||||
case 11:r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_R); break;
|
||||
case 16:r |= 1;break; //joypad connected bit
|
||||
default:r |= 1;break; //after 16th read, all subsequent reads return 1
|
||||
}
|
||||
if(++status.joypad1_read_pos > 17)status.joypad1_read_pos = 17;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
//RDNMI
|
||||
uint8 bCPU::mmio_r4210() {
|
||||
uint8 r = 0x00;
|
||||
uint16 v, h, hcycles, visible_scanlines;
|
||||
v = clock->vcounter();
|
||||
h = clock->hcounter();
|
||||
hcycles = clock->hcycles();
|
||||
visible_scanlines = clock->visible_scanlines();
|
||||
if(status.r4210_read == false) {
|
||||
if(v == 0 && hcycles < 2) {
|
||||
r |= 0x80;
|
||||
status.r4210_read = true;
|
||||
} else if(v == (visible_scanlines + 1) && hcycles >= 2) {
|
||||
r |= 0x80;
|
||||
status.r4210_read = true;
|
||||
} else if(v >= (visible_scanlines + 1)) {
|
||||
r |= 0x80;
|
||||
status.r4210_read = true;
|
||||
}
|
||||
}
|
||||
r |= 0x40;
|
||||
r |= 0x02; //cpu version number
|
||||
status.nmi_pin = 1;
|
||||
return r;
|
||||
}
|
||||
|
||||
//TIMEUP
|
||||
uint8 bCPU::mmio_r4211() {
|
||||
uint8 r = 0x00;
|
||||
r |= 0x40;
|
||||
if(status.irq_triggered == true)r |= 0x80;
|
||||
status.irq_triggered = false;
|
||||
return r;
|
||||
}
|
||||
|
||||
//HVBJOY
|
||||
uint8 bCPU::mmio_r4212() {
|
||||
uint8 r;
|
||||
uint16 v, h, hcycles, visible_scanlines;
|
||||
r = 0x00;
|
||||
|
||||
v = clock->vcounter();
|
||||
h = clock->hcounter();
|
||||
hcycles = clock->hcycles();
|
||||
visible_scanlines = clock->visible_scanlines();
|
||||
|
||||
//auto joypad polling
|
||||
if(v >= (visible_scanlines + 1) && v <= (visible_scanlines + 3))r |= 0x01;
|
||||
|
||||
//hblank
|
||||
if(hcycles <= 4 || hcycles >= 1098)r |= 0x40;
|
||||
|
||||
//vblank
|
||||
if(v == 0 && hcycles < 2)r |= 0x80;
|
||||
if(v == (visible_scanlines + 1) && hcycles >= 2)r |= 0x80;
|
||||
if(v > (visible_scanlines + 1))r |= 0x80;
|
||||
return r;
|
||||
}
|
||||
|
||||
//RDIO
|
||||
uint8 bCPU::mmio_r4213() {
|
||||
return status.pio;
|
||||
}
|
||||
|
||||
//RDDIVL
|
||||
uint8 bCPU::mmio_r4214() {
|
||||
return status.r4214;
|
||||
}
|
||||
|
||||
//RDDIVH
|
||||
uint8 bCPU::mmio_r4215() {
|
||||
return status.r4214 >> 8;
|
||||
}
|
||||
|
||||
//RDMPYL
|
||||
uint8 bCPU::mmio_r4216() {
|
||||
return status.r4216;
|
||||
}
|
||||
|
||||
//RDMPYH
|
||||
uint8 bCPU::mmio_r4217() {
|
||||
return status.r4216 >> 8;
|
||||
}
|
||||
|
||||
//JOY1L
|
||||
uint8 bCPU::mmio_r4218() {
|
||||
uint8 r = 0x00;
|
||||
uint16 v = clock->vcounter();
|
||||
if(status.auto_joypad_poll == false)return 0x00; //can't read joypad if auto polling not enabled
|
||||
//if(v >= 225 && v <= 227)return 0x00; //can't read joypad while SNES is polling input
|
||||
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_A) << 7;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_X) << 6;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_L) << 5;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_R) << 4;
|
||||
return r;
|
||||
}
|
||||
|
||||
//JOY1H
|
||||
uint8 bCPU::mmio_r4219() {
|
||||
uint8 r = 0x00;
|
||||
uint16 v = clock->vcounter();
|
||||
if(status.auto_joypad_poll == false)return 0x00; //can't read joypad if auto polling not enabled
|
||||
//if(v >= 225 && v <= 227)return 0x00; //can't read joypad while SNES is polling input
|
||||
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_B) << 7;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_Y) << 6;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_SELECT) << 5;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_START) << 4;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_UP) << 3;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_DOWN) << 2;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_LEFT) << 1;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_RIGHT);
|
||||
return r;
|
||||
}
|
||||
|
||||
uint8 bCPUMMIO::read(uint32 addr) {
|
||||
clock->sync();
|
||||
switch(addr) {
|
||||
case 0x2180:return cpu->mmio_r2180(); //WMDATA
|
||||
case 0x21c2:return cpu->mmio_r21c2(); //???
|
||||
case 0x21c3:return cpu->mmio_r21c3(); //???
|
||||
case 0x4016:return cpu->mmio_r4016(); //JOYSER0
|
||||
case 0x4210:return cpu->mmio_r4210(); //RDNMI
|
||||
case 0x4211:return cpu->mmio_r4211(); //TIMEUP
|
||||
case 0x4212:return cpu->mmio_r4212(); //HVBJOY
|
||||
case 0x4213:return cpu->mmio_r4213(); //RDIO
|
||||
case 0x4214:return cpu->mmio_r4214(); //RDDIVL
|
||||
case 0x4215:return cpu->mmio_r4215(); //RDDIVH
|
||||
case 0x4216:return cpu->mmio_r4216(); //RDMPYL
|
||||
case 0x4217:return cpu->mmio_r4217(); //RDMPYH
|
||||
case 0x4218:return cpu->mmio_r4218(); //JOY1L
|
||||
case 0x4219:return cpu->mmio_r4219(); //JOY1H
|
||||
}
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
//WMDATA
|
||||
void bCPU::mmio_w2180(uint8 value) {
|
||||
mem_bus->write(0x7e0000 | status.wram_addr, value);
|
||||
status.wram_addr++;
|
||||
status.wram_addr &= 0x01ffff;
|
||||
}
|
||||
|
||||
//WMADDL
|
||||
void bCPU::mmio_w2181(uint8 value) {
|
||||
status.wram_addr = (status.wram_addr & 0xffff00) | value;
|
||||
status.wram_addr &= 0x01ffff;
|
||||
}
|
||||
|
||||
//WMADDM
|
||||
void bCPU::mmio_w2182(uint8 value) {
|
||||
status.wram_addr = (status.wram_addr & 0xff00ff) | (value << 8);
|
||||
status.wram_addr &= 0x01ffff;
|
||||
}
|
||||
|
||||
//WMADDH
|
||||
void bCPU::mmio_w2183(uint8 value) {
|
||||
status.wram_addr = (status.wram_addr & 0x00ffff) | (value << 16);
|
||||
status.wram_addr &= 0x01ffff;
|
||||
}
|
||||
|
||||
//JOYSER0
|
||||
void bCPU::mmio_w4016(uint8 value) {
|
||||
status.joypad1_strobe_value = (value & 1);
|
||||
if(value == 1) {
|
||||
snes->poll_input();
|
||||
status.joypad1_read_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//NMITIMEN
|
||||
void bCPU::mmio_w4200(uint8 value) {
|
||||
status.nmi_enabled = !!(value & 0x80);
|
||||
status.virq_enabled = !!(value & 0x20);
|
||||
status.hirq_enabled = !!(value & 0x10);
|
||||
status.auto_joypad_poll = !!(value & 0x01);
|
||||
}
|
||||
|
||||
//WRIO
|
||||
void bCPU::mmio_w4201(uint8 value) {
|
||||
if((status.pio & 0x80) && !(value & 0x80)) {
|
||||
ppu->latch_counters();
|
||||
}
|
||||
status.pio = value;
|
||||
}
|
||||
|
||||
//WRMPYA
|
||||
void bCPU::mmio_w4202(uint8 value) {
|
||||
status.mul_a = value;
|
||||
}
|
||||
|
||||
void bCPU::mmio_w4203(uint8 value) {
|
||||
status.mul_b = value;
|
||||
status.r4216 = status.mul_a * status.mul_b;
|
||||
}
|
||||
|
||||
//WRDIVL
|
||||
void bCPU::mmio_w4204(uint8 value) {
|
||||
status.div_a = (status.div_a & 0xff00) | value;
|
||||
}
|
||||
|
||||
//WRDIVH
|
||||
void bCPU::mmio_w4205(uint8 value) {
|
||||
status.div_a = (status.div_a & 0x00ff) | (value << 8);
|
||||
}
|
||||
|
||||
//WRDIVB
|
||||
void bCPU::mmio_w4206(uint8 value) {
|
||||
status.div_b = value;
|
||||
status.r4214 = (status.div_b)?status.div_a / status.div_b:0;
|
||||
status.r4216 = (status.div_b)?status.div_a % status.div_b:0;
|
||||
}
|
||||
|
||||
//HTIMEL
|
||||
void bCPU::mmio_w4207(uint8 value) {
|
||||
status.hirq_pos = (status.hirq_pos & 0xff00) | value;
|
||||
}
|
||||
|
||||
//HTIMEH
|
||||
void bCPU::mmio_w4208(uint8 value) {
|
||||
status.hirq_pos = (status.hirq_pos & 0x00ff) | (value << 8);
|
||||
}
|
||||
|
||||
//VTIMEL
|
||||
void bCPU::mmio_w4209(uint8 value) {
|
||||
status.virq_pos = (status.virq_pos & 0xff00) | value;
|
||||
}
|
||||
|
||||
//VTIMEH
|
||||
void bCPU::mmio_w420a(uint8 value) {
|
||||
status.virq_pos = (status.virq_pos & 0x00ff) | (value << 8);
|
||||
}
|
||||
|
||||
//DMAEN
|
||||
void bCPU::mmio_w420b(uint8 value) {
|
||||
if(value != 0x00) {
|
||||
clock->add_cc1_cycles(18);
|
||||
}
|
||||
|
||||
for(int i=0;i<8;i++) {
|
||||
if(value & (1 << i)) {
|
||||
dma->channel[i].active = true;
|
||||
dma->channel[i].hdma_active = false;
|
||||
clock->add_cc1_cycles(8);
|
||||
cpustate = CPUSTATE_DMA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//HDMAEN
|
||||
void bCPU::mmio_w420c(uint8 value) {
|
||||
for(int i=0;i<8;i++) {
|
||||
dma->channel[i].hdma_active = !!(value & (1 << i));
|
||||
}
|
||||
}
|
||||
|
||||
//MEMSEL
|
||||
void bCPU::mmio_w420d(uint8 value) {
|
||||
mem_bus->fastROM = value & 1;
|
||||
}
|
||||
|
||||
//DMAPx
|
||||
void bCPU::mmio_w43x0(uint8 value, uint8 i) {
|
||||
dma->channel[i].direction = !!(value & 0x80);
|
||||
dma->channel[i].hdma_indirect = !!(value & 0x40);
|
||||
dma->channel[i].incmode = (value & 0x10)?-1:1;
|
||||
dma->channel[i].fixedxfer = !!(value & 0x08);
|
||||
dma->channel[i].xfermode = value & 7;
|
||||
}
|
||||
|
||||
//BBADx
|
||||
void bCPU::mmio_w43x1(uint8 value, uint8 i) {
|
||||
dma->channel[i].destaddr = value;
|
||||
}
|
||||
|
||||
//A1TxL
|
||||
void bCPU::mmio_w43x2(uint8 value, uint8 i) {
|
||||
dma->channel[i].srcaddr = (dma->channel[i].srcaddr & 0xffff00) | value;
|
||||
}
|
||||
|
||||
//A1TxH
|
||||
void bCPU::mmio_w43x3(uint8 value, uint8 i) {
|
||||
dma->channel[i].srcaddr = (dma->channel[i].srcaddr & 0xff00ff) | (value << 8);
|
||||
}
|
||||
|
||||
//A1Bx
|
||||
void bCPU::mmio_w43x4(uint8 value, uint8 i) {
|
||||
dma->channel[i].srcaddr = (dma->channel[i].srcaddr & 0x00ffff) | (value << 16);
|
||||
}
|
||||
|
||||
//DASxL
|
||||
void bCPU::mmio_w43x5(uint8 value, uint8 i) {
|
||||
dma->channel[i].xfersize = (dma->channel[i].xfersize & 0xff00) | value;
|
||||
}
|
||||
|
||||
//DASxH
|
||||
void bCPU::mmio_w43x6(uint8 value, uint8 i) {
|
||||
dma->channel[i].xfersize = (dma->channel[i].xfersize & 0x00ff) | (value << 8);
|
||||
}
|
||||
|
||||
//DASBx
|
||||
void bCPU::mmio_w43x7(uint8 value, uint8 i) {
|
||||
dma->channel[i].hdma_indirect_bank = value;
|
||||
}
|
||||
|
||||
void bCPUMMIO::write(uint32 addr, uint8 value) {
|
||||
int i;
|
||||
clock->sync();
|
||||
switch(addr) {
|
||||
case 0x2180:cpu->mmio_w2180(value);return; //WMDATA
|
||||
case 0x2181:cpu->mmio_w2181(value);return; //WMADDL
|
||||
case 0x2182:cpu->mmio_w2182(value);return; //WMADDM
|
||||
case 0x2183:cpu->mmio_w2183(value);return; //WMADDH
|
||||
case 0x4016:cpu->mmio_w4016(value);return; //JOYSER0
|
||||
case 0x4200:cpu->mmio_w4200(value);return; //NMITIMEN
|
||||
case 0x4201:cpu->mmio_w4201(value);return; //WRIO
|
||||
case 0x4202:cpu->mmio_w4202(value);return; //WRMPYA
|
||||
case 0x4203:cpu->mmio_w4203(value);return; //WRMPYB
|
||||
case 0x4204:cpu->mmio_w4204(value);return; //WRDIVL
|
||||
case 0x4205:cpu->mmio_w4205(value);return; //WRDIVH
|
||||
case 0x4206:cpu->mmio_w4206(value);return; //WRDIVB
|
||||
case 0x4207:cpu->mmio_w4207(value);return; //HTIMEL
|
||||
case 0x4208:cpu->mmio_w4208(value);return; //HTIMEH
|
||||
case 0x4209:cpu->mmio_w4209(value);return; //VTIMEL
|
||||
case 0x420a:cpu->mmio_w420a(value);return; //VTIMEH
|
||||
case 0x420b:cpu->mmio_w420b(value);return; //DMAEN
|
||||
case 0x420c:cpu->mmio_w420c(value);return; //HDMAEN
|
||||
case 0x420d:cpu->mmio_w420d(value);return; //MEMSEL
|
||||
//DMAPx
|
||||
case 0x4300:case 0x4310:case 0x4320:case 0x4330:
|
||||
case 0x4340:case 0x4350:case 0x4360:case 0x4370:
|
||||
cpu->mmio_w43x0(value, (addr >> 4) & 7);
|
||||
return;
|
||||
//BBADx
|
||||
case 0x4301:case 0x4311:case 0x4321:case 0x4331:
|
||||
case 0x4341:case 0x4351:case 0x4361:case 0x4371:
|
||||
cpu->mmio_w43x1(value, (addr >> 4) & 7);
|
||||
return;
|
||||
//A1TxL
|
||||
case 0x4302:case 0x4312:case 0x4322:case 0x4332:
|
||||
case 0x4342:case 0x4352:case 0x4362:case 0x4372:
|
||||
cpu->mmio_w43x2(value, (addr >> 4) & 7);
|
||||
return;
|
||||
//A1TxH
|
||||
case 0x4303:case 0x4313:case 0x4323:case 0x4333:
|
||||
case 0x4343:case 0x4353:case 0x4363:case 0x4373:
|
||||
cpu->mmio_w43x3(value, (addr >> 4) & 7);
|
||||
return;
|
||||
//A1Bx
|
||||
case 0x4304:case 0x4314:case 0x4324:case 0x4334:
|
||||
case 0x4344:case 0x4354:case 0x4364:case 0x4374:
|
||||
cpu->mmio_w43x4(value, (addr >> 4) & 7);
|
||||
return;
|
||||
//DASxL
|
||||
case 0x4305:case 0x4315:case 0x4325:case 0x4335:
|
||||
case 0x4345:case 0x4355:case 0x4365:case 0x4375:
|
||||
cpu->mmio_w43x5(value, (addr >> 4) & 7);
|
||||
return;
|
||||
//DASxH
|
||||
case 0x4306:case 0x4316:case 0x4326:case 0x4336:
|
||||
case 0x4346:case 0x4356:case 0x4366:case 0x4376:
|
||||
cpu->mmio_w43x6(value, (addr >> 4) & 7);
|
||||
return;
|
||||
//DASBx
|
||||
case 0x4307:case 0x4317:case 0x4327:case 0x4337:
|
||||
case 0x4347:case 0x4357:case 0x4367:case 0x4377:
|
||||
cpu->mmio_w43x7(value, (addr >> 4) & 7);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bCPUMMIO::bCPUMMIO(bCPU *_cpu) {
|
||||
cpu = _cpu;
|
||||
}
|
||||
|
||||
uint16 bDMA::dma_cputommio(uint8 i, uint8 index) {
|
||||
uint8 x;
|
||||
x = mem_bus->read(channel[i].srcaddr);
|
||||
mem_bus->write(0x2100 | ((channel[i].destaddr + index) & 0xff), x);
|
||||
if(channel[i].fixedxfer == false) {
|
||||
channel[i].srcaddr = (channel[i].srcaddr & 0xff0000) + ((channel[i].srcaddr + channel[i].incmode) & 0xffff);
|
||||
}
|
||||
clock->add_cc1_cycles(8);
|
||||
return --channel[i].xfersize;
|
||||
}
|
||||
|
||||
uint16 bDMA::dma_mmiotocpu(uint8 i, uint8 index) {
|
||||
uint8 x;
|
||||
x = mem_bus->read(0x2100 | ((channel[i].destaddr + index) & 0xff));
|
||||
mem_bus->write(channel[i].srcaddr, x);
|
||||
if(channel[i].fixedxfer == false) {
|
||||
channel[i].srcaddr = (channel[i].srcaddr & 0xff0000) + ((channel[i].srcaddr + channel[i].incmode) & 0xffff);
|
||||
}
|
||||
clock->add_cc1_cycles(8);
|
||||
return --channel[i].xfersize;
|
||||
}
|
||||
|
||||
void bDMA::dma_xfer_type0(uint8 i) {
|
||||
if(channel[i].direction == 0) {
|
||||
if(dma_cputommio(i, 0) == 0)return;
|
||||
} else {
|
||||
if(dma_mmiotocpu(i, 0) == 0)return;
|
||||
}
|
||||
}
|
||||
|
||||
void bDMA::dma_xfer_type1(uint8 i) {
|
||||
if(channel[i].direction == 0) {
|
||||
if(dma_cputommio(i, 0) == 0)return;
|
||||
if(dma_cputommio(i, 1) == 0)return;
|
||||
} else {
|
||||
if(dma_mmiotocpu(i, 0) == 0)return;
|
||||
if(dma_mmiotocpu(i, 1) == 0)return;
|
||||
}
|
||||
}
|
||||
|
||||
void bDMA::dma_xfer_type2(uint8 i) {
|
||||
if(channel[i].direction == 0) {
|
||||
if(dma_cputommio(i, 0) == 0)return;
|
||||
if(dma_cputommio(i, 0) == 0)return;
|
||||
} else {
|
||||
if(dma_mmiotocpu(i, 0) == 0)return;
|
||||
if(dma_mmiotocpu(i, 0) == 0)return;
|
||||
}
|
||||
}
|
||||
|
||||
void bDMA::dma_xfer_type3(uint8 i) {
|
||||
if(channel[i].direction == 0) {
|
||||
if(dma_cputommio(i, 0) == 0)return;
|
||||
if(dma_cputommio(i, 0) == 0)return;
|
||||
if(dma_cputommio(i, 1) == 0)return;
|
||||
if(dma_cputommio(i, 1) == 0)return;
|
||||
} else {
|
||||
if(dma_mmiotocpu(i, 0) == 0)return;
|
||||
if(dma_mmiotocpu(i, 0) == 0)return;
|
||||
if(dma_mmiotocpu(i, 1) == 0)return;
|
||||
if(dma_mmiotocpu(i, 1) == 0)return;
|
||||
}
|
||||
}
|
||||
|
||||
void bDMA::dma_xfer_type4(uint8 i) {
|
||||
if(channel[i].direction == 0) {
|
||||
if(dma_cputommio(i, 0) == 0)return;
|
||||
if(dma_cputommio(i, 1) == 0)return;
|
||||
if(dma_cputommio(i, 2) == 0)return;
|
||||
if(dma_cputommio(i, 3) == 0)return;
|
||||
} else {
|
||||
if(dma_mmiotocpu(i, 0) == 0)return;
|
||||
if(dma_mmiotocpu(i, 1) == 0)return;
|
||||
if(dma_mmiotocpu(i, 2) == 0)return;
|
||||
if(dma_mmiotocpu(i, 3) == 0)return;
|
||||
}
|
||||
}
|
||||
|
||||
void bDMA::dma_xfer_type5(uint8 i) {
|
||||
if(channel[i].direction == 0) {
|
||||
if(dma_cputommio(i, 0) == 0)return;
|
||||
if(dma_cputommio(i, 1) == 0)return;
|
||||
if(dma_cputommio(i, 0) == 0)return;
|
||||
if(dma_cputommio(i, 1) == 0)return;
|
||||
} else {
|
||||
if(dma_mmiotocpu(i, 0) == 0)return;
|
||||
if(dma_mmiotocpu(i, 1) == 0)return;
|
||||
if(dma_mmiotocpu(i, 0) == 0)return;
|
||||
if(dma_mmiotocpu(i, 1) == 0)return;
|
||||
}
|
||||
}
|
||||
|
||||
void bDMA::run() {
|
||||
for(int i=0;i<8;i++) {
|
||||
if(channel[i].active == false)continue;
|
||||
switch(channel[i].xfermode) {
|
||||
case 0:dma_xfer_type0(i);break;
|
||||
case 1:dma_xfer_type1(i);break;
|
||||
case 2:dma_xfer_type2(i);break;
|
||||
case 3:dma_xfer_type3(i);break;
|
||||
case 4:dma_xfer_type4(i);break;
|
||||
case 5:dma_xfer_type5(i);break;
|
||||
case 6:dma_xfer_type2(i);break;
|
||||
case 7:dma_xfer_type3(i);break;
|
||||
}
|
||||
if(channel[i].xfersize == 0) {
|
||||
channel[i].active = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
cpu->cpustate = bCPU::CPUSTATE_RUN;
|
||||
}
|
||||
|
||||
void bDMA::hdma_write(uint8 i, uint8 l, uint8 x) {
|
||||
switch(channel[i].xfermode) {
|
||||
case 0:mem_bus->write(0x2100 | ((channel[i].destaddr) & 0xff), x);break;
|
||||
case 1:mem_bus->write(0x2100 | ((channel[i].destaddr + l) & 0xff), x);break;
|
||||
case 2:mem_bus->write(0x2100 | ((channel[i].destaddr) & 0xff), x);break;
|
||||
case 3:mem_bus->write(0x2100 | ((channel[i].destaddr + (l >> 1)) & 0xff), x);break;
|
||||
case 4:mem_bus->write(0x2100 | ((channel[i].destaddr + l) & 0xff), x);break;
|
||||
case 5:mem_bus->write(0x2100 | ((channel[i].destaddr + (l & 1)) & 0xff), x);break;
|
||||
case 6:mem_bus->write(0x2100 | ((channel[i].destaddr) & 0xff), x);break;
|
||||
case 7:mem_bus->write(0x2100 | ((channel[i].destaddr + (l >> 1)) & 0xff), x);break;
|
||||
}
|
||||
}
|
||||
|
||||
void bDMA::hdma_run() {
|
||||
int l, xferlen;
|
||||
uint8 x, active_channels = 0;
|
||||
for(int i=0;i<8;i++) {
|
||||
if(channel[i].hdma_completed == true)continue;
|
||||
clock->add_cc1_cycles(8);
|
||||
active_channels++;
|
||||
if(channel[i].hdma_line_counter == 0) {
|
||||
channel[i].hdma_line_counter = mem_bus->read(channel[i].hdma_address++);
|
||||
// channel[i].r43x8 = channel[i].hdma_address;
|
||||
if(channel[i].hdma_line_counter == 0) {
|
||||
channel[i].hdma_completed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(channel[i].hdma_line_counter > 0x80) {
|
||||
channel[i].hdma_repeat = true;
|
||||
channel[i].hdma_line_counter -= 0x80;
|
||||
} else {
|
||||
channel[i].hdma_repeat = false;
|
||||
}
|
||||
|
||||
channel[i].hdma_first_line = true;
|
||||
if(channel[i].hdma_indirect == false) {
|
||||
channel[i].hdma_iaddress = channel[i].hdma_address;
|
||||
} else {
|
||||
channel[i].hdma_iaddress = mem_bus->read(channel[i].hdma_address);
|
||||
channel[i].hdma_iaddress |= mem_bus->read(channel[i].hdma_address + 1) << 8;
|
||||
channel[i].hdma_iaddress |= channel[i].hdma_indirect_bank << 16;
|
||||
channel[i].hdma_address += 2;
|
||||
clock->add_cc1_cycles(16);
|
||||
}
|
||||
}
|
||||
|
||||
channel[i].hdma_line_counter--;
|
||||
if(channel[i].hdma_first_line == false && channel[i].hdma_repeat == false)continue;
|
||||
channel[i].hdma_first_line = false;
|
||||
|
||||
if(channel[i].hdma_indirect == false) {
|
||||
channel[i].hdma_iaddress = channel[i].hdma_address;
|
||||
}
|
||||
|
||||
switch(channel[i].xfermode) {
|
||||
case 0: xferlen = 1;break;
|
||||
case 1:case 2:case 6: xferlen = 2;break;
|
||||
case 3:case 4:case 5:case 7:xferlen = 4;break;
|
||||
}
|
||||
|
||||
for(l=0;l<xferlen;l++) {
|
||||
x = mem_bus->read(channel[i].hdma_iaddress++);
|
||||
if(channel[i].hdma_indirect == false) {
|
||||
channel[i].hdma_address++;
|
||||
}
|
||||
hdma_write(i, l, x);
|
||||
clock->add_cc1_cycles(8);
|
||||
}
|
||||
}
|
||||
if(active_channels != 0) {
|
||||
clock->add_cc1_cycles(18);
|
||||
}
|
||||
}
|
||||
|
||||
void bDMA::hdma_initialize() {
|
||||
uint8 active_channels = 0;
|
||||
for(int i=0;i<8;i++) {
|
||||
if(channel[i].hdma_active == false) {
|
||||
channel[i].hdma_completed = true;
|
||||
continue;
|
||||
}
|
||||
active_channels++;
|
||||
channel[i].hdma_first_line = true;
|
||||
channel[i].hdma_repeat = false;
|
||||
channel[i].hdma_line_counter = 0;
|
||||
channel[i].hdma_address = channel[i].srcaddr;
|
||||
channel[i].hdma_completed = false;
|
||||
if(channel[i].hdma_indirect == false) {
|
||||
clock->add_cc1_cycles(8);
|
||||
} else {
|
||||
clock->add_cc1_cycles(24);
|
||||
}
|
||||
}
|
||||
if(active_channels != 0) {
|
||||
clock->add_cc1_cycles(18);
|
||||
}
|
||||
}
|
||||
|
||||
void bDMA::reset() {
|
||||
for(int i=0;i<8;i++) {
|
||||
channel[i].active = false;
|
||||
channel[i].hdma_active = false;
|
||||
channel[i].direction = 0;
|
||||
channel[i].hdma_indirect = false;
|
||||
channel[i].incmode = 1;
|
||||
channel[i].fixedxfer = false;
|
||||
channel[i].xfermode = 0;
|
||||
channel[i].destaddr = 0;
|
||||
channel[i].srcaddr = 0;
|
||||
channel[i].xfersize = 0;
|
||||
channel[i].hdma_indirect_bank = 0;
|
||||
channel[i].hdma_first_line = false;
|
||||
channel[i].hdma_repeat = false;
|
||||
channel[i].hdma_line_counter = 0;
|
||||
channel[i].hdma_address = 0;
|
||||
channel[i].hdma_iaddress = 0;
|
||||
channel[i].hdma_completed = true;
|
||||
}
|
||||
}
|
||||
|
||||
bDMA::bDMA(bCPU *_cpu) {
|
||||
cpu = _cpu;
|
||||
reset();
|
||||
}
|
||||
@@ -1,464 +0,0 @@
|
||||
inline void bCPU::flags_adc_b() {
|
||||
int32 r = regs.a.l + rd.l + regs.p.c;
|
||||
//bcd
|
||||
if(regs.p.d) {
|
||||
if(((r ) & 15) > 9)r += 6;
|
||||
if(((r >> 4) & 15) > 9)r += 6 << 4;
|
||||
}
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.v = !!(~(regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
|
||||
regs.p.z = ((byte)r == 0);
|
||||
regs.p.c = (r > 0xff);
|
||||
regs.a.l = r;
|
||||
}
|
||||
|
||||
inline void bCPU::flags_adc_w() {
|
||||
int32 r = regs.a.w + rd.w + regs.p.c;
|
||||
//bcd
|
||||
if(regs.p.d) {
|
||||
if(((r ) & 15) > 9)r += 6;
|
||||
if(((r >> 4) & 15) > 9)r += 6 << 4;
|
||||
if(((r >> 8) & 15) > 9)r += 6 << 8;
|
||||
if(((r >> 12) & 15) > 9)r += 6 << 12;
|
||||
}
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.v = !!(~(regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
|
||||
regs.p.z = ((word)r == 0);
|
||||
regs.p.c = (r > 0xffff);
|
||||
regs.a.w = r;
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x69: adc #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
void bCPU::op_adc_constb() {
|
||||
rd.l = op_read(); //2
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_constw() {
|
||||
rd.l = op_read(); //2
|
||||
rd.h = op_read(); //2a
|
||||
flags_adc_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x6d: adc addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_adc_addrb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_addrw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
|
||||
flags_adc_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x7d: adc addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operadc
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_adc_addrxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_addrxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a
|
||||
flags_adc_w();
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x65: adc dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operadc
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_adc_dpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_dpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
rd.h = op_read(OPMODE_DP, dp + 1); //3a
|
||||
flags_adc_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x72: adc (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_adc_idpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //5
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_idpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //5
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //5
|
||||
flags_adc_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x67: adc [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_adc_ildpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
rd.l = op_read(OPMODE_LONG, aa.d); //6
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_ildpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
rd.l = op_read(OPMODE_LONG, aa.d); //6
|
||||
rd.h = op_read(OPMODE_LONG, aa.d + 1); //6a
|
||||
flags_adc_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x6f: adc long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
void bCPU::op_adc_longb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
rd.l = op_read(OPMODE_LONG, aa.d); //5
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_longw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
rd.l = op_read(OPMODE_LONG, aa.d); //5
|
||||
rd.h = op_read(OPMODE_LONG, aa.d + 1); //5a
|
||||
flags_adc_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x7f: adc long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_adc_longxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_longxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
|
||||
rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a
|
||||
flags_adc_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x79: adc addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operadc
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_adc_addryb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_addryw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a
|
||||
flags_adc_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x75: adc dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_adc_dpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_dpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
|
||||
flags_adc_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x61: adc (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_adc_idpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //6
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_idpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //6
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //6a
|
||||
flags_adc_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x71: adc (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_adc_idpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_idpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a
|
||||
flags_adc_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x77: adc [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_adc_ildpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_ildpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
|
||||
rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a
|
||||
flags_adc_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x63: adc sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_adc_srb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_SP, sp); //4
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_srw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_SP, sp); //4
|
||||
rd.h = op_read(OPMODE_SP, sp + 1); //4a
|
||||
flags_adc_w();
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x73: adc (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_adc_isryb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
|
||||
flags_adc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_adc_isryw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a
|
||||
flags_adc_w();
|
||||
}
|
||||
@@ -1,444 +0,0 @@
|
||||
inline void bCPU::flags_and_b() {
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::flags_and_w() {
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x29: and #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
void bCPU::op_and_constb() {
|
||||
regs.a.l &= op_read(); //2
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_constw() {
|
||||
regs.a.l &= op_read(); //2
|
||||
regs.a.h &= op_read(); //2a
|
||||
flags_and_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x2d: and addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_and_addrb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
regs.a.l &= op_read(OPMODE_DBR, aa.w); //4
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_addrw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
regs.a.l &= op_read(OPMODE_DBR, aa.w); //4
|
||||
regs.a.h &= op_read(OPMODE_DBR, aa.w + 1); //4a
|
||||
flags_and_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x3d: and addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_and_addrxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.x.w); //4
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_addrxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.x.w); //4
|
||||
regs.a.h &= op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a
|
||||
flags_and_w();
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x25: and dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_and_dpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
regs.a.l &= op_read(OPMODE_DP, dp); //3
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_dpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
regs.a.l &= op_read(OPMODE_DP, dp); //3
|
||||
regs.a.h &= op_read(OPMODE_DP, dp + 1); //3a
|
||||
flags_and_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x32: and (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_and_idpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
regs.a.l &= op_read(OPMODE_DBR, aa.w); //5
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_idpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
regs.a.l &= op_read(OPMODE_DBR, aa.w); //5
|
||||
regs.a.h &= op_read(OPMODE_DBR, aa.w + 1); //5
|
||||
flags_and_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x27: and [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_and_ildpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l &= op_read(OPMODE_LONG, aa.d); //6
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_ildpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l &= op_read(OPMODE_LONG, aa.d); //6
|
||||
regs.a.h &= op_read(OPMODE_LONG, aa.d + 1); //6a
|
||||
flags_and_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x2f: and long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
void bCPU::op_and_longb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l &= op_read(OPMODE_LONG, aa.d); //5
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_longw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l &= op_read(OPMODE_LONG, aa.d); //5
|
||||
regs.a.h &= op_read(OPMODE_LONG, aa.d + 1); //5a
|
||||
flags_and_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x3f: and long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_and_longxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l &= op_read(OPMODE_LONG, aa.d + regs.x.w); //5
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_longxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l &= op_read(OPMODE_LONG, aa.d + regs.x.w); //5
|
||||
regs.a.h &= op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a
|
||||
flags_and_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x39: and addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_and_addryb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //4
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_addryw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //4
|
||||
regs.a.h &= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a
|
||||
flags_and_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x35: and dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_and_dpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
regs.a.l &= op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_dpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
regs.a.l &= op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
regs.a.h &= op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
|
||||
flags_and_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x21: and (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_and_idpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
regs.a.l &= op_read(OPMODE_DBR, aa.w); //6
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_idpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
regs.a.l &= op_read(OPMODE_DBR, aa.w); //6
|
||||
regs.a.h &= op_read(OPMODE_DBR, aa.w + 1); //6a
|
||||
flags_and_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x31: and (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_and_idpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //5
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_idpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //5
|
||||
regs.a.h &= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a
|
||||
flags_and_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x37: and [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_and_ildpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l &= op_read(OPMODE_LONG, aa.d + regs.y.w); //6
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_ildpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l &= op_read(OPMODE_LONG, aa.d + regs.y.w); //6
|
||||
regs.a.h &= op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a
|
||||
flags_and_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x23: and sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_and_srb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
regs.a.l &= op_read(OPMODE_SP, sp); //4
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_srw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
regs.a.l &= op_read(OPMODE_SP, sp); //4
|
||||
regs.a.h &= op_read(OPMODE_SP, sp + 1); //4a
|
||||
flags_and_w();
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x33: and (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_and_isryb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //7
|
||||
flags_and_b();
|
||||
}
|
||||
|
||||
void bCPU::op_and_isryw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //7
|
||||
regs.a.h &= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a
|
||||
flags_and_w();
|
||||
}
|
||||
@@ -1,448 +0,0 @@
|
||||
inline void bCPU::flags_cmp_b() {
|
||||
int32 r = regs.a.l - rd.l;
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
|
||||
inline void bCPU::flags_cmp_w() {
|
||||
int32 r = regs.a.w - rd.w;
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xc9: cmp #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
void bCPU::op_cmp_constb() {
|
||||
rd.l = op_read(); //2
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_constw() {
|
||||
rd.l = op_read(); //2
|
||||
rd.h = op_read(); //2a
|
||||
flags_cmp_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xcd: cmp addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_cmp_addrb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_addrw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
|
||||
flags_cmp_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xdd: cmp addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opercmp
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_cmp_addrxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_addrxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a
|
||||
flags_cmp_w();
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xc5: cmp dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opercmp
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_cmp_dpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_dpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
rd.h = op_read(OPMODE_DP, dp + 1); //3a
|
||||
flags_cmp_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd2: cmp (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_cmp_idpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //5
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_idpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //5
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //5
|
||||
flags_cmp_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xc7: cmp [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_cmp_ildpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
rd.l = op_read(OPMODE_LONG, aa.d); //6
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_ildpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
rd.l = op_read(OPMODE_LONG, aa.d); //6
|
||||
rd.h = op_read(OPMODE_LONG, aa.d + 1); //6a
|
||||
flags_cmp_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xcf: cmp long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
void bCPU::op_cmp_longb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
rd.l = op_read(OPMODE_LONG, aa.d); //5
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_longw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
rd.l = op_read(OPMODE_LONG, aa.d); //5
|
||||
rd.h = op_read(OPMODE_LONG, aa.d + 1); //5a
|
||||
flags_cmp_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xdf: cmp long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_cmp_longxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_longxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
|
||||
rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a
|
||||
flags_cmp_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xd9: cmp addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opercmp
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_cmp_addryb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_addryw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a
|
||||
flags_cmp_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd5: cmp dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_cmp_dpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_dpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
|
||||
flags_cmp_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xc1: cmp (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_cmp_idpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //6
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_idpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //6
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //6a
|
||||
flags_cmp_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xd1: cmp (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_cmp_idpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_idpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a
|
||||
flags_cmp_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xd7: cmp [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_cmp_ildpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_ildpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
|
||||
rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a
|
||||
flags_cmp_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xc3: cmp sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_cmp_srb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_SP, sp); //4
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_srw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_SP, sp); //4
|
||||
rd.h = op_read(OPMODE_SP, sp + 1); //4a
|
||||
flags_cmp_w();
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0xd3: cmp (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_cmp_isryb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
|
||||
flags_cmp_b();
|
||||
}
|
||||
|
||||
void bCPU::op_cmp_isryw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a
|
||||
flags_cmp_w();
|
||||
}
|
||||
@@ -1,444 +0,0 @@
|
||||
inline void bCPU::flags_eor_b() {
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::flags_eor_w() {
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x49: eor #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
void bCPU::op_eor_constb() {
|
||||
regs.a.l ^= op_read(); //2
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_constw() {
|
||||
regs.a.l ^= op_read(); //2
|
||||
regs.a.h ^= op_read(); //2a
|
||||
flags_eor_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x4d: eor addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_eor_addrb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
regs.a.l ^= op_read(OPMODE_DBR, aa.w); //4
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_addrw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
regs.a.l ^= op_read(OPMODE_DBR, aa.w); //4
|
||||
regs.a.h ^= op_read(OPMODE_DBR, aa.w + 1); //4a
|
||||
flags_eor_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x5d: eor addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opereor
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_eor_addrxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.x.w); //4
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_addrxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.x.w); //4
|
||||
regs.a.h ^= op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a
|
||||
flags_eor_w();
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x45: eor dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opereor
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_eor_dpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
regs.a.l ^= op_read(OPMODE_DP, dp); //3
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_dpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
regs.a.l ^= op_read(OPMODE_DP, dp); //3
|
||||
regs.a.h ^= op_read(OPMODE_DP, dp + 1); //3a
|
||||
flags_eor_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x52: eor (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_eor_idpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
regs.a.l ^= op_read(OPMODE_DBR, aa.w); //5
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_idpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
regs.a.l ^= op_read(OPMODE_DBR, aa.w); //5
|
||||
regs.a.h ^= op_read(OPMODE_DBR, aa.w + 1); //5
|
||||
flags_eor_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x47: eor [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_eor_ildpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l ^= op_read(OPMODE_LONG, aa.d); //6
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_ildpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l ^= op_read(OPMODE_LONG, aa.d); //6
|
||||
regs.a.h ^= op_read(OPMODE_LONG, aa.d + 1); //6a
|
||||
flags_eor_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x4f: eor long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
void bCPU::op_eor_longb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l ^= op_read(OPMODE_LONG, aa.d); //5
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_longw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l ^= op_read(OPMODE_LONG, aa.d); //5
|
||||
regs.a.h ^= op_read(OPMODE_LONG, aa.d + 1); //5a
|
||||
flags_eor_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x5f: eor long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_eor_longxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l ^= op_read(OPMODE_LONG, aa.d + regs.x.w); //5
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_longxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l ^= op_read(OPMODE_LONG, aa.d + regs.x.w); //5
|
||||
regs.a.h ^= op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a
|
||||
flags_eor_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x59: eor addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opereor
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_eor_addryb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //4
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_addryw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //4
|
||||
regs.a.h ^= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a
|
||||
flags_eor_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x55: eor dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_eor_dpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
regs.a.l ^= op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_dpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
regs.a.l ^= op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
regs.a.h ^= op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
|
||||
flags_eor_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x41: eor (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_eor_idpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
regs.a.l ^= op_read(OPMODE_DBR, aa.w); //6
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_idpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
regs.a.l ^= op_read(OPMODE_DBR, aa.w); //6
|
||||
regs.a.h ^= op_read(OPMODE_DBR, aa.w + 1); //6a
|
||||
flags_eor_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x51: eor (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_eor_idpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //5
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_idpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //5
|
||||
regs.a.h ^= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a
|
||||
flags_eor_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x57: eor [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_eor_ildpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l ^= op_read(OPMODE_LONG, aa.d + regs.y.w); //6
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_ildpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l ^= op_read(OPMODE_LONG, aa.d + regs.y.w); //6
|
||||
regs.a.h ^= op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a
|
||||
flags_eor_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x43: eor sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_eor_srb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
regs.a.l ^= op_read(OPMODE_SP, sp); //4
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_srw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
regs.a.l ^= op_read(OPMODE_SP, sp); //4
|
||||
regs.a.h ^= op_read(OPMODE_SP, sp + 1); //4a
|
||||
flags_eor_w();
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x53: eor (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_eor_isryb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //7
|
||||
flags_eor_b();
|
||||
}
|
||||
|
||||
void bCPU::op_eor_isryw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //7
|
||||
regs.a.h ^= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a
|
||||
flags_eor_w();
|
||||
}
|
||||
@@ -1,433 +0,0 @@
|
||||
/*****************
|
||||
*** 0x1a: inc ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
void bCPU::op_incb() {
|
||||
cpu_io(); //2
|
||||
regs.a.l++;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_incw() {
|
||||
cpu_io(); //2
|
||||
regs.a.w++;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xee: inc addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
void bCPU::op_inc_addrb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
rd.l++;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DBR, aa.w, rd.l); //6
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_inc_addrw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
|
||||
rd.w++;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a
|
||||
op_write(OPMODE_DBR, aa.w, rd.l); //6
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xfe: inc addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
void bCPU::op_inc_addrxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
|
||||
rd.l++;
|
||||
cpu_io(); //6
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_inc_addrxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a
|
||||
rd.w++;
|
||||
cpu_io(); //6
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xe6: inc dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
void bCPU::op_inc_dpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
rd.l++;
|
||||
cpu_io(); //4
|
||||
op_write(OPMODE_DP, dp, rd.l); //5
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_inc_dpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
rd.h = op_read(OPMODE_DP, dp + 1); //3a
|
||||
rd.w++;
|
||||
cpu_io(); //4
|
||||
op_write(OPMODE_DP, dp + 1, rd.h); //5a
|
||||
op_write(OPMODE_DP, dp, rd.l); //5
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf6: inc dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
void bCPU::op_inc_dpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
rd.l++;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_inc_dpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
|
||||
rd.w++;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a
|
||||
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xe8: inx ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
void bCPU::op_inxb() {
|
||||
cpu_io(); //2
|
||||
regs.x.l++;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_inxw() {
|
||||
cpu_io(); //2
|
||||
regs.x.w++;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xc8: iny ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
void bCPU::op_inyb() {
|
||||
cpu_io(); //2
|
||||
regs.y.l++;
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_inyw() {
|
||||
cpu_io(); //2
|
||||
regs.y.w++;
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x3a: dec ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
void bCPU::op_decb() {
|
||||
cpu_io(); //2
|
||||
regs.a.l--;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_decw() {
|
||||
cpu_io(); //2
|
||||
regs.a.w--;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xce: dec addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
void bCPU::op_dec_addrb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
rd.l--;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DBR, aa.w, rd.l); //6
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_dec_addrw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
|
||||
rd.w--;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a
|
||||
op_write(OPMODE_DBR, aa.w, rd.l); //6
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xde: dec addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
void bCPU::op_dec_addrxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
|
||||
rd.l--;
|
||||
cpu_io(); //6
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_dec_addrxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a
|
||||
rd.w--;
|
||||
cpu_io(); //6
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xc6: dec dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
void bCPU::op_dec_dpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
rd.l--;
|
||||
cpu_io(); //4
|
||||
op_write(OPMODE_DP, dp, rd.l); //5
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_dec_dpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
rd.h = op_read(OPMODE_DP, dp + 1); //3a
|
||||
rd.w--;
|
||||
cpu_io(); //4
|
||||
op_write(OPMODE_DP, dp + 1, rd.h); //5a
|
||||
op_write(OPMODE_DP, dp, rd.l); //5
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd6: dec dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
void bCPU::op_dec_dpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
rd.l--;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_dec_dpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
|
||||
rd.w--;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a
|
||||
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xca: dex ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
void bCPU::op_dexb() {
|
||||
cpu_io(); //2
|
||||
regs.x.l--;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_dexw() {
|
||||
cpu_io(); //2
|
||||
regs.x.w--;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x88: dey ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
void bCPU::op_deyb() {
|
||||
cpu_io(); //2
|
||||
regs.y.l--;
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_deyw() {
|
||||
cpu_io(); //2
|
||||
regs.y.w--;
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
@@ -1,444 +0,0 @@
|
||||
inline void bCPU::flags_lda_b() {
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::flags_lda_w() {
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xa9: lda #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
void bCPU::op_lda_constb() {
|
||||
regs.a.l = op_read(); //2
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_constw() {
|
||||
regs.a.l = op_read(); //2
|
||||
regs.a.h = op_read(); //2a
|
||||
flags_lda_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xad: lda addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_lda_addrb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
regs.a.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_addrw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
regs.a.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
regs.a.h = op_read(OPMODE_DBR, aa.w + 1); //4a
|
||||
flags_lda_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xbd: lda addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_lda_addrxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_addrxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
|
||||
regs.a.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a
|
||||
flags_lda_w();
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xa5: lda dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_lda_dpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
regs.a.l = op_read(OPMODE_DP, dp); //3
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_dpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
regs.a.l = op_read(OPMODE_DP, dp); //3
|
||||
regs.a.h = op_read(OPMODE_DP, dp + 1); //3a
|
||||
flags_lda_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xb2: lda (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_lda_idpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
regs.a.l = op_read(OPMODE_DBR, aa.w); //5
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_idpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
regs.a.l = op_read(OPMODE_DBR, aa.w); //5
|
||||
regs.a.h = op_read(OPMODE_DBR, aa.w + 1); //5
|
||||
flags_lda_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xa7: lda [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_lda_ildpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l = op_read(OPMODE_LONG, aa.d); //6
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_ildpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l = op_read(OPMODE_LONG, aa.d); //6
|
||||
regs.a.h = op_read(OPMODE_LONG, aa.d + 1); //6a
|
||||
flags_lda_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xaf: lda long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
void bCPU::op_lda_longb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l = op_read(OPMODE_LONG, aa.d); //5
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_longw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l = op_read(OPMODE_LONG, aa.d); //5
|
||||
regs.a.h = op_read(OPMODE_LONG, aa.d + 1); //5a
|
||||
flags_lda_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xbf: lda long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_lda_longxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_longxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
|
||||
regs.a.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a
|
||||
flags_lda_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xb9: lda addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_lda_addryb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_addryw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
|
||||
regs.a.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a
|
||||
flags_lda_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xb5: lda dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_lda_dpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
regs.a.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_dpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
regs.a.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
regs.a.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
|
||||
flags_lda_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xa1: lda (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_lda_idpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
regs.a.l = op_read(OPMODE_DBR, aa.w); //6
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_idpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
regs.a.l = op_read(OPMODE_DBR, aa.w); //6
|
||||
regs.a.h = op_read(OPMODE_DBR, aa.w + 1); //6a
|
||||
flags_lda_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xb1: lda (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_lda_idpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_idpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
|
||||
regs.a.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a
|
||||
flags_lda_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xb7: lda [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_lda_ildpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_ildpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
|
||||
regs.a.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a
|
||||
flags_lda_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xa3: lda sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_lda_srb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
regs.a.l = op_read(OPMODE_SP, sp); //4
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_srw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
regs.a.l = op_read(OPMODE_SP, sp); //4
|
||||
regs.a.h = op_read(OPMODE_SP, sp + 1); //4a
|
||||
flags_lda_w();
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0xb3: lda (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_lda_isryb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
|
||||
flags_lda_b();
|
||||
}
|
||||
|
||||
void bCPU::op_lda_isryw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
|
||||
regs.a.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a
|
||||
flags_lda_w();
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,444 +0,0 @@
|
||||
inline void bCPU::flags_ora_b() {
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::flags_ora_w() {
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x09: ora #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
void bCPU::op_ora_constb() {
|
||||
regs.a.l |= op_read(); //2
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_constw() {
|
||||
regs.a.l |= op_read(); //2
|
||||
regs.a.h |= op_read(); //2a
|
||||
flags_ora_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x0d: ora addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_ora_addrb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
regs.a.l |= op_read(OPMODE_DBR, aa.w); //4
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_addrw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
regs.a.l |= op_read(OPMODE_DBR, aa.w); //4
|
||||
regs.a.h |= op_read(OPMODE_DBR, aa.w + 1); //4a
|
||||
flags_ora_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x1d: ora addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operora
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_ora_addrxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.x.w); //4
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_addrxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.x.w); //4
|
||||
regs.a.h |= op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a
|
||||
flags_ora_w();
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x05: ora dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operora
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_ora_dpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
regs.a.l |= op_read(OPMODE_DP, dp); //3
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_dpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
regs.a.l |= op_read(OPMODE_DP, dp); //3
|
||||
regs.a.h |= op_read(OPMODE_DP, dp + 1); //3a
|
||||
flags_ora_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x12: ora (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_ora_idpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
regs.a.l |= op_read(OPMODE_DBR, aa.w); //5
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_idpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
regs.a.l |= op_read(OPMODE_DBR, aa.w); //5
|
||||
regs.a.h |= op_read(OPMODE_DBR, aa.w + 1); //5
|
||||
flags_ora_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x07: ora [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_ora_ildpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l |= op_read(OPMODE_LONG, aa.d); //6
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_ildpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l |= op_read(OPMODE_LONG, aa.d); //6
|
||||
regs.a.h |= op_read(OPMODE_LONG, aa.d + 1); //6a
|
||||
flags_ora_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x0f: ora long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
void bCPU::op_ora_longb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l |= op_read(OPMODE_LONG, aa.d); //5
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_longw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l |= op_read(OPMODE_LONG, aa.d); //5
|
||||
regs.a.h |= op_read(OPMODE_LONG, aa.d + 1); //5a
|
||||
flags_ora_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x1f: ora long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_ora_longxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l |= op_read(OPMODE_LONG, aa.d + regs.x.w); //5
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_longxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
regs.a.l |= op_read(OPMODE_LONG, aa.d + regs.x.w); //5
|
||||
regs.a.h |= op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a
|
||||
flags_ora_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x19: ora addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operora
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_ora_addryb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //4
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_addryw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //4
|
||||
regs.a.h |= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a
|
||||
flags_ora_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x15: ora dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_ora_dpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
regs.a.l |= op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_dpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
regs.a.l |= op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
regs.a.h |= op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
|
||||
flags_ora_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x01: ora (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_ora_idpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
regs.a.l |= op_read(OPMODE_DBR, aa.w); //6
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_idpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
regs.a.l |= op_read(OPMODE_DBR, aa.w); //6
|
||||
regs.a.h |= op_read(OPMODE_DBR, aa.w + 1); //6a
|
||||
flags_ora_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x11: ora (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_ora_idpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //5
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_idpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //5
|
||||
regs.a.h |= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a
|
||||
flags_ora_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x17: ora [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_ora_ildpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l |= op_read(OPMODE_LONG, aa.d + regs.y.w); //6
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_ildpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
regs.a.l |= op_read(OPMODE_LONG, aa.d + regs.y.w); //6
|
||||
regs.a.h |= op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a
|
||||
flags_ora_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x03: ora sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_ora_srb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
regs.a.l |= op_read(OPMODE_SP, sp); //4
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_srw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
regs.a.l |= op_read(OPMODE_SP, sp); //4
|
||||
regs.a.h |= op_read(OPMODE_SP, sp + 1); //4a
|
||||
flags_ora_w();
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x13: ora (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_ora_isryb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //7
|
||||
flags_ora_b();
|
||||
}
|
||||
|
||||
void bCPU::op_ora_isryw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //7
|
||||
regs.a.h |= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a
|
||||
flags_ora_w();
|
||||
}
|
||||
@@ -1,441 +0,0 @@
|
||||
/**********************
|
||||
*** 0x4c: jmp addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; new pcl
|
||||
[3] pbr,pc+2 ; new pch
|
||||
*/
|
||||
void bCPU::op_jmp_addr() {
|
||||
rd.l = op_read(); //2
|
||||
rd.h = op_read(); //3
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x5c: jmp long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; new pcl
|
||||
[3] pbr,pc+2 ; new pch
|
||||
[4] pbr,pc+3 ; new pbr
|
||||
*/
|
||||
void bCPU::op_jmp_long() {
|
||||
rd.l = op_read(); //2
|
||||
rd.h = op_read(); //3
|
||||
rd.b = op_read(); //4
|
||||
regs.pc.d = rd.d;
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x6c: jmp (addr) ***
|
||||
************************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] pbr,pc+2 ; aah
|
||||
[4] 0,aa ; new pcl
|
||||
[5] 0,aa+1 ; new pch
|
||||
*/
|
||||
void bCPU::op_jmp_iaddr() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_ADDR, aa.w); //4
|
||||
rd.h = op_read(OPMODE_ADDR, aa.w + 1); //5
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x7c: jmp (addr,x) ***
|
||||
**************************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] pbr,pc+2 ; aah
|
||||
[4] pbr,pc+2 ; io
|
||||
[5] pbr,aa+x ; new pcl
|
||||
[6] pbr,aa+x+1 ; new pch
|
||||
*/
|
||||
void bCPU::op_jmp_iaddrx() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w); //5
|
||||
rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1); //6
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xdc: jmp [addr] ***
|
||||
************************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] pbr,pc+2 ; aah
|
||||
[4] 0,aa ; new pcl
|
||||
[5] 0,aa+1 ; new pch
|
||||
[6] 0,aa+2 ; new pbr
|
||||
*/
|
||||
void bCPU::op_jmp_iladdr() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_ADDR, aa.w); //4
|
||||
rd.h = op_read(OPMODE_ADDR, aa.w + 1); //5
|
||||
rd.b = op_read(OPMODE_ADDR, aa.w + 2); //6
|
||||
regs.pc.d = rd.d;
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x20: jsr addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; new pcl
|
||||
[3] pbr,pc+2 ; new pch
|
||||
[4] pbr,pc+2 ; io
|
||||
[5] 0,s ; pch
|
||||
[6] 0,s-1 ; pcl
|
||||
*/
|
||||
void bCPU::op_jsr_addr() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
regs.pc.w--;
|
||||
stack_write(regs.pc.h); //5
|
||||
stack_write(regs.pc.l); //6
|
||||
regs.pc.w = aa.w;
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x22: jsr long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; new pcl
|
||||
[3] pbr,pc+2 ; new pch
|
||||
[4] 0,s ; pbr
|
||||
[5] 0,s ; io
|
||||
[6] pbr,pc+3 ; new pbr
|
||||
[7] 0,s-1 ; pch
|
||||
[8] 0,s-2 ; pcl
|
||||
*/
|
||||
void bCPU::op_jsr_long() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
stack_write(regs.pc.b); //4
|
||||
cpu_io(); //5
|
||||
aa.b = op_read(); //6
|
||||
regs.pc.w--;
|
||||
stack_write(regs.pc.h); //7
|
||||
stack_write(regs.pc.l); //8
|
||||
regs.pc.d = aa.d;
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0xfc: jsr (addr,x) ***
|
||||
**************************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] 0,s ; pch
|
||||
[4] 0,s-1 ; pcl
|
||||
[5] pbr,pc+2 ; aah
|
||||
[6] pbr,pc+2 ; io
|
||||
[7] pbr,aa+x ; new pcl
|
||||
[8] pbr,aa+x+1 ; new pch
|
||||
*/
|
||||
void bCPU::op_jsr_iaddrx() {
|
||||
aa.l = op_read(); //2
|
||||
stack_write(regs.pc.h); //3
|
||||
stack_write(regs.pc.l); //4
|
||||
aa.h = op_read(); //5
|
||||
cpu_io(); //6
|
||||
rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w); //7
|
||||
rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1); //8
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x40: rti ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
[3] pbr,pc+1 ; io
|
||||
[4] 0,s+1 ; p
|
||||
[5] 0,s+2 ; new pcl
|
||||
[6] 0,s+3 ; new pch
|
||||
[7] 0,s+4 ; pbr [7]
|
||||
*/
|
||||
void bCPU::op_rtie() {
|
||||
cpu_io(); //2
|
||||
cpu_io(); //3
|
||||
regs.p = stack_read(); //4
|
||||
rd.l = stack_read(); //5
|
||||
rd.h = stack_read(); //6
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
void bCPU::op_rtin() {
|
||||
cpu_io(); //2
|
||||
cpu_io(); //3
|
||||
regs.p = stack_read(); //4
|
||||
rd.l = stack_read(); //5
|
||||
rd.h = stack_read(); //6
|
||||
rd.b = stack_read(); //7
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
regs.pc.d = rd.d;
|
||||
|
||||
switch((regs.p >> 4) & 3) {
|
||||
case 0:optbl = optbl_mx;break;
|
||||
case 1:optbl = optbl_mX;break;
|
||||
case 2:optbl = optbl_Mx;break;
|
||||
case 3:optbl = optbl_MX;break;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x60: rts ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
[3] pbr,pc+1 ; io
|
||||
[4] 0,s+1 ; pcl
|
||||
[5] 0,s+2 ; pch
|
||||
[6] 0,s+2 ; io
|
||||
*/
|
||||
void bCPU::op_rts() {
|
||||
cpu_io(); //2
|
||||
cpu_io(); //3
|
||||
rd.l = stack_read(); //4
|
||||
rd.h = stack_read(); //5
|
||||
cpu_io(); //6
|
||||
regs.pc.w = rd.w;
|
||||
regs.pc.w++;
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x6b: rtl ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
[3] pbr,pc+1 ; io
|
||||
[4] 0,s+1 ; pcl
|
||||
[5] 0,s+2 ; pch
|
||||
[6] 0,s+3 ; pbr
|
||||
*/
|
||||
void bCPU::op_rtl() {
|
||||
cpu_io(); //2
|
||||
cpu_io(); //3
|
||||
rd.l = stack_read(); //4
|
||||
rd.h = stack_read(); //5
|
||||
rd.b = stack_read(); //6
|
||||
regs.pc.d = rd.d;
|
||||
regs.pc.w++;
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x80: bra near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
void bCPU::op_bra() {
|
||||
uint16 r;
|
||||
rd.l = op_read(); //2
|
||||
cpu_io(); //2a
|
||||
r = regs.pc + (int8)rd.l;
|
||||
cpu_c6(r); //2b
|
||||
regs.pc.w = r;
|
||||
}
|
||||
|
||||
/*********************
|
||||
*** 0x82: brl far ***
|
||||
*********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; offset low
|
||||
[3] pbr,pc+2 ; offset high
|
||||
[4] pbr,pc+2 ; io
|
||||
*/
|
||||
void bCPU::op_brl() {
|
||||
uint16 r;
|
||||
rd.l = op_read(); //2
|
||||
rd.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
r = regs.pc + (int16)rd.w;
|
||||
regs.pc.w = r;
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x90: bcc near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
void bCPU::op_bcc() {
|
||||
uint16 r;
|
||||
rd.l = op_read(); //2
|
||||
if(!regs.p.c) {
|
||||
cpu_io(); //2a
|
||||
r = regs.pc + (int8)rd.l;
|
||||
cpu_c6(r); //2b
|
||||
regs.pc.w = r;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xb0: bcs near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
void bCPU::op_bcs() {
|
||||
uint16 r;
|
||||
rd.l = op_read(); //2
|
||||
if(regs.p.c) {
|
||||
cpu_io(); //2a
|
||||
r = regs.pc + (int8)rd.l;
|
||||
cpu_c6(r); //2b
|
||||
regs.pc.w = r;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd0: bne near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
void bCPU::op_bne() {
|
||||
uint16 r;
|
||||
rd.l = op_read(); //2
|
||||
if(!regs.p.z) {
|
||||
cpu_io(); //2a
|
||||
r = regs.pc + (int8)rd.l;
|
||||
cpu_c6(r); //2b
|
||||
regs.pc.w = r;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf0: beq near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
void bCPU::op_beq() {
|
||||
uint16 r;
|
||||
rd.l = op_read(); //2
|
||||
if(regs.p.z) {
|
||||
cpu_io(); //2a
|
||||
r = regs.pc + (int8)rd.l;
|
||||
cpu_c6(r); //2b
|
||||
regs.pc.w = r;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x10: bpl near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
void bCPU::op_bpl() {
|
||||
uint16 r;
|
||||
rd.l = op_read(); //2
|
||||
if(!regs.p.n) {
|
||||
cpu_io(); //2a
|
||||
r = regs.pc + (int8)rd.l;
|
||||
cpu_c6(r); //2b
|
||||
regs.pc.w = r;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x30: bmi near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
void bCPU::op_bmi() {
|
||||
uint16 r;
|
||||
rd.l = op_read(); //2
|
||||
if(regs.p.n) {
|
||||
cpu_io(); //2a
|
||||
r = regs.pc + (int8)rd.l;
|
||||
cpu_c6(r); //2b
|
||||
regs.pc.w = r;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x50: bvc near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
void bCPU::op_bvc() {
|
||||
uint16 r;
|
||||
rd.l = op_read(); //2
|
||||
if(!regs.p.v) {
|
||||
cpu_io(); //2a
|
||||
r = regs.pc + (int8)rd.l;
|
||||
cpu_c6(r); //2b
|
||||
regs.pc.w = r;
|
||||
}
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x70: bvs near ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; offset
|
||||
[2a] pbr,pc+1 ; io [5]
|
||||
[2b] pbr,pc+1 ; io [6]
|
||||
*/
|
||||
void bCPU::op_bvs() {
|
||||
uint16 r;
|
||||
rd.l = op_read(); //2
|
||||
if(regs.p.v) {
|
||||
cpu_io(); //2a
|
||||
r = regs.pc + (int8)rd.l;
|
||||
cpu_c6(r); //2b
|
||||
regs.pc.w = r;
|
||||
}
|
||||
}
|
||||
@@ -1,464 +0,0 @@
|
||||
inline void bCPU::flags_sbc_b() {
|
||||
int32 r = regs.a.l - rd.l - !regs.p.c;
|
||||
//bcd
|
||||
if(regs.p.d) {
|
||||
if(((r ) & 15) > 9)r -= 6;
|
||||
if(((r >> 4) & 15) > 9)r -= 6 << 4;
|
||||
}
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.v = !!((regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
|
||||
regs.p.z = ((byte)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
regs.a.l = r;
|
||||
}
|
||||
|
||||
inline void bCPU::flags_sbc_w() {
|
||||
int32 r = regs.a.w - rd.w - !regs.p.c;
|
||||
//bcd
|
||||
if(regs.p.d) {
|
||||
if(((r ) & 15) > 9)r -= 6;
|
||||
if(((r >> 4) & 15) > 9)r -= 6 << 4;
|
||||
if(((r >> 8) & 15) > 9)r -= 6 << 8;
|
||||
if(((r >> 12) & 15) > 9)r -= 6 << 12;
|
||||
}
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.v = !!((regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
|
||||
regs.p.z = ((word)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
regs.a.w = r;
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xe9: sbc #const ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; idl
|
||||
[2a] pbr,pc+2 ; idh [1]
|
||||
*/
|
||||
void bCPU::op_sbc_constb() {
|
||||
rd.l = op_read(); //2
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_constw() {
|
||||
rd.l = op_read(); //2
|
||||
rd.h = op_read(); //2a
|
||||
flags_sbc_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xed: sbc addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sbc_addrb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_addrw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
|
||||
flags_sbc_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xfd: sbc addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opersbc
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sbc_addrxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_addrxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a
|
||||
flags_sbc_w();
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0xe5: sbc dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opersbc
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sbc_dpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_dpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
rd.h = op_read(OPMODE_DP, dp + 1); //3a
|
||||
flags_sbc_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf2: sbc (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sbc_idpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //5
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_idpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //5
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //5
|
||||
flags_sbc_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xe7: sbc [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sbc_ildpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
rd.l = op_read(OPMODE_LONG, aa.d); //6
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_ildpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
rd.l = op_read(OPMODE_LONG, aa.d); //6
|
||||
rd.h = op_read(OPMODE_LONG, aa.d + 1); //6a
|
||||
flags_sbc_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xef: sbc long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
void bCPU::op_sbc_longb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
rd.l = op_read(OPMODE_LONG, aa.d); //5
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_longw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
rd.l = op_read(OPMODE_LONG, aa.d); //5
|
||||
rd.h = op_read(OPMODE_LONG, aa.d + 1); //5a
|
||||
flags_sbc_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xff: sbc long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_sbc_longxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_longxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
|
||||
rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a
|
||||
flags_sbc_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xf9: sbc addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opersbc
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sbc_addryb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_addryw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a
|
||||
flags_sbc_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf5: sbc dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_sbc_dpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_dpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
|
||||
flags_sbc_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xe1: sbc (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sbc_idpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //6
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_idpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //6
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //6a
|
||||
flags_sbc_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xf1: sbc (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sbc_idpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_idpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a
|
||||
flags_sbc_w();
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0xf7: sbc [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sbc_ildpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_ildpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
|
||||
rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a
|
||||
flags_sbc_w();
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xe3: sbc sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sbc_srb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_SP, sp); //4
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_srw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_SP, sp); //4
|
||||
rd.h = op_read(OPMODE_SP, sp + 1); //4a
|
||||
flags_sbc_w();
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0xf3: sbc (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sbc_isryb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
|
||||
flags_sbc_b();
|
||||
}
|
||||
|
||||
void bCPU::op_sbc_isryw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a
|
||||
flags_sbc_w();
|
||||
}
|
||||
@@ -1,779 +0,0 @@
|
||||
/*****************
|
||||
*** 0x0a: asl ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
void bCPU::op_aslb() {
|
||||
cpu_io(); //2
|
||||
regs.p.c = !!(regs.a.l & 0x80);
|
||||
regs.a.l <<= 1;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_aslw() {
|
||||
cpu_io(); //2
|
||||
regs.p.c = !!(regs.a.w & 0x8000);
|
||||
regs.a.w <<= 1;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x0e: asl addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
void bCPU::op_asl_addrb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
rd.l <<= 1;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DBR, aa.w, rd.l); //6
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_asl_addrw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
rd.w <<= 1;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a
|
||||
op_write(OPMODE_DBR, aa.w, rd.l); //6
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x1e: asl addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
void bCPU::op_asl_addrxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
rd.l <<= 1;
|
||||
cpu_io(); //6
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_asl_addrxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
rd.w <<= 1;
|
||||
cpu_io(); //6
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x06: asl dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
void bCPU::op_asl_dpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
rd.l <<= 1;
|
||||
cpu_io(); //4
|
||||
op_write(OPMODE_DP, dp, rd.l); //5
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_asl_dpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
rd.h = op_read(OPMODE_DP, dp + 1); //3a
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
rd.w <<= 1;
|
||||
cpu_io(); //4
|
||||
op_write(OPMODE_DP, dp + 1, rd.h); //5a
|
||||
op_write(OPMODE_DP, dp, rd.l); //5
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x16: asl dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
void bCPU::op_asl_dpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
rd.l <<= 1;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_asl_dpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
rd.w <<= 1;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a
|
||||
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x4a: lsr ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
void bCPU::op_lsrb() {
|
||||
cpu_io(); //2
|
||||
regs.p.c = regs.a.l & 1;
|
||||
regs.a.l >>= 1;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_lsrw() {
|
||||
cpu_io(); //2
|
||||
regs.p.c = regs.a.w & 1;
|
||||
regs.a.w >>= 1;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x4e: lsr addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
void bCPU::op_lsr_addrb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l >>= 1;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DBR, aa.w, rd.l); //6
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_lsr_addrw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w >>= 1;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a
|
||||
op_write(OPMODE_DBR, aa.w, rd.l); //6
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x5e: lsr addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
void bCPU::op_lsr_addrxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l >>= 1;
|
||||
cpu_io(); //6
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_lsr_addrxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w >>= 1;
|
||||
cpu_io(); //6
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x46: lsr dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
void bCPU::op_lsr_dpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l >>= 1;
|
||||
cpu_io(); //4
|
||||
op_write(OPMODE_DP, dp, rd.l); //5
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_lsr_dpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
rd.h = op_read(OPMODE_DP, dp + 1); //3a
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w >>= 1;
|
||||
cpu_io(); //4
|
||||
op_write(OPMODE_DP, dp + 1, rd.h); //5a
|
||||
op_write(OPMODE_DP, dp, rd.l); //5
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x56: lsr dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
void bCPU::op_lsr_dpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l >>= 1;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_lsr_dpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w >>= 1;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a
|
||||
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x2a: rol ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
void bCPU::op_rolb() {
|
||||
uint8 c = regs.p.c;
|
||||
cpu_io(); //2
|
||||
regs.p.c = !!(regs.a.l & 0x80);
|
||||
regs.a.l <<= 1;
|
||||
regs.a.l |= c;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_rolw() {
|
||||
uint16 c = regs.p.c;
|
||||
cpu_io(); //2
|
||||
regs.p.c = !!(regs.a.w & 0x8000);
|
||||
regs.a.w <<= 1;
|
||||
regs.a.w |= c;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x2e: rol addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
void bCPU::op_rol_addrb() {
|
||||
uint8 c = regs.p.c;
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
rd.l <<= 1;
|
||||
rd.l |= c;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DBR, aa.w, rd.l); //6
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_rol_addrw() {
|
||||
uint16 c = regs.p.c;
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
rd.w <<= 1;
|
||||
rd.w |= c;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a
|
||||
op_write(OPMODE_DBR, aa.w, rd.l); //6
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x3e: rol addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
void bCPU::op_rol_addrxb() {
|
||||
uint8 c = regs.p.c;
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
rd.l <<= 1;
|
||||
rd.l |= c;
|
||||
cpu_io(); //6
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_rol_addrxw() {
|
||||
uint16 c = regs.p.c;
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
rd.w <<= 1;
|
||||
rd.w |= c;
|
||||
cpu_io(); //6
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x26: rol dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
void bCPU::op_rol_dpb() {
|
||||
uint8 c = regs.p.c;
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
rd.l <<= 1;
|
||||
rd.l |= c;
|
||||
cpu_io(); //4
|
||||
op_write(OPMODE_DP, dp, rd.l); //5
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_rol_dpw() {
|
||||
uint16 c = regs.p.c;
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
rd.h = op_read(OPMODE_DP, dp + 1); //3a
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
rd.w <<= 1;
|
||||
rd.w |= c;
|
||||
cpu_io(); //4
|
||||
op_write(OPMODE_DP, dp + 1, rd.h); //5a
|
||||
op_write(OPMODE_DP, dp, rd.l); //5
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x36: rol dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
void bCPU::op_rol_dpxb() {
|
||||
uint8 c = regs.p.c;
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
rd.l <<= 1;
|
||||
rd.l |= c;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_rol_dpxw() {
|
||||
uint16 c = regs.p.c;
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
rd.w <<= 1;
|
||||
rd.w |= c;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a
|
||||
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x6a: ror ***
|
||||
*****************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; io
|
||||
*/
|
||||
void bCPU::op_rorb() {
|
||||
uint8 c = (regs.p.c)?0x80:0;
|
||||
cpu_io(); //2
|
||||
regs.p.c = regs.a.l & 1;
|
||||
regs.a.l >>= 1;
|
||||
regs.a.l |= c;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_rorw() {
|
||||
uint16 c = (regs.p.c)?0x8000:0;
|
||||
cpu_io(); //2
|
||||
regs.p.c = regs.a.w & 1;
|
||||
regs.a.w >>= 1;
|
||||
regs.a.w |= c;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x6e: ror addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
[5 ] dbr,aa+1 ; io
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
[6 ] dbr,aa ; data low
|
||||
*/
|
||||
void bCPU::op_ror_addrb() {
|
||||
uint8 c = (regs.p.c)?0x80:0;
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l >>= 1;
|
||||
rd.l |= c;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DBR, aa.w, rd.l); //6
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_ror_addrw() {
|
||||
uint16 c = (regs.p.c)?0x8000:0;
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
rd.l = op_read(OPMODE_DBR, aa.w); //4
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w >>= 1;
|
||||
rd.w |= c;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a
|
||||
op_write(OPMODE_DBR, aa.w, rd.l); //6
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x7e: ror addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aah,aal+xl ; io
|
||||
[5 ] dbr,aa+x ; data low
|
||||
[5a] dbr,aa+x+1 ; data high [1]
|
||||
[6 ] dbr,aa+x+1 ; io
|
||||
[7a] dbr,aa+x+1 ; data high [1]
|
||||
[7 ] dbr,aa+x ; data low
|
||||
*/
|
||||
void bCPU::op_ror_addrxb() {
|
||||
uint8 c = (regs.p.c)?0x80:0;
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l >>= 1;
|
||||
rd.l |= c;
|
||||
cpu_io(); //6
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_ror_addrxw() {
|
||||
uint16 c = (regs.p.c)?0x8000:0;
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
|
||||
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w >>= 1;
|
||||
rd.w |= c;
|
||||
cpu_io(); //6
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x66: ror dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
[4 ] 0,d+dp+1 ; io
|
||||
[5a] 0,d+dp+1 ; data high [1]
|
||||
[5 ] 0,d+dp ; data low
|
||||
*/
|
||||
void bCPU::op_ror_dpb() {
|
||||
uint8 c = (regs.p.c)?0x80:0;
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l >>= 1;
|
||||
rd.l |= c;
|
||||
cpu_io(); //4
|
||||
op_write(OPMODE_DP, dp, rd.l); //5
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_ror_dpw() {
|
||||
uint16 c = (regs.p.c)?0x8000:0;
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
rd.l = op_read(OPMODE_DP, dp); //3
|
||||
rd.h = op_read(OPMODE_DP, dp + 1); //3a
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w >>= 1;
|
||||
rd.w |= c;
|
||||
cpu_io(); //4
|
||||
op_write(OPMODE_DP, dp + 1, rd.h); //5a
|
||||
op_write(OPMODE_DP, dp, rd.l); //5
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x76: ror dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high [1]
|
||||
[5 ] 0,d+dp+x+1 ; io
|
||||
[6a] 0,d+dp+x+1 ; data high [1]
|
||||
[6 ] 0,d+dp+x ; data low
|
||||
*/
|
||||
void bCPU::op_ror_dpxb() {
|
||||
uint8 c = (regs.p.c)?0x80:0;
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l >>= 1;
|
||||
rd.l |= c;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_ror_dpxw() {
|
||||
uint16 c = (regs.p.c)?0x8000:0;
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w >>= 1;
|
||||
rd.w |= c;
|
||||
cpu_io(); //5
|
||||
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a
|
||||
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
@@ -1,387 +0,0 @@
|
||||
/**********************
|
||||
*** 0x8d: sta addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] dbr,aa ; data low
|
||||
[4a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sta_addrb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
op_write(OPMODE_DBR, aa.w, regs.a.l); //4
|
||||
}
|
||||
|
||||
void bCPU::op_sta_addrw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
op_write(OPMODE_DBR, aa.w, regs.a.l); //4
|
||||
op_write(OPMODE_DBR, aa.w + 1, regs.a.h); //4a
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x9d: sta addr,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+xl ; io [4]
|
||||
[4 ] dbr,aa+x ; data low
|
||||
[4a] dbr,aa+x+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sta_addrxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w, regs.a.l); //4
|
||||
}
|
||||
|
||||
void bCPU::op_sta_addrxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.x.w); //3a
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w, regs.a.l); //4
|
||||
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, regs.a.h); //4a
|
||||
}
|
||||
|
||||
/********************
|
||||
*** 0x85: sta dp ***
|
||||
********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; data low
|
||||
[3a] 0,d+dp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sta_dpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
op_write(OPMODE_DP, dp, regs.a.l); //3
|
||||
}
|
||||
|
||||
void bCPU::op_sta_dpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
op_write(OPMODE_DP, dp, regs.a.l); //3
|
||||
op_write(OPMODE_DP, dp + 1, regs.a.h); //3a
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x92: sta (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] dbr,aa ; data low
|
||||
[5a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sta_idpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
op_write(OPMODE_DBR, aa.w, regs.a.l); //5
|
||||
}
|
||||
|
||||
void bCPU::op_sta_idpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
op_write(OPMODE_DBR, aa.w, regs.a.l); //5
|
||||
op_write(OPMODE_DBR, aa.w + 1, regs.a.h); //5
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x87: sta [dp] ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa ; data low
|
||||
[6a] aab,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sta_ildpb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
op_write(OPMODE_LONG, aa.d, regs.a.l); //6
|
||||
}
|
||||
|
||||
void bCPU::op_sta_ildpw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
op_write(OPMODE_LONG, aa.d, regs.a.l); //6
|
||||
op_write(OPMODE_LONG, aa.d + 1, regs.a.h); //6a
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x8f: sta long ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa ; data low
|
||||
[5a] aab,aa+1 ; data high
|
||||
*/
|
||||
void bCPU::op_sta_longb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
op_write(OPMODE_LONG, aa.d, regs.a.l); //5
|
||||
}
|
||||
|
||||
void bCPU::op_sta_longw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
op_write(OPMODE_LONG, aa.d, regs.a.l); //5
|
||||
op_write(OPMODE_LONG, aa.d + 1, regs.a.h); //5a
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x9f: sta long,x ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[4 ] pbr,pc+3 ; aab
|
||||
[5 ] aab,aa+x ; data low
|
||||
[5a] aab,aa+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_sta_longxb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l); //5
|
||||
}
|
||||
|
||||
void bCPU::op_sta_longxw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
aa.b = op_read(); //4
|
||||
op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l); //5
|
||||
op_write(OPMODE_LONG, aa.d + regs.x.w + 1, regs.a.h); //5a
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x99: sta addr,y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; operand
|
||||
[2 ] pbr,pc+1 ; aal
|
||||
[3 ] pbr,pc+2 ; aah
|
||||
[3a] dbr,aah,aal+yl ; io [4]
|
||||
[4 ] dbr,aa+y ; data low
|
||||
[4a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sta_addryb() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //4
|
||||
}
|
||||
|
||||
void bCPU::op_sta_addryw() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //3a
|
||||
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //4
|
||||
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); //4a
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x95: sta dp,x ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; data low
|
||||
[4a] 0,d+dp+x+1 ; data high
|
||||
*/
|
||||
void bCPU::op_sta_dpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
op_write(OPMODE_DP, dp + regs.x.w, regs.a.l); //4
|
||||
}
|
||||
|
||||
void bCPU::op_sta_dpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
op_write(OPMODE_DP, dp + regs.x.w, regs.a.l); //4
|
||||
op_write(OPMODE_DP, dp + regs.x.w + 1, regs.a.h); //4a
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x81: sta (dp,x) ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,d+dp+x ; aal
|
||||
[5 ] 0,d+dp+x+1 ; aah
|
||||
[6 ] dbr,aa ; data low
|
||||
[6a] dbr,aa+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sta_idpxb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
op_write(OPMODE_DBR, aa.w, regs.a.l); //6
|
||||
}
|
||||
|
||||
void bCPU::op_sta_idpxw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
|
||||
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
|
||||
op_write(OPMODE_DBR, aa.w, regs.a.l); //6
|
||||
op_write(OPMODE_DBR, aa.w + 1, regs.a.h); //6a
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x91: sta (dp),y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[4a] dbr,aah,aal+yl ; io [4]
|
||||
[5 ] dbr,aa+y ; data low
|
||||
[5a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sta_idpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //5
|
||||
}
|
||||
|
||||
void bCPU::op_sta_idpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
cpu_c4(aa.w, aa.w + regs.y.w); //4a
|
||||
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //5
|
||||
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); //5a
|
||||
}
|
||||
|
||||
/************************
|
||||
*** 0x97: sta [dp],y ***
|
||||
************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io [2]
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,d+dp+2 ; aab
|
||||
[6 ] aab,aa+y ; data low
|
||||
[6a] aab,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sta_ildpyb() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l); //6
|
||||
}
|
||||
|
||||
void bCPU::op_sta_ildpyw() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
aa.b = op_read(OPMODE_DP, dp + 2); //5
|
||||
op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l); //6
|
||||
op_write(OPMODE_LONG, aa.d + regs.y.w + 1, regs.a.h); //6a
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x83: sta sr,s ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; data low
|
||||
[4a] 0,s+sp+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sta_srb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
op_write(OPMODE_SP, sp, regs.a.l); //4
|
||||
}
|
||||
|
||||
void bCPU::op_sta_srw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
op_write(OPMODE_SP, sp, regs.a.l); //4
|
||||
op_write(OPMODE_SP, sp + 1, regs.a.h); //4a
|
||||
}
|
||||
|
||||
/**************************
|
||||
*** 0x93: sta (sr,s),y ***
|
||||
**************************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; sp
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+sp ; aal
|
||||
[5 ] 0,s+sp+1 ; aah
|
||||
[6 ] 0,s+sp+1 ; io
|
||||
[7 ] dbr,aa+y ; data low
|
||||
[7a] dbr,aa+y+1 ; data high [1]
|
||||
*/
|
||||
void bCPU::op_sta_isryb() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //7
|
||||
}
|
||||
|
||||
void bCPU::op_sta_isryw() {
|
||||
sp = op_read(); //2
|
||||
cpu_io(); //3
|
||||
aa.l = op_read(OPMODE_SP, sp); //4
|
||||
aa.h = op_read(OPMODE_SP, sp + 1); //5
|
||||
cpu_io(); //6
|
||||
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //7
|
||||
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); //7a
|
||||
}
|
||||
@@ -1,317 +0,0 @@
|
||||
/*****************
|
||||
*** 0x48: pha ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
void bCPU::op_phab() {
|
||||
cpu_io(); //2
|
||||
stack_write(regs.a.l); //3
|
||||
}
|
||||
|
||||
void bCPU::op_phaw() {
|
||||
cpu_io(); //2
|
||||
stack_write(regs.a.h); //3a
|
||||
stack_write(regs.a.l); //3
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x8b: phb ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] 0,s-1 ; dbr
|
||||
*/
|
||||
void bCPU::op_phb() {
|
||||
cpu_io(); //2
|
||||
stack_write(regs.db); //3
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x0b: phd ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
void bCPU::op_phd() {
|
||||
cpu_io(); //2
|
||||
stack_write(regs.d.h); //3a
|
||||
stack_write(regs.d.l); //3
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x4b: phk ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] 0,s-1 ; pcb
|
||||
*/
|
||||
void bCPU::op_phk() {
|
||||
cpu_io(); //2
|
||||
stack_write(regs.pc.b); //3
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x08: php ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
void bCPU::op_php() {
|
||||
cpu_io(); //2
|
||||
stack_write(regs.p); //3
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xda: phx ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
void bCPU::op_phxb() {
|
||||
cpu_io(); //2
|
||||
stack_write(regs.x.l); //3
|
||||
}
|
||||
|
||||
void bCPU::op_phxw() {
|
||||
cpu_io(); //2
|
||||
stack_write(regs.x.h); //3a
|
||||
stack_write(regs.x.l); //3
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x5a: phy ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3a] 0,s ; reg high [1]
|
||||
[3 ] 0,s-1 ; reg low
|
||||
*/
|
||||
void bCPU::op_phyb() {
|
||||
cpu_io(); //2
|
||||
stack_write(regs.y.l); //3
|
||||
}
|
||||
|
||||
void bCPU::op_phyw() {
|
||||
cpu_io(); //2
|
||||
stack_write(regs.y.h); //3a
|
||||
stack_write(regs.y.l); //3
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x68: pla ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
void bCPU::op_plab() {
|
||||
cpu_io(); //2
|
||||
cpu_io(); //3
|
||||
regs.a.l = stack_read(); //4
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_plaw() {
|
||||
cpu_io(); //2
|
||||
cpu_io(); //3
|
||||
regs.a.l = stack_read(); //4
|
||||
regs.a.h = stack_read(); //4a
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xab: plb ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
*/
|
||||
void bCPU::op_plb() {
|
||||
cpu_io(); //2
|
||||
cpu_io(); //3
|
||||
regs.db = stack_read(); //4
|
||||
regs.p.n = !!(regs.db & 0x80);
|
||||
regs.p.z = (regs.db == 0);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x2b: pld ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high
|
||||
*/
|
||||
void bCPU::op_pld() {
|
||||
cpu_io(); //2
|
||||
cpu_io(); //3
|
||||
regs.d.l = stack_read(); //4
|
||||
regs.d.h = stack_read(); //4a
|
||||
regs.p.n = !!(regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x28: plp ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
*/
|
||||
void bCPU::op_plp() {
|
||||
cpu_io(); //2
|
||||
cpu_io(); //3
|
||||
regs.p = stack_read(); //4
|
||||
if(regs.e) {
|
||||
regs.p |= 0x30;
|
||||
} else {
|
||||
switch((regs.p >> 4) & 3) {
|
||||
case 0:optbl = optbl_mx;break;
|
||||
case 1:optbl = optbl_mX;break;
|
||||
case 2:optbl = optbl_Mx;break;
|
||||
case 3:optbl = optbl_MX;break;
|
||||
}
|
||||
}
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0xfa: plx ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
void bCPU::op_plxb() {
|
||||
cpu_io(); //2
|
||||
cpu_io(); //3
|
||||
regs.x.l = stack_read(); //4
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_plxw() {
|
||||
cpu_io(); //2
|
||||
cpu_io(); //3
|
||||
regs.x.l = stack_read(); //4
|
||||
regs.x.h = stack_read(); //4a
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
|
||||
/*****************
|
||||
*** 0x7a: ply ***
|
||||
*****************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; io
|
||||
[3 ] pbr,pc+1 ; io
|
||||
[4 ] 0,s+1 ; reg low
|
||||
[4a] 0,s+2 ; reg high [1]
|
||||
*/
|
||||
void bCPU::op_plyb() {
|
||||
cpu_io(); //2
|
||||
cpu_io(); //3
|
||||
regs.y.l = stack_read(); //4
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
}
|
||||
|
||||
void bCPU::op_plyw() {
|
||||
cpu_io(); //2
|
||||
cpu_io(); //3
|
||||
regs.y.l = stack_read(); //4
|
||||
regs.y.h = stack_read(); //4a
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xf4: pea addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; aal
|
||||
[3] pbr,pc+2 ; aah
|
||||
[4] 0,s ; aah
|
||||
[5] 0,s-1 ; aal
|
||||
*/
|
||||
void bCPU::op_pea() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
stack_write(aa.h); //4
|
||||
stack_write(aa.l); //5
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0xd4: pei (dp) ***
|
||||
**********************
|
||||
cycles:
|
||||
[1 ] pbr,pc ; opcode
|
||||
[2 ] pbr,pc+1 ; dp
|
||||
[2a] pbr,pc+1 ; io
|
||||
[3 ] 0,d+dp ; aal
|
||||
[4 ] 0,d+dp+1 ; aah
|
||||
[5 ] 0,s ; aah
|
||||
[6 ] 0,s-1 ; aal
|
||||
*/
|
||||
void bCPU::op_pei() {
|
||||
dp = op_read(); //2
|
||||
cpu_c2(); //2a
|
||||
aa.l = op_read(OPMODE_DP, dp); //3
|
||||
aa.h = op_read(OPMODE_DP, dp + 1); //4
|
||||
stack_write(aa.h); //5
|
||||
stack_write(aa.l); //6
|
||||
}
|
||||
|
||||
/**********************
|
||||
*** 0x62: per addr ***
|
||||
**********************
|
||||
cycles:
|
||||
[1] pbr,pc ; opcode
|
||||
[2] pbr,pc+1 ; offset low
|
||||
[3] pbr,pc+2 ; offset high
|
||||
[4] pbr,pc+2 ; io
|
||||
[5] 0,s ; pch+offset
|
||||
[6] 0,s-1 ; pcl+offset
|
||||
*/
|
||||
void bCPU::op_per() {
|
||||
aa.l = op_read(); //2
|
||||
aa.h = op_read(); //3
|
||||
cpu_io(); //4
|
||||
rd.w = regs.pc.d + (int16)aa.w;
|
||||
stack_write(rd.h); //5
|
||||
stack_write(rd.l); //6
|
||||
}
|
||||
+4
-1
@@ -2,5 +2,8 @@
|
||||
#include "dcpu.cpp"
|
||||
|
||||
CPU::CPU() {
|
||||
mmio = &mmio_unmapped;
|
||||
cpu_version = 1;
|
||||
}
|
||||
|
||||
CPU::~CPU() {
|
||||
}
|
||||
+76
-33
@@ -1,49 +1,92 @@
|
||||
#include "cpuregs.h"
|
||||
|
||||
class CPU {
|
||||
class CPU : public MMIO {
|
||||
public:
|
||||
MMIO *mmio;
|
||||
virtual void enter() = 0;
|
||||
|
||||
public:
|
||||
//CPU version number
|
||||
//* 1 and 2 are known
|
||||
//* reported by $4210
|
||||
//* affects DRAM refresh behavior
|
||||
uint8 cpu_version;
|
||||
|
||||
//timing
|
||||
virtual uint16 vcounter() = 0;
|
||||
virtual uint16 hcounter() = 0;
|
||||
virtual uint16 hclock() = 0;
|
||||
virtual bool interlace() = 0;
|
||||
virtual bool interlace_field() = 0;
|
||||
virtual bool overscan() = 0;
|
||||
virtual uint16 region_scanlines() = 0;
|
||||
virtual void set_interlace(bool r) = 0;
|
||||
virtual void set_overscan (bool r) = 0;
|
||||
|
||||
CPURegs regs;
|
||||
virtual uint8 port_read (uint8 port) = 0;
|
||||
virtual void port_write(uint8 port, uint8 value) = 0;
|
||||
|
||||
enum {
|
||||
FLAG_N = 0x80, FLAG_V = 0x40,
|
||||
FLAG_M = 0x20, FLAG_X = 0x10,
|
||||
FLAG_D = 0x08, FLAG_I = 0x04,
|
||||
FLAG_Z = 0x02, FLAG_C = 0x01
|
||||
};
|
||||
virtual uint8 pio_status() = 0;
|
||||
virtual void run() = 0;
|
||||
virtual void scanline() = 0;
|
||||
virtual void frame() = 0;
|
||||
virtual void power() = 0;
|
||||
virtual void reset() = 0;
|
||||
virtual uint8 pio_status() = 0;
|
||||
virtual void scanline() = 0;
|
||||
virtual void frame() = 0;
|
||||
virtual void power() = 0;
|
||||
virtual void reset() = 0;
|
||||
|
||||
/*****
|
||||
* in opcode-based CPU emulators, the main emulation routine
|
||||
* will only be able to call the disassemble_opcode() function
|
||||
* on clean opcode edges. but with cycle-based CPU emulators,
|
||||
* the CPU may be in the middle of executing an opcode when the
|
||||
* emulator (e.g. debugger) wants to disassemble an opcode. this
|
||||
* would mean that important registers may not reflect what they
|
||||
* did at the start of the opcode (especially regs.pc), so in
|
||||
* cycle-based emulators, this function should be overridden to
|
||||
* reflect whether or not an opcode has only been partially
|
||||
* executed. if not, the debugger should abort attempts to skip,
|
||||
* disable, or disassemble the current opcode.
|
||||
*****/
|
||||
virtual bool in_opcode() { return false; }
|
||||
|
||||
/*****
|
||||
* opcode disassembler
|
||||
*****/
|
||||
enum {
|
||||
OPTYPE_DP = 0, //dp
|
||||
OPTYPE_DPX, //dp,x
|
||||
OPTYPE_DPY, //dp,y
|
||||
OPTYPE_IDP, //(dp)
|
||||
OPTYPE_IDPX, //(dp,x)
|
||||
OPTYPE_IDPY, //(dp),y
|
||||
OPTYPE_ILDP, //[dp]
|
||||
OPTYPE_ILDPY, //[dp],y
|
||||
OPTYPE_ADDR, //addr
|
||||
OPTYPE_ADDRX, //addr,x
|
||||
OPTYPE_ADDRY, //addr,y
|
||||
OPTYPE_IADDRX, //(addr,x)
|
||||
OPTYPE_ILADDR, //[addr]
|
||||
OPTYPE_LONG, //long
|
||||
OPTYPE_LONGX, //long, x
|
||||
OPTYPE_SR, //sr,s
|
||||
OPTYPE_ISRY, //(sr,s),y
|
||||
OPTYPE_ADDR_PC, //pbr:addr
|
||||
OPTYPE_IADDR_PC, //pbr:(addr)
|
||||
OPTYPE_RELB, //relb
|
||||
OPTYPE_RELW, //relw
|
||||
};
|
||||
|
||||
//opcode disassembler
|
||||
enum {
|
||||
OPTYPE_DP = 0, //dp
|
||||
OPTYPE_DPX, //dp,x
|
||||
OPTYPE_DPY, //dp,y
|
||||
OPTYPE_IDP, //(dp)
|
||||
OPTYPE_IDPX, //(dp,x)
|
||||
OPTYPE_IDPY, //(dp),y
|
||||
OPTYPE_ILDP, //[dp]
|
||||
OPTYPE_ILDPY, //[dp],y
|
||||
OPTYPE_ADDR, //addr
|
||||
OPTYPE_ADDRX, //addr,x
|
||||
OPTYPE_ADDRY, //addr,y
|
||||
OPTYPE_IADDRX, //(addr,x)
|
||||
OPTYPE_ILADDR, //[addr]
|
||||
OPTYPE_LONG, //long
|
||||
OPTYPE_LONGX, //long, x
|
||||
OPTYPE_SR, //sr,s
|
||||
OPTYPE_ISRY, //(sr,s),y
|
||||
OPTYPE_ADDR_PC, //pbr:addr
|
||||
OPTYPE_IADDR_PC //pbr:(addr)
|
||||
};
|
||||
void disassemble_opcode(char *output);
|
||||
uint32 resolve_offset(uint8 offset_type, uint32 addr);
|
||||
uint8 dreadb(uint32 addr);
|
||||
uint16 dreadw(uint32 addr);
|
||||
uint32 dreadl(uint32 addr);
|
||||
uint32 decode(uint8 offset_type, uint32 addr);
|
||||
uint8 opcode_length();
|
||||
uint16 __relb(int8 offset);
|
||||
uint16 __relw(int16 offset);
|
||||
|
||||
CPU();
|
||||
virtual ~CPU();
|
||||
};
|
||||
+49
-58
@@ -1,76 +1,66 @@
|
||||
class CPURegFlags {
|
||||
private:
|
||||
template <uint8 B> class bit {
|
||||
public:
|
||||
uint8 b;
|
||||
inline operator bool() { return (b & B); }
|
||||
inline operator = (bool i) { (i) ? b |= B : b &= ~B; return (b & B); }
|
||||
inline operator & (bool i) { if(i)b &= ~B; return (b & B); }
|
||||
inline operator | (bool i) { if(i)b |= B; return (b & B); }
|
||||
inline operator ^ (bool i) { if(i)b ^= B; return (b & B); }
|
||||
};
|
||||
public:
|
||||
union {
|
||||
uint8 b;
|
||||
bit<0x80> n;
|
||||
bit<0x40> v;
|
||||
bit<0x20> m;
|
||||
bit<0x10> x;
|
||||
bit<0x08> d;
|
||||
bit<0x04> i;
|
||||
bit<0x02> z;
|
||||
bit<0x01> c;
|
||||
union {
|
||||
uint8 data;
|
||||
struct {
|
||||
bool order_msb8(n:1, v:1, m:1, x:1, d:1, i:1, z:1, c:1);
|
||||
};
|
||||
};
|
||||
|
||||
CPURegFlags() { b = 0; }
|
||||
inline operator uint8() { return b; }
|
||||
inline unsigned operator = (uint8 i) { b = i; return b; }
|
||||
inline unsigned operator &= (uint8 i) { b &= i; return b; }
|
||||
inline unsigned operator |= (uint8 i) { b |= i; return b; }
|
||||
inline unsigned operator ^= (uint8 i) { b ^= i; return b; }
|
||||
inline operator unsigned() const { return data; }
|
||||
template<typename T> inline unsigned operator = (const T i) { data = i; return data; }
|
||||
template<typename T> inline unsigned operator |= (const T i) { data |= i; return data; }
|
||||
template<typename T> inline unsigned operator ^= (const T i) { data ^= i; return data; }
|
||||
template<typename T> inline unsigned operator &= (const T i) { data &= i; return data; }
|
||||
|
||||
CPURegFlags() : data(0) {}
|
||||
};
|
||||
|
||||
class CPUReg16 {
|
||||
public:
|
||||
union {
|
||||
union {
|
||||
uint16 w;
|
||||
struct { uint8 l, h; };
|
||||
};
|
||||
struct { uint8 order_lsb2(l, h); };
|
||||
};
|
||||
|
||||
CPUReg16() { w = 0; }
|
||||
inline operator uint16() { return w; }
|
||||
inline unsigned operator = (uint16 i) { w = i; return w; }
|
||||
inline unsigned operator += (uint16 i) { w += i; return w; }
|
||||
inline unsigned operator -= (uint16 i) { w -= i; return w; }
|
||||
inline unsigned operator *= (uint16 i) { w *= i; return w; }
|
||||
inline unsigned operator /= (uint16 i) { w /= i; return w; }
|
||||
inline unsigned operator &= (uint16 i) { w &= i; return w; }
|
||||
inline unsigned operator |= (uint16 i) { w |= i; return w; }
|
||||
inline unsigned operator ^= (uint16 i) { w ^= i; return w; }
|
||||
inline unsigned operator <<= (uint16 i) { w <<= i; return w; }
|
||||
inline unsigned operator >>= (uint16 i) { w >>= i; return w; }
|
||||
inline operator unsigned() const { return w; }
|
||||
template<typename T> inline unsigned operator = (const T i) { w = i; return w; }
|
||||
template<typename T> inline unsigned operator |= (const T i) { w |= i; return w; }
|
||||
template<typename T> inline unsigned operator ^= (const T i) { w ^= i; return w; }
|
||||
template<typename T> inline unsigned operator &= (const T i) { w &= i; return w; }
|
||||
template<typename T> inline unsigned operator <<= (const T i) { w <<= i; return w; }
|
||||
template<typename T> inline unsigned operator >>= (const T i) { w >>= i; return w; }
|
||||
template<typename T> inline unsigned operator += (const T i) { w += i; return w; }
|
||||
template<typename T> inline unsigned operator -= (const T i) { w -= i; return w; }
|
||||
template<typename T> inline unsigned operator *= (const T i) { w *= i; return w; }
|
||||
template<typename T> inline unsigned operator /= (const T i) { w /= i; return w; }
|
||||
template<typename T> inline unsigned operator %= (const T i) { w %= i; return w; }
|
||||
|
||||
CPUReg16() : w(0) {}
|
||||
};
|
||||
|
||||
class CPUReg24 {
|
||||
public:
|
||||
union {
|
||||
uint16 w;
|
||||
union {
|
||||
uint32 d;
|
||||
struct { uint8 l, h, b; };
|
||||
};
|
||||
struct { uint16 order_lsb2(w, wh); };
|
||||
struct { uint8 order_lsb4(l, h, b, bh); };
|
||||
};
|
||||
|
||||
CPUReg24() { d = 0; }
|
||||
inline operator uint32() { return (d & 0xffffff); }
|
||||
inline unsigned operator = (uint16 i) { d = i; return d; }
|
||||
inline unsigned operator += (uint16 i) { d += i; return d; }
|
||||
inline unsigned operator -= (uint16 i) { d -= i; return d; }
|
||||
inline unsigned operator *= (uint16 i) { d *= i; return d; }
|
||||
inline unsigned operator /= (uint16 i) { d /= i; return d; }
|
||||
inline unsigned operator &= (uint16 i) { d &= i; return d; }
|
||||
inline unsigned operator |= (uint16 i) { d |= i; return d; }
|
||||
inline unsigned operator ^= (uint16 i) { d ^= i; return d; }
|
||||
inline unsigned operator <<= (uint16 i) { d <<= i; return d; }
|
||||
inline unsigned operator >>= (uint16 i) { d >>= i; return d; }
|
||||
inline operator unsigned() const { return d; }
|
||||
template<typename T> inline unsigned operator = (const T i) { d = uclip<24>(i); return d; }
|
||||
template<typename T> inline unsigned operator |= (const T i) { d = uclip<24>(d | i); return d; }
|
||||
template<typename T> inline unsigned operator ^= (const T i) { d = uclip<24>(d ^ i); return d; }
|
||||
template<typename T> inline unsigned operator &= (const T i) { d = uclip<24>(d & i); return d; }
|
||||
template<typename T> inline unsigned operator <<= (const T i) { d = uclip<24>(d << i); return d; }
|
||||
template<typename T> inline unsigned operator >>= (const T i) { d = uclip<24>(d >> i); return d; }
|
||||
template<typename T> inline unsigned operator += (const T i) { d = uclip<24>(d + i); return d; }
|
||||
template<typename T> inline unsigned operator -= (const T i) { d = uclip<24>(d - i); return d; }
|
||||
template<typename T> inline unsigned operator *= (const T i) { d = uclip<24>(d * i); return d; }
|
||||
template<typename T> inline unsigned operator /= (const T i) { d = uclip<24>(d / i); return d; }
|
||||
template<typename T> inline unsigned operator %= (const T i) { d = uclip<24>(d % i); return d; }
|
||||
|
||||
CPUReg24() : d(0) {}
|
||||
};
|
||||
|
||||
class CPURegs {
|
||||
@@ -79,6 +69,7 @@ CPUReg24 pc;
|
||||
CPUReg16 a, x, y, s, d;
|
||||
CPURegFlags p;
|
||||
uint8 db;
|
||||
uint8 mdr;
|
||||
bool e;
|
||||
CPURegs() { db = 0; e = false; }
|
||||
CPURegs() : db(0), mdr(0x00), e(false) {}
|
||||
};
|
||||
+368
-332
@@ -1,16 +1,28 @@
|
||||
uint16 CPU::__relb(int8 offset) {
|
||||
uint32 addr;
|
||||
addr = (regs.pc.d & 0xff0000) | ((regs.pc.d + 2) & 0xffff);
|
||||
return addr + offset;
|
||||
uint8 CPU::dreadb(uint32 addr) {
|
||||
if((addr & 0x40ffff) >= 0x2000 && (addr & 0x40ffff) <= 0x5fff) {
|
||||
//$[00-3f|80-bf]:[2000-5fff]
|
||||
//do not read MMIO registers within debugger
|
||||
return 0x00;
|
||||
}
|
||||
return r_mem->read(addr);
|
||||
}
|
||||
|
||||
uint16 CPU::__relw(int16 offset) {
|
||||
uint32 addr;
|
||||
addr = (regs.pc.d & 0xff0000) | ((regs.pc.d + 3) & 0xffff);
|
||||
return addr + offset;
|
||||
uint16 CPU::dreadw(uint32 addr) {
|
||||
uint16 r;
|
||||
r = dreadb((addr + 0) & 0xffffff) << 0;
|
||||
r |= dreadb((addr + 1) & 0xffffff) << 8;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32 CPU::resolve_offset(uint8 offset_type, uint32 addr) {
|
||||
uint32 CPU::dreadl(uint32 addr) {
|
||||
uint32 r;
|
||||
r = dreadb((addr + 0) & 0xffffff) << 0;
|
||||
r |= dreadb((addr + 1) & 0xffffff) << 8;
|
||||
r |= dreadb((addr + 2) & 0xffffff) << 16;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32 CPU::decode(uint8 offset_type, uint32 addr) {
|
||||
uint32 r = 0;
|
||||
switch(offset_type) {
|
||||
case OPTYPE_DP:
|
||||
@@ -24,23 +36,23 @@ uint32 r = 0;
|
||||
break;
|
||||
case OPTYPE_IDP:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = (regs.db << 16) + mem_bus->read_word(addr);
|
||||
r = (regs.db << 16) + dreadw(addr);
|
||||
break;
|
||||
case OPTYPE_IDPX:
|
||||
addr = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
|
||||
r = (regs.db << 16) + mem_bus->read_word(addr);
|
||||
r = (regs.db << 16) + dreadw(addr);
|
||||
break;
|
||||
case OPTYPE_IDPY:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = (regs.db << 16) + mem_bus->read_word(addr) + regs.y;
|
||||
r = (regs.db << 16) + dreadw(addr) + regs.y;
|
||||
break;
|
||||
case OPTYPE_ILDP:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = mem_bus->read_long(addr);
|
||||
r = dreadl(addr);
|
||||
break;
|
||||
case OPTYPE_ILDPY:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = mem_bus->read_long(addr) + regs.y;
|
||||
r = dreadl(addr) + regs.y;
|
||||
break;
|
||||
case OPTYPE_ADDR:
|
||||
r = (regs.db << 16) + (addr & 0xffff);
|
||||
@@ -61,356 +73,376 @@ uint32 r = 0;
|
||||
r = (regs.pc.b << 16) + ((addr + regs.x) & 0xffff);
|
||||
break;
|
||||
case OPTYPE_ILADDR:
|
||||
r = addr & 0xffffff;
|
||||
r = addr;
|
||||
break;
|
||||
case OPTYPE_LONG:
|
||||
r = addr & 0xffffff;
|
||||
r = addr;
|
||||
break;
|
||||
case OPTYPE_LONGX:
|
||||
r = (addr + regs.x) & 0xffffff;
|
||||
r = (addr + regs.x);
|
||||
break;
|
||||
case OPTYPE_SR:
|
||||
r = (regs.s + (addr & 0xff)) & 0xffff;
|
||||
break;
|
||||
case OPTYPE_ISRY:
|
||||
addr = (regs.s + (addr & 0xff)) & 0xffff;
|
||||
r = (regs.db << 16) + mem_bus->read_word(addr) + regs.y;
|
||||
r = (regs.db << 16) + dreadw(addr) + regs.y;
|
||||
break;
|
||||
case OPTYPE_RELB:
|
||||
r = (regs.pc.b << 16) + ((regs.pc.w + 2) & 0xffff);
|
||||
r += int8(addr);
|
||||
break;
|
||||
case OPTYPE_RELW:
|
||||
r = (regs.pc.b << 16) + ((regs.pc.w + 3) & 0xffff);
|
||||
r += int16(addr);
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
return(r & 0xffffff);
|
||||
}
|
||||
|
||||
void CPU::disassemble_opcode(char *output) {
|
||||
char *s = output;
|
||||
static CPUReg24 pc;
|
||||
char t[256];
|
||||
uint8 op, op0, op1, op2;
|
||||
sprintf(s, "%0.6x ", regs.pc.d);
|
||||
char *s = output;
|
||||
|
||||
//TODO: This should wrap around the bank byte
|
||||
op = mem_bus->read(regs.pc.d);
|
||||
op0 = mem_bus->read(regs.pc.d + 1);
|
||||
op1 = mem_bus->read(regs.pc.d + 2);
|
||||
op2 = mem_bus->read(regs.pc.d + 3);
|
||||
|
||||
switch(op) {
|
||||
case 0x00:sprintf(t, "brk #$%0.2x ", op0);break;
|
||||
case 0x01:sprintf(t, "ora ($%0.2x,x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDPX, op0));break;
|
||||
case 0x02:sprintf(t, "cop #$%0.2x ", op0);break;
|
||||
case 0x03:sprintf(t, "ora $%0.2x,s [$%0.6x]", op0, resolve_offset(OPTYPE_SR, op0));break;
|
||||
case 0x04:sprintf(t, "tsb $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x05:sprintf(t, "ora $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x06:sprintf(t, "asl $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x07:sprintf(t, "ora [$%0.2x] [$%0.6x]", op0, resolve_offset(OPTYPE_ILDP, op0));break;
|
||||
case 0x08:sprintf(t, "php ");break;
|
||||
case 0x09:
|
||||
if(regs.p.m)sprintf(t, "ora #$%0.2x ", op0);
|
||||
else sprintf(t, "ora #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x0a:sprintf(t, "asl a ");break;
|
||||
case 0x0b:sprintf(t, "phd ");break;
|
||||
case 0x0c:sprintf(t, "tsb $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x0d:sprintf(t, "ora $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x0e:sprintf(t, "asl $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x0f:sprintf(t, "ora $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x10:sprintf(t, "bpl $%0.4x [$%0.6x]", __relb(op0)&0xffff, __relb(op0)&0xffffff);break;
|
||||
case 0x11:sprintf(t, "ora ($%0.2x),y [$%0.6x]", op0, resolve_offset(OPTYPE_IDPY, op0));break;
|
||||
case 0x12:sprintf(t, "ora ($%0.2x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDP, op0));break;
|
||||
case 0x13:sprintf(t, "ora ($%0.2x,s),y [$%0.6x]", op0, resolve_offset(OPTYPE_ISRY, op0));break;
|
||||
case 0x14:sprintf(t, "trb $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x15:sprintf(t, "ora $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0x16:sprintf(t, "asl $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0x17:sprintf(t, "ora [$%0.2x],y [$%0.6x]", op0, resolve_offset(OPTYPE_ILDPY, op0));break;
|
||||
case 0x18:sprintf(t, "clc ");break;
|
||||
case 0x19:sprintf(t, "ora $%0.4x,y [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x1a:sprintf(t, "inc ");break;
|
||||
case 0x1b:sprintf(t, "tcs ");break;
|
||||
case 0x1c:sprintf(t, "trb $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x1d:sprintf(t, "ora $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x1e:sprintf(t, "asl $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x1f:sprintf(t, "ora $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x20:sprintf(t, "jsr $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR_PC, (op0|op1<<8)));break;
|
||||
case 0x21:sprintf(t, "and ($%0.2x,x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDPX, op0));break;
|
||||
case 0x22:sprintf(t, "jsl $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x23:sprintf(t, "and $%0.2x,s [$%0.6x]", op0, resolve_offset(OPTYPE_SR, op0));break;
|
||||
case 0x24:sprintf(t, "bit $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x25:sprintf(t, "and $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x26:sprintf(t, "rol $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x27:sprintf(t, "and [$%0.2x] [$%0.6x]", op0, resolve_offset(OPTYPE_ILDP, op0));break;
|
||||
case 0x28:sprintf(t, "plp ");break;
|
||||
case 0x29:
|
||||
if(regs.p.m)sprintf(t, "and #$%0.2x ", op0);
|
||||
else sprintf(t, "and #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x2a:sprintf(t, "rol a ");break;
|
||||
case 0x2b:sprintf(t, "pld ");break;
|
||||
case 0x2c:sprintf(t, "bit $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x2d:sprintf(t, "and $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x2e:sprintf(t, "rol $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x2f:sprintf(t, "and $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x30:sprintf(t, "bmi $%0.4x [$%0.6x]", __relb(op0)&0xffff, __relb(op0)&0xffffff);break;
|
||||
case 0x31:sprintf(t, "and ($%0.2x),y [$%0.6x]", op0, resolve_offset(OPTYPE_IDPY, op0));break;
|
||||
case 0x32:sprintf(t, "and ($%0.2x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDP, op0));break;
|
||||
case 0x33:sprintf(t, "and ($%0.2x,s),y [$%0.6x]", op0, resolve_offset(OPTYPE_ISRY, op0));break;
|
||||
case 0x34:sprintf(t, "bit $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0x35:sprintf(t, "and $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0x36:sprintf(t, "rol $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0x37:sprintf(t, "and [$%0.2x],y [$%0.6x]", op0, resolve_offset(OPTYPE_ILDPY, op0));break;
|
||||
case 0x38:sprintf(t, "sec ");break;
|
||||
case 0x39:sprintf(t, "and $%0.4x,y [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x3a:sprintf(t, "dec ");break;
|
||||
case 0x3b:sprintf(t, "tsc ");break;
|
||||
case 0x3c:sprintf(t, "bit $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x3d:sprintf(t, "and $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x3e:sprintf(t, "rol $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x3f:sprintf(t, "and $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x40:sprintf(t, "rti ");break;
|
||||
case 0x41:sprintf(t, "eor ($%0.2x,x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDPX, op0));break;
|
||||
case 0x42:sprintf(t, "wdm ");break;
|
||||
case 0x43:sprintf(t, "eor $%0.2x,s [$%0.6x]", op0, resolve_offset(OPTYPE_SR, op0));break;
|
||||
case 0x44:sprintf(t, "mvp $%0.2x,$%0.2x ", op1, op0);break;
|
||||
case 0x45:sprintf(t, "eor $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x46:sprintf(t, "lsr $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x47:sprintf(t, "eor [$%0.2x] [$%0.6x]", op0, resolve_offset(OPTYPE_ILDP, op0));break;
|
||||
case 0x48:sprintf(t, "pha ");break;
|
||||
case 0x49:
|
||||
if(regs.p.m)sprintf(t, "eor #$%0.2x ", op0);
|
||||
else sprintf(t, "eor #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x4a:sprintf(t, "lsr a ");break;
|
||||
case 0x4b:sprintf(t, "phk ");break;
|
||||
case 0x4c:sprintf(t, "jmp $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR_PC, (op0|op1<<8)));break;
|
||||
case 0x4d:sprintf(t, "eor $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x4e:sprintf(t, "lsr $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x4f:sprintf(t, "eor $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x50:sprintf(t, "bvc $%0.4x [$%0.6x]", __relb(op0)&0xffff, __relb(op0)&0xffffff);break;
|
||||
case 0x51:sprintf(t, "eor ($%0.2x),y [$%0.6x]", op0, resolve_offset(OPTYPE_IDPY, op0));break;
|
||||
case 0x52:sprintf(t, "eor ($%0.2x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDP, op0));break;
|
||||
case 0x53:sprintf(t, "eor ($%0.2x,s),y [$%0.6x]", op0, resolve_offset(OPTYPE_ISRY, op0));break;
|
||||
case 0x54:sprintf(t, "mvn $%0.2x,$%0.2x ", op1, op0);break;
|
||||
case 0x55:sprintf(t, "eor $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0x56:sprintf(t, "lsr $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0x57:sprintf(t, "eor [$%0.2x],y [$%0.6x]", op0, resolve_offset(OPTYPE_ILDPY, op0));break;
|
||||
case 0x58:sprintf(t, "cli ");break;
|
||||
case 0x59:sprintf(t, "eor $%0.4x,y [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x5a:sprintf(t, "phy ");break;
|
||||
case 0x5b:sprintf(t, "tcd ");break;
|
||||
case 0x5c:sprintf(t, "jml $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x5d:sprintf(t, "eor $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x5e:sprintf(t, "lsr $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x5f:sprintf(t, "eor $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x60:sprintf(t, "rts ");break;
|
||||
case 0x61:sprintf(t, "adc ($%0.2x,x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDPX, op0));break;
|
||||
case 0x62:sprintf(t, "per $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x63:sprintf(t, "adc $%0.2x,s [$%0.6x]", op0, resolve_offset(OPTYPE_SR, op0));break;
|
||||
case 0x64:sprintf(t, "stz $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x65:sprintf(t, "adc $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x66:sprintf(t, "ror $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x67:sprintf(t, "adc [$%0.2x] [$%0.6x]", op0, resolve_offset(OPTYPE_ILDP, op0));break;
|
||||
case 0x68:sprintf(t, "pla ");break;
|
||||
case 0x69:
|
||||
if(regs.p.m)sprintf(t, "adc #$%0.2x ", op0);
|
||||
else sprintf(t, "adc #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x6a:sprintf(t, "ror a ");break;
|
||||
case 0x6b:sprintf(t, "rtl ");break;
|
||||
case 0x6c:sprintf(t, "jmp ($%0.4x) [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_IADDR_PC, (op0|op1<<8)));break;
|
||||
case 0x6d:sprintf(t, "adc $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x6e:sprintf(t, "ror $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x6f:sprintf(t, "adc $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x70:sprintf(t, "bvs $%0.4x [$%0.6x]", __relb(op0)&0xffff, __relb(op0)&0xffffff);break;
|
||||
case 0x71:sprintf(t, "adc ($%0.2x),y [$%0.6x]", op0, resolve_offset(OPTYPE_IDPY, op0));break;
|
||||
case 0x72:sprintf(t, "adc ($%0.2x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDP, op0));break;
|
||||
case 0x73:sprintf(t, "adc ($%0.2x,s),y [$%0.6x]", op0, resolve_offset(OPTYPE_ISRY, op0));break;
|
||||
case 0x74:sprintf(t, "stz $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0x75:sprintf(t, "adc $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0x76:sprintf(t, "ror $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0x77:sprintf(t, "adc [$%0.2x],y [$%0.6x]", op0, resolve_offset(OPTYPE_ILDPY, op0));break;
|
||||
case 0x78:sprintf(t, "sei ");break;
|
||||
case 0x79:sprintf(t, "adc $%0.4x,y [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x7a:sprintf(t, "ply ");break;
|
||||
case 0x7b:sprintf(t, "tdc ");break;
|
||||
case 0x7c:sprintf(t, "jmp ($%0.4x,x) [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_IADDRX, (op0|op1<<8)));break;
|
||||
case 0x7d:sprintf(t, "adc $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x7e:sprintf(t, "ror $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x7f:sprintf(t, "adc $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x80:sprintf(t, "bra $%0.4x [$%0.6x]", __relb(op0)&0xffff, __relb(op0)&0xffffff);break;
|
||||
case 0x81:sprintf(t, "sta ($%0.2x,x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDPX, op0));break;
|
||||
case 0x82:sprintf(t, "brl $%0.4x [$%0.6x]", __relw(op0|op1<<8)&0xffff, __relw(op0|op1<<8)&0xffffff);break;
|
||||
case 0x83:sprintf(t, "sta $%0.2x,s [$%0.6x]", op0, resolve_offset(OPTYPE_SR, op0));break;
|
||||
case 0x84:sprintf(t, "sty $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x85:sprintf(t, "sta $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x86:sprintf(t, "stx $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0x87:sprintf(t, "sta [$%0.2x] [$%0.6x]", op0, resolve_offset(OPTYPE_ILDP, op0));break;
|
||||
case 0x88:sprintf(t, "dey ");break;
|
||||
case 0x89:
|
||||
if(regs.p.m)sprintf(t, "bit #$%0.2x ", op0);
|
||||
else sprintf(t, "bit #$%0.4x ", op0|op1<<8);break;
|
||||
case 0x8a:sprintf(t, "txa ");break;
|
||||
case 0x8b:sprintf(t, "phb ");break;
|
||||
case 0x8c:sprintf(t, "sty $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x8d:sprintf(t, "sta $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x8e:sprintf(t, "stx $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x8f:sprintf(t, "sta $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0x90:sprintf(t, "bcc $%0.4x [$%0.6x]", __relb(op0)&0xffff, __relb(op0)&0xffffff);break;
|
||||
case 0x91:sprintf(t, "sta ($%0.2x),y [$%0.6x]", op0, resolve_offset(OPTYPE_IDPY, op0));break;
|
||||
case 0x92:sprintf(t, "sta ($%0.2x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDP, op0));break;
|
||||
case 0x93:sprintf(t, "sta ($%0.2x,s),y [$%0.6x]", op0, resolve_offset(OPTYPE_ISRY, op0));break;
|
||||
case 0x94:sprintf(t, "sty $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0x95:sprintf(t, "sta $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0x96:sprintf(t, "stx $%0.2x,y [$%0.6x]", op0, resolve_offset(OPTYPE_DPY, op0));break;
|
||||
case 0x97:sprintf(t, "sta [$%0.2x],y [$%0.6x]", op0, resolve_offset(OPTYPE_ILDPY, op0));break;
|
||||
case 0x98:sprintf(t, "tya ");break;
|
||||
case 0x99:sprintf(t, "sta $%0.4x,y [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0x9a:sprintf(t, "txs ");break;
|
||||
case 0x9b:sprintf(t, "txy ");break;
|
||||
case 0x9c:sprintf(t, "stz $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0x9d:sprintf(t, "sta $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x9e:sprintf(t, "stz $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0x9f:sprintf(t, "sta $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xa0:
|
||||
if(regs.p.x)sprintf(t, "ldy #$%0.2x ", op0);
|
||||
else sprintf(t, "ldy #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xa1:sprintf(t, "lda ($%0.2x,x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDPX, op0));break;
|
||||
case 0xa2:
|
||||
if(regs.p.x)sprintf(t, "ldx #$%0.2x ", op0);
|
||||
else sprintf(t, "ldx #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xa3:sprintf(t, "lda $%0.2x,s [$%0.6x]", op0, resolve_offset(OPTYPE_SR, op0));break;
|
||||
case 0xa4:sprintf(t, "ldy $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0xa5:sprintf(t, "lda $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0xa6:sprintf(t, "ldx $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0xa7:sprintf(t, "lda [$%0.2x] [$%0.6x]", op0, resolve_offset(OPTYPE_ILDP, op0));break;
|
||||
case 0xa8:sprintf(t, "tay ");break;
|
||||
case 0xa9:
|
||||
if(regs.p.m)sprintf(t, "lda #$%0.2x ", op0);
|
||||
else sprintf(t, "lda #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xaa:sprintf(t, "tax ");break;
|
||||
case 0xab:sprintf(t, "plb ");break;
|
||||
case 0xac:sprintf(t, "ldy $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xad:sprintf(t, "lda $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xae:sprintf(t, "ldx $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xaf:sprintf(t, "lda $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xb0:sprintf(t, "bcs $%0.4x [$%0.6x]", __relb(op0)&0xffff, __relb(op0)&0xffffff);break;
|
||||
case 0xb1:sprintf(t, "lda ($%0.2x),y [$%0.6x]", op0, resolve_offset(OPTYPE_IDPY, op0));break;
|
||||
case 0xb2:sprintf(t, "lda ($%0.2x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDP, op0));break;
|
||||
case 0xb3:sprintf(t, "lda ($%0.2x,s),y [$%0.6x]", op0, resolve_offset(OPTYPE_ISRY, op0));break;
|
||||
case 0xb4:sprintf(t, "ldy $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0xb5:sprintf(t, "lda $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0xb6:sprintf(t, "ldx $%0.2x,y [$%0.6x]", op0, resolve_offset(OPTYPE_DPY, op0));break;
|
||||
case 0xb7:sprintf(t, "lda [$%0.2x],y [$%0.6x]", op0, resolve_offset(OPTYPE_ILDPY, op0));break;
|
||||
case 0xb8:sprintf(t, "clv ");break;
|
||||
case 0xb9:sprintf(t, "lda $%0.4x,y [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0xba:sprintf(t, "tsx ");break;
|
||||
case 0xbb:sprintf(t, "tyx ");break;
|
||||
case 0xbc:sprintf(t, "ldy $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xbd:sprintf(t, "lda $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xbe:sprintf(t, "ldx $%0.4x,y [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0xbf:sprintf(t, "lda $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xc0:
|
||||
if(regs.p.x)sprintf(t, "cpy #$%0.2x ", op0);
|
||||
else sprintf(t, "cpy #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xc1:sprintf(t, "cmp ($%0.2x,x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDPX, op0));break;
|
||||
case 0xc2:sprintf(t, "rep #$%0.2x ", op0);break;
|
||||
case 0xc3:sprintf(t, "cmp $%0.2x,s [$%0.6x]", op0, resolve_offset(OPTYPE_SR, op0));break;
|
||||
case 0xc4:sprintf(t, "cpy $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0xc5:sprintf(t, "cmp $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0xc6:sprintf(t, "dec $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0xc7:sprintf(t, "cmp [$%0.2x] [$%0.6x]", op0, resolve_offset(OPTYPE_ILDP, op0));break;
|
||||
case 0xc8:sprintf(t, "iny ");break;
|
||||
case 0xc9:
|
||||
if(regs.p.m)sprintf(t, "cmp #$%0.2x ", op0);
|
||||
else sprintf(t, "cmp #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xca:sprintf(t, "dex ");break;
|
||||
case 0xcb:sprintf(t, "wai ");break;
|
||||
case 0xcc:sprintf(t, "cpy $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xcd:sprintf(t, "cmp $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xce:sprintf(t, "dec $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xcf:sprintf(t, "cmp $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xd0:sprintf(t, "bne $%0.4x [$%0.6x]", __relb(op0)&0xffff, __relb(op0)&0xffffff);break;
|
||||
case 0xd1:sprintf(t, "cmp ($%0.2x),y [$%0.6x]", op0, resolve_offset(OPTYPE_IDPY, op0));break;
|
||||
case 0xd2:sprintf(t, "cmp ($%0.2x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDP, op0));break;
|
||||
case 0xd3:sprintf(t, "cmp ($%0.2x,s),y [$%0.6x]", op0, resolve_offset(OPTYPE_ISRY, op0));break;
|
||||
case 0xd4:sprintf(t, "pei ($%0.2x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDP, op0));break;
|
||||
case 0xd5:sprintf(t, "cmp $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0xd6:sprintf(t, "dec $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0xd7:sprintf(t, "cmp [$%0.2x],y [$%0.6x]", op0, resolve_offset(OPTYPE_ILDPY, op0));break;
|
||||
case 0xd8:sprintf(t, "cld ");break;
|
||||
case 0xd9:sprintf(t, "cmp $%0.4x,y [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0xda:sprintf(t, "phx ");break;
|
||||
case 0xdb:sprintf(t, "stp ");break;
|
||||
case 0xdc:sprintf(t, "jmp [$%0.4x] [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ILADDR, (op0|op1<<8)));break;
|
||||
case 0xdd:sprintf(t, "cmp $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xde:sprintf(t, "dec $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xdf:sprintf(t, "cmp $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xe0:
|
||||
if(regs.p.x)sprintf(t, "cpx #$%0.2x ", op0);
|
||||
else sprintf(t, "cpx #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xe1:sprintf(t, "sbc ($%0.2x,x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDPX, op0));break;
|
||||
case 0xe2:sprintf(t, "sep #$%0.2x ", op0);break;
|
||||
case 0xe3:sprintf(t, "sbc $%0.2x,s [$%0.6x]", op0, resolve_offset(OPTYPE_SR, op0));break;
|
||||
case 0xe4:sprintf(t, "cpx $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0xe5:sprintf(t, "sbc $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0xe6:sprintf(t, "inc $%0.2x [$%0.6x]", op0, resolve_offset(OPTYPE_DP, op0));break;
|
||||
case 0xe7:sprintf(t, "sbc [$%0.2x] [$%0.6x]", op0, resolve_offset(OPTYPE_ILDP, op0));break;
|
||||
case 0xe8:sprintf(t, "inx ");break;
|
||||
case 0xe9:
|
||||
if(regs.p.m)sprintf(t, "sbc #$%0.2x ", op0);
|
||||
else sprintf(t, "sbc #$%0.4x ", op0|op1<<8);break;
|
||||
case 0xea:sprintf(t, "nop ");break;
|
||||
case 0xeb:sprintf(t, "xba ");break;
|
||||
case 0xec:sprintf(t, "cpx $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xed:sprintf(t, "sbc $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xee:sprintf(t, "inc $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xef:sprintf(t, "sbc $%0.6x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONG, (op0|op1<<8|op2<<16)));break;
|
||||
case 0xf0:sprintf(t, "beq $%0.4x [$%0.6x]", __relb(op0)&0xffff, __relb(op0)&0xffffff);break;
|
||||
case 0xf1:sprintf(t, "sbc ($%0.2x),y [$%0.6x]", op0, resolve_offset(OPTYPE_IDPY, op0));break;
|
||||
case 0xf2:sprintf(t, "sbc ($%0.2x) [$%0.6x]", op0, resolve_offset(OPTYPE_IDP, op0));break;
|
||||
case 0xf3:sprintf(t, "sbc ($%0.2x,s),y [$%0.6x]", op0, resolve_offset(OPTYPE_ISRY, op0));break;
|
||||
case 0xf4:sprintf(t, "pea $%0.4x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDR, (op0|op1<<8)));break;
|
||||
case 0xf5:sprintf(t, "sbc $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0xf6:sprintf(t, "inc $%0.2x,x [$%0.6x]", op0, resolve_offset(OPTYPE_DPX, op0));break;
|
||||
case 0xf7:sprintf(t, "sbc [$%0.2x],y [$%0.6x]", op0, resolve_offset(OPTYPE_ILDPY, op0));break;
|
||||
case 0xf8:sprintf(t, "sed ");break;
|
||||
case 0xf9:sprintf(t, "sbc $%0.4x,y [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRY, (op0|op1<<8)));break;
|
||||
case 0xfa:sprintf(t, "plx ");break;
|
||||
case 0xfb:sprintf(t, "xce ");break;
|
||||
case 0xfc:sprintf(t, "jsr ($%0.4x,x) [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_IADDRX, (op0|op1<<8)));break;
|
||||
case 0xfd:sprintf(t, "sbc $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xfe:sprintf(t, "inc $%0.4x,x [$%0.6x]", op0|op1<<8, resolve_offset(OPTYPE_ADDRX, (op0|op1<<8)));break;
|
||||
case 0xff:sprintf(t, "sbc $%0.6x,x [$%0.6x]", op0|op1<<8|op2<<16, resolve_offset(OPTYPE_LONGX, (op0|op1<<8|op2<<16)));break;
|
||||
if(in_opcode() == true) {
|
||||
strcpy(s, "?????? <CPU within opcode>");
|
||||
return;
|
||||
}
|
||||
|
||||
pc.d = regs.pc.d;
|
||||
sprintf(s, "%0.6x ", uint32(pc.d));
|
||||
|
||||
uint8 op = dreadb(pc.d); pc.w++;
|
||||
uint8 op0 = dreadb(pc.d); pc.w++;
|
||||
uint8 op1 = dreadb(pc.d); pc.w++;
|
||||
uint8 op2 = dreadb(pc.d);
|
||||
|
||||
#define op8 ((op0))
|
||||
#define op16 ((op0) | (op1 << 8))
|
||||
#define op24 ((op0) | (op1 << 8) | (op2 << 16))
|
||||
#define a8 (regs.e || regs.p.m)
|
||||
#define x8 (regs.e || regs.p.x)
|
||||
switch(op) {
|
||||
case 0x00: sprintf(t, "brk #$%0.2x ", op8); break;
|
||||
case 0x01: sprintf(t, "ora ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x02: sprintf(t, "cop #$%0.2x ", op8); break;
|
||||
case 0x03: sprintf(t, "ora $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x04: sprintf(t, "tsb $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x05: sprintf(t, "ora $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x06: sprintf(t, "asl $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x07: sprintf(t, "ora [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x08: sprintf(t, "php "); break;
|
||||
case 0x09: if(a8)sprintf(t, "ora #$%0.2x ", op8);
|
||||
else sprintf(t, "ora #$%0.4x ", op16); break;
|
||||
case 0x0a: sprintf(t, "asl a "); break;
|
||||
case 0x0b: sprintf(t, "phd "); break;
|
||||
case 0x0c: sprintf(t, "tsb $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x0d: sprintf(t, "ora $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x0e: sprintf(t, "asl $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x0f: sprintf(t, "ora $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x10: sprintf(t, "bpl $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x11: sprintf(t, "ora ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x12: sprintf(t, "ora ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x13: sprintf(t, "ora ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x14: sprintf(t, "trb $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x15: sprintf(t, "ora $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x16: sprintf(t, "asl $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x17: sprintf(t, "ora [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x18: sprintf(t, "clc "); break;
|
||||
case 0x19: sprintf(t, "ora $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x1a: sprintf(t, "inc "); break;
|
||||
case 0x1b: sprintf(t, "tcs "); break;
|
||||
case 0x1c: sprintf(t, "trb $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x1d: sprintf(t, "ora $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x1e: sprintf(t, "asl $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x1f: sprintf(t, "ora $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0x20: sprintf(t, "jsr $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break;
|
||||
case 0x21: sprintf(t, "and ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x22: sprintf(t, "jsl $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x23: sprintf(t, "and $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x24: sprintf(t, "bit $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x25: sprintf(t, "and $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x26: sprintf(t, "rol $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x27: sprintf(t, "and [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x28: sprintf(t, "plp "); break;
|
||||
case 0x29: if(a8)sprintf(t, "and #$%0.2x ", op8);
|
||||
else sprintf(t, "and #$%0.4x ", op16); break;
|
||||
case 0x2a: sprintf(t, "rol a "); break;
|
||||
case 0x2b: sprintf(t, "pld "); break;
|
||||
case 0x2c: sprintf(t, "bit $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x2d: sprintf(t, "and $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x2e: sprintf(t, "rol $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x2f: sprintf(t, "and $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x30: sprintf(t, "bmi $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x31: sprintf(t, "and ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x32: sprintf(t, "and ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x33: sprintf(t, "and ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x34: sprintf(t, "bit $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x35: sprintf(t, "and $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x36: sprintf(t, "rol $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x37: sprintf(t, "and [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x38: sprintf(t, "sec "); break;
|
||||
case 0x39: sprintf(t, "and $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x3a: sprintf(t, "dec "); break;
|
||||
case 0x3b: sprintf(t, "tsc "); break;
|
||||
case 0x3c: sprintf(t, "bit $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x3d: sprintf(t, "and $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x3e: sprintf(t, "rol $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x3f: sprintf(t, "and $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0x40: sprintf(t, "rti "); break;
|
||||
case 0x41: sprintf(t, "eor ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x42: sprintf(t, "wdm "); break;
|
||||
case 0x43: sprintf(t, "eor $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x44: sprintf(t, "mvp $%0.2x,$%0.2x ", op1, op8); break;
|
||||
case 0x45: sprintf(t, "eor $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x46: sprintf(t, "lsr $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x47: sprintf(t, "eor [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x48: sprintf(t, "pha "); break;
|
||||
case 0x49: if(a8)sprintf(t, "eor #$%0.2x ", op8);
|
||||
else sprintf(t, "eor #$%0.4x ", op16); break;
|
||||
case 0x4a: sprintf(t, "lsr a "); break;
|
||||
case 0x4b: sprintf(t, "phk "); break;
|
||||
case 0x4c: sprintf(t, "jmp $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break;
|
||||
case 0x4d: sprintf(t, "eor $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x4e: sprintf(t, "lsr $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x4f: sprintf(t, "eor $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x50: sprintf(t, "bvc $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x51: sprintf(t, "eor ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x52: sprintf(t, "eor ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x53: sprintf(t, "eor ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x54: sprintf(t, "mvn $%0.2x,$%0.2x ", op1, op8); break;
|
||||
case 0x55: sprintf(t, "eor $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x56: sprintf(t, "lsr $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x57: sprintf(t, "eor [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x58: sprintf(t, "cli "); break;
|
||||
case 0x59: sprintf(t, "eor $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x5a: sprintf(t, "phy "); break;
|
||||
case 0x5b: sprintf(t, "tcd "); break;
|
||||
case 0x5c: sprintf(t, "jml $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x5d: sprintf(t, "eor $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x5e: sprintf(t, "lsr $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x5f: sprintf(t, "eor $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0x60: sprintf(t, "rts "); break;
|
||||
case 0x61: sprintf(t, "adc ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x62: sprintf(t, "per $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x63: sprintf(t, "adc $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x64: sprintf(t, "stz $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x65: sprintf(t, "adc $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x66: sprintf(t, "ror $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x67: sprintf(t, "adc [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x68: sprintf(t, "pla "); break;
|
||||
case 0x69: if(a8)sprintf(t, "adc #$%0.2x ", op8);
|
||||
else sprintf(t, "adc #$%0.4x ", op16); break;
|
||||
case 0x6a: sprintf(t, "ror a "); break;
|
||||
case 0x6b: sprintf(t, "rtl "); break;
|
||||
case 0x6c: sprintf(t, "jmp ($%0.4x) [$%0.6x]", op16, decode(OPTYPE_IADDR_PC, op16)); break;
|
||||
case 0x6d: sprintf(t, "adc $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x6e: sprintf(t, "ror $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x6f: sprintf(t, "adc $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x70: sprintf(t, "bvs $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x71: sprintf(t, "adc ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x72: sprintf(t, "adc ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x73: sprintf(t, "adc ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x74: sprintf(t, "stz $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x75: sprintf(t, "adc $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x76: sprintf(t, "ror $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x77: sprintf(t, "adc [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x78: sprintf(t, "sei "); break;
|
||||
case 0x79: sprintf(t, "adc $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x7a: sprintf(t, "ply "); break;
|
||||
case 0x7b: sprintf(t, "tdc "); break;
|
||||
case 0x7c: sprintf(t, "jmp ($%0.4x,x) [$%0.6x]", op16, decode(OPTYPE_IADDRX, op16)); break;
|
||||
case 0x7d: sprintf(t, "adc $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x7e: sprintf(t, "ror $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x7f: sprintf(t, "adc $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0x80: sprintf(t, "bra $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x81: sprintf(t, "sta ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x82: sprintf(t, "brl $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELW, op16)), decode(OPTYPE_RELW, op16)); break;
|
||||
case 0x83: sprintf(t, "sta $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x84: sprintf(t, "sty $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x85: sprintf(t, "sta $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x86: sprintf(t, "stx $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x87: sprintf(t, "sta [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x88: sprintf(t, "dey "); break;
|
||||
case 0x89: if(a8)sprintf(t, "bit #$%0.2x ", op8);
|
||||
else sprintf(t, "bit #$%0.4x ", op16); break;
|
||||
case 0x8a: sprintf(t, "txa "); break;
|
||||
case 0x8b: sprintf(t, "phb "); break;
|
||||
case 0x8c: sprintf(t, "sty $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x8d: sprintf(t, "sta $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x8e: sprintf(t, "stx $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x8f: sprintf(t, "sta $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x90: sprintf(t, "bcc $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x91: sprintf(t, "sta ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x92: sprintf(t, "sta ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x93: sprintf(t, "sta ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x94: sprintf(t, "sty $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x95: sprintf(t, "sta $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x96: sprintf(t, "stx $%0.2x,y [$%0.6x]", op8, decode(OPTYPE_DPY, op8)); break;
|
||||
case 0x97: sprintf(t, "sta [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x98: sprintf(t, "tya "); break;
|
||||
case 0x99: sprintf(t, "sta $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x9a: sprintf(t, "txs "); break;
|
||||
case 0x9b: sprintf(t, "txy "); break;
|
||||
case 0x9c: sprintf(t, "stz $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x9d: sprintf(t, "sta $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x9e: sprintf(t, "stz $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x9f: sprintf(t, "sta $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0xa0: if(x8)sprintf(t, "ldy #$%0.2x ", op8);
|
||||
else sprintf(t, "ldy #$%0.4x ", op16); break;
|
||||
case 0xa1: sprintf(t, "lda ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0xa2: if(x8)sprintf(t, "ldx #$%0.2x ", op8);
|
||||
else sprintf(t, "ldx #$%0.4x ", op16); break;
|
||||
case 0xa3: sprintf(t, "lda $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0xa4: sprintf(t, "ldy $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xa5: sprintf(t, "lda $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xa6: sprintf(t, "ldx $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xa7: sprintf(t, "lda [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0xa8: sprintf(t, "tay "); break;
|
||||
case 0xa9: if(a8)sprintf(t, "lda #$%0.2x ", op8);
|
||||
else sprintf(t, "lda #$%0.4x ", op16); break;
|
||||
case 0xaa: sprintf(t, "tax "); break;
|
||||
case 0xab: sprintf(t, "plb "); break;
|
||||
case 0xac: sprintf(t, "ldy $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xad: sprintf(t, "lda $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xae: sprintf(t, "ldx $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xaf: sprintf(t, "lda $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0xb0: sprintf(t, "bcs $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xb1: sprintf(t, "lda ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0xb2: sprintf(t, "lda ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xb3: sprintf(t, "lda ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0xb4: sprintf(t, "ldy $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xb5: sprintf(t, "lda $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xb6: sprintf(t, "ldx $%0.2x,y [$%0.6x]", op8, decode(OPTYPE_DPY, op8)); break;
|
||||
case 0xb7: sprintf(t, "lda [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0xb8: sprintf(t, "clv "); break;
|
||||
case 0xb9: sprintf(t, "lda $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0xba: sprintf(t, "tsx "); break;
|
||||
case 0xbb: sprintf(t, "tyx "); break;
|
||||
case 0xbc: sprintf(t, "ldy $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xbd: sprintf(t, "lda $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xbe: sprintf(t, "ldx $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0xbf: sprintf(t, "lda $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0xc0: if(x8)sprintf(t, "cpy #$%0.2x ", op8);
|
||||
else sprintf(t, "cpy #$%0.4x ", op16); break;
|
||||
case 0xc1: sprintf(t, "cmp ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0xc2: sprintf(t, "rep #$%0.2x ", op8); break;
|
||||
case 0xc3: sprintf(t, "cmp $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0xc4: sprintf(t, "cpy $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xc5: sprintf(t, "cmp $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xc6: sprintf(t, "dec $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xc7: sprintf(t, "cmp [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0xc8: sprintf(t, "iny "); break;
|
||||
case 0xc9: if(a8)sprintf(t, "cmp #$%0.2x ", op8);
|
||||
else sprintf(t, "cmp #$%0.4x ", op16); break;
|
||||
case 0xca: sprintf(t, "dex "); break;
|
||||
case 0xcb: sprintf(t, "wai "); break;
|
||||
case 0xcc: sprintf(t, "cpy $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xcd: sprintf(t, "cmp $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xce: sprintf(t, "dec $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xcf: sprintf(t, "cmp $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0xd0: sprintf(t, "bne $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xd1: sprintf(t, "cmp ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0xd2: sprintf(t, "cmp ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xd3: sprintf(t, "cmp ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0xd4: sprintf(t, "pei ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xd5: sprintf(t, "cmp $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xd6: sprintf(t, "dec $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xd7: sprintf(t, "cmp [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0xd8: sprintf(t, "cld "); break;
|
||||
case 0xd9: sprintf(t, "cmp $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0xda: sprintf(t, "phx "); break;
|
||||
case 0xdb: sprintf(t, "stp "); break;
|
||||
case 0xdc: sprintf(t, "jmp [$%0.4x] [$%0.6x]", op16, decode(OPTYPE_ILADDR, op16)); break;
|
||||
case 0xdd: sprintf(t, "cmp $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xde: sprintf(t, "dec $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xdf: sprintf(t, "cmp $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0xe0: if(x8)sprintf(t, "cpx #$%0.2x ", op8);
|
||||
else sprintf(t, "cpx #$%0.4x ", op16); break;
|
||||
case 0xe1: sprintf(t, "sbc ($%0.2x,x) [$%0.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0xe2: sprintf(t, "sep #$%0.2x ", op8); break;
|
||||
case 0xe3: sprintf(t, "sbc $%0.2x,s [$%0.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0xe4: sprintf(t, "cpx $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xe5: sprintf(t, "sbc $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xe6: sprintf(t, "inc $%0.2x [$%0.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xe7: sprintf(t, "sbc [$%0.2x] [$%0.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0xe8: sprintf(t, "inx "); break;
|
||||
case 0xe9: if(a8)sprintf(t, "sbc #$%0.2x ", op8);
|
||||
else sprintf(t, "sbc #$%0.4x ", op16); break;
|
||||
case 0xea: sprintf(t, "nop "); break;
|
||||
case 0xeb: sprintf(t, "xba "); break;
|
||||
case 0xec: sprintf(t, "cpx $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xed: sprintf(t, "sbc $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xee: sprintf(t, "inc $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xef: sprintf(t, "sbc $%0.6x [$%0.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0xf0: sprintf(t, "beq $%0.4x [$%0.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xf1: sprintf(t, "sbc ($%0.2x),y [$%0.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0xf2: sprintf(t, "sbc ($%0.2x) [$%0.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xf3: sprintf(t, "sbc ($%0.2x,s),y [$%0.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0xf4: sprintf(t, "pea $%0.4x [$%0.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xf5: sprintf(t, "sbc $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xf6: sprintf(t, "inc $%0.2x,x [$%0.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xf7: sprintf(t, "sbc [$%0.2x],y [$%0.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0xf8: sprintf(t, "sed "); break;
|
||||
case 0xf9: sprintf(t, "sbc $%0.4x,y [$%0.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0xfa: sprintf(t, "plx "); break;
|
||||
case 0xfb: sprintf(t, "xce "); break;
|
||||
case 0xfc: sprintf(t, "jsr ($%0.4x,x) [$%0.6x]", op16, decode(OPTYPE_IADDRX, op16)); break;
|
||||
case 0xfd: sprintf(t, "sbc $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xfe: sprintf(t, "inc $%0.4x,x [$%0.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xff: sprintf(t, "sbc $%0.6x,x [$%0.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
}
|
||||
#undef op8
|
||||
#undef op16
|
||||
#undef op24
|
||||
#undef a8
|
||||
#undef x8
|
||||
|
||||
strcat(s, t);
|
||||
strcat(s, " ");
|
||||
|
||||
sprintf(t, "A:%0.4x X:%0.4x Y:%0.4x S:%0.4x D:%0.4x DB:%0.2x ",
|
||||
regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d, regs.db);
|
||||
regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d.w, regs.db);
|
||||
strcat(s, t);
|
||||
|
||||
if(regs.e) {
|
||||
sprintf(t, "%c%c%c%c%c%c%c%c",
|
||||
(regs.p.n)?'N':'n', (regs.p.v)?'V':'v',
|
||||
(regs.p.m)?'1':'0', (regs.p.x)?'B':'b',
|
||||
(regs.p.d)?'D':'d', (regs.p.i)?'I':'i',
|
||||
(regs.p.z)?'Z':'z', (regs.p.c)?'C':'c');
|
||||
(regs.p.n) ? 'N' : 'n', (regs.p.v) ? 'V' : 'v',
|
||||
(regs.p.m) ? '1' : '0', (regs.p.x) ? 'B' : 'b',
|
||||
(regs.p.d) ? 'D' : 'd', (regs.p.i) ? 'I' : 'i',
|
||||
(regs.p.z) ? 'Z' : 'z', (regs.p.c) ? 'C' : 'c');
|
||||
} else {
|
||||
sprintf(t, "%c%c%c%c%c%c%c%c",
|
||||
(regs.p.n)?'N':'n', (regs.p.v)?'V':'v',
|
||||
(regs.p.m)?'M':'m', (regs.p.x)?'X':'x',
|
||||
(regs.p.d)?'D':'d', (regs.p.i)?'I':'i',
|
||||
(regs.p.z)?'Z':'z', (regs.p.c)?'C':'c');
|
||||
(regs.p.n) ? 'N' : 'n', (regs.p.v) ? 'V' : 'v',
|
||||
(regs.p.m) ? 'M' : 'm', (regs.p.x) ? 'X' : 'x',
|
||||
(regs.p.d) ? 'D' : 'd', (regs.p.i) ? 'I' : 'i',
|
||||
(regs.p.z) ? 'Z' : 'z', (regs.p.c) ? 'C' : 'c');
|
||||
}
|
||||
|
||||
strcat(s, t);
|
||||
strcat(s, " ");
|
||||
|
||||
sprintf(t, "V:%3d H:%4d", vcounter(), hclock());
|
||||
strcat(s, t);
|
||||
}
|
||||
|
||||
/*
|
||||
opcode_length() retrieves the length of the next opcode
|
||||
to be executed. It is used by the debugger to step over,
|
||||
disable, and proceed cpu opcodes.
|
||||
|
||||
5 and 6 are special cases, 5 is used for #consts based on
|
||||
the A register size, 6 for the X/Y register size. the
|
||||
rest are literal sizes. There's no need to test for
|
||||
emulation mode, as regs.p.m/regs.p.x should *always* be
|
||||
set in emulation mode.
|
||||
*/
|
||||
/*****
|
||||
* opcode_length() retrieves the length of the next opcode
|
||||
* to be executed. It is used by the debugger to step over,
|
||||
* disable and proceed cpu opcodes.
|
||||
*
|
||||
* 5 and 6 are special cases, 5 is used for #consts based on
|
||||
* the A register size, 6 for the X/Y register size. the
|
||||
* rest are literal sizes. There's no need to test for
|
||||
* emulation mode, as regs.p.m/regs.p.x should *always* be
|
||||
* set in emulation mode.
|
||||
*****/
|
||||
uint8 CPU::opcode_length() {
|
||||
uint8 op, len;
|
||||
static uint8 op_len_tbl[256] = {
|
||||
//0,1,2,3, 4,5,6,7, 8,9,a,b, c,d,e,f
|
||||
|
||||
2,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x0n
|
||||
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x1n
|
||||
3,2,4,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x2n
|
||||
@@ -431,9 +463,13 @@ static uint8 op_len_tbl[256] = {
|
||||
6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xen
|
||||
2,2,2,2, 3,2,2,2, 1,3,1,1, 3,3,3,4 //0xfn
|
||||
};
|
||||
op = mem_bus->read(regs.pc.d);
|
||||
if(in_opcode() == true) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
op = dreadb(regs.pc.d);
|
||||
len = op_len_tbl[op];
|
||||
if(len == 5)return (regs.p.m)?2:3;
|
||||
if(len == 6)return (regs.p.x)?2:3;
|
||||
if(len == 5)return (regs.e || regs.p.m) ? 2 : 3;
|
||||
if(len == 6)return (regs.e || regs.p.x) ? 2 : 3;
|
||||
return len;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
cl /nologo /O2 scpugen.cpp
|
||||
@pause
|
||||
@del *.obj
|
||||
@@ -0,0 +1 @@
|
||||
@del *.exe
|
||||
@@ -0,0 +1,64 @@
|
||||
#include "opfn.cpp"
|
||||
|
||||
#include "op_read.cpp"
|
||||
#include "op_write.cpp"
|
||||
#include "op_rmw.cpp"
|
||||
#include "op_pc.cpp"
|
||||
#include "op_misc.cpp"
|
||||
|
||||
void sCPU::enter() { loop:
|
||||
if(event.irq) {
|
||||
event.irq = false;
|
||||
if(status.nmi_pending == true) {
|
||||
status.nmi_pending = false;
|
||||
event.irq_vector = (regs.e == false) ? 0xffea : 0xfffa;
|
||||
} else if(status.irq_pending == true) {
|
||||
status.irq_pending = false;
|
||||
event.irq_vector = (regs.e == false) ? 0xffee : 0xfffe;
|
||||
}
|
||||
op_irq();
|
||||
}
|
||||
|
||||
tracer.trace_cpuop(); //traces CPU opcode (only if tracer is enabled)
|
||||
|
||||
status.in_opcode = true;
|
||||
(this->*optbl[op_readpc()])();
|
||||
status.in_opcode = false;
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
||||
void sCPU::op_irq() {
|
||||
op_read(regs.pc.d);
|
||||
op_io();
|
||||
if(!regs.e)op_writestack(regs.pc.b);
|
||||
op_writestack(regs.pc.h);
|
||||
op_writestack(regs.pc.l);
|
||||
op_writestack(regs.e ? (regs.p & ~0x10) : regs.p);
|
||||
rd.l = op_read(event.irq_vector + 0);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
rd.h = op_read(event.irq_vector + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
alwaysinline void sCPU::op_io_cond2() {
|
||||
if(regs.d.l != 0x00) {
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::op_io_cond4(uint16 x, uint16 y) {
|
||||
if(!regs.p.x || (x & 0xff00) != (y & 0xff00)) {
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::op_io_cond6(uint16 addr) {
|
||||
if(regs.e && (regs.pc.w & 0xff00) != (addr & 0xff00)) {
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
void (sCPU::*optbl[256])();
|
||||
|
||||
CPUReg24 aa, rd;
|
||||
uint8 dp, sp;
|
||||
|
||||
void op_irq();
|
||||
|
||||
inline bool in_opcode() { return status.in_opcode; }
|
||||
|
||||
//op_read
|
||||
void op_adc_b();
|
||||
void op_adc_w();
|
||||
void op_and_b();
|
||||
void op_and_w();
|
||||
void op_bit_b();
|
||||
void op_bit_w();
|
||||
void op_cmp_b();
|
||||
void op_cmp_w();
|
||||
void op_cpx_b();
|
||||
void op_cpx_w();
|
||||
void op_cpy_b();
|
||||
void op_cpy_w();
|
||||
void op_eor_b();
|
||||
void op_eor_w();
|
||||
void op_lda_b();
|
||||
void op_lda_w();
|
||||
void op_ldx_b();
|
||||
void op_ldx_w();
|
||||
void op_ldy_b();
|
||||
void op_ldy_w();
|
||||
void op_ora_b();
|
||||
void op_ora_w();
|
||||
void op_sbc_b();
|
||||
void op_sbc_w();
|
||||
//op_rmw
|
||||
void op_inc_b();
|
||||
void op_inc_w();
|
||||
void op_dec_b();
|
||||
void op_dec_w();
|
||||
void op_asl_b();
|
||||
void op_asl_w();
|
||||
void op_lsr_b();
|
||||
void op_lsr_w();
|
||||
void op_rol_b();
|
||||
void op_rol_w();
|
||||
void op_ror_b();
|
||||
void op_ror_w();
|
||||
void op_trb_b();
|
||||
void op_trb_w();
|
||||
void op_tsb_b();
|
||||
void op_tsb_w();
|
||||
|
||||
void op_io_cond2();
|
||||
void op_io_cond4(uint16 x, uint16 y);
|
||||
void op_io_cond6(uint16 addr);
|
||||
|
||||
#include "op.h"
|
||||
@@ -0,0 +1,256 @@
|
||||
void op_adc_const();
|
||||
void op_and_const();
|
||||
void op_cmp_const();
|
||||
void op_cpx_const();
|
||||
void op_cpy_const();
|
||||
void op_eor_const();
|
||||
void op_lda_const();
|
||||
void op_ldx_const();
|
||||
void op_ldy_const();
|
||||
void op_ora_const();
|
||||
void op_sbc_const();
|
||||
void op_adc_addr();
|
||||
void op_and_addr();
|
||||
void op_bit_addr();
|
||||
void op_cmp_addr();
|
||||
void op_cpx_addr();
|
||||
void op_cpy_addr();
|
||||
void op_eor_addr();
|
||||
void op_lda_addr();
|
||||
void op_ldx_addr();
|
||||
void op_ldy_addr();
|
||||
void op_ora_addr();
|
||||
void op_sbc_addr();
|
||||
void op_adc_addrx();
|
||||
void op_and_addrx();
|
||||
void op_bit_addrx();
|
||||
void op_cmp_addrx();
|
||||
void op_eor_addrx();
|
||||
void op_lda_addrx();
|
||||
void op_ldy_addrx();
|
||||
void op_ora_addrx();
|
||||
void op_sbc_addrx();
|
||||
void op_adc_addry();
|
||||
void op_and_addry();
|
||||
void op_cmp_addry();
|
||||
void op_eor_addry();
|
||||
void op_lda_addry();
|
||||
void op_ldx_addry();
|
||||
void op_ora_addry();
|
||||
void op_sbc_addry();
|
||||
void op_adc_long();
|
||||
void op_and_long();
|
||||
void op_cmp_long();
|
||||
void op_eor_long();
|
||||
void op_lda_long();
|
||||
void op_ora_long();
|
||||
void op_sbc_long();
|
||||
void op_adc_longx();
|
||||
void op_and_longx();
|
||||
void op_cmp_longx();
|
||||
void op_eor_longx();
|
||||
void op_lda_longx();
|
||||
void op_ora_longx();
|
||||
void op_sbc_longx();
|
||||
void op_adc_dp();
|
||||
void op_and_dp();
|
||||
void op_bit_dp();
|
||||
void op_cmp_dp();
|
||||
void op_cpx_dp();
|
||||
void op_cpy_dp();
|
||||
void op_eor_dp();
|
||||
void op_lda_dp();
|
||||
void op_ldx_dp();
|
||||
void op_ldy_dp();
|
||||
void op_ora_dp();
|
||||
void op_sbc_dp();
|
||||
void op_adc_dpx();
|
||||
void op_and_dpx();
|
||||
void op_bit_dpx();
|
||||
void op_cmp_dpx();
|
||||
void op_eor_dpx();
|
||||
void op_lda_dpx();
|
||||
void op_ldy_dpx();
|
||||
void op_ora_dpx();
|
||||
void op_sbc_dpx();
|
||||
void op_ldx_dpy();
|
||||
void op_adc_idp();
|
||||
void op_and_idp();
|
||||
void op_cmp_idp();
|
||||
void op_eor_idp();
|
||||
void op_lda_idp();
|
||||
void op_ora_idp();
|
||||
void op_sbc_idp();
|
||||
void op_adc_idpx();
|
||||
void op_and_idpx();
|
||||
void op_cmp_idpx();
|
||||
void op_eor_idpx();
|
||||
void op_lda_idpx();
|
||||
void op_ora_idpx();
|
||||
void op_sbc_idpx();
|
||||
void op_adc_idpy();
|
||||
void op_and_idpy();
|
||||
void op_cmp_idpy();
|
||||
void op_eor_idpy();
|
||||
void op_lda_idpy();
|
||||
void op_ora_idpy();
|
||||
void op_sbc_idpy();
|
||||
void op_adc_ildp();
|
||||
void op_and_ildp();
|
||||
void op_cmp_ildp();
|
||||
void op_eor_ildp();
|
||||
void op_lda_ildp();
|
||||
void op_ora_ildp();
|
||||
void op_sbc_ildp();
|
||||
void op_adc_ildpy();
|
||||
void op_and_ildpy();
|
||||
void op_cmp_ildpy();
|
||||
void op_eor_ildpy();
|
||||
void op_lda_ildpy();
|
||||
void op_ora_ildpy();
|
||||
void op_sbc_ildpy();
|
||||
void op_adc_sr();
|
||||
void op_and_sr();
|
||||
void op_cmp_sr();
|
||||
void op_eor_sr();
|
||||
void op_lda_sr();
|
||||
void op_ora_sr();
|
||||
void op_sbc_sr();
|
||||
void op_adc_isry();
|
||||
void op_and_isry();
|
||||
void op_cmp_isry();
|
||||
void op_eor_isry();
|
||||
void op_lda_isry();
|
||||
void op_ora_isry();
|
||||
void op_sbc_isry();
|
||||
void op_bit_const();
|
||||
void op_sta_addr();
|
||||
void op_stx_addr();
|
||||
void op_sty_addr();
|
||||
void op_stz_addr();
|
||||
void op_sta_addrx();
|
||||
void op_stz_addrx();
|
||||
void op_sta_addry();
|
||||
void op_sta_long();
|
||||
void op_sta_longx();
|
||||
void op_sta_dp();
|
||||
void op_stx_dp();
|
||||
void op_sty_dp();
|
||||
void op_stz_dp();
|
||||
void op_sta_dpx();
|
||||
void op_sty_dpx();
|
||||
void op_stz_dpx();
|
||||
void op_stx_dpy();
|
||||
void op_sta_idp();
|
||||
void op_sta_ildp();
|
||||
void op_sta_idpx();
|
||||
void op_sta_idpy();
|
||||
void op_sta_ildpy();
|
||||
void op_sta_sr();
|
||||
void op_sta_isry();
|
||||
void op_inc();
|
||||
void op_inx();
|
||||
void op_iny();
|
||||
void op_dec();
|
||||
void op_dex();
|
||||
void op_dey();
|
||||
void op_asl();
|
||||
void op_lsr();
|
||||
void op_rol();
|
||||
void op_ror();
|
||||
void op_inc_addr();
|
||||
void op_dec_addr();
|
||||
void op_asl_addr();
|
||||
void op_lsr_addr();
|
||||
void op_rol_addr();
|
||||
void op_ror_addr();
|
||||
void op_trb_addr();
|
||||
void op_tsb_addr();
|
||||
void op_inc_addrx();
|
||||
void op_dec_addrx();
|
||||
void op_asl_addrx();
|
||||
void op_lsr_addrx();
|
||||
void op_rol_addrx();
|
||||
void op_ror_addrx();
|
||||
void op_inc_dp();
|
||||
void op_dec_dp();
|
||||
void op_asl_dp();
|
||||
void op_lsr_dp();
|
||||
void op_rol_dp();
|
||||
void op_ror_dp();
|
||||
void op_trb_dp();
|
||||
void op_tsb_dp();
|
||||
void op_inc_dpx();
|
||||
void op_dec_dpx();
|
||||
void op_asl_dpx();
|
||||
void op_lsr_dpx();
|
||||
void op_rol_dpx();
|
||||
void op_ror_dpx();
|
||||
void op_bcc();
|
||||
void op_bcs();
|
||||
void op_bne();
|
||||
void op_beq();
|
||||
void op_bpl();
|
||||
void op_bmi();
|
||||
void op_bvc();
|
||||
void op_bvs();
|
||||
void op_bra();
|
||||
void op_brl();
|
||||
void op_jmp_addr();
|
||||
void op_jmp_long();
|
||||
void op_jmp_iaddr();
|
||||
void op_jmp_iaddrx();
|
||||
void op_jmp_iladdr();
|
||||
void op_jsr_addr();
|
||||
void op_jsr_long();
|
||||
void op_jsr_iaddrx();
|
||||
void op_rti();
|
||||
void op_rts();
|
||||
void op_rtl();
|
||||
void op_nop();
|
||||
void op_wdm();
|
||||
void op_xba();
|
||||
void op_mvn();
|
||||
void op_mvp();
|
||||
void op_brk();
|
||||
void op_cop();
|
||||
void op_stp();
|
||||
void op_wai();
|
||||
void op_xce();
|
||||
void op_clc();
|
||||
void op_cld();
|
||||
void op_cli();
|
||||
void op_clv();
|
||||
void op_sec();
|
||||
void op_sed();
|
||||
void op_sei();
|
||||
void op_rep();
|
||||
void op_sep();
|
||||
void op_tax();
|
||||
void op_tay();
|
||||
void op_txa();
|
||||
void op_txy();
|
||||
void op_tya();
|
||||
void op_tyx();
|
||||
void op_tcd();
|
||||
void op_tcs();
|
||||
void op_tdc();
|
||||
void op_tsc();
|
||||
void op_tsx();
|
||||
void op_txs();
|
||||
void op_pha();
|
||||
void op_phx();
|
||||
void op_phy();
|
||||
void op_phd();
|
||||
void op_phb();
|
||||
void op_phk();
|
||||
void op_php();
|
||||
void op_pla();
|
||||
void op_plx();
|
||||
void op_ply();
|
||||
void op_pld();
|
||||
void op_plb();
|
||||
void op_plp();
|
||||
void op_pea();
|
||||
void op_pei();
|
||||
void op_per();
|
||||
@@ -0,0 +1,299 @@
|
||||
nop(0xea) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
wdm(0x42) {
|
||||
1:last_cycle();
|
||||
op_readpc();
|
||||
}
|
||||
|
||||
xba(0xeb) {
|
||||
1:op_io();
|
||||
2:last_cycle();
|
||||
op_io();
|
||||
regs.a.l ^= regs.a.h;
|
||||
regs.a.h ^= regs.a.l;
|
||||
regs.a.l ^= regs.a.h;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
mvn(0x54, ++),
|
||||
mvp(0x44, --) {
|
||||
1:dp = op_readpc();
|
||||
2:sp = op_readpc();
|
||||
3:regs.db = dp;
|
||||
rd.l = op_readlong((sp << 16) | regs.x.w);
|
||||
4:op_writelong((dp << 16) | regs.y.w, rd.l);
|
||||
5:op_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l $1;
|
||||
regs.y.l $1;
|
||||
} else {
|
||||
regs.x.w $1;
|
||||
regs.y.w $1;
|
||||
}
|
||||
6:last_cycle();
|
||||
op_io();
|
||||
if(regs.a.w--)regs.pc.w -= 3;
|
||||
}
|
||||
|
||||
brk(0x00, 0xfffe, 0xffff, 0xffe6, 0xffe7),
|
||||
cop(0x02, 0xfff4, 0xfff5, 0xffe4, 0xffe5) {
|
||||
1:op_readpc();
|
||||
2:if(!regs.e)op_writestack(regs.pc.b);
|
||||
3:op_writestack(regs.pc.h);
|
||||
4:op_writestack(regs.pc.l);
|
||||
5:op_writestack(regs.p);
|
||||
6:rd.l = op_readlong((regs.e) ? $1 : $3);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
7:last_cycle();
|
||||
rd.h = op_readlong((regs.e) ? $2 : $4);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
stp(0xdb) {
|
||||
1:op_io();
|
||||
2:last_cycle();
|
||||
while(1) { op_io(); }
|
||||
}
|
||||
|
||||
wai(0xcb) {
|
||||
//last_cycle() will set event.wai to false
|
||||
//once an NMI / IRQ edge is reached
|
||||
1:event.wai = true;
|
||||
while(event.wai) {
|
||||
last_cycle();
|
||||
op_io();
|
||||
}
|
||||
2:op_io();
|
||||
}
|
||||
|
||||
xce(0xfb) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = regs.e;
|
||||
regs.e = carry;
|
||||
if(regs.e) {
|
||||
regs.p |= 0x30;
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
clc(0x18, regs.p.c = 0),
|
||||
cld(0xd8, regs.p.d = 0),
|
||||
cli(0x58, regs.p.i = 0),
|
||||
clv(0xb8, regs.p.v = 0),
|
||||
sec(0x38, regs.p.c = 1),
|
||||
sed(0xf8, regs.p.d = 1),
|
||||
sei(0x78, regs.p.i = 1) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
$1;
|
||||
}
|
||||
|
||||
rep(0xc2, &=~),
|
||||
sep(0xe2, |=) {
|
||||
1:rd.l = op_readpc();
|
||||
2:last_cycle();
|
||||
op_io();
|
||||
regs.p $1 rd.l;
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
tax(0xaa, regs.p.x, x, a),
|
||||
tay(0xa8, regs.p.x, y, a),
|
||||
txa(0x8a, regs.p.m, a, x),
|
||||
txy(0x9b, regs.p.x, y, x),
|
||||
tya(0x98, regs.p.m, a, y),
|
||||
tyx(0xbb, regs.p.x, x, y) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
if($1) {
|
||||
regs.$2.l = regs.$3.l;
|
||||
regs.p.n = !!(regs.$2.l & 0x80);
|
||||
regs.p.z = (regs.$2.l == 0);
|
||||
} else {
|
||||
regs.$2.w = regs.$3.w;
|
||||
regs.p.n = !!(regs.$2.w & 0x8000);
|
||||
regs.p.z = (regs.$2.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
tcd(0x5b) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
regs.d.w = regs.a.w;
|
||||
regs.p.n = !!(regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
}
|
||||
|
||||
tcs(0x1b) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
regs.s.w = regs.a.w;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
tdc(0x7b) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
regs.a.w = regs.d.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
tsc(0x3b) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
regs.a.w = regs.s.w;
|
||||
if(regs.e) {
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
tsx(0xba) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l = regs.s.l;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w = regs.s.w;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
txs(0x9a) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
if(regs.e) {
|
||||
regs.s.l = regs.x.l;
|
||||
} else {
|
||||
regs.s.w = regs.x.w;
|
||||
}
|
||||
}
|
||||
|
||||
pha(0x48, regs.p.m, a),
|
||||
phx(0xda, regs.p.x, x),
|
||||
phy(0x5a, regs.p.x, y) {
|
||||
1:op_io();
|
||||
2:if(!$1)op_writestack(regs.$2.h);
|
||||
3:last_cycle();
|
||||
op_writestack(regs.$2.l);
|
||||
}
|
||||
|
||||
phd(0x0b) {
|
||||
1:op_io();
|
||||
2:op_writestackn(regs.d.h);
|
||||
3:last_cycle();
|
||||
op_writestackn(regs.d.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
phb(0x8b, regs.db),
|
||||
phk(0x4b, regs.pc.b),
|
||||
php(0x08, regs.p) {
|
||||
1:op_io();
|
||||
2:last_cycle();
|
||||
op_writestack($1);
|
||||
}
|
||||
|
||||
pla(0x68, regs.p.m, a),
|
||||
plx(0xfa, regs.p.x, x),
|
||||
ply(0x7a, regs.p.x, y) {
|
||||
1:op_io();
|
||||
2:op_io();
|
||||
3:if($1)last_cycle();
|
||||
regs.$2.l = op_readstack();
|
||||
if($1) {
|
||||
regs.p.n = !!(regs.$2.l & 0x80);
|
||||
regs.p.z = (regs.$2.l == 0);
|
||||
end;
|
||||
}
|
||||
4:last_cycle();
|
||||
regs.$2.h = op_readstack();
|
||||
regs.p.n = !!(regs.$2.w & 0x8000);
|
||||
regs.p.z = (regs.$2.w == 0);
|
||||
}
|
||||
|
||||
pld(0x2b) {
|
||||
1:op_io();
|
||||
2:op_io();
|
||||
3:regs.d.l = op_readstackn();
|
||||
4:last_cycle();
|
||||
regs.d.h = op_readstackn();
|
||||
regs.p.n = !!(regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
plb(0xab) {
|
||||
1:op_io();
|
||||
2:op_io();
|
||||
3:last_cycle();
|
||||
regs.db = op_readstack();
|
||||
regs.p.n = !!(regs.db & 0x80);
|
||||
regs.p.z = (regs.db == 0);
|
||||
}
|
||||
|
||||
plp(0x28) {
|
||||
1:op_io();
|
||||
2:op_io();
|
||||
3:last_cycle();
|
||||
regs.p = op_readstack();
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
pea(0xf4) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_writestackn(aa.h);
|
||||
4:last_cycle();
|
||||
op_writestackn(aa.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
pei(0xd4) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:op_writestackn(aa.h);
|
||||
6:last_cycle();
|
||||
op_writestackn(aa.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
per(0x62) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io();
|
||||
rd.w = regs.pc.d + (int16)aa.w;
|
||||
4:op_writestackn(rd.h);
|
||||
5:last_cycle();
|
||||
op_writestackn(rd.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
@@ -0,0 +1,490 @@
|
||||
void sCPU::op_nop() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
void sCPU::op_wdm() {
|
||||
last_cycle();
|
||||
op_readpc();
|
||||
}
|
||||
|
||||
void sCPU::op_xba() {
|
||||
op_io();
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.a.l ^= regs.a.h;
|
||||
regs.a.h ^= regs.a.l;
|
||||
regs.a.l ^= regs.a.h;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
void sCPU::op_mvn() {
|
||||
dp = op_readpc();
|
||||
sp = op_readpc();
|
||||
regs.db = dp;
|
||||
rd.l = op_readlong((sp << 16) | regs.x.w);
|
||||
op_writelong((dp << 16) | regs.y.w, rd.l);
|
||||
op_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l ++;
|
||||
regs.y.l ++;
|
||||
} else {
|
||||
regs.x.w ++;
|
||||
regs.y.w ++;
|
||||
}
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.a.w--)regs.pc.w -= 3;
|
||||
}
|
||||
|
||||
void sCPU::op_mvp() {
|
||||
dp = op_readpc();
|
||||
sp = op_readpc();
|
||||
regs.db = dp;
|
||||
rd.l = op_readlong((sp << 16) | regs.x.w);
|
||||
op_writelong((dp << 16) | regs.y.w, rd.l);
|
||||
op_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l --;
|
||||
regs.y.l --;
|
||||
} else {
|
||||
regs.x.w --;
|
||||
regs.y.w --;
|
||||
}
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.a.w--)regs.pc.w -= 3;
|
||||
}
|
||||
|
||||
void sCPU::op_brk() {
|
||||
op_readpc();
|
||||
if(!regs.e)op_writestack(regs.pc.b);
|
||||
op_writestack(regs.pc.h);
|
||||
op_writestack(regs.pc.l);
|
||||
op_writestack(regs.p);
|
||||
rd.l = op_readlong((regs.e) ? 0xfffe : 0xffe6);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
last_cycle();
|
||||
rd.h = op_readlong((regs.e) ? 0xffff : 0xffe7);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
void sCPU::op_cop() {
|
||||
op_readpc();
|
||||
if(!regs.e)op_writestack(regs.pc.b);
|
||||
op_writestack(regs.pc.h);
|
||||
op_writestack(regs.pc.l);
|
||||
op_writestack(regs.p);
|
||||
rd.l = op_readlong((regs.e) ? 0xfff4 : 0xffe4);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
last_cycle();
|
||||
rd.h = op_readlong((regs.e) ? 0xfff5 : 0xffe5);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
void sCPU::op_stp() {
|
||||
op_io();
|
||||
last_cycle();
|
||||
while(1) { op_io(); }
|
||||
}
|
||||
|
||||
void sCPU::op_wai() {
|
||||
//last_cycle() will set event.wai to false
|
||||
//once an NMI / IRQ edge is reached
|
||||
event.wai = true;
|
||||
while(event.wai) {
|
||||
last_cycle();
|
||||
op_io();
|
||||
}
|
||||
op_io();
|
||||
}
|
||||
|
||||
void sCPU::op_xce() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = regs.e;
|
||||
regs.e = carry;
|
||||
if(regs.e) {
|
||||
regs.p |= 0x30;
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_clc() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.p.c = 0;
|
||||
}
|
||||
|
||||
void sCPU::op_cld() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.p.d = 0;
|
||||
}
|
||||
|
||||
void sCPU::op_cli() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.p.i = 0;
|
||||
}
|
||||
|
||||
void sCPU::op_clv() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.p.v = 0;
|
||||
}
|
||||
|
||||
void sCPU::op_sec() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.p.c = 1;
|
||||
}
|
||||
|
||||
void sCPU::op_sed() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.p.d = 1;
|
||||
}
|
||||
|
||||
void sCPU::op_sei() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.p.i = 1;
|
||||
}
|
||||
|
||||
void sCPU::op_rep() {
|
||||
rd.l = op_readpc();
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.p &=~ rd.l;
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_sep() {
|
||||
rd.l = op_readpc();
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.p |= rd.l;
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_tax() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l = regs.a.l;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w = regs.a.w;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_tay() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.x) {
|
||||
regs.y.l = regs.a.l;
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
} else {
|
||||
regs.y.w = regs.a.w;
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_txa() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.m) {
|
||||
regs.a.l = regs.x.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.a.w = regs.x.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_txy() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.x) {
|
||||
regs.y.l = regs.x.l;
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
} else {
|
||||
regs.y.w = regs.x.w;
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_tya() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.m) {
|
||||
regs.a.l = regs.y.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.a.w = regs.y.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_tyx() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l = regs.y.l;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w = regs.y.w;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_tcd() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.d.w = regs.a.w;
|
||||
regs.p.n = !!(regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
}
|
||||
|
||||
void sCPU::op_tcs() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.s.w = regs.a.w;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void sCPU::op_tdc() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.a.w = regs.d.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
void sCPU::op_tsc() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.a.w = regs.s.w;
|
||||
if(regs.e) {
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_tsx() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l = regs.s.l;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w = regs.s.w;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_txs() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.e) {
|
||||
regs.s.l = regs.x.l;
|
||||
} else {
|
||||
regs.s.w = regs.x.w;
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_pha() {
|
||||
op_io();
|
||||
if(!regs.p.m)op_writestack(regs.a.h);
|
||||
last_cycle();
|
||||
op_writestack(regs.a.l);
|
||||
}
|
||||
|
||||
void sCPU::op_phx() {
|
||||
op_io();
|
||||
if(!regs.p.x)op_writestack(regs.x.h);
|
||||
last_cycle();
|
||||
op_writestack(regs.x.l);
|
||||
}
|
||||
|
||||
void sCPU::op_phy() {
|
||||
op_io();
|
||||
if(!regs.p.x)op_writestack(regs.y.h);
|
||||
last_cycle();
|
||||
op_writestack(regs.y.l);
|
||||
}
|
||||
|
||||
void sCPU::op_phd() {
|
||||
op_io();
|
||||
op_writestackn(regs.d.h);
|
||||
last_cycle();
|
||||
op_writestackn(regs.d.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void sCPU::op_phb() {
|
||||
op_io();
|
||||
last_cycle();
|
||||
op_writestack(regs.db);
|
||||
}
|
||||
|
||||
void sCPU::op_phk() {
|
||||
op_io();
|
||||
last_cycle();
|
||||
op_writestack(regs.pc.b);
|
||||
}
|
||||
|
||||
void sCPU::op_php() {
|
||||
op_io();
|
||||
last_cycle();
|
||||
op_writestack(regs.p);
|
||||
}
|
||||
|
||||
void sCPU::op_pla() {
|
||||
op_io();
|
||||
op_io();
|
||||
if(regs.p.m)last_cycle();
|
||||
regs.a.l = op_readstack();
|
||||
if(regs.p.m) {
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
return;
|
||||
}
|
||||
last_cycle();
|
||||
regs.a.h = op_readstack();
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
void sCPU::op_plx() {
|
||||
op_io();
|
||||
op_io();
|
||||
if(regs.p.x)last_cycle();
|
||||
regs.x.l = op_readstack();
|
||||
if(regs.p.x) {
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
return;
|
||||
}
|
||||
last_cycle();
|
||||
regs.x.h = op_readstack();
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
|
||||
void sCPU::op_ply() {
|
||||
op_io();
|
||||
op_io();
|
||||
if(regs.p.x)last_cycle();
|
||||
regs.y.l = op_readstack();
|
||||
if(regs.p.x) {
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
return;
|
||||
}
|
||||
last_cycle();
|
||||
regs.y.h = op_readstack();
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
|
||||
void sCPU::op_pld() {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.d.l = op_readstackn();
|
||||
last_cycle();
|
||||
regs.d.h = op_readstackn();
|
||||
regs.p.n = !!(regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void sCPU::op_plb() {
|
||||
op_io();
|
||||
op_io();
|
||||
last_cycle();
|
||||
regs.db = op_readstack();
|
||||
regs.p.n = !!(regs.db & 0x80);
|
||||
regs.p.z = (regs.db == 0);
|
||||
}
|
||||
|
||||
void sCPU::op_plp() {
|
||||
op_io();
|
||||
op_io();
|
||||
last_cycle();
|
||||
regs.p = op_readstack();
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_pea() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_writestackn(aa.h);
|
||||
last_cycle();
|
||||
op_writestackn(aa.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void sCPU::op_pei() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
op_writestackn(aa.h);
|
||||
last_cycle();
|
||||
op_writestackn(aa.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void sCPU::op_per() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.w = regs.pc.d + (int16)aa.w;
|
||||
op_writestackn(rd.h);
|
||||
last_cycle();
|
||||
op_writestackn(rd.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,163 @@
|
||||
bcc(0x90, !regs.p.c),
|
||||
bcs(0xb0, regs.p.c),
|
||||
bne(0xd0, !regs.p.z),
|
||||
beq(0xf0, regs.p.z),
|
||||
bpl(0x10, !regs.p.n),
|
||||
bmi(0x30, regs.p.n),
|
||||
bvc(0x50, !regs.p.v),
|
||||
bvs(0x70, regs.p.v) {
|
||||
1:if(!$1)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if($1) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
end;
|
||||
}
|
||||
2:op_io_cond6(aa.w);
|
||||
3:last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
bra(0x80) {
|
||||
1:rd.l = op_readpc();
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
2:op_io_cond6(aa.w);
|
||||
3:last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
brl(0x82) {
|
||||
1:rd.l = op_readpc();
|
||||
2:rd.h = op_readpc();
|
||||
3:last_cycle();
|
||||
op_io();
|
||||
regs.pc.w = regs.pc.d + (int16)rd.w;
|
||||
}
|
||||
|
||||
jmp_addr(0x4c) {
|
||||
1:rd.l = op_readpc();
|
||||
2:last_cycle();
|
||||
rd.h = op_readpc();
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
jmp_long(0x5c) {
|
||||
1:rd.l = op_readpc();
|
||||
2:rd.h = op_readpc();
|
||||
3:last_cycle();
|
||||
rd.b = op_readpc();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
|
||||
jmp_iaddr(0x6c) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:rd.l = op_readaddr(aa.w);
|
||||
4:last_cycle();
|
||||
rd.h = op_readaddr(aa.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
jmp_iaddrx(0x7c) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io();
|
||||
4:rd.l = op_readpbr(aa.w + regs.x.w);
|
||||
5:last_cycle();
|
||||
rd.h = op_readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
jmp_iladdr(0xdc) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:rd.l = op_readaddr(aa.w);
|
||||
4:rd.h = op_readaddr(aa.w + 1);
|
||||
5:last_cycle();
|
||||
rd.b = op_readaddr(aa.w + 2);
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
|
||||
jsr_addr(0x20) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io();
|
||||
4:regs.pc.w--;
|
||||
op_writestack(regs.pc.h);
|
||||
5:last_cycle();
|
||||
op_writestack(regs.pc.l);
|
||||
regs.pc.w = aa.w;
|
||||
}
|
||||
|
||||
jsr_long(0x22) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_writestackn(regs.pc.b);
|
||||
4:op_io();
|
||||
5:aa.b = op_readpc();
|
||||
6:regs.pc.w--;
|
||||
op_writestackn(regs.pc.h);
|
||||
7:last_cycle();
|
||||
op_writestackn(regs.pc.l);
|
||||
regs.pc.d = aa.d & 0xffffff;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
jsr_iaddrx(0xfc) {
|
||||
1:aa.l = op_readpc();
|
||||
2:op_writestackn(regs.pc.h);
|
||||
3:op_writestackn(regs.pc.l);
|
||||
4:aa.h = op_readpc();
|
||||
5:op_io();
|
||||
6:rd.l = op_readpbr(aa.w + regs.x.w);
|
||||
7:last_cycle();
|
||||
rd.h = op_readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
rti(0x40) {
|
||||
1:op_io();
|
||||
2:op_io();
|
||||
3:regs.p = op_readstack();
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
4:rd.l = op_readstack();
|
||||
5:if(regs.e)last_cycle();
|
||||
rd.h = op_readstack();
|
||||
if(regs.e) {
|
||||
regs.pc.w = rd.w;
|
||||
end;
|
||||
}
|
||||
6:last_cycle();
|
||||
rd.b = op_readstack();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
|
||||
rts(0x60) {
|
||||
1:op_io();
|
||||
2:op_io();
|
||||
3:rd.l = op_readstack();
|
||||
4:rd.h = op_readstack();
|
||||
5:last_cycle();
|
||||
op_io();
|
||||
regs.pc.w = rd.w;
|
||||
regs.pc.w++;
|
||||
}
|
||||
|
||||
rtl(0x6b) {
|
||||
1:op_io();
|
||||
2:op_io();
|
||||
3:rd.l = op_readstackn();
|
||||
4:rd.h = op_readstackn();
|
||||
5:last_cycle();
|
||||
rd.b = op_readstackn();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
regs.pc.w++;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
void sCPU::op_bcc() {
|
||||
if(!!regs.p.c)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(!regs.p.c) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
void sCPU::op_bcs() {
|
||||
if(!regs.p.c)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(regs.p.c) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
void sCPU::op_bne() {
|
||||
if(!!regs.p.z)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(!regs.p.z) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
void sCPU::op_beq() {
|
||||
if(!regs.p.z)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(regs.p.z) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
void sCPU::op_bpl() {
|
||||
if(!!regs.p.n)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(!regs.p.n) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
void sCPU::op_bmi() {
|
||||
if(!regs.p.n)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(regs.p.n) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
void sCPU::op_bvc() {
|
||||
if(!!regs.p.v)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(!regs.p.v) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
void sCPU::op_bvs() {
|
||||
if(!regs.p.v)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(regs.p.v) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
void sCPU::op_bra() {
|
||||
rd.l = op_readpc();
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
void sCPU::op_brl() {
|
||||
rd.l = op_readpc();
|
||||
rd.h = op_readpc();
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.pc.w = regs.pc.d + (int16)rd.w;
|
||||
}
|
||||
|
||||
void sCPU::op_jmp_addr() {
|
||||
rd.l = op_readpc();
|
||||
last_cycle();
|
||||
rd.h = op_readpc();
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
void sCPU::op_jmp_long() {
|
||||
rd.l = op_readpc();
|
||||
rd.h = op_readpc();
|
||||
last_cycle();
|
||||
rd.b = op_readpc();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
|
||||
void sCPU::op_jmp_iaddr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readaddr(aa.w);
|
||||
last_cycle();
|
||||
rd.h = op_readaddr(aa.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
void sCPU::op_jmp_iaddrx() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readpbr(aa.w + regs.x.w);
|
||||
last_cycle();
|
||||
rd.h = op_readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
void sCPU::op_jmp_iladdr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readaddr(aa.w);
|
||||
rd.h = op_readaddr(aa.w + 1);
|
||||
last_cycle();
|
||||
rd.b = op_readaddr(aa.w + 2);
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
|
||||
void sCPU::op_jsr_addr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
regs.pc.w--;
|
||||
op_writestack(regs.pc.h);
|
||||
last_cycle();
|
||||
op_writestack(regs.pc.l);
|
||||
regs.pc.w = aa.w;
|
||||
}
|
||||
|
||||
void sCPU::op_jsr_long() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_writestackn(regs.pc.b);
|
||||
op_io();
|
||||
aa.b = op_readpc();
|
||||
regs.pc.w--;
|
||||
op_writestackn(regs.pc.h);
|
||||
last_cycle();
|
||||
op_writestackn(regs.pc.l);
|
||||
regs.pc.d = aa.d & 0xffffff;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void sCPU::op_jsr_iaddrx() {
|
||||
aa.l = op_readpc();
|
||||
op_writestackn(regs.pc.h);
|
||||
op_writestackn(regs.pc.l);
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readpbr(aa.w + regs.x.w);
|
||||
last_cycle();
|
||||
rd.h = op_readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void sCPU::op_rti() {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.p = op_readstack();
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
rd.l = op_readstack();
|
||||
if(regs.e)last_cycle();
|
||||
rd.h = op_readstack();
|
||||
if(regs.e) {
|
||||
regs.pc.w = rd.w;
|
||||
return;
|
||||
}
|
||||
last_cycle();
|
||||
rd.b = op_readstack();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
|
||||
void sCPU::op_rts() {
|
||||
op_io();
|
||||
op_io();
|
||||
rd.l = op_readstack();
|
||||
rd.h = op_readstack();
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.pc.w = rd.w;
|
||||
regs.pc.w++;
|
||||
}
|
||||
|
||||
void sCPU::op_rtl() {
|
||||
op_io();
|
||||
op_io();
|
||||
rd.l = op_readstackn();
|
||||
rd.h = op_readstackn();
|
||||
last_cycle();
|
||||
rd.b = op_readstackn();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
regs.pc.w++;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,317 @@
|
||||
adc_const(0x69, adc, regs.p.m),
|
||||
and_const(0x29, and, regs.p.m),
|
||||
cmp_const(0xc9, cmp, regs.p.m),
|
||||
cpx_const(0xe0, cpx, regs.p.x),
|
||||
cpy_const(0xc0, cpy, regs.p.x),
|
||||
eor_const(0x49, eor, regs.p.m),
|
||||
lda_const(0xa9, lda, regs.p.m),
|
||||
ldx_const(0xa2, ldx, regs.p.x),
|
||||
ldy_const(0xa0, ldy, regs.p.x),
|
||||
ora_const(0x09, ora, regs.p.m),
|
||||
sbc_const(0xe9, sbc, regs.p.m) {
|
||||
1:if($2)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if($2) { op_$1_b(); end; }
|
||||
2:last_cycle();
|
||||
rd.h = op_readpc();
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_addr(0x6d, adc, regs.p.m),
|
||||
and_addr(0x2d, and, regs.p.m),
|
||||
bit_addr(0x2c, bit, regs.p.m),
|
||||
cmp_addr(0xcd, cmp, regs.p.m),
|
||||
cpx_addr(0xec, cpx, regs.p.x),
|
||||
cpy_addr(0xcc, cpy, regs.p.x),
|
||||
eor_addr(0x4d, eor, regs.p.m),
|
||||
lda_addr(0xad, lda, regs.p.m),
|
||||
ldx_addr(0xae, ldx, regs.p.x),
|
||||
ldy_addr(0xac, ldy, regs.p.x),
|
||||
ora_addr(0x0d, ora, regs.p.m),
|
||||
sbc_addr(0xed, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:if($2)last_cycle();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
4:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_addrx(0x7d, adc, regs.p.m),
|
||||
and_addrx(0x3d, and, regs.p.m),
|
||||
bit_addrx(0x3c, bit, regs.p.m),
|
||||
cmp_addrx(0xdd, cmp, regs.p.m),
|
||||
eor_addrx(0x5d, eor, regs.p.m),
|
||||
lda_addrx(0xbd, lda, regs.p.m),
|
||||
ldy_addrx(0xbc, ldy, regs.p.x),
|
||||
ora_addrx(0x1d, ora, regs.p.m),
|
||||
sbc_addrx(0xfd, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io_cond4(aa.w, aa.w + regs.x.w);
|
||||
4:if($2)last_cycle();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
5:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_addry(0x79, adc, regs.p.m),
|
||||
and_addry(0x39, and, regs.p.m),
|
||||
cmp_addry(0xd9, cmp, regs.p.m),
|
||||
eor_addry(0x59, eor, regs.p.m),
|
||||
lda_addry(0xb9, lda, regs.p.m),
|
||||
ldx_addry(0xbe, ldx, regs.p.x),
|
||||
ora_addry(0x19, ora, regs.p.m),
|
||||
sbc_addry(0xf9, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io_cond4(aa.w, aa.w + regs.y.w);
|
||||
4:if($2)last_cycle();
|
||||
rd.l = op_readdbr(aa.w + regs.y.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
5:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + regs.y.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_long(0x6f, adc, regs.p.m),
|
||||
and_long(0x2f, and, regs.p.m),
|
||||
cmp_long(0xcf, cmp, regs.p.m),
|
||||
eor_long(0x4f, eor, regs.p.m),
|
||||
lda_long(0xaf, lda, regs.p.m),
|
||||
ora_long(0x0f, ora, regs.p.m),
|
||||
sbc_long(0xef, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:aa.b = op_readpc();
|
||||
4:if($2)last_cycle();
|
||||
rd.l = op_readlong(aa.d);
|
||||
if($2) { op_$1_b(); end; }
|
||||
5:last_cycle();
|
||||
rd.h = op_readlong(aa.d + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_longx(0x7f, adc, regs.p.m),
|
||||
and_longx(0x3f, and, regs.p.m),
|
||||
cmp_longx(0xdf, cmp, regs.p.m),
|
||||
eor_longx(0x5f, eor, regs.p.m),
|
||||
lda_longx(0xbf, lda, regs.p.m),
|
||||
ora_longx(0x1f, ora, regs.p.m),
|
||||
sbc_longx(0xff, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:aa.b = op_readpc();
|
||||
4:if($2)last_cycle();
|
||||
rd.l = op_readlong(aa.d + regs.x.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
5:last_cycle();
|
||||
rd.h = op_readlong(aa.d + regs.x.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_dp(0x65, adc, regs.p.m),
|
||||
and_dp(0x25, and, regs.p.m),
|
||||
bit_dp(0x24, bit, regs.p.m),
|
||||
cmp_dp(0xc5, cmp, regs.p.m),
|
||||
cpx_dp(0xe4, cpx, regs.p.x),
|
||||
cpy_dp(0xc4, cpy, regs.p.x),
|
||||
eor_dp(0x45, eor, regs.p.m),
|
||||
lda_dp(0xa5, lda, regs.p.m),
|
||||
ldx_dp(0xa6, ldx, regs.p.x),
|
||||
ldy_dp(0xa4, ldy, regs.p.x),
|
||||
ora_dp(0x05, ora, regs.p.m),
|
||||
sbc_dp(0xe5, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:if($2)last_cycle();
|
||||
rd.l = op_readdp(dp);
|
||||
if($2) { op_$1_b(); end; }
|
||||
4:last_cycle();
|
||||
rd.h = op_readdp(dp + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_dpx(0x75, adc, regs.p.m),
|
||||
and_dpx(0x35, and, regs.p.m),
|
||||
bit_dpx(0x34, bit, regs.p.m),
|
||||
cmp_dpx(0xd5, cmp, regs.p.m),
|
||||
eor_dpx(0x55, eor, regs.p.m),
|
||||
lda_dpx(0xb5, lda, regs.p.m),
|
||||
ldy_dpx(0xb4, ldy, regs.p.x),
|
||||
ora_dpx(0x15, ora, regs.p.m),
|
||||
sbc_dpx(0xf5, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:op_io();
|
||||
4:if($2)last_cycle();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
5:last_cycle();
|
||||
rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
ldx_dpy(0xb6, ldx, regs.p.x) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:op_io();
|
||||
4:if($2)last_cycle();
|
||||
rd.l = op_readdp(dp + regs.y.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
5:last_cycle();
|
||||
rd.h = op_readdp(dp + regs.y.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_idp(0x72, adc, regs.p.m),
|
||||
and_idp(0x32, and, regs.p.m),
|
||||
cmp_idp(0xd2, cmp, regs.p.m),
|
||||
eor_idp(0x52, eor, regs.p.m),
|
||||
lda_idp(0xb2, lda, regs.p.m),
|
||||
ora_idp(0x12, ora, regs.p.m),
|
||||
sbc_idp(0xf2, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:if($2)last_cycle();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
6:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_idpx(0x61, adc, regs.p.m),
|
||||
and_idpx(0x21, and, regs.p.m),
|
||||
cmp_idpx(0xc1, cmp, regs.p.m),
|
||||
eor_idpx(0x41, eor, regs.p.m),
|
||||
lda_idpx(0xa1, lda, regs.p.m),
|
||||
ora_idpx(0x01, ora, regs.p.m),
|
||||
sbc_idpx(0xe1, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:op_io();
|
||||
4:aa.l = op_readdp(dp + regs.x.w);
|
||||
5:aa.h = op_readdp(dp + regs.x.w + 1);
|
||||
6:if($2)last_cycle();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
7:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_idpy(0x71, adc, regs.p.m),
|
||||
and_idpy(0x31, and, regs.p.m),
|
||||
cmp_idpy(0xd1, cmp, regs.p.m),
|
||||
eor_idpy(0x51, eor, regs.p.m),
|
||||
lda_idpy(0xb1, lda, regs.p.m),
|
||||
ora_idpy(0x11, ora, regs.p.m),
|
||||
sbc_idpy(0xf1, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:op_io_cond4(aa.w, aa.w + regs.y.w);
|
||||
6:if($2)last_cycle();
|
||||
rd.l = op_readdbr(aa.w + regs.y.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
7:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + regs.y.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_ildp(0x67, adc, regs.p.m),
|
||||
and_ildp(0x27, and, regs.p.m),
|
||||
cmp_ildp(0xc7, cmp, regs.p.m),
|
||||
eor_ildp(0x47, eor, regs.p.m),
|
||||
lda_ildp(0xa7, lda, regs.p.m),
|
||||
ora_ildp(0x07, ora, regs.p.m),
|
||||
sbc_ildp(0xe7, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:aa.b = op_readdp(dp + 2);
|
||||
6:if($2)last_cycle();
|
||||
rd.l = op_readlong(aa.d);
|
||||
if($2) { op_$1_b(); end; }
|
||||
7:last_cycle();
|
||||
rd.h = op_readlong(aa.d + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_ildpy(0x77, adc, regs.p.m),
|
||||
and_ildpy(0x37, and, regs.p.m),
|
||||
cmp_ildpy(0xd7, cmp, regs.p.m),
|
||||
eor_ildpy(0x57, eor, regs.p.m),
|
||||
lda_ildpy(0xb7, lda, regs.p.m),
|
||||
ora_ildpy(0x17, ora, regs.p.m),
|
||||
sbc_ildpy(0xf7, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:aa.b = op_readdp(dp + 2);
|
||||
6:if($2)last_cycle();
|
||||
rd.l = op_readlong(aa.d + regs.y.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
7:last_cycle();
|
||||
rd.h = op_readlong(aa.d + regs.y.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_sr(0x63, adc, regs.p.m),
|
||||
and_sr(0x23, and, regs.p.m),
|
||||
cmp_sr(0xc3, cmp, regs.p.m),
|
||||
eor_sr(0x43, eor, regs.p.m),
|
||||
lda_sr(0xa3, lda, regs.p.m),
|
||||
ora_sr(0x03, ora, regs.p.m),
|
||||
sbc_sr(0xe3, sbc, regs.p.m) {
|
||||
1:sp = op_readpc();
|
||||
2:op_io();
|
||||
3:if($2)last_cycle();
|
||||
rd.l = op_readsp(sp);
|
||||
if($2) { op_$1_b(); end; }
|
||||
4:last_cycle();
|
||||
rd.h = op_readsp(sp + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_isry(0x73, adc),
|
||||
and_isry(0x33, and),
|
||||
cmp_isry(0xd3, cmp),
|
||||
eor_isry(0x53, eor),
|
||||
lda_isry(0xb3, lda),
|
||||
ora_isry(0x13, ora),
|
||||
sbc_isry(0xf3, sbc) {
|
||||
1:sp = op_readpc();
|
||||
2:op_io();
|
||||
3:aa.l = op_readsp(sp);
|
||||
4:aa.h = op_readsp(sp + 1);
|
||||
5:op_io();
|
||||
6:if(regs.p.m)last_cycle();
|
||||
rd.l = op_readdbr(aa.w + regs.y.w);
|
||||
if(regs.p.m) { op_$1_b(); end; }
|
||||
7:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + regs.y.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
bit_const(0x89) {
|
||||
1:if(regs.p.m)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(regs.p.m) {
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
end;
|
||||
}
|
||||
2:last_cycle();
|
||||
rd.h = op_readpc();
|
||||
regs.p.z = ((rd.w & regs.a.w) == 0);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,181 @@
|
||||
inc(0x1a, regs.p.m, a),
|
||||
inx(0xe8, regs.p.x, x),
|
||||
iny(0xc8, regs.p.x, y) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
if($1) {
|
||||
regs.$2.l++;
|
||||
regs.p.n = !!(regs.$2.l & 0x80);
|
||||
regs.p.z = (regs.$2.l == 0);
|
||||
} else {
|
||||
regs.$2.w++;
|
||||
regs.p.n = !!(regs.$2.w & 0x8000);
|
||||
regs.p.z = (regs.$2.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
dec(0x3a, regs.p.m, a),
|
||||
dex(0xca, regs.p.x, x),
|
||||
dey(0x88, regs.p.x, y) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
if($1) {
|
||||
regs.$2.l--;
|
||||
regs.p.n = !!(regs.$2.l & 0x80);
|
||||
regs.p.z = (regs.$2.l == 0);
|
||||
} else {
|
||||
regs.$2.w--;
|
||||
regs.p.n = !!(regs.$2.w & 0x8000);
|
||||
regs.p.z = (regs.$2.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
asl(0x0a) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
if(regs.p.m) {
|
||||
regs.p.c = !!(regs.a.l & 0x80);
|
||||
regs.a.l <<= 1;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = !!(regs.a.w & 0x8000);
|
||||
regs.a.w <<= 1;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
lsr(0x4a) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
if(regs.p.m) {
|
||||
regs.p.c = regs.a.l & 1;
|
||||
regs.a.l >>= 1;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = regs.a.w & 1;
|
||||
regs.a.w >>= 1;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
rol(0x2a) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
uint16 c = regs.p.c;
|
||||
if(regs.p.m) {
|
||||
regs.p.c = !!(regs.a.l & 0x80);
|
||||
regs.a.l <<= 1;
|
||||
regs.a.l |= c;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = !!(regs.a.w & 0x8000);
|
||||
regs.a.w <<= 1;
|
||||
regs.a.w |= c;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
ror(0x6a) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
uint16 c;
|
||||
if(regs.p.m) {
|
||||
c = (regs.p.c)?0x80:0;
|
||||
regs.p.c = regs.a.l & 1;
|
||||
regs.a.l >>= 1;
|
||||
regs.a.l |= c;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
c = (regs.p.c)?0x8000:0;
|
||||
regs.p.c = regs.a.w & 1;
|
||||
regs.a.w >>= 1;
|
||||
regs.a.w |= c;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
inc_addr(0xee, inc),
|
||||
dec_addr(0xce, dec),
|
||||
asl_addr(0x0e, asl),
|
||||
lsr_addr(0x4e, lsr),
|
||||
rol_addr(0x2e, rol),
|
||||
ror_addr(0x6e, ror),
|
||||
trb_addr(0x1c, trb),
|
||||
tsb_addr(0x0c, tsb) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:rd.l = op_readdbr(aa.w);
|
||||
4:if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
5:op_io();
|
||||
if(regs.p.m) { op_$1_b(); }
|
||||
else { op_$1_w();
|
||||
6:op_writedbr(aa.w + 1, rd.h); }
|
||||
7:last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
}
|
||||
|
||||
inc_addrx(0xfe, inc),
|
||||
dec_addrx(0xde, dec),
|
||||
asl_addrx(0x1e, asl),
|
||||
lsr_addrx(0x5e, lsr),
|
||||
rol_addrx(0x3e, rol),
|
||||
ror_addrx(0x7e, ror) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io();
|
||||
4:rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
5:if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
6:op_io();
|
||||
if(regs.p.m) { op_$1_b(); }
|
||||
else { op_$1_w();
|
||||
7:op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
8:last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
inc_dp(0xe6, inc),
|
||||
dec_dp(0xc6, dec),
|
||||
asl_dp(0x06, asl),
|
||||
lsr_dp(0x46, lsr),
|
||||
rol_dp(0x26, rol),
|
||||
ror_dp(0x66, ror),
|
||||
trb_dp(0x14, trb),
|
||||
tsb_dp(0x04, tsb) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:rd.l = op_readdp(dp);
|
||||
4:if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
5:op_io();
|
||||
if(regs.p.m) { op_$1_b(); }
|
||||
else { op_$1_w();
|
||||
6:op_writedp(dp + 1, rd.h); }
|
||||
7:last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
}
|
||||
|
||||
inc_dpx(0xf6, inc),
|
||||
dec_dpx(0xd6, dec),
|
||||
asl_dpx(0x16, asl),
|
||||
lsr_dpx(0x56, lsr),
|
||||
rol_dpx(0x36, rol),
|
||||
ror_dpx(0x76, ror) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:op_io();
|
||||
4:rd.l = op_readdp(dp + regs.x.w);
|
||||
5:if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
6:op_io();
|
||||
if(regs.p.m) { op_$1_b(); }
|
||||
else { op_$1_w();
|
||||
7:op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
8:last_cycle();
|
||||
op_writedp(dp + regs.x.w, rd.l);
|
||||
}
|
||||
@@ -0,0 +1,532 @@
|
||||
void sCPU::op_inc() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.m) {
|
||||
regs.a.l++;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.a.w++;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_inx() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l++;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w++;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_iny() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.x) {
|
||||
regs.y.l++;
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
} else {
|
||||
regs.y.w++;
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_dec() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.m) {
|
||||
regs.a.l--;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.a.w--;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_dex() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l--;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w--;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_dey() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.x) {
|
||||
regs.y.l--;
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
} else {
|
||||
regs.y.w--;
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_asl() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.m) {
|
||||
regs.p.c = !!(regs.a.l & 0x80);
|
||||
regs.a.l <<= 1;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = !!(regs.a.w & 0x8000);
|
||||
regs.a.w <<= 1;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_lsr() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.p.m) {
|
||||
regs.p.c = regs.a.l & 1;
|
||||
regs.a.l >>= 1;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = regs.a.w & 1;
|
||||
regs.a.w >>= 1;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_rol() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
uint16 c = regs.p.c;
|
||||
if(regs.p.m) {
|
||||
regs.p.c = !!(regs.a.l & 0x80);
|
||||
regs.a.l <<= 1;
|
||||
regs.a.l |= c;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = !!(regs.a.w & 0x8000);
|
||||
regs.a.w <<= 1;
|
||||
regs.a.w |= c;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_ror() {
|
||||
last_cycle();
|
||||
op_io();
|
||||
uint16 c;
|
||||
if(regs.p.m) {
|
||||
c = (regs.p.c)?0x80:0;
|
||||
regs.p.c = regs.a.l & 1;
|
||||
regs.a.l >>= 1;
|
||||
regs.a.l |= c;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
c = (regs.p.c)?0x8000:0;
|
||||
regs.p.c = regs.a.w & 1;
|
||||
regs.a.w >>= 1;
|
||||
regs.a.w |= c;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_inc_addr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_inc_b(); }
|
||||
else { op_inc_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_dec_addr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_dec_b(); }
|
||||
else { op_dec_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_asl_addr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_asl_b(); }
|
||||
else { op_asl_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_lsr_addr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_lsr_b(); }
|
||||
else { op_lsr_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_rol_addr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_rol_b(); }
|
||||
else { op_rol_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_ror_addr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_ror_b(); }
|
||||
else { op_ror_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_trb_addr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_trb_b(); }
|
||||
else { op_trb_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_tsb_addr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_tsb_b(); }
|
||||
else { op_tsb_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_inc_addrx() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_inc_b(); }
|
||||
else { op_inc_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_dec_addrx() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_dec_b(); }
|
||||
else { op_dec_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_asl_addrx() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_asl_b(); }
|
||||
else { op_asl_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_lsr_addrx() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_lsr_b(); }
|
||||
else { op_lsr_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_rol_addrx() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_rol_b(); }
|
||||
else { op_rol_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_ror_addrx() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_ror_b(); }
|
||||
else { op_ror_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_inc_dp() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_inc_b(); }
|
||||
else { op_inc_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_dec_dp() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_dec_b(); }
|
||||
else { op_dec_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_asl_dp() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_asl_b(); }
|
||||
else { op_asl_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_lsr_dp() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_lsr_b(); }
|
||||
else { op_lsr_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_rol_dp() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_rol_b(); }
|
||||
else { op_rol_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_ror_dp() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_ror_b(); }
|
||||
else { op_ror_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_trb_dp() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_trb_b(); }
|
||||
else { op_trb_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_tsb_dp() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_tsb_b(); }
|
||||
else { op_tsb_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_inc_dpx() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_inc_b(); }
|
||||
else { op_inc_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_dec_dpx() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_dec_b(); }
|
||||
else { op_dec_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_asl_dpx() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_asl_b(); }
|
||||
else { op_asl_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_lsr_dpx() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_lsr_b(); }
|
||||
else { op_lsr_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_rol_dpx() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_rol_b(); }
|
||||
else { op_rol_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
void sCPU::op_ror_dpx() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_ror_b(); }
|
||||
else { op_ror_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
sta_addr(0x8d, regs.p.m, regs.a.w),
|
||||
stx_addr(0x8e, regs.p.x, regs.x.w),
|
||||
sty_addr(0x8c, regs.p.x, regs.y.w),
|
||||
stz_addr(0x9c, regs.p.m, 0x0000) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:if($1)last_cycle();
|
||||
op_writedbr(aa.w, $2);
|
||||
if($1)end;
|
||||
4:last_cycle();
|
||||
op_writedbr(aa.w + 1, $2 >> 8);
|
||||
}
|
||||
|
||||
sta_addrx(0x9d, regs.p.m, regs.a.w),
|
||||
stz_addrx(0x9e, regs.p.m, 0x0000) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io();
|
||||
4:if($1)last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, $2);
|
||||
if($1)end;
|
||||
5:last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w + 1, $2 >> 8);
|
||||
}
|
||||
|
||||
sta_addry(0x99) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io();
|
||||
4:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
5:last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_long(0x8f) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:aa.b = op_readpc();
|
||||
4:if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
5:last_cycle();
|
||||
op_writelong(aa.d + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_longx(0x9f) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:aa.b = op_readpc();
|
||||
4:if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d + regs.x.w, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
5:last_cycle();
|
||||
op_writelong(aa.d + regs.x.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_dp(0x85, regs.p.m, regs.a.w),
|
||||
stx_dp(0x86, regs.p.x, regs.x.w),
|
||||
sty_dp(0x84, regs.p.x, regs.y.w),
|
||||
stz_dp(0x64, regs.p.m, 0x0000) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:if($1)last_cycle();
|
||||
op_writedp(dp, $2);
|
||||
if($1)end;
|
||||
4:last_cycle();
|
||||
op_writedp(dp + 1, $2 >> 8);
|
||||
}
|
||||
|
||||
sta_dpx(0x95, regs.p.m, regs.a.w),
|
||||
sty_dpx(0x94, regs.p.x, regs.y.w),
|
||||
stz_dpx(0x74, regs.p.m, 0x0000) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:op_io();
|
||||
4:if($1)last_cycle();
|
||||
op_writedp(dp + regs.x.w, $2);
|
||||
if($1)end;
|
||||
5:last_cycle();
|
||||
op_writedp(dp + regs.x.w + 1, $2 >> 8);
|
||||
}
|
||||
|
||||
stx_dpy(0x96) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:op_io();
|
||||
4:if(regs.p.x)last_cycle();
|
||||
op_writedp(dp + regs.y.w, regs.x.l);
|
||||
if(regs.p.x)end;
|
||||
5:last_cycle();
|
||||
op_writedp(dp + regs.y.w + 1, regs.x.h);
|
||||
}
|
||||
|
||||
sta_idp(0x92) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
6:last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_ildp(0x87) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:aa.b = op_readdp(dp + 2);
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writelong(aa.d + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_idpx(0x81) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:op_io();
|
||||
4:aa.l = op_readdp(dp + regs.x.w);
|
||||
5:aa.h = op_readdp(dp + regs.x.w + 1);
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_idpy(0x91) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:op_io();
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_ildpy(0x97) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:aa.b = op_readdp(dp + 2);
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_sr(0x83) {
|
||||
1:sp = op_readpc();
|
||||
2:op_io();
|
||||
3:if(regs.p.m)last_cycle();
|
||||
op_writesp(sp, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
4:last_cycle();
|
||||
op_writesp(sp + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_isry(0x93) {
|
||||
1:sp = op_readpc();
|
||||
2:op_io();
|
||||
3:aa.l = op_readsp(sp);
|
||||
4:aa.h = op_readsp(sp + 1);
|
||||
5:op_io();
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
@@ -0,0 +1,266 @@
|
||||
void sCPU::op_sta_addr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.w);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.w >> 8);
|
||||
}
|
||||
|
||||
void sCPU::op_stx_addr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedbr(aa.w, regs.x.w);
|
||||
if(regs.p.x)return;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.x.w >> 8);
|
||||
}
|
||||
|
||||
void sCPU::op_sty_addr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedbr(aa.w, regs.y.w);
|
||||
if(regs.p.x)return;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.y.w >> 8);
|
||||
}
|
||||
|
||||
void sCPU::op_stz_addr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, 0x0000);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, 0x0000 >> 8);
|
||||
}
|
||||
|
||||
void sCPU::op_sta_addrx() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, regs.a.w);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w + 1, regs.a.w >> 8);
|
||||
}
|
||||
|
||||
void sCPU::op_stz_addrx() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, 0x0000);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w + 1, 0x0000 >> 8);
|
||||
}
|
||||
|
||||
void sCPU::op_sta_addry() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
void sCPU::op_sta_long() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
aa.b = op_readpc();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d, regs.a.l);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writelong(aa.d + 1, regs.a.h);
|
||||
}
|
||||
|
||||
void sCPU::op_sta_longx() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
aa.b = op_readpc();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d + regs.x.w, regs.a.l);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writelong(aa.d + regs.x.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
void sCPU::op_sta_dp() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedp(dp, regs.a.w);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, regs.a.w >> 8);
|
||||
}
|
||||
|
||||
void sCPU::op_stx_dp() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedp(dp, regs.x.w);
|
||||
if(regs.p.x)return;
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, regs.x.w >> 8);
|
||||
}
|
||||
|
||||
void sCPU::op_sty_dp() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedp(dp, regs.y.w);
|
||||
if(regs.p.x)return;
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, regs.y.w >> 8);
|
||||
}
|
||||
|
||||
void sCPU::op_stz_dp() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedp(dp, 0x0000);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, 0x0000 >> 8);
|
||||
}
|
||||
|
||||
void sCPU::op_sta_dpx() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedp(dp + regs.x.w, regs.a.w);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w + 1, regs.a.w >> 8);
|
||||
}
|
||||
|
||||
void sCPU::op_sty_dpx() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedp(dp + regs.x.w, regs.y.w);
|
||||
if(regs.p.x)return;
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w + 1, regs.y.w >> 8);
|
||||
}
|
||||
|
||||
void sCPU::op_stz_dpx() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedp(dp + regs.x.w, 0x0000);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w + 1, 0x0000 >> 8);
|
||||
}
|
||||
|
||||
void sCPU::op_stx_dpy() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedp(dp + regs.y.w, regs.x.l);
|
||||
if(regs.p.x)return;
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.y.w + 1, regs.x.h);
|
||||
}
|
||||
|
||||
void sCPU::op_sta_idp() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.l);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
void sCPU::op_sta_ildp() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
aa.b = op_readdp(dp + 2);
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d, regs.a.l);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writelong(aa.d + 1, regs.a.h);
|
||||
}
|
||||
|
||||
void sCPU::op_sta_idpx() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
aa.l = op_readdp(dp + regs.x.w);
|
||||
aa.h = op_readdp(dp + regs.x.w + 1);
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.l);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
void sCPU::op_sta_idpy() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
void sCPU::op_sta_ildpy() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
aa.b = op_readdp(dp + 2);
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
void sCPU::op_sta_sr() {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writesp(sp, regs.a.l);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writesp(sp + 1, regs.a.h);
|
||||
}
|
||||
|
||||
void sCPU::op_sta_isry() {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
aa.l = op_readsp(sp);
|
||||
aa.h = op_readsp(sp + 1);
|
||||
op_io();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)return;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
//op_read
|
||||
inline void sCPU::op_adc_b() {
|
||||
int32 r = regs.a.l + rd.l + regs.p.c;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.l ) & 15;
|
||||
uint8 n1 = (regs.a.l >> 4) & 15;
|
||||
n0 += ((rd.l) & 15) + regs.p.c;
|
||||
if(n0 > 9) {
|
||||
n0 -= 10;
|
||||
n0 &= 15;
|
||||
n1++;
|
||||
}
|
||||
n1 += ((rd.l >> 4) & 15);
|
||||
if(n1 > 9) {
|
||||
n1 -= 10;
|
||||
n1 &= 15;
|
||||
regs.p.c = 1;
|
||||
} else {
|
||||
regs.p.c = 0;
|
||||
}
|
||||
r = (n1 << 4) | (n0);
|
||||
} else {
|
||||
r = regs.a.l + rd.l + regs.p.c;
|
||||
regs.p.c = (r > 0xff);
|
||||
}
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.v = !!(~(regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.a.l = r;
|
||||
}
|
||||
|
||||
inline void sCPU::op_adc_w() {
|
||||
int32 r;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.w ) & 15;
|
||||
uint8 n1 = (regs.a.w >> 4) & 15;
|
||||
uint8 n2 = (regs.a.w >> 8) & 15;
|
||||
uint8 n3 = (regs.a.w >> 12) & 15;
|
||||
n0 += ((rd.w) & 15) + regs.p.c;
|
||||
if(n0 > 9) {
|
||||
n0 -= 10;
|
||||
n0 &= 15;
|
||||
n1++;
|
||||
}
|
||||
n1 += ((rd.w >> 4) & 15);
|
||||
if(n1 > 9) {
|
||||
n1 -= 10;
|
||||
n1 &= 15;
|
||||
n2++;
|
||||
}
|
||||
n2 += ((rd.w >> 8) & 15);
|
||||
if(n2 > 9) {
|
||||
n2 -= 10;
|
||||
n2 &= 15;
|
||||
n3++;
|
||||
}
|
||||
n3 += ((rd.w >> 12) & 15);
|
||||
if(n3 > 9) {
|
||||
n3 -= 10;
|
||||
n3 &= 15;
|
||||
regs.p.c = 1;
|
||||
} else {
|
||||
regs.p.c = 0;
|
||||
}
|
||||
r = (n3 << 12) | (n2 << 8) | (n1 << 4) | (n0);
|
||||
} else {
|
||||
r = regs.a.w + rd.w + regs.p.c;
|
||||
regs.p.c = (r > 0xffff);
|
||||
}
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.v = !!(~(regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.a.w = r;
|
||||
}
|
||||
|
||||
inline void sCPU::op_and_b() {
|
||||
regs.a.l &= rd.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_and_w() {
|
||||
regs.a.w &= rd.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_bit_b() {
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.v = !!(rd.l & 0x40);
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_bit_w() {
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.v = !!(rd.w & 0x4000);
|
||||
regs.p.z = ((rd.w & regs.a.w) == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_cmp_b() {
|
||||
int32 r = regs.a.l - rd.l;
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_cmp_w() {
|
||||
int32 r = regs.a.w - rd.w;
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_cpx_b() {
|
||||
int32 r = regs.x.l - rd.l;
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_cpx_w() {
|
||||
int32 r = regs.x.w - rd.w;
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_cpy_b() {
|
||||
int32 r = regs.y.l - rd.l;
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_cpy_w() {
|
||||
int32 r = regs.y.w - rd.w;
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_eor_b() {
|
||||
regs.a.l ^= rd.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_eor_w() {
|
||||
regs.a.w ^= rd.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_lda_b() {
|
||||
regs.a.l = rd.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_lda_w() {
|
||||
regs.a.w = rd.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_ldx_b() {
|
||||
regs.x.l = rd.l;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_ldx_w() {
|
||||
regs.x.w = rd.w;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_ldy_b() {
|
||||
regs.y.l = rd.l;
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_ldy_w() {
|
||||
regs.y.w = rd.w;
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_ora_b() {
|
||||
regs.a.l |= rd.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_ora_w() {
|
||||
regs.a.w |= rd.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_sbc_b() {
|
||||
int32 r;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.l ) & 15;
|
||||
uint8 n1 = (regs.a.l >> 4) & 15;
|
||||
n0 -= ((rd.l ) & 15) + !regs.p.c;
|
||||
n1 -= ((rd.l >> 4) & 15);
|
||||
if(n0 > 9) {
|
||||
n0 += 10;
|
||||
n1--;
|
||||
}
|
||||
if(n1 > 9) {
|
||||
n1 += 10;
|
||||
regs.p.c = 0;
|
||||
} else {
|
||||
regs.p.c = 1;
|
||||
}
|
||||
r = (n1 << 4) | (n0);
|
||||
} else {
|
||||
r = regs.a.l - rd.l - !regs.p.c;
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.v = !!((regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.a.l = r;
|
||||
}
|
||||
|
||||
inline void sCPU::op_sbc_w() {
|
||||
int32 r;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.w ) & 15;
|
||||
uint8 n1 = (regs.a.w >> 4) & 15;
|
||||
uint8 n2 = (regs.a.w >> 8) & 15;
|
||||
uint8 n3 = (regs.a.w >> 12) & 15;
|
||||
n0 -= ((rd.w ) & 15) + !regs.p.c;
|
||||
n1 -= ((rd.w >> 4) & 15);
|
||||
n2 -= ((rd.w >> 8) & 15);
|
||||
n3 -= ((rd.w >> 12) & 15);
|
||||
if(n0 > 9) {
|
||||
n0 += 10;
|
||||
n1--;
|
||||
}
|
||||
if(n1 > 9) {
|
||||
n1 += 10;
|
||||
n2--;
|
||||
}
|
||||
if(n2 > 9) {
|
||||
n2 += 10;
|
||||
n3--;
|
||||
}
|
||||
if(n3 > 9) {
|
||||
n3 += 10;
|
||||
regs.p.c = 0;
|
||||
} else {
|
||||
regs.p.c = 1;
|
||||
}
|
||||
r = (n3 << 12) | (n2 << 8) | (n1 << 4) | (n0);
|
||||
} else {
|
||||
r = regs.a.w - rd.w - !regs.p.c;
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.v = !!((regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.a.w = r;
|
||||
}
|
||||
|
||||
//op_rmw
|
||||
inline void sCPU::op_inc_b() {
|
||||
rd.l++;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_inc_w() {
|
||||
rd.w++;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_dec_b() {
|
||||
rd.l--;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_dec_w() {
|
||||
rd.w--;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_asl_b() {
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
rd.l <<= 1;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_asl_w() {
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
rd.w <<= 1;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_lsr_b() {
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l >>= 1;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_lsr_w() {
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w >>= 1;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_rol_b() {
|
||||
uint16 carry = (uint16)regs.p.c;
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
rd.l = (rd.l << 1) | carry;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_rol_w() {
|
||||
uint16 carry = (uint16)regs.p.c;
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
rd.w = (rd.w << 1) | carry;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_ror_b() {
|
||||
uint16 carry = (uint16)regs.p.c << 7;
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l = carry | (rd.l >> 1);
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_ror_w() {
|
||||
uint16 carry = (uint16)regs.p.c << 15;
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w = carry | (rd.w >> 1);
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_trb_b() {
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
rd.l &= ~regs.a.l;
|
||||
}
|
||||
|
||||
inline void sCPU::op_trb_w() {
|
||||
regs.p.z = ((rd.w & regs.a.w) == 0);
|
||||
rd.w &= ~regs.a.w;
|
||||
}
|
||||
|
||||
inline void sCPU::op_tsb_b() {
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
rd.l |= regs.a.l;
|
||||
}
|
||||
|
||||
inline void sCPU::op_tsb_w() {
|
||||
regs.p.z = ((rd.w & regs.a.w) == 0);
|
||||
rd.w |= regs.a.w;
|
||||
}
|
||||
@@ -0,0 +1,256 @@
|
||||
optbl[0x69] = &sCPU::op_adc_const;
|
||||
optbl[0x29] = &sCPU::op_and_const;
|
||||
optbl[0xc9] = &sCPU::op_cmp_const;
|
||||
optbl[0xe0] = &sCPU::op_cpx_const;
|
||||
optbl[0xc0] = &sCPU::op_cpy_const;
|
||||
optbl[0x49] = &sCPU::op_eor_const;
|
||||
optbl[0xa9] = &sCPU::op_lda_const;
|
||||
optbl[0xa2] = &sCPU::op_ldx_const;
|
||||
optbl[0xa0] = &sCPU::op_ldy_const;
|
||||
optbl[0x09] = &sCPU::op_ora_const;
|
||||
optbl[0xe9] = &sCPU::op_sbc_const;
|
||||
optbl[0x6d] = &sCPU::op_adc_addr;
|
||||
optbl[0x2d] = &sCPU::op_and_addr;
|
||||
optbl[0x2c] = &sCPU::op_bit_addr;
|
||||
optbl[0xcd] = &sCPU::op_cmp_addr;
|
||||
optbl[0xec] = &sCPU::op_cpx_addr;
|
||||
optbl[0xcc] = &sCPU::op_cpy_addr;
|
||||
optbl[0x4d] = &sCPU::op_eor_addr;
|
||||
optbl[0xad] = &sCPU::op_lda_addr;
|
||||
optbl[0xae] = &sCPU::op_ldx_addr;
|
||||
optbl[0xac] = &sCPU::op_ldy_addr;
|
||||
optbl[0x0d] = &sCPU::op_ora_addr;
|
||||
optbl[0xed] = &sCPU::op_sbc_addr;
|
||||
optbl[0x7d] = &sCPU::op_adc_addrx;
|
||||
optbl[0x3d] = &sCPU::op_and_addrx;
|
||||
optbl[0x3c] = &sCPU::op_bit_addrx;
|
||||
optbl[0xdd] = &sCPU::op_cmp_addrx;
|
||||
optbl[0x5d] = &sCPU::op_eor_addrx;
|
||||
optbl[0xbd] = &sCPU::op_lda_addrx;
|
||||
optbl[0xbc] = &sCPU::op_ldy_addrx;
|
||||
optbl[0x1d] = &sCPU::op_ora_addrx;
|
||||
optbl[0xfd] = &sCPU::op_sbc_addrx;
|
||||
optbl[0x79] = &sCPU::op_adc_addry;
|
||||
optbl[0x39] = &sCPU::op_and_addry;
|
||||
optbl[0xd9] = &sCPU::op_cmp_addry;
|
||||
optbl[0x59] = &sCPU::op_eor_addry;
|
||||
optbl[0xb9] = &sCPU::op_lda_addry;
|
||||
optbl[0xbe] = &sCPU::op_ldx_addry;
|
||||
optbl[0x19] = &sCPU::op_ora_addry;
|
||||
optbl[0xf9] = &sCPU::op_sbc_addry;
|
||||
optbl[0x6f] = &sCPU::op_adc_long;
|
||||
optbl[0x2f] = &sCPU::op_and_long;
|
||||
optbl[0xcf] = &sCPU::op_cmp_long;
|
||||
optbl[0x4f] = &sCPU::op_eor_long;
|
||||
optbl[0xaf] = &sCPU::op_lda_long;
|
||||
optbl[0x0f] = &sCPU::op_ora_long;
|
||||
optbl[0xef] = &sCPU::op_sbc_long;
|
||||
optbl[0x7f] = &sCPU::op_adc_longx;
|
||||
optbl[0x3f] = &sCPU::op_and_longx;
|
||||
optbl[0xdf] = &sCPU::op_cmp_longx;
|
||||
optbl[0x5f] = &sCPU::op_eor_longx;
|
||||
optbl[0xbf] = &sCPU::op_lda_longx;
|
||||
optbl[0x1f] = &sCPU::op_ora_longx;
|
||||
optbl[0xff] = &sCPU::op_sbc_longx;
|
||||
optbl[0x65] = &sCPU::op_adc_dp;
|
||||
optbl[0x25] = &sCPU::op_and_dp;
|
||||
optbl[0x24] = &sCPU::op_bit_dp;
|
||||
optbl[0xc5] = &sCPU::op_cmp_dp;
|
||||
optbl[0xe4] = &sCPU::op_cpx_dp;
|
||||
optbl[0xc4] = &sCPU::op_cpy_dp;
|
||||
optbl[0x45] = &sCPU::op_eor_dp;
|
||||
optbl[0xa5] = &sCPU::op_lda_dp;
|
||||
optbl[0xa6] = &sCPU::op_ldx_dp;
|
||||
optbl[0xa4] = &sCPU::op_ldy_dp;
|
||||
optbl[0x05] = &sCPU::op_ora_dp;
|
||||
optbl[0xe5] = &sCPU::op_sbc_dp;
|
||||
optbl[0x75] = &sCPU::op_adc_dpx;
|
||||
optbl[0x35] = &sCPU::op_and_dpx;
|
||||
optbl[0x34] = &sCPU::op_bit_dpx;
|
||||
optbl[0xd5] = &sCPU::op_cmp_dpx;
|
||||
optbl[0x55] = &sCPU::op_eor_dpx;
|
||||
optbl[0xb5] = &sCPU::op_lda_dpx;
|
||||
optbl[0xb4] = &sCPU::op_ldy_dpx;
|
||||
optbl[0x15] = &sCPU::op_ora_dpx;
|
||||
optbl[0xf5] = &sCPU::op_sbc_dpx;
|
||||
optbl[0xb6] = &sCPU::op_ldx_dpy;
|
||||
optbl[0x72] = &sCPU::op_adc_idp;
|
||||
optbl[0x32] = &sCPU::op_and_idp;
|
||||
optbl[0xd2] = &sCPU::op_cmp_idp;
|
||||
optbl[0x52] = &sCPU::op_eor_idp;
|
||||
optbl[0xb2] = &sCPU::op_lda_idp;
|
||||
optbl[0x12] = &sCPU::op_ora_idp;
|
||||
optbl[0xf2] = &sCPU::op_sbc_idp;
|
||||
optbl[0x61] = &sCPU::op_adc_idpx;
|
||||
optbl[0x21] = &sCPU::op_and_idpx;
|
||||
optbl[0xc1] = &sCPU::op_cmp_idpx;
|
||||
optbl[0x41] = &sCPU::op_eor_idpx;
|
||||
optbl[0xa1] = &sCPU::op_lda_idpx;
|
||||
optbl[0x01] = &sCPU::op_ora_idpx;
|
||||
optbl[0xe1] = &sCPU::op_sbc_idpx;
|
||||
optbl[0x71] = &sCPU::op_adc_idpy;
|
||||
optbl[0x31] = &sCPU::op_and_idpy;
|
||||
optbl[0xd1] = &sCPU::op_cmp_idpy;
|
||||
optbl[0x51] = &sCPU::op_eor_idpy;
|
||||
optbl[0xb1] = &sCPU::op_lda_idpy;
|
||||
optbl[0x11] = &sCPU::op_ora_idpy;
|
||||
optbl[0xf1] = &sCPU::op_sbc_idpy;
|
||||
optbl[0x67] = &sCPU::op_adc_ildp;
|
||||
optbl[0x27] = &sCPU::op_and_ildp;
|
||||
optbl[0xc7] = &sCPU::op_cmp_ildp;
|
||||
optbl[0x47] = &sCPU::op_eor_ildp;
|
||||
optbl[0xa7] = &sCPU::op_lda_ildp;
|
||||
optbl[0x07] = &sCPU::op_ora_ildp;
|
||||
optbl[0xe7] = &sCPU::op_sbc_ildp;
|
||||
optbl[0x77] = &sCPU::op_adc_ildpy;
|
||||
optbl[0x37] = &sCPU::op_and_ildpy;
|
||||
optbl[0xd7] = &sCPU::op_cmp_ildpy;
|
||||
optbl[0x57] = &sCPU::op_eor_ildpy;
|
||||
optbl[0xb7] = &sCPU::op_lda_ildpy;
|
||||
optbl[0x17] = &sCPU::op_ora_ildpy;
|
||||
optbl[0xf7] = &sCPU::op_sbc_ildpy;
|
||||
optbl[0x63] = &sCPU::op_adc_sr;
|
||||
optbl[0x23] = &sCPU::op_and_sr;
|
||||
optbl[0xc3] = &sCPU::op_cmp_sr;
|
||||
optbl[0x43] = &sCPU::op_eor_sr;
|
||||
optbl[0xa3] = &sCPU::op_lda_sr;
|
||||
optbl[0x03] = &sCPU::op_ora_sr;
|
||||
optbl[0xe3] = &sCPU::op_sbc_sr;
|
||||
optbl[0x73] = &sCPU::op_adc_isry;
|
||||
optbl[0x33] = &sCPU::op_and_isry;
|
||||
optbl[0xd3] = &sCPU::op_cmp_isry;
|
||||
optbl[0x53] = &sCPU::op_eor_isry;
|
||||
optbl[0xb3] = &sCPU::op_lda_isry;
|
||||
optbl[0x13] = &sCPU::op_ora_isry;
|
||||
optbl[0xf3] = &sCPU::op_sbc_isry;
|
||||
optbl[0x89] = &sCPU::op_bit_const;
|
||||
optbl[0x8d] = &sCPU::op_sta_addr;
|
||||
optbl[0x8e] = &sCPU::op_stx_addr;
|
||||
optbl[0x8c] = &sCPU::op_sty_addr;
|
||||
optbl[0x9c] = &sCPU::op_stz_addr;
|
||||
optbl[0x9d] = &sCPU::op_sta_addrx;
|
||||
optbl[0x9e] = &sCPU::op_stz_addrx;
|
||||
optbl[0x99] = &sCPU::op_sta_addry;
|
||||
optbl[0x8f] = &sCPU::op_sta_long;
|
||||
optbl[0x9f] = &sCPU::op_sta_longx;
|
||||
optbl[0x85] = &sCPU::op_sta_dp;
|
||||
optbl[0x86] = &sCPU::op_stx_dp;
|
||||
optbl[0x84] = &sCPU::op_sty_dp;
|
||||
optbl[0x64] = &sCPU::op_stz_dp;
|
||||
optbl[0x95] = &sCPU::op_sta_dpx;
|
||||
optbl[0x94] = &sCPU::op_sty_dpx;
|
||||
optbl[0x74] = &sCPU::op_stz_dpx;
|
||||
optbl[0x96] = &sCPU::op_stx_dpy;
|
||||
optbl[0x92] = &sCPU::op_sta_idp;
|
||||
optbl[0x87] = &sCPU::op_sta_ildp;
|
||||
optbl[0x81] = &sCPU::op_sta_idpx;
|
||||
optbl[0x91] = &sCPU::op_sta_idpy;
|
||||
optbl[0x97] = &sCPU::op_sta_ildpy;
|
||||
optbl[0x83] = &sCPU::op_sta_sr;
|
||||
optbl[0x93] = &sCPU::op_sta_isry;
|
||||
optbl[0x1a] = &sCPU::op_inc;
|
||||
optbl[0xe8] = &sCPU::op_inx;
|
||||
optbl[0xc8] = &sCPU::op_iny;
|
||||
optbl[0x3a] = &sCPU::op_dec;
|
||||
optbl[0xca] = &sCPU::op_dex;
|
||||
optbl[0x88] = &sCPU::op_dey;
|
||||
optbl[0x0a] = &sCPU::op_asl;
|
||||
optbl[0x4a] = &sCPU::op_lsr;
|
||||
optbl[0x2a] = &sCPU::op_rol;
|
||||
optbl[0x6a] = &sCPU::op_ror;
|
||||
optbl[0xee] = &sCPU::op_inc_addr;
|
||||
optbl[0xce] = &sCPU::op_dec_addr;
|
||||
optbl[0x0e] = &sCPU::op_asl_addr;
|
||||
optbl[0x4e] = &sCPU::op_lsr_addr;
|
||||
optbl[0x2e] = &sCPU::op_rol_addr;
|
||||
optbl[0x6e] = &sCPU::op_ror_addr;
|
||||
optbl[0x1c] = &sCPU::op_trb_addr;
|
||||
optbl[0x0c] = &sCPU::op_tsb_addr;
|
||||
optbl[0xfe] = &sCPU::op_inc_addrx;
|
||||
optbl[0xde] = &sCPU::op_dec_addrx;
|
||||
optbl[0x1e] = &sCPU::op_asl_addrx;
|
||||
optbl[0x5e] = &sCPU::op_lsr_addrx;
|
||||
optbl[0x3e] = &sCPU::op_rol_addrx;
|
||||
optbl[0x7e] = &sCPU::op_ror_addrx;
|
||||
optbl[0xe6] = &sCPU::op_inc_dp;
|
||||
optbl[0xc6] = &sCPU::op_dec_dp;
|
||||
optbl[0x06] = &sCPU::op_asl_dp;
|
||||
optbl[0x46] = &sCPU::op_lsr_dp;
|
||||
optbl[0x26] = &sCPU::op_rol_dp;
|
||||
optbl[0x66] = &sCPU::op_ror_dp;
|
||||
optbl[0x14] = &sCPU::op_trb_dp;
|
||||
optbl[0x04] = &sCPU::op_tsb_dp;
|
||||
optbl[0xf6] = &sCPU::op_inc_dpx;
|
||||
optbl[0xd6] = &sCPU::op_dec_dpx;
|
||||
optbl[0x16] = &sCPU::op_asl_dpx;
|
||||
optbl[0x56] = &sCPU::op_lsr_dpx;
|
||||
optbl[0x36] = &sCPU::op_rol_dpx;
|
||||
optbl[0x76] = &sCPU::op_ror_dpx;
|
||||
optbl[0x90] = &sCPU::op_bcc;
|
||||
optbl[0xb0] = &sCPU::op_bcs;
|
||||
optbl[0xd0] = &sCPU::op_bne;
|
||||
optbl[0xf0] = &sCPU::op_beq;
|
||||
optbl[0x10] = &sCPU::op_bpl;
|
||||
optbl[0x30] = &sCPU::op_bmi;
|
||||
optbl[0x50] = &sCPU::op_bvc;
|
||||
optbl[0x70] = &sCPU::op_bvs;
|
||||
optbl[0x80] = &sCPU::op_bra;
|
||||
optbl[0x82] = &sCPU::op_brl;
|
||||
optbl[0x4c] = &sCPU::op_jmp_addr;
|
||||
optbl[0x5c] = &sCPU::op_jmp_long;
|
||||
optbl[0x6c] = &sCPU::op_jmp_iaddr;
|
||||
optbl[0x7c] = &sCPU::op_jmp_iaddrx;
|
||||
optbl[0xdc] = &sCPU::op_jmp_iladdr;
|
||||
optbl[0x20] = &sCPU::op_jsr_addr;
|
||||
optbl[0x22] = &sCPU::op_jsr_long;
|
||||
optbl[0xfc] = &sCPU::op_jsr_iaddrx;
|
||||
optbl[0x40] = &sCPU::op_rti;
|
||||
optbl[0x60] = &sCPU::op_rts;
|
||||
optbl[0x6b] = &sCPU::op_rtl;
|
||||
optbl[0xea] = &sCPU::op_nop;
|
||||
optbl[0x42] = &sCPU::op_wdm;
|
||||
optbl[0xeb] = &sCPU::op_xba;
|
||||
optbl[0x54] = &sCPU::op_mvn;
|
||||
optbl[0x44] = &sCPU::op_mvp;
|
||||
optbl[0x00] = &sCPU::op_brk;
|
||||
optbl[0x02] = &sCPU::op_cop;
|
||||
optbl[0xdb] = &sCPU::op_stp;
|
||||
optbl[0xcb] = &sCPU::op_wai;
|
||||
optbl[0xfb] = &sCPU::op_xce;
|
||||
optbl[0x18] = &sCPU::op_clc;
|
||||
optbl[0xd8] = &sCPU::op_cld;
|
||||
optbl[0x58] = &sCPU::op_cli;
|
||||
optbl[0xb8] = &sCPU::op_clv;
|
||||
optbl[0x38] = &sCPU::op_sec;
|
||||
optbl[0xf8] = &sCPU::op_sed;
|
||||
optbl[0x78] = &sCPU::op_sei;
|
||||
optbl[0xc2] = &sCPU::op_rep;
|
||||
optbl[0xe2] = &sCPU::op_sep;
|
||||
optbl[0xaa] = &sCPU::op_tax;
|
||||
optbl[0xa8] = &sCPU::op_tay;
|
||||
optbl[0x8a] = &sCPU::op_txa;
|
||||
optbl[0x9b] = &sCPU::op_txy;
|
||||
optbl[0x98] = &sCPU::op_tya;
|
||||
optbl[0xbb] = &sCPU::op_tyx;
|
||||
optbl[0x5b] = &sCPU::op_tcd;
|
||||
optbl[0x1b] = &sCPU::op_tcs;
|
||||
optbl[0x7b] = &sCPU::op_tdc;
|
||||
optbl[0x3b] = &sCPU::op_tsc;
|
||||
optbl[0xba] = &sCPU::op_tsx;
|
||||
optbl[0x9a] = &sCPU::op_txs;
|
||||
optbl[0x48] = &sCPU::op_pha;
|
||||
optbl[0xda] = &sCPU::op_phx;
|
||||
optbl[0x5a] = &sCPU::op_phy;
|
||||
optbl[0x0b] = &sCPU::op_phd;
|
||||
optbl[0x8b] = &sCPU::op_phb;
|
||||
optbl[0x4b] = &sCPU::op_phk;
|
||||
optbl[0x08] = &sCPU::op_php;
|
||||
optbl[0x68] = &sCPU::op_pla;
|
||||
optbl[0xfa] = &sCPU::op_plx;
|
||||
optbl[0x7a] = &sCPU::op_ply;
|
||||
optbl[0x2b] = &sCPU::op_pld;
|
||||
optbl[0xab] = &sCPU::op_plb;
|
||||
optbl[0x28] = &sCPU::op_plp;
|
||||
optbl[0xf4] = &sCPU::op_pea;
|
||||
optbl[0xd4] = &sCPU::op_pei;
|
||||
optbl[0x62] = &sCPU::op_per;
|
||||
@@ -0,0 +1,18 @@
|
||||
#define CLASS_NAME "sCPU"
|
||||
#include "../../../lib/opgen_so.cpp"
|
||||
|
||||
int main() {
|
||||
fph = fopen("op.h", "wb");
|
||||
fpt = fopen("optable.cpp", "wb");
|
||||
|
||||
generate("op_read.cpp", "op_read.b");
|
||||
generate("op_write.cpp", "op_write.b");
|
||||
generate("op_rmw.cpp", "op_rmw.b");
|
||||
generate("op_pc.cpp", "op_pc.b");
|
||||
generate("op_misc.cpp", "op_misc.b");
|
||||
|
||||
fclose(fph);
|
||||
fclose(fpt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,274 @@
|
||||
void sCPU::dma_add_clocks(uint clocks) {
|
||||
status.dma_clocks += clocks;
|
||||
add_clocks(clocks);
|
||||
}
|
||||
|
||||
/*****
|
||||
* used by both DMA and HDMA
|
||||
*
|
||||
* DMA address bus A cannot read from or write to the following addresses :
|
||||
* $[00-3f|80-bf]:43[00-7f] <DMA control registers>
|
||||
* $[00-3f|80-bf]:420b <DMA enable register>
|
||||
* $[00-3f|80-bf]:420c <HDMA enable register>
|
||||
* WRAM<>WRAM transfers via $2180
|
||||
*****/
|
||||
void sCPU::dma_transfer(bool direction, uint8 bbus, uint32 abus) {
|
||||
uint8 r;
|
||||
if(direction == 0) { //a->b
|
||||
if((abus & 0x40ff00) == 0x2100 || (abus & 0x40ff80) == 0x4300 ||
|
||||
(abus & 0x40ffff) == 0x420b || (abus & 0x40ffff) == 0x420c) {
|
||||
r = regs.mdr;
|
||||
} else {
|
||||
r = r_mem->read(abus);
|
||||
}
|
||||
r_mem->write(0x2100 | bbus, r);
|
||||
} else { //b->a
|
||||
if(bbus == 0x80 && ((abus & 0x7e0000) == 0x7e0000 || (abus & 0x40e000) == 0x0000)) {
|
||||
//prevent WRAM->WRAM transfers
|
||||
r = regs.mdr;
|
||||
} else {
|
||||
r = r_mem->read(0x2100 | bbus);
|
||||
}
|
||||
if((abus & 0x40ff00) == 0x2100 || (abus & 0x40ff80) == 0x4300 ||
|
||||
(abus & 0x40ffff) == 0x420b || (abus & 0x40ffff) == 0x420c)return;
|
||||
r_mem->write(abus, r);
|
||||
}
|
||||
|
||||
dma_add_clocks(8);
|
||||
cycle_edge();
|
||||
}
|
||||
|
||||
/*****
|
||||
* address calculation functions
|
||||
*****/
|
||||
|
||||
uint8 sCPU::dma_bbus(uint8 i, uint8 index) {
|
||||
switch(channel[i].xfermode) {
|
||||
default:
|
||||
case 0: return (channel[i].destaddr); break; //0
|
||||
case 1: return (channel[i].destaddr + (index & 1)); break; //0,1
|
||||
case 2: return (channel[i].destaddr); break; //0,0
|
||||
case 3: return (channel[i].destaddr + ((index >> 1) & 1)); break; //0,0,1,1
|
||||
case 4: return (channel[i].destaddr + (index & 3)); break; //0,1,2,3
|
||||
case 5: return (channel[i].destaddr + (index & 1)); break; //0,1,0,1
|
||||
case 6: return (channel[i].destaddr); break; //0,0 [2]
|
||||
case 7: return (channel[i].destaddr + ((index >> 1) & 1)); break; //0,0,1,1 [3]
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32 sCPU::dma_addr(uint8 i) {
|
||||
uint32 r = (channel[i].srcbank << 16) | (channel[i].srcaddr);
|
||||
|
||||
if(channel[i].fixedxfer == false) {
|
||||
if(channel[i].reversexfer == false) {
|
||||
channel[i].srcaddr++;
|
||||
} else {
|
||||
channel[i].srcaddr--;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
inline uint32 sCPU::hdma_addr(uint8 i) {
|
||||
return (channel[i].srcbank << 16) | (channel[i].hdma_addr++);
|
||||
}
|
||||
|
||||
inline uint32 sCPU::hdma_iaddr(uint8 i) {
|
||||
return (channel[i].hdma_ibank << 16) | (channel[i].hdma_iaddr++);
|
||||
}
|
||||
|
||||
/*****
|
||||
* DMA functions
|
||||
*****/
|
||||
|
||||
void sCPU::dma_transfertobusb(uint8 i, uint8 bbus) {
|
||||
if(cartridge.info.sdd1 == true && sdd1->dma_active() == true) {
|
||||
r_mem->write(0x2100 | bbus, sdd1->dma_read());
|
||||
} else {
|
||||
dma_transfer(0, bbus, dma_addr(i));
|
||||
}
|
||||
channel[i].xfersize--;
|
||||
}
|
||||
|
||||
void sCPU::dma_transfertobusa(uint8 i, uint8 bbus) {
|
||||
dma_transfer(1, bbus, dma_addr(i));
|
||||
channel[i].xfersize--;
|
||||
}
|
||||
|
||||
inline void sCPU::dma_write(uint8 i, uint8 index) {
|
||||
//cannot use dma_transfer() directly, due to current S-DD1 implementation
|
||||
if(channel[i].direction == 0) {
|
||||
dma_transfertobusb(i, index);
|
||||
} else {
|
||||
dma_transfertobusa(i, index);
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::dma_run() {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(channel[i].dma_enabled == false)continue;
|
||||
dma_add_clocks(8);
|
||||
|
||||
if(cartridge.info.sdd1 == true) {
|
||||
sdd1->dma_begin(i, (channel[i].srcbank << 16) | (channel[i].srcaddr),
|
||||
channel[i].xfersize);
|
||||
}
|
||||
|
||||
if(tracer.enabled() == true && tracer.cpudma_enabled() == true) {
|
||||
tprintf("[DMA] channel:%d direction:%s reverse:%c fixed:%c mode:%d b_addr:$21%0.2x "
|
||||
"a_addr:$%0.2x%0.4x length:$%0.4x (%5d)",
|
||||
i, channel[i].direction ? "b->a" : "a->b", channel[i].reversexfer ? '1' : '0',
|
||||
channel[i].fixedxfer ? '1' : '0', channel[i].xfermode, channel[i].destaddr,
|
||||
channel[i].srcbank, channel[i].srcaddr,
|
||||
channel[i].xfersize, channel[i].xfersize ? channel[i].xfersize : 65536);
|
||||
}
|
||||
|
||||
uint index = 0;
|
||||
do {
|
||||
dma_write(i, dma_bbus(i, index++));
|
||||
} while(channel[i].dma_enabled && channel[i].xfersize);
|
||||
|
||||
channel[i].dma_enabled = false;
|
||||
}
|
||||
|
||||
counter.set(counter.irq_delay, 2);
|
||||
}
|
||||
|
||||
/*****
|
||||
* HDMA functions
|
||||
*****/
|
||||
|
||||
inline bool sCPU::hdma_active(uint8 i) {
|
||||
return (channel[i].hdma_enabled && !channel[i].hdma_completed);
|
||||
}
|
||||
|
||||
inline bool sCPU::hdma_active_after(uint8 i) {
|
||||
for(int n = i + 1; n < 8; n++) {
|
||||
if(hdma_active(n) == true) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline uint8 sCPU::hdma_enabled_channels() {
|
||||
uint8 r = 0;
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(channel[i].hdma_enabled)r++;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
inline uint8 sCPU::hdma_active_channels() {
|
||||
uint8 r = 0;
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(hdma_active(i) == true)r++;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void sCPU::hdma_update(uint8 i) {
|
||||
channel[i].hdma_line_counter = r_mem->read(hdma_addr(i));
|
||||
dma_add_clocks(8);
|
||||
|
||||
channel[i].hdma_completed = (channel[i].hdma_line_counter == 0);
|
||||
channel[i].hdma_do_transfer = !channel[i].hdma_completed;
|
||||
|
||||
if(channel[i].hdma_indirect) {
|
||||
channel[i].hdma_iaddr = r_mem->read(hdma_addr(i)) << 8;
|
||||
dma_add_clocks(8);
|
||||
|
||||
if(!channel[i].hdma_completed || hdma_active_after(i)) {
|
||||
channel[i].hdma_iaddr >>= 8;
|
||||
channel[i].hdma_iaddr |= r_mem->read(hdma_addr(i)) << 8;
|
||||
dma_add_clocks(8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::hdma_run() {
|
||||
static uint8 hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 };
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(hdma_active(i) == false)continue;
|
||||
channel[i].dma_enabled = false; //HDMA run during DMA will stop DMA mid-transfer
|
||||
dma_add_clocks(8);
|
||||
|
||||
if(channel[i].hdma_do_transfer) {
|
||||
int xferlen = hdma_xferlen[channel[i].xfermode];
|
||||
for(int index = 0; index < xferlen; index++) {
|
||||
if(bool(config::cpu.hdma_enable) == true) {
|
||||
dma_transfer(channel[i].direction, dma_bbus(i, index),
|
||||
!channel[i].hdma_indirect ? hdma_addr(i) : hdma_iaddr(i));
|
||||
} else {
|
||||
dma_add_clocks(8);
|
||||
cycle_edge();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
channel[i].hdma_line_counter--;
|
||||
channel[i].hdma_do_transfer = bool(channel[i].hdma_line_counter & 0x80);
|
||||
if((channel[i].hdma_line_counter & 0x7f) == 0) {
|
||||
hdma_update(i);
|
||||
}
|
||||
}
|
||||
|
||||
counter.set(counter.irq_delay, 2);
|
||||
}
|
||||
|
||||
void sCPU::hdma_init_reset() {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
channel[i].hdma_completed = false;
|
||||
channel[i].hdma_do_transfer = false;
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::hdma_init() {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(!channel[i].hdma_enabled)continue;
|
||||
channel[i].dma_enabled = false; //HDMA init during DMA will stop DMA mid-transfer
|
||||
|
||||
channel[i].hdma_addr = channel[i].srcaddr;
|
||||
hdma_update(i);
|
||||
}
|
||||
|
||||
counter.set(counter.irq_delay, 2);
|
||||
}
|
||||
|
||||
/*****
|
||||
* power / reset functions
|
||||
*****/
|
||||
|
||||
void sCPU::dma_power() {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
channel[i].dmap = 0xff;
|
||||
channel[i].direction = 1;
|
||||
channel[i].hdma_indirect = true;
|
||||
channel[i].reversexfer = true;
|
||||
channel[i].fixedxfer = true;
|
||||
channel[i].xfermode = 7;
|
||||
|
||||
channel[i].destaddr = 0xff;
|
||||
|
||||
channel[i].srcaddr = 0xffff;
|
||||
channel[i].srcbank = 0xff;
|
||||
|
||||
channel[i].xfersize = 0xffff;
|
||||
//channel[i].hdma_iaddr = 0xffff; //union with xfersize
|
||||
channel[i].hdma_ibank = 0xff;
|
||||
|
||||
channel[i].hdma_addr = 0xffff;
|
||||
channel[i].hdma_line_counter = 0xff;
|
||||
channel[i].unknown = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::dma_reset() {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
channel[i].dma_enabled = false;
|
||||
channel[i].hdma_enabled = false;
|
||||
|
||||
channel[i].hdma_completed = false;
|
||||
channel[i].hdma_do_transfer = false;
|
||||
}
|
||||
}
|
||||
Loaded 100 of 439 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user