aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/edboxutl.s203
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