# build-ml.ps1 - assemble vml.s with cc65 and generate vml.c, the Power C unit # that carries the machine code as a byte array plus its C wrappers. # # powershell -NoProfile -File build-ml.ps1 # # Run it whenever vml.s or vmlwrap.c changes, then build.ps1 as usual. # vml.c is generated: edit vml.s (the code) or vmlwrap.c (the C side). # # The code is assembled for $C000. At start-up mlinit() calls highmem($C000) so # Power C keeps below it, and copies the array up there. Entry addresses come # from ld65's label file and are written into vml.c as #defines. $ErrorActionPreference = "Stop" $here = $PSScriptRoot $ca65 = (Get-Command ca65 -ErrorAction SilentlyContinue).Source if (-not $ca65) { throw "ca65 not found on PATH (cc65 bin folder)" } $ld65 = Join-Path (Split-Path $ca65) "ld65.exe" $tmp = Join-Path $env:TEMP "vml-build" New-Item -ItemType Directory -Force -Path $tmp | Out-Null $cfg = Join-Path $tmp "vml.cfg" @" MEMORY { M: start = `$C000, size = `$0400, file = "%O"; } SEGMENTS { CODE: load = M, type = ro; } "@ | Set-Content $cfg -Encoding ascii $obj = Join-Path $tmp "vml.o" $lbl = Join-Path $tmp "vml.lbl" $out = Join-Path $here "vml.bin" & $ca65 (Join-Path $here "vml.s") -o $obj if ($LASTEXITCODE) { throw "ca65 failed" } & $ld65 -C $cfg -o $out -Ln $lbl $obj if ($LASTEXITCODE) { throw "ld65 failed" } # entry points: "al 00C000 .scrn" $defs = @() foreach ($ln in (Get-Content $lbl)) { if ($ln -match '^al\s+([0-9A-Fa-f]+)\s+\.(scrn|row|bmove|ladj|kpop)$') { $defs += ("#define ML{0} 0x{1}" -f $matches[2].ToUpper(), $matches[1].Substring(2).ToLower()) } } if ($defs.Count -ne 5) { throw "expected 5 entry labels in $lbl, got $($defs.Count)" } $b = [IO.File]::ReadAllBytes($out) $rows = @() for ($i = 0; $i -lt $b.Length; $i += 12) { $n = [Math]::Min(12, $b.Length - $i) $rows += " " + (($b[$i..($i + $n - 1)] | ForEach-Object { "$_" }) -join ", ") } $arr = $rows -join ",`n" $wrap = Get-Content (Join-Path $here "vmlwrap.c") -Raw @" /* vml.c - GENERATED by build-ml.ps1 from vml.s and vmlwrap.c. Do not edit. * * The machine code helpers as a byte array. mlinit() copies them to `$C000. */ $($defs -join "`n") #define MLSIZE $($b.Length) char mlcode[$($b.Length)] = { $arr }; $wrap "@ | Set-Content (Join-Path $here "vml.c") -Encoding ascii Write-Host ("vml.bin {0} bytes -> vml.c ({1})" -f $b.Length, ($defs -join '; '))