| @@ -0,0 +1,71 @@ | |||
| @echo off | |||
| setlocal | |||
| REM ------------------------------------------------------------------ | |||
| REM Build the vim editor with Spinnaker Power C on a private copy of | |||
| REM the system disk at ..\reference\POWERc.d81. | |||
| REM | |||
| REM The editor is two source files because Power C's compiler reports | |||
| REM "program too big" when the whole thing is one unit; both objects | |||
| REM are linked into vim. | |||
| REM | |||
| REM Power C is interactive: "cc" asks for the source, compiler and | |||
| REM object disks, and "link" prompts for object files, the "^" library | |||
| REM line and the output file name. -keybuf answers all of it; the runs | |||
| REM of \n are those prompts. -keybuf-delay spaces the answers out: fed | |||
| REM all at once they land before the later disk prompts appear and are | |||
| REM lost, which leaves cc waiting for the object disk. | |||
| REM ------------------------------------------------------------------ | |||
| set "VICE=C:\Program Files\GTK3VICE-3.10-win64\bin" | |||
| set "HERE=%~dp0" | |||
| set "BASE=%HERE%..\reference\POWERc.d81" | |||
| set "IMG=%HERE%vim.d81" | |||
| if not exist "%VICE%\x64sc.exe" goto novice | |||
| if not exist "%BASE%" goto nobody | |||
| echo === fresh work disk | |||
| copy /y "%BASE%" "%IMG%" >nul | |||
| echo === ASCII source -^> PETSCII | |||
| powershell -NoProfile -ExecutionPolicy Bypass -File "%HERE%to-petscii.ps1" "%HERE%vim.c" "%HERE%vim.pet" | |||
| if errorlevel 1 goto bad | |||
| powershell -NoProfile -ExecutionPolicy Bypass -File "%HERE%to-petscii.ps1" "%HERE%vscreen.c" "%HERE%vscreen.pet" | |||
| if errorlevel 1 goto bad | |||
| echo === write both sources to the disk | |||
| for %%f in (vim.c vim.o vscreen.c vscreen.o vim) do "%VICE%\c1541.exe" "%IMG%" -delete %%f >nul 2>&1 | |||
| "%VICE%\c1541.exe" "%IMG%" -write "%HERE%vim.pet" "vim.c,s" >nul | |||
| if errorlevel 1 goto bad | |||
| "%VICE%\c1541.exe" "%IMG%" -write "%HERE%vscreen.pet" "vscreen.c,s" >nul | |||
| if errorlevel 1 goto bad | |||
| echo === cc vim.c (a minute or so in warp mode) | |||
| "%VICE%\x64sc.exe" -8 "%IMG%" -autostart "%IMG%:shell" -autostart-warp -warp -sounddev dummy -keybuf-delay 300 -keybuf "cc vim.c\n\n\n\n\n\n\n\n\n\n\n\n" -limitcycles 600000000 | |||
| echo === cc vscreen.c | |||
| "%VICE%\x64sc.exe" -8 "%IMG%" -autostart "%IMG%:shell" -autostart-warp -warp -sounddev dummy -keybuf-delay 300 -keybuf "cc vscreen.c\n\n\n\n\n\n\n\n\n\n\n\n" -limitcycles 600000000 | |||
| echo === link -s -^> vim | |||
| "%VICE%\x64sc.exe" -8 "%IMG%" -autostart "%IMG%:shell" -autostart-warp -warp -sounddev dummy -keybuf-delay 300 -keybuf "link -s\nvim.o\nvscreen.o\n^\n\nvim\n\n\n" -limitcycles 600000000 | |||
| del "%HERE%vim.pet" >nul 2>&1 | |||
| del "%HERE%vscreen.pet" >nul 2>&1 | |||
| echo === disk contents | |||
| "%VICE%\c1541.exe" "%IMG%" -list | findstr /i "vim vscreen" | |||
| echo. | |||
| echo Run it with: | |||
| echo x64sc -autostart "%IMG%:vim" | |||
| exit /b 0 | |||
| :novice | |||
| echo x64sc.exe not found in "%VICE%" | |||
| exit /b 1 | |||
| :nobody | |||
| echo %BASE% not found - is the repository complete? | |||
| exit /b 1 | |||
| :bad | |||
| echo BUILD FAILED | |||
| exit /b 1 | |||
| @@ -0,0 +1,31 @@ | |||
| # to-petscii.ps1 - convert an ASCII C source file into the PETSCII form | |||
| # Power C expects on a C64 disk: uppercase letters shifted into $C1-$DA, | |||
| # lowercase into $41-$5A, { } into $DB/$DD, and CR ($0D) line endings. | |||
| # | |||
| # Usage: | |||
| # powershell -NoProfile -File to-petscii.ps1 vim.c vim.pet | |||
| param( | |||
| [Parameter(Mandatory = $true)][string]$InFile, | |||
| [Parameter(Mandatory = $true)][string]$OutFile | |||
| ) | |||
| $bytes = [System.IO.File]::ReadAllBytes($InFile) | |||
| $start = 0 | |||
| if ($bytes.Length -ge 3 -and $bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF) { | |||
| $start = 3 # skip a UTF-8 BOM if an editor added one | |||
| } | |||
| $out = New-Object System.Collections.Generic.List[byte] | |||
| for ($i = $start; $i -lt $bytes.Length; $i++) { | |||
| $b = $bytes[$i] | |||
| if ($b -eq 13) { continue } # CRLF -> single CR | |||
| if ($b -eq 10) { $out.Add([byte]13); continue } | |||
| if ($b -ge 0x61 -and $b -le 0x7A) { $out.Add([byte]($b - 0x20)); continue } # a-z | |||
| if ($b -ge 0x41 -and $b -le 0x5A) { $out.Add([byte]($b + 0x80)); continue } # A-Z | |||
| if ($b -ge 0x7B -and $b -le 0x7F) { $out.Add([byte]($b + 0x60)); continue } # { | } ~ -> $DB-$DF | |||
| $out.Add([byte]$b) | |||
| } | |||
| [System.IO.File]::WriteAllBytes($OutFile, $out.ToArray()) | |||
| Write-Host ("wrote {0} PETSCII bytes to {1}" -f $out.Count, $OutFile) | |||
| @@ -0,0 +1,420 @@ | |||
| /* vim.c - a small vi/vim-style screen editor for the Commodore 64 | |||
| * | |||
| * Core half of the program: text buffer, cursor motion, key handling | |||
| * and saving. Drawing lives in vscreen.c because Power C's compiler | |||
| * reports "program too big" when the whole editor is one unit. The two | |||
| * halves share functions only - every piece of state stays private to | |||
| * this file and is handed to draw() as arguments - because sharing | |||
| * variables across Power C object files proved unreliable. | |||
| * | |||
| * Modal editing, like vi: | |||
| * | |||
| * COMMAND mode INSERT mode | |||
| * i insert here any key type text | |||
| * a append after char RETURN split the line | |||
| * o open line below DEL backspace | |||
| * O open line above RUN/STOP back to COMMAND mode | |||
| * x delete character cursor keys move | |||
| * h j k l or cursor keys CLR/HOME start of line | |||
| * 0 start of line | |||
| * $ end of line | |||
| * : command line | |||
| * | |||
| * : commands | |||
| * :w write "notes" to disk (SEQ file, drive 8) | |||
| * :wq write and quit | |||
| * :q quit | |||
| * | |||
| * Special C characters, on the same keys the Power C manual gives for ced: | |||
| * | |||
| * { SHIFT + } SHIFT - \ English pound key | |||
| * ~ C= (logo) P _ C= (logo) @ | C= (logo) * | |||
| * | |||
| * The Kernal already produces the codes Power C expects for these | |||
| * ($DB, $DD, $5C, $AF, $A4, $DF - read from the key tables at $EB81), | |||
| * so insert mode only has to accept them. The character ROM has no | |||
| * brace or bar glyphs, so on screen they appear as the nearest glyph. | |||
| * | |||
| * ESCAPE is the C64 RUN/STOP key, which the Kernal reports in the | |||
| * zero-page STOP flag at $91. | |||
| * | |||
| * The text buffer holds 2000 bytes with 13 ($0D) as the line break. | |||
| * Keys come from the Kernal keyboard buffer at $0277, count at $c6. | |||
| * | |||
| * Build with build.bat in this folder: | |||
| * | |||
| * cc vim.c -> vim.o | |||
| * cc vscreen.c -> vscreen.o | |||
| * link -s | |||
| * > vim.o | |||
| * > vscreen.o | |||
| * > ^ (stdlib.l + syslib.l) | |||
| * > | |||
| * output file name: vim | |||
| * | |||
| * Then run with: x64sc -autostart "vim.d81:vim" | |||
| * or from BASIC: LOAD"VIM",8,1 : RUN | |||
| * | |||
| * Note: this Power C build rejects both $7C and $DC as "illegal | |||
| * character" for the | operator, so nested tests are used instead of ||. | |||
| */ | |||
| #include <stdio.h> | |||
| static char text[2000]; /* document, 13 = line break */ | |||
| static int tlen; /* bytes in use */ | |||
| static int pos; /* cursor, byte offset into text */ | |||
| static int mode; /* 0 command, 1 insert, 2 : prompt */ | |||
| static char fname[17]; /* file name used by :w */ | |||
| static char cmd[9]; /* text after the ':' */ | |||
| static int cmdlen; | |||
| static int quit; | |||
| static int msgcode; /* message for draw(): 0 none, 1-4 */ | |||
| static char *defnam = "notes"; | |||
| /* ---------- provided by vscreen.c ---------- */ | |||
| int draw(); | |||
| int clrscr(); | |||
| /* ---------- buffer helpers ---------- */ | |||
| static lstart(n) /* offset of the first byte of line n */ | |||
| int n; | |||
| { | |||
| int i; | |||
| int c; | |||
| if (n <= 0) return 0; | |||
| c = 0; | |||
| i = 0; | |||
| while (i < tlen) { | |||
| if (text[i] == 13) { | |||
| c = c + 1; | |||
| if (c == n) return i + 1; | |||
| } | |||
| i = i + 1; | |||
| } | |||
| return tlen; | |||
| } | |||
| static lcount() /* number of line breaks */ | |||
| { | |||
| int i; | |||
| int c; | |||
| c = 0; | |||
| for (i = 0; i < tlen; i++) | |||
| if (text[i] == 13) c = c + 1; | |||
| return c; | |||
| } | |||
| static lnof() /* line holding the cursor */ | |||
| { | |||
| int i; | |||
| int c; | |||
| c = 0; | |||
| for (i = 0; i < pos && i < tlen; i++) | |||
| if (text[i] == 13) c = c + 1; | |||
| return c; | |||
| } | |||
| static intend(o) /* offset of the line end */ | |||
| int o; | |||
| { | |||
| int e; | |||
| e = o; | |||
| while (e < tlen && text[e] != 13) e = e + 1; | |||
| return e; | |||
| } | |||
| static inschr(ch) | |||
| int ch; | |||
| { | |||
| int i; | |||
| if (tlen >= 1999) { | |||
| msgcode = 1; | |||
| return; | |||
| } | |||
| for (i = tlen; i > pos; i--) | |||
| text[i] = text[i - 1]; | |||
| text[pos] = ch; | |||
| tlen = tlen + 1; | |||
| pos = pos + 1; | |||
| } | |||
| static delat() | |||
| { | |||
| int i; | |||
| if (pos >= tlen) return; | |||
| for (i = pos; i < tlen - 1; i++) | |||
| text[i] = text[i + 1]; | |||
| tlen = tlen - 1; | |||
| } | |||
| static backsp() | |||
| { | |||
| if (pos <= 0) return; | |||
| pos = pos - 1; | |||
| delat(); | |||
| } | |||
| /* ---------- cursor motion ---------- */ | |||
| static movleft() | |||
| { | |||
| if (pos > 0) pos = pos - 1; | |||
| } | |||
| static movright() | |||
| { | |||
| if (pos < tlen) pos = pos + 1; | |||
| } | |||
| static movdown() | |||
| { | |||
| int ln; | |||
| int cs; | |||
| int o; | |||
| int e; | |||
| ln = lnof(); | |||
| if (ln + 1 > lcount()) return; | |||
| cs = pos - lstart(ln); | |||
| o = lstart(ln + 1); | |||
| e = intend(o); | |||
| pos = o + cs; | |||
| if (pos > e) pos = e; | |||
| } | |||
| static movup() | |||
| { | |||
| int ln; | |||
| int cs; | |||
| int o; | |||
| int e; | |||
| ln = lnof(); | |||
| if (ln <= 0) return; | |||
| cs = pos - lstart(ln); | |||
| o = lstart(ln - 1); | |||
| e = intend(o); | |||
| pos = o + cs; | |||
| if (pos > e) pos = e; | |||
| } | |||
| static linehome() | |||
| { | |||
| pos = lstart(lnof()); | |||
| } | |||
| static lineend() | |||
| { | |||
| pos = intend(lstart(lnof())); | |||
| } | |||
| /* ---------- saving ---------- */ | |||
| static savfil() | |||
| { | |||
| FILE *f; | |||
| int i; | |||
| f = fopen(fname, "w"); | |||
| if (!f) { | |||
| msgcode = 2; | |||
| return; | |||
| } | |||
| if (ferror(f)) { | |||
| msgcode = 2; | |||
| fclose(f); | |||
| return; | |||
| } | |||
| for (i = 0; i < tlen; i++) fputc(text[i], f); | |||
| fclose(f); | |||
| msgcode = 3; | |||
| } | |||
| /* ---------- : command line ---------- */ | |||
| static docmd() | |||
| { | |||
| if (cmdlen == 0) return; | |||
| if (cmd[0] == 'w') { | |||
| if (cmdlen > 1 && cmd[1] == 'q') { | |||
| savfil(); | |||
| quit = 1; | |||
| return; | |||
| } | |||
| savfil(); | |||
| return; | |||
| } | |||
| if (cmd[0] == 'q') { | |||
| quit = 1; | |||
| return; | |||
| } | |||
| msgcode = 4; | |||
| } | |||
| /* ---------- key handlers ---------- */ | |||
| static insk(k) | |||
| int k; | |||
| { | |||
| if (k == 3) { /* ESC: leave insert mode */ | |||
| mode = 0; | |||
| if (pos > 0) pos = pos - 1; | |||
| return; | |||
| } | |||
| if (k == 13) { inschr(13); return; } | |||
| if (k == 20) { backsp(); return; } | |||
| if (k == 157) { movleft(); return; } | |||
| if (k == 29) { movright(); return; } | |||
| if (k == 145) { movup(); return; } | |||
| if (k == 17) { movdown(); return; } | |||
| if (k == 19) { linehome(); return; } | |||
| if (k >= 32 && k < 128) { inschr(k); return; } | |||
| if (k == 219) { inschr(k); return; } /* SHIFT + : { */ | |||
| if (k == 221) { inschr(k); return; } /* SHIFT - : } */ | |||
| if (k == 223) { inschr(k); return; } /* logo * : | */ | |||
| if (k == 175) { inschr(k); return; } /* logo P : ~ */ | |||
| if (k == 164) { inschr(k); return; } /* logo @ : _ */ | |||
| } | |||
| static cmdk(k) | |||
| int k; | |||
| { | |||
| if (k >= 65 && k <= 90) k = k + 32; /* letters arrive as PETSCII $41-$5A */ | |||
| if (k == ':') { | |||
| mode = 2; | |||
| cmdlen = 0; | |||
| cmd[0] = 0; | |||
| return; | |||
| } | |||
| if (k == 'i') { mode = 1; return; } | |||
| if (k == 'a') { | |||
| if (pos < tlen && text[pos] != 13) pos = pos + 1; | |||
| mode = 1; | |||
| return; | |||
| } | |||
| if (k == 'o') { | |||
| pos = intend(lstart(lnof())); | |||
| inschr(13); | |||
| mode = 1; | |||
| return; | |||
| } | |||
| if (k == 'O') { | |||
| pos = lstart(lnof()); | |||
| inschr(13); | |||
| pos = pos - 1; | |||
| mode = 1; | |||
| return; | |||
| } | |||
| if (k == 'x') { delat(); return; } | |||
| if (k == 'h') { movleft(); return; } | |||
| if (k == 157) { movleft(); return; } | |||
| if (k == 'l') { movright(); return; } | |||
| if (k == 29) { movright(); return; } | |||
| if (k == 'j') { movdown(); return; } | |||
| if (k == 17) { movdown(); return; } | |||
| if (k == 'k') { movup(); return; } | |||
| if (k == 145) { movup(); return; } | |||
| if (k == '0') { linehome(); return; } | |||
| if (k == 19) { linehome(); return; } | |||
| if (k == '$') { lineend(); return; } | |||
| } | |||
| /* ---------- keyboard ---------- */ | |||
| static getkey() /* one byte from the Kernal keyboard | |||
| buffer, $0277, count at $c6 */ | |||
| { | |||
| char *cnt; | |||
| char *buf; | |||
| int i; | |||
| int k; | |||
| cnt = (char *) 198; | |||
| buf = (char *) 631; | |||
| if (*cnt == 0) return 0; | |||
| if (*cnt > 10) { | |||
| *cnt = 0; | |||
| return 0; | |||
| } | |||
| k = buf[0]; | |||
| for (i = 0; i < 9; i++) buf[i] = buf[i + 1]; | |||
| *cnt = *cnt - 1; | |||
| return k; | |||
| } | |||
| static waitkey() | |||
| { | |||
| char *stop; | |||
| int k; | |||
| for (;;) { | |||
| stop = (char *) 145; /* $91: RUN/STOP flag */ | |||
| if (*stop) { | |||
| *stop = 0; | |||
| return 3; | |||
| } | |||
| k = getkey(); | |||
| if (k) return k; | |||
| } | |||
| } | |||
| /* ---------- main loop ---------- */ | |||
| main() | |||
| { | |||
| int k; | |||
| int i; | |||
| tlen = 0; | |||
| pos = 0; | |||
| mode = 0; | |||
| cmdlen = 0; | |||
| quit = 0; | |||
| msgcode = 0; | |||
| i = 0; | |||
| while (defnam[i]) { | |||
| fname[i] = defnam[i]; | |||
| i = i + 1; | |||
| } | |||
| fname[i] = 0; | |||
| while (!quit) { | |||
| draw(text, tlen, pos, mode, fname, cmd, cmdlen, msgcode); | |||
| msgcode = 0; | |||
| k = waitkey(); | |||
| if (mode == 2) { | |||
| if (k == 13) { | |||
| mode = 0; | |||
| docmd(); | |||
| } | |||
| else if (k == 20) { | |||
| if (cmdlen > 0) cmdlen = cmdlen - 1; | |||
| } | |||
| else if (k >= 32 && cmdlen < 8) { | |||
| if (k >= 65 && k <= 90) k = k + 32; | |||
| cmd[cmdlen] = k; | |||
| cmdlen = cmdlen + 1; | |||
| } | |||
| continue; | |||
| } | |||
| if (mode == 1) { | |||
| insk(k); | |||
| continue; | |||
| } | |||
| cmdk(k); | |||
| } | |||
| clrscr(); | |||
| printf("bye\n"); | |||
| } | |||
| @@ -0,0 +1,248 @@ | |||
| /* vscreen.c - screen half of the vim editor for the C64 (Power C) | |||
| * | |||
| * Draws the text window, the status line and the cursor straight into | |||
| * the screen matrix at $0400 and colour RAM at $d800. Kept in its own | |||
| * file because Power C overflows its compiler when the whole editor is | |||
| * one source. | |||
| * | |||
| * This module owns no program state: draw() receives everything it | |||
| * needs from vim.c as arguments. Sharing variables between Power C | |||
| * object files proved unreliable, so only functions cross the boundary. | |||
| */ | |||
| static char stat[40]; /* status line build buffer */ | |||
| static int slen; | |||
| /* ---------- status line text ---------- */ | |||
| static sclr() | |||
| { | |||
| slen = 0; | |||
| stat[0] = 0; | |||
| } | |||
| static sadd(c) | |||
| char c; | |||
| { | |||
| if (slen < 39) { | |||
| stat[slen] = c; | |||
| slen = slen + 1; | |||
| stat[slen] = 0; | |||
| } | |||
| } | |||
| static sstr(s) | |||
| char *s; | |||
| { | |||
| while (*s) { | |||
| sadd(*s); | |||
| s = s + 1; | |||
| } | |||
| } | |||
| static snum(n) | |||
| int n; | |||
| { | |||
| char b[6]; | |||
| int i; | |||
| if (n < 0) { | |||
| sadd('-'); | |||
| n = -n; | |||
| } | |||
| if (n == 0) { | |||
| sadd('0'); | |||
| return; | |||
| } | |||
| i = 0; | |||
| while (n > 0) { | |||
| b[i] = '0' + (n % 10); | |||
| i = i + 1; | |||
| n = n / 10; | |||
| } | |||
| while (i > 0) { | |||
| i = i - 1; | |||
| sadd(b[i]); | |||
| } | |||
| } | |||
| /* ---------- PETSCII byte -> screen code ---------- */ | |||
| static sccode(c) | |||
| int c; | |||
| { | |||
| if (c >= 193 && c <= 218) return c - 192; /* shifted letters $C1-$DA */ | |||
| if (c >= 96 && c <= 127) return c - 32; | |||
| if (c >= 64 && c <= 95) return c - 64; | |||
| /* the C-only characters have no glyph of their own in the ROM */ | |||
| if (c == 219) return 91; /* { -> [ */ | |||
| if (c == 221) return 93; /* } -> ] */ | |||
| if (c == 223) return 94; /* | -> up arrow */ | |||
| if (c == 175) return 126; /* ~ -> its graphics glyph */ | |||
| if (c == 164) return 95; /* _ -> left arrow */ | |||
| return c; | |||
| } | |||
| /* ---------- screen output ---------- */ | |||
| clrscr() | |||
| { | |||
| char *s; | |||
| char *m; | |||
| int i; | |||
| s = (char *) 1024; | |||
| m = (char *) 55296; | |||
| for (i = 0; i < 1000; i++) { | |||
| s[i] = 32; | |||
| m[i] = 1; | |||
| } | |||
| } | |||
| static putchr(x, y, ch, c) | |||
| int x; | |||
| int y; | |||
| int ch; | |||
| int c; | |||
| { | |||
| char *s; | |||
| char *m; | |||
| int o; | |||
| if (x < 0) return; | |||
| if (x > 39) return; | |||
| if (y < 0) return; | |||
| if (y > 24) return; | |||
| o = y * 40 + x; | |||
| s = (char *) 1024; | |||
| m = (char *) 55296; | |||
| s[o] = ch; | |||
| m[o] = c; | |||
| } | |||
| static putstr(x, y, s, c) | |||
| int x; | |||
| int y; | |||
| char *s; | |||
| int c; | |||
| { | |||
| while (*s && x < 40) { | |||
| putchr(x, y, sccode(*s), c); | |||
| x = x + 1; | |||
| s = s + 1; | |||
| } | |||
| } | |||
| static revchr(o) /* reverse the character in a cell */ | |||
| int o; | |||
| { | |||
| char *s; | |||
| s = (char *) 1024; | |||
| if (s[o] < 128) s[o] = s[o] + 128; | |||
| } | |||
| /* ---------- buffer scans over the caller's text ---------- */ | |||
| static lstartx(tp, len, n) /* offset of the first byte of line n */ | |||
| char *tp; | |||
| int len; | |||
| int n; | |||
| { | |||
| int i; | |||
| int c; | |||
| if (n <= 0) return 0; | |||
| c = 0; | |||
| i = 0; | |||
| while (i < len) { | |||
| if (tp[i] == 13) { | |||
| c = c + 1; | |||
| if (c == n) return i + 1; | |||
| } | |||
| i = i + 1; | |||
| } | |||
| return len; | |||
| } | |||
| static lnofx(tp, cur) /* line holding the cursor */ | |||
| char *tp; | |||
| int cur; | |||
| { | |||
| int i; | |||
| int c; | |||
| c = 0; | |||
| for (i = 0; i < cur; i++) | |||
| if (tp[i] == 13) c = c + 1; | |||
| return c; | |||
| } | |||
| /* ---------- full redraw ---------- */ | |||
| draw(tp, len, cur, md, name, cp, cl, mc) | |||
| char *tp; | |||
| int len; | |||
| int cur; | |||
| int md; | |||
| char *name; | |||
| char *cp; | |||
| int cl; | |||
| int mc; | |||
| { | |||
| int ln; | |||
| int top; | |||
| int r; | |||
| int i; | |||
| int to; | |||
| int c; | |||
| int cs; | |||
| int cr; | |||
| ln = lnofx(tp, cur); | |||
| top = ln - 11; | |||
| if (top < 0) top = 0; | |||
| clrscr(); | |||
| to = lstartx(tp, len, top); | |||
| for (r = 0; r < 23; r++) { | |||
| i = 0; | |||
| while (to < len && i < 40) { | |||
| c = tp[to]; | |||
| if (c == 13) break; | |||
| putchr(i, r, sccode(c), 1); | |||
| i = i + 1; | |||
| to = to + 1; | |||
| } | |||
| while (to < len && tp[to] != 13) to = to + 1; | |||
| if (to < len) to = to + 1; | |||
| } | |||
| for (i = 0; i < 40; i++) putchr(i, 24, 32, 11); | |||
| sclr(); | |||
| if (md == 1) sstr("INSERT"); | |||
| else if (md == 2) sstr(": "); | |||
| else sstr("COMMAND"); | |||
| sstr(" line "); | |||
| snum(ln + 1); | |||
| sstr(" "); | |||
| sstr(name); | |||
| if (mc == 1) sstr(" full"); | |||
| else if (mc == 2) sstr(" save err"); | |||
| else if (mc == 3) sstr(" saved"); | |||
| else if (mc == 4) sstr(" ?cmd"); | |||
| putstr(0, 24, stat, 11); | |||
| if (md == 2) { | |||
| putchr(0, 23, sccode(':'), 1); | |||
| for (i = 0; i < cl; i++) putchr(i + 1, 23, sccode(cp[i]), 1); | |||
| } | |||
| cs = cur - lstartx(tp, len, ln); | |||
| if (cs > 39) cs = 39; | |||
| if (cs < 0) cs = 0; | |||
| cr = ln - top; | |||
| if (cr >= 0 && cr < 23) revchr(cr * 40 + cs); | |||
| } | |||
Powered by TurnKey Linux.