- Add midnight/next day increment
- Add date and time commands (functionality limited) Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3715
This commit is contained in:
parent
1887b2590b
commit
a5ee614503
5 changed files with 218 additions and 26 deletions
|
@ -87,6 +87,8 @@ public:
|
|||
void CMD_HELP(char * args);
|
||||
void CMD_CLS(char * args);
|
||||
void CMD_COPY(char * args);
|
||||
void CMD_DATE(char * args);
|
||||
void CMD_TIME(char * args);
|
||||
void CMD_DIR(char * args);
|
||||
void CMD_DELETE(char * args);
|
||||
void CMD_ECHO(char * args);
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include "dosbox.h"
|
||||
#include "bios.h"
|
||||
#include "mem.h"
|
||||
|
@ -41,6 +40,34 @@ void DOS_SetError(Bit16u code) {
|
|||
dos.errorcode=code;
|
||||
}
|
||||
|
||||
const Bit8u DOS_DATE_months[] = {
|
||||
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
||||
};
|
||||
|
||||
static void DOS_AddDays(Bitu days) {
|
||||
dos.date.day += days;
|
||||
Bit8u monthlimit = DOS_DATE_months[dos.date.month];
|
||||
|
||||
if(dos.date.day > monthlimit) {
|
||||
if((dos.date.year %4 == 0) && (dos.date.month==2)) {
|
||||
// leap year
|
||||
if(dos.date.day > 29) {
|
||||
dos.date.month++;
|
||||
dos.date.day -= 29;
|
||||
}
|
||||
} else {
|
||||
//not leap year
|
||||
dos.date.month++;
|
||||
dos.date.day -= monthlimit;
|
||||
}
|
||||
if(dos.date.month > 12) {
|
||||
// year over
|
||||
dos.date.month = 1;
|
||||
dos.date.year++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define DATA_TRANSFERS_TAKE_CYCLES 1
|
||||
#ifdef DATA_TRANSFERS_TAKE_CYCLES
|
||||
|
||||
|
@ -373,6 +400,9 @@ static Bitu DOS_21Handler(void) {
|
|||
break;
|
||||
case 0x2a: /* Get System Date */
|
||||
{
|
||||
reg_ax=0; // get time
|
||||
CALLBACK_RunRealInt(0x1a);
|
||||
if(reg_al) DOS_AddDays(reg_al);
|
||||
int a = (14 - dos.date.month)/12;
|
||||
int y = dos.date.year - a;
|
||||
int m = dos.date.month + 12*a - 2;
|
||||
|
@ -385,28 +415,37 @@ static Bitu DOS_21Handler(void) {
|
|||
case 0x2b: /* Set System Date */
|
||||
if (reg_cx<1980) { reg_al=0xff;break;}
|
||||
if ((reg_dh>12) || (reg_dh==0)) { reg_al=0xff;break;}
|
||||
if ((reg_dl>31) || (reg_dl==0)) { reg_al=0xff;break;}
|
||||
if (reg_dl==0) { reg_al=0xff;break;}
|
||||
if (reg_dl>DOS_DATE_months[reg_dh]) {
|
||||
if(!((reg_dh==2)&&(reg_cx%4 == 0)&&(reg_dl==29))) // february pass
|
||||
{ reg_al=0xff;break; }
|
||||
}
|
||||
dos.date.year=reg_cx;
|
||||
dos.date.month=reg_dh;
|
||||
dos.date.day=reg_dl;
|
||||
reg_al=0;
|
||||
break;
|
||||
case 0x2c: /* Get System Time */
|
||||
//TODO Get time through bios calls date is fixed
|
||||
{
|
||||
/* Calculate how many miliseconds have passed */
|
||||
Bitu ticks=5*(mem_readd(BIOS_TIMER) - time_start);
|
||||
ticks = ((ticks / 59659u) << 16) + ((ticks % 59659u) << 16) / 59659u;
|
||||
Bitu seconds=(ticks/100);
|
||||
reg_ch=(Bit8u)(seconds/3600);
|
||||
reg_cl=(Bit8u)((seconds % 3600)/60);
|
||||
reg_dh=(Bit8u)(seconds % 60);
|
||||
reg_dl=(Bit8u)(ticks % 100);
|
||||
}
|
||||
case 0x2c: { /* Get System Time */
|
||||
reg_ax=0; // get time
|
||||
CALLBACK_RunRealInt(0x1a);
|
||||
if(reg_al) DOS_AddDays(reg_al);
|
||||
|
||||
Bitu time=((Bitu)reg_cx<<16)|reg_dx;
|
||||
Bitu ticks=(Bitu)(5.49254945 * (double)time);
|
||||
|
||||
reg_dl=(Bit8u)((Bitu)ticks % 100); // 1/100 seconds
|
||||
ticks/=100;
|
||||
reg_dh=(Bit8u)((Bitu)ticks % 60); // seconds
|
||||
ticks/=60;
|
||||
reg_cl=(Bit8u)((Bitu)ticks % 60); // minutes
|
||||
ticks/=60;
|
||||
reg_ch=(Bit8u)((Bitu)ticks % 24); // hours
|
||||
|
||||
//Simulate DOS overhead for timing-sensitive games
|
||||
//Robomaze 2
|
||||
//Robomaze 2
|
||||
overhead();
|
||||
break;
|
||||
}
|
||||
case 0x2d: /* Set System Time */
|
||||
LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Set System Time not supported");
|
||||
//Check input parameters nonetheless
|
||||
|
@ -1188,16 +1227,6 @@ public:
|
|||
|
||||
dos.version.major=5;
|
||||
dos.version.minor=0;
|
||||
|
||||
/* Setup time and date */
|
||||
time_t curtime;struct tm *loctime;
|
||||
curtime = time (NULL);loctime = localtime (&curtime);
|
||||
|
||||
dos.date.day=(Bit8u)loctime->tm_mday;
|
||||
dos.date.month=(Bit8u)loctime->tm_mon+1;
|
||||
dos.date.year=(Bit16u)loctime->tm_year+1900;
|
||||
Bit32u ticks=(Bit32u)((loctime->tm_hour*3600+loctime->tm_min*60+loctime->tm_sec)*(float)PIT_TICK_RATE/65536.0);
|
||||
mem_writed(BIOS_TIMER,ticks);
|
||||
}
|
||||
~DOS(){
|
||||
for (Bit16u i=0;i<DOS_DRIVES;i++) delete Drives[i];
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#include "mouse.h"
|
||||
#include "setup.h"
|
||||
#include "serialport.h"
|
||||
#include <time.h>
|
||||
#include <sys/timeb.h>
|
||||
|
||||
|
||||
/* if mem_systems 0 then size_extended is reported as the real size else
|
||||
|
@ -311,7 +313,8 @@ static Bitu INT1A_Handler(void) {
|
|||
case 0x00: /* Get System time */
|
||||
{
|
||||
Bit32u ticks=mem_readd(BIOS_TIMER);
|
||||
reg_al=0; /* Midnight never passes :) */
|
||||
reg_al=mem_readb(BIOS_24_HOURS_FLAG);
|
||||
mem_writeb(BIOS_24_HOURS_FLAG,0); // reset the "flag"
|
||||
reg_cx=(Bit16u)(ticks >> 16);
|
||||
reg_dx=(Bit16u)(ticks & 0xffff);
|
||||
break;
|
||||
|
@ -371,9 +374,45 @@ static Bitu INT11_Handler(void) {
|
|||
#ifndef DOSBOX_CLOCKSYNC
|
||||
#define DOSBOX_CLOCKSYNC 0
|
||||
#endif
|
||||
|
||||
static void BIOS_HostTimeSync() {
|
||||
/* Setup time and date */
|
||||
struct timeb timebuffer;
|
||||
ftime(&timebuffer);
|
||||
|
||||
struct tm *loctime;
|
||||
loctime = localtime (&timebuffer.time);
|
||||
|
||||
/*
|
||||
loctime->tm_hour = 23;
|
||||
loctime->tm_min = 59;
|
||||
loctime->tm_sec = 45;
|
||||
loctime->tm_mday = 28;
|
||||
loctime->tm_mon = 2-1;
|
||||
loctime->tm_year = 2007 - 1900;
|
||||
*/
|
||||
|
||||
dos.date.day=(Bit8u)loctime->tm_mday;
|
||||
dos.date.month=(Bit8u)loctime->tm_mon+1;
|
||||
dos.date.year=(Bit16u)loctime->tm_year+1900;
|
||||
|
||||
Bit32u ticks=(Bit32u)(((double)(
|
||||
loctime->tm_hour*3600*1000+
|
||||
loctime->tm_min*60*1000+
|
||||
loctime->tm_sec*1000+
|
||||
timebuffer.millitm))*(((double)PIT_TICK_RATE/65536.0)/1000.0));
|
||||
mem_writed(BIOS_TIMER,ticks);
|
||||
}
|
||||
|
||||
static Bitu INT8_Handler(void) {
|
||||
/* Increase the bios tick counter */
|
||||
Bit32u value = mem_readd(BIOS_TIMER) + 1;
|
||||
if(value >= 0x1800B0) {
|
||||
// time wrap at midnight
|
||||
mem_writeb(BIOS_24_HOURS_FLAG,mem_readb(BIOS_24_HOURS_FLAG)+1);
|
||||
value=0;
|
||||
}
|
||||
|
||||
#if DOSBOX_CLOCKSYNC
|
||||
static bool check = false;
|
||||
if((value %50)==0) {
|
||||
|
@ -1079,6 +1118,7 @@ public:
|
|||
size_extended=IO_Read(0x71);
|
||||
IO_Write(0x70,0x31);
|
||||
size_extended|=(IO_Read(0x71) << 8);
|
||||
BIOS_HostTimeSync();
|
||||
}
|
||||
~BIOS(){
|
||||
/* abort DAC playing */
|
||||
|
|
|
@ -464,6 +464,23 @@ void SHELL_Init() {
|
|||
MSG_Add("SHELL_CMD_CHDIR_HINT","To change to different drive type \033[31m%c:\033[0m\n");
|
||||
MSG_Add("SHELL_CMD_CHDIR_HINT_2","directoryname is longer than 8 characters and/or contains spaces.\nTry \033[31mcd %s\033[0m\n");
|
||||
MSG_Add("SHELL_CMD_CHDIR_HINT_3","You are still on drive Z:, change to a mounted drive with \033[31mC:\033[0m.\n");
|
||||
MSG_Add("SHELL_CMD_DATE_HELP","Displays or changes the internal date.\n");
|
||||
MSG_Add("SHELL_CMD_DATE_ERROR","The specified date is not correct.\n");
|
||||
MSG_Add("SHELL_CMD_DATE_DAYS","3SunMonTueWedThuFriSat"); // "2SoMoDiMiDoFrSa"
|
||||
MSG_Add("SHELL_CMD_DATE_NOW","Current date: ");
|
||||
MSG_Add("SHELL_CMD_DATE_SETHLP","Type 'date MM-DD-YYYY' to change.\n");
|
||||
MSG_Add("SHELL_CMD_DATE_FORMAT","M/D/Y");
|
||||
MSG_Add("SHELL_CMD_DATE_HELP_LONG","DATE [[/T] [/H] [/S] | MM-DD-YYYY]\n"\
|
||||
" MM-DD-YYYY: new date to set\n"\
|
||||
" /S: Permanently use host time and date as DOS time\n"\
|
||||
" /F: Switch back to DOSBox internal time (opposite of /S)\n"\
|
||||
" /T: Only display date\n"\
|
||||
" /H: Synchronize with host\n");
|
||||
MSG_Add("SHELL_CMD_TIME_HELP","Displays the internal time.\n");
|
||||
MSG_Add("SHELL_CMD_TIME_NOW","Current time: ");
|
||||
MSG_Add("SHELL_CMD_TIME_HELP_LONG","TIME [/T] [/H]\n"\
|
||||
" /T: Display simple time\n"\
|
||||
" /H: Synchronize with host\n");
|
||||
MSG_Add("SHELL_CMD_MKDIR_ERROR","Unable to make: %s.\n");
|
||||
MSG_Add("SHELL_CMD_RMDIR_ERROR","Unable to remove: %s.\n");
|
||||
MSG_Add("SHELL_CMD_DEL_ERROR","Unable to delete: %s.\n");
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <time.h>
|
||||
|
||||
static SHELL_Cmd cmd_list[]={
|
||||
{ "DIR", 0, &DOS_Shell::CMD_DIR, "SHELL_CMD_DIR_HELP"},
|
||||
|
@ -39,6 +40,7 @@ static SHELL_Cmd cmd_list[]={
|
|||
{ "CHOICE", 1, &DOS_Shell::CMD_CHOICE, "SHELL_CMD_CHOICE_HELP"},
|
||||
{ "CLS", 0, &DOS_Shell::CMD_CLS, "SHELL_CMD_CLS_HELP"},
|
||||
{ "COPY", 0, &DOS_Shell::CMD_COPY, "SHELL_CMD_COPY_HELP"},
|
||||
{ "DATE", 0, &DOS_Shell::CMD_DATE, "SHELL_CMD_DATE_HELP"},
|
||||
{ "DEL", 0, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"},
|
||||
{ "DELETE", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"},
|
||||
{ "ERASE", 1, &DOS_Shell::CMD_DELETE, "SHELL_CMD_DELETE_HELP"},
|
||||
|
@ -61,6 +63,7 @@ static SHELL_Cmd cmd_list[]={
|
|||
{ "SET", 1, &DOS_Shell::CMD_SET, "SHELL_CMD_SET_HELP"},
|
||||
{ "SHIFT", 1, &DOS_Shell::CMD_SHIFT, "SHELL_CMD_SHIFT_HELP"},
|
||||
{ "SUBST", 1, &DOS_Shell::CMD_SUBST, "SHELL_CMD_SUBST_HELP"},
|
||||
{ "TIME", 0, &DOS_Shell::CMD_TIME, "SHELL_CMD_TIME_HELP"},
|
||||
{ "TYPE", 0, &DOS_Shell::CMD_TYPE, "SHELL_CMD_TYPE_HELP"},
|
||||
{ "VER", 0, &DOS_Shell::CMD_VER, "SHELL_CMD_VER_HELP"},
|
||||
{0,0,0,0}
|
||||
|
@ -937,6 +940,107 @@ void DOS_Shell::CMD_CALL(char * args){
|
|||
this->call=false;
|
||||
}
|
||||
|
||||
void DOS_Shell::CMD_DATE(char * args) {
|
||||
HELP("DATE");
|
||||
if(ScanCMDBool(args,"h")) {
|
||||
// synchronize date with host parameter
|
||||
time_t curtime;
|
||||
struct tm *loctime;
|
||||
curtime = time (NULL);
|
||||
loctime = localtime (&curtime);
|
||||
|
||||
reg_cx = loctime->tm_year+1900;
|
||||
reg_dh = loctime->tm_mon+1;
|
||||
reg_dl = loctime->tm_mday;
|
||||
|
||||
reg_ah=0x2b; // set system date
|
||||
CALLBACK_RunRealInt(0x21);
|
||||
return;
|
||||
}
|
||||
// check if a date was passed in command line
|
||||
Bitu newday,newmonth,newyear;
|
||||
if(sscanf(args,"%u-%u-%u",&newmonth,&newday,&newyear)==3) {
|
||||
reg_cx = newyear;
|
||||
reg_dh = newmonth;
|
||||
reg_dl = newday;
|
||||
|
||||
reg_ah=0x2b; // set system date
|
||||
CALLBACK_RunRealInt(0x21);
|
||||
if(reg_al==0xff) WriteOut(MSG_Get("SHELL_CMD_DATE_ERROR"));
|
||||
return;
|
||||
}
|
||||
// display the current date
|
||||
reg_ah=0x2a; // get system date
|
||||
CALLBACK_RunRealInt(0x21);
|
||||
|
||||
const char* datestring = MSG_Get("SHELL_CMD_DATE_DAYS");
|
||||
Bit8u length;
|
||||
char day[6] = {0};
|
||||
if(sscanf(datestring,"%u",&length) && (length<5) && (strlen(datestring)==(length*7+1))) {
|
||||
// date string appears valid
|
||||
for(int i = 0; i < length; i++) day[i] = datestring[reg_al*length+1+i];
|
||||
}
|
||||
bool dateonly = ScanCMDBool(args,"t");
|
||||
if(!dateonly) WriteOut(MSG_Get("SHELL_CMD_DATE_NOW"));
|
||||
|
||||
const char* formatstring = MSG_Get("SHELL_CMD_DATE_FORMAT");
|
||||
if(strlen(formatstring)!=5) return;
|
||||
char buffer[15] = {0};
|
||||
Bitu bufferptr=0;
|
||||
for(Bitu i = 0; i < 5; i++) {
|
||||
if(i==1 || i==3) {
|
||||
buffer[bufferptr] = formatstring[i];
|
||||
bufferptr++;
|
||||
} else {
|
||||
if(formatstring[i]=='M') bufferptr += sprintf(buffer+bufferptr,"%02u",(Bitu)reg_dh);
|
||||
if(formatstring[i]=='D') bufferptr += sprintf(buffer+bufferptr,"%02u",(Bitu)reg_dl);
|
||||
if(formatstring[i]=='Y') bufferptr += sprintf(buffer+bufferptr,"%04u",(Bitu)reg_cx);
|
||||
}
|
||||
}
|
||||
WriteOut("%s %s\n",day, buffer);
|
||||
if(!dateonly) WriteOut(MSG_Get("SHELL_CMD_DATE_SETHLP"));
|
||||
};
|
||||
|
||||
void DOS_Shell::CMD_TIME(char * args) {
|
||||
HELP("TIME");
|
||||
if(ScanCMDBool(args,"h")) {
|
||||
// synchronize time with host parameter
|
||||
time_t curtime;
|
||||
struct tm *loctime;
|
||||
curtime = time (NULL);
|
||||
loctime = localtime (&curtime);
|
||||
|
||||
//reg_cx = loctime->;
|
||||
//reg_dh = loctime->;
|
||||
//reg_dl = loctime->;
|
||||
|
||||
// reg_ah=0x2d; // set system time TODO
|
||||
// CALLBACK_RunRealInt(0x21);
|
||||
|
||||
Bit32u ticks=(Bit32u)(((double)(loctime->tm_hour*3600+
|
||||
loctime->tm_min*60+
|
||||
loctime->tm_sec))*18.206481481);
|
||||
mem_writed(BIOS_TIMER,ticks);
|
||||
return;
|
||||
}
|
||||
bool timeonly = ScanCMDBool(args,"t");
|
||||
|
||||
reg_ah=0x2c; // get system time
|
||||
CALLBACK_RunRealInt(0x21);
|
||||
/*
|
||||
reg_dl= // 1/100 seconds
|
||||
reg_dh= // seconds
|
||||
reg_cl= // minutes
|
||||
reg_ch= // hours
|
||||
*/
|
||||
if(timeonly) {
|
||||
WriteOut("%2u:%02u\n",reg_ch,reg_cl);
|
||||
} else {
|
||||
WriteOut(MSG_Get("SHELL_CMD_TIME_NOW"));
|
||||
WriteOut("%2u:%02u:%02u,%02u\n",reg_ch,reg_cl,reg_dh,reg_dl);
|
||||
}
|
||||
};
|
||||
|
||||
void DOS_Shell::CMD_SUBST (char * args) {
|
||||
/* If more that one type can be substed think of something else
|
||||
* E.g. make basedir member dos_drive instead of localdrive
|
||||
|
|
Loading…
Add table
Reference in a new issue