├── README.md ├── goomba.gba ├── src ├── font._lz77 ├── font.lz77 ├── fontpal.bin ├── mbclient.h ├── speedhack.h ├── minilzo.c ├── sgb.h ├── cart.h ├── gba_mb_my.specs ├── gba_my.specs ├── rumble.h ├── mappers.h ├── my_mb.specs ├── my.specs ├── memory.h ├── all.s ├── io.h ├── gbz80.h ├── cache.h ├── includes.h ├── sound.h ├── dma.h ├── minilzo.107 │ ├── Makefile │ ├── minilzo.h │ ├── testmini.c │ ├── README.LZO │ └── lzoconf.h ├── lcd.h ├── ui.h ├── config.h ├── pocketnes_text.h ├── main.h ├── rumble.c ├── sram.h ├── gbcgamedetect.c ├── gba.h ├── visoly.s ├── speedhacks_old._s ├── cache.c ├── state.s ├── savestate.c ├── asmcalls.h ├── mbclient.c ├── client.h ├── pocketnes_text.c ├── memory.s ├── mappers.s ├── _gba_crt0_my.s ├── gba_crt0_my.s ├── macro.h ├── gba_cart_my.ld ├── gba_mb_my.ld ├── timeout.s └── equates.h └── Makefile /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lesserkuma/goombacolor/HEAD/README.md -------------------------------------------------------------------------------- /goomba.gba: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lesserkuma/goombacolor/HEAD/goomba.gba -------------------------------------------------------------------------------- /src/font._lz77: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lesserkuma/goombacolor/HEAD/src/font._lz77 -------------------------------------------------------------------------------- /src/font.lz77: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lesserkuma/goombacolor/HEAD/src/font.lz77 -------------------------------------------------------------------------------- /src/fontpal.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lesserkuma/goombacolor/HEAD/src/fontpal.bin -------------------------------------------------------------------------------- /src/mbclient.h: -------------------------------------------------------------------------------- 1 | #ifndef __MBCLIENT_H__ 2 | #define __MBCLIENT_H__ 3 | 4 | int SendMBImageToClient(void); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /src/speedhack.h: -------------------------------------------------------------------------------- 1 | #ifndef __SPEEDHACK_H__ 2 | #define __SPEEDHACK_H__ 3 | 4 | void find_speedhacks(void); 5 | 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /src/minilzo.c: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | 3 | #define LZO_NO_SYS_TYPES_H 4 | 5 | #if CARTSRAM 6 | #include "minilzo.107/minilzo.c" 7 | #endif 8 | -------------------------------------------------------------------------------- /src/sgb.h: -------------------------------------------------------------------------------- 1 | @IMPORT joy0_W_SGB 2 | @IMPORT joy0_R_SGB 3 | @IMPORT g_update_border_palette 4 | @IMPORT sgb_reset 5 | @IMPORT g_sgb_mask 6 | @.end 7 | -------------------------------------------------------------------------------- /src/cart.h: -------------------------------------------------------------------------------- 1 | @IMPORT loadcart_after_sgb_border 2 | @IMPORT loadcart 3 | @IMPORT map0123_ 4 | @IMPORT map4567_ 5 | @ IMPORT map01234567_ 6 | @IMPORT mapAB_ 7 | @.end 8 | -------------------------------------------------------------------------------- /src/gba_mb_my.specs: -------------------------------------------------------------------------------- 1 | %rename link old_link 2 | 3 | *link: 4 | %(old_link) -T ../src/gba_mb_my.ld%s 5 | 6 | *startfile: 7 | gba_crt0_my%O%s crti%O%s crtbegin%O%s 8 | -------------------------------------------------------------------------------- /src/gba_my.specs: -------------------------------------------------------------------------------- 1 | %rename link old_link 2 | 3 | *link: 4 | %(old_link) -T ../src/gba_cart_my.ld%s 5 | 6 | *startfile: 7 | gba_crt0_my%O%s crti%O%s crtbegin%O%s 8 | 9 | -------------------------------------------------------------------------------- /src/rumble.h: -------------------------------------------------------------------------------- 1 | #ifndef __RUMBLE_H__ 2 | #define __RUMBLE_H__ 3 | 4 | extern u32 SerialIn, DoRumble, RumbleCnt; 5 | extern u16 stage, ind; 6 | extern u16 SerOut0, SerOut1; 7 | 8 | void RumbleInterrupt(void); 9 | void StartRumbleComs(void); 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /src/mappers.h: -------------------------------------------------------------------------------- 1 | @IMPORT mbc0init 2 | @IMPORT mbc1init 3 | @IMPORT mbc2init 4 | @IMPORT mbc3init 5 | @IMPORT mbc4init 6 | @IMPORT mbc5init 7 | @IMPORT mbc6init 8 | @IMPORT mbc7init 9 | @IMPORT mmm01init 10 | @IMPORT huc1init 11 | @IMPORT huc3init 12 | @.end 13 | -------------------------------------------------------------------------------- /src/my_mb.specs: -------------------------------------------------------------------------------- 1 | %rename link old_link 2 | %rename link_gcc_c_sequence old_gcc_c_sequence 3 | 4 | *link_gcc_c_sequence: 5 | %(old_gcc_c_sequence) --start-group -lsysbase -lc --end-group 6 | 7 | *link: 8 | -T gba_mb.ld%s %(old_link) 9 | 10 | *startfile: 11 | gba_crt0_my%O%s crti%O%s crtbegin%O%s 12 | -------------------------------------------------------------------------------- /src/my.specs: -------------------------------------------------------------------------------- 1 | %rename link old_link 2 | %rename link_gcc_c_sequence old_gcc_c_sequence 3 | 4 | *link_gcc_c_sequence: 5 | %(old_gcc_c_sequence) --start-group -lsysbase -lc --end-group 6 | 7 | *link: 8 | %(old_link) -T gba_cart.ld%s 9 | 10 | *startfile: 11 | gba_crt0_my%O%s crti%O%s crtbegin%O%s 12 | 13 | -------------------------------------------------------------------------------- /src/memory.h: -------------------------------------------------------------------------------- 1 | @IMPORT void 2 | @IMPORT empty_R 3 | @IMPORT empty_W 4 | @IMPORT mem_R00 5 | @IMPORT mem_R20 6 | @IMPORT mem_R40 7 | @IMPORT mem_R60 8 | @IMPORT mem_R80 9 | @IMPORT mem_RA0 10 | @IMPORT mem_RC0 11 | @IMPORT mem_RC0_2 12 | @IMPORT sram_W 13 | @IMPORT sram_W2 14 | @IMPORT wram_W 15 | @IMPORT wram_W_2 16 | @IMPORT echo_W 17 | @IMPORT echo_R 18 | 19 | @IMPORT memset32_ 20 | @IMPORT memcpy32_ 21 | @IMPORT memset32 22 | @IMPORT memcpy32 23 | @.end 24 | -------------------------------------------------------------------------------- /src/all.s: -------------------------------------------------------------------------------- 1 | @I need to do this to get around limitations of gnu assembler 2 | #include "config.h" 3 | #include "equates.h" 4 | #include "gbz80mac.h" 5 | 6 | .global MULTIBOOT_LIMIT 7 | 8 | #include "gbz80.s" 9 | #include "timeout.s" 10 | #include "gamespecific.s" 11 | #include "memory.s" 12 | #include "cart.s" 13 | #include "mappers.s" 14 | #include "lcd.s" 15 | #include "io.s" 16 | #include "sound.s" 17 | #include "sgb.s" 18 | #include "gbpalettes.s" 19 | #include "state.s" 20 | 21 | .end 22 | -------------------------------------------------------------------------------- /src/io.h: -------------------------------------------------------------------------------- 1 | @IMPORT _E0 2 | @IMPORT _E2 3 | @IMPORT _F0 4 | @IMPORT _F2 5 | 6 | 7 | @IMPORT thumbcall_r1 8 | @IMPORT IO_reset 9 | @IMPORT IO_R 10 | @IMPORT IO_High_R 11 | @IMPORT IO_W 12 | @IMPORT IO_High_W 13 | @IMPORT joypad_write_ptr 14 | @IMPORT joy0_W 15 | @IMPORT suspend 16 | @IMPORT gettime 17 | @IMPORT refreshNESjoypads 18 | @IMPORT serialinterrupt 19 | @IMPORT _FF70W 20 | @IMPORT FF41_R_ptr 21 | @IMPORT FF44_R_ptr 22 | 23 | @IMPORT io_read_tbl 24 | @IMPORT io_write_tbl 25 | 26 | @.end 27 | -------------------------------------------------------------------------------- /src/gbz80.h: -------------------------------------------------------------------------------- 1 | @IMPORT novblankwait 2 | 3 | @IMPORT XGB_RAM 4 | @IMPORT XGB_HRAM 5 | @IMPORT CHR_DECODE 6 | 7 | @IMPORT GLOBAL_PTR_BASE 8 | @IMPORT emu_reset 9 | @IMPORT default_scanlinehook 10 | @IMPORT cpustate 11 | @IMPORT rommap 12 | @IMPORT checkIRQ 13 | @IMPORT line145_to_end 14 | @IMPORT gbc_mode 15 | 16 | @IMPORT immediate_check_irq 17 | 18 | .if RESIZABLE 19 | @IMPORT XGB_sram 20 | @IMPORT XGB_sramsize 21 | @IMPORT XGB_vram 22 | @IMPORT XGB_vramsize 23 | @IMPORT GBC_exram 24 | @IMPORT GBC_exramsize 25 | @IMPORT END_of_exram 26 | @IMPORT XGB_vram_8000 27 | @IMPORT XGB_vram_1800 28 | @IMPORT XGB_vram_1C00 29 | .endif 30 | 31 | 32 | @.end 33 | -------------------------------------------------------------------------------- /src/cache.h: -------------------------------------------------------------------------------- 1 | #ifndef __CACHE_H__ 2 | #define __CACHE_H__ 3 | 4 | #define MAX_CACHE_SIZE 16 5 | 6 | extern u8 *const bank_0; 7 | extern u8 *const bank_1; 8 | 9 | extern u8* cache_location[MAX_CACHE_SIZE]; 10 | extern int cache_queue_cursor; 11 | extern u16 prgcache[MAX_CACHE_SIZE]; 12 | extern u8* cachebase; 13 | extern u8 cachepages; 14 | extern u32* pageoffsets; 15 | 16 | u8 *make_instant_pages(u8* rom_base); 17 | void init_cache(void); 18 | void flushcache(void); 19 | void clear_instant_prg(void); 20 | void regenerate_instant_prg(void); 21 | void loadcachepage(int i,int bank); 22 | void getbank(int kilobyte); 23 | void get_rom_map(void); 24 | void update_cache(void); 25 | 26 | void reload_vram_page1(void); 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /src/includes.h: -------------------------------------------------------------------------------- 1 | #ifndef __INCLUDES_H__ 2 | #define __INCLUDES_H__ 3 | 4 | #ifdef __cplusplus 5 | extern "C" { 6 | #endif 7 | 8 | #ifndef ARRSIZE 9 | #define ARRSIZE(xxxx) (sizeof((xxxx))/sizeof((xxxx)[0])) 10 | #endif 11 | 12 | #include "config.h" 13 | 14 | //#if !RESIZABLE 15 | //#define XGB_sram XGB_SRAM 16 | //#define END_of_exram END_OF_EXRAM 17 | //#endif 18 | 19 | #include 20 | #include 21 | #include "gba.h" 22 | 23 | #include "asmcalls.h" 24 | //#include "fs.h" 25 | #include "minilzo.107/minilzo.h" 26 | #include "main.h" 27 | #include "ui.h" 28 | #include "sram.h" 29 | #include "rumble.h" 30 | #include "mbclient.h" 31 | #include "cache.h" 32 | #include "dma.h" 33 | #include "pocketnes_text.h" 34 | 35 | #if MOVIEPLAYER 36 | #include "filemenu.h" 37 | #endif 38 | 39 | #ifdef __cplusplus 40 | } 41 | #endif 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/sound.h: -------------------------------------------------------------------------------- 1 | @IMPORT Sound_reset 2 | @IMPORT _FF10W 3 | @IMPORT _FF11W 4 | @IMPORT _FF12W 5 | @IMPORT _FF13W 6 | @IMPORT _FF14W 7 | @IMPORT _FF16W 8 | @IMPORT _FF17W 9 | @IMPORT _FF18W 10 | @IMPORT _FF19W 11 | @IMPORT _FF1AW 12 | @IMPORT _FF1BW 13 | @IMPORT _FF1CW 14 | @IMPORT _FF1DW 15 | @IMPORT _FF1EW 16 | @IMPORT _FF20W 17 | @IMPORT _FF21W 18 | @IMPORT _FF22W 19 | @IMPORT _FF23W 20 | @IMPORT _FF24W 21 | @IMPORT _FF25W 22 | @IMPORT _FF26W 23 | @IMPORT _FF30W 24 | 25 | @IMPORT _FF10R 26 | @IMPORT _FF11R 27 | @IMPORT _FF12R 28 | @IMPORT _FF13R 29 | @IMPORT _FF14R 30 | @IMPORT _FF16R 31 | @IMPORT _FF17R 32 | @IMPORT _FF18R 33 | @IMPORT _FF19R 34 | @IMPORT _FF1AR 35 | @IMPORT _FF1BR 36 | @IMPORT _FF1CR 37 | @IMPORT _FF1DR 38 | @IMPORT _FF1ER 39 | @IMPORT _FF20R 40 | @IMPORT _FF21R 41 | @IMPORT _FF22R 42 | @IMPORT _FF23R 43 | @IMPORT _FF24R 44 | @IMPORT _FF25R 45 | @IMPORT _FF26R 46 | @IMPORT _FF30R 47 | -------------------------------------------------------------------------------- /src/dma.h: -------------------------------------------------------------------------------- 1 | #ifndef __DMA_H__ 2 | #define __DMA_H__ 3 | 4 | extern u16 _dma_src; 5 | extern u16 _dma_dest; 6 | extern u8 _vrambank; 7 | 8 | void UpdateTiles1(u8 *sourceAddress, int byteCount, int vramAddress1); 9 | void UpdateTiles2(u8 *sourceAddress, int byteCount, int vramAddress1); 10 | void UpdateTiles3(u8 *sourceAddress, int byteCount, int vramAddress1); 11 | 12 | void DoDma(int byteCountRemaining); 13 | 14 | /* 15 | extern u8* _vram_packet_dest; 16 | extern u8* _vram_packet_source; 17 | 18 | extern u8 *vram_packet_first_dest; 19 | extern u8 *vram_packet_first_source; 20 | */ 21 | 22 | /* 23 | typedef struct 24 | { 25 | u8 *dest; 26 | u8 *source; 27 | u16 length; 28 | u16 dirty; 29 | } VramPacketData; 30 | 31 | static const int MAX_PACKETS = 8; 32 | extern VramPacketData vram_packets[]; 33 | */ 34 | 35 | //void register_packet(u8* dest, u8* source, int size); 36 | //void new_dma_packet(u8 *newDestAddress, u8* newSourceAddress); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/minilzo.107/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # a very simple Makefile for miniLZO 3 | # 4 | # Copyright (C) 1996-2000 Markus F.X.J. Oberhumer 5 | # 6 | 7 | SOURCES = testmini.c minilzo.c 8 | 9 | default all: 10 | @echo "Please choose one of the following targets:" 11 | @echo " gcc gcc-i386 gcc-rs6000" 12 | @echo " visualc watcomc watcomc16" 13 | @echo " hpux hpux9" 14 | 15 | 16 | # 17 | # gcc 18 | # 19 | gcc: 20 | gcc -Wall -O2 -s -o testmini $(SOURCES) 21 | 22 | gcc-i386: 23 | gcc -Wall -O2 -fomit-frame-pointer -fno-strength-reduce -s -o testmini $(SOURCES) 24 | 25 | gcc-rs6000: 26 | gcc -Wall -O2 -fno-schedule-insns -fno-schedule-insns2 -o testmini $(SOURCES) 27 | 28 | 29 | # 30 | # Windows 31 | # 32 | visualc: 33 | cl -nologo -ML -W3 -O2 -GF $(SOURCES) 34 | 35 | watcomc: 36 | wcl386 -zq -mf -5r -zc -wx -oneatx $(SOURCES) 37 | 38 | watcomc16: 39 | wcl -zq -ml -5 -zc -wx -oneatx $(SOURCES) 40 | 41 | 42 | # 43 | # UNIX 44 | # 45 | 46 | hpux: 47 | cc -Ae -o testmini $(SOURCES) 48 | 49 | hpux9: 50 | cc -Aa -D_HPUX_SOURCE -o testmini $(SOURCES) 51 | 52 | 53 | # 54 | # other targets 55 | # 56 | clean: 57 | rm -f testmini testmini.exe *.err *.o *.obj core 58 | 59 | -------------------------------------------------------------------------------- /src/lcd.h: -------------------------------------------------------------------------------- 1 | @IMPORT update_ui_border_masks 2 | @IMPORT newframe_vblank 3 | 4 | @IMPORT update_sgb_palette 5 | 6 | @IMPORT OAM_W 7 | @IMPORT OAM_R 8 | 9 | @IMPORT gbc_chr_update 10 | @IMPORT GFX_init 11 | @IMPORT GFX_reset 12 | @IMPORT FF40_R 13 | @IMPORT FF40_W 14 | @IMPORT FF41_R 15 | @IMPORT FF41_W 16 | @IMPORT FF42_R 17 | @IMPORT FF42_W 18 | @IMPORT FF43_R 19 | @IMPORT FF43_W 20 | @IMPORT FF44_R 21 | @IMPORT FF44_W 22 | @IMPORT FF45_R 23 | @IMPORT FF45_W 24 | @IMPORT FF46_W 25 | @IMPORT FF47_R 26 | @IMPORT FF47_W 27 | @IMPORT FF48_R 28 | @IMPORT FF48_W 29 | @IMPORT FF49_R 30 | @IMPORT FF49_W 31 | @IMPORT FF4A_R 32 | @IMPORT FF4A_W 33 | @IMPORT FF4B_R 34 | @IMPORT FF4B_W 35 | @IMPORT FF4F_W 36 | @IMPORT FF4F_R 37 | @IMPORT FF68_R 38 | @IMPORT FF69_R 39 | @IMPORT FF6A_R 40 | @IMPORT FF6B_R 41 | @IMPORT FF68_W 42 | @IMPORT FF69_W 43 | @IMPORT FF6A_W 44 | @IMPORT FF6B_W 45 | @IMPORT vram_W 46 | @IMPORT vram_W2 47 | @ IMPORT agb_nt_map 48 | @ IMPORT VRAM_chr 49 | @ IMPORT vram_map 50 | @IMPORT gbc_palette 51 | @IMPORT debug_ 52 | @ IMPORT map_palette 53 | @IMPORT newframe 54 | @IMPORT lcdstate 55 | @ IMPORT writeBG 56 | @ IMPORT oambuffer 57 | @IMPORT resetlcdregs 58 | @.end 59 | -------------------------------------------------------------------------------- /src/ui.h: -------------------------------------------------------------------------------- 1 | #ifndef __UI_H__ 2 | #define __UI_H__ 3 | 4 | extern u8 autoA,autoB; //0=off, 1=on, 2=R 5 | extern u8 stime; 6 | extern u8 autostate; 7 | extern int selected;//selected menuitem. used by all menus. 8 | extern int mainmenuitems;//? or CARTMENUITEMS, depending on whether saving is allowed 9 | extern u32 oldkey;//init this before using getmenuinput 10 | 11 | extern char str[32]; 12 | 13 | 14 | u32 getmenuinput(int menuitems); 15 | void ui(void); 16 | void subui(int menunr); 17 | void ui2(void); 18 | void ui3(void); 19 | void ui4(void); 20 | int text(int row,char *str); 21 | int text2(int row,char *str); 22 | void strmerge(char *dst,char *src1,char *src2); 23 | void drawui1(void); 24 | void drawui2(void); 25 | void drawui3(void); 26 | void drawui4(void); 27 | void drawclock(void); 28 | void autoAset(void); 29 | void autoBset(void); 30 | void controller(void); 31 | void sleepset(void); 32 | void vblset(void); 33 | void fpsset(void); 34 | void brightset(void); 35 | void multiboot(void); 36 | void restart(void); 37 | void exit_(void); 38 | void sleep_(void); 39 | void fadetowhite(void); 40 | void swapAB(void); 41 | void autostateset(void); 42 | void chpalette(void); 43 | void gbtype(void); 44 | void gbatype(void); 45 | void sgbpalnum(void); 46 | void timermode(void); 47 | void go_multiboot(void); 48 | void changeautoborder(void); 49 | void changelcdhack(void); 50 | void changedmamode(void); 51 | 52 | #if SPEEDHACKS_OLD 53 | void find_best_speedhack(void); 54 | void autodetect_speedhack(void); 55 | #endif 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/config.h: -------------------------------------------------------------------------------- 1 | #ifndef __CONFIG_H__ 2 | #define __CONFIG_H__ 3 | 4 | #define GCC 1 5 | 6 | #ifndef SRAM_SIZE 7 | #define SRAM_SIZE 64 8 | #endif 9 | 10 | #define VERSION "20210516" 11 | 12 | #define STATEID 0x57a731d8 13 | #define STATEID2 0x57a731d9 14 | 15 | //#define LITTLESOUNDDJ 0 16 | //Little Sound DJ Hack requires M3/G6/Supercard 17 | 18 | //DEFAULT settings 19 | #define RTCSUPPORT 1 20 | #define ROMVERSION 1 21 | #define SPLASH 1 22 | #define MULTIBOOT 0 23 | #define CARTSRAM 1 24 | #define USETRIM 1 25 | #define MOVIEPLAYER 0 26 | #define MOVIEPLAYERDEBUG 0 27 | #define FLASHCART 1 28 | #define RUMBLE 1 29 | #define RESIZABLE 0 30 | #define GOMULTIBOOT 0 31 | #define POGOSHELL 1 32 | #define VISOLY 1 33 | #define SHANTAE_HACK 1 34 | #define REDUCED_FONT 1 35 | #define FAST_LDI_HL_A 1 36 | #define EARLY_LINE_0 1 37 | #define SPEEDHACKS_NEW 1 38 | #define LCD_HACKS 1 39 | #define LCD_HACKS_ACCURATE 1 40 | #define LCD_HACKS_ACCURATE_DIV 1 41 | #define JOYSTICK_READ_HACKS 0 42 | 43 | #ifdef _MB_VERSION 44 | #define RTCSUPPORT 0 45 | #define ROMVERSION 0 46 | #define SPLASH 0 47 | #define MULTIBOOT 1 48 | #define GOMULTIBOOT 1 49 | #define CARTSRAM 0 50 | #define SHANTAE_HACK 0 51 | #endif 52 | #ifdef _GBAMP_VERSION 53 | #define RTCSUPPORT 0 54 | #define CARTSRAM 0 55 | #define MOVIEPLAYER 1 56 | #define MOVIEPLAYERDEBUG 1 57 | #define RUMBLE 0 58 | #define RESIZABLE 1 59 | #define GOMULTIBOOT 0 60 | #define POGOSHELL 0 61 | #define VISOLY 0 62 | #define SHANTAE_HACK 0 63 | #endif 64 | 65 | #define SPEEDHACKS_OLD 0 66 | 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/pocketnes_text.h: -------------------------------------------------------------------------------- 1 | #ifndef __POCKETNES_TEXT_H__ 2 | #define __POCKETNES_TEXT_H__ 3 | 4 | #if REDUCED_FONT 5 | #define FONT_FIRSTCHAR (0 - 10) 6 | #define FONT_MEM_FIRSTCHAR 0 7 | #else 8 | #define FONT_FIRSTCHAR 0 9 | #define FONT_MEM_FIRSTCHAR 0 10 | #endif 11 | 12 | #define FONT_CHAR_PAGE 1 13 | #define FONT_PALETTE_NUMBER 5 14 | #define UI_TILEMAP_NUMBER 9 15 | #define SCREEN_ROW_OFFSET 11 16 | #define UI_Y_BASE (SCREEN_ROW_OFFSET * 8) 17 | #define SCREENBASE (u16*)((u8*)MEM_VRAM + UI_TILEMAP_NUMBER*2048 + SCREEN_ROW_OFFSET * 64 ) 18 | #define FONT_MEM (u16*)((u8*)MEM_VRAM + FONT_CHAR_PAGE*16384 + FONT_MEM_FIRSTCHAR*32 ) 19 | #define FONT_PAL (u16*)((u8*)MEM_PALETTE + FONT_PALETTE_NUMBER*16*2 ) 20 | 21 | #ifdef __cplusplus 22 | extern "C" { 23 | #endif 24 | 25 | extern u32 oldkey; 26 | extern int selected; 27 | 28 | extern int ui_x; 29 | extern int ui_y; 30 | 31 | void move_ui_expose(void); 32 | void move_ui_scroll(void); 33 | void move_ui_wait(void); 34 | void move_ui(void); 35 | 36 | void loadfont(void); 37 | void loadfontpal(void); 38 | void get_ready_to_display_text(void); 39 | u32 getmenuinput(int menuitems); 40 | void cls(int chrmap); 41 | void drawtext(int row,const char *str,int hilite); 42 | void drawtextl(int row,const char *str,int hilite, int len); 43 | void setdarkness(int dark); 44 | void setbrightnessall(int light); 45 | void waitkey(void); 46 | void clearoldkey(void); 47 | 48 | int lookup_character(int character); 49 | 50 | void scrolll(int doFade); 51 | void scrollr(int doFade); 52 | 53 | static __inline void cls_primary() 54 | { 55 | cls(8); 56 | } 57 | 58 | static __inline void cls_secondary() 59 | { 60 | cls(4); 61 | } 62 | 63 | void drawtext_primary(int row, const char *str, int hilite); 64 | void drawtext_secondary(int row, const char *str, int hilite); 65 | 66 | void make_ui_visible(void); 67 | void make_ui_invisible(void); 68 | 69 | 70 | #ifdef __cplusplus 71 | } 72 | #endif 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /src/main.h: -------------------------------------------------------------------------------- 1 | #ifndef __MAIN_H__ 2 | #define __MAIN_H__ 3 | 4 | #define NORETURN __attribute__ ((noreturn)) 5 | 6 | #include "includes.h" 7 | #if MOVIEPLAYER 8 | extern int usinggbamp; 9 | extern int usingcache; 10 | extern File rom_file; 11 | extern char save_slot; 12 | 13 | extern int rom_filesize; 14 | #endif 15 | 16 | #define TRIM 0x4D495254 17 | 18 | #if FLASHCART 19 | #define AGB_ROM ((u8*)0x8000000) 20 | #define AGB_SRAM ((u8*)0xE000000) 21 | #define AGB_SRAM_SIZE SRAM_SIZE*1024 22 | #define _FLASH_WRITE(pa, pd) { *(((u16 *)AGB_ROM)+((pa)/2)) = pd; __asm("nop"); } 23 | extern u8 flash_type; 24 | extern u32 get_flash_type(); 25 | void flash_write(u8 flash_type, u32 sa); 26 | void save_sram_FLASH(); 27 | #endif 28 | 29 | extern u32 max_multiboot_size; 30 | 31 | extern u32 oldinput; 32 | extern u8 *textstart;//points to first GB rom (initialized by boot.s) 33 | extern u8 *ewram_start;//points to first NES rom (initialized by boot.s) 34 | extern int roms;//total number of roms 35 | extern int selectedrom; 36 | extern int ui_x; 37 | extern int ui_y; 38 | extern int ui_y_real; 39 | extern u32 max_multiboot_size; 40 | #if POGOSHELL 41 | extern char pogoshell_romname[32]; //keep track of rom name (for state saving, etc) 42 | extern char pogoshell; 43 | #endif 44 | extern char rtc; 45 | extern char gameboyplayer; 46 | extern char gbaversion; 47 | 48 | //#define WORSTCASE ((82048)+(82048)/64+16+4+64) 49 | 50 | void C_entry(void); 51 | void splash(const u16* splashImage); 52 | #if MOVIEPLAYER 53 | int get_saved_sram_CF(char* sramname); 54 | int save_sram_CF(char* sramname); 55 | #endif 56 | void jump_to_rommenu(void) NORETURN; 57 | void rommenu(void); 58 | u8 *findrom2(int n); 59 | u8 *findrom(int n); 60 | int drawmenu(int sel); 61 | int getinput(void); 62 | //void cls(int chrmap); 63 | //void drawtext(int row,char *str,int hilite); 64 | //void drawtextl(int row,char *str,int hilite,int len); 65 | //void setdarkness(int dark); 66 | //void setbrightnessall(int light); 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/rumble.c: -------------------------------------------------------------------------------- 1 | #include "gba.h" 2 | 3 | extern char gameboyplayer; 4 | 5 | EWRAM_BSS u32 SerialIn, DoRumble, RumbleCnt; 6 | EWRAM_BSS u16 stage, ind; 7 | EWRAM_BSS u16 SerOut0, SerOut1; 8 | char const GBPData[]={"NINTENDO"}; 9 | 10 | void RumbleInterrupt(void) { 11 | u32 OutData=0; 12 | u16 SerIn0, SerIn1; 13 | u16 *GBPD2 = (u16*)GBPData; 14 | 15 | SerialIn = REG_SIODATA32; 16 | switch(stage) { 17 | case 0: 18 | SerIn0 = SerialIn>>16; 19 | SerIn1 = SerialIn; 20 | if(SerIn0 == SerOut1){ 21 | if(ind <=3){ 22 | if( SerialIn == ~(SerOut1 | (SerOut0<<16)) ){ 23 | ind++; 24 | } 25 | }else{ 26 | if(SerIn1 == 0x8002){ 27 | OutData = 0x10000010; 28 | stage=1; 29 | break; 30 | } 31 | } 32 | }else{ 33 | ind = 0; 34 | } 35 | if(ind <=3){ 36 | SerOut0 = GBPD2[ind]; 37 | }else{ 38 | SerOut0 = 0x8000; 39 | } 40 | SerOut1 = ~SerIn1; 41 | OutData = SerOut1 | (SerOut0<<16); 42 | break; 43 | 44 | case 1: 45 | if(SerialIn == 0x10000010){ 46 | OutData = 0x20000013; 47 | stage=2; 48 | }else{ 49 | stage = 4; 50 | } 51 | break; 52 | 53 | case 2: 54 | if(SerialIn == 0x20000013){ 55 | OutData = 0x40000004; 56 | stage=3; 57 | }else{ 58 | stage = 4; 59 | } 60 | break; 61 | 62 | case 3: 63 | if(SerialIn == 0x30000003){ 64 | if(DoRumble) RumbleCnt = 2; 65 | if(RumbleCnt){ 66 | RumbleCnt--; 67 | OutData = 0x40000026; 68 | }else{ 69 | OutData = 0x40000004; 70 | } 71 | }else{ 72 | stage = 4; 73 | } 74 | break; 75 | 76 | case 4: 77 | SerialIn = 0; 78 | DoRumble = 0; 79 | stage = 0; 80 | ind = 0; 81 | SerOut0 = 0; 82 | SerOut1 = 0; 83 | return; 84 | } 85 | 86 | REG_SIODATA32 = OutData; 87 | REG_SIOCNT |= 0x80; 88 | } 89 | 90 | void StartRumbleComs(void) { 91 | if( (SerialIn != 0x30000003) && gameboyplayer){ 92 | REG_RCNT = 0x0; 93 | REG_SIOCNT = 0x1008; 94 | REG_SIOCNT |= 0x4000; 95 | REG_SIOCNT &=~1; 96 | REG_SIOCNT |= 0x0080; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/sram.h: -------------------------------------------------------------------------------- 1 | #ifndef __SRAM_H__ 2 | #define __SRAM_H__ 3 | 4 | extern int totalstatesize; //how much SRAM is used 5 | extern u32 sram_owner; 6 | 7 | //extern u8 *buffer1; 8 | //extern u8 *buffer2; 9 | //extern u8 *buffer3; 10 | 11 | typedef struct { 12 | u16 size; //header+data 13 | u16 type; //=STATESAVE or SRAMSAVE 14 | u32 uncompressed_size; 15 | u32 framecount; 16 | u32 checksum; 17 | char title[32]; 18 | } stateheader; 19 | 20 | typedef struct { //(modified stateheader) 21 | u16 size; 22 | u16 type; //=CONFIGSAVE 23 | char unused1; 24 | char palettebank; 25 | char misc; 26 | char reserved3; 27 | u32 sram_checksum; //checksum of rom using SRAM e000-ffff 28 | u32 zero; //=0 29 | char reserved4[32]; //="CFG" 30 | } configdata; 31 | 32 | void bytecopy(u8 *dst,u8 *src,int count); 33 | void flush_end_sram(void); 34 | void flush_xgb_sram(void); 35 | void getsram(void); 36 | 37 | u32 checksum_this(void); 38 | u32 checksum_mem(u8 *p); 39 | u32 checksum_romnum(int romNumber); 40 | //u32 checksum(u8 *p); 41 | 42 | void writeerror(void); 43 | int updatestates(int index,int erase,int type); 44 | int twodigits(int n,char *s); 45 | void getstatetimeandsize(char *s,int time,u32 size,u32 freespace); 46 | stateheader* drawstates(int menutype,int *menuitems,int *menuoffset, int needed_size); 47 | void compressstate(lzo_uint size,u16 type,const u8 *src, u8 *dest, void *workspace); 48 | void managesram(void); 49 | void savestatemenu(void); 50 | int findstate(u32 checksum,int type,stateheader **stateptr); 51 | void uncompressstate(int rom,stateheader *sh); 52 | int using_flashcart(void); 53 | void quickload(void); 54 | void quicksave(void); 55 | int backup_gb_sram(int called_from); 56 | int save_new_sram(u8 *SRAM_SOURCE); 57 | int get_saved_sram(void); 58 | void register_sram_owner(void); 59 | void no_sram_owner(void); 60 | void setup_sram_after_loadstate(void); 61 | int find_rom_number_by_checksum(u32 sum); 62 | void loadstatemenu(void); 63 | void writeconfig(void); 64 | void readconfig(void); 65 | 66 | static __inline u32 get_sram_owner() 67 | { 68 | return sram_owner; 69 | } 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /src/gbcgamedetect.c: -------------------------------------------------------------------------------- 1 | #include "includes.h" 2 | 3 | #ifndef ARRSIZE 4 | #define ARRSIZE(xxxx) (sizeof((xxxx))/sizeof((xxxx)[0])) 5 | #endif 6 | 7 | const u8 gameHashTable[] = 8 | { 9 | 0x71, 0x00, 10 | 0xFF, 0x00, 11 | 0x00, 0x00, 12 | 0x15, 0x00, 13 | 0xDB, 0x00, 14 | 0x00, 0x00, 15 | 0x88, 0x00, 16 | 0x00, 0x00, 17 | 0x0C, 0x00, 18 | 0x16, 0x00, 19 | 0x35, 0x00, 20 | 0x67, 0x00, 21 | 0x75, 0x00, 22 | 0x92, 0x00, 23 | 0x99, 0x00, 24 | 0xB7, 0x00, 25 | 0x00, 0x00, 26 | 0x28, 0x41, 27 | 0xA5, 0x41, 28 | 0xE8, 0x00, 29 | 0x00, 0x00, 30 | 0x58, 0x00, 31 | 0x00, 0x00, 32 | 0x6F, 0x00, 33 | 0x00, 0x00, 34 | 0x8C, 0x00, 35 | 0x00, 0x00, 36 | 0x61, 0x45, 37 | 0x00, 0x00, 38 | 0xD3, 0x52, 39 | 0x00, 0x00, 40 | 0x14, 0x00, 41 | 0x00, 0x00, 42 | 0xAA, 0x00, 43 | 0x00, 0x00, 44 | 0x3C, 0x00, 45 | 0x00, 0x00, 46 | 0x9C, 0x00, 47 | 0x00, 0x00, 48 | 0xB3, 0x55, 49 | 0x00, 0x00, 50 | 0x34, 0x00, 51 | 0x66, 0x45, 52 | 0xF4, 0x20, 53 | 0x00, 0x00, 54 | 0x3D, 0x00, 55 | 0x6A, 0x49, 56 | 0x00, 0x00, 57 | 0x19, 0x00, 58 | 0x00, 0x00, 59 | 0x1D, 0x00, 60 | 0x00, 0x00, 61 | 0x46, 0x45, 62 | 0x00, 0x00, 63 | 0x0D, 0x45, 64 | 0x00, 0x00, 65 | 0xBF, 0x20, 66 | 0x00, 0x00, 67 | 0x28, 0x46, 68 | 0x4B, 0x00, 69 | 0x90, 0x00, 70 | 0x9A, 0x00, 71 | 0xBD, 0x00, 72 | 0x00, 0x00, 73 | 0x39, 0x00, 74 | 0x43, 0x00, 75 | 0x97, 0x00, 76 | 0x00, 0x00, 77 | 0xA5, 0x52, 78 | 0x00, 0x00, 79 | 0x18, 0x49, 80 | 0x3F, 0x00, 81 | 0x66, 0x4C, 82 | 0xC6, 0x20, 83 | 0x00, 0x00, 84 | 0x95, 0x00, 85 | 0xB3, 0x52, 86 | 0x00, 0x00, 87 | 0x3E, 0x00, 88 | 0xE0, 0x00, 89 | 0x00, 0x00, 90 | 0x0D, 0x52, 91 | 0x69, 0x00, 92 | 0xF2, 0x00, 93 | 0x00, 0x00, 94 | 0x59, 0x00, 95 | 0xC6, 0x41, 96 | 0x00, 0x00, 97 | 0x86, 0x00, 98 | 0xA8, 0x00, 99 | 0x00, 0x00, 100 | 0xBF, 0x43, 101 | 0xCE, 0x00, 102 | 0xD1, 0x00, 103 | 0xF0, 0x00, 104 | 0x00, 0x00, 105 | 0x36, 0x00, 106 | 0x00, 0x00, 107 | 0x27, 0x42, 108 | 0x49, 0x00, 109 | 0x5C, 0x00, 110 | 0xB3, 0x42, 111 | 0x00, 0x00, 112 | 0xC9, 0x00, 113 | 0x00, 0x00, 114 | 0x4E, 0x00, 115 | 0x00, 0x00, 116 | 0x18, 0x4B, 117 | 0x6A, 0x4B, 118 | 0x6B, 0x00, 119 | 0x00, 0x00, 120 | 0x9D, 0x00, 121 | 0x00, 0x00, 122 | 0x17, 0x00, 123 | 0x27, 0x4E, 124 | 0x61, 0x41, 125 | 0x8B, 0x00, 126 | 0x00, 0x00, 127 | 0x01, 0x00, 128 | 0x10, 0x00, 129 | 0x29, 0x00, 130 | 0x52, 0x00, 131 | 0x5D, 0x00, 132 | 0x68, 0x00, 133 | 0x6D, 0x00, 134 | 0xF6, 0x00, 135 | 0x00, 0x00, 136 | 0x70, 0x00, 137 | 0x00, 0x00, 138 | 0xA2, 0x00, 139 | 0xF7, 0x00, 140 | 0x00, 0x00, 141 | 0x46, 0x52, 142 | 0x00, 0x00, 143 | 0xD3, 0x49, 144 | 0x00, 0x00, 145 | 0xF4, 0x2D 146 | }; 147 | 148 | static const int FIRST_GBC_PALETTE = 49; 149 | 150 | int GetGbcPaletteNumber(u8 *rom) 151 | { 152 | int entryCount = ARRSIZE(gameHashTable); 153 | int nameSum = 0; 154 | for (int i = 0; i < 16; i++) 155 | { 156 | nameSum += rom[0x0134 + i]; 157 | } 158 | int fourthLetter = rom[0x0134 + 3]; 159 | nameSum &= 0xFF; 160 | int gameNumber = 0; 161 | for (int i = 0; i < entryCount; i+=2) 162 | { 163 | int hash = gameHashTable[i]; 164 | int disambig = gameHashTable[i+1]; 165 | if (hash == 0) 166 | { 167 | gameNumber++; 168 | } 169 | else if (hash == nameSum) 170 | { 171 | if (disambig == 0 || disambig == fourthLetter) 172 | { 173 | return gameNumber + FIRST_GBC_PALETTE; 174 | } 175 | } 176 | } 177 | return 0; 178 | } 179 | -------------------------------------------------------------------------------- /src/minilzo.107/minilzo.h: -------------------------------------------------------------------------------- 1 | /* minilzo.h -- mini subset of the LZO real-time data compression library 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer 6 | Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer 7 | Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer 8 | Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer 9 | Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer 10 | 11 | The LZO library is free software; you can redistribute it and/or 12 | modify it under the terms of the GNU General Public License as 13 | published by the Free Software Foundation; either version 2 of 14 | the License, or (at your option) any later version. 15 | 16 | The LZO library is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with the LZO library; see the file COPYING. 23 | If not, write to the Free Software Foundation, Inc., 24 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25 | 26 | Markus F.X.J. Oberhumer 27 | 28 | http://wildsau.idv.uni-linz.ac.at/mfx/lzo.html 29 | */ 30 | 31 | /* 32 | * NOTE: 33 | * the full LZO package can be found at 34 | * http://wildsau.idv.uni-linz.ac.at/mfx/lzo.html 35 | */ 36 | 37 | 38 | #ifndef __MINILZO_H 39 | #define __MINILZO_H 40 | 41 | #define MINILZO_VERSION 0x1070 42 | 43 | #ifdef __LZOCONF_H 44 | # error "you cannot use both LZO and miniLZO" 45 | #endif 46 | 47 | #undef LZO_HAVE_CONFIG_H 48 | #include "lzoconf.h" 49 | 50 | #if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION) 51 | # error "version mismatch in header files" 52 | #endif 53 | 54 | 55 | #ifdef __cplusplus 56 | extern "C" { 57 | #endif 58 | 59 | 60 | /*********************************************************************** 61 | // 62 | ************************************************************************/ 63 | 64 | /* Memory required for the wrkmem parameter. 65 | * When the required size is 0, you can also pass a NULL pointer. 66 | */ 67 | 68 | #define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS 69 | #define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t)) 70 | #define LZO1X_MEM_DECOMPRESS (0) 71 | 72 | 73 | /* compression */ 74 | LZO_EXTERN(int) 75 | lzo1x_1_compress ( const lzo_byte *src, lzo_uint src_len, 76 | lzo_byte *dst, lzo_uint *dst_len, 77 | lzo_voidp wrkmem ); 78 | 79 | /* decompression */ 80 | LZO_EXTERN(int) 81 | lzo1x_decompress ( const lzo_byte *src, lzo_uint src_len, 82 | lzo_byte *dst, lzo_uint *dst_len, 83 | lzo_voidp wrkmem /* NOT USED */ ); 84 | 85 | /* safe decompression with overrun testing */ 86 | LZO_EXTERN(int) 87 | lzo1x_decompress_safe ( const lzo_byte *src, lzo_uint src_len, 88 | lzo_byte *dst, lzo_uint *dst_len, 89 | lzo_voidp wrkmem /* NOT USED */ ); 90 | 91 | 92 | #ifdef __cplusplus 93 | } /* extern "C" */ 94 | #endif 95 | 96 | #endif /* already included */ 97 | 98 | -------------------------------------------------------------------------------- /src/gba.h: -------------------------------------------------------------------------------- 1 | #ifndef GBA_HEADER 2 | #define GBA_HEADER 3 | 4 | #ifndef EWRAM_BSS 5 | #define EWRAM_BSS __attribute__((section(".sbss"))) 6 | #endif 7 | 8 | #ifndef EWRAM_DATA 9 | #define EWRAM_DATA __attribute__((section(".ewram"))) 10 | #endif 11 | 12 | #define SAVE_FORBIDDEN //return; 13 | 14 | typedef unsigned char u8; 15 | typedef unsigned short u16; 16 | typedef unsigned long u32; 17 | 18 | typedef int bool; 19 | 20 | typedef signed char s8; 21 | typedef signed short s16; 22 | typedef signed long s32; 23 | 24 | typedef volatile unsigned char vu8; 25 | typedef volatile unsigned short vu16; 26 | typedef volatile unsigned long vu32; 27 | 28 | typedef void (*fptr)(void); 29 | 30 | extern u8 g_sramsize; 31 | 32 | #ifndef true 33 | #define true 1 34 | #endif 35 | #ifndef false 36 | #define false 0 37 | #endif 38 | 39 | #define MEM_PALETTE ((u16*)0x5000000) 40 | #define MEM_VRAM ((u8*)0x6000000) 41 | #define MEM_OAM ((u32*)0x7000000) 42 | #define MEM_SRAM ((u8*)0xE000000) 43 | #define INTR_VECT (*(u32*)0x3007FFC) 44 | 45 | #define REG_DISPCNT (*(vu32*)0x4000000) 46 | #define MODE0 0 47 | #define MODE1 1 48 | #define MODE2 2 49 | #define MODE3 3 50 | #define MODE4 4 51 | #define MODE5 5 52 | #define OBJ_H_STOP 0x20 53 | #define OBJ_1D 0x40 54 | #define FORCE_BLANK 0x80 55 | #define BG0_EN 0x100 56 | #define BG1_EN 0x200 57 | #define BG2_EN 0x400 58 | #define BG3_EN 0x800 59 | #define OBJ_EN 0x1000 60 | #define WINDOW0_EN 0x2000 61 | #define WINDOW1_EN 0x4000 62 | #define OBJ_WINDOW_EN 0x8000 63 | 64 | #define REG_DISPSTAT (*(vu16*)0x4000004) 65 | #define SCANLINE (*(vu8*)0x4000005) 66 | #define VBLANK 1 67 | #define HBLANK 2 68 | #define VCOUNT_HIT 4 69 | #define V_IRQ 8 70 | #define H_IRQ 16 71 | #define VCOUNT_IRQ 32 72 | 73 | #define REG_BG0HOFS (*(vu16*)0x4000010) 74 | #define REG_BG0VOFS (*(vu16*)0x4000012) 75 | #define REG_BG1HOFS (*(vu16*)0x4000014) 76 | #define REG_BG1VOFS (*(vu16*)0x4000016) 77 | #define REG_BG2HOFS (*(vu16*)0x4000018) 78 | #define REG_BG2VOFS (*(vu16*)0x400001a) 79 | #define REG_BG3HOFS (*(vu16*)0x400001c) 80 | #define REG_BG3VOFS (*(vu16*)0x400001e) 81 | #define REG_BG0CNT (*(vu16*)0x4000008) 82 | #define REG_BG1CNT (*(vu16*)0x400000a) 83 | #define REG_BG2CNT (*(vu16*)0x400000c) 84 | #define REG_BG3CNT (*(vu16*)0x400000e) 85 | 86 | #define REG_WIN0H (*(vu16*)0x4000040) 87 | #define REG_WIN1H (*(vu16*)0x4000042) 88 | #define REG_WIN0V (*(vu16*)0x4000044) 89 | #define REG_WIN1V (*(vu16*)0x4000046) 90 | #define REG_WININ (*(vu16*)0x4000048) 91 | #define REG_WINOUT (*(vu16*)0x400004A) 92 | 93 | #define COLOR16 0x0000 94 | #define COLOR256 0x0080 95 | #define SIZE256x256 0x0000 96 | #define SIZE512x256 0x4000 97 | #define SIZE256x512 0x8000 98 | #define SIZE512x512 0xC000 99 | 100 | #define REG_VCOUNT (*(vu16*)0x4000006) 101 | 102 | #define REG_IE (*(vu16*)0x4000200) 103 | #define REG_IF (*(vu16*)0x4000202) 104 | #define REG_IME (*(vu16*)0x4000208) 105 | 106 | #define REG_P1 (*(vu16*)0x4000130) 107 | #define A_BTN 1 108 | #define B_BTN 2 109 | #define SELECT 4 110 | #define START 8 111 | #define RIGHT 16 112 | #define LEFT 32 113 | #define UP 64 114 | #define DOWN 128 115 | #define R_BTN 256 116 | #define L_BTN 512 117 | 118 | #define REG_DM0CNT_H (*(vu16*)0x40000ba) 119 | #define REG_DM1CNT_H (*(vu16*)0x40000c6) 120 | #define REG_DM2CNT_H (*(vu16*)0x40000d2) 121 | #define REG_DM3CNT_H (*(vu16*)0x40000de) 122 | #define REG_BLDMOD (*(vu16*)0x4000050) 123 | #define REG_BLDALPHA (*(vu16*)0x4000052) 124 | #define REG_BLDY (*(vu16*)0x4000054) 125 | #define REG_SGCNT0_L (*(vu16*)0x4000080) 126 | #define REG_SGBIAS (*(vu16*)0x4000088) 127 | #define REG_BG2X (*(vu32*)0x4000028) 128 | #define REG_BG2Y (*(vu32*)0x400002c) 129 | #define REG_BG2PA (*(vu16*)0x4000020) 130 | #define REG_BG2PB (*(vu16*)0x4000022) 131 | #define REG_BG2PC (*(vu16*)0x4000024) 132 | #define REG_BG2PD (*(vu16*)0x4000026) 133 | 134 | #define REG_SIODATA32 (*(vu32*)0x4000120) 135 | #define REG_SIOMULTI0 (*(vu16*)0x4000120) 136 | #define REG_SIOMULTI1 (*(vu16*)0x4000122) 137 | #define REG_SIOMULTI2 (*(vu16*)0x4000124) 138 | #define REG_SIOMULTI3 (*(vu16*)0x4000126) 139 | #define REG_SIOCNT (*(vu16*)0x4000128) 140 | #define REG_SIOMLT_SEND (*(vu16*)0x400012a) 141 | #define REG_RCNT (*(vu16*)0x4000134) 142 | #define REG_TM0CNT (*(vu16*)0x4000102) 143 | #define REG_WRWAITCTL (*(vu32*)0x04000800) 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /src/visoly.s: -------------------------------------------------------------------------------- 1 | #include "equates.h" 2 | 3 | .text 4 | 5 | #if VISOLY 6 | 7 | global_func VISOLY_START 8 | global_func VISOLY_END 9 | 10 | .pool 11 | 12 | VISOLY_START: 13 | @Disable interrupts and DMA before calling this 14 | adr r2,rom_addresses @the addresses to write to/read from (or special numbers indicating a run) 15 | adr r3,data_values @the 16-bit data values to write (or special numbers indicating a run) 16 | mov r4,#0 @r4 = number of same address in a run (address values smaller than 65536 indicate this) 17 | mov r5,#0 @r5 = number of same 16-bit values to write (data values smaller than 512 indicate this) 18 | 19 | @ reset EZ FLASH, SC, Visoly 20 | ldr r1,=6+4+8+1500 @6 writes for EZ, 4 writes for supercard, 1508 writes for Visoly, total is 1518 21 | bl do_writes 22 | 23 | @ reset M3, G6 24 | mov r1,#14+14 @14 reads for M3, 14 reads for G6 25 | bl do_reads 26 | 27 | mov r0, #0 28 | ldr r1,=0x3007ffa @must be 0 before swi 0x00 is run, otherwise it tries to start from 0x02000000. 29 | strh r0,[r1] 30 | 31 | mov r0, #8 @VRAM clear 32 | swi 0x010000 33 | @Reboot 34 | swi 0x000000 35 | 36 | 37 | @ ldmfd sp!,{lr,r4,r5} 38 | @ bx lr 39 | get_word: 40 | movs r4,r4 @any left in the run? jump ahead 41 | bne 1f 42 | ldr r12,[r2],#4 @read address 43 | movs r12,r12 @if address == 0, or address > 65536, it's a legitimate address. 44 | bxeq lr 45 | cmp r12,#0x00010000 @otherwise, it's a RLE length 46 | bxgt lr 47 | sub r4,r12,#1 @process first word 48 | ldr r12,[r2],#4 49 | bx lr 50 | 1: 51 | ldr r12,[r2,#-4] @read old word again 52 | sub r4,r4,#1 @decrease remaining count 53 | bx lr 54 | 55 | get_hword: 56 | movs r5,r5 @any left in the run? jump ahead 57 | bne 1f 58 | ldrh r0,[r3],#2 @read data 59 | movs r0,r0 @if data == 0, or data > 512, it's a proper data word 60 | bxeq lr 61 | cmp r0,#0x0200 @otherwise it's a RLE length 62 | bxgt lr 63 | sub r5,r0,#1 @process first halfword 64 | ldrh r0,[r3],#2 65 | bx lr 66 | 1: 67 | ldrh r0,[r3,#-2] @read old halfword again 68 | sub r5,r5,#1 @decrease remaining count 69 | bx lr 70 | 71 | do_reads: 72 | stmfd sp!,{lr} 73 | 0: 74 | bl get_word @Get the address to read from 75 | ldrh r0,[r12] @perform the read 76 | subs r1,r1,#1 @decrease remaining 77 | bne 0b @repeat for the next address 78 | 79 | ldmfd sp!,{pc} 80 | 81 | do_writes: 82 | stmfd sp!,{lr} 83 | 0: 84 | bl get_word @Get the address to write to 85 | bl get_hword @Get the value to write 86 | strh r0,[r12] @perform the write 87 | subs r1,r1,#1 @decrease remaining 88 | bne 0b @repeat for the next address and value 89 | 90 | ldmfd sp!,{pc} 91 | 92 | rom_addresses: 93 | @ez flash 94 | .word 0x9FE0000 95 | .word 0x8000000 96 | .word 0x8020000 97 | .word 0x8040000 98 | .word 0x9880000 99 | .word 0x9FC0000 100 | 101 | @SC 102 | .word 4 103 | .word 0x09FFFFFE 104 | 105 | @Visoly 106 | .word (0x00987654 * 2) + 0x08000000 107 | .word 1001 108 | .word (0x00012345 * 2) + 0x08000000 109 | .word (0x00987654 * 2) + 0x08000000 110 | .word (0x00012345 * 2) + 0x08000000 111 | .word (0x00765400 * 2) + 0x08000000 112 | .word (0x00013450 * 2) + 0x08000000 113 | .word 500 114 | .word (0x00012345 * 2) + 0x08000000 115 | .word (0x00987654 * 2) + 0x08000000 116 | .word 0x096B592E 117 | 118 | @M3 (reads) 119 | .word 0x08E00002 120 | .word 0x0800000E 121 | .word 0x08801FFC 122 | .word 0x0800104A 123 | .word 0x08800612 124 | .word 0x08000000 125 | .word 0x08801B66 126 | .word 0x08800008 127 | .word 0x0800080E 128 | .word 0x08000000 129 | .word 0x080001E4 130 | .word 0x080001E4 131 | .word 0x08000188 132 | .word 0x08000188 133 | 134 | @G6 (reads) 135 | .word 0x09000000 136 | .word 0x09FFFFE0 137 | .word 3 138 | .word 0x09FFFFEC 139 | .word 3 140 | .word 0x09FFFFFC 141 | .word 3 142 | .word 0x09FFFF4A 143 | .word 0x09200000 144 | .word 0x09FFFFF0 145 | .word 0x09FFFFE8 146 | 147 | data_values: 148 | @ez_flash 149 | .hword 0xD200 150 | .hword 0x1500 151 | .hword 0xD200 152 | .hword 0x1500 153 | .hword 0x8000 154 | .hword 0x1500 155 | 156 | @SC 157 | .hword 0xA55A 158 | .hword 0xA55A 159 | .hword 0 160 | .hword 0 161 | 162 | @visoly 163 | .hword 0x5354 164 | .hword 500 165 | .hword 0x1234 166 | .hword 0x5354 167 | .hword 500 168 | .hword 0x5678 169 | .hword 0x5354 170 | .hword 0x5354 171 | .hword 0x5678 172 | .hword 0x1234 173 | .hword 500 174 | .hword 0xABCD 175 | .hword 0x5354 176 | .hword 0 177 | 178 | .pool 179 | VISOLY_END: 180 | 181 | .pool 182 | @.end 183 | 184 | #endif 185 | -------------------------------------------------------------------------------- /src/minilzo.107/testmini.c: -------------------------------------------------------------------------------- 1 | /* testmini.c -- very simple test program for the miniLZO library 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer 6 | 7 | The LZO library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2 of 10 | the License, or (at your option) any later version. 11 | 12 | The LZO library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with the LZO library; see the file COPYING. 19 | If not, write to the Free Software Foundation, Inc., 20 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 21 | 22 | Markus F.X.J. Oberhumer 23 | markus.oberhumer@jk.uni-linz.ac.at 24 | */ 25 | 26 | 27 | #include 28 | #include 29 | 30 | 31 | /************************************************************************* 32 | // This program shows the basic usage of the LZO library. 33 | // We will compress a block of data and decompress again. 34 | // 35 | // For more information, documentation, example programs and other support 36 | // files (like Makefiles and build scripts) please download the full LZO 37 | // package from 38 | // http://wildsau.idv.uni-linz.ac.at/mfx/lzo.html 39 | **************************************************************************/ 40 | 41 | /* First let's include "minizo.h". */ 42 | 43 | #include "minilzo.h" 44 | 45 | 46 | /* We want to compress the data block at `in' with length `IN_LEN' to 47 | * the block at `out'. Because the input block may be incompressible, 48 | * we must provide a little more output space in case that compression 49 | * is not possible. 50 | */ 51 | 52 | #define IN_LEN (128*1024L) 53 | #define OUT_LEN (IN_LEN + IN_LEN / 64 + 16 + 3) 54 | 55 | static lzo_byte in [ IN_LEN ]; 56 | static lzo_byte out [ OUT_LEN ]; 57 | 58 | 59 | /* Work-memory needed for compression. Allocate memory in units 60 | * of `long' (instead of `char') to make sure it is properly aligned. 61 | */ 62 | 63 | #define HEAP_ALLOC(var,size) \ 64 | long __LZO_MMODEL var [ ((size) + (sizeof(long) - 1)) / sizeof(long) ] 65 | 66 | static HEAP_ALLOC(wrkmem,LZO1X_1_MEM_COMPRESS); 67 | 68 | 69 | /************************************************************************* 70 | // 71 | **************************************************************************/ 72 | 73 | int main(int argc, char *argv[]) 74 | { 75 | int r; 76 | lzo_uint in_len; 77 | lzo_uint out_len; 78 | lzo_uint new_len; 79 | 80 | #if defined(__EMX__) 81 | _response(&argc,&argv); 82 | _wildcard(&argc,&argv); 83 | #endif 84 | 85 | if (argc < 0 && argv == NULL) /* avoid warning about unused args */ 86 | return 0; 87 | 88 | printf("\nLZO real-time data compression library (v%s, %s).\n", 89 | lzo_version_string(), lzo_version_date()); 90 | printf("Copyright (C) 1996-2000 Markus Franz Xaver Johannes Oberhumer\n\n"); 91 | 92 | 93 | /* 94 | * Step 1: initialize the LZO library 95 | */ 96 | if (lzo_init() != LZO_E_OK) 97 | { 98 | printf("lzo_init() failed !!!\n"); 99 | return 3; 100 | } 101 | 102 | /* 103 | * Step 2: prepare the input block that will get compressed. 104 | * We just fill it with zeros in this example program, 105 | * but you would use your real-world data here. 106 | */ 107 | in_len = IN_LEN; 108 | lzo_memset(in,0,in_len); 109 | 110 | /* 111 | * Step 3: compress from `in' to `out' with LZO1X-1 112 | */ 113 | r = lzo1x_1_compress(in,in_len,out,&out_len,wrkmem); 114 | if (r == LZO_E_OK) 115 | printf("compressed %lu bytes into %lu bytes\n", 116 | (long) in_len, (long) out_len); 117 | else 118 | { 119 | /* this should NEVER happen */ 120 | printf("internal error - compression failed: %d\n", r); 121 | return 2; 122 | } 123 | /* check for an incompressible block */ 124 | if (out_len >= in_len) 125 | { 126 | printf("This block contains incompressible data.\n"); 127 | return 0; 128 | } 129 | 130 | /* 131 | * Step 4: decompress again, now going from `out' to `in' 132 | */ 133 | r = lzo1x_decompress(out,out_len,in,&new_len,NULL); 134 | if (r == LZO_E_OK && new_len == in_len) 135 | printf("decompressed %lu bytes back into %lu bytes\n", 136 | (long) out_len, (long) in_len); 137 | else 138 | { 139 | /* this should NEVER happen */ 140 | printf("internal error - decompression failed: %d\n", r); 141 | return 1; 142 | } 143 | 144 | printf("\nminiLZO simple compression test passed.\n"); 145 | return 0; 146 | } 147 | 148 | /* 149 | vi:ts=4 150 | */ 151 | 152 | -------------------------------------------------------------------------------- /src/minilzo.107/README.LZO: -------------------------------------------------------------------------------- 1 | -----BEGIN PGP SIGNED MESSAGE----- 2 | 3 | 4 | ============================================================================ 5 | miniLZO -- mini subset of the LZO real-time data compression library 6 | ============================================================================ 7 | 8 | Author : Markus Franz Xaver Johannes Oberhumer 9 | 10 | http://wildsau.idv.uni-linz.ac.at/mfx/lzo.html 11 | Version : 1.07 12 | Date : 18-Oct-2000 13 | 14 | I've created miniLZO for projects where it is inconvenient to 15 | include (or require) the full LZO source code just because you 16 | want to add a little bit of data compression to your application. 17 | 18 | miniLZO implements the LZO1X-1 compressor and both the standard and 19 | safe LZO1X decompressor. Apart from fast compression it also useful 20 | for situations where you want to use pre-compressed data files (which 21 | must have been compressed with LZO1X-999). 22 | 23 | miniLZO consists of one C source file and two header files: 24 | minilzo.c 25 | minilzo.h 26 | lzoconf.h 27 | 28 | To use miniLZO just copy these files into your source directory, add 29 | minilzo.c to your Makefile and #include minilzo.h from your program. 30 | Note: you also must distribute this file (`README.LZO') with your project. 31 | 32 | minilzo.o compiles to about 6 kB (using gcc or Watcom C on a i386), and 33 | the sources are about 14 kB when packed with zip - so there's no more 34 | excuse that your application doesn't support data compression :-) 35 | 36 | For more information, documentation, example programs and other support 37 | files (like Makefiles and build scripts) please download the full LZO 38 | package from 39 | http://wildsau.idv.uni-linz.ac.at/mfx/lzo.html 40 | 41 | Have fun, 42 | Markus 43 | 44 | 45 | P.S. minilzo.c is generated automatically from the LZO sources and 46 | therefore functionality is completely identical 47 | 48 | 49 | Appendix A: building miniLZO 50 | ---------------------------- 51 | miniLZO is written such a way that it should compile and run 52 | out-of-the-box on most machines. 53 | 54 | If you are running on a very unusual architecture and lzo_init() fails then 55 | you should first recompile with `-DLZO_DEBUG' to see what causes the failure. 56 | The most probable case is something like `sizeof(char *) != sizeof(long)'. 57 | After identifying the problem you can compile by adding some defines 58 | like `-DSIZEOF_CHAR_P=8' to your Makefile. 59 | 60 | The best solution is (of course) using Autoconf - if your project uses 61 | Autoconf anyway just add `-DMINILZO_HAVE_CONFIG_H' to your compiler 62 | flags when compiling minilzo.c. See the LZO distribution for an example 63 | how to set up configure.in. 64 | 65 | 66 | Appendix B: list of public functions available in miniLZO 67 | --------------------------------------------------------- 68 | Library initialization 69 | lzo_init() 70 | 71 | Compression 72 | lzo1x_1_compress() 73 | 74 | Decompression 75 | lzo1x_decompress() 76 | lzo1x_decompress_safe() 77 | 78 | Checksum functions 79 | lzo_adler32() 80 | 81 | Version functions 82 | lzo_version() 83 | lzo_version_string() 84 | lzo_version_date() 85 | 86 | Portable (but slow) string functions 87 | lzo_memcmp() 88 | lzo_memcpy() 89 | lzo_memmove() 90 | lzo_memset() 91 | 92 | 93 | Appendix C: suggested macros for `configure.in' when using Autoconf 94 | ------------------------------------------------------------------- 95 | Checks for typedefs and structures 96 | AC_CHECK_TYPE(ptrdiff_t,long) 97 | AC_TYPE_SIZE_T 98 | AC_CHECK_SIZEOF(unsigned short) 99 | AC_CHECK_SIZEOF(unsigned) 100 | AC_CHECK_SIZEOF(unsigned long) 101 | AC_CHECK_SIZEOF(char *) 102 | AC_CHECK_SIZEOF(ptrdiff_t) 103 | AC_CHECK_SIZEOF(size_t) 104 | 105 | Checks for compiler characteristics 106 | AC_C_CONST 107 | 108 | Checks for library functions 109 | AC_CHECK_FUNCS(memcmp memcpy memmove memset) 110 | 111 | 112 | Appendix D: Copyright 113 | --------------------- 114 | LZO and miniLZO are Copyright (C) 1996-2000 115 | Markus Franz Xaver Johannes Oberhumer 116 | 117 | LZO and miniLZO are distributed under the terms of the GNU General 118 | Public License (GPL). See the file COPYING. 119 | 120 | Special licenses for commercial and other applications which 121 | are not willing to accept the GNU General Public License 122 | are available by contacting the author. 123 | 124 | 125 | 126 | 127 | -----BEGIN PGP SIGNATURE----- 128 | Version: 2.6.3ia 129 | Charset: noconv 130 | 131 | iQCVAwUBOez6EG10fyLu8beJAQFYJAQAx5RYO13VB8A25KGP2BFzvHWfX+QkGTmO 132 | LEUfTm2URZZ9DDyz7UbZsVWuK+ztOqD4H6BiwpXldJ1JWf02gI9seCZd7GA5LaGP 133 | VyLrU2Kuv7DVf74cVMRs+CSKDYV6AW0KsGDeBY7Uceh7r9nBSM8QJkcqCnZnFkm5 134 | JXP8ySD6u9U= 135 | =oXrB 136 | -----END PGP SIGNATURE----- 137 | -------------------------------------------------------------------------------- /src/speedhacks_old._s: -------------------------------------------------------------------------------- 1 | .if SPEEDHACKS_OLD 2 | .global g_hackflags 3 | .global g_hackflags2 4 | .global SPEEDHACK_FIND_JR_Z_BUF 5 | .global SPEEDHACK_FIND_JR_NZ_BUF 6 | .global SPEEDHACK_FIND_JR_C_BUF 7 | .global SPEEDHACK_FIND_JR_NC_BUF 8 | .endif 9 | 10 | .if SPEEDHACKS_OLD 11 | .global g_hackflags 12 | .global g_hackflags2 13 | .global cpuhack_reset 14 | .endif 15 | 16 | .if SPEEDHACKS_OLD 17 | @---------------------------------------------------------------------------- 18 | _20x:@ JR NZ,* jump if not zero - speedhack version 19 | @---------------------------------------------------------------------------- 20 | ldrsb r0,[gb_pc],#1 21 | tst gb_flg,#PSR_Z 22 | bne 0f 23 | add gb_pc,gb_pc,r0 24 | sub cycles,cycles,#4*CYCLE 25 | cmp r0,#-4 26 | andeq cycles,cycles,#CYC_MASK 27 | 0: 28 | fetch 8 29 | .endif 30 | 31 | .if SPEEDHACKS_OLD 32 | @---------------------------------------------------------------------------- 33 | _28x:@ JR Z,* jump if zero - speedhack version 34 | @---------------------------------------------------------------------------- 35 | tst gb_flg,#PSR_Z 36 | ldrsb r0,[gb_pc],#1 37 | beq 0f 38 | add gb_pc,gb_pc,r0 39 | sub cycles,cycles,#4*CYCLE 40 | cmp r0,#-4 41 | andeq cycles,cycles,#CYC_MASK 42 | 0: 43 | fetch 8 44 | 45 | .endif 46 | 47 | .if SPEEDHACKS_OLD 48 | @---------------------------------------------------------------------------- 49 | _30x:@ JR NC,* jump if no carry - speedhack version 50 | @---------------------------------------------------------------------------- 51 | tst gb_flg,#PSR_C 52 | ldrsb r0,[gb_pc],#1 53 | bne 0f 54 | add gb_pc,gb_pc,r0 55 | sub cycles,cycles,#4*CYCLE 56 | cmp r0,#-4 57 | andeq cycles,cycles,#CYC_MASK 58 | 0: 59 | fetch 8 60 | .endif 61 | 62 | .if SPEEDHACKS_OLD 63 | @---------------------------------------------------------------------------- 64 | _38x:@ JR C,* jump if carry - speedhack version 65 | @---------------------------------------------------------------------------- 66 | tst gb_flg,#PSR_C 67 | ldrsb r0,[gb_pc],#1 68 | beq 0f 69 | add gb_pc,gb_pc,r0 70 | sub cycles,cycles,#4*CYCLE 71 | cmp r0,#-4 72 | andeq cycles,cycles,#CYC_MASK 73 | 0: 74 | fetch 8 75 | .endif 76 | 77 | .if SPEEDHACKS_OLD 78 | @---------------------------------------------------------------------------- 79 | _20z:@ JR NZ,* jump if not zero - speedhack version 80 | @---------------------------------------------------------------------------- 81 | ldr r1,=SPEEDHACK_FIND_JR_NZ_BUF 82 | ldr r2,=_20 83 | b _find_speedhack_thingy 84 | @---------------------------------------------------------------------------- 85 | _28z:@ JR Z,* jump if zero - speedhack version 86 | @---------------------------------------------------------------------------- 87 | ldr r1,=SPEEDHACK_FIND_JR_Z_BUF 88 | ldr r2,=_28 89 | b _find_speedhack_thingy 90 | @---------------------------------------------------------------------------- 91 | _30z:@ JR NC,* jump if no carry - speedhack version 92 | @---------------------------------------------------------------------------- 93 | ldr r1,=SPEEDHACK_FIND_JR_NC_BUF 94 | ldr r2,=_30 95 | b _find_speedhack_thingy 96 | @---------------------------------------------------------------------------- 97 | _38z:@ JR C,* jump if carry - speedhack version 98 | @---------------------------------------------------------------------------- 99 | ldr r1,=SPEEDHACK_FIND_JR_C_BUF 100 | ldr r2,=_38 101 | b _find_speedhack_thingy 102 | 103 | _find_speedhack_thingy: 104 | ldrsb r0,[gb_pc] 105 | 106 | @between -17 and -2 107 | cmp r0,#-17 108 | bxlt r2 109 | cmp r0,#-2 110 | bxgt r2 111 | rsb r0,r0,#0 112 | sub r0,r0,#2 113 | mov r0,r0,lsl#2 114 | add r0,r0,r1 115 | ldr r1,[r0] 116 | add r1,r1,#1 117 | str r1,[r0] 118 | bx r2 119 | .endif 120 | 121 | .if SPEEDHACKS_OLD 122 | normalops: 123 | .word _20,_28,_30,_38 124 | jmpops: 125 | .word _20x,_28x,_30x,_38x 126 | finderops: 127 | .word _20z,_28z,_30z,_38z 128 | opindex: 129 | .word op_table+0x20*4,op_table+0x28*4,op_table+0x30*4,op_table+0x38*4 130 | 131 | cpuhack_reset: 132 | stmfd sp!,{r0-r4,r10} 133 | ldr r10,=GLOBAL_PTR_BASE 134 | 135 | ldrb_ r0,hackflags 136 | cmp r0,#1 137 | adreq r2,finderops 138 | adrne r2,normalops 139 | adr r3,opindex 140 | mov r4,#3 141 | 0: 142 | ldr r0,[r2,r4,lsl#2] 143 | ldr r1,[r3,r4,lsl#2] 144 | str r0,[r1] 145 | subs r4,r4,#1 146 | bpl 0b 147 | 148 | ldrb_ r4,hackflags 149 | subs r4,r4,#2 150 | bmi 1f 151 | adr r2,jmpops 152 | ldr r0,[r2,r4,lsl#2] 153 | ldr r1,[r3,r4,lsl#2] 154 | str r0,[r1] 155 | 156 | ldrb_ r1,hackflags2 157 | strb r1,[r0,#5*4] 158 | 1: 159 | ldmfd sp!,{r0-r4,r10} 160 | bx lr 161 | .endif 162 | 163 | .if SPEEDHACKS_OLD 164 | bl cpuhack_reset 165 | .endif 166 | 167 | .if SPEEDHACKS_OLD 168 | simple_speedhack_test: 169 | @is it ld a,(Cxxx/Dxxx) (FA) 170 | ldrb r0,[gb_pc] 171 | cmp r0,#0xFA 172 | bne_long _fetch8 173 | @bxne lr 174 | ldrb r0,[gb_pc,#2] 175 | and r0,r0,#0xE0 176 | cmp r0,#0xC0 177 | bne_long _fetch8 178 | @bxne lr 179 | 180 | @is it "cp #" (FE) or "and a" (A7) 181 | ldrb r0,[gb_pc,#3] 182 | cmp r0,#0xFE 183 | cmpne r0,#0xA7 184 | @peform the speedhack 185 | andeq cycles,cycles,#CYC_MASK 186 | b_long _fetch8 187 | @bx lr 188 | .endif 189 | 190 | 191 | -------------------------------------------------------------------------------- /src/cache.c: -------------------------------------------------------------------------------- 1 | #include "includes.h" 2 | 3 | #define page_size (16) 4 | #define page_size_2 (page_size*1024) 5 | 6 | #define CRAP_AMOUNT 512 7 | 8 | u8 *const bank_1=(u8*)0x06010000-CRAP_AMOUNT; 9 | 10 | #if MOVIEPLAYER 11 | int cache_queue_cursor; 12 | u16 prgcache[MAX_CACHE_SIZE]; 13 | u8* cache_location[MAX_CACHE_SIZE]; 14 | u8* cachebase; 15 | u8 cachepages; 16 | u32* pageoffsets; 17 | #endif 18 | 19 | u8 *make_instant_pages(u8* rom_base) 20 | { 21 | //this is for cases where there is no caching! 22 | u32 *p=(u32*)rom_base; 23 | u8 *page0_rom; 24 | // u8 cartsizebyte; 25 | int i; 26 | 27 | #if MOVIEPLAYER 28 | if (usingcache) 29 | { 30 | return rom_base; 31 | } 32 | #endif 33 | 34 | #if USETRIM 35 | if (*p==TRIM) 36 | { 37 | p+=2; 38 | // num_pages=p[0]/4-8; 39 | // page_mask=num_pages-1; 40 | for (i=0;i<256;i++) 41 | { 42 | INSTANT_PAGES[i]=rom_base+p[i];//&page_mask]; 43 | } 44 | } 45 | else 46 | #endif 47 | { 48 | // num_pages=(2<0) 59 | { 60 | //copy bank 0 to VRAM 61 | // memcpy(bank_1,page0_rom,16384); 62 | memcpy(bank_1,page0_rom,16384+CRAP_AMOUNT); 63 | INSTANT_PAGES[0]=bank_1; 64 | } 65 | return page0_rom; 66 | } 67 | 68 | #if !MOVIEPLAYER 69 | void init_cache() {} 70 | #endif 71 | 72 | #if MOVIEPLAYER 73 | 74 | void init_cache() 75 | { 76 | int i; 77 | u8* dest=ewram_start; 78 | 79 | #if RESIZABLE 80 | u8 *end_of_cache=END_of_exram; 81 | #else 82 | u8 *end_of_cache=(u8*)(&END_OF_EXRAM); 83 | #endif 84 | if (!usingcache) return; 85 | 86 | // g_banks[0]=0; 87 | // g_banks[1]=1; 88 | 89 | cachebase=dest; 90 | cachepages=(end_of_cache-cachebase)/page_size_2; 91 | //set up cache locations, first few are sequential 92 | for (i=0;i=cachepages) cache_queue_cursor=0; 184 | 185 | for (j=0;j<2;j++) 186 | { 187 | if (slotcontent!=65535) 188 | { 189 | if (banks[j]*16/page_size==slotcontent) 190 | { 191 | goto slot_is_locked; 192 | } 193 | } 194 | } 195 | prgcache[i]=bank; 196 | 197 | #if 0 198 | if (usingcompcache) 199 | { 200 | int srcoffset; 201 | srcoffset = 16 + pageoffsets[bank]; 202 | // dest = (u8*)06014000; 203 | // FAT_fseek(rom_file,srcoffset,SEEK_SET); 204 | // src=FAT_fread_16(dest,1,16384,rom_file); 205 | 206 | dest = cachebase+0x4000*cachepages; 207 | FAT_fseek(rom_file,srcoffset,SEEK_SET); 208 | FAT_fread(dest,1,16384,rom_file); 209 | src=dest; 210 | dest =cachebase+0x4000*i; 211 | depack(src,dest); 212 | } 213 | else 214 | #endif 215 | loadcachepage(i,bank); 216 | } 217 | 218 | void get_rom_map() 219 | { 220 | u32 *banks=g_banks; 221 | u8**memmap = g_memmap_tbl; 222 | u8**instant_prg = INSTANT_PAGES; 223 | int i; 224 | int j; 225 | 226 | for (i=0;i<2;i++) 227 | { 228 | u8* data=instant_prg[banks[i]]-(i*16384); 229 | for (j=0;j<4;j++) 230 | { 231 | memmap[i*4+j]=data; 232 | } 233 | } 234 | } 235 | void update_cache() 236 | { 237 | //updates the cache's state, and all the lookup tables 238 | //also fixes the memory map and vram map 239 | u32 *banks=g_banks; 240 | int i; 241 | 242 | clear_instant_prg(); 243 | for (i=0;i<2;i++) 244 | { 245 | getbank(banks[i]*16); 246 | } 247 | regenerate_instant_prg(); 248 | get_rom_map(); 249 | } 250 | 251 | #if RESIZABLE 252 | void add_exram() 253 | { 254 | GBC_exramsize=0x6000; 255 | GBC_exram=END_of_exram-GBC_exramsize; 256 | memset(GBC_exram,0,GBC_exramsize); 257 | END_of_exram=GBC_exram; 258 | init_cache(); 259 | update_cache(); 260 | } 261 | #endif 262 | 263 | /* 264 | void reload_vram_page1() 265 | { 266 | int i=cachepages-2; 267 | int bank=prgcache[i]; 268 | if (bank<65535) 269 | { 270 | loadcachepage(i,bank); 271 | } 272 | } 273 | */ 274 | 275 | #endif 276 | -------------------------------------------------------------------------------- /src/state.s: -------------------------------------------------------------------------------- 1 | .text 2 | global_func SaveIo 3 | global_func LoadIo 4 | global_func SaveRegs 5 | global_func LoadRegs 6 | global_func AfterLoadState 7 | 8 | SaveRegs: 9 | stmfd sp!,{r3-r11,lr} 10 | mov r12,r0 11 | 12 | @AF, BC, DE, HL, SP, PC, Cycles 13 | ldr r10,=GLOBAL_PTR_BASE 14 | adr_ r2,cpuregs 15 | ldmia r2,{gb_flg-gb_pc,gb_sp} 16 | encodeFLG 17 | orr r0,r0,gb_a,lsr#16 18 | strh r0,[r12],#2 19 | mov r0,gb_bc,lsr#16 20 | strh r0,[r12],#2 21 | mov r0,gb_de,lsr#16 22 | strh r0,[r12],#2 23 | mov r0,gb_hl,lsr#16 24 | strh r0,[r12],#2 25 | mov r0,gb_sp,lsr#16 26 | strh r0,[r12],#2 27 | ldr_ r0,lastbank 28 | sub r0,gb_pc,r0 29 | strh r0,[r12],#2 30 | str cycles,[r12],#4 31 | ldmfd sp!,{r3-r11,lr} 32 | mov r0,#16 33 | bx lr 34 | LoadRegs: 35 | stmfd sp!,{r3-r11,lr} 36 | mov r12,r0 37 | ldr r10,=GLOBAL_PTR_BASE 38 | @AF, BC, DE, HL, SP, PC, Cycles 39 | 40 | adr_ r2,cpuregs 41 | ldmia r2,{gb_flg-gb_pc,gb_sp} 42 | ldrb r0,[r12],#1 43 | decodeFLG 44 | ldrb r0,[r12],#1 45 | mov gb_a,r0,lsl#24 46 | ldrh r0,[r12],#2 47 | mov gb_bc,r0,lsl#16 48 | ldrh r0,[r12],#2 49 | mov gb_de,r0,lsl#16 50 | ldrh r0,[r12],#2 51 | mov gb_hl,r0,lsl#16 52 | ldrh r0,[r12],#2 53 | mov gb_sp,r0,lsl#16 54 | ldrh r0,[r12],#2 55 | mov gb_pc,r0 56 | ldr cycles,[r12],#4 57 | 58 | stmia r2,{gb_flg-gb_pc,gb_sp} 59 | ldmfd sp!,{r3-r11,lr} 60 | mov r0,#1 61 | bx lr 62 | 63 | SaveIo: 64 | @r0 = address to write 256 bytes to 65 | stmfd sp!,{r3-r11,lr} 66 | 67 | ldr r10,=GLOBAL_PTR_BASE 68 | ldr_ cycles,cpuregs+0x14 69 | mov r3,r0 70 | @clear state to 00s 71 | mov r2,#0x80 72 | mov r1,#0 73 | bl memset32_ 74 | 75 | mov r4,#0 76 | 0: 77 | mov r0,#0 78 | mov r2,r4 79 | bl IO_High_R 80 | strb r0,[r3,r4] 81 | add r4,r4,#1 82 | cmp r4,#0x100 83 | blt 0b 84 | 85 | @write-only sound registers 86 | ldrb_ r0,sound_shadow+0 87 | strb r0,[r3,#0x11] 88 | ldrb_ r0,sound_shadow+1 89 | strb r0,[r3,#0x13] 90 | ldrb_ r0,sound_shadow+2 91 | strb r0,[r3,#0x14] 92 | 93 | ldrb_ r0,sound_shadow+3 94 | strb r0,[r3,#0x16] 95 | ldrb_ r0,sound_shadow+4 96 | strb r0,[r3,#0x18] 97 | ldrb_ r0,sound_shadow+5 98 | strb r0,[r3,#0x19] 99 | 100 | ldrb_ r0,sound_shadow+6 101 | strb r0,[r3,#0x1B] 102 | ldrb_ r0,sound_shadow+7 103 | strb r0,[r3,#0x1D] 104 | ldrb_ r0,sound_shadow+8 105 | strb r0,[r3,#0x1E] 106 | 107 | 108 | ldmfd sp!,{r3-r11,lr} 109 | mov r0,#0x100 110 | bx lr 111 | 112 | 113 | LoadIo: 114 | @TODO: write this 115 | @r0 = address to read 256 bytes from 116 | stmfd sp!,{r3-r11,lr} 117 | ldr r10,=GLOBAL_PTR_BASE 118 | ldr_ cycles,cpuregs+0x14 119 | mov r3,r0 120 | @joystick, serial port 121 | ldrb r0,[r3,#0x00] 122 | strb_ r0,joy0serial 123 | ldrb r0,[r3,#0x02] 124 | strb_ r0,stctrl 125 | @divider, timer, interrupt flags 126 | ldrb r0,[r3,#0x04] 127 | strb_ r0,dividereg+3 128 | 129 | @timer flags, interrupt flags, sound registers... 130 | mov r0,#0x05 131 | 132 | ldrb r0,[r3,#0x05] 133 | strb_ r0,timercounter+3 134 | ldrb r0,[r3,#0x06] 135 | strb_ r0,timermodulo 136 | ldrb r0,[r3,#0x07] 137 | strb_ r0,timerctrl 138 | ldrb r0,[r3,#0x0F] 139 | strb_ r0,gb_if 140 | 141 | @write IO registers 10-3F directly 142 | mov r4,#0x10 143 | 0: 144 | ldrb r0,[r3,r4] 145 | @set Initial flag on all sound registers 146 | @ cmp r4,#0x14 147 | @ cmpne r4,#0x19 148 | @ cmpne r4,#0x1E 149 | @ cmpne r4,#0x23 150 | @ orreq r0,r0,#0x80 151 | mov r2,r4 152 | bl_long IO_High_W 153 | add r4,r4,#1 154 | cmp r4,#0x40 155 | blt 0b 156 | 157 | @lcd control, lcd status, scrolling 158 | ldrb r0,[r3,#0x40] 159 | strb_ r0,lcdctrl 160 | mov r1,r0 161 | bl_long FF40W_entry 162 | ldrb r0,[r3,#0x41] 163 | ldr r1,=lcdstat 164 | strb r0,[r1] 165 | bl_long FF41_W 166 | ldrb r0,[r3,#0x42] 167 | bl_long FF42W_entry 168 | ldrb r0,[r3,#0x43] 169 | bl_long FF43W_entry 170 | 171 | @ignore FF44 (scanline number) 172 | 173 | @line compare 174 | ldrb r0,[r3,#0x45] 175 | bl_long FF45_W 176 | 177 | @ignore FF46 (sprite DMA transfer) 178 | 179 | @gb palettes, windows 180 | ldrb r0,[r3,#0x47] 181 | bl_long FF47_W_ 182 | ldrb r0,[r3,#0x48] 183 | bl_long FF48_W_ 184 | ldrb r0,[r3,#0x49] 185 | bl_long FF49_W_ 186 | ldrb r0,[r3,#0x4A] 187 | bl_long FF4A_W_ 188 | ldrb r0,[r3,#0x4B] 189 | bl_long FF4B_W_ 190 | 191 | @double speed 192 | ldrb r0,[r3,#0x4D] 193 | strb_ r0,doublespeed 194 | bl updatespeed 195 | 196 | @vram bank 197 | ldrb r0,[r3,#0x4F] 198 | bl_long FF4F_W 199 | 200 | @HDMA 201 | ldrb r0,[r3,#0x51] 202 | bl_long FF51_W 203 | ldrb r0,[r3,#0x52] 204 | bl_long FF52_W 205 | ldrb r0,[r3,#0x53] 206 | bl_long FF53_W 207 | ldrb r0,[r3,#0x54] 208 | bl_long FF54_W 209 | 210 | @palette index 211 | ldrb r0,[r3,#0x68] 212 | bl_long FF68_W 213 | ldrb r0,[r3,#0x6A] 214 | bl_long FF6A_W 215 | 216 | @ram bank 217 | ldrb r0,[r3,#0x70] 218 | bl_long _FF70W 219 | 220 | @HRAM and IE 221 | mov r4,#0x80 222 | 0: 223 | ldrb r0,[r3,r4] 224 | mov r2,r4 225 | bl_long IO_High_W 226 | add r4,r4,#1 227 | cmp r4,#0x100 228 | blt 0b 229 | 230 | 231 | ldmfd sp!,{r3-r11,lr} 232 | mov r0,#1 233 | bx lr 234 | 235 | AfterLoadState: 236 | stmfd sp!,{r3-r11,lr} 237 | ldr r10,=GLOBAL_PTR_BASE 238 | @AF, BC, DE, HL, SP, PC, Cycles 239 | adr_ r2,cpuregs 240 | ldmia r2,{gb_flg-gb_pc,gb_sp} 241 | 242 | mov r0,#0 243 | str_ r0,lastbank 244 | 245 | @make VRAM all dirty 246 | mov r1,#0xFFFFFFFF 247 | ldr r0,=DIRTY_TILE_BITS 248 | mov r2,#48 249 | bl memset32_ 250 | ldr r0,=dirty_map_words 251 | mov r2,#64 252 | bl memset32_ 253 | 254 | @clear all VRAM packets (Shantae) 255 | mov r1,#0 256 | ldr r0,=vram_packets_incoming 257 | mov r2,#128 258 | bl memset32_ 259 | ldr r0,=vram_packets_registered_bank0 260 | mov r2,#128 261 | bl memset32_ 262 | ldr r0,=vram_packets_registered_bank1 263 | mov r2,#128 264 | bl memset32_ 265 | ldr r0,=vram_packets_dirty 266 | mov r2,#132 267 | bl memset32_ 268 | 269 | @load banks 270 | ldr_ r0,bank0 271 | bl_long map0123_ 272 | ldr_ r0,bank1 273 | bl_long map4567_ 274 | @ram enable/ram bank 275 | bl_long RamSelect 276 | 277 | adr_ r2,cpuregs 278 | stmia r2,{gb_flg-gb_pc,gb_sp} 279 | 280 | bl_long copy_gbc_palette 281 | bl_long transfer_palette 282 | bl_long display_sprites 283 | @these destroy r10 284 | bl_long render_dirty_tiles 285 | bl_long render_dirty_bg 286 | 287 | ldmfd sp!,{r3-r11,lr} 288 | bx lr 289 | -------------------------------------------------------------------------------- /src/savestate.c: -------------------------------------------------------------------------------- 1 | #include "includes.h" 2 | 3 | //extern int SaveState(u8 *dest); 4 | //extern int LoadState(u8 *source, int maxLength); 5 | 6 | 7 | void AfterLoadState(void); 8 | 9 | typedef int(*saveFuncPtr)(u8*); 10 | typedef bool(*loadFuncPtr)(u8*, int); 11 | 12 | int SaveVers(u8* dest); 13 | int SaveRam(u8 *dest); 14 | int SaveRam2(u8 *dest); 15 | int SaveVram(u8 *dest); 16 | int SaveIo(u8 *dest); 17 | int SaveRegs(u8* dest); 18 | int SaveMapper(u8 *dest); 19 | int SavePalette(u8 *dest); 20 | int SaveEmu(u8 *dest); 21 | int SaveOam(u8 *dest); 22 | int SaveSgb(u8 *dest); 23 | 24 | static const int SAVE_VERSION = 1; 25 | EWRAM_BSS int saveVersion; 26 | 27 | bool LoadVers(u8 *src, int size); 28 | bool LoadRam(u8 *src, int size); 29 | bool LoadRam2(u8 *src, int size); 30 | bool LoadVram(u8 *src, int size); 31 | bool LoadIo(u8 *src, int size); 32 | bool LoadRegs(u8 *src, int size); 33 | bool LoadMapper(u8 *src, int size); 34 | bool LoadPalette(u8 *src, int size); 35 | bool LoadEmu(u8 *src, int size); 36 | bool LoadOam(u8 *src, int size); 37 | bool LoadSgb(u8 *src, int size); 38 | 39 | const char tags[][4] = 40 | { 41 | {'V','E','R','S'}, 42 | {'R','A','M',' '}, 43 | {'R','A','M','2'}, 44 | {'V','R','A','M'}, 45 | {'I','O',' ',' '}, 46 | {'R','E','G','S'}, 47 | {'M','A','P','R'}, 48 | {'P','A','L',' '}, 49 | {'E','M','U',' '}, 50 | {'O','A','M',' '}, 51 | {'S','G','B',' '}, 52 | }; 53 | 54 | const saveFuncPtr saveFunc[] = 55 | { 56 | SaveVers, 57 | SaveRam, 58 | SaveRam2, 59 | SaveVram, 60 | SaveIo, 61 | SaveRegs, 62 | SaveMapper, 63 | SavePalette, 64 | SaveEmu, 65 | SaveOam, 66 | SaveSgb 67 | }; 68 | 69 | const loadFuncPtr loadFunc[] = 70 | { 71 | LoadVers, 72 | LoadRam, 73 | LoadRam2, 74 | LoadVram, 75 | LoadIo, 76 | LoadRegs, 77 | LoadMapper, 78 | LoadPalette, 79 | LoadEmu, 80 | LoadOam, 81 | LoadSgb 82 | }; 83 | 84 | typedef enum 85 | { 86 | _Success, 87 | _OutOfBoundsTag, 88 | _UnknownTag, 89 | _Failed 90 | } LoadStateError; 91 | 92 | static u32 GetTagName(int tagId) 93 | { 94 | if (tagId < 0 || tagId >= ARRSIZE(tags)) 95 | { 96 | return 0; 97 | } 98 | else 99 | { 100 | const char *tagNameChar = tags[tagId]; 101 | u32 tagNameInt = *((const u32*)tagNameChar); 102 | return tagNameInt; 103 | } 104 | } 105 | 106 | static int GetTagId(u32 tagName) 107 | { 108 | for (int i = 0; i < ARRSIZE(tags); i++) 109 | { 110 | u32 otherTag = GetTagName(i); 111 | if (otherTag == tagName) 112 | { 113 | return i; 114 | } 115 | } 116 | return -1; 117 | } 118 | 119 | 120 | LoadStateError LoadState(u8 *source, int maxLength) 121 | { 122 | u8 *ptr = source; 123 | u8 *limit = source + maxLength; 124 | LoadStateError status = _Success; 125 | while (ptr < limit) 126 | { 127 | //Get Tag Name 128 | u32 tagName = *((u32*)(ptr + 0)); 129 | u32 tagLength = *((u32*)(ptr + 4)); 130 | 131 | ptr += 8; 132 | u8 *nextPtr = ptr + (((tagLength - 1) | 3) + 1); 133 | if (nextPtr > limit) 134 | { 135 | return _OutOfBoundsTag; 136 | } 137 | 138 | int tagId = GetTagId(tagName); 139 | if (tagId == -1) 140 | { 141 | status = _UnknownTag; 142 | return status; 143 | } 144 | else 145 | { 146 | bool value = loadFunc[tagId](ptr, tagLength); 147 | if (value == false) 148 | { 149 | status = _Failed; 150 | return status; 151 | } 152 | } 153 | ptr = nextPtr; 154 | } 155 | AfterLoadState(); 156 | return status; 157 | } 158 | 159 | int SaveState(u8 *dest) 160 | { 161 | u8 *startPosition = dest; 162 | for (int i=0; i < ARRSIZE(tags); i++) 163 | { 164 | u32 tagName = GetTagName(i); 165 | int size = saveFunc[i](dest + 8); 166 | if (size > 0) 167 | { 168 | *((u32*)dest) = tagName; 169 | dest += 4; 170 | *((u32*)dest) = size; 171 | dest += 4; 172 | dest += size; 173 | } 174 | } 175 | return dest - startPosition; 176 | } 177 | 178 | 179 | int SaveVers(u8 *dest) 180 | { 181 | *((u32*)(dest)) = SAVE_VERSION; 182 | return 4; 183 | } 184 | //in state.s 185 | //int SaveRegs(u8* dest) 186 | //{ 187 | // return 0; 188 | //} 189 | int SaveRam(u8 *dest) 190 | { 191 | memcpy32(dest, XGB_RAM, 0x2000); 192 | return 0x2000; 193 | } 194 | int SaveRam2(u8 *dest) 195 | { 196 | if (gbc_mode) 197 | { 198 | memcpy32(dest, GBC_EXRAM, 0x6000); 199 | return 0x6000; 200 | } 201 | return 0; 202 | } 203 | int SaveVram(u8 *dest) 204 | { 205 | if (!gbc_mode) 206 | { 207 | memcpy32(dest, XGB_VRAM, 0x2000); 208 | return 0x2000; 209 | } 210 | else 211 | { 212 | memcpy32(dest, XGB_VRAM, 0x4000); 213 | return 0x4000; 214 | } 215 | return 0; 216 | } 217 | //In state.s 218 | //int SaveIo(u8 *dest) 219 | //{ 220 | // return 0; 221 | //} 222 | int SaveMapper(u8 *dest) 223 | { 224 | memcpy32(dest, g_banks, 44); 225 | return 44; 226 | } 227 | int SavePalette(u8 *dest) 228 | { 229 | if (gbc_mode) 230 | { 231 | memcpy32(dest, gbc_palette, 128); 232 | return 128; 233 | } 234 | return 0; 235 | } 236 | int SaveEmu(u8 *dest) 237 | { 238 | return 0; 239 | } 240 | int SaveOam(u8 *dest) 241 | { 242 | memcpy32(dest, _gb_oam_buffer_writing, 160); 243 | return 160; 244 | } 245 | int SaveSgb(u8 *dest) 246 | { 247 | return 0; 248 | } 249 | 250 | bool LoadVers(u8 *src, int size) 251 | { 252 | if (size == 4) 253 | { 254 | saveVersion = *((u32*)(src)); 255 | return true; 256 | } 257 | return false; 258 | } 259 | //bool LoadRegs(u8 *src, int size) 260 | //{ 261 | // return false; 262 | //} 263 | bool LoadRam(u8 *src, int size) 264 | { 265 | if (size == 0x2000) 266 | { 267 | memcpy32(XGB_RAM, src, size); 268 | return true; 269 | } 270 | return false; 271 | } 272 | bool LoadRam2(u8 *src, int size) 273 | { 274 | if (size == 0x6000) 275 | { 276 | memcpy32(GBC_EXRAM, src, size); 277 | return true; 278 | } 279 | return false; 280 | } 281 | bool LoadVram(u8 *src, int size) 282 | { 283 | if (size == 0x2000 || size == 0x4000) 284 | { 285 | memcpy32(XGB_VRAM, src, size); 286 | return true; 287 | } 288 | return false; 289 | } 290 | //In state.s 291 | //bool LoadIo(u8 *src, int size) 292 | //{ 293 | // return false; 294 | //} 295 | bool LoadMapper(u8 *src, int size) 296 | { 297 | if (size == 44) 298 | { 299 | memcpy32(g_banks, src, size); 300 | return true; 301 | } 302 | return false; 303 | } 304 | bool LoadPalette(u8 *src, int size) 305 | { 306 | if (size == 128) 307 | { 308 | memcpy32(gbc_palette, src, size); 309 | return true; 310 | } 311 | return false; 312 | } 313 | bool LoadEmu(u8 *src, int size) 314 | { 315 | return false; 316 | } 317 | bool LoadOam(u8 *src, int size) 318 | { 319 | if (size == 160) 320 | { 321 | memcpy32(_gb_oam_buffer_writing, src, size); 322 | memcpy32(_gb_oam_buffer_screen, src, size); 323 | memcpy32(_gb_oam_buffer_alt, src, size); 324 | return true; 325 | } 326 | return false; 327 | } 328 | bool LoadSgb(u8 *src, int size) 329 | { 330 | return false; 331 | } 332 | -------------------------------------------------------------------------------- /src/asmcalls.h: -------------------------------------------------------------------------------- 1 | #ifndef __ASMCALLS_H__ 2 | #define __ASMCALLS_H__ 3 | 4 | static __inline void breakpoint() 5 | { 6 | __asm volatile ("mov r11,r11"); 7 | } 8 | 9 | 10 | //#include "fs.h" 11 | //#include "cache.h" 12 | 13 | #if ROMVERSION 14 | extern u8 goomba_mb_gba[]; 15 | #if !GCC 16 | extern u32 goomba_mb_gba_size[]; 17 | #define GOOMBA_MB_GBA_SIZE ((u32)(&goomba_mb_gba_size)) 18 | #else 19 | extern u32 goomba_mb_gba_size; 20 | #define GOOMBA_MB_GBA_SIZE goomba_mb_gba_size 21 | #endif 22 | #endif 23 | 24 | void jump_r0(u32); 25 | 26 | extern u8 auto_border; 27 | 28 | extern u8 ui_border_visible; 29 | extern u8 darkness; 30 | //extern u8 border_visible; 31 | extern int ui_x; 32 | extern int ui_y_real; 33 | 34 | extern u8 sgb_palette_number; 35 | 36 | extern u32 ewram_canary_1; 37 | extern u32 ewram_canary_2; 38 | 39 | #if !GCC 40 | extern u8 Image$$RO$$Base[]; 41 | extern u8 Image$$RW$$Base[]; 42 | extern u8 Image$$RO$$Limit[]; 43 | extern u8 Image$$RW$$Limit[]; 44 | #endif 45 | 46 | extern u32 max_multiboot_size; 47 | 48 | //gbz80.s 49 | #if SPEEDHACKS_OLD 50 | extern u32 SPEEDHACK_FIND_JR_Z_BUF[16]; 51 | extern u32 SPEEDHACK_FIND_JR_NZ_BUF[16]; 52 | extern u32 SPEEDHACK_FIND_JR_C_BUF[16]; 53 | extern u32 SPEEDHACK_FIND_JR_NC_BUF[16]; 54 | extern u8 g_hackflags; 55 | extern u8 g_hackflags2; 56 | 57 | #endif 58 | 59 | void update_doublespeed_ui(void); 60 | 61 | void emu_reset(void); 62 | void cpuhack_reset(void); 63 | void run(int dont_stop); 64 | extern u32 op_table[256]; 65 | extern void default_scanlinehook(void); 66 | extern u32 cpustate[26]; 67 | extern u32 _lastbank; 68 | 69 | #define STATE_A (cpustate[1] >> 24) 70 | #define STATE_BC (cpustate[2] >> 16) 71 | #define STATE_DE (cpustate[3] >> 16) 72 | #define STATE_HL (cpustate[4] >> 16) 73 | #define STATE_PC (cpustate[6] - (u32)_lastbank); 74 | 75 | extern u8 *rommap[16]; 76 | extern u8 *g_memmap_tbl[16]; 77 | 78 | extern void* g_readmem_tbl[8]; 79 | extern void* g_writemem_tbl[8]; 80 | 81 | extern u32 frametotal; 82 | extern u32 sleeptime; 83 | extern u8 novblankwait; 84 | extern u8 request_gb_type; 85 | extern u8 request_gba_mode; 86 | 87 | extern u8 g_hackflags; 88 | extern u32 num_speedhacks; 89 | extern u16 speedhacks[256]; 90 | 91 | extern u8 gbc_mode; 92 | extern u8 sgb_mode; 93 | extern u8 doubletimer; 94 | 95 | extern u8 dontstop; 96 | 97 | //extern u8* g_gbz80_pc; 98 | //extern u8* g_lastbank; 99 | 100 | extern u8 XGB_RAM[0x2000]; 101 | extern u8 XGB_HRAM[128]; 102 | #if !RESIZABLE 103 | extern u8 XGB_SRAM[0x8000]; 104 | #endif 105 | extern u8 XGB_VRAM[0x4000]; 106 | extern u8 GBC_EXRAM[0x6000]; 107 | 108 | #if RESIZABLE 109 | extern u8 *XGB_sram, *XGB_vram, *GBC_exram, *END_of_exram; 110 | extern u32 XGB_sramsize,XGB_vramsize,GBC_exramsize; 111 | extern u8 *XGB_vram_1800, *XGB_vram_1C00; 112 | #endif 113 | 114 | //apack.s 115 | void depack(u8 *source, u8 *destination); 116 | 117 | //boot.s 118 | extern u8 font_lz77[]; //from boot.s 119 | extern u8 fontpal_bin[]; //from boot.s 120 | 121 | //cart.s 122 | 123 | extern u8* INSTANT_PAGES[256]; 124 | 125 | extern u32 g_rammask; 126 | extern u32 g_banks[2]; 127 | 128 | void loadcart(int rom_number,int emu_flags); //from cart.s 129 | void map0123_(int page); 130 | void map4567_(int page); 131 | void map01234567_(int page); 132 | void mapAB_(int page); 133 | 134 | int savestate(void* dest); 135 | void loadstate(int, void* dest); 136 | 137 | extern u32 g_emuflags; 138 | extern u8* romstart; 139 | extern u32 romnum; 140 | extern u32 END_OF_EXRAM; 141 | 142 | /* 143 | extern char lfnName[256]; 144 | extern unsigned char globalBuffer[BYTE_PER_READ]; 145 | extern unsigned char fatWriteBuffer[BYTE_PER_READ]; 146 | extern unsigned char fatBuffer[BYTE_PER_READ]; 147 | extern FAT_FILE openFiles[MAX_FILES_OPEN]; 148 | */ 149 | 150 | extern char SramName[256]; 151 | extern u8 mapperstate[32]; 152 | 153 | //void loadstate_gfx(void); 154 | 155 | extern u8 AGB_BG[8192]; 156 | 157 | extern u8 g_cartflags; //(from GB header) 158 | extern int bcolor; //Border Color 159 | 160 | //io.s 161 | extern u32 joycfg; //from io.s 162 | //void resetSIO(u32); //io.s 163 | void vbaprint(const char *text); //io.s 164 | void LZ77UnCompVram(const void *source,u16 *destination); //io.s 165 | void waitframe(void); //io.s 166 | int CheckGBAVersion(void); //io.s 167 | void suspend(void); //io.s 168 | void waitframe(void); //io.s 169 | int gettime(void); //io.s 170 | 171 | /* 172 | //memory.s 173 | extern u32 sram_R[]; 174 | extern u32 sram_W[]; 175 | extern u32 rom_R60[]; 176 | extern u32 empty_W[]; 177 | */ 178 | 179 | //lcd.s 180 | extern u32 *vblankfptr; //from lcd.s 181 | //extern u32 *vcountfptr; //from lcd.s 182 | extern u32 vbldummy; //from lcd.s 183 | extern u32 vblankinterrupt; //from lcd.s 184 | //extern u32 vcountinterrupt; //from lcd.s 185 | extern u32 AGBinput; //from lcd.s 186 | extern u32 EMUinput; 187 | 188 | void GFX_init(void); //lcd.s 189 | void GFX_init_irq(void); //lcd.s 190 | void debug_(int,int); //lcd.s 191 | void paletteinit(void); //lcd.s 192 | void PaletteTxAll(void); //lcd.s 193 | void transfer_palette(void); //lcd.s 194 | void move_ui_asm(void); 195 | //void makeborder(void); //lcd.s 196 | extern u32 FPSValue; //from lcd.s 197 | extern u8 fpsenabled; //from lcd.s 198 | extern u32 palettebank; //from lcd.s palette bank 199 | //extern u32 bcolor; //from lcd.s ,border color, black, grey, blue 200 | extern u8 gammavalue; //from lcd.s 201 | 202 | extern u8 g_lcdhack; 203 | extern u8 _dmamode; 204 | extern u16 _dma_src; 205 | extern u16 _dma_dest; 206 | extern u8 _vrambank; 207 | 208 | extern u8 gbc_palette[]; 209 | 210 | extern u8* _dirty_tile_bits; 211 | extern u8* _gb_oam_buffer_screen; 212 | extern u8* _gb_oam_buffer_writing; 213 | extern u8* _gb_oam_buffer_alt; 214 | 215 | //extern u8* _dirty_tiles; 216 | //extern u8* _dirty_rows; 217 | 218 | //void _set_bg_cache_full(int mode); 219 | 220 | extern u8 dirty_map_words[]; 221 | 222 | void memcpy32(void *dest, const void *src, int byteCount); 223 | void memset32(void *dest, u32 value, int byteCount); 224 | void memset8(u8 *dest, u8 value, int byteCount); 225 | void memcpy_unaligned_src(void *dest, const void *src, int byteCount); 226 | 227 | void copy_map_and_compare(u8 *destAddress, u8 *sourceAddress, int byteCount, u8* dirtyMapWordsPtr); 228 | 229 | 230 | void update_lcdhack(void); 231 | 232 | //ppu.s 233 | /* 234 | extern u32 *vblankfptr; //from ppu.s 235 | extern u32 vbldummy; //from ppu.s 236 | extern u32 vblankinterrupt; //from ppu.s 237 | extern u32 AGBinput; //from ppu.s 238 | extern u32 EMUinput; 239 | 240 | void debug_(int,int); //ppu.s 241 | void paletteinit(void); //ppu.s 242 | void PaletteTxAll(void); //ppu.s 243 | 244 | void PPU_reset(void); 245 | void PPU_init(void); 246 | 247 | extern u32 FPSValue; //from ppu.s 248 | extern char fpsenabled; //from ppu.s 249 | extern char gammavalue; //from ppu.s 250 | extern char twitch; //from ppu.s 251 | extern char flicker; //from ppu.s 252 | extern u32 wtop; //from ppu.s 253 | 254 | extern u32 ppustate[8]; 255 | extern u16 agb_pal[48]; 256 | extern u32 agb_nt_map[4]; 257 | 258 | */ 259 | 260 | //sound.s 261 | /* 262 | void make_freq_table(void); 263 | extern u16* freqtbl; 264 | extern u16 FREQTBL2[2048]; 265 | */ 266 | 267 | /* 268 | */ 269 | 270 | //visoly.s 271 | void doReset(void); 272 | 273 | //sgb.s 274 | extern u8 g_update_border_palette; 275 | 276 | #if SPEEDHACKS_NEW 277 | extern u8 _quickhackcount; 278 | extern u8 _quickhackused; 279 | extern const u8* _speedhack_pc; 280 | 281 | void speedhack_reset(void); 282 | void install_speedhack(const u8 *speedhack_pc, int isJump); 283 | 284 | #endif 285 | 286 | #endif 287 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | MAKEFILE := makefile 2 | 3 | #--------------------------------------------------------------------------------- 4 | # Clear the implicit built in rules 5 | #--------------------------------------------------------------------------------- 6 | .SUFFIXES: 7 | #--------------------------------------------------------------------------------- 8 | ifeq ($(strip $(DEVKITARM)),) 9 | $(error "Please set DEVKITARM in your environment. export DEVKITARM=devkitARM) 10 | endif 11 | 12 | 13 | include $(DEVKITARM)/gba_rules 14 | 15 | #-------- 16 | # Overrides for default rules 17 | 18 | #%.o: %.s 19 | # @echo $(notdir $<) 20 | # $(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ 21 | # 22 | #%.o: %.S 23 | # @echo $(notdir $<) 24 | # $(CC) -MMD -MP -MF $(DEPSDIR)/$*.d -x assembler-with-cpp $(ASFLAGS) -c $< -o $@ 25 | 26 | #OBJCOPY := $(OBJCOPY) -R.pad 27 | 28 | # We override the specs file because the default crt0 always clears EWRAM, and we don't want this. 29 | # when DevKitArm changes the specs files, change the copy in the project too! 30 | 31 | %_mb.elf: 32 | @echo linking multiboot CUSTOM 33 | @$(LD) $(LDFLAGS) -specs=../src/gba_mb_my.specs $(OFILES) $(LIBPATHS) $(LIBS) -o $@ 34 | %.elf: 35 | @echo linking cartridge CUSTOM 36 | @$(LD) $(LDFLAGS) -specs=../src/gba_my.specs $(OFILES) $(LIBPATHS) $(LIBS) -o $@ 37 | 38 | #------- 39 | 40 | 41 | 42 | #--------------------------------------------------------------------------------- 43 | # TARGET is the name of the output, if this ends with _mb generates a multiboot image 44 | # BUILD is the directory where object files & intermediate files will be placed 45 | # SOURCES is a list of directories containing source code 46 | # INCLUDES is a list of directories containing extra header files 47 | #--------------------------------------------------------------------------------- 48 | TARGET := goomba 49 | BUILD := build 50 | SOURCES := src 51 | INCLUDES := 52 | 53 | #--------------------------------------------------------------------------------- 54 | # options for code generation 55 | #--------------------------------------------------------------------------------- 56 | ARCH := -mthumb -mthumb-interwork 57 | 58 | CFLAGS := -g -Wall -Os\ 59 | -mcpu=arm7tdmi -mtune=arm7tdmi\ 60 | -fomit-frame-pointer\ 61 | -ffast-math \ 62 | -std=c99 \ 63 | $(ARCH) 64 | 65 | CFLAGS += $(INCLUDE) 66 | 67 | CXXFLAGS := $(CFLAGS) \ 68 | -fno-rtti -fno-exceptions 69 | 70 | ASFLAGS := $(ARCH) 71 | LDFLAGS = -g $(ARCH) -Wl,-Map,$(notdir $@).map 72 | 73 | #--------------------------------------------------------------------------------- 74 | # path to tools - this can be deleted if you set the path in windows 75 | #--------------------------------------------------------------------------------- 76 | export PATH := $(DEVKITARM)/bin:$(PATH) 77 | 78 | #--------------------------------------------------------------------------------- 79 | # any extra libraries we wish to link with the project 80 | #--------------------------------------------------------------------------------- 81 | LIBS := -lgba 82 | 83 | #--------------------------------------------------------------------------------- 84 | # list of directories containing libraries, this must be the top level containing 85 | # include and lib 86 | #--------------------------------------------------------------------------------- 87 | LIBDIRS := $(LIBGBA) 88 | 89 | #--------------------------------------------------------------------------------- 90 | # no real need to edit anything past this point unless you need to add additional 91 | # rules for different file extensions 92 | #--------------------------------------------------------------------------------- 93 | ifneq ($(BUILD),$(notdir $(CURDIR))) 94 | #--------------------------------------------------------------------------------- 95 | 96 | export OUTPUT := $(CURDIR)/$(TARGET) 97 | 98 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) 99 | export PATH := $(DEVKITARM)/bin:$(PATH) 100 | export DEPSDIR := $(CURDIR)/$(BUILD) 101 | 102 | #--------------------------------------------------------------------------------- 103 | # automatically build a list of object files for our project 104 | #--------------------------------------------------------------------------------- 105 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) 106 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) 107 | SFILES := all.s 108 | DATA1 := font.lz77 109 | DATA2 := fontpal.bin 110 | DATA3 := #../goomba_mb.gba 111 | 112 | #--------------------------------------------------------------------------------- 113 | # use CXX for linking C++ projects, CC for standard C 114 | #--------------------------------------------------------------------------------- 115 | ifeq ($(strip $(CPPFILES)),) 116 | #--------------------------------------------------------------------------------- 117 | export LD := $(CC) 118 | #--------------------------------------------------------------------------------- 119 | else 120 | #--------------------------------------------------------------------------------- 121 | export LD := $(CXX) 122 | #--------------------------------------------------------------------------------- 123 | endif 124 | #--------------------------------------------------------------------------------- 125 | 126 | export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o) $(DATA1:.lz77=.o) $(DATA2:.bin=.o) $(DATA3:.gba=.o) 127 | 128 | #--------------------------------------------------------------------------------- 129 | # build a list of include paths 130 | #--------------------------------------------------------------------------------- 131 | export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ 132 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ 133 | -I$(CURDIR)/$(BUILD) 134 | 135 | #--------------------------------------------------------------------------------- 136 | # build a list of library paths 137 | #--------------------------------------------------------------------------------- 138 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) 139 | 140 | .PHONY: $(BUILD) clean 141 | 142 | #--------------------------------------------------------------------------------- 143 | $(BUILD): 144 | @[ -d $@ ] || mkdir -p $@ 145 | @make --no-print-directory -C $(BUILD) -f $(CURDIR)/$(MAKEFILE) 146 | 147 | all : $(BUILD) 148 | #--------------------------------------------------------------------------------- 149 | semiclean: 150 | @echo deleting intermediate files... 151 | @rm -fr $(BUILD) $(TARGET).elf 152 | 153 | clean: semiclean 154 | @echo deleting main binary 155 | @rm -f $(TARGET).gba 156 | 157 | #--------------------------------------------------------------------------------- 158 | else 159 | 160 | DEPENDS := $(OFILES:.o=.d) 161 | 162 | %.o : %.lz77 163 | @echo $(notdir $<) 164 | @$(bin2o) 165 | 166 | %.o : %.bin 167 | @echo $(notdir $<) 168 | @$(bin2o) 169 | 170 | %.o : %.gba 171 | @echo $(notdir $<) 172 | @$(bin2o) 173 | 174 | 175 | #--------------------------------------------------------------------------------- 176 | # main targets 177 | #--------------------------------------------------------------------------------- 178 | $(OUTPUT).gba : $(OUTPUT).elf 179 | 180 | $(OUTPUT).elf : $(OFILES) gba_crt0_my.o 181 | 182 | -include $(DEPENDS) 183 | 184 | #replacement rule for gbafix 185 | #--------------------------------------------------------------------------------- 186 | %.gba: %.elf 187 | @$(OBJCOPY) -O binary $< $@ 188 | @echo CUSTOM built ... $(notdir $@) 189 | @echo gbafix $@ -t GOOMBA COLOR -c GMBC 190 | @gbafix $@ "-tGOOMBA COLOR" "-cGMBC" 191 | 192 | 193 | 194 | #--------------------------------------------------------------------------------- 195 | endif 196 | #--------------------------------------------------------------------------------- 197 | -------------------------------------------------------------------------------- /src/mbclient.c: -------------------------------------------------------------------------------- 1 | #include "includes.h" 2 | 3 | #if MULTIBOOT 4 | 5 | 6 | //based on Jeff Frohwein's slave boot demo: 7 | //http://www.devrs.com/gba/files/mbclient.txt 8 | 9 | #include 10 | #include "gba.h" 11 | 12 | u8 *findrom(int); 13 | 14 | 15 | #if GCC 16 | 17 | extern u8 __load_stop_iwram9[]; //using this instead of __end__, because it's also cart compatible 18 | extern u8 __iwram_lma[]; 19 | 20 | #define EMUSIZE1 ( ( (u32)(&__iwram_lma) ) & 0x3FFFF ) 21 | #define EMUSIZE2 ( ( ( (u32)(&__load_stop_iwram9) ) - EMUSIZE1 ) & 0x7FFF ) 22 | 23 | #else 24 | 25 | extern u8 Image$$RO$$Limit[]; 26 | extern u8 Image$$ZI$$Base[]; 27 | 28 | #define EMUSIZE1 (((u32)(&Image$$RO$$Limit)&0x3ffff)) 29 | #define EMUSIZE2 (((u32)(&Image$$ZI$$Base)&0x7fff)) 30 | 31 | #endif 32 | extern u32 romnum; //from cart.s 33 | extern u8 *textstart; //from main.c 34 | 35 | 36 | //extern char pogoshell; 37 | 38 | typedef struct { 39 | u32 reserve1[5]; // 40 | u8 hs_data; // 20 ($14) Needed by BIOS 41 | u8 reserve2; // 21 ($15) 42 | u16 reserve3; // 22 ($16) 43 | u8 pc; // 24 ($18) Needed by BIOS 44 | u8 cd[3]; // 25 ($19) 45 | u8 palette; // 28 ($1c) Needed by BIOS - Palette flash while load 46 | u8 reserve4; // 29 ($1d) rb 47 | u8 cb; // 30 ($1e) Needed by BIOS 48 | u8 reserve5; // 31 ($1f) 49 | u8 *startp; // 32 ($20) Needed by BIOS 50 | u8 *endp; // 36 ($24) Needed by BIOS 51 | u8 *reserve6; // 40 ($28) 52 | u8 *reserve7[3]; // 44 ($2c) 53 | u32 reserve8[4]; // 56 ($38) 54 | u8 reserve9; // 72 ($48) 55 | u8 reserve10; // 73 ($49) 56 | u8 reserve11; // 74 ($4a) 57 | u8 reserve12; // 75 ($4b) 58 | } MBStruct; 59 | 60 | const 61 | #include "client.h" 62 | 63 | void delay() { 64 | int i=32768; 65 | while(--i); //(we're running from EWRAM) 66 | } 67 | 68 | #if GCC 69 | void DelayCycles (u32 cycles) __attribute__((noinline)); 70 | void DelayCycles (u32 cycles) 71 | { 72 | __asm__ volatile ( 73 | "mov r11,r11\n\t" 74 | "adr r1,delaycycles_enter_arm\n\t" 75 | "bx r1\n\t" 76 | ".code 32\n" 77 | "delaycycles_enter_arm:\n\t" 78 | "mov r0, %0\n\t" 79 | "mov r2, pc\n\t" 80 | "mov r1, #12\n\t" 81 | "cmp r2, #0x02000000\n\t" 82 | "beq MultiBootWaitCyclesLoop\n\t" 83 | 84 | // ROM 4/2 wait 85 | "mov r1, #14\n\t" 86 | "cmp r2, #0x08000000\n\t" 87 | "beq MultiBootWaitCyclesLoop\n\t" 88 | 89 | // IWRAM 90 | "mov r1, #4\n" 91 | 92 | "MultiBootWaitCyclesLoop:\n\t" 93 | "subs r0, r0, r1\n\t" 94 | "bgt MultiBootWaitCyclesLoop\n\t" 95 | "adr r1,delaycycles_enter_thumb+1\n\t" 96 | "bx r1\n\t" 97 | ".code 16\n" 98 | "delaycycles_enter_thumb:" 99 | : :"r"(cycles) : "r0","r1","r2" 100 | ); 101 | return; 102 | } 103 | #else 104 | void DelayCycles (u32 cycles) 105 | { 106 | __asm{mov r2, pc} 107 | 108 | // EWRAM 109 | __asm{mov r1, #12} 110 | __asm{cmp r2, #0x02000000} 111 | __asm{beq MultiBootWaitCyclesLoop} 112 | 113 | // ROM 4/2 wait 114 | __asm{mov r1, #14} 115 | __asm{cmp r2, #0x08000000} 116 | __asm{beq MultiBootWaitCyclesLoop} 117 | 118 | // IWRAM 119 | __asm{mov r1, #4} 120 | 121 | __asm{MultiBootWaitCyclesLoop:} 122 | __asm{sub r0, r0, r1} 123 | __asm{bgt MultiBootWaitCyclesLoop} 124 | } 125 | #endif 126 | 127 | u16 xfer(u16 send) { 128 | u32 i; 129 | 130 | i=1000; 131 | 132 | REG_SIOMLT_SEND = send; 133 | REG_SIOCNT = 0x2083; 134 | while((REG_SIOCNT & 0x80) && --i) {DelayCycles(10);} 135 | return (REG_SIOMULTI1); 136 | } 137 | 138 | #if GCC 139 | int swi25(void *p) { 140 | int i; 141 | __asm__ volatile ( 142 | "mov r11,r11\n\t" 143 | "mov r0,%1\n\t" 144 | "mov r1,#1\n\t" 145 | "swi 0x25\n\t" 146 | "mov %0,r0" 147 | : "=r" (i) : "r"(p) : "r0","r1","r2" 148 | ); 149 | return i; 150 | } 151 | #else 152 | int swi25(void *p) { 153 | __asm{mov r1,#1} 154 | __asm{swi 0x25, {r0-r1}, {}, {r0-r2} } 155 | } 156 | #endif 157 | //returns error code: 1=no link, 2=bad send, 3=too big 158 | #define TIMEOUT 40 159 | int SendMBImageToClient(void) { 160 | MBStruct mp; 161 | u8 palette; 162 | u32 i,j; 163 | u16 key; 164 | u16 *p; 165 | u16 ie; 166 | u32 emusize1,emusize2,romsize; 167 | u32 totalsize; 168 | u16 *src_ewram; 169 | u16 *src_iwram; 170 | u32 bytepos; 171 | 172 | #if ROMVERSION 173 | src_ewram=(u16*)goomba_mb_gba; 174 | src_iwram=NULL; 175 | emusize1=GOOMBA_MB_GBA_SIZE; 176 | emusize2=0; 177 | #else 178 | src_iwram=(u16*)0x03000000; 179 | src_ewram=(u16*)0x02000000; 180 | emusize1=EMUSIZE1; 181 | emusize2=EMUSIZE2; 182 | #endif 183 | 184 | // if(pogoshell) romsize=48+16+(*(u8*)(findrom(romnum)+48+4))*16*1024+(*(u8*)(findrom(romnum)+48+5))*8*1024; //need to read this from ROM 185 | // else romsize=48+*(u32*)(findrom(romnum)+32); 186 | romsize = (0x8000 << (*(findrom(romnum)+0x148))); 187 | if(emusize1+romsize>192*1024) return 3; 188 | 189 | totalsize = emusize1+emusize2+romsize; 190 | 191 | #if 0 192 | //this check frequently causes hangs, and is not necessary 193 | REG_RCNT=0x8003; //general purpose comms - sc/sd inputs 194 | i=TIMEOUT; 195 | while(--i && (REG_RCNT&3)==3) delay(); 196 | if(!i) return 1; 197 | 198 | i=TIMEOUT; 199 | while(--i && (REG_RCNT&3)!=3) delay(); 200 | if(!i) return 1; 201 | #endif 202 | 203 | REG_RCNT=0; //non-general purpose comms 204 | 205 | i=250; 206 | do { 207 | DelayCycles(10); 208 | j=xfer(0x6202); 209 | } while(--i && j!=0x7202); 210 | if(!i) return 2; 211 | 212 | xfer (0x6100); 213 | p=(u16*)src_ewram; 214 | for(bytepos=0;bytepos<96; bytepos++) { //send header 215 | xfer(*p); 216 | p++; 217 | } 218 | 219 | xfer(0x6202); 220 | mp.cb = 2; 221 | mp.pc = 0xd1; 222 | mp.startp=(u8*)Client; 223 | i=sizeof(Client); 224 | i=(i+15)&~15; //16 byte units 225 | mp.endp=(u8*)Client+i; 226 | 227 | palette = 0xef; 228 | //8x=purple->blue 229 | //9x=blue->emerald 230 | //ax=emerald->green 231 | //bx=green->yellow 232 | //cx=yellow->red 233 | //dx=red->purple 234 | //ex=purple->white 235 | mp.palette = palette; 236 | 237 | xfer(0x6300+palette); 238 | i=xfer(0x6300+palette); 239 | 240 | mp.cd[0] = i; 241 | mp.cd[1] = 0xff; 242 | mp.cd[2] = 0xff; 243 | 244 | key = (0x11 + (i & 0xff) + 0xff + 0xff) & 0xff; 245 | mp.hs_data = key; 246 | 247 | xfer(0x6400 | (key & 0xff)); 248 | 249 | ie=REG_IE; 250 | REG_IE=0; //don't interrupt 251 | REG_DM0CNT_H=0; //DMA stop 252 | REG_DM1CNT_H=0; 253 | REG_DM2CNT_H=0; 254 | REG_DM3CNT_H=0; 255 | 256 | if(swi25(&mp)){ //Execute BIOS routine to transfer client binary to slave unit 257 | i=2; 258 | goto transferEnd; 259 | } 260 | //now send everything else 261 | 262 | REG_RCNT=0; //non-general purpose comms 263 | i=200; 264 | do { 265 | delay(); 266 | j=xfer(0x99); 267 | } while(--i && j!=0x99); //wait til client is ready 268 | if(!i){ //mbclient not responding 269 | i=2; 270 | goto transferEnd; 271 | } 272 | xfer(totalsize&0xFFFF); //transmission size.. 273 | xfer(totalsize>>16); 274 | 275 | p=(u16*)(src_ewram); //(from ewram.) 276 | for(bytepos=0;bytepos=30) return; 63 | 64 | for (row=0;row<21;row++) 65 | { 66 | u16 from_vram=(SCREENBASE)[row*32+col]; 67 | u8 from_textmem=TEXTMEM[row][col]; 68 | u16 to_vram=(lookup_character(from_textmem & 0x7F) + FONT_PALETTE_NUMBER * 0x1000 + (from_textmem >> 7) * 0x1000); 69 | u8 to_textmem=( lookup_character_inverse(from_vram) + ((from_vram - FONT_PALETTE_NUMBER * 0x1000) & 0x1000) / 32); 70 | TEXTMEM[row][col]=to_textmem; 71 | (SCREENBASE)[row*32+col]=to_vram; 72 | } 73 | } 74 | 75 | void move_ui_expose() 76 | { 77 | //get exposed area 78 | { 79 | u32 current_col=(old_ui_x/8)&0x3F; 80 | u32 new_col=(ui_x/8)&0x3F; 81 | u32 col; 82 | 83 | if (current_col!=new_col) 84 | { 85 | int delta=(new_col-current_col)&0x3F; 86 | if (delta>32) 87 | { 88 | current_col=(current_col-1)&0x3F; 89 | new_col=(new_col-1)&0x3F; 90 | for (col=current_col;col!=new_col;col=(col-1)&0x3F) 91 | { 92 | swap_column(col&0x1F); 93 | } 94 | } 95 | else 96 | { 97 | for (col=current_col;col!=new_col;col=(col+1)&0x3F) 98 | { 99 | swap_column(col&0x1F); 100 | } 101 | } 102 | } 103 | } 104 | old_ui_x = ui_x; 105 | } 106 | 107 | void move_ui_scroll() 108 | { 109 | ui_y_real = ui_y + UI_Y_BASE; 110 | move_ui_asm(); 111 | } 112 | 113 | void move_ui_wait() 114 | { 115 | move_ui_scroll(); 116 | waitframe(); 117 | move_ui_expose(); 118 | } 119 | 120 | void move_ui() 121 | { 122 | move_ui_scroll(); 123 | move_ui_expose(); 124 | } 125 | 126 | void loadfont() 127 | { 128 | //memcpy32(FONT_MEM,(const u32*)&font, font_size); 129 | LZ77UnCompVram((const u32*)&font_lz77,FONT_MEM); 130 | } 131 | void loadfontpal() 132 | { 133 | memcpy32(FONT_PAL,&fontpal_bin,64); 134 | } 135 | void get_ready_to_display_text() 136 | { 137 | //this function is used exclusively to display error messages 138 | setdarkness(0); 139 | REG_DISPCNT&=~(7 | FORCE_BLANK); //force mode 0, and turn off force blank 140 | REG_DISPCNT|=BG2_EN; //text on BG2 141 | REG_BG2CNT= 0 | (FONT_CHAR_PAGE << 2) | (UI_TILEMAP_NUMBER << 8) | (0<<14); 142 | REG_BG2VOFS = UI_Y_BASE; 143 | REG_BG2HOFS = 0; 144 | loadfont(); 145 | loadfontpal(); 146 | } 147 | 148 | void clearoldkey() 149 | { 150 | oldkey=~REG_P1; 151 | } 152 | 153 | u32 getmenuinput(int menuitems) 154 | { 155 | u32 keyhit; 156 | u32 tmp; 157 | int sel=selected; 158 | 159 | waitframe(); //(polling REG_P1 too fast seems to cause problems) 160 | tmp=~REG_P1; 161 | keyhit=(oldkey^tmp)&tmp; 162 | oldkey=tmp; 163 | if (menuitems==0) return keyhit; 164 | if(keyhit&UP) 165 | sel=(sel+menuitems-1)%menuitems; 166 | if(keyhit&DOWN) 167 | sel=(sel+1)%menuitems; 168 | if(keyhit&RIGHT) { 169 | sel+=10; 170 | if(sel>menuitems-1) sel=menuitems-1; 171 | } 172 | if(keyhit&LEFT) { 173 | sel-=10; 174 | if(sel<0) sel=0; 175 | } 176 | if((oldkey&(L_BTN+R_BTN))!=L_BTN+R_BTN) 177 | keyhit&=~(L_BTN+R_BTN); 178 | selected=sel; 179 | return keyhit; 180 | } 181 | 182 | void cls(int chrmap) 183 | { 184 | //chrmap is a bitfield 185 | //1 = left, 2 = right, 4 = whichever is off the screen, 8 = whichever is on the screen 186 | int i=0,len=0x200; 187 | u32 *scr=(u32*)SCREENBASE; 188 | 189 | const u32 FILL_PATTERN = (FONT_MEM_FIRSTCHAR + FONT_PALETTE_NUMBER*0x1000)*0x10001; 190 | 191 | if ( (chrmap & 8) || ((chrmap & 1) && !(ui_x & 256)) || ((chrmap & 2) && (ui_x & 256)) ) 192 | { 193 | len=0x540/4; 194 | for(;i= 32 && (ui_x & 256)) || (row <32 && !(ui_x&256))) 314 | { 315 | u16 *here=SCREENBASE+(row&0x1F)*32; 316 | int i=0; 317 | u16 asterisk; 318 | u16 space; 319 | int map_add = 0x1000 * FONT_PALETTE_NUMBER; 320 | map_add+= hilite * 0x1000; 321 | space = lookup_character(' '); 322 | asterisk = lookup_character('*') + map_add; 323 | 324 | if (hilite>=0) 325 | { 326 | //leading asterisk 327 | *here = hilite ? asterisk : space; 328 | here++; 329 | } 330 | else 331 | { 332 | hilite=-hilite-1; 333 | } 334 | 335 | while(str[i]>=' ' && i<29 && i =' ' && i<29) 361 | { 362 | *dest++=str[i++]+hilite; 363 | } 364 | for (;i<29;i++) 365 | { 366 | *dest=' '; 367 | } 368 | } 369 | } 370 | } 371 | 372 | void setdarkness(int dark) { 373 | darkness=dark; 374 | //REG_BLDCNT=0x01f1; //darken game screen 375 | //REG_BLDY=dark; //Darken screen 376 | //REG_BLDALPHA=(0x10-dark)<<8; //set blending for OBJ affected BG0 377 | } 378 | 379 | void setbrightnessall(int light) { 380 | darkness=light|0x80; 381 | //REG_BLDCNT=0x00bf; //brightness increase all 382 | //REG_BLDY=light; 383 | } 384 | 385 | void waitkey() 386 | { 387 | u32 key; 388 | clearoldkey(); 389 | do 390 | { 391 | key=getmenuinput(1); 392 | waitframe(); 393 | } while (!(key & (A_BTN | B_BTN | START))); 394 | } 395 | 396 | //#endif 397 | -------------------------------------------------------------------------------- /src/memory.s: -------------------------------------------------------------------------------- 1 | .section .iwram.2, "ax", %progbits 2 | 3 | @ #include "equates.h" 4 | @ #include "gbz80.h" 5 | @ #include "lcd.h" 6 | 7 | global_func void 8 | global_func empty_R 9 | global_func empty_W 10 | global_func mem_R00 11 | global_func mem_R20 12 | global_func mem_R40 13 | global_func mem_R60 14 | global_func mem_R80 15 | global_func mem_RA0 16 | global_func mem_RC0 17 | global_func mem_RC0_2 18 | global_func sram_W 19 | global_func sram_W2 20 | global_func wram_W 21 | global_func wram_W_2 22 | global_func echo_W 23 | global_func echo_R 24 | 25 | global_func memset32_ 26 | global_func memcpy32_ 27 | global_func memset32 28 | global_func memcpy32 29 | global_func memcpy_unaligned_src 30 | 31 | .global sram_W2_modify 32 | @---------------------------------------------------------------------------- 33 | empty_R: @read bad address (error) 34 | @---------------------------------------------------------------------------- 35 | .if DEBUG 36 | mov r0,addy 37 | mov r1,#0 38 | b debug_ 39 | .endif 40 | 41 | @ mov gb_flg,addy,lsr#8 42 | @ mov pc,lr 43 | void: @- - - - - - - - -empty function 44 | mov r0,#0xff @is this good? 45 | mov pc,lr 46 | @---------------------------------------------------------------------------- 47 | empty_W: @write bad address (error) 48 | @---------------------------------------------------------------------------- 49 | .if DEBUG 50 | mov r0,addy 51 | mov r1,#0 52 | b debug_ 53 | .else 54 | mov pc,lr 55 | .endif 56 | @---------------------------------------------------------------------------- 57 | mem_R00: @rom read ($0000-$1FFF) 58 | @---------------------------------------------------------------------------- 59 | ldr_ r1,memmap_tbl 60 | ldrb r0,[r1,addy] 61 | mov pc,lr 62 | @---------------------------------------------------------------------------- 63 | mem_R20: @rom read ($2000-$3FFF) 64 | @---------------------------------------------------------------------------- 65 | ldr_ r1,memmap_tbl+8 66 | ldrb r0,[r1,addy] 67 | mov pc,lr 68 | @---------------------------------------------------------------------------- 69 | mem_R40: @rom read ($4000-$5FFF) 70 | @---------------------------------------------------------------------------- 71 | ldr_ r1,memmap_tbl+16 72 | ldrb r0,[r1,addy] 73 | mov pc,lr 74 | @---------------------------------------------------------------------------- 75 | mem_R60: @rom read ($6000-$7FFF) 76 | @---------------------------------------------------------------------------- 77 | ldr_ r1,memmap_tbl+24 78 | ldrb r0,[r1,addy] 79 | mov pc,lr 80 | @---------------------------------------------------------------------------- 81 | mem_R80: @vram read ($8000-$9FFF) 82 | @---------------------------------------------------------------------------- 83 | ldr_ r1,memmap_tbl+32 84 | ldrb r0,[r1,addy] 85 | mov pc,lr 86 | @---------------------------------------------------------------------------- 87 | mem_RA0: @sram read ($A000-$BFFF) 88 | @---------------------------------------------------------------------------- 89 | ldr_ r1,memmap_tbl+40 90 | ldrb r0,[r1,addy] 91 | mov pc,lr 92 | @---------------------------------------------------------------------------- 93 | mem_RC0: @ram read ($C000-$CFFF) 94 | @---------------------------------------------------------------------------- 95 | ldr_ r1,memmap_tbl+48 96 | ldrb r0,[r1,addy] 97 | mov pc,lr 98 | @---------------------------------------------------------------------------- 99 | mem_RC0_2: @ram read ($D000-$DFFF) 100 | @---------------------------------------------------------------------------- 101 | ldr_ r1,memmap_tbl+52 102 | ldrb r0,[r1,addy] 103 | mov pc,lr 104 | @---------------------------------------------------------------------------- 105 | sram_W2: @write to real sram ($A000-$BFFF) AND emulated sram 106 | @---------------------------------------------------------------------------- 107 | orr r1,addy,#0xe000000 @r1=e00A000+ 108 | sram_W2_modify: 109 | .if SRAM_32 110 | sub r1,r1,#0x4000 @32k sram: A000>>6000 111 | .else @64k sram 112 | add r1,r1,#0x4000 @64k sram: A000>>E000 113 | .endif 114 | strb r0,[r1] 115 | @---------------------------------------------------------------------------- 116 | sram_W: @sram write ($A000-$BFFF) 117 | @---------------------------------------------------------------------------- 118 | ldr_ r1,memmap_tbl+40 119 | strb r0,[r1,addy] 120 | mov pc,lr 121 | @---------------------------------------------------------------------------- 122 | wram_W: @wram write ($C000-$CFFF) 123 | @---------------------------------------------------------------------------- 124 | @ ldr r1,memmap_tbl+48 125 | adrl_ r1,xgb_ram-0xC000 126 | strb r0,[r1,addy] 127 | mov pc,lr 128 | @---------------------------------------------------------------------------- 129 | wram_W_2: @wram write ($D000-$DFFF) 130 | @---------------------------------------------------------------------------- 131 | ldr_ r1,memmap_tbl+52 132 | strb r0,[r1,addy] 133 | mov pc,lr 134 | .text 135 | echo_R: 136 | sub addy,addy,#0x2000 137 | tst addy,#0x1000 138 | beq mem_RC0 139 | b_long mem_RC0_2 140 | 141 | echo_W: 142 | sub addy,addy,#0x2000 143 | tst addy,#0x1000 144 | beq wram_W 145 | b_long wram_W_2 146 | .section .iwram.2, "ax", %progbits 147 | 148 | 149 | memset32: 150 | @word aligned only 151 | @r0 = dest, r1 = data, r2 = byte count 152 | @if byte count is not word aligned, will overwrite more bytes until aligned 153 | subs r2,r2,#32 154 | blt 2f 155 | stmfd sp!,{r3-r9} 156 | mov r3,r1 157 | mov r4,r1 158 | mov r5,r1 159 | mov r6,r1 160 | mov r7,r1 161 | mov r8,r1 162 | mov r9,r1 163 | 0: 164 | stmia r0!,{r1,r3-r9} 165 | subs r2,r2,#32 166 | blt 1f 167 | stmia r0!,{r1,r3-r9} 168 | subs r2,r2,#32 169 | blt 1f 170 | stmia r0!,{r1,r3-r9} 171 | subs r2,r2,#32 172 | blt 1f 173 | stmia r0!,{r1,r3-r9} 174 | subs r2,r2,#32 175 | bge 0b 176 | 1: 177 | ldmfd sp!,{r3-r9} 178 | 2: 179 | adds r2,r2,#32 180 | bxle lr 181 | 0: 182 | str r1,[r0],#4 183 | subs r2,r2,#4 184 | bgt 0b 185 | bx lr 186 | memcpy32: 187 | @dest and source must be word-aligned, count may be unaligned 188 | @r0=dest, r1=src, r2=byte count 189 | subs r2,r2,#32 190 | blt 2f 191 | stmfd sp!,{r3-r10} 192 | 0: 193 | ldmia r1!,{r3-r10} 194 | stmia r0!,{r3-r10} 195 | subs r2,r2,#32 196 | blt 1f 197 | ldmia r1!,{r3-r10} 198 | stmia r0!,{r3-r10} 199 | subs r2,r2,#32 200 | blt 1f 201 | ldmia r1!,{r3-r10} 202 | stmia r0!,{r3-r10} 203 | subs r2,r2,#32 204 | blt 1f 205 | ldmia r1!,{r3-r10} 206 | stmia r0!,{r3-r10} 207 | subs r2,r2,#32 208 | bge 0b 209 | 1: 210 | ldmfd sp!,{r3-r10} 211 | 2: 212 | adds r2,r2,#32 213 | bxle lr 214 | 0: 215 | @subtract first to see if we go negative, don't do a copy step if we're negative 216 | subs r2,r2,#4 217 | ldrge r12,[r1],#4 218 | strge r12,[r0],#4 219 | bgt 0b 220 | bxeq lr 221 | @trailing bytes 222 | @fall thru to bytecopy_plus4 223 | 224 | global_func bytecopy 225 | bytecopy_plus4: 226 | add r2,r2,#4 227 | bytecopy: 228 | ldrb r12,[r1],#1 229 | strb r12,[r0],#1 230 | subs r2,r2,#1 231 | bgt bytecopy 232 | bx lr 233 | 234 | global_func memset8 235 | memset8: 236 | strb r1,[r0],#1 237 | subs r2,r2,#1 238 | bgt memset8 239 | bx lr 240 | 241 | 242 | 243 | global_func memcpy 244 | 245 | memcpy: 246 | @r0 = dest, r1 = src, r2 = count 247 | @unaligned destination? Use bytecopy instead. 248 | ands r12,r0,#3 249 | bne bytecopy 250 | 251 | @dest must be word aligned, count may be unaligned 252 | memcpy_unaligned_src: 253 | @get shift values/alignment 254 | ands r12,r1,#3 255 | @use aligned memcpy if aligned 256 | beq memcpy32 257 | stmfd sp!,{r3,r4,lr} 258 | mov r12,r12,lsl#3 259 | rsb lr,r12,#32 260 | @r12 = RSHIFT 261 | @lr = LSHIFT 262 | bic r1,r1,#3 263 | ldr r3,[r1],#4 264 | mov r3,r3,lsr r12 265 | 0: 266 | @subtract first to see if we go negative, don't do a store if we're negative 267 | subs r2,r2,#4 268 | @loop: load word, merge with old word (at proper shift location), store word 269 | ldr r4,[r1],#4 270 | orr r3,r3,r4,lsl lr 271 | strge r3,[r0],#4 272 | movge r3,r4,lsr r12 273 | bgt 0b 274 | ldmeqfd sp!,{r3,r4,lr} 275 | bxeq lr 276 | @do remaining bytes of r3 277 | add r2,r2,#4 278 | 0: 279 | strb r3,[r0],#1 280 | mov r3,r3,lsr#8 281 | subs r2,r2,#1 282 | bgt 0b 283 | ldmfd sp!,{r3,r4,lr} 284 | bx lr 285 | 286 | 287 | .align 288 | .pool 289 | .text 290 | .align 291 | .pool 292 | memset32_: 293 | b_long memset32 294 | memcpy32_: 295 | b_long memcpy32 296 | 297 | 298 | @filler_ ;r0=data r1=dest r2=word count 299 | @@ exit with r0 unchanged 300 | @@---------------------------------------------------------------------------- 301 | @ subs r2,r2,#1 302 | @ str r0,[r1,r2,lsl#2] 303 | @ bne filler_ 304 | @ bx lr 305 | @@---------------------------------------------------------------------------- 306 | @copy_ 307 | @ ;r0=dest, r1=src, r2=count, addy=destroyed 308 | @ subs r2,r2,#1 309 | @ ldr addy,[r1,r2,lsl#2] 310 | @ str addy,[r0,r2,lsl#2] 311 | @ bne copy_ 312 | @ bx lr 313 | 314 | @.end 315 | -------------------------------------------------------------------------------- /src/mappers.s: -------------------------------------------------------------------------------- 1 | .section .iwram.2, "ax", %progbits 2 | 3 | @ #include "equates.h" 4 | @ #include "memory.h" 5 | @ #include "lcd.h" 6 | @ #include "cart.h" 7 | @ #include "io.h" 8 | 9 | .if RUMBLE 10 | @IMPORT DoRumble 11 | .endif 12 | global_func mbc0init 13 | global_func mbc1init 14 | global_func mbc2init 15 | global_func mbc3init 16 | global_func mbc4init 17 | global_func mbc5init 18 | global_func mbc6init 19 | global_func mbc7init 20 | global_func mmm01init 21 | global_func huc1init 22 | global_func huc3init 23 | global_func RamSelect 24 | @---------------------------------------------------------------------------- 25 | RamSelect: 26 | @---------------------------------------------------------------------------- 27 | ldrb_ r0,mapperdata+2 @ram enable 28 | @---------------------------------------------------------------------------- 29 | RamEnable: 30 | @---------------------------------------------------------------------------- 31 | strb_ r0,mapperdata+2 32 | and r0,r0,#0x0F 33 | cmp r0,#0x0A 34 | adrnel r1,empty_W 35 | ldreq_ r1,sramwptr 36 | str_ r1,writemem_tbl+40 37 | str_ r1,writemem_tbl+44 38 | adrnel r1,empty_R 39 | adreql r1,mem_RA0 40 | str_ r1,readmem_tbl_-40 41 | str_ r1,readmem_tbl_-44 42 | ldrb_ r0,mapperdata+4 @rambank 43 | b mapAB_ 44 | 45 | .pushsection .text 46 | @---------------------------------------------------------------------------- 47 | mbc0init: 48 | @---------------------------------------------------------------------------- 49 | .word void,void,void,void 50 | mov pc,lr 51 | 52 | @mapperdata for mbc1: 53 | @0 low 5 bits of rom bank number (00-1F), 00 becomes 01. 54 | @1 high 2 bits of rom bank number 55 | @2 sram enabled (0A if enabled) 56 | @3 rom/ram bankswitch mode (0 for rom, 1 for ram) 57 | @4 sram bank 58 | @5 2 bits for either rom bank or sram bank 59 | 60 | @---------------------------------------------------------------------------- 61 | mbc1init: 62 | @---------------------------------------------------------------------------- 63 | .word RamEnable,MBC1map0,MBC1map1,MBC1mode 64 | mov pc,lr 65 | 66 | .popsection 67 | @---------------------------------------------------------------------------- 68 | MBC1map0: 69 | @---------------------------------------------------------------------------- 70 | ands r0,r0,#0x1f 71 | moveq r0,#1 72 | strb_ r0,mapperdata 73 | ldrb_ r1,mapperdata+1 74 | orr r0,r0,r1,lsl#5 75 | b map4567_ 76 | 77 | .pushsection .text 78 | @---------------------------------------------------------------------------- 79 | MBC1map1: 80 | @---------------------------------------------------------------------------- 81 | and r0,r0,#0x03 82 | strb_ r0,mapperdata+5 @Ram/Rom bank select. 83 | ldrb_ r0,mapperdata+3 84 | @---------------------------------------------------------------------------- 85 | MBC1mode: 86 | @---------------------------------------------------------------------------- 87 | strb_ r0,mapperdata+3 88 | tst r0,#1 89 | ldrb_ r0,mapperdata+5 90 | mov r1,#0 91 | streqb_ r0,mapperdata+1 @16Mbit Rom 92 | strneb_ r1,mapperdata+1 @4Mbit Rom 93 | streqb_ r1,mapperdata+4 @8kByte Ram 94 | strneb_ r0,mapperdata+4 @32kbyte Ram 95 | 96 | ldrb_ r0,mapperdata 97 | ldrb_ r1,mapperdata+1 98 | orr r0,r0,r1,lsl#5 99 | str lr,[sp,#-4]! 100 | bl map4567_ 101 | ldr lr,[sp],#4 102 | b RamSelect 103 | 104 | @---------------------------------------------------------------------------- 105 | mbc2init: 106 | @---------------------------------------------------------------------------- 107 | .word MBC2RamEnable,MBC2map,void,void 108 | mov pc,lr 109 | .popsection 110 | @---------------------------------------------------------------------------- 111 | MBC2map: 112 | @---------------------------------------------------------------------------- 113 | tst addy,#0x0100 114 | moveq pc,lr 115 | ands r0,r0,#0xf 116 | moveq r0,#1 117 | b map4567_ 118 | .pushsection .text 119 | @---------------------------------------------------------------------------- 120 | MBC2RamEnable: 121 | tst addy,#0x0100 122 | beq_long RamEnable 123 | mov pc,lr 124 | 125 | @---------------------------------------------------------------------------- 126 | mbc3init: 127 | @---------------------------------------------------------------------------- 128 | .word RamEnable,map4567_,mbc3bank,mbc3latchtime 129 | mov pc,lr 130 | @---------------------------------------------------------------------------- 131 | mbc3latchtime: 132 | @---------------------------------------------------------------------------- 133 | ldrb_ r1,mapperdata+3 134 | strb_ r0,mapperdata+3 135 | eor r1,r1,r0 136 | and r1,r1,r0 137 | cmp r1,#1 138 | movne pc,lr 139 | stmfd sp!,{r3,lr} 140 | bl_long gettime 141 | ldmfd sp!,{r3,lr} 142 | mov pc,lr 143 | @---------------------------------------------------------------------------- 144 | mbc3bank: 145 | @---------------------------------------------------------------------------- 146 | strb_ r0,mapperdata+4 147 | tst r0,#8 148 | beq RamSelect 149 | ldr r1,=empty_W 150 | str_ r1,writemem_tbl+40 151 | str_ r1,writemem_tbl+44 152 | ldr r1,=empty_R 153 | cmp r0,#0x8 154 | adreq r1,clk_sec 155 | cmp r0,#0x9 156 | adreq r1,clk_min 157 | cmp r0,#0xA 158 | adreq r1,clk_hrs 159 | cmp r0,#0xB 160 | adreq r1,clk_dayL 161 | cmp r0,#0xC 162 | adreq r1,clk_dayH 163 | str_ r1,readmem_tbl_-40 164 | str_ r1,readmem_tbl_-44 165 | mov pc,lr 166 | 167 | @------------------------------ 168 | clk_sec: 169 | ldrb_ r0,mapperdata+30 170 | b calctime 171 | @------------------------------ 172 | clk_min: 173 | ldrb_ r0,mapperdata+29 174 | b calctime 175 | @------------------------------ 176 | clk_hrs: 177 | ldrb_ r0,mapperdata+28 178 | and r0,r0,#0x3F 179 | b calctime 180 | @------------------------------ 181 | clk_dayL: 182 | ldrb_ r0,mapperdata+26 183 | b calctime 184 | clk_dayH: 185 | mov r0,#0 186 | calctime: 187 | and r1,r0,#0xf 188 | mov r0,r0,lsr#4 189 | add r0,r0,r0,lsl#2 190 | add r0,r1,r0,lsl#1 191 | mov pc,lr 192 | @------------------------------ 193 | 194 | 195 | @---------------------------------------------------------------------------- 196 | mbc5init: 197 | @---------------------------------------------------------------------------- 198 | .word RamEnable,MBC5map0,MBC5RAMB,void 199 | mov pc,lr 200 | .popsection 201 | @---------------------------------------------------------------------------- 202 | MBC5map0: 203 | @---------------------------------------------------------------------------- 204 | tst addy,#0x1000 205 | andne r0,r0,#0x01 206 | strneb_ r0,mapperdata+1 207 | streqb_ r0,mapperdata 208 | ldr_ r0,mapperdata 209 | b map4567_ 210 | @---------------------------------------------------------------------------- 211 | MBC5RAMB: 212 | @---------------------------------------------------------------------------- 213 | strb_ r0,mapperdata+4 214 | @ tst r0,#0x08 ;rumble motor. 215 | and r0,r0,#0x8 216 | .if RUMBLE 217 | ldr r1,=DoRumble 218 | str r0,[r1] 219 | .endif 220 | b RamSelect 221 | 222 | .pushsection .text 223 | @---------------------------------------------------------------------------- 224 | mbc7init: 225 | @---------------------------------------------------------------------------- 226 | .word void,MBC7map,MBC7RAMB,void 227 | mov pc,lr 228 | .popsection 229 | @---------------------------------------------------------------------------- 230 | MBC7map: 231 | @---------------------------------------------------------------------------- 232 | ands r0,r0,#0x7f 233 | moveq r0,#1 234 | strb_ r0,mapperdata 235 | b map4567_ 236 | .pushsection .text 237 | @---------------------------------------------------------------------------- 238 | MBC7RAMB: 239 | @---------------------------------------------------------------------------- 240 | strb_ r0,mapperdata+4 241 | cmp r0,#9 242 | movmi r0,#0xA 243 | movpl r0,#0 244 | strb_ r0,mapperdata+2 245 | b RamSelect 246 | 247 | @---------------------------------------------------------------------------- 248 | huc1init: 249 | @---------------------------------------------------------------------------- 250 | .word RamEnable,HUC1map0,MBC1map1,MBC1mode 251 | @ DCD RamEnable,HUC1map0,MBC5RAMB,void 252 | mov pc,lr 253 | .popsection 254 | @---------------------------------------------------------------------------- 255 | HUC1map0: 256 | @---------------------------------------------------------------------------- 257 | ands r0,r0,#0x3f 258 | moveq r0,#1 259 | strb_ r0,mapperdata 260 | @ ldrb r1,mapperdata+1 261 | @ orr r0,r0,r1,lsl#5 262 | b map4567_ 263 | 264 | .pushsection .text 265 | @---------------------------------------------------------------------------- 266 | huc3init: 267 | @---------------------------------------------------------------------------- 268 | .word RamEnable,map4567_,MBC5RAMB,void 269 | mov pc,lr 270 | 271 | @---------------------------------------------------------------------------- 272 | mmm01init: 273 | mbc4init: 274 | mbc6init: 275 | @---------------------------------------------------------------------------- 276 | .word RamEnable,map4567_,void,void 277 | mov pc,lr 278 | .popsection 279 | 280 | @---------------------------------------------------------------------------- 281 | @---------------------------------------------------------------------------- 282 | @.end 283 | -------------------------------------------------------------------------------- /src/_gba_crt0_my.s: -------------------------------------------------------------------------------- 1 | .section ".init" 2 | .global _start 3 | .align 4 | .arm 5 | @--------------------------------------------------------------------------------- 6 | _start: 7 | @--------------------------------------------------------------------------------- 8 | b rom_header_end 9 | 10 | .fill 156,1,0 @ Nintendo Logo Character Data (8000004h) 11 | .fill 16,1,0 @ Game Title 12 | .byte 0x30,0x31 @ Maker Code (80000B0h) 13 | .byte 0x96 @ Fixed Value (80000B2h) 14 | .byte 0x00 @ Main Unit Code (80000B3h) 15 | .byte 0x00 @ Device Type (80000B4h) 16 | .fill 7,1,0 @ unused 17 | .byte 0x00 @ Software Version No (80000BCh) 18 | .byte 0xf0 @ Complement Check (80000BDh) 19 | .byte 0x00,0x00 @ Checksum (80000BEh) 20 | 21 | @--------------------------------------------------------------------------------- 22 | rom_header_end: 23 | @--------------------------------------------------------------------------------- 24 | b start_vector @ This branch must be here for proper 25 | @ positioning of the following header. 26 | 27 | .GLOBAL __boot_method, __slave_number 28 | @--------------------------------------------------------------------------------- 29 | __boot_method: 30 | @--------------------------------------------------------------------------------- 31 | .byte 0 @ boot method (0=ROM boot, 3=Multiplay boot) 32 | @--------------------------------------------------------------------------------- 33 | __slave_number: 34 | @--------------------------------------------------------------------------------- 35 | .byte 0 @ slave # (1=slave#1, 2=slave#2, 3=slave#3) 36 | 37 | .byte 0 @ reserved 38 | .byte 0 @ reserved 39 | .word 0 @ reserved 40 | .word 0 @ reserved 41 | .word 0 @ reserved 42 | .word 0 @ reserved 43 | .word 0 @ reserved 44 | .word 0 @ reserved 45 | 46 | .global start_vector 47 | .align 48 | @--------------------------------------------------------------------------------- 49 | start_vector: 50 | @--------------------------------------------------------------------------------- 51 | mov r0, #0x4000000 @ REG_BASE 52 | str r0, [r0, #0x208] 53 | 54 | mov r0, #0x12 @ Switch to IRQ Mode 55 | msr cpsr, r0 56 | ldr sp, =__sp_irq @ Set IRQ stack 57 | mov r0, #0x1f @ Switch to System Mode 58 | msr cpsr, r0 59 | ldr sp, =__sp_usr @ Set user stack 60 | 61 | @--------------------------------------------------------------------------------- 62 | @ Enter Thumb mode 63 | @--------------------------------------------------------------------------------- 64 | add r0, pc, #1 65 | bx r0 66 | 67 | .thumb 68 | 69 | mov r7,#0 70 | goback: 71 | ldr r0, =__text_start 72 | lsl r0, #5 @ Was code compiled at 0x08000000 or higher? 73 | bcs DoEWRAMClear @ yes, you can not run it in external WRAM 74 | 75 | mov r0, pc 76 | lsl r0, #5 @ Are we running from ROM (0x8000000 or higher) ? 77 | bcc SkipEWRAMClear @ No, so no need to do a copy. 78 | 79 | @--------------------------------------------------------------------------------- 80 | @ We were started in ROM, silly emulators. :P 81 | @ So we need to copy to ExWRAM. 82 | @--------------------------------------------------------------------------------- 83 | mov r7,#1 84 | 85 | mov r2, #2 86 | lsl r2, r2, #24 @ r2= 0x02000000 87 | ldr r3, =__end__ @ last ewram address 88 | sub r3, r2 @ r3= actual binary size 89 | mov r6, r2 @ r6= 0x02000000 90 | lsl r1, r2, #2 @ r1= 0x08000000 91 | 92 | bl CopyMem 93 | ldr r0,=goback+1 94 | mov pc,r0 95 | 96 | ; bx r6 @ Jump to the code to execute 97 | 98 | @--------------------------------------------------------------------------------- 99 | DoEWRAMClear: @ Clear External WRAM to 0x00 100 | @--------------------------------------------------------------------------------- 101 | mov r1, #0x40 102 | lsl r1, #12 @ r1 = 0x40000 103 | lsl r0, r1, #7 @ r0 = 0x2000000 104 | bl ClearMem 105 | 106 | @--------------------------------------------------------------------------------- 107 | SkipEWRAMClear: @ Clear Internal WRAM to 0x00 108 | @--------------------------------------------------------------------------------- 109 | 110 | @--------------------------------------------------------------------------------- 111 | @ Clear BSS section to 0x00 112 | @--------------------------------------------------------------------------------- 113 | ldr r0, =__bss_start 114 | ldr r1, =__bss_end 115 | sub r1, r0 116 | bl ClearMem 117 | 118 | @--------------------------------------------------------------------------------- 119 | @ Clear SBSS section to 0x00 120 | @--------------------------------------------------------------------------------- 121 | ldr r0, =__sbss_start 122 | ldr r1, =__sbss_end 123 | sub r1, r0 124 | bl ClearMem 125 | 126 | @--------------------------------------------------------------------------------- 127 | @ Copy initialized data (data section) from LMA to VMA (ROM to RAM) 128 | @--------------------------------------------------------------------------------- 129 | ldr r1, =__data_lma 130 | ldr r2, =__data_start 131 | ldr r4, =__data_end 132 | bl CopyMemChk 133 | 134 | @--------------------------------------------------------------------------------- 135 | @ Copy internal work ram (iwram section) from LMA to VMA (ROM to RAM) 136 | @--------------------------------------------------------------------------------- 137 | ldr r1,= __iwram_lma 138 | ldr r2,= __iwram_start 139 | ldr r4,= __iwram_end 140 | bl CopyMemChk 141 | 142 | @--------------------------------------------------------------------------------- 143 | @ Copy internal work ram overlay 0 (iwram0 section) from LMA to VMA (ROM to RAM) 144 | @--------------------------------------------------------------------------------- 145 | ldr r2,= __load_stop_iwram0 146 | ldr r1,= __load_start_iwram0 147 | sub r3, r2, r1 @ Is there any data to copy? 148 | beq CIW0Skip @ no 149 | 150 | ldr r2,= __iwram_overlay_start 151 | bl CopyMem 152 | @--------------------------------------------------------------------------------- 153 | CIW0Skip: 154 | @--------------------------------------------------------------------------------- 155 | @ Copy external work ram (ewram section) from LMA to VMA (ROM to RAM) 156 | @--------------------------------------------------------------------------------- 157 | ldr r1, =__ewram_lma 158 | ldr r2, =__ewram_start 159 | ldr r4, =__ewram_end 160 | bl CopyMemChk 161 | 162 | @--------------------------------------------------------------------------------- 163 | CEW0Skip: 164 | @--------------------------------------------------------------------------------- 165 | @ set heap end 166 | @--------------------------------------------------------------------------------- 167 | ldr r1, =fake_heap_end 168 | ldr r0, =__eheap_end 169 | str r0, [r1] 170 | @--------------------------------------------------------------------------------- 171 | @ global constructors 172 | @--------------------------------------------------------------------------------- 173 | ldr r3, =__libc_init_array 174 | bl _call_via_r3 175 | @--------------------------------------------------------------------------------- 176 | @ Jump to user code 177 | @--------------------------------------------------------------------------------- 178 | ldr r0,=copiedfromrom 179 | str r7,[r0] 180 | 181 | mov r0, #0 @ int argc 182 | mov r1, #0 @ char *argv[] 183 | 184 | ldr r3, =main 185 | bl _call_via_r3 186 | @--------------------------------------------------------------------------------- 187 | @ Clear memory to 0x00 if length != 0 188 | @--------------------------------------------------------------------------------- 189 | @ r0 = Start Address 190 | @ r1 = Length 191 | @--------------------------------------------------------------------------------- 192 | ClearMem: 193 | @--------------------------------------------------------------------------------- 194 | mov r2,#3 @ These commands are used in cases where 195 | add r1,r2 @ the length is not a multiple of 4, 196 | bic r1,r2 @ even though it should be. 197 | 198 | beq ClearMX @ Length is zero so exit 199 | 200 | mov r2,#0 201 | @--------------------------------------------------------------------------------- 202 | ClrLoop: 203 | @--------------------------------------------------------------------------------- 204 | stmia r0!, {r2} 205 | sub r1,#4 206 | bne ClrLoop 207 | @--------------------------------------------------------------------------------- 208 | ClearMX: 209 | @--------------------------------------------------------------------------------- 210 | bx lr 211 | 212 | @--------------------------------------------------------------------------------- 213 | @ Copy memory if length != 0 214 | @--------------------------------------------------------------------------------- 215 | @ r1 = Source Address 216 | @ r2 = Dest Address 217 | @ r4 = Dest Address + Length 218 | @--------------------------------------------------------------------------------- 219 | CopyMemChk: 220 | @--------------------------------------------------------------------------------- 221 | sub r3, r4, r2 @ Is there any data to copy? 222 | @--------------------------------------------------------------------------------- 223 | @ Copy memory 224 | @--------------------------------------------------------------------------------- 225 | @ r1 = Source Address 226 | @ r2 = Dest Address 227 | @ r3 = Length 228 | @--------------------------------------------------------------------------------- 229 | CopyMem: 230 | @--------------------------------------------------------------------------------- 231 | mov r0, #3 @ These commands are used in cases where 232 | add r3, r0 @ the length is not a multiple of 4, 233 | bic r3, r0 @ even though it should be. 234 | beq CIDExit @ Length is zero so exit 235 | 236 | @--------------------------------------------------------------------------------- 237 | CIDLoop: 238 | @--------------------------------------------------------------------------------- 239 | ldmia r1!, {r0} 240 | stmia r2!, {r0} 241 | sub r3, #4 242 | bne CIDLoop 243 | @--------------------------------------------------------------------------------- 244 | CIDExit: 245 | @--------------------------------------------------------------------------------- 246 | bx lr 247 | 248 | .align 249 | .pool 250 | .end 251 | 252 | -------------------------------------------------------------------------------- /src/gba_crt0_my.s: -------------------------------------------------------------------------------- 1 | #include "equates.h" 2 | 3 | .section ".init" 4 | global_func _start 5 | .align 6 | .arm 7 | @--------------------------------------------------------------------------------- 8 | _start: 9 | @--------------------------------------------------------------------------------- 10 | b rom_header_end 11 | 12 | .fill 156,1,0 @ Nintendo Logo Character Data (8000004h) 13 | .fill 16,1,0 @ Game Title 14 | .byte 0x30,0x31 @ Maker Code (80000B0h) 15 | .byte 0x96 @ Fixed Value (80000B2h) 16 | .byte 0x00 @ Main Unit Code (80000B3h) 17 | .byte 0x00 @ Device Type (80000B4h) 18 | .fill 7,1,0 @ unused 19 | .byte 0x00 @ Software Version No (80000BCh) 20 | .byte 0xf0 @ Complement Check (80000BDh) 21 | .byte 0x00,0x00 @ Checksum (80000BEh) 22 | 23 | @--------------------------------------------------------------------------------- 24 | rom_header_end: 25 | @--------------------------------------------------------------------------------- 26 | b start_vector @ This branch must be here for proper 27 | @ positioning of the following header. 28 | 29 | .GLOBAL __boot_method, __slave_number 30 | @--------------------------------------------------------------------------------- 31 | __boot_method: 32 | @--------------------------------------------------------------------------------- 33 | .byte 0 @ boot method (0=ROM boot, 3=Multiplay boot) 34 | @--------------------------------------------------------------------------------- 35 | __slave_number: 36 | @--------------------------------------------------------------------------------- 37 | .byte 0 @ slave # (1=slave#1, 2=slave#2, 3=slave#3) 38 | 39 | .byte 0 @ reserved 40 | .byte 0 @ reserved 41 | .word 0 @ reserved 42 | .word 0 @ reserved 43 | .word 0 @ reserved 44 | .word 0 @ reserved 45 | .word 0 @ reserved 46 | .word 0 @ reserved 47 | 48 | global_func start_vector 49 | .align 50 | @--------------------------------------------------------------------------------- 51 | start_vector: 52 | @--------------------------------------------------------------------------------- 53 | mov r0, #0x4000000 @ REG_BASE 54 | str r0, [r0, #0x208] 55 | 56 | mov r0, #0x12 @ Switch to IRQ Mode 57 | msr cpsr, r0 58 | ldr sp, =__sp_irq @ Set IRQ stack 59 | mov r0, #0x1f @ Switch to System Mode 60 | msr cpsr, r0 61 | ldr sp, =__sp_usr @ Set user stack 62 | 63 | @--------------------------------------------------------------------------------- 64 | @ Enter Thumb mode 65 | @--------------------------------------------------------------------------------- 66 | add r0, pc, #1 67 | bx r0 68 | 69 | .thumb 70 | 71 | mov r7,#0 72 | goback: 73 | ldr r0, =__text_start 74 | lsl r0, #5 @ Was code compiled at 0x08000000 or higher? 75 | @ bcs DoEWRAMClear @ yes, you can not run it in external WRAM 76 | bcs SkipEWRAMClear @ yes, you can not run it in external WRAM 77 | 78 | mov r0, pc 79 | lsl r0, #5 @ Are we running from ROM (0x8000000 or higher) ? 80 | bcc SkipEWRAMClear @ No, so no need to do a copy. 81 | 82 | @--------------------------------------------------------------------------------- 83 | @ We were started in ROM, silly emulators. :P 84 | @ So we need to copy to ExWRAM. 85 | @--------------------------------------------------------------------------------- 86 | mov r7,#1 87 | 88 | mov r2, #2 89 | lsl r2, r2, #24 @ r2= 0x02000000 90 | ldr r3, =__end__ @ last ewram address 91 | sub r3, r2 @ r3= actual binary size 92 | mov r6, r2 @ r6= 0x02000000 93 | lsl r1, r2, #2 @ r1= 0x08000000 94 | 95 | bl CopyMem 96 | ldr r0,=goback+1 97 | mov pc,r0 98 | 99 | @ bx r6 @ Jump to the code to execute 100 | 101 | @--------------------------------------------------------------------------------- 102 | @DoEWRAMClear: @ Clear External WRAM to 0x00 103 | @--------------------------------------------------------------------------------- 104 | @ mov r1, #0x40 105 | @ lsl r1, #12 @ r1 = 0x40000 106 | @ lsl r0, r1, #7 @ r0 = 0x2000000 107 | @ bl ClearMem 108 | 109 | @--------------------------------------------------------------------------------- 110 | SkipEWRAMClear: @ Clear Internal WRAM to 0x00 111 | @--------------------------------------------------------------------------------- 112 | 113 | @--------------------------------------------------------------------------------- 114 | @ Copy initialized data (data section) from LMA to VMA (ROM to RAM) 115 | @--------------------------------------------------------------------------------- 116 | ldr r1, =__data_lma 117 | ldr r2, =__data_start__ 118 | ldr r4, =__data_end__ 119 | bl CopyMemChk 120 | 121 | @--------------------------------------------------------------------------------- 122 | @ Copy internal work ram (iwram section) from LMA to VMA (ROM to RAM) 123 | @--------------------------------------------------------------------------------- 124 | ldr r1,= __iwram_lma 125 | ldr r2,= __iwram_start__ 126 | ldr r4,= __iwram_end__ 127 | bl CopyMemChk 128 | 129 | @--------------------------------------------------------------------------------- 130 | @ Copy internal work ram overlay 0 (iwram0 section) from LMA to VMA (ROM to RAM) 131 | @--------------------------------------------------------------------------------- 132 | ldr r2,= __load_stop_iwram0 133 | ldr r1,= __load_start_iwram0 134 | sub r3, r2, r1 @ Is there any data to copy? 135 | beq CIW0Skip @ no 136 | 137 | ldr r2,= __iwram_overlay_start 138 | bl CopyMem 139 | @--------------------------------------------------------------------------------- 140 | CIW0Skip: 141 | @--------------------------------------------------------------------------------- 142 | @ Copy external work ram (ewram section) from LMA to VMA (ROM to RAM) 143 | @--------------------------------------------------------------------------------- 144 | ldr r1, =__ewram_lma 145 | ldr r2, =__ewram_start 146 | ldr r4, =__ewram_end 147 | bl CopyMemChk 148 | 149 | @--------------------------------------------------------------------------------- 150 | @ Clear BSS section to 0x00 151 | @--------------------------------------------------------------------------------- 152 | ldr r0, =__bss_start__ 153 | ldr r1, =__bss_end__ 154 | sub r1, r0 155 | bl ClearMem 156 | 157 | @--------------------------------------------------------------------------------- 158 | @ Clear SBSS section to 0x00 159 | @--------------------------------------------------------------------------------- 160 | ldr r0, =__sbss_start__ 161 | ldr r1, =__sbss_end__ 162 | sub r1, r0 163 | bl ClearMem 164 | 165 | @--------------------------------------------------------------------------------- 166 | CEW0Skip: 167 | @--------------------------------------------------------------------------------- 168 | @ set heap end 169 | @--------------------------------------------------------------------------------- 170 | ldr r1, =fake_heap_end 171 | ldr r0, =__eheap_end 172 | str r0, [r1] 173 | @--------------------------------------------------------------------------------- 174 | @ global constructors 175 | @--------------------------------------------------------------------------------- 176 | ldr r3, =__libc_init_array 177 | bl _blx_r3_stub 178 | @--------------------------------------------------------------------------------- 179 | @ Jump to user code 180 | @--------------------------------------------------------------------------------- 181 | ldr r0,=copiedfromrom 182 | str r7,[r0] 183 | 184 | mov r0, #0 @ int argc 185 | mov r1, #0 @ char *argv[] 186 | ldr r3, =main 187 | bl _blx_r3_stub 188 | @--------------------------------------------------------------------------------- 189 | @ Clear memory to 0x00 if length != 0 190 | @--------------------------------------------------------------------------------- 191 | @ r0 = Start Address 192 | @ r1 = Length 193 | @--------------------------------------------------------------------------------- 194 | ClearMem: 195 | @--------------------------------------------------------------------------------- 196 | mov r2,#3 @ These commands are used in cases where 197 | add r1,r2 @ the length is not a multiple of 4, 198 | bic r1,r2 @ even though it should be. 199 | 200 | beq ClearMX @ Length is zero so exit 201 | 202 | mov r2,#0 203 | @--------------------------------------------------------------------------------- 204 | ClrLoop: 205 | @--------------------------------------------------------------------------------- 206 | stmia r0!, {r2} 207 | sub r1,#4 208 | bne ClrLoop 209 | @--------------------------------------------------------------------------------- 210 | ClearMX: 211 | @--------------------------------------------------------------------------------- 212 | bx lr 213 | 214 | @--------------------------------------------------------------------------------- 215 | _blx_r3_stub: 216 | @--------------------------------------------------------------------------------- 217 | bx r3 218 | 219 | @--------------------------------------------------------------------------------- 220 | @ Copy memory if length != 0 221 | @--------------------------------------------------------------------------------- 222 | @ r1 = Source Address 223 | @ r2 = Dest Address 224 | @ r4 = Dest Address + Length 225 | @--------------------------------------------------------------------------------- 226 | CopyMemChk: 227 | @--------------------------------------------------------------------------------- 228 | sub r3, r4, r2 @ Is there any data to copy? 229 | @--------------------------------------------------------------------------------- 230 | @ Copy memory 231 | @--------------------------------------------------------------------------------- 232 | @ r1 = Source Address 233 | @ r2 = Dest Address 234 | @ r3 = Length 235 | @--------------------------------------------------------------------------------- 236 | CopyMem: 237 | @--------------------------------------------------------------------------------- 238 | mov r0, #3 @ These commands are used in cases where 239 | add r3, r0 @ the length is not a multiple of 4, 240 | bic r3, r0 @ even though it should be. 241 | beq CIDExit @ Length is zero so exit 242 | 243 | @--------------------------------------------------------------------------------- 244 | CIDLoop: 245 | @--------------------------------------------------------------------------------- 246 | ldmia r1!, {r0} 247 | stmia r2!, {r0} 248 | sub r3, #4 249 | bne CIDLoop 250 | @--------------------------------------------------------------------------------- 251 | CIDExit: 252 | @--------------------------------------------------------------------------------- 253 | bx lr 254 | 255 | .align 256 | .pool 257 | .end 258 | 259 | -------------------------------------------------------------------------------- /src/macro.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | .macro global_func function 4 | .global \function 5 | .type \function STT_FUNC 6 | .endm 7 | 8 | .macro adrl2 reg,label 9 | mov \reg,#\label&0x0FF00000 10 | add \reg,\reg,#\label&0x000FFFFF 11 | .endm 12 | 13 | .macro start_map base, register 14 | @GBLA _map_address_ 15 | _map_address_ = \base 16 | .endm 17 | 18 | .macro _m_ label=0,size 19 | .if \label != 0 20 | \label = _map_address_ 21 | .endif 22 | _map_address_ = _map_address_ + \size 23 | .endm 24 | 25 | .macro ldr_ reg,label 26 | ldr \reg,[globalptr,#\label] 27 | .endm 28 | 29 | .macro ldrb_ reg,label 30 | ldrb \reg,[globalptr,#\label] 31 | .endm 32 | 33 | .macro ldrh_ reg,label 34 | ldrh \reg,[globalptr,#\label] 35 | .endm 36 | 37 | .macro str_ reg,label 38 | str \reg,[globalptr,#\label] 39 | .endm 40 | 41 | .macro strb_ reg,label 42 | strb \reg,[globalptr,#\label] 43 | .endm 44 | 45 | .macro strh_ reg,label 46 | strh \reg,[globalptr,#\label] 47 | .endm 48 | 49 | 50 | 51 | .macro ldreq_ reg,label 52 | ldreq \reg,[globalptr,#\label] 53 | .endm 54 | 55 | .macro ldreqb_ reg,label 56 | ldreqb \reg,[globalptr,#\label] 57 | .endm 58 | 59 | .macro streq_ reg,label 60 | streq \reg,[globalptr,#\label] 61 | .endm 62 | 63 | .macro streqb_ reg,label 64 | streqb \reg,[globalptr,#\label] 65 | .endm 66 | 67 | 68 | 69 | 70 | .macro ldrne_ reg,label 71 | ldrne \reg,[globalptr,#\label] 72 | .endm 73 | 74 | .macro ldrneb_ reg,label 75 | ldrneb \reg,[globalptr,#\label] 76 | .endm 77 | 78 | .macro strne_ reg,label 79 | strne \reg,[globalptr,#\label] 80 | .endm 81 | 82 | .macro strneb_ reg,label 83 | strneb \reg,[globalptr,#\label] 84 | .endm 85 | 86 | 87 | 88 | .macro ldrhi_ reg,label 89 | ldrhi \reg,[globalptr,#\label] 90 | .endm 91 | 92 | .macro ldrhib_ reg,label 93 | ldrhib \reg,[globalptr,#\label] 94 | .endm 95 | 96 | .macro strhi_ reg,label 97 | strhi \reg,[globalptr,#\label] 98 | .endm 99 | 100 | .macro strhib_ reg,label 101 | strhib \reg,[globalptr,#\label] 102 | .endm 103 | 104 | 105 | .macro ldrmi_ reg,label 106 | ldrmi \reg,[globalptr,#\label] 107 | .endm 108 | 109 | .macro ldrmib_ reg,label 110 | ldrmib \reg,[globalptr,#\label] 111 | .endm 112 | 113 | .macro strmi_ reg,label 114 | strmi \reg,[globalptr,#\label] 115 | .endm 116 | 117 | .macro strmib_ reg,label 118 | strmib \reg,[globalptr,#\label] 119 | .endm 120 | 121 | .macro ldrpl_ reg,label 122 | ldrpl \reg,[globalptr,#\label] 123 | .endm 124 | 125 | .macro ldrplb_ reg,label 126 | ldrplb \reg,[globalptr,#\label] 127 | .endm 128 | 129 | .macro strpl_ reg,label 130 | strpl \reg,[globalptr,#\label] 131 | .endm 132 | 133 | .macro strplb_ reg,label 134 | strplb \reg,[globalptr,#\label] 135 | .endm 136 | 137 | 138 | .macro ldrgt_ reg,label 139 | ldrgt \reg,[globalptr,#\label] 140 | .endm 141 | 142 | .macro ldrgtb_ reg,label 143 | ldrgtb \reg,[globalptr,#\label] 144 | .endm 145 | 146 | .macro strgt_ reg,label 147 | strgt \reg,[globalptr,#\label] 148 | .endm 149 | 150 | .macro strgtb_ reg,label 151 | strgtb \reg,[globalptr,#\label] 152 | .endm 153 | 154 | 155 | .macro ldrge_ reg,label 156 | ldrge \reg,[globalptr,#\label] 157 | .endm 158 | 159 | .macro ldrgeb_ reg,label 160 | ldrgeb \reg,[globalptr,#\label] 161 | .endm 162 | 163 | .macro strge_ reg,label 164 | strge \reg,[globalptr,#\label] 165 | .endm 166 | 167 | .macro strgeb_ reg,label 168 | strgeb \reg,[globalptr,#\label] 169 | .endm 170 | 171 | 172 | .macro ldrlt_ reg,label 173 | ldrlt \reg,[globalptr,#\label] 174 | .endm 175 | 176 | .macro ldrltb_ reg,label 177 | ldrltb \reg,[globalptr,#\label] 178 | .endm 179 | 180 | .macro strlt_ reg,label 181 | strlt \reg,[globalptr,#\label] 182 | .endm 183 | 184 | .macro strltb_ reg,label 185 | strltb \reg,[globalptr,#\label] 186 | .endm 187 | 188 | 189 | .macro ldrle_ reg,label 190 | ldrle \reg,[globalptr,#\label] 191 | .endm 192 | 193 | .macro ldrleb_ reg,label 194 | ldrleb \reg,[globalptr,#\label] 195 | .endm 196 | 197 | .macro strle_ reg,label 198 | strle \reg,[globalptr,#\label] 199 | .endm 200 | 201 | .macro strleb_ reg,label 202 | strleb \reg,[globalptr,#\label] 203 | .endm 204 | 205 | 206 | .macro ldrlo_ reg,label 207 | ldrlo \reg,[globalptr,#\label] 208 | .endm 209 | 210 | .macro ldrlob_ reg,label 211 | ldrlob \reg,[globalptr,#\label] 212 | .endm 213 | 214 | .macro strlo_ reg,label 215 | strlo \reg,[globalptr,#\label] 216 | .endm 217 | 218 | .macro strlob_ reg,label 219 | strlob \reg,[globalptr,#\label] 220 | .endm 221 | 222 | 223 | .macro adr_ reg,label 224 | add \reg,globalptr,#\label 225 | .endm 226 | 227 | .macro adrl_ reg,label 228 | .if \label&0x80000000 229 | sub \reg,globalptr,#((-(\label)) & 0xFF00FF00) 230 | sub \reg,\reg,#((-(\label)) & 0x000000FF) 231 | .else 232 | add \reg,globalptr,#((\label) & 0xFF00FF00) 233 | add \reg,\reg,#((\label) & 0x000000FF) 234 | .endif 235 | .endm 236 | 237 | .if VERSION_IN_ROM 238 | .macro bl_long label 239 | mov lr,pc 240 | ldr pc,=\label 241 | .endm 242 | 243 | .macro bleq_long label 244 | moveq lr,pc 245 | ldreq pc,=\label 246 | .endm 247 | 248 | .macro bllo_long label 249 | movlo lr,pc 250 | ldrlo pc,=\label 251 | .endm 252 | 253 | .macro blhi_long label 254 | movhi lr,pc 255 | ldrhi pc,=\label 256 | .endm 257 | 258 | .macro bllt_long label 259 | movlt lr,pc 260 | ldrlt pc,=\label 261 | .endm 262 | 263 | .macro blgt_long label 264 | movgt lr,pc 265 | ldrgt pc,=\label 266 | .endm 267 | 268 | .macro blle_long label 269 | movle lr,pc 270 | ldrle pc,=\label 271 | .endm 272 | 273 | .macro blge_long label 274 | movge lr,pc 275 | ldrge pc,=\label 276 | .endm 277 | 278 | .macro blne_long label 279 | movne lr,pc 280 | ldrne pc,=\label 281 | .endm 282 | 283 | .macro blcc_long label 284 | movcc lr,pc 285 | ldrcc pc,=\label 286 | .endm 287 | 288 | .macro blpl_long label 289 | movpl lr,pc 290 | ldrpl pc,=\label 291 | .endm 292 | 293 | .macro blx_long label 294 | add lr,pc,#4 295 | ldr r12,=\label 296 | bx r12 297 | .endm 298 | 299 | .macro blxeq_long label 300 | addeq lr,pc,#4 301 | ldreq r12,=\label 302 | bxeq r12 303 | .endm 304 | 305 | .macro blxlo_long label 306 | addlo lr,pc,#4 307 | ldrlo r12,=\label 308 | bxlo r12 309 | .endm 310 | 311 | .macro blxhi_long label 312 | addhi lr,pc,#4 313 | ldrhi r12,=\label 314 | bxhi r12 315 | .endm 316 | 317 | .macro blxlt_long label 318 | addlt lr,pc,#4 319 | ldrlt r12,=\label 320 | bxlt r12 321 | .endm 322 | 323 | .macro blxgt_long label 324 | addgt lr,pc,#4 325 | ldrgt r12,=\label 326 | bxgt r12 327 | .endm 328 | 329 | .macro blxne_long label 330 | addne lr,pc,#4 331 | ldrne r12,=\label 332 | bxne r12 333 | .endm 334 | 335 | .macro blxcc_long label 336 | addcc lr,pc,#4 337 | ldrcc r12,=\label 338 | bxcc r12 339 | .endm 340 | 341 | .macro blxpl_long label 342 | addpl lr,pc,#4 343 | ldrpl r12,=\label 344 | bxpl r12 345 | .endm 346 | 347 | .macro blxmi_long label 348 | addmi lr,pc,#4 349 | ldrmi r12,=\label 350 | bxmi r12 351 | .endm 352 | 353 | .macro b_long label 354 | ldr pc,=\label 355 | .endm 356 | 357 | .macro bcc_long label 358 | ldrcc pc,=\label 359 | .endm 360 | 361 | .macro bhs_long label 362 | ldrhs pc,=\label 363 | .endm 364 | 365 | .macro beq_long label 366 | ldreq pc,=\label 367 | .endm 368 | 369 | .macro bne_long label 370 | ldrne pc,=\label 371 | .endm 372 | 373 | .macro blo_long label 374 | ldrlo pc,=\label 375 | .endm 376 | 377 | .macro bhi_long label 378 | ldrhi pc,=\label 379 | .endm 380 | 381 | .macro bgt_long label 382 | ldrgt pc,=\label 383 | .endm 384 | 385 | .macro blt_long label 386 | ldrlt pc,=\label 387 | .endm 388 | 389 | .macro bge_long label 390 | ldrge pc,=\label 391 | .endm 392 | 393 | .macro ble_long label 394 | ldrle pc,=\label 395 | .endm 396 | 397 | .macro bcs_long label 398 | ldrcs pc,=\label 399 | .endm 400 | 401 | .macro bmi_long label 402 | ldrmi pc,=\label 403 | .endm 404 | 405 | .macro bpl_long label 406 | ldrpl pc,=\label 407 | .endm 408 | 409 | .else 410 | 411 | .macro blx_long label 412 | add lr,pc,#4 413 | ldr r12,=\label 414 | bx r12 415 | .endm 416 | 417 | .macro blxeq_long label 418 | addeq lr,pc,#4 419 | ldreq r12,=\label 420 | bxeq r12 421 | .endm 422 | 423 | .macro blxlo_long label 424 | addlo lr,pc,#4 425 | ldrlo r12,=\label 426 | bxlo r12 427 | .endm 428 | 429 | .macro blxhi_long label 430 | addhi lr,pc,#4 431 | ldrhi r12,=\label 432 | bxhi r12 433 | .endm 434 | 435 | .macro blxlt_long label 436 | addlt lr,pc,#4 437 | ldrlt r12,=\label 438 | bxlt r12 439 | .endm 440 | 441 | .macro blxgt_long label 442 | addgt lr,pc,#4 443 | ldrgt r12,=\label 444 | bxgt r12 445 | .endm 446 | 447 | .macro blxne_long label 448 | addne lr,pc,#4 449 | ldrne r12,=\label 450 | bxne r12 451 | .endm 452 | 453 | .macro blxcc_long label 454 | addcc lr,pc,#4 455 | ldrcc r12,=\label 456 | bxcc r12 457 | .endm 458 | 459 | .macro blxpl_long label 460 | addpl lr,pc,#4 461 | ldrpl r12,=\label 462 | bxpl r12 463 | .endm 464 | 465 | .macro blxmi_long label 466 | addmi lr,pc,#4 467 | ldrmi r12,=\label 468 | bxmi r12 469 | .endm 470 | 471 | .macro bl_long label 472 | bl \label 473 | .endm 474 | 475 | .macro bleq_long label 476 | bleq \label 477 | .endm 478 | 479 | .macro bllo_long label 480 | bllo \label 481 | .endm 482 | 483 | .macro blhi_long label 484 | blhi \label 485 | .endm 486 | 487 | .macro bllt_long label 488 | bllt \label 489 | .endm 490 | 491 | .macro blgt_long label 492 | blgt \label 493 | .endm 494 | 495 | .macro blle_long label 496 | blle \label 497 | .endm 498 | 499 | .macro blge_long label 500 | blge \label 501 | .endm 502 | 503 | .macro blne_long label 504 | blne \label 505 | .endm 506 | 507 | .macro blcc_long label 508 | blcc \label 509 | .endm 510 | 511 | .macro blpl_long label 512 | blpl \label 513 | .endm 514 | 515 | .macro b_long label 516 | b \label 517 | .endm 518 | 519 | .macro bcc_long label 520 | bcc \label 521 | .endm 522 | 523 | .macro bhs_long label 524 | bhs \label 525 | .endm 526 | 527 | .macro beq_long label 528 | beq \label 529 | .endm 530 | 531 | .macro bne_long label 532 | bne \label 533 | .endm 534 | 535 | .macro blo_long label 536 | blo \label 537 | .endm 538 | 539 | .macro bhi_long label 540 | bhi \label 541 | .endm 542 | 543 | .macro bgt_long label 544 | bgt \label 545 | .endm 546 | 547 | .macro blt_long label 548 | blt \label 549 | .endm 550 | 551 | .macro bge_long label 552 | bge \label 553 | .endm 554 | 555 | .macro ble_long label 556 | ble \label 557 | .endm 558 | 559 | .macro bcs_long label 560 | bcs \label 561 | .endm 562 | 563 | .macro bmi_long label 564 | bmi \label 565 | .endm 566 | 567 | .macro bpl_long label 568 | bpl \label 569 | .endm 570 | .endif 571 | 572 | @.end 573 | 574 | -------------------------------------------------------------------------------- /src/gba_cart_my.ld: -------------------------------------------------------------------------------- 1 | /* Customized Link script based on DevkitArm's linkscript 2 | Features: 3 | * vram1 section to stick code into VRAM 4 | * bss_prefix section - put zero-initialized data in IWRAM before anything else 5 | * bss sections come after data sections 6 | * supports named sections to appear in a specific order (.data.1, .data.2, etc) 7 | */ 8 | 9 | 10 | /* Linker Script Original v1.3 by Jeff Frohwein */ 11 | /* v1.0 - Original release */ 12 | /* v1.1 - Added proper .data section support */ 13 | /* v1.2 - Added support for c++ & iwram overlays */ 14 | /* - Major contributions by Jason Wilkins. */ 15 | /* v1.3 - .ewram section now can be used when */ 16 | /* compiling for MULTIBOOT mode. This fixes */ 17 | /* malloc() in DevKitAdvance which depends */ 18 | /* on __eheap_start instead of end to define*/ 19 | /* the starting location of heap space. */ 20 | /* External global variable __gba_iwram_heap*/ 21 | /* support added to allow labels end, _end, */ 22 | /* & __end__ to point to end of iwram or */ 23 | /* the end of ewram. */ 24 | /* Additions by WinterMute */ 25 | /* v1.4 - .sbss section added for unitialised */ 26 | /* data in ewram */ 27 | /* v1.5 - padding section added to stop EZF */ 28 | /* stripping important data */ 29 | 30 | /* This file is released into the public domain */ 31 | /* for commercial or non-commercial use with no */ 32 | /* restrictions placed upon it. */ 33 | 34 | /* NOTE!!!: This linker script defines the RAM & */ 35 | /* ROM start addresses. In order for it to work */ 36 | /* properly, remove -Ttext and -Tbss linker */ 37 | /* options from your makefile if they are */ 38 | /* present. */ 39 | 40 | /* You can use the following to view section */ 41 | /* addresses in your .elf file: */ 42 | /* objdump -h file.elf */ 43 | /* Please note that empty sections may incorrectly*/ 44 | /* list the lma address as the vma address for */ 45 | /* some versions of objdump. */ 46 | 47 | OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") 48 | OUTPUT_ARCH(arm) 49 | ENTRY(_start) 50 | /* SEARCH_DIR(/bin/arm); */ 51 | 52 | /* The linker script function "var1 += var2;" sometimes */ 53 | /* reports incorrect values in the *.map file but the */ 54 | /* actual value it calculates is usually, if not always, */ 55 | /* correct. If you leave out the ". = ALIGN(4);" at the */ 56 | /* end of each section then the return value of SIZEOF() */ 57 | /* is sometimes incorrect and "var1 += var2;" appears to */ 58 | /* not work as well. "var1 += var2" style functions are */ 59 | /* avoided below as a result. */ 60 | 61 | MEMORY { 62 | 63 | rom : ORIGIN = 0x08000000, LENGTH = 32M 64 | iwram : ORIGIN = 0x03000000, LENGTH = 32K 65 | ewram : ORIGIN = 0x02000000, LENGTH = 256K 66 | vram1 : ORIGIN = 0x0600F000, LENGTH = 3584 67 | } 68 | 69 | 70 | 71 | __text_start = ORIGIN(rom); 72 | __eheap_end = ORIGIN(ewram) + LENGTH(ewram); 73 | __iwram_start = ORIGIN(iwram); 74 | __iwram_top = ORIGIN(iwram) + LENGTH(iwram);; 75 | //__sp_irq = __iwram_top - 0x060; 76 | //__sp_usr = __sp_irq - 0x0a0; 77 | __sp_irq = __iwram_top - 0x060; 78 | __sp_usr = __sp_irq - 0x060; 79 | __irq_flags = 0x03007ff8; 80 | 81 | SECTIONS 82 | { 83 | . = __text_start; 84 | .init : 85 | { 86 | KEEP (*(.init)) 87 | . = ALIGN(4); 88 | } >rom =0xff 89 | 90 | .plt : 91 | { 92 | *(.plt) 93 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 94 | } >rom 95 | 96 | .text : /* ALIGN (4): */ 97 | { 98 | *(EXCLUDE_FILE (*.iwram*) .text) 99 | *(.text .stub SORT_BY_NAME(.text.*) .gnu.linkonce.t.*) 100 | KEEP (*(.text.*personality*)) 101 | /* .gnu.warning sections are handled specially by elf32.em. */ 102 | *(.gnu.warning) 103 | *(.glue_7t) *(.glue_7) *(.vfp11_veneer) 104 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 105 | } >rom = 0xff 106 | 107 | __text_end = .; 108 | .fini : 109 | { 110 | KEEP (*(.fini)) 111 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 112 | } >rom =0 113 | 114 | .rodata : 115 | { 116 | *(.rodata) 117 | *all.rodata*(*) 118 | *(.roda) 119 | *(.rodata.*) 120 | *(.gnu.linkonce.r*) 121 | SORT(CONSTRUCTORS) 122 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 123 | } >rom = 0xff 124 | .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >rom 125 | __exidx_start = .; 126 | .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >rom 127 | __exidx_end = .; 128 | 129 | .ctors : 130 | { 131 | /* gcc uses crtbegin.o to find the start of the constructors, so 132 | we make sure it is first. Because this is a wildcard, it 133 | doesn't matter if the user does not actually link against 134 | crtbegin.o; the linker won't look for a file to match a 135 | wildcard. The wildcard also means that it doesn't matter which 136 | directory crtbegin.o is in. */ 137 | KEEP (*crtbegin.o(.ctors)) 138 | KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) 139 | KEEP (*(SORT(.ctors.*))) 140 | KEEP (*(.ctors)) 141 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 142 | } >rom = 0 143 | 144 | .dtors : 145 | { 146 | KEEP (*crtbegin.o(.dtors)) 147 | KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) 148 | KEEP (*(SORT(.dtors.*))) 149 | KEEP (*(.dtors)) 150 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 151 | } >rom = 0 152 | 153 | 154 | .eh_frame : 155 | { 156 | KEEP (*(.eh_frame)) 157 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 158 | } >rom = 0 159 | 160 | .gcc_except_table : 161 | { 162 | *(.gcc_except_table) 163 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 164 | } >rom = 0 165 | 166 | __iwram_lma = .; 167 | 168 | .bss_prefix __iwram_start (NOLOAD) : 169 | { 170 | __bss_prefix_start__ = ABSOLUTE(.); 171 | *(.bss_prefix) 172 | *(SORT_BY_NAME(.bss_prefix.*)) 173 | *(.bss_prefix*) 174 | . = ALIGN(4); 175 | __bss_prefix_end__ = ABSOLUTE(.); 176 | } >iwram 177 | 178 | .iwram ALIGN(4) : AT (__iwram_lma) 179 | { 180 | __iwram_start__ = ABSOLUTE(.) ; 181 | *(.iwram) 182 | *iwram.*(.text) 183 | *(SORT_BY_NAME(.iwram.*)) 184 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 185 | __iwram_end__ = ABSOLUTE(.) ; 186 | } >iwram = 0xff 187 | 188 | __data_lma = __iwram_lma + SIZEOF(.iwram) ; 189 | 190 | .data ALIGN(4) : AT (__data_lma) 191 | { 192 | __data_start__ = ABSOLUTE(.); 193 | *(.data) 194 | *(SORT_BY_NAME(.data.*)) 195 | *(.gnu.linkonce.d*) 196 | CONSTRUCTORS 197 | . = ALIGN(4); 198 | } >iwram = 0xff 199 | 200 | __preinit_lma = __data_lma + SIZEOF(.data); 201 | 202 | .preinit_array ALIGN(4) : AT (__preinit_lma) 203 | { 204 | __preinit_array_start = ABSOLUTE(.); 205 | KEEP (*(.preinit_array)) 206 | __preinit_array_end = ABSOLUTE(.); 207 | } >iwram 208 | 209 | __init_lma = __preinit_lma + SIZEOF(.preinit_array); 210 | 211 | .init_array ALIGN(4) : AT (__init_lma) 212 | { 213 | __init_array_start = ABSOLUTE(.); 214 | KEEP (*(SORT(.init_array.*))) 215 | KEEP (*(.init_array)) 216 | __init_array_end = ABSOLUTE(.); 217 | } >iwram 218 | 219 | __fini_lma = __init_lma + SIZEOF(.init_array); 220 | 221 | .fini_array ALIGN(4) : AT (__fini_lma) 222 | { 223 | __fini_array_start = ABSOLUTE(.); 224 | KEEP (*(SORT(.fini_array.*))) 225 | KEEP (*(.fini_array)) 226 | __fini_array_end = ABSOLUTE(.); 227 | } >iwram 228 | 229 | __jcr_lma = __fini_lma + SIZEOF(.fini_array); 230 | .jcr ALIGN(4) : AT (__jcr_lma) { KEEP (*(.jcr)) } >iwram 231 | 232 | __data_end__ = ABSOLUTE(.); 233 | 234 | .bss ALIGN(4) (NOLOAD) : 235 | { 236 | __bss_start = ABSOLUTE(.); 237 | __bss_start__ = ABSOLUTE(.); 238 | *(.dynbss) 239 | *(.gnu.linkonce.b*) 240 | *(.bss) 241 | *(COMMON) 242 | *(SORT_BY_NAME(.bss.*)) 243 | *(.bss*) 244 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 245 | __bss_end__ = ABSOLUTE(.); 246 | 247 | } AT>iwram 248 | 249 | __iwram_overlay_lma = __jcr_lma + SIZEOF(.jcr); 250 | 251 | __iwram_overlay_start = . ; 252 | 253 | OVERLAY ALIGN(4) : NOCROSSREFS AT (__iwram_overlay_lma) 254 | { 255 | .iwram0 { *(.iwram0) . = ALIGN(4);} 256 | .iwram1 { *(.iwram1) . = ALIGN(4);} 257 | .iwram2 { *(.iwram2) . = ALIGN(4);} 258 | .iwram3 { *(.iwram3) . = ALIGN(4);} 259 | .iwram4 { *(.iwram4) . = ALIGN(4);} 260 | .iwram5 { *(.iwram5) . = ALIGN(4);} 261 | .iwram6 { *(.iwram6) . = ALIGN(4);} 262 | .iwram7 { *(.iwram7) . = ALIGN(4);} 263 | .iwram8 { *(.iwram8) . = ALIGN(4);} 264 | .iwram9 { *(.iwram9) . = ALIGN(4);} 265 | }>iwram = 0xff 266 | 267 | __iwram_overlay_end = . ; 268 | __ewram_lma = __iwram_overlay_lma + (__iwram_overlay_end - __iwram_overlay_start) ; 269 | 270 | __iheap_start = . ; 271 | 272 | __ewram_start = ORIGIN(ewram); 273 | .ewram __ewram_start : AT (__ewram_lma) 274 | { 275 | *(.ewram) 276 | *(SORT_BY_NAME(.ewram.*)) 277 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 278 | __ewram_end = ABSOLUTE(.); 279 | }>ewram = 0xff 280 | 281 | .sbss ALIGN(4)(NOLOAD): 282 | { 283 | __sbss_start__ = ABSOLUTE(.); 284 | *(.sbss) 285 | *(SORT_BY_NAME(.sbss.*)) 286 | . = ALIGN(4); 287 | __sbss_end__ = ABSOLUTE(.); 288 | __end__ = ABSOLUTE(.); 289 | __eheap_start = ABSOLUTE(.); 290 | } AT>ewram 291 | 292 | /* new section: .vram1 */ 293 | __vram1_lma = __ewram_lma + SIZEOF(.ewram); 294 | 295 | __vram1_start = ORIGIN(vram1); 296 | .vram1 __vram1_start : AT (__vram1_lma) 297 | { 298 | *(.vram1) 299 | *(SORT_BY_NAME(.vram1.*)) 300 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 301 | __vram1_end = ABSOLUTE(.); 302 | __vram1_end__ = ABSOLUTE(.); 303 | }>vram1 = 0xff 304 | 305 | __pad_lma = __vram1_lma + SIZEOF(.vram1); 306 | 307 | /* old line: __pad_lma = __ewram_lma + SIZEOF(.ewram); */ 308 | 309 | /* EZF Advance strips trailing 0xff bytes, add a pad section so nothing important is removed */ 310 | .pad ALIGN(4) : AT (__pad_lma) 311 | { 312 | LONG(0x52416b64) 313 | LONG(0x4d) 314 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 315 | } = 0xff 316 | __rom_end__ = __pad_lma + SIZEOF(.pad); 317 | 318 | 319 | /* Stabs debugging sections. */ 320 | .stab 0 : { *(.stab) } 321 | .stabstr 0 : { *(.stabstr) } 322 | .stab.excl 0 : { *(.stab.excl) } 323 | .stab.exclstr 0 : { *(.stab.exclstr) } 324 | .stab.index 0 : { *(.stab.index) } 325 | .stab.indexstr 0 : { *(.stab.indexstr) } 326 | .comment 0 : { *(.comment) } 327 | /* DWARF debug sections. 328 | Symbols in the DWARF debugging sections are relative to the beginning 329 | of the section so we begin them at 0. */ 330 | /* DWARF 1 */ 331 | .debug 0 : { *(.debug) } 332 | .line 0 : { *(.line) } 333 | /* GNU DWARF 1 extensions */ 334 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 335 | .debug_sfnames 0 : { *(.debug_sfnames) } 336 | /* DWARF 1.1 and DWARF 2 */ 337 | .debug_aranges 0 : { *(.debug_aranges) } 338 | .debug_pubnames 0 : { *(.debug_pubnames) } 339 | /* DWARF 2 */ 340 | .debug_info 0 : { *(.debug_info) } 341 | .debug_abbrev 0 : { *(.debug_abbrev) } 342 | .debug_line 0 : { *(.debug_line) } 343 | .debug_frame 0 : { *(.debug_frame) } 344 | .debug_str 0 : { *(.debug_str) } 345 | .debug_loc 0 : { *(.debug_loc) } 346 | .debug_macinfo 0 : { *(.debug_macinfo) } 347 | /* SGI/MIPS DWARF 2 extensions */ 348 | .debug_weaknames 0 : { *(.debug_weaknames) } 349 | .debug_funcnames 0 : { *(.debug_funcnames) } 350 | .debug_typenames 0 : { *(.debug_typenames) } 351 | .debug_varnames 0 : { *(.debug_varnames) } 352 | .stack 0x80000 : { _stack = .; *(.stack) } 353 | /* These must appear regardless of . */ 354 | .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) } 355 | .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) } 356 | /DISCARD/ : { *(.note.GNU-stack) } 357 | } 358 | -------------------------------------------------------------------------------- /src/gba_mb_my.ld: -------------------------------------------------------------------------------- 1 | /* Customized Link script based on DevkitArm's linkscript 2 | Features: 3 | * vram1 section to stick code into VRAM 4 | * bss_prefix section - put zero-initialized data in IWRAM before anything else 5 | * bss sections come after data sections 6 | * supports named sections to appear in a specific order (.data.1, .data.2, etc) 7 | * removed EWRAM overlays, heap now appears immediately after the end of the 8 | SBSS section, to make more memory available to the program 9 | */ 10 | 11 | /* Linker Script Original v1.3 by Jeff Frohwein */ 12 | /* v1.0 - Original release */ 13 | /* v1.1 - Added proper .data section support */ 14 | /* v1.2 - Added support for c++ & iwram overlays */ 15 | /* - Major contributions by Jason Wilkins. */ 16 | /* v1.3 - .ewram section now can be used when */ 17 | /* compiling for MULTIBOOT mode. This fixes */ 18 | /* malloc() in DevKitAdvance which depends */ 19 | /* on __eheap_start instead of end to define*/ 20 | /* the starting location of heap space. */ 21 | /* External global variable __gba_iwram_heap*/ 22 | /* support added to allow labels end, _end, */ 23 | /* & __end__ to point to end of iwram or */ 24 | /* the end of ewram. */ 25 | /* Additions by WinterMute */ 26 | /* v1.4 - .sbss section added for unitialised */ 27 | /* data in ewram */ 28 | /* v1.5 - padding section added to stop EZF */ 29 | /* stripping important data */ 30 | /* v1.6 - added memory sections */ 31 | 32 | /* This file is released into the public domain */ 33 | /* for commercial or non-commercial use with no */ 34 | /* restrictions placed upon it. */ 35 | 36 | /* NOTE!!!: This linker script defines the RAM & */ 37 | /* ROM start addresses. In order for it to work */ 38 | /* properly, remove -Ttext and -Tbss linker */ 39 | /* options from your makefile if they are */ 40 | /* present. */ 41 | 42 | /* You can use the following to view section */ 43 | /* addresses in your .elf file: */ 44 | /* objdump -h file.elf */ 45 | /* Please note that empty sections may incorrectly*/ 46 | /* list the lma address as the vma address for */ 47 | /* some versions of objdump. */ 48 | 49 | OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") 50 | OUTPUT_ARCH(arm) 51 | ENTRY(_start) 52 | 53 | MEMORY { 54 | 55 | rom : ORIGIN = 0x08000000, LENGTH = 32M 56 | iwram : ORIGIN = 0x03000000, LENGTH = 32K 57 | ewram : ORIGIN = 0x02000000, LENGTH = 256K 58 | vram1 : ORIGIN = 0x0600F000, LENGTH = 3584 59 | } 60 | 61 | 62 | 63 | __text_start = ORIGIN(ewram); 64 | __eheap_end = ORIGIN(ewram) + LENGTH(ewram); 65 | __iwram_start = ORIGIN(iwram); 66 | __iwram_top = ORIGIN(iwram) + LENGTH(iwram);; 67 | //__sp_irq = __iwram_top - 0x060; 68 | //__sp_usr = __sp_irq - 0x0a0; 69 | __sp_irq = __iwram_top - 0x060; 70 | __sp_usr = __sp_irq - 0x060; 71 | __irq_flags = 0x03007ff8; 72 | 73 | SECTIONS 74 | { 75 | . = __text_start; 76 | .init : 77 | { 78 | KEEP (*(.init)) 79 | . = ALIGN(4); 80 | } >ewram =0xff 81 | 82 | .plt : 83 | { 84 | *(.plt) 85 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 86 | } >ewram 87 | 88 | .text ALIGN (4): 89 | { 90 | *(EXCLUDE_FILE (*.iwram*) .text) 91 | *(.text .stub SORT_BY_NAME(.text.*) .gnu.linkonce.t.*) 92 | KEEP (*(.text.*personality*)) 93 | /* .gnu.warning sections are handled specially by elf32.em. */ 94 | *(.gnu.warning) 95 | *(.glue_7t) *(.glue_7) *(.vfp11_veneer) 96 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 97 | } >ewram = 0xff 98 | 99 | __text_end = .; 100 | .fini : 101 | { 102 | KEEP (*(.fini)) 103 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 104 | } >ewram =0 105 | 106 | .rodata : 107 | { 108 | *(.rodata) 109 | *all.rodata*(*) 110 | *(.roda) 111 | *(.rodata.*) 112 | *(.gnu.linkonce.r*) 113 | SORT(CONSTRUCTORS) 114 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 115 | } >ewram = 0xff 116 | 117 | .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram 118 | __exidx_start = .; 119 | .ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram 120 | __exidx_end = .; 121 | /* Ensure the __preinit_array_start label is properly aligned. We 122 | could instead move the label definition inside the section, but 123 | the linker would then create the section even if it turns out to 124 | be empty, which isn't pretty. */ 125 | . = ALIGN(32 / 8); 126 | PROVIDE (__preinit_array_start = .); 127 | .preinit_array : { KEEP (*(.preinit_array)) } >ewram = 0xff 128 | PROVIDE (__preinit_array_end = .); 129 | PROVIDE (__init_array_start = .); 130 | .init_array : { KEEP (*(.init_array)) } >ewram = 0xff 131 | PROVIDE (__init_array_end = .); 132 | PROVIDE (__fini_array_start = .); 133 | .fini_array : { KEEP (*(.fini_array)) } >ewram = 0xff 134 | PROVIDE (__fini_array_end = .); 135 | .ctors : 136 | { 137 | /* gcc uses crtbegin.o to find the start of the constructors, so 138 | we make sure it is first. Because this is a wildcard, it 139 | doesn't matter if the user does not actually link against 140 | crtbegin.o; the linker won't look for a file to match a 141 | wildcard. The wildcard also means that it doesn't matter which 142 | directory crtbegin.o is in. */ 143 | KEEP (*crtbegin.o(.ctors)) 144 | KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) 145 | KEEP (*(SORT(.ctors.*))) 146 | KEEP (*(.ctors)) 147 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 148 | } >ewram = 0 149 | 150 | .dtors : 151 | { 152 | KEEP (*crtbegin.o(.dtors)) 153 | KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) 154 | KEEP (*(SORT(.dtors.*))) 155 | KEEP (*(.dtors)) 156 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 157 | } >ewram = 0 158 | 159 | .jcr : { KEEP (*(.jcr)) } >ewram 160 | .eh_frame : 161 | { 162 | KEEP (*(.eh_frame)) 163 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 164 | } >ewram = 0 165 | 166 | .gcc_except_table : 167 | { 168 | *(.gcc_except_table) 169 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 170 | } >ewram = 0 171 | 172 | 173 | __ewram_lma = .; 174 | 175 | /* v1.3 */ 176 | __ewram_start = __ewram_lma ; 177 | 178 | .ewram __ewram_start : AT (__ewram_lma) 179 | { 180 | *(.ewram) 181 | *(SORT_BY_NAME(.ewram.*)) 182 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 183 | __ewram_end = ABSOLUTE(.); 184 | }>ewram = 0xff 185 | 186 | .sbss ALIGN(4)(NOLOAD): 187 | { 188 | __sbss_start__ = ABSOLUTE(.); 189 | *(.sbss) 190 | *(SORT_BY_NAME(.sbss.*)) 191 | . = ALIGN(4); 192 | __sbss_end__ = ABSOLUTE(.); 193 | __end__ = ABSOLUTE(.); 194 | __eheap_start = ABSOLUTE(.); 195 | } 196 | 197 | /* __ewram_overlay_lma = __ewram_lma + SIZEOF(.ewram); */ 198 | 199 | /* 200 | OVERLAY ALIGN(4): NOCROSSREFS AT (__ewram_overlay_lma) 201 | { 202 | .ewram0 { *(.ewram0) . = ALIGN(4);} 203 | .ewram1 { *(.ewram1) . = ALIGN(4);} 204 | .ewram2 { *(.ewram2) . = ALIGN(4);} 205 | .ewram3 { *(.ewram3) . = ALIGN(4);} 206 | .ewram4 { *(.ewram4) . = ALIGN(4);} 207 | .ewram5 { *(.ewram5) . = ALIGN(4);} 208 | .ewram6 { *(.ewram6) . = ALIGN(4);} 209 | .ewram7 { *(.ewram7) . = ALIGN(4);} 210 | .ewram8 { *(.ewram8) . = ALIGN(4);} 211 | .ewram9 { *(.ewram9) . = ALIGN(4);} 212 | } >ewram = 0xff 213 | __ewram_overlay_end = ABSOLUTE(.); 214 | */ 215 | __iwram_lma = __ewram_lma + SIZEOF(.ewram) ; 216 | 217 | .bss_prefix __iwram_start (NOLOAD) : 218 | { 219 | __bss_prefix_start__ = ABSOLUTE(.); 220 | *(.bss_prefix) 221 | *(SORT_BY_NAME(.bss_prefix.*)) 222 | *(.bss_prefix*) 223 | . = ALIGN(4); 224 | __bss_prefix_end__ = ABSOLUTE(.); 225 | } >iwram 226 | 227 | .iwram ALIGN(4) : AT (__iwram_lma) 228 | { 229 | __iwram_start__ = ABSOLUTE(.) ; 230 | *(.iwram) 231 | *iwram.*(.text) 232 | *(SORT_BY_NAME(.iwram.*)) 233 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 234 | __iwram_end__ = ABSOLUTE(.) ; 235 | } >iwram = 0xff 236 | 237 | __data_lma = __iwram_lma + SIZEOF(.iwram) ; 238 | 239 | .data ALIGN(4) : AT (__data_lma) 240 | { 241 | __data_start__ = ABSOLUTE(.); 242 | *(.data) 243 | *(SORT_BY_NAME(.data.*)) 244 | *(.gnu.linkonce.d*) 245 | CONSTRUCTORS 246 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 247 | __data_end__ = ABSOLUTE(.); 248 | } >iwram = 0xff 249 | 250 | .bss ALIGN(4) (NOLOAD) : 251 | { 252 | __bss_start__ = ABSOLUTE(.); 253 | *(.dynbss) 254 | *(.gnu.linkonce.b*) 255 | *(.bss) 256 | *(COMMON) 257 | *(SORT_BY_NAME(.bss.*)) 258 | *(.bss*) 259 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 260 | __bss_end__ = ABSOLUTE(.); 261 | } 262 | 263 | __iwram_overlay_lma = __data_lma + SIZEOF(.data); 264 | 265 | PROVIDE (edata = .); 266 | __iwram_overlay_start = . ; 267 | 268 | OVERLAY ALIGN(4) : NOCROSSREFS AT (__iwram_overlay_lma) 269 | { 270 | .iwram0 { *(.iwram0) . = ALIGN(4);} 271 | .iwram1 { *(.iwram1) . = ALIGN(4);} 272 | .iwram2 { *(.iwram2) . = ALIGN(4);} 273 | .iwram3 { *(.iwram3) . = ALIGN(4);} 274 | .iwram4 { *(.iwram4) . = ALIGN(4);} 275 | .iwram5 { *(.iwram5) . = ALIGN(4);} 276 | .iwram6 { *(.iwram6) . = ALIGN(4);} 277 | .iwram7 { *(.iwram7) . = ALIGN(4);} 278 | .iwram8 { *(.iwram8) . = ALIGN(4);} 279 | .iwram9 { *(.iwram9) . = ALIGN(4);} 280 | }>iwram = 0xff 281 | 282 | /* __ewram_lma = LOADADDR(.iwram0) + SIZEOF(.iwram0)+SIZEOF(.iwram1)+SIZEOF(.iwram2)+SIZEOF(.iwram3)+SIZEOF(.iwram4)+SIZEOF(.iwram5)+SIZEOF(.iwram6)+SIZEOF(.iwram7)+SIZEOF(.iwram8)+SIZEOF(.iwram9); */ 283 | 284 | __iwram_overlay_end = LOADADDR(.iwram0) + SIZEOF(.iwram0)+SIZEOF(.iwram1)+SIZEOF(.iwram2)+SIZEOF(.iwram3)+SIZEOF(.iwram4)+SIZEOF(.iwram5)+SIZEOF(.iwram6)+SIZEOF(.iwram7)+SIZEOF(.iwram8)+SIZEOF(.iwram9); 285 | 286 | 287 | 288 | /* new section: .vram1 */ 289 | __vram1_lma = __iwram_overlay_end; 290 | 291 | __vram1_start = ORIGIN(vram1); 292 | .vram1 __vram1_start : AT (__vram1_lma) 293 | { 294 | *(.vram1) 295 | *(SORT_BY_NAME(.vram1.*)) 296 | . = ALIGN(4); /* REQUIRED. LD is flaky without it. */ 297 | __vram1_end = ABSOLUTE(.); 298 | __vram1_end__ = ABSOLUTE(.); 299 | }>vram1 = 0xff 300 | 301 | __append_lma = __vram1_lma + SIZEOF(.vram1); 302 | __append_start = __append_lma; 303 | .append __append_start : AT (__append_lma) 304 | { 305 | *(SORT_BY_NAME(.append*)) 306 | . = ALIGN(4); 307 | __append_end = ABSOLUTE(.); 308 | } 309 | 310 | 311 | /* __eheap_start = __iwram_overlay_end ; */ 312 | 313 | /*_end = __vram1_lma + SIZEOF(.vram1);*/ 314 | _end = __append_lma + SIZEOF(.append); 315 | __end__ = _end; 316 | __rom_end__ = __end__; 317 | 318 | /* 319 | _end = __iwram_overlay_end; 320 | __end__ = __iwram_overlay_end; 321 | __rom_end__ = __iwram_overlay_end; 322 | */ 323 | 324 | /* Stabs debugging sections. */ 325 | .stab 0 : { *(.stab) } 326 | .stabstr 0 : { *(.stabstr) } 327 | .stab.excl 0 : { *(.stab.excl) } 328 | .stab.exclstr 0 : { *(.stab.exclstr) } 329 | .stab.index 0 : { *(.stab.index) } 330 | .stab.indexstr 0 : { *(.stab.indexstr) } 331 | .comment 0 : { *(.comment) } 332 | /* DWARF debug sections. 333 | Symbols in the DWARF debugging sections are relative to the beginning 334 | of the section so we begin them at 0. */ 335 | /* DWARF 1 */ 336 | .debug 0 : { *(.debug) } 337 | .line 0 : { *(.line) } 338 | /* GNU DWARF 1 extensions */ 339 | .debug_srcinfo 0 : { *(.debug_srcinfo) } 340 | .debug_sfnames 0 : { *(.debug_sfnames) } 341 | /* DWARF 1.1 and DWARF 2 */ 342 | .debug_aranges 0 : { *(.debug_aranges) } 343 | .debug_pubnames 0 : { *(.debug_pubnames) } 344 | /* DWARF 2 */ 345 | .debug_info 0 : { *(.debug_info) } 346 | .debug_abbrev 0 : { *(.debug_abbrev) } 347 | .debug_line 0 : { *(.debug_line) } 348 | .debug_frame 0 : { *(.debug_frame) } 349 | .debug_str 0 : { *(.debug_str) } 350 | .debug_loc 0 : { *(.debug_loc) } 351 | .debug_macinfo 0 : { *(.debug_macinfo) } 352 | /* SGI/MIPS DWARF 2 extensions */ 353 | .debug_weaknames 0 : { *(.debug_weaknames) } 354 | .debug_funcnames 0 : { *(.debug_funcnames) } 355 | .debug_typenames 0 : { *(.debug_typenames) } 356 | .debug_varnames 0 : { *(.debug_varnames) } 357 | .stack 0x80000 : { _stack = .; *(.stack) } 358 | /* These must appear regardless of . */ 359 | } 360 | -------------------------------------------------------------------------------- /src/timeout.s: -------------------------------------------------------------------------------- 1 | .section .vram1, "ax", %progbits 2 | @---------------------------------------------------------------------------- 3 | @cycles ran out 4 | @---------------------------------------------------------------------------- 5 | line0: 6 | adr_ r2,cpuregs 7 | stmia r2,{gb_flg-gb_pc,gb_sp} @save gbz80 state 8 | 9 | ldrb_ r0,autoborderstate 10 | cmp r0,#1 11 | bne 0f 12 | ldr_ r0,frame 13 | ldr_ r1,auto_border_reboot_frame 14 | cmp r0,r1 15 | blt 0f 16 | bl_long loadcart_after_sgb_border 17 | 0: 18 | 19 | 20 | 21 | @waitformulti 22 | ldr r1,=REG_P1 @refresh input every frame 23 | ldrh r0,[r1] 24 | eor r0,r0,#0xff 25 | eor r0,r0,#0x300 @r0=button state (raw) 26 | ldr_ r1,AGBjoypad 27 | eor r1,r1,r0 28 | and r1,r1,r0 @r1=button state (0->1) 29 | str_ r0,AGBjoypad 30 | 31 | ldrb_ r2,dontstop_ 32 | cmp r2,#0 33 | ldmeqfd sp!,{gb_flg-gb_pc,globalptr,r11,lr} @exit here if doing single frame: 34 | bxeq lr @return to rommenu() 35 | 36 | @----anything from here til line0x won't get executed while rom menu is active--- 37 | 38 | @ mov r2,#REG_BASE 39 | @ mov r3,#0x0110 ;was 0x0310 40 | @ strh r3,[r2,#REG_BLDMOD] ;stop darkened screen,OBJ blend to BG0/1 41 | @ mov r3,#0x1000 ;BG0/1=16, OBJ=0 42 | @ strh r3,[r2,#REG_BLDALPHA] ;Alpha values 43 | 44 | adr lr,line0x @return here after doing L/R + SEL/START 45 | 46 | tst r1,#0x300 @if L or R was pressed 47 | tstne r0,#0x100 48 | tstne r0,#0x200 @and both L+R are held.. 49 | ldrne r1,=ui 50 | bxne r1 @do menu 51 | 52 | 53 | ands r3,r0,#0x300 @if either L or R is pressed (not both) 54 | eornes r3,r3,#0x300 55 | bicne r0,r0,#0x0c @ hide sel,start from NES 56 | str_ r0,XGBjoypad 57 | beq line0x @skip ahead if neither or both are pressed 58 | 59 | @ tst r0,#0x200 60 | @ tstne r1,#4 ;L+SEL for BG adjust 61 | @ ldrne r2,adjustblend 62 | @ addne r2,r2,#1 63 | @ strne r2,adjustblend 64 | 65 | tst r0,#0x200 @L? 66 | tstne r1,#8 @START? 67 | ldrb_ r2,novblankwait_ @0=Normal, 1=No wait, 2=Slomo 68 | addne r2,r2,#1 69 | cmp r2,#3 70 | moveq r2,#0 71 | strb_ r2,novblankwait_ 72 | 73 | tst r0,#0x100 @R? 74 | tstne r1,#8 @START: 75 | ldrne r1,=quickload 76 | bxne r1 77 | 78 | tst r0,#0x100 @R? 79 | tstne r1,#4 @SELECT: 80 | ldrne r1,=quicksave 81 | bxne r1 82 | line0x: 83 | bl_long refreshNESjoypads @Z=1 if communication ok 84 | 85 | #if JOYSTICK_READ_HACKS 86 | @joystick speed hacks 87 | mov r1,#-64 88 | strb_ r1,joy_read_count 89 | #endif 90 | 91 | @ bne waitformulti ;waiting on other GBA.. 92 | 93 | ldr_ r0,AGBjoypad 94 | ldr_ r2,fiveminutes_ @sleep after 5/10/30 minutes of inactivity 95 | cmp r0,#0 @(left out of the loop so waiting on multi-link 96 | ldrne_ r2,sleeptime_ @doesn't accelerate time) 97 | subs r2,r2,#1 98 | str_ r2,fiveminutes_ 99 | bleq_long suspend 100 | 101 | mov r1,#0 102 | strb_ r1,scanline @reset scanline count 103 | @ bl newframe @display update 104 | 105 | @now do double speed vblank stuff: 106 | ldr_ r0,doubletimer_ 107 | tst r0,#0x01 108 | blne_long updatespeed 109 | 110 | adr_ r0,cpuregs 111 | ldmia r0,{gb_flg-gb_pc,gb_sp} @restore GB-Z80 state 112 | 113 | @ ldrb r1,lcdctrl ;not liked by SML. 114 | @ tst r1,#0x80 115 | ldr r1,=lcdstat 116 | ldrb r0,[r1] @ 117 | and r2,r0,#0x7C @reset lcd mode flags (vblank/hblank/oam/lcd) 118 | cmp r0,r2 119 | strneb r2,[r1] @ 120 | strneb r2,[r1,#-12] @FIXME 121 | 122 | ldr_ r0,cyclesperscanline 123 | add cycles,cycles,r0 124 | 125 | ldr r0,=line1_to_71 126 | str_ r0,nexttimeout 127 | 128 | adrl_ r1,FF41_R_function 129 | ldr r0,[r1] 130 | @ ldr r0,=FF41_R 131 | ldr r1,=FF41_R_ptr 132 | str r0,[r1] 133 | 134 | ldr_ pc,scanlinehook 135 | 136 | .section .iwram.3, "ax", %progbits 137 | 138 | line1_to_71: @------------------------ 139 | ldr_ r0,cyclesperscanline 140 | add cycles,cycles,r0 141 | 142 | ldrb_ r1,scanline 143 | add r1,r1,#1 144 | strb_ r1,scanline 145 | cmp r1,#75 @was 71 146 | ldrmi_ pc,scanlinehook 147 | @--------------------------------------------- between 71 and 72 148 | 149 | ldrb_ r0,lcdctrl 150 | strb_ r0,lcdctrl0midframe @Chase HQ likes this 151 | 152 | ldrb_ r0,sgb_mask 153 | movs r0,r0 154 | bleq_long copy_gbc_palette 155 | 156 | @@@ 157 | @@@bl gbc_chr_update 158 | @@@ 159 | 160 | adr addy,line72_to_143 161 | str_ addy,nexttimeout 162 | ldr_ pc,scanlinehook 163 | line72_to_143: @------------------------ 164 | ldr_ r0,cyclesperscanline 165 | add cycles,cycles,r0 166 | 167 | ldrb_ r1,scanline 168 | add r1,r1,#1 169 | strb_ r1,scanline 170 | cmp r1,#143 171 | ldrmi_ pc,scanlinehook 172 | 173 | adr addy,line144 174 | str_ addy,nexttimeout 175 | ldr_ pc,scanlinehook 176 | 177 | .pushsection .iwram.3 178 | line144: @------------------------ 179 | #if SPEEDHACKS_NEW 180 | @quick hack finder code 181 | 182 | @quick hack finder used? 183 | ldrb_ r0,quickhackused 184 | movs r0,r0 185 | bne 0f 186 | @increment counter 187 | ldrb_ r0,quickhackcounter 188 | adds r0,r0,#1 189 | strb_ r0,quickhackcounter 190 | cmp r0,#8 191 | @under 8, don't search 192 | blt 1f 193 | stmfd sp!,{r3} 194 | 195 | adr_ r0,cpuregs 196 | stmia r0,{gb_flg-gb_pc,gb_sp} 197 | 198 | mov r0,gb_pc 199 | ldr_ r1,lastbank 200 | blx_long quickhackfinder 201 | ldmfd sp!,{r3} 202 | 0: 203 | @if quick hack finder was called, or hack was used, reset counter to 0 204 | mov r0,#0 205 | strb_ r0,quickhackcounter 206 | strb_ r0,quickhackused 207 | 1: 208 | #endif 209 | ldrb_ r0,doubletimer_ 210 | tst r0,#1 211 | blne_long updatespeed 212 | bl newframe_vblank 213 | @ stmfd sp!,{r0-addy,lr} 214 | 215 | @ [ BUILD <> "DEBUG" 216 | @ ldrb r2,novblankwait 217 | @ teq r2,#1 218 | @ beq l03 219 | @l01 220 | @ mov r0,#0 ;don't wait if not necessary 221 | @ mov r1,#1 ;VBL wait 222 | @ swi 0x040000 ; Turn of CPU until IRQ if not too late allready. 223 | @ teq r2,#2 ;Check for slomo 224 | @ moveq r2,#0 225 | @ beq l01 226 | @l03 227 | @ ] 228 | @ ldmfd sp!,{r0-addy,lr} 229 | 230 | 231 | ldr_ r0,fpsvalue 232 | add r0,r0,#1 233 | str_ r0,fpsvalue 234 | 235 | 236 | 237 | @ [ DEBUG 238 | @ mov r1,#REG_BASE ;darken screen during GB vblank 239 | @ mov r0,#0x00f1 240 | @ strh r0,[r1,#REG_BLDMOD] 241 | @ ldrh r0,[r1,#REG_VCOUNT] 242 | @ mov r1,#19 243 | @ bl debug_ 244 | @ ] 245 | tst cycles,#CYC_LCD_ENABLED 246 | @ldrb_ r0,lcdctrl @LCD turned on? 247 | @tst r0,#0x80 248 | beq novbirq 249 | 250 | adrl_ r1,FF41_R_vblank_function 251 | ldr r0,[r1] 252 | @ ldr r0,=FF41_R_vblank 253 | ldr r1,=FF41_R_ptr 254 | str r0,[r1] 255 | 256 | adrl r1,lcdstat 257 | ldrb r0,[r1] @vbl flag 258 | and r0,r0,#0x7C 259 | orr r0,r0,#0x01 260 | strb r0,[r1] @vbl flag 261 | strb r0,[r1,#-12] @FIXME 262 | 263 | 264 | ldrb_ r0,gb_if 265 | orr r0,r0,#0x01 @1=VBL 266 | strb_ r0,gb_if 267 | novbirq: 268 | mov r0,#24*CYCLE 269 | add cycles,cycles,r0 270 | 271 | mov r1,#144 272 | strb_ r1,scanline 273 | 274 | adr addy,VBL_Hook 275 | str_ addy,nexttimeout 276 | b _GO 277 | VBL_Hook: 278 | ldr_ r0,cyclesperscanline 279 | sub r0,r0,#24*CYCLE 280 | add cycles,cycles,r0 281 | 282 | adr addy,line145_to_end 283 | str_ addy,nexttimeout 284 | ldr_ pc,scanlinehook 285 | line145_to_end: @------------------------ 286 | ldr_ r0,cyclesperscanline 287 | add cycles,cycles,r0 288 | 289 | ldrb_ r1,scanline 290 | add r1,r1,#1 291 | strb_ r1,scanline 292 | cmp r1,#153 @last scanline 293 | ldrmi_ pc,scanlinehook 294 | 295 | #if !EARLY_LINE_0 296 | ldr addy,=line0 297 | str_ addy,nexttimeout 298 | ldr_ pc,scanlinehook 299 | #else 300 | sub cycles,cycles,r0 301 | toLineZero_modify1: 302 | adds cycles,cycles,#16*CYCLE @8 for non-double speed mode 303 | 304 | @bmi toLineZero 305 | adr addy,toLineZero 306 | str_ addy,nexttimeout 307 | ldr_ pc,scanlinehook 308 | 309 | toLineZero: 310 | @line 0, but still in Vblank state 311 | mov r0,#0 312 | strb_ r0,scanline 313 | @ bl_long newframe @display update 314 | 315 | ldr_ r0,cyclesperscanline 316 | toLineZero_modify2: 317 | sub r0,r0,#16*CYCLE @8 for non-double speed mode 318 | add cycles,cycles,r0 319 | ldr addy,=line0 320 | str_ addy,nexttimeout 321 | ldr_ r0,frame 322 | add r0,r0,#1 323 | str_ r0,frame 324 | ldr_ pc,scanlinehook 325 | #endif 326 | 327 | immediate_check_irq: 328 | ldrb_ r0,gb_ie @0xFFFF=Interrupt Enable. 329 | ldrb_ r1,gb_if 330 | ands r1,r1,r0 331 | tstne cycles,#CYC_IE 332 | bxeq lr 333 | b_long immediate_check_irq_2 334 | @ ldrb_ r0,gb_ime 335 | @ movs r0,r0 336 | @ bxeq lr 337 | @different ugly hack which doesn't mess up timing, 338 | @this is necessary because goomba must finish executing its instruction before checking for GB interrupts 339 | .pushsection .text 340 | immediate_check_irq_2: 341 | ldr_ r0,nexttimeout 342 | @don't override checkMasterIRQ_minus12 343 | ldr r1,=checkMasterIRQ_minus12 344 | cmp r0,r1 345 | bxeq lr 346 | sub cycles,cycles,#1024*CYCLE @this just makes it go somewhere else instead of the next instruction 347 | 348 | str_ r0,nexttimeout_alt 349 | ldr r1,=no_more_irq_hack 350 | str_ r1,nexttimeout 351 | bx lr 352 | 353 | no_more_irq_hack: 354 | add cycles,cycles,#1024*CYCLE 355 | ldr_ r0,nexttimeout_alt 356 | str_ r0,nexttimeout 357 | b_long checkIRQ 358 | .popsection 359 | 360 | 361 | @---------------------------------------------------------- 362 | default_scanlinehook: 363 | checkScanlineIRQ: 364 | default_scanlinehook_nohblank: 365 | tst cycles,#CYC_LCD_ENABLED 366 | beq noScanlineIRQ 367 | 368 | @do LC==LYC test 369 | ldrb_ r1,scanline 370 | ldrb_ r0,lcdyc 371 | cmp r0,r1 372 | adrl r1,lcdstat 373 | ldrb r0,[r1] 374 | @LY==LYC bit must change from 0 to 1 to trigger an LY==LYC interrupt 375 | orreq r2,r0,#4 376 | bicne r2,r0,#4 377 | cmp r2,r0 378 | @ne if LYC bit has changed 379 | strneb r2,[r1] 380 | strneb r2,[r1,#-12] @FIXME 381 | @ beq 0f 382 | @has it turned on, and interrupts are enabled? 383 | tstne r2,#4 384 | tstne r2,#0x40 385 | bne ScanlineIRQ 386 | @ ldrb r2,lcdstat 387 | @0: 388 | @in vblank? no Hblank or Mode 2 IRQ 389 | tst r2,#0x01 390 | bne noScanlineIRQ 391 | @Hblank IRQ or Mode 2 IRQ enabled? 392 | @TODO: real Hblank IRQ 393 | tst r2,#0x28 394 | beq noScanlineIRQ 395 | ScanlineIRQ: 396 | ldrb_ r0,gb_if 397 | orr r0,r0,#0x02 @2=LCD STAT 398 | strb_ r0,gb_if 399 | noScanlineIRQ: 400 | @------------------ 401 | 402 | @------------------ 403 | checkTimerIRQ: 404 | ldr_ r2,timercyclesperscanline 405 | 406 | ldr_ r0,dividereg 407 | add r0,r0,r2,lsl#12 @256th cycles. 408 | str_ r0,dividereg 409 | 410 | ldrb_ r1,timerctrl 411 | tst r1,#0x4 412 | beq noTimer 413 | ands r1,r1,#3 414 | moveq r1,#4 415 | mov r0,#18 416 | sub r1,r0,r1,lsl#1 417 | ldr_ r0,timercounter 418 | adds r0,r0,r2,lsl r1 419 | bcc noTimerIRQ 420 | ldrb_ r0,gb_if 421 | orr r0,r0,#0x04 @4=Timer 422 | strb_ r0,gb_if 423 | ldrb_ r0,timermodulo 424 | mov r0,r0,lsl#24 425 | noTimerIRQ: 426 | str_ r0,timercounter 427 | noTimer: 428 | ldrb_ r1,gb_if 429 | tst r1,#0x08 @Serial 430 | ldrneb_ r0,stctrl 431 | andne r0,r0,#0x7F @Clear Serial Transfer flag. 432 | strneb_ r0,stctrl 433 | checkMasterIRQDelayed: 434 | tst cycles,#CYC_IE 435 | beq _GO 436 | checkIRQDelayed: 437 | ldrb_ r0,gb_ie 438 | ldrb_ r1,gb_if 439 | ands r0,r0,r1 440 | beq _GO 441 | 442 | ldrb r2,[gb_pc] 443 | cmp r2,#0x76 @Check if we're doing Halt. 444 | beq irqGBZ80_ifhalt 445 | 446 | ldr_ r12,cyclesperscanline 447 | sub r12,r12,#8*CYCLE 448 | subs r12,cycles,r12 449 | bmi irqGBZ80_nothalt 450 | mov cycles,r12 451 | 452 | ldrb r0,lcdstat 453 | orr r0,r0,#2 454 | strb r0,lcdstat 455 | 456 | ldr_ r0,nexttimeout 457 | str_ r0,nexttimeout_alt 458 | adr r0,checkMasterIRQ_minus12 459 | str_ r0,nexttimeout 460 | b _GO 461 | 462 | checkMasterIRQ_minus12: 463 | ldrb r0,lcdstat 464 | bic r0,r0,#2 465 | strb r0,lcdstat 466 | 467 | ldr_ r0,cyclesperscanline 468 | add r0,#8*CYCLE 469 | add cycles,cycles,r0 470 | ldr_ r0,nexttimeout_alt 471 | str_ r0,nexttimeout 472 | @proceed to checkMasterIRQ 473 | 474 | @---------------------------------------------------------- 475 | checkMasterIRQ: 476 | @---------------------------------------------------------- 477 | tst cycles,#CYC_IE 478 | @ldrb_ r2,gb_ime 479 | @tst r2,#1 480 | beq _GO 481 | @---------------------------------------------------------- 482 | checkIRQ: 483 | @---------------------------------------------------------- 484 | ldrb_ r0,gb_ie 485 | ldrb_ r1,gb_if 486 | ands r0,r0,r1 487 | beq _GO 488 | @---------------------------------------------------------- 489 | irqGBZ80: 490 | @---------------------------------------------------------- 491 | ldrb r2,[gb_pc] 492 | cmp r2,#0x76 @Check if we're doing Halt. 493 | irqGBZ80_ifhalt: 494 | @ cmpne r2,#0x10 ;or STOP 495 | addeq gb_pc,gb_pc,#1 @get out of HALT 496 | irqGBZ80_nothalt: 497 | bic cycles,cycles,#CYC_IE 498 | @ mov r2,#0 @disable IRQ 499 | @ strb_ r2,gb_ime 500 | 501 | tst r0,#0x01 @VBlank 502 | movne r2,#0x40 503 | bicne r1,r1,#0x01 @clear the IRQ flag 504 | bne doIRQ 505 | 506 | tst r0,#0x02 @LCD Stat 507 | movne r2,#0x48 508 | bicne r1,r1,#0x02 @clear the IRQ flag 509 | bne doIRQ 510 | 511 | tst r0,#0x04 @Timer 512 | movne r2,#0x50 513 | bicne r1,r1,#0x04 @clear the IRQ flag 514 | @ bne doIRQ 515 | beq_long _irqGBZ80_ 516 | @10 instructions moved to .text section 517 | @ tst r0,#0x08 @Serial 518 | @ movne r2,#0x58 519 | @ bicne r1,r1,#0x08 @clear the IRQ flag 520 | @ bne doIRQ 521 | @ 522 | @ tst r0,#0x10 @Joypad 523 | @ movne r2,#0x60 524 | @ bicne r1,r1,#0x10 @clear the IRQ flag 525 | @ bne doIRQ 526 | @ 527 | @ and r1,r1,#0x1f @unknown IRQ? 528 | @ mov r2,#0x40 529 | 530 | doIRQ: 531 | strb_ r1,gb_if 532 | ldr_ r0,lastbank 533 | sub r0,gb_pc,r0 534 | mov gb_pc,r2 @get IRQ vector 535 | 536 | push16_novram @save PC 537 | encodePC_afterpush16 538 | 539 | fetch 24 540 | 541 | .pushsection .text 542 | _irqGBZ80_: 543 | tst r0,#0x08 @Serial 544 | movne r2,#0x58 545 | bicne r1,r1,#0x08 @clear the IRQ flag 546 | bne_long doIRQ 547 | 548 | tst r0,#0x10 @Joypad 549 | movne r2,#0x60 550 | bicne r1,r1,#0x10 @clear the IRQ flag 551 | bne_long doIRQ 552 | 553 | and r1,r1,#0x1f @unknown IRQ? 554 | mov r2,#0x40 555 | b_long doIRQ 556 | .popsection 557 | 558 | 559 | .section .iwram.end.105, "ax", %progbits 560 | @---------------------------------------------------------------------------- 561 | fiveminutes: .word 5*60*60 @fiveminutes_ 562 | sleeptime: .word 5*60*60 @sleeptime_ 563 | dontstop: .byte 0 @dontstop_ 564 | g_hackflags: .byte 0 @hackflags 565 | g_hackflags2: .byte 0 @hackflags2 566 | .byte 0 567 | @---------------------------------------------------------------------------- 568 | -------------------------------------------------------------------------------- /src/minilzo.107/lzoconf.h: -------------------------------------------------------------------------------- 1 | /* lzoconf.h -- configuration for the LZO real-time data compression library 2 | 3 | This file is part of the LZO real-time data compression library. 4 | 5 | Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer 6 | Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer 7 | Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer 8 | Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer 9 | Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer 10 | 11 | The LZO library is free software; you can redistribute it and/or 12 | modify it under the terms of the GNU General Public License as 13 | published by the Free Software Foundation; either version 2 of 14 | the License, or (at your option) any later version. 15 | 16 | The LZO library is distributed in the hope that it will be useful, 17 | but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | GNU General Public License for more details. 20 | 21 | You should have received a copy of the GNU General Public License 22 | along with the LZO library; see the file COPYING. 23 | If not, write to the Free Software Foundation, Inc., 24 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 25 | 26 | Markus F.X.J. Oberhumer 27 | 28 | http://wildsau.idv.uni-linz.ac.at/mfx/lzo.html 29 | */ 30 | 31 | 32 | #ifndef __LZOCONF_H 33 | #define __LZOCONF_H 34 | 35 | #define LZO_VERSION 0x1070 36 | #define LZO_VERSION_STRING "1.07" 37 | #define LZO_VERSION_DATE "Oct 18 2000" 38 | 39 | /* internal Autoconf configuration file - only used when building LZO */ 40 | #if defined(LZO_HAVE_CONFIG_H) 41 | # include 42 | #endif 43 | #include 44 | 45 | #ifdef __cplusplus 46 | extern "C" { 47 | #endif 48 | 49 | 50 | /*********************************************************************** 51 | // LZO requires a conforming 52 | ************************************************************************/ 53 | 54 | #if !defined(CHAR_BIT) || (CHAR_BIT != 8) 55 | # error "invalid CHAR_BIT" 56 | #endif 57 | #if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX) 58 | # error "check your compiler installation" 59 | #endif 60 | #if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1) 61 | # error "your limits.h macros are broken" 62 | #endif 63 | 64 | /* workaround a cpp bug under hpux 10.20 */ 65 | #define LZO_0xffffffffL 4294967295ul 66 | 67 | 68 | /*********************************************************************** 69 | // architecture defines 70 | ************************************************************************/ 71 | 72 | #if !defined(__LZO_WIN) && !defined(__LZO_DOS) && !defined(__LZO_OS2) 73 | # if defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) 74 | # define __LZO_WIN 75 | # elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) 76 | # define __LZO_WIN 77 | # elif defined(__NT__) || defined(__NT_DLL__) || defined(__WINDOWS_386__) 78 | # define __LZO_WIN 79 | # elif defined(__DOS__) || defined(__MSDOS__) || defined(MSDOS) 80 | # define __LZO_DOS 81 | # elif defined(__OS2__) || defined(__OS2V2__) || defined(OS2) 82 | # define __LZO_OS2 83 | # elif defined(__palmos__) 84 | # define __LZO_PALMOS 85 | # elif defined(__TOS__) || defined(__atarist__) 86 | # define __LZO_TOS 87 | # endif 88 | #endif 89 | 90 | #if (UINT_MAX < LZO_0xffffffffL) 91 | # if defined(__LZO_WIN) 92 | # define __LZO_WIN16 93 | # elif defined(__LZO_DOS) 94 | # define __LZO_DOS16 95 | # elif defined(__LZO_PALMOS) 96 | # define __LZO_PALMOS16 97 | # elif defined(__LZO_TOS) 98 | # define __LZO_TOS16 99 | # elif defined(__C166__) 100 | # else 101 | # error "16-bit target not supported - contact me for porting hints" 102 | # endif 103 | #endif 104 | 105 | #if !defined(__LZO_i386) 106 | # if defined(__LZO_DOS) || defined(__LZO_WIN16) 107 | # define __LZO_i386 108 | # elif defined(__i386__) || defined(__386__) || defined(_M_IX86) 109 | # define __LZO_i386 110 | # endif 111 | #endif 112 | 113 | #if defined(__LZO_STRICT_16BIT) 114 | # if (UINT_MAX < LZO_0xffffffffL) 115 | # include 116 | # endif 117 | #endif 118 | 119 | /* memory checkers */ 120 | #if !defined(__LZO_CHECKER) 121 | # if defined(__BOUNDS_CHECKING_ON) 122 | # define __LZO_CHECKER 123 | # elif defined(__CHECKER__) 124 | # define __LZO_CHECKER 125 | # elif defined(__INSURE__) 126 | # define __LZO_CHECKER 127 | # elif defined(__PURIFY__) 128 | # define __LZO_CHECKER 129 | # endif 130 | #endif 131 | 132 | 133 | /*********************************************************************** 134 | // integral and pointer types 135 | ************************************************************************/ 136 | 137 | /* Integral types with 32 bits or more */ 138 | #if !defined(LZO_UINT32_MAX) 139 | # if (UINT_MAX >= LZO_0xffffffffL) 140 | typedef unsigned int lzo_uint32; 141 | typedef int lzo_int32; 142 | # define LZO_UINT32_MAX UINT_MAX 143 | # define LZO_INT32_MAX INT_MAX 144 | # define LZO_INT32_MIN INT_MIN 145 | # elif (ULONG_MAX >= LZO_0xffffffffL) 146 | typedef unsigned long lzo_uint32; 147 | typedef long lzo_int32; 148 | # define LZO_UINT32_MAX ULONG_MAX 149 | # define LZO_INT32_MAX LONG_MAX 150 | # define LZO_INT32_MIN LONG_MIN 151 | # else 152 | # error "lzo_uint32" 153 | # endif 154 | #endif 155 | 156 | /* lzo_uint is used like size_t */ 157 | #if !defined(LZO_UINT_MAX) 158 | # if (UINT_MAX >= LZO_0xffffffffL) 159 | typedef unsigned int lzo_uint; 160 | typedef int lzo_int; 161 | # define LZO_UINT_MAX UINT_MAX 162 | # define LZO_INT_MAX INT_MAX 163 | # define LZO_INT_MIN INT_MIN 164 | # elif (ULONG_MAX >= LZO_0xffffffffL) 165 | typedef unsigned long lzo_uint; 166 | typedef long lzo_int; 167 | # define LZO_UINT_MAX ULONG_MAX 168 | # define LZO_INT_MAX LONG_MAX 169 | # define LZO_INT_MIN LONG_MIN 170 | # else 171 | # error "lzo_uint" 172 | # endif 173 | #endif 174 | 175 | 176 | /* Memory model that allows to access memory at offsets of lzo_uint. */ 177 | #if !defined(__LZO_MMODEL) 178 | # if (LZO_UINT_MAX <= UINT_MAX) 179 | # define __LZO_MMODEL 180 | # elif defined(__LZO_DOS16) || defined(__LZO_WIN16) 181 | # define __LZO_MMODEL __huge 182 | # define LZO_999_UNSUPPORTED 183 | # elif defined(__LZO_PALMOS16) || defined(__LZO_TOS16) 184 | # define __LZO_MMODEL 185 | # else 186 | # error "__LZO_MMODEL" 187 | # endif 188 | #endif 189 | 190 | /* no typedef here because of const-pointer issues */ 191 | #define lzo_byte unsigned char __LZO_MMODEL 192 | #define lzo_bytep unsigned char __LZO_MMODEL * 193 | #define lzo_charp char __LZO_MMODEL * 194 | #define lzo_voidp void __LZO_MMODEL * 195 | #define lzo_shortp short __LZO_MMODEL * 196 | #define lzo_ushortp unsigned short __LZO_MMODEL * 197 | #define lzo_uint32p lzo_uint32 __LZO_MMODEL * 198 | #define lzo_int32p lzo_int32 __LZO_MMODEL * 199 | #define lzo_uintp lzo_uint __LZO_MMODEL * 200 | #define lzo_intp lzo_int __LZO_MMODEL * 201 | #define lzo_voidpp lzo_voidp __LZO_MMODEL * 202 | #define lzo_bytepp lzo_bytep __LZO_MMODEL * 203 | 204 | typedef int lzo_bool; 205 | 206 | #ifndef lzo_sizeof_dict_t 207 | # define lzo_sizeof_dict_t sizeof(lzo_bytep) 208 | #endif 209 | 210 | 211 | /*********************************************************************** 212 | // function types 213 | ************************************************************************/ 214 | 215 | /* linkage */ 216 | #if !defined(__LZO_EXTERN_C) 217 | # ifdef __cplusplus 218 | # define __LZO_EXTERN_C extern "C" 219 | # else 220 | # define __LZO_EXTERN_C extern 221 | # endif 222 | #endif 223 | 224 | /* calling conventions */ 225 | #if !defined(__LZO_CDECL) 226 | # if defined(__LZO_DOS16) || defined(__LZO_WIN16) 227 | # define __LZO_CDECL __far __cdecl 228 | # elif defined(__LZO_i386) && defined(_MSC_VER) 229 | # define __LZO_CDECL __cdecl 230 | # elif defined(__LZO_i386) && defined(__WATCOMC__) 231 | # define __LZO_CDECL __near __cdecl 232 | # else 233 | # define __LZO_CDECL 234 | # endif 235 | #endif 236 | #if !defined(__LZO_ENTRY) 237 | # define __LZO_ENTRY __LZO_CDECL 238 | #endif 239 | 240 | /* DLL export information */ 241 | #if !defined(__LZO_EXPORT1) 242 | # define __LZO_EXPORT1 243 | #endif 244 | #if !defined(__LZO_EXPORT2) 245 | # define __LZO_EXPORT2 246 | #endif 247 | 248 | /* calling convention for C functions */ 249 | #if !defined(LZO_PUBLIC) 250 | # define LZO_PUBLIC(_rettype) __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_ENTRY 251 | #endif 252 | #if !defined(LZO_EXTERN) 253 | # define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype) 254 | #endif 255 | #if !defined(LZO_PRIVATE) 256 | # define LZO_PRIVATE(_rettype) static _rettype __LZO_ENTRY 257 | #endif 258 | 259 | /* cdecl calling convention for assembler functions */ 260 | #if !defined(LZO_PUBLIC_CDECL) 261 | # define LZO_PUBLIC_CDECL(_rettype) \ 262 | __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL 263 | #endif 264 | #if !defined(LZO_EXTERN_CDECL) 265 | # define LZO_EXTERN_CDECL(_rettype) __LZO_EXTERN_C LZO_PUBLIC_CDECL(_rettype) 266 | #endif 267 | 268 | 269 | typedef int 270 | (__LZO_ENTRY *lzo_compress_t) ( const lzo_byte *src, lzo_uint src_len, 271 | lzo_byte *dst, lzo_uint *dst_len, 272 | lzo_voidp wrkmem ); 273 | 274 | typedef int 275 | (__LZO_ENTRY *lzo_decompress_t) ( const lzo_byte *src, lzo_uint src_len, 276 | lzo_byte *dst, lzo_uint *dst_len, 277 | lzo_voidp wrkmem ); 278 | 279 | typedef int 280 | (__LZO_ENTRY *lzo_optimize_t) ( lzo_byte *src, lzo_uint src_len, 281 | lzo_byte *dst, lzo_uint *dst_len, 282 | lzo_voidp wrkmem ); 283 | 284 | typedef int 285 | (__LZO_ENTRY *lzo_compress_dict_t)(const lzo_byte *src, lzo_uint src_len, 286 | lzo_byte *dst, lzo_uint *dst_len, 287 | lzo_voidp wrkmem, 288 | const lzo_byte *dict, lzo_uint dict_len ); 289 | 290 | typedef int 291 | (__LZO_ENTRY *lzo_decompress_dict_t)(const lzo_byte *src, lzo_uint src_len, 292 | lzo_byte *dst, lzo_uint *dst_len, 293 | lzo_voidp wrkmem, 294 | const lzo_byte *dict, lzo_uint dict_len ); 295 | 296 | 297 | /* a progress indicator callback function */ 298 | typedef void (__LZO_ENTRY *lzo_progress_callback_t) (lzo_uint, lzo_uint); 299 | 300 | 301 | /*********************************************************************** 302 | // error codes and prototypes 303 | ************************************************************************/ 304 | 305 | /* Error codes for the compression/decompression functions. Negative 306 | * values are errors, positive values will be used for special but 307 | * normal events. 308 | */ 309 | #define LZO_E_OK 0 310 | #define LZO_E_ERROR (-1) 311 | #define LZO_E_OUT_OF_MEMORY (-2) /* not used right now */ 312 | #define LZO_E_NOT_COMPRESSIBLE (-3) /* not used right now */ 313 | #define LZO_E_INPUT_OVERRUN (-4) 314 | #define LZO_E_OUTPUT_OVERRUN (-5) 315 | #define LZO_E_LOOKBEHIND_OVERRUN (-6) 316 | #define LZO_E_EOF_NOT_FOUND (-7) 317 | #define LZO_E_INPUT_NOT_CONSUMED (-8) 318 | 319 | 320 | /* lzo_init() should be the first function you call. 321 | * Check the return code ! 322 | * 323 | * lzo_init() is a macro to allow checking that the library and the 324 | * compiler's view of various types are consistent. 325 | */ 326 | #define lzo_init() __lzo_init2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\ 327 | (int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\ 328 | (int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\ 329 | (int)sizeof(lzo_compress_t)) 330 | LZO_EXTERN(int) __lzo_init2(unsigned,int,int,int,int,int,int,int,int,int); 331 | 332 | /* version functions (useful for shared libraries) */ 333 | LZO_EXTERN(unsigned) lzo_version(void); 334 | LZO_EXTERN(const char *) lzo_version_string(void); 335 | LZO_EXTERN(const char *) lzo_version_date(void); 336 | LZO_EXTERN(const lzo_charp) _lzo_version_string(void); 337 | LZO_EXTERN(const lzo_charp) _lzo_version_date(void); 338 | 339 | /* string functions */ 340 | LZO_EXTERN(int) 341 | lzo_memcmp(const lzo_voidp _s1, const lzo_voidp _s2, lzo_uint _len); 342 | LZO_EXTERN(lzo_voidp) 343 | lzo_memcpy(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len); 344 | LZO_EXTERN(lzo_voidp) 345 | lzo_memmove(lzo_voidp _dest, const lzo_voidp _src, lzo_uint _len); 346 | LZO_EXTERN(lzo_voidp) 347 | lzo_memset(lzo_voidp _s, int _c, lzo_uint _len); 348 | 349 | /* checksum functions */ 350 | LZO_EXTERN(lzo_uint32) 351 | lzo_adler32(lzo_uint32 _adler, const lzo_byte *_buf, lzo_uint _len); 352 | LZO_EXTERN(lzo_uint32) 353 | lzo_crc32(lzo_uint32 _c, const lzo_byte *_buf, lzo_uint _len); 354 | 355 | /* memory allocation functions */ 356 | LZO_EXTERN(lzo_bytep) lzo_alloc(lzo_uint _nelems, lzo_uint _size); 357 | LZO_EXTERN(lzo_bytep) lzo_malloc(lzo_uint _size); 358 | LZO_EXTERN(void) lzo_free(lzo_voidp _ptr); 359 | 360 | typedef lzo_bytep (__LZO_ENTRY *lzo_alloc_hook_t) (lzo_uint, lzo_uint); 361 | typedef void (__LZO_ENTRY *lzo_free_hook_t) (lzo_voidp); 362 | 363 | extern lzo_alloc_hook_t lzo_alloc_hook; 364 | extern lzo_free_hook_t lzo_free_hook; 365 | 366 | /* misc. */ 367 | LZO_EXTERN(lzo_bool) lzo_assert(int _expr); 368 | LZO_EXTERN(int) _lzo_config_check(void); 369 | typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u; 370 | typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u; 371 | 372 | /* align a char pointer on a boundary that is a multiple of `size' */ 373 | LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp _ptr, lzo_uint _size); 374 | #define LZO_PTR_ALIGN_UP(_ptr,_size) \ 375 | ((_ptr) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(_ptr),(lzo_uint)(_size))) 376 | 377 | /* deprecated - only for backward compatibility */ 378 | #define LZO_ALIGN(_ptr,_size) LZO_PTR_ALIGN_UP(_ptr,_size) 379 | 380 | 381 | #ifdef __cplusplus 382 | } /* extern "C" */ 383 | #endif 384 | 385 | #endif /* already included */ 386 | 387 | -------------------------------------------------------------------------------- /src/equates.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "config.h" 3 | 4 | //Must update cleanup_ewram if EWRAM equates are changed! 5 | 6 | 7 | VERSION_IN_ROM = 1 8 | #ifndef _GBAMP_VERSION 9 | #define _GBAMP_VERSION 0 10 | #endif 11 | GBAMPVERSION = _GBAMP_VERSION 12 | 13 | #include "macro.h" 14 | 15 | @GBLL DEBUG 16 | @GBLL SAFETY 17 | @GBLL PROFILE 18 | @GBLL SPEEDHACKS_OLD 19 | @GBLL MOVIEPLAYER 20 | @GBLL RESIZABLE 21 | @GBLL RUMBLE 22 | @GBLL SAVESTATES 23 | 24 | @GBLL SRAM_32 25 | 26 | @GBLL VISOLY 27 | 28 | @GBLL LITTLESOUNDDJ 29 | 30 | SRAM_32 = 0 31 | 32 | DEBUG = 0 33 | PROFILE = 0 34 | @ SPEEDHACKS_OLD = 0 35 | // LITTLESOUNDDJ = 0 36 | 37 | // .if GBAMPVERSION 38 | // MOVIEPLAYER = 1 39 | // RESIZABLE = 1 40 | // RUMBLE = 0 41 | // VISOLY = 0 42 | // .else 43 | // MOVIEPLAYER = 0 44 | // RESIZABLE = 0 45 | // RUMBLE = 1 46 | // VISOLY = 1 47 | // .endif 48 | 49 | SAVESTATES = 0 50 | 51 | 52 | @BUILD SETS "DEBUG"/"GBA" (defined at cmdline) 53 | @---------------------------------------------------------------------------- 54 | 55 | MAX_RECENT_TILES = 96 @if you change this, change RECENT_TILES as well! 56 | RECENT_TILENUM_SIZE = 128 57 | 58 | @ BG_CACHE_SIZE = 512 59 | 60 | 61 | @statck starts at 0x03007700 62 | 63 | BORDER_PALETTE = 0x0600EF80 @formerly 0x06006F80 64 | 65 | 66 | 67 | 68 | 69 | @VRAM areas: 70 | @0x600 bytes at 06006200 71 | @0x80 bytes at 06006f00 72 | @0x400 bytes at 0600cc00 73 | @0x4000 at 06014000 74 | @0x300 at 06007D00-06008000 75 | 76 | @SGB border areas coincide with the GBA areas reserved for them 77 | SNES_VRAM = 0x0600C220 @one tile ahead, too bad if games don't write low tiles then high tiles, also overlaps with recent_tiles... 78 | SNES_MAP = 0x0600E780 @overlaps with recent_tiles, map must be updated in reverse order 79 | RECENT_TILES = 0x0600E200 @DIRTY_TILES-(MAX_RECENT_TILES*16) 80 | 81 | AGB_SGB_MAP = 0x0600E800 82 | AGB_SGB_VRAM = 0x0600C200 83 | 84 | @GBLA Next 85 | 86 | MEM_END = 0x02040000 87 | 88 | Next = MEM_END 89 | 90 | .if MOVIEPLAYER 91 | FAT_MEM_END = MEM_END 92 | FAT_MEM_START = FAT_MEM_END-4096 93 | fatBuffer = FAT_MEM_END-512 94 | fatWriteBuffer = fatBuffer 95 | globalBuffer = fatBuffer-512 96 | lfnName = globalBuffer-256 97 | SramName = lfnName-256 98 | openFiles = SramName-1200 99 | stateexist = openFiles-36 100 | System = stateexist-4 101 | PALMode = System-4 102 | rom_file = PALMode-4 103 | nocash = rom_file-4 104 | rom_filesize = nocash-4 105 | 106 | Next = FAT_MEM_START 107 | .endif 108 | 109 | .if RESIZABLE 110 | .else 111 | XGB_SRAM = Next-0x8000 112 | XGB_VRAM = XGB_SRAM-0x4000 113 | GBC_EXRAM = XGB_VRAM-0x6000 114 | Next = GBC_EXRAM 115 | .endif 116 | 117 | @ INSTANT_PAGES = 0x06004c00 @SGB_PACKET-1024 ;formerly 0x0600CC00 118 | 119 | SGB_PALETTE = Next-16*4 120 | 121 | Next = SGB_PALETTE 122 | 123 | @ DIRTY_ROWS = Next-48 124 | @ DIRTY_TILES = DIRTY_ROWS-768-4 125 | @ RECENT_TILENUM = DIRTY_TILES-(MAX_RECENT_TILES+2)*2 126 | 127 | @ BG_CACHE = RECENT_TILENUM-BG_CACHE_SIZE 128 | 129 | @ Next = RECENT_TILENUM 130 | 131 | .if RESIZABLE 132 | .else 133 | SGB_PALS = Next-4096 134 | SGB_ATFS = SGB_PALS-4096 135 | SGB_PACKET = SGB_ATFS-112 136 | SGB_ATTRIBUTES = SGB_PACKET-360 137 | 138 | Next = SGB_ATTRIBUTES 139 | .endif 140 | 141 | 142 | 143 | 144 | GBOAMBUFF1 = Next-160 145 | GBOAMBUFF2 = GBOAMBUFF1-160 146 | GBOAMBUFF3 = GBOAMBUFF2-160 147 | 148 | BG0CNT_SCROLL_BUFF = GBOAMBUFF3-144*24 149 | WINDOWBUFF = BG0CNT_SCROLL_BUFF-144*2 150 | DISPCNTBUFF = WINDOWBUFF-144*2 151 | 152 | BG0CNT_SCROLL_BUFF2 = DISPCNTBUFF-144*24 153 | WINDOWBUFF2 = BG0CNT_SCROLL_BUFF2-144*2 154 | DISPCNTBUFF2 = WINDOWBUFF2-144*2 155 | 156 | Next = DISPCNTBUFF2 157 | 158 | @WXBUFF1 EQU DISPCNTBUFF-144 159 | @YSCROLLBUFF1 EQU WXBUFF1-144 160 | @XSCROLLBUFF1 EQU YSCROLLBUFF1-144 161 | @LCDCBUFF1 EQU XSCROLLBUFF1-144 162 | @WXBUFF2 EQU LCDCBUFF1-144 163 | @YSCROLLBUFF2 EQU WXBUFF2-144 164 | @XSCROLLBUFF2 EQU YSCROLLBUFF2-144 165 | @LCDCBUFF2 EQU XSCROLLBUFF2-144 166 | 167 | 168 | TEXTMEM = Next - 632 169 | Next = TEXTMEM 170 | 171 | ewram_canary_2 = Next - 4 172 | Next = ewram_canary_2 173 | 174 | DIRTY_TILE_BITS = Next - 48 175 | dirty_map_words = DIRTY_TILE_BITS - 64 176 | Next = dirty_map_words 177 | 178 | RECENT_TILENUM = Next - RECENT_TILENUM_SIZE @32 words 179 | Next = RECENT_TILENUM 180 | 181 | @24 packets at 8 bytes per packet, 20 packets might be okay too... (modify dma.c as well) 182 | vram_packets_incoming = Next - 192 183 | vram_packets_registered_bank0 = vram_packets_incoming - 192 184 | vram_packets_registered_bank1 = vram_packets_registered_bank0 - 192 185 | vram_packets_dirty = vram_packets_registered_bank1 - 196 186 | 187 | Next = vram_packets_dirty 188 | 189 | INSTANT_PAGES = Next-1024 190 | Next = INSTANT_PAGES 191 | 192 | ewram_canary_1 = Next - 4 193 | Next = ewram_canary_1 194 | 195 | .if SPEEDHACKS_OLD 196 | SPEEDHACK_FIND_JR_Z_BUF = Next - 64 197 | SPEEDHACK_FIND_JR_NZ_BUF = SPEEDHACK_FIND_JR_Z_BUF-64 198 | SPEEDHACK_FIND_JR_C_BUF = SPEEDHACK_FIND_JR_NZ_BUF-64 199 | SPEEDHACK_FIND_JR_NC_BUF = SPEEDHACK_FIND_JR_C_BUF-64 200 | Next = SPEEDHACK_FIND_JR_NC_BUF 201 | .endif 202 | 203 | @ _FF41_PC_4 = Next - 168 204 | @ Next = _FF41_PC_4 205 | 206 | 207 | MULTIBOOT_LIMIT = Next @How much data is left for Multiboot to work. 208 | END_OF_EXRAM = MULTIBOOT_LIMIT 209 | 210 | 211 | 212 | 213 | 214 | AGB_IRQVECT = 0x3007FFC 215 | AGB_PALETTE = 0x5000000 216 | AGB_VRAM = 0x6000000 217 | AGB_OAM = 0x7000000 218 | AGB_SRAM = 0xE000000 219 | 220 | REG_BASE = 0x4000000 221 | REG_DISPCNT = 0x00 222 | REG_DISPSTAT = 0x04 223 | REG_VCOUNT = 0x06 224 | REG_BG0CNT = 0x08 225 | REG_BG1CNT = 0x0A 226 | REG_BG2CNT = 0x0C 227 | REG_BG3CNT = 0x0E 228 | REG_BG0HOFS = 0x10 229 | REG_BG0VOFS = 0x12 230 | REG_BG1HOFS = 0x14 231 | REG_BG1VOFS = 0x16 232 | REG_BG2HOFS = 0x18 233 | REG_BG2VOFS = 0x1A 234 | REG_BG3HOFS = 0x1C 235 | REG_BG3VOFS = 0x1E 236 | REG_WIN0H = 0x40 237 | REG_WIN1H = 0x42 238 | REG_WIN0V = 0x44 239 | REG_WIN1V = 0x46 240 | REG_WININ = 0x48 241 | REG_WINOUT = 0x4A 242 | REG_BLDMOD = 0x50 243 | REG_BLDALPHA = 0x52 244 | REG_BLDY = 0x54 245 | REG_SG1CNT_L = 0x60 246 | REG_SG1CNT_H = 0x62 247 | REG_SG1CNT_X = 0x64 248 | REG_SG2CNT_L = 0x68 249 | REG_SG2CNT_H = 0x6C 250 | REG_SG3CNT_L = 0x70 251 | REG_SG3CNT_H = 0x72 252 | REG_SG3CNT_X = 0x74 253 | REG_SG4CNT_L = 0x78 254 | REG_SG4CNT_H = 0x7c 255 | REG_SGCNT_L = 0x80 256 | REG_SGCNT_H = 0x82 257 | REG_SGCNT_X = 0x84 258 | REG_SGBIAS = 0x88 259 | REG_SGWR0_L = 0x90 260 | REG_FIFO_A_L = 0xA0 261 | REG_FIFO_A_H = 0xA2 262 | REG_FIFO_B_L = 0xA4 263 | REG_FIFO_B_H = 0xA6 264 | REG_DM0SAD = 0xB0 265 | REG_DM0DAD = 0xB4 266 | REG_DM0CNT_L = 0xB8 267 | REG_DM0CNT_H = 0xBA 268 | REG_DM1SAD = 0xBC 269 | REG_DM1DAD = 0xC0 270 | REG_DM1CNT_L = 0xC4 271 | REG_DM1CNT_H = 0xC6 272 | REG_DM2SAD = 0xC8 273 | REG_DM2DAD = 0xCC 274 | REG_DM2CNT_L = 0xD0 275 | REG_DM2CNT_H = 0xD2 276 | REG_DM3SAD = 0xD4 277 | REG_DM3DAD = 0xD8 278 | REG_DM3CNT_L = 0xDC 279 | REG_DM3CNT_H = 0xDE 280 | REG_TM0D = 0x100 281 | REG_TM0CNT = 0x102 282 | REG_IE = 0x200 283 | REG_IME = 0x208 284 | REG_IF = 0x4000202 285 | REG_P1 = 0x4000130 286 | REG_P1CNT = 0x132 287 | REG_WAITCNT = 0x4000204 288 | 289 | REG_SIOMULTI0 = 0x20 @+100 290 | REG_SIOMULTI1 = 0x22 @+100 291 | REG_SIOMULTI2 = 0x24 @+100 292 | REG_SIOMULTI3 = 0x26 @+100 293 | REG_SIOCNT = 0x28 @+100 294 | REG_SIOMLT_SEND = 0x2a @+100 295 | REG_RCNT = 0x34 @+100 296 | 297 | @r0,r1,r2=temp regs 298 | gb_flg .req r3 @bit 31=N, Z=1 if bits 0-7=0 299 | gb_a .req r4 @bits 0-15=0 300 | gb_bc .req r5 @bits 0-15=0 301 | gb_de .req r6 @bits 0-15=0 302 | gb_hl .req r7 @bits 0-15=0 303 | cycles .req r8 304 | gb_pc .req r9 305 | globalptr .req r10 @=wram_globals* ptr 306 | gb_optbl .req r10 307 | gb_sp .req r11 308 | addy .req r12 @keep this at r12 (scratch for APCS) 309 | @r13=SP 310 | @r14=LR 311 | @r15=PC 312 | @---------------------------------------------------------------------------- 313 | 314 | @everything in wram_globals* areas: 315 | 316 | start_map -19*4,globalptr @gbz80.s 317 | _m_ speedhack_ram_address,4 318 | _m_ quickhackused,1 319 | _m_ quickhackcounter,1 320 | _m_ joy_read_count,1 321 | _m_ speedhack_mode,1 322 | _m_ speedhack_pc,4 323 | @readmem_tbl 324 | _m_ readmem_tbl_begin,0 325 | _m_ readmem_tbl_end,16*4 326 | _m_ ,-4 327 | _m_ readmem_tbl_,0 328 | _m_ ,4 329 | _m_ opz,256*4 330 | _m_ writemem_tbl,16*4 331 | _m_ memmap_tbl,16*4 332 | _m_ cpuregs,8*4 333 | _m_ ,1 @gb_ime,1 @not used 334 | _m_ gb_ie,1 335 | _m_ gb_if,1 336 | _m_ ,1 @gb_interrupt_lines, not used 337 | _m_ rambank,1 338 | _m_ gbcmode,1 339 | _m_ sgbmode,1 340 | _m_ ,1 341 | 342 | _m_ dividereg,4 343 | _m_ timercounter,4 344 | _m_ timermodulo,1 345 | _m_ timerctrl,1 346 | _m_ stctrl,1 347 | _m_ ,1 348 | _m_ frame,4 349 | _m_ nexttimeout,4 350 | _m_ nexttimeout_alt,4 351 | _m_ scanlinehook,4 352 | _m_ lastbank,4 353 | _m_ cyclesperscanline,4 354 | _m_ timercyclesperscanline,4 355 | _m_ scanline_oam_position,4 356 | @ .if PROFILE 357 | @ _m_ profiler,4 358 | @ .endif 359 | _m_ doubletimer_,1 360 | _m_ gbamode,1 361 | _m_ request_gb_type_,1 362 | _m_ novblankwait_,1 363 | 364 | .if RESIZABLE 365 | _m_ xgb_sram,4 366 | _m_ xgb_sramsize,4 367 | _m_ xgb_vram,4 368 | _m_ xgb_vramsize,4 369 | _m_ gbc_exram,4 370 | _m_ gbc_exramsize,4 371 | _m_ end_of_exram,4 372 | _m_ xgb_vram_1800,4 373 | _m_ xgb_vram_1C00,4 374 | _m_ sgb_pals,4 375 | _m_ sgb_atfs,4 376 | _m_ sgb_packet,4 377 | _m_ sgb_attributes,4 378 | _m_ ,12 @padding 379 | .endif 380 | @#6 word (of 8) 381 | @lcd.s (wram_globals1) 382 | _m_ fpsvalue,4 383 | _m_ AGBjoypad,4 384 | _m_ XGBjoypad,4 385 | 386 | _m_ lcdctrl,1 387 | _m_ lcdstat_save,1 388 | _m_ scrollX,1 389 | _m_ scrollY,1 390 | 391 | _m_ scanline,1 392 | _m_ lcdyc,1 393 | _m_ ,1 394 | _m_ bgpalette,1 395 | 396 | _m_ ob0palette,1 397 | _m_ ob1palette,1 398 | _m_ windowX,1 399 | _m_ windowY,1 400 | 401 | _m_ BCPS_index,1 402 | _m_ doublespeed,1 403 | _m_ OCPS_index,1 404 | _m_ vrambank,1 405 | 406 | _m_ dma_src,2 407 | _m_ dma_dest,2 408 | _m_ dirty_tile_bits,4 409 | _m_ gb_oam_buffer_alt,4 410 | @ _m_ dirty_tiles,4 411 | @ _m_ dirty_rows,4 412 | 413 | _m_ bigbuffer,4 414 | _m_ bg01cnt,4 415 | _m_ bg23cnt,4 416 | _m_ xyscroll,4 417 | _m_ xyscroll2,4 418 | _m_ dispcntdata,4 419 | _m_ windata,4 420 | _m_ dispcntaddr,4 421 | _m_ windowyscroll,4 422 | _m_ buffer_lastscanline,4 423 | 424 | _m_ lcdctrl0midframe,1 425 | _m_ lcdctrl0frame,1 426 | _m_ rendermode,1 427 | _m_ _ui_border_visible,1 428 | 429 | _m_ _sgb_palette_number,1 430 | _m_ _gammavalue,1 431 | _m_ _darkness,1 432 | _m_ ,1 433 | 434 | _m_ ui_border_cnt_bic,4 435 | _m_ ui_border_cnt_orr,4 436 | _m_ ui_border_scroll2,4 437 | _m_ ui_border_scroll3,4 438 | _m_ _ui_x,4 439 | _m_ _ui_y,4 440 | _m_ _ui_border_request,4 441 | _m_ _ui_border_screen,4 442 | _m_ _ui_border_buffer,4 443 | 444 | _m_ dispcntbase,4 445 | _m_ dispcntbase2,4 446 | _m_ bigbufferbase,4 447 | _m_ bigbufferbase2,4 448 | 449 | _m_ gboamdirty,1 450 | _m_ consume_dirty,1 451 | _m_ consume_buffer,1 452 | _m_ vblank_happened,1 453 | 454 | _m_ gb_oam_buffer_screen,4 455 | _m_ gb_oam_buffer_writing,4 456 | 457 | _m_ _palettebank,4 458 | 459 | @ _m_ bg_cache_cursor,4 460 | @ _m_ bg_cache_base,4 461 | @ _m_ bg_cache_limit,4 462 | @ _m_ bg_cache_full,1 463 | @ _m_ bg_cache_updateok,1 464 | @ _m_ lcdhack,1 465 | @ _m_ dmamode,1 466 | 467 | _m_ sound_shadow,12 468 | _m_ ,1 469 | _m_ bg_cache_updateok,1 470 | _m_ lcdhack,1 471 | _m_ dmamode,1 472 | 473 | 474 | @VRAM_name0_ptr # 4 475 | 476 | @cart.s (wram_globals2) 477 | _m_ bank0,4 478 | _m_ bank1,4 479 | _m_ srambank,4 480 | _m_ mapperdata,32 481 | _m_ sramwptr,4 482 | 483 | _m_ biosbase,4 484 | _m_ rombase,4 485 | _m_ romnumber,4 486 | _m_ emuflags,4 @NOT ACTUALLY USED! 487 | 488 | _m_ rommask,4 489 | _m_ rammask,4 490 | 491 | _m_ cartflags,1 492 | _m_ sramsize,1 493 | _m_ ,2 494 | @io.s (wram_globals3) 495 | _m_ joy0state,1 496 | _m_ joy1state,1 497 | _m_ joy2state,1 498 | _m_ joy3state,1 499 | _m_ joy0serial,1 500 | _m_ ,1 501 | _m_ ,2 502 | 503 | @sgb.s (wram_globals4) 504 | _m_ packetcursor,4 505 | _m_ packetbitcursor,4 506 | _m_ packetstate,1 507 | _m_ player_turn,1 508 | _m_ player_mask,1 509 | _m_ sgb_mask,1 510 | 511 | _m_ update_border_palette,1 512 | _m_ autoborder,1 513 | _m_ autoborderstate,1 514 | _m_ borderpartsadded,1 515 | _m_ sgb_hack_frame,4 516 | _m_ auto_border_reboot_frame,4 517 | _m_ lineslow,1 518 | _m_ ,1 519 | _m_ ,1 520 | _m_ ,1 521 | 522 | @gbz80.s (wram_globals5) 523 | _m_ fiveminutes_,4 524 | _m_ sleeptime_,4 525 | _m_ dontstop_,1 526 | _m_ hackflags,1 527 | _m_ hackflags2,1 528 | _m_ ,1 529 | @lcd.s (wram_globals6) 530 | _m_ FF41_R_function,4 531 | _m_ FF41_R_vblank_function,4 532 | _m_ vram_packet_dest,4 533 | _m_ vram_packet_source,4 534 | 535 | _m_ FF41_PC,4 536 | _m_ FF41_handler,4 537 | _m_ FF41_PC_2,4 538 | _m_ FF41_handler_2,4 539 | _m_ FF41_PC_3,4 540 | _m_ FF41_handler_3,4 541 | _m_ FF41_PC_4,4 542 | _m_ FF41_handler_4,4 543 | 544 | _m_ FF44_PC,4 545 | _m_ FF44_handler,4 546 | _m_ FF44_PC_2,4 547 | _m_ FF44_handler_2,4 548 | 549 | @gbz80.s (wram_globals7) 550 | _m_ xgb_ram,0x2000 551 | _m_ xgb_hram,0x80 552 | 553 | 554 | 555 | @---------------------------------------------------------------------------- 556 | @IRQ_VECTOR EQU 0xfffe ; IRQ/BRK interrupt vector address 557 | @RES_VECTOR EQU 0xfffc ; RESET interrupt vector address 558 | @NMI_VECTOR EQU 0xfffa ; NMI interrupt vector address 559 | @-----------------------------------------------------------cartflags 560 | MBC_RAM = 0x01 @ram in cart 561 | MBC_SAV = 0x02 @battery in cart 562 | MBC_TIM = 0x04 @timer in cart 563 | MBC_RUM = 0x08 @rumble in cart 564 | MBC_TIL = 0x10 @tilt in cart 565 | 566 | @-----------------------------------------------------------hackflags 567 | USEPPUHACK = 1 @use $2002 hack 568 | CPUHACK = 2 @don't use JMP hack 569 | @? EQU 16 570 | @FOLLOWMEM EQU 32 ;0=follow sprite, 1=follow mem 571 | 572 | @bits 8-5=scale type 573 | 574 | @bits 16-31=sprite follow val 575 | 576 | @---------------------------------------------------------------------------- 577 | CYC_SHIFT = 4 578 | CYCLE = 1<