1
0
mirror of https://gitlab.com/camelot/kickc.git synced 2024-09-08 17:54:40 +00:00

Moved routines into stdlib.

This commit is contained in:
jespergravgaard 2019-06-24 00:22:23 +02:00
parent 20ec350ca5
commit 048d87b251
7 changed files with 961 additions and 945 deletions

37
src/main/kc/stdlib/sqr.kc Normal file
View File

@ -0,0 +1,37 @@
// Table-based implementation of integer square sqr() and square root sqrt()
import "stdlib"
// The number of squares to pre-calculate. Limits what values sqr() can calculate and the result of sqrt()
byte NUM_SQUARES = 0xff;
// Squares for each byte value SQUARES[i] = i*i
// Initialized by init_squares()
word* SQUARES;
// Initialize squares table
// Uses iterative formula (x+1)^2 = x^2 + 2*x + 1
void init_squares() {
SQUARES = (word*)malloc(NUM_SQUARES*sizeof(word));
word* squares = SQUARES;
word sqr = 0;
for( byte i: 0..NUM_SQUARES-1) {
*squares++ = sqr;
sqr += i*2+1;
}
}
// Find the square of a byte value
// Uses a table of squares that must be initialized by calling init_squares()
word sqr(byte val) {
return SQUARES[val];
}
// Find the (integer) square root of a word value
// If the square is not an integer then it returns the largest integer N where N*N <= val
// Uses a table of squares that must be initialized by calling init_squares()
byte sqrt(word val) {
word* found = bsearch16u(val, SQUARES, NUM_SQUARES);
byte sq = (byte)((byte*)found-(byte*)SQUARES)/2;
return sq;
}

View File

@ -17,4 +17,25 @@ unsigned char* malloc(unsigned int size) {
// A block of memory previously allocated by a call to malloc is deallocated, making it available again for further allocations.
// If ptr is a null pointer, the function does nothing.
void free(unsigned char* ptr) {
}
// Searches an array of nitems unsigned words, the initial member of which is pointed to by base, for a member that matches the value key.
// - key - The value to look for
// - items - Pointer to the start of the array to search in
// - num - The number of items in the array
// Returns pointer to an entry in the array that matches the search key
word* bsearch16u(word key, word* items, byte num) {
while (num > 0) {
word* pivot = items + (num >> 1);
signed word result = (signed word)key-(signed word)*pivot;
if (result == 0)
return pivot;
if (result > 0) {
items = pivot+1;
num--;
}
num >>= 1;
}
// not found - return closest lower value
return *items<=key?items:items-1;
}

View File

@ -1,6 +1,7 @@
// Calculate the distance to the center of the screen - and show it using font-hex
import "stdlib"
import "sqr"
import "c64"
import "font-hex"
@ -28,59 +29,4 @@ void main() {
*screen++ = d;
}
}
}
// The number of squares to pre-calculate. Limits what values sqr() can calculate and the result of sqrt()
byte NUM_SQUARES = 0xff;
// Squares for each byte value SQUARES[i] = i*i
// Initialized by init_squares()
word* SQUARES;
// Initialize squares table
// Uses iterative formula (x+1)^2 = x^2 + 2*x + 1
void init_squares() {
SQUARES = malloc(NUM_SQUARES*sizeof(word));
word* squares = SQUARES;
word sqr = 0;
for( byte i: 0..NUM_SQUARES-1) {
*squares++ = sqr;
sqr += i*2+1;
}
}
// Find the square of a byte value
// Uses a table of squares that must be initialized by calling init_squares()
word sqr(byte val) {
return SQUARES[val];
}
// Find the (integer) square root of a word value
// If the square is not an integer then it returns the largest integer N where N*N <= val
// Uses a table of squares that must be initialized by calling init_squares()
byte sqrt(word val) {
word* found = bsearch16u(val, SQUARES, NUM_SQUARES);
byte sqr1 = (byte)((byte*)found-(byte*)SQUARES)/2;
return sqr1;
}
// Searches an array of nitems unsigned words, the initial member of which is pointed to by base, for a member that matches the value key.
// - key - The value to look for
// - items - Pointer to the start of the array to search in
// - num - The number of items in the array
// Returns pointer to an entry in the array that matches the search key
word* bsearch16u(word key, word* items, byte num) {
while (num > 0) {
word* pivot = items + (num >> 1);
signed word result = (signed word)key-(signed word)*pivot;
if (result == 0)
return pivot;
if (result > 0) {
items = pivot+1;
num--;
}
num >>= 1;
}
// not found - return closest lower value
return *items<=key?items:items-1;
}

