1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-06-03 07:29:37 +00:00
kickc/src/test/kc/examples/kernalload/kernalload.c
2020-12-30 01:55:04 +01:00

126 lines
3.4 KiB
C

// Load a file to memory using the C64 KERNAL LOAD functions
// The kernalload.ld link file creates a D64 disk image containing the executable and the sprite.
// To execute the program succesfully you must mount the D64 disk image and execute the kernalload.PRG program
#pragma link("kernalload.ld")
#pragma extension("d64")
#include <string.h>
#include <c64.h>
// Sprite file
#pragma data_seg(Sprite)
export char SPRITE[] = kickasm(resource "sprite.png") {{
.var pic = LoadPicture("sprite.png", List().add($000000, $ffffff))
.for (var y=0; y<21; y++)
.for (var x=0;x<3; x++)
.byte pic.getSinglecolorByte(x,y)
}};
// Program file
#pragma data_seg(Data)
// Address to load to
char* const LOAD_SPRITE = 0x3000;
char* const SCREEN = 0x0400;
char* const SPRITES_PTR = SCREEN+OFFSET_SPRITE_PTRS;
void main() {
// Load sprite file into memory
char status = loadFileToMemory(8, "SPRITE", LOAD_SPRITE);
if(status!=0xff) {
VICII->BORDER_COLOR = 0x02;
error(status);
}
// Show the loaded sprite on screen
VICII->SPRITES_ENABLE = %00000001;
SPRITES_PTR[0] = toSpritePtr(LOAD_SPRITE);
SPRITES_COLOR[0] = GREEN;
SPRITES_XPOS[0] = 0x15;
SPRITES_YPOS[0] = 0x33;
}
// Load a file to memory
// Returns a status:
// - 0xff: Success
// - other: Kernal Error Code (https://commodore.ca/manuals/pdfs/commodore_error_messages.pdf)
char loadFileToMemory( char device, char* filename, char* address) {
setnam(filename);
setlfs(device);
return load(address, false);
}
// Basic ERROR function
// ERROR. Show error.
void error(char err) {
char* const errCode = 0xff;
*errCode = err;
asm {
// Basic SHOWERR function
// Input: X = Error Code
ldx errCode
jsr $a437
}
}
// Kernal SETNAM function
// SETNAM. Set file name parameters.
void setnam(char* filename) {
char* const filename_len = 0xfd;
char** const filename_ptr = 0xfe;
*filename_len = (char)strlen(filename);
*filename_ptr = filename;
asm {
// Kernal SETNAM function
// SETNAM. Set file name parameters.
// Input: A = File name length; X/Y = Pointer to file name.
lda filename_len
ldx filename_ptr
ldy filename_ptr+1
jsr $ffbd
}
}
// SETLFS. Set file parameters.
void setlfs(char device) {
char* const deviceNum = 0xff;
*deviceNum = device;
asm {
// SETLFS. Set file parameters.
// Input: A = Logical number; X = Device number; Y = Secondary address.
ldx deviceNum
lda #1
ldy #0
jsr $ffba
}
}
//LOAD. Load or verify file. (Must call SETLFS and SETNAM beforehands.)
// Returns a status, 0xff: Success other: Kernal Error Code
char load(char* address, bool verify) {
char* loadOrVerify = 0xfd;
char** loadAddress = 0xfe;
char* status = 0xfd;
*loadOrVerify = (char)verify;
*loadAddress = address;
asm {
//LOAD. Load or verify file. (Must call SETLFS and SETNAM beforehands.)
// Input: A: 0 = Load, 1-255 = Verify; X/Y = Load address (if secondary address = 0).
// Output: Carry: 0 = No errors, 1 = Error; A = KERNAL error code (if Carry = 1); X/Y = Address of last byte loaded/verified (if Carry = 0).
ldx loadAddress
ldy loadAddress+1
lda loadOrVerify
jsr $ffd5
bcs error
lda #$ff
error:
sta status
}
return *status;
}