diff --git a/snes/wram/Makefile b/snes/wram/Makefile new file mode 100644 index 0000000..b65cf4c --- /dev/null +++ b/snes/wram/Makefile @@ -0,0 +1,70 @@ +# SDK Config + + +PLATFORM=$(shell uname) + +ifeq ($(PLATFORM),Linux) + # Linux Wine + SDK=/home/david/.wine/drive_c/65xx_FreeSDK + WINE=wine + EMU=../../tools/bsnes/bsnes + DISASM=/home/david/Devel/arch/snes/devkit/bin/disasm + UCON=ucon64 +else + # Mac Wine + SDK=/Users/david/.wine/drive_c/65xx_FreeSDK + WINE=wine + EMU=zsnes + DISASM=/Users/david/Devel/arch/snes/devkit/bin/disasm + UCON=ucon64 +endif + +CC=$(WINE) $(SDK)/bin/WDC816CC.exe +AS=$(WINE) $(SDK)/bin/WDC816AS.exe +LD=$(WINE) $(SDK)/bin/WDCLN.exe + + +# Project + +INC=$(SDK)/include +LIBS=-L$(SDK)/lib/cl +#-L$(SDK)/lib/c134 + + +OBJS=StartupSnes.obj main.obj pad.obj PPU.obj debug.obj ressource.obj +APP=wram.smc +GFX=debugfont + +all: $(APP) repair + +run: + $(EMU) $(APP) + + +disasm: $(APP) + rm -rf $(APP) + $(DISASM) $(APP) > $(APP).asm + +repair: $(APP) + $(UCON) -snes -chk $(APP) 2>&1 >/dev/null + rm -rf *.bak + +StartupSnes.obj: StartupSnes.asm + $(AS) -V $? + +ressource.obj: ressource.asm + $(AS) -V $? + +%.obj: %.c + $(CC) -wl -wp -sop -ML -I $(INC) $? + +$(APP): $(OBJS) + $(LD) -B -HB -M21 -V -T -Pff \ + -C008000,0000 -U0000,0000 \ + -Avectors=FFE4,7FE4 \ + -Aregistration_data=FFB0,7FB0 \ + -Aressource=18000,8000 \ + -N $(OBJS) $(LIBS) -O $@ + +clean: + rm -vf $(APP) *.obj *.TMP diff --git a/snes/wram/PPU.c b/snes/wram/PPU.c new file mode 100644 index 0000000..a0fd197 --- /dev/null +++ b/snes/wram/PPU.c @@ -0,0 +1,90 @@ +#include "data.h" + +byte tileMapLocation[4]; +word characterLocation[4]; + +void waitForVBlank(void) +{ + byte Status; + do { + Status = *(byte *) 0x4210; + } while (!(Status & 0x80)); +} + +void setTileMapLocation(word vramDst, byte screenProp, byte bgNumber) +{ + tileMapLocation[bgNumber] = ((vramDst >> 8) & 0xfc) | (screenProp & 0x03); + *(byte *) (0x2107 + bgNumber) = tileMapLocation[bgNumber]; +} + +void restoreTileMapLocation(byte bgNumber) +{ + *(byte *) (0x2107 + bgNumber) = tileMapLocation[bgNumber]; +} + +void setCharacterLocation(word vramDst, byte bgNumber) +{ + characterLocation[bgNumber] = vramDst; + if (bgNumber < 2) { + *(byte *) 0x210b = + (characterLocation[1] >> 8 & 0xf0) + (characterLocation[0] >> 12); + } else { + *(byte *) 0x210c = + (characterLocation[3] >> 8 & 0xf0) + (characterLocation[2] >> 12); + } +} + +void restoreCharacterLocation(byte bgNumber) +{ + setCharacterLocation(characterLocation[bgNumber], bgNumber); +} + +void VRAMByteWrite(byte value, word vramDst) +{ + *(byte *) 0x2115 = 0x80; + *(word *) 0x2116 = vramDst; + + *(byte *) 0x2118 = value; +} + +void VRAMLoad(word src, word vramDst, word size) +{ + // set address in VRam for read or write ($2116) + block size transfer ($2115) + *(byte *) 0x2115 = 0x80; + *(word *) 0x2116 = vramDst; + + *(word *) 0x4300 = 0x1801; // set DMA control register (1 word inc) + // and destination ($21xx xx -> 0x18) + *(word *) 0x4302 = src; // DMA channel x source address offset + // (low $4302 and high $4303 optimisation) + *(byte *) 0x4304 = 0x01; // DMA channel x source address bank + *(word *) 0x4305 = size; // DMA channel x transfer size + // (low $4305 and high $4306 optimisation) + + // Turn on DMA transfer for this channel + waitForVBlank(); + *(byte *) 0x2100 = 0x80; + *(byte *) 0x420b = 0x01; + *(byte *) 0x2100 = 0x00; +} + +void CGRAMLoad(word src, byte cgramDst, word size) +{ + + // set address in VRam for read or write + block size + *(byte *) 0x2121 = cgramDst; + + *(word *) 0x4300 = 0x2200; // set DMA control register (1 byte inc) + // and destination ($21xx xx -> 022) + *(word *) 0x4302 = src; // DMA channel x source address offset + // (low $4302 and high $4303 optimisation) + *(byte *) 0x4304 = 0x01; // DMA channel x source address bank + *(word *) 0x4305 = size; // DMA channel x transfer size + // (low $4305 and high $4306 optimisation) + + // Turn on DMA transfer for this channel + waitForVBlank(); + *(byte *) 0x2100 = 0x80; + *(byte *) 0x420b = 0x01; + *(byte *) 0x2100 = 0x00; +} diff --git a/snes/wram/PPU.h b/snes/wram/PPU.h new file mode 100644 index 0000000..a0a3899 --- /dev/null +++ b/snes/wram/PPU.h @@ -0,0 +1,11 @@ +extern byte tileMapLocation[4]; +extern word characterLocation[4]; + +void waitForVBlank(void); +void setTileMapLocation(word vramDst, byte screenProp, byte bgNumber); +void restoreTileMapLocation(byte bgNumber); +void setCharacterLocation(word vramDst, byte bgNumber); +void restoreCharacterLocation(byte bgNumber); +void VRAMByteWrite(byte value, word vramDst); +void VRAMLoad(word src, word vramDst, word size); +void CGRAMLoad(word src, byte cgramDst, word size); diff --git a/snes/wram/StartupSnes.asm b/snes/wram/StartupSnes.asm new file mode 100644 index 0000000..13844b7 --- /dev/null +++ b/snes/wram/StartupSnes.asm @@ -0,0 +1,240 @@ +; SNES ROM startup code + +;****************************************************************************** +;*** Define a special section in case most of the code is not in bank 0. *** +;****************************************************************************** + +;STACK EQU $01ff ;CHANGE THIS FOR YOUR SYSTEM + +;STARTUP SECTION OFFSET $008000 + +CODE + + XDEF START +START: + XREF ~~main + + sei ; Disabled interrupts + clc ; clear carry to switch to native mode + xce ; Xchange carry & emulation bit. native mode + rep #$18 ; Binary mode (decimal mode off), X/Y 16 bit + LONGI ON + ldx #$1FFF ; set stack to $1FFF + txs + + rep #$30 + longa on + longi on + + ; Init data used for heap + ; see heap definition below + XREF ~~_heap_top + XREF ~~_mem_start + stz ~~_heap_top + stz ~~_mem_start + + XREF ~~preInit + jsr >~~preInit + + sep #$30 ; X,Y,A are 8 bit numbers + LONGA OFF + LONGI OFF + lda #$8F ; screen off, full brightness + sta $2100 ; brightness + screen enable register + stz $2101 ; Sprite register (size + address in VRAM) + stz $2102 ; Sprite registers (address of sprite memory [OAM]) + stz $2103 ; "" "" + stz $2105 ; Mode 0, = Graphic mode register + stz $2106 ; noplanes, no mosaic, = Mosaic register + stz $2107 ; Plane 0 map VRAM location + stz $2108 ; Plane 1 map VRAM location + stz $2109 ; Plane 2 map VRAM location + stz $210A ; Plane 3 map VRAM location + stz $210B ; Plane 0+1 Tile data location + stz $210C ; Plane 2+3 Tile data location + stz $210D ; Plane 0 scroll x (first 8 bits) + stz $210D ; Plane 0 scroll x (last 3 bits) #$0 - #$07ff + stz $210E ; Plane 0 scroll y (first 8 bits) + stz $210E ; Plane 0 scroll y (last 3 bits) #$0 - #$07ff + stz $210F ; Plane 1 scroll x (first 8 bits) + stz $210F ; Plane 1 scroll x (last 3 bits) #$0 - #$07ff + stz $2110 ; Plane 1 scroll y (first 8 bits) + stz $2110 ; Plane 1 scroll y (last 3 bits) #$0 - #$07ff + stz $2111 ; Plane 2 scroll x (first 8 bits) + stz $2111 ; Plane 2 scroll x (last 3 bits) #$0 - #$07ff + stz $2112 ; Plane 2 scroll y (first 8 bits) + stz $2112 ; Plane 2 scroll y (last 3 bits) #$0 - #$07ff + stz $2113 ; Plane 3 scroll x (first 8 bits) + stz $2113 ; Plane 3 scroll x (last 3 bits) #$0 - #$07ff + stz $2114 ; Plane 3 scroll y (first 8 bits) + stz $2114 ; Plane 3 scroll y (last 3 bits) #$0 - #$07ff + lda #$80 ; increase VRAM address after writing to $2119 + sta $2115 ; VRAM address increment register + stz $2116 ; VRAM address low + stz $2117 ; VRAM address high + stz $211A ; Initial Mode 7 setting register + stz $211B ; Mode 7 matrix parameter A register (low) + lda #$01 + sta $211B ; Mode 7 matrix parameter A register (high) + stz $211C ; Mode 7 matrix parameter B register (low) + stz $211C ; Mode 7 matrix parameter B register (high) + stz $211D ; Mode 7 matrix parameter C register (low) + stz $211D ; Mode 7 matrix parameter C register (high) + stz $211E ; Mode 7 matrix parameter D register (low) + sta $211E ; Mode 7 matrix parameter D register (high) + stz $211F ; Mode 7 center position X register (low) + stz $211F ; Mode 7 center position X register (high) + stz $2120 ; Mode 7 center position Y register (low) + stz $2120 ; Mode 7 center position Y register (high) + stz $2121 ; Color number register ($0-ff) + stz $2123 ; BG1 & BG2 Window mask setting register + stz $2124 ; BG3 & BG4 Window mask setting register + stz $2125 ; OBJ & Color Window mask setting register + stz $2126 ; Window 1 left position register + stz $2127 ; Window 2 left position register + stz $2128 ; Window 3 left position register + stz $2129 ; Window 4 left position register + stz $212A ; BG1, BG2, BG3, BG4 Window Logic register + stz $212B ; OBJ, Color Window Logic Register (or,and,xor,xnor) + sta $212C ; Main Screen designation (planes, sprites enable) + stz $212D ; Sub Screen designation + stz $212E ; Window mask for Main Screen + stz $212F ; Window mask for Sub Screen + lda #$30 + sta $2130 ; Color addition & screen addition init setting + stz $2131 ; Add/Sub sub designation for screen, sprite, color + lda #$E0 + sta $2132 ; color data for addition/subtraction + stz $2133 ; Screen setting (interlace x,y/enable SFX data) + stz $4200 ; Enable V-blank, interrupt, Joypad register + lda #$FF + sta $4201 ; Programmable I/O port + stz $4202 ; Multiplicand A + stz $4203 ; Multiplier B + stz $4204 ; Multiplier C + stz $4205 ; Multiplicand C + stz $4206 ; Divisor B + stz $4207 ; Horizontal Count Timer + stz $4208 ; Horizontal Count Timer MSB (most significant bit) + stz $4209 ; Vertical Count Timer + stz $420A ; Vertical Count Timer MSB + stz $420B ; General DMA enable (bits 0-7) + stz $420C ; Horizontal DMA (HDMA) enable (bits 0-7) + stz $420D ; Access cycle designation (slow/fast rom) + cli ; Enable interrupts + + rep #$30 + longa on + longi on + + jsr >~~main + brk + + XDEF IRQ +IRQ: + XREF ~~IRQHandler + LONGA ON + LONGI ON + rep #$30 + pha + phx + phy + jsr ~~IRQHandler + ply + plx + pla + rti + + XDEF NMI +NMI: + XREF ~~NMIHandler + LONGA ON + LONGI ON + rep #$30 + pha + phx + phy + phd + phb + lda #$0000 + sep #$30 ; X,Y,A are 8 bit numbers + LONGA OFF + LONGI OFF + lda $4210 ; Read NMI + LONGA ON + LONGI ON + rep #$30 + jsr ~~NMIHandler + plb + pld + ply + plx + pla + rti + +DIRQ: + rti + +ENDS + +;****************************************************************************** +;*** Heap definition *** +;****************************************************************************** + +DATA + + XDEF ~~heap_start + XDEF ~~heap_end + +~~heap_start: + WORD $1000 +~~heap_end: + WORD $1200 + +;****************************************************************************** +;*** SNES ROM Registartion Data *** +;****************************************************************************** + +REGISTRATION_DATA SECTION + +MAKER_CODE FCC /FF/ +GAME_CODE FCC /SMWJ/ +FIXED_VALUE0 BYTE $00, $00, $00, $00, $00, $00, $00 +EXPANSION_RAM_SIZE BYTE $00 +SPECIAL_VERSION BYTE $00 +CARTRIDGE_TYPE_SUB BYTE $00 +GAME_TITLE FCC /GAME TITLE !/ + ;012345678901234567890; +MAP_MODE BYTE $20 +CARTRIDGE_SIZE BYTE $00 +ROM_SIZE BYTE $09 +RAM_SIZE BYTE $00 +DESTINATION_CODE BYTE $00 +FIXED_VALUE1 BYTE $33 +MASK_ROM_VERSION BYTE $00 +COMPLEMENT_CHECK BYTE $00, $00 +CHEKSUM BYTE $00, $00 + +;****************************************************************************** +;*** SNES Interrupts and Reset vector *** +;****************************************************************************** + +VECTORS SECTION +; Native vector +N_COP DW DIRQ +N_BRK DW DIRQ +N_ABORT DW DIRQ +N_NMI DW NMI +N_RSRVD DW DIRQ +N_IRQ DW IRQ + DS 4 +; Emulation vector +E_COP DW DIRQ +E_RSRVD DW DIRQ +E_ABORT DW DIRQ +E_NMI DW DIRQ +E_RESET DW START +E_IRQ DW DIRQ + +END + diff --git a/snes/wram/crc.c b/snes/wram/crc.c new file mode 100644 index 0000000..12749a3 --- /dev/null +++ b/snes/wram/crc.c @@ -0,0 +1,37 @@ +#include "data.h" + + +word crc_update(char far * data, word size) +{ + word i; + word j; + word crc = 0; + for (j = 0; j < size; j++) { + crc = crc ^ ((word) data[j] << 8); + for (i = 0; i < 8; i++) { + if (crc & 0x8000) + crc = (crc << 1) ^ 0x1021; + else + crc <<= 1; + } + } + return crc; +} + + +word crc_update_mem(unsigned long addr, word size) +{ + word i; + word j; + word crc = 0; + for (j = 0; j < size; j++) { + crc = crc ^ ((word) * (byte *) (addr + j) << 8); + for (i = 0; i < 8; i++) { + if (crc & 0x8000) + crc = (crc << 1) ^ 0x1021; + else + crc <<= 1; + } + } + return crc; +} diff --git a/snes/wram/crc.h b/snes/wram/crc.h new file mode 100644 index 0000000..8108d80 --- /dev/null +++ b/snes/wram/crc.h @@ -0,0 +1,3 @@ + +word crc_update(byte * data, word size); +word crc_update_mem(unsigned long, word size); diff --git a/snes/wram/data.h b/snes/wram/data.h new file mode 100644 index 0000000..673102c --- /dev/null +++ b/snes/wram/data.h @@ -0,0 +1,8 @@ + +#ifndef _DATA + +typedef unsigned char byte; +typedef unsigned short word; + +#define _DATA +#endif diff --git a/snes/wram/debug.c b/snes/wram/debug.c new file mode 100644 index 0000000..5a3ba02 --- /dev/null +++ b/snes/wram/debug.c @@ -0,0 +1,224 @@ +#include +#include +#include +#include + +#include "debug.h" +#include "data.h" +#include "pad.h" +#include "PPU.h" +#include "ressource.h" + + + +#define DEBUG_BUFFER_SIZE 128 + +word debugMap[0x400]; +char debug_buffer[DEBUG_BUFFER_SIZE]; +char screen_buffer[DEBUG_BUFFER_SIZE]; + + +void debug_init(void) +{ + word i; + for (i = 0; i < 0x400; i++) { + debugMap[i] = 0x00; + } + memset(debug_buffer, 0, DEBUG_BUFFER_SIZE); + memset(screen_buffer, 0,DEBUG_BUFFER_SIZE); +} + + +void debug_enable(void) +{ + VRAMLoad((word) debugFont_pic, 0x5000, 2048); + VRAMLoad((word) debugMap, 0x4000, 0x0800); + setTileMapLocation(0x4000, (byte) 0x00, (byte) 0); + setCharacterLocation(0x5000, (byte) 0); + *(byte *) 0x2100 = 0x0f; // enable background + + // Font Color + // hex(24 << 10 | 24 << 5 | 24 ) = '0x6318' + *(byte *) 0x2121 = 0x02; + *(byte *) 0x2122 = 0xff; + *(byte *) 0x2122 = 0x7f; + + // Font Border Color + *(byte *) 0x2121 = 0x00; + *(byte *) 0x2122 = 0x00; + *(byte *) 0x2122 = 0x00; + + // Background Color + *(byte *) 0x2121 = 0x01; + *(byte *) 0x2122 = 0x05; + *(byte *) 0x2122 = 0x29; + + +} + +void clears(void) +{ + word i, y; + for (y = 0; y < 20; y++) { + waitForVBlank(); + for (i = 0; i < 32; i++) { + *(byte *) 0x2115 = 0x80; + *(word *) 0x2116 = 0x4000 + i + (y * 0x20); + *(byte *) 0x2118 = 0; + } + } +} + +void _print_char(word y, word x, char c) +{ + waitForVBlank(); + VRAMByteWrite((byte) (c - 32), (word) (0x4000 + x + (y * 0x20))); +} + +void _print_screen(word y, char *buffer) +{ + char l; + unsigned int x; + x = y * 0x20; + l = strlen(buffer); + waitForVBlank(); + while (*buffer) { + if (*buffer == '\n') { + while (x++ < 32) { + *(byte *) 0x2115 = 0x80; + *(word *) 0x2116 = 0x4000 + x + (y * 0x20); + *(byte *) 0x2118 = 0; + } + x = 0; + y += 0x20; + buffer++; + waitForVBlank(); + continue; + } + *(byte *) 0x2115 = 0x80; + *(word *) 0x2116 = 0x4000 + x; + *(byte *) 0x2118 = *buffer - 32; + x++; + buffer++; +#if 1 + waitForVBlank(); +#endif + } +} +void _print_console(const char *buffer) +{ + while (*buffer) + *(byte *) 0x3000 = *buffer++; +} + + + + +void printfc(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vsprintf(debug_buffer, fmt, ap); + va_end(ap); + _print_console(debug_buffer); + //memset(debug_buffer,0,DEBUG_BUFFER_SIZE); + +} + +void printfs(word y, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vsprintf(screen_buffer, fmt, ap); + va_end(ap); + _print_screen(y, screen_buffer); + //memset(screen_buffer, 0, DEBUG_BUFFER_SIZE); +} + +void printc_packet(unsigned long addr, unsigned int len, byte * packet) +{ + unsigned int i, j; + unsigned int sum = 0; + unsigned int last_sum = 0; + unsigned int clear = 0; + + for (i = 0; i < len; i += 16) { + + sum = 0; + for (j = 0; j < 16; j++) { + sum += packet[i + j]; + } + if (!sum) { + clear = 1; + continue; + } + + if (last_sum == sum) { + clear = 1; + continue; + } + + if (clear) { + printfc("*\n"); + clear = 0; + } + printfc("%06lX:", addr + i); + for (j = 0; j < 16; j++) { + printfc(" %02x", packet[i + j]); + } + printfc(" |"); + for (j = 0; j < 16; j++) { + if (packet[i + j] >= 33 && packet[i + j] <= 126) + printfc("%c", packet[i + j]); + else + printfc("."); + } + printfc("|\n"); + last_sum = sum; + } +} +/* + * keep the linker happy + */ +int open(const char *_name, int _mode) +{ + _print_console("open called\n"); + return -1; +} + +int close(int fd) +{ + _print_console("close called\n"); + return -1; + +} + +size_t read(int fd, void *buff, size_t len) +{ + _print_console("read called\n"); + return 0; +} + +size_t write(int fd, void *buffer, size_t len) +{ + _print_console("write called\n"); + return 0; +} + +long lseek(int fd, long off, int count) +{ + _print_console("lseek called\n"); + return 0; +} + +int unlink(const char *name) +{ + _print_console("unlink called\n"); + return -1; +} + +int isatty() +{ + _print_console("isatty called\n"); + return 1; +} diff --git a/snes/wram/debug.h b/snes/wram/debug.h new file mode 100644 index 0000000..6f82af9 --- /dev/null +++ b/snes/wram/debug.h @@ -0,0 +1,8 @@ +#include "data.h" + +void debug_init(void); +void debug_enable(void); +void printfs(word y, const char *fmt, ...); +void printfc(const char *fmt, ...); +void clears(void); +void printc_packet(unsigned long addr, unsigned int len, byte * packet); diff --git a/snes/wram/event.c b/snes/wram/event.c new file mode 100644 index 0000000..d3bc9ba --- /dev/null +++ b/snes/wram/event.c @@ -0,0 +1,106 @@ +#include + +#include "data.h"; +#include "event.h"; + +event *events; + +void initEvents(void) +{ + events = NULL; +} + +event *createEvent(char (*callback) (word counter)) +{ + event *myEvent; + + myEvent = (event *) malloc(sizeof(event)); + + myEvent->VBlankCount = 0; + myEvent->callback = callback; + myEvent->nextEvent = NULL; + myEvent->previousEvent = NULL; + + + return myEvent; +} + +event *addEvent(char (*callback) (word counter), int noDuplicateCallback) +{ + + event *lastEvent; + event *myEvent; + + if (events == NULL) { + events = createEvent(callback); + return events; + } else { + lastEvent = events; + // TODO optimise this with noduplicate + while (lastEvent->nextEvent != NULL) { + if (noDuplicateCallback == 1 && lastEvent->callback == *callback) { + return NULL; + } + lastEvent = lastEvent->nextEvent; + } + if (noDuplicateCallback == 1 && lastEvent->callback == *callback) { + return NULL; + } + myEvent = createEvent(callback); + myEvent->previousEvent = lastEvent; + lastEvent->nextEvent = myEvent; + return myEvent; + } + + +} + +void removeEvent(event * eventElement) +{ + + byte alone = 0; + event *next, *previous; + + next = eventElement->nextEvent; + previous = eventElement->previousEvent; + + if (eventElement->nextEvent != NULL && eventElement->previousEvent != NULL) { + alone++; + next->previousEvent = previous; + previous->nextEvent = next; + + } else if (eventElement->nextEvent != NULL) { + alone++; + next->previousEvent = NULL; + events = next; + + } else if (eventElement->previousEvent != NULL) { + alone++; + previous->nextEvent = NULL; + } + + free(eventElement); + + if (alone == 0) { + events = NULL; + } +} + +void processEvents(void) +{ + + event *currentEvent; + char returnValue; + + currentEvent = events; + while (currentEvent != NULL) { + returnValue = currentEvent->callback(currentEvent->VBlankCount); + if (returnValue == EVENT_CONTINUE) { + currentEvent->VBlankCount++; + } else { + removeEvent(currentEvent); + } + currentEvent = currentEvent->nextEvent; + } + +} diff --git a/snes/wram/event.h b/snes/wram/event.h new file mode 100644 index 0000000..0f38195 --- /dev/null +++ b/snes/wram/event.h @@ -0,0 +1,17 @@ +typedef struct event { + word VBlankCount; + char (*callback) (word counter); + struct event *previousEvent; + struct event *nextEvent; +} event; + +#define EVENT_STOP 0 +#define EVENT_CONTINUE 1 + +extern event *events; + +void initEvents(void); +extern event *addEvent(char (*callback) (word counter), + int noDuplicateCallback); +extern void removeEvent(event * eventElement); +extern void processEvents(void); diff --git a/snes/wram/integer.h b/snes/wram/integer.h new file mode 100644 index 0000000..68843e0 --- /dev/null +++ b/snes/wram/integer.h @@ -0,0 +1,48 @@ +/*-------------------------------------------*/ +/* + * Integer type definitions for FatFs module + */ +/*-------------------------------------------*/ + +#ifndef _INTEGER + + +/* + * These types must be 16-bit, 32-bit or larger integer + */ +typedef int INT; +typedef unsigned int UINT; + +/* + * These types must be 8-bit integer + */ +typedef signed char CHAR; +typedef unsigned char UCHAR; +typedef unsigned char BYTE; + +/* + * These types must be 16-bit integer + */ +typedef short SHORT; +typedef unsigned short USHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; + +/* + * These types must be 32-bit integer + */ +typedef long LONG; +typedef unsigned long ULONG; +typedef unsigned long DWORD; + +/* + * Boolean type + */ +// enum { false = 0 , true } bool; + +//typedef int BOOL; +#define FALSE 0 +#define TRUE 1 + +#define _INTEGER +#endif diff --git a/snes/wram/main.c b/snes/wram/main.c new file mode 100644 index 0000000..94edd8f --- /dev/null +++ b/snes/wram/main.c @@ -0,0 +1,128 @@ + +#include +#include +#include + +#include "data.h"; +#include "pad.h"; +#include "event.h"; +#include "myEvents.h"; +#include "ressource.h"; +#include "PPU.h" +#include "debug.h" +#include "integer.h" + + + +typedef void (*FUNC) (void); + +padStatus pad1; + +void initInternalRegisters(void) +{ + characterLocation[0] = 0x0000; + characterLocation[1] = 0x0000; + characterLocation[2] = 0x0000; + characterLocation[3] = 0x0000; + debug_init(); +} + +void preInit(void) +{ + + // For testing purpose ... + // Insert code here to be executed before register init +} + +void halt(void) +{ + while (1); +} + +void wait(void) +{ + printfc("SNES::wait: press A to continue\n"); + enablePad(); + pad1 = readPad((byte) 0); + while (!pad1.A) { + waitForVBlank(); + pad1 = readPad((byte) 0); + } + printfc("SNES::wait: done\n"); +} + +void boot(DWORD addr) +{ + FUNC fn; + //printfc("SNES::boot addr=%lx\n", addr); + fn = (FUNC) addr; + fn(); + +} +void main(void) +{ + unsigned char i,j; + unsigned long addr; + initInternalRegisters(); + *(byte *) 0x2105 = 0x01; // MODE 1 value + *(byte *) 0x212c = 0x01; // Plane 0 (bit one) enable register + *(byte *) 0x212d = 0x00; // All subPlane disable + *(byte *) 0x2100 = 0x0f; // enable background + + debug_enable(); +#if 0 + addr = 0x008000; + for (i=0;i<28;i++){ + printfs(i,"ROW %02i %02X %08li %06lX",i,i,addr,addr); + printfc("ROW %02i %02X %08li %06lX\n",i,i,addr,addr); + addr += 0x10000; + } +#endif + +#define START_ADDR 0x020000 +#define END_ADDR 0x7f2000 + addr = 0x000000; + i=0; + j=0; + for (addr=START_ADDR; addr < END_ADDR; addr+=0x1000){ + if (addr > START_ADDR && addr%0x2000==0){ + //printfc("hit %06lx\n",addr); + addr += 0x10000 - 0x2000; + j++; + if (j>26) + j=0; + } + i++; + printfc("fill mem=%06lx tag=%02x tag=%i \n", addr, i, i); + *(byte *) (addr) = i; + } + i=0; + j=0; + for (addr=START_ADDR; addr < END_ADDR; addr+=0x1000){ + if (addr > START_ADDR && addr%0x2000==0){ + addr += 0x10000 - 0x2000; + i++; + j++; + if (j>26) + j=0; + } + printfs(j,"DUMP %06lX ",addr); + printc_packet(addr,16,(byte *) (addr)); + } + + + while (1) { + wait(); + } +} + +void IRQHandler(void) +{ + +} + +void NMIHandler(void) +{ + + // processEvents(); +} diff --git a/snes/wram/myEvents.c b/snes/wram/myEvents.c new file mode 100644 index 0000000..832c70d --- /dev/null +++ b/snes/wram/myEvents.c @@ -0,0 +1,103 @@ +#include "data.h"; +#include "pad.h"; +#include "event.h"; + +extern padStatus pad1; +extern word scrollValue; + +char fadeOut(word counter) +{ + static byte fadeOutValue; + + if (counter == 0) { + // init fade value + fadeOutValue = 0x0f; + } else { + fadeOutValue--; + } + + *(byte *) 0x2100 = fadeOutValue; + + if (fadeOutValue == 0x00) { + return EVENT_STOP; + } else { + return EVENT_CONTINUE; + } +} + +char fadeIn(word counter) +{ + static byte fadeInValue; + + if (counter == 0) { + // init fade value + fadeInValue = 0x00; + } else { + fadeInValue++; + } + + *(byte *) 0x2100 = fadeInValue; + + if (fadeInValue >= 0x0f) { + return EVENT_STOP; + } else { + return EVENT_CONTINUE; + } +} + +char mosaicOut(word counter) +{ + static byte mosaicOutValue; + + if (counter == 0) { + // init fade value + mosaicOutValue = 0xff; + } else { + mosaicOutValue -= 0x10; + } + + *(byte *) 0x2106 = mosaicOutValue; + + if (mosaicOutValue == 0x0f) { + return EVENT_STOP; + } else { + return EVENT_CONTINUE; + } +} + +char mosaicIn(word counter) +{ + static byte mosaicInValue; + + if (counter == 0) { + // init fade value + mosaicInValue = 0x0f; + } else { + mosaicInValue += 0x10; + } + + *(byte *) 0x2106 = mosaicInValue; + + if (mosaicInValue == 0xff) { + return EVENT_STOP; + } else { + return EVENT_CONTINUE; + } +} + +char NMIReadPad(word counter) +{ + pad1 = readPad((byte) 0); + + return EVENT_CONTINUE; +} + +char scrollLeft(word counter) +{ + scrollValue++; + + *(byte *) 0x210d = (byte) scrollValue; + *(byte *) 0x210d = (byte) (scrollValue >> 8); + + return EVENT_CONTINUE; +} diff --git a/snes/wram/myEvents.h b/snes/wram/myEvents.h new file mode 100644 index 0000000..0f2412a --- /dev/null +++ b/snes/wram/myEvents.h @@ -0,0 +1,6 @@ +char fadeOut(word counter); +char fadeIn(word counter); +char mosaicOut(word counter); +char mosaicIn(word counter); +char NMIReadPad(word counter); +char scrollLeft(word counter); diff --git a/snes/wram/pad.c b/snes/wram/pad.c new file mode 100644 index 0000000..9304eb1 --- /dev/null +++ b/snes/wram/pad.c @@ -0,0 +1,26 @@ +#include "data.h"; +#include "pad.h"; +#include "debug.h"; + +void enablePad(void) +{ + // Enable pad reading and NMI + *(byte *) 0x4200 = 0x01; +} + +void disablePad(void) +{ + // Enable pad reading and NMI + *(byte *) 0x4200 = 0x00; +} + +padStatus readPad(byte padNumber) +{ + word test; + padStatus *status; + padNumber = padNumber << 1; + test = (word) * (byte *) 0x4218 + padNumber << 8; + test |= (word) * (byte *) 0x4219 + padNumber; + status = (padStatus *) & test; + return *status; +} diff --git a/snes/wram/pad.h b/snes/wram/pad.h new file mode 100644 index 0000000..33fbde5 --- /dev/null +++ b/snes/wram/pad.h @@ -0,0 +1,20 @@ +typedef struct padStatus { + byte right:1; + byte left:1; + byte down:1; + byte up:1; + byte start:1; // Enter + byte select:1; // Space + byte Y:1; // X + byte B:1; // C + // -------------------------------- + byte Dummy:4; + byte R:1; // Z + byte L:1; // A + byte X:1; // S + byte A:1; // D +} padStatus; + +extern void enablePad(void); +extern void disablePad(void); +extern padStatus readPad(byte padNumber); diff --git a/snes/wram/ressource.asm b/snes/wram/ressource.asm new file mode 100644 index 0000000..64712dd --- /dev/null +++ b/snes/wram/ressource.asm @@ -0,0 +1,9 @@ +ressource .section + + + XDEF ~~debugFont_pic +~~debugFont_pic + INSERT ressource/debugFont.pic + + +.ends diff --git a/snes/wram/ressource.h b/snes/wram/ressource.h new file mode 100644 index 0000000..7f65ed4 --- /dev/null +++ b/snes/wram/ressource.h @@ -0,0 +1,2 @@ + +extern word debugFont_pic[]; diff --git a/snes/wram/ressource/debugFont.clr b/snes/wram/ressource/debugFont.clr new file mode 100644 index 0000000..aad4428 Binary files /dev/null and b/snes/wram/ressource/debugFont.clr differ diff --git a/snes/wram/ressource/debugFont.pcx b/snes/wram/ressource/debugFont.pcx new file mode 100644 index 0000000..9a481e0 Binary files /dev/null and b/snes/wram/ressource/debugFont.pcx differ diff --git a/snes/wram/ressource/debugFont.pic b/snes/wram/ressource/debugFont.pic new file mode 100644 index 0000000..ea179dc Binary files /dev/null and b/snes/wram/ressource/debugFont.pic differ diff --git a/snes/wram/ressource/debugFont.xcf b/snes/wram/ressource/debugFont.xcf new file mode 100644 index 0000000..e38f416 Binary files /dev/null and b/snes/wram/ressource/debugFont.xcf differ diff --git a/snes/wram/wram.bnk b/snes/wram/wram.bnk new file mode 100644 index 0000000..ad25a06 --- /dev/null +++ b/snes/wram/wram.bnk @@ -0,0 +1,91 @@ + +Sections: +org=00000000 siz=00001BAF end=00001BAF 'CODE' +org=00001BAF siz=00000394 end=00001F43 'DATA' +org=00000000 siz=00000B1C end=00000B1C 'UDATA' +org=00007FE4 siz=0000001C end=00008000 'vectors' +org=00007FB0 siz=00000030 end=00007FE0 'registration_data' +org=00008000 siz=00000800 end=00008800 'ressource' + +Module map: +ROM:00000000 0000013B REL:00008000 0000813B S=CODE M=StartupSnes.obj F=StartupSnes.obj +ROM:00000000 00000002 REL:00000000 00000002 S=UDATA M=main.obj F=main.obj +ROM:00000002 00000004 REL:00000002 00000004 S=UDATA M=pad.obj F=pad.obj +ROM:00000004 00000010 REL:00000004 00000010 S=UDATA M=PPU.obj F=PPU.obj +ROM:00000010 00000910 REL:00000010 00000910 S=UDATA M=debug.obj F=debug.obj +ROM:0000013B 0000030E REL:0000813B 0000830E S=CODE M=main.obj F=main.obj +ROM:0000030E 00000390 REL:0000830E 00008390 S=CODE M=pad.obj F=pad.obj +ROM:00000390 000005CC REL:00008390 000085CC S=CODE M=PPU.obj F=PPU.obj +ROM:000005CC 00000AB8 REL:000085CC 00008AB8 S=CODE M=debug.obj F=debug.obj +ROM:00000910 00000914 REL:00000910 00000914 S=UDATA M=sbrk F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00000914 00000918 REL:00000914 00000918 S=UDATA M=_mem_start F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00000918 00000B18 REL:00000918 00000B18 S=UDATA M=_format F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00000AB8 00000B06 REL:00008AB8 00008B06 S=CODE M=sbrk F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00000B06 00000B32 REL:00008B06 00008B32 S=CODE M=memset F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00000B18 00000B1C REL:00000B18 00000B1C S=UDATA M=_close_stdio F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00000B32 00000B50 REL:00008B32 00008B50 S=CODE M=strlen F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00000B50 00000BAD REL:00008B50 00008BAD S=CODE M=vsprintf F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00000BAD 00000BCE REL:00008BAD 00008BCE S=CODE M=~fmov F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00000BCE 00000BEE REL:00008BCE 00008BEE S=CODE M=~fnmov F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00000BEE 00000BF6 REL:00008BEE 00008BF6 S=CODE M=~lcal F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00000BF6 00000BFE REL:00008BF6 00008BFE S=CODE M=~lsr F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00000BFE 000013E6 REL:00008BFE 000093E6 S=CODE M=_format F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:000013E6 00001400 REL:000093E6 00009400 S=CODE M=~ludv F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00001400 00001415 REL:00009400 00009415 S=CODE M=~lumd F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00001415 00001436 REL:00009415 00009436 S=CODE M=~swt F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00001436 000016E0 REL:00009436 000096E0 S=CODE M=_flsbuf F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:000016E0 000017A9 REL:000096E0 000097A9 S=CODE M=_getbuf F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:000017A9 00001886 REL:000097A9 00009886 S=CODE M=malloc F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00001886 000018C7 REL:00009886 000098C7 S=CODE M=~comdiv F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:000018C7 000018FB REL:000098C7 000098FB S=CODE M=~udv F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:000018FB 0000193B REL:000098FB 0000993B S=CODE M=_closeall F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:0000193B 00001A3E REL:0000993B 00009A3E S=CODE M=fclose F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00001A3E 00001ABB REL:00009A3E 00009ABB S=CODE M=fflush F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00001ABB 00001B84 REL:00009ABB 00009B84 S=CODE M=free F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00001B84 00001BA9 REL:00009B84 00009BA9 S=CODE M=strcpy F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00001BA9 00001BAF REL:00009BA9 00009BAF S=CODE M=~umd F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00001BAF 00001C0F REL:00009BAF 00009C0F S=DATA M=main.obj F=main.obj +ROM:00001C0F 00001C8C REL:00009C0F 00009C8C S=DATA M=debug.obj F=debug.obj +ROM:00001C8C 00001CAE REL:00009C8C 00009CAE S=DATA M=_format F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00001CAE 00001DAF REL:00009CAE 00009DAF S=DATA M=_ctype F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00001DAF 00001F3F REL:00009DAF 00009F3F S=DATA M=_iob F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00001F3F 00001F43 REL:00009F3F 00009F43 S=DATA M=fclose F=/home/david/.wine/drive_c/65xx_FreeSDK/lib/cl.lib +ROM:00007FB0 00007FE0 REL:0000FFB0 0000FFE0 S=registrati M=StartupSnes.obj F=StartupSnes.obj +ROM:00007FE4 00008000 REL:0000FFE4 00010000 S=vectors M=StartupSnes.obj F=StartupSnes.obj +ROM:00008000 00008800 REL:00018000 00018800 S=ressource M=ressource.obj F=ressource.obj + +TOTSTRINGS=1191 + CACHE: 0 + OBJMOD: 1914 + SECMAP: 200 +SECINFO: 6720 + SYMTAB: 576 + OUTPUT: 0 + STRING: 2836 + SYMBOL: 1782 +SECTION: 528 + FILE: 112 +TOTMEM: 14668 + +Section: ORG: ROM ORG: SIZE: +CODE 008000 000000 1BAFH ( 7087) +DATA 009BAF 001BAF 394H ( 916) +UDATA 000000 ------ B1CH ( 2844) +vectors 00FFE4 007FE4 1CH ( 28) +registra 00FFB0 007FB0 30H ( 48) +ressourc 018000 008000 800H ( 2048) +Total 32ABH ( 12971) + + +TOTSTRINGS=1191 + CACHE: 17580 + OBJMOD: 1914 + SECMAP: 200 +SECINFO: 6720 + SYMTAB: 576 + OUTPUT: 0 + STRING: 2836 + SYMBOL: 1782 +SECTION: 528 + FILE: 112 +TOTMEM: 32248