[← Home](../../README.md) · [Reverse Engineering](../README.md)
# Non-C Languages — AMOS, Blitz Basic, E, Modula-2, FORTH, and Others
## Overview
While C and assembly dominated Amiga development, a surprising number of applications and games were built in higher-level or domain-specific languages. **AMOS Professional** and **Blitz Basic 2** produced hundreds of commercial and shareware titles. **Amiga E** (by Wouter van Oortmerssen) was a fast compiled language with C-like performance and Python-like expressiveness. **Modula-2** and **Oberon** brought structured programming from ETH Zürich. **FORTH** (JForth, HSForth) powered interactive development environments and embedded systems. **ARexx** served as the system-wide scripting glue. **CanDo** and **AmigaVision** enabled non-programmers to build multimedia applications.
Each of these languages leaves a **distinctive runtime fingerprint** in the binary — an interpreter loop, a tokenized bytecode format, a compiler-specific runtime library, or a unique memory layout. Reversing these binaries requires recognizing the language first, then applying language-specific decompilation strategies that bear little resemblance to standard C reverse engineering.
```mermaid
graph TB
subgraph "Languages on Amiga"
ASM["Assembly
Direct m68k"]
C_FAM["C / C++
SAS/C, GCC, VBCC, StormC"]
BASIC["BASIC dialects
AMOS, Blitz Basic, ABasiC"]
E_LANG["Amiga E
Compiled, fast, modular"]
MODULA["Modula-2 / Oberon
ETH heritage"]
FORTH_LANG["FORTH
JForth, HSForth"]
PASCAL["Pascal
HiSoft, Maxon"]
SCRIPT["Scripting / Visual
ARexx, CanDo, AmigaVision"]
end
subgraph "Binary Fingerprint"
NATIVE["Native code
HUNK binary, direct m68k"]
TOKENIZED["Tokenized bytecode
Interpreter loop, opcode tables"]
HYBRID["Hybrid
Compiled to m68k with runtime"]
THREADED["Threaded code
FORTH dictionary, NEXT routine"]
end
ASM --> NATIVE
C_FAM --> NATIVE
E_LANG --> NATIVE
MODULA --> NATIVE
PASCAL --> NATIVE
BASIC --> TOKENIZED
BASIC --> HYBRID
SCRIPT --> TOKENIZED
FORTH_LANG --> THREADED
```
---
## Architecture Overview
### Language Classification by Binary Type
| Category | Languages | Binary Format | RE Strategy |
|---|---|---|---|
| **Native Code** | Amiga E, Modula-2, Oberon, Pascal | Standard HUNK binary | Standard disassembly with language-specific runtime library recognition |
| **Tokenized Bytecode** | AMOS, ABasiC, Hisoft BASIC, CanDo | Custom executable with embedded interpreter | Extract bytecode, identify opcode table, decompile token stream |
| **Hybrid (Compiled + Runtime)** | Blitz Basic 2, AmigaVision | HUNK binary + runtime library + optional tokenized sections | Identify Blitz runtime calls; decompile library calls back to BASIC semantics |
| **Threaded Code** | JForth, HSForth, Yerk | HUNK binary with threaded interpreter | Identify NEXT routine, walk dictionary, reconstruct FORTH words |
| **Scripted / Embedded** | ARexx, Installer | ARexx macro files (.rexx), Installer scripts | Plain-text or tokenized script; host application provides runtime |
---
## Language Quick-Reference Table
| Language | Compiler / Runtime | Binary Type | Main Runtime Library | Key Identifier |
|---|---|---|---|---|
| **AMOS** | AMOSPro_Interpreter | Custom + tokenized IFF | `AMOS.library` | `AMOS` or `AMOSPro` string |
| **Blitz Basic 2** | Blitz2 compiler | HUNK native code | `blitzlib.library` | `BB_` prefixed runtime calls |
| **Amiga E** | `ec` / CreativE | HUNK native code | `ec.runtime` | `E_GC`, module export tables |
| **Modula-2** | M2Amiga | HUNK native code | M2 runtime | Module `_init`/`_final` |
| **Oberon** | AmigaOberon / OOC | HUNK native code | Oberon runtime | Type-bound procedure dispatch |
| **FORTH** | JForth, HSForth | HUNK + threaded dict | Built-in | Threaded `NEXT` interpreter |
| **ARexx** | `rexxsyslib.library` | Plain text / tokenized `.rexx` | `rexxsyslib.library` | ARexx script header |
| **ABasiC** | Metacomco ABasiC | Tokenized | ABasiC runtime | ABasiC token format |
| **Hisoft BASIC** | Hisoft compiler | HUNK native code | Hisoft runtime | Hisoft runtime calls |
| **Hisoft Pascal** | Hisoft compiler | HUNK native code | Hisoft Pascal runtime | Pascal calling convention, string descriptors |
| **Maxon Pascal** | Maxon compiler | HUNK native code | Maxon runtime | Module system, OOP extensions |
| **CanDo** | CanDo runtime | Tokenized deck format | `cando.library` | Deck file magic bytes, card/button descriptors |
| **AmigaVision** | AmigaVision runtime | Hybrid (compiled flows) | AmigaVision runtime | Flow chart bytecode, media references |
| **DevPAC** | DevPAC assembler macros | HUNK native (asm) | None (pure m68k) | DevPAC-specific include/macro signatures |
---
## Language-Specific RE Guides
### AMOS Professional / AMOS Basic
AMOS compiles to a tokenized bytecode embedded in a custom executable wrapper. The interpreter is `AMOS.library` or the standalone `AMOSPro_Interpreter`. Tokenized programs contain:
- **Token stream**: 1-byte opcodes with inline arguments
- **Sprite/bob data**: Embedded IFF ILBM chunks
- **Sample data**: Embedded IFF 8SVX chunks
- **String table**: Pascal strings (length-prefixed)
- **Bank system**: Separate memory banks for sprites, samples, music, code — each with its own identifier
**Detection**: Look for `AMOS` or `AMOSPro` strings, or the `AMOS.library` OpenLibrary call. Tokenized executables have a distinct header with bank count and sizes.
**Decompilation methodology**:
**Decompilation tools**: `AMOSList` (token dumper), `AMOS2ASCII` converters exist but are incomplete.
**Key Challenge**: AMOS extensions (AMAL, AMOS 3D, TOME, etc.) add custom opcodes to the token stream. An unextended decompiler will fail on these. You must map extension opcodes to their extension name.
#### AMOS-Specific Pitfalls
---
### Blitz Basic 2 / AmiBlitz
Blitz Basic 2 compiles to native m68k code linked with `BlitzLibs` (or `AmiBlitz` libraries). The compiled output:
- Uses standard HUNK format
- Links against `blitzlib.library` or specific Blitz support libraries
- Generates surprisingly efficient code for a BASIC compiler (rivals hand-written C in some cases)
- Library calls are regular `JSR LVO(A6)` but use Blitz-specific libraries
- Supports inline assembly via `[asm] ... [end asm]` blocks
**Detection**: Look for `blitzlib.library` OpenLibrary calls, or Blitz-specific runtime functions. Common BlitzLib function prefixes:
| BlitzLib Function Prefix | Purpose | Example |
|---|---|---|
| `BB_AllocMem` | Memory allocation | Blitz's internal allocator |
| `BB_FreeMem` | Memory deallocation | Matching free |
| `BB_StrCopy` | String copy | Blitz string handling |
| `BB_StrCmp` | String compare | Case-sensitive comparison |
| `BB_LoadShape` | Load IFF ILBM shape | Used with `LoadShape` statement |
| `BB_LoadSound` | Load IFF 8SVX sample | Used with `LoadSound` statement |
| `BB_DisplayShape` | Blit shape to screen | `ShowShape` / `DisplayShape` statement |
| `BB_QSprite` | QSprite (hardware sprite) management | Blitz sprite system |
| `BB_Poke` / `BB_Peek` | Direct memory access | `Poke.b`, `Peek.w` etc. |
| `BB_Print` | Text output | Blitz `Print` statement |
| `BB_Input` | Text input | Blitz `Input` / `Edit()` function |
> [!NOTE]
> Blitz Basic 2 inline assembly (`[asm]...[/asm]`) requires A4-A6 to be preserved. Look for `MOVEM.L` save/restore of A4-A6 around code blocks that contain direct hardware access — these are likely inline asm blocks within a Blitz program.
**Decompilation methodology**:
**Key Challenge**: Blitz inlines certain operations. A `For...Next` loop generates a `DBRA` directly. Understanding the mapping between Blitz statements and their code generation patterns is essential.
**BlitzLib to BASIC mapping table**:
#### Blitz-Specific Pitfalls
---
### Amiga E
Amiga E compiles to native m68k code via the `ec` compiler (or `CreativE`). Key characteristics:
- **Garbage collector**: `E_GC()` runtime calls interspersed in the code for conservative stack scanning
- **Module system**: `.e` modules compile to `.m` object files with specific export tables
- **Exception handling**: Try/Except generates custom stack unwinding code
- **List comprehension**: Generates iteration patterns with `E_Next()` calls
- **Object system**: Message-passing OOP (not C++ vtables) — objects have a **method table** pointer at +00, but the table maps message IDs to handlers, not fixed-offset virtual methods
- **Concurrency**: Lightweight tasks via `E_Task()` — cooperative coroutines, not exec tasks
**Amiga E Object Layout**:
```
E Object:
+00: method_table_ptr → MethodTable
+04: instance_var_1
+08: instance_var_2
...
MethodTable:
+00: class_name (string ptr)
+04: parent_method_table (ptr or NULL)
+08: message_handler_count
+0C: message_id_0 → handler_0
+10: message_id_1 → handler_1
...
```
**Critical difference from C++**: E methods are dispatched by **message ID** (a symbol/integer), not by fixed vtable offset. The method table is a key-value map, not an array. A call like `obj.method()` compiles to a search through the method table for the matching message ID, then a `JSR` to the handler. This is more dynamic than C++ and harder to reconstruct from static analysis alone.
**Detection**: Look for `ec.runtime` library calls, `E_GC`, or module export tables with `.m` format. The E runtime is typically statically linked.
**Decompilation methodology**:
**Key Challenge**: E's syntax is so expressive that a single line of E can generate 15–20 m68k instructions. Mapping back to source-level intent requires understanding E's compilation strategies.
#### Amiga E-Specific Pitfalls
---
### Modula-2 / Oberon
Modula-2 (via the Modula-2 Development System or M2Amiga) compiles to native code with distinctive patterns:
- **Module initialization**: Each module has `_init` and `_final` procedures called at load/unload
- **COROUTINES**: `NEWPROCESS`/`TRANSFER` generate custom context-switching code
- **Opaque types**: Information hiding generates accessor functions that only appear for exported types
- **No preprocessor**: No `#include`, no macros — all dependencies are explicit IMPORT/EXPORT
- **Range-checked arrays**: Runtime bounds checking generates additional CMP/Bcc instructions
- **Set operations**: Bit-manipulation patterns for set types with `INCL`/`EXCL` (include/exclude)
Oberon (via AmigaOberon or OOC) adds:
- **Type-bound procedures** (method-like dispatch but not virtual tables like C++)
- **Garbage collection** (optional — generates GC safe-points in code)
- **Type extension** (single inheritance without vtables — uses descriptor records)
- **Dynamic arrays**: Runtime-allocated with descriptor blocks
**Detection**: Look for module init signatures, or the distinctive `M2_` / `OB_` runtime function prefixes. Modula-2 modules may use `.mod` or `.m2` file references. Oberon's type-bound procedures use descriptor-based dispatch (function pointer tables at known offsets, but not C++ vtables).
**Decompilation methodology**:
---
### FORTH (JForth, HSForth, Yerk)
FORTH on Amiga uses **threaded code** — the binary is a dictionary of word definitions, each consisting of:
1. A header (link to previous word, name, flags)
2. A code field (pointer to native code for primitives, or to the inner interpreter for colon definitions)
3. A parameter field (list of execution tokens for colon definitions)
**Detection**: Look for the FORTH inner interpreter (`NEXT` routine) — typically:
```asm
; NEXT: (ip) → W, advance ip, jump to (W)
NEXT:
MOVE.L (A4)+, A5 ; load next execution token from IP, advance
MOVE.L (A5), A6 ; load code field address
JMP (A6) ; execute it (threaded dispatch)
```
Additional detection heuristics:
- `LIT` routine (pushes inline literal to data stack)
- `EXIT` routine (pops return stack to IP — `MOVE.L (A3)+, A4` / `JMP (A4)`)
- Stack pointer registers: A3=data stack, A4=return stack in JForth convention
- Dictionary header format: link field → name length byte + name characters → code field → parameter field
**Decompilation methodology**:
**Key Challenge**: FORTH code is a data structure, not a call graph. Standard disassemblers see only the inner interpreter loop; the actual program logic is in the dictionary data, which IDA treats as data words, not code. You must write a custom dictionary walker.
**FORTH dialects on Amiga**:
---
### ARexx
**Detection**: ARexx scripts are plain text (`.rexx`) or tokenized by the host application. The `rexxsyslib.library` provides the interpreter. Scripts are typically found as external files, not embedded in HUNK binaries, but macros are often stored as resources inside applications.
**Decompilation methodology**:
---
### Pascal (HiSoft Pascal, Maxon Pascal)
HiSoft Pascal generates native HUNK code with:
- **String descriptors**: Pascal strings are length-prefixed with a descriptor (length byte + characters)
- **Set operations**: Bit-field operations for Pascal SET types (up to 256 elements)
- **Nested procedures**: Static link chain for accessing outer procedure locals — generates `LINK A6` chains unlike C
- **Runtime checks**: Array bounds, subrange, NIL pointer checks generate conditional trap code
Maxon Pascal adds OOP extensions with:
- **Object type dispatch**: Not C++ vtables; uses method lookup tables with different layout
- **Module system**: Similar to Modula-2 with explicit IMPORT/EXPORT
**Detection**: Look for Pascal string descriptor patterns, nested procedure static links (`MOVE.L (A6), A6` chains), runtime check trap sequences, and Pascal-specific runtime library calls.
**Key Challenge**: Pascal nested procedures create non-standard call graphs where a procedure has access to its enclosing procedure's local variables via the static link. IDA/Ghidra don't natively understand this — you must trace the static link chain manually.
---
### CanDo / AmigaVision
**CanDo**: A hypermedia authoring system using a "deck of cards" metaphor. Programs are stored as "deck" files containing:
- Card descriptors (background, size, color)
- Button/field objects with attached scripts
- Script bytecode (proprietary CanDo scripting language)
- Embedded media (IFF ILBM, 8SVX)
**AmigaVision**: A flowchart-based multimedia authoring tool. Programs are flow charts where nodes are actions (display image, play sound, wait, branch). Stored in a custom format with:
- Flow chart structure (node connections)
- Node type identifiers
- Parameter data per node
- Embedded media references
**Detection**: CanDo deck files have a recognizable header; AmigaVision flow files have a node count + edge table structure. Both reference `cando.library` or the AmigaVision runtime.
**Key Challenge**: These are not traditional programming languages — reversing them means understanding the runtime engine's interpretation of the data structure, not disassembling code. The logic is in the data, similar to FORTH but at a much higher abstraction level.
---
## Decision Guide: Identifying the Language
```mermaid
graph TD
BIN["Unknown binary"]
HUNK{"Standard HUNK
header?"}
INTERP_STR{"'AMOS' or 'AMOSPro'
string present?"}
BLITZ_LIB{"blitzlib.library
OpenLibrary call?"}
E_RUNTIME{"ec.runtime or E_GC
calls present?"}
FORTH_NEXT{"FORTH NEXT
threaded interpreter?"}
M2_INIT{"Module init/final
export tables?"}
PASCAL_STR{"Pascal string
descriptors?"}
REX_HEADER{"ARexx script
header?"}
CANDO_HDR{"CanDo deck
magic bytes?"}
BIN --> HUNK
HUNK -->|"No"| REX_HEADER
REX_HEADER -->|"Yes"| AREXX_RESULT["ARexx script
→ detokenize or read as text"]
REX_HEADER -->|"No"| CANDO_HDR
CANDO_HDR -->|"Yes"| CANDO_RESULT["CanDo deck
→ card/button extraction"]
CANDO_HDR -->|"No"| AMOS_CUSTOM["Check for AMOS
tokenized header"]
HUNK -->|"Yes"| INTERP_STR
INTERP_STR -->|"Yes"| AMOS_RESULT["AMOS/AMOSPro
→ tokenized bytecode"]
INTERP_STR -->|"No"| BLITZ_LIB
BLITZ_LIB -->|"Yes"| BLITZ_RESULT["Blitz Basic 2
→ decompile BlitzLib calls"]
BLITZ_LIB -->|"No"| E_RUNTIME
E_RUNTIME -->|"Yes"| E_RESULT["Amiga E
→ ec.runtime analysis"]
E_RUNTIME -->|"No"| FORTH_NEXT
FORTH_NEXT -->|"Yes"| FORTH_RESULT["FORTH
→ dictionary walk"]
FORTH_NEXT -->|"No"| M2_INIT
M2_INIT -->|"Yes"| M2_RESULT["Modula-2 / Oberon"]
M2_INIT -->|"No"| PASCAL_STR
PASCAL_STR -->|"Yes"| PASCAL_RESULT["HiSoft/Maxon Pascal"]
PASCAL_STR -->|"No"| C_ASM["Likely C or ASM
→ see other guides"]
```
---
## Best Practices — Cross-Language RE
1. **Identify the language before disassembling** — each language has a fundamentally different binary architecture
2. **Don't treat tokenized binaries as native code** — they will confuse every standard tool
3. **For native-code languages, find the runtime library first** — it tells you the language and provides anchor xrefs
4. **FORTH requires custom tooling** — standard disassemblers cannot handle threaded code
5. **BASIC compilers leave recognizable patterns** — library calls, loop structures, string handling distinguish them from C
6. **Check for embedded media** — AMOS and Blitz binaries often contain IFF chunks (ILBM, 8SVX) that confirm the language
7. **String format is a strong differentiator** — C strings (null-terminated) vs Pascal strings (length-prefixed) vs E strings (custom format) vs FORTH counted strings
8. **ARexx macros are often plain text** — check the binary's resources for readable script text before disassembling
9. **Mixed-language programs exist** — C core + ARexx scripting + asm hot paths; analyze each section with the appropriate methodology
10. **Build language-specific IDA/Ghidra loaders** — for tokenized/threaded formats, a custom loader that pre-processes the binary saves enormous time
---
## Named Antipatterns
### 1. The C Disassembler Default
**Wrong**: Loading a Blitz Basic or AMOS binary into IDA and treating it like C.
**Why**: The token stream or interpreter loop looks like garbled code to a standard disassembler. You'll waste hours trying to make sense of what is fundamentally not native code.
### 2. The Missing Interpreter
**Wrong**: Disassembling only the HUNK code and ignoring the embedded runtime interpreter.
**Why**: AMOS tokenized programs carry a chunk of the interpreter or reference `AMOS.library`. Without understanding the opcode dispatch loop, the token stream is opaque.
### 3. The FORTH Data Wall
**Wrong**: Running standard recursive-descent disassembly on a FORTH binary.
**Why**: FORTH dictionaries are data structures, not call graphs. Standard disassembly produces one huge function (the `NEXT` loop) and treats the entire dictionary as data bytes.
### 4. The BASIC Loop Assumption
**Wrong**: Seeing `DBRA D0, loop` and assuming it's a C `for` loop.
**Why**: Blitz Basic generates `DBRA` for `For...Next` loops, but the loop variable semantics differ — BASIC loops may have different termination conditions and the counter may be used differently than in C.
### 5. The String Format Switcheroo
**Wrong**: Assuming all strings are null-terminated C strings.
**Why**: Pascal uses length-prefixed strings (1-byte length + chars). Amiga E uses a custom string format with GC metadata. FORTH uses counted strings. Reading past the actual string boundary produces garbage.
### 6. The Garbage Collector Blindness
**Wrong**: Ignoring `E_GC()` calls as irrelevant runtime noise.
**Why**: Amiga E's garbage collector roots determine which objects survive. Missing a GC root means you misunderstand object lifetimes and may think objects are leaked when they're actually reachable.
### 7. The Module Boundary Erasure
**Wrong**: Analyzing Modula-2 or E code without understanding module boundaries.
**Why**: Module `_init`/`_final` pairs and import/export tables define the program's dependency graph. Treating all functions as a flat namespace loses the architectural structure.
### 8. The ARexx-as-C Mistake
**Wrong**: Loading an ARexx script file into a hex editor and trying to find machine code.
**Why**: ARexx is a scripting language. The "binary" may be plain text with a `/*` comment header containing ARexx script. Running it through a disassembler produces garbage.
---
## Pitfalls
### 1. Mixed-Language Binaries
Many Amiga applications mix languages: C for the core + ARexx for scripting + assembler for performance-critical routines. A single binary may contain multiple RE challenges requiring different methodologies.
### 2. Custom Token Formats
Some Blitz Basic variants allow inline assembly, which gets embedded as raw m68k opcodes within the token stream. A pure token decompiler will fail at these boundaries.
### 3. Version-Specific Runtimes
AMOS 1.3, AMOS Professional, and AMOS Compiler use different token encodings. Blitz Basic 2 and AmiBlitz have different runtime library versions. Always identify the exact language version before decompiling.
### 4. FORTH Dialect Variance
### 5. Pascal Static Link Chain Complexity
### 6. Amiga E GC Root Misidentification
### 7. Tokenized BASIC Extension Opcodes
### 8. ARexx Host Command Context
### 9. CanDo / AmigaVision Data-Driven Logic
### 10. Oberon Type-Bound Procedure vs C++ vtable Confusion
---
## Use-Case Cookbook
### Pattern 1: Identifying AMOS Tokenized Binaries Programmatically
### Pattern 2: Walking a FORTH Dictionary
### Pattern 3: Decompiling Blitz Basic Library Calls to Source Patterns
### Pattern 4: Reconstructing Amiga E Module Dependencies
### Pattern 5: Extracting ARexx Macros from Application Binaries
### Pattern 6: Decompiling HiSoft Pascal to Source
### Pattern 7: Recovering an AMOS Sprite Bank from a Tokenized Binary
### Pattern 8: Mapping a FORTH Program's Control Flow
### Pattern 9: Reconstructing an Oberon Type Hierarchy
### Pattern 10: Identifying Language from an Unknown Binary (Blind Triage)
---
## Real-World Examples
### AMOS
### Blitz Basic 2
### Amiga E
### FORTH
### ARexx
### Modula-2 / Oberon
---
## Cross-Platform Comparison
| Platform | Equivalent Language | Amiga Parallel |
|---|---|---|
| **C64** | Simons' BASIC, COMAL | AMOS / Blitz Basic — tokenized BASIC with extended graphics |
| **Atari ST** | ST BASIC, GFA BASIC | Blitz Basic 2 (similar compiled BASIC approach) |
| **DOS** | QBasic, Turbo Basic | AMOS (tokenized), Blitz (compiled) |
| **Mac OS** | HyperCard, FutureBASIC | AMOS (similar ease-of-use + graphics focus), CanDo (HyperCard analog) |
| **Acorn Archimedes** | BBC BASIC V (ARM) | Blitz Basic 2 (fast compiled BASIC with inline asm) |
| **Apple IIGS** | ORCA/Pascal, TML Pascal | HiSoft/Maxon Pascal (Wirth-family languages on 16-bit) |
| **NeXT** | Objective-C | Amiga E (fast, modular, object-oriented with message-passing) |
| **Windows 3.1** | Visual Basic, ToolBook | CanDo / AmigaVision (visual programming with scripting) |
---
## Historical Context — Why So Many Languages on Amiga?
The Amiga's open architecture and lack of a "blessed" development language created a uniquely diverse programming ecosystem:
| Factor | Effect |
|---|---|
| **No official language** | Unlike Mac (Object Pascal), DOS (Turbo C/QuickBasic), or ST (GFA BASIC), Commodore didn't push a specific development tool. C, assembly, BASIC, and others coexisted as equals. |
| **Beginner accessibility** | AMOS (1990) and Blitz Basic 2 (1991) filled the gap for users who found C intimidating. AMOS alone produced hundreds of shareware games. |
| **FORTH migration** | FORTH programmers carried their development culture from 8-bit machines (C64, Spectrum) to Amiga — JForth and HSForth were mature systems. |
| **ARexx as system glue** | ARexx (1988) provided system-wide scripting that no other platform matched until AppleScript (1993). Any application could expose an ARexx port. |
| **Educational influence** | Modula-2 and Oberon (from ETH Zürich, Niklaus Wirth) brought structured programming to Amiga. HiSoft Pascal ported the Mac's dominant educational language. |
| **Multimedia authoring** | CanDo and AmigaVision made application creation accessible to non-programmers — precursors to tools like HyperCard and modern no-code platforms. |
| **Late C++ arrival** | Without early C++ compilers, E (1993) filled the niche for a modern, object-oriented compiled language — it was what C++ should have been for Amiga. |
---
## Modern Analogies
| Amiga Language Concept | Modern Analogy | Where It Holds / Breaks |
|---|---|---|
| AMOS tokenized bytecode | Python `.pyc` bytecode | Holds: interpreted bytecode with embedded media; breaks: AMOS bytecode is undocumented, Python's is open |
| Blitz Basic compiled output | Go (compiled, fast, runtime-linked) | Holds: compiled native code with runtime library; breaks: Blitz is tied to one platform |
| Amiga E GC + modules | Go / D (GC + fast compilation) | Holds: modern compiled language with GC; breaks: E is single-threaded |
| FORTH threaded code | WASM stack machine | Holds: stack-based execution model; breaks: FORTH is memory-mapped, WASM is sandboxed |
| ARexx system scripting | AppleScript / VBA | Holds: system-wide IPC scripting; breaks: ARexx is string-based, AppleScript is object-based |
| Oberon type-bound procedures | Go interfaces | Holds: non-inheritance-based polymorphism; breaks: Oberon uses explicit descriptors, Go uses implicit satisfaction |
| CanDo hypermedia | HyperCard / Powerpoint VBA | Holds: card-based visual programming; breaks: CanDo is a standalone runtime |
---
## FAQ
### Q1: Which language should I learn to reverse Amiga software most effectively?
### Q2: Is there an automatic decompiler for AMOS or Blitz Basic?
### Q3: How do I tell if a binary is AMOS or Blitz without running it?
### Q4: Can IDA Pro decompile FORTH binaries?
### Q5: How do I extract embedded media from an AMOS program?
### Q6: What's the difference between JForth and HSForth binary formats?
### Q7: How do I handle Amiga E binaries that mix E and C code?
### Q8: Can ARexx macros be tokenized? How do I detokenize them?
### Q9: How do I distinguish between Modula-2 and Oberon binaries?
### Q10: Is there a Ghidra plugin for any of these languages?
### Q11: How do I decompile a Blitz Basic program that uses inline assembly?
### Q12: What are the most common non-C languages found in Amiga games?
### Q13: How do I reverse engineer a CanDo deck file?
### Q14: What tools exist for batch language identification of unknown Amiga binaries?
---
## FPGA / Emulation Impact
---
## References
- [asm68k_binaries.md](asm68k_binaries.md) — Hand-written assembly reverse engineering
- [ansi_c_reversing.md](ansi_c_reversing.md) — C binary reverse engineering
- [cpp_vtables_reversing.md](cpp_vtables_reversing.md) — C++ OOP reverse engineering
- [compiler_fingerprints.md](../compiler_fingerprints.md) — Compiler identification
- [m68k_codegen_patterns.md](m68k_codegen_patterns.md) — Code generation patterns
- [api_call_identification.md](api_call_identification.md) — Library call recognition
- [hunk_reconstruction.md](hunk_reconstruction.md) — HUNK binary reconstruction
- [rexxsyslib.md](../../11_libraries/rexxsyslib.md) — ARexx library internals
- *AMOS Professional Manual* — François Lionet, Europress Software
- *Blitz Basic 2 Manual* — Mark Sibly, Acid Software
- *Amiga E Manual* — Wouter van Oortmerssen
- *JForth Manual* — Delta Research
- *HiSoft Pascal Manual* — HiSoft
- *CanDo User Manual* — INOVAtronics
- [Amiga E Compiler Source](https://github.com/Amiga-E/ec) — Open-source `ec` compiler