41 Commits

Author SHA1 Message Date
David Voswinkel
764c0dd2c1 o compiles and still crashes 2009-05-14 20:22:39 +02:00
David Voswinkel
a1763efe21 o mac compiles and stil crashed 2009-05-14 20:21:18 +02:00
David Voswinkel
b3d930b143 o cleanup mocs 2009-05-12 23:18:16 +02:00
David Voswinkel
3063b354e7 o mac compiles 2009-05-12 23:17:44 +02:00
David Voswinkel
571737d59b o add missing files 2009-05-12 22:24:35 +02:00
David Voswinkel
09198f5099 o add missing files 2009-05-12 22:20:41 +02:00
David Voswinkel
8e877d38d4 o switch to v46 2009-05-12 22:17:42 +02:00
David Voswinkel
7a878eab39 o compiles now for mac but crashes 2009-05-12 22:15:09 +02:00
David Voswinkel
091b82a7ef o add my bsnes branch 2009-05-12 20:05:00 +02:00
David Voswinkel
1c30d3db56 o remove old bsnes version 2009-05-12 19:44:23 +02:00
David Voswinkel
9cf6eae076 o add missing files
o add usbload
2009-05-12 19:01:03 +02:00
David Voswinkel
67a25941a7 o add kirby 2009-05-12 18:58:59 +02:00
David Voswinkel
aedc6dab5b o add gnususb as reference bootloader
o refactor boot loader  cpde
o
2009-05-06 23:55:56 +02:00
optixx
c40b9c32b6 o cleanup code
o add more states
o decouple read buffer size
2009-05-04 00:13:24 +02:00
optixx
59aad4c7a8 o done testing 2009-05-03 18:35:40 +02:00
optixx
af48032798 o add first working draft of usb version
o having bad sync problems only can use 4 bytes buffer, supper slow
2009-05-03 18:25:40 +02:00
optixx
d481bd5061 o cleanup 2009-05-02 13:19:58 +02:00
optixx
96c273fe89 o start usb uploadr avr 2009-05-02 11:35:13 +02:00
optixx
25c1f38aed o add vusb 2009-05-02 11:28:11 +02:00
optixx
0693dbc933 o add more test roms 2009-04-27 09:29:36 +02:00
optixx
500e6326c1 o add missing roms 2009-04-26 19:46:28 +02:00
optixx
d229719d0c o add bankselect test for logic analyser test 2009-04-26 16:24:04 +02:00
optixx
096ad71b4e o make crc an 8mb game
o add rand garbage in banks 3-8 and banks 9-16
2009-04-26 16:22:41 +02:00
optixx
aa29d483eb o get crc working on 8 banks 2009-04-26 15:02:10 +02:00
optixx
dc83f998c7 o switch to compact mem layout
o 16 bit code
0 24 bit data
2009-04-26 11:39:23 +02:00
optixx
369667e154 o cleanup
o refactor debug function
o add ifeq platform to makefile
o get crc working on bank 0
2009-04-26 11:00:02 +02:00
optixx
4a083cbea3 o crc checking rom 2009-04-25 20:41:02 +02:00
optixx
edf204ac24 o more crc checking 2009-04-24 09:21:54 +02:00
optixx
0c378a9f7c o cleanup 2009-04-22 20:04:28 +02:00
optixx
55e3468f74 o tried other rom 2009-04-22 20:02:29 +02:00
optixx
78e9dce5ea o add new test roms 2009-04-22 09:09:34 +02:00
optixx
eaf0bda3ee o add converter tools: 2009-04-22 09:08:16 +02:00
optixx
d58d3439ec o add crc check 2009-04-22 09:07:52 +02:00
optixx
b5f111fa41 o use up more rom space to test mem holes 2009-04-21 21:14:36 +02:00
optixx
6508530384 o add dex x hex x binary converter 2009-04-20 21:59:50 +02:00
optixx
e4364eedb1 o add test roms 2009-04-20 21:45:38 +02:00
optixx
74312e08e1 o add bank test
o cleanup bank debug in uploaded
o add header dump to uploader
2009-04-20 21:44:14 +02:00
optixx
09f42acfc8 o played with banks
o add ditz
o add checksize
2009-04-20 20:14:42 +02:00
optixx
70984ebd00 o 2009-04-17 08:53:46 +02:00
optixx
cafe5b8efd o add cleanup db
o add analyse sql batch
2009-04-17 08:53:13 +02:00
optixx
a1e89d9528 o finish rom analyse 2009-04-13 17:30:04 +02:00
1355 changed files with 52495 additions and 12066 deletions

4
.ditz-config Normal file
View File

@@ -0,0 +1,4 @@
--- !ditz.rubyforge.org,2008-03-06/config
name: David
email: david@optixx.org
issue_dir: bugs

View File

@@ -1,278 +0,0 @@
include lib/nall/Makefile.string
prefix = /usr/local
ui = ui_qt
################
### compiler ###
################
ifneq ($(findstring gcc,$(compiler)),) # GCC family
flags = -O3 -fomit-frame-pointer -Ilib
# note: libco *requires* -fomit-frame-pointer on i386 arch
libcoflags := $(flags) -static
c = $(compiler)
cpp = $(subst cc,++,$(compiler))
obj = o
rule = -c $< -o $@
link = -s
mkbin = -o$1
mkdef = -D$1
mkincpath = -I$1
mklib = -l$1
mklibpath = -L$1
# profile-guided optimization:
# flags += -fprofile-generate
# link += -lgcov
# flags += -fprofile-use
else ifeq ($(compiler),cl) # Visual C++
flags = /nologo /wd4355 /wd4805 /wd4996 /Ox /GL /EHsc /Ilib
libcoflags = $(flags)
c = cl
cpp = cl
obj = obj
rule = /c $< /Fo$@
link = /link
mkbin = /Fe$1
mkdef = /D$1
mkincpath = /I$1
mklib = $1.lib
mklibpath = /L$1
else
unknown_compiler: help;
endif
##########
### os ###
##########
ifeq ($(platform),x) # X11
ruby = video.glx video.xv video.sdl audio.alsa audio.openal audio.oss audio.pulseaudio audio.ao input.sdl input.x
delete = rm -f $1
else ifeq ($(platform),win) # Windows
mingw_link_flags = -mwindows
# mingw_links_flags = -mconsole
# enable static linking to Qt for Windows build
mingw_link_flags += -enable-stdcall-fixup -Wl,-s -Wl,-enable-auto-import -Wl,-enable-runtime-pseudo-reloc
ruby = video.direct3d video.wgl video.directdraw video.gdi audio.directsound input.rawinput input.directinput
delete = $(if $(findstring i586-mingw-gcc,$(compiler)),rm -f $1,del $(subst /,\,$1))
link += $(if $(findstring mingw,$(compiler)),$(mingw_link_flags))
link += $(call mklib,uuid)
link += $(call mklib,kernel32)
link += $(call mklib,user32)
link += $(call mklib,gdi32)
link += $(call mklib,shell32)
else
unknown_platform: help;
endif
############
### ruby ###
############
rubyflags = $(if $(findstring .sdl,$(ruby)),`sdl-config --cflags`)
link += $(if $(findstring .sdl,$(ruby)),`sdl-config --libs`)
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.wgl,$(ruby)),$(call mklib,opengl32))
link += $(if $(findstring video.xv,$(ruby)),$(call mklib,Xv))
link += $(if $(findstring audio.alsa,$(ruby)),$(call mklib,asound))
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 audio.pulseaudio,$(ruby)),$(call mklib,pulse-simple))
link += $(if $(findstring input.directinput,$(ruby)),$(call mklib,dinput8) $(call mklib,dxguid))
link += $(if $(findstring input.rawinput,$(ruby)),$(call mklib,xinput) $(call mklib,dinput8) $(call mklib,dxguid))
####################
### core objects ###
####################
objects = libco ruby libfilter string \
reader cart cheat \
memory smemory cpu scpu smp ssmp sdsp ppu bppu snes \
bsx srtc sdd1 spc7110 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
######################
### implicit rules ###
######################
compile = \
$(strip \
$(if $(filter %.c,$<), \
$(c) $(flags) $1 $(rule), \
$(if $(filter %.cpp,$<), \
$(cpp) $(flags) $1 $(rule) \
) \
) \
)
%.$(obj): $<; $(call compile)
all: build;
include $(ui)/Makefile
objects := $(patsubst %,obj/%.$(obj),$(objects))
rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),$(call mkdef,$c))
#################
### libraries ###
#################
obj/ruby.$(obj): lib/ruby/ruby.cpp lib/ruby/* lib/ruby/video/* lib/ruby/audio/* lib/ruby/input/*
$(call compile,$(rubydef) $(rubyflags))
obj/libco.$(obj): lib/libco/libco.c lib/libco/*
$(c) $(libcoflags) $(rule)
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/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/spc7110.$(obj): chip/spc7110/spc7110.cpp chip/spc7110/*
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: ui_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/pixmaps/bsnes.png
install -D -m 644 data/bsnes.desktop $(DESTDIR)$(prefix)/share/applications/bsnes.desktop
clean: ui_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 ""

View File

@@ -1,234 +0,0 @@
#include <../base.hpp>
#include <../chip/chip.hpp>
#include <../reader/reader.hpp>
#define CART_CPP
#include <nall/crc32.hpp>
#include <nall/ups.hpp>
#include "cart.hpp"
#include "cart_file.cpp"
#include "cart_header.cpp"
#include "cart_loader.cpp"
namespace memory {
MappedRAM cartrom, cartram, cartrtc;
MappedRAM bscram;
MappedRAM stArom, stAram;
MappedRAM stBrom, stBram;
};
Cartridge cartridge;
void Cartridge::load_begin(Mode cartridge_mode) {
cart.rom = cart.ram = cart.rtc = 0;
bs.ram = 0;
stA.rom = stA.ram = 0;
stB.rom = stB.ram = 0;
cart.rom_size = cart.ram_size = cart.rtc_size = 0;
bs.ram_size = 0;
stA.rom_size = stA.ram_size = 0;
stB.rom_size = stB.ram_size = 0;
set(loaded, false);
set(bsx_flash_loaded, false);
set(patched, false);
set(mode, cartridge_mode);
}
void Cartridge::load_end() {
memory::cartrom.map(cart.rom, cart.rom_size);
memory::cartram.map(cart.ram, cart.ram_size);
memory::cartrtc.map(cart.rtc, cart.rtc_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);
string cheat_file = get_filename(cart.filename, "cht", snes.config.path.cheat);
if(file::exists(cheat_file)) {
cheat.clear();
cheat.load(cheat_file);
}
bus.load_cart();
set(loaded, true);
}
void Cartridge::unload() {
if(loaded() == false) return;
bus.unload_cart();
switch(mode()) {
case ModeNormal: unload_normal(); break;
case ModeBsxSlotted: unload_bsx_slotted(); break;
case ModeBsx: unload_bsx(); break;
case ModeSufamiTurbo: unload_sufami_turbo(); break;
}
if(cart.rom) { delete[] cart.rom; cart.rom = 0; }
if(cart.ram) { delete[] cart.ram; cart.ram = 0; }
if(cart.rtc) { delete[] cart.rtc; cart.rtc = 0; }
if(bs.ram) { delete[] bs.ram; bs.ram = 0; }
if(stA.rom) { delete[] stA.rom; stA.rom = 0; }
if(stA.ram) { delete[] stA.ram; stA.ram = 0; }
if(stB.rom) { delete[] stB.rom; stB.rom = 0; }
if(stB.ram) { delete[] stB.ram; stB.ram = 0; }
string cheat_file = get_filename(cart.filename, "cht", snes.config.path.cheat);
if(cheat.count() > 0 || file::exists(cheat_file)) {
cheat.save(cheat_file);
cheat.clear();
}
set(loaded, false);
}
Cartridge::Cartridge() {
set(loaded, false);
}
Cartridge::~Cartridge() {
if(loaded() == true) unload();
}
void Cartridge::set_cartinfo(const Cartridge::cartinfo_t &source) {
set(region, source.region);
set(mapper, source.mapper);
set(dsp1_mapper, source.dsp1_mapper);
set(has_bsx_slot, source.bsx_slot);
set(has_superfx, source.superfx);
set(has_sa1, source.sa1);
set(has_srtc, source.srtc);
set(has_sdd1, source.sdd1);
set(has_spc7110, source.spc7110);
set(has_spc7110rtc, source.spc7110rtc);
set(has_cx4, source.cx4);
set(has_dsp1, source.dsp1);
set(has_dsp2, source.dsp2);
set(has_dsp3, source.dsp3);
set(has_dsp4, source.dsp4);
set(has_obc1, source.obc1);
set(has_st010, source.st010);
set(has_st011, source.st011);
set(has_st018, source.st018);
}
//==========
//cartinfo_t
//==========
void Cartridge::cartinfo_t::reset() {
type = TypeUnknown;
mapper = LoROM;
dsp1_mapper = DSP1Unmapped;
region = NTSC;
rom_size = 0;
ram_size = 0;
bsx_slot = false;
superfx = false;
sa1 = false;
srtc = false;
sdd1 = false;
spc7110 = false;
spc7110rtc = false;
cx4 = false;
dsp1 = false;
dsp2 = false;
dsp3 = false;
dsp4 = false;
obc1 = false;
st010 = false;
st011 = false;
st018 = false;
}
Cartridge::cartinfo_t::cartinfo_t() {
reset();
}
//=======
//utility
//=======
//ensure file path is absolute (eg resolve relative paths)
string Cartridge::filepath(const char *filename, const char *pathname) {
//if no pathname, return filename as-is
string file(filename);
file.replace("\\", "/");
string path = (!pathname || !*pathname) ? (const char*)snes.config.path.current : pathname;
//ensure path ends with trailing '/'
path.replace("\\", "/");
if(!strend(path, "/")) path.append("/");
//replace relative path with absolute path
if(strbegin(path, "./")) {
ltrim(path, "./");
path = string() << snes.config.path.base << path;
}
//remove folder part of filename
lstring part;
part.split("/", file);
return path << part[part.size() - 1];
}
//remove directory information and file extension ("/foo/bar.ext" -> "bar")
string Cartridge::basename(const char *filename) {
string name(filename);
//remove extension
for(signed i = strlen(name) - 1; i >= 0; i--) {
if(name[i] == '.') {
name[i] = 0;
break;
}
}
//remove directory information
for(signed i = strlen(name) - 1; i >= 0; i--) {
if(name[i] == '/' || name[i] == '\\') {
i++;
char *output = name();
while(true) {
*output++ = name[i];
if(!name[i]) break;
i++;
}
break;
}
}
return name;
}
//remove filename and return path only ("/foo/bar.ext" -> "/foo/bar/")
string Cartridge::basepath(const char *filename) {
string path(filename);
path.replace("\\", "/");
//remove filename
for(signed i = strlen(path) - 1; i >= 0; i--) {
if(path[i] == '/') {
path[i] = 0;
break;
}
}
if(!strend(path, "/")) path.append("/");
return path;
}

View File

@@ -1,178 +0,0 @@
class Cartridge : public property {
public:
enum Mode {
ModeNormal,
ModeBsxSlotted,
ModeBsx,
ModeSufamiTurbo,
};
enum Type {
TypeNormal,
TypeBsxSlotted,
TypeBsxBios,
TypeBsx,
TypeSufamiTurboBios,
TypeSufamiTurbo,
TypeUnknown,
};
enum Region {
NTSC,
PAL,
};
enum MemoryMapper {
LoROM,
HiROM,
ExLoROM,
ExHiROM,
SPC7110ROM,
BSCLoROM,
BSCHiROM,
BSXROM,
STROM,
};
enum DSP1MemoryMapper {
DSP1Unmapped,
DSP1LoROM1MB,
DSP1LoROM2MB,
DSP1HiROM,
};
//properties can be read via operator(), eg "if(cartridge.loaded() == true)";
//warning: if loaded() == false, no other property is considered valid!
property_t<bool> loaded; //is a base cartridge inserted?
property_t<bool> bsx_flash_loaded; //is a BS-X flash cart connected?
property_t<bool> patched; //has a UPS patch been applied?
property_t<string> name; //display name (filename sans path and extension)
property_t<Mode> mode;
property_t<Region> region;
property_t<MemoryMapper> mapper;
property_t<DSP1MemoryMapper> dsp1_mapper;
property_t<bool> has_bsx_slot;
property_t<bool> has_superfx;
property_t<bool> has_sa1;
property_t<bool> has_srtc;
property_t<bool> has_sdd1;
property_t<bool> has_spc7110, has_spc7110rtc;
property_t<bool> has_cx4;
property_t<bool> has_dsp1, has_dsp2, has_dsp3, has_dsp4;
property_t<bool> has_obc1;
property_t<bool> has_st010, has_st011, has_st018;
//main interface
bool load_normal (const char *base);
bool load_bsx_slotted (const char *base, const char *slot = "");
bool load_bsx (const char *base, const char *slot = "");
bool load_sufami_turbo(const char *base, const char *slotA = "", const char *slotB = "");
void unload();
//utility functions
static string filepath(const char *filename, const char *pathname); //"./bar.ext" -> "/foo/bar.ext"
static string basename(const char *filename); //"/foo/bar.ext" -> "bar"
static string basepath(const char *filename); //"/foo/bar.ext" -> "/foo/bar/"
//this function will load 'filename', decompress it if needed, and determine what type of
//image file 'filename' refers to (eg normal cart, BS-X flash cart, Sufami Turbo cart, etc.)
//warning: this operation is very expensive, use sparingly!
Type detect_image_type(const char *filename) const;
Cartridge();
~Cartridge();
private:
void load_begin(Mode);
void load_end();
void unload_normal();
void unload_bsx_slotted();
void unload_bsx();
void unload_sufami_turbo();
struct cartinfo_t {
Type type;
Region region;
MemoryMapper mapper;
DSP1MemoryMapper dsp1_mapper;
unsigned rom_size, ram_size;
bool bsx_slot;
bool superfx;
bool sa1;
bool srtc;
bool sdd1;
bool spc7110, spc7110rtc;
bool cx4;
bool dsp1, dsp2, dsp3, dsp4;
bool obc1;
bool st010, st011, st018;
void reset();
cartinfo_t();
};
enum HeaderField {
CartName = 0x00,
Mapper = 0x15,
RomType = 0x16,
RomSize = 0x17,
RamSize = 0x18,
CartRegion = 0x19,
Company = 0x1a,
Version = 0x1b,
Complement = 0x1c, //inverse checksum
Checksum = 0x1e,
ResetVector = 0x3c,
};
void read_header(cartinfo_t &info, const uint8_t *data, unsigned size) const;
unsigned find_header(const uint8_t *data, unsigned size) const;
unsigned score_header(const uint8_t *data, unsigned size, unsigned addr) const;
void set_cartinfo(const cartinfo_t&);
bool load_image(const char *filename, uint8_t *&data, unsigned &size, bool &patched) const;
bool load_ram (const char *filename, uint8_t *&data, unsigned size, uint8_t init_value) const;
enum CompressionMode {
CompressionNone, //always load without compression
CompressionInspect, //use file header inspection
CompressionAuto, //use file extension or file header inspection (configured by user)
};
bool load_file(const char *fn, uint8 *&data, unsigned &size, CompressionMode compression = CompressionNone) const;
bool save_file(const char *fn, uint8 *data, unsigned size) const;
bool apply_patch(const uint8_t *pdata, unsigned psize, uint8_t *&data, unsigned &size) const;
string modify_extension(const char *filename, const char *extension) const;
string get_filename(const char *source, const char *extension, const char *path) const;
struct {
string filename;
uint8_t *rom, *ram, *rtc;
unsigned rom_size, ram_size, rtc_size;
} cart;
struct {
string filename;
uint8_t *ram;
unsigned ram_size;
} bs;
struct {
string filename;
uint8_t *rom, *ram;
unsigned rom_size, ram_size;
} stA, stB;
};
namespace memory {
extern MappedRAM cartrom, cartram, cartrtc;
extern MappedRAM bscram;
extern MappedRAM stArom, stAram;
extern MappedRAM stBrom, stBram;
};
extern Cartridge cartridge;

View File

@@ -1,109 +0,0 @@
#ifdef CART_CPP
#include "../reader/filereader.hpp"
#if defined(GZIP_SUPPORT)
#include "../reader/gzreader.hpp"
#include "../reader/zipreader.hpp"
#endif
#if defined(JMA_SUPPORT)
#include "../reader/jmareader.hpp"
#endif
string Cartridge::modify_extension(const char *filename_, const char *extension) const {
string filename = filename_;
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;
return filename << "." << extension;
}
string Cartridge::get_filename(const char *source, const char *extension, const char *path) const {
return filepath(modify_extension(source, extension), path);
}
bool Cartridge::load_file(const char *fn, uint8 *&data, unsigned &size, CompressionMode compression) const {
if(file::exists(fn) == false) return false;
Reader::Type filetype = Reader::Normal;
if(compression == CompressionInspect) filetype = Reader::detect(fn, true);
if(compression == CompressionAuto) filetype = Reader::detect(fn, snes.config.file.autodetect_type);
switch(filetype) { default:
case Reader::Normal: {
FileReader ff(fn);
if(!ff.ready()) return false;
size = ff.size();
data = ff.read();
} break;
#ifdef GZIP_SUPPORT
case Reader::GZIP: {
GZReader gf(fn);
if(!gf.ready()) return false;
size = gf.size();
data = gf.read();
} break;
case Reader::ZIP: {
ZipReader zf(fn);
if(!zf.ready()) return false;
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) {
return false;
}
} break;
#endif
}
return true;
}
bool Cartridge::apply_patch(const uint8_t *pdata, const unsigned psize, uint8_t *&data, unsigned &size) const {
uint8_t *outdata = 0;
unsigned outsize;
ups patcher;
ups::result result = patcher.apply(pdata, psize, data, size, outdata, outsize);
bool apply = false;
if(result == ups::ok) apply = true;
if(snes.config.file.bypass_patch_crc32 == true) {
if(result == ups::input_crc32_invalid) apply = true;
if(result == ups::output_crc32_invalid) apply = true;
}
//if patch application was successful, replace old data, size with new data, size
if(apply == true) {
delete[] data;
data = new uint8_t[size = outsize];
memcpy(data, outdata, outsize);
}
if(outdata) delete[] outdata;
return apply;
}
bool Cartridge::save_file(const char *fn, uint8 *data, unsigned size) const {
file fp;
if(!fp.open(fn, file::mode_write)) return false;
fp.write(data, size);
fp.close();
return true;
}
#endif

View File

@@ -1,244 +0,0 @@
#ifdef CART_CPP
//================
//Normal cartridge
//================
bool Cartridge::load_normal(const char *base) {
uint8_t *data;
unsigned size;
bool patch_applied;
cart.filename = base;
load_begin(ModeNormal);
if(load_image(base, data, size, patch_applied) == false) return false;
snes.config.path.current = basepath(cart.filename);
if(patch_applied) set(patched, true);
cartinfo_t cartinfo;
read_header(cartinfo, cart.rom = data, cart.rom_size = size);
set_cartinfo(cartinfo);
if(cartinfo.ram_size > 0) {
load_ram(get_filename(base, "srm", snes.config.path.save), cart.ram, cart.ram_size = cartinfo.ram_size, 0xff);
}
if(cartinfo.srtc || cartinfo.spc7110rtc) {
load_ram(get_filename(base, "rtc", snes.config.path.save), cart.rtc, cart.rtc_size = 20, 0x00);
}
load_end();
set(name, basename(base));
return true;
}
void Cartridge::unload_normal() {
if(cart.ram) save_file(get_filename(cart.filename, "srm", snes.config.path.save), cart.ram, cart.ram_size);
if(cart.rtc) save_file(get_filename(cart.filename, "rtc", snes.config.path.save), cart.rtc, cart.rtc_size);
}
//======================
//BS-X slotted cartridge
//======================
bool Cartridge::load_bsx_slotted(const char *base, const char *slot) {
uint8_t *data;
unsigned size;
bool patch_applied;
cart.filename = base;
bs.filename = slot;
load_begin(ModeBsxSlotted);
if(load_image(base, data, size, patch_applied) == false) return false;
snes.config.path.current = basepath(cart.filename);
if(patch_applied) set(patched, true);
cartinfo_t cartinfo;
read_header(cartinfo, cart.rom = data, cart.rom_size = size);
set_cartinfo(cartinfo);
if(load_image(slot, data, size, patch_applied) == true) {
set(bsx_flash_loaded, true);
if(patch_applied) set(patched, true);
bs.ram = data;
bs.ram_size = size;
}
if(cartinfo.ram_size > 0) {
load_ram(get_filename(base, "srm", snes.config.path.save), cart.ram, cart.ram_size = cartinfo.ram_size, 0xff);
}
load_end();
string filename = basename(base);
if(*slot) filename << " + " << basename(slot);
set(name, filename);
return true;
}
void Cartridge::unload_bsx_slotted() {
if(cart.ram) save_file(get_filename(cart.filename, "srm", snes.config.path.save), cart.ram, cart.ram_size);
}
//====================
//BS-X flash cartridge
//====================
bool Cartridge::load_bsx(const char *base, const char *slot) {
uint8_t *data;
unsigned size;
bool patch_applied;
cart.filename = base;
bs.filename = slot;
load_begin(ModeBsx);
if(load_image(base, data, size, patch_applied) == false) return false;
snes.config.path.current = basepath(cart.filename);
if(patch_applied) set(patched, true);
cartinfo_t cartinfo;
read_header(cartinfo, cart.rom = data, cart.rom_size = size);
set_cartinfo(cartinfo);
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_filename(base, "srm", snes.config.path.save), data, size, CompressionNone) == true) {
memcpy(bsxcart.sram.handle (), data, min(bsxcart.sram.size (), size));
delete[] data;
}
if(load_file(get_filename(base, "psr", snes.config.path.save), data, size, CompressionNone) == true) {
memcpy(bsxcart.psram.handle(), data, min(bsxcart.psram.size(), size));
delete[] data;
}
if(load_image(slot, data, size, patch_applied) == true) {
set(bsx_flash_loaded, true);
if(patch_applied) set(patched, true);
bs.ram = data;
bs.ram_size = size;
}
load_end();
set(name, !*slot ? basename(base) : basename(slot));
return true;
}
void Cartridge::unload_bsx() {
save_file(get_filename(cart.filename, "srm", snes.config.path.save), bsxcart.sram.handle (), bsxcart.sram.size ());
save_file(get_filename(cart.filename, "psr", snes.config.path.save), bsxcart.psram.handle(), bsxcart.psram.size());
}
//============================
//Sufami Turbo flash cartridge
//============================
bool Cartridge::load_sufami_turbo(const char *base, const char *slotA, const char *slotB) {
uint8_t *data;
unsigned size;
bool patch_applied;
cart.filename = base;
stA.filename = slotA;
stB.filename = slotB;
load_begin(ModeSufamiTurbo);
if(load_image(base, data, size, patch_applied) == false) return false;
snes.config.path.current = basepath(cart.filename);
if(patch_applied) set(patched, true);
cartinfo_t cartinfo;
read_header(cartinfo, cart.rom = data, cart.rom_size = size);
set_cartinfo(cartinfo);
if(load_image(slotA, data, size, patch_applied) == true) {
if(patch_applied) set(patched, true);
stA.rom = new(zeromemory) uint8_t[stA.rom_size = 0x100000];
memcpy(stA.rom, data, min(size, stA.rom_size));
delete[] data;
load_ram(get_filename(slotA, "srm", snes.config.path.save), stA.ram, stA.ram_size = 0x020000, 0xff);
}
if(load_image(slotB, data, size, patch_applied) == true) {
if(patch_applied) set(patched, true);
stB.rom = new(zeromemory) uint8_t[stB.rom_size = 0x100000];
memcpy(stB.rom, data, min(size, stB.rom_size));
delete[] data;
load_ram(get_filename(slotB, "srm", snes.config.path.save), stB.ram, stB.ram_size = 0x020000, 0xff);
}
load_end();
string filename;
if(!*slotA && !*slotB) filename << basename(base);
else if( *slotA && !*slotB) filename << basename(slotA);
else if(!*slotA && *slotB) filename << basename(slotB);
else filename << basename(slotA) << " + " << basename(slotB);
set(name, filename);
return true;
}
void Cartridge::unload_sufami_turbo() {
if(stA.ram) save_file(get_filename(stA.filename, "srm", snes.config.path.save), stA.ram, stA.ram_size);
if(stB.ram) save_file(get_filename(stB.filename, "srm", snes.config.path.save), stB.ram, stB.ram_size);
}
//=================
//utility functions
//=================
Cartridge::Type Cartridge::detect_image_type(const char *filename) const {
uint8_t *data;
unsigned size;
bool patch_applied;
if(!load_image(filename, data, size, patch_applied)) return TypeUnknown;
cartinfo_t info;
read_header(info, data, size);
delete[] data;
return info.type;
}
bool Cartridge::load_image(const char *filename, uint8_t *&data, unsigned &size, bool &patched) const {
if(!filename || !*filename) return false;
if(!load_file(filename, data, size, CompressionAuto)) return false;
if((size & 0x7fff) == 512) {
//remove 512-byte header
memmove(data, data + 512, size -= 512);
}
uint8_t *pdata;
unsigned psize;
if(load_file(get_filename(filename, "ups", snes.config.path.patch), pdata, psize, CompressionInspect) == true) {
apply_patch(pdata, psize, data, size);
delete[] pdata;
patched = true;
} else {
patched = false;
}
return true;
}
bool Cartridge::load_ram(const char *filename, uint8_t *&data, unsigned size, uint8_t init) const {
data = new uint8_t[size];
memset(data, init, size);
uint8_t *savedata;
unsigned savesize;
if(load_file(filename, savedata, savesize, CompressionNone) == false) return false;
memcpy(data, savedata, min(size, savesize));
delete[] savedata;
return true;
}
#endif

View File

@@ -1,3 +0,0 @@
::@mingw32-make platform=win compiler=mingw32-gcc
@mingw32-make platform=win compiler=mingw32-gcc enable_gzip=true enable_jma=true
@pause

View File

@@ -1,2 +0,0 @@
make platform=x compiler=gcc
#make platform=x compiler=gcc enable_gzip=true enable_jma=true

View File

@@ -1 +0,0 @@
@mingw32-make platform=win compiler=mingw32-gcc clean

View File

@@ -1 +0,0 @@
make platform=x compiler=gcc clean

View File

@@ -1,74 +0,0 @@
class CPU : public MMIO {
public:
virtual void enter() = 0;
//CPU version number
//* 1 and 2 are known
//* reported by $4210
//* affects timing (DRAM refresh, HDMA init, etc)
uint8 cpu_version;
virtual uint8 pio() = 0;
virtual bool joylatch() = 0;
virtual uint8 port_read(uint8 port) = 0;
virtual void port_write(uint8 port, uint8 value) = 0;
#include "cpuregs.hpp"
regs_t regs;
virtual void scanline() = 0;
virtual void power();
virtual void reset();
/*****
* in opcode-based CPU emulators, the main emulation routine
* will only be able to call the disassemble_opcode() function
* on clean opcode edges. but with cycle-based CPU emulators,
* the CPU may be in the middle of executing an opcode when the
* emulator (e.g. debugger) wants to disassemble an opcode. this
* would mean that important registers may not reflect what they
* did at the start of the opcode (especially regs.pc), so in
* cycle-based emulators, this function should be overridden to
* reflect whether or not an opcode has only been partially
* executed. if not, the debugger should abort attempts to skip,
* disable, or disassemble the current opcode.
*****/
virtual bool in_opcode() { return false; }
/*****
* opcode disassembler
*****/
enum {
OPTYPE_DP = 0, //dp
OPTYPE_DPX, //dp,x
OPTYPE_DPY, //dp,y
OPTYPE_IDP, //(dp)
OPTYPE_IDPX, //(dp,x)
OPTYPE_IDPY, //(dp),y
OPTYPE_ILDP, //[dp]
OPTYPE_ILDPY, //[dp],y
OPTYPE_ADDR, //addr
OPTYPE_ADDRX, //addr,x
OPTYPE_ADDRY, //addr,y
OPTYPE_IADDRX, //(addr,x)
OPTYPE_ILADDR, //[addr]
OPTYPE_LONG, //long
OPTYPE_LONGX, //long, x
OPTYPE_SR, //sr,s
OPTYPE_ISRY, //(sr,s),y
OPTYPE_ADDR_PC, //pbr:addr
OPTYPE_IADDR_PC, //pbr:(addr)
OPTYPE_RELB, //relb
OPTYPE_RELW, //relw
};
void disassemble_opcode(char *output);
uint8 dreadb(uint32 addr);
uint16 dreadw(uint32 addr);
uint32 dreadl(uint32 addr);
uint32 decode(uint8 offset_type, uint32 addr);
uint8 opcode_length();
CPU();
virtual ~CPU();
};

