diff options
Diffstat (limited to 'src/edboxutl.s')
| -rw-r--r-- | src/edboxutl.s | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/src/edboxutl.s b/src/edboxutl.s new file mode 100644 index 0000000..dc89798 --- /dev/null +++ b/src/edboxutl.s @@ -0,0 +1,203 @@ +; asm rewrites of functions originally written in C, for edbox.c. +; old C code here as comments, for reference. + + .export _edbox_addchr, _edbox_space, _edbox_set, _edbox_clear + .export _hide_cursor, _show_cursor, _storechr + .export _copy_to_old, _restore_old, _backspace, _inschr + .import _edbox_len, _edbox_pos, _old_edbox, _old_len, _typeover + .import _del_char, _bell, _move_right + .importzp ptr1 + + ; EDBOX_SIZE + 1, see edbox.h + EDBOX_SIZE_PLUS_1 = $f1 + EDBOX_SIZE = $f0 + EDBOX_MAXPOS = $ef + + EDBOX_ADDR = $0600 ; MUST agree with EDBOX_ADDR from addrs.h! + +; this compiled to like 31 bytes of code... +; this version is 7 bytes. +;; void storechr(char c) { +;; edit_box[edbox_pos] = c; +;; } +_storechr: + ldx _edbox_pos + sta EDBOX_ADDR,x + rts + +;; void hide_cursor(void) { +;; edit_box[edbox_pos] &= 0x7f; +;; } +_hide_cursor: + ldx _edbox_pos + lda EDBOX_ADDR,x + and #$7f +store_curs: + sta EDBOX_ADDR,x + rts + +;; void show_cursor(void) { +;; edit_box[edbox_pos] |= 0x80; +;; } +_show_cursor: + ldx _edbox_pos + lda EDBOX_ADDR,x + ora #$80 + bne store_curs + +;; static void copy_to_old(void) { +;; if(!edbox_len) return; +;; memcpy(old_edbox, edit_box, edbox_len); +;; bzero(old_edbox + edbox_len, EDBOX_MAXPOS - edbox_len); +;; old_len = edbox_len; +;; } +_copy_to_old: + lda _edbox_len + beq nope + ldx #0 +@l: + lda EDBOX_ADDR,x + sta _old_edbox,x + inx + cpx #EDBOX_SIZE + bne @l + lda _edbox_len + sta _old_len +nope: + rts + +;; static void restore_old(void) { +;; edbox_clear(); +;; hide_cursor(); +;; memcpy(edit_box, old_edbox, old_len); +;; edbox_pos = edbox_len = old_len; +;; } +_restore_old: + lda _old_len + beq nope + ldx #0 +@l: + lda _old_edbox,x + sta EDBOX_ADDR,x + inx + cpx #EDBOX_SIZE + bne @l + lda _old_len + sta _edbox_len + sta _edbox_pos + rts + +;; static void backspace(void) { +;; if(!edbox_pos) return; +;; edbox_pos--; +;; if(typeover) +;; edit_box[edbox_pos] = ' '; +;; else +;; del_char(); +;; } +_backspace: + lda _edbox_pos + beq @nope + dec _edbox_pos + lda _typeover + bne @spc + jmp _del_char +@spc: + lda #$20 + ldx _edbox_pos + sta EDBOX_ADDR,x +@nope: + rts + +;; void inschr(char c) { +;; if(edbox_len == EDBOX_MAXPOS) { +;; /* buffer full, can't insert */ +;; bell(); +;; return; +;; } +;; move_right(); +;; edbox_len++; +;; storechr(c); +;; edbox_pos++; +;; } +_inschr: + pha + lda _edbox_len + cmp #EDBOX_MAXPOS + bne @ok + pla + jmp _bell +@ok: + jsr _move_right + inc _edbox_len + pla + jsr _storechr + inc _edbox_pos + rts + +;; void edbox_clear(void) { +;; bzero(edit_box, EDBOX_SIZE + 1); +;; edbox_pos = edbox_len = 0; +;; show_cursor(); // not needed? seems it is.. +;; } + +_edbox_clear: + ldx #0 + txa +@l: + sta EDBOX_ADDR,x + inx + cpx #EDBOX_SIZE_PLUS_1 + bne @l + sta _edbox_pos + sta _edbox_len + jmp _show_cursor + +;; void edbox_space(void) { +;; edbox_addchr(' '); +;; } +_edbox_space: + lda #$20 + ; fall thru... + +;; void edbox_addchr(char c) { +;; edit_box[edbox_len++] = c; +;; edbox_pos = edbox_len; +;; } + +_edbox_addchr: + ldx _edbox_len + sta EDBOX_ADDR,x + inx + stx _edbox_len + stx _edbox_pos + rts + +;; void edbox_set(char *contents) { +;; edbox_clear(); +;; while(*contents) { +;; edit_box[edbox_len++] = *contents++; +;; } +;; edbox_pos = edbox_len; +;; } + +; notice the asm version does bounds checking, which the C version +; didn't do. +_edbox_set: + sta ptr1 + stx ptr1+1 + jsr _edbox_clear + ldy #0 +@l: + lda (ptr1),y + sta EDBOX_ADDR,y + beq @done ; if we hit a 0 byte in the input, we're done + inx + iny + cpy #EDBOX_SIZE_PLUS_1 ; if we hit the edbox size limit, we're done + bne @l + dey +@done: + sty _edbox_len + sty _edbox_pos + rts |
