Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

131 строка
5.2KB

  1. # E01-S05: prove cfg/compiler.cfg capacity checks, then run the map skeleton
  2. # in VICE x128 and verify the fixed test mailbox at $1BF0.
  3. [CmdletBinding()]
  4. param(
  5. [int]$RemotePort = 6513,
  6. [int]$TimeoutSeconds = 30
  7. )
  8. $ErrorActionPreference = "Stop"
  9. $project = Split-Path $PSScriptRoot -Parent
  10. $build = Join-Path $project "build"
  11. $program = Join-Path $build "map-skeleton.prg"
  12. $screenshot = Join-Path $build "map-skeleton-vicii.png"
  13. $x128 = "C:\Program Files\GTK3VICE-3.10-win64\bin\x128.exe"
  14. $mailbox = 0x1BF0
  15. # 1. Every bounded region must reject an overflow at link time.
  16. foreach ($region in "ZP", "COMMON", "MAIN", "SWSTACK", "TABLES") {
  17. & (Join-Path $PSScriptRoot "build-map-skeleton.ps1") -Overflow $region
  18. }
  19. # 2. The real skeleton.
  20. & (Join-Path $PSScriptRoot "build-map-skeleton.ps1")
  21. if (-not (Test-Path -LiteralPath $x128)) { throw "x128.exe not found at $x128" }
  22. if (Test-Path -LiteralPath $screenshot) { Remove-Item -LiteralPath $screenshot -Force }
  23. $arguments = @(
  24. "-autostart", ('"' + $program + '"'),
  25. "-autostart-warp", "-warp", "-sounddev", "dummy",
  26. "-exitscreenshotvicii", ('"' + $screenshot + '"'),
  27. "-remotemonitor", "-remotemonitoraddress", ("ip4://127.0.0.1:{0}" -f $RemotePort)
  28. ) -join ' '
  29. $psi = [Diagnostics.ProcessStartInfo]::new()
  30. $psi.FileName = $x128
  31. $psi.Arguments = $arguments
  32. $psi.UseShellExecute = $true
  33. $psi.WindowStyle = [Diagnostics.ProcessWindowStyle]::Hidden
  34. $process = [Diagnostics.Process]::Start($psi)
  35. $client = $null
  36. function Read-Available($stream) {
  37. $buffer = New-Object byte[] 16384
  38. $text = ""
  39. Start-Sleep -Milliseconds 300
  40. while ($stream.DataAvailable) {
  41. $count = $stream.Read($buffer, 0, $buffer.Length)
  42. if ($count -le 0) { break }
  43. $text += [Text.Encoding]::ASCII.GetString($buffer, 0, $count)
  44. Start-Sleep -Milliseconds 50
  45. }
  46. return $text
  47. }
  48. function Convert-Dump([string]$text) {
  49. $memory = @{}
  50. $rows = [regex]::Matches($text, "(?i)C:([0-9a-f]{4})((?:[ ]{1,2}[0-9a-f]{2}){1,16})")
  51. foreach ($row in $rows) {
  52. $address = [Convert]::ToInt32($row.Groups[1].Value, 16)
  53. foreach ($hex in ($row.Groups[2].Value.Trim() -split '\s+')) {
  54. $memory[$address] = [Convert]::ToInt32($hex, 16)
  55. $address++
  56. }
  57. }
  58. return $memory
  59. }
  60. try {
  61. $deadline = [DateTime]::UtcNow.AddSeconds(10)
  62. while ([DateTime]::UtcNow -lt $deadline) {
  63. if ($process.HasExited) { throw "x128 exited before remote verification" }
  64. try {
  65. $client = [Net.Sockets.TcpClient]::new()
  66. $client.Connect("127.0.0.1", $RemotePort)
  67. break
  68. } catch {
  69. if ($client) { $client.Dispose(); $client = $null }
  70. Start-Sleep -Milliseconds 200
  71. }
  72. }
  73. if (-not $client -or -not $client.Connected) { throw "could not connect to VICE remote monitor" }
  74. $stream = $client.GetStream()
  75. $writer = [IO.StreamWriter]::new($stream, [Text.Encoding]::ASCII, 1024, $true)
  76. $writer.NewLine = "`n"
  77. $writer.AutoFlush = $true
  78. # Mailbox protocol: magic "N8", then status leaves RUNNING ($01).
  79. $memory = @{}
  80. $deadline = [DateTime]::UtcNow.AddSeconds($TimeoutSeconds)
  81. while ($true) {
  82. Start-Sleep -Seconds 1
  83. $writer.WriteLine(("m `${0:X4} `${1:X4}" -f $mailbox, ($mailbox + 15)))
  84. $chunk = Read-Available $stream
  85. $memory = Convert-Dump $chunk
  86. $magic = ($memory[$mailbox] -eq 0x4E -and $memory[$mailbox + 1] -eq 0x38)
  87. if ($magic -and $memory[$mailbox + 3] -in 0xA5, 0xFA) { break }
  88. if ([DateTime]::UtcNow -ge $deadline) {
  89. throw "mailbox never reached a final status; last response: $chunk"
  90. }
  91. $writer.WriteLine("x")
  92. Read-Available $stream | Out-Null
  93. }
  94. $writer.WriteLine("x")
  95. Start-Sleep -Seconds 2 # let the OK line print
  96. $writer.WriteLine("m 0000 0000")
  97. Read-Available $stream | Out-Null
  98. $bytes = 0..15 | ForEach-Object { "{0:X2}" -f $memory[$mailbox + $_] }
  99. $code = $memory[$mailbox + 4] + 256 * $memory[$mailbox + 5]
  100. $writer.WriteLine("quit")
  101. $writer.Dispose(); $client.Dispose(); $client = $null
  102. if (-not $process.WaitForExit(10000)) { throw "x128 did not exit after monitor quit" }
  103. Write-Host ("mailbox `$1BF0: {0}" -f ($bytes -join ' '))
  104. $checks = @(@(0x01, "ZP"), @(0x02, "KCALL"), @(0x04, "BANK1"), @(0x08, "NMI"),
  105. @(0x10, "COMMON"), @(0x20, "RESTORE"))
  106. $failed = @($checks | Where-Object { $code -band $_[0] } | ForEach-Object { $_[1] })
  107. if ($memory[$mailbox + 2] -ne 0x01) { throw "producer is not the platform skeleton" }
  108. if ($memory[$mailbox + 3] -ne 0xA5 -or $code -ne 0) {
  109. throw ("skeleton FAILED checks: {0} (code `${1:X4})" -f ($failed -join ', '), $code)
  110. }
  111. $nmis = $memory[$mailbox + 8]
  112. if ($nmis -lt 1) { throw "no NMI was counted" }
  113. Write-Host ("verified mailbox PASS, code `$0000, {0} NMI(s) under CR `${1:X2} / P0 page `${2:X2}, ZP sentinel `${3:X2}" -f
  114. $nmis, $memory[$mailbox + 9], $memory[$mailbox + 10], $memory[$mailbox + 11])
  115. if (Test-Path -LiteralPath $screenshot) { Write-Host ("screenshot: {0}" -f $screenshot) }
  116. } finally {
  117. if ($client) { $client.Dispose() }
  118. if ($process -and -not $process.HasExited) { $process.Kill(); $process.WaitForExit() }
  119. }

Powered by TurnKey Linux.