From d229719d0c9d6de831b62694b2380d540ee51edb Mon Sep 17 00:00:00 2001 From: optixx Date: Sun, 26 Apr 2009 16:24:04 +0200 Subject: [PATCH] o add bankselect test for logic analyser test --- snes/bankselect/Makefile | 79 ++++++++ snes/bankselect/PPU.c | 80 ++++++++ snes/bankselect/PPU.h | 11 ++ snes/bankselect/StartupSnes.asm | 240 ++++++++++++++++++++++++ snes/bankselect/crc.c | 37 ++++ snes/bankselect/crc.h | 4 + snes/bankselect/data.h | 2 + snes/bankselect/debug.c | 60 ++++++ snes/bankselect/debug.h | 5 + snes/bankselect/event.c | 101 ++++++++++ snes/bankselect/event.h | 16 ++ snes/bankselect/hex.py | 10 + snes/bankselect/main.c | 71 +++++++ snes/bankselect/myEvents.c | 97 ++++++++++ snes/bankselect/myEvents.h | 6 + snes/bankselect/pad.c | 17 ++ snes/bankselect/pad.h | 19 ++ snes/bankselect/ressource.asm | 23 +++ snes/bankselect/ressource.h | 3 + snes/bankselect/ressource/debugFont.clr | Bin 0 -> 2 bytes snes/bankselect/ressource/debugFont.pcx | Bin 0 -> 3154 bytes snes/bankselect/ressource/debugFont.pic | Bin 0 -> 2048 bytes snes/bankselect/ressource/debugFont.xcf | Bin 0 -> 6237 bytes snes/bankselect/ressource/kungfu.clr | Bin 0 -> 512 bytes snes/bankselect/ressource/kungfu.pcx | Bin 0 -> 7706 bytes snes/bankselect/ressource/kungfu.pic | Bin 0 -> 7136 bytes snes/bankselect/tools/Pcx2Snes.exe | Bin 0 -> 98816 bytes snes/bankselect/tools/padbin.exe | Bin 0 -> 16095 bytes 28 files changed, 881 insertions(+) create mode 100644 snes/bankselect/Makefile create mode 100644 snes/bankselect/PPU.c create mode 100644 snes/bankselect/PPU.h create mode 100644 snes/bankselect/StartupSnes.asm create mode 100644 snes/bankselect/crc.c create mode 100644 snes/bankselect/crc.h create mode 100644 snes/bankselect/data.h create mode 100644 snes/bankselect/debug.c create mode 100644 snes/bankselect/debug.h create mode 100644 snes/bankselect/event.c create mode 100644 snes/bankselect/event.h create mode 100644 snes/bankselect/hex.py create mode 100644 snes/bankselect/main.c create mode 100644 snes/bankselect/myEvents.c create mode 100644 snes/bankselect/myEvents.h create mode 100644 snes/bankselect/pad.c create mode 100644 snes/bankselect/pad.h create mode 100644 snes/bankselect/ressource.asm create mode 100644 snes/bankselect/ressource.h create mode 100644 snes/bankselect/ressource/debugFont.clr create mode 100644 snes/bankselect/ressource/debugFont.pcx create mode 100644 snes/bankselect/ressource/debugFont.pic create mode 100644 snes/bankselect/ressource/debugFont.xcf create mode 100644 snes/bankselect/ressource/kungfu.clr create mode 100644 snes/bankselect/ressource/kungfu.pcx create mode 100644 snes/bankselect/ressource/kungfu.pic create mode 100644 snes/bankselect/tools/Pcx2Snes.exe create mode 100644 snes/bankselect/tools/padbin.exe diff --git a/snes/bankselect/Makefile b/snes/bankselect/Makefile new file mode 100644 index 0000000..d08191a --- /dev/null +++ b/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 diff --git a/snes/bankselect/PPU.c b/snes/bankselect/PPU.c new file mode 100644 index 0000000..e61b481 --- /dev/null +++ b/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; +} \ No newline at end of file diff --git a/snes/bankselect/PPU.h b/snes/bankselect/PPU.h new file mode 100644 index 0000000..36ecef9 --- /dev/null +++ b/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); \ No newline at end of file diff --git a/snes/bankselect/StartupSnes.asm b/snes/bankselect/StartupSnes.asm new file mode 100644 index 0000000..e856c70 --- /dev/null +++ b/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 + diff --git a/snes/bankselect/crc.c b/snes/bankselect/crc.c new file mode 100644 index 0000000..8c951a0 --- /dev/null +++ b/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> ((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 +} \ No newline at end of file diff --git a/snes/bankselect/debug.h b/snes/bankselect/debug.h new file mode 100644 index 0000000..3465a39 --- /dev/null +++ b/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); \ No newline at end of file diff --git a/snes/bankselect/event.c b/snes/bankselect/event.c new file mode 100644 index 0000000..1c62c4a --- /dev/null +++ b/snes/bankselect/event.c @@ -0,0 +1,101 @@ +#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/bankselect/event.h b/snes/bankselect/event.h new file mode 100644 index 0000000..76b07dc --- /dev/null +++ b/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); diff --git a/snes/bankselect/hex.py b/snes/bankselect/hex.py new file mode 100644 index 0000000..12355e5 --- /dev/null +++ b/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; + diff --git a/snes/bankselect/main.c b/snes/bankselect/main.c new file mode 100644 index 0000000..78f17bd --- /dev/null +++ b/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 + +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(); +} diff --git a/snes/bankselect/myEvents.c b/snes/bankselect/myEvents.c new file mode 100644 index 0000000..92c78ac --- /dev/null +++ b/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; +} \ No newline at end of file diff --git a/snes/bankselect/myEvents.h b/snes/bankselect/myEvents.h new file mode 100644 index 0000000..719abe7 --- /dev/null +++ b/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); \ No newline at end of file diff --git a/snes/bankselect/pad.c b/snes/bankselect/pad.c new file mode 100644 index 0000000..2b86eac --- /dev/null +++ b/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; +} diff --git a/snes/bankselect/pad.h b/snes/bankselect/pad.h new file mode 100644 index 0000000..e5a907f --- /dev/null +++ b/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); diff --git a/snes/bankselect/ressource.asm b/snes/bankselect/ressource.asm new file mode 100644 index 0000000..6802a07 --- /dev/null +++ b/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 diff --git a/snes/bankselect/ressource.h b/snes/bankselect/ressource.h new file mode 100644 index 0000000..8298c7e --- /dev/null +++ b/snes/bankselect/ressource.h @@ -0,0 +1,3 @@ + +extern word debugFont_pic[]; +extern word debugFont_pal[]; diff --git a/snes/bankselect/ressource/debugFont.clr b/snes/bankselect/ressource/debugFont.clr new file mode 100644 index 0000000000000000000000000000000000000000..09f370e38f498a462e1ca0faa724559b6630c04f GIT binary patch literal 2 JcmZQz0000200961 literal 0 HcmV?d00001 diff --git a/snes/bankselect/ressource/debugFont.pcx b/snes/bankselect/ressource/debugFont.pcx new file mode 100644 index 0000000000000000000000000000000000000000..9a481e084bc507111f54174d01131fa9268d0117 GIT binary patch literal 3154 zcmeH}Yi`^y41{F^MT??G$^8!?KawWfGqg9^&Nn1wyImB>?`C%`$$Sil6m9L-Pt%vC z&wcvbo~EaX^}9Y(o8RwrM7U4a@5}TyEp45)w)ooH^xU-CB;9p&U7JLU=3i4s%W}a= zzs0{;*NDE{U$x#7yyLJ7@tDHJAXijEKK@0-5%+rA6{?FRA))Z9?AomKG|bj$RuXNS zHFPbR7tJ==Syo_0KkTcH<(ic#V@j)6hK4LrX9ph3p*hIri!X4Sq&~JMN)37t`Lc@fl1J z^$RWTJ*uie(W&fS_lCs1z~x`OYNNBXf8SbRYc{Kk8>G8vMKCu9U0rWMSt-E+;`t$A z-+Kphh1rD!Uc(diAvhk7lXs>rs51l{j##lT#Y1F;WU^kVq^knZ$2YySA|D^DH;K+i zJ4Zb-a@=+Bo=#&LERNz_MaR*TOMBME8PCk02r&7@>79o?do6)A1Ndwg)@kOOVOFXE e$`Su8mYUo)-}K++-tPJwe{w!n9~Jm-D)1XJOx*kc literal 0 HcmV?d00001 diff --git a/snes/bankselect/ressource/debugFont.pic b/snes/bankselect/ressource/debugFont.pic new file mode 100644 index 0000000000000000000000000000000000000000..ea179dc0fc59ef93fe15239af9bb545c4bab84b1 GIT binary patch literal 2048 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 GFaHBIqLwfK literal 0 HcmV?d00001 diff --git a/snes/bankselect/tools/Pcx2Snes.exe b/snes/bankselect/tools/Pcx2Snes.exe new file mode 100644 index 0000000000000000000000000000000000000000..de0917252720a69ae1c40f584b75e40e1423ed33 GIT binary patch literal 98816 zcmeFaeSBP1wLd&bCUjb+oPa4r?3Dm1Zw0Itw6#a|{?Qb=fR3RZ7{UWrmQaI2mpxtc4H1`N#e{jRmonKP55 z!0-C}@jM?2Idk^jYp=cb+H0@9_S!F};e+cV6_H3Jiobk566wM(|0U#kV$9ep zI?Ez;Bz2sB=QiECvI%KVp9Ub(#kv~0{VcVS$l`OCFS(`ZmPq8vw;+~vug34$_znF_ zAmv;Ii%gx1gvCf_r3fGTmjHLp{g?t?I{^usksiZudJMSbx8DAVk3=F3aioI>kz??? zY!uvuh<)?l|A#r?UHjHZ#M@Gd$JMBY_ZGf=4#MI6@I*ZBL-TuocpDy9A0LVAd*lBW zIRo~Fj^Z{zzgT!)Y;c}-`1JKKw49v&SoCDfhb?)dg|Mdx(tOeA5k&?SdME4nzA$Ux^p`N=GtAS)AAo z%@jvpnId@NDJV4Ic*=eJ13m?%c>$w&Pu9Gu2qkZi>t}Z~yHABZP%DJgp@dreO?4u8 z*2uFOZ&mn}r@@^av(`Q#FeUn{#%UN};scU6LOe$IVW1e94dT`=Lmc?vG*nkK)L9QS4B%&a z4@MkF76Ecc2|%^RfMwMcNx&uDisXpCh4c0xssaO)lN>}kt6h;Cs$gx_sv`DUMY&X$ zQP6Tp+AtnvlN;>j4FUHzcn70oKmbSPZ%DcSA?+8po9iN0+ZRNa+^>i? z@yBp+69}H2++^iGArPBGNt+>Hvy+>x+*Q)L_xJQ4-kgEer`f`5!;}r ze^NF%XgAj+tjxv8ZZ}V@wK5mT+vZv;cLLtPOs8Q}&$E>k4V#@s8?w<3Px~OF?Vj2~ z%Dj#i?`g?f11u*iK42aP3u~lBuM0pk^0o;@|8IzRuV7&XRI!etw4@G+;yTcRms+DI zHf##2oloBHeFF;2Ta8C+bFFCewxj^p&IccRlN%B6TW6zosw%L4PI9BQcB%kw^qb+- zMT1U~q4w&S_X|i{W1=yVOKwlOPr|-~(a@NnttBzFqFUmaZslrka+u}xChte%7P{s( zhCCJn08Q}$G$a60u?=Nqy~$00^ob2b=~PVBdXt+&Nr5O;Ajxjt9I-OAGwkL~c&o&l z*C*6FNlF>JpU`~!^->Gc90!n5ARe1~6rZ-u27_|wArV&EM+5d4gziZNWKyC$dZdd= z-po5j<=y7z{gMpoadhB{Y8or3t6y#etjmj8wLzXlPn zCH|$^3*s+z7)$(-h2sC`S0Mhsz{74HhGwE1ILU2?`)ER!c{-wOlK|9Mk)CWFScqg% zmFN*rhzF-rKBC#oLx+KGC!dffTD9rhIfUJKg`~rl`W#vd>a3?fDjB!<8MjMDK9TWM zX1t#nPt}Z$AWpf5V8H1_V5W};rQhTu*(*r+1QLvpk@NtO{PuFmf7aJ>t`6-wsLIaH)|b%2>)>q*DZ6PA>L?Y<*7ZCat;k7@?j@ZVg~Jr(qpjXP4ozF|=*{c^1PFj+R)-}+^4lsI z*4iZi7?b58`J6)}A^9w@F!Q!h63cV$Wd%W3UW)g&v+1+a^j%2czuwIKhA<*B=yy zT9R+3mcl}bkpA$PNV`P(wajMrOI~@3Kue8tQsbWpdk+8r>_M3Xf@p_ZU!`1;Xn!E* z1Q4>-Ge^>`wN+9wc_R6#EewgGI81F=Q{lV-GJi#erOy#z@jIBvtLayg`)kt2jOHmc z)n;ibX@>%3V`I+TCiN?VHAQ2(AeKq5Py&>B?;-&Xk-;iU-g~76@eb!+Dd)Lp#p4w@ z*1+-mS6Iiz8%BQeb9)}TAAyVo4DNmnI zQl4V3)%|WmTcqi1hGm$Ej8H@TP$V%P?vyI{SAn!b&mS#SLZG#ln%$+DTZ=S$QtA513N!^WBKYI51^Ce#A&5}LrK=R!B1#M6Hzim&;13934ypCluo{c; zkZPDJur}@&#F&B1=n(WIq!<>Fuf2BpLDgP6G&tI=Vh=RIe8UV8hM!KW;1qKq&AH^Z zlsh>^q;ca`LCTwslWXkeH88^{djehq2zP;k zL!Dj)?XBhC3JANo8kC%kx00z0W+t!~)QVk`YK*vFkYIRv#C^F2V# zLX>z!E4szkjA`rEo@bBBMd5JS45L!~3YkUgtu~n03Ynn)^(Thmk~if})JpW+x*oI7 z&4Bc0pa0lmzHu2FG3K3s(!Cd{e}9RGwC`u$&Lq>mB%t7}tAcO`Uap}KaYL=mLuyE0 zQs6M0-MJ_h6X;S|7%R7*E6Xl||E)Ok<@Z||uEquP^+9sF1ghs{`j$?G$7;VgWGXB6 zi*IK5o$$L9AuJoKlrsDElv4J3OR0{HE(CF}T?YJ0N36(*(=Y^QHHXA+qcwcK%Y-ln zuQ&VzZO00CpgZQV-{0^)X~y*J3|uLJXnGj~^(L^Mf%8nDn}O3!-~aLu1HUqXGz0rgU;_h>n7{!B{>=mqG4M?jsQv^38%>~& z0mlT+W8f|mXky@#Ca|4>B_=Syz;z~Y#xevh(}2&q)`3+}B$V3B2Izl^R&S;qZ+OAm zAu|@4Ri)m{Mn4HI5YZwcgR>;F8%IzdNb!Ch6Nb2 zfVAW*AApr$0Ow$Y^?d^S|-0+!0jc9=3OzoK2hu2o}^Gt(!B0%Y&xGitTba?t?D zc|QWJlG1`VtBu|`4U6I&gQ!cwL_ItiMEwAHMicc3D|2m0g7D~HM8`+PdpC%sO<=$< zJ1E7i9nFJ24E+J;uVQiYO0X&qmivSE&^S%FE{y0XBBI@GJuE$kI;^e)Z_2$foaHGP z4dS8=S2dNB>?yZPjQg1P6_}{XTv!vdAnfJ=u$8-8Og{#Bg+endG@YQ1I1Q3PWwwNY z=YAKe^#@RLfKxK03G+9M?aZ)=f$xVioFN%RjaV62Xvi(y!^+SrAQWY2zoa)a>-P+v zJ_a_MfXl#*VWdwT&8$PHj3q)yX@a?v6=l-8lZr*#Q0wZ4!@^XBGDE_ap)V&rz>>~1 z#nyfjfvF~N1p}4_%sP+KK9l)UO#PqtC=b>!aL5F@72 z3dyB8t-*Af*k%Z}ST3^}?1VHa!cdg_bM{+pG8dJ{P7GJtU*=~svtA3mkiQl_7@(J_?E}JJCr1L0P|ClDN=XjC zjv7$-wTOx%l%S3$smFt%5=6N>Id-plM=EvS;g_(Mn~`;C6Q3N`$hH$uRC+tvojhM; zRU4CQxTQFhLw>Aa!1A%z2n=B@BBM%Bf%^{2Fk|ux+e{Rfm*I+p>za&rL^ynCEQyB0 zp_OPYX&Lgh?qnNipSBS0&8&f3CGh5H7iX{*!PcE@xG-Q_F(88k1nvo{6%|(t;(9Yo zIbC*=5CDQ*$fD=GKqSedkU*Jd+yK;lO}HPy5?Bcar! zZ?#MP(W3(^;Y@T{9jPu1c#y&j4F!w#bOdS2T`gr)QOmwn0Esr`-l3&vKmAPkDbv?=C25qgVU@9fx<+iI8HSYtGAWJvri{4lmxeYos`->4JvEqOYxfUh$bk4%h67FgOaTUD&GciLBDTV)LuZeaSv?} zqz{JDBbx5pD8sD!8rW$Rr|M4^@SGvaIF`+ysonJ_D5>+Ypt>PGpV)~e4sn|Rq#h#(L?Umf=!5Ky)_7Nb*)Rg<6 zOaV9@?oGh^5GEO3hN7u}9>f8?I1AXh`ObQte!-c-706`ot}X(VCif5S6wbzka&dvF zBv%+e_i+ez`f^I(e0dW7M`gXa2EcwXAZfK^ssfY5XClsWyEzWF!@UYVj(D~53(#I& zIOc?#ZhFjq#IgHr@J*Iw{lf5DOds-+lh|i6y5^cm=+jLILx7CDSXm3EVWo{Tdw1=z z5iXHurXi4CSWiJn*Q3$X^Z8!x{zAO)AzA3GLv9FI=Nb5&4bMWxh=^ZtI1UZh*h2X! zTLEY9p2|XQK_PZ?6GFr&Y7{RfJDe!;__n za4W#$x=DhuvdXjXk>k2$mFMB5laJYzv+%TRI@l#*3&Zx@8F->mAxcE#OlCM+A2s{- zN4A`Sa3>>KEOw=!R6|^q5W@3h@`A$@0ckjY1sbcVA^1{*Y+Hz<5od2VpN)D$&PMER zD36!l4i4j7OK}2@XrXibR@2ytk?p)78_uom@{@q2w$OWu``7F2|8eR6ah%G6@A{>E{blW=NrxxPQfFH(_(QPB@;b5G#f|D?mkA6hTzu8Cx^U0KmmXQ1?o!s z|LdfW`iZ;Kis>R(T&i1pca4xxtZ75~qguw70f4gWM6Ap|37N&{+%LQ=)%23$;-;2A zSu#-NQG;T492yN}?j^wP7<%l9cq`UOBN#GDHPUSKYhNQ>AP%e18fnmIq`^QV`P2=f zP(2mN!W+xS&`JJ|Kc7SC{TEUd8lCi*_`pZ$r27F=tdlkiV6m>41yM);f5z7@IGeeu zfV|ATeT+O&$x{V&ae^M10&yiU*{`Eph`j!xX z4~m;R#9w5z-CDIN?3L9Oz9N;aE$Z35M2H%0T`Bs-%5V`3Vr#FgfegsdQl$mm7Aojd zr3HD*HJg*D4ytGF2Jq_}Xz?l_!Z7JH3_F)rJBzAXu>}SZkGEp~MDjE*-OoJhL zXnK9s;l4ACf{m-DWnKIP>RKp<*VMdN`hn_F<$)biv*%Y?HpKyX6vw5XoKpjIBr)ike;_leL#H_1v(QstmqIsJiC(PiYc&73w$tC z;9Eu)NHj7Uk#oH5K-NkTa4<9tIhRIp*bJ5!Wp{QZ2OEPut=Jz8VgI2x#EYr}EHXls z42VOe1L9D4Kpf(LI1~(sLxKS#TUh0XtiS(_{ztWZl~_=R?o?6QN7Vmj@POi`#RSD2 zwn+o~w^)sz4?87LGsdud7N&-;##f-j6^Vn6D;N$U-X6fI>V=$PqqV5*iXyem5j0&h zuT%k_Bv?ZV*!wIO>Nw`q=_*4&lTm#yglKvedq;|B@>L&?G#9iIwD1BEk`buGKu3oF zVD-_srhP(vsa<05A~CLC3YGWC((-&3X1J=;7%et)7RaC}hjkMMdv`63ASc0Q4a#?- znOU@R(z~TZVPu(GDP`3bx?c!AR0C`*yQj7SmzNB1?AiSWirE-0=3ih$+q*->_)N%r zQfV$3Bfz0xjJRGobPNdarQ|9>SJcZ;&njwZm~%6XIhS$|W10)1QCQ0Tna)1F7SSSX zf^sW!EK0{H9E=}vbY(V>sLg8AM6;BDw}lA!1q7`~B&erHi~^^g)+R#+|(fVt7TpGqj?ZIp9Tjh&g|#HEc+wyHqoV6@}4a#=eHuE9evQ&R^>j zeL{bR-x+kG%00h9-!=MVRj6*$Kvq#h3I2CL3yop#WI`DSFq)TU4D6jTIz6nKLZ^rK zqF}3-PEUZ6PVa=uTQ#~o<``c_4L-P7z-&y0FwU0<>=#4m|7i^L=rQA(_w*;&1Dqd- z{VZ^?Eu7p#B*N|D4?+RFF!&dulxR@4-6;gBt@saAm`{Z&mpE-yTbXHMfzp7!PI?|p zefWB$`f&aRHx)Dnz&KCKH^8(R#`u4u)(UoD9&^*=(9Fj=FmLHd#^>y{+OWnhr&44V zhLrjFtHBlSfx^fXOdmR?k?N36^iR`#L1uR)To(Fk3iN0WMgcxK3UC_%6QcmXJqqyi z1e`hwuw@kBwFDd-HI8353J~U2L{yKRbdR!|-3sfT-NHUMUzgc?V zh6H_RXF+F(-vJG3oDsvkPQ}c^dG7>H=4hjbdNRg$I&IL|w5y-2fugP+%y2j#!nPbj z`v7JD&L#&us2?5za48PKa6T+vi?&xdS(b4Y(+4R{hI63da6V8peq(>;siTBw5ZS_L zWf&he!}zqsSOhLJJl-U*USlN$)O+KZJt!J8I6PN0fv3ZhM>#z^PD zrus-KKV>1v2o)LdPsWqG1hqIQ4C-G7I7F8hvCQ;S+IX?(qo76*D z4CCY9a9&KS(bg!1s5OWam^YZqQ6F)R=2-&yswV7%gMk(BwPue6UnK>J9W=u99=?;oXUk3Wh1In?94 zzXQ-XVPjdGlN=!l{jxzjG-g9AKd%*c5F!Rs5&Cr0k%J;}bxe&1X5BJyHkAFe4P<=A>p^Kmkk3eT9s;twydnp$YB_1=?q;$>EThV z{Rw=ZMXUv3-md^VCQltC2p6jYF2<*$N&!FV*oGt_RVE9In5u8WZEXR2723ns5Nses za3(-oTo#wwzzV*>jHJk`F2V^aikrE$$xDMdux^~h*)Srf*W*bZNz4q1!IP{)N9;v5 z;drQ{7VLMGKXdvtJ$P}cg>fHz%0(Pf9vc-ZBk&Pa<_5=WW1rls89-~}@#?^_xnnl+6e?h?R7vW?`DBha7i0AR z3P<-@Y*j4pPH*H(xw~8tg`8VmwU8^DM)hZ8q8k;9X9#tRr3z_($B+*pz%(X^liu*9 z(;3e_6h%rqpeIC$+41qQ^bV!Og`rsL15s-Wn@H@yiqah=Vm^X}dGB+OW)zKRSX#$w z)7bOlwYtmXLz;>R>e<7IIH#t;7>4zR1PhINfte&rzp9gsLzBk8C_eWObEMK3HL(JK zNOgn-)?F0m8`VK#Qj9($H8Kffmih52{1{ie()c4K8Z}sLWfqwltgM2)j|LD)gG%V{ z$LS8ICDl%|0uHw-``MFn(Y>5hQm`=&ZoiBDbQouSqjjq<04nkbWwp+aM{4yAZcdD4 zmK>=?3QEM;Yj!gUOopB}d3qByybd1Ga$79Ce2^lB5H;jq;~Q#WXJK93xuPzbd9vve zsEv7bvFn_d?3bg<&pG@n``L=7*z_mbCtPyrikF?eJ^itY9{yC}=W+YFiXN}L>8KaJ zi>yZh<}$z_`^~%XjP5GxpHm^vkU~@$<^oo^A$@~b3{w9CYGpe3MrrbDzpdMJF}oTw zTHFq6n01J?(>)8flz`tV?5NhZyFU#RImh;9Gd>*;T4Cb zKb~!Ht;)tnBwblnGUVhDq@4v6-(S}2Y&BlDP#Z=s?ANPS}-qw z`Y-@U{eYoJE*e>er%(~9kP=v^AB$qo@L()ey4ep@NLn9>S+Kw;nG!>%fY z#e6J`yIbLB`S4ei!n-dg==n06s*L361OcbqLM#35v2cs)wu@4w=nFS~!4C*G?+4X+ zwEK)s3qxHj1a0PD^v{Lr80ga!8CmXbgfcAQAN4h;fQcbphr9Du`-;_U)l&^ROz}|d zR11+u9)MzYYgRpjl|n|tz*m_9UTDu@xlY(#9Dmgth3kOyH6rJxJHY$}KLupyFskrH z*`udDjsrT*VmYqhb9 zHkNbU5^T90ECgP;CL9ynSbLerxf;wHFajVr_=(|NK+X#$Pej%y@VEef zXXCF1e@mUCmS!h(TwLCM2_zvtNpT`c&uX!@maN>5n@Y zU|!hj?6vzj$gq?QOF|(FBy_<7Lx2gNA15vO_qB%Bg=2`*N4Bo_}h-Z zrOw6WOS6}hcU)Z7en}Y?8iX{b+mH8SIxengzofzsIo(%YMGB{lrqBL!h5eU+N*1~P zg{^+RefuyNVq(}d594eUgWzACRdrQIKaEN@z3ba-!KR}-j(M-O;+l&uncwtJ9mjN> zFzbmG$&M?_I<70j+Z?;M+}=}eyX7nX>*kww`3z~A{=&DKPIs;xajqKyRMo7%t%&z{ zRXu;ILa2P!-@1S}^0w}q?Y{g?yHNUW=Xl4O_4tZE&Tp!j_2(7+^P7%seHOb*BCXHy zIp>KLKc5fuR8%4T&V5&>0Fl4L_nh>Ns-K3@=Sq4H^b_iAYz`TL*XYOsDZ&yaZ?}gj z;@cmh%wUpuSmqNMMl+<`XJs0#Rzk568q%PuZv$=1sSK>vf-DRDuhZW6FVQ8h+upc8 z09RG?hU^U;{39v%tLpH6z4petq)=?`J7nFnPq;;Tl>l;B2Kfo_ji~MvLjzssGc~ zzwU4k)p(QDQC8p9-84soEB?nR`*Hr&SMRFWZx7~YK5F+wza1$nYi)9!`VoMg+IFbv z#BWnyG#!JVNWQ83`JdtU}8S>SdxD-x;`B=G)K3vWxKX0bWaieg&C} zc@LnK42EpOh%Duf$n0h099^)0VKCj_xF`iFm~nCjw4iJ(xrwO1#iwJyTuzCd&jAtj z_H)tfBAp$yQ3u1+$VFSAOLOz;_lx=rmEvup7Hl5E-DY$O(Ol}2+d=$Q%aBO;`V;#0 z39(e8p+v|F(i`*X76^ZO^WH>cNhc6SQcJS5q$2R#s`EB`tDB#4BUWOzJcK2VPCooE zj%?ZM$H@0fw(Mq*4^AH|nYg9fhwxpIg2nBGfE%}s`%U=5+}bO_{VCV8m?#{LZuiBJ z$d(i`+jIFu`_P`T=Q0sv6=%SWdG}?p_@nNHFo)b%V8go`5!2bnk`J=Yg&}B;Oe6QVgI4e9e3B23{-*!ajtq>gVzxz5%p*W{;SeILZX5u~$wZ})0JtEgg<)rI;B|sENY#uroq6Us@)$GeaJ* z(>Gy;YcgD`eF5Htn#l=Wm=RjwEclMHn7l1OmjfCuQ8Rr-z!x!;Zx7IaXnGQ`_*2Jt zUBv}x+2vADVMg^~4Hu?Ax@CFoWfD*Kp_%322jo2SE)pM~0|$uSEF&|_7F{a>Earx< zn1M;=qNW!q7Jo(+%p6O0uLSeyGMAnA}ZDmTMo2~g1KDOH%r#}*~oaxTlF&?W($OLYfA}&e1dn~-a57G!!m?)6i-D4!j3wz!w?r$Q(O2t7BF(4eysy%93?lL?#T>e{Uegw`4WC`GwJ6+k=#s*1n3MV z;HNkt0u~^l3_sz7TyknQGeY^G!+*?XTL8gBDthpCl#@=QLis6es&&_Xjm((432~6e zE12GNDbri1dox2^rrF77#GE5bBh`_3sP0t&+QPg6hJvE`4K$7K6-%FoTsf&5a!H2W zRYAB3SPWIm@akTJ+Ni+Y2OPSmL3)bR6KVxZE&mPGh%4m54BRg&Lj!ND%2l%hF)2*b z-u*Yx$6EcfklHl_?f#>FJZ3&AsPBFBvgvzIeWGIjH6RETO}XWo$DsFPM}|U}DDc#| zD*qV&q~L?V>VyAW!P9-AxF7i_FhQ21dj>dQ(>?&F>90ou1OWSsuLc8l^FpL>)imt} z#U@sSLF8vkn1bd~9#PgsAQx%iYs!Ftc(eqQp^`a5)B;4g#C4HSb2yUEI|d9ds_}&Y zLxg>S^f~nVcOruK`VW$cJ|+LI1GFDT2GdDV`bso*0VNb4`<=;{pF*i9q+)N}GNg`4 zq3(~VW$}}8nS(5z9CbUyD2it@eTXu*^YImcC`RN%=8uw&EXEHz6Ui9&|6?grtdF6@KqrE z+KQ7?$i}A^3UGWST-Vun{D^PV6i}ZV0!`saWpIfW=}L7~`+&|O)aSUF&*0|Bdv{$9 zweqWqz6H4FP@v*I6w%=@azXLn-bI0kh9OXmFa)Vebqzzc`6QWYgn-1e%nr65Dmj(j z3Sgs6hM3#^b_3h}f)Z__X_Ik@HrxQ|<7&$y=@!wTny^r;NU(AU;)k&SPi$$UzH2<* z{g&vbXk&%@8%Q!GPynLgUBjbI&64r+f_sATldt2CpXgbggb14rf{PFIKlZ%21b_s{ z!kQ>KMyS#3FBi%nh3-~_Nb`rz=)VmBMIOSSD0uW7dbRn})@&=R~y(@8wEw*yXWTI%J%td<^K!)-Gxu61>w{UNAsF6b|M&bREwgEU0HDCXTzH`;Y!^8qSV<26%1drH< zVM%Xen?b2ZZ$V6CF=D=~F~z7t_$W2f7w-T*aH|05)6dY}*wsMiAY z-0L?nob=+J7Jsv5to_y@tQ@x||F$RjBHay`lSE{3Ut)*$B>%=(R+a57_xxf{Ob&Mf z!{2v{82xgMt5LHMd9qrL*Poh6a0%#eGK}bmT<}uZQcy@_t$YXBck!OD+${U7g1uz2yBV{9wMcZ}xVj)y zv#OqALABU;lc82Ry8E{WDI(ll4z~xviZU4XBoz@XH-X@0GdKyc1C5KI=H?QAcNX>( zFj97-VV_qyddZlBy6`jb=g224V3=U4It_)TqnFFHRXF1ctePo*6%U?D-J%p^1r}Aj9uqlv;`-&7xiBK2l zpG$unxT{@E0uV=!i-fkM;j`K_>3YR+$F7#Xn~$liV|in=lUZ;+_s3GdE#l6b%O`Mh z78}Z!9V6eD#>&U?8c%dT>Iwt=kpr_oI1#x+2qaBK0QKwXudL+$O0dA0!czIkAb5#6 z!~nwI2h2^=d<@O_&On^(N&PeCjrkx`LMUdVkLgc=0 zprmt*!nsCqdbbNjqG8b0vzgr>6Q9Jx6Q2f_cRsO-XxhIwvkzhZGxhM!0tV8V%`8NU z$K`9gVI=C^r7vZkIGh_s%DvkW)7mi7f*)@&9srAZn1Dw-an*j0`D^W+{He0;c^?uS z!HEUU_AU1&BKf+UgP-@~Z$AFsjlXm7w-A3j@E579EUVOi<&_ncl~HdUtU7JFv#bo4 zx3CPJa(kre{PZyj!l#e%#8vIImq|B1GK>h^*e<`)ZHWS(R77+xp3Tjhzu%J$54m3D#pnsKWWN~!Ey|tOR;-{>y^0-r%WmLFPAYI3ql9&=7RyZDb(mA z5$`lSB>RJ4tz^%1A+1B6?Si8>d61xr5UZiyRL~@OY|VpDaUzSolTT12s!XGJ_dtf) zv~w%QVOdGVg6WMHNKqh3_RYPRd@F? zrQmGlexL-qkg8^gEiqVPJUCl0TWc2~3Ey7@+|0+8IJQsHNDToXc!QBEG+T zDa*$#>zfg@ck&sr?h%tztZRv{NFHQ`v6QW|s}OYshG#R|k=YRfvY9mA^EuYt-pO|~ z7#j$m;6%VU{vb*C$_gXAp8{IbrlW!=>m-mM47wXkAcHcS0QX{Yq*h(&j%aKr$JnK~ z9OoE8egGkj!$Cq(snVKHM%kKTjEZjR#$lO0bi_m;Y=M>#6G9pZt*aKGpC-GcRkwXq z9W$zlScILdf<0DcyDmC zeq%H!4C5hmO+Tjr0uv2NJ^?9`!K~>KW~;&=gD59#*Fc}4=I3N1&#eXM5SPzZR)W3V zFht0J-ppPQLRinnBNS|sAjzf__Gb3u4IR?=w=&4Sq&e6ZwGNz_@5yu{bq2o4j32xE z>h??zUU0Hn<_PqfX)YqxTtrM_0f24_RuGN$4>W@`e+y7#?`^}=`ABCI~tdO+!D<7&P>ISCYu&)6+$XK<>euV7*+s#th%5 zicv}?d&q{~u_rPkkAATYweYsED&M;T1zu$DmYrdL@MDg2(_{Dg?8EO12!|yZrU5&pkq<;#(U&UYT*AtOQRasSeRpDO+ zU!zr(e#}u5VzF4&Lw$c(E|nZpIrLE}K~if-v-D zGfjMvXEw7K@A({K?45j%SbCIRptG49nIP}wjs$c}T!!eBd+LQO5M$!)lATXTyNrn> zH(V_NLCrMdXO&X#Gbr19D&_z&(wzee@dquuNP$p&ELo0I>00-9tS9cyeLsG^_cE~a zdZ3zM-E$5Cj?8Vab^VOaMC7s!iO50xy&VSmkMLImlkjx>-G#qfAcbBF76f&?^pH33 z5(e{U*s!u0G+wg1I!sR1xz9BAqx7MB|8MtkiM{wauTmW{;WUShr1@zJo^4Nuhf>S{7(LV$d!}vH0 z0UqpClHHX);$e)GSU;D=2Cj6L;D%Qwgqt+$d>EMQ2=-ZWuU4XTe~J{2bZ+2sVzw7^ z%ABi5Z8S0r7=>?XF+!?#~EFD>@C^mU7sbtpGKnTW@mXi>wq4D#XHRuCvmO*us)GD|j2R83Y=1BWUJEsBChF-Mj-; zyFn1{Fjc|faXlTbb=)B&w>006T|?DcvV~Jd@r0?sTM>s;tOV2k0F9CgccoM>9Ovf< z$F&%^N>C=v4I;XV-Qnzyy1qKvPnNK9^-}5xT(4|?sDGMU+=j_B+Kj?}!|zeH=tm8p zRJi~$;{6+nE+`l6|Mmcv(9pU6QTt=xEi)6B1&Y?fzHHt?eu{+0*r=-8ZZS&JVupkH zMaTvJz{;(xSd0K@xUJm+@Hc7{n+iTdcP40#3K&Un+&FduNiB;ix-) z);O+00i*kSUaD}ilqcK>V?TFN`@AQj;*c9ZXWie&%_%a#EvBMK@vTB^hQ-y}^r5JZ zv4>C8+v>+hzb#>9XzGm*frFOglD+{&c^#qhCi^=jMyQ*HC<{2HFywI zK!{~d?)^@=hcGh2yun<{hi+5x_i6tt3_q}OI?Wmgv+E)EC~GRbK3cfh!K{y+o8GNn z>W%+Nl^0sV$(yAsT5pYW445uV-S{;bdUa)nN>Xm9IbL|dI}4~d&7A-;ybxqQx&?l^ z_11g?feuFTEn2LC-h-g=5$IUa=XKDpon7!|;KYPkIxy2wS!U8xgMH$DZ@eVEUu*T~ zfs$J3itj1Fo;Ihv=lif<9u12-){9OfUh2a(mcpWGG0>x>yn5iq*!JK3 zsPhZ~KL#-jzJOk+`%T5ro0*iu8A|eMXeTxIQiwz2!b+R9up8e zN8+rtA}4f^$tr_ya15#ZRG@sBh=z!u4J^Kq(RR7oz<$Y7fYfK86vnfo9Q=bq)Ry@_ zh|-&BF3>j^%O@~zaPSU2QH*7CU)oU0JqI(ez!?4%fIXehjoYjV|L~n!z%Vr9$b~_R z4ivo_LW-l)p!A#{-HqmG*5Gt$uYz7M?hc)=@q87mo`2N*sT<{r5p^@Dq9T|+4*sM)eoYP700E^s37M3Am%2JJHPM; zvFCR!5f>_T3y9e@vwI1)V&GrvolzFFqRP2C?pza}eRXU_rO>u(!PP(M!s6%ilgtY^ znY}!gy(pT!E&hQU9*stP$yP!zuIoLV0Mz=1+%n+nvO8jTSFim)^Fd0MRl==xju3i*ORHD+bb0#s*0 z5(mw-rh}dH5U!|X?40DFwN|a_LENX;8_n!TrTNdpC#mzDS4d7M(xKK_Ya@|vf14BI zZ9+YOhor7ANo{577yMMb6yKAP;27}WBepsK1Mx_GlzotwK zGMXw>U5w<$TY}ODQ|?E!Sekg)$}3;HQ4jM(cVmx~$0{HNZcg{bos5au$)TvXniVM* zVp4ANS0sV$i4w+ZFY-@LHl-6dh2fuT>aBE9O~!Qc1irFUmb*Kdz)_N|BZ&xbcd6_w z1p?SWDYHMfy7A6*^a^hA1HGtCF4~@Q?_Nu?;5t{USSuEDAL*8g`Ita;Pk(s@m+s{c zIK_jyyBaC;xA1H~61MEeZ}I$<_iy3+p;j5I3cd8T16Ef@cyxk;D(rOJYm4iclQLfx z0XfCWaF~Yy4~8p4EwH~qKX0%_icMWmA?x&}+W;yeubS*nb?rV1qa z$yB;1fo>Q{uJW=X{Q&^&4-mMAv>+o3w}(NUvE#k(78f@PpCE7NX9-5QL8E0g*g_8XJL#stY$&OZ0o=lSClte8O~mTG7qWM&*lXz zU5u0$;iI%NTt?7Ul{&mh!E~g7?LI-Ql9^c<(?qn6-bO~D8sn<6o;wE7g9qU@$~WNN z5l+-~A%ITipq+1&c1HVq*sYE!49O#-&hTlB?TLd z2d6iA^k z@~C&Xp~sTgA4)@+hW4dXwGR%9pz-`TBeBE2#12nS4)hF{CFqb=u|WN4ZVX`JMgzeW zu`t&tO+zixf9Jy&ZgBG(caPWJM!0K09FdXtY^>1*uraBpOk-}x7je*-!DjYwANU!- zlr`uB4>CYSE8kwpPtiVLI+>B-uK-5mjAotb12mT*yg`H+ZHGJ@6N0S4`R{@wgXz;i zdAO<%W=vJ}Y8BIu-Ga!SBZc|ZM9*J=Tc)KS`#`|%A7%k;L9|34p5f1@-j3lP5}L)v z22S6Xw7@L$JLM}>XR_$PamYOt)+@T|9}!#P14LJ@wCt-yG;r>LOK7v#B-#bnd5HBl zwW_Icu(kOh=aH7JWAwp2EsH7G9v!bG*RsGn618kI*};-U&$H27{L);sr;^z1ZW?@M zTY!t4|RSar@G&0sAJkx1bQX zg4@N=@g4_#9=bnv%S!9Twvb(&e5Bl4$*kScEop>CSK=uDLzz%HrV>k?w)!>1-!QZ^ z8*NyISMNW77c6cAcf73_-g4Mk#A$DS$^d$Yd`mC+#`uX9h%)Q$$5FRj@(a5871)SN+O*1RBG%q)cvX3<$>eB@+S%VU_y`D~)K;oXOa+4}8s8_k|aHp?EB z8M5bR#?lP>MG8NhXVy^+qxmbyIT-qB=lD$U6z+f6a z_S{vBQ_J1G7=<8V5)w-0qUbN2d{zoH^EJm_RW+b-$O!EKux0U+q-%bT`e&M?4hi(Ffqr01CuDk$H3*7VN zFi{k#*Di1yB@jb4oUEOBAn>D>_u_pjUfY)ob%Q_-`PbrK0j4_R?kl%^2YoE z_bko-A&K@Kfs5b?j5%jI^;1($eND=(G(aJ*n({~Qlf%{~+H@L#;(xCM7GwGgbAW=C zW*fM$V%P)ixslbNKZOCgc+Q=u>Dmmy-#V}Z(#&3?>;I+=IW<4lvT5Ez^Ky`g z|8!+52b@Yoso(vV(*KJR{|&fW(OCeahZvbT`qNd&DW(HP{4)2;|IWq?t$>eRL3R;) zuBqTh5s*Dsw%ouE+s$mj!kyWfE1-VG_1$RhiPEUx%&SjkAS)IWsoqwYlMagbwOIMe33NwllQYyv0R2hJralWFIry09=^c3n{zo$ zPPrFpg6+Th=rL3ilHeSxL?6VDC5y}`O+xHl=s5rt~wxd_bT8q~U8HM(Ki?y2O9p37!dvwZ3 zn8}FqX5xW1e+WO;>ZuxdoPiJ^XS_1t=z<1)#YKwDR6*$H`U*M|3Le8k!nU{*&_~dg z!G^cC&jTAG%%(W#D>LwqV663H&4y9zM4Btma1h`=arFE%HRx{~rIT&C?!@GWDH?`) zo~^9tq2(q0_FKXZUUVnHHOTByRl-fT8*;~t=#2_%Ha@fK-xjbI{KxDTmf$bc?gzd>>ml%F;>vz@NMQRNDh?7 zQiUZ)XUQu*82ut{)M8KP=*lHR-aRJ~I=UhPIz%GaU(Fs7^59`%9ry14RNt`4V;|mx zU|@od9K9DU8-2oEjZy??K-0c^z083; zs4?X)UaI*!27cXJ2!c)l`Z4*1W#BhdHd`g=-+N%fzL@0IqHIiT8XJn^K-uh%PZYR>;bQ|oTwyVOa;7S~h;pQ_==;q> z6Ro>x0&y7Wz7Eq=S!6J)|A?C5M@a?l`Jq;H54eU44(Rr6mt7Wg{~~J#0e=Ex%0d}Pps2>cIE0{4c=Y}-gpH% zQ>8_PA7_JPO#X3XHiyglj(FevCNadqmaps*Vi!u6-Z#Ij6c!WjBi=WU5eRqCV{(7M z@cdxPeO{IZA!~ie{kpH4KOY_eu_XISL|E!ef0Wi&+FtiFy13IQwbv7iff9h z^i-WqLoAd6rW)P{kkq*hfTA+uTlnhb7}->aNcm8) zeaBEaG)}d3&m2TShSa3rxTGs;jbHi|B1f_#1&nIppJ<03hy@L2X8QF z8e1GJWhD`Jv@u9iQUtcZ9Y?PReVu0QK^RUG1u8{0dr(htS~@?f8{NeM;{`U{W#Iiz zG~TdrLDAHwt}5{sg~oG`fOepwhviQ8afS$X4ne7vBUThWlE}nR(i9|tH^^%I%AA@Y z0(J+70YGx?K#0aBiXl`;I+VBpg059O-?s;J{TdDHdUqi&7BiKgK@v3JJ)&_+iHZBJ z#<4ZwPgl5q);Kn15N9I}GK25yQ6%9d=tePvLGltLE01iX%ia_F4i~NOqV@kvSn9I% zFZ{K%{werr`&A-xAoSOb_l@|wAAc|4FEXKQ!h{Ls6DCyPCyKub6DskE_5sXX49mC> zpeq^d9gP+4dww9}y-Et_kSZUh@1VKQMV#5{Gt^tjjXwM*@N(wC?AIC5%`UVwH0}L( zGrNF>eK$wZE}&t57ZCP;jM@bxn*zZqZBfN2ZV2w1k&QG1(3vtxB#ZO-zyla8;yzX- zP6RRNOtPa!k#UX*p_Y9(V|we1yqfuWXnzg*K-SBH)v1uBDvH~FW z9ha|ofgAU3xasCy`r)dki|;oDXTwg*4vSA`HGisxQUzpZr&x|O}Vt`0sVB! zQU0e>j<@%i&$Rp&pH4X&pH6wZ`E*KLKb^8-Pxgf8Yg(Vf@#qNNj=>v>!drCalY(<* z_oYpfW_D*M;JYlBt{4WvD>6QfMxJ!Na=q{{^C4vC4jc?eQ_+mP12KjH30AjRl_Xpl zfW&QLAZrAY?y=}7Ska!Q)&Gc$_FTcB%2uv+4%vrVnD>eh$}vutl@eh|MS~Dtslv&LBoevEPc&$Juo+ZIvpqVT)^kGc$a-#>=r0m)k%i( za|kM!xs1ovPg~fZtU!8J!ffL+?WY$2+J*i1-Cx+m-JXS;K&!PS$`a{3h zvtg8cjVCpP6sdV9s5zo65)us)?CE$r0`^?VZ)KRQZUns(jG*CWc$)b#(5en*X||AN7hm-2Bk zm}`-uhQr4>I0OK#M)~JOWB>@qVt)t@b8{r5(~-zA$%VtB+FElu0;IBl0{8!Y(kEB( z_C{L)74beH#z%OnUYLK8evF_6BkX?Uu;;S(Antt#z&4yl!JkXzXszXNte%py@TLaO zO1yQ56R*8Y%`-X=y;}&X$_I-`SOMtd=e>o~JR*tjz*EKeyJb|#7@w)yE8LAWR(WQy z5A_vRXu-A6%{51Nuc*PuR82iS^U1^iEuSz4u%9lwa^{oHo||rXv?|!Oy?~&m zI6)}IVMIbJK= ze)!k8Tj$r2aN($LU|--WAIPko9OjmM+`)js+pwMEcIX4FG@GC|OZXau>o(^J>tpD#Pa2(x?d5cCBSCnIqp-uB?qV{e8=C4#6HIa%2{x1aLVLXiq!qnfD& z@@4l|WRu-;OL1>Ii-cNR8LI8?y5N1mAA%#)N|B z5%GrEChX(9_hac1;Mzmp0x3vFNRP4)&aq@~^xu#5UF!F*d>^+?cLAqd zX5QM|#Sz0=$C;be_7&l27v9>))1Tl$2tZrwI7V7+n@ki6vD$0`ec8l-1Rv;T69sCm zw)YYUYD_R4#h5Eh0M)eGW-|F2JbIITEhqxwhsK?WH{(4@9-s?H`T(wSKigSgSoi0b{aJ7qKBQ z+=1lI`8_?#9At17=k3U^JS8tm<>V}|gr*j+Q**KR`yhU~S9_mm$NZG|H^c^q-x{bm zRQWFN6AsCMpn8{GP)&1nk(-h8RKRQW5)7z*&fj1TilIbveg`=*%od#Gd*g7H?={Zy zp@Oq~Zye6@y~HMF%QjTe7U%cgIGo>mJCN2eQ0)93FwSpy$oFoWZ)KhbIr83Owfzq7 zU>y44f8q^y*P?5{8tTN3BiKgSqJP$@c(z!!V&5I z7gQu5bD5F9Kw)GC@a)YT!V_`=Is9KP4xLBA=0`4arvP30Y);T3jd!JMWv1p{yMe@o ze9OG9p2n{`70dk;@yrlN!DmkJgw;u9qMzIb$V+<+$e@7miQYfhT{aJ>8AlA___?@Qtnso5_IWEi_|;iW~r9sCa%_lHAwnl>3#R3N1p{m2gWyU1LsCg|Q%T zAp~-w8!9A-Vn8|R0p%Q<3&e(e-Y7>}Rz?{29i}L)2J(zvKo@;Oe_3JuoDv1G z_`NxtV>HHCB+||zWK&2NY4(sfntxZ%rMTv>Pi=X1tH<|q_{fw={HF${?{#)(%A9BA z#?{oWefeoSI9yLl$#bDRub1bI@?0!W8Pcbv<(;=(<)7LZxbS_+r9j9M1Yj@LM&#u4V#1kKDdA7E^Ct81Ze^GE&f76pE zc2C8fzTMBC*F_aP^BKv1I`f}&$*jJnzor(r9L=3RbV!$@IeusDYWnrty6wI^9G1cU zFLV}mkM7#BBtrTV*RO-=buCdf$Lg&$$LQM!E$pjATryS*JYEIVAvRY<@MGmJW5Qg{ zpv%)syWW_We1e_-cs&E80PHVQ+;=HQ2aTp2=}|lF=jag zC#P*?y@|oU;d{uKE;S4t-4o`c@K60=gX*5RRVm=|AN{RTI31}qkdQ!QRuY)B$~^!y z=m1XlSpZ%=3cQ@)oB?1dVI=}~Gxi#+eG4Ldr>kr1$1E;hoGT?*84i_niP7cc!}+>h ziSnisnZU#Jemer-BXZ$qh(C67Efio3Z^kQIEA+}3p{_UMGp)tAz&=C^uo-R=-z)nw zR5XoQOe8%^hI`H`+yx6MA;E?;ANK2jC3>BC(7+$F2%6DiRbDX)UWcvx6f!Vy`U-3< z>3Akg2W;q{EiiP1J$x?$h_<(S?l=b`C1K0~0Y3vMCTCc$dADZ5@|!p*jpJ-84Cy&N z)*7~+!*foQOY99^@JE&#_dbevb!u`ZpjFp`*_Fsrsw+W?3w*TFJhJMYON2qgzE+kx zB8O3qQ_{0{)6@|5#-H$U_C`wi@)xNT z=ZCwYU5l=vx$9$N+gs5PXjythE8JMR>lOY&3O-2x6%Flu+Nt;Fj?pUaaz6k@N3lsI z9WyJ}xsr+xfzeS+vI1f*S_1jB(W*HYypB1{rCz4h`jzy37n&NR-(=v1Nc*iuRClaO zOV56fI)RppprEkkfh$n7)Vkf&y2@hfT&KgI@E|WiMo~20J;g3P;aadd21o`x;@X_T zd%3pq#eG^2x7 zj5TGm>8vgc+JourG9j8wreo23BAwEO-e|m--HY5MLVj7suA?71YECVUCKK^8ZXuUg zZtFr-LFiqUw{zgC%HetZ`NBXty`-GCFPcaevQAYW!y`oVLSG_j3snO-A(=?wB+f-( z@!tLcJDTB*?rF&88wTvyl2+b|>Qf+NPi9sko6FDSl7~V?U1^_5n7oZoOP}s;5=O zPoXx5!&RcTkSkx2x7Y52UG1N_tmAu{yL#qFTACZHi^7%^WHi=&u+1`vnQNReQgOj1 zgB=k_2yw~eg*8HMAYDktg$9_VDh6XCAH5e}d+(WcEHA_h zgBc-~9?T@|Jol8bY<^Fm(c^_)a>_#0aLri#39k=dzjv{sn=W>J%<}d7IJoc4-Uv#EFdIO zyfi60w?7)K;6Ji(n0?L|3acK3Iv0mg)&o1}EjTw%9Zbh!!vSajX@m*f2l3_k(rNPT3*i%JgXjMVZLr*=UF3s zksJmNng|H9FkIW@nw_}<(go3M3YB7vcY7IwJz+>cggH`<#t1t;b&NdH6|#rM-u_NI zlg{RKq014I4@>YzG%7W>JF0}AMYVxYTxb}G!fu3-CpePn0$01LT#dk;e^s1h8FE30 z;2a8(^~rVdB<4M>iC8wBOZVl4`H5TsYSl1fhR_HU`cb+!8_g~wJ*3Mjs9t49Hr=0% z4nm!BV|^+st2?rGE+=%_c}$=3X(7(b<_Bycn#m*+&SVPxRN0!27m~1g$WuuI=Hj{U3B)6Pq7OfCD zib+ICy%^~i34i;ldftYWNG}8Rhm$n3f zem{v#T+9y`dS)2ML~!6o(kD(tG7%s8$I^v7EXZkJY+$sJC*a8w?!BIVyVRDRGP~w* zjX=R1n{x5W$L-WoXTF-t$KkP-@*B~i9^^Yb*+MFx0OHON4|{@Mbhos3bvZe7$-0`` zW|v*E#`e}obK6Kxry|PgA(gd4DxDYXRJzbVAmlPp*bTG@4u2?-hDIgw3Ct9i^Zw`6 zGAgI+vm7MePq_e<%V0_`EKOwdWK?~HRE#^17`!%r0M+l`XZ=0tls%ltpN26LiI9)> zChd}3Qjp3OQj|$1Mu=l zc9QEOr^Ji+s@PEJ%X-ZYImeFg$!fJbFLR8Qt|Wn&JA zO~wjIzEtCc1WN7vzb-!#7ol(?@4y^|F|cSRXv3P2$FeE<2+P0dck0F=n@7ou*q1FI zIfYMi`zlAvX<3_Ao(X~SZl<-y%Fa;$Wztxm#v0tzsX`>iV^fLT0917# zs$5+rraEZ?ZzfcBMVC^~V>LZ9kcj2D3h0iO41J7_^QFt7EEX+O{amhY=p)zjOcaar zh#Fy)d{2#s6r8sKfbg)RE(jg5VYw@1Bk&XHYHEwLHi1XLF*JafTqzTR4|60(+Y6VN zRq_x!jF6T$5s0F;@;YiWsK{ACCPc90x&+u{62mr@LwP{SGS42V zD<>&}Fr&8C68M`H6lzTj(n33r(c#sKVmY5Yx}4%4eH}xDhaM=FdKnbxz1RJw@1Z z`yt(>!^tnEDy#f*x*!Y|5bexi^*Ygq8t|qLfHz7D!Ad7>8C3MG+Ux*-0LWAZ=NOeup$^h)RPh z95xB972Ar}BhoaSQcqM;1JKd2frFe^Qpk-Fw`)C7I4pW6#~Hvz@Zf%T80Fg$C7~$o zm>w7RBZYjrHqImN#6@H4o^FO*dF4z#y1Ld*jiz{Y7Bh=HZVOS=;#A_)-~@dUQLj9e zA40p(A#@APNZW)i!O1NBPwjL^@AkH`^I5Z4Wx3~sy*vK2wl{(I+4j7L%-T#cnj&XX ziJ6T%wp7K3XOM&PCd6cnEY0F^@6* zaNQv6l@P`Jf!ioBBh}~rnR`tDCuGyi- z)9x|Lzzzp9&iscfR&oAQ0*USFGn)Tg zHu9-ppX^g!!+C7vGY)^3hrp*nz&|&_P6E-v{Ul}u!i1}iEw5t&V_Ob(GmghO`B*xxE<67w&gs26 zIxa0czpU*1^0MXBXk_`ZI@p;S6o9Y(7 z>37b_4L3UJx!3P{pU&#fS;5m=!2gT&JJt)%?Y;g#_d_SE-c9fNg!~bg|8DR)CPU4ta0>r+)kVu6G!d&T%9oKe(_h!r$|( zL3$9CKuUVFvo%70gPmlO5oKXrOC$Ukrof~+w^xpi#{67=jUWc^ei-wzfX<#UAe5J^OHc- zd6bg;l#={(k8H7ckLsm&u_-+iM9-l1Q69CA+D1hA)c=%Ef54osNkY1AaIZU%QkhN= z<#)L${Rw2M|H~kHb`nJQ2SEZT1NuBD3nE#m9mKx^L^7Z2rspB0`{#q`{z?$l17E=3 z{=LqWulad;SgJgVu6=G@F^d;y}Tc1J$TlFl_E zyK%Z?(F*L0&G4WmHeWDyJ-xBtkRBXFu!goLMVMNFocVT^_9ij*d%90=`SXB2joA&f z`Fsx8lQye&_D;>j;`tKXqmo_uxO}L9ijcuY!N^2w4JLj^DEldiv39Zd|rwKW~`TAEr=#@emXyI;ra9Uc>|hE_$}a9 zjo6NuO)q1;*w>Zdf|Jn4kLz}~gV@v--i`-3-US3yQYF53E4u8w16l)ioC2Yp#6|LV zW4k9i!of9)y*8O3zIaKUzDov;E9&pAUs_4uo=cR`5mIga{+`JS5Pw1?8 z({Rk@VQes?TkuEb`L6;rjqE{j`XU!$S5>sq9+{cgaoL?-fM6H);$_)3l4@^ud@m#X z_P()zJvnv>OeSZJD^}Z`E05Nx-qcFx2aH2&%XI8~HY-`k z4N&`M77$y_LRYpEA`Q-lp@w`m=|G!hM>{yu21&vddNE~m4&<7_oSvl$BkaGZrlwT9 zy^pRLo7>dc*3?qmTUe-QX=sgRN*cVh{2Fz6hlc=t5fcEznc^z(1Sv0_>wDI}Jy5N@ zYMvBIgzgB_%{jO~EIsVITG^!hQh8E&Q`xP*qaR=#ZU{!Lp&PS}ZX;@>jI)f3jBgw3 zjN6UP#v{fv#vhH>jSq|-QxD}rOmx13O%?0JPO(S)u6VO}C!RP%(xmxPOv*^>q}!#< z(j(IQ($Vr&@;HBWU}m5@kP55_tPX4mY!AE~I7peQ1e7l+Usb-UPSKLuGVLzyq~Mm| z3Vp49pZ>7^mj0OWC*uucs(FbC*U#dRdz^N#_EYT*?XSUu^`muB*Yw5udHPNI5A;9k zhZ|`lZ~W9a);!UiZq}Nb88REpE;D8hm>bQz%*V~$=1S{(*7vRZtw*glt)s$vI2_J} ze;Ix>{6QF%!`^ozIY{giv*L5&%i>~bxpcmCm9$2>LAqJ`k#vu=3+yP_0{vY`7^KbFL?H?Z)2;>8o2G#_g4(tfL7ci8F za*1-aa-VXrdbDb&5jCTprCzAsq&}+tR((MoryZ^}Ypb<8wJq9f+B@1;f{Ebf;KRX6 z{Yd><{YHI<{-Qn)eeyfw1!JOlh$)$hdAiwSo^M`cK4?B{ZZ)@=Pn)~Ud7*e{N$9(w z`$O-9eAWW%CTqJjC45?VZg>$|`%0KCcD^gm70(pECLS+cB7IwW5WV%9q{_FUWzWf9 zK+CrKBK}$aA^)@f;{vULT;PGg9|Io-ROK4wVdd9~UyZ73)JN3gG)Ysmd$gyt57B>T z26Mqx!CN5po52r)rx=aKcHd6y4Gq8w}$Bp{58OOn&=nTi?@q4Qls=4 zd7?Z?o-7|BC*(EqT6u$fi@Z@j)c1n#HQzSnKa}^C3F>O?VQqS_HTX>M+2DIYrcclh zgC0!PPu5S<{d!QJrT6On`q%U!eWm_={Wkp${m1&xb!=1{SW%<`bYXfhGH0oZ6uB5#>Hsw z-NyZ}-0iTUN#^0^RP!eDhvrYACl#RsLeoQap*f*>q0>V>p=9W5q2sI?%V!0xCTpG* zwFa##tgEf{)-BfE*1ubCSQX*H@I_=Jmt#JKUR`ciFTsZ@RHJat&TUVTX2uD+P(Q5R=|GaBVfria8+s&+bmbuZo!@9@1&-%Ibfc22| znDvD96fE&s>nq`H;Xj1`7A9dIguDlfCyJ`r0ImDI_?CF6bgZ;Mx>))WJk7Q8WAd}| zhrmt(cHe?tJ@0$NH_3mLzrk<&hoMhT`v2R1RG>a^Zs3)`c;yhqhF`xA_W7LhN97&m zK=li1NIgScrhZ4gOMOb+slKLuPBXPG?JL?3wb!-D!J~pT!Bp_a!T$>WH!QY7KR`c9 zpQbnItM&EzRAa00o6w=w#n6WDTlb;`zqj7DI>STZHQ`&szX-oeIFe;Hw@Syzr$H;0!K!bQe<@G#h2by1hn_gXKij|FztMk}f2;pD z{@?j01&$6Vfp}nBU}xYEDg5TWykA~d-c^o(j$Es*RX3=&s2kNy z>YcEVqclOAqxEYS1-~6!2mkX(@U!|1eU6^cm+I&1m+9B(cj}Mo&+EJO!;CK&3E0RD z#!rl=jpHy<%rU=it~c*6?=^Rt6GBJ8CNiN5LO%}e4jpM7XPstU0`0pOdiD}puZBC} zMK1}j3qKg%5q>L-i7I;&5KIt{5Ie-QxJ+CvZW5mqUlso*HcN{zZfutRCY>Pr3d|4Sf)rU>$Bv zwv3P}ey?B@SnD}S$4e@A6 zmfECM(w!2M50k58Lmq&C+$`^u5BF93PV=?+CI!w2*y!Uw1r9?mACH+pm2!$w3(ftB zauMw8v(V6X%n8odF4q34MS{n`yFaD>R^O@b(qGVn@NgN}+OTmpMnc2vFcanl=4Iyn zp(jFfth22Ptbc>Ff3V)OjtS2W$HJFFSAQO6uQRq4GRvYST4JO4MfBEuago?74u~l+ zFD@5Xh!?=)UnyQAUMFr4Z$&TOEp8U?7atZM7oQe)h`Yo;iMz$Wif_Z;jh8B=$boiNBQj63nEtFEyaq>L*ER13A%4hfnean3p`PTTp@4LtMitkYW6u;$P z>_5lNnI&)Y~w+zNAjq+O+lBFSQ9lBUlK| z(pz*iq8@8ANLFeWX@7?Af0ObSSMW9INxowgmZ?CjpD`_H2J3^3!8yT&!OMf+3SJZ3 zfKhWiejTUU+<-o1D=L@b5$w6s%tLE0_7iCNEDjAys_ zHu^UC?)0I6cX$YR2>jC_fMMAE&BtR|aXUhtJ&d)4|DVSetfnn=n@%xM0qZpz%dR&K zF&fJFLGitp5Ll&{t9wjbxyp$x7O!u|^_1dWghbaq&DdG)HDSMNCu45NnbGsSeEEUGTS?+z{+N=6rzOeYiX{pV`H$4K)(VSCcK literal 0 HcmV?d00001 diff --git a/snes/bankselect/tools/padbin.exe b/snes/bankselect/tools/padbin.exe new file mode 100644 index 0000000000000000000000000000000000000000..dcd84809309d153d1ce260cda1d5b79fcf7bf676 GIT binary patch literal 16095 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 literal 0 HcmV?d00001