Skip to content

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

; Code blocks are represented as code
lda #$00
sta a_D020
; Code blocks are represented as code
lda #$00
sta a_D020
// Code blocks are represented as code
lda #$00
sta a_D020
; Code blocks are represented as code
lda #$00
sta a_D020

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

; Byte blocks are represented as bytes
.byte $80, $40, $a2, $ff
; Byte blocks are represented as bytes
!byte $80, $40, $a2, $ff
// Byte blocks are represented as bytes
.byte $80, $40, $a2, $ff
; Byte blocks are represented as bytes
.byte $80, $40, $a2, $ff

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

; Word blocks are represented as words
.word $1234, $ffaa, $5678, $0000, $abcd
; Word blocks are represented as words
!word $1234, $ffaa, $5678, $0000, $abcd
// Word blocks are represented as words
.word $1234, $ffaa, $5678, $0000, $abcd
; Word blocks are represented as words
.word $1234, $ffaa, $5678, $0000, $abcd

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

; Address blocks are represented as words, that generates an address reference
.word a_1234, a_FFAA, a_5678, a_0000, a_ABCD
; Address blocks are represented as words, that generates an address reference
!word a_1234, a_FFAA, a_5678, a_0000, a_ABCD
// Address blocks are represented as words, that generates an address reference
.word a_1234, a_FFAA, a_5678, a_0000, a_ABCD
; Address blocks are represented as words, that generates an address reference
.word a_1234, a_FFAA, a_5678, a_0000, a_ABCD

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

.encode
.enc "none"
.text "hello world"
.endencode
!text "hello world"
.encoding "petscii_upper"
.text "hello world"
.byte "hello world"

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

.encode
.enc "screen"
.text "hello world"
.endencode
!scr "hello world"
.encoding "screencode_mixed"
.text "hello world"
; Requires .macpack cbm
scrcode "hello world"

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

; Assume that you have these bytes:
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; They will be represented as:
.byte <a_C000, <a_D101, <a_E202, <a_F303
.byte >a_C000, >a_D101, >a_E202, >a_F303
; Assume that you have these bytes:
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; They will be represented as:
!byte <a_C000, <a_D101, <a_E202, <a_F303
!byte >a_C000, >a_D101, >a_E202, >a_F303
// Assume that you have these bytes:
// $00, $01, $02, $03, $c0, $d1, $e2, $f3
// They will be represented as:
.byte <a_C000, <a_D101, <a_E202, <a_F303
.byte >a_C000, >a_D101, >a_E202, >a_F303
; Assume that you have these bytes:
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; They will be represented as:
.byte <a_C000, <a_D101, <a_E202, <a_F303
.byte >a_C000, >a_D101, >a_E202, >a_F303

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

; Assume that you have these bytes:
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; They will be represented as:
.byte >a_00C0, >a_01D1, >a_02E2, >a_03F3
.byte <a_00C0, <a_01D1, <a_02E2, <a_03F3
; Assume that you have these bytes:
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; They will be represented as:
!byte >a_00C0, >a_01D1, >a_02E2, >a_03F3
!byte <a_00C0, <a_01D1, <a_02E2, <a_03F3
// Assume that you have these bytes:
// $00, $01, $02, $03, $c0, $d1, $e2, $f3
// They will be represented as:
.byte >a_00C0, >a_01D1, >a_02E2, >a_03F3
.byte <a_00C0, <a_01D1, <a_02E2, <a_03F3
; Assume that you have these bytes:
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; They will be represented as:
.byte >a_00C0, >a_01D1, >a_02E2, >a_03F3
.byte <a_00C0, <a_01D1, <a_02E2, <a_03F3

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

; Assume that you have these bytes:
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; They will be represented as:
.byte <$C000, <$D101, <$E202, <$F303
.byte >$C000, >$D101, >$E202, >$F303
; Assume that you have these bytes:
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; They will be represented as:
!byte <$C000, <$D101, <$E202, <$F303
!byte >$C000, >$D101, >$E202, >$F303
// Assume that you have these bytes:
// $00, $01, $02, $03, $c0, $d1, $e2, $f3
// They will be represented as:
.byte <$C000, <$D101, <$E202, <$F303
.byte >$C000, >$D101, >$E202, >$F303
; Assume that you have these bytes:
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; They will be represented as:
.byte <$C000, <$D101, <$E202, <$F303
.byte >$C000, >$D101, >$E202, >$F303

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

; Assume that you have these bytes:
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; They will be represented as:
.byte >$00C0, >$01D1, >$02E2, >$03F3
.byte <$00C0, <$01D1, <$02E2, <$03F3
; Assume that you have these bytes:
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; They will be represented as:
!byte >$00C0, >$01D1, >$02E2, >$03F3
!byte <$00C0, <$01D1, <$02E2, <$03F3
// Assume that you have these bytes:
// $00, $01, $02, $03, $c0, $d1, $e2, $f3
// They will be represented as:
.byte >$00C0, >$01D1, >$02E2, >$03F3
.byte <$00C0, <$01D1, <$02E2, <$03F3
; Assume that you have these bytes:
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; They will be represented as:
.byte >$00C0, >$01D1, >$02E2, >$03F3
.byte <$00C0, <$01D1, <$02E2, <$03F3

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

; Assume that you have these bytes at address $1000
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; A binary file called "export-$1000-$1007.bin" will be generated
; And this code will be generated
.binary "export-$1000-$1007.bin"
; Assume that you have these bytes at address $1000
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; A binary file called "export-$1000-$1007.bin" will be generated
; And this code will be generated
!binary "export-$1000-$1007.bin"
// Assume that you have these bytes at address $1000
// $00, $01, $02, $03, $c0, $d1, $e2, $f3
// A binary file called "export-$1000-$1007.bin" will be generated
// And this code will be generated
.import binary "export-$1000-$1007.bin"
; Assume that you have these bytes at address $1000
; $00, $01, $02, $03, $c0, $d1, $e2, $f3
; A binary file called "export-$1000-$1007.bin" will be generated
; And this code will be generated
.incbin "export-$1000-$1007.bin"

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

; Undefined blocks are represented as single bytes, one byte per line.
.byte $00
.byte $ca
.byte $ff
; Undefined blocks are represented as single bytes, one byte per line.
!byte $00
!byte $ca
!byte $ff
// Undefined blocks are represented as single bytes, one byte per line.
.byte $00
.byte $ca
.byte $ff
; Undefined blocks are represented as single bytes, one byte per line.
.byte $00
.byte $ca
.byte $ff

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.

my_routine
    .block
    lda #$00
    beq l00
    bne l11
l00
    sta $d020
l11
    rts
    .bend

    jsr my_routine
    jmp my_routine.l00

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.

my_routine
{
    lda #$00
    beq l00
    bne l11
l00:
    sta $d020
l11:
    rts
}

    jsr my_routine
    jmp my_routine.l00

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:

  1. Visual Separation: Inserts a visual separator (newline) in the disassembly view.
  2. 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:

a_1000   .byte $01, $02, $03, $04, $05, $06, $07, $08
        .byte $09, $0a, $0b, $0c, $0d, $0e, $0f, $10

Collapsed View:

a_1000  ; Collapsed Byte block from $1000-$100F

Example

Valid for the Block view: collapsed blocks are tagged with a +.

  $0900-$09FF [Code]
+ $1000-$100F [Byte]
  $1010-$11FF [Code]
  • 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).