Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion kernel/blockio.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ void AllocateHMASpace (size_t lowbuffer, size_t highbuffer)
do
{
/* check if buffer intersects with requested area */
if (FP_OFF(bp) < highbuffer && FP_OFF(bp+1) > lowbuffer)
if (FP_OFF(bp) <= highbuffer && FP_OFF(bp+1) > lowbuffer)
{
flush1(bp);
/* unlink bp from buffer chain */
Expand Down
37 changes: 26 additions & 11 deletions kernel/inthndlr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1928,26 +1928,41 @@ VOID ASMCFUNC int2F_12_handler(struct int2f12regs FAR *pr)
{
COUNT rc;
long lrc;
UDWORD tsize;
UWORD requestedsize;

#define r (*pr)

if (r.AH == 0x4a)
{
size_t size = 0, offs = 0xffff;
size_t size = 0, offs = 0xffff, realoffs; /* defaults for no alloc */

r.ES = offs;
if (FP_SEG(firstAvailableBuf) == offs) /* HMA present? */
{
offs = FP_OFF(firstAvailableBuf);
size = ~offs; /* BX for query HMA */
if (r.AL == 0x02) /* allocate HMA space */
{
tsize = (r.BX + 0xf) & 0xfffffff0UL; /* align to paragraph */
if (tsize < size)
size = (UWORD)tsize;
AllocateHMASpace(offs, offs+size);
firstAvailableBuf += size;
realoffs = FP_OFF(firstAvailableBuf);
if (realoffs <= 0xFFF0) { /* if any free (not yet exthausted) */
offs = realoffs;
offs += 15;
offs &= ~ 15; /* annoying: buffers may be unaligned */
size = - offs; /* bx + di = 10000h */
if (r.AL == 0x02) /* allocate HMA space */
{
requestedsize = (r.BX + 15) & ~ 15; /* align to paragraph */
if (requestedsize < r.BX ||
requestedsize > size) { /* overflow or OOM */
size = 0;
offs = 0xffff; /* requested more than we have */
} else {
UWORD alignment = offs - realoffs;
size = (UWORD)requestedsize; /* return rounded size */
AllocateHMASpace(realoffs, offs + size - 1); /* ! realoffs */
if ( ((UDWORD)offs + (UDWORD)size) == 0x10000UL ) {
firstAvailableBuf = MK_FP(0xFFFF, 0xFFFF); /* exhausted */
} else {
firstAvailableBuf += size + alignment; /* advance free pointer */
}
}
}
}
}
r.DI = offs;
Expand Down