summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2006-10-28 23:28:31 +0000
committerIan C <ianc@noddybox.co.uk>2006-10-28 23:28:31 +0000
commit73a685f5a17852b6990c0810d0f1f0984c2c358f (patch)
tree2d6bed133b7c59b2787c544a153798c723c64d16
parent6fe1a8fd4735ce006d69cf8bb23df8f7adea7b41 (diff)
Updates from work away
-rw-r--r--.cvsignore3
-rw-r--r--CHANGES10
-rw-r--r--arm9/CHANGES10
-rw-r--r--arm9/include/gui.h1
-rw-r--r--arm9/include/zx81.h4
-rw-r--r--arm9/source/gui.c73
-rw-r--r--arm9/source/main.c62
-rw-r--r--arm9/source/zx81.c124
-rw-r--r--include/gui.h1
-rw-r--r--include/zx81.h4
-rw-r--r--source/gui.c73
-rw-r--r--source/main.c62
-rw-r--r--source/zx81.c124
13 files changed, 530 insertions, 21 deletions
diff --git a/.cvsignore b/.cvsignore
index 6b59bb1..d414090 100644
--- a/.cvsignore
+++ b/.cvsignore
@@ -2,4 +2,5 @@ build
ds81.arm9
ds81.ds.gba
ds81.elf
-ds81.nds \ No newline at end of file
+ds81.nds
+*.p
diff --git a/CHANGES b/CHANGES
new file mode 100644
index 0000000..ae3637f
--- /dev/null
+++ b/CHANGES
@@ -0,0 +1,10 @@
+Key:
+ + Completed
+ * In progress
+ - Not done.
+
+Changes from V1.0 to V1.1
+
+ * Added external FAT file loading.
+ - Added Mazogs as a built-in tape (Paul ....)
+ - Fixed bug where the ROM input routine locks up -- remove ROM bounce?.
diff --git a/arm9/CHANGES b/arm9/CHANGES
new file mode 100644
index 0000000..ae3637f
--- /dev/null
+++ b/arm9/CHANGES
@@ -0,0 +1,10 @@
+Key:
+ + Completed
+ * In progress
+ - Not done.
+
+Changes from V1.0 to V1.1
+
+ * Added external FAT file loading.
+ - Added Mazogs as a built-in tape (Paul ....)
+ - Fixed bug where the ROM input routine locks up -- remove ROM bounce?.
diff --git a/arm9/include/gui.h b/arm9/include/gui.h
index 93557dc..4a07915 100644
--- a/arm9/include/gui.h
+++ b/arm9/include/gui.h
@@ -23,5 +23,6 @@
#define DS81_GUI_H
int GUI_Menu(const char *opts[]);
+void GUI_Alert(int fatal, const char *text);
#endif /* DS81_GUI_H */
diff --git a/arm9/include/zx81.h b/arm9/include/zx81.h
index 1f63f50..992cba7 100644
--- a/arm9/include/zx81.h
+++ b/arm9/include/zx81.h
@@ -39,6 +39,10 @@ void ZX81Init(uint16 *vram, Z80 *z80);
*/
void ZX81HandleKey(SoftKey k, int is_pressed);
+/* Enable fopen() loading of tape files
+*/
+void ZX81EnableFileSystem(int enable);
+
/* Set a file to load from tape
*/
void ZX81SetTape(const Z80Byte *image, int len);
diff --git a/arm9/source/gui.c b/arm9/source/gui.c
index 91c7f8d..713ad02 100644
--- a/arm9/source/gui.c
+++ b/arm9/source/gui.c
@@ -116,3 +116,76 @@ int GUI_Menu(const char *opts[])
return sel;
}
+
+void GUI_Alert(int fatal, const char *text)
+{
+ char line[80];
+ int h;
+ const char *p;
+ char *d;
+
+ h=40;
+ p=text;
+
+ while(*p)
+ {
+ if (*p++=='\n')
+ {
+ h+=8;
+ }
+ }
+
+ FB_FillBox(0,0,SCREEN_WIDTH,h,FB_RGB(0,0,0));
+ FB_Box(1,1,SCREEN_WIDTH-2,h-2,FB_RGB(31,0,0));
+
+ p=text;
+ h=4;
+ d=line;
+
+ while(*p)
+ {
+ if (*p=='\n')
+ {
+ *d++=0;
+ p++;
+ FB_Centre(line,h,FB_RGB(31,31,31),-1);
+ h+=8;
+ d=line;
+ }
+ else
+ {
+ *d++=*p++;
+ }
+ }
+
+ if (d>line)
+ {
+ *d=0;
+ FB_Centre(line,h,FB_RGB(31,31,31),-1);
+ h+=8;
+ }
+
+ if (!fatal)
+ {
+ FB_Centre("PRESS ANY BUTTON OR SCREEN",h+16,FB_RGB(31,31,0),-1);
+
+ while(!keysDown())
+ {
+ swiWaitForVBlank();
+ }
+
+ while(keysHeld())
+ {
+ swiWaitForVBlank();
+ }
+ }
+ else
+ {
+ FB_Centre("PLEASE RESET YOUR CONSOLE",h+16,FB_RGB(31,31,0),-1);
+
+ while(1)
+ {
+ swiWaitForVBlank();
+ }
+ }
+}
diff --git a/arm9/source/main.c b/arm9/source/main.c
index 1da90c2..1a3aa8c 100644
--- a/arm9/source/main.c
+++ b/arm9/source/main.c
@@ -22,7 +22,9 @@
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <nds.h>
+#include <fat.h>
#include "framebuffer.h"
#include "gui.h"
@@ -42,6 +44,7 @@ static const char *main_menu[]=
"Select Tape",
"Sticky Shift On",
"Sticky Shift Off",
+ "Map Joypad to Keys",
"Cancel",
NULL
};
@@ -52,6 +55,7 @@ typedef enum
MenuSelectTape,
MenuStickyOn,
MenuStickyOff,
+ MenuMapJoypad
} MenuOpt;
@@ -74,11 +78,17 @@ static void Splash(void)
"PRESS A TO CONTINUE",
" ",
"http://www.noddybox.co.uk/",
+ " ",
+ " ",
+ " ",
+ " ",
+ "Checking for FAT device...",
NULL
};
sImage img;
int f;
+ int y;
FB_Clear();
@@ -87,9 +97,53 @@ static void Splash(void)
FB_Blit(&img,0,0);
+ y=10;
+
for(f=0;text[f];f++)
{
- FB_Centre(text[f],10+f*8,FB_RGB(31,31,31),-1);
+ FB_Centre(text[f],y,FB_RGB(31,31,31),-1);
+ y+=8;
+ }
+
+ y+=8;
+
+ if (fatInitialise(32,true))
+ {
+ ZX81EnableFileSystem(TRUE);
+
+ FB_Centre("Found a FAT device.",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("If you place .P tape files in",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("the top directory or ZX81TAPE",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("then you should be able to load",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("GAME.P with the command",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("LOAD \"GAME\"",y,FB_RGB(31,31,31),-1);
+ y+=8;
+ }
+ else
+ {
+ ZX81EnableFileSystem(FALSE);
+
+ FB_Centre("Sorry, but you don't have a",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("supported FAT device.",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("Only the internal tape",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("files can be used.",y,FB_RGB(31,31,31),-1);
+ y+=8;
}
ZX81DisplayString("10 print '%the zx81 is ace%'\n20 goto 10");
@@ -153,7 +207,7 @@ int main(int argc, char *argv[])
if (!z80)
{
- return EXIT_FAILURE;
+ GUI_Alert(TRUE,"Failed to initialise\nthe Z80 CPU emulation!");
}
ZX81Init((uint16*)SCREEN_BASE_BLOCK(0), z80);
@@ -195,6 +249,10 @@ int main(int argc, char *argv[])
case MenuStickyOff:
SK_SetSticky(SK_SHIFT,0);
break;
+
+ case MenuMapJoypad:
+ SK_DisplayKeyboard(BG_GFX_SUB);
+ break;
}
SK_DisplayKeyboard(BG_GFX_SUB);
diff --git a/arm9/source/zx81.c b/arm9/source/zx81.c
index 0b7e729..6173701 100644
--- a/arm9/source/zx81.c
+++ b/arm9/source/zx81.c
@@ -19,7 +19,7 @@
-------------------------------------------------------------------------
- Provides the emulation for the ZX81
+ Provides the emulation for the zX81
*/
#include <stdlib.h>
@@ -29,6 +29,7 @@
#include <nds.h>
#include "zx81.h"
+#include "gui.h"
#include "zx81_bin.h"
@@ -40,6 +41,8 @@
#define FALSE 0
#endif
+#define MAX_FNAME_LEN 30
+
/* ---------------------------------------- STATICS
*/
@@ -86,6 +89,7 @@ static Z80Word RAMLEN=0;
/* Tape
*/
+static int enable_filesystem;
static const Z80Byte *tape_image;
static int tape_len;
@@ -244,17 +248,85 @@ static Z80Byte FromASCII(char c)
}
-static void LoadTape(Z80 *z80)
+/* Open a tape file the passed address
+*/
+static FILE *OpenTapeFile(Z80Word addr)
{
- if (tape_image)
+ FILE *fp;
+ char fn[MAX_FNAME_LEN];
+ int f;
+ int done;
+
+ f=0;
+ done=FALSE;
+
+ while(f<(MAX_FNAME_LEN-3) && !done)
+ {
+ int ch;
+
+ ch=mem[addr++];
+
+ if (ch&0x80)
+ {
+ done=TRUE;
+ ch&=0x7f;
+ }
+
+ switch(ch)
+ {
+ case 22:
+ fn[f++]='-';
+ break;
+
+ case 27:
+ fn[f++]='.';
+
+ default:
+ if (ch>=28 && ch<=37)
+ {
+ fn[f++]='0'+(ch-28);
+ }
+ else if (ch>=38 && ch<=63)
+ {
+ fn[f++]='A'+(ch-38);
+ }
+ break;
+ }
+ }
+
+ fn[f++]='.';
+ fn[f++]='P';
+ fn[f]=0;
+
+ if (!(fp=fopen(fn,"rb")))
{
- memcpy(mem+0x4009,tape_image,tape_len);
+ char full_fn[MAX_FNAME_LEN+11]="\\ZX81SNAP\\";
+
+ strcat(full_fn,fn);
+ fp=fopen(full_fn,"rb");
}
+
+ return fp;
}
-static void SaveTape(Z80 *z80)
+static void LoadInternalTape(Z80 *z80)
{
+ memcpy(mem+0x4009,tape_image,tape_len);
+}
+
+
+static void LoadExternalTape(FILE *tape, Z80 *z80)
+{
+ int c;
+ Z80Byte *a;
+
+ a=mem+0x4009;
+
+ while((c=getc(tape))!=EOF)
+ {
+ *a++=c;
+ }
}
@@ -371,7 +443,6 @@ static void ZX81HouseKeeping(Z80 *z80)
}
}
- /* if ((lastk1 || lastk2) && (lastk1!=prev_lk1 || lastk2!=prev_lk2)) */
if (lastk1 && (lastk1!=prev_lk1 || lastk2!=prev_lk2))
{
mem[CDFLAG]|=1;
@@ -429,11 +500,42 @@ static int EDCallback(Z80 *z80, Z80Val data)
switch((Z80Byte)data)
{
case ED_SAVE:
- SaveTape(z80);
break;
case ED_LOAD:
- LoadTape(z80);
+ /* Try and load the external file if a name given. Otherwise, we
+ try the internal one. Some of this is slightly dodgy -- it was
+ never intended for the emulator to be doing any GUI related
+ nonsense (like the alerts) but simply emulating.
+ */
+ if (enable_filesystem && z80->DE.w<0x8000)
+ {
+ FILE *fp;
+
+ if ((fp=OpenTapeFile(z80->DE.w)))
+ {
+ LoadExternalTape(fp,z80);
+ fclose(fp);
+ }
+ else
+ {
+ GUI_Alert(FALSE,"Couldn't open tape");
+ SK_DisplayKeyboard(BG_GFX_SUB);
+ }
+ }
+ else
+ {
+ if (tape_image)
+ {
+ LoadInternalTape(z80);
+ }
+ else
+ {
+ GUI_Alert(FALSE,"No tape image selected");
+ SK_DisplayKeyboard(BG_GFX_SUB);
+ }
+ }
+
mem[CDFLAG]=0xc0;
break;
@@ -629,6 +731,12 @@ void ZX81Reset(Z80 *z80)
}
+void ZX81EnableFileSystem(int enable)
+{
+ enable_filesystem=enable;
+}
+
+
void ZX81SetTape(const Z80Byte *image, int len)
{
tape_image=image;
diff --git a/include/gui.h b/include/gui.h
index 93557dc..4a07915 100644
--- a/include/gui.h
+++ b/include/gui.h
@@ -23,5 +23,6 @@
#define DS81_GUI_H
int GUI_Menu(const char *opts[]);
+void GUI_Alert(int fatal, const char *text);
#endif /* DS81_GUI_H */
diff --git a/include/zx81.h b/include/zx81.h
index 1f63f50..992cba7 100644
--- a/include/zx81.h
+++ b/include/zx81.h
@@ -39,6 +39,10 @@ void ZX81Init(uint16 *vram, Z80 *z80);
*/
void ZX81HandleKey(SoftKey k, int is_pressed);
+/* Enable fopen() loading of tape files
+*/
+void ZX81EnableFileSystem(int enable);
+
/* Set a file to load from tape
*/
void ZX81SetTape(const Z80Byte *image, int len);
diff --git a/source/gui.c b/source/gui.c
index 91c7f8d..713ad02 100644
--- a/source/gui.c
+++ b/source/gui.c
@@ -116,3 +116,76 @@ int GUI_Menu(const char *opts[])
return sel;
}
+
+void GUI_Alert(int fatal, const char *text)
+{
+ char line[80];
+ int h;
+ const char *p;
+ char *d;
+
+ h=40;
+ p=text;
+
+ while(*p)
+ {
+ if (*p++=='\n')
+ {
+ h+=8;
+ }
+ }
+
+ FB_FillBox(0,0,SCREEN_WIDTH,h,FB_RGB(0,0,0));
+ FB_Box(1,1,SCREEN_WIDTH-2,h-2,FB_RGB(31,0,0));
+
+ p=text;
+ h=4;
+ d=line;
+
+ while(*p)
+ {
+ if (*p=='\n')
+ {
+ *d++=0;
+ p++;
+ FB_Centre(line,h,FB_RGB(31,31,31),-1);
+ h+=8;
+ d=line;
+ }
+ else
+ {
+ *d++=*p++;
+ }
+ }
+
+ if (d>line)
+ {
+ *d=0;
+ FB_Centre(line,h,FB_RGB(31,31,31),-1);
+ h+=8;
+ }
+
+ if (!fatal)
+ {
+ FB_Centre("PRESS ANY BUTTON OR SCREEN",h+16,FB_RGB(31,31,0),-1);
+
+ while(!keysDown())
+ {
+ swiWaitForVBlank();
+ }
+
+ while(keysHeld())
+ {
+ swiWaitForVBlank();
+ }
+ }
+ else
+ {
+ FB_Centre("PLEASE RESET YOUR CONSOLE",h+16,FB_RGB(31,31,0),-1);
+
+ while(1)
+ {
+ swiWaitForVBlank();
+ }
+ }
+}
diff --git a/source/main.c b/source/main.c
index 1da90c2..1a3aa8c 100644
--- a/source/main.c
+++ b/source/main.c
@@ -22,7 +22,9 @@
#include <stdlib.h>
#include <stdio.h>
+#include <string.h>
#include <nds.h>
+#include <fat.h>
#include "framebuffer.h"
#include "gui.h"
@@ -42,6 +44,7 @@ static const char *main_menu[]=
"Select Tape",
"Sticky Shift On",
"Sticky Shift Off",
+ "Map Joypad to Keys",
"Cancel",
NULL
};
@@ -52,6 +55,7 @@ typedef enum
MenuSelectTape,
MenuStickyOn,
MenuStickyOff,
+ MenuMapJoypad
} MenuOpt;
@@ -74,11 +78,17 @@ static void Splash(void)
"PRESS A TO CONTINUE",
" ",
"http://www.noddybox.co.uk/",
+ " ",
+ " ",
+ " ",
+ " ",
+ "Checking for FAT device...",
NULL
};
sImage img;
int f;
+ int y;
FB_Clear();
@@ -87,9 +97,53 @@ static void Splash(void)
FB_Blit(&img,0,0);
+ y=10;
+
for(f=0;text[f];f++)
{
- FB_Centre(text[f],10+f*8,FB_RGB(31,31,31),-1);
+ FB_Centre(text[f],y,FB_RGB(31,31,31),-1);
+ y+=8;
+ }
+
+ y+=8;
+
+ if (fatInitialise(32,true))
+ {
+ ZX81EnableFileSystem(TRUE);
+
+ FB_Centre("Found a FAT device.",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("If you place .P tape files in",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("the top directory or ZX81TAPE",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("then you should be able to load",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("GAME.P with the command",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("LOAD \"GAME\"",y,FB_RGB(31,31,31),-1);
+ y+=8;
+ }
+ else
+ {
+ ZX81EnableFileSystem(FALSE);
+
+ FB_Centre("Sorry, but you don't have a",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("supported FAT device.",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("Only the internal tape",y,FB_RGB(31,31,31),-1);
+ y+=8;
+
+ FB_Centre("files can be used.",y,FB_RGB(31,31,31),-1);
+ y+=8;
}
ZX81DisplayString("10 print '%the zx81 is ace%'\n20 goto 10");
@@ -153,7 +207,7 @@ int main(int argc, char *argv[])
if (!z80)
{
- return EXIT_FAILURE;
+ GUI_Alert(TRUE,"Failed to initialise\nthe Z80 CPU emulation!");
}
ZX81Init((uint16*)SCREEN_BASE_BLOCK(0), z80);
@@ -195,6 +249,10 @@ int main(int argc, char *argv[])
case MenuStickyOff:
SK_SetSticky(SK_SHIFT,0);
break;
+
+ case MenuMapJoypad:
+ SK_DisplayKeyboard(BG_GFX_SUB);
+ break;
}
SK_DisplayKeyboard(BG_GFX_SUB);
diff --git a/source/zx81.c b/source/zx81.c
index 0b7e729..6173701 100644
--- a/source/zx81.c
+++ b/source/zx81.c
@@ -19,7 +19,7 @@
-------------------------------------------------------------------------
- Provides the emulation for the ZX81
+ Provides the emulation for the zX81
*/
#include <stdlib.h>
@@ -29,6 +29,7 @@
#include <nds.h>
#include "zx81.h"
+#include "gui.h"
#include "zx81_bin.h"
@@ -40,6 +41,8 @@
#define FALSE 0
#endif
+#define MAX_FNAME_LEN 30
+
/* ---------------------------------------- STATICS
*/
@@ -86,6 +89,7 @@ static Z80Word RAMLEN=0;
/* Tape
*/
+static int enable_filesystem;
static const Z80Byte *tape_image;
static int tape_len;
@@ -244,17 +248,85 @@ static Z80Byte FromASCII(char c)
}
-static void LoadTape(Z80 *z80)
+/* Open a tape file the passed address
+*/
+static FILE *OpenTapeFile(Z80Word addr)
{
- if (tape_image)
+ FILE *fp;
+ char fn[MAX_FNAME_LEN];
+ int f;
+ int done;
+
+ f=0;
+ done=FALSE;
+
+ while(f<(MAX_FNAME_LEN-3) && !done)
+ {
+ int ch;
+
+ ch=mem[addr++];
+
+ if (ch&0x80)
+ {
+ done=TRUE;
+ ch&=0x7f;
+ }
+
+ switch(ch)
+ {
+ case 22:
+ fn[f++]='-';
+ break;
+
+ case 27:
+ fn[f++]='.';
+
+ default:
+ if (ch>=28 && ch<=37)
+ {
+ fn[f++]='0'+(ch-28);
+ }
+ else if (ch>=38 && ch<=63)
+ {
+ fn[f++]='A'+(ch-38);
+ }
+ break;
+ }
+ }
+
+ fn[f++]='.';
+ fn[f++]='P';
+ fn[f]=0;
+
+ if (!(fp=fopen(fn,"rb")))
{
- memcpy(mem+0x4009,tape_image,tape_len);
+ char full_fn[MAX_FNAME_LEN+11]="\\ZX81SNAP\\";
+
+ strcat(full_fn,fn);
+ fp=fopen(full_fn,"rb");
}
+
+ return fp;
}
-static void SaveTape(Z80 *z80)
+static void LoadInternalTape(Z80 *z80)
{
+ memcpy(mem+0x4009,tape_image,tape_len);
+}
+
+
+static void LoadExternalTape(FILE *tape, Z80 *z80)
+{
+ int c;
+ Z80Byte *a;
+
+ a=mem+0x4009;
+
+ while((c=getc(tape))!=EOF)
+ {
+ *a++=c;
+ }
}
@@ -371,7 +443,6 @@ static void ZX81HouseKeeping(Z80 *z80)
}
}
- /* if ((lastk1 || lastk2) && (lastk1!=prev_lk1 || lastk2!=prev_lk2)) */
if (lastk1 && (lastk1!=prev_lk1 || lastk2!=prev_lk2))
{
mem[CDFLAG]|=1;
@@ -429,11 +500,42 @@ static int EDCallback(Z80 *z80, Z80Val data)
switch((Z80Byte)data)
{
case ED_SAVE:
- SaveTape(z80);
break;
case ED_LOAD:
- LoadTape(z80);
+ /* Try and load the external file if a name given. Otherwise, we
+ try the internal one. Some of this is slightly dodgy -- it was
+ never intended for the emulator to be doing any GUI related
+ nonsense (like the alerts) but simply emulating.
+ */
+ if (enable_filesystem && z80->DE.w<0x8000)
+ {
+ FILE *fp;
+
+ if ((fp=OpenTapeFile(z80->DE.w)))
+ {
+ LoadExternalTape(fp,z80);
+ fclose(fp);
+ }
+ else
+ {
+ GUI_Alert(FALSE,"Couldn't open tape");
+ SK_DisplayKeyboard(BG_GFX_SUB);
+ }
+ }
+ else
+ {
+ if (tape_image)
+ {
+ LoadInternalTape(z80);
+ }
+ else
+ {
+ GUI_Alert(FALSE,"No tape image selected");
+ SK_DisplayKeyboard(BG_GFX_SUB);
+ }
+ }
+
mem[CDFLAG]=0xc0;
break;
@@ -629,6 +731,12 @@ void ZX81Reset(Z80 *z80)
}
+void ZX81EnableFileSystem(int enable)
+{
+ enable_filesystem=enable;
+}
+
+
void ZX81SetTape(const Z80Byte *image, int len)
{
tape_image=image;