diff --git a/src/main/kc/include/mos6561.h b/src/main/kc/include/mos6561.h index dce704b9f..164e22332 100644 --- a/src/main/kc/include/mos6561.h +++ b/src/main/kc/include/mos6561.h @@ -15,11 +15,12 @@ struct MOS6561_VIC { // bit 7: Upper bit of video matrix address (also controls address of COLOR RAM) char MATRIX_COLUMNS; // Number of Screen Rows - // bits 1-6: set ol rows - // bit 7: sets or 16 chars + // bit 0: select 0) 8x8 chars or 1) 16x8 chars + // bits 1-6: Number of rows + // bit 7: Current TV raster mean line bit 0. char MATRIX_ROWS; // The Raster Line - // bits 0-7: Current TV raster beam line + // bits 0-7: Current TV raster beam line (bit 8-1) char RASTER; // Character and Screen Address // bits 0-3: start of character memory (default 0) diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 4bf633bd4..976c05a50 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -44,6 +44,12 @@ public class TestPrograms { public TestPrograms() { } + @Test + public void testVic20Raster() throws IOException, URISyntaxException { + compileAndCompare("vic20-raster.c"); + } + + @Test public void testVic20Simple() throws IOException, URISyntaxException { compileAndCompare("vic20-simple.c"); diff --git a/src/test/kc/plus4-keyboard-test.c b/src/test/kc/plus4-keyboard-test.c new file mode 100644 index 000000000..f1ef0f892 --- /dev/null +++ b/src/test/kc/plus4-keyboard-test.c @@ -0,0 +1,30 @@ +// Test reading keyboard port on the TED of the Plus/4 +#pragma target(plus4basic) + +#include + +// Keyboard latch +char * const KEYBOARD_INPUT = 0xff08; +// Keyboard scan +char * const KEYBOARD_SCAN = 0xfd30; +// Default address of screen character matrix +char * const DEFAULT_SCREEN = 0x0c00; + +void main() { + asm { sei } + memset(DEFAULT_SCREEN, ' ', 0x0400); + while(1) { + char * row = DEFAULT_SCREEN; + for(char y=0;y<8;y++) { + *KEYBOARD_SCAN = 0xff^(1< + +void main() { + asm { sei } + while(1) { + VIC->BORDER_BACKGROUND_COLOR = VIC->RASTER; + } +} \ No newline at end of file diff --git a/src/test/ref/vic20-raster.asm b/src/test/ref/vic20-raster.asm new file mode 100644 index 000000000..f714b81a9 --- /dev/null +++ b/src/test/ref/vic20-raster.asm @@ -0,0 +1,17 @@ +// VIC 20 Raster bars +.pc = $1001 "Basic" +:BasicUpstart(main) +.pc = $100d "Program" + .const OFFSET_STRUCT_MOS6561_VIC_RASTER = 4 + .const OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR = $f + // The MOS 6560/6561 VIC Video Interface Chip + .label VIC = $9000 +main: { + // asm + sei + __b1: + // VIC->BORDER_BACKGROUND_COLOR = VIC->RASTER + lda VIC+OFFSET_STRUCT_MOS6561_VIC_RASTER + sta VIC+OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR + jmp __b1 +} diff --git a/src/test/ref/vic20-raster.cfg b/src/test/ref/vic20-raster.cfg new file mode 100644 index 000000000..3b0fe8dc0 --- /dev/null +++ b/src/test/ref/vic20-raster.cfg @@ -0,0 +1,17 @@ +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() + +(void()) main() +main: scope:[main] from @1 + asm { sei } + to:main::@1 +main::@1: scope:[main] from main main::@1 + [5] *((byte*)(const nomodify struct MOS6561_VIC*) VIC+(const byte) OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR) ← *((byte*)(const nomodify struct MOS6561_VIC*) VIC+(const byte) OFFSET_STRUCT_MOS6561_VIC_RASTER) + to:main::@1 diff --git a/src/test/ref/vic20-raster.log b/src/test/ref/vic20-raster.log new file mode 100644 index 000000000..be540ce4c --- /dev/null +++ b/src/test/ref/vic20-raster.log @@ -0,0 +1,344 @@ + +CONTROL FLOW GRAPH SSA +@begin: scope:[] from + to:@1 + +(void()) main() +main: scope:[main] from @1 + asm { sei } + to:main::@1 +main::@1: scope:[main] from main main::@2 + (bool~) main::$0 ← (number) 0 != (number) 1 + if((bool~) main::$0) goto main::@2 + to:main::@return +main::@2: scope:[main] from main::@1 + *((byte*)(const nomodify struct MOS6561_VIC*) VIC+(const byte) OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR) ← *((byte*)(const nomodify struct MOS6561_VIC*) VIC+(const byte) OFFSET_STRUCT_MOS6561_VIC_RASTER) + to:main::@1 +main::@return: scope:[main] from main::@1 + return + to:@return +@1: scope:[] from @begin + call main + to:@2 +@2: scope:[] from @1 + to:@end +@end: scope:[] from @2 + +SYMBOL TABLE SSA +(label) @1 +(label) @2 +(label) @begin +(label) @end +(byte) MOS6522_VIA::AUX_CONTROL +(byte) MOS6522_VIA::INTERRUPT_ENABLE +(byte) MOS6522_VIA::INTERRUPT_FLAG +(byte) MOS6522_VIA::PERIPHERAL_CONTROL +(byte) MOS6522_VIA::PORT_A +(byte) MOS6522_VIA::PORT_A_DDR +(byte) MOS6522_VIA::PORT_A_OUTPUT +(byte) MOS6522_VIA::PORT_B +(byte) MOS6522_VIA::PORT_B_DDR +(byte) MOS6522_VIA::SHIFT +(byte) MOS6522_VIA::TIMER1_HIGH +(byte) MOS6522_VIA::TIMER1_LATCH_HIGH +(byte) MOS6522_VIA::TIMER1_LATCH_LOW +(byte) MOS6522_VIA::TIMER1_LOW +(byte) MOS6522_VIA::TIMER2_HIGH +(byte) MOS6522_VIA::TIMER2_LOW +(byte) MOS6561_VIC::BORDER_BACKGROUND_COLOR +(byte) MOS6561_VIC::CH1_FREQ +(byte) MOS6561_VIC::CH2_FREQ +(byte) MOS6561_VIC::CH3_FREQ +(byte) MOS6561_VIC::CH4_FREQ +(byte) MOS6561_VIC::LIGHTPEN_X +(byte) MOS6561_VIC::LIGHTPEN_Y +(byte) MOS6561_VIC::MATRIX_COLUMNS +(byte) MOS6561_VIC::MATRIX_ROWS +(byte) MOS6561_VIC::MEMORY +(byte) MOS6561_VIC::ORIGIN_X +(byte) MOS6561_VIC::ORIGIN_Y +(byte) MOS6561_VIC::PADDLE_X +(byte) MOS6561_VIC::PADDLE_Y +(byte) MOS6561_VIC::RASTER +(byte) MOS6561_VIC::VOLUME_COLOR +(const byte) OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR = (byte) $f +(const byte) OFFSET_STRUCT_MOS6561_VIC_RASTER = (byte) 4 +(const nomodify struct MOS6561_VIC*) VIC = (struct MOS6561_VIC*)(number) $9000 +(void()) main() +(bool~) main::$0 +(label) main::@1 +(label) main::@2 +(label) main::@return + +Simplifying constant pointer cast (struct MOS6561_VIC*) 36864 +Successful SSA optimization PassNCastSimplification +Simple Condition (bool~) main::$0 [2] if((number) 0!=(number) 1) goto main::@2 +Successful SSA optimization Pass2ConditionalJumpSimplification +if() condition always true - replacing block destination [2] if((number) 0!=(number) 1) goto main::@2 +Successful SSA optimization Pass2ConstantIfs +Removing unused block main::@return +Successful SSA optimization Pass2EliminateUnusedBlocks +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @2 +Adding NOP phi() at start of @end +Adding NOP phi() at start of main::@1 +CALL GRAPH +Calls in [] to main:2 + +Created 0 initial phi equivalence classes +Coalesced down to 0 phi equivalence classes +Culled Empty Block (label) @2 +Culled Empty Block (label) main::@1 +Renumbering block main::@2 to main::@1 +Adding NOP phi() at start of @begin +Adding NOP phi() at start of @1 +Adding NOP phi() at start of @end + +FINAL CONTROL FLOW GRAPH +@begin: scope:[] from + [0] phi() + to:@1 +@1: scope:[] from @begin + [1] phi() + [2] call main + to:@end +@end: scope:[] from @1 + [3] phi() + +(void()) main() +main: scope:[main] from @1 + asm { sei } + to:main::@1 +main::@1: scope:[main] from main main::@1 + [5] *((byte*)(const nomodify struct MOS6561_VIC*) VIC+(const byte) OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR) ← *((byte*)(const nomodify struct MOS6561_VIC*) VIC+(const byte) OFFSET_STRUCT_MOS6561_VIC_RASTER) + to:main::@1 + + +VARIABLE REGISTER WEIGHTS +(byte) MOS6522_VIA::AUX_CONTROL +(byte) MOS6522_VIA::INTERRUPT_ENABLE +(byte) MOS6522_VIA::INTERRUPT_FLAG +(byte) MOS6522_VIA::PERIPHERAL_CONTROL +(byte) MOS6522_VIA::PORT_A +(byte) MOS6522_VIA::PORT_A_DDR +(byte) MOS6522_VIA::PORT_A_OUTPUT +(byte) MOS6522_VIA::PORT_B +(byte) MOS6522_VIA::PORT_B_DDR +(byte) MOS6522_VIA::SHIFT +(byte) MOS6522_VIA::TIMER1_HIGH +(byte) MOS6522_VIA::TIMER1_LATCH_HIGH +(byte) MOS6522_VIA::TIMER1_LATCH_LOW +(byte) MOS6522_VIA::TIMER1_LOW +(byte) MOS6522_VIA::TIMER2_HIGH +(byte) MOS6522_VIA::TIMER2_LOW +(byte) MOS6561_VIC::BORDER_BACKGROUND_COLOR +(byte) MOS6561_VIC::CH1_FREQ +(byte) MOS6561_VIC::CH2_FREQ +(byte) MOS6561_VIC::CH3_FREQ +(byte) MOS6561_VIC::CH4_FREQ +(byte) MOS6561_VIC::LIGHTPEN_X +(byte) MOS6561_VIC::LIGHTPEN_Y +(byte) MOS6561_VIC::MATRIX_COLUMNS +(byte) MOS6561_VIC::MATRIX_ROWS +(byte) MOS6561_VIC::MEMORY +(byte) MOS6561_VIC::ORIGIN_X +(byte) MOS6561_VIC::ORIGIN_Y +(byte) MOS6561_VIC::PADDLE_X +(byte) MOS6561_VIC::PADDLE_Y +(byte) MOS6561_VIC::RASTER +(byte) MOS6561_VIC::VOLUME_COLOR +(void()) main() + +Initial phi equivalence classes +Complete equivalence classes + +INITIAL ASM +Target platform is vic20basic / MOS6502X + // File Comments +// VIC 20 Raster bars + // Upstart +.pc = $1001 "Basic" +:BasicUpstart(main) +.pc = $100d "Program" + // Global Constants & labels + .const OFFSET_STRUCT_MOS6561_VIC_RASTER = 4 + .const OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR = $f + // The MOS 6560/6561 VIC Video Interface Chip + .label VIC = $9000 + // @begin +__bbegin: + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: + jmp __b1 + // @1 +__b1: + // [2] call main + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +__bend_from___b1: + jmp __bend + // @end +__bend: + // main +main: { + // asm { sei } + sei + jmp __b1 + // main::@1 + __b1: + // [5] *((byte*)(const nomodify struct MOS6561_VIC*) VIC+(const byte) OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR) ← *((byte*)(const nomodify struct MOS6561_VIC*) VIC+(const byte) OFFSET_STRUCT_MOS6561_VIC_RASTER) -- _deref_pbuc1=_deref_pbuc2 + lda VIC+OFFSET_STRUCT_MOS6561_VIC_RASTER + sta VIC+OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR + jmp __b1 +} + // File Data + +REGISTER UPLIFT POTENTIAL REGISTERS +Statement [5] *((byte*)(const nomodify struct MOS6561_VIC*) VIC+(const byte) OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR) ← *((byte*)(const nomodify struct MOS6561_VIC*) VIC+(const byte) OFFSET_STRUCT_MOS6561_VIC_RASTER) [ ] ( main:2 [ ] { } ) always clobbers reg byte a + +REGISTER UPLIFT SCOPES +Uplift Scope [MOS6561_VIC] +Uplift Scope [MOS6522_VIA] +Uplift Scope [main] +Uplift Scope [] + +Uplifting [MOS6561_VIC] best 127 combination +Uplifting [MOS6522_VIA] best 127 combination +Uplifting [main] best 127 combination +Uplifting [] best 127 combination + +ASSEMBLER BEFORE OPTIMIZATION + // File Comments +// VIC 20 Raster bars + // Upstart +.pc = $1001 "Basic" +:BasicUpstart(main) +.pc = $100d "Program" + // Global Constants & labels + .const OFFSET_STRUCT_MOS6561_VIC_RASTER = 4 + .const OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR = $f + // The MOS 6560/6561 VIC Video Interface Chip + .label VIC = $9000 + // @begin +__bbegin: + // [1] phi from @begin to @1 [phi:@begin->@1] +__b1_from___bbegin: + jmp __b1 + // @1 +__b1: + // [2] call main + jsr main + // [3] phi from @1 to @end [phi:@1->@end] +__bend_from___b1: + jmp __bend + // @end +__bend: + // main +main: { + // asm { sei } + sei + jmp __b1 + // main::@1 + __b1: + // [5] *((byte*)(const nomodify struct MOS6561_VIC*) VIC+(const byte) OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR) ← *((byte*)(const nomodify struct MOS6561_VIC*) VIC+(const byte) OFFSET_STRUCT_MOS6561_VIC_RASTER) -- _deref_pbuc1=_deref_pbuc2 + lda VIC+OFFSET_STRUCT_MOS6561_VIC_RASTER + sta VIC+OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR + jmp __b1 +} + // File Data + +ASSEMBLER OPTIMIZATIONS +Removing instruction jmp __b1 +Removing instruction jmp __bend +Removing instruction jmp __b1 +Succesful ASM optimization Pass5NextJumpElimination +Removing instruction __b1_from___bbegin: +Removing instruction __b1: +Removing instruction __bend_from___b1: +Succesful ASM optimization Pass5RedundantLabelElimination +Removing instruction __bbegin: +Removing instruction __bend: +Succesful ASM optimization Pass5UnusedLabelElimination +Removing instruction jsr main +Succesful ASM optimization Pass5SkipBegin + +FINAL SYMBOL TABLE +(label) @1 +(label) @begin +(label) @end +(byte) MOS6522_VIA::AUX_CONTROL +(byte) MOS6522_VIA::INTERRUPT_ENABLE +(byte) MOS6522_VIA::INTERRUPT_FLAG +(byte) MOS6522_VIA::PERIPHERAL_CONTROL +(byte) MOS6522_VIA::PORT_A +(byte) MOS6522_VIA::PORT_A_DDR +(byte) MOS6522_VIA::PORT_A_OUTPUT +(byte) MOS6522_VIA::PORT_B +(byte) MOS6522_VIA::PORT_B_DDR +(byte) MOS6522_VIA::SHIFT +(byte) MOS6522_VIA::TIMER1_HIGH +(byte) MOS6522_VIA::TIMER1_LATCH_HIGH +(byte) MOS6522_VIA::TIMER1_LATCH_LOW +(byte) MOS6522_VIA::TIMER1_LOW +(byte) MOS6522_VIA::TIMER2_HIGH +(byte) MOS6522_VIA::TIMER2_LOW +(byte) MOS6561_VIC::BORDER_BACKGROUND_COLOR +(byte) MOS6561_VIC::CH1_FREQ +(byte) MOS6561_VIC::CH2_FREQ +(byte) MOS6561_VIC::CH3_FREQ +(byte) MOS6561_VIC::CH4_FREQ +(byte) MOS6561_VIC::LIGHTPEN_X +(byte) MOS6561_VIC::LIGHTPEN_Y +(byte) MOS6561_VIC::MATRIX_COLUMNS +(byte) MOS6561_VIC::MATRIX_ROWS +(byte) MOS6561_VIC::MEMORY +(byte) MOS6561_VIC::ORIGIN_X +(byte) MOS6561_VIC::ORIGIN_Y +(byte) MOS6561_VIC::PADDLE_X +(byte) MOS6561_VIC::PADDLE_Y +(byte) MOS6561_VIC::RASTER +(byte) MOS6561_VIC::VOLUME_COLOR +(const byte) OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR = (byte) $f +(const byte) OFFSET_STRUCT_MOS6561_VIC_RASTER = (byte) 4 +(const nomodify struct MOS6561_VIC*) VIC = (struct MOS6561_VIC*) 36864 +(void()) main() +(label) main::@1 + + + +FINAL ASSEMBLER +Score: 112 + + // File Comments +// VIC 20 Raster bars + // Upstart +.pc = $1001 "Basic" +:BasicUpstart(main) +.pc = $100d "Program" + // Global Constants & labels + .const OFFSET_STRUCT_MOS6561_VIC_RASTER = 4 + .const OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR = $f + // The MOS 6560/6561 VIC Video Interface Chip + .label VIC = $9000 + // @begin + // [1] phi from @begin to @1 [phi:@begin->@1] + // @1 + // [2] call main + // [3] phi from @1 to @end [phi:@1->@end] + // @end + // main +main: { + // asm + // asm { sei } + sei + // main::@1 + __b1: + // VIC->BORDER_BACKGROUND_COLOR = VIC->RASTER + // [5] *((byte*)(const nomodify struct MOS6561_VIC*) VIC+(const byte) OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR) ← *((byte*)(const nomodify struct MOS6561_VIC*) VIC+(const byte) OFFSET_STRUCT_MOS6561_VIC_RASTER) -- _deref_pbuc1=_deref_pbuc2 + lda VIC+OFFSET_STRUCT_MOS6561_VIC_RASTER + sta VIC+OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR + jmp __b1 +} + // File Data + diff --git a/src/test/ref/vic20-raster.sym b/src/test/ref/vic20-raster.sym new file mode 100644 index 000000000..6d7f38773 --- /dev/null +++ b/src/test/ref/vic20-raster.sym @@ -0,0 +1,41 @@ +(label) @1 +(label) @begin +(label) @end +(byte) MOS6522_VIA::AUX_CONTROL +(byte) MOS6522_VIA::INTERRUPT_ENABLE +(byte) MOS6522_VIA::INTERRUPT_FLAG +(byte) MOS6522_VIA::PERIPHERAL_CONTROL +(byte) MOS6522_VIA::PORT_A +(byte) MOS6522_VIA::PORT_A_DDR +(byte) MOS6522_VIA::PORT_A_OUTPUT +(byte) MOS6522_VIA::PORT_B +(byte) MOS6522_VIA::PORT_B_DDR +(byte) MOS6522_VIA::SHIFT +(byte) MOS6522_VIA::TIMER1_HIGH +(byte) MOS6522_VIA::TIMER1_LATCH_HIGH +(byte) MOS6522_VIA::TIMER1_LATCH_LOW +(byte) MOS6522_VIA::TIMER1_LOW +(byte) MOS6522_VIA::TIMER2_HIGH +(byte) MOS6522_VIA::TIMER2_LOW +(byte) MOS6561_VIC::BORDER_BACKGROUND_COLOR +(byte) MOS6561_VIC::CH1_FREQ +(byte) MOS6561_VIC::CH2_FREQ +(byte) MOS6561_VIC::CH3_FREQ +(byte) MOS6561_VIC::CH4_FREQ +(byte) MOS6561_VIC::LIGHTPEN_X +(byte) MOS6561_VIC::LIGHTPEN_Y +(byte) MOS6561_VIC::MATRIX_COLUMNS +(byte) MOS6561_VIC::MATRIX_ROWS +(byte) MOS6561_VIC::MEMORY +(byte) MOS6561_VIC::ORIGIN_X +(byte) MOS6561_VIC::ORIGIN_Y +(byte) MOS6561_VIC::PADDLE_X +(byte) MOS6561_VIC::PADDLE_Y +(byte) MOS6561_VIC::RASTER +(byte) MOS6561_VIC::VOLUME_COLOR +(const byte) OFFSET_STRUCT_MOS6561_VIC_BORDER_BACKGROUND_COLOR = (byte) $f +(const byte) OFFSET_STRUCT_MOS6561_VIC_RASTER = (byte) 4 +(const nomodify struct MOS6561_VIC*) VIC = (struct MOS6561_VIC*) 36864 +(void()) main() +(label) main::@1 +