diff --git a/ChangeLog b/ChangeLog index b1c06c19..6807255e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,19 @@ - Fixed commandline parsing when .bat files involved (fixes -exit) - Fixed issues with tabs in commandline not being processed correctly - Returned filename in ds:dx in create-random-file (c2woody) + - Cleaned/improved shutdown sequence. + - Fixed a bug with date and time used on open files. + - Added ps2 mouse-emulation in bios interrupts. (c2woody) + - Made our XMS driver conform the specs better. (c2woody) + - Added intelligent mpu401 emulation. (Srecko) + - Changed sensitivity settings of the mouse. + - Fixed a bug with an unterminated string in the drivelabel. + - Changed file search routines a bit to be more compatible. + - Added support for attribute-searching with fcb's + - Changed OpenGL so that it is initialized only when used. + - Added basic SDA. + - Changed psp and dta functions to use dta. + - Added some more PIC commands. (c2woody) 0.61 - Added a beta dynamic cpu for x86 hosts (very unstable) diff --git a/include/dos_inc.h b/include/dos_inc.h index 6724f168..7771d2d4 100644 --- a/include/dos_inc.h +++ b/include/dos_inc.h @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_inc.h,v 1.41 2004-04-18 14:49:48 qbix79 Exp $ */ +/* $Id: dos_inc.h,v 1.42 2004-05-04 18:34:07 qbix79 Exp $ */ #ifndef DOS_H_ #define DOS_H_ @@ -45,27 +45,6 @@ struct DOS_Version { Bit8u major,minor,revision; }; -struct DOS_Block { - DOS_Date date; - DOS_Version version; - Bit16u firstMCB; - Bit16u errorcode; - Bit16u psp; - Bit16u env; - RealPt cpmentry; - RealPt dta; - Bit8u return_code,return_mode; - - Bit8u current_drive; - bool verify; - bool breakcheck; - bool echo; // if set to true dev_con::read will echo input - struct { - RealPt indosflag; - RealPt mediaid; - RealPt tempdta; - } tables; -}; #ifdef _MSC_VER #pragma pack (1) @@ -93,7 +72,7 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3}; #define DOS_DRIVES 26 /* internal Dos Tables */ -extern DOS_Block dos; + extern DOS_File * Files[DOS_FILES]; extern DOS_Drive * Drives[DOS_DRIVES]; extern Bit8u dos_copybuf[0x10000]; @@ -273,8 +252,6 @@ public: void RestoreVectors (void); void SetSize (Bit16u size) { sSave(sPSP,next_seg,size); }; Bit16u GetSize (void) { return sGet(sPSP,next_seg); }; - void SetDTA (RealPt ptdta) { sSave(sPSP,dta,ptdta); }; - RealPt GetDTA (void) { return sGet(sPSP,dta); }; void SetEnvironment (Bit16u envseg) { sSave(sPSP,environment,envseg); }; Bit16u GetEnvironment (void) { return sGet(sPSP,environment); }; Bit16u GetSegment (void) { return seg; }; @@ -312,8 +289,11 @@ private: Bit16u max_files; /* Maximum open files */ RealPt file_table; /* Pointer to File Table PSP:0x18 */ RealPt prev_psp; /* Pointer to previous PSP */ - RealPt dta; /* Pointer to current Process DTA */ - Bit8u fill_2[16]; /* Lot's of unused stuff i can't care aboue */ + Bit8u interim_flag; + Bit8u truename_flag; + Bit16u nn_flags; + Bit16u dos_version; + Bit8u fill_2[14]; /* Lot's of unused stuff i can't care aboue */ Bit8u service[3]; /* INT 0x21 Service call int 0x21;retf; */ Bit8u fill_3[9]; /* This has some blocks with FCB info */ Bit8u fcb1[16]; /* first FCB */ @@ -520,10 +500,77 @@ private: #endif }; -extern DOS_InfoBlock dos_infoblock;; +extern Bit16u sdaseg; +#define DOS_SDA_SEG sdaseg +#define DOS_SDA_OFS 0 + + +class DOS_SDA : public MemStruct { +public: + DOS_SDA(Bit16u _seg,Bit16u _offs) { SetPt(_seg,_offs); } + void Init(); + void SetDrive(Bit8u _drive) { sSave(sSDA,current_drive, _drive); } + void SetDTA(Bit32u _dta) { sSave(sSDA,current_dta, _dta); } + void SetPSP(Bit16u _psp) { sSave(sSDA,current_psp, _psp); } + Bit8u GetDrive(void) { return sGet(sSDA,current_drive); } + Bit16u GetPSP(void) { return sGet(sSDA,current_psp); } + Bit32u GetDTA(void) { return sGet(sSDA,current_dta); } + + +private: + #ifdef _MSC_VER + #pragma pack (1) + #endif + struct sSDA { + Bit8u crit_error_flag; /* 0x00 Critical Error Flag */ + Bit8u inDOS_flag; /* 0x01 InDOS flag (count of active INT 21 calls) */ + Bit8u drive_crit_error; /* 0x02 Drive on which current critical error occurred or FFh */ + Bit8u locus_of_last_error; /* 0x03 locus of last error */ + Bit16u extended_error_code; /* 0x04 extended error code of last error */ + Bit8u suggested_action; /* 0x06 suggested action for last error */ + Bit8u error_class; /* 0x07 class of last error*/ + Bit32u last_error_pointer; /* 0x08 ES:DI pointer for last error */ + Bit32u current_dta; /* 0x0C current DTA (Disk Transfer Address) */ + Bit16u current_psp; /* 0x10 current PSP */ + Bit16u sp_int_23; /* 0x12 stores SP across an INT 23 */ + Bit16u return_code; /* 0x14 return code from last process termination (zerod after reading with AH=4Dh) */ + Bit8u current_drive; /* 0x16 current drive */ + Bit8u extended_break_flag; /* 0x17 extended break flag */ + Bit8u fill[2]; /* 0x18 flag: code page switching || flag: copy of previous byte in case of INT 24 Abort*/ + } GCC_ATTRIBUTE(packed); + #ifdef _MSC_VER + #pragma pack() + #endif +}; +extern DOS_InfoBlock dos_infoblock; + +struct DOS_Block { + DOS_Date date; + DOS_Version version; + Bit16u firstMCB; + Bit16u errorcode; + Bit16u psp(){return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetPSP();}; + void psp(Bit16u _seg){ DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetPSP(_seg);}; + Bit16u env; + RealPt cpmentry; + RealPt dta(){return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetDTA();}; + void dta(RealPt _dta){DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDTA(_dta);}; + Bit8u return_code,return_mode; + + Bit8u current_drive; + bool verify; + bool breakcheck; + bool echo; // if set to true dev_con::read will echo input + struct { + RealPt mediaid; + RealPt tempdta; + } tables; +}; + +extern DOS_Block dos; INLINE Bit8u RealHandle(Bit16u handle) { - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); return psp.GetFileHandle(handle); } diff --git a/src/dos/dos.cpp b/src/dos/dos.cpp index 1782b5ff..3a9928f9 100644 --- a/src/dos/dos.cpp +++ b/src/dos/dos.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos.cpp,v 1.70 2004-03-23 18:24:05 qbix79 Exp $ */ +/* $Id: dos.cpp,v 1.71 2004-05-04 18:34:07 qbix79 Exp $ */ #include #include @@ -45,20 +45,20 @@ void DOS_SetError(Bit16u code) { #define DOSNAMEBUF 256 static Bitu DOS_21Handler(void) { if (((reg_ah != 0x50) && (reg_ah != 0x51) && (reg_ah != 0x62) && (reg_ah != 0x64)) && (reg_ah<0x6c)) { - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); psp.SetStack(RealMake(SegValue(ss),reg_sp-18)); } + char name1[DOSNAMEBUF+1]; char name2[DOSNAMEBUF+1]; switch (reg_ah) { case 0x01: /* Read character from STDIN, with echo */ { Bit8u c;Bit16u n=1; - dos.echo=true; + dos.echo=true; DOS_ReadFile(STDIN,&c,&n); reg_al=c; - dos.echo=false; - + dos.echo=false; } break; case 0x02: /* Write character to STDOUT */ @@ -181,7 +181,7 @@ static Bitu DOS_21Handler(void) { break; case 0x10: /* Close File using FCB */ if(DOS_FCBClose(SegValue(ds),reg_dx)){ - reg_al=0; + reg_al=0; }else{ reg_al=0xff; } @@ -189,7 +189,7 @@ static Bitu DOS_21Handler(void) { break; case 0x11: /* Find First Matching File using FCB */ if(DOS_FCBFindFirst(SegValue(ds),reg_dx)){ - reg_al=0; + reg_al=0; }else{ reg_al=0xff; } @@ -197,7 +197,7 @@ static Bitu DOS_21Handler(void) { break; case 0x12: /* Find Next Matching File using FCB */ if(DOS_FCBFindNext(SegValue(ds),reg_dx)){ - reg_al=0; + reg_al=0; }else{ reg_al=0xff; } @@ -254,29 +254,26 @@ static Bitu DOS_21Handler(void) { LOG(LOG_FCB,LOG_NORMAL)("DOS:0x28 FCB-Random(block) write used, result:al=%d",reg_al); break; case 0x29: /* Parse filename into FCB */ - { Bit8u difference; - char string[1024]; - MEM_StrCopy(SegPhys(ds)+reg_si,string,1024); - reg_al=FCB_Parsename(SegValue(es),reg_di,reg_al ,string, &difference); - reg_si+=difference; - } + { + Bit8u difference; + char string[1024]; + MEM_StrCopy(SegPhys(ds)+reg_si,string,1024); + reg_al=FCB_Parsename(SegValue(es),reg_di,reg_al ,string, &difference); + reg_si+=difference; + } LOG(LOG_FCB,LOG_NORMAL)("DOS:29:FCB Parse Filename, result:al=%d",reg_al); - break; + break; case 0x19: /* Get current default drive */ reg_al=DOS_GetDefaultDrive(); break; case 0x1a: /* Set Disk Transfer Area Address */ - { - dos.dta=RealMakeSeg(ds,reg_dx); - DOS_PSP psp(dos.psp); - psp.SetDTA(dos.dta); - } + dos.dta(RealMakeSeg(ds,reg_dx)); break; case 0x25: /* Set Interrupt Vector */ RealSetVec(reg_al,RealMakeSeg(ds,reg_dx)); break; case 0x26: /* Create new PSP */ - DOS_NewPSP(reg_dx,DOS_PSP(dos.psp).GetSize()); + DOS_NewPSP(reg_dx,DOS_PSP(dos.psp()).GetSize()); break; case 0x2a: /* Get System Date */ { @@ -319,29 +316,43 @@ static Bitu DOS_21Handler(void) { dos.verify=(reg_al==1); break; case 0x2f: /* Get Disk Transfer Area */ - SegSet16(es,RealSeg(dos.dta)); - reg_bx=RealOff(dos.dta); + SegSet16(es,RealSeg(dos.dta())); + reg_bx=RealOff(dos.dta()); break; case 0x30: /* Get DOS Version */ if (reg_al==0) reg_bh=0xFF; /* Fake Microsoft DOS */ if (reg_al==1) reg_bh=0x10; /* DOS is in HMA */ reg_al=dos.version.major; reg_ah=dos.version.minor; + /* Serialnumber */ + reg_bl=0x00; + reg_cx=0x0000; break; case 0x31: /* Terminate and stay resident */ //TODO First get normal files executing // Important: This service does not set the carry flag! - DOS_ResizeMemory(dos.psp,®_dx); + DOS_ResizeMemory(dos.psp(),®_dx); DOS_Terminate(true); - dos.return_code=reg_al; + dos.return_code=reg_al; //Officially a field in the SDA dos.return_mode=RETURN_TSR; break; + case 0x32: /* Get drive parameter block for specific drive */ + { /* Officially a dpb should be returned as well. The disk detection part is implemented */ + Bitu drive=reg_dl;if(!drive) drive=dos.current_drive;else drive--; + if(Drives[drive]) { + reg_al=0x00; + LOG(LOG_DOSMISC,LOG_ERROR)("Get drive parameter block."); + } else { + reg_al=0xff; + } + } + break; case 0x33: /* Extended Break Checking */ switch (reg_al) { case 0:reg_dl=dos.breakcheck;break; /* Get the breakcheck flag */ case 1:dos.breakcheck=(reg_dl>0);break; /* Set the breakcheck flag */ case 2:{bool old=dos.breakcheck;dos.breakcheck=(reg_dl>0);reg_dl=old;}break; - case 5:reg_dl=3;break; /* Always boot from c: :) */ + case 5:reg_dl=3;break;//TODO should be z /* Always boot from c: :) */ case 6: /* Get true version number */ reg_bl=dos.version.major; reg_bh=dos.version.minor; @@ -353,8 +364,8 @@ static Bitu DOS_21Handler(void) { } break; case 0x34: /* Get INDos Flag */ - SegSet16(es,RealSeg(dos.tables.indosflag)); - reg_bx=RealOff(dos.tables.indosflag); + SegSet16(es,DOS_SDA_SEG); + reg_bx=DOS_SDA_OFS + 0x01; break; case 0x35: /* Get interrupt vector */ reg_bx=real_readw(0,((Bit16u)reg_al)*4); @@ -363,8 +374,8 @@ static Bitu DOS_21Handler(void) { case 0x36: /* Get Free Disk Space */ { Bit16u bytes,clusters,free; - Bit8u sectors; - if (DOS_GetFreeDiskSpace(reg_dl,&bytes,§ors,&clusters,&free)) { + Bit8u sectors; + if(DOS_GetFreeDiskSpace(reg_dl,&bytes,§ors,&clusters,&free)) { reg_ax=sectors; reg_bx=free; reg_cx=bytes; @@ -466,7 +477,7 @@ static Bitu DOS_21Handler(void) { case 0x3f: /* READ Read from file or device */ { Bit16u toread=reg_cx; - dos.echo=true; + dos.echo=true; if (DOS_ReadFile(reg_bx,dos_copybuf,&toread)) { MEM_BlockWrite(SegPhys(ds)+reg_dx,dos_copybuf,toread); reg_ax=toread; @@ -475,7 +486,7 @@ static Bitu DOS_21Handler(void) { reg_ax=dos.errorcode; CALLBACK_SCF(true); } - dos.echo=false; + dos.echo=false; break; } case 0x40: /* WRITE Write to file or device */ @@ -621,7 +632,7 @@ static Bitu DOS_21Handler(void) { break; //TODO Check for use of execution state AL=5 case 0x00: - reg_ax=0x4c00; /* Terminate Program */ + reg_ax=0x4c00; /* Terminate Program */ case 0x4c: /* EXIT Terminate with return code */ { @@ -634,7 +645,7 @@ static Bitu DOS_21Handler(void) { break; } case 0x4d: /* Get Return code */ - reg_al=dos.return_code; + reg_al=dos.return_code;/* Officially read from SDA and clear when read */ reg_ah=dos.return_mode; break; case 0x4e: /* FINDFIRST Find first matching file */ @@ -657,10 +668,10 @@ static Bitu DOS_21Handler(void) { }; break; case 0x50: /* Set current PSP */ - dos.psp=reg_bx; + dos.psp(reg_bx); break; case 0x51: /* Get current PSP */ - reg_bx=dos.psp; + reg_bx=dos.psp(); break; case 0x52: { /* Get list of lists */ RealPt addr=dos_infoblock.GetPointer(); @@ -671,14 +682,14 @@ static Bitu DOS_21Handler(void) { //TODO Think hard how shit this is gonna be //And will any game ever use this :) case 0x53: /* Translate BIOS parameter block to drive parameter block */ - E_Exit("Unhandled Dos 21 call %02X",reg_ah); - break; + E_Exit("Unhandled Dos 21 call %02X",reg_ah); + break; case 0x54: /* Get verify flag */ - reg_al=dos.verify?1:0; + reg_al=dos.verify?1:0; break; case 0x55: /* Create Child PSP*/ DOS_ChildPSP(reg_dx,reg_si); - dos.psp = reg_dx; + dos.psp(reg_dx); break; case 0x56: /* RENAME Rename file */ MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF); @@ -764,6 +775,15 @@ static Bitu DOS_21Handler(void) { } break; } + case 0x5d: /* Network Functions */ + if(reg_al == 0x06) { + SegSet16(ds,DOS_SDA_SEG); + reg_si = DOS_SDA_OFS; + reg_cx = 0x80; // swap if in dos + reg_dx = 0x1a; // swap always + LOG(LOG_DOSMISC,LOG_ERROR)("Get SDA, Let's hope for the best!"); + } + break; case 0x5f: /* Network redirection */ reg_ax=0x0001; //Failing it CALLBACK_SCF(true); @@ -779,7 +799,7 @@ static Bitu DOS_21Handler(void) { } break; case 0x62: /* Get Current PSP Address */ - reg_bx=dos.psp; + reg_bx=dos.psp(); break; case 0x64: /* Set device driver lookahead flag */ E_Exit("Unhandled Dos 21 call %02X",reg_ah); @@ -840,7 +860,7 @@ static Bitu DOS_21Handler(void) { case 0x67: /* Set handle count */ /* Weird call to increase amount of file handles needs to allocate memory if >20 */ { - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); psp.SetNumFiles(reg_bx); CALLBACK_SCF(false); break; @@ -873,6 +893,7 @@ static Bitu DOS_21Handler(void) { CALLBACK_SCF(true); LOG(LOG_DOSMISC,LOG_NORMAL)("DOS:Windows long file name support call %2X",reg_al); break; + case 0x68: /* FFLUSH Commit file */ case 0x63: /* Weirdo double byte stuff (fails but say it succeeded) available only in MSDOS 2.25 */ CALLBACK_SCF(false); //mirek @@ -884,10 +905,8 @@ static Bitu DOS_21Handler(void) { case 0x6b: /* NULL Function */ case 0x61: /* UNUSED */ case 0xEF: /* Used in Ancient Art Of War CGA */ - case 0x5d: /* Network Functions ||HMMM seems to critical error info and return 1!! Maybe implement it.??*/ - /* al=06 clears cf and leaves al=6 and returns crit error flag location*/ case 0x1f: /* Get drive parameter block for default drive */ - case 0x32: /* Get drive parameter block for specific drive */ + case 0x5c: /* FLOCK File region locking */ case 0x5e: /* More Network Functions */ default: @@ -912,7 +931,7 @@ static Bitu DOS_27Handler(void) { // Terminate & stay resident Bit16u para = (reg_dx/16)+((reg_dx % 16)>0); - if (DOS_ResizeMemory(dos.psp,¶)) DOS_Terminate(true); + if (DOS_ResizeMemory(dos.psp(),¶)) DOS_Terminate(true); return CBRET_NONE; } static Bitu DOS_25Handler(void) { @@ -921,9 +940,10 @@ static Bitu DOS_25Handler(void) { SETFLAGBIT(CF,true); }else{ SETFLAGBIT(CF,false); - reg_ax=0; if((reg_cx != 1) ||(reg_dx != 1)) - LOG(LOG_DOSMISC,LOG_NORMAL)("int 25 called but not as diskdetection"); + LOG(LOG_DOSMISC,LOG_NORMAL)("int 25 called but not as diskdetection drive %X",reg_al); + + reg_ax=0; } return CBRET_NONE; } diff --git a/src/dos/dos_classes.cpp b/src/dos/dos_classes.cpp index 38b79d28..733b4dc5 100644 --- a/src/dos/dos_classes.cpp +++ b/src/dos/dos_classes.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_classes.cpp,v 1.36 2004-04-18 14:49:48 qbix79 Exp $ */ +/* $Id: dos_classes.cpp,v 1.37 2004-05-04 18:34:08 qbix79 Exp $ */ #include #include @@ -119,7 +119,7 @@ Bit16u DOS_PSP::rootpsp = 0; void DOS_PSP::MakeNew(Bit16u mem_size) { /* get previous */ - DOS_PSP prevpsp(dos.psp); + DOS_PSP prevpsp(dos.psp()); /* Clear it first */ Bitu i; for (i=0;i #include @@ -95,7 +95,7 @@ static void RestoreRegisters(void) { extern void GFX_SetTitle(Bits cycles,Bits frameskip); void DOS_UpdatePSPName(void) { - DOS_MCB mcb(dos.psp-1); + DOS_MCB mcb(dos.psp()-1); static char name[9]; mcb.GetFileName(name); if (!strlen(name)) strcpy(name,"DOSBOX"); @@ -108,10 +108,10 @@ bool DOS_Terminate(bool tsr) { dos.return_code=reg_al; dos.return_mode=RETURN_EXIT; - Bit16u mempsp = dos.psp; + Bit16u mempsp = dos.psp(); - DOS_PSP curpsp(dos.psp); - if (dos.psp==curpsp.GetParent()) return true; + DOS_PSP curpsp(mempsp); + if (mempsp==curpsp.GetParent()) return true; /* Free Files owned by process */ if (!tsr) curpsp.CloseFiles(); @@ -120,10 +120,9 @@ bool DOS_Terminate(bool tsr) { /* Restore vector 22,23,24 */ curpsp.RestoreVectors(); /* Set the parent PSP */ - dos.psp = curpsp.GetParent(); + dos.psp(curpsp.GetParent()); DOS_PSP parentpsp(curpsp.GetParent()); - /* Restore the DTA of the parent psp */ - dos.dta = parentpsp.GetDTA(); + /* Restore the SS:SP to the previous one */ SegSet16(ss,RealSeg(parentpsp.GetStack())); reg_sp = RealOff(parentpsp.GetStack()); @@ -141,7 +140,7 @@ bool DOS_Terminate(bool tsr) { static bool MakeEnv(char * name,Bit16u * segment) { /* If segment to copy environment is 0 copy the caller's environment */ - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); PhysPt envread,envwrite; Bit16u envsize=1; bool parentenv=true; @@ -211,27 +210,11 @@ static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) { DOS_PSP psp(pspseg); psp.MakeNew(memsize); psp.SetEnvironment(envseg); - /* Copy file handles //QBIX::ALWAYS COPY BUT LEFT ORIGINAL INCASE OF MISTAKES -/* if (DOS_PSP::rootpsp!=dos.psp) { */ - // TODO: Improve this - // If prog wasnt started from commandline copy file table (California Games 2) -/* DOS_PSP oldpsp(dos.psp); - psp.CopyFileTable(&oldpsp); - } else { - psp.SetFileHandle(STDIN ,DOS_FindDevice("CON")); - psp.SetFileHandle(STDOUT,DOS_FindDevice("CON")); - psp.SetFileHandle(STDERR,DOS_FindDevice("CON")); - psp.SetFileHandle(STDAUX,DOS_FindDevice("CON")); - psp.SetFileHandle(STDNUL,DOS_FindDevice("CON")); - psp.SetFileHandle(STDPRN,DOS_FindDevice("CON")); - } */ - /* Save old DTA in psp */ - DOS_PSP oldpsp(dos.psp); - psp.CopyFileTable(&oldpsp,true); - psp.SetDTA(dos.dta); - /* Setup the DTA */ - dos.dta=RealMake(pspseg,0x80); + /* Copy file handles */ + DOS_PSP oldpsp(dos.psp()); + psp.CopyFileTable(&oldpsp,true); + } static void SetupCMDLine(Bit16u pspseg,DOS_ParamBlock & block) { @@ -311,12 +294,13 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { /* Load the executable */ Bit8u * loadbuf=(Bit8u *)new Bit8u[0x10000]; loadaddress=PhysMake(loadseg,0); + if (iscom) { /* COM Load 64k - 256 bytes max */ pos=0;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET); readsize=0xffff-256; DOS_ReadFile(fhandle,loadbuf,&readsize); MEM_BlockWrite(loadaddress,loadbuf,readsize); - } else { /* EXE Load in 32kb blocks and then relocate */ + } else { /* EXE Load in 32kb blocks and then relocate */ pos=headersize;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET); while (imagesize>0x7FFF) { readsize=0x8000;DOS_ReadFile(fhandle,loadbuf,&readsize); @@ -350,7 +334,6 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { SetupPSP(pspseg,memsize,envseg); SetupCMDLine(pspseg,block); }; - CALLBACK_SCF(false); /* Carry flag cleared for caller if successfull */ if (flags==OVERLAY) return true; /* Everything done for overlays */ RealPt csip,sssp; @@ -364,12 +347,13 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { } if (flags==LOAD) { - DOS_PSP callpsp(dos.psp); + DOS_PSP callpsp(dos.psp()); /* Save the SS:SP on the PSP of calling program */ callpsp.SetStack(RealMakeSeg(ss,reg_sp)); /* Switch the psp's */ - dos.psp=pspseg; - + dos.psp(pspseg); + DOS_PSP newpsp(dos.psp()); + dos.dta(RealMake(newpsp.GetSegment(),0x80)); block.exec.initsssp = sssp; block.exec.initcsip = csip; block.SaveData(); @@ -380,14 +364,13 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { /* Get Caller's program CS:IP of the stack and set termination address to that */ RealSetVec(0x22,RealMake(mem_readw(SegPhys(ss)+reg_sp+2),mem_readw(SegPhys(ss)+reg_sp))); SaveRegisters(); - DOS_PSP callpsp(dos.psp); + DOS_PSP callpsp(dos.psp()); /* Save the SS:SP on the PSP of calling program */ callpsp.SetStack(RealMakeSeg(ss,reg_sp)); /* Switch the psp's and set new DTA */ - dos.psp=pspseg; - DOS_PSP newpsp(dos.psp); - newpsp.SetDTA(dos.dta); /* Original: change this and line below. This way seems better(zone66 and unpack) */ - //dos.dta=newpsp.GetDTA(); + dos.psp(pspseg); + DOS_PSP newpsp(dos.psp()); + dos.dta(RealMake(newpsp.GetSegment(),0x80)); /* save vectors */ newpsp.SaveVectors(); /* copy fcbs */ @@ -423,7 +406,7 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) { index++; } memset(&stripname[index],0,8-index); - DOS_MCB pspmcb(dos.psp-1); + DOS_MCB pspmcb(dos.psp()-1); pspmcb.SetFileName(stripname); DOS_UpdatePSPName(); return true; diff --git a/src/dos/dos_files.cpp b/src/dos/dos_files.cpp index 6b3ad232..9f4d74a0 100644 --- a/src/dos/dos_files.cpp +++ b/src/dos/dos_files.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_files.cpp,v 1.55 2004-04-18 14:49:48 qbix79 Exp $ */ +/* $Id: dos_files.cpp,v 1.56 2004-05-04 18:34:08 qbix79 Exp $ */ #include #include @@ -218,7 +218,7 @@ bool DOS_Rename(char * oldname,char * newname) { } bool DOS_FindFirst(char * search,Bit16u attr,bool fcb_findfirst) { - DOS_DTA dta(dos.dta); + DOS_DTA dta(dos.dta()); Bit8u drive;char fullsearch[DOS_PATHLENGTH]; char dir[DOS_PATHLENGTH];char pattern[DOS_PATHLENGTH]; if (!DOS_MakeName(search,fullsearch,&drive)) return false; @@ -240,7 +240,7 @@ bool DOS_FindFirst(char * search,Bit16u attr,bool fcb_findfirst) { } bool DOS_FindNext(void) { - DOS_DTA dta(dos.dta); + DOS_DTA dta(dos.dta()); if (Drives[dta.GetSearchDrive()]->FindNext(dta)) return true; return false; } @@ -318,7 +318,7 @@ bool DOS_CloseFile(Bit16u entry) { /* Devices won't allow themselves to be closed or killed */ if (Files[handle]->Close()) { //if close succesfull => delete file/update psp - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); psp.SetFileHandle(entry,0xff); if (Files[handle]->RemoveRef()<=0) { delete Files[handle]; @@ -335,7 +335,7 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) { return DOS_OpenFile(name, 0, entry); char fullname[DOS_PATHLENGTH];Bit8u drive; - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); if (!DOS_MakeName(name,fullname,&drive)) return false; /* Check for a free file handle */ Bit8u handle=DOS_FILES;Bit8u i; @@ -378,7 +378,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) { } } - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); Bit8u handle=DOS_FindDevice((char *)name); bool device=false;char fullname[DOS_PATHLENGTH];Bit8u drive;Bit8u i; if (handle!=255) { @@ -519,7 +519,7 @@ bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry) { DOS_SetError(DOSERR_INVALID_HANDLE); return false; }; - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); *newentry = psp.FindFreeFileEntry(); if (*newentry==0xff) { DOS_SetError(DOSERR_TOO_MANY_OPEN_FILES); @@ -556,7 +556,7 @@ bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry) { DOS_CloseFile(newentry); return false; }; - DOS_PSP psp(dos.psp); + DOS_PSP psp(dos.psp()); Files[orig]->AddRef(); psp.SetFileHandle(newentry,(Bit8u)entry); return true; @@ -719,7 +719,7 @@ static void SaveFindResult(DOS_FCB & find_fcb) { drive=find_fcb.GetDrive()+1; /* Create a correct file and extention */ DTAExtendName(name,file_name,ext); - DOS_FCB fcb(RealSeg(dos.dta),RealOff(dos.dta)); + DOS_FCB fcb(RealSeg(dos.dta()),RealOff(dos.dta()));//TODO fcb.Create(find_fcb.Extended()); fcb.SetName(drive,file_name,ext); fcb.SetAttr(attr); /* Only adds attribute if fcb is extended */ @@ -747,7 +747,7 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) { /* Check, if file is already opened */ for (Bit8u i=0;iIsOpen() && Files[i]->IsName(fullname)) { handle = psp.FindEntryByHandle(i); if (handle==0xFF) { @@ -773,25 +773,23 @@ bool DOS_FCBClose(Bit16u seg,Bit16u offset) { return true; } -bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset) -{ +bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); - RealPt old_dta=dos.dta;dos.dta=dos.tables.tempdta; + RealPt old_dta=dos.dta();dos.dta(dos.tables.tempdta); char name[DOS_FCBNAME];fcb.GetName(name); Bit8u attr = DOS_ATTR_ARCHIVE; fcb.GetAttr(attr); /* Gets search attributes if extended */ bool ret=DOS_FindFirst(name,attr,true); - dos.dta=old_dta; + dos.dta(old_dta); if (ret) SaveFindResult(fcb); return ret; } -bool DOS_FCBFindNext(Bit16u seg,Bit16u offset) -{ +bool DOS_FCBFindNext(Bit16u seg,Bit16u offset) { DOS_FCB fcb(seg,offset); - RealPt old_dta=dos.dta;dos.dta=dos.tables.tempdta; + RealPt old_dta=dos.dta();dos.dta(dos.tables.tempdta); bool ret=DOS_FindNext(); - dos.dta=old_dta; + dos.dta(old_dta); if (ret) SaveFindResult(fcb); return ret; } @@ -807,11 +805,11 @@ Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset,Bit16u recno) { if (!DOS_ReadFile(fhandle,dos_copybuf,&toread)) return FCB_READ_NODATA; if (toread==0) return FCB_READ_NODATA; if (toread0;i--) mem_writeb(fill++,0); } - MEM_BlockWrite(Real2Phys(dos.dta)+recno*rec_size,dos_copybuf,rec_size); + MEM_BlockWrite(Real2Phys(dos.dta())+recno*rec_size,dos_copybuf,rec_size); if (++cur_rec>127) { cur_block++;cur_rec=0; } fcb.SetRecord(cur_block,cur_rec); if (toread==rec_size) return FCB_SUCCESS; @@ -827,7 +825,7 @@ Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno) fcb.GetRecord(cur_block,cur_rec); Bit32u pos=((cur_block*128)+cur_rec)*rec_size; if (!DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET)) return FCB_ERR_WRITE; - MEM_BlockRead(Real2Phys(dos.dta)+recno*rec_size,dos_copybuf,rec_size); + MEM_BlockRead(Real2Phys(dos.dta())+recno*rec_size,dos_copybuf,rec_size); Bit16u towrite=rec_size; if (!DOS_WriteFile(fhandle,dos_copybuf,&towrite)) return FCB_ERR_WRITE; Bit32u size;Bit16u date,time; @@ -863,7 +861,7 @@ Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore) { /* Set the correct record from the random data */ fcb.GetRandom(random); fcb.SetRecord((Bit16u)(random / 128),(Bit8u)(random & 127)); - if (restore) fcb.GetRecord(old_block,old_rec);//store this for after the read. + if (restore) fcb.GetRecord(old_block,old_rec);//store this for after the read. // Read records for (int i=0; i #include @@ -46,7 +46,7 @@ public: // Show list of cdroms if (cmd->FindExist("-cd",false)) { int num = SDL_CDNumDrives(); - WriteOut("CDROMs found: %d\n",num); + WriteOut(MSG_Get("PROGRAM_MOUNT_CDROMS_FOUND"),num); for (int i=0; iGetMediaByte()); - WriteOut("Drive %c mounted as %s\n",drive,newdrive->GetInfo()); + WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),drive,newdrive->GetInfo()); /* check if volume label is given */ if (cmd->FindString("-label",label,true)) newdrive->dirCache.SetLabel(label.c_str()); return; @@ -443,6 +443,8 @@ static void INTRO_ProgramStart(Program * * make) { void DOS_SetupPrograms(void) { /*Add Messages */ + + MSG_Add("PROGRAM_MOUNT_CDROMS_FOUND","CDROMs found: %d\n"); MSG_Add("PROGRAM_MOUNT_STATUS_2","Drive %c is mounted as %s\n"); MSG_Add("PROGRAM_MOUNT_STATUS_1","Current mounted drives are:\n"); MSG_Add("PROGRAM_MOUNT_ERROR_1","Directory %s doesn't exist.\n"); diff --git a/src/dos/dos_tables.cpp b/src/dos/dos_tables.cpp index 30122508..d54c3139 100644 --- a/src/dos/dos_tables.cpp +++ b/src/dos/dos_tables.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: dos_tables.cpp,v 1.9 2004-03-23 18:51:21 qbix79 Exp $ */ +/* $Id: dos_tables.cpp,v 1.10 2004-05-04 18:34:08 qbix79 Exp $ */ #include "dosbox.h" #include "mem.h" @@ -38,6 +38,8 @@ RealPt DOS_TableUpCase; RealPt DOS_TableLowCase; static Bit16u dos_memseg; +Bit16u sdaseg; + Bit16u DOS_GetMemory(Bit16u pages) { if (pages+dos_memseg>=0xe000) { E_Exit("DOS:Not enough memory for internal tables"); @@ -54,9 +56,6 @@ void DOS_SetupTables(void) { dos.tables.mediaid=RealMake(DOS_GetMemory(2),0); dos.tables.tempdta=RealMake(DOS_GetMemory(4),0); for (i=0;i @@ -44,6 +44,7 @@ struct PIC_Controller { Bitu active; Bitu inservice; + bool special; bool auto_eoi; bool request_issr; Bit8u vector_base; @@ -103,6 +104,11 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { } } //TODO Warnings? break; + case 0x4a: /* OCW3 select read interrupt request register */ + LOG(LOG_PIC,LOG_NORMAL)("port %X : special OFF",port); + pic->special = false; + pic->request_issr = false; + break; case 0x60:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67: /* Spefific EOI 0-7 */ if (PIC_IRQActive==(irq_base+val-0x60U)) { @@ -117,6 +123,15 @@ static void write_command(Bitu port,Bitu val,Bitu iolen) { } }//TODO Warnings? break; + case 0x68:/* OCW3 select */ + pic->special=true; + LOG(LOG_PIC,LOG_NORMAL)("port %X : special ON",port); + break; + case 0x6b: /* OCW3 select read interrupt in-service register */ + LOG(LOG_PIC,LOG_NORMAL)("port %X : special ON",port); + pic->special = true; + pic->request_issr = true; + break; case 0xC0:case 0xC1:case 0xC2:case 0xC3:case 0xC4:case 0xC5:case 0xC6:case 0xC7: /* Priority order, no need for it */ break; @@ -244,7 +259,7 @@ void PIC_runIRQs(void) { Bit16u activeIRQ = PIC_IRQActive; if (activeIRQ==PIC_NOIRQ) activeIRQ = 16; for (i=0;i<=15;i++) { - if (IRQ_priority_lookup[i] #include @@ -65,7 +65,7 @@ static Bitu PROGRAMS_Handler(void) { PROGRAMS_Main * handler=0; //It will get sneakily itinialized Bitu size=sizeof(PROGRAMS_Main *); /* Read the handler from program code in memory */ - PhysPt reader=PhysMake(dos.psp,256+sizeof(exe_block)); + PhysPt reader=PhysMake(dos.psp(),256+sizeof(exe_block)); HostPt writer=(HostPt)&handler; for (;size>0;size--) *writer++=mem_readb(reader++); Program * new_program; @@ -81,13 +81,13 @@ static Bitu PROGRAMS_Handler(void) { Program::Program() { /* Find the command line and setup the PSP */ - psp = new DOS_PSP(dos.psp); + psp = new DOS_PSP(dos.psp()); /* Scan environment for filename */ PhysPt envscan=PhysMake(psp->GetEnvironment(),0); while (mem_readb(envscan)) envscan+=mem_strlen(envscan)+1; envscan+=3; CommandTail tail; - MEM_BlockRead(PhysMake(dos.psp,128),&tail,128); + MEM_BlockRead(PhysMake(dos.psp(),128),&tail,128); if (tail.count<127) tail.buffer[tail.count]=0; else tail.buffer[126]=0; char filename[256]; diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index fdf828fd..e9789547 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell.cpp,v 1.40 2004-02-19 12:00:38 qbix79 Exp $ */ +/* $Id: shell.cpp,v 1.41 2004-05-04 18:34:08 qbix79 Exp $ */ #include #include @@ -376,8 +376,9 @@ void SHELL_Init() { strcpy(tail.buffer,init_line); MEM_BlockWrite(PhysMake(psp_seg,128),&tail,128); /* Setup internal DOS Variables */ - dos.dta=psp.GetDTA(); - dos.psp=psp_seg; + + dos.dta(RealMake(psp_seg,0x80)); + dos.psp(psp_seg); Program * new_program; SHELL_ProgramStart(&new_program); diff --git a/src/shell/shell_batch.cpp b/src/shell/shell_batch.cpp index 4642a2b7..a506e676 100644 --- a/src/shell/shell_batch.cpp +++ b/src/shell/shell_batch.cpp @@ -16,6 +16,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $Id: shell_batch.cpp,v 1.13 2004-05-04 18:34:08 qbix79 Exp $ */ + #include #include diff --git a/src/shell/shell_cmds.cpp b/src/shell/shell_cmds.cpp index a9eb3f9b..7294c7bf 100644 --- a/src/shell/shell_cmds.cpp +++ b/src/shell/shell_cmds.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_cmds.cpp,v 1.40 2004-04-01 13:00:05 qbix79 Exp $ */ +/* $Id: shell_cmds.cpp,v 1.41 2004-05-04 18:34:08 qbix79 Exp $ */ #include @@ -121,7 +121,7 @@ void DOS_Shell::CMD_DELETE(char * args) { //end can't be 0, but if it is we'll get a nice crash, who cares :) char * end=strrchr(full,'\\')+1;*end=0; char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u time,date;Bit8u attr; - DOS_DTA dta(dos.dta); + DOS_DTA dta(dos.dta()); while (res) { dta.GetResult(name,size,date,time,attr); if (!(attr & (DOS_ATTR_DIRECTORY|DOS_ATTR_READ_ONLY))) { @@ -286,7 +286,7 @@ void DOS_Shell::CMD_DIR(char * args) { *(strrchr(path,'\\')+1)=0; WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),path); - DOS_DTA dta(dos.dta); + DOS_DTA dta(dos.dta()); bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME); if (!ret) { WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args); @@ -359,7 +359,7 @@ void DOS_Shell::CMD_DIR(char * args) { void DOS_Shell::CMD_COPY(char * args) { StripSpaces(args); - DOS_DTA dta(dos.dta); + DOS_DTA dta(dos.dta()); Bit32u size;Bit16u date;Bit16u time;Bit8u attr; char name[DOS_NAMELENGTH_ASCII]; diff --git a/src/shell/shell_misc.cpp b/src/shell/shell_misc.cpp index efefd63b..b890e9ca 100644 --- a/src/shell/shell_misc.cpp +++ b/src/shell/shell_misc.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: shell_misc.cpp,v 1.28 2004-01-10 14:03:36 qbix79 Exp $ */ +/* $Id: shell_misc.cpp,v 1.29 2004-05-04 18:34:08 qbix79 Exp $ */ #include #include @@ -196,7 +196,7 @@ void DOS_Shell::InputCommand(char * line) { bool res = DOS_FindFirst(mask, 0xffff & ~DOS_ATTR_VOLUME); if (!res) break; // TODO: beep - DOS_DTA dta(dos.dta); + DOS_DTA dta(dos.dta()); char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr; while (res) { @@ -369,10 +369,10 @@ void DOS_Shell::Execute(char * name,char * args) { MEM_BlockWrite(SegPhys(ss)+reg_sp+0x100,&cmd,128); /* Parse FCB (first two parameters) and put them into the current DOS_PSP */ Bit8u add; - FCB_Parsename(dos.psp,0x5C,0x00,cmd.buffer,&add); - FCB_Parsename(dos.psp,0x6C,0x00,&cmd.buffer[add],&add); - block.exec.fcb1=RealMake(dos.psp,0x5C); - block.exec.fcb2=RealMake(dos.psp,0x6C); + FCB_Parsename(dos.psp(),0x5C,0x00,cmd.buffer,&add); + FCB_Parsename(dos.psp(),0x6C,0x00,&cmd.buffer[add],&add); + block.exec.fcb1=RealMake(dos.psp(),0x5C); + block.exec.fcb2=RealMake(dos.psp(),0x6C); /* Set the command line in the block and save it */ block.exec.cmdtail=RealMakeSeg(ss,reg_sp+0x100); block.SaveData();