//
//  Copyright (C) 1997,1998,1999 Forest Edge Software, All Rights Reserved
//
//  Program:    eVAX, a "Virtual VAX"
//
//  Author:     Tom Cole
//
//  Module:     p1_vector.c
//
//  Purpose:    This handles the P1 system service vector for running VMS
//              programs.  It can generate the P1 vector, and generates the
//              symbol table entries required to allow direct calls.
//
//  History:    11/08/99        Created.
//

#include "vax.pch"
#include "vaxinstr.h"
#include "asmproto.h"
#include "shim.h"
#include "services.h"

void declare_services( void );

long service_count = 0;

struct P1_VECTOR {
    char * name;
    LONGWORD addr;
    CALLV service;
} p1_vector[] = {

{ "SYS$ABORT_RU",           0x7FFEE640, 0L },
{ "SYS$ABORT_TRANS",        0x7FFEE6E0, 0L },
{ "SYS$ABORT_TRANSW",       0x7FFEE738, 0L },
{ "SYS$ACK_EVENT",          0x7FFEE838, 0L },
{ "SYS$ADD_BRANCH",         0x7FFEE708, 0L },
{ "SYS$ADD_BRANCHW",        0x7FFEE760, 0L },
{ "SYS$ADJSTK",             0x7FFEDE20, 0L },
{ "SYS$ADJWSL",             0x7FFEDE28, 0L },
{ "SYS$ALCDNP",             0x7FFEDE30, 0L },
{ "SYS$ALLOC",              0x7FFEDE38, 0L },
{ "SYS$ASCEFC",             0x7FFEDE40, 0L },
{ "SYS$ASCTIM",             0x7FFEDE48, 0L },
{ "SYS$ASCTOID",            0x7FFEE4B0, 0L },
{ "SYS$ASCUTC",             0x7FFEE590, 0L },
{ "SYS$ASSIGN",             0x7FFEDE50, 0L },
{ "SYS$AUDIT_EVENT",        0x7FFEE8A8, 0L },
{ "SYS$AUDIT_EVENTW",       0x7FFEE8B0, 0L },
{ "SYS$AUDIT_EVENTW_2",     0x7FFEE8B8, 0L },
{ "SYS$AUDIT_EVENTW_3",     0x7FFEE8C0, 0L },
{ "SYS$BINTIM",             0x7FFEDE58, 0L },
{ "SYS$BINUTC",             0x7FFEE588, 0L },
{ "SYS$BRDCST",             0x7FFEE098, 0L },
{ "SYS$BRKTHRU",            0x7FFEE4C8, 0L },
{ "SYS$BRKTHRUW",           0x7FFEE4E8, 0L },
{ "SYS$BRKTHRUW_2",         0x7FFEE4F0, 0L },
// { "SYS$CALL_HANDL",         0x80000010, 0L },
{ "SYS$CALL_HANDL_JACKET",  0x7FFEE568, 0L },
{ "SYS$CANCEL",             0x7FFEDE60, 0L },
{ "SYS$CANCEL_SELECTIVE",   0x7FFEE5E8, 0L },
{ "SYS$CANEVTAST",          0x7FFEE3B0, 0L },
{ "SYS$CANEXH",             0x7FFEE0C0, 0L },
{ "SYS$CANRNH",             0x7FFEE528, 0L },
{ "SYS$CANRUH",             0x7FFEE650, 0L },
{ "SYS$CANTIM",             0x7FFEDE68, 0L },
{ "SYS$CANWAK",             0x7FFEDE70, 0L },
{ "SYS$CFS_SERVICE",        0x7FFEE5F8, 0L },
{ "SYS$CHECK_AUDIT",        0x7FFEE800, 0L },
{ "SYS$CHECK_PRIVILEGE",    0x7FFEE8C8, 0L },
{ "SYS$CHECK_PRIVILEGE2_2", 0x7FFEE8D8, 0L },
{ "SYS$CHECK_PRIVILEGE2_3", 0x7FFEE8E0, 0L },
{ "SYS$CHECK_PRIVILEGEW",   0x7FFEE8D0, 0L },
{ "SYS$CHKPRO",             0x7FFEE4E0, 0L },
{ "SYS$CLI",                0x7FFEDE18, 0L },
{ "SYS$CLOSE",              0x7FFEE1B8, 0L },
{ "SYS$CLRAST",             0x7FFEE108, 0L },
{ "SYS$CLRAST_2",           0x7FFEE110, 0L },
{ "SYS$CLRCLUEVT",          0x7FFEE820, 0L },
{ "SYS$CLREF",              0x7FFEDE98, 0L },
{ "SYS$CLRPAR",             0x7FFEDE80, 0L },
{ "SYS$CMEXEC",             0x7FFEDE88, 0L },
{ "SYS$CMKRNL",             0x7FFEDE90, 0L },
{ "SYS$CNTREG",             0x7FFEDEA0, 0L },
{ "SYS$COMMIT_RU",          0x7FFEE638, 0L },
{ "SYS$CONNECT",            0x7FFEE1C0, 0L },
{ "SYS$CREATE",             0x7FFEE1C8, 0L },
{ "SYS$CREATE_BRANCH",      0x7FFEE840, 0L },
{ "SYS$CREATE_BRANCHW",     0x7FFEE848, 0L },
{ "SYS$CREATE_BRANCHW_1",   0x7FFEE850, 0L },
{ "SYS$CREATE_BUFOBJ",      0x7FFEE550, 0L },
{ "SYS$CREATE_UID",         0x7FFEE788, 0L },
{ "SYS$CRELNM",             0x7FFEE480, 0L },
{ "SYS$CRELNT",             0x7FFEE478, 0L },
{ "SYS$CRELOG",             0x7FFEDEB0, 0L },
{ "SYS$CREMBX",             0x7FFEDEB8, 0L },
{ "SYS$CREPRC",             0x7FFEDEC0, 0L },
{ "SYS$CRETVA",             0x7FFEDEC8, 0L },
{ "SYS$CRMPSC",             0x7FFEDE78, 0L },
{ "SYS$DACEFC",             0x7FFEDED0, 0L },
{ "SYS$DALLOC",             0x7FFEDED8, 0L },
{ "SYS$DASSGN",             0x7FFEDEE0, 0L },
{ "SYS$DCLAST",             0x7FFEDEE8, 0L },
{ "SYS$DCLCMH",             0x7FFEE0A0, 0L },
{ "SYS$DCLEVT",             0x7FFEE388, 0L },
{ "SYS$DCLEXH",             0x7FFEDEF0, 0L },
{ "SYS$DCLRNH",             0x7FFEE520, 0L },
{ "SYS$DCLRUH",             0x7FFEE648, 0L },
{ "SYS$DECLARE_RM",         0x7FFEE6E8, 0L },
{ "SYS$DECLARE_RMW",        0x7FFEE740, 0L },
{ "SYS$DELETE",             0x7FFEE168, 0L },
{ "SYS$DELETE_BUFOBJ",      0x7FFEE558, 0L },
{ "SYS$DELLNM",             0x7FFEE488, 0L },
{ "SYS$DELLOG",             0x7FFEDEF8, 0L },
{ "SYS$DELMBX",             0x7FFEDF00, 0L },
{ "SYS$DELPRC",             0x7FFEDF08, 0L },
{ "SYS$DELTVA",             0x7FFEDF10, 0L },
{ "SYS$DEQ",                0x7FFEE3C8, 0L },
{ "SYS$DERLMB",             0x7FFEE0B8, 0L },
{ "SYS$DEVICE_SCAN",        0x7FFEE518, 0L },
{ "SYS$DGBLSC",             0x7FFEDF18, 0L },
{ "SYS$DIAGNOSE",           0x7FFEE560, 0L },
{ "SYS$DISABLE_VP_USE",     0x7FFEE7B0, 0L },
{ "SYS$DISABLE_VP_USE_INT", 0x7FFEE7B8, 0L },
{ "SYS$DISCONNECT",         0x7FFEE1D0, 0L },
{ "SYS$DISPLAY",            0x7FFEE1D8, 0L },
{ "SYS$DLCDNP",             0x7FFEDF20, 0L },
{ "SYS$DLCEFC",             0x7FFEDF28, 0L },
{ "SYS$DNS",                0x7FFEE5A0, 0L },
{ "SYS$DNSW",               0x7FFEE5A8, 0L },
{ "SYS$EMAA",               0x7FFEE790, 0L },
{ "SYS$ENABLE_VP_USE",      0x7FFEE7A0, 0L },
{ "SYS$ENABLE_VP_USE_INT",  0x7FFEE7A8, 0L },
{ "SYS$END_BRANCH",         0x7FFEE5B0, 0L },
{ "SYS$END_BRANCHW",        0x7FFEE5B8, 0L },
{ "SYS$END_BRANCHW_2",      0x7FFEE5C0, 0L },
{ "SYS$END_RU",             0x7FFEE678, 0L },
{ "SYS$END_RU_2",           0x7FFEE680, 0L },
{ "SYS$END_TRANS",          0x7FFEE6D8, 0L },
{ "SYS$END_TRANSW",         0x7FFEE730, 0L },
{ "SYS$ENQ",                0x7FFEE3C0, 0L },
{ "SYS$ENQW",               0x7FFEE3D0, 0L },
{ "SYS$ENQW_2",             0x7FFEE3D8, 0L },
{ "SYS$ENQW_3",             0x7FFEE3E0, 0L },
{ "SYS$ENTER",              0x7FFEE228, 0L },
{ "SYS$ERAPAT",             0x7FFEE470, 0L },
{ "SYS$ERASE",              0x7FFEE1E0, 0L },
{ "SYS$EVDPOSTEVENT",       0x7FFEE798, 0L },
{ "SYS$EXCMSG",             0x7FFEE0E8, 0L },
{ "SYS$EXIT",               0x7FFEDF40, 0L },
{ "SYS$EXPREG",             0x7FFEDF48, 0L },
{ "SYS$EXTEND",             0x7FFEE1E8, 0L },
{ "SYS$EXTRNH",             0x7FFEE530, 0L },
{ "SYS$FAO",                0x7FFEDF50, 0L },
{ "SYS$FAOL",               0x7FFEDF58, 0L },
{ "SYS$FILESCAN",           0x7FFEE278, 0L },
{ "SYS$FIND",               0x7FFEE170, 0L },
{ "SYS$FINISH_RDB",         0x7FFEE4B8, 0L },
{ "SYS$FINISH_RMOP",        0x7FFEE700, 0L },
{ "SYS$FINISH_RMOPW",       0x7FFEE758, 0L },
{ "SYS$FLUSH",              0x7FFEE1F0, 0L },
{ "SYS$FORCEX",             0x7FFEDF60, 0L },
{ "SYS$FORGET_RM",          0x7FFEE6F0, 0L },
{ "SYS$FORGET_RMW",         0x7FFEE748, 0L },
{ "SYS$FORGE_WORD",         0x7FFEE900, 0L },
{ "SYS$FREE",               0x7FFEE178, 0L },
{ "SYS$GET",                0x7FFEE180, 0L },
{ "SYS$GETCHN",             0x7FFEE0C8, 0L },
{ "SYS$GETDEV",             0x7FFEE0D0, 0L },
{ "SYS$GETDVI",             0x7FFEE410, 0L },
{ "SYS$GETDVIW",            0x7FFEE418, 0L },
{ "SYS$GETEVI",             0x7FFEE3B8, 0L },
{ "SYS$GETJPI",             0x7FFEE0D8, 0L },
{ "SYS$GETJPIW",            0x7FFEE420, 0L },
{ "SYS$GETJPIW_2",          0x7FFEE428, 0L },
{ "SYS$GETLKI",             0x7FFEE498, 0L },
{ "SYS$GETLKIW",            0x7FFEE4A0, 0L },
{ "SYS$GETLKIW_2",          0x7FFEE4A8, 0L },
{ "SYS$GETLUI",             0x7FFEE690, 0L },
{ "SYS$GETMSG",             0x7FFEE0B0, 0L },
{ "SYS$GETPTI",             0x7FFEDEA8, 0L },
{ "SYS$GETQUI",             0x7FFEE4F8, 0L },
{ "SYS$GETQUIW",            0x7FFEE500, 0L },
{ "SYS$GETQUIW_2",          0x7FFEE508, 0L },
{ "SYS$GETSECI",            0x7FFEE6B8, 0L },
{ "SYS$GETSYI",             0x7FFEE3F8, 0L },
{ "SYS$GETSYIW",            0x7FFEE430, 0L },
{ "SYS$GETTIM",             0x7FFEDF78, 0L },
{ "SYS$GETUTC",             0x7FFEE578, 0L },
{ "SYS$GET_DEFAULT_TRANS", 0x7FFEE858, 0L },
{ "SYS$GET_RUID", 0x7FFEE670, 0L },
{ "SYS$GET_SECURITY", 0x7FFEE8F0, 0L },
{ "SYS$GL_ASTRET", 0x7FFEE110, 0L },
{ "SYS$GL_COMMON", 0x7FFEE114, 0L },
{ "SYS$GRANTID", 0x7FFEE4D0, 0L },
{ "SYS$GRANT_LICENSE", 0x7FFEE698, 0L },
{ "SYS$HASH_PASSWORD", 0x7FFEE538, 0L },
{ "SYS$HIBER", 0x7FFEDF88, 0L },
{ "SYS$IDTOASC", 0x7FFEE4C0, 0L },
{ "SYS$IMGACT", 0x7FFEDF90, 0L },
{ "SYS$IMGFIX", 0x7FFEE400, 0L },
{ "SYS$IMGFIX_2", 0x7FFEE408, 0L },
{ "SYS$IMGSTA", 0x7FFEDF68, 0L },
{ "SYS$IPC", 0x7FFEE6C8, 0L },
{ "SYS$IPCW", 0x7FFEE770, 0L },
{ "SYS$IPCW_2", 0x7FFEE778, 0L },
{ "SYS$IPCW_3", 0x7FFEE780, 0L },
{ "SYS$JOIN_RM", 0x7FFEE6F8, 0L },
{ "SYS$JOIN_RMW", 0x7FFEE750, 0L },
{ "SYS$JOIN_RU", 0x7FFEE658, 0L },
{ "SYS$LCKPAG", 0x7FFEDF98, 0L },
{ "SYS$LKWSET", 0x7FFEDFA0, 0L },
{ "SYS$LOOKUP_LICENSE", 0x7FFEE6C0, 0L },
{ "SYS$MAKE_REF", 0x7FFEE540, 0L },
{ "SYS$MGBLSC", 0x7FFEDFA8, 0L },
{ "SYS$MODIFY", 0x7FFEE1F8, 0L },
{ "SYS$MTACCESS", 0x7FFEE688, 0L },
{ "SYS$NETWORK_LOGIN", 0x7FFEE828, 0L },
{ "SYS$NUMTIM", 0x7FFEDFB8, 0L },
{ "SYS$NUMUTC", 0x7FFEE580, 0L },
{ "SYS$NXTVOL", 0x7FFEE200, 0L },
{ "SYS$OPEN", 0x7FFEE208, 0L },
{ "SYS$PARSE", 0x7FFEE230, 0L },
{ "SYS$POSIX_FORK_CONTROL", 0x7FFEE5E0, 0L },
{ "SYS$POSIX_IOSERVICE", 0x7FFEE5D8, 0L },
{ "SYS$POSIX_SERVICE", 0x7FFEE5D0, 0L },
{ "SYS$POSIX_UMSERVICE", 0x7FFEE5F0, 0L },
{ "SYS$PRCTERM", 0x7FFEE818, 0L },
{ "SYS$PREPARE_RU", 0x7FFEE630, 0L },
{ "SYS$PROCESS_SCAN", 0x7FFEE510, 0L },
{ "SYS$PURGWS", 0x7FFEDFB0, 0L },
{ "SYS$PUT", 0x7FFEE188, 0L },
{ "SYS$PUTMSG", 0x7FFEE0E0, 0L },
{ "SYS$QIO", 0x7FFEDFC8, 0L },
{ "SYS$QIOW", 0x7FFEDE00, 0L },
{ "SYS$QIOW_2", 0x7FFEDE08, 0L },
{ "SYS$QIOW_3", 0x7FFEDE10, 0L },
{ "SYS$READ", 0x7FFEE190, 0L },
{ "SYS$READEF", 0x7FFEDFD0, 0L },
{ "SYS$RECOVER", 0x7FFEE860, 0L },
{ "SYS$RECOVERW", 0x7FFEE868, 0L },
{ "SYS$RECOVERW_1", 0x7FFEE870, 0L },
{ "SYS$RELEASE", 0x7FFEE198, 0L },
{ "SYS$RELEASE_LICENSE", 0x7FFEE6A0, 0L },
{ "SYS$RELEASE_VP", 0x7FFEE7C0, 0L },
{ "SYS$RELEASE_VP_INT", 0x7FFEE7C8, 0L },
{ "SYS$REMOVE", 0x7FFEE238, 0L },
{ "SYS$REMOVE_REF", 0x7FFEE548, 0L },
{ "SYS$RENAME", 0x7FFEE240, 0L },
{ "SYS$REPORT_EVENT", 0x7FFEE808, 0L },
{ "SYS$RESCHED", 0x7FFEE6B0, 0L },
{ "SYS$RESTORE_VP_EXCEPTION", 0x7FFEE7D0, 0L },
{ "SYS$RESTORE_VP_EXC_INT", 0x7FFEE7D8, 0L },
{ "SYS$RESTORE_VP_STATE", 0x7FFEE7F0, 0L },
{ "SYS$RESUME", 0x7FFEDFD8, 0L },
{ "SYS$REVOKID", 0x7FFEE4D8, 0L },
{ "SYS$REWIND", 0x7FFEE210, 0L },
{ "SYS$RMSRUNDWN", 0x7FFEE268, 0L },
{ "SYS$RUNDOWN_RU", 0x7FFEE668, 0L },
{ "SYS$RUNDWN", 0x7FFEDFE0, 0L },
{ "SYS$SAVE_VP_EXCEPTION", 0x7FFEE7E0, 0L },
{ "SYS$SAVE_VP_EXC_INT", 0x7FFEE7E8, 0L },
{ "SYS$SCHDWK", 0x7FFEDFF0, 0L },
{ "SYS$SCHED", 0x7FFEE7F8, 0L },
{ "SYS$SEARCH", 0x7FFEE248, 0L },
{ "SYS$SETAST", 0x7FFEDFF8, 0L },
{ "SYS$SETCLUEVT", 0x7FFEE810, 0L },
{ "SYS$SETDDIR", 0x7FFEE250, 0L },
{ "SYS$SETDFPROT", 0x7FFEE258, 0L },
{ "SYS$SETEF", 0x7FFEE000, 0L },
{ "SYS$SETEVTAST", 0x7FFEE390, 0L },
{ "SYS$SETEVTASTW", 0x7FFEE398, 0L },
{ "SYS$SETEVTASTW_2", 0x7FFEE3A0, 0L },
{ "SYS$SETEVTASTW_3", 0x7FFEE3A8, 0L },
{ "SYS$SETEXV", 0x7FFEE008, 0L },
{ "SYS$SETIME", 0x7FFEE0F8, 0L },
{ "SYS$SETIMR", 0x7FFEE020, 0L },
{ "SYS$SETPFM", 0x7FFEE0A8, 0L },
{ "SYS$SETPRA", 0x7FFEE018, 0L },
{ "SYS$SETPRI", 0x7FFEE028, 0L },
{ "SYS$SETPRN", 0x7FFEE010, 0L },
{ "SYS$SETPRT", 0x7FFEE030, 0L },
{ "SYS$SETPRV", 0x7FFEE100, 0L },
{ "SYS$SETRWM", 0x7FFEE038, 0L },
{ "SYS$SETSFM", 0x7FFEE040, 0L },
{ "SYS$SETSHLV", 0x7FFEE908, 0L },
{ "SYS$SETSSF", 0x7FFEE3E8, 0L },
{ "SYS$SETSTK", 0x7FFEE3F0, 0L },
{ "SYS$SETSWM", 0x7FFEE048, 0L },
{ "SYS$SET_DEFAULT_TRANS", 0x7FFEE878, 0L },
{ "SYS$SET_DEFAULT_TRANSW", 0x7FFEE880, 0L },
{ "SYS$SET_DEF_TRAN_DUMMY", 0x7FFEE888, 0L },
{ "SYS$SET_RESOURCE_DOMAIN", 0x7FFEE8F8, 0L },
{ "SYS$SET_SECURITY", 0x7FFEE8E8, 0L },
{ "SYS$SIGPRC", 0x7FFEE6A8, 0L },
{ "SYS$SNDACC", 0x7FFEE0F0, 0L },
{ "SYS$SNDERR", 0x7FFEDF38, 0L },
{ "SYS$SNDJBC", 0x7FFEDF70, 0L },
{ "SYS$SNDJBCW", 0x7FFEE438, 0L },
{ "SYS$SNDOPR", 0x7FFEDFC0, 0L },
{ "SYS$SNDSMB", 0x7FFEDFE8, 0L },
{ "SYS$SPACE", 0x7FFEE218, 0L },
{ "SYS$SPARE_VECTOR_1", 0x7FFEE270, 0L },
{ "SYS$SRCHANDLER", 0x7FFEE118, 0L },
{ "SYS$SSVEXC", 0x7FFEE260, 0L },
{ "SYS$SS_VECTOR_DUMMY_3_1", 0x7FFEE5C8, 0L },
{ "SYS$SS_VECTOR_DUMMY_3_10", 0x7FFEE610, 0L },
{ "SYS$SS_VECTOR_DUMMY_3_11", 0x7FFEE618, 0L },
{ "SYS$SS_VECTOR_DUMMY_3_12", 0x7FFEE620, 0L },
{ "SYS$SS_VECTOR_DUMMY_3_8", 0x7FFEE600, 0L },
{ "SYS$SS_VECTOR_DUMMY_3_9", 0x7FFEE608, 0L },
{ "SYS$SS_VECTOR_SPARE", 0x7FFEE918, 0L },
{ "SYS$START_BRANCH", 0x7FFEE710, 0L },
{ "SYS$START_BRANCHW", 0x7FFEE768, 0L },
{ "SYS$START_RU", 0x7FFEE628, 0L },
{ "SYS$START_TRANS", 0x7FFEE6D0, 0L },
{ "SYS$START_TRANSW", 0x7FFEE718, 0L },
{ "SYS$START_TRANSW_2", 0x7FFEE720, 0L },
{ "SYS$START_TRANSW_3", 0x7FFEE728, 0L },
{ "SYS$SUBSYSTEM", 0x7FFEE598, 0L },
{ "SYS$SUSPND", 0x7FFEE050, 0L },
{ "SYS$SYNCH", 0x7FFEE440, 0L },
{ "SYS$SYNCH_INT", 0x7FFEE910, 0L },
{ "SYS$TIMCON", 0x7FFEE570, 0L },
{ "SYS$TRANS_EVENT", 0x7FFEE890, 0L },
{ "SYS$TRANS_EVENTW", 0x7FFEE898, 0L },
{ "SYS$TRANS_EVENTW_1", 0x7FFEE8A0, 0L },
{ "SYS$TRNLNM", 0x7FFEE490, 0L },
{ "SYS$TRNLOG", 0x7FFEE058, 0L },
{ "SYS$TRUNCATE", 0x7FFEE220, 0L },
{ "SYS$TSTCLUEVT", 0x7FFEE830, 0L },
{ "SYS$ULKPAG", 0x7FFEE060, 0L },
{ "SYS$ULWSET", 0x7FFEE068, 0L },
{ "SYS$UNJOIN_RU", 0x7FFEE660, 0L },
{ "SYS$UNWIND", 0x7FFEE070, 0L },
{ "SYS$UPDATE", 0x7FFEE1A0, 0L },
{ "SYS$UPDSEC", 0x7FFEDF30, 0L },
{ "SYS$UPDSECW", 0x7FFEDF80, 0L },
{ "SYS$WAIT", 0x7FFEE1A8, 0L },
{ "SYS$WAITFR", 0x7FFEE078, 0L },
{ "SYS$WAIT_FORM", 0x7FFEE120, 0L },
{ "SYS$WAKE", 0x7FFEE080, 0L },
{ "SYS$WFLAND", 0x7FFEE088, 0L },
{ "SYS$WFLOR", 0x7FFEE090, 0L },
{ "SYS$WRITE", 0x7FFEE1B0, 0L },
{ 0L, 0L, 0L }};


