From 2de919a22534600f20f1e299ef33d991c07fa914 Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Thu, 2 Nov 2023 17:03:40 -0500 Subject: [PATCH] hacked in "incbin" for C files, c64 lz4 example --- presets/c64/image-c64.multi.lz4 | Bin 0 -> 7156 bytes presets/c64/testlz4.c | 49 ++++++++++++++++++++++++++++++++ src/common/util.ts | 3 ++ src/ide/project.ts | 4 +-- src/platform/c64.ts | 1 + src/worker/tools/cc65.ts | 33 +++++++++++++++++++-- 6 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 presets/c64/image-c64.multi.lz4 create mode 100644 presets/c64/testlz4.c diff --git a/presets/c64/image-c64.multi.lz4 b/presets/c64/image-c64.multi.lz4 new file mode 100644 index 0000000000000000000000000000000000000000..309957c090019184afa9a0a639068821b62dc9ac GIT binary patch literal 7156 zcmWl84_Fgtw)c5wGRe#^l0O7gS~XzNFruKXeOzi~#JWqfZH>r)PPJmU?k7`QwfDB& z_3NJ)p(J z0-2eYnfILYJHPWg@0jwRobjC0dGkJi@m!wgRk==4jc6=Zci=!YogV+f-`L2%!0q3! z>$+hWNl_Hl-710ON?~CvCK@~+GYBk>#i|LU>`M6Fy&mIi^4z!4DBc4

Q->P{1&n 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 YLLe{<{vb5be2RJ+|KiTYlgU~CA4CyXkN^Mx literal 0 HcmV?d00001 diff --git a/presets/c64/testlz4.c b/presets/c64/testlz4.c new file mode 100644 index 00000000..50a0e704 --- /dev/null +++ b/presets/c64/testlz4.c @@ -0,0 +1,49 @@ + +// sid config so we don't use stack above $8000 + +//#resource "c64-sid.cfg" +#define CFGFILE c64-sid.cfg + +#include "common.h" +//#link "common.c" + +#include "mcbitmap.h" +//#link "mcbitmap.c" + +#include + +// include the LZ4 binary data -> image_c64_multi_lz4[] + +//#incbin "image-c64.multi.lz4" + +/* +CharData equ . +ScreenData equ CharData+8000 +ColorData equ ScreenData+1000 +XtraData equ ColorData+1000 +*/ + +void main() { + char* const uncomp = (char*)0xb000; + char bgcolor; + + // setup VIC for multicolor bitmap + // colormap = $c000-$c7ff + // bitmap = $e000-$ffff + setup_bitmap_multi(); + // enable HIMEM so we can write to $c000-$ffff + ENABLE_HIMEM(); + // decompress into $8000-$a711 + decompress_lz4(image_c64_multi_lz4+11, uncomp, 10002); + // read background color + bgcolor = uncomp[10000]; + // copy data to destination areas + memcpy((void*)MCB_BITMAP, uncomp, 8000); + memcpy(COLOR_RAM, uncomp+9000, 1000); + memcpy((void*)MCB_COLORS, uncomp+8000, 1000); + DISABLE_HIMEM(); + // set background color + VIC.bgcolor0 = bgcolor; + // wait for key + cgetc(); +} diff --git a/src/common/util.ts b/src/common/util.ts index d2687958..db372cf6 100644 --- a/src/common/util.ts +++ b/src/common/util.ts @@ -424,6 +424,9 @@ export function clamp(minv:number, maxv:number, v:number) { } export function safeident(s : string) : string { + // if starts with non-alpha character, prefix with '_' + if (s.length == 0) return ''; + if (!s.match(/^[a-zA-Z_]/)) s = '_' + s; return s.replace(/\W+/g, "_"); } diff --git a/src/ide/project.ts b/src/ide/project.ts index 83b42ab0..c9451257 100644 --- a/src/ide/project.ts +++ b/src/ide/project.ts @@ -200,9 +200,9 @@ export class CodeProject { this.pushAllFiles(files, m[2]); } // for .c -- //#resource "file" (or ;resource or #resource) - let re3 = /^\s*([;']|[/][/])#resource\s+"(.+?)"/gm; + let re3 = /^\s*([;']|[/][/])#(resource|incbin)\s+"(.+?)"/gm; while (m = re3.exec(text)) { - this.pushAllFiles(files, m[2]); + this.pushAllFiles(files, m[3]); } // for XASM only (USE include.ext) // for merlin32 (ASM include.ext) diff --git a/src/platform/c64.ts b/src/platform/c64.ts index 0c4e5505..65847938 100644 --- a/src/platform/c64.ts +++ b/src/platform/c64.ts @@ -23,6 +23,7 @@ const C64_PRESETS = [ {id:'test_multispritelib.c', name:'Sprite Multiplexing Library'}, {id:'scrolling_text.c', name:'Big Scrolling Text'}, {id:'mcbitmap.c', name:'Multicolor Bitmap Mode'}, + {id:'testlz4.c', name:'LZ4 Bitmap Compression'}, //{id:'mandel.c', name:'Mandelbrot Fractal'}, {id:'musicplayer.c', name:'Music Player'}, //{id:'sidtune.dasm', name:'Tiny SID Tune (ASM)'}, diff --git a/src/worker/tools/cc65.ts b/src/worker/tools/cc65.ts index 460aa5fd..383225ae 100644 --- a/src/worker/tools/cc65.ts +++ b/src/worker/tools/cc65.ts @@ -1,5 +1,5 @@ -import { getFilenamePrefix, getRootBasePlatform } from "../../common/util"; +import { convertDataToUint8Array, getFilenamePrefix, getRootBasePlatform, safeident } from "../../common/util"; import { CodeListingMap, WorkerError } from "../../common/workertypes"; import { re_crlf, BuildStepResult, anyTargetChanged, execMain, gatherFiles, msvcErrorMatcher, populateEntry, populateExtraFiles, populateFiles, print_fn, putWorkFile, setupFS, staleFiles, BuildStep, emglobal, loadNative, moduleInstFn, fixParamsWithDefines, store, makeErrorMatcher, getWorkFileAsString } from "../workermain"; import { EmscriptenModule } from "../workermain" @@ -272,6 +272,27 @@ export function linkLD65(step: BuildStep): BuildStepResult { } } +function processIncbin(code: string) { + let re3 = /^\s*([;']|[/][/])#incbin\s+"(.+?)"/gm; + // find #incbin "filename.bin" and replace with C array declaration + return code.replace(re3, (m, m1, m2) => { + let filename = m2; + let filedata = store.getFileData(filename); + let bytes = convertDataToUint8Array(filedata); + if (!bytes) throw new Error('#incbin: file not found: "' + filename + '"'); + let out = ''; + let ident = safeident(filename); + console.log('#incbin', filename, ident, bytes.length); + out += 'const unsigned char ' + ident + '[' + bytes.length + '] = {'; + for (let i = 0; i < bytes.length; i++) { + out += bytes[i].toString() + ','; + } + out += '};'; + console.log('incbin', out); + return out; + }); +} + export function compileCC65(step: BuildStep): BuildStepResult { loadNative("cc65"); var params = step.params; @@ -303,7 +324,15 @@ export function compileCC65(step: BuildStep): BuildStepResult { }); var FS = CC65.FS; setupFS(FS, '65-' + getRootBasePlatform(step.platform)); - populateFiles(step, FS); + populateFiles(step, FS, { + mainFilePath: step.path, + processFn: (path, code) => { + if (typeof code === 'string') { + code = processIncbin(code); + } + return code; + } + }); fixParamsWithDefines(step.path, params); var args = [ '-I', '/share/include',