summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asmmon.h7
-rw-r--r--assemble.c6
-rw-r--r--disasm.c17
-rw-r--r--lexer.c38
-rw-r--r--programs/sub-suite/declare.s16
-rw-r--r--programs/sub-suite/lexer.s10
-rw-r--r--sux.c15
-rw-r--r--sux.h1
-rw-r--r--test/subroutine.s67
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 <string.h>
+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