This version works.
authorGregory Minshall <minshall@ucbvax.Berkeley.EDU>
Thu, 21 May 1987 03:24:13 +0000 (19:24 -0800)
committerGregory Minshall <minshall@ucbvax.Berkeley.EDU>
Thu, 21 May 1987 03:24:13 +0000 (19:24 -0800)
SCCS-vsn: usr.bin/tn3270/distribution/sys_dos/termout.c 1.5
SCCS-vsn: usr.bin/tn3270/distribution/sys_dos/spint.h 1.2
SCCS-vsn: usr.bin/tn3270/distribution/sys_dos/spintasm.asm 1.3
SCCS-vsn: usr.bin/tn3270/distribution/sys_dos/spintc.c 1.3

usr/src/usr.bin/tn3270/distribution/sys_dos/spint.h
usr/src/usr.bin/tn3270/distribution/sys_dos/spintasm.asm
usr/src/usr.bin/tn3270/distribution/sys_dos/spintc.c
usr/src/usr.bin/tn3270/distribution/sys_dos/termout.c

index 20559cb..2072452 100644 (file)
@@ -11,4 +11,4 @@ typedef struct {
     int                        int_no; /* Which interrupt to wait on */
     int                        done;   /* Are we done, or just took an interrupt? */
     int                        rc;     /* return code */
     int                        int_no; /* Which interrupt to wait on */
     int                        done;   /* Are we done, or just took an interrupt? */
     int                        rc;     /* return code */
-} Spawn;
+} Spint;
index bfe70ff..5d9b009 100644 (file)
@@ -1,29 +1,29 @@
 ;
 ;
-; The code in this file complete the spawn_int calls
+; The code in this file complete the spint calls
 ;
 
 ;
 
-spawn  struc
+spint  struc
 ; union REGS
 ; union REGS
-spawn_ax       dw      1
-spawn_bx       dw      1
-spawn_cx       dw      1
-spawn_dx       dw      1
-spawn_si       dw      1
-spawn_di       dw      1
-spawn_cflag    dw      1
+spint_ax       dw      1
+spint_bx       dw      1
+spint_cx       dw      1
+spint_dx       dw      1
+spint_si       dw      1
+spint_di       dw      1
+spint_cflag    dw      1
 ; struct SREGS
 ; struct SREGS
-spawn_es       dw      1
-spawn_cs       dw      1
-spawn_ss       dw      1
-spawn_ds       dw      1
+spint_es       dw      1
+spint_cs       dw      1
+spint_ss       dw      1
+spint_ds       dw      1
 ; int intno
 ; int intno
-spawn_intno    dw      1
+spint_intno    dw      1
 ; int done
 ; int done
-spawn_done     dw      1
+spint_done     dw      1
 ; int rc
 ; int rc
-spawn_rc       dw      1
+spint_rc       dw      1
 ;
 ;
-spawn  ends
+spint  ends
 
 
 ENTER  MACRO
 
 
 ENTER  MACRO
@@ -42,15 +42,17 @@ ENTER       MACRO
        push    es
        pushf
 
        push    es
        pushf
 
-       mov     cs:save_sp, sp
-       mov     cs:save_ss, ss
+       mov     cs:start_sp, sp
+       mov     cs:start_ss, ss
        ; End enter
        ENDM
 
 LEAVE  MACRO
        ; Begin leave
        ; End enter
        ENDM
 
 LEAVE  MACRO
        ; Begin leave
-       mov     sp, cs:save_sp
-       mov     ss, cs:save_ss
+       cli
+       mov     sp, cs:start_sp
+       mov     ss, cs:start_ss
+       sti
 
        popf
        pop     es
 
        popf
        pop     es
@@ -71,19 +73,19 @@ LEAVE       MACRO
 
 GETREGS        MACRO   wherefrom
        mov     si, wherefrom
 
 GETREGS        MACRO   wherefrom
        mov     si, wherefrom
