diff options
-rw-r--r-- | programs/subasm.s | 239 | ||||
-rw-r--r-- | sux.c | 84 | ||||
-rw-r--r-- | test/input.s | 92 |
3 files changed, 367 insertions, 48 deletions
diff --git a/programs/subasm.s b/programs/subasm.s new file mode 100644 index 0000000..fe02794 --- /dev/null +++ b/programs/subasm.s @@ -0,0 +1,239 @@ +; SuBAsm +; The Sux Bootstrapped Assembler. +; +; by mr b0nk 500 <b0nk@b0nk.xyz> + +; Variables +.org $1000 +prg_name: + .byte "SuBAsm" +ver_txt: + .byte ", version " +ver_num: + .byte "0.1" +x: + .word $0 +y: + .word $0 + +str_buf: + +; Input buffer. +.org $2000 +buf: + +; Control Register. +.org $C000 +ctrl_reg: + +; Screen. +.org $C001 +scr: + +; Keyboard. +.org $C002 +kbd: + +; Main program. +.org $0 +reset: + cps + ldx.w #$FFFF + txs + ldy #$0 + jsr clr_buf + ldx.w #$0 ; Reset x. + ldy #$0 ; Reset y. + jmp print_title + +read: + lda ctrl_reg ; Is the keyboard ready? + beq read ; Loop until the keyboard is ready. + lda #$0 ; Start resetting the control register. + sta ctrl_reg ; Reset the control register. + jmp getchar ; We got a key. + +rset_x: + + ldx #$0 ; Reset x. + stx.w x + rts + +print_title: + lda prg_name, x + beq print_ver ; Did we find a null terminator? + sta ; Print character. + inx ; Increment offset. + inc x + jmp print_title ; Keep printing more characters. + +print_ver + jsr rset_x + lda ver_txt, x + beq print_num ; Did we find a null terminator? + sta scr ; Print character. + inx ; Increment offset. + jmp print_ver ; Keep printing more characters. + +print_num: + lda ver_num, x + beq getline ; Did we find a null terminator? + sta scr ; Print character. + inx ; Increment offset. + jmp print_num ; Keep printing more characters. +getline: + lda #$A + sta scr ; Print newline + inc y + jsr rset_x + jmp read + +getchar: + lda kbd ; Get typed character. + cmp #$1B ; Did the user type an escape? + beq esc ; Yes, so start getting the escape code. + cmp #$A ; Did the user type a newline? + beq nl ; Yes, so start parsing the input. + cmp #$8 ; Did the user type a backspace? + beq bs ; Yes, so start checking the buffer. + jsr echo ; Print character to screen. + +store_char: + sta buf, y ; Store typed character into the input buffer. + iny ; Increment buffer offset. + jmp read ; Get another character. + +esc: + lda ctrl_reg ; Skip the '['. + lda ctrl_reg ; Get the next character. + beq read ; We have an error, so discard it, and read the next character. + lda kbd ; Get the escape code. + cmp #$41 ; Did the user press the up arrow? + beq up ; Yes, so move the cursor up. + cmp #$42 ; Did the user press the down arrow? + beq down ; Yes, so move the cursor down. + cmp #$43 ; Did the user press the left arrow? + beq left ; Yes, so move the cursor left. + cmp #$44 ; Did the user press the right arrow? + beq right ; Yes, so move the cursor right. + +up: + lda #$1B + sta scr + lda #$5B + sta scr + lda #$41 + sta scr + jmp read +down: + lda #$1B + sta scr + lda #$5B + sta scr + lda #$42 + sta scr + jmp read +left: + lda #$1B + sta scr + lda #$5B + sta scr + lda #$43 + sta scr + jmp read +right: + lda #$1B + sta scr + lda #$5B + sta scr + lda #$44 + sta scr + jmp read + + + +nl: + sta scr ; Print newline. + lda #$0 ; Put a null terminator, in place of the newline. + sta buf, y ; Place it into the input buffer. + ldy.w #$0 ; Reset y, to parse the input. + jmp parse + +back: + jsr echo ; Print backspace. + lda #$0 ; Put a null terminator, in place of the backspace. + sta buf, y ; Place it into the input buffer. + dey ; Decrement buffer offset. + jmp read ; Get next character. + +bs: + cpy #$0 ; Are we at the start of the buffer? + beq read ; We are, so do not store the backspace into the buffer. + jmp back ; We are not, so add the backspace to the buffer. + +parse: + lda buf, y + beq clr_buf ; Reset y, if we hit the null terminator. + sta scr ; Print 'You have typed, ' + iny ; Increment offset. + jmp result ; Keep printing. + +rset_y: + ldy.w #$0 + jmp print_buf ; Print the input buffer. + +print_buf: + lda buf, y ; Get a character from the input buffer. + beq fin ; Are we done with printing the buffer? + sta scr ; Print said character. + iny + jmp print_buf ; Keep printing the buffer. + +spin: + nop + nop + nop + jmp spin + +clr_buf: + lda #$0 + cpy.w #$1000 + beq clr_end + sta buf, y + iny + jmp clr_buf +clr_sbuf: + lda #$0 + cpy.w #$40 + beq clr_end + sta str_buf, y + iny + jmp clr_sbuf + +clr_end: + rts + +echo: + sta scr ; Echo typed character. + rts ; Return. + +.org $FFC0 +.qword reset + +.org $FF50 +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin +.qword spin + +.org $FFA0 +.qword irq_routine +;.org $0 +;viewmem +;.org $100 +;viewmem +;q +done @@ -44,7 +44,7 @@ void *run(void *args) { struct suxthr *thr = (void *)args; struct sux *cpu = &thr->sx; uint8_t thread = thr->th; - uint64_t address; + uint64_t address = 0; uint8_t prefix = 0; uint8_t opcode = 0; uint8_t end = 0; @@ -57,10 +57,12 @@ void *run(void *args) { uint8_t lines = (6*thread)+2; uint16_t tv = 0xFF50; /* Starting address of the Thread Vectors. */ int x = 0, y = 0; + uint8_t esc = 0; #if bench gettimeofday(&str[thread], 0); #endif while (!end) { + address = 0; if (wai) { for (int8_t i = 56; i >= 0; i-=8) { if (i) @@ -91,7 +93,7 @@ void *run(void *args) { prefix = 0; opcode = addr[cpu->pc[thread]]; - #if debug && !bench && keypoll + #if debug && !bench #if keypoll pthread_mutex_lock(&mutex); #endif @@ -762,22 +764,53 @@ void *run(void *args) { #if keypoll pthread_mutex_lock(&mutex); #endif - if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') { - if (x > 0) { - x--; - wmove(scr, y, x); + if (esc) { + switch(addr[address]) { + case 'A': + if (y > 0) + y--; + wmove(scr, y, x); + esc = 0; + break; + case 'B': + if (y < getmaxy(scr)) + y++; + wmove(scr, y, x); + esc = 0; + break; + case 'C': + if (x < getmaxx(scr)) + x++; + wmove(scr, y, x); + esc = 0; + break; + case 'D': + if (x > 0) + x--; + wmove(scr, y, x); + esc = 0; + break; } - wdelch(scr); - wrefresh(scr); } else { - wmove(scr, y, x); - waddch(scr, addr[address]); - wrefresh(scr); - if (addr[address] == '\n') { - x = 0; - y+=1; + if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') { + if (x > 0) { + x--; + wmove(scr, y, x); + } + wdelch(scr); + wrefresh(scr); + } else if (addr[address] == '\033') { + esc = 1; } else { - x+=1; + wmove(scr, y, x); + waddch(scr, addr[address]); + wrefresh(scr); + if (addr[address] == '\n') { + x = 0; + y+=1; + } else { + x+=1; + } } } #if keypoll @@ -1296,6 +1329,8 @@ void *run(void *args) { cpu->a[thread]+=1; cpu->z[thread] = (cpu->a[thread] == 0); cpu->n[thread] = (cpu->a[thread] >> 63); + (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); + (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); } if (opcode == INY || opcode == IAY) { cpu->y[thread]+=1; @@ -1307,8 +1342,6 @@ void *run(void *args) { cpu->z[thread] = (cpu->x[thread] == 0); cpu->n[thread] = (cpu->x[thread] >> 63); } - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); break; case 0xD0: /* JMP Zero Matrix. */ address = (uint32_t)addr[cpu->pc[thread]] @@ -1329,6 +1362,8 @@ void *run(void *args) { cpu->a[thread]-=1; cpu->z[thread] = (cpu->a[thread] == 0); cpu->n[thread] = (cpu->a[thread] >> 63); + (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); + (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); } if (opcode == DEY || opcode == DAY) { cpu->y[thread]-=1; @@ -1340,8 +1375,6 @@ void *run(void *args) { cpu->z[thread] = (cpu->x[thread] == 0); cpu->n[thread] = (cpu->x[thread] >> 63); } - (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread)); - (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread)); break; case JSL: /* Jump to Subroutine Long. */ address = (uint64_t)addr[cpu->pc[thread]] @@ -1457,10 +1490,11 @@ void *run(void *args) { break; } ins++; - #if debug && !bench && keypoll + #if debug && !bench #if keypoll pthread_mutex_lock(&mutex); #endif + mvwprintw(scr, getmaxy(scr)-lines, 0, "Operand: $%llx", address); mvwprintw(scr, (24*thread)+1, 0, "Instructions executed: %llu, Clock cycles: %llu\r", ins, iclk); wrefresh(scr); #if keypoll @@ -1507,7 +1541,7 @@ int main(int argc, char **argv) { crmode(); noecho(); nl(); - curs_set(0); + curs_set(1); werase(scr); scrollok(scr, 1); wrefresh(scr); @@ -1562,8 +1596,10 @@ int main(int argc, char **argv) { #if !bench if ((c != EOF && c !=-1)) { pthread_mutex_lock(&main_mutex); + curs_set(0); pthread_cond_wait(&main_cond, &main_mutex); pthread_mutex_unlock(&main_mutex); + curs_set(1); c = 0; addr[CTRL_ADDR] = 0; } @@ -1571,12 +1607,6 @@ int main(int argc, char **argv) { pthread_mutex_lock(&mutex); #endif getyx(scr, y, x); - attroff(A_REVERSE); - attron(A_BLINK); - wprintw(scr, "_"); - attroff(A_BLINK); - wmove(scr, y, x); - wrefresh(scr); c = wgetch(scr); switch (c) { case ERR: diff --git a/test/input.s b/test/input.s index b699dda..a2725f6 100644 --- a/test/input.s +++ b/test/input.s @@ -12,7 +12,10 @@ string2: .byte "You typed, " end: .byte $0 - +x: + .word $0 +tmp: + .word $0 ; Input buffer. .org $2000 buffer: @@ -26,7 +29,7 @@ reset: ldy #$0 clr_buf: lda #$0 - cpy.w #$400 + cpy.w #$1000 beq start sta buffer, y iny @@ -47,7 +50,6 @@ sleep: lda end bne spin ; Are we done with getting input? read: - nop ; Sleep until we get a character. lda $C000 ; Get control register. beq rset_a ; Loop until we get a character. lda #$0 @@ -63,17 +65,66 @@ print: getchar: lda $C002 ; Get typed character. + cmp #$1B + beq esc cmp #$A beq nl ; Did the user type a newline? cmp #$8 beq bs ; Did the user type a backspace? + cmp #$7F + beq bs ; Did the user type a backspace? echo: sta $C001 ; Echo typed character. sta buffer, y ; Store typed character into the input buffer. iny ; Increment buffer offset. - nop jmp rset_a ; We are not, so add the backspace to the buffer. +esc: + lda $C000 ; Skip the '['. + lda $C000 ; Get the next character. + beq read ; We have an error, so discard it, and read the next character. + lda $C002 ; Get the escape code. + cmp #$41 ; Did the user press the up arrow? + beq up ; Yes, so move the cursor up. + cmp #$42 ; Did the user press the down arrow? + beq down ; Yes, so move the cursor down. + cmp #$43 ; Did the user press the right arrow? + beq right ; Yes, so move the cursor right. + cmp #$44 ; Did the user press the left arrow? + beq left ; Yes, so move the cursor left. +up: + lda #$1B + sta $C001 + lda #$5B + sta $C001 + lda #$41 + sta $C001 + jmp rset_a +down: + lda #$1B + sta $C001 + lda #$5B + sta $C001 + lda #$42 + sta $C001 + jmp rset_a +right: + lda #$1B + sta $C001 + lda #$5B + sta $C001 + lda #$43 + sta $C001 + jmp rset_a +left: + lda #$1B + sta $C001 + lda #$5B + sta $C001 + lda #$44 + sta $C001 + jmp rset_a + nl: sta $C001 lda #$0 ; Replace newline with a null terminator. @@ -81,10 +132,17 @@ nl: ldy.w #$0 ; Reset y, to print the result. jmp result +back: + sta $C001 ; Print backspace. + lda #$0 ; Put a null terminator, in place of the backspace. + sta buffer, y ; Place it into the input buffer. + dey ; Decrement buffer offset. + jmp read ; Get next character. + bs: - cpy #$0 - beq return ; Are we at the start of the buffer? - jmp echo ; We are not, so add the backspace to the buffer. + cpy #$0 ; Are we at the start of the buffer? + beq rset_a ; We are, so do not store the backspace into the buffer. + jmp back ; We are not, so add the backspace to the buffer. result: lda string2, y @@ -93,25 +151,18 @@ result: iny ; Increment offset. jmp result ; Keep printing. + rset_y: ldy.w #$0 jmp print_buf ; Print the input buffer. print_buf: lda buffer, y ; Get a character from the input buffer. - beq fin ; Are we done with printing the buffer? + beq spin ; Are we done with printing the buffer? sta $C001 ; Print said character. iny jmp print_buf ; Keep printing the buffer. -fin: - lda #$A ; Load a newline. - sta $C001 ; Print the newline. - lda #$1 ; Tell the program that we are done. - sta end ; We are done. - jmp sleep - - spin: nop nop @@ -132,10 +183,9 @@ spin: .org $FFA0 .qword irq_routine -;.org $0 -;viewmem -;.org $100 -;viewmem +.org $8000 +viewmem +.org $8100 +viewmem ;q done - |