summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2007-03-01 00:36:54 +0000
committerIan C <ianc@noddybox.co.uk>2007-03-01 00:36:54 +0000
commit6be2806499299bb13edde3481803f28416429902 (patch)
treeee80944e5af4f9ab002fb91c73f032ee6d385de8
parentb7fc2934d2cd1e593fe5d1c99678321a21d0948d (diff)
Changed lower screen to 8-bits and added overlayed text mode. Monitor stub in place. Text mode helpers being developed.
-rw-r--r--CHANGES3
-rw-r--r--data/cpatrol_inlay.binbin28889 -> 7485 bytes
-rw-r--r--data/keyb.binbin16390 -> 13447 bytes
-rw-r--r--data/maze_inlay.binbin32392 -> 10654 bytes
-rw-r--r--data/mazogs_inlay.binbin36155 -> 15329 bytes
-rw-r--r--data/sabotage_inlay.binbin26323 -> 12794 bytes
-rw-r--r--data/splashimg.binbin23615 -> 19171 bytes
-rw-r--r--include/framebuffer.h69
-rw-r--r--include/monitor.h27
-rw-r--r--include/textmode.h37
-rw-r--r--include/z80_config.h2
-rw-r--r--include/zx81.h2
-rw-r--r--source/framebuffer.c193
-rw-r--r--source/gui.c70
-rw-r--r--source/keyboard.c18
-rw-r--r--source/main.c105
-rw-r--r--source/monitor.c32
-rw-r--r--source/tapes.c19
-rw-r--r--source/textmode.c146
19 files changed, 578 insertions, 145 deletions
diff --git a/CHANGES b/CHANGES
index 9a0170f..513e4a5 100644
--- a/CHANGES
+++ b/CHANGES
@@ -34,3 +34,6 @@ Changes from V1.1a to V1.2
+ Added file selector with LOAD "*"
+ Handling of 1K display files is a bit better.
+ Added option for RAM in place of ROM mirror.
+ + Changed lower screen to 8-bit deep so I can overlay a tiled mode.
+ * Added lower screen console routines.
+ * Added Machine Code Monitor.
diff --git a/data/cpatrol_inlay.bin b/data/cpatrol_inlay.bin
index af70c60..6349d6f 100644
--- a/data/cpatrol_inlay.bin
+++ b/data/cpatrol_inlay.bin
Binary files differ
diff --git a/data/keyb.bin b/data/keyb.bin
index 3759ec5..adbfd5d 100644
--- a/data/keyb.bin
+++ b/data/keyb.bin
Binary files differ
diff --git a/data/maze_inlay.bin b/data/maze_inlay.bin
index 26a7e97..d48cb22 100644
--- a/data/maze_inlay.bin
+++ b/data/maze_inlay.bin
Binary files differ
diff --git a/data/mazogs_inlay.bin b/data/mazogs_inlay.bin
index a725c57..1088716 100644
--- a/data/mazogs_inlay.bin
+++ b/data/mazogs_inlay.bin
Binary files differ
diff --git a/data/sabotage_inlay.bin b/data/sabotage_inlay.bin
index da3f094..904c29a 100644
--- a/data/sabotage_inlay.bin
+++ b/data/sabotage_inlay.bin
Binary files differ
diff --git a/data/splashimg.bin b/data/splashimg.bin
index 38161e4..de16798 100644
--- a/data/splashimg.bin
+++ b/data/splashimg.bin
Binary files differ
diff --git a/include/framebuffer.h b/include/framebuffer.h
index 7b04685..3055e51 100644
--- a/include/framebuffer.h
+++ b/include/framebuffer.h
@@ -22,17 +22,64 @@
#ifndef DS81_FRAMEBUFFER_H
#define DS81_FRAMEBUFFER_H
-#define FB_RGB(r,g,b) ((RGB15(r,g,b))|0x8000)
-
-void FB_Init(uint16 *vram);
-void FB_Print(const char *text, int x, int y, int colour, int paper);
-void FB_Centre(const char *text, int y, int colour, int paper);
-void FB_printf(int x, int y, int colour, int paper, const char *format, ...);
-void FB_HLine(int x1, int x2, int y, int colour);
-void FB_VLine(int x, int y1, int y2, int colour);
-void FB_Box(int x, int y, int w, int h, int colour);
-void FB_FillBox(int x, int y, int w, int h, int colour);
+/* Predefined colours.
+*/
+typedef enum
+{
+ COL_TRANSPARENT = -1,
+ COL_BLACK = 0,
+ COL_WHITE = 240,
+ COL_RED = 241,
+ COL_GREEN = 242,
+ COL_BLUE = 243,
+ COL_GUISELECT = 244,
+ COL_GREY = 245,
+ COL_LIGHTGREY = 246,
+ COL_DARKGREY = 247,
+ COL_YELLOW = 248
+} FB_Colour;
+
+
+/* Initialise 'framebuffer' code. vram is where the 8-bit framebuffer is.
+ palette is the palette to use/set.
+*/
+void FB_Init(uint16 *vram, uint16 *palette);
+
+/* Load the internal framebuffer font as a set of ASCII tiles (starting with
+ space) at tiles. The tiles will use colour COL_WHITE.
+*/
+void FB_LoadASCIITiles(uint16 *tiles);
+
+/* Print the text into the framebuffer.
+*/
+void FB_Print(const char *text, int x, int y,
+ FB_Colour colour, FB_Colour paper);
+void FB_Centre(const char *text, int y,
+ FB_Colour colour, FB_Colour paper);
+void FB_printf(int x, int y, FB_Colour colour, FB_Colour paper,
+ const char *format, ...);
+
+/* Lines and boxes.
+*/
+void FB_HLine(int x1, int x2, int y, FB_Colour colour);
+void FB_VLine(int x, int y1, int y2, FB_Colour colour);
+void FB_Box(int x, int y, int w, int h, FB_Colour colour);
+void FB_FillBox(int x, int y, int w, int h, FB_Colour colour);
+
+/* Clear to background
+*/
void FB_Clear(void);
-void FB_Blit(sImage *img, int x, int y);
+
+/* Draw the image. The image must be an 8-bit image, but with only the first
+ 16 palette entries used. Just to complicate matters!
+
+ The image is assumed to be an even number of pixels wide. Also the passed
+ X co-ord will be forced even.
+
+ offset is used to give an offset into the palette to place colours from the
+ image. Palette entries 1 - 128 will always be safe to use (these routines
+ will never use them).
+*/
+void FB_Blit(sImage *img, int x, int y, int offset);
#endif /* DS81_FRAMEBUFFER_H */
diff --git a/include/monitor.h b/include/monitor.h
new file mode 100644
index 0000000..5bbdc8b
--- /dev/null
+++ b/include/monitor.h
@@ -0,0 +1,27 @@
+/*
+ ds81 - Nintendo DS ZX81 emulator.
+
+ Copyright (C) 2007 Ian Cowburn <ianc@noddybox.co.uk>
+
+ 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$
+*/
+#ifndef DS81_MONITOR_H
+#define DS81_MONITOR_H
+
+void MachineCodeMonitor(void);
+
+#endif /* DS81_MONITOR_H */
diff --git a/include/textmode.h b/include/textmode.h
new file mode 100644
index 0000000..751ad05
--- /dev/null
+++ b/include/textmode.h
@@ -0,0 +1,37 @@
+/*
+ ds81 - Nintendo DS ZX81 emulator.
+
+ Copyright (C) 2007 Ian Cowburn <ianc@noddybox.co.uk>
+
+ 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$
+*/
+#ifndef DS81_TEXTMODE_H
+#define DS81_TEXTMODE_H
+
+/* Note that the co-ords are into the map -- the user is free to use this and
+ move the map around, scale it, blend it, do want they want with it...
+
+ The routines assume they can write into this map using the ASCII code
+ with 32 subtracted for each char.
+*/
+void TM_Init(uint16 *vram, int map_width, int map_height, int map_is_rotation);
+
+void TM_Cls(void);
+void TM_Put(int x, int y, const char *str);
+void TM_printf(int x, int y, const char *format, ...);
+
+#endif /* DS81_TEXTMODE_H */
diff --git a/include/z80_config.h b/include/z80_config.h
index 8be062b..af36944 100644
--- a/include/z80_config.h
+++ b/include/z80_config.h
@@ -34,8 +34,8 @@
/* Define this to enable the disassembly interface
-#define ENABLE_DISASSEM
*/
+#define ENABLE_DISASSEM
/* Define this to enable the array-based memory model. In this mode
diff --git a/include/zx81.h b/include/zx81.h
index c50c1a4..2606c98 100644
--- a/include/zx81.h
+++ b/include/zx81.h
@@ -77,6 +77,8 @@ void ZX81WriteMem(Z80 *z80, Z80Word addr, Z80Byte val);
Z80Byte ZX81ReadPort(Z80 *z80, Z80Word port);
void ZX81WritePort(Z80 *z80, Z80Word port, Z80Byte val);
+#define ZX81ReadDisassem ZX81ReadMem
+
#endif
diff --git a/source/framebuffer.c b/source/framebuffer.c
index 691862e..6d16529 100644
--- a/source/framebuffer.c
+++ b/source/framebuffer.c
@@ -25,12 +25,16 @@
#include <stdarg.h>
#include <string.h>
+#include "framebuffer.h"
+
/* ---------------------------------------- STATIC DATA
*/
#define WIDTH 256
+#define SCAN 128
#define HEIGHT 192
-static uint16 *buff=0;
+static uint16 *buff;
+static uint16 *pal;
static uint8 font[]=
{
@@ -132,60 +136,138 @@ static uint8 font[]=
0x3c, 0x42, 0x99, 0x85, 0x85, 0x99, 0x42, 0x3c
};
+
+/* ---------------------------------------- PRIVATE INTERFACES
+*/
+static inline void Plot(int x, int y, int col)
+{
+ uint16 *base;
+ uint16 cur;
+ int odd;
+
+ if (col == -1)
+ return;
+
+ odd = x&1;
+ x /= 2;
+
+ base = buff+x+y*SCAN;
+ cur = *base;
+
+ if (odd)
+ {
+ cur = (cur & 0xff) | (col<<8);
+ }
+ else
+ {
+ cur = (cur & 0xff00) | col;
+ }
+
+ *base = cur;
+}
+
+
/* ---------------------------------------- PUBLIC INTERFACES
*/
-void FB_Init(uint16 *vram)
+void FB_Init(uint16 *vram, uint16 *palette)
{
- buff=vram;
+ buff = vram;
+ pal = palette;
+
+ pal[COL_BLACK] = RGB15(0,0,0);
+ pal[COL_WHITE] = RGB15(31,31,31);
+ pal[COL_RED] = RGB15(31,0,0);
+ pal[COL_GREEN] = RGB15(0,31,0);
+ pal[COL_BLUE] = RGB15(0,0,31);
+ pal[COL_GUISELECT] = RGB15(8,8,31);
+ pal[COL_GREY] = RGB15(15,15,15);
+ pal[COL_LIGHTGREY] = RGB15(22,22,22);
+ pal[COL_DARKGREY] = RGB15(8,8,8);
+ pal[COL_YELLOW] = RGB15(31,31,0);
}
-void FB_Print(const char *text, int x, int y, int colour, int paper)
+void FB_LoadASCIITiles(uint16 *tiles)
{
- uint16 *base;
+ uint8 *src;
+ int c;
+ int row;
+ int val;
+ int mask;
- base=buff+y*WIDTH+x;
+ src = font;
- while(*text)
+ for(c = 32; c < 127; c++)
{
- int x,y;
- int ch;
+ for(row = 0; row < 8; row++)
+ {
+ for(mask = 1; mask < 0xff; mask<<=1)
+ {
+ if (*src & mask)
+ {
+ val = COL_WHITE;
+ }
+ else
+ {
+ val = 0;
+ }
+
+ mask <<= 1;
+
+ if (*src & mask)
+ {
+ val |= COL_WHITE << 8;
+ }
+
+ *tiles++ = val;
+ }
+
+ src++;
+ }
+ }
+}
+
+void FB_Print(const char *text, int x, int y, FB_Colour colour, FB_Colour paper)
+{
+ int cx,cy;
+ int ch;
+
+ while(*text)
+ {
ch=((*text)-32)*8;
- for(y=0;y<8;y++)
+ for(cy=0;cy<8;cy++)
{
- for(x=0;x<8;x++)
+ for(cx=0;cx<8;cx++)
{
- if (font[ch]&(1<<x))
+ if (font[ch]&(1<<cx))
{
- *(base+x+y*WIDTH)=colour;
+ Plot(x+cx, y+cy, colour);
}
else
{
- if (paper!=-1)
- {
- *(base+x+y*WIDTH)=paper;
- }
+ Plot(x+cx, y+cy, paper);
}
}
ch++;
}
- base+=8;
+ x+=8;
text++;
}
}
-void FB_Centre(const char *text, int y, int colour, int paper)
+void FB_Centre(const char *text, int y, FB_Colour colour, FB_Colour paper)
{
FB_Print(text,WIDTH/2-strlen(text)*4,y,colour,paper);
}
-void FB_printf(int x, int y, int colour, int paper, const char *format, ...)
+void FB_printf(int x, int y, FB_Colour colour, FB_Colour paper,
+ const char *format, ...)
{
char buff[80];
va_list va;
@@ -198,7 +280,7 @@ void FB_printf(int x, int y, int colour, int paper, const char *format, ...)
}
-void FB_HLine(int x1, int x2, int y, int colour)
+void FB_HLine(int x1, int x2, int y, FB_Colour colour)
{
uint16 *line;
@@ -206,28 +288,21 @@ void FB_HLine(int x1, int x2, int y, int colour)
while(x1<=x2)
{
- *line++=colour;
- x1++;
+ Plot(x1++,y,colour);
}
}
-void FB_VLine(int x, int y1, int y2, int colour)
+void FB_VLine(int x, int y1, int y2, FB_Colour colour)
{
- uint16 *line;
-
- line=buff+y1*WIDTH+x;
-
while(y1<=y2)
{
- *line=colour;
- line+=WIDTH;
- y1++;
+ Plot(x,y1++,colour);
}
}
-void FB_Box(int x, int y, int w, int h, int colour)
+void FB_Box(int x, int y, int w, int h, FB_Colour colour)
{
FB_HLine(x,x+w-1,y,colour);
FB_HLine(x,x+w-1,y+h-1,colour);
@@ -236,21 +311,11 @@ void FB_Box(int x, int y, int w, int h, int colour)
}
-void FB_FillBox(int x, int y, int w, int h, int colour)
+void FB_FillBox(int x, int y, int w, int h, FB_Colour colour)
{
- int f;
- uint16 *base;
-
- base=buff+x+y*WIDTH;
-
while(h--)
{
- for(f=0;f<w;f++)
- {
- *(base+f)=colour;
- }
-
- base+=WIDTH;
+ FB_HLine(x,x+w-1,y++,colour);
}
}
@@ -260,30 +325,50 @@ void FB_Clear(void)
uint16 *p;
int f;
- f=WIDTH*HEIGHT;
+ f=WIDTH*HEIGHT/2;
p=buff;
while(f--)
{
- *p++=0x8000;
+ *p++=0;
}
}
-void FB_Blit(sImage *img, int x, int y)
+void FB_Blit(sImage *img, int x, int y, int offset)
{
- if (img->width==WIDTH && img->height==HEIGHT)
+ uint16 *dest;
+ uint16 *row;
+ uint8 *src;
+ uint16 pix;
+ int hww;
+ int ht;
+ int f;
+
+ x /= 2;
+
+ ht = img->height;
+ hww = img->width / 2;
+ dest = buff+x+y*SCAN;
+ src = img->image.data8;
+
+ for(f=0;f<16;f++)
{
- dmaCopy(img->image.data8,buff,SCREEN_WIDTH*SCREEN_HEIGHT*2);
+ pal[offset+f] = img->palette[f];
}
- else
+
+ while(ht--)
{
- int f;
+ row = dest;
- for(f=0;f<img->height;f++)
+ for(f=0;f<hww;f++)
{
- dmaCopy(img->image.data16+(f*img->width),
- buff+x+(y+f)*WIDTH,img->width*2);
+ pix = *src++ + offset;
+ pix |= (*src++ + offset) << 8;
+
+ *row++ = pix;
}
+
+ dest += SCAN;
}
}
diff --git a/source/gui.c b/source/gui.c
index 92f6836..2027a37 100644
--- a/source/gui.c
+++ b/source/gui.c
@@ -219,13 +219,13 @@ int GUI_Menu(const char *opts[])
{
uint32 key=0;
- FB_FillBox(x,y,w,h,FB_RGB(0,0,0));
- FB_Box(x,y,w,h,FB_RGB(31,31,31));
- FB_FillBox(x+1,y+sel*16+1,w-2,14,FB_RGB(8,8,31));
+ FB_FillBox(x,y,w,h,COL_BLACK);
+ FB_Box(x,y,w,h,COL_WHITE);
+ FB_FillBox(x+1,y+sel*16+1,w-2,14,COL_GUISELECT);
for(f=0;f<no;f++)
{
- FB_Centre(opts[f],y+4+f*16,FB_RGB(31,31,31),-1);
+ FB_Centre(opts[f],y+4+f*16,COL_WHITE,COL_TRANSPARENT);
}
do
@@ -290,8 +290,8 @@ void GUI_Alert(int fatal, const char *text)
}
}
- 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));
+ FB_FillBox(0,0,SCREEN_WIDTH,h,COL_BLACK);
+ FB_Box(1,1,SCREEN_WIDTH-2,h-2,COL_WHITE);
p=text;
h=4;
@@ -303,7 +303,7 @@ void GUI_Alert(int fatal, const char *text)
{
*d++=0;
p++;
- FB_Centre(line,h,FB_RGB(31,31,31),-1);
+ FB_Centre(line,h,COL_WHITE,COL_TRANSPARENT);
h+=8;
d=line;
}
@@ -316,13 +316,13 @@ void GUI_Alert(int fatal, const char *text)
if (d>line)
{
*d=0;
- FB_Centre(line,h,FB_RGB(31,31,31),-1);
+ FB_Centre(line,h,COL_WHITE,COL_TRANSPARENT);
h+=8;
}
if (!fatal)
{
- FB_Centre("PRESS ANY BUTTON OR SCREEN",h+16,FB_RGB(31,31,0),-1);
+ FB_Centre("PRESS ANY BUTTON OR SCREEN",h+16,COL_YELLOW,COL_TRANSPARENT);
while(!keysDown())
{
@@ -336,7 +336,7 @@ void GUI_Alert(int fatal, const char *text)
}
else
{
- FB_Centre("PLEASE RESET YOUR CONSOLE",h+16,FB_RGB(31,31,0),-1);
+ FB_Centre("PLEASE RESET YOUR CONSOLE",h+16,COL_YELLOW,COL_TRANSPARENT);
while(1)
{
@@ -359,18 +359,18 @@ void GUI_Config(void)
FB_Clear();
- FB_Centre("Up/Down to select",140,FB_RGB(31,31,0),-1);
- FB_Centre("A to toggle",150,FB_RGB(31,31,0),-1);
- FB_Centre("Or use touchscreen",160,FB_RGB(31,31,0),-1);
- FB_Centre("START to finish",170,FB_RGB(31,31,0),-1);
+ FB_Centre("Up/Down to select",140,COL_YELLOW,COL_TRANSPARENT);
+ FB_Centre("A to toggle",150,COL_YELLOW,COL_TRANSPARENT);
+ FB_Centre("Or use touchscreen",160,COL_YELLOW,COL_TRANSPARENT);
+ FB_Centre("START to finish",170,COL_YELLOW,COL_TRANSPARENT);
#ifndef DS81_DISABLE_FAT
- FB_Centre("SELECT to finish and save",180,FB_RGB(31,31,0),-1);
+ FB_Centre("SELECT to finish and save",180,COL_YELLOW,COL_TRANSPARENT);
#endif
for(f=0;f<DS81_NUM_CONFIG_ITEMS;f++)
{
- FB_Print(ConfigDesc(f),14,20+f*14,FB_RGB(31,31,31),-1);
+ FB_Print(ConfigDesc(f),14,20+f*14,COL_WHITE,COL_TRANSPARENT);
}
while(!done)
@@ -380,19 +380,19 @@ void GUI_Config(void)
for(f=0;f<DS81_NUM_CONFIG_ITEMS;f++)
{
FB_FillBox(2,20+f*14-1,10,10,
- DS81_Config[f] ? FB_RGB(31,31,31):FB_RGB(0,0,0));
+ DS81_Config[f] ? COL_WHITE : COL_BLACK);
- FB_Box(2,20+f*14-1,10,10,FB_RGB(18,18,18));
+ FB_Box(2,20+f*14-1,10,10,COL_GREY);
}
- FB_Box(0,20+sel*14-3,SCREEN_WIDTH-1,14,FB_RGB(18,18,31));
+ FB_Box(0,20+sel*14-3,SCREEN_WIDTH-1,14,COL_GUISELECT);
do
{
swiWaitForVBlank();
} while(!(key=keysDownRepeat()));
- FB_Box(0,20+sel*14-3,SCREEN_WIDTH-1,14,FB_RGB(0,0,0));
+ FB_Box(0,20+sel*14-3,SCREEN_WIDTH-1,14,COL_BLACK);
if (key & KEY_START)
{
@@ -448,8 +448,7 @@ bool GUI_FileSelect(char pwd[], char selected_file[], const char *filter)
double bar_step;
bool done;
bool ret;
- int pen;
- int paper;
+ FB_Colour paper;
int off;
int f;
bool drag;
@@ -459,12 +458,12 @@ bool GUI_FileSelect(char pwd[], char selected_file[], const char *filter)
FB_Clear();
- FB_printf(0,0,FB_RGB(0,0,0),FB_RGB(22,22,22),"%-32.32s",pwd);
+ FB_printf(0,0,COL_BLACK,COL_LIGHTGREY,"%-32.32s",pwd);
- FB_Centre("Use pad and A to select",140,FB_RGB(31,31,0),-1);
- FB_Centre("L and R to page up/down",150,FB_RGB(31,31,0),-1);
- FB_Centre("Or use touchscreen",160,FB_RGB(31,31,0),-1);
- FB_Centre("B to cancel",170,FB_RGB(31,31,0),-1);
+ FB_Centre("Use pad and A to select",140,COL_YELLOW,COL_TRANSPARENT);
+ FB_Centre("L and R to page up/down",150,COL_YELLOW,COL_TRANSPARENT);
+ FB_Centre("Or use touchscreen",160,COL_YELLOW,COL_TRANSPARENT);
+ FB_Centre("B to cancel",170,COL_YELLOW,COL_TRANSPARENT);
no = LoadDir(pwd,filter);
@@ -498,16 +497,14 @@ bool GUI_FileSelect(char pwd[], char selected_file[], const char *filter)
{
if (off == sel)
{
- pen = FB_RGB(0,0,0);
- paper = FB_RGB(31,31,31);
+ paper = COL_GUISELECT;
}
else
{
- pen = FB_RGB(31,31,31);
- paper = FB_RGB(0,0,0);
+ paper = COL_BLACK;
}
- FB_printf(8,FSEL_LIST_Y+f*8,pen,paper,
+ FB_printf(8,FSEL_LIST_Y+f*8,COL_WHITE,paper,
"%-*s %s",
FSEL_FILENAME_LEN,
fsel[off].name,
@@ -515,7 +512,7 @@ bool GUI_FileSelect(char pwd[], char selected_file[], const char *filter)
}
else
{
- FB_printf(8,FSEL_LIST_Y+f*8,FB_RGB(31,31,31),FB_RGB(0,0,0),
+ FB_printf(8,FSEL_LIST_Y+f*8,COL_WHITE,COL_BLACK,
"%-*s %s",
FSEL_FILENAME_LEN,
off==0 ? "No Files!" : "",
@@ -523,8 +520,8 @@ bool GUI_FileSelect(char pwd[], char selected_file[], const char *filter)
}
}
- FB_FillBox(240,FSEL_LIST_Y,16,FSEL_LIST_H,FB_RGB(10,10,10));
- FB_FillBox(240,FSEL_LIST_Y+top*bar_step,16,bar_size,FB_RGB(31,31,31));
+ FB_FillBox(240,FSEL_LIST_Y,16,FSEL_LIST_H,COL_DARKGREY);
+ FB_FillBox(240,FSEL_LIST_Y+top*bar_step,16,bar_size,COL_WHITE);
if (drag)
{
@@ -681,8 +678,7 @@ bool GUI_FileSelect(char pwd[], char selected_file[], const char *filter)
{
AddPath(pwd,fsel[sel].name);
- FB_printf(0,0,FB_RGB(0,0,0),FB_RGB(22,22,22),
- "%-32.32s",pwd);
+ FB_printf(0,0,COL_BLACK,COL_LIGHTGREY,"%-32.32s",pwd);
no = LoadDir(pwd,filter);
diff --git a/source/keyboard.c b/source/keyboard.c
index 37ae4ef..8853dd1 100644
--- a/source/keyboard.c
+++ b/source/keyboard.c
@@ -29,8 +29,6 @@
/* ---------------------------------------- STATIC DATA
*/
-static uint16 white = FB_RGB(31, 31, 31);
-static uint16 black = FB_RGB(0, 0, 0);
static struct
{
@@ -238,7 +236,8 @@ static int GetEvent(SoftKeyEvent *ev, int map)
x = 3 + (f % 10) * 25;
y = 37 + (f / 10) * 30;
- FB_Box(x, y, 25, 18, key_state[f].new_state ? white:black);
+ FB_Box(x, y, 25, 18, key_state[f].new_state ?
+ COL_WHITE : COL_BLACK);
}
}
}
@@ -270,11 +269,16 @@ static int GetEvent(SoftKeyEvent *ev, int map)
*/
void SK_DisplayKeyboard(uint16 *vram)
{
- sImage img;
+ static sImage img;
+ static int loaded;
- loadPCX(keyb_bin,&img);
- image8to16(&img);
- dmaCopy(img.image.data8,vram,SCREEN_WIDTH*SCREEN_HEIGHT*2);
+ if (!loaded)
+ {
+ loadPCX(keyb_bin,&img);
+ loaded = true;
+ }
+
+ FB_Blit(&img,0,0,110);
}
diff --git a/source/main.c b/source/main.c
index cfdf231..9d25ee0 100644
--- a/source/main.c
+++ b/source/main.c
@@ -33,6 +33,8 @@
#include "zx81.h"
#include "tapes.h"
#include "config.h"
+#include "textmode.h"
+#include "monitor.h"
#include "splashimg_bin.h"
#include "rom_font_bin.h"
@@ -45,6 +47,7 @@ static const char *main_menu[]=
"Select Tape",
"Configure",
"Map Joypad to Keys",
+ "Machine Code Monitor",
"Cancel",
NULL
};
@@ -55,6 +58,7 @@ typedef enum
MenuSelectTape,
MenuConfigure,
MenuMapJoypad,
+ MenuMonitor,
} MenuOpt;
/* ---------------------------------------- IRQ FUNCS
@@ -69,6 +73,15 @@ static void VBlankFunc(void)
static void Splash(void)
{
+ static char scroller[]=
+ {
+ " "
+ "Welcome to DS81, a ZX81 emulator for the Ninetendo DS. "
+ "You can safely ignore this message. I was just bored for half an "
+ "hour. "
+ "Thanks to Slay Radio for coding fuel."
+ };
+
static const char *text[]=
{
"DS81 \177 2006 Ian C",
@@ -91,22 +104,24 @@ static void Splash(void)
int f;
int y;
int res=FALSE;
+ int scr_x=0;
ZX81SuspendDisplay();
ZX81DisplayString("10 print '%the zx81 is ace%'\n20 goto 10");
+ TM_printf(0,23,"%-34.34s",scroller);
+
FB_Clear();
loadPCX(splashimg_bin,&img);
- image8to16(&img);
- FB_Blit(&img,0,0);
+ FB_Blit(&img,0,0,1);
y = 10;
for(f=0;text[f];f++)
{
- FB_Centre(text[f],y,FB_RGB(31,31,31),-1);
+ FB_Centre(text[f],y,COL_WHITE,COL_TRANSPARENT);
y += 8;
}
@@ -120,46 +135,65 @@ static void Splash(void)
{
ZX81EnableFileSystem(TRUE);
- FB_Centre("Found a FAT device.",y,FB_RGB(31,31,31),-1);
+ FB_Centre("Found a FAT device.",y,COL_WHITE,COL_TRANSPARENT);
y += 8;
- FB_Centre("If you place .P tape files in",y,FB_RGB(31,31,31),-1);
+ FB_Centre("If you place .P tape files in",y,COL_WHITE,COL_TRANSPARENT);
y += 8;
- FB_Centre("the top directory or ZX81SNAP",y,FB_RGB(31,31,31),-1);
+ FB_Centre("the top directory or ZX81SNAP",y,COL_WHITE,COL_TRANSPARENT);
y += 8;
- FB_Centre("then you should be able to load",y,FB_RGB(31,31,31),-1);
+ FB_Centre("then you should be able to load",y,
+ COL_WHITE,COL_TRANSPARENT);
y += 8;
- FB_Centre("GAME.P with the command",y,FB_RGB(31,31,31),-1);
+ FB_Centre("GAME.P with the command",y,COL_WHITE,COL_TRANSPARENT);
y += 8;
- FB_Centre("LOAD \"GAME\"",y,FB_RGB(31,31,31),-1);
+ FB_Centre("LOAD \"GAME\"",y,COL_WHITE,COL_TRANSPARENT);
y += 8;
}
else
{
ZX81EnableFileSystem(FALSE);
- FB_Centre("Sorry, but you don't have a",y,FB_RGB(31,31,31),-1);
+ FB_Centre("Sorry, but you don't have a",y,COL_WHITE,COL_TRANSPARENT);
y += 8;
- FB_Centre("supported FAT device.",y,FB_RGB(31,31,31),-1);
+ FB_Centre("supported FAT device.",y,COL_WHITE,COL_TRANSPARENT);
y += 8;
- FB_Centre("Only the internal tape",y,FB_RGB(31,31,31),-1);
+ FB_Centre("Only the internal tape",y,COL_WHITE,COL_TRANSPARENT);
y += 8;
- FB_Centre("files can be used.",y,FB_RGB(31,31,31),-1);
+ FB_Centre("files can be used.",y,COL_WHITE,COL_TRANSPARENT);
y += 8;
}
while(!(keysDown() & KEY_A))
{
swiWaitForVBlank();
+
+ if (++scr_x == 8)
+ {
+ size_t l = sizeof scroller;
+ char c;
+
+ scr_x = 0;
+
+ c = scroller[0];
+ memmove(scroller,scroller+1,l-2);
+ scroller[l-2] = c;
+
+ TM_printf(0,23,"%-34.34s",scroller);
+ }
+
+ SUB_BG0_X0 = scr_x;
}
+ SUB_BG0_X0 = 0;
+
ZX81ResumeDisplay();
}
@@ -241,7 +275,8 @@ int main(int argc, char *argv[])
vramSetBankA(VRAM_A_MAIN_BG_0x06000000);
vramSetBankB(VRAM_B_MAIN_BG_0x06020000);
- BG0_CR = BG_COLOR_256 | BG_MAP_BASE(0) | BG_TILE_BASE(1) | BG_PRIORITY(0);
+ BG0_CR = BG_COLOR_256 | BG_32x32 | BG_MAP_BASE(0) |
+ BG_TILE_BASE(1) | BG_PRIORITY(0);
BG0_X0 = 0;
BG0_Y0 = 0;
@@ -258,22 +293,35 @@ int main(int argc, char *argv[])
dmaCopy(rom_font_bin,(void *)BG_TILE_RAM(1),rom_font_bin_size);
- /* Set up the sub-screen for rotation (basically for use as a framebuffer)
+ /* Set up the sub-screen for rotation (basically for use as a framebuffer).
+ Now overlaid with a text screen for the monitor (I thought a bitmapped
+ printing routine would needlessly slow down the monitor when watching
+ the ZX81 run).
*/
- videoSetModeSub(MODE_5_2D | DISPLAY_BG2_ACTIVE);
+ videoSetModeSub(MODE_3_2D | DISPLAY_BG0_ACTIVE | DISPLAY_BG3_ACTIVE);
vramSetBankC(VRAM_C_SUB_BG_0x06200000);
- SUB_BG2_CR = BG_BMP16_256x256;
- SUB_BG2_XDX = 0x100;
- SUB_BG2_XDY = 0;
- SUB_BG2_YDX = 0;
- SUB_BG2_YDY = 0x100;
- SUB_BG2_CX = 0;
- SUB_BG2_CY = 0;
+ SUB_BG0_CR = BG_COLOR_256 | BG_64x32 | BG_MAP_BASE(4) |
+ BG_TILE_BASE(0) | BG_PRIORITY(0);
+ SUB_BG0_X0 = 0;
+ SUB_BG0_Y0 = 0;
+
+ SUB_BG3_CR = BG_BMP8_256x256 | BG_BMP_BASE(1) | BG_PRIORITY(1);
+ SUB_BG3_XDX = 0x100;
+ SUB_BG3_XDY = 0;
+ SUB_BG3_YDX = 0;
+ SUB_BG3_YDY = 0x100;
+ SUB_BG3_CX = 0;
+ SUB_BG3_CY = 0;
/* Tell 'framebuffer' routines to use this
*/
- FB_Init(BG_GFX_SUB);
+ FB_Init((uint16*)BG_BMP_RAM_SUB(1), BG_PALETTE_SUB);
+
+ /* Set up lower screen text overlay
+ */
+ FB_LoadASCIITiles((uint16*)BG_TILE_RAM_SUB(0));
+ TM_Init((uint16*)BG_MAP_RAM_SUB(4),64,32,FALSE);
/* Set up interrupts and timers
*/
@@ -289,7 +337,7 @@ int main(int argc, char *argv[])
ZX81WriteMem,
ZX81ReadPort,
ZX81WritePort,
- NULL);
+ ZX81ReadDisassem);
if (!z80)
{
@@ -311,6 +359,9 @@ int main(int argc, char *argv[])
{
SoftKeyEvent ev;
+ TM_printf(0,0,"HL = %4.4x",z80->HL.w);
+ TM_printf(0,23,"PC = %4.4x",z80->PC);
+
Z80Exec(z80);
while(SK_GetEvent(&ev))
@@ -341,6 +392,10 @@ int main(int argc, char *argv[])
case MenuMapJoypad:
MapJoypad();
break;
+
+ case MenuMonitor:
+ MachineCodeMonitor();
+ break;
}
SK_DisplayKeyboard(BG_GFX_SUB);
diff --git a/source/monitor.c b/source/monitor.c
new file mode 100644
index 0000000..62d5f3b
--- /dev/null
+++ b/source/monitor.c
@@ -0,0 +1,32 @@
+/*
+ ds81 - Nintendo DS ZX81 emulator.
+
+ Copyright (C) 2006 Ian Cowburn <ianc@noddybox.co.uk>
+
+ 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 <stdlib.h>
+
+#include "monitor.h"
+
+/* ---------------------------------------- PUBLIC INTERFACES
+*/
+void MachineCodeMonitor(void)
+{
+}
diff --git a/source/tapes.c b/source/tapes.c
index 8f141f9..b6df688 100644
--- a/source/tapes.c
+++ b/source/tapes.c
@@ -204,22 +204,21 @@ static void InitTapes(void)
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);
- FB_Print("REMEMBER TO",0,60,FB_RGB(255,255,255),-1);
- FB_Print("LOAD \"\"",0,70,FB_RGB(255,255,255),-1);
- FB_Print("ON THE ZX81!",0,80,FB_RGB(255,255,255),-1);
+ FB_Blit(&t->img,255-t->img.width,0,1);
+
+ FB_Print("LEFT/RIGHT",0,0,COL_WHITE,COL_TRANSPARENT);
+ FB_Print("to choose",0,10,COL_WHITE,COL_TRANSPARENT);
+ FB_Print("A to select",0,30,COL_WHITE,COL_TRANSPARENT);
+ FB_Print("B to cancel",0,40,COL_WHITE,COL_TRANSPARENT);
+ FB_Print("REMEMBER TO",0,60,COL_WHITE,COL_TRANSPARENT);
+ FB_Print("LOAD \"\"",0,70,COL_WHITE,COL_TRANSPARENT);
+ FB_Print("ON THE ZX81!",0,80,COL_WHITE,COL_TRANSPARENT);
ZX81DisplayString(t->text);
}
diff --git a/source/textmode.c b/source/textmode.c
new file mode 100644
index 0000000..aa6de44
--- /dev/null
+++ b/source/textmode.c
@@ -0,0 +1,146 @@
+/*
+ ds81 - Nintendo DS ZX81 emulator.
+
+ Copyright (C) 2007 Ian Cowburn <ianc@noddybox.co.uk>
+
+ 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 <stdio.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "textmode.h"
+
+/* ---------------------------------------- STATIC DATA
+*/
+static int mapw;
+static int maph;
+static uint16 *text;
+static int is_rot;
+static void (*draw_string)(const char *str, int x, int y);
+
+
+/* ---------------------------------------- PRIVATE INTERFACES
+*/
+static inline void Plot_Text(int x, int y, int c)
+{
+ int xw;
+ int yw;
+
+ xw = x/32;
+ yw = y/32;
+ x %= 32;
+ y %= 32;
+
+ *(text + x + y*32 + (xw+yw) * 1024) = c;
+}
+
+
+static inline void Plot_RS(int x, int y, int c)
+{
+ int xw;
+ int yw;
+
+ xw = x/32;
+ yw = y/32;
+ x %= 32;
+ y %= 32;
+
+ *(text + x + y*32 + (xw+yw) * 1024) = c;
+}
+
+
+static void Text_Put(const char *str, int x, int y)
+{
+ while(*str && x<mapw)
+ {
+ Plot_Text(x,y,*str - 32);
+ x++;
+ str++;
+ }
+}
+
+static void RS_Put(const char *str, int x, int y)
+{
+ while(*str && x<mapw)
+ {
+ Plot_RS(x,y,*str - 32);
+ x++;
+ str++;
+ }
+}
+
+/* ---------------------------------------- PUBLIC INTERFACES
+*/
+void TM_Init(uint16 *vram, int map_width, int map_height, int map_is_rotation)
+{
+ text = vram;
+
+ mapw = map_width;
+ maph = map_height;
+
+ is_rot = map_is_rotation;
+
+ draw_string = map_is_rotation ? Text_Put : RS_Put;
+
+ TM_Cls();
+}
+
+
+void TM_Cls(void)
+{
+ uint16 *scr;
+ int f;
+
+ scr = text;
+
+ if (is_rot)
+ {
+ for(f=0;f<mapw*maph/2;f++)
+ {
+ *scr++=0;
+ }
+ }
+ else
+ {
+ for(f=0;f<mapw*maph;f++)
+ {
+ *scr++=0;
+ }
+ }
+}
+
+
+void TM_Put(int x, int y, const char *str)
+{
+ draw_string(str,x,y);
+}
+
+
+void TM_printf(int x, int y, const char *format, ...)
+{
+ char buff[128];
+ va_list va;
+
+ va_start(va,format);
+ vsnprintf(buff,sizeof buff,format,va);
+ va_end(va);
+
+ draw_string(buff,x,y);
+}