-       mov     spawn_segment, ds
-       mov     spawn_offset, si
-
-       mov     ax, spawn_ax[si]
-       mov     bx, spawn_bx[si]
-       mov     cx, spawn_cx[si]
-       mov     dx, spawn_dx[si]
-       ; XXX mov       si, spawn_si[si]
-       mov     di, spawn_di[si]
-       mov     es, spawn_es[si]
+       mov     spint_segment, ds
+       mov     spint_offset, si
+
+       mov     ax, spint_ax[si]
+       mov     bx, spint_bx[si]
+       mov     cx, spint_cx[si]
+       mov     dx, spint_dx[si]
+       ; XXX mov       si, spint_si[si]
+       mov     di, spint_di[si]
+       mov     es, spint_es[si]
        ; Now, need to do DS, SI
        ; Now, need to do DS, SI
-       push    spawn_ds[si]
-       mov     si, spawn_si[si]
+       push    spint_ds[si]
+       mov     si, spint_si[si]
        pop     ds
        ENDM
 
        pop     ds
        ENDM
 
@@ -92,26 +94,26 @@ SETREGS     MACRO
        mov     cs:old_si, si
        mov     cs:old_ds, ds
 
        mov     cs:old_si, si
        mov     cs:old_ds, ds
 
-       mov     ds, cs:spawn_segment
-       mov     si, cs:spawn_offset
+       mov     ds, cs:spint_segment
+       mov     si, cs:spint_offset
 
 
-       mov     spawn_ax[si], ax
-       mov     spawn_bx[si], bx
-       mov     spawn_cx[si], cx
-       mov     spawn_dx[si], dx
+       mov     spint_ax[si], ax
+       mov     spint_bx[si], bx
+       mov     spint_cx[si], cx
+       mov     spint_dx[si], dx
 
 
-       mov     spawn_si[si], si
-       mov     spawn_di[si], di
+       mov     spint_si[si], si
+       mov     spint_di[si], di
 
 
-       mov     spawn_cs[si], cs
-       mov     spawn_ds[si], ds
-       mov     spawn_es[si], es
-       mov     spawn_ss[si], ss
+       mov     spint_cs[si], cs
+       mov     spint_ds[si], ds
+       mov     spint_es[si], es
+       mov     spint_ss[si], ss
        ; now, need to do SI, DS
        mov     ax, old_si
        ; now, need to do SI, DS
        mov     ax, old_si
-       mov     spawn_si[si], ax
+       mov     spint_si[si], ax
        mov     ax, old_ds
        mov     ax, old_ds
-       mov     spawn_ds[si], ax
+       mov     spint_ds[si], ax
        ENDM
 
 
        ENDM
 
 
@@ -133,68 +135,85 @@ DGROUP    group   CONST, _BSS, _DATA
 
 _TEXT  segment
 
 
 _TEXT  segment
 
-save_sp                dw      1               ; For use in our 'longjmp'
-save_ss                dw      1               ; For use in our 'longjmp'
+start_sp       dw      1 dup (?)       ; For use in our 'longjmp'
+start_ss       dw      1 dup (?)       ; For use in our 'longjmp'
 
 
-spawn_segment  dw      1               ; Segment of spawn control block
-spawn_offset   dw      1               ; Offset of spawn control block
+spint_segment  dw      1 dup (?)       ; Segment of spawn control block
+spint_offset   dw      1 dup (?)       ; Offset of spawn control block
 
 
-old_si         dw      1               ; SI of interrupt issuer (temporary)
-old_ds         dw      1               ; DS of interrupt issuer (temporary)
+old_si         dw      1 dup (?)       ; SI of interrupt issuer (temporary)
+old_ds         dw      1 dup (?)       ; DS of interrupt issuer (temporary)
 
 
-issuer_sp      dw      1               ; sp of person who called us (permanent)
+issuer_ss      dw      1 dup (?)       ; ss of person who called us (permanent)
+issuer_sp      dw      1 dup (?)       ; sp of person who called us (permanent)
+
+int21_stack    db      100 dup (?)     ; Stack for int21.
 
 ;
 
 ;