View File

@@ -1,4 +0,0 @@
g++ -c scpugen.cpp -I../../../lib
g++ -c ../../../lib/nall/string.cpp -I../../../lib
g++ -o scpugen scpugen.o string.o
rm *.o

View File

@@ -1 +0,0 @@
rm scpugen

View File

@@ -1,90 +0,0 @@
#ifdef SCPU_CPP
#include "opfn.cpp"
void sCPU::enter() {
initialize:
//initial latch values for $213c/$213d
//[x]0035 : [y]0000 (53.0 -> 212) [lda $2137]
//[x]0038 : [y]0000 (56.5 -> 226) [nop : lda $2137]
add_clocks(186);
loop:
if(status.interrupt_pending) {
status.interrupt_pending = false;
if(status.nmi_pending) {
status.nmi_pending = false;
status.interrupt_vector = (regs.e == false ? 0xffea : 0xfffa);
} else if(status.irq_pending) {
status.irq_pending = false;
status.interrupt_vector = (regs.e == false ? 0xffee : 0xfffe);
}
op_irq();
}
tracer.trace_cpuop(); //traces CPU opcode (only if tracer is enabled)
status.in_opcode = true;
switch(op_readpc()) {
#include "op_read.cpp"
#include "op_write.cpp"
#include "op_rmw.cpp"
#include "op_pc.cpp"
#include "op_misc.cpp"
}
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(status.interrupt_vector + 0);
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
rd.h = op_read(status.interrupt_vector + 1);
regs.pc.w = rd.w;
}
//immediate, 2-cycle opcodes with I/O cycle will become bus read
//when an IRQ is to be triggered immediately after opcode completion
//this affects the following opcodes:
// clc, cld, cli, clv, sec, sed, sei,
// tax, tay, txa, txy, tya, tyx,
// tcd, tcs, tdc, tsc, tsx, txs,
// inc, inx, iny, dec, dex, dey,
// asl, lsr, rol, ror, nop, xce.
alwaysinline void sCPU::op_io_irq() {
if(status.interrupt_pending) {
//IRQ pending, modify I/O cycle to bus read cycle, do not increment PC
op_read(regs.pc.d);
} else {
op_io();
}
}
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

View File

@@ -1,298 +0,0 @@
nop(0xea) {
1:last_cycle();
op_io_irq();
}
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(true) op_io();
}
wai(0xcb) {
//last_cycle() will clear status.wai_lock once an NMI / IRQ edge is reached
1:status.wai_lock = true;
while(status.wai_lock) {
last_cycle();
op_io();
}
2:op_io();
}
xce(0xfb) {
1:last_cycle();
op_io_irq();
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_irq();
$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_irq();
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_irq();
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_irq();
regs.s.w = regs.a.w;
if(regs.e) regs.s.h = 0x01;
}
tdc(0x7b) {
1:last_cycle();
op_io_irq();
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_irq();
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_irq();
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_irq();
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;
}

View File

@@ -1,539 +0,0 @@
#ifdef SCPU_CPP
//nop
case 0xea: {
last_cycle();
op_io_irq();
} break;
//wdm
case 0x42: {
last_cycle();
op_readpc();
} break;
//xba
case 0xeb: {
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);
} break;
//mvn
case 0x54: {
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;
} break;
//mvp
case 0x44: {
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;
} break;
//brk
case 0x00: {
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;
} break;
//cop
case 0x02: {
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;
} break;
//stp
case 0xdb: {
op_io();
last_cycle();
while(true) op_io();
} break;
//wai
case 0xcb: {
//last_cycle() will clear status.wai_lock once an NMI / IRQ edge is reached
status.wai_lock = true;
while(status.wai_lock) {
last_cycle();
op_io();
}
op_io();
} break;
//xce
case 0xfb: {
last_cycle();
op_io_irq();
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;
}
} break;
//clc
case 0x18: {
last_cycle();
op_io_irq();
regs.p.c = 0;
} break;
//cld
case 0xd8: {
last_cycle();
op_io_irq();
regs.p.d = 0;
} break;
//cli
case 0x58: {
last_cycle();
op_io_irq();
regs.p.i = 0;
} break;
//clv
case 0xb8: {
last_cycle();
op_io_irq();
regs.p.v = 0;
} break;
//sec
case 0x38: {
last_cycle();
op_io_irq();
regs.p.c = 1;
} break;
//sed
case 0xf8: {
last_cycle();
op_io_irq();
regs.p.d = 1;
} break;
//sei
case 0x78: {
last_cycle();
op_io_irq();
regs.p.i = 1;
} break;
//rep
case 0xc2: {
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;
}
} break;
//sep
case 0xe2: {
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;
}
} break;
//tax
case 0xaa: {
last_cycle();
op_io_irq();
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);
}
} break;
//tay
case 0xa8: {
last_cycle();
op_io_irq();
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);
}
} break;
//txa
case 0x8a: {
last_cycle();
op_io_irq();
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);
}
} break;
//txy
case 0x9b: {
last_cycle();
op_io_irq();
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);
}
} break;
//tya
case 0x98: {
last_cycle();
op_io_irq();
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);
}
} break;
//tyx
case 0xbb: {
last_cycle();
op_io_irq();
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);
}
} break;
//tcd
case 0x5b: {
last_cycle();
op_io_irq();
regs.d.w = regs.a.w;
regs.p.n = !!(regs.d.w & 0x8000);
regs.p.z = (regs.d.w == 0);
} break;
//tcs
case 0x1b: {
last_cycle();
op_io_irq();
regs.s.w = regs.a.w;
if(regs.e) regs.s.h = 0x01;
} break;
//tdc
case 0x7b: {
last_cycle();
op_io_irq();
regs.a.w = regs.d.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
} break;
//tsc
case 0x3b: {
last_cycle();
op_io_irq();
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);
}
} break;
//tsx
case 0xba: {
last_cycle();
op_io_irq();
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);
}
} break;
//txs
case 0x9a: {
last_cycle();
op_io_irq();
if(regs.e) {
regs.s.l = regs.x.l;
} else {
regs.s.w = regs.x.w;
}
} break;
//pha
case 0x48: {
op_io();
if(!regs.p.m)op_writestack(regs.a.h);
last_cycle();
op_writestack(regs.a.l);
} break;
//phx
case 0xda: {
op_io();
if(!regs.p.x)op_writestack(regs.x.h);
last_cycle();
op_writestack(regs.x.l);
} break;
//phy
case 0x5a: {
op_io();
if(!regs.p.x)op_writestack(regs.y.h);
last_cycle();
op_writestack(regs.y.l);
} break;
//phd
case 0x0b: {
op_io();
op_writestackn(regs.d.h);
last_cycle();
op_writestackn(regs.d.l);
if(regs.e) regs.s.h = 0x01;
} break;
//phb
case 0x8b: {
op_io();
last_cycle();
op_writestack(regs.db);
} break;
//phk
case 0x4b: {
op_io();
last_cycle();
op_writestack(regs.pc.b);
} break;
//php
case 0x08: {
op_io();
last_cycle();
op_writestack(regs.p);
} break;
//pla
case 0x68: {
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);
break;
}
last_cycle();
regs.a.h = op_readstack();
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
} break;
//plx
case 0xfa: {
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);
break;
}
last_cycle();
regs.x.h = op_readstack();
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
} break;
//ply
case 0x7a: {
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);
break;
}
last_cycle();
regs.y.h = op_readstack();
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
} break;
//pld
case 0x2b: {
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;
} break;
//plb
case 0xab: {
op_io();
op_io();
last_cycle();
regs.db = op_readstack();
regs.p.n = !!(regs.db & 0x80);
regs.p.z = (regs.db == 0);
} break;
//plp
case 0x28: {
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;
}
} break;
//pea
case 0xf4: {
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;
} break;
//pei
case 0xd4: {
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;
} break;
//per
case 0x62: {
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;
} break;
#endif

View File

@@ -1,163 +0,0 @@
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;
}

View File

@@ -1,279 +0,0 @@
#ifdef SCPU_CPP
//bcc
case 0x90: {
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 {
break;
}
op_io_cond6(aa.w);
last_cycle();
op_io();
} break;
//bcs
case 0xb0: {
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 {
break;
}
op_io_cond6(aa.w);
last_cycle();
op_io();
} break;
//bne
case 0xd0: {
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 {
break;
}
op_io_cond6(aa.w);
last_cycle();
op_io();
} break;
//beq
case 0xf0: {
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 {
break;
}
op_io_cond6(aa.w);
last_cycle();
op_io();
} break;
//bpl
case 0x10: {
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 {
break;
}
op_io_cond6(aa.w);
last_cycle();
op_io();
} break;
//bmi
case 0x30: {
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 {
break;
}
op_io_cond6(aa.w);
last_cycle();
op_io();
} break;
//bvc
case 0x50: {
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 {
break;
}
op_io_cond6(aa.w);
last_cycle();
op_io();
} break;
//bvs
case 0x70: {
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 {
break;
}
op_io_cond6(aa.w);
last_cycle();
op_io();
} break;
//bra
case 0x80: {
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();
} break;
//brl
case 0x82: {
rd.l = op_readpc();
rd.h = op_readpc();
last_cycle();
op_io();
regs.pc.w = regs.pc.d + (int16)rd.w;
} break;
//jmp_addr
case 0x4c: {
rd.l = op_readpc();
last_cycle();
rd.h = op_readpc();
regs.pc.w = rd.w;
} break;
//jmp_long
case 0x5c: {
rd.l = op_readpc();
rd.h = op_readpc();
last_cycle();
rd.b = op_readpc();
regs.pc.d = rd.d & 0xffffff;
} break;
//jmp_iaddr
case 0x6c: {
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;
} break;
//jmp_iaddrx
case 0x7c: {
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;
} break;
//jmp_iladdr
case 0xdc: {
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;
} break;
//jsr_addr
case 0x20: {
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;
} break;
//jsr_long
case 0x22: {
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;
} break;
//jsr_iaddrx
case 0xfc: {
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;
} break;
//rti
case 0x40: {
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;
break;
}
last_cycle();
rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
} break;
//rts
case 0x60: {
op_io();
op_io();
rd.l = op_readstack();
rd.h = op_readstack();
last_cycle();
op_io();
regs.pc.w = rd.w;
regs.pc.w++;
} break;
//rtl
case 0x6b: {
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;
} break;
#endif

View File

@@ -1,317 +0,0 @@
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

View File

@@ -1,181 +0,0 @@
inc(0x1a, regs.p.m, a),
inx(0xe8, regs.p.x, x),
iny(0xc8, regs.p.x, y) {
1:last_cycle();
op_io_irq();
if($1) {
regs.$2.l++;
regs.p.n = !!(regs.$2.l & 0x80);
regs.p.z = (regs.$2.l == 0);
} else {
regs.$2.w++;
regs.p.n = !!(regs.$2.w & 0x8000);
regs.p.z = (regs.$2.w == 0);
}
}
dec(0x3a, regs.p.m, a),
dex(0xca, regs.p.x, x),
dey(0x88, regs.p.x, y) {
1:last_cycle();
op_io_irq();
if($1) {
regs.$2.l--;
regs.p.n = !!(regs.$2.l & 0x80);
regs.p.z = (regs.$2.l == 0);
} else {
regs.$2.w--;
regs.p.n = !!(regs.$2.w & 0x8000);
regs.p.z = (regs.$2.w == 0);
}
}
asl(0x0a) {
1:last_cycle();
op_io_irq();
if(regs.p.m) {
regs.p.c = !!(regs.a.l & 0x80);
regs.a.l <<= 1;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.c = !!(regs.a.w & 0x8000);
regs.a.w <<= 1;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
lsr(0x4a) {
1:last_cycle();
op_io_irq();
if(regs.p.m) {
regs.p.c = regs.a.l & 1;
regs.a.l >>= 1;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.c = regs.a.w & 1;
regs.a.w >>= 1;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
rol(0x2a) {
1:last_cycle();
op_io_irq();
uint16 c = regs.p.c;
if(regs.p.m) {
regs.p.c = !!(regs.a.l & 0x80);
regs.a.l <<= 1;
regs.a.l |= c;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.c = !!(regs.a.w & 0x8000);
regs.a.w <<= 1;
regs.a.w |= c;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
ror(0x6a) {
1:last_cycle();
op_io_irq();
uint16 c;
if(regs.p.m) {
c = regs.p.c ? 0x80 : 0;
regs.p.c = regs.a.l & 1;
regs.a.l >>= 1;
regs.a.l |= c;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
c = regs.p.c ? 0x8000 : 0;
regs.p.c = regs.a.w & 1;
regs.a.w >>= 1;
regs.a.w |= c;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
inc_addr(0xee, inc),
dec_addr(0xce, dec),
asl_addr(0x0e, asl),
lsr_addr(0x4e, lsr),
rol_addr(0x2e, rol),
ror_addr(0x6e, ror),
trb_addr(0x1c, trb),
tsb_addr(0x0c, tsb) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:rd.l = op_readdbr(aa.w);
4:if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
5:op_io();
if(regs.p.m) { op_$1_b(); }
else { op_$1_w();
6:op_writedbr(aa.w + 1, rd.h); }
7:last_cycle();
op_writedbr(aa.w, rd.l);
}
inc_addrx(0xfe, inc),
dec_addrx(0xde, dec),
asl_addrx(0x1e, asl),
lsr_addrx(0x5e, lsr),
rol_addrx(0x3e, rol),
ror_addrx(0x7e, ror) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:op_io();
4:rd.l = op_readdbr(aa.w + regs.x.w);
5:if(!regs.p.m) rd.h = op_readdbr(aa.w + regs.x.w + 1);
6:op_io();
if(regs.p.m) { op_$1_b(); }
else { op_$1_w();
7:op_writedbr(aa.w + regs.x.w + 1, rd.h); }
8:last_cycle();
op_writedbr(aa.w + regs.x.w, rd.l);
}
inc_dp(0xe6, inc),
dec_dp(0xc6, dec),
asl_dp(0x06, asl),
lsr_dp(0x46, lsr),
rol_dp(0x26, rol),
ror_dp(0x66, ror),
trb_dp(0x14, trb),
tsb_dp(0x04, tsb) {
1:dp = op_readpc();
2:op_io_cond2();
3:rd.l = op_readdp(dp);
4:if(!regs.p.m) rd.h = op_readdp(dp + 1);
5:op_io();
if(regs.p.m) { op_$1_b(); }
else { op_$1_w();
6:op_writedp(dp + 1, rd.h); }
7:last_cycle();
op_writedp(dp, rd.l);
}
inc_dpx(0xf6, inc),
dec_dpx(0xd6, dec),
asl_dpx(0x16, asl),
lsr_dpx(0x56, lsr),
rol_dpx(0x36, rol),
ror_dpx(0x76, ror) {
1:dp = op_readpc();
2:op_io_cond2();
3:op_io();
4:rd.l = op_readdp(dp + regs.x.w);
5:if(!regs.p.m) rd.h = op_readdp(dp + regs.x.w + 1);
6:op_io();
if(regs.p.m) { op_$1_b(); }
else { op_$1_w();
7:op_writedp(dp + regs.x.w + 1, rd.h); }
8:last_cycle();
op_writedp(dp + regs.x.w, rd.l);
}

View File

@@ -1,573 +0,0 @@
#ifdef SCPU_CPP
//inc
case 0x1a: {
last_cycle();
op_io_irq();
if(regs.p.m) {
regs.a.l++;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.a.w++;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
} break;
//inx
case 0xe8: {
last_cycle();
op_io_irq();
if(regs.p.x) {
regs.x.l++;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
} else {
regs.x.w++;
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
} break;
//iny
case 0xc8: {
last_cycle();
op_io_irq();
if(regs.p.x) {
regs.y.l++;
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
} else {
regs.y.w++;
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}
} break;
//dec
case 0x3a: {
last_cycle();
op_io_irq();
if(regs.p.m) {
regs.a.l--;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.a.w--;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
} break;
//dex
case 0xca: {
last_cycle();
op_io_irq();
if(regs.p.x) {
regs.x.l--;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
} else {
regs.x.w--;
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
} break;
//dey
case 0x88: {
last_cycle();
op_io_irq();
if(regs.p.x) {
regs.y.l--;
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
} else {
regs.y.w--;
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}
} break;
//asl
case 0x0a: {
last_cycle();
op_io_irq();
if(regs.p.m) {
regs.p.c = !!(regs.a.l & 0x80);
regs.a.l <<= 1;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.c = !!(regs.a.w & 0x8000);
regs.a.w <<= 1;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
} break;
//lsr
case 0x4a: {
last_cycle();
op_io_irq();
if(regs.p.m) {
regs.p.c = regs.a.l & 1;
regs.a.l >>= 1;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.c = regs.a.w & 1;
regs.a.w >>= 1;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
} break;
//rol
case 0x2a: {
last_cycle();
op_io_irq();
uint16 c = regs.p.c;
if(regs.p.m) {
regs.p.c = !!(regs.a.l & 0x80);
regs.a.l <<= 1;
regs.a.l |= c;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.c = !!(regs.a.w & 0x8000);
regs.a.w <<= 1;
regs.a.w |= c;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
} break;
//ror
case 0x6a: {
last_cycle();
op_io_irq();
uint16 c;
if(regs.p.m) {
c = regs.p.c ? 0x80 : 0;
regs.p.c = regs.a.l & 1;
regs.a.l >>= 1;
regs.a.l |= c;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
c = regs.p.c ? 0x8000 : 0;
regs.p.c = regs.a.w & 1;
regs.a.w >>= 1;
regs.a.w |= c;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
} break;
//inc_addr
case 0xee: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.p.m) { op_inc_b(); }
else { op_inc_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
op_writedbr(aa.w, rd.l);
} break;
//dec_addr
case 0xce: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.p.m) { op_dec_b(); }
else { op_dec_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
op_writedbr(aa.w, rd.l);
} break;
//asl_addr
case 0x0e: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.p.m) { op_asl_b(); }
else { op_asl_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
op_writedbr(aa.w, rd.l);
} break;
//lsr_addr
case 0x4e: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.p.m) { op_lsr_b(); }
else { op_lsr_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
op_writedbr(aa.w, rd.l);
} break;
//rol_addr
case 0x2e: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.p.m) { op_rol_b(); }
else { op_rol_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
op_writedbr(aa.w, rd.l);
} break;
//ror_addr
case 0x6e: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.p.m) { op_ror_b(); }
else { op_ror_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
op_writedbr(aa.w, rd.l);
} break;
//trb_addr
case 0x1c: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.p.m) { op_trb_b(); }
else { op_trb_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
op_writedbr(aa.w, rd.l);
} break;
//tsb_addr
case 0x0c: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.p.m) { op_tsb_b(); }
else { op_tsb_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
op_writedbr(aa.w, rd.l);
} break;
//inc_addrx
case 0xfe: {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
rd.l = op_readdbr(aa.w + regs.x.w);
if(!regs.p.m) rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_io();
if(regs.p.m) { op_inc_b(); }
else { op_inc_w();
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
last_cycle();
op_writedbr(aa.w + regs.x.w, rd.l);
} break;
//dec_addrx
case 0xde: {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
rd.l = op_readdbr(aa.w + regs.x.w);
if(!regs.p.m) rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_io();
if(regs.p.m) { op_dec_b(); }
else { op_dec_w();
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
last_cycle();
op_writedbr(aa.w + regs.x.w, rd.l);
} break;
//asl_addrx
case 0x1e: {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
rd.l = op_readdbr(aa.w + regs.x.w);
if(!regs.p.m) rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_io();
if(regs.p.m) { op_asl_b(); }
else { op_asl_w();
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
last_cycle();
op_writedbr(aa.w + regs.x.w, rd.l);
} break;
//lsr_addrx
case 0x5e: {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
rd.l = op_readdbr(aa.w + regs.x.w);
if(!regs.p.m) rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_io();
if(regs.p.m) { op_lsr_b(); }
else { op_lsr_w();
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
last_cycle();
op_writedbr(aa.w + regs.x.w, rd.l);
} break;
//rol_addrx
case 0x3e: {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
rd.l = op_readdbr(aa.w + regs.x.w);
if(!regs.p.m) rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_io();
if(regs.p.m) { op_rol_b(); }
else { op_rol_w();
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
last_cycle();
op_writedbr(aa.w + regs.x.w, rd.l);
} break;
//ror_addrx
case 0x7e: {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
rd.l = op_readdbr(aa.w + regs.x.w);
if(!regs.p.m) rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_io();
if(regs.p.m) { op_ror_b(); }
else { op_ror_w();
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
last_cycle();
op_writedbr(aa.w + regs.x.w, rd.l);
} break;
//inc_dp
case 0xe6: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.p.m) rd.h = op_readdp(dp + 1);
op_io();
if(regs.p.m) { op_inc_b(); }
else { op_inc_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
op_writedp(dp, rd.l);
} break;
//dec_dp
case 0xc6: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.p.m) rd.h = op_readdp(dp + 1);
op_io();
if(regs.p.m) { op_dec_b(); }
else { op_dec_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
op_writedp(dp, rd.l);
} break;
//asl_dp
case 0x06: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.p.m) rd.h = op_readdp(dp + 1);
op_io();
if(regs.p.m) { op_asl_b(); }
else { op_asl_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
op_writedp(dp, rd.l);
} break;
//lsr_dp
case 0x46: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.p.m) rd.h = op_readdp(dp + 1);
op_io();
if(regs.p.m) { op_lsr_b(); }
else { op_lsr_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
op_writedp(dp, rd.l);
} break;
//rol_dp
case 0x26: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.p.m) rd.h = op_readdp(dp + 1);
op_io();
if(regs.p.m) { op_rol_b(); }
else { op_rol_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
op_writedp(dp, rd.l);
} break;
//ror_dp
case 0x66: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.p.m) rd.h = op_readdp(dp + 1);
op_io();
if(regs.p.m) { op_ror_b(); }
else { op_ror_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
op_writedp(dp, rd.l);
} break;
//trb_dp
case 0x14: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.p.m) rd.h = op_readdp(dp + 1);
op_io();
if(regs.p.m) { op_trb_b(); }
else { op_trb_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
op_writedp(dp, rd.l);
} break;
//tsb_dp
case 0x04: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.p.m) rd.h = op_readdp(dp + 1);
op_io();
if(regs.p.m) { op_tsb_b(); }
else { op_tsb_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
op_writedp(dp, rd.l);
} break;
//inc_dpx
case 0xf6: {
dp = op_readpc();
op_io_cond2();
op_io();
rd.l = op_readdp(dp + regs.x.w);
if(!regs.p.m) rd.h = op_readdp(dp + regs.x.w + 1);
op_io();
if(regs.p.m) { op_inc_b(); }
else { op_inc_w();
op_writedp(dp + regs.x.w + 1, rd.h); }
last_cycle();
op_writedp(dp + regs.x.w, rd.l);
} break;
//dec_dpx
case 0xd6: {
dp = op_readpc();
op_io_cond2();
op_io();
rd.l = op_readdp(dp + regs.x.w);
if(!regs.p.m) rd.h = op_readdp(dp + regs.x.w + 1);
op_io();
if(regs.p.m) { op_dec_b(); }
else { op_dec_w();
op_writedp(dp + regs.x.w + 1, rd.h); }
last_cycle();
op_writedp(dp + regs.x.w, rd.l);
} break;
//asl_dpx
case 0x16: {
dp = op_readpc();
op_io_cond2();
op_io();
rd.l = op_readdp(dp + regs.x.w);
if(!regs.p.m) rd.h = op_readdp(dp + regs.x.w + 1);
op_io();
if(regs.p.m) { op_asl_b(); }
else { op_asl_w();
op_writedp(dp + regs.x.w + 1, rd.h); }
last_cycle();
op_writedp(dp + regs.x.w, rd.l);
} break;
//lsr_dpx
case 0x56: {
dp = op_readpc();
op_io_cond2();
op_io();
rd.l = op_readdp(dp + regs.x.w);
if(!regs.p.m) rd.h = op_readdp(dp + regs.x.w + 1);
op_io();
if(regs.p.m) { op_lsr_b(); }
else { op_lsr_w();
op_writedp(dp + regs.x.w + 1, rd.h); }
last_cycle();
op_writedp(dp + regs.x.w, rd.l);
} break;
//rol_dpx
case 0x36: {
dp = op_readpc();
op_io_cond2();
op_io();
rd.l = op_readdp(dp + regs.x.w);
if(!regs.p.m) rd.h = op_readdp(dp + regs.x.w + 1);
op_io();
if(regs.p.m) { op_rol_b(); }
else { op_rol_w();
op_writedp(dp + regs.x.w + 1, rd.h); }
last_cycle();
op_writedp(dp + regs.x.w, rd.l);
} break;
//ror_dpx
case 0x76: {
dp = op_readpc();
op_io_cond2();
op_io();
rd.l = op_readdp(dp + regs.x.w);
if(!regs.p.m) rd.h = op_readdp(dp + regs.x.w + 1);
op_io();
if(regs.p.m) { op_ror_b(); }
else { op_ror_w();
op_writedp(dp + regs.x.w + 1, rd.h); }
last_cycle();
op_writedp(dp + regs.x.w, rd.l);
} break;
#endif

View File

@@ -1,181 +0,0 @@
sta_addr(0x8d, regs.p.m, regs.a.w),
stx_addr(0x8e, regs.p.x, regs.x.w),
sty_addr(0x8c, regs.p.x, regs.y.w),
stz_addr(0x9c, regs.p.m, 0x0000) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:if($1) last_cycle();
op_writedbr(aa.w, $2);
if($1) end;
4:last_cycle();
op_writedbr(aa.w + 1, $2 >> 8);
}
sta_addrx(0x9d, regs.p.m, regs.a.w),
stz_addrx(0x9e, regs.p.m, 0x0000) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:op_io();
4:if($1) last_cycle();
op_writedbr(aa.w + regs.x.w, $2);
if($1) end;
5:last_cycle();
op_writedbr(aa.w + regs.x.w + 1, $2 >> 8);
}
sta_addry(0x99) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:op_io();
4:if(regs.p.m) last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m) end;
5:last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
}
sta_long(0x8f) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:aa.b = op_readpc();
4:if(regs.p.m) last_cycle();
op_writelong(aa.d, regs.a.l);
if(regs.p.m) end;
5:last_cycle();
op_writelong(aa.d + 1, regs.a.h);
}
sta_longx(0x9f) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:aa.b = op_readpc();
4:if(regs.p.m) last_cycle();
op_writelong(aa.d + regs.x.w, regs.a.l);
if(regs.p.m) end;
5:last_cycle();
op_writelong(aa.d + regs.x.w + 1, regs.a.h);
}
sta_dp(0x85, regs.p.m, regs.a.w),
stx_dp(0x86, regs.p.x, regs.x.w),
sty_dp(0x84, regs.p.x, regs.y.w),
stz_dp(0x64, regs.p.m, 0x0000) {
1:dp = op_readpc();
2:op_io_cond2();
3:if($1) last_cycle();
op_writedp(dp, $2);
if($1) end;
4:last_cycle();
op_writedp(dp + 1, $2 >> 8);
}
sta_dpx(0x95, regs.p.m, regs.a.w),
sty_dpx(0x94, regs.p.x, regs.y.w),
stz_dpx(0x74, regs.p.m, 0x0000) {
1:dp = op_readpc();
2:op_io_cond2();
3:op_io();
4:if($1) last_cycle();
op_writedp(dp + regs.x.w, $2);
if($1) end;
5:last_cycle();
op_writedp(dp + regs.x.w + 1, $2 >> 8);
}
stx_dpy(0x96) {
1:dp = op_readpc();
2:op_io_cond2();
3:op_io();
4:if(regs.p.x) last_cycle();
op_writedp(dp + regs.y.w, regs.x.l);
if(regs.p.x) end;
5:last_cycle();
op_writedp(dp + regs.y.w + 1, regs.x.h);
}
sta_idp(0x92) {
1:dp = op_readpc();
2:op_io_cond2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:if(regs.p.m) last_cycle();
op_writedbr(aa.w, regs.a.l);
if(regs.p.m) end;
6:last_cycle();
op_writedbr(aa.w + 1, regs.a.h);
}
sta_ildp(0x87) {
1:dp = op_readpc();
2:op_io_cond2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:aa.b = op_readdp(dp + 2);
6:if(regs.p.m) last_cycle();
op_writelong(aa.d, regs.a.l);
if(regs.p.m) end;
7:last_cycle();
op_writelong(aa.d + 1, regs.a.h);
}
sta_idpx(0x81) {
1:dp = op_readpc();
2:op_io_cond2();
3:op_io();
4:aa.l = op_readdp(dp + regs.x.w);
5:aa.h = op_readdp(dp + regs.x.w + 1);
6:if(regs.p.m) last_cycle();
op_writedbr(aa.w, regs.a.l);
if(regs.p.m) end;
7:last_cycle();
op_writedbr(aa.w + 1, regs.a.h);
}
sta_idpy(0x91) {
1:dp = op_readpc();
2:op_io_cond2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:op_io();
6:if(regs.p.m) last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m) end;
7:last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
}
sta_ildpy(0x97) {
1:dp = op_readpc();
2:op_io_cond2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:aa.b = op_readdp(dp + 2);
6:if(regs.p.m) last_cycle();
op_writelong(aa.d + regs.y.w, regs.a.l);
if(regs.p.m) end;
7:last_cycle();
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
}
sta_sr(0x83) {
1:sp = op_readpc();
2:op_io();
3:if(regs.p.m) last_cycle();
op_writesp(sp, regs.a.l);
if(regs.p.m) end;
4:last_cycle();
op_writesp(sp + 1, regs.a.h);
}
sta_isry(0x93) {
1:sp = op_readpc();
2:op_io();
3:aa.l = op_readsp(sp);
4:aa.h = op_readsp(sp + 1);
5:op_io();
6:if(regs.p.m) last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m) end;
7:last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
}

