mirror of
https://github.com/FDOS/kernel.git
synced 2025-04-08 17:15:17 +02:00
fix 2F.4A MS-DOS v5 style HMA access services
* Reject allocation call with too large requested size, rather than allocating the remaining HMA. * Align returned offset to paragraph boundary. * Allow to allocate up to the very last byte of the HMA, rather than 1 byte less. * Pass last allocated byte to AllocateHMASpace instead of the byte past it, which would carry for a full allocation.
This commit is contained in:
parent
5de2eb1aa0
commit
85be764a50
@ -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 */
|
||||
|
@ -1928,26 +1928,40 @@ 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 {
|
||||
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; /* advance free pointer */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
r.DI = offs;
|
||||
|
Loading…
x
Reference in New Issue
Block a user