go-studybox/script/docs/instructions.md

503 lines
9.0 KiB
Markdown

## 0x80 Play Beep
Stack Arguments: 0
Inline Arguments: 0
Vars used:
Byte_0493
Play's an audible beep on the Square 1 channel.
## 0x81 Halt
Stack Arguments: 0
Inline Arguments: 0
Vars used:
N/A
Infinite loop that does not return.
## 0x82 Tape NMI Shenanigans
Stack Arguments: 0
Inline Arguments: 0
Vars:
Byte_E0_TapeCtrl_Cache
Byte_EE
Byte_F2
Byte_0740
Byte_07EF
Byte_07F3
JSRs:
L2706_SetupNMI_ED00_LongJump
L2721_TurnOnNMI_LongJump
L2724_TurnOffNMI_LongJump
L2742
## 0x83 Tape Wait
Stack Arguments: 0
Inline Arguments: 0
Vars:
Byte_0740
JMPs to `L1329_WaitOn_EE`
## 0x84 Jump
Stack Arguments: 0
Inline Arguments: 1 Word
Vars:
Code_Pointer
Argument_A
Updates the script pointer to the inline address and continues script execution
from the new address.
## 0x85 Call
Stack Arguments: 0
Inline Arguments: 1 Word
Vars:
Code_Pointer
Argument_A
Stack_Pointer
Pushes return address to the stack and performs a Jump to the inline script
address.
## 0x86 Return
Stack Arguments: 0 (1 Word, implied)
Inline Arguments: 0
Vars:
Stack_Pointer
Code_Pointer
Remove a script address from the stack and update the `Code_Pointer` to it
before continuing execution.
## 0x87 Loop
Stack Arguments: 0 (4 implied)
Inline Arguments: 0
Args manually pulled from stack:
- Limit
- Increment
- LoopVar
- LoopEntry
ArgA `Stack_Pointer-6`
ArgB `(ArgD)`
ArgC `Stack_Pointer-2`
ArgD `Stack_Pointer-4`
ArgE `ArgA+1`
Vars:
Argument_A
Argument_B
Argument_C
Argument_D
Argument_E
Stack_Pointer
JSRs:
Handler_CB_Sum
Handler_C7_LessThan
JMPs to `L49CD_LessThan`
## 0x88 Play Sound
Stack Arguments: 32 bytes (string copied to `$0700`)
Inline Arguments: 0
Plays a short SFX defined by a string.
Vars:
Pointer_A0
Pointer_A2
Byte_0494
Byte_0495
Byte_0496
Byte_0497
Byte_0498
Byte_0499
Byte_04AC_AudioState
Byte_04AD
Vars inside `L5C18_CopyPtrA0PtrA2`:
Byte_0490_PtrA0Len
Vars inside `L5A6F_DecodeAudioString_EntryPoint`:
Pointer_A2
Byte_04AC_AudioState
Word_049A+0 (current channel ID)
Word_049A+1 (current channel mask)
Byte_0497 Byte_0498 Byte_0499
enable byte for each channel. RTS if != 1 on entry
written to with value of Byte_04B3
Byte_0494 Byte_0495 Byte_0496
Pointer_A2 low for channel. looks like it's updated after reading a
string.
Byte_049F Added to note lookup index; used with O stuff?
Byte_04B1 octave? value from Table_04A6
Byte_04B2 T value
Byte_04B3 = Byte_04B1 * Byte_04B2
Table_049C Y#
Table_04A0 V##
Table_04A3 M#
Table_04A6 ?? note related. octave? value after letter
Table_04A9 O#
Table_04AE T#
Table_B391 G??
JSRs:
L5C08_DataLen_A0
L5C18_CopyPtrA0PtrA2
L5CC5_LongDelay
L5A6F_DecodeAudioString_EntryPoint
L5A8F_DecodeAudioString (if audio is turned on)
L5C42 (for weird chars?)
Hard-coded addresses:
$0700 (Pointer_A0)
$0420 (Pointer_A2)
$0441 (Pointer_A2)
$0462 (Pointer_A2)
Copies data currently at `$0700` to three locations (`$0420`, `$0441`, `$0462`)
### String format
Three channels are encoded in this string, separated by a colon (`:`). The
string consists of letter and number pairs. The order of the individual pairs
in the overal string don't seem to matter.
M# Loop & Constant volume
number is 0 or 1.
V## Volume
number between 0 and 15, inclusive
Y# Duty
number between 0 and 3, inclusive
T# ?? $4001/$4006?
number between 1 and 9, inclusive (verify this)
O# Note related (timer low/high stuff)
number between 1 and 6, inclusive
A#-G# Notes and octaves?
number between 0 and 10, inclusive
## 0x89
Stack Arguments: 3
Inline Arguments: 0
## 0x8A Pop String to Address
Stack Arguments: 0
Inline Arguments: 1 Word
Removes 32 bytes from the stack and writes them starting to the inline address.
## 0x8B
## 0x97
Arguments: 2
ArgA
ArgB
Vars:
Byte_0740
Byte_44FE
Byte_4598 = Argument_B+0
Byte_44FD
Argument_A
Array_44FB+2 ($44FD)
JSRs:
L5592_CheckForZero
Conditionally sets up NMI stuff depending on byte $0740
If ArgA >= 3, setup some more stuff
## 0xA9
Arguments: 1
ArgA
Some sort of nametable restore operation?
Writes smaller updates to the nametable for animation purposes.
## 0x9D Something Tape (draw screen?)
Arguments: 2
ArgA -> X
AgrB
Vars:
Byte_44FE
Array_44F8, X
Array_44CF, X
Array_457A, X
If ArgB != 0
ldx ArgA
lda #1
sta Array_44F8, X
sta Array_44CF, X
lda #0
Array_457A, X
else, check for zero from $44F9 through $44FC.
if non-zero, store #1 into `Byte_FF4E` and return.
else:
ldx ArgA
lda #1
sta Array_44F8, X
lda #0
sta Byte_44F8
Then wait for `Array_44F8, X` to become zero. We're waiting for the IRQ to
finish writing data from the tape to RAM.
After this, jump into opcode `0x9E` after the argument parsing to draw a
screen.
## 0x9E Draw And Show Screen
Arguments: 2
ArgA
ArgB
If ArgB == 0, clear out a bunch of arguments and call `Handler_DD`. Clears
`Byte_44FE` afterwards and returns.
If ArgB != 0, make sure data has been loaded off the tape and is ready to draw.
This is done by checking `Word_FF49, X` for a value of 1. If 1, increment it
and store it in `Byte_44FE` before returning. Continue otherwise.
### Drawing
lda #0
sta Byte_0750
sta Byte_4579
sta Byte_457A ("Array_457A")
lda ArgA
sta Byte_4C
### Data layout
Data in RAM, starting at CPU address $5000
$5000 Word offset to palette data. Added to #$5004.
$5002 Word
$5004 Byte loop counter apparently?? adds #6 to #$5004 this many times in a
pointer. additional header data?
// generic image header data
$5005 Byte Width (data row len (tile data len))
$5006 Byte Height (row count (title count))
Data length = Width*Height (stored in Word_61 and Word_6AFE)
$5007 Word data length? offset offset to attr data?
$5008 Byte X/Y coords
$5009 Byte X/Y coords
$500B Data start
## 0xBB Push String / Push Data
Stack Arguments: 0
Inline Arguments: 32 bytes max (NULL terminated)
Push a NULL terminated string to the stack. This opperation will increment the
stack pointer by 32 bytes, always. Even if more than 32 bytes are pushed to
the stack. The code pointer is properly incremented, so long as there is a
NULL byte within 255 bytes of the start of data.
## 0xC1 Jump Switch
Stack Arguments: 1
Inline Arguments: 3+
ArgA
## 0xC5 Equal
If ArgA == ArgB
push 1 to stack
If ArgA != ArgB
push 0 to stack
## 0xC6 Not Equal
Stack Arguments: 2
Stack Result: 1
If ArgA != ArgB
push 1 to stack
If ArgA == ArgB
push 0 to stack
## 0xC7 Less Than
If ArgA < ArgB
push 1 to stack
If ArgA >= ArgB
push 0 to stack
## 0xC8 Less Than or Equal
If ArgA <= ArgB
push 1 to stack
If ArgA > ArgB
push 0 to stack
## 0xC9 Greater Than
If ArgA > ArgB
push 1 to stack
If ArgA <= ArgB
push 0 to stack
## 0xCA Greater Than or Equal To
If ArgA >= ArgB
push 1 to stack
If ArgA < ArgB
push 0 to stack
## 0xCB Add
ArgA = ArgA + ArgB
## 0xCC Subtract
ArgA = ArgA - ArgB
## 0xCD Multiply
ArgA-ArgB = ArgA * ArgB
## 0xCE Signed Divide
ArgA = ArgA / ArgB
## 0xCF Negate
ArgA = 0 - ArgA
## 0xD1 Controller Stuff
Stack Arguments: 2
Inline Arguments: 0
Vars:
Argument_C+0 = Argument_A+0
Argument_A = Word_B1 + Argument_B
Argument_B
# 0xD4 Set Cursor Location
Stack Arguments: 3
Some sort of setup for 0xFE Draw Rom Character.
Byte_0606 = ArgA
Byte_0604 = ArgB
Byte_0605 = ArgC
## 0xE0 Modulo
ArgA = ArgA % ArgB
# 0xE7 Draw Metasprite
Stack Arguments: 7
ArgA sprite ID? (read as byte, but high is used as temp) Some sort of list size or count (header count?)
This is used as a table lookup into a metasprite pointer table at $6980
ArgB (byte) X Coord
ArgC (byte) Y Coord
ArgD (byte?) Palette override. If positive, bottom two bits are used directly for palette index.
ArgE (byte) switch of some sort. sets X to $00 if zero, $20 if not zero
ArgF (byte) Sprite flip. Uses two middle bits of value (`%0001_1000`)
ArgG (byte) Extra args on HW stack??
Header data for metasprites. This location is pointed to by a table at $6980.
Width
Height
Count
Palette??
There is a table at $0140 that keeps track of sprite allocations. Each byte
corresponds to a hardware sprite and the value corresponds to a metasprite that
that hardware sprite is a part of.
# 0xFE Draw Rom Character
Stack Arguments: 4
Inline Arguments: 1 Word
Observed drawing a 1bpp kanji character taken from the SBX ROM charset.
Inline word seems to be an ID or index for the character to draw.