|
- # 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)
|