|
- # E04-S01: run the PRG/MAP writer test in x128, inspect the disk artifacts,
- # and autostart the generated PRG to prove the startup path and termination.
- [CmdletBinding()]
- param(
- [int]$Port = 6530,
- [int]$RunPort = 6531,
- [int]$TimeoutSeconds = 90
- )
-
- $ErrorActionPreference = "Stop"
- $project = Split-Path $PSScriptRoot -Parent
- Import-Module (Join-Path $PSScriptRoot "lib\Nova128Test.psm1") -Force
- & (Join-Path $PSScriptRoot "build-output-test.ps1")
-
- $out = Join-Path $project "build\output-test"
- $disk = Join-Path $out "output-test.d81"
- $c1541 = Get-ViceTool "c1541"
-
- $session = Start-Nova128X128 -Autostart $disk -Drive8Image $disk -Port $Port `
- -Screenshot (Join-Path $out "output-test-vicii.png")
- try {
- $mb = Wait-Nova128Mailbox $session -TimeoutSeconds $TimeoutSeconds
- } finally {
- Stop-Nova128X128 $session
- }
- Write-Host ('mailbox: ' + (($mb | ForEach-Object { $_.ToString('X2') }) -join ' '))
- Write-Host ('results: finish={0} collision={1} order={2} abort={3}' -f $mb[8], $mb[9], $mb[10], $mb[11])
-
- $failures = @()
- if ($mb[2] -ne 0x01) { $failures += "producer $($mb[2]) is not the platform test" }
- if ($mb[3] -ne 0xA5) { $failures += "fixture status is not PASS" }
- $want = @(0, 1, 2, 0)
- for ($i = 0; $i -lt $want.Count; $i++) {
- if ($mb[8 + $i] -ne $want[$i]) {
- $failures += "result $i is $($mb[8 + $i]), expected $($want[$i])"
- }
- }
- if ($mb[4] -ne 0 -or $mb[5] -ne 0) {
- $failures += "code is $($mb[4] + 256 * $mb[5])"
- }
-
- function Read-DiskFile([string]$Name, [string]$Dest, [bool]$Seq) {
- if (Test-Path -LiteralPath $Dest) { Remove-Item -LiteralPath $Dest -Force }
- $spec = if ($Seq) { "$Name,s" } else { $Name }
- & $c1541 -attach $disk -read $spec $Dest 2>&1 | Out-Null
- if (-not (Test-Path -LiteralPath $Dest)) { throw "could not read $Name from the test disk" }
- }
-
- $prgPath = Join-Path $out "generate.prg"
- $mapPath = Join-Path $out "generate.map"
- $collidePrg = Join-Path $out "collide-check.prg"
- $collideMap = Join-Path $out "collide-check.map"
- Read-DiskFile "generate.prg" $prgPath $false
- Read-DiskFile "generate.map" $mapPath $true
- Read-DiskFile "collide.prg" $collidePrg $false
- Read-DiskFile "collide.map" $collideMap $true
-
- $bytes = [IO.File]::ReadAllBytes($prgPath)
- if ($bytes.Length -ne 133) { $failures += "GENERATE.PRG is $($bytes.Length) bytes, expected 133" }
- if ($bytes[0] -ne 0x01 -or $bytes[1] -ne 0x1C) {
- $failures += ("load address is ${0:X2}{1:X2}, expected 011C" -f $bytes[1], $bytes[0])
- }
- $stub = [byte[]](0x0B, 0x1C, 0x0A, 0x00, 0x9E, 0x37, 0x31, 0x38, 0x31, 0x00, 0x00, 0x00)
- for ($i = 0; $i -lt $stub.Length; $i++) {
- if ($bytes[2 + $i] -ne $stub[$i]) {
- $failures += ("BASIC stub byte {0} is {1:X2}, expected {2:X2}" -f $i, $bytes[2 + $i], $stub[$i])
- }
- }
- $padOffset = 2 + (0x1C80 - 0x1C01)
- $pad = @(0xDE, 0xAD, 0xBE, 0xEF)
- for ($i = 0; $i -lt $pad.Count; $i++) {
- if ($bytes[$padOffset + $i] -ne $pad[$i]) {
- $failures += ("PAD byte {0} is {1:X2}, expected {2:X2}" -f $i, $bytes[$padOffset + $i], $pad[$i])
- }
- }
- for ($i = 2 + 12 + 80; $i -lt $padOffset; $i++) {
- if ($bytes[$i] -ne 0) { $failures += "gap byte at $i is not zero"; break }
- }
-
- $mapLines = ([IO.File]::ReadAllText($mapPath)).TrimEnd("`r", "`n") -split "`r`n|`r|`n"
- $expectedMap = @(
- "NOVA128 MAP 1",
- "ENTRY 1C0D",
- "SECTION STUB 1C01 000C",
- "SECTION START 1C0D 004A",
- "SECTION PAD 1C80 0004")
- if (($mapLines -join "`n") -ne ($expectedMap -join "`n")) {
- $failures += ("GENERATE.MAP differs:`n got: " + ($mapLines -join "`n ") +
- "`n want: " + ($expectedMap -join "`n "))
- }
-
- $keep = [Text.Encoding]::ASCII.GetString([IO.File]::ReadAllBytes($collidePrg))
- if ($keep -cne "KEEP") { $failures += "COLLIDE.PRG changed to '$keep'" }
- $keepMap = [Text.Encoding]::ASCII.GetString([IO.File]::ReadAllBytes($collideMap)).TrimEnd("`r", "`n")
- if ($keepMap -cne "KEEPMAP") { $failures += "COLLIDE.MAP changed to '$keepMap'" }
-
- $listing = (& $c1541 -attach $disk -list 2>&1) -join "`n"
- foreach ($absent in @("abort.prg", "abort.map", "order.prg", "order.map")) {
- if ($listing -match ('"' + [regex]::Escape($absent) + '"')) {
- $failures += "$absent exists after abort/failure"
- }
- }
-
- if ($failures) { throw ("output verification failed:`n " + ($failures -join "`n ")) }
-
- # ---------------------------------------------------------- generated run
- $run = Start-Nova128X128 -Autostart $prgPath -Port $RunPort
- try {
- $gmb = Wait-Nova128Mailbox $run -TimeoutSeconds $TimeoutSeconds
- } finally {
- Stop-Nova128X128 $run
- }
- if ($gmb[2] -ne 0x03) { throw "generated producer is $($gmb[2]), expected 3" }
- if ($gmb[3] -ne 0xA5) { throw "generated program did not report PASS" }
- if ($gmb[4] -ne 0 -or $gmb[5] -ne 0) { throw "generated code is $($gmb[4] + 256 * $gmb[5])" }
- for ($i = 8; $i -lt 16; $i++) {
- if ($gmb[$i] -ne 0) { throw "generated data byte $i is not zero" }
- }
-
- Write-Host "verified PRG header, BASIC stub, PAD section, and MAP:"
- $expectedMap | ForEach-Object { Write-Host " |$_" }
- Write-Host "COLLIDE.PRG/MAP unchanged; ABORT/ORDER left no output"
- Write-Host "generated PRG autostarted: producer 3, PASS, code 0"
- Write-Host "PRG bytes: $($bytes.Length); screenshots not requested"
|