-; int_spawn gets control on an interrupt.  It switches the stack
-; and does a 'return' from start_spawn.
+; _spint_int gets control on an interrupt.  It switches the stack
+; and does a 'return' from _spint_start.
 ;
 ;
-       public  _int_spawn
+       public  __spint_int
 
 
-_int_spawn     proc    near
+__spint_int    proc    near
        mov     cs:issuer_sp, sp
        mov     cs:issuer_sp, sp
+       mov     cs:issuer_ss, ss
+       sti
 
        SETREGS
 
        LEAVE
 
        SETREGS
 
        LEAVE
-_int_spawn     endp
+__spint_int    endp
 
 ;
 
 ;
-; start_spawn issues the dos interrupt after setting up the passed
-; registers.  When control returns to it, it sets spawn->done to non-zero.
+; _spint_start issues the dos interrupt after setting up the passed
+; registers.  When control returns to it, it sets spint->done to non-zero.
 ;
 ;
-       public  _start_spawn
+       public  __spint_start
 
 
-_start_spawn   proc    near
+__spint_start  proc    near
        ENTER
 
        GETREGS 4[bp]
 
        ENTER
 
        GETREGS 4[bp]
 
+       ; Now, switch to a different (short) stack.  This is so
+       ; that our games won't mess up the stack int 21 (hardware and,
+       ; possibly, software) stores things on.
+
+       cli
+       mov     cs:int21_stack, cs
+       mov     ss, cs:int21_stack
+       mov     sp, offset int21_stack
+       add     sp, (length int21_stack) - 4
+       sti
+
        int     21H             ; Issue DOS interrupt
 
        SETREGS
 
        int     21H             ; Issue DOS interrupt
 
        SETREGS
 
-       mov     ds, cs:spawn_segment
-       mov     si, cs:spawn_offset
-       mov     spawn_done[si], 1       ; We are done
+       mov     ds, cs:spint_segment
+       mov     si, cs:spint_offset
+       mov     spint_done[si], 1       ; We are done
 
        LEAVE
 
        LEAVE
-_start_spawn   endp
+__spint_start  endp
 
 ;
 
 ;
-; After int_spawn has faked a return from start_spawn, we come here to
+; After _spint_int has faked a return from start_spawn, we come here to
 ; return to the interrupt issuer.
 ;
 ; return to the interrupt issuer.
 ;
-       public  _continue_spawn
+       public  __spint_continue
 
 
-_continue_spawn        proc    near
+__spint_continue       proc    near
        ENTER
 
        GETREGS 4[bp]
 
        mov     sp, cs:issuer_sp                ; Restore SP
        ENTER
 
        GETREGS 4[bp]
 
        mov     sp, cs:issuer_sp                ; Restore SP
+       mov     ss, cs:issuer_ss                ; Restore SS
 
        iret
 
        iret
-_continue_spawn        endp
+__spint_continue       endp
 
 _TEXT  ends
 
 
 _TEXT  ends
 
index 3350bd3..6375029 100644 (file)
@@ -22,15 +22,64 @@ typedef struct {
        fcb2_ptr_segment;       /* Segment of FCB 2 */
 } ExecList;
 
        fcb2_ptr_segment;       /* Segment of FCB 2 */
 } ExecList;
 
+
+static int int_offset, int_segment;
+
+
 void
 void
-do_spawn(command, spawn)
+spint_finish(spint)
+Spint *spint;
+{
+    union REGS regs;
+    struct SREGS sregs;
+
+    if (spint->done == 0) {
+       return;                         /* Not done yet */
+    }
+
+    /*
+     * Restore old interrupt handler.
+     */
+
+    regs.h.ah = 0x25;
+    regs.h.al = spint->int_no;
+    regs.x.dx = int_offset;
+    sregs.ds = int_segment;
+    intdosx(&regs, &regs, &sregs);
+
+    if (spint->regs.x.cflag) {
+       fprintf(stderr, "0x%x return code from EXEC.\n", spint->regs.x.ax);
+       spint->done = 1;
+       spint->rc = 99;
+       return;
+    }
+
+    regs.h.ah = 0x4d;                  /* Get return code */
+
+    intdos(&regs, &regs);
+
+    spint->rc = regs.x.ax;
+}
+
+void
+spint_continue(spint)
+Spint *spint;
+{
+    _spint_continue(spint);            /* Return to caller */
+    spint_finish(spint);
+}
+
+
+void
+spint_start(command, spint)
 char *command;
 char *command;
