diff --git a/main.c b/main.c index 611040c..d4555ba 100644 --- a/main.c +++ b/main.c @@ -47,6 +47,8 @@ uint8_t title_length = 9; #define T_THEN 0x92 #define T_GR 0x93 #define T_TEXT 0x94 +#define T_COLOR 0x95 +#define T_PLOT 0x96 // Operators. These encode both the operator (high nybble) and the precedence // (low nybble). Lower precedence has a lower low nybble value. For example, @@ -117,6 +119,8 @@ static uint8_t *TOKEN[] = { "THEN", "GR", "TEXT", + "COLOR", + "PLOT", }; static int16_t TOKEN_COUNT = sizeof(TOKEN)/sizeof(TOKEN[0]); @@ -771,6 +775,26 @@ static void compile_buffer(uint8_t *buffer, uint16_t line_number) { } else if (*s == T_TEXT) { s += 1; add_call(text_statement); + } else if (*s == T_COLOR) { + s += 1; + if (*s != T_EQUAL) { + error = 1; + } else { + s += 1; + s = compile_expression(s); + add_call(color_statement); + } + } else if (*s == T_PLOT) { + s += 1; + s = compile_expression(s); + add_call(pushax); + if (*s != ',') { + error = 1; + } else { + s += 1; + s = compile_expression(s); + add_call(plot_statement); + } } else { error = 1; } @@ -980,6 +1004,7 @@ int16_t main(void) { int16_t blink; + /* // For testing generated code. TODO remove { int16_t a, b, c; @@ -987,6 +1012,7 @@ int16_t main(void) c = 6; a = b == c; } + */ // Clear stored program. new_statement(); diff --git a/runtime.c b/runtime.c index 73ab6ef..ab4f9d3 100644 --- a/runtime.c +++ b/runtime.c @@ -21,6 +21,10 @@ uint8_t g_cursor_ch = 0; // Whether in low-res graphics mode. uint8_t g_gr_mode = 0; +// 4-bit low-res color. +uint8_t g_gr_color_high = 0; // High nybble. +uint8_t g_gr_color_low = 0; // Low nybble. + // List of variable names, two bytes each, in the same order they are // in the zero page (starting at FIRST_VARIABLE). Two nuls means an unused // slot. One-letter variable names have a nul for the second character. @@ -250,3 +254,26 @@ void text_statement(void) { g_gr_mode = 0; } + +/** + * Set the low-res color. + */ +void color_statement(uint16_t color) { + g_gr_color_high = (uint8_t) ((color << 4) & 0xF0); + g_gr_color_low = (uint8_t) (color & 0x0F); +} + +/** + * Plot a pixel in low-res graphics mode. + */ +void plot_statement(uint16_t x, uint16_t y) { + uint8_t *pos = screen_pos(x, y >> 1); + + if ((y & 1) == 0) { + // Even, bottom pixel. + *pos = (*pos & 0xF0) | g_gr_color_low; + } else { + // Odd, top pixel. + *pos = (*pos & 0x0F) | g_gr_color_high; + } +} diff --git a/runtime.h b/runtime.h index 66c186c..3cbd514 100644 --- a/runtime.h +++ b/runtime.h @@ -38,5 +38,7 @@ void syntax_error_in_line(uint16_t line_number); void gr_statement(void); void text_statement(void); +void color_statement(uint16_t color); +void plot_statement(uint16_t x, uint16_t y); #endif // __RUNTIME_H__