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:
parent
2c6dbdf194
commit
31591f162c
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
241
kernel/chario.c
241
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user