|
- # 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/<name>.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"
- }
|