Skip to content

Commit 2a3c81e

Browse files
committed
Add interrupt handler 21h 57h
- Add GetSetFileDateAndTime method - Add DateTimeFormDosDateAndTime method - Setup int 21h 57h to call GetSetFileDateAndTime method
1 parent 6fdee16 commit 2a3c81e

1 file changed

Lines changed: 70 additions & 1 deletion

File tree

src/Spice86.Core/Emulator/InterruptHandlers/Dos/DosInt21Handler.cs

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,16 +176,17 @@ private void FillDispatchTable() {
176176
AddAction(0x47, () => GetCurrentDirectory(true));
177177
AddAction(0x48, () => AllocateMemoryBlock(true));
178178
AddAction(0x49, () => FreeMemoryBlock(true));
179-
AddAction(0x50, () => SetCurrentPsp());
180179
AddAction(0x4A, () => ModifyMemoryBlock(true));
181180
AddAction(0x4B, () => LoadAndOrExecute(true));
182181
AddAction(0x4C, QuitWithExitCode);
183182
AddAction(0x4D, GetReturnCode);
184183
AddAction(0x4E, () => FindFirstMatchingFile(true));
185184
AddAction(0x4F, () => FindNextMatchingFile(true));
185+
AddAction(0x50, () => SetCurrentPsp());
186186
AddAction(0x51, GetPspAddress);
187187
AddAction(0x52, GetListOfLists);
188188
AddAction(0x55, CreateChildPsp);
189+
AddAction(0x57, () => GetSetFileDateAndTime(true));
189190
AddAction(0x58, () => AllocationStrategyOrUpperMemoryLinkState(true));
190191
AddAction(0x62, GetPspAddress);
191192
AddAction(0x63, GetLeadByteTable);
@@ -1951,6 +1952,74 @@ public void GetSetFileAttributes(bool calledFromVm) {
19511952
}
19521953
}
19531954

1955+
/// <summary>
1956+
/// Gets (AL: 0) or sets (AL: 1) file DateTime for the file identified via its file path at DS:DX.
1957+
/// </summary>
1958+
/// <returns>
1959+
/// CF is cleared on success. <br/>
1960+
/// CF is set on error. Possible error code in AX: 0x1 (function number invalid) 0x6 (invalid handle). <br/>
1961+
/// </returns>
1962+
/// <param name="calledFromVm">Whether this was called from internal emulator code.</param>
1963+
public void GetSetFileDateAndTime(bool calledFromVm) {
1964+
byte op = State.AL;
1965+
string dosFileName = _dosStringDecoder.GetZeroTerminatedStringAtDsDx();
1966+
string? fileName = _dosFileManager.TryGetFullHostPathFromDos(dosFileName);
1967+
if (!File.Exists(fileName)) {
1968+
LogDosError(calledFromVm);
1969+
SetCarryFlag(true, calledFromVm);
1970+
// invalid handle
1971+
State.AX = 0x6;
1972+
return;
1973+
}
1974+
switch (op) {
1975+
case 0: {
1976+
if (LoggerService.IsEnabled(LogEventLevel.Verbose)) {
1977+
LoggerService.Verbose("GET FILE DATETIME {FileName}", fileName);
1978+
}
1979+
DateTime dateTime = File.GetLastAccessTime(fileName);
1980+
State.CX = DosFileManager.ToDosTime(dateTime);
1981+
State.DX = DosFileManager.ToDosDate(dateTime);
1982+
SetCarryFlag(false, calledFromVm);
1983+
break;
1984+
}
1985+
case 1: {
1986+
ushort dosFileTime = State.CX;
1987+
ushort dosFileDate = State.DX;
1988+
if (LoggerService.IsEnabled(LogEventLevel.Verbose)) {
1989+
LoggerService.Verbose("SET FILE DATETIME {FileName}, {FileTime}, {FileDate}",
1990+
fileName, dosFileDate, dosFileTime);
1991+
}
1992+
DateTime fileDateTime = DateTimeFormDosDateAndTime(dosFileTime, dosFileDate);
1993+
File.SetLastAccessTime(fileName, fileDateTime);
1994+
SetCarryFlag(false, calledFromVm);
1995+
break;
1996+
}
1997+
default: {
1998+
SetCarryFlag(true, calledFromVm);
1999+
// function number invalid
2000+
State.AX = 0x1;
2001+
break;
2002+
}
2003+
}
2004+
}
2005+
2006+
/// <summary>
2007+
/// Converts DOS Date and Time to DateTime
2008+
/// DOS date format: bits 15-9=year-1980, bits 8-5=month, bits 4-0=day.
2009+
/// DOS time format: bits 15-11=hour, bits 10-5=minute, bits 4-0=seconds/2.
2010+
/// </summary>
2011+
public static DateTime DateTimeFormDosDateAndTime(ushort dosDate, ushort dosTime) {
2012+
int day = (dosDate >> 0) & 0b11111;
2013+
int month = (dosDate >> 5) & 0b1111;
2014+
int year = (dosDate >> 9) & 0b1111111 + 1980;
2015+
2016+
int seconds = (dosTime >> 0) & 0b11111 * 2;
2017+
int minutes = (dosTime >> 5) & 0b111111;
2018+
int hours = (dosTime >> 11) & 0b11111;
2019+
2020+
return new DateTime(year, month, day, hours, minutes, seconds);
2021+
}
2022+
19542023
/// <summary>
19552024
/// Gets the FCB linear address from DS:DX.
19562025
/// </summary>

0 commit comments

Comments
 (0)