From 3eba81d2bdeb4590d2ea2437334921d81c4d48c5 Mon Sep 17 00:00:00 2001 From: Raimon Zamora Date: Mon, 30 Jan 2017 19:37:11 +0100 Subject: [PATCH] Work in progress --- constants.h | 38 +++++++++++++++ main.cpp | 35 +++++++++++++- parser.cpp | 107 +++++++++++++++++++++++++++++++++++++------ parser.h | 1 + rom.lbl | Bin 287 -> 305 bytes test.bas | 43 +++++++++-------- tokenizer.cpp | 29 +++++++++++- tokenizer.h | 3 ++ vbvm.vcxproj | 1 + vbvm.vcxproj.filters | 3 ++ vdp.cpp | 9 +++- vdp.h | 2 +- vm.cpp | 16 ++----- 13 files changed, 237 insertions(+), 50 deletions(-) create mode 100644 constants.h diff --git a/constants.h b/constants.h new file mode 100644 index 0000000..9ecfdc9 --- /dev/null +++ b/constants.h @@ -0,0 +1,38 @@ +#pragma once +#include "parser.h" + +void register_constants() { + parser_register_constant("ink_red", 0x00); + parser_register_constant("ink_lime", 0x01); + parser_register_constant("ink_blue", 0x02); + parser_register_constant("ink_magenta", 0x03); + parser_register_constant("ink_yellow", 0x04); + parser_register_constant("ink_cyan", 0x05); + parser_register_constant("ink_white", 0x06); + parser_register_constant("ink_black", 0x07); + parser_register_constant("ink_brown", 0x08); + parser_register_constant("ink_green", 0x09); + parser_register_constant("ink_navy", 0x0A); + parser_register_constant("ink_purple", 0x0B); + parser_register_constant("ink_gold", 0x0C); + parser_register_constant("ink_teal", 0x0D); + parser_register_constant("ink_gray", 0x0E); + parser_register_constant("ink_black2", 0x0F); + + parser_register_constant("paper_red", 0x00); + parser_register_constant("paper_lime", 0x10); + parser_register_constant("paper_blue", 0x20); + parser_register_constant("paper_magenta", 0x30); + parser_register_constant("paper_yellow", 0x40); + parser_register_constant("paper_cyan", 0x50); + parser_register_constant("paper_white", 0x60); + parser_register_constant("paper_black", 0x70); + parser_register_constant("paper_brown", 0x80); + parser_register_constant("paper_green", 0x90); + parser_register_constant("paper_navy", 0xA0); + parser_register_constant("paper_purple", 0xB0); + parser_register_constant("paper_gold", 0xC0); + parser_register_constant("paper_teal", 0xD0); + parser_register_constant("paper_gray", 0xE0); + parser_register_constant("paper_black2", 0xF0); +} diff --git a/main.cpp b/main.cpp index ac6f038..fc10df9 100644 --- a/main.cpp +++ b/main.cpp @@ -4,6 +4,35 @@ #include "vdp.h" #include +#define BTN_ANY 0 +#define BTN_UP 1 +#define BTN_DOWN 2 +#define BTN_LEFT 3 +#define BTN_RIGHT 4 +#define BTN_A 5 +#define BTN_B 6 +#define BTN_MENU 7 + +bool anykey = false; +unsigned char data_in; + +void input_data_in(const unsigned char& value) { + data_in = value; +} + +unsigned char input_data_out() { + const Uint8* keys = SDL_GetKeyboardState(nullptr); + switch (data_in) { + case BTN_ANY: return anykey; break; + case BTN_UP: return keys[SDL_SCANCODE_UP]; break; + case BTN_DOWN: return keys[SDL_SCANCODE_DOWN]; break; + case BTN_LEFT: return keys[SDL_SCANCODE_LEFT]; break; + case BTN_RIGHT: return keys[SDL_SCANCODE_RIGHT]; break; + case BTN_A: return keys[SDL_SCANCODE_RCTRL]; break; + case BTN_B: return keys[SDL_SCANCODE_RSHIFT]; break; + case BTN_MENU: return keys[SDL_SCANCODE_RETURN]; break; + }; +} int main(int argc, char** argv) { @@ -11,22 +40,26 @@ int main(int argc, char** argv) { vdp_init(); vm_register_out_port(10, vdp_data_out); vm_register_out_port(11, vdp_cmd_out); + vm_register_out_port(20, input_data_in); + vm_register_in_port(21, input_data_out); static bool should_quit = false; static SDL_Event sdlEvent; SDL_Scancode just_pressed; + //Uint32 ticks = SDL_GetTicks(); while (!should_quit) { just_pressed = SDL_SCANCODE_UNKNOWN; while (SDL_PollEvent(&sdlEvent)) { if (sdlEvent.type == SDL_QUIT) { should_quit = true; break; } else if (sdlEvent.type == SDL_KEYDOWN) { - //anyKey = true; + anykey = true; just_pressed = sdlEvent.key.keysym.scancode; if (sdlEvent.key.keysym.scancode == SDL_SCANCODE_ESCAPE) { should_quit = true; } } } vm_step(); + //if (SDL_GetTicks() - ticks >= 15) { vdp_flip(); ticks = SDL_GetTicks(); } } vdp_quit(); diff --git a/parser.cpp b/parser.cpp index bc3b5a6..f3924f6 100644 --- a/parser.cpp +++ b/parser.cpp @@ -9,6 +9,7 @@ #define MAX_LABELS 256 #define MAX_EXTERNAL_FUNCTIONS 256 #define MAX_IDENTIFIER_LENGTH 40 +#define MAX_CONSTANTS 256 struct t_label { char name[MAX_IDENTIFIER_LENGTH]; @@ -33,6 +34,11 @@ struct t_string { int num_references = 1; }; +struct t_constant { + char name[MAX_IDENTIFIER_LENGTH]; + byte value; +}; + static byte* code; // [MAX_CODE_SIZE]; static word codepos = 0; @@ -57,6 +63,9 @@ static int num_strings = 0; static bool parser_finished = false; +static t_constant constants[MAX_CONSTANTS]; +static int num_constants; + /****************************************************************************************/ /* GENERIC FUNCTIONS */ /****************************************************************************************/ @@ -119,11 +128,27 @@ static int get_variable_index(const char* string, const int array_size = 1) { else { variables = newvar; } - return newvar->index; + return newvar->index + 0xC000; } static bool is_variable_array() { return variable_is_array; } +/****************************************************************************************/ +/* CONSTANT MANAGEMENT */ +/****************************************************************************************/ +void parser_register_constant(const char* name, const unsigned char value) { + strcpy(constants[num_constants].name, name); + constants[num_constants++].value = value; +} + +static const int get_constant(const char* name) { + for (int i = 0; i < num_constants; i++) { + if (strcmp(constants[i].name, name) == 0) + return constants[i].value; + } + return -1; +} + /****************************************************************************************/ /* LABEL MANAGEMENT */ /****************************************************************************************/ @@ -167,7 +192,7 @@ static void register_label_address(const char* string) { i++; } } - num_known_labels++; + //num_known_labels++; } static void generate_anonymous_labelname(char* dest) { @@ -206,6 +231,14 @@ static void append_strings() { static void parse_expression(); static void parse_statements(); +static void parse_strleft(); +static void parse_str(); +static void parse_chr(); + +static void parse_strlen(); +static void parse_keypressed(); +static void parse_anykey(); + #define EXPECT(X, Y) if (tkn_get_token() != X) { parser_finished = true; error_raise(Y); return; } static void parse_concat_atom() { @@ -227,6 +260,9 @@ static void parse_concat_atom() { tkn_next(); return; } + if (tkn_get_token() == TOKEN_STRLEFT) { tkn_next(); parse_strleft(); return; } + if (tkn_get_token() == TOKEN_STR) { tkn_next(); parse_str(); return; } + if (tkn_get_token() == TOKEN_CHR) { tkn_next(); parse_chr(); return; } parser_finished = true; error_raise("Syntax error"); return; } @@ -248,6 +284,13 @@ static void parse_expr_atom() { return; } if (tkn_get_token() == TOKEN_IDENTIFIER) { + int constvalue = get_constant(tkn_get_string()); + if (constvalue != -1) { + emmit(OP_PUSH); + emmit(constvalue); + tkn_next(); + return; + } int ivar = get_variable_index(tkn_get_string()); if (is_variable_array()) { tkn_next(); EXPECT(TOKEN_LPAR, "Expected array index"); @@ -282,6 +325,10 @@ static void parse_expr_atom() { tkn_next(); return; } + if (tkn_get_token() == TOKEN_STRLEN) { tkn_next(); parse_strlen(); return; } + if (tkn_get_token() == TOKEN_KEYPRESSED) { tkn_next(); parse_keypressed(); return; } + if (tkn_get_token() == TOKEN_ANYKEY) { tkn_next(); parse_anykey(); return; } + parser_finished = true; error_raise("Syntax error"); return; } @@ -339,6 +386,17 @@ static void parse_expression() { } } +static void parse_const() { + EXPECT(TOKEN_IDENTIFIER, "Expected identifier"); + char constname[40]; + strcpy(constname, tkn_get_string()); + tkn_next(); EXPECT(TOKEN_EQ, "Expected '='"); + tkn_next(); EXPECT(TOKEN_NUMBER, "Expected integer constant"); + int constvalue = tkn_get_value(); + parser_register_constant(constname, constvalue); + tkn_next(); +} + static void parse_dim() { EXPECT(TOKEN_IDENTIFIER, "Expected variable"); char varname[40]; @@ -674,9 +732,22 @@ static void parse_border() { emmit_w(get_label_address("_sys_vdp_border")); } +static void parse_clrscr() { + emmit(OP_JSR); + emmit_w(get_label_address("_sys_vdp_clrscr")); +} + +static void parse_wait() { + parse_expression(); + emmit(OP_SLEEP); +} + + static void parse_statements() { while (!parser_finished) { switch (tkn_get_token()) { + case TOKEN_CONST: + tkn_next(); parse_const(); break; case TOKEN_DIM: tkn_next(); parse_dim(); break; case TOKEN_LET: @@ -704,16 +775,16 @@ static void parse_statements() { case TOKEN_REM: tkn_next(); break; - case TOKEN_STRLEFT: - tkn_next(); parse_strleft(); break; - case TOKEN_STRLEN: - tkn_next(); parse_strlen(); break; + //case TOKEN_STRLEFT: <--- Parsed in parse_concat_atom + // tkn_next(); parse_strleft(); break; + //case TOKEN_STRLEN: <--- Parsed in parse_expr_atom + // tkn_next(); parse_strlen(); break; case TOKEN_DEBUG: tkn_next(); parse_debug(); break; - case TOKEN_CHR: - tkn_next(); parse_chr(); break; - case TOKEN_STR: - tkn_next(); parse_str(); break; + //case TOKEN_CHR: + // tkn_next(); parse_chr(); break; <--- Parsed in parse_concat_atom + //case TOKEN_STR: + // tkn_next(); parse_str(); break; <--- Parsed in parse_concat_atom case TOKEN_SETSPRITE: tkn_next(); parse_setsprite(); break; case TOKEN_PUTSPRITE: @@ -726,16 +797,20 @@ static void parse_statements() { tkn_next(); parse_putchar(); break; case TOKEN_SETCHAR: tkn_next(); parse_setchar(); break; - case TOKEN_KEYPRESSED: - tkn_next(); parse_keypressed(); break; - case TOKEN_ANYKEY: - tkn_next(); parse_anykey(); break; + //case TOKEN_KEYPRESSED: <--- Parsed in parse_expr_atom + // tkn_next(); parse_keypressed(); break; + //case TOKEN_ANYKEY: <--- Parsed in parse_expr_atom + // tkn_next(); parse_anykey(); break; case TOKEN_UPDATESCR: tkn_next(); parse_updatescr(); break; case TOKEN_COLOR: tkn_next(); parse_color(); break; case TOKEN_BORDER: tkn_next(); parse_border(); break; + case TOKEN_CLRSCR: + tkn_next(); parse_clrscr(); break; + case TOKEN_WAIT: + tkn_next(); parse_wait(); break; case TOKEN_IDENTIFIER: for (int i = 0; i < num_external_functions; i++) { @@ -781,6 +856,10 @@ void parser_parse(const char* buffer, byte* mem) { parse_statements(); append_strings(); + FILE *f = fopen("test.bin", "wb"); + fwrite(mem, codepos, 1, f); + fclose(f); + //return code; } diff --git a/parser.h b/parser.h index f43086b..c3b64bf 100644 --- a/parser.h +++ b/parser.h @@ -78,3 +78,4 @@ void parser_parse(const char* buffer, unsigned char* mem); const int parser_get_codesize(); const int parser_get_memory_usage(); void parser_register_external_function(const char* name, const int num_parameters); +void parser_register_constant(const char* name, const unsigned char value); \ No newline at end of file diff --git a/rom.lbl b/rom.lbl index 37a390c9dc0eda969c4db7c53ab379ba118f99af..5dbc3f55dddcedefed7771de46f31ca16c120153 100644 GIT binary patch delta 51 zcmbQww2_HXU?U?3qXvI`ab= 48 && CCHR <= 57) || (CCHR >= 65 && CCHR <= 70)) { + do { value = (value << 4) + hex_digit(CCHR); NEXT; } while ((CCHR >= 48 && CCHR <= 57) || (CCHR >= 65 && CCHR <= 70)); + current_token = TOKEN_NUMBER; return; + } + } + if ((CCHR | 32) == 'b') { + NEXT; + if (CCHR == 48 || CCHR == 49) { + do { value = (value << 1) + (CCHR-48); NEXT; } while (CCHR == 48 || CCHR == 49); + current_token = TOKEN_NUMBER; return; + } + } + current_token = TOKEN_ERROR; + error_raise("Syntax error"); + return; + } + // if no match, it's an error current_token = TOKEN_ERROR; return; } diff --git a/tokenizer.h b/tokenizer.h index 54f6bc2..9904db8 100644 --- a/tokenizer.h +++ b/tokenizer.h @@ -11,6 +11,7 @@ enum t_tokentype { TOKEN_IDENTIFIER, TOKEN_LABEL, TOKEN_DIM, + TOKEN_CONST, TOKEN_LET, TOKEN_IF, @@ -66,6 +67,8 @@ enum t_tokentype { TOKEN_UPDATESCR, TOKEN_COLOR, TOKEN_BORDER, + TOKEN_CLRSCR, + TOKEN_WAIT, }; void tkn_init(const char* buffer); diff --git a/vbvm.vcxproj b/vbvm.vcxproj index e3faf46..70777dc 100644 --- a/vbvm.vcxproj +++ b/vbvm.vcxproj @@ -88,6 +88,7 @@ + diff --git a/vbvm.vcxproj.filters b/vbvm.vcxproj.filters index c28762b..1c443c9 100644 --- a/vbvm.vcxproj.filters +++ b/vbvm.vcxproj.filters @@ -62,5 +62,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/vdp.cpp b/vdp.cpp index 42f6c81..39beb3d 100644 --- a/vdp.cpp +++ b/vdp.cpp @@ -13,6 +13,7 @@ #define VDP_CMD_FLIP 6 #define VDP_CMD_COLOR 7 #define VDP_CMD_BORDER 8 +#define VDP_CMD_CLRSCR 9 struct t_sprite { Uint8 x = 0; @@ -96,7 +97,7 @@ void vdp_quit() { SDL_Quit(); } -static void flip() { +void vdp_flip() { Uint8* sb = screen_buffer; Uint8* sm = screen_map; Uint8* sc = screen_color; @@ -191,7 +192,7 @@ void vdp_cmd_out(const unsigned char& value) { sprites[n].col = data_stack[data_stack_pos - 3] & 0xF; break; case VDP_CMD_FLIP: - flip(); break; + vdp_flip(); break; case VDP_CMD_COLOR: color = data_stack[0]; break; @@ -199,6 +200,10 @@ void vdp_cmd_out(const unsigned char& value) { border = data_stack[0] & 0xF; SDL_SetRenderDrawColor(sdlRenderer, palette[border][0], palette[border][1], palette[border][2], palette[border][3]); break; + case VDP_CMD_CLRSCR: + for (int i = 0; i < 16 * 12; i++) screen_map[i] = 32; + for (int i = 0; i < 16 * 12; i++) screen_color[i] = color; + break; } data_stack_pos = 0; } diff --git a/vdp.h b/vdp.h index 2d5ac40..1344a00 100644 --- a/vdp.h +++ b/vdp.h @@ -2,7 +2,7 @@ void vdp_init(); void vdp_quit(); - +void vdp_flip(); void vdp_data_out(const unsigned char& value); void vdp_cmd_out(const unsigned char& value); unsigned char vdp_in(); diff --git a/vm.cpp b/vm.cpp index 726b9ec..5e2f633 100644 --- a/vm.cpp +++ b/vm.cpp @@ -3,6 +3,8 @@ #include #include "parser.h" #include "error.h" +#include "constants.h" +#include // For SDL_Delay #define MAX_EXTERNAL_CALLS 256 #define MAX_DATA_STACK 256 @@ -116,30 +118,22 @@ static void load_rom() { } static void load_program(const char* filename) { -/* FILE *f = fopen(filename, "rb"); - fseek(f, 0, SEEK_END); - long fsize = ftell(f); - fseek(f, 0, SEEK_SET); - fread(mem, fsize, 1, f); - fclose(f);*/ FILE *f = fopen(filename, "rb"); fseek(f, 0, SEEK_END); long fsize = ftell(f); fseek(f, 0, SEEK_SET); //same as rewind(f); - char *program = (char*)malloc(fsize + 1); fread(program, fsize, 1, f); fclose(f); - program[fsize] = 0; - //unsigned char* rawCode = + register_constants(); + parser_parse(program, mem); free(program); if (error_raised()) { error_print(); - //getchar(); } else { printf("Compilation complete!\nProgram size: %d bytes\nMemory usage: %d bytes\n", parser_get_codesize(), parser_get_memory_usage()); @@ -240,7 +234,7 @@ const int vm_step() { case OP_GEQ: stack_push(vm_datastack, stack_pop(vm_datastack) >= stack_pop(vm_datastack)); vm_cycles++; break; case OP_IN: stack_push(vm_datastack, in_ports[vm_program[vm_pc++]]()); vm_cycles++; break; case OP_OUT: out_ports[vm_program[vm_pc++]](stack_pop(vm_datastack)); vm_cycles++; break; - case OP_SLEEP: sleeping = true; vm_cycles++; break; + case OP_SLEEP: SDL_Delay(stack_pop(vm_datastack) * 1000); vm_cycles++; break; } return vm_cycles; }