diff options
-rw-r--r-- | asmmon.c | 4 | ||||
-rw-r--r-- | programs/subasm.s | 3 | ||||
-rw-r--r-- | sux.c | 128 | ||||
-rw-r--r-- | test/input.s | 230 |
4 files changed, 287 insertions, 78 deletions
@@ -207,9 +207,9 @@ int asmmon(const char *fn) { SETOP(78, "IAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3); SETOP(79, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC4); SETOP(80, "IAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xC5); - SETOP(81, "DEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1); + SETOP(81, "DEC", 0x00, 0xF3, 0x00, 0x00, 0xF1, 0xD1); SETOP(82, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2); - SETOP(83, "DAY", 0x00, 0xF3, 0x00, 0x00, 0xF1, 0xD3); + SETOP(83, "DAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD3); SETOP(84, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD4); SETOP(85, "DAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD5); SETOP(86, "WAI", 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8); diff --git a/programs/subasm.s b/programs/subasm.s index fe02794..46effce 100644 --- a/programs/subasm.s +++ b/programs/subasm.s @@ -84,6 +84,9 @@ print_num: getline: lda #$A sta scr ; Print newline + inc scr_row + lda #$0 + sta scr_col inc y jsr rset_x jmp read @@ -1,11 +1,12 @@ #include "opcode.h" #include <assert.h> #include <curses.h> +#include <ctype.h> #include <string.h> #include <pthread.h> #define bench 0 -#define debug 1 -#define IO 0 +#define debug 0 +#define IO 1 #define keypoll 0 #if bench #include <sys/time.h> @@ -55,6 +56,8 @@ void *run(void *args) { uint64_t sign = 0; char *s = malloc(2048); uint8_t lines = (6*thread)+2; + uint8_t bcd[4]; + uint8_t idx = 3, iscol = 0; uint16_t tv = 0xFF50; /* Starting address of the Thread Vectors. */ int x = 0, y = 0; uint8_t esc = 0; @@ -97,9 +100,9 @@ void *run(void *args) { #if keypoll pthread_mutex_lock(&mutex); #endif - mvwprintw(scr, lines, 0, "pc: 0x%08llx, a: 0x%016llx, x: 0x%016llx, y: 0x%016llx" - ", sp: 0x%04lx, ps: 0x%016llx, prefix: 0x%02x, opcode: 0x%02x, thread: %u, inst: %s \r" - , cpu->pc[thread], cpu->a[thread], cpu->x[thread], cpu->y[thread] + mvwprintw(scr, lines, 0, "pc: $%08llx, a: $%016llx, b: $%016llx, x: $%016llx, y: $%016llx" + ", sp: $%04lx, ps: $%016llx, prefix: $%02x, opcode: $%02x, thread: %u, inst: %s \r" + , cpu->pc[thread], cpu->a[thread], cpu->b[thread], cpu->x[thread], cpu->y[thread] , cpu->sp[thread], cpu->ps, prefix, opcode, thread, opname[opcode]); wrefresh(scr); #if keypoll @@ -799,6 +802,38 @@ void *run(void *args) { wmove(scr, y, x); esc = 0; break; + case 'H': + if (!bcd[2] && !bcd[3]) + y = 0; + else + y = ((bcd[3]*10) + bcd[2]); + if (!bcd[0] && !bcd[1]) + x = 0; + else + x = ((bcd[1]*10) + bcd[0]); + idx = 3; + wmove(scr, y, x); + bcd[0] = 0; + bcd[1] = 0; + bcd[2] = 0; + bcd[3] = 0; + esc = 0; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + bcd[idx--] = (addr[address] - '0'); + break; + default: + iscol = (addr[address] == ';'); + break; } } else { if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') { @@ -826,6 +861,78 @@ void *run(void *args) { pthread_mutex_unlock(&mutex); #endif } + #else + if (address == TX_ADDR) { + if (esc) { + switch(addr[address]) { + case 'A': + if (y > 0) + y--; + esc = 0; + break; + case 'B': + if (y < getmaxy(scr)) + y++; + esc = 0; + break; + case 'C': + if (x < getmaxx(scr)) + x++; + esc = 0; + break; + case 'D': + if (x > 0) + x--; + esc = 0; + break; + case 'H': + if (!bcd[2] && !bcd[3]) + y = 0; + else + y = ((bcd[3]*10) + bcd[2]); + if (!bcd[0] && !bcd[1]) + x = 0; + else + x = ((bcd[1]*10) + bcd[0]); + idx = 3; + bcd[0] = 0; + bcd[1] = 0; + bcd[2] = 0; + bcd[3] = 0; + esc = 0; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + bcd[idx--] = (addr[address] - '0'); + break; + default: + iscol = (addr[address] == ';'); + break; + } else { + if (addr[address] == CURSES_BACKSPACE || addr[address] == '\b') { + if (x > 0) { + x--; + } + } else if (addr[address] == '\033') { + esc = 1; + } else { + if (addr[address] == '\n') { + x = 0; + y+=1; + } else { + x+=1; + } + } + } + } #endif if (regsize >= 2) addr[address+1] = value >> 8; @@ -1444,7 +1551,7 @@ void *run(void *args) { break; case 0xF1: /* DEC Absolute. */ case 0xF3: /* DEC Zero Matrix. */ - if (opcode == 0xE1) { + if (opcode == 0xF1) { address = (uint64_t)addr[cpu->pc[thread]] | (uint64_t)addr[cpu->pc[thread]+1] << 8 | (uint64_t)addr[cpu->pc[thread]+2] << 16 @@ -1456,7 +1563,7 @@ void *run(void *args) { cpu->pc[thread]+=8; iclk++; } - if (opcode == 0xE3) { + if (opcode == 0xF3) { address = addr[cpu->pc[thread]] | addr[cpu->pc[thread]+1] << 8 | addr[cpu->pc[thread]+2] << 16 @@ -1504,7 +1611,12 @@ void *run(void *args) { #if keypoll pthread_mutex_lock(&mutex); #endif - mvwprintw(scr, getmaxy(scr)-lines, 0, "Operand: $%llx", address); + mvwprintw(scr, getmaxy(scr)-lines, 0, "Operand: $%llx" + ", $%04llx: $%02x, $%04llx: $%02x" + ", $1000: $%02x, $1001: $%02x " + , value + , RX_ADDR, addr[RX_ADDR], TX_ADDR, addr[TX_ADDR] + , addr[0x1000], addr[0x1001]); mvwprintw(scr, (24*thread)+1, 0, "Instructions executed: %llu, Clock cycles: %llu\r", ins, iclk); wrefresh(scr); #if keypoll diff --git a/test/input.s b/test/input.s index 95b4077..169372f 100644 --- a/test/input.s +++ b/test/input.s @@ -6,23 +6,27 @@ ; Initalize some variables. .org $1000 -string: - .byte "Please, type something.\n" -string2: - .byte "You typed, " -end: - .byte $0 scr_row: - .word $0 + .byte $0 scr_col: - .word $0 + .byte $0 a: .word $0 b: .word $0 +c: + .word $0 +d: + .word $0 +string: + .byte "Please, type something.\n" +string2: + .byte "You typed, " +end: + .byte $0 ; Input buffer. -.org $2000 +.org $0000 buffer: ; Main program @@ -42,7 +46,7 @@ clr_buf: start: ldx.w #$0 ; Reset x. - ldy #$0 ; Reset y. + ldy.w #$0 ; Reset y. jmp print rset_a: @@ -66,6 +70,14 @@ print: beq rset_a ; Did we find a null terminator? sta $C001 ; Print character. inx ; Increment offset. + cmp #$A + beq inc_row + inc scr_col + jmp print +inc_row: + inc scr_row + lda #$0 + sta scr_col jmp print ; Keep printing more characters. getchar: @@ -79,98 +91,157 @@ getchar: cmp #$7F beq bs ; Did the user type a backspace? echo: + sta a + ldx scr_col + cpx #$79 + bne echo_print +linewrap: + inc scr_row + ldx #$0 + stx scr_col + jsr update_pos +echo_print: + lda a sta $C001 ; Echo typed character. + inc scr_col ; Increment the cursor's x coordinate. sta buffer, y ; Store typed character into the input buffer. - iny ; Increment buffer offset. - jmp rset_a ; We are not, so add the backspace to the buffer. + iny ; Increment the buffer offset. + jmp rset_a ; Start getting user input. 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. + beq read ; We have an error, so discard it, and go back to getting user input. lda $C002 ; Get the escape code. - cmp #$41 ; Did the user press the up arrow? + sta c ; Store the escape code, until we need it. + jsr isup ; Check if the user pressed up. + lda d + cmp #$0 + bne esc_end + jsr isdown ; Check if the user pressed down. + lda d + cmp #$0 + bne esc_end + lda #$0 + jsr isleft ; Check if the user pressed left. + lda d + cmp #$0 + bne esc_end + jsr isright ; Check if the user pressed right. +esc_end: + lda #$0 + sta d + jmp rset_a ; Go back to getting user input. + +isup: + lda scr_row ; Is the cursor at the top of the screen? + beq isup_done ; Yes, so return. + lda c ; No, so load the escape code back into the accumulator. + cmp #$41 ; Did the user press the up arrow key? beq up ; Yes, so move the cursor up. - cmp #$42 ; Did the user press the down arrow? +isup_done: + rts ; End of isup. + +isdown: + lda scr_row ; Start checking the y coordinate of the cursor. + cmp #$17 ; Is the cursor at the bottom of the screen? + beq isdown_done ; Yes, so return. + lda c ; No, so load the escape code back into the accumulator. + cmp #$42 ; Did the user press the down arrow key? beq down ; Yes, so move the cursor down. - cmp #$43 ; Did the user press the right arrow? +isdown_done: + rts ; End of isdown. + +isright: + lda scr_col ; Start checking the x coordinate of the cursor. + cmp #$4F ; Is the cursor at the far right of the screen? + beq isright_end ; Yes, so return. + lda c ; No, so load the escape code back into the accumulator. + cmp #$43 ; Did the user press the right arrow key? beq right ; Yes, so move the cursor right. - cmp #$44 ; Did the user press the left arrow? +isright_end: + rts ; End of isright. + +isleft: + lda scr_col ; Is the cursor at the far left of the screen? + beq isleft_done ; Yes, so return. + lda c ; No, so load the escape code back into the accumulator. + cmp #$44 ; Did the user press the left arrow key? beq left ; Yes, so move the cursor left. +isleft_done: + rts ; End of isleft. + up: - lda scr_row - beq rset_a dec scr_row jsr update_pos - lda #$1B - sta $C001 - lda #$5B - sta $C001 - lda #$41 - sta $C001 - jmp rset_a + lda #$1 + sta d + jmp isup_done down: inc scr_row jsr update_pos - lda #$1B - sta $C001 - lda #$5B - sta $C001 - lda #$42 - sta $C001 - jmp rset_a + lda #$1 + sta d + jmp isdown_done right: - lda scr_col - cmp #$50 - beq rset_a inc scr_col jsr update_pos - lda #$1B - sta $C001 - lda #$5B - sta $C001 - lda #$43 - sta $C001 - jmp rset_a + jmp isright_end left: - lda scr_col - beq rset_a dec scr_col jsr update_pos - lda #$1B - sta $C001 - lda #$5B - sta $C001 - lda #$44 - sta $C001 - jmp rset_a + lda #$1 + sta d + jmp isleft_done update_pos: - lda #$1B - sta $C001 - lda #$5B - sta $C001 - lda scr_row - jsr uint_to_bcd - jmp spin + lda #$1B ; Print an escape character + sta $C001 ; to the screen. + lda #$5B ; Print '[' + sta $C001 ; to the screen, and start the escape sequence. + jsr getrow ; Start printing the row number to the screen. + jsr getcol ; Start printing the column number to the screen. + lda #$48 ; Print 'H' + sta $C001 ; to the screen. + rts ; End of update_pos. +getrow: + lda scr_row ; Get the cursor's y coordinate. + div #$A ; Divide A by 10. + adc #$30 ; Convert it to ascii, and + sta $C001 ; print to the screen. + tba ; Get the remainder. + adc #$30 ; Convert it to ascii, and + sta $C001 ; print to the screen. + rts ; End of getrow. +getcol: + lda #$3B ; Print ';' + sta $C001 ; to the screen. + lda scr_col ; Get the cursor's x coordinate. + div #$A ; Divide A by 10. + adc #$30 ; Convert it to ascii, and + sta $C001 ; print to the screen. + tba ; Get the remainder. + adc #$30 ; Convert it to ascii, and + sta $C001 ; print to the screen. + rts ; End of getrow. uint_to_bcd: - div #$A - lsl #$4 - sta a - tba - sta b - lda a - ora b - rts + div #$A ; Divide A by 10. + lsl #$4 ; Shift the result left by 4 bits. + sta a ; Store the result for later. + tba ; Get the remainder. + sta b ; Store the remainder for later. + lda a ; Get the result. + ora b ; Or the result, with the remainder. + rts ; We've converted the value to BCD, so return. nl: lda #$A sta $C001 inc scr_row - jsr update_pos lda #$0 ; Replace newline with a null terminator. sta buffer, y ; Store said terminator into the input buffer. + sta scr_col ldy.w #$0 ; Reset y, to print the result. jmp result @@ -179,6 +250,7 @@ back: lda #$0 ; Put a null terminator, in place of the backspace. sta buffer, y ; Place it into the input buffer. dey ; Decrement buffer offset. + dec scr_col jmp read ; Get next character. bs: @@ -187,9 +259,19 @@ bs: jmp back ; We are not, so add the backspace to the buffer. result: + ldx scr_col + cpx #$79 + bne result_print +linewrap: + inc scr_row + ldx #$0 + stx scr_col + jsr update_pos +result_print: lda string2, y beq rset_y ; Reset y, if we hit the null terminator. sta $C001 ; Print 'You have typed, ' + inc scr_col ; Increment the cursor's x coordinate. iny ; Increment offset. jmp result ; Keep printing. @@ -199,9 +281,19 @@ rset_y: jmp print_buf ; Print the input buffer. print_buf: + ldx scr_col + cpx #$79 + bne buf_print +linewrap: + inc scr_row + ldx #$0 + stx scr_col + jsr update_pos +buf_print: lda buffer, y ; Get a character from the input buffer. beq spin ; Are we done with printing the buffer? sta $C001 ; Print said character. + inc scr_col ; Increment the cursor's x coordinate. iny jmp print_buf ; Keep printing the buffer. @@ -229,6 +321,8 @@ spin: viewmem .org $8100 viewmem +.org $8200 +viewmem ;q done |