Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

175 linhas
6.3KB

  1. # E01-S04: build and verify display/clock behavior in both x128 modes.
  2. [CmdletBinding()]
  3. param(
  4. [int]$RemotePort = 6510,
  5. [int]$LimitCycles = 30000000
  6. )
  7. $ErrorActionPreference = "Stop"
  8. $project = Split-Path $PSScriptRoot -Parent
  9. $build = Join-Path $project "build"
  10. $program = Join-Path $build "display-clock.prg"
  11. $traceCommands = Join-Path $project "monitor\display-clock-trace.txt"
  12. $x128 = "C:\Program Files\GTK3VICE-3.10-win64\bin\x128.exe"
  13. & (Join-Path $PSScriptRoot "build-display-clock.ps1")
  14. if ($LASTEXITCODE -ne 0) { throw "display/clock build failed" }
  15. if (-not (Test-Path -LiteralPath $x128)) { throw "x128.exe not found at $x128" }
  16. function Quote-Arg([string]$value) {
  17. if ($value -ne "" -and $value -notmatch '[\s"]') { return $value }
  18. $escaped = $value -replace '(\\*)"', '$1$1\"'
  19. $escaped = $escaped -replace '(\\+)$', '$1$1'
  20. return '"' + $escaped + '"'
  21. }
  22. function Start-X128([string[]]$arguments) {
  23. $psi = [Diagnostics.ProcessStartInfo]::new()
  24. $psi.FileName = $x128
  25. $psi.Arguments = ($arguments | ForEach-Object { Quote-Arg $_ }) -join ' '
  26. $psi.UseShellExecute = $true
  27. $psi.WindowStyle = [Diagnostics.ProcessWindowStyle]::Hidden
  28. return [Diagnostics.Process]::Start($psi)
  29. }
  30. function Invoke-Screenshot([string]$mode) {
  31. $screenshot = Join-Path $build ("display-clock-{0}.png" -f $mode)
  32. if (Test-Path -LiteralPath $screenshot) {
  33. Remove-Item -LiteralPath $screenshot -Force
  34. }
  35. $captureOption = if ($mode -eq '40') { '-exitscreenshotvicii' } else { '-exitscreenshot' }
  36. $process = Start-X128 @(
  37. ("-{0}col" -f $mode),
  38. '-autostart', $program,
  39. '-autostart-warp', '-warp',
  40. '-sounddev', 'dummy',
  41. '-limitcycles', "$LimitCycles",
  42. $captureOption, $screenshot
  43. )
  44. $process.WaitForExit()
  45. if (-not (Test-Path -LiteralPath $screenshot)) {
  46. throw "x128 did not create $screenshot"
  47. }
  48. if ((Get-Item -LiteralPath $screenshot).Length -lt 1000) {
  49. throw "$screenshot is unexpectedly small"
  50. }
  51. Write-Host ("{0}-column screenshot: {1}" -f $mode, $screenshot)
  52. }
  53. function Invoke-MonitorVerification(
  54. [string]$mode,
  55. [byte]$expectedResult,
  56. [byte]$expectedMode,
  57. [byte]$expectedFast
  58. ) {
  59. $transcript = Join-Path $build ("display-clock-{0}-remote.txt" -f $mode)
  60. foreach ($path in @($transcript)) {
  61. if (Test-Path -LiteralPath $path) { Remove-Item -LiteralPath $path -Force }
  62. }
  63. $process = Start-X128 @(
  64. ("-{0}col" -f $mode),
  65. '-autostart', $program,
  66. '-autostart-warp', '-warp',
  67. '-sounddev', 'dummy',
  68. '-moncommands', $traceCommands,
  69. '-remotemonitor',
  70. '-remotemonitoraddress', ("ip4://127.0.0.1:{0}" -f $RemotePort)
  71. )
  72. $client = $null
  73. try {
  74. $deadline = [DateTime]::UtcNow.AddSeconds(10)
  75. while ([DateTime]::UtcNow -lt $deadline) {
  76. if ($process.HasExited) { throw "x128 exited before $mode-column verification" }
  77. try {
  78. $client = [Net.Sockets.TcpClient]::new()
  79. $client.Connect('127.0.0.1', $RemotePort)
  80. break
  81. } catch {
  82. if ($client) { $client.Dispose(); $client = $null }
  83. Start-Sleep -Milliseconds 200
  84. }
  85. }
  86. if (-not $client -or -not $client.Connected) {
  87. throw "could not connect to the VICE remote monitor"
  88. }
  89. Start-Sleep -Seconds 3
  90. $stream = $client.GetStream()
  91. $stream.ReadTimeout = 2000
  92. $writer = [IO.StreamWriter]::new($stream, [Text.Encoding]::ASCII, 1024, $true)
  93. $writer.NewLine = "`n"
  94. $writer.AutoFlush = $true
  95. $writer.WriteLine('m $1d0f $1d14')
  96. Start-Sleep -Milliseconds 300
  97. $writer.WriteLine('m $d030 $d030')
  98. Start-Sleep -Milliseconds 700
  99. $buffer = New-Object byte[] 8192
  100. $response = ""
  101. while ($stream.DataAvailable) {
  102. $count = $stream.Read($buffer, 0, $buffer.Length)
  103. if ($count -le 0) { break }
  104. $response += [Text.Encoding]::ASCII.GetString($buffer, 0, $count)
  105. Start-Sleep -Milliseconds 50
  106. }
  107. [IO.File]::WriteAllText($transcript, $response, [Text.Encoding]::ASCII)
  108. $expectedBytes = '{0:x2}\s+{1:x2}\s+{2:x2}\s+00\s+5a\s+c3' -f
  109. $expectedResult, $expectedMode, $expectedFast
  110. if ($response -notmatch ("(?i)C:1d0f\s+" + $expectedBytes)) {
  111. throw "$mode-column result block mismatch; response: $response"
  112. }
  113. $clockMatch = [regex]::Match($response, '(?i)C:d030\s+([0-9a-f]{2})\b')
  114. if (-not $clockMatch.Success) {
  115. throw "$mode-column response did not include `$D030"
  116. }
  117. $clockValue = [Convert]::ToByte($clockMatch.Groups[1].Value, 16)
  118. if (($clockValue -band 0x01) -ne 0) {
  119. throw "$mode-column fallback left `$D030 speed bit set"
  120. }
  121. $writer.WriteLine('q')
  122. $writer.Dispose()
  123. $client.Dispose()
  124. $client = $null
  125. if (-not $process.WaitForExit(5000)) {
  126. throw "x128 did not exit after remote-monitor quit"
  127. }
  128. # With a remote monitor connected, non-stopping trace messages are
  129. # delivered in the remote transcript.
  130. $trace = $response
  131. if ($trace -notmatch '(?i)1c8c') {
  132. throw "$mode-column trace did not reach fallback_done"
  133. }
  134. if ($mode -eq '40') {
  135. if ($trace -notmatch '(?i)1c2e') { throw '40-column trace missed its path' }
  136. if ($trace -match '(?i)1c49') { throw '40-column path entered fast checkpoint' }
  137. } else {
  138. if ($trace -notmatch '(?i)1c3d') { throw '80-column trace missed its path' }
  139. if ($trace -notmatch '(?i)1c49') { throw '80-column trace missed fast checkpoint' }
  140. }
  141. Write-Host ("verified {0}-column result `${1:X2}, mode `${2:X2}, fast `${3:X2}, final clock `$00" -f
  142. $mode, $expectedResult, $expectedMode, $expectedFast)
  143. } finally {
  144. if ($client) { $client.Dispose() }
  145. if ($process -and -not $process.HasExited) {
  146. $process.Kill()
  147. $process.WaitForExit()
  148. }
  149. }
  150. }
  151. Invoke-Screenshot '40'
  152. Invoke-Screenshot '80'
  153. Invoke-MonitorVerification '40' 0x44 0x00 0x00
  154. Invoke-MonitorVerification '80' 0x85 0x80 0x01
  155. Write-Host 'display/clock probe passed in 40- and 80-column modes'

Powered by TurnKey Linux.