From 6701f6a9d4f979cc1eadb673e767b5c46cd2a9c8 Mon Sep 17 00:00:00 2001 From: Ian C Date: Tue, 10 Apr 2007 23:59:35 +0000 Subject: Initial import --- arm9/source/spec.c | 507 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 507 insertions(+) create mode 100644 arm9/source/spec.c (limited to 'arm9/source/spec.c') diff --git a/arm9/source/spec.c b/arm9/source/spec.c new file mode 100644 index 0000000..70b1931 --- /dev/null +++ b/arm9/source/spec.c @@ -0,0 +1,507 @@ +/* + ds48 - Nintendo DS ZX Spectrum emulator. + + Copyright (C) 2007 Ian Cowburn + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + $Id$ + +*/ +#include +#include +#include +#include + +#include "spec.h" +#include "spec48_bin.h" + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define HIBYTE(w) ((w)>>8) +#define LOBYTE(w) ((w)&0xff) + + +/* ---------------------------------------- STATICS +*/ +static uint16 *vram; + +static const int ROMLEN=0x4000; +static const int ROM_SAVE=0x4c6; +static const int ROM_LOAD=0x562; + +#define LOAD_PATCH 0xf0 +#define SAVE_PATCH 0xf1 + +/* The SPEC screen +*/ +#define SCR_W 256 +#define SCR_H 192 +#define TXT_W 32 +#define TXT_H 24 +#define SCRDATA 0x4000 +#define ATTR 0x5800 + +#define ATTR_AT(x,y) Z80_MEMORY[ATTR+(x)+((y)/8)*32] + +Z80Byte Z80_MEMORY[0x10000]; + +/* Number of cycles per frame +*/ +static Z80Val FRAME_CYCLES=69888; + + +/* GFX vars +*/ +#define FLASH 16 /* Frames per flash */ + +static int flash=0; +static int flashctr=0; + +#define NVAL 25 /* Normal RGB intensity */ +#define BVAL 31 /* Bright RGB intensity */ + +static Z80Byte *line[SCR_H]; /* Accelerators to screen data */ + +static struct +{ + uint16 col; + int r,g,b; +} coltable[16]= +{ + {0, 0x00,0x00,0x00}, /* BLACK */ + {0, 0x00,0x00,NVAL}, /* BLUE */ + {0, NVAL,0x00,0x00}, /* RED */ + {0, NVAL,0x00,NVAL}, /* MAGENTA */ + {0, 0x00,NVAL,0x00}, /* GREEN */ + {0, 0x00,NVAL,NVAL}, /* CYAN */ + {0, NVAL,NVAL,0x00}, /* YELLOW */ + {0, NVAL,NVAL,NVAL}, /* WHITE */ + + {0, 0x00,0x00,0x00}, /* BLACK */ + {0, 0x00,0x00,BVAL}, /* BLUE */ + {0, BVAL,0x00,0x00}, /* RED */ + {0, BVAL,0x00,BVAL}, /* MAGENTA */ + {0, 0x00,BVAL,0x00}, /* GREEN */ + {0, 0x00,BVAL,BVAL}, /* CYAN */ + {0, BVAL,BVAL,0x00}, /* YELLOW */ + {0, BVAL,BVAL,BVAL}, /* WHITE */ + +}; + + +/* The keyboard +*/ +static Z80Byte matrix[8]; + +static struct +{ + int row; + int bit; +} key_matrix[]= + { + {3,0x01}, {3,0x02}, {3,0x04}, {3,0x08}, {3,0x10}, /* 1 - 5 */ + {4,0x10}, {4,0x08}, {4,0x04}, {4,0x02}, {4,0x01}, /* 6 - 0 */ + {2,0x01}, {2,0x02}, {2,0x04}, {2,0x08}, {2,0x10}, /* Q - T */ + {5,0x10}, {5,0x08}, {5,0x04}, {5,0x02}, {5,0x01}, /* Y - P */ + {1,0x01}, {1,0x02}, {1,0x04}, {1,0x08}, {1,0x10}, /* A - G */ + {6,0x10}, {6,0x08}, {6,0x04}, {6,0x02}, {6,0x01}, /* H - NL */ + {0,0x01}, {0,0x02}, {0,0x04}, {0,0x08}, {0,0x10}, /* CAPS - V */ + {7,0x10}, {7,0x08}, {7,0x04}, {7,0x02}, {7,0x01} /* B - SPACE */ + }; + +static int debug_matrix = FALSE; + + +/* ---------------------------------------- PRIVATE FUNCTIONS +*/ +static void FillBox(int x, int y, int w, int h, int colour) +{ + int f; + uint16 *base; + + colour|=0x8000; + + base=vram+x+y*256; + + while(h--) + { + for(f=0;f>3; + + if (att&0x40) + { + ink+=8; + paper+=8; + } + + if ((att&0x80)&&(flash)) + { + t=ink; + ink=paper; + paper=t; + } + + b=*scr++; + + for(r=0;r<8;r++) + { + if (b&(1<<(7-r))) + { + *vr++=coltable[ink].col; + } + else + { + *vr++=coltable[paper].col; + } + } + } + } + + if (debug_matrix) + { + int m; + int b; + + for(m=0;m<8;m++) + { + for(b=0;b<8;b++) + { + uint16 col; + + if (matrix[m]&(1<=ROMLEN) + Z80_MEMORY[addr]=val; +} + + +static int EDCallback(Z80 *z80, Z80Val data) +{ + switch((Z80Byte)data) + { + case SAVE_PATCH: + z80->AF.w&=~eZ80_Carry; + break; + + case LOAD_PATCH: + /* + if (TAPLoad(HIBYTE(state.AF), + z80->IX, + z80->DE, + SnapPoke)) + { + state.AF|=eZ80_Carry; + state.BC=0xb001; + } + else + { + state.AF&=~eZ80_Carry; + state.BC=0xff01; + } + */ + + break; + + default: + break; + } + + return TRUE; +} + + +static int CheckTimers(Z80 *z80, Z80Val val) +{ + if (val>FRAME_CYCLES) + { + Z80ResetCycles(z80,val-FRAME_CYCLES); + + flashctr++; + + if (flashctr==FLASH) + { + flash^=1; + flashctr=0; + } + + Z80Interrupt(z80,0xff); + + DrawScreen(); + + /* TODO: Process sound emulation */ + + return FALSE; + } + else + { + return TRUE; + } +} + + +/* ---------------------------------------- EXPORTED INTERFACES +*/ +void SPECInit(uint16 *v, Z80 *z80) +{ + vram=v; + + memcpy(Z80_MEMORY,spec48_bin,ROMLEN); + + /* Patch the ROM + */ + RomPatch(); + Z80LodgeCallback(z80,eZ80_EDHook,EDCallback); + Z80LodgeCallback(z80,eZ80_Instruction,CheckTimers); + + SPECReset(z80); +} + + +void SPECHandleKey(SoftKey key, int is_pressed) +{ + if (key>8; + Z80Byte b=0xff; + int f; + + switch(lo) + { + case 0x1f: /* Kempston joystick */ + break; + + case 0x7f: /* Fuller joystick */ + break; + + case 0xfb: /* ZX Printer */ + break; + + default: /* ULA */ + if (!(lo&1)) + { + /* Key matrix + */ + b=0xff; + + for(f=0;f<8;f++) + if (!(hi&(1<