View File

@@ -1,293 +0,0 @@
#ifdef SCPU_CPP
//sta_addr
case 0x8d: {
aa.l = op_readpc();
aa.h = op_readpc();
if(regs.p.m) last_cycle();
op_writedbr(aa.w, regs.a.w);
if(regs.p.m) break;
last_cycle();
op_writedbr(aa.w + 1, regs.a.w >> 8);
} break;
//stx_addr
case 0x8e: {
aa.l = op_readpc();
aa.h = op_readpc();
if(regs.p.x) last_cycle();
op_writedbr(aa.w, regs.x.w);
if(regs.p.x) break;
last_cycle();
op_writedbr(aa.w + 1, regs.x.w >> 8);
} break;
//sty_addr
case 0x8c: {
aa.l = op_readpc();
aa.h = op_readpc();
if(regs.p.x) last_cycle();
op_writedbr(aa.w, regs.y.w);
if(regs.p.x) break;
last_cycle();
op_writedbr(aa.w + 1, regs.y.w >> 8);
} break;
//stz_addr
case 0x9c: {
aa.l = op_readpc();
aa.h = op_readpc();
if(regs.p.m) last_cycle();
op_writedbr(aa.w, 0x0000);
if(regs.p.m) break;
last_cycle();
op_writedbr(aa.w + 1, 0x0000 >> 8);
} break;
//sta_addrx
case 0x9d: {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
if(regs.p.m) last_cycle();
op_writedbr(aa.w + regs.x.w, regs.a.w);
if(regs.p.m) break;
last_cycle();
op_writedbr(aa.w + regs.x.w + 1, regs.a.w >> 8);
} break;
//stz_addrx
case 0x9e: {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
if(regs.p.m) last_cycle();
op_writedbr(aa.w + regs.x.w, 0x0000);
if(regs.p.m) break;
last_cycle();
op_writedbr(aa.w + regs.x.w + 1, 0x0000 >> 8);
} break;
//sta_addry
case 0x99: {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
if(regs.p.m) last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m) break;
last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
} break;
//sta_long
case 0x8f: {
aa.l = op_readpc();
aa.h = op_readpc();
aa.b = op_readpc();
if(regs.p.m) last_cycle();
op_writelong(aa.d, regs.a.l);
if(regs.p.m) break;
last_cycle();
op_writelong(aa.d + 1, regs.a.h);
} break;
//sta_longx
case 0x9f: {
aa.l = op_readpc();
aa.h = op_readpc();
aa.b = op_readpc();
if(regs.p.m) last_cycle();
op_writelong(aa.d + regs.x.w, regs.a.l);
if(regs.p.m) break;
last_cycle();
op_writelong(aa.d + regs.x.w + 1, regs.a.h);
} break;
//sta_dp
case 0x85: {
dp = op_readpc();
op_io_cond2();
if(regs.p.m) last_cycle();
op_writedp(dp, regs.a.w);
if(regs.p.m) break;
last_cycle();
op_writedp(dp + 1, regs.a.w >> 8);
} break;
//stx_dp
case 0x86: {
dp = op_readpc();
op_io_cond2();
if(regs.p.x) last_cycle();
op_writedp(dp, regs.x.w);
if(regs.p.x) break;
last_cycle();
op_writedp(dp + 1, regs.x.w >> 8);
} break;
//sty_dp
case 0x84: {
dp = op_readpc();
op_io_cond2();
if(regs.p.x) last_cycle();
op_writedp(dp, regs.y.w);
if(regs.p.x) break;
last_cycle();
op_writedp(dp + 1, regs.y.w >> 8);
} break;
//stz_dp
case 0x64: {
dp = op_readpc();
op_io_cond2();
if(regs.p.m) last_cycle();
op_writedp(dp, 0x0000);
if(regs.p.m) break;
last_cycle();
op_writedp(dp + 1, 0x0000 >> 8);
} break;
//sta_dpx
case 0x95: {
dp = op_readpc();
op_io_cond2();
op_io();
if(regs.p.m) last_cycle();
op_writedp(dp + regs.x.w, regs.a.w);
if(regs.p.m) break;
last_cycle();
op_writedp(dp + regs.x.w + 1, regs.a.w >> 8);
} break;
//sty_dpx
case 0x94: {
dp = op_readpc();
op_io_cond2();
op_io();
if(regs.p.x) last_cycle();
op_writedp(dp + regs.x.w, regs.y.w);
if(regs.p.x) break;
last_cycle();
op_writedp(dp + regs.x.w + 1, regs.y.w >> 8);
} break;
//stz_dpx
case 0x74: {
dp = op_readpc();
op_io_cond2();
op_io();
if(regs.p.m) last_cycle();
op_writedp(dp + regs.x.w, 0x0000);
if(regs.p.m) break;
last_cycle();
op_writedp(dp + regs.x.w + 1, 0x0000 >> 8);
} break;
//stx_dpy
case 0x96: {
dp = op_readpc();
op_io_cond2();
op_io();
if(regs.p.x) last_cycle();
op_writedp(dp + regs.y.w, regs.x.l);
if(regs.p.x) break;
last_cycle();
op_writedp(dp + regs.y.w + 1, regs.x.h);
} break;
//sta_idp
case 0x92: {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp);
aa.h = op_readdp(dp + 1);
if(regs.p.m) last_cycle();
op_writedbr(aa.w, regs.a.l);
if(regs.p.m) break;
last_cycle();
op_writedbr(aa.w + 1, regs.a.h);
} break;
//sta_ildp
case 0x87: {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp);
aa.h = op_readdp(dp + 1);
aa.b = op_readdp(dp + 2);
if(regs.p.m) last_cycle();
op_writelong(aa.d, regs.a.l);
if(regs.p.m) break;
last_cycle();
op_writelong(aa.d + 1, regs.a.h);
} break;
//sta_idpx
case 0x81: {
dp = op_readpc();
op_io_cond2();
op_io();
aa.l = op_readdp(dp + regs.x.w);
aa.h = op_readdp(dp + regs.x.w + 1);
if(regs.p.m) last_cycle();
op_writedbr(aa.w, regs.a.l);
if(regs.p.m) break;
last_cycle();
op_writedbr(aa.w + 1, regs.a.h);
} break;
//sta_idpy
case 0x91: {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp);
aa.h = op_readdp(dp + 1);
op_io();
if(regs.p.m) last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m) break;
last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
} break;
//sta_ildpy
case 0x97: {
dp = op_readpc();
op_io_cond2();
aa.l = op_readdp(dp);
aa.h = op_readdp(dp + 1);
aa.b = op_readdp(dp + 2);
if(regs.p.m) last_cycle();
op_writelong(aa.d + regs.y.w, regs.a.l);
if(regs.p.m) break;
last_cycle();
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
} break;
//sta_sr
case 0x83: {
sp = op_readpc();
op_io();
if(regs.p.m) last_cycle();
op_writesp(sp, regs.a.l);
if(regs.p.m) break;
last_cycle();
op_writesp(sp + 1, regs.a.h);
} break;
//sta_isry
case 0x93: {
sp = op_readpc();
op_io();
aa.l = op_readsp(sp);
aa.h = op_readsp(sp + 1);
op_io();
if(regs.p.m) last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m) break;
last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
} break;
#endif

View File

@@ -1,12 +0,0 @@
#define CLASS_NAME "sCPU"
#include <tool/opgen_switch.cpp>
int main() {
generate("op_read.cpp", "op_read.b");
generate("op_write.cpp", "op_write.b");
generate("op_rmw.cpp", "op_rmw.b");
generate("op_pc.cpp", "op_pc.b");
generate("op_misc.cpp", "op_misc.b");
return 0;
}

View File

@@ -1,125 +0,0 @@
#ifdef SCPU_CPP
/*****
* These 3 functions control bus timing for the CPU.
* cpu_io is an I/O cycle, and always 6 clock cycles long.
* mem_read / mem_write indicate memory access bus cycles.
* they are either 6, 8, or 12 bus cycles long, depending
* both on location and the $420d.d0 FastROM enable bit.
*****/
void sCPU::op_io() {
status.clock_count = 6;
precycle_edge();
add_clocks(6);
cycle_edge();
}
uint8 sCPU::op_read(uint32 addr) {
status.clock_count = bus.speed(addr);
precycle_edge();
add_clocks(status.clock_count - 4);
regs.mdr = bus.read(addr);
add_clocks(4);
cycle_edge();
return regs.mdr;
}
void sCPU::op_write(uint32 addr, uint8 data) {
status.clock_count = bus.speed(addr);
precycle_edge();
add_clocks(status.clock_count);
regs.mdr = data;
bus.write(addr, regs.mdr);
cycle_edge();
}
//
alwaysinline uint8 sCPU::op_readpc() {
return op_read((regs.pc.b << 16) + regs.pc.w++);
}
alwaysinline uint8 sCPU::op_readstack() {
if(regs.e) {
regs.s.l++;
} else {
regs.s.w++;
}
return op_read(regs.s.w);
}
alwaysinline uint8 sCPU::op_readstackn() {
return op_read(++regs.s.w);
}
alwaysinline uint8 sCPU::op_readaddr(uint32 addr) {
return op_read(addr & 0xffff);
}
alwaysinline uint8 sCPU::op_readlong(uint32 addr) {
return op_read(addr & 0xffffff);
}
alwaysinline uint8 sCPU::op_readdbr(uint32 addr) {
return op_read(((regs.db << 16) + addr) & 0xffffff);
}
alwaysinline uint8 sCPU::op_readpbr(uint32 addr) {
return op_read((regs.pc.b << 16) + (addr & 0xffff));
}
alwaysinline uint8 sCPU::op_readdp(uint32 addr) {
if(regs.e && regs.d.l == 0x00) {
return op_read((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff));
} else {
return op_read((regs.d + (addr & 0xffff)) & 0xffff);
}
}
alwaysinline uint8 sCPU::op_readsp(uint32 addr) {
return op_read((regs.s + (addr & 0xffff)) & 0xffff);
}
alwaysinline void sCPU::op_writestack(uint8 data) {
op_write(regs.s.w, data);
if(regs.e) {
regs.s.l--;
} else {
regs.s.w--;
}
}
alwaysinline void sCPU::op_writestackn(uint8 data) {
op_write(regs.s.w--, data);
}
alwaysinline void sCPU::op_writeaddr(uint32 addr, uint8 data) {
op_write(addr & 0xffff, data);
}
alwaysinline void sCPU::op_writelong(uint32 addr, uint8 data) {
op_write(addr & 0xffffff, data);
}
alwaysinline void sCPU::op_writedbr(uint32 addr, uint8 data) {
op_write(((regs.db << 16) + addr) & 0xffffff, data);
}
alwaysinline void sCPU::op_writepbr(uint32 addr, uint8 data) {
op_write((regs.pc.b << 16) + (addr & 0xffff), data);
}
alwaysinline void sCPU::op_writedp(uint32 addr, uint8 data) {
if(regs.e && regs.d.l == 0x00) {
op_write((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff), data);
} else {
op_write((regs.d + (addr & 0xffff)) & 0xffff, data);
}
}
alwaysinline void sCPU::op_writesp(uint32 addr, uint8 data) {
op_write((regs.s + (addr & 0xffff)) & 0xffff, data);
}
#endif //ifdef SCPU_CPP

View File

@@ -1,35 +0,0 @@
/*****
* CPU<>APU communication ports
*****/
uint8 apu_port[4];
uint8 port_read(uint8 port) { return apu_port[port & 3]; }
void port_write(uint8 port, uint8 data) { apu_port[port & 3] = data; }
/*****
* core CPU bus functions
*****/
void op_io();
uint8 op_read(uint32 addr);
void op_write(uint32 addr, uint8 data);
/*****
* helper memory addressing functions used by CPU core
*****/
uint8 op_readpc ();
uint8 op_readstack ();
uint8 op_readstackn();
uint8 op_readaddr (uint32 addr);
uint8 op_readlong (uint32 addr);
uint8 op_readdbr (uint32 addr);
uint8 op_readpbr (uint32 addr);
uint8 op_readdp (uint32 addr);
uint8 op_readsp (uint32 addr);
void op_writestack (uint8 data);
void op_writestackn(uint8 data);
void op_writeaddr (uint32 addr, uint8 data);
void op_writelong (uint32 addr, uint8 data);
void op_writedbr (uint32 addr, uint8 data);
void op_writepbr (uint32 addr, uint8 data);
void op_writedp (uint32 addr, uint8 data);
void op_writesp (uint32 addr, uint8 data);

View File

@@ -1,61 +0,0 @@
#include <../base.hpp>
#define SCPU_CPP
#include <nall/priorityqueue.hpp>
priority_queue<unsigned> event(512, bind(&sCPU::queue_event, &cpu));
#include "core/core.cpp"
#include "dma/dma.cpp"
#include "memory/memory.cpp"
#include "mmio/mmio.cpp"
#include "timing/timing.cpp"
void sCPU::power() {
CPU::power();
regs.a = regs.x = regs.y = 0x0000;
regs.s = 0x01ff;
mmio_power();
dma_power();
timing_power();
reset();
}
void sCPU::reset() {
CPU::reset();
regs.pc.d = 0x000000;
regs.pc.l = bus.read(0xfffc);
regs.pc.h = bus.read(0xfffd);
//note: some 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;
regs.mdr = 0x00;
status.wai_lock = false;
status.interrupt_pending = false;
status.interrupt_vector = 0xfffc; //reset vector address
mmio_reset();
dma_reset();
timing_reset();
apu_port[0] = 0x00;
apu_port[1] = 0x00;
apu_port[2] = 0x00;
apu_port[3] = 0x00;
}
sCPU::sCPU() {
}
sCPU::~sCPU() {
}

View File

@@ -1,24 +0,0 @@
#include "cheat/cheat.hpp"
#include "memory/memory.hpp"
#include "memory/smemory/smemory.hpp"
#include "cpu/cpu.hpp"
#include "cpu/scpu/scpu.hpp"
#include "ppu/ppu.hpp"
#include "ppu/bppu/bppu.hpp"
#include "smp/smp.hpp"
#include "smp/ssmp/ssmp.hpp"
#include "dsp/dsp.hpp"
#include "dsp/sdsp/sdsp.hpp"
extern BUSCORE bus;
extern CPUCORE cpu;
extern SMPCORE smp;
extern DSPCORE dsp;
extern PPUCORE ppu;
#include "snes/snes.hpp"

View File

@@ -1,157 +0,0 @@
/* broken -- need to port libstring to bstring */
#include "libbase.h"
#include "libstring.h"
#include "libstring.cpp"
FILE *fp, *fph, *fpt;
stringarray data, line, part, subpart;
stringarray output_table, output_header, output_op;
struct _op_list {
stringarray name, arg;
} op_list[64];
int32 op_count, line_num;
void clear_op_list() {
op_count = 0;
for(int i = 0; i < 64; i++) {
strcpy(op_list[i].name, "");
for(int l = 0; l < 8; l++) {
strcpy(op_list[i].arg[l], "");
}
}
}
void gen_header() {
int i = line_num;
char t[4096];
clear_op_list();
while(1) {
int z = op_count++;
strcpy(part, line[i]);
strrtrim(part, "),");
strrtrim(part, ") {");
split(subpart, "(", part);
strcpy(op_list[z].name, subpart[0]);
split(part, ", ", subpart[1]);
for(int l = 0; l < count(part); l++) {
strcpy(op_list[z].arg[l], part[l]);
}
if(strend(line[i], " {"))break;
i++;
}
sprintf(output_op, "void " CLASS_NAME "::op_$$() {\r\n switch(status.cycle_pos++) {\r\n");
sprintf(output_header, "void op_$$();\r\n");
sprintf(output_table, "optbl[$0] = &" CLASS_NAME "::op_$$;\r\n");
line_num = i + 1;
}
void update_line(int i, int n) {
char t[4096];
replace(line[i], "end;", "status.cycle_pos = 0;");
replace(line[i], "skip;", "status.cycle_pos++;");
}
void gen_op() {
int i = line_num, n, c;
char t[4096];
while(1) {
if(strmatch(line[i], "}"))break;
n = strdec(line[i]);
sprintf(t, "%d:", n);
strltrim(line[i], t);
sprintf(t, " case %d: {\r\n", n);
strcat(output_op, t);
update_line(i, n);
if(!strmatch(line[i], "")) {
strcat(output_op, " ");
strcat(output_op, line[i]);
strcat(output_op, "\r\n");
}
i++;
while(1) {
if(strptr(line[i])[1] == ':' || strptr(line[i])[2] == ':' || strmatch(line[i], "}"))break;
update_line(i, n);
strcat(output_op, " ");
strcat(output_op, line[i]);
strcat(output_op, "\r\n");
i++;
}
if(strmatch(line[i], "}")) {
strcat(output_op, " status.cycle_pos = 0;\r\n");
}
strcat(output_op, " } break;\r\n");
}
strcat(output_op, " }\r\n}");
line_num = i + 1;
}
void gen_final() {
string t;
for(int i = 0; i < op_count; i++) {
strcpy(t, output_op);
replace(t, "$$", op_list[i].name);
replace(t, "$0", op_list[i].arg[0]);
replace(t, "$1", op_list[i].arg[1]);
replace(t, "$2", op_list[i].arg[2]);
replace(t, "$3", op_list[i].arg[3]);
replace(t, "$4", op_list[i].arg[4]);
replace(t, "$5", op_list[i].arg[5]);
replace(t, "$6", op_list[i].arg[6]);
replace(t, "$7", op_list[i].arg[7]);
fprintf(fp, "%s\r\n\r\n", strptr(t));
strcpy(t, output_header);
replace(t, "$$", op_list[i].name);
fprintf(fph, "%s", strptr(t));
strcpy(t, output_table);
replace(t, "$$", op_list[i].name);
replace(t, "$0", op_list[i].arg[0]);
fprintf(fpt, "%s", strptr(t));
}
}
void generate(char *dest, char *src) {
fp = fopen(src, "rb");
fseek(fp, 0, SEEK_END);
int fsize = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *buf = (char*)malloc(fsize + 1);
fread(buf, 1, fsize, fp);
fclose(fp);
buf[fsize] = 0;
strcpy(data, buf);
free(buf);
replace(data, "\r\n", "\n");
split(line, "\n", data);
fp = fopen(dest, "wb");
line_num = 0;
while(line_num < count(line)) {
while(line_num < count(line) && strmatch(line[line_num], ""))line_num++;
if(line_num >= count(line))break;
gen_header();
gen_op();
gen_final();
}
fclose(fp);
}

View File

@@ -1,149 +0,0 @@
/* broken -- need to port libstring to bstring */
#include "libbase.h"
#include "libstring.h"
#include "libstring.cpp"
FILE *fp, *fph, *fpt;
stringarray data, line, part, subpart;
stringarray output_table, output_header, output_op;
struct _op_list {
stringarray name, arg;
} op_list[64];
int32 op_count, line_num;
void clear_op_list() {
op_count = 0;
for(int i = 0; i < 64; i++) {
strcpy(op_list[i].name, "");
for(int l = 0; l < 8; l++) {
strcpy(op_list[i].arg[l], "");
}
}
}
void gen_header() {
int i = line_num;
char t[4096];
clear_op_list();
while(1) {
int z = op_count++;
strcpy(part, line[i]);
strrtrim(part, "),");
strrtrim(part, ") {");
split(subpart, "(", part);
strcpy(op_list[z].name, subpart[0]);
split(part, ", ", subpart[1]);
for(int l = 0; l < count(part); l++) {
strcpy(op_list[z].arg[l], part[l]);
}
if(strend(line[i], " {"))break;
i++;
}
sprintf(output_op, "void " CLASS_NAME "::op_$$() {\r\n");
sprintf(output_header, "void op_$$();\r\n");
sprintf(output_table, "optbl[$0] = &" CLASS_NAME "::op_$$;\r\n");
line_num = i + 1;
}
void update_line(int i) {
char t[4096];
replace(line[i], "end;", "return;");
}
void gen_op() {
int i = line_num, n, c;
char t[4096];
while(1) {
if(!strcmp(line[i], "}"))break;
n = strdec(line[i]);
sprintf(t, "%d:", n);
strltrim(line[i], t);
//sprintf(t, " case %d: {\r\n", n);
//strcat(output_op, t);
update_line(i);
if(strcmp(line[i], "")) {
strcat(output_op, " ");
strcat(output_op, line[i]);
strcat(output_op, "\r\n");
}
i++;
while(1) {
if(strptr(line[i])[1] == ':' || strptr(line[i])[2] == ':' || !strcmp(line[i], "}"))break;
update_line(i);
strcat(output_op, line[i]);
strcat(output_op, "\r\n");
i++;
}
}
strcat(output_op, "}");
line_num = i + 1;
}
void gen_final() {
string t;
for(int i = 0; i < op_count; i++) {
strcpy(t, output_op);
replace(t, "$$", op_list[i].name);
replace(t, "$0", op_list[i].arg[0]);
replace(t, "$1", op_list[i].arg[1]);
replace(t, "$2", op_list[i].arg[2]);
replace(t, "$3", op_list[i].arg[3]);
replace(t, "$4", op_list[i].arg[4]);
replace(t, "$5", op_list[i].arg[5]);
replace(t, "$6", op_list[i].arg[6]);
replace(t, "$7", op_list[i].arg[7]);
fprintf(fp, "%s\r\n\r\n", strptr(t));
strcpy(t, output_header);
replace(t, "$$", op_list[i].name);
fprintf(fph, "%s", strptr(t));
strcpy(t, output_table);
replace(t, "$$", op_list[i].name);
replace(t, "$0", op_list[i].arg[0]);
fprintf(fpt, "%s", strptr(t));
}
}
void generate(char *dest, char *src) {
fp = fopen(src, "rb");
fseek(fp, 0, SEEK_END);
int fsize = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *buf = (char*)malloc(fsize + 1);
fread(buf, 1, fsize, fp);
fclose(fp);
buf[fsize] = 0;
strcpy(data, buf);
free(buf);
replace(data, "\r\n", "\n");
split(line, "\n", data);
fp = fopen(dest, "wb");
line_num = 0;
while(line_num < count(line)) {
while(line_num < count(line) && !strcmp(line[line_num], ""))line_num++;
if(line_num >= count(line))break;
gen_header();
gen_op();
gen_final();
}
fclose(fp);
}

View File

@@ -1,127 +0,0 @@
#include <nall/string.hpp>
using namespace nall;
FILE *fp;
string data, output_op;
lstring line, part, subpart;
struct OpList {
string name;
lstring arg;
} op_list[64];
int32_t op_count, line_num;
void clear_op_list() {
op_count = 0;
for(unsigned i = 0; i < 64; i++) {
strcpy(op_list[i].name, "");
for(unsigned l = 0; l < 8; l++) {
strcpy(op_list[i].arg[l], "");
}
}
}
void gen_begin() {
int i = line_num;
clear_op_list();
while(true) {
int z = op_count++;
string temp = line[i];
rtrim(temp, "),");
rtrim(temp, ") {");
split(subpart, "(", temp);
strcpy(op_list[z].name, subpart[0]);
split(part, ", ", subpart[1]);
for(unsigned l = 0; l < count(part); l++) {
strcpy(op_list[z].arg[l], part[l]);
}
if(strend(line[i], " {") == true) break;
i++;
}
strcpy(output_op, "//$$\r\ncase $0: {\r\n");
line_num = i + 1;
}
void update_line(int i) {
replace(line[i], "end;", "break;");
}
void gen_op() {
int i = line_num, n, c;
char t[4096];
while(true) {
if(!strcmp(line[i], "}"))break;
//remove cycle number
n = strdec((const char*)line[i]);
sprintf(t, "%d:", n);
ltrim(line[i], t);
//sprintf(t, "//%d:\r\n", n);
//strcat(output_op, t);
update_line(i);
if(strcmp(line[i], "")) {
strcat(output_op, " ");
strcat(output_op, line[i]);
strcat(output_op, "\r\n");
}
i++;
while(true) {
if(line[i][1] == ':' || line[i][2] == ':' || line[i] == "}") break;
update_line(i);
strcat(output_op, line[i]);
strcat(output_op, "\r\n");
i++;
}
}
strcat(output_op, "} break;");
line_num = i + 1;
}
void gen_end() {
string t;
for(unsigned i = 0; i < op_count; i++) {
t = output_op;
replace(t, "$$", op_list[i].name);
replace(t, "$0", op_list[i].arg[0]);
replace(t, "$1", op_list[i].arg[1]);
replace(t, "$2", op_list[i].arg[2]);
replace(t, "$3", op_list[i].arg[3]);
replace(t, "$4", op_list[i].arg[4]);
replace(t, "$5", op_list[i].arg[5]);
replace(t, "$6", op_list[i].arg[6]);
replace(t, "$7", op_list[i].arg[7]);
fprintf(fp, "%s\r\n\r\n", (const char*)t);
}
}
void generate(const char *dest, const char *src) {
fread(data, src);
replace(data, "\r\n", "\n");
split(line, "\n", data);
fp = fopen(dest, "wb");
string header = CLASS_NAME;
fprintf(fp, "#ifdef %s_CPP\n\n", (const char*)strupper(header)); //inclusion guard
line_num = 0;
while(line_num < count(line)) {
while(line_num < count(line) && !strcmp(line[line_num], "")) line_num++;
if(line_num >= count(line)) break;
gen_begin();
gen_op();
gen_end();
}
fprintf(fp, "#endif\n");
fclose(fp);
}

View File

@@ -1,5 +0,0 @@
#include <../base.hpp>
#define SMP_CPP
#include "iplrom.hpp"
#include "dsmp.cpp"

View File

@@ -1,4 +0,0 @@
g++ -c ssmpgen.cpp -I../../../lib
g++ -c ../../../lib/nall/string.cpp -I../../../lib
g++ -o ssmpgen ssmpgen.o string.o
rm *.o

View File

@@ -1 +0,0 @@
rm ssmpgen

View File

@@ -1,21 +0,0 @@
#ifdef SSMP_CPP
#include "opfn.cpp"
void sSMP::enter() { loop:
tracer.trace_smpop(); //traces SMP opcode (only if tracer is enabled)
status.in_opcode = true;
switch(op_readpc()) {
#include "op_mov.cpp"
#include "op_pc.cpp"
#include "op_read.cpp"
#include "op_rmw.cpp"
#include "op_misc.cpp"
}
status.in_opcode = false;
goto loop;
}
#endif //ifdef SSMP_CPP

View File

