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
#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 {

View File

@ -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;
/*

View File

@ -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++;
char *bufend = &kb_buf.kb_buf[kb_buf.kb_count + 2];
if (ReadCount >= kp->kb_count && kp->kb_count < kp->kb_size)
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;
}
/*

View File

@ -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);

View File

@ -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;

View File

@ -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

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);
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);

View File

@ -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 */