Hacker's Edge Game Guide: Programming/Working with the KERNEL.SYS APIs

Working with the KERNEL.SYS APIs
Aug. 3, 2016

In this guide we will go through how to use the official KERNEL.SYS APIs to create some simple programs which rely on basic input and output. In this section there are also some fully working example code, however it doesn't really explain what's going on and how you should be calling these APIs.

JSR %print

This is the easiest API of the Kernel to use, and thankfully it is. It is very useful for displaying a null-terminated string to the terminal. These strings do not need to be newline terminated if you need that functionality. Here is how the API should be called:

.INC kernel.inc
LDY #hello
JSR %print
BRK

.DATA
hello:
DCS Hello World!\n\0

This API requires the use of the data segment to function. You only need to set the Y register to the offset in your data segment before making the actual API call. In this example, the label hello will be at an offset of $00. Also be sure to null-terminate the string you wish to display on the terminal. Failing to do so will have some very unexpected issues.

JSR %input

This API works exactly as the %print API, and uses the same options. You should be aware of where you place the input buffer in memory however, as the user can cause buffer overflows to occur with ease.

.INC kernel.inc
LDY #buffer
JSR %input
BRK

.DATA
string:
DCS Please program data before the string input buffer...\0
buffer:
DCB $00,$00,$00,$00,$00,$00,$00

It is not required to use DCB and zero out the buffer, the input API call will automatically null-terminate the string obtained from the user for you. It is recommended to have a common buffer location like this at the end of your program which is used for every input request. Then another part of your program after the input is complete can move the string to a more permanent location for usage during the program. This new location can also size limit the string.

JSR %strcmp

This is a basic null-terminated string compare API, it is more complex to use than the previous API calls as it requires 2 strings to be given to the API. It isn't too complex though.

.INC kernel.inc                                                                                   
LDA $f1                                                                                           
STA $fb                                                                                           
STA $fd                                                                                           
LDA #str1                                                                                           
STA $fa
LDA #str2
STA $fc
JSR %strcmp
LDA $ff
BRK

.DATA
str1:
DCS String 1\0
str2:
DCS String 1\0

This API call doesn't require any registers to work, rather it uses some specific memory locations in the zero-page to store pointers to the null-terminated strings you wish to compare. $fa and $fc should both contain a 16-bit address pointer to somewhere in memory where the strings you wish to compare are located. Unlike the last two APIs, this API can work with any memory location. In this example, we use the data segment as it is the easiest to work. The result of the compare is stored in $ff, you can then use BNE or BEQ to determine if the strings are equal(match) or not.

JSR %memclr

This API call lets you easily clear a page of memory, it uses a similar API call structure to strcmp API call as you will notice.

; This example clears memory from $f100-f1ff
; Size to clear is set to the Y register.
.INC kernel.inc
LDY #$ff
LDA #$00
STA $fa
LDA #$f1
STA $fb
LDA #0
JSR %memclr
BRK

The size of memory to clear is set to the Y register, and the beginning address to start the clear is set to $fa as a 16-bit address pointer. This could be used to say clear an input buffer section after a password is entered for example.

JSR %memcpy

This API call is very similar to the memory clearing API call, but we need to pass a second 16-bit address pointer.

; This example copys a page of memory from $f000 to $f100
; Size to copy is set in the Y register.
.INC kernel.inc
LDY #$ff
LDA #$00
STA $fa
STA $fc
LDA #$f0
STA $fb
LDA #$f1
STA $fd
JSR %memcpy
BRK

Similar to how we pass 2 address pointers in the string compare API call, we set the two memory locations through $fa and $fc, $fa is then copied over to $fc. The size of data to copy is set in the Y register.