Browse Source

calc: typed-file block I/O (ladder 25674)

write/read with a leading TFile now compile: the compiler parses the single
data argument, requires its width to equal the file's declared element size,
and lowers the call to DOS INT 21h AH=40h/3Fh (BX=handle, CX=count,
DS:DX=buffer).  A DI-addressed record element (Sheet[I,J]) and a plain
variable are both supported.  The DOS result is passed to the new tiny
io_store runtime entry, so IOResult sees the last block-I/O status.

t90_fileio covers a `file of Rec', a scalar and an array element, with
assign/rewrite/reset/read/write/close.  It is compile-only: neither boot
harness has a filesystem, so there is no honest execution oracle for a
successful file operation.

The CALC ladder moves 23700 -> 25674; the next blocker is text-file output
(Writeln(MCFile), Write(MCFile,' '), writeln(MCFile,Line)).  Runtime is 3911
bytes / 40 entries, ~41 bytes below the probe HDR.

Verified: compile matrix 91/91, ladder 1/1, 82 .COM linked, 79 executed under
both qemu and Exec86, rt_exec 276/276, nonvacuity 121/121, run_all ALL PASS.
Eric Streit 6 ngày trước cách đây
mục cha
commit
0859a3b531

+ 24 - 16
CALC-COMPILE.md

@@ -97,7 +97,7 @@ Current rung (measured today, normalised position):
 
 | position | blocker |
 |---|---|
-| **23700** | `write(MCfile, Sheet[I,J])` in `Save` — typed-file data I/O (`ERR 102`) |
+| **25674** | `Writeln(MCFile)` in `Print` — text-file output (`ERR 102`) |
 
 Rungs behind it (now passed):
 
@@ -135,7 +135,8 @@ Rungs ahead:
 |---|---|
 | 22280 | file operations (`Assign`, `Reset`, `Rewrite`, `Close`, `IoResult`) - done by the file control-block rung |
 | 22706 | `var Line : AnyString` - a by-reference string parameter |
-| 23700 | typed-file data write (`write(MCfile, Sheet[I,J])`) |
+| 23700 | typed-file data write (`write(MCfile, Sheet[I,J])`) - DONE |
+| 25674 | text-file output (`Writeln(MCFile)`) |
 
 Corrections the measurements force, worth stating plainly because the stage list
 below was written before them:
@@ -344,7 +345,7 @@ recipe above regenerates them, and the numbers are what this document keeps.
    grow into the other. CALC's code is **16,560 bytes**, which the old fixed
    4 KiB window could not emit; that was a port artefact, not a TP3 limit.
 2. **`MaxCode = 24,000` is not the binding constraint for the compile goal.**
-   16,560 + 3,907 (our current runtime) = 20,467, comfortably inside 24,000.
+   16,560 + 3,911 (our current runtime) = 20,471, comfortably inside 24,000.
    The old `dataBase` alone had to move; `t43_codewindow` was the fixture that
    policed it and has been re-baselined (§3.2).
 3. **The §3 data budget is confirmed, not inferred.** Reported data is
@@ -357,7 +358,7 @@ recipe above regenerates them, and the numbers are what this document keeps.
    **DS size `0315h` (12,624 B)**, and **heap/stack `0400h` (16,384 B)**, with
    `A000h` as the maximum (640 KiB, in paragraphs). A `.COM` still uses
    separate CS/DS segments; the original proves it.
-5. **The runtime is 11,341 bytes** in the original. Ours is 3,907 B. It
+5. **The runtime is 11,341 bytes** in the original. Ours is 3,911 B. It
    explains where the original's fixed `pc := $2D7C` / `dc := $0240` came
    from, and why `TPSRC7:81-82` looks the way it does.
 
@@ -424,7 +425,7 @@ inline initmem    mode 0006, CS 0813, DS 11D7,
 
 The file is runtime + code, exactly the shape we now emit; the data is in the
 separate DS described by the inline parameters. Our CALC image will be smaller
-in runtime (3,907 B instead of 11,341 B) but has the same code-only, high-data
+in runtime (3,911 B instead of 11,341 B) but has the same code-only, high-data
 shape. The ladder moved **20,912 → 22,253** on this change; the next blocker is
 not layout but the untyped `file` declaration; that is fixed in the next rung.
 
@@ -456,9 +457,10 @@ subscripts, write field widths, WITH with n-dimensional subscripts, set-field
 assignment, string fields through DI, REAL constants, UpCase, run-time set
 membership, string fields in WRITE, real output, run-time set algebra,
 `Succ`/`Pred`, the original memory layout, the untyped file type, the
-file control-block operations, VAR string parameters and `Chr`). The
-ladder has moved from the first typed constant at 7,791 to **23,700**, where
-`write(MCfile, Sheet[I,J])` asks for typed-file data I/O.
+file control-block operations, VAR string parameters, `Chr`, and typed-file
+block I/O). The
+ladder has moved from the first typed constant at 7,791 to **25,674**, where
+`Writeln(MCFile)` asks for text-file output.
 
 The rung commits and their tags, in order (each is one rung with its own
 fixture, red proof, and — where the harness allows — execution under qemu and
@@ -496,7 +498,8 @@ Exec86):
 | `ff05141` | `v-TP3-CALC-LAYOUT` | `ERR 1 22253` (untyped file, initially misread as a function) |
 | `ed9e790` | `v-TP3-CALC-UNTYPEDFILE` | `ERR 41 22280` (`assign`) |
 | `ab7cced` | `v-TP3-CALC-FILEOPS` | `ERR 102 22706` (VAR string parameter) |
-| *(this commit)* | `v-TP3-CALC-VARSTR` | **`ERR 102 23700`** (typed-file data write) |
+| `02d5b6e` | `v-TP3-CALC-VARSTR` | `ERR 102 23700` (typed-file data write) |
+| *(this commit)* | `v-TP3-CALC-FILEIO` | **`ERR 102 25674`** (text-file output) |
 
 - **Code HEAD** is the layout rung (`v-TP3-CALC-LAYOUT`).  Nothing is pushed.
   The terminal-config work (`v-TP3-TERMCFG`) and the editor key map
@@ -542,6 +545,11 @@ Exec86):
   parameter slot holds the caller's address; assignment, `Read`, `Length`,
   `writeln`, concatenation, comparison and `x[i]` all go through that address.
   `Chr(n)` folds or loads an ordinal and yields a CHAR.
+- **Typed-file block I/O is landed (`t90_fileio`).**  `write`/`read` with a
+  leading `TFile` lower to DOS INT 21h AH=40h/3Fh; the element size must agree
+  with the file's declared element, and the result goes through the tiny
+  `io_store` runtime entry.  The fixture is compile-only because neither
+  harness has a filesystem.
 - **File TYPES and the control-block OPERATIONS are landed (Stage 13).**
   `text`, `file of T`, and untyped `file`; a file variable is our control block
   (`FileVarSize` = 132: handle, mode, 128-byte NUL-terminated name).  The
@@ -611,7 +619,7 @@ Exec86):
   `ERR 1 22253`, terminal config **4/4**, 78 `.COM` linked and **76 executed
   under both qemu and Exec86** (`t64_arrays` remains compile-only because it
   has no `.out`).  `tests/nonvacuity.sh`: **121 ok, 0 failed**.  The runtime is
-  3,907 bytes (wrintw, real_from_int, real_add, real_sub, real_mul, real_div,
+  3,911 bytes (wrintw, real_from_int, real_add, real_sub, real_mul, real_div,
   real_cmp, real_int, real_fmt, real_val, real_write, set_op, set_cmp,
   set_copy; the golden was re-blessed) and `tests/rt_exec.py` passes
   **275/275**, including the MBF arithmetic/output/parse cases and eleven
@@ -1115,11 +1123,11 @@ filename, `Reset`/`Rewrite`/`Close` issue DOS `INT 21h` open/create/close, and
 so both answer `AH=3Dh` with `CF=1, AX=2`; the fixture checks that error path
 under qemu and Exec86, and `rt_exec` pins the name copy.
 
-Not yet: `EndOfFile`, and `read`/`write` with a leading file argument
-(`writeln (MCFile, Line)`, `Readln (H, Buffer^[count])`).  These need
-text-mode newline/`^Z` semantics and typed-file block I/O (`RESUME-TP3.md`
-§2).  The next ladder blocker is not file data I/O, though: it is `var Line :
-AnyString`, a by-reference string parameter.
+Typed-file block I/O (`write`/`read` with a `TFile`) is done (`t90_fileio`,
+compile-only because the harness has no filesystem).  Still open: TEXT file
+output (`Writeln(MCFile)`, `Write(MCFile,' ')`, `writeln(MCFile,Line)`), then
+`EndOfFile` and text `Readln(H, ...)`.  These need text-mode newline/`^Z`
+semantics (`RESUME-TP3.md` §2).  The next ladder blocker is text output.
 
 **Stage 14 — the CRT identifiers.** `GotoXY` (25), `LowVideo`/`NormVideo`
 (16 + 16), `ClrEol` (10), `ClrScr` (6), `KeyPressed` (3), `Delay` (1),
@@ -1163,7 +1171,7 @@ remaining run-time capacity note.
 | limit | value | CALC needs | verdict |
 |---|---|---|---|
 | `TextLimit` (source buffer) | 62,903 | `CALC.PAS` + `CALC.INC`, normalised = **62,415** | **488 bytes of slack** |
-| `MaxCode` | 24,000 | 16,560 B program + 3,907 B runtime = **20,467 B** | **OK, 3,533 B spare** (§3.2) |
+| `MaxCode` | 24,000 | 16,560 B program + 3,911 B runtime = **20,471 B** | **OK, 3,529 B spare** (§3.2) |
 | code window | `CodeMax = 6F00h`, capped by `MaxCode` | 20,227 B | **OK**; no data gap (§3.2) |
 | data area | fixed image `8000h`, zeroed by `initmem` | **12,032 B** (measured, §3.1) | **OK for compile**; see the run-time cargo note (§3.2) |
 | stack | 16,384 min / 655,360 max | 16,384 min | matches the original's `minstk`/`maxstk` |

+ 3 - 2
SUMMARY.md

@@ -2044,7 +2044,7 @@ the compiler *emitting* a 16,560-byte program). The ratchet and front-end
 features through **file control-block operations and the original memory
 layout** are landed: the ladder (`tests/calc_ladder.sh` +
 `tests/fixtures/calc_ladder.tsv`, run by `run_all.sh`; CALC.PAS now stops at
-`ERR 102` at pos 23700, `write(MCfile, Sheet[I,J])` in `Save`), the `{$I}` include,
+`ERR 102` at pos 25674, `Writeln(MCFile)` in `Print`), the `{$I}` include,
 `^X`/`#nn`, scalar typed constants, sets, enums, records (CellRec = 80),
 subranges, arrays, element/field access, file types, string value parameters,
 `Length`, the CRT identifiers (`ClrScr`/`GotoXY`/`ClrEol`/`LowVideo`/
@@ -2060,7 +2060,8 @@ real output (`t84_realwrite`), run-time set algebra and `Succ`/`Pred`
 (`t85`/`t86`), the original code-only `.COM` layout (§3.2), the untyped `file`
 type (`t87`), file control-block operations (`t88`: `Assign`/`Reset`/
 `Rewrite`/`Close`/`IoResult`; data I/O is still refused), and VAR string
-parameters plus `Chr` (`t89`). The next rung is typed-file data I/O. The runtime is 3,907 bytes / 39 entries and its probe
+parameters plus `Chr` (`t89`), and typed-file block I/O (`t90`, compile-only:
+the harness has no filesystem). The next rung is text-file output. The runtime is 3,907 bytes / 39 entries and its probe
 scaffold is nearly full, so the next runtime addition must move HDR. Items 1-4
 below are independent of both tracks.
 

+ 74 - 6
shell/Compiler.mod

@@ -404,6 +404,7 @@ VAR
    TU_FileRewrite : CARDINAL ;
    TU_FileClose   : CARDINAL ;
    TU_IoResult    : CARDINAL ;
+   TU_IoStore     : CARDINAL ;  (* save AX as the last I/O status *)
    TU_CmpStr   : CARDINAL ;  (* string comparison; two addresses on the stack,
                                 signed -1/0/+1 in AX *)
    TU_StrCat   : CARDINAL ;  (* string concatenation; dest and source addresses
@@ -1494,6 +1495,40 @@ BEGIN
    END
 END EmStoreInd ;
 
+PROCEDURE EmFileIo (reading : BOOLEAN ; fileLocal : BOOLEAN ; fileOff : CARDINAL ;
+                    addrKind : CARDINAL ; addrLocal : BOOLEAN ;
+                    addrOff, count : CARDINAL) ;
+(* Typed-file block I/O: read/write `count' bytes at the data argument to the
+   open file in the file variable.
+
+   ABI to DOS: BX = handle, CX = byte count, DS:DX = buffer, AH = 3Fh read /
+   40h write.  The handle is the first word of the file control block.  For a
+   DI-addressed record (`Sheet[I,J]') the address is already in DI; a plain
+   variable's address is formed by LEA.  The DOS result is handed to the
+   io_store runtime entry, so IOResult sees it.
+
+   This is emitted directly rather than through a runtime entry because the
+   runtime has only ~45 bytes of probe headroom left; the code is two words
+   per call site and the compiler's code budget is the loose one. *)
+BEGIN
+   IF addrKind = 5 THEN
+      Ebyte (89H) ; Ebyte (0FAH)         (* MOV DX,DI *)
+   ELSIF addrKind = 1 THEN
+      EmLeaDi (addrLocal, addrOff) ;
+      Ebyte (89H) ; Ebyte (0FAH)         (* MOV DX,DI *)
+   ELSE
+      Err (ETypeErr) ;
+      RETURN
+   END ;
+   EmLoadVar (fileLocal, fileOff, 2) ;   (* AX := the DOS handle *)
+   Ebyte (89H) ; Ebyte (0C3H) ;          (* MOV BX,AX *)
+   EmMovCxi (count) ;
+   Ebyte (0B4H) ;                        (* MOV AH,3Fh/40h *)
+   IF reading THEN Ebyte (3FH) ELSE Ebyte (40H) END ;
+   Ebyte (0CDH) ; Ebyte (21H) ;          (* INT 21h *)
+   DropC (EmCall (TU_IoStore))
+END EmFileIo ;
+
 PROCEDURE EmSubSp (n : CARDINAL) ;
 BEGIN
    Ebyte (81H) ; Ebyte (0ECH) ; Eword (n MOD 10000H)
@@ -5027,12 +5062,12 @@ BEGIN
                argument as the last argument's value, and pushed an argument
                that an earlier inline string's call had already overwritten. *)
             skipArg := FALSE ;
-            IF (nArgs = 0) AND ((arg.cls = TText) OR (arg.cls = TFile)) THEN
-               (* A leading FILE argument: `Read(Kbd, Ch)'.  KBD is the console
-                  keyboard and this runtime's read entries already read the
-                  console, so the file is dropped and the rest of the argument
-                  list is read exactly as without it.  A real file is not
-                  implemented yet - loud, rather than silently reading the file
+            IF (nArgs = 0) AND (arg.cls = TText) THEN
+               (* A leading TEXT file argument.  KBD is the console keyboard
+                  and this runtime's read entries already read the console, so
+                  the file is dropped and the rest of the argument list is read
+                  exactly as without it.  Other text-file I/O is the next file
+                  increment and stays loud rather than reading the file
                   variable as a data argument. *)
                IF reading AND (arg.kind = 1) AND symtab [arg.idx].isKbd THEN
                   IF NOT MatchDelim (',') THEN
@@ -5044,6 +5079,38 @@ BEGIN
                   Err (ENoLib) ;
                   RETURN
                END
+            ELSIF (nArgs = 0) AND (arg.cls = TFile) THEN
+               (* Typed-file block I/O: `write(MCfile, Sheet[I,J])' and the
+                  symmetric `read(MCfile, Sheet[FX,FY])'.  TP3 moves exactly
+                  one element per call, so consume the single data argument
+                  here and emit the DOS block call.  The element size comes
+                  from the data expression and must agree with the file's
+                  declared element size; a mismatch is a type error, not a
+                  reason to write the wrong number of bytes. *)
+               IF (arg.kind # 1) OR NOT MatchDelim (',') THEN
+                  Err (ETypeErr) ;
+                  RETURN
+               END ;
+               ParseExpr (dummy) ;
+               IF NOT OK () THEN
+                  RETURN
+               END ;
+               IF ((dummy.kind # 1) AND (dummy.kind # 5))
+                  OR (VarSize (dummy) # symtab [arg.idx].elem) THEN
+                  Err (ETypeErr) ;
+                  RETURN
+               END ;
+               IF dummy.kind = 5 THEN
+                  EmFileIo (reading, symtab [arg.idx].local,
+                            symtab [arg.idx].off, 5, FALSE, 0, VarSize (dummy))
+               ELSE
+                  EmFileIo (reading, symtab [arg.idx].local,
+                            symtab [arg.idx].off, 1, symtab [dummy.idx].local,
+                            (symtab [dummy.idx].off + dummy.boff) MOD 10000H,
+                            VarSize (dummy))
+               END ;
+               ExpectDelim (')', ENoSemi) ;
+               RETURN
             END ;
             IF NOT skipArg THEN
             pushed := TRUE ;      (* default: value is on the stack -> call + pop *)
@@ -7012,6 +7079,7 @@ BEGIN
    TU_FileRewrite := RT_Entry (36) ;
    TU_FileClose   := RT_Entry (37) ;
    TU_IoResult    := RT_Entry (38) ;
+   TU_IoStore     := RT_Entry (39) ;
    TU_WrStr    := RT_Entry (15) ;      (* a string variable is written through
                                           the address on the stack *)
    TU_RdStr    := RT_Entry (16) ;      (* readln(s)/read(s): TPSRC8 prdstr,

+ 1 - 0
shell/Runtime.def

@@ -77,6 +77,7 @@ CONST
    E_FileRewrite = 36 ;     (* [BP+4]=file; DOS create/truncate *)
    E_FileClose = 37 ;       (* [BP+4]=file; DOS close if open *)
    E_IoResult = 38 ;        (* AX = last DOS status, then clear it *)
+   E_IoStore = 39 ;         (* AX = status; save it for IOResult *)
 
    (* File control block, mirrored by Compiler.FileVarSize. *)
    F_NameOff = 4 ;           (* handle word, mode word, then the name *)

+ 8 - 2
shell/Runtime.mod

@@ -155,7 +155,7 @@ VAR
    dataAt : CARDINAL ;
    rtBase : CARDINAL ;
    built  : BOOLEAN ;
-   entNm  : ARRAY [0..38] OF ARRAY [0..MaxNm] OF CHAR ;
+   entNm  : ARRAY [0..39] OF ARRAY [0..MaxNm] OF CHAR ;
 
 (* ---------------------------------------------------------------- *)
 (*  name helpers                                                     *)
@@ -3019,6 +3019,11 @@ BEGIN
    StDataImm (D_IORES, 0) ;
    RetR ;
 
+   (* Typed-file block I/O is lowered by the compiler to INT 21h; it calls
+      this with AX = the DOS result so the next IOResult can report it. *)
+   M ("io_store") ;
+   StDataAx (D_IORES) ;
+   RetR
 END EmitFileOps ;
 
 PROCEDURE EmitData ;
@@ -3270,6 +3275,7 @@ BEGIN
    SetStr (entNm [36], "file_rewrite") ;
    SetStr (entNm [37], "file_close") ;
    SetStr (entNm [38], "ioresult") ;
+   SetStr (entNm [39], "io_store") ;
    built := TRUE
 END RT_Build ;
 
@@ -3297,7 +3303,7 @@ BEGIN
    IF NOT built THEN
       RT_Build (0)
    END ;
-   IF i > 38 THEN
+   IF i > 39 THEN
       RETURN 0
    END ;
    RETURN rtBase + LblOff (entNm [i])

+ 4 - 3
shell/tests/RtProbe.mod

@@ -108,7 +108,7 @@ END PENT ;
 
 PROCEDURE Main ;
 VAR i, n, base : CARDINAL ;
-    names : ARRAY [0..38] OF ARRAY [0..15] OF CHAR ;
+    names : ARRAY [0..39] OF ARRAY [0..15] OF CHAR ;
 BEGIN
    base := GetBase () ;
    RT_Build (base) ;
@@ -121,7 +121,7 @@ BEGIN
    PCARD (RT_Size ()) ; PS (" bytes") ; NL ;
    PS ("code ends at ") ; PCARD (RT_CodeEnd ()) ; NL ;
    i := 0 ;
-   WHILE i <= 38 DO
+   WHILE i <= 39 DO
       names [i] := "" ;
       INC (i)
    END ;
@@ -151,8 +151,9 @@ BEGIN
    names [36] := "file_rewrite" ;
    names [37] := "file_close" ;
    names [38] := "ioresult" ;
+   names [39] := "io_store" ;
    i := 0 ;
-   WHILE i <= 38 DO
+   WHILE i <= 39 DO
       PENT (i, names [i]) ;
       INC (i)
    END ;

+ 1 - 0
shell/tests/audit_helpers.py

@@ -158,6 +158,7 @@ NON_ONE_LINE = {
         "EmitFileOps": COMP,
     },
     "Compiler.mod": {
+        "FileIo": COMP,        # typed-file INT 21h sequence; see EmFileIo
         "AddSp": PARAM, "SubSp": PARAM, "Setcc": PARAM,
         "Call": COMP, "Jcc": COMP, "JmpNear": COMP,
         "BpDisp": COMP, "LoadVar": COMP, "StoreVar": COMP,

+ 8 - 8
shell/tests/fixtures/calc_ladder.tsv

@@ -25,11 +25,11 @@
 # positions shift — which is exactly why this must be a measured number, not a
 # remembered one.
 #
-# Current rung (2026-10-22): `write(MCfile, Sheet[I,J])' in Save.  UpCase,
-# run-time set membership, string fields through DI, the original memory
-# layout, untyped-file declarations, file control-block operations, VAR string
-# parameters and Chr moved the ladder 15911 -> 18267 -> 19847 -> 20912 ->
-# 22253 -> 22280 -> 22706 -> 22859 -> 23700.  The next blocker is DATA I/O on
-# a typed file: a leading TFile argument to write/read, still refused with
-# ENoLib (TP3 error 102).
-CALC.PAS	ERR	102	23700
+# Current rung (2026-10-22): `Writeln(MCFile)' in Print.  UpCase, run-time set
+# membership, string fields through DI, the original memory layout, untyped-file
+# declarations, file control-block operations, VAR string parameters, Chr and
+# typed-file block I/O moved the ladder 15911 -> 18267 -> 19847 -> 20912 ->
+# 22253 -> 22280 -> 22706 -> 22859 -> 23700 -> 25674.  The next blocker is TEXT
+# file output (`Writeln(MCFile)`, `Write(MCFile,' ')`, `writeln(MCFile,Line)`),
+# still refused with ENoLib (TP3 error 102).
+CALC.PAS	ERR	102	25674

+ 8 - 0
shell/tests/fixtures/expected.tsv

@@ -643,3 +643,11 @@ t88_fileops	OK	109	137
 #                   Length through it, and a function takes a VAR string.  The
 #                   output is hand-derived from the Pascal: hello, 5, Hello!, H.
 t89_varstr	OK	390	276
+
+#   t90_fileio           typed-file block I/O: write/read a scalar and an
+#                   array element through a `file of Rec'.  Compile-only:
+#                   neither harness has a filesystem, so no hand-derived
+#                   successful execution output exists.  The emitted DOS
+#                   sequence and the runtime's io_store status path are the
+#                   checked parts.
+t90_fileio	OK	212	149

+ 35 - 0
shell/tests/fixtures/t90_fileio.pas

@@ -0,0 +1,35 @@
+program t90_fileio;
+
+{ t90 -- typed-file block I/O.  CALC.INC's Save and Load do
+
+      write (MCfile, Sheet[I,J]);
+      read  (MCFile, Sheet[FX,FY]);
+
+  where MCFile is `file of CellRec' and the data argument is a record
+  element.  This fixture compiles the scalar and variable-address forms and
+  the file operations around them.  It is compile-only: neither boot harness
+  has a filesystem, so there is no honest hand-derived execution output for a
+  successful open/read/write. }
+
+type
+  Rec = record
+    A, B : integer;
+  end;
+
+var
+  F : file of Rec;
+  X : Rec;
+  Rows : array [1..2] of Rec;
+begin
+  assign (F, 'T90.DAT');
+  rewrite (F);
+  X.A := 1;
+  X.B := 2;
+  write (F, X);
+  write (F, Rows[1]);
+  reset (F);
+  read (F, X);
+  read (F, Rows[2]);
+  close (F);
+  writeln ('file io compiled')
+end.

+ 2 - 1
shell/tests/rt_exec.py

@@ -113,7 +113,7 @@ ENTS = ["initmem", "progend", "stackchk", "wrint", "wrchar", "wrbool",
         "real_div", "real_cmp", "real_int", "real_fmt", "real_val",
         "real_write", "set_op", "set_cmp", "set_copy",
         "file_assign", "file_reset", "file_rewrite", "file_close",
-        "ioresult"]
+        "ioresult", "io_store"]
 
 # A call slot's flags, as rtdrv.s reads them.
 F_STACK = 1     # the argument goes on the stack, popped by the caller
@@ -491,6 +491,7 @@ def build_cases():
         dumpadr=FILEBLK,
         note="handle=FFFF, mode=0, then the NUL-terminated name")
 
+
     for v, why in [(0, "the one value where a signed/unsigned slip is invisible"),
                    (1, ""), (-1, ""), (7, ""), (10, ""), (42, ""),
                    (100, ""), (12345, ""), (-32768, "the sign bit"), (32767, "")]:

+ 103 - 101
shell/tests/runtime.golden

@@ -41,7 +41,7 @@
 0036  58          pop ax
 0037  F7 D8       neg ax
 0039  B9 0A 00    mov cx,0ah
-003C  BB 86 0F    mov bx,0f86h
+003C  BB 8A 0F    mov bx,0f8ah
 003F  89 DE       mov si,bx
 0041  31 D2       xor dx,dx
 0043  F7 F1       div ax,cx
@@ -93,7 +93,7 @@
 00A2  58          pop ax
 00A3  F7 D8       neg ax
 00A5  B9 0A 00    mov cx,0ah
-00A8  BB 86 0F    mov bx,0f86h
+00A8  BB 8A 0F    mov bx,0f8ah
 00AB  89 DE       mov si,bx
 00AD  31 D2       xor dx,dx
 00AF  F7 F1       div ax,cx
@@ -125,18 +125,18 @@
 00DE  83 7E 04 00 cmp word ptr [bp+4h],0h
 00E2  89 EC       mov sp,bp
 00E4  75 05       jne 0ebh
-00E6  BA 8B 0F    mov dx,0f8bh
+00E6  BA 8F 0F    mov dx,0f8fh
 00E9  EB 03       jmp 0eeh
-00EB  BA 86 0F    mov dx,0f86h
+00EB  BA 8A 0F    mov dx,0f8ah
 00EE  B4 09       mov ah,9h
 00F0  CD 21       int 21h
 00F2  5D          pop bp
 00F3  C3          ret
-00F4  BA 94 0F    mov dx,0f94h
+00F4  BA 98 0F    mov dx,0f98h
 00F7  B4 09       mov ah,9h
 00F9  CD 21       int 21h
 00FB  C3          ret
-00FC  BA 91 0F    mov dx,0f91h
+00FC  BA 95 0F    mov dx,0f95h
 00FF  B4 09       mov ah,9h
 0101  CD 21       int 21h
 0103  C3          ret
@@ -303,12 +303,12 @@
 0217  EB EF       jmp 208h
 0219  58          pop ax
 021A  C3          ret
-021B  8B 1E 9A 0F mov bx,word ptr [0f9ah]
+021B  8B 1E 9E 0F mov bx,word ptr [0f9eh]
 021F  83 FB 00    cmp bx,0h
 0222  74 09       je 22dh
 0224  8A C3       mov al,bl
 0226  31 DB       xor bx,bx
-0228  89 1E 9A 0F mov word ptr [0f9ah],bx
+0228  89 1E 9E 0F mov word ptr [0f9eh],bx
 022C  C3          ret
 022D  B4 08       mov ah,8h
 022F  CD 21       int 21h
@@ -316,7 +316,7 @@
 0232  88 C2       mov dl,al
 0234  BB 01 00    mov bx,1h
 0237  8A DA       mov bl,dl
-0239  89 1E 9A 0F mov word ptr [0f9ah],bx
+0239  89 1E 9E 0F mov word ptr [0f9eh],bx
 023D  C3          ret
 023E  55          push bp
 023F  8B EC       mov bp,sp
@@ -543,7 +543,7 @@
 03C2  8B 4D 06    mov cx,word ptr [di+6h]
 03C5  8B 75 08    mov si,word ptr [di+8h]
 03C8  8B 7D 0A    mov di,word ptr [di+0ah]
-03CB  C7 06 9C 0F 00 00 mov word ptr [0f9ch],0h
+03CB  C7 06 A0 0F 00 00 mov word ptr [0fa0h],0h
 03D1  E8 4D 00    call 421h
 03D4  5F          pop di
 03D5  89 05       mov word ptr [di],ax
@@ -572,7 +572,7 @@
 03FE  8B 4D 06    mov cx,word ptr [di+6h]
 0401  8B 75 08    mov si,word ptr [di+8h]
 0404  8B 7D 0A    mov di,word ptr [di+0ah]
-0407  C7 06 9C 0F 00 80 mov word ptr [0f9ch],8000h
+0407  C7 06 A0 0F 00 80 mov word ptr [0fa0h],8000h
 040D  E8 11 00    call 421h
 0410  5F          pop di
 0411  89 05       mov word ptr [di],ax
@@ -587,7 +587,7 @@
 0420  C3          ret
 0421  80 F9 00    cmp cl,0h
 0424  74 0E       je 434h
-0426  33 3E 9C 0F xor di,word ptr [0f9ch]
+0426  33 3E A0 0F xor di,word ptr [0fa0h]
 042A  3C 00       cmp al,0h
 042C  75 07       jne 435h
 042E  89 C8       mov ax,cx
@@ -599,16 +599,16 @@
 0439  91          xchg ax,cx
 043A  87 F3       xchg bx,si
 043C  87 FA       xchg dx,di
-043E  88 0E A0 0F mov byte ptr [0fa0h],cl
+043E  88 0E A4 0F mov byte ptr [0fa4h],cl
 0442  28 C1       sub cl,al
 0444  80 F9 28    cmp cl,28h
 0447  72 06       jb 44fh
-0449  8A 0E A0 0F mov cl,byte ptr [0fa0h]
+0449  8A 0E A4 0F mov cl,byte ptr [0fa4h]
 044D  EB DF       jmp 42eh
-044F  89 3E 9C 0F mov word ptr [0f9ch],di
-0453  80 26 9D 0F 80 and byte ptr [0f9dh],80h
-0458  89 3E 9E 0F mov word ptr [0f9eh],di
-045C  30 36 9F 0F xor byte ptr [0f9fh],dh
+044F  89 3E A0 0F mov word ptr [0fa0h],di
+0453  80 26 A1 0F 80 and byte ptr [0fa1h],80h
+0458  89 3E A2 0F mov word ptr [0fa2h],di
+045C  30 36 A3 0F xor byte ptr [0fa3h],dh
 0460  81 CF 00 80 or di,8000h
 0464  80 CE 80    or dh,80h
 0467  80 F9 10    cmp cl,10h
@@ -633,8 +633,8 @@
 0492  D0 DC       rcr ah,1h
 0494  FE C9       dec cl
 0496  75 F6       jne 48eh
-0498  A0 A0 0F    mov al,byte ptr [0fa0h]
-049B  F6 06 9F 0F 80 test byte ptr [0f9fh],80h
+0498  A0 A4 0F    mov al,byte ptr [0fa4h]
+049B  F6 06 A3 0F 80 test byte ptr [0fa3h],80h
 04A0  75 14       jne 4b6h
 04A2  00 EC       add ah,ch
 04A4  11 F3       adc bx,si
@@ -654,7 +654,7 @@
 04BE  19 F3       sbb bx,si
 04C0  19 FA       sbb dx,di
 04C2  73 14       jnb 4d8h
-04C4  80 36 9D 0F 80 xor byte ptr [0f9dh],80h
+04C4  80 36 A1 0F 80 xor byte ptr [0fa1h],80h
 04C9  F6 D4       not ah
 04CB  F7 D3       not bx
 04CD  F7 D2       not dx
@@ -686,7 +686,7 @@
 0506  31 D2       xor dx,dx
 0508  C3          ret
 0509  80 E6 7F    and dh,7fh
-050C  32 36 9D 0F xor dh,byte ptr [0f9dh]
+050C  32 36 A1 0F xor dh,byte ptr [0fa1h]
 0510  C3          ret
 0511  55          push bp
 0512  8B EC       mov bp,sp
@@ -732,23 +732,23 @@
 0565  B0 01       mov al,1h
 0567  B4 4C       mov ah,4ch
 0569  CD 21       int 21h
-056B  89 0E A7 0F mov word ptr [0fa7h],cx
+056B  89 0E AB 0F mov word ptr [0fabh],cx
 056F  8B CA       mov cx,dx
 0571  31 F9       xor cx,di
 0573  F6 D5       not ch
 0575  80 E5 80    and ch,80h
-0578  88 2E 9D 0F mov byte ptr [0f9dh],ch
+0578  88 2E A1 0F mov byte ptr [0fa1h],ch
 057C  80 CE 80    or dh,80h
 057F  81 CF 00 80 or di,8000h
-0583  89 36 A9 0F mov word ptr [0fa9h],si
-0587  89 3E AB 0F mov word ptr [0fabh],di
-058B  A3 A1 0F    mov word ptr [0fa1h],ax
-058E  89 1E A3 0F mov word ptr [0fa3h],bx
-0592  89 16 A5 0F mov word ptr [0fa5h],dx
+0583  89 36 AD 0F mov word ptr [0fadh],si
+0587  89 3E AF 0F mov word ptr [0fafh],di
+058B  A3 A5 0F    mov word ptr [0fa5h],ax
+058E  89 1E A7 0F mov word ptr [0fa7h],bx
+0592  89 16 A9 0F mov word ptr [0fa9h],dx
 0596  30 E4       xor ah,ah
 0598  31 DB       xor bx,bx
 059A  31 D2       xor dx,dx
-059C  BF A7 0F    mov di,0fa7h
+059C  BF AB 0F    mov di,0fabh
 059F  B1 05       mov cl,5h
 05A1  47          inc di
 05A2  8A 2D       mov ch,byte ptr [di]
@@ -763,9 +763,9 @@
 05B5  BE 08 00    mov si,8h
 05B8  D0 DD       rcr ch,1h
 05BA  73 0C       jnb 5c8h
-05BC  02 26 A2 0F add ah,byte ptr [0fa2h]
-05C0  13 1E A3 0F adc bx,word ptr [0fa3h]
-05C4  13 16 A5 0F adc dx,word ptr [0fa5h]
+05BC  02 26 A6 0F add ah,byte ptr [0fa6h]
+05C0  13 1E A7 0F adc bx,word ptr [0fa7h]
+05C4  13 16 A9 0F adc dx,word ptr [0fa9h]
 05C8  D1 DA       rcr dx,1h
 05CA  D1 DB       rcr bx,1h
 05CC  D0 DC       rcr ah,1h
@@ -785,7 +785,7 @@
 05E6  74 02       je 5eah
 05E8  FE C9       dec cl
 05EA  91          xchg ax,cx
-05EB  32 36 9D 0F xor dh,byte ptr [0f9dh]
+05EB  32 36 A1 0F xor dh,byte ptr [0fa1h]
 05EF  3C 00       cmp al,0h
 05F1  75 06       jne 5f9h
 05F3  31 C0       xor ax,ax
@@ -834,29 +834,29 @@
 0647  B0 01       mov al,1h
 0649  B4 4C       mov ah,4ch
 064B  CD 21       int 21h
-064D  89 0E A7 0F mov word ptr [0fa7h],cx
+064D  89 0E AB 0F mov word ptr [0fabh],cx
 0651  8B CA       mov cx,dx
 0653  31 F9       xor cx,di
 0655  F6 D5       not ch
 0657  80 E5 80    and ch,80h
-065A  88 2E 9D 0F mov byte ptr [0f9dh],ch
+065A  88 2E A1 0F mov byte ptr [0fa1h],ch
 065E  80 CE 80    or dh,80h
 0661  81 CF 00 80 or di,8000h
-0665  89 36 A9 0F mov word ptr [0fa9h],si
-0669  89 3E AB 0F mov word ptr [0fabh],di
-066D  A2 A1 0F    mov byte ptr [0fa1h],al
-0670  BF A6 0F    mov di,0fa6h
+0665  89 36 AD 0F mov word ptr [0fadh],si
+0669  89 3E AF 0F mov word ptr [0fafh],di
+066D  A2 A5 0F    mov byte ptr [0fa5h],al
+0670  BF AA 0F    mov di,0faah
 0673  B1 05       mov cl,5h
 0675  BE 08 00    mov si,8h
-0678  3B 16 AB 0F cmp dx,word ptr [0fabh]
+0678  3B 16 AF 0F cmp dx,word ptr [0fafh]
 067C  75 0A       jne 688h
-067E  3B 1E A9 0F cmp bx,word ptr [0fa9h]
+067E  3B 1E AD 0F cmp bx,word ptr [0fadh]
 0682  75 04       jne 688h
-0684  3A 26 A8 0F cmp ah,byte ptr [0fa8h]
+0684  3A 26 AC 0F cmp ah,byte ptr [0fach]
 0688  72 0C       jb 696h
-068A  2A 26 A8 0F sub ah,byte ptr [0fa8h]
-068E  1B 1E A9 0F sbb bx,word ptr [0fa9h]
-0692  1B 16 AB 0F sbb dx,word ptr [0fabh]
+068A  2A 26 AC 0F sub ah,byte ptr [0fach]
+068E  1B 1E AD 0F sbb bx,word ptr [0fadh]
+0692  1B 16 AF 0F sbb dx,word ptr [0fafh]
 0696  F5          cmc
 0697  D0 D5       rcl ch,1h
 0699  4E          dec si
@@ -870,24 +870,24 @@
 06A8  D1 D3       rcl bx,1h
 06AA  D1 D2       rcl dx,1h
 06AC  73 CA       jnb 678h
-06AE  2A 26 A8 0F sub ah,byte ptr [0fa8h]
-06B2  1B 1E A9 0F sbb bx,word ptr [0fa9h]
-06B6  1B 16 AB 0F sbb dx,word ptr [0fabh]
+06AE  2A 26 AC 0F sub ah,byte ptr [0fach]
+06B2  1B 1E AD 0F sbb bx,word ptr [0fadh]
+06B6  1B 16 AF 0F sbb dx,word ptr [0fafh]
 06BA  F8          clc
 06BB  EB D9       jmp 696h
 06BD  D0 E4       shl ah,1h
 06BF  D1 D3       rcl bx,1h
 06C1  D1 D2       rcl dx,1h
 06C3  72 11       jb 6d6h
-06C5  3B 16 AB 0F cmp dx,word ptr [0fabh]
+06C5  3B 16 AF 0F cmp dx,word ptr [0fafh]
 06C9  75 0A       jne 6d5h
-06CB  3B 1E A9 0F cmp bx,word ptr [0fa9h]
+06CB  3B 1E AD 0F cmp bx,word ptr [0fadh]
 06CF  75 04       jne 6d5h
-06D1  3A 26 A8 0F cmp ah,byte ptr [0fa8h]
+06D1  3A 26 AC 0F cmp ah,byte ptr [0fach]
 06D5  F5          cmc
-06D6  8B 0E A1 0F mov cx,word ptr [0fa1h]
-06DA  8B 1E A3 0F mov bx,word ptr [0fa3h]
-06DE  8B 16 A5 0F mov dx,word ptr [0fa5h]
+06D6  8B 0E A5 0F mov cx,word ptr [0fa5h]
+06DA  8B 1E A7 0F mov bx,word ptr [0fa7h]
+06DE  8B 16 A9 0F mov dx,word ptr [0fa9h]
 06E2  9F          lahf
 06E3  F6 C6 80    test dh,80h
 06E6  75 09       jne 6f1h
@@ -1030,47 +1030,47 @@
 07EC  B5 00       mov ch,0h
 07EE  B6 00       mov dh,0h
 07F0  51          push cx
-07F1  BB F7 0F    mov bx,0ff7h
+07F1  BB FB 0F    mov bx,0ffbh
 07F4  E8 41 02    call 0a38h
 07F7  59          pop cx
 07F8  89 D8       mov ax,bx
-07FA  BB F7 0F    mov bx,0ff7h
+07FA  BB FB 0F    mov bx,0ffbh
 07FD  2B C3       sub ax,bx
-07FF  A3 37 10    mov word ptr [1037h],ax
-0802  89 0E 39 10 mov word ptr [1039h],cx
-0806  8B 06 39 10 mov ax,word ptr [1039h]
-080A  8B 16 37 10 mov dx,word ptr [1037h]
+07FF  A3 3B 10    mov word ptr [103bh],ax
+0802  89 0E 3D 10 mov word ptr [103dh],cx
+0806  8B 06 3D 10 mov ax,word ptr [103dh]
+080A  8B 16 3B 10 mov dx,word ptr [103bh]
 080E  2B C2       sub ax,dx
 0810  83 F8 00    cmp ax,0h
 0813  7D 02       jnl 817h
 0815  31 C0       xor ax,ax
-0817  A3 3B 10    mov word ptr [103bh],ax
-081A  8B 16 37 10 mov dx,word ptr [1037h]
+0817  A3 3F 10    mov word ptr [103fh],ax
+081A  8B 16 3B 10 mov dx,word ptr [103bh]
 081E  03 C2       add ax,dx
 0820  3D FF 00    cmp ax,0ffh
 0823  77 03       jnbe 828h
 0825  E9 03 00    jmp 82bh
 0828  B8 FF 00    mov ax,0ffh
-082B  A3 3D 10    mov word ptr [103dh],ax
+082B  A3 41 10    mov word ptr [1041h],ax
 082E  8B 56 06    mov dx,word ptr [bp+6h]
 0831  89 D7       mov di,dx
 0833  88 05       mov byte ptr [di],al
 0835  47          inc di
-0836  8B 0E 3B 10 mov cx,word ptr [103bh]
+0836  8B 0E 3F 10 mov cx,word ptr [103fh]
 083A  E3 07       jcxz 843h
 083C  B0 20       mov al,20h
 083E  88 05       mov byte ptr [di],al
 0840  47          inc di
 0841  E2 F9       loop 83ch
-0843  BE F7 0F    mov si,0ff7h
-0846  8B 0E 37 10 mov cx,word ptr [1037h]
+0843  BE FB 0F    mov si,0ffbh
+0846  8B 0E 3B 10 mov cx,word ptr [103bh]
 084A  E3 08       jcxz 854h
 084C  8A 04       mov al,byte ptr [si]
 084E  88 05       mov byte ptr [di],al
 0850  46          inc si
 0851  47          inc di
 0852  E2 F8       loop 84ch
-0854  8B 06 3D 10 mov ax,word ptr [103dh]
+0854  8B 06 41 10 mov ax,word ptr [1041h]
 0858  5F          pop di
 0859  5E          pop si
 085A  5A          pop dx
@@ -1086,12 +1086,12 @@
 0866  57          push di
 0867  8B 5E 04    mov bx,word ptr [bp+4h]
 086A  8B 7E 06    mov di,word ptr [bp+6h]
-086D  89 1E 3F 10 mov word ptr [103fh],bx
+086D  89 1E 43 10 mov word ptr [1043h],bx
 0871  E8 CF 02    call 0b43h
 0874  73 03       jnb 879h
 0876  E9 0B 00    jmp 884h
 0879  89 D8       mov ax,bx
-087B  8B 16 3F 10 mov dx,word ptr [103fh]
+087B  8B 16 43 10 mov dx,word ptr [1043h]
 087F  2B C2       sub ax,dx
 0881  E9 03 00    jmp 887h
 0884  B8 FF FF    mov ax,0ffffh
@@ -1140,7 +1140,7 @@
 08CE  52          push dx
 08CF  53          push bx
 08D0  50          push ax
-08D1  88 0E B9 0F mov byte ptr [0fb9h],cl
+08D1  88 0E BD 0F mov byte ptr [0fbdh],cl
 08D5  80 F9 00    cmp cl,0h
 08D8  78 03       js 8ddh
 08DA  E9 02 00    jmp 8dfh
@@ -1151,7 +1151,7 @@
 08E6  D0 EB       shr bl,1h
 08E8  00 FB       add bl,bh
 08EA  30 FF       xor bh,bh
-08EC  8D BF BB 0F lea di,[bx+0fbbh]
+08EC  8D BF BF 0F lea di,[bx+0fbfh]
 08F0  8B 05       mov ax,word ptr [di]
 08F2  8B 5D 02    mov bx,word ptr [di+2h]
 08F5  8B 55 04    mov dx,word ptr [di+4h]
@@ -1168,7 +1168,7 @@
 0910  58          pop ax
 0911  5B          pop bx
 0912  5A          pop dx
-0913  F6 06 B9 0F 80 test byte ptr [0fb9h],80h
+0913  F6 06 BD 0F 80 test byte ptr [0fbdh],80h
 0918  74 03       je 91dh
 091A  E9 03 00    jmp 920h
 091D  E9 27 FC    jmp 547h
@@ -1195,11 +1195,11 @@
 0947  3C 00       cmp al,0h
 0949  74 03       je 94eh
 094B  E9 16 00    jmp 964h
-094E  BE AD 0F    mov si,0fadh
+094E  BE B1 0F    mov si,0fb1h
 0951  C7 04 30 30 mov word ptr [si],3030h
 0955  46          inc si
 0956  46          inc si
-0957  81 FE B9 0F cmp si,0fb9h
+0957  81 FE BD 0F cmp si,0fbdh
 095B  74 03       je 960h
 095D  E9 F1 FF    jmp 951h
 0960  B9 00 00    mov cx,0h
@@ -1243,7 +1243,7 @@
 09AF  FE C9       dec cl
 09B1  74 03       je 9b6h
 09B3  E9 F3 FF    jmp 9a9h
-09B6  BE AD 0F    mov si,0fadh
+09B6  BE B1 0F    mov si,0fb1h
 09B9  88 F5       mov ch,dh
 09BB  B1 04       mov cl,4h
 09BD  D2 ED       shr ch,cl
@@ -1269,13 +1269,13 @@
 09E1  D1 D3       rcl bx,1h
 09E3  D1 D2       rcl dx,1h
 09E5  46          inc si
-09E6  81 FE B9 0F cmp si,0fb9h
+09E6  81 FE BD 0F cmp si,0fbdh
 09EA  74 03       je 9efh
 09EC  E9 CA FF    jmp 9b9h
 09EF  59          pop cx
 09F0  C3          ret
 09F1  30 E4       xor ah,ah
-09F3  BB AD 0F    mov bx,0fadh
+09F3  BB B1 0F    mov bx,0fb1h
 09F6  03 D8       add bx,ax
 09F8  80 3F 35    cmp byte ptr [bx],35h
 09FB  C6 07 00    mov byte ptr [bx],0h
@@ -1346,7 +1346,7 @@
 0A92  00 C8       add al,cl
 0A94  78 03       js 0a99h
 0A96  E9 08 00    jmp 0aa1h
-0A99  C6 06 AD 0F 00 mov byte ptr [0fadh],0h
+0A99  C6 06 B1 0F 00 mov byte ptr [0fb1h],0h
 0A9E  E9 0C 00    jmp 0aadh
 0AA1  3C 0C       cmp al,0ch
 0AA3  73 03       jnb 0aa8h
@@ -1354,7 +1354,7 @@
 0AA8  B0 0B       mov al,0bh
 0AAA  E8 44 FF    call 9f1h
 0AAD  5B          pop bx
-0AAE  BE AD 0F    mov si,0fadh
+0AAE  BE B1 0F    mov si,0fb1h
 0AB1  F6 C5 80    test ch,80h
 0AB4  75 03       jne 0ab9h
 0AB6  E9 05 00    jmp 0abeh
@@ -1440,7 +1440,7 @@
 0B75  31 DB       xor bx,bx
 0B77  31 D2       xor dx,dx
 0B79  31 C9       xor cx,cx
-0B7B  C6 06 BA 0F 00 mov byte ptr [0fbah],0h
+0B7B  C6 06 BE 0F 00 mov byte ptr [0fbeh],0h
 0B80  8A 0C       mov cl,byte ptr [si]
 0B82  80 F9 61    cmp cl,61h
 0B85  73 03       jnb 0b8ah
@@ -1469,7 +1469,7 @@
 0BB5  58          pop ax
 0BB6  5B          pop bx
 0BB7  5A          pop dx
-0BB8  C7 06 9C 0F 00 00 mov word ptr [0f9ch],0h
+0BB8  C7 06 A0 0F 00 00 mov word ptr [0fa0h],0h
 0BBE  E8 60 F8    call 421h
 0BC1  59          pop cx
 0BC2  5E          pop si
@@ -1477,7 +1477,7 @@
 0BC4  F6 C5 40    test ch,40h
 0BC7  75 03       jne 0bcch
 0BC9  E9 04 00    jmp 0bd0h
-0BCC  FE 0E BA 0F dec byte ptr [0fbah]
+0BCC  FE 0E BE 0F dec byte ptr [0fbeh]
 0BD0  46          inc si
 0BD1  E9 AC FF    jmp 0b80h
 0BD4  80 F9 2E    cmp cl,2eh
@@ -1489,7 +1489,7 @@
 0BE4  80 CD 40    or ch,40h
 0BE7  E9 E6 FF    jmp 0bd0h
 0BEA  80 F9 45    cmp cl,45h
-0BED  8A 0E BA 0F mov cl,byte ptr [0fbah]
+0BED  8A 0E BE 0F mov cl,byte ptr [0fbeh]
 0BF1  74 03       je 0bf6h
 0BF3  E9 4D 00    jmp 0c43h
 0BF6  E8 2A FD    call 923h
@@ -1555,31 +1555,31 @@
 0C77  56          push si
 0C78  57          push di
 0C79  8B 46 06    mov ax,word ptr [bp+6h]
-0C7C  A3 39 10    mov word ptr [1039h],ax
+0C7C  A3 3D 10    mov word ptr [103dh],ax
 0C7F  8B 56 04    mov dx,word ptr [bp+4h]
 0C82  8B 4E 06    mov cx,word ptr [bp+6h]
 0C85  8B 7E 08    mov di,word ptr [bp+8h]
-0C88  BB F7 0F    mov bx,0ff7h
+0C88  BB FB 0F    mov bx,0ffbh
 0C8B  E8 AA FD    call 0a38h
 0C8E  89 D8       mov ax,bx
-0C90  BB F7 0F    mov bx,0ff7h
+0C90  BB FB 0F    mov bx,0ffbh
 0C93  2B C3       sub ax,bx
-0C95  A3 37 10    mov word ptr [1037h],ax
-0C98  8B 06 39 10 mov ax,word ptr [1039h]
-0C9C  8B 16 37 10 mov dx,word ptr [1037h]
+0C95  A3 3B 10    mov word ptr [103bh],ax
+0C98  8B 06 3D 10 mov ax,word ptr [103dh]
+0C9C  8B 16 3B 10 mov dx,word ptr [103bh]
 0CA0  2B C2       sub ax,dx
 0CA2  83 F8 00    cmp ax,0h
 0CA5  7D 02       jnl 0ca9h
 0CA7  31 C0       xor ax,ax
-0CA9  A3 3B 10    mov word ptr [103bh],ax
-0CAC  8B 0E 3B 10 mov cx,word ptr [103bh]
+0CA9  A3 3F 10    mov word ptr [103fh],ax
+0CAC  8B 0E 3F 10 mov cx,word ptr [103fh]
 0CB0  E3 08       jcxz 0cbah
 0CB2  B0 20       mov al,20h
 0CB4  B4 02       mov ah,2h
 0CB6  CD 21       int 21h
 0CB8  E2 F8       loop 0cb2h
-0CBA  BE F7 0F    mov si,0ff7h
-0CBD  8B 0E 37 10 mov cx,word ptr [1037h]
+0CBA  BE FB 0F    mov si,0ffbh
+0CBD  8B 0E 3B 10 mov cx,word ptr [103bh]
 0CC1  E3 09       jcxz 0ccch
 0CC3  8A 04       mov al,byte ptr [si]
 0CC5  B4 02       mov ah,2h
@@ -1750,14 +1750,14 @@
 0DE4  B8 01 00    mov ax,1h
 0DE7  89 45 02    mov word ptr [di+2h],ax
 0DEA  31 C0       xor ax,ax
-0DEC  A3 41 10    mov word ptr [1041h],ax
+0DEC  A3 45 10    mov word ptr [1045h],ax
 0DEF  EB 10       jmp 0e01h
 0DF1  89 C3       mov bx,ax
 0DF3  B8 FF FF    mov ax,0ffffh
 0DF6  89 05       mov word ptr [di],ax
 0DF8  31 C0       xor ax,ax
 0DFA  89 45 02    mov word ptr [di+2h],ax
-0DFD  89 1E 41 10 mov word ptr [1041h],bx
+0DFD  89 1E 45 10 mov word ptr [1045h],bx
 0E01  5F          pop di
 0E02  5A          pop dx
 0E03  59          pop cx
@@ -1781,14 +1781,14 @@
 0E21  B8 02 00    mov ax,2h
 0E24  89 45 02    mov word ptr [di+2h],ax
 0E27  31 C0       xor ax,ax
-0E29  A3 41 10    mov word ptr [1041h],ax
+0E29  A3 45 10    mov word ptr [1045h],ax
 0E2C  EB 10       jmp 0e3eh
 0E2E  89 C3       mov bx,ax
 0E30  B8 FF FF    mov ax,0ffffh
 0E33  89 05       mov word ptr [di],ax
 0E35  31 C0       xor ax,ax
 0E37  89 45 02    mov word ptr [di+2h],ax
-0E3A  89 1E 41 10 mov word ptr [1041h],bx
+0E3A  89 1E 45 10 mov word ptr [1045h],bx
 0E3E  5F          pop di
 0E3F  5A          pop dx
 0E40  59          pop cx
@@ -1813,13 +1813,15 @@
 0E61  89 05       mov word ptr [di],ax
 0E63  31 C0       xor ax,ax
 0E65  89 45 02    mov word ptr [di+2h],ax
-0E68  89 1E 41 10 mov word ptr [1041h],bx
+0E68  89 1E 45 10 mov word ptr [1045h],bx
 0E6C  5F          pop di
 0E6D  5A          pop dx
 0E6E  5B          pop bx
 0E6F  89 EC       mov sp,bp
 0E71  5D          pop bp
 0E72  C3          ret
-0E73  8B 06 41 10 mov ax,word ptr [1041h]
-0E77  C7 06 41 10 00 00 mov word ptr [1041h],0h
+0E73  8B 06 45 10 mov ax,word ptr [1045h]
+0E77  C7 06 45 10 00 00 mov word ptr [1045h],0h
 0E7D  C3          ret
+0E7E  A3 45 10    mov word ptr [1045h],ax
+0E81  C3          ret