diff --git a/docs/history.txt b/docs/history.txt index 3d53f2b..e9ca0a5 100644 --- a/docs/history.txt +++ b/docs/history.txt @@ -20,6 +20,7 @@ Changelog items can list SVN revision rNUMBER and bugzilla bug NUMBER. during booting when forcing LBA mode option set * r1702 improve handling for sectors not 512 bytes in size (up to 2048 bytes, larger sizes not yet working) + * r1705 add cpu detection so memdisk args supported in 8086 build + Changes Bart * r? diff --git a/hdr/lol.h b/hdr/lol.h index 538c370..b18fa6f 100644 --- a/hdr/lol.h +++ b/hdr/lol.h @@ -55,7 +55,7 @@ struct lol { unsigned short nbuffers; /* 3f Number of buffers */ unsigned short nlookahead; /* 41 Number of lookahead buffers */ unsigned char BootDrive; /* 43 bootdrive (1=A:) */ - unsigned char dwordmoves; /* 44 use dword moves (unused) */ + unsigned char cpu; /* 44 CPU family [was unused dword moves] */ unsigned short xmssize; /* 45 extended memory size in KB */ struct buffer far *firstbuf; /* 47 head of buffers linked list */ unsigned short dirtybuf; /* 4b number of dirty buffers */ diff --git a/kernel/config.c b/kernel/config.c index e5cf3bd..9746be9 100644 --- a/kernel/config.c +++ b/kernel/config.c @@ -599,13 +599,6 @@ STATIC void umb_init(void) } } -/* we require 386, so only supported for 386+ compiled kernels */ -#if defined(MEMDISK_ARGS) -#ifndef I386 -#undef MEMDISK_ARGS -#endif -#endif - #ifdef MEMDISK_ARGS struct memdiskinfo { UWORD bytes; /* Total size of this structure, value >= 26 */ @@ -638,8 +631,12 @@ VOID DoConfig(int nPass) /* check if MEMDISK used for LoL->BootDrive, if so check for special appended arguments */ struct memdiskinfo FAR *mdsk; BYTE FAR *mdsk_cfg = NULL; - UBYTE drv = (LoL->BootDrive < 3)?0x0:0x80; /* 1=A,2=B,3=C */ - mdsk = query_memdisk(drv); + /* memdisk check & usage requires 386+, DO NOT invoke if less than 386 */ + if (LoL->cpu >= 3) + { + UBYTE drv = (LoL->BootDrive < 3)?0x0:0x80; /* 1=A,2=B,3=C */ + mdsk = query_memdisk(drv); + } #endif if (nPass==0) diff --git a/kernel/cpu.asm b/kernel/cpu.asm new file mode 100644 index 0000000..281dfd8 --- /dev/null +++ b/kernel/cpu.asm @@ -0,0 +1,74 @@ +; File: +; cpu.asm +; Description: +; Query basic CPU running on +; +; DOS-C +; Copyright (c) 2012 +; FreeDOS +; All Rights Reserved +; +; This file is part of DOS-C. +; +; DOS-C is free software; you can redistribute it and/or +; modify it under the terms of the GNU General Public License +; as published by the Free Software Foundation; either version +; 2, or (at your option) any later version. +; +; DOS-C is distributed in the hope that it will be useful, but +; WITHOUT ANY WARRANTY; without even the implied warranty of +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +; the GNU General Public License for more details. +; +; + +%include "segs.inc" +segment INIT_TEXT + +CPU 386 +;********************************************************************* +; +; UWORD query_cpu() based on Eric Auer's public domain cpulevel.asm +; input: none +; output: ax = cpu, 0=8086/8088, 1=186/188, 2=286, 3=386+ + global _query_cpu + _query_cpu: + ; save registers, assumes enough space on stack & valid stack frame setup + ;push ax - no need to save, return value saved here + push bx + push cx + pushf ; save flags + + ; begin check, assume x86 unless later family detected + xor bx, bx ; 808x or 186 highest detected family stored in bx + push bx + popf ; try to clear all flag bits + pushf ; copy flags to ax so we can test if clear succeeded + pop ax + and ax, 0f000h + cmp ax, 0f000h + jnz is286 ; no the 4 msb stuck set to 1, so is a 808x or 8018x + mov ax,1 ; determine if 8086 or 186 + mov cl,64 ; try to shift further than size of ax + shr ax,cl + or ax,ax + jz is086 ; 186 ignores the upper bits of cl + mov bx, 1 ; 186: above 808x, below 286 +is086: jmp short cleanup +is286: mov bx, 2 ; at least 286 + mov ax, 0f000h + push ax + popf ; try to set 4 msb of flags + pushf ; copy flags to ax so we can test if clear succeeded + pop ax + test ax, 0f000h + jz cleanup ; 4 msb stuck to 0: 80286 + mov bx, 3 ; at least 386 + + cleanup: + mov ax, bx ; return CPU family + popf + pop cx + pop bx + retn + diff --git a/kernel/globals.h b/kernel/globals.h index 8399e46..effcd3d 100644 --- a/kernel/globals.h +++ b/kernel/globals.h @@ -326,6 +326,7 @@ extern BYTE ASM verify_ena, /* verify enabled flag */ extern UWORD ASM return_code; /* Process termination rets */ extern UBYTE ASM BootDrive, /* Drive we came up from */ + ASM CPULevel, /* CPU family, 0=8086, 1=186, ... */ ASM scr_pos; /* screen position for bs, ht, etc */ /*extern WORD NumFloppies; !!*//* How many floppies we have */ diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index a0666ec..b245d63 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -39,7 +39,7 @@ BYTE *RcsId = #ifdef TSC STATIC VOID StartTrace(VOID); -static bTraceNext = FALSE; +STATIC bTraceNext = FALSE; #endif #if 0 /* Very suspicious, passing structure by value?? @@ -81,7 +81,7 @@ VOID ASMCFUNC int21_syscall(iregs FAR * irp) /* Set Ctrl-C flag; returns dl = break_ena */ case 0x01: break_ena = irp->DL & 1; - /* fall through */ + /* fall through so DL only low bit (as in MS-DOS) */ /* Get Ctrl-C flag */ case 0x00: @@ -105,19 +105,26 @@ VOID ASMCFUNC int21_syscall(iregs FAR * irp) case 0x06: irp->BL = os_major; irp->BH = os_minor; - irp->DL = rev_number; + irp->DL = 0; /* lower 3 bits revision #, remaining should be 0 */ irp->DH = version_flags; /* bit3:runs in ROM,bit 4: runs in HMA */ break; - case 0x03: /* DOS 7 does not set AL */ - case 0x07: /* neither here */ + /* case 0x03: */ /* DOS 7 does not set AL */ + /* case 0x07: */ /* neither here */ default: /* set AL=0xFF as error, NOT carry */ irp->AL = 0xff; break; - /* set FreeDOS returned version for int 21.30 from BX */ - case 0xfc: /* 0xfc ... 0xff are FreeDOS extensions */ + /* the remaining are FreeDOS extensions */ + + /* return CPU family */ + case 0xfa: + irp->AL = CPULevel; + break; + + /* set FreeDOS returned version for int 21.30 from BX */ + case 0xfc: os_setver_major = irp->BL; os_setver_minor = irp->BH; break; @@ -724,9 +731,12 @@ dispatch: /* Get (editable) DOS Version */ case 0x30: + if (lr.AL == 1) /* from RBIL, if AL=1 then return version_flags */ + lr.BH = version_flags; + else + lr.BH = OEM_ID; lr.AL = os_setver_major; lr.AH = os_setver_minor; - lr.BH = OEM_ID; lr.BL = REVISION_SEQ; lr.CX = 0; /* do not set this to a serial number! 32RTM won't like non-zero values */ @@ -943,6 +953,33 @@ dispatch: lr.AX = lr.CX; break; +#if 0 + case 0x02: + /* get compressed size -> compression not support returns size in clusters */ + /* rc = DosGetClusterCnt((BYTE FAR *) FP_DS_DX); */ + goto error_invalid; +#endif + + case 0xff: /* DOS 7.20 (w98) extended name (128 char length) functions */ + { + switch(lr.CL) + { + /* Dos Create Directory */ + case 0x39: + /* Dos Remove Directory */ + case 0x3a: + rc = DosMkRmdir(FP_DS_DX, lr.AH); + goto short_check; + + /* Dos rename file */ + case 0x56: + rc = DosRename(FP_DS_DX, FP_ES_DI); + goto short_check; + + /* fall through to goto error_invaid */ + } + } + default: goto error_invalid; } diff --git a/kernel/kernel.asm b/kernel/kernel.asm index de80b31..c852ee0 100644 --- a/kernel/kernel.asm +++ b/kernel/kernel.asm @@ -103,7 +103,8 @@ beyond_entry: resb 256-(beyond_entry-entry) segment INIT_TEXT extern _FreeDOSmain - + extern _query_cpu + ; ; kernel start-up ; @@ -189,6 +190,10 @@ cont: ; Now set up call frame ;!! shr al,cl ;!! inc al ;!! mov byte [_NumFloppies],al ; and how many + + call _query_cpu + mov byte [_CPULevel],al + ; TODO display error if built for 386 running on 8086 etc mov ax,ss mov ds,ax @@ -335,11 +340,11 @@ _LoL_nbuffers dw 1 ; 003F number of buffers global _BootDrive _BootDrive db 1 ; 0043 drive we booted from -%IF XCPU < 386 - db 0 ; 0044 cpu type (1 if >=386) -%ELSE - db 1 ; 0044 cpu type (1 if >=386) -%ENDIF + global _CPULevel +_CPULevel db 0 ; 0044 cpu type (MSDOS >0 indicates dword moves ok, ie 386+) + ; unless compatibility issues arise FD uses + ; 0=808x, 1=18x, 2=286, 3=386+ + ; see cpu.asm, use >= as may add checks for 486 ... dw 0 ; 0045 Extended memory in KBytes buf_info: @@ -379,7 +384,6 @@ _os_setver_major db 5 _os_minor db 0 global _os_major _os_major db 5 - global _rev_number _rev_number db 0 global _version_flags _version_flags db 0 diff --git a/kernel/makefile b/kernel/makefile index 935ac8f..ded0245 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -22,7 +22,7 @@ inthndlr.obj OBJS5=ioctl.obj memmgr.obj task.obj newstuff.obj nls.obj network.obj OBJS6=prf.obj misc.obj strings.obj syspack.obj lfnapi.obj iasmsupt.obj memdisk.obj OBJS7=main.obj config.obj initoem.obj inithma.obj dyninit.obj iprf.obj \ -initdisk.obj initclk.obj +initdisk.obj initclk.obj cpu.obj OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS6) $(OBJS7) # *Explicit Rules* @@ -71,6 +71,7 @@ $(TARGET).lnk: turboc.cfg makefile ../mkfiles/generic.mak ../mkfiles/$(COMPILER) apisupt.obj: apisupt.asm segs.inc $(TARGET).lnk asmsupt.obj: asmsupt.asm segs.inc $(TARGET).lnk console.obj: console.asm io.inc $(TARGET).lnk +cpu.obj: cpu.asm segs.inc $(TARGET).lnk dosidle.obj: dosidle.asm segs.inc $(TARGET).lnk entry.obj: entry.asm segs.inc $(HDR)stacks.inc $(TARGET).lnk execrh.obj: execrh.asm segs.inc $(TARGET).lnk diff --git a/kernel/memdisk.asm b/kernel/memdisk.asm index 7de53c0..fb76e64 100644 --- a/kernel/memdisk.asm +++ b/kernel/memdisk.asm @@ -22,7 +22,7 @@ ; ; -%if XCPU == 386 ; requires 386+ registers, until CPU check implemented only allow for 386 builds +; requires 386+ registers, check LoL->CPU >=3 prior to calling (or use 386 build) %include "segs.inc" segment INIT_TEXT @@ -77,5 +77,3 @@ CPU 386 pop di pop es retn - -%endif