@@ -1,163 +0,0 @@
nop(0x00) {
1:op_io();
}
sleep(0xef),
stop(0xff) {
1:op_io();
2:op_io();
regs.pc--;
}
xcn(0x9f) {
1:op_io();
2:op_io();
3:op_io();
4:op_io();
regs.a = (regs.a >> 4) | (regs.a << 4);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
daa(0xdf) {
1:op_io();
2:op_io();
if(regs.p.c || (regs.a) > 0x99) {
regs.a += 0x60;
regs.p.c = 1;
}
if(regs.p.h || (regs.a & 15) > 0x09) {
regs.a += 0x06;
}
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
das(0xbe) {
1:op_io();
2:op_io();
if(!regs.p.c || (regs.a) > 0x99) {
regs.a -= 0x60;
regs.p.c = 0;
}
if(!regs.p.h || (regs.a & 15) > 0x09) {
regs.a -= 0x06;
}
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
clrc(0x60, regs.p.c = 0),
clrp(0x20, regs.p.p = 0),
setc(0x80, regs.p.c = 1),
setp(0x40, regs.p.p = 1) {
1:op_io();
$1;
}
clrv(0xe0) {
1:op_io();
regs.p.v = 0;
regs.p.h = 0;
}
notc(0xed) {
1:op_io();
2:op_io();
regs.p.c = !regs.p.c;
}
ei(0xa0, 1),
di(0xc0, 0) {
1:op_io();
2:op_io();
regs.p.i = $1;
}
set0_dp(0x02, rd |= 0x01),
clr0_dp(0x12, rd &= ~0x01),
set1_dp(0x22, rd |= 0x02),
clr1_dp(0x32, rd &= ~0x02),
set2_dp(0x42, rd |= 0x04),
clr2_dp(0x52, rd &= ~0x04),
set3_dp(0x62, rd |= 0x08),
clr3_dp(0x72, rd &= ~0x08),
set4_dp(0x82, rd |= 0x10),
clr4_dp(0x92, rd &= ~0x10),
set5_dp(0xa2, rd |= 0x20),
clr5_dp(0xb2, rd &= ~0x20),
set6_dp(0xc2, rd |= 0x40),
clr6_dp(0xd2, rd &= ~0x40),
set7_dp(0xe2, rd |= 0x80),
clr7_dp(0xf2, rd &= ~0x80) {
1:dp = op_readpc();
2:rd = op_readdp(dp);
3:$1;
op_writedp(dp, rd);
}
push_a(0x2d, a),
push_x(0x4d, x),
push_y(0x6d, y),
push_p(0x0d, p) {
1:op_io();
2:op_io();
3:op_writestack(regs.$1);
}
pop_a(0xae, a),
pop_x(0xce, x),
pop_y(0xee, y),
pop_p(0x8e, p) {
1:op_io();
2:op_io();
3:regs.$1 = op_readstack();
}
mul_ya(0xcf) {
1:op_io();
2:op_io();
3:op_io();
4:op_io();
5:op_io();
6:op_io();
7:op_io();
8:op_io();
ya = regs.y * regs.a;
regs.a = ya;
regs.y = ya >> 8;
//result is set based on y (high-byte) only
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
}
div_ya_x(0x9e) {
1:op_io();
2:op_io();
3:op_io();
4:op_io();
5:op_io();
6:op_io();
7:op_io();
8:op_io();
9:op_io();
10:op_io();
11:op_io();
ya = regs.ya;
//overflow set if quotient >= 256
regs.p.v = !!(regs.y >= regs.x);
regs.p.h = !!((regs.y & 15) >= (regs.x & 15));
if(regs.y < (regs.x << 1)) {
//if quotient is <= 511 (will fit into 9-bit result)
regs.a = ya / regs.x;
regs.y = ya % regs.x;
} else {
//otherwise, the quotient won't fit into regs.p.v + regs.a
//this emulates the odd behavior of the S-SMP in this case
regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x);
regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x);
}
//result is set based on a (quotient) only
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}

View File

@@ -1,349 +0,0 @@
#ifdef SSMP_CPP
//nop
case 0x00: {
op_io();
} break;
//sleep
case 0xef: {
op_io();
op_io();
regs.pc--;
} break;
//stop
case 0xff: {
op_io();
op_io();
regs.pc--;
} break;
//xcn
case 0x9f: {
op_io();
op_io();
op_io();
op_io();
regs.a = (regs.a >> 4) | (regs.a << 4);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//daa
case 0xdf: {
op_io();
op_io();
if(regs.p.c || (regs.a) > 0x99) {
regs.a += 0x60;
regs.p.c = 1;
}
if(regs.p.h || (regs.a & 15) > 0x09) {
regs.a += 0x06;
}
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//das
case 0xbe: {
op_io();
op_io();
if(!regs.p.c || (regs.a) > 0x99) {
regs.a -= 0x60;
regs.p.c = 0;
}
if(!regs.p.h || (regs.a & 15) > 0x09) {
regs.a -= 0x06;
}
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//clrc
case 0x60: {
op_io();
regs.p.c = 0;
} break;
//clrp
case 0x20: {
op_io();
regs.p.p = 0;
} break;
//setc
case 0x80: {
op_io();
regs.p.c = 1;
} break;
//setp
case 0x40: {
op_io();
regs.p.p = 1;
} break;
//clrv
case 0xe0: {
op_io();
regs.p.v = 0;
regs.p.h = 0;
} break;
//notc
case 0xed: {
op_io();
op_io();
regs.p.c = !regs.p.c;
} break;
//ei
case 0xa0: {
op_io();
op_io();
regs.p.i = 1;
} break;
//di
case 0xc0: {
op_io();
op_io();
regs.p.i = 0;
} break;
//set0_dp
case 0x02: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x01;
op_writedp(dp, rd);
} break;
//clr0_dp
case 0x12: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x01;
op_writedp(dp, rd);
} break;
//set1_dp
case 0x22: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x02;
op_writedp(dp, rd);
} break;
//clr1_dp
case 0x32: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x02;
op_writedp(dp, rd);
} break;
//set2_dp
case 0x42: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x04;
op_writedp(dp, rd);
} break;
//clr2_dp
case 0x52: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x04;
op_writedp(dp, rd);
} break;
//set3_dp
case 0x62: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x08;
op_writedp(dp, rd);
} break;
//clr3_dp
case 0x72: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x08;
op_writedp(dp, rd);
} break;
//set4_dp
case 0x82: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x10;
op_writedp(dp, rd);
} break;
//clr4_dp
case 0x92: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x10;
op_writedp(dp, rd);
} break;
//set5_dp
case 0xa2: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x20;
op_writedp(dp, rd);
} break;
//clr5_dp
case 0xb2: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x20;
op_writedp(dp, rd);
} break;
//set6_dp
case 0xc2: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x40;
op_writedp(dp, rd);
} break;
//clr6_dp
case 0xd2: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x40;
op_writedp(dp, rd);
} break;
//set7_dp
case 0xe2: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= 0x80;
op_writedp(dp, rd);
} break;
//clr7_dp
case 0xf2: {
dp = op_readpc();
rd = op_readdp(dp);
rd &= ~0x80;
op_writedp(dp, rd);
} break;
//push_a
case 0x2d: {
op_io();
op_io();
op_writestack(regs.a);
} break;
//push_x
case 0x4d: {
op_io();
op_io();
op_writestack(regs.x);
} break;
//push_y
case 0x6d: {
op_io();
op_io();
op_writestack(regs.y);
} break;
//push_p
case 0x0d: {
op_io();
op_io();
op_writestack(regs.p);
} break;
//pop_a
case 0xae: {
op_io();
op_io();
regs.a = op_readstack();
} break;
//pop_x
case 0xce: {
op_io();
op_io();
regs.x = op_readstack();
} break;
//pop_y
case 0xee: {
op_io();
op_io();
regs.y = op_readstack();
} break;
//pop_p
case 0x8e: {
op_io();
op_io();
regs.p = op_readstack();
} break;
//mul_ya
case 0xcf: {
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
ya = regs.y * regs.a;
regs.a = ya;
regs.y = ya >> 8;
//result is set based on y (high-byte) only
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
} break;
//div_ya_x
case 0x9e: {
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
op_io();
ya = regs.ya;
//overflow set if quotient >= 256
regs.p.v = !!(regs.y >= regs.x);
regs.p.h = !!((regs.y & 15) >= (regs.x & 15));
if(regs.y < (regs.x << 1)) {
//if quotient is <= 511 (will fit into 9-bit result)
regs.a = ya / regs.x;
regs.y = ya % regs.x;
} else {
//otherwise, the quotient won't fit into regs.p.v + regs.a
//this emulates the odd behavior of the S-SMP in this case
regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x);
regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x);
}
//result is set based on a (quotient) only
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
#endif

View File

@@ -1,217 +0,0 @@
mov_a_x(0x7d, a, x),
mov_a_y(0xdd, a, y),
mov_x_a(0x5d, x, a),
mov_y_a(0xfd, y, a),
mov_x_sp(0x9d, x, sp) {
1:op_io();
regs.$1 = regs.$2;
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_sp_x(0xbd, sp, x) {
1:op_io();
regs.$1 = regs.$2;
}
mov_a_const(0xe8, a),
mov_x_const(0xcd, x),
mov_y_const(0x8d, y) {
1:regs.$1 = op_readpc();
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_a_ix(0xe6) {
1:op_io();
2:regs.a = op_readdp(regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_a_ixinc(0xbf) {
1:op_io();
2:regs.a = op_readdp(regs.x++);
3:op_io();
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_a_dp(0xe4, a),
mov_x_dp(0xf8, x),
mov_y_dp(0xeb, y) {
1:sp = op_readpc();
2:regs.$1 = op_readdp(sp);
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_a_dpx(0xf4, a, x),
mov_x_dpy(0xf9, x, y),
mov_y_dpx(0xfb, y, x) {
1:sp = op_readpc();
2:op_io();
3:regs.$1 = op_readdp(sp + regs.$2);
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_a_addr(0xe5, a),
mov_x_addr(0xe9, x),
mov_y_addr(0xec, y) {
1:sp = op_readpc();
2:sp |= op_readpc() << 8;
3:regs.$1 = op_readaddr(sp);
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_a_addrx(0xf5, x),
mov_a_addry(0xf6, y) {
1:sp = op_readpc();
2:sp |= op_readpc() << 8;
3:op_io();
4:regs.a = op_readaddr(sp + regs.$1);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_a_idpx(0xe7) {
1:dp = op_readpc() + regs.x;
2:op_io();
3:sp = op_readdp(dp);
4:sp |= op_readdp(dp + 1) << 8;
5:regs.a = op_readaddr(sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_a_idpy(0xf7) {
1:dp = op_readpc();
2:op_io();
3:sp = op_readdp(dp);
4:sp |= op_readdp(dp + 1) << 8;
5:regs.a = op_readaddr(sp + regs.y);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_dp_dp(0xfa) {
1:sp = op_readpc();
2:rd = op_readdp(sp);
3:dp = op_readpc();
4:op_writedp(dp, rd);
}
mov_dp_const(0x8f) {
1:rd = op_readpc();
2:dp = op_readpc();
3:op_readdp(dp);
4:op_writedp(dp, rd);
}
mov_ix_a(0xc6) {
1:op_io();
2:op_readdp(regs.x);
3:op_writedp(regs.x, regs.a);
}
mov_ixinc_a(0xaf) {
1:op_io();
2:op_io();
3:op_writedp(regs.x++, regs.a);
}
mov_dp_a(0xc4, a),
mov_dp_x(0xd8, x),
mov_dp_y(0xcb, y) {
1:dp = op_readpc();
2:op_readdp(dp);
3:op_writedp(dp, regs.$1);
}
mov_dpx_a(0xd4, x, a),
mov_dpy_x(0xd9, y, x),
mov_dpx_y(0xdb, x, y) {
1:dp = op_readpc();
2:op_io();
dp += regs.$1;
3:op_readdp(dp);
4:op_writedp(dp, regs.$2);
}
mov_addr_a(0xc5, a),
mov_addr_x(0xc9, x),
mov_addr_y(0xcc, y) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:op_readaddr(dp);
4:op_writeaddr(dp, regs.$1);
}
mov_addrx_a(0xd5, x),
mov_addry_a(0xd6, y) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:op_io();
dp += regs.$1;
4:op_readaddr(dp);
5:op_writeaddr(dp, regs.a);
}
mov_idpx_a(0xc7) {
1:sp = op_readpc();
2:op_io();
sp += regs.x;
3:dp = op_readdp(sp);
4:dp |= op_readdp(sp + 1) << 8;
5:op_readaddr(dp);
6:op_writeaddr(dp, regs.a);
}
mov_idpy_a(0xd7) {
1:sp = op_readpc();
2:dp = op_readdp(sp);
3:dp |= op_readdp(sp + 1) << 8;
4:op_io();
dp += regs.y;
5:op_readaddr(dp);
6:op_writeaddr(dp, regs.a);
}
movw_ya_dp(0xba) {
1:sp = op_readpc();
2:regs.a = op_readdp(sp);
3:op_io();
4:regs.y = op_readdp(sp + 1);
regs.p.n = !!(regs.ya & 0x8000);
regs.p.z = (regs.ya == 0);
}
movw_dp_ya(0xda) {
1:dp = op_readpc();
2:op_readdp(dp);
3:op_writedp(dp, regs.a);
4:op_writedp(dp + 1, regs.y);
}
mov1_c_bit(0xaa) {
1:sp = op_readpc();
2:sp |= op_readpc() << 8;
3:bit = sp >> 13;
sp &= 0x1fff;
rd = op_readaddr(sp);
regs.p.c = !!(rd & (1 << bit));
}
mov1_bit_c(0xca) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
if(regs.p.c)rd |= (1 << bit);
else rd &= ~(1 << bit);
4:op_io();
5:op_writeaddr(dp, rd);
}

View File

@@ -1,392 +0,0 @@
#ifdef SSMP_CPP
//mov_a_x
case 0x7d: {
op_io();
regs.a = regs.x;
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//mov_a_y
case 0xdd: {
op_io();
regs.a = regs.y;
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//mov_x_a
case 0x5d: {
op_io();
regs.x = regs.a;
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
} break;
//mov_y_a
case 0xfd: {
op_io();
regs.y = regs.a;
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
} break;
//mov_x_sp
case 0x9d: {
op_io();
regs.x = regs.sp;
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
} break;
//mov_sp_x
case 0xbd: {
op_io();
regs.sp = regs.x;
} break;
//mov_a_const
case 0xe8: {
regs.a = op_readpc();
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//mov_x_const
case 0xcd: {
regs.x = op_readpc();
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
} break;
//mov_y_const
case 0x8d: {
regs.y = op_readpc();
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
} break;
//mov_a_ix
case 0xe6: {
op_io();
regs.a = op_readdp(regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//mov_a_ixinc
case 0xbf: {
op_io();
regs.a = op_readdp(regs.x++);
op_io();
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//mov_a_dp
case 0xe4: {
sp = op_readpc();
regs.a = op_readdp(sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//mov_x_dp
case 0xf8: {
sp = op_readpc();
regs.x = op_readdp(sp);
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
} break;
//mov_y_dp
case 0xeb: {
sp = op_readpc();
regs.y = op_readdp(sp);
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
} break;
//mov_a_dpx
case 0xf4: {
sp = op_readpc();
op_io();
regs.a = op_readdp(sp + regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//mov_x_dpy
case 0xf9: {
sp = op_readpc();
op_io();
regs.x = op_readdp(sp + regs.y);
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
} break;
//mov_y_dpx
case 0xfb: {
sp = op_readpc();
op_io();
regs.y = op_readdp(sp + regs.x);
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
} break;
//mov_a_addr
case 0xe5: {
sp = op_readpc();
sp |= op_readpc() << 8;
regs.a = op_readaddr(sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//mov_x_addr
case 0xe9: {
sp = op_readpc();
sp |= op_readpc() << 8;
regs.x = op_readaddr(sp);
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
} break;
//mov_y_addr
case 0xec: {
sp = op_readpc();
sp |= op_readpc() << 8;
regs.y = op_readaddr(sp);
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
} break;
//mov_a_addrx
case 0xf5: {
sp = op_readpc();
sp |= op_readpc() << 8;
op_io();
regs.a = op_readaddr(sp + regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//mov_a_addry
case 0xf6: {
sp = op_readpc();
sp |= op_readpc() << 8;
op_io();
regs.a = op_readaddr(sp + regs.y);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//mov_a_idpx
case 0xe7: {
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
regs.a = op_readaddr(sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//mov_a_idpy
case 0xf7: {
dp = op_readpc();
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
regs.a = op_readaddr(sp + regs.y);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
} break;
//mov_dp_dp
case 0xfa: {
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
op_writedp(dp, rd);
} break;
//mov_dp_const
case 0x8f: {
rd = op_readpc();
dp = op_readpc();
op_readdp(dp);
op_writedp(dp, rd);
} break;
//mov_ix_a
case 0xc6: {
op_io();
op_readdp(regs.x);
op_writedp(regs.x, regs.a);
} break;
//mov_ixinc_a
case 0xaf: {
op_io();
op_io();
op_writedp(regs.x++, regs.a);
} break;
//mov_dp_a
case 0xc4: {
dp = op_readpc();
op_readdp(dp);
op_writedp(dp, regs.a);
} break;
//mov_dp_x
case 0xd8: {
dp = op_readpc();
op_readdp(dp);
op_writedp(dp, regs.x);
} break;
//mov_dp_y
case 0xcb: {
dp = op_readpc();
op_readdp(dp);
op_writedp(dp, regs.y);
} break;
//mov_dpx_a
case 0xd4: {
dp = op_readpc();
op_io();
dp += regs.x;
op_readdp(dp);
op_writedp(dp, regs.a);
} break;
//mov_dpy_x
case 0xd9: {
dp = op_readpc();
op_io();
dp += regs.y;
op_readdp(dp);
op_writedp(dp, regs.x);
} break;
//mov_dpx_y
case 0xdb: {
dp = op_readpc();
op_io();
dp += regs.x;
op_readdp(dp);
op_writedp(dp, regs.y);
} break;
//mov_addr_a
case 0xc5: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_readaddr(dp);
op_writeaddr(dp, regs.a);
} break;
//mov_addr_x
case 0xc9: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_readaddr(dp);
op_writeaddr(dp, regs.x);
} break;
//mov_addr_y
case 0xcc: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_readaddr(dp);
op_writeaddr(dp, regs.y);
} break;
//mov_addrx_a
case 0xd5: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
dp += regs.x;
op_readaddr(dp);
op_writeaddr(dp, regs.a);
} break;
//mov_addry_a
case 0xd6: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
dp += regs.y;
op_readaddr(dp);
op_writeaddr(dp, regs.a);
} break;
//mov_idpx_a
case 0xc7: {
sp = op_readpc();
op_io();
sp += regs.x;
dp = op_readdp(sp);
dp |= op_readdp(sp + 1) << 8;
op_readaddr(dp);
op_writeaddr(dp, regs.a);
} break;
//mov_idpy_a
case 0xd7: {
sp = op_readpc();
dp = op_readdp(sp);
dp |= op_readdp(sp + 1) << 8;
op_io();
dp += regs.y;
op_readaddr(dp);
op_writeaddr(dp, regs.a);
} break;
//movw_ya_dp
case 0xba: {
sp = op_readpc();
regs.a = op_readdp(sp);
op_io();
regs.y = op_readdp(sp + 1);
regs.p.n = !!(regs.ya & 0x8000);
regs.p.z = (regs.ya == 0);
} break;
//movw_dp_ya
case 0xda: {
dp = op_readpc();
op_readdp(dp);
op_writedp(dp, regs.a);
op_writedp(dp + 1, regs.y);
} break;
//mov1_c_bit
case 0xaa: {
sp = op_readpc();
sp |= op_readpc() << 8;
bit = sp >> 13;
sp &= 0x1fff;
rd = op_readaddr(sp);
regs.p.c = !!(rd & (1 << bit));
} break;
//mov1_bit_c
case 0xca: {
dp = op_readpc();
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
if(regs.p.c)rd |= (1 << bit);
else rd &= ~(1 << bit);
op_io();
op_writeaddr(dp, rd);
} break;
#endif

View File

@@ -1,179 +0,0 @@
bra(0x2f, 0),
beq(0xf0, !regs.p.z),
bne(0xd0, regs.p.z),
bcs(0xb0, !regs.p.c),
bcc(0x90, regs.p.c),
bvs(0x70, !regs.p.v),
bvc(0x50, regs.p.v),
bmi(0x30, !regs.p.n),
bpl(0x10, regs.p.n) {
1:rd = op_readpc();
if($1)end;
2:op_io();
3:op_io();
regs.pc += (int8)rd;
}
bbs0(0x03, 0x01, !=),
bbc0(0x13, 0x01, ==),
bbs1(0x23, 0x02, !=),
bbc1(0x33, 0x02, ==),
bbs2(0x43, 0x04, !=),
bbc2(0x53, 0x04, ==),
bbs3(0x63, 0x08, !=),
bbc3(0x73, 0x08, ==),
bbs4(0x83, 0x10, !=),
bbc4(0x93, 0x10, ==),
bbs5(0xa3, 0x20, !=),
bbc5(0xb3, 0x20, ==),
bbs6(0xc3, 0x40, !=),
bbc6(0xd3, 0x40, ==),
bbs7(0xe3, 0x80, !=),
bbc7(0xf3, 0x80, ==) {
1:dp = op_readpc();
2:sp = op_readdp(dp);
3:rd = op_readpc();
4:op_io();
if((sp & $1) $2 $1)end;
5:op_io();
6:op_io();
regs.pc += (int8)rd;
}
cbne_dp(0x2e) {
1:dp = op_readpc();
2:sp = op_readdp(dp);
3:rd = op_readpc();
4:op_io();
if(regs.a == sp)end;
5:op_io();
6:op_io();
regs.pc += (int8)rd;
}
cbne_dpx(0xde) {
1:dp = op_readpc();
2:op_io();
3:sp = op_readdp(dp + regs.x);
4:rd = op_readpc();
5:op_io();
if(regs.a == sp)end;
6:op_io();
7:op_io();
regs.pc += (int8)rd;
}
dbnz_dp(0x6e) {
1:dp = op_readpc();
2:wr = op_readdp(dp);
3:op_writedp(dp, --wr);
4:rd = op_readpc();
if(wr == 0x00)end;
5:op_io();
6:op_io();
regs.pc += (int8)rd;
}
dbnz_y(0xfe) {
1:rd = op_readpc();
2:op_io();
regs.y--;
3:op_io();
if(regs.y == 0x00)end;
4:op_io();
5:op_io();
regs.pc += (int8)rd;
}
jmp_addr(0x5f) {
1:rd = op_readpc();
2:rd |= op_readpc() << 8;
regs.pc = rd;
}
jmp_iaddrx(0x1f) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:op_io();
dp += regs.x;
4:rd = op_readaddr(dp);
5:rd |= op_readaddr(dp + 1) << 8;
regs.pc = rd;
}
call(0x3f) {
1:rd = op_readpc();
2:rd |= op_readpc() << 8;
3:op_io();
4:op_io();
5:op_io();
6:op_writestack(regs.pc >> 8);
7:op_writestack(regs.pc);
regs.pc = rd;
}
pcall(0x4f) {
1:rd = op_readpc();
2:op_io();
3:op_io();
4:op_writestack(regs.pc >> 8);
5:op_writestack(regs.pc);
regs.pc = 0xff00 | rd;
}
tcall_0(0x01, 0),
tcall_1(0x11, 1),
tcall_2(0x21, 2),
tcall_3(0x31, 3),
tcall_4(0x41, 4),
tcall_5(0x51, 5),
tcall_6(0x61, 6),
tcall_7(0x71, 7),
tcall_8(0x81, 8),
tcall_9(0x91, 9),
tcall_10(0xa1, 10),
tcall_11(0xb1, 11),
tcall_12(0xc1, 12),
tcall_13(0xd1, 13),
tcall_14(0xe1, 14),
tcall_15(0xf1, 15) {
1:dp = 0xffde - ($1 << 1);
rd = op_readaddr(dp);
2:rd |= op_readaddr(dp + 1) << 8;
3:op_io();
4:op_io();
5:op_io();
6:op_writestack(regs.pc >> 8);
7:op_writestack(regs.pc);
regs.pc = rd;
}
brk(0x0f) {
1:rd = op_readaddr(0xffde);
2:rd |= op_readaddr(0xffdf) << 8;
3:op_io();
4:op_io();
5:op_writestack(regs.pc >> 8);
6:op_writestack(regs.pc);
7:op_writestack(regs.p);
regs.pc = rd;
regs.p.b = 1;
regs.p.i = 0;
}
ret(0x6f) {
1:rd = op_readstack();
2:rd |= op_readstack() << 8;
3:op_io();
4:op_io();
regs.pc = rd;
}
reti(0x7f) {
1:regs.p = op_readstack();
2:rd = op_readstack();
3:rd |= op_readstack() << 8;
4:op_io();
5:op_io();
regs.pc = rd;
}

View File

@@ -1,606 +0,0 @@
#ifdef SSMP_CPP
//bra
case 0x2f: {
rd = op_readpc();
if(0)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//beq
case 0xf0: {
rd = op_readpc();
if(!regs.p.z)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bne
case 0xd0: {
rd = op_readpc();
if(regs.p.z)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bcs
case 0xb0: {
rd = op_readpc();
if(!regs.p.c)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bcc
case 0x90: {
rd = op_readpc();
if(regs.p.c)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bvs
case 0x70: {
rd = op_readpc();
if(!regs.p.v)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bvc
case 0x50: {
rd = op_readpc();
if(regs.p.v)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bmi
case 0x30: {
rd = op_readpc();
if(!regs.p.n)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bpl
case 0x10: {
rd = op_readpc();
if(regs.p.n)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbs0
case 0x03: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x01) != 0x01)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbc0
case 0x13: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x01) == 0x01)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbs1
case 0x23: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x02) != 0x02)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbc1
case 0x33: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x02) == 0x02)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbs2
case 0x43: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x04) != 0x04)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbc2
case 0x53: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x04) == 0x04)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbs3
case 0x63: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x08) != 0x08)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbc3
case 0x73: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x08) == 0x08)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbs4
case 0x83: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x10) != 0x10)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbc4
case 0x93: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x10) == 0x10)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbs5
case 0xa3: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x20) != 0x20)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbc5
case 0xb3: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x20) == 0x20)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbs6
case 0xc3: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x40) != 0x40)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbc6
case 0xd3: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x40) == 0x40)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbs7
case 0xe3: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x80) != 0x80)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//bbc7
case 0xf3: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if((sp & 0x80) == 0x80)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//cbne_dp
case 0x2e: {
dp = op_readpc();
sp = op_readdp(dp);
rd = op_readpc();
op_io();
if(regs.a == sp)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//cbne_dpx
case 0xde: {
dp = op_readpc();
op_io();
sp = op_readdp(dp + regs.x);
rd = op_readpc();
op_io();
if(regs.a == sp)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//dbnz_dp
case 0x6e: {
dp = op_readpc();
wr = op_readdp(dp);
op_writedp(dp, --wr);
rd = op_readpc();
if(wr == 0x00)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//dbnz_y
case 0xfe: {
rd = op_readpc();
op_io();
regs.y--;
op_io();
if(regs.y == 0x00)break;
op_io();
op_io();
regs.pc += (int8)rd;
} break;
//jmp_addr
case 0x5f: {
rd = op_readpc();
rd |= op_readpc() << 8;
regs.pc = rd;
} break;
//jmp_iaddrx
case 0x1f: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
dp += regs.x;
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
regs.pc = rd;
} break;
//call
case 0x3f: {
rd = op_readpc();
rd |= op_readpc() << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//pcall
case 0x4f: {
rd = op_readpc();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = 0xff00 | rd;
} break;
//tcall_0
case 0x01: {
dp = 0xffde - (0 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_1
case 0x11: {
dp = 0xffde - (1 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_2
case 0x21: {
dp = 0xffde - (2 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_3
case 0x31: {
dp = 0xffde - (3 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_4
case 0x41: {
dp = 0xffde - (4 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_5
case 0x51: {
dp = 0xffde - (5 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_6
case 0x61: {
dp = 0xffde - (6 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_7
case 0x71: {
dp = 0xffde - (7 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_8
case 0x81: {
dp = 0xffde - (8 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_9
case 0x91: {
dp = 0xffde - (9 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_10
case 0xa1: {
dp = 0xffde - (10 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_11
case 0xb1: {
dp = 0xffde - (11 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_12
case 0xc1: {
dp = 0xffde - (12 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_13
case 0xd1: {
dp = 0xffde - (13 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_14
case 0xe1: {
dp = 0xffde - (14 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//tcall_15
case 0xf1: {
dp = 0xffde - (15 << 1);
rd = op_readaddr(dp);
rd |= op_readaddr(dp + 1) << 8;
op_io();
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
regs.pc = rd;
} break;
//brk
case 0x0f: {
rd = op_readaddr(0xffde);
rd |= op_readaddr(0xffdf) << 8;
op_io();
op_io();
op_writestack(regs.pc >> 8);
op_writestack(regs.pc);
op_writestack(regs.p);
regs.pc = rd;
regs.p.b = 1;
regs.p.i = 0;
} break;
//ret
case 0x6f: {
rd = op_readstack();
rd |= op_readstack() << 8;
op_io();
op_io();
regs.pc = rd;
} break;
//reti
case 0x7f: {
regs.p = op_readstack();
rd = op_readstack();
rd |= op_readstack() << 8;
op_io();
op_io();
regs.pc = rd;
} break;
#endif

View File

@@ -1,205 +0,0 @@
adc_a_const(0x88, adc, a),
and_a_const(0x28, and, a),
cmp_a_const(0x68, cmp, a),
cmp_x_const(0xc8, cmp, x),
cmp_y_const(0xad, cmp, y),
eor_a_const(0x48, eor, a),
or_a_const(0x08, or, a),
sbc_a_const(0xa8, sbc, a) {
1:rd = op_readpc();
regs.$2 = op_$1(regs.$2, rd);
}
adc_a_ix(0x86, adc),
and_a_ix(0x26, and),
cmp_a_ix(0x66, cmp),
eor_a_ix(0x46, eor),
or_a_ix(0x06, or),
sbc_a_ix(0xa6, sbc) {
1:op_io();
2:rd = op_readdp(regs.x);
regs.a = op_$1(regs.a, rd);
}
adc_a_dp(0x84, adc, a),
and_a_dp(0x24, and, a),
cmp_a_dp(0x64, cmp, a),
cmp_x_dp(0x3e, cmp, x),
cmp_y_dp(0x7e, cmp, y),
eor_a_dp(0x44, eor, a),
or_a_dp(0x04, or, a),
sbc_a_dp(0xa4, sbc, a) {
1:dp = op_readpc();
2:rd = op_readdp(dp);
regs.$2 = op_$1(regs.$2, rd);
}
adc_a_dpx(0x94, adc),
and_a_dpx(0x34, and),
cmp_a_dpx(0x74, cmp),
eor_a_dpx(0x54, eor),
or_a_dpx(0x14, or),
sbc_a_dpx(0xb4, sbc) {
1:dp = op_readpc();
2:op_io();
3:rd = op_readdp(dp + regs.x);
regs.a = op_$1(regs.a, rd);
}
adc_a_addr(0x85, adc, a),
and_a_addr(0x25, and, a),
cmp_a_addr(0x65, cmp, a),
cmp_x_addr(0x1e, cmp, x),
cmp_y_addr(0x5e, cmp, y),
eor_a_addr(0x45, eor, a),
or_a_addr(0x05, or, a),
sbc_a_addr(0xa5, sbc, a) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:rd = op_readaddr(dp);
regs.$2 = op_$1(regs.$2, rd);
}
adc_a_addrx(0x95, adc, x),
adc_a_addry(0x96, adc, y),
and_a_addrx(0x35, and, x),
and_a_addry(0x36, and, y),
cmp_a_addrx(0x75, cmp, x),
cmp_a_addry(0x76, cmp, y),
eor_a_addrx(0x55, eor, x),
eor_a_addry(0x56, eor, y),
or_a_addrx(0x15, or, x),
or_a_addry(0x16, or, y),
sbc_a_addrx(0xb5, sbc, x),
sbc_a_addry(0xb6, sbc, y) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:op_io();
4:rd = op_readaddr(dp + regs.$2);
regs.a = op_$1(regs.a, rd);
}
adc_a_idpx(0x87, adc),
and_a_idpx(0x27, and),
cmp_a_idpx(0x67, cmp),
eor_a_idpx(0x47, eor),
or_a_idpx(0x07, or),
sbc_a_idpx(0xa7, sbc) {
1:dp = op_readpc() + regs.x;
2:op_io();
3:sp = op_readdp(dp);
4:sp |= op_readdp(dp + 1) << 8;
5:rd = op_readaddr(sp);
regs.a = op_$1(regs.a, rd);
}
adc_a_idpy(0x97, adc),
and_a_idpy(0x37, and),
cmp_a_idpy(0x77, cmp),
eor_a_idpy(0x57, eor),
or_a_idpy(0x17, or),
sbc_a_idpy(0xb7, sbc) {
1:dp = op_readpc();
2:op_io();
3:sp = op_readdp(dp);
4:sp |= op_readdp(dp + 1) << 8;
5:rd = op_readaddr(sp + regs.y);
regs.a = op_$1(regs.a, rd);
}
adc_ix_iy(0x99, adc, 1),
and_ix_iy(0x39, and, 1),
cmp_ix_iy(0x79, cmp, 0),
eor_ix_iy(0x59, eor, 1),
or_ix_iy(0x19, or, 1),
sbc_ix_iy(0xb9, sbc, 1) {
1:op_io();
2:rd = op_readdp(regs.y);
3:wr = op_readdp(regs.x);
wr = op_$1(wr, rd);
4:($2) ? op_writedp(regs.x, wr) : op_io();
}
adc_dp_dp(0x89, adc, 1),
and_dp_dp(0x29, and, 1),
cmp_dp_dp(0x69, cmp, 0),
eor_dp_dp(0x49, eor, 1),
or_dp_dp(0x09, or, 1),
sbc_dp_dp(0xa9, sbc, 1) {
1:sp = op_readpc();
2:rd = op_readdp(sp);
3:dp = op_readpc();
4:wr = op_readdp(dp);
5:wr = op_$1(wr, rd);
($2) ? op_writedp(dp, wr) : op_io();
}
adc_dp_const(0x98, adc, 1),
and_dp_const(0x38, and, 1),
cmp_dp_const(0x78, cmp, 0),
eor_dp_const(0x58, eor, 1),
or_dp_const(0x18, or, 1),
sbc_dp_const(0xb8, sbc, 1) {
1:rd = op_readpc();
2:dp = op_readpc();
3:wr = op_readdp(dp);
4:wr = op_$1(wr, rd);
($2) ? op_writedp(dp, wr) : op_io();
}
addw_ya_dp(0x7a, addw),
subw_ya_dp(0x9a, subw) {
1:dp = op_readpc();
2:rd = op_readdp(dp);
3:op_io();
4:rd |= op_readdp(dp + 1) << 8;
regs.ya = op_$1(regs.ya, rd);
}
cmpw_ya_dp(0x5a) {
1:dp = op_readpc();
2:rd = op_readdp(dp);
3:rd |= op_readdp(dp + 1) << 8;
op_cmpw(regs.ya, rd);
}
and1_bit(0x4a, !!),
and1_notbit(0x6a, !) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
regs.p.c = regs.p.c & $1(rd & (1 << bit));
}
eor1_bit(0x8a) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
4:op_io();
regs.p.c = regs.p.c ^ !!(rd & (1 << bit));
}
not1_bit(0xea) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
rd ^= (1 << bit);
4:op_writeaddr(dp, rd);
}
or1_bit(0x0a, !!),
or1_notbit(0x2a, !) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
4:op_io();
regs.p.c = regs.p.c | $1(rd & (1 << bit));
}

View File

@@ -1,747 +0,0 @@
#ifdef SSMP_CPP
//adc_a_const
case 0x88: {
rd = op_readpc();
regs.a = op_adc(regs.a, rd);
} break;
//and_a_const
case 0x28: {
rd = op_readpc();
regs.a = op_and(regs.a, rd);
} break;
//cmp_a_const
case 0x68: {
rd = op_readpc();
regs.a = op_cmp(regs.a, rd);
} break;
//cmp_x_const
case 0xc8: {
rd = op_readpc();
regs.x = op_cmp(regs.x, rd);
} break;
//cmp_y_const
case 0xad: {
rd = op_readpc();
regs.y = op_cmp(regs.y, rd);
} break;
//eor_a_const
case 0x48: {
rd = op_readpc();
regs.a = op_eor(regs.a, rd);
} break;
//or_a_const
case 0x08: {
rd = op_readpc();
regs.a = op_or(regs.a, rd);
} break;
//sbc_a_const
case 0xa8: {
rd = op_readpc();
regs.a = op_sbc(regs.a, rd);
} break;
//adc_a_ix
case 0x86: {
op_io();
rd = op_readdp(regs.x);
regs.a = op_adc(regs.a, rd);
} break;
//and_a_ix
case 0x26: {
op_io();
rd = op_readdp(regs.x);
regs.a = op_and(regs.a, rd);
} break;
//cmp_a_ix
case 0x66: {
op_io();
rd = op_readdp(regs.x);
regs.a = op_cmp(regs.a, rd);
} break;
//eor_a_ix
case 0x46: {
op_io();
rd = op_readdp(regs.x);
regs.a = op_eor(regs.a, rd);
} break;
//or_a_ix
case 0x06: {
op_io();
rd = op_readdp(regs.x);
regs.a = op_or(regs.a, rd);
} break;
//sbc_a_ix
case 0xa6: {
op_io();
rd = op_readdp(regs.x);
regs.a = op_sbc(regs.a, rd);
} break;
//adc_a_dp
case 0x84: {
dp = op_readpc();
rd = op_readdp(dp);
regs.a = op_adc(regs.a, rd);
} break;
//and_a_dp
case 0x24: {
dp = op_readpc();
rd = op_readdp(dp);
regs.a = op_and(regs.a, rd);
} break;
//cmp_a_dp
case 0x64: {
dp = op_readpc();
rd = op_readdp(dp);
regs.a = op_cmp(regs.a, rd);
} break;
//cmp_x_dp
case 0x3e: {
dp = op_readpc();
rd = op_readdp(dp);
regs.x = op_cmp(regs.x, rd);
} break;
//cmp_y_dp
case 0x7e: {
dp = op_readpc();
rd = op_readdp(dp);
regs.y = op_cmp(regs.y, rd);
} break;
//eor_a_dp
case 0x44: {
dp = op_readpc();
rd = op_readdp(dp);
regs.a = op_eor(regs.a, rd);
} break;
//or_a_dp
case 0x04: {
dp = op_readpc();
rd = op_readdp(dp);
regs.a = op_or(regs.a, rd);
} break;
//sbc_a_dp
case 0xa4: {
dp = op_readpc();
rd = op_readdp(dp);
regs.a = op_sbc(regs.a, rd);
} break;
//adc_a_dpx
case 0x94: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
regs.a = op_adc(regs.a, rd);
} break;
//and_a_dpx
case 0x34: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
regs.a = op_and(regs.a, rd);
} break;
//cmp_a_dpx
case 0x74: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
regs.a = op_cmp(regs.a, rd);
} break;
//eor_a_dpx
case 0x54: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
regs.a = op_eor(regs.a, rd);
} break;
//or_a_dpx
case 0x14: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
regs.a = op_or(regs.a, rd);
} break;
//sbc_a_dpx
case 0xb4: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
regs.a = op_sbc(regs.a, rd);
} break;
//adc_a_addr
case 0x85: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.a = op_adc(regs.a, rd);
} break;
//and_a_addr
case 0x25: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.a = op_and(regs.a, rd);
} break;
//cmp_a_addr
case 0x65: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.a = op_cmp(regs.a, rd);
} break;
//cmp_x_addr
case 0x1e: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.x = op_cmp(regs.x, rd);
} break;
//cmp_y_addr
case 0x5e: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.y = op_cmp(regs.y, rd);
} break;
//eor_a_addr
case 0x45: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.a = op_eor(regs.a, rd);
} break;
//or_a_addr
case 0x05: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.a = op_or(regs.a, rd);
} break;
//sbc_a_addr
case 0xa5: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.a = op_sbc(regs.a, rd);
} break;
//adc_a_addrx
case 0x95: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.x);
regs.a = op_adc(regs.a, rd);
} break;
//adc_a_addry
case 0x96: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.y);
regs.a = op_adc(regs.a, rd);
} break;
//and_a_addrx
case 0x35: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.x);
regs.a = op_and(regs.a, rd);
} break;
//and_a_addry
case 0x36: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.y);
regs.a = op_and(regs.a, rd);
} break;
//cmp_a_addrx
case 0x75: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.x);
regs.a = op_cmp(regs.a, rd);
} break;
//cmp_a_addry
case 0x76: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.y);
regs.a = op_cmp(regs.a, rd);
} break;
//eor_a_addrx
case 0x55: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.x);
regs.a = op_eor(regs.a, rd);
} break;
//eor_a_addry
case 0x56: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.y);
regs.a = op_eor(regs.a, rd);
} break;
//or_a_addrx
case 0x15: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.x);
regs.a = op_or(regs.a, rd);
} break;
//or_a_addry
case 0x16: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.y);
regs.a = op_or(regs.a, rd);
} break;
//sbc_a_addrx
case 0xb5: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.x);
regs.a = op_sbc(regs.a, rd);
} break;
//sbc_a_addry
case 0xb6: {
dp = op_readpc();
dp |= op_readpc() << 8;
op_io();
rd = op_readaddr(dp + regs.y);
regs.a = op_sbc(regs.a, rd);
} break;
//adc_a_idpx
case 0x87: {
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp);
regs.a = op_adc(regs.a, rd);
} break;
//and_a_idpx
case 0x27: {
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp);
regs.a = op_and(regs.a, rd);
} break;
//cmp_a_idpx
case 0x67: {
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp);
regs.a = op_cmp(regs.a, rd);
} break;
//eor_a_idpx
case 0x47: {
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp);
regs.a = op_eor(regs.a, rd);
} break;
//or_a_idpx
case 0x07: {
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp);
regs.a = op_or(regs.a, rd);
} break;
//sbc_a_idpx
case 0xa7: {
dp = op_readpc() + regs.x;
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp);
regs.a = op_sbc(regs.a, rd);
} break;
//adc_a_idpy
case 0x97: {
dp = op_readpc();
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp + regs.y);
regs.a = op_adc(regs.a, rd);
} break;
//and_a_idpy
case 0x37: {
dp = op_readpc();
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp + regs.y);
regs.a = op_and(regs.a, rd);
} break;
//cmp_a_idpy
case 0x77: {
dp = op_readpc();
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp + regs.y);
regs.a = op_cmp(regs.a, rd);
} break;
//eor_a_idpy
case 0x57: {
dp = op_readpc();
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp + regs.y);
regs.a = op_eor(regs.a, rd);
} break;
//or_a_idpy
case 0x17: {
dp = op_readpc();
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp + regs.y);
regs.a = op_or(regs.a, rd);
} break;
//sbc_a_idpy
case 0xb7: {
dp = op_readpc();
op_io();
sp = op_readdp(dp);
sp |= op_readdp(dp + 1) << 8;
rd = op_readaddr(sp + regs.y);
regs.a = op_sbc(regs.a, rd);
} break;
//adc_ix_iy
case 0x99: {
op_io();
rd = op_readdp(regs.y);
wr = op_readdp(regs.x);
wr = op_adc(wr, rd);
(1) ? op_writedp(regs.x, wr) : op_io();
} break;
//and_ix_iy
case 0x39: {
op_io();
rd = op_readdp(regs.y);
wr = op_readdp(regs.x);
wr = op_and(wr, rd);
(1) ? op_writedp(regs.x, wr) : op_io();
} break;
//cmp_ix_iy
case 0x79: {
op_io();
rd = op_readdp(regs.y);
wr = op_readdp(regs.x);
wr = op_cmp(wr, rd);
(0) ? op_writedp(regs.x, wr) : op_io();
} break;
//eor_ix_iy
case 0x59: {
op_io();
rd = op_readdp(regs.y);
wr = op_readdp(regs.x);
wr = op_eor(wr, rd);
(1) ? op_writedp(regs.x, wr) : op_io();
} break;
//or_ix_iy
case 0x19: {
op_io();
rd = op_readdp(regs.y);
wr = op_readdp(regs.x);
wr = op_or(wr, rd);
(1) ? op_writedp(regs.x, wr) : op_io();
} break;
//sbc_ix_iy
case 0xb9: {
op_io();
rd = op_readdp(regs.y);
wr = op_readdp(regs.x);
wr = op_sbc(wr, rd);
(1) ? op_writedp(regs.x, wr) : op_io();
} break;
//adc_dp_dp
case 0x89: {
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
wr = op_readdp(dp);
wr = op_adc(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
} break;
//and_dp_dp
case 0x29: {
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
wr = op_readdp(dp);
wr = op_and(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
} break;
//cmp_dp_dp
case 0x69: {
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
wr = op_readdp(dp);
wr = op_cmp(wr, rd);
(0) ? op_writedp(dp, wr) : op_io();
} break;
//eor_dp_dp
case 0x49: {
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
wr = op_readdp(dp);
wr = op_eor(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
} break;
//or_dp_dp
case 0x09: {
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
wr = op_readdp(dp);
wr = op_or(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
} break;
//sbc_dp_dp
case 0xa9: {
sp = op_readpc();
rd = op_readdp(sp);
dp = op_readpc();
wr = op_readdp(dp);
wr = op_sbc(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
} break;
//adc_dp_const
case 0x98: {
rd = op_readpc();
dp = op_readpc();
wr = op_readdp(dp);
wr = op_adc(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
} break;
//and_dp_const
case 0x38: {
rd = op_readpc();
dp = op_readpc();
wr = op_readdp(dp);
wr = op_and(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
} break;
//cmp_dp_const
case 0x78: {
rd = op_readpc();
dp = op_readpc();
wr = op_readdp(dp);
wr = op_cmp(wr, rd);
(0) ? op_writedp(dp, wr) : op_io();
} break;
//eor_dp_const
case 0x58: {
rd = op_readpc();
dp = op_readpc();
wr = op_readdp(dp);
wr = op_eor(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
} break;
//or_dp_const
case 0x18: {
rd = op_readpc();
dp = op_readpc();
wr = op_readdp(dp);
wr = op_or(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
} break;
//sbc_dp_const
case 0xb8: {
rd = op_readpc();
dp = op_readpc();
wr = op_readdp(dp);
wr = op_sbc(wr, rd);
(1) ? op_writedp(dp, wr) : op_io();
} break;
//addw_ya_dp
case 0x7a: {
dp = op_readpc();
rd = op_readdp(dp);
op_io();
rd |= op_readdp(dp + 1) << 8;
regs.ya = op_addw(regs.ya, rd);
} break;
//subw_ya_dp
case 0x9a: {
dp = op_readpc();
rd = op_readdp(dp);
op_io();
rd |= op_readdp(dp + 1) << 8;
regs.ya = op_subw(regs.ya, rd);
} break;
//cmpw_ya_dp
case 0x5a: {
dp = op_readpc();
rd = op_readdp(dp);
rd |= op_readdp(dp + 1) << 8;
op_cmpw(regs.ya, rd);
} break;
//and1_bit
case 0x4a: {
dp = op_readpc();
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
regs.p.c = regs.p.c & !!(rd & (1 << bit));
} break;
//and1_notbit
case 0x6a: {
dp = op_readpc();
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
regs.p.c = regs.p.c & !(rd & (1 << bit));
} break;
//eor1_bit
case 0x8a: {
dp = op_readpc();
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
op_io();
regs.p.c = regs.p.c ^ !!(rd & (1 << bit));
} break;
//not1_bit
case 0xea: {
dp = op_readpc();
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
rd ^= (1 << bit);
op_writeaddr(dp, rd);
} break;
//or1_bit
case 0x0a: {
dp = op_readpc();
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
op_io();
regs.p.c = regs.p.c | !!(rd & (1 << bit));
} break;
//or1_notbit
case 0x2a: {
dp = op_readpc();
dp |= op_readpc() << 8;
bit = dp >> 13;
dp &= 0x1fff;
rd = op_readaddr(dp);
op_io();
regs.p.c = regs.p.c | !(rd & (1 << bit));
} break;
#endif

View File

@@ -1,74 +0,0 @@
inc_a(0xbc, inc, a),
inc_x(0x3d, inc, x),
inc_y(0xfc, inc, y),
dec_a(0x9c, dec, a),
dec_x(0x1d, dec, x),
dec_y(0xdc, dec, y),
asl_a(0x1c, asl, a),
lsr_a(0x5c, lsr, a),
rol_a(0x3c, rol, a),
ror_a(0x7c, ror, a) {
1:op_io();
regs.$2 = op_$1(regs.$2);
}
inc_dp(0xab, inc),
dec_dp(0x8b, dec),
asl_dp(0x0b, asl),
lsr_dp(0x4b, lsr),
rol_dp(0x2b, rol),
ror_dp(0x6b, ror) {
1:dp = op_readpc();
2:rd = op_readdp(dp);
3:rd = op_$1(rd);
op_writedp(dp, rd);
}
inc_dpx(0xbb, inc),
dec_dpx(0x9b, dec),
asl_dpx(0x1b, asl),
lsr_dpx(0x5b, lsr),
rol_dpx(0x3b, rol),
ror_dpx(0x7b, ror) {
1:dp = op_readpc();
2:op_io();
3:rd = op_readdp(dp + regs.x);
4:rd = op_$1(rd);
op_writedp(dp + regs.x, rd);
}
inc_addr(0xac, inc),
dec_addr(0x8c, dec),
asl_addr(0x0c, asl),
lsr_addr(0x4c, lsr),
rol_addr(0x2c, rol),
ror_addr(0x6c, ror) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:rd = op_readaddr(dp);
4:rd = op_$1(rd);
op_writeaddr(dp, rd);
}
tset_addr_a(0x0e, |),
tclr_addr_a(0x4e, &~) {
1:dp = op_readpc();
2:dp |= op_readpc() << 8;
3:rd = op_readaddr(dp);
regs.p.n = !!((regs.a - rd) & 0x80);
regs.p.z = ((regs.a - rd) == 0);
4:op_readaddr(dp);
5:op_writeaddr(dp, rd $1 regs.a);
}
incw_dp(0x3a, ++),
decw_dp(0x1a, --) {
1:dp = op_readpc();
2:rd = op_readdp(dp);
rd$1;
3:op_writedp(dp++, rd);
4:rd += op_readdp(dp) << 8;
5:op_writedp(dp, rd >> 8);
regs.p.n = !!(rd & 0x8000);
regs.p.z = (rd == 0);
}

View File

@@ -1,265 +0,0 @@
#ifdef SSMP_CPP
//inc_a
case 0xbc: {
op_io();
regs.a = op_inc(regs.a);
} break;
//inc_x
case 0x3d: {
op_io();
regs.x = op_inc(regs.x);
} break;
//inc_y
case 0xfc: {
op_io();
regs.y = op_inc(regs.y);
} break;
//dec_a
case 0x9c: {
op_io();
regs.a = op_dec(regs.a);
} break;
//dec_x
case 0x1d: {
op_io();
regs.x = op_dec(regs.x);
} break;
//dec_y
case 0xdc: {
op_io();
regs.y = op_dec(regs.y);
} break;
//asl_a
case 0x1c: {
op_io();
regs.a = op_asl(regs.a);
} break;
//lsr_a
case 0x5c: {
op_io();
regs.a = op_lsr(regs.a);
} break;
//rol_a
case 0x3c: {
op_io();
regs.a = op_rol(regs.a);
} break;
//ror_a
case 0x7c: {
op_io();
regs.a = op_ror(regs.a);
} break;
//inc_dp
case 0xab: {
dp = op_readpc();
rd = op_readdp(dp);
rd = op_inc(rd);
op_writedp(dp, rd);
} break;
//dec_dp
case 0x8b: {
dp = op_readpc();
rd = op_readdp(dp);
rd = op_dec(rd);
op_writedp(dp, rd);
} break;
//asl_dp
case 0x0b: {
dp = op_readpc();
rd = op_readdp(dp);
rd = op_asl(rd);
op_writedp(dp, rd);
} break;
//lsr_dp
case 0x4b: {
dp = op_readpc();
rd = op_readdp(dp);
rd = op_lsr(rd);
op_writedp(dp, rd);
} break;
//rol_dp
case 0x2b: {
dp = op_readpc();
rd = op_readdp(dp);
rd = op_rol(rd);
op_writedp(dp, rd);
} break;
//ror_dp
case 0x6b: {
dp = op_readpc();
rd = op_readdp(dp);
rd = op_ror(rd);
op_writedp(dp, rd);
} break;
//inc_dpx
case 0xbb: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
rd = op_inc(rd);
op_writedp(dp + regs.x, rd);
} break;
//dec_dpx
case 0x9b: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
rd = op_dec(rd);
op_writedp(dp + regs.x, rd);
} break;
//asl_dpx
case 0x1b: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
rd = op_asl(rd);
op_writedp(dp + regs.x, rd);
} break;
//lsr_dpx
case 0x5b: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
rd = op_lsr(rd);
op_writedp(dp + regs.x, rd);
} break;
//rol_dpx
case 0x3b: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
rd = op_rol(rd);
op_writedp(dp + regs.x, rd);
} break;
//ror_dpx
case 0x7b: {
dp = op_readpc();
op_io();
rd = op_readdp(dp + regs.x);
rd = op_ror(rd);
op_writedp(dp + regs.x, rd);
} break;
//inc_addr
case 0xac: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
rd = op_inc(rd);
op_writeaddr(dp, rd);
} break;
//dec_addr
case 0x8c: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
rd = op_dec(rd);
op_writeaddr(dp, rd);
} break;
//asl_addr
case 0x0c: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
rd = op_asl(rd);
op_writeaddr(dp, rd);
} break;
//lsr_addr
case 0x4c: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
rd = op_lsr(rd);
op_writeaddr(dp, rd);
} break;
//rol_addr
case 0x2c: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
rd = op_rol(rd);
op_writeaddr(dp, rd);
} break;
//ror_addr
case 0x6c: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
rd = op_ror(rd);
op_writeaddr(dp, rd);
} break;
//tset_addr_a
case 0x0e: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.p.n = !!((regs.a - rd) & 0x80);
regs.p.z = ((regs.a - rd) == 0);
op_readaddr(dp);
op_writeaddr(dp, rd | regs.a);
} break;
//tclr_addr_a
case 0x4e: {
dp = op_readpc();
dp |= op_readpc() << 8;
rd = op_readaddr(dp);
regs.p.n = !!((regs.a - rd) & 0x80);
regs.p.z = ((regs.a - rd) == 0);
op_readaddr(dp);
op_writeaddr(dp, rd &~ regs.a);
} break;
//incw_dp
case 0x3a: {
dp = op_readpc();
rd = op_readdp(dp);
rd++;
op_writedp(dp++, rd);
rd += op_readdp(dp) << 8;
op_writedp(dp, rd >> 8);
regs.p.n = !!(rd & 0x8000);
regs.p.z = (rd == 0);
} break;
//decw_dp
case 0x1a: {
dp = op_readpc();
rd = op_readdp(dp);
rd--;
op_writedp(dp++, rd);
rd += op_readdp(dp) << 8;
op_writedp(dp, rd >> 8);
regs.p.n = !!(rd & 0x8000);
regs.p.z = (rd == 0);
} break;
#endif