/*
 *  Called by XFC #7A, which invokes a system service.
 */

long call_service( LONGWORD pc )
{
    int n;
    CALLV callv;
    LONGWORD rc, argc, size, * argv;

    char msg[ 256 ], mbuff[ 10 ];

    /*
     *  Figure out which service it is.
     */

    for( n = 0; n < service_count; n++ ) {

        if( p1_vector[ n ].addr == pc ) 
            break;
    }

    if( n >= service_count ) {
        printf( "Attempt to execute at non-existant P1 vector %08lX\n", pc );
        return VAX_NOSERVICE;
    }


    callv = p1_vector[ n ].service;

    strcpy( msg, p1_vector[ n ].name );
    strcat( msg, "( " );

/*
 *  Find out how many arguments there are
 */

    rc = load_memory( vax-> AP, ( void * ) &argc, 4 );
    if( rc )
        return rc;

/*
 *  Allocate an argument array natively for them.
 */

    size = sizeof( LONGWORD ) * argc;
    argv = ( LONGWORD * ) getmem( size );
    if( argv == 0L )
        return VAX_MEM;

/*
 *  Get the arguments locally in native format
 */

    for( n = 0; n < argc; n++ ) {
    
        rc = load_memory( ( vax-> AP ) + (( n + 1 ) * 4 ), ( void * ) &( argv[ n ]), 4 );
        if( rc )
            return rc;

        if( n > 0 )
            strcat( msg, ", " );
        sprintf( mbuff, "%08lX", argv[ n ] );
        strcat( msg, mbuff );
        
    }
    strcat( msg, n ? " )" : ")" );

/*
 *  If at this point we know there's no place to go, give it up.
 */

    if( callv == 0L ) {
        printf( "Unimplemented native service for %s\n", msg );
        return VAX_NOSERVICE;
    }

    rc = (*callv)( argc, argv );

    if( vax-> debug & DBG_SERVICES ) {
        sprintf( mbuff, "%08lX", rc );
        strcat( msg, ", returns " );
        strcat( msg, mbuff );
        printf( "DEBUG(SERVICES): %s\n", msg );
    }
    
    vax-> R0 = rc;
    freemem( argv );

    return VAX_OK;
}