-Spawn *spawn;
+Spint *spint;
 {
     ExecList mylist;
     char *comspec;
 {
     ExecList mylist;
     char *comspec;
-    void int_spawn();
-    int int_offset, int_segment;
+    void _spint_int();
+    union REGS regs;
+    struct SREGS sregs;
 
     /*
      * Get comspec.
 
     /*
      * Get comspec.
@@ -38,8 +87,8 @@ Spawn *spawn;
     comspec = getenv("COMSPEC");
     if (comspec == 0) {                        /* Can't find where command.com is */
        fprintf(stderr, "Unable to find COMSPEC in the environment.");
     comspec = getenv("COMSPEC");
     if (comspec == 0) {                        /* Can't find where command.com is */
        fprintf(stderr, "Unable to find COMSPEC in the environment.");
-       spawn->done = 1;
-       spawn->rc = 99; /* XXX */
+       spint->done = 1;
+       spint->rc = 99; /* XXX */
        return;
     }
 
        return;
     }
 
@@ -47,36 +96,36 @@ Spawn *spawn;
      * Now, hook up our interrupt routine.
      */
 
      * Now, hook up our interrupt routine.
      */
 
-    spawn->regs.h.ah = 0x35;
-    spawn->regs.h.al = spawn->int_no;
-    intdosx(&spawn->regs, &spawn->regs, &spawn->sregs);
+    regs.h.ah = 0x35;
+    regs.h.al = spint->int_no;
+    intdosx(&regs, &regs, &sregs);
 
     /* Save old routine */
 
     /* Save old routine */
-    int_offset = spawn->regs.x.bx;
-    int_segment = spawn->sregs.es;
+    int_offset = regs.x.bx;
+    int_segment = sregs.es;
 
 
-    spawn->regs.h.ah = 0x25;
-    spawn->regs.h.al = spawn->int_no;
-    spawn->regs.x.dx = (int) int_spawn;
-    segread(&spawn->sregs);
-    spawn->sregs.ds = spawn->sregs.cs;
-    intdosx(&spawn->regs, &spawn->regs, &spawn->sregs);
+    regs.h.ah = 0x25;
+    regs.h.al = spint->int_no;
+    regs.x.dx = (int) _spint_int;
+    segread(&sregs);
+    sregs.ds = sregs.cs;
+    intdosx(&regs, &regs, &sregs);
 
     /*
      * Read in segment registers.
      */
 
 
     /*
      * Read in segment registers.
      */
 
-    segread(&spawn->sregs);
+    segread(&spint->sregs);
 
     /*
      * Set up registers for the EXEC call.
      */
 
 
     /*
      * Set up registers for the EXEC call.
      */
 
-    spawn->regs.h.ah = 0x4b;
-    spawn->regs.h.al = 0;
-    spawn->regs.x.dx = (int) comspec;
-    spawn->sregs.es = spawn->sregs.ds;         /* Superfluous, probably */
-    spawn->regs.x.bx = (int) &mylist;
+    spint->regs.h.ah = 0x4b;
+    spint->regs.h.al = 0;
+    spint->regs.x.dx = (int) comspec;
+    spint->sregs.es = spint->sregs.ds;         /* Superfluous, probably */
+    spint->regs.x.bx = (int) &mylist;
 
     /*
      * Set up EXEC parameter list.
 
     /*
      * Set up EXEC parameter list.
@@ -84,7 +133,7 @@ Spawn *spawn;
 
     ClearElement(mylist);
     mylist.cmd_ptr_offset = (int) command;
 
     ClearElement(mylist);
     mylist.cmd_ptr_offset = (int) command;
-    mylist.cmd_ptr_segment = spawn->sregs.ds;
+    mylist.cmd_ptr_segment = spint->sregs.ds;
     mylist.fcb1_ptr_offset = PSP_FCB1;
     mylist.fcb1_ptr_segment = _psp;
     mylist.fcb2_ptr_offset = PSP_FCB2;
     mylist.fcb1_ptr_offset = PSP_FCB1;
     mylist.fcb1_ptr_segment = _psp;
     mylist.fcb2_ptr_offset = PSP_FCB2;
@@ -93,117 +142,10 @@ Spawn *spawn;
 
     /*
      * Call to assembly language routine to actually set up for
 
     /*
      * Call to assembly language routine to actually set up for
-     * the spawn.
-     */
-
-    start_spawn(spawn);
-    spawn->done = 1;                   /* XXX */
-
-    if (spawn->done == 0) {
-       return;                         /* Not done yet */
-    }
-
-    if (spawn->regs.x.cflag) {
-       fprintf(stderr, "0x%x return code from EXEC.\n", spawn->regs.x.ax);
-       spawn->done = 1;
-       spawn->rc = 99;
-       return;
-    }
-
-    spawn->regs.h.ah = 0x4d;                   /* Get return code */
-
-    intdos(&spawn->regs, &spawn->regs);
-
-    spawn->rc = spawn->regs.x.ax;
-
-    /*
-     * Restore old interrupt handler.
+     * the spint.
      */
 
      */
 
-    spawn->regs.h.ah = 0x25;
-    spawn->regs.h.al = spawn->int_no;
-    spawn->regs.x.dx = int_offset;
-    spawn->sregs.ds = int_segment;
-    intdosx(&spawn->regs, &spawn->regs, &spawn->sregs);
-}
-\f
-/* XXX */
-
-#define        INTERRUPT_NUMBER        73
-
-main(argc, argv, envp)
-int    argc;                           /* Number of passed arguments */
-char   *argv[];                        /* Arguments passed */
-char   *envp[];                        /* Inherited environment */
-{
-    Spawn spawned;
-    static char command[256];
-
-    ClearElement(spawned);
-    spawned.int_no = INTERRUPT_NUMBER;
-    if (argc == 1) {
-       command[0] = 0;
-    } else {
-       char *cmdptr;
-       int length;
-
-       argc--;
-       argv++;
-       strcpy(command, " /c");
-       cmdptr = command+strlen(command);
-       while (argc) {
-           if ((cmdptr+strlen(*argv)) >= (command+sizeof command)) {
-               fprintf(stderr, "Argument list too long at argument *%s*.\n",
-                           *argv);
-               return 0;
-           }
-           *cmdptr++ = ' ';            /* Blank separators */
-           strcpy(cmdptr, *argv);
-           cmdptr += strlen(cmdptr);
-           argc--;
-           argv++;
-       }
-       length = strlen(command)-1;
-       if (length < 0) {
-           length = 0;
-       }
-       command[0] = length;
-    }
+    _spint_start(spint);
 
 
-    /*
-     * do_spawn() returns when either the command has finished, or when
-     * the required interrupt comes in.  In the latter case, the appropriate
-     * thing to do is to process the interrupt, and then return to
-     * the interrupt issuer by calling continue_spawn().
-     */
-    do_spawn(command, &spawned);
-    while (spawned.done == 0) {
-       /* Process request */
-       spawned.regs.h.al = 0;
-       spawned.regs.x.cflag = 0;               /* No errors (yet) */
-       switch (spawned.regs.h.ah) {
-       case 1:                 /* Add */
-           spawned.regs.x.bx += spawned.regs.x.cx;
-           break;
-       case 2:                 /* Subtract */
-           spawned.regs.x.bx -= spawned.regs.x.cx;
-           break;
-       case 3:                 /* Multiply */
-           spawned.regs.x.bx *= spawned.regs.x.cx;
-           break;
-       case 4:                 /* Divide */
-           spawned.regs.x.bx /= spawned.regs.x.cx;
-           break;
-       default:
-           spawned.regs.h.al = -1;     /* Error */
-           spawned.regs.x.cflag = 1;
-           break;
-       }
-       spawned.regs.h.ah = 0;                  /* We saw this */
-       continue_spawn(&spawned);
-    }
-    if (spawned.rc != 0) {
-       fprintf(stderr, "Process generated a return code of 0x%x.\n",
-                                                               spawned.rc);
-    }
+    spint_finish(spint);
 }
 }
index 0a78eed..8254fbb 100644 (file)
@@ -188,7 +188,8 @@ int
     segread(&segregs);         /* read the current segment register */
 
     scrwait();
     segread(&segregs);         /* read the current segment register */
 
     scrwait();
-    movedata(segregs.ds, source, scrseg(), offset, length);
+    movedata(segregs.ds, source, scrseg(), sizeof *source*offset,
+                                               sizeof *source*length);
 }
 
 static void
 }
 
 static void
@@ -200,36 +201,39 @@ ScreenBuffer *buffer;
     segread(&segregs);         /* read the current segment register */
 
     scrwait();
     segread(&segregs);         /* read the current segment register */
 
     scrwait();
-    movedata(scrseg(), 0, segregs.ds, buffer, scrseg(), 0, crt_cols*crt_lins*2);
+    movedata(scrseg(), 0, segregs.ds, buffer, crt_cols*crt_lins*2);
 }
 
 static void
 scrrest(buffer)
 ScreenBuffer *buffer;
 {
 }
 
 static void
 scrrest(buffer)
 ScreenBuffer *buffer;
 {
-    scrwrite(buffer, 2*crt_cols*crt_lins, 0);
+    scrwrite(buffer, crt_cols*crt_lins, 0);
 }
 \f
 static void
 TryToSend()
 {
 }
 \f
 static void
 TryToSend()
 {
-#define        STANDOUT        0x0a
+#define        STANDOUT        0x0a    /* Highlighted mode */
 #define        NORMAL          0x02    /* Normal mode */
 #define        NORMAL          0x02    /* Normal mode */
-
-#define        DoAttribute(a)      if (IsHighlightedAttr(a)) { \
-                               a = STANDOUT; \
-                           } else { \
-                               a = NORMAL; \
-                           } \
-                           if (IsNonDisplayAttr(a)) { \
-                               a = 0;  /* zero == don't display */ \
-                           } \
-                           if (!FormattedScreen()) { \
-                               a = 1;  /* one ==> do display on unformatted */\
+#define        NONDISPLAY      0x00    /* Don't display */
+
+#define        DoAttribute(a)      \
+                           if (screenIsFormatted) { \
+                               if (IsNonDisplayAttr(a)) { \
+                                   a = NONDISPLAY;     /* don't display */ \
+                               } else if (IsHighlightedAttr(a)) { \
+                                   a = STANDOUT; \
+                               } else { \
+                                   a = NORMAL; \
+                               } \
+                           } else  { \
+                               a = NORMAL;     /* do display on unformatted */\
                            }
     ScreenImage *p, *upper;
     ScreenBuffer *sp;
     int fieldattr;             /* spends most of its time == 0 or 1 */
                            }
     ScreenImage *p, *upper;
     ScreenBuffer *sp;
     int fieldattr;             /* spends most of its time == 0 or 1 */
