Blitz! BASIC Compiler¶
BPP+ provides full compatibility with the Blitz! BASIC Compiler through special directives and syntax extensions. These directives control runtime behavior and compiler optimizations.
Almost full speed ahead!¶
Blitz! 1 is a BASIC compiler for the Commodore 64 that translates BASIC programs into faster-executing P-Code. Originally developed by Skyles Electric Works and later enhanced by Commodore Buromaschinen GmbH (as Austro-Comp) and Daniel Kahlin.
BPP+ and C*Base Larry Mod v3.1 development package uses the Blitz!/Austro-Comp compiler v0.1 by Daniel Kahlin as the default compiler. The table below lists multiple compiler variants and tools available for different development environments and workflows.
- Video overview: The 8-Bit Theory - Blitz! BASIC Compiler (YouTube)
- Related: BLITZ! 128 Manual (PDF)
Compilers and tools¶
| Name | Version | Description | Link | File |
|---|---|---|---|---|
| Blitz!/Austro-Comp compiler | v0.1 | Cross-compiler by Daniel Kahlin (default for BPP+/C*Base) | CSDB | ZIP |
| Blitz!/Austro-Speed decompiler | v0.1 | Decompiler for Blitz!-compiled programs back to BASIC | CSDB | ZIP |
| Reblitz64 | - | JavaScript port of Blitz! compiler (extremely fast, browser-based) | GitHub | ZIP |
| BC64 | - | Cross-compiler with C128-style forced integer support | GitHub | ZIP |
Why use Blitz! compilation?¶
Blitz! compilation provides significant advantages over interpreted BASIC:
Performance improvements¶
- Provides 3-5x performance improvements over interpreted BASIC
- Pre-stored variable and array locations (no runtime searching)
- Pre-stored line number destinations for GOTO/GOSUB (no runtime searching)
- Pre-converted numeric constants (no runtime conversion)
- Compilation-time syntax checking (no runtime checking)
- True integer arithmetic for integer expressions
- Optimized expression evaluation with minimal intermediate storage
Code size benefits¶
- Compiled P-Code typically reduces program size to 60-70% of the original
- Runtime routines add overhead, but programs 30KB+ usually become smaller overall
- More efficient memory usage for larger programs
Development benefits¶
- Syntax errors caught at compile-time, not runtime
- Better performance for production releases
- Copy protection options (STOP key disable, dongle support)
- Compiled programs cannot be listed (automatic protection)
Directive syntax¶
Two equivalent syntaxes are supported in BPP+:
Native Blitz! syntax (preserved verbatim)¶
rem ** se rem Enable STOP key
rem ** sa rem Disable STOP key (default)
rem ** ie rem Enable INPUT command
rem ** ia rem Disable INPUT command (default)
rem ** sp [number] rem Specify dongle number
rem ** ne rem No extension listing
BPP+ alternative syntax (converted to native form)¶
!blitz se rem Converted to: rem ** se
!blitz sa rem Converted to: rem ** sa
!blitz ie rem Converted to: rem ** ie
!blitz ia rem Converted to: rem ** ia
!blitz sp 1234 rem Converted to: rem ** sp 1234
!blitz ne rem Converted to: rem ** ne
Blitz! directives reference¶
| # | BASIC directive | BPP+ directive | Purpose |
|---|---|---|---|
| 1 | rem ** se |
!blitz se |
Enable STOP key |
| 2 | rem ** sa |
!blitz sa |
Disable STOP key |
| 3 | rem ** ie |
!blitz ie |
Enable INPUT command |
| 4 | rem ** ia |
!blitz ia |
Disable INPUT command |
| 5 | rem ** sp [n] |
!blitz sp [n] |
Check dongle |
| 6 | rem ** ne |
!blitz ne |
No extension listing |
| 7 | :: |
:: |
Extension marker |
Directive details¶
1. Enable STOP key¶
Allows program to be interrupted with RUN/STOP key.
Directive¶
rem ** se/!blitz se
Use cases¶
- Development and debugging
- Testing compiled programs
- Allowing user to exit long-running operations
Default state¶
- Interpreted BASIC: STOP key enabled
- Compiled programs: STOP key disabled (must use this directive to re-enable)
Example¶
!blitz se rem Enable STOP key for debugging
main:
gosub test_routine
print "tests complete"
end
test_routine:
rem User can press STOP to interrupt during testing
for i=1 to 10000
print i
next i
return
2. Disable STOP key¶
Prevents program interruption with RUN/STOP key.
Directive¶
rem ** sa/!blitz sa
Use cases¶
- Production releases
- Copy protection
- Preventing user interruption during critical operations
- Kiosk or demo programs
Default state¶
- Compiled programs have STOP key disabled by default
- This directive explicitly documents the behavior
Example¶
rem ** sa rem Disable STOP key (production)
main:
gosub init
gosub game_loop
end
3. Enable INPUT command¶
Allows runtime INPUT statements if supported by Blitz! version.
Directive¶
rem ** ie/!blitz ie
Trade-offs¶
- Increases compiled program size
- Adds INPUT command support to runtime routines
Use cases¶
- Programs requiring user text input
- Interactive applications
- Data entry programs
Example¶
!blitz ie rem Enable INPUT command
main:
print "enter your name:"
input nm$
print "hello, ";nm$
end
4. Disable INPUT command¶
Removes INPUT command support from compiled program.
Directive¶
rem ** ia/!blitz ia
Benefits¶
- Reduces compiled program size
- Removes unused runtime code
Default state¶
- INPUT command not supported by default (must explicitly enable with
rem ** ie)
Use cases¶
- Programs that don't need INPUT
- Size-optimized programs
- Games and demos using GET instead of INPUT
Example¶
rem ** ia rem Disable INPUT (default, explicit)
main:
gosub get_keypress rem Use GET instead of INPUT
end
get_keypress:
get k$
if k$="" then get_keypress
return
5. Check dongle¶
Verifies presence of copy protection dongle.
Directive¶
rem ** sp [number]/!blitz sp [number]
Parameters¶
number= Dongle ID (specific hardware identifier)
Behavior¶
- Program terminates if specified dongle not detected
- Used for commercial software copy protection
Example¶
!blitz sp 1234 rem Require dongle #1234
main:
rem Program only runs with correct dongle present
gosub game_loop
end
6. No extension listing¶
Suppresses line number output during compilation. Compiled programs cannot be listed anyway - attempting to LIST will only show SYS address or "compiled by blitz" message.
Directive¶
rem ** ne/!blitz ne
Use cases¶
- Cleaner compilation output (no line numbers printed)
- Faster compilation (skips line number display)
- Quieter build process
Example¶
rem ** ne rem Suppress line numbers during compilation
main:
gosub main_loop
end
7. Extension marker¶
Forces statement to be passed to the BASIC interpreter at runtime rather than being compiled. Allows non-BASIC V2 commands (BASIC extensions) to be used without causing syntax errors during compilation.
Directive¶
::
Syntax¶
:: statement rem Single statement
:: statement1: statement2 rem Multiple statements (up to next line)
Use cases¶
- BASIC extensions - Commands from Plum's Extensions, Simon's BASIC, JiffyDOS, etc.
- Kernal enhancements - Extended commands provided by ML routines
- Non-standard commands - Any command not recognized by Blitz! compiler
- Machine code routine calls (SYS)
- Self-modifying code that changes at runtime
- Dynamic calculations that cannot be compile-time resolved
- Debugging statements in compiled code
- Intentional delay loops that should not be optimized
Why use extension marker?¶
Without ::, the compiler will throw a SYNTAX ERROR when encountering commands it doesn't recognize (anything beyond standard BASIC V2). The extension marker tells Blitz! to skip compilation and pass the command to the BASIC interpreter at runtime, where ML-based extensions can handle it.
Important note¶
If a BASIC command is treated as extension, all related commands must also be extensions. For example:
FOR-NEXTpairs must both be extensions or both be compiledOPEN-PRINT#-CLOSEgroups should all be extensions or all compiled
Example¶
main:
:: @ rem JiffyDOS directory command (extension)
:: dload"file",8 rem JiffyDOS fast load (extension)
:: sys 49152 rem Machine code call (extension)
poke 53281,0 rem Standard BASIC (compiled - faster)
return
dynamic_loop:
rem Runtime-calculated loop (cannot optimize)
:: for i=1 to x: print i: next i
return
Performance impact¶
- Extension marker bypasses Blitz! optimization
- Interpreted statements execute at normal BASIC speed (much slower than compiled P-Code)
- Use sparingly to maintain performance benefits
- Extensions handled by ML routines may still be fast despite interpretation
Practical examples¶
Development vs production configuration¶
Development build¶
!blitz se rem Enable STOP key for debugging
!blitz ie rem Enable INPUT for testing
main:
:: poke 53280,0 rem Debug statement (interpreted)
input "continue (y/n)";a$
end
Production build¶
rem ** sa rem Disable STOP key
rem ** ia rem Disable INPUT (smaller size)
rem ** ne rem No extension listing
main:
poke 53280,0 rem All compiled for maximum speed
get k$ rem Use GET instead of INPUT
end
Integer optimization¶
rem Standard floating point (slower)
for i=1 to 100
poke 1024+i,i
next i
rem Optimized with integers (faster)
for i%=1 to 100
poke 1024+i%,i%
next i%
Extension marker usage¶
main:
poke 53280,0 rem Compiled (fast)
:: sys 49152 rem Extension (interpreted at runtime)
:: for i=1 to x: next i rem Dynamic loop (runtime only)
end
Comment preservation¶
Standard BPP+ comment removal does not affect Blitz! directives. This ensures the compiler receives all necessary control directives while minimizing program size.
Comment handling¶
; This BPP+ comment is REMOVED during preprocessing
rem This regular comment is REMOVED
rem ** se rem This directive is PRESERVED
!blitz sa rem Converted and PRESERVED as: rem ** sa
Result after preprocessing¶
rem ** se
rem ** sa
This behavior ensures:
- Blitz! compiler receives all directives
- Program size minimized by removing unnecessary comments
- Source code remains clean and maintainable
Blitz-specific constraints¶
When writing BPP+ code for Blitz! compilation, observe these requirements:
Array dimensioning¶
All multi-dimensional arrays must be explicitly dimensioned with DIM statements.
Rules¶
- Single-dimensional arrays: DIM optional (defaults to 11 elements)
- Multi-dimensional arrays: DIM required (compilation fails without it)
- Integer arrays: Use
%suffix for better performance
Examples¶
rem Single-dimensional arrays
dim a(10) rem Explicit dimension (recommended)
a(5)=100 rem Without DIM, defaults to DIM a(10)
rem Multi-dimensional arrays - DIM REQUIRED
dim b(10,10) rem Must use DIM
dim c(5,5,5) rem Must use DIM
rem Integer arrays for performance
dim px%(255) rem Integer array (faster)
dim py%(255) rem Integer array (faster)
Error example¶
rem ERROR: Multi-dimensional array without DIM
b(5,5)=100 rem Compilation fails - missing DIM statement
rem CORRECT: Use DIM first
dim b(10,10)
b(5,5)=100 rem OK
Integer optimization¶
Integer variables provide significant speed improvement in compiled programs.
Benefits¶
- True integer arithmetic (no float conversion)
- Faster FOR-NEXT loops
- Reduced memory overhead
- Better performance in array indexing
Usage¶
rem Standard floating point loop (slower)
for i=1 to 100
print i
next i
rem Optimized integer loop (faster with Blitz!)
for i%=1 to 100
print i%
next i%
rem Integer variables in calculations
x%=10
y%=20
z%=x%*y% rem Integer arithmetic (fast)
rem Mixing types (avoid for best performance)
x%=10
y=20
z=x%*y rem Mixed types (slower due to conversion)
Best practices¶
- Use integer variables for loop counters
- Use integer variables for array indices
- Use integer variables for simple calculations
- Use floating point only when decimals needed
Reserved identifier¶
The array name z*% is reserved by Blitz! internally and must be avoided.
Forbidden¶
dim z*%(100) rem ERROR: reserved array name
Alternatives¶
dim z(100) rem OK: standard array
dim zz%(100) rem OK: integer array
dim za%(100) rem OK: different name
dim arr_z%(100) rem OK: prefixed name
Performance optimization guidelines¶
Compile these for maximum speed¶
- Simple POKE/PEEK operations
- FOR-NEXT loops (especially with integer variables)
- Arithmetic calculations
- Array access
- GOSUB/GOTO branching
- Variable assignments
Use extensions (::) for¶
- SYS calls to machine code
- Self-modifying code
- Dynamic runtime calculations
- Commands not recognized by compiler
- Debugging statements
- Intentional delays that shouldn't be optimized
Example showing optimal compilation strategy¶
main:
rem Compiled statements (fast)
for i%=1 to 1000
poke 1024+i%,i%
next i%
rem Extension for machine code call
:: sys 49152
rem Compiled statements (fast)
for i%=1 to 1000
poke 55296+i%,1
next i%
end
Integration with BPP+ features¶
Blitz! directives work seamlessly with all BPP+ features:
game: {
!blitz se rem Enable STOP during development
init:
dim px%(255), py%(255) rem Integer arrays for speed
for i%=0 to 255
px%(i%)=i%*2
next i%
:: sys 49152 rem Extension for sprite routine
return
}
See also¶
- Compilation pipeline - Blitz! compiler workflow
- Lexical structure - Comment preservation rules
-
Authors: Skyles Electric Works, Commodore Buromaschinen GmbH and Daniel Kahlin ↩