diff --git a/hdr/lol.h b/hdr/lol.h index 97f75d7..6da4ccb 100644 --- a/hdr/lol.h +++ b/hdr/lol.h @@ -26,6 +26,8 @@ /* Boston, MA 02111-1307 USA. */ /****************************************************************/ +enum {LOC_CONV=0, LOC_HMA=1}; + /* note: we start at DOSDS:0, but the "official" list of lists starts a little later at DOSDS:26 (this is what is returned by int21/ah=52) */ @@ -60,7 +62,7 @@ struct lol { struct buffer far *lookahead;/* 4d pointer to lookahead buffer */ unsigned short slookahead; /* 51 number of lookahead sectors */ unsigned char bufloc; /* 53 BUFFERS loc (1=HMA) */ - struct buffer far *deblock; /* 54 pointer to workspace buffer */ + char far *deblock_buf; /* 54 pointer to workspace buffer */ char filler2[5]; /* 58 ???/unused */ unsigned char int24fail; /* 5d int24 fail while making i/o stat call*/ unsigned char memstrat; /* 5e memory allocation strat during exec */ diff --git a/kernel/blockio.c b/kernel/blockio.c index 00b6bd7..66038fa 100644 --- a/kernel/blockio.c +++ b/kernel/blockio.c @@ -291,7 +291,7 @@ STATIC BOOL flush1(struct buffer FAR * bp) UWORD result; /* BER 9/4/00 */ - if ((bp->b_flag & BFR_VALID) && (bp->b_flag & BFR_DIRTY)) + if ((bp->b_flag & (BFR_VALID | BFR_DIRTY)) == (BFR_VALID | BFR_DIRTY)) { /* BER 9/4/00 */ result = dskxfer(bp->b_unit, bp->b_blkno, bp->b_buffer, 1, DSKWRITE); @@ -405,7 +405,6 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks, IoReqHdr.r_status = 0; IoReqHdr.r_meddesc = dpbp->dpb_mdb; - IoReqHdr.r_trans = (BYTE FAR *) buf; IoReqHdr.r_count = numblocks; if (blkno >= MAXSHORT) { @@ -414,8 +413,26 @@ UWORD dskxfer(COUNT dsk, ULONG blkno, VOID FAR * buf, UWORD numblocks, } else IoReqHdr.r_start = blkno; - execrh((request FAR *) & IoReqHdr, dpbp->dpb_device); - if (!(IoReqHdr.r_status & S_ERROR) && (IoReqHdr.r_status & S_DONE)) + /* + * Some drivers normalise transfer address so HMA transfers are disastrous! + * Then transfer block through xferbuf (DiskTransferBuffer doesn't work!) + * (But this won't work for multi-block HMA transfers... are there any?) + */ + if (FP_SEG(buf) >= 0xa000 && numblocks == 1 && bufloc != LOC_CONV) + { + IoReqHdr.r_trans = deblock_buf; + if (mode == DSKWRITE) + fmemcpy(deblock_buf, buf, SEC_SIZE); + execrh((request FAR *) & IoReqHdr, dpbp->dpb_device); + if (mode == DSKREAD) + fmemcpy(buf, deblock_buf, SEC_SIZE); + } + else + { + IoReqHdr.r_trans = (BYTE FAR *) buf; + execrh((request FAR *) & IoReqHdr, dpbp->dpb_device); + } + if ((IoReqHdr.r_status & (S_ERROR | S_DONE)) == S_DONE) break; /* INT25/26 (_SEEMS_ TO) return immediately with 0x8002, diff --git a/kernel/config.c b/kernel/config.c index a938a7a..edc396c 100644 --- a/kernel/config.c +++ b/kernel/config.c @@ -226,20 +226,6 @@ BYTE HMAState = 0; #define HMA_DONE 2 /* Moved kernel to HMA */ #define HMA_LOW 3 /* Definitely LOW */ -STATIC void FAR* ConfigAlloc(COUNT bytes, char type) -{ - VOID FAR *p; - - p = HMAalloc(bytes); - - if (p == NULL) - p = KernelAlloc(bytes, type, 0); - - /* printf("ConfigAlloc %d at %p\n", bytes, p); */ - - return p; -} - /* Do first time initialization. Store last so that we can reset it */ /* later. */ void PreConfig(void) @@ -1242,7 +1228,7 @@ STATIC BOOL LoadDevice(BYTE * pLine, char FAR *top, COUNT mode) */ /* add \r\n to the command line */ - strcat(szBuf, "\r\n"); + strcat(szBuf, " \r\n"); dhp = MK_FP(base, 0); @@ -1639,9 +1625,23 @@ VOID config_init_buffers(COUNT anzBuffers) lpTop = lpOldTop; LoL->inforecptr = &LoL->firstbuf; - LoL->firstbuf = ConfigAlloc(sizeof(struct buffer) * anzBuffers, 'B'); + + { + size_t bytes = sizeof(struct buffer) * anzBuffers; + pbuffer = HMAalloc(bytes); - pbuffer = LoL->firstbuf; + if (pbuffer == NULL) + { + pbuffer = KernelAlloc(bytes, 'B', 0); + } + else + { + LoL->bufloc = LOC_HMA; + LoL->deblock_buf = KernelAlloc(SEC_SIZE, 'B', 0); + } + } + + LoL->firstbuf = pbuffer; DebugPrintf(("init_buffers (size %u) at", sizeof(struct buffer))); DebugPrintf((" (%p)", LoL->firstbuf)); diff --git a/kernel/globals.h b/kernel/globals.h index 7858e55..ae88d1e 100644 --- a/kernel/globals.h +++ b/kernel/globals.h @@ -247,6 +247,9 @@ FAR * ASM clock, /* CLOCK$ device */ extern WORD ASM maxbksize; /* Number of Drives in system */ extern struct buffer FAR *ASM firstbuf; /* head of buffers linked list */ +enum {LOC_CONV=0, LOC_HMA=1}; +extern unsigned char ASM bufloc; /* 0=conv, 1=HMA */ +extern void far * ASM deblock_buf; /* pointer to workspace buffer */ GLOBAL char FAR *firstAvailableBuf; extern struct cds FAR * ASM CDSp; /* Current Directory Structure */ extern diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index ab6b7f3..4bb6f66 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -89,6 +89,7 @@ VOID ASMCFUNC int21_syscall(iregs FAR * irp) irp->DL = break_ena; break_ena = tmp != 0; } + break; /* Get Boot Drive */ case 0x05: diff --git a/kernel/kernel.asm b/kernel/kernel.asm index 0755dc6..f39c4d8 100644 --- a/kernel/kernel.asm +++ b/kernel/kernel.asm @@ -318,8 +318,10 @@ _firstbuf dd 0 ; 0047 disk buffer chain dw 0 ; 004B Number of dirty buffers dd 0 ; 004D pre-read buffer dw 0 ; 0051 number of look-ahead buffers - db 0 ; 0053 00=conv 01=HMA -deblock_buf dd 0 ; 0054 deblock buffer + global _bufloc +_bufloc db 0 ; 0053 00=conv 01=HMA + global _deblock_buf +_deblock_buf dd 0 ; 0054 deblock buffer times 3 db 0 ; 0058 unknown dw 0 ; 005B unknown db 0, 0FFh, 0 ; 005D unknown diff --git a/kernel/main.c b/kernel/main.c index 3aed3ac..29deeba 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -219,6 +219,7 @@ STATIC void init_kernel(void) set_DTA(MK_FP(DOS_PSP, 0x80)); init_PSPSet(DOS_PSP); init_PSPInit(DOS_PSP); + ((psp far *)MK_FP(DOS_PSP, 0))->ps_environ = DOS_PSP + 8; Init_clk_driver(); @@ -531,7 +532,7 @@ BOOL init_device(struct dhdr FAR * dhp, char *cmdLine, COUNT mode, /* * Added needed Error handle */ - if (rq.r_status & S_ERROR) + if ((rq.r_status & (S_ERROR | S_DONE)) == S_ERROR) return TRUE; if (cmdLine)