[script] Add draw_image
- This command draws an image from data already loaded from tape. - Also added a comment to another command.
This commit is contained in:
parent
e01c51bbc6
commit
1ded375e60
|
|
@ -0,0 +1,502 @@
|
|||
## 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.
|
||||
|
||||
|
|
@ -60,6 +60,8 @@ var Instructions []*Instruction = []*Instruction{
|
|||
&Instruction{ 0x9A, 0, 0, 0, false, ""},
|
||||
&Instruction{ 0x9B, 0, 0, 0, false, "halt"},
|
||||
&Instruction{ 0x9C, 0, 0, 0, false, "toggle_44FE"},
|
||||
|
||||
// Waits for data from the tape then jumps into 0x9E code
|
||||
&Instruction{ 0x9D, 2, 0, 0, false, "something_tape"},
|
||||
|
||||
// Calls 0xEB draw_overlay. Draws the whole screen from data previously
|
||||
|
|
@ -206,7 +208,13 @@ var Instructions []*Instruction = []*Instruction{
|
|||
&Instruction{ 0xDD, 5, 0, 0, false, "fill_box"},
|
||||
|
||||
&Instruction{ 0xDE, 3, 0, 0, false, ""},
|
||||
&Instruction{ 0xDF, 3, 0, 0, false, ""},
|
||||
|
||||
// ArgA: ??
|
||||
// ArgB: X (tile coords)
|
||||
// ArgC: Y (tile coords)
|
||||
// Draws an image on top of the background using data already
|
||||
// loaded from *somewhere*. (seen using data from tape)
|
||||
&Instruction{ 0xDF, 3, 0, 0, false, "draw_image"},
|
||||
|
||||
// Divide and return remainder
|
||||
&Instruction{ 0xE0, 2, 0, 1, false, "modulo"},
|
||||
|
|
|
|||
Loading…
Reference in New Issue