From 74fe4fda2a3059b97d1bfcc03e37be1a19ea82fe Mon Sep 17 00:00:00 2001 From: Ian C Date: Sat, 26 Jun 2021 18:19:14 +0000 Subject: Fast mode working and partial text mode. Plan on attempting a ULA emulation. --- include/zx81.h | 2 +- source/framebuffer.c | 6 ++ source/main.c | 83 +++++++++++++++++++++++++- source/zx81.c | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 246 insertions(+), 6 deletions(-) diff --git a/include/zx81.h b/include/zx81.h index 770a132..912a106 100644 --- a/include/zx81.h +++ b/include/zx81.h @@ -39,7 +39,7 @@ void ZX81Init(Z80 *z80); /* Render the display */ -void ZX81RenderDisplay(Framebuffer *fb); +void ZX81RenderDisplay(Framebuffer *fb, Z80 *z80); /* Handle keypresses */ diff --git a/source/framebuffer.c b/source/framebuffer.c index efdd27b..a06ef00 100644 --- a/source/framebuffer.c +++ b/source/framebuffer.c @@ -222,6 +222,12 @@ void FB_EndFrame(void) } +u16 FB_GetColour(FB_Colour col) +{ + return pal[col]; +} + + void FB_Print(Framebuffer *fb, const char *text, int x, int y, FB_Colour colour, FB_Colour paper) { diff --git a/source/main.c b/source/main.c index b41efe6..8ea8e00 100644 --- a/source/main.c +++ b/source/main.c @@ -69,6 +69,7 @@ static const char *main_menu[]= "Load Memory Snapshot", "Save Joypad/Key State", "Load Joypad/Key State", + "Help", "Exit 3DS81", "Cancel", NULL @@ -84,6 +85,7 @@ typedef enum MenuLoadSnapshot, MenuSaveMappings, MenuLoadMappings, + MenuHelp, MenuExit } MenuOpt; @@ -179,6 +181,80 @@ static void Splash(void) } +/* ---------------------------------------- HELP +*/ +static void ShowHelp(void) +{ + struct + { + FB_Colour col; + const char *text; + } + help[] = + { + {COL_RED, "KEYBOARD"}, + {COL_BLACK, "Use the touchscreen to press keys on the computer."}, + {COL_BLACK, "The ZX81 had a keyword entry system, so when the"}, + {COL_BLACK, "cursor is an inverse K then the keyword printed"}, + {COL_BLACK, "at the top of the key is displayed. Therefore"}, + {COL_BLACK, "to load a tape press the J key, then the SHIFT"}, + {COL_BLACK, "key (which by default stays pressed until you"}, + {COL_BLACK, "click it again) and press the P key to enter a"}, + {COL_BLACK, "quote, press the SHIFT key to stop pressing it,"}, + {COL_BLACK, "type the name of the .P file and close it with"}, + {COL_BLACK, "another quote, then press ENTER"}, + {COL_TRANSPARENT, ""}, + {COL_RED, "LOADING TAPES"}, + {COL_BLACK, "There are two ways of loading tapes in the"}, + {COL_BLACK, "simulator. The first is to put .P files in"}, + {COL_BLACK, "either the root directory of the SD card"}, + {COL_BLACK, "or a directory called ZX81SNAP. Files from"}, + {COL_BLACK, "either place can be loaded by typing"}, + {COL_BLACK, "LOAD \"GAME\" to load GAME.P. Alternatively"}, + {COL_BLACK, "you can type LOAD \"*\" to display a file"}, + {COL_BLACK, "selector that allows you to select the tape"}, + {COL_BLACK, "to load. LOAD \"\" can be used to load an"}, + {COL_BLACK, "internal tape image once it has been selected."}, + {COL_TRANSPARENT, NULL} + }; + + int done = FALSE; + u32 key; + Framebuffer upper; + Framebuffer lower; + + while(!done) + { + int f; + + FB_StartFrame(&upper, &lower); + + FB_Clear(&upper, COL_WHITE); + FB_Clear(&lower, COL_BLACK); + + for(f = 0; help[f].text; f++) + { + FB_Print(&upper, help[f].text, 0, upper.height - f * 8, + help[f].col,COL_TRANSPARENT); + } + + FB_Print(&lower, "Scroll around help by using the\n" + "control pad\n" + "Press A to finish.", + 0, lower.height - 40, COL_YELLOW,COL_TRANSPARENT); + + FB_EndFrame(); + + key = hidKeysDown(); + + if (key & KEY_A) + { + done = TRUE; + } + } +} + + /* ---------------------------------------- JOYPAD MAPPING */ static void MapJoypad(void) @@ -246,7 +322,6 @@ int main(int argc, char *argv[]) int quit = FALSE; gfxInit(GSP_RGB565_OES, GSP_RGB565_OES, false); - consoleInit(GFX_TOP, NULL); FB_Init(); @@ -289,7 +364,7 @@ int main(int argc, char *argv[]) Z80Exec(z80); - ZX81RenderDisplay(&upper); + ZX81RenderDisplay(&upper, z80); FB_EndFrame(); @@ -338,6 +413,10 @@ int main(int argc, char *argv[]) SNAP_Load(z80, NULL, SNAP_TYPE_KEYBOARD); break; + case MenuHelp: + ShowHelp(); + break; + case MenuExit: quit = TRUE; break; diff --git a/source/zx81.c b/source/zx81.c index b2d85b1..1335d0b 100644 --- a/source/zx81.c +++ b/source/zx81.c @@ -29,6 +29,7 @@ #include "zx81.h" #include "gui.h" +#include "framebuffer.h" #include "stream.h" @@ -655,10 +656,164 @@ void ZX81Init(Z80 *z80) } -void ZX81RenderDisplay(Framebuffer *fb) +void ZX81RenderDisplay(Framebuffer *fb, Z80 *z80) { - FB_Clear(fb, COL_BLACK); - FB_Centre(fb, "TODO", 10, COL_WHITE, COL_TRANSPARENT); + u16 black; + u16 white; + + black = FB_GetColour(COL_BLACK); + white = FB_GetColour(COL_WHITE); + + if (fast_mode) + { + u16 x; + u16 y; + + for(x = 0; x < fb->width; x++) + { + for(y = 0; y < fb->height; y++) + { + FB_ADDR(fb, x, y) = ((x+y) % 2) ? black : white; + } + } + } + else if (hires) + { + int x; + int y; + Z80Byte *dfile; + + FB_Clear(fb, COL_WHITE); + + dfile = mem + WORD(DFILE); + + dfile++; + + for(y = 0; y < SCR_H; y++) + { + for(x = 0; x < TXT_W; x++) + { + int ch = *dfile++; + int px; + uint pen; + uint paper; + int data; + + if (ch == 118) + { + break; + } + + if (ch & 0x80) + { + pen = white; + paper = black; + ch -= 0x80; + } + else + { + pen = black; + paper = white; + } + + data = mem[z80->I * 256 + ch * 8]; + + for(px = 0; px < 8; px++) + { + if (data & 0x80) + { + FB_ADDR(fb, + x * 8 + px + 72, + fb->height - 24 - y) = pen; + } + else + { + FB_ADDR(fb, + x * 8 + px + 72, + fb->height - 24 - y) = paper; + } + + data = data<<1; + } + } + + if (*dfile == 118) + { + dfile++; + } + } + } + else + { + int x; + int y; + Z80Byte *dfile; + + FB_Clear(fb, COL_WHITE); + + dfile = mem + WORD(DFILE); + + dfile++; + + for(y = 0; y < TXT_H; y++) + { + for(x = 0; x < TXT_W; x++) + { + int ch = *dfile++; + int px; + int py; + uint pen; + uint paper; + + if (ch == 118) + { + break; + } + + if (ch & 0x80) + { + pen = white; + paper = black; + ch -= 0x80; + } + else + { + pen = black; + paper = white; + } + + for(py = 0; py < 8; py++) + { + int data; + + data = mem[z80->I * 256 + ch * 8 + py]; + + for(px = 0; px < 8; px++) + { + if (data & 0x80) + { + FB_ADDR(fb, + x * 8 + px + 72, + fb->height - 24 - y * 8 - py) = pen; + } + else + { + FB_ADDR(fb, + x * 8 + px + 72, + fb->height - 24 - y * 8 - py) = paper; + } + + data = data<<1; + } + } + } + + if (*dfile == 118) + { + dfile++; + } + } + } } -- cgit v1.2.3