; 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