SRAM Map
BS-X uses a 32kb battery-backup SRAM. This is the BS-X SRAM Map. Everything is Little Endian, unless said otherwise. In the Memory Map, it's 10-17:5000-5FFF.
Offset - Size (Bytes) - Description
[Bank 0x10 - Dedicated to BS-X]
$0000 - 0x02 - Always $4753 (String "SG")
$0002 - 0x02 - Reversed Checksum \ Checksum of Banks 0x10-0x12
$0004 - 0x02 - Checksum /
$0006 - 0x14 - Name (Shift-JIS)
$001C - 0x02 - Gender (0 = Boy, more than 0 = Girl)
$001E - 0x06 - Money
$0024 - 0x02 - Number of Items
$0026 - 0x44 - Item Entries (4 bytes each, see Item Entry)
$006A - 0x8F0 - Custom Item Data
$095A - 0x02 - Remaining Time of Sprint Shoes
$095C - 0x02 - Amount of Sprint Shoes
$095E - 0x02 - Remaining Calls with Telephone Card (minus 1)
$0960 - 0x02 - Amount of Telephone Cards
$0962 - 0x02 - Amount of Transfer Devices
$0964 - 0x02 - Amount of Fishing Rods
$0966 - 0x02 - Amount of Secret Club Cards
$0968 - 0x02 - Arrow Cursor Design Select (0x0000 to 0x0005)
$096A - 0x03 - Frame Design 24-bit Pointer
$096D - 0x03 - Color Scheme 24-bit Pointer
$0970 - 0x01 - Got 500G from Mr. Money
$0971 - 0x01 - Got 1000G from Mr. Money
$0972 - 0x01 - Got 5000G from Mr. Money
$0973 - 0x01 - Got Red Ball
$0974 - 0x2C8 - BIOS Function Hooks
$0C3C - 0x64 - BIOS Reset Function
$0CA0 - 0x100 - BIOS Script Bytecode Handlers
$0DA0 - 0x260 - Unused/Reserved
[Bank 0x11 - Reserved for Saves and BS-X Updates]
$1000 - 0x3A0 - Reserved for BS-X BIOS Function Updates
$13A0 - 0xC60 - Reserved for Saves
[Bank 0x12 - Reserved for Saves]
$2000 - 0x1000 - Reserved for Saves
[Bank 0x13 - Backup of Bank 0x10]
[Bank 0x14 - Backup of Bank 0x11]
[Bank 0x15 - Backup of Bank 0x12]
[Bank 0x16 - General Purpose]
$6000 - 0x1000 - General Purpose
[Bank 0x17 - General Purpose]
$7000 - 0x1000 - General Purpose
Item Entry
Byte Format:
TT AAAAAA
TT = Type (00 = ROM, 01 = RAM)
AAAAAA = Address to Item Data (Little Endian)
ROM Items
Pointer - Item
88C229 - Transfer Device
88C2B8 - Telephone Card (5)
88C347 - Telephone Card (4)
88C3D6 - Telephone Card (3)
88C465 - Telephone Card (2)
88C4F4 - Telephone Card (1)
88C583 - Fishing Rod
88C612 - Express Ticket
88C6A1 - Regular Ticket
88C630 - Bus Ticket
88C7BF - Taxi Ticket
88C84E - Rental Car Ticket
88C8DD - Sprint Shoes
88C96C - Soap Shoes
88C9FB - Whale Bait
88CA8A - Dolphin Bait
88CB19 - Ricefish Bait
88CBA8 - Genderbender
88CC37 - Male Symbol
88CCC6 - Female Symbol
88CD55 - Select Club Card
88CDE4 - Name Frog
88CE73 - Frame Frog
88CF02 - Color Frog
88CF91 - Arrow Frog
BIOS Function Hooks
It's now known that Nintendo actually changes these for updates in SRAM. Taken from nocash's documentation, added the hook instructions.
Hooks
$105974: rtl - boot_hook
$105978: rtl - nmi_hook
$10597C: rtl - irq_vector
$105980: rtl - download_start_hook
$105984: rtl - file_start_hook
$105988: rtl - whatever_hook
SRAM Vectors
$10598C: jml $80C2AD - detect_receiver
[Out: If Z flag set, Satellaview is NOT found]
$105990: jml $80C2DF - powerdown_receiver (port_2194_clr_bit0)
$105994: jml $80C2E8 - port_2196_test_bit1 [Out: $2196.bit1]
Copy Data Queue to RAM Buffer
$105998: jml $80C2F0 - set_port_218B_and_218C_to_01h
$10599C: jml $80C303 - set_port_218C_to_00h
$1059A0: jml $80C30B - read_data_queue (Max 0x14 packets)
[Out: $7E9A20 - Packet Prefixes, $7E9A34 - Packet Data]
Port 2199h (serial port 2) (maybe satellite audio related)
$1059A4: jml $80C36D - init_port_2199_registers
(Sends: 0008 - 8800 - 8001 - 0402 - 0003 - 0804 - 0005 - 7006)
$1059A8: jml $80C399 - send_array_to_port_2199
[In: $7E0000 - Array of 7 bytes to send]
$1059AC: jml $80C3AF - recv_3x8bit_from_port_2199
[Out: $7E0000 - Array of 3 bytes received]
$1059B0: jml $80C3D6 - send_16bit_to_port_2199 [In: A]
$1059B4: jml $80C403 - recv_8bit_from_port_2199 [Out: A]
Port 2198h (serial port 1) (unused/expansion or so)
$1059B8: jml $80C41C - port_2198_send_cmd_recv_multiple_words
[In: A | 0x80, Out: $7E0000, 10 bytes]
$1059BC: jml $80C459 - port_2198_send_cmd_recv_single_word
[In: A | 0x80, Out: A]
$1059C0: jml $80C488 - port_2198_send_cmd_send_verify_multiple_words
$1059C4: jml $80C4AD - port_2198_send_cmd_send_verify_single_word
$1059C8: jml $80C4C2 - port_2198_send_cmd_send_single_word
$1059CC: jml $80C4DF - port_2198_send_10h_send_verify_single_word
$1059D0: jml $80C50A - port_2198_send_cmd_verify_FFFFh
$1059D4: jml $80C529 - port_2198_send_20h_verify_FFFFh
$1059D8: jml $80C546 - recv_2198_skip_x BUGGED!
$1059DC: jml $80C55D - recv_2198_want_x
$1059E0: jml $80C56B - send_30h_to_port_2198
$1059E4: jml $80C579 - send_00h_to_port_2198
$1059E8: jml $80C589 - send_8bit_to_port_2198
$1059EC: jml $80C5AE - wait_port_2198_bit7
Forward Data Queue from RAM to Target
$1059F0: jml $80D2E6 - forward_data_queue_to_target
$1059F4: jml $80D31C - forward_queue_to_wram
$1059F8: jml $80D4DA - forward_queue_to_psram
$1059FC: jml $80D69E - forward_queue_to_entire_flash
$105A00: jml $80D6C7 - forward_queue_to_entire_flash_type1
$105A04: jml $80D94A - forward_queue_to_entire_flash_type2
$105A08: jml $80D6C7 - forward_queue_to_entire_flash_type3
$105A0C: jml $80D6C7 - forward_queue_to_entire_flash_type4
$105A10: jml $80DBB4 - forward_queue_to_flash_sectors
$105A14: jml $80DBDD - forward_queue_to_flash_sectors_type1
$105A18: jml $80DE33 - forward_queue_to_flash_sectors_type2
$105A1C: jml $80DBDD - forward_queue_to_flash_sectors_type3
$105A20: jml $80DBDD - forward_queue_to_flash_sectors_type4
$105A24: jml $80E0E5 - forward_queue_to_channel_map ;with 5-byte frame-header
$105A28: jml $80E249 - forward_queue_to_town_status
FLASH Files
$105A2C: jml $80CA3F - scan_flash_directory (Limited Starts Check here)
$105A30: jml $80CB11 - allocate_flash_blocks
$105A34: jml $80CB63 - .. prepare exec / map file or so [Out: C flag set = Error]
$105A38: jml $80CC6B - verify_file_checksum
$105A3C: jml $80CCD0 - get_flash_file_header_a
$105A40: jml $80CCE4 - delete_flash_file_a
$105A44: jml $80CD20 - get_flash_file_header_5A
$105A48: jml $80CDAF - copy_file_header
$105A4C: jml $80CDC6 - search_test_file_header, out:[57]
$105A50: jml $80CE05 - test_gamecode_field
$105A54: jml $80CE1D - copy_file_to_psram
$105A58: jml $80CE6F - get_file_size
$105A5C: jml $80CE92 - decrease_limited_starts
Memory Mapping
$105A60: jml $80BAAE - map_flash_as_data_file (for non-executable data-files?)
$105A64: jml $80BADD - map_psram_as_data_file (for non-executable data-files?)
$105A68: jml $80BB0C - .. mapping and copy 512Kbytes ?
$105A6C: jml $80BB84 - map_flash_for_rw_access
$105A70: jml $80BBB1 - map_flash_for_no_rw_access
$105A74: jml $80BBDE - map_flash_for_reloc_to_psram
$105A78: jml $80BC0B - .. mapping (unused?)
$105A7C: jml $80BC2C - map_flash_as_lorom_or_hirom
$105A80: jml $80BC84 - execute_game_code
$105A84: jml $80BCB0 - .. map_psram_for_streaming ???
$105A88: jml $80BCD9 - map_psram_as_lorom_or_hirom
$105A8C: jml $80BD35 - .. copy 256Kbytes... (PSRAM)
FLASH Memory
$105A90: jml $80BD6C - flash_abort
$105A94: jml $80BD95 - flash_abort_type1
$105A98: jml $80BD9C - flash_abort_type2
$105A9C: jml $80BD95 - flash_abort_type3
$105AA0: jml $80BD95 - flash_abort_type4
$105AA4: jml $80BDAF - flash_erase_entire
$105AA8: jml $80BDD8 - flash_erase_entire_type1
$105AAC: jml $80BE27 - flash_erase_entire_type2
$105AB0: jml $80BDD8 - flash_erase_entire_type4 ;4!
$105AB4: jml $80BE03 - flash_erase_entire_type3
$105AB8: jml $80BE50 - flash_test_status ERASE-PROGRESS
$105ABC: jml $80BE7F - flash_test_status_type1
$105AC0: jml $80BEE7 - flash_test_status_type2
$105AC4: jml $80BE7F - flash_test_status_type4 ;4!
$105AC8: jml $80BEA4 - flash_test_status_type3
$105ACC: jml $80BF33 - flash_erase_first_sector
$105AD0: jml $80BF5C - flash_erase_first_sector_type1
$105AD4: jml $80BF82 - flash_erase_first_sector_type2
$105AD8: jml $80BF5C - flash_erase_first_sector_type3
$105ADC: jml $80BF5C - flash_erase_first_sector_type4
$105AE0: jml $80BFC0 - flash_erase_next_sector
$105AE4: jml $80BFEF - flash_erase_next_sector_type1
$105AE8: jml $80C039 - flash_erase_next_sector_type2
$105AEC: jml $80BFEF - flash_erase_next_sector_type3
$105AF0: jml $80BFEF - flash_erase_next_sector_type4
$105AF4: jml $80C0B9 - flash_write_byte
$105AF8: jml $80C0EE - flash_write_byte_type1
$105AFC: jml $80C114 - flash_write_byte_type2
$105B00: jml $80C0EE - flash_write_byte_type3
$105B04: jml $80C0EE - flash_write_byte_type4
$105B08: jml $80C157 - flash_get_free_memory_size
$105B0C: jml $80C177 - flash_get_and_interprete_id
$105B10: jml $80C1C5 - flash_get_id
$105B14: jml $80C248 - flash_init_chip
$105B18: jml $80C277 - flash_init_chip_type1
$105B1C: jml $80C2AB - flash_init_chip_type2
$105B20: jml $80C2AB - flash_init_chip_type3
$105B24: jml $80C277 - flash_init_chip_type4
Satellite Directory
$105B28: jml $80CEFB - apply_satellite_directory
$105B2C: jml $80D024 - directory_find_8bit_folder_id
[In: A, Out: C flag set = Error, $7E004E = Address?]
$105B30: jml $80D0BE - directory_find_32bit_file_channel
[In: $7E13E3 = 32-bit Software Channel]
[Out: C flag set = Error, $7E004E = File Address at Software Channel]
$105B34: jml $80D173 - test_if_file_available
[In: $7E004E = File Address, Out: C flag set = Error]
$105B38: jml $80D1A6 - download_file_and_include_files
[In: $7E004E = Main File Address at Software Channel]
$105B3C: jml $80D238 - directory_find_32bit_bugged
Misc...
$105B40: jml $80F1EB - .. initialize stuff on reset
$105B44: jml $80F231 - download_nmi_handling (with download_callback etc.)
$105B48: jml $80F273 - download_nmi_do_timeout_counting
$105B4C: jml $80F2AB - nmi_do_led_blinking
$105B50: jml $80F2DC - mark_flash_busy
$105B54: jml $80F2E7 - mark_flash_ready
$105B58: jml $80F2F2 - mute_radio_audio (set_port_2197_bit7)
$105B5C: jml $80F303 - unmute_radio_audio (clr_port_2197_bit7)
$105B60: jml $80F314 - detect_receiver_and_port_2196_test_bit1
$105B64: jml $80F334 - init_flash_chip_with_err_29h
$105B68: jml $80F355 - init_flash_chip_with_err_2Ah
$105B6C: jml $80F376 - detect_receiver_and_do_downloads
$105B70: jml $80E7A3 - do_download_function
$105B74: jml $80E806 - retry_previous_download
$105B78: jml $80E93E - set_target_id_and_search_channel_map
$105B7C: jml $80E967 - apply_target_for_download
$105B80: jml $80E9C4 - clear_queue_and_set_13D1_13D2
$105B84: jml $80E4D4 - flush_old_download ;[218C]=0, clear some bytes
Invoke Download Main Functions
$105B88: jml $80E4E8 - download_to_whatever (BUGGED)
$105B8C: jml $80E542 - download_channel_map
$105B90: jml $80E589 - download_welcome_message
$105B94: jml $80E5D9 - download_snes_patch
$105B98: jml $80E629 - download_town_status
$105B9C: jml $80E684 - download_town_directory
$105BA0: jml $80E6DF - download_to_memory
Download sub functions
$105BA4: jml $80E774 - add_download_array
$105BA8: jml $80E786 - wait_if_too_many_downloads
$105BAC: jml $80EA28 - do_download_callback
$105BB0: jml $80EA3C - dload_channel_map_callback_1
$105BB4: jml $80EA55 - dload_channel_map_callback_2
$105BB8: jml $80EA8C - dload_welcome_message_callback
$105BBC: jml $80EA98 - dload_snes_patch_callback
$105BC0: jml $80EB07 - dload_town_status_callback_1
$105BC4: jml $80EBE7 - dload_town_status_callback_2
$105BC8: jml $80EC08 - dload_town_directory_callback_1
$105BCC: jml $80EC2B - dload_town_directory_callback_2
$105BD0: jml $80EC35 - .. flash status
$105BD4: jml $80EC42 - dload_to_mem_wram_callback1 ;\
$105BD8: jml $80EC42 - dload_to_mem_wram_callback2 ;
$105BDC: jml $80EC54 - dload_to_mem_psram_callback1 ;
$105BE0: jml $80ECA2 - dload_to_mem_psram_callback2 ; dload_to_memory_callbacks
$105BE4: jml $80ECED - dload_to_mem_entire_flash_callback1 ;
$105BE8: jml $80ECED - dload_to_mem_entire_flash_callback2 ;
$105BEC: jml $80ED27 - dload_to_mem_free_flash_callback1 ;
$105BF0: jml $80ED27 - dload_to_mem_free_flash_callback2 ;/
$105BF4: jml $80ED61 - dload_to_mem_entire_flash_callback_final
$105BF8: jml $80EE63 - dload_to_mem_free_flash_callback_final
$105BFC: jml $80EEDE - reset_interpreter_and_run_thread_958000h
$105C00: jml $80EEFE - verify_channel_map_header
$105C04: jml $80EF2E - raise_error_count_check_retry_limit
$105C08: jml $80EF5D - search_channel_map
$105C0C: jml $80EFD6 - post_download_error_handling
$105C10: jml $80F1B9 - .. erase satellite info ?
APU Functions
$105C14: jml $8096F4 - apu_flush_and_clear_queues
$105C18: jml $809710 - apu_flush_raw
$105C1C: jml $809720 - apu_message
$105C20: jml $8097A6 - apu_nmi_handling
$105C24: jml $8098B2 - apu_upload_extra_thread
$105C28: jml $80995A - apu_upload_curr_thread
$105C2C: jml $8099DF - apu_enable_effects_music_b
$105C30: jml $8099F4 - apu_enable_effects_music_a
$105C34: jml $809A09 - apu_mute_effects_and_music
$105C38: jml $809A1E - apu_enable_effects_only
Reset
$105C3C: reboot_bios (this one works even when BIOS=disabled or WRAM=destroyed)
BIOS Reset Function
reboot_bios:
PEA $8000 ;Push $8000 to the stack
PLB ;Pull $00 from stack to Data Bank Register
PLB ;Pull $80 from stack to Data Bank Register
REP #$30 ;--Set 16-bit Accumulator and Index Registers
LDA #$5347
STA $0661
EOR #$FFFF
STA $0663
SEP #$20
LDA #$00
STA $4200 ;Force Blank
CLI
STA $055000 ;PSRAM Location Bit0 = 0
STA $065000 ;PSRAM Location Bit1 = 0
STA $045000 ;Disable PSRAM in Fast Memory Area ($80-$FF)
STA $015000 ;Disable Memory Pack IRQ Ready
STA $0C5000 ;Disable Memory Pack Write
STA $0D5000 ;Disable EXTMEM Write?
LDA #$80
STA $025000 ;Set Memory Map to HiROM
STA $035000 ;Enable PSRAM in Slow Memory Area ($00-$7D)
;Sets PSRAM to $00-07:$8000-FFFF (Unused)
; and $40-47:$0000-FFFF
; and $20-3F:$6000-7FFF
STA $075000 ;Enable BIOS ROM in Slow Memory Area ($00-3F:$8000-FFFF)
STA $085000 ;Enable BIOS ROM in Fast Memory Area ($00-3F:$8000-FFFF)
STA $0E5000 ;--Apply MCC Changes
LDX #$000B
reboot_bios_copy_loop:
LDA $BD61,X ;Copy 11 byte function from $80BD61 from BIOS ROM (DB = $80)
STA $001400,X ;to $001400
DEX
BPL reboot_bios_copy_loop
JML $001400 ;Jump to copied function
code_80BD61:
LDA #$80
STA $0E5000 ;Apply MCC Changes (why?)
NOP
NOP
JMP ($FFFC) ;Jump to RESET vector