+#include <string.h>
 #include <stdlib.h>
 #include <fcntl.h>
 #if defined(_MSC_VER)
 #endif
 
 /* common */
+#include "cmdline.h"
 #include "print.h"
 #include "xmalloc.h"
 
 
 typedef void (*PVFunc) (CPURegs* Regs);
 
+static unsigned ArgStart;
+
 
 
 /*****************************************************************************/
 
 
 
+static unsigned GetAX (CPURegs* Regs)
+{
+    return Regs->AC + (Regs->XR << 8);
+}
+
+
+
+static void SetAX (CPURegs* Regs, unsigned Val)
+{
+    Regs->AC = Val & 0xFF;
+    Val >>= 8;
+    Regs->XR = Val;
+}
+
+
+
+static void MemWriteWord (unsigned Addr, unsigned Val)
+{
+    MemWriteByte (Addr, Val);
+    Val >>= 8;
+    MemWriteByte (Addr + 1, Val);
+}
+
+
+
 static unsigned char Pop (CPURegs* Regs)
 {
     return MemReadByte (0x0100 + ++Regs->SP);
 {
     unsigned SP = MemReadZPWord (0x00);
     unsigned Val = MemReadWord (SP);
-    SP += Incr;
-    MemWriteByte (0x00, SP);
-    SP >>= 8;
-    MemWriteByte (0x01, SP);
+    MemWriteWord (0x0000, SP + Incr);
     return Val;
 }
 
 
 
+static void PVArgs (CPURegs* Regs)
+{
+    unsigned ArgC = ArgCount - ArgStart;
+    unsigned ArgV = GetAX (Regs);
+    unsigned SP   = MemReadZPWord (0x00);
+    unsigned Args = SP - (ArgC + 1) * 2;
+
+    Print (stdout, 2, "PVArgs ($%04X)\n", ArgV);
+
+    MemWriteWord (ArgV, Args);
+
+    SP = Args;
+    while (ArgStart < ArgCount) {
+        unsigned I = 0;
+        const char* Arg = ArgVec[ArgStart++];
+        SP -= strlen (Arg) + 1;
+        do {
+            MemWriteByte (SP + I, Arg[I]);
+        }
+        while (Arg[I++]);
+
+        MemWriteWord (Args, SP);
+        Args += 2;
+    }
+    MemWriteWord (Args, 0x0000);
+
+    MemWriteWord (0x0000, SP);
+    SetAX (Regs, ArgC);
+}
+
+
+
 static void PVExit (CPURegs* Regs)
 {
     Print (stdout, 1, "PVExit ($%02X)\n", Regs->AC);
 
     RetVal = open (Path, OFlag);
 
-    Regs->AC = RetVal & 0xFF;
-    RetVal >>= 8;
-    Regs->XR = RetVal & 0xFF;
+    SetAX (Regs, RetVal);
 }
 
 
 {
     unsigned RetVal;
 
-    unsigned FD = Regs->AC + (Regs->XR << 8);
+    unsigned FD = GetAX (Regs);
 
     Print (stdout, 2, "PVClose ($%04X)\n", FD);
 
     RetVal = close (FD);
 
-    Regs->AC = RetVal & 0xFF;
-    RetVal >>= 8;
-    Regs->XR = RetVal & 0xFF;
+    SetAX (Regs, RetVal);
 }
 
 
     unsigned char* Data;
     unsigned RetVal, I = 0;
 
-    unsigned Count = Regs->AC + (Regs->XR << 8);
+    unsigned Count = GetAX (Regs);
     unsigned Buf   = PopParam (2);
     unsigned FD    = PopParam (2);
 
     }
     xfree (Data);
 
-    Regs->AC = RetVal & 0xFF;
-    RetVal >>= 8;
-    Regs->XR = RetVal & 0xFF;
+    SetAX (Regs, RetVal);
 }
 
 
     unsigned char* Data;
     unsigned RetVal, I = 0;
 
-    unsigned Count = Regs->AC + (Regs->XR << 8);
+    unsigned Count = GetAX (Regs);
     unsigned Buf   = PopParam (2);
     unsigned FD    = PopParam (2);
 
 
     xfree (Data);
 
-    Regs->AC = RetVal & 0xFF;
-    RetVal >>= 8;
-    Regs->XR = RetVal & 0xFF;
+    SetAX (Regs, RetVal);
 }
 
 
 
 static const PVFunc Hooks[] = {
+    PVArgs,
     PVExit,
     PVOpen,
     PVClose,
 
 
 
-void ParaVirtualization (CPURegs* Regs)
-/* Potentially execute paravirtualization hook */
+void ParaVirtInit (unsigned aArgStart)
+/* Initialize the paravirtualization subsystem */
+{
+    ArgStart = aArgStart;
+};
+
+
+
+void ParaVirtHooks (CPURegs* Regs)
+/* Potentially execute paravirtualization hooks */
 {
     /* Check for paravirtualization address range */
     if (Regs->PC <  0xFFF0 ||