kvisc/vm/in/super.c

118 lines
2.8 KiB
C

// The OS/K Team licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
#include <unistd.h>
#include <pc/device.h>
#include <in/instrs.h>
#include <pc/console.h>
//----------------------------------------------------------------------------//
void do_hlt()
{
SDL_Event evt;
while (1)
{
if (SDL_WaitEvent(&evt) == 1)
{
if (evt.type == SDL_QUIT)
die(0);
if (evt.type == SDL_KEYDOWN)
{
console_handle_input(evt.key.keysym.sym);
if (evt.key.keysym.sym == SDLK_RETURN)
break;
}
}
}
}
//----------------------------------------------------------------------------//
IMPL_START(hlt, 0) { CHK_SUPERV(); do_hlt(); return 0; }
IMPL_START(stop, 0) { CHK_SUPERV(); _except(E_SHT, "STOP INSTR"); }
IMPL_START(crash, 0) { CHK_SUPERV(); _except(1023, "CRASH instruction"); }
//----------------------------------------------------------------------------//
IMPL_START(trap, 1)
{
if (p1->val > 255) _except(E_ILL, "TRAP number greater than 255");
_except(p1->val + 256, "TRAP instruction");
}
IMPL_START(iret, 0) {
if (ctx->dumpsw)
trace("\nReturning from exception #%ld\n\n", R(R13));
// should do more checks
R(RIP) = R(R15);
rfs_current_idx = R(R14);
ctx->rf = rfs[R(R14)];
return 0;
}
//----------------------------------------------------------------------------//
//
// code common to devctl and iocall
//
dev_t *devctl_common(ulong idx)
{
dev_t *dev = devget(idx);
if (!dev) R(RAX) = -2;
else if (dev->state == DEVPWOF) R(RAX) = -3;
else if (dev->state == DEVFERR) R(RAX) = -4;
else if (dev->state == DEVPLUG) R(RAX) = -5;
else return dev;
return NULL;
}
IMPL_START(devctl, 2)
{
CHK_SUPERV();
dev_t *dev = devctl_common(p1->val);
if (dev == NULL)
return 0;
switch (p2->val) {
case 0: writestr(R(AX0), DEVLEN, dev->type); break;
case 1: writestr(R(AX0), DEVLEN, dev->name); break;
case 2: writestr(R(AX0), DEVLEN, dev->modl); break;
case 3: writestr(R(AX0), DEVLEN, dev->vend); break;
case 4: R(RAX) = dev->major; R(RDX) = dev->minor; break;
case 5: R(RAX) = dev->feats; R(RDX) = dev->revis; break;
default: R(RAX) = -6; break;
}
return 0;
}
IMPL_START(iocall, 2)
{
CHK_SUPERV();
long rc;
dev_t *dev = devctl_common(p1->val);
if (dev == NULL) return 0;
else if (p2->val >= DEVSLOTS || dev->fslots[p2->val] == NULL) R(RAX) = -6;
else {
rc = dev->fslots[p2->val](dev);
if (rc < 0) { R(RAX) = rc; R(RDX) = 0; }
}
return 0;
}
//----------------------------------------------------------------------------//