Skip to content

A Commodore 128 software framework for enabling high-level development of C128 programs.

License

Notifications You must be signed in to change notification settings

c128lib/framework

Repository files navigation

Framework

A Commodore 128 software framework for enabling high-level development of C128 programs.

Integrate c128lib

  • Create a build.gradle file with this content
plugins {
    id "com.github.c64lib.retro-assembler" version "1.7.6"
}

repositories {
    mavenCentral()
}

apply plugin: "com.github.c64lib.retro-assembler"

retroProject {
    dialect = "KickAssembler"
    dialectVersion = "5.25"
    libDirs = [".ra/deps/c128lib", ".."]
    srcDirs = ["."]
    excludes = ["**/_*.asm", ".ra/**/*", "libs/*"]

    // dependencies
    libFromGitHub "c128lib/common", "0.6.0"
    libFromGitHub "c128lib/chipset", "0.7.1"
}
  • check for retro-assembler plugin latest version here
  • check for KickAssembler latest version here (set it on dialectVersion field)
  • set libDirs where libraries should live
  • set srcDirs where your source code should be
  • set excludes to indicate which files should be compiled
  • set a libFromGitHub row for every dependecies you need (with the right version)
  • install JDK
  • install Gradle
  • type gradle on command prompt and let the magic happens

Z80 code integration

Starting with v0.2.0 (still unreleased) are available some macros for Z80 code integration. Macros will help developers to setup Z80 code and prepare programs to start execution.

The code for Z80 will not run in parallel with the code for 8502 but there will only be preemptive multitasking. To understand mechanism for Z80 and 8502 switchover look at this post.

Macros

There are two kind of macros:

  • c128lib_PreZ80Code() and c128lib_PostZ80Code()
  • c128lib_RunZ80Code(z80CodeAddress)

The first two macros are needed to decorate your Z80 code (setup Mmu at start and jmp to bootlink routine at the end to consent 8502 restart). They must be called before and after your Z80 code.

The last macro will prepare environment to start Z80 code execution and handles return from z80 code.

Here an example of entry point to call Z80 code:


c128lib_BasicUpstart128($2000)

* = $2000 "Entry"
Entry: {
  // Some code executed on 8502

  c128lib_RunZ80Code(z80CodeAddress)

  // Other code executed on 8502

  rts
}

Then, you can define an area (called z80CodeAddress on the example above) and call macros to decorate it:


* = * "z80CodeAddress"
z80CodeAddress:
  c128lib_PreZ80Code()

  .byte $3E, $08        // LD A, #$08   -- load up the #$08 (H) byte
  .byte $32, $00, $04   // LD ($0400),A -- write on screen
  .byte $3C             // INC A
  .byte $32, $01, $04   // LD ($0401),A -- write on screen
  .byte $3E, $21        // LD A, #$21   -- load up the #$21 (!) byte
  .byte $32, $02, $04   // LD ($0402),A -- write on screen

  c128lib_PostZ80Code()

If you run this script, you'll see "HI!" printed on the 40 col screen by Z80 processor. At this time, z80 code must be written as a byte sequence of machine language instruction. I hope I can change that soon.

PS: i'm not an expert of z80 code... so that code it's quite stupid, probably not optimized etc..., take it just as an example.

I suggest to use GlassZ80 as assembler to generate machine language code. Code can be assembled on external file and imported with .import binary "file" to make code more readable and separate concerns. Z80 code can be assembled like:

java -jar glass.jar test.zasm test.bin

and then importing with:

.import binary "test.bin"