# DEMO: write a Nova128 program in the Vim clone (x64sc, C64 mode), then check # it on the C128 (x128) with the compiler front end as it exists today. # # pwsh -File scripts/demo-write-check.ps1 (good.n8 and bad.n8) # pwsh -File scripts/demo-write-check.ps1 -Programs good.n8 # # For each demo/.n8 (an ASCII mirror): # 1. x64sc autostarts VIM from a fresh copy of vim/work.d81 and the program # is TYPED into it through the keyboard buffer: file name, `y` to create, # `i`, the text, RUN/STOP, `:w`. Vim writes the PETSCII SEQ file and # stays on screen for the exit screenshot. # 2. The SEQ file is read back with c1541 and compared with the mirror. # 3. x128 autostarts N8CHECK from the same disk (after x64sc has exited), # the file name is typed at its prompt, and it parses the file. # 4. The screen and NAME.ERR, if any, are shown. # Screenshots go to build/demo/. No code is generated yet (epic E04). [CmdletBinding()] # At 120 ms per key Vim once saw a doubled key and a lost RETURN; the # read-back comparison catches that, and 200 ms leaves more margin. param([string[]]$Programs = @("good.n8", "bad.n8"), [int]$KeyDelay = 200) $ErrorActionPreference = "Stop" $project = Split-Path $PSScriptRoot -Parent $repository = Split-Path $project -Parent Import-Module (Join-Path $PSScriptRoot "lib\Nova128Test.psm1") -Force $out = Join-Path $project "build\demo" New-Item -ItemType Directory -Force -Path $out | Out-Null $c1541 = Get-ViceTool "c1541" $x64 = Get-ViceTool "x64sc" $x128 = Get-ViceTool "x128" # ------------------------------------------------------------- build $link = Invoke-Nova128Link -Name "n8check" -BuildDir $out ` -Config (Join-Path $project "cfg\compiler.cfg") -Sources @( (Join-Path $project "src\compiler\mmu.s"), (Join-Path $project "src\compiler\diskio.s"), (Join-Path $project "src\compiler\source.s"), (Join-Path $project "src\compiler\lexer.s"), (Join-Path $project "src\compiler\names.s"), (Join-Path $project "src\compiler\diagnostics.s"), (Join-Path $project "src\compiler\parser.s"), (Join-Path $project "src\compiler\types.s"), (Join-Path $project "demo\n8check.s")) # A fresh copy: the Vim work disk itself is never written. $disk = Join-Path $out "demo.d81" if (Test-Path $disk) { Remove-Item $disk -Force } Copy-Item (Join-Path $repository "vim\work.d81") $disk & $c1541 $disk -write $link.Program "n8check" 2>&1 | Out-Null foreach ($p in $Programs) { # stale copies, if any & $c1541 $disk -delete $p ($p -replace '\.n8$', '.err') 2>&1 | Out-Null } function Quote-Arg([string]$a) { if ($a -ne "" -and $a -notmatch '[\s"]') { return $a } $e = $a -replace '(\\*)"', '$1$1\"' $e = $e -replace '(\\+)$', '$1$1' return '"' + $e + '"' } # One emulator at a time, run from build/demo so "demo.d81:prog" has no drive # letter colon, and waited for so nothing else touches the image. function Invoke-Vice([string]$exe, [string[]]$argv) { $psi = [Diagnostics.ProcessStartInfo]::new() $psi.FileName = $exe $psi.WorkingDirectory = $out $psi.Arguments = ($argv | ForEach-Object { Quote-Arg $_ }) -join ' ' $psi.UseShellExecute = $false $psi.RedirectStandardOutput = $true # VICE's log is noise here $psi.RedirectStandardError = $true $proc = [Diagnostics.Process]::Start($psi) $stdout = $proc.StandardOutput.ReadToEndAsync() $stderr = $proc.StandardError.ReadToEndAsync() $proc.WaitForExit() [void]$stdout.Result; [void]$stderr.Result Start-Sleep -Milliseconds 900 # let the image write settle } function Get-Cycles([int]$keys, [int]$extraSeconds) { $wall = $keys * $KeyDelay / 1000.0 + $extraSeconds return [long][Math]::Min([Math]::Max($wall * 13000000, 150000000), 2000000000) } function ConvertFrom-PetsciiText([byte[]]$bytes) { return -join ($bytes | ForEach-Object { if ($_ -eq 13) { "`n" } elseif ($_ -ge 0x41 -and $_ -le 0x5A) { [char]($_ + 0x20) } elseif ($_ -ge 0xC1 -and $_ -le 0xDA) { [char]($_ - 0x80) } else { [char]$_ } }) } foreach ($name in $Programs) { $base = $name -replace '\.n8$', '' $mirror = (Get-Content -Raw (Join-Path $project "demo\$name")) -replace "`r", "" $text = $mirror.TrimEnd("`n") if ($text -cmatch '[A-Z"\\]') { throw "$name must be lowercase without quotes or backslashes (typed via -keybuf)" } Write-Host "" Write-Host "=== $name" # 1. type it into Vim on the C64 $keys = "$name\n" + "y" + "i" + ($text -replace "`n", "\n") + "\x03" + ":w\n" $shot = Join-Path $out "$base-vim.png" if (Test-Path $shot) { Remove-Item $shot -Force } Write-Host " x64sc: typing $($text.Length) characters into VIM..." Invoke-Vice $x64 @("-drive8type", "1581", "-8", "demo.d81", "-autostart", "demo.d81:vim", "-autostart-warp", "-warp", "-sounddev", "dummy", "-keybuf-delay", "$KeyDelay", "-keybuf", $keys, "-limitcycles", "$(Get-Cycles $keys.Length 25)", "-exitscreenshot", $shot) # 2. read back what Vim wrote $seq = Join-Path $out "$base.seq" if (Test-Path $seq) { Remove-Item $seq -Force } & $c1541 $disk -read "$name,s" $seq 2>&1 | Out-Null if (-not (Test-Path $seq)) { throw "VIM did not write $name (see $shot)" } $saved = (ConvertFrom-PetsciiText ([IO.File]::ReadAllBytes($seq))).TrimEnd("`n") if ($saved -ne $text) { throw "$name on disk differs from demo\$name (see $shot)" } Write-Host " VIM saved $name as a SEQ file: $(([IO.File]::ReadAllBytes($seq)).Length) PETSCII bytes, identical to the mirror" # 3. check it on the C128 $shot128 = Join-Path $out "$base-check.png" if (Test-Path $shot128) { Remove-Item $shot128 -Force } Write-Host " x128: N8CHECK $name ..." Invoke-Vice $x128 @("-drive8type", "1581", "-8", "demo.d81", "-autostart", "demo.d81:n8check", "-autostart-warp", "-warp", "-sounddev", "dummy", "-keybuf-delay", "$KeyDelay", "-keybuf", "$name\n", "-limitcycles", "$(Get-Cycles 10 40)", "-exitscreenshotvicii", $shot128) # 4. results $err = Join-Path $out "$base.err.txt" if (Test-Path $err) { Remove-Item $err -Force } $listing = (& $c1541 -attach $disk -list 2>$null) | Out-String if ($listing -match ('"' + [regex]::Escape("$base.err") + '"')) { & $c1541 $disk -read "$base.err,s" $err 2>$null | Out-Null } if (Test-Path $err) { Write-Host " $base.err:" foreach ($line in ([Text.Encoding]::ASCII.GetString([IO.File]::ReadAllBytes($err)).TrimEnd("`r") -split "`r")) { Write-Host " $line" } } else { Write-Host " no $base.err: the program has no errors" } Write-Host " screenshots: $shot, $shot128" }