Browse Source

o add bankselect test for logic analyser test

optixx 15 years ago
parent
commit
d229719d0c

+ 79 - 0
snes/bankselect/Makefile

@@ -0,0 +1,79 @@
+# SDK Config
+
+
+PLATFORM=mac
+
+ifeq ($(PLATFORM),linux)
+
+    # Linux Wine 
+    SDK=/home/david/.wine/drive_c/65xx_FreeSDK
+    WINE=wine
+    EMU=zsnes
+    EMU_DEBUG=/home/david/Devel/arch/snes/tools/zsnes_linux_debug151/src/zsnesd -d 
+else
+    # Mac Wine 
+    SDK=/Users/david/.wine/drive_c/65xx_FreeSDK
+    WINE=wine
+    EMU=zsnes
+endif
+
+CC=$(WINE) $(SDK)/bin/WDC816CC.exe
+AS=$(WINE) $(SDK)/bin/WDC816AS.exe
+LD=$(WINE) $(SDK)/bin/WDCLN.exe
+PADBIN=$(WINE) tools/padbin.exe
+PCX2SNES=$(WINE) tools/Pcx2Snes.exe
+
+
+
+# Project
+
+INC=$(SDK)/include
+LIBS=$(SDK)/lib/cc
+#OBJS=StartupSnes.obj main.obj pad.obj event.obj myEvents.obj PPU.obj debug.obj ressource.obj
+OBJS=StartupSnes.obj main.obj pad.obj PPU.obj debug.obj ressource.obj crc.obj
+APP=banks.smc
+GFX=kungfu debugfont
+
+all:  $(APP)
+
+run:  
+	$(EMU) $(APP)
+
+debugger:  
+	$(EMU_DEBUG) $(APP)
+
+upload:
+	ucon64 $(APP)
+	cp -rv $(APP) /Volumes/SNES
+	sync
+	diskutil unmount /Volumes/SNES
+
+crc:
+	python ../../scripts/crc_xmodem.py $(APP)
+
+kungfu:
+		$(PCX2SNES) ressource/kungfu -n -c16 -screen
+
+debugfont:
+		$(PCX2SNES) ressource/debugFont -n -c16 -s8 -o1
+
+StartupSnes.obj: StartupSnes.asm
+		$(AS) -V $?
+
+ressource.obj: ressource.asm
+		$(AS) -V $?
+
+%.obj: %.c
+		$(CC)  -wl -wp -sop -MC -I $(INC) $?
+
+$(APP): $(OBJS)
+		$(LD) -HB -M21 -V -T -Pff \
+                -C008000,0000 -U0000,0000 \
+                -Avectors=FFE4,7FE4 \
+                -Aregistration_data=FFB0,7FB0 \
+                -Aressource=18000,8000 \
+                -N $(OBJS) -L$(LIBS) -O $@
+		$(PADBIN) 0x40000 $(APP)
+
+clean:
+		rm -vf $(APP) *.obj

+ 80 - 0
snes/bankselect/PPU.c

@@ -0,0 +1,80 @@
+#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;
+}

+ 11 - 0
snes/bankselect/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);

+ 240 - 0
snes/bankselect/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	$08
+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
+

+ 37 - 0
snes/bankselect/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;
+}

+ 4 - 0
snes/bankselect/crc.h

@@ -0,0 +1,4 @@
+
+word crc_update (byte *data, word size);
+word crc_update_mem (unsigned long, word size);
+

+ 2 - 0
snes/bankselect/data.h

@@ -0,0 +1,2 @@
+typedef	unsigned char	byte;
+typedef	unsigned short	word;

+ 60 - 0
snes/bankselect/debug.c

@@ -0,0 +1,60 @@
+#include "data.h"
+#include "pad.h"
+#include "PPU.h"
+#include "ressource.h"
+#include "crc.h"
+
+word debugMap[0x400];
+void initDebugMap(void) {
+	word i;
+	for(i=0; i<0x400; i++) {
+		debugMap[i] = 0x00;
+	}
+}
+
+char hex_chars[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
+
+void int2hex(unsigned long number, char *buf,word size)
+{
+    /*
+    long a;
+    for (a = 0; a < size; ++a) {
+        buf[a] = (i >> ((long)size * (2 * 2 - 1 - a))) & 0xf;
+        if (buf[a] < 10)
+            buf[a] += '0';
+        else
+            buf[a] += 'A' - 10;
+    }
+    */
+    //buf[a] = 0;
+    
+    
+    unsigned long n;
+    unsigned char i;
+    //unsigned char x;
+    for (i = 0; i < size; i++) {
+        n = number >> 4;
+        //x = (number - (n << 4));
+        buf[size-i-1] = hex_chars[(number - (n << 4))]; 
+        number = n;    
+    }
+
+}
+
+void writeln(char *buffer,word y){
+    char i;
+    waitForVBlank();
+	for(i=0; i<32; i++) {
+		waitForVBlank();
+		VRAMByteWrite((byte) (buffer[i]-32), (word) (0x4000+i+(y*0x20)));
+	}
+}
+
+void enableDebugScreen(void){
+	VRAMLoad((word) debugFont_pic, 0x5000, 2048);
+	CGRAMLoad((word) debugFont_pal, (byte) 0x00, (word) 16);
+	VRAMLoad((word) debugMap, 0x4000, 0x0800);
+	setTileMapLocation(0x4000, (byte) 0x00, (byte) 0);
+	setCharacterLocation(0x5000, (byte) 0);
+	*(byte*) 0x2100 = 0x0f; // enable background
+}

+ 5 - 0
snes/bankselect/debug.h

@@ -0,0 +1,5 @@
+void initDebugMap(void);
+void debug(void);
+void int2hex(unsigned long i, char *buf,word size);
+void writeln(char* line,word y);
+void enableDebugScreen(void);

+ 101 - 0
snes/bankselect/event.c

@@ -0,0 +1,101 @@
+#include <stdlib.h>
+
+#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;
+	}
+
+}

