summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2003-12-24 18:19:00 +0000
committerIan C <ianc@noddybox.co.uk>2003-12-24 18:19:00 +0000
commit6a86fc4668ce7e213330bb78aff45c578e159f54 (patch)
tree360d7295ff108f6408ab740ff297fb99468faa08 /src
parent33dfea1c74749124379ef8052f0689577ebe68ff (diff)
devel snapshot
Diffstat (limited to 'src')
-rw-r--r--src/Makefile19
-rw-r--r--src/config.c8
-rw-r--r--src/config.h3
-rw-r--r--src/gfx.c32
-rw-r--r--src/gfx.h16
-rw-r--r--src/main.c11
-rw-r--r--src/memmenu.c55
-rw-r--r--src/spec.c531
8 files changed, 312 insertions, 363 deletions
diff --git a/src/Makefile b/src/Makefile
index ed3c38e..347c5d0 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -18,7 +18,7 @@
#
# -------------------------------------------------------------------------
#
-# $Id: Makefile,v 1.1.1.1 2003-12-23 23:33:02 ianc Exp $
+# $Id: Makefile,v 1.2 2003-12-24 18:19:00 ianc Exp $
#
@@ -89,13 +89,13 @@ main.o: /usr/local/include/SDL/SDL_keyboard.h
main.o: /usr/local/include/SDL/SDL_keysym.h
main.o: /usr/local/include/SDL/SDL_mouse.h /usr/local/include/SDL/SDL_video.h
main.o: /usr/local/include/SDL/SDL_mutex.h /usr/local/include/SDL/SDL_quit.h
-main.o: /usr/local/include/SDL/SDL_version.h gfx.h gui.h memmenu.h config.h
-main.o: exit.h
+main.o: /usr/local/include/SDL/SDL_version.h z80/z80.h spec.h gfx.h gui.h
+main.o: memmenu.h config.h exit.h
spec.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h
spec.o: /usr/include/sys/_types.h /usr/include/machine/_types.h
spec.o: /usr/include/stdio.h /usr/include/string.h /usr/include/strings.h
-spec.o: gfx.h /usr/local/include/SDL/SDL.h /usr/local/include/SDL/SDL_main.h
-spec.o: /usr/local/include/SDL/SDL_types.h
+spec.o: spec.h z80/z80.h /usr/local/include/SDL/SDL.h
+spec.o: /usr/local/include/SDL/SDL_main.h /usr/local/include/SDL/SDL_types.h
spec.o: /usr/local/include/SDL/SDL_getenv.h
spec.o: /usr/local/include/SDL/SDL_error.h
spec.o: /usr/local/include/SDL/begin_code.h
@@ -111,7 +111,7 @@ spec.o: /usr/local/include/SDL/SDL_keyboard.h
spec.o: /usr/local/include/SDL/SDL_keysym.h
spec.o: /usr/local/include/SDL/SDL_mouse.h /usr/local/include/SDL/SDL_video.h
spec.o: /usr/local/include/SDL/SDL_mutex.h /usr/local/include/SDL/SDL_quit.h
-spec.o: /usr/local/include/SDL/SDL_version.h gui.h config.h exit.h
+spec.o: /usr/local/include/SDL/SDL_version.h gfx.h gui.h config.h exit.h
config.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h
config.o: /usr/include/sys/_types.h /usr/include/machine/_types.h
config.o: /usr/include/stdio.h /usr/include/string.h /usr/include/strings.h
@@ -156,8 +156,9 @@ gui.o: /usr/local/include/SDL/SDL_quit.h /usr/local/include/SDL/SDL_version.h
gui.o: gfx.h exit.h
memmenu.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h
memmenu.o: /usr/include/sys/_types.h /usr/include/machine/_types.h
-memmenu.o: /usr/include/string.h /usr/include/strings.h memmenu.h gfx.h
-memmenu.o: /usr/local/include/SDL/SDL.h /usr/local/include/SDL/SDL_main.h
+memmenu.o: /usr/include/string.h /usr/include/strings.h memmenu.h z80/z80.h
+memmenu.o: spec.h /usr/local/include/SDL/SDL.h
+memmenu.o: /usr/local/include/SDL/SDL_main.h
memmenu.o: /usr/local/include/SDL/SDL_types.h
memmenu.o: /usr/local/include/SDL/SDL_getenv.h
memmenu.o: /usr/local/include/SDL/SDL_error.h
@@ -177,7 +178,7 @@ memmenu.o: /usr/local/include/SDL/SDL_mouse.h
memmenu.o: /usr/local/include/SDL/SDL_video.h
memmenu.o: /usr/local/include/SDL/SDL_mutex.h
memmenu.o: /usr/local/include/SDL/SDL_quit.h
-memmenu.o: /usr/local/include/SDL/SDL_version.h gui.h
+memmenu.o: /usr/local/include/SDL/SDL_version.h gfx.h gui.h
exit.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h
exit.o: /usr/include/sys/_types.h /usr/include/machine/_types.h
exit.o: /usr/include/stdarg.h exit.h /usr/local/include/SDL/SDL.h
diff --git a/src/config.c b/src/config.c
index 4035d22..c1c6e09 100644
--- a/src/config.c
+++ b/src/config.c
@@ -51,6 +51,7 @@ static int memsize=16;
static int frames=50;
static int scale=1;
static int trace=0;
+static int sound=1;
static const struct
{
@@ -61,10 +62,10 @@ static const struct
{"rompath", rompath, FALSE},
{"tapedir", tapedir, FALSE},
{"fullscreen", &fullscreen, TRUE},
- {"memsize", &memsize, TRUE},
{"frames", &frames, TRUE},
{"scale", &scale, TRUE},
{"trace", &trace, TRUE},
+ {"sound", &sound, TRUE},
{NULL, NULL, FALSE}
};
@@ -136,7 +137,7 @@ void ConfigRead(void)
if (getenv("HOME"))
strcpy(path,getenv("HOME"));
- strcat(path,"/.ezx81");
+ strcat(path,"/.espec");
if ((fp=fopen(path,"r")))
{
@@ -154,7 +155,8 @@ int IConfig(IConfigVar v)
&memsize,
&frames,
&scale,
- &trace
+ &trace,
+ &sound
};
return *vars[v];
diff --git a/src/config.h b/src/config.h
index 94dad15..4115460 100644
--- a/src/config.h
+++ b/src/config.h
@@ -36,7 +36,8 @@ typedef enum
CONF_MEMSIZE,
CONF_FRAMES_PER_SEC,
CONF_SCALE,
- CONF_TRACE
+ CONF_TRACE,
+ CONF_SOUND
} IConfigVar;
diff --git a/src/gfx.c b/src/gfx.c
index a77c496..739b876 100644
--- a/src/gfx.c
+++ b/src/gfx.c
@@ -51,7 +51,7 @@ static const char ident_fh[]=ESPEC_FONT_H;
#endif
#define SCR_W 320
-#define SCR_H 200
+#define SCR_H 300
#define LOCK do \
{ \
@@ -168,8 +168,16 @@ void GFXInit(void)
frame=1000/IConfig(CONF_FRAMES_PER_SEC);
- if (SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO))
- Exit("Failed to init SDL: %s\n",SDL_GetError());
+ if (IConfig(CONF_SOUND))
+ {
+ if (SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO|SDL_INIT_AUDIO))
+ Exit("Failed to init SDL: %s\n",SDL_GetError());
+ }
+ else
+ {
+ if (SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO))
+ Exit("Failed to init SDL: %s\n",SDL_GetError());
+ }
if (!(surface=SDL_SetVideoMode(SCR_W*scale,
SCR_H*scale,
@@ -262,6 +270,18 @@ SDL_Event *GFXWaitKey(void)
}
+void GFXLock(void)
+{
+ LOCK;
+}
+
+
+void GFXUnlock(void)
+{
+ UNLOCK;
+}
+
+
void GFXPlot(int x, int y, Uint32 col)
{
LOCK;
@@ -272,6 +292,12 @@ void GFXPlot(int x, int y, Uint32 col)
}
+void GFXFastPlot(int x, int y, Uint32 col)
+{
+ putpixel(x,y,col);
+}
+
+
void GFXRect(int x, int y, int w, int h, Uint32 col, int solid)
{
LOCK;
diff --git a/src/gfx.h b/src/gfx.h
index baa19d2..d3f1ec3 100644
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -92,11 +92,27 @@ SDL_Event *GFXGetKey(void);
SDL_Event *GFXWaitKey(void);
+/* Lock the screen for updates
+*/
+void GFXLock(void);
+
+
+/* Unlock the screen following updates
+*/
+void GFXUnlock(void);
+
+
/*
Note that no bound checking (except for GFXPrint()) is done - it is the
callers responsibility to plot onscreen.
*/
+/* Plot a point without locking. GFXLock() and GFXUnlock() MUST surround
+ calls to this
+*/
+void GFXFastPlot(int x, int y, Uint32 col);
+
+
/* Plot a point
*/
void GFXPlot(int x, int y, Uint32 col);
diff --git a/src/main.c b/src/main.c
index e69eb77..c97aab3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -91,8 +91,19 @@ int main(int argc, char *argv[])
while(!quit)
{
+ Z80State s1,s2;
+
+ Z80GetState(z80,&s1);
Z80SingleStep(z80);
+ Z80GetState(z80,&s2);
+
+ if (s2.PC>0x3fff)
+ {
+ printf("PC > 0x3fff - from 0x%4.4x\n",s1.PC);
+ return 0;
+ }
+
if (trace)
{
DisplayState(z80);
diff --git a/src/memmenu.c b/src/memmenu.c
index 2badf65..516bd36 100644
--- a/src/memmenu.c
+++ b/src/memmenu.c
@@ -20,13 +20,14 @@
-------------------------------------------------------------------------
- Provides a common error exit point
+ Provides the memory menu
*/
static const char ident[]="$Id$";
#include <stdlib.h>
#include <string.h>
+#include <ctype.h>
#include "memmenu.h"
#include "spec.h"
@@ -51,8 +52,6 @@ static const char ident_h[]=ESPEC_MEMMENU_H;
#define GREEN GFXRGB(100,255,100)
#define BLUE GFXRGB(100,100,255)
-#define MENU
-
/* ---------------------------------------- PRIVATE FUNCTIONS
*/
@@ -104,7 +103,49 @@ static const char *FlagString(Z80Byte flag)
}
-static int EnterAddress(Z80Word *w)
+static int StrEq(const char *a, const char *b)
+{
+ while(*a && *b && tolower(*a)==tolower(*b))
+ {
+ a++;
+ b++;
+ }
+
+ if (*a || *b)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+
+static Z80Word Address(Z80 *z80, const char *p)
+{
+ Z80State s;
+
+ Z80GetState(z80,&s);
+
+ if (StrEq(p,"AF"))
+ return s.AF;
+ else if (StrEq(p,"BC"))
+ return s.BC;
+ else if (StrEq(p,"DE"))
+ return s.DE;
+ else if (StrEq(p,"HL"))
+ return s.HL;
+ else if (StrEq(p,"IX"))
+ return s.IX;
+ else if (StrEq(p,"IY"))
+ return s.IY;
+ else if (StrEq(p,"SP"))
+ return s.SP;
+ else if (StrEq(p,"PC"))
+ return s.PC;
+
+ return (Z80Word)strtoul(p,NULL,0);
+}
+
+
+static int EnterAddress(Z80 *z80, Z80Word *w)
{
unsigned long ul;
const char *p;
@@ -113,7 +154,7 @@ static int EnterAddress(Z80Word *w)
if (*p)
{
- ul=strtoul(p,NULL,0);
+ ul=Address(z80,p);
if (ul>0xffff)
{
@@ -213,7 +254,7 @@ static void DoDisassem(Z80 *z80, const Z80State *s)
case SDLK_RETURN:
case SDLK_KP_ENTER:
- EnterAddress(&pc);
+ EnterAddress(z80,&pc);
break;
case SDLK_UP:
@@ -324,6 +365,4 @@ void DisplayState(Z80 *z80)
}
-
-
/* END OF FILE */
diff --git a/src/spec.c b/src/spec.c
index 51006df..a8cb9eb 100644
--- a/src/spec.c
+++ b/src/spec.c
@@ -47,51 +47,79 @@ static const char ident_h[]=ESPEC_SPECH;
/* ---------------------------------------- STATICS
*/
-static const int ROMLEN=0x2000;
-static const int ROM_SAVE=0x2fc;
-static const int ROM_LOAD=0x347;
-
-/* No of cycles in each 64us HSYNC (hopefully)
-*/
-static const int HSYNC_PERIOD=321;
+static const int ROMLEN=0x4000;
+static const int ROM_SAVE=0x4c6;
+static const int ROM_LOAD=0x562;
/* The SPEC screen
*/
-static const int SCR_W=256;
-static const int SCR_H=192;
-static const int TXT_W=32;
-static const int TXT_H=24;
+#define GFX_W 320
+#define GFX_H 300
+#define SCR_W 256
+#define SCR_H 192
+#define TXT_W 32
+#define TXT_H 24
+#define SCRDATA 0x4000
+#define ATTR 0x5800
-/* These assume a 320x200 screen
-*/
-static const int OFF_X=(320-256)/2;
-static const int OFF_Y=(200-192)/2;
+#define ATTR_AT(x,y) \
+ mem[ATTR+(x)+((y)/8)*32]
+
+static const int OFF_X=(GFX_W-SCR_W)/2;
+static const int OFF_Y=(GFX_H-SCR_H)/2;
static Z80Byte mem[0x10000];
-static Z80Word RAMBOT=0;
-static Z80Word RAMTOP=0;
-static Z80Word RAMLEN=0;
-/* Counter used when triggering the interrupts for the display
+/* Number of cycles per scan lines and scan line control
*/
-static int nmigen=FALSE;
-static int hsync=FALSE;
+static Z80Val SCAN_CYCLES=224;
+static int scanline=0;
+
-/* The ULA
+/* GFX vars
*/
+#define FLASH 16 /* Frames per flash */
+
+static int flash=0;
+static int flashctr=0;
+
+static int border=0;
+
+#define TOPL 64 /* Scanlines before 'first' line */
+#define SCRL SCR_H /* Scanlines making up screen data */
+#define BOTL 56 /* Scanlines after 'last' line */
+
+#define TOTL (TOPL+SCRL+BOTL)
+
+#define NVAL 235 /* Normal RGB intensity */
+#define BVAL 255 /* Bright RGB intensity */
+
static struct
{
- int x;
- int y;
- int c;
- int release;
-} ULA;
+ Uint32 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 */
-/* GFX vars
-*/
-static Uint32 white;
-static Uint32 black;
+};
/* The keyboard
@@ -150,9 +178,6 @@ static const MatrixMap keymap[]=
{SDLK_RETURN, KY1(6,0)},
{SDLK_SPACE, KY1(7,0)},
- {SDLK_COMMA, KY1(7,1)}, /* In the right place... */
- {SDLK_PERIOD, KY1(7,1)}, /* ...or the right key... */
-
{SDLK_BACKSPACE, KY2(0,0,4,0)},
{SDLK_DELETE, KY2(0,0,4,0)},
{SDLK_UP, KY2(0,0,4,3)},
@@ -160,8 +185,13 @@ static const MatrixMap keymap[]=
{SDLK_LEFT, KY2(0,0,3,4)},
{SDLK_RIGHT, KY2(0,0,4,2)},
- {SDLK_RSHIFT, KY1(0,0)},
{SDLK_LSHIFT, KY1(0,0)},
+ {SDLK_RSHIFT, KY1(7,1)},
+ {SDLK_LCTRL, KY1(0,0)},
+ {SDLK_RCTRL, KY1(7,1)},
+ {SDLK_LALT, KY1(0,0)},
+ {SDLK_RALT, KY1(7,1)},
+ {SDLK_CAPSLOCK, KY2(0,0,3,1)},
{SDLK_UNKNOWN, 0,0,0,0},
};
@@ -169,19 +199,71 @@ static const MatrixMap keymap[]=
/* ---------------------------------------- PRIVATE FUNCTIONS
*/
+void DrawScanline(int y)
+{
+ int aline;
+ int f,r;
+ int ink,paper,t;
+ Z80Byte *scr;
+ Z80Byte b;
+ Z80Byte att;
+
+ aline=scanline-TOPL;
+
+ GFXHLine(0,GFX_W-1,y,coltable[border].col);
+
+ if (aline>=0 && aline<SCRL)
+ {
+ GFXLock();
+
+ scr=mem+SCRDATA+aline*TXT_W;
+
+ for(f=0;f<TXT_W;f++)
+ {
+ att=ATTR_AT(f,aline);
+
+ ink=(att&0x07);
+ paper=(att&0x38)>>3;
+
+ if (att&0x40)
+ {
+ ink+=8;
+ paper+=8;
+ }
+
+ if ((att&0x80)&&(flash))
+ {
+ t=ink;
+ ink=paper;
+ paper=t;
+ }
+
+ for(r=7,b=*scr++;r>=0;r--)
+ if (b&(1<<r))
+ GFXFastPlot(f*8+r+OFF_X,y,coltable[ink].col);
+ else
+ GFXFastPlot(f*8+r+OFF_X,y,coltable[paper].col);
+ }
+
+ GFXUnlock();
+ }
+}
+
+
static void RomPatch(void)
{
static const Z80Byte save[]=
{
0xed, 0xf0, /* ED F0 illegal op */
- 0xc3, 0x08, 0x02, /* JP $0207 */
+ 0xc9, /* RET */
0xff /* End of patch */
};
static const Z80Byte load[]=
{
- 0xed, 0xf1, /* ED F0 illegal op */
- 0xc3, 0x08, 0x02, /* JP $0207 */
+ 0x08, /* EX AF,AF' */
+ 0xed, 0xf1, /* ED F1 illegal op */
+ 0xc9, /* RET */
0xff /* End of patch */
};
@@ -195,121 +277,16 @@ static void RomPatch(void)
}
-static char ToASCII(Z80Byte b)
-{
- if (b==0) /* SPACE */
- return ' ';
-
- if (b==22) /* Dash (-) */
- return '-';
-
- if (b>=28 && b<=37) /* 0-9 */
- return '0'+b-28;
-
- if (b>=38 && b<=63) /* A-Z */
- return 'a'+b-38;
-
- return 0;
-}
-
-
-static const char *ConvertFilename(Z80Word addr)
-{
- static char buff[FILENAME_MAX];
- char *p;
-
- p=buff;
- *p=0;
-
- if (addr>0x8000)
- return buff;
-
- do
- {
- char c=ToASCII(mem[addr]&0x7f);
-
- if (c)
- *p++=c;
-
- } while(mem[addr++]<0x80);
-
- *p=0;
-
- return buff;
-}
-
static void LoadTape(Z80State *state)
{
- const char *p=ConvertFilename(state->DE);
- char path[FILENAME_MAX];
- FILE *fp;
- Z80Word addr;
- int c;
-
- if (strlen(p)==0)
- {
- GUIMessage("ERROR","Can't load empty filename");
- return;
- }
-
- strcpy(path,SConfig(CONF_TAPEDIR));
- strcat(path,"/");
- strcat(path,p);
- strcat(path,".p");
-
- if (!(fp=fopen(path,"rb")))
- {
- GUIMessage("ERROR","Can't load file:\n%s",path);
- return;
- }
-
- addr=0x4009;
-
- while((c=getc(fp))!=EOF)
- {
- if (addr>=0x4000)
- mem[addr]=(Z80Byte)c;
-
- addr++;
- }
-
- fclose(fp);
+ state->AF|=Z80_F_Carry;
}
static void SaveTape(Z80State *state)
{
- const char *p=ConvertFilename(state->DE);
- char path[FILENAME_MAX];
- FILE *fp;
- Z80Word start;
- Z80Word end;
-
- if (strlen(p)==0)
- {
- GUIMessage("ERROR","Can't save empty filename");
- return;
- }
-
- strcpy(path,SConfig(CONF_TAPEDIR));
- strcat(path,"/");
- strcat(path,p);
- strcat(path,".p");
-
- if (!(fp=fopen(path,"wb")))
- {
- GUIMessage("ERROR","Can't write file:\n%s",path);
- return;
- }
-
- start=0x4009;
- end=(Z80Word)mem[0x4014]|(Z80Word)mem[0x4015]<<8;
-
- while(start<=end)
- putc(mem[start++],fp);
-
- fclose(fp);
+ state->AF|=Z80_F_Carry;
}
@@ -333,87 +310,51 @@ static int EDCallback(Z80 *z80, Z80Val data)
break;
}
+ Z80SetState(z80,&state);
+
return TRUE;
}
-static void ULA_Video_Shifter(Z80 *z80, Z80Byte val)
+static int CheckTimers(Z80 *z80, Z80Val val)
{
- Z80State state;
- Z80Word base;
- int x,y;
- int inv;
- int b;
-
- Z80GetState(z80,&state);
-
- /* Extra check due to out dodgy ULA emulation
- */
- if (ULA.y>=0 && ULA.y<SCR_H)
+ if (val>SCAN_CYCLES)
{
- Uint32 fg,bg;
+ int y;
- /* Position on screen corresponding to ULA
- */
- x=OFF_X+ULA.x*8;
- y=OFF_Y+ULA.y;
+ Z80ResetCycles(z80,val-SCAN_CYCLES);
- /* Get ULA invert state and clear to ULA 6-but code
+ /* Increment scan line and check for frame flyback
*/
- inv=val&0x80;
- val&=0x3f;
+ scanline++;
- base=((Z80Word)state.I<<8)|(val<<3)|ULA.c;
-
- if (inv)
- {
- fg=white;
- bg=black;
- }
- else
+ if (scanline==TOTL)
{
- fg=black;
- bg=white;
- }
+ scanline=0;
- for(b=0;b<8;b++)
- {
- if (mem[base]&(1<<(7-b)))
- GFXPlot(x+b,y,fg);
- else
- GFXPlot(x+b,y,bg);
- }
- }
+ flashctr++;
- ULA.x=(ULA.x+1)&0x1f;
+ if (flashctr==FLASH)
+ {
+ flash^=1;
+ flashctr=0;
+ }
- if (ULA.x==0)
- Z80Interrupt(z80,0xff);
-}
+ Z80Interrupt(z80,0xff);
+ GFXEndFrame(TRUE);
+ GFXStartFrame();
+ }
-static int CheckTimers(Z80 *z80, Z80Val val)
-{
- if (val>HSYNC_PERIOD)
- {
- Z80ResetCycles(z80,0);
+ /* Draw scanline
+ y=OFF_X-TOPL+scanline;
+ */
+ y=scanline-TOPL+OFF_Y;
- if (nmigen)
- {
- Z80NMI(z80,0xff);
- printf("NMIGEN\n");
- }
- else if (hsync)
- {
- printf("HSYNC\n");
- if (ULA.release)
- {
- /* ULA.release=FALSE; */
- ULA.c=(ULA.c+1)&7;
- ULA.y++;
- ULA.x=0;
- }
- }
+ if (y>=0 && y<GFX_H)
+ DrawScanline(y);
+
+ /* TODO: Process sound emulation */
}
return TRUE;
@@ -429,7 +370,8 @@ void SPECInit(Z80 *z80)
if (!(fp=fopen(SConfig(CONF_ROMFILE),"rb")))
{
- GUIMessage("ERROR","Failed to open SPEC ROM\n%s",SConfig(CONF_ROMFILE));
+ GUIMessage("ERROR","Failed to open Spectrum ROM\n%s",
+ SConfig(CONF_ROMFILE));
Exit("");
}
@@ -446,32 +388,19 @@ void SPECInit(Z80 *z80)
Z80LodgeCallback(z80,Z80_EDHook,EDCallback);
Z80LodgeCallback(z80,Z80_Fetch,CheckTimers);
- /* Mirror the ROM
- */
- memcpy(mem+ROMLEN,mem,ROMLEN);
-
- RAMBOT=0x4000;
-
- /* Memory size (1 or 16K)
+ /* Set up the keyboard
*/
- if (IConfig(CONF_MEMSIZE)==16)
- RAMLEN=0x2000;
- else
- RAMLEN=0x400;
-
- RAMTOP=RAMBOT+RAMLEN;
-
- for(f=RAMBOT;f<=RAMTOP;f++)
- mem[f]=0;
-
for(f=0;f<8;f++)
matrix[f]=0x1f;
- white=GFXRGB(230,230,230);
- black=GFXRGB(0,0,0);
+ /* Set up the colours
+ */
+ for(f=0;f<16;f++)
+ coltable[f].col=GFXRGB(coltable[f].r,coltable[f].g,coltable[f].b);
- nmigen=FALSE;
- hsync=FALSE;
+ scanline=0;
+ flash=0;
+ flashctr=0;
GFXStartFrame();
}
@@ -510,115 +439,53 @@ void SPECKeyEvent(SDL_Event *e)
Z80Byte SPECReadMem(Z80 *z80, Z80Word addr)
{
- /* Memory reads above 32K invoke the ULA
- */
- if (addr>0x7fff)
- {
- Z80Byte b;
-
- /* B6 of R is tied to the IRQ line (only when HSYNC active?)
- if ((HSYNC)&&(!(z80->R&0x40)))
- z80->IRQ=TRUE;
- */
-
- b=mem[addr&0x7fff];
-
- /* If bit 6 of the opcode is set the opcode is sent as is to the
- Z80. If it's not, the byte is interretted by the ULA.
- */
- if (b&0x40)
- {
- ULA_Video_Shifter(z80,0);
- }
- else
- {
- ULA_Video_Shifter(z80,b);
- b=0;
- }
-
- return b;
- }
- else
- return mem[addr&0x7fff];
-
+ /* TODO: Emulation of contention */
+ return mem[addr];
}
void SPECWriteMem(Z80 *z80, Z80Word addr, Z80Byte val)
{
- addr=addr&0x7fff;
-
- if (addr>=RAMBOT && addr<=RAMTOP)
+ if (addr>=ROMLEN)
mem[addr]=val;
}
Z80Byte SPECReadPort(Z80 *z80, Z80Word port)
{
- Z80Byte b=0;
-
- printf("IN %4.4x\n",port);
+ Z80Byte lo=port&0xff;
+ Z80Byte hi=port>>8;
+ Z80Byte b=0xff;
+ int f;
- switch(port&0xff)
+ switch(lo)
{
- case 0xfe: /* ULA */
+ case 0x1f: /* TODO: Kempston joystick */
+ break;
+
+ case 0x7f: /* TODO: Fuller joystick */
+ break;
+
+ case 0xfb: /* TODO: ZX Printer */
+ break;
+
+ case 0x01: /* ULA */
/* Key matrix
*/
- switch(port&0xff00)
- {
- case 0xfe00:
- b=matrix[0];
- break;
- case 0xfd00:
- b=matrix[1];
- break;
- case 0xfb00:
- b=matrix[2];
- break;
- case 0xf700:
- b=matrix[3];
- break;
- case 0xef00:
- b=matrix[4];
- break;
- case 0xdf00:
- b=matrix[5];
- break;
- case 0xbf00:
- b=matrix[6];
- break;
- case 0x7f00:
- b=matrix[7];
- break;
- }
+ b=0;
- /* Turn off HSYNC if NMI generator is OFF and redraw screen to
- match output ULA has since sent out.
- */
- if (!nmigen && hsync)
- {
- hsync=FALSE;
+ for(f=0;f<8;f++)
+ if (!(hi&(1<<f)))
+ b&=matrix[f];
- GFXEndFrame(TRUE);
- GFXClear(white);
+ b|=0xa0;
- ULA.x=0;
- ULA.y=-1;
- ULA.c=7;
- ULA.release=FALSE;
+ /* TODO: Emulation of contention */
- GFXStartFrame();
- }
- else
- {
- /* Reset and hold ULA counter
- */
- ULA.c=0;
- ULA.release=FALSE;
- }
break;
default:
+ b=0xff;
break;
}
@@ -628,25 +495,15 @@ Z80Byte SPECReadPort(Z80 *z80, Z80Word port)
void SPECWritePort(Z80 *z80, Z80Word port, Z80Byte val)
{
- printf("OUT %4.4x\n",port);
-
- /* Any port write releases the ULA line counter
- */
- ULA.release=TRUE;
+ Z80Byte lo=port&0xff;
- switch(port&0xff)
+ switch(lo)
{
- case 0xfd: /* NMI generator OFF */
- nmigen=FALSE;
+ case 0x01: /* ULA */
+ border=val&0x07;
break;
- case 0xfe: /* NMI generator ON */
- nmigen=TRUE;
- break;
-
- case 0xff: /* HSYNC generator ON */
- hsync=TRUE;
- Z80ResetCycles(z80,0);
+ default:
break;
}
}
@@ -654,17 +511,13 @@ void SPECWritePort(Z80 *z80, Z80Word port, Z80Byte val)
Z80Byte SPECReadForDisassem(Z80 *z80, Z80Word addr)
{
- return mem[addr&0x7fff];
+ return mem[addr];
}
const char *SPECInfo(Z80 *z80)
{
- static char buff[80];
-
- sprintf(buff,"NMIGEN: %s HSYNC: %s",
- nmigen ? "ON":"OFF",
- hsync ? "ON":"OFF");
+ static char buff[80]={0};
return buff;
}