View File

@ -9,6 +9,7 @@
.label CHARSET = $2000
.label SCREEN = $2800
.const NUM_SQUARES = $30
.label SQUARES = HEAP_START
main: {
.const toD0181_return = (>(SCREEN&$3fff)*4)|(>CHARSET)/4&$f
.label yds = $16
@ -37,10 +38,10 @@ main: {
adc #$18+1
b4:
jsr sqr
lda sqr.return_2
sta sqr.return
lda sqr.return_2+1
sta sqr.return+1
lda sqr.return
sta sqr.return_2
lda sqr.return+1
sta sqr.return_2+1
lda #0
sta x
b5:
@ -91,15 +92,15 @@ main: {
// sqrt(word zeropage($18) val)
sqrt: {
.label _3 = 6
.label val = $18
.label found = 6
.label val = $18
jsr bsearch16u
lda _3
sec
sbc #<HEAP_START
sbc #<SQUARES
sta _3
lda _3+1
sbc #>HEAP_START
sbc #>SQUARES
sta _3+1
lda _3
lsr
@ -113,14 +114,14 @@ sqrt: {
// bsearch16u(word zeropage($18) key, word* zeropage(6) items, byte register(X) num)
bsearch16u: {
.label _2 = 6
.label key = $18
.label return = 6
.label pivot = $1a
.label result = $1c
.label return = 6
.label items = 6
lda #<HEAP_START
.label key = $18
lda #<SQUARES
sta items
lda #>HEAP_START
lda #>SQUARES
sta items+1
ldx #NUM_SQUARES
b3:
@ -197,15 +198,14 @@ bsearch16u: {
// Uses a table of squares that must be initialized by calling init_squares()
// sqr(byte register(A) val)
sqr: {
.label return = $16
.label return_1 = $18
.label return_2 = $18
.label return = $18
.label return_2 = $16
asl
tay
lda HEAP_START,y
sta return_2
lda #0
sta return_2+1
lda SQUARES,y
sta return
lda SQUARES+1,y
sta return+1
rts
}
// Initialize squares table
@ -215,9 +215,9 @@ init_squares: {
.label sqr = 9
jsr malloc
ldx #0
lda #<HEAP_START
lda #<SQUARES
sta squares
lda #>HEAP_START
lda #>SQUARES
sta squares+1
txa
sta sqr

View File

@ -31,10 +31,10 @@ main::@4: scope:[main] from main::@2 main::@3
[13] (byte) main::yd#0 ← phi( main::@2/(byte~) main::$8 main::@3/(byte~) main::$6 )
[14] (byte) sqr::val#0 ← (byte) main::yd#0
[15] call sqr
[16] (word) sqr::return#0 ← (word) sqr::return#2
[16] (word) sqr::return#2 ← (word) sqr::return#0
to:main::@11
main::@11: scope:[main] from main::@4
[17] (word) main::yds#0 ← (word) sqr::return#0
[17] (word) main::yds#0 ← (word) sqr::return#2
to:main::@5
main::@5: scope:[main] from main::@11 main::@13
[18] (byte*) main::screen#2 ← phi( main::@11/(byte*) main::screen#10 main::@13/(byte*) main::screen#1 )
@ -49,17 +49,17 @@ main::@8: scope:[main] from main::@6 main::@7
[22] (byte) main::xd#0 ← phi( main::@6/(byte~) main::$16 main::@7/(byte~) main::$14 )
[23] (byte) sqr::val#1 ← (byte) main::xd#0
[24] call sqr
[25] (word) sqr::return#1 ← (word) sqr::return#2
[25] (word) sqr::return#3 ← (word) sqr::return#0
to:main::@12
main::@12: scope:[main] from main::@8
[26] (word) main::xds#0 ← (word) sqr::return#1
[26] (word) main::xds#0 ← (word) sqr::return#3
[27] (word) main::ds#0 ← (word) main::xds#0 + (word) main::yds#0
[28] (word) sqrt::val#0 ← (word) main::ds#0
[29] call sqrt
[30] (byte) sqrt::return#0 ← (byte) sqrt::return#1
[30] (byte) sqrt::return#2 ← (byte) sqrt::return#0
to:main::@13
main::@13: scope:[main] from main::@12
[31] (byte) main::d#0 ← (byte) sqrt::return#0
[31] (byte) main::d#0 ← (byte) sqrt::return#2
[32] *((byte*) main::screen#2) ← (byte) main::d#0
[33] (byte*) main::screen#1 ← ++ (byte*) main::screen#2
[34] (byte) main::x#1 ← ++ (byte) main::x#2
@ -81,13 +81,13 @@ main::@2: scope:[main] from main::@1
sqrt: scope:[sqrt] from main::@12
[41] (word) bsearch16u::key#0 ← (word) sqrt::val#0
[42] call bsearch16u
[43] (word*) bsearch16u::return#0 ← (word*) bsearch16u::return#2
[43] (word*) bsearch16u::return#3 ← (word*) bsearch16u::return#1
to:sqrt::@1
sqrt::@1: scope:[sqrt] from sqrt
[44] (word*) sqrt::found#0 ← (word*) bsearch16u::return#0
[45] (word~) sqrt::$3 ← (byte*)(word*) sqrt::found#0 - (const byte*) HEAP_START#0
[44] (word*) sqrt::found#0 ← (word*) bsearch16u::return#3
[45] (word~) sqrt::$3 ← (byte*)(word*) sqrt::found#0 - (byte*)(const word*) SQUARES#1
[46] (byte~) sqrt::$4 ← (byte)(word~) sqrt::$3
[47] (byte) sqrt::return#1 ← (byte~) sqrt::$4 >> (byte) 1
[47] (byte) sqrt::return#0 ← (byte~) sqrt::$4 >> (byte) 1
to:sqrt::@return
sqrt::@return: scope:[sqrt] from sqrt::@1
[48] return
@ -96,8 +96,8 @@ bsearch16u: scope:[bsearch16u] from sqrt
[49] phi()
to:bsearch16u::@3
bsearch16u::@3: scope:[bsearch16u] from bsearch16u bsearch16u::@7
[50] (word*) bsearch16u::items#2 ← phi( bsearch16u/(const byte*) HEAP_START#0 bsearch16u::@7/(word*) bsearch16u::items#8 )
[50] (byte) bsearch16u::num#3 ← phi( bsearch16u/(const byte) NUM_SQUARES#0 bsearch16u::@7/(byte) bsearch16u::num#1 )
[50] (word*) bsearch16u::items#2 ← phi( bsearch16u/(const word*) SQUARES#1 bsearch16u::@7/(word*) bsearch16u::items#8 )
[50] (byte) bsearch16u::num#3 ← phi( bsearch16u/(const byte) NUM_SQUARES#1 bsearch16u::@7/(byte) bsearch16u::num#0 )
[51] if((byte) bsearch16u::num#3>(byte) 0) goto bsearch16u::@4
to:bsearch16u::@5
bsearch16u::@5: scope:[bsearch16u] from bsearch16u::@3
@ -107,10 +107,10 @@ bsearch16u::@1: scope:[bsearch16u] from bsearch16u::@5
[53] (word*~) bsearch16u::$2 ← (word*) bsearch16u::items#2 - (byte) 1*(const byte) SIZEOF_WORD
to:bsearch16u::@2
bsearch16u::@2: scope:[bsearch16u] from bsearch16u::@1 bsearch16u::@5
[54] (word*) bsearch16u::return#3 ← phi( bsearch16u::@5/(word*) bsearch16u::items#2 bsearch16u::@1/(word*~) bsearch16u::$2 )
[54] (word*) bsearch16u::return#2 ← phi( bsearch16u::@5/(word*) bsearch16u::items#2 bsearch16u::@1/(word*~) bsearch16u::$2 )
to:bsearch16u::@return
bsearch16u::@return: scope:[bsearch16u] from bsearch16u::@2 bsearch16u::@8
[55] (word*) bsearch16u::return#2 ← phi( bsearch16u::@8/(word*~) bsearch16u::return#6 bsearch16u::@2/(word*) bsearch16u::return#3 )
[55] (word*) bsearch16u::return#1 ← phi( bsearch16u::@8/(word*~) bsearch16u::return#6 bsearch16u::@2/(word*) bsearch16u::return#2 )
[56] return
to:@return
bsearch16u::@4: scope:[bsearch16u] from bsearch16u::@3
@ -127,18 +127,18 @@ bsearch16u::@6: scope:[bsearch16u] from bsearch16u::@4
[63] if((signed word) bsearch16u::result#0<=(signed byte) 0) goto bsearch16u::@7
to:bsearch16u::@9
bsearch16u::@9: scope:[bsearch16u] from bsearch16u::@6
[64] (word*) bsearch16u::items#1 ← (word*) bsearch16u::pivot#0 + (byte) 1*(const byte) SIZEOF_WORD
[65] (byte) bsearch16u::num#2 ← -- (byte) bsearch16u::num#3
[64] (word*) bsearch16u::items#0 ← (word*) bsearch16u::pivot#0 + (byte) 1*(const byte) SIZEOF_WORD
[65] (byte) bsearch16u::num#1 ← -- (byte) bsearch16u::num#3
to:bsearch16u::@7
bsearch16u::@7: scope:[bsearch16u] from bsearch16u::@6 bsearch16u::@9
[66] (word*) bsearch16u::items#8 ← phi( bsearch16u::@9/(word*) bsearch16u::items#1 bsearch16u::@6/(word*) bsearch16u::items#2 )
[66] (byte) bsearch16u::num#5 ← phi( bsearch16u::@9/(byte) bsearch16u::num#2 bsearch16u::@6/(byte) bsearch16u::num#3 )
[67] (byte) bsearch16u::num#1 ← (byte) bsearch16u::num#5 >> (byte) 1
[66] (word*) bsearch16u::items#8 ← phi( bsearch16u::@9/(word*) bsearch16u::items#0 bsearch16u::@6/(word*) bsearch16u::items#2 )
[66] (byte) bsearch16u::num#5 ← phi( bsearch16u::@9/(byte) bsearch16u::num#1 bsearch16u::@6/(byte) bsearch16u::num#3 )
[67] (byte) bsearch16u::num#0 ← (byte) bsearch16u::num#5 >> (byte) 1
to:bsearch16u::@3
sqr: scope:[sqr] from main::@4 main::@8
[68] (byte) sqr::val#2 ← phi( main::@4/(byte) sqr::val#0 main::@8/(byte) sqr::val#1 )
[69] (byte~) sqr::$0 ← (byte) sqr::val#2 << (byte) 1
[70] (word) sqr::return#2 ← *((const byte*) HEAP_START#0 + (byte~) sqr::$0)
[70] (word) sqr::return#0 ← *((const word*) SQUARES#1 + (byte~) sqr::$0)
to:sqr::@return
sqr::@return: scope:[sqr] from sqr
[71] return
@ -149,15 +149,15 @@ init_squares: scope:[init_squares] from main::@10
to:init_squares::@1
init_squares::@1: scope:[init_squares] from init_squares init_squares::@1
[74] (byte) init_squares::i#2 ← phi( init_squares::@1/(byte) init_squares::i#1 init_squares/(byte) 0 )
[74] (word*) init_squares::squares#2 ← phi( init_squares::@1/(word*) init_squares::squares#1 init_squares/(const byte*) HEAP_START#0 )
[74] (word*) init_squares::squares#2 ← phi( init_squares::@1/(word*) init_squares::squares#1 init_squares/(const word*) SQUARES#1 )
[74] (word) init_squares::sqr#2 ← phi( init_squares::@1/(word) init_squares::sqr#1 init_squares/(byte) 0 )
[75] *((word*) init_squares::squares#2) ← (word) init_squares::sqr#2
[76] (word*) init_squares::squares#1 ← (word*) init_squares::squares#2 + (const byte) SIZEOF_WORD
[77] (byte~) init_squares::$3 ← (byte) init_squares::i#2 << (byte) 1
[78] (byte~) init_squares::$4 ← (byte~) init_squares::$3 + (byte) 1
[79] (word) init_squares::sqr#1 ← (word) init_squares::sqr#2 + (byte~) init_squares::$4
[77] (byte~) init_squares::$4 ← (byte) init_squares::i#2 << (byte) 1
[78] (byte~) init_squares::$5 ← (byte~) init_squares::$4 + (byte) 1
[79] (word) init_squares::sqr#1 ← (word) init_squares::sqr#2 + (byte~) init_squares::$5
[80] (byte) init_squares::i#1 ← ++ (byte) init_squares::i#2
[81] if((byte) init_squares::i#1!=(const byte) NUM_SQUARES#0-(byte) 1+(byte) 1) goto init_squares::@1
[81] if((byte) init_squares::i#1!=(const byte) NUM_SQUARES#1-(byte) 1+(byte) 1) goto init_squares::@1
to:init_squares::@return
init_squares::@return: scope:[init_squares] from init_squares::@1
[82] return

File diff suppressed because it is too large Load Diff

View File

@ -10,11 +10,12 @@
(byte*) HEAP_START
(const byte*) HEAP_START#0 HEAP_START = (byte*) 49152
(byte) NUM_SQUARES
(const byte) NUM_SQUARES#0 NUM_SQUARES = (byte) $30
(const byte) NUM_SQUARES#1 NUM_SQUARES = (byte) $30
(byte*) SCREEN
(const byte*) SCREEN#0 SCREEN = (byte*) 10240
(const byte) SIZEOF_WORD SIZEOF_WORD = (byte) 2
(word*) SQUARES
(const word*) SQUARES#1 SQUARES = (word*)(const byte*) HEAP_START#0
(word*()) bsearch16u((word) bsearch16u::key , (word*) bsearch16u::items , (byte) bsearch16u::num)
(byte~) bsearch16u::$16 reg byte a 2002.0
(word*~) bsearch16u::$2 $2 zp ZP_WORD:6 4.0
@ -30,14 +31,14 @@
(label) bsearch16u::@9
(label) bsearch16u::@return
(word*) bsearch16u::items
(word*) bsearch16u::items#1 items zp ZP_WORD:6 1001.0
(word*) bsearch16u::items#0 items zp ZP_WORD:6 1001.0
(word*) bsearch16u::items#2 items zp ZP_WORD:6 334.33333333333337
(word*) bsearch16u::items#8 items zp ZP_WORD:6 1501.5
(word) bsearch16u::key
(word) bsearch16u::key#0 key zp ZP_WORD:24 0.2857142857142857
(byte) bsearch16u::num
(byte) bsearch16u::num#0 reg byte x 2002.0
(byte) bsearch16u::num#1 reg byte x 2002.0
(byte) bsearch16u::num#2 reg byte x 2002.0
(byte) bsearch16u::num#3 reg byte x 556.1111111111111
(byte) bsearch16u::num#5 reg byte x 3003.0
(word*) bsearch16u::pivot
@ -45,9 +46,9 @@
(signed word) bsearch16u::result
(signed word) bsearch16u::result#0 result zp ZP_WORD:28 1501.5
(word*) bsearch16u::return
(word*) bsearch16u::return#0 return zp ZP_WORD:6 4.0
(word*) bsearch16u::return#2 return zp ZP_WORD:6 2.0
(word*) bsearch16u::return#3 return zp ZP_WORD:6 6.0
(word*) bsearch16u::return#1 return zp ZP_WORD:6 2.0
(word*) bsearch16u::return#2 return zp ZP_WORD:6 6.0
(word*) bsearch16u::return#3 return zp ZP_WORD:6 4.0
(word*~) bsearch16u::return#6 return zp ZP_WORD:6 4.0
(byte*) heap_head
(void()) init_font_hex((byte*) init_font_hex::charset)
@ -84,8 +85,8 @@
(byte*) init_font_hex::proto_lo#1 proto_lo zp ZP_WORD:18 50.5
(byte*) init_font_hex::proto_lo#4 proto_lo zp ZP_WORD:18 92.53846153846155
(void()) init_squares()
(byte~) init_squares::$3 reg byte a 22.0
(byte~) init_squares::$4 reg byte a 22.0
(byte~) init_squares::$5 reg byte a 22.0
(label) init_squares::@1
(label) init_squares::@return
(byte) init_squares::i
@ -165,9 +166,9 @@
(byte~) sqr::$0 reg byte a 4.0
(label) sqr::@return
(word) sqr::return
(word) sqr::return#0 return zp ZP_WORD:22 22.0
(word) sqr::return#1 return#1 zp ZP_WORD:24 202.0
(word) sqr::return#2 return#2 zp ZP_WORD:24 28.5
(word) sqr::return#0 return zp ZP_WORD:24 28.5
(word) sqr::return#2 return#2 zp ZP_WORD:22 22.0
(word) sqr::return#3 return zp ZP_WORD:24 202.0
(byte) sqr::val
(byte) sqr::val#0 reg byte a 22.0
(byte) sqr::val#1 reg byte a 202.0
@ -180,9 +181,9 @@
(word*) sqrt::found
(word*) sqrt::found#0 found zp ZP_WORD:6 2.0
(byte) sqrt::return
(byte) sqrt::return#0 reg byte a 202.0
(byte) sqrt::return#1 reg byte a 34.33333333333333
(byte) sqrt::sqr1
(byte) sqrt::return#0 reg byte a 34.33333333333333
(byte) sqrt::return#2 reg byte a 202.0
(byte) sqrt::sq
(word) sqrt::val
(word) sqrt::val#0 val zp ZP_WORD:24 103.0
@ -191,8 +192,8 @@ reg byte a [ main::yd#0 main::$8 main::$6 ]
zp ZP_BYTE:3 [ main::x#2 main::x#1 ]
zp ZP_WORD:4 [ main::screen#2 main::screen#10 main::screen#1 ]
reg byte a [ main::xd#0 main::$16 main::$14 ]
zp ZP_WORD:6 [ bsearch16u::return#2 bsearch16u::return#6 bsearch16u::return#3 bsearch16u::items#2 bsearch16u::items#8 bsearch16u::$2 bsearch16u::items#1 bsearch16u::return#0 sqrt::found#0 sqrt::$3 ]
reg byte x [ bsearch16u::num#5 bsearch16u::num#2 bsearch16u::num#3 bsearch16u::num#1 ]
zp ZP_WORD:6 [ bsearch16u::return#1 bsearch16u::return#6 bsearch16u::return#2 bsearch16u::items#2 bsearch16u::items#8 bsearch16u::$2 bsearch16u::items#0 bsearch16u::return#3 sqrt::found#0 sqrt::$3 ]
reg byte x [ bsearch16u::num#5 bsearch16u::num#1 bsearch16u::num#3 bsearch16u::num#0 ]
reg byte a [ sqr::val#2 sqr::val#0 sqr::val#1 ]
zp ZP_WORD:9 [ init_squares::sqr#2 init_squares::sqr#1 ]
zp ZP_WORD:11 [ init_squares::squares#2 init_squares::squares#1 ]
@ -205,20 +206,20 @@ zp ZP_BYTE:20 [ init_font_hex::c1#4 init_font_hex::c1#1 ]
reg byte x [ init_font_hex::i#2 init_font_hex::i#1 ]
zp ZP_BYTE:21 [ init_font_hex::idx#5 init_font_hex::idx#2 ]
reg byte a [ main::y2#0 ]
zp ZP_WORD:22 [ sqr::return#0 main::yds#0 ]
zp ZP_WORD:22 [ sqr::return#2 main::yds#0 ]
reg byte a [ main::x2#0 ]
zp ZP_WORD:24 [ sqr::return#1 main::xds#0 sqr::return#2 main::ds#0 sqrt::val#0 bsearch16u::key#0 ]
reg byte a [ sqrt::return#0 ]
zp ZP_WORD:24 [ sqr::return#3 main::xds#0 sqr::return#0 main::ds#0 sqrt::val#0 bsearch16u::key#0 ]
reg byte a [ sqrt::return#2 ]
reg byte a [ main::d#0 ]
reg byte a [ sqrt::$4 ]
reg byte a [ sqrt::return#1 ]
reg byte a [ sqrt::return#0 ]
reg byte a [ bsearch16u::$6 ]
reg byte a [ bsearch16u::$16 ]
zp ZP_WORD:26 [ bsearch16u::pivot#0 ]
zp ZP_WORD:28 [ bsearch16u::result#0 ]
reg byte a [ sqr::$0 ]
reg byte a [ init_squares::$3 ]
reg byte a [ init_squares::$4 ]
reg byte a [ init_squares::$5 ]
zp ZP_BYTE:30 [ init_font_hex::$0 ]
reg byte a [ init_font_hex::$1 ]
reg byte a [ init_font_hex::$2 ]