diff options
| -rw-r--r-- | CHANGES | 3 | ||||
| -rw-r--r-- | data/cpatrol_inlay.bin | bin | 28889 -> 7485 bytes | |||
| -rw-r--r-- | data/keyb.bin | bin | 16390 -> 13447 bytes | |||
| -rw-r--r-- | data/maze_inlay.bin | bin | 32392 -> 10654 bytes | |||
| -rw-r--r-- | data/mazogs_inlay.bin | bin | 36155 -> 15329 bytes | |||
| -rw-r--r-- | data/sabotage_inlay.bin | bin | 26323 -> 12794 bytes | |||
| -rw-r--r-- | data/splashimg.bin | bin | 23615 -> 19171 bytes | |||
| -rw-r--r-- | include/framebuffer.h | 69 | ||||
| -rw-r--r-- | include/monitor.h | 27 | ||||
| -rw-r--r-- | include/textmode.h | 37 | ||||
| -rw-r--r-- | include/z80_config.h | 2 | ||||
| -rw-r--r-- | include/zx81.h | 2 | ||||
| -rw-r--r-- | source/framebuffer.c | 193 | ||||
| -rw-r--r-- | source/gui.c | 70 | ||||
| -rw-r--r-- | source/keyboard.c | 18 | ||||
| -rw-r--r-- | source/main.c | 105 | ||||
| -rw-r--r-- | source/monitor.c | 32 | ||||
| -rw-r--r-- | source/tapes.c | 19 | ||||
| -rw-r--r-- | source/textmode.c | 146 | 
19 files changed, 578 insertions, 145 deletions
| @@ -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.binBinary files differ index af70c60..6349d6f 100644 --- a/data/cpatrol_inlay.bin +++ b/data/cpatrol_inlay.bin diff --git a/data/keyb.bin b/data/keyb.binBinary files differ index 3759ec5..adbfd5d 100644 --- a/data/keyb.bin +++ b/data/keyb.bin diff --git a/data/maze_inlay.bin b/data/maze_inlay.binBinary files differ index 26a7e97..d48cb22 100644 --- a/data/maze_inlay.bin +++ b/data/maze_inlay.bin diff --git a/data/mazogs_inlay.bin b/data/mazogs_inlay.binBinary files differ index a725c57..1088716 100644 --- a/data/mazogs_inlay.bin +++ b/data/mazogs_inlay.bin diff --git a/data/sabotage_inlay.bin b/data/sabotage_inlay.binBinary files differ index da3f094..904c29a 100644 --- a/data/sabotage_inlay.bin +++ b/data/sabotage_inlay.bin diff --git a/data/splashimg.bin b/data/splashimg.binBinary files differ index 38161e4..de16798 100644 --- a/data/splashimg.bin +++ b/data/splashimg.bin 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); +} | 