/*
 *  Initialize the P1 space for the current micro-kernel
 *  based system.  Fill in the supported service handlers
 *  where known.
 */

long p1_init()
{
    LONGWORD setpte_multiple( char ** P );
    long n, min, max;
    long rc;
    LONGWORD addr;
    short mask;
    char byte;
    int saved_mode;
    char buff[ 64 ], *bp;
    
    saved_mode = vax-> pslw.cur_mod;
    set_mode_stack( 0 );
    
    max = 0;
    min = 0x7FFFFFFF;

    mask = 0x0;          /* Procedure mask is empty */

    for( n = 0; n < 1000; n++ ) {

        if( p1_vector[ n ].name == 0L )
            break;

        addr = p1_vector[ n ].addr;

        rc = set_symbol_direct( p1_vector[ n ].name, addr );
        if( rc )
            return rc;

        vax-> console.last_symbol-> flags |= 
            SYM_ENTRY | SYM_PERMANENT;

        /*  Write the procedure entry mask to memory */

        rc = store_memory( addr, ( void * ) &mask, 2 );
        if( rc )
            return rc;


        /*  Write the XFC opcode */

        byte = 0xFC;
        rc = store_memory( addr+2, ( void * ) &byte, 1 );
        if( rc )
            return rc;


        /*  Write the XFC$P1VECTOR selector code */

        byte = 0x7A;
        rc = store_memory( addr+3, ( void * ) &byte, 1 );
        if( rc )
            return rc;


        /*  Write the RET instruction */

        byte = 0x04;
        rc = store_memory( addr+4, ( void * ) &byte, 1 );
        if( rc )
            return rc;



        /*  Update the min and max values */

        if( ( unsigned long ) p1_vector[ n ].addr >= 0x80000000UL )
            continue;

        if( p1_vector[ n ].addr > max )
            max = p1_vector[ n ].addr;

        if( p1_vector[ n ].addr < min )
            min = p1_vector[ n ].addr;

    }

    service_count = n;

    set_symbol_direct( "EXE$P1_VECTOR_BASE", min );
    set_symbol_direct( "EXE$P1_VECTOR_END",  max );
    
    declare_services();

    bp = buff;
    strcpy( bp, "EXE$P1_VECTOR_BASE TO EXE$P1_VECTOR_END PROT=PTE$K_UR" );
    
    setpte_multiple( &bp );
    
    set_mode_stack( saved_mode );
    
    return VAX_OK;
}

   
    
/*
 *  Declare a handler for a system service.
 */

long declare_service( char * name, CALLV handler )
{

    int n;

    for( n = 0; n < service_count; n++ ) {
        if( strcmp( name, p1_vector[ n ].name ) == 0 ) {
            p1_vector[ n ].service = handler;
            return VAX_OK;
        }
    }

    return VAX_NOSERVICE;
}


/*
 *  Declare all services we know about
 */

void declare_services( void )
{

    declare_service( "SYS$CLREF",           sys_clref );
    declare_service( "SYS$SETEF",           sys_setef );
    declare_service( "SYS$READEF",          sys_readef );
    declare_service( "SYS$EXPREG",          sys_expreg );
    declare_service( "SYS$TRNLNM",          sys_trnlnm );
    declare_service( "SYS$DCLEXH",          sys_dclexh );

}