View File

@@ -1,29 +0,0 @@
uint8 ram_read(uint16 addr);
void ram_write(uint16 addr, uint8 data);
uint8 port_read(uint8 port);
void port_write(uint8 port, uint8 data);
//======================
//core SMP bus functions
//======================
uint8 op_busread(uint16 addr);
void op_buswrite(uint16 addr, uint8 data);
void op_io();
uint8 op_read(uint16 addr);
void op_write(uint16 addr, uint8 data);
//===================================================
//helper memory addressing functions used by SMP core
//===================================================
uint8 op_readpc();
uint8 op_readstack();
void op_writestack(uint8 data);
uint8 op_readaddr(uint16 addr);
void op_writeaddr(uint16 addr, uint8 data);
uint8 op_readdp(uint8 addr);
void op_writedp(uint8 addr, uint8 data);

View File

@@ -1,10 +0,0 @@
#ifdef SNES_CPP
void SNES::Audio::update(uint16 l_sample, uint16 r_sample) {
snesinterface.audio_sample(l_sample, r_sample);
}
void SNES::Audio::init() {
}
#endif //ifdef SNES_CPP

View File

@@ -1,7 +0,0 @@
class Audio {
public:
void update(uint16 l_sample, uint16 r_sample);
void init();
friend class SNES;
} audio;

View File

@@ -1,17 +0,0 @@
//====================
//SNES interface class
//====================
//Interfaces SNES core with platform-specific functionality (video, audio, input, ...)
class SNESInterface {
public:
void video_refresh(uint16_t *data, unsigned pitch, unsigned *line, unsigned width, unsigned height);
void audio_sample(uint16_t l_sample, uint16_t r_sample);
void input_poll();
int16_t input_poll(unsigned deviceid, unsigned id);
void init();
void term();
};
extern SNESInterface snesinterface;

View File

@@ -1,84 +0,0 @@
#include "interface/interface.hpp"
#include "scheduler/scheduler.hpp"
#include "tracer/tracer.hpp"
class VideoFilter;
class SNES {
public:
enum Region { NTSC = 0, PAL = 1 };
enum RegionAutodetect { Autodetect = 2 };
enum ExpansionPortDevice { ExpansionNone = 0, ExpansionBSX = 1 };
struct Config {
unsigned controller_port1;
unsigned controller_port2;
unsigned expansion_port;
unsigned region;
struct File {
bool autodetect_type;
bool bypass_patch_crc32;
} file;
struct Path {
string base; //binary path
string user; //user profile path (bsnes.cfg, ...)
string current; //current working directory (path to currently loaded cartridge)
string rom, save, patch, cheat, data;
string bsx, st;
} path;
struct CPU {
unsigned version;
unsigned ntsc_clock_rate;
unsigned pal_clock_rate;
unsigned alu_mul_delay;
unsigned alu_div_delay;
unsigned wram_init_value;
} cpu;
struct SMP {
unsigned ntsc_clock_rate;
unsigned pal_clock_rate;
} smp;
struct PPU1 {
unsigned version;
} ppu1;
struct PPU2 {
unsigned version;
} ppu2;
} config;
//system functions
virtual void run();
virtual void runtoframe();
virtual void init();
virtual void term();
virtual void power();
virtual void reset();
virtual void frame();
virtual void scanline();
//return *active* region / expansion port device information
//settings cached upon power-on
Region region() const;
ExpansionPortDevice expansion() const;
#include "video/video.hpp"
#include "audio/audio.hpp"
#include "input/input.hpp"
SNES();
virtual ~SNES() {}
private:
unsigned snes_region;
unsigned snes_expansion;
};
extern SNES snes;

View File

