unit wmfpuemu_Glue;

interface

uses fpu_types, config;

procedure math_abort (info: pinfo; signal: word);
procedure fpu_verify_area (what: unsigned; ptr: pointer; n: unsigned);
function fpu_get_user (ptr: pointer; len: integer): longword;
function fpu_put_user (val: longword; ptr: pointer; len: unsigned): longword;
function fpu_get_ds: word;

{$include fpu_const.pas}
implementation

uses cpu, fpu_system, Service, SysUtils;

procedure math_abort (info: pinfo; signal: word);
  begin
    bx_cpu.Exception(16, 0, 0);
  end;

procedure fpu_verify_area (what: unsigned; ptr: pointer; n: unsigned);
  var
    seg: pbx_segment_reg_t;
  begin

    seg := @fpu_cpu_ptr^.sregs[fpu_iptr^.seg];

    if (what = VERIFY_READ) then
      begin
      fpu_cpu_ptr^.read_virtual_checks(seg, Bit32u(ptr), n);
      end
    else; {  // VERIFY_WRITE
    fpu_cpu_ptr->write_virtual_checks(seg, PTR2INT(ptr), n);
    }
    //BX_DEBUG(( "verify_area: 0x%x", PTR2INT(ptr)));
  end;

function fpu_get_user (ptr: pointer; len: integer): longword;
  var
    val32: Bit32u;
    val16: Bit16u;
    val8:  Bit8u;
  begin
    case (len) of
      1:
        begin
        fpu_cpu_ptr^.read_virtual_byte(fpu_iptr^.seg, Bit32u(ptr), @val8);
        val32 := val8;
        end;
      2:
        begin
        fpu_cpu_ptr^.read_virtual_word(fpu_iptr^.seg, Bit32u(ptr), @val16);
        val32 := val16;
        end;
      4:
        begin
        fpu_cpu_ptr^.read_virtual_dword(fpu_iptr^.seg, Bit32u(ptr), @val32);
        end;
      else
        BX_PANIC(Format('fpu_get_user: len:=%u', [len]));
      end;
    Result := (val32);
  end;

function fpu_put_user (val: longword; ptr: pointer; len: unsigned): longword;
  var
    val32: Bit32u;
    val16: Bit16u;
    val8:  Bit8u;
  begin
    case (len) of
      1:
        begin
        val8 := val;
        fpu_cpu_ptr^.write_virtual_byte(fpu_iptr^.seg, Bit32u(ptr), @val8);
        end;
      2:
        begin
        val16 := val;
        fpu_cpu_ptr^.write_virtual_word(fpu_iptr^.seg, Bit32u(ptr), @val16);
        end;
      4:
        begin
        val32 := val;
        fpu_cpu_ptr^.write_virtual_dword(fpu_iptr^.seg, Bit32u(ptr), @val32);
        end;
      else
        BX_PANIC(Format('fpu_put_user: len:=%u', [len]));
      end;
  end;

function fpu_get_ds: word;
  begin
    Result := (fpu_cpu_ptr^.sregs[BX_SEG_REG_DS].selector.Value);
  end;

end.
