From ba90f9ea65e9cb933f7f536588ee85aa751cb0ab Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Sat, 6 Jun 2020 01:19:28 +0200 Subject: [PATCH] Added NES conio initial support. (scrolling not working atm.) --- src/main/kc/include/c64.h | 6 +- src/main/kc/include/nes.h | 14 +- src/main/kc/lib/conio-nes.c | 173 + src/main/kc/lib/conio.c | 2 + src/main/kc/lib/nes.c | 14 + .../dk/camelot64/kickc/test/TestPrograms.java | 4 + src/test/kc/.vscode/tasks.json | 189 +- .../nes-conio/characters.901225-01.bin | Bin 0 -> 4096 bytes src/test/kc/examples/nes-conio/nes-conio.c | 96 + src/test/ref/examples/nes-conio/nes-conio.asm | 674 ++ src/test/ref/examples/nes-conio/nes-conio.cfg | 374 + src/test/ref/examples/nes-conio/nes-conio.log | 6505 +++++++++++++++++ src/test/ref/examples/nes-conio/nes-conio.sym | 298 + src/test/ref/examples/nes/nes-demo.log | 2 + src/test/vs.code/kickc-test.code-workspace | 3 +- 15 files changed, 8227 insertions(+), 127 deletions(-) create mode 100644 src/main/kc/lib/conio-nes.c create mode 100644 src/test/kc/examples/nes-conio/characters.901225-01.bin create mode 100644 src/test/kc/examples/nes-conio/nes-conio.c create mode 100644 src/test/ref/examples/nes-conio/nes-conio.asm create mode 100644 src/test/ref/examples/nes-conio/nes-conio.cfg create mode 100644 src/test/ref/examples/nes-conio/nes-conio.log create mode 100644 src/test/ref/examples/nes-conio/nes-conio.sym diff --git a/src/main/kc/include/c64.h b/src/main/kc/include/c64.h index 548905f09..ca14d938d 100644 --- a/src/main/kc/include/c64.h +++ b/src/main/kc/include/c64.h @@ -1,11 +1,11 @@ // Commodore 64 Registers and Constants +#ifndef __C64__ +#error "Target platform must be C64" +#endif #include #include #include -#ifndef __C64__ -#error "Target platform must be C64" -#endif // Processor port data direction register char* const PROCPORT_DDR = 0x00; diff --git a/src/main/kc/include/nes.h b/src/main/kc/include/nes.h index e72be564f..a6cdea93e 100644 --- a/src/main/kc/include/nes.h +++ b/src/main/kc/include/nes.h @@ -1,6 +1,9 @@ // Nintendo Entertainment System (NES // https://en.wikipedia.org/wiki/Nintendo_Entertainment_System_(Model_NES-101) // https://github.com/gregkrsak/first_nes +#ifndef __NES__ +#error "Target platform must be NES" +#endif #include #include @@ -83,6 +86,10 @@ void ppuDataPrepare(void* const ppuData); // The byte is put into the current PPU address pointed to by the (autoincrementing) PPU->PPUADDR void ppuDataPut(char val); +// Read one byte from PPU memory +// The byte is read from the current PPU address pointed to by the (autoincrementing) PPU->PPUADDR +char ppuDataRead(); + // Fill a number of bytes in the PPU memory // - ppuData : Pointer in the PPU memory // - size : The number of bytes to transfer @@ -99,8 +106,11 @@ void ppuDataTransfer(void* const ppuData, void* const cpuData, unsigned int size // - tile : The tile to transfer void ppuDataPutTile(void* const ppuData, char* tile); - // Set one byte in PPU memory // - ppuData : Pointer in the PPU memory // - val : The value to set -void ppuDataSet(void* const ppuData, char val); \ No newline at end of file +void ppuDataSet(void* const ppuData, char val); + +// Get one byte from PPU memory +// - ppuData : Pointer in the PPU memory +char ppuDataGet(void* const ppuData); diff --git a/src/main/kc/lib/conio-nes.c b/src/main/kc/lib/conio-nes.c new file mode 100644 index 000000000..423d54872 --- /dev/null +++ b/src/main/kc/lib/conio-nes.c @@ -0,0 +1,173 @@ +// Conio.h implementation for NES +// No support for colors so far +// Scrolling is done by moving all chars in the PPU memory - very slowly! +#include +#include + +// The screen width +#define CONIO_WIDTH 32 +// The screen height +#define CONIO_HEIGHT 30 +// The number of bytes on the screen +#define CONIO_BYTES CONIO_HEIGHT*CONIO_WIDTH +// The text screen address +char * const CONIO_SCREEN_TEXT = PPU_NAME_TABLE_0; + +// Return true if there's any key pressed, return false if not +unsigned char kbhit (void) { + return ~readJoy1(); +} + +// Set the color for the background. The old color setting is returned. +unsigned char bgcolor(unsigned char color) { + return 0; +} + +// Set the color for the border. The old color setting is returned. +unsigned char bordercolor(unsigned char color) { + return 0; +} + +// The current cursor x-position +__ma char conio_cursor_x = 0; +// The current cursor y-position +__ma char conio_cursor_y = 0; +// The current text cursor line start +__ma char *conio_line_text = CONIO_SCREEN_TEXT; +// Is a cursor shown when waiting for input (0: no, other: yes) +__ma char conio_display_cursor = 0; +// Is scrolling enabled when outputting beyond the end of the screen (1: yes, 0: no). +// If disabled the cursor just moves back to (0,0) instead +__ma char conio_scroll_enable = 1; + +// clears the screen and moves the cursor to the upper left-hand corner of the screen. +void clrscr(void) { + ppuDataFill(CONIO_SCREEN_TEXT, ' ', 0x3c0); + conio_cursor_x = 0; + conio_cursor_y = 0; + conio_line_text = CONIO_SCREEN_TEXT; +} + +// Set the cursor to the specified position +void gotoxy(unsigned char x, unsigned char y) { + if(y>CONIO_HEIGHT) y = 0; + if(x>=CONIO_WIDTH) x = 0; + conio_cursor_x = x; + conio_cursor_y = y; + unsigned int line_offset = (unsigned int)y*CONIO_WIDTH; + conio_line_text = CONIO_SCREEN_TEXT + line_offset; +} + +// Return the current screen size. +void screensize(unsigned char* x, unsigned char* y) { + *x = CONIO_WIDTH; + *y = CONIO_HEIGHT; +} + +// Return the current screen size X width. +inline char screensizex() { + return CONIO_WIDTH; +} + +// Return the current screen size Y height. +inline char screensizey() { + return CONIO_HEIGHT; +} + +// Return the X position of the cursor +inline unsigned char wherex(void) { + return conio_cursor_x; +} + +// Return the Y position of the cursor +inline unsigned char wherey(void) { + return conio_cursor_y; +} + +// Output one character at the current cursor position +// Moves the cursor forward. Scrolls the entire screen if needed +void cputc(char c) { + if(c=='\n') { + cputln(); + } else { + ppuDataSet(conio_line_text+conio_cursor_x, c); + if(++conio_cursor_x==CONIO_WIDTH) + cputln(); + } +} + +// Print a newline +void cputln() { + conio_line_text += CONIO_WIDTH; + conio_cursor_x = 0; + conio_cursor_y++; + cscroll(); +} + +// Scroll the entire screen if the cursor is beyond the last line +void cscroll() { + if(conio_cursor_y==CONIO_HEIGHT) { + if(conio_scroll_enable) { + // Scroll lines up + char* line1 = CONIO_SCREEN_TEXT; + char* line2 = CONIO_SCREEN_TEXT+CONIO_WIDTH; + for(char y=0;y