# E01-S04: build the independent C128 display/clock probe. [CmdletBinding()] param() $ErrorActionPreference = "Stop" $project = Split-Path $PSScriptRoot -Parent $build = Join-Path $project "build" $source = Join-Path $project "src\platform\display-clock.s" $config = Join-Path $project "cfg\display-clock-c128.cfg" $object = Join-Path $build "display-clock.o" $program = Join-Path $build "display-clock.prg" $map = Join-Path $build "display-clock.map" $labels = Join-Path $build "display-clock.lbl" $debug = Join-Path $build "display-clock.dbg" $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)) { if (Test-Path -LiteralPath $path) { Remove-Item -LiteralPath $path -Force } } # VDC register access would make semantic storage/display behavior ambiguous. $sourceText = Get-Content -Raw -LiteralPath $source $codeOnly = ($sourceText -split "`n" | ForEach-Object { ($_ -split ';', 2)[0] }) -join "`n" if ($codeOnly -match '(?i)\$D60[01]') { throw "display/clock probe must not access VDC address/data registers" } & $ca65 --cpu 6502 --debug-info -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 "display-clock.prg is unexpectedly short" } if ($bytes[0] -ne 0x01 -or $bytes[1] -ne 0x1C) { throw "display-clock.prg load address is not `$1C01" } $labelText = Get-Content -Raw -LiteralPath $labels $expectedLabels = @{ display_clock_entry = '001C0D' mode_40_checkpoint = '001C2E' mode_80_checkpoint = '001C3D' fast_checkpoint = '001C49' fallback_done = '001C8C' display_result = '001D0F' mode_observed = '001D10' fast_observed = '001D11' final_clock = '001D12' semantic_a = '001D13' semantic_b = '001D14' } foreach ($item in $expectedLabels.GetEnumerator()) { $pattern = "(?im)^al\s+" + $item.Value + "\s+\." + [regex]::Escape($item.Key) + "\s*$" if ($labelText -notmatch $pattern) { throw ("linker label {0} did not resolve to `${1}" -f $item.Key, $item.Value.Substring(2)) } } Write-Host ("built {0} ({1} bytes)" -f $program, $bytes.Length) Write-Host ("map {0}" -f $map) Write-Host ("labels {0}" -f $labels)