(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:
Bart Oldeman 2003-09-09 17:43:43 +00:00
parent 8c22873b3e
commit b0e54ff704
7 changed files with 246 additions and 252 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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