mirror of
https://github.com/ares-emulator/ares.git
synced 2026-11-08 08:03:07 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9e3827e2a2 | ||
|
|
e499670ad9 | ||
|
|
805398e5a8 | ||
|
|
7e6e3e3a69 | ||
|
|
16ba1d1191 | ||
|
|
29c871ef62 | ||
|
|
42f1d08c02 | ||
|
|
521f4f6952 | ||
|
|
92cfb1268a | ||
|
|
4d922ba17c | ||
|
|
3b2918791c | ||
|
|
b7d34a8aa3 | ||
|
|
8fd90cc123 | ||
|
|
e651beb72e | ||
|
|
4cbba77fc7 | ||
|
|
1194d3f9dc | ||
|
|
89a1b3d65f | ||
|
|
5a82cdf978 | ||
|
|
52be510d2b | ||
|
|
8b7219bdef | ||
|
|
926ffd9695 | ||
|
|
a1389a2ba3 | ||
|
|
5263ffb7aa | ||
|
|
1744bcb99c | ||
|
|
6362044c05 | ||
|
|
319b244af4 | ||
|
|
a3f1802845 | ||
|
|
4370acae2e | ||
|
|
5a804eac58 | ||
|
|
3b65b50aea | ||
|
|
a85ff8c437 | ||
|
|
a15d15047c | ||
|
|
f77aca7172 | ||
|
|
c32195cbd6 | ||
|
|
161366df9b | ||
|
|
4c43e85141 | ||
|
|
9da42c18c3 | ||
|
|
d115c7f6aa | ||
|
|
2efce0fd83 | ||
|
|
f6732133e7 | ||
|
|
95547f4ff8 | ||
|
|
4f5bdfe347 | ||
|
|
49b0bed1a6 | ||
|
|
1554170312 | ||
|
|
ec137d6fb9 | ||
|
|
aee683a475 | ||
|
|
cdbf07b642 | ||
|
|
8a857dada3 | ||
|
|
ab1975a6cb | ||
|
|
476a1c819a | ||
|
|
42d3f2a37f | ||
|
|
c58e3af1b5 | ||
|
|
8226e243b8 | ||
|
|
9ab3fa6227 | ||
|
|
85fa3cc968 | ||
|
|
d1fcddee9c | ||
|
|
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 | ||
|
|
ea38ea2537 |
No files matched your search
@@ -1,21 +0,0 @@
|
||||
#[bsnes v0.007 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.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
+85
-9
@@ -1,10 +1,86 @@
|
||||
bsnes Licensing Agreement:
|
||||
bsnes (TM) Reference License
|
||||
Copyright (C) 2004 - 2008 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 decompressor, author: NSRT Team, license: GPL (*)
|
||||
NTSC filter, author: blargg, license: LGPL
|
||||
zlib decompressor, license: zlib license
|
||||
|
||||
(*) bsnes has received an exemption from the copyright holder to use this work.
|
||||
|
||||
The software also includes works which have been released to the public domain,
|
||||
which are not bound to any licensing agreements. Below is a complete list of all
|
||||
such software.
|
||||
|
||||
libco, author: byuu
|
||||
libui, author: byuu
|
||||
OBC-1 emu, author: byuu
|
||||
S-DD1 emu, author: Andreas Naive
|
||||
S-RTC emu, author: byuu
|
||||
|
||||
Any software listed above as exemptions may be relicensed individually from
|
||||
bsnes under their respective terms. However, no bsnes licensed portions can be
|
||||
combined with such a derivative work.
|
||||
|
||||
The software also includes the work of other copyright holders, which is
|
||||
licensed under the terms of the bsnes license, with permission to do so from the
|
||||
respective authors. Below is a complete list of all such software.
|
||||
|
||||
Cx4 emu, authors: anomie, Overload, zsKnight, Nach
|
||||
DSP-1 emu, authors: Overload, John Weidman, Neviksti, Andreas Naive
|
||||
DSP-2 emu, author: Overload
|
||||
DSP-3 emu, authors: John Weidman, Kris Bleakley, Lancer, z80 gaiden
|
||||
DSP-4 emu, authors: Dreamer Nom, John Weidman, Kris Bleakley, Nach, z80 gaiden
|
||||
S-DSP emu, author: blargg
|
||||
ST-010 emu, authors: John Weidman, Matthew Kendora, Overload, Feather
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
bsnes
|
||||
Version: 0.030
|
||||
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.
|
||||
|
||||
------------------
|
||||
Known Limitations:
|
||||
------------------
|
||||
S-CPU
|
||||
- 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
|
||||
|
||||
ST-011
|
||||
SETA DSP used only by Quick-move Shogi Match with Nidan Rank-holder Morita
|
||||
|
||||
ST-018
|
||||
SETA RISC CPU used only by Quick-move Shogi Match with Nidan Rank-holder Morita 2
|
||||
|
||||
Super Gameboy
|
||||
Cartridge passthrough used for playing Gameboy games
|
||||
|
||||
------------------------
|
||||
Unsupported Controllers:
|
||||
------------------------
|
||||
Mouse
|
||||
Super Scope
|
||||
Justifier
|
||||
Multitap (4-port and 5-port)
|
||||
+277
@@ -0,0 +1,277 @@
|
||||
include lib/nall/Makefile.string
|
||||
prefix = /usr/local
|
||||
|
||||
################
|
||||
### compiler ###
|
||||
################
|
||||
|
||||
ifneq ($(findstring gcc,$(compiler)),) # GCC family
|
||||
flags = -O3 -fomit-frame-pointer -Ilib
|
||||
c = $(compiler) $(flags)
|
||||
cpp = $(subst cc,++,$(compiler)) $(flags)
|
||||
obj = o
|
||||
rule = -c $< -o $@
|
||||
link =
|
||||
mkbin = -o$1
|
||||
mkdef = -D$1
|
||||
mklib = -l$1
|
||||
else ifeq ($(compiler),cl) # Visual C++
|
||||
flags = /nologo /wd4355 /wd4996 /O2 /EHsc /Ilib
|
||||
c = cl $(flags)
|
||||
cpp = cl $(flags)
|
||||
obj = obj
|
||||
rule = /c $< /Fo$@
|
||||
link = /link
|
||||
mkbin = /Fe$1
|
||||
mkdef = /D$1
|
||||
mklib = $1.lib
|
||||
else
|
||||
unknown_compiler: help;
|
||||
endif
|
||||
|
||||
##########
|
||||
### os ###
|
||||
##########
|
||||
|
||||
ifeq ($(platform),x) # X11
|
||||
ruby = video.glx video.xv video.sdl audio.openal audio.oss audio.ao input.sdl input.x
|
||||
link += `pkg-config --libs gtk+-2.0`
|
||||
link += $(call mklib,Xtst)
|
||||
delete = rm -f $1
|
||||
else ifeq ($(platform),win) # Windows
|
||||
ruby = video.direct3d video.directdraw video.gdi audio.directsound input.directinput
|
||||
link += $(if $(findstring mingw,$(compiler)),-mwindows)
|
||||
link += $(call mklib,uuid)
|
||||
link += $(call mklib,kernel32)
|
||||
link += $(call mklib,user32)
|
||||
link += $(call mklib,gdi32)
|
||||
link += $(call mklib,shell32)
|
||||
link += $(call mklib,winmm)
|
||||
link += $(call mklib,comdlg32)
|
||||
link += $(call mklib,comctl32)
|
||||
delete = $(if $(findstring i586-mingw-gcc,$(compiler)),rm -f $1,del $(subst /,\,$1))
|
||||
else
|
||||
unknown_platform: help;
|
||||
endif
|
||||
|
||||
############
|
||||
### ruby ###
|
||||
############
|
||||
|
||||
rubyflags =
|
||||
rubyflags += $(if $(findstring .sdl,$(ruby)),`sdl-config --cflags`)
|
||||
|
||||
link += $(if $(findstring video.direct3d,$(ruby)),$(call mklib,d3d9))
|
||||
link += $(if $(findstring video.directdraw,$(ruby)),$(call mklib,ddraw))
|
||||
link += $(if $(findstring video.glx,$(ruby)),$(call mklib,GL))
|
||||
link += $(if $(findstring video.xv,$(ruby)),$(call mklib,Xv))
|
||||
link += $(if $(findstring audio.ao,$(ruby)),$(call mklib,ao))
|
||||
link += $(if $(findstring audio.directsound,$(ruby)),$(call mklib,dsound))
|
||||
link += $(if $(findstring audio.openal,$(ruby)),$(if $(call streq,$(platform),x),$(call mklib,openal),$(call mklib,openal32)))
|
||||
link += $(if $(findstring input.directinput,$(ruby)),$(call mklib,dinput8) $(call mklib,dxguid))
|
||||
link += $(if $(findstring input.sdl,$(ruby)),`sdl-config --libs`)
|
||||
|
||||
####################################
|
||||
### main target and dependencies ###
|
||||
####################################
|
||||
|
||||
objects = main libco hiro ruby libfilter string reader cart cheat \
|
||||
memory smemory cpu scpu smp ssmp sdsp ppu bppu snes \
|
||||
bsx srtc sdd1 cx4 dsp1 dsp2 dsp3 dsp4 obc1 st010
|
||||
|
||||
ifeq ($(enable_gzip),true)
|
||||
objects += adler32 compress crc32 deflate gzio inffast inflate inftrees ioapi trees unzip zip zutil
|
||||
flags += $(call mkdef,GZIP_SUPPORT)
|
||||
endif
|
||||
|
||||
ifeq ($(enable_jma),true)
|
||||
objects += jma jcrc32 lzmadec 7zlzma iiostrm inbyte lzma winout
|
||||
flags += $(call mkdef,JMA_SUPPORT)
|
||||
endif
|
||||
|
||||
objects := $(patsubst %,obj/%.$(obj),$(objects))
|
||||
rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),$(call mkdef,$c))
|
||||
|
||||
# Windows resource file
|
||||
ifeq ($(platform),win)
|
||||
ifeq ($(compiler),cl)
|
||||
objects += obj/bsnes.res
|
||||
else ifneq ($(findstring gcc,$(compiler)),)
|
||||
objects += obj/bsnesrc.$(obj)
|
||||
endif
|
||||
endif
|
||||
|
||||
################
|
||||
### implicit ###
|
||||
################
|
||||
|
||||
compile = \
|
||||
$(strip \
|
||||
$(if $(filter %.c,$<), \
|
||||
$(c) $1 $(rule), \
|
||||
$(if $(filter %.cpp,$<), \
|
||||
$(cpp) $1 $(rule) \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
||||
%.$(obj): $<; $(call compile)
|
||||
|
||||
all: build;
|
||||
|
||||
############
|
||||
### main ###
|
||||
############
|
||||
|
||||
obj/main.$(obj): ui/main.cpp ui/* ui/base/* ui/loader/* ui/settings/*
|
||||
obj/bsnes.res: ui/bsnes.rc; rc /r /foobj/bsnes.res ui/bsnes.rc
|
||||
obj/bsnesrc.$(obj): ui/bsnes.rc; windres ui/bsnes.rc obj/bsnesrc.$(obj)
|
||||
|
||||
#################
|
||||
### libraries ###
|
||||
#################
|
||||
|
||||
obj/ruby.$(obj): lib/ruby/ruby.cpp lib/ruby/*
|
||||
$(call compile,$(rubydef) $(rubyflags))
|
||||
obj/hiro.$(obj): lib/hiro/hiro.cpp lib/hiro/* lib/hiro/gtk/* lib/hiro/win/*
|
||||
$(call compile,$(if $(call streq,$(platform),x),`pkg-config --cflags gtk+-2.0`))
|
||||
obj/libco.$(obj): lib/libco/libco.c lib/libco/*
|
||||
$(call compile,-static)
|
||||
obj/libfilter.$(obj): lib/libfilter/libfilter.cpp lib/libfilter/*
|
||||
obj/string.$(obj): lib/nall/string.cpp lib/nall/*
|
||||
|
||||
#################
|
||||
### utilities ###
|
||||
#################
|
||||
|
||||
obj/reader.$(obj): reader/reader.cpp reader/*
|
||||
obj/cart.$(obj) : cart/cart.cpp cart/*
|
||||
obj/cheat.$(obj) : cheat/cheat.cpp cheat/*
|
||||
|
||||
##############
|
||||
### memory ###
|
||||
##############
|
||||
|
||||
obj/memory.$(obj) : memory/memory.cpp memory/*
|
||||
obj/smemory.$(obj): memory/smemory/smemory.cpp memory/smemory/* memory/smemory/mapper/*
|
||||
|
||||
###########
|
||||
### cpu ###
|
||||
###########
|
||||
|
||||
obj/cpu.$(obj) : cpu/cpu.cpp cpu/*
|
||||
obj/scpu.$(obj): cpu/scpu/scpu.cpp cpu/scpu/* cpu/scpu/core/* cpu/scpu/dma/* cpu/scpu/memory/* cpu/scpu/mmio/* cpu/scpu/timing/*
|
||||
|
||||
###########
|
||||
### smp ###
|
||||
###########
|
||||
|
||||
obj/smp.$(obj) : smp/smp.cpp smp/*
|
||||
obj/ssmp.$(obj): smp/ssmp/ssmp.cpp smp/ssmp/* smp/ssmp/core/* smp/ssmp/memory/* smp/ssmp/timing/*
|
||||
|
||||
###########
|
||||
### dsp ###
|
||||
###########
|
||||
|
||||
obj/adsp.$(obj): dsp/adsp/adsp.cpp dsp/adsp/*
|
||||
obj/bdsp.$(obj): dsp/bdsp/bdsp.cpp dsp/bdsp/*
|
||||
obj/sdsp.$(obj): dsp/sdsp/sdsp.cpp dsp/sdsp/*
|
||||
|
||||
###########
|
||||
### ppu ###
|
||||
###########
|
||||
|
||||
obj/ppu.$(obj) : ppu/ppu.cpp ppu/*
|
||||
obj/bppu.$(obj): ppu/bppu/bppu.cpp ppu/bppu/*
|
||||
|
||||
############
|
||||
### snes ###
|
||||
############
|
||||
|
||||
obj/snes.$(obj): snes/snes.cpp snes/* snes/scheduler/* snes/video/* snes/audio/* snes/input/*
|
||||
|
||||
#####################
|
||||
### special chips ###
|
||||
#####################
|
||||
|
||||
obj/bsx.$(obj) : chip/bsx/bsx.cpp chip/bsx/*
|
||||
obj/srtc.$(obj) : chip/srtc/srtc.cpp chip/srtc/*
|
||||
obj/sdd1.$(obj) : chip/sdd1/sdd1.cpp chip/sdd1/*
|
||||
obj/cx4.$(obj) : chip/cx4/cx4.cpp chip/cx4/*
|
||||
obj/dsp1.$(obj) : chip/dsp1/dsp1.cpp chip/dsp1/*
|
||||
obj/dsp2.$(obj) : chip/dsp2/dsp2.cpp chip/dsp2/*
|
||||
obj/dsp3.$(obj) : chip/dsp3/dsp3.cpp chip/dsp3/*
|
||||
obj/dsp4.$(obj) : chip/dsp4/dsp4.cpp chip/dsp4/*
|
||||
obj/obc1.$(obj) : chip/obc1/obc1.cpp chip/obc1/*
|
||||
obj/st010.$(obj): chip/st010/st010.cpp chip/st010/*
|
||||
|
||||
############
|
||||
### zlib ###
|
||||
############
|
||||
|
||||
obj/adler32.$(obj) : reader/zlib/adler32.c reader/zlib/*
|
||||
obj/compress.$(obj): reader/zlib/compress.c reader/zlib/*
|
||||
obj/crc32.$(obj) : reader/zlib/crc32.c reader/zlib/*
|
||||
obj/deflate.$(obj) : reader/zlib/deflate.c reader/zlib/*
|
||||
obj/gzio.$(obj) : reader/zlib/gzio.c reader/zlib/*
|
||||
obj/inffast.$(obj) : reader/zlib/inffast.c reader/zlib/*
|
||||
obj/inflate.$(obj) : reader/zlib/inflate.c reader/zlib/*
|
||||
obj/inftrees.$(obj): reader/zlib/inftrees.c reader/zlib/*
|
||||
obj/ioapi.$(obj) : reader/zlib/ioapi.c reader/zlib/*
|
||||
obj/trees.$(obj) : reader/zlib/trees.c reader/zlib/*
|
||||
obj/unzip.$(obj) : reader/zlib/unzip.c reader/zlib/*
|
||||
obj/zip.$(obj) : reader/zlib/zip.c reader/zlib/*
|
||||
obj/zutil.$(obj) : reader/zlib/zutil.c reader/zlib/*
|
||||
|
||||
###########
|
||||
### jma ###
|
||||
###########
|
||||
|
||||
obj/jma.$(obj) : reader/jma/jma.cpp reader/jma/*
|
||||
obj/jcrc32.$(obj) : reader/jma/jcrc32.cpp reader/jma/*
|
||||
obj/lzmadec.$(obj): reader/jma/lzmadec.cpp reader/jma/*
|
||||
obj/7zlzma.$(obj) : reader/jma/7zlzma.cpp reader/jma/*
|
||||
obj/iiostrm.$(obj): reader/jma/iiostrm.cpp reader/jma/*
|
||||
obj/inbyte.$(obj) : reader/jma/inbyte.cpp reader/jma/*
|
||||
obj/lzma.$(obj) : reader/jma/lzma.cpp reader/jma/*
|
||||
obj/winout.$(obj) : reader/jma/winout.cpp reader/jma/*
|
||||
|
||||
###############
|
||||
### targets ###
|
||||
###############
|
||||
|
||||
build: $(objects)
|
||||
$(strip $(cpp) $(call mkbin,../bsnes) $(objects) $(link))
|
||||
|
||||
install:
|
||||
install -D -m 755 ../bsnes $(DESTDIR)$(prefix)/bin/bsnes
|
||||
install -D -m 644 data/bsnes.png $(DESTDIR)$(prefix)/share/icons/bsnes.png
|
||||
|
||||
clean:
|
||||
-@$(call delete,obj/*.$(obj))
|
||||
-@$(call delete,*.res)
|
||||
-@$(call delete,*.pgd)
|
||||
-@$(call delete,*.pgc)
|
||||
-@$(call delete,*.ilk)
|
||||
-@$(call delete,*.pdb)
|
||||
-@$(call delete,*.manifest)
|
||||
|
||||
help:
|
||||
@echo "Usage: $(MAKE) platform=(os) compiler=(cc) [options]"
|
||||
@echo ""
|
||||
@echo "Supported platforms:"
|
||||
@echo " x - Linux / BSD (x86, x86-64)"
|
||||
@echo " win - Windows (x86, x86-64)"
|
||||
@echo ""
|
||||
@echo "Supported compilers:"
|
||||
@echo " gcc - GCC compiler"
|
||||
@echo " mingw32-gcc - MinGW compiler"
|
||||
@echo " i586-mingw32-gcc - MinGW cross compiler"
|
||||
@echo " cl - Visual C++"
|
||||
@echo ""
|
||||
@echo "Available options:"
|
||||
@echo " enable_gzip=[true|false] - Enable ZIP / GZ support (default=false)"
|
||||
@echo " enable_jma=[true|false] - Enable JMA support (default=false)"
|
||||
@echo ""
|
||||
@echo "Example: $(MAKE) platform=x compiler=gcc enable_gzip=true"
|
||||
@echo ""
|
||||
+51
-16
@@ -1,16 +1,51 @@
|
||||
#include "lib/libbase.h"
|
||||
|
||||
//structs
|
||||
typedef struct {
|
||||
uint8 *data;
|
||||
uint32 size;
|
||||
}lfile;
|
||||
|
||||
//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, ...);
|
||||
|
||||
//various class interfaces
|
||||
#include "interface.h"
|
||||
#define BSNES_VERSION "0.030"
|
||||
#define BSNES_TITLE "bsnes v" BSNES_VERSION
|
||||
|
||||
#define BUSCORE sBus
|
||||
#define CPUCORE sCPU
|
||||
#define SMPCORE sSMP
|
||||
#define DSPCORE sDSP
|
||||
#define PPUCORE bPPU
|
||||
|
||||
//FAST_FRAMESKIP disables calculation of RTO during frameskip
|
||||
//frameskip offers near-zero speedup if RTO is calculated
|
||||
//accuracy is not affected by this define when frameskipping is off
|
||||
#define FAST_FRAMESKIP
|
||||
|
||||
//game genie + pro action replay code support (~1-3% speed hit)
|
||||
#define CHEAT_SYSTEM
|
||||
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/array.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/config.hpp>
|
||||
#include <nall/detect.hpp>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/new.hpp>
|
||||
#include <nall/sort.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
using namespace nall;
|
||||
|
||||
#include <libco/libco.h>
|
||||
#include <bbase.h>
|
||||
|
||||
//platform-specific global functions
|
||||
void alert(const char*, ...);
|
||||
void dprintf(const char*, ...);
|
||||
void dprintf(uint, const char*, ...);
|
||||
|
||||
namespace source {
|
||||
enum {
|
||||
none = 0,
|
||||
debug,
|
||||
cpu,
|
||||
ppu,
|
||||
smp,
|
||||
dsp,
|
||||
bus,
|
||||
};
|
||||
};
|
||||
|
||||
#include "interface.h"
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "../base.h"
|
||||
#define CART_CPP
|
||||
|
||||
#include "cart_normal.cpp"
|
||||
#include "cart_bsx.cpp"
|
||||
#include "cart_bsc.cpp"
|
||||
#include "cart_st.cpp"
|
||||
|
||||
#include "cart_file.cpp"
|
||||
#include "cart_header.cpp"
|
||||
|
||||
namespace memory {
|
||||
MappedRAM cartrom, cartram;
|
||||
MappedRAM bscram;
|
||||
MappedRAM stArom, stAram;
|
||||
MappedRAM stBrom, stBram;
|
||||
};
|
||||
|
||||
Cartridge cartridge;
|
||||
|
||||
Cartridge::MemoryMapper Cartridge::mapper() { return info.mapper; }
|
||||
Cartridge::Region Cartridge::region() { return info.region; }
|
||||
|
||||
bool Cartridge::loaded() { return cart.loaded; }
|
||||
|
||||
void Cartridge::load_begin(CartridgeType cart_type) {
|
||||
cart.rom = cart.ram = 0;
|
||||
bs.ram = 0;
|
||||
stA.rom = stA.ram = 0;
|
||||
stB.rom = stB.ram = 0;
|
||||
|
||||
cart.rom_size = cart.ram_size = 0;
|
||||
bs.ram_size = 0;
|
||||
stA.rom_size = stA.ram_size = 0;
|
||||
stB.rom_size = stB.ram_size = 0;
|
||||
|
||||
info.type = cart_type;
|
||||
|
||||
info.bsxbase = false;
|
||||
info.bsxcart = false;
|
||||
info.bsxflash = false;
|
||||
info.st = false;
|
||||
|
||||
info.superfx = false;
|
||||
info.sa1 = false;
|
||||
info.srtc = false;
|
||||
info.sdd1 = false;
|
||||
info.cx4 = false;
|
||||
info.dsp1 = false;
|
||||
info.dsp2 = false;
|
||||
info.dsp3 = false;
|
||||
info.dsp4 = false;
|
||||
info.obc1 = false;
|
||||
info.st010 = false;
|
||||
info.st011 = false;
|
||||
info.st018 = false;
|
||||
|
||||
info.dsp1_mapper = DSP1Unmapped;
|
||||
|
||||
info.header_index = 0xffc0;
|
||||
info.mapper = LoROM;
|
||||
info.name[0] = 0;
|
||||
info.region = NTSC;
|
||||
|
||||
info.rom_size = 0;
|
||||
info.ram_size = 0;
|
||||
}
|
||||
|
||||
void Cartridge::load_end() {
|
||||
memory::cartrom.map(cart.rom, cart.rom_size);
|
||||
memory::cartram.map(cart.ram, cart.ram_size);
|
||||
memory::bscram.map(bs.ram, bs.ram_size);
|
||||
memory::stArom.map(stA.rom, stA.rom_size);
|
||||
memory::stAram.map(stA.ram, stA.ram_size);
|
||||
memory::stBrom.map(stB.rom, stB.rom_size);
|
||||
memory::stBram.map(stB.ram, stB.ram_size);
|
||||
|
||||
memory::cartrom.write_protect(true);
|
||||
memory::cartram.write_protect(false);
|
||||
memory::bscram.write_protect(true);
|
||||
memory::stArom.write_protect(true);
|
||||
memory::stAram.write_protect(false);
|
||||
memory::stBrom.write_protect(true);
|
||||
memory::stBram.write_protect(false);
|
||||
|
||||
if(fexists(get_cheat_filename(cart.fn, "cht"))) {
|
||||
cheat.clear();
|
||||
cheat.load(cheatfn);
|
||||
}
|
||||
|
||||
cart.loaded = true;
|
||||
bus.load_cart();
|
||||
}
|
||||
|
||||
bool Cartridge::unload() {
|
||||
if(cart.loaded == false) return false;
|
||||
|
||||
bus.unload_cart();
|
||||
|
||||
switch(info.type) {
|
||||
case CartridgeNormal: unload_cart_normal(); break;
|
||||
case CartridgeBSX: unload_cart_bsx(); break;
|
||||
case CartridgeBSC: unload_cart_bsc(); break;
|
||||
case CartridgeSufamiTurbo: unload_cart_st(); break;
|
||||
}
|
||||
|
||||
safe_free(cart.rom);
|
||||
safe_free(cart.ram);
|
||||
safe_free(bs.ram);
|
||||
safe_free(stA.rom);
|
||||
safe_free(stA.ram);
|
||||
safe_free(stB.rom);
|
||||
safe_free(stB.ram);
|
||||
|
||||
char fn[PATH_MAX];
|
||||
strcpy(fn, cart.fn);
|
||||
modify_extension(fn, "cht");
|
||||
if(cheat.count() > 0 || fexists(get_cheat_filename(cart.fn, "cht"))) {
|
||||
cheat.save(cheatfn);
|
||||
cheat.clear();
|
||||
}
|
||||
|
||||
cart.loaded = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
Cartridge::Cartridge() {
|
||||
cart.loaded = false;
|
||||
}
|
||||
|
||||
Cartridge::~Cartridge() {
|
||||
if(cart.loaded == true) unload();
|
||||
}
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
class Cartridge {
|
||||
public:
|
||||
enum CartridgeType {
|
||||
CartridgeNormal,
|
||||
CartridgeBSX,
|
||||
CartridgeBSC,
|
||||
CartridgeSufamiTurbo,
|
||||
};
|
||||
|
||||
enum HeaderField {
|
||||
CART_NAME = 0x00,
|
||||
MAPPER = 0x15,
|
||||
ROM_TYPE = 0x16,
|
||||
ROM_SIZE = 0x17,
|
||||
RAM_SIZE = 0x18,
|
||||
REGION = 0x19,
|
||||
COMPANY = 0x1a,
|
||||
VERSION = 0x1b,
|
||||
ICKSUM = 0x1c,
|
||||
CKSUM = 0x1e,
|
||||
RESL = 0x3c,
|
||||
RESH = 0x3d,
|
||||
};
|
||||
|
||||
enum Region {
|
||||
NTSC,
|
||||
PAL,
|
||||
};
|
||||
|
||||
enum MemoryMapper {
|
||||
LoROM,
|
||||
HiROM,
|
||||
ExLoROM,
|
||||
ExHiROM,
|
||||
BSXROM,
|
||||
BSCLoROM,
|
||||
BSCHiROM,
|
||||
STROM,
|
||||
};
|
||||
|
||||
enum DSP1MemoryMapper {
|
||||
DSP1Unmapped,
|
||||
DSP1LoROM1MB,
|
||||
DSP1LoROM2MB,
|
||||
DSP1HiROM,
|
||||
};
|
||||
|
||||
struct {
|
||||
bool loaded;
|
||||
char fn[PATH_MAX];
|
||||
uint8 *rom, *ram;
|
||||
uint rom_size, ram_size;
|
||||
} cart;
|
||||
|
||||
struct {
|
||||
char fn[PATH_MAX];
|
||||
uint8 *ram;
|
||||
uint ram_size;
|
||||
} bs;
|
||||
|
||||
struct {
|
||||
char fn[PATH_MAX];
|
||||
uint8 *rom, *ram;
|
||||
uint rom_size, ram_size;
|
||||
} stA, stB;
|
||||
|
||||
struct {
|
||||
CartridgeType type;
|
||||
|
||||
uint32 crc32;
|
||||
char filename[PATH_MAX * 4];
|
||||
char name[128];
|
||||
|
||||
Region region;
|
||||
MemoryMapper mapper;
|
||||
uint rom_size;
|
||||
uint ram_size;
|
||||
|
||||
bool bsxbase;
|
||||
bool bsxcart;
|
||||
bool bsxflash;
|
||||
bool st;
|
||||
bool superfx;
|
||||
bool sa1;
|
||||
bool srtc;
|
||||
bool sdd1;
|
||||
bool cx4;
|
||||
bool dsp1;
|
||||
bool dsp2;
|
||||
bool dsp3;
|
||||
bool dsp4;
|
||||
bool obc1;
|
||||
bool st010;
|
||||
bool st011;
|
||||
bool st018;
|
||||
|
||||
DSP1MemoryMapper dsp1_mapper;
|
||||
|
||||
uint header_index;
|
||||
} info;
|
||||
|
||||
MemoryMapper mapper();
|
||||
Region region();
|
||||
|
||||
void load_cart_normal(const char*);
|
||||
void load_cart_bsx(const char*, const char*);
|
||||
void load_cart_bsc(const char*, const char*);
|
||||
void load_cart_st(const char*, const char*, const char*);
|
||||
|
||||
void unload_cart_normal();
|
||||
void unload_cart_bsx();
|
||||
void unload_cart_bsc();
|
||||
void unload_cart_st();
|
||||
|
||||
bool loaded();
|
||||
void load_begin(CartridgeType);
|
||||
void load_end();
|
||||
bool unload();
|
||||
|
||||
void find_header();
|
||||
void read_header();
|
||||
void read_extended_header();
|
||||
|
||||
bool load_file(const char *fn, uint8 *&data, uint &size);
|
||||
bool save_file(const char *fn, uint8 *data, uint size);
|
||||
char* modify_extension(char *filename, const char *extension);
|
||||
char* get_base_filename(char *filename);
|
||||
char* get_path_filename(char *filename, const char *path, const char *source, const char *extension);
|
||||
char* get_save_filename(const char *source, const char *extension);
|
||||
char* get_cheat_filename(const char *source, const char *extension);
|
||||
|
||||
Cartridge();
|
||||
~Cartridge();
|
||||
|
||||
private:
|
||||
char savefn[PATH_MAX];
|
||||
char cheatfn[PATH_MAX];
|
||||
};
|
||||
|
||||
namespace memory {
|
||||
extern MappedRAM cartrom, cartram;
|
||||
extern MappedRAM bscram;
|
||||
extern MappedRAM stArom, stAram;
|
||||
extern MappedRAM stBrom, stBram;
|
||||
};
|
||||
|
||||
extern Cartridge cartridge;
|
||||
@@ -0,0 +1,56 @@
|
||||
#ifdef CART_CPP
|
||||
|
||||
void Cartridge::load_cart_bsc(const char *base, const char *slot) {
|
||||
if(!base || !*base) return;
|
||||
|
||||
strcpy(cart.fn, base);
|
||||
strcpy(bs.fn, slot ? slot : "");
|
||||
load_begin(CartridgeBSC);
|
||||
|
||||
uint8_t *data = 0;
|
||||
unsigned size;
|
||||
load_file(cart.fn, data, size);
|
||||
cart.rom = data, cart.rom_size = size;
|
||||
|
||||
if(*bs.fn) {
|
||||
if(load_file(bs.fn, data, size) == true) {
|
||||
info.bsxflash = true;
|
||||
bs.ram = data, bs.ram_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
find_header();
|
||||
read_header();
|
||||
|
||||
info.mapper = cartridge.info.header_index == 0x7fc0 ? BSCLoROM : BSCHiROM;
|
||||
info.region = NTSC;
|
||||
|
||||
if(info.ram_size > 0) {
|
||||
cart.ram = (uint8*)malloc(cart.ram_size = info.ram_size);
|
||||
memset(cart.ram, 0xff, cart.ram_size);
|
||||
|
||||
if(load_file(get_save_filename(cart.fn, "srm"), data, size) == true) {
|
||||
memcpy(cart.ram, data, min(size, cart.ram_size));
|
||||
safe_free(data);
|
||||
}
|
||||
}
|
||||
|
||||
load_end();
|
||||
|
||||
//set base filename
|
||||
strcpy(info.filename, cart.fn);
|
||||
get_base_filename(info.filename);
|
||||
if(*bs.fn) {
|
||||
char filenameBS[PATH_MAX];
|
||||
strcpy(filenameBS, bs.fn);
|
||||
get_base_filename(filenameBS);
|
||||
strcat(info.filename, " + ");
|
||||
strcat(info.filename, filenameBS);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::unload_cart_bsc() {
|
||||
if(cart.ram) save_file(get_save_filename(cart.fn, "srm"), cart.ram, cart.ram_size);
|
||||
}
|
||||
|
||||
#endif //ifdef CART_CPP
|
||||
@@ -0,0 +1,52 @@
|
||||
#ifdef CART_CPP
|
||||
|
||||
void Cartridge::load_cart_bsx(const char *base, const char *slot) {
|
||||
if(!base || !*base) return;
|
||||
|
||||
strcpy(cart.fn, base);
|
||||
strcpy(bs.fn, slot ? slot : "");
|
||||
|
||||
load_begin(CartridgeBSX);
|
||||
info.bsxbase = true;
|
||||
info.bsxcart = true;
|
||||
info.mapper = BSXROM;
|
||||
info.region = NTSC;
|
||||
|
||||
uint8_t *data = 0;
|
||||
unsigned size;
|
||||
load_file(cart.fn, data, size);
|
||||
cart.rom = data, cart.rom_size = size;
|
||||
cart.ram = 0, cart.ram_size = 0;
|
||||
|
||||
memset(bsxcart.sram.handle (), 0x00, bsxcart.sram.size ());
|
||||
memset(bsxcart.psram.handle(), 0x00, bsxcart.psram.size());
|
||||
|
||||
if(load_file(get_save_filename(cart.fn, "srm"), data, size) == true) {
|
||||
memcpy(bsxcart.sram.handle (), data, min(bsxcart.sram.size (), size));
|
||||
safe_free(data);
|
||||
}
|
||||
|
||||
if(load_file(get_save_filename(cart.fn, "psr"), data, size) == true) {
|
||||
memcpy(bsxcart.psram.handle(), data, min(bsxcart.psram.size(), size));
|
||||
safe_free(data);
|
||||
}
|
||||
|
||||
if(*bs.fn) {
|
||||
if(load_file(bs.fn, data, size) == true) {
|
||||
info.bsxflash = true;
|
||||
bs.ram = data, bs.ram_size = size;
|
||||
}
|
||||
}
|
||||
|
||||
load_end();
|
||||
|
||||
strcpy(info.filename, !*bs.fn ? cart.fn : bs.fn);
|
||||
get_base_filename(info.filename);
|
||||
}
|
||||
|
||||
void Cartridge::unload_cart_bsx() {
|
||||
save_file(get_save_filename(cart.fn, "srm"), bsxcart.sram.handle (), bsxcart.sram.size ());
|
||||
save_file(get_save_filename(cart.fn, "psr"), bsxcart.psram.handle(), bsxcart.psram.size());
|
||||
}
|
||||
|
||||
#endif //ifdef CART_CPP
|
||||
@@ -0,0 +1,144 @@
|
||||
#ifdef CART_CPP
|
||||
|
||||
#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
|
||||
|
||||
char* Cartridge::modify_extension(char *filename, const char *extension) {
|
||||
int i;
|
||||
for(i = strlen(filename); i >= 0; i--) {
|
||||
if(filename[i] == '.') break;
|
||||
if(filename[i] == '/') break;
|
||||
if(filename[i] == '\\') break;
|
||||
}
|
||||
if(i > 0 && filename[i] == '.') filename[i] = 0;
|
||||
strcat(filename, ".");
|
||||
strcat(filename, extension);
|
||||
return filename;
|
||||
}
|
||||
|
||||
//remove directory information and file extension ("/foo/bar.ext" -> "bar")
|
||||
char* Cartridge::get_base_filename(char *filename) {
|
||||
//remove extension
|
||||
for(int i = strlen(filename) - 1; i >= 0; i--) {
|
||||
if(filename[i] == '.') {
|
||||
filename[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//remove directory information
|
||||
for(int i = strlen(filename) - 1; i >= 0; i--) {
|
||||
if(filename[i] == '/' || filename[i] == '\\') {
|
||||
i++;
|
||||
char *output = filename;
|
||||
while(true) {
|
||||
*output++ = filename[i];
|
||||
if(!filename[i]) break;
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char* Cartridge::get_path_filename(char *filename, const char *path, const char *source, const char *extension) {
|
||||
strcpy(filename, source);
|
||||
for(char *p = filename; *p; p++) { if(*p == '\\') *p = '/'; }
|
||||
modify_extension(filename, extension);
|
||||
|
||||
//override path with user-specified folder, if one was defined
|
||||
if(*path) {
|
||||
lstring part;
|
||||
split(part, "/", filename);
|
||||
string fn = path;
|
||||
if(strend(fn, "/") == false) strcat(fn, "/");
|
||||
strcat(fn, part[count(part) - 1]);
|
||||
strcpy(filename, fn);
|
||||
|
||||
//resolve relative path, if found
|
||||
if(strbegin(fn, "./") == true) {
|
||||
ltrim(fn, "./");
|
||||
strcpy(filename, config::path.base);
|
||||
strcat(filename, fn);
|
||||
}
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
char* Cartridge::get_save_filename(const char *source, const char *extension) {
|
||||
return get_path_filename(savefn, config::path.save, source, extension);
|
||||
}
|
||||
|
||||
char* Cartridge::get_cheat_filename(const char *source, const char *extension) {
|
||||
return get_path_filename(cheatfn, config::path.cheat, source, extension);
|
||||
}
|
||||
|
||||
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)) {
|
||||
default:
|
||||
case Reader::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::GZIP: {
|
||||
GZReader gf(fn);
|
||||
if(!gf.ready()) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
size = gf.size();
|
||||
data = gf.read();
|
||||
} break;
|
||||
|
||||
case Reader::ZIP: {
|
||||
ZipReader zf(fn);
|
||||
size = zf.size();
|
||||
data = zf.read();
|
||||
} break;
|
||||
#endif
|
||||
|
||||
#ifdef JMA_SUPPORT
|
||||
case Reader::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;
|
||||
}
|
||||
|
||||
#endif //ifdef CART_CPP
|
||||
@@ -0,0 +1,189 @@
|
||||
#ifdef CART_CPP
|
||||
|
||||
void Cartridge::read_header() {
|
||||
uint8 *rom = cart.rom;
|
||||
uint index = info.header_index;
|
||||
uint8 mapper = rom[index + MAPPER];
|
||||
uint8 rom_type = rom[index + ROM_TYPE];
|
||||
uint8 company = rom[index + COMPANY];
|
||||
uint8 region = rom[index + REGION] & 0x7f;
|
||||
|
||||
//detect presence of BS-X flash cartridge connector (reads extended header information)
|
||||
bool has_bsxflash = false;
|
||||
if(rom[index - 14] == 'Z') {
|
||||
if(rom[index - 11] == 'J') {
|
||||
uint8 n13 = rom[index - 13];
|
||||
if((n13 >= 'A' && n13 <= 'Z') || (n13 >= '0' && n13 <= '9')) {
|
||||
if(company == 0x33 || (rom[index - 10] == 0x00 && rom[index - 4] == 0x00)) {
|
||||
has_bsxflash = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(has_bsxflash == true) {
|
||||
info.mapper = index == 0x7fc0 ? BSCLoROM : BSCHiROM;
|
||||
} else if(index == 0x7fc0 && cart.rom_size >= 0x401000) {
|
||||
info.mapper = ExLoROM;
|
||||
} else if(index == 0x7fc0 && mapper == 0x32) {
|
||||
info.mapper = ExLoROM;
|
||||
} else if(index == 0x7fc0) {
|
||||
info.mapper = LoROM;
|
||||
} else if(index == 0xffc0) {
|
||||
info.mapper = HiROM;
|
||||
} else { //index == 0x40ffc0
|
||||
info.mapper = ExHiROM;
|
||||
}
|
||||
|
||||
if(mapper == 0x20 && (rom_type == 0x13 || rom_type == 0x14 || rom_type == 0x15 || rom_type == 0x1a)) {
|
||||
info.superfx = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x23 && (rom_type == 0x34 || rom_type == 0x35)) {
|
||||
info.sa1 = true;
|
||||
}
|
||||
|
||||
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.cx4 = true;
|
||||
}
|
||||
|
||||
if((mapper == 0x20 || mapper == 0x21) && rom_type == 0x03) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x05 && company != 0xb2) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x31 && (rom_type == 0x03 || rom_type == 0x05)) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(info.dsp1 == true) {
|
||||
if((mapper & 0x2f) == 0x20 && cart.rom_size <= 0x100000) {
|
||||
info.dsp1_mapper = DSP1LoROM1MB;
|
||||
} else if((mapper & 0x2f) == 0x20) {
|
||||
info.dsp1_mapper = DSP1LoROM2MB;
|
||||
} else if((mapper & 0x2f) == 0x21) {
|
||||
info.dsp1_mapper = DSP1HiROM;
|
||||
}
|
||||
}
|
||||
|
||||
if(mapper == 0x20 && rom_type == 0x05) {
|
||||
info.dsp2 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x05 && company == 0xb2) {
|
||||
info.dsp3 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x03) {
|
||||
info.dsp4 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x25) {
|
||||
info.obc1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0xf6) {
|
||||
//TODO: both ST010 and ST011 share the same mapper + rom_type.
|
||||
//need way to determine which is which.
|
||||
//for now, default to supported ST010.
|
||||
info.st010 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0xf5) {
|
||||
info.st018 = true;
|
||||
}
|
||||
|
||||
if(rom[info.header_index + RAM_SIZE] & 7) {
|
||||
info.ram_size = 1024 << (rom[info.header_index + RAM_SIZE] & 7);
|
||||
} else {
|
||||
info.ram_size = 0;
|
||||
}
|
||||
|
||||
//0, 1, 13 = NTSC; 2 - 12 = PAL
|
||||
info.region = (region <= 1 || region >= 13) ? NTSC : PAL;
|
||||
|
||||
memcpy(&info.name, &rom[info.header_index + CART_NAME], 21);
|
||||
info.name[21] = 0;
|
||||
trim(info.name);
|
||||
|
||||
//convert undisplayable characters (half-width katakana, etc) to '?' characters
|
||||
for(int i = 0; i < 21; i++) {
|
||||
if(info.name[i] & 0x80) info.name[i] = '?';
|
||||
}
|
||||
|
||||
//always display something
|
||||
if(!info.name[0]) strcpy(info.name, "(untitled)");
|
||||
}
|
||||
|
||||
void Cartridge::find_header() {
|
||||
int32 score_lo = 0, score_hi = 0, score_ex = 0;
|
||||
uint8_t *rom = cart.rom;
|
||||
|
||||
if(cart.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 + COMPANY] < 3) score_lo++;
|
||||
if(rom[0xffc0 + COMPANY] < 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(cart.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;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //ifdef CART_CPP
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifdef CART_CPP
|
||||
|
||||
void Cartridge::load_cart_normal(const char *filename) {
|
||||
if(!filename || !*filename) return;
|
||||
|
||||
uint8_t *data = 0;
|
||||
unsigned size;
|
||||
if(load_file(filename, data, size) == false) return;
|
||||
strcpy(cart.fn, filename);
|
||||
|
||||
load_begin(CartridgeNormal);
|
||||
|
||||
//load ROM data, ignore 512-byte header if detected
|
||||
if((size & 0x7fff) != 512) {
|
||||
cart.rom = (uint8*)malloc(cart.rom_size = size);
|
||||
memcpy(cart.rom, data, size);
|
||||
} else {
|
||||
cart.rom = (uint8*)malloc(cart.rom_size = size - 512);
|
||||
memcpy(cart.rom, data + 512, size - 512);
|
||||
}
|
||||
safe_free(data);
|
||||
|
||||
info.crc32 = crc32_calculate(cart.rom, cart.rom_size);
|
||||
|
||||
find_header();
|
||||
read_header();
|
||||
|
||||
if(info.ram_size > 0) {
|
||||
cart.ram = (uint8*)malloc(cart.ram_size = info.ram_size);
|
||||
memset(cart.ram, 0xff, cart.ram_size);
|
||||
|
||||
if(load_file(get_save_filename(cart.fn, "srm"), data, size) == true) {
|
||||
memcpy(cart.ram, data, min(size, cart.ram_size));
|
||||
safe_free(data);
|
||||
}
|
||||
}
|
||||
|
||||
load_end();
|
||||
|
||||
//set base filename
|
||||
strcpy(info.filename, cart.fn);
|
||||
get_base_filename(info.filename);
|
||||
}
|
||||
|
||||
void Cartridge::unload_cart_normal() {
|
||||
if(cart.ram) save_file(get_save_filename(cart.fn, "srm"), cart.ram, cart.ram_size);
|
||||
}
|
||||
|
||||
#endif //ifdef CART_CPP
|
||||
@@ -0,0 +1,84 @@
|
||||
#ifdef CART_CPP
|
||||
|
||||
void Cartridge::load_cart_st(const char *base, const char *slotA, const char *slotB) {
|
||||
if(!base || !*base) return;
|
||||
|
||||
strcpy(cart.fn, base);
|
||||
strcpy(stA.fn, slotA ? slotA : "");
|
||||
strcpy(stB.fn, slotB ? slotB : "");
|
||||
|
||||
load_begin(CartridgeSufamiTurbo);
|
||||
info.st = true;
|
||||
info.mapper = STROM;
|
||||
info.region = NTSC;
|
||||
|
||||
uint8_t *data = 0;
|
||||
unsigned size;
|
||||
if(load_file(cart.fn, data, size) == true) {
|
||||
cart.rom = (uint8*)malloc(cart.rom_size = 0x040000);
|
||||
memcpy(cart.rom, data, min(size, cart.rom_size));
|
||||
safe_free(data);
|
||||
}
|
||||
|
||||
if(*stA.fn) {
|
||||
if(load_file(stA.fn, data, size) == true) {
|
||||
stA.rom = (uint8*)malloc(stA.rom_size = 0x100000);
|
||||
memcpy(stA.rom, data, min(size, stA.rom_size));
|
||||
safe_free(data);
|
||||
|
||||
stA.ram = (uint8*)malloc(stA.ram_size = 0x020000);
|
||||
memset(stA.ram, 0xff, stA.ram_size);
|
||||
|
||||
if(load_file(get_save_filename(stA.fn, "srm"), data, size) == true) {
|
||||
memcpy(stA.ram, data, min(size, 0x020000U));
|
||||
safe_free(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(*stB.fn) {
|
||||
if(load_file(stB.fn, data, size) == true) {
|
||||
stB.rom = (uint8*)malloc(stB.rom_size = 0x100000);
|
||||
memcpy(stB.rom, data, min(size, stB.rom_size));
|
||||
safe_free(data);
|
||||
|
||||
stB.ram = (uint8*)malloc(stB.ram_size = 0x020000);
|
||||
memset(stB.ram, 0xff, stB.ram_size);
|
||||
|
||||
if(load_file(get_save_filename(stB.fn, "srm"), data, size) == true) {
|
||||
memcpy(stB.ram, data, min(size, 0x020000U));
|
||||
safe_free(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
load_end();
|
||||
|
||||
//set base filename
|
||||
if(!*stA.fn && !*stB.fn) {
|
||||
strcpy(info.filename, cart.fn);
|
||||
get_base_filename(info.filename);
|
||||
} else if(*stA.fn && !*stB.fn) {
|
||||
strcpy(info.filename, stA.fn);
|
||||
get_base_filename(info.filename);
|
||||
} else if(!*stA.fn && *stB.fn) {
|
||||
strcpy(info.filename, stB.fn);
|
||||
get_base_filename(info.filename);
|
||||
} else {
|
||||
char filenameA[PATH_MAX], filenameB[PATH_MAX];
|
||||
strcpy(filenameA, stA.fn);
|
||||
get_base_filename(filenameA);
|
||||
strcpy(filenameB, stB.fn);
|
||||
get_base_filename(filenameB);
|
||||
strcpy(info.filename, filenameA);
|
||||
strcat(info.filename, " + ");
|
||||
strcat(info.filename, filenameB);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::unload_cart_st() {
|
||||
if(stA.ram) save_file(get_save_filename(stA.fn, "srm"), stA.ram, stA.ram_size);
|
||||
if(stB.ram) save_file(get_save_filename(stB.fn, "srm"), stB.ram, stB.ram_size);
|
||||
}
|
||||
|
||||
#endif //ifdef CART_CPP
|
||||
@@ -0,0 +1,3 @@
|
||||
::@make platform=win compiler=mingw32-gcc
|
||||
@make platform=win compiler=mingw32-gcc enable_gzip=true enable_jma=true
|
||||
@pause
|
||||
@@ -0,0 +1,2 @@
|
||||
make platform=x compiler=gcc
|
||||
#make platform=x compiler=gcc enable_gzip=true enable_jma=true
|
||||
@@ -0,0 +1,329 @@
|
||||
#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) {
|
||||
string t, part;
|
||||
strcpy(t, str);
|
||||
strlower(t());
|
||||
if(strlen(t) == 8 || (strlen(t) == 9 && t()[6] == ':')) {
|
||||
type = ProActionReplay;
|
||||
replace(t, ":", "");
|
||||
uint32 r = strhex((const char*)t);
|
||||
addr = r >> 8;
|
||||
data = r & 0xff;
|
||||
return true;
|
||||
} else if(strlen(t) == 9 && t()[4] == '-') {
|
||||
type = GameGenie;
|
||||
replace(t, "-", "");
|
||||
strtr(t, "df4709156bc8a23e", "0123456789abcdef");
|
||||
uint32 r = strhex((const char*)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 == ProActionReplay) {
|
||||
sprintf(str, "%0.6x:%0.2x", addr, data);
|
||||
return true;
|
||||
} else if(type == GameGenie) {
|
||||
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(unsigned 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 >= CheatLimit) 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(unsigned 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
|
||||
*****/
|
||||
|
||||
/* file format: */
|
||||
/* nnnn-nnnn = status, "description" \r\n */
|
||||
/* ... */
|
||||
|
||||
bool Cheat::load(const char *fn) {
|
||||
string data;
|
||||
if(!fread(data, fn)) return false;
|
||||
replace(data, "\r\n", "\n");
|
||||
qreplace(data, "=", ",");
|
||||
qreplace(data, " ", "");
|
||||
|
||||
lstring line;
|
||||
split(line, "\n", data);
|
||||
for(unsigned i = 0; i < ::count(line); i++) {
|
||||
lstring part;
|
||||
split(part, ",", line[i]);
|
||||
if(::count(part) != 3) continue;
|
||||
trim(part[2], "\"");
|
||||
add(part[1] == "enabled", part[0](), part[2]());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cheat::save(const char *fn) {
|
||||
FILE *fp = fopen(fn, "wb");
|
||||
if(!fp) return false;
|
||||
for(unsigned i = 0; i < cheat_count; i++) {
|
||||
fprintf(fp, "%9s = %8s, \"%s\"\r\n",
|
||||
index[i].code,
|
||||
index[i].enabled ? "enabled" : "disabled",
|
||||
index[i].desc);
|
||||
}
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*****
|
||||
* initialization routines
|
||||
*****/
|
||||
|
||||
void Cheat::clear() {
|
||||
cheat_enabled = false;
|
||||
cheat_count = 0;
|
||||
memset(mask, 0, 0x200000);
|
||||
for(unsigned i = 0; i <= CheatLimit; 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,51 @@
|
||||
class Cheat {
|
||||
public:
|
||||
enum { CheatLimit = 1024 };
|
||||
|
||||
enum Type {
|
||||
ProActionReplay,
|
||||
GameGenie,
|
||||
};
|
||||
|
||||
struct CheatIndex {
|
||||
bool enabled;
|
||||
uint32 addr;
|
||||
uint8 data;
|
||||
char code[ 16 + 1];
|
||||
char desc[128 + 1];
|
||||
} index[CheatLimit + 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);
|
||||
|
||||
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();
|
||||
|
||||
private:
|
||||
uint mirror_address(uint addr);
|
||||
void set(uint32 addr);
|
||||
void clear(uint32 addr);
|
||||
};
|
||||
|
||||
extern Cheat cheat;
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "../../base.h"
|
||||
#define BSX_CPP
|
||||
|
||||
#include "bsx_base.cpp"
|
||||
#include "bsx_cart.cpp"
|
||||
#include "bsx_flash.cpp"
|
||||
@@ -0,0 +1,77 @@
|
||||
class BSXBase : public MMIO {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 mmio_read(uint addr);
|
||||
void mmio_write(uint addr, uint8 data);
|
||||
|
||||
private:
|
||||
struct {
|
||||
uint8 r2188, r2189, r218a, r218b;
|
||||
uint8 r218c, r218d, r218e, r218f;
|
||||
uint8 r2190, r2191, r2192, r2193;
|
||||
uint8 r2194, r2195, r2196, r2197;
|
||||
uint8 r2198, r2199, r219a, r219b;
|
||||
uint8 r219c, r219d, r219e, r219f;
|
||||
|
||||
uint8 r2192_counter;
|
||||
uint8 r2192_hour, r2192_minute, r2192_second;
|
||||
} regs;
|
||||
};
|
||||
|
||||
class BSXCart : public MMIO {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 mmio_read(uint addr);
|
||||
void mmio_write(uint addr, uint8 data);
|
||||
|
||||
MappedRAM sram;
|
||||
MappedRAM psram;
|
||||
|
||||
BSXCart();
|
||||
~BSXCart();
|
||||
|
||||
private:
|
||||
uint8 *sram_data; //256kbit SRAM
|
||||
uint8 *psram_data; // 4mbit PSRAM
|
||||
|
||||
struct {
|
||||
uint8 r[16];
|
||||
} regs;
|
||||
|
||||
void update_memory_map();
|
||||
};
|
||||
|
||||
class BSXFlash : public Memory {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint size();
|
||||
uint8 read(uint addr);
|
||||
void write(uint addr, uint8 data);
|
||||
|
||||
private:
|
||||
struct {
|
||||
uint command;
|
||||
uint8 write_old;
|
||||
uint8 write_new;
|
||||
|
||||
bool flash_enable;
|
||||
bool read_enable;
|
||||
bool write_enable;
|
||||
} regs;
|
||||
};
|
||||
|
||||
extern BSXBase bsxbase;
|
||||
extern BSXCart bsxcart;
|
||||
extern BSXFlash bsxflash;
|
||||
@@ -0,0 +1,137 @@
|
||||
#ifdef BSX_CPP
|
||||
|
||||
void BSXBase::init() {
|
||||
}
|
||||
|
||||
void BSXBase::enable() {
|
||||
for(uint16 i = 0x2188; i <= 0x219f; i++) memory::mmio.map(i, *this);
|
||||
}
|
||||
|
||||
void BSXBase::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void BSXBase::reset() {
|
||||
memset(®s, 0x00, sizeof regs);
|
||||
}
|
||||
|
||||
uint8 BSXBase::mmio_read(uint addr) {
|
||||
addr &= 0xffff;
|
||||
|
||||
switch(addr) {
|
||||
case 0x2188: return regs.r2188;
|
||||
case 0x2189: return regs.r2189;
|
||||
case 0x218a: return regs.r218a;
|
||||
case 0x218c: return regs.r218c;
|
||||
case 0x218e: return regs.r218e;
|
||||
case 0x218f: return regs.r218f;
|
||||
case 0x2190: return regs.r2190;
|
||||
|
||||
case 0x2192: {
|
||||
uint counter = regs.r2192_counter++;
|
||||
if(regs.r2192_counter >= 18) regs.r2192_counter = 0;
|
||||
|
||||
if(counter == 0) {
|
||||
time_t rawtime;
|
||||
time(&rawtime);
|
||||
tm *t = localtime(&rawtime);
|
||||
|
||||
regs.r2192_hour = t->tm_hour;
|
||||
regs.r2192_minute = t->tm_min;
|
||||
regs.r2192_second = t->tm_sec;
|
||||
}
|
||||
|
||||
switch(counter) {
|
||||
case 0: return 0x00; //???
|
||||
case 1: return 0x00; //???
|
||||
case 2: return 0x00; //???
|
||||
case 3: return 0x00; //???
|
||||
case 4: return 0x00; //???
|
||||
case 5: return 0x01;
|
||||
case 6: return 0x01;
|
||||
case 7: return 0x00;
|
||||
case 8: return 0x00;
|
||||
case 9: return 0x00;
|
||||
case 10: return regs.r2192_second;
|
||||
case 11: return regs.r2192_minute;
|
||||
case 12: return regs.r2192_hour;
|
||||
case 13: return 0x00; //???
|
||||
case 14: return 0x00; //???
|
||||
case 15: return 0x00; //???
|
||||
case 16: return 0x00; //???
|
||||
case 17: return 0x00; //???
|
||||
}
|
||||
} break;
|
||||
|
||||
case 0x2193: return regs.r2193 & ~0x0c;
|
||||
case 0x2194: return regs.r2194;
|
||||
case 0x2196: return regs.r2196;
|
||||
case 0x2197: return regs.r2197;
|
||||
case 0x2199: return regs.r2199;
|
||||
}
|
||||
|
||||
return cpu.regs.mdr;
|
||||
}
|
||||
|
||||
void BSXBase::mmio_write(uint addr, uint8 data) {
|
||||
addr &= 0xffff;
|
||||
|
||||
switch(addr) {
|
||||
case 0x2188: {
|
||||
regs.r2188 = data;
|
||||
} break;
|
||||
|
||||
case 0x2189: {
|
||||
regs.r2189 = data;
|
||||
} break;
|
||||
|
||||
case 0x218a: {
|
||||
regs.r218a = data;
|
||||
} break;
|
||||
|
||||
case 0x218b: {
|
||||
regs.r218b = data;
|
||||
} break;
|
||||
|
||||
case 0x218c: {
|
||||
regs.r218c = data;
|
||||
} break;
|
||||
|
||||
case 0x218e: {
|
||||
regs.r218e = data;
|
||||
} break;
|
||||
|
||||
case 0x218f: {
|
||||
regs.r218e >>= 1;
|
||||
regs.r218e = regs.r218f - regs.r218e;
|
||||
regs.r218f >>= 1;
|
||||
} break;
|
||||
|
||||
case 0x2191: {
|
||||
regs.r2191 = data;
|
||||
regs.r2192_counter = 0;
|
||||
} break;
|
||||
|
||||
case 0x2192: {
|
||||
regs.r2190 = 0x80;
|
||||
} break;
|
||||
|
||||
case 0x2193: {
|
||||
regs.r2193 = data;
|
||||
} break;
|
||||
|
||||
case 0x2194: {
|
||||
regs.r2194 = data;
|
||||
} break;
|
||||
|
||||
case 0x2197: {
|
||||
regs.r2197 = data;
|
||||
} break;
|
||||
|
||||
case 0x2199: {
|
||||
regs.r2199 = data;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //ifdef BSX_CPP
|
||||
@@ -0,0 +1,99 @@
|
||||
#ifdef BSX_CPP
|
||||
|
||||
void BSXCart::init() {
|
||||
}
|
||||
|
||||
void BSXCart::enable() {
|
||||
for(uint16 i = 0x5000; i <= 0x5fff; i++) memory::mmio.map(i, *this);
|
||||
}
|
||||
|
||||
void BSXCart::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void BSXCart::reset() {
|
||||
for(uint i = 0; i < 16; i++) regs.r[i] = 0x00;
|
||||
regs.r[0x07] = 0x80;
|
||||
regs.r[0x08] = 0x80;
|
||||
|
||||
update_memory_map();
|
||||
}
|
||||
|
||||
void BSXCart::update_memory_map() {
|
||||
Memory &cart = (regs.r[0x01] & 0x80) == 0x00 ? (Memory&)bsxflash : (Memory&)psram;
|
||||
|
||||
if((regs.r[0x02] & 0x80) == 0x00) { //LoROM mapping
|
||||
bus.map(Bus::MapLinear, 0x00, 0x7d, 0x8000, 0xffff, cart);
|
||||
bus.map(Bus::MapLinear, 0x80, 0xff, 0x8000, 0xffff, cart);
|
||||
} else { //HiROM mapping
|
||||
bus.map(Bus::MapShadow, 0x00, 0x3f, 0x8000, 0xffff, cart);
|
||||
bus.map(Bus::MapLinear, 0x40, 0x7d, 0x0000, 0xffff, cart);
|
||||
bus.map(Bus::MapShadow, 0x80, 0xbf, 0x8000, 0xffff, cart);
|
||||
bus.map(Bus::MapLinear, 0xc0, 0xff, 0x0000, 0xffff, cart);
|
||||
}
|
||||
|
||||
if(regs.r[0x03] & 0x80) {
|
||||
bus.map(Bus::MapLinear, 0x60, 0x6f, 0x0000, 0xffff, psram);
|
||||
//bus.map(Bus::MapLinear, 0x70, 0x77, 0x0000, 0xffff, psram);
|
||||
}
|
||||
|
||||
if((regs.r[0x05] & 0x80) == 0x00) {
|
||||
bus.map(Bus::MapLinear, 0x40, 0x4f, 0x0000, 0xffff, psram);
|
||||
}
|
||||
|
||||
if((regs.r[0x06] & 0x80) == 0x00) {
|
||||
bus.map(Bus::MapLinear, 0x50, 0x5f, 0x0000, 0xffff, psram);
|
||||
}
|
||||
|
||||
if(regs.r[0x07] & 0x80) {
|
||||
bus.map(Bus::MapLinear, 0x00, 0x1f, 0x8000, 0xffff, memory::cartrom);
|
||||
}
|
||||
|
||||
if(regs.r[0x08] & 0x80) {
|
||||
bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom);
|
||||
}
|
||||
|
||||
bus.map(Bus::MapShadow, 0x20, 0x3f, 0x6000, 0x7fff, psram);
|
||||
bus.map(Bus::MapLinear, 0x70, 0x77, 0x0000, 0xffff, psram);
|
||||
}
|
||||
|
||||
uint8 BSXCart::mmio_read(uint addr) {
|
||||
if((addr & 0xf0ffff) == 0x005000) { //$[00-0f]:5000 MMIO
|
||||
uint8 n = (addr >> 16) & 15;
|
||||
return regs.r[n];
|
||||
}
|
||||
|
||||
if((addr & 0xf8f000) == 0x105000) { //$[10-17]:[5000-5fff] SRAM
|
||||
return sram.read(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff));
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void BSXCart::mmio_write(uint addr, uint8 data) {
|
||||
if((addr & 0xf0ffff) == 0x005000) { //$[00-0f]:5000 MMIO
|
||||
uint8 n = (addr >> 16) & 15;
|
||||
regs.r[n] = data;
|
||||
if(n == 0x0e && data & 0x80) update_memory_map();
|
||||
return;
|
||||
}
|
||||
|
||||
if((addr & 0xf8f000) == 0x105000) { //$[10-17]:[5000-5fff] SRAM
|
||||
return sram.write(((addr >> 16) & 7) * 0x1000 + (addr & 0xfff), data);
|
||||
}
|
||||
}
|
||||
|
||||
BSXCart::BSXCart() {
|
||||
sram_data = (uint8*)malloc( 32 * 1024);
|
||||
psram_data = (uint8*)malloc(512 * 1024);
|
||||
|
||||
sram.map (sram_data, 32 * 1024);
|
||||
psram.map(psram_data, 512 * 1024);
|
||||
}
|
||||
|
||||
BSXCart::~BSXCart() {
|
||||
safe_free(sram_data);
|
||||
safe_free(psram_data);
|
||||
}
|
||||
|
||||
#endif //ifdef BSX_CPP
|
||||
@@ -0,0 +1,113 @@
|
||||
#ifdef BSX_CPP
|
||||
|
||||
void BSXFlash::init() {}
|
||||
void BSXFlash::enable() {}
|
||||
|
||||
void BSXFlash::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void BSXFlash::reset() {
|
||||
regs.command = 0;
|
||||
regs.write_old = 0x00;
|
||||
regs.write_new = 0x00;
|
||||
|
||||
regs.flash_enable = false;
|
||||
regs.read_enable = false;
|
||||
regs.write_enable = false;
|
||||
}
|
||||
|
||||
uint BSXFlash::size() {
|
||||
return memory::bscram.size();
|
||||
}
|
||||
|
||||
uint8 BSXFlash::read(uint addr) {
|
||||
if(addr == 0x0002) {
|
||||
if(regs.flash_enable) return 0x80;
|
||||
}
|
||||
|
||||
if(addr == 0x5555) {
|
||||
if(regs.flash_enable) return 0x80;
|
||||
}
|
||||
|
||||
if(regs.read_enable && addr >= 0xff00 && addr <= 0xff13) {
|
||||
//read flash cartridge vendor information
|
||||
switch(addr - 0xff00) {
|
||||
case 0x00: return 0x4d;
|
||||
case 0x01: return 0x00;
|
||||
case 0x02: return 0x50;
|
||||
case 0x03: return 0x00;
|
||||
case 0x04: return 0x00;
|
||||
case 0x05: return 0x00;
|
||||
case 0x06: return 0x2a; //0x2a = 8mbit, 0x2b = 16mbit (not known to exist, though BIOS recognizes ID)
|
||||
case 0x07: return 0x00;
|
||||
default: return 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
return memory::bscram.read(addr);
|
||||
}
|
||||
|
||||
void BSXFlash::write(uint addr, uint8 data) {
|
||||
//there exist both read-only and read-write BS-X flash cartridges ...
|
||||
//unfortunately, the vendor info is not stored inside memory dumps
|
||||
//of BS-X flashcarts, so it is impossible to determine whether a
|
||||
//given flashcart is writeable.
|
||||
//however, it has been observed that LoROM-mapped BS-X carts always
|
||||
//use read-write flashcarts, and HiROM-mapped BS-X carts always use
|
||||
//read-only flashcarts.
|
||||
//below is an unfortunately necessary workaround to this problem.
|
||||
if(cartridge.mapper() == Cartridge::BSCHiROM) return;
|
||||
|
||||
if((addr & 0xff0000) == 0) {
|
||||
regs.write_old = regs.write_new;
|
||||
regs.write_new = data;
|
||||
|
||||
if(regs.write_enable && regs.write_old == regs.write_new) {
|
||||
return memory::bscram.write(addr, data);
|
||||
}
|
||||
} else {
|
||||
if(regs.write_enable) {
|
||||
return memory::bscram.write(addr, data);
|
||||
}
|
||||
}
|
||||
|
||||
if(addr == 0x0000) {
|
||||
regs.command <<= 8;
|
||||
regs.command |= data;
|
||||
|
||||
if((regs.command & 0xffff) == 0x38d0) {
|
||||
regs.flash_enable = true;
|
||||
regs.read_enable = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(addr == 0x2aaa) {
|
||||
regs.command <<= 8;
|
||||
regs.command |= data;
|
||||
}
|
||||
|
||||
if(addr == 0x5555) {
|
||||
regs.command <<= 8;
|
||||
regs.command |= data;
|
||||
|
||||
if((regs.command & 0xffffff) == 0xaa5570) {
|
||||
regs.write_enable = false;
|
||||
}
|
||||
|
||||
if((regs.command & 0xffffff) == 0xaa55a0) {
|
||||
regs.write_old = 0x00;
|
||||
regs.write_new = 0x00;
|
||||
regs.flash_enable = true;
|
||||
regs.write_enable = true;
|
||||
}
|
||||
|
||||
if((regs.command & 0xffffff) == 0xaa55f0) {
|
||||
regs.flash_enable = false;
|
||||
regs.read_enable = false;
|
||||
regs.write_enable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif //ifdef BSX_CPP
|
||||
@@ -0,0 +1,10 @@
|
||||
#include "bsx/bsx.h"
|
||||
#include "srtc/srtc.h"
|
||||
#include "sdd1/sdd1.h"
|
||||
#include "cx4/cx4.h"
|
||||
#include "dsp1/dsp1.h"
|
||||
#include "dsp2/dsp2.h"
|
||||
#include "dsp3/dsp3.h"
|
||||
#include "dsp4/dsp4.h"
|
||||
#include "obc1/obc1.h"
|
||||
#include "st010/st010.h"
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
C4 emulation
|
||||
|
||||
Used in Rockman X2/X3 (Megaman X2/X3)
|
||||
Portions (c) anomie, Overload, zsKnight, Nach, byuu
|
||||
*/
|
||||
|
||||
#include "../../base.h"
|
||||
#define CX4_CPP
|
||||
|
||||
#include "cx4data.cpp"
|
||||
#include "cx4fn.cpp"
|
||||
#include "cx4oam.cpp"
|
||||
#include "cx4ops.cpp"
|
||||
|
||||
void Cx4::init() {}
|
||||
void Cx4::enable() {}
|
||||
|
||||
uint32 Cx4::ldr(uint8 r) {
|
||||
uint16 addr = 0x0080 + (r * 3);
|
||||
return (reg[addr]) | (reg[addr + 1] << 8) | (reg[addr + 2] << 16);
|
||||
}
|
||||
|
||||
void Cx4::str(uint8 r, uint32 data) {
|
||||
uint16 addr = 0x0080 + (r * 3);
|
||||
reg[addr ] = (data);
|
||||
reg[addr + 1] = (data >> 8);
|
||||
reg[addr + 2] = (data >> 16);
|
||||
}
|
||||
|
||||
void Cx4::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 Cx4::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 Cx4::cos(uint32 rx) {
|
||||
return sin(rx + 0x080);
|
||||
}
|
||||
|
||||
void Cx4::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 Cx4::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++, bus.read(src++));
|
||||
}
|
||||
}
|
||||
|
||||
void Cx4::write(uint 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 Cx4::writeb(uint16 addr, uint8 data) {
|
||||
write(addr, data);
|
||||
}
|
||||
|
||||
void Cx4::writew(uint16 addr, uint16 data) {
|
||||
write(addr, data);
|
||||
write(addr + 1, data >> 8);
|
||||
}
|
||||
|
||||
void Cx4::writel(uint16 addr, uint32 data) {
|
||||
write(addr, data);
|
||||
write(addr + 1, data >> 8);
|
||||
write(addr + 2, data >> 16);
|
||||
}
|
||||
|
||||
uint8 Cx4::read(uint addr) {
|
||||
addr &= 0x1fff;
|
||||
|
||||
if(addr < 0x0c00) {
|
||||
return ram[addr];
|
||||
}
|
||||
|
||||
if(addr >= 0x1f00) {
|
||||
return reg[addr & 0xff];
|
||||
}
|
||||
|
||||
return cpu.regs.mdr;
|
||||
}
|
||||
|
||||
uint8 Cx4::readb(uint16 addr) {
|
||||
return read(addr);
|
||||
}
|
||||
|
||||
uint16 Cx4::readw(uint16 addr) {
|
||||
return read(addr) | (read(addr + 1) << 8);
|
||||
}
|
||||
|
||||
uint32 Cx4::readl(uint16 addr) {
|
||||
return read(addr) | (read(addr + 1) << 8) + (read(addr + 2) << 16);
|
||||
}
|
||||
|
||||
void Cx4::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void Cx4::reset() {
|
||||
memset(ram, 0, 0x0c00);
|
||||
memset(reg, 0, 0x0100);
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
class Cx4 : public Memory {
|
||||
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();
|
||||
|
||||
uint8 readb(uint16 addr);
|
||||
uint16 readw(uint16 addr);
|
||||
uint32 readl(uint16 addr);
|
||||
|
||||
void writeb(uint16 addr, uint8 data);
|
||||
void writew(uint16 addr, uint16 data);
|
||||
void writel(uint16 addr, uint32 data);
|
||||
|
||||
//
|
||||
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 read (uint addr);
|
||||
void write(uint addr, uint8 data);
|
||||
};
|
||||
|
||||
extern Cx4 cx4;
|
||||
@@ -0,0 +1,187 @@
|
||||
#ifdef CX4_CPP
|
||||
|
||||
const uint8 Cx4::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 Cx4::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 Cx4::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 Cx4::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 Cx4::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
|
||||
};
|
||||
|
||||
#endif //ifdef CX4_CPP
|
||||
@@ -0,0 +1,246 @@
|
||||
#ifdef CX4_CPP
|
||||
|
||||
#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 Cx4::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 Cx4::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 Cx4::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 Cx4::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(bus.read(line) == 0xff && bus.read(line + 1) == 0xff) {
|
||||
int32 tmp = line - 5;
|
||||
while(bus.read(tmp + 2) == 0xff && bus.read(tmp + 3) == 0xff && (tmp + 2) >= 0) { tmp -= 5; }
|
||||
point1 = (read(0x1f82) << 16) | (bus.read(tmp + 2) << 8) | bus.read(tmp + 3);
|
||||
} else {
|
||||
point1 = (read(0x1f82) << 16) | (bus.read(line) << 8) | bus.read(line + 1);
|
||||
}
|
||||
point2 = (read(0x1f82) << 16) | (bus.read(line + 2) << 8) | bus.read(line + 3);
|
||||
|
||||
X1=(bus.read(point1 + 0) << 8) | bus.read(point1 + 1);
|
||||
Y1=(bus.read(point1 + 2) << 8) | bus.read(point1 + 3);
|
||||
Z1=(bus.read(point1 + 4) << 8) | bus.read(point1 + 5);
|
||||
X2=(bus.read(point2 + 0) << 8) | bus.read(point2 + 1);
|
||||
Y2=(bus.read(point2 + 2) << 8) | bus.read(point2 + 3);
|
||||
Z2=(bus.read(point2 + 4) << 8) | bus.read(point2 + 5);
|
||||
Color = bus.read(line + 4);
|
||||
C4DrawLine(X1, Y1, Z1, X2, Y2, Z2, Color);
|
||||
}
|
||||
}
|
||||
|
||||
void Cx4::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 Cx4::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;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //ifdef CX4_CPP
|
||||
@@ -0,0 +1,223 @@
|
||||
#ifdef CX4_CPP
|
||||
|
||||
//Build OAM
|
||||
void Cx4::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(bus.read(spraddr)) {
|
||||
int16 x, y;
|
||||
for(int sprcnt = bus.read(spraddr++); sprcnt > 0 && sprcount > 0; sprcnt--, spraddr += 4) {
|
||||
x = (int8)bus.read(spraddr + 1);
|
||||
if(sprattr & 0x40) {
|
||||
x = -x - ((bus.read(spraddr) & 0x20) ? 16 : 8);
|
||||
}
|
||||
x += sprx;
|
||||
if(x >= -16 && x <= 272) {
|
||||
y = (int8)bus.read(spraddr + 2);
|
||||
if(sprattr & 0x80) {
|
||||
y = -y - ((bus.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 + bus.read(spraddr + 3);
|
||||
ram[oamptr + 3] = sprattr ^ (bus.read(spraddr) & 0xc0);
|
||||
ram[oamptr2] &= ~(3 << offset);
|
||||
if(x & 0x100)ram[oamptr2] |= 1 << offset;
|
||||
if(bus.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 Cx4::op00_03() {
|
||||
C4DoScaleRotate(0);
|
||||
}
|
||||
|
||||
//Transform Lines
|
||||
void Cx4::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 Cx4::op00_07() {
|
||||
C4DoScaleRotate(64);
|
||||
}
|
||||
|
||||
//Draw Wireframe
|
||||
void Cx4::op00_08() {
|
||||
C4DrawWireFrame();
|
||||
}
|
||||
|
||||
//Disintegrate
|
||||
void Cx4::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 Cx4::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;
|
||||
}
|
||||
}
|
||||
|
||||
#endif //ifdef CX4_CPP
|
||||
@@ -0,0 +1,226 @@
|
||||
#ifdef CX4_CPP
|
||||
|
||||
//Sprite Functions
|
||||
void Cx4::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 Cx4::op01() {
|
||||
memset(ram + 0x300, 0, 2304);
|
||||
C4DrawWireFrame();
|
||||
}
|
||||
|
||||
//Propulsion
|
||||
void Cx4::op05() {
|
||||
int32 temp = 0x10000;
|
||||
if(readw(0x1f83)) {
|
||||
temp = sar((temp / readw(0x1f83)) * readw(0x1f81), 8);
|
||||
}
|
||||
writew(0x1f80, temp);
|
||||
}
|
||||
|
||||
//Set Vector length
|
||||
void Cx4::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 Cx4::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 Cx4::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 Cx4::op15() {
|
||||
C41FXVal = readw(0x1f80);
|
||||
C41FYVal = readw(0x1f83);
|
||||
C41FDist = (int16)sqrt((double)C41FXVal * (double)C41FXVal + (double)C41FYVal * (double)C41FYVal);
|
||||
writew(0x1f80, C41FDist);
|
||||
}
|
||||
|
||||
//Calculate distance
|
||||
void Cx4::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 Cx4::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 Cx4::op25() {
|
||||
r0 = ldr(0);
|
||||
r1 = ldr(1);
|
||||
mul(r0, r1, r0, r1);
|
||||
str(0, r0);
|
||||
str(1, r1);
|
||||
}
|
||||
|
||||
//Transform Coords
|
||||
void Cx4::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 Cx4::op40() {
|
||||
r0 = 0;
|
||||
for(uint32 i=0;i<0x800;i++) {
|
||||
r0 += ram[i];
|
||||
}
|
||||
str(0, r0);
|
||||
}
|
||||
|
||||
//Square
|
||||
void Cx4::op54() {
|
||||
r0 = ldr(0);
|
||||
mul(r0, r0, r1, r2);
|
||||
str(1, r1);
|
||||
str(2, r2);
|
||||
}
|
||||
|
||||
//Immediate Register
|
||||
void Cx4::op5c() {
|
||||
str(0, 0x000000);
|
||||
immediate_reg(0);
|
||||
}
|
||||
|
||||
//Immediate Register (Multiple)
|
||||
void Cx4::op5e() { immediate_reg( 0); }
|
||||
void Cx4::op60() { immediate_reg( 3); }
|
||||
void Cx4::op62() { immediate_reg( 6); }
|
||||
void Cx4::op64() { immediate_reg( 9); }
|
||||
void Cx4::op66() { immediate_reg(12); }
|
||||
void Cx4::op68() { immediate_reg(15); }
|
||||
void Cx4::op6a() { immediate_reg(18); }
|
||||
void Cx4::op6c() { immediate_reg(21); }
|
||||
void Cx4::op6e() { immediate_reg(24); }
|
||||
void Cx4::op70() { immediate_reg(27); }
|
||||
void Cx4::op72() { immediate_reg(30); }
|
||||
void Cx4::op74() { immediate_reg(33); }
|
||||
void Cx4::op76() { immediate_reg(36); }
|
||||
void Cx4::op78() { immediate_reg(39); }
|
||||
void Cx4::op7a() { immediate_reg(42); }
|
||||
void Cx4::op7c() { immediate_reg(45); }
|
||||
|
||||
//Immediate ROM
|
||||
void Cx4::op89() {
|
||||
str(0, 0x054336);
|
||||
str(1, 0xffffff);
|
||||
}
|
||||
|
||||
#endif //ifdef CX4_CPP
|
||||
@@ -0,0 +1,57 @@
|
||||
#include "../../base.h"
|
||||
#define DSP1_CPP
|
||||
|
||||
#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::DSP1LoROM1MB: {
|
||||
//$[20-3f]:[8000-bfff] = DR, $[20-3f]:[c000-ffff] = SR
|
||||
return (addr >= 0xc000);
|
||||
}
|
||||
|
||||
case Cartridge::DSP1LoROM2MB: {
|
||||
//$[60-6f]:[0000-3fff] = DR, $[60-6f]:[4000-7fff] = SR
|
||||
return (addr >= 0x4000);
|
||||
}
|
||||
|
||||
case Cartridge::DSP1HiROM: {
|
||||
//$[00-1f]:[6000-6fff] = DR, $[00-1f]:[7000-7fff] = SR
|
||||
return (addr >= 0x7000);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8 DSP1::read(uint addr) {
|
||||
return (addr_decode(addr) == 0) ? dsp1.getDr() : dsp1.getSr();
|
||||
}
|
||||
|
||||
void DSP1::write(uint addr, uint8 data) {
|
||||
if(addr_decode(addr) == 0) {
|
||||
dsp1.setDr(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "dsp1emu.h"
|
||||
|
||||
class DSP1 : public Memory {
|
||||
private:
|
||||
Dsp1 dsp1;
|
||||
bool addr_decode(uint16 addr);
|
||||
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 read(uint addr);
|
||||
void write(uint 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,135 @@
|
||||
#include "../../base.h"
|
||||
#define DSP2_CPP
|
||||
|
||||
#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(uint 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(uint 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,44 @@
|
||||
class DSP2 : public Memory {
|
||||
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();
|
||||
|
||||
uint8 read(uint addr);
|
||||
void write(uint addr, uint8 data);
|
||||
|
||||
DSP2();
|
||||
~DSP2();
|
||||
|
||||
protected:
|
||||
void op01();
|
||||
void op03();
|
||||
void op05();
|
||||
void op06();
|
||||
void op09();
|
||||
void op0d();
|
||||
};
|
||||
|
||||
extern DSP2 dsp2;
|
||||
@@ -0,0 +1,177 @@
|
||||
#ifdef DSP2_CPP
|
||||
|
||||
//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];
|
||||
}
|
||||
}
|
||||
|
||||
#endif //ifdef DSP2_CPP
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "../../base.h"
|
||||
#define DSP3_CPP
|
||||
|
||||
namespace DSP3i {
|
||||
#define bool8 uint8
|
||||
#include "dsp3emu.c"
|
||||
#undef bool8
|
||||
};
|
||||
|
||||
void DSP3::init() {
|
||||
}
|
||||
|
||||
void DSP3::enable() {
|
||||
}
|
||||
|
||||
void DSP3::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void DSP3::reset() {
|
||||
DSP3i::DSP3_Reset();
|
||||
}
|
||||
|
||||
uint8 DSP3::read(uint addr) {
|
||||
DSP3i::dsp3_address = addr & 0xffff;
|
||||
DSP3i::DSP3GetByte();
|
||||
return DSP3i::dsp3_byte;
|
||||
}
|
||||
|
||||
void DSP3::write(uint addr, uint8 data) {
|
||||
DSP3i::dsp3_address = addr & 0xffff;
|
||||
DSP3i::dsp3_byte = data;
|
||||
DSP3i::DSP3SetByte();
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class DSP3 : public Memory {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 read (uint addr);
|
||||
void write(uint addr, uint8 data);
|
||||
};
|
||||
|
||||
extern DSP3 dsp3;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,54 @@
|
||||
#include "../../base.h"
|
||||
#define DSP4_CPP
|
||||
|
||||
namespace DSP4i {
|
||||
inline uint16 READ_WORD(uint8 *addr) {
|
||||
return (addr[0]) + (addr[1] << 8);
|
||||
}
|
||||
|
||||
inline uint32 READ_DWORD(uint8 *addr) {
|
||||
return (addr[0]) + (addr[1] << 8) + (addr[2] << 16) + (addr[3] << 24);
|
||||
}
|
||||
|
||||
inline void WRITE_WORD(uint8 *addr, uint16 data) {
|
||||
addr[0] = data;
|
||||
addr[1] = data >> 8;
|
||||
}
|
||||
|
||||
#define bool8 uint8
|
||||
#include "dsp4emu.c"
|
||||
#undef bool8
|
||||
};
|
||||
|
||||
void DSP4::init() {
|
||||
}
|
||||
|
||||
void DSP4::enable() {
|
||||
}
|
||||
|
||||
void DSP4::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void DSP4::reset() {
|
||||
DSP4i::InitDSP4();
|
||||
}
|
||||
|
||||
uint8 DSP4::read(uint addr) {
|
||||
addr &= 0xffff;
|
||||
if(addr < 0xc000) {
|
||||
DSP4i::dsp4_address = addr;
|
||||
DSP4i::DSP4GetByte();
|
||||
return DSP4i::dsp4_byte;
|
||||
}
|
||||
return 0x80;
|
||||
}
|
||||
|
||||
void DSP4::write(uint addr, uint8 data) {
|
||||
addr &= 0xffff;
|
||||
if(addr < 0xc000) {
|
||||
DSP4i::dsp4_address = addr;
|
||||
DSP4i::dsp4_byte = data;
|
||||
DSP4i::DSP4SetByte();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class DSP4 : public Memory {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 read (uint addr);
|
||||
void write(uint addr, uint8 data);
|
||||
};
|
||||
|
||||
extern DSP4 dsp4;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,108 @@
|
||||
//DSP-4 emulator code
|
||||
//Copyright (c) 2004-2006 Dreamer Nom, John Weidman, Kris Bleakley, Nach, z80 gaiden
|
||||
|
||||
#ifndef DSP4EMU_H
|
||||
#define DSP4EMU_H
|
||||
|
||||
#undef TRUE
|
||||
#undef FALSE
|
||||
#define TRUE true
|
||||
#define FALSE false
|
||||
|
||||
struct DSP4_t
|
||||
{
|
||||
bool8 waiting4command;
|
||||
bool8 half_command;
|
||||
uint16 command;
|
||||
uint32 in_count;
|
||||
uint32 in_index;
|
||||
uint32 out_count;
|
||||
uint32 out_index;
|
||||
uint8 parameters[512];
|
||||
uint8 output[512];
|
||||
};
|
||||
|
||||
extern struct DSP4_t DSP4;
|
||||
|
||||
struct DSP4_vars_t
|
||||
{
|
||||
// op control
|
||||
int8 DSP4_Logic; // controls op flow
|
||||
|
||||
|
||||
// projection format
|
||||
int16 lcv; // loop-control variable
|
||||
int16 distance; // z-position into virtual world
|
||||
int16 raster; // current raster line
|
||||
int16 segments; // number of raster lines drawn
|
||||
|
||||
// 1.15.16 or 1.15.0 [sign, integer, fraction]
|
||||
int32 world_x; // line of x-projection in world
|
||||
int32 world_y; // line of y-projection in world
|
||||
int32 world_dx; // projection line x-delta
|
||||
int32 world_dy; // projection line y-delta
|
||||
int16 world_ddx; // x-delta increment
|
||||
int16 world_ddy; // y-delta increment
|
||||
int32 world_xenv; // world x-shaping factor
|
||||
int16 world_yofs; // world y-vertical scroll
|
||||
|
||||
int16 view_x1; // current viewer-x
|
||||
int16 view_y1; // current viewer-y
|
||||
int16 view_x2; // future viewer-x
|
||||
int16 view_y2; // future viewer-y
|
||||
int16 view_dx; // view x-delta factor
|
||||
int16 view_dy; // view y-delta factor
|
||||
int16 view_xofs1; // current viewer x-vertical scroll
|
||||
int16 view_yofs1; // current viewer y-vertical scroll
|
||||
int16 view_xofs2; // future viewer x-vertical scroll
|
||||
int16 view_yofs2; // future viewer y-vertical scroll
|
||||
int16 view_yofsenv; // y-scroll shaping factor
|
||||
int16 view_turnoff_x; // road turnoff data
|
||||
int16 view_turnoff_dx; // road turnoff delta factor
|
||||
|
||||
|
||||
// drawing area
|
||||
|
||||
int16 viewport_cx; // x-center of viewport window
|
||||
int16 viewport_cy; // y-center of render window
|
||||
int16 viewport_left; // x-left of viewport
|
||||
int16 viewport_right; // x-right of viewport
|
||||
int16 viewport_top; // y-top of viewport
|
||||
int16 viewport_bottom; // y-bottom of viewport
|
||||
|
||||
|
||||
// sprite structure
|
||||
|
||||
int16 sprite_x; // projected x-pos of sprite
|
||||
int16 sprite_y; // projected y-pos of sprite
|
||||
int16 sprite_attr; // obj attributes
|
||||
bool8 sprite_size; // sprite size: 8x8 or 16x16
|
||||
int16 sprite_clipy; // visible line to clip pixels off
|
||||
int16 sprite_count;
|
||||
|
||||
// generic projection variables designed for
|
||||
// two solid polygons + two polygon sides
|
||||
|
||||
int16 poly_clipLf[2][2]; // left clip boundary
|
||||
int16 poly_clipRt[2][2]; // right clip boundary
|
||||
int16 poly_ptr[2][2]; // HDMA structure pointers
|
||||
int16 poly_raster[2][2]; // current raster line below horizon
|
||||
int16 poly_top[2][2]; // top clip boundary
|
||||
int16 poly_bottom[2][2]; // bottom clip boundary
|
||||
int16 poly_cx[2][2]; // center for left/right points
|
||||
int16 poly_start[2]; // current projection points
|
||||
int16 poly_plane[2]; // previous z-plane distance
|
||||
|
||||
|
||||
// OAM
|
||||
int16 OAM_attr[16]; // OAM (size,MSB) data
|
||||
int16 OAM_index; // index into OAM table
|
||||
int16 OAM_bits; // offset into OAM table
|
||||
|
||||
int16 OAM_RowMax; // maximum number of tiles per 8 aligned pixels (row)
|
||||
int16 OAM_Row[32]; // current number of tiles per row
|
||||
};
|
||||
|
||||
extern struct DSP4_vars_t DSP4_vars;
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,89 @@
|
||||
#include "../../base.h"
|
||||
|
||||
void OBC1::init() {}
|
||||
void OBC1::enable() {}
|
||||
|
||||
void OBC1::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void OBC1::reset() {
|
||||
for(uint i = 0x0000; i <= 0x1fff; i++) ram_write(i, 0xff);
|
||||
|
||||
status.baseptr = (ram_read(0x1ff5) & 1) ? 0x1800 : 0x1c00;
|
||||
status.address = (ram_read(0x1ff6) & 0x7f);
|
||||
status.shift = (ram_read(0x1ff6) & 3) << 1;
|
||||
}
|
||||
|
||||
uint8 OBC1::read(uint addr) {
|
||||
addr &= 0x1fff;
|
||||
if((addr & 0x1ff8) != 0x1ff0) return ram_read(addr);
|
||||
|
||||
switch(addr) {
|
||||
case 0x1ff0:
|
||||
return ram_read(status.baseptr + (status.address << 2) + 0);
|
||||
case 0x1ff1:
|
||||
return ram_read(status.baseptr + (status.address << 2) + 1);
|
||||
case 0x1ff2:
|
||||
return ram_read(status.baseptr + (status.address << 2) + 2);
|
||||
case 0x1ff3:
|
||||
return ram_read(status.baseptr + (status.address << 2) + 3);
|
||||
case 0x1ff4:
|
||||
return ram_read(status.baseptr + (status.address >> 2) + 0x200);
|
||||
case 0x1ff5:
|
||||
case 0x1ff6:
|
||||
case 0x1ff7:
|
||||
return ram_read(addr);
|
||||
}
|
||||
|
||||
return 0x00; //never used, avoids compiler warning
|
||||
}
|
||||
|
||||
void OBC1::write(uint addr, uint8 data) {
|
||||
addr &= 0x1fff;
|
||||
if((addr & 0x1ff8) != 0x1ff0) return ram_write(addr, data);
|
||||
|
||||
switch(addr) {
|
||||
case 0x1ff0:
|
||||
ram_write(status.baseptr + (status.address << 2) + 0, data);
|
||||
break;
|
||||
case 0x1ff1:
|
||||
ram_write(status.baseptr + (status.address << 2) + 1, data);
|
||||
break;
|
||||
case 0x1ff2:
|
||||
ram_write(status.baseptr + (status.address << 2) + 2, data);
|
||||
break;
|
||||
case 0x1ff3:
|
||||
ram_write(status.baseptr + (status.address << 2) + 3, data);
|
||||
break;
|
||||
case 0x1ff4: {
|
||||
uint8 temp;
|
||||
temp = ram_read(status.baseptr + (status.address >> 2) + 0x200);
|
||||
temp = (temp & ~(3 << status.shift)) | ((data & 3) << status.shift);
|
||||
ram_write(status.baseptr + (status.address >> 2) + 0x200, temp);
|
||||
} break;
|
||||
case 0x1ff5:
|
||||
status.baseptr = (data & 1) ? 0x1800 : 0x1c00;
|
||||
ram_write(addr, data);
|
||||
break;
|
||||
case 0x1ff6:
|
||||
status.address = (data & 0x7f);
|
||||
status.shift = (data & 3) << 1;
|
||||
ram_write(addr, data);
|
||||
break;
|
||||
case 0x1ff7:
|
||||
ram_write(addr, data);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint8 OBC1::ram_read(uint addr) {
|
||||
return memory::cartram.read(addr & 0x1fff);
|
||||
}
|
||||
|
||||
void OBC1::ram_write(uint addr, uint8 data) {
|
||||
memory::cartram.write(addr & 0x1fff, data);
|
||||
}
|
||||
|
||||
OBC1::OBC1() {}
|
||||
OBC1::~OBC1() {}
|
||||
@@ -0,0 +1,25 @@
|
||||
class OBC1 : public Memory {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 read(uint addr);
|
||||
void write(uint addr, uint8 data);
|
||||
|
||||
OBC1();
|
||||
~OBC1();
|
||||
|
||||
private:
|
||||
uint8 ram_read(uint addr);
|
||||
void ram_write(uint addr, uint8 data);
|
||||
|
||||
struct {
|
||||
uint16 address;
|
||||
uint16 baseptr;
|
||||
uint16 shift;
|
||||
} status;
|
||||
};
|
||||
|
||||
extern OBC1 obc1;
|
||||
@@ -0,0 +1,110 @@
|
||||
#include "../../base.h"
|
||||
#define SDD1_CPP
|
||||
|
||||
#include "sdd1emu.cpp"
|
||||
|
||||
void SDD1::init() {}
|
||||
|
||||
void SDD1::enable() {
|
||||
for(int i = 0x4800; i <= 0x4807; i++) memory::mmio.map(i, *this);
|
||||
}
|
||||
|
||||
void SDD1::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void SDD1::reset() {
|
||||
sdd1.dma_active = false;
|
||||
|
||||
regs.r4800 = 0x00;
|
||||
regs.r4801 = 0x00;
|
||||
|
||||
regs.r4804 = 0x00;
|
||||
regs.r4805 = 0x01;
|
||||
regs.r4806 = 0x02;
|
||||
regs.r4807 = 0x03;
|
||||
|
||||
bus.map(Bus::MapLinear, 0xc0, 0xcf, 0x0000, 0xffff, memory::cartrom, (regs.r4804 & 7) << 20);
|
||||
bus.map(Bus::MapLinear, 0xd0, 0xdf, 0x0000, 0xffff, memory::cartrom, (regs.r4805 & 7) << 20);
|
||||
bus.map(Bus::MapLinear, 0xe0, 0xef, 0x0000, 0xffff, memory::cartrom, (regs.r4806 & 7) << 20);
|
||||
bus.map(Bus::MapLinear, 0xf0, 0xff, 0x0000, 0xffff, memory::cartrom, (regs.r4807 & 7) << 20);
|
||||
}
|
||||
|
||||
uint8 SDD1::mmio_read(uint addr) {
|
||||
switch(addr & 0xffff) {
|
||||
case 0x4804: return regs.r4804;
|
||||
case 0x4805: return regs.r4805;
|
||||
case 0x4806: return regs.r4806;
|
||||
case 0x4807: return regs.r4807;
|
||||
}
|
||||
|
||||
return cpu.regs.mdr;
|
||||
}
|
||||
|
||||
void SDD1::mmio_write(uint addr, uint8 data) {
|
||||
switch(addr & 0xffff) {
|
||||
case 0x4800: {
|
||||
regs.r4800 = data;
|
||||
} break;
|
||||
|
||||
case 0x4801: {
|
||||
regs.r4801 = data;
|
||||
} break;
|
||||
|
||||
case 0x4804: {
|
||||
if(regs.r4804 != data) {
|
||||
regs.r4804 = data;
|
||||
bus.map(Bus::MapLinear, 0xc0, 0xcf, 0x0000, 0xffff,
|
||||
memory::cartrom, (regs.r4804 & 7) << 20);
|
||||
}
|
||||
} break;
|
||||
|
||||
case 0x4805: {
|
||||
if(regs.r4805 != data) {
|
||||
regs.r4805 = data;
|
||||
bus.map(Bus::MapLinear, 0xd0, 0xdf, 0x0000, 0xffff,
|
||||
memory::cartrom, (regs.r4805 & 7) << 20);
|
||||
}
|
||||
} break;
|
||||
|
||||
case 0x4806: {
|
||||
if(regs.r4806 != data) {
|
||||
regs.r4806 = data;
|
||||
bus.map(Bus::MapLinear, 0xe0, 0xef, 0x0000, 0xffff,
|
||||
memory::cartrom, (regs.r4806 & 7) << 20);
|
||||
}
|
||||
} break;
|
||||
|
||||
case 0x4807: {
|
||||
if(regs.r4807 != data) {
|
||||
regs.r4807 = data;
|
||||
bus.map(Bus::MapLinear, 0xf0, 0xff, 0x0000, 0xffff,
|
||||
memory::cartrom, (regs.r4807 & 7) << 20);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void SDD1::dma_begin(uint8 channel, uint32 addr, uint16 length) {
|
||||
if(regs.r4800 & (1 << channel) && regs.r4801 & (1 << channel)) {
|
||||
regs.r4801 &= ~(1 << channel);
|
||||
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,39 @@
|
||||
#include "sdd1emu.h"
|
||||
|
||||
class SDD1 : public MMIO {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 mmio_read (uint addr);
|
||||
void mmio_write(uint addr, uint8 data);
|
||||
|
||||
void dma_begin(uint8 channel, uint32 addr, uint16 length);
|
||||
bool dma_active();
|
||||
uint8 dma_read();
|
||||
|
||||
SDD1();
|
||||
|
||||
private:
|
||||
SDD1emu sdd1emu;
|
||||
|
||||
struct {
|
||||
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 dma_active;
|
||||
} sdd1;
|
||||
|
||||
struct {
|
||||
uint8 r4800;
|
||||
uint8 r4801;
|
||||
uint8 r4804;
|
||||
uint8 r4805;
|
||||
uint8 r4806;
|
||||
uint8 r4807;
|
||||
} regs;
|
||||
};
|
||||
|
||||
extern SDD1 sdd1;
|
||||
@@ -0,0 +1,451 @@
|
||||
#ifdef SDD1_CPP
|
||||
|
||||
/************************************************************************
|
||||
|
||||
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) (bus.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)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
#endif //ifdef SDD1_CPP
|
||||
@@ -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,189 @@
|
||||
/*
|
||||
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"
|
||||
|
||||
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() {
|
||||
memory::mmio.map(0x2800, *this);
|
||||
memory::mmio.map(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(uint addr) {
|
||||
switch(addr & 0xffff) {
|
||||
|
||||
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 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(uint addr, uint8 data) {
|
||||
switch(addr & 0xffff) {
|
||||
|
||||
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 (uint addr);
|
||||
void mmio_write(uint addr, uint8 data);
|
||||
|
||||
SRTC();
|
||||
};
|
||||
|
||||
extern SRTC srtc;
|
||||
@@ -0,0 +1,86 @@
|
||||
#include "../../base.h"
|
||||
#define ST010_CPP
|
||||
|
||||
#include "st010_data.h"
|
||||
#include "st010_op.cpp"
|
||||
|
||||
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(uint addr) {
|
||||
return readb(addr);
|
||||
}
|
||||
|
||||
void ST010::write(uint addr, uint8 data) {
|
||||
writeb(addr, data);
|
||||
|
||||
if((addr & 0xfff) == 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,42 @@
|
||||
class ST010 : public Memory {
|
||||
public:
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 read (uint addr);
|
||||
void write(uint addr, uint8 data);
|
||||
|
||||
private:
|
||||
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);
|
||||
};
|
||||
|
||||
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,261 @@
|
||||
#ifdef ST010_CPP
|
||||
|
||||
//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);
|
||||
}
|
||||
|
||||
#endif //ifdef ST010_CPP
|
||||
@@ -0,0 +1 @@
|
||||
@make platform=win compiler=mingw32-gcc clean
|
||||
@@ -0,0 +1 @@
|
||||
make platform=x compiler=gcc 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,119 @@
|
||||
namespace config {
|
||||
|
||||
configuration& config() {
|
||||
static configuration config;
|
||||
return config;
|
||||
}
|
||||
|
||||
integral_setting File::autodetect_type(config(), "file.autodetect_type",
|
||||
"Auto-detect file type by inspecting file header, rather than by file extension.\n"
|
||||
"In other words, if a .zip file is renamed to .smc, it will still be correctly\n"
|
||||
"identified as a .zip file. However, there is an infinitesimal (1:~500,000,000)\n"
|
||||
"chance of a false detection when loading an uncompressed image file, if this\n"
|
||||
"option is enabled.",
|
||||
integral_setting::boolean, false);
|
||||
|
||||
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, "./")) {
|
||||
ltrim(path(), "./");
|
||||
string temp;
|
||||
strcpy(temp, config::path.base);
|
||||
strcat(temp, path);
|
||||
strcpy(path, temp);
|
||||
}
|
||||
|
||||
lstring part;
|
||||
split(part, "/", file);
|
||||
strcat(path, part[count(part) - 1]);
|
||||
return path;
|
||||
}
|
||||
|
||||
string_setting Path::base("path.base",
|
||||
"Path that bsnes resides in", "");
|
||||
string_setting Path::rom(config(), "path.rom",
|
||||
"Default path to look for ROM files in (\"\" = use default directory)", "");
|
||||
string_setting Path::save(config(), "path.save",
|
||||
"Default path for all save RAM files (\"\" = use current directory)", "");
|
||||
string_setting Path::cheat(config(), "path.cheat",
|
||||
"Default path for all cheat files (\"\" = use current directory)", "");
|
||||
string_setting Path::bsx(config(), "path.bsx", "", "");
|
||||
string_setting Path::st(config(), "path.st", "", "");
|
||||
|
||||
integral_setting SNES::controller_port0(config(), "snes.controller_port_1",
|
||||
"Controller attached to SNES port 1", integral_setting::decimal, ::SNES::Input::DeviceIDJoypad1);
|
||||
integral_setting SNES::controller_port1(config(), "snes.controller_port_2",
|
||||
"Controller attached to SNES port 2", integral_setting::decimal, ::SNES::Input::DeviceIDJoypad2);
|
||||
|
||||
integral_setting CPU::ntsc_clock_rate(config(), "cpu.ntsc_clock_rate",
|
||||
"NTSC S-CPU clock rate (in hz)", integral_setting::decimal, 21477272);
|
||||
integral_setting CPU::pal_clock_rate(config(), "cpu.pal_clock_rate",
|
||||
"PAL S-CPU clock rate (in hz)", integral_setting::decimal, 21281370);
|
||||
integral_setting CPU::wram_init_value(config(), "cpu.wram_init_value",
|
||||
"Value to initialize 128k WRAM to upon power cycle.\n"
|
||||
"Note that on real hardware, this value is undefined; meaning it can vary\n"
|
||||
"per power-on, and per SNES unit. Such randomness is undesirable for an\n"
|
||||
"emulator, so a static value is needed. There is also some form of pattern\n"
|
||||
"to the randomness that has yet to be determined, which some games rely upon.\n"
|
||||
"A value of 0x55 is safe for all known commercial software, and should be used.\n"
|
||||
"However, some software written for SNES copiers, or backup units, relies on\n"
|
||||
"WRAM being initialized to 0x00; which was a side-effect of the BIOS program\n"
|
||||
"which executed on these copiers. Using 0x00 will therefore fix many homebrew\n"
|
||||
"programs, but *will* break some poorly programmed commercial software titles,\n"
|
||||
"which do not properly initialize WRAM upon power cycle.\n",
|
||||
integral_setting::hex, 0x55);
|
||||
|
||||
integral_setting CPU::hdma_enable("cpu.hdma_enable",
|
||||
"Enable HDMA effects", integral_setting::boolean, true);
|
||||
|
||||
integral_setting SMP::ntsc_clock_rate(config(), "smp.ntsc_clock_rate",
|
||||
"NTSC S-SMP clock rate (in hz)", integral_setting::decimal, 24606720);
|
||||
integral_setting SMP::pal_clock_rate(config(), "smp.pal_clock_rate",
|
||||
"PAL S-SMP clock rate (in hz)", integral_setting::decimal, 24606720);
|
||||
|
||||
integral_setting PPU::Hack::render_scanline_position(config(), "ppu.hack.render_scanline_position",
|
||||
"Approximate HCLOCK position to render at for scanline-based renderers",
|
||||
integral_setting::decimal, 512);
|
||||
integral_setting 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",
|
||||
integral_setting::boolean, false);
|
||||
integral_setting 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.",
|
||||
integral_setting::boolean, true);
|
||||
integral_setting 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.",
|
||||
integral_setting::boolean, true);
|
||||
|
||||
integral_setting PPU::opt_enable("ppu.opt_enable", "Enable offset-per-tile effects", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg1_pri0_enable("ppu.bg1_pri0_enable", "Enable BG1 Priority 0", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg1_pri1_enable("ppu.bg1_pri1_enable", "Enable BG1 Priority 1", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg2_pri0_enable("ppu.bg2_pri0_enable", "Enable BG2 Priority 0", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg2_pri1_enable("ppu.bg2_pri1_enable", "Enable BG2 Priority 1", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg3_pri0_enable("ppu.bg3_pri0_enable", "Enable BG3 Priority 0", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg3_pri1_enable("ppu.bg3_pri1_enable", "Enable BG3 Priority 1", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg4_pri0_enable("ppu.bg4_pri0_enable", "Enable BG4 Priority 0", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg4_pri1_enable("ppu.bg4_pri1_enable", "Enable BG4 Priority 1", integral_setting::boolean, true);
|
||||
integral_setting PPU::oam_pri0_enable("ppu.oam_pri0_enable", "Enable OAM Priority 0", integral_setting::boolean, true);
|
||||
integral_setting PPU::oam_pri1_enable("ppu.oam_pri1_enable", "Enable OAM Priority 1", integral_setting::boolean, true);
|
||||
integral_setting PPU::oam_pri2_enable("ppu.oam_pri2_enable", "Enable OAM Priority 2", integral_setting::boolean, true);
|
||||
integral_setting PPU::oam_pri3_enable("ppu.oam_pri3_enable", "Enable OAM Priority 3", integral_setting::boolean, true);
|
||||
|
||||
} //namespace config
|
||||
@@ -0,0 +1,48 @@
|
||||
namespace config {
|
||||
|
||||
extern configuration& config();
|
||||
|
||||
string file_updatepath(const char*, const char*);
|
||||
|
||||
extern struct File {
|
||||
static integral_setting autodetect_type;
|
||||
} file;
|
||||
|
||||
extern struct Path {
|
||||
static string_setting base, rom, save, cheat;
|
||||
static string_setting bsx, st;
|
||||
} path;
|
||||
|
||||
extern struct SNES {
|
||||
static integral_setting controller_port0;
|
||||
static integral_setting controller_port1;
|
||||
} snes;
|
||||
|
||||
extern struct CPU {
|
||||
static integral_setting ntsc_clock_rate, pal_clock_rate;
|
||||
static integral_setting wram_init_value;
|
||||
static integral_setting hdma_enable;
|
||||
} cpu;
|
||||
|
||||
extern struct SMP {
|
||||
static integral_setting ntsc_clock_rate, pal_clock_rate;
|
||||
} smp;
|
||||
|
||||
extern struct PPU {
|
||||
struct Hack {
|
||||
static integral_setting render_scanline_position;
|
||||
static integral_setting obj_cache;
|
||||
static integral_setting oam_address_invalidation;
|
||||
static integral_setting cgram_address_invalidation;
|
||||
} hack;
|
||||
|
||||
static integral_setting opt_enable;
|
||||
static integral_setting bg1_pri0_enable, bg1_pri1_enable;
|
||||
static integral_setting bg2_pri0_enable, bg2_pri1_enable;
|
||||
static integral_setting bg3_pri0_enable, bg3_pri1_enable;
|
||||
static integral_setting bg4_pri0_enable, bg4_pri1_enable;
|
||||
static integral_setting oam_pri0_enable, oam_pri1_enable;
|
||||
static integral_setting 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
|
||||
}
|
||||
+7
-2
@@ -1,6 +1,11 @@
|
||||
#include "../base.h"
|
||||
#include "../base.h"
|
||||
#define CPU_CPP
|
||||
|
||||
#include "dcpu.cpp"
|
||||
|
||||
CPU::CPU() {
|
||||
mmio = &mmio_unmapped;
|
||||
cpu_version = 1;
|
||||
}
|
||||
|
||||
CPU::~CPU() {
|
||||
}
|
||||
+51
-14
@@ -1,23 +1,55 @@
|
||||
#include "cpuregs.h"
|
||||
|
||||
class CPU {
|
||||
class CPU : public MMIO {
|
||||
public:
|
||||
MMIO *mmio;
|
||||
CPURegs regs;
|
||||
virtual void enter() = 0;
|
||||
|
||||
//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 hdot() = 0;
|
||||
|
||||
virtual uint8 pio_status() = 0;
|
||||
virtual uint8 port_read(uint8 port) = 0;
|
||||
virtual void port_write(uint8 port, uint8 value) = 0;
|
||||
|
||||
CPURegs regs;
|
||||
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 void scanline() = 0;
|
||||
virtual void frame() = 0;
|
||||
virtual void power() = 0;
|
||||
virtual void reset() = 0;
|
||||
|
||||
//opcode disassembler
|
||||
/*****
|
||||
* 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
|
||||
@@ -37,13 +69,18 @@ CPURegs regs;
|
||||
OPTYPE_SR, //sr,s
|
||||
OPTYPE_ISRY, //(sr,s),y
|
||||
OPTYPE_ADDR_PC, //pbr:addr
|
||||
OPTYPE_IADDR_PC //pbr:(addr)
|
||||
OPTYPE_IADDR_PC, //pbr:(addr)
|
||||
OPTYPE_RELB, //relb
|
||||
OPTYPE_RELW, //relw
|
||||
};
|
||||
|
||||
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();
|
||||
};
|
||||
+51
-60
@@ -1,84 +1,75 @@
|
||||
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;
|
||||
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 {
|
||||
uint16 w;
|
||||
struct { uint8 l, h; };
|
||||
uint16 w;
|
||||
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;
|
||||
uint32 d;
|
||||
struct { uint8 l, h, b; };
|
||||
uint32 d;
|
||||
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 {
|
||||
public:
|
||||
CPUReg24 pc;
|
||||
CPUReg16 a, x, y, s, d;
|
||||
CPURegFlags p;
|
||||
uint8 db;
|
||||
bool e;
|
||||
CPURegs() { db = 0; e = false; }
|
||||
CPUReg24 pc;
|
||||
CPUReg16 a, x, y, s, d;
|
||||
CPURegFlags p;
|
||||
uint8 db;
|
||||
uint8 mdr;
|
||||
bool e;
|
||||
CPURegs() : db(0), mdr(0x00), e(false) {}
|
||||
};
|
||||
+372
-332
@@ -1,16 +1,30 @@
|
||||
uint16 CPU::__relb(int8 offset) {
|
||||
uint32 addr;
|
||||
addr = (regs.pc.d & 0xff0000) | ((regs.pc.d + 2) & 0xffff);
|
||||
return addr + offset;
|
||||
#ifdef CPU_CPP
|
||||
|
||||
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 bus.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 +38,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 +75,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(), hcounter());
|
||||
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 +465,15 @@ 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;
|
||||
}
|
||||
|
||||
#endif //ifdef CPU_CPP
|
||||
@@ -0,0 +1,3 @@
|
||||
cl /nologo /O2 scpugen.cpp
|
||||
@pause
|
||||
@del *.obj
|
||||
@@ -0,0 +1 @@
|
||||
@del *.exe
|
||||
@@ -0,0 +1,66 @@
|
||||
#ifdef SCPU_CPP
|
||||
|
||||
#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();
|
||||
}
|
||||
}
|
||||
|
||||
#endif //ifdef SCPU_CPP
|
||||
@@ -0,0 +1,57 @@
|
||||
void (sCPU::*optbl[256])();
|
||||
|
||||
CPUReg24 aa, rd;
|
||||
uint8_t 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
Loaded 100 of 524 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user