362 lines
8.3 KiB
ObjectPascal
362 lines
8.3 KiB
ObjectPascal
{ ************************************************
|
|
* Asuro
|
|
* Unit: util
|
|
* Description: Utilities for data manipulation
|
|
************************************************
|
|
* Author: K Morris
|
|
* Contributors:
|
|
************************************************ }
|
|
|
|
unit util;
|
|
|
|
{$ASMMODE intel}
|
|
|
|
interface
|
|
|
|
uses
|
|
bios_data_area, tracer;
|
|
|
|
function INTE : boolean;
|
|
procedure CLI();
|
|
procedure STI();
|
|
procedure GPF();
|
|
|
|
function hi(b : uint8) : uint8;
|
|
function lo(b : uint8) : uint8;
|
|
function switchendian(b : uint8) : uint8;
|
|
function getWord(i : uint32; hi : boolean) : uint16;
|
|
function getByte(i : uint32; index : uint8) : uint8;
|
|
|
|
procedure outb(port : uint16; val : uint8);
|
|
procedure outw(port : uint16; val : uint16);
|
|
procedure outl(port : uint16; val : uint32);
|
|
function inb(port : uint16) : uint8;
|
|
function inw(port : uint16) : uint16;
|
|
function inl(port : uint16) : uint32;
|
|
procedure io_wait;
|
|
|
|
procedure memset(location : uint32; value : uint8; size : uint32);
|
|
procedure memcpy(source : uint32; dest : uint32; size : uint32);
|
|
|
|
procedure printmemory(source : uint32; length : uint32; col : uint32; delim : PChar; offset_row : boolean);
|
|
|
|
procedure halt_and_catch_fire();
|
|
procedure halt_and_dont_catch_fire();
|
|
procedure BSOD(fault : pchar; info : pchar);
|
|
procedure psleep(t : uint16);
|
|
|
|
var
|
|
endptr : uint32; external name '__end';
|
|
stack : uint32; external name 'KERNEL_STACK';
|
|
|
|
implementation
|
|
|
|
uses
|
|
console;
|
|
|
|
function INTE : boolean;
|
|
var
|
|
flags : uint32;
|
|
begin
|
|
asm
|
|
PUSH EAX
|
|
PUSHF
|
|
POP EAX
|
|
MOV flags, EAX
|
|
POP EAX
|
|
end;
|
|
INTE:= (flags AND (1 SHL 9)) > 0;
|
|
end;
|
|
|
|
procedure io_wait;
|
|
var
|
|
port : uint8;
|
|
val : uint8;
|
|
begin
|
|
port:= $80;
|
|
val:= 0;
|
|
asm
|
|
PUSH EAX
|
|
PUSH EDX
|
|
MOV DX, port
|
|
MOV AL, val
|
|
OUT DX, AL
|
|
POP EDX
|
|
POP EAX
|
|
end;
|
|
end;
|
|
|
|
procedure printmemory(source : uint32; length : uint32; col : uint32; delim : PChar; offset_row : boolean);
|
|
var
|
|
buf : puint8;
|
|
i : uint32;
|
|
|
|
begin
|
|
push_trace('util.printmemory');
|
|
buf:= puint8(source);
|
|
for i:=0 to length do begin
|
|
if offset_row and (i = 0) then begin
|
|
console.writehex(source + (i * col));
|
|
console.writestring(': ');
|
|
end;
|
|
console.writehexpair(buf[i]);
|
|
if ((i+1) MOD col) = 0 then begin
|
|
console.writestringln(' ');
|
|
if offset_row then begin
|
|
console.writehex(source + (i * col));
|
|
console.writestring(': ');
|
|
end;
|
|
end else begin
|
|
console.writestring(delim);
|
|
end;
|
|
end;
|
|
console.writestringln(' ');
|
|
pop_trace;
|
|
end;
|
|
|
|
function hi(b : uint8) : uint8; [public, alias: 'util_hi'];
|
|
begin
|
|
hi:= (b AND $F0) SHR 4;
|
|
end;
|
|
|
|
function lo(b : uint8) : uint8; [public, alias: 'util_lo'];
|
|
begin
|
|
lo:= b AND $0F;
|
|
end;
|
|
|
|
procedure CLI(); assembler; nostackframe;
|
|
asm
|
|
CLI
|
|
end;
|
|
|
|
procedure STI(); assembler; nostackframe;
|
|
asm
|
|
STI
|
|
end;
|
|
|
|
procedure GPF(); assembler;
|
|
asm
|
|
INT 13
|
|
end;
|
|
|
|
function switchendian(b : uint8) : uint8; [public, alias: 'util_switchendian'];
|
|
begin
|
|
switchendian:= (lo(b) SHL 4) OR hi(b);
|
|
end;
|
|
|
|
procedure psleep(t : uint16);
|
|
var
|
|
t1, t2 : uint16;
|
|
|
|
begin
|
|
t1:= BDA^.Ticks;
|
|
t2:= BDA^.Ticks;
|
|
while t2-t1 < t do begin
|
|
t2:= BDA^.Ticks;
|
|
if t2 < t1 then break;
|
|
end;
|
|
end;
|
|
|
|
procedure outl(port : uint16; val : uint32); [public, alias: 'util_outl'];
|
|
begin
|
|
asm
|
|
PUSH EAX
|
|
PUSH EDX
|
|
MOV DX, port
|
|
MOV EAX, val
|
|
OUT DX, EAX
|
|
POP EDX
|
|
POP EAX
|
|
end;
|
|
end;
|
|
|
|
procedure outw(port : uint16; val : uint16); [public, alias: 'util_outw'];
|
|
begin
|
|
asm
|
|
PUSH EAX
|
|
PUSH EDX
|
|
MOV DX, port
|
|
MOV AX, val
|
|
OUT DX, AX
|
|
POP EDX
|
|
POP EAX
|
|
end;
|
|
end;
|
|
|
|
procedure outb(port : uint16; val : uint8); [public, alias: 'util_outb'];
|
|
begin
|
|
asm
|
|
PUSH EAX
|
|
PUSH EDX
|
|
MOV DX, port
|
|
MOV AL, val
|
|
OUT DX, AL
|
|
POP EDX
|
|
POP EAX
|
|
end;
|
|
end;
|
|
|
|
procedure halt_and_catch_fire(); [public, alias: 'util_halt_and_catch_fire'];
|
|
begin
|
|
asm
|
|
cli
|
|
hlt
|
|
end;
|
|
end;
|
|
|
|
procedure halt_and_dont_catch_fire(); [public, alias: 'util_halt_and_dont_catch_fire'];
|
|
begin
|
|
while true do begin
|
|
end;
|
|
end;
|
|
|
|
function inl(port : uint16) : uint32; [public, alias: 'util_inl'];
|
|
begin
|
|
asm
|
|
PUSH EAX
|
|
PUSH EDX
|
|
MOV DX, port
|
|
IN EAX, DX
|
|
MOV inl, EAX
|
|
POP EDX
|
|
POP EAX
|
|
end;
|
|
end;
|
|
|
|
function inw(port : uint16) : uint16; [public, alias: 'util_inw'];
|
|
begin
|
|
asm
|
|
PUSH EAX
|
|
PUSH EDX
|
|
MOV DX, port
|
|
IN AX, DX
|
|
MOV inw, AX
|
|
POP EDX
|
|
POP EAX
|
|
end;
|
|
end;
|
|
|
|
function inb(port : uint16) : uint8; [public, alias: 'util_inb'];
|
|
begin
|
|
asm
|
|
PUSH EAX
|
|
PUSH EDX
|
|
MOV DX, port
|
|
IN AL, DX
|
|
MOV inb, AL
|
|
POP EDX
|
|
POP EAX
|
|
end;
|
|
end;
|
|
|
|
procedure memset(location : uint32; value : uint8; size : uint32);
|
|
var
|
|
loc : puint8;
|
|
i : uint32;
|
|
|
|
begin
|
|
push_trace('util.memset');
|
|
for i:=0 to size-1 do begin
|
|
loc:= puint8(location + i);
|
|
loc^:= value;
|
|
end;
|
|
pop_trace;
|
|
end;
|
|
|
|
procedure memcpy(source : uint32; dest : uint32; size : uint32);
|
|
var
|
|
src, dst : puint8;
|
|
i : uint32;
|
|
|
|
begin
|
|
push_trace('util.memcpy');
|
|
for i:=0 to size-1 do begin
|
|
src:= puint8(source + i);
|
|
dst:= puint8(dest + i);
|
|
dst^:= src^;
|
|
end;
|
|
pop_trace;
|
|
end;
|
|
|
|
function getWord(i : uint32; hi : boolean) : uint16;
|
|
begin
|
|
if hi then begin
|
|
getWord:= (i AND $FFFF0000) SHR 16;
|
|
end else begin
|
|
getWord:= (i AND $0000FFFF);
|
|
end;
|
|
end;
|
|
|
|
function getByte(i : uint32; index : uint8) : uint8;
|
|
var
|
|
mask : uint32;
|
|
|
|
begin
|
|
mask:= ($FF SHL (8*index));
|
|
getByte:= (i AND mask) SHR (8*index);
|
|
end;
|
|
|
|
procedure BSOD(fault : pchar; info : pchar);
|
|
var
|
|
trace : pchar;
|
|
i : uint32;
|
|
z : uint32;
|
|
|
|
begin
|
|
disable_cursor;
|
|
if not BSOD_ENABLE then exit;
|
|
console.setdefaultattribute(console.combinecolors(white, Red));
|
|
console.clear;
|
|
console.writestringln(' ');
|
|
console.writestringln(' ');
|
|
console.writestring(' ');
|
|
console.setdefaultattribute(console.combinecolors(black, white));
|
|
console.writestring(' ');
|
|
console.setdefaultattribute(console.combinecolors(white, Red));
|
|
console.writestringln(' ');
|
|
console.writestring(' ');
|
|
console.setdefaultattribute(console.combinecolors(black, white));
|
|
console.writestring(' ASURO DID A WHOOPSIE! :( ');
|
|
console.setdefaultattribute(console.combinecolors(lwhite, Red));
|
|
console.writestringln(' ');
|
|
console.writestring(' ');
|
|
console.setdefaultattribute(console.combinecolors(black, white));
|
|
console.writestring(' ');
|
|
console.setdefaultattribute(console.combinecolors(white, Red));
|
|
console.writestringln(' ');
|
|
console.writestringln(' ');
|
|
console.writestringln(' ');
|
|
console.writestringln(' Asuro encountered an error and your computer is now a teapot.');
|
|
console.writestringln(' ');
|
|
console.writestringln(' Your data is almost certainly safe.');
|
|
console.writestringln(' ');
|
|
console.writestringln(' Details of the fault (for those boring enough to read) are as follows: ');
|
|
console.writestringln(' ');
|
|
console.writestring(' Fault ID: ');
|
|
console.writestringln(fault);
|
|
console.writestring(' Fault Info: ');
|
|
console.writestringln(info);
|
|
console.writestringln(' ');
|
|
console.writestring(' Call Stack: ');
|
|
trace:= tracer.get_last_trace;
|
|
if trace <> nil then begin
|
|
console.writestring('[-0] ');
|
|
console.writestringln(trace);
|
|
for i:=1 to 6 do begin
|
|
trace:= tracer.get_trace_N(i);
|
|
if trace <> nil then begin
|
|
console.writestring(' [');
|
|
console.writestring('-');
|
|
console.writeint(i);
|
|
console.writestring('] ');
|
|
console.writestringln(trace);
|
|
end;
|
|
end;
|
|
end else begin
|
|
console.writestringln('Unknown.')
|
|
end;
|
|
halt_and_catch_fire();
|
|
end;
|
|
|
|
end.
|