diff -ruNp ./rockbox/apps/plugins/2600box/16bpp_disp.c ./rockbox-working/apps/plugins/2600box/16bpp_disp.c --- ./rockbox/apps/plugins/2600box/16bpp_disp.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/16bpp_disp.c 2013-11-14 15:52:44.098742889 -0500 @@ -0,0 +1,206 @@ +#include "config.h" +#include "version.h" +/* + The RockBOX display code. + */ + +/* Standard Includes */ +#include "rbconfig.h" +#include +#include + +/* 2600 includes */ +#include "types.h" +#include "vmachine.h" +#include "address.h" +#include "files.h" +#include "colours.h" +#include "keyboard.h" +#include "limiter.h" +#include "options.h" + + +#define Palette_GetR(x) ((BYTE) (colortable[x] >> 16)) +#define Palette_GetG(x) ((BYTE) (colortable[x] >> 8)) +#define Palette_GetB(x) ((BYTE) colortable[x]) +#define Palette_GetY(x) (0.30 * Palette_GetR(x) + 0.59 * Palette_GetG(x) + 0.11 * Palette_GetB(x)) + + +#define NUMCOLS 128 + +#if LCD_WIDTH < 320 +short /*fb_data*/ colors[NUMCOLS]; +#else +int /*fb_data*/ colors[NUMCOLS]; +#endif + +int tv_depth; +int tv_bytes_pp; +/* Various variables and short functions */ + +/* Start of image data */ +#if LCD_WIDTH < 320 +short *vscreen; +#else +BYTE *vscreen; +#endif + +#if LCD_WIDTH < 320 +short screenmem [ 160*192 ]; +#endif + + +/* The width and height of the image, including any magnification */ +int vwidth, vheight, theight; + +/* The frame rate counter. Used by the -rr switch */ +int tv_counter = 0; + +/* Optionally set by the X debugger. */ +int redraw_flag = 1; + + +/* Inline helper to place the tv image */ +static inline void +put_image (void) +{ +#if LCD_WIDTH < 320 + int X_STEP = ((tv_width<<16) / LCD_WIDTH); + int Y_STEP = ((tv_height<<16) / LCD_HEIGHT); + fb_data *frameb; + int x=0,y=0; + int srcx, srcy=0; /* x / y coordinates in source image */ + short* image; + image = &screenmem[0]; + frameb = rb->lcd_framebuffer; + for(y = 0; y < LCD_HEIGHT; y++) + { + srcx = 0; /* reset our x counter before each row... */ + for(x = 0; x < LCD_WIDTH; x++) + { + *frameb = image[srcx>>16]; + srcx += X_STEP; /* move through source image */ + frameb++; + } + srcy += Y_STEP; /* move through the source image... */ + image += (srcy>>16)*tv_width; /* and possibly to the next row. */ + srcy &= 0xffff; /* set up the y-coordinate between 0 and 1 */ + } +#endif + + rb->lcd_update(); +} + +/* Create the color map of Atari colors */ +/* VGA colors are only 6 bits wide */ +static void +create_cmap (void) +{ + int i; + /* Initialise parts of the colors array */ + for (i = 0; i < NUMCOLS; i++) + { + + /* Use the color values from the color table */ + colors[i] = LCD_RGBPACK ( Palette_GetR(i*2) , Palette_GetG(i*2) , Palette_GetB(i*2)); + } +} + +/* Create the main window */ +/* argc: argument count */ +/* argv: argument text */ +static void +create_window (int argc, char **argv) +{ + int i; + + /* Calculate the video width and height */ +#if LCD_WIDTH >= 320 + vwidth = LCD_WIDTH; + vheight = LCD_HEIGHT; +#else + vwidth = tv_width; + vheight = tv_height; +#endif + + theight = vheight; + + /* Turn on the keyboard. Must be done after toplevel is created */ + init_keyboard (); + + /* Create the color map */ + create_cmap (); +#if LCD_WIDTH < 320 + tv_depth=8; + tv_bytes_pp=tv_depth/4; +#else + tv_depth=16; + tv_bytes_pp=tv_depth/8; +#endif +} + + +/* Turns on the television. */ +/* argc: argument count */ +/* argv: argument text */ +/* returns: 1 for success, 0 for failure */ +int +tv_on (int argc, char **argv) +{ +#if LCD_WIDTH >= 320 + vscreen = (BYTE*)rb -> lcd_framebuffer ; +#else + vscreen = &screenmem[0]; +#endif + create_window(NULL,NULL); + return (1); +} + + +/* Turn off the tv. Closes the X connection and frees the shared memory */ +void +tv_off (void) +{ + +} + + +/* Translates a 2600 color value into an X11 pixel value */ +/* b: byte containing 2600 colour value */ +/* returns: X11 pixel value */ +#if LCD_WIDTH >= 320 +unsigned int +#else +unsigned short +#endif +tv_color (BYTE b) +{ + +#if LCD_WIDTH >= 320 + return (colors[b>>1] | colors [b>>1] << 16); +#else + return (colors[b>>1]); +#endif +} + +/* Displays the tv screen */ +void +tv_display (void) +{ + /* Only display if the frame is a valid one. */ + if (tv_counter % base_opts.rr == 0) + { + put_image (); + } + tv_counter++; + + +} + +/* The Event code. */ +void +tv_event (void) +{ + read_keyboard (); +} + diff -ruNp ./rockbox/apps/plugins/2600box/2600box.make ./rockbox-working/apps/plugins/2600box/2600box.make --- ./rockbox/apps/plugins/2600box/2600box.make 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/2600box.make 2013-11-14 09:48:15.015455315 -0500 @@ -0,0 +1,40 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id$ +# + +2600BOX_SRCDIR = $(APPSDIR)/plugins/2600box +2600BOX_OBJDIR = $(BUILDDIR)/apps/plugins/2600box + +2600BOX_SRC := $(call preprocess, $(2600BOX_SRCDIR)/SOURCES) +2600BOX_OBJ := $(call c2obj, $(2600BOX_SRC)) + +OTHER_SRC += $(2600BOX_SRC) + +ifeq ($(findstring YES, $(call preprocess, $(APPSDIR)/plugins/BUILD_OVERLAY)), YES) + ## lowmem targets + ROCKS += $(2600BOX_OBJDIR)/2600box.ovl + 2600BOX_OUTLDS = $(2600BOX_OBJDIR)/2600box.link + 2600BOX_OVLFLAGS = -T$(2600BOX_OUTLDS) -Wl,--gc-sections -Wl,-Map,$(basename $@).map +else + ROCKS += $(2600BOX_OBJDIR)/2600box.rock +endif + +$(2600BOX_OBJDIR)/2600box.rock: $(2600BOX_OBJ) + +$(2600BOX_OBJDIR)/2600box.refmap: $(2600BOX_OBJ) + +$(2600BOX_OUTLDS): $(PLUGIN_LDS) $(2600BOX_OBJDIR)/2600box.refmap + $(call PRINTS,PP $(@F))$(call preprocess2file,$<,$@,-DOVERLAY_OFFSET=$(shell \ + $(TOOLSDIR)/ovl_offset.pl $(2600BOX_OBJDIR)/2600box.refmap)) + +$(2600BOX_OBJDIR)/2600box.ovl: $(2600BOX_OBJ) $(2600BOX_OUTLDS) + $(SILENT)$(CC) $(PLUGINFLAGS) -o $(basename $@).elf \ + $(filter %.o, $^) \ + $(filter %.a, $+) \ + -lgcc $(2600BOX_OVLFLAGS) + $(call PRINTS,LD $(@F))$(call objcopy,$(basename $@).elf,$@) diff -ruNp ./rockbox/apps/plugins/2600box/4bpp_hp_disp.c ./rockbox-working/apps/plugins/2600box/4bpp_hp_disp.c --- ./rockbox/apps/plugins/2600box/4bpp_hp_disp.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/4bpp_hp_disp.c 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,184 @@ +#include "config.h" +#include "version.h" +/* + The RockBOX display code. + */ + +/* Standard Includes */ +#include "rbconfig.h" +#include +#include + +/* 2600 includes */ +#include "types.h" +#include "vmachine.h" +#include "address.h" +#include "files.h" +#include "colours.h" +#include "keyboard.h" +#include "limiter.h" +#include "options.h" + + +#define Palette_GetR(x) ((BYTE) (colortable[x] >> 16)) +#define Palette_GetG(x) ((BYTE) (colortable[x] >> 8)) +#define Palette_GetB(x) ((BYTE) colortable[x]) +#define Palette_GetY(x) (0.30 * Palette_GetR(x) + 0.59 * Palette_GetG(x) + 0.11 * Palette_GetB(x)) + + +#define NUMCOLS 128 +BYTE colors[NUMCOLS]; + + +int tv_depth; +int tv_bytes_pp; +/* Various variables and short functions */ + +/* Start of image data */ +BYTE *vscreen; +BYTE screen[160*228] IBSS_ATTR; + +/* The width and height of the image, including any magnification */ +int vwidth, vheight, theight; + +/* The frame rate counter. Used by the -rr switch */ +int tv_counter = 0; + +/* Optionally set by the X debugger. */ +int redraw_flag = 1; + + + +#define FB_WIDTH ((LCD_WIDTH+3)/4) +unsigned char pixmask[4] ICONST_ATTR = { + 0xC0, 0x30, 0x0C, 0x03 +}; + +/* Inline helper to place the tv image */ +static inline void +put_image (void) +{ + fb_data *frameb; + int y=0; + int x=0; + +int X_STEP =((tv_width<<16) / LCD_WIDTH); +int Y_STEP =((tv_height<<16) / LCD_HEIGHT); + + unsigned char* image; + int srcx, srcy=0; /* x / y coordinates in source image */ + image = &screen[0]; + unsigned mask; + + for(y = 0; y < LCD_HEIGHT; y++) + { + frameb = rb->lcd_framebuffer + (y) * FB_WIDTH; + srcx = 0; /* reset our x counter before each row... */ + for(x = 0; x < LCD_WIDTH; x++) + { + mask = pixmask[x & 3]; + frameb[x >> 2] = (frameb[x >> 2] & ~mask) | ((image[(srcx>>16)]&0x3) << ((3-(x & 3 )) * 2 )); + srcx += X_STEP; /* move through source image */ + } + srcy += Y_STEP; /* move through the source image... */ + image += (srcy>>16)*tv_width; /* and possibly to the next row. */ + srcy &= 0xffff; /* set up the y-coordinate between 0 and 1 */ + } + + rb->lcd_update(); +} + +/* Create the color map of Atari colors */ +/* VGA colors are only 6 bits wide */ +static void +create_cmap (void) +{ + int i; + /* Initialise parts of the colors array */ + for (i = 0; i < NUMCOLS; i++) + { + + /* Use the color values from the color table */ + colors[i] = LCD_BRIGHTNESS (Palette_GetY(i*2)); + } +} + +/* Create the main window */ +/* argc: argument count */ +/* argv: argument text */ +static void +create_window (int argc, char **argv) +{ + int i; + + /* Calculate the video width and height */ + vwidth = tv_width; + + vheight = tv_height; + + + theight = vheight; + + /* Turn on the keyboard. Must be done after toplevel is created */ + init_keyboard (); + + /* Create the color map */ + create_cmap (); + tv_depth=8; + tv_bytes_pp=tv_depth/8; +} + + +/* Turns on the television. */ +/* argc: argument count */ +/* argv: argument text */ +/* returns: 1 for success, 0 for failure */ +int +tv_on (int argc, char **argv) +{ + + vscreen = &screen[0] ; + create_window(NULL,NULL); + return (1); +} + + +/* Turn off the tv. Closes the X connection and frees the shared memory */ +void +tv_off (void) +{ + +} + + +/* Translates a 2600 color value into an X11 pixel value */ +/* b: byte containing 2600 colour value */ +/* returns: X11 pixel value */ +BYTE +tv_color (BYTE b) +{ +// return (b); + return (colors[b]); +} + +/* Displays the tv screen */ +void +tv_display (void) +{ + /* Only display if the frame is a valid one. */ + if (tv_counter % base_opts.rr == 0) + { + put_image (); + } + tv_counter++; + + +} + +/* The Event code. */ +void +tv_event (void) +{ + read_keyboard (); +} + diff -ruNp ./rockbox/apps/plugins/2600box/address.h ./rockbox-working/apps/plugins/2600box/address.h --- ./rockbox/apps/plugins/2600box/address.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/address.h 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,110 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: address.h,v 1.4 1996/04/01 14:51:50 alex Exp $ +******************************************************************************/ + +#ifndef ADDRESS_H +#define ADDRESS_H + +/* Contains the addresses of the 2600 hardware */ +/* $Id: address.h,v 1.4 1996/04/01 14:51:50 alex Exp $ */ + +/* TIA Write Addresses (6 bit) */ + +#define VSYNC 0x00 +#define VBLANK 0x01 +#define WSYNC 0x02 +#define RSYNC 0x03 +#define NUSIZ0 0x04 +#define NUSIZ1 0x05 +#define COLUP0 0x06 +#define COLUP1 0x07 +#define COLUPF 0x08 +#define COLUBK 0x09 +#define CTRLPF 0x0A +#define REFP0 0x0B +#define REFP1 0x0C +#define PF0 0x0D +#define PF1 0x0E +#define PF2 0x0F +#define RESP0 0x10 +#define RESP1 0x11 +#define RESM0 0x12 +#define RESM1 0x13 +#define RESBL 0x14 +#define AUDC0 0x15 +#define AUDC1 0x16 +#define AUDF0 0x17 +#define AUDF1 0x18 +#define AUDV0 0x19 +#define AUDV1 0x1A +#define GRP0 0x1B +#define GRP1 0x1C +#define ENAM0 0x1D +#define ENAM1 0x1E +#define ENABL 0x1F +#define HMP0 0x20 +#define HMP1 0x21 +#define HMM0 0x22 +#define HMM1 0x23 +#define HMBL 0x24 +#define VDELP0 0x25 +#define VDELP1 0x26 +#define VDELBL 0x27 +#define RESMP0 0x28 +#define RESMP1 0x29 +#define HMOVE 0x2A +#define HMCLR 0x2B +#define CXCLR 0x2C + +/* TIA Read Addresses */ +#define CXM0P 0x0 +#define CXM1P 0x1 +#define CXP0FB 0x2 +#define CXP1FB 0x3 +#define CXM0FB 0x4 +#define CXM1FB 0x5 +#define CXBLPF 0x6 +#define CXPPMM 0x7 +#define INPT0 0x8 +#define INPT1 0x9 +#define INPT2 0xA +#define INPT3 0xB +#define INPT4 0xC +#define INPT5 0xD + +/* RIOT Addresses */ + +#define RAM 0x80 /* till 0xff */ +#define SWCHA 0x280 +#define SWACNT 0x281 +#define SWCHB 0x282 +#define SWBCNT 0x283 +#define INTIM 0x284 + +#define TIM1T 0x294 +#define TIM8T 0x295 +#define TIM64T 0x296 +#define T1024T 0x297 + +#define ROM 0xE000 /* To FFFF,0x1000-1FFF */ + +#endif + + + + + + + + diff -ruNp ./rockbox/apps/plugins/2600box/asm.h ./rockbox-working/apps/plugins/2600box/asm.h --- ./rockbox/apps/plugins/2600box/asm.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/asm.h 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,167 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: asm.h,v 1.2 1996/04/01 14:51:50 alex Exp $ +******************************************************************************/ + +/* + * This file is was part of x64. + * + * Error codes and messages used in asm.c and + * control codes for both asm and mon. + * + * Written by + * Vesa-Matti Puro (vmp@lut.fi) + * + * + */ + +#ifndef X64_ASM_H +#define X64_ASM_H + + +#define NUM_OF_MNEMS 56 +#define TOTAL_CODES 256 +#define MAXARG 19 /* command + addr + 16 bytes + 1 */ + + /* optimise searching a little */ +#define OP_MNEM_SPC 0x04 + +#define OP_IMPL_MIN 0x00 +#define OP_IMPL_MAX 0xfa +#define OP_IMPL_SPC 0x02 + +#define OP_IMM_MIN 0x09 +#define OP_IMM_MAX 0xeb +#define OP_IMM_SPC 0x01 /* not used */ + +#define OP_ACCU_MIN 0x0a +#define OP_ACCU_MAX 0x6a +#define OP_ACCU_SPC 0x20 + +#define OP_ABS_MIN 0x0c +#define OP_ABS_MAX 0xff +#define OP_ABS_SPC 0x04 + + + /* Symbol definitions */ + +#define SYMBOL_BYTE 1 +#define SYMBOL_WORD 2 +#define SYMBOL_FOUND 16 +#define SYMBOL_SET 32 +#define SYMBOL_VALID 64 + +#define SYMBOL_MAX_CHARS 8 + /* For portability, labels should be 6 characters or less. */ + + + /* + * Define 'mode' + */ + +#define MODE_HEX 1 +#define MODE_SYMBOL 2 +#define MODE_QUOTE 4 +#define MODE_MON (1 << 5) +#define MODE_ASM (1 << 6) +#define MODE_INF (1 << 7) +#define MODE_OUTF (1 << 8) +#define MODE_QUIET (1 << 9) +#define MODE_VERBOSE (1 << 10) +#define MODE_QUERY (1 << 12) +#define MODE_SPACE (1 << 13) /* space terminates calculation (MON) */ + + + /* + * Error messages + */ + +#define ERRORS_TO_STOP 20 /* screenfull on terminal */ + +#define E_OK 0 + + /* Warnings */ + +#define E_UNDOCUMENTED (-1) +#define E_SIZE (-2) +#define E_LARGE_VALUE (-3) +#define E_LONG_NAME (-4) +#define E_FORWARD_REF (-5) + + /* Errors */ +#define E_ERROR (-64) /* General error */ + +/* Line Syntax */ +#define E_SYNTAX (E_ERROR) +#define E_PARSE_ERROR (E_ERROR -1) +#define E_TOO_MANY_ERRORS (E_ERROR -2) + +/* Assembler */ +#define E_BAD_IDENTIFIER (E_ERROR -8) +#define E_BAD_DIRECTIVE (E_ERROR -9) +#define E_SYMBOL_UNDEFINED (E_ERROR -10) +#define E_SYMBOL_REDEF (E_ERROR -11) +#define E_PC_DECREMENT (E_ERROR -12) + +/* Mnemonic */ +#define E_BAD_MNEM (E_ERROR -16) +#define E_LONG_BRANCH (E_ERROR -17) +#define E_MISSING_OPER (E_ERROR -18) + +/* Operand Syntax */ +#define E_PARAMETER_SYNTAX (E_ERROR -24) +#define E_TOO_MANY_COMMAS (E_ERROR -25) +#define E_RIGHT_PARENTHESIS (E_ERROR -26) +#define E_LEFT_PARENTHESIS (E_ERROR -27) +#define E_PARENTHESIS (E_ERROR -28) + +#define E_MIXED_XY (E_ERROR -30) +#define E_MISSING_XY (E_ERROR -31) +#define E_BAD_INDEX (E_ERROR -32) + + + + /* Warnings */ +#define EM_UNDOCUMENTED "Undocumented opcode used" +#define EM_SIZE "Operand length changed" +#define EM_LARGE_VALUE "Value too large" +#define EM_LONG_NAME "Symbol name too long" +#define EM_FORWARD_REF "Forward reference" + + /* Errors */ +#define EM_SYNTAX "Syntax error" +#define EM_PARSE_ERROR "Parse error: I don't get it." +#define EM_TOO_MANY_ERRORS "Keep your filthy fingers off here!" + +#define EM_BAD_IDENTIFIER "Identifier error" +#define EM_BAD_DIRECTIVE "Unrecognised directive" +#define EM_SYMBOL_UNDEFINED "Undefined symbol" +#define EM_SYMBOL_REDEF "Symbol redefined" +#define EM_PC_DECREMENT "PC decrement" + +#define EM_BAD_MNEM "Illegal mnemonic" +#define EM_LONG_BRANCH "Branch out of range" +#define EM_MISSING_OPER "Operand missing" + +#define EM_PARAMETER_SYNTAX "Parameter syntax error" +#define EM_TOO_MANY_COMMAS "Too many commas found" +#define EM_RIGHT_PARENTHESIS "Too many right parenthesis, 1 is maximum" +#define EM_LEFT_PARENTHESIS "Too many left parenthesis, 1 is maximum" +#define EM_PARENTHESIS "Not equally right and left parenthesis" + +#define EM_MIXED_XY "Indirect mode indexed both X and Y" +#define EM_MISSING_XY "Index register missing" +#define EM_BAD_INDEX "Index register must be X or Y" + + +#endif /* X64_ASM_H */ diff -ruNp ./rockbox/apps/plugins/2600box/c26def.h ./rockbox-working/apps/plugins/2600box/c26def.h --- ./rockbox/apps/plugins/2600box/c26def.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/c26def.h 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,101 @@ +#ifndef C26DEF_H +#define C26DEF_H + +/* + Common 2600 (.c26) format v1.0 specification + ------------------------------------- + Alex Hornby, ahornby@zetnet.co.uk + + + Introduction + ============ + + Common 2600 file format definitions. For discussion and suggestions for + improvement, e-mail ahornby@zetnet.co.uk. I would like to see a fully + comprehensive 2600 file format develop so please copy this structure + and use it in your emulators. + + The format has been developed due to the multitude of different banking + schemes for 2600 cartridges, along with the need to select an appropriate + control device for each game. Using the .c26 format you will be able to + load games without giving loads of command line switches. + + Philosophy + ========== + To avoid the format splitting into several competing ones, please do + not alter the format without discussing it first. I'm not trying to be + bossy, just to keep the common format truly common. + + Tags + ==== + The format is tagged so as to be extensible and allow both forward and + backward compatibility. It also means that information that is not + needed or known does not have to be stored. e.g. If the cartridge image + is not a saved game then I do not need the game state tags. + + The format is a system of tags each being a tag type and the length of + data in that section. If a tag is not recognised then it should + be ignored. Each tag is a zero terminated string followed by a 32bit + signed integer describing the length. If the tag is small the the length + integer can constitute the data item. + + Case is NOT important in tag names + + Cross Platform Notes + ==================== + Note that integers are stored in the Intel/DEC Alpha style. + All strings are zero terminated . +*/ + +/* + Defined TAGS + ============ + + + Audit tags: All files should include these tags at the start of the file. + + _2600_VERSION: Gives file format version as an integer. Currently 1 + WRITER: Name of program that wrote file. + + + Cartridge Information tags: useful for collectors. + + CARTNAME: Name of cartridge. + CARTMAN: Manufacturer of cartridge. + CARTAUTHOR: Name of programmer/programming team who wrote cartridge. + CARTSERIAL: Serial number of the cartridge. + + + Cartridge operation tags: necessary for the running of the game. + + TVTYPE: integer, 0=NTSC 1=PAL. + CONTROLLERS: Left controller BYTE then Right controller BYTE. + BANKING: Bank switching scheme. + DATA: Cartridge ROM data. + + + Game state tags: used for saved games. + + CPUREGS: CPU registers. + GAMEREGS: TIA and PIA registers. + PIARAM: The 128 bytes of RAM from the PIA. + + CARTRAM: Cartridge RAM, if supported by the BANKING type + + */ +enum TAGTYPE { _2600_VERSION=-1, WRITER=1, + CARTNAME=2, CARTMAN=3, CARTAUTHOR=4, CARTSERIAL=5, + TVTYPE=-2, CONTROLLERS=-3, BANKING=-4, DATA=6, + CPUREGS=7, GAMEREGS=8, PIARAM=9, CARTRAM=10 }; + +char *tag_desc[]={ "_2600_VERSION", "WRITER", + "CARTNAME", "CARTMAN", "CARTAUTHOR", "CARTSERIAL", + "TVTYPE", "CONTROLLERS", "BANKING", "DATA", + "CPUREGS", "GAMEREGS", "PIARAM", "CARTRAM"}; + + +/* Tag structure */ + +struct c26_tag { + int type; + int len; +}; + + +#endif diff -ruNp ./rockbox/apps/plugins/2600box/collision.c ./rockbox-working/apps/plugins/2600box/collision.c --- ./rockbox/apps/plugins/2600box/collision.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/collision.c 2013-11-14 10:04:18.399423931 -0500 @@ -0,0 +1,119 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: collision.c,v 1.10 1997/11/22 14:27:47 ahornby Exp $ +******************************************************************************/ + +/* The 2600 collision detection code */ + +#include "rbconfig.h" + +#include + +#include "options.h" +#include "types.h" +#include "address.h" +#include "vmachine.h" +#include "col_mask.h" + +/* + There are 6 different objects on the screen. Each takes one bit of the + collision vector. + Bit 0: Player 0 + Bit 1: Player 1 + Bit 2: Missile 0 + Bit 3: Missile 1 + Bit 4: Ball + Bit 5: Playfield + */ + +/* The collision vector */ +BYTE *colvect=0; + +/* The collision lookup table */ +unsigned short col_table[256]; + +/* The collision state */ +unsigned short col_state; + +/* Resets the collision registers of the tia */ +inline void +extern reset_collisions (void) +{ + col_state=0; +} + +/* Does collision testing on the pixel b */ +/* b: byte to test for collisions */ +/* Used to build up the collision table */ +int +set_collisions (BYTE b) +{ + int res=0; + + if ((b & ML0_MASK) && (b & PL1_MASK)) + res |= M0P1_MASK; + if ((b & ML0_MASK) && (b & PL0_MASK)) + res |= M0P0_MASK; + if ((b & ML1_MASK) && (b & PL0_MASK)) + res |= M1P0_MASK; + if ((b & ML1_MASK) && (b & PL1_MASK)) + res |= M1P1_MASK; + + if ((b & PL0_MASK) && (b & PF_MASK)) + res |= P0PF_MASK; + if ((b & PL0_MASK) && (b & BL_MASK)) + res |= P0BL_MASK; + if ((b & PL1_MASK) && (b & PF_MASK)) + res |= P1PF_MASK ; + if ((b & PL1_MASK) && (b & BL_MASK)) + res |= P1BL_MASK; + + if ((b & ML0_MASK) && (b & PF_MASK)) + res |= M0PF_MASK; + if ((b & ML0_MASK) && (b & BL_MASK)) + res |= M0BL_MASK; + if ((b & ML1_MASK) && (b & PF_MASK)) + res |= M1PF_MASK; + if ((b & ML1_MASK) && (b & BL_MASK)) + res |= M1BL_MASK; + + if ((b & BL_MASK) && (b & PF_MASK)) + res |=BLPF_MASK; + if ((b & PL0_MASK) && (b & PL1_MASK)) + res |=P0P1_MASK ; + if ((b & ML0_MASK) && (b & ML1_MASK)) + res |=M0M1_MASK ; + + return res; +} + +char colvect_MEM[28*8]; +void +init_collisions(void) +{ + int i; + + /* Set up the collision lookup table */ + for (i = 0; i < 256; i++) + col_table[i] = set_collisions(i); + + /* Stop memory leaking */ +/* if(colvect!=0) + free(colvect);*/ + + /* Get the colvect 8 byte aligned */ +/* colvect=(BYTE *)calloc(28, 8);*/ + colvect = &colvect_MEM[0]; + + reset_collisions(); +} diff -ruNp ./rockbox/apps/plugins/2600box/collision.h ./rockbox-working/apps/plugins/2600box/collision.h --- ./rockbox/apps/plugins/2600box/collision.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/collision.h 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,49 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: collision.h,v 1.5 1996/08/29 16:03:24 ahornby Exp $ +******************************************************************************/ + +/* + Defines for the hardware collision detection. + */ + +#ifndef COLLISION_H +#define COLLISION_H + +#include "col_mask.h" + +/* The collsion vector */ +extern BYTE* colvect; + +/* The collision lookup table */ +extern unsigned short col_table[256]; + +/* The collision state */ +extern unsigned short col_state; + +extern void +init_collisions(void); + +extern void +reset_collisions(void); + +extern int +set_collisions(BYTE b); + +#endif + + + + + + diff -ruNp ./rockbox/apps/plugins/2600box/col_mask.h ./rockbox-working/apps/plugins/2600box/col_mask.h --- ./rockbox/apps/plugins/2600box/col_mask.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/col_mask.h 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,45 @@ +#ifndef COL_MASK_H +#define COL_MASK_H + +#define PL0_MASK 0x01 +#define PL1_MASK 0x02 +#define ML0_MASK 0x04 +#define ML1_MASK 0x08 +#define BL_MASK 0x10 +#define PF_MASK 0x20 +#define PF_MASK32 0x20202020 + +#define M0P0_MASK 0x01 +#define M0P1_MASK 0x02 + +#define M1P1_MASK 0x04 +#define M1P0_MASK 0x08 + +#define P0BL_MASK 0x10 +#define P0PF_MASK 0x20 + +#define P1BL_MASK 0x40 +#define P1PF_MASK 0x80 + +#define M0BL_MASK 0x100 +#define M0PF_MASK 0x200 + +#define M1BL_MASK 0x400 +#define M1PF_MASK 0x800 + +#define BLPF_MASK 0x1000 + +#define M0M1_MASK 0x2000 +#define P0P1_MASK 0x4000 + +#define CXM0P_MASK (M0P1_MASK | M0P0_MASK) +#define CXM1P_MASK (M1P0_MASK | M1P1_MASK) +#define CXP0FB_MASK (P0PF_MASK | P0BL_MASK) +#define CXP1FB_MASK (P1PF_MASK | P1BL_MASK) +#define CXM0FB_MASK (M0PF_MASK | M0BL_MASK) +#define CXM1FB_MASK (M1PF_MASK | M1BL_MASK) +#define CXBLPF_MASK BLPF_MASK +#define CXPPMM_MASK (P0P1_MASK | M0M1_MASK) + +#endif + diff -ruNp ./rockbox/apps/plugins/2600box/colours.h ./rockbox-working/apps/plugins/2600box/colours.h --- ./rockbox/apps/plugins/2600box/colours.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/colours.h 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,123 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: colours.h,v 1.3 1996/04/01 14:51:50 alex Exp $ +******************************************************************************/ + +/* + A table of all possible Atari 2600 colors. + Credit to the author of atari800, for most of them, + but some were wrong for the VCS. + */ + +static int colortable[256] = +{ + /* Grey */ + 0x0, 0x1c1c1c, 0x393939, 0x595959, + 0x797979, 0x929292, 0xababab, 0xbcbcbc, + 0xcdcdcd, 0xd9d9d9, 0xe6e6e6, 0xececec, + 0xf2f2f2, 0xf8f8f8, 0xffffff, 0xffffff, + + /* Gold */ + 0x391701, 0x5e2304, 0x833008, 0xa54716, + 0xc85f24, 0xe37820, 0xff911d, 0xffab1d, + 0xffc51d, 0xffce34, 0xffd84c, 0xffe651, + 0xfff456, 0xfff977, 0xffff98, 0xffff98, + + /* Orange */ + 0x451904, 0x721e11, 0x9f241e, 0xb33a20, + 0xc85122, 0xe36920, 0xff811e, 0xff8c25, + 0xff982c, 0xffae38, 0xffc545, 0xffc559, + 0xffc66d, 0xffd587, 0xffe4a1, 0xffe4a1, + + /* Red Orange */ + 0x4a1704, 0x7e1a0d, 0xb21d17, 0xc82119, + 0xdf251c, 0xec3b38, 0xfa5255, 0xfc6161, + 0xff706e, 0xff7f7e, 0xff8f8f, 0xff9d9e, + 0xffabad, 0xffb9bd, 0xffc7ce, 0xffc7ce, + + /* Pink */ + 0x50568, 0x3b136d, 0x712272, 0x8b2a8c, + 0xa532a6, 0xb938ba, 0xcd3ecf, 0xdb47dd, + 0xea51eb, 0xf45ff5, 0xfe6dff, 0xfe7afd, + 0xff87fb, 0xff95fd, 0xffa4ff, 0xffa4ff, + + /* Purple */ + 0x280479, 0x400984, 0x590f90, 0x70249d, + 0x8839aa, 0xa441c3, 0xc04adc, 0xd054ed, + 0xe05eff, 0xe96dff, 0xf27cff, 0xf88aff, + 0xff98ff, 0xfea1ff, 0xfeabff, 0xfeabff, + + /* Blue Purple */ + 0x35088a, 0x420aad, 0x500cd0, 0x6428d0, + 0x7945d0, 0x8d4bd4, 0xa251d9, 0xb058ec, + 0xbe60ff, 0xc56bff, 0xcc77ff, 0xd183ff, + 0xd790ff, 0xdb9dff, 0xdfaaff, 0xdfaaff, + + /* Blue */ + 0x51e81, 0x626a5, 0x82fca, 0x263dd4, + 0x444cde, 0x4f5aee, 0x5a68ff, 0x6575ff, + 0x7183ff, 0x8091ff, 0x90a0ff, 0x97a9ff, + 0x9fb2ff, 0xafbeff, 0xc0cbff, 0xc0cbff, + + /* Blue */ + 0xc048b, 0x2218a0, 0x382db5, 0x483ec7, + 0x584fda, 0x6159ec, 0x6b64ff, 0x7a74ff, + 0x8a84ff, 0x918eff, 0x9998ff, 0xa5a3ff, + 0xb1aeff, 0xb8b8ff, 0xc0c2ff, 0xc0c2ff, + + /* Light Blue */ + 0x1d295a, 0x1d3876, 0x1d4892, 0x1c5cac, + 0x1c71c6, 0x3286cf, 0x489bd9, 0x4ea8ec, + 0x55b6ff, 0x70c7ff, 0x8cd8ff, 0x93dbff, + 0x9bdfff, 0xafe4ff, 0xc3e9ff, 0xc3e9ff, + + /* Turquoise */ + 0x2f4302, 0x395202, 0x446103, 0x417a12, + 0x3e9421, 0x4a9f2e, 0x57ab3b, 0x5cbd55, + 0x61d070, 0x69e27a, 0x72f584, 0x7cfa8d, + 0x87ff97, 0x9affa6, 0xadffb6, 0xadffb6, + + /* Green blue */ + 0xa4108, 0xd540a, 0x10680d, 0x137d0f, + 0x169212, 0x19a514, 0x1cb917, 0x1ec919, + 0x21d91b, 0x47e42d, 0x6ef040, 0x78f74d, + 0x83ff5b, 0x9aff7a, 0xb2ff9a, 0xb2ff9a, + + /* Green */ + 0x4410b, 0x5530e, 0x66611, 0x77714, + 0x88817, 0x99b1a, 0xbaf1d, 0x48c41f, + 0x86d922, 0x8fe924, 0x99f927, 0xa8fc41, + 0xb7ff5b, 0xc9ff6e, 0xdcff81, 0xdcff81, + + /* Yellow Green */ + 0x2350f, 0x73f15, 0xc4a1c, 0x2d5f1e, + 0x4f7420, 0x598324, 0x649228, 0x82a12e, + 0xa1b034, 0xa9c13a, 0xb2d241, 0xc4d945, + 0xd6e149, 0xe4f04e, 0xf2ff53, 0xf2ff53, + + /* Orange Green */ + 0x263001, 0x243803, 0x234005, 0x51541b, + 0x806931, 0x978135, 0xaf993a, 0xc2a73e, + 0xd5b543, 0xdbc03d, 0xe1cb38, 0xe2d836, + 0xe3e534, 0xeff258, 0xfbff7d, 0xfbff7d, + + /* Light Orange */ + 0x401a02, 0x581f05, 0x702408, 0x8d3a13, + 0xab511f, 0xb56427, 0xbf7730, 0xd0853a, + 0xe19344, 0xeda04e, 0xf9ad58, 0xfcb75c, + 0xffc160, 0xffc671, 0xffcb83, 0xffcb83, +}; + + + + diff -ruNp ./rockbox/apps/plugins/2600box/cpu.c ./rockbox-working/apps/plugins/2600box/cpu.c --- ./rockbox/apps/plugins/2600box/cpu.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/cpu.c 2013-11-14 11:59:50.167198117 -0500 @@ -0,0 +1,5054 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: cpu.c,v 1.11.1.11 1997/11/22 14:27:47 ahornby Exp $ +******************************************************************************/ +/* + * 6507 CPU emulation + * + * Originally from X64 + * Modified by Alex Hornby for use in x2600 + * See COPYING for license terms + */ + +#include +#include +#include +#include "cpu.h" +#include "macro.h" +#include "vmachine.h" +#include "memory.h" +#include "display.h" +/* #include "misc.h" */ + +#include "rbconfig.h" +#include "exmacro.h" +#include "debug.h" +#include "dbg_mess.h" + + +void +show () +{ +} + + +/* Verbose output flag from X64 debugging code */ +int verflg = 0; + +/* Hex output flag from X64 debugging code */ +int hexflg = 0; + +/* X64 compatible debug code. depreciated */ +void +mon (ADDRESS a) +{ +} + +/* X64 compatible debug code. depreciated */ +#ifdef DEBUG +#include "memory.h" +int rd[RAMSIZE]; +int wr[RAMSIZE]; +long instructions[256]; +#endif + +/* The X based debugger prototypes */ +#ifdef XDEBUGGER +extern void x_loop (void); +extern void set_single (void); +#endif + +/* CPU internals */ +ADDRESS program_counter; +BYTE x_register, y_register, stack_pointer; +BYTE accumulator, status_register; +int zero_flag; +int sign_flag; +int overflow_flag; +int break_flag; +int decimal_flag; +int interrupt_flag; +int carry_flag; + +/* CPU Clock counts */ +/* Aggregate */ +CLOCK clk; +/* Current instruction */ +CLOCK clkcount = 0; + +/* Electron beam adjuctment values for nine and twelve colour clock ins. */ +#define BEAMNINE 5 +#define BEAMTWELVE 9 +int beamadj; + +/* Used in undocumented 6507 instructions */ +/* These are unusual and have no discernable use, but here it is. */ +/* val: register to be acted upon */ +/* address: address to take high byte from */ +/* index: index to add to calculated address */ +#ifndef NO_UNDOC_CMDS +void +u_stoshr (unsigned int val, ADDRESS address, BYTE index) +{ + val &= (((address >> 8) + 1) & 0xff); + if (((address & 0xff) + index) > 0xff) + address = val; + STORE ((address + index), val); +} +#endif /* UNDOC */ + +/* Initialise the CPU */ +/* addr: reset vector address */ +/* Called from init_hardware() */ +void +init_cpu (ADDRESS addr) +{ + SET_SR (0x20); + AC=0; + XR=0; + YR=0; + SP = 0xff; + dbg_message(DBG_NORMAL,"ADDR=%x\n",addr); + PC = LOAD_ADDR (addr); + clk = 0; + clkcount = 0; +} + +/* The main emulation loop, performs the CPU emulation */ +void +mainloop (void) +{ + register BYTE b; + init_hardware (); + while (1) + { + dbg_message(DBG_NORMAL,"Reset flag=%d\n",reset_flag); + if (reset_flag) + { + reset_flag = 0; + if (fselLoad () == 0) + { + dbg_message(DBG_NORMAL,"Calling init_hardware\n"); + init_hardware (); + } + } + + dbg_message(DBG_NORMAL,"Starting mainloop at %x\n", PC); + while (!reset_flag) + { + do_screen (clkcount); + +#ifdef XDEBUGGER + if (debugf_on); + x_loop (); +#endif + b = LOADEXEC (PC); + beamadj = 0; + + /* "remove this when keybrd driver is ready" */ + int buttons = rb->button_status(); + if (buttons & PLUGIN_QUIT) + return; + + switch (b) + { + case 0: + { + PC++; + /* Force break. */ + +#ifdef DEBUG + if (verflg) + { + printf ("BRK %ld\n", clk); + show (); + } +#endif + + SET_BREAK (1); /* Set break status. */ + PUSH (UPPER (PC)); + PUSH (LOWER (PC)); /* Push return address into the stack. */ + PUSH (GET_SR ()); /* Push status register into the stack. */ + SET_INTERRUPT (1); /* Disable interrupts. */ + PC = LOAD_ADDR ((ADDRESS) 65534); /* Jump using BRK vector (0xfffe). */ + clkcount = 7; + } + break; + + case 1: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1 + XR)); + PC += 2; + + src |= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 6; + } + + break; + + case 2: + { + PC++; + /* No such opcode. */ + (void) printf ("Illegal instruction.\n"); + verflg = 1; + --PC; + show (); + mon (PC); + } + + break; + + case 3: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1 + XR)); + PC += 2; + + /* src = asl(src); AC = ora(src); */ + + SET_CARRY (src & 0x80); /* ASL+ORA */ + src <<= 1; + src |= AC; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE (LOAD_ZERO_ADDR (p1 + XR), (src));; + clkcount = 8; + } + + break; + + case 4: + { + PC += 2; + + clkcount = 3; + } + + break; + + case 5: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + src |= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 3; + } + + break; + + case 6: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + SET_CARRY (src & 0x80); + src <<= 1; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE_ZERO (p1, (src));; + clkcount = 5; + } + + break; + + case 7: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + /* src = asl(src); AC = ora(src); */ + + SET_CARRY (src & 0x80); /* ASL+ORA */ + src <<= 1; + src |= AC; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE_ZERO (p1, (src));; + clkcount = 5; + } + + break; + + case 8: + { + register unsigned src = GET_SR (); + PC++; + + PUSH (src); + /* First push item onto stack and then decrement SP. */ + clkcount = 3; + } + + break; + + case 9: + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + PC += 2; + + src |= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 2; + } + + break; + + case 10: + { + register unsigned src = AC; + PC++; + + SET_CARRY (src & 0x80); + src <<= 1; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 2; + } + + break; + + case 11: + { + register p1 = LOAD (PC + 1); + register unsigned src = (AC & p1); + PC += 2; + + src &= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 2; + } + + break; + + case 12: + { + PC += 3; + + clkcount = 4; + } + + break; + + case 13: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + src |= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 4; + } + + break; + + case 14: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + SET_CARRY (src & 0x80); + src <<= 1; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2, (src));; + clkcount = 6; + } + + break; + + case 15: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + /* src = asl(src); AC = ora(src); */ + + SET_CARRY (src & 0x80); /* ASL+ORA */ + src <<= 1; + src |= AC; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2, (src));; + clkcount = 6; + } + + break; + + case 16: +/* BPL, RELATIVE */ + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + register BYTE hb; + PC += 2; + /* Branch if sign flag is clear. */ + if (!IF_SIGN ()) + { + hb = UPPER (PC); + PC = REL_ADDR (PC, src); + if (brtest (hb)) + /* Same page */ + clkcount = 3; + else + /* Different page */ + clkcount = 4; + } + else + clkcount = 2; + } + + break; + + case 17: +/* ORA, INDIRECT_Y */ + { + register p1 = LOAD (PC + 1); + register ADDRESS p2 = LOAD_ZERO_ADDR (p1); + register unsigned src = LOAD (p2 + YR); + PC += 2; + + /* If low byte of address + index reg is > 0xff then extra cycle */ + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 6; + else + /* Same page */ + clkcount = 5; + src |= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + } + + break; + + case 18: + { + PC++; + /* No such opcode. */ + (void) printf ("Illegal instruction.\n"); + verflg = 1; + --PC; + show (); + mon (PC); + } + + break; + + case 19: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1) + YR); + PC += 2; + + /* src = asl(src); AC = ora(src); */ + + SET_CARRY (src & 0x80); /* ASL+ORA */ + src <<= 1; + src |= AC; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE (LOAD_ZERO_ADDR (p1) + YR, (src));; + clkcount = 8; + } + + break; + + case 20: + { + PC += 2; + + clkcount = 4; + } + + break; + + case 21: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + src |= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 4; + } + + break; + + case 22: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + SET_CARRY (src & 0x80); + src <<= 1; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE_ZERO (p1 + XR, (src));; + clkcount = 6; + } + + break; + + case 23: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + /* src = asl(src); AC = ora(src); */ + + SET_CARRY (src & 0x80); /* ASL+ORA */ + src <<= 1; + src |= AC; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE_ZERO (p1 + XR, (src));; + clkcount = 6; + } + + break; + + case 24: + { + PC++; + + + SET_CARRY ((0));; + clkcount = 2; + } + + break; + + case 25: +/* ORA, ABSOLUTE_Y */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + PC += 3; + + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + src |= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + } + + break; + + case 26: + { + PC++; + + clkcount = 2; + } + + break; + + case 27: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + PC += 3; + + /* src = asl(src); AC = ora(src); */ + + SET_CARRY (src & 0x80); /* ASL+ORA */ + src <<= 1; + src |= AC; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2 + YR, (src));; + clkcount = 7; + } + + break; + + case 28: + { + PC += 3; + + clkcount = 4; + } + + break; + + case 29: +/* ORA, ABSOLUTE_X */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + + if (pagetest (p2, XR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + src |= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + } + + break; + + case 30: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + + SET_CARRY (src & 0x80); + src <<= 1; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2 + XR, (src));; + clkcount = 7; + } + + break; + + case 31: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + + /* src = asl(src); AC = ora(src); */ + + SET_CARRY (src & 0x80); /* ASL+ORA */ + src <<= 1; + src |= AC; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2 + XR, (src));; + clkcount = 7; + } + + break; + + case 32: + { + register p2 = load_abs_addr (); + register unsigned src = p2; + PC += 3; + /* Jump to subroutine. */ + PC--; + PUSH ((PC >> 8) & 0xff); /* Push return address onto the stack. */ + PUSH (PC & 0xff); + +#ifdef DEBUG + if (traceflg) + print_stack (SP); +#endif + + + PC = (src);; + clkcount = 6; + } + + break; + + case 33: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1 + XR)); + PC += 2; + + src &= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 6; + } + + break; + + case 34: + { + PC++; + /* No such opcode. */ + (void) printf ("Illegal instruction.\n"); + verflg = 1; + --PC; + show (); + mon (PC); + } + + break; + + case 35: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1 + XR)); + PC += 2; + + /* src = rol(src); AC = and(src); */ + + src <<= 1; + if (IF_CARRY ()) /* ROL+AND */ + src |= 0x1; + SET_CARRY (src > 0xff); + src &= 0xff; + + AC &= src; + SET_SIGN (AC); + SET_ZERO (AC); + /* rotated, not disturbed */ + STORE (LOAD_ZERO_ADDR (p1 + XR), (src));; + clkcount = 8; + } + + break; + + case 36: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + SET_SIGN (src); + SET_OVERFLOW (0x40 & src); /* Copy bit 6 to OVERFLOW flag. */ + SET_ZERO (src & AC); + clkcount = 3; + } + + break; + + case 37: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + src &= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 3; + } + + break; + + case 38: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + src <<= 1; + if (IF_CARRY ()) + src |= 0x1; + SET_CARRY (src > 0xff); + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE_ZERO (p1, (src));; + clkcount = 5; + } + + break; + + case 39: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + /* src = rol(src); AC = and(src); */ + + src <<= 1; + if (IF_CARRY ()) /* ROL+AND */ + src |= 0x1; + SET_CARRY (src > 0xff); + src &= 0xff; + + AC &= src; + SET_SIGN (AC); + SET_ZERO (AC); + /* rotated, not disturbed */ + STORE_ZERO (p1, (src));; + clkcount = 5; + } + + break; + + case 40: + { + register unsigned src; + PC++; + + /* First increment stack pointer and then pull item from stack. */ + src = PULL (); + + SET_SR ((src));; + clkcount = 4; + } + + break; + + case 41: + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + PC += 2; + + src &= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 2; + } + + break; + + case 42: + { + register unsigned src = AC; + PC++; + + src <<= 1; + if (IF_CARRY ()) + src |= 0x1; + SET_CARRY (src > 0xff); + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 2; + } + + break; + + case 43: + { + register p1 = LOAD (PC + 1); + register unsigned src = (AC & p1); + PC += 2; + + src &= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 2; + } + + break; + + case 44: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + SET_SIGN (src); + SET_OVERFLOW (0x40 & src); /* Copy bit 6 to OVERFLOW flag. */ + SET_ZERO (src & AC); + clkcount = 4; + } + + break; + + case 45: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + src &= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 4; + } + + break; + + case 46: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + src <<= 1; + if (IF_CARRY ()) + src |= 0x1; + SET_CARRY (src > 0xff); + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2, (src));; + clkcount = 6; + } + + break; + + case 47: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + /* src = rol(src); AC = and(src); */ + + src <<= 1; + if (IF_CARRY ()) /* ROL+AND */ + src |= 0x1; + SET_CARRY (src > 0xff); + src &= 0xff; + + AC &= src; + SET_SIGN (AC); + SET_ZERO (AC); + /* rotated, not disturbed */ + STORE (p2, (src));; + clkcount = 6; + } + + break; + + case 48: +/* BMI, RELATIVE */ + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + register BYTE hb; + PC += 2; + /* Branch if sign flag is set. */ + if (IF_SIGN ()) + { + hb = UPPER (PC); + PC = REL_ADDR (PC, src); + if (brtest (hb)) + /* Same page */ + clkcount = 3; + else + /* Different page */ + clkcount = 4; + } + else + clkcount = 2; + } + + break; + + case 49: +/* AND, INDIRECT_Y */ + { + register p1 = LOAD (PC + 1); + register ADDRESS p2 = LOAD_ZERO_ADDR (p1); + register unsigned src = LOAD (p2 + YR); + PC += 2; + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 6; + else + /* Same page */ + clkcount = 5; + + src &= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + } + + break; + + case 50: + { + PC++; + /* No such opcode. */ + (void) printf ("Illegal instruction.\n"); + verflg = 1; + --PC; + show (); + mon (PC); + } + + break; + + case 51: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1) + YR); + PC += 2; + + /* src = rol(src); AC = and(src); */ + + src <<= 1; + if (IF_CARRY ()) /* ROL+AND */ + src |= 0x1; + SET_CARRY (src > 0xff); + src &= 0xff; + + AC &= src; + SET_SIGN (AC); + SET_ZERO (AC); + /* rotated, not disturbed */ + STORE (LOAD_ZERO_ADDR (p1) + YR, (src));; + clkcount = 8; + } + + break; + + case 52: + { + PC += 2; + + clkcount = 4; + } + + break; + + case 53: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + src &= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 4; + } + + break; + + case 54: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + src <<= 1; + if (IF_CARRY ()) + src |= 0x1; + SET_CARRY (src > 0xff); + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE_ZERO (p1 + XR, (src));; + clkcount = 6; + } + + break; + + case 55: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + /* src = rol(src); AC = and(src); */ + + src <<= 1; + if (IF_CARRY ()) /* ROL+AND */ + src |= 0x1; + SET_CARRY (src > 0xff); + src &= 0xff; + + AC &= src; + SET_SIGN (AC); + SET_ZERO (AC); + /* rotated, not disturbed */ + STORE_ZERO (p1 + XR, (src));; + clkcount = 6; + } + + break; + + case 56: + { + PC++; + + + SET_CARRY ((1));; + clkcount = 2; + } + + break; + + case 57: +/* AND, ABSOLUTE_Y */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + PC += 3; + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + src &= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src); + } + + break; + + case 58: + { + PC++; + + clkcount = 2; + } + + break; + + case 59: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + PC += 3; + + /* src = rol(src); AC = and(src); */ + + src <<= 1; + if (IF_CARRY ()) /* ROL+AND */ + src |= 0x1; + SET_CARRY (src > 0xff); + src &= 0xff; + + AC &= src; + SET_SIGN (AC); + SET_ZERO (AC); + /* rotated, not disturbed */ + STORE (p2 + YR, (src));; + clkcount = 7; + } + + break; + + case 60: + { + PC += 3; + + clkcount = 4; + } + + break; + + case 61: +/* AND, ABSOLUTE_X */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + if (pagetest (p2, XR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + src &= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + } + + break; + + case 62: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + + src <<= 1; + if (IF_CARRY ()) + src |= 0x1; + SET_CARRY (src > 0xff); + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2 + XR, (src));; + clkcount = 7; + } + + break; + + case 63: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + + /* src = rol(src); AC = and(src); */ + + src <<= 1; + if (IF_CARRY ()) /* ROL+AND */ + src |= 0x1; + SET_CARRY (src > 0xff); + src &= 0xff; + + AC &= src; + SET_SIGN (AC); + SET_ZERO (AC); + /* rotated, not disturbed */ + STORE (p2 + XR, (src));; + clkcount = 7; + } + + break; + + case 64: + { + register unsigned src; + PC++; + /* Return from interrupt. */ + /* Load program status and program counter from stack. */ + src = PULL (); + SET_SR (src); + src = PULL (); + src |= (PULL () << 8); /* Load return address from stack. */ + +#ifdef DEBUG + if (traceflg) + print_stack (SP); +#endif + + + PC = (src);; + clkcount = 6; + } + + break; + + case 65: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1 + XR)); + PC += 2; + + src ^= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src & 0xff);; + clkcount = 6; + } + + break; + + case 66: + { + PC++; + /* No such opcode. */ + (void) printf ("Illegal instruction.\n"); + verflg = 1; + --PC; + show (); + mon (PC); + } + + break; + + case 67: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1 + XR)); + PC += 2; + + /* src = lsr(src); AC = eor(src); */ + + SET_CARRY (src & 0x01); /* LSR+EOR */ + src >>= 1; + src ^= AC; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + + STORE (LOAD_ZERO_ADDR (p1 + XR), (src));; + clkcount = 8; + } + + break; + + case 68: + { + PC += 2; + + clkcount = 3; + } + + break; + + case 69: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + src ^= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src & 0xff);; + clkcount = 3; + } + + break; + + case 70: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + SET_CARRY (src & 0x01); + src >>= 1; + + SET_SIGN (src); + SET_ZERO (src); + + STORE_ZERO (p1, (src));; + clkcount = 5; + } + + break; + + case 71: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + /* src = lsr(src); AC = eor(src); */ + + SET_CARRY (src & 0x01); /* LSR+EOR */ + src >>= 1; + src ^= AC; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + + STORE_ZERO (p1, (src));; + clkcount = 5; + } + + break; + + case 72: +/* PHA, IMPLIED */ + { + register unsigned src = AC; + PC++; + + beamadj = BEAMNINE; + PUSH (src); + /* First push item onto stack and then decrement SP. */ + clkcount = 3; + } + + break; + + case 73: + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + PC += 2; + + src ^= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src & 0xff);; + clkcount = 2; + } + + break; + + case 74: + { + register unsigned src = AC; + PC++; + + SET_CARRY (src & 0x01); + src >>= 1; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 2; + } + + break; + + case 75: + { + register p1 = LOAD (PC + 1); + register unsigned src = (AC & p1); + PC += 2; + + SET_CARRY (src & 0x01); + src >>= 1; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 2; + } + + break; + + case 76: + { + register p2 = load_abs_addr (); + register unsigned src = p2; + PC += 3; + + + PC = (src);; + clkcount = 3; + } + + break; + + case 77: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + src ^= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src & 0xff);; + clkcount = 4; + } + + break; + + case 78: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + SET_CARRY (src & 0x01); + src >>= 1; + + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2, (src));; + clkcount = 6; + } + + break; + + case 79: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + /* src = lsr(src); AC = eor(src); */ + + SET_CARRY (src & 0x01); /* LSR+EOR */ + src >>= 1; + src ^= AC; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + + STORE (p2, (src));; + clkcount = 6; + } + + break; + + case 80: +/* BVC, RELATIVE */ + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + register BYTE hb; + PC += 2; + /* Branch if overflow flag is clear. */ + if (!IF_OVERFLOW ()) + { + hb = UPPER (PC); + PC = REL_ADDR (PC, src); + if (brtest (hb)) + /* Same page */ + clkcount = 3; + else + /* Different page */ + clkcount = 4; + } + else + clkcount = 2; + } + + break; + + case 81: +/* EOR, INDIRECT_Y */ + { + register p1 = LOAD (PC + 1); + register p2 = LOAD_ZERO_ADDR (p1); + register unsigned src = LOAD (p2 + YR); + PC += 2; + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 6; + else + /* Same page */ + clkcount = 5; + + src ^= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src & 0xff);; + } + + break; + + case 82: + { + PC++; + /* No such opcode. */ + (void) printf ("Illegal instruction.\n"); + verflg = 1; + --PC; + show (); + mon (PC); + } + + break; + + case 83: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1) + YR); + PC += 2; + + /* src = lsr(src); AC = eor(src); */ + + SET_CARRY (src & 0x01); /* LSR+EOR */ + src >>= 1; + src ^= AC; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + + STORE (LOAD_ZERO_ADDR (p1) + YR, (src));; + clkcount = 8; + } + + break; + + case 84: + { + PC += 2; + + clkcount = 4; + } + + break; + + case 85: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + src ^= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src & 0xff);; + clkcount = 4; + } + + break; + + case 86: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + SET_CARRY (src & 0x01); + src >>= 1; + + SET_SIGN (src); + SET_ZERO (src); + + STORE_ZERO (p1 + XR, (src));; + clkcount = 6; + } + + break; + + case 87: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + /* src = lsr(src); AC = eor(src); */ + + SET_CARRY (src & 0x01); /* LSR+EOR */ + src >>= 1; + src ^= AC; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + + STORE_ZERO (p1 + XR, (src));; + clkcount = 6; + } + + break; + + case 88: + { + PC++; + + + SET_INTERRUPT ((0));; + clkcount = 2; + } + + break; + + case 89: +/* EOR, ABSOLUTE_Y */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + PC += 3; + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + src ^= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src & 0xff); + } + + break; + + case 90: + { + PC++; + + clkcount = 2; + } + + break; + + case 91: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + PC += 3; + + /* src = lsr(src); AC = eor(src); */ + + SET_CARRY (src & 0x01); /* LSR+EOR */ + src >>= 1; + src ^= AC; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + + STORE (p2 + YR, (src));; + clkcount = 7; + } + + break; + + case 92: + { + PC += 3; + + clkcount = 4; + } + + break; + + case 93: +/* EOR, ABSOLUTE_X */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + if (pagetest (p2, XR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + src ^= AC; + SET_SIGN (src); + SET_ZERO (src); + + AC = (src & 0xff);; + } + + break; + + case 94: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + + SET_CARRY (src & 0x01); + src >>= 1; + + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2 + XR, (src));; + clkcount = 7; + } + + break; + + case 95: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + + /* src = lsr(src); AC = eor(src); */ + + SET_CARRY (src & 0x01); /* LSR+EOR */ + src >>= 1; + src ^= AC; + src &= 0xff; + SET_SIGN (src); + SET_ZERO (src); + + + STORE (p2 + XR, (src));; + clkcount = 7; + } + + break; + + case 96: + { + register unsigned src; + PC++; + /* Return from subroutine. */ + src = PULL (); + src += ((PULL ()) << 8) + 1; /* Load return address from stack and add 1. */ + +#ifdef DEBUG + if (traceflg) + print_stack (SP); +#endif + + + PC = (src);; + clkcount = 6; + } + + break; + + case 97: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1 + XR)); + register unsigned int temp = src + AC + (IF_CARRY ()? 1 : 0); + PC += 2; + + + SET_ZERO (temp & 0xff); /* This is not valid in decimal mode */ + + /* + * In decimal mode this is "correct" but not exact emulation. However, + * the probability of different result when using undefined BCD codes is + * less than 6% + * Sign and Overflow are set between BCD fixup of the two digits -MSM + */ + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (src & 0xf) + (IF_CARRY ()? 1 : 0)) > 9) + temp += 6; + + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + + if (temp > 0x99) + temp += 96; + + SET_CARRY (temp > 0x99); + } + else + { + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + SET_CARRY (temp > 0xff); + } + + AC = ((BYTE) temp);; + clkcount = 6; + } + + break; + + case 98: + { + PC++; + /* No such opcode. */ + (void) printf ("Illegal instruction.\n"); + verflg = 1; + --PC; + show (); + mon (PC); + } + + break; + + case 99: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1 + XR)); + register unsigned int temp; + PC += 2; + + + /* src = ror(src); AC = adc(src); + * the real operation discovered by msmakela + * ADC only does the BCD fixup */ + + temp = src >> 1; /* ROR+ADC */ + if (IF_CARRY ()) + temp |= 0x80; + + SET_SIGN (temp); + SET_ZERO (temp); /* Set flags like ROR does */ + + SET_OVERFLOW ((temp ^ src) & 0x40); /* ROR causes this ? */ + + if (IF_DECIMAL ()) + { + if ((src & 0x0f) > 4) /* half of the normal */ + temp = (temp & 0xf0) | ((temp + 6) & 0xf); + if (src > 0x4f) + temp += 96; + + SET_CARRY (src > 0x4f); + } + else + { + SET_CARRY (src & 0x80); /* 8502 behaviour */ + } + + + STORE (LOAD_ZERO_ADDR (p1 + XR), ((BYTE) temp));; + clkcount = 8; + } + + break; + + case 100: + { + PC += 2; + + clkcount = 3; + } + + break; + + case 101: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + register unsigned int temp = src + AC + (IF_CARRY ()? 1 : 0); + PC += 2; + + + SET_ZERO (temp & 0xff); /* This is not valid in decimal mode */ + + /* + * In decimal mode this is "correct" but not exact emulation. However, + * the probability of different result when using undefined BCD codes is + * less than 6% + * Sign and Overflow are set between BCD fixup of the two digits -MSM + */ + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (src & 0xf) + (IF_CARRY ()? 1 : 0)) > 9) + temp += 6; + + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + + if (temp > 0x99) + temp += 96; + + SET_CARRY (temp > 0x99); + } + else + { + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + SET_CARRY (temp > 0xff); + } + + AC = ((BYTE) temp);; + clkcount = 3; + } + + break; + + case 102: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + if (IF_CARRY ()) + src |= 0x100; + SET_CARRY (src & 0x01); + src >>= 1; + + SET_SIGN (src); + SET_ZERO (src); + + STORE_ZERO (p1, (src));; + clkcount = 5; + } + + break; + + case 103: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + register unsigned int temp; + PC += 2; + + + /* src = ror(src); AC = adc(src); + * the real operation discovered by msmakela + * ADC only does the BCD fixup */ + + temp = src >> 1; /* ROR+ADC */ + if (IF_CARRY ()) + temp |= 0x80; + + SET_SIGN (temp); + SET_ZERO (temp); /* Set flags like ROR does */ + + SET_OVERFLOW ((temp ^ src) & 0x40); /* ROR causes this ? */ + + if (IF_DECIMAL ()) + { + if ((src & 0x0f) > 4) /* half of the normal */ + temp = (temp & 0xf0) | ((temp + 6) & 0xf); + if (src > 0x4f) + temp += 96; + + SET_CARRY (src > 0x4f); + } + else + { + SET_CARRY (src & 0x80); /* 8502 behaviour */ + } + + + STORE_ZERO (p1, ((BYTE) temp));; + clkcount = 5; + } + + break; + + case 104: +/* PLA, IMPLIED */ + { + register unsigned src; + PC++; + + clkcount = 4; + /* First increment stack pointer and then pull item from stack. */ + src = PULL (); + SET_SIGN (src); /* Change sign and zero flag accordingly. */ + SET_ZERO (src); + + AC = (src); + } + + break; + + case 105: + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + register unsigned int temp = src + AC + (IF_CARRY ()? 1 : 0); + PC += 2; + + + SET_ZERO (temp & 0xff); /* This is not valid in decimal mode */ + + /* + * In decimal mode this is "correct" but not exact emulation. However, + * the probability of different result when using undefined BCD codes is + * less than 6% + * Sign and Overflow are set between BCD fixup of the two digits -MSM + */ + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (src & 0xf) + (IF_CARRY ()? 1 : 0)) > 9) + temp += 6; + + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + + if (temp > 0x99) + temp += 96; + + SET_CARRY (temp > 0x99); + } + else + { + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + SET_CARRY (temp > 0xff); + } + + AC = ((BYTE) temp);; + clkcount = 2; + } + + break; + + case 106: + { + register unsigned src = AC; + PC++; + + if (IF_CARRY ()) + src |= 0x100; + SET_CARRY (src & 0x01); + src >>= 1; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 2; + } + + break; + + case 107: + { + register p1 = LOAD (PC + 1); + register unsigned src = (AC & p1); + PC += 2; + + if (IF_CARRY ()) + src |= 0x100; + SET_CARRY (src & 0x01); + src >>= 1; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 2; + } + + break; + + case 108: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD_ADDR (p2); + PC += 3; + + + PC = (src);; + clkcount = 5; + } + + break; + + case 109: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + register unsigned int temp = src + AC + (IF_CARRY ()? 1 : 0); + PC += 3; + + + SET_ZERO (temp & 0xff); /* This is not valid in decimal mode */ + + /* + * In decimal mode this is "correct" but not exact emulation. However, + * the probability of different result when using undefined BCD codes is + * less than 6% + * Sign and Overflow are set between BCD fixup of the two digits -MSM + */ + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (src & 0xf) + (IF_CARRY ()? 1 : 0)) > 9) + temp += 6; + + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + + if (temp > 0x99) + temp += 96; + + SET_CARRY (temp > 0x99); + } + else + { + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + SET_CARRY (temp > 0xff); + } + + AC = ((BYTE) temp);; + clkcount = 4; + } + + break; + + case 110: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + if (IF_CARRY ()) + src |= 0x100; + SET_CARRY (src & 0x01); + src >>= 1; + + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2, (src));; + clkcount = 6; + } + + break; + + case 111: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + register unsigned int temp; + PC += 3; + + + /* src = ror(src); AC = adc(src); + * the real operation discovered by msmakela + * ADC only does the BCD fixup */ + + temp = src >> 1; /* ROR+ADC */ + if (IF_CARRY ()) + temp |= 0x80; + + SET_SIGN (temp); + SET_ZERO (temp); /* Set flags like ROR does */ + + SET_OVERFLOW ((temp ^ src) & 0x40); /* ROR causes this ? */ + + if (IF_DECIMAL ()) + { + if ((src & 0x0f) > 4) /* half of the normal */ + temp = (temp & 0xf0) | ((temp + 6) & 0xf); + if (src > 0x4f) + temp += 96; + + SET_CARRY (src > 0x4f); + } + else + { + SET_CARRY (src & 0x80); /* 8502 behaviour */ + } + + + STORE (p2, ((BYTE) temp));; + clkcount = 6; + } + + break; + + case 112: +/* BVS, RELATIVE */ + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + register BYTE hb; + PC += 2; + /* Branch if overflow flag is set. */ + if (IF_OVERFLOW ()) + { + hb = UPPER (PC); + PC = REL_ADDR (PC, src); + if (brtest (hb)) + /* Same page */ + clkcount = 3; + else + /* Different page */ + clkcount = 4; + } + else + clkcount = 2; + } + + break; + + case 113: + { + register p1 = LOAD (PC + 1); + register ADDRESS p2 = LOAD_ZERO_ADDR (p1); + register unsigned src = LOAD (p2 + YR); + register unsigned int temp = src + AC + (IF_CARRY ()? 1 : 0); + PC += 2; + + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 6; + else + /* Same page */ + clkcount = 5; + + SET_ZERO (temp & 0xff); /* This is not valid in decimal mode */ + + /* + * In decimal mode this is "correct" but not exact emulation. However, + * the probability of different result when using undefined BCD codes is + * less than 6% + * Sign and Overflow are set between BCD fixup of the two digits -MSM + */ + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (src & 0xf) + (IF_CARRY ()? 1 : 0)) > 9) + temp += 6; + + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + + if (temp > 0x99) + temp += 96; + + SET_CARRY (temp > 0x99); + } + else + { + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + SET_CARRY (temp > 0xff); + } + + AC = ((BYTE) temp); + } + + break; + + case 114: + { + PC++; + /* No such opcode. */ + (void) printf ("Illegal instruction.\n"); + verflg = 1; + --PC; + show (); + mon (PC); + } + + break; + + case 115: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1) + YR); + register unsigned int temp; + PC += 2; + + + /* src = ror(src); AC = adc(src); + * the real operation discovered by msmakela + * ADC only does the BCD fixup */ + + temp = src >> 1; /* ROR+ADC */ + if (IF_CARRY ()) + temp |= 0x80; + + SET_SIGN (temp); + SET_ZERO (temp); /* Set flags like ROR does */ + + SET_OVERFLOW ((temp ^ src) & 0x40); /* ROR causes this ? */ + + if (IF_DECIMAL ()) + { + if ((src & 0x0f) > 4) /* half of the normal */ + temp = (temp & 0xf0) | ((temp + 6) & 0xf); + if (src > 0x4f) + temp += 96; + + SET_CARRY (src > 0x4f); + } + else + { + SET_CARRY (src & 0x80); /* 8502 behaviour */ + } + + + STORE (LOAD_ZERO_ADDR (p1) + YR, ((BYTE) temp));; + clkcount = 8; + } + + break; + + case 116: + { + PC += 2; + + clkcount = 4; + } + + break; + + case 117: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + register unsigned int temp = src + AC + (IF_CARRY ()? 1 : 0); + PC += 2; + + + SET_ZERO (temp & 0xff); /* This is not valid in decimal mode */ + + /* + * In decimal mode this is "correct" but not exact emulation. However, + * the probability of different result when using undefined BCD codes is + * less than 6% + * Sign and Overflow are set between BCD fixup of the two digits -MSM + */ + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (src & 0xf) + (IF_CARRY ()? 1 : 0)) > 9) + temp += 6; + + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + + if (temp > 0x99) + temp += 96; + + SET_CARRY (temp > 0x99); + } + else + { + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + SET_CARRY (temp > 0xff); + } + + AC = ((BYTE) temp);; + clkcount = 4; + } + + break; + + case 118: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + if (IF_CARRY ()) + src |= 0x100; + SET_CARRY (src & 0x01); + src >>= 1; + + SET_SIGN (src); + SET_ZERO (src); + + STORE_ZERO (p1 + XR, (src));; + clkcount = 6; + } + + break; + + case 119: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + register unsigned int temp; + PC += 2; + + + /* src = ror(src); AC = adc(src); + * the real operation discovered by msmakela + * ADC only does the BCD fixup */ + + temp = src >> 1; /* ROR+ADC */ + if (IF_CARRY ()) + temp |= 0x80; + + SET_SIGN (temp); + SET_ZERO (temp); /* Set flags like ROR does */ + + SET_OVERFLOW ((temp ^ src) & 0x40); /* ROR causes this ? */ + + if (IF_DECIMAL ()) + { + if ((src & 0x0f) > 4) /* half of the normal */ + temp = (temp & 0xf0) | ((temp + 6) & 0xf); + if (src > 0x4f) + temp += 96; + + SET_CARRY (src > 0x4f); + } + else + { + SET_CARRY (src & 0x80); /* 8502 behaviour */ + } + + + STORE_ZERO (p1 + XR, ((BYTE) temp));; + clkcount = 6; + } + + break; + + case 120: + { + PC++; + + + SET_INTERRUPT ((1));; + clkcount = 2; + } + + break; + + case 121: +/* ADC, ABSOLUTE_Y */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + register unsigned int temp = src + AC + (IF_CARRY ()? 1 : 0); + PC += 3; + + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + SET_ZERO (temp & 0xff); /* This is not valid in decimal mode */ + + /* + * In decimal mode this is "correct" but not exact emulation. However, + * the probability of different result when using undefined BCD codes is + * less than 6% + * Sign and Overflow are set between BCD fixup of the two digits -MSM + */ + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (src & 0xf) + (IF_CARRY ()? 1 : 0)) > 9) + temp += 6; + + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + + if (temp > 0x99) + temp += 96; + + SET_CARRY (temp > 0x99); + } + else + { + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + SET_CARRY (temp > 0xff); + } + + AC = ((BYTE) temp); + } + + break; + + case 122: + { + PC++; + + clkcount = 2; + } + + break; + + case 123: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + register unsigned int temp; + PC += 3; + + + /* src = ror(src); AC = adc(src); + * the real operation discovered by msmakela + * ADC only does the BCD fixup */ + + temp = src >> 1; /* ROR+ADC */ + if (IF_CARRY ()) + temp |= 0x80; + + SET_SIGN (temp); + SET_ZERO (temp); /* Set flags like ROR does */ + + SET_OVERFLOW ((temp ^ src) & 0x40); /* ROR causes this ? */ + + if (IF_DECIMAL ()) + { + if ((src & 0x0f) > 4) /* half of the normal */ + temp = (temp & 0xf0) | ((temp + 6) & 0xf); + if (src > 0x4f) + temp += 96; + + SET_CARRY (src > 0x4f); + } + else + { + SET_CARRY (src & 0x80); /* 8502 behaviour */ + } + + + STORE (p2 + YR, ((BYTE) temp));; + clkcount = 7; + } + + break; + + case 124: + { + PC += 3; + + clkcount = 4; + } + + break; + + case 125: +/* ADC, ABSOLUTE_X */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + register unsigned int temp = src + AC + (IF_CARRY ()? 1 : 0); + PC += 3; + + if (pagetest (p2, XR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + SET_ZERO (temp & 0xff); /* This is not valid in decimal mode */ + + /* + * In decimal mode this is "correct" but not exact emulation. However, + * the probability of different result when using undefined BCD codes is + * less than 6% + * Sign and Overflow are set between BCD fixup of the two digits -MSM + */ + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (src & 0xf) + (IF_CARRY ()? 1 : 0)) > 9) + temp += 6; + + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + + if (temp > 0x99) + temp += 96; + + SET_CARRY (temp > 0x99); + } + else + { + SET_SIGN (temp); + SET_OVERFLOW (!((AC ^ src) & 0x80) && ((AC ^ temp) & 0x80)); + SET_CARRY (temp > 0xff); + } + + AC = ((BYTE) temp); + } + + break; + + case 126: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + + if (IF_CARRY ()) + src |= 0x100; + SET_CARRY (src & 0x01); + src >>= 1; + + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2 + XR, (src));; + clkcount = 7; + } + + break; + + case 127: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + register unsigned int temp; + PC += 3; + + + /* src = ror(src); AC = adc(src); + * the real operation discovered by msmakela + * ADC only does the BCD fixup */ + + temp = src >> 1; /* ROR+ADC */ + if (IF_CARRY ()) + temp |= 0x80; + + SET_SIGN (temp); + SET_ZERO (temp); /* Set flags like ROR does */ + + SET_OVERFLOW ((temp ^ src) & 0x40); /* ROR causes this ? */ + + if (IF_DECIMAL ()) + { + if ((src & 0x0f) > 4) /* half of the normal */ + temp = (temp & 0xf0) | ((temp + 6) & 0xf); + if (src > 0x4f) + temp += 96; + + SET_CARRY (src > 0x4f); + } + else + { + SET_CARRY (src & 0x80); /* 8502 behaviour */ + } + + + STORE (p2 + XR, ((BYTE) temp));; + clkcount = 7; + } + + break; + + case 128: + { + PC += 2; + + clkcount = 2; + } + + break; + + case 129: + { + register p1 = LOAD (PC + 1); + register unsigned src = AC; + PC += 2; + + + STORE (LOAD_ZERO_ADDR (p1 + XR), (src));; + clkcount = 6; + } + + break; + + case 130: + { + PC += 2; + + clkcount = 2; + } + + break; + + case 131: + { + register p1 = LOAD (PC + 1); + register unsigned src = (AC & XR); + PC += 2; + + + STORE (LOAD_ZERO_ADDR (p1 + XR), (src));; + clkcount = 6; + } + + break; + + case 132: +/* STY, ZERO_PAGE */ + { + register p1 = LOAD (PC + 1); + register unsigned src = YR; + + clkcount = 3; + PC += 2; + + beamadj = BEAMNINE; + STORE_ZERO (p1, (src)); + } + + break; + + case 133: +/* STA, ZERO_PAGE */ + { + register p1 = LOAD (PC + 1); + register unsigned src = AC; + + clkcount = 3; + PC += 2; + + beamadj = BEAMNINE; + STORE_ZERO (p1, (src)); + } + + break; + + case 134: +/* STX, ZERO_PAGE */ + { + register p1 = LOAD (PC + 1); + register unsigned src = XR; + + clkcount = 3; + PC += 2; + + beamadj = BEAMNINE; + STORE_ZERO (p1, (src)); + } + + break; + + case 135: + { + register p1 = LOAD (PC + 1); + register unsigned src = (AC & XR); + PC += 2; + + + STORE_ZERO (p1, (src));; + clkcount = 3; + } + + break; + + case 136: + { + register unsigned src = YR; + PC++; + + src = (src - 1) & 0xff; + SET_SIGN (src); + SET_ZERO (src); + + YR = (src);; + clkcount = 2; + } + + break; + + case 137: + { + PC += 2; + + clkcount = 2; + } + + break; + + case 138: + { + register unsigned src = XR; + PC++; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 2; + } + + break; + + case 139: + { + register p1 = LOAD (PC + 1); + register unsigned src = ((AC | 0xee) & XR & p1); + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 2; + } + + break; + + case 140: +/* STY, ABSOLUTE */ + { + register p2 = load_abs_addr (); + register unsigned src = YR; + PC += 3; + + beamadj = BEAMTWELVE; + STORE (p2, (src));; + clkcount = 4; + } + + break; + + case 141: +/* STA, ABSOLUTE */ + { + register p2 = load_abs_addr (); + register unsigned src = AC; + PC += 3; + + beamadj = BEAMTWELVE; + STORE (p2, (src));; + clkcount = 4; + } + + break; + + case 142: +/* STA, ABSOLUTE */ + { + register p2 = load_abs_addr (); + register unsigned src = XR; + PC += 3; + + beamadj = BEAMTWELVE; + STORE (p2, (src));; + clkcount = 4; + } + + break; + + case 143: +/* STX, ABSOLUTE */ + { + register p2 = load_abs_addr (); + register unsigned src = (AC & XR); + PC += 3; + + beamadj = BEAMTWELVE; + STORE (p2, (src));; + clkcount = 4; + } + + break; + + case 144: +/* BCC, RELATIVE */ + { + register p1 = LOAD (PC + 1); + register hb; + register unsigned src = p1; + PC += 2; + /* Branch if carry flag is clear. */ + if (!IF_CARRY ()) + { + hb = UPPER (PC); + PC = REL_ADDR (PC, src); + if (brtest (hb)) + /* Same page */ + clkcount = 3; + else + /* Different page */ + clkcount = 4; + } + else + clkcount = 2; + } + + break; + + case 145: + { + register p1 = LOAD (PC + 1); + register unsigned src = AC; + PC += 2; + + + STORE (LOAD_ZERO_ADDR (p1) + YR, (src));; + clkcount = 6; + } + + break; + + case 146: + { + PC++; + /* No such opcode. */ + (void) printf ("Illegal instruction.\n"); + verflg = 1; + --PC; + show (); + mon (PC); + } + + break; + + case 147: + { + register p1 = LOAD (PC + 1); + register unsigned src = (AC & XR); + PC += 2; + + + u_stoshr (src, LOAD_ZERO_ADDR (p1), YR);; + clkcount = 6; + } + + break; + + case 148: + { + register p1 = LOAD (PC + 1); + register unsigned src = YR; + clkcount = 4; + PC += 2; + + beamadj = BEAMTWELVE; + STORE_ZERO (p1 + XR, (src)); + } + + break; + + case 149: +/* STA, ZERO_PAGE_X */ + { + register p1 = LOAD (PC + 1); + register unsigned src = AC; + clkcount = 4; + PC += 2; + + beamadj = BEAMTWELVE; + STORE_ZERO (p1 + XR, (src)); + } + + break; + + case 150: +/* STX, ZERO_PAGE_Y */ + { + register p1 = LOAD (PC + 1); + register unsigned src = XR; + clkcount = 4; + PC += 2; + + beamadj = BEAMTWELVE; + STORE_ZERO (p1 + YR, (src)); + } + + break; + + case 151: + { + register p1 = LOAD (PC + 1); + register unsigned src = (AC & XR); + PC += 2; + + + STORE_ZERO (p1 + YR, (src));; + clkcount = 4; + } + + break; + + case 152: + { + register unsigned src = YR; + PC++; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 2; + } + + break; + + case 153: + { + register p2 = load_abs_addr (); + register unsigned src = AC; + PC += 3; + + + STORE (p2 + YR, (src));; + clkcount = 5; + } + + break; + + case 154: + { + register unsigned src = XR; + PC++; + + + SP = (src);; + clkcount = 2; + } + + break; + + case 155: + { + register unsigned src = (AC & XR); + PC += 3; + + + SP = src; /* SHS */ ; + clkcount = 5; + } + + break; + + case 156: + { + register p2 = load_abs_addr (); + register unsigned src = YR; + PC += 3; + + + u_stoshr (src, p2, XR);; + clkcount = 5; + } + + break; + + case 157: + { + register p2 = load_abs_addr (); + register unsigned src = AC; + PC += 3; + + + STORE (p2 + XR, (src));; + clkcount = 5; + } + + break; + + case 158: + { + register p2 = load_abs_addr (); + register unsigned src = XR; + PC += 3; + + + u_stoshr (src, p2, YR);; + clkcount = 5; + } + + break; + + case 159: + { + register p2 = load_abs_addr (); + register unsigned src = (AC & XR); + PC += 3; + + + u_stoshr (src, p2, YR);; + clkcount = 5; + } + + break; + + case 160: + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + YR = (src);; + clkcount = 2; + } + + break; + + case 161: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1 + XR)); + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 6; + } + + break; + + case 162: + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + XR = (src);; + clkcount = 2; + } + + break; + + case 163: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1 + XR)); + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + AC = XR = (src);; + clkcount = 6; + } + + break; + + case 164: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + YR = (src);; + clkcount = 3; + } + + break; + + case 165: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 3; + } + + break; + + case 166: +/* LDX, ZERO_PAGE */ + { + register p1 = LOADEXEC (PC + 1); + register unsigned src = LOAD_ZERO (p1); + + clkcount = 3; + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + XR = (src); + } + + break; + + case 167: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + AC = XR = (src);; + clkcount = 3; + } + + break; + + case 168: + { + register unsigned src = AC; + PC++; + + SET_SIGN (src); + SET_ZERO (src); + + YR = (src);; + clkcount = 2; + } + + break; + + case 169: + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 2; + } + + break; + + case 170: + { + register unsigned src = AC; + PC++; + + SET_SIGN (src); + SET_ZERO (src); + + XR = (src);; + clkcount = 2; + } + + break; + + case 171: + { + register p1 = LOAD (PC + 1); + register unsigned src = (AC & p1); + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + AC = XR = (src);; + clkcount = 2; + } + + break; + + case 172: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + SET_SIGN (src); + SET_ZERO (src); + + YR = (src);; + clkcount = 4; + } + + break; + + case 173: /* LDA absolute */ + { + register p2 = load_abs_addr (); + register unsigned src; + clkcount = 4; + src = LOAD (p2); + PC += 3; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src); + } + + break; + + case 174: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + SET_SIGN (src); + SET_ZERO (src); + + XR = (src);; + clkcount = 4; + } + + break; + + case 175: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + SET_SIGN (src); + SET_ZERO (src); + + AC = XR = (src);; + clkcount = 4; + } + + break; + + case 176: +/* BCS, RELATIVE */ + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + register BYTE hb; + PC += 2; + /* Branch if carry flag is set. */ + if (IF_CARRY ()) + { + hb = UPPER (PC); + PC = REL_ADDR (PC, src); + if (brtest (hb)) + /* Same page */ + clkcount = 3; + else + /* Different page */ + clkcount = 4; + } + else + clkcount = 2; + } + + break; + + case 177: +/* LDA, INDIRECT_Y */ + { + register p1 = LOAD (PC + 1); + register ADDRESS p2 = LOAD_ZERO_ADDR (p1); + register unsigned src = LOAD (p2 + YR); + PC += 2; + + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 6; + else + /* Same page */ + clkcount = 5; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src); + } + + break; + + case 178: + { + PC++; + /* No such opcode. */ + (void) printf ("Illegal instruction.\n"); + verflg = 1; + --PC; + show (); + mon (PC); + } + + break; + + case 179: +/* LAX, INDIRECT_Y */ + { + register p1 = LOAD (PC + 1); + register ADDRESS p2 = LOAD_ZERO_ADDR (p1); + register unsigned src = LOAD (p2 + YR); + PC += 2; + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 6; + else + /* Same page */ + clkcount = 5; + + SET_SIGN (src); + SET_ZERO (src); + + AC = XR = (src); + } + + break; + + case 180: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + YR = (src);; + clkcount = 4; + } + + break; + + case 181: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src);; + clkcount = 4; + } + + break; + + case 182: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + YR); + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + XR = (src);; + clkcount = 4; + } + + break; + + case 183: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + YR); + PC += 2; + + SET_SIGN (src); + SET_ZERO (src); + + AC = XR = (src);; + clkcount = 4; + } + + break; + + case 184: + { + PC++; + + + SET_OVERFLOW ((0));; + clkcount = 2; + } + + break; + + case 185: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + PC += 3; + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src); + } + + break; + + case 186: + { + register unsigned src = SP; + PC++; + + SET_SIGN (src); + SET_ZERO (src); + + XR = (src);; + clkcount = 2; + } + + break; + + case 187: + { + register p2 = load_abs_addr (); + register unsigned src = (SP & LOAD (p2 + YR)); + PC += 3; + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + SET_SIGN (src); + SET_ZERO (src); + + AC = XR = SP = (src); + } + + break; + + case 188: +/* LDY, ABSOLUTE_X */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + if (pagetest (p2, XR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + + SET_SIGN (src); + SET_ZERO (src); + + YR = (src); + } + + break; + + case 189: +/* LDA, ABSOLUTE_X */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + + if (pagetest (p2, XR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + SET_SIGN (src); + SET_ZERO (src); + + AC = (src); + } + + break; + + case 190: +/* LDX, ABSOLUTE_Y */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + PC += 3; + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + SET_SIGN (src); + SET_ZERO (src); + + XR = (src); + } + + break; + + case 191: +/* LAX, ABSOLUTE_Y */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + PC += 3; + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + SET_SIGN (src); + SET_ZERO (src); + + AC = XR = (src); + } + + break; + + case 192: + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + PC += 2; + + src = YR - src; + SET_CARRY (src < 0x100); + SET_SIGN (src); + SET_ZERO (src &= 0xff); + clkcount = 2; + } + + break; + + case 193: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1 + XR)); + PC += 2; + + src = AC - src; + SET_CARRY (src < 0x100); + SET_SIGN (src); + SET_ZERO (src &= 0xff); + clkcount = 6; + } + + break; + + case 194: + { + PC += 2; + + clkcount = 2; + } + + break; + + case 195: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1 + XR)); + PC += 2; + + /* cmp(--src & 0xff)); */ + + src = (src - 1) & 0xff; /* DEC+CMP */ + SET_CARRY (AC >= src); + SET_SIGN (AC - src); + SET_ZERO (AC != src); + + STORE (LOAD_ZERO_ADDR (p1 + XR), (src));; + clkcount = 8; + } + + break; + + case 196: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + src = YR - src; + SET_CARRY (src < 0x100); + SET_SIGN (src); + SET_ZERO (src &= 0xff); + clkcount = 3; + } + + break; + + case 197: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + src = AC - src; + SET_CARRY (src < 0x100); + SET_SIGN (src); + SET_ZERO (src &= 0xff); + clkcount = 3; + } + + break; + + case 198: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + src = (src - 1) & 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE_ZERO (p1, (src));; + clkcount = 5; + } + + break; + + case 199: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + /* cmp(--src & 0xff)); */ + + src = (src - 1) & 0xff; /* DEC+CMP */ + SET_CARRY (AC >= src); + SET_SIGN (AC - src); + SET_ZERO (AC != src); + + STORE_ZERO (p1, (src));; + clkcount = 5; + } + + break; + + case 200: + { + register unsigned src = YR; + PC++; + + src = (src + 1) & 0xff; + SET_SIGN (src); + SET_ZERO (src); + + YR = (src);; + clkcount = 2; + } + + break; + + case 201: + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + PC += 2; + + src = AC - src; + SET_CARRY (src < 0x100); + SET_SIGN (src); + SET_ZERO (src &= 0xff); + clkcount = 2; + } + + break; + + case 202: + { + register unsigned src = XR; + PC++; + + src = (src - 1) & 0xff; + SET_SIGN (src); + SET_ZERO (src); + + XR = (src);; + clkcount = 2; + } + + break; + + case 203: + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + PC += 2; + + src = (AC & XR) - src; /* Carry is ignored (CMP) */ + /* Overflow flag may be affected */ + SET_CARRY (src < 0x100); + + src &= 0xff; /* No decimal mode */ + SET_SIGN (src); + SET_ZERO (src); + + XR = (src);; + clkcount = 2; + } + + break; + + case 204: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + src = YR - src; + SET_CARRY (src < 0x100); + SET_SIGN (src); + SET_ZERO (src &= 0xff); + clkcount = 4; + } + + break; + + case 205: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + src = AC - src; + SET_CARRY (src < 0x100); + SET_SIGN (src); + SET_ZERO (src &= 0xff); + clkcount = 4; + } + + break; + + case 206: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + src = (src - 1) & 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2, (src));; + clkcount = 6; + } + + break; + + case 207: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + /* cmp(--src & 0xff)); */ + + src = (src - 1) & 0xff; /* DEC+CMP */ + SET_CARRY (AC >= src); + SET_SIGN (AC - src); + SET_ZERO (AC != src); + + STORE (p2, (src));; + clkcount = 6; + } + + break; + + case 208: +/* BNE, RELATIVE */ + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + register BYTE hb; + PC += 2; + /* Branch if zero flag is clear. */ + if (!IF_ZERO ()) + { + hb = UPPER (PC); + PC = REL_ADDR (PC, src); + if (brtest (hb)) + /* Same page */ + clkcount = 3; + else + /* Different page */ + clkcount = 4; + } + else + clkcount = 2; + } + + break; + + case 209: +/* CMP, INDIRECT_Y */ + { + register p1 = LOAD (PC + 1); + register ADDRESS p2 = LOAD_ZERO_ADDR (p1); + register unsigned src = LOAD (p2 + YR); + PC += 2; + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 6; + else + /* Same page */ + clkcount = 5; + + src = AC - src; + SET_CARRY (src < 0x100); + SET_SIGN (src); + SET_ZERO (src &= 0xff); + } + + break; + + case 210: + { + PC++; + /* No such opcode. */ + (void) printf ("Illegal instruction.\n"); + verflg = 1; + --PC; + show (); + mon (PC); + } + + break; + + case 211: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1) + YR); + PC += 2; + + /* cmp(--src & 0xff)); */ + + src = (src - 1) & 0xff; /* DEC+CMP */ + SET_CARRY (AC >= src); + SET_SIGN (AC - src); + SET_ZERO (AC != src); + + STORE (LOAD_ZERO_ADDR (p1) + YR, (src));; + clkcount = 8; + } + + break; + + case 212: + { + PC += 2; + + clkcount = 4; + } + + break; + + case 213: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + src = AC - src; + SET_CARRY (src < 0x100); + SET_SIGN (src); + SET_ZERO (src &= 0xff); + clkcount = 4; + } + + break; + + case 214: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + src = (src - 1) & 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE_ZERO (p1 + XR, (src));; + clkcount = 6; + } + + break; + + case 215: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + /* cmp(--src & 0xff)); */ + + src = (src - 1) & 0xff; /* DEC+CMP */ + SET_CARRY (AC >= src); + SET_SIGN (AC - src); + SET_ZERO (AC != src); + + STORE_ZERO (p1 + XR, (src));; + clkcount = 6; + } + + break; + + case 216: + { + PC++; + + + SET_DECIMAL ((0));; + clkcount = 2; + } + + break; + + case 217: +/* CMP, ABSOLUTE_Y */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + PC += 3; + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + src = AC - src; + SET_CARRY (src < 0x100); + SET_SIGN (src); + SET_ZERO (src &= 0xff); + } + + break; + + case 218: + { + PC++; + + clkcount = 2; + } + + break; + + case 219: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + PC += 3; + + /* cmp(--src & 0xff)); */ + + src = (src - 1) & 0xff; /* DEC+CMP */ + SET_CARRY (AC >= src); + SET_SIGN (AC - src); + SET_ZERO (AC != src); + + STORE (p2 + YR, (src));; + clkcount = 7; + } + + break; + + case 220: + { + PC += 3; + + clkcount = 4; + } + + break; + + case 221: +/* CMP, ABSOLUTE_X */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + if (pagetest (p2, XR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + src = AC - src; + SET_CARRY (src < 0x100); + SET_SIGN (src); + SET_ZERO (src &= 0xff); + } + + break; + + case 222: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + + src = (src - 1) & 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2 + XR, (src));; + clkcount = 7; + } + + break; + + case 223: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + + /* cmp(--src & 0xff)); */ + + src = (src - 1) & 0xff; /* DEC+CMP */ + SET_CARRY (AC >= src); + SET_SIGN (AC - src); + SET_ZERO (AC != src); + + STORE (p2 + XR, (src));; + clkcount = 7; + } + + break; + + case 224: + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + PC += 2; + + src = XR - src; + SET_CARRY (src < 0x100); + SET_SIGN (src); + SET_ZERO (src &= 0xff); + clkcount = 2; + } + + break; + + case 225: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1 + XR)); + register unsigned int temp = AC - src - (IF_CARRY ()? 0 : 1); + PC += 2; + + /* + * SBC is not exact either. It has 6% different results too. + */ + + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = (temp & 0xff);; + clkcount = 6; + } + + break; + + case 226: + { + PC += 2; + + clkcount = 2; + } + + break; + + case 227: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1 + XR)); + register unsigned int temp; + PC += 2; + + + /* src = ++src & 0xff; AC = sbc(src); */ + + src = ((src + 1) & 0xff); /* INC+SBC */ + + temp = AC - src - (IF_CARRY ()? 0 : 1); + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = temp; + /* src saved */ + STORE (LOAD_ZERO_ADDR (p1 + XR), (src));; + clkcount = 8; + } + + break; + + case 228: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + src = XR - src; + SET_CARRY (src < 0x100); + SET_SIGN (src); + SET_ZERO (src &= 0xff); + clkcount = 3; + } + + break; + + case 229: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + register unsigned int temp = AC - src - (IF_CARRY ()? 0 : 1); + PC += 2; + + /* + * SBC is not exact either. It has 6% different results too. + */ + + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = (temp & 0xff);; + clkcount = 3; + } + + break; + + case 230: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + PC += 2; + + src = (src + 1) & 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE_ZERO (p1, (src));; + clkcount = 5; + } + + break; + + case 231: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1); + register unsigned int temp; + PC += 2; + + + /* src = ++src & 0xff; AC = sbc(src); */ + + src = ((src + 1) & 0xff); /* INC+SBC */ + + temp = AC - src - (IF_CARRY ()? 0 : 1); + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = temp; + /* src saved */ + STORE_ZERO (p1, (src));; + clkcount = 5; + } + + break; + + case 232: + { + register unsigned src = XR; + PC++; + + src = (src + 1) & 0xff; + SET_SIGN (src); + SET_ZERO (src); + + XR = (src);; + clkcount = 2; + } + + break; + + case 233: +/* SBC, IMMEDIATE */ + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + register unsigned int temp = AC - src - (IF_CARRY ()? 0 : 1); + PC += 2; + + /* + * SBC is not exact either. It has 6% different results too. + */ + + if (!IF_DECIMAL ()) + { + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + SET_CARRY (temp < 0x100); + AC = (temp & 0xff); + + } + else + { + int bcd1, bcd2; + BYTE old_A; + int C = IF_CARRY ()? 1 : 0; + + old_A = AC; + + bcd1 = fromBCD (AC); + bcd2 = fromBCD (src); + + bcd1 = bcd1 - bcd2 - !C; + + if (bcd1 < 0) + bcd1 = 100 - (-bcd1); + AC = toBCD (bcd1); + + SET_CARRY ((old_A < (src + !C)) ? 0 : 1); + SET_OVERFLOW ((old_A ^ AC) & 0x80); + } + clkcount = 2; + } + + break; + + case 234: + { + PC++; + + clkcount = 2; + } + + break; + + case 235: + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + register unsigned int temp = AC - src - (IF_CARRY ()? 0 : 1); + PC += 2; + + /* + * SBC is not exact either. It has 6% different results too. + */ + + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = (temp & 0xff);; + clkcount = 2; + } + + break; + + case 236: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + src = XR - src; + SET_CARRY (src < 0x100); + SET_SIGN (src); + SET_ZERO (src &= 0xff); + clkcount = 4; + } + + break; + + case 237: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + register unsigned int temp = AC - src - (IF_CARRY ()? 0 : 1); + PC += 3; + + /* + * SBC is not exact either. It has 6% different results too. + */ + + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = (temp & 0xff);; + clkcount = 4; + } + + break; + + case 238: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + PC += 3; + + src = (src + 1) & 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2, (src));; + clkcount = 6; + } + + break; + + case 239: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2); + register unsigned int temp; + PC += 3; + + + /* src = ++src & 0xff; AC = sbc(src); */ + + src = ((src + 1) & 0xff); /* INC+SBC */ + + temp = AC - src - (IF_CARRY ()? 0 : 1); + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = temp; + /* src saved */ + STORE (p2, (src));; + clkcount = 6; + } + + break; + + case 240: +/* BEQ, RELATIVE */ + { + register p1 = LOAD (PC + 1); + register unsigned src = p1; + register BYTE hb; + PC += 2; + /* Branch if zero flag is set. */ + if (IF_ZERO ()) + { + hb = UPPER (PC); + PC = REL_ADDR (PC, src); + if (brtest (hb)) + /* Same page */ + clkcount = 3; + else + /* Different page */ + clkcount = 4; + } + else + clkcount = 2; + } + + break; + + case 241: + { + register p1 = LOAD (PC + 1); + register ADDRESS p2 = LOAD_ZERO_ADDR (p1); + register unsigned src = LOAD (p2 + YR); + register unsigned int temp = AC - src - (IF_CARRY ()? 0 : 1); + PC += 2; + + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 6; + else + /* Same page */ + clkcount = 5; + + /* + * SBC is not exact either. It has 6% different results too. + */ + + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = (temp & 0xff); + } + + break; + + case 242: + { + PC++; + /* No such opcode. */ + (void) printf ("Illegal instruction.\n"); + verflg = 1; + --PC; + show (); + mon (PC); + } + + break; + + case 243: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD (LOAD_ZERO_ADDR (p1) + YR); + register unsigned int temp; + PC += 2; + + + /* src = ++src & 0xff; AC = sbc(src); */ + + src = ((src + 1) & 0xff); /* INC+SBC */ + + temp = AC - src - (IF_CARRY ()? 0 : 1); + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = temp; + /* src saved */ + STORE (LOAD_ZERO_ADDR (p1) + YR, (src));; + clkcount = 8; + } + + break; + + case 244: + { + PC += 2; + + clkcount = 4; + } + + break; + + case 245: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + register unsigned int temp = AC - src - (IF_CARRY ()? 0 : 1); + PC += 2; + + /* + * SBC is not exact either. It has 6% different results too. + */ + + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = (temp & 0xff);; + clkcount = 4; + } + + break; + + case 246: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + PC += 2; + + src = (src + 1) & 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE_ZERO (p1 + XR, (src));; + clkcount = 6; + } + + break; + + case 247: + { + register p1 = LOAD (PC + 1); + register unsigned src = LOAD_ZERO (p1 + XR); + register unsigned int temp; + PC += 2; + + + /* src = ++src & 0xff; AC = sbc(src); */ + + src = ((src + 1) & 0xff); /* INC+SBC */ + + temp = AC - src - (IF_CARRY ()? 0 : 1); + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = temp; + /* src saved */ + STORE_ZERO (p1 + XR, (src));; + clkcount = 6; + } + + break; + + case 248: +/* SED, IMPLIED */ + { + PC++; + + SET_DECIMAL ((1));; + clkcount = 2; + } + + break; + + case 249: +/* SBC, ABSOLUTE_Y */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + register unsigned int temp = AC - src - (IF_CARRY ()? 0 : 1); + PC += 3; + + if (pagetest (p2, YR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + /* + * SBC is not exact either. It has 6% different results too. + */ + + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = (temp & 0xff); + } + + break; + + case 250: + { + PC++; + + clkcount = 2; + } + + break; + + case 251: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + YR); + register unsigned int temp; + PC += 3; + + + /* src = ++src & 0xff; AC = sbc(src); */ + + src = ((src + 1) & 0xff); /* INC+SBC */ + + temp = AC - src - (IF_CARRY ()? 0 : 1); + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = temp; + /* src saved */ + STORE (p2 + YR, (src));; + clkcount = 7; + } + + break; + + case 252: + { + PC += 3; + + clkcount = 4; + } + + break; + + case 253: +/* SBC, ABSOLUTE_X */ + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + register unsigned int temp = AC - src - (IF_CARRY ()? 0 : 1); + PC += 3; + + if (pagetest (p2, XR)) + /* Over page */ + clkcount = 5; + else + /* Same page */ + clkcount = 4; + + /* + * SBC is not exact either. It has 6% different results too. + */ + + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = (temp & 0xff); + } + + break; + + case 254: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + PC += 3; + + src = (src + 1) & 0xff; + SET_SIGN (src); + SET_ZERO (src); + + STORE (p2 + XR, (src));; + clkcount = 7; + } + + break; + + case 255: + { + register p2 = load_abs_addr (); + register unsigned src = LOAD (p2 + XR); + register unsigned int temp; + PC += 3; + + + /* src = ++src & 0xff; AC = sbc(src); */ + + src = ((src + 1) & 0xff); /* INC+SBC */ + + temp = AC - src - (IF_CARRY ()? 0 : 1); + + SET_SIGN (temp); + SET_ZERO (temp & 0xff); /* Sign and Zero are invalid in decimal mode */ + + SET_OVERFLOW (((AC ^ temp) & 0x80) && ((AC ^ src) & 0x80)); + + if (IF_DECIMAL ()) + { + if (((AC & 0xf) + (IF_CARRY ()? 1 : 0)) < (src & 0xf)) + temp -= 6; + if (temp > 0x99) + temp -= 0x60; + } + SET_CARRY (temp < 0x100); + + AC = temp; + /* src saved */ + STORE (p2 + XR, (src));; + clkcount = 7; + } + + break; + + + + } /* switch */ + + clk += clkcount; + + } /* while(1) */ + } /* while(!reset_flag) */ +} /* mainloop */ diff -ruNp ./rockbox/apps/plugins/2600box/cpu.h ./rockbox-working/apps/plugins/2600box/cpu.h --- ./rockbox/apps/plugins/2600box/cpu.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/cpu.h 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,184 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: cpu.h,v 1.6 1997/11/22 14:29:54 ahornby Exp $ +******************************************************************************/ +/* + * + * This file was part of x64. + * + * This file contains useful stuff when you are creating + * virtual machine like MCS6510 based microcomputer. + * + * Included are: + * o registers + * o flags in PSW + * o addressing modes + * + * Written by + * Vesa-Matti Puro (vmp@lut.fi) + * Jarkko Sonninen (sonninen@lut.fi) + * Jouko Valta (jopi@stekt.oulu.fi) + * + * + */ + +#ifndef X2600_CPU_H +#define X2600_CPU_H + + +#include "rbconfig.h" +#include "types.h" + +/* 6507 Registers. */ +#define AC accumulator +#define XR x_register +#define YR y_register +#define SP stack_pointer +#define PC program_counter +#define PCH ((PC>>8)&0xff) +#define PCL (PC&0xff) + +#define ZF zero_flag +#define SF sign_flag +#define OF overflow_flag +#define BF break_flag +#define DF decimal_flag +#define IF interrupt_flag +#define CF carry_flag + + +/* Masks which indicate location of status flags in PSW. */ +#define S_SIGN 0x80 +#define S_OVERFLOW 0x40 +#define S_NOTUSED 0x20 +#define S_BREAK 0x10 +#define S_DECIMAL 0x08 +#define S_INTERRUPT 0x04 +#define S_ZERO 0x02 +#define S_CARRY 0x01 + + +/* ADDRESSING MODES */ + +#define IMPLIED 0 +#define ACCUMULATOR 1 +#define IMMEDIATE 2 + +#define ZERO_PAGE 3 +#define ZERO_PAGE_X 4 +#define ZERO_PAGE_Y 5 + +#define ABSOLUTE 6 +#define ABSOLUTE_X 7 +#define ABSOLUTE_Y 8 + +#define ABS_INDIRECT 9 +#define INDIRECT_X 10 +#define INDIRECT_Y 11 + +#define RELATIVE 12 + +#define ASS_CODE 13 + + +/* + * Declaration for lookup-table which is used to translate MOS6502 + * machine instructions. Machine code is used as index to array called + * lookup. Pointer to function is then fetched from array and function + * is called. + */ + +extern struct lookup_tag { + char *mnemonic; /* Selfdocumenting? */ + short addr_mode; + unsigned char source; + unsigned char destination; + unsigned char cycles; + unsigned char pbc_fix; /* Cycle for Page Boundary Crossing */ +} lookup[]; + + +/* Addressing mode (addr_mode) is used when instruction is diassembled + * or assembled by diassembler or assembler. This is used i.e. + * in function char *sprint_opcode() in the file misc.c. + * + * MOS6502 addressing modes are #defined in the file "vmachine.h". + * + * Mnemonic is character string telling the name of the instruction. + */ + +#define M_NONE 0 +#define M_AC 1 +#define M_XR 2 +#define M_YR 3 +#define M_SP 4 +#define M_SR 5 +#define M_PC 6 +#define M_IMM 7 +#define M_ZERO 8 +#define M_ZERX 9 +#define M_ZERY 10 +#define M_ABS 11 +#define M_ABSX 12 +#define M_ABSY 13 +#define M_AIND 14 +#define M_INDX 15 +#define M_INDY 16 +#define M_REL 17 +#define M_FC 18 +#define M_FD 19 +#define M_FI 20 +#define M_FV 21 +#define M_ADDR 22 +#define M_ 23 + +#ifndef NO_UNDOC_CMDS +#define M_ACIM 24 /* Source: AC & IMMED (bus collision) */ +#define M_ANXR 25 /* Source: AC & XR (bus collision) */ +#define M_AXIM 26 /* Source: (AC | #EE) & XR & IMMED (bus collision) */ +#define M_ACNC 27 /* Dest: M_AC and Carry = Negative */ +#define M_ACXR 28 /* Dest: M_AC, M_XR */ + +#define M_SABY 29 /* Source: (ABS_Y & SP) (bus collision) */ +#define M_ACXS 30 /* Dest: M_AC, M_XR, M_SP */ +#define M_STH0 31 /* Dest: Store (src & Addr_Hi+1) to (Addr +0x100) */ +#define M_STH1 32 +#define M_STH2 33 +#define M_STH3 34 + +#else +#define M_ACIM M_NONE +#define M_ANXR M_NONE +#define M_AXIM M_NONE +#define M_ACNC M_NONE +#define M_ACXR M_NONE + +#define M_SABY M_NONE +#define M_ACXS M_NONE +#define M_STH0 M_NONE +#define M_STH1 M_NONE +#define M_STH2 M_NONE +#define M_STH3 M_NONE +#endif + + + +#endif /* X2600_CPU_H */ + + + + + + + + diff -ruNp ./rockbox/apps/plugins/2600box/dbg_mess.c ./rockbox-working/apps/plugins/2600box/dbg_mess.c --- ./rockbox/apps/plugins/2600box/dbg_mess.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/dbg_mess.c 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,55 @@ +/***************************************************************************** + + This file is part of Virtual 2600, the Atari 2600 Emulator + ========================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: dbg_mess.c,v 1.3 1997/11/22 14:27:47 ahornby Exp $ +******************************************************************************/ + +/* Print debugging messages of the appropriate urgency */ + +#include "rbconfig.h" +#include +#include + +#include "types.h" +#include "options.h" + +/* + Levels with meanings + -------------------- + + None, (No stdout) + User level, (User level messages) + Normal programmers debug, (Programmer debug messages) + Lots programmers debug, (Every frame) + Obscene programmers debug (Every line or more) + + */ + +enum dbg_level {DBG_NONE=0, DBG_USER=1, DBG_NORMAL=2, DBG_LOTS=3, DBG_OBSCENE=4}; + +void +dbg_message(int level, const char *format, ...) +{ +#if Verbose + + if( level <= base_opts.dbg_level ) + { + va_list ap; + + va_start(ap, format); + + vfprintf(stderr, format, ap ); + } +#endif +} + + diff -ruNp ./rockbox/apps/plugins/2600box/dbg_mess.h ./rockbox-working/apps/plugins/2600box/dbg_mess.h --- ./rockbox/apps/plugins/2600box/dbg_mess.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/dbg_mess.h 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,9 @@ +#ifndef DBG_MESS_H +#define DBG_MESS_H + +enum dbg_level {DBG_NONE=0, DBG_USER=1, DBG_NORMAL=2, DBG_LOTS=3, DBG_OBSCENE=4}; + +void +dbg_message(int level, const char *format, ... ); + +#endif diff -ruNp ./rockbox/apps/plugins/2600box/debug.h ./rockbox-working/apps/plugins/2600box/debug.h --- ./rockbox/apps/plugins/2600box/debug.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/debug.h 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,28 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: debug.h,v 1.3 1996/08/24 19:00:26 ahornby Exp $ +******************************************************************************/ + +/* + Debugging flags. + */ + +#ifndef DEBUG_H +extern int debugf_on, debugf_halt, debugf_trace, debugf_raster; +#endif + + + + + + diff -ruNp ./rockbox/apps/plugins/2600box/display.h ./rockbox-working/apps/plugins/2600box/display.h --- ./rockbox/apps/plugins/2600box/display.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/display.h 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,51 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: display.h,v 1.13 1997/11/22 14:29:54 ahornby Exp $ +******************************************************************************/ + +/* + Defines for the X11 display code. + */ + +#ifndef DISPLAY_H +#define DISPLAY_H +int fselLoad(void); +void rate_update(void); +void tv_off(void); +int tv_on(int argc, char **argv); +void tv_event(void); +void tv_display(void); +void tv_putpixel(int x, int y, BYTE value); +#if LCD_WIDTH >= 320 +extern unsigned int tv_color(BYTE b); +#else +//extern BYTE tv_color(BYTE b); +extern unsigned short tv_color(BYTE b); +#endif + +extern int redraw_flag; + +extern BYTE *vscreen; +extern int vwidth,vheight,theight; +extern int tv_counter; +extern int tv_depth; +extern int tv_bytes_pp; +extern unsigned long tv_red_mask; +extern unsigned long tv_blue_mask; +extern unsigned long tv_green_mask; +#endif + + + + + diff -ruNp ./rockbox/apps/plugins/2600box/exmacro.c ./rockbox-working/apps/plugins/2600box/exmacro.c --- ./rockbox/apps/plugins/2600box/exmacro.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/exmacro.c 2013-11-14 09:58:43.167434853 -0500 @@ -0,0 +1,66 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for Details. + + $Id: exmacro.c,v 1.6 1996/08/26 15:04:20 ahornby Exp $ +******************************************************************************/ + +/* Things that used to be macros, but are now inline functions. + Done for ease of debugging */ + +#include "types.h" +#include "extern.h" +#include "macro.h" +#include "memory.h" + +/* Loads an absolute address uising the quicker load mechanism */ +inline ADDRESS +extern load_abs_addr (void) +{ + return (LOADEXEC (PC + 1) | (LOADEXEC (PC + 2) << 8)); +} + +/* Used in variable cycle time indexed addressing */ +/* a: address to be incremented */ +/* b: increment value */ +/* returns: TRUE if an address increment will cross a page boundary */ +inline int +extern pagetest (ADDRESS a, BYTE b) +{ + return (LOWER (a) + b > 0xff); +} + +/* Used in variable cycle time branches */ +/* a: high byte of new address */ +/* returns: TRUE if a branch is to the same page */ +inline int +extern brtest (BYTE a) +{ + return (UPPER (PC) == (a)); +} + +/* Convert from binary to BCD (Binary Coded Decimal) */ +/* a: binary value */ +/* returns: BCD value */ +inline int +extern toBCD (int a) +{ + return (((a % 100) / 10) << 4) | (a % 10); +} + +/* Convert from BCD to binary */ +/* a: BCD value */ +/* returns: binary value */ +inline int +extern fromBCD (int a) +{ + return ((a >> 4) & 0xf) * 10 + (a & 0xf); +} diff -ruNp ./rockbox/apps/plugins/2600box/exmacro.h ./rockbox-working/apps/plugins/2600box/exmacro.h --- ./rockbox/apps/plugins/2600box/exmacro.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/exmacro.h 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,30 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: exmacro.h,v 1.5 1996/11/24 16:55:40 ahornby Exp $ +******************************************************************************/ + +/* + Defines inline functions that would otherwise be macros. + */ + +#ifndef EXMACRO_H +#define EXMACRO_H + +inline ADDRESS load_abs_addr(void); +inline int pagetest( ADDRESS a, BYTE b); +inline int brtest( BYTE a); +inline int toBCD( int a); +inline int fromBCD( int a); + +#endif + diff -ruNp ./rockbox/apps/plugins/2600box/extern.h ./rockbox-working/apps/plugins/2600box/extern.h --- ./rockbox/apps/plugins/2600box/extern.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/extern.h 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,59 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: extern.h,v 1.3 1996/04/01 14:51:50 alex Exp $ +******************************************************************************/ + +/* + Defines the external variables needed by most hardware access code. + */ + +#ifndef VCSEXTERN_H +#define VCSEXTERN_H + + +#include "types.h" /* for BYTE, ADDRESS, etc. types and structures */ + +extern int clength[]; + +/* Processor registers */ +extern BYTE accumulator; +extern BYTE x_register; +extern BYTE y_register; +extern BYTE stack_pointer; +extern BYTE status_register; +extern ADDRESS program_counter; +extern CLOCK clk; + +/* Processor flags */ +extern int zero_flag; +extern int sign_flag; +extern int overflow_flag; +extern int break_flag; +extern int decimal_flag; +extern int interrupt_flag; +extern int carry_flag; + +/* Debugging */ +extern int hexflg; +extern int verflg; +extern int traceflg; +extern int debugflg; +extern int runflg; + +#endif + + + + + + diff -ruNp ./rockbox/apps/plugins/2600box/files.c ./rockbox-working/apps/plugins/2600box/files.c --- ./rockbox/apps/plugins/2600box/files.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/files.c 2013-11-14 08:18:05.031631555 -0500 @@ -0,0 +1,267 @@ + + +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: files.c,v 1.18 1997/02/23 20:39:29 ahornby Exp ahornby $ +******************************************************************************/ + +/* + Used to load cartridge images into memory. + */ + +#include "rbconfig.h" +#include +/*#include */ +#include "options.h" +#include "types.h" +#include "vmachine.h" +#include "c26def.h" +#include "okie.h" +#include "dbg_mess.h" + +/* Return the size of the file pointed to by fp */ +/* Avoids need for UNIX type stat, leaves file */ +/* pointer untouched. */ +long +filesize (int fd) +{ + long curpos, length; + + curpos = rb->lseek(fd, 0, SEEK_CUR); + rb -> lseek (fd, 0L, SEEK_END); + length = rb->lseek(fd, 0, SEEK_CUR); + rb -> lseek (fd, curpos, SEEK_SET); + return length; +} + +/* Load from the common 2600 format */ +/* Uses the tag structure from c26def.h */ +int +loadc26 (int fd, long flen) +{ +#if 0 + char databuf[65535]; + struct c26_tag tag; + + while (fread (&tag, sizeof (struct c26_tag), 1, fp)) + { + /* If positive then it has a data block */ + if (tag.type >= 0) + { + if (fread (databuf, sizeof (BYTE), tag.len, fp)) + { + perror ("v2600 loadc26:"); + fprintf (stderr, "Error reading data.\n"); + } + } + + switch (tag.type) + { + + case _2600_VERSION: + if (Verbose) + printf ("File version %d\n", tag.len); + break; + + case WRITER: + if (Verbose) + printf ("Written by: %s\n", databuf); + break; + + case TVTYPE: + base_opts.tvtype = tag.len; + break; + + case CONTROLLERS: + /* Higher byte */ + base_opts.lcon = (tag.len & 0xff00)>>8; + /* Low byte */ + base_opts.rcon = (tag.len) & 0xff; + + case BANKING: + base_opts.bank = tag.len; + break; + + case DATA: + if (tag.len <= 16384) + memcpy (&theCart[0], databuf, tag.len); + else + { + fprintf (stderr, "Data larger that 16k!\n"); + exit (-1); + } + rom_size = tag.len; + if (tag.len == 2048) + { + memcpy (&theCart[0], databuf, tag.len); + memcpy (&theCart[2048], databuf, tag.len); + } + break; + + default: + fprintf (stderr, "Unknown tag %d\n. Ignoring.", tag.type); + break; + } + } +#endif + return 0; +} + +/* Load a raw binary image */ +/* fp: file stream to load */ +/* stat_data: unix stat structure for file pointed to by fp */ +/* returns: size of file loaded */ +int +loadRaw (int fd, long flen) +{ + + int size = flen; + if (Verbose) + rb -> splash (HZ, "Raw loading %d bytes\n"); + + if (size > 16384) + size = 16384; + rb -> read ( fd , theCart , size ); + rom_size = size; + if (size == 2048) + { + memcpy (&theCart[2048], &theCart[0], 2048); + rom_size = 4096; + } + else if (size < 2048) + { + theCart[0x0ffc] = 0x00; + theCart[0x0ffd] = 0xf0; + rom_size = 4096; + } + + return size; + +} + +/* Load a default game */ +void +load_okie_dokie(void) +{ + memcpy (&theCart[0], &okie_dokie_data[0], 2048); + rom_size = 2048; + memcpy (&theCart[2048], &theCart[0], 2048); + rom_size = 4096; +} + +/* Load a commodore format .prg file */ +/* fp: file stream to load */ +/* stat_data: unix stat structure for file pointed to by fp */ +/* returns: size of file loaded */ +int +loadPrg (int fd, long flen) +{ +#if 0 + int start; + int rompos; + int size; + unsigned char buf1, buf2; + + /* Get the load address */ + fread (&buf1, sizeof (BYTE), 1, fp); + fread (&buf2, sizeof (BYTE), 1, fp); + start = buf2 * 256 + buf1; + + /* Translate the load address to a ROM address */ + rompos = start & 0xfff; + + /* Get length of data part */ + size = flen - 2; + + if (Verbose) + printf ("Loading .prg at %x\n", start); + + /* Load the data */ + fread (&theCart[rompos], sizeof (BYTE), size, fp); + + /* Put the load address into the reset vector */ + theCart[0x0ffc] = buf1; + theCart[0x0ffd] = buf2; + return size; +#endif + return 0; +} + +/* Load a cartridge image */ +/* name: filename to load */ +/* returns: -1 on error 0 otherwise */ +int +loadCart (void) +{ + int fd; + char *ext; + int flen; + char *name = base_opts.filename; + + if (name == NULL || strcmp("",name)==0) + { + load_okie_dokie(); + return 0; + } + + fd = rb -> open (name, O_RDONLY); + if(fd < 0) { + return -1; + } + + if (Verbose) + rb -> splash (HZ , "Loading cart: %s\n"); + flen = filesize (fd); + + ext = strrchr (name, '.'); + if(!ext) { + ext=".bin"; + } + + if (strcmp (".pal", ext) == 0 || strcmp (".vcs", ext) == 0 || + strcmp (".raw", ext) == 0 || strcmp (".bin", ext) == 0 || + strcmp (".BIN", ext) == 0) + { + int size=loadRaw (fd, flen); + /* try and correct for idiots */ + if(base_opts.bank==0) { + switch(size) { + case 8192: + base_opts.bank=1; + break; + case 16384: + base_opts.bank=2; + break; + default: + break; + /* Do nothing */ + } + } + } + else if (strcmp (".prg", ext) == 0) + { + loadPrg (fd, flen); + } + else if (strcmp (".c26", ext) == 0) + { + loadc26 (fd, flen); + } + else + { + rb -> splash (HZ , "Unknown file format %s\n"); + return -1; + } + rb -> close (fd); + + return 0; +} diff -ruNp ./rockbox/apps/plugins/2600box/files.h ./rockbox-working/apps/plugins/2600box/files.h --- ./rockbox/apps/plugins/2600box/files.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/files.h 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,26 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: files.h,v 1.3 1996/08/24 19:00:26 ahornby Exp $ +******************************************************************************/ + +/* + Prototype for loadCart. + */ + +#ifndef VCSFILES_H +#define VCSFILES_H + +int +loadCart(void); + +#endif diff -ruNp ./rockbox/apps/plugins/2600box/keybdrv.h ./rockbox-working/apps/plugins/2600box/keybdrv.h --- ./rockbox/apps/plugins/2600box/keybdrv.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/keybdrv.h 2013-11-14 07:47:53.827690560 -0500 @@ -0,0 +1,21 @@ +#ifndef KEYBDRV_H +#define KEYBDRV_H + +void +keybdrv_close (void); + +int +keybdrv_init (void); + +void +keybdrv_setmap(void); + +int +keybdrv_pressed(int key); + +void +keybdrv_update (void); + +#endif + + diff -ruNp ./rockbox/apps/plugins/2600box/keyboard.c ./rockbox-working/apps/plugins/2600box/keyboard.c --- ./rockbox/apps/plugins/2600box/keyboard.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/keyboard.c 2013-11-14 12:46:54.119106120 -0500 @@ -0,0 +1,256 @@ +/***************************************************************************** + + This file is part of Virtual 2600, the Atari 2600 Emulator + ========================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: keyboard.c,v 1.18 1997/11/22 14:27:47 ahornby Exp $ +******************************************************************************/ + +/* The device independant keyboard and mouse interface. */ + +#include + +#include "rbconfig.h" +#include "options.h" +#include "types.h" +#include "address.h" +#include "vmachine.h" +#include "macro.h" +#include "extern.h" +#include "memory.h" +#include "kmap.h" +#include "realjoy.h" +#include "display.h" +#include "keybdrv.h" +#include "moudrv.h" + +enum control {STICK, PADDLE, KEYPAD}; + +enum joydirs {JLEFT, JRIGHT, JUP, JDOWN, JFIRE}; +int joykeys[2][5]={ + {kmapLARROW, kmapRARROW, kmapUARROW, kmapDARROW, kmapSPACE}, + {kmapA, kmapS, kmapW, kmapZ, kmapLEFTALT}}; + +int padkeys[2][4][3]={ { {kmap1,kmap2,kmap3}, + {kmapQ, kmapW, kmapE}, + {kmapA, kmapS, kmapD}, + {kmapZ, kmapX, kmapD}}, + { {kmap5,kmap6,kmap7}, + {kmapT, kmapY, kmapU}, + {kmapG, kmapH, kmapJ}, + {kmapB, kmapN, kmapM}}}; + +int moudrv_x, moudrv_y, moudrv_but; + +static int raw; + +/* Stores the keycodes */ +int keymap[103]; + +/* Returns mouse position */ +int +mouse_position (void) +{ + int res; + moudrv_read(); + + if(base_opts.mousey==1) + res=(((moudrv_y/base_opts.magstep)*320)/200); + else + res=moudrv_x/base_opts.magstep; + + return res; +} + +/* Returns mouse button state */ +int +mouse_button (void) +{ + moudrv_read(); + return moudrv_but; +} + +/* Read from the keypad */ +void +read_keypad(int pad) +{ + int i,row,col; + + for(i=0; i<4; i++) + keypad[pad][i]=0xff; + + for(row=0;row<4;row++) + { + for(col=0;col<3;col++) + { + if (keybdrv_pressed(padkeys[pad][row][col])) + keypad[pad][row]=col; + } + } +} + + +/* Read from the emulated joystick */ +void +read_stick (void) +{ + BYTE v[2]; + int i,jres; + + v[0] = v[1] = 0x0f; + + int buttons = rb->button_status(); + if (buttons & JOY_LEFT) + v[0] &= 0x0B; + if (buttons & JOY_RIGHT) + v[0] &= 0x07; + if (buttons & JOY_UP) + v[0] &= 0x0E; + if (buttons & JOY_DOWN) + v[0] &= 0x0D; + + for(i=0;i<2;i++) + { + jres = get_realjoy (i); + if (keybdrv_pressed(joykeys[i][JUP]) || (jres & UJOYMASK)) + v[i] &= 0x0E; + else if (keybdrv_pressed(joykeys[i][JDOWN]) || (jres & DJOYMASK)) + v[i] &= 0x0D; + if (keybdrv_pressed(joykeys[i][JLEFT]) || (jres & LJOYMASK)) + v[i] &= 0x0B; + else if (keybdrv_pressed(joykeys[i][JRIGHT]) || (jres & RJOYMASK)) + v[i] &= 0x07; + } + + /* Swap if necessary */ + if (base_opts.swap) + riotRead[SWCHA] = (v[1] << 4) | v[0]; + else + riotRead[SWCHA] = (v[0] << 4) | v[1]; +} + +/* Read from emulated joystick trigger */ +void +read_trigger (void) +{ + int kr = 0x80, kl = 0x80, temp; + int jres; + + int buttons = rb->button_status(); + if (buttons & JOY_TRIGGER) + kr = 0x00; + + /* keyboard_update(); */ + /* update_realjoy(); */ + + /* Left Player */ + jres = get_realjoy (1); + if (keybdrv_pressed(joykeys[1][JFIRE]) || (jres & B1JOYMASK)) + kl = 0x00; + + /* Right Player */ + jres = get_realjoy (0); + if (keybdrv_pressed(joykeys[0][JFIRE]) || (jres & B1JOYMASK)) + kr = 0x00; + + /* Swap the buttons if necessary */ + if (base_opts.swap) + { + temp = kl; + kl = kr; + kr = temp; + } + + /* The normal non-latched mode */ + if (!(tiaWrite[VBLANK] & 0x40)) + { + tiaRead[INPT4] = kr; + tiaRead[INPT5] = kl; + } + /* The latched mode */ + else + { + if (kr == 0) + tiaRead[INPT4] = 0x00; + if (kl == 0) + tiaRead[INPT5] = 0x00; + } +} + +/* Reads the keyboard */ +void +read_keyboard (void) +{ + if (raw) + { + keybdrv_update (); + moudrv_update (); + } + //if (keybdrv_pressed(kmapF10)) + //exit (0); +} + +/* Read console switches */ +void +read_console (void) +{ + riotRead[SWCHB] |= 0x03; + int buttons = rb->button_status(); + if (buttons & CONSOLE_OPTION) + riotRead[SWCHB] &= 0xFD; + if (buttons & CONSOLE_RESET) + riotRead[SWCHB] &= 0xFE; + + if (keybdrv_pressed(kmapF2)) + riotRead[SWCHB] &= 0xFE; /* Reset */ + if (keybdrv_pressed(kmapF3)) + riotRead[SWCHB] &= 0xFD; /* Select */ + + if (keybdrv_pressed(kmapF4)) + { + if (riotRead[SWCHB] & 0x08) + /* BW */ + riotRead[SWCHB] &= 0xF7; + else + /* Color */ + riotRead[SWCHB] |= 0x08; + while (keybdrv_pressed(kmapF4)) + keybdrv_update (); + } + + if (keybdrv_pressed(kmapF5)) + riotRead[SWCHB] &= 0xBF; /* P0 amateur */ + else if (keybdrv_pressed(kmapF6)) + riotRead[SWCHB] |= 0x40; /* P0 pro */ + if (keybdrv_pressed(kmapF7)) + riotRead[SWCHB] &= 0x7f; /* P1 amateur */ + else if (keybdrv_pressed(kmapF8)) + riotRead[SWCHB] |= 0x80; /* P1 pro */ +} + +/* Close the keyboard */ +void +close_keyboard (void) +{ + moudrv_close(); + keybdrv_close (); + raw=0; +} + +/* Initialises the keyboard */ +void +init_keyboard (void) +{ + keybdrv_init (); + keybdrv_setmap(); + moudrv_init(); + raw=1; +} + diff -ruNp ./rockbox/apps/plugins/2600box/keyboard.h ./rockbox-working/apps/plugins/2600box/keyboard.h --- ./rockbox/apps/plugins/2600box/keyboard.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/keyboard.h 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,52 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: keyboard.h,v 1.4 1996/08/26 15:05:03 ahornby Exp $ +******************************************************************************/ + +/* + Keyboard prototypes. + */ + +#ifndef KEYBOARD_H +#define KEYBOARD_H + +enum control {STICK, PADDLE, KEYPAD}; + +int +mouse_position(void); + +int +mouse_button(void); + +void +read_trigger(void); + +void +read_stick(void); + +void +read_keypad(int pad); + +void +read_console(void); + +void +init_keyboard(void); + +void +close_keyboard(void); + +void +read_keyboard(void); + +#endif diff -ruNp ./rockbox/apps/plugins/2600box/kmap.h ./rockbox-working/apps/plugins/2600box/kmap.h --- ./rockbox/apps/plugins/2600box/kmap.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/kmap.h 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,110 @@ +#ifndef KMAP_H +#define KMAP_H + +#define kmapSYSREQ 0 +#define kmapCAPSLOCK 1 +#define kmapNUMLOCK 2 +#define kmapSCROLLLOCK 3 +#define kmapLEFTCTRL 4 +#define kmapLEFTALT 5 +#define kmapLEFTSHIFT 6 +#define kmapRIGHTCTRL 7 +#define kmapRIGHTALT 8 +#define kmapRIGHTSHIFT 9 +#define kmapESC 10 +#define kmapBACKSPACE 11 +#define kmapENTER 12 +#define kmapSPACE 13 +#define kmapTAB 14 +#define kmapF1 15 +#define kmapF2 16 +#define kmapF3 17 +#define kmapF4 18 +#define kmapF5 19 +#define kmapF6 20 +#define kmapF7 21 +#define kmapF8 22 +#define kmapF9 23 +#define kmapF10 24 +#define kmapF11 25 +#define kmapF12 27 +#define kmapA 28 +#define kmapB 29 +#define kmapC 30 +#define kmapD 31 +#define kmapE 32 +#define kmapF 33 +#define kmapG 34 +#define kmapH 35 +#define kmapI 36 +#define kmapJ 37 +#define kmapK 38 +#define kmapL 39 +#define kmapM 40 +#define kmapN 41 +#define kmapO 42 +#define kmapP 43 +#define kmapQ 44 +#define kmapR 45 +#define kmapS 46 +#define kmapT 47 +#define kmapU 48 +#define kmapV 49 +#define kmapW 50 +#define kmapX 51 +#define kmapY 52 +#define kmapZ 53 +#define kmap1 54 +#define kmap2 55 +#define kmap3 56 +#define kmap4 57 +#define kmap5 58 +#define kmap6 59 +#define kmap7 60 +#define kmap8 61 +#define kmap9 62 +#define kmap0 63 +#define kmapMINUS 64 +#define kmapEQUAL 65 +#define kmapLBRACKET 66 +#define kmapRBRACKET 67 +#define kmapSEMICOLON 68 +#define kmapTICK 69 +#define kmapAPOSTROPHE 70 +#define kmapBACKSLASH 71 +#define kmapCOMMA 72 +#define kmapPERIOD 73 +#define kmapSLASH 74 +#define kmapINS 75 +#define kmapDEL 76 +#define kmapHOME 77 +#define kmapEND 78 +#define kmapPGUP 79 +#define kmapPGDN 80 +#define kmapLARROW 81 +#define kmapRARROW 82 +#define kmapUARROW 83 +#define kmapDARROW 84 +#define kmapKEYPAD0 85 +#define kmapKEYPAD1 86 +#define kmapKEYPAD2 87 +#define kmapKEYPAD3 88 +#define kmapKEYPAD4 89 +#define kmapKEYPAD5 90 +#define kmapKEYPAD6 91 +#define kmapKEYPAD7 92 +#define kmapKEYPAD8 93 +#define kmapKEYPAD9 94 +#define kmapKEYPADDEL 95 +#define kmapKEYPADSTAR 96 +#define kmapKEYPADMINUS 97 +#define kmapKEYPADPLUS 98 +#define kmapKEYPADENTER 99 +#define kmapCTRLPRTSC 100 +#define kmapSHIFTPRTSC 101 +#define kmapKEYPADSLASH 102 + +#endif /* KMAP_H*/ + + + diff -ruNp ./rockbox/apps/plugins/2600box/limiter.c ./rockbox-working/apps/plugins/2600box/limiter.c --- ./rockbox/apps/plugins/2600box/limiter.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/limiter.c 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,111 @@ + + +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for Details. + + $Id: limiter.c,v 1.8 1997/11/22 14:27:47 ahornby Exp $ +******************************************************************************/ + +/* + Attempt at a speed limiter. + (You'll have a fast computer to need it though!) + */ + +#include "rbconfig.h" +#include "options.h" +#include "types.h" +#include "vmachine.h" + +/* Global variables. A C++ implementation would hide these */ + +/* +struct timeval limiter_lastClk; +struct timeval limiter_newClk; +long limiter_fTime = 0; +long limiter_last = 0; +long limiter_new = 0; +long limiter_endSleep = 0; +int limiter_frameRate = 0; +int limiter_vRate = 0; +*/ + +/* Get the currently set frame rate */ +/* returns: currently set rate */ +int +limiter_getFrameRate (void) +{ + /* + if (limiter_vRate < 0) + limiter_vRate = tv_hertz; + return limiter_vRate;*/ + return 0; +} + +/* Set the desired frame rate */ +/* f: frame rate in frames per second */ +void +limiter_setFrameRate (int f) +{ +/* limiter_frameRate = f; + limiter_fTime = 1000000 / f;*/ +} + +/* Initialise the frame limiter */ +void +limiter_init (void) +{/* + gettimeofday (&limiter_lastClk, NULL); + gettimeofday (&limiter_newClk, NULL); + limiter_endSleep = limiter_lastClk.tv_usec; + */ +} + +/* Perform the speed limiting syncronisation */ +/* returns: number of microseconds since last call */ +long +limiter_sync (void) +{ +#if 0 + long delta = 0, wait = 0; + + /* Get the current time */ + gettimeofday (&limiter_newClk, NULL); + + if (limiter_newClk.tv_usec < limiter_endSleep) + limiter_endSleep -= 1000000; + + /* how long to wait. Min is 0 usec, max is ftime. */ + wait = (limiter_fTime - limiter_newClk.tv_usec + limiter_endSleep); + if (wait < 0) + wait = 0; + else if (wait > limiter_fTime) + wait = limiter_fTime; + + /* Do the waiting */ +#if HAVE_SELECT + if(base_opts.limit && wait>10) + { + struct timeval tv_wait={0, wait}; + select(0,0,0,0,&tv_wait); + } +#endif + + limiter_endSleep = limiter_newClk.tv_usec + wait; + delta = limiter_newClk.tv_usec - limiter_lastClk.tv_usec; + + gettimeofday (&limiter_lastClk, NULL); + + limiter_vRate = 1000000 / delta; + return delta; +#endif + return 0; +} diff -ruNp ./rockbox/apps/plugins/2600box/limiter.h ./rockbox-working/apps/plugins/2600box/limiter.h --- ./rockbox/apps/plugins/2600box/limiter.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/limiter.h 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,36 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: limiter.h,v 1.4 1996/04/01 14:51:50 alex Exp $ +******************************************************************************/ + +/* + Prototypes for the speed limiter. + Ready for that 500Mhz DEC Alpha. + + Inspired by Brad Pitzels C++ Timer class. + */ + +#ifndef LIMITER_H +#define LIMITER_H + +void limiter_setFrameRate( int f ); +void limiter_init(void); +long limiter_sync(void); +int limiter_getFrameRate(void); + +#endif + + + + + diff -ruNp ./rockbox/apps/plugins/2600box/macro.h ./rockbox-working/apps/plugins/2600box/macro.h --- ./rockbox/apps/plugins/2600box/macro.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/macro.h 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,99 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: macro.h,v 1.7 1996/11/24 16:55:40 ahornby Exp $ +******************************************************************************/ + +/* + * + * Originally from x64 by + * Vesa-Matti Puro (vmp@lut.fi) + * Jarkko Sonninen (sonninen@lut.fi) + * + * NOTE: Can add zero page optimizations + */ + +#ifndef X2600_MACRO_H +#define X2600_MACRO_H + + +#include "types.h" +#include "cpu.h" + +#define LOAD(a) decRead(a) +#define LOADEXEC(a) undecRead(a) +#define DLOAD(a) dbgRead(a) +#define LOAD_ZERO(a) decRead((ADDRESS)a) +#define LOAD_ADDR(a) ((LOAD(a+1)<<8)+LOAD(a)) +#define LOAD_ZERO_ADDR(a) LOAD_ADDR(a) + +#define STORE(a,b) decWrite((a),(b)) +#define STORE_ZERO(a,b) decWrite((a),(b)) + +#define PUSH(b) decWrite(SP+0x100,(b));SP-- +#define PULL() decRead((++SP)+0x100) + +#define UPPER(ad) (((ad)>>8)&0xff) +#define LOWER(ad) ((ad)&0xff) +#define LOHI(lo,hi) ((lo)|((hi)<<8)) + +#define REL_ADDR(pc,src) (pc+((SIGNED_CHAR)src)) + +#define SET_SIGN(a) (SF=(a)&S_SIGN) +#define SET_ZERO(a) (ZF=!(a)) +#define SET_CARRY(a) (CF=(a)) + +#define SET_INTERRUPT(a) (IF=(a)) +#define SET_DECIMAL(a) (DF=(a)) +#define SET_OVERFLOW(a) (OF=(a)) +#define SET_BREAK(a) (BF=(a)) + +#define SET_SR(a) (SF=(a) & S_SIGN,\ + ZF=(a) & S_ZERO,\ + CF=(a) & S_CARRY,\ + IF=(a) & S_INTERRUPT,\ + DF=(a) & S_DECIMAL,\ + OF=(a) & S_OVERFLOW,\ + BF=(a) & S_BREAK) + +#define GET_SR() ((SF ? S_SIGN : 0) |\ + (ZF ? S_ZERO : 0) |\ + (CF ? S_CARRY : 0) |\ + (IF ? S_INTERRUPT : 0) |\ + (DF ? S_DECIMAL : 0) |\ + (OF ? S_OVERFLOW : 0) |\ + (BF ? S_BREAK : 0) | S_NOTUSED) + +#define IF_SIGN() SF +#define IF_ZERO() ZF +#define IF_CARRY() CF +#define IF_INTERRUPT() IF +#define IF_DECIMAL() DF +#define IF_OVERFLOW() OF +#define IF_BREAK() BF + + +#define sprint_status() sprint_binary(GET_SR()) + + +#endif /* X2600_MACRO_H */ + + + + + + + + + + + diff -ruNp ./rockbox/apps/plugins/2600box/memory.c ./rockbox-working/apps/plugins/2600box/memory.c --- ./rockbox/apps/plugins/2600box/memory.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/memory.c 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,891 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for Details. + + $Id: memory.c,v 2.23 1997/04/06 02:19:12 ahornby Exp $ +******************************************************************************/ + +/* + * Holds the memory access routines to both memory and memory mapped + * i/o, hence memory.c + * + * Uses GNU C extensions. + */ +#include "rbconfig.h" +#include +#include "types.h" +#include "address.h" +#include "vmachine.h" +#include "misc.h" +#include "display.h" +#include "raster.h" +#include "limiter.h" +#include "collision.h" +#include "col_mask.h" +#include "options.h" +#include "keyboard.h" +#include "sound.h" +#include "dbg_mess.h" + +extern CLOCK clkcount; +extern CLOCK clk; +extern int beamadj; + +/* Undecoded Read, for executable code etc. */ +/* a: address to read */ +/* returns: byte at address a */ +BYTE +undecRead (ADDRESS a) +{ + if (a & 0x1000) + return theRom[a & 0xfff]; + else + return theRam[a & 0x7f]; +} + + +inline void +bank_switch_write (ADDRESS a, BYTE b) +{ + a&=0xfff; + switch (base_opts.bank) + { + + case 1: + /* Atari 8k F8 */ + switch (a) + { + case 0xff8: + theRom = &theCart[0]; + break; + case 0xff9: + theRom = &theCart[4096]; + break; + } + break; + + case 2: + /* Atari 16k F6 */ + switch (a) + { + case 0xff6: + theRom = &theCart[0]; + break; + case 0xff7: + theRom = &theCart[4096]; + break; + case 0xff8: + theRom = &theCart[8192]; + break; + case 0xff9: + theRom = &theCart[12288]; + break; + } + break; + + case 3: + /* Parker Brothers 8k E0 */ + { + ADDRESS a1; + if (a > 0xfdf && a < 0xfe8) + { + a1=(a&0x07)<<10; + memcpy(&cartScratch[0],&theCart[a1],0x400); + } + else if (a > 0xfe7 && a < 0xff0) + { + a1=(a&0x07)<<10; + memcpy(&cartScratch[0x400],&theCart[a1],0x400); + } + else if (a > 0xfef && a < 0xff8) + { + a1=(a&0x07)<<10; + memcpy(&cartScratch[0x800],&theCart[a1],0x400); + } + } + break; + + case 4: + /* CBS Ram Plus FA */ + if (a < 0x100) + cartRam[a & 0xff]=b; + else + { + switch (a) + { + case 0xff8: + theRom = &theCart[0]; + break; + case 0xff9: + theRom = &theCart[4096]; + break; + case 0xffa: + theRom = &theCart[8192]; + break; + } + } + break; + + case 5: + /* Atari 16k + super chip ram F6SC */ + if (a < 0x80) + cartRam[a & 0x7f] = b; + else + { + switch (a) + { + case 0xff6: + theRom = &theCart[0]; + break; + case 0xff7: + theRom = &theCart[4096]; + break; + case 0xff8: + theRom = &theCart[8192]; + break; + case 0xff9: + theRom = &theCart[12288]; + break; + } + } + break; + } +} + +inline BYTE +bank_switch_read (ADDRESS a) +{ + BYTE res; + + a&=0xfff; + switch (base_opts.bank) + { + case 1: + /* Atari 8k F8 */ + switch (a) + { + case 0xff8: + theRom = &theCart[0]; + break; + case 0xff9: + theRom = &theCart[4096]; + break; + } + res=theRom[a]; + break; + + case 2: + /* Atari 16k F6 */ + switch (a) + { + case 0xff6: + theRom = &theCart[0]; + break; + case 0xff7: + theRom = &theCart[4096]; + break; + case 0xff8: + theRom = &theCart[8192]; + break; + case 0xff9: + theRom = &theCart[12288]; + break; + } + res=theRom[a]; + break; + + case 3: + /* Parker Brothers 8k E0 */ + /* Parker Brothers 8k E0 */ + { + ADDRESS a1; + if (a > 0xfdf && a < 0xfe8) + { + a1=(a&0x07)<<10; + memcpy(&cartScratch[0],&theCart[a1],0x400); + } + else if (a > 0xfe7 && a < 0xff0) + { + a1=(a&0x07)<<10; + memcpy(&cartScratch[0x400],&theCart[a1],0x400); + } + else if (a > 0xfef && a < 0xff8) + { + a1=(a&0x07)<<10; + memcpy(&cartScratch[0x800],&theCart[a1],0x400); + } + } + res=theRom[a]; + break; + + case 4: + /* CBS Ram Plus FA */ + if (a > 0xff && a < 0x200) + res=cartRam[a & 0xff]; + else + { + switch (a) + { + case 0xff8: + theRom = &theCart[0]; + break; + case 0xff9: + theRom = &theCart[4096]; + break; + case 0xffa: + theRom = &theCart[8192]; + break; + } + res=theRom[a]; + } + break; + + case 5: + /* Atari 16k + super chip ram F6SC */ + if (a > 0x7f && a < 0x100) + res=cartRam[a & 0x7f]; + else + { + switch (a) + { + case 0xff6: + theRom = &theCart[0]; + break; + case 0xff7: + theRom = &theCart[4096]; + break; + case 0xff8: + theRom = &theCart[8192]; + break; + case 0xff9: + theRom = &theCart[12288]; + break; + } + res=theRom[a]; + } + break; + default: + res=theRom[a]; + break; + } + return res; +} + + +/* Decoded write to memory */ +/* a: address written to */ +/* b: byte value written */ +void +decWrite (ADDRESS a, BYTE b) +{ + int i; + + /* A Write to the ROM area */ + if (a & 0x1000) + { + bank_switch_write (a,b); + } + /* A Write to the RAM area in Page 0 and 1 */ + else if ((a & 0x280) == 0x80) + { + theRam[a & 0x7f] = b; + } + /* TIA */ + else if (!(a & 0x80)) + { + switch (a & 0x7f) + { + case VSYNC: + if (b & 0x02) + { + /* Start vertical sync */ + vbeam_state = VSYNCSTATE; + } + break; + case VBLANK: + do_vblank (b); + /* Ground paddle pots */ + if (b & 0x80) + { + /* Grounded ports */ + tiaRead[INPT0] = 0x00; + tiaRead[INPT1] = 0x00; + } + else + { + /* Processor now measures time for a logic 1 to appear + at each paddle port */ + tiaRead[INPT0] = 0x80; + tiaRead[INPT1] = 0x80; + paddle[0].val = clk; + paddle[1].val = clk; + } + /* Logic for dumped input ports */ + if (b & 0x40) + { + if (tiaWrite[VBLANK] & 0x40) + { + tiaRead[INPT4] = 0x80; + tiaRead[INPT5] = 0x80; + } + else + { + read_trigger (); + } + } + tiaWrite[VBLANK] = b; + break; + case WSYNC: + /* Skip to HSYNC pulse */ + do_hsync (); + break; + case RSYNC: + /* used in chip testing */ + dbg_message(DBG_LOTS,"ARGHH an undocumented RSYNC!\n"); + break; + case NUSIZ0: + /* + printf("P0 nusize: ebeamx=%d, ebeamy=%d, nusize=%02x\n", + ebeamx, ebeamy, (int)b); + */ + pl[0].nusize = b & 0x07; + ml[0].width = (b & 0x30) >> 4; + break; + case NUSIZ1: + /* + printf("P1 nusize: ebeamx=%d, ebeamy=%d, nusize=%02x\n", + ebeamx, ebeamy, (int)b); + */ + pl[1].nusize = b & 0x07; + ml[1].width = (b & 0x30) >> 4; + break; + case COLUP0: + do_unified_change (0, tv_color (b)); + break; + case COLUP1: + do_unified_change (1, tv_color (b)); + break; + case COLUPF: + do_unified_change (2, tv_color (b)); + break; + case COLUBK: + /*printf("BKcolour = %d, line=%d\n", (int)(b>>1), ebeamy); */ + do_unified_change (3, tv_color (b)); + break; + case CTRLPF: + tiaWrite[CTRLPF] = b & 0x37; /* Bitmask 00110111 */ + do_pfraster_change (0, 3, b & 0x01); /* Reflection */ + + /* Normal/Alternate priority */ + do_unified_change(4, (b & 0x04)); + + /* Scores/Not scores */ + do_unified_change(5, (b & 0x02)); + + break; + case REFP0: + pl[0].reflect = (b & 0x08) >> 3; + break; + case REFP1: + pl[1].reflect = (b & 0x08) >> 3; + break; + case PF0: + do_pfraster_change (0, 0, b & 0xf0); + break; + case PF1: + do_pfraster_change (0, 1, b); + break; + case PF2: + do_pfraster_change (0, 2, b); + break; + case RESP0: + /* Ghost in pacman! + if(beamadj == 0) { + printf("RESP0: ebeamx=%d, ebeamy=%d\n", + ebeamx, ebeamy); + show(); + } */ + pl[0].x = ebeamx + beamadj; + /* As per page 20 Stella Programmers Guide */ + if (pl[0].x < 0) + pl[0].x = 0; + break; + case RESP1: + /*if(beamadj == 0) { + printf("RESP1: ebeamx=%d, ebeamy=%d\n", + ebeamx, ebeamy); + show(); + } */ + pl[1].x = ebeamx + beamadj; + /* As per page 20 Stella Programmers Guide */ + if (pl[1].x < 0) + pl[1].x = 0; + break; + case RESM0: + ml[0].x = ebeamx + beamadj; + /* As per page 20 Stella Programmers Guide */ + if (ml[0].x < 0) + ml[0].x = 0; + break; + case RESM1: + ml[1].x = ebeamx + beamadj; + /* As per page 20 Stella Programmers Guide */ + if (ml[1].x < 0) + ml[1].x = 0; + break; + case RESBL: + ml[2].x = ebeamx + beamadj; + /* As per page 20 Stella Programmers Guide */ + if (ml[2].x < 0) + ml[2].x = 0; + break; + case AUDC0: + sound_waveform (0, b & 0x0f); + break; + case AUDC1: + sound_waveform (1, b & 0x0f); + break; + case AUDF0: + sound_freq (0, b & 0x1f); + break; + case AUDF1: + sound_freq (1, b & 0x1f); + break; + case AUDV0: + sound_volume (0, b & 0x0f); + break; + case AUDV1: + sound_volume (1, b & 0x0f); + break; + case GRP0: + do_plraster_change (0, 0, b); + do_plraster_change (1, 1, b); + break; + case GRP1: + do_plraster_change (1, 0, b); + do_plraster_change (0, 1, b); + ml[2].vdel = ml[2].enabled; + break; + case ENAM0: + ml[0].enabled = b & 0x02; + if (tiaWrite[RESMP0]) + ml[0].enabled = 0; + break; + case ENAM1: + ml[1].enabled = b & 0x02; + if (tiaWrite[RESMP1]) + ml[1].enabled = 0; + break; + case ENABL: + ml[2].enabled = b & 0x02; + break; + case HMP0: + pl[0].hmm = (b >> 4); + break; + case HMP1: + pl[1].hmm = (b >> 4); + break; + case HMM0: + ml[0].hmm = (b >> 4); + break; + case HMM1: + ml[1].hmm = (b >> 4); + break; + case HMBL: + ml[2].hmm = (b >> 4); + break; + case VDELP0: + pl[0].vdel_flag = b & 0x01; + break; + case VDELP1: + pl[1].vdel_flag = b & 0x01; + break; + case VDELBL: + ml[2].vdel_flag = b & 0x01; + break; + case RESMP0: + tiaWrite[RESMP0] = b & 0x02; + if (b & 0x02) + { + ml[0].x = pl[0].x + 4; + ml[0].enabled = 0; + } + break; + case RESMP1: + tiaWrite[RESMP1] = b & 0x02; + if (b & 0x02) + { + ml[1].x = pl[1].x + 4; + ml[1].enabled = 0; + } + break; + case HMOVE: + /* Player 0 */ + if (pl[0].hmm & 0x08) + pl[0].x += ((pl[0].hmm ^ 0x0f) + 1); + else + pl[0].x -= pl[0].hmm; + if (pl[0].x > 160) + pl[0].x = -68; + else if (pl[0].x < -68) + pl[0].x = 160; + + /* Player 2 */ + if (pl[1].hmm & 0x08) + pl[1].x += ((pl[1].hmm ^ 0x0f) + 1); + else + pl[1].x -= pl[1].hmm; + if (pl[1].x > 160) + pl[1].x = -68; + else if (pl[1].x < -68) + pl[1].x = 160; + + /* Missiles */ + for (i = 0; i < 3; i++) + { + if (ml[i].hmm & 0x08) + ml[i].x += ((ml[i].hmm ^ 0x0f) + 1); + else + ml[i].x -= ml[i].hmm; + if (ml[i].x > 160) + ml[i].x = -68; + else if (ml[i].x < -68) + ml[i].x = 160; + } + break; + case HMCLR: + pl[0].hmm = 0; + pl[1].hmm = 0; + for (i = 0; i < 3; i++) + ml[i].hmm = 0; + break; + case CXCLR: + col_state=0; + break; + } + } + else + { + switch (a & 0x2ff) + { + /* RIOT I/O ports */ + case SWCHA: + riotWrite[SWCHA] = b; + break; + case SWACNT: + riotWrite[SWACNT] = b; + break; + case SWCHB: + case SWBCNT: + /* Do nothing */ + break; + + /* Timer ports */ + case TIM1T: + set_timer (0, b, clkcount); + break; + case TIM8T: + set_timer (3, b, clkcount); + break; + case TIM64T: + set_timer (6, b, clkcount); + break; + case T1024T: + set_timer (10, b, clkcount); + break; + default: + printf ("Unknown write %x\n", a); + show (); + break; + } + } +} + + +/* Decoded read from memory */ +/* a: address to read */ +/* returns: byte value from address a */ +BYTE +decRead (ADDRESS a) +{ + BYTE res = 65; + + if (a & 0x1000) + { + a = a & 0xfff; + if (base_opts.bank != 0) + res= bank_switch_read (a); + else + res = theRom[a]; + } + else if ((a & 0x280) == 0x80) + { + res = theRam[a & 0x7f]; + } + else if (!(a & 0x80)) + { + switch (a & 0x0f) + { + /* TIA */ + case CXM0P: + res = (col_state & CXM0P_MASK) << 6; + break; + case CXM1P: + res = (col_state & CXM1P_MASK) << 4; + break; + case CXP0FB: + res = (col_state & CXP0FB_MASK) << 2; + break; + case CXP1FB: + res = (col_state & CXP1FB_MASK); + break; + case CXM0FB: + res = (col_state & CXM0FB_MASK) >> 2; + break; + case CXM1FB: + res = (col_state & CXM1FB_MASK) >> 4; + break; + case CXBLPF: + res = (col_state & CXBLPF_MASK) >> 5; + break; + case CXPPMM: + res = (col_state & CXPPMM_MASK) >> 7; + break; + case INPT0: + if (base_opts.lcon == PADDLE) + { + tiaRead[INPT0] = do_paddle (0); + } + else if (base_opts.lcon == KEYPAD) + do_keypad (0, 0); + res = tiaRead[INPT0]; + break; + case INPT1: + if (base_opts.lcon == PADDLE) + { + tiaRead[INPT1] = do_paddle (1); + } + if (base_opts.lcon == KEYPAD) + tiaRead[INPT1]=do_keypad (0, 1); + res = tiaRead[INPT1]; + break; + case INPT2: + if (base_opts.rcon == KEYPAD) + do_keypad (1, 0); + res = tiaRead[INPT2]; + break; + case INPT3: + if (base_opts.rcon == KEYPAD) + tiaRead[INPT3]=do_keypad ( 1, 1); + res = tiaRead[INPT3]; + break; + case INPT4: + switch (base_opts.lcon) + { + case KEYPAD: + tiaRead[INPT4]=do_keypad ( 0, 2); + break; + case STICK: + read_trigger (); + break; + } + res =tiaRead[INPT4]; + break; + case INPT5: + switch (base_opts.rcon) + { + case KEYPAD: + tiaRead[INPT5]=do_keypad (1, 2); + break; + case STICK: + read_trigger (); + break; + } + res = tiaRead[INPT5]; + break; + case 0x0e: + case 0x0f: + res = 0x0f; + /* RAM, mapped to page 0 and 1 */ + } + } + else + { + switch (a & 0x2ff) + { + /* Timer output */ + case INTIM: + case 0x285: + case 0x286: + case TIM1T: + case TIM8T: + case TIM64T: + case T1024T: + res = do_timer (clkcount); + /*printf("Timer is %d res is %d\n", res, timer_res); */ + break; + case SWCHA: + switch (base_opts.lcon) + { + case PADDLE: + if (base_opts.lcon == PADDLE) + { + if (mouse_button ()) + riotRead[SWCHA] &= 0x7f; + else + riotRead[SWCHA] |= 0x80; + } + else if (base_opts.rcon == PADDLE) + { + if (mouse_button ()) + riotRead[SWCHA] &= 0xbf; + else + riotRead[SWCHA] |= 0x40; + } + break; + case STICK: + read_stick (); + break; + } + res = riotRead[SWCHA]; + break; + /* Switch B is hardwired to input */ + case SWCHB: + case SWCHB + 0x100: + read_console (); + res = riotRead[SWCHB]; + break; + default: + printf ("Unknown read 0x%x\n", a & 0x2ff); + show (); + res = 65; + break; + } + } + return res; +} + + +/* Debugging read from memory */ +/* a: address to read from */ +/* returns: value at address a, WITHOUT side effects */ +BYTE +dbgRead (ADDRESS a) +{ + BYTE res; + + if (a & 0x1000) + { + a = a & 0xfff; + res = theRom[a]; + if (base_opts.bank != 0) + bank_switch_read (a); + } + else if ((a & 0x280) == 0x80) + { + res = theRam[a & 0x7f]; + } + else if (!(a & 0x80)) + { + switch (a & 0x0f) + { + /* TIA */ + case COLUP0: + res = colour_table[P0M0_COLOUR] & 0xff; + break; + case COLUP1: + res = colour_table[P1M1_COLOUR] & 0xff; + break; + case COLUPF: + res = colour_table[PFBL_COLOUR] & 0xff; + break; + case COLUBK: + res = colour_table[BK_COLOUR] & 0xff; + break; + case CTRLPF: + res = tiaWrite[CTRLPF]; /* Bitmask 00110111 */ + break; + case REFP0: + res = tiaWrite[REFP0]; + break; + case REFP1: + res = tiaWrite[REFP1]; + break; + case PF0: + res = pf[0].pf0; + break; + case PF1: + res = pf[0].pf1; + break; + case PF2: + res = pf[0].pf2; + break; + default: + res = 0; + break; + /* case CXM0P: + break; + case CXM1P: + break; + case CXP0FB: + break; + case CXP1FB: + break; + case CXM0FB: + break; + case CXM1FB: + break; + case CXBLPF: + break; + case CXPPMM: + break; + case INPT0: + break; + case INPT1: + break; + case INPT2: + break; + case INPT3: + break; + case INPT4: + break; + case INPT5: + break; + */ + } + } + else + { + switch (a & 0x2ff) + { + /* Timer output */ + case INTIM: + case 0x285: + case 0x29d: + case INTIM + 0x100: + res = riotRead[INTIM]; + break; + case SWCHA: + case SWCHA + 0x100: + res = riotRead[SWCHA]; + break; + /* Switch B is hardwired to input */ + case SWCHB: + case SWCHB + 0x100: + res = riotRead[SWCHB]; + break; + default: + res = 0; + break; + } + } + return res; +} diff -ruNp ./rockbox/apps/plugins/2600box/memory.h ./rockbox-working/apps/plugins/2600box/memory.h --- ./rockbox/apps/plugins/2600box/memory.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/memory.h 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,36 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: memory.h,v 1.5 1996/11/24 16:55:40 ahornby Exp $ +******************************************************************************/ + +/* + Prototypes for the memory interface. + */ + +#ifndef VCSMEMORY_H +#define VCSMEMORY_H + +inline BYTE +undecRead (ADDRESS a); + +void +decWrite ( ADDRESS a, BYTE b); + +BYTE +decRead (ADDRESS a); + +BYTE +dbgRead (ADDRESS a); + + +#endif diff -ruNp ./rockbox/apps/plugins/2600box/misc.c ./rockbox-working/apps/plugins/2600box/misc.c --- ./rockbox/apps/plugins/2600box/misc.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/misc.c 2013-11-14 08:22:39.503622614 -0500 @@ -0,0 +1,529 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for Details. + + $Id: misc.c,v 1.4 1996/08/26 15:04:20 ahornby Exp $ +******************************************************************************/ + +/* + + * This WAS part of the x64 Commodore 64 emulator. + * + * This file contains misc funtions to help debugging. + * Included are: + * o Show numeric conversions + * o Show CPU registers + * o Show Stack contents + * o Print binary number + * o Print instruction hexas from memory + * o Print instruction from memory + * o Decode instruction + * o Find effective address for operand + * o Create a copy of string + * o Move memory + * + * sprint_opcode returns mnemonic code of machine instruction. + * sprint_binary returns binary form of given code (8bit) + * + * Written by + * Vesa-Matti Puro (vmp@lut.fi) + * Jarkko Sonninen (sonninen@lut.fi) + * Jouko Valta (jopi@stekt.oulu.fi) + * + */ + +//#include +/* #include */ +#include "rbconfig.h" +#include +#include + +#include "cpu.h" +#include "macro.h" +#include "misc.h" +#include "extern.h" +#include "memory.h" +#include "asm.h" + +#define HEX 1 + +/* + * Numeric evaluation with error checking + * + * char *s; pointer to input string + * int level; recursion level + * int mode; flag: dec/hex mode + */ + +int +sconv (char *s, int level, int mode) +{ + static char hexas[] = "0123456789abcdefg"; + char *p = s; + int base = 0; + int result = 0, sign = 1; + int i = 0; + + if (!p) + return (0); + + switch (tolower (*p)) + { + case '%': + p++; + base = 2; + break; + + case 'o': + case '&': + p++; + base = 8; + break; + + case 'x': + case '$': + p++; + base = 16; + break; + + case 'u': + case 'i': + case '#': + p++; + base = 10; + break; + + case '0': /* 0x 0b 0d */ + if (!*++p) + return ((mode & MODE_QUERY) ? 1 : 0); + if (!isdigit (*p)) + return (sconv (p, level + 1, mode)); + + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + base = (mode & MODE_HEX) ? 16 : 10; + break; + + case 'a': + case 'c': + case 'e': + case 'f': + if (mode & MODE_HEX) + base = 16; + break; + + case 'b': /* hex or binary */ + if (mode & MODE_HEX) + base = 16; + else + { + base = 2; + p++; + } + break; + + case 'd': /* hex or decimal */ + if (mode & MODE_HEX) + base = 16; + else + { + base = 10; + p++; + } + break; + + default: + break; + } + + /* + * now p points to start of string to convert and base hold its base + * number 2, 8, 10 or 16 + */ + + if (!base) + return (0); + + if (*p == '-') + { + sign = -1; + p++; + } + while (tolower (*p)) + { + for (i = 0; i < base; i++) + if (*p == hexas[i]) + { + result = result * base + i; + break; + } + if (i >= base) + { + /* unknown char has occurred, return value or error */ + if (strchr (",-+()", *p) || isspace (*p)) + i = 0; + else if (!level && !(mode & MODE_QUERY)) + printf ("Bad character near '%s'\n", p); + + break; + } + p++; + } + /* printf ("mode %02X last %d base %d value %d\n", + mode, i, base, result); */ + + /* return final value */ + return ((mode & MODE_QUERY) ? (i < base) : result * sign); +} + + +/* + * Base conversions. + * (+) -%&#$ + */ + +void +show_bases (char *line, int mode) +{ + char buf[20]; + int temparg = sconv (line, 0, mode); + + strcpy (buf, sprint_binary (UPPER (temparg))); + printf ("\n %17x x\n %17d d\n %17o o\n %s %s b\n\n", + temparg, temparg, temparg, buf, + sprint_binary (LOWER (temparg))); +} + + +/* + * show prints PSW and contents of registers. + */ + +void +show (void) +{ + hexflg = 1; + if (1) + printf (hexflg ? + "PC=%4X AC=%2X XR=%2X YR=%2X PF=%s SP=%2X %3X %3d %s\n" : + "PC=%04d AC=%03d XR=%03d YR=%03d PF=%s SP=%03d %3d %2X %s\n", + (int) PC, (int) AC, (int) XR, (int) YR, + sprint_status (), (int) SP, + LOAD (PC), LOAD (PC), sprint_opcode (PC, hexflg)); + else + printf (hexflg ? "%lx %4X %s\n" : "%ld %4d %s\n", + clk, PC, sprint_opcode (PC, hexflg)); +} + + +void +print_stack (BYTE sp) +{ + int i; + + printf ("Stack: "); + for (i = 0x101 + sp; i < 0x200; i += 2) + printf ("%02X%02X ", dbgRead (i + 1), dbgRead (i)); + printf ("\n"); +} + + +char + * +sprint_binary (BYTE code) +{ + static char bin[9]; + int i; + + bin[8] = 0; /* Terminator. */ + + for (i = 0; i < 8; i++) + { + bin[i] = (code & 128) ? '1' : '0'; + code <<= 1; + } + + return bin; +} + + +/* ------------------------------------------------------------------------- */ + +char + * +sprint_ophex (ADDRESS p) +{ + static char hexbuf[20]; + char *bp; + int j, len; + + len = clength[lookup[DLOAD (p)].addr_mode]; + *hexbuf = '\0'; + for (j = 0, bp = hexbuf; j < 3; j++, bp += 3) + { + if (j < len) + { + sprintf (bp, "%02X ", DLOAD (p + j)); + } + else + { + strcat (bp, " "); + } + } + return hexbuf; +} + + +/* sprint_opcode parameters: + + * string the name of the machine instruction + * addr_mode # describing used addressing mode, see "vmachine.h" + * base if 1==base => HEX, 0==base => DEC, see code + * opcode address of memory where machine instruction + * and argument are. First byte is unused, because + * it is the machine code and it is already known - + * string! + */ + + +char + * +sprint_opcode (ADDRESS counter, int base) +{ + BYTE x = DLOAD (counter); + BYTE p1 = DLOAD (counter + 1); + BYTE p2 = DLOAD (counter + 2); + + return sprint_disassembled (counter, x, p1, p2, base); +} + + +char + * +sprint_disassembled (ADDRESS counter, BYTE x, BYTE p1, BYTE p2, int base) +{ + char *string; + int addr_mode; + char *buffp; + static char buff[20]; + int ival; + + ival = p1 & 0xFF; + + buffp = buff; + string = lookup[x].mnemonic; + addr_mode = lookup[x].addr_mode; + + sprintf (buff, "%s", string); /* Print opcode. */ + while (*++buffp); + + switch (addr_mode) + { + /* + * Bits 0 and 1 are usual marks for X and Y indexed addresses, i.e. + * if bit #0 is set addressing mode is X indexed something and if + * bit #1 is set addressing mode is Y indexed something. This is not + * from MOS6502, but convention used in this program. See + * "vmachine.h" for details. + */ + + /* Print arguments of the machine instruction. */ + + case IMPLIED: + break; + + case ACCUMULATOR: + sprintf (buffp, " A"); + break; + + case IMMEDIATE: + sprintf (buffp, ((base & HEX) ? " #$%02X" : " %3d"), ival); + break; + + case ZERO_PAGE: + sprintf (buffp, ((base & HEX) ? " $%02X" : " %3d"), ival); + break; + + case ZERO_PAGE_X: + sprintf (buffp, ((base & HEX) ? " $%02X,X" : " %3d,X"), ival); + break; + + case ZERO_PAGE_Y: + sprintf (buffp, ((base & HEX) ? " $%02X,Y" : " %3d,Y"), ival); + break; + + case ABSOLUTE: + ival |= ((p2 & 0xFF) << 8); + sprintf (buffp, ((base & HEX) ? " $%04X" : " %5d"), ival); + break; + + case ABSOLUTE_X: + ival |= ((p2 & 0xFF) << 8); + sprintf (buffp, ((base & HEX) ? " $%04X,X" : " %5d,X"), ival); + break; + + case ABSOLUTE_Y: + ival |= ((p2 & 0xFF) << 8); + sprintf (buffp, ((base & HEX) ? " $%04X,Y" : " %5d,Y"), ival); + break; + + case INDIRECT_X: + sprintf (buffp, ((base & HEX) ? " ($%02X,X)" : " (%3d,X)"), ival); + break; + + case INDIRECT_Y: + sprintf (buffp, ((base & HEX) ? " ($%02X),Y" : " (%3d),Y"), ival); + break; + + case ABS_INDIRECT: + ival |= ((p2 & 0xFF) << 8); + sprintf (buffp, ((base & HEX) ? " ($%04X)" : " (%5d)"), ival); + break; + + case RELATIVE: + if (0x80 & ival) + ival -= 256; + ival += counter; + ival += 2; + sprintf (buffp, ((base & HEX) ? " $%04X" : " %5d"), ival); + break; + } + + return buff; +} + + +int +eff_address (ADDRESS counter, int step) +{ + int addr_mode, eff; + BYTE x = LOAD (counter); + BYTE p1 = 0; + ADDRESS p2 = 0; + + + addr_mode = lookup[x].addr_mode; + + switch (clength[addr_mode]) + { + case 2: + p1 = LOAD (counter + 1); + break; + case 3: + p2 = LOAD (counter + 1) | (LOAD (counter + 2) << 8); + break; + } + + switch (addr_mode) + { + + case IMPLIED: + case ACCUMULATOR: + eff = -1; + break; + + case IMMEDIATE: + eff = -1; + break; + + case ZERO_PAGE: + eff = p1; + break; + + case ZERO_PAGE_X: + eff = (p1 + XR) & 0xff; + break; + + case ZERO_PAGE_Y: + eff = (p1 + YR) & 0xff; + break; + + case ABSOLUTE: + eff = p2; + break; + + case ABSOLUTE_X: + eff = p2 + XR; + break; + + case ABSOLUTE_Y: + eff = p2 + YR; + break; + + case ABS_INDIRECT: /* loads 2-byte address */ + eff = p2; + break; + + case INDIRECT_X: + eff = LOAD_ZERO_ADDR (p1 + XR); + break; + + case INDIRECT_Y: + eff = LOAD_ZERO_ADDR (p1) + YR; + break; + + case RELATIVE: + eff = REL_ADDR (counter + 2, p1); + break; + + default: + eff = -1; + } + + return eff; +} + + +/* ------------------------------------------------------------------------- */ + +char + * +xstrdup (char *str) +{ + char *t = (char *) malloc (strlen (str) + 1); + strcpy (t, str); + return (t); +} + + +char + * +strndupp (char *str, int n){ + char *t = (char *) malloc (n + 1); + strncpy (t, str, n); + t[n] = '\0'; + return (t); +} + + +void +memmov (char *target, char *source, unsigned int length) +{ + if (target > source) + { + target += length; + source += length; + while (length--) + *--target = *--source; + } + else if (target < source) + { + while (length--) + *target++ = *source++; + } +} diff -ruNp ./rockbox/apps/plugins/2600box/misc.h ./rockbox-working/apps/plugins/2600box/misc.h --- ./rockbox/apps/plugins/2600box/misc.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/misc.h 2013-11-14 08:22:49.119622303 -0500 @@ -0,0 +1,61 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: misc.h,v 1.2 1996/04/01 14:51:50 alex Exp $ +******************************************************************************/ + +/* + * This file was part of x64. + * + * This file contains misc funtions to help debugging. + * Included are: + * o Show numeric conversions + * o Show CPU registers + * o Show Stack contents + * o Print binary number + * o Print instruction from memory + * o Decode instruction + * o Find effective address for operand + * o Create a copy of string + * o Move memory + * + * sprint_opcode returns mnemonic code of machine instruction. + * sprint_binary returns binary form of given code (8bit) + * + * + * Written by + * Vesa-Matti Puro (vmp@lut.fi) + * Jouko Valta (jopi@stekt.oulu.fi) + * + */ + +#ifndef X2600_MISC_H +#define X2600_MISC_H + +#include "types.h" + +extern void show_bases ( char *line, int mode ); +extern void show ( void ); +extern void print_stack ( BYTE sp ); +extern char *sprint_binary ( BYTE code ); +extern char *sprint_ophex ( ADDRESS p); +extern char *sprint_opcode ( ADDRESS counter, int base ); +extern char *sprint_disassembled ( ADDRESS counter, BYTE x, BYTE p1, BYTE p2, int base ); +extern char *xstrdup ( char *str ); +extern char *strndupp ( char *str, int n ); +extern void memmov ( char *target, char *source, unsigned int length ); +extern int eff_address(ADDRESS counter, int step); + +#endif /* X2600_MISC_H */ + + + diff -ruNp ./rockbox/apps/plugins/2600box/mnemonic.h ./rockbox-working/apps/plugins/2600box/mnemonic.h --- ./rockbox/apps/plugins/2600box/mnemonic.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/mnemonic.h 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,141 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: mnemonic.h,v 1.2 1996/04/01 14:51:50 alex Exp $ +******************************************************************************/ + +/* + * + * This file was part of x64. + * See README for copyright notice + * + * This file contains #defines for MOS6010 instruction mnemonics. + * + * Written by + * Vesa-Matti Puro (vmp@lut.fi) + * Jouko Valta (jopi@stekt.oulu.fi) + */ + +#ifndef X2600_MNEMONIC_H +#define X2600_MNEMONIC_H + + +/* INSTRUCTION MNEMONICS. */ + +#define ADC "ADC" +#define AND "AND" +#define ASL "ASL" +#define BCC "BCC" +#define BCS "BCS" +#define BEQ "BEQ" +#define BIT "BIT" +#define BMI "BMI" +#define BNE "BNE" +#define BPL "BPL" +#define BRK "BRK" +#define BVC "BVC" +#define BVS "BVS" +#define CLC "CLC" +#define CLD "CLD" +#define CLI "CLI" +#define CLV "CLV" +#define CMP "CMP" +#define CPX "CPX" +#define CPY "CPY" +#define DEC "DEC" +#define DEX "DEX" +#define DEY "DEY" +#define EOR "EOR" +#define INC "INC" +#define INX "INX" +#define INY "INY" +#define JMP "JMP" +#define JSR "JSR" +#define LDA "LDA" +#define LDX "LDX" +#define LDY "LDY" +#define LSR "LSR" +#define NOOP "NOOP" +#define NOP "NOP" +#define ORA "ORA" +#define PHA "PHA" +#define PHP "PHP" +#define PLA "PLA" +#define PLP "PLP" +#define ROL "ROL" +#define ROR "ROR" +#define RTI "RTI" +#define RTS "RTS" +#define SBC "SBC" +#define SEC "SEC" +#define SED "SED" +#define SEI "SEI" +#define STA "STA" +#define STX "STX" +#define STY "STY" +#define TAX "TAX" +#define TAY "TAY" +#define TSX "TSX" +#define TXA "TXA" +#define TXS "TXS" +#define TYA "TYA" + +#ifndef NO_UNDOC_CMDS +#define ANC "ANC" +#define ANE "ANE" +#define ARR "ARR" +#define ASR "ASR" +#define DCP "DCP" +#define ISB "ISB" +#define JAM "JAM" +#define LAS "LAS" +#define LAX "LAX" +#define LXA "LXA" + /* NOOP undefined NOP */ +#define RLA "RLA" +#define RRA "RRA" +#define SAX "SAX" +#define USBC "USBC" /* undefined SBC */ +#define SBX "SBX" +#define SHA "SHA" +#define SHS "SHS" +#define SHX "SHX" +#define SHY "SHY" +#define SLO "SLO" +#define SRE "SRE" + +#else +#define ANC NOOP +#define ANE NOOP +#define ARR NOOP +#define ASR NOOP +#define DCP NOOP +#define ISB NOOP +#define JAM NOOP +#define LAS NOOP +#define LAX NOOP +#define LXA NOOP + /* NOOP undefined NOP */ +#define RLA NOOP +#define RRA NOOP +#define SAX NOOP +#define USBC NOOP +#define SBX NOOP +#define SHA NOOP +#define SHS NOOP +#define SHX NOOP +#define SHY NOOP +#define SLO NOOP +#define SRE NOOP +#endif + +#endif /* X2600_MNEMONIC_H */ diff -ruNp ./rockbox/apps/plugins/2600box/moudrv.h ./rockbox-working/apps/plugins/2600box/moudrv.h --- ./rockbox/apps/plugins/2600box/moudrv.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/moudrv.h 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,16 @@ +#ifndef MOUDRV_H +#define MOUDRV_H + +void +moudrv_init(void); + +void +moudrv_close(void); + +void +moudrv_read(void); + +void +moudrv_update(void); + +#endif diff -ruNp ./rockbox/apps/plugins/2600box/no_joy.c ./rockbox-working/apps/plugins/2600box/no_joy.c --- ./rockbox/apps/plugins/2600box/no_joy.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/no_joy.c 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,41 @@ + + +#define LJOYMASK 0x01 +#define RJOYMASK 0x02 +#define UJOYMASK 0x04 +#define DJOYMASK 0x08 +#define B1JOYMASK 0x10 +#define B2JOYMASK 0x20 + +/* This should be called from xxx_keyb.c */ +int +get_realjoy (int stick) +{ + return 0; +} + + +/* This should be called once per frame */ +void +update_realjoy (void) +{ +} + + +/* These can be called from anywhere. */ +void +calibrate_realjoy (int stick) +{ +} + + +void +init_realjoy (void) +{ +} + + +void +close_realjoy (void) +{ +} diff -ruNp ./rockbox/apps/plugins/2600box/no_mouse.c ./rockbox-working/apps/plugins/2600box/no_mouse.c --- ./rockbox/apps/plugins/2600box/no_mouse.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/no_mouse.c 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,21 @@ + +void +moudrv_init(void) +{ +} + +void +moudrv_close(void) +{ +} + +void +moudrv_read(void) +{ +} + +void +moudrv_update(void) +{ +} + diff -ruNp ./rockbox/apps/plugins/2600box/no_sound.c ./rockbox-working/apps/plugins/2600box/no_sound.c --- ./rockbox/apps/plugins/2600box/no_sound.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/no_sound.c 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,41 @@ + + +/* A set of sound stubs for those without sound */ +/* $Id: no_sound.c,v 1.4 1996/11/24 16:55:40 ahornby Exp $ */ +#include "types.h" + + +void +sound_init (void) +{ +} + +void +sound_close (void) +{ +} + +void +sound_freq (int channel, BYTE freq) +{ +} + +void +sound_volume (int channel, BYTE vol) +{ +} + +void +sound_waveform (int channel, BYTE value) +{ +} + +void +sound_flush (void) +{ +} + +void +sound_update (void) +{ +} diff -ruNp ./rockbox/apps/plugins/2600box/no_ui.c ./rockbox-working/apps/plugins/2600box/no_ui.c --- ./rockbox/apps/plugins/2600box/no_ui.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/no_ui.c 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,37 @@ + +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: no_ui.c,v 1.3 1996/11/24 16:55:40 ahornby Exp $ +******************************************************************************/ + +/* + User Interface (UI) prototypes for those without FWF etc. + */ +#include "rbconfig.h" + +#if HAVE_LIBXT +#include +#else +typedef int Widget; +#endif + +void +fancy_widgets (Widget parent) +{ +} + +int +fselLoad (void) +{ + return 0; +} diff -ruNp ./rockbox/apps/plugins/2600box/okie.h ./rockbox-working/apps/plugins/2600box/okie.h --- ./rockbox/apps/plugins/2600box/okie.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/okie.h 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,130 @@ +ADDRESS okie_dokie_data[]={ +0xffff,0xffff,0xffff,0x5000,0x8888,0x0050,0x0050,0x0000 +,0x5000,0x5088,0x0000,0x8850,0x8800,0x8888,0x0088,0x0000 +,0xd8d8,0x0000,0xd850,0x8888,0x50d8,0x5088,0x8888,0x8850 +,0x88f8,0x2020,0xf888,0x0088,0x0000,0x8800,0xd850,0xd8d8 +,0x50d8,0x2000,0x8888,0x0020,0xf888,0x7070,0x88f8,0x0000 +,0x1010,0x0000,0x0000,0x0000,0x0010,0xa0e0,0xa0a0,0x38a8 +,0x0800,0x2010,0x0000,0x4830,0x48a0,0x0880,0x0010,0x0080 +,0x1040,0xff80,0x0190,0x9090,0x38c0,0x28c0,0x2850,0x6838 +,0x48b0,0x4030,0xf0f8,0xf0f8,0xf0f8,0x10a8,0x08a0,0x0800 +,0xf8d8,0x98e8,0xf878,0x0000,0x1048,0x5000,0x50c8,0xa040 +,0x8010,0x00e0,0x30c8,0x30c0,0x0150,0x8030,0x8101,0xb010 +,0x1880,0x7880,0x0000,0x0000,0x0000,0x8900,0x928b,0x88e1 +,0xf78b,0x0003,0x0000,0x09c9,0xdd89,0x0088,0x00ff,0x0080 +,0x0600,0xa909,0x0146,0x807e,0x0000,0x0000,0x2a14,0x4149 +,0x0080,0x0000,0x0000,0x3500,0x4949,0x8039,0x0000,0x0000 +,0x0000,0x0c07,0x47aa,0x0000,0x0000,0x0000,0xffff,0xffff +,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 +,0x3800,0x6c7c,0xbad6,0xfeba,0xd6fe,0x7c7c,0x0038,0x2a00 +,0x827c,0xee6c,0x82aa,0x44ba,0x7c38,0xd6ee,0xc67c,0xec82 +,0x3818,0x6828,0x88c8,0x0404,0x0404,0x0202,0x0102,0x4201 +,0x3838,0x2828,0xeeee,0x8282,0xeeee,0x2828,0x3838,0x4800 +,0x1010,0x2828,0x5454,0xbaba,0x5454,0x2828,0x1010,0xac00 +,0x2810,0x2c2c,0x2828,0x282c,0x7c38,0xf6f6,0x6cf6,0x0e38 +,0x8200,0xba92,0x546c,0x546c,0xba6c,0xaa92,0x1028,0xc200 +,0xee44,0x4444,0x8282,0x7c54,0xfe6c,0x7cba,0x0038,0x6200 +,0x387c,0xa510,0x18ac,0x1069,0xac85,0x90c9,0x04d0,0x10a9 +,0xac85,0xa960,0x8501,0x8525,0xa426,0xb183,0x85ae,0x851b +,0xb102,0x85b0,0xb11c,0x85b2,0xb11b,0x85b4,0xb19e,0xaab6 +,0xb8b1,0xa5a8,0x859e,0x861c,0x841b,0x851c,0xc61b,0x1083 +,0xa9d8,0x8500,0x8525,0x8526,0x851c,0x851b,0x601c,0x80a5 +,0x83e5,0x8085,0xa060,0xa905,0x9900,0x00a0,0xc699,0x8800 +,0xf510,0x9860,0xe918,0xaa0b,0x8cb5,0x8b45,0x8c95,0xff60 +,0x0000,0x0000,0x0000,0x4080,0x4038,0x0080,0x8870,0x7088 +,0xf000,0x0808,0x00f0,0xe000,0x3018,0xe018,0x8800,0x88f8 +,0xf800,0x2040,0xf810,0xe800,0x0000,0x0000,0x0000,0x0000 +,0x0000,0x4800,0xa8a8,0x0090,0xa8f8,0x8888,0xf800,0x0808 +,0x0008,0xa8f8,0x8888,0xf800,0x8888,0x0088,0x8080,0x80f8 +,0x0080,0xf800,0x0808,0x0008,0xa8f8,0x8888,0xc000,0x0830 +,0xc030,0xf800,0x88a8,0x0088,0x08f8,0x0808,0x0008,0x0000 +,0x0000,0x0ba2,0xf9a9,0xae95,0xa9ca,0x9500,0xcaae,0xf410 +,0x82a5,0xe918,0x180b,0xaa2a,0x90a9,0xae95,0xa960,0x85f8 +,0x8493,0xa092,0xb105,0x9992,0x008c,0x1088,0x60f8,0xf8a9 +,0x9385,0xaba5,0x9285,0x05a0,0x92b1,0x8c59,0x9900,0x008c +,0x1088,0x60f5,0xd878,0xffa2,0xe89a,0xa08a,0x9510,0xca00 +,0xfbd0,0xd088,0xa9f8,0x850c,0x8582,0xa915,0x8510,0x85ac +,0x20ad,0xf9e5,0x03a9,0x8685,0x7f20,0xc6ff,0x20c0,0xfa72 +,0xffa2,0x86a5,0x01c9,0x02d0,0x3ca6,0xa786,0x9fc6,0x0410 +,0x00a9,0x1985,0x57a9,0x0285,0x0185,0x0085,0x2aa9,0x958d +,0xac02,0x0284,0xfbd0,0x0284,0x0084,0x24a9,0x968d,0xa502 +,0xc986,0x3002,0xd00a,0x2005,0xffac,0x88e6,0x3d20,0xadff +,0x0282,0xb06a,0xa539,0x85ac,0xa2ad,0x8600,0x861a,0x2088 +,0xff9c,0x86e8,0xa586,0xc9a6,0xd0b4,0xa518,0xc5aa,0xd0ab +,0xca04,0x9c20,0x20ff,0xf9e5,0xaaa4,0x8d20,0x20fa,0xfa9e +,0xbb4c,0x20fb,0xf9e5,0xa6a4,0x8d20,0x4cfa,0xfbbb,0xa2a8 +,0x2001,0xff9c,0x9320,0x98f9,0xb06a,0xa533,0xd081,0xe64c +,0xa581,0xf086,0xa90f,0x8500,0x8586,0x8588,0xa91a,0x85fa +,0x20a6,0xf9e5,0xa6a5,0x6918,0xc906,0xd0ba,0x2005,0xf9e5 +,0x00a9,0xa685,0x20a8,0xfa8d,0x7f20,0x4cff,0xfc68,0xf0a0 +,0x86a5,0x01c9,0x06d0,0x80ad,0x2902,0xa8f0,0xf0c0,0x0bd0 +,0xa7a5,0x0710,0x00a9,0x8185,0x684c,0xa6fc,0xe681,0xe081 +,0xf000,0xe00d,0xf010,0x4c03,0xfc68,0x00a9,0x8185,0xf7f0 +,0xa7a5,0x3a10,0x0a98,0x0bb0,0x82a4,0xc0c8,0xd012,0xa002 +,0x840c,0x0a82,0x0bb0,0x82a4,0xc088,0xd00b,0xa002,0x8411 +,0x0a82,0x0fb0,0x8ae6,0x8aa5,0x05c9,0x12d0,0x00a9,0x8a85 +,0x0e4c,0x0afc,0x08b0,0x8ac6,0x0410,0x04a0,0x8a84,0xa7a5 +,0x8029,0x54d0,0x7f20,0xa6ff,0xe88a,0x37bd,0x85ff,0xa48b +,0x2082,0xf9f3,0x8aa6,0xbde8,0xff31,0x8b85,0xf020,0xc8fd +,0x06c0,0x03f0,0xf320,0x88f9,0x3088,0x202d,0xf9f3,0x05a0 +,0x9e84,0x8cb9,0x2900,0xf0f8,0xa904,0x8500,0x889e,0xf210 +,0x9ea5,0x14f0,0x02a9,0x8685,0x0aa9,0xc185,0xc585,0x04a9 +,0x1685,0x00a9,0xa985,0x8885,0x88a5,0x0985,0x84ac,0xd002 +,0x84fb,0xa002,0x8404,0x8401,0xa902,0x8585,0x8480,0xa902 +,0x8500,0x850d,0x850e,0x850f,0x850b,0x8621,0xa602,0xa080 +,0x8400,0xe089,0xd075,0xa930,0x8584,0xa908,0x8501,0xa50a +,0x8588,0x8506,0xa207,0xbd0b,0xffd6,0x9295,0x10ca,0x20f8 +,0xfd4e,0xffa9,0x0f85,0x06a0,0x8384,0x18a9,0x0685,0x0785 +,0x6e20,0xa2fd,0x8671,0xe080,0xd071,0xa912,0x8501,0xa90f +,0xa0f9,0x990d,0x0092,0x8888,0xf910,0x444c,0xc8fd,0x70e0 +,0x34f0,0xe0c8,0xf060,0xc82f,0x50e0,0x2af0,0xe0c8,0xf040 +,0xc825,0x30e0,0x20f0,0xe0c8,0xd020,0x8449,0xa989,0x85ff +,0x200f,0xfddf,0x08a9,0x8385,0x6e20,0xa9fd,0x8500,0x200f +,0xfefc,0x09a0,0x07d0,0x8984,0xd020,0xa0fe,0x840e,0xa683 +,0xbdad,0xf90f,0x0685,0x0785,0xde20,0x20f9,0xfd6e,0x88a5 +,0x89a6,0xe4ca,0xd08a,0xa902,0x8543,0x8506,0xa007,0x8402 +,0x2083,0xf9a3,0x80c6,0x03f0,0x8b4c,0x4cfc,0xfadb,0x03a9 +,0x0485,0x0585,0x06a2,0x00a0,0x0285,0x10ca,0xeafd,0x1085 +,0x1185,0xd0a9,0x2085,0xe0a9,0x2185,0x0285,0x2a85,0x01a9 +,0x2585,0x2685,0x83a4,0x92b1,0x1b85,0x0285,0x94b1,0x1c85 +,0x96b1,0x1b85,0x98b1,0x9e85,0x9ab1,0xb1aa,0xa89c,0x9ea5 +,0x1c85,0x1b86,0x1c84,0x1b85,0x83c6,0xd810,0x00a9,0x2585 +,0x2685,0x1c85,0x1b85,0x1c85,0x0060,0x8971,0x8989,0x7089 +,0x2900,0x8a4b,0x2841,0x0000,0x00c0,0xc080,0x0000,0xf000 +,0x8989,0x8888,0x00f0,0x15e4,0xe516,0x0004,0xa700,0x2a2c +,0xa007,0xba00,0xc5f8,0xd0f8,0xdbf8,0xe6f8,0xf1f8,0xa5f8 +,0x85c0,0x8506,0xa207,0xbd0b,0xfdd3,0x9295,0x10ca,0x60f8 +,0x1898,0x0be9,0xb5aa,0x45c6,0x958b,0x60c6,0xffff,0xffff +,0x0000,0x4438,0x4444,0x4444,0x3844,0x0000,0x0000,0x0000 +,0x0000,0x1010,0x1010,0x1010,0x1030,0x0000,0x0000,0x0000 +,0x0000,0x407c,0x3040,0x0408,0x3844,0x0000,0x0000,0x0000 +,0x0000,0x4438,0x0444,0x0418,0x3844,0x0000,0x0000,0x0000 +,0x0000,0x0404,0x447e,0x1424,0x040c,0x0000,0x0000,0x0000 +,0x0000,0x4438,0x0444,0x4078,0x7c40,0x0000,0x0000,0x0000 +,0x0000,0x4438,0x7844,0x4040,0x3844,0x0000,0x0000,0x0000 +,0x0000,0x2020,0x1010,0x0808,0x7804,0x0000,0x0000,0x0000 +,0x0000,0x4438,0x4444,0x4438,0x3844,0x0000,0x0000,0x0000 +,0x0000,0x4438,0x3c04,0x4444,0x3844,0x0000,0x0000,0x0000 +,0xfc00,0x8080,0x8080,0x8080,0x8080,0x0000,0x0000,0x0000 +,0x1000,0x2828,0x4444,0x8282,0x8282,0x0000,0x0000,0x0000 +,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 +,0x0285,0x89a6,0x31bd,0x85ff,0xa28b,0xa00d,0xa506,0x103d +,0xb906,0x008c,0xea4c,0xb9fe,0x00c6,0x8b25,0x04d0,0x00a9 +,0x02f0,0xada5,0x9195,0xcaca,0x1088,0x60e2,0x0ba2,0x05a0 +,0xfea9,0x9295,0xa0b9,0x9500,0xca91,0x88ca,0xf210,0xc0a9 +,0x9285,0x86a4,0x0ad0,0xa0a9,0x9285,0x9685,0xb0a9,0x9485 +,0xc0a9,0x9c85,0x03c0,0x08d0,0x9485,0x9685,0x9885,0x9a85 +,0x0060,0x4080,0x1020,0x0008,0xe0c0,0x3870,0xe61c,0xa5a8 +,0xc9a8,0xd008,0xa939,0x8500,0xa9a8,0x85fa,0xa993,0xa42d +,0xc086,0xf003,0xa906,0x85fa,0xa993,0x1800,0xa965,0x9285 +,0x05a0,0x92b1,0x8c99,0x8800,0xf810,0xa9e6,0x27a9,0x86a4 +,0x02c0,0x02f0,0x40a9,0xa9c5,0x04d0,0x00a9,0xa985,0xa960 +,0x85ff,0xa919,0x8510,0xf89f,0x04a2,0xa0b5,0x6918,0x9510 +,0xc9a0,0xd000,0xca05,0x00e0,0xf0d0,0x60d8,0xaab5,0x6918 +,0x9506,0xc9aa,0xd0b4,0xa904,0x9500,0x60aa,0xc1a5,0x2130 +,0xc5c6,0xc5a5,0x04c9,0x19f0,0x00c9,0x14d0,0xc1c6,0x1030 +,0x08a9,0x1a85,0xc1a6,0xe2bd,0x85ff,0xbdc5,0xffec,0x1885 +,0xa960,0x8500,0x601a,0xfda9,0xfdb0,0xfdb7,0xfdbe,0xfdc5 +,0xfdcc,0x0920,0x2009,0x1818,0x1818,0x0909,0x100e,0x1412 +,0x1011,0x1011,0x1312,0xffff,0xffff,0xffff,0xfab4,0xfab4}; + diff -ruNp ./rockbox/apps/plugins/2600box/options.c ./rockbox-working/apps/plugins/2600box/options.c --- ./rockbox/apps/plugins/2600box/options.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/options.c 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,75 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: options.c,v 1.7 1996/11/24 16:55:40 ahornby Exp $ +******************************************************************************/ + +/* Command Line Option Parser */ +#include "rbconfig.h" +#include +#include +/* #include */ + + +#include "dbg_mess.h" + + +#include "version.h" +/* *INDENT-OFF* */ +/* Options common to all ports of x2600 */ +struct BaseOptions { + int rr; + int tvtype; + int lcon; + int rcon; + int bank; + int magstep; + char filename[80]; + int sound; + int swap; + int realjoy; + int limit; + int mousey; + int mitshm; + int dbg_level; +} base_opts={1,0,0,0,0,1,"",0,0,0,0,0,1,0}; + +static void +copyright(void) +{ + +} + +static void +base_usage(void) +{ + +} + +static void +usage(void) +{ + base_usage(); +} + +int +parse_options(char *file) +{ + strcpy ( &base_opts.filename[0] , file ); + return 0; +} + + + + + + diff -ruNp ./rockbox/apps/plugins/2600box/options.h ./rockbox-working/apps/plugins/2600box/options.h --- ./rockbox/apps/plugins/2600box/options.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/options.h 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,27 @@ +#ifndef OPTIONS_H +#define OPTIONS_H + +enum {NTSC=0, PAL=1, SECAM=2}; + +/* Options common to all ports of x2600 */ +extern struct BaseOptions { + int rr; + int tvtype; + int lcon; + int rcon; + int bank; + int magstep; + char filename[80]; + int sound; + int swap; + int realjoy; + int limit; + int mousey; + int mitshm; + int dbg_level; +} base_opts; + +int +parse_options(char *file); + +#endif diff -ruNp ./rockbox/apps/plugins/2600box/raster.c ./rockbox-working/apps/plugins/2600box/raster.c --- ./rockbox/apps/plugins/2600box/raster.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/raster.c 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,1172 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for Details. + + $Id: raster.c,v 1.30 1997/11/22 14:27:47 ahornby Exp $ +******************************************************************************/ + +/* Raster graphics procedures */ + +#include "rbconfig.h" + +#include +#include "types.h" +#include "address.h" +#include "vmachine.h" +#include "display.h" +#include "options.h" +#include "debug.h" +#include "dbg_mess.h" +#include "collision.h" + +/* Color lookup tables. Used to speed up rendering */ +/* The current colour lookup table */ +unsigned int *colour_lookup; + +/* Colour table */ +#define P0M0_COLOUR 0 +#define P1M1_COLOUR 1 +#define PFBL_COLOUR 2 +#define BK_COLOUR 3 + +unsigned int colour_table[4]; + +/* normal/alternate, not scores/scores*/ +int norm_val, scores_val; +int *colour_ptrs[2][3]; + +/* Normal priority */ +static int colour_normal[64]; +static int colour_normscoresl[64]; +static int colour_normscoresr[64]; + +/* Alternate priority */ +static int colour_alternate[64]; +static int colour_altscoresl[64]; +static int colour_altscoresr[64]; + +/* Playfield screen position */ +UINT32 *pf_pos; +BYTE *line_ptr; + +/* Draw playfield register PF0 */ +/* pf: playfield structure */ +/* dir: 1=normal, 0=mirrored */ +inline void +draw_pf0 (struct PlayField *pf, int dir) +{ + int pfm; /* playfield mask */ + /* 1=forward */ + if (dir) + { + for (pfm = 0x10; pfm < 0x100; pfm <<= 1) + { + if (pf->pf0 & pfm) + *(pf_pos++) = PF_MASK32; + else + pf_pos++; + } + } + else + { + for (pfm = 0x80; pfm > 0x08; pfm >>= 1) + { + if (pf->pf0 & pfm) + *(pf_pos++) = PF_MASK32; + else + pf_pos++; + } + } +} + +/* Draw playfield register PF1 */ +/* pf: playfield structure */ +/* dir: 1=normal, 0=mirrored */ +inline void +draw_pf1 (struct PlayField *pf, int dir) +{ + int pfm; /* playfield mask */ + /* 1=forward */ + if (dir) + { + /* do PF1 */ + for (pfm = 0x80; pfm > 0; pfm >>= 1) + { + if (pf->pf1 & pfm) + *(pf_pos++) = PF_MASK32; + else + pf_pos ++; + } + } + else + { + /* do PF1 */ + for (pfm = 0x01; pfm < 0x100; pfm <<= 1) + { + if (pf->pf1 & pfm) + *(pf_pos++) = PF_MASK32; + else + pf_pos ++; + } + } +} + +/* Draw playfield register PF2 */ +/* pf: playfield structure */ +/* dir: 1=normal, 0=mirrored */ +inline void +draw_pf2 (struct PlayField *pf, int dir) +{ + int pfm; /* playfield mask */ + /* 1=forward */ + if (dir) + { + /* do PF2 */ + for (pfm = 0x01; pfm < 0x100; pfm <<= 1) + { + if (pf->pf2 & pfm) + *(pf_pos++) = PF_MASK32; + else + pf_pos ++; + } + } + else + { + for (pfm = 0x80; pfm > 0; pfm >>= 1) + { + if (pf->pf2 & pfm) + *(pf_pos++) = PF_MASK32; + else + pf_pos ++; + } + } +} + +/* Update from the playfield display list */ +/* num: playfield to use. Now depreciated as only pf[0] is used */ +/* nextx: the start position of the next playfield element */ +/* pfc: the number of the next playfield change structure */ +/* pf_max: the highest playfield change structure */ +inline void +pf_update (int num, int nextx, int *pfc, int pf_max) +{ + for (; (*pfc < pf_max) && (nextx + 3 > pf_change[num][*pfc].x); (*pfc)++) + { + use_pfraster_change (&pf[num], &pf_change[num][*pfc]); + } +} + +/* Draw the playfield */ +void +draw_playfield (void) +{ + const int num = 0; /* Stick to one playfield */ + int pfc = 0; + int pf_max = pf_change_count[num]; + + pf_pos = (UINT32 *)colvect; + /* First half of playfield */ + + pf_update (num, 0, &pfc, pf_max); + draw_pf0 (&pf[0], 1); + pf_update (num, 16, &pfc, pf_max); + draw_pf1 (&pf[0], 1); + pf_update (num, 48, &pfc, pf_max); + draw_pf2 (&pf[0], 1); + + pf_update (num, 80, &pfc, pf_max); + /* Second half of playfield */ + if (pf[0].ref) + { + draw_pf2 (&pf[0], 0); + pf_update (num, 112, &pfc, pf_max); + draw_pf1 (&pf[0], 0); + pf_update (num, 144, &pfc, pf_max); + draw_pf0 (&pf[0], 0); + } + else + { + draw_pf0 (&pf[0], 1); + pf_update (num, 96, &pfc, pf_max); + draw_pf1 (&pf[0], 1); + pf_update (num, 128, &pfc, pf_max); + draw_pf2 (&pf[0], 1); + } + /* Use last changes */ + for (; pfc < pf_max; pfc++) + use_pfraster_change (&pf[num], &pf_change[num][pfc]); + + pf_change_count[num] = 0; +} + +/* Draws a normal (8 clocks) sized player */ +/* p: the player to draw */ +/* x: the position to draw it */ +inline void +pl_normal (struct Player *p, int x) +{ + /* Set pointer to start of player graphic */ + BYTE *ptr = colvect + x; + BYTE mask; + BYTE gr; + + if (p->vdel_flag) + gr = p->vdel; + else + gr = p->grp; + + if (p->reflect) + { + /* Reflected: start with D0 of GRP on left */ + for (mask = 0x01; mask > 0; mask <<= 1) + { + if (gr & mask) + { + *(ptr++) |= p->mask; + } + else + ptr++; + } + } + else + { + /* Unreflected: start with D7 of GRP on left */ + for (mask = 0x80; mask > 0; mask >>= 1) + { + if (gr & mask) + { + *(ptr++) |= p->mask; + } + else + ptr++; + } + } +} + +/* Draws a double width ( 16 clocks ) player */ +/* p: the player to draw */ +/* x: the position to draw it */ +inline void +pl_double (struct Player *p, int x) +{ + /* Set pointer to start of player graphic */ + BYTE *ptr = colvect + (x); + BYTE mask; + BYTE gr; + + if (p->vdel_flag) + gr = p->vdel; + else + gr = p->grp; + + if (p->reflect) + { + for (mask = 0x01; mask > 0; mask <<= 1) + { + if (gr & mask) + { + *(ptr++) |= p->mask; + *(ptr++) |= p->mask; + } + else + ptr += 2; + } + } + else + { + for (mask = 0x80; mask > 0; mask >>= 1) + { + if (gr & mask) + { + *(ptr++) |= p->mask; + *(ptr++) |= p->mask; + } + else + ptr += 2; + } + } +} + +/* Draws a quad sized ( 32 clocks) player */ +/* p: the player to draw */ +/* x: the position to draw it */ +inline void +pl_quad (struct Player *p, int x) +{ + /* Set pointer to start of player graphic */ + BYTE *ptr = colvect + x; + BYTE mask; + BYTE gr; + + if (p->vdel_flag) + gr = p->vdel; + else + gr = p->grp; + + if (p->reflect) + { + for (mask = 0x01; mask > 0; mask <<= 1) + { + if (gr & mask) + { + *(ptr++) |= p->mask; + *(ptr++) |= p->mask; + *(ptr++) |= p->mask; + *(ptr++) |= p->mask; + } + else + ptr += 4; + } + } + else + { + for (mask = 0x80; mask > 0; mask >>= 1) + { + if (gr & mask) + { + *(ptr++) |= p->mask; + *(ptr++) |= p->mask; + *(ptr++) |= p->mask; + *(ptr++) |= p->mask; + } + else + ptr += 4; + } + } +} + +/* Consume the player display list */ +inline void +pl_update (int num, int nextx, int *plc, int pl_max) +{ + for (; (*plc < pl_max) && (nextx > pl_change[num][*plc].x); (*plc)++) + { + use_plraster_change (&pl[num], &pl_change[num][*plc]); + } +} + +/* Draw a player graphic */ +/* line: the vertical position of the raster */ +/* num: the number of player to draw, current 0 or 1 for P0 and P1 */ +static inline void +pl_draw (int num) +{ + int plc = 0; + int pl_max = pl_change_count[num]; + int nextx; + + pl_update (num, pl[num].x, &plc, pl_max); + if (pl[num].x >= 0 && pl[num].x < tv_width) + { + + /*if(pl_max > plc) + use_plraster_change( &pl[num], &pl_change[num][plc++]); */ + switch (pl[num].nusize) + { + case 0: + /* One copy */ + pl_normal (&pl[num], pl[num].x); + break; + case 1: + /* Two copies close */ + pl_normal (&pl[num], pl[num].x); + nextx = pl[num].x + 8 + 8; + pl_update (num, nextx, &plc, pl_max); + pl_normal (&pl[num], nextx); + break; + case 2: + /* Two copies medium */ + pl_normal (&pl[num], pl[num].x); + nextx = pl[num].x + 8 + 24; + pl_update (num, nextx, &plc, pl_max); + pl_normal (&pl[num], nextx); + break; + case 3: + /* Three copies close */ + /* Pacman score line */ + pl_normal (&pl[num], pl[num].x); + + nextx = pl[num].x + 16; + pl_update (num, nextx, &plc, pl_max); + pl_normal (&pl[num], nextx); + + nextx = pl[num].x + 32; + pl_update (num, nextx, &plc, pl_max); + + pl_normal (&pl[num], nextx); + break; + case 4: + /* Two copies wide */ + pl_normal (&pl[num], pl[num].x); + nextx = pl[num].x + 8 + 56; + pl_update (num, nextx, &plc, pl_max); + pl_normal (&pl[num], nextx); + break; + case 5: + /* Double sized player */ + pl_double (&pl[num], pl[num].x); + break; + case 6: + /* Three copies medium */ + pl_normal (&pl[num], pl[num].x); + nextx = pl[num].x + 8 + 24; + pl_update (num, nextx, &plc, pl_max); + pl_normal (&pl[num], nextx); + nextx = pl[num].x + 8 + 56; + pl_update (num, nextx, &plc, pl_max); + pl_normal (&pl[num], nextx); + break; + case 7: + /* Quad sized player */ + pl_quad (&pl[num], pl[num].x); + break; + } + } + /* Use last changes */ + for (; plc < pl_max; plc++) + use_plraster_change (&pl[num], &pl_change[num][plc]); + pl_change_count[num] = 0; +} + + +/* Draw the ball graphic */ +/* line: the vertical position of the raster */ +static inline void +draw_ball (void) +{ + int i; + BYTE *blptr; + BYTE e; + + if (ml[2].vdel_flag) + e = ml[2].vdel; + else + e = ml[2].enabled; + + if (e && ml[2].x >= 0) + { + blptr = colvect + (ml[2].x); + switch (tiaWrite[CTRLPF] >> 4) + { + case 3: + /* Eight clocks */ + for (i = 0; i < 8; i++) + *(blptr++) |= BL_MASK; + break; + case 2: + /* Four clocks */ + for (i = 0; i < 4; i++) + *(blptr++) |= BL_MASK; + break; + case 1: + /* Two clocks */ + for (i = 0; i < 2; i++) + *(blptr++) |= BL_MASK; + break; + case 0: + /* One clock */ + *(blptr++) |= BL_MASK; + break; + } + } +} + + +/* Draw a missile graphic */ +static inline void +do_missile (int num, BYTE * misptr) +{ + int i; + + switch (ml[num].width) + { + case 0: + /* one clock */ + *(misptr++) |= ml[num].mask; + break; + case 1: + /* two clocks */ + for (i = 0; i < 2; i++) + *(misptr++) |= ml[num].mask; + break; + case 2: + /* four clocks */ + for (i = 0; i < 4; i++) + *(misptr++) |= ml[num].mask; + break; + case 3: + /* Eight clocks */ + for (i = 0; i < 8; i++) + *(misptr++) |= ml[num].mask; + break; + } /* switch */ +} + +/* Draw a missile taking into account the player's position. */ +/* line: the vertical position of the raster */ +/* num: 0 for M0, 1 for M1 */ +static inline void +draw_missile (int num) +{ + BYTE *misptr; + + if (ml[num].enabled && ml[num].x >= 0) + { + switch (pl[num].nusize) + { + case 0: + misptr = colvect + (ml[num].x); + do_missile (num, misptr); + break; + case 1: + misptr = colvect + (ml[num].x); + do_missile (num, misptr); + misptr = misptr + 16; + do_missile (num, misptr); + break; + case 2: + misptr = colvect + (ml[num].x); + do_missile (num, misptr); + misptr = misptr + 32; + do_missile (num, misptr); + break; + case 3: + misptr = colvect + (ml[num].x); + do_missile (num, misptr); + misptr = misptr + 16; + do_missile (num, misptr); + misptr = misptr + 16; + do_missile (num, misptr); + break; + case 4: + misptr = colvect + (ml[num].x); + do_missile (num, misptr); + misptr = misptr + 64; + do_missile (num, misptr); + break; + case 5: + misptr = colvect + (ml[num].x); + do_missile (num, misptr); + break; + case 6: + misptr = colvect + (ml[num].x); + do_missile (num, misptr); + misptr = misptr + 32; + do_missile (num, misptr); + misptr = misptr + 32; + do_missile (num, misptr); + break; + case 7: + misptr = colvect + (ml[num].x); + do_missile (num, misptr); + break; + + } + + } /* If */ +} + + +/* Construct one tv raster line colvect */ +/* line: the vertical position of the raster */ +void +tv_rasterise (int line) +{ + line_ptr = vscreen + line * vwidth * base_opts.magstep * tv_bytes_pp; + /* Draw the playfield first */ + draw_playfield (); + + /* Do the ball */ + draw_ball (); + + /* Do the player 1 graphics */ + draw_missile (1); + pl_draw (1); + + /* Do the player 0 graphics */ + draw_missile (0); + pl_draw (0); +} + +/* Reset the collision vector */ +void +reset_vector (void) +{ + int i; + UINT32 *cpos=(UINT32 *)colvect; + for (i = 0; i < 40; i++) + cpos[i] = 0; +} + + +/* draw the collision vector */ +/* Quick version with no magnification */ +void +draw_vector_q (void) +{ + int i; + int uct = 0; + int colind, colval; + unsigned int pad; + unsigned short *tv_ptr = (short *) line_ptr; + + /* Check for scores */ + if(scores_val ==2) + { + scores_val=1; + colour_lookup=colour_ptrs[norm_val][scores_val]; + } + + /* Use starting changes */ + while (uct < unified_count && unified[uct].x < 0) + use_unified_change (&unified[uct++]); + + for (i = 0; i < 80; i++) + { + if (uct < unified_count && unified[uct].x == i) + use_unified_change (&unified[uct++]); + + if((colval=colvect[i])){ + + /* Collision detection */ + col_state|=col_table[colval]; + + colind=colour_lookup[colval]; + pad=colour_table[colind]; + } else + pad=colour_table[BK_COLOUR]; + + tv_ptr[i] = pad; + } + + /* Check for scores */ + if(scores_val ==1) + { + scores_val=2; + colour_lookup=colour_ptrs[norm_val][scores_val]; + } + for (i = 80; i < 160; i++) + { + if (uct < unified_count && unified[uct].x == i) + use_unified_change (&unified[uct++]); + + if((colval=colvect[i])){ + + /* Collision detection */ + col_state|=col_table[colval]; + + colind=colour_lookup[colval]; + pad=colour_table[colind]; + } else + pad=colour_table[BK_COLOUR]; + + tv_ptr[i] = pad; + } + + while (uct < unified_count) + use_unified_change (&unified[uct++]); + unified_count = 0; +} + +/* draw the collision vector */ +/* Quick version with no magnification */ +void +draw_vector_2 (void) +{ + int i; + int uct = 0; + int colind, colval; + unsigned int pad; + unsigned int *tv_ptr = (int *) line_ptr; + + /* Check for scores */ + if(scores_val ==2) + { + scores_val=1; + colour_lookup=colour_ptrs[norm_val][scores_val]; + } + + /* Use starting changes */ + while (uct < unified_count && unified[uct].x < 0) + use_unified_change (&unified[uct++]); + + for (i = 0; i < 80; i++) + { + if (uct < unified_count && unified[uct].x == i) + use_unified_change (&unified[uct++]); + + if((colval=colvect[i])){ + + /* Collision detection */ + col_state|=col_table[colval]; + + colind=colour_lookup[colval]; + pad=colour_table[colind]; + } else + pad=colour_table[BK_COLOUR]; + + tv_ptr[i] = pad; + } + + /* Check for scores */ + if(scores_val ==1) + { + scores_val=2; + colour_lookup=colour_ptrs[norm_val][scores_val]; + } + for (i = 80; i < 160; i++) + { + if (uct < unified_count && unified[uct].x == i) + use_unified_change (&unified[uct++]); + + if((colval=colvect[i])){ + + /* Collision detection */ + col_state|=col_table[colval]; + + colind=colour_lookup[colval]; + pad=colour_table[colind]; + } else + pad=colour_table[BK_COLOUR]; + + tv_ptr[i] = pad; + } + + while (uct < unified_count) + use_unified_change (&unified[uct++]); + unified_count = 0; +} + + +/* draw the collision vector */ +/* const agrument ensures that constant propagation occurs, meaning + less slow down for the magstep=1 case */ +void +draw_vector(const int magstep) +{ + int i,j; + int uct = 0; + int colind, colval; + unsigned int pad; + unsigned short *tv_ptr = (short *) line_ptr; + + /* Check for scores */ + if(scores_val ==2) + { + scores_val=1; + colour_lookup=colour_ptrs[norm_val][scores_val]; + } + + /* Use starting changes */ + while (uct < unified_count && unified[uct].x < 0) + use_unified_change (&unified[uct++]); + + for (i = 0; i < 80; i++) + { + if (uct < unified_count && unified[uct].x == i) + use_unified_change (&unified[uct++]); + + if((colval=colvect[i])){ + + /* Collision detection */ + col_state|=col_table[colval]; + + colind=colour_lookup[colval]; + pad=colour_table[colind]; + } else + pad=colour_table[BK_COLOUR]; + + for(j=0; j theight)) + { + update_registers (); + } + else + { + reset_vector(); + tv_rasterise (line); + switch( tv_depth ) + { + case 8: + { + switch (base_opts.magstep) + { + case 1: + draw_vector_q (); + break; + case 2: + draw_vector_2 (); + /* Duplicate line if magnifying */ + memcpy (line_ptr + vwidth, + line_ptr, vwidth); + + break; + case 3: + draw_vector (3); + /* Duplicate line if magnifying */ + for (j = 0; j < 2; j++) + { + memcpy (line_ptr + vwidth, + line_ptr, vwidth); + } + break; + } + break; + } + case 16: + { + /* Magstep is not doubled */ + + draw_vector_true_color16(base_opts.magstep); + break; + } + case 32: + { + /* Magstep is doubled */ + draw_vector_true_color24(base_opts.magstep*2); + break; + } + } +#ifdef XDEBUGGER + if (debugf_raster) + { + *(line_ptr + 320) = 0; + *(line_ptr + 321) = colour_table[P0M0_COLOUR]; + tv_display (); + debugf_halt = 1; + } +#endif + } +} + +void +init_raster (void) +{ + int i,val; + + init_collisions(); + + /* Normal Priority */ + for (i=0; i<64; i++) + { + if (i & (PL0_MASK | ML0_MASK)) + val = P0M0_COLOUR; + else if (i & (PL1_MASK | ML1_MASK)) + val = P1M1_COLOUR; + else if (i & (BL_MASK | PF_MASK)) + val = PFBL_COLOUR; + else + val = BK_COLOUR; + colour_normal[i]=val; + } + + /* Alternate Priority */ + for (i=0; i<64; i++) + { + if (i & (BL_MASK | PF_MASK)) + val = PFBL_COLOUR; + else if (i & (PL0_MASK | ML0_MASK)) + val = P0M0_COLOUR; + else if (i & (PL1_MASK | ML1_MASK)) + val = P1M1_COLOUR; + else + val = BK_COLOUR; + colour_alternate[i]=val; + } + + /* Normal Scores Left */ + for (i=0; i<64; i++) + { + if (i & (PL0_MASK | ML0_MASK)) + val = P0M0_COLOUR; + else if (i & (PL1_MASK | ML1_MASK)) + val = P1M1_COLOUR; + else if (i & (BL_MASK | PF_MASK)) + /* Use P1 colour */ + val = P0M0_COLOUR; + else + val = BK_COLOUR; + colour_normscoresl[i]=val; + } + + /* Normal Scores Right */ + for (i=0; i<64; i++) + { + if (i & (PL0_MASK | ML0_MASK)) + val = P0M0_COLOUR; + else if (i & (PL1_MASK | ML1_MASK)) + val = P1M1_COLOUR; + else if (i & (BL_MASK | PF_MASK)) + /* Use P1 colour */ + val = P1M1_COLOUR; + else + val = BK_COLOUR; + colour_normscoresr[i]=val; + } + + /* Alternate Scores Left*/ + for (i=0; i<64; i++) + { + if (i & (BL_MASK | PF_MASK)) + val = P0M0_COLOUR; + else if (i & (PL0_MASK | ML0_MASK)) + val = P0M0_COLOUR; + else if (i & (PL1_MASK | ML1_MASK)) + val = P1M1_COLOUR; + else + val = BK_COLOUR; + colour_altscoresl[i]=val; + } + + /* Alternate Scores Right*/ + for (i=0; i<64; i++) + { + if (i & (BL_MASK | PF_MASK)) + val = P1M1_COLOUR; + else if (i & (PL0_MASK | ML0_MASK)) + val = P0M0_COLOUR; + else if (i & (PL1_MASK | ML1_MASK)) + val = P1M1_COLOUR; + else + val = BK_COLOUR; + colour_altscoresr[i]=val; + } + + colour_ptrs[0][0]=colour_normal; + colour_ptrs[1][0]=colour_alternate; + colour_ptrs[0][1]=colour_normscoresl; + colour_ptrs[1][1]=colour_altscoresl; + colour_ptrs[0][2]=colour_normscoresr; + colour_ptrs[1][2]=colour_altscoresr; + norm_val=0; scores_val=0; + + colour_lookup=colour_normal; +} diff -ruNp ./rockbox/apps/plugins/2600box/raster.h ./rockbox-working/apps/plugins/2600box/raster.h --- ./rockbox/apps/plugins/2600box/raster.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/raster.h 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,44 @@ +/***************************************************************************** + + This file is part of Virtual 2600, the Atari 2600 Emulator + ========================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: raster.h,v 1.5 1997/04/06 02:15:13 ahornby Exp $ +******************************************************************************/ + +/* + The raster prototypes. + */ + +#ifndef RASTER_H +#define RASTER_H +/* Color lookup tables. Used to speed up rendering */ +/* The current colour lookup table */ +extern int *colour_lookup; + +/* Colour table */ +#define P0M0_COLOUR 0 +#define P1M1_COLOUR 1 +#define PFBL_COLOUR 2 +#define BK_COLOUR 3 +extern unsigned int colour_table[4]; + +/* normal/alternate, not scores/scores*/ +extern int norm_val, scores_val; +extern int *colour_ptrs[2][3]; + +void tv_raster(int line); + +extern void +init_raster(void); +#endif + + + diff -ruNp ./rockbox/apps/plugins/2600box/rb2600.c ./rockbox-working/apps/plugins/2600box/rb2600.c --- ./rockbox/apps/plugins/2600box/rb2600.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/rb2600.c 2013-11-14 09:30:22.187490266 -0500 @@ -0,0 +1,82 @@ +#include "rbconfig.h" + +#ifdef USE_IRAM +extern char iramcopy[]; +extern char iramstart[]; +extern char iramend[]; +extern char iedata[]; +extern char iend[]; +#endif + +/**v2600 headers***********/ +#include "types.h" /**/ +#include "display.h" /**/ +#include "keyboard.h" /**/ +#include "realjoy.h" /**/ +#include "files.h" /**/ +#include "config.h" /**/ +#include "vmachine.h" /**/ +#include "profile.h" /**/ +#include "options.h" /**/ +/*************************/ +/* The mainloop from cpu.c */ +extern void mainloop (void); + +enum plugin_status plugin_start(const void* parameter) +{ + +#if CODEC == SWCODEC && !defined SIMULATOR + rb->pcm_play_stop(); +#endif + rb->splash(HZ, "Welcome to Atari 2600 :)"); + +#ifdef USE_IRAM + /* We need to stop audio playback in order to use IRAM */ + rb->audio_stop(); + + memcpy(iramstart, iramcopy, iramend-iramstart); + memset(iedata, 0, iend - iedata); +#endif + + +#if defined(HAVE_ADJUSTABLE_CPU_FREQ) + rb->cpu_boost(true); +#endif + +/* main loop here */ + if ( parameter != NULL ) + parse_options (parameter); + else + parse_options ( "" ); + /* Initialise the 2600 hardware */ + init_hardware (); + + /* Turn the virtual TV on. */ + tv_on (NULL, NULL); + + /* Turn on sound */ + sound_init (); + + init_realjoy (); + + /* load cartridge image */ + if (loadCart ()) + { + rb->splash (HZ, "Error loading cartridge image.\n"); + } + + /* Cannot be done until file is loaded */ + init_banking(); + mainloop(); + + +#if defined(HAVE_ADJUSTABLE_CPU_FREQ) + rb->cpu_boost(false); +#endif + +#if CODEC == SWCODEC && !defined SIMULATOR + rb->pcm_play_stop(); +#endif + +return PLUGIN_OK; +} diff -ruNp ./rockbox/apps/plugins/2600box/rbconfig.h ./rockbox-working/apps/plugins/2600box/rbconfig.h --- ./rockbox/apps/plugins/2600box/rbconfig.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/rbconfig.h 2013-11-14 16:11:33.410706097 -0500 @@ -0,0 +1,292 @@ +#ifndef RBCONFIG_H +#define RBCONFIG_H + +#include +extern const struct plugin_api * rb; + +/* KEYMAPS */ +#ifdef HAVE_TOUCHSCREEN +#define JOY_LEFT BUTTON_MIDLEFT +#define JOY_RIGHT BUTTON_MIDRIGHT +#else +#define JOY_LEFT BUTTON_LEFT +#define JOY_RIGHT BUTTON_RIGHT +#endif + +#if CONFIG_KEYPAD == IRIVER_H100_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define CONSOLE_OPTION BUTTON_OFF +#define JOY_TRIGGER BUTTON_SELECT +#define PLUGIN_QUIT BUTTON_MODE +#define CONSOLE_RESET BUTTON_NONE + +#elif CONFIG_KEYPAD == IRIVER_H300_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define CONSOLE_OPTION BUTTON_MODE +#define JOY_TRIGGER BUTTON_SELECT +#define PLUGIN_QUIT BUTTON_OFF +#define CONSOLE_RESET BUTTON_NONE + +#elif CONFIG_KEYPAD == RECORDER_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define CONSOLE_RESET BUTTON_F1 +#define CONSOLE_OPTION BUTTON_F2 +#define JOY_TRIGGER BUTTON_PLAY +#define PLUGIN_QUIT BUTTON_OFF + +#elif CONFIG_KEYPAD == IPOD_4G_PAD +#define JOY_UP BUTTON_MENU +#define JOY_DOWN BUTTON_PLAY +#define CONSOLE_OPTION BUTTON_NONE +#define JOY_TRIGGER BUTTON_SELECT +#define CONSOLE_RESET BUTTON_NONE +#define PLUGIN_QUIT (BUTTON_SELECT | BUTTON_REPEAT) + +#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define CONSOLE_OPTION BUTTON_EQ +#define CONSOLE_RESET BUTTON_MODE +#define JOY_TRIGGER BUTTON_SELECT +#define PLUGIN_QUIT BUTTON_EQ + +#elif CONFIG_KEYPAD == GIGABEAT_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define CONSOLE_RESET BUTTON_VOL_UP +#define CONSOLE_OPTION BUTTON_VOL_DOWN +#define JOY_TRIGGER BUTTON_SELECT +#define PLUGIN_QUIT BUTTON_MENU + +#elif CONFIG_KEYPAD == SANSA_E200_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define JOY_TRIGGER BUTTON_SELECT +#define CONSOLE_OPTION BUTTON_REC +#define PLUGIN_QUIT BUTTON_POWER +#define CONSOLE_RESET BUTTON_NONE + +#elif CONFIG_KEYPAD == SANSA_FUZE_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define JOY_TRIGGER BUTTON_SELECT +#define CONSOLE_OPTION BUTTON_HOME +#define PLUGIN_QUIT BUTTON_POWER +#define CONSOLE_RESET BUTTON_NONE + +#elif CONFIG_KEYPAD == SANSA_C200_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define JOY_TRIGGER BUTTON_SELECT +#define CONSOLE_OPTION BUTTON_REC +#define PLUGIN_QUIT BUTTON_POWER +#define CONSOLE_RESET BUTTON_VOL_DOWN + +#elif CONFIG_KEYPAD == SANSA_CLIP_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define JOY_TRIGGER BUTTON_SELECT +#define CONSOLE_OPTION BUTTON_HOME +#define CONSOLE_RESET BUTTON_VOL_DOWN +#define PLUGIN_QUIT BUTTON_POWER + +/* MARK */ + +#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define CONSOLE_OPTION BUTTON_REC +#define JOY_TRIGGER BUTTON_SELECT +#define CONSOLE_RESET BUTTON_PLAY +#define PLUGIN_QUIT BUTTON_POWER + +#elif CONFIG_KEYPAD == IRIVER_H10_PAD +#define JOY_UP BUTTON_SCROLL_UP +#define JOY_DOWN BUTTON_SCROLL_DOWN +#define JOY_TRIGGER BUTTON_PLAY +#define CONSOLE_OPTION BUTTON_FF +#define CONSOLE_RESET BUTTON_REW +#define PLUGIN_QUIT BUTTON_POWER + +#elif CONFIG_KEYPAD == MROBE500_PAD +#define PLUGIN_QUIT BUTTON_POWER +#define CONSOLE_RESET BUTTON_NONE + +#elif CONFIG_KEYPAD == COWON_D2_PAD +#define JOY_TRIGGER BUTTON_PLUS +#define CONSOLE_OPTION BUTTON_MINUS +#define PLUGIN_QUIT BUTTON_MENU +#define CONSOLE_RESET BUTTON_NONE + +#elif CONFIG_KEYPAD == GIGABEAT_S_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define CONSOLE_OPTION BUTTON_MENU +#define CONSOLE_RESET BUTTON_BACK +#define JOY_TRIGGER BUTTON_SELECT +#define PLUGIN_QUIT BUTTON_POWER + +#elif CONFIG_KEYPAD == CREATIVEZVM_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define CONSOLE_RESET BUTTON_CUSTOM +#define CONSOLE_OPTION BUTTON_PLAY +#define JOY_TRIGGER BUTTON_SELECT +#define PLUGIN_QUIT BUTTON_MENU + +#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define CONSOLE_RESET BUTTON_VOL_UP +#define CONSOLE_OPTION BUTTON_VOL_DOWN +#define JOY_TRIGGER BUTTON_SELECT +#define PLUGIN_QUIT BUTTON_MENU + +#elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define CONSOLE_RESET BUTTON_VOL_UP +#define CONSOLE_OPTION BUTTON_VOL_DOWN +#define JOY_TRIGGER BUTTON_PLAY +#define PLUGIN_QUIT BUTTON_MENU + +#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define JOY_TRIGGER BUTTON_VOL_UP +#define CONSOLE_OPTION BUTTON_VOL_DOWN +#define PLUGIN_QUIT BUTTON_MENU +#define CONSOLE_RESET BUTTON_NONE + +#elif CONFIG_KEYPAD == ONDAVX747_PAD +#define JOY_TRIGGER BUTTON_VOL_UP +#define CONSOLE_OPTION BUTTON_VOL_DOWN +#define PLUGIN_QUIT BUTTON_MENU +#define CONSOLE_RESET BUTTON_NONE + +#elif CONFIG_KEYPAD == ONDAVX777_PAD +#define PLUGIN_QUIT BUTTON_POWER +#define CONSOLE_RESET BUTTON_NONE + +#elif CONFIG_KEYPAD == IRIVER_H10_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define JOY_TRIGGER BUTTON_PLAY +#define CONSOLE_OPTION BUTTON_FFWD +#define PLUGIN_QUIT BUTTON_REW + +#elif CONFIG_KEYPAD == SAMSUNG_YH_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define JOY_TRIGGER BUTTON_PLAY +#define CONSOLE_OPTION BUTTON_REW +#define CONSOLE_RESET BUTTON_FFWD +#define PLUGIN_QUIT BUTTON_REC + +#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD +#define JOY_UP BUTTON_OK +#define JOY_DOWN BUTTON_CANCEL +#define JOY_LEFT BUTTON_PREV +#define JOY_RIGHT BUTTON_NEXT +#define JOY_TRIGGER BUTTON_POWER +#define CONSOLE_OPTION BUTTON_REC +#define CONSOLE_RESET BUTTON_PLAY +#define PLUGIN_QUIT BUTTON_MENU + +#elif CONFIG_KEYPAD == MPIO_HD300_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define JOY_LEFT BUTTON_REW +#define JOY_RIGHT BUTTON_FF +#define JOY_TRIGGER BUTTON_PLAY +#define CONSOLE_OPTION BUTTON_REC +#define CONSOLE_RESET BUTTON_ENTER +#define PLUGIN_QUIT BUTTON_MENU + +#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define CONSOLE_RESET BUTTON_VOL_UP +#define CONSOLE_OPTION BUTTON_VOL_DOWN +#define JOY_TRIGGER BUTTON_SELECT +#define PLUGIN_QUIT BUTTON_BACK + +#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define CONSOLE_RESET BUTTON_VOL_UP +#define CONSOLE_OPTION BUTTON_VOL_DOWN +#define PLUGIN_QUIT BUTTON_NEXT +#define JOY_TRIGGER BUTTON_SELECT + +#elif CONFIG_KEYPAD == SAMSUNG_YPR0_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define JOY_TRIGGER BUTTON_SELECT +#define CONSOLE_OPTION BUTTON_BACK +#define CONSOLE_RESET BUTTON_USER +#define PLUGIN_QUIT BUTTON_MENU + +#elif CONFIG_KEYPAD == HM801_PAD +#define JOY_UP BUTTON_UP +#define JOY_DOWN BUTTON_DOWN +#define JOY_TRIGGER BUTTON_PREV +#define CONSOLE_OPTION BUTTON_NEXT +#define CONSOLE_RESET BUTTON_PLAY +#define JOY_TRIGGER BUTTON_SELECT +#define PLUGIN_QUIT BUTTON_POWER + +#else +#error No Keymap Defined! +#endif + +#ifdef HAVE_TOUCHSCREEN +#define JOY_UP BUTTON_TOPMIDDLE +#define JOY_DOWN BUTTON_BOTTOMMIDDLE +#define JOY_TRIGGER BUTTON_TOPRIGHT +#define JOY_TRIGGER BUTTON_CENTER +#if CONFIG_KEYPAD == MROBE500_PAD +#define JOY_TRIGGER BUTTON_BOTTOMLEFT +#define CONSOLE_OPTION BUTTON_BOTTOMRIGHT +#elif CONFIG_KEYPAD != COWON_D2_PAD +#define JOY_TRIGGER BUTTON_BOTTOMLEFT +#define CONSOLE_OPTION BUTTON_BOTTOMRIGHT +#define PLUGIN_QUIT BUTTON_TOPLEFT +#endif +#define CONSOLE_RESET BUTTON_NONE +#endif + + +/* was too lazy to change in all files :( */ +#define memset rb->memset +#define memcpy rb->memcpy +#define strrchr rb->strrchr +#define strchr rb->strchr +#define strcpy rb->strcpy +#define strcmp rb->strcmp +#define strcat rb->strcat +#define printf (void) + +#define SETTINGS_MIN_VERSION 1 +#define SETTINGS_VERSION 1 + +/* Define if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define if your processor stores words with the most significant + byte first (like Motorola and SPARC, unlike Intel and VAX). */ +/* #undef WORDS_BIGENDIAN */ + +/* Debugging Level */ +#define Verbose 0 + +/* Xdebugger */ +#undef XDEBUGGER + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H + +#endif diff -ruNp ./rockbox/apps/plugins/2600box/rb_keyb.c ./rockbox-working/apps/plugins/2600box/rb_keyb.c --- ./rockbox/apps/plugins/2600box/rb_keyb.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/rb_keyb.c 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,179 @@ +/***************************************************************************** + + This file is part of Virtual 2600, the Atari 2600 Emulator + ========================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: dos_keyb.c,v 1.1 1996/08/28 11:26:57 ahornby Exp $ +******************************************************************************/ + +/* The keyboard interface. */ +#include + +#include "rbconfig.h" +#include "options.h" +#include "types.h" +#include "address.h" +#include "vmachine.h" +#include "macro.h" +#include "extern.h" +#include "memory.h" +#include "display.h" +#include "kmap.h" + +enum control {STICK, PADDLE, KEYPAD}; + +extern int keymap[103]; + +/* Update the current keyboard state. */ +void +keybdrv_update (void) +{ +} + +/* Is this key presssed? */ +int +keybdrv_pressed(int kval) +{ +#if 0 + return (key[keymap[kval]]); +#endif + return 0; +} + +/* Defines the keyboard mappings */ +void +keybdrv_setmap(void) +{ +#if 0 + keymap[ kmapSYSREQ ]=0; + keymap[ kmapCAPSLOCK ]=KEY_CAPSLOCK; + keymap[ kmapNUMLOCK ]=KEY_NUMLOCK; + keymap[ kmapSCROLLLOCK ]=0; + keymap[ kmapLEFTCTRL ]=KEY_CONTROL; + keymap[ kmapLEFTALT ]=KEY_ALT; + keymap[ kmapLEFTSHIFT ]=KEY_LSHIFT; + keymap[ kmapRIGHTCTRL ]=KEY_CONTROL; + keymap[ kmapRIGHTALT ]=KEY_ALT; + keymap[ kmapRIGHTSHIFT ]=KEY_RSHIFT; + keymap[ kmapESC ]=KEY_ESC; + keymap[ kmapBACKSPACE ]=KEY_BACKSPACE; + keymap[ kmapENTER ]=KEY_ENTER; + keymap[ kmapSPACE ]=KEY_SPACE; + keymap[ kmapTAB ]=KEY_TAB; + keymap[ kmapF1 ]=KEY_F1; + keymap[ kmapF2 ]=KEY_F2; + keymap[ kmapF3 ]=KEY_F3; + keymap[ kmapF4 ]=KEY_F4; + keymap[ kmapF5 ]=KEY_F5; + keymap[ kmapF6 ]=KEY_F6; + keymap[ kmapF7 ]=KEY_F7; + keymap[ kmapF8 ]=KEY_F8; + keymap[ kmapF9 ]=KEY_F9; + keymap[ kmapF10 ]=KEY_F10; + keymap[ kmapF11 ]=KEY_F11; + keymap[ kmapF12 ]=KEY_F12; + keymap[ kmapA ]=KEY_A; + keymap[ kmapB ]=KEY_B; + keymap[ kmapC ]=KEY_C; + keymap[ kmapD ]=KEY_D; + keymap[ kmapE ]=KEY_E; + keymap[ kmapF ]=KEY_F; + keymap[ kmapG ]=KEY_G; + keymap[ kmapH ]=KEY_H; + keymap[ kmapI ]=KEY_I; + keymap[ kmapJ ]=KEY_J; + keymap[ kmapK ]=KEY_K; + keymap[ kmapL ]=KEY_L; + keymap[ kmapM ]=KEY_M; + keymap[ kmapN ]=KEY_N; + keymap[ kmapO ]=KEY_O; + keymap[ kmapP ]=KEY_P; + keymap[ kmapQ ]=KEY_Q; + keymap[ kmapR ]=KEY_R; + keymap[ kmapS ]=KEY_S; + keymap[ kmapT ]=KEY_T; + keymap[ kmapU ]=KEY_U; + keymap[ kmapV ]=KEY_V; + keymap[ kmapW ]=KEY_W ; + keymap[ kmapX ]=KEY_X ; + keymap[ kmapY ]=KEY_Y; + keymap[ kmapZ ]=KEY_Z ; + keymap[ kmap1 ]=KEY_1; + keymap[ kmap2 ]=KEY_2; + keymap[ kmap3 ]=KEY_3; + keymap[ kmap4 ]=KEY_4; + keymap[ kmap5 ]=KEY_5; + keymap[ kmap6 ]=KEY_6; + keymap[ kmap7 ]=KEY_7; + keymap[ kmap8 ]=KEY_8; + keymap[ kmap9 ]=KEY_9; + keymap[ kmap0 ]=KEY_0; + keymap[ kmapMINUS ]=KEY_MINUS; + keymap[ kmapEQUAL ]=0; + keymap[ kmapLBRACKET ]=0x1A; + keymap[ kmapRBRACKET ]=0x1B; + keymap[ kmapSEMICOLON ]=0x27; + keymap[ kmapTICK ]=0x28; + keymap[ kmapAPOSTROPHE ]=0x29; + keymap[ kmapBACKSLASH ]=0x2B; + keymap[ kmapCOMMA ]=0x33; + keymap[ kmapPERIOD ]=0x34; + keymap[ kmapSLASH ]=0x35; + keymap[ kmapINS ]=0xD2; + keymap[ kmapDEL ]=0xD3; + keymap[ kmapHOME ]=0xC7; + keymap[ kmapEND ]=0xCF; + keymap[ kmapPGUP ]=0xC9; + keymap[ kmapPGDN ]=0xD1; + keymap[ kmapLARROW ]=KEY_LEFT; + keymap[ kmapRARROW ]=KEY_RIGHT; + keymap[ kmapUARROW ]=KEY_UP; + keymap[ kmapDARROW ]=KEY_DOWN; + keymap[ kmapKEYPAD0 ]=KEY_0; + keymap[ kmapKEYPAD1 ]=KEY_1; + keymap[ kmapKEYPAD2 ]=KEY_2; + keymap[ kmapKEYPAD3 ]=KEY_3; + keymap[ kmapKEYPAD4 ]=KEY_4; + keymap[ kmapKEYPAD5 ]=KEY_5; + keymap[ kmapKEYPAD6 ]=KEY_6; + keymap[ kmapKEYPAD7 ]=KEY_7; + keymap[ kmapKEYPAD8 ]=KEY_8; + keymap[ kmapKEYPAD9 ]=KEY_9; + keymap[ kmapKEYPADDEL ]=0; + keymap[ kmapKEYPADSTAR ]=0; + keymap[ kmapKEYPADMINUS ]=KEY_MINUS; + keymap[ kmapKEYPADPLUS ]=0; + keymap[ kmapKEYPADENTER ]=KEY_ENTER; + keymap[ kmapCTRLPRTSC ]=0; + keymap[ kmapSHIFTPRTSC ]=0; + keymap[ kmapKEYPADSLASH ]=0; +#endif +} + +/* Zeros the keyboard array, and installs event handlers. */ +int +keybdrv_init (void) +{ + return 0; +} + +/* Close the keyboard and tidy up */ +void +keybdrv_close (void) +{ + +} + + + + + + + diff -ruNp ./rockbox/apps/plugins/2600box/realjoy.h ./rockbox-working/apps/plugins/2600box/realjoy.h --- ./rockbox/apps/plugins/2600box/realjoy.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/realjoy.h 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,29 @@ +#ifndef REALJOY_H +#define REALJOY_H + +#define LJOYMASK 0x01 +#define RJOYMASK 0x02 +#define UJOYMASK 0x04 +#define DJOYMASK 0x08 +#define B1JOYMASK 0x10 +#define B2JOYMASK 0x20 + +/* This should be called from xxx_keyb.c */ +int +get_realjoy(int stick); + +/* This should be called once per frame */ +void +update_realjoy(void); + +/* These can be called from anywhere. */ +void +calibrate_realjoy(int stick); + +void +init_realjoy(void); + +void +close_realjoy(void); + +#endif diff -ruNp ./rockbox/apps/plugins/2600box/sound.h ./rockbox-working/apps/plugins/2600box/sound.h --- ./rockbox/apps/plugins/2600box/sound.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/sound.h 2013-11-14 07:47:53.831690560 -0500 @@ -0,0 +1,24 @@ +#ifndef X2600_SOUND_H +#define X2600_SOUND_H + +/* $Id: sound.h,v 1.4 1996/09/04 22:37:48 ahornby Exp $ */ +#include "types.h" +void +sound_init(void); + +void +sound_close(void); + +void +sound_freq(int channel, BYTE freq); + +void +sound_volume(int channel, BYTE vol); + +void +sound_waveform(int channel, BYTE value); + +void +sound_update(void); + +#endif diff -ruNp ./rockbox/apps/plugins/2600box/SOURCES ./rockbox-working/apps/plugins/2600box/SOURCES --- ./rockbox/apps/plugins/2600box/SOURCES 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/SOURCES 2013-11-14 12:36:35.951126257 -0500 @@ -0,0 +1,24 @@ +collision.c +cpu.c +dbg_mess.c +exmacro.c +files.c +keyboard.c +limiter.c +memory.c +no_joy.c +no_mouse.c +no_sound.c +no_ui.c +options.c +raster.c +table.c +tiasound.c +vmachine.c +rb_keyb.c +rb2600.c +#if LCD_DEPTH == 16 +16bpp_disp.c +#elif LCD_DEPTH < 4 && LCD_PIXELFORMAT == HORIZONTAL_PACKING +4bpp_hp_disp.c +#endif diff -ruNp ./rockbox/apps/plugins/2600box/table.c ./rockbox-working/apps/plugins/2600box/table.c --- ./rockbox/apps/plugins/2600box/table.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/table.c 2013-11-14 07:47:53.835690560 -0500 @@ -0,0 +1,643 @@ + + + + + +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for Details. + + $Id: table.c,v 1.4 1996/08/26 15:04:20 ahornby Exp $ +******************************************************************************/ + +/* + * $Id: table.c,v 1.4 1996/08/26 15:04:20 ahornby Exp $ + * + * This was part of the x64 Commodore 64 emulator. + * See README for copyright notice + * + * This file contains lookup-table which is used to translate + * MOS6502 machine instructions. Machine code is used as index + * to array called lookup. Pointer to function is then fetched + * from array and function is called. + * Timing of the undocumented opcodes is based on information + * in an article in C=Lehti by Kai Lindfors and Topi Maurola. + * + * + * Written by + * Vesa-Matti Puro (vmp@lut.fi) + * Jarkko Sonninen (sonninen@lut.fi) + * Jouko Valta (jopi@stekt.oulu.fi) + * + */ + +#include "cpu.h" +#include "mnemonic.h" + + +/* + * The "mnemonic.h" file contains #defines for BRK, ORA, NOOP... which + * are character strings, i.e. #define BRK "BRK" + * #define ORA "ORA" . . . Used mainly to reduce typing... + * + * There are #defines for addressing modes i.e. IMPLIED, INDIRECT_X, + * ZERO_PAGE in "cpu.h"... These can be used to make a diassembler. + */ + + +int clength[] = +{1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 2, 2, 2, 0}; + +struct lookup_tag lookup[] = +{ + +/**** Positive ****/ + + /* 00 */ + {BRK, IMPLIED, M_NONE, M_PC, 7, 0}, /* Pseudo Absolute */ + /* 01 */ + {ORA, INDIRECT_X, M_INDX, M_AC, 6, 0}, /* (Indirect,X) */ + /* 02 */ + {JAM, IMPLIED, M_NONE, M_NONE, 0, 0}, /* TILT */ + /* 03 */ + {SLO, INDIRECT_X, M_INDX, M_INDX, 8, 0}, + + /* 04 */ + {NOOP, ZERO_PAGE, M_NONE, M_NONE, 3, 0}, + /* 05 */ + {ORA, ZERO_PAGE, M_ZERO, M_AC, 3, 0}, /* Zeropage */ + /* 06 */ + {ASL, ZERO_PAGE, M_ZERO, M_ZERO, 5, 0}, /* Zeropage */ + /* 07 */ + {SLO, ZERO_PAGE, M_ZERO, M_ZERO, 5, 0}, + + /* 08 */ + {PHP, IMPLIED, M_SR, M_NONE, 3, 0}, + /* 09 */ + {ORA, IMMEDIATE, M_IMM, M_AC, 2, 0}, /* Immediate */ + /* 0a */ + {ASL, ACCUMULATOR, M_AC, M_AC, 2, 0}, /* Accumulator */ + /* 0b */ + {ANC, IMMEDIATE, M_ACIM, M_ACNC, 2, 0}, + + /* 0c */ + {NOOP, ABSOLUTE, M_NONE, M_NONE, 4, 0}, + /* 0d */ + {ORA, ABSOLUTE, M_ABS, M_AC, 4, 0}, /* Absolute */ + /* 0e */ + {ASL, ABSOLUTE, M_ABS, M_ABS, 6, 0}, /* Absolute */ + /* 0f */ + {SLO, ABSOLUTE, M_ABS, M_ABS, 6, 0}, + + /* 10 */ + {BPL, RELATIVE, M_REL, M_NONE, 2, 0}, + /* 11 */ + {ORA, INDIRECT_Y, M_INDY, M_AC, 5, 1}, /* (Indirect),Y */ + /* 12 */ + {JAM, IMPLIED, M_NONE, M_NONE, 0, 0}, /* TILT */ + /* 13 */ + {SLO, INDIRECT_Y, M_INDY, M_INDY, 8, 0}, + + /* 14 */ + {NOOP, ZERO_PAGE_X, M_NONE, M_NONE, 4, 0}, + /* 15 */ + {ORA, ZERO_PAGE_X, M_ZERX, M_AC, 4, 0}, /* Zeropage,X */ + /* 16 */ + {ASL, ZERO_PAGE_X, M_ZERX, M_ZERX, 6, 0}, /* Zeropage,X */ + /* 17 */ + {SLO, ZERO_PAGE_X, M_ZERX, M_ZERX, 6, 0}, + + /* 18 */ + {CLC, IMPLIED, M_NONE, M_FC, 2, 0}, + /* 19 */ + {ORA, ABSOLUTE_Y, M_ABSY, M_AC, 4, 1}, /* Absolute,Y */ + /* 1a */ + {NOOP, IMPLIED, M_NONE, M_NONE, 2, 0}, + /* 1b */ + {SLO, ABSOLUTE_Y, M_ABSY, M_ABSY, 7, 0}, + + /* 1c */ + {NOOP, ABSOLUTE_X, M_NONE, M_NONE, 4, 1}, + /* 1d */ + {ORA, ABSOLUTE_X, M_ABSX, M_AC, 4, 1}, /* Absolute,X */ + /* 1e */ + {ASL, ABSOLUTE_X, M_ABSX, M_ABSX, 7, 0}, /* Absolute,X */ + /* 1f */ + {SLO, ABSOLUTE_X, M_ABSX, M_ABSX, 7, 0}, + + /* 20 */ + {JSR, ABSOLUTE, M_ADDR, M_PC, 6, 0}, + /* 21 */ + {AND, INDIRECT_X, M_INDX, M_AC, 6, 0}, /* (Indirect ,X) */ + /* 22 */ + {JAM, IMPLIED, M_NONE, M_NONE, 0, 0}, /* TILT */ + /* 23 */ + {RLA, INDIRECT_X, M_INDX, M_INDX, 8, 0}, + + /* 24 */ + {BIT, ZERO_PAGE, M_ZERO, M_NONE, 3, 0}, /* Zeropage */ + /* 25 */ + {AND, ZERO_PAGE, M_ZERO, M_AC, 3, 0}, /* Zeropage */ + /* 26 */ + {ROL, ZERO_PAGE, M_ZERO, M_ZERO, 5, 0}, /* Zeropage */ + /* 27 */ + {RLA, ZERO_PAGE, M_ZERO, M_ZERO, 5, 0}, + + /* 28 */ + {PLP, IMPLIED, M_NONE, M_SR, 4, 0}, + /* 29 */ + {AND, IMMEDIATE, M_IMM, M_AC, 2, 0}, /* Immediate */ + /* 2a */ + {ROL, ACCUMULATOR, M_AC, M_AC, 2, 0}, /* Accumulator */ + /* 2b */ + {ANC, IMMEDIATE, M_ACIM, M_ACNC, 2, 0}, + + /* 2c */ + {BIT, ABSOLUTE, M_ABS, M_NONE, 4, 0}, /* Absolute */ + /* 2d */ + {AND, ABSOLUTE, M_ABS, M_AC, 4, 0}, /* Absolute */ + /* 2e */ + {ROL, ABSOLUTE, M_ABS, M_ABS, 6, 0}, /* Absolute */ + /* 2f */ + {RLA, ABSOLUTE, M_ABS, M_ABS, 6, 0}, + + /* 30 */ + {BMI, RELATIVE, M_REL, M_NONE, 2, 0}, + /* 31 */ + {AND, INDIRECT_Y, M_INDY, M_AC, 5, 1}, /* (Indirect),Y */ + /* 32 */ + {JAM, IMPLIED, M_NONE, M_NONE, 0, 0}, /* TILT */ + /* 33 */ + {RLA, INDIRECT_Y, M_INDY, M_INDY, 8, 0}, + + /* 34 */ + {NOOP, ZERO_PAGE_X, M_NONE, M_NONE, 4, 0}, + /* 35 */ + {AND, ZERO_PAGE_X, M_ZERX, M_AC, 4, 0}, /* Zeropage,X */ + /* 36 */ + {ROL, ZERO_PAGE_X, M_ZERX, M_ZERX, 6, 0}, /* Zeropage,X */ + /* 37 */ + {RLA, ZERO_PAGE_X, M_ZERX, M_ZERX, 6, 0}, + + /* 38 */ + {SEC, IMPLIED, M_NONE, M_FC, 2, 0}, + /* 39 */ + {AND, ABSOLUTE_Y, M_ABSY, M_AC, 4, 1}, /* Absolute,Y */ + /* 3a */ + {NOOP, IMPLIED, M_NONE, M_NONE, 2, 0}, + /* 3b */ + {RLA, ABSOLUTE_Y, M_ABSY, M_ABSY, 7, 0}, + + /* 3c */ + {NOOP, ABSOLUTE_X, M_NONE, M_NONE, 4, 1}, + /* 3d */ + {AND, ABSOLUTE_X, M_ABSX, M_AC, 4, 1}, /* Absolute,X */ + /* 3e */ + {ROL, ABSOLUTE_X, M_ABSX, M_ABSX, 7, 0}, /* Absolute,X */ + /* 3f */ + {RLA, ABSOLUTE_X, M_ABSX, M_ABSX, 7, 0}, + + /* 40 */ + {RTI, IMPLIED, M_NONE, M_PC, 6, 0}, + /* 41 */ + {EOR, INDIRECT_X, M_INDX, M_AC, 6, 0}, /* (Indirect,X) */ + /* 42 */ + {JAM, IMPLIED, M_NONE, M_NONE, 0, 0}, /* TILT */ + /* 43 */ + {SRE, INDIRECT_X, M_INDX, M_INDX, 8, 0}, + + /* 44 */ + {NOOP, ZERO_PAGE, M_NONE, M_NONE, 3, 0}, + /* 45 */ + {EOR, ZERO_PAGE, M_ZERO, M_AC, 3, 0}, /* Zeropage */ + /* 46 */ + {LSR, ZERO_PAGE, M_ZERO, M_ZERO, 5, 0}, /* Zeropage */ + /* 47 */ + {SRE, ZERO_PAGE, M_ZERO, M_ZERO, 5, 0}, + + /* 48 */ + {PHA, IMPLIED, M_AC, M_NONE, 3, 0}, + /* 49 */ + {EOR, IMMEDIATE, M_IMM, M_AC, 2, 0}, /* Immediate */ + /* 4a */ + {LSR, ACCUMULATOR, M_AC, M_AC, 2, 0}, /* Accumulator */ + /* 4b */ + {ASR, IMMEDIATE, M_ACIM, M_AC, 2, 0}, /* (AC & IMM) >>1 */ + + /* 4c */ + {JMP, ABSOLUTE, M_ADDR, M_PC, 3, 0}, /* Absolute */ + /* 4d */ + {EOR, ABSOLUTE, M_ABS, M_AC, 4, 0}, /* Absolute */ + /* 4e */ + {LSR, ABSOLUTE, M_ABS, M_ABS, 6, 0}, /* Absolute */ + /* 4f */ + {SRE, ABSOLUTE, M_ABS, M_ABS, 6, 0}, + + /* 50 */ + {BVC, RELATIVE, M_REL, M_NONE, 2, 0}, + /* 51 */ + {EOR, INDIRECT_Y, M_INDY, M_AC, 5, 1}, /* (Indirect),Y */ + /* 52 */ + {JAM, IMPLIED, M_NONE, M_NONE, 0, 0}, /* TILT */ + /* 53 */ + {SRE, INDIRECT_Y, M_INDY, M_INDY, 8, 0}, + + /* 54 */ + {NOOP, ZERO_PAGE_X, M_NONE, M_NONE, 4, 0}, + /* 55 */ + {EOR, ZERO_PAGE_X, M_ZERX, M_AC, 4, 0}, /* Zeropage,X */ + /* 56 */ + {LSR, ZERO_PAGE_X, M_ZERX, M_ZERX, 6, 0}, /* Zeropage,X */ + /* 57 */ + {SRE, ZERO_PAGE_X, M_ZERX, M_ZERX, 6, 0}, + + /* 58 */ + {CLI, IMPLIED, M_NONE, M_FI, 2, 0}, + /* 59 */ + {EOR, ABSOLUTE_Y, M_ABSY, M_AC, 4, 1}, /* Absolute,Y */ + /* 5a */ + {NOOP, IMPLIED, M_NONE, M_NONE, 2, 0}, + /* 5b */ + {SRE, ABSOLUTE_Y, M_ABSY, M_ABSY, 7, 0}, + + /* 5c */ + {NOOP, ABSOLUTE_X, M_NONE, M_NONE, 4, 1}, + /* 5d */ + {EOR, ABSOLUTE_X, M_ABSX, M_AC, 4, 1}, /* Absolute,X */ + /* 5e */ + {LSR, ABSOLUTE_X, M_ABSX, M_ABSX, 7, 0}, /* Absolute,X */ + /* 5f */ + {SRE, ABSOLUTE_X, M_ABSX, M_ABSX, 7, 0}, + + /* 60 */ + {RTS, IMPLIED, M_NONE, M_PC, 6, 0}, + /* 61 */ + {ADC, INDIRECT_X, M_INDX, M_AC, 6, 0}, /* (Indirect,X) */ + /* 62 */ + {JAM, IMPLIED, M_NONE, M_NONE, 0, 0}, /* TILT */ + /* 63 */ + {RRA, INDIRECT_X, M_INDX, M_INDX, 8, 0}, + + /* 64 */ + {NOOP, ZERO_PAGE, M_NONE, M_NONE, 3, 0}, + /* 65 */ + {ADC, ZERO_PAGE, M_ZERO, M_AC, 3, 0}, /* Zeropage */ + /* 66 */ + {ROR, ZERO_PAGE, M_ZERO, M_ZERO, 5, 0}, /* Zeropage */ + /* 67 */ + {RRA, ZERO_PAGE, M_ZERO, M_ZERO, 5, 0}, + + /* 68 */ + {PLA, IMPLIED, M_NONE, M_AC, 4, 0}, + /* 69 */ + {ADC, IMMEDIATE, M_IMM, M_AC, 2, 0}, /* Immediate */ + /* 6a */ + {ROR, ACCUMULATOR, M_AC, M_AC, 2, 0}, /* Accumulator */ + /* 6b */ + {ARR, IMMEDIATE, M_ACIM, M_AC, 2, 0}, /* ARR isn't typo */ + + /* 6c */ + {JMP, ABS_INDIRECT, M_AIND, M_PC, 5, 0}, /* Indirect */ + /* 6d */ + {ADC, ABSOLUTE, M_ABS, M_AC, 4, 0}, /* Absolute */ + /* 6e */ + {ROR, ABSOLUTE, M_ABS, M_ABS, 6, 0}, /* Absolute */ + /* 6f */ + {RRA, ABSOLUTE, M_ABS, M_ABS, 6, 0}, + + /* 70 */ + {BVS, RELATIVE, M_REL, M_NONE, 2, 0}, + /* 71 */ + {ADC, INDIRECT_Y, M_INDY, M_AC, 5, 1}, /* (Indirect),Y */ + /* 72 */ + {JAM, IMPLIED, M_NONE, M_NONE, 0, 0}, /* TILT relative? */ + /* 73 */ + {RRA, INDIRECT_Y, M_INDY, M_INDY, 8, 0}, + + /* 74 */ + {NOOP, ZERO_PAGE_X, M_NONE, M_NONE, 4, 0}, + /* 75 */ + {ADC, ZERO_PAGE_X, M_ZERX, M_AC, 4, 0}, /* Zeropage,X */ + /* 76 */ + {ROR, ZERO_PAGE_X, M_ZERX, M_ZERX, 6, 0}, /* Zeropage,X */ + /* 77 */ + {RRA, ZERO_PAGE_X, M_ZERX, M_ZERX, 6, 0}, + + /* 78 */ + {SEI, IMPLIED, M_NONE, M_FI, 2, 0}, + /* 79 */ + {ADC, ABSOLUTE_Y, M_ABSY, M_AC, 4, 1}, /* Absolute,Y */ + /* 7a */ + {NOOP, IMPLIED, M_NONE, M_NONE, 2, 0}, + /* 7b */ + {RRA, ABSOLUTE_Y, M_ABSY, M_ABSY, 7, 0}, + + /* 7c */ + {NOOP, ABSOLUTE_X, M_NONE, M_NONE, 4, 1}, + /* 7d */ + {ADC, ABSOLUTE_X, M_ABSX, M_AC, 4, 1}, /* Absolute,X */ + /* 7e */ + {ROR, ABSOLUTE_X, M_ABSX, M_ABSX, 7, 0}, /* Absolute,X */ + /* 7f */ + {RRA, ABSOLUTE_X, M_ABSX, M_ABSX, 7, 0}, + +/**** Negative ****/ + + /* 80 */ + {NOOP, IMMEDIATE, M_NONE, M_NONE, 2, 0}, + /* 81 */ + {STA, INDIRECT_X, M_AC, M_INDX, 6, 0}, /* (Indirect,X) */ + /* 82 */ + {NOOP, IMMEDIATE, M_NONE, M_NONE, 2, 0}, + /* 83 */ + {SAX, INDIRECT_X, M_ANXR, M_INDX, 6, 0}, + + /* 84 */ + {STY, ZERO_PAGE, M_YR, M_ZERO, 3, 0}, /* Zeropage */ + /* 85 */ + {STA, ZERO_PAGE, M_AC, M_ZERO, 3, 0}, /* Zeropage */ + /* 86 */ + {STX, ZERO_PAGE, M_XR, M_ZERO, 3, 0}, /* Zeropage */ + /* 87 */ + {SAX, ZERO_PAGE, M_ANXR, M_ZERO, 3, 0}, + + /* 88 */ + {DEY, IMPLIED, M_YR, M_YR, 2, 0}, + /* 89 */ + {NOOP, IMMEDIATE, M_NONE, M_NONE, 2, 0}, + /* 8a */ + {TXA, IMPLIED, M_XR, M_AC, 2, 0}, +/**** very abnormal: usually AC = AC | #$EE & XR & #$oper ****/ + /* 8b */ + {ANE, IMMEDIATE, M_AXIM, M_AC, 2, 0}, + + /* 8c */ + {STY, ABSOLUTE, M_YR, M_ABS, 4, 0}, /* Absolute */ + /* 8d */ + {STA, ABSOLUTE, M_AC, M_ABS, 4, 0}, /* Absolute */ + /* 8e */ + {STX, ABSOLUTE, M_XR, M_ABS, 4, 0}, /* Absolute */ + /* 8f */ + {SAX, ABSOLUTE, M_ANXR, M_ABS, 4, 0}, + + /* 90 */ + {BCC, RELATIVE, M_REL, M_NONE, 2, 0}, + /* 91 */ + {STA, INDIRECT_Y, M_AC, M_INDY, 6, 0}, /* (Indirect),Y */ + /* 92 */ + {JAM, IMPLIED, M_NONE, M_NONE, 0, 0}, /* TILT relative? */ + /* 93 */ + {SHA, INDIRECT_Y, M_ANXR, M_STH0, 6, 0}, + + /* 94 */ + {STY, ZERO_PAGE_X, M_YR, M_ZERX, 4, 0}, /* Zeropage,X */ + /* 95 */ + {STA, ZERO_PAGE_X, M_AC, M_ZERX, 4, 0}, /* Zeropage,X */ + /* 96 */ + {STX, ZERO_PAGE_Y, M_XR, M_ZERY, 4, 0}, /* Zeropage,Y */ + /* 97 */ + {SAX, ZERO_PAGE_Y, M_ANXR, M_ZERY, 4, 0}, + + /* 98 */ + {TYA, IMPLIED, M_YR, M_AC, 2, 0}, + /* 99 */ + {STA, ABSOLUTE_Y, M_AC, M_ABSY, 5, 0}, /* Absolute,Y */ + /* 9a */ + {TXS, IMPLIED, M_XR, M_SP, 2, 0}, +/*** This is very mysterious command ... */ + /* 9b */ + {SHS, ABSOLUTE_Y, M_ANXR, M_STH3, 5, 0}, + + /* 9c */ + {SHY, ABSOLUTE_X, M_YR, M_STH2, 5, 0}, + /* 9d */ + {STA, ABSOLUTE_X, M_AC, M_ABSX, 5, 0}, /* Absolute,X */ + /* 9e */ + {SHX, ABSOLUTE_Y, M_XR, M_STH1, 5, 0}, + /* 9f */ + {SHA, ABSOLUTE_Y, M_ANXR, M_STH1, 5, 0}, + + /* a0 */ + {LDY, IMMEDIATE, M_IMM, M_YR, 2, 0}, /* Immediate */ + /* a1 */ + {LDA, INDIRECT_X, M_INDX, M_AC, 6, 0}, /* (indirect,X) */ + /* a2 */ + {LDX, IMMEDIATE, M_IMM, M_XR, 2, 0}, /* Immediate */ + /* a3 */ + {LAX, INDIRECT_X, M_INDX, M_ACXR, 6, 0}, /* (indirect,X) */ + + /* a4 */ + {LDY, ZERO_PAGE, M_ZERO, M_YR, 3, 0}, /* Zeropage */ + /* a5 */ + {LDA, ZERO_PAGE, M_ZERO, M_AC, 3, 0}, /* Zeropage */ + /* a6 */ + {LDX, ZERO_PAGE, M_ZERO, M_XR, 3, 0}, /* Zeropage */ + /* a7 */ + {LAX, ZERO_PAGE, M_ZERO, M_ACXR, 3, 0}, + + /* a8 */ + {TAY, IMPLIED, M_AC, M_YR, 2, 0}, + /* a9 */ + {LDA, IMMEDIATE, M_IMM, M_AC, 2, 0}, /* Immediate */ + /* aa */ + {TAX, IMPLIED, M_AC, M_XR, 2, 0}, + /* ab */ + {LXA, IMMEDIATE, M_ACIM, M_ACXR, 2, 0}, /* LXA isn't a typo */ + + /* ac */ + {LDY, ABSOLUTE, M_ABS, M_YR, 4, 0}, /* Absolute */ + /* ad */ + {LDA, ABSOLUTE, M_ABS, M_AC, 4, 0}, /* Absolute */ + /* ae */ + {LDX, ABSOLUTE, M_ABS, M_XR, 4, 0}, /* Absolute */ + /* af */ + {LAX, ABSOLUTE, M_ABS, M_ACXR, 4, 0}, + + /* b0 */ + {BCS, RELATIVE, M_REL, M_NONE, 2, 0}, + /* b1 */ + {LDA, INDIRECT_Y, M_INDY, M_AC, 5, 1}, /* (indirect),Y */ + /* b2 */ + {JAM, IMPLIED, M_NONE, M_NONE, 0, 0}, /* TILT */ + /* b3 */ + {LAX, INDIRECT_Y, M_INDY, M_ACXR, 5, 1}, + + /* b4 */ + {LDY, ZERO_PAGE_X, M_ZERX, M_YR, 4, 0}, /* Zeropage,X */ + /* b5 */ + {LDA, ZERO_PAGE_X, M_ZERX, M_AC, 4, 0}, /* Zeropage,X */ + /* b6 */ + {LDX, ZERO_PAGE_Y, M_ZERY, M_XR, 4, 0}, /* Zeropage,Y */ + /* b7 */ + {LAX, ZERO_PAGE_Y, M_ZERY, M_ACXR, 4, 0}, + + /* b8 */ + {CLV, IMPLIED, M_NONE, M_FV, 2, 0}, + /* b9 */ + {LDA, ABSOLUTE_Y, M_ABSY, M_AC, 4, 1}, /* Absolute,Y */ + /* ba */ + {TSX, IMPLIED, M_SP, M_XR, 2, 0}, + /* bb */ + {LAS, ABSOLUTE_Y, M_SABY, M_ACXS, 4, 1}, + + /* bc */ + {LDY, ABSOLUTE_X, M_ABSX, M_YR, 4, 1}, /* Absolute,X */ + /* bd */ + {LDA, ABSOLUTE_X, M_ABSX, M_AC, 4, 1}, /* Absolute,X */ + /* be */ + {LDX, ABSOLUTE_Y, M_ABSY, M_XR, 4, 1}, /* Absolute,Y */ + /* bf */ + {LAX, ABSOLUTE_Y, M_ABSY, M_ACXR, 4, 1}, + + /* c0 */ + {CPY, IMMEDIATE, M_IMM, M_NONE, 2, 0}, /* Immediate */ + /* c1 */ + {CMP, INDIRECT_X, M_INDX, M_NONE, 6, 0}, /* (Indirect,X) */ + /* c2 */ + {NOOP, IMMEDIATE, M_NONE, M_NONE, 2, 0}, /* occasional TILT */ + /* c3 */ + {DCP, INDIRECT_X, M_INDX, M_INDX, 8, 0}, + + /* c4 */ + {CPY, ZERO_PAGE, M_ZERO, M_NONE, 3, 0}, /* Zeropage */ + /* c5 */ + {CMP, ZERO_PAGE, M_ZERO, M_NONE, 3, 0}, /* Zeropage */ + /* c6 */ + {DEC, ZERO_PAGE, M_ZERO, M_ZERO, 5, 0}, /* Zeropage */ + /* c7 */ + {DCP, ZERO_PAGE, M_ZERO, M_ZERO, 5, 0}, + + /* c8 */ + {INY, IMPLIED, M_YR, M_YR, 2, 0}, + /* c9 */ + {CMP, IMMEDIATE, M_IMM, M_NONE, 2, 0}, /* Immediate */ + /* ca */ + {DEX, IMPLIED, M_XR, M_XR, 2, 0}, + /* cb */ + {SBX, IMMEDIATE, M_IMM, M_XR, 2, 0}, + + /* cc */ + {CPY, ABSOLUTE, M_ABS, M_NONE, 4, 0}, /* Absolute */ + /* cd */ + {CMP, ABSOLUTE, M_ABS, M_NONE, 4, 0}, /* Absolute */ + /* ce */ + {DEC, ABSOLUTE, M_ABS, M_ABS, 6, 0}, /* Absolute */ + /* cf */ + {DCP, ABSOLUTE, M_ABS, M_ABS, 6, 0}, + + /* d0 */ + {BNE, RELATIVE, M_REL, M_NONE, 2, 0}, + /* d1 */ + {CMP, INDIRECT_Y, M_INDY, M_NONE, 5, 1}, /* (Indirect),Y */ + /* d2 */ + {JAM, IMPLIED, M_NONE, M_NONE, 0, 0}, /* TILT */ + /* d3 */ + {DCP, INDIRECT_Y, M_INDY, M_INDY, 8, 0}, + + /* d4 */ + {NOOP, ZERO_PAGE_X, M_NONE, M_NONE, 4, 0}, + /* d5 */ + {CMP, ZERO_PAGE_X, M_ZERX, M_NONE, 4, 0}, /* Zeropage,X */ + /* d6 */ + {DEC, ZERO_PAGE_X, M_ZERX, M_ZERX, 6, 0}, /* Zeropage,X */ + /* d7 */ + {DCP, ZERO_PAGE_X, M_ZERX, M_ZERX, 6, 0}, + + /* d8 */ + {CLD, IMPLIED, M_NONE, M_FD, 2, 0}, + /* d9 */ + {CMP, ABSOLUTE_Y, M_ABSY, M_NONE, 4, 1}, /* Absolute,Y */ + /* da */ + {NOOP, IMPLIED, M_NONE, M_NONE, 2, 0}, + /* db */ + {DCP, ABSOLUTE_Y, M_ABSY, M_ABSY, 7, 0}, + + /* dc */ + {NOOP, ABSOLUTE_X, M_NONE, M_NONE, 4, 1}, + /* dd */ + {CMP, ABSOLUTE_X, M_ABSX, M_NONE, 4, 1}, /* Absolute,X */ + /* de */ + {DEC, ABSOLUTE_X, M_ABSX, M_ABSX, 7, 0}, /* Absolute,X */ + /* df */ + {DCP, ABSOLUTE_X, M_ABSX, M_ABSX, 7, 0}, + + /* e0 */ + {CPX, IMMEDIATE, M_IMM, M_NONE, 2, 0}, /* Immediate */ + /* e1 */ + {SBC, INDIRECT_X, M_INDX, M_AC, 6, 0}, /* (Indirect,X) */ + /* e2 */ + {NOOP, IMMEDIATE, M_NONE, M_NONE, 2, 0}, + /* e3 */ + {ISB, INDIRECT_X, M_INDX, M_INDX, 8, 0}, + + /* e4 */ + {CPX, ZERO_PAGE, M_ZERO, M_NONE, 3, 0}, /* Zeropage */ + /* e5 */ + {SBC, ZERO_PAGE, M_ZERO, M_AC, 3, 0}, /* Zeropage */ + /* e6 */ + {INC, ZERO_PAGE, M_ZERO, M_ZERO, 5, 0}, /* Zeropage */ + /* e7 */ + {ISB, ZERO_PAGE, M_ZERO, M_ZERO, 5, 0}, + + /* e8 */ + {INX, IMPLIED, M_XR, M_XR, 2, 0}, + /* e9 */ + {SBC, IMMEDIATE, M_IMM, M_AC, 2, 0}, /* Immediate */ + /* ea */ + {NOP, IMPLIED, M_NONE, M_NONE, 2, 0}, + /* eb */ + {USBC, IMMEDIATE, M_IMM, M_AC, 2, 0}, /* same as e9 */ + + /* ec */ + {CPX, ABSOLUTE, M_ABS, M_NONE, 4, 0}, /* Absolute */ + /* ed */ + {SBC, ABSOLUTE, M_ABS, M_AC, 4, 0}, /* Absolute */ + /* ee */ + {INC, ABSOLUTE, M_ABS, M_ABS, 6, 0}, /* Absolute */ + /* ef */ + {ISB, ABSOLUTE, M_ABS, M_ABS, 6, 0}, + + /* f0 */ + {BEQ, RELATIVE, M_REL, M_NONE, 2, 0}, + /* f1 */ + {SBC, INDIRECT_Y, M_INDY, M_AC, 5, 1}, /* (Indirect),Y */ + /* f2 */ + {JAM, IMPLIED, M_NONE, M_NONE, 0, 0}, /* TILT */ + /* f3 */ + {ISB, INDIRECT_Y, M_INDY, M_INDY, 8, 0}, + + /* f4 */ + {NOOP, ZERO_PAGE_X, M_NONE, M_NONE, 4, 0}, + /* f5 */ + {SBC, ZERO_PAGE_X, M_ZERX, M_AC, 4, 0}, /* Zeropage,X */ + /* f6 */ + {INC, ZERO_PAGE_X, M_ZERX, M_ZERX, 6, 0}, /* Zeropage,X */ + /* f7 */ + {ISB, ZERO_PAGE_X, M_ZERX, M_ZERX, 6, 0}, + + /* f8 */ + {SED, IMPLIED, M_NONE, M_FD, 2, 0}, + /* f9 */ + {SBC, ABSOLUTE_Y, M_ABSY, M_AC, 4, 1}, /* Absolute,Y */ + /* fa */ + {NOOP, IMPLIED, M_NONE, M_NONE, 2, 0}, + /* fb */ + {ISB, ABSOLUTE_Y, M_ABSY, M_ABSY, 7, 0}, + + /* fc */ + {NOOP, ABSOLUTE_X, M_NONE, M_NONE, 4, 1}, + /* fd */ + {SBC, ABSOLUTE_X, M_ABSX, M_AC, 4, 1}, /* Absolute,X */ + /* fe */ + {INC, ABSOLUTE_X, M_ABSX, M_ABSX, 7, 0}, /* Absolute,X */ + /* ff */ + {ISB, ABSOLUTE_X, M_ABSX, M_ABSX, 7, 0} +}; diff -ruNp ./rockbox/apps/plugins/2600box/tiasound.c ./rockbox-working/apps/plugins/2600box/tiasound.c --- ./rockbox/apps/plugins/2600box/tiasound.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/tiasound.c 2013-11-14 07:47:53.835690560 -0500 @@ -0,0 +1,607 @@ +/*****************************************************************************/ +/* */ +/* Module: TIA Chip Sound Simulator */ +/* Purpose: To emulate the sound generation hardware of the Atari TIA chip. */ +/* Author: Ron Fries */ +/* */ +/* Revision History: */ +/* 10-Sep-96 - V1.0 - Initial Release */ +/* 14-Jan-97 - V1.1 - Cleaned up sound output by eliminating counter */ +/* reset. */ +/* */ +/*****************************************************************************/ +/* */ +/* License Information and Copyright Notice */ +/* ======================================== */ +/* */ +/* TiaSound is Copyright(c) 1996 by Ron Fries */ +/* */ +/* This library is free software; you can redistribute it and/or modify it */ +/* under the terms of version 2 of the GNU Library General Public License */ +/* as published by the Free Software Foundation. */ +/* */ +/* This library is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library */ +/* General Public License for more details. */ +/* To obtain a copy of the GNU Library General Public License, write to the */ +/* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* */ +/* Any permitted reproduction of these routines, in whole or in part, must */ +/* bear this legend. */ +/* */ +/*****************************************************************************/ + +#include +#include +/*#include */ +#include "rbconfig.h" + +/* define some data types to keep it platform independent */ +#define int8 char +#define int16 short +#define int32 int + +#define uint8 unsigned int8 +#define uint16 unsigned int16 +#define uint32 unsigned int32 + + +/* CONSTANT DEFINITIONS */ + +/* definitions for AUDCx (15, 16) */ +#define SET_TO_1 0x00 /* 0000 */ +#define POLY4 0x01 /* 0001 */ +#define DIV31_POLY4 0x02 /* 0010 */ +#define POLY5_POLY4 0x03 /* 0011 */ +#define PURE 0x04 /* 0100 */ +#define PURE2 0x05 /* 0101 */ +#define DIV31_PURE 0x06 /* 0110 */ +#define POLY5_2 0x07 /* 0111 */ +#define POLY9 0x08 /* 1000 */ +#define POLY5 0x09 /* 1001 */ +#define DIV31_POLY5 0x0a /* 1010 */ +#define POLY5_POLY5 0x0b /* 1011 */ +#define DIV3_PURE 0x0c /* 1100 */ +#define DIV3_PURE2 0x0d /* 1101 */ +#define DIV93_PURE 0x0e /* 1110 */ +#define DIV3_POLY5 0x0f /* 1111 */ + +#define DIV3_MASK 0x0c + +#define AUDC0 0x15 +#define AUDC1 0x16 +#define AUDF0 0x17 +#define AUDF1 0x18 +#define AUDV0 0x19 +#define AUDV1 0x1a + +/* the size (in entries) of the 4 polynomial tables */ +#define POLY4_SIZE 0x000f +#define POLY5_SIZE 0x001f +#define POLY9_SIZE 0x01ff + +/* channel definitions */ +#define CHAN1 0 +#define CHAN2 1 + +#define FALSE 0 +#define TRUE 1 + + +/* LOCAL GLOBAL VARIABLE DEFINITIONS */ + +/* structures to hold the 6 tia sound control bytes */ +uint8 AUDC[2]; /* AUDCx (15, 16) */ +uint8 AUDF[2]; /* AUDFx (17, 18) */ +uint8 AUDV[2]; /* AUDVx (19, 1A) */ + +static uint8 Outvol[2]; /* last output volume for each channel */ + + +/* Initialze the bit patterns for the polynomials. */ + +/* The 4bit and 5bit patterns are the identical ones used in the tia chip. */ +/* Though the patterns could be packed with 8 bits per byte, using only a */ +/* single bit per byte keeps the math simple, which is important for */ +/* efficient processing. */ + +static uint8 Bit4[POLY4_SIZE] = + { 1,1,0,1,1,1,0,0,0,0,1,0,1,0,0 }; + +static uint8 Bit5[POLY5_SIZE] = + { 0,0,1,0,1,1,0,0,1,1,1,1,1,0,0,0,1,1,0,1,1,1,0,1,0,1,0,0,0,0,1 }; + +/* I've treated the 'Div by 31' counter as another polynomial because of */ +/* the way it operates. It does not have a 50% duty cycle, but instead */ +/* has a 13:18 ratio (of course, 13+18 = 31). This could also be */ +/* implemented by using counters. */ + +static uint8 Div31[POLY5_SIZE] = + { 0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0 }; + +/* Rather than have a table with 511 entries, I use a random number */ +/* generator. */ + +static uint8 Bit9[POLY9_SIZE]; + +static uint8 P4[2]; /* Position pointer for the 4-bit POLY array */ +static uint8 P5[2]; /* Position pointer for the 5-bit POLY array */ +static uint16 P9[2]; /* Position pointer for the 9-bit POLY array */ + +static uint8 Div_n_cnt[2]; /* Divide by n counter. one for each channel */ +static uint8 Div_n_max[2]; /* Divide by n maximum, one for each channel */ + + +/* In my routines, I treat the sample output as another divide by N counter. */ +/* For better accuracy, the Samp_n_cnt has a fixed binary decimal point */ +/* which has 8 binary digits to the right of the decimal point. */ + +static uint16 Samp_n_max; /* Sample max, multiplied by 256 */ +static uint16 Samp_n_cnt; /* Sample cnt. */ + + + +/*****************************************************************************/ +/* Module: Tia_sound_init() */ +/* Purpose: to handle the power-up initialization functions */ +/* these functions should only be executed on a cold-restart */ +/* */ +/* Author: Ron Fries */ +/* Date: September 10, 1996 */ +/* */ +/* Inputs: sample_freq - the value for the '30 Khz' Tia audio clock */ +/* playback_freq - the playback frequency in samples per second */ +/* */ +/* Outputs: Adjusts local globals - no return value */ +/* */ +/*****************************************************************************/ + +void Tia_sound_init (uint16 sample_freq, uint16 playback_freq) +{ + uint8 chan; + int16 n; + + /* fill the 9bit polynomial with random bits */ + for (n=0; nrand() & 0x01; /* fill poly9 with random bits */ + } + + /* calculate the sample 'divide by N' value based on the playback freq. */ + Samp_n_max = (uint16)(((uint32)sample_freq<<8)/playback_freq); + Samp_n_cnt = 0; /* initialize all bits of the sample counter */ + + /* initialize the local globals */ + for (chan = CHAN1; chan <= CHAN2; chan++) + { + Outvol[chan] = 0; + Div_n_cnt[chan] = 0; + Div_n_max[chan] = 0; + AUDC[chan] = 0; + AUDF[chan] = 0; + AUDV[chan] = 0; + P4[chan] = 0; + P5[chan] = 0; + P9[chan] = 0; + } +} + + +/*****************************************************************************/ +/* Module: Update_tia_sound() */ +/* Purpose: To process the latest control values stored in the AUDF, AUDC, */ +/* and AUDV s. It pre-calculates as much information as */ +/* possible for better performance. This routine has not been */ +/* optimized. */ +/* */ +/* Author: Ron Fries */ +/* Date: January 14, 1997 */ +/* */ +/* Inputs: addr - the address of the parameter to be changed */ +/* val - the new value to be placed in the specified address */ +/* */ +/* Outputs: Adjusts local globals - no return value */ +/* */ +/*****************************************************************************/ + +void Update_tia_sound (uint16 addr, uint8 val) +{ + uint16 new_val = 0; + uint8 chan; + + /* determine which address was changed */ + switch (addr) + { + case AUDC0: + AUDC[0] = val & 0x0f; + chan = 0; + break; + + case AUDC1: + AUDC[1] = val & 0x0f; + chan = 1; + break; + + case AUDF0: + AUDF[0] = val & 0x1f; + chan = 0; + break; + + case AUDF1: + AUDF[1] = val & 0x1f; + chan = 1; + break; + + case AUDV0: + AUDV[0] = (val & 0x0f) << 3; + chan = 0; + break; + + case AUDV1: + AUDV[1] = (val & 0x0f) << 3; + chan = 1; + break; + + default: + chan = 255; + break; + } + + /* if the output value changed */ + if (chan != 255) + { + /* an AUDC value of 0 is a special case */ + if (AUDC[chan] == SET_TO_1) + { + /* indicate the clock is zero so no processing will occur */ + new_val = 0; + + /* and set the output to the selected volume */ + Outvol[chan] = AUDV[chan]; + } + else + { + /* otherwise calculate the 'divide by N' value */ + new_val = AUDF[chan] + 1; + + /* if bits 2 & 3 are set, then multiply the 'div by n' count by 3 */ + if ((AUDC[chan] & DIV3_MASK) == DIV3_MASK) + { + new_val *= 3; + } + } + + /* only reset those channels that have changed */ + if (new_val != Div_n_max[chan]) + { + /* reset the divide by n counters */ + Div_n_max[chan] = new_val; + + /* if the channel is now volume only or was volume only */ + if ((Div_n_cnt[chan] == 0) || (new_val == 0)) + { + /* reset the counter (otherwise let it complete the previous) */ + Div_n_cnt[chan] = new_val; + } + } + } +} + + +/*****************************************************************************/ +/* Module: Tia_process_2() */ +/* Purpose: To fill the output buffer with the sound output based on the */ +/* tia chip parameters. This routine has not been optimized. */ +/* Though it is not used by the program, I've left it for reference.*/ +/* */ +/* Author: Ron Fries */ +/* Date: September 10, 1996 */ +/* */ +/* Inputs: *buffer - pointer to the buffer where the audio output will */ +/* be placed */ +/* n - size of the playback buffer */ +/* */ +/* Outputs: the buffer will be filled with n bytes of audio - no return val */ +/* */ +/*****************************************************************************/ + +void Tia_process ( unsigned char *buffer, uint16 n) +{ + uint8 chan; + + /* loop until the buffer is filled */ + while (n) + { + /* loop through the channels */ + for (chan = CHAN1; chan <= CHAN2; chan++) + { + /* NOTE: this routine intentionally does not count down to zero */ + /* since 0 is used as a special case - no clock */ + + /* if the divide by N counter can count down */ + if (Div_n_cnt[chan] > 1) + { + /* decrement and loop */ + Div_n_cnt[chan]--; + } + /* otherwise if we've reached the bottom */ + else if (Div_n_cnt[chan] == 1) + { + /* reset the counter */ + Div_n_cnt[chan] = Div_n_max[chan]; + + /* the P5 counter has multiple uses, so we inc it here */ + P5[chan]++; + if (P5[chan] == POLY5_SIZE) + P5[chan] = 0; + + /* check clock modifier for clock tick */ + + /* if we're using pure tones OR + we're using DIV31 and the DIV31 bit is set OR + we're using POLY5 and the POLY5 bit is set */ + if (((AUDC[chan] & 0x02) == 0) || + (((AUDC[chan] & 0x01) == 0) && Div31[P5[chan]]) || + (((AUDC[chan] & 0x01) == 1) && Bit5[P5[chan]])) + { + if (AUDC[chan] & 0x04) /* pure modified clock selected */ + { + if (Outvol[chan]) /* if the output was set */ + Outvol[chan] = 0; /* turn it off */ + else + Outvol[chan] = AUDV[chan]; /* else turn it on */ + } + else if (AUDC[chan] & 0x08) /* check for p5/p9 */ + { + if (AUDC[chan] == POLY9) /* check for poly9 */ + { + /* inc the poly9 counter */ + P9[chan]++; + if (P9[chan] == POLY9_SIZE) + P9[chan] = 0; + + if (Bit9[P9[chan]]) /* if poly9 bit is set */ + Outvol[chan] = AUDV[chan]; + else + Outvol[chan] = 0; + } + else /* must be poly5 */ + { + if (Bit5[P5[chan]]) + Outvol[chan] = AUDV[chan]; + else + Outvol[chan] = 0; + } + } + else /* poly4 is the only remaining option */ + { + /* inc the poly4 counter */ + P4[chan]++; + if (P4[chan] == POLY4_SIZE) + P4[chan] = 0; + + if (Bit4[P4[chan]]) + Outvol[chan] = AUDV[chan]; + else + Outvol[chan] = 0; + } + } + } + } + + /* decrement the sample counter - value is 256 since the lower + byte contains the fractional part */ + Samp_n_cnt -= 256; + + /* if the count down has reached zero */ + if (Samp_n_cnt < 256) + { + /* adjust the sample counter */ + Samp_n_cnt += Samp_n_max; + + /* calculate the latest output value and place in buffer */ + *(buffer++) = Outvol[0] + Outvol[1]; + + /* and indicate one less byte to process */ + n--; + } + } +} + + +/*****************************************************************************/ +/* Module: Tia_process() */ +/* Purpose: To fill the output buffer with the sound output based on the */ +/* tia chip parameters. This routine has been optimized. */ +/* */ +/* Author: Ron Fries */ +/* Date: September 10, 1996 */ +/* */ +/* Inputs: *buffer - pointer to the buffer where the audio output will */ +/* be placed */ +/* n - size of the playback buffer */ +/* */ +/* Outputs: the buffer will be filled with n bytes of audio - no return val */ +/* */ +/*****************************************************************************/ + +void Tia_process_2 ( unsigned char *buffer, uint16 n) +{ + uint8 audc0,audv0,audc1,audv1; + uint8 div_n_cnt0,div_n_cnt1; + uint8 p5_0, p5_1,outvol_0,outvol_1; + + audc0 = AUDC[0]; + audv0 = AUDV[0]; + audc1 = AUDC[1]; + audv1 = AUDV[1]; + + /* make temporary local copy */ + p5_0 = P5[0]; + p5_1 = P5[1]; + outvol_0 = Outvol[0]; + outvol_1 = Outvol[1]; + div_n_cnt0 = Div_n_cnt[0]; + div_n_cnt1 = Div_n_cnt[1]; + + /* loop until the buffer is filled */ + while (n) + { + /* Process channel 0 */ + if (div_n_cnt0 > 1) + { + div_n_cnt0--; + } + else if (div_n_cnt0 == 1) + { + div_n_cnt0 = Div_n_max[0]; + + /* the P5 counter has multiple uses, so we inc it here */ + p5_0++; + if (p5_0 == POLY5_SIZE) + p5_0 = 0; + + /* check clock modifier for clock tick */ + if (((audc0 & 0x02) == 0) || + (((audc0 & 0x01) == 0) && Div31[p5_0]) || + (((audc0 & 0x01) == 1) && Bit5[p5_0])) + { + if (audc0 & 0x04) /* pure modified clock selected */ + { + if (outvol_0) /* if the output was set */ + outvol_0 = 0; /* turn it off */ + else + outvol_0 = audv0; /* else turn it on */ + } + else if (audc0 & 0x08) /* check for p5/p9 */ + { + if (audc0 == POLY9) /* check for poly9 */ + { + /* inc the poly9 counter */ + P9[0]++; + if (P9[0] == POLY9_SIZE) + P9[0] = 0; + + if (Bit9[P9[0]]) + outvol_0 = audv0; + else + outvol_0 = 0; + } + else /* must be poly5 */ + { + if (Bit5[p5_0]) + outvol_0 = audv0; + else + outvol_0 = 0; + } + } + else /* poly4 is the only remaining option */ + { + /* inc the poly4 counter */ + P4[0]++; + if (P4[0] == POLY4_SIZE) + P4[0] = 0; + + if (Bit4[P4[0]]) + outvol_0 = audv0; + else + outvol_0 = 0; + } + } + } + + + /* Process channel 1 */ + if (div_n_cnt1 > 1) + { + div_n_cnt1--; + } + else if (div_n_cnt1 == 1) + { + div_n_cnt1 = Div_n_max[1]; + + /* the P5 counter has multiple uses, so we inc it here */ + p5_1++; + if (p5_1 == POLY5_SIZE) + p5_1 = 0; + + /* check clock modifier for clock tick */ + if (((audc1 & 0x02) == 0) || + (((audc1 & 0x01) == 0) && Div31[p5_1]) || + (((audc1 & 0x01) == 1) && Bit5[p5_1])) + { + if (audc1 & 0x04) /* pure modified clock selected */ + { + if (outvol_1) /* if the output was set */ + outvol_1 = 0; /* turn it off */ + else + outvol_1 = audv1; /* else turn it on */ + } + else if (audc1 & 0x08) /* check for p5/p9 */ + { + if (audc1 == POLY9) /* check for poly9 */ + { + /* inc the poly9 counter */ + P9[1]++; + if (P9[1] == POLY9_SIZE) + P9[1] = 0; + + if (Bit9[P9[1]]) + outvol_1 = audv1; + else + outvol_1 = 0; + } + else /* must be poly5 */ + { + if (Bit5[p5_1]) + outvol_1 = audv1; + else + outvol_1 = 0; + } + } + else /* poly4 is the only remaining option */ + { + /* inc the poly4 counter */ + P4[1]++; + if (P4[1] == POLY4_SIZE) + P4[1] = 0; + + if (Bit4[P4[1]]) + outvol_1 = audv1; + else + outvol_1 = 0; + } + } + } + + /* decrement the sample counter - value is 256 since the lower + byte contains the fractional part */ + Samp_n_cnt -= 256; + + /* if the count down has reached zero */ + if (Samp_n_cnt < 256) + { + /* adjust the sample counter */ + Samp_n_cnt += Samp_n_max; + + /* calculate the latest output value and place in buffer */ + *(buffer++) = outvol_0 + outvol_1; + + /* and indicate one less byte to process */ + n--; + } + } + + /* save for next round */ + P5[0] = p5_0; + P5[1] = p5_1; + Outvol[0] = outvol_0; + Outvol[1] = outvol_1; + Div_n_cnt[0] = div_n_cnt0; + Div_n_cnt[1] = div_n_cnt1; + +} + + + diff -ruNp ./rockbox/apps/plugins/2600box/tiasound.h ./rockbox-working/apps/plugins/2600box/tiasound.h --- ./rockbox/apps/plugins/2600box/tiasound.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/tiasound.h 2013-11-14 07:47:53.835690560 -0500 @@ -0,0 +1,42 @@ +/*****************************************************************************/ +/* */ +/* Module: TIA Chip Sound Simulator Includes, V1.0 */ +/* Purpose: Define global function prototypes and structures for the TIA */ +/* Chip Sound Simulator. */ +/* Author: Ron Fries */ +/* Date: September 10, 1996 */ +/* */ +/*****************************************************************************/ +/* */ +/* License Information and Copyright Notice */ +/* ======================================== */ +/* */ +/* TiaSound is Copyright(c) 1996 by Ron Fries */ +/* */ +/* This library is free software; you can redistribute it and/or modify it */ +/* under the terms of version 2 of the GNU Library General Public License */ +/* as published by the Free Software Foundation. */ +/* */ +/* This library is distributed in the hope that it will be useful, but */ +/* WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library */ +/* General Public License for more details. */ +/* To obtain a copy of the GNU Library General Public License, write to the */ +/* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +/* */ +/* Any permitted reproduction of these routines, in whole or in part, must */ +/* bear this legend. */ +/* */ +/*****************************************************************************/ + +#ifndef _TIASOUND_H +#define _TIASOUND_H + +void Tia_sound_init (unsigned int sample_freq, unsigned int playback_freq); +void Update_tia_sound (unsigned int addr, unsigned char val); +void Tia_process_2 (register unsigned char *buffer, + register unsigned int n); +void Tia_process (register unsigned char *buffer, + register unsigned int n); + +#endif diff -ruNp ./rockbox/apps/plugins/2600box/txt_debug.c ./rockbox-working/apps/plugins/2600box/txt_debug.c --- ./rockbox/apps/plugins/2600box/txt_debug.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/txt_debug.c 2013-11-14 07:47:53.835690560 -0500 @@ -0,0 +1,13 @@ + + +int debugf_on, debugf_halt, debugf_trace, debugf_raster; + +void +init_debugger (void) +{ +} + +void +x_loop (void) +{ +} diff -ruNp ./rockbox/apps/plugins/2600box/types.h ./rockbox-working/apps/plugins/2600box/types.h --- ./rockbox/apps/plugins/2600box/types.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/types.h 2013-11-14 09:23:53.135502940 -0500 @@ -0,0 +1,37 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: types.h,v 1.4 1996/09/04 22:37:48 ahornby Exp $ +******************************************************************************/ + + +/* + * This file declares useful types. + */ + + +#ifndef V2600_TYPES_H +#define V2600_TYPES_H + + +typedef signed char SIGNED_CHAR; + +typedef unsigned int UINT32; +typedef unsigned short UINT16; + +typedef unsigned char BYTE; +typedef unsigned short ADDRESS; +typedef unsigned long CLOCK; + +typedef int ADDR_T; + +#endif diff -ruNp ./rockbox/apps/plugins/2600box/ui.h ./rockbox-working/apps/plugins/2600box/ui.h --- ./rockbox/apps/plugins/2600box/ui.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/ui.h 2013-11-14 07:47:53.835690560 -0500 @@ -0,0 +1,30 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: ui.h,v 1.3 1996/08/12 21:31:25 ahornby Exp $ +******************************************************************************/ + +/* + User Interface (UI) prototypes. + */ + + +#ifndef UI_H +#define UI_H + +void +fancy_widgets(Widget parent); + +int +fselLoad(void); + +#endif diff -ruNp ./rockbox/apps/plugins/2600box/version.h ./rockbox-working/apps/plugins/2600box/version.h --- ./rockbox/apps/plugins/2600box/version.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/version.h 2013-11-14 07:47:53.835690560 -0500 @@ -0,0 +1 @@ +#define _2600_VERSION "0.82" diff -ruNp ./rockbox/apps/plugins/2600box/vidmode.h ./rockbox-working/apps/plugins/2600box/vidmode.h --- ./rockbox/apps/plugins/2600box/vidmode.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/vidmode.h 2013-11-14 07:47:53.835690560 -0500 @@ -0,0 +1,24 @@ +#ifndef _VIDMODE +#define _VIDMODE + +int +get_nummodes(void); + +char * +describe_mode(int m); + +void +modeswitch(int mode); + +int +modeswitch_on(void); + +void +modeswitch_off(void); + +void +position_port(int x, int y); + +extern int modeswitch_flag; + +#endif diff -ruNp ./rockbox/apps/plugins/2600box/vmachine.c ./rockbox-working/apps/plugins/2600box/vmachine.c --- ./rockbox/apps/plugins/2600box/vmachine.c 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/vmachine.c 2013-11-14 10:03:20.307425825 -0500 @@ -0,0 +1,717 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: vmachine.c,v 2.22 1997/11/22 14:27:47 ahornby Exp $ +******************************************************************************/ + +/* + The virtual machine. Contains the RIOT timer code, and hardware + initialisation. + */ + +#include +#include "types.h" +#include "address.h" +#include "options.h" +#include "display.h" +#include "raster.h" +#include "limiter.h" +#include "cpu.h" +#include "misc.h" +#include "collision.h" +#include "sound.h" +#include "keyboard.h" +#include "realjoy.h" +#include "dbg_mess.h" + +/* The Rom define might need altering for paged carts */ +/* Enough for 16k carts */ +int rom_size; + +/* Used as a simple file buffer to store the data */ +BYTE theCart[16384]; + +/* Pointer to start of ROM data */ +BYTE *theRom; + +/* Scratch area for those banking types that require memcpy() */ +BYTE cartScratch[4096]; + +/* Area for those carts containing RAM */ +BYTE cartRam[1024]; + +BYTE theRam[128]; +BYTE tiaRead[0x0e]; +BYTE tiaWrite[0x2d]; +BYTE keypad[2][4]; + +/* These don't strictly need so much space */ +BYTE riotRead[0x298]; +BYTE riotWrite[0x298]; + +/* + Hardware addresses not programmer accessible + */ + +/* Set if whole emulator is reset */ +int reset_flag = 0; + +/* The timer resolution, can be 1,8,64,1024 */ +int timer_res = 32; +int timer_count = 0; +int timer_clks = 0; +extern CLOCK clk; +extern int beamadj; + +/* Electron beam position */ +int ebeamx, ebeamy, sbeamx; + +/* The state of the electron beam */ +#define VSYNCSTATE 1 +#define VBLANKSTATE 2 +#define HSYNCSTATE 4 +#define DRAWSTATE 8 +#define OVERSTATE 16 +int vbeam_state; /* 1 2 8 or 16 */ +int hbeam_state; /* 4 8 or 16 */ + +/* The tv size, varies with PAL/NTSC */ +int tv_width, tv_height, tv_vsync, tv_vblank, tv_overscan, tv_frame, tv_hertz, + tv_hsync; + +/* The PlayField structure */ +struct PlayField + { + BYTE pf0, pf1, pf2, ref; + } +pf[2]; + +struct Paddle + { + int pos; + int val; + } +paddle[4]; + +/* The player variables */ +struct Player + { + int x; + BYTE grp; + BYTE hmm; + BYTE vdel; + BYTE vdel_flag; + BYTE nusize; + BYTE reflect; + BYTE mask; + } +pl[2]; + +/* The element used in display lists */ +struct RasterChange + { + int x; /* Position at which change happened */ + int type; /* Type of change */ + int val; /* Value of change */ + }; + +#define MAXLIST 80 +/* The various display lists */ +struct RasterChange pl_change[2][MAXLIST], pf_change[1][MAXLIST], unified[MAXLIST]; + +/* The display list counters */ +int pl_change_count[2], pf_change_count[1], unified_count; + +/* The missile an ball positions */ +struct Missile + { + int x; + BYTE hmm; + BYTE enabled; + BYTE locked; + BYTE width; + BYTE vdel; + BYTE vdel_flag; + BYTE mask; + } +ml[3]; + + + +/*************************************************************************** + Let the functions begin! +****************************************************************************/ + +/* Device independent screen initialisations */ +void +extern init_screen (void) +{ + /* Set the electron beam to the top left */ + ebeamx = -tv_hsync; + ebeamy = 0; + sbeamx = 0; + vbeam_state = VSYNCSTATE; + hbeam_state = OVERSTATE; + + tv_vsync = 3; + tv_hsync = 68; + switch (base_opts.tvtype) + { + case NTSC: + tv_width = 160; + tv_height = 192; + tv_vblank = 40; + tv_overscan = 30; + tv_frame = 262; + tv_hertz = 60; + break; + case PAL: + case SECAM: + tv_width = 160; + tv_height = 228; + tv_vblank = 48; + tv_overscan = 36; + tv_frame = 312; + tv_hertz = 50; + break; + } + + limiter_init (); + limiter_setFrameRate (tv_hertz); +} + +/* Initialise the RIOT (also known as PIA) */ +void +extern init_riot (void) +{ + int i; + + /* Reset the arrays */ + for(i=0; i< 0x298;i++) + { + riotRead[i]=0; + riotWrite[i]=0; + } + + /* Wipe the RAM */ + for (i = 0; i < 0x80; i++) + theRam[i] = 0; + + /* Set the timer to zero */ + riotRead[INTIM] = 0; + + /* Set the joysticks and switches to input */ + riotWrite[SWACNT] = 0; + riotWrite[SWBCNT] = 0; + + /* Centre the joysticks */ + riotRead[SWCHA] = 0xff; + riotRead[SWCHB] = 0x0b; + + /* Set the counter resolution */ + timer_res = 32; + timer_count = 0; + timer_clks = 0; +} + +/* Initialise the television interface adaptor (TIA) */ +void +extern init_tia (void) +{ + int i; + for(i=0; i< 0x2d;i++) + { + tiaWrite[i]=0; + } + for(i=0; i< 0x0e;i++) + { + tiaRead[i]=0; + } + + tiaWrite[CTRLPF] = 0x00; + for (i = 0; i < 2; i++) + { + pl[i].hmm = 0x0; + pl[i].x = 0x0; + pl[i].nusize = 0; + pl[i].grp = 0; + pl[i].vdel = 0; + pl[i].vdel_flag = 0; + pl_change_count[i] = 0; + } + + pl[0].mask = PL0_MASK; + pl[1].mask = PL1_MASK; + ml[0].mask = ML0_MASK; + ml[1].mask = ML1_MASK; + reset_collisions (); + + pf_change_count[0] = 0; + unified_count = 0; + for (i = 0; i < 3; i++) + { + ml[i].x = 0; + ml[i].hmm = 0; + ml[i].enabled = 0; + ml[i].locked = 0; + ml[i].width = 0; + ml[i].vdel = 0; + ml[i].vdel_flag = 0; + } + + tiaWrite[VBLANK] = 0; + tiaRead[INPT4] = 0x80; + tiaRead[INPT5] = 0x80; + + /* Set up the colour table */ + colour_table[P0M0_COLOUR]= tv_color(0); + colour_table[P1M1_COLOUR]= tv_color(0); + colour_table[PFBL_COLOUR] = tv_color(0); + colour_table[BK_COLOUR] = tv_color(0); +} + +void +extern init_memory(void) +{ + int i; + for(i=0;i<1024; i++) + cartRam[i]=0; + for(i=0; i<128;i++) + theRam[i]=0; +} + +void +extern init_banking (void) +{ + /* Set to the first bank */ + dbg_message(DBG_NORMAL, "rom_size is set at %d bytes\n", rom_size); + if (rom_size == 2048) + theRom = &theCart[rom_size - 2048]; + else + theRom = &theCart[rom_size - 4096]; + + switch(base_opts.bank) + { + case 3: + /* Parker Brothers 8k E0 */ + memcpy(&cartScratch[0xc00],&theCart[0x1c00],1024); + memcpy(&cartScratch[0],&theCart[0],3072); + theRom=cartScratch; + break; + default: + break; + } +} + +extern void init_cpu( ADDRESS addr); + +/* Main hardware startup */ +void +extern init_hardware (void) +{ + dbg_message(DBG_NORMAL,"Setting Up hardware\n"); + init_screen (); + init_riot (); + init_tia (); + init_raster (); + init_memory(); + init_banking(); + init_cpu (0xfffc); +} + +/* Do a raster change */ +inline void +extern do_raster_change (int i, int type, int val, struct RasterChange *rc) +{ + if (beamadj == 0) + { + printf ("BEAMADJ == 0\n"); + show (); + } + rc->x = ebeamx + beamadj; + rc->type = type; + rc->val = val; +} + +/* Do a raster change on the unified list */ +/* type: type of change */ +/* val: value of change */ +inline void +extern do_unified_change (int type, int val) +{ + if (unified_count < MAXLIST) + { + unified[unified_count].x = ebeamx + beamadj; + unified[unified_count].type = type; + unified[unified_count].val = val; + unified_count++; + } +} + +/* Do a player raster change */ +/* i: player to change. 0 or 1 */ +/* type: type of change */ +/* val: value of change */ +inline void +extern do_plraster_change (int i, int type, int val) +{ + int plc = pl_change_count[i]; + /*printf("Raster change i=%d, x=%d, type=%d, val=%d\n", i, x, type, val); */ + if (plc < MAXLIST) + { + do_raster_change (i, type, val, &pl_change[i][plc]); + if (type == 1) + pl_change[i][plc].x -= 3; + pl_change_count[i]++; + } +} + +/* Do a playfield raster change */ +/* i: playfield to change. Depreciated, as 0 is now only one used */ +/* type: type of change */ +/* val: value of change */ +inline void +extern do_pfraster_change (int i, int type, int val) +{ + int pfc = pf_change_count[i]; + /* + if(ebeamy>=100) { + printf("Raster change i=%d, x=%d, type=%d, val=%d\n", + i, ebeamx+beamadj, type, val); + show(); + } + */ + if (pfc < MAXLIST) + { + do_raster_change (i, type, val, &pf_change[i][pfc]); + pf_change_count[i]++; + } +} + + +/* Use a unified change */ +/* rc: unified change structure to use */ +inline void +extern use_unified_change (struct RasterChange *rc) +{ + switch (rc->type) + { + case 0: + /* P0MO colour */ + colour_table[P0M0_COLOUR] = rc->val; + break; + case 1: + /* POM0 colour */ + colour_table[P1M1_COLOUR] = rc->val; + break; + case 2: + /* PFBL colour */ + colour_table[PFBL_COLOUR] = rc->val; + break; + case 3: + /* BK colour */ + colour_table[BK_COLOUR] = rc->val; + break; + case 4: + /* Priority change Normal */ + if(rc->val) + norm_val=1; + else + norm_val=0; + colour_lookup=colour_ptrs[norm_val][scores_val]; + break; + case 5: + /* Priority change Scores */ + if(rc->val) + { + if(rc->x < 80) + scores_val=1; + else + scores_val=2; + } + else + scores_val=0; + colour_lookup=colour_ptrs[norm_val][scores_val]; + break; + } +} + +/* Use a playfield change */ +/* pl: playfield to change */ +/* rc: change to make */ +inline void +extern use_pfraster_change (struct PlayField *pl, struct RasterChange *rc) +{ + switch (rc->type) + { + case 0: + /* PF0 */ + pl->pf0 = rc->val; + break; + case 1: + /* PF1 */ + pl->pf1 = rc->val; + break; + case 2: + /* PF2 */ + pl->pf2 = rc->val; + break; + case 3: + /* Reflection */ + pl->ref = rc->val; + break; + } +} + +/* Use a player change */ +/* pl: player to change */ +/* rc: change to make */ +inline void +extern use_plraster_change (struct Player *pl, struct RasterChange *rc) +{ + switch (rc->type) + { + case 0: + /* GRP */ + pl->grp = rc->val; + break; + /* Vertical delay */ + case 1: + pl->vdel = pl->grp; + break; + } +} + + +int +extern do_paddle (int padnum) +{ + int res = 0x80; + int x; + if ((tiaWrite[VBLANK] & 0x80) == 0) + { + x = 320 - mouse_position (); + x = x * 45; + x += paddle[padnum].val; + if (x > clk) + res = 0x00; + } + return res; +} + +/* Calculate the keypad rows */ +/* i.e. when reading from INPTx we don't know the row */ +BYTE +extern do_keypad (int pad, int col) +{ + BYTE res= 0x80; + + read_keypad(pad); + + /* Bottom row */ + if(pad==0) { + if( (riotWrite[SWCHA] & 0x80) && keypad[pad][col]==3) + res=0x00; + /* Third row */ + if( (riotWrite[SWCHA] & 0x40) && keypad[pad][col]==2) + res=0x00; + if( (riotWrite[SWCHA] & 0x20) && keypad[pad][col]==1) + res=0x00; + if( (riotWrite[SWCHA] & 0x10) && keypad[pad][col]==0) + res=0x00; + } + else { + /* Bottom row */ + if( (riotWrite[SWCHA] & 0x80) && keypad[pad][col]==3) + res=0x00; + /* Third row */ + if( (riotWrite[SWCHA] & 0x40) && keypad[pad][col]==2) + res=0x00; + if( (riotWrite[SWCHA] & 0x20) && keypad[pad][col]==1) + res=0x00; + if( (riotWrite[SWCHA] & 0x10) && keypad[pad][col]==0) + res=0x00; + } + return res; +} + + +/* + Called when the timer is set . + Note that res is the bit shift, not absolute value. + Assumes that any timer interval set will last longer than the instruction + setting it. + */ +/* res: timer interval resolution as a bit shift value */ +/* count: the number of intervals to set */ +/* clkadj: the number of CPU cycles into the current instruction */ +void +extern set_timer (int res, int count, int clkadj) +{ + timer_count = count << res; + timer_clks = clk + clkadj; + timer_res = res; +} + +/* New timer code, now only called on a read of INTIM */ +/* clkadj: the number of CPU cycles into the current instruction */ +/* returns: the current timer value */ +BYTE +extern do_timer (int clkadj) +{ + BYTE result; + int delta; + int value; + + delta = clk - timer_clks; + value = delta >> timer_res; + if (delta <= timer_count) + { /* Timer is still going down in res intervals */ + result = value; + } + else + { + if (value == 0) + /* Timer is in holding period */ + result = 0; + else + { + /* Timer is descending from 0xff in clock intervals */ + set_timer (0, 0xff, clkadj); + result = 0; + } + } + + /* printf("Timer result=%d\n", result); */ + return result; +} + +/* Do the screen related part of a write to VBLANK */ +/* b: the byte written */ +void +extern do_vblank (BYTE b) +{ + if (b & 0x02) + { + /* Start vertical blank */ + vbeam_state = VBLANKSTATE; + /* Also means we can update screen */ + sound_update (); + update_realjoy (); + tv_event (); + tv_display (); + /* Only wait if we're on a faster display */ + if (base_opts.rr == 1) + limiter_sync (); + } + else + { + /* End vblank, and start first hsync drawing */ + int i; + + vbeam_state = DRAWSTATE; + hbeam_state = HSYNCSTATE; + /* Set up the screen */ + for (i = 0; i < unified_count; i++) + use_unified_change (&unified[i]); + /* Hope for a WSYNC, but just in case */ + ebeamx = -tv_hsync; + ebeamy = 0; + } +} + + +/* do a horizontal sync */ +void +extern do_hsync (void) +{ + /* Only perform heavy stuff if electron beam is in correct position */ + if (vbeam_state == DRAWSTATE && (ebeamx > -tv_hsync)) + { + tv_raster (ebeamy); + /* Fix the clock value */ + clk += (ebeamx - tv_width) / 3; + ebeamy++; + } + hbeam_state = HSYNCSTATE; + ebeamx = -tv_hsync; + sbeamx = 0; +} + +/* Main screen logic */ +/* clks: CPU clock length of last instruction */ +void +extern do_screen (int clks) +{ + switch (vbeam_state) + { + case VSYNCSTATE: + case VBLANKSTATE: + switch (hbeam_state) + { + case HSYNCSTATE: + ebeamx += clks * 3; + if (ebeamx >= 0) + { + hbeam_state = DRAWSTATE; + } + break; + case DRAWSTATE: + ebeamx += clks * 3; + if (ebeamx >= tv_width) + { + ebeamx -= (tv_hsync + tv_width); + /* Insert hsync stuff here */ + sbeamx = ebeamx; + hbeam_state = HSYNCSTATE; + } + break; + case OVERSTATE: + break; + } + break; + case DRAWSTATE: + switch (hbeam_state) + { + case HSYNCSTATE: + ebeamx += clks * 3; + if (ebeamx >= 0) + { + hbeam_state = DRAWSTATE; + } + break; + case DRAWSTATE: + ebeamx += clks * 3; + if (ebeamx >= tv_width) + { + /* Insert hsync stuff here */ + sbeamx = ebeamx; + ebeamx -= (tv_hsync + tv_width); + tv_raster (ebeamy); + ebeamy++; + hbeam_state = HSYNCSTATE; + } + if (ebeamy >= tv_height + tv_overscan) + { + vbeam_state = OVERSTATE; + ebeamy = 0; + } + break; + case OVERSTATE: + break; + } + break; + case OVERSTATE: + break; + } +} + diff -ruNp ./rockbox/apps/plugins/2600box/vmachine.h ./rockbox-working/apps/plugins/2600box/vmachine.h --- ./rockbox/apps/plugins/2600box/vmachine.h 1969-12-31 19:00:00.000000000 -0500 +++ ./rockbox-working/apps/plugins/2600box/vmachine.h 2013-11-14 07:47:53.835690560 -0500 @@ -0,0 +1,137 @@ +/***************************************************************************** + + This file is part of x2600, the Atari 2600 Emulator + =================================================== + + Copyright 1996 Alex Hornby. For contributions see the file CREDITS. + + This software is distributed under the terms of the GNU General Public + License. This is free software with ABSOLUTELY NO WARRANTY. + + See the file COPYING for details. + + $Id: vmachine.h,v 2.13 1996/11/24 16:55:40 ahornby Exp $ +******************************************************************************/ + + +/* + External definitions of the 2600 virtual machine. +*/ + + +#ifndef VMACHINE_H +#define VMACHINE_H + +extern int rom_size; +extern BYTE theCart[16384]; +extern BYTE *theRom; +extern BYTE cartScratch[4096]; +extern BYTE cartRam[1024]; +extern BYTE theRam[128]; +extern BYTE riotRead[0x298]; +extern BYTE riotWrite[0x298]; +extern BYTE tiaWrite[0x2d]; +extern BYTE tiaRead[0x0e]; +extern BYTE keypad[2][4]; + +extern int reset_flag; + +extern int ebeamx, ebeamy, sbeamx; + +#define VSYNCSTATE 1 +#define VBLANKSTATE 2 +#define HSYNCSTATE 4 +#define DRAWSTATE 8 +#define OVERSTATE 16 + +extern int vbeam_state, hbeam_state; + +extern int tv_width, tv_height, tv_vsync, tv_vblank, + tv_overscan, tv_frame, tv_hertz, tv_hsync; + +extern int timer_res, timer_count, timer_clks; + +extern struct PlayField { + BYTE pf0,pf1,pf2; + BYTE ref; +} pf[2]; + +extern struct Paddle { + int pos; + int val; +} paddle[4]; + +extern struct Player { + int x; + BYTE grp; + BYTE hmm; + BYTE vdel; + BYTE vdel_flag; + BYTE nusize; + BYTE reflect; + BYTE mask; +} pl[2]; + +struct RasterChange { + int x; /* Position at which change happened */ + int type; /* Type of change */ + int val; /* Value of change */ +} ; + +extern struct RasterChange pl_change[2][80], pf_change[1][80], unified[80]; + +extern int pl_change_count[2], pf_change_count[1], unified_count; + +/* The missile and ball positions */ +extern struct Missile { + int x; + BYTE hmm; + BYTE locked; + BYTE enabled; + BYTE width; + BYTE vdel; + BYTE vdel_flag; + BYTE mask; +} ml[3]; + +/**************************************************************************** + functions. +*****************************************************************************/ + +inline void +do_plraster_change(int i, int type, int val); + +inline void +do_unified_change(int type, int val); + +inline void +use_unified_change( struct RasterChange *rc); + +inline void +use_plraster_change( struct Player *pl, struct RasterChange *rc); + +inline void +do_pfraster_change(int i, int type, int val); + +inline void +use_pfraster_change( struct PlayField *pf, struct RasterChange *rc); + +void init_hardware(void); +void init_banking(void); + +inline void set_timer(int res, int count, int clkadj); +inline BYTE do_timer(int clkadj); +inline void do_vblank(BYTE b); +inline void do_hsync(void); + +int do_paddle(int padnum); +BYTE do_keypad(int pad, int col); +inline void do_screen(int clks); + +#endif + + + + + + diff -ruNp ./rockbox/apps/plugins/CATEGORIES ./rockbox-working/apps/plugins/CATEGORIES --- ./rockbox/apps/plugins/CATEGORIES 2013-11-14 17:03:19.762604904 -0500 +++ ./rockbox-working/apps/plugins/CATEGORIES 2013-11-14 10:12:07.675408645 -0500 @@ -132,3 +132,4 @@ wavview,viewers wormlet,games xobox,games zxbox,viewers +2600box,viewers diff -ruNp ./rockbox/apps/plugins/SUBDIRS ./rockbox-working/apps/plugins/SUBDIRS --- ./rockbox/apps/plugins/SUBDIRS 2013-11-14 17:03:19.826604902 -0500 +++ ./rockbox-working/apps/plugins/SUBDIRS 2013-11-14 17:02:13.650607058 -0500 @@ -11,7 +11,7 @@ clock /* For all targets with a bitmap display */ #ifdef HAVE_LCD_BITMAP - +2600box #if (CONFIG_KEYPAD != ONDIO_PAD) /* not enough buttons */ \ && (CONFIG_KEYPAD != SANSA_M200_PAD) /* not enough buttons */ \ && (CONFIG_KEYPAD != HM60X_PAD) /* not enough buttons */ \ diff -ruNp ./rockbox/apps/plugins/viewers.config ./rockbox-working/apps/plugins/viewers.config --- ./rockbox/apps/plugins/viewers.config 2013-11-14 17:03:19.766604904 -0500 +++ ./rockbox-working/apps/plugins/viewers.config 2013-11-14 10:33:04.771367692 -0500 @@ -22,6 +22,7 @@ jpeg,viewers/bench_mem_jpeg,- png,viewers/imageviewer,2 #ifdef HAVE_LCD_COLOR ppm,viewers/imageviewer,2 +bin,viewers/2600box,12 #endif gif,viewers/imageviewer,2 ucl,viewers/rockbox_flash,3