diff options
Diffstat (limited to 'arm9/source/main.c')
-rw-r--r-- | arm9/source/main.c | 427 |
1 files changed, 427 insertions, 0 deletions
diff --git a/arm9/source/main.c b/arm9/source/main.c new file mode 100644 index 0000000..b32174a --- /dev/null +++ b/arm9/source/main.c @@ -0,0 +1,427 @@ +/* + ds48 - Nintendo DS ZX Spectrum 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 <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <nds.h> +#include <fat.h> + +#include "framebuffer.h" +#include "gui.h" +#include "keyboard.h" +#include "z80.h" +#include "config.h" +#include "textmode.h" +#include "monitor.h" +#include "tapes.h" +#include "spec.h" + +#include "splashimg_bin.h" + +#ifndef DS48_VERSION +#define DS48_VERSION "DEV " __TIME__ "/" __DATE__ +#endif + + +/* ---------------------------------------- STATIC DATA +*/ +static const char *main_menu[]= + { + "Reset Spectrum", + "Select Tape", + "Configure", + "Map Joypad to Keys", + "Machine Code Monitor", + "Cancel", + NULL + }; + +typedef enum +{ + MenuReset, + MenuSelectTape, + MenuConfigure, + MenuMapJoypad, + MenuMonitor, +} MenuOpt; + +/* ---------------------------------------- IRQ FUNCS +*/ + +/* ---------------------------------------- DISPLAY FUNCS +*/ +static void VBlankFunc(void) +{ + scanKeys(); +} + +static void Splash(void) +{ + static char scroller[]= + { + " " + "Welcome to DS48, a ZX Spectrum emulator for the Ninetendo DS. " + "You may note a cunning similarity to the ZX81 emulator, DS81, in " + "some of this emulator's appearance... " + "Any similarity is purely intentional. " + "Thanks, as ever, to Slay Radio for coding fuel." + }; + + static const char *text[]= + { + "DS48 \177 2006 Ian C", + " ", + "Spectrum ROM \177 Amstrad", + " ", + "Amstrad have kindly given", + "permission for the Spectrum", + "ROM to be distributed along", + "with emulators.", + " ", + "PRESS A TO CONTINUE", + " ", + "http://www.noddybox.co.uk/", + " ", + " ", + "Checking for FAT device...", + NULL + }; + + static const char *fat_text[]= + { + "Found a FAT device.", + "If you place tape files in", + "the top directory or /SPECGAME", + "then you should be able to load", + "with the command LOAD \"FILE\"", + NULL + }; + + static const char *no_fat_text[]= + { + "Sorry, but you dont have a", + "supported FAT device.", + "Only the internal tape", + "files can be used.", + NULL + }; + + sImage img; + int f; + int y; + int res=FALSE; + int scr_x=0; + + SUB_BG2_XDX = 0x080; + SUB_BG2_YDY = 0x080; + + TM_printf(0,11,"%-18.18s",scroller); + + FB_Clear(); + + loadPCX(splashimg_bin,&img); + + FB_Blit(&img,0,0,1); + + y = 10; + + for(f=0;text[f];f++) + { + FB_Centre(text[f],y,COL_WHITE,COL_TRANSPARENT); + y += 8; + } + + y += 8; + +#ifndef DS48_DISABLE_FAT + res = fatInitDefault(); +#endif + + if (res) + { + SPECEnableFileSystem(TRUE); + + for(f=0;fat_text[f];f++) + { + FB_Centre(fat_text[f],y,COL_WHITE,COL_TRANSPARENT); + y += 8; + } + } + else + { + SPECEnableFileSystem(FALSE); + + for(f=0;no_fat_text[f];f++) + { + FB_Centre(no_fat_text[f],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,11,"%-18.18s",scroller); + } + + SUB_BG2_CX = scr_x << 8; + } + + SUB_BG2_XDX = 0x100; + SUB_BG2_YDY = 0x100; + SUB_BG2_CX = 0; + + TM_Cls(); +} + + +/* ---------------------------------------- JOYPAD MAPPING +*/ +static void MapJoypad(void) +{ +#if 0 + SoftKeyEvent ev; + SoftKey pad = NUM_SOFT_KEYS; + int done = FALSE; + char text[256]; + + SK_DisplayKeyboard(); + + ZX SpectrumSuspendDisplay(); + + ZX SpectrumDisplayString("press the joypad button you want\n" + "to define and then the ZX Spectrum key\n" + "you want to use.\n\n" + "press on the config banner to\n" + "finish."); + + while(!done) + { + while(SK_GetBareEvent(&ev)) + { + if (ev.pressed) + { + if (ev.key==SK_ABOUT || ev.key==SK_CONFIG) + { + done = true; + } + } + else + { + if (ev.key>=SK_PAD_UP && ev.key<=SK_PAD_SELECT) + { + pad = ev.key; + + /* Now, just how dumb was making % the inverse on/off... + */ + sprintf(text,"defining\n %%%s%%",SK_KeyName(pad)); + ZX SpectrumDisplayString(text); + } + + if (ev.key<=SK_SPACE && pad!=NUM_SOFT_KEYS) + { + sprintf(text,"mapped\n %%%s%%\nto\n %%%s%%", + SK_KeyName(pad),SK_KeyName(ev.key)); + ZX SpectrumDisplayString(text); + + SK_DefinePad(pad,ev.key); + + pad = NUM_SOFT_KEYS; + } + } + } + + swiWaitForVBlank(); + } + + ZX SpectrumResumeDisplay(); +#endif +} + + +/* ---------------------------------------- MAIN +*/ +int main(int argc, char *argv[]) +{ + Z80 *z80; + + powerON(POWER_ALL_2D); + + /* Set up main screen for ZX Spectrum. + */ + videoSetMode(MODE_3_2D | DISPLAY_BG0_ACTIVE | DISPLAY_BG3_ACTIVE); + + vramSetBankA(VRAM_A_MAIN_BG_0x06000000); + vramSetBankB(VRAM_B_MAIN_BG_0x06020000); + + BG0_CR = BG_COLOR_256 | BG_32x32 | BG_MAP_BASE(0) | + BG_TILE_BASE(1) | BG_PRIORITY(0); + BG0_X0 = 0; + BG0_Y0 = 0; + + BG_PALETTE[0] = RGB15(31,31,31); + BG_PALETTE[1] = RGB15(0,0,0); + + BG3_CR = BG_BMP16_256x256 | BG_BMP_BASE(2) | BG_PRIORITY(1); + BG3_XDX = 0x100; + BG3_XDY = 0; + BG3_YDX = 0; + BG3_YDY = 0x100; + BG3_CX = 0; + BG3_CY = 0; + + /* 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 Spectrum run). Having said the overlay is currently a rotation map + for some pointless frippery! Still be quicker though. + */ + videoSetModeSub(MODE_4_2D | DISPLAY_BG2_ACTIVE | DISPLAY_BG3_ACTIVE); + vramSetBankC(VRAM_C_SUB_BG_0x06200000); + + SUB_BG2_CR = BG_COLOR_256 | BG_RS_32x32 | BG_MAP_BASE(4) | + BG_TILE_BASE(0) | BG_PRIORITY(0); + 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_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((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),32,32,TRUE); + + /* Set up interrupts and timers + */ + irqInit(); + irqSet(IRQ_VBLANK,VBlankFunc); + irqEnable(IRQ_VBLANK); + + /* All required stuff initialised + */ + keysSetRepeat(30,15); + + z80 = Z80Init(SPECPeek, + SPECPoke, + SPECReadPort, + SPECWritePort, + SPECDisPeek); + + if (!z80) + { + GUI_Alert(TRUE,"Failed to initialise\nthe Z80 CPU emulation!"); + } + + SPECInit((uint16*)BG_BMP_RAM(2), z80); + + Splash(); + + LoadConfig(); + SPECReconfigure(); + + SK_DisplayKeyboard(); + + SK_SetSticky(SK_CAPS_SHIFT,DS48_Config[DS48_STICKY_CAPS]); + SK_SetSticky(SK_SYMBOL_SHIFT,DS48_Config[DS48_STICKY_SYM]); + + while(1) + { + SoftKeyEvent ev; + + /* Z80Exec(z80); */ + + while(SK_GetEvent(&ev)) + { + switch(ev.key) + { + case SK_ABOUT: + case SK_CONFIG: + if (ev.pressed) + { + switch(GUI_Menu(main_menu)) + { + case MenuReset: + SPECReset(z80); + break; + + case MenuSelectTape: + SelectTape(); + break; + + case MenuConfigure: + GUI_Config(); + SK_SetSticky(SK_CAPS_SHIFT, + DS48_Config[DS48_STICKY_CAPS]); + SK_SetSticky(SK_SYMBOL_SHIFT, + DS48_Config[DS48_STICKY_SYM]); + SPECReconfigure(); + break; + + case MenuMapJoypad: + MapJoypad(); + break; + + case MenuMonitor: + MachineCodeMonitor(z80); + break; + } + + SK_DisplayKeyboard(); + } + break; + + default: + SPECHandleKey(ev.key,ev.pressed); + break; + } + } + } + + return 0; +} |