(with a little help from Arkady)
inthndler.c, chario.c, break.c simplifications and cleanups. Pass a near pointer to the far pointer that points to the device instead of an SFT index (in general). Make cooked_write much faster by only testing for input every 32 characters. No longer test for ctl_s on syscon if writing to the printer: just read from the printer which will return zero characters. Fix reading/writing zero characters by returning "256" (special code). Adjust interfaces in other files. git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@683 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
parent
8c22873b3e
commit
b0e54ff704
@ -47,9 +47,14 @@ static BYTE *RcsId =
|
|||||||
* 1) flag at 40:71 bit 7
|
* 1) flag at 40:71 bit 7
|
||||||
* 2) STDIN stream via con_break()
|
* 2) STDIN stream via con_break()
|
||||||
*/
|
*/
|
||||||
int control_break(void)
|
int check_handle_break(void)
|
||||||
{
|
{
|
||||||
return (CB_FLG & CB_MSK) || con_break();
|
if (CB_FLG & CB_MSK) {
|
||||||
|
CB_FLG &= ~CB_MSK; /* reset the ^Break flag */
|
||||||
|
handle_break(&syscon);
|
||||||
|
}
|
||||||
|
/* con_break will call handle_break() for CTL_C */
|
||||||
|
return con_break();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -61,13 +66,10 @@ int control_break(void)
|
|||||||
* 3) decrease the InDOS flag as the kernel drops back to user space
|
* 3) decrease the InDOS flag as the kernel drops back to user space
|
||||||
* 4) invoke INT-23 and never come back
|
* 4) invoke INT-23 and never come back
|
||||||
*/
|
*/
|
||||||
void handle_break(int sft_idx)
|
void handle_break(struct dhdr FAR **pdev)
|
||||||
{
|
{
|
||||||
if (CB_FLG & CB_MSK) /* Ctrl-Break pressed */
|
|
||||||
CB_FLG &= ~CB_MSK; /* reset the ^Break flag */
|
|
||||||
else /* Ctrl-C pressed */
|
|
||||||
echo_char_stdin(CTL_C);
|
echo_char_stdin(CTL_C);
|
||||||
KbdFlush(sft_idx); /* Er, this is con_flush() */
|
con_flush(pdev);
|
||||||
if (!ErrorMode) /* within int21_handler, InDOS is not incremented */
|
if (!ErrorMode) /* within int21_handler, InDOS is not incremented */
|
||||||
if (InDOS)
|
if (InDOS)
|
||||||
--InDOS; /* fail-safe */
|
--InDOS; /* fail-safe */
|
||||||
|
303
kernel/chario.c
303
kernel/chario.c
@ -37,15 +37,17 @@ static BYTE *charioRcsId =
|
|||||||
|
|
||||||
#include "globals.h"
|
#include "globals.h"
|
||||||
|
|
||||||
STATIC int CharRequest(struct dhdr FAR *dev)
|
STATIC int CharRequest(struct dhdr FAR **pdev, unsigned command)
|
||||||
{
|
{
|
||||||
|
struct dhdr FAR *dev = *pdev;
|
||||||
|
CharReqHdr.r_command = command;
|
||||||
CharReqHdr.r_unit = 0;
|
CharReqHdr.r_unit = 0;
|
||||||
CharReqHdr.r_status = 0;
|
CharReqHdr.r_status = 0;
|
||||||
CharReqHdr.r_length = sizeof(request);
|
CharReqHdr.r_length = sizeof(request);
|
||||||
execrh(&CharReqHdr, dev);
|
execrh(&CharReqHdr, dev);
|
||||||
if (CharReqHdr.r_status & S_ERROR)
|
if (CharReqHdr.r_status & S_ERROR)
|
||||||
{
|
{
|
||||||
charloop:
|
for (;;) {
|
||||||
switch (char_error(&CharReqHdr, dev))
|
switch (char_error(&CharReqHdr, dev))
|
||||||
{
|
{
|
||||||
case ABORT:
|
case ABORT:
|
||||||
@ -56,147 +58,134 @@ STATIC int CharRequest(struct dhdr FAR *dev)
|
|||||||
return 0;
|
return 0;
|
||||||
case RETRY:
|
case RETRY:
|
||||||
return 1;
|
return 1;
|
||||||
default:
|
|
||||||
goto charloop;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
}
|
||||||
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
long BinaryCharIO(struct dhdr FAR * dev, size_t n, void FAR * bp, unsigned command)
|
long BinaryCharIO(struct dhdr FAR **pdev, size_t n, void FAR * bp,
|
||||||
|
unsigned command)
|
||||||
{
|
{
|
||||||
int err = SUCCESS;
|
int err;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
CharReqHdr.r_command = command;
|
|
||||||
CharReqHdr.r_count = n;
|
CharReqHdr.r_count = n;
|
||||||
CharReqHdr.r_trans = bp;
|
CharReqHdr.r_trans = bp;
|
||||||
} while ((err = CharRequest(dev)) == 1);
|
err = CharRequest(pdev, command);
|
||||||
|
} while (err == 1);
|
||||||
return err == SUCCESS ? (long)CharReqHdr.r_count : err;
|
return err == SUCCESS ? (long)CharReqHdr.r_count : err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STATIC int CharIO(struct dhdr FAR **pdev, unsigned char ch, unsigned command)
|
||||||
|
{
|
||||||
|
int err = (int)BinaryCharIO(pdev, 1, &ch, command);
|
||||||
|
if (err == 0)
|
||||||
|
return 256;
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
/* STATE FUNCTIONS */
|
/* STATE FUNCTIONS */
|
||||||
|
|
||||||
STATIC struct dhdr FAR *idx_to_dev(int sft_idx)
|
void CharCmd(struct dhdr FAR **pdev, unsigned command)
|
||||||
{
|
{
|
||||||
sft FAR *s = idx_to_sft(sft_idx);
|
while (CharRequest(pdev, command) == 1);
|
||||||
if (FP_OFF(s) == (size_t)-1 || (s->sft_mode & SFT_MWRITE) ||
|
}
|
||||||
!(s->sft_flags & SFT_FDEVICE))
|
|
||||||
|
STATIC int Busy(struct dhdr FAR **pdev)
|
||||||
|
{
|
||||||
|
CharCmd(pdev, C_ISTAT);
|
||||||
|
return CharReqHdr.r_status & S_BUSY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void con_flush(struct dhdr FAR **pdev)
|
||||||
|
{
|
||||||
|
CharCmd(pdev, C_IFLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if the sft is invalid, then we just monitor syscon */
|
||||||
|
struct dhdr FAR *sft_to_dev(sft FAR *s)
|
||||||
|
{
|
||||||
|
if (FP_OFF(s) == (size_t) -1)
|
||||||
return syscon;
|
return syscon;
|
||||||
else
|
|
||||||
return s->sft_dev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if sft_idx is invalid, then we just monitor syscon */
|
|
||||||
STATIC BOOL Busy(int sft_idx)
|
|
||||||
{
|
|
||||||
sft FAR *s = idx_to_sft(sft_idx);
|
|
||||||
|
|
||||||
if (s->sft_flags & SFT_FDEVICE)
|
if (s->sft_flags & SFT_FDEVICE)
|
||||||
{
|
return s->sft_dev;
|
||||||
struct dhdr FAR *dev = idx_to_dev(sft_idx);
|
return NULL;
|
||||||
do {
|
|
||||||
CharReqHdr.r_command = C_ISTAT;
|
|
||||||
} while(CharRequest(dev) == 1);
|
|
||||||
if (CharReqHdr.r_status & S_BUSY)
|
|
||||||
return TRUE;
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
int StdinBusy(void)
|
||||||
|
{
|
||||||
|
sft FAR *s = get_sft(STDIN);
|
||||||
|
struct dhdr FAR *dev = sft_to_dev(s);
|
||||||
|
|
||||||
|
if (dev)
|
||||||
|
return Busy(&dev);
|
||||||
|
|
||||||
return s->sft_posit >= s->sft_size;
|
return s->sft_posit >= s->sft_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL StdinBusy(void)
|
STATIC void Do_DosIdle_loop(struct dhdr FAR **pdev)
|
||||||
{
|
|
||||||
return Busy(get_sft_idx(STDIN));
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void Do_DosIdle_loop(int sft_idx)
|
|
||||||
{
|
{
|
||||||
/* the idle loop is only safe if we're using the character stack */
|
/* the idle loop is only safe if we're using the character stack */
|
||||||
if (user_r->AH < 0xd)
|
if (user_r->AH < 0xd)
|
||||||
while (Busy(sft_idx))
|
while (Busy(pdev) && Busy(&syscon))
|
||||||
DosIdle_int();
|
DosIdle_int();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get character from the console - this is how DOS gets
|
/* get character from the console - this is how DOS gets
|
||||||
CTL_C/CTL_S/CTL_P when outputting */
|
CTL_C/CTL_S/CTL_P when outputting */
|
||||||
STATIC int ndread(int sft_idx)
|
STATIC int ndread(struct dhdr FAR **pdev)
|
||||||
{
|
{
|
||||||
struct dhdr FAR *dev = idx_to_dev(sft_idx);
|
CharCmd(pdev, C_NDREAD);
|
||||||
do {
|
|
||||||
CharReqHdr.r_command = C_NDREAD;
|
|
||||||
} while(CharRequest(dev) == 1);
|
|
||||||
if (CharReqHdr.r_status & S_BUSY)
|
if (CharReqHdr.r_status & S_BUSY)
|
||||||
return -1;
|
return -1;
|
||||||
return CharReqHdr.r_ndbyte;
|
return CharReqHdr.r_ndbyte;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC int con_get_char(int sft_idx)
|
STATIC void con_skip_char(struct dhdr FAR **pdev)
|
||||||
{
|
{
|
||||||
unsigned char c;
|
if (CharIO(pdev, 0, C_INPUT) == CTL_C)
|
||||||
BinaryCharIO(idx_to_dev(sft_idx), 1, &c, C_INPUT);
|
handle_break(pdev);
|
||||||
if (c == CTL_C)
|
|
||||||
handle_break(sft_idx);
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void con_hold(int sft_idx)
|
STATIC void con_hold(struct dhdr FAR **pdev)
|
||||||
{
|
{
|
||||||
int c;
|
int c = check_handle_break();
|
||||||
if (control_break())
|
if (*pdev != syscon)
|
||||||
handle_break(-1);
|
c = ndread(pdev);
|
||||||
c = ndread(sft_idx);
|
if (c == CTL_S || c == CTL_C)
|
||||||
if (c == CTL_S)
|
|
||||||
{
|
{
|
||||||
con_get_char(sft_idx);
|
con_skip_char(pdev);
|
||||||
Do_DosIdle_loop(sft_idx);
|
Do_DosIdle_loop(pdev);
|
||||||
/* just wait */
|
/* just wait */
|
||||||
c = con_get_char(sft_idx);
|
check_handle_break();
|
||||||
}
|
con_skip_char(pdev);
|
||||||
if (c == CTL_C)
|
|
||||||
{
|
|
||||||
con_get_char(sft_idx);
|
|
||||||
handle_break(sft_idx);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL con_break(void)
|
int con_break(void)
|
||||||
{
|
{
|
||||||
if (ndread(-1) == CTL_C)
|
int c = ndread(&syscon);
|
||||||
{
|
if (c == CTL_C)
|
||||||
con_get_char(-1);
|
con_skip_char(&syscon);
|
||||||
return TRUE;
|
return c;
|
||||||
}
|
|
||||||
else
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OUTPUT FUNCTIONS */
|
/* OUTPUT FUNCTIONS */
|
||||||
|
|
||||||
#ifdef __WATCOMC__
|
#ifdef __WATCOMC__
|
||||||
void int29(char c);
|
void fast_put_char(char c);
|
||||||
#pragma aux int29 = "int 29h" parm[al] modify exact [bx]
|
#pragma aux fast_put_char = "int 29h" parm[al] modify exact [bx]
|
||||||
#endif
|
#else
|
||||||
|
|
||||||
/* writes a character in raw mode; use int29 if possible
|
/* writes a character in raw mode using int29 for speed */
|
||||||
for speed */
|
STATIC void fast_put_char(unsigned char chr)
|
||||||
STATIC int raw_put_char(int sft_idx, int c)
|
|
||||||
{
|
|
||||||
struct dhdr FAR *dev = idx_to_dev(sft_idx);
|
|
||||||
unsigned char chr = (unsigned char)c;
|
|
||||||
|
|
||||||
if (PrinterEcho)
|
|
||||||
DosWrite(STDPRN, 1, &chr);
|
|
||||||
|
|
||||||
if (dev->dh_attr & ATTR_FASTCON)
|
|
||||||
{
|
{
|
||||||
#if defined(__TURBOC__)
|
#if defined(__TURBOC__)
|
||||||
_AL = chr;
|
_AL = chr;
|
||||||
__int__(0x29);
|
__int__(0x29);
|
||||||
#elif defined(__WATCOMC__)
|
|
||||||
int29(chr);
|
|
||||||
#elif defined(I86)
|
#elif defined(I86)
|
||||||
asm
|
asm
|
||||||
{
|
{
|
||||||
@ -204,59 +193,79 @@ STATIC int raw_put_char(int sft_idx, int c)
|
|||||||
int 0x29;
|
int 0x29;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
c = (int)BinaryCharIO(dev, 1, &chr, C_OUTPUT);
|
|
||||||
if (c < 0)
|
|
||||||
return c;
|
|
||||||
else
|
|
||||||
return chr;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* writes a character in cooked mode; maybe with printer echo;
|
/* writes a character in cooked mode; maybe with printer echo;
|
||||||
handles TAB expansion */
|
handles TAB expansion */
|
||||||
STATIC int cooked_put_char(int sft_idx, int c)
|
STATIC int cooked_write_char(struct dhdr FAR **pdev,
|
||||||
|
unsigned char c,
|
||||||
|
unsigned char *fast_counter)
|
||||||
{
|
{
|
||||||
int err = 0;
|
|
||||||
unsigned char scrpos = scr_pos;
|
unsigned char scrpos = scr_pos;
|
||||||
|
unsigned char count = 1;
|
||||||
|
|
||||||
/* Test for hold char */
|
if (c == CR)
|
||||||
con_hold(sft_idx);
|
|
||||||
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case CR:
|
|
||||||
scrpos = 0;
|
scrpos = 0;
|
||||||
break;
|
else if (c == BS) {
|
||||||
case LF:
|
|
||||||
case BELL:
|
|
||||||
break;
|
|
||||||
case BS:
|
|
||||||
if (scrpos > 0)
|
if (scrpos > 0)
|
||||||
scrpos--;
|
scrpos--;
|
||||||
break;
|
} else if (c != LF && c != BELL) {
|
||||||
case HT:
|
if (c == HT) {
|
||||||
do
|
count = 8 - (scrpos & 7);
|
||||||
err = raw_put_char(sft_idx, ' ');
|
c = ' ';
|
||||||
while (err >= 0 && ((++scrpos) & 7));
|
}
|
||||||
break;
|
scrpos += count;
|
||||||
default:
|
|
||||||
scrpos++;
|
|
||||||
}
|
}
|
||||||
scr_pos = scrpos;
|
scr_pos = scrpos;
|
||||||
if (c != HT)
|
|
||||||
err = raw_put_char(sft_idx, c);
|
do {
|
||||||
|
|
||||||
|
/* if not fast then < 0x80; always check
|
||||||
|
otherwise check every 32 characters */
|
||||||
|
if (*fast_counter <= 0x80)
|
||||||
|
/* Test for hold char and ctl_c */
|
||||||
|
con_hold(pdev);
|
||||||
|
*fast_counter += 1;
|
||||||
|
*fast_counter &= 0x9f;
|
||||||
|
|
||||||
|
if (PrinterEcho)
|
||||||
|
DosWrite(STDPRN, 1, &c);
|
||||||
|
if (*fast_counter & 0x80)
|
||||||
|
{
|
||||||
|
fast_put_char(c);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int err = CharIO(pdev, c, C_OUTPUT);
|
||||||
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
} while (--count > 0);
|
||||||
|
return SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
long cooked_write(int sft_idx, size_t n, char FAR *bp)
|
long cooked_write(struct dhdr FAR **pdev, size_t n, char FAR *bp)
|
||||||
{
|
{
|
||||||
size_t xfer;
|
size_t xfer = 0;
|
||||||
int err = SUCCESS;
|
unsigned char fast_counter;
|
||||||
|
|
||||||
for (xfer = 0; err >= SUCCESS && xfer < n && *bp != CTL_Z; bp++, xfer++)
|
/* bit 7 means fastcon; low 5 bits count number of characters */
|
||||||
err = cooked_put_char(sft_idx, *bp);
|
fast_counter = ((*pdev)->dh_attr & ATTR_FASTCON) << 3;
|
||||||
return err < SUCCESS ? (long)err : xfer;
|
|
||||||
|
for (xfer = 0; xfer < n; xfer++)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
unsigned char c = *bp++;
|
||||||
|
|
||||||
|
if (c == CTL_Z)
|
||||||
|
break;
|
||||||
|
|
||||||
|
err = cooked_write_char(pdev, c, &fast_counter);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
return xfer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* writes character for disk file or device */
|
/* writes character for disk file or device */
|
||||||
@ -276,13 +285,13 @@ void write_char_stdout(int c)
|
|||||||
/* this is for handling things like ^C, mostly used in echoed input */
|
/* this is for handling things like ^C, mostly used in echoed input */
|
||||||
STATIC int echo_char(int c, int sft_idx)
|
STATIC int echo_char(int c, int sft_idx)
|
||||||
{
|
{
|
||||||
|
int out = c;
|
||||||
if (iscntrl(c) && c != HT && c != LF && c != CR)
|
if (iscntrl(c) && c != HT && c != LF && c != CR)
|
||||||
{
|
{
|
||||||
write_char('^', sft_idx);
|
write_char('^', sft_idx);
|
||||||
write_char(c + '@', sft_idx);
|
out += '@';
|
||||||
}
|
}
|
||||||
else
|
write_char(out, sft_idx);
|
||||||
write_char(c, sft_idx);
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,28 +309,28 @@ STATIC void destr_bs(int sft_idx)
|
|||||||
|
|
||||||
/* READ FUNCTIONS */
|
/* READ FUNCTIONS */
|
||||||
|
|
||||||
STATIC int raw_get_char(int sft_idx, BOOL check_break)
|
STATIC int raw_get_char(struct dhdr FAR **pdev, BOOL check_break)
|
||||||
{
|
{
|
||||||
unsigned char c;
|
Do_DosIdle_loop(pdev);
|
||||||
int err;
|
|
||||||
|
|
||||||
Do_DosIdle_loop(sft_idx);
|
|
||||||
if (check_break)
|
if (check_break)
|
||||||
con_hold(sft_idx);
|
{
|
||||||
|
con_hold(pdev);
|
||||||
err = (int)BinaryCharIO(idx_to_dev(sft_idx), 1, &c, C_INPUT);
|
Do_DosIdle_loop(pdev);
|
||||||
return err < 0 ? err : c;
|
}
|
||||||
|
return CharIO(pdev, 0, C_INPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
long cooked_read(int sft_idx, size_t n, char FAR *bp)
|
long cooked_read(struct dhdr FAR **pdev, size_t n, char FAR *bp)
|
||||||
{
|
{
|
||||||
unsigned xfer = 0;
|
unsigned xfer = 0;
|
||||||
int c;
|
int c;
|
||||||
while(n--)
|
while(n--)
|
||||||
{
|
{
|
||||||
c = raw_get_char(sft_idx, TRUE);
|
c = raw_get_char(pdev, TRUE);
|
||||||
if (c < 0)
|
if (c < 0)
|
||||||
return c;
|
return c;
|
||||||
|
if (c == 256)
|
||||||
|
break;
|
||||||
*bp++ = c;
|
*bp++ = c;
|
||||||
xfer++;
|
xfer++;
|
||||||
if (bp[-1] == CTL_Z)
|
if (bp[-1] == CTL_Z)
|
||||||
@ -333,10 +342,10 @@ long cooked_read(int sft_idx, size_t n, char FAR *bp)
|
|||||||
unsigned char read_char(int sft_idx, BOOL check_break)
|
unsigned char read_char(int sft_idx, BOOL check_break)
|
||||||
{
|
{
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
sft FAR *s = idx_to_sft(sft_idx);
|
struct dhdr FAR *dev = sft_to_dev(idx_to_sft(sft_idx));
|
||||||
|
|
||||||
if ((FP_OFF(s) == (size_t) -1) || (s->sft_flags & SFT_FDEVICE))
|
if (dev)
|
||||||
return raw_get_char(sft_idx, check_break);
|
return (unsigned char)raw_get_char(&dev, check_break);
|
||||||
|
|
||||||
DosRWSft(sft_idx, 1, &c, XFR_READ);
|
DosRWSft(sft_idx, 1, &c, XFR_READ);
|
||||||
return c;
|
return c;
|
||||||
@ -352,18 +361,6 @@ unsigned char read_char_stdin(BOOL check_break)
|
|||||||
return read_char(get_sft_idx(STDIN), check_break);
|
return read_char(get_sft_idx(STDIN), check_break);
|
||||||
}
|
}
|
||||||
|
|
||||||
void KbdFlush(int sft_idx)
|
|
||||||
{
|
|
||||||
struct dhdr FAR *dev = idx_to_dev(sft_idx);
|
|
||||||
|
|
||||||
do {
|
|
||||||
CharReqHdr.r_unit = 0;
|
|
||||||
CharReqHdr.r_status = 0;
|
|
||||||
CharReqHdr.r_command = C_IFLUSH;
|
|
||||||
CharReqHdr.r_length = sizeof(request);
|
|
||||||
} while (CharRequest(dev) == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reads a line (buffered, called by int21/ah=0ah, 3fh) */
|
/* reads a line (buffered, called by int21/ah=0ah, 3fh) */
|
||||||
void read_line(int sft_in, int sft_out, keyboard FAR * kp)
|
void read_line(int sft_in, int sft_out, keyboard FAR * kp)
|
||||||
{
|
{
|
||||||
|
@ -230,10 +230,12 @@ long DosRWSft(int sft_idx, size_t n, void FAR * bp, int mode)
|
|||||||
/* Do a device transfer if device */
|
/* Do a device transfer if device */
|
||||||
if (s->sft_flags & SFT_FDEVICE)
|
if (s->sft_flags & SFT_FDEVICE)
|
||||||
{
|
{
|
||||||
|
struct dhdr FAR *dev = s->sft_dev;
|
||||||
|
|
||||||
/* Now handle raw and cooked modes */
|
/* Now handle raw and cooked modes */
|
||||||
if (s->sft_flags & SFT_FBINARY)
|
if (s->sft_flags & SFT_FBINARY)
|
||||||
{
|
{
|
||||||
long rc = BinaryCharIO(s->sft_dev, n, bp,
|
long rc = BinaryCharIO(&dev, n, bp,
|
||||||
mode == XFR_READ ? C_INPUT : C_OUTPUT);
|
mode == XFR_READ ? C_INPUT : C_OUTPUT);
|
||||||
if (mode == XFR_WRITE && rc > 0 && (s->sft_flags & SFT_FCONOUT))
|
if (mode == XFR_WRITE && rc > 0 && (s->sft_flags & SFT_FCONOUT))
|
||||||
{
|
{
|
||||||
@ -275,7 +277,7 @@ long DosRWSft(int sft_idx, size_t n, void FAR * bp, int mode)
|
|||||||
if (s->sft_flags & SFT_FCONIN)
|
if (s->sft_flags & SFT_FCONIN)
|
||||||
rc = read_line_handle(sft_idx, n, bp);
|
rc = read_line_handle(sft_idx, n, bp);
|
||||||
else
|
else
|
||||||
rc = cooked_read(sft_idx, n, bp);
|
rc = cooked_read(&dev, n, bp);
|
||||||
if (*(char *)bp == CTL_Z)
|
if (*(char *)bp == CTL_Z)
|
||||||
s->sft_flags &= ~SFT_FEOF;
|
s->sft_flags &= ~SFT_FEOF;
|
||||||
return rc;
|
return rc;
|
||||||
@ -289,7 +291,7 @@ long DosRWSft(int sft_idx, size_t n, void FAR * bp, int mode)
|
|||||||
if (s->sft_flags & SFT_FNUL)
|
if (s->sft_flags & SFT_FNUL)
|
||||||
return n;
|
return n;
|
||||||
else
|
else
|
||||||
return cooked_write(sft_idx, n, bp);
|
return cooked_write(&dev, n, bp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1399,13 +1401,13 @@ struct dhdr FAR *IsDevice(const char FAR * fname)
|
|||||||
|
|
||||||
for (i = 0; i < FNAME_SIZE; i++)
|
for (i = 0; i < FNAME_SIZE; i++)
|
||||||
{
|
{
|
||||||
char c1 = froot[i];
|
unsigned char c1 = (unsigned char)froot[i];
|
||||||
if (c1 == '.' || c1 == '\0')
|
if (c1 == '.' || c1 == '\0')
|
||||||
{
|
{
|
||||||
/* check if remainder of device name consists of spaces or nulls */
|
/* check if remainder of device name consists of spaces or nulls */
|
||||||
for (; i < FNAME_SIZE; i++)
|
for (; i < FNAME_SIZE; i++)
|
||||||
{
|
{
|
||||||
char c2 = dhp->dh_name[i];
|
unsigned char c2 = dhp->dh_name[i];
|
||||||
if (c2 != ' ' && c2 != '\0')
|
if (c2 != ' ' && c2 != '\0')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -429,6 +429,9 @@ VOID fputbyte(VOID FAR *, UBYTE);
|
|||||||
/*#define is_leap_year(y) ((y) & 3 ? 0 : (y) % 100 ? 1 : (y) % 400 ? 0 : 1) */
|
/*#define is_leap_year(y) ((y) & 3 ? 0 : (y) % 100 ? 1 : (y) % 400 ? 0 : 1) */
|
||||||
|
|
||||||
/* ^Break handling */
|
/* ^Break handling */
|
||||||
|
#ifdef __WATCOMC__
|
||||||
|
#pragma aux (cdecl) spawn_int23 aborts;
|
||||||
|
#endif
|
||||||
void ASMCFUNC spawn_int23(void); /* procsupt.asm */
|
void ASMCFUNC spawn_int23(void); /* procsupt.asm */
|
||||||
|
|
||||||
GLOBAL BYTE ReturnAnyDosVersionExpected;
|
GLOBAL BYTE ReturnAnyDosVersionExpected;
|
||||||
|
@ -374,7 +374,6 @@ VOID ASMCFUNC int21_service(iregs FAR * r)
|
|||||||
#define FP_DS_DX (MK_FP(lr.DS, lr.DX))
|
#define FP_DS_DX (MK_FP(lr.DS, lr.DX))
|
||||||
#define FP_ES_DI (MK_FP(lr.ES, lr.DI))
|
#define FP_ES_DI (MK_FP(lr.ES, lr.DI))
|
||||||
|
|
||||||
|
|
||||||
#define CLEAR_CARRY_FLAG() r->FLAGS &= ~FLG_CARRY
|
#define CLEAR_CARRY_FLAG() r->FLAGS &= ~FLG_CARRY
|
||||||
#define SET_CARRY_FLAG() r->FLAGS |= FLG_CARRY
|
#define SET_CARRY_FLAG() r->FLAGS |= FLG_CARRY
|
||||||
|
|
||||||
@ -407,23 +406,8 @@ dispatch:
|
|||||||
|
|
||||||
|
|
||||||
/* Check for Ctrl-Break */
|
/* Check for Ctrl-Break */
|
||||||
switch (lr.AH)
|
if (break_ena || (lr.AH >= 1 && lr.AH <= 5) || (lr.AH >= 8 && lr.AH <= 0x0b))
|
||||||
{
|
check_handle_break;
|
||||||
default:
|
|
||||||
if (!break_ena)
|
|
||||||
break;
|
|
||||||
case 0x01:
|
|
||||||
case 0x02:
|
|
||||||
case 0x03:
|
|
||||||
case 0x04:
|
|
||||||
case 0x05:
|
|
||||||
case 0x08:
|
|
||||||
case 0x09:
|
|
||||||
case 0x0a:
|
|
||||||
case 0x0b:
|
|
||||||
if (control_break())
|
|
||||||
handle_break(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The dispatch handler */
|
/* The dispatch handler */
|
||||||
switch (lr.AH)
|
switch (lr.AH)
|
||||||
@ -436,13 +420,16 @@ dispatch:
|
|||||||
|
|
||||||
/* Read Keyboard with Echo */
|
/* Read Keyboard with Echo */
|
||||||
case 0x01:
|
case 0x01:
|
||||||
|
DOS_01:
|
||||||
lr.AL = read_char_stdin(TRUE);
|
lr.AL = read_char_stdin(TRUE);
|
||||||
write_char_stdout(lr.AL);
|
write_char_stdout(lr.AL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Display Character */
|
/* Display Character */
|
||||||
case 0x02:
|
case 0x02:
|
||||||
write_char_stdout(lr.DL);
|
DOS_02:
|
||||||
|
lr.AL = lr.DL;
|
||||||
|
write_char_stdout(lr.AL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Auxiliary Input */
|
/* Auxiliary Input */
|
||||||
@ -461,27 +448,28 @@ dispatch:
|
|||||||
|
|
||||||
/* Direct Console I/O */
|
/* Direct Console I/O */
|
||||||
case 0x06:
|
case 0x06:
|
||||||
|
DOS_06:
|
||||||
if (lr.DL != 0xff)
|
if (lr.DL != 0xff)
|
||||||
write_char_stdout(lr.DL);
|
goto DOS_02;
|
||||||
else if (StdinBusy())
|
|
||||||
{
|
|
||||||
lr.AL = 0x00;
|
lr.AL = 0x00;
|
||||||
r->FLAGS |= FLG_ZERO;
|
r->FLAGS |= FLG_ZERO;
|
||||||
}
|
if (StdinBusy())
|
||||||
else
|
break;
|
||||||
{
|
|
||||||
r->FLAGS &= ~FLG_ZERO;
|
r->FLAGS &= ~FLG_ZERO;
|
||||||
lr.AL = read_char_stdin(FALSE);
|
lr.AL = read_char_stdin(FALSE);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Direct Console Input */
|
/* Direct Console Input */
|
||||||
case 0x07:
|
case 0x07:
|
||||||
|
DOS_07:
|
||||||
lr.AL = read_char_stdin(FALSE);
|
lr.AL = read_char_stdin(FALSE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Read Keyboard Without Echo */
|
/* Read Keyboard Without Echo */
|
||||||
case 0x08:
|
case 0x08:
|
||||||
|
DOS_08:
|
||||||
lr.AL = read_char_stdin(TRUE);
|
lr.AL = read_char_stdin(TRUE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -501,35 +489,34 @@ dispatch:
|
|||||||
|
|
||||||
/* Buffered Keyboard Input */
|
/* Buffered Keyboard Input */
|
||||||
case 0x0a:
|
case 0x0a:
|
||||||
|
DOS_0A:
|
||||||
read_line(get_sft_idx(STDIN), get_sft_idx(STDOUT), FP_DS_DX);
|
read_line(get_sft_idx(STDIN), get_sft_idx(STDOUT), FP_DS_DX);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Check Stdin Status */
|
/* Check Stdin Status */
|
||||||
case 0x0b:
|
case 0x0b:
|
||||||
|
lr.AL = 0xFF;
|
||||||
if (StdinBusy())
|
if (StdinBusy())
|
||||||
lr.AL = 0x00;
|
lr.AL = 0x00;
|
||||||
else
|
|
||||||
lr.AL = 0xFF;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Flush Buffer, Read Keyboard */
|
/* Flush Buffer, Read Keyboard */
|
||||||
case 0x0c:
|
case 0x0c:
|
||||||
KbdFlush(get_sft_idx(STDIN));
|
{
|
||||||
|
struct dhdr FAR *dev = sft_to_dev(get_sft(STDIN));
|
||||||
|
if (dev)
|
||||||
|
con_flush(&dev);
|
||||||
switch (lr.AL)
|
switch (lr.AL)
|
||||||
{
|
{
|
||||||
case 0x01:
|
case 0x01: goto DOS_01;
|
||||||
case 0x06:
|
case 0x06: goto DOS_06;
|
||||||
case 0x07:
|
case 0x07: goto DOS_07;
|
||||||
case 0x08:
|
case 0x08: goto DOS_08;
|
||||||
case 0x0a:
|
case 0x0a: goto DOS_0A;
|
||||||
lr.AH = lr.AL;
|
}
|
||||||
goto dispatch;
|
|
||||||
|
|
||||||
default:
|
|
||||||
lr.AL = 0x00;
|
lr.AL = 0x00;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
|
||||||
/* Reset Drive */
|
/* Reset Drive */
|
||||||
case 0x0d:
|
case 0x0d:
|
||||||
@ -1819,6 +1806,9 @@ struct int2f12regs {
|
|||||||
|
|
||||||
extern short AllocateHMASpace (size_t lowbuffer, size_t highbuffer);
|
extern short AllocateHMASpace (size_t lowbuffer, size_t highbuffer);
|
||||||
|
|
||||||
|
/* WARNING: modifications in `r' are used outside of int2F_12_handler()
|
||||||
|
* On input r.ax==0x12xx, 0x4A01 or 0x4A02
|
||||||
|
*/
|
||||||
VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
||||||
{
|
{
|
||||||
UWORD function = r.ax & 0xff;
|
UWORD function = r.ax & 0xff;
|
||||||
@ -1829,35 +1819,30 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs r)
|
|||||||
*/
|
*/
|
||||||
if ((r.ax & 0xff00) == 0x4a00)
|
if ((r.ax & 0xff00) == 0x4a00)
|
||||||
{
|
{
|
||||||
size_t wantedBytes = r.bx;
|
size_t wantedBytes, offs;
|
||||||
|
|
||||||
|
if (function != 1 && function != 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
wantedBytes = r.bx;
|
||||||
|
r.es = r.di = 0xffff;
|
||||||
r.bx = 0;
|
r.bx = 0;
|
||||||
r.es = FP_SEG(firstAvailableBuf);
|
|
||||||
r.di = FP_OFF(firstAvailableBuf);
|
|
||||||
if (FP_SEG(firstAvailableBuf) != 0xffff)
|
if (FP_SEG(firstAvailableBuf) != 0xffff)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (r.ax == 0x4a01)
|
offs = FP_OFF(firstAvailableBuf);
|
||||||
{
|
r.di = offs;
|
||||||
r.bx = 0 - FP_OFF(firstAvailableBuf);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (r.ax == 0x4a02)
|
if (function == 0x02)
|
||||||
{
|
{
|
||||||
if (wantedBytes > 0 - FP_OFF(firstAvailableBuf))
|
if (wantedBytes > ~offs)
|
||||||
{
|
|
||||||
r.bx = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
AllocateHMASpace(FP_OFF(firstAvailableBuf),
|
AllocateHMASpace(FP_OFF(firstAvailableBuf),
|
||||||
FP_OFF(firstAvailableBuf)+wantedBytes);
|
FP_OFF(firstAvailableBuf)+wantedBytes);
|
||||||
firstAvailableBuf += wantedBytes;
|
firstAvailableBuf += wantedBytes;
|
||||||
|
r.bx = wantedBytes;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (function > 0x31)
|
if (function > 0x31)
|
||||||
|
@ -48,23 +48,28 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks,
|
|||||||
/* *** End of change */
|
/* *** End of change */
|
||||||
|
|
||||||
/* break.c */
|
/* break.c */
|
||||||
int control_break(void);
|
#ifdef __WATCOMC__
|
||||||
void handle_break(int sft_idx);
|
#pragma aux handle_break aborts;
|
||||||
|
#endif
|
||||||
|
int check_handle_break(void);
|
||||||
|
void handle_break(struct dhdr FAR **pdev);
|
||||||
|
|
||||||
/* chario.c */
|
/* chario.c */
|
||||||
long BinaryCharIO(struct dhdr FAR * dev, size_t n, void FAR * bp, unsigned command);
|
struct dhdr FAR *sft_to_dev(sft FAR *sft);
|
||||||
|
long BinaryCharIO(struct dhdr FAR **pdev, size_t n, void FAR * bp,
|
||||||
|
unsigned command);
|
||||||
int echo_char_stdin(int c);
|
int echo_char_stdin(int c);
|
||||||
BOOL con_break(void);
|
int con_break(void);
|
||||||
BOOL StdinBusy(void);
|
int StdinBusy(void);
|
||||||
void KbdFlush(int sft_idx);
|
void con_flush(struct dhdr FAR **pdev);
|
||||||
unsigned char read_char(int sft_idx, BOOL check_break);
|
unsigned char read_char(int sft_idx, BOOL check_break);
|
||||||
unsigned char read_char_stdin(BOOL check_break);
|
unsigned char read_char_stdin(BOOL check_break);
|
||||||
long cooked_read(int sft_idx, size_t n, char FAR *bp);
|
long cooked_read(struct dhdr FAR **pdev, size_t n, char FAR *bp);
|
||||||
void read_line(int sft_in, int sft_out, keyboard FAR * kp);
|
void read_line(int sft_in, int sft_out, keyboard FAR * kp);
|
||||||
size_t read_line_handle(int sft_idx, size_t n, char FAR * bp);
|
size_t read_line_handle(int sft_idx, size_t n, char FAR * bp);
|
||||||
void write_char(int c, int sft_idx);
|
void write_char(int c, int sft_idx);
|
||||||
void write_char_stdout(int c);
|
void write_char_stdout(int c);
|
||||||
long cooked_write(int sft_idx, size_t n, char FAR *bp);
|
long cooked_write(struct dhdr FAR **pdev, size_t n, char FAR *bp);
|
||||||
|
|
||||||
sft FAR *get_sft(UCOUNT);
|
sft FAR *get_sft(UCOUNT);
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ UWORD DaysFromYearMonthDay(UWORD Year, UWORD Month, UWORD DayOfMonth)
|
|||||||
/* common - call the clock driver */
|
/* common - call the clock driver */
|
||||||
void ExecuteClockDriverRequest(BYTE command)
|
void ExecuteClockDriverRequest(BYTE command)
|
||||||
{
|
{
|
||||||
BinaryCharIO(clock, sizeof(struct ClockRecord), &ClkRecord, command);
|
BinaryCharIO(&clock, sizeof(struct ClockRecord), &ClkRecord, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DosGetTime(struct dostime *dt)
|
void DosGetTime(struct dostime *dt)
|
||||||
|
Loading…
Reference in New Issue
Block a user