mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-11-06 14:01:35 +08:00
Resync new repository with old repo r5166
git-svn-id: http://svn.code.sf.net/p/nuttx/code/trunk@5153 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
############################################################################
|
||||
# insn16/prun/Make.defs
|
||||
# NuttX runtime makefile fragment
|
||||
#
|
||||
# Copyright (C) 2008 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
PRUN_ASRCS =
|
||||
PRUN_CSRCS = pload.c pexec.c
|
||||
@@ -0,0 +1,87 @@
|
||||
############################################################################
|
||||
# insn16/prun/Makefile
|
||||
# Host system makefile
|
||||
#
|
||||
# Copyright (C) 2008 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
############################################################################
|
||||
#
|
||||
# Directories
|
||||
#
|
||||
PRUNDIR = ${shell pwd}
|
||||
INSNDIR = $(PRUNDIR)/..
|
||||
PASCAL = $(PRUNDIR)/../..
|
||||
|
||||
include $(PASCAL)/Make.config
|
||||
include $(PASCAL)/Make.defs
|
||||
|
||||
INCDIR = $(PASCAL)/include
|
||||
LIBDIR = $(PASCAL)/lib
|
||||
BINDIR = $(PASCAL)/bin16
|
||||
|
||||
#
|
||||
# Tools
|
||||
#
|
||||
EXTRA_INCLUDES = -I$(INSNDIR)/include
|
||||
INCLUDES += $(EXTRA_INCLUDES)
|
||||
CFLAGS += $(EXTRA_INCLUDES)
|
||||
|
||||
#
|
||||
# Objects and targets
|
||||
#
|
||||
RUNSRCS = prun.c pdbg.c pload.c pexec.c
|
||||
RUNOBJS = $(RUNSRCS:.c=.o)
|
||||
|
||||
OBJS = $(RUNOBJS)
|
||||
|
||||
all: prun
|
||||
.PHONY: all prun clean
|
||||
|
||||
$(OBJS): %.o: %.c
|
||||
@$(CC) -c $(CFLAGS) $< -o $@
|
||||
|
||||
check_libs:
|
||||
@if [ ! -f $(LIBDIR)/libpoff.a ] ; then \
|
||||
echo "$(LIBDIR)/libpoff.a does not exist" ; \
|
||||
exit 1 ; \
|
||||
fi
|
||||
@if [ ! -f $(LIBDIR)/libpas.a ] ; then \
|
||||
echo "$(LIBDIR)/libpas.a does not exist" ; \
|
||||
exit 1 ; \
|
||||
fi
|
||||
|
||||
$(BINDIR)/prun: check_libs $(RUNOBJS)
|
||||
@$(CC) -o $@ $(LDFLAGS) $(RUNOBJS) -linsn -lpoff -lpas -lm
|
||||
|
||||
prun: $(BINDIR)/prun
|
||||
|
||||
clean:
|
||||
$(RM) prun *.o core *~
|
||||
@@ -0,0 +1,748 @@
|
||||
/**********************************************************************
|
||||
* pdbg.c
|
||||
* P-Code Debugger
|
||||
*
|
||||
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
/**********************************************************************
|
||||
* Included Files
|
||||
**********************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "keywords.h"
|
||||
#include "pdefs.h"
|
||||
#include "podefs.h"
|
||||
#include "pinsn16.h"
|
||||
#include "pxdefs.h"
|
||||
#include "pedefs.h"
|
||||
|
||||
#include "paslib.h"
|
||||
#include "pinsn.h"
|
||||
#include "pexec.h"
|
||||
#include "pdbg.h"
|
||||
|
||||
/**********************************************************************
|
||||
* Pre-processor Definitions
|
||||
**********************************************************************/
|
||||
|
||||
#define TRACE_ARRAY_SIZE 16
|
||||
#define MAX_BREAK_POINTS 8
|
||||
#define DISPLAY_STACK_SIZE 16
|
||||
#define DISPLAY_INST_SIZE 16
|
||||
|
||||
/**********************************************************************
|
||||
* Private Type Definitions
|
||||
**********************************************************************/
|
||||
|
||||
enum command_e
|
||||
{
|
||||
eCMD_NONE = 0,
|
||||
eCMD_RESET,
|
||||
eCMD_RUN,
|
||||
eCMD_STEP,
|
||||
eCMD_NEXT,
|
||||
eCMD_GO,
|
||||
eCMD_BS,
|
||||
eCMD_BC,
|
||||
eCMD_DP,
|
||||
eCMD_DT,
|
||||
eCMD_DS,
|
||||
eCMD_DI,
|
||||
eCMD_DB,
|
||||
eCMD_HELP,
|
||||
eCMD_QUIT
|
||||
};
|
||||
|
||||
struct trace_s
|
||||
{
|
||||
paddr_t pc;
|
||||
paddr_t sp;
|
||||
ustack_t tos;
|
||||
};
|
||||
typedef struct trace_s trace_t;
|
||||
|
||||
/**********************************************************************
|
||||
* Private Constant Data
|
||||
**********************************************************************/
|
||||
|
||||
/**********************************************************************
|
||||
* Private Data
|
||||
**********************************************************************/
|
||||
|
||||
static enum command_e g_lastcmd = eCMD_NONE;
|
||||
static uint32_t g_lastvalue;
|
||||
|
||||
/**********************************************************************
|
||||
* Private Function Prototypes
|
||||
**********************************************************************/
|
||||
|
||||
static void pdbg_showcommands(void);
|
||||
static void pdbg_execcommand(struct pexec_s *st, enum command_e cmd, uint32_t value);
|
||||
static int32_t pdbg_readdecimal(char *ptr);
|
||||
static int32_t pdbg_readhex(char *ptr, int32_t defaultvalue);
|
||||
static void pdbg_programstatus(struct pexec_s *st);
|
||||
static paddr_t pdbg_printpcode(struct pexec_s *st, paddr_t pc, int16_t nitems);
|
||||
static paddr_t pdbg_printstack(struct pexec_s *st, paddr_t sp, int16_t nitems);
|
||||
static void pdbg_printregisters(struct pexec_s *st);
|
||||
static void pdbg_printtracearray(struct pexec_s *st);
|
||||
static void pdbg_addbreakpoint(paddr_t pc);
|
||||
static void pdbg_deletebreakpoint(int16_t bpno);
|
||||
static void pdbg_printbreakpoints(struct pexec_s *st);
|
||||
static void pdbg_checkbreakpoint(struct pexec_s *st);
|
||||
static void pdbg_initdebugger(void);
|
||||
static void pdbg_debugpcode(struct pexec_s *st);
|
||||
|
||||
/**********************************************************************
|
||||
* Global Variables
|
||||
**********************************************************************/
|
||||
|
||||
/**********************************************************************
|
||||
* Private Variables
|
||||
**********************************************************************/
|
||||
|
||||
/* Debugging variables */
|
||||
|
||||
static trace_t g_tracearray[TRACE_ARRAY_SIZE];
|
||||
/* Holds execution histor */
|
||||
static uint16_t g_tracendx;
|
||||
/* This is the index into the circular g_tracearray */
|
||||
static uint16_t g_ntracepoints;
|
||||
/* This is the number of valid enties in g_tracearray */
|
||||
static paddr_t g_breakpoint[MAX_BREAK_POINTS];
|
||||
/* Contains address associated with all active */
|
||||
/* break points. */
|
||||
static paddr_t g_untilpoint;
|
||||
/* The 'g_untilpoint' is a temporary breakpoint */
|
||||
static uint16_t g_nbreakpoints;
|
||||
/* Number of items in breakPoints[] */
|
||||
static paddr_t g_displayloc;
|
||||
/* P-code display location display */
|
||||
static bool g_bstopexecution;
|
||||
/* true means to stop program execution */
|
||||
|
||||
/* I/O variables */
|
||||
|
||||
static char g_inline[LINE_SIZE+1];
|
||||
/* Command line buffer */
|
||||
|
||||
/**********************************************************************
|
||||
* Public Functions
|
||||
**********************************************************************/
|
||||
|
||||
void dbg_run(struct pexec_s *st)
|
||||
{
|
||||
paddr_t pc;
|
||||
int i;
|
||||
|
||||
pdbg_showcommands();
|
||||
pdbg_initdebugger();
|
||||
pdbg_programstatus(st);
|
||||
|
||||
while (true)
|
||||
{
|
||||
printf("CMD: ");
|
||||
(void) fgets(g_inline, LINE_SIZE, stdin);
|
||||
switch (toupper(g_inline[0]))
|
||||
{
|
||||
case 'R' :
|
||||
switch (toupper(g_inline[1])) {
|
||||
case 'E' : /* Reset */
|
||||
pdbg_execcommand(st, eCMD_RESET, 0);
|
||||
break;
|
||||
case 'U' : /* Run */
|
||||
pdbg_execcommand(st, eCMD_RUN, 0);
|
||||
break;
|
||||
default :
|
||||
printf("Unrecognized Command\n");
|
||||
pdbg_execcommand(st, eCMD_HELP, 0);
|
||||
break;
|
||||
} /* end switch */
|
||||
break;
|
||||
case 'S' : /* Single Step (into) */
|
||||
pdbg_execcommand(st, eCMD_STEP, 0);
|
||||
break;
|
||||
case 'N' : /* Single Step (over) */
|
||||
pdbg_execcommand(st, eCMD_NEXT, 0);
|
||||
break;
|
||||
case 'G' : /* Go */
|
||||
pdbg_execcommand(st, eCMD_GO, 0);
|
||||
break;
|
||||
case 'B' :
|
||||
switch (toupper(g_inline[1])) {
|
||||
case 'S' : /* Set Breakpoint */
|
||||
pc = pdbg_readhex(&g_inline[2], st->pc);
|
||||
pdbg_execcommand(st, eCMD_BS, pc);
|
||||
break;
|
||||
case 'C' : /* Clear Breakpoint */
|
||||
i = pdbg_readdecimal(&g_inline[2]);
|
||||
pdbg_execcommand(st, eCMD_BC, i);
|
||||
break;
|
||||
default :
|
||||
printf("Unrecognized Command\n");
|
||||
pdbg_execcommand(st, eCMD_HELP, 0);
|
||||
break;
|
||||
} /* end switch */
|
||||
break;
|
||||
case 'D' :
|
||||
switch (toupper(g_inline[1])) {
|
||||
case 'P' : /* Display Program Status */
|
||||
pdbg_execcommand(st, eCMD_DP, 0);
|
||||
break;
|
||||
case 'T' : /* Display Program Trace */
|
||||
pdbg_execcommand(st, eCMD_DT, 0);
|
||||
break;
|
||||
case 'S' : /* Display Stack */
|
||||
pc = pdbg_readhex(&g_inline[2], st->sp);
|
||||
pdbg_execcommand(st, eCMD_DS, pc);
|
||||
break;
|
||||
case 'I' : /* Display Instructions */
|
||||
pc = pdbg_readhex(&g_inline[2], st->pc);
|
||||
pdbg_execcommand(st, eCMD_DI, pc);
|
||||
break;
|
||||
case 'B' : /* Display Breakpoints */
|
||||
pdbg_execcommand(st, eCMD_DB, pc);
|
||||
break;
|
||||
default :
|
||||
printf("Unrecognized Command\n");
|
||||
pdbg_execcommand(st, eCMD_HELP, 0);
|
||||
break;
|
||||
} /* end switch */
|
||||
break;
|
||||
case 'Q' : /* Quit */
|
||||
pdbg_execcommand(st, eCMD_QUIT, pc);
|
||||
break;
|
||||
case 'H' : /* Help */
|
||||
case '?' :
|
||||
pdbg_execcommand(st, eCMD_HELP, 0);
|
||||
break;
|
||||
case '\0' : /* Repeat last command */
|
||||
case '\n' : /* Repeat last command */
|
||||
pdbg_execcommand(st, g_lastcmd, g_lastvalue);
|
||||
break;
|
||||
default :
|
||||
printf("Unrecognized Command\n");
|
||||
pdbg_execcommand(st, eCMD_HELP, 0);
|
||||
break;
|
||||
} /* end switch */
|
||||
} /* end while */
|
||||
|
||||
} /* end pdbg_debugpcodeProgram */
|
||||
|
||||
/**********************************************************************
|
||||
* Private Functions
|
||||
**********************************************************************/
|
||||
/* Show command characters */
|
||||
|
||||
static void pdbg_showcommands(void)
|
||||
{
|
||||
printf("Commands:\n");
|
||||
printf(" RE[set] - Reset\n");
|
||||
printf(" RU[n] - Run\n");
|
||||
printf(" S[tep] - Single Step (Into)\n");
|
||||
printf(" N[ext] - Single Step (Over)\n");
|
||||
printf(" G[o] - Go\n");
|
||||
printf(" BS xxxx - Set Breakpoint\n");
|
||||
printf(" BC n - Clear Breakpoint\n");
|
||||
printf(" DP - Display Program Status\n");
|
||||
printf(" DT - Display Program Trace\n");
|
||||
printf(" DS [xxxx] - Display Stack\n");
|
||||
printf(" DI [xxxx] - Display Instructions\n");
|
||||
printf(" DB - Display Breakpoints\n");
|
||||
printf(" H or ? - Shows this list\n");
|
||||
printf(" Q[uit] - Quit\n");
|
||||
|
||||
} /* end pdbg_showcommands */
|
||||
|
||||
/***********************************************************************/
|
||||
static void pdbg_execcommand(struct pexec_s *st, enum command_e cmd, uint32_t value)
|
||||
{
|
||||
/* Save the command to resuse if the user enters nothing */
|
||||
|
||||
g_lastcmd = cmd;
|
||||
g_lastvalue = value;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case eCMD_NONE: /* Do nothing */
|
||||
break;
|
||||
case eCMD_RESET: /* Reset */
|
||||
pexec_reset(st);
|
||||
pdbg_initdebugger();
|
||||
pdbg_programstatus(st);
|
||||
g_lastcmd = eCMD_NONE;
|
||||
break;
|
||||
case eCMD_RUN: /* Run */
|
||||
pexec_reset(st);
|
||||
pdbg_initdebugger();
|
||||
pdbg_debugpcode(st);
|
||||
pdbg_programstatus(st);
|
||||
break;
|
||||
case eCMD_STEP: /* Single Step (into)*/
|
||||
g_bstopexecution = true;
|
||||
pdbg_debugpcode(st);
|
||||
pdbg_programstatus(st);
|
||||
break;
|
||||
case eCMD_NEXT: /* Single Step (over) */
|
||||
if (st->ispace[st->pc] == oPCAL)
|
||||
{
|
||||
g_bstopexecution = false;
|
||||
g_untilpoint = st->pc + 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_bstopexecution = true;
|
||||
}
|
||||
pdbg_debugpcode(st);
|
||||
g_untilpoint = 0;
|
||||
pdbg_programstatus(st);
|
||||
break;
|
||||
case eCMD_GO: /* Go */
|
||||
g_bstopexecution = false;
|
||||
pdbg_debugpcode(st);
|
||||
pdbg_programstatus(st);
|
||||
break;
|
||||
case eCMD_BS: /* Set Breakpoint */
|
||||
if (g_nbreakpoints >= MAX_BREAK_POINTS)
|
||||
{
|
||||
printf("Too many breakpoints\n");
|
||||
g_lastcmd = eCMD_NONE;
|
||||
}
|
||||
else if (value >= st->maxpc)
|
||||
{
|
||||
printf("Invalid address for breakpoint\n");
|
||||
g_lastcmd = eCMD_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
pdbg_addbreakpoint(value);
|
||||
pdbg_printbreakpoints(st);
|
||||
} /* end else */
|
||||
break;
|
||||
case eCMD_BC: /* Clear Breakpoint */
|
||||
if ((value >= 1) && (value <= g_nbreakpoints))
|
||||
{
|
||||
pdbg_deletebreakpoint(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Invalid breakpoint number\n");
|
||||
g_lastcmd = eCMD_NONE;
|
||||
}
|
||||
pdbg_printbreakpoints(st);
|
||||
break;
|
||||
case eCMD_DP: /* Display Program Status */
|
||||
pdbg_programstatus(st);
|
||||
break;
|
||||
case eCMD_DT: /* Display Program Trace */
|
||||
pdbg_printtracearray(st);
|
||||
break;
|
||||
case eCMD_DS: /* Display Stack */
|
||||
if (value > st->sp)
|
||||
{
|
||||
printf("Invalid stack address\n");
|
||||
g_lastcmd = eCMD_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_lastvalue = pdbg_printstack(st, value, DISPLAY_STACK_SIZE);
|
||||
} /* end else */
|
||||
break;
|
||||
case eCMD_DI: /* Display Instructions */
|
||||
if (value >= st->maxpc)
|
||||
{
|
||||
printf("Invalid instruction address\n");
|
||||
g_lastcmd = eCMD_NONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
g_lastvalue = pdbg_printpcode(st, value, DISPLAY_INST_SIZE);
|
||||
} /* end else */
|
||||
break;
|
||||
case eCMD_DB: /* Display Breakpoints */
|
||||
pdbg_printbreakpoints(st);
|
||||
break;
|
||||
case eCMD_QUIT: /* Quit */
|
||||
printf("Goodbye\n");
|
||||
exit(0);
|
||||
break;
|
||||
case eCMD_HELP: /* Help */
|
||||
default: /* Internal error */
|
||||
pdbg_showcommands();
|
||||
g_lastcmd = eCMD_NONE;
|
||||
break;
|
||||
} /* end switch */
|
||||
|
||||
} /* end pdbg_execcommand */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Read a decimal value from the input string */
|
||||
|
||||
static int32_t pdbg_readdecimal(char *ptr)
|
||||
{
|
||||
int32_t decimal = 0;
|
||||
|
||||
while (!isspace(*ptr)) ptr++;
|
||||
while (isspace(*ptr)) ptr++;
|
||||
for (; ((*ptr >= '0') && (*ptr <= '9')); ptr++)
|
||||
decimal = 10*decimal + (int32_t)*ptr - (int32_t)'0';
|
||||
|
||||
return decimal;
|
||||
|
||||
} /* end pdbg_readdecimal */
|
||||
/***********************************************************************/
|
||||
/* Read a hexadecimal value from the input string */
|
||||
|
||||
static int32_t pdbg_readhex(char *ptr, int32_t defaultvalue)
|
||||
{
|
||||
char c;
|
||||
int32_t hex = 0;
|
||||
bool found = false;
|
||||
|
||||
while (!isspace(*ptr)) ptr++;
|
||||
while (isspace(*ptr)) ptr++;
|
||||
while (true) {
|
||||
|
||||
c = toupper(*ptr);
|
||||
if ((c >= '0') && (c <= '9')) {
|
||||
hex = ((hex << 4) | ((int32_t)c - (int32_t)'0'));
|
||||
found = true;
|
||||
} /* end if */
|
||||
else if ((c >= 'A') && (c <= 'F')) {
|
||||
hex = ((hex << 4) | ((int32_t)c - (int32_t)'A' + 10));
|
||||
found = true;
|
||||
} /* end else if */
|
||||
else {
|
||||
if (found)
|
||||
return hex;
|
||||
else
|
||||
return defaultvalue;
|
||||
} /* end else */
|
||||
ptr++;
|
||||
|
||||
} /* end while */
|
||||
|
||||
} /* end pdbg_readhex */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Print the disassembled P-Code at PC */
|
||||
|
||||
static void pdbg_programstatus(struct pexec_s *st)
|
||||
{
|
||||
(void)pdbg_printpcode(st, st->pc, 1);
|
||||
(void)pdbg_printstack(st, st->sp, 2);
|
||||
pdbg_printregisters(st);
|
||||
|
||||
} /* end pdbg_programstatus */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Print the disassembled P-Code at PC */
|
||||
|
||||
static paddr_t pdbg_printpcode(struct pexec_s *st, paddr_t pc, int16_t nitems)
|
||||
{
|
||||
OPTYPE op;
|
||||
paddr_t opsize;
|
||||
uint8_t *address;
|
||||
|
||||
for (; ((pc < st->maxpc) && (nitems > 0)); nitems--)
|
||||
{
|
||||
address = &st->ispace[pc];
|
||||
|
||||
op.op = *address++;
|
||||
op.arg1 = 0;
|
||||
op.arg2 = 0;
|
||||
opsize = 1;
|
||||
printf("PC:%04x %02x", pc, op.op);
|
||||
|
||||
if ((op.op & o8) != 0)
|
||||
{
|
||||
op.arg1 = *address++;
|
||||
printf("%02x", op.arg1);
|
||||
opsize++;
|
||||
} /* end if */
|
||||
else
|
||||
printf("..");
|
||||
|
||||
if ((op.op & o16) != 0)
|
||||
{
|
||||
op.arg2 = ((*address++) << 8);
|
||||
op.arg2 |= *address++;
|
||||
printf("%04x", op.arg2);
|
||||
opsize += 2;
|
||||
} /* end if */
|
||||
else
|
||||
printf("....");
|
||||
|
||||
/* The disassemble it to stdout */
|
||||
|
||||
printf(" ");
|
||||
insn_DisassemblePCode(stdout, &op);
|
||||
|
||||
/* Get the address of the next P-Code */
|
||||
|
||||
pc += opsize;
|
||||
|
||||
} /* end for */
|
||||
|
||||
return pc;
|
||||
|
||||
} /* end pdbg_printpcode */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Print the stack value at SP */
|
||||
|
||||
static paddr_t pdbg_printstack(struct pexec_s *st, paddr_t sp, int16_t nitems)
|
||||
{
|
||||
int32_t isp;
|
||||
|
||||
if ((st->sp < st->stacksize) && (sp <= st->sp))
|
||||
{
|
||||
isp = BTOISTACK(sp);
|
||||
printf("SP:%04x %04x\n", sp, st->dstack.i[isp]);
|
||||
|
||||
for (isp--, sp -= BPERI, nitems--;
|
||||
((isp >= 0) && (nitems > 0));
|
||||
isp--, sp -= BPERI, nitems--)
|
||||
printf(" %04x %04x\n", sp, st->dstack.i[isp] & 0xffff);
|
||||
} /* end if */
|
||||
else
|
||||
{
|
||||
printf("SP:%04x BAD\n", sp);
|
||||
} /* end else */
|
||||
|
||||
return sp;
|
||||
} /* end pdbg_printstack */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Print the base register */
|
||||
|
||||
static void pdbg_printregisters(struct pexec_s *st)
|
||||
{
|
||||
if (st->fp <= st->sp)
|
||||
printf("FP:%04x ", st->fp);
|
||||
|
||||
printf("CSP:%04x\n", st->csp);
|
||||
|
||||
} /* end pdbg_printregisters */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Print the g_tracearray */
|
||||
|
||||
static void pdbg_printtracearray(struct pexec_s *st)
|
||||
{
|
||||
int nprinted;
|
||||
int index;
|
||||
|
||||
index = g_tracendx + TRACE_ARRAY_SIZE - g_ntracepoints;
|
||||
if (index >= TRACE_ARRAY_SIZE)
|
||||
index -= TRACE_ARRAY_SIZE;
|
||||
|
||||
for (nprinted = 0; nprinted < g_ntracepoints; nprinted++) {
|
||||
|
||||
printf("SP:%04x %04x ",
|
||||
g_tracearray[ index ].sp, g_tracearray[ index ].tos);
|
||||
|
||||
/* Print the instruction executed at this traced address */
|
||||
(void)pdbg_printpcode(st, g_tracearray[ index ].pc, 1);
|
||||
|
||||
/* Index to the next trace entry */
|
||||
if (++index >= TRACE_ARRAY_SIZE)
|
||||
index = 0;
|
||||
|
||||
} /* end for */
|
||||
|
||||
} /* end pdbg_printtracearray */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Add a breakpoint to the breakpoint array */
|
||||
|
||||
static void pdbg_addbreakpoint(paddr_t pc)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Is there room for another breakpoint? */
|
||||
|
||||
if (g_nbreakpoints < MAX_BREAK_POINTS)
|
||||
{
|
||||
/* Yes..Check if the breakpoint already exists */
|
||||
|
||||
for (i = 0; i < g_nbreakpoints; i++)
|
||||
{
|
||||
if (g_breakpoint[i] == pc)
|
||||
{
|
||||
/* It is already set. Return without doing anything */
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* The breakpoint is not already set -- set it */
|
||||
|
||||
g_breakpoint[g_nbreakpoints++] = pc;
|
||||
} /* end if */
|
||||
|
||||
} /* end pdbg_addbreakpoint */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Remove a breakpoint from the breakpoint array */
|
||||
|
||||
static void pdbg_deletebreakpoint(int16_t bpno)
|
||||
{
|
||||
if ((bpno >= 1) && (bpno <= g_nbreakpoints)) {
|
||||
|
||||
for (; (bpno < g_nbreakpoints); bpno++)
|
||||
g_breakpoint[bpno-1] = g_breakpoint[bpno];
|
||||
|
||||
g_nbreakpoints--;
|
||||
|
||||
} /* end if */
|
||||
|
||||
} /* end pdbg_deletebreakpoint */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Print the breakpoint array */
|
||||
|
||||
static void pdbg_printbreakpoints(struct pexec_s *st)
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("BP:# Address P-Code\n");
|
||||
for (i = 0; i < g_nbreakpoints; i++)
|
||||
{
|
||||
printf("BP:%d ", (i+1));
|
||||
(void)pdbg_printpcode(st, g_breakpoint[i], 1);
|
||||
} /* end for */
|
||||
|
||||
} /* end pdbg_printbreakpoints */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Check if a breakpoint is set at the current value of program counter.
|
||||
* If so, print the instruction and stop execution. */
|
||||
|
||||
static void pdbg_checkbreakpoint(struct pexec_s *st)
|
||||
{
|
||||
uint16_t bpIndex;
|
||||
|
||||
/* Check for a user breakpoint */
|
||||
|
||||
for (bpIndex = 0;
|
||||
((bpIndex < g_nbreakpoints) && (!g_bstopexecution));
|
||||
bpIndex++)
|
||||
{
|
||||
if (g_breakpoint[bpIndex] == st->pc)
|
||||
{
|
||||
printf("Breakpoint #%d -- Execution Stopped\n", (bpIndex+1));
|
||||
g_bstopexecution = true;
|
||||
return;
|
||||
} /* end if */
|
||||
} /* end for */
|
||||
|
||||
} /* end pdbg_checkbreakpoint */
|
||||
|
||||
/***********************************************************************/
|
||||
/* Initialize Debugger variables */
|
||||
|
||||
static void pdbg_initdebugger(void)
|
||||
{
|
||||
g_bstopexecution = false;
|
||||
g_displayloc = 0;
|
||||
g_tracendx = 0;
|
||||
g_ntracepoints = 0;
|
||||
}
|
||||
|
||||
/***********************************************************************/
|
||||
/* This function executes the P-Code program until a stopping condition
|
||||
* is encountered. */
|
||||
|
||||
static void pdbg_debugpcode(struct pexec_s *st)
|
||||
{
|
||||
uint16_t errno;
|
||||
|
||||
do {
|
||||
/* Trace the next instruction execution */
|
||||
|
||||
g_tracearray[g_tracendx].pc = st->pc;
|
||||
g_tracearray[g_tracendx].sp = st->sp;
|
||||
if (st->sp < st->stacksize)
|
||||
g_tracearray[g_tracendx].tos = st->dstack.i[BTOISTACK(st->sp)];
|
||||
else
|
||||
g_tracearray[g_tracendx].tos = 0;
|
||||
|
||||
if (++g_tracendx >= TRACE_ARRAY_SIZE)
|
||||
g_tracendx = 0;
|
||||
if (g_ntracepoints < TRACE_ARRAY_SIZE)
|
||||
g_ntracepoints++;
|
||||
|
||||
/* Execute the instruction */
|
||||
|
||||
errno = pexec(st);
|
||||
|
||||
/* Check for exceptional stopping conditions */
|
||||
|
||||
if (errno != eNOERROR)
|
||||
{
|
||||
if (errno == eEXIT)
|
||||
printf("Normal Termination\n");
|
||||
else
|
||||
printf("Runtime error 0x%02x -- Execution Stopped\n", errno);
|
||||
g_bstopexecution = true;
|
||||
} /* end if */
|
||||
|
||||
/* Check for normal stopping conditions */
|
||||
|
||||
if (!g_bstopexecution)
|
||||
{
|
||||
/* Check for attempt to execute code outside of legal range */
|
||||
|
||||
if (st->pc >= st->maxpc)
|
||||
g_bstopexecution = true;
|
||||
|
||||
/* Check for a temporary breakpoint */
|
||||
|
||||
else if ((g_untilpoint > 0) && (g_untilpoint == st->pc))
|
||||
g_bstopexecution = true;
|
||||
|
||||
/* Check if there is a breakpoint at the next instruction */
|
||||
|
||||
else if (g_nbreakpoints > 0)
|
||||
pdbg_checkbreakpoint(st);
|
||||
}
|
||||
|
||||
} while (!g_bstopexecution);
|
||||
|
||||
} /* end pdbg_debugpcode */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,176 @@
|
||||
/****************************************************************************
|
||||
* pload.c
|
||||
*
|
||||
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "keywords.h"
|
||||
#include "pedefs.h"
|
||||
#include "pofflib.h"
|
||||
#include "perr.h"
|
||||
#include "pexec.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Constant Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct pexec_s *pload(const char *filename, paddr_t varsize, paddr_t strsize)
|
||||
{
|
||||
struct pexec_attr_s attr;
|
||||
struct pexec_s *st;
|
||||
poffHandle_t phandle;
|
||||
FILE *exe;
|
||||
uint16_t err;
|
||||
uint8_t ftype;
|
||||
uint8_t farch;
|
||||
|
||||
/* Create a handle to contain the executable data */
|
||||
|
||||
phandle = poffCreateHandle();
|
||||
if (phandle == NULL) fatal(eNOMEMORY);
|
||||
|
||||
/* Open the executable file */
|
||||
|
||||
if (!(exe = fopen(filename, "rb")))
|
||||
{
|
||||
dbg("ERROR: Error opening '%s': %d\n", filename, errno);
|
||||
goto errout_with_handle;
|
||||
}
|
||||
|
||||
/* Load the POFF file into memory */
|
||||
|
||||
err = poffReadFile(phandle, exe);
|
||||
if (err != eNOERROR)
|
||||
{
|
||||
dbg("ERROR: Could not read %s: %d\n", filename, err);
|
||||
goto errout_with_file;
|
||||
}
|
||||
|
||||
/* Verify that the file is a pascal executable */
|
||||
|
||||
ftype = poffGetFileType(phandle);
|
||||
if (ftype != FHT_EXEC)
|
||||
{
|
||||
dbg("ERROR: File is not a pascal executable: %d\n", ftype);
|
||||
goto errout_with_file;
|
||||
}
|
||||
|
||||
farch = poffGetArchitecture(phandle);
|
||||
if (farch != FHA_PCODE_INSN16)
|
||||
{
|
||||
dbg("ERROR: File is not 16-bit pcode: %d\n", farch);
|
||||
goto errout_with_file;
|
||||
}
|
||||
|
||||
/* Initialize the attribute structure */
|
||||
|
||||
attr.varsize = varsize;
|
||||
attr.strsize = strsize;
|
||||
|
||||
/* Extract the program entry point from the pascal executable */
|
||||
|
||||
attr.entry = poffGetEntryPoint(phandle);
|
||||
|
||||
/* Close the POFF file */
|
||||
|
||||
(void)fclose(exe);
|
||||
|
||||
/* Extract the program data from the POFF image */
|
||||
|
||||
attr.maxpc = poffExtractProgramData(phandle, &attr.ispace);
|
||||
|
||||
/* Extract the read-only data from the POFF image */
|
||||
|
||||
attr.rosize = poffExtractRoData(phandle, &attr.rodata);
|
||||
|
||||
/* Destroy the POFF image */
|
||||
|
||||
poffDestroyHandle(phandle);
|
||||
|
||||
/* Initialize the p-code interpreter */
|
||||
|
||||
st = pexec_init(&attr);
|
||||
if (!st && attr.ispace)
|
||||
{
|
||||
/* Initialization failed, discard the allocated I-Space */
|
||||
|
||||
free(st->ispace);
|
||||
}
|
||||
|
||||
/* Discard the allocated RO data in any event */
|
||||
|
||||
if (attr.rodata)
|
||||
{
|
||||
free(attr.rodata);
|
||||
}
|
||||
return st;
|
||||
|
||||
errout_with_file:
|
||||
(void)fclose(exe);
|
||||
|
||||
errout_with_handle:
|
||||
poffDestroyHandle(phandle);
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
/****************************************************************************
|
||||
* prun.c
|
||||
*
|
||||
* Copyright (C) 2008-2009 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "keywords.h"
|
||||
#include "pdefs.h"
|
||||
#include "pinsn16.h"
|
||||
#include "pxdefs.h"
|
||||
#include "pedefs.h"
|
||||
|
||||
#include "paslib.h"
|
||||
#include "perr.h"
|
||||
#include "pexec.h"
|
||||
#include "pdbg.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define MIN_STACK_SIZE 1024
|
||||
#define DEFAULT_STACK_SIZE 4096
|
||||
#define DEFAULT_STKSTR_SIZE 0
|
||||
|
||||
/****************************************************************************
|
||||
* Private Type Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Constant Data
|
||||
****************************************************************************/
|
||||
|
||||
static const struct option long_options[] =
|
||||
{
|
||||
{"stack", 1, NULL, 's'},
|
||||
{"string", 1, NULL, 't'},
|
||||
{"debug", 0, NULL, 'd'},
|
||||
{"help", 0, NULL, 'h'},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
static const char *g_pofffilename;
|
||||
static int32_t g_varstacksize = DEFAULT_STACK_SIZE;
|
||||
static int32_t g_strstacksize = DEFAULT_STKSTR_SIZE;
|
||||
static int g_debug = 0;
|
||||
|
||||
/****************************************************************************
|
||||
* Global Variables
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: prun_showusage
|
||||
****************************************************************************/
|
||||
|
||||
static void prun_showusage(const char *progname)
|
||||
{
|
||||
fprintf(stderr, "Usage:\n");
|
||||
fprintf(stderr, " %s [options] <program-filename>\n",
|
||||
progname);
|
||||
fprintf(stderr, "options:\n");
|
||||
fprintf(stderr, " -s <stack-size>\n");
|
||||
fprintf(stderr, " --stack <stack-size>\n");
|
||||
fprintf(stderr, " Memory in bytes to allocate for the pascal program\n");
|
||||
fprintf(stderr, " stack in bytes (minimum is %d; default is %d bytes)\n",
|
||||
MIN_STACK_SIZE, DEFAULT_STACK_SIZE);
|
||||
fprintf(stderr, " -t <stack-size>\n");
|
||||
fprintf(stderr, " --string <string-storage-size>\n");
|
||||
fprintf(stderr, " Memory in bytes to allocate for the pascal program\n");
|
||||
fprintf(stderr, " string storage in bytes (default is %d bytes)\n",
|
||||
DEFAULT_STKSTR_SIZE);
|
||||
fprintf(stderr, " -d\n");
|
||||
fprintf(stderr, " --debug\n");
|
||||
fprintf(stderr, " Enable PCode program debugger\n");
|
||||
fprintf(stderr, " -h\n");
|
||||
fprintf(stderr, " --help\n");
|
||||
fprintf(stderr, " Shows this message\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: prun_parseargs
|
||||
****************************************************************************/
|
||||
|
||||
static void prun_parseargs(int argc, char **argv)
|
||||
{
|
||||
int option_index;
|
||||
int size;
|
||||
int c;
|
||||
|
||||
/* Check for existence of filename argument */
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Filename required\n");
|
||||
prun_showusage(argv[0]);
|
||||
} /* end if */
|
||||
|
||||
/* Parse the command line options */
|
||||
|
||||
do
|
||||
{
|
||||
c = getopt_long (argc, argv, "t:s:dh",
|
||||
long_options, &option_index);
|
||||
if (c != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 's' :
|
||||
size = atoi(optarg);
|
||||
if (size < MIN_STACK_SIZE)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Invalid stack size\n");
|
||||
prun_showusage(argv[0]);
|
||||
}
|
||||
g_varstacksize = (size + 3) & ~3;
|
||||
break;
|
||||
|
||||
case 't' :
|
||||
size = atoi(optarg);
|
||||
if (size < 0)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Invalid string storage size\n");
|
||||
prun_showusage(argv[0]);
|
||||
}
|
||||
g_strstacksize = ((size + 3) & ~3);
|
||||
break;
|
||||
|
||||
case 'd' :
|
||||
g_debug++;
|
||||
break;
|
||||
|
||||
case 'h' :
|
||||
prun_showusage(argv[0]);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Shouldn't happen */
|
||||
|
||||
fprintf(stderr, "ERROR: Unrecognized option\n");
|
||||
prun_showusage(argv[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (c != -1);
|
||||
|
||||
if (optind != argc-1)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Only one filename permitted on command line\n");
|
||||
prun_showusage(argv[0]);
|
||||
}
|
||||
|
||||
/* Get the name of the p-code file(s) from the last argument(s) */
|
||||
|
||||
g_pofffilename = argv[argc-1];
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: prun
|
||||
*
|
||||
* Description:
|
||||
* This function executes the P-Code program until a stopping condition
|
||||
* is encountered.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void prun(struct pexec_s *st)
|
||||
{
|
||||
int errcode;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
/* Execute the instruction; Check for exceptional conditions */
|
||||
|
||||
errcode = pexec(st);
|
||||
if (errcode != eNOERROR) break;
|
||||
}
|
||||
|
||||
if (errcode != eEXIT)
|
||||
{
|
||||
printf("Runtime error 0x%02x -- Execution Stopped\n", errcode);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: main
|
||||
****************************************************************************/
|
||||
|
||||
int main(int argc, char *argv[], char *envp[])
|
||||
{
|
||||
struct pexec_s *st;
|
||||
char fileName[FNAME_SIZE+1]; /* Object file name */
|
||||
|
||||
/* Parse the command line arguments */
|
||||
|
||||
prun_parseargs(argc, argv);
|
||||
|
||||
/* Load the POFF files specified on the command line */
|
||||
/* Use .o or command line extension, if supplied */
|
||||
|
||||
(void)extension(g_pofffilename, "o", fileName, 0);
|
||||
|
||||
/* Load the POFF file */
|
||||
|
||||
st = pload(fileName, g_varstacksize, g_strstacksize);
|
||||
if (!st)
|
||||
{
|
||||
fprintf(stderr, "ERROR: Could not load %s\n", fileName);
|
||||
exit(1);
|
||||
} /* end if */
|
||||
printf("%s Loaded\n", fileName);
|
||||
|
||||
/* And start program execution in the specified mode */
|
||||
|
||||
if (g_debug)
|
||||
dbg_run(st);
|
||||
else
|
||||
prun(st);
|
||||
|
||||
/* Clean up resources used by the interpreter */
|
||||
|
||||
pexec_release(st);
|
||||
return 0;
|
||||
|
||||
} /* end main */
|
||||
Reference in New Issue
Block a user