Skip to content

Commit

Permalink
Feature: support calling MS-DOS and DPMI INT services from Win16Platform
Browse files Browse the repository at this point in the history
  • Loading branch information
uxmal committed Jul 15, 2024
1 parent 1de9bd0 commit fee2293
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/Core/Hll/C/NamedDataTypeExtractor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ private Argument_v1 ConvertParameter(ParamDecl decl)
attr.Tokens[iTok + 2].Value is null ||
attr.Tokens[iTok + 2].Type != CTokenType.StringLiteral)
throw new FormatException("[[reko::arg(register,<name>)]] attribute expects a register name and a value.");
kind = new Register_v1 { Name = (string) attr.Tokens[2].Value! };
kind = new Register_v1 { Name = (string) attr.Tokens[iTok + 2].Value! };
iTok += 3;
}
else if (attr.Tokens[iTok].Type == CTokenType.Id)
Expand Down
4 changes: 3 additions & 1 deletion src/Drivers/reko.config
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,9 @@
<TypeLibrary Loader="spec" Name="user.exe16.spec" Module="USER"/>
<TypeLibrary Loader="spec" Name="commdlg.dll16.spec" Module="COMMDLG" />
<TypeLibrary Name="win16c.xml" />
</TypeLibraries>
<TypeLibrary Name="dpmi.inc" Loader="RekoCHeader" />
<TypeLibrary Name="realmodeintservices.xml" />
</TypeLibraries>
<Characteristics>
<TypeLibrary Name="win16characteristics.xml" />
</Characteristics>
Expand Down
24 changes: 24 additions & 0 deletions src/Environments/Msdos/dpmi.inc
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,21 @@
[[reko::arg(register,"bx")]] unsigned short selector_to_free,
[[reko::arg(out,register,"ax")]] unsigned short error_code);

[[reko::service(vector=0x31,regs={ax:0x0003})]]
[[reko::returns(register,"ax")]] unsigned short dpmi_get_next_selector_increment_value();

[[reko::service(vector=0x31,regs={ax:0x0006})]]
[[reko::returns(flag,"C")]] bool DPMI_get_segment_base_address(
[[reko::arg(register,"bx")]] unsigned short selector,
[[reko::arg(out,seq,"cx","dx")]] unsigned int linear_base_address,
[[reko::arg(out,register,"ax")]] unsigned int error_code);

[[reko::service(vector=0x31,regs={ax:0x000B})]]
[[reko::returns(flag,"C")]] bool DPMI_get_descriptor(
[[reko::arg(register,"bx")]] unsigned short selector,
[[reko::arg(seq,"es","di")]] unsigned char __far * descriptorBuffer, // 8 bytes
[[reko::arg(out,register,"ax")]] unsigned int error_code);

[[reko::service(vector=0x31,regs={ax:0x0007})]]
[[reko::returns(flag,"C")]] bool DPMI_set_segment_base_address(
[[reko::arg(register,"bx")]] unsigned short selector,
Expand Down Expand Up @@ -51,9 +60,24 @@
[[reko::returns(seq,"cx","dx")]] unsigned int DPMI_get_real_mode_interrupt_vector(
[[reko::arg(register,"bl")]] unsigned char interrupt_number);

[[reko::service(vector=0x31,regs={ax:0x0400})]]
void DPMI_get_version(
[[reko::arg(out,register,"ah")]] unsigned char major,
[[reko::arg(out,register,"al")]] unsigned char minor,
[[reko::arg(out,register,"bx")]] unsigned short dpmiHostFlags,
[[reko::arg(out,register,"cl")]] unsigned char processorType, // (02h=80286, 03h=80386, 04h=80486)
[[reko::arg(out,register,"dh")]] unsigned char virtualMasterInterruptControllerBaseInterrupt,
[[reko::arg(out,register,"dl")]] unsigned char virtualSlaveInterruptControllerBaseInterrupt);


[[reko::service(vector=0x31,regs={ax:0x0501})]]
[[reko::returns(flag,"C")]] bool DPMI_allocate_memory_block(
[[reko::arg(seq,"bx","cx")]] unsigned int byte_count,
[[reko::arg(out,seq,"bx","cx")]] unsigned int linear_address,
[[reko::arg(out,seq,"si","di")]] unsigned int memory_block_handle,
[[reko::arg(out,register,"ax")]] unsigned short error_code);

[[reko::service(vector=0x31,regs={ax:0x0502})]]
[[reko::returns(flag,"C")]] bool DPMI_free_memory_block(
[[reko::arg(seq,"si","di")]] unsigned int memory_block_handle,
[[reko::arg(out,register,"ax")]] unsigned short error_code);
10 changes: 10 additions & 0 deletions src/Environments/Windows/Win16Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,16 @@ public override ICallingConvention GetCallingConvention(string? ccName)

public override SystemService? FindService(int vector, ProcessorState? state, IMemory? memory)
{
var ax = state?.GetRegister(RegisterStorage.Reg16("ax", 0));
if (vector == 0x31 && ax is not null && ax.IsValid && ax.ToInt32() == 0x400)
_ = this; //$DEBUG

var metadata = EnsureTypeLibraries(PlatformIdentifier);
foreach (var module in metadata.Modules.Values)
{
if (module.ServicesByVector.TryGetValue(vector, out List<SystemService>? svcs))
return svcs.FirstOrDefault(s => s.SyscallInfo!.Matches(vector, state));
}
return null;
}

Expand Down

0 comments on commit fee2293

Please sign in to comment.