Improved line character input; exExtraBytes fix.

git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@416 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2002-08-05 19:56:38 +00:00
parent 2c6dbdf194
commit 31591f162c
8 changed files with 183 additions and 136 deletions

View File

@ -35,7 +35,9 @@ static BYTE *kbd_hRcsId =
#endif #endif
#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 */ /* Keyboard buffer */
typedef struct { typedef struct {

View File

@ -35,13 +35,11 @@ static BYTE *tail_hRcsId =
#endif #endif
#endif #endif
#ifndef LINESIZE #define CTBUFFERSIZE 127
#define LINESIZE 127
#endif
typedef struct { typedef struct {
UBYTE ctCount; /* number of bytes returned */ UBYTE ctCount; /* number of bytes returned */
BYTE ctBuffer[LINESIZE]; /* the buffer itself */ char ctBuffer[CTBUFFERSIZE]; /* the buffer itself */
} CommandTail; } CommandTail;
/* /*

View File

@ -37,14 +37,6 @@ static BYTE *charioRcsId =
#include "globals.h" #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 /* Return a pointer to the first driver in the chain that
* matches the attributes. * matches the attributes.
* not necessary because we have the syscon pointer. * not necessary because we have the syscon pointer.
@ -155,7 +147,7 @@ VOID sto(COUNT c)
DosWrite(STDOUT, 1, (BYTE FAR *) & c, & UnusedRetVal); DosWrite(STDOUT, 1, (BYTE FAR *) & c, & UnusedRetVal);
} }
VOID mod_cso(REG UCOUNT c) unsigned mod_cso(register unsigned c)
{ {
if (c < ' ' && c != HT) if (c < ' ' && c != HT)
{ {
@ -164,6 +156,7 @@ VOID mod_cso(REG UCOUNT c)
} }
else else
cso(c); cso(c);
return c;
} }
VOID destr_bs(void) VOID destr_bs(void)
@ -285,47 +278,25 @@ VOID KbdFlush(void)
execrh((request FAR *) & CharReqHdr, syscon); execrh((request FAR *) & CharReqHdr, syscon);
} }
STATIC VOID kbfill(keyboard FAR * kp, UCOUNT c, BOOL ctlf, UWORD * vp) /* reads a line */
{ void sti_0a(keyboard FAR * kp)
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)
{ {
REG UWORD c, cu_pos = scr_pos; REG UWORD c, cu_pos = scr_pos;
UWORD virt_pos = scr_pos; unsigned count = 0, stored_pos = 0, size = kp->kb_size, stored_size = kp->kb_count;
UWORD init_count = 0; /* kp->kb_count; */ BOOL insert = FALSE;
BOOL eof = FALSE;
#ifndef NOSPCL
static BYTE local_buffer[LINESIZE];
#endif
if (kp->kb_size == 0) if (size == 0)
return eof; return;
/* if (kp->kb_size <= kp->kb_count || kp->kb_buf[kp->kb_count] != CR) */
kp->kb_count = 0; /* the stored line is invalid unless it ends with a CR */
FOREVER if (kp->kb_buf[stored_size] != CR)
{ {
switch (c = _sti(TRUE)) stored_size = 0;
}
while ((c = _sti(TRUE)) != CR)
{
switch (c)
{ {
case CTL_C: case CTL_C:
handle_break(); handle_break();
@ -339,23 +310,53 @@ UCOUNT sti_0a(keyboard FAR * kp)
case LEFT: case LEFT:
goto backspace; 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: case RIGHT:
c = local_buffer[kp->kb_count]; case F1:
if (c) if (stored_pos < stored_size && count < size - 1)
kbfill(kp, c, FALSE, &virt_pos); 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;
} }
break; break;
@ -364,79 +365,109 @@ UCOUNT sti_0a(keyboard FAR * kp)
case CTL_BS: case CTL_BS:
case BS: case BS:
backspace: 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(); unsigned i;
--virt_pos; new_pos = cu_pos;
} for (i = 0; i < count; i++)
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
{ {
destr_bs(); if (local_buffer[i] == HT)
--virt_pos; 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; 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: case LF:
cso(CR);
cso(LF);
break; break;
case ESC: case ESC:
cso('\\'); cso('\\');
start_new_line:
cso(CR); cso(CR);
cso(LF); cso(LF);
for (c = 0; c < cu_pos; c++) for (c = 0; c < cu_pos; c++)
cso(' '); cso(' ');
kp->kb_count = init_count; count = 0;
eof = FALSE; stored_pos = 0;
insert = FALSE;
break; break;
case CTL_Z:
eof = kp->kb_count;
/* fall through */ /* fall through */
default: 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; 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); char *bufend = &kb_buf.kb_buf[kb_buf.kb_count + 2];
kp->kb_count++;
if (inputptr == NULL)
if (ReadCount >= kp->kb_count && kp->kb_count < kp->kb_size)
{ {
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); 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;
} }
/* /*

View File

@ -207,11 +207,12 @@ UCOUNT DosRWSft(sft FAR * s, UCOUNT n, void FAR * bp, COUNT * err, int mode)
{ {
if (mode==XFR_READ) if (mode==XFR_READ)
{ {
char c;
/* First test for eof and exit */ /* First test for eof and exit */
/* immediately if it is */ /* immediately if it is */
if (!(s->sft_flags & SFT_FEOF) || (s->sft_flags & SFT_FNUL)) if (!(s->sft_flags & SFT_FEOF) || (s->sft_flags & SFT_FNUL))
{ {
s->sft_flags &= ~SFT_FEOF;
return 0; 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); return BinaryCharIO(s->sft_dev, n, bp, C_INPUT, err);
if (s->sft_flags & SFT_FCONIN) if (s->sft_flags & SFT_FCONIN)
{ {
UCOUNT ReadCount; n = sti(n, bp);
if (n == 0)
kb_buf.kb_size = LINESIZE - 1; c = CTL_Z;
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;
} }
*(char FAR *)bp = _sti(FALSE); else
return 1; {
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 else
{ {
/* set to no EOF */ /* reset EOF state (set to no EOF) */
s->sft_flags |= SFT_FEOF; s->sft_flags |= SFT_FEOF;
/* if null just report full transfer */ /* if null just report full transfer */
@ -329,7 +337,6 @@ UCOUNT BinaryReadSft(sft FAR * s, void *bp, COUNT *err)
/* immediately if it is */ /* immediately if it is */
if (!(s->sft_flags & SFT_FEOF) || (s->sft_flags & SFT_FNUL)) if (!(s->sft_flags & SFT_FEOF) || (s->sft_flags & SFT_FNUL))
{ {
s->sft_flags &= ~SFT_FEOF;
return 0; return 0;
} }
return BinaryCharIO(s->sft_dev, 1, bp, C_INPUT, err); return BinaryCharIO(s->sft_dev, 1, bp, C_INPUT, err);

View File

@ -131,8 +131,15 @@ FAR * ASM DPBp; /* First drive Parameter Block */
#define ESC 0x1b #define ESC 0x1b
#define CTL_BS 0x7f #define CTL_BS 0x7f
#define INS 0x52
#define DEL 0x53
#define F1 0x3b #define F1 0x3b
#define F2 0x3c
#define F3 0x3d #define F3 0x3d
#define F4 0x3e
#define F5 0x3f
#define F6 0x40
#define LEFT 0x4b #define LEFT 0x4b
#define RIGHT 0x4d #define RIGHT 0x4d
@ -157,12 +164,6 @@ FAR * ASM DPBp; /* First drive Parameter Block */
#define MASK12 0xFF8 #define MASK12 0xFF8
#define BAD12 0xFF0 #define BAD12 0xFF0
/* Keyboard buffer maximum size */
#ifdef LINESIZE
#undef LINESIZE
#endif
#define LINESIZE KBD_MAXLENGTH
/* NLS character table type */ /* NLS character table type */
typedef BYTE *UPMAP; typedef BYTE *UPMAP;
@ -260,6 +261,7 @@ extern BYTE ASM NetDelay, ASM NetRetry;
extern UWORD ASM first_mcb, /* Start of user memory */ extern UWORD ASM first_mcb, /* Start of user memory */
ASM uppermem_root; /* Start of umb chain (usually 9fff) */ 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 sfttbl FAR * ASM sfthead; /* System File Table head */
extern struct dhdr extern struct dhdr
FAR * ASM clock, /* CLOCK$ device */ FAR * ASM clock, /* CLOCK$ device */
@ -351,6 +353,7 @@ extern BYTE ASM BootDrive, /* Drive we came up from */
NumFloppies; !!*//* How many floppies we have */ NumFloppies; !!*//* How many floppies we have */
extern keyboard ASM kb_buf; extern keyboard ASM kb_buf;
extern char ASM local_buffer[LINEBUFSIZE0A];
extern struct cds extern struct cds
ASM TempCDS; ASM TempCDS;

View File

@ -268,7 +268,8 @@ _NetRetry dw 3 ;-000c network retry count
_NetDelay dw 1 ;-000a network delay count _NetDelay dw 1 ;-000a network delay count
global _DskBuffer global _DskBuffer
_DskBuffer dd -1 ;-0008 current dos disk buffer _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 global _first_mcb
_first_mcb dw 0 ;-0002 Start of user memory _first_mcb dw 0 ;-0002 Start of user memory
global _DPBp global _DPBp
@ -362,9 +363,12 @@ _firstsftt:
global MARK01FBH global MARK01FBH
MARK01FBH equ $ 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 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 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 ; Variables that follow are documented as part of the DOS 4.0-6.X swappable

View File

@ -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); UCOUNT BinaryCharIO(struct dhdr FAR * dev, UCOUNT n, void FAR * bp, unsigned command, COUNT *err);
VOID sto(COUNT c); VOID sto(COUNT c);
VOID cso(COUNT c); VOID cso(COUNT c);
VOID mod_cso(REG UCOUNT c); unsigned mod_cso(unsigned c);
VOID destr_bs(void); VOID destr_bs(void);
UCOUNT _sti(BOOL check_break); UCOUNT _sti(BOOL check_break);
VOID con_hold(void); VOID con_hold(void);
@ -61,8 +61,8 @@ BOOL con_break(void);
BOOL StdinBusy(void); BOOL StdinBusy(void);
VOID KbdFlush(void); VOID KbdFlush(void);
VOID Do_DosIdle_loop(void); VOID Do_DosIdle_loop(void);
UCOUNT sti_0a(keyboard FAR * kp); void sti_0a(keyboard FAR * kp);
UCOUNT sti(keyboard * kp); unsigned sti(unsigned n, char FAR * bp);
sft FAR *get_sft(UCOUNT); sft FAR *get_sft(UCOUNT);

View File

@ -153,6 +153,8 @@ int main(int argc, char **argv)
return 1; return 1;
} }
start_seg = strtol(argv[3], NULL, 0); start_seg = strtol(argv[3], NULL, 0);
if (header.exExtraBytes == 0)
header.exExtraBytes = 0x200;
printf("header len = %lu = 0x%lx\n", header.exHeaderSize * 16UL, printf("header len = %lu = 0x%lx\n", header.exHeaderSize * 16UL,
header.exHeaderSize * 16UL); header.exHeaderSize * 16UL);
size = size =
@ -278,7 +280,7 @@ int main(int argc, char **argv)
if (UPX) if (UPX)
{ {
/* UPX trailer */ /* 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 */ static char trailer[] = { /* shift down everything by sizeof JumpBehindCode */
0xE8, 0x00, 0x00, /* call 103 */ 0xE8, 0x00, 0x00, /* call 103 */
0x59, /* pop cx */ 0x59, /* pop cx */