summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--programs/subasm.s239
-rw-r--r--sux.c84
-rw-r--r--test/input.s92
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
diff --git a/sux.c b/sux.c
index 3f31d4e..70b8a92 100644
--- a/sux.c
+++ b/sux.c
@@ -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
-