de06353194
some programs are now 100% source compatible between C64 and Cx16 targets! import libraries have been rena;med |
||
---|---|---|
.idea | ||
compiler | ||
docs | ||
examples | ||
gradle/wrapper | ||
parser | ||
scripts | ||
.gitignore | ||
.travis.yml | ||
gradle.properties | ||
gradlew | ||
gradlew.bat | ||
LICENSE | ||
README.md | ||
settings.gradle |
Prog8 - Structured Programming Language for 8-bit 6502/65c02 microprocessors
Written by Irmen de Jong (irmen@razorvine.net)
Software license: GNU GPL 3.0, see file LICENSE
This is a structured programming language for the 8-bit 6502/6510/65c02 microprocessor from the late 1970's and 1980's as used in many home computers from that era. It is a medium to low level programming language, which aims to provide many conveniences over raw assembly code (even when using a macro assembler).
Documentation
Full documentation (syntax reference, how to use the language and the compiler, etc.) can be found at: https://prog8.readthedocs.io/
What use Prog8 provide?
- reduction of source code length over raw assembly
- modularity, symbol scoping, subroutines
- various data types other than just bytes (16-bit words, floats, strings)
- automatic variable allocations, automatic string and array variables and string sharing
- subroutines with an input- and output parameter signature
- constant folding in expressions
- conditional branches
- 'when' statement to provide a concise jump table alternative to if/elseif chains
- structs to group together sets of variables and manipulate them at once
- floating point operations (requires the C64 Basic ROM routines for this)
- abstracting away low level aspects such as ZeroPage handling, program startup, explicit memory addresses
- various code optimizations (code structure, logical and numerical expressions, unused code removal...)
- inline assembly allows you to have full control when every cycle or byte matters
- many built-in functions such as
sin
,cos
,rnd
,abs
,min
,max
,sqrt
,msb
,rol
,ror
,swap
,memset
,memcopy
,sort
andreverse
Rapid edit-compile-run-debug cycle:
- use a modern PC to do the work on
- very quick compilation times
- can automatically run the program in the Vice emulator after succesful compilation
- breakpoints, that let the Vice emulator drop into the monitor if execution hits them
- source code labels automatically loaded in Vice emulator so it can show them in disassembly
Two supported compiler targets (contributions to improve these or to add support for other machines are welcome!):
- "c64": Commodore-64 (6510 CPU = almost a 6502) premium support.
- "cx16": CommanderX16 (65c02 CPU) experimental support.
Additional required tools
64tass - cross assembler. Install this on your shell path. A recent .exe version of this tool for Windows can be obtained from my clone of this project. For other platforms it is very easy to compile it yourself (make ; make install).
A Java runtime (jre or jdk), version 8 or newer is required to run a prepackaged version of the compiler. If you want to build it from source, you'll need a Java SDK + Kotlin 1.3.x SDK (or for instance, IntelliJ IDEA with the Kotlin plugin).
It's handy to have an emulator (or a real machine perhaps!) to run the programs on. The compiler assumes the presence of the Vice emulator for the C64 target, and the x16emu emulator for the CommanderX16 target.
Example code
This code calculates prime numbers using the Sieve of Eratosthenes algorithm::
%import c64textio
%zeropage basicsafe
main {
ubyte[256] sieve
ubyte candidate_prime = 2
sub start() {
memset(sieve, 256, false) ; clear the sieve
txt.print("prime numbers up to 255:\n\n")
ubyte amount=0
repeat {
ubyte prime = find_next_prime()
if prime==0
break
txt.print_ub(prime)
txt.print(", ")
amount++
}
c64.CHROUT('\n')
txt.print("number of primes (expected 54): ")
txt.print_ub(amount)
c64.CHROUT('\n')
}
sub find_next_prime() -> ubyte {
while sieve[candidate_prime] {
candidate_prime++
if candidate_prime==0
return 0 ; we wrapped; no more primes available
}
; found next one, mark the multiples and return it.
sieve[candidate_prime] = true
uword multiple = candidate_prime
while multiple < len(sieve) {
sieve[lsb(multiple)] = true
multiple += candidate_prime
}
return candidate_prime
}
}
when compiled an ran on a C-64 you'll get:
One of the included examples (wizzine.p8) animates a bunch of sprite balloons and looks like this:
Another example (cube3d-sprites.p8) draws the vertices of a rotating 3d cube:
If you want to play a video game, a fully working Tetris clone is included in the examples:
The CommanderX16 compiler target is quite capable already too, here's a well known space ship animated in 3D with hidden line removal, in the CommanderX16 emulator: