diff --git a/hdr/kbd.h b/hdr/kbd.h index 4894665..faa4914 100644 --- a/hdr/kbd.h +++ b/hdr/kbd.h @@ -35,7 +35,9 @@ static BYTE *kbd_hRcsId = #endif #endif -#define KBD_MAXLENGTH 256 +#define LINEBUFSIZECON 128 +#define KBD_MAXLENGTH LINEBUFSIZECON+1 /* the above + LF */ +#define LINEBUFSIZE0A 256 /* maximum length for int21/ah=0a */ /* Keyboard buffer */ typedef struct { diff --git a/hdr/tail.h b/hdr/tail.h index 2b36d28..e093ccc 100644 --- a/hdr/tail.h +++ b/hdr/tail.h @@ -35,13 +35,11 @@ static BYTE *tail_hRcsId = #endif #endif -#ifndef LINESIZE -#define LINESIZE 127 -#endif +#define CTBUFFERSIZE 127 typedef struct { UBYTE ctCount; /* number of bytes returned */ - BYTE ctBuffer[LINESIZE]; /* the buffer itself */ + char ctBuffer[CTBUFFERSIZE]; /* the buffer itself */ } CommandTail; /* diff --git a/kernel/chario.c b/kernel/chario.c index 3f3f53c..004d227 100644 --- a/kernel/chario.c +++ b/kernel/chario.c @@ -37,14 +37,6 @@ static BYTE *charioRcsId = #include "globals.h" -#ifdef PROTO -STATIC VOID kbfill(keyboard FAR *, UCOUNT, BOOL, UWORD *); -struct dhdr FAR *finddev(UWORD attr_mask); -#else -STATIC VOID kbfill(); -struct dhdr FAR *finddev(); -#endif - /* Return a pointer to the first driver in the chain that * matches the attributes. * not necessary because we have the syscon pointer. @@ -155,7 +147,7 @@ VOID sto(COUNT c) DosWrite(STDOUT, 1, (BYTE FAR *) & c, & UnusedRetVal); } -VOID mod_cso(REG UCOUNT c) +unsigned mod_cso(register unsigned c) { if (c < ' ' && c != HT) { @@ -164,6 +156,7 @@ VOID mod_cso(REG UCOUNT c) } else cso(c); + return c; } VOID destr_bs(void) @@ -285,47 +278,25 @@ VOID KbdFlush(void) execrh((request FAR *) & CharReqHdr, syscon); } -STATIC VOID kbfill(keyboard FAR * kp, UCOUNT c, BOOL ctlf, UWORD * vp) -{ - if (kp->kb_count >= kp->kb_size) - { - cso(BELL); - return; - } - kp->kb_buf[kp->kb_count++] = c; - if (!ctlf) - { - mod_cso(c); - *vp += 2; - } - else - { - cso(c); - if (c != HT) - ++ * vp; - else - *vp = (*vp + 8) & -8; - } -} - -/* return number of characters before EOF if there is one, else just the total */ -UCOUNT sti_0a(keyboard FAR * kp) +/* reads a line */ +void sti_0a(keyboard FAR * kp) { REG UWORD c, cu_pos = scr_pos; - UWORD virt_pos = scr_pos; - UWORD init_count = 0; /* kp->kb_count; */ - BOOL eof = FALSE; -#ifndef NOSPCL - static BYTE local_buffer[LINESIZE]; -#endif + unsigned count = 0, stored_pos = 0, size = kp->kb_size, stored_size = kp->kb_count; + BOOL insert = FALSE; - if (kp->kb_size == 0) - return eof; - /* if (kp->kb_size <= kp->kb_count || kp->kb_buf[kp->kb_count] != CR) */ - kp->kb_count = 0; - FOREVER + if (size == 0) + return; + + /* the stored line is invalid unless it ends with a CR */ + if (kp->kb_buf[stored_size] != CR) { - switch (c = _sti(TRUE)) + stored_size = 0; + } + + while ((c = _sti(TRUE)) != CR) + { + switch (c) { case CTL_C: handle_break(); @@ -339,23 +310,53 @@ UCOUNT sti_0a(keyboard FAR * kp) case LEFT: goto backspace; - case F3: - { - REG COUNT i; - - for (i = kp->kb_count; local_buffer[i] != '\0'; i++) - { - c = local_buffer[kp->kb_count]; - kbfill(kp, c, FALSE, &virt_pos); - } - break; - } - - case F1: case RIGHT: - c = local_buffer[kp->kb_count]; - if (c) - kbfill(kp, c, FALSE, &virt_pos); + case F1: + if (stored_pos < stored_size && count < size - 1) + local_buffer[count++] = mod_cso(kp->kb_buf[stored_pos++]); + break; + + case F2: + c = _sti(TRUE); + /* insert up to character c */ + insert_to_c: + while (stored_pos < stored_size && count < size - 1) + { + char c2 = kp->kb_buf[stored_pos]; + if (c2 == c) + break; + stored_pos++; + local_buffer[count++] = mod_cso(c2); + } + break; + + case F3: + c = (unsigned)-1; + goto insert_to_c; + + case F4: + c = _sti(TRUE); + /* delete up to character c */ + while (stored_pos < stored_size && c != kp->kb_buf[stored_pos]) + stored_pos++; + break; + + case F5: + fmemcpy(kp->kb_buf, local_buffer, count); + stored_size = count; + cso('@'); + goto start_new_line; + + case F6: + c = CTL_Z; + goto default_case; + + case INS: + insert = !insert; + break; + + case DEL: + stored_pos++; break; } break; @@ -364,79 +365,109 @@ UCOUNT sti_0a(keyboard FAR * kp) case CTL_BS: case BS: backspace: - if (kp->kb_count > 0) + if (count > 0) { - if (kp->kb_buf[kp->kb_count - 1] >= ' ') + unsigned new_pos; + c = local_buffer[--count]; + if (c == HT) { - destr_bs(); - --virt_pos; - } - else if ((kp->kb_buf[kp->kb_count - 1] < ' ') - && (kp->kb_buf[kp->kb_count - 1] != HT)) - { - destr_bs(); - destr_bs(); - virt_pos -= 2; - } - else if (kp->kb_buf[kp->kb_count - 1] == HT) - { - do + unsigned i; + new_pos = cu_pos; + for (i = 0; i < count; i++) { - destr_bs(); - --virt_pos; + if (local_buffer[i] == HT) + new_pos = (new_pos + 8) & ~7; + else if (local_buffer[i] < ' ') + new_pos += 2; + else + new_pos++; } - while ((virt_pos > cu_pos) && (virt_pos & 7)); + do + destr_bs(); + while (scr_pos > new_pos); + } + else + { + if (c < ' ') + destr_bs(); + destr_bs(); } - --kp->kb_count; } + if (stored_pos > 0 && !insert) + stored_pos--; break; - case CR: -#ifndef NOSPCL - fmemcpy(local_buffer, kp->kb_buf, (COUNT) kp->kb_count); - local_buffer[kp->kb_count] = '\0'; -#endif - kbfill(kp, CR, TRUE, &virt_pos); - if (eof) - return eof; - else - return kp->kb_count--; - case LF: + cso(CR); + cso(LF); break; case ESC: cso('\\'); + start_new_line: cso(CR); cso(LF); for (c = 0; c < cu_pos; c++) cso(' '); - kp->kb_count = init_count; - eof = FALSE; + count = 0; + stored_pos = 0; + insert = FALSE; break; - case CTL_Z: - eof = kp->kb_count; /* fall through */ default: - kbfill(kp, c, FALSE, &virt_pos); + default_case: + if (count < size - 1) + local_buffer[count++] = mod_cso(c); + else + cso(BELL); + if (stored_pos < stored_size && !insert) + stored_pos++; break; } } + local_buffer[count] = CR; + cso(CR); + fmemcpy(kp->kb_buf, local_buffer, count + 1); + /* if local_buffer overflows into the CON default buffer we + must invalidate it */ + if (count > LINEBUFSIZECON) + kb_buf.kb_size = 0; + kp->kb_count = count; } -UCOUNT sti(keyboard * kp) +unsigned sti(unsigned n, char FAR * bp) { - UCOUNT ReadCount = sti_0a(kp); - kp->kb_count++; - - if (ReadCount >= kp->kb_count && kp->kb_count < kp->kb_size) + char *bufend = &kb_buf.kb_buf[kb_buf.kb_count + 2]; + + if (inputptr == NULL) { - kp->kb_buf[kp->kb_count++] = LF; + /* can we reuse kb_buf or was it overwritten? */ + if (kb_buf.kb_size != LINEBUFSIZECON) + { + kb_buf.kb_count = 0; + kb_buf.kb_size = LINEBUFSIZECON; + } + sti_0a(&kb_buf); + bufend = &kb_buf.kb_buf[kb_buf.kb_count + 2]; + bufend[-1] = LF; cso(LF); - ReadCount++; + inputptr = kb_buf.kb_buf; + if (*inputptr == CTL_Z) + { + inputptr = NULL; + return 0; + } } - return ReadCount; + + if (inputptr > bufend - n) + n = bufend - inputptr; + + fmemcpy(bp, inputptr, n); + inputptr += n; + if (inputptr == bufend) + inputptr = NULL; + return n; } /* diff --git a/kernel/dosfns.c b/kernel/dosfns.c index c2d3803..0de7c08 100644 --- a/kernel/dosfns.c +++ b/kernel/dosfns.c @@ -207,11 +207,12 @@ UCOUNT DosRWSft(sft FAR * s, UCOUNT n, void FAR * bp, COUNT * err, int mode) { if (mode==XFR_READ) { + char c; + /* First test for eof and exit */ /* immediately if it is */ if (!(s->sft_flags & SFT_FEOF) || (s->sft_flags & SFT_FNUL)) { - s->sft_flags &= ~SFT_FEOF; return 0; } @@ -220,21 +221,28 @@ UCOUNT DosRWSft(sft FAR * s, UCOUNT n, void FAR * bp, COUNT * err, int mode) return BinaryCharIO(s->sft_dev, n, bp, C_INPUT, err); if (s->sft_flags & SFT_FCONIN) { - UCOUNT ReadCount; - - kb_buf.kb_size = LINESIZE - 1; - ReadCount = sti(&kb_buf); - if (ReadCount < kb_buf.kb_count) - s->sft_flags &= ~SFT_FEOF; - fmemcpy(bp, kb_buf.kb_buf, kb_buf.kb_count); - return ReadCount; + n = sti(n, bp); + if (n == 0) + c = CTL_Z; } - *(char FAR *)bp = _sti(FALSE); - return 1; + else + { + n = 1; + Do_DosIdle_loop(); + BinaryReadSft(s, &c, err); + if (c != CTL_Z) + *(char FAR *)bp = c; + } + if (c == CTL_Z) + { + n = 0; + s->sft_flags &= ~SFT_FEOF; + } + return n; } else { - /* set to no EOF */ + /* reset EOF state (set to no EOF) */ s->sft_flags |= SFT_FEOF; /* if null just report full transfer */ @@ -329,7 +337,6 @@ UCOUNT BinaryReadSft(sft FAR * s, void *bp, COUNT *err) /* immediately if it is */ if (!(s->sft_flags & SFT_FEOF) || (s->sft_flags & SFT_FNUL)) { - s->sft_flags &= ~SFT_FEOF; return 0; } return BinaryCharIO(s->sft_dev, 1, bp, C_INPUT, err); diff --git a/kernel/globals.h b/kernel/globals.h index 392d51d..9d4289c 100644 --- a/kernel/globals.h +++ b/kernel/globals.h @@ -131,8 +131,15 @@ FAR * ASM DPBp; /* First drive Parameter Block */ #define ESC 0x1b #define CTL_BS 0x7f +#define INS 0x52 +#define DEL 0x53 + #define F1 0x3b +#define F2 0x3c #define F3 0x3d +#define F4 0x3e +#define F5 0x3f +#define F6 0x40 #define LEFT 0x4b #define RIGHT 0x4d @@ -157,12 +164,6 @@ FAR * ASM DPBp; /* First drive Parameter Block */ #define MASK12 0xFF8 #define BAD12 0xFF0 -/* Keyboard buffer maximum size */ -#ifdef LINESIZE -#undef LINESIZE -#endif -#define LINESIZE KBD_MAXLENGTH - /* NLS character table type */ typedef BYTE *UPMAP; @@ -260,6 +261,7 @@ extern BYTE ASM NetDelay, ASM NetRetry; extern UWORD ASM first_mcb, /* Start of user memory */ ASM uppermem_root; /* Start of umb chain (usually 9fff) */ +extern char * ASM inputptr; /* pointer to unread CON input */ extern sfttbl FAR * ASM sfthead; /* System File Table head */ extern struct dhdr FAR * ASM clock, /* CLOCK$ device */ @@ -351,6 +353,7 @@ extern BYTE ASM BootDrive, /* Drive we came up from */ NumFloppies; !!*//* How many floppies we have */ extern keyboard ASM kb_buf; +extern char ASM local_buffer[LINEBUFSIZE0A]; extern struct cds ASM TempCDS; diff --git a/kernel/kernel.asm b/kernel/kernel.asm index 030937e..810bdde 100644 --- a/kernel/kernel.asm +++ b/kernel/kernel.asm @@ -268,7 +268,8 @@ _NetRetry dw 3 ;-000c network retry count _NetDelay dw 1 ;-000a network delay count global _DskBuffer _DskBuffer dd -1 ;-0008 current dos disk buffer - dw 0 ;-0004 Unread con input + global _inputptr +_inputptr dw 0 ;-0004 Unread con input global _first_mcb _first_mcb dw 0 ;-0002 Start of user memory global _DPBp @@ -362,9 +363,12 @@ _firstsftt: global MARK01FBH MARK01FBH equ $ - times 128 db 0 + global _local_buffer ; local_buffer is 256 bytes long + ; so it overflows into kb_buf!! + ; only when kb_buf is used, local_buffer is limited to 128 bytes. +_local_buffer: times 128 db 0 global _kb_buf -_kb_buf db 129,0 ; initialise buffer to empty +_kb_buf db 128,0 ; initialise buffer to empty times 128+1 db 0 ; room for 128 byte readline + LF ; ; Variables that follow are documented as part of the DOS 4.0-6.X swappable diff --git a/kernel/proto.h b/kernel/proto.h index 512f59b..3021b44 100644 --- a/kernel/proto.h +++ b/kernel/proto.h @@ -53,7 +53,7 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks, UCOUNT BinaryCharIO(struct dhdr FAR * dev, UCOUNT n, void FAR * bp, unsigned command, COUNT *err); VOID sto(COUNT c); VOID cso(COUNT c); -VOID mod_cso(REG UCOUNT c); +unsigned mod_cso(unsigned c); VOID destr_bs(void); UCOUNT _sti(BOOL check_break); VOID con_hold(void); @@ -61,8 +61,8 @@ BOOL con_break(void); BOOL StdinBusy(void); VOID KbdFlush(void); VOID Do_DosIdle_loop(void); -UCOUNT sti_0a(keyboard FAR * kp); -UCOUNT sti(keyboard * kp); +void sti_0a(keyboard FAR * kp); +unsigned sti(unsigned n, char FAR * bp); sft FAR *get_sft(UCOUNT); diff --git a/utils/exeflat.c b/utils/exeflat.c index f6ae449..d2c8503 100644 --- a/utils/exeflat.c +++ b/utils/exeflat.c @@ -153,6 +153,8 @@ int main(int argc, char **argv) return 1; } start_seg = strtol(argv[3], NULL, 0); + if (header.exExtraBytes == 0) + header.exExtraBytes = 0x200; printf("header len = %lu = 0x%lx\n", header.exHeaderSize * 16UL, header.exHeaderSize * 16UL); size = @@ -278,7 +280,7 @@ int main(int argc, char **argv) if (UPX) { /* UPX trailer */ - /* hand assembled - so this reamins ANSI C ;-) */ + /* hand assembled - so this remains ANSI C ;-) */ static char trailer[] = { /* shift down everything by sizeof JumpBehindCode */ 0xE8, 0x00, 0x00, /* call 103 */ 0x59, /* pop cx */