diff options
-rw-r--r-- | CHANGES | 10 | ||||
-rw-r--r-- | arm7/Makefile | 2 | ||||
-rw-r--r-- | arm7/source/main.c | 285 | ||||
-rw-r--r-- | arm9/Makefile | 2 | ||||
-rw-r--r-- | arm9/include/ds81_global.h | 37 | ||||
-rw-r--r-- | arm9/source/framebuffer.c | 2 | ||||
-rw-r--r-- | arm9/source/gui.c | 2 | ||||
-rw-r--r-- | arm9/source/keyboard.c | 5 | ||||
-rw-r--r-- | arm9/source/main.c | 215 | ||||
-rw-r--r-- | arm9/source/tapes.c | 2 | ||||
-rw-r--r-- | arm9/source/zx81.c | 12 | ||||
-rw-r--r-- | common/ds81_fader.h | 31 | ||||
-rw-r--r-- | common/ds81_ipc.h | 28 | ||||
-rw-r--r-- | instructions.txt | 4 | ||||
-rw-r--r-- | source/framebuffer.c | 2 | ||||
-rw-r--r-- | source/gui.c | 2 | ||||
-rw-r--r-- | source/keyboard.c | 5 | ||||
-rw-r--r-- | source/main.c | 215 | ||||
-rw-r--r-- | source/tapes.c | 2 | ||||
-rw-r--r-- | source/zx81.c | 12 |
20 files changed, 713 insertions, 162 deletions
@@ -7,3 +7,13 @@ Changes from V1.0 to V1.1 + Fixed bug where the ROM input routine could be easily locked up. This was caused by a problem in the way I set up the LASTK system variables from the house-keeping routine. + + +Changes from V1.1 to V1.1a (uncontrolled release). + + + Fixed hideous mess up that was the keyboard fix. + +Changes from V1.1a to V1.2 + + + Controlled version of keyboard fix. + * Adding Wifi code so that a web server can act as a file store. diff --git a/arm7/Makefile b/arm7/Makefile index c4ede78..f3f6c8f 100644 --- a/arm7/Makefile +++ b/arm7/Makefile @@ -16,7 +16,7 @@ include $(DEVKITARM)/ds_rules #--------------------------------------------------------------------------------- BUILD := build SOURCES := source -INCLUDES := include build +INCLUDES := include build ../common DATA := #--------------------------------------------------------------------------------- diff --git a/arm7/source/main.c b/arm7/source/main.c index 34aef8f..6579ad2 100644 --- a/arm7/source/main.c +++ b/arm7/source/main.c @@ -1,17 +1,27 @@ -/*--------------------------------------------------------------------------------- - $Id$ +/* + 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$ + + This file is largely based on the libnds examples. +*/ - Simple ARM7 stub (sends RTC, TSC, and X/Y data to the ARM 9) - - $Log$ - Revision 1.2 2005/09/07 20:06:06 wntrmute - updated for latest libnds changes - - Revision 1.8 2005/08/03 05:13:16 wntrmute - corrected sound code - - ----------------------------------------------------------------------------------*/ #include <nds.h> #include <nds/bios.h> @@ -20,159 +30,150 @@ #include <dswifi7.h> +#include "ds81_ipc.h" -//--------------------------------------------------------------------------------- -void startSound(int sampleRate, const void* data, u32 bytes, u8 channel, u8 vol, u8 pan, u8 format) { -//--------------------------------------------------------------------------------- - SCHANNEL_TIMER(channel) = SOUND_FREQ(sampleRate); - SCHANNEL_SOURCE(channel) = (u32)data; - SCHANNEL_LENGTH(channel) = bytes >> 2 ; - SCHANNEL_CR(channel) = SCHANNEL_ENABLE | SOUND_ONE_SHOT | SOUND_VOL(vol) | SOUND_PAN(pan) | (format==1?SOUND_8BIT:SOUND_16BIT); -} - - -//--------------------------------------------------------------------------------- -s32 getFreeSoundChannel() { -//--------------------------------------------------------------------------------- - int i; - for (i=0; i<16; i++) { - if ( (SCHANNEL_CR(i) & SCHANNEL_ENABLE) == 0 ) return i; - } - return -1; -} +static void FIFO_Handler(u32 msg); -//--------------------------------------------------------------------------------- -void VblankHandler(void) { -//--------------------------------------------------------------------------------- - static int heartbeat = 0; +static void VblankHandler(void) +{ + static int heartbeat = 0; - uint16 but=0, x=0, y=0, xpx=0, ypx=0, z1=0, z2=0, batt=0, aux=0; - int t1=0, t2=0; - uint32 temp=0; - uint8 ct[sizeof(IPC->curtime)]; - u32 i; + uint16 but=0, x=0, y=0, xpx=0, ypx=0, z1=0, z2=0, batt=0, aux=0; + int t1=0, t2=0; + uint32 temp=0; + uint8 ct[sizeof(IPC->curtime)]; + u32 i; - // Update the heartbeat - heartbeat++; + /* Update the heartbeat */ + heartbeat++; - // Read the touch screen + /* Read the touch screen */ + but = REG_KEYXY; - but = REG_KEYXY; + if (!(but & (1<<6))) + { + touchPosition tempPos = touchReadXY(); - if (!(but & (1<<6))) { + x = tempPos.x; + y = tempPos.y; + xpx = tempPos.px; + ypx = tempPos.py; + } - touchPosition tempPos = touchReadXY(); - - x = tempPos.x; - y = tempPos.y; - xpx = tempPos.px; - ypx = tempPos.py; - } + z1 = touchRead(TSC_MEASURE_Z1); + z2 = touchRead(TSC_MEASURE_Z2); - z1 = touchRead(TSC_MEASURE_Z1); - z2 = touchRead(TSC_MEASURE_Z2); - - - batt = touchRead(TSC_MEASURE_BATTERY); - aux = touchRead(TSC_MEASURE_AUX); - - // Read the time - rtcGetTime((uint8 *)ct); - BCDToInteger((uint8 *)&(ct[1]), 7); - - // Read the temperature - temp = touchReadTemperature(&t1, &t2); - - // Update the IPC struct - IPC->heartbeat = heartbeat; - IPC->buttons = but; - IPC->touchX = x; - IPC->touchY = y; - IPC->touchXpx = xpx; - IPC->touchYpx = ypx; - IPC->touchZ1 = z1; - IPC->touchZ2 = z2; - IPC->battery = batt; - IPC->aux = aux; - - for(i=0; i<sizeof(ct); i++) { - IPC->curtime[i] = ct[i]; - } + batt = touchRead(TSC_MEASURE_BATTERY); + aux = touchRead(TSC_MEASURE_AUX); - IPC->temperature = temp; - IPC->tdiode1 = t1; - IPC->tdiode2 = t2; + /* Read the time */ + rtcGetTime((uint8 *)ct); + BCDToInteger((uint8 *)&(ct[1]), 7); + /* Read the temperature */ + temp = touchReadTemperature(&t1, &t2); - //sound code :) - TransferSound *snd = IPC->soundData; - IPC->soundData = 0; + /* Update the IPC struct */ + IPC->mailBusy = 1; - if (0 != snd) { + IPC->heartbeat = heartbeat; + IPC->buttons = but; + IPC->touchX = x; + IPC->touchY = y; + IPC->touchXpx = xpx; + IPC->touchYpx = ypx; + IPC->touchZ1 = z1; + IPC->touchZ2 = z2; + IPC->battery = batt; + IPC->aux = aux; - for (i=0; i<snd->count; i++) { - s32 chan = getFreeSoundChannel(); + for(i=0; i<sizeof(ct); i++) + { + IPC->curtime[i] = ct[i]; + } - if (chan >= 0) { - startSound(snd->data[i].rate, snd->data[i].data, snd->data[i].len, chan, snd->data[i].vol, snd->data[i].pan, snd->data[i].format); - } - } - } + IPC->temperature = temp; + IPC->tdiode1 = t1; + IPC->tdiode2 = t2; - Wifi_Update(); // update wireless in vblank + IPC->mailBusy = 0; + Wifi_Update(); } -// callback to allow wifi library to notify arm9 -void arm7_synctoarm9() { // send fifo message - REG_IPC_FIFO_TX = 0x87654321; +/* callback to allow wifi library to notify arm9 +*/ +static void ARM7_SyncToARM9(void) +{ + REG_IPC_FIFO_TX = DS81_WIFI_SYNC_IPC; } -// interrupt handler to allow incoming notifications from arm9 -void arm7_fifo() { // check incoming fifo messages - u32 msg = REG_IPC_FIFO_RX; - if(msg==0x87654321) Wifi_Sync(); + +/* interrupt handler to allow incoming notifications from arm9 +*/ +static void ARM7_Fifo(void) +{ + while(!(REG_IPC_FIFO_CR & IPC_FIFO_RECV_EMPTY)) + { + u32 msg; + + msg = REG_IPC_FIFO_RX; + FIFO_Handler(msg); + } } -//--------------------------------------------------------------------------------- -int main(int argc, char ** argv) { -//--------------------------------------------------------------------------------- - REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR; // enable & prepare fifo asap - // Reset the clock if needed - rtcReset(); - - //enable sound - powerON(POWER_SOUND); - SOUND_CR = SOUND_ENABLE | SOUND_VOL(0x7F); - IPC->soundData = 0; - - irqInit(); - irqSet(IRQ_VBLANK, VblankHandler); - irqEnable(IRQ_VBLANK); - - irqSet(IRQ_WIFI, Wifi_Interrupt); // set up wifi interrupt +/* Handler for FIFO messages +*/ +static void FIFO_Handler(u32 msg) +{ + static int next_is_wifi=0; + + if (next_is_wifi) + { + next_is_wifi = 0; + Wifi_Init(msg); + Wifi_SetSyncHandler(ARM7_SyncToARM9); + + irqSet(IRQ_WIFI, Wifi_Interrupt); irqEnable(IRQ_WIFI); + } + else + { + switch(msg) + { + case DS81_WIFI_INIT_IPC: + next_is_wifi = 1; + break; + + case DS81_WIFI_SYNC_IPC: + Wifi_Sync(); + break; + } + } +} + +int main(int argc, char ** argv) +{ + /* enable & prepare fifo asap */ + REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_SEND_CLEAR; + + IPC->mailBusy = 1; + + /* Reset the clock if needed */ + rtcReset(); + + irqInit(); + irqSet(IRQ_VBLANK, VblankHandler); + irqEnable(IRQ_VBLANK); + + irqSet(IRQ_FIFO_NOT_EMPTY,ARM7_Fifo); /* set up fifo irq */ + irqEnable(IRQ_FIFO_NOT_EMPTY); + + REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_RECV_IRQ; -{ // sync with arm9 and init wifi - u32 fifo_temp; - - while(1) { // wait for magic number - while(REG_IPC_FIFO_CR&IPC_FIFO_RECV_EMPTY) swiWaitForVBlank(); - fifo_temp=REG_IPC_FIFO_RX; - if(fifo_temp==0x12345678) break; - } - while(REG_IPC_FIFO_CR&IPC_FIFO_RECV_EMPTY) swiWaitForVBlank(); - fifo_temp=REG_IPC_FIFO_RX; // give next value to wifi_init - Wifi_Init(fifo_temp); - - irqSet(IRQ_FIFO_NOT_EMPTY,arm7_fifo); // set up fifo irq - irqEnable(IRQ_FIFO_NOT_EMPTY); - REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_RECV_IRQ; - - Wifi_SetSyncHandler(arm7_synctoarm9); // allow wifi lib to notify arm9 - } // arm7 wifi init complete - - // Keep the ARM7 out of main RAM - while (1) swiWaitForVBlank(); + while (1) + { + swiWaitForVBlank(); + } } diff --git a/arm9/Makefile b/arm9/Makefile index 0eb1905..26ad86a 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -16,7 +16,7 @@ include $(DEVKITARM)/ds_rules #--------------------------------------------------------------------------------- BUILD := build SOURCES := source -INCLUDES := include +INCLUDES := include build ../common DATA := data #--------------------------------------------------------------------------------- diff --git a/arm9/include/ds81_global.h b/arm9/include/ds81_global.h new file mode 100644 index 0000000..96fb23c --- /dev/null +++ b/arm9/include/ds81_global.h @@ -0,0 +1,37 @@ +/* + 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$ +*/ +#ifndef DS81_GLOBAL_H +#define DS81_GLOBAL_H + +#define DS81STR(x) #x + +/* Tracing. Remove calls once debugged -- relatively expensive ops +*/ +#define TRACE do \ + { \ + int sprintf(char *,const char *,...); \ + char s[32]; \ + sprintf(s,"%s:%d ",__func__,__LINE__); \ + FB_Print(s,0,184,FB_RGB(31,31,31),FB_RGB(10,10,10));\ + } while(0) + +#endif /* DS81_GLOBAL_H */ diff --git a/arm9/source/framebuffer.c b/arm9/source/framebuffer.c index 4a4b03d..65bedc9 100644 --- a/arm9/source/framebuffer.c +++ b/arm9/source/framebuffer.c @@ -23,6 +23,8 @@ #include <nds.h> #include <string.h> +#include "ds81_global.h" + /* ---------------------------------------- STATIC DATA */ #define WIDTH 256 diff --git a/arm9/source/gui.c b/arm9/source/gui.c index 713ad02..e505330 100644 --- a/arm9/source/gui.c +++ b/arm9/source/gui.c @@ -23,6 +23,8 @@ #include <nds.h> #include <string.h> +#include "ds81_global.h" + #include "framebuffer.h" diff --git a/arm9/source/keyboard.c b/arm9/source/keyboard.c index bbc0c61..76f16e6 100644 --- a/arm9/source/keyboard.c +++ b/arm9/source/keyboard.c @@ -21,6 +21,9 @@ */ #include <nds.h> + +#include "ds81_global.h" + #include "keyboard.h" #include "framebuffer.h" #include "keyb_bin.h" @@ -143,8 +146,6 @@ static int GetEvent(SoftKeyEvent *ev, int map) int f; uint32 keys; - scanKeys(); - keys = keysHeld(); /* Clear the non-sticky keys diff --git a/arm9/source/main.c b/arm9/source/main.c index 162ca2d..0f996bb 100644 --- a/arm9/source/main.c +++ b/arm9/source/main.c @@ -25,6 +25,12 @@ #include <string.h> #include <nds.h> #include <fat.h> +#include <dswifi9.h> + +#include "ds81_ipc.h" + +#include "ds81_global.h" +#include "ds81_fader.h" #include "framebuffer.h" #include "gui.h" @@ -45,6 +51,7 @@ static const char *main_menu[]= "Sticky Shift On", "Sticky Shift Off", "Map Joypad to Keys", + "Select Web Server (WFC)", "Cancel", NULL }; @@ -55,14 +62,89 @@ typedef enum MenuSelectTape, MenuStickyOn, MenuStickyOff, - MenuMapJoypad + MenuMapJoypad, + MenuConfigNetwork } MenuOpt; +/* Hope ints are atomic... Having said that we are on the one processor so + I doubt it'll mess up. Which are usually famous last words. +*/ +static volatile int wifi_enabled = FALSE; + +static u32 main_heartbeat; + + +/* ---------------------------------------- IRQ FUNCS +*/ + +static void Timer(void) +{ + { + static int c=0; + char s[32]; + sprintf(s,"%d",(c++)/50); + FB_Print(s,0,184-10,FB_RGB(31,31,31),FB_RGB(10,10,10)); + } + + if (wifi_enabled) + { + Wifi_Timer(50); + } +} + +static void ARM9_SyncToARM7(void) +{ + REG_IPC_FIFO_TX = DS81_WIFI_SYNC_IPC; +} + + +static void ARM9_Fifo(void) +{ + static int c=0; + u32 v; + + v = REG_IPC_FIFO_RX; + + { + char s[32]; + sprintf(s,"%d:%x ",c++,v); + FB_Print(s,0,184,FB_RGB(31,31,31),FB_RGB(10,10,10)); + } + + if (v == DS81_WIFI_SYNC_IPC) + { + Wifi_Sync(); + } +} + + /* ---------------------------------------- DISPLAY FUNCS */ static void VBlankFunc(void) { +#if 0 + char t[32]; + + if (IPC->rtc_hours < 12) + { + sprintf(t,"%2.2d:%2.2d:%2.2d",IPC->rtc_hours, + IPC->rtc_minutes, + IPC->rtc_seconds); + } + else + { + sprintf(t,"%2.2d:%2.2d:%2.2d",IPC->rtc_hours-40, + IPC->rtc_minutes, + IPC->rtc_seconds); + } + + FB_Print(t,192,0,FB_RGB(31,31,31),FB_RGB(10,10,10)); + + sprintf(t,"H:%8.8x M:%8.8x",IPC->heartbeat,main_heartbeat); + FB_Print(t,0,0,FB_RGB(31,31,31),FB_RGB(10,10,10)); +#endif + scanKeys(); } @@ -218,6 +300,109 @@ static void MapJoypad(void) } +/* ---------------------------------------- NETWORK CONFIGURATION +*/ +static const char *AssocStatus(enum WIFI_ASSOCSTATUS s, int *exit_loop) +{ + switch(s) + { + case ASSOCSTATUS_DISCONNECTED: + return "Not trying to connect..."; + + case ASSOCSTATUS_SEARCHING: + return "Searching for AP..."; + + case ASSOCSTATUS_AUTHENTICATING: + return "Connecting (authenticate)..."; + + case ASSOCSTATUS_ASSOCIATING: + return "Connecting (associating)..."; + + case ASSOCSTATUS_ACQUIRINGDHCP: + return "Requesting IP address..."; + + case ASSOCSTATUS_ASSOCIATED: + *exit_loop = 1; + return "Associated"; + + case ASSOCSTATUS_CANNOTCONNECT: + *exit_loop = 1; + return "Cannot connect"; + + default: + *exit_loop = 1; + return "Unknown status"; + } +} + +static void ConfigNetwork(void) +{ + int col; + int coli; + u32 wifi_pass; + enum WIFI_ASSOCSTATUS assoc; + int exit_loop; + + FB_Clear(); + + FB_Centre("Initialising WIFI...",0,FB_RGB(31,31,31),-1); + + wifi_pass = Wifi_Init(WIFIINIT_OPTION_USELED); + + REG_IPC_FIFO_TX = DS81_WIFI_INIT_IPC; + REG_IPC_FIFO_TX = wifi_pass; + + Wifi_SetSyncHandler(ARM9_SyncToARM7); + wifi_enabled = TRUE; + + FB_Centre("Waiting for WIFI...",10,FB_RGB(31,31,31),-1); + + col = 31; + coli = -1; + + while(Wifi_CheckInit() == 0) + { + FB_Centre("Waiting for WIFI...",10,FB_RGB(col,col,col),-1); + DS81_BOUNCE(col,coli); + swiWaitForVBlank(); + } + + FB_Centre("Waiting for WIFI...",10,FB_RGB(31,31,31),-1); + + FB_Centre("Using WFC settings...",20,FB_RGB(31,31,31),-1); + Wifi_AutoConnect(); + + FB_Centre("Waiting for association...",30,FB_RGB(31,31,31),-1); + exit_loop = FALSE; + + while(!exit_loop) + { + assoc = Wifi_AssocStatus(); + + FB_Centre(AssocStatus(assoc,&exit_loop),40,FB_RGB(col,col,col),-1); + DS81_BOUNCE(col,coli); + swiWaitForVBlank(); + } + + FB_Centre(AssocStatus(assoc,&exit_loop),40,FB_RGB(31,31,31),-1); + + FB_Centre("Press a key...",60,FB_RGB(31,31,31),-1); + + while(!keysDown()) + { + swiWaitForVBlank(); + } + + while(keysHeld()) + { + swiWaitForVBlank(); + } + + SK_DisplayKeyboard(BG_GFX_SUB); + swiWaitForVBlank(); +} + + /* ---------------------------------------- MAIN */ int main(int argc, char *argv[]) @@ -255,12 +440,30 @@ int main(int argc, char *argv[]) SUB_BG2_CX = 0; SUB_BG2_CY = 0; + /* Tell 'framebuffer' routines to use this + */ + FB_Init(BG_GFX_SUB); + + /* Set up interrupts and timers + */ irqInit(); irqSet(IRQ_VBLANK,VBlankFunc); + irqEnable(IRQ_VBLANK); - keysSetRepeat(30,15); + REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_RECV_IRQ; - FB_Init(BG_GFX_SUB); + TIMER3_CR = 0; + + irqSet(IRQ_TIMER3,Timer); + TIMER3_DATA = TIMER_FREQ_256(20); + TIMER3_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_DIV_256; + + irqSet(IRQ_FIFO_NOT_EMPTY,ARM9_Fifo); + irqEnable(IRQ_FIFO_NOT_EMPTY); + + /* All required stuff initialised + */ + keysSetRepeat(30,15); z80 = Z80Init(ZX81ReadMem, ZX81WriteMem, @@ -285,6 +488,8 @@ int main(int argc, char *argv[]) { SoftKeyEvent ev; + main_heartbeat++; + Z80Exec(z80); while(SK_GetEvent(&ev)) @@ -316,6 +521,10 @@ int main(int argc, char *argv[]) case MenuMapJoypad: MapJoypad(); break; + + case MenuConfigNetwork: + ConfigNetwork(); + break; } SK_DisplayKeyboard(BG_GFX_SUB); diff --git a/arm9/source/tapes.c b/arm9/source/tapes.c index bc5ac8b..5c49346 100644 --- a/arm9/source/tapes.c +++ b/arm9/source/tapes.c @@ -22,6 +22,8 @@ #include <nds.h> +#include "ds81_global.h" + #include "tapes.h" #include "framebuffer.h" #include "keyboard.h" diff --git a/arm9/source/zx81.c b/arm9/source/zx81.c index 533c382..41ff686 100644 --- a/arm9/source/zx81.c +++ b/arm9/source/zx81.c @@ -28,6 +28,8 @@ #include <ctype.h> #include <nds.h> +#include "ds81_global.h" + #include "zx81.h" #include "gui.h" @@ -446,10 +448,14 @@ static void ZX81HouseKeeping(Z80 *z80) if (lastk1 && (lastk1!=prev_lk1 || lastk2!=prev_lk2)) { mem[CDFLAG]|=1; - - mem[LASTK1]=lastk1^0xff; - mem[LASTK2]=lastk2^0xff; } + else + { + mem[CDFLAG]&=~1; + } + + mem[LASTK1]=lastk1^0xff; + mem[LASTK2]=lastk2^0xff; prev_lk1=lastk1; prev_lk2=lastk2; diff --git a/common/ds81_fader.h b/common/ds81_fader.h new file mode 100644 index 0000000..195283f --- /dev/null +++ b/common/ds81_fader.h @@ -0,0 +1,31 @@ +/* + 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$ +*/ +#ifndef DS81_FADER_H +#define DS81_FADER_H + +#define DS81_BOUNCE(col,coli) do \ + { \ + col+=coli; \ + if (col==0 || col==31) coli=-coli; \ + } while(0) + +#endif /* DS81_FADER_H */ diff --git a/common/ds81_ipc.h b/common/ds81_ipc.h new file mode 100644 index 0000000..2079aff --- /dev/null +++ b/common/ds81_ipc.h @@ -0,0 +1,28 @@ +/* + 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$ +*/ +#ifndef DS81_IPC_H +#define DS81_IPC_H + +#define DS81_WIFI_INIT_IPC 0x12345678 +#define DS81_WIFI_SYNC_IPC 0x87654321 + +#endif /* DS81_IPC_H */ diff --git a/instructions.txt b/instructions.txt index c0d81d2..b7f6089 100644 --- a/instructions.txt +++ b/instructions.txt @@ -49,10 +49,10 @@ initialisation causes problem on your homebrew device: ds81.nds - Nintendo DS version - ds81.bs.gba - As above with a GBA wrapper. + ds81.ds.gba - As above with a GBA wrapper. ds81-nofat.nds - Nintendo DS version; no FAT library initialisation. - ds81-nofat.bs.gba - As above with a GBA wrapper. + ds81-nofat.ds.gba - As above with a GBA wrapper. I'm probably being overly paranoid there, but better safe than sorry. diff --git a/source/framebuffer.c b/source/framebuffer.c index 4a4b03d..65bedc9 100644 --- a/source/framebuffer.c +++ b/source/framebuffer.c @@ -23,6 +23,8 @@ #include <nds.h> #include <string.h> +#include "ds81_global.h" + /* ---------------------------------------- STATIC DATA */ #define WIDTH 256 diff --git a/source/gui.c b/source/gui.c index 713ad02..e505330 100644 --- a/source/gui.c +++ b/source/gui.c @@ -23,6 +23,8 @@ #include <nds.h> #include <string.h> +#include "ds81_global.h" + #include "framebuffer.h" diff --git a/source/keyboard.c b/source/keyboard.c index bbc0c61..76f16e6 100644 --- a/source/keyboard.c +++ b/source/keyboard.c @@ -21,6 +21,9 @@ */ #include <nds.h> + +#include "ds81_global.h" + #include "keyboard.h" #include "framebuffer.h" #include "keyb_bin.h" @@ -143,8 +146,6 @@ static int GetEvent(SoftKeyEvent *ev, int map) int f; uint32 keys; - scanKeys(); - keys = keysHeld(); /* Clear the non-sticky keys diff --git a/source/main.c b/source/main.c index 162ca2d..0f996bb 100644 --- a/source/main.c +++ b/source/main.c @@ -25,6 +25,12 @@ #include <string.h> #include <nds.h> #include <fat.h> +#include <dswifi9.h> + +#include "ds81_ipc.h" + +#include "ds81_global.h" +#include "ds81_fader.h" #include "framebuffer.h" #include "gui.h" @@ -45,6 +51,7 @@ static const char *main_menu[]= "Sticky Shift On", "Sticky Shift Off", "Map Joypad to Keys", + "Select Web Server (WFC)", "Cancel", NULL }; @@ -55,14 +62,89 @@ typedef enum MenuSelectTape, MenuStickyOn, MenuStickyOff, - MenuMapJoypad + MenuMapJoypad, + MenuConfigNetwork } MenuOpt; +/* Hope ints are atomic... Having said that we are on the one processor so + I doubt it'll mess up. Which are usually famous last words. +*/ +static volatile int wifi_enabled = FALSE; + +static u32 main_heartbeat; + + +/* ---------------------------------------- IRQ FUNCS +*/ + +static void Timer(void) +{ + { + static int c=0; + char s[32]; + sprintf(s,"%d",(c++)/50); + FB_Print(s,0,184-10,FB_RGB(31,31,31),FB_RGB(10,10,10)); + } + + if (wifi_enabled) + { + Wifi_Timer(50); + } +} + +static void ARM9_SyncToARM7(void) +{ + REG_IPC_FIFO_TX = DS81_WIFI_SYNC_IPC; +} + + +static void ARM9_Fifo(void) +{ + static int c=0; + u32 v; + + v = REG_IPC_FIFO_RX; + + { + char s[32]; + sprintf(s,"%d:%x ",c++,v); + FB_Print(s,0,184,FB_RGB(31,31,31),FB_RGB(10,10,10)); + } + + if (v == DS81_WIFI_SYNC_IPC) + { + Wifi_Sync(); + } +} + + /* ---------------------------------------- DISPLAY FUNCS */ static void VBlankFunc(void) { +#if 0 + char t[32]; + + if (IPC->rtc_hours < 12) + { + sprintf(t,"%2.2d:%2.2d:%2.2d",IPC->rtc_hours, + IPC->rtc_minutes, + IPC->rtc_seconds); + } + else + { + sprintf(t,"%2.2d:%2.2d:%2.2d",IPC->rtc_hours-40, + IPC->rtc_minutes, + IPC->rtc_seconds); + } + + FB_Print(t,192,0,FB_RGB(31,31,31),FB_RGB(10,10,10)); + + sprintf(t,"H:%8.8x M:%8.8x",IPC->heartbeat,main_heartbeat); + FB_Print(t,0,0,FB_RGB(31,31,31),FB_RGB(10,10,10)); +#endif + scanKeys(); } @@ -218,6 +300,109 @@ static void MapJoypad(void) } +/* ---------------------------------------- NETWORK CONFIGURATION +*/ +static const char *AssocStatus(enum WIFI_ASSOCSTATUS s, int *exit_loop) +{ + switch(s) + { + case ASSOCSTATUS_DISCONNECTED: + return "Not trying to connect..."; + + case ASSOCSTATUS_SEARCHING: + return "Searching for AP..."; + + case ASSOCSTATUS_AUTHENTICATING: + return "Connecting (authenticate)..."; + + case ASSOCSTATUS_ASSOCIATING: + return "Connecting (associating)..."; + + case ASSOCSTATUS_ACQUIRINGDHCP: + return "Requesting IP address..."; + + case ASSOCSTATUS_ASSOCIATED: + *exit_loop = 1; + return "Associated"; + + case ASSOCSTATUS_CANNOTCONNECT: + *exit_loop = 1; + return "Cannot connect"; + + default: + *exit_loop = 1; + return "Unknown status"; + } +} + +static void ConfigNetwork(void) +{ + int col; + int coli; + u32 wifi_pass; + enum WIFI_ASSOCSTATUS assoc; + int exit_loop; + + FB_Clear(); + + FB_Centre("Initialising WIFI...",0,FB_RGB(31,31,31),-1); + + wifi_pass = Wifi_Init(WIFIINIT_OPTION_USELED); + + REG_IPC_FIFO_TX = DS81_WIFI_INIT_IPC; + REG_IPC_FIFO_TX = wifi_pass; + + Wifi_SetSyncHandler(ARM9_SyncToARM7); + wifi_enabled = TRUE; + + FB_Centre("Waiting for WIFI...",10,FB_RGB(31,31,31),-1); + + col = 31; + coli = -1; + + while(Wifi_CheckInit() == 0) + { + FB_Centre("Waiting for WIFI...",10,FB_RGB(col,col,col),-1); + DS81_BOUNCE(col,coli); + swiWaitForVBlank(); + } + + FB_Centre("Waiting for WIFI...",10,FB_RGB(31,31,31),-1); + + FB_Centre("Using WFC settings...",20,FB_RGB(31,31,31),-1); + Wifi_AutoConnect(); + + FB_Centre("Waiting for association...",30,FB_RGB(31,31,31),-1); + exit_loop = FALSE; + + while(!exit_loop) + { + assoc = Wifi_AssocStatus(); + + FB_Centre(AssocStatus(assoc,&exit_loop),40,FB_RGB(col,col,col),-1); + DS81_BOUNCE(col,coli); + swiWaitForVBlank(); + } + + FB_Centre(AssocStatus(assoc,&exit_loop),40,FB_RGB(31,31,31),-1); + + FB_Centre("Press a key...",60,FB_RGB(31,31,31),-1); + + while(!keysDown()) + { + swiWaitForVBlank(); + } + + while(keysHeld()) + { + swiWaitForVBlank(); + } + + SK_DisplayKeyboard(BG_GFX_SUB); + swiWaitForVBlank(); +} + + /* ---------------------------------------- MAIN */ int main(int argc, char *argv[]) @@ -255,12 +440,30 @@ int main(int argc, char *argv[]) SUB_BG2_CX = 0; SUB_BG2_CY = 0; + /* Tell 'framebuffer' routines to use this + */ + FB_Init(BG_GFX_SUB); + + /* Set up interrupts and timers + */ irqInit(); irqSet(IRQ_VBLANK,VBlankFunc); + irqEnable(IRQ_VBLANK); - keysSetRepeat(30,15); + REG_IPC_FIFO_CR = IPC_FIFO_ENABLE | IPC_FIFO_RECV_IRQ; - FB_Init(BG_GFX_SUB); + TIMER3_CR = 0; + + irqSet(IRQ_TIMER3,Timer); + TIMER3_DATA = TIMER_FREQ_256(20); + TIMER3_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_DIV_256; + + irqSet(IRQ_FIFO_NOT_EMPTY,ARM9_Fifo); + irqEnable(IRQ_FIFO_NOT_EMPTY); + + /* All required stuff initialised + */ + keysSetRepeat(30,15); z80 = Z80Init(ZX81ReadMem, ZX81WriteMem, @@ -285,6 +488,8 @@ int main(int argc, char *argv[]) { SoftKeyEvent ev; + main_heartbeat++; + Z80Exec(z80); while(SK_GetEvent(&ev)) @@ -316,6 +521,10 @@ int main(int argc, char *argv[]) case MenuMapJoypad: MapJoypad(); break; + + case MenuConfigNetwork: + ConfigNetwork(); + break; } SK_DisplayKeyboard(BG_GFX_SUB); diff --git a/source/tapes.c b/source/tapes.c index bc5ac8b..5c49346 100644 --- a/source/tapes.c +++ b/source/tapes.c @@ -22,6 +22,8 @@ #include <nds.h> +#include "ds81_global.h" + #include "tapes.h" #include "framebuffer.h" #include "keyboard.h" diff --git a/source/zx81.c b/source/zx81.c index 533c382..41ff686 100644 --- a/source/zx81.c +++ b/source/zx81.c @@ -28,6 +28,8 @@ #include <ctype.h> #include <nds.h> +#include "ds81_global.h" + #include "zx81.h" #include "gui.h" @@ -446,10 +448,14 @@ static void ZX81HouseKeeping(Z80 *z80) if (lastk1 && (lastk1!=prev_lk1 || lastk2!=prev_lk2)) { mem[CDFLAG]|=1; - - mem[LASTK1]=lastk1^0xff; - mem[LASTK2]=lastk2^0xff; } + else + { + mem[CDFLAG]&=~1; + } + + mem[LASTK1]=lastk1^0xff; + mem[LASTK2]=lastk2^0xff; prev_lk1=lastk1; prev_lk2=lastk2; |