Block Types and helpers
In Regenerator 2000, every byte of the loaded binary is assigned a Block Type. This type tells the disassembly engine how to interpret that byte. You can change the Block Type for any region of memory using keyboard shortcuts (in Visual Mode or for the single line under the cursor).
The available Block Types are:
1. Disassemble Address (Flow Analysis)
- Shortcut: D
- Description: Starting from the current cursor address, simulated execution follows standard 6502 branches and jumps to discover all reachable execution paths. It traces relative branches and absolute jumps, queuing subroutine targets. As soon as it encounters an invalid opcode, it stops the current trace. All discovered ranges of valid instructions are converted into Code blocks!
- Use Case: When you encounter unmapped data bytes that you suspect are actually code, place the cursor on the entry point and press D. This is much more robust than manually selecting regions and pressing C because it will skip static data tables hidden between routines!
Note
Unconditional breaks like RTS or RTI will terminate the current segment trace. If there is dead code after
a return, it will remain unmapped (unless it is explicitly jumped to from somewhere else).
2. Code
- Shortcut: C
- Description: Interprets the bytes as MOS 6502/6510 instructions.
- Use Case: Use this for all executable machine code.
Example
3. Data Byte
- Shortcut: B
- Description: Represents data as single 8-bit values.
- Use Case: sprite data, distinct variables, tables, memory regions where the data format is unknown, etc.
Example
Fill Run Threshold
When a contiguous run of identical bytes exceeds the Fill run threshold (configurable in settings), they are grouped and exported using fill directives:
- 64tass:
.fill N, $XX - ACME:
!fill N, $XX - KickAssembler:
.fill N, $XX - ca65:
.res N, $XX
4. Data Word
- Shortcut: W
- Description: Represents data as 16-bit Little-Endian values.
- Use Case: Use for 16-bit counters, pointers (that shouldn't be analyzed as code references), or math constants.
Example
5. Address
- Shortcut: A
- Description: Represents data as 16-bit addresses. Unlike "Data Word", this type explicitly tells the analyzer that the value points to a location in memory.
- Use Case: Essential for Jump Tables. When you mark a table as "Address", Regenerator 2000 will create Cross-References (X-Refs) to the target locations, allowing you to see where indirect jumps land.
Example
6. PETSCII Text
- Shortcut: P
- Description: Interprets bytes as PETSCII text sequences.
- Use Case: Use for game messages, high score names, or print routines. The disassembler will try to group contiguous characters into a single string.
Example
7. Screencode Text
- Shortcut: S
- Description: Interprets bytes as Commodore Screen Codes (Matrix codes) text.
- Use Case: Use for data that is directly copied to Screen RAM ($0400). These values differ from standard PETSCII (e.g., 'A' is 1, not 65).
Example
8. Lo/Hi Address Table
- Shortcut: <
- Description: Marks the selected bytes as the Low / High address table. Must have an even number of bytes. The first half will be the lo addresses, the second half will be the hi addresses.
- Use Case: C64 games often split address tables into two arrays (one for Low bytes, one for High bytes).
Example
9. Hi/Lo Address Table
- Shortcut: >
- Description: Marks the selected bytes as the High / Low address table. Must have an even number of bytes. The first half will be the hi addresses, the second half will be the lo addresses.
- Use Case: C64 games often split address tables into two arrays (one for Low bytes, one for High bytes).
Example
10. Lo/Hi Word Table
- Shortcut: ,
- Description: Marks the selected bytes as the Low / High word table. Must have a size divisible by 4. The first half will be the lo words, the second half will be the hi words.
- Use Case: The C64 SID frequency table.
Example
11. Hi/Lo Word Table
- Shortcut: .
- Description: Marks the selected bytes as the High / Low word table. Must have a size divisible by 4. The first half will be the hi words, the second half will be the lo words.
- Use Case: The C64 SID frequency table.
Example
12. External File
- Shortcut: E
- Description: Treats the selected region as external binary data.
- Use Case: Use for large chunks of included binary data (like music SID files, raw bitmaps, or character sets) that
you don't want to clutter the main source file. These will be exported as
.binary "filename.bin"includes.
Example
13. Undefined
- Shortcut: ?
- Description: Resets the block to an "Unknown" state.
- Use Case: Use this if you made a mistake and want the Auto-Analyzer to take a fresh look at the usage of this region.
Example
14. Helpers for Immediate Mode instructions
Cycle Data Types for immediate mode instructions
- Shortcut: I / Shift+I
- Description: Cycles the current immediate mode instruction through the available representations (Hex, Decimal,
Binary):
- I: Cycles forward.
- Shift+I: Cycles backward.
- Use Case: Sometimes a decimal, or binary representation makes more sense than an hexadecimal one.
| Representation | Name |
|---|---|
lda #$d2 |
Hexadecimal |
lda #~$2d |
Inverse Hexadecimal |
lda #210 |
Decimal |
lda #-46 |
Inverse Decimal |
lda #%11010010 |
Binary |
lda #~%00101101 |
Inverse Binary |
Convert LDA/LDX/LDY vector instructions to lo/hi, or hi/lo addresses
- Shortcut: [ / ]
- Description: Quickly assigns a "lo/hi" or "hi/lo" address to the selection.
- [: For Lo/Hi Address.
- ]: For Hi/Lo Address.
- Use Case: When manually setting 16-bit pointers. See exmaple.
Example:
It is clear that $0314 / $0315 contains a vector.
Select the first 3 lines in the Dissasembly view, and press [.
lda #$80 ; $80 is the low part of $1480
sta $0314
lda #$14 ; $14 is the high part of $1480
sta $0315
; IRQ handler in address $1480
rti
And it will be converted to a "lo/hi" address, and it will look like:
; And the LDA #immediate_mode will be converted to an lo/hi address
lda #<p_1480
sta $0314
lda #>p_1480
sta $0315
; IRQ handler in address $1480
p_1480
rti
You can also revert the change by pressing:
- U to undo
- or press D to remove the hi/lo or lo/hi address, and represent it as hexadecimal again.
Organization Tools
Beyond data types, you can organize your view using Comments, Splitters, and Collapsing:
Comments
- Side Comment: ;
- Line Comment: :
You can add comments to any line to annotate your disassembly.
- Side Comments: Displayed on the same line as the instruction or data, to the right.
- Line Comments: Displayed on a separate line above the instruction or data.
Note
Line Comments also function as Splitters. Inserting a line comment into a grouped block (like a sequence of bytes) will split the block at that point, preventing the auto-merger from combining them.
Scopes
- Create Scope: R
- Remove Scope: Del (only at the beginning or end of a scope)
- Exclude External Address: Del (when cursor is on an external label address, excludes it from analysis)
Note
Scopes are not a different type of block. Instead they "encapsulate" existing blocks within a scope (AKA "namespace", "proc", etc).
Scopes allow you to group instructions and data into logical blocks, typically representing routines or functions. The primary purpose of scopes is to restrict the visibility of local labels, preventing naming conflicts between different parts of the code.
When you export your disassembly, scopes are directly translated into the corresponding directives of your chosen assembler.
Example
In 64tass, scopes are mapped to the .block and .bend directives. If a name is provided, it's placed as a label just before the .block.
ACME does not support scopes. Any scopes defined in your project will be ignored during export if you select ACME as your assembler.
In Kick Assembler, scopes are represented using curly braces { and }. The scope name is placed right before the opening brace.
In ca65, scopes are mapped to the .proc and .endproc directives. The scope name is passed as an argument to .proc. Unnamed scopes are automatically named unnamed_scope.
.proc my_routine
lda #$00
beq l00
bne l11
l00:
sta $d020
l11:
rts
.endproc
jsr my_routine
; IMPORTANT: ca65 is a one-pass assembler, so if calling a label defined in a scope,
; the label must be defined before the call. Otherwise, it will be treated as an undefined label,
; and the assembly will fail.
jmp my_routine::l00
Splitters and Auto-Merging
- Shortcut: |
In Regenerator 2000, adjacent blocks of the same type are automatically merged into a single contiguous block. This feature keeps the disassembly clean (e.g., combining adjacent Byte blocks into single Byte block).
Note
Only adjacent blocks of the same type are auto-merged.
graph LR
A[Byte Block A <br/> $1000-$1FFF] -->|Auto-Merge| M[Merged Byte Block <br/> $1000-$2FFF]
B[Byte Block B <br/> $2000-$2FFF] --> M
Splitters (and Line Comments) are used to prevent this behavior when needed. They serve two purposes:
- Visual Separation: Inserts a visual separator (newline) in the disassembly view.
- Logical Separation: Acts as a barrier that stops the auto-merger.
Example: Imagine you have a Lo/Hi table right after another. Without a splitter, they become one. With a splitter, they remain separate.
graph TD
subgraph Without Splitter
A1[Lo/Hi Table 1 <br/> $C000-$C0FF] --- B1[Lo/Hi Table 2 <br/> $C100-$C1FF] --> C1[Merged Lo/Hi Table <br/> $C000-$C1FF]
end
graph TD
subgraph With Splitter
A2[Lo/Hi Table 1 <br/> $C000-$C0FF] --- S[Splitter] --- B2[Lo/Hi Table 2 <br/> $C100-$C1FF] --> A3[Lo/Hi Table 1 <br/> $C000-$C0FF]
B2 --> B3[Lo/Hi Table 2 <br/> $C100-$C1FF]
end
Important
Splitters are especially critical for Lo/Hi and Hi/Lo Address/Word Table blocks. Because these blocks calculate the split point between the Low and High parts based on the total length of the block, merging two independent tables would result in an incorrect calculation of addresses.
Collapsing Blocks
- Collapse/Uncollapse: Ctrl+K
- Description: Hides or shows the content of a block, showing only a summary line.
Example
Valid for the Disassembly view.
Expanded View:
Collapsed View:
Example
Valid for the Block view: collapsed blocks are tagged with a +.
- Use Case: Use this to hide large tables, long text strings, or finished subroutines to keep your workspace clean and focus on the code you are currently analyzing.
- Scope: This is a visual-only feature for the Disassembly View. It does not affect:
- The exported assembly code (all code is always exported).
- Other views (e.g., Hex Dump, Character Set).