Java API for C64

Introduction

Commodore 64 support for java_grinder is a work-in-progress, but complete enough for certain games and demos. The API can be added to (or replaced entirely) but modifying these files:

java/net/mikekohn/java_grinder/c64/VIC.java

java/net/mikekohn/java_grinder/c64/SID.java

api/c64_vic.cxx

api/c64_vic.h

api/c64_sid.cxx

api/c64_sid.h

generator/API_C64.h

generator/C64.cxx

generator/C64.h

The M6502 generator uses 16-bit math, and javac doesn't make much of an effort to optimize the bytecode output, so expect large program sizes. (Many features and API methods are placed into subroutines, but there is still plenty of inline code.)

Only NTSC is supported, although eventually I hope to have an API call for choosing NTSC or PAL.

Classes

The relevant Java classes are:

Memory Layout

BASIC and KERNAL ROMs are switched off. Graphics data may be copied to D000-DFFF as long as the processor port is toggled like this:

CPU.asm(" sei\n"); // disable interrupts
Memory.write8(0x01, 0x34); // enable all RAM
// copy data
Memory.write8(0x01, 0x35); // disable RAM at 0xd000-0xdfff
CPU.asm(" cli\n"); // enable interrupts

Class Members

CPU:

Insert inline assembly (uses naken_asm syntax, '\n' is required for new line, etc.):

Note: The X register is used internally as the Java stack pointer, so it will have to be saved and restored if used by inline assembly or custom API routines.


Grinder:

Call this at the beginning of a program to increase the variable stack size from 64 to 256 (238 if timerInterrupt() is used), at the cost of performance and increased code size.


Math:


Memory:

These are similar to PEEK and POKE in BASIC:


Timer:

Time is set in processor cycles. "Cycles" and "divider" set the countdown for CIA #1 timers A and B respectively, interrupt occurs when timer B underflows:


Turn the timer on or off:


TimerListener:

The program class should implement TimerListener, and include this method containing the interrupt code:


VIC:

Double-buffering is available if textEnable(1) is used, after which calls to textCopy() will update the screen. Color RAM is unaffected.

Binary data may be loaded at build time like this:

byte my_sprite[] = Memory.preloadByteArray("my_sprite.bin");

It then can be copied to the VIC-II graphics area:

VIC.copyDataFromArray(my_sprite, 0xe000, 63);

Sprite pointers need to be set for both screens unless only screen 0 will be used:

Memory.write8(0xc3f8, (byte)128); // sprite data at 0xe000
Memory.write8(0xc7f8, (byte)128); // sprite data at 0xe000

Sprite methods:

Sprite positions are updated during the vertical blanking interval.


Colors:


Registers:


Text support:


High-resolution graphics:


SID:

ADSR is set with a single 16-bit value arranged as SRAD (highest to lowest nybble).