From 9864995afb799046a72a13b4d28923b8a0b2615f Mon Sep 17 00:00:00 2001 From: Jesper Gravgaard Date: Sun, 19 May 2019 21:17:39 +0200 Subject: [PATCH] Created utoa10 with smaller memory footprint. --- ...pwuc1_derefidx_vbuxx_le_vwuz1_then_la1.asm | 8 + ...pwuc1_derefidx_vbuyy_le_vwuz1_then_la1.asm | 8 + ...vwuz1=vwuz1_minus_pwuc1_derefidx_vbuxx.asm | 7 + ...vwuz1=vwuz1_minus_pwuc1_derefidx_vbuyy.asm | 7 + src/main/fragment/vwuz1_le_vwuz2_then_la1.asm | 2 +- src/test/kc/hex2dec.kc | 82 ++++- src/test/ref/hex2dec.asm | 305 +++++++----------- 7 files changed, 208 insertions(+), 211 deletions(-) create mode 100644 src/main/fragment/pwuc1_derefidx_vbuxx_le_vwuz1_then_la1.asm create mode 100644 src/main/fragment/pwuc1_derefidx_vbuyy_le_vwuz1_then_la1.asm create mode 100644 src/main/fragment/vwuz1=vwuz1_minus_pwuc1_derefidx_vbuxx.asm create mode 100644 src/main/fragment/vwuz1=vwuz1_minus_pwuc1_derefidx_vbuyy.asm diff --git a/src/main/fragment/pwuc1_derefidx_vbuxx_le_vwuz1_then_la1.asm b/src/main/fragment/pwuc1_derefidx_vbuxx_le_vwuz1_then_la1.asm new file mode 100644 index 000000000..ef873ab36 --- /dev/null +++ b/src/main/fragment/pwuc1_derefidx_vbuxx_le_vwuz1_then_la1.asm @@ -0,0 +1,8 @@ +lda {c1}+1,x +cmp {z1}+1 +bne !+ +lda {c1},x +cmp {z1} +beq {la1} +!: +bcc {la1} diff --git a/src/main/fragment/pwuc1_derefidx_vbuyy_le_vwuz1_then_la1.asm b/src/main/fragment/pwuc1_derefidx_vbuyy_le_vwuz1_then_la1.asm new file mode 100644 index 000000000..427b691bd --- /dev/null +++ b/src/main/fragment/pwuc1_derefidx_vbuyy_le_vwuz1_then_la1.asm @@ -0,0 +1,8 @@ +lda {c1}+1,y +cmp {z1}+1 +bne !+ +lda {c1},y +cmp {z1} +beq {la1} +!: +bcc {la1} diff --git a/src/main/fragment/vwuz1=vwuz1_minus_pwuc1_derefidx_vbuxx.asm b/src/main/fragment/vwuz1=vwuz1_minus_pwuc1_derefidx_vbuxx.asm new file mode 100644 index 000000000..0b9a494d5 --- /dev/null +++ b/src/main/fragment/vwuz1=vwuz1_minus_pwuc1_derefidx_vbuxx.asm @@ -0,0 +1,7 @@ +sec +lda {z1} +sbc {c1},x +sta {z1} +lda {z1}+1 +sbc {c1}+1,x +sta {z1}+1 diff --git a/src/main/fragment/vwuz1=vwuz1_minus_pwuc1_derefidx_vbuyy.asm b/src/main/fragment/vwuz1=vwuz1_minus_pwuc1_derefidx_vbuyy.asm new file mode 100644 index 000000000..001c5e74d --- /dev/null +++ b/src/main/fragment/vwuz1=vwuz1_minus_pwuc1_derefidx_vbuyy.asm @@ -0,0 +1,7 @@ +sec +lda {z1} +sbc {c1},y +sta {z1} +lda {z1}+1 +sbc {c1}+1,y +sta {z1}+1 diff --git a/src/main/fragment/vwuz1_le_vwuz2_then_la1.asm b/src/main/fragment/vwuz1_le_vwuz2_then_la1.asm index 54a02388d..cc7e71a71 100644 --- a/src/main/fragment/vwuz1_le_vwuz2_then_la1.asm +++ b/src/main/fragment/vwuz1_le_vwuz2_then_la1.asm @@ -3,6 +3,6 @@ cmp {z2}+1 bne !+ lda {z1} cmp {z2} +beq {la1} !: bcc {la1} -beq {la1} \ No newline at end of file diff --git a/src/test/kc/hex2dec.kc b/src/test/kc/hex2dec.kc index d1d838356..f27a6e7d4 100644 --- a/src/test/kc/hex2dec.kc +++ b/src/test/kc/hex2dec.kc @@ -13,12 +13,19 @@ void main() { } while (rst!=0x30); unsigned char *screen = 0x0400; *bordercol = 1; - utoa(00000, screen); (*bordercol)++; screen += 40; - utoa(01234, screen); (*bordercol)++; screen += 40; - utoa(05678, screen); (*bordercol)++; screen += 40; - utoa(09999, screen); (*bordercol)++; screen += 40; - utoa(59999, screen); + unsigned char time_start = *raster; + utoa10b(00000, screen); (*bordercol)++; screen += 40; + utoa10b(01234, screen); (*bordercol)++; screen += 40; + utoa10b(05678, screen); (*bordercol)++; screen += 40; + utoa10b(09999, screen); (*bordercol)++; screen += 40; + utoa10b(58888, screen); + unsigned char time_end = *raster; *bordercol = 0; + unsigned char time = time_end - time_start; + utoa10b((unsigned int)time, screen+80); + byte[] msg = "raster lines"; + for( byte i=0; msg[i]!=0; i++ ) (screen+80+3)[i] = msg[i]; + //for( byte* m="lines", s=screen+80+6 ;*m!=0;m++,s++) *s = *m; } } @@ -28,29 +35,70 @@ void cls() { for( unsigned char *sc: screen..screen+999) *sc=' '; } -unsigned char[] DIGITS = "0123456789abcdef"; const unsigned char RADIX_BINARY = 2; const unsigned char RADIX_OCTAL = 8; const unsigned char RADIX_DECIMAL = 10; const unsigned char RADIX_HEX = 16; - - // simple 'utoa' without using multiply or divide -unsigned int append(unsigned char *dst, unsigned int value, unsigned int sub){ - *dst = '0'; +unsigned int utoa_digit(unsigned char *dst, unsigned int value, unsigned int sub){ + unsigned char digit = 0; unsigned int sub3 = sub*2+sub; - while (value >= sub3){ *dst += 3; value -= sub3; } - while (value >= sub){ ++*dst; value -= sub; } + while (value >= sub3){ digit += 3; value -= sub3; } + while (value >= sub){ ++digit; value -= sub; } + *dst = DIGITS[digit]; return value; } void utoa(unsigned int value, unsigned char *dst){ unsigned char bStarted = 0; - if (bStarted == 1 || value >= 10000){ value = append(dst++, value, 10000); bStarted = 1; } - if (bStarted == 1 || value >= 1000){ value = append(dst++, value, 1000); bStarted = 1; } - if (bStarted == 1 || value >= 100){ value = append(dst++, value, 100); bStarted = 1; } - if (bStarted == 1 || value >= 10){ value = append(dst++, value, 10); bStarted = 1; } + if (bStarted == 1 || value >= 10000){ value = utoa_digit(dst++, value, 10000); bStarted = 1; } + if (bStarted == 1 || value >= 1000){ value = utoa_digit(dst++, value, 1000); bStarted = 1; } + if (bStarted == 1 || value >= 100){ value = utoa_digit(dst++, value, 100); bStarted = 1; } + if (bStarted == 1 || value >= 10){ value = utoa_digit(dst++, value, 10); bStarted = 1; } *dst++ = '0' + (unsigned char) value; - *dst = 0; + //*dst = 0; } + +unsigned char[] DIGITS = "0123456789abcdef"; +unsigned int[] SUB3 = { 30000, 3000, 300, 30 }; +unsigned int[] SUB1 = { 10000, 1000, 100, 10 }; + +// Simple decimal utoa() without using multiply or divide +void utoa10(unsigned int value, unsigned char* dst) { + unsigned char bStarted = 0; + for( unsigned char i: 0..3) { + unsigned char digit = 0; + unsigned int sub1 = SUB1[i]; + if(value>=sub1) { + unsigned int sub3 = SUB3[i]; + while(value>=sub3) { digit += 3; value -= sub3; bStarted = 1; } + while(value>=sub1) { digit += 1; value -= sub1; bStarted = 1; } + } + if(bStarted!=0) { + *dst++ = DIGITS[digit]; + } + } + *dst++ = DIGITS[(unsigned char) value]; + //*dst = 0; +} + +unsigned int[] SUB = { 30000, 10000, 3000, 1000, 300, 100, 30, 10 }; +unsigned char[] VAL = { 3, 1, 3, 1, 3, 1, 3, 1 }; + +// Decimal utoa() without using multiply or divide +void utoa10b(unsigned int value, unsigned char* dst) { + unsigned char bStarted = 0; + unsigned char digit = 0; + for( unsigned char i: 0..7) { + while(value>=SUB[i]) { digit += VAL[i]; value -= SUB[i]; bStarted = 1; } + if((i&1)!=0) { + if(bStarted!=0) { + *dst++ = DIGITS[digit]; + } + digit = 0; + } + } + *dst++ = DIGITS[(unsigned char) value]; + *dst = 0; +} \ No newline at end of file diff --git a/src/test/ref/hex2dec.asm b/src/test/ref/hex2dec.asm index b080e5c44..4fbbca239 100644 --- a/src/test/ref/hex2dec.asm +++ b/src/test/ref/hex2dec.asm @@ -6,7 +6,8 @@ .label raster = $d012 .label bordercol = $d020 main: { - .label _1 = 8 + .label _1 = 4 + .label time_start = 8 sei jsr cls b1: @@ -20,112 +21,129 @@ main: { bne b1 lda #1 sta bordercol + lda raster + sta time_start lda #<$400 - sta utoa.dst + sta utoa10b.dst lda #>$400 - sta utoa.dst+1 + sta utoa10b.dst+1 lda #0 - sta utoa.value - sta utoa.value+1 - jsr utoa + sta utoa10b.value + sta utoa10b.value+1 + jsr utoa10b inc bordercol lda #<$400+$28 - sta utoa.dst + sta utoa10b.dst lda #>$400+$28 - sta utoa.dst+1 + sta utoa10b.dst+1 lda #<$4d2 - sta utoa.value + sta utoa10b.value lda #>$4d2 - sta utoa.value+1 - jsr utoa + sta utoa10b.value+1 + jsr utoa10b inc bordercol lda #<$400+$28+$28 - sta utoa.dst + sta utoa10b.dst lda #>$400+$28+$28 - sta utoa.dst+1 + sta utoa10b.dst+1 lda #<$162e - sta utoa.value + sta utoa10b.value lda #>$162e - sta utoa.value+1 - jsr utoa + sta utoa10b.value+1 + jsr utoa10b inc bordercol lda #<$400+$28+$28+$28 - sta utoa.dst + sta utoa10b.dst lda #>$400+$28+$28+$28 - sta utoa.dst+1 + sta utoa10b.dst+1 lda #<$270f - sta utoa.value + sta utoa10b.value lda #>$270f - sta utoa.value+1 - jsr utoa + sta utoa10b.value+1 + jsr utoa10b inc bordercol lda #<$400+$28+$28+$28+$28 - sta utoa.dst + sta utoa10b.dst lda #>$400+$28+$28+$28+$28 - sta utoa.dst+1 - lda #<$ea5f - sta utoa.value - lda #>$ea5f - sta utoa.value+1 - jsr utoa + sta utoa10b.dst+1 + lda #<$e608 + sta utoa10b.value + lda #>$e608 + sta utoa10b.value+1 + jsr utoa10b + ldx raster lda #0 sta bordercol - jmp b1 -} -// utoa(word zeropage(2) value, byte* zeropage(4) dst) -utoa: { - .label value = 2 - .label dst = 4 - lda value+1 - cmp #>$2710 - bcc !+ - beq !b5+ - jmp b5 - !b5: - lda value - cmp #<$2710 - bcc !b5+ - jmp b5 - !b5: - !: + txa + sec + sbc time_start + sta utoa10b.value + lda #0 + sta utoa10b.value+1 + lda #<$400+$28+$28+$28+$28+$50 + sta utoa10b.dst + lda #>$400+$28+$28+$28+$28+$50 + sta utoa10b.dst+1 + jsr utoa10b ldx #0 - b1: - cpx #1 - beq b6 - lda value+1 - cmp #>$3e8 - bcc !+ - bne b6 - lda value - cmp #<$3e8 - bcs b6 - !: - b2: - cpx #1 - beq b7 - lda value+1 - cmp #>$64 - bcc !+ - bne b7 - lda value - cmp #<$64 - bcs b7 - !: b3: - cpx #1 - beq b8 - lda value+1 - cmp #>$a - bcc !+ - bne b8 - lda value - cmp #<$a - bcs b8 + lda msg,x + sta $400+$28+$28+$28+$28+$50+3,x + inx + lda msg,x + cmp #0 + bne b3 + jmp b1 + msg: .text "raster lines@" +} +// Decimal utoa() without using multiply or divide +// utoa10b(word zeropage(2) value, byte* zeropage(6) dst) +utoa10b: { + .label value = 2 + .label digit = 4 + .label dst = 6 + .label bStarted = 5 + lda #0 + sta bStarted + sta digit + tax + b1: + txa + asl + tay + lda SUB+1,y + cmp value+1 + bne !+ + lda SUB,y + cmp value + beq b2 !: - b4: + bcc b2 + txa + and #1 + cmp #0 + beq b6 + lda bStarted + cmp #0 + beq b7 + ldy digit + lda DIGITS,y + ldy #0 + sta (dst),y + inc dst + bne !+ + inc dst+1 + !: + b7: + lda #0 + sta digit + b6: + inx + cpx #8 + bne b1 lda value - clc - adc #'0' + tay + lda DIGITS,y ldy #0 sta (dst),y inc dst @@ -136,125 +154,23 @@ utoa: { tay sta (dst),y rts - b8: - lda #$a - sta append.sub - lda #0 - sta append.sub+1 - jsr append - inc dst - bne !+ - inc dst+1 - !: - jmp b4 - b7: - lda #$64 - sta append.sub - lda #0 - sta append.sub+1 - jsr append - inc dst - bne !+ - inc dst+1 - !: - ldx #1 - jmp b3 - b6: - lda #<$3e8 - sta append.sub - lda #>$3e8 - sta append.sub+1 - jsr append - inc dst - bne !+ - inc dst+1 - !: - ldx #1 - jmp b2 - b5: - lda #<$2710 - sta append.sub - lda #>$2710 - sta append.sub+1 - jsr append - inc dst - bne !+ - inc dst+1 - !: - ldx #1 - jmp b1 -} -// simple 'utoa' without using multiply or divide -// append(byte* zeropage(4) dst, word zeropage(2) value, word zeropage(6) sub) -append: { - .label _0 = 9 - .label sub3 = 9 - .label value = 2 - .label dst = 4 - .label return = 2 - .label sub = 6 - lda #'0' - ldy #0 - sta (dst),y - lda sub - asl - sta _0 - lda sub+1 - rol - sta _0+1 - lda sub3 - clc - adc sub - sta sub3 - lda sub3+1 - adc sub+1 - sta sub3+1 - b1: - lda sub3+1 - cmp value+1 - bne !+ - lda sub3 - cmp value - !: - bcc b2 - beq b2 - b3: - lda sub+1 - cmp value+1 - bne !+ - lda sub - cmp value - !: - bcc b4 - beq b4 - rts - b4: - ldy #0 - lda (dst),y - clc - adc #1 - sta (dst),y - lda value - sec - sbc sub - sta value - lda value+1 - sbc sub+1 - sta value+1 - jmp b3 b2: - lda #3 + lda VAL,x clc - ldy #0 - adc (dst),y - sta (dst),y - lda value + adc digit + sta digit + txa + asl + tay sec - sbc sub3 + lda value + sbc SUB,y sta value lda value+1 - sbc sub3+1 + sbc SUB+1,y sta value+1 + lda #1 + sta bStarted jmp b1 } cls: { @@ -280,3 +196,6 @@ cls: { bne b1 rts } + DIGITS: .text "0123456789abcdef@" + SUB: .word $7530, $2710, $bb8, $3e8, $12c, $64, $1e, $a + VAL: .byte 3, 1, 3, 1, 3, 1, 3, 1