# E01-S02: build the isolated C128 MMU/common-RAM proof. [CmdletBinding()] param() $ErrorActionPreference = "Stop" $project = Split-Path $PSScriptRoot -Parent $build = Join-Path $project "build" $source = Join-Path $project "src\platform\mmu-probe.s" $config = Join-Path $project "cfg\mmu-probe-c128.cfg" $object = Join-Path $build "mmu-probe.o" $program = Join-Path $build "mmu-probe.prg" $map = Join-Path $build "mmu-probe.map" $labels = Join-Path $build "mmu-probe.lbl" $debug = Join-Path $build "mmu-probe.dbg" $listing = Join-Path $build "mmu-probe.lst" $ca65 = (Get-Command ca65 -ErrorAction Stop).Source $ld65 = (Get-Command ld65 -ErrorAction Stop).Source New-Item -ItemType Directory -Force -Path $build | Out-Null foreach ($path in @($object, $program, $map, $labels, $debug, $listing)) { if (Test-Path -LiteralPath $path) { Remove-Item -LiteralPath $path -Force } } & $ca65 --cpu 6502 --debug-info -l $listing -o $object $source if ($LASTEXITCODE -ne 0) { throw "ca65 failed with exit code $LASTEXITCODE" } & $ld65 -C $config -o $program -m $map -Ln $labels --dbgfile $debug $object if ($LASTEXITCODE -ne 0) { throw "ld65 failed with exit code $LASTEXITCODE" } $bytes = [IO.File]::ReadAllBytes($program) if ($bytes.Length -lt 16) { throw "mmu-probe.prg is unexpectedly short" } if ($bytes[0] -ne 0x01 -or $bytes[1] -ne 0x1C) { throw "mmu-probe.prg load address is not `$1C01" } $expectedHeader = [byte[]](0x0B,0x1C,0x0A,0x00,0x9E,0x37,0x31,0x38,0x31,0x00,0x00,0x00) for ($i = 0; $i -lt $expectedHeader.Length; $i++) { if ($bytes[$i + 2] -ne $expectedHeader[$i]) { throw ("BASIC header differs at file offset {0}" -f ($i + 2)) } } # The last loaded byte must remain below $2000, the end of the selected 8K # bottom-common window. File bytes after the two-byte load address begin $1C01. $lastAddress = 0x1C01 + ($bytes.Length - 2) - 1 if ($lastAddress -ge 0x2000) { throw ("probe ends at `${0:X4}, outside bottom common RAM" -f $lastAddress) } $labelText = Get-Content -Raw -LiteralPath $labels foreach ($name in @( 'mmu_probe_entry','mmu_probe_done','mmu_probe_result','mmu_probe_complete', 'mmu_probe_observed_bank0','mmu_probe_observed_bank1', 'mmu_probe_observed_p0','mmu_probe_observed_p1')) { if ($labelText -notmatch ("(?im)^al\s+[0-9a-f]+\s+\." + [regex]::Escape($name) + "\s*$")) { throw "missing exported linker label $name" } } Write-Host ("built {0} ({1} bytes, ends `${2:X4})" -f $program, $bytes.Length, $lastAddress) Write-Host ("map {0}" -f $map) Write-Host ("labels {0}" -f $labels)