@@ -1,85 +0,0 @@
##############################
### platform configuration ###
##############################
objects := main $(if $(call streq,$(platform),win),resource) $(objects)
moc = moc
rcc = rcc
ifeq ($(platform),x) # X11
link += $(call mklib,Xtst)
link += `pkg-config --libs QtCore QtGui`
qtflags = `pkg-config --cflags QtCore QtGui`
else ifeq ($(platform),win) # Windows
qtdir = c:/qt450
link += $(call mklibpath,$(qtdir)/lib)
link += $(call mklibpath,$(qtdir)/plugins/imageformats)
link += $(call mklib,mingw32)
link += $(call mklib,qtmain)
link += $(call mklib,QtGui)
link += $(call mklib,comdlg32)
link += $(call mklib,oleaut32)
link += $(call mklib,imm32)
link += $(call mklib,winmm)
link += $(call mklib,winspool)
link += $(call mklib,msimg32)
link += $(call mklib,QtCore)
link += $(call mklib,ole32)
link += $(call mklib,advapi32)
link += $(call mklib,ws2_32)
link += $(call mklib,uuid)
link += $(call mklib,gdi32)
# optional image-file support:
# link += $(call mklib,qjpeg)
# link += $(call mklib,qmng)
qtflags = $(call mkincpath,$(qtdir)/include)
qtflags += $(call mkincpath,$(qtdir)/include/QtCore)
qtflags += $(call mkincpath,$(qtdir)/include/QtGui)
endif
moc_objects = \
$(ui)/base/main.moc \
$(ui)/base/loader.moc \
$(ui)/base/htmlviewer.moc \
$(ui)/base/about.moc \
$(ui)/settings/settings.moc \
$(ui)/settings/video.moc \
$(ui)/settings/audio.moc \
$(ui)/settings/input.moc \
$(ui)/settings/paths.moc \
$(ui)/settings/cheateditor.moc \
$(ui)/settings/advanced.moc \
$(ui)/settings/utility/inputcapture.moc \
$(ui)/settings/utility/codeeditor.moc \
#############
### rules ###
#############
%.moc: $<; $(moc) $(patsubst %.moc,%.hpp,$@) -o $@
$(foreach object,$(moc_objects),$(eval $(object): $(patsubst %.moc,%.hpp,$(object))))
obj/main.$(obj): $(ui)/main.cpp \
$(ui)/* $(ui)/input/* $(ui)/utility/* $(ui)/base/* $(ui)/settings/* $(ui)/settings/utility/* \
data/*
$(call compile,$(qtflags))
$(ui)/resource/resource.rcc: $(ui)/resource/resource.qrc data/*
$(rcc) $(ui)/resource/resource.qrc -o $(ui)/resource/resource.rcc
obj/resource.$(obj): $(ui)/resource/resource.rc
windres $(ui)/resource/resource.rc obj/resource.$(obj)
###############
### targets ###
###############
ui_build: $(ui)/resource/resource.rcc $(moc_objects);
ui_clean:
-$(foreach object,$(moc_objects),@$(call delete,$(object)))
-@$(call delete,$(ui)/resource/resource.rcc)

View File

@@ -1,31 +0,0 @@
SNESInterface snesinterface;
void SNESInterface::video_refresh(uint16_t *data, unsigned pitch, unsigned *line, unsigned width, unsigned height) {
uint32_t *output;
unsigned outpitch;
if(video.lock(output, outpitch) == true) {
unsigned outwidth, outheight;
libfilter::filter.render(output, outpitch, outwidth, outheight, data, pitch, line, width, height);
video.unlock();
video.refresh(outwidth, outheight);
}
}
void SNESInterface::audio_sample(uint16_t left, uint16_t right) {
if(config.audio.mute) left = right = 0;
audio.sample(left, right);
}
void SNESInterface::input_poll() {
inputManager.poll();
}
int16_t SNESInterface::input_poll(unsigned deviceid, unsigned id) {
return inputManager.getStatus(deviceid, id);
}
void SNESInterface::init() {
}
void SNESInterface::term() {
}

View File

@@ -1,163 +0,0 @@
string Utility::selectCartridge() {
audio.clear();
QString filename = QFileDialog::getOpenFileName(0,
"Load Cartridge",
utf8() << (snes.config.path.rom != "" ? snes.config.path.rom : snes.config.path.current),
"SNES images (*.smc *.sfc *.swc *.fig *.bs *.st"
#if defined(GZIP_SUPPORT)
" *.zip *.gz"
#endif
#if defined(JMA_SUPPORT)
" *.jma"
#endif
");;"
"All files (*)"
);
return string() << filename.toUtf8().constData();
}
string Utility::selectFolder(const char *title) {
audio.clear();
QString pathname = QFileDialog::getExistingDirectory(0,
title, utf8() << snes.config.path.current,
QFileDialog::ShowDirsOnly);
return string() << pathname.toUtf8().constData();
}
void Utility::loadCartridge(const char *filename) {
switch(cartridge.detect_image_type(filename)) {
case Cartridge::TypeNormal: loadCartridgeNormal(filename); break;
case Cartridge::TypeBsxSlotted: winLoader->loadBsxSlottedCartridge(filename, ""); break;
case Cartridge::TypeBsxBios: winLoader->loadBsxCartridge(filename, ""); break;
case Cartridge::TypeBsx: winLoader->loadBsxCartridge(snes.config.path.bsx, filename); break;
case Cartridge::TypeSufamiTurboBios: winLoader->loadSufamiTurboCartridge(filename, "", ""); break;
case Cartridge::TypeSufamiTurbo: winLoader->loadSufamiTurboCartridge(snes.config.path.st, filename, ""); break;
}
}
bool Utility::loadCartridgeNormal(const char *base) {
if(!*base) return false;
unloadCartridge();
cartridge.load_normal(base);
modifySystemState(LoadCartridge);
return true;
}
bool Utility::loadCartridgeBsxSlotted(const char *base, const char *slot) {
if(!*base) return false;
unloadCartridge();
cartridge.load_bsx_slotted(base, slot);
modifySystemState(LoadCartridge);
return true;
}
bool Utility::loadCartridgeBsx(const char *base, const char *slot) {
if(!*base) return false;
unloadCartridge();
cartridge.load_bsx(base, slot);
modifySystemState(LoadCartridge);
return true;
}
bool Utility::loadCartridgeSufamiTurbo(const char *base, const char *slotA, const char *slotB) {
if(!*base) return false;
unloadCartridge();
cartridge.load_sufami_turbo(base, slotA, slotB);
modifySystemState(LoadCartridge);
return true;
}
void Utility::unloadCartridge() {
if(cartridge.loaded()) {
cartridge.unload();
modifySystemState(UnloadCartridge);
}
}
void Utility::modifySystemState(system_state_t state) {
video.clear();
audio.clear();
switch(state) {
case LoadCartridge: {
//must call cartridge.load_cart_...() before calling modifySystemState(LoadCartridge)
if(cartridge.loaded() == false) break;
application.power = true;
application.pause = false;
snes.power();
//warn if unsupported hardware detected
string chip;
if(cartridge.has_superfx()) chip = "SuperFX";
else if(cartridge.has_sa1()) chip = "SA-1";
else if(cartridge.has_st011()) chip = "ST011";
else if(cartridge.has_st018()) chip = "ST018";
else if(cartridge.has_dsp3()) chip = "DSP-3";
if(chip != "") {
QMessageBox::warning(winMain->window, "Warning", utf8()
<< "<p><b>Warning:</b><br>Unsupported " << chip << " chip detected. "
<< "It is unlikely that this title will work properly.</p>");
}
showMessage(utf8()
<< "Loaded " << cartridge.name()
<< (cartridge.patched() ? ", and applied UPS patch." : "."));
winMain->window->setWindowTitle(utf8() << BSNES_TITLE << " - " << cartridge.name());
} break;
case UnloadCartridge: {
if(cartridge.loaded() == false) break; //no cart to unload?
cartridge.unload();
application.power = false;
application.pause = true;
showMessage(utf8() << "Unloaded " << cartridge.name() << ".");
winMain->window->setWindowTitle(utf8() << BSNES_TITLE);
} break;
case PowerOn: {
if(cartridge.loaded() == false || application.power == true) break;
application.power = true;
application.pause = false;
snes.power();
showMessage("Power on.");
} break;
case PowerOff: {
if(cartridge.loaded() == false || application.power == false) break;
application.power = false;
application.pause = true;
showMessage("Power off.");
} break;
case PowerCycle: {
if(cartridge.loaded() == false) break;
application.power = true;
application.pause = false;
snes.power();
showMessage("System power was cycled.");
} break;
case Reset: {
if(cartridge.loaded() == false || application.power == false) break;
application.pause = false;
snes.reset();
showMessage("System was reset.");
} break;
}
winMain->syncUi();
winCodeEditor->dismiss();
winCheatEditor->reloadList();
winCheatEditor->syncUi();
}

8
bugs/project.yaml Normal file
View File

@@ -0,0 +1,8 @@
--- !ditz.rubyforge.org,2008-03-06/project
name: snesram
version: "0.5"
components:
- !ditz.rubyforge.org,2008-03-06/component
name: snesram
releases: []

View File

@@ -182,7 +182,7 @@ AVRDUDE_PROGRAMMER = stk500v2
# com1 = serial port. Use lpt1 to connect to parallel port.
AVRDUDE_PORT = /dev/tty.PL2303-00002006
AVRDUDE_PORT =/dev/tty.PL2303-00001124
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex

View File

@@ -8,8 +8,8 @@
# Revision: $Id: checksize 83 2006-01-05 22:20:53Z cs $
error=0
codelimit=8192 # default value
datalimit=992 # default value; leave 32 bytes for stack
codelimit=2048 # default value
datalimit=96 # default value; leave 32 bytes for stack
if [ $# -gt 1 ]; then
codelimit="$2"

View File

@@ -29,7 +29,7 @@ extern FILE uart_stdout;
#define RAM_REG PINA
#define CTRL_PORT PORTB
#define CTR_DIR DDRB
#define CTRL_DIR DDRB
#define LATCH_PORT PORTB
#define LATCH_DIR DDRB
@@ -39,14 +39,77 @@ extern FILE uart_stdout;
#define LED_PORT PORTD
#define LED_DIR DDRD
#define FILENAME "sprite.raw"
//#define FILENAME "sprite.raw" //ok
//#define FILENAME "ascii.smc" //ok
//#define FILENAME "rom.smc" //ok
//#define FILENAME "supert.smc" //ok
//#define FILENAME "vortex.smc" //failed
//#define FILENAME "mrdo.smc" //failed
//#define FILENAME "spacei.smc" //ok ntsc
//#define FILENAME "bank01.smc" //ok
//#define FILENAME "bank02.smc" //ok
//#define FILENAME "bank03.smc" //ok
//#define FILENAME "bank04.smc" //ok
//#define FILENAME "bank05.smc" //ok
//#define FILENAME "bank06.smc" //ok
//#define FILENAME "bank07.smc" //ok
//#define FILENAME "banklo.smc" //ok
//#define FILENAME "bankhi.smc" //ok
//#define FILENAME "vram2.smc" //ok
//#define FILENAME "super02.smc" //ok
//#define FILENAME "super01.smc"//ok
//#define FILENAME "crc.smc" //ok
//#define FILENAME "banks.smc" //ok
//#define FILENAME "hungry.smc" //ok
//#define FILENAME "arkanoid.smc"//ok
//#define FILENAME "eric.smc"
#define FILENAME "turrican.smc"
#define ROMSIZE 4
#define DUMPNAME "dump256.smc"
#define BUFFER_SIZE 512
#define BLOCKS 512
#define BLOCKS (ROMSIZE << 8)
#define MEMSIZE 0x80000
uint8_t read_buffer[BUFFER_SIZE];
uint16_t crc_xmodem_update (uint16_t crc, uint8_t data)
{
int i;
crc = crc ^ ((uint16_t)data << 8);
for (i=0; i<8; i++)
{
if (crc & 0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
}
return crc;
}
uint16_t do_crc(uint8_t * data,uint16_t size)
{
uint16_t crc =0;
uint16_t i;
for (i=0; i<size; i++){
crc = crc_xmodem_update(crc,data[i]);
//printf("%x : %x\n",crc,data[i]);
}
return crc;
}
uint16_t do_crc_update(uint16_t crc,uint8_t * data,uint16_t size)
{
uint16_t i;
for (i=0; i<size; i++)
crc = crc_xmodem_update(crc,data[i]);
return crc;
}
void dump_packet(uint32_t addr,uint32_t len,uint8_t *packet){
uint16_t i,j;
uint16_t sum = 0;
@@ -101,6 +164,17 @@ void spi_master_transmit(unsigned char cData)
while(!(SPSR & (1<<SPIF)));
}
void sram_set_addr(uint32_t addr)
{
spi_master_transmit((uint8_t)(addr>>16));
spi_master_transmit((uint8_t)(addr>>8));
spi_master_transmit((uint8_t)(addr>>0));
LATCH_PORT |= (1<<S_LATCH);
LATCH_PORT &= ~(1<<S_LATCH);
}
uint8_t sram_read(uint32_t addr)
{
uint8_t byte;
@@ -164,18 +238,28 @@ void sram_init(void){
RAM_DIR = 0x00;
RAM_PORT = 0x00;
CTR_DIR |= ((1<<R_WR) | (1<<R_RD));
CTRL_DIR |= ((1<<R_WR) | (1<<R_RD));
CTRL_PORT |= (1<<R_RD);
CTRL_PORT |= (1<<R_WR);
LED_PORT |= (1<<D_LED0);
}
void sram_snes_mode(void){
void sram_snes_mode01(void){
CTRL_PORT |= (1<<R_WR);
CTRL_PORT &= ~(1<<R_RD);
}
void sram_snes_mode02(void){
CTRL_DIR |= (1<<R_WR);
CTRL_PORT |= (1<<R_WR);
//CTRL_PORT &= ~(1<<R_RD);
CTRL_DIR &= ~(1<<R_RD);
CTRL_PORT &= ~(1<<R_RD);
}
void sram_clear(uint32_t addr, uint32_t len){
uint32_t i;
@@ -217,8 +301,9 @@ int main(void)
uint8_t fat_attrib = 0;
uint32_t fat_size = 0;
uint32_t rom_addr = 0;
uint32_t skip_block = 0;
uint8_t bank_cnt = 0;
uint16_t crc = 0;
uint16_t block_cnt;
uart_init();
stdout = &uart_stdout;
@@ -228,19 +313,37 @@ int main(void)
spi_init();
printf("SPI Init\n");
//sram_clear(0x000000, 0x400000);
//printf("sram_clear\n");
#if 0
uint8_t t[] = "david";
printf("Test CRC %x\n",do_crc(t,5));
while(1);
#endif
//printf("read 0x0f0f\n");
//sram_read(0x0f0f);
//printf("write 0x0f0f\n");
//sram_write(0x0f0f,0xaa);
//while(1);
#if 0
sram_clear(0x000000, 0x80000);
printf("sram_clear\n");
#endif
#if 0
printf("read 0x0f0f\n");
sram_read(0x0f0f);
printf("write 0x0f0f\n");
sram_write(0x0f0f,0xaa);
#endif
#if 0
rom_addr = 0x4aaaa;
printf("write %lx\n",rom_addr);
sram_set_addr(rom_addr);
while(1);
#endif
while ( mmc_init() !=0) {
printf("No sdcard...\n");
}
printf("MMC Init sone\n");
printf("MMC Init done\n");
fat_init(read_buffer);
printf("FAT Init done.\n");
rom_addr = 0x000000;
@@ -253,29 +356,102 @@ int main(void)
read_buffer) == 1) {
for (uint16_t block_cnt=0; block_cnt<BLOCKS; block_cnt++) {
for (block_cnt=0; block_cnt<BLOCKS; block_cnt++) {
fat_read_file (fat_cluster,read_buffer,block_cnt);
if (block_cnt % 16 == 0)
printf("Write Ram 0x%lx Skipped %li\n",rom_addr,skip_block);
if (sram_check(read_buffer,512))
sram_copy(rom_addr,read_buffer,512);
else
skip_block +=1;
if (block_cnt && block_cnt % 64 == 0){
printf("Write Ram Bank: 0x%x Addr: 0x%lx Block: %x CRC: %x\n",bank_cnt,rom_addr,block_cnt,crc);
bank_cnt++;
crc = 0;
}
crc = do_crc_update(crc,read_buffer,512);
sram_copy(rom_addr,read_buffer,512);
rom_addr += 512;
}
printf("Done 0x%lx Skipped %li\n",rom_addr,skip_block);
printf("Write Ram Bank: 0x%x Addr: 0x%lx Block: %x CRC: %x\n",bank_cnt,rom_addr,block_cnt,crc);
printf("Done\n");
}
printf("Dump Headern\r");
rom_addr = 0x8000-512;
sram_read_buffer(rom_addr,read_buffer,512);
dump_packet(rom_addr,512,read_buffer);
#if 0
printf("Dump Memory\n\r");
rom_addr = 0x000000;
for (uint16_t block_cnt=0; block_cnt<BLOCKS; block_cnt++) {
for (uint16_t block_cnt=0; block_cnt < 64; block_cnt++) {
sram_read_buffer(rom_addr,read_buffer,512);
dump_packet(rom_addr,512,read_buffer);
rom_addr += 512;
}
printf("\nDone 0x%lx\n",rom_addr);
sram_snes_mode();
printf("\nEnter Snes mode\n");
#endif
#if 1
block_cnt = 0;
crc = 0;
bank_cnt=0x00;
rom_addr = 0x000000;
for (block_cnt=0; block_cnt<BLOCKS; block_cnt++) {
sram_read_buffer(rom_addr,read_buffer,512);
if (block_cnt && block_cnt % 64 == 0){
printf("Read Ram Bank: 0x%x Addr: 0x%lx Block: %x CRC: %x\n",bank_cnt,rom_addr,block_cnt,crc);
bank_cnt++;
crc = 0;
}
crc = do_crc_update(crc,read_buffer,512);
rom_addr += 512;
}
printf("Read Ram Bank: 0x%x Addr: 0x%lx Block: %x CRC: %x\n",bank_cnt,rom_addr,block_cnt,crc);
#endif
#if 0
printf("Look for %s\n",DUMPNAME);
fat_cluster = 0;
fat_attrib = 0;
fat_size = 0;
if (fat_search_file((uint8_t*)DUMPNAME,
&fat_cluster,
&fat_size,
&fat_attrib,
read_buffer) == 1) {
printf("Found %s\n",DUMPNAME);
rom_addr = 0x000000;
bank_cnt =0;
for (uint16_t block_cnt=0; block_cnt<BLOCKS; block_cnt++) {
printf("Write 1");
sram_read_buffer(rom_addr,read_buffer,512);
printf("Write 2");
fat_write_file (fat_cluster,read_buffer,block_cnt);
if (block_cnt % 64 == 0){
bank_cnt++;
}
printf("Write File Bank: 0x%x Addr: 0x%lx Skipped: %li\n",bank_cnt,rom_addr,skip_block);
rom_addr += 512;
}
printf("Done 0x%lx Skipped %li\n",rom_addr,skip_block);
}
#endif
#if 0
sram_snes_mode01();
printf("\nEnter Snes mode 02\n");
#endif
#if 0
sram_snes_mode02();
printf("\nEnter Snes mode 02\n");
#endif
printf("\nUpload done.\n");
while(1);
return 0 ;

168
poc/avr_usbload/Makefile Normal file
View File

@@ -0,0 +1,168 @@
# Name: Makefile
# Project: custom-class example
# Author: Christian Starkjohann
# Creation Date: 2008-04-07
# Tabsize: 4
# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
# This Revision: $Id: Makefile 692 2008-11-07 15:07:40Z cs $
DEVICE = atmega16
F_CPU = 16000000 # in Hz
FUSE_L = # see below for fuse values for particular devices
FUSE_H =
AVRDUDE = avrdude -c stk500v2 -p $(DEVICE) -P /dev/tty.PL2303-00002006
#AVRDUDE = avrdude -c stk500v2 -p $(DEVICE) -P /dev/tty.PL2303-00001424
CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0
#-std=gnu99
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o uart.o fifo.o sram.o crc.o debug.o
COMPILE = avr-gcc -Wall -Os -DF_CPU=$(F_CPU) $(CFLAGS) -mmcu=$(DEVICE)
##############################################################################
# Fuse values for particular devices
##############################################################################
# If your device is not listed here, go to
# http://palmavr.sourceforge.net/cgi-bin/fc.cgi
# and choose options for external crystal clock and no clock divider
#
################################## ATMega8 ##################################
# ATMega8 FUSE_L (Fuse low byte):
# 0x9f = 1 0 0 1 1 1 1 1
# ^ ^ \ / \--+--/
# | | | +------- CKSEL 3..0 (external >8M crystal)
# | | +--------------- SUT 1..0 (crystal osc, BOD enabled)
# | +------------------ BODEN (BrownOut Detector enabled)
# +-------------------- BODLEVEL (2.7V)
# ATMega8 FUSE_H (Fuse high byte):
# 0xc9 = 1 1 0 0 1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000)
# ^ ^ ^ ^ ^ ^ ^------ BOOTSZ0
# | | | | | +-------- BOOTSZ1
# | | | | + --------- EESAVE (don't preserve EEPROM over chip erase)
# | | | +-------------- CKOPT (full output swing)
# | | +---------------- SPIEN (allow serial programming)
# | +------------------ WDTON (WDT not always on)
# +-------------------- RSTDISBL (reset pin is enabled)
#
############################## ATMega48/88/168 ##############################
# ATMega*8 FUSE_L (Fuse low byte):
# 0xdf = 1 1 0 1 1 1 1 1
# ^ ^ \ / \--+--/
# | | | +------- CKSEL 3..0 (external >8M crystal)
# | | +--------------- SUT 1..0 (crystal osc, BOD enabled)
# | +------------------ CKOUT (if 0: Clock output enabled)
# +-------------------- CKDIV8 (if 0: divide by 8)
# ATMega*8 FUSE_H (Fuse high byte):
# 0xde = 1 1 0 1 1 1 1 0
# ^ ^ ^ ^ ^ \-+-/
# | | | | | +------ BODLEVEL 0..2 (110 = 1.8 V)
# | | | | + --------- EESAVE (preserve EEPROM over chip erase)
# | | | +-------------- WDTON (if 0: watchdog always on)
# | | +---------------- SPIEN (allow serial programming)
# | +------------------ DWEN (debug wire enable)
# +-------------------- RSTDISBL (reset pin is enabled)
#
############################## ATTiny25/45/85 ###############################
# ATMega*5 FUSE_L (Fuse low byte):
# 0xef = 1 1 1 0 1 1 1 1
# ^ ^ \+/ \--+--/
# | | | +------- CKSEL 3..0 (clock selection -> crystal @ 12 MHz)
# | | +--------------- SUT 1..0 (BOD enabled, fast rising power)
# | +------------------ CKOUT (clock output on CKOUT pin -> disabled)
# +-------------------- CKDIV8 (divide clock by 8 -> don't divide)
# ATMega*5 FUSE_H (Fuse high byte):
# 0xdd = 1 1 0 1 1 1 0 1
# ^ ^ ^ ^ ^ \-+-/
# | | | | | +------ BODLEVEL 2..0 (brownout trigger level -> 2.7V)
# | | | | +---------- EESAVE (preserve EEPROM on Chip Erase -> not preserved)
# | | | +-------------- WDTON (watchdog timer always on -> disable)
# | | +---------------- SPIEN (enable serial programming -> enabled)
# | +------------------ DWEN (debug wire enable)
# +-------------------- RSTDISBL (disable external reset -> enabled)
#
################################ ATTiny2313 #################################
# ATTiny2313 FUSE_L (Fuse low byte):
# 0xef = 1 1 1 0 1 1 1 1
# ^ ^ \+/ \--+--/
# | | | +------- CKSEL 3..0 (clock selection -> crystal @ 12 MHz)
# | | +--------------- SUT 1..0 (BOD enabled, fast rising power)
# | +------------------ CKOUT (clock output on CKOUT pin -> disabled)
# +-------------------- CKDIV8 (divide clock by 8 -> don't divide)
# ATTiny2313 FUSE_H (Fuse high byte):
# 0xdb = 1 1 0 1 1 0 1 1
# ^ ^ ^ ^ \-+-/ ^
# | | | | | +---- RSTDISBL (disable external reset -> enabled)
# | | | | +-------- BODLEVEL 2..0 (brownout trigger level -> 2.7V)
# | | | +-------------- WDTON (watchdog timer always on -> disable)
# | | +---------------- SPIEN (enable serial programming -> enabled)
# | +------------------ EESAVE (preserve EEPROM on Chip Erase -> not preserved)
# +-------------------- DWEN (debug wire enable)
# symbolic targets:
help:
@echo "This Makefile has no default rule. Use one of the following:"
@echo "make hex ....... to build main.hex"
@echo "make program ... to flash fuses and firmware"
@echo "make fuse ...... to flash the fuses"
@echo "make flash ..... to flash the firmware (use this on metaboard)"
@echo "make clean ..... to delete objects and hex file"
all: hex
hex: main.hex
program: flash fuse
# rule for programming fuse bits:
fuse:
@[ "$(FUSE_H)" != "" -a "$(FUSE_L)" != "" ] || \
{ echo "*** Edit Makefile and choose values for FUSE_L and FUSE_H!"; exit 1; }
$(AVRDUDE) -U hfuse:w:$(FUSE_H):m -U lfuse:w:$(FUSE_L):m
# rule for uploading firmware:
flash: main.hex
$(AVRDUDE) -U flash:w:main.hex:i
# rule for deleting dependent files (those which can be built by Make):
clean:
rm -f main.hex main.lst main.obj main.cof main.list main.map main.eep.hex main.elf *.o usbdrv/*.o main.s usbdrv/oddebug.s usbdrv/usbdrv.s
# Generic rule for compiling C files:
.c.o:
$(COMPILE) -c $< -o $@
# Generic rule for assembling Assembler source files:
.S.o:
$(COMPILE) -x assembler-with-cpp -c $< -o $@
# "-x assembler-with-cpp" should not be necessary since this is the default
# file type for the .S (with capital S) extension. However, upper case
# characters are not always preserved on Windows. To ensure WinAVR
# compatibility define the file type manually.
# Generic rule for compiling C to assembler, used for debugging only.
.c.s:
$(COMPILE) -S $< -o $@
# file targets:
# Since we don't want to ship the driver multipe times, we copy it into this project:
usbdrv:
cp -r ../../../usbdrv .
main.elf: usbdrv $(OBJECTS) # usbdrv dependency only needed because we copy it
$(COMPILE) -o main.elf $(OBJECTS)
main.hex: main.elf
rm -f main.hex main.eep.hex
avr-objcopy -j .text -j .data -O ihex main.elf main.hex
avr-size main.hex
# debugging targets:
disasm: main.elf
avr-objdump -d main.elf
cpp:
$(COMPILE) -E main.c

35
poc/avr_usbload/checksize Normal file
View File

@@ -0,0 +1,35 @@
#!/bin/sh
# Name: checksize
# Project: PowerSwitch/AVR-USB
# Author: Christian Starkjohann
# Creation Date: 2004-12-29
# Tabsize: 4
# Copyright: (c) 2005 OBJECTIVE DEVELOPMENT Software GmbH.
# Revision: $Id: checksize 83 2006-01-05 22:20:53Z cs $
error=0
codelimit=16384 # default value
datalimit=992 # default value; leave 32 bytes for stack
if [ $# -gt 1 ]; then
codelimit="$2"
fi
if [ $# -gt 2 ]; then
datalimit="$3"
fi
set -- `avr-size -d "$1" | awk '/[0-9]/ {print $1 + $2, $2 + $3, $2}'`
if [ $1 -gt $codelimit ]; then
echo "*** code size $1 exceeds limit of $codelimit"
error=1
else
echo "ROM: $1 bytes (data=$3)"
fi
if [ $2 -gt $datalimit ]; then
echo "*** data size $2 exceeds limit of $datalimit"
error=1
else
echo "RAM: $2 bytes"
fi
exit $error

View File

@@ -0,0 +1,48 @@
# Name: Makefile
# Project: custom-class example
# Author: Christian Starkjohann
# Creation Date: 2008-04-06
# Tabsize: 4
# Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
# License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
# This Revision: $Id: Makefile 692 2008-11-07 15:07:40Z cs $
# Concigure the following definitions according to your system.
# This Makefile has been tested on Mac OS X, Linux and Windows.
# Use the following 3 lines on Unix (uncomment the framework on Mac OS X):
USBFLAGS = `libusb-config --cflags`
USBLIBS = `libusb-config --libs`
EXE_SUFFIX =
# Use the following 3 lines on Windows and comment out the 3 above. You may
# have to change the include paths to where you installed libusb-win32
#USBFLAGS = -I/usr/local/include
#USBLIBS = -L/usr/local/lib -lusb
#EXE_SUFFIX = .exe
NAME = snesuploader
OBJECTS = opendevice.o $(NAME).o
CC = gcc
CFLAGS = $(CPPFLAGS) $(USBFLAGS) -O -g -Wall
LIBS = $(USBLIBS)
PROGRAM = $(NAME)$(EXE_SUFFIX)
all: $(PROGRAM)
.c.o:
$(CC) $(CFLAGS) -c $<
$(PROGRAM): $(OBJECTS)
$(CC) -o $(PROGRAM) $(OBJECTS) $(LIBS)
strip: $(PROGRAM)
strip $(PROGRAM)
clean:
rm -f *.o $(PROGRAM)

View File

@@ -0,0 +1,285 @@
/*
* Name: opendevice.c Project: V-USB host-side library Author: Christian
* Starkjohann Creation Date: 2008-04-10 Tabsize: 4 Copyright: (c) 2008 by
* OBJECTIVE DEVELOPMENT Software GmbH License: GNU GPL v2 (see License.txt),
* GNU GPL v3 or proprietary (CommercialLicense.txt) This Revision: $Id:
* opendevice.c 740 2009-04-13 18:23:31Z cs $
*/
/*
* General Description: The functions in this module can be used to find and
* open a device based on libusb or libusb-win32.
*/
#include <stdio.h>
#include "opendevice.h"
/*
* -------------------------------------------------------------------------
*/
#define MATCH_SUCCESS 1
#define MATCH_FAILED 0
#define MATCH_ABORT -1
/*
* private interface: match text and p, return MATCH_SUCCESS, MATCH_FAILED, or
* MATCH_ABORT.
*/
static int _shellStyleMatch(char *text, char *p)
{
int last,
matched,
reverse;
for (; *p; text++, p++) {
if (*text == 0 && *p != '*')
return MATCH_ABORT;
switch (*p) {
case '\\':
/*
* Literal match with following character.
*/
p++;
/*
* FALLTHROUGH
*/
default:
if (*text != *p)
return MATCH_FAILED;
continue;
case '?':
/*
* Match anything.
*/
continue;
case '*':
while (*++p == '*')
/*
* Consecutive stars act just like one.
*/
continue;
if (*p == 0)
/*
* Trailing star matches everything.
*/
return MATCH_SUCCESS;
while (*text)
if ((matched = _shellStyleMatch(text++, p)) != MATCH_FAILED)
return matched;
return MATCH_ABORT;
case '[':
reverse = p[1] == '^';
if (reverse) /* Inverted character class. */
p++;
matched = MATCH_FAILED;
if (p[1] == ']' || p[1] == '-')
if (*++p == *text)
matched = MATCH_SUCCESS;
for (last = *p; *++p && *p != ']'; last = *p)
if (*p == '-' && p[1] != ']' ? *text <= *++p
&& *text >= last : *text == *p)
matched = MATCH_SUCCESS;
if (matched == reverse)
return MATCH_FAILED;
continue;
}
}
return *text == 0;
}
/*
* public interface for shell style matching: returns 0 if fails, 1 if matches
*/
static int shellStyleMatch(char *text, char *pattern)
{
if (pattern == NULL) /* NULL pattern is synonymous to "*" */
return 1;
return _shellStyleMatch(text, pattern) == MATCH_SUCCESS;
}
/*
* -------------------------------------------------------------------------
*/
int usbGetStringAscii(usb_dev_handle * dev, int index, char *buf, int buflen)
{
char buffer[256];
int rval,
i;
if ((rval = usb_get_string_simple(dev, index, buf, buflen)) >= 0) /* use
* libusb
* version
* if
* it
* works
*/
return rval;
if ((rval =
usb_control_msg(dev, USB_ENDPOINT_IN, USB_REQ_GET_DESCRIPTOR,
(USB_DT_STRING << 8) + index, 0x0409, buffer,
sizeof(buffer), 5000)) < 0)
return rval;
if (buffer[1] != USB_DT_STRING) {
*buf = 0;
return 0;
}
if ((unsigned char) buffer[0] < rval)
rval = (unsigned char) buffer[0];
rval /= 2;
/*
* lossy conversion to ISO Latin1:
*/
for (i = 1; i < rval; i++) {
if (i > buflen) /* destination buffer overflow */
break;
buf[i - 1] = buffer[2 * i];
if (buffer[2 * i + 1] != 0) /* outside of ISO Latin1 range */
buf[i - 1] = '?';
}
buf[i - 1] = 0;
return i - 1;
}
/*
* -------------------------------------------------------------------------
*/
int usbOpenDevice(usb_dev_handle ** device, int vendorID,
char *vendorNamePattern, int productID,
char *productNamePattern, char *serialNamePattern,
FILE * printMatchingDevicesFp, FILE * warningsFp)
{
struct usb_bus *bus;
struct usb_device *dev;
usb_dev_handle *handle = NULL;
int errorCode = USBOPEN_ERR_NOTFOUND;
usb_find_busses();
usb_find_devices();
for (bus = usb_get_busses(); bus; bus = bus->next) {
for (dev = bus->devices; dev; dev = dev->next) { /* iterate over
* all devices
* on all
* busses */
if ((vendorID == 0 || dev->descriptor.idVendor == vendorID)
&& (productID == 0 || dev->descriptor.idProduct == productID)) {
char vendor[256],
product[256],
serial[256];
int len;
handle = usb_open(dev); /* we need to open the device in order
* to query strings */
if (!handle) {
errorCode = USBOPEN_ERR_ACCESS;
if (warningsFp != NULL)
fprintf(warningsFp,
"Warning: cannot open VID=0x%04x PID=0x%04x: %s\n",
dev->descriptor.idVendor,
dev->descriptor.idProduct, usb_strerror());
continue;
}
/*
* now check whether the names match:
*/
len = vendor[0] = 0;
if (dev->descriptor.iManufacturer > 0) {
len =
usbGetStringAscii(handle, dev->descriptor.iManufacturer,
vendor, sizeof(vendor));
}
if (len < 0) {
errorCode = USBOPEN_ERR_ACCESS;
if (warningsFp != NULL)
fprintf(warningsFp,
"Warning: cannot query manufacturer for VID=0x%04x PID=0x%04x: %s\n",
dev->descriptor.idVendor,
dev->descriptor.idProduct, usb_strerror());
} else {
errorCode = USBOPEN_ERR_NOTFOUND;
/*
* printf("seen device from vendor ->%s<-\n", vendor);
*/
if (shellStyleMatch(vendor, vendorNamePattern)) {
len = product[0] = 0;
if (dev->descriptor.iProduct > 0) {
len =
usbGetStringAscii(handle,
dev->descriptor.iProduct,
product, sizeof(product));
}
if (len < 0) {
errorCode = USBOPEN_ERR_ACCESS;
if (warningsFp != NULL)
fprintf(warningsFp,
"Warning: cannot query product for VID=0x%04x PID=0x%04x: %s\n",
dev->descriptor.idVendor,
dev->descriptor.idProduct,
usb_strerror());
} else {
errorCode = USBOPEN_ERR_NOTFOUND;
/*
* printf("seen product ->%s<-\n", product);
*/
if (shellStyleMatch(product, productNamePattern)) {
len = serial[0] = 0;
if (dev->descriptor.iSerialNumber > 0) {
len =
usbGetStringAscii(handle,
dev->descriptor.
iSerialNumber, serial,
sizeof(serial));
}
if (len < 0) {
errorCode = USBOPEN_ERR_ACCESS;
if (warningsFp != NULL)
fprintf(warningsFp,
"Warning: cannot query serial for VID=0x%04x PID=0x%04x: %s\n",
dev->descriptor.idVendor,
dev->descriptor.idProduct,
usb_strerror());
}
if (shellStyleMatch(serial, serialNamePattern)) {
if (printMatchingDevicesFp != NULL) {
if (serial[0] == 0) {
fprintf(printMatchingDevicesFp,
"VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\"\n",
dev->descriptor.idVendor,
dev->descriptor.idProduct,
vendor, product);
} else {
fprintf(printMatchingDevicesFp,
"VID=0x%04x PID=0x%04x vendor=\"%s\" product=\"%s\" serial=\"%s\"\n",
dev->descriptor.idVendor,
dev->descriptor.idProduct,
vendor, product, serial);
}
} else {
break;
}
}
}
}
}
}
usb_close(handle);
handle = NULL;
}
}
if (handle) /* we have found a deice */
break;
}
if (handle != NULL) {
errorCode = 0;
*device = handle;
}
if (printMatchingDevicesFp != NULL) /* never return an error for listing
* only */
errorCode = 0;
return errorCode;
}
/*
* -------------------------------------------------------------------------
*/

View File

