@@ -10,41 +10,12 @@
#include < stddef.h> // offsetof()
#include " ints/ints.h"
#include " defs.h"
#include " global.h"
#include " psp.h"
#define DOS_ADDR 0x100
#pragma pack(push, 1)
struct PSP {
uint8_t CPMExit[2 ]; // 0
uint16_t FirstFreeSegment; // 2
uint8_t Reserved1; // 4
uint8_t CPMCall5Compat[5 ]; // 5
uint32_t OldTSRAddress; // 12
uint32_t OldBreakAddress;
uint32_t CriticalErrorHandlerAddress;
uint16_t CallerPSPSegment;
uint8_t JobFileTable[20 ];
uint16_t EnvironmentSegment;
uint32_t INT21SSSP;
uint16_t JobFileTableSize;
uint32_t JobFileTablePointer;
uint32_t PreviousPSP;
uint32_t Reserved2;
uint16_t DOSVersion;
uint8_t Reserved3[14 ];
uint8_t DOSFarCall[3 ];
uint16_t Reserved4;
uint8_t ExtendedFCB1[7 ];
uint8_t FCB1[16 ];
uint8_t FCB2[20 ];
uint8_t CommandLineLength;
char CommandLine[127 ];
};
#pragma pack(pop)
static void usage (char *prog)
@@ -53,44 +24,6 @@ static void usage(char *prog)
printf (" Syntax: %s <COM>\n " , prog);
}
static void setup_psp (int16_t seg, uint8_t *fcontent, int argc, char **argv)
{
uint32_t abs = MK_FP (seg, 0 );
int i, j;
uint8_t c = 0 ;
struct PSP *PSP = (struct PSP *)(fcontent + abs );
// CPMExit: INT 20h
PSP->CPMExit [0 ] = 0xcd ;
PSP->CPMExit [1 ] = 0x20 ;
// DOS Far Call: INT 21h + RETF
PSP->DOSFarCall [0 ] = 0xcd ;
PSP->DOSFarCall [1 ] = 0x21 ;
PSP->DOSFarCall [2 ] = 0xcb ;
// first FSB = empty file name
PSP->FCB1 [0 ] = 0x01 ;
PSP->FCB1 [1 ] = 0x20 ;
for (i = 2 ; i < argc && c < 0x7E ; i++) {
j = 0 ;
PSP->CommandLine [c++] = ' ' ;
while (argv[i][j] && c < 0x7E )
PSP->CommandLine [c++] = argv[i][j++];
}
PSP->CommandLine [c] = 0x0D ;
PSP->CommandLineLength = c;
/*
printf("==== offset of c = %x\n", offsetof(struct PSP, CommandLineLength));
printf("==== offset of c1 = %x\n", offsetof(struct PSP, CPMCall5Compat));
printf("==== offset of c1 = %u\n", offsetof(struct PSP, OldTSRAddress));
printf("==== cmd[1] = %c\n", PSP->CommandLine[1]);
printf("==== cmd[2] = %c\n", PSP->CommandLine[2]);
*/
}
// callback for handling interrupt
void hook_intr (uc_engine *uc, uint32_t intno, void *user_data)
{
@@ -169,12 +102,14 @@ int main(int argc, char **argv)
}
// initialize internal settings
global_init ();
int10_init ();
int15_init ();
int21_init ();
// setup PSP
setup_psp (0 , fcontent, argc, argv);
psp_setup (0 , fcontent, argc, argv);
// write machine code to be emulated in, including the prefix PSP
uc_mem_write (uc, 0 , fcontent, DOS_ADDR + fsize);