diff --git a/.gitignore b/.gitignore index af96791fc..3d77281fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +llvm-mos-sdk.code-workspace .vscode build diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index edf4a87a6..8d391f85c 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -36,3 +36,6 @@ endif() if(PLATFORM MATCHES rpc8e) add_subdirectory(rpc8e) endif() +if(PLATFORM MATCHES ^cx16) + add_subdirectory(cx16) +endif() diff --git a/examples/cx16/CMakeLists.txt b/examples/cx16/CMakeLists.txt new file mode 100644 index 000000000..00ffaf98f --- /dev/null +++ b/examples/cx16/CMakeLists.txt @@ -0,0 +1,11 @@ +add_executable(k_console_test.prg k_console_test.c) +install_example(k_console_test.prg) + +add_executable(k_datetime_test.prg k_datetime_test.c) +install_example(k_datetime_test.prg) + +add_executable(k_graph_test.prg k_graph_test.c) +install_example(k_graph_test.prg) + +add_executable(k_graph_line_test.prg k_graph_line_test.c) +install_example(k_graph_line_test.prg) diff --git a/examples/cx16/k_console_test.c b/examples/cx16/k_console_test.c new file mode 100644 index 000000000..01ddb5446 --- /dev/null +++ b/examples/cx16/k_console_test.c @@ -0,0 +1,54 @@ +// llvm-mos-sdk cx16 kernel test +// +// vim: set et ts=4 sw=4 + +#include +#include +#include + +#include +#include + +unsigned char face[64] = { + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 1, 1, + 1, 0, 1, 0, 0, 1, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 1, 0, 0, 1, 0, 1, + 1, 0, 0, 1, 1, 0, 0, 1, + 1, 1, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 +}; + +void wait_key(void) +{ + while (cbm_k_getin() == 0) + ; +} + +void console_puts(const char *str, unsigned char wordwrap) +{ + uint8_t c = 0; + while ((c = *str++) != 0) + { + cx16_k_console_put_char(c, wordwrap); + } +} + +int main(void) +{ + cx16_k_screen_mode_set(128); + cx16_k_graph_set_colors(1, 0, 0); + cx16_k_console_init(0, 0, 0, 0); + console_puts("\x92Hello Commander X16!", 0); + + wait_key(); + + // BUG: I don't understand why this clears/scrolls screen... + cx16_k_console_put_image(face, 8, 8); + + wait_key(); + + cx16_k_screen_mode_set(0); + printf("DONE.\n"); +} diff --git a/examples/cx16/k_datetime_test.c b/examples/cx16/k_datetime_test.c new file mode 100644 index 000000000..bbe0a94b0 --- /dev/null +++ b/examples/cx16/k_datetime_test.c @@ -0,0 +1,70 @@ +// llvm-mos-sdk cx16 kernel test +// +// vim: set et ts=4 sw=4 + +#include +#include +#include + +#include +#include + +static void hexdump(const void *ptr, size_t bytes) +{ + uint8_t *p = (uint8_t *)ptr; + for (size_t i = 0; i < bytes; i++) + { + if ((i & 0xf) == 0) + { + if (i) + { + printf("\n"); + } + printf("%04x: ", i); + } + else + { + printf(", "); + } + printf("%02x", p[i]); + } + printf("\n"); +} + +int main(void) +{ + static cx16_date_time_t tm; + + putchar(15); // ISO mode + printf("llvm-mos-sdk CX16 Kernal Test\n\n"); + + printf("\ncx16_k_clock_get_date_time(&tm);\n"); + cx16_k_clock_get_date_time(&tm); + + printf("Result: year=%d, mon=%d, day=%d, hour=%d, min=%d, sec=%d, jif=%d\n", + 1900 + tm.year, + tm.mon, + tm.day, + tm.hour, + tm.min, + tm.sec, + tm.jif); + hexdump(&tm, sizeof(tm)); + + printf("\ncx16_k_clock_set_date_time(2023-1900, 4, 5, 10, 12, 13, 42);\n"); + cx16_k_clock_set_date_time(2023 - 1900, 4, 5, 10, 12, 13, 42); + + cx16_k_clock_get_date_time(&tm); + + printf("Result: year=%d, mon=%d, day=%d, hour=%d, min=%d, sec=%d, jif=%d\n", + 1900 + tm.year, + tm.mon, + tm.day, + tm.hour, + tm.min, + tm.sec, + tm.jif); + hexdump(&tm, sizeof(tm)); + + printf("Done\n"); // finished +} diff --git a/examples/cx16/k_graph_line_test.c b/examples/cx16/k_graph_line_test.c new file mode 100644 index 000000000..e625ecce1 --- /dev/null +++ b/examples/cx16/k_graph_line_test.c @@ -0,0 +1,37 @@ +// llvm-mos-sdk cx16 kernel test +// +// vim: set et ts=4 sw=4 + +#include +#include + +#include +#include + +int main(void) +{ + int16_t x, y; + uint8_t c; + + cx16_k_screen_mode_set(128); // 320x240x8-bpp + cx16_k_graph_init(NULL); // initialize kernal graph with defaults + c = 0; // initialize color + + // draw line pattern + for (y = 0; y < 240; y += 3) + { + cx16_k_graph_set_colors(c++, 0, 0); + cx16_k_graph_draw_line(0, y, 319, 239 - y); + } + + for (x = 0; x < 320; x += 3) + { + cx16_k_graph_set_colors(c++, 0, 0); + cx16_k_graph_draw_line(x, 0, 319 - x, y); + } + + while (cbm_k_getin() == 0) // wait for a keypress + ; + + cx16_k_screen_mode_set(0); // reset screen mode to 80x30 +} diff --git a/examples/cx16/k_graph_test.c b/examples/cx16/k_graph_test.c new file mode 100644 index 000000000..24fab6c29 --- /dev/null +++ b/examples/cx16/k_graph_test.c @@ -0,0 +1,129 @@ +// llvm-mos-sdk cx16 kernel test +// +// vim: set et ts=4 sw=4 + +#include +#include +#include + +#include +#include + +unsigned char face[64] = {1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 0, 0, 0, 1, 1, + 1, 0, 5, 0, 0, 5, 0, 1, + 1, 0, 0, 0, 0, 0, 0, 1, + 1, 0, 1, 0, 0, 1, 0, 1, + 1, 0, 0, 1, 1, 0, 0, 1, + 1, 1, 0, 0, 0, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 + }; + +void wait_key(void) +{ + while (cbm_k_getin() == 0) + ; +} + +void graph_put_string(unsigned int x, unsigned int y, const char *str) +{ + graph_pos_t pos; + pos.x = x; + pos.y = y; + uint8_t c = 0; + while ((c = *str++) != 0) + { + cx16_k_graph_put_char(&pos, c); + } +} + +int main(void) +{ + uint8_t scolor = 1; // stroke color + int16_t xpos = 160, ypos = 120; // initial face position + int8_t xd = 1; // initial face direction + + // set 320x240x8-bpp + cx16_k_screen_mode_set(128); + + // init default graphics driver + cx16_k_graph_init(0); + + // default font + cx16_k_graph_set_font(0); + + // draw outline box + cx16_k_graph_set_colors(4, 0, 0); + cx16_k_graph_draw_line(10, 10, 320 - 10, 10); + cx16_k_graph_draw_line(320 - 10, 10, 320 - 10, 240 - 10); + cx16_k_graph_draw_line(320 - 10, 240 - 10, 10, 240 - 10); + cx16_k_graph_draw_line(10, 240 - 10, 10, 10); + + // welcome message + cx16_k_graph_set_colors(0, 0, 0); + graph_put_string(75, 20, "Hello Commander X16 and llvm-mos!\n\n Basic cx16_k_graph* wrapper test..."); + + // window clipping test + cx16_k_graph_set_window(0, 0, 320 / 2, 240); + cx16_k_graph_set_colors(4, 0, 0); + graph_put_string(50, 60, "This text is using clipping to draw in two colors."); + cx16_k_graph_set_window(320 / 2, 0, 320 / 2, 240); + cx16_k_graph_set_colors(5, 0, 0); + graph_put_string(50, 60, "This text is using clipping to draw in two colors."); + + // full screen window + cx16_k_graph_set_window(0, 0, 0, 0); + + // draw outline rectangle + cx16_k_graph_set_colors(6, 0, 0); + cx16_k_graph_draw_rect(50, 50, 42, 14, 0, 0); + // move (copy) rectangle + cx16_k_graph_move_rect(50, 50, 65, 65, 42, 15); + + // label moved rectangle + cx16_k_graph_set_colors(0, 0, 0); + graph_put_string(110, 75, "<- rectangle moved here"); + + // stop message + graph_put_string(110, 240 - 20, "Press a key to stop"); + + // until a key is pressed, bounce face and rectangle + while (cbm_k_getin() == 0) + { + // draw 8x8 "face" image + cx16_k_graph_draw_image(xpos, ypos, face, 8, 8); + + // update x position + xpos += xd; + + // if near edges, reverse direction + if (xpos < 64 || xpos > 320 - 64) + { + xd = -xd; + } + + // draw filled rectangle offset from face using incrementing color + scolor += 1; + cx16_k_graph_set_colors(scolor, scolor + 1, 0); + cx16_k_graph_draw_rect(xpos - 12, ypos + 20, 8, 16, 0, 1); + + waitvsync(); + } + + // erase old message + cx16_k_graph_set_colors(1, 1, 1); + cx16_k_graph_draw_rect(20, 240 - 20 - 10, 280, 20, 0, 1); + + // exit message + cx16_k_graph_set_colors(0, 0, 0); + graph_put_string(110, 240 - 20, "Press a key to exit"); + + // wait for final key press + wait_key(); + + // restore 80x60 text mode + cx16_k_screen_mode_set(0); + + // done message + printf("DONE.\n"); +} diff --git a/mos-platform/atari8-common/atari.h b/mos-platform/atari8-common/atari.h index 1844e481f..b60fcf5b1 100644 --- a/mos-platform/atari8-common/atari.h +++ b/mos-platform/atari8-common/atari.h @@ -3,7 +3,7 @@ // See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license // information. -// Originally from cc65. Modififed from original version. +// Originally from cc65. Modified from original version. /*****************************************************************************/ /* */ diff --git a/mos-platform/c64/c64.h b/mos-platform/c64/c64.h index 6c66d0c79..6a77719e6 100644 --- a/mos-platform/c64/c64.h +++ b/mos-platform/c64/c64.h @@ -3,7 +3,7 @@ // See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license // information. -// Originally from cc65. Modififed from original version. +// Originally from cc65. Modified from original version. /*****************************************************************************/ /* */ diff --git a/mos-platform/commodore/CMakeLists.txt b/mos-platform/commodore/CMakeLists.txt index 7835601aa..0ed574f03 100644 --- a/mos-platform/commodore/CMakeLists.txt +++ b/mos-platform/commodore/CMakeLists.txt @@ -30,7 +30,8 @@ add_platform_library(commodore-c cbm_k_chkin.s cbm_k_chrin.c cbm_k_chrout.c - cbm_k_ciout.c + cbm_k_cint.c + cbm_k_ciout.c cbm_k_ckout.s cbm_k_clall.c cbm_k_close.c diff --git a/mos-platform/commodore/cbm.h b/mos-platform/commodore/cbm.h index 6fb0b58b9..bf624223b 100644 --- a/mos-platform/commodore/cbm.h +++ b/mos-platform/commodore/cbm.h @@ -3,7 +3,7 @@ // See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license // information. -// Originally from cc65. Modififed from original version. +// Originally from cc65. Modified from original version. /*****************************************************************************/ /* */ @@ -206,6 +206,7 @@ void cbm_k_bsout (unsigned char C); unsigned char cbm_k_chkin (unsigned char FN); unsigned char cbm_k_chrin (void); void cbm_k_chrout (unsigned char C); +void cbm_k_cint (void); void cbm_k_ciout (unsigned char C); unsigned char cbm_k_ckout (unsigned char FN); void cbm_k_clall (void); @@ -214,10 +215,10 @@ void cbm_k_clrch (void); unsigned char cbm_k_getin (void); unsigned cbm_k_iobase (void); void cbm_k_listen (unsigned char dev); -unsigned int cbm_k_load(unsigned char flag, unsigned addr); +void *cbm_k_load(unsigned char flag, void *startaddr); unsigned char cbm_k_open (void); unsigned char cbm_k_readst (void); -unsigned char cbm_k_save(unsigned int start, unsigned int end); +unsigned char cbm_k_save(void *startaddr, void *endaddr_plusone); void cbm_k_scnkey (void); void cbm_k_second (unsigned char addr); void cbm_k_setlfs (unsigned char LFN, unsigned char DEV, diff --git a/mos-platform/commodore/cbm_k_cint.c b/mos-platform/commodore/cbm_k_cint.c new file mode 100644 index 000000000..2b0e8f7e5 --- /dev/null +++ b/mos-platform/commodore/cbm_k_cint.c @@ -0,0 +1,5 @@ +extern void __CINT(void); + +void cbm_k_cint(void) { + __CINT(); +} diff --git a/mos-platform/commodore/cbm_k_load.s b/mos-platform/commodore/cbm_k_load.s index 610235936..a3bd30e23 100644 --- a/mos-platform/commodore/cbm_k_load.s +++ b/mos-platform/commodore/cbm_k_load.s @@ -3,18 +3,19 @@ .text ; -; unsigned int cbm_k_load(unsigned char flag, unsigned addr); +; void *cbm_k_load(unsigned char verifyflag, void *startaddr); // if result address < 256, likely an error code +; a rc2/3 ; .global cbm_k_load cbm_k_load: - ldy __rc2 + ldx __rc2 + ldy __rc2+1 jsr __LOAD bcc noerror ; error code in a ; ldx #0 rts noerror: - txa - sty __rc2 - ldx __rc2 + stx __rc2 ; store end+1 low + sty __rc2+1 ; store end+1 high rts diff --git a/mos-platform/commodore/cbm_k_save.s b/mos-platform/commodore/cbm_k_save.s index cd9851452..69f588f4f 100644 --- a/mos-platform/commodore/cbm_k_save.s +++ b/mos-platform/commodore/cbm_k_save.s @@ -2,15 +2,14 @@ .text ; -; unsigned char cbm_k_save(unsigned int start, unsigned int end); +; unsigned char cbm_k_save(void *startaddr, void *endaddr_plusone); +; rc2/3 rc4/5 ; .global cbm_k_save cbm_k_save: - sta __rc4 - stx __rc5 - ldx __rc2 - ldy __rc3 - lda #__rc4 + ldx __rc4 + ldy __rc5 + lda #__rc2 jsr __SAVE bcs someerror lda #0 diff --git a/mos-platform/commodore/cbm_kernal.inc b/mos-platform/commodore/cbm_kernal.inc index 9b88134ef..e8776322a 100644 --- a/mos-platform/commodore/cbm_kernal.inc +++ b/mos-platform/commodore/cbm_kernal.inc @@ -14,13 +14,15 @@ #ifdef __CX16__ ; CX16 extended jump table + SAVEHL = $FEBA KBDBUF_PEEK = $FEBD KBDBUF_GET_MODIFIERS = $FEC0 KBDBUF_PUT = $FEC3 I2C_READ_BYTE = $FEC6 I2C_WRITE_BYTE = $FEC9 - CX_MONITOR = $FECC + MONITOR = $FECC ENTROPY_GET = $FECF + KEYMAP = $FED2 CONSOLE_SET_PAGE_MSG = $FED5 CONSOLE_PUT_IMAGE = $FED8 CONSOLE_INIT = $FEDB @@ -58,8 +60,8 @@ GRAPH_SET_FONT = $FF3B GRAPH_GET_CHAR_SIZE = $FF3E GRAPH_PUT_CHAR = $FF41 - MULTI_ACPTR = $FF44 - RESTORE_BASIC = $FF47 + MACPTR = $FF44 + ENTER_BASIC = $FF47 CLOCK_SET_DATE_TIME = $FF4D CLOCK_GET_DATE_TIME = $FF50 JOYSTICK_SCAN = $FF53 @@ -68,6 +70,7 @@ SCREEN_SET_CHARSET = $FF62 MOUSE_CONFIG = $FF68 MOUSE_GET = $FF6B + MOUSE_SCAN = $FF71 #endif #ifdef __C128__ diff --git a/mos-platform/cx16/CMakeLists.txt b/mos-platform/cx16/CMakeLists.txt index fbd1962f3..ecd9adcad 100644 --- a/mos-platform/cx16/CMakeLists.txt +++ b/mos-platform/cx16/CMakeLists.txt @@ -7,8 +7,81 @@ endif() install(FILES _6522.h cx16.h TYPE INCLUDE) install(FILES imag-regs.ld link.ld TYPE LIB) +install(FILES cx16.inc DESTINATION ${ASMINCDIR}) + add_platform_object_file(cx16-basic-header basic-header.o basic-header.S) -add_platform_library(cx16-c kernal.S) -target_include_directories(cx16-c BEFORE PUBLIC .) +add_platform_library(cx16-c + cx16_k_clock_get_date_time.s + cx16_k_clock_set_date_time.s + cx16_k_console_get_char.s + cx16_k_console_init.s + cx16_k_console_put_char.s + cx16_k_console_put_image.s + cx16_k_console_set_paging_message.s + cx16_k_enter_basic.s + cx16_k_entropy_get.s + cx16_k_fb_cursor_next_line.s + cx16_k_fb_cursor_position.s + cx16_k_fb_fill_pixels.s + cx16_k_fb_filter_pixels.s + cx16_k_fb_get_info.s + cx16_k_fb_get_pixel.s + cx16_k_fb_get_pixels.s + cx16_k_fb_init.s + cx16_k_fb_move_pixels.s + cx16_k_fb_set_8_pixels.s + cx16_k_fb_set_8_pixels_opaque.s + cx16_k_fb_set_palette.s + cx16_k_graph_clear.s + cx16_k_graph_draw_image.s + cx16_k_graph_draw_line.s + cx16_k_graph_draw_oval.s + cx16_k_graph_draw_rect.s + cx16_k_graph_get_char_size.s + cx16_k_graph_init.s + cx16_k_graph_move_rect.s + cx16_k_graph_put_char.s + cx16_k_graph_set_colors.s + cx16_k_graph_set_font.s + cx16_k_graph_set_window.s + cx16_k_i2c_read_byte.s + cx16_k_i2c_write_byte.s + cx16_k_joystick_get.s + cx16_k_joystick_scan.s + cx16_k_kbdbuf_get_modifiers.s + cx16_k_kbdbuf_peek.s + cx16_k_kbdbuf_put.s + cx16_k_keymap_get_id.s + cx16_k_keymap_set.s + cx16_k_macptr.s + cx16_k_memory_copy.s + cx16_k_memory_crc.s + cx16_k_memory_decompress.s + cx16_k_memory_fill.s + cx16_k_monitor.s + cx16_k_mouse_config.s + cx16_k_mouse_get.s + cx16_k_mouse_scan.s + cx16_k_savehl.s + cx16_k_screen_mode_get.s + cx16_k_screen_mode_set.s + cx16_k_screen_set_charset.s + cx16_k_sprite_set_image.s + cx16_k_sprite_set_position.s + get_numbanks.s + get_ostype.s + get_tv.s + set_tv.s + vera_layer_enable.s + vera_sprites_enable.s + videomode.s + vpeek.s + vpoke.s + waitvsync.s + kernal.S +) +target_include_directories(cx16-c BEFORE PUBLIC .) +target_compile_options(cx16-c PUBLIC -mcpu=mosw65c02) +target_link_libraries(cx16-c PRIVATE common-asminc cx16) diff --git a/mos-platform/cx16/NOTES.md b/mos-platform/cx16/NOTES.md new file mode 100644 index 000000000..84ac3b72b --- /dev/null +++ b/mos-platform/cx16/NOTES.md @@ -0,0 +1,5 @@ +# Commander X16 llvm-mos-sdk notes + +llvm-mos-sdk CX16 kernel stubs - Xark 2023 - [https://github.com/XarkLabs](https://github.com/XarkLabs) + +TODO: Do fb_* function wrappers make sense? Should these be calling via RAM vectors (or additional ifb_* versions)? diff --git a/mos-platform/cx16/_6522.h b/mos-platform/cx16/_6522.h index fa03eccab..33000ed4d 100644 --- a/mos-platform/cx16/_6522.h +++ b/mos-platform/cx16/_6522.h @@ -3,7 +3,7 @@ // See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license // information. // -// Originally from cc65. Modififed from original version. +// Originally from cc65. Modified from original version. /*****************************************************************************/ /* */ diff --git a/mos-platform/cx16/basic-header.S b/mos-platform/cx16/basic-header.S index 0bfea77aa..52aeb41c6 100644 --- a/mos-platform/cx16/basic-header.S +++ b/mos-platform/cx16/basic-header.S @@ -2,11 +2,11 @@ ; follows the header if it's at the beginning of BASIC memory ($0801). .section .basic_header,"aR",@progbits - .short next_line ; address of next BASIC line - .short 7773 ; line number: l33t for LLVM, a hint that this program was - ; compiled with LLVM + .short next_line ; address of next BASIC line + .short 7773 ; line number: l33t for LLVM, a hint that this program was + ; compiled with LLVM .byte 0x9e ; SYS keyword BASIC token .mos_addr_asciz _start, 4 ; the location of the _start symbol, in 4 decimal - ; ASCII digits + ; ASCII digits next_line: - .short 0 ; end of basic program + .short 0 ; end of basic program diff --git a/mos-platform/cx16/cx16.h b/mos-platform/cx16/cx16.h index 5f45a31e1..a9f7046b3 100644 --- a/mos-platform/cx16/cx16.h +++ b/mos-platform/cx16/cx16.h @@ -3,7 +3,7 @@ // See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license // information. // -// Originally from cc65. Modififed from original version. +// Originally from cc65. Modified from original version. /*****************************************************************************/ /* */ @@ -141,6 +141,7 @@ /* get_tv() return codes ** set_tv() argument codes +** NOTE: llvm-mos-sdk added newer 240P modes */ enum { TV_NONE = 0x00, @@ -150,7 +151,15 @@ enum { TV_NONE2, TV_VGA2, TV_NTSC_MONO, - TV_RGB2 + TV_RGB2, + TV_NONE_240P, + TV_VGA_240P, + TV_NTSC_COLOR_240P, + TV_RGB_240P, + TV_NONE2_240P, + TV_VGA2_240P, + TV_NTSC_MONO_240P, + TV_RGB2_240P }; /* Video modes for videomode() */ @@ -296,5 +305,164 @@ struct __emul { /* An array window into the half Mebibyte or two Mebibytes of banked RAM */ #define BANK_RAM ((volatile unsigned char *)0xA000) -/* End of cX16.h */ -#endif +/*****************************************************************************/ +/* CX16 kernal functions */ +/*****************************************************************************/ + +/* Kernel function structure type definitions */ +typedef struct +{ + unsigned char year, mon, day, hour, min, sec, jif; +} cx16_date_time_t; /* cx16_k_clock_get_date_time() */ + +typedef struct +{ + unsigned int width, height; + unsigned char depth; +} cx16_fb_info_t; /* cx16_k_fb_get_info_depth() */ + +typedef struct +{ + void *fb_init; + void *fb_get_info; + void *fb_set_palette; + void *fb_cursor_position; + void *fb_cursor_next_line; + void *fb_get_pixel; + void *fb_get_pixels; + void *fb_set_pixel; + void *fb_set_pixels; + void *fb_set_8_pixels; + void *fb_set_8_pixels_opaque; + void *fb_fill_pixels; + void *fb_filter_pixels; + void *fb_move_pixels; +} graph_fb_functions_t; /* cx16_k_graph_init() */ + +typedef struct +{ + int x, y; +} graph_pos_t; /* fb_graph_put_char() */ + +typedef struct +{ + int x, y; +} mouse_pos_t; /* cx16_k_mouse_get() */ + +typedef struct +{ + unsigned char mode, columns, rows; +} screen_mode_info_t; /* cx16_k_screen_mode_get() */ + +/* Kernal-level functions */ +void cx16_k_clock_get_date_time(cx16_date_time_t *datetime_ptr); +void cx16_k_clock_set_date_time(unsigned char year, unsigned char mon, unsigned char day, unsigned char hour, unsigned char min, unsigned char sec, unsigned char jif); +unsigned char cx16_k_console_get_char(void); +void cx16_k_console_init(unsigned int x, unsigned int y, unsigned int width, unsigned int height); +void cx16_k_console_put_char(unsigned char c, unsigned char wrapwordflag); +void cx16_k_console_put_image(void *imageaddr, unsigned int width, unsigned int height); +void cx16_k_console_set_paging_message(void *msgaddr); +void cx16_k_enter_basic(unsigned char coldstart) __attribute__((noreturn)); +unsigned long cx16_k_entropy_get(void); // returns 24-bit value +void cx16_k_fb_cursor_next_line(unsigned int x); +void cx16_k_fb_cursor_position(unsigned int x, unsigned int y); +void cx16_k_fb_fill_pixels(unsigned int count, unsigned int step, unsigned char color); +void cx16_k_fb_filter_pixels(void *filterfunc, unsigned int count); +void cx16_k_fb_get_info(cx16_fb_info_t *info_ptr); +unsigned char fb_get_pixel(void); +void cx16_k_fb_get_pixels(void *pixeladdr, unsigned int count); +void cx16_k_fb_init(void); +void cx16_k_fb_move_pixels(unsigned int sx, unsigned int sy, unsigned int tx, unsigned int ty, unsigned int count); +void cx16_k_fb_set_8_pixels(unsigned char pattern, unsigned char color); +void cx16_k_fb_set_8_pixels_opaque(unsigned char pattern, unsigned char mask, unsigned char color1, unsigned char color2); +void cx16_k_fb_set_palette(void *paladdr, unsigned char index, unsigned char count); +void cx16_k_graph_clear(void); +void cx16_k_graph_draw_image(unsigned int x, unsigned int y, void *imageaddr, unsigned int width, unsigned int height); +void cx16_k_graph_draw_line(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2); +void cx16_k_graph_draw_oval(unsigned int x, unsigned int y, unsigned int width, unsigned int height, unsigned int corner_radius, unsigned char fillflag); +void cx16_k_graph_draw_rect(unsigned int x, unsigned int y, unsigned int width, unsigned int height, unsigned int corner_radius, unsigned char fillflag); +long cx16_k_graph_get_char_size(unsigned char c, unsigned char style); // if printable returns info (0x00bbwwhh), else negative style byte (0xFF0000ss) +void cx16_k_graph_init(graph_fb_functions_t *fb_funcs_ptr); +void cx16_k_graph_move_rect(unsigned int sx, unsigned int sy, unsigned int tx, unsigned int ty, unsigned int width, unsigned int height); +void cx16_k_graph_put_char(graph_pos_t *pos_ptr, unsigned char c); +void cx16_k_graph_set_colors(unsigned char stroke, unsigned char fill, unsigned char background); +void cx16_k_graph_set_font(void *fontaddr); +void cx16_k_graph_set_window(unsigned int x, unsigned int y, unsigned int width, unsigned int height); +int cx16_k_i2c_read_byte(unsigned char device, unsigned char offset); // returns negative on error +int cx16_k_i2c_write_byte(unsigned char device, unsigned char offset, unsigned char byte); // return negative on error +long cx16_k_joystick_get(unsigned char sticknum); // returns $YYYYXXAA (see docs, result negative if joystick not present) +void cx16_k_joystick_scan(void); +unsigned char cx16_k_kbdbuf_get_modifiers(void); +int cx16_k_kbdbuf_peek(unsigned char *index_ptr); // returns negative if empty, if index_ptr non-NULL set contents to queue length +void cx16_k_kbdbuf_put(unsigned char c); +const char* cx16_k_keymap_get_id(void); +unsigned char cx16_k_keymap_set(const char* identifier); // returns 0 on success +long cx16_k_macptr(unsigned char count, unsigned char noadvance, void *destaddr); // return negative if not supported +void cx16_k_memory_copy(void *source, void *target, unsigned int num_bytes); +unsigned int cx16_k_memory_crc(void *dataaddr, unsigned int num_bytes); +void cx16_k_memory_decompress(void *inaddr, void *outaddr); +void cx16_k_memory_fill(void *addr, unsigned int num_bytes, unsigned char value); +void cx16_k_monitor(void) __attribute__((noreturn)); +void cx16_k_mouse_config(unsigned char showmouse, unsigned char xsize8, unsigned char ysize8); +unsigned char cx16_k_mouse_get(mouse_pos_t *mouse_pos_ptr); // returns mouse button byte +void cx16_k_mouse_scan(void); +unsigned char cx16_k_savehl(void *startaddr, void *endaddr_plusone); // returns 0 on success +unsigned char cx16_k_screen_mode_get(screen_mode_info_t *info_ptr); // returns 0 on success +unsigned char cx16_k_screen_mode_set(unsigned char mode); // returns 0 on success +void cx16_k_screen_set_charset(unsigned char charset_type, void *charsetaddr); +unsigned char cx16_k_sprite_set_image(unsigned char num, unsigned char w, unsigned char h, unsigned char maskflag, void *imageaddr, void *maskaddr, unsigned char bpp); // returns 0 on success +unsigned char cx16_k_sprite_set_position(unsigned char sprnum, unsigned int xpos, unsigned int ypos); // returns 0 on success + +/* cc65 compatible cx16 functions */ + +/* Return the number of 8K RAM banks that the machine has */ +/* at 0xA000-0xBFFF using MEMTOP (64=512K up to 256=2MB) */ +unsigned short get_numbanks(void); // return number of 8K RAM banks at 0xA000-0xBFFF (64=512K up to 256=2MB) + +/* Get the ROM build version. +** -1 -- custom build +** Negative -- prerelease build +** Positive -- release build +*/ +signed char get_ostype(void); // return ROM build version (negative pre-release, -1=custom) + +/* Return the video signal type that the machine is using. +** Return a TV_xx constant. +*/ +unsigned char get_tv(void); // return TV_* enum constant for current video signal type + +/* Set the video signal type that the machine will use. +** Call with a TV_xx constant. +** NOTE: Be careful, can overrides user setting for current monitor type (set in config menu) +*/ +void set_tv(unsigned char type); // set video signal type using TV_* enum constant + +/* Display the layers that are "named" by the bit flags in layers. +** A value of 0b01 shows layer 0, a value of 0b10 shows layer 1, +** a value of 0b11 shows both layers. Return the previous value. +*/ +unsigned char vera_layer_enable(unsigned char layers); // enable/disable VERA layers 0/1 (bits 0/1), returns previous + +/* Enable the sprite engine when mode is non-zero (true); +** disable sprites when mode is zero. Return the previous mode. +*/ +unsigned char vera_sprites_enable(unsigned char enable); // enable/disable VERA sprites (0=off, non-zero=on), returns previous + +/* Set the video mode, return the old mode. +** Return -1 if Mode isn't valid. +** Call with one of the VIDEOMODE_xx constants. +*/ +signed char videomode(signed char mode); // set video mode using VIDEOMODE_* enum constant, returns previous or -1 if error + +/* Get a byte from a location in VERA's internal address space. */ +unsigned char vpeek(unsigned long addr); // read byte from VERA VRAM address + +/* Put a byte into a location in VERA's internal address space. +** (addr is second instead of first for the sake of code efficiency.) +*/ +void vpoke(unsigned char data, unsigned long addr); // write byte value to VERA VRAM address + +void waitvsync(void); // wait for the vertical blank interrupt + +#endif // _CX16_H + diff --git a/mos-platform/cx16/cx16.inc b/mos-platform/cx16/cx16.inc new file mode 100644 index 000000000..176765735 --- /dev/null +++ b/mos-platform/cx16/cx16.inc @@ -0,0 +1,237 @@ +; Copyright 2022 LLVM-MOS Project +; Licensed under the Apache License, Version 2.0 with LLVM Exceptions. +; See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license +; information. + +; Commander X16 definitions + +; save X16 kernal registers (r6-r10) that llvm-mos needs preserved (rc20-rc29) using Y +.macro X16_kernal_push_r6_r10 + ldy __r6 + phy + ldy __r6+1 + phy + ldy __r7 + phy + ldy __r7+1 + phy + ldy __r8 + phy + ldy __r8+1 + phy + ldy __r9 + phy + ldy __r9+1 + phy + ldy __r10 + phy + ldy __r10+1 + phy +.endm + +; restore X16 kernal registers (r6-r10) that llvm-mos needs preserved (rc20-rc29) using Y +.macro X16_kernal_pop_r6_r10 + ply + sty __r10+1 + ply + sty __r10 + ply + sty __r9+1 + ply + sty __r9 + ply + sty __r8+1 + ply + sty __r8 + ply + sty __r7+1 + ply + sty __r7 + ply + sty __r6+1 + ply + sty __r6 +.endm + +; cx16 hardware I/O addresses (derived from x16-rom io.inc) +; https://github.com/X16Community/x16-rom/blob/master/inc/io.inc + +ram_bank = 0 ; read/write current RAM bank at $A000-$BFFF +rom_bank = 1 ; read/write current ROM bank at $C000-$FFFF + +IO_PAGE = $9f ; I/O addresses are $9fxx + +via1 = $9f00 ; VIA 6522 #1 +d1prb = (via1+0) +d1pra = (via1+1) +d1ddrb = (via1+2) +d1ddra = (via1+3) +d1t1l = (via1+4) +d1t1h = (via1+5) +d1t1ll = (via1+6) +d1t1lh = (via1+7) +d1t2l = (via1+8) +d1t2h = (via1+9) +d1sr = (via1+10) +d1acr = (via1+11) +d1pcr = (via1+12) +d1ifr = (via1+13) +d1ier = (via1+14) +d1ora = (via1+15) + +via2 = $9f10 ; VIA 6522 #2 +d2prb = (via2+0) +d2pra = (via2+1) +d2ddrb = (via2+2) +d2ddra = (via2+3) +d2t1l = (via2+4) +d2t1h = (via2+5) +d2t1ll = (via2+6) +d2t1lh = (via2+7) +d2t2l = (via2+8) +d2t2h = (via2+9) +d2sr = (via2+10) +d2acr = (via2+11) +d2pcr = (via2+12) +d2ifr = (via2+13) +d2ier = (via2+14) +d2ora = (via2+15) + +YM_REG = $9F40 ; YM2151 register address (read status) +YM_DATA = $9F41 ; YM2151 register datata (read status) + +; VERA info: https://github.com/X16Community/x16-docs/blob/master/VERA%20Programmer's%20Reference.md + +VERA_BASE = $9F20 + +VERA_ADDR_L = (VERA_BASE+$00) ; ADDRx_L +VERA_ADDR_M = (VERA_BASE+$01) ; ADDRx_M +VERA_ADDR_H = (VERA_BASE+$02) ; INCRx [7:4], DECRx [3], ADDRx_H [0] (x=ADDRSEL) +VERA_DATA0 = (VERA_BASE+$03) +VERA_DATA1 = (VERA_BASE+$04) +VERA_CTRL = (VERA_BASE+$05) ; RESET [7], DCSEL[6:1], ADDRSEL[0] + +VERA_IEN = (VERA_BASE+$06) +VERA_ISR = (VERA_BASE+$07) +VERA_IRQ_LINE_L = (VERA_BASE+$08) + +VERA_DC_VIDEO = (VERA_BASE+$09) ; DCSEL = 0 +VERA_DC_HSCALE = (VERA_BASE+$0A) ; DCSEL = 0 +VERA_DC_VSCALE = (VERA_BASE+$0B) ; DCSEL = 0 +VERA_DC_BORDER = (VERA_BASE+$0C) ; DCSEL = 0 + +VERA_DC_HSTART = (VERA_BASE+$09) ; DCSEL = 1 +VERA_DC_HSTOP = (VERA_BASE+$0A) ; DCSEL = 1 +VERA_DC_VSTART = (VERA_BASE+$0B) ; DCSEL = 1 +VERA_DC_VSTOP = (VERA_BASE+$0C) ; DCSEL = 1 + +VERA_L0_CONFIG = (VERA_BASE+$0D) +VERA_L0_MAPBASE = (VERA_BASE+$0E) +VERA_L0_TILEBASE = (VERA_BASE+$0F) +VERA_L0_HSCROLL_L = (VERA_BASE+$10) +VERA_L0_HSCROLL_H = (VERA_BASE+$11) +VERA_L0_VSCROLL_L = (VERA_BASE+$12) +VERA_L0_VSCROLL_H = (VERA_BASE+$13) + +VERA_L1_CONFIG = (VERA_BASE+$14) +VERA_L1_MAPBASE = (VERA_BASE+$15) +VERA_L1_TILEBASE = (VERA_BASE+$16) +VERA_L1_HSCROLL_L = (VERA_BASE+$17) +VERA_L1_HSCROLL_H = (VERA_BASE+$18) +VERA_L1_VSCROLL_L = (VERA_BASE+$19) +VERA_L1_VSCROLL_H = (VERA_BASE+$1A) + +VERA_AUDIO_CTRL = (VERA_BASE+$1B) +VERA_AUDIO_RATE = (VERA_BASE+$1C) +VERA_AUDIO_DATA = (VERA_BASE+$1D) + +VERA_SPI_DATA = (VERA_BASE+$1E) +VERA_SPI_CTRL = (VERA_BASE+$1F) + +VERA_PSG_BASE = $1F9C0 ; VERA address (writes also to VRAM for reads) +VERA_PALETTE_BASE = $1FA00 ; VERA address (writes also to VRAM for reads) +VERA_SPRITES_BASE = $1FC00 ; VERA address (writes also to VRAM for reads) + +; +; VERA Video RAM Layout (ROM default) +; +; $0:0000 - $1:2BFF 320x240@256c Bitmap [320x200: - $0:F9FF] +; $1:2C00 - $1:2FFF -- unused -- +; $1:3000 - $1:AFFF Sprites ($1000 per sprite) +; $1:B000 - $1:EBFF Text Mode +; $1:EC00 - $1:EFFF -- unused -- +; $1:F000 - $1:F7FF Charset +; $1:F800 - $1:F9BF -- unused -- +; $1:F9C0 - $1:FFFF Vera internal (PSG, pal, spr) + +fb_addr = $00000 ; VERA address (64K aligned) +sprite_addr = $13000 ; VERA address (sprite data) +screen_addr = $1b000 ; VERA address (text screen base) +charset_addr = $1f000 ; VERA address (charset base) + +; --------------------------------------------------------------------------- +; CX16 mostly Commodore C64 compatible kernal variables +; (unofficial ones are defined by cc65, but best to avoid) +; +; unofficial kernal zero-page variables +KTEMP2 = $80 +FNAM = $8A +TXTPTR = $EE + +; unofficial kernal variables +BASIC_BUF = $0200 +SCREEN_PTR = $0262 +STATUS = $0287 +IN_DEV = $028B +OUT_DEV = $028C +FNAM_LEN = $028F +SECADR = $0291 +DEVADR = $0292 + +; documented kernal vectors +CINV = $0314 +CBINV = $0316 +NMINV = $0318 +IOPEN = $031A +ICLOSE = $031C +ICHKIN = $031E +ICKOUT = $0320 +ICLRCH = $0322 +IBASIN = $0324 +IBSOUT = $0326 +ISTOP = $0328 +IGETIN = $032A +ICLALL = $032C +ILOAD = $0330 +ISAVE = $0332 + +; unofficial kernal variables +CURS_COLOR = $0373 +CHARCOLOR = $0376 +RVS = $0377 +CURS_FLAG = $037B +CURS_BLINK = $037C +CURS_CHAR = $037D +CURS_STATE = $037E +CURS_X = $0380 +CURS_Y = $0383 +LLEN = $0386 +NLINES = $0387 +VARTAB = $03E1 +MEMSIZ = $03E9 + +; CX16 framebuffer vectors +I_FB_INIT = $02E4 +I_FB_GET_INFO = $02E6 +I_FB_SET_PALETTE = $02E8 +I_FB_CURSOR_POSITION = $02EA +I_FB_CURSOR_NEXT_LINE = $02EC +I_FB_GET_PIXEL = $02EE +I_FB_GET_PIXELS = $02F0 +I_FB_SET_PIXEL = $02F2 +I_FB_SET_PIXELS = $02F4 +I_FB_SET_8_PIXELS = $02F6 +I_FB_SET_8_PIXELS_OPAQUE = $02F8 +I_FB_FILL_PIXELS = $02FA +I_FB_FILTER_PIXELS = $02FC +I_FB_MOVE_PIXELS = $02FE diff --git a/mos-platform/cx16/cx16_k_clock_get_date_time.s b/mos-platform/cx16/cx16_k_clock_get_date_time.s new file mode 100644 index 000000000..d70cc1844 --- /dev/null +++ b/mos-platform/cx16/cx16_k_clock_get_date_time.s @@ -0,0 +1,30 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; typedef struct { unsigned char year, mon, day, hour, min, sec, jif; } cx16_date_time_t; +; void cx16_k_clock_get_date_time(cx16_date_time_t *datetime_ptr); +; rc2/3 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-clock_get_date_time +; +.global cx16_k_clock_get_date_time +cx16_k_clock_get_date_time: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ldy __rc2 ; push datetime_ptr + phy + ldy __rc2+1 + phy + jsr __CLOCK_GET_DATE_TIME + ply ; pop datetime_ptr to r4 + sty __r4+1 + ply + sty __r4 + ldy #7-1 ; copy 7 bytes of data +1: lda __r0,y + sta (__r4),y + dey + bpl 1b + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_clock_set_date_time.s b/mos-platform/cx16/cx16_k_clock_set_date_time.s new file mode 100644 index 000000000..9f57662ae --- /dev/null +++ b/mos-platform/cx16/cx16_k_clock_set_date_time.s @@ -0,0 +1,31 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_clock_set_date_time(unsigned char year, unsigned char mon, unsigned char day, unsigned char hour, unsigned char min, unsigned char sec, unsigned char jif); +; llvm-mos: A X rc2 rc3 rc4 rc5 rc6 +; llvm-mos aliases: A X r0L r0H r1L r1H r2L +; X16 kernal: r0L r0H r1L r1H r2L r2H r3L +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-clock_set_date_time +; +.global cx16_k_clock_set_date_time +cx16_k_clock_set_date_time: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ldy __rc6 ; NOTE: copy args backwards due to overlap + sty __r3 ; r3L = jif + ldy __rc5 + sty __r2+1 ; r2H = sec + ldy __rc4 + sty __r2 ; r2L = min + ldy __rc3 + sty __r1+1 ; r1H = hour + ldy __rc2 + sty __r1 ; r1L = day + stx __r0+1 ; r0H = month + sta __r0 ; r0L = year + jsr __CLOCK_SET_DATE_TIME + X16_kernal_pop_r6_r10 ; assuming additional regs trashed (paranoia) + rts + diff --git a/mos-platform/cx16/cx16_k_console_get_char.s b/mos-platform/cx16/cx16_k_console_get_char.s new file mode 100644 index 000000000..e631a8358 --- /dev/null +++ b/mos-platform/cx16/cx16_k_console_get_char.s @@ -0,0 +1,15 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; unsigned char cx16_k_console_get_char(void); +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-console_get_char +; +.global cx16_k_console_get_char +cx16_k_console_get_char: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + jsr __CONSOLE_GET_CHAR + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_console_init.s b/mos-platform/cx16/cx16_k_console_init.s new file mode 100644 index 000000000..142f258a3 --- /dev/null +++ b/mos-platform/cx16/cx16_k_console_init.s @@ -0,0 +1,32 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_console_init(unsigned int x, unsigned int y, unsigned int width, unsigned int height); +; llvm-mos: A/X rc2/3 rc4/5 rc6/7 +; llvm-mos aliases: A/X r0 r1 r2 +; X16 kernal: r0 r1 r2 r3 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-console_init +; +.global cx16_k_console_init +cx16_k_console_init: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ldy __rc6 ; NOTE: copy args backwards due to overlap + sty __r3 ; r3 = height + ldy __rc6+1 + sty __r3+1 + ldy __rc4 + sty __r2 ; r3 = width + ldy __rc4+1 + sty __r2+1 + ldy __rc2 + sty __r1 ; r3 = y + ldy __rc2+1 + sty __r1+1 + sta __r0 ; r0 = x + stx __r0+1 + jsr __CONSOLE_INIT + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_console_put_char.s b/mos-platform/cx16/cx16_k_console_put_char.s new file mode 100644 index 000000000..e43940950 --- /dev/null +++ b/mos-platform/cx16/cx16_k_console_put_char.s @@ -0,0 +1,19 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_console_put_char(unsigned char c, unsigned char wrapwordflag); +; llvm-mos: A X +; X16 kernal: A C +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-console_put_char +; +.global cx16_k_console_put_char +cx16_k_console_put_char: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ; A = c + cpx #1 ; C = set if wrapwordflag >= 1 + jsr __CONSOLE_PUT_CHAR + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_console_put_image.s b/mos-platform/cx16/cx16_k_console_put_image.s new file mode 100644 index 000000000..62b2bf588 --- /dev/null +++ b/mos-platform/cx16/cx16_k_console_put_image.s @@ -0,0 +1,25 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_console_put_image(void *imageaddr, unsigned int width, unsigned int height); +; llvm-mos: rc2/3 A/X rc4/5 +; llvm-mos aliases: r0 A/X r1 +; X16 kernal: r0 r1 r2 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-console_put_image +; +.global cx16_k_console_put_image +cx16_k_console_put_image: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ldy __rc4 + sty __r2 ; r2 = height + ldy __rc4+1 + sty __r2+1 + sta __r1 ; r1 = width + stx __r1+1 + ; r0 = imageaddr (already set) + jsr __CONSOLE_PUT_IMAGE + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_console_set_paging_message.s b/mos-platform/cx16/cx16_k_console_set_paging_message.s new file mode 100644 index 000000000..1d1cce59d --- /dev/null +++ b/mos-platform/cx16/cx16_k_console_set_paging_message.s @@ -0,0 +1,19 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_console_set_paging_message(void *msgaddr); +; llvm-mos: rc2/3 +; llvm-mos aliases: r0 +; X16 kernal: r0 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-console_set_paging_message +; +.global cx16_k_console_set_paging_message +cx16_k_console_set_paging_message: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ; r0 = addr (already set) + jsr __CONSOLE_SET_PAGE_MSG + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_enter_basic.s b/mos-platform/cx16/cx16_k_enter_basic.s new file mode 100644 index 000000000..b1257cee2 --- /dev/null +++ b/mos-platform/cx16/cx16_k_enter_basic.s @@ -0,0 +1,14 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_enter_basic(unsigned char coldstart) __attribute__((noreturn)); +; A +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-enter_basic +; +.global cx16_k_enter_basic +cx16_k_enter_basic: + cmp #1 ; set carry if coldstart >= 1 + jmp __ENTER_BASIC diff --git a/mos-platform/cx16/cx16_k_entropy_get.s b/mos-platform/cx16/cx16_k_entropy_get.s new file mode 100644 index 000000000..b1994ed71 --- /dev/null +++ b/mos-platform/cx16/cx16_k_entropy_get.s @@ -0,0 +1,16 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; unsigned long cx16_k_entropy_get(void); // returns 24-bit value +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-entropy_get +; +.global cx16_k_entropy_get +cx16_k_entropy_get: + jsr __ENTROPY_GET + stz __rc2+1 ; zero [31:24] + sty __rc2 ; set [23:16] + ; A/X [15:0] + rts diff --git a/mos-platform/cx16/cx16_k_fb_cursor_next_line.s b/mos-platform/cx16/cx16_k_fb_cursor_next_line.s new file mode 100644 index 000000000..ac82e9d5d --- /dev/null +++ b/mos-platform/cx16/cx16_k_fb_cursor_next_line.s @@ -0,0 +1,17 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_fb_cursor_next_line(unsigned int x); +; llvm-mos: A/X +; llvm-mos alias: A/X +; X16 kernal: r0 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-fb_cursor_next_line +; +.global cx16_k_fb_cursor_next_line +cx16_k_fb_cursor_next_line: + sta __r0 ; __r0 = x + stx __r0+1 + jmp __FB_CURSOR_NEXT_LINE diff --git a/mos-platform/cx16/cx16_k_fb_cursor_position.s b/mos-platform/cx16/cx16_k_fb_cursor_position.s new file mode 100644 index 000000000..e48b9cafb --- /dev/null +++ b/mos-platform/cx16/cx16_k_fb_cursor_position.s @@ -0,0 +1,21 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_fb_cursor_position(unsigned int x, unsigned int y); +; llvm-mos: A/X rc2/3 +; llvm-mos aliases: A/X r0 +; X16 kernal: r0 r1 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-fb_cursor_position +; +.global cx16_k_fb_cursor_position +cx16_k_fb_cursor_position: + ldy __rc2 ; NOTE: copy args backwards due to overlap + sty __r1 ; r1 = y + ldy __rc2+1 + sty __r1+1 + sta __r0 ; r0 = x + stx __r0+1 + jmp __FB_CURSOR_POSITION diff --git a/mos-platform/cx16/cx16_k_fb_fill_pixels.s b/mos-platform/cx16/cx16_k_fb_fill_pixels.s new file mode 100644 index 000000000..cc65b01f8 --- /dev/null +++ b/mos-platform/cx16/cx16_k_fb_fill_pixels.s @@ -0,0 +1,22 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_fb_fill_pixels(unsigned int count, unsigned int step, unsigned char color); +; llvm-mos: A/X rc2/3 rc4 +; llvm-mos aliases: A/X r0 r1L +; X16 kernal: r0 r1 A +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-fb_fill_pixels +; +.global cx16_k_fb_fill_pixels +cx16_k_fb_fill_pixels: + ldy __rc2 ; NOTE: copy args backwards due to overlap + sty __r1 ; r1 = step + ldy __rc2+1 + sty __r1+1 + sta __r0 ; r0 = count + stx __r0+1 + lda __rc4 ; A = color + jmp __FB_FILL_PIXELS diff --git a/mos-platform/cx16/cx16_k_fb_filter_pixels.s b/mos-platform/cx16/cx16_k_fb_filter_pixels.s new file mode 100644 index 000000000..b4209d4dc --- /dev/null +++ b/mos-platform/cx16/cx16_k_fb_filter_pixels.s @@ -0,0 +1,18 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_fb_filter_pixels(void *filterfunc, unsigned int count); +; llvm-mos: rc2/3 A/X +; llvm-mos aliases: r0 A/X +; X16 kernal: r0 r1 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-fb_filter_pixels +; +.global cx16_k_fb_filter_pixels +cx16_k_fb_filter_pixels: + ; r0 = filterfunc (already set) + sta __r1 ; r1 = count + stx __r1+1 + jmp __FB_FILTER_PIXELS diff --git a/mos-platform/cx16/cx16_k_fb_get_info.s b/mos-platform/cx16/cx16_k_fb_get_info.s new file mode 100644 index 000000000..44a2320b8 --- /dev/null +++ b/mos-platform/cx16/cx16_k_fb_get_info.s @@ -0,0 +1,30 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; typedef struct { unsigned int width, height; unsigned char depth; } cx16_fb_info_t; +; void cx16_k_fb_get_info(cx16_fb_info_t *info_ptr); +; llvm-mos: rc2/3 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-fb_get_info +; +.global cx16_k_fb_get_info +cx16_k_fb_get_info: + ldy __rc2 ; push info_ptr + phy + ldy __rc2+1 + phy + jsr __FB_GET_INFO + ply ; pop info_ptr to r4 + sta __r4+1 + ply + sta __r4 + ldy #5-1 ; offset to depth + sta (__r4),y ; store depth to info_ptr + dey ; copy remaining 4 bytes +1: lda __r0,y ; from r0 & r1 + sta (__r4),y ; to info_ptr + dey + bpl 1b + rts diff --git a/mos-platform/cx16/cx16_k_fb_get_pixel.s b/mos-platform/cx16/cx16_k_fb_get_pixel.s new file mode 100644 index 000000000..5b05486af --- /dev/null +++ b/mos-platform/cx16/cx16_k_fb_get_pixel.s @@ -0,0 +1,14 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; unsigned char cx16_k_fb_get_pixel(void); +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-fb_get_pixel +; +.global cx16_k_fb_get_pixel +cx16_k_fb_get_pixel: + jsr __FB_GET_PIXEL + ldx #0 + rts diff --git a/mos-platform/cx16/cx16_k_fb_get_pixels.s b/mos-platform/cx16/cx16_k_fb_get_pixels.s new file mode 100644 index 000000000..953679236 --- /dev/null +++ b/mos-platform/cx16/cx16_k_fb_get_pixels.s @@ -0,0 +1,18 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_fb_get_pixels(void *pixeladdr, unsigned int count); +; llvm-mos: rc2/3 A/X +; llvm-mos aliases: r0 A/X +; X16 kernal: r0 r1 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-fb_get_pixels +; +.global cx16_k_fb_get_pixels +cx16_k_fb_get_pixels: + ; r0 = pixeladdr (already set) + sta __r1 ; r1 = count + stx __r1+1 + jmp __FB_GET_PIXELS diff --git a/mos-platform/cx16/cx16_k_fb_init.s b/mos-platform/cx16/cx16_k_fb_init.s new file mode 100644 index 000000000..a03a9418f --- /dev/null +++ b/mos-platform/cx16/cx16_k_fb_init.s @@ -0,0 +1,13 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_fb_init(void); +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-fb_init +; +.global cx16_k_fb_init +cx16_k_fb_init: + jmp __FB_INIT + diff --git a/mos-platform/cx16/cx16_k_fb_move_pixels.s b/mos-platform/cx16/cx16_k_fb_move_pixels.s new file mode 100644 index 000000000..a0b9c75e8 --- /dev/null +++ b/mos-platform/cx16/cx16_k_fb_move_pixels.s @@ -0,0 +1,33 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_fb_fill_pixels(unsigned int sx, unsigned int sy, unsigned int tx, unsigned int ty, unsigned int count); +; llvm-mos: A/X rc2/3 rc4/5 rc6/7 rc8/9 +; llvm-mos aliases: A/X r0 r1 r2 r3 +; X16 kernal: r0 r1 r2 r3 r4 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-fb_move_pixels +; +.global cx16_k_fb_fill_pixels +cx16_k_fb_fill_pixels: + ldy __rc8 ; NOTE: copy args backwards due to overlap + sty __r4 ; r4 = count + ldy __rc8+1 + sty __r4+1 + ldy __rc6 + sty __r3 ; r3 = height + ldy __rc6+1 + sty __r3+1 + ldy __rc4 + sty __r2 ; r2 = width + ldy __rc4+1 + sty __r2+1 + ldy __rc2 + sty __r1 ; r1 = y + ldy __rc2+1 + sty __r1+1 + sta __r0 ; r0 = x + stx __r0+1 + jmp __FB_MOVE_PIXELS diff --git a/mos-platform/cx16/cx16_k_fb_set_8_pixels.s b/mos-platform/cx16/cx16_k_fb_set_8_pixels.s new file mode 100644 index 000000000..0a97dcc67 --- /dev/null +++ b/mos-platform/cx16/cx16_k_fb_set_8_pixels.s @@ -0,0 +1,16 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_fb_set_8_pixels(unsigned char pattern, unsigned char color); +; llvm-mos: A X +; X16 kernal: A X +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-fb_set_8_pixels +; +.global cx16_k_fb_set_8_pixels +cx16_k_fb_set_8_pixels: + ; a = pattern (already set) + ; x = color (already set) + jmp __FB_SET_8_PIXELS diff --git a/mos-platform/cx16/cx16_k_fb_set_8_pixels_opaque.s b/mos-platform/cx16/cx16_k_fb_set_8_pixels_opaque.s new file mode 100644 index 000000000..28df9e6ff --- /dev/null +++ b/mos-platform/cx16/cx16_k_fb_set_8_pixels_opaque.s @@ -0,0 +1,19 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_fb_set_8_pixels_opaque(unsigned char pattern, unsigned char mask, unsigned char color1, unsigned char color2); +; llvm-mos: A X rc2 rc3 +; llvm-mos aliases: A X r0L r0H +; X16 kernal: A r0L X Y +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-fb_set_8_pixels_opaque +; +.global cx16_k_fb_set_8_pixels_opaque +cx16_k_fb_set_8_pixels_opaque: + stx __r0 ; r0L = mask + ldx __rc2 ; X = color1 + ldy __rc3 ; Y = color2 + ; A = pattern (already set) + jmp __FB_SET_8_PIXELS_OPAQUE diff --git a/mos-platform/cx16/cx16_k_fb_set_palette.s b/mos-platform/cx16/cx16_k_fb_set_palette.s new file mode 100644 index 000000000..ab145f37c --- /dev/null +++ b/mos-platform/cx16/cx16_k_fb_set_palette.s @@ -0,0 +1,18 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void fb_set_palette(void *paladdr, unsigned char index, unsigned char count); +; llvm-mos: rc2/3 A X +; llvm-mos aliases: r0 A X +; X16 kernal: r0 A X +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-fb_set_palette +; +.global cx16_k_fb_set_palette +cx16_k_fb_set_palette: + ; r0 = paladdr (already set) + ; A = index (already set) + ; X = count (already set) + jmp __FB_SET_PALETTE diff --git a/mos-platform/cx16/cx16_k_graph_clear.s b/mos-platform/cx16/cx16_k_graph_clear.s new file mode 100644 index 000000000..a2cbcc49b --- /dev/null +++ b/mos-platform/cx16/cx16_k_graph_clear.s @@ -0,0 +1,16 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_graph_clear(void); +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-graph_clear +; +.global cx16_k_graph_clear +cx16_k_graph_clear: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + jsr __GRAPH_CLEAR + X16_kernal_pop_r6_r10 + rts + diff --git a/mos-platform/cx16/cx16_k_graph_draw_image.s b/mos-platform/cx16/cx16_k_graph_draw_image.s new file mode 100644 index 000000000..e537c8582 --- /dev/null +++ b/mos-platform/cx16/cx16_k_graph_draw_image.s @@ -0,0 +1,36 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_graph_draw_image(unsigned int x, unsigned int y, void *imageaddr, unsigned int width, unsigned int height); +; llvm-mos: A/X rc2/3 rc4/5 rc6/7 rc8/9 +; llvm-mos aliases: A/X r0 r1 r2 r3 +; X16 kernal: r0 r1 r2 r3 r4 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-graph_draw_image +; +.global cx16_k_graph_draw_image +cx16_k_graph_draw_image: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ldy __rc8 ; NOTE: copy args backwards due to overlap + sty __r4 ; r4 = height + ldy __rc8+1 + sty __r4+1 + ldy __rc6 + sty __r3 ; r3 = width + ldy __rc6+1 + sty __r3+1 + ldy __rc4 + sty __r2 ; r2 = ptr + ldy __rc4+1 + sty __r2+1 + ldy __rc2 + sty __r1 ; r3 = y + ldy __rc2+1 + sty __r1+1 + sta __r0 ; r0 = x + stx __r0+1 + jsr __GRAPH_DRAW_IMAGE + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_graph_draw_line.s b/mos-platform/cx16/cx16_k_graph_draw_line.s new file mode 100644 index 000000000..9769336b3 --- /dev/null +++ b/mos-platform/cx16/cx16_k_graph_draw_line.s @@ -0,0 +1,32 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_graph_draw_line(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2); +; llvm-mos A/X rc2/3 rc4/5 rc6/7 +; llvm-mos aliases: A/X r0 r1 r2 +; X16 kernal: r0 r1 r2 r3 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-graph_draw_line +; +.global cx16_k_graph_draw_line +cx16_k_graph_draw_line: + X16_kernal_push_r6_r10 ; documented as trashing additional regs + ldy __rc6 ; NOTE: copy args backwards due to overlap + sty __r3 ; __r3 = y2 + ldy __rc6+1 + sty __r3+1 + ldy __rc4 + sty __r2 ; __r2 = x2 + ldy __rc4+1 + sty __r2+1 + ldy __rc2 + sty __r1 ; __r1 = y1 + ldy __rc2+1 + sty __r1+1 + sta __r0 ; __r0 = x1 + stx __r0+1 + jsr __GRAPH_DRAW_LINE + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_graph_draw_oval.s b/mos-platform/cx16/cx16_k_graph_draw_oval.s new file mode 100644 index 000000000..9af701c4b --- /dev/null +++ b/mos-platform/cx16/cx16_k_graph_draw_oval.s @@ -0,0 +1,34 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_graph_draw_oval(unsigned int x, unsigned int y, unsigned int width, unsigned int height, unsigned char fillflag); +; llvm-mos A/X rc2/3 rc4/5 rc6/7 r8 +; llvm-mos aliases: A/X r0 r1 r2 r3L +; X16 kernal: r0 r1 r2 r3 C +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-graph_draw_oval +; +.global cx16_k_graph_draw_oval +cx16_k_graph_draw_oval: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ldy __rc8 ; load fillflag + cpy #1 ; C = set if fillflag >= 1 + ldy __rc6 ; NOTE: copy args backwards due to overlap + sty __r3 ; r3 = height + ldy __rc6+1 + sty __r3+1 + ldy __rc4 + sty __r2 ; r2 = width + ldy __rc4+1 + sty __r2+1 + ldy __rc2 + sty __r1 ; r1 = y + ldy __rc2+1 + sty __r1+1 + sta __r0 ; r0 = x + stx __r0+1 + jsr __GRAPH_DRAW_OVAL + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_graph_draw_rect.s b/mos-platform/cx16/cx16_k_graph_draw_rect.s new file mode 100644 index 000000000..e1c3c233d --- /dev/null +++ b/mos-platform/cx16/cx16_k_graph_draw_rect.s @@ -0,0 +1,38 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_graph_draw_rect(unsigned int x, unsigned int y, unsigned int width, unsigned int height, unsigned int corner_radius, unsigned char fillflag); +; llvm-mos A/X rc2/3 rc4/5 rc6/7 r8/9 rc10 +; llvm-mos aliases: A/X r0 r1 r2 r3 r4L +; X16 kernal: r0 r1 r2 r3 r4 C +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-graph_draw_rect +; +.global cx16_k_graph_draw_rect +cx16_k_graph_draw_rect: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ldy __rc10 ; load fillflag + cpy #1 ; C = set if fillflag >= 1 + ldy __rc8 ; NOTE: copy args backwards due to overlap + sty __r4 ; r4 = corner_radius + ldy __rc8+1 + sty __r4+1 + ldy __rc6 + sty __r3 ; r3 = height + ldy __rc6+1 + sty __r3+1 + ldy __rc4 + sty __r2 ; r2 = width + ldy __rc4+1 + sty __r2+1 + ldy __rc2 + sty __r1 ; r3 = y + ldy __rc2+1 + sty __r1+1 + sta __r0 ; r0 = x + stx __r0+1 + jsr __GRAPH_DRAW_RECT + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_graph_get_char_size.s b/mos-platform/cx16/cx16_k_graph_get_char_size.s new file mode 100644 index 000000000..8ee7a7700 --- /dev/null +++ b/mos-platform/cx16/cx16_k_graph_get_char_size.s @@ -0,0 +1,31 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; long cx16_k_graph_get_char_size(unsigned char c, unsigned char style); // if printable returns info (0x00bbwwhh), else negative style byte (0xFF0000ss) +; llvm-mos: A X +; X16-kernal: A X +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-graph_get_char_size +; +.global cx16_k_graph_get_char_size +cx16_k_graph_get_char_baseline: + X16_kernal_push_r6_r10 ; appears to trash additional registers + ; A = c (already set) + ; X = format (already set) + jsr __GRAPH_GET_CHAR_SIZE + stz __rc3 ; upper byte 0 + bcc 1f ; branch if is printable char + dec __rc3 ; upper byte $FF + stz __rc2 + tya ; set 0xFF0000ss style from Y + ldx #0 + rts +1: sta __rc2 ; set 0x00bbxxxx baseline offset from A + phx ; save width from X + tya + tax ; set 0x00xxhhxx height from Y + pla ; set 0x00xxxxww width + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_graph_init.s b/mos-platform/cx16/cx16_k_graph_init.s new file mode 100644 index 000000000..81bef633f --- /dev/null +++ b/mos-platform/cx16/cx16_k_graph_init.s @@ -0,0 +1,32 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; typedef struct { void *fb_init; +; void *fb_get_info; +; void *fb_set_palette; +; void *fb_cursor_position; +; void *fb_cursor_next_line; +; void *fb_get_pixel; +; void *fb_get_pixels; +; void *fb_set_pixel; +; void *fb_set_pixels; +; void *fb_set_8_pixels; +; void *fb_set_8_pixels_opaque; +; void *fb_fill_pixels; +; void *fb_filter_pixels; +; void *fb_move_pixels; +; } graph_fb_functions_t; +; void cx16_k_graph_init(graph_fb_functions_t *fb_funcs_ptr); +; llvm-mos: rc2/3 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-graph_init +; +.global cx16_k_graph_init +cx16_k_graph_init: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ; r0 = fb_vector_table (already set) + jsr __GRAPH_INIT + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_graph_move_rect.s b/mos-platform/cx16/cx16_k_graph_move_rect.s new file mode 100644 index 000000000..05b33981a --- /dev/null +++ b/mos-platform/cx16/cx16_k_graph_move_rect.s @@ -0,0 +1,40 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_graph_move_rect(unsigned int sx, unsigned int sy, unsigned int tx, unsigned int ty, unsigned int width, unsigned int height); +; llvm-mos A/X rc2/3 rc4/5 rc6/7 r8/9 rc10/11 +; llvm-mos aliases: A/X r0 r1 r2 r3 r4 +; X16 kernal: r0 r1 r2 r3 r4 r5 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-graph_move_rect +; +.global cx16_k_graph_move_rect +cx16_k_graph_move_rect: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ldy __rc10 ; NOTE: copy args backwards due to overlap + sty __r5 ; r5 = height + ldy __rc10+1 + sty __r5+1 + ldy __rc8 + sty __r4 ; r4 = width + ldy __rc8+1 + sty __r4+1 + ldy __rc6 + sty __r3 ; r3 = ty + ldy __rc6+1 + sty __r3+1 + ldy __rc4 + sty __r2 ; r2 = tx + ldy __rc4+1 + sty __r2+1 + ldy __rc2 + sty __r1 ; r1 = y + ldy __rc2+1 + sty __r1+1 + sta __r0 ; r0 = x + stx __r0+1 + jsr __GRAPH_MOVE_RECT + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_graph_put_char.s b/mos-platform/cx16/cx16_k_graph_put_char.s new file mode 100644 index 000000000..8dbe5e8dc --- /dev/null +++ b/mos-platform/cx16/cx16_k_graph_put_char.s @@ -0,0 +1,40 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; typedef struct { int x, y } graph_pos_t; +; void cx16_k_graph_put_char(graph_pos_t *pos_ptr, unsigned char c); +; llvm-mos: rc2/3 A +; llvm-mos aliases: r0 A +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-graph_put_char +; +.global cx16_k_graph_put_char +cx16_k_graph_put_char: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ldy __rc2 ; push rc2/3 + sty __r4 + phy + ldy __rc2+1 + sty __r4+1 + phy + tax ; save c + ldy #4-1 ; copy 4 bytes +1: lda (__r4),y ; from pos_ptr x, y + sta __r0,y ; to r0 & r1 + dey + bpl 1b + txa ; A = c + jsr __GRAPH_PUT_CHAR + ply + sty __r4+1 + ply + sty __r4 + ldy #4-1 ; copy 4 bytes +2: lda __r0,y ; from r0 & r1 + sta (__r4),y ; to pos_ptr x, y + dey + bpl 2b + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_graph_set_colors.s b/mos-platform/cx16/cx16_k_graph_set_colors.s new file mode 100644 index 000000000..712fe1eeb --- /dev/null +++ b/mos-platform/cx16/cx16_k_graph_set_colors.s @@ -0,0 +1,20 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_graph_set_colors(unsigned char stroke, unsigned char fill, unsigned char background); +; llvm-mos: A X rc2 +; X16-kernal: A X Y +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-graph_set_colors +; +.global cx16_k_graph_set_colors +cx16_k_graph_set_colors: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ; A = stroke (already set) + ; X = fill (already set) + ldy __rc2 ; Y = background + jsr __GRAPH_SET_COLORS + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_graph_set_font.s b/mos-platform/cx16/cx16_k_graph_set_font.s new file mode 100644 index 000000000..af94b5a10 --- /dev/null +++ b/mos-platform/cx16/cx16_k_graph_set_font.s @@ -0,0 +1,17 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_graph_set_font(void *fontaddr); +; llvm-mos: rc2/3 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-graph_set_font +; +.global cx16_k_graph_set_font +cx16_k_graph_set_font: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ; r0 = fontaddr (already present) + jsr __GRAPH_SET_FONT + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_graph_set_window.s b/mos-platform/cx16/cx16_k_graph_set_window.s new file mode 100644 index 000000000..25032eaad --- /dev/null +++ b/mos-platform/cx16/cx16_k_graph_set_window.s @@ -0,0 +1,32 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_graph_set_window(unsigned int x, unsigned int y, unsigned int width, unsigned int height); +; llvm-mos A/X rc2/3 rc4/5 rc6/7 +; llvm-mos aliases: A/X r0 r1 r2 +; X16 kernal: r0 r1 r2 r3 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-graph_set_window +; +.global cx16_k_graph_set_window +cx16_k_graph_set_window: + X16_kernal_push_r6_r10 ; assuming additional regs trashed (paranoia) + ldy __rc6 ; NOTE: copy args backwards due to overlap + sty __r3 ; r3 = height + ldy __rc6+1 + sty __r3+1 + ldy __rc4 + sty __r2 ; r2 = width + ldy __rc4+1 + sty __r2+1 + ldy __rc2 + sty __r1 ; r1 = y + ldy __rc2+1 + sty __r1+1 + sta __r0 ; r0 = x + stx __r0+1 + jsr __GRAPH_SET_WINDOW + X16_kernal_pop_r6_r10 + rts diff --git a/mos-platform/cx16/cx16_k_i2c_read_byte.s b/mos-platform/cx16/cx16_k_i2c_read_byte.s new file mode 100644 index 000000000..7ba3c9e85 --- /dev/null +++ b/mos-platform/cx16/cx16_k_i2c_read_byte.s @@ -0,0 +1,23 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; int cx16_k_i2c_read_byte(unsigned char device, unsigned char offset); // returns negative on error +; llvm-mos: A X +; X16-kernal: X Y +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-i2c_read_byte +; +.global cx16_k_i2c_read_byte +cx16_k_i2c_read_byte: + sta __rc2 + txa + ldx __rc2 ; X = device + tay ; Y = offset + jsr __I2C_READ_BYTE + ldx #$0 + bcc 1f ; branch if no error + dex ; return -1 on error + txa +1: rts diff --git a/mos-platform/cx16/cx16_k_i2c_write_byte.s b/mos-platform/cx16/cx16_k_i2c_write_byte.s new file mode 100644 index 000000000..00e001fa9 --- /dev/null +++ b/mos-platform/cx16/cx16_k_i2c_write_byte.s @@ -0,0 +1,24 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; int cx16_k_i2c_write_byte(unsigned char device, unsigned char offset, unsigned char byte); // return negative on error +; llvm-mos: A X rc2 +; X16 kernal: X Y A +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-i2c_write_byte +; +.global cx16_k_i2c_write_byte +cx16_k_i2c_write_byte: + sta __rc3 ; save device + stx __rc4 ; save offset + lda __rc2 ; A = byte + ldy __rc4 ; Y = offset + ldx __rc3 ; X = device + jsr __I2C_WRITE_BYTE + ldx #0 + bcc 1f ; branch if no error + dex ; return -1 on error +1: txa ; 0 or -1 + rts diff --git a/mos-platform/cx16/cx16_k_joystick_get.s b/mos-platform/cx16/cx16_k_joystick_get.s new file mode 100644 index 000000000..bef64ef6c --- /dev/null +++ b/mos-platform/cx16/cx16_k_joystick_get.s @@ -0,0 +1,18 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; long cx16_k_joystick_get(unsigned char sticknum); // returns $YYYYXXAA (see docs, result negative if joystick not present) +; llvm-mos: A +; X16 kernal: A +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-joystick_get +; +.global cx16_k_joystick_get +cx16_k_joystick_get: + ; A = sticknum (already set) + jsr __JOYSTICK_GET + sty __rc2 + sty __rc3 + rts diff --git a/mos-platform/cx16/cx16_k_joystick_scan.s b/mos-platform/cx16/cx16_k_joystick_scan.s new file mode 100644 index 000000000..a339d0c90 --- /dev/null +++ b/mos-platform/cx16/cx16_k_joystick_scan.s @@ -0,0 +1,12 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_joystick_scan(void); +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-joystick_scan +; +.global cx16_k_joystick_scan +cx16_k_joystick_scan: + jmp __JOYSTICK_SCAN diff --git a/mos-platform/cx16/cx16_k_kbdbuf_get_modifiers.s b/mos-platform/cx16/cx16_k_kbdbuf_get_modifiers.s new file mode 100644 index 000000000..2cb295f9d --- /dev/null +++ b/mos-platform/cx16/cx16_k_kbdbuf_get_modifiers.s @@ -0,0 +1,14 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; unsigned char cx16_k_kbdbuf_get_modifiers(void); +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-kbdbuf_get_modifiers +; +.global cx16_k_kbdbuf_get_modifiers +cx16_k_kbdbuf_get_modifiers: + jsr __KBDBUF_GET_MODIFIERS + ldx #0 + rts diff --git a/mos-platform/cx16/cx16_k_kbdbuf_peek.s b/mos-platform/cx16/cx16_k_kbdbuf_peek.s new file mode 100644 index 000000000..36bfc6046 --- /dev/null +++ b/mos-platform/cx16/cx16_k_kbdbuf_peek.s @@ -0,0 +1,27 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; int cx16_k_kbdbuf_peek(unsigned char *index_ptr); // returns negative if empty, if non-NULL contents of index set to queue length +; llvm-mos: rc2/3 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-kbdbuf_peek +; +.global cx16_k_kbdbuf_peek +cx16_k_kbdbuf_peek: + jsr __KBDBUF_PEEK + tay ; save (possible) char + lda __rc2 + ora __rc2+1 + beq 1f ; branch if index_ptr NULL + txa + sta (__rc2) ; set *index_ptr to queue len +1: txa ; test queue len + beq 2f ; branch if queue empty + ldx #0 + tya ; restore char + rts ; return char +2: ldx #$ff ; return -1 for empty + txa + rts diff --git a/mos-platform/cx16/cx16_k_kbdbuf_put.s b/mos-platform/cx16/cx16_k_kbdbuf_put.s new file mode 100644 index 000000000..ec5b54c11 --- /dev/null +++ b/mos-platform/cx16/cx16_k_kbdbuf_put.s @@ -0,0 +1,15 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_kbdbuf_put(unsigned char c); +; llvm-mos: A +; X16 kernal: A +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-kbdbuf_put +; +.global cx16_k_kbdbuf_put +cx16_k_kbdbuf_put: + ; A = c (already set) + jmp __KBDBUF_PUT diff --git a/mos-platform/cx16/cx16_k_keymap_get_id.s b/mos-platform/cx16/cx16_k_keymap_get_id.s new file mode 100644 index 000000000..c24c69b02 --- /dev/null +++ b/mos-platform/cx16/cx16_k_keymap_get_id.s @@ -0,0 +1,17 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; const char* cx16_k_keymap_get_id(void); +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-keymap +; +.global cx16_k_keymap_get_id +cx16_k_keymap_get_id: + sec ; set C for get keymap identifier + jsr __KEYMAP + txa + sty __rc2 + ldx __rc2 + rts diff --git a/mos-platform/cx16/cx16_k_keymap_set.s b/mos-platform/cx16/cx16_k_keymap_set.s new file mode 100644 index 000000000..f3ad4f68b --- /dev/null +++ b/mos-platform/cx16/cx16_k_keymap_set.s @@ -0,0 +1,20 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; unsigned char cx16_k_keymap_set(const char* identifier); // returns 0 on success +; llvm-mos: rc2/3 +; X16 kernal: X/Y C=0 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-keymap +; +.global cx16_k_keymap_set +cx16_k_keymap_set: + ldx __rc2 ; X/Y = identifier + ldy __rc3 + clc ; C = clear for set keymap + jsr __KEYMAP + lda #0 ; return 0 on success + adc #0 ; return 1 on error (carry set) + rts diff --git a/mos-platform/cx16/cx16_k_macptr.s b/mos-platform/cx16/cx16_k_macptr.s new file mode 100644 index 000000000..e55d43b5f --- /dev/null +++ b/mos-platform/cx16/cx16_k_macptr.s @@ -0,0 +1,31 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; long cx16_k_macptr(unsigned char count, unsigned char noadvance, void *destaddr); // return negative if not supported +; llvm-mos: A X rc2/3 +; X16 kernal: A C X/Y +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-macptr +; +.global cx16_k_macptr +cx16_k_macptr: + ; A = count + cpx #1 ; C = set if noadvance >= 1 + ldx __rc2 ; X/Y = destaddr + ldy __rc2+1 + jsr __MACPTR + bcc noerror + lda #$FF ; -1 on error + tax + sta __rc2 + sta __rc3 + rts +noerror: + txa + sty __rc2 + ldx __rc2 + stz __rc2 ; zero extend return + stz __rc3 + rts diff --git a/mos-platform/cx16/cx16_k_memory_copy.s b/mos-platform/cx16/cx16_k_memory_copy.s new file mode 100644 index 000000000..153566cde --- /dev/null +++ b/mos-platform/cx16/cx16_k_memory_copy.s @@ -0,0 +1,19 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_memory_copy(void *source, void *target, unsigned int num_bytes); +; llvm-mos: rc2/3 rc4/5 A/X +; llvm-mos aliases: r0 r1 A/X +; X16 kernal: r0 r1 r2 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-memory_copy +; +.global cx16_k_memory_copy +cx16_k_memory_copy: + sta __r2 ; r2 = num_bytes + stx __r2+1 + ; r1 = target (already set) + ; r0 = source (already set) + jmp __MEMORY_COPY diff --git a/mos-platform/cx16/cx16_k_memory_crc.s b/mos-platform/cx16/cx16_k_memory_crc.s new file mode 100644 index 000000000..131b77b6a --- /dev/null +++ b/mos-platform/cx16/cx16_k_memory_crc.s @@ -0,0 +1,21 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; unsigned int cx16_k_memory_crc(void *dataaddr, unsigned int num_bytes); +; llvm-mos: rc2/3 A/X +; llvm-mos aliases: r0 A/X +; X16 kernal: r0 r1 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-memory_crc +; +.global cx16_k_memory_crc +cx16_k_memory_crc: + sta __r1 ; r1 = num_bytes + stx __r1+1 + ; r0 = dataaddr (already set) + jsr __MEMORY_CRC + lda __r2 ; return = __r2 + ldx __r2+1 + rts diff --git a/mos-platform/cx16/cx16_k_memory_decompress.s b/mos-platform/cx16/cx16_k_memory_decompress.s new file mode 100644 index 000000000..75fec3f77 --- /dev/null +++ b/mos-platform/cx16/cx16_k_memory_decompress.s @@ -0,0 +1,17 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_memory_decompress(void *inaddr, void *outaddr); +; llvm-mos: rc2/3 rc4/5 +; llvm-mos aliases: r0 r1 +; X16 kernal: r0 r1 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-memory_decompress +; +.global cx16_k_memory_decompress +cx16_k_memory_decompress: + ; r0 = inaddr (already set) + ; r1 = outaddr (already set) + jmp __MEMORY_DECOMPRESS diff --git a/mos-platform/cx16/cx16_k_memory_fill.s b/mos-platform/cx16/cx16_k_memory_fill.s new file mode 100644 index 000000000..4a30c3034 --- /dev/null +++ b/mos-platform/cx16/cx16_k_memory_fill.s @@ -0,0 +1,19 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_memory_fill(void *addr, unsigned int num_bytes, unsigned char value); +; llvm-mos: rc2/3 A/X rc4 +; llvm-mos aliases: r0 A/X r1L +; llvm-mos: r0 r1 A +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-memory_fill +; +.global cx16_k_memory_fill +cx16_k_memory_fill: + ; r0 = addr (already set) + sta __r1 ; r1 = num_bytes + stx __r1+1 + lda __rc4 ; A = value + jmp __MEMORY_FILL diff --git a/mos-platform/cx16/cx16_k_monitor.s b/mos-platform/cx16/cx16_k_monitor.s new file mode 100644 index 000000000..9e51dd79e --- /dev/null +++ b/mos-platform/cx16/cx16_k_monitor.s @@ -0,0 +1,12 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_monitor(void) __attribute__((noreturn)); +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-monitor +; +.global cx16_k_monitor +cx16_k_monitor: + jmp __MONITOR diff --git a/mos-platform/cx16/cx16_k_mouse_config.s b/mos-platform/cx16/cx16_k_mouse_config.s new file mode 100644 index 000000000..104ebaf30 --- /dev/null +++ b/mos-platform/cx16/cx16_k_mouse_config.s @@ -0,0 +1,18 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_mouse_config(unsigned char showmouse, unsigned char xsize8, unsigned char ysize8); +; llvm-mos: A X rc2 +; llvm-mos aliases: A X r0L +; X16 kernal: A X Y +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-mouse_config +; +.global cx16_k_mouse_config +cx16_k_mouse_config: + ; A = showmouse (already set) + ; X = xsize8 (already set) + ldy __rc2 ; Y = ysize8 + jmp __MOUSE_CONFIG diff --git a/mos-platform/cx16/cx16_k_mouse_get.s b/mos-platform/cx16/cx16_k_mouse_get.s new file mode 100644 index 000000000..24b02d37e --- /dev/null +++ b/mos-platform/cx16/cx16_k_mouse_get.s @@ -0,0 +1,24 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; typedef struct { int x, y; } mouse_pos_t; +; unsigned char cx16_k_mouse_get(mouse_pos_t *mouse_pos_ptr); // returns mouse button byte +; llvm-mos: rc2/3 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-mouse_get +; +.global cx16_k_mouse_get +cx16_k_mouse_get: + ldx #__r4 ; x = temp pos + jsr __MOUSE_GET + tax ; save buttons + ldy #4-1 ; copy 4 byte pos to xy_ptr +1: lda __r4,y + sta (__rc2),y + dey + bpl 1b + txa ; return buttons + ldx #0 + rts diff --git a/mos-platform/cx16/cx16_k_mouse_scan.s b/mos-platform/cx16/cx16_k_mouse_scan.s new file mode 100644 index 000000000..cfadfade9 --- /dev/null +++ b/mos-platform/cx16/cx16_k_mouse_scan.s @@ -0,0 +1,12 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_mouse_scan(void); +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-mouse_scan +; +.global cx16_k_mouse_scan +cx16_k_mouse_scan: + jmp __MOUSE_SCAN diff --git a/mos-platform/cx16/cx16_k_savehl.s b/mos-platform/cx16/cx16_k_savehl.s new file mode 100644 index 000000000..c7bf49d61 --- /dev/null +++ b/mos-platform/cx16/cx16_k_savehl.s @@ -0,0 +1,21 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; unsigned char cx16_k_savehl(void *startaddr, void *endaddr_plusone); // returns 0 on success +; llvm-mos: rc2/3 rc4/5 +; X16-kernel: A X/Y +; +; Not documented on https://github.com/X16Community/x16-docs +; similar to cbm_k_save, but no two byte header written +; +.global cx16_k_savehl +cbm_k_savehl: + ldx __rc4 ; X/Y = end + ldy __rc4+1 + lda #__rc2 ; A = &startaddr + jsr __SAVEHL + bcs 1f ; branch on error + lda #0 +1: rts diff --git a/mos-platform/cx16/cx16_k_screen_mode_get.s b/mos-platform/cx16/cx16_k_screen_mode_get.s new file mode 100644 index 000000000..622fe25dc --- /dev/null +++ b/mos-platform/cx16/cx16_k_screen_mode_get.s @@ -0,0 +1,25 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; typedef struct { unsigned char mode, columns, rows; } screen_mode_info_t; +; unsigned char cx16_k_screen_mode_get(screen_mode_info_t *info_ptr); // returns 0 on success +; llvm-mos: rc2/3 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-screen_mode +; +.global cx16_k_screen_mode_get +cx16_k_screen_mode_get: + sec ; C = set for get screen mode info + jsr __SCREEN_MODE + sty __r4 ; save tile_h + ldy #0 + sta (__rc2),y ; store mode + iny + txa + sta (__rc2),y ; store columns + iny + lda __r4 + sta (__rc2),y ; store rows + rts diff --git a/mos-platform/cx16/cx16_k_screen_mode_set.s b/mos-platform/cx16/cx16_k_screen_mode_set.s new file mode 100644 index 000000000..dc5022643 --- /dev/null +++ b/mos-platform/cx16/cx16_k_screen_mode_set.s @@ -0,0 +1,19 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; unsigned char cx16_k_screen_mode_set(unsigned char mode); // returns 0 on success +; llvm-mos: A +; X16 kernal: A +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-screen_mode +; +.global cx16_k_screen_mode_set +cx16_k_screen_mode_set: + ; A = mode (already set) + clc ; clear C for set screen mode + jsr __SCREEN_MODE + lda #0 ; return 0 on success + adc #0 ; return 1 on error (carry set) + rts diff --git a/mos-platform/cx16/cx16_k_screen_set_charset.s b/mos-platform/cx16/cx16_k_screen_set_charset.s new file mode 100644 index 000000000..7eaf593ff --- /dev/null +++ b/mos-platform/cx16/cx16_k_screen_set_charset.s @@ -0,0 +1,17 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void cx16_k_screen_set_charset(unsigned char charset_type, void *charsetaddr); +; llvm-mos: A rc2/rc3 +; X16-kernal: A X/Y +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-screen_set_charset +; +.global cx16_k_screen_set_charset +cx16_k_screen_set_charset: + ; A = charset_type (already set) + ldx __rc2 ; X/Y = charset_addr + ldy __rc2+1 + jmp __SCREEN_SET_CHARSET diff --git a/mos-platform/cx16/cx16_k_sprite_set_image.s b/mos-platform/cx16/cx16_k_sprite_set_image.s new file mode 100644 index 000000000..f467642bf --- /dev/null +++ b/mos-platform/cx16/cx16_k_sprite_set_image.s @@ -0,0 +1,34 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; unsigned char cx16_k_sprite_set_image(unsigned char num, unsigned char w, unsigned char h, unsigned char maskflag, void *imageaddr, void *maskaddr, unsigned char bpp); // returns 0 on success +; llvm-mos: A X rc2 rc3 rc4/5 rc6/7 rc8 +; llvm-mos aliases: A X r0L r0H r1 r2 r3L +; X16 kernal: A X Y C r0 r1 r2L +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-sprite_set_image +; +.global cx16_k_sprite_set_image +cx16_k_sprite_set_image: + ldy __rc2 ; save h in r4 temp + sty __r4 + ldy __rc3 ; load maskflag + cpy #1 ; C = set if maskflag >= 1 + ldy __rc4 + sty __r0 ; r0 = imageaddr + ldy __rc4+1 + sty __r0+1 + ldy __rc6 + sty __r1 ; r1 = maskaddr + ldy __rc6+1 + sty __r1+1 + ldy __rc8 + sty __r2 ; r2 = bpp + ; A = num (already set) + ; X = w (already set) + ldy __r4 ; Y = h + jsr __SPRITE_SET_IMAGE + lda #0 ; return 0 on success + adc #0 ; return 1 on error (carry set) + rts diff --git a/mos-platform/cx16/cx16_k_sprite_set_position.s b/mos-platform/cx16/cx16_k_sprite_set_position.s new file mode 100644 index 000000000..bd252d16a --- /dev/null +++ b/mos-platform/cx16/cx16_k_sprite_set_position.s @@ -0,0 +1,26 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; unsigned char cx16_k_sprite_set_position(unsigned char num, unsigned int xpos, unsigned int ypos); // returns 0 on success +; llvm-mos: A X/rc2 rc3/4 +; llvm-mos aliases: A r0L/X r0H/r1L +; X16 kernal: A r0 r1 +; +; https://github.com/X16Community/x16-docs/blob/master/X16%20Reference%20-%2004%20-%20KERNAL.md#function-name-sprite_set_position +; +.global cx16_k_sprite_set_position +cx16_k_sprite_set_position: + sta __r4 ; save num in r4 temp + lda __rc2 + ldy __rc3 + stx __r0 ; r0 = xpos + sta __r0+1 + sty __r1 ; r1 = ypos + ldy __rc3+1 + sty __r1+1 + lda __r4 ; A = num (restored from temp) + jsr __SPRITE_SET_POSITION + lda #0 ; return 0 on success + adc #0 ; return 1 on error (carry set) + rts diff --git a/mos-platform/cx16/get_numbanks.s b/mos-platform/cx16/get_numbanks.s new file mode 100644 index 000000000..34f053c1e --- /dev/null +++ b/mos-platform/cx16/get_numbanks.s @@ -0,0 +1,20 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; unsigned short get_numbanks(void); // return number of 8K RAM banks at 0xA000-0xBFFF (64=512K up to 256=2MB) +; +; Originally from cc65. Modified from original version. See license information in cx16.h +; https://github.com/cc65/cc65/blob/master/libsrc/cx16/get_numbanks.s +; +.global get_numbanks +get_numbanks: + sec ; set carry to get MEMTOP + jsr __MEMTOP + ldx #0 ; assume < 256 + cmp #0 ; is it 0? (means 256) + bne 1f ; branch if not + inx ; increment high for 256 +1: rts + diff --git a/mos-platform/cx16/get_ostype.s b/mos-platform/cx16/get_ostype.s new file mode 100644 index 000000000..9c67acc59 --- /dev/null +++ b/mos-platform/cx16/get_ostype.s @@ -0,0 +1,21 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; signed char get_ostype(void); // return ROM build version (negative pre-release, -1=custom) +; +; Originally from cc65. Modified from original version. See license information in cx16.h +; https://github.com/cc65/cc65/blob/master/libsrc/cx16/get_ostype.s +; +.global get_numbanks +get_numbanks: + ldy ROM_BANK ; make sure ROM bank 0 + stz ROM_BANK + ldx #0 ; clear high + lda $FF80 ; special ROM build version byte + sty ROM_BANK ; restore previous bank + bpl 1f ; branch if version negative + dex ; decrement high for sign extend +1: rts + diff --git a/mos-platform/cx16/get_tv.s b/mos-platform/cx16/get_tv.s new file mode 100644 index 000000000..252eade12 --- /dev/null +++ b/mos-platform/cx16/get_tv.s @@ -0,0 +1,17 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; unsigned char get_tv(void); // return TV_* enum constant for current video signal type +; +; Originally from cc65. Modified from original version. See license information in cx16.h +; https://github.com/cc65/cc65/blob/master/libsrc/cx16/get_tv.s +; +.global get_tv +get_tv: + stz VERA_CTRL ; set DCSEL=0 to access DC_VIDEO + lda VERA_DC_VIDEO ; load DC_VIDEO + and #$0F ; mask out non-mode bits + ldx #0 ; zero extend +1: rts diff --git a/mos-platform/cx16/imag-regs.ld b/mos-platform/cx16/imag-regs.ld index 86558bd80..2361dc7d1 100644 --- a/mos-platform/cx16/imag-regs.ld +++ b/mos-platform/cx16/imag-regs.ld @@ -19,22 +19,27 @@ * is, __r0 through __r15. */ -__r0 = 0x0002; -__r1 = 0x0004; -__r2 = 0x0006; -__r3 = 0x0008; -__r4 = 0x000a; -__r5 = 0x000c; -__r6 = 0x000e; -__r7 = 0x0010; -__r8 = 0x0012; -__r9 = 0x0014; -__r10 = 0x0016; -__r11 = 0x0018; -__r12 = 0x001a; -__r13 = 0x001c; -__r14 = 0x001e; -__r15 = 0x0020; +/* CAUTION: Some X16 kernal calls deviate from this convention! */ + +/* X16 kernal reg X16 convention LLVM reg alias LLVM convention */ +__r0 = 0x0002; /* in/out (args) __rc2, __rc3 trash */ +__r1 = 0x0004; /* in/out (args) __rc4, __rc5 trash */ +__r2 = 0x0006; /* in/out (args) __rc6, __rc7 trash */ +__r3 = 0x0008; /* in/out (args) __rc8, __rc9 trash */ +__r4 = 0x000a; /* in/out (args) - - (mos-sdk temp) */ +__r5 = 0x000c; /* in/out (args) - - (unused) */ +__r6 = 0x000e; /* preserve __rc20, __rc21 preserve */ +__r7 = 0x0010; /* preserve __rc22, __rc23 preserve */ +__r8 = 0x0012; /* preserve __rc24, __rc25 preserve */ +__r9 = 0x0014; /* preserve __rc26, __rc27 preserve */ +__r10 = 0x0016; /* preserve __rc28, __rc29 preserve */ +__r11 = 0x0018; /* trash __rc10, __rc11 trash */ +__r12 = 0x001a; /* trash __rc12, __rc13 trash */ +__r13 = 0x001c; /* trash __rc14, __rc15 trash */ +__r14 = 0x001e; /* trash __rc16, __rc17 trash */ +__r15 = 0x0020; /* trash __rc18, __rc19 trash */ +/* = 0x0022 __rc0, __rc1 preserve */ +/* = 0x0024 __rc30, __rc31 preserve */ /* LLVM-MOS caller-saved => X16 callee-saved (arguments; rs1-rs4 => r0-r3). * This allows setting arguments in KERNAL wrappers without stashing. diff --git a/mos-platform/cx16/kernal.S b/mos-platform/cx16/kernal.S index acd638893..476ac4815 100644 --- a/mos-platform/cx16/kernal.S +++ b/mos-platform/cx16/kernal.S @@ -19,6 +19,64 @@ .global __\name .endm +weakdef SAVEHL +weakdef KBDBUF_PEEK +weakdef KBDBUF_GET_MODIFIERS +weakdef KBDBUF_PUT +weakdef I2C_READ_BYTE +weakdef I2C_WRITE_BYTE +weakdef CX_MONITOR +weakdef ENTROPY_GET +weakdef KEYMAP +weakdef CONSOLE_SET_PAGE_MSG +weakdef CONSOLE_PUT_IMAGE +weakdef CONSOLE_INIT +weakdef CONSOLE_PUT_CHAR +weakdef CONSOLE_GET_CHAR +weakdef MEMORY_FILL +weakdef MEMORY_COPY +weakdef MEMORY_CRC +weakdef MEMORY_DECOMPRESS +weakdef SPRITE_SET_IMAGE +weakdef SPRITE_SET_POSITION +weakdef FB_INIT +weakdef FB_GET_INFO +weakdef FB_SET_PALETTE +weakdef FB_CURSOR_POSITION +weakdef FB_CURSOR_NEXT_LINE +weakdef FB_GET_PIXEL +weakdef FB_GET_PIXELS +weakdef FB_SET_PIXEL +weakdef FB_SET_PIXELS +weakdef FB_SET_8_PIXELS +weakdef FB_SET_8_PIXELS_OPAQUE +weakdef FB_FILL_PIXELS +weakdef FB_FILTER_PIXELS +weakdef FB_MOVE_PIXELS +weakdef GRAPH_INIT +weakdef GRAPH_CLEAR +weakdef GRAPH_SET_WINDOW +weakdef GRAPH_SET_COLORS +weakdef GRAPH_DRAW_LINE +weakdef GRAPH_DRAW_RECT +weakdef GRAPH_MOVE_RECT +weakdef GRAPH_DRAW_OVAL +weakdef GRAPH_DRAW_IMAGE +weakdef GRAPH_SET_FONT +weakdef GRAPH_GET_CHAR_SIZE +weakdef GRAPH_PUT_CHAR +weakdef MACPTR +weakdef ENTER_BASIC +weakdef CLOCK_SET_DATE_TIME +weakdef CLOCK_GET_DATE_TIME +weakdef JOYSTICK_SCAN +weakdef JOYSTICK_GET +weakdef SCREEN_MODE +weakdef SCREEN_SET_CHARSET +weakdef MOUSE_CONFIG +weakdef MOUSE_GET +weakdef MOUSE_SCAN + weakdef CHKIN weakdef CKOUT weakdef CHKOUT diff --git a/mos-platform/cx16/set_tv.s b/mos-platform/cx16/set_tv.s new file mode 100644 index 000000000..c4779c261 --- /dev/null +++ b/mos-platform/cx16/set_tv.s @@ -0,0 +1,19 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void set_tv(unsigned char type); // set video signal type using TV_* enum constant +; llvm-mos: A +; +; Originally from cc65. Modified from original version. See license information in cx16.h +; https://github.com/cc65/cc65/blob/master/libsrc/cx16/set_tv.s +; +.global set_tv +set_tv: + stz VERA_CTRL ; set DCSEL=0 to access DC_VIDEO + eor VERA_DC_VIDEO ; eor in current register bits + and #$0F ; don't alter layer or sprite bits + eor VERA_DC_VIDEO ; eor in video mode bits again + sta VERA_DC_VIDEO ; store result with low 4 bits altered + rts diff --git a/mos-platform/cx16/vera_layer_enable.s b/mos-platform/cx16/vera_layer_enable.s new file mode 100644 index 000000000..e95f7951a --- /dev/null +++ b/mos-platform/cx16/vera_layer_enable.s @@ -0,0 +1,31 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; unsigned char vera_layer_enable(unsigned char layers); // enable/disable VERA layers 0/1 (bits 0/1), returns previous +; llvm-mos: A +; +; Originally from cc65. Modified from original version. See license information in cx16.h +; https://github.com/cc65/cc65/blob/master/libsrc/cx16/layer_enable.s +; +.global vera_layer_enable +vera_layer_enable: + stz VERA_CTRL ; set DCSEL=0 to access DC_VIDEO + asl + asl ; shift new flags into position + asl + asl + ldy VERA_DC_VIDEO ; save previous value + eor VERA_DC_VIDEO + and #$30 + eor VERA_DC_VIDEO ; Replace old flags with new flags + sta VERA_DC_VIDEO + tya + and #$30 ; Get old flags + lsr + lsr + lsr + lsr + ldx #0 ; zero extend + rts diff --git a/mos-platform/cx16/vera_sprites_enable.s b/mos-platform/cx16/vera_sprites_enable.s new file mode 100644 index 000000000..3417eeb94 --- /dev/null +++ b/mos-platform/cx16/vera_sprites_enable.s @@ -0,0 +1,29 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; unsigned char vera_sprites_enable(unsigned char enable); // enable/disable VERA sprites (0=off, non-zero=on), returns previous +; llvm-mos: A +; +; Originally from cc65. Modified from original version. See license information in cx16.h +; https://github.com/cc65/cc65/blob/master/libsrc/cx16/layer_enable.s +; +.global vera_sprites_enable +vera_sprites_enable: + stz VERA_CTRL ; set DCSEL=0 to access DC_VIDEO + tax ; test A + beq 1f ; branch if zero + lda #$40 +1: ldy VERA_DC_VIDEO ; save previous value + eor VERA_DC_VIDEO + and #$40 + eor VERA_DC_VIDEO ; Replace old flags with new flags + sta VERA_DC_VIDEO + tya + and #$40 ; Get old flags + asl ; move bit 6 to bit 0 via carry + asl + rol + ldx #0 ; zero extend + rts diff --git a/mos-platform/cx16/videomode.s b/mos-platform/cx16/videomode.s new file mode 100644 index 000000000..a1942450c --- /dev/null +++ b/mos-platform/cx16/videomode.s @@ -0,0 +1,27 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; signed char videomode(signed char mode); // set video mode using VIDEOMODE_* enum constant, returns previous or -1 if error +; llvm-mos: A +; +; Originally from cc65. Modified from original version. See license information in cx16.h +; https://github.com/cc65/cc65/blob/master/libsrc/cx16/videomode.s +; +.global videomode +videomode: + pha ; save new mode + sec ; get old mode + jsr __SCREEN_MODE + plx ; get new mode in X + pha ; save old mode + txa ; get new mode in A + clc ; set new mode + jsr __SCREEN_MODE + pla ; get old mode + ldx #0 ; zero extend + bcc 1f ; branch if mode valid + dex ; -1 for error + txa +1: rts diff --git a/mos-platform/cx16/vpeek.s b/mos-platform/cx16/vpeek.s new file mode 100644 index 000000000..1b38871f7 --- /dev/null +++ b/mos-platform/cx16/vpeek.s @@ -0,0 +1,21 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; unsigned char vpeek(unsigned long addr); // read byte from VERA VRAM address +; llvm-mos: A/X/rc2/3 +; +; Originally from cc65. Modified from original version. See license information in cx16.h +; https://github.com/cc65/cc65/blob/master/libsrc/cx16/vpeek.s +; +.global vpeek +vpeek: + stz VERA_CTRL ; set DCSEL=0 to access ADDRSEL=0 + ldy __rc2 + sty VERA_ADDR_H + stx VERA_ADDR_M + sta VERA_ADDR_L + ldx #0 + lda VERA_DATA0 + rts diff --git a/mos-platform/cx16/vpoke.s b/mos-platform/cx16/vpoke.s new file mode 100644 index 000000000..f44eeaaf8 --- /dev/null +++ b/mos-platform/cx16/vpoke.s @@ -0,0 +1,22 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void vpoke(unsigned char data, unsigned long addr); // write byte value to VERA VRAM address +; llvm-mos: A X/rc2/3/4 +; +; Originally from cc65. Modified from original version. See license information in cx16.h +; https://github.com/cc65/cc65/blob/master/libsrc/cx16/vpoke.s +; +.global vpoke +vpoke: + stz VERA_CTRL ; set DCSEL=0 to access ADDRSEL=0 + ldy __rc4 + sty VERA_ADDR_H + ldy __rc3 + sty VERA_ADDR_M + ldy __rc2 + sty VERA_ADDR_L + sta VERA_DATA0 + rts diff --git a/mos-platform/cx16/waitvsync.s b/mos-platform/cx16/waitvsync.s new file mode 100644 index 000000000..a1f833eca --- /dev/null +++ b/mos-platform/cx16/waitvsync.s @@ -0,0 +1,18 @@ +.include "imag.inc" +.include "cx16.inc" +.text + +; +; void waitvsync(void); // wait for the vertical blank interrupt +; +; Originally from cc65. Modified from original version. See license information in cx16.h +; https://github.com/cc65/cc65/blob/master/libsrc/cx16/waitvsync.s +; +.global waitvsync +waitvsync: + jsr __RDTIM + sta __rc2 +1: jsr __RDTIM + cmp __rc2 + beq 1b + rts diff --git a/mos-platform/nes/nes.h b/mos-platform/nes/nes.h index 4e5866838..a84cd6449 100644 --- a/mos-platform/nes/nes.h +++ b/mos-platform/nes/nes.h @@ -3,7 +3,7 @@ // See https://github.com/llvm-mos/llvm-mos-sdk/blob/main/LICENSE for license // information. -// Originally from cc65. Modififed from original version. +// Originally from cc65. Modified from original version. /*****************************************************************************/ /* */ diff --git a/utils/sim/mos-sim.c b/utils/sim/mos-sim.c index 6f19c6f88..9a3824f47 100644 --- a/utils/sim/mos-sim.c +++ b/utils/sim/mos-sim.c @@ -66,12 +66,12 @@ int8_t read6502(uint16_t address) { void finish(void) { if (shouldPrintCycles) - fprintf(stderr, "%ld cycles\n", clockticks6502); + fprintf(stderr, "%llu cycles\n", clockticks6502); if (shouldProfile) for (int addr = 0; addr < 65536; ++addr) if (clockTicksAtAddress[addr]) - fprintf(stderr, "%04x %ld\n", addr, clockTicksAtAddress[addr]); + fprintf(stderr, "%04x %llu\n", addr, clockTicksAtAddress[addr]); } void write6502(uint16_t address, uint8_t value) {