@@ -1,11 +1,11 @@
/* Name: opendevice.h
* Project: AVR-USB host-side library
* Project: V-USB host-side library
* Author: Christian Starkjohann
* Creation Date: 2008-04-10
* Tabsize: 4
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id: opendevice.h 692 2008-11-07 15:07:40Z cs $
* This Revision: $Id: opendevice.h 740 2009-04-13 18:23:31Z cs $
*/
/*

View File

@@ -0,0 +1,244 @@
/*
* Name: set-led.c Project: custom-class, a basic USB example Author:
* Christian Starkjohann Creation Date: 2008-04-10 Tabsize: 4 Copyright: (c)
* 2008 by OBJECTIVE DEVELOPMENT Software GmbH License: GNU GPL v2 (see
* License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) This
* Revision: $Id: set-led.c 692 2008-11-07 15:07:40Z cs $
*/
/*
* General Description: This is the host-side driver for the custom-class
* example device. It searches the USB for the LEDControl device and sends the
* requests understood by this device. This program must be linked with libusb
* on Unix and libusb-win32 on Windows. See http://libusb.sourceforge.net/ or
* http://libusb-win32.sourceforge.net/ respectively.
*/
#define READ_BUFFER_SIZE 1024
#define SEND_BUFFER_SIZE 128
#define BUFFER_CRC (1024 * 32)
#define BANK_SIZE (1<<15)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <usb.h> /* this is libusb */
#include "opendevice.h" /* common code moved to separate module */
#include "../requests.h" /* custom request numbers */
#include "../usbconfig.h" /* device's VID/PID and names */
void dump_packet(uint32_t addr, uint32_t len, uint8_t * packet)
{
uint16_t i,
j;
uint16_t sum = 0;
uint8_t clear = 0;
for (i = 0; i < len; i += 16) {
sum = 0;
for (j = 0; j < 16; j++) {
sum += packet[i + j];
}
if (!sum) {
clear = 1;
continue;
}
if (clear) {
printf("*\n");
clear = 0;
}
printf("%08x:", addr + i);
for (j = 0; j < 16; j++) {
printf(" %02x", packet[i + j]);
}
printf(" |");
for (j = 0; j < 16; j++) {
if (packet[i + j] >= 33 && packet[i + j] <= 126)
printf("%c", packet[i + j]);
else
printf(".");
}
printf("|\n");
}
}
uint16_t crc_xmodem_update(uint16_t crc, uint8_t data)
{
int i;
crc = crc ^ ((uint16_t) data << 8);
for (i = 0; i < 8; i++) {
if (crc & 0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
}
return crc;
}
uint16_t do_crc(uint8_t * data, uint16_t size)
{
uint16_t crc = 0;
uint16_t i;
for (i = 0; i < size; i++) {
crc = crc_xmodem_update(crc, data[i]);
}
return crc;
}
uint16_t do_crc_update(uint16_t crc, uint8_t * data, uint16_t size)
{
uint16_t i;
for (i = 0; i < size; i++)
crc = crc_xmodem_update(crc, data[i]);
return crc;
}
static void usage(char *name)
{
fprintf(stderr, "usage:\n");
fprintf(stderr, " %s upload filename.. upload\n", name);
}
int main(int argc, char **argv)
{
usb_dev_handle *handle = NULL;
const unsigned char rawVid[2] = { USB_CFG_VENDOR_ID }, rawPid[2] = {
USB_CFG_DEVICE_ID};
char vendor[] = { USB_CFG_VENDOR_NAME, 0 }, product[] = {
USB_CFG_DEVICE_NAME, 0};
int cnt,
vid,
pid;
int cnt_crc = 0;
uint8_t *read_buffer;
uint8_t *crc_buffer;
uint32_t addr = 0;
uint16_t addr_lo = 0;
uint16_t addr_hi = 0;
uint16_t step = 0;
uint16_t crc = 0;
uint8_t bank = 0;
FILE *fp;
usb_init();
if (argc < 2) { /* we need at least one argument */
usage(argv[0]);
exit(1);
}
/*
* compute VID/PID from usbconfig.h so that there is a central source
* of information
*/
vid = rawVid[1] * 256 + rawVid[0];
pid = rawPid[1] * 256 + rawPid[0];
/*
* The following function is in opendevice.c:
*/
if (usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) !=
0) {
fprintf(stderr,
"Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n",
product, vid, pid);
exit(1);
}
printf("Open USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid,
pid);
if (strcasecmp(argv[1], "upload") == 0) {
if (argc < 3) { /* we need at least one argument */
usage(argv[0]);
exit(1);
}
fp = fopen(argv[2], "r");
if (fp == NULL) {
fprintf(stderr, "Cannot open file %s ", argv[2]);
exit(1);
}
read_buffer = (unsigned char *) malloc(READ_BUFFER_SIZE);
crc_buffer = (unsigned char *) malloc(BUFFER_CRC);
memset(crc_buffer, 0, BUFFER_CRC);
addr = 0x000000;
usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
USB_UPLOAD_INIT, 0, 0, NULL, 0, 5000);
while ((cnt = fread(read_buffer, READ_BUFFER_SIZE, 1, fp)) > 0) {
for (step = 0; step < READ_BUFFER_SIZE; step += SEND_BUFFER_SIZE) {
addr_lo = addr & 0xffff;
addr_hi = (addr >> 16) & 0xff;
usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_ENDPOINT_OUT, USB_UPLOAD_ADDR, addr_hi,
addr_lo, (char *) read_buffer + step,
SEND_BUFFER_SIZE, 5000);
#if 0
dump_packet(addr, SEND_BUFFER_SIZE, read_buffer + step);
#endif
addr += SEND_BUFFER_SIZE;
}
memcpy(crc_buffer + cnt_crc, read_buffer, READ_BUFFER_SIZE);
cnt_crc += READ_BUFFER_SIZE;
if (cnt_crc >= BANK_SIZE) {
crc = do_crc(crc_buffer, BANK_SIZE);
printf
("Addr: 0x%06x Bank: 0x%02x HiAddr: 0x%02x LoAddr: 0x%04x Crc: 0x%04x\n",
addr, bank, addr_hi, addr_lo, crc);
memset(crc_buffer, 0, BUFFER_CRC);
bank++;
cnt_crc = 0;
}
}
cnt = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_ENDPOINT_OUT, USB_CRC, addr_hi, addr_lo, NULL,
0, 5000);
if (cnt < 1) {
if (cnt < 0) {
fprintf(stderr, "USB error: %s\n", usb_strerror());
} else {
fprintf(stderr, "only %d bytes received.\n", cnt);
}
}
} else if (strcasecmp(argv[1], "crc") == 0) {
/*
* if(argc < 2){ usage(argv[0]); exit(1); }
*/
addr = 0x000000;
addr_lo = addr & 0xffff;
addr_hi = (addr >> 16) & 0xff;
printf("Request CRC for Addr: 0x%06x\n", addr);
cnt = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_ENDPOINT_OUT, USB_CRC_ADDR, addr_hi, addr_lo,
NULL, (1 << 15) / 4, 5000);
if (cnt < 1) {
if (cnt < 0) {
fprintf(stderr, "USB error: %s\n", usb_strerror());
} else {
fprintf(stderr, "only %d bytes received.\n", cnt);
}
}
} else {
usage(argv[0]);
exit(1);
}
usb_close(handle);
return 0;
}

41
poc/avr_usbload/crc.c Normal file
View File

@@ -0,0 +1,41 @@
#include <stdlib.h>
#include <stdint.h>
#include "crc.h"
#include "uart.h"
extern FILE uart_stdout;
uint16_t crc_xmodem_update(uint16_t crc, uint8_t data)
{
int i;
crc = crc ^ ((uint16_t) data << 8);
for (i = 0; i < 8; i++) {
if (crc & 0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
}
return crc;
}
uint16_t do_crc(uint8_t * data, uint16_t size)
{
uint16_t crc = 0;
uint16_t i;
for (i = 0; i < size; i++) {
crc = crc_xmodem_update(crc, data[i]);
// printf("%x : %x\n",crc,data[i]);
}
return crc;
}
uint16_t do_crc_update(uint16_t crc, uint8_t * data, uint16_t size)
{
uint16_t i;
for (i = 0; i < size; i++)
crc = crc_xmodem_update(crc, data[i]);
return crc;
}

7
poc/avr_usbload/crc.h Normal file
View File

@@ -0,0 +1,7 @@
#include <stdlib.h>
#include <stdint.h>
uint16_t crc_xmodem_update (uint16_t crc, uint8_t data);
uint16_t do_crc(uint8_t * data,uint16_t size);
uint16_t do_crc_update(uint16_t crc,uint8_t * data,uint16_t size);

44
poc/avr_usbload/debug.c Normal file
View File

@@ -0,0 +1,44 @@
#include <stdlib.h>
#include <stdint.h>
#include "debug.h"
#include "uart.h"
extern FILE uart_stdout;
void dump_packet(uint32_t addr, uint32_t len, uint8_t * packet)
{
uint16_t i,
j;
uint16_t sum = 0;
uint8_t clear = 0;
for (i = 0; i < len; i += 16) {
sum = 0;
for (j = 0; j < 16; j++) {
sum += packet[i + j];
}
if (!sum) {
clear = 1;
continue;
}
if (clear) {
printf("*\n");
clear = 0;
}
printf("%08lx:", addr + i);
for (j = 0; j < 16; j++) {
printf(" %02x", packet[i + j]);
}
printf(" |");
for (j = 0; j < 16; j++) {
if (packet[i + j] >= 33 && packet[i + j] <= 126)
printf("%c", packet[i + j]);
else
printf(".");
}
printf("|\n");
}
}

5
poc/avr_usbload/debug.h Normal file
View File

@@ -0,0 +1,5 @@
#include <stdlib.h>
#include <stdint.h>
void dump_packet(uint32_t addr,uint32_t len,uint8_t *packet);

28
poc/avr_usbload/fifo.c Normal file
View File

@@ -0,0 +1,28 @@
#include "fifo.h"
void fifo_init(fifo_t * f, uint8_t * buffer, const uint8_t size)
{
f->count = 0;
f->pread = f->pwrite = buffer;
f->read2end = f->write2end = f->size = size;
}
uint8_t fifo_put(fifo_t * f, const uint8_t data)
{
return _inline_fifo_put(f, data);
}
uint8_t fifo_get_wait(fifo_t * f)
{
while (!f->count);
return _inline_fifo_get(f);
}
int fifo_get_nowait(fifo_t * f)
{
if (!f->count)
return -1;
return (int) _inline_fifo_get(f);
}

69
poc/avr_usbload/fifo.h Normal file
View File

@@ -0,0 +1,69 @@
#ifndef _FIFO_H_
#define _FIFO_H_
#include <avr/io.h>
#include <avr/interrupt.h>
typedef struct {
uint8_t volatile count; // # Zeichen im Puffer
uint8_t size; // Puffer-Größe
uint8_t *pread; // Lesezeiger
uint8_t *pwrite; // Schreibzeiger
uint8_t read2end, write2end; // # Zeichen bis zum Überlauf Lese-/Schreibzeiger
} fifo_t;
extern void fifo_init(fifo_t *, uint8_t * buf, const uint8_t size);
extern uint8_t fifo_put(fifo_t *, const uint8_t data);
extern uint8_t fifo_get_wait(fifo_t *);
extern int fifo_get_nowait(fifo_t *);
static inline uint8_t _inline_fifo_put(fifo_t * f, const uint8_t data)
{
if (f->count >= f->size)
return 0;
uint8_t *pwrite = f->pwrite;
*(pwrite++) = data;
uint8_t write2end = f->write2end;
if (--write2end == 0) {
write2end = f->size;
pwrite -= write2end;
}
f->write2end = write2end;
f->pwrite = pwrite;
uint8_t sreg = SREG;
cli();
f->count++;
SREG = sreg;
return 1;
}
static inline uint8_t _inline_fifo_get(fifo_t * f)
{
uint8_t *pread = f->pread;
uint8_t data = *(pread++);
uint8_t read2end = f->read2end;
if (--read2end == 0) {
read2end = f->size;
pread -= read2end;
}
f->pread = pread;
f->read2end = read2end;
uint8_t sreg = SREG;
cli();
f->count--;
SREG = sreg;
return data;
}
#endif /* _FIFO_H_ */

213
poc/avr_usbload/main.c Normal file
View File

@@ -0,0 +1,213 @@
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h> /* for sei() */
#include <util/delay.h> /* for _delay_ms() */
#include <stdlib.h>
#include <avr/pgmspace.h> /* required by usbdrv.h */
#include "usbdrv.h"
#include "oddebug.h" /* This is also an example for using debug
* macros */
#include "requests.h" /* The custom request numbers we use */
#include "uart.h"
#include "sram.h"
#include "debug.h"
#include "crc.h"
#define REQ_IDLE 0
#define REQ_UPLOAD 1
#define RES_CRC 2
#define BUFFER_SIZE 256
extern FILE uart_stdout;
uint8_t read_buffer[BUFFER_SIZE];
uint32_t req_addr = 0;
uint32_t req_size;
uint8_t req_bank;
uint32_t req_bank_size;
uint8_t req_state = REQ_IDLE;
uint8_t rx_remaining = 0;
uint8_t tx_remaining = 0;
uint16_t sync_errors = 0;
uint8_t tx_buffer[32];
uint8_t data_buffer[4];
uint32_t addr;
void crc_check_memory(uint32_t top_addr)
{
uint16_t crc = 0;
uint32_t addr;
req_bank = 0;
for (addr = 0x000000; addr < top_addr; addr += BUFFER_SIZE) {
sram_read_buffer(addr, read_buffer, BUFFER_SIZE);
crc = do_crc_update(crc, read_buffer, BUFFER_SIZE);
if (addr && addr % 32768 == 0) {
printf("crc_check_memory: req_bank: 0x%x Addr: 0x%lx CRC: %x\n",
req_bank, addr, crc);
req_bank++;
crc = 0;
}
}
}
void crc_check_memory_
range(uint32_t start_addr, uint32_t size)
{
uint16_t crc = 0;
uint32_t addr;
req_bank = 0;
for (addr = start_addr; addr < start_addr + size; addr += BUFFER_SIZE) {
sram_read_buffer(addr, read_buffer, BUFFER_SIZE);
crc = do_crc_update(crc, read_buffer, BUFFER_SIZE);
}
tx_buffer[0] = crc & 0xff;
tx_buffer[1] = (crc >> 8) & 0xff;
printf("crc_check_memory_range: Addr: 0x%lx CRC: %x\n", addr, crc);
}
usbMsgLen_t usbFunctionSetup(uchar data[8])
{
usbRequest_t *rq = (void *) data;
uint8_t ret_len = 0;
if (rq->bRequest == USB_UPLOAD_INIT) {
req_bank = 0;
rx_remaining = 0;
req_bank_size = 1 << rq->wValue.word;
sync_errors = 0;
printf("USB_UPLOAD_INIT: bank size %li\n", req_bank_size);
} else if (rq->bRequest == USB_UPLOAD_ADDR) { /* echo -- used for
* reliability tests */
req_state = REQ_UPLOAD;
req_addr = rq->wValue.word;
req_addr = req_addr << 16;
req_addr = req_addr | rq->wIndex.word;
if (rx_remaining) {
sync_errors++;
printf
("USB_UPLOAD_ADDR: Out of sync Addr=0x%lx remain=%i packet=%i sync_error=%i\n",
req_addr, rx_remaining, rq->wLength.word, sync_errors);
ret_len = 0;
}
rx_remaining = rq->wLength.word;
ret_len = 0xff;
if (req_addr && req_addr % req_bank_size == 0) {
printf("USB_UPLOAD_ADDR: req_bank: 0x%x Addr: 0x%08lx \n",
req_bank, req_addr);
req_bank++;
}
ret_len = 0xff;
} else if (rq->bRequest == USB_DOWNLOAD_INIT) {
printf("USB_DOWNLOAD_INIT\n");
} else if (rq->bRequest == USB_DOWNLOAD_ADDR) {
printf("USB_DOWNLOAD_ADDR\n");
} else if (rq->bRequest == USB_CRC) {
req_addr = rq->wValue.word;
req_addr = req_addr << 16;
req_addr = req_addr | rq->wIndex.word;
printf("USB_CRC: Addr 0x%lx \n", req_addr);
cli();
crc_check_memory(req_addr);
sei();
} else if (rq->bRequest == USB_CRC_ADDR) {
req_addr = rq->wValue.word;
req_addr = req_addr << 16;
req_addr = req_addr | rq->wIndex.word;
printf("USB_CRC_ADDR: Addr: 0x%lx Size: %i\n", req_addr,
rq->wLength.word);
req_size = rq->wLength.word;
req_size = req_size << 2;
tx_remaining = 2;
printf("USB_CRC_ADDR: Addr: 0x%lx Size: %li\n", req_addr, req_size);
cli();
// crc_check_memory_range(req_addr,req_size);
sei();
ret_len = 2;
}
usbMsgPtr = data_buffer;
return ret_len; /* default for not implemented requests: return
* no data back to host */
}
uint8_t usbFunctionWrite(uint8_t * data, uint8_t len)
{
if (len > rx_remaining) {
printf("usbFunctionWrite more data than expected remain: %i len: %i\n",
rx_remaining, len);
len = rx_remaining;
}
if (req_state == REQ_UPLOAD) {
rx_remaining -= len;
#if 1
printf("usbFunctionWrite addr: 0x%08lx len: %i rx_remaining=%i\n",
req_addr, len, rx_remaining);
#endif
cli();
sram_copy(req_addr, data, len);
sei();
req_addr += len;
}
return len;
}
uint8_t usbFunctionRead(uint8_t * data, uint8_t len)
{
uint8_t i;
if (len > tx_remaining)
len = tx_remaining;
tx_remaining -= len;
#if 1
printf("usbFunctionRead len=%i tx_remaining=%i \n", len, tx_remaining);
#endif
for (i = 0; i < len; i++) {
*data = tx_buffer[len];
data++;
}
return len;
}
/*
* -------------------------------------------------------------------------
*/
int main(void)
{
uint8_t i;
wdt_enable(WDTO_1S);
uart_init();
stdout = &uart_stdout;
sram_init();
printf("SRAM Init\n");
spi_init();
printf("SPI Init\n");
usbInit();
printf("USB Init\n");
usbDeviceDisconnect(); /* enforce re-enumeration, do this while
* interrupts are disabled! */
printf("USB disconnect\n");
i = 10;
while (--i) { /* fake USB disconnect for > 250 ms */
wdt_reset();
_delay_ms(1);
}
usbDeviceConnect();
printf("USB connect\n");
sei();
printf("USB poll\n");
for (;;) { /* main event loop */
wdt_reset();
usbPoll();
}
return 0;
}
/*
* -------------------------------------------------------------------------
*/

View File

@@ -0,0 +1,26 @@
/* Name: requests.h
* Project: custom-class, a basic USB example
* Author: Christian Starkjohann
* Creation Date: 2008-04-09
* Tabsize: 4
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id: requests.h 692 2008-11-07 15:07:40Z cs $
*/
/* This header is shared between the firmware and the host software. It
* defines the USB request numbers (and optionally data types) used to
* communicate between the host and the device.
*/
#ifndef __REQUESTS_H_INCLUDED__
#define __REQUESTS_H_INCLUDED__
#define USB_UPLOAD_INIT 0
#define USB_UPLOAD_ADDR 1
#define USB_DOWNLOAD_INIT 2
#define USB_DOWNLOAD_ADDR 3
#define USB_CRC 4
#define USB_CRC_ADDR 5
#endif /* __REQUESTS_H_INCLUDED__ */

172
poc/avr_usbload/sram.c Normal file
View File

@@ -0,0 +1,172 @@
#include <stdlib.h>
#include <stdint.h>
#include <avr/io.h>
#include "sram.h"
#include "uart.h"
#include "debug.h"
void spi_init(void)
{
/*
* Set MOSI and SCK output, all others input
*/
SPI_DIR |= ((1 << S_MOSI) | (1 << S_SCK) | (1 << S_LATCH));
SPI_DIR &= ~(1 << S_MISO);
SPI_PORT |= (1 << S_MISO);
/*
* Enable SPI, Master
*/
SPCR = ((1 << SPE) | (1 << MSTR));
}
void spi_master_transmit(unsigned char cData)
{
/*
* Start transmission
*/
SPDR = cData;
/*
* Wait for transmission complete
*/
while (!(SPSR & (1 << SPIF)));
}
void sram_set_addr(uint32_t addr)
{
spi_master_transmit((uint8_t) (addr >> 16));
spi_master_transmit((uint8_t) (addr >> 8));
spi_master_transmit((uint8_t) (addr >> 0));
LATCH_PORT |= (1 << S_LATCH);
LATCH_PORT &= ~(1 << S_LATCH);
}
uint8_t sram_read(uint32_t addr)
{
uint8_t byte;
RAM_DIR = 0x00;
RAM_PORT = 0xff;
CTRL_PORT |= (1 << R_RD);
CTRL_PORT |= (1 << R_WR);
spi_master_transmit((uint8_t) (addr >> 16));
spi_master_transmit((uint8_t) (addr >> 8));
spi_master_transmit((uint8_t) (addr >> 0));
LATCH_PORT |= (1 << S_LATCH);
LATCH_PORT &= ~(1 << S_LATCH);
CTRL_PORT &= ~(1 << R_RD);
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
asm volatile ("nop");
byte = RAM_REG;
CTRL_PORT |= (1 << R_RD);
RAM_DIR = 0x00;
RAM_PORT = 0x00;
return byte;
}
void sram_write(uint32_t addr, uint8_t data)
{
RAM_DIR = 0xff;
CTRL_PORT |= (1 << R_RD);
CTRL_PORT |= (1 << R_WR);
spi_master_transmit((uint8_t) (addr >> 16));
spi_master_transmit((uint8_t) (addr >> 8));
spi_master_transmit((uint8_t) (addr >> 0));
LATCH_PORT |= (1 << S_LATCH);
LATCH_PORT &= ~(1 << S_LATCH);
CTRL_PORT &= ~(1 << R_WR);
RAM_PORT = data;
CTRL_PORT |= (1 << R_WR);
RAM_DIR = 0x00;
RAM_PORT = 0x00;
}
void sram_init(void)
{
RAM_DIR = 0x00;
RAM_PORT = 0x00;
CTRL_DIR |= ((1 << R_WR) | (1 << R_RD));
CTRL_PORT |= (1 << R_RD);
CTRL_PORT |= (1 << R_WR);
LED_PORT |= (1 << D_LED0);
}
void sram_snes_mode01(void)
{
CTRL_PORT |= (1 << R_WR);
CTRL_PORT &= ~(1 << R_RD);
}
void sram_snes_mode02(void)
{
CTRL_DIR |= (1 << R_WR);
CTRL_PORT |= (1 << R_WR);
// CTRL_PORT &= ~(1<<R_RD);
CTRL_DIR &= ~(1 << R_RD);
CTRL_PORT &= ~(1 << R_RD);
}
void sram_clear(uint32_t addr, uint32_t len)
{
uint32_t i;
for (i = addr; i < (addr + len); i++) {
if (0 == i % 0xfff)
printf("sram_clear %lx\n\r", i);
sram_write(i, 0x00);
}
}
void sram_copy(uint32_t addr, uint8_t * src, uint32_t len)
{
uint32_t i;
uint8_t *ptr = src;
for (i = addr; i < (addr + len); i++)
sram_write(i, *ptr++);
}
void sram_read_buffer(uint32_t addr, uint8_t * dst, uint32_t len)
{
uint32_t i;
uint8_t *ptr = dst;
for (i = addr; i < (addr + len); i++) {
*ptr = sram_read(i);
ptr++;
}
}
uint8_t sram_check(uint8_t * buffer, uint32_t len)
{
uint16_t cnt;
for (cnt = 0; cnt < len; cnt++)
if (buffer[cnt])
return 1;
return 0;
}

51
poc/avr_usbload/sram.h Normal file
View File

@@ -0,0 +1,51 @@
#include <stdlib.h>
#include <stdint.h>
#include <avr/io.h>
//SREG defines
#define S_MOSI PB5
#define S_MISO PB6
#define S_SCK PB7
#define S_LATCH PB4
//DEBUG defines
#define D_LED0 PD6
//SRAM defines
#define R_WR PB1
#define R_RD PB0
#define RAM_PORT PORTA
#define RAM_DIR DDRA
#define RAM_REG PINA
#define CTRL_PORT PORTB
#define CTRL_DIR DDRB
#define LATCH_PORT PORTB
#define LATCH_DIR DDRB
#define SPI_PORT PORTB
#define SPI_DIR DDRB
#define LED_PORT PORTD
#define LED_DIR DDRD
#define ROMSIZE 4
#define BLOCKS (ROMSIZE << 8)
#define MEMSIZE 0x80000
void spi_init(void);
void spi_master_transmit(unsigned char cData);
void sram_set_addr(uint32_t addr);
uint8_t sram_read(uint32_t addr);
void sram_write(uint32_t addr, uint8_t data);
void sram_init(void);
void sram_snes_mode01(void);
void sram_snes_mode02(void);
void sram_clear(uint32_t addr, uint32_t len);
void sram_copy(uint32_t addr,uint8_t *src, uint32_t len);
void sram_read_buffer(uint32_t addr,uint8_t *dst, uint32_t len);
uint8_t sram_check(uint8_t *buffer, uint32_t len);

77
poc/avr_usbload/uart.c Normal file
View File

@@ -0,0 +1,77 @@
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdio.h>
#include "uart.h"
#include "fifo.h"
volatile struct {
uint8_t tmr_int:1;
uint8_t adc_int:1;
uint8_t rx_int:1;
} intflags;
/*
* * Last character read from the UART.
*
*/
volatile char rxbuff;
FILE uart_stdout = FDEV_SETUP_STREAM(uart_stream, NULL, _FDEV_SETUP_WRITE);
void uart_init(void)
{
UCSRA = _BV(U2X); /* improves baud rate error @ F_CPU = 1 MHz */
UCSRB = _BV(TXEN) | _BV(RXEN) | _BV(RXCIE); /* tx/rx enable, rx complete
* intr */
UBRRL = (F_CPU / (8 * 115200UL)) - 1; /* 9600 Bd */
}
ISR(USART_RXC_vect)
{
uint8_t c;
c = UDR;
if (bit_is_clear(UCSRA, FE)) {
rxbuff = c;
intflags.rx_int = 1;
}
}
void uart_putc(uint8_t c)
{
loop_until_bit_is_set(UCSRA, UDRE);
UDR = c;
}
void uart_puts(const char *s)
{
do {
uart_putc(*s);
}
while (*s++);
}
void uart_puts_P(PGM_P s)
{
while (1) {
unsigned char c = pgm_read_byte(s);
s++;
if ('\0' == c)
break;
uart_putc(c);
}
}
static int uart_stream(char c, FILE * stream)
{
if (c == '\n')
uart_putc('\r');
loop_until_bit_is_set(UCSRA, UDRE);
UDR = c;
return 0;
}

18
poc/avr_usbload/uart.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef _UART_H_
#define _UART_H_
#define CR "\r\n"
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdio.h>
void uart_init(void);
void uart_putc(const uint8_t);
void uart_puts(const char *s);
void uart_puts_P(PGM_P s);
static int uart_stream(char c, FILE *stream);
#endif /* _UART_H_ */

351
poc/avr_usbload/usbconfig.h Normal file
View File

@@ -0,0 +1,351 @@
/* Name: usbconfig.h
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Christian Starkjohann
* Creation Date: 2005-04-01
* Tabsize: 4
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id: usbconfig-prototype.h 740 2009-04-13 18:23:31Z cs $
*/
#ifndef __usbconfig_h_included__
#define __usbconfig_h_included__
/*
General Description:
This file is an example configuration (with inline documentation) for the USB
driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
wire the lines to any other port, as long as D+ is also wired to INT0 (or any
other hardware interrupt, as long as it is the highest level interrupt, see
section at the end of this file).
*/
/* ---------------------------- Hardware Config ---------------------------- */
#define USB_CFG_IOPORTNAME D
/* This is the port where the USB bus is connected. When you configure it to
* "B", the registers PORTB, PINB and DDRB will be used.
*/
#define USB_CFG_DMINUS_BIT 4
/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected.
* This may be any bit in the port.
*/
#define USB_CFG_DPLUS_BIT 2
/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected.
* This may be any bit in the port. Please note that D+ must also be connected
* to interrupt pin INT0! [You can also use other interrupts, see section
* "Optional MCU Description" below, or you can connect D- to the interrupt, as
* it is required if you use the USB_COUNT_SOF feature. If you use D- for the
* interrupt, the USB interrupt will also be triggered at Start-Of-Frame
* markers every millisecond.]
*/
#define USB_CFG_CLOCK_KHZ (F_CPU/1000)
/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000,
* 16500 and 20000. The 12.8 MHz and 16.5 MHz versions of the code require no
* crystal, they tolerate +/- 1% deviation from the nominal frequency. All
* other rates require a precision of 2000 ppm and thus a crystal!
* Default if not specified: 12 MHz
*/
#define USB_CFG_CHECK_CRC 0
/* Define this to 1 if you want that the driver checks integrity of incoming
* data packets (CRC checks). CRC checks cost quite a bit of code size and are
* currently only available for 18 MHz crystal clock. You must choose
* USB_CFG_CLOCK_KHZ = 18000 if you enable this option.
*/
/* ----------------------- Optional Hardware Config ------------------------ */
#define USB_CFG_PULLUP_IOPORTNAME D
/* If you connect the 1.5k pullup resistor from D- to a port pin instead of
* V+, you can connect and disconnect the device from firmware by calling
* the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h).
* This constant defines the port on which the pullup resistor is connected.
*/
#define USB_CFG_PULLUP_BIT 6
/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined
* above) where the 1.5k pullup resistor is connected. See description
* above for details.
*/
/* --------------------------- Functional Range ---------------------------- */
#define USB_CFG_HAVE_INTRIN_ENDPOINT 0
/* Define this to 1 if you want to compile a version with two endpoints: The
* default control endpoint 0 and an interrupt-in endpoint (any other endpoint
* number).
*/
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
/* Define this to 1 if you want to compile a version with three endpoints: The
* default control endpoint 0, an interrupt-in endpoint 3 (or the number
* configured below) and a catch-all default interrupt-in endpoint as above.
* You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
*/
#define USB_CFG_EP3_NUMBER 3
/* If the so-called endpoint 3 is used, it can now be configured to any other
* endpoint number (except 0) with this macro. Default if undefined is 3.
*/
/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
/* The above macro defines the startup condition for data toggling on the
* interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1.
* Since the token is toggled BEFORE sending any data, the first packet is
* sent with the oposite value of this configuration!
*/
#define USB_CFG_IMPLEMENT_HALT 0
/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature
* for endpoint 1 (interrupt endpoint). Although you may not need this feature,
* it is required by the standard. We have made it a config option because it
* bloats the code considerably.
*/
#define USB_CFG_SUPPRESS_INTR_CODE 1
/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
* want to send any data over them. If this macro is defined to 1, functions
* usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
* you need the interrupt-in endpoints in order to comply to an interface
* (e.g. HID), but never want to send any data. This option saves a couple
* of bytes in flash memory and the transmit buffers in RAM.
*/
#define USB_CFG_INTR_POLL_INTERVAL 10
/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
* interval. The value is in milliseconds and must not be less than 10 ms for
* low speed devices.
*/
#define USB_CFG_IS_SELF_POWERED 0
/* Define this to 1 if the device has its own power supply. Set it to 0 if the
* device is powered from the USB bus.
*/
#define USB_CFG_MAX_BUS_POWER 40
/* Set this variable to the maximum USB bus power consumption of your device.
* The value is in milliamperes. [It will be divided by two since USB
* communicates power requirements in units of 2 mA.]
*/
#define USB_CFG_IMPLEMENT_FN_WRITE 1
/* Set this to 1 if you want usbFunctionWrite() to be called for control-out
* transfers. Set it to 0 if you don't need it and want to save a couple of
* bytes.
*/
#define USB_CFG_IMPLEMENT_FN_READ 0
/* Set this to 1 if you need to send control replies which are generated
* "on the fly" when usbFunctionRead() is called. If you only want to send
* data from a static buffer, set it to 0 and return the data from
* usbFunctionSetup(). This saves a couple of bytes.
*/
#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0
/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints.
* You must implement the function usbFunctionWriteOut() which receives all
* interrupt/bulk data sent to any endpoint other than 0. The endpoint number
* can be found in 'usbRxToken'.
*/
#define USB_CFG_HAVE_FLOWCONTROL 0
/* Define this to 1 if you want flowcontrol over USB data. See the definition
* of the macros usbDisableAllRequests() and usbEnableAllRequests() in
* usbdrv.h.
*/
#define USB_CFG_LONG_TRANSFERS 0
/* Define this to 1 if you want to send/receive blocks of more than 254 bytes
* in a single control-in or control-out transfer. Note that the capability
* for long transfers increases the driver size.
*/
/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */
/* This macro is a hook if you want to do unconventional things. If it is
* defined, it's inserted at the beginning of received message processing.
* If you eat the received message and don't want default processing to
* proceed, do a return after doing your things. One possible application
* (besides debugging) is to flash a status LED on each packet.
*/
/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */
/* This macro is a hook if you need to know when an USB RESET occurs. It has
* one parameter which distinguishes between the start of RESET state and its
* end.
*/
/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */
/* This macro (if defined) is executed when a USB SET_ADDRESS request was
* received.
*/
#define USB_COUNT_SOF 0
/* define this macro to 1 if you need the global variable "usbSofCount" which
* counts SOF packets. This feature requires that the hardware interrupt is
* connected to D- instead of D+.
*/
/* #ifdef __ASSEMBLER__
* macro myAssemblerMacro
* in YL, TCNT0
* sts timer0Snapshot, YL
* endm
* #endif
* #define USB_SOF_HOOK myAssemblerMacro
* This macro (if defined) is executed in the assembler module when a
* Start Of Frame condition is detected. It is recommended to define it to
* the name of an assembler macro which is defined here as well so that more
* than one assembler instruction can be used. The macro may use the register
* YL and modify SREG. If it lasts longer than a couple of cycles, USB messages
* immediately after an SOF pulse may be lost and must be retried by the host.
* What can you do with this hook? Since the SOF signal occurs exactly every
* 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in
* designs running on the internal RC oscillator.
* Please note that Start Of Frame detection works only if D- is wired to the
* interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES!
*/
#define USB_CFG_CHECK_DATA_TOGGLING 0
/* define this macro to 1 if you want to filter out duplicate data packets
* sent by the host. Duplicates occur only as a consequence of communication
* errors, when the host does not receive an ACK. Please note that you need to
* implement the filtering yourself in usbFunctionWriteOut() and
* usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable
* for each control- and out-endpoint to check for duplicate packets.
*/
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0
/* define this macro to 1 if you want the function usbMeasureFrameLength()
* compiled in. This function can be used to calibrate the AVR's RC oscillator.
*/
/* -------------------------- Device Description --------------------------- */
#define USB_CFG_VENDOR_ID 0xc0, 0x16
/* USB vendor ID for the device, low byte first. If you have registered your
* own Vendor ID, define it here. Otherwise you use one of obdev's free shared
* VID/PID pairs. Be sure to read USBID-License.txt for rules!
*/
#define USB_CFG_DEVICE_ID 0xdc, 0x05
/* This is the ID of the product, low byte first. It is interpreted in the
* scope of the vendor ID. If you have registered your own VID with usb.org
* or if you have licensed a PID from somebody else, define it here. Otherwise
* you use obdev's free shared VID/PID pair. Be sure to read the rules in
* USBID-License.txt!
*/
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
/* Version number of the device: Minor number first, then major number.
*/
#define USB_CFG_VENDOR_NAME 'o', 'p', 't', 'i', 'x', 'x', '.', 'o', 'r', 'g'
#define USB_CFG_VENDOR_NAME_LEN 10
/* These two values define the vendor name returned by the USB device. The name
* must be given as a list of characters under single quotes. The characters
* are interpreted as Unicode (UTF-16) entities.
* If you don't want a vendor name string, undefine these macros.
* ALWAYS define a vendor name containing your Internet domain name if you use
* obdev's free shared VID/PID pair. See the file USBID-License.txt for
* details.
*/
#define USB_CFG_DEVICE_NAME 'S', 'N', 'E', 'S', 'R', 'A', 'M'
#define USB_CFG_DEVICE_NAME_LEN 7
/* Same as above for the device name. If you don't want a device name, undefine
* the macros. See the file USBID-License.txt before you assign a name if you
* use a shared VID/PID.
*/
/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */
/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */
/* Same as above for the serial number. If you don't want a serial number,
* undefine the macros.
* It may be useful to provide the serial number through other means than at
* compile time. See the section about descriptor properties below for how
* to fine tune control over USB descriptors such as the string descriptor
* for the serial number.
*/
#define USB_CFG_DEVICE_CLASS 0xff /* set to 0 if deferred to interface */
#define USB_CFG_DEVICE_SUBCLASS 0
/* See USB specification if you want to conform to an existing device class.
* Class 0xff is "vendor specific".
*/
#define USB_CFG_INTERFACE_CLASS 0 /* define class here if not at device level */
#define USB_CFG_INTERFACE_SUBCLASS 0
#define USB_CFG_INTERFACE_PROTOCOL 0
/* See USB specification if you want to conform to an existing device class or
* protocol. The following classes must be set at interface level:
* HID class is 3, no subclass and protocol required (but may be useful!)
* CDC class is 2, use subclass 2 and protocol 1 for ACM
*/
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0
/* Define this to the length of the HID report descriptor, if you implement
* an HID device. Otherwise don't define it or define it to 0.
* If you use this define, you must add a PROGMEM character array named
* "usbHidReportDescriptor" to your code which contains the report descriptor.
* Don't forget to keep the array and this define in sync!
*/
/* #define USB_PUBLIC static */
/* Use the define above if you #include usbdrv.c instead of linking against it.
* This technique saves a couple of bytes in flash memory.
*/
/* ------------------- Fine Control over USB Descriptors ------------------- */
/* If you don't want to use the driver's default USB descriptors, you can
* provide our own. These can be provided as (1) fixed length static data in
* flash memory, (2) fixed length static data in RAM or (3) dynamically at
* runtime in the function usbFunctionDescriptor(). See usbdrv.h for more
* information about this function.
* Descriptor handling is configured through the descriptor's properties. If
* no properties are defined or if they are 0, the default descriptor is used.
* Possible properties are:
* + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched
* at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is
* used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if
* you want RAM pointers.
* + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found
* in static memory is in RAM, not in flash memory.
* + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash),
* the driver must know the descriptor's length. The descriptor itself is
* found at the address of a well known identifier (see below).
* List of static descriptor names (must be declared PROGMEM if in flash):
* char usbDescriptorDevice[];
* char usbDescriptorConfiguration[];
* char usbDescriptorHidReport[];
* char usbDescriptorString0[];
* int usbDescriptorStringVendor[];
* int usbDescriptorStringDevice[];
* int usbDescriptorStringSerialNumber[];
* Other descriptors can't be provided statically, they must be provided
* dynamically at runtime.
*
* Descriptor properties are or-ed or added together, e.g.:
* #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18))
*
* The following descriptors are defined:
* USB_CFG_DESCR_PROPS_DEVICE
* USB_CFG_DESCR_PROPS_CONFIGURATION
* USB_CFG_DESCR_PROPS_STRINGS
* USB_CFG_DESCR_PROPS_STRING_0
* USB_CFG_DESCR_PROPS_STRING_VENDOR
* USB_CFG_DESCR_PROPS_STRING_PRODUCT
* USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER
* USB_CFG_DESCR_PROPS_HID
* USB_CFG_DESCR_PROPS_HID_REPORT
* USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver)
*
* Note about string descriptors: String descriptors are not just strings, they
* are Unicode strings prefixed with a 2 byte header. Example:
* int serialNumberDescriptor[] = {
* USB_STRING_DESCRIPTOR_HEADER(6),
* 'S', 'e', 'r', 'i', 'a', 'l'
* };
*/
#define USB_CFG_DESCR_PROPS_DEVICE 0
#define USB_CFG_DESCR_PROPS_CONFIGURATION 0
#define USB_CFG_DESCR_PROPS_STRINGS 0
#define USB_CFG_DESCR_PROPS_STRING_0 0
#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0
#define USB_CFG_DESCR_PROPS_HID 0
#define USB_CFG_DESCR_PROPS_HID_REPORT 0
#define USB_CFG_DESCR_PROPS_UNKNOWN 0
/* ----------------------- Optional MCU Description ------------------------ */
/* The following configurations have working defaults in usbdrv.h. You
* usually don't need to set them explicitly. Only if you want to run
* the driver on a device which is not yet supported or with a compiler
* which is not fully supported (such as IAR C) or if you use a differnt
* interrupt than INT0, you may have to define some of these.
*/
/* #define USB_INTR_CFG MCUCR */
/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */
/* #define USB_INTR_CFG_CLR 0 */
/* #define USB_INTR_ENABLE GIMSK */
/* #define USB_INTR_ENABLE_BIT INT0 */
/* #define USB_INTR_PENDING GIFR */
/* #define USB_INTR_PENDING_BIT INTF0 */
/* #define USB_INTR_VECTOR SIG_INTERRUPT0 */
#endif /* __usbconfig_h_included__ */