+    int screenIsFormatted = FormattedScreen();
 
 /* OK.  We want to do this a quickly as possible.  So, we assume we
  * only need to go from Lowest to Highest.  However, if we find a
 
 /* OK.  We want to do this a quickly as possible.  So, we assume we
  * only need to go from Lowest to Highest.  However, if we find a
@@ -238,14 +242,11 @@ TryToSend()
  * In particular, we separate out the two cases from the beginning.
  */
     if ((Highest != HighestScreen()) || (Lowest != LowestScreen())) {
  * In particular, we separate out the two cases from the beginning.
  */
     if ((Highest != HighestScreen()) || (Lowest != LowestScreen())) {
-       register int columnsleft;
-
        sp = &Screen[Lowest];
        p = &Host[Lowest];
        upper = &Host[Highest];
        fieldattr = FieldAttributes(Lowest);
        DoAttribute(fieldattr); /* Set standout, non-display status */
        sp = &Screen[Lowest];
        p = &Host[Lowest];
        upper = &Host[Highest];
        fieldattr = FieldAttributes(Lowest);
        DoAttribute(fieldattr); /* Set standout, non-display status */
-       columnsleft = NumberColumns-ScreenLineOffset(p-Host);
 
        while (p <= upper) {
            if (IsStartFieldPointer(p)) {       /* New field? */
 
        while (p <= upper) {
            if (IsStartFieldPointer(p)) {       /* New field? */
@@ -254,17 +255,12 @@ TryToSend()
                TryToSend();            /* Recurse */
                return;
            } else if (fieldattr) {     /* Should we display? */
                TryToSend();            /* Recurse */
                return;
            } else if (fieldattr) {     /* Should we display? */
-               sp->data = disp_asc[p->data];   /* Display translated data */
-               sp->attr = fieldattr;
+                               /* Display translated data */
+               sp->data = disp_asc[GetHostPointer(p)];
            } else {
                sp->data = ' ';
            } else {
                sp->data = ' ';
-               sp->attr = NORMAL;
            }
            }
-                       /* If the physical screen is larger than what we
-                        * are using, we need to make sure that each line
-                        * starts at the beginning of the line.  Otherwise,
-                        * we will just string all the lines together.
-                        */
+           sp->attr = fieldattr;
            p++;
            sp++;
        }
            p++;
            sp++;
        }
@@ -280,27 +276,25 @@ TryToSend()
            if (IsStartFieldPointer(p)) {       /* New field? */
                fieldattr = FieldAttributesPointer(p);  /* Get attributes */
                DoAttribute(fieldattr); /* Set standout, non-display */
            if (IsStartFieldPointer(p)) {       /* New field? */
                fieldattr = FieldAttributesPointer(p);  /* Get attributes */
                DoAttribute(fieldattr); /* Set standout, non-display */
+           }
+           if (fieldattr) {    /* Should we display? */
+                           /* Display translated data */
+               sp->data = disp_asc[GetHostPointer(p)];
            } else {
            } else {
-               if (fieldattr) {        /* Should we display? */
-                               /* Display translated data */
-                   sp->data = disp_asc[p->data];
-                   sp->attr = fieldattr;
-               } else {
-                   sp->data = ' ';
-                   sp->attr = NORMAL;
-               }
+               sp->data = ' ';
            }
            }
-                       /* If the physical screen is larger than what we
-                        * are using, we need to make sure that each line
-                        * starts at the beginning of the line.  Otherwise,
-                        * we will just string all the lines together.
-                        */
+           sp->attr = fieldattr;
            p++;
            sp++;
        }
     }
     terminalCursorAddress = CorrectTerminalCursor();
            p++;
            sp++;
        }
     }
     terminalCursorAddress = CorrectTerminalCursor();
-    scrwrite(Screen+Lowest, sizeof Screen[0]*(Highest-Lowest), Lowest);
+    /*
+     * We might be here just to update the cursor address.
+     */
+    if (Highest >= Lowest) {
+       scrwrite(Screen+Lowest, (1+Highest-Lowest), Lowest);
+    }
     setcursor(ScreenLine(terminalCursorAddress),
                    ScreenLineOffset(terminalCursorAddress), 0);
     Lowest = HighestScreen()+1;
     setcursor(ScreenLine(terminalCursorAddress),
                    ScreenLineOffset(terminalCursorAddress), 0);
     Lowest = HighestScreen()+1;