From 6be2806499299bb13edde3481803f28416429902 Mon Sep 17 00:00:00 2001
From: Ian C <ianc@noddybox.co.uk>
Date: Thu, 1 Mar 2007 00:36:54 +0000
Subject: Changed lower screen to 8-bits and added overlayed text mode. 
 Monitor stub in place.  Text mode helpers being developed.

---
 source/framebuffer.c | 193 +++++++++++++++++++++++++++++++++++++--------------
 source/gui.c         |  70 +++++++++----------
 source/keyboard.c    |  18 +++--
 source/main.c        | 105 +++++++++++++++++++++-------
 source/monitor.c     |  32 +++++++++
 source/tapes.c       |  19 +++--
 source/textmode.c    | 146 ++++++++++++++++++++++++++++++++++++++
 7 files changed, 450 insertions(+), 133 deletions(-)
 create mode 100644 source/monitor.c
 create mode 100644 source/textmode.c

(limited to 'source')

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);
+}
-- 
cgit v1.2.3