View File

@@ -268,3 +268,10 @@ Scroll down to the bottom to see the most recent changes.
- Integrated a module with CRC checks at 18 MHz by Lukas Schrittwieser.
* Release 2009-03-23
- Hid-mouse example used settings from hid-data example, fixed that.
- Renamed project to V-USB due to a trademark issue with Atmel(r).
- Changed CommercialLicense.txt and USBID-License.txt to make the
background of USB ID registration clearer.
* Release 2009-04-15

View File

@@ -1,5 +1,5 @@
AVR-USB Driver Software License Agreement
Version 2008-10-07
V-USB Driver Software License Agreement
Version 2009-04-14
THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN
ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING
@@ -13,8 +13,8 @@ Grosse Schiffgasse 1A/7, 1020 Wien, AUSTRIA.
1.2 "You" shall mean the Licensee.
1.3 "AVR-USB" shall mean all files included in the package distributed under
the name "avrusb" by OBJECTIVE DEVELOPMENT (http://www.obdev.at/avrusb/)
1.3 "V-USB" shall mean all files included in the package distributed under
the name "vusb" by OBJECTIVE DEVELOPMENT (http://www.obdev.at/vusb/)
unless otherwise noted. This includes the firmware-only USB device
implementation for Atmel AVR microcontrollers, some simple device examples
and host side software examples and libraries.
@@ -23,21 +23,22 @@ and host side software examples and libraries.
2 LICENSE GRANTS
2.1 Source Code. OBJECTIVE DEVELOPMENT shall furnish you with the source
code of AVR-USB.
code of V-USB.
2.2 Distribution and Use. OBJECTIVE DEVELOPMENT grants you the
non-exclusive right to use, copy and distribute AVR-USB with your hardware
non-exclusive right to use, copy and distribute V-USB with your hardware
product(s), restricted by the limitations in section 3 below.
2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify
the source code and your copy of AVR-USB according to your needs.
the source code and your copy of V-USB according to your needs.
2.4 USB IDs. OBJECTIVE DEVELOPMENT grants you the exclusive rights to use
USB Product ID(s) sent to you in e-mail after receiving your payment in
conjunction with USB Vendor ID 5824. OBJECTIVE DEVELOPMENT has acquired an
exclusive license for this pair of USB identifiers from Wouter van Ooijen
(www.voti.nl), who has licensed the VID from the USB Implementers Forum,
Inc. (www.usb.org).
2.4 USB IDs. OBJECTIVE DEVELOPMENT furnishes you with one or two USB Product
ID(s), sent to you in e-mail. These Product IDs are reserved exclusively for
you. They have been obtained from Wouter van Ooijen (www.voti.nl), who has
reserved the Vendor ID 5824 (decimal) at the USB Implementers Forum, Inc.
(www.usb.org). This mechanism ensures that there are no Product ID conflicts,
but you cannot become USB certified (enter into the USB-IF Trademark License
Agreement) as you would need your own Vendor ID for that.
3 LICENSE RESTRICTIONS
@@ -46,21 +47,21 @@ Inc. (www.usb.org).
applicable. Which one is determined by the amount you pay to OBJECTIVE
DEVELOPMENT, see section 4 ("Payment") below.
Hobby License: You may use AVR-USB according to section 2 above in no more
Hobby License: You may use V-USB according to section 2 above in no more
than 5 hardware units. These units must not be sold for profit.
Entry Level License: You may use AVR-USB according to section 2 above in no
Entry Level License: You may use V-USB according to section 2 above in no
more than 150 hardware units.
Professional License: You may use AVR-USB according to section 2 above in
Professional License: You may use V-USB according to section 2 above in
any number of hardware units, except for large scale production ("unlimited
fair use"). Quantities below 10,000 units are not considered large scale
production. If your reach quantities which are obviously large scale
production, you must pay a license fee of 0.10 EUR per unit for all units
above 10,000.
3.2 Rental. You may not rent, lease, or lend AVR-USB or otherwise encumber
any copy of AVR-USB, or any of the rights granted herein.
3.2 Rental. You may not rent, lease, or lend V-USB or otherwise encumber
any copy of V-USB, or any of the rights granted herein.
3.3 Transfer. You may not transfer your rights under this Agreement to
another party without OBJECTIVE DEVELOPMENT's prior written consent. If
@@ -78,7 +79,7 @@ non-exclusive.
by third parties. In particular, you are not allowed to use the USB logo or
other trademarks owned by the USB Implementers Forum, Inc. without their
consent. Since such consent depends on USB certification, it should be
noted that AVR-USB will not pass certification because it does not
noted that V-USB will not pass certification because it does not
implement checksum verification and the microcontroller ports do not meet
the electrical specifications.
@@ -88,15 +89,15 @@ the electrical specifications.
The payment amount depends on the variation of this agreement (according to
section 3.1) into which you want to enter. Concrete prices are listed on
OBJECTIVE DEVELOPMENT's web site, usually at
http://www.obdev.at/avrusb/license.html. You agree to pay the amount listed
http://www.obdev.at/vusb/license.html. You agree to pay the amount listed
there to OBJECTIVE DEVELOPMENT or OBJECTIVE DEVELOPMENT's payment processor
or reseller.
5 COPYRIGHT AND OWNERSHIP
AVR-USB is protected by copyright laws and international copyright
treaties, as well as other intellectual property laws and treaties. AVR-USB
V-USB is protected by copyright laws and international copyright
treaties, as well as other intellectual property laws and treaties. V-USB
is licensed, not sold.
@@ -112,12 +113,12 @@ and limitation of liability shall survive termination of this agreement.
7 DISCLAIMER OF WARRANTY AND LIABILITY
LIMITED WARRANTY. AVR-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
LIMITED WARRANTY. V-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OBJECTIVE
DEVELOPMENT AND ITS SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES, EITHER
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND
NON-INFRINGEMENT, WITH REGARD TO AVR-USB, AND THE PROVISION OF OR FAILURE
NON-INFRINGEMENT, WITH REGARD TO V-USB, AND THE PROVISION OF OR FAILURE
TO PROVIDE SUPPORT SERVICES. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL
RIGHTS. YOU MAY HAVE OTHERS, WHICH VARY FROM STATE/JURISDICTION TO
STATE/JURISDICTION.
@@ -127,11 +128,11 @@ IN NO EVENT SHALL OBJECTIVE DEVELOPMENT OR ITS SUPPLIERS BE LIABLE FOR ANY
SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER
(INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY
LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE AVR-USB OR THE
LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE V-USB OR THE
PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF OBJECTIVE
DEVELOPMENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY
CASE, OBJECTIVE DEVELOPMENT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS
AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR AVR-USB.
AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR V-USB.
8 MISCELLANEOUS TERMS

View File

@@ -1,18 +1,18 @@
OBJECTIVE DEVELOPMENT GmbH's AVR-USB driver software is distributed under the
OBJECTIVE DEVELOPMENT GmbH's V-USB driver software is distributed under the
terms and conditions of the GNU GPL version 2 or the GNU GPL version 3. It is
your choice whether you apply the terms of version 2 or version 3. The full
text of GPLv2 is included below. In addition to the requirements in the GPL,
we STRONGLY ENCOURAGE you to do the following:
(1) Publish your entire project on a web site and drop us a note with the URL.
Use the form at http://www.obdev.at/avrusb/feedback.html for your submission.
Use the form at http://www.obdev.at/vusb/feedback.html for your submission.
(2) Adhere to minimum publication standards. Please include AT LEAST:
- a circuit diagram in PDF, PNG or GIF format
- full source code for the host software
- a Readme.txt file in ASCII format which describes the purpose of the
project and what can be found in which directories and which files
- a reference to http://www.obdev.at/avrusb/
- a reference to http://www.obdev.at/vusb/
(3) If you improve the driver firmware itself, please give us a free license
to your modifications for our commercial license offerings.

View File

@@ -1,6 +1,6 @@
This is the Readme file to Objective Development's firmware-only USB driver
for Atmel AVR microcontrollers. For more information please visit
http://www.obdev.at/avrusb/
http://www.obdev.at/vusb/
This directory contains the USB firmware only. Copy it as-is to your own
project and add all .c and .S files to your project (these files are marked
@@ -53,7 +53,7 @@ actual clock rate must be configured in usbdrv.h unless you use the default
12 MHz.
12 MHz Clock
This is the traditional clock rate of AVR-USB because it's the lowest clock
This is the traditional clock rate of V-USB because it's the lowest clock
rate where the timing constraints of the USB spec can be met.
15 MHz Clock
@@ -78,7 +78,7 @@ oscillator can reach 16.5 MHz with the RC oscillator. This includes the very
popular ATTiny25, ATTiny45, ATTiny85 series as well as the ATTiny26. Almost
all AVRs can reach 12.8 MHz, although this is outside the specified range.
See the EasyLogger example at http://www.obdev.at/avrusb/easylogger.html for
See the EasyLogger example at http://www.obdev.at/vusb/easylogger.html for
code which calibrates the RC oscillator based on the USB frame clock.
18 MHz Clock
@@ -108,14 +108,14 @@ and hobbyists, we provide some VID/PID pairs for free. See the file
USBID-License.txt for details.
Objective Development also has some license offerings which include product
IDs. See http://www.obdev.at/avrusb/ for details.
IDs. See http://www.obdev.at/vusb/ for details.
DEVELOPMENT SYSTEM
==================
This driver has been developed and optimized for the GNU compiler version 3
(gcc 3). It does work well with gcc 4, but with bigger code size. We recommend
that you use the GNU compiler suite because it is freely available. AVR-USB
that you use the GNU compiler suite because it is freely available. V-USB
has also been ported to the IAR compiler and assembler. It has been tested
with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the "small" and "tiny"
memory model. Not every release is tested with IAR CC and the driver may
@@ -123,8 +123,8 @@ therefore fail to compile with IAR. Please note that gcc is more efficient for
usbdrv.c because this module has been deliberately optimized for gcc.
USING AVR-USB FOR FREE
======================
USING V-USB FOR FREE
====================
The AVR firmware driver is published under the GNU General Public License
Version 2 (GPL2) and the GNU General Public License Version 3 (GPL3). It is
your choice whether you apply the terms of version 2 or version 3.
@@ -133,26 +133,26 @@ If you decide for the free GPL2 or GPL3, we STRONGLY ENCOURAGE you to do the
following things IN ADDITION to the obligations from the GPL:
(1) Publish your entire project on a web site and drop us a note with the URL.
Use the form at http://www.obdev.at/avrusb/feedback.html for your submission.
Use the form at http://www.obdev.at/vusb/feedback.html for your submission.
If you don't have a web site, you can publish the project in obdev's
documentation wiki at
http://www.obdev.at/goto.php?t=avrusb-wiki&p=hosted-projects.
http://www.obdev.at/goto.php?t=vusb-wiki&p=hosted-projects.
(2) Adhere to minimum publication standards. Please include AT LEAST:
- a circuit diagram in PDF, PNG or GIF format
- full source code for the host software
- a Readme.txt file in ASCII format which describes the purpose of the
project and what can be found in which directories and which files
- a reference to http://www.obdev.at/avrusb/
- a reference to http://www.obdev.at/vusb/
(3) If you improve the driver firmware itself, please give us a free license
to your modifications for our commercial license offerings.
COMMERCIAL LICENSES FOR AVR-USB
===============================
COMMERCIAL LICENSES FOR V-USB
=============================
If you don't want to publish your source code under the terms of the GPL,
you can simply pay money for AVR-USB. As an additional benefit you get
USB PIDs for free, licensed exclusively to you. See the file
you can simply pay money for V-USB. As an additional benefit you get
USB PIDs for free, reserved exclusively to you. See the file
"CommercialLicense.txt" for details.

View File

@@ -1,10 +1,17 @@
Royalty-Free Non-Exclusive License USB Product-ID
Royalty-Free Non-Exclusive Use of USB Product-IDs
=================================================
Version 2008-04-07
Version 2009-04-13
Strictly speaking, this is not a license. You can't give a license to use
a simple number (such as e.g. 1500) for any purpose. This is a set of rules
which should make it possible to build USB devices without the requirement
for individual USB IDs. If you break one of the rules, you will run into
technical problems sooner or later, but you don't risk legal trouble.
OBJECTIVE DEVELOPMENT Software GmbH hereby grants you the non-exclusive
right to use three USB.org vendor-ID (VID) / product-ID (PID) pairs with
right to use four USB.org vendor-ID (VID) / product-ID (PID) pairs with
products based on Objective Development's firmware-only USB driver for
Atmel AVR microcontrollers:
@@ -27,10 +34,11 @@ used by many companies and individuals for different products. To avoid
conflicts, your device and host driver software MUST adhere to the rules
outlined below.
OBJECTIVE DEVELOPMENT Software GmbH has licensed these VID/PID pairs from
Wouter van Ooijen (see www.voti.nl), who has licensed the VID from the USB
Implementers Forum, Inc. (see www.usb.org). The VID is registered for the
company name "Van Ooijen Technische Informatica".
OBJECTIVE DEVELOPMENT Software GmbH has obtained these VID/PID pairs from
Wouter van Ooijen (see www.voti.nl) for exclusive disposition. Wouter van
Ooijen has obtained the VID from the USB Implementers Forum, Inc.
(see www.usb.org). The VID is registered for the company name
"Van Ooijen Technische Informatica".
RULES AND RESTRICTIONS
@@ -44,7 +52,7 @@ MUST be available at least in USB language 0x0409 (English/US).
domain name (e.g. "mycompany.com") registered and owned by you, or an
e-mail address under your control (e.g. "myname@gmx.net"). You can embed
the domain name or e-mail address in any string you like, e.g. "Objective
Development http://www.obdev.at/avrusb/".
Development http://www.obdev.at/vusb/".
(3) You are responsible for retaining ownership of the domain or e-mail
address for as long as any of your products are in use.
@@ -142,5 +150,5 @@ violates the USB specification. If you do it, you do it at your own risk.
To avoid possible incompatibilities, we highly recommend that you get your
own VID/PID pair if you intend to sell your product. Objective
Development's commercial licenses for AVR-USB include a PID for
Development's commercial licenses for V-USB include a PID for
unrestricted exclusive use.

View File

@@ -1,5 +1,5 @@
/* Name: asmcommon.inc
* Project: AVR USB driver
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Christian Starkjohann
* Creation Date: 2007-11-05
* Tabsize: 4

View File

@@ -1,11 +1,11 @@
/* Name: usbconfig.h
* Project: AVR USB driver
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Christian Starkjohann
* Creation Date: 2005-04-01
* Tabsize: 4
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id: usbconfig-prototype.h 734 2009-03-23 11:10:07Z cs $
* This Revision: $Id: usbconfig-prototype.h 740 2009-04-13 18:23:31Z cs $
*/
#ifndef __usbconfig_h_included__
@@ -14,7 +14,7 @@
/*
General Description:
This file is an example configuration (with inline documentation) for the USB
driver. It configures AVR-USB for USB D+ connected to Port D bit 2 (which is
driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is
also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may
wire the lines to any other port, as long as D+ is also wired to INT0 (or any
other hardware interrupt, as long as it is the highest level interrupt, see

View File

@@ -1,11 +1,11 @@
/* Name: usbdrv.c
* Project: AVR USB driver
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Christian Starkjohann
* Creation Date: 2004-12-29
* Tabsize: 4
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id: usbdrv.c 721 2009-03-16 19:03:19Z cs $
* This Revision: $Id: usbdrv.c 740 2009-04-13 18:23:31Z cs $
*/
#include "usbportability.h"

View File

@@ -1,11 +1,11 @@
/* Name: usbdrv.h
* Project: AVR USB driver
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Christian Starkjohann
* Creation Date: 2004-12-29
* Tabsize: 4
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id: usbdrv.h 738 2009-03-23 11:13:24Z cs $
* This Revision: $Id: usbdrv.h 748 2009-04-15 15:05:07Z cs $
*/
#ifndef __usbdrv_h_included__
@@ -122,7 +122,7 @@ USB messages, even if they address another (low-speed) device on the same bus.
/* --------------------------- Module Interface ---------------------------- */
/* ------------------------------------------------------------------------- */
#define USBDRV_VERSION 20090323
#define USBDRV_VERSION 20090415
/* This define uniquely identifies a driver version. It is a decimal number
* constructed from the driver's release date in the form YYYYMMDD. If the
* driver's behavior or interface changes, you can use this constant to

View File

@@ -1,11 +1,11 @@
/* Name: usbdrvasm.S
* Project: AVR USB driver
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Christian Starkjohann
* Creation Date: 2007-06-13
* Tabsize: 4
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* Revision: $Id: usbdrvasm.S 722 2009-03-16 19:03:57Z cs $
* Revision: $Id: usbdrvasm.S 740 2009-04-13 18:23:31Z cs $
*/
/*

View File

@@ -1,5 +1,5 @@
/* Name: usbdrvasm.asm
* Project: AVR USB driver
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Christian Starkjohann
* Creation Date: 2006-03-01
* Tabsize: 4

View File

@@ -1,11 +1,11 @@
/* Name: usbdrvasm12.inc
* Project: AVR USB driver
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Christian Starkjohann
* Creation Date: 2004-12-29
* Tabsize: 4
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id: usbdrvasm12.inc 692 2008-11-07 15:07:40Z cs $
* This Revision: $Id: usbdrvasm12.inc 740 2009-04-13 18:23:31Z cs $
*/
/* Do not link this file! Link usbdrvasm.S instead, which includes the

View File

@@ -1,11 +1,11 @@
/* Name: usbdrvasm128.inc
* Project: AVR USB driver
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Christian Starkjohann
* Creation Date: 2008-10-11
* Tabsize: 4
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id: usbdrvasm128.inc 692 2008-11-07 15:07:40Z cs $
* This Revision: $Id: usbdrvasm128.inc 740 2009-04-13 18:23:31Z cs $
*/
/* Do not link this file! Link usbdrvasm.S instead, which includes the

View File

@@ -1,11 +1,11 @@
/* Name: usbdrvasm15.inc
* Project: AVR USB driver
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: contributed by V. Bosch
* Creation Date: 2007-08-06
* Tabsize: 4
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* Revision: $Id: usbdrvasm15.inc 692 2008-11-07 15:07:40Z cs $
* Revision: $Id: usbdrvasm15.inc 740 2009-04-13 18:23:31Z cs $
*/
/* Do not link this file! Link usbdrvasm.S instead, which includes the

View File

@@ -1,11 +1,11 @@
/* Name: usbdrvasm16.inc
* Project: AVR USB driver
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Christian Starkjohann
* Creation Date: 2007-06-15
* Tabsize: 4
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* Revision: $Id: usbdrvasm16.inc 692 2008-11-07 15:07:40Z cs $
* Revision: $Id: usbdrvasm16.inc 740 2009-04-13 18:23:31Z cs $
*/
/* Do not link this file! Link usbdrvasm.S instead, which includes the

View File

@@ -1,11 +1,11 @@
/* Name: usbdrvasm165.inc
* Project: AVR USB driver
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Christian Starkjohann
* Creation Date: 2007-04-22
* Tabsize: 4
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* Revision: $Id: usbdrvasm165.inc 692 2008-11-07 15:07:40Z cs $
* Revision: $Id: usbdrvasm165.inc 740 2009-04-13 18:23:31Z cs $
*/
/* Do not link this file! Link usbdrvasm.S instead, which includes the

View File

@@ -1,11 +1,11 @@
/* Name: usbdrvasm18.inc
* Project: AVR USB driver
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Lukas Schrittwieser (based on 20 MHz usbdrvasm20.inc by Jeroen Benschop)
* Creation Date: 2009-01-20
* Tabsize: 4
* Copyright: (c) 2008 by Lukas Schrittwieser and OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* Revision: $Id: usbdrvasm18-crc.inc 734 2009-03-23 11:10:07Z cs $
* Revision: $Id: usbdrvasm18-crc.inc 740 2009-04-13 18:23:31Z cs $
*/
/* Do not link this file! Link usbdrvasm.S instead, which includes the

View File

@@ -1,12 +1,12 @@
/* Name: usbdrvasm20.inc
* Project: AVR USB driver
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Jeroen Benschop
* Based on usbdrvasm16.inc from Christian Starkjohann
* Creation Date: 2008-03-05
* Tabsize: 4
* Copyright: (c) 2008 by Jeroen Benschop and OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* Revision: $Id: usbdrvasm20.inc 692 2008-11-07 15:07:40Z cs $
* Revision: $Id: usbdrvasm20.inc 740 2009-04-13 18:23:31Z cs $
*/
/* Do not link this file! Link usbdrvasm.S instead, which includes the

View File

@@ -1,11 +1,11 @@
/* Name: usbportability.h
* Project: AVR USB driver
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers
* Author: Christian Starkjohann
* Creation Date: 2008-06-17
* Tabsize: 4
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id: usbportability.h 692 2008-11-07 15:07:40Z cs $
* This Revision: $Id: usbportability.h 740 2009-04-13 18:23:31Z cs $
*/
/*

Some files were not shown because too many files have changed in this diff Show More