From 3132790ab5a3450bdc064ec7de9ec42f2e0e3c8a Mon Sep 17 00:00:00 2001 From: jespergravgaard Date: Tue, 21 May 2019 00:33:36 +0200 Subject: [PATCH] Added very naive heap implementation. --- .../dk/camelot64/kickc/test/TestPrograms.java | 5 ++ src/test/kc/memory-heap.kc | 34 ++++++++++ src/test/ref/memory-heap.asm | 66 +++++++++++++++++++ 3 files changed, 105 insertions(+) create mode 100644 src/test/kc/memory-heap.kc create mode 100644 src/test/ref/memory-heap.asm diff --git a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java index 39ac64c0b..4a2357ddc 100644 --- a/src/test/java/dk/camelot64/kickc/test/TestPrograms.java +++ b/src/test/java/dk/camelot64/kickc/test/TestPrograms.java @@ -68,6 +68,11 @@ public class TestPrograms { compileAndCompare("hex2dec"); } + @Test + public void testMemoryHeap() throws IOException, URISyntaxException { + compileAndCompare("memory-heap"); + } + @Test public void testTernaryInference() throws IOException, URISyntaxException { compileAndCompare("ternary-inference"); diff --git a/src/test/kc/memory-heap.kc b/src/test/kc/memory-heap.kc new file mode 100644 index 000000000..2fa915342 --- /dev/null +++ b/src/test/kc/memory-heap.kc @@ -0,0 +1,34 @@ +// Experiments with malloc() + +void main() { + unsigned char* buf1 = (unsigned char*) malloc(100); + unsigned char* buf2 = (unsigned char*) malloc(100); + for(unsigned char i:0..99) { + buf1[i] = i; + buf2[i] = 255-i; + } + free(buf1); + free(buf2); + unsigned char* screen = 0x0400; + screen[0] = *buf1; + screen[1] = *buf2; +} + +// Start of the heap used by malloc() +unsigned char* HEAP_START = 0xc000; + +// Head of the heap. Moved forward for each malloc() +unsigned char* heap_head = HEAP_START; + +// Allocates a block of size bytes of memory, returning a pointer to the beginning of the block. +// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values. +unsigned char* malloc(unsigned int size) { + unsigned char* mem = heap_head; + heap_head+= size; + return mem; +} + +// 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) { +} \ No newline at end of file diff --git a/src/test/ref/memory-heap.asm b/src/test/ref/memory-heap.asm new file mode 100644 index 000000000..769942503 --- /dev/null +++ b/src/test/ref/memory-heap.asm @@ -0,0 +1,66 @@ +// Experiments with malloc() +.pc = $801 "Basic" +:BasicUpstart(main) +.pc = $80d "Program" + // Start of the heap used by malloc() + .label HEAP_START = $c000 + .label heap_head = 2 +main: { + .label screen = $400 + .label buf1 = 4 + .label buf2 = 6 + lda #HEAP_START + sta heap_head+1 + jsr malloc + lda malloc.return_2 + sta malloc.return + lda malloc.return_2+1 + sta malloc.return+1 + jsr malloc + ldy #0 + b1: + tya + sta (buf1),y + tya + eor #$ff + clc + adc #$ff+1 + sta (buf2),y + iny + cpy #$64 + bne b1 + jsr free + jsr free + ldy #0 + lda (buf1),y + sta screen + lda (buf2),y + sta screen+1 + rts +} +// 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. +free: { + rts +} +// Allocates a block of size bytes of memory, returning a pointer to the beginning of the block. +// The content of the newly allocated block of memory is not initialized, remaining with indeterminate values. +malloc: { + .label return = 4 + .label return_1 = 6 + .label return_2 = 6 + lda heap_head + sta return_2 + lda heap_head+1 + sta return_2+1 + lda #$64 + clc + adc heap_head + sta heap_head + bcc !+ + inc heap_head+1 + !: + rts +}