From 784ff59108b887e246b0f33ff696dfd981659ab2 Mon Sep 17 00:00:00 2001 From: mrb0nk500 Date: Thu, 24 Sep 2020 08:21:08 -0400 Subject: - Fixed some more bugs with struct, and union handling. --- asmmon.h | 7 +++-- assemble.c | 6 ++-- disasm.c | 17 +++++++++++ lexer.c | 38 +++++++++++++++---------- programs/sub-suite/declare.s | 16 +++++++---- programs/sub-suite/lexer.s | 10 +++---- sux.c | 15 +--------- sux.h | 1 + test/subroutine.s | 67 ++++++++++++++++++++++++++------------------ 9 files changed, 104 insertions(+), 73 deletions(-) diff --git a/asmmon.h b/asmmon.h index 27a6ede..a031e7d 100644 --- a/asmmon.h +++ b/asmmon.h @@ -60,9 +60,9 @@ struct sym { symbol *up; uint16_t count; uint64_t val; - uint8_t isstruct; - uint8_t isanon; - uint8_t def; + uint8_t isstruct : 1; + uint8_t isanon : 1; + uint8_t def : 1; char *name; uint16_t id; }; @@ -567,4 +567,5 @@ extern token *skip_expr(token *t, uint8_t dbg); extern uint64_t parse_tokens(token *tm, line **l, bytecount *bc, uint8_t isasm, uint64_t address, uint8_t dbg); extern token *make_token(uint8_t id, uint8_t type, uint8_t space, uint8_t tab, uint64_t value, char *str, symbol *s); extern void assemble(line *ln, bytecount *bc, uint8_t dbg); +extern void fix_symtree(line *l); extern void cleanup(); diff --git a/assemble.c b/assemble.c index 24037d9..8d7eb85 100644 --- a/assemble.c +++ b/assemble.c @@ -192,9 +192,11 @@ uint16_t handle_struct(line **ln, uint64_t address, uint16_t offset, uint8_t dbg if (member && t->type != DIR_UNION && t->type != DIR_STRUCT) { member->val = offset; } - size += member_size; if (is_struct) { + size += member_size; offset += member_size; + } else if (size < member_size) { + size = member_size; } } ismember = 0; @@ -666,7 +668,7 @@ static void print_symtree(symbol *s, int depth) { } } -static void fix_symtree(line *l) { +void fix_symtree(line *l) { symbol *s = symbols; symbol *cur_sym = NULL; symbol *sym_struct = NULL; diff --git a/disasm.c b/disasm.c index 43f78db..3fd0c11 100644 --- a/disasm.c +++ b/disasm.c @@ -2,6 +2,23 @@ #include "disasm.h" #include +void print_regs(struct sux *cpu, uint8_t lines, uint8_t thread) { + for (uint8_t i = (24*thread)+2; i <= 24*(thread+1); i++) { + wmove(scr, i, 0); + waddch(scr, (i == lines) ? '>' : ' '); + } + wmove(scr, lines, 1); + wclrtoeol(scr); + wprintw(scr, "pc: $%04"PRIX64 , cpu->pc); + wprintw(scr, ", a: $%016"PRIX64, cpu->a); + wprintw(scr, ", b: $%016"PRIX64, cpu->b); + wprintw(scr, ", x: $%016"PRIX64, cpu->x); + wprintw(scr, ", y: $%016"PRIX64, cpu->y); + wprintw(scr, ", sp: $%04X", cpu->sp); + wprintw(scr, ", ps: $%02X", cpu->ps.u8[thread]); + wprintw(scr, ", inst: "); +} + void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint8_t thread) { uint64_t value; uint64_t address = get_addr(cpu, opcode, prefix, 0, 0, thread); diff --git a/lexer.c b/lexer.c index e239a5e..31c205f 100644 --- a/lexer.c +++ b/lexer.c @@ -243,7 +243,7 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { uint8_t k = 0; union reg ch; - ch.u64 =0; + ch.u64 = 0; uint8_t rs = 0; uint8_t of = 0; uint8_t base = 0; @@ -359,21 +359,15 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { if ((k == DIR_ENDSTRUCT || k == DIR_ENDUNION)) { int skip = 0; if ((int)is_anon > 0) { - if ((cur_sym->up && !cur_sym->up->isanon) || (struct_sym && struct_sym->isanon)) { + if ((cur_sym && cur_sym->isanon) || (cur_sym->up && !cur_sym->up->isanon) || (struct_sym && struct_sym->isanon)) { is_anon--; + } else if ((int)is_struct <= 0) { + is_anon = 0; } skip = (!is_anon); } - if ((int)(is_struct-is_anon) > 0 && !skip && cur_sym->up) { - symbol *s = cur_sym; - for (; s->prev; s = s->prev) { - if (s->up == NULL && cur_sym->up) { - s->up = cur_sym->up; - } - if (dbg) { - printf("s: %p, s->up: %p, cur_sym->up: %p, last_loc: %p\n", s, s->up, cur_sym->up, last_loc); - } - } + if (((int)(is_struct-is_anon) > 0 && !skip) || ((int)is_anon <= 0 && (int)is_struct <= 0)) { + symbol *s; for (s = locals; s; s = s->next) { if (s->up == NULL) { s->up = cur_sym; @@ -385,11 +379,25 @@ uint64_t lex(char *str, uint64_t address, uint16_t bline, uint8_t dbg) { if (cur_sym->down == NULL) { cur_sym->down = locals; } - cur_sym = cur_sym->up; - for (struct_sym = locals->up; struct_sym->prev && !struct_sym->isanon; struct_sym = struct_sym->prev); + } + if (((int)is_anon <= 0 || (int)is_struct <= 0)) { + for (struct_sym = cur_sym; struct_sym->prev && !struct_sym->isanon; struct_sym = struct_sym->prev); + } + if ((int)(is_struct-is_anon) > 0 && !skip) { + symbol *s = cur_sym; + for (; s->prev; s = s->prev) { + if (s->up == NULL && cur_sym->up) { + s->up = cur_sym->up; + } + if (dbg) { + printf("s: %p, s->up: %p, cur_sym->up: %p, last_loc: %p\n", s, s->up, cur_sym->up, last_loc); + } + } + if (cur_sym->up) { + cur_sym = cur_sym->up; + } for (locals = locals->up; locals->prev; locals = locals->prev); for (last_loc = locals; last_loc->next; last_loc = last_loc->next); - } else if (!is_struct) { } } break; diff --git a/programs/sub-suite/declare.s b/programs/sub-suite/declare.s index cd97b60..183d09d 100644 --- a/programs/sub-suite/declare.s +++ b/programs/sub-suite/declare.s @@ -51,8 +51,12 @@ val .qword ; Value of symbol. - strct .byte ; Flag that says this symbol is a struct, or union. - def .byte ; Flag that says this symbol has been defined. + .union + strct .byte ; Bit 0: Struct/Union flag. + anon .byte ; Bit 1: Anonymous struct/union flag. + def .byte ; Bit 2: Defined symbol flag. + flags .byte ; Flags. + .endunion name .qword ; Name of symbol. id .word ; ID of symbol. @@ -301,19 +305,19 @@ t_sym: ; Current token. ctok: - .res 2 + .res 8 ; Last token. ltok: - .res 2 + .res 8 ; Current line. cline: - .res 2 + .res 8 ; Last line. lline: - .res 2 + .res 8 ; Lexeme type. lex_type: diff --git a/programs/sub-suite/lexer.s b/programs/sub-suite/lexer.s index 72f1db6..50bf21e 100644 --- a/programs/sub-suite/lexer.s +++ b/programs/sub-suite/lexer.s @@ -18,15 +18,15 @@ lex: ; jsr isdigit ; Is this character a digit? ; pla ; Get the character back. @getline: - lda #2 ; Get the third byte, of the line table address. - lsl #$10 ; Shift it by 2 bytes. ldb #1 ; Set the second pointer - lda.w lline ; to the last line. + lda.q lline ; to the last line. jsr set_ptr ; - lda.w (ptr2) ; Get the next line. + ldy #ln.next ; Set the index to the next line pointer. + lda.q (ptr2), y ; Get the next line. jsr set_ptr ; Set the second pointer to the next line. - sta.w cline ; Make it the current line. + sta.q cline ; Make it the current line. and #0 ; Reset A. + tay ; Reset Y. @loop: ldy.w idx0 ; Get the string index. lda (ptr), y ; Get a character from the line. diff --git a/sux.c b/sux.c index 2be2875..f1b07df 100644 --- a/sux.c +++ b/sux.c @@ -213,20 +213,7 @@ void *run(void *args) { #if keypoll pthread_mutex_lock(&mutex); #endif - for (uint8_t i = (24*thread)+2; i <= 24*(thread+1); i++) { - wmove(scr, i, 0); - waddch(scr, (i == lines) ? '>' : ' '); - } - wmove(scr, lines, 1); - wclrtoeol(scr); - wprintw(scr, "pc: $%04"PRIX64 , cpu->pc); - wprintw(scr, ", a: $%016"PRIX64, cpu->a); - wprintw(scr, ", b: $%016"PRIX64, cpu->b); - wprintw(scr, ", x: $%016"PRIX64, cpu->x); - wprintw(scr, ", y: $%016"PRIX64, cpu->y); - wprintw(scr, ", sp: $%04X", cpu->sp); - wprintw(scr, ", ps: $%02X", cpu->ps.u8[thread]); - wprintw(scr, ", inst: "); + print_regs(cpu, lines, thread); #if keypoll pthread_mutex_unlock(&mutex); #endif diff --git a/sux.h b/sux.h index 1f87be3..8dbc064 100644 --- a/sux.h +++ b/sux.h @@ -43,6 +43,7 @@ extern pthread_cond_t cond; extern pthread_cond_t main_cond; #if debug +extern void print_regs(struct sux *cpu, uint8_t lines, uint8_t thread); extern void disasm(struct sux *cpu, uint8_t lines, uint8_t opcode, uint8_t prefix, uint8_t thread); #endif diff --git a/test/subroutine.s b/test/subroutine.s index 122c34c..b7d8d17 100644 --- a/test/subroutine.s +++ b/test/subroutine.s @@ -1,45 +1,56 @@ -.org $2000 -buf: - -.org $0 +.org 0 +scr_ptr: + .res 2 ptr: -.qword $0 + .res 8 ptr2: -.qword $0 + .res 8 + +.org $2000 +buf: + .res $2000 .org $8000 reset: - cps - ldx.w #$FFFF - txs -start: - ldy #0 - ldb #0 - tyx - lda.w #buf - sta.q ptr - adc #8 - sta.q ptr2 - ;inb - ;stb $C010 - ;deb + cps ; Reset the processor status register. + ldx.w #$FFFF ; Reset the stack pointer. + txs ; @bench: - jsr clr_buf + tay ; Reset Y. + lda.w #$1FFF ; Set the clear count to $1FFF. + sta.w scr_ptr ; + lda.d #buf ; Set the array to be cleared to the screen buffer. + jsr clr_arr ; Clear the screen buffer. bra @bench -clr_buf: - tba ; Reset the Accumulator. - cpy.w #$1FFF ; Did we clear all of the screen buffer? +clr_arr: + phb ; Preserve whatever was in B. + ldb #0 ; Clear B. + sta.q ptr ; + adc #8 ; Set the second pointer to the parameter, plus eight. + sta.q ptr2 ; + tba ; +@loop: + cpy.w scr_ptr ; Did we clear all of the array? bcs @end ; Yes, so we're done. sta.q (ptr), y ; No, so clear eight bytes. sta.q (ptr2), y ; Clear eight more bytes. - tya ; Copy the buffer index. + tya ; Copy the array index. adc #$10 ; Increment the index by 16. tay ; Update the index. - bra clr_buf ; Keep looping. + tba ; Reset the Accumulator. + sta.q (ptr), y ; Do this one more time, to clear 32 bytes. + sta.q (ptr2), y ; + tya ; + adc #$10 ; + tay ; + tba ; + bra @loop ; Keep looping. @end: - tay ; Set the index back to zero. - rts ; End of clr_buf. + tay ; Reset A. + plb ; Get whatever was in the B register, back. + rts ; End of clr_arr. + ;.org $C010 ;.byte $1 -- cgit v1.2.3-13-gbd6f