Seiken Densetsu 3:Threading System

From Data Crystal
Jump to navigation Jump to search

Most of the game's code is executed inside its threading system. A thread is basically an execution context. Each thread has its own direct page memory and stack memory (between 7e:0000 and 7e:1bff). Threads can send messages to each other, and when a thread wants to receive a message, the system takes that opportunity to switch threads. Since return addresses are part of the stack, the system switches to the proper stack pointer and returns to where that thread left off.

The thread system code is in bank C0, between 495b and roughly 62ed. When looking at game ASM you'll often see variations on the following pattern:

C1/2A44:	lda #$80		; Message Type
C1/2A46:	jsr $C00520		; Create new message of Type A
C1/2A4A:	lda #$8E
C1/2A4C:	sta $0004,X		; First param. Often an opcode.
C1/2A4F:	pla 
C1/2A50:	sta $0005,X		; Additional param
C1/2A53:	lda $22
C1/2A55:	sta $0006,X		; Additional param
C1/2A58:	lda $7E2008		; A specific Thread ID
C1/2A5C:	jsr $C00528		; Send message X to Thread A

Thread IDs for permanent threads are stored at 7e:2000-7e:2008 (one byte each). Some threads live forever during gameplay, and other threads are temporary and complete an operation and are then recycled.

Looking at this code, it's triggering something, but there's no way to determine what it's actually doing without just observing the game behavior or finding the code that the other thread executes and seeing how it responds to a message with a code of #8e. The documentation for each thread will make that easier.

Threads are created by calling c00440 (c04d70). The long address to the thread params are passed in via A and X. These parameters specify the thread's start location, type, and priority. Type is used when code sends a message to all threads matching a certain type. Priority determines how quickly the thread gets switched to, with lower values being faster.


Permanent Threads

Thread ID Memory Location Thread ID Name
n/a 2 Input/Monitor Thread
7e2003 3 Audio/Clock Thread
7e2001 4 Thread 4
7e2000 5 Thread 5
7e2002 6 Thread 6
7e2007 7 Thread 7
7e2008 8 Thread 8
7e2006 9 Thread 9
7f0386 a Thread 0A
7e33f1 b Character Overlay UI Thread

Audio/Clock Thread

All audio-related code as well as incrementing the game clock (day/night cycle). Operations 00-2c are audio commands.

Thread ID 3
DP/Stack Memory 0100
Code Bank C0
Parent Thread 1
Priority 80
Type 10
Thread Params Location c0ff80
Start Location c0b84d

Direct Page:

Offset Use
$00-01 Current message
$02 A thread ID

Operations:

Op Code Routine Address Description Parameters
00 bc23 Play sound effect [5]: Effect id, [6]: Pan
80 b953 Pause game clock (ref counted) None
81 b96a Resume game clock (ref counted) None
c9 b97d Respond with 8:ca or 8:cb depending on $02 None
cc b9ac If sender == $02, clear $02 None
c6 ba08 If $06[msg[5][3]] == 0, $04++. $06[msg[5][3]] = sender. [5-6]: Unknown pointer
c7 ba25 If $06[msg[5][3]] != 0, $04-- and $06[msg[5][3]] = 0. [5-6]: Unknown pointer
c8 ba3f Related to $04 None
e3 b9c6 Allocate buffer. Respond with 8:0:bufferAddress [5-6]: Requested buffer size
f8 b9ef Get 1c06, returned as 8:1c06 None

Character Overlay UI Thread

Draws the UI for each character that is displayed during gameplay.

Thread ID B
DP/Stack Memory 0900
Code Bank C4
Parent Thread 6
Priority 70
Type 0
Thread Params Location c462db
Start Location c461a2

Direct Page:

Offset Use
$04-05 (character selector? 0-2)
$20-21 Draw location 1
$22-23 Draw location 2
$24-25 Draw location 3
$26-27 Character addr 1
$28-29 Character addr 2
$2a-2b Character addr 3
$2e Bitwise (bit 1 checked at 5a09)
$42 (Counter)
$44 Character count
$46 Current sender
$48 AT mode for character 1
$49 AT mode for character 2
$4a AT mode for character 3

Operations:

Op Code Routine Address Description Parameters
1 5a3d Clear, calculate, redraw character UIs None
2 614c Clear all UIs, respond with Type8 msg None
3 5a4b Prep and draw Char UIs if 2e bit 1 is set None
4 5a09 ?
5-8 5a5b Do nothing None
9 60ee Set character address and redraw all [5]: Character index
a 612b Remove character 3 from UI None
b 60af Set AT mode for character, redraw if necessary [5]: Character thread ID
c 60b4 Clear AT mode for character, redraw if necessary [5]: Character thread ID


Temporary/Transient Threads

Graphics Loader

Loads various graphics into VRAM.

Code Bank C4
Priority 50
Type 0
Thread Params Location c4681b
Start Location c4679f

Operations:

Op Code Routine Address Description Parameters
0 63be Load overlay UI and battle-related graphics, respond with Type8 message None
1 631e Load fullscreen menu background graphics None
2 62e9 Load window background graphics [5]: Window style, [6-7]: Buffer to use
3 65d3 ? None