summaryrefslogtreecommitdiff
path: root/arm9/source
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2006-10-09 00:32:14 +0000
committerIan C <ianc@noddybox.co.uk>2006-10-09 00:32:14 +0000
commita50b3820e29af6d12b86c55afb8be1aee9091558 (patch)
treea3e74e4706488db0701bc992b1eb75e29d52e7a1 /arm9/source
parent09a74c822519bae9d20f79b8e7808f19c5094e7f (diff)
Working version with a few games included
Diffstat (limited to 'arm9/source')
-rw-r--r--arm9/source/framebuffer.c19
-rw-r--r--arm9/source/main.c20
-rw-r--r--arm9/source/tapes.c175
-rw-r--r--arm9/source/zx81.c117
4 files changed, 290 insertions, 41 deletions
diff --git a/arm9/source/framebuffer.c b/arm9/source/framebuffer.c
index 26b95de..22a4e12 100644
--- a/arm9/source/framebuffer.c
+++ b/arm9/source/framebuffer.c
@@ -253,3 +253,22 @@ void FB_Clear(void)
*p++=0x8000;
}
}
+
+
+void FB_Blit(sImage *img, int x, int y)
+{
+ if (img->width==WIDTH && img->height==HEIGHT)
+ {
+ dmaCopy(img->data8,buff,SCREEN_WIDTH*SCREEN_HEIGHT*2);
+ }
+ else
+ {
+ int f;
+
+ for(f=0;f<img->height;f++)
+ {
+ dmaCopy(img->data16+(f*img->width),
+ buff+x+(y+f)*WIDTH,img->width*2);
+ }
+ }
+}
diff --git a/arm9/source/main.c b/arm9/source/main.c
index 43c8993..78d40c1 100644
--- a/arm9/source/main.c
+++ b/arm9/source/main.c
@@ -29,6 +29,7 @@
#include "keyboard.h"
#include "z80.h"
#include "zx81.h"
+#include "tapes.h"
#include "splashimg_bin.h"
#include "rom_font_bin.h"
@@ -38,8 +39,9 @@
static const char *main_menu[]=
{
"Reset ZX81",
- "Sticky Keys On",
- "Sticky Keys Off",
+ "Select Tape",
+ "Sticky Shift On",
+ "Sticky Shift Off",
"Define Joystick",
"Cancel",
NULL
@@ -48,6 +50,7 @@ static const char *main_menu[]=
typedef enum
{
MenuReset,
+ MenuSelectTape,
MenuStickyOn,
MenuStickyOff,
MenuDefineJoystick
@@ -89,13 +92,16 @@ static void Splash(void)
loadPCX(splashimg_bin,&img);
image8to16(&img);
- dmaCopy(img.data8,BG_GFX_SUB,SCREEN_WIDTH*SCREEN_HEIGHT*2);
+
+ FB_Blit(&img,0,0);
for(f=0;text[f];f++)
{
FB_Centre(text[f],40+f*8,FB_RGB(31,31,31),-1);
}
+ ZX81DisplayString("10 print '%the zx81 is ace%'\n20 goto 10");
+
while(!(keysDown() & KEY_A))
{
swiWaitForVBlank();
@@ -147,8 +153,6 @@ int main(int argc, char *argv[])
FB_Init(BG_GFX_SUB);
- Splash();
-
z80 = Z80Init(ZX81ReadMem,
ZX81WriteMem,
ZX81ReadPort,
@@ -162,6 +166,8 @@ int main(int argc, char *argv[])
ZX81Init((uint16*)SCREEN_BASE_BLOCK(0), z80);
+ Splash();
+
SK_DisplayKeyboard(BG_GFX_SUB);
SK_SetSticky(SK_SHIFT,1);
@@ -186,6 +192,10 @@ int main(int argc, char *argv[])
ZX81Reset(z80);
break;
+ case MenuSelectTape:
+ SelectTape();
+ break;
+
case MenuStickyOn:
SK_SetSticky(SK_SHIFT,1);
break;
diff --git a/arm9/source/tapes.c b/arm9/source/tapes.c
new file mode 100644
index 0000000..adac3b6
--- /dev/null
+++ b/arm9/source/tapes.c
@@ -0,0 +1,175 @@
+/*
+ ds81 - Nintendo DS ZX81 emulator.
+
+ Copyright (C) 2006 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 <nds.h>
+
+#include "tapes.h"
+#include "framebuffer.h"
+#include "zx81.h"
+
+#include "maze_bin.h"
+#include "maze_inlay_bin.h"
+#include "cpatrol_bin.h"
+#include "cpatrol_inlay_bin.h"
+#include "sabotage_bin.h"
+#include "sabotage_inlay_bin.h"
+
+
+/* ---------------------------------------- STATIC DATA
+*/
+typedef struct
+{
+ const u8 *tape;
+ const u32 *tape_len;
+ sImage img;
+ void *source_pcx;
+ const char *text;
+} Tape;
+
+#define NO_TAPES 3
+
+static Tape tapes[NO_TAPES]=
+ {
+ {
+ maze_bin,
+ &maze_bin_size,
+ {0},
+ maze_inlay_bin,
+ "%3d monster maze%\n"
+ "(c) 1983 Malcom E. Evans\n\n"
+ "Escape the maze and its T-Rex\n"
+ "\n\n"
+ "%note% when the screen goes grey\n"
+ "for 30-60 seconds this is not a\n"
+ "problem, and is the game creating\n"
+ "the lair of rex."
+ },
+ {
+ cpatrol_bin,
+ &cpatrol_bin_size,
+ {0},
+ cpatrol_inlay_bin,
+ "%city patrol%\n"
+ "(c) 1982 Don Priestley\n\n"
+ "Defend the city from the aliens.\n\n"
+ "yes - that parallax city was\n"
+ "done with a text mode and the\n"
+ "equivalent of a 0.8mhz z80"
+ },
+ {
+ sabotage_bin,
+ &sabotage_bin_size,
+ {0},
+ sabotage_inlay_bin,
+ "%sabotage%\n"
+ "(c) 1982 Don Priestley\n\n"
+ "Destroy the boxes before the\n"
+ "guard finds you.\n\n"
+ "or find the saboteur as the\n"
+ "guard.\n\n"
+ "while this game may not feature\n"
+ "the dazzling graphics of other\n"
+ "ZX81 games it more than makes\n"
+ "up with a simply joyous\n"
+ "gameplay mechanic.\n"
+ }
+ };
+
+
+static int current=0;
+
+/* ---------------------------------------- PRIVATE INTERFACES
+*/
+static void InitTapes(void)
+{
+ static int init=FALSE;
+ int f;
+
+ if (init)
+ {
+ return;
+ }
+
+ init=TRUE;
+
+ for(f=0;f<NO_TAPES;f++)
+ {
+ loadPCX(tapes[f].source_pcx,&tapes[f].img);
+ image8to16(&tapes[f].img);
+ }
+}
+
+static void DisplayTape(Tape *t)
+{
+ FB_Clear();
+ FB_Blit(&t->img,255-t->img.width,0);
+
+ FB_Print("LEFT/RIGHT",0,0,FB_RGB(255,255,255),-1);
+ FB_Print("to choose",0,10,FB_RGB(255,255,255),-1);
+ FB_Print("A to select",0,30,FB_RGB(255,255,255),-1);
+ FB_Print("B to cancel",0,40,FB_RGB(255,255,255),-1);
+
+ ZX81DisplayString(t->text);
+}
+
+/* ---------------------------------------- PUBLIC INTERFACES
+*/
+void SelectTape(void)
+{
+ int done=FALSE;
+
+ InitTapes();
+
+ while(!done)
+ {
+ uint32 key=0;
+
+ DisplayTape(tapes+current);
+
+ do
+ {
+ swiWaitForVBlank();
+ } while(!(key=keysDownRepeat()));
+
+ if (key & KEY_LEFT)
+ {
+ if (--current<0)
+ {
+ current=NO_TAPES-1;
+ }
+ }
+ else if (key & KEY_RIGHT)
+ {
+ current=(current+1)%NO_TAPES;
+ }
+ else if (key & KEY_A)
+ {
+ done=TRUE;
+ ZX81SetTape(tapes[current].tape,*tapes[current].tape_len);
+ }
+ else if (key & KEY_B)
+ {
+ done=TRUE;
+ }
+ }
+}
+
diff --git a/arm9/source/zx81.c b/arm9/source/zx81.c
index 5b8f6b7..2b81e2b 100644
--- a/arm9/source/zx81.c
+++ b/arm9/source/zx81.c
@@ -25,12 +25,12 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
#include <nds.h>
#include "zx81.h"
#include "zx81_bin.h"
-#include "maze_bin.h"
#ifndef TRUE
#define TRUE 1
@@ -84,6 +84,11 @@ static Z80Word RAMLEN=0;
#define WORD(a) (mem[a] | (Z80Word)mem[a+1]<<8)
+/* Tape
+*/
+static const Z80Byte *tape_image;
+static int tape_len;
+
/* GFX vars
*/
static uint16 *screen;
@@ -199,58 +204,52 @@ static void RomPatch(void)
mem[0x02ec]=0;
}
-static char ToASCII(Z80Byte b)
+static Z80Byte FromASCII(char c)
{
- if (b==0) /* SPACE */
- return ' ';
-
- if (b==22) /* Dash (-) */
- return '-';
-
- if (b==27) /* Period (.) */
- return '.';
-
- if (b>=28 && b<=37) /* 0-9 */
- return '0'+b-28;
+ switch(c)
+ {
+ case '\'':
+ case '"':
+ return 11;
- if (b>=38 && b<=63) /* A-Z */
- return 'a'+b-38;
+ case '(':
+ return 16;
- return 0;
-}
+ case ')':
+ return 17;
+ case '-':
+ return 22;
-static const char *ConvertFilename(Z80Word addr)
-{
- static char buff[FILENAME_MAX];
- char *p;
+ case '*':
+ return 23;
- p=buff;
- *p=0;
+ case ',':
+ return 26;
- if (addr>0x8000)
- {
- return buff;
+ case '.':
+ return 27;
}
- do
- {
- char c=ToASCII(mem[addr]&0x7f);
+ if (c>='0' && c<='9')
+ return (c-'0')+28;
- if (c)
- *p++=c;
+ if (c>='a' && c<='z')
+ return (c-'a')+38;
- } while(mem[addr++]<0x80);
+ if (c>='A' && c<='Z')
+ return (c-'A')+38;
- *p=0;
-
- return buff;
+ return 0;
}
static void LoadTape(Z80 *z80)
{
- memcpy(mem+0x4009,maze_bin,maze_bin_size);
+ if (tape_image)
+ {
+ memcpy(mem+0x4009,tape_image,tape_len);
+ }
}
@@ -630,4 +629,50 @@ void ZX81Reset(Z80 *z80)
}
+void ZX81SetTape(const Z80Byte *image, int len)
+{
+ tape_image=image;
+ tape_len=len;
+}
+
+
+void ZX81DisplayString(const char *p)
+{
+ uint16 *s;
+ uint16 inv=0;
+ int f;
+
+ s = screen;
+
+ for(f=0;f<TXT_W*TXT_H;f++)
+ {
+ *s++=0;
+ }
+
+ s = screen;
+ f = 0;
+
+ while(*p)
+ {
+ switch(*p)
+ {
+ case '\n':
+ s+=32;
+ f=0;
+ break;
+
+ case '%':
+ inv^=0x40;
+ break;
+
+ default:
+ s[f++]=FromASCII(*p)|inv;
+ break;
+ }
+
+ p++;
+ }
+}
+
+
/* END OF FILE */