+ 16 - 0
snes/bankselect/event.h

@@ -0,0 +1,16 @@
+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);

+ 10 - 0
snes/bankselect/hex.py

@@ -0,0 +1,10 @@
+
+number=0xffaaee
+size = 6
+print hex(number)
+
+for i in range(0,size):
+    n = number >> 4;
+    print size-i-1,  hex(number - (n << 4));
+    number = n;
+

+ 71 - 0
snes/bankselect/main.c

@@ -0,0 +1,71 @@
+#include "data.h";
+#include "pad.h";
+#include "event.h";
+#include "myEvents.h";
+#include "ressource.h";
+#include "PPU.h"
+#include "debug.h"
+#include "crc.h"
+
+
+#include <stdlib.h>
+
+padStatus pad1;
+
+void initInternalRegisters(void) {
+	characterLocation[0] = 0x0000;
+	characterLocation[1] = 0x0000;
+	characterLocation[2] = 0x0000;
+	characterLocation[3] = 0x0000;
+	initDebugMap();
+}
+
+void preInit(void) {
+	// For testing purpose ... 
+	// Insert code here to be executed before register init
+}
+
+void main(void) {
+	word i,j;
+	word crc01;
+	word crc02;
+    padStatus pad1;       //012345678901234567890123456789012
+	char line_header[32] = "BANK ADDR   VAL 123456789ABCDEF";
+    char line[32] = "                             ";	
+    char space; 
+    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
+
+    enablePad();    
+    enableDebugScreen();
+    writeln(line_header,0);
+
+	while(1){
+		addr = 0x018000;
+		for(j=1; j<16; j++) {
+			int2hex((unsigned long)j,&line[0],4);
+			int2hex((unsigned long)addr,&line[5],6);
+			int2hex((unsigned long)*(byte*)addr,&line[12],4);
+            writeln(line,j+1);
+    		addr+= 0x010000;
+        	pad1 = readPad((byte) 0);
+        		while(!pad1.start) {
+    			//waitForVBlank();
+    			pad1 = readPad((byte) 0);
+    		}
+        }
+    }
+	while(1);
+}
+
+void IRQHandler(void) {
+}
+
+void NMIHandler(void) {
+	//processEvents();
+}

+ 97 - 0
snes/bankselect/myEvents.c

@@ -0,0 +1,97 @@
+#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;
+}

+ 6 - 0
snes/bankselect/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);

+ 17 - 0
snes/bankselect/pad.c

@@ -0,0 +1,17 @@
+#include "data.h";
+#include "pad.h";
+
+void enablePad(void) {
+	// Enable pad reading and NMI
+	*(byte*)0x4200 = 0x81;
+}
+
+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;
+}

+ 19 - 0
snes/bankselect/pad.h

@@ -0,0 +1,19 @@
+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 padStatus readPad(byte padNumber);

+ 23 - 0
snes/bankselect/ressource.asm

@@ -0,0 +1,23 @@
+ressource	.section
+
+;	XDEF __title_map
+;__title_map:
+;	INSERT ressource/kungfu.map
+;
+;	XDEF __title_pic
+;__title_pic:
+;	INSERT ressource/kungfu.pic
+;	
+;	XDEF __title_pal	
+;__title_pal:
+;make	INSERT ressource/kungfu.clr
+
+	XDEF _~debugFont_pic
+_~debugFont_pic
+	INSERT ressource/debugFont.pic
+
+	XDEF _~debugFont_pal
+_~debugFont_pal
+	INSERT ressource/debugFont.clr
+
+.ends

+ 3 - 0
snes/bankselect/ressource.h

@@ -0,0 +1,3 @@
+
+extern word debugFont_pic[];
+extern word debugFont_pal[];

BIN
snes/bankselect/ressource/debugFont.clr


BIN
snes/bankselect/ressource/debugFont.pcx


BIN
snes/bankselect/ressource/debugFont.pic


BIN
snes/bankselect/ressource/debugFont.xcf


BIN
snes/bankselect/ressource/kungfu.clr


BIN
snes/bankselect/ressource/kungfu.pcx


BIN
snes/bankselect/ressource/kungfu.pic


BIN
snes/bankselect/tools/Pcx2Snes.exe


BIN
snes/bankselect/tools/padbin.exe