Prog8 documentation - 6.5-BETA

Prog8 logo

What is Prog8?

This is a compiled programming language targeting the 8-bit 6502 / 6510 / 65c02 microprocessors. This CPU is from the late 1970’s and early 1980’s and was used in many home computers from that era, such as the Commodore-64. The language aims to provide many conveniences over raw assembly code (even when using a macro assembler), while still being low level enough to create high performance programs.

Prog8 is copyright © Irmen de Jong (irmen@razorvine.net | http://www.razorvine.net). The project is on github: https://github.com/irmen/prog8.git

This software is licensed under the GNU GPL 3.0, see https://www.gnu.org/licenses/gpl.html

3d rotating sprites Simple wizzine sprite effect Fully playable tetris clone

Language features

  • It is a cross-compiler running on modern machines (Linux, MacOS, Windows, …) It generates a machine code program runnable on actual 8-bit 6502 hardware.
  • Fast execution speed due to compilation to native assembly code. It’s possible to write certain raster interrupt ‘demoscene’ effects purely in Prog8.
  • Provides a very convenient edit/compile/run cycle by being able to directly launch the compiled program in an emulator and provide debugging information to this emulator.
  • Based on simple and familiar imperative structured programming (it looks like a mix of C and Python)
  • Modular programming and scoping via modules, code blocks, and subroutines.
  • Provide high level programming constructs but at the same time stay close to the metal; still able to directly use memory addresses and ROM subroutines, and inline assembly to have full control when every register, cycle or byte matters
  • Subroutines with parameters and return values
  • complex nested expressions are possible
  • Variables are allocated statically
  • Nested subroutines can access variables from outer scopes to avoids the overhead to pass everything via parameters
  • Variable data types include signed and unsigned bytes and words, arrays, strings and floats.
  • Strings can contain excaped characters but also many symbols directly if they have a petscii equivalent, such as “♠♥♣♦π▚●○╳”. Characters like ^, _, \, {, } and | are also accepted and converted to the closest petscii equivalents.
  • High-level code optimizations, such as const-folding, expression and statement simplifications/rewriting.
  • Many built-in functions, such as sin, cos, rnd, abs, min, max, sqrt, msb, rol, ror, swap, sort and reverse
  • Programs can be run multiple times without reloading because of automatic variable (re)initializations.
  • Supports the sixteen ‘virtual’ 16-bit registers R0 .. R15 from the Commander X16, also on the C64.
  • If you only use standard kernal and prog8 library routines, it is possible to compile the exact same program for both machines (just change the compiler target flag)!

Code example

This code calculates prime numbers using the Sieve of Eratosthenes algorithm:

%import textio
%zeropage basicsafe

main {
    ubyte[256] sieve
    ubyte candidate_prime = 2       ; is increased in the loop

    sub start() {
        ; clear the sieve, to reset starting situation on subsequent runs
        sys.memset(sieve, 256, false)
        ; calculate primes
        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++
        }
        txt.nl()
        txt.print("number of primes (expected 54): ")
        txt.print_ub(amount)
        txt.nl()
    }

    sub find_next_prime() -> ubyte {
        while sieve[candidate_prime] {
            candidate_prime++
            if candidate_prime==0
                return 0        ; we wrapped; no more primes available in the sieve
        }

        ; 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 get this:

result when run on C-64

when the exact same program is compiled for the Commander X16 target, and run on the emulator, you get this:

result when run on CX16 emulator

Required tools

64tass - cross assembler. Install this on your shell path. It’s very easy to compile yourself. A recent precompiled .exe (only for Windows) can be obtained from my clone of this project. You need at least version 1.55.2257 of this assembler to correctly use the breakpoints feature. It’s possible to use older versions, but it is very likely that the automatic Vice breakpoints won’t work with them.

A Java runtime (jre or jdk), version 11 or newer is required to run the prog8 compiler itself. If you’re scared of Oracle’s licensing terms, most Linux distributions ship OpenJDK in their packages repository instead. For Windows it’s possible to get that as well; check out AdoptOpenJDK . For MacOS you can use the Homebrew system to install a recent version of OpenJDK.

Finally: an emulator (or a real machine ofcourse) to test and run your programs on. In C64 mode, thhe compiler assumes the presence of the Vice emulator. If you’re targeting the CommanderX16 instead, there’s the x16emu. Make sure you use cx16 emulator and roms V39 or newer! Starting from version 6.5, prog8 targets that system version. Your program may work on V38 but that will only be by luck.

Important

Building the compiler itself: (Only needed if you have not downloaded a pre-built ‘fat-jar’)

(Re)building the compiler itself requires a recent Kotlin SDK. The compiler is developed using IntelliJ IDEA , but only a Kotlin SDK installation should work as well, because the gradle tool is used to compile everything from the commandline.

Instructions on how to obtain a prebuilt compiler are in First, getting a working compiler.

Index