From aaa20093ef30ef4ba5412d2faa5676fce5f091cc Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 5 Nov 2020 22:27:50 +0100 Subject: [PATCH] cleaning up and correcting cc for builtin functions --- compiler/res/prog8lib/math.asm | 69 - compiler/res/prog8lib/prog8_funcs.asm | 1308 ++++++++++++++++- compiler/res/prog8lib/prog8_lib.asm | 1235 ---------------- .../c64/codegen/BuiltinFunctionsAsmGen.kt | 188 ++- docs/source/programming.rst | 3 + examples/test.p8 | 441 +++++- 6 files changed, 1784 insertions(+), 1460 deletions(-) diff --git a/compiler/res/prog8lib/math.asm b/compiler/res/prog8lib/math.asm index 392fb0156..a8d872169 100644 --- a/compiler/res/prog8lib/math.asm +++ b/compiler/res/prog8lib/math.asm @@ -1243,75 +1243,6 @@ mul_word_100 .proc ; ----------- end optimized multiplications ----------- -sign_ub_into_A .proc - cmp #0 - bne _pos - rts -_pos lda #1 - rts - .pend - -sign_ub_cc .proc - jsr sign_ub_into_A - sta P8ESTACK_LO,x - dex - rts - .pend - -sign_uw_into_A .proc - cpy #0 - beq _possibly_zero -_pos lda #1 - rts -_possibly_zero cmp #0 - bne _pos - rts - .pend - -sign_uw_cc .proc - jsr sign_uw_into_A - sta P8ESTACK_LO,x - dex - rts - .pend - -sign_b_into_A .proc - cmp #0 - beq _zero - bmi _neg - lda #1 -_zero rts -_neg lda #-1 - rts - .pend - -sign_b_cc .proc - jsr sign_b_into_A - sta P8ESTACK_LO,x - dex - rts - .pend - -sign_w_into_A .proc - cpy #0 - beq _possibly_zero - bmi _neg -_pos lda #1 - rts -_neg lda #-1 - rts -_possibly_zero cmp #0 - bne _pos - rts - .pend - - -sign_w_cc .proc - jsr sign_w_into_A - sta P8ESTACK_LO,x - dex - rts - .pend ; bit shifts. ; anything below 3 is done inline. anything above 7 is done via other optimizations. diff --git a/compiler/res/prog8lib/prog8_funcs.asm b/compiler/res/prog8lib/prog8_funcs.asm index ccd728384..2fd348992 100644 --- a/compiler/res/prog8lib/prog8_funcs.asm +++ b/compiler/res/prog8lib/prog8_funcs.asm @@ -3,14 +3,16 @@ func_any_b_stack .proc jsr func_any_b_into_A -_pushA sta P8ESTACK_LO,x + sta P8ESTACK_LO,x dex rts .pend func_all_b_stack .proc jsr func_all_b_into_A - jmp func_any_b_stack._pushA + sta P8ESTACK_LO,x + dex + rts .pend func_any_b_into_A .proc @@ -42,3 +44,1305 @@ _cmp_mod cpy #255 ; modified _got_not_all rts .pend +func_any_w_into_A .proc + asl a + jmp func_any_b_into_A + .pend + +func_any_w_stack .proc + asl a + jsr func_any_b_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +func_all_w_into_A .proc + ; -- all(warray), array in P8ZP_SCRATCH_W1, num bytes in A + asl a ; times 2 because of word + sta _cmp_mod+1 ; self-modifying code + ldy #0 +- lda (P8ZP_SCRATCH_W1),y + bne + + iny + lda (P8ZP_SCRATCH_W1),y + bne ++ + lda #0 + rts ++ iny ++ iny +_cmp_mod cpy #255 ; modified + bne - + lda #1 + rts + .pend + +func_all_w_stack .proc + jsr func_all_w_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +func_sin8_into_A .proc + tay + lda _sinecos8,y + rts +_sinecos8 .char trunc(127.0 * sin(range(256+64) * rad(360.0/256.0))) + .pend + +func_sin8u_into_A .proc + tay + lda _sinecos8u,y + rts +_sinecos8u .byte trunc(128.0 + 127.5 * sin(range(256+64) * rad(360.0/256.0))) + .pend + +func_sin8_stack .proc + tay + lda func_sin8_into_A._sinecos8,y + sta P8ESTACK_LO,x + dex + rts + .pend + +func_sin8u_stack .proc + tay + lda func_sin8u_into_A._sinecos8u,y + sta P8ESTACK_LO,x + dex + rts + .pend + +func_cos8_into_A .proc + tay + lda func_sin8_into_A._sinecos8+64,y + rts + .pend + +func_cos8u_into_A .proc + tay + lda func_sin8u_into_A._sinecos8u+64,y + rts + .pend + +func_cos8_stack .proc + tay + lda func_sin8_into_A._sinecos8+64,y + sta P8ESTACK_LO,x + dex + rts + .pend + +func_cos8u_stack .proc + tay + lda func_sin8u_into_A._sinecos8u+64,y + sta P8ESTACK_LO,x + dex + rts + .pend + +func_sin16_into_AY .proc + tay + lda _sinecos8lo,y + pha + lda _sinecos8hi,y + tay + pla + rts +_ := trunc(32767.0 * sin(range(256+64) * rad(360.0/256.0))) +_sinecos8lo .byte <_ +_sinecos8hi .byte >_ + .pend + +func_sin16u_into_AY .proc + tay + lda _sinecos8ulo,y + pha + lda _sinecos8uhi,y + tay + pla + rts +_ := trunc(32768.0 + 32767.5 * sin(range(256+64) * rad(360.0/256.0))) +_sinecos8ulo .byte <_ +_sinecos8uhi .byte >_ + .pend + + +func_sin16_stack .proc + tay + lda func_sin16_into_AY._sinecos8lo,y + sta P8ESTACK_LO,x + lda func_sin16_into_AY._sinecos8hi,y + sta P8ESTACK_HI,x + dex + rts + .pend + +func_sin16u_stack .proc + tay + lda func_sin16u_into_AY._sinecos8ulo,y + sta P8ESTACK_LO,x + lda func_sin16u_into_AY._sinecos8uhi,y + sta P8ESTACK_HI,x + dex + rts + .pend + +func_cos16_into_AY .proc + tay + lda func_sin16_into_AY._sinecos8lo+64,y + pha + lda func_sin16_into_AY._sinecos8hi+64,y + tay + pla + rts + .pend + +func_cos16u_into_AY .proc + tay + lda func_sin16u_into_AY._sinecos8ulo+64,y + pha + lda func_sin16u_into_AY._sinecos8uhi+64,y + tay + pla + rts + .pend + +func_cos16_stack .proc + tay + lda func_sin16_into_AY._sinecos8lo+64,y + sta P8ESTACK_LO,x + lda func_sin16_into_AY._sinecos8hi+64,y + sta P8ESTACK_HI,x + dex + rts + .pend + +func_cos16u_stack .proc + tay + lda func_sin16u_into_AY._sinecos8ulo+64,y + sta P8ESTACK_LO,x + lda func_sin16u_into_AY._sinecos8uhi+64,y + sta P8ESTACK_HI,x + dex + rts + .pend + +abs_b_stack .proc + ; -- push abs(A) on stack (as byte) + jsr abs_b_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +abs_b_into_A .proc + ; -- A = abs(A) + cmp #0 + bmi + + rts ++ eor #$ff + clc + adc #1 + rts + .pend + +abs_w_stack .proc + ; -- push abs(AY) on stack (as word) + jsr abs_w_into_AY + sta P8ESTACK_LO,x + tya + sta P8ESTACK_HI,x + dex + rts + .pend + +abs_w_into_AY .proc + ; -- AY = abs(AY) + cpy #0 + bmi + + rts ++ eor #$ff + pha + tya + eor #$ff + tay + pla + clc + adc #1 + bcc + + iny ++ rts + .pend + +func_sign_b_into_A .proc + cmp #0 + beq _zero + bmi _neg + lda #1 +_zero rts +_neg lda #-1 + rts + .pend + +func_sign_b_stack .proc + jsr func_sign_b_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +func_sign_ub_into_A .proc + cmp #0 + bne _pos + rts +_pos lda #1 + rts + .pend + +func_sign_ub_stack .proc + jsr func_sign_ub_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +func_sign_uw_into_A .proc + cpy #0 + beq _possibly_zero +_pos lda #1 + rts +_possibly_zero cmp #0 + bne _pos + rts + .pend + +func_sign_uw_stack .proc + jsr func_sign_uw_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +func_sign_w_into_A .proc + cpy #0 + beq _possibly_zero + bmi _neg +_pos lda #1 + rts +_neg lda #-1 + rts +_possibly_zero cmp #0 + bne _pos + rts + .pend + + +func_sign_w_stack .proc + jsr func_sign_w_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +func_sqrt16_stack .proc + jsr func_sqrt16_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +func_sqrt16_into_A .proc + ; integer square root from http://6502org.wikidot.com/software-math-sqrt + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + txa + pha + lda #0 + sta P8ZP_SCRATCH_B1 + sta P8ZP_SCRATCH_REG + ldx #8 +- sec + lda P8ZP_SCRATCH_W1+1 + sbc #$40 + tay + lda P8ZP_SCRATCH_REG + sbc P8ZP_SCRATCH_B1 + bcc + + sty P8ZP_SCRATCH_W1+1 + sta P8ZP_SCRATCH_REG ++ rol P8ZP_SCRATCH_B1 + asl P8ZP_SCRATCH_W1 + rol P8ZP_SCRATCH_W1+1 + rol P8ZP_SCRATCH_REG + asl P8ZP_SCRATCH_W1 + rol P8ZP_SCRATCH_W1+1 + rol P8ZP_SCRATCH_REG + dex + bne - + pla + tax + lda P8ZP_SCRATCH_B1 + rts + .pend + +func_rnd_stack .proc + ; -- put a random ubyte on the estack + jsr math.randbyte + sta P8ESTACK_LO,x + dex + rts + .pend + +func_rndw_stack .proc + ; -- put a random uword on the estack + jsr math.randword + sta P8ESTACK_LO,x + tya + sta P8ESTACK_HI,x + dex + rts + .pend + +func_min_ub_into_A .proc + ; -- min(ubarray) -> A. (array in P8ZP_SCRATCH_W1, num elements in A) + tay + dey + lda #255 + sta P8ZP_SCRATCH_B1 +- lda (P8ZP_SCRATCH_W1),y + cmp P8ZP_SCRATCH_B1 + bcs + + sta P8ZP_SCRATCH_B1 ++ dey + cpy #255 + bne - + lda P8ZP_SCRATCH_B1 + rts + .pend + +func_min_ub_stack .proc + jsr func_min_ub_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +func_min_b_into_A .proc + ; -- min(barray) -> A. (array in P8ZP_SCRATCH_W1, num elements in A) + tay + lda #127 + sta P8ZP_SCRATCH_B1 +- lda (P8ZP_SCRATCH_W1),y + clc + sbc P8ZP_SCRATCH_B1 + bvc + + eor #$80 ++ bpl + + lda (P8ZP_SCRATCH_W1),y + sta P8ZP_SCRATCH_B1 ++ dey + cpy #255 + bne - + lda P8ZP_SCRATCH_B1 + rts + .pend + +func_min_b_stack .proc + jsr func_min_b_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +func_min_uw_into_AY .proc + ; -- min(uwarray) -> AY (array in P8ZP_SCRATCH_W1, num elements in A) + asl a + tay + dey + dey + lda #$ff + sta _result_minuw + sta _result_minuw+1 +_loop + iny + lda (P8ZP_SCRATCH_W1),y + dey + cmp _result_minuw+1 + bcc _less + bne _gtequ + lda (P8ZP_SCRATCH_W1),y + cmp _result_minuw + bcs _gtequ +_less lda (P8ZP_SCRATCH_W1),y + sta _result_minuw + iny + lda (P8ZP_SCRATCH_W1),y + sta _result_minuw+1 + dey +_gtequ dey + dey + cpy #254 + bne _loop + lda _result_minuw + ldy _result_minuw+1 + rts +_result_minuw .word 0 + .pend + +func_min_w_into_AY .proc + ; -- min(warray) -> AY (array in P8ZP_SCRATCH_W1, num elements in A) + asl a + tay + dey + dey + lda #$ff + sta _result_minw + lda #$7f + sta _result_minw+1 +_loop + lda (P8ZP_SCRATCH_W1),y + cmp _result_minw + iny + lda (P8ZP_SCRATCH_W1),y + dey + sbc _result_minw+1 + bvc + + eor #$80 ++ bpl _gtequ + lda (P8ZP_SCRATCH_W1),y + sta _result_minw + iny + lda (P8ZP_SCRATCH_W1),y + sta _result_minw+1 + dey +_gtequ dey + dey + cpy #254 + bne _loop + lda _result_minw + ldy _result_minw+1 + rts +_result_minw .word 0 + .pend + +func_min_uw_stack .proc + jsr func_min_uw_into_AY + sta P8ESTACK_LO,x + tya + sta P8ESTACK_HI,x + dex + rts + .pend + +func_min_w_stack .proc + jsr func_min_w_into_AY + sta P8ESTACK_LO,x + tya + sta P8ESTACK_HI,x + dex + rts + .pend + +func_max_ub_into_A .proc + ; -- max(ubarray) -> A (array in P8ZP_SCRATCH_W1, num elements in A) + tay + lda #0 + sta P8ZP_SCRATCH_B1 +- lda (P8ZP_SCRATCH_W1),y + cmp P8ZP_SCRATCH_B1 + bcc + + sta P8ZP_SCRATCH_B1 ++ dey + cpy #255 + bne - + lda P8ZP_SCRATCH_B1 + rts + .pend + +func_max_ub_stack .proc + jsr func_max_ub_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +func_max_b_into_A .proc + ; -- max(barray) -> A (array in P8ZP_SCRATCH_W1, num elements in A) + tay + lda #-128 + sta P8ZP_SCRATCH_B1 +- lda (P8ZP_SCRATCH_W1),y + sec + sbc P8ZP_SCRATCH_B1 + bvc + + eor #$80 ++ bmi + + lda (P8ZP_SCRATCH_W1),y + sta P8ZP_SCRATCH_B1 ++ dey + cpy #255 + bne - + lda P8ZP_SCRATCH_B1 + rts + .pend + +func_max_b_stack .proc + jsr func_max_b_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + +func_max_uw_into_AY .proc + ; -- max(uwarray) -> AY (array in P8ZP_SCRATCH_W1, num elements in A) + asl a + tay + dey + dey + lda #0 + sta _result_maxuw + sta _result_maxuw+1 +_loop + iny + lda (P8ZP_SCRATCH_W1),y + dey + cmp _result_maxuw+1 + bcc _lesseq + bne _greater + lda (P8ZP_SCRATCH_W1),y + cmp _result_maxuw + bcc _lesseq +_greater lda (P8ZP_SCRATCH_W1),y + sta _result_maxuw + iny + lda (P8ZP_SCRATCH_W1),y + sta _result_maxuw+1 + dey +_lesseq dey + dey + cpy #254 + bne _loop + lda _result_maxuw + ldy _result_maxuw+1 + rts +_result_maxuw .word 0 + .pend + +func_max_uw_stack .proc + jsr func_max_uw_into_AY + sta P8ESTACK_LO,x + tya + sta P8ESTACK_HI,x + dex + rts + .pend + +func_max_w_into_AY .proc + ; -- max(uwarray) -> AY (array in P8ZP_SCRATCH_W1, num elements in A) + asl a + tay + dey + dey + lda #0 + sta _result_maxw + lda #$80 + sta _result_maxw+1 +_loop + lda (P8ZP_SCRATCH_W1),y + cmp _result_maxw + iny + lda (P8ZP_SCRATCH_W1),y + dey + sbc _result_maxw+1 + bvc + + eor #$80 ++ bmi _lesseq + lda (P8ZP_SCRATCH_W1),y + sta _result_maxw + iny + lda (P8ZP_SCRATCH_W1),y + sta _result_maxw+1 + dey +_lesseq dey + dey + cpy #254 + bne _loop + lda _result_maxw + ldy _result_maxw+1 + rts +_result_maxw .word 0 + .pend + +func_max_w_stack .proc + jsr func_max_w_into_AY + sta P8ESTACK_LO,x + tya + sta P8ESTACK_HI,x + dex + rts + .pend + +func_sum_ub_into_AY .proc + ; -- sum(ubarray) -> AY (array in P8ZP_SCRATCH_W1, num elements in A) + tay + dey + lda #0 + sta P8ZP_SCRATCH_W2 + sta P8ZP_SCRATCH_W2+1 +- lda (P8ZP_SCRATCH_W1),y + clc + adc P8ZP_SCRATCH_W2 + sta P8ZP_SCRATCH_W2 + bcc + + inc P8ZP_SCRATCH_W2+1 ++ dey + cpy #255 + bne - + lda P8ZP_SCRATCH_W2 + ldy P8ZP_SCRATCH_W2+1 + rts + .pend + +func_sum_ub_stack .proc + jsr func_sum_ub_into_AY + sta P8ESTACK_LO,x + tya + sta P8ESTACK_HI,x + dex + rts + .pend + + +func_sum_b_into_AY .proc + ; -- sum(barray) -> AY (array in P8ZP_SCRATCH_W1, num elements in A) + tay + dey + lda #0 + sta P8ZP_SCRATCH_W2 + sta P8ZP_SCRATCH_W2+1 +_loop lda (P8ZP_SCRATCH_W1),y + pha + clc + adc P8ZP_SCRATCH_W2 + sta P8ZP_SCRATCH_W2 + ; sign extend the high byte + pla + and #$80 + beq + + lda #$ff ++ adc P8ZP_SCRATCH_W2+1 + sta P8ZP_SCRATCH_W2+1 + dey + cpy #255 + bne _loop + lda P8ZP_SCRATCH_W2 + ldy P8ZP_SCRATCH_W2+1 + rts + .pend + +func_sum_b_stack .proc + jsr func_sum_b_into_AY + sta P8ESTACK_LO,x + tya + sta P8ESTACK_HI,x + dex + rts + .pend + +func_sum_uw_into_AY .proc + ; -- sum(uwarray) -> AY (array in P8ZP_SCRATCH_W1, num elements in A) + asl a + tay + dey + dey + lda #0 + sta P8ZP_SCRATCH_W2 + sta P8ZP_SCRATCH_W2+1 +- lda (P8ZP_SCRATCH_W1),y + iny + clc + adc P8ZP_SCRATCH_W2 + sta P8ZP_SCRATCH_W2 + lda (P8ZP_SCRATCH_W1),y + adc P8ZP_SCRATCH_W2+1 + sta P8ZP_SCRATCH_W2+1 + dey + dey + dey + cpy #254 + bne - + lda P8ZP_SCRATCH_W2 + ldy P8ZP_SCRATCH_W2+1 + rts + .pend + +func_sum_uw_stack .proc + jsr func_sum_uw_into_AY + sta P8ESTACK_LO,x + tya + sta P8ESTACK_HI,x + dex + rts + .pend + + +func_sum_w_into_AY = func_sum_uw_into_AY +func_sum_w_stack = func_sum_uw_stack + + +func_sort_ub .proc + ; 8bit unsigned sort + ; sorting subroutine coded by mats rosengren (mats.rosengren@esa.int) + ; input: address of array to sort in P8ZP_SCRATCH_W1, length in S + ; first, put pointer BEFORE array + sta P8ZP_SCRATCH_B1 + lda P8ZP_SCRATCH_W1 + bne + + dec P8ZP_SCRATCH_W1+1 ++ dec P8ZP_SCRATCH_W1 +_sortloop ldy P8ZP_SCRATCH_B1 ;start of subroutine sort + lda (P8ZP_SCRATCH_W1),y ;last value in (what is left of) sequence to be sorted + sta P8ZP_SCRATCH_REG ;save value. will be over-written by largest number + jmp _l2 +_l1 dey + beq _l3 + lda (P8ZP_SCRATCH_W1),y + cmp P8ZP_SCRATCH_W2+1 + bcc _l1 +_l2 sty P8ZP_SCRATCH_W2 ;index of potentially largest value + sta P8ZP_SCRATCH_W2+1 ;potentially largest value + jmp _l1 +_l3 ldy P8ZP_SCRATCH_B1 ;where the largest value shall be put + lda P8ZP_SCRATCH_W2+1 ;the largest value + sta (P8ZP_SCRATCH_W1),y ;put largest value in place + ldy P8ZP_SCRATCH_W2 ;index of free space + lda P8ZP_SCRATCH_REG ;the over-written value + sta (P8ZP_SCRATCH_W1),y ;put the over-written value in the free space + dec P8ZP_SCRATCH_B1 ;end of the shorter sequence still left + bne _sortloop ;start working with the shorter sequence + rts + .pend + + +func_sort_b .proc + ; 8bit signed sort + ; sorting subroutine coded by mats rosengren (mats.rosengren@esa.int) + ; input: address of array to sort in P8ZP_SCRATCH_W1, length in A + ; first, put pointer BEFORE array + sta P8ZP_SCRATCH_B1 + lda P8ZP_SCRATCH_W1 + bne + + dec P8ZP_SCRATCH_W1+1 ++ dec P8ZP_SCRATCH_W1 +_sortloop ldy P8ZP_SCRATCH_B1 ;start of subroutine sort + lda (P8ZP_SCRATCH_W1),y ;last value in (what is left of) sequence to be sorted + sta P8ZP_SCRATCH_REG ;save value. will be over-written by largest number + jmp _l2 +_l1 dey + beq _l3 + lda (P8ZP_SCRATCH_W1),y + cmp P8ZP_SCRATCH_W2+1 + bmi _l1 +_l2 sty P8ZP_SCRATCH_W2 ;index of potentially largest value + sta P8ZP_SCRATCH_W2+1 ;potentially largest value + jmp _l1 +_l3 ldy P8ZP_SCRATCH_B1 ;where the largest value shall be put + lda P8ZP_SCRATCH_W2+1 ;the largest value + sta (P8ZP_SCRATCH_W1),y ;put largest value in place + ldy P8ZP_SCRATCH_W2 ;index of free space + lda P8ZP_SCRATCH_REG ;the over-written value + sta (P8ZP_SCRATCH_W1),y ;put the over-written value in the free space + dec P8ZP_SCRATCH_B1 ;end of the shorter sequence still left + bne _sortloop ;start working with the shorter sequence + rts + .pend + + +func_sort_uw .proc + ; 16bit unsigned sort + ; sorting subroutine coded by mats rosengren (mats.rosengren@esa.int) + ; input: address of array to sort in P8ZP_SCRATCH_W1, length in A + ; first: subtract 2 of the pointer + asl a + sta P8ZP_SCRATCH_B1 + lda P8ZP_SCRATCH_W1 + sec + sbc #2 + sta P8ZP_SCRATCH_W1 + bcs _sort_loop + dec P8ZP_SCRATCH_W1+1 +_sort_loop ldy P8ZP_SCRATCH_B1 ;start of subroutine sort + lda (P8ZP_SCRATCH_W1),y ;last value in (what is left of) sequence to be sorted + sta _work3 ;save value. will be over-written by largest number + iny + lda (P8ZP_SCRATCH_W1),y + sta _work3+1 + dey + jmp _l2 +_l1 dey + dey + beq _l3 + iny + lda (P8ZP_SCRATCH_W1),y + dey + cmp P8ZP_SCRATCH_W2+1 + bne + + lda (P8ZP_SCRATCH_W1),y + cmp P8ZP_SCRATCH_W2 ++ bcc _l1 +_l2 sty _work1 ;index of potentially largest value + lda (P8ZP_SCRATCH_W1),y + sta P8ZP_SCRATCH_W2 ;potentially largest value + iny + lda (P8ZP_SCRATCH_W1),y + sta P8ZP_SCRATCH_W2+1 + dey + jmp _l1 +_l3 ldy P8ZP_SCRATCH_B1 ;where the largest value shall be put + lda P8ZP_SCRATCH_W2 ;the largest value + sta (P8ZP_SCRATCH_W1),y ;put largest value in place + iny + lda P8ZP_SCRATCH_W2+1 + sta (P8ZP_SCRATCH_W1),y + ldy _work1 ;index of free space + lda _work3 ;the over-written value + sta (P8ZP_SCRATCH_W1),y ;put the over-written value in the free space + iny + lda _work3+1 + sta (P8ZP_SCRATCH_W1),y + dey + dec P8ZP_SCRATCH_B1 ;end of the shorter sequence still left + dec P8ZP_SCRATCH_B1 + bne _sort_loop ;start working with the shorter sequence + rts +_work1 .byte 0 +_work3 .word 0 + .pend + + +func_sort_w .proc + ; 16bit signed sort + ; sorting subroutine coded by mats rosengren (mats.rosengren@esa.int) + ; input: address of array to sort in P8ZP_SCRATCH_W1, length in A + ; first: subtract 2 of the pointer + asl a + sta P8ZP_SCRATCH_B1 + lda P8ZP_SCRATCH_W1 + sec + sbc #2 + sta P8ZP_SCRATCH_W1 + bcs _sort_loop + dec P8ZP_SCRATCH_W1+1 +_sort_loop ldy P8ZP_SCRATCH_B1 ;start of subroutine sort + lda (P8ZP_SCRATCH_W1),y ;last value in (what is left of) sequence to be sorted + sta _work3 ;save value. will be over-written by largest number + iny + lda (P8ZP_SCRATCH_W1),y + sta _work3+1 + dey + jmp _l2 +_l1 dey + dey + beq _l3 + lda (P8ZP_SCRATCH_W1),y + cmp P8ZP_SCRATCH_W2 + iny + lda (P8ZP_SCRATCH_W1),y + dey + sbc P8ZP_SCRATCH_W2+1 + bvc + + eor #$80 ++ bmi _l1 +_l2 sty _work1 ;index of potentially largest value + lda (P8ZP_SCRATCH_W1),y + sta P8ZP_SCRATCH_W2 ;potentially largest value + iny + lda (P8ZP_SCRATCH_W1),y + sta P8ZP_SCRATCH_W2+1 + dey + jmp _l1 +_l3 ldy P8ZP_SCRATCH_B1 ;where the largest value shall be put + lda P8ZP_SCRATCH_W2 ;the largest value + sta (P8ZP_SCRATCH_W1),y ;put largest value in place + iny + lda P8ZP_SCRATCH_W2+1 + sta (P8ZP_SCRATCH_W1),y + ldy _work1 ;index of free space + lda _work3 ;the over-written value + sta (P8ZP_SCRATCH_W1),y ;put the over-written value in the free space + iny + lda _work3+1 + sta (P8ZP_SCRATCH_W1),y + dey + dec P8ZP_SCRATCH_B1 ;end of the shorter sequence still left + dec P8ZP_SCRATCH_B1 + bne _sort_loop ;start working with the shorter sequence + rts +_work1 .byte 0 +_work3 .word 0 + .pend + + +func_reverse_b .proc + ; --- reverse an array of bytes (in-place) + ; inputs: pointer to array in P8ZP_SCRATCH_W1, length in A +_index_right = P8ZP_SCRATCH_W2 +_index_left = P8ZP_SCRATCH_W2+1 +_loop_count = P8ZP_SCRATCH_REG + sta _loop_count + lsr _loop_count + sec + sbc #1 + sta _index_right + lda #0 + sta _index_left +_loop ldy _index_right + lda (P8ZP_SCRATCH_W1),y + pha + ldy _index_left + lda (P8ZP_SCRATCH_W1),y + ldy _index_right + sta (P8ZP_SCRATCH_W1),y + pla + ldy _index_left + sta (P8ZP_SCRATCH_W1),y + inc _index_left + dec _index_right + dec _loop_count + bne _loop + rts + .pend + + +func_reverse_w .proc + ; --- reverse an array of words (in-place) + ; inputs: pointer to array in P8ZP_SCRATCH_W1, length in A +_index_first = P8ZP_SCRATCH_W2 +_index_second = P8ZP_SCRATCH_W2+1 +_loop_count = P8ZP_SCRATCH_REG + pha + asl a ; *2 because words + sec + sbc #2 + sta _index_first + lda #0 + sta _index_second + pla + lsr a + pha + sta _loop_count + ; first reverse the lsbs +_loop_lo ldy _index_first + lda (P8ZP_SCRATCH_W1),y + pha + ldy _index_second + lda (P8ZP_SCRATCH_W1),y + ldy _index_first + sta (P8ZP_SCRATCH_W1),y + pla + ldy _index_second + sta (P8ZP_SCRATCH_W1),y + inc _index_second + inc _index_second + dec _index_first + dec _index_first + dec _loop_count + bne _loop_lo + ; now reverse the msbs + dec _index_second + inc _index_first + inc _index_first + inc _index_first + pla + sta _loop_count +_loop_hi ldy _index_first + lda (P8ZP_SCRATCH_W1),y + pha + ldy _index_second + lda (P8ZP_SCRATCH_W1),y + ldy _index_first + sta (P8ZP_SCRATCH_W1),y + pla + ldy _index_second + sta (P8ZP_SCRATCH_W1),y + dec _index_second + dec _index_second + inc _index_first + inc _index_first + dec _loop_count + bne _loop_hi + + rts + .pend + + +func_exit .proc + ; -- immediately exit the program with a return code in the A register + ldx orig_stackpointer + txs + rts ; return to original caller + .pend + + +func_read_flags_stack .proc + ; -- put the processor status register on the stack + php + pla + sta P8ESTACK_LO,x + dex + rts + .pend + + +func_memset .proc + ; note: clobbers A,Y + txa + pha + lda _arg_address + sta P8ZP_SCRATCH_W1 + lda _arg_address+1 + sta P8ZP_SCRATCH_W1+1 + ldx _arg_numbytes + ldy _arg_numbytes+1 + lda _arg_bytevalue + jsr memset + pla + tax + rts +_arg_address .word 0 +_arg_numbytes .word 0 +_arg_bytevalue .byte 0 + .pend + + +func_memsetw .proc + ; note: clobbers A,Y + txa + pha + lda _arg_address + sta P8ZP_SCRATCH_W1 + lda _arg_address+1 + sta P8ZP_SCRATCH_W1+1 + lda _arg_numwords + sta P8ZP_SCRATCH_W2 + lda _arg_numwords+1 + sta P8ZP_SCRATCH_W2+1 + lda _arg_wordvalue + ldy _arg_wordvalue+1 + jsr memsetw + pla + tax + rts +_arg_address .word 0 +_arg_numwords .word 0 +_arg_wordvalue .word 0 + .pend + + +func_memcopy .proc + ; memcopy of any number of bytes, note: clobbers A,Y + stx P8ZP_SCRATCH_REG + lda _arg_from + sta P8ZP_SCRATCH_W1 + lda _arg_from+1 + sta P8ZP_SCRATCH_W1+1 + lda _arg_to + sta P8ZP_SCRATCH_W2 + lda _arg_to+1 + sta P8ZP_SCRATCH_W2+1 + + ldy #0 + ldx _arg_numbytes+1 + beq _remain +- lda (P8ZP_SCRATCH_W1),y ; move a page at a time + sta (P8ZP_SCRATCH_W2),y + iny + bne - + inc P8ZP_SCRATCH_W1+1 + inc P8ZP_SCRATCH_W2+1 + dex + bne - +_remain ldx _arg_numbytes + beq _done +- lda (P8ZP_SCRATCH_W1),y ; move the remaining bytes + sta (P8ZP_SCRATCH_W2),y + iny + dex + bne - + +_done ldx P8ZP_SCRATCH_REG + rts + +_arg_from .word 0 +_arg_to .word 0 +_arg_numbytes .word 0 + .pend + + +func_memcopy255 .proc + ; fast memcopy of up to 255 bytes, note: clobbers A,Y + ; note: also uses the _arg variables from regular func_memcopy + stx P8ZP_SCRATCH_REG + lda func_memcopy._arg_from + sta P8ZP_SCRATCH_W1 + lda func_memcopy._arg_from+1 + sta P8ZP_SCRATCH_W1+1 + lda func_memcopy._arg_to + sta P8ZP_SCRATCH_W2 + lda func_memcopy._arg_to+1 + sta P8ZP_SCRATCH_W2+1 + ldx func_memcopy._arg_numbytes + ldy #0 +- lda (P8ZP_SCRATCH_W1), y + sta (P8ZP_SCRATCH_W2), y + iny + dex + bne - + ldx P8ZP_SCRATCH_REG + rts + .pend + + +func_leftstr .proc + ; leftstr(source, target, length) + lda _arg_source + ldy _arg_source+1 + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + lda _arg_target + ldy _arg_target+1 + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + ldy _arg_length + lda #0 + sta (P8ZP_SCRATCH_W2),y + cpy #0 + bne _loop + rts +_loop dey + lda (P8ZP_SCRATCH_W1),y + sta (P8ZP_SCRATCH_W2),y + cpy #0 + bne _loop ++ rts + +_arg_source .word 0 +_arg_target .word 0 +_arg_length .byte 0 + .pend + + +func_rightstr .proc + ; rightstr(source, target, length) + lda _arg_source + ldy _arg_source+1 + jsr func_strlen_into_A + sec + sbc _arg_length + sta P8ZP_SCRATCH_B1 + lda _arg_source + ldy _arg_source+1 + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + lda _arg_target + ldy _arg_target+1 + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + ldy #0 + sty P8ZP_SCRATCH_REG +- ldy P8ZP_SCRATCH_B1 + lda (P8ZP_SCRATCH_W1),y + inc P8ZP_SCRATCH_B1 + ldy P8ZP_SCRATCH_REG + sta (P8ZP_SCRATCH_W2),y + inc P8ZP_SCRATCH_REG + cmp #0 + bne - + rts + +_arg_source .word 0 +_arg_target .word 0 +_arg_length .byte 0 + .pend + + +func_strlen_into_A .proc + ; -- put length of 0-terminated string in A/Y into A + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + ldy #0 +- lda (P8ZP_SCRATCH_W1),y + beq + + iny + bne - ++ tya + rts + .pend + +func_strlen_stack .proc + jsr func_strlen_into_A + sta P8ESTACK_LO,x + dex + rts + .pend + + +func_substr .proc + ; substr(source, target, start, length) + lda _arg_source + ldy _arg_source+1 + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + lda _arg_target + ldy _arg_target+1 + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + ldy _arg_length + lda _arg_start + sta P8ZP_SCRATCH_B1 + + ; adjust src location + clc + lda P8ZP_SCRATCH_W1 + adc P8ZP_SCRATCH_B1 + sta P8ZP_SCRATCH_W1 + bcc + + inc P8ZP_SCRATCH_W1+1 ++ lda #0 + sta (P8ZP_SCRATCH_W2),y + jmp _startloop +- lda (P8ZP_SCRATCH_W1),y + sta (P8ZP_SCRATCH_W2),y +_startloop dey + cpy #$ff + bne - + rts + +_arg_source .word 0 +_arg_target .word 0 +_arg_start .byte 0 +_arg_length .byte 0 + .pend + + +func_strcmp .proc + ; -- compare 2 strings -> A + lda _arg_s2 + ldy _arg_s2+1 + sta P8ZP_SCRATCH_W2 + sty P8ZP_SCRATCH_W2+1 + lda _arg_s1 + ldy _arg_s1+1 + jmp strcmp_mem +_arg_s1 .word 0 +_arg_s2 .word 0 + .pend + +func_strcmp_stack .proc + jsr func_strcmp + sta P8ESTACK_LO,x + dex + rts + .pend diff --git a/compiler/res/prog8lib/prog8_lib.asm b/compiler/res/prog8lib/prog8_lib.asm index 8032d32cd..4a8d12b66 100644 --- a/compiler/res/prog8lib/prog8_lib.asm +++ b/compiler/res/prog8lib/prog8_lib.asm @@ -30,16 +30,6 @@ write_byte_to_address_on_stack .proc .pend -add_a_to_zpword .proc - ; -- add ubyte in A to the uword in P8ZP_SCRATCH_W1 - clc - adc P8ZP_SCRATCH_W1 - sta P8ZP_SCRATCH_W1 - bcc + - inc P8ZP_SCRATCH_W1+1 -+ rts - .pend - neg_b .proc lda #0 sec @@ -245,52 +235,6 @@ xor_w .proc .pend -abs_b_cc .proc - ; -- push abs(A) on stack (as byte) - jsr abs_b_into_A_cc - sta P8ESTACK_LO,x - dex - rts - .pend - -abs_w_cc .proc - ; -- push abs(AY) on stack (as word) - jsr abs_w_into_AY_cc - sta P8ESTACK_LO,x - tya - sta P8ESTACK_HI,x - dex - rts - .pend - -abs_b_into_A_cc .proc - ; -- A = abs(A) - cmp #0 - bmi + - rts -+ eor #$ff - clc - adc #1 - rts - .pend - -abs_w_into_AY_cc .proc - ; -- AY = abs(AY) - cpy #0 - bmi + - rts -+ eor #$ff - pha - tya - eor #$ff - tay - pla - clc - adc #1 - bcc + - iny -+ rts - .pend add_w .proc ; -- push word+word / uword+uword @@ -685,779 +629,6 @@ shiftright_b .proc orig_stackpointer .byte 0 ; stores the Stack pointer register at program start -func_exit .proc - ; -- immediately exit the program with a return code in the A register - lda P8ESTACK_LO+1,x - ldx orig_stackpointer - txs - rts ; return to original caller - .pend - - -func_read_flags .proc - ; -- put the processor status register on the stack - php - pla - sta P8ESTACK_LO,x - dex - rts - .pend - -func_sqrt16_into_A .proc - ; integer square root from http://6502org.wikidot.com/software-math-sqrt - sta P8ZP_SCRATCH_W1 - sty P8ZP_SCRATCH_W1+1 - txa - pha - lda #0 - sta P8ZP_SCRATCH_B1 - sta P8ZP_SCRATCH_REG - ldx #8 -- sec - lda P8ZP_SCRATCH_W1+1 - sbc #$40 - tay - lda P8ZP_SCRATCH_REG - sbc P8ZP_SCRATCH_B1 - bcc + - sty P8ZP_SCRATCH_W1+1 - sta P8ZP_SCRATCH_REG -+ rol P8ZP_SCRATCH_B1 - asl P8ZP_SCRATCH_W1 - rol P8ZP_SCRATCH_W1+1 - rol P8ZP_SCRATCH_REG - asl P8ZP_SCRATCH_W1 - rol P8ZP_SCRATCH_W1+1 - rol P8ZP_SCRATCH_REG - dex - bne - - pla - tax - lda P8ZP_SCRATCH_B1 - rts - .pend - - -func_sin8_into_A .proc - tay - lda _sinecos8,y - rts -_sinecos8 .char trunc(127.0 * sin(range(256+64) * rad(360.0/256.0))) - .pend - -func_sin8u_into_A .proc - tay - lda _sinecos8u,y - rts -_sinecos8u .byte trunc(128.0 + 127.5 * sin(range(256+64) * rad(360.0/256.0))) - .pend - -func_sin16_into_AY .proc - tay - lda _sinecos8lo,y - pha - lda _sinecos8hi,y - tay - pla - rts -_ := trunc(32767.0 * sin(range(256+64) * rad(360.0/256.0))) -_sinecos8lo .byte <_ -_sinecos8hi .byte >_ - .pend - -func_sin16u_into_AY .proc - tay - lda _sinecos8ulo,y - pha - lda _sinecos8uhi,y - tay - pla - rts -_ := trunc(32768.0 + 32767.5 * sin(range(256+64) * rad(360.0/256.0))) -_sinecos8ulo .byte <_ -_sinecos8uhi .byte >_ - .pend - -func_cos8_into_A .proc - tay - lda func_sin8_into_A._sinecos8+64,y - rts - .pend - -func_cos8u_into_A .proc - tay - lda func_sin8u_into_A._sinecos8u+64,y - rts - .pend - -func_cos16_into_AY .proc - tay - lda func_sin16_into_AY._sinecos8lo+64,y - pha - lda func_sin16_into_AY._sinecos8hi+64,y - tay - pla - rts - .pend - -func_cos16u_into_AY .proc - tay - lda func_sin16u_into_AY._sinecos8ulo+64,y - pha - lda func_sin16u_into_AY._sinecos8uhi+64,y - tay - pla - rts - .pend - -func_sin8_cc .proc - tay - lda func_sin8_into_A._sinecos8,y - sta P8ESTACK_LO,x - dex - rts - .pend - -func_sin8u_cc .proc - tay - lda func_sin8u_into_A._sinecos8u,y - sta P8ESTACK_LO,x - dex - rts - .pend - -func_sin16_cc .proc - tay - lda func_sin16_into_AY._sinecos8lo,y - sta P8ESTACK_LO,x - lda func_sin16_into_AY._sinecos8hi,y - sta P8ESTACK_HI,x - dex - rts - - .pend - -func_sin16u_cc .proc - tay - lda func_sin16u_into_AY._sinecos8ulo,y - sta P8ESTACK_LO,x - lda func_sin16u_into_AY._sinecos8uhi,y - sta P8ESTACK_HI,x - dex - rts - .pend - -func_cos8_cc .proc - tay - lda func_sin8_into_A._sinecos8+64,y - sta P8ESTACK_LO,x - dex - rts - .pend - -func_cos8u_cc .proc - tay - lda func_sin8u_into_A._sinecos8u+64,y - sta P8ESTACK_LO,x - dex - rts - .pend - -func_cos16_cc .proc - tay - lda func_sin16_into_AY._sinecos8lo+64,y - sta P8ESTACK_LO,x - lda func_sin16_into_AY._sinecos8hi+64,y - sta P8ESTACK_HI,x - dex - rts - .pend - -func_cos16u_cc .proc - tay - lda func_sin16u_into_AY._sinecos8ulo+64,y - sta P8ESTACK_LO,x - lda func_sin16u_into_AY._sinecos8uhi+64,y - sta P8ESTACK_HI,x - dex - rts - .pend - - -peek_address .proc - ; -- peek address on stack into P8ZP_SCRATCH_W1 - lda P8ESTACK_LO+1,x - sta P8ZP_SCRATCH_W1 - lda P8ESTACK_HI+1,x - sta P8ZP_SCRATCH_W1+1 - rts - .pend - -func_any_w_into_A .proc - jsr func_any_w_cc - jmp func_any_b_into_A._popA - .pend - -func_all_w_into_A .proc - jsr func_all_w_cc - jmp func_any_b_into_A._popA - .pend - - -func_any_w_cc .proc - ; TODO args not via stack - inx - lda P8ESTACK_LO,x ; array size - asl a ; times 2 because of word - jmp func_any_b_cc._entry - .pend - -func_all_w_cc .proc - ; TODO arg not via stack - inx - lda P8ESTACK_LO,x ; array size - asl a ; times 2 because of word - sta _cmp_mod+1 ; self-modifying code - jsr peek_address - ldy #0 -- lda (P8ZP_SCRATCH_W1),y - bne + - iny - lda (P8ZP_SCRATCH_W1),y - bne ++ - lda #0 - sta P8ESTACK_LO+1,x - rts -+ iny -+ iny -_cmp_mod cpy #255 ; modified - bne - - lda #1 - sta P8ESTACK_LO+1,x - rts - .pend - -func_max_ub_cc .proc - ; TODO args not via stack - jsr pop_array_and_lengthmin1Y - lda #0 - sta P8ZP_SCRATCH_B1 -- lda (P8ZP_SCRATCH_W1),y - cmp P8ZP_SCRATCH_B1 - bcc + - sta P8ZP_SCRATCH_B1 -+ dey - cpy #255 - bne - - lda P8ZP_SCRATCH_B1 - sta P8ESTACK_LO,x - dex - rts - .pend - -func_max_b_cc .proc - ; TODO args not via stack - jsr pop_array_and_lengthmin1Y - lda #-128 - sta P8ZP_SCRATCH_B1 -- lda (P8ZP_SCRATCH_W1),y - sec - sbc P8ZP_SCRATCH_B1 - bvc + - eor #$80 -+ bmi + - lda (P8ZP_SCRATCH_W1),y - sta P8ZP_SCRATCH_B1 -+ dey - cpy #255 - bne - - lda P8ZP_SCRATCH_B1 - sta P8ESTACK_LO,x - dex - rts - .pend - -func_max_uw_bb .proc - ; TODO args not via stack - lda #0 - sta _result_maxuw - sta _result_maxuw+1 - jsr pop_array_and_lengthmin1Y - tya - asl a - tay -_loop - iny - lda (P8ZP_SCRATCH_W1),y - dey - cmp _result_maxuw+1 - bcc _lesseq - bne _greater - lda (P8ZP_SCRATCH_W1),y - cmp _result_maxuw - bcc _lesseq -_greater lda (P8ZP_SCRATCH_W1),y - sta _result_maxuw - iny - lda (P8ZP_SCRATCH_W1),y - sta _result_maxuw+1 - dey -_lesseq dey - dey - cpy #254 - bne _loop - lda _result_maxuw - sta P8ESTACK_LO,x - lda _result_maxuw+1 - sta P8ESTACK_HI,x - dex - rts -_result_maxuw .word 0 - .pend - -func_max_w_cc .proc - ; TODO args not via stack - lda #0 - sta _result_maxw - lda #$80 - sta _result_maxw+1 - jsr pop_array_and_lengthmin1Y - tya - asl a - tay -_loop - lda (P8ZP_SCRATCH_W1),y - cmp _result_maxw - iny - lda (P8ZP_SCRATCH_W1),y - dey - sbc _result_maxw+1 - bvc + - eor #$80 -+ bmi _lesseq - lda (P8ZP_SCRATCH_W1),y - sta _result_maxw - iny - lda (P8ZP_SCRATCH_W1),y - sta _result_maxw+1 - dey -_lesseq dey - dey - cpy #254 - bne _loop - lda _result_maxw - sta P8ESTACK_LO,x - lda _result_maxw+1 - sta P8ESTACK_HI,x - dex - rts -_result_maxw .word 0 - .pend - - -func_sum_b_cc .proc - ; TODO args not via stack - jsr pop_array_and_lengthmin1Y - lda #0 - sta P8ESTACK_LO,x - sta P8ESTACK_HI,x -_loop lda (P8ZP_SCRATCH_W1),y - pha - clc - adc P8ESTACK_LO,x - sta P8ESTACK_LO,x - ; sign extend the high byte - pla - and #$80 - beq + - lda #$ff -+ adc P8ESTACK_HI,x - sta P8ESTACK_HI,x - dey - cpy #255 - bne _loop - dex - rts - .pend - -func_sum_ub_cc .proc - ; TODO args not via stack - jsr pop_array_and_lengthmin1Y - lda #0 - sta P8ESTACK_HI,x -- clc - adc (P8ZP_SCRATCH_W1),y - bcc + - inc P8ESTACK_HI,x -+ dey - cpy #255 - bne - - sta P8ESTACK_LO,x - dex - rts - .pend - -func_sum_uw_cc .proc - ; TODO args not via stack - jsr pop_array_and_lengthmin1Y - tya - asl a - tay - lda #0 - sta P8ESTACK_LO,x - sta P8ESTACK_HI,x -- lda (P8ZP_SCRATCH_W1),y - iny - clc - adc P8ESTACK_LO,x - sta P8ESTACK_LO,x - lda (P8ZP_SCRATCH_W1),y - adc P8ESTACK_HI,x - sta P8ESTACK_HI,x - dey - dey - dey - cpy #254 - bne - - dex - rts - .pend - -func_sum_w_cc .proc - jmp func_sum_uw_cc - .pend - - -pop_array_and_lengthmin1Y .proc - inx - ldy P8ESTACK_LO,x - dey ; length minus 1, for iteration - lda P8ESTACK_LO+1,x - sta P8ZP_SCRATCH_W1 - lda P8ESTACK_HI+1,x - sta P8ZP_SCRATCH_W1+1 - inx - rts - .pend - -func_min_ub_into_A .proc - jsr func_min_ub_cc -_popA inx - lda P8ESTACK_LO,x - rts - .pend - -func_min_b_into_A .proc - jsr func_min_b_cc - jmp func_min_ub_into_A._popA - .pend - -func_max_ub_into_A .proc - jsr func_max_ub_cc - jmp func_min_ub_into_A._popA - .pend - -func_max_b_into_A .proc - jsr func_max_b_cc - jmp func_min_ub_into_A._popA - .pend - -func_sum_ub_into_AY .proc - jsr func_sum_ub_cc -_popAY inx - lda P8ESTACK_LO,x - ldy P8ESTACK_HI,x - rts - .pend - -func_sum_b_into_AY .proc - jsr func_sum_b_cc - jmp func_sum_ub_into_AY._popAY - .pend - -func_min_uw_into_AY .proc - jsr func_min_uw_cc - jmp func_sum_ub_into_AY._popAY - .pend - -func_min_w_into_AY .proc - jsr func_min_w_cc - jmp func_sum_ub_into_AY._popAY - .pend - -func_max_uw_into_AY .proc - jsr func_max_uw_cc - jmp func_sum_ub_into_AY._popAY - .pend - -func_max_w_into_AY .proc - jsr func_max_w_cc - jmp func_sum_ub_into_AY._popAY - .pend - -func_sum_uw_into_AY .proc - jsr func_sum_uw_cc - jmp func_sum_ub_into_AY._popAY - .pend - -func_sum_w_into_AY .proc - jsr func_sum_w_cc - jmp func_sum_ub_into_AY._popAY - .pend - - -func_min_ub_cc .proc - ; TODO args not via stack - jsr pop_array_and_lengthmin1Y - lda #255 - sta P8ZP_SCRATCH_B1 -- lda (P8ZP_SCRATCH_W1),y - cmp P8ZP_SCRATCH_B1 - bcs + - sta P8ZP_SCRATCH_B1 -+ dey - cpy #255 - bne - - lda P8ZP_SCRATCH_B1 - sta P8ESTACK_LO,x - dex - rts - .pend - - -func_min_b_cc .proc - ; TODO args not via stack - jsr pop_array_and_lengthmin1Y - lda #127 - sta P8ZP_SCRATCH_B1 -- lda (P8ZP_SCRATCH_W1),y - clc - sbc P8ZP_SCRATCH_B1 - bvc + - eor #$80 -+ bpl + - lda (P8ZP_SCRATCH_W1),y - sta P8ZP_SCRATCH_B1 -+ dey - cpy #255 - bne - - lda P8ZP_SCRATCH_B1 - sta P8ESTACK_LO,x - dex - rts - .pend - -func_min_uw_cc .proc - ; TODO args not via stack - lda #$ff - sta _result_minuw - sta _result_minuw+1 - jsr pop_array_and_lengthmin1Y - tya - asl a - tay -_loop - iny - lda (P8ZP_SCRATCH_W1),y - dey - cmp _result_minuw+1 - bcc _less - bne _gtequ - lda (P8ZP_SCRATCH_W1),y - cmp _result_minuw - bcs _gtequ -_less lda (P8ZP_SCRATCH_W1),y - sta _result_minuw - iny - lda (P8ZP_SCRATCH_W1),y - sta _result_minuw+1 - dey -_gtequ dey - dey - cpy #254 - bne _loop - lda _result_minuw - sta P8ESTACK_LO,x - lda _result_minuw+1 - sta P8ESTACK_HI,x - dex - rts -_result_minuw .word 0 - .pend - -func_min_w_cc .proc - ; TODO not via stack - lda #$ff - sta _result_minw - lda #$7f - sta _result_minw+1 - jsr pop_array_and_lengthmin1Y - tya - asl a - tay -_loop - lda (P8ZP_SCRATCH_W1),y - cmp _result_minw - iny - lda (P8ZP_SCRATCH_W1),y - dey - sbc _result_minw+1 - bvc + - eor #$80 -+ bpl _gtequ - lda (P8ZP_SCRATCH_W1),y - sta _result_minw - iny - lda (P8ZP_SCRATCH_W1),y - sta _result_minw+1 - dey -_gtequ dey - dey - cpy #254 - bne _loop - lda _result_minw - sta P8ESTACK_LO,x - lda _result_minw+1 - sta P8ESTACK_HI,x - dex - rts -_result_minw .word 0 - .pend - -func_rnd .proc - ; -- put a random ubyte on the estack - jsr math.randbyte - sta P8ESTACK_LO,x - dex - rts - .pend - -func_rndw .proc - ; -- put a random uword on the estack - jsr math.randword - sta P8ESTACK_LO,x - tya - sta P8ESTACK_HI,x - dex - rts - .pend - - -func_memcopy255_cc .proc - ; fast memcopy of up to 255 bytes, note: clobbers A,Y - ; note: also uses the _arg variables from regular func_memcopy - stx P8ZP_SCRATCH_REG - lda func_memcopy_cc._arg_from - sta P8ZP_SCRATCH_W1 - lda func_memcopy_cc._arg_from+1 - sta P8ZP_SCRATCH_W1+1 - lda func_memcopy_cc._arg_to - sta P8ZP_SCRATCH_W2 - lda func_memcopy_cc._arg_to+1 - sta P8ZP_SCRATCH_W2+1 - ldx func_memcopy_cc._arg_numbytes - ldy #0 -- lda (P8ZP_SCRATCH_W1), y - sta (P8ZP_SCRATCH_W2), y - iny - dex - bne - - ldx P8ZP_SCRATCH_REG - rts - .pend - -func_memcopy_cc .proc - ; memcopy of any number of bytes, note: clobbers A,Y - stx P8ZP_SCRATCH_REG - lda _arg_from - sta P8ZP_SCRATCH_W1 - lda _arg_from+1 - sta P8ZP_SCRATCH_W1+1 - lda _arg_to - sta P8ZP_SCRATCH_W2 - lda _arg_to+1 - sta P8ZP_SCRATCH_W2+1 - - ldy #0 - ldx _arg_numbytes+1 - beq _remain -- lda (P8ZP_SCRATCH_W1),y ; move a page at a time - sta (P8ZP_SCRATCH_W2),y - iny - bne - - inc P8ZP_SCRATCH_W1+1 - inc P8ZP_SCRATCH_W2+1 - dex - bne - -_remain ldx _arg_numbytes - beq _done -- lda (P8ZP_SCRATCH_W1),y ; move the remaining bytes - sta (P8ZP_SCRATCH_W2),y - iny - dex - bne - - -_done ldx P8ZP_SCRATCH_REG - rts - -_arg_from .word 0 -_arg_to .word 0 -_arg_numbytes .word 0 - .pend - -func_memset_cc .proc - ; note: clobbers A,Y - stx P8ZP_SCRATCH_REG - lda _arg_address - sta P8ZP_SCRATCH_W1 - lda _arg_address+1 - sta P8ZP_SCRATCH_W1+1 - ldx _arg_numbytes - ldy _arg_numbytes+1 - lda _arg_bytevalue - jsr memset - ldx P8ZP_SCRATCH_REG - rts -_arg_address .word 0 -_arg_numbytes .word 0 -_arg_bytevalue .byte 0 - .pend - -func_memsetw_cc .proc - ; note: clobbers A,Y - txa - pha - lda _arg_address - sta P8ZP_SCRATCH_W1 - lda _arg_address+1 - sta P8ZP_SCRATCH_W1+1 - lda _arg_numwords - sta P8ZP_SCRATCH_W2 - lda _arg_numwords+1 - sta P8ZP_SCRATCH_W2+1 - lda _arg_wordvalue - ldy _arg_wordvalue+1 - jsr memsetw - pla - tax - rts -_arg_address .word 0 -_arg_numwords .word 0 -_arg_wordvalue .word 0 - .pend - -strlen .proc - ; -- put length of 0-terminated string in A/Y into A - sta P8ZP_SCRATCH_W1 - sty P8ZP_SCRATCH_W1+1 - ldy #0 -- lda (P8ZP_SCRATCH_W1),y - beq + - iny - bne - -+ tya - rts - .pend memcopy16_up .proc @@ -1570,286 +741,6 @@ _done rts .pend -sort_ub .proc - ; 8bit unsigned sort - ; sorting subroutine coded by mats rosengren (mats.rosengren@esa.int) - ; input: address of array to sort in P8ZP_SCRATCH_W1, length in P8ZP_SCRATCH_B1 - ; first, put pointer BEFORE array - lda P8ZP_SCRATCH_W1 - bne + - dec P8ZP_SCRATCH_W1+1 -+ dec P8ZP_SCRATCH_W1 -_sortloop ldy P8ZP_SCRATCH_B1 ;start of subroutine sort - lda (P8ZP_SCRATCH_W1),y ;last value in (what is left of) sequence to be sorted - sta P8ZP_SCRATCH_REG ;save value. will be over-written by largest number - jmp _l2 -_l1 dey - beq _l3 - lda (P8ZP_SCRATCH_W1),y - cmp P8ZP_SCRATCH_W2+1 - bcc _l1 -_l2 sty P8ZP_SCRATCH_W2 ;index of potentially largest value - sta P8ZP_SCRATCH_W2+1 ;potentially largest value - jmp _l1 -_l3 ldy P8ZP_SCRATCH_B1 ;where the largest value shall be put - lda P8ZP_SCRATCH_W2+1 ;the largest value - sta (P8ZP_SCRATCH_W1),y ;put largest value in place - ldy P8ZP_SCRATCH_W2 ;index of free space - lda P8ZP_SCRATCH_REG ;the over-written value - sta (P8ZP_SCRATCH_W1),y ;put the over-written value in the free space - dec P8ZP_SCRATCH_B1 ;end of the shorter sequence still left - bne _sortloop ;start working with the shorter sequence - rts - .pend - - -sort_b .proc - ; 8bit signed sort - ; sorting subroutine coded by mats rosengren (mats.rosengren@esa.int) - ; input: address of array to sort in P8ZP_SCRATCH_W1, length in P8ZP_SCRATCH_B1 - ; first, put pointer BEFORE array - lda P8ZP_SCRATCH_W1 - bne + - dec P8ZP_SCRATCH_W1+1 -+ dec P8ZP_SCRATCH_W1 -_sortloop ldy P8ZP_SCRATCH_B1 ;start of subroutine sort - lda (P8ZP_SCRATCH_W1),y ;last value in (what is left of) sequence to be sorted - sta P8ZP_SCRATCH_REG ;save value. will be over-written by largest number - jmp _l2 -_l1 dey - beq _l3 - lda (P8ZP_SCRATCH_W1),y - cmp P8ZP_SCRATCH_W2+1 - bmi _l1 -_l2 sty P8ZP_SCRATCH_W2 ;index of potentially largest value - sta P8ZP_SCRATCH_W2+1 ;potentially largest value - jmp _l1 -_l3 ldy P8ZP_SCRATCH_B1 ;where the largest value shall be put - lda P8ZP_SCRATCH_W2+1 ;the largest value - sta (P8ZP_SCRATCH_W1),y ;put largest value in place - ldy P8ZP_SCRATCH_W2 ;index of free space - lda P8ZP_SCRATCH_REG ;the over-written value - sta (P8ZP_SCRATCH_W1),y ;put the over-written value in the free space - dec P8ZP_SCRATCH_B1 ;end of the shorter sequence still left - bne _sortloop ;start working with the shorter sequence - rts - .pend - - -sort_uw .proc - ; 16bit unsigned sort - ; sorting subroutine coded by mats rosengren (mats.rosengren@esa.int) - ; input: address of array to sort in P8ZP_SCRATCH_W1, length in P8ZP_SCRATCH_B1 - ; first: subtract 2 of the pointer - asl P8ZP_SCRATCH_B1 ; *2 because words - lda P8ZP_SCRATCH_W1 - sec - sbc #2 - sta P8ZP_SCRATCH_W1 - bcs _sort_loop - dec P8ZP_SCRATCH_W1+1 -_sort_loop ldy P8ZP_SCRATCH_B1 ;start of subroutine sort - lda (P8ZP_SCRATCH_W1),y ;last value in (what is left of) sequence to be sorted - sta _work3 ;save value. will be over-written by largest number - iny - lda (P8ZP_SCRATCH_W1),y - sta _work3+1 - dey - jmp _l2 -_l1 dey - dey - beq _l3 - iny - lda (P8ZP_SCRATCH_W1),y - dey - cmp P8ZP_SCRATCH_W2+1 - bne + - lda (P8ZP_SCRATCH_W1),y - cmp P8ZP_SCRATCH_W2 -+ bcc _l1 -_l2 sty _work1 ;index of potentially largest value - lda (P8ZP_SCRATCH_W1),y - sta P8ZP_SCRATCH_W2 ;potentially largest value - iny - lda (P8ZP_SCRATCH_W1),y - sta P8ZP_SCRATCH_W2+1 - dey - jmp _l1 -_l3 ldy P8ZP_SCRATCH_B1 ;where the largest value shall be put - lda P8ZP_SCRATCH_W2 ;the largest value - sta (P8ZP_SCRATCH_W1),y ;put largest value in place - iny - lda P8ZP_SCRATCH_W2+1 - sta (P8ZP_SCRATCH_W1),y - ldy _work1 ;index of free space - lda _work3 ;the over-written value - sta (P8ZP_SCRATCH_W1),y ;put the over-written value in the free space - iny - lda _work3+1 - sta (P8ZP_SCRATCH_W1),y - dey - dec P8ZP_SCRATCH_B1 ;end of the shorter sequence still left - dec P8ZP_SCRATCH_B1 - bne _sort_loop ;start working with the shorter sequence - rts -_work1 .byte 0 -_work3 .word 0 - .pend - - -sort_w .proc - ; 16bit signed sort - ; sorting subroutine coded by mats rosengren (mats.rosengren@esa.int) - ; input: address of array to sort in P8ZP_SCRATCH_W1, length in P8ZP_SCRATCH_B1 - ; first: subtract 2 of the pointer - asl P8ZP_SCRATCH_B1 ; *2 because words - lda P8ZP_SCRATCH_W1 - sec - sbc #2 - sta P8ZP_SCRATCH_W1 - bcs _sort_loop - dec P8ZP_SCRATCH_W1+1 -_sort_loop ldy P8ZP_SCRATCH_B1 ;start of subroutine sort - lda (P8ZP_SCRATCH_W1),y ;last value in (what is left of) sequence to be sorted - sta _work3 ;save value. will be over-written by largest number - iny - lda (P8ZP_SCRATCH_W1),y - sta _work3+1 - dey - jmp _l2 -_l1 dey - dey - beq _l3 - lda (P8ZP_SCRATCH_W1),y - cmp P8ZP_SCRATCH_W2 - iny - lda (P8ZP_SCRATCH_W1),y - dey - sbc P8ZP_SCRATCH_W2+1 - bvc + - eor #$80 -+ bmi _l1 -_l2 sty _work1 ;index of potentially largest value - lda (P8ZP_SCRATCH_W1),y - sta P8ZP_SCRATCH_W2 ;potentially largest value - iny - lda (P8ZP_SCRATCH_W1),y - sta P8ZP_SCRATCH_W2+1 - dey - jmp _l1 -_l3 ldy P8ZP_SCRATCH_B1 ;where the largest value shall be put - lda P8ZP_SCRATCH_W2 ;the largest value - sta (P8ZP_SCRATCH_W1),y ;put largest value in place - iny - lda P8ZP_SCRATCH_W2+1 - sta (P8ZP_SCRATCH_W1),y - ldy _work1 ;index of free space - lda _work3 ;the over-written value - sta (P8ZP_SCRATCH_W1),y ;put the over-written value in the free space - iny - lda _work3+1 - sta (P8ZP_SCRATCH_W1),y - dey - dec P8ZP_SCRATCH_B1 ;end of the shorter sequence still left - dec P8ZP_SCRATCH_B1 - bne _sort_loop ;start working with the shorter sequence - rts -_work1 .byte 0 -_work3 .word 0 - .pend - - -reverse_b .proc - ; --- reverse an array of bytes (in-place) - ; inputs: pointer to array in P8ZP_SCRATCH_W1, length in A -_index_right = P8ZP_SCRATCH_W2 -_index_left = P8ZP_SCRATCH_W2+1 -_loop_count = P8ZP_SCRATCH_REG - sta _loop_count - lsr _loop_count - sec - sbc #1 - sta _index_right - lda #0 - sta _index_left -_loop ldy _index_right - lda (P8ZP_SCRATCH_W1),y - pha - ldy _index_left - lda (P8ZP_SCRATCH_W1),y - ldy _index_right - sta (P8ZP_SCRATCH_W1),y - pla - ldy _index_left - sta (P8ZP_SCRATCH_W1),y - inc _index_left - dec _index_right - dec _loop_count - bne _loop - rts - .pend - - -reverse_w .proc - ; --- reverse an array of words (in-place) - ; inputs: pointer to array in P8ZP_SCRATCH_W1, length in A -_index_first = P8ZP_SCRATCH_W2 -_index_second = P8ZP_SCRATCH_W2+1 -_loop_count = P8ZP_SCRATCH_REG - pha - asl a ; *2 because words - sec - sbc #2 - sta _index_first - lda #0 - sta _index_second - pla - lsr a - pha - sta _loop_count - ; first reverse the lsbs -_loop_lo ldy _index_first - lda (P8ZP_SCRATCH_W1),y - pha - ldy _index_second - lda (P8ZP_SCRATCH_W1),y - ldy _index_first - sta (P8ZP_SCRATCH_W1),y - pla - ldy _index_second - sta (P8ZP_SCRATCH_W1),y - inc _index_second - inc _index_second - dec _index_first - dec _index_first - dec _loop_count - bne _loop_lo - ; now reverse the msbs - dec _index_second - inc _index_first - inc _index_first - inc _index_first - pla - sta _loop_count -_loop_hi ldy _index_first - lda (P8ZP_SCRATCH_W1),y - pha - ldy _index_second - lda (P8ZP_SCRATCH_W1),y - ldy _index_first - sta (P8ZP_SCRATCH_W1),y - pla - ldy _index_second - sta (P8ZP_SCRATCH_W1),y - dec _index_second - dec _index_second - inc _index_first - inc _index_first - dec _loop_count - bne _loop_hi - - rts - .pend ror2_mem_ub .proc ; -- in-place 8-bit ror of byte at memory location on stack @@ -2091,129 +982,3 @@ _return_minusone lda #-1 rts .pend - - -func_leftstr .proc - ; leftstr(source, target, length) with params on stack - inx - lda P8ESTACK_LO,x - tay ; length - inx - lda P8ESTACK_LO,x - sta P8ZP_SCRATCH_W2 - lda P8ESTACK_HI,x - sta P8ZP_SCRATCH_W2+1 - inx - lda P8ESTACK_LO,x - sta P8ZP_SCRATCH_W1 - lda P8ESTACK_HI,x - sta P8ZP_SCRATCH_W1+1 - lda #0 - sta (P8ZP_SCRATCH_W2),y -- dey - cpy #$ff - bne + - rts -+ lda (P8ZP_SCRATCH_W1),y - sta (P8ZP_SCRATCH_W2),y - jmp - - .pend - -func_rightstr .proc - ; rightstr(source, target, length) with params on stack - ; make place for the 4 parameters for substr() - dex - dex - dex - dex - ; X-> . - ; x+1 -> length of segment - ; x+2 -> start index - ; X+3 -> target LO+HI - ; X+4 -> source LO+HI - ; original parameters: - ; x+5 -> original length LO - ; x+6 -> original targetLO + HI - ; x+7 -> original sourceLO + HI - ; replicate paramters: - lda P8ESTACK_LO+5,x - sta P8ESTACK_LO+1,x - lda P8ESTACK_LO+6,x - sta P8ESTACK_LO+3,x - lda P8ESTACK_HI+6,x - sta P8ESTACK_HI+3,x - lda P8ESTACK_LO+7,x - sta P8ESTACK_LO+4,x - sta P8ZP_SCRATCH_W1 - lda P8ESTACK_HI+7,x - sta P8ESTACK_HI+4,x - sta P8ZP_SCRATCH_W1+1 - ; determine string length - ldy #0 -- lda (P8ZP_SCRATCH_W1),y - beq + - iny - bne - -+ tya - sec - sbc P8ESTACK_LO+1,x ; start index = strlen - segment length - sta P8ESTACK_LO+2,x - jsr func_substr - ; unwind original params - inx - inx - inx - rts - .pend - -func_substr .proc - ; substr(source, target, start, length) with params on stack - inx - ldy P8ESTACK_LO,x ; length - inx - lda P8ESTACK_LO,x ; start - sta P8ZP_SCRATCH_B1 - inx - lda P8ESTACK_LO,x - sta P8ZP_SCRATCH_W2 - lda P8ESTACK_HI,x - sta P8ZP_SCRATCH_W2+1 - inx - lda P8ESTACK_LO,x - sta P8ZP_SCRATCH_W1 - lda P8ESTACK_HI,x - sta P8ZP_SCRATCH_W1+1 - ; adjust src location - clc - lda P8ZP_SCRATCH_W1 - adc P8ZP_SCRATCH_B1 - sta P8ZP_SCRATCH_W1 - bcc + - inc P8ZP_SCRATCH_W1+1 -+ lda #0 - sta (P8ZP_SCRATCH_W2),y - jmp _startloop -- lda (P8ZP_SCRATCH_W1),y - sta (P8ZP_SCRATCH_W2),y -_startloop dey - cpy #$ff - bne - - rts - - .pend - - -func_strcmp .proc - inx - lda P8ESTACK_LO,x - sta P8ZP_SCRATCH_W2 - lda P8ESTACK_HI,x - sta P8ZP_SCRATCH_W2+1 - lda P8ESTACK_HI+1,x - tay - lda P8ESTACK_LO+1,x - jsr strcmp_mem - sta P8ESTACK_LO+1,x - ; make sure A contains the result value as well - rts - .pend diff --git a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt index 40665c880..8127d61d7 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/BuiltinFunctionsAsmGen.kt @@ -70,7 +70,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } "read_flags" -> { if(resultToStack) - asmgen.out(" jsr prog8_lib.func_read_flags") + asmgen.out(" jsr prog8_lib.func_read_flags_stack") else asmgen.out(" php | pla") } @@ -83,9 +83,12 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val "memcopy", "memset", "memsetw" -> funcMemSetCopy(fcall, func) "substr", "leftstr", "rightstr" -> { translateArguments(fcall.args, func) - asmgen.out(" jsr prog8_lib.func_${func.name}_cc") // TODO + asmgen.out(" jsr prog8_lib.func_${func.name}") + } + "exit" -> { + translateArguments(fcall.args, func) + asmgen.out(" jmp prog8_lib.func_exit") } - "exit" -> asmgen.out(" jmp prog8_lib.func_exit") else -> TODO("missing asmgen for builtin func ${func.name}") } } @@ -118,7 +121,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val if((count!=null && count <= 255) || countDt.istype(DataType.UBYTE) || countDt.istype(DataType.BYTE)) { // fast memcopy of up to 255 translateArguments(fcall.args, func) - asmgen.out(" jsr prog8_lib.func_memcopy255_cc") + asmgen.out(" jsr prog8_lib.func_memcopy255") return } @@ -142,7 +145,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val } "memsetw" -> { translateArguments(fcall.args, func) - asmgen.out(" jsr prog8_lib.func_memsetw_cc") + asmgen.out(" jsr prog8_lib.func_memsetw") } } } else { @@ -151,27 +154,27 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val val countDt = fcall.args[2].inferType(program) if((count!=null && count <= 255) || countDt.istype(DataType.UBYTE) || countDt.istype(DataType.BYTE)) { translateArguments(fcall.args, func) - asmgen.out(" jsr prog8_lib.func_memcopy255_cc") + asmgen.out(" jsr prog8_lib.func_memcopy255") return } } translateArguments(fcall.args, func) - asmgen.out(" jsr prog8_lib.func_${func.name}_cc") + asmgen.out(" jsr prog8_lib.func_${func.name}") } } private fun funcStrcmp(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) { translateArguments(fcall.args, func) if(resultToStack) - asmgen.out(" jsr prog8_lib.func_strcmp_cc") // TODO + asmgen.out(" jsr prog8_lib.func_strcmp_stack") else - asmgen.out(" jsr prog8_lib.func_strcmp_into_A") // TODO + asmgen.out(" jsr prog8_lib.func_strcmp") } private fun funcSqrt16(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) { translateArguments(fcall.args, func) if(resultToStack) - asmgen.out(" jsr prog8_lib.func_sqrt16") + asmgen.out(" jsr prog8_lib.func_sqrt16_stack") else asmgen.out(" jsr prog8_lib.func_sqrt16_into_A") } @@ -179,7 +182,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val private fun funcSinCosInt(fcall: IFunctionCall, func: FSignature, resultToStack: Boolean) { translateArguments(fcall.args, func) if(resultToStack) - asmgen.out(" jsr prog8_lib.func_${func.name}_cc") // TODO + asmgen.out(" jsr prog8_lib.func_${func.name}_stack") else when(func.name) { "sin8", "sin8u", "cos8", "cos8u" -> asmgen.out(" jsr prog8_lib.func_${func.name}_into_A") @@ -195,36 +198,31 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val val numElements = decl.arraysize!!.constIndex() when (decl.datatype) { DataType.ARRAY_UB, DataType.ARRAY_B -> { - // TODO cc asmgen.out(""" - lda #<$varName - ldy #>$varName - sta P8ZP_SCRATCH_W1 - sty P8ZP_SCRATCH_W1+1 - lda #$numElements - jsr prog8_lib.reverse_b_cc - """) + lda #<$varName + ldy #>$varName + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + lda #$numElements + jsr prog8_lib.func_reverse_b""") } DataType.ARRAY_UW, DataType.ARRAY_W -> { - // TODO cc asmgen.out(""" - lda #<$varName - ldy #>$varName - sta P8ZP_SCRATCH_W1 - sty P8ZP_SCRATCH_W1+1 - lda #$numElements - jsr prog8_lib.reverse_w_cc - """) + lda #<$varName + ldy #>$varName + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + lda #$numElements + jsr prog8_lib.func_reverse_w""") } DataType.ARRAY_F -> { asmgen.out(""" - lda #<$varName - ldy #>$varName - sta P8ZP_SCRATCH_W1 - sty P8ZP_SCRATCH_W1+1 - lda #$numElements - jsr floats.func_reverse_f - """) + lda #<$varName + ldy #>$varName + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + lda #$numElements + jsr floats.func_reverse_f""") } else -> throw AssemblyError("weird type") } @@ -239,28 +237,22 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val val numElements = decl.arraysize!!.constIndex() when (decl.datatype) { DataType.ARRAY_UB, DataType.ARRAY_B -> { - // TODO cc asmgen.out(""" - lda #<$varName - ldy #>$varName - sta P8ZP_SCRATCH_W1 - sty P8ZP_SCRATCH_W1+1 - lda #$numElements - sta P8ZP_SCRATCH_B1 - """) - asmgen.out(if (decl.datatype == DataType.ARRAY_UB) " jsr prog8_lib.sort_ub_cc" else " jsr prog8_lib.sort_b_cc") + lda #<$varName + ldy #>$varName + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + lda #$numElements""") + asmgen.out(if (decl.datatype == DataType.ARRAY_UB) " jsr prog8_lib.func_sort_ub" else " jsr prog8_lib.func_sort_b") } DataType.ARRAY_UW, DataType.ARRAY_W -> { - // TODO cc asmgen.out(""" - lda #<$varName - ldy #>$varName - sta P8ZP_SCRATCH_W1 - sty P8ZP_SCRATCH_W1+1 - lda #$numElements - sta P8ZP_SCRATCH_B1 - """) - asmgen.out(if (decl.datatype == DataType.ARRAY_UW) " jsr prog8_lib.sort_uw_cc" else " jsr prog8_lib.sort_w_cc") + lda #<$varName + ldy #>$varName + sta P8ZP_SCRATCH_W1 + sty P8ZP_SCRATCH_W1+1 + lda #$numElements""") + asmgen.out(if (decl.datatype == DataType.ARRAY_UW) " jsr prog8_lib.func_sort_uw" else " jsr prog8_lib.func_sort_w") } DataType.ARRAY_F -> throw AssemblyError("sorting of floating point array is not supported") else -> throw AssemblyError("weird type") @@ -299,9 +291,10 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.UWORD -> { when (what) { is ArrayIndexedExpression -> { + // TODO cc asmgen.translateExpression(what.arrayvar) asmgen.translateExpression(what.indexer) - asmgen.out(" jsr prog8_lib.ror2_array_uw") + asmgen.out(" jsr prog8_lib.ror2_array_uw_cc") } is IdentifierReference -> { val variable = asmgen.asmVariableName(what) @@ -321,15 +314,17 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.UBYTE -> { when (what) { is ArrayIndexedExpression -> { + // TODO cc asmgen.translateExpression(what.arrayvar) asmgen.translateExpression(what.indexer) - asmgen.out(" jsr prog8_lib.ror_array_ub") + asmgen.out(" jsr prog8_lib.ror_array_ub_cc") } is DirectMemoryRead -> { if (what.addressExpression is NumericLiteralValue) { val number = (what.addressExpression as NumericLiteralValue).number asmgen.out(" ror ${number.toHex()}") } else { + // TODO cc asmgen.translateExpression(what.addressExpression) asmgen.out(""" inx @@ -351,9 +346,10 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.UWORD -> { when (what) { is ArrayIndexedExpression -> { + // TODO cc asmgen.translateExpression(what.arrayvar) asmgen.translateExpression(what.indexer) - asmgen.out(" jsr prog8_lib.ror_array_uw") + asmgen.out(" jsr prog8_lib.ror_array_uw_cc") } is IdentifierReference -> { val variable = asmgen.asmVariableName(what) @@ -373,17 +369,19 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.UBYTE -> { when (what) { is ArrayIndexedExpression -> { + // TODO cc asmgen.translateExpression(what.arrayvar) asmgen.translateExpression(what.indexer) - asmgen.out(" jsr prog8_lib.rol2_array_ub") + asmgen.out(" jsr prog8_lib.rol2_array_ub_cc") } is DirectMemoryRead -> { if (what.addressExpression is NumericLiteralValue) { val number = (what.addressExpression as NumericLiteralValue).number asmgen.out(" lda ${number.toHex()} | cmp #\$80 | rol a | sta ${number.toHex()}") } else { + // TODO cc asmgen.translateExpression(what.addressExpression) - asmgen.out(" jsr prog8_lib.rol2_mem_ub") + asmgen.out(" jsr prog8_lib.rol2_mem_ub_cc") } } is IdentifierReference -> { @@ -396,9 +394,10 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.UWORD -> { when (what) { is ArrayIndexedExpression -> { + // TODO cc asmgen.translateExpression(what.arrayvar) asmgen.translateExpression(what.indexer) - asmgen.out(" jsr prog8_lib.rol2_array_uw") + asmgen.out(" jsr prog8_lib.rol2_array_uw_cc") } is IdentifierReference -> { val variable = asmgen.asmVariableName(what) @@ -418,15 +417,17 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.UBYTE -> { when (what) { is ArrayIndexedExpression -> { + // TODO cc asmgen.translateExpression(what.arrayvar) asmgen.translateExpression(what.indexer) - asmgen.out(" jsr prog8_lib.rol_array_ub") + asmgen.out(" jsr prog8_lib.rol_array_ub_cc") } is DirectMemoryRead -> { if (what.addressExpression is NumericLiteralValue) { val number = (what.addressExpression as NumericLiteralValue).number asmgen.out(" rol ${number.toHex()}") } else { + // TODO cc asmgen.translateExpression(what.addressExpression) asmgen.out(""" inx @@ -448,9 +449,10 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val DataType.UWORD -> { when (what) { is ArrayIndexedExpression -> { + // TODO cc asmgen.translateExpression(what.arrayvar) asmgen.translateExpression(what.indexer) - asmgen.out(" jsr prog8_lib.rol_array_uw") + asmgen.out(" jsr prog8_lib.rol_array_uw_cc") } is IdentifierReference -> { val variable = asmgen.asmVariableName(what) @@ -476,19 +478,19 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val val dt = fcall.args.single().inferType(program) if(resultToStack) { when (dt.typeOrElse(DataType.STRUCT)) { - DataType.UBYTE -> asmgen.out(" jsr math.sign_ub_cc") - DataType.BYTE -> asmgen.out(" jsr math.sign_b_cc") - DataType.UWORD -> asmgen.out(" jsr math.sign_uw_cc") - DataType.WORD -> asmgen.out(" jsr math.sign_w_cc") + DataType.UBYTE -> asmgen.out(" jsr prog8_lib.func_sign_ub_stack") + DataType.BYTE -> asmgen.out(" jsr prog8_lib.func_sign_b_stack") + DataType.UWORD -> asmgen.out(" jsr prog8_lib.func_sign_uw_stack") + DataType.WORD -> asmgen.out(" jsr prog8_lib.func_sign_w_stack") DataType.FLOAT -> asmgen.out(" jsr floats.func_sign_f_stack") else -> throw AssemblyError("weird type $dt") } } else { when (dt.typeOrElse(DataType.STRUCT)) { - DataType.UBYTE -> asmgen.out(" jsr math.sign_ub_into_A") - DataType.BYTE -> asmgen.out(" jsr math.sign_b_into_A") - DataType.UWORD -> asmgen.out(" jsr math.sign_uw_into_A") - DataType.WORD -> asmgen.out(" jsr math.sign_w_into_A") + DataType.UBYTE -> asmgen.out(" jsr prog8_lib.func_sign_ub_into_A") + DataType.BYTE -> asmgen.out(" jsr prog8_lib.func_sign_b_into_A") + DataType.UWORD -> asmgen.out(" jsr prog8_lib.func_sign_uw_into_A") + DataType.WORD -> asmgen.out(" jsr prog8_lib.func_sign_w_into_A") DataType.FLOAT -> asmgen.out(" jsr floats.func_sign_f_into_A") else -> throw AssemblyError("weird type $dt") } @@ -500,8 +502,8 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val val dt = fcall.args.single().inferType(program) if(resultToStack) { when (dt.typeOrElse(DataType.STRUCT)) { - DataType.ARRAY_B, DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${function.name}_b_cc") - DataType.ARRAY_UW, DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${function.name}_w_cc") + DataType.ARRAY_B, DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${function.name}_b_stack") + DataType.ARRAY_UW, DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${function.name}_w_stack") DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${function.name}_f_stack") else -> throw AssemblyError("weird type $dt") } @@ -520,10 +522,10 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val val dt = fcall.args.single().inferType(program) if(resultToStack) { when (dt.typeOrElse(DataType.STRUCT)) { - DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${function.name}_ub_cc") - DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_${function.name}_b_cc") - DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_${function.name}_uw_cc") - DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${function.name}_w_cc") + DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_${function.name}_ub_stack") + DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_${function.name}_b_stack") + DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_${function.name}_uw_stack") + DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_${function.name}_w_stack") DataType.ARRAY_F -> asmgen.out(" jsr floats.func_${function.name}_f_stack") else -> throw AssemblyError("weird type $dt") } @@ -544,10 +546,10 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val val dt = fcall.args.single().inferType(program) if(resultToStack) { when (dt.typeOrElse(DataType.STRUCT)) { - DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_sum_ub_cc") - DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_sum_b_cc") - DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_sum_uw_cc") - DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_sum_w_cc") + DataType.ARRAY_UB, DataType.STR -> asmgen.out(" jsr prog8_lib.func_sum_ub_stack") + DataType.ARRAY_B -> asmgen.out(" jsr prog8_lib.func_sum_b_stack") + DataType.ARRAY_UW -> asmgen.out(" jsr prog8_lib.func_sum_uw_stack") + DataType.ARRAY_W -> asmgen.out(" jsr prog8_lib.func_sum_w_stack") DataType.ARRAY_F -> asmgen.out(" jsr floats.func_sum_f_stack") else -> throw AssemblyError("weird type $dt") } @@ -567,18 +569,14 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val val name = asmgen.asmVariableName(fcall.args[0] as IdentifierReference) val type = fcall.args[0].inferType(program) when { - type.istype(DataType.STR) -> { - asmgen.out(" lda #<$name | ldy #>$name | jsr prog8_lib.strlen") - if(resultToStack) - asmgen.out(" sta P8ESTACK_LO,x | dex") - } - type.istype(DataType.UWORD) -> { - asmgen.out(" lda $name | ldy $name+1 | jsr prog8_lib.strlen") - if(resultToStack) - asmgen.out(" sta P8ESTACK_LO,x | dex") - } + type.istype(DataType.STR) -> asmgen.out(" lda #<$name | ldy #>$name") + type.istype(DataType.UWORD) -> asmgen.out(" lda $name | ldy $name+1") else -> throw AssemblyError("strlen requires str or uword arg") } + if(resultToStack) + asmgen.out(" jsr prog8_lib.func_strlen_stack") + else + asmgen.out(" jsr prog8_lib.func_strlen_into_A") } private fun funcSwap(fcall: IFunctionCall) { @@ -943,15 +941,15 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val val dt = fcall.args.single().inferType(program).typeOrElse(DataType.STRUCT) if(resultToStack) { when (dt) { - in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b_cc") - in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w_cc") + in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b_stack") + in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w_stack") DataType.FLOAT -> asmgen.out(" jsr floats.abs_f_stack") else -> throw AssemblyError("weird type") } } else { when (dt) { - in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b_into_A_cc") - in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w_into_AY_cc") + in ByteDatatypes -> asmgen.out(" jsr prog8_lib.abs_b_into_A") + in WordDatatypes -> asmgen.out(" jsr prog8_lib.abs_w_into_AY") DataType.FLOAT -> asmgen.out(" jsr floats.abs_f_fac1") else -> throw AssemblyError("weird type") } @@ -962,13 +960,13 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val when(func.name) { "rnd" -> { if(resultToStack) - asmgen.out(" jsr prog8_lib.func_rnd") + asmgen.out(" jsr prog8_lib.func_rnd_stack") else asmgen.out(" jsr math.randbyte") } "rndw" -> { if(resultToStack) - asmgen.out(" jsr prog8_lib.func_rndw") + asmgen.out(" jsr prog8_lib.func_rndw_stack") else asmgen.out(" jsr math.randword") } @@ -1080,7 +1078,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val val value = it.first.first when { conv.variable -> { - val varname = "prog8_lib.func_${signature.name}_cc._arg_${paramName}" // TODO after all builtin funcs have been changed into _cc, remove that suffix again + val varname = "prog8_lib.func_${signature.name}._arg_${paramName}" val src = when (conv.dt) { DataType.FLOAT -> getSourceForFloat(value) in PassByReferenceDatatypes -> { diff --git a/docs/source/programming.rst b/docs/source/programming.rst index b9e4c7a04..71e78296f 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -785,11 +785,13 @@ memsetw(address, numwords, wordvalue) leftstr(source, target, length) Copies the left side of the source string of the given length to target string. It is assumed the target string buffer is large enough to contain the result. + Also, you have to make sure yourself that length is smaller or equal to the length of the source string. Modifies in-place, doesn't return a value (so can't be used in an expression). rightstr(source, target, length) Copies the right side of the source string of the given length to target string. It is assumed the target string buffer is large enough to contain the result. + Also, you have to make sure yourself that length is smaller or equal to the length of the source string. Modifies in-place, doesn't return a value (so can't be used in an expression). strlen(str) @@ -806,6 +808,7 @@ substr(source, target, start, length) Copies a segment from the source string, starting at the given index, and of the given length to target string. It is assumed the target string buffer is large enough to contain the result. + Also, you have to make sure yourself that start and length are within bounds of the strings. Modifies in-place, doesn't return a value (so can't be used in an expression). Miscellaneous diff --git a/examples/test.p8 b/examples/test.p8 index d0f6bab57..209f080c1 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,92 +4,415 @@ %zeropage basicsafe ; builtin functions converted to new call convention: +; ; all functions operating on floating-point and fp arrays. ; ; mkword ; lsb ; msb +; swap +; abs +; sgn +; sqrt16 +; rnd, rndw +; sin8, sin8u, cos8, cos8u +; sin16, sin16u, cos16, cos16u +; max, min +; any, all +; sum +; sort +; reverse + +; exit +; read_flags +; memset, memsetw, memcopy +; leftstr, rightstr, substr +; strlen, strcmp + +; TODO: in-place rols and rors main { sub start() { - ubyte[] barr = [1,2,3,4,5,0,4,3,2,1] + const uword ADDR = $0400 + const uword ADDR2 = $4000 + +; memset(ADDR2, 40*25, '*') +; memset(ADDR2, 40, '1') +; memset(ADDR2+24*40, 39, '2') +; memsetw(ADDR2, 40*25/2, $3132) +; memsetw(ADDR2, 20, $4142) +; memsetw(ADDR2+24*40, 19, $4241) +; memcopy(ADDR2, ADDR, 200) + + str result = "." *10 + str s1 = "irmen" + str s2 = "hello" + + ubyte ub + byte bb + ubyte zero=0 + + + + bb = strcmp(s1, s2) + txt.print_b(bb) + txt.chrout('\n') + txt.print_ub(s1==s2) + txt.chrout('\n') + txt.print_ub(s1