# E01-S03: build the C128 KERNAL wrapper probe and its test disk. [CmdletBinding()] param() $ErrorActionPreference = "Stop" $project = Split-Path $PSScriptRoot -Parent $build = Join-Path $project "build" $source = Join-Path $project "src\platform\kernal-probe.s" $config = Join-Path $project "cfg\kernal-probe-c128.cfg" $object = Join-Path $build "kernal-probe.o" $program = Join-Path $build "kernal-probe.prg" $map = Join-Path $build "kernal-probe.map" $labels = Join-Path $build "kernal-probe.lbl" $debug = Join-Path $build "kernal-probe.dbg" $listing = Join-Path $build "kernal-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 "kernal-probe.prg is unexpectedly short" } if ($bytes[0] -ne 0x01 -or $bytes[1] -ne 0x1C) { throw "kernal-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 @( 'kprobe_entry','kprobe_done','kprobe_result','kprobe_complete', 'kprobe_state_result','kprobe_fail_a','kprobe_fail_p','kprobe_fail_st', 'kprobe_status_buf','kprobe_code_end','kcall')) { if ($labelText -notmatch ("(?im)^al\s+[0-9a-f]+\s+\." + [regex]::Escape($name) + "\s*$")) { throw "missing exported linker label $name" } } # The drive-8 success path needs a real disk: a fresh D64 holding only the # probe, so autostart loads it through true drive emulation. $c1541 = "C:\Program Files\GTK3VICE-3.10-win64\bin\c1541.exe" if (-not (Test-Path -LiteralPath $c1541)) { throw "c1541.exe not found at $c1541" } $disk = Join-Path $build "kernal-probe.d64" if (Test-Path -LiteralPath $disk) { Remove-Item -LiteralPath $disk -Force } & $c1541 -format "kprobe,kp" d64 $disk -write $program "kernal-probe" | Out-Null if ($LASTEXITCODE -ne 0 -or -not (Test-Path -LiteralPath $disk)) { throw "c1541 could not create $disk" } Write-Host ("built {0} ({1} bytes, ends `${2:X4})" -f $program, $bytes.Length, $lastAddress) Write-Host ("disk {0}" -f $disk) Write-Host ("map {0}" -f $map) Write-Host ("labels {0}" -f $labels)