Update to Dave Hein's version 0.97.

This commit is contained in:
David Betz 2018-04-12 22:20:22 -04:00
parent 66915a7ad1
commit c33ed7cf35
64 changed files with 47390 additions and 10652 deletions

View File

@ -21,7 +21,7 @@ endif
TARGET = $(BUILD)/spinsim$(EXT)
SOURCES = spinsim.c spininterp.c spindebug.c pasmsim.c pasmdebug.c pasmsim2.c pasmdebug2.c eeprom.c debug.c gdb.c
SOURCES = spinsim.c spininterp.c spindebug.c pasmsim.c pasmdebug.c pasmsim2.c pasmdebug2.c eeprom.c debug.c gdb.c disasm2.c
ifneq ($(OS),msys)
SOURCES += conion.c
@ -47,5 +47,5 @@ $(BUILD)/%.o: %.c
$(CC) $(CFLAGS) $< -o $@
clean: FORCE
rm -f $(BUILD)
rm -rf $(BUILD)
FORCE:

223
README.md
View File

@ -1,135 +1,88 @@
Spinsim 0.75
This version of spinsim supports about two-thirds of the opcodes in the P2
instruction set. The list of implemented opcodes is shown below, along with
the list of opcodes that have not been implemented yet. Spinsim runs in the P1
mode by default. It can be set to run in the P2 mode with the -t parameter.
In the P2 mode, spinsim will load a P2 OBJ file into hub RAM, and start cog 0
with the code located at $E00. A simulated serial port is supported by using
the -b option. The default baud rate is 115,200, but other rates can be used
by specifying it with -b, such as -b9600. The serial port uses pin 31 and 30,
just like with P1.
Spinsim is built using the Makefile, and typing make. I have successfully
built and run it under Cygwin and Ubuntu Linux.
The sample program, pfth.spin can be run by building it with the PNut P2
assembler. PNut is contained in the Terasic_Prop2_Emulation zip file,
which can be downloaded from the first post in the "HUB EXEC Update Here"
thread in the Propeller 2 forum.
There are two demo programs, which are the pfth Forth interpreter and the
p1spin Spin interpreter that runs P1 Spin binaries on the P2 processor.
The pfth program is run under spinsim as follows:
./spinsim -t -b pfth.obj
p1spin runs at a baud rate of 57600, so it is run as follows:
./spinsim -t -b57600 p1spin.obj
Spinsim supports execution from cog memory and hub execution, but it does not
support multi-tasking. Only the core processor is supported, and none of the
counters, video hardware or cordic hardware is simulated. Support for multi-
tasking, peripheral hardware and cordic instructions will be added later.
Spinsim contains a simple debugger, which is enabled with the -d command-line
option. The debugger prints the prompt "DEBUG>" to indicate that it is ready
to accept a command. The "help" command will print the following:
Debug Commands
help - Print command list
exit - Exit spinsim
step - Run one cycle
stepx - Run next executed instruction
run - Run continuously
verbose # - Set verbosity level
reboot - Reboot the Prop
setbr cog addr - Set breakpoint for cog to addr
state cog - Dump cog state
The "step" command will run one cycle, and the "stepx" command will run any
non-executing cycles until it encounters an instruction that is executed.
The previous command can be executed again by just pushing the enter key.
This is useful for stepping where the "step" command is typed once, and
the enter key can then be used to step again.
The "run" command will run until a breakpoint is encountered or ^] is typed.
^] is typed by holding down the control key and pressing the "]" key.
While running, spinsim will print out the results of each cycle as
controlled by the verbosity level, which is set by the "verbose" command.
The verbosity level can also be set with the command-line parameter "-v#".
The verbosity levels are as follows:
0 - Disable printing
1 - Print only the executed instructions
2 - Print only the executed instructions, and show the execution results
3 - Print executed and instruction not executed due to condition code
4 - Also print instructions invalidated in the pipeline due to jumps
5 - Also print instructions that include hub and hardware waits
6 - Also print instructions that include icache waits
7 - Also print instructions waiting for a pin state
8 - Print all cycles, including waitcnt waits
The verbosity level is entered as a hexadecimal number. If the verbosity level
is entered as a single digit it will apply to all cogs. If more than one digit
is entered each digit will be used for each cog, starting with cog 0 for the
right-most digit. As an example, a value of 456 will cause 6 to be used for
cog 0, 5 for cog 1, and 4 for cog 2. All other cogs will use 0.
Implemented Opcodes
-------------------
abs add addabs addptra addptrb addptrx addptry adds
addsx addx and andn augd augs bingry blmask
call calla callad callb callbd calld callx callxd
cally callyd chkptrx chkptry clkset clracca clraccb clraccs
clrb clrp cmp cmpcnt cmps cmpsub cmpsx cmpx
cogid coginit cognew cogstop dcachex decd decds decmod
decod2 decod3 decod4 decod5 div32 div32u div64 div64d
div64u djnz djnzd djz djzd encod fixinda fixindb
fixindx frac getacah getacal getacbh getacbl getbyte getcnt
getdivq getdivr getmulh getmull getnib getnp getp getptra
getptrb getptrx getptry getsqrt getword icachen icachep icachex
ijnz ijnzd ijz ijzd incd incds incmod isob
jmp jmpd jmpsw jmpswd jnp jnpd jnz jnzd
jp jpd jz jzd locbase locbyte lockclr locknew
lockret lockset loclong locptra locptrb locword maca macb
max maxs mergew min mins mov mul mul32
mul32u muxc muxnc muxnz muxz neg negc negnc
negnz negz not notb notp offp onecnt or
pop popzc push pushzc rcl rcr rdaux rdauxr
rdbyte rdbytec rdlong rdlongc rdwide rdwidec rdword rdwordc
repd reps ret reta retad retb retbd retd
retx retxd rety retyd rev rol ror sar
saracca saraccb saraccs setacca setaccb setb setbc setbnc
setbnz setbyte setbz setd seti setindb setindx setnib
setp setpc setpnc setpnz setptra setptrb setptrx setptry
setpz sets setwide setwidz setword setzc seussf seussr
shl shr splitw sqrt32 sqrt64 sub subabs subcnt
subptra subptrb subptrx subptry subr subs subsx subx
sumc sumnc sumnz sumz test testn wait waitcnt
waitpeq waitpne wraux wrauxr wrbyte wrlong wrwide wrword
xor zercnt
Opcodes Not Implemented
-----------------------
addphsa addphsb addphss addpix bcdbin binbcd blnpix capctra
capctrb capctrs cfgdac0 cfgdac1 cfgdac2 cfgdac3 cfgdacs cfgpins
cmpr decpat eswap4 eswap8 getcntx getcosa getcosb getlfsr
getphsa getphsb getphza getphzb getpix getqx getqy getqz
getsina getsinb grybin incpat jmplist jmptask locinst mergeb
mixpix movbyts mulpix packrgb passcnt polctra polctrb polvid
qartan qexp qlog qrotate qsincos rolbyte rolnib rolword
scl serina serinb serouta seroutb setbyts setctra setctrb
setctrs setdac0 setdac1 setdac2 setdac3 setdacs setfrqa setfrqb
setfrqs setmap setmix setphsa setphsb setphss setpix setpixa
setpixb setpixg setpixr setpixu setpixv setpixw setpixz setpora
setporb setporc setpord setqi setqz setrace setsera setserb
settask setvid setvidi setvidq setvidy setwava setwavb setwavs
setwrds setx setxch setxft splitb subphsa subphsb subphss
synctra synctrb taskid testb unpkrgb waitpf waitpr waitpx
waitvid
Spinsim 0.97
This version of spinsim supports most of the opcodes in the P2 v20 instruction
set. The opcodes that are not supported are as follows:
xzero xinit xcont clkset setdacs setxfrq getxcos getxsin
setbrk setcy setci setcq setcfrq setcmod getrnd xoro32
skip skipf execf
skip, skipf and execf have been partially implemented, but do not handle jumps
or interrupts correctly.
Spinsim runs in the P1 mode by default. It can be set to run in the P2 mode
with the -t parameter. In the P2 mode, spinsim will load a P2 binary file into
hub RAM, and start cog 0 with the code located at $000. A simulated serial
port is supported by using the -b option. The default baud rate is 115200, but
other rates can be used by specifying it with -b, such as -b9600. The serial
port uses pins 63 and 62 when in the P2 mode.
Spinsim is built under Linux, MinGW or Cygwin by using the Makefile, and typing
make. The Windows executable, spinsim.exe is included with this distribution.
The sub-directory verify contains five programs that have been used to test
spinsim against the FPGA implementation. Approximately 150 instructions have
been verified to match the hardware. The verify directory contains the
original C source code and the binary each of the five programs. It also
contains the output from running the test programs on the FPGA.
A test program can be run by going into the verify directory and typing
../spinsim -t -b testopsa.bin
The output can be redirected to a file and compared with the hardware file
to verify that spinsim matches the hardware.
Spinsim supports the cordic instructions, but implements them with C functions
instead of simulating the cordic hardware. The instructions xvector and
xrotate are functionally equivalent to the P2, but will produce slightly
different results. qdiv and qfract bit exact results as long as the quotient
fits within 32 bits. It produces different results if the quotient overflows
a 32-bit value. The I/O streamer is currently not supported.
Spinsim contains a simple debugger, which is enabled with the -d command-line
option. The debugger prints the prompt "DEBUG>" to indicate that it is ready
to accept a command. The "help" command will print the following:
Debug Commands
help - Print command list
exit - Exit spinsim
step - Run one cycle
stepx - Run next executed instruction
run - Run continuously
verbose # - Set verbosity level
reboot - Reboot the Prop
setbr cog addr - Set breakpoint for cog to addr
state cog - Dump cog state
peekc cog addr - Print out a cog memory location
peekh addr - Print out a hub memory location
The "step" command will run one cycle, and the "stepx" command will run any
non-executing cycles until it encounters an instruction that is executed.
The previous command can be executed again by just pushing the enter key.
This is useful for stepping where the "step" command is typed once, and
the enter key can then be used to step again.
The "run" command will run until a breakpoint is encountered or ^] is typed.
^] is typed by holding down the control key and pressing the "]" key.
While running, spinsim will print out the results of each cycle as
controlled by the verbosity level, which is set by the "verbose" command.
The verbosity level can also be set with the command-line parameter "-v#".
The verbosity levels are as follows:
0 - Disable printing
1 - Print only the executed instructions
2 - Print only the executed instructions, and show the execution results
3 - Print executed and instruction not executed due to condition code
4 - Also print instructions invalidated in the pipeline due to jumps
5 - Also print instructions that include hub and hardware waits
6 - Also print instructions that include icache waits
7 - Also print instructions waiting for a pin state
8 - Print all cycles, including waitcnt waits
The verbosity level is entered as a hexadecimal number. If the verbosity level
is entered as a single digit it will apply to all cogs. If more than one digit
is entered each digit will be used for each cog, starting with cog 0 for the
right-most digit. As an example, a value of 456 will cause 6 to be used for
cog 0, 5 for cog 1, and 4 for cog 2. All other cogs will use 0.

View File

@ -1,136 +0,0 @@
'******************************************************************************
' Author: Dave Hein
' Version 1.0
' Copyright (c) 2010, 2011
' See end of file for terms of use.
'******************************************************************************
{{
This object provides console I/O functions for SpinSim. It implements the same methods as FullDuplexSerial.
}}
con
SYS_COMMAND = $12340000
SYS_LOCKNUM = $12340002
SYS_PARM = $12340004
SYS_CON_PUTCH = 1
SYS_CON_GETCH = 2
PUB start(rxpin, txpin, mode, baudrate) : okay
ifnot word[SYS_LOCKNUM]
word[SYS_LOCKNUM] := locknew + 1
return 1
PUB stop
PUB rxflush
'' Flush receive buffer
repeat while rxcheck => 0
PUB rxtime(ms) : rxbyte | t
'' Wait ms milliseconds for a byte to be received
'' returns -1 if no byte received, $00..$FF if byte
t := cnt
repeat until (rxbyte := rxcheck) => 0 or (cnt - t) / (clkfreq / 1000) > ms
PUB rx : rxbyte
'' Receive byte (may wait for byte)
'' returns $00..$FF
repeat while (rxbyte := rxcheck) < 0
PUB rxcheck | locknum
locknum := word[SYS_LOCKNUM] - 1
if locknum == -1
return -1
repeat until not lockset(locknum)
word[SYS_COMMAND] := SYS_CON_GETCH
repeat while word[SYS_COMMAND]
result := long[SYS_PARM]
lockclr(locknum)
PUB tx(txbyte) | locknum
'' Send byte (may wait for room in buffer)
locknum := word[SYS_LOCKNUM] - 1
if locknum == -1
return
repeat until not lockset(locknum)
long[SYS_PARM] := txbyte
word[SYS_COMMAND] := SYS_CON_PUTCH
repeat while word[SYS_COMMAND]
lockclr(locknum)
PUB str(stringptr)
'' Send string
repeat strsize(stringptr)
tx(byte[stringptr++])
PUB dec(value) | i, x
'' Print a decimal number
x := value == NEGX 'Check for max negative
if value < 0
value := ||(value+x) 'If negative, make positive; adjust for max negative
tx("-") 'and output sign
i := 1_000_000_000 'Initialize divisor
repeat 10 'Loop for 10 digits
if value => i
tx(value / i + "0" + x*(i == 1)) 'If non-zero digit, output digit; adjust for max negative
value //= i 'and digit from value
result~~ 'flag non-zero found
elseif result or i == 1
tx("0") 'If zero digit (or only digit) output it
i /= 10 'Update divisor
PUB hex(value, digits)
'' Print a hexadecimal number
value <<= (8 - digits) << 2
repeat digits
tx(lookupz((value <-= 4) & $F : "0".."9", "A".."F"))
'tx(hexdigit[(value <-= 4) & $F])
PUB bin(value, digits)
'' Print a binary number
value <<= 32 - digits
repeat digits
tx((value <-= 1) & 1 + "0")
PUB out(char)
tx(char)
{{
+------------------------------------------------------------------------------------------------------------------------------+
| TERMS OF USE: MIT License |
+------------------------------------------------------------------------------------------------------------------------------+
|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation |
|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, |
|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software|
|is furnished to do so, subject to the following conditions: |
| |
|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.|
| |
|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE |
|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
+------------------------------------------------------------------------------------------------------------------------------+
}}

136
conion.c
View File

@ -1,73 +1,63 @@
#ifdef LINUX
#include <stdio.h>
#include "conion.h"
#ifdef STD_CONSOLE_INPUT
void initialize_console_io()
{
}
void restore_console_io()
{
}
int kbhit(void)
{
return 0;
}
char getch(void)
{
return getchar();
}
#else
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
static struct termios oldt;
static int oldf;
static int lastkey = EOF;
static int initialized = 0;
void initialize_console_io()
{
struct termios newt;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
initialized = 1;
}
void restore_console_io()
{
if (initialized)
{
initialized = 0;
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);
}
}
int kbhit(void)
{
if (lastkey == EOF)
lastkey = getchar();
return (lastkey != EOF);
}
char getch(void)
{
int ch;
while (!kbhit());
ch = lastkey;
lastkey = EOF;
return ch;
}
#endif
#endif
#include <stdio.h>
#include "conion.h"
#ifdef STD_CONSOLE_INPUT
void initialize_console_io()
{
}
void restore_console_io()
{
}
int kbhit(void)
{
return 0;
}
#else
#include <unistd.h>
#include <termios.h>
#include <sys/select.h>
#include <sys/ioctl.h>
static int initialized = 0;
static struct termios oldt;
void initialize_console_io(void)
{
struct termios newt;
if (initialized) return;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO | ISIG);
newt.c_iflag &= ~(ICRNL | INLCR);
newt.c_oflag &= ~OPOST;
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
initialized = 1;
}
void restore_console_io(void)
{
if (!initialized) return;
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
initialized = 0;
}
int kbhit(void)
{
fd_set set;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&set);
FD_SET(STDIN_FILENO, &set);
return select(STDIN_FILENO + 1, &set, NULL, NULL, &tv) > 0;
}
#endif
int getch(void)
{
return getchar();
}

View File

@ -4,7 +4,7 @@
#undef STD_CONSOLE_INPUT
int kbhit(void);
char getch(void);
int getch(void);
void initialize_console_io(void);
void restore_console_io(void);

63
conion.new Executable file
View File

@ -0,0 +1,63 @@
#include <stdio.h>
#include "conion.h"
#ifdef STD_CONSOLE_INPUT
void initialize_console_io()
{
}
void restore_console_io()
{
}
int kbhit(void)
{
return 0;
}
#else
#include <unistd.h>
#include <termios.h>
#include <sys/select.h>
#include <sys/ioctl.h>
static int initialized = 0;
static struct termios oldt;
void initialize_console_io(void)
{
struct termios newt;
if (initialized) return;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO | ISIG);
newt.c_iflag &= ~(ICRNL | INLCR);
newt.c_oflag &= ~OPOST;
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
initialized = 1;
}
void restore_console_io(void)
{
if (!initialized) return;
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
initialized = 0;
}
int kbhit(void)
{
fd_set set;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&set);
FD_SET(STDIN_FILENO, &set);
return select(STDIN_FILENO + 1, &set, NULL, NULL, &tv) > 0;
}
#endif
int getch(void)
{
return getchar();
}

71
conion.old Executable file
View File

@ -0,0 +1,71 @@
#include <stdio.h>
#include "conion.h"
#ifdef STD_CONSOLE_INPUT
void initialize_console_io()
{
}
void restore_console_io()
{
}
int kbhit(void)
{
return 0;
}
int getch(void)
{
return getchar();
}
#else
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
static struct termios oldt;
static int oldf;
static int lastkey = EOF;
static int initialized = 0;
void initialize_console_io()
{
struct termios newt;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
initialized = 1;
}
void restore_console_io()
{
if (initialized)
{
initialized = 0;
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);
}
}
int kbhit(void)
{
if (lastkey == EOF)
lastkey = getchar();
return (lastkey != EOF);
}
int getch(void)
{
int ch;
while (!kbhit());
ch = lastkey;
lastkey = EOF;
return ch;
}
#endif

83
debug.c
View File

@ -9,14 +9,9 @@
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#ifdef LINUX
#include <dirent.h>
#include <sys/stat.h>
#include "conion.h"
#else
#include <conio.h>
#include <direct.h>
#endif
#include "interp.h"
#include "spindebug.h"
#include "eeprom.h"
@ -29,22 +24,26 @@ extern int32_t eeprom;
extern char *hubram;
extern int32_t printbreak;
extern PasmVarsT PasmVars[8];
extern SerialT serial_in;
extern SerialT serial_out;
void GetDebugString(char *ptr);
int32_t RunProp(int32_t maxloops);
void Help(void)
{
printf("Debug Commands\n");
printf("help - Print command list\n");
printf("exit - Exit spinsim\n");
printf("step - Run one cycle\n");
printf("stepx - Run next executed instruction\n");
printf("run - Run continuously\n");
printf("verbose # - Set verbosity level\n");
printf("reboot - Reboot the Prop\n");
printf("setbr cog addr - Set breakpoint for cog to addr\n");
printf("state cog - Dump cog state\n");
printf("Debug Commands%s", NEW_LINE);
printf("help - Print command list%s", NEW_LINE);
printf("exit - Exit spinsim%s", NEW_LINE);
printf("step - Run one cycle%s", NEW_LINE);
printf("stepx - Run next executed instruction%s", NEW_LINE);
printf("run - Run continuously%s", NEW_LINE);
printf("verbose # - Set verbosity level%s", NEW_LINE);
printf("reboot - Reboot the Prop%s", NEW_LINE);
printf("setbr cog addr - Set breakpoint for cog to addr%s", NEW_LINE);
printf("state cog - Dump cog state%s", NEW_LINE);
printf("peekc cog addr - Peek cog memory%s", NEW_LINE);
printf("peekh addr - Peek hub memory%s", NEW_LINE);
}
char *SkipChar(char *str, int value)
@ -59,15 +58,15 @@ char *SkipChar(char *str, int value)
void DumpState(PasmVarsT *pasmvars)
{
printf("cflag = %d, zflag = %d, waitflag = %d\n",
pasmvars->cflag, pasmvars->zflag, pasmvars->waitflag);
printf("ptra = %5.5x, ptrb = %5.5x, ptrx = %2.2x, ptry = %2.2x, inda = %3.3x, indb = %3.3x\n",
printf("cflag = %d, zflag = %d, waitflag = %d%s",
pasmvars->cflag, pasmvars->zflag, pasmvars->waitflag, NEW_LINE);
printf("ptra = %5.5x, ptrb = %5.5x, ptrx = %2.2x, ptry = %2.2x, inda = %3.3x, indb = %3.3x%s",
pasmvars->ptra, pasmvars->ptra, pasmvars->ptrx,
pasmvars->ptry, pasmvars->inda, pasmvars->indb);
printf("pc1 = %8.8x, instruct1 = %8.8x\n", pasmvars->pc1, pasmvars->instruct1);
printf("pc2 = %8.8x, instruct2 = %8.8x\n", pasmvars->pc2, pasmvars->instruct2);
printf("pc3 = %8.8x, instruct3 = %8.8x\n", pasmvars->pc3, pasmvars->instruct3);
printf("pc4 = %8.8x, instruct4 = %8.8x\n", pasmvars->pc4, pasmvars->instruct4);
pasmvars->ptry, pasmvars->inda, pasmvars->indb, NEW_LINE);
printf("pc1 = %8.8x, instruct1 = %8.8x%s", pasmvars->pc1, pasmvars->instruct1, NEW_LINE);
printf("pc2 = %8.8x, instruct2 = %8.8x%s", pasmvars->pc2, pasmvars->instruct2, NEW_LINE);
printf("pc3 = %8.8x, instruct3 = %8.8x%s", pasmvars->pc3, pasmvars->instruct3, NEW_LINE);
printf("pc4 = %8.8x, instruct4 = %8.8x%s", pasmvars->pc4, pasmvars->instruct4, NEW_LINE);
}
void Debug(void)
@ -84,7 +83,7 @@ void Debug(void)
{
while (1)
{
printf("\nDEBUG> ");
printf("%sDEBUG> ", NEW_LINE);
fflush(stdout);
GetDebugString(buffer);
if (buffer[0] == 0) strcpy(buffer, lastcmd);
@ -139,9 +138,21 @@ void Debug(void)
{
int cognum, address;
sscanf(buffer+6, "%x %x", &cognum, &address);
PasmVars[cognum&7].breakpnt = address;
PasmVars[cognum&15].breakpnt = address;
LONG(SYS_DEBUG) = printflag;
}
else if (!strncmp(buffer, "peekc ", 6))
{
int cognum, address;
sscanf(buffer+6, "%x %x", &cognum, &address);
printf("%8.8x%s", PasmVars[cognum&15].mem[address&511], NEW_LINE);
}
else if (!strncmp(buffer, "peekh ", 6))
{
int address;
sscanf(buffer+6, "%x", &address);
printf("%8.8x%s", hubram[address], NEW_LINE);
}
else if (!strcmp(buffer, "reboot"))
{
RebootProp();
@ -152,7 +163,7 @@ void Debug(void)
DumpState(&PasmVars[cognum]);
}
else
printf("?\n");
printf("?%s", NEW_LINE);
}
if (runflag) RunProp(maxloops);
if (stepflag)
@ -168,6 +179,7 @@ void Debug(void)
void GetDebugString(char *ptr)
{
int value;
char *ptr0 = ptr;
while (1)
{
@ -175,12 +187,25 @@ void GetDebugString(char *ptr)
while (!kbhit());
#endif
value = getch();
putchx(value);
if (value == 8 || value == 0x7f)
{
if (ptr != ptr0)
{
ptr--;
putchx(8);
putchx(' ');
putchx(8);
}
continue;
}
if (value == 13 || value == 10)
{
putchx(13);
putchx(10);
*ptr = 0;
return;
}
putchx(value);
*ptr++ = value;
}
}
@ -195,8 +220,8 @@ int32_t RunProp(int32_t maxloops)
CheckCommand();
if (baudrate)
{
CheckSerialOut();
if (CheckSerialIn()) return 1;
CheckSerialOut(&serial_out);
if (CheckSerialIn(&serial_in)) return 1;
}
if (eeprom)
CheckEEProm();

View File

@ -6,12 +6,12 @@
'******************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include "spinsim.h"
extern int32_t pin_val;
extern int32_t pin_val_a;
extern int32_t eeprom;
static int32_t scl_prev = 1;
@ -28,8 +28,8 @@ static unsigned char memory[256*256];
void CheckEEProm()
{
int32_t scl = (pin_val >> 28) & 1;
int32_t sda = (pin_val >> 29) & 1;
int32_t scl = (pin_val_a >> 28) & 1;
int32_t sda = (pin_val_a >> 29) & 1;
if (!eeprom) return;
@ -136,7 +136,7 @@ void CheckEEProm()
}
if (drivepin)
{
pin_val = (pin_val & (~(1 << 29))) | (driveval << 29);
pin_val_a = (pin_val_a & (~(1 << 29))) | (driveval << 29);
sda = driveval;
}
scl_prev = scl;
@ -148,7 +148,7 @@ static FILE *OpenFile(char *fname, char *mode)
FILE *file = fopen(fname, mode);
if (!file)
{
printf("Could not open %s\n", fname);
printf("Could not open %s%s", fname, NEW_LINE);
spinsim_exit(1);
}
return file;

View File

@ -1,189 +0,0 @@
'******************************************************************************
' Author: Dave Hein
' Version 1.0
' Copyright (c) 2010, 2011
' See end of file for terms of use.
'******************************************************************************
{{
This object provide file I/O functions for SpinSim. It currently implements only popen, pclose and pread.
The methods a similar to the ones the FSRW object. A dummy mount routine is provide for compatibility.
}}
con
SYS_COMMAND = $12340000
SYS_LOCKNUM = $12340002
SYS_PARM = $12340004
SYS_FILE_OPEN = 3
SYS_FILE_CLOSE = 4
SYS_FILE_READ = 5
SYS_FILE_WRITE = 6
SYS_FILE_OPENDIR = 7
SYS_FILE_CLOSEDIR = 8
SYS_FILE_READDIR = 9
SYS_FILE_SEEK = 10
SYS_FILE_TELL = 11
SYS_FILE_REMOVE = 12
SYS_FILE_CHDIR = 13
SYS_FILE_GETCWD = 14
SYS_FILE_MKDIR = 15
SYS_FILE_GETMOD = 16
dat
handle0 long 0
dirhand0 long 0
direntbuf long 0[20]
'****************************
' FSRW Routines
'****************************
pub mount(pin)
ifnot word[SYS_LOCKNUM]
word[SYS_LOCKNUM] := locknew + 1
pub mount_explicit(DO, CLK, DI, CS)
ifnot word[SYS_LOCKNUM]
word[SYS_LOCKNUM] := locknew + 1
pub popen(fname, mode)
pclose
handle0 := hopen(fname, mode)
ifnot handle0
return -1
pub pclose
if handle0
hclose(handle0)
handle0~
pub pread(buffer, num)
return hread(handle0, buffer, num)
pub pwrite(buffer, num)
return hwrite(handle0, buffer, num)
pub opendir
if dirhand0
hclosedir(dirhand0)
dirhand0 := hopendir
ifnot dirhand0
return -1
pub nextfile(fbuf)
return hnextfile(dirhand0, fbuf)
pub seek(position)
result := hseek(handle0, position)
pub tell
result := htell(handle0)
pub get_filesize
result := hget_filesize(handle0)
'****************************
' handle Routines
'****************************
pub hopen(fname, mode)
if mode => "a" and mode =< "z"
mode -= "a" - "A"
if mode == "R"
mode := string("rb")
elseif mode == "W"
mode := string("wb")
elseif mode == "A"
mode := string("ab")
elseif mode == "D"
return SystemCall(SYS_FILE_REMOVE, fname)
else
return 0
result := SystemCall(SYS_FILE_OPEN, @fname)
pub hclose(handle)
result := SystemCall(SYS_FILE_CLOSE, handle)
pub hread(handle, buffer, num)
result := SystemCall(SYS_FILE_READ, @handle)
pub hwrite(handle, buffer, num)
result := SystemCall(SYS_FILE_WRITE, @handle)
pub hopendir
result := SystemCall(SYS_FILE_OPENDIR, 0)
pub hclosedir(handle)
result := SystemCall(SYS_FILE_CLOSEDIR, handle)
pub hnextfile(handle, fbuf) | num
result := hreaddir(handle)
if result
num := strsize(@direntbuf[2])
if num > 31
num := 31
bytemove(fbuf, @direntbuf[2], num)
byte[fbuf][num] := 0
pub hreaddir(handle) | pdirent
pdirent := @direntbuf
result := SystemCall(SYS_FILE_READDIR, @handle)
if result
result := @direntbuf
pub hseek(handle, position) | whence
whence~
result := SystemCall(SYS_FILE_SEEK, @handle)
pub htell(handle)
result := SystemCall(SYS_FILE_TELL, handle)
pub hget_filesize(handle) | offset, whence, position, filesize
position := SystemCall(SYS_FILE_TELL, handle)
offset~
whence := 2
SystemCall(SYS_FILE_SEEK, @handle)
filesize := SystemCall(SYS_FILE_TELL, handle)
offset := position
whence~
SystemCall(SYS_FILE_SEEK, @handle)
return filesize
pub chdir(path)
result := SystemCall(SYS_FILE_CHDIR, path)
pub getcwd(str, num)
result := SystemCall(SYS_FILE_CHDIR, @str)
pub mkdir(path)
result := SystemCall(SYS_FILE_MKDIR, path)
pub getmod(fname)
result := SystemCall(SYS_FILE_GETMOD, fname)
pub SystemCall(command, parm) | locknum
locknum := word[SYS_LOCKNUM] - 1
if locknum == -1
return -1
repeat until not lockset(locknum)
long[SYS_PARM] := parm
word[SYS_COMMAND] := command
repeat while word[SYS_COMMAND]
result := long[SYS_PARM]
lockclr(locknum)
{{
+------------------------------------------------------------------------------------------------------------------------------+
| TERMS OF USE: MIT License |
+------------------------------------------------------------------------------------------------------------------------------+
|Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation |
|files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, |
|modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software|
|is furnished to do so, subject to the following conditions: |
| |
|The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.|
| |
|THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE |
|WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR |
|COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, |
|ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
+------------------------------------------------------------------------------------------------------------------------------+
}}

6
gdb.c
View File

@ -8,14 +8,9 @@
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#ifdef LINUX
#include <dirent.h>
#include <sys/stat.h>
#include "conion.h"
#else
#include <conio.h>
#include <direct.h>
#endif
#include "interp.h"
#include "spinsim.h"
@ -27,7 +22,6 @@ extern FILE *cmdfile;
extern PasmVarsT PasmVars[8];
extern char *hubram;
char cmd[1028];
extern int32_t proptwo;
extern int32_t profile;
extern int32_t loopcount;

100
interp.h
View File

@ -19,6 +19,16 @@
#define INVALIDATE_INSTR 0x80000000
typedef struct SerialS {
int32_t mode;
int32_t flag;
int32_t state;
int32_t count;
int32_t value;
int32_t pin_num;
int32_t bitcycles;
} SerialT;
// This struct is used by the PASM simulator
typedef struct PasmVarsS {
int32_t mem[512];
@ -31,6 +41,7 @@ typedef struct PasmVarsS {
int32_t waitmode;
int32_t breakpnt;
// P2 variables
int32_t lut[512];
int32_t instruct1;
int32_t instruct2;
int32_t instruct3;
@ -39,10 +50,16 @@ typedef struct PasmVarsS {
int32_t pc2;
int32_t pc3;
int32_t pc4;
int32_t dcachehubaddr;
int32_t dcachecogaddr;
int32_t icachehubaddr[4];
int32_t icachenotused[4];
int32_t str_fifo_buffer[16];
int32_t str_fifo_rindex;
int32_t str_fifo_windex;
int32_t str_fifo_head_addr;
int32_t str_fifo_tail_addr;
int32_t str_fifo_addr0;
int32_t str_fifo_addr1;
int32_t str_fifo_mode;
int32_t str_fifo_work_word;
int32_t str_fifo_work_flag;
int32_t ptra;
int32_t ptra0;
int32_t ptrb;
@ -61,23 +78,64 @@ typedef struct PasmVarsS {
int32_t repbot;
int32_t reptop;
int32_t repforever;
int32_t dcache[8];
int32_t icache[4][8];
int32_t retstack[4];
int32_t auxram[256];
int32_t retstack[8];
int32_t printflag;
int32_t retptr;
int32_t divq;
int32_t divr;
int32_t divisor;
int32_t mulcount;
int32_t memflag;
int32_t qreg;
int32_t qxreg;
int32_t qyreg;
int32_t qxposted;
int32_t qyposted;
int32_t cordic_count;
int32_t cordic_depth;
int32_t qxqueue[3];
int32_t qyqueue[3];
int32_t augsvalue;
int32_t augsflag;
int32_t augdvalue;
int32_t augdflag;
int32_t altsflag;
int32_t altsvalue;
int32_t altdflag;
int32_t altdvalue;
int32_t altrflag;
int32_t altrvalue;
int32_t altiflag;
int32_t altivalue;
int32_t altnflag;
int32_t altnvalue;
int32_t altsvflag;
int32_t altsvvalue;
int32_t prefetch;
int32_t sqrt;
int32_t lastd;
int32_t phase;
int32_t rwrep;
int32_t cntreg1;
int32_t cntreg2;
int32_t cntreg3;
int32_t intflags;
int32_t intstate;
int32_t intenable1;
int32_t intenable2;
int32_t intenable3;
int32_t pinpatmode;
int32_t pinpatmask;
int32_t pinpattern;
int32_t pinedge;
int32_t lockedge;
int32_t rdl_mask;
int32_t wrl_mask;
int32_t blnpix_var;
int32_t mixpix_mode;
int32_t share_lut;
uint32_t skip_mask;
uint32_t skip_mode;
SerialT serina;
SerialT serinb;
SerialT serouta;
SerialT seroutb;
int64_t acca;
int64_t accb;
int64_t mul;
@ -125,13 +183,21 @@ void RebootProp(void);
int32_t GetCnt(void);
void UpdatePins(void);
int32_t MAP_ADDR(int32_t addr);
void DebugPasmInstruction(PasmVarsT *pasmvars);
int ExecutePasmInstruction(PasmVarsT *pasmvars);
void DebugPasmInstruction2(PasmVarsT *pasmvars);
int ExecutePasmInstruction2(PasmVarsT *pasmvars);
void StartCog(SpinVarsT *spinvars, int par, int cogid);
int CheckSerialIn(SerialT *serial);
void CheckSerialOut(SerialT *serial);
int SerialSend(SerialT *serial, int portval);
void SerialReceive(SerialT *serial, int portval);
void SerialInit(SerialT *serial, int pin_num, int baudrate, int mode);
void StartPasmCog(PasmVarsT *pasmvars, int par, int addr, int cogid);
void StartPasmCog2(PasmVarsT *pasmvars, int par, int addr, int cogid);
void StartPasmCog2(PasmVarsT *pasmvars, int par, int addr, int cogid, int hubexec);
void StartPasmCog3(PasmVarsT *pasmvars, int par, int addr, int cogid);
void DebugPasmInstruction(PasmVarsT *pasmvars);
void DebugPasmInstruction2(PasmVarsT *pasmvars);
void DebugPasmInstruction3(PasmVarsT *pasmvars);
int ExecutePasmInstruction(PasmVarsT *pasmvars);
int ExecutePasmInstruction2(PasmVarsT *pasmvars);
int ExecutePasmInstruction3(PasmVarsT *pasmvars);
/*
+ -----------------------------------------------------------------------------------------------------------------------------+
| TERMS OF USE: MIT License |

Binary file not shown.

View File

@ -1,243 +0,0 @@
'**********************************************
' Dhrystone 1.1
'**********************************************
OBJ
ser : "Simple_Serial"
CON
_clkmode = xtal1+pll16x
_clkfreq = 80000000
LOOPS = 500
Ident1 = 1
Ident2 = 2
Ident3 = 3
Ident4 = 4
Ident5 = 5
' typedef struct Record
PtrComp = 0
Discr = 4
EnumComp = 8
IntComp = 12
StringComp = 16
NULL = 0
DAT
Version byte "1.1", 0
Array1Glob long 0[51]
Array2Glob long 0[51*51]
xxx long 0[12]
yyy long 0[12]
PtrGlb long 0
PtrGlbNext long 0
IntGlob long 0
BoolGlob long 0
Char1Glob long 0
Char2Glob long 0
String1Loc long 0[8]
String2Loc long 0[8]
starttime long 0
benchtime long 0
nulltime long 0
PUB Dhrystone11
PtrGlb := @xxx
PtrGlbNext := @yyy
Proc0
{
* Package 1
}
PUB Proc0 | IntLoc1, IntLoc2, IntLoc3, CharLoc, CharIndex, EnumLoc, i
starttime := time_msec
i := 0
repeat while (i < LOOPS)
++i
nulltime := time_msec - starttime { Computes o'head of loop }
long[PtrGlb + PtrComp] := PtrGlbNext
long[PtrGlb + Discr] := Ident1
long[PtrGlb + EnumComp] := Ident3
long[PtrGlb + IntComp] := 40
strcpy((PtrGlb + StringComp), string("DHRYSTONE PROGRAM, SOME STRING"))
strcpy(@String1Loc, string("DHRYSTONE PROGRAM, 1'ST STRING")) {GOOF}
long[@Array2Glob][8 * 51 + 7] := 10 { Was missing in published program }
{****************
-- Start Timer --
****************}
starttime := time_msec
i := 0
repeat while (i < LOOPS)
Proc5
Proc4
IntLoc1 := 2
IntLoc2 := 3
strcpy(@String2Loc, string("DHRYSTONE PROGRAM, 2'ND STRING"))
EnumLoc := Ident2
BoolGlob := not Func2(@String1Loc, @String2Loc)
repeat while (IntLoc1 < IntLoc2)
IntLoc3 := 5 * IntLoc1 - IntLoc2
Proc7(IntLoc1, IntLoc2, @IntLoc3)
++IntLoc1
Proc8(@Array1Glob, @Array2Glob, IntLoc1, IntLoc3)
Proc1(PtrGlb)
byte[@CharIndex] := "A"
repeat while (byte[@CharIndex] =< Char2Glob)
if (EnumLoc == Func1(byte[@CharIndex], "C"))
Proc6(Ident1, @EnumLoc)
byte[@CharIndex] := byte[@charIndex] + 1
IntLoc3 := IntLoc2 * IntLoc1
IntLoc2 := IntLoc3 / IntLoc1
IntLoc2 := 7 *(IntLoc3 - IntLoc2) - IntLoc1
Proc2(@IntLoc1)
++i
{****************
-- Stop Timer --
****************}
benchtime := time_msec - starttime - nulltime
ser.str(string("Dhrystone("))
ser.str(@Version)
ser.str(string(") time for "))
ser.dec(LOOPS)
ser.str(string(" passes = "))
ser.dec(benchtime)
ser.str(string(" msec", 13))
ser.str(string("This machine benchmarks at "))
ser.dec(LOOPS * 1000 / benchtime)
ser.str(string(" dhrystones/second", 13))
PUB Proc1(PtrParIn)
memcpy(long[PtrParIn + PtrComp], PtrGlb, 48)
long[PtrParIn + IntComp] := 5
long[long[PtrParIn + PtrComp] + IntComp] := long[PtrParIn + IntComp]
long[long[PtrParIn + PtrComp] + PtrComp] := long[PtrParIn + PtrComp]
Proc3(long[long[PtrParIn + PtrComp] + PtrComp])
if (long[long[PtrParIn + PtrComp] + Discr] == Ident1)
long[long[PtrParIn + PtrComp] + IntComp] := 6
Proc6(long[PtrParIn + EnumComp], long[PtrParIn + PtrComp] + EnumComp)
long[long[PtrParIn + PtrComp] + PtrComp] := long[PtrGlb + PtrComp]
Proc7(long[long[PtrParIn + PtrComp] + IntComp], 10, long[PtrParIn + PtrComp] + IntComp)
else
memcpy(PtrParIn, long[PtrParIn + PtrComp], 48)
PUB Proc2(IntParIO) | IntLoc, EnumLoc
IntLoc := long[IntParIO] + 10
repeat 'while ()
if (Char1Glob == "A")
--IntLoc
long[IntParIO] := IntLoc - IntGlob
EnumLoc := Ident1
if (EnumLoc == Ident1)
quit
PUB Proc3(PtrParOut)
if (PtrGlb <> NULL)
PtrParOut := long[PtrGlb + PtrComp]
else
IntGlob := 100
Proc7(10, IntGlob, PtrGlb + IntComp)
PUB Proc4 | BoolLoc
BoolLoc := Char1Glob == "A"
BoolLoc |= BoolGlob
Char2Glob := "B"
PUB Proc5
Char1Glob := "A"
BoolGlob := FALSE
PUB Proc6(EnumParIn, EnumParOut)
long[EnumParOut] := EnumParIn
ifnot Func3(EnumParIn)
long[EnumParOut] := Ident4
if EnumParIn == Ident1
long[EnumParOut] := Ident1
elseif EnumParIn == Ident2
if (IntGlob > 100)
long[EnumParOut] := Ident1
else
long[EnumParOut] := Ident4
elseif EnumParIn == Ident3
long[EnumParOut] := Ident2
elseif (EnumParIn == Ident4) or (EnumParIn == Ident5)
long[EnumParOut] := Ident3
PUB Proc7(IntParI1, IntParI2, IntParOut) | IntLoc
IntLoc := IntParI1 + 2
long[IntParOut] := IntParI2 + IntLoc
PUB Proc8(Array1Par, Array2Par, IntParI1, IntParI2) | IntLoc, IntIndex
IntLoc := IntParI1 + 5
long[Array1Par][IntLoc] := IntParI2
long[Array1Par][IntLoc + 1] := long[Array1Par][IntLoc]
long[Array1Par][IntLoc + 30] := IntLoc
IntIndex := IntLoc
repeat while (IntIndex =<(IntLoc + 1))
long[Array2Par][IntLoc * 51 + IntIndex] := IntLoc
++IntIndex
++long[Array2Par][IntLoc * 51 + IntLoc - 1]
long[Array2Par][(IntLoc + 20) * 51 + IntLoc] := long[Array1Par][IntLoc]
IntGlob := 5
PUB Func1(CharPar1, CharPar2) | CharLoc1, CharLoc2
byte[@CharLoc1] := byte[@CharPar1]
byte[@CharLoc2] := byte[@CharLoc1]
if (byte[@CharLoc2] <> byte[@CharPar2])
return (Ident1)
else
return (Ident2)
PUB Func2(StrParI1, StrParI2) | IntLoc, CharLoc
IntLoc := 1
repeat while (IntLoc =< 1)
if (Func1(byte[StrParI1][IntLoc], byte[StrParI2][IntLoc + 1]) == Ident1)
byte[@CharLoc] := "A"
++IntLoc
if (byte[@CharLoc] => "W" and byte[@CharLoc] =< "Z")
IntLoc := 7
if (byte[@CharLoc] == "X")
return (TRUE)
else
if (strcmp(StrParI1, StrParI2) > 0)
IntLoc += 7
return (TRUE)
else
return (FALSE)
PUB Func3(EnumParIn) | EnumLoc
EnumLoc := EnumParIn
if (EnumLoc == Ident3)
return (TRUE)
return (FALSE)
PUB strcpy(dst, src)
bytemove(dst, src, strsize(src) + 1)
{
repeat strsize(src)
byte[dst++] := byte[src++]
}
PUB memcpy(dst, src, num)
bytemove(dst, src, num)
{
repeat num
byte[dst++] := byte[src++]
}
PUB strcmp(str1, str2)
result := not strcomp(str1, str2)
{
repeat while byte[str1]
if byte[str1] <> byte[str2]
quit
str1++
str2++
return byte[str1] - byte[str2]
}
PUB time_msec
return cnt / (_clkfreq/1000)

File diff suppressed because it is too large Load Diff

View File

@ -1,351 +0,0 @@
SPASM(1) User Commands SPASM(1)
NAME
spasm - spin assembler
SYNOPSIS
spasm [-l] [-d] FILE
DESCRIPTION
Spasm assembles the source file given by FILE. The file name may
include the extension, or .spa will be assumed if no extension is
specified. The assembled binary program will written to a file with
the same root name plus a .bin extension. If -l is specified, it will
print an assembly listing. If -d is specified, spasm will print debug
information.
Spasm is an assembly language that defines mnemonics for Spin
bytecodes. Spin bytecodes are executed by the Spin interpreter, which
is loaded at boot time from the internal ROM. The Spin interpreter is
a stack-based virtual machine that uses the stack to store parameters
that are used by operators, such as add, sub, etc. The operators store
their results back onto the stack. There are other operators that
transfer data back and forth between the stack and hub RAM.
The Spin bytecodes are listed below. They are separated into four
major groups -- lower, memory, math and extened operators. The lower
group contains a mix of operators, including those that handle program
flow, lookup, lookdown, case, and several other miscellaneous functions.
The math operators implement the various math and logic functions that
use two arguments.
The memory operators implement load, store, execute and address
functions. A load operation reads data from the hub RAM and pushes it
onto the stack. A store operation pops a value off the stack and
stores it in RAM. The address operator is used to push the absolute
address of a hub RAM location onto the stack.
The execute operation is used to execute an operation directly on a RAM
location. The result can be optionally pushed to the stack. The
operations that can be executed directly on a hub RAM location include
the standard 32 math operations plus a small number of extended
operations. The extended operators include pre and post increment and
decrement, sign extension and the random function.
The format of the memory mnemonics is as follows:
<operation><size><type><mode>
operation = {ld, st, ex, la},
size = {b, w, l},
type = {i, l, o, a, v, s}
mode = {c, x, 0, 1, m1, p}
The operations are load, store, execute and load address as stated
earlier. The size refers to byte, word and long. The types are
immediate, local, object, absolute, variable and stack. The modes
are compact, indexed, zero, one, minus one and packed.
As an example, the instruction ldwi means load-word-immediate. It
will load an immediate value onto the stack. The instruction stba
will store a byte at the absolute address residing in the stack.
There are compact instructions that use a single byte to address
the first 8 long values residing in the method's stack frame or in
an object's variable space. These use the size, type and mode
characters "llc". As an example, the method result value can be
set with the "stllc 0" instruction. The fourth long in the objet's
variable section could be loaded with "ldllc 12".
When an execute memory operation is specified it is followed by one of
the math operators or an extended operator. An execute instruction may
also specify the "load" extended operator to save the result on the
stack. Examples of using execute instructions are as follows:
exlo $8 add ' Add value on stack to the object long at offset $8
exwv $20 preinc ' Increment the VAR word at offset $20
exll $10 postdec load ' Decrement stack location $10 and load
Spasm also includes psuedo-ops, which are shortened versions of the
memory mnenomics. The psuedo-ops are made up only of the operation
and size fields, plus the "x" charater if it is indexed. The
psuedo-ops are mapped to explicit opcodes depending on the context
of the operand. As an example "ldl 1" maps into "ldli1", and
"ldl result" maps into "ldllc 0".
The Spasm opcodes are listed below. The offsets used for the jump
instructions are signed offsets that are relative to the address of the
next instruction. A "jmp 0" instruction will just execute the next
instruction.
Signed offsets are encoded in either one or two bytes depending
on the value of the most significant bit in the first byte. If the
MSB is zero the remaining seven bits are treated as a signed 7-bit
number in the range from -64 to 63. If the MSB is non-zero, the
remaining seven bits are used as the most significant bits of a 15-bit
signed number, and the next byte provides the eight least sigficant
bits. The 15-bit signed offset has a range from -16384 to 16383.
The memory opcodes use an unsigned offset that can also be encoded in
one or two bytes. The MSB is used to determine whether it is one or
two bytes just like for signed offset. However, since it is unsigned,
the range for the one-byte offset is 0 to 128, and for two bytes it is
0 to 32768.
Lower Opcodes
-------------
00 ldfrmr - Load call frame with return value required
01 ldfrm - Load call frame
02 ldfrmar - Load call frame with abort trap & return value
03 ldfrma - Load call frame with abort trap
04 jmp offset - Jump to signed object offset
05 call meth - Call method
06 callobj meth, obj - Call method in object
07 callobjx meth, obj - Call method in object with index
08 tjz offset - Test and jump if zero
09 djnz offset - Decrement and jump if not zero
0a jz offset - Jump if zero
0b jnz offset - Jump if not zero
0c casedone - Case done without a match
0d casevalue - Execute if value matches case value
0e caserange - Execute if case value within range
0f lookdone - Look up/down done without a match
10 lookupval -
11 lookdnval
12 lookuprng
13 lookdnrng
14 pop - Discard N bytes from the stack
15 run - Prepare new spin cog stack for execution
16 strsize - Determine the size of a string
17 strcomp - Compare two strings
18 bytefill - Fill memory with a constant byte value
19 wordfill - Fill memory with a constant word value
1a longfill - Fill memory with a constant long value
1b waitpeq - Wait till pins are equal to a value
1c bytemove - Copy bytes to a new location
1d wordmove - Copy words to a new location
1e longmove - Copy longs to a new location
1f waitpne - Wait till pins are not equal to value
20 clkset - Change the clock frequency and mode
21 cogstop - Stop the specified cog
22 lockret - Return a lock
23 waitcnt - Wait for cnt to equal a specified value
24 ldlsx
25 stlsx
26 exlsx
27 waitvid - Wait on video
28 coginitret - Start a cog and return the cog number
29 locknewret - Allocate a lock and return the lock number
2a locksetret - Set a lock and return the previous value
2b lockclrret - Clear a lock and return the previous value
2c coginit - Start a cog
2d locknew - Allocate a lock with no return value
2e lockset - Set a lock with no return value
2f lockclr - Clear a lock with no return value
30 abort - Perform an abort to the next abort trap
31 abortval - Perform an abort and return a value
32 ret - Return without loading a return value
33 retval - Return and load a return value on the stack
34 ldlim1 - Load a minus 1
35 ldli0 - Load zero
36 ldli1 - Load 1
37 ldlip value - Load a packed-byte constant
38 ldbi value - Load a single-byte constant
39 ldwi value - Load a two-byte constant
3a ldmi value - Load a three-byte constant
3b ldli value - Load a four-byte constant
3c --- - Unused opcode
3d ldregbit - Load a bit from a register
3d stregbit - Store a bit to a register
3e ldregbits - Load bits from a register
3e stregbits - Store bit to a register
3f ldreg - Load a register
3f streg - Store a register
Compact Memory Opcodes
--------------
40 ldlvc offset - Load long variable compact
41 stlvc offset - Store long variable compact
42 exlvc offset - Execute on a long variable compact
43 lalvc offset - Load address of a long variable compact
60 ldllc offset - Load long local compact
61 stllc offset - Store long local compact
62 exllc offset - Execute on a long local compact
63 lallc offset - Load address of a long local compact
Byte Memory Opcodes
--------------
80 ldba - Load byte absolute
81 stba - Store byte absolute
82 exba - Execute on a byte absolute
83 laba - Load address of a byte absolute
84 ldbo offset - Load byte object offset
85 stbo offset
86 exbo offset
87 labo offset
88 ldbv offset - Load byte variable offset
89 stbv offset
8a exbv offset
8b labv offset
8c ldbl offset - Load byte local offset
8d stbl offset
8e exbl offset
8f labl offset
90 ldbax - Load byte absolute with index
91 stbax
92 exbax
93 labax
94 ldbox offset - Load byte object offset with index
95 stbox offset
96 exbox offset
97 labox offset
98 ldbvx offset - Load byte variable offset with index
99 stbvx offset
9a exbvx offset
9b labvx offset
9c ldblx offset - Load byte local offset with index
9d stblx offset
9e exblx offset
9f lablx offset
Word Memory Opcodes
-------------------
a0 ldwa - Load word absolute
a1 stwa
a2 exwa
a3 lawa
a4 ldwo offset
a5 stwo offset
a6 exwo offset
a7 lawo offset
a8 ldwv offset
a9 stwv offset
aa exwv offset
ab lawv offset
ac ldwl offset
ad stwl offset
ae exwl offset
af lawl offset
b0 ldwax - Load word absolute with index
b1 stwax
b2 exwax
b3 lawax
b4 ldwox offset
b5 stwox offset
b6 exwox offset
b7 lawox offset
b8 ldwvx offset
b9 stwvx offset
ba exwvx offset
bb lawvx offset
bc ldwlx offset
bd stwlx offset
be exwlx offset
bf lawlx offset
Long Memory Opcodes
-------------------
c0 ldla - Load long absolute
c1 stla
c2 exla
c3 lala
c4 ldlo offset
c5 stlo offset
c6 exlo offset
c7 lalo offset
c8 ldlv offset
c9 stlv offset
ca exlv offset
cb lalv offset
cc ldll offset
cd stll offset
ce exll offset
cf lall offset
d0 ldlax - Load long absolute with index
d1 stlax
d2 exlax
d3 lalax
d4 ldlox offset
d5 stlox offset
d6 exlox offset
d7 lalox offset
d8 ldlvx offset
d9 stlvx offset
da exlvx offset
db lalvx offset
dc ldllx offset
dd stllx offset
de exllx offset
df lallx offset
Math Opcodes
------------
e0 ror - Rotate right
e1 rol - Rotate left
e2 shr - Shift right
e3 shl - Shift left
e4 min - Maximum
e5 max - Minimum
e6 neg - Negate
e7 com - Compliment
e8 and - Bitwise and
e9 abs - Absolute value
ea or - Bitwise or
eb xor - Bitwise exclusive or
ec add - Add
ed sub - Subtract
ee sar - Shift arithmetic right
ef rev - Bit reverse
f0 andl - Logical and
f1 encode - Shift "1" left
f2 orl - Logical or
f3 decode - Find left-most "1" bit
f4 mul - Multiply
f5 mulh - Multiply high
f6 div - Divide
f7 mod - Modulus
f8 sqrt - Square root
f9 cmplt - Less than
fa cmpgt - Greater than
fb cmpne - Not equal
fc cmpeq - Equal
fd cmple - Less than or equal
fe cmpge - Greater than or equal
ff notl - Logical not
Extended opcodes
----------------
00 load - Load the value
02 repeat - Repeat index from first to last
06 repeats - Repeat index from first to last with step
08 randf - Forward random number
0c randr - Reverse random number
10 sexb - Sign extend byte
14 sexw - Sign extend word
18 postclr - Post clear to zero
1c postset - Post set to all ones
26 preinc - Pre-increment
2e postinc - Post-increment
36 predec - Pre-decrement
3e postdec - Post-decrement
AUTHOR
Dave Hein
COPYRIGHT
Copyright (c) 2011, 2012, Dave Hein
MIT License (See license.txt in the root directory)
This is free software: you are free to change and redistribute it.
There is no warranty, to the extent permitted by law.
SPASM March 2012 SPASM(1)

Binary file not shown.

View File

@ -1,14 +0,0 @@
CON
_clkmode = xtal1+pll16x
_clkfreq = 80_000_000
OBJ
ser : "Simple_Serial"
dry : "dry11"
PUB main | ptr, count
'waitcnt(clkfreq*3+cnt)
ser.init(31, 30, 19200)
ser.str(string(13, "Testing Spin Interpreter", 13))
dry.Dhrystone11
waitcnt(clkfreq/10+cnt)

View File

@ -9,7 +9,7 @@
#include "interp.h"
char *FindChar(char *str, int32_t val);
int32_t CheckWaitFlag(PasmVarsT *pasmvars, int mode);
int32_t CheckWaitFlag1(PasmVarsT *pasmvars, int mode);
extern char *hubram;
extern int32_t memsize;
@ -168,7 +168,7 @@ void DebugPasmInstruction(PasmVarsT *pasmvars)
{
if (opcode <= 0x07) // hubop
{
if (CheckWaitFlag(pasmvars, 3)) xflag = 2;
if (CheckWaitFlag1(pasmvars, 3)) xflag = 2;
}
else if (opcode == 0x3e) // waitcnt
{
@ -202,15 +202,9 @@ void DebugPasmInstruction(PasmVarsT *pasmvars)
while (i < 7) opstr[i++] = ' ';
opstr[i] = 0;
#if 0
fprintf(tracefile, "%3.3x %8.8x %d %d %s %s %s %3.3x %s%3.3x %8.8x %8.8x", pasmvars->pc,
instruct, zflag, cflag, xstr[xflag], condnames[cond], opstr, dstaddr,
istr[zcri & 1], srcaddr, value1, value2);
#else
fprintf(tracefile, "%6d %3.3x %8.8x %s %s %s %3.3x, %s%3.3x%s%s%s", loopcount * 4, pc,
instruct, xstr[xflag], condnames[cond], opstr, dstaddr,
istr[zcri & 1], srcaddr, wzstr, wcstr, wrstr);
#endif
}
/*
+------------------------------------------------------------------------------------------------------------------------------+

View File

@ -9,7 +9,7 @@
#include "interp.h"
#include "spinsim.h"
#define REG_PINA 0x1f4
#define ADDR_MASK 0xfffff
extern char *hubram;
extern int32_t memsize;
@ -19,249 +19,18 @@ extern int32_t pin_val;
extern FILE *tracefile;
static char *condnames[16] = {
"if_never ", "if_nz_and_nc", "if_z_and_nc ", "if_nc ",
"if_nz_and_c ", "if_nz ", "if_z_ne_c ", "if_nz_or_nc ",
"if_z_and_c ", "if_z_eq_c ", "if_z ", "if_z_or_nc ",
"if_c ", "if_nz_or_c ", "if_z_or_c ", " "};
void Disassemble2(int instruct, int pc, char *debugstr, int *errflag);
char *opcodes_lower[64] = {
"rdbyte","rdbytec","rdword","rdwordc","rdlong","rdlongc","rdaux","rdauxr",
"isob","notb","clrb","setb","setbc","setbnc","setbz","setbnz",
"andn","and","or","xor","muxc","muxnc","muxz","muxnz",
"ror","rol","shr","shl","rcr","rcl","sar","rev",
"mov","not","abs","neg","negc","negnc","negz","negnz",
"add","sub","addx","subx","adds","subs","addsx","subsx",
"sumc","sumnc","sumz","sumnz","min","max","mins","maxs",
"addabs","subabs","incmod","decmod","cmpsub","subr","mul","scl"};
char *opcodes_upper[62][4] = {
{"decod2", "decod2", "decod2", "decod2"},
{"decod3", "decod3", "decod3", "decod3"},
{"decod4", "decod4", "decod4", "decod4"},
{"decod5", "decod5", "decod5", "decod5"},
{"encod", "blmask", "encod", "blmask"},
{"onecnt", "zercnt", "onecnt", "zercnt"},
{"incpat", "incpat", "decpat", "decpat"},
{"splitb", "mergeb", "splitw", "mergew"},
{"getnib", "setnib", "getnib", "setnib"},
{"getnib", "setnib", "getnib", "setnib"},
{"getnib", "setnib", "getnib", "setnib"},
{"getnib", "setnib", "getnib", "setnib"},
{"getword","setword","getword","setword"},
{"setwrds","rolnib", "rolbyte","rolword"},
{"sets", "setd", "setx", "seti"},
{"cognew", "cognew", "waitcnt","waitcnt"},
{"getbyte","setbyte","getbyte","setbyte"},
{"getbyte","setbyte","getbyte","setbyte"},
{"setbyts","movbyts","packrgb","unpkrgb"},
{"addpix", "mulpix", "blnpix", "mixpix"},
{"jmpsw", "jmpsw", "jmpsw", "jmpsw"},
{"jmpswd", "jmpswd", "jmpswd", "jmpswd"},
{"ijz", "ijzd", "ijnz", "ijnzd"},
{"djz", "djzd", "djnz", "djnzd"},
{"testb", "testb", "testb", "testb"},
{"testn", "testn", "testn", "testn"},
{"test", "test", "test", "test"},
{"cmp", "cmp", "cmp", "cmp"},
{"cmpx", "cmpx", "cmpx", "cmpx"},
{"cmps", "cmps", "cmps", "cmps"},
{"cmpsx", "cmpsx", "cmpsx", "cmpsx"},
{"cmpr", "cmpr", "cmpr", "cmpr"},
{"coginit","waitvid","coginit","waitvid"},
{"coginit","waitvid","coginit","waitvid"},
{"coginit","waitvid","coginit","waitvid"},
{"coginit","waitvid","coginit","waitvid"},
{"waitpeq","waitpeq","waitpeq","waitpeq"},
{"waitpeq","waitpeq","waitpeq","waitpeq"},
{"waitpne","waitpne","waitpne","waitpne"},
{"waitpne","waitpne","waitpne","waitpne"},
{"wrbyte", "wrbyte", "wrword", "wrword"},
{"wrlong", "wrlong", "frac", "frac"},
{"wraux", "wraux", "wrauxr", "wrauxr"},
{"setacca","setacca","setaccb","setaccb"},
{"maca", "maca", "macb", "macb"},
{"mul32", "mul32", "mul32u", "mul32u"},
{"div32", "div32", "div32u", "div32u"},
{"div64", "div64", "div64u", "div64u"},
{"sqrt64", "sqrt64", "qsincos","qsincos"},
{"qarctan","qarctan","qrotate","qrotate"},
{"setsera","setsera","setserb","setserb"},
{"setctrs","setctrs","setwavs","setwavs"},
{"setfrqs","setfrqs","setphss","setphss"},
{"addphss","addphss","subphss","subphss"},
{"jp", "jp", "jpd", "jpd"},
{"jnp", "jnp", "jnpd", "jnpd"},
{"cfgpins","cfgpins","cfgpins","cfgpins"},
{"cfgpins","cfgpins","jmptask","jmptask"},
{"setxfr", "setxfr", "setmix", "setmix"},
{"jz", "jzd", "jnz", "jnzd"},
{"locbase","locbyte","locword","loclong"},
{"jmplist","locinst","augs", "augd"}};
int zci_upper[62][4] = {
{7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7},
{5, 5, 5, 5}, {5, 5, 5, 5}, {3, 3, 3, 3}, {1, 1, 1, 1},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {3, 3, 3, 3},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{7, 7, 7, 7}, {7, 7, 7, 7}, {1, 1, 1, 1}, {1, 1, 1, 1},
{7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7},
{7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7}, {7, 7, 7, 7},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{3, 3, 3, 3}, {3, 3, 3, 3}, {3, 3, 3, 3}, {3, 3, 3, 3},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1},
{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}, {1, 1, 1, 1}};
char *opcodes_ind[16] = {
"invalid", "fixinda", "setinda", "setinda",
"fixindb", "fixinds", "invalid", "invalid",
"setindb", "invalid", "setinds", "setinds",
"setindb", "invalid", "setinds", "setinds"};
char *opcodes_16[14] = {
"locptra","locptrb","jmp","jmpd","call","calld","calla",
"callad","callb","callbd","callx","callxd","cally","callyd"};
char *opcodes_set1[49] = {
"cogid","taskid","locknew","getlfsr","getcnt","getcntx","getacal","getacah",
"getacbl","getacbh","getptra","getptrb","getptrx","getptry","serina","serinb",
"getmull","getmulh","getdivq","getdivr","getsqrt","getqx","getqy","getqz",
"getphsa","getphza","getcosa","getsina","getphsb","getphzb","getcosb","getsinb",
"pushzc","popzc","subcnt","getpix","binbcd","bcdbin","bingry","grybin",
"eswap4","eswap8","seussf","seussr","incd","decd","incds","decds","pop"};
char *opcodes_set2[] = {
"clkset", "cogstop", "lockset", "lockclr", "lockret", "rdwidec", "rdwide",
"wrwide", "getp", "getnp", "serouta", "seroutb", "cmpcnt", "waitpx",
"waitpr", "waitpf", "setzc", "setmap", "setxch", "settask", "setrace",
"saracca", "saraccb", "saraccs", "setptra", "setptrb", "addptra", "addptrb",
"subptra", "subptrb", "setwide", "setwidz", "setptrx", "setptry",
"addptrx", "addptry", "subptrx", "subptry", "passcnt", "wait", "offp",
"notp", "clrp", "setp", "setpc", "setpnc", "setpz", "stpnz", "div64d",
"sqrt32", "qlog", "qexp", "setqi", "setqz", "cfgdacs", "setdacs",
"cfgdac0", "cfgdac1", "cfgdac2", "cfgdac3", "setdac0", "setdac1",
"setdac2", "seddac3", "setctra", "setwava", "setfrqa", "setphsa",
"addphsa", "subphsa", "setvid", "setvidy", "setctrb", "setwavb", "setfrqb",
"setphsb", "addphsb", "subphsb", "setvidi", "setvidq", "setpix", "setpixz",
"setpixu", "setpixv", "setpixa", "setpixr", "setpixg", "setpixb",
"setpora", "setporb", "setporc", "setpord", "push"};
char *opcodes_set3[40] = {
"jmp", "jmpd", "call", "calld", "calla", "callad", "callb", "callbd",
"callx", "callxd", "cally", "callyd", "reta", "retad", "retb", "retbd",
"retx", "retxd", "rety", "retyd", "ret", "retd", "polctra", "polctrb",
"polvid", "capctra", "capctrb", "capctrs", "setpixw", "clracca", "clraccb",
"clraccs", "chkptrx", "chkptry", "syntra", "synctrb", "dcachex", "icachex",
"icachep", "icachen"};
int zci_set3[40] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 0, 0, 0,
0, 0, 0, 0, 6, 6, 0, 0, 0, 0, 0, 0};
char *GetOpname2(unsigned int instr, int *pzci)
{
int opcode = instr >> 25;
int zci = (instr >> 22) & 7;
int cond = (instr >> 18) & 15;
int src = instr & 0x1ff;
int dst = (instr >> 9) & 0x1ff;
int zc = zci >> 1;
//printf("opcode = $%2.2x, zci = %d\n", opcode, zci);
if (opcode < 64)
{
*pzci = 7;
return opcodes_lower[opcode];
}
else if(opcode < 126)
{
*pzci = zci_upper[opcode-64][zc];
return opcodes_upper[opcode-64][zc];
}
else if (opcode == 126 && zci == 0)
{
*pzci = 0;
return opcodes_ind[cond];
}
else if (opcode == 126)
{
*pzci = 0;
return opcodes_16[(zci-1)*2 + (dst >> 8)];
}
else if (src <= 48)
{
if (src < 44 || src == 48)
*pzci = 7;
else
*pzci = 5;
return opcodes_set1[src];
}
if (src < 64)
{
*pzci = 0;
return "invalid";
}
if (src < 128)
{
*pzci = 1;
return "repd";
}
if (src < 220)
{
if (src == 136 || src == 137 || src == 144)
*pzci = 7;
else if (src == 130 || src == 131)
*pzci = 3;
else
*pzci = 1;
return opcodes_set2[src-128];
}
if (src < 0xf4)
{
*pzci = 0;
return "invalid";
}
if (src <= 0x11b)
{
*pzci = zci_set3[src-0xf4];
return opcodes_set3[src-0xf4];
}
*pzci = 0;
return "invalid";
}
void StartPasmCog2(PasmVarsT *pasmvars, int32_t par, int32_t addr, int32_t cogid)
void StartPasmCog2(PasmVarsT *pasmvars, int32_t par, int32_t addr, int32_t cogid, int32_t hubexec)
{
int32_t i;
// printf("\nStartPasmCog2: %8.8x, %8.8x, %d\n", par, addr, cogid);
par &= 0x3ffff;
addr &= 0x3fffc;
//printf("\nStartPasmCog2: %8.8x, %8.8x, %d, %d\n", par, addr, cogid, hubexec);
par &= ADDR_MASK;
addr &= ADDR_MASK;
pasmvars->waitflag = 0;
pasmvars->cflag = 0;
pasmvars->zflag = 0;
pasmvars->pc = 0;
pasmvars->cogid = cogid;
pasmvars->state = 5;
pasmvars->ptra = par;
@ -278,8 +47,6 @@ void StartPasmCog2(PasmVarsT *pasmvars, int32_t par, int32_t addr, int32_t cogid
pasmvars->repbot = 0;
pasmvars->reptop = 0;
pasmvars->repforever = 0;
pasmvars->dcachehubaddr = 0xffffffff;
pasmvars->dcachecogaddr = 0xffffffff;
pasmvars->instruct1 = 0;
pasmvars->instruct2 = 0;
pasmvars->instruct3 = 0;
@ -291,27 +58,68 @@ void StartPasmCog2(PasmVarsT *pasmvars, int32_t par, int32_t addr, int32_t cogid
pasmvars->retptr = 0;
pasmvars->acca = 0;
pasmvars->accb = 0;
pasmvars->mulcount = 0;
pasmvars->cordic_count = 0;
pasmvars->cordic_depth = 0;
pasmvars->qxposted = 0;
pasmvars->qyposted = 0;
pasmvars->breakpnt = -1;
pasmvars->augsflag = 0;
pasmvars->augsvalue = 0;
pasmvars->augdflag = 0;
pasmvars->augdvalue = 0;
pasmvars->icachehubaddr[0] = 0xffffffff;
pasmvars->icachehubaddr[1] = 0xffffffff;
pasmvars->icachehubaddr[2] = 0xffffffff;
pasmvars->icachehubaddr[3] = 0xffffffff;
pasmvars->icachenotused[0] = 0;
pasmvars->icachenotused[1] = 0;
pasmvars->icachenotused[2] = 0;
pasmvars->icachenotused[3] = 0;
pasmvars->prefetch = 1;
pasmvars->altsflag = 0;
pasmvars->altsvalue = 0;
pasmvars->altdflag = 0;
pasmvars->altdvalue = 0;
pasmvars->altrflag = 0;
pasmvars->altrvalue = 0;
pasmvars->altiflag = 0;
pasmvars->altivalue = 0;
pasmvars->prefetch = 0;
pasmvars->serina.mode = 0;
pasmvars->serinb.mode = 0;
pasmvars->serouta.mode = 0;
pasmvars->seroutb.mode = 0;
pasmvars->phase = 0;
pasmvars->rwrep = 0;
pasmvars->str_fifo_work_flag = 0;
pasmvars->str_fifo_addr0 = 0;
pasmvars->str_fifo_addr1 = 0;
pasmvars->str_fifo_head_addr = 0;
pasmvars->str_fifo_tail_addr = 0;
pasmvars->str_fifo_rindex = 0;
pasmvars->str_fifo_windex = 0;
pasmvars->str_fifo_mode = 0;
pasmvars->str_fifo_buffer[0] = 0;
pasmvars->cntreg1 = 0;
pasmvars->cntreg2 = 0;
pasmvars->cntreg3 = 0;
pasmvars->intflags = 0;
pasmvars->intstate = 0;
pasmvars->qreg = 0;
pasmvars->memflag = 0;
pasmvars->intenable1 = 0;
pasmvars->intenable2 = 0;
pasmvars->intenable3 = 0;
pasmvars->pinpatmode = 0;
pasmvars->pinpatmask = 0;
pasmvars->pinpattern = 0;
pasmvars->pinedge = 0;
pasmvars->lockedge = 0;
pasmvars->rdl_mask = 0;
pasmvars->wrl_mask = 0;
for (i = 0; i < 0x1f4; i++)
if (!hubexec)
{
pasmvars->mem[i] = LONG(addr);
addr += 4;
for (i = 0; i < 0x1f4; i++)
{
pasmvars->mem[i] = LONG(addr);
addr += 4;
}
pasmvars->pc = 0;
}
else
pasmvars->pc = addr;
for (i = 0x1f4; i < 512; i++) pasmvars->mem[i] = 0;
}
@ -321,43 +129,14 @@ void DebugPasmInstruction2(PasmVarsT *pasmvars)
int32_t cflag = pasmvars->cflag;
int32_t zflag = pasmvars->zflag;
int32_t instruct, pc, cond, xflag;
int32_t opcode, zci;
int32_t srcaddr, dstaddr;
char *wzstr = "";
char *wcstr = "";
char opstr[20];
char *istr[3] = {" ", "#", "@"};
char *xstr[8] = {" ", "X", "I", "H", "C", "P", "W", "?"};
int zci_mask;
int32_t sflag, dflag, indirect, opcode_zci;
char *xstr[12] = {" ", "X", "I", "H", "C", "P", "W", "F", "w", "E", "?", "S"};
// Fetch the instruction
pc = pasmvars->pc4;
instruct = pasmvars->instruct4;
cond = (instruct >> 18) & 15;
// Extract parameters from the instruction
opcode = (instruct >> 25) & 127;
srcaddr = instruct & 511;
dstaddr = (instruct >> 9) & 511;
zci = (instruct >> 22) & 7;
opcode_zci = (opcode << 3) | zci;
// Decode the immediate flags for the source and destination fields
sflag = (opcode_zci >= 0x3ea) | (zci & 1);
dflag = (opcode >= 0x68 && opcode <= 0x7a && (zci & 2)) |
(opcode_zci >= 0x302 && opcode_zci <= 0x31f) |
(opcode != 0x7f && opcode_zci >= 0x3eb) |
(opcode == 0x7f && srcaddr >= 0x40 && srcaddr <= 0xdc && (zci & 1)) |
(opcode == 0x7f && srcaddr >= 0x100);
// Determine if indirect registers are used
indirect = (!sflag && (srcaddr & 0x1fe) == 0x1f2) |
(!dflag && (dstaddr & 0x1fe) == 0x1f2) |
(opcode_zci == 0x3f0);
if (indirect) cond = 0xf;
pc = pasmvars->pc2;
instruct = pasmvars->instruct2;
cond = (instruct >> 28) & 15;
if (cond == 0 && instruct != 0) cond = 15;
xflag = ((cond >> ((cflag << 1) | zflag)) & 1);
xflag ^= 1;
@ -381,15 +160,17 @@ void DebugPasmInstruction2(PasmVarsT *pasmvars)
xflag = 5;
else if (pasmvars->waitmode == WAIT_HUB)
xflag = 3;
else if (pasmvars->waitmode == WAIT_FLAG)
xflag = 8;
else if (pasmvars->waitmode == WAIT_CORDIC)
xflag = 9;
else
xflag = 7;
xflag = 10;
}
strcpy(opstr, GetOpname2(instruct, &zci_mask));
zci &= zci_mask;
if (zci & 4) wzstr = " wz";
if (zci & 2) wcstr = " wc";
else if (pasmvars->phase == 0)
xflag = 7;
else if (pasmvars->skip_mask & 1)
xflag = 11;
i = strlen(opstr);
while (i < 7) opstr[i++] = ' ';
@ -403,31 +184,21 @@ void DebugPasmInstruction2(PasmVarsT *pasmvars)
strcpy(opstr, "nop ");
}
// Check for REPS
if ((instruct & 0xffc00000) == 0xfac00000)
{
cond = 15;
if (xflag == 1) xflag = 0;
strcpy(opstr, "reps ");
}
// Check for AUGS or AUGD
if (opcode_zci >= 0x3ec && opcode_zci <= 0x3ef)
{
cond = 15;
if (xflag == 1) xflag = 0;
}
if (pasmvars->printflag - 2 < xflag && xflag != 0)
{
pasmvars->printflag = 0;
return;
}
fprintf(tracefile, "Cog %d: %8.8x ", pasmvars->cogid, loopcount);
fprintf(tracefile, "%4.4x %8.8x %s %s %s %s%3.3x, %s%3.3x%s%s", pc,
instruct, xstr[xflag], condnames[cond], opstr, istr[dflag], dstaddr,
istr[sflag], srcaddr, wzstr, wcstr);
{
int errflag;
char debugstr[100];
Disassemble2(instruct, pc, debugstr, &errflag);
fprintf(tracefile, "Cog %2d: %8.8x ", pasmvars->cogid, loopcount);
fprintf(tracefile, "%4.4x %8.8x %s %s", pc,
instruct, xstr[xflag], debugstr);
}
}
/*
+------------------------------------------------------------------------------------------------------------------------------+

View File

@ -9,22 +9,21 @@
extern char *hubram;
extern int32_t memsize;
extern char lockstate[8];
extern char lockalloc[8];
extern char lockstate[16];
extern char lockalloc[16];
extern PasmVarsT PasmVars[8];
extern int32_t pasmspin;
extern int32_t cycleaccurate;
extern int32_t loopcount;
extern int32_t proptwo;
extern int32_t pin_val;
extern int32_t pin_val_a;
extern FILE *tracefile;
void PrintResults(int32_t zcri, int32_t zflag, int32_t cflag, int32_t result)
{
if (zcri & 8) printf(" Z=%d", zflag);
if (zcri & 4) printf(" C=%d", cflag);
if (zcri & 2) printf(" R=%8.8x", result);
if (zcri & 8) fprintf(tracefile, " Z=%d", zflag);
if (zcri & 4) fprintf(tracefile, " C=%d", cflag);
if (zcri & 2) fprintf(tracefile, " R=%8.8x", result);
}
static int32_t parity(int32_t val)
@ -42,7 +41,7 @@ static int32_t abs(int32_t val)
return val < 0 ? -val : val;
}
int32_t CheckWaitFlag(PasmVarsT *pasmvars, int mode)
int32_t CheckWaitFlag1(PasmVarsT *pasmvars, int mode)
{
int32_t hubmode = mode & 1;
int32_t debugmode = mode & 2;
@ -54,18 +53,12 @@ int32_t CheckWaitFlag(PasmVarsT *pasmvars, int mode)
}
else if (hubmode)
{
if (proptwo)
waitflag = (pasmvars->cogid - loopcount) & 7;
else
waitflag = ((pasmvars->cogid >> 1) - loopcount) & 3;
waitflag = ((pasmvars->cogid >> 1) - loopcount) & 3;
waitflag++;
}
else
{
if (proptwo)
waitflag = 2;
else
waitflag = 1;
waitflag = 1;
}
if (!debugmode)
{
@ -127,7 +120,7 @@ int32_t ExecutePasmInstruction(PasmVarsT *pasmvars)
// Check for a hub wait
if (cycleaccurate && !(instruct & 0xe0000000))
{
if (CheckWaitFlag(pasmvars, 1)) return 0;
if (CheckWaitFlag1(pasmvars, 1)) return 0;
}
// Extract parameters from the instruction
@ -143,7 +136,7 @@ int32_t ExecutePasmInstruction(PasmVarsT *pasmvars)
else if (srcaddr == 0x1f1)
value2 = GetCnt();
else if (srcaddr == 0x1f2)
value2 = pin_val;
value2 = pin_val_a;
else
value2 = pasmvars->mem[srcaddr];
@ -570,7 +563,7 @@ int32_t ExecutePasmInstruction(PasmVarsT *pasmvars)
case 1: // cmpsx
result = value1 - value2 - cflag;
cflag = value1 < (value2 + cflag);
cflag = value1 < ((int64_t)value2 + cflag);
zflag = (result == 0) & zflag;
break;
@ -620,7 +613,8 @@ int32_t ExecutePasmInstruction(PasmVarsT *pasmvars)
case 0: // cmpsub
cflag = (((uint32_t)value1) >= ((uint32_t)value2));
result = cflag ? value1 - value2 : value1;
zflag = (result == 0);
//zflag = (result == 0) & cflag;
zflag = (value1 == value2);
break;
case 1: // djnz
@ -645,7 +639,7 @@ int32_t ExecutePasmInstruction(PasmVarsT *pasmvars)
break;
case 4: // waitpeq - result, zflag and cflag not validated
result = (pin_val & value2) ^ value1;
result = (pin_val_a & value2) ^ value1;
if (result)
{
//pasmvars->state = 6;
@ -662,7 +656,7 @@ int32_t ExecutePasmInstruction(PasmVarsT *pasmvars)
break;
case 5: // waitpne - result, zflag and cflag not validated
result = (pin_val & value2) ^ value1;
result = (pin_val_a & value2) ^ value1;
if (!result)
{
//pasmvars->state = 6;

6963
pasmsim2.c

File diff suppressed because it is too large Load Diff

View File

@ -1,89 +0,0 @@
\ Define data space that will be used by the serial cog
create bufserstack 40 allot \ Data stack space
create bufserreturn 40 allot \ Return stack space
create bufserbuffer 32 allot \ Serial buffer
create bufserrdindex 0 , \ Read index
create bufserwrindex 0 , \ Write index
\ This word runs in a separate cog and writes input characters into the buffer
: bufsercog
bufserbuffer
begin
getchar over bufserwrindex @ + c!
bufserwrindex dup @ 1 + 31 and swap !
again ;
\ This word replaces the old KEY word with one that reads from the buffer
: bufkey
bufserrdindex @
begin
dup
bufserwrindex @
-
until
bufserbuffer + c@
bufserrdindex dup @ 1 + 31 and swap !
;
\ This is the cog configuration structure used by the serial cog
create bufserconfig \ Forth cog config structure
' bufsercog >body , \ Get execution token for TOGGLE
bufserstack , \ Initial value of stack ptr
bufserstack , \ Empty value for stack ptr
bufserreturn , \ Initial value of return ptr
bufserreturn , \ Empty value for return ptr
\ This word starts a cog running the BUFSER word
: startbufsercog forth @ bufserconfig cognew ;
\ This word starts the serial cog and sets key to the new one
: bufser startbufsercog ['] bufkey is key ;
\ Buffer the serial input into memory until an ESC is received
: bufferit here 256 + dup
." Buffering serial input to memory" cr
." Enter <ESC> to exit" cr
begin
key dup 27 <>
while
over c! 1+
repeat
drop over -
\ over infile cog!
;
\ Determine the length of the current line
: linelen ( addr count -- addr len )
>r dup ( addr ptr ) ( left )
begin
r@ 0 <=
if over - r> drop exit then
dup c@ dup 10 = swap 13 = or
if over - r> drop exit then
1+ r> 1- >r
again
;
\ Variables to store the buffer address and count
variable evalbufaddr
variable evalbufcount
\ Evaluate a buffer containing multiple lines
: evalbuf ( addr count )
evalbufcount !
evalbufaddr !
begin
evalbufcount @ 0 >
while
evalbufaddr @ evalbufcount @
linelen
dup 1+ dup
evalbufaddr @ + evalbufaddr !
evalbufcount @ swap - evalbufcount !
over over type cr
evaluate
repeat
;
\ Redefine switch to use buffered serial
\ : switch bufser ;

View File

@ -1,94 +0,0 @@
Changes in pfth 1.03
1. Added umod and u/ words
2. Fixed the #, udmod and ud/ words to handle numbers with the MSB set.
These changes fix a problem with the u. word when the MSB is set.
3. Fixed the putch PASM routine so that it only writes P30 in OUTA
Changes in pfth 1.02
1. Added ospfth.spin, which runs under Spinix
2. Added support for two simultaneous open files
3. Added bye and reboot words
4. Added sub-directory support
5. Added CD word to change the working directory
6. Modified the s" word to work in the interpretation mode
7. Added a kernel word to make constants and values more efficient
Changes in pfth 1.00
1. Fixed the FOR and NEXT words
2. Fixed a bug in UNLOOP
3. Added create-file, file-write, file-line, file-flush, file-close and
delete-file
4. Added linux.fth that implements simple ls, rm, cp and cat commands
5. Added sdutils.fth that contains some file utilities
6. Added TED -- a tiny text editor
7. Changed SAVE to EESAVE in i2c.fth
Changes in pfth 0.89
1. Changed the dictionary word structure to use 16-bit pointers instead of 32
bits.
2. Changed the execution list in compiled words to use 16-bit execution tokens
instead of 32 bits.
3. Changed the positions of the code pointer and DOES pointer to make the inner
loop more efficient. It now runs about 25% faster.
4. Changed SEE back to printing "_lit" for numbers.
5. Implemented a _loop kernel word to make DO-LOOP faster.
Changes in pfth 0.83
1. Changed SEE in see.fth so that it doesn't print "_lit" for numbers
2. Added bufser.fth that contains a buffered serial driver
3. Added a BUFFERIT word in bufser.fth that reads the serial input into memory
until it encounters an "ESC" character.
4. Added an EVALBUF word in bufser.fth that will evaluate multiple lines in a
memory buffer
5. Updated the readme.txt file with text contributed by Loopy
6. Updated the readme.txt file with a description of the dictionary word format
7. Added a SAVE word to i2c.fth that will write the current hub RAM image to
EEPROM. Note: The small Spin program at the end of memory must have been
preserved for this to boot properly.
8. Changed the CR word so that it emits both a carriage return and a line feed.
9. Added CASE, ENDCASE, OF and ENDOF to init.fth
10. Improved WAITCNT and MS in propwords.fth. Removed INA!
11. Fixed LIST-FILES in sd.fth to skip over deleted files in the directory
12. Changed the execution token so that it points to the code pointer instead
of the beginning of the word in the dictionary
13. Made KEY a deferred word so that it can be re-assigned to the serial input
after reading the FILEs in memory

View File

@ -1,608 +0,0 @@
\ This program was written by Lennart Benschop and converted to ANS Forth by
\ by Jeff Fox. It was further modified by Dave Hein to run under pfth. The
\ orignal source is available at http://www.ultatechnology.com/chess.html.
HEX
: scroll cr ;
: cls page ;
: key? 1 ;
: off false swap ! ;
: >defer 2 + w@ 4 - ;
3 constant maxlevel
create bp0
maxlevel 1 + c0 * allot
variable bpv
: bp bpv @ ;
: b@ bpv @ + c@ ;
: b! bpv @ + c! ;
: boardvar create ,
does> c@ bpv @ + ;
0c boardvar start
0d boardvar castlew
0e boardvar castleb
0f boardvar ep
1c boardvar starting
1d boardvar piece
1e boardvar best
1f boardvar farther?
2c boardvar wlcastle?
2d boardvar blcastle?
2e boardvar check
2f boardvar pawnmove
3c boardvar kingw
3d boardvar kingb
3e boardvar inpassing
3f boardvar advance
4c boardvar valuew
5c boardvar alfa
6c boardvar beta
7c boardvar (eval)
8c boardvar highest
9c boardvar cutoff
ac boardvar valueb
bc boardvar played
variable level
variable lastcnt
: +level
bp dup c0 + c0 cmove
c0 bpv +! 1 level +! ;
: -level
-c0 bpv +! -1 level +! ;
create symbols
CHAR . , CHAR p , CHAR k , CHAR b ,
CHAR r , CHAR q , CHAR K ,
create values
0 , 40 , c0 , c0 , 140 , 240 , 3000 ,
: .board
cls
0 0 at-xy 20 spaces
cr 2 spaces
[CHAR] H 1 + [CHAR] A do i emit 2 spaces loop
bp 20 + 8 0 do
cr 20 spaces
cr [CHAR] 8 i - emit
0a 2 do space
dup i + c@ dup
07 and cells symbols + 1 type
dup 80 and if ." W" drop else
if ." B" else ." ." then
then
loop
10 +
loop cr drop ;
: .pos
10 /mod
swap 2 - [CHAR] A + emit
[CHAR] 8 2 + swap - emit ;
\ constants that indicate the directions on the board
-11 constant nw -0f constant no
0f constant zw 11 constant zo
-10 constant n 10 constant z
-1 constant w 1 constant o
create spring
-12 , -21 , -1f , -0e , 12 , 21 , 1f , 0e ,
defer tmove
defer attacktest
: mine?
b@ dup 0= 0= swap 80 and start c@ = and ;
variable movits
: moveit
starting c@ best c! 1 farther? c!
begin
best c@ over + dup best c!
dup mine? over b@ 87 = or 0=
farther? c@ and while
tmove
b@ 0= farther? c!
repeat
drop drop
1 movits +! ;
: Bishop
no nw zo zw moveit moveit moveit moveit ;
: Rook
n o z w moveit moveit moveit moveit ;
: Queen
n o z w no nw zo zw 8 0 do moveit loop ;
: Knight
8 0 do
i cells spring + @
starting c@ + dup best c!
dup mine? swap b@ 87 = or 0=
if tmove then
loop ;
: ?castle
start c@ 80 = if castlew else castleb then c@ check c@ 0= and ;
: ?lcastle
start c@ 80 = if wlcastle? else blcastle? then c@ check c@ 0= and ;
: king
n o z w no nw zo zw 8 0 do
starting c@ + dup best c!
dup mine? swap b@ 87 = or 0=
if tmove then
loop
?castle if 28 start c@ if 70 + then
dup bp + 1- @ 0=
if
dup 1- attacktest 0=
if
best c! tmove
else drop then
else drop then
then
?lcastle if 24 start c@ if 70 + then
dup bp + @ over bp + 1- @ or 0=
if
dup 1 + attacktest 0=
if
best c! tmove
else drop then
else drop then
then ;
: Pawnrow
start c@ if negate then ;
: Pawnz
dup best c!
f0 and start c@ if 20 else 90 then =
if 6 2 do i advance c! tmove loop
else tmove then
0 pawnmove c! 0 inpassing c! 0 advance c! ;
: Pawn
starting c@ z Pawnrow +
dup b@ if
drop
else
dup Pawnz
z Pawnrow + dup b@ if
drop
else
starting c@ f0 and
start c@ if 80 else 30 then =
if starting c@ 0f and pawnmove c!
Pawnz
else drop
then
then
then
zw zo 2 0 do
Pawnrow starting c@ +
dup f0 and start c@ if 40 else 70 then =
over 0f and ep c@ = and
if 1 inpassing c!
dup Pawnz
then
dup b@ dup 0= 2 pick mine? or
swap 87 = or
if drop else Pawnz then
loop ;
create pieces
' noop , ' Pawn , ' Knight , ' Bishop , ' Rook , ' Queen , ' king ,
: piecemove
\ using above jump table for each type of piece - jump table uses , (CELLS)
piece c@ cells pieces + @ execute ;
: ?piecemove
starting c@ dup mine? if
b@ 07 and piece c!
0 pawnmove c! 0 inpassing c! 0 advance c!
piecemove
else drop then ;
: allmoves
[char] . emit
start c@ 0= if
22 starting c!
8 0 do
8 0 do
?piecemove starting c@ 1 + starting c!
loop
starting c@ 8 + starting c!
loop
else
92 starting c!
8 0 do
8 0 do
?piecemove starting c@ 1 + starting c!
loop
starting c@ 18 - starting c!
loop
then ;
variable attack
: ?attack
best c@ dup mine? 0=
swap b@ 07 and piece c@ = and
attack @ or attack ! ;
: attacked?
attack off 0 7 1 do
i piece c!
piecemove
attack @ if drop 1 leave then
loop ;
variable starting'
variable best'
variable start'
variable tmove'
: settest
starting c@ starting' c!
best c@ best' c!
start c@ start' c!
['] tmove >defer tmove' !
['] ?attack is tmove ;
: po@
starting' c@ starting c!
best' c@ best c!
start' c@ start c!
tmove' @ is tmove ;
: changecolor
start c@ 80 xor start c! ;
variable endf
variable playlevel
variable #legal
variable selected
variable compcolor
variable move#
create bp1 c0 allot
: endgame?
start c@ if valueb else valuew then @ c1 < ;
: evalboard
valueb @ valuew @ - start c@ if negate then
55 mine? 1 and + 56 mine? 1 and + 65 mine? 1 and + 66 mine? 1 and +
changecolor 55 mine? + 56 mine? + 65 mine? + 66 mine? + changecolor
endgame? if
start c@ if kingb else kingw then c@
dup f0 and dup 20 = swap 90 = or 7 and
swap 0f and dup 2 = swap 9 = or 7 and + +
then ;
: ?check
settest
start c@ if kingw else kingb then c@
starting c! attacked? check c!
po@ ;
: (attacktest)
['] tmove >defer ['] ?attack <> if
settest
starting c!
attacked?
po@
else drop true
then ;
' (attacktest) is attacktest
variable seed
: rnd
seed @ 743 * 43 + dup seed ! ;
\ 1 ;
: domove
best c@ b@ 7 and cells values + @ negate start c@
if valueb else valuew then +!
starting c@ b@ best c@ b!
0 starting c@ b!
advance c@ if
advance c@ dup cells values + @ 40 - start c@
if valueb else valueb then +!
start c@ or best c@ b!
then
piece c@ 4 = if
starting c@ 0f and 2 =
if
0 start c@ if wlcastle? else blcastle? then c!
then
starting c@ 0f and 9 =
if
0 start c@ if castlew else castleb then c!
then
then
piece c@ 6 = if
0 0 start c@ if castlew else castleb then dup >r c!
r> 1f + c!
best c@ starting c@ - 2 =
if
4 start c@ or best c@ 1- b!
0 best c@ 1 + b!
then
best c@ starting c@ - -2 =
if
4 start c@ or best c@ 1 + b!
0 best c@ 2 - b!
then
best c@ start c@ if kingw else kingb then c!
then
inpassing c@ if
0 best c@ n Pawnrow + b!
-40 start c@ if valueb else valuew then +!
then
pawnmove c@ ep c! ;
: deeper
cutoff @
invert if
+level
domove
?check check c@ if -level exit then
-1 played c0 - !
level @ playlevel @ = if
evalboard
(eval) c0 - !
else
alfa @ highest !
alfa @ negate beta @ negate alfa ! beta !
changecolor
0 played !
allmoves
played @ 0= if
?check check c@ if -2000 highest ! else 0 highest ! then
then
highest @ negate
(eval) c0 - !
then
-level
(eval) @ highest @ max
highest !
highest @ beta @ > if TRUE cutoff ! then
then ;
: analyse
+level
domove
?check check c@ 0= if
1 #legal +!
changecolor
['] tmove >defer
['] deeper is tmove
0 played !
allmoves
is tmove
played @ 0= if
?check check c@ if -2000 highest ! else 0 highest ! then
then
highest @ beta c0 - @ = if
rnd 2000 > if #legal @ selected ! then
then
highest @ beta c0 - @ < if
#legal @ selected !
highest @ beta c0 - !
then
then
-level ;
: select
+level
domove
?check check c@ 0= if
1 #legal +!
#legal @ selected @ = if
bp bp1 c0 cmove
starting c@ .pos ." -" best c@ .pos space
then
then
-level ;
: against
+level
domove
?check check c@ 0= if
1 #legal +!
then
-level ;
: compmove
.board
['] analyse is tmove
0 #legal !
-4000 alfa ! 4000 beta !
\ 0 18 at-xy cr
scroll
\ 28 spaces
start c@ if 1 move# +! move# @ 3 .r space else 4 spaces then
?check check c@ if ." Check" then
1 selected !
allmoves
#legal @ 0= if
check c@ if
." mate"
else
." Pat"
then
TRUE endf !
else
['] select is tmove
0 #legal !
allmoves
bp1 bp0 c0 cmove
changecolor
['] against is tmove
0 #legal !
allmoves
?check check c@ if ." Check" then
#legal @ 0= if
check c@ if
." mate"
else
." Pat"
then
TRUE endf !
then
then
.board ;
variable startingm
variable bestm
variable personmove
: legal
startingm @ starting c@ =
bestm @ best c@ = and
personmove @ advance c@ = and
if
+level
domove
?check check c@ 0= if
1 #legal !
bp bp1 c0 cmove
then
-level
then ;
create inputbuf 6 allot
: inpos
dup inputbuf + c@ [CHAR] A -
dup 8 u<
rot inputbuf + 1 + c@ [CHAR] 1 -
dup 8 u< rot and
swap 7 swap - 10 * rot + 22 + ;
: promote
0 6 2 do over symbols i cells + c@ = if drop i then loop ;
: person
begin
.board
scroll
\ 28 spaces
start c@ if 1 move# +! move# @ 3 .r else 3 spaces then
inputbuf 5 expect cr
\ [char] X emit inputbuf 5 type [char] X emit
inputbuf c@ [CHAR] Q = if quit then
0 inpos startingm !
2 inputbuf + c@ [CHAR] - = and
3 inpos bestm !
and
bestm @ f0 and start c@ if 20 else 90 then =
startingm b@ 07 and 1 = and
if
." What piece? " 0 0 begin drop drop key promote dup until
personmove ! emit
else
0 personmove !
then
if
['] legal is tmove
0 #legal !
startingm c@ starting c! ?piecemove
#legal @
else
0
then
dup 0= start c@ and if -1 move# +! then
until
bp1 bp0 c0 cmove
changecolor
cr
.board ;
: setmove
compcolor @ 0< start c@ 80 = = if compmove else person then ;
variable manVsMachine
: askcolor
manVSmachine @
if ." Do you want White Y/N"
key dup [CHAR] Y = swap [CHAR] y = or
if 1 else -1 then compcolor !
then ;
: asklevel
cr ." Level? 2-"
maxlevel . key [CHAR] 0 - 2 max maxlevel min playlevel !
cls ;
: init
0 level ! bp0 bpv !
bp c0 87 fill
4 2 3 6 5 3 2 4 8 0 do bp 22 + i + c! loop
bp 32 + 8 01 fill
bp 42 + 8 00 fill bp 52 + 8 00 fill
bp 62 + 8 00 fill bp 72 + 8 00 fill
bp 82 + 8 81 fill
84 82 83 86 85 83 82 84 8 0 do bp 92 + i + c! loop
1 castlew c! 1 castleb c! 0 ep c! 1 wlcastle? c! 1 blcastle? c! 0 advance c!
80 start c! 96 kingw c! 26 kingb c!
askcolor cr asklevel
0 move# ! 0 endf !
0 check c! 9c0 valuew ! 9c0 valueb ! ;
: play
begin setmove endf @ until ;
: games
begin init play again ;
: autoplay
begin setmove compcolor @ negate compcolor ! key? if quit then endf @ until ;
: auto
init -1 compcolor ! autoplay ;
: chess
cls
." ANS Forth Chess" cr
." Do you want to play against the computer? Y/N" cr
begin rnd drop key? until key
dup [CHAR] Y = swap [CHAR] y = or dup manVsMachine !
if games else auto then ;
decimal

View File

@ -1,145 +0,0 @@
( This program checks for all 133 ANS Forth core words )
: checkword 1 + ' 0 =
if swap 1 + swap source type ." failed" 13 emit 10 emit then ;
: checkdone swap dup
if swap dup rot rot swap - . ." out of "
else drop ." All " then
. ." ANS Forth core words implemented" 13 emit 10 emit ;
0 0
checkword !
checkword #
checkword #>
checkword #S
checkword '
checkword (
checkword *
checkword */
checkword */MOD
checkword +
checkword +!
checkword +LOOP
checkword ,
checkword -
checkword .
checkword ."
checkword /
checkword /MOD
checkword 0<
checkword 0=
checkword 1+
checkword 1-
checkword 2!
checkword 2*
checkword 2/
checkword 2@
checkword 2DROP
checkword 2DUP
checkword 2OVER
checkword 2SWAP
checkword :
checkword ;
checkword <
checkword <#
checkword =
checkword >
checkword >BODY
checkword >IN
checkword >NUMBER
checkword >R
checkword ?DUP
checkword @
checkword ABORT
checkword ABORT"
checkword ABS
checkword ACCEPT
checkword ALIGN
checkword ALIGNED
checkword ALLOT
checkword AND
checkword BASE
checkword BEGIN
checkword BL
checkword C!
checkword C,
checkword C@
checkword CELL+
checkword CELLS
checkword CHAR
checkword CHAR+
checkword CHARS
checkword CONSTANT
checkword COUNT
checkword CR
checkword CREATE
checkword DECIMAL
checkword DEPTH
checkword DO
checkword DOES>
checkword DROP
checkword DUP
checkword ELSE
checkword EMIT
checkword ENVIRONMENT?
checkword EVALUATE
checkword EXECUTE
checkword EXIT
checkword FILL
checkword FIND
checkword FM/MOD
checkword HERE
checkword HOLD
checkword I
checkword IF
checkword IMMEDIATE
checkword INVERT
checkword J
checkword KEY
checkword LEAVE
checkword LITERAL
checkword LOOP
checkword LSHIFT
checkword M*
checkword MAX
checkword MIN
checkword MOD
checkword MOVE
checkword NEGATE
checkword OR
checkword OVER
checkword POSTPONE
checkword QUIT
checkword R>
checkword R@
checkword RECURSE
checkword REPEAT
checkword ROT
checkword RSHIFT
checkword S"
checkword S>D
checkword SIGN
checkword SM/REM
checkword SOURCE
checkword SPACE
checkword SPACES
checkword STATE
checkword SWAP
checkword THEN
checkword TYPE
checkword U.
checkword U<
checkword UM*
checkword UM/MOD
checkword UNLOOP
checkword UNTIL
checkword VARIABLE
checkword WHILE
checkword WORD
checkword XOR
checkword [
checkword [']
checkword [CHAR]
checkword ]
checkdone

View File

@ -1,57 +0,0 @@
( This program checks for all 45 ANS Forth core ext words )
: checkword 1 + ' 0 =
if swap 1 + swap source type ." failed" 13 emit 10 emit then ;
: checkdone swap dup
if swap dup rot rot swap - . ." out of "
else drop ." All " then
. ." ANS Forth core ext words implemented" 13 emit 10 emit ;
0 0
checkword #tib
checkword .(
checkword .r
checkword 0<>
checkword 0>
checkword 2>r
checkword 2r>
checkword 2r@
checkword :noname
checkword <>
checkword ?do
checkword again
checkword c"
checkword case
checkword compile,
checkword convert
checkword endcase
checkword endof
checkword erase
checkword expect
checkword false
checkword hex
checkword marker
checkword nip
checkword of
checkword pad
checkword parse
checkword pick
checkword query
checkword refill
checkword restore-input
checkword roll
checkword save-input
checkword source-id
checkword span
checkword tib
checkword to
checkword true
checkword tuck
checkword u.r
checkword u>
checkword value
checkword within
checkword [compile]
checkword \
checkdone

View File

@ -1,29 +0,0 @@
( Useful non-standard words )
: @+ dup cell+ swap @ ;
: !+ over ! cell+ ;
: c@+ dup char+ swap c@ ;
: c!+ over c! char+ ;
: between 1+ within ;
: bounds over + swap ;
: buffer: create allot ;
: cell 4 ;
: cell- cell - ;
: not 0= ;
: parse-word bl word count ;
: perform @ execute ;
: >= < 0= ;
: <= > 0= ;
: -rot rot rot ;
: 2- 2 - ;
: 2+ 2 + ;
: 3dup dup 2over rot ;
: 4dup 2over 2over ;
: noop ;
: off false swap ! ;
: on true swap ! ;
: for ['] >r compile, ['] _lit compile, 0 compile, ['] >r compile, here ;
immediate
: next ['] _lit compile, 1 compile, ['] _loop compile, ['] _jz compile,
compile, ['] r> compile, ['] r> compile, ['] 2drop compile, ; immediate
: zstrlen dup begin dup c@ while 1+ repeat swap - ;
: zcount dup zstrlen ;

View File

@ -1,88 +0,0 @@
\ ############################################################################
\ # fds.fth - This program implements a full duplex serial port. It is base
\ # on the FullDuplexSerial Spin object.
\ #
\ # Copyright (c) 2012 Dave Hein
\ # MIT Licensed
\ ############################################################################
0 value fds_cog
create fds_vars 68 allot
: fds_var create , does> @ fds_vars + ;
0 fds_var rx_head
4 fds_var rx_tail
8 fds_var tx_head
12 fds_var tx_tail
16 fds_var rx_pin
20 fds_var tx_pin
24 fds_var rxtx_mode
28 fds_var bit_ticks
32 fds_var buffer_ptr
36 fds_var rx_buffer
52 fds_var tx_buffer
hex
create fds_entry
a0bca9f0 , 80fca810 , 08bcaa54 , a0fcb201 , 2cbcb255 , 80fca804 , 08bcaa54 ,
a0fcbe01 , 2cbcbe55 , 80fca804 , 08bcae54 , 80fca804 , 08bcb054 , 80fca804 ,
08bcb454 , a0bcc05a , 80fcc010 , 627cae04 , 617cae02 , 689be85f , 68abec5f ,
a0fcc833 , 5cbcbc64 , 627cae01 , 613cb3f2 , 5c640016 , a0fcb809 , a0bcba58 ,
28fcba01 , 80bcbbf1 , 80bcba58 , 5cbcbc64 , a0bca85d , 84bca9f1 , c17ca800 ,
5c4c001f , 613cb3f2 , 30fcb601 , e4fcb81e , 28fcb617 , 60fcb6ff , 627cae01 ,
6cd4b6ff , 08bcabf0 , 80bcaa5a , 003cb655 , 84bcaa5a , 80fcaa01 , 60fcaa0f ,
083cabf0 , 5c7c0016 , 5cbcc85e , a0bca9f0 , 80fca808 , 08bcaa54 , 80fca804 ,
08bcac54 , 863caa56 , 5c680033 , 80bcac60 , 00bcc256 , 84bcac60 , 80fcac01 ,
60fcac0f , 083cac54 , 68fcc300 , 2cfcc202 , 68fcc201 , a0fcc40b , a0bcc7f1 ,
627cae04 , 617cae02 , 6ce0c201 , 29fcc201 , 70abe85f , 7497ec5f , 80bcc658 ,
5cbcc85e , a0bca863 , 84bca9f1 , c17ca800 , 5c4c004d , e4fcc446 , 5c7c0033 ,
decimal
: fds_start ( rxpin txpin mode baudrate ... )
>r
fds_vars 16 0 fill
rxtx_mode ! tx_pin ! rx_pin !
clkfreq@ r> / bit_ticks !
rx_buffer buffer_ptr !
0 dira!
fds_entry rx_head cognew
1+ dup to fds_cog
;
: fds_stop fds_cog if fds_cog 1- cogstop 0 to fds_cog then ;
: fds_rxcheck rx_tail @ rx_head @ 2dup . . cr =
if
-1
else
rx_tail @ rx_buffer + c@
rx_tail @ 1+ 15 and rx_tail !
then
;
: fds_rx begin fds_rxcheck dup -1 = while drop repeat ;
: fds_tx begin tx_tail @ tx_head @ 1+ 15 and <> until
tx_head @ tx_buffer + c!
tx_head @ 1+ 15 and tx_head !
rxtx_mode @ 8 and if fds_rx then
;
: fdstest
." Type 'q' to quit" cr
31 30 0 115200 fds_start
drop
begin
fds_rx
dup [char] q <>
while
[char] < fds_tx fds_tx [char] > fds_tx
repeat
drop
fds_stop
1 30 lshift dira!
;

View File

@ -1,217 +0,0 @@
\ ############################################################################
\ # i2c.fth - This program reads and writes EEPROMs using the I2C protocol.
\ # This program is based on Mike Green's basic_i2c_driver, which is found in
\ # the Parallax Object Exchange (OBEX).
\ #
\ # The first parameter for all routines is the pin number of the clock. It
\ # is assumed that the data pin number is one greater than the clock pin
\ # number.
\ #
\ # Copyright (c) 2012 Dave Hein
\ # MIT Licensed
\ ############################################################################
: i2c_dira_sda_high dup dira@ or dira! ;
: i2c_outa_sda_high dup outa@ or outa! ;
: i2c_dira_scl_high over dira@ or dira! ;
: i2c_outa_scl_high over outa@ or outa! ;
: i2c_dira_sda_low dup invert dira@ and dira! ;
: i2c_outa_sda_low dup invert outa@ and outa! ;
: i2c_dira_scl_low over invert dira@ and dira! ;
: i2c_outa_scl_low over invert outa@ and outa! ;
\ This routine should be called before calling any of the other ones to ensure
\ that the EEPROM is in a known ready state.
: i2c_init ( scl ... )
1 swap lshift dup 2* \ sda := scl + 1
i2c_outa_scl_high \ outa[scl] := 1
i2c_dira_scl_high \ dira[scl] := 1
i2c_dira_sda_low \ dira[sda] := 0
9 0 do \ repeat 9
i2c_outa_scl_low \ outa[scl] := 0
i2c_outa_scl_high \ outa[scl[ := 1
dup ina@ and if leave then \ if ina[sda] quit
loop
2drop
;
\ This routine sends a start bit
: i2c_start ( scl ... )
1 swap lshift dup 2* \ sda := scl + 1
i2c_outa_scl_high \ outa[scl]~~
i2c_dira_scl_high \ dira[scl]~~
i2c_outa_sda_high \ outa[sda]~~
i2c_dira_sda_high \ dira[sda]~~
i2c_outa_sda_low \ outa[sda]~
i2c_outa_scl_low \ outa[scl]~
2drop
;
\ This routine sends a stop bit
: i2c_stop ( scl ... )
1 swap lshift dup 2* \ sda := scl + 1
i2c_outa_scl_high \ outa[scl]~~
i2c_outa_sda_high \ outa[sda]~~
i2c_dira_scl_low \ dira[scl]~
i2c_dira_sda_low \ dira[sda]~
2drop
;
\ This routine sends one byte and returns the ACK bit
: i2c_write ( scl data ... ackbit )
23 lshift swap \ data <<= 23
1 swap lshift dup 2* \ sda := scl + 1
8 0 do \ repeat 8
rot 2* dup 0<
if
rot rot
i2c_outa_sda_high \ outa[sda] := 1
else
rot rot
i2c_outa_sda_low \ outa[sda] := 0
then
i2c_outa_scl_high \ outa[scl]~~
i2c_outa_scl_low \ dira[scl]~
loop
i2c_dira_sda_low \ dira[sda]~
i2c_outa_scl_high \ outa[scl]~~
dup ina@ and >r \ ackbit := ina[sda]
i2c_outa_scl_low \ outa[scl]~
i2c_outa_sda_low \ outa[sda]~
i2c_dira_sda_high \ dira[sda]~~
2drop drop
r> \ return ackbit
;
\ This routine reads one byte from the EEPROM
: i2c_read ( scl ackbit ... data )
>r \ save ackbit
0 swap \ data := 0
1 swap lshift dup 2* \ sda := scl + 1
i2c_dira_sda_low \ dira[sda]~
8 0 do \ repeat 8
i2c_outa_scl_high \ outa[scl]~~
rot 2* \ data <<= 1
over ina@ and if 1 or then \ if ina[sda] data |= 1
rot rot
i2c_outa_scl_low \ outa[scl]~
loop
r> if
i2c_outa_sda_high \ outa[sda]~~
else
i2c_outa_sda_low \ outa[sda]~
then
i2c_dira_sda_high \ dira[sda]~~
i2c_outa_scl_high \ outa[scl]~~
i2c_outa_scl_low \ outa[scl]~
i2c_outa_sda_low \ outa[sda]~
2drop \ return data
;
\ This routine reads up to one page of data from the EEPROM
: i2c_readpage ( scl devsel addrreg dataptr count ... ackbit )
>r >r \ Move count and dataptr to the return stack
dup 15 rshift 14 and rot or \ Assemble the devsel byte
dup >r rot dup dup >r \ Copy devsel and scl to the return stack
i2c_start \ Send a start bit
swap \ Arrange the scl and devsel on the stack
i2c_write drop \ Send the devsel byte
dup 8 rshift 255 and r@ swap \ Extract the second address byte
i2c_write drop \ Send the second address byte
255 and r@ swap \ Extract the third address byte
i2c_write drop \ Send it
r@ \ Get the scl from the return stack
i2c_start \ Send a start bit
r> r> 1 or over >r \ Get the scl and devsel byte and set the LSB
i2c_write drop \ Send the devsel byte
r> r> r> 1 ?do \ Get scl, dataptr and count and start do loop
over 0 i2c_read over c! 1+ \ Read a byte from the EEPROM and save it
loop
over 1 i2c_read swap c! \ Read the last byte from the EEPROM
i2c_stop \ Send a stop bit
0 \ Return the ack bit
;
variable i2c_var
\ This routine reads a byte from the specified address
: i2c_readbyte ( scl devsel addrreg )
i2c_var 1 i2c_readpage drop i2c_var c@ ;
\ This routine reads a word from the specified address
: i2c_readword ( scl devsel addrreg )
0 i2c_var ! i2c_var 2 i2c_readpage drop i2c_var @ ;
\ This routine reads a long from the specified address
: i2c_readlong ( scl devsel addrreg )
i2c_var 4 i2c_readpage drop i2c_var @ ;
\ This routine writes up to one page of data to the EEPROM
: i2c_writepage ( scl devsel addrreg dataptr count ... ackbit )
>r >r \ ( scl devsel addrreg ) r( count dataptr )
dup 15 rshift 14 and rot or \ ( scl addrreg devsel )
rot dup >r \ ( addrreg devsel scl ) r( count dataptr scl )
i2c_start \ ( addrreg devsel ) r( count dataptr scl )
r@ swap \ ( addrreg slc devsel ) r( count dataptr scl )
i2c_write drop \ ( addrreg ) r( count dataptr scl )
dup 8 rshift 255 and r@ swap
i2c_write drop
255 and r@ swap
i2c_write drop
r> r> r> 0 ?do
2dup c@ i2c_write drop 1+
loop
drop
i2c_stop
0
;
\ This routine writes a byte to the specified address
: i2c_writebyte ( scl devsel addrreg data )
i2c_var ! i2c_var 1 i2c_writepage drop ;
\ This routine writes a word to the specified address
: i2c_writeword ( scl devsel addrreg data )
i2c_var ! i2c_var 2 i2c_writepage drop ;
\ This routine writes a long to the specified address
: i2c_writelong ( scl devsel addrreg data )
i2c_var ! i2c_var 4 i2c_writepage drop ;
\ This routine returns a zero if the EEPROM is ready after a write
\ Otherwise it returns a non-zero value
: i2c_writewait ( scl devsel addrreg )
15 rshift 14 and or
over i2c_start
over >r i2c_write
r> i2c_stop
;
\ This word will be run at startup
: startup
1 30 lshift dup outa! dira!
pfthversion type cr
;
\ Set up the cog config struct
: setupconfig
496 cog@ \ Get config struct address from PAR
dup 16 + @ \ Get the address of the return stack
4 + over 12 + ! \ Add four and set initial address of return stack
['] interpret >body \ Get the address of the Forth interpreter
over 16 + @ ! \ Write it to the return stack
['] startup >body \ Get the address of the startup word
swap ! \ Write it to the intial value of the program counter
;
\ Save the hub RAM to EEPROM
: eesave
setupconfig
28 i2c_init
512 0
do
28 160 i 64 * dup 64 i2c_writepage drop
begin 28 160 0 i2c_writewait 0= until
i 7 and 7 = if [char] . emit then
loop
;

View File

@ -1,400 +0,0 @@
: link>flags 2 + ;
: immediate 81 last @ link>flags c! ;
: \ 100 word drop ; immediate
\ The above lines implement the words to allow for "\" comments
\ All numbers are in hex at this point.
\ DEFINE CELL SIZE
: cellsize 4 ;
: cellmask 3 ;
: compsize 2 ;
: compmask 1 ;
\ BASIC STACK WORDS
: rot 2 roll ;
: over 1 pick ;
: 2dup over over ;
: 2drop drop drop ;
: 2swap 3 roll 3 roll ;
: 2over 3 pick 3 pick ;
\ WORD HEADER ACCESSORS
: >does 2 + ;
: >body 4 + ;
: name>xt dup c@ + 4 + 0 4 - and ;
: link>name 3 + ;
: link>xt link>name name>xt ;
: link>does link>xt 2 + ;
: link>body link>xt 4 + ;
\ DEFINE BASIC WORD BUILDERS
: source tib #tib @ ;
\ : compile, , ;
: ' 20 word find 0 = 0 = and ;
: _does r> dup >r 2 + last @ link>does w! ;
: _setjmp 0a last @ link>flags c! ;
: literal 0 compile, compile, ; immediate
last @ link>body dup @ swap 2 + w! \ Patch in address of _lit
: postpone ' compile, ; immediate
: ['] ' postpone literal ; immediate
: [compile] ' postpone literal ['] compile, compile, ; immediate
: does> [compile] _does [compile] exit ; immediate
\ CONDITIONAL EXECUTION AND LOOPING
: if ['] _jz compile, here 2 allot ; immediate
: else ['] _jmp compile, here 2 + swap w! here 2 allot ; immediate
: then here swap w! ; immediate
: begin here ; immediate
: until ['] _jz compile, compile, ; immediate
: again ['] _jmp compile, compile, ; immediate
: while ['] _jz compile, here 2 allot ; immediate
: repeat ['] _jmp compile, here 2 + swap w! compile, ; immediate
: do ['] _lit compile, here 2 allot ['] drop compile,
['] swap compile, ['] >r compile, ['] >r compile, here ; immediate
: ?do ['] 2dup compile, ['] > compile, ['] _jz compile, here 2 allot
['] swap compile, ['] >r compile, ['] >r compile, here ; immediate
\ : _loop r> swap r> + r> dup >r swap dup >r > 0 = swap >r ;
: loop ['] _lit compile, 1 compile, ['] _loop compile, ['] _jz compile, compile, ['] r> compile,
['] r> compile, here swap w! ['] 2drop compile, ; immediate
: +loop ['] _loop compile, ['] _jz compile, compile, ['] r> compile,
['] r> compile, here swap w! ['] 2drop compile, ; immediate
: leave r> r> drop r> dup >r >r >r ;
: i r> r> dup >r swap >r ;
: j r> r> r> r> dup >r swap >r swap >r swap >r ;
\ DEFINE >FLAGS AND >LINK
: >flags begin 1 - dup c@ 80 and until ;
: >link >flags 2 - ;
\ DEFINE DEFER AND IS
\ Change code pointer from varfunc to deferfunc
: defer create last @ link>xt dup w@ 3 + swap w! ;
: is state @
if [compile] >body ' >does postpone literal [compile] w!
else >body ' >does w!
then ; immediate
\ REDEFINE REFILL AS A DEFERRED WORD
' refill
defer refill
is refill
\ DEFINE "(" COMMENT WORD NOW THAT WE CAN LOOP
: ( begin
#tib @ >in @
?do tib i + c@ 29 = if i 1 + >in ! r> r> drop drop exit then loop
refill 0 =
until ; immediate
( PAD AND PRINT SUPPORT )
create pad 100 allot
create printptr 4 allot
: _d2a dup 0a < if 30 else 57 then + ;
: _a2d dup 30 <
if
drop 0 1 -
else
dup 39 >
if
dup 41 <
if
drop 0 1 -
else
dup 5a >
if
dup 61 <
if
drop 0 1 -
else
dup 7a >
if
drop 0 1 -
else
57 -
then
then
else
37 -
then
then
else
30 -
then
then
dup base @ < 0 =
if
drop 0 1 -
then
;
: c!-- dup >r c! r> 1 - ;
: cprint printptr @ c! printptr @ 1 - printptr ! ;
( DOUBLE WORDS )
: s>d 0 pick 0 < ;
: m* * s>d ;
: um* * 0 ;
: d+ drop 1 roll drop + s>d ;
: d- drop 1 roll drop - s>d ;
: d* drop 1 roll drop * s>d ;
: d/ drop 1 roll drop / s>d ;
: dmod drop 1 roll drop mod s>d ;
: _u/ over over swap 1 rshift swap / dup + dup >r over * rot swap - swap < 1 + r> + ;
: u/ over 0 < if _u/ else / then ;
: ud/ drop 1 roll drop u/ 0 ;
: _umod swap dup 1 rshift 2 pick mod dup + swap 1 and + swap mod ;
: umod over 0 < if _umod else mod then ;
: udmod drop 1 roll drop umod 0 ;
( CORE WORDS )
: +! dup @ rot + swap ! ;
: /mod over over >r >r mod r> r> / ;
: [ state 0 ! ;
: ] state 1 ! ;
: r@ r> r> dup >r swap >r ;
: sm/rem >r 2dup r@ s>d d/ drop r> swap >r s>d dmod drop r> ;
: um/mod >r 2dup r@ s>d ud/ drop r> swap >r s>d udmod drop r> ;
: fm/mod over over xor 1 31 lshift and if sm/rem else sm/rem then ; ( TODO )
: */mod >r m* r> sm/rem ;
: */ */mod swap drop ;
: <# pad ff + printptr ! ;
: hold cprint ;
: # drop dup base @ umod _d2a cprint base @ u/ 0 ;
: #s begin # over over or 0 = until ;
: #> drop drop printptr @ 1 + dup pad 100 + swap - ;
: sign 0 < if 2d hold then ;
: abs dup 0 < if 0 swap - then ;
: type 0 ?do dup c@ emit 1 + loop drop ;
: ._ dup abs 0 <# #s rot sign #> type ;
: . ._ 20 emit ;
: >number dup 0 ?do >r dup c@ _a2d dup 0 < if drop r> leave else swap >r >r
base @ 0 d* r> 0 d+ r> 1 + r> 1 - then loop ;
: 0= 0 = ;
: 0< 0 < ;
: 1+ 1 + ;
: 1- 1 - ;
: 2! swap over ! cellsize + ! ;
: 2* dup + ;
: 2/ dup 80000000 and swap 1 rshift or ;
: 2@ dup cellsize + @ swap @ ;
: ?dup dup if dup then ;
: aligned cellmask + 0 cellsize - and ;
: align here aligned here - allot ;
: bl 20 ;
: c, here c! 1 allot ;
: cell+ cellsize + ;
: cells cellsize * ;
: char+ 1 + ;
: chars ;
\ : count dup char+ swap c@ ;
: char 20 word count 0= if drop 0 else c@ then ;
: [char] char postpone literal ; immediate
\ : constant create here ! cellsize allot does> @ ;
: constant create , last @ link>xt dup w@ 3 - swap w! ;
: cr 0a emit 0d emit ;
: decimal 0a base ! ;
: environment? drop drop 0 ;
: fill swap >r swap r> 0 ?do 2dup c! 1 + loop 2drop ;
: hex 10 base ! ;
: invert 0 1 - xor ;
: max 2dup < if swap then drop ;
: min 2dup > if swap then drop ;
\ : cmove >r swap r> 0 ?do 2dup c@ swap c! 1+ swap 1+ swap loop 2drop ;
: cmove> >r swap r> dup >r 1- dup >r + swap r> + swap r> ?do 2dup c@ swap c!
1- swap 1- swap loop 2drop ;
: move r> 2dup > if r> cmove else r> cmove> then ;
: negate 0 swap - ;
: recurse last @ , ; immediate
: _lit" r> dup 1 + swap dup c@ dup rot + compsize + 0 compsize - and >r ;
84 last @ link>flags c! ( Set STRING flag )
: _compile" [char] " word count dup >r dup >r c, here r> cmove r> allot
compsize here - compmask and allot ; immediate
create s"buf 50 allot
: s" state @ if ['] _lit" compile, postpone _compile" else
[char] " word count >r s"buf r@ cmove s"buf r> then ; immediate
: ." postpone s" ['] type compile, ; immediate
: _abort" if type abort else drop drop then ;
\ : abort" postpone s" ['] _abort" compile, ; immediate
: abort" postpone s" ['] _abort" compile, ;
: space 20 emit ;
: spaces 0 ?do space loop ;
: u._ 0 <# #s #> type ;
: u. u._ 20 emit ;
: u< over over xor 1 31 lshift and if swap then < ;
: unloop r> r> r> drop drop >r ;
: variable create cellsize allot ;
( CORE EXT )
: 0<> 0= invert ;
: 0> 0 > ;
: 2>r r> rot >r swap >r >r ;
: 2r> r> r> r> rot >r swap ;
: 2r@ r> r> r> 2dup >r >r swap rot >r ;
: <> = 0= ;
: erase 0 ?do dup 0 swap ! 1 + loop drop ;
variable span
: expect accept span ! ;
: false 0 ;
: marker create last @ , does> @ dup dp ! @ last ! ;
: nip swap drop ;
: parse word count ;
: true 0 1 - ;
: tuck swap over ;
: to ' >body state @ if postpone literal [compile] ! else ! then ; immediate
\ : value create here ! cellsize allot does> @ ;
: value create , last @ link>xt dup w@ 3 - swap w! ;
: within over - >r - r> u< ;
: .r_ >r dup abs 0 <# #s rot sign #> dup r> swap - spaces type ;
: .r .r_ 20 emit ;
: u.r_ >r 0 <# #s #> dup r> swap - spaces type ;
: u.r .r_ 20 emit ;
: u> over over xor 80000000 and if swap then > ;
: unused 8000 here - ;
: case 0 ; immediate
: of ['] over compile, ['] = compile,
['] _jz compile, here 4 allot ['] drop compile, ; immediate
: endof ['] _jmp compile, here 2 + swap w! here 2 allot ; immediate
: endcase ['] drop compile, begin ?dup while here swap w! repeat ; immediate
: c" ['] _lit" compile, postpone _compile" ['] drop compile, ['] 1- compile, ; immediate
: .( [char] ) word count type ; immediate
: :noname align here ['] words @ , [ ;
( DOUBLE )
: d= rot = rot rot = and ;
: d0= or 0 = ;
: 2constant create swap , , does> dup @ swap cellsize + @ ;
( STRING )
: blank 0 ?do dup bl swap c! 1+ loop drop ;
: -trailing dup 0 ?do 2dup + 1- c@ bl = if 1- else leave then loop ;
: /string dup >r - swap r> + swap ;
( TOOLS )
: ? @ . ;
: .s 3c emit depth ._ 3e emit 20 emit depth 0 ?do depth i - 1 - pick . loop ;
: dump 0 ?do i 0f and 0 = if cr dup . then dup c@ 3 .r 1 + loop drop cr ;
: forget 20 word find if >link dup dp ! w@ last ! else abort" ?" then ;
: .name dup link>name count type space ;
: ?newline dup >r link>name c@ dup rot + 1 + dup 4e > if cr else swap then drop r> ;
: words 0 last @ begin dup while ?newline .name w@ repeat 2drop ;
( UTILITY )
: at-xy 2 emit swap emit emit ;
: page 0 emit ;
( VERSION STRING )
: pfthversion s" pfth 1.03" ;
create evalmode 0 ,
0 value source-id
create srcstk0 30 allot
srcstk0 value srcstk
: resetstack depth 0 <
if
begin depth while 0 repeat
else
begin depth while drop repeat
then
;
: getnumber 2dup >r >r swap dup c@ [char] - =
if
swap
dup 1 <
if
2drop 2drop r> r> 1
else
swap 1 + swap 1 -
>number dup
if
2drop 2drop r> r> 1
else
2drop drop negate 0 r> r> 2drop
then
then
else
swap
>number dup
if
2drop 2drop r> r> 1
else
2drop drop 0 r> r> 2drop
then
then
;
: compilenumber
dup ['] _lit compile, compile,
dup ffff 10 lshift and
if
10 rshift
['] _lit compile, compile,
['] _lit compile, 10 compile,
['] lshift compile,
['] or compile,
else
drop
then
;
: _interpret
begin
20 word dup c@
while
find dup
if
state @ =
if
compile,
else
execute
then
else
dup rot count getnumber
if
type ." ?" cr
else
state @
if
compilenumber
then
then
then
repeat
drop
;
: .savesrc ." _savesrc " srcstk0 . srcstk . cr ;
: .loadsrc ." _loadsrc " srcstk0 . srcstk . cr ;
: _savesrc ( .savesrc ) tib srcstk ! #tib @ srcstk 4 + ! >in @ srcstk 8 + ! source-id srcstk 0c + ! srcstk 10 + to srcstk ;
: _loadsrc srcstk 10 - to srcstk ( .loadsrc ) srcstk @ to tib srcstk 4 + @ #tib ! srcstk 8 + @ >in ! srcstk 0c + @ to source-id ;
: evaluate _savesrc 0 1 - to source-id #tib ! to tib 0 >in ! _interpret _loadsrc ;
( INTERPRETER )
: interpret
begin
_interpret
depth 0 <
if
." Stack Underflow" cr
resetstack
else
source-id 0 1 - =
if
_loadsrc
\ 0 to source-id
else
source-id 0=
if ." ok" cr then
refill
then
then
again
;
decimal
interpret

View File

@ -1,22 +0,0 @@
+--------------------------------------------------------------------
| TERMS OF USE: MIT License
+--------------------------------------------------------------------
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files
(the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of the Software,
and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+------------------------------------------------------------------

View File

@ -1 +0,0 @@
Object "pfth.spin" Interface: Program: 0 Longs Variable: 0 Longs

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,62 +0,0 @@
\ primes.4th
\
\ Example code for kForth
\ Copyright (c) 1998 Creative Consulting for Research and Education
\
\ Test for a prime number. Return the largest divisor (< n )
\ and a flag indicating whether the number is prime or not.
: ?prime ( n -- m flag | is n a prime number? )
\ if flag is false (0), m is the largest divisor of n
abs
dup 3 > \ is n > 3 ?
if
abs
dup 2 /mod
swap 0=
if \ is n divisible by 2 ?
nip false
else
1- \ check for divisibility starting
begin \ with n/2 - 1 and counting down
2dup mod
over 1 >
and
while
1-
repeat
nip
dup 1 <=
then
else
dup 1 > IF drop 1 true ELSE false THEN
then
;
: test_prime ( n -- | test for prime number and display result )
?prime
if
." is a prime number" drop
else
." is NOT prime. Its largest divisor is " .
then
cr
;
: list_primes ( n -- | list all the prime numbers from 2 to n )
abs
dup 0>
if
1+ 2 do
i ?prime
if
i . cr
then
drop
loop
else
drop
then
;

View File

@ -1,40 +0,0 @@
( PROP WORDS)
hex
( REGISTER ACCESS )
: cnt@ 1f1 cog@ ;
: ina@ 1f2 cog@ ;
: outa@ 1f4 cog@ ;
: outa! 1f4 cog! ;
: dira@ 1f6 cog@ ;
: dira! 1f6 cog! ;
: clkfreq@ 0 @ ;
( BIT SETTING AND CLEARING )
: dirasetbit dira@ or dira! ;
: diraclrbit invert dira@ and dira! ;
: outasetbit outa@ or outa! ;
: outaclrbit invert outa@ and outa! ;
( HUBOPS )
: cogid ( ... cogid ) 0 0cfc0001 cogx1 ;
: locknew ( ... locknum ) 0 0cfc0004 cogx1 ;
: lockret ( locknum ... ) 0cfc0005 cogx1 drop ;
: cogstop ( cognum ... ) 0c7c0003 cogx1 drop ;
: coginit ( codeptr dataptr cognum ... cognum )
>r 0e lshift or 2 lshift r> or 0ffc0002 cogx1 ;
: cognew ( codeptr dataptr ... cognum ) 8 coginit ;
: waitcnt ( count ... count ) f8fc0000 cogx1 ;
: reboot 80 0cfc0000 cogx1 ;
decimal
( ANS UTILITY )
: ms ( msec ... ) cnt@ swap clkfreq@ 1000 / * + waitcnt drop ;
( ANS TOOLS EXT )
: bye reboot ;
( ENABLE SERIAL OUTPUT )
1 30 lshift dup outa! dira!

View File

@ -1,42 +0,0 @@
0 value ii 0 value jj
0 value KeyAddr 0 value KeyLen
create SArray 256 allot \ state array of 256 bytes
: KeyArray KeyLen mod KeyAddr ;
: get_byte + c@ ;
: set_byte + c! ;
: as_byte 255 and ;
: reset_ij 0 TO ii 0 TO jj ;
: i_update 1 + as_byte TO ii ;
: j_update ii SArray get_byte + as_byte TO jj ;
: swap_s_ij
jj SArray get_byte
ii SArray get_byte jj SArray set_byte
ii SArray set_byte
;
: rc4_init ( KeyAddr KeyLen -- )
256 min TO KeyLen TO KeyAddr
256 0 DO i i SArray set_byte LOOP
reset_ij
BEGIN
ii KeyArray get_byte jj + j_update
swap_s_ij
ii 255 < WHILE
ii i_update
REPEAT
reset_ij
;
: rc4_byte
ii i_update jj j_update
swap_s_ij
ii SArray get_byte jj SArray get_byte + as_byte SArray get_byte xor
;
hex
create AKey 61 c, 8A c, 63 c, D2 c, FB c,
\ create AKey 97 c, 8A c, 99 c, D2 c, FB c,
: test cr 0 DO rc4_byte . LOOP cr ;
AKey 5 rc4_init
2C F9 4C EE DC 5 test \ output should be: F1 38 29 C9 DE

View File

@ -1,49 +0,0 @@
0 value ii 0 value jj
0 value KeyAddr 0 value KeyLen
create SArray 256 allot \ state array of 256 bytes
create Results 100 allot
: KeyArray KeyLen mod KeyAddr ;
: get_byte + c@ ;
: set_byte + c! ;
: as_byte 255 and ;
: reset_ij 0 TO ii 0 TO jj ;
: i_update 1 + as_byte TO ii ;
: j_update ii SArray get_byte + as_byte TO jj ;
: swap_s_ij
jj SArray get_byte
ii SArray get_byte jj SArray set_byte
ii SArray set_byte
;
: rc4_init ( KeyAddr KeyLen -- )
256 min TO KeyLen TO KeyAddr
256 0 DO i i SArray set_byte LOOP
reset_ij
BEGIN
ii KeyArray get_byte jj + j_update
swap_s_ij
ii 255 < WHILE
ii i_update
REPEAT
reset_ij
;
: rc4_byte
ii i_update jj j_update
swap_s_ij
ii SArray get_byte jj SArray get_byte + as_byte SArray get_byte xor
;
\ : cnt@ 0 ;
hex
create AKey 61 c, 8a c, 63 c, d2 c, fb c,
\ create AKey 97 c, 8a c, 99 c, d2 c, fb c,
: test 0 DO rc4_byte Results i + c! LOOP ;
: test1 cr 0 do Results i + c@ . loop cr ;
: time hex cnt@
AKey 5 rc4_init
2c f9 4c ee dc 5 test \ output should be: f1 38 29 c9 de
cnt@ 5 test1 swap - 13880 / decimal . ." msec" cr ;
decimal

View File

@ -1,244 +0,0 @@
pfth Version 1.03
November 8, 2013
Dave Hein
(with additions from G. Herzog)
INTRODUCTION
------------
pfth is an ANS Forth interpreter that runs on the Propeller. It is written in
PASM and Forth, and it can be built using the Prop Tool or BST. pfth
implements all 133 of the ANS Forth core words, and 38 of the 45 core ext
words. pfth will run on any Propeller board that supports the standard serial
interface. The default settings of the serial port are 115200 baud, 8 bits, no
parity and 1 stop bit.
After loading and communications is established, use 'words' to verify that the
display is correct. The CR word is defined to emit both a carriage return and
a line feed. If your terminal displays an extra line you can either disable
the linefeed character on your terminal, or re-define CR to only emit a
carriage return.
VERSIONS OF SPIN FILES
----------------------
There are four versions of pfth.
The first version can be used to build stand-alone Forth applications. It is
in pfth.spin. In this version, Forth programs are included using the Spin FILE
directive.
A second version interfaces to an SD card and can execute Forth programs on
the SD card. This version is in sdpfth.spin. The program is set up for the C3
card, but it can be modified to support other cards.
The third version is named ospfth.spin, and runs under the Spinix operating
system. When Spinix starts up pfth it provides information about the SD pins,
the current working directory and a parameter list. The OS version of pfth
uses this information to initialize the SD card driver and change to the
working directory. It includes the file given by the parameter list.
The final version is called chess.spin, and implements a chess program. After
the program is loaded type "chess" to start playing. A move is entered by
typing the source and destination postions separated by a "-". As an example,
the move "D2-D4" will move the white queen's pawn two spaces ahead.
LEXICON
-------
pfth has over 50 kernel words, with most of them from the ANS core word set.
The source code for pfth is contained in pfth.spin, init.fth and other Forth
programs included at the end of pfth.spin.
Two of the non-standard words implemented by pfth are cog@ and cog!. These are
are used to read and write cog memory locations. Their main purpose is to
access the Prop registers, such as CNT, INA and OUTA.
Another non-standard word is cogx1, which is used to execute native Prop
instructions. The TOS contains the Prop instruction, and the next value on the
stack is used for the destination register value. The result of the execution
of the instruction is returned on the stack.
Some other non-standard words are _lit, _gethex, _jz and .x.
_lit is used to encode literal values.
_gethex is used during the boot phase to convert numeric strings to hex values.
_jz implements a jump-on-zero primitive.
.x is used for debug purposes, and it prints values as 8-digit hex numbers.
Some of the kernel words are shown below.
Interpreter Words Math and Logical Words Memory Access
----------------- ---------------------- -------------
evaluate + !
execute - @
find * c!
word / c@
refill mod
create and Console I/O
: or -----------
; xor emit
< key
= accept
Program Termination >
------------------- lshift Primitive Words
abort rshift ---------------
exit _lit
quit Variables _gethex
--------- _jz
Stack Operations #tib .x
---------------- tib
drop >in Propeller Words
pick base ---------------
roll dp cog!
>r last cog@
r> state cogx1
depth
swap
dup
pfth also contains a small number of pre-compiled Forth words written
in Forth. These words are here, allot, ",", _jmp and count. The definition
of these words is as follows.
: here dp @ ;
: allot dp @ + dp ! ;
: , here ! 4 allot ;
: _jmp r> @ >r ;
: count 0 pick 1 + 1 roll c@ ;
AT START UP
-----------
When pfth starts up, it runs a small boot interpreter that compiles
the ANS dictionary contained in init.fth. This file is included in the
PASM binary image using the PASM FILE directive. Other Forth source files
may be included after init.fth to add additional words and to implement a
specific application.
The boot interpreter can only handle 16-bit hex numbers, so pfth is in the hex
mode when first starting up. The boot interpreter has no error handling
capability, and is only used to build the initial dictionary. The boot
interpreter uses a limited vocabulary consisting of the following 20
kernel words.
dp state _lit _gethex : ; c@ @ ! + = pick roll drop
r> >r word find execute refill
The boot interpreter is shown below in a pseudo-Forth language. The
labels (label1), (label2), etc. are actually encoded as PASM labels, but
they are shown symbolically in the code below.
: xboot
(label1)
20 word 0 pick c@ _jz (label2) ( Get word, refill if empty )
find 0 pick _jz (label3) ( Find word, get number if not found )
state @ = _jz (label4) ( Go execute if not compile mode or immediate )
, _jmp (label1) ( Otherwise, compile and loop again )
(label4)
execute _jmp (label1) ( Execute and loop again )
(label3)
drop count _gethex ( Get number )
state @ _jz (label1) ( Loop again if not compile mode )
_lit _lit , , _jmp (label1) ( Otherwise, compile number and loop again )
(label2)
drop refill _jmp (label1) ( Refill and loop again )
;
The boot interpreter compiles init.fth, which then runs the main interpreter.
The main interpreter performs some error handling by checking for undefined
words and stack underflows. It also handles negative numbers and numbers in
any base.
SOURCE PROGRAMS
---------------
There are a number of additional Forth source programs included in this
distribution that can be run by pfth. Open and read these as text files to
learn more details.
comus.fth - provides a several useful non-standard words that are commonly
used.
starting.fth - contains samples of code from the "Starting Forth" tutorial.
rc4time.fth - implements the RC4 code included in the Wikipedia Forth entry.
It also displays the time required to run the RC4 code.
i2c.fth - is a Forth implementation of Mike Green's basic_i2c_driver from
the OBEX.
fds.fth - implementes some of the functions from the FullDuplexSerial
driver. It uses the binary PASM code from FullDuplexSerial.
toggle.fth - will start up a cog running the Forth interpreter. It toggles
P15, but it can easily be modified to toggle another pin.
ted.fth - a simple line-oriented text editor based on the ED text editor.
linux.fth - implements some basic linux commands, such as ls, cat, rm and cp.
STARTING FORTH COGS
-------------------
Forth cogs are started with cognew or coginit by specifying the Forth cog image
as the execution pointer and a 5-long structure as the data pointer. The
5-long structure is defined as follow
First long: Address of the body of a word that will be executed on startup
Second long: Initial value of the stack pointer
Third long: Address of the beginning of the stack
Fourth long: Initial value of the return stack pointer
Fifth long: Address of the beginning the the return stack
CELL SIZE
---------
The cell size for pfth is 32 bits. The words !, @ and "," words access 32-bit
values that are 32-bit aligned. Additional words are provide for smaller unit
access, such as w! and w@ for word access, and c! and c@ for byte access.
The compiled list cell size is 16 bits. The compile, word must be used when
compiling execution tokens into a list rather than just using the "," word.
DICTIONARY ENTRY FORMAT
-----------------------
The format for the pfth dictionary entry is shown below. The beginning of a
word entry and its body are long-aligned. The link pointer contains the
address of the previous word in the dictionary.
The flags byte contains various flag bits that indicate if the word is an
immediate word, a literal number or string, or a jump word. The name length
byte and the name string specify the name of the word. It is followed by
padding bytes that ensure long alignment.
The code pointer contains the cog address of the PASM code that is to be
executed. The execution token for a word points to this field. The does>
pointer contains the hub address of a list of execution tokens that is to be
called.
The body is a variable length field that contains the contents of a variable or
the list of execution tokens for a compiled word. The list for a compiled word
consists of one execution token per word, and is terminated by a zero-valued
word.
Offset Content Size
------ ------- ----
0 Link Pointer word
2 Flags byte
3 Name Length byte
4 Name String Len bytes
4+Len Padding (-Len) & 3 bytes
4+(Len+3)&(-4) Code Pointer word
6+(Len+3)&(-4) DOES> Pointer word
8+(Len+3)&(-4) Body Variable

View File

@ -1,65 +0,0 @@
: cond.name ( link )
dup link>flags c@ dup 2 and ( link flag literal )
if
8 and
if
.name
then
else
4 and
if
[char] s emit [char] " emit bl emit
else
.name
then
then
;
: seefunc ( xt )
>body ( listptr )
begin
dup w@ ( listptr xt )
while
dup w@ ( listptr xt )
>link .name link>flags c@ dup 2 and ( listptr flags literal )
if
8 and ( listptr flags jump )
if
2 + dup dup w@ swap - 2 - 2 / .
else
2 + dup w@ .
then
else
4 and ( listptr string )
if
2 + dup count type [char] " emit space
dup c@ + 0 2 - and
then
then
compsize + ( listptr+=compsize)
repeat
drop
;
: see
' dup ( xt xt )
if
dup >flags c@ dup 16 and ( xt flags kernel )
if
drop
drop
." Kernel Word"
else
32 and
if
drop
." Variable"
else
seefunc
then
then
else
drop
." ?"
then
;

View File

@ -1,20 +0,0 @@
: waitcnt begin dup cnt@ - 0< until ;
: putch 256 or dup + clkfreq@ 9600 /
11 >r
cnt@
begin
r> 1- dup >r
while
rot dup
30 lshift
outa!
1 rshift
swap rot dup rot +
waitcnt
repeat
r> 2drop 2drop
;
: test cnt@ 65 putch cnt@ swap - 80 / . ;

View File

@ -1,65 +0,0 @@
: STAR 42 EMIT ;
: MARGIN CR 30 SPACES ;
: BLIP MARGIN STAR ;
: STARS 0 DO STAR LOOP ;
: BAR MARGIN 5 STARS ;
: F BAR BLIP BAR BLIP BLIP CR ;
: MULT CR 11 1 DO DUP I * . LOOP DROP ;
: TABLE CR 11 1 DO I MULT LOOP ;
: TABLE1 CR 11 1 DO 11 1 DO I J * . LOOP CR LOOP ;
: DUB 32767 1 DO I . I +LOOP ;
: GREET ." Hello, I speak Forth " ;
: GIFT ." chocolate" ;
: GIVER ." Mum" ;
: THANKS CR ." Dear " GIVER ." ,"
CR ." Thanks for the " GIFT ." . " ;
: EGGSIZE DUP 18 < IF ." reject " ELSE
DUP 21 < IF ." small " ELSE
DUP 24 < IF ." medium " ELSE
DUP 27 < IF ." large " ELSE
DUP 30 < IF ." extra large " ELSE
." error "
THEN THEN THEN THEN THEN DROP ;
: FALSE 0 ;
: TRUE -1 ;
: TEST IF ." non-" THEN ." zero " ;
: /CHECK ?DUP IF / THEN ;
: UNCOUNT DROP 1 - ;
: max-int -1 1 rshift ;
: min-int max-int negate 1 - ;
: max-uint -1 ;
: OUTPUT-TEST
." YOU SHOULD SEE THE STANDARD GRAPHIC CHARACTERS:" CR
41 BL DO I EMIT LOOP CR
61 41 DO I EMIT LOOP CR
127 61 DO I EMIT LOOP CR
." YOU SHOULD SEE 0-9 SEPARATED BY A SPACE:" CR
9 1+ 0 DO I . LOOP CR
." YOU SHOULD SEE 0-9 (WITH NO SPACES):" CR
57 1+ 48 DO I 0 SPACES EMIT LOOP CR
." YOU SHOULD SEE A-G SEPARATED BY A SPACE:" CR
71 1+ 65 DO I EMIT SPACE LOOP CR
." YOU SHOULD SEE 0-5 SEPARATED BY TWO SPACES:" CR
5 1+ 0 DO I 48 + EMIT 2 SPACES LOOP CR
." YOU SHOULD SEE TWO SEPARATE LINES:" CR
." LINE 1" CR ." LINE 2" CR
." YOU SHOULD SEE THE NUMBER RANGES OF SIGNED AND UNSIGNED NUMBERS:" CR
." SIGNED: " MIN-INT . MAX-INT . CR
." UNSIGNED: " 0 . MAX-UINT U. CR
;
output-test
f
10 mult
table
table1
dub
greet
thanks cr
17 eggsize cr
22 eggsize cr
25 eggsize cr
28 eggsize cr
32 eggsize cr
0 test cr
1 test cr

View File

@ -1,2 +0,0 @@
: TIME CNT@ 100000 BEGIN 1 - DUP 0 = UNTIL DROP CNT@ SWAP - 8000 / . ;

View File

@ -1,33 +0,0 @@
\ ############################################################################
\ # toggle.fth - This program starts up a Forth cog that toggles P15
\ #
\ # Copyright (c) 2012 Dave Hein
\ # MIT Licensed
\ ############################################################################
create cogstack 80 allot \ Allocate data stack space
create cogreturn 80 allot \ Allocate return stack space
create delaycnt 80000000 , \ This variable controls the blink rate
hex
\ This word toggles bit P15 every "delaycnt" cycles
: toggle
8000 dirasetbit cnt@ \ Set P15 for output and get CNT
begin
delaycnt @ + waitcnt \ Wait "delaycnt" cycles
8000 outasetbit \ Set P15
delaycnt @ + waitcnt \ Wait "delaycnt" cycles
8000 outaclrbit \ Clear P15
again ; \ Repeat forever
decimal
create cogconfig \ Forth cog config structure
' toggle >body , \ Get execution token for TOGGLE
cogstack , \ Initial value of stack ptr
cogstack , \ Empty value for stack ptr
cogreturn , \ Initial value of return ptr
cogreturn , \ Empty value for return ptr
\ This word starts a cog running the TOGGLE word
: starttoggle forth @ cogconfig cognew ;

View File

@ -7,14 +7,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef LINUX
#include "conion.h"
#else
#include <conio.h>
#endif
#include <ctype.h>
#include "interp.h"
#include "opcodes.h"
#include "spinsim.h"
#define OP_NONE 0
#define OP_UNSIGNED_OBJ_OFFSET 1
@ -106,7 +103,7 @@ void ProcessRet(void)
{
if (!symflag) return;
methodlev--;
fprintf(tracefile, "return %s\n\n", objname[methodlev]);
fprintf(tracefile, "return %s%s%s", objname[methodlev], NEW_LINE, NEW_LINE);
}
static char linebuf[200];
@ -135,7 +132,7 @@ void ProcessCall(int32_t subnum, int32_t mode)
methnum++;
if (methnum == subnum)
{
fprintf(tracefile, "call %s:%s\n", objname[methodlev], linebuf);
fprintf(tracefile, "call %s:%s%s", objname[methodlev], linebuf, NEW_LINE);
fclose(infile);
return;
}
@ -152,7 +149,7 @@ void ProcessCall(int32_t subnum, int32_t mode)
methnum++;
if (methnum == subnum)
{
fprintf(tracefile, "call %s:%s\n", objname[methodlev], linebuf);
fprintf(tracefile, "call %s:%s%s", objname[methodlev], linebuf, NEW_LINE);
fclose(infile);
return;
}
@ -270,7 +267,7 @@ void PrintOp(SpinVarsT *spinvars)
int32_t opcode;
int32_t opform = 0;
char *opstr;
int exop1, exop2;
//int exop1, exop2;
int32_t val;
int32_t operand;
char *regop[] = {"ldreg", "streg", "exreg", "??reg"};
@ -281,8 +278,8 @@ void PrintOp(SpinVarsT *spinvars)
if (spinvars->state != 1) return;
opcode = BYTE(pcurr);
exop1 = GetOpIndex(opcode);
exop2 = -1;
//exop1 = GetOpIndex(opcode);
//exop2 = -1;
opstr = FindOpcode(pcurr, &opform, 0);
memset(bytestr, ' ', 40);
@ -418,7 +415,7 @@ void PrintOp(SpinVarsT *spinvars)
{
char *loadstr = "";
opcode = BYTE(pcurr);
exop2 = GetExOpIndex(opcode);
//exop2 = GetExOpIndex(opcode);
if (opcode & 0x80)
{
loadstr = "load";
@ -453,7 +450,7 @@ void PrintOp(SpinVarsT *spinvars)
pcurr++;
}
bytestr[strlen(bytestr)] = ' ';
fprintf(tracefile, "%s %s\n", bytestr, symstr);
fprintf(tracefile, "%s %s%s", bytestr, symstr, NEW_LINE);
//fprintf(tracefile, "%s [%2d,%2d] %s\n", bytestr, exop1, exop2, symstr);
}
@ -561,14 +558,14 @@ void PrintStats(void)
}
exname = optable[k].opname;
}
fprintf(tracefile, "%10d, %2.2x:%2.2x, %s:%s\n",
exopcount[opindex][j], i, exop, opname, exname);
fprintf(tracefile, "%10d, %2.2x:%2.2x, %s:%s%s",
exopcount[opindex][j], i, exop, opname, exname, NEW_LINE);
}
}
else
{
fprintf(tracefile, "%10d, %2.2x, %s\n", opcount[i], i, opname);
fprintf(tracefile, "%10d, %2.2x, %s%s", opcount[i], i, opname, NEW_LINE);
}
}
}

View File

@ -7,14 +7,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef LINUX
#include "conion.h"
#else
#include <conio.h>
#endif
#include <ctype.h>
#include <sys/timeb.h>
#include "interp.h"
#include "spinsim.h"
extern int32_t printflag;
extern PasmVarsT PasmVars[8];
@ -22,11 +19,11 @@ extern char *hubram;
extern int32_t memsize;
extern int32_t loopcount;
extern int32_t cycleaccurate;
extern int32_t proptwo;
extern int32_t pin_val;
extern int32_t propmode;
extern int32_t pin_val_a;
extern char lockstate[8];
extern char lockalloc[8];
extern char lockstate[16];
extern char lockalloc[16];
extern FILE *tracefile;
@ -48,8 +45,12 @@ int32_t MAP_ADDR(int32_t addr)
}
else if (((uint32_t)addr) >= memsize)
{
fprintf(tracefile, "MAP_ADDR: address out of bounds %8.8x\n", addr);
#if 0
fprintf(tracefile, "MAP_ADDR(%d): address out of bounds %8.8x\n", loopcount, addr);
addr = memsize + 12;
#else
addr &= memsize - 1;
#endif
}
//fprintf(tracefile, "MAP_ADDR: %8.8x %8.8x\n", addr, ((uint32_t *)hubram)[addr>>2]);
@ -62,7 +63,7 @@ int32_t GetCnt()
if (cycleaccurate)
{
if (proptwo)
if (propmode >= 2)
cycles = loopcount;
else
cycles = loopcount * 4;
@ -98,7 +99,7 @@ void UpdatePins(void)
mask |= mask1;
}
}
pin_val = (~mask) | val;
pin_val_a = (~mask) | val;
}
int32_t GetSignedOffset(int32_t *ppcurr)
@ -398,7 +399,7 @@ void ExecuteLowerOp(SpinVarsT *spinvars)
pcurr = 0xfffc;
}
else
fprintf(tracefile, "%4.4x %2.2x - NOT IMPLEMENTED\n", pcurr - 1, opcode);
fprintf(tracefile, "%4.4x %2.2x - NOT IMPLEMENTED%s", pcurr - 1, opcode, NEW_LINE);
}
else if (opcode >= 0x16 && opcode <= 0x23)
{
@ -729,7 +730,7 @@ void ExecuteLowerOp(SpinVarsT *spinvars)
}
else
{
fprintf(tracefile, "NOT PROCESSED\n");
fprintf(tracefile, "NOT PROCESSED%s", NEW_LINE);
}
spinvars->pcurr = pcurr;
spinvars->dcurr = dcurr;
@ -787,7 +788,7 @@ void ExecuteRegisterOp(SpinVarsT *spinvars, int32_t operand, int32_t msb, int32_
if (operand == 0x11) // cnt = $1f1
parm1 = GetCnt();
else if (operand == 0x12) // ina = $1f2
parm1 = pin_val;
parm1 = pin_val_a;
else
parm1 = reg[operand];
parm1 = (parm1 >> lsb) & mask;
@ -804,7 +805,7 @@ void ExecuteRegisterOp(SpinVarsT *spinvars, int32_t operand, int32_t msb, int32_
if (operand == 0x11) // cnt = $1f1
parm1 = GetCnt();
else if (operand == 0x12) // ina = $1f2
parm1 = pin_val;
parm1 = pin_val_a;
else
parm1 = reg[operand];
}
@ -825,7 +826,7 @@ void ExecuteRegisterOp(SpinVarsT *spinvars, int32_t operand, int32_t msb, int32_
dcurr = spinvars->dcurr;
}
else
fprintf(tracefile, "Undefined register operation\n");
fprintf(tracefile, "Undefined register operation%s", NEW_LINE);
spinvars->pcurr = pcurr;
spinvars->dcurr = dcurr;
@ -1040,7 +1041,7 @@ int32_t ExecuteExtraOp(SpinVarsT *spinvars, int32_t opcode, int32_t parm1, int32
}
else
{
fprintf(tracefile, "NOT IMPLEMENTED\n");
fprintf(tracefile, "NOT IMPLEMENTED%s", NEW_LINE);
parm2 = 0;
}
@ -1264,7 +1265,7 @@ int32_t ExecuteMathOp(SpinVarsT *spinvars, int32_t opcode, int32_t parm1)
break;
default:
fprintf(tracefile, "NOT PROCESSED\n");
fprintf(tracefile, "NOT PROCESSED%s", NEW_LINE);
}
// Push the result back to the stack

314
spinsim.c
View File

@ -1,34 +1,23 @@
/*******************************************************************************
' Author: Dave Hein
' Version 0.75
' Copyright (c) 2010 - 2014
' Version 0.97
' Copyright (c) 2010 - 2017
' See end of file for terms of use.
'******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#ifdef LINUX
#include <dirent.h>
#include <sys/stat.h>
#include "spinsim.h"
#include "conion.h"
#else
#include <conio.h>
#include <direct.h>
#endif
#include "interp.h"
#include "rom.h"
#include "spindebug.h"
#include "eeprom.h"
// Define system I/O addresses and commands
//#define SYS_COMMAND 0x12340000
//#define SYS_LOCKNUM 0x12340002
//#define SYS_PARM 0x12340004
//#define SYS_DEBUG 0x12340008
#define SYS_CON_PUTCH 1
#define SYS_CON_GETCH 2
#define SYS_FILE_OPEN 3
@ -57,8 +46,8 @@ char *extram[4];
int32_t extmemsize[4];
uint32_t extmembase[4];
int32_t extmemnum = 0;
char lockstate[8];
char lockalloc[8];
char lockstate[16];
char lockalloc[16];
char objname[100][20];
int32_t methodnum[100];
@ -71,19 +60,26 @@ int32_t profile = 0;
int32_t memsize = 64;
int32_t cycleaccurate = 0;
int32_t loopcount = 0;
int32_t proptwo = 0;
int32_t propmode = 0;
int32_t baudrate = 0;
int32_t pin_val = -1;
int32_t pin_val_a = -1;
int32_t pin_val_b = -1;
int32_t gdbmode = 0;
int32_t eeprom = 0;
int32_t debugmode = 0;
int32_t printbreak = 0;
SerialT serial_in;
SerialT serial_out;
int32_t fjmpflag = 0;
int32_t nohubslots = 0;
int32_t pstmode = 0;
int32_t kludge = 0;
FILE *logfile = NULL;
FILE *tracefile = NULL;
FILE *cmdfile = NULL;
PasmVarsT PasmVars[8];
PasmVarsT PasmVars[16];
void PrintOp(SpinVarsT *spinvars);
void ExecuteOp(SpinVarsT *spinvars);
@ -91,17 +87,19 @@ char *FindChar(char *str, int32_t val);
void Debug(void);
int32_t RunProp(int32_t maxloops);
void gdb(void);
void UpdateRWlongFlags(void);
void spinsim_exit(int32_t exitcode)
{
// dbetz: not defined for Windows and a nop for anything else
// restore_console_io();
#ifndef __MINGW32__
restore_console_io();
#endif
exit(exitcode);
}
void usage(void)
{
fprintf(stderr, "Spinsim Version 0.75\n");
fprintf(stderr, "Spinsim Version 0.97\n");
fprintf(stderr, "usage: spinsim [options] file\n");
fprintf(stderr, "The options are as follows:\n");
fprintf(stderr, " -v# Set verbosity level\n");
@ -112,7 +110,7 @@ void usage(void)
fprintf(stderr, " -P Profile Spin opcode usage\n");
fprintf(stderr, " -m# Set the hub memory size to # K-bytes\n");
//fprintf(stderr, " -c Enable cycle-accurate mode for pasm cogs\n");
fprintf(stderr, " -t Enable the Prop 2 mode\n");
fprintf(stderr, " -t# Enable the Prop 2 mode. # specifies options\n");
fprintf(stderr, " -b# Enable the serial port and set the baudrate to # (default 115200)\n");
fprintf(stderr, " -gdb Operate as a GDB target over stdin/stdout\n");
fprintf(stderr, " -L <filename> Log GDB remote comm to <filename>\n");
@ -120,6 +118,7 @@ void usage(void)
//fprintf(stderr, " -x# Set the external memory size to # K-bytes\n");
fprintf(stderr, " -e Use eeprom.dat\n");
fprintf(stderr, " -d Use debugger\n");
fprintf(stderr, " -pst Use PST mode\n");
spinsim_exit(1);
}
@ -129,6 +128,7 @@ void putchx(int32_t val)
fflush(stdout);
}
#if 0
int32_t getchx(void)
{
uint8_t val = 0;
@ -137,6 +137,7 @@ int32_t getchx(void)
if (val == 10) val = 13;
return val;
}
#endif
char *FindExtMem(uint32_t addr, int32_t num)
{
@ -269,7 +270,7 @@ void CheckCommand(void)
pdirent = readdir(pdir);
if (pdirent)
{
#ifdef LINUX
#if 1
FILE *infile;
int32_t d_size = 0;
int32_t d_attr = 0;
@ -321,7 +322,6 @@ void CheckCommand(void)
{
char *path = (char *)&BYTE(parm);
char fullpath[200];
char *ptr;
if (path[0] == '/')
{
strcpy(fullpath, rootdir);
@ -330,8 +330,8 @@ void CheckCommand(void)
else
strcpy(fullpath, path);
ptr = fullpath;
#ifndef LINUX
#if 0
char *ptr = fullpath;
while (*ptr)
{
if (*ptr == '/') *ptr = 0x5c;
@ -343,20 +343,15 @@ void CheckCommand(void)
}
else if (command == SYS_FILE_GETCWD)
{
char *ptr;
char *str = (char *)&BYTE(LONG(parm));
int32_t num = LONG(parm+4);
ptr = getcwd(str, num);
getcwd(str, num);
LONG(SYS_PARM) = LONG(parm);
}
else if (command == SYS_FILE_MKDIR)
{
//char *fname = (char *)&BYTE(parm);
#ifdef LINUX
#if 0
LONG(SYS_PARM) = mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO);
#endif
#else
char *fname = (char *)&BYTE(parm);
LONG(SYS_PARM) = mkdir(fname);
#endif
}
@ -372,7 +367,7 @@ void CheckCommand(void)
if (!pdirent) break;
if (strcmp(pdirent->d_name, fname) == 0)
{
#ifdef LINUX
#if 1
#if 0
int32_t d_type = pdirent->d_type;
attrib = 0;
@ -461,141 +456,130 @@ void CheckCommand(void)
WORD(SYS_COMMAND) = 0;
}
int CheckSerialIn(void)
void SerialInit(SerialT *serial, int pin_num, int bitcycles, int mode)
{
static int state = 0;
static int count = 0;
static int val;
serial->flag = 0;
serial->state = 0;
serial->count = 0;
serial->mode = mode;
serial->pin_num = pin_num;
serial->bitcycles = bitcycles;
}
if (state == 0)
int SerialSend(SerialT *serial, int portval)
{
int bitval;
int flipbit = serial->mode & 1;
int pin_num = serial->pin_num;
if (serial->state == 0)
{
if (kbhit1())
if (serial->flag)
{
val = getch();
if (val == 0x1d) return 1;
val |= 0x300;
if (proptwo)
count = 80000000 / baudrate;
else
{
count = LONG(0) / baudrate;
count >>= 2;
}
//if (!proptwo) count >>= 2;
pin_val &= 0x7fffffff;
state = 1;
serial->value |= 0x300;
serial->count = serial->bitcycles;
portval = (portval & ~(1 << pin_num)) | (flipbit << pin_num);
serial->state = 1;
//printf("portval = %8.8x\n", portval);
}
}
else if (--count <= 0)
else if (--serial->count <= 0)
{
if (++state > 11)
if (++serial->state > 11)
{
state = 0;
serial->flag = 0;
serial->state = 0;
}
else
{
pin_val = (pin_val & 0x7fffffff) | ((val & 1) << 31);
val >>= 1;
#if 0
count = LONG(0) / baudrate;
if (!proptwo) count >>= 2;
#endif
if (proptwo)
count = 80000000 / baudrate;
else
{
count = LONG(0) / baudrate;
count >>= 2;
}
bitval = (serial->value & 1) ^ flipbit;
portval = (portval & ~(1 << pin_num)) | (bitval << pin_num);
serial->value >>= 1;
serial->count = serial->bitcycles;
//printf("portval = %8.8x\n", portval);
}
}
return portval;
}
int CheckSerialIn(SerialT *serial)
{
int value;
if (propmode == 2)
pin_val_b = SerialSend(serial, pin_val_b);
else
pin_val_a = SerialSend(serial, pin_val_a);
if (!serial->flag && kbhit1())
{
value = getch();
//printf("CheckSerialIn: value = %x\n", value);
if (value == 0x1d) return 1;
serial->flag = 1;
serial->value = value;
}
return 0;
}
void CheckSerialOut(void)
void SerialReceive(SerialT *serial, int portval)
{
int txbit = 0;
static int val;
static int state = -2;
static int count;
//static int txbit0 = 0;
int bitval = ((portval >> serial->pin_num) & 1) ^ (serial->mode & 1);
txbit = (pin_val >> 30) & 1;
//if (txbit != txbit0) fprintf(stderr, "txbit = %d, loopcount = %d\n", txbit, loopcount);
//txbit0 = txbit;
if (state == -2)
if (serial->state == 0)
{
if (txbit)
{
state = -1;
//fprintf(stderr, "Start Serial\n");
}
if (bitval)
serial->state = 1;
}
else if (state == -1)
else if (serial->state == 1)
{
if (!txbit)
if (!bitval)
{
val = 0;
state = 0;
#if 0
count = LONG(0) / baudrate;
if (!proptwo) count >>= 2;
#endif
if (proptwo)
count = 80000000 / baudrate;
else
{
count = LONG(0) / baudrate;
count >>= 2;
}
count += count >> 1;
serial->value = 0;
serial->state = 2;
serial->count = serial->bitcycles;
serial->count += serial->count >> 1;
}
}
else
{
if (--count <= 0)
if (--serial->count <= 0)
{
if (state > 7)
if (serial->state > 9)
{
state = -1;
#if 1
if (val == 13)
putchx(10);
else
putchx(val);
#else
printf("<%2.2x>\n", val);
#endif
serial->flag = 1;
serial->state = 1;
}
else
{
//fprintf(stderr, "%d", txbit);
val |= txbit << state;
#if 0
count = LONG(0) / baudrate;
if (!proptwo) count >>= 2;
#endif
if (proptwo)
count = 80000000 / baudrate;
else
{
count = LONG(0) / baudrate;
count >>= 2;
}
state++;
serial->value |= bitval << (serial->state - 2);
serial->count = serial->bitcycles;
serial->state++;
}
}
}
}
void CheckSerialOut(SerialT *serial)
{
if (propmode == 2)
SerialReceive(serial, pin_val_b);
else
SerialReceive(serial, pin_val_a);
if (serial->flag)
{
serial->flag = 0;
if (serial->value == 13 && pstmode)
putchx(10);
else
putchx(serial->value);
}
}
void PrintStack(SpinVarsT *spinvars)
{
int32_t dcurr = spinvars->dcurr;
printf("PrintStack: %4.4x %8.8x %8.8x %8.8x\n",
dcurr, LONG(dcurr-4), LONG(dcurr-8), LONG(dcurr-12));
printf("PrintStack: %4.4x %8.8x %8.8x %8.8x%s",
dcurr, LONG(dcurr-4), LONG(dcurr-8), LONG(dcurr-12), NEW_LINE);
}
char *bootfile;
@ -606,10 +590,11 @@ void RebootProp(void)
int32_t dbase;
char *ptr;
FILE *infile;
int32_t bitcycles;
if (!proptwo) memset(hubram, 0, 32768);
memset(lockstate, 0, 8);
memset(lockalloc, 0, 8);
if (!propmode) memset(hubram, 0, 32768);
memset(lockstate, 0, 16);
memset(lockalloc, 0, 16);
chdir(rootdir);
@ -625,12 +610,12 @@ void RebootProp(void)
spinsim_exit(1);
}
i = fread(hubram, 1, 32768, infile);
i = fread(hubram, 1, memsize, infile);
fclose(infile);
}
// Copy in the ROM contents
if (!proptwo)
if (!propmode)
{
memcpy(hubram + 32768, romdata, 32768);
dbase = WORD(10);
@ -643,12 +628,15 @@ void RebootProp(void)
WORD(SYS_LOCKNUM) = 1;
lockalloc[0] = 1;
for (i = 0; i < 8; i++) PasmVars[i].state = 0;
for (i = 0; i < 16; i++) PasmVars[i].state = 0;
if (pasmspin)
{
if (proptwo)
StartPasmCog2(&PasmVars[0], 0, 0x0e00, 0);
if (propmode == 2)
{
//StartPasmCog2(&PasmVars[0], 0, 0x0e00, 0);
StartPasmCog2(&PasmVars[0], 0, 0x0000, 0, 0);
}
else
StartPasmCog(&PasmVars[0], 0x0004, 0xf004, 0);
}
@ -677,6 +665,16 @@ void RebootProp(void)
methodlev = 1;
}
if (baudrate)
{
if (propmode)
bitcycles = 60000000 / baudrate;
else
bitcycles = (LONG(0) / baudrate) >> 2;
SerialInit(&serial_in, 31, bitcycles, 2);
SerialInit(&serial_out, 30, bitcycles, 2);
}
//LONG(SYS_DEBUG) = printflag;
}
@ -687,7 +685,8 @@ int step_chip(void)
int runflag = 0;
int breakflag = 0;
SpinVarsT *spinvars;
for (i = 0; i < 8; i++)
if (propmode == 2) UpdateRWlongFlags();
for (i = 0; i < 16; i++)
{
state = PasmVars[i].state;
PasmVars[i].printflag = (LONG(SYS_DEBUG) >> (i*4)) & 15;
@ -695,22 +694,22 @@ int step_chip(void)
{
if (PasmVars[i].printflag && state == 5)
{
if (!proptwo)
if (!propmode)
{
fprintf(tracefile, "Cog %d: ", i);
DebugPasmInstruction(&PasmVars[i]);
}
}
if (proptwo)
if (propmode == 2)
{
breakflag = ExecutePasmInstruction2(&PasmVars[i]);
if (PasmVars[i].printflag && state == 5)
fprintf(tracefile, "\n");
fprintf(tracefile, NEW_LINE);
}
else
{
ExecutePasmInstruction(&PasmVars[i]);
if (PasmVars[i].printflag && state == 5) printf("\n");
if (PasmVars[i].printflag && state == 5) fprintf(tracefile, NEW_LINE);
}
if (!breakflag &&
!(printbreak && PasmVars[i].printflag && state == 5))
@ -736,13 +735,12 @@ int step_chip(void)
int main(int argc, char **argv)
{
char *ptr;
char *fname = 0;
int32_t i;
int32_t maxloops = -1;
tracefile = stdout;
ptr = getcwd(rootdir, 100);
getcwd(rootdir, 100);
for (i = 1; i < argc; i++)
{
@ -759,18 +757,25 @@ int main(int argc, char **argv)
fprintf(stderr, "Unable to open trace file %s.\n", argv[i]);
spinsim_exit(1);
}
} else if (strcmp(argv[i], "-t") == 0)
}
else if (strncmp(argv[i], "-t", 2) == 0)
{
proptwo = 1;
propmode = 2;
pasmspin = 1;
memsize = 256;
memsize = 512;
cycleaccurate = 1;
fjmpflag = argv[i][2] & 1;
nohubslots = (argv[i][2] & 2) >> 1;
}
else if (strcmp(argv[i], "-p") == 0)
{
pasmspin = 1;
cycleaccurate = 1;
}
else if (strcmp(argv[i], "-pst") == 0)
pstmode = 1;
else if (strcmp(argv[i], "-k") == 0)
kludge = 1;
else if (strcmp(argv[i], "-s") == 0)
symflag = 1;
else if (strcmp(argv[i], "-P") == 0)
@ -891,15 +896,18 @@ int main(int argc, char **argv)
if (!fname && !gdbmode && !eeprom) usage();
RebootProp();
// dbetz: not defined for Windows and a nop for anything else
// initialize_console_io();
#ifndef __MINGW32__
initialize_console_io();
#endif
if (gdbmode)
gdb();
else if (debugmode)
Debug();
else
RunProp(maxloops);
// restore_console_io();
#ifndef __MINGW32__
restore_console_io();
#endif
if (eeprom) EEPromClose();
if (profile) PrintStats();
return 0;

View File

@ -1,13 +1,21 @@
#include <stdint.h>
int step_chip(void);
int CheckSerialIn(void);
//int CheckSerialIn(SerialT *serial);
void CheckCommand(void);
void putchx(int32_t val);
void CheckSerialOut(void);
//void CheckSerialOut(SerialT *serial);
void spinsim_exit(int32_t exitcode);
#define WAIT_CNT 01
#define WAIT_MULT 02
#define WAIT_PIN 03
#define WAIT_HUB 16
#define WAIT_CACHE 17
#define WAIT_CNT 01
#define WAIT_CORDIC 02
#define WAIT_PIN 03
#define WAIT_HUB 16
#define WAIT_CACHE 17
#define WAIT_FLAG 18
#ifdef __MINGW32__
#define NEW_LINE "\n"
#else
#define NEW_LINE "\r\n"
#endif

18504
verify/testhdw.txt Executable file

File diff suppressed because it is too large Load Diff

16448
verify/testhdw1.txt Executable file

File diff suppressed because it is too large Load Diff

1216
verify/testhdwa.txt Executable file

File diff suppressed because it is too large Load Diff

2448
verify/testhdwd.txt Executable file

File diff suppressed because it is too large Load Diff

3221
verify/testhdwq.txt Executable file

File diff suppressed because it is too large Load Diff

BIN
verify/testops.bin Executable file

Binary file not shown.

130
verify/testops.c Executable file
View File

@ -0,0 +1,130 @@
/*
* Testbench for the alu
* (c) Pacito.Sys
*/
#include <stdio.h>
#include <string.h>
#define PRINT_INPUT_VALUES
#define NUM_VALUES 8
#define MAX_POS 0x7fffffff
#define MAX_NEG 0x80000000
#define MAX_NEG1 0x80000001
#define WZ_BIT 0x00080000
#define WC_BIT 0x00100000
void testit(int *);
char *opcodeName[] = {
"ror", "rol", "shr", "shl", "rcr", "rcl", "sar", "sal",
"add", "addx", "adds", "addsx", "sub", "subx", "subs", "subsx",
"cmp", "cmpx", "cmps", "cmpsx", "cmpr", "cmpm", "subr", "cmpsub",
"fge", "fle", "fges", "fles", "sumc", "sumnc", "sumz", "sumnz",
"bitl", "bith", "bitc", "bitnc", "bitz", "bitnz", "bitnot",
"andn", "and", "or", "xor", "muxc", "muxnc", "muxz", "muxnz",
"mov", "not", "abs", "neg", "negc", "negnc", "negz", "negnz",
"incmod", "decmod", "encod", "testn", "test", "anyb", "setnib", "getnib",
"rolnib", "setbyte", "getbyte", "rolbyte", "getword", "sets", "signx", "movbyts",
"muls"};
int instruct[] = {
0x00000000, 0x00200000, 0x00400000, 0x00600000, 0x00800000, 0x00a00000, 0x00c00000, 0x00e00000,
0x01000000, 0x01200000, 0x01400000, 0x01600000, 0x01800000, 0x01a00000, 0x01c00000, 0x01e00000,
0x02000000, 0x02200000, 0x02400000, 0x02600000, 0x02800000, 0x02a00000, 0x02c00000, 0x02e00000,
0x03000000, 0x03200000, 0x03400000, 0x03600000, 0x03800000, 0x03a00000, 0x03c00000, 0x03e00000,
0x04000000, 0x04200000, 0x04400000, 0x04600000, 0x04800000, 0x04a00000, 0x04e00000,
0x05000000, 0x05200000, 0x05400000, 0x05600000, 0x05800000, 0x05a00000, 0x05c00000, 0x05e00000,
0x06000000, 0x06200000, 0x06400000, 0x06600000, 0x06800000, 0x06a00000, 0x06c00000, 0x06e00000,
0x07000000, 0x07200000, 0x07400000, 0x07800000, 0x07a00000, 0x07c00000, 0x08000000, 0x08400000,
0x08800000, 0x08c00000, 0x08e00000, 0x09000000, 0x09300000, 0x09b80000, 0x09d80000, 0x09f80000,
0x0a100000};
int test_values[] = { 0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff };
int mailbox[4];
void alu(int opcode, int S, int D, int C, int Z, int *alu_q, int *alu_c, int *alu_z)
{
mailbox[0] = opcode;
mailbox[1] = D;
mailbox[2] = S;
mailbox[3] = (Z << 1) | C;
testit(mailbox);
*alu_q = mailbox[1];
*alu_c = mailbox[3] & 1;
*alu_z = (mailbox[3] >> 1) & 1;
}
void writeTest(int index)
{
int instr;
int testnum = 0;
int s1, d1, S, D, C, Z;
int alu_q, alu_c, alu_z;
char name[20];
strcpy(name, " ");
memcpy(name, opcodeName[index], strlen(opcodeName[index]));
printf("%s", name);
#ifdef PRINT_INPUT_VALUES
printf(" ---D---- ---S---- CZ = ");
#endif
printf("---Q---- CZ\n");
instr = instruct[index] | 0xf018120a;
for (s1 = 0; s1 < NUM_VALUES; s1++)
{
S = test_values[s1];
for (d1 = 0; d1 < NUM_VALUES; d1++)
{
D = test_values[d1];
for (C = 0; C <= 1; C++)
{
for (Z = 0; Z <= 1; Z++)
{
alu(instr, S, D, C, Z, &alu_q, &alu_c, &alu_z);
printf("%02x %03x", index, testnum++);
#ifdef PRINT_INPUT_VALUES
printf(" %08x %08x %1x%1x =", D, S, C, Z);
#endif
printf(" %08x %x%x\n", alu_q, alu_c, alu_z);
}
}
}
}
}
int main(void)
{
int j;
sleep(1);
for (j = 0; j < 72; j++)
{
writeTest(j);
}
return 0;
}
void testit(int *list)
{
__asm__(" rdlong r1, r0");
__asm__(" wrlong r1, ##instruct");
__asm__(" add r0, #4");
__asm__(" rdlong r2, r0");
__asm__(" add r0, #4");
__asm__(" rdlong r3, r0");
__asm__(" add r0, #4");
__asm__(" rdlong r1, r0");
__asm__(" shr r1, #1 wc");
__asm__(" and r1, #1");
__asm__(" xor r1, #1 wz");
__asm__(" jmp #instruct");
__asm__("instruct mov r2, r3 wcz");
__asm__(" if_nz_and_nc mov r1, #0");
__asm__(" if_nz_and_c mov r1, #1");
__asm__(" if_z_and_nc mov r1, #2");
__asm__(" if_z_and_c mov r1, #3");
__asm__(" wrlong r1, r0");
__asm__(" sub r0, #8");
__asm__(" wrlong r2, r0");
}

BIN
verify/testops1.bin Executable file

Binary file not shown.

127
verify/testops1.c Executable file
View File

@ -0,0 +1,127 @@
/*
* Testbench for the alu
* (c) Pacito.Sys
*/
#include <stdio.h>
#include <string.h>
#define PRINT_INPUT_VALUES
#define NUM_VALUES 8
#define MAX_POS 0x7fffffff
#define MAX_NEG 0x80000000
#define MAX_NEG1 0x80000001
#define WZ_BIT 0x00080000
#define WC_BIT 0x00100000
void testit(int *);
char *opcodeName[] = {
"testb0", "testb1", "testb2", "testb3", "testbn0", "testbn1", "testbn2", "testbn3",
"setnib0", "setnib1", "setnib2", "setnib3", "setnib4", "setnib5", "setnib6", "setnib7",
"getnib0", "getnib1", "getnib2", "getnib3", "getnib4", "getnib5", "getnib6", "getnib7",
"rolnib0", "rolnib1", "rolnib2", "rolnib3", "rolnib4", "rolnib5", "rolnib6", "rolnib7",
"setbyte0", "setbyte1", "setbyte2", "setbyte3", "getbyte0", "getbyte1", "getbyte2", "getbyte3",
"rolbyte0", "rolbyte1", "rolbyte2", "rolbyte3", "setword0", "setword1", "getword0", "getword1",
"rolword0", "rolword1", "setr", "setd", "sets", "decod", "bmask", "zerox",
"signx", "muxnits", "muxnibs", "movbyts", "mul", "muls", "addpix", "mulpix"};
int instruct[] = {
0x04100000, 0x04500000, 0x04900000, 0x04d00000, 0x04300000, 0x04700000, 0x04b00000, 0x04f00000,
0x08000000, 0x08080000, 0x08100000, 0x08180000, 0x08200000, 0x08280000, 0x08300000, 0x08380000,
0x08400000, 0x08480000, 0x08500000, 0x08580000, 0x08600000, 0x08680000, 0x08700000, 0x08780000,
0x08800000, 0x08880000, 0x08900000, 0x08980000, 0x08a00000, 0x08a80000, 0x08b00000, 0x08b80000,
0x08c00000, 0x08c80000, 0x08d00000, 0x08d80000, 0x08e00000, 0x08e80000, 0x08f00000, 0x08f80000,
0x09000000, 0x09080000, 0x09100000, 0x09180000, 0x09200000, 0x09280000, 0x09300000, 0x09380000,
0x09400000, 0x09480000, 0x09a80000, 0x09b00000, 0x09b80000, 0x09c00000, 0x09c80000, 0x09d00000,
0x09d80000, 0x09e00000, 0x09e80000, 0x09f80000, 0x0a080000, 0x0a180000, 0x0a400000, 0x0a480000};
int test_values[] = { 0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff };
int mailbox[4];
void alu(int opcode, int S, int D, int C, int Z, int *alu_q, int *alu_c, int *alu_z)
{
mailbox[0] = opcode;
mailbox[1] = D;
mailbox[2] = S;
mailbox[3] = (Z << 1) | C;
testit(mailbox);
*alu_q = mailbox[1];
*alu_c = mailbox[3] & 1;
*alu_z = (mailbox[3] >> 1) & 1;
}
void writeTest(int index)
{
int instr;
int testnum = 0;
int s1, d1, S, D, C, Z;
int alu_q, alu_c, alu_z;
char name[20];
strcpy(name, " ");
memcpy(name, opcodeName[index], strlen(opcodeName[index]));
printf("%s", name);
#ifdef PRINT_INPUT_VALUES
printf(" ---D---- ---S---- CZ = ");
#endif
printf("---Q---- CZ\n");
instr = instruct[index] | 0xf000120a;
for (s1 = 0; s1 < NUM_VALUES; s1++)
{
S = test_values[s1];
for (d1 = 0; d1 < NUM_VALUES; d1++)
{
D = test_values[d1];
for (C = 0; C <= 1; C++)
{
for (Z = 0; Z <= 1; Z++)
{
alu(instr, S, D, C, Z, &alu_q, &alu_c, &alu_z);
printf("%02x %03x", index, testnum++);
#ifdef PRINT_INPUT_VALUES
printf(" %08x %08x %1x%1x =", D, S, C, Z);
#endif
printf(" %08x %x%x\n", alu_q, alu_c, alu_z);
}
}
}
}
}
int main(void)
{
int j;
sleep(1);
for (j = 0; j < 64; j++)
{
writeTest(j);
}
return 0;
}
void testit(int *list)
{
__asm__(" rdlong r1, r0");
__asm__(" wrlong r1, ##instruct");
__asm__(" add r0, #4");
__asm__(" rdlong r2, r0");
__asm__(" add r0, #4");
__asm__(" rdlong r3, r0");
__asm__(" add r0, #4");
__asm__(" rdlong r1, r0");
__asm__(" shr r1, #1 wc");
__asm__(" and r1, #1");
__asm__(" xor r1, #1 wz");
__asm__(" jmp #instruct");
__asm__("instruct mov r2, r3 wcz");
__asm__(" if_nz_and_nc mov r1, #0");
__asm__(" if_nz_and_c mov r1, #1");
__asm__(" if_z_and_nc mov r1, #2");
__asm__(" if_z_and_c mov r1, #3");
__asm__(" wrlong r1, r0");
__asm__(" sub r0, #8");
__asm__(" wrlong r2, r0");
}

BIN
verify/testopsa.bin Executable file

Binary file not shown.

167
verify/testopsa.c Executable file
View File

@ -0,0 +1,167 @@
/*
* Testbench for the alu
* (c) Pacito.Sys
*/
#include <stdio.h>
#include <string.h>
#define PRINT_INPUT_VALUES
#define MAX_POS 0x7fffffff
#define MAX_NEG 0x80000000
#define MAX_NEG1 0x80000001
#define WZ_BIT 0x00080000
#define WC_BIT 0x00100000
void testit(int *);
char *opcodeName[] = {
"altsn", "altgn/g", "altgn/r", "altsb", "altgb/g", "altgb/r", "altsw", "altgw/g",
"altgw/r", "altr", "altd", "alts", "altb", "alti"};
int instruct[] = {
0xf804015a, 0xf8401400, 0xf8801400, 0xf8c4015a, 0xf8e01400, 0xf9001400, 0xf924015a, 0xf9301400,
0xf9401400, 0xf1001208, 0xf1001208, 0xf1001208, 0xf1001208, 0xf1001009};
int inst[] = {
0xf9501009, 0xf9581009, 0xf9581009, 0xf9601009, 0xf9681009, 0xf9681009, 0xf9701009, 0xf9781009,
0xf9781009, 0xf9801009, 0xf9881009, 0xf9901009, 0xf9981009, 0xf9a01208};
int vshift[] = {3, 3, 3, 2, 2, 2, 1, 1, 1, 0, 0, 0, 5, 0};
int mailbox[6];
void alu(int opcode, int S, int D, int C, int Z, int opcode1, int Q, int *alu_r, int *alu_c, int *alu_z, int *alu_x, int *alu_y)
{
mailbox[0] = opcode;
mailbox[1] = opcode1;
mailbox[2] = Q;
mailbox[3] = D;
mailbox[4] = S;
testit(mailbox);
*alu_r = mailbox[2];
*alu_x = mailbox[3];
*alu_y = mailbox[4];
*alu_c = 0;
*alu_z = 0;
}
void writeTest(int index)
{
int instr, instr1;
int testnum = 0;
int r1, r2, r3, incr, roff, val;
int alu_r, alu_c, alu_z, alu_x, alu_y;
char name[20];
int vnum = 1 << vshift[index];
int vshi = vshift[index];
if (vshi == 5) vnum = 1;
strcpy(name, " ");
memcpy(name, opcodeName[index], strlen(opcodeName[index]));
printf("instr ");
#ifdef PRINT_INPUT_VALUES
printf(" ---r3--- ---r2--- CZ ---r1--- = ");
#endif
printf("---r1--- CZ ---r2--- ---r3---\n");
instr = instruct[index];
instr1 = inst[index];
for (r3 = 0x12345678; r3 <= 0x12345678; r3++)
{
for (r2 = 0x78900003; r2 <= 0x78900003; r2++)
{
for (incr = -2; incr <= 2; incr++)
{
for (roff = 5; roff <= 7; roff++)
{
for (val = 0; val < vnum; val++)
{
r1 = (roff << vshi) | val;
r2 |= (incr & 511) << 9;
alu(instr, r3, r2, 0, 0, instr1, r1, &alu_r, &alu_c, &alu_z, &alu_x, &alu_y);
printf(name);
#ifdef PRINT_INPUT_VALUES
printf(" %08x %08x %1x%1x", r3, r2, 0, 0);
printf(" %08x =", r1);
#endif
printf(" %08x %x%x", alu_r, alu_c, alu_z);
printf(" %08x %08x\n", alu_x, alu_y);
}
}
}
}
}
}
void writeTestAlti(int index)
{
int instr, instr1;
int testnum = 0;
int r1, r2, r3, incr, roff, val;
int alu_r, alu_c, alu_z, alu_x, alu_y;
char name[20];
strcpy(name, " ");
memcpy(name, opcodeName[index], strlen(opcodeName[index]));
printf("instr ");
#ifdef PRINT_INPUT_VALUES
printf(" ---r3--- ---r2--- CZ ---r1--- = ");
#endif
printf("---r1--- CZ ---r2--- ---r3---\n");
instr = instruct[index];
instr1 = inst[index];
r3 = 0x12345678;
for (val = 0; val < 512; val++)
{
if ((val >> 6) == 5)
r2 = 0xf1801208;
else
r2 = (10 << 19) | (9 << 9) | 8;
r1 = 0x2ee00 | val;
alu(instr, r3, r2, 0, 0, instr1, r1, &alu_r, &alu_c, &alu_z, &alu_x, &alu_y);
printf(name);
#ifdef PRINT_INPUT_VALUES
printf(" %08x %08x %1x%1x", r3, r2, 0, 0);
printf(" %08x =", r1);
#endif
printf(" %08x %x%x", alu_r, alu_c, alu_z);
printf(" %08x %08x\n", alu_x, alu_y);
}
}
int main(void)
{
int j;
sleep(1);
for (j = 0; j < 13; j++)
{
writeTest(j);
}
writeTestAlti(13);
return 0;
}
void testit(int *list)
{
__asm__(" rdlong r1, r0");
__asm__(" wrlong r1, ##instruct");
__asm__(" add r0, #4");
__asm__(" rdlong r1, r0");
__asm__(" wrlong r1, ##instruct0");
__asm__(" add r0, #4");
__asm__(" rdlong r1, r0");
__asm__(" add r0, #4");
__asm__(" rdlong r2, r0");
__asm__(" add r0, #4");
__asm__(" rdlong r3, r0");
__asm__(" jmp #instruct0");
__asm__("instruct0 setq r1");
__asm__("instruct add r2, r3 wcz");
__asm__(" wrlong r3, r0");
__asm__(" sub r0, #4");
__asm__(" wrlong r2, r0");
__asm__(" sub r0, #4");
__asm__(" wrlong r1, r0");
}

BIN
verify/testopsd.bin Executable file

Binary file not shown.

124
verify/testopsd.c Executable file
View File

@ -0,0 +1,124 @@
/*
* Testbench for the alu
* (c) Pacito.Sys
*/
#include <stdio.h>
#include <string.h>
#define PRINT_INPUT_VALUES
#define NUM_VALUES 38
#define MAX_POS 0x7fffffff
#define MAX_NEG 0x80000000
#define MAX_NEG1 0x80000001
#define WZ_BIT 0x00080000
#define WC_BIT 0x00100000
void testit(int *);
char *opcodeName[] = {
"splitb", "mergeb", "splitw", "mergew", "seussf", "seussr", "rgbsqz", "rgbexp",
"rev", "rczr", "rczl", "wrc", "wrnc", "wrz", "wrnz", "modcz"};
int instruct[] = {
0x0d600060, 0x0d600061, 0x0d600062, 0x0d600063, 0x0d600064, 0x0d600065, 0x0d600066, 0x0d600067,
0x0d600069, 0x0d78006a, 0x0d78006b, 0x0d60006c, 0x0d60006d, 0x0d60006e, 0x0d60006f, 0x0d7c006f};
int test_values[38] = { 0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff,
4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000,
0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000,
0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000};
int mailbox[4];
void alu(int opcode, int S, int D, int C, int Z, int *alu_q, int *alu_c, int *alu_z)
{
mailbox[0] = opcode;
mailbox[1] = D;
mailbox[2] = S;
mailbox[3] = (Z << 1) | C;
testit(mailbox);
*alu_q = mailbox[1];
*alu_c = mailbox[3] & 1;
*alu_z = (mailbox[3] >> 1) & 1;
}
void writeTest(int index)
{
int instr;
int testnum = 0;
int s1, d1, S, D, C, Z;
int alu_q, alu_c, alu_z;
char name[20];
strcpy(name, " ");
memcpy(name, opcodeName[index], strlen(opcodeName[index]));
printf("%s", name);
#ifdef PRINT_INPUT_VALUES
printf(" ---D---- ---S---- CZ = ");
#endif
printf("---Q---- CZ\n");
instr = instruct[index] | 0xf0001200;
for (s1 = 0; s1 < 1; s1++)
{
S = test_values[s1];
for (d1 = 0; d1 < NUM_VALUES; d1++)
{
if (index == 15)
{
D = d1;
instr = (instr & ~0x3fe00) | ((D & 255) << 9);
}
else
D = test_values[d1];
for (C = 0; C <= 1; C++)
{
for (Z = 0; Z <= 1; Z++)
{
alu(instr, S, D, C, Z, &alu_q, &alu_c, &alu_z);
printf("%02x %03x", index, testnum++);
#ifdef PRINT_INPUT_VALUES
printf(" %08x %08x %1x%1x =", D, S, C, Z);
#endif
printf(" %08x %x%x\n", alu_q, alu_c, alu_z);
}
}
}
}
}
int main(void)
{
int j;
sleep(1);
for (j = 0; j < 16; j++)
{
writeTest(j);
}
return 0;
}
void testit(int *list)
{
__asm__(" rdlong r1, r0");
__asm__(" wrlong r1, ##instruct");
__asm__(" add r0, #4");
__asm__(" rdlong r2, r0");
__asm__(" add r0, #4");
__asm__(" rdlong r3, r0");
__asm__(" add r0, #4");
__asm__(" rdlong r1, r0");
__asm__(" shr r1, #1 wc");
__asm__(" and r1, #1");
__asm__(" xor r1, #1 wz");
__asm__(" jmp #instruct");
__asm__("instruct mov r2, r3 wcz");
__asm__(" if_nz_and_nc mov r1, #0");
__asm__(" if_nz_and_c mov r1, #1");
__asm__(" if_z_and_nc mov r1, #2");
__asm__(" if_z_and_c mov r1, #3");
__asm__(" wrlong r1, r0");
__asm__(" sub r0, #8");
__asm__(" wrlong r2, r0");
}

BIN
verify/testopsq.bin Executable file

Binary file not shown.

171
verify/testopsq.c Executable file
View File

@ -0,0 +1,171 @@
/*
* Testbench for the alu
* (c) Pacito.Sys
*/
#include <stdio.h>
#include <string.h>
#define PRINT_INPUT_VALUES
#define NUM_VALUES 8
#define MAX_POS 0x7fffffff
#define MAX_NEG 0x80000000
#define MAX_NEG1 0x80000001
#define WZ_BIT 0x00080000
#define WC_BIT 0x00100000
#define SETQ_INSTR 0xfd601016
#define SETPIX_INS 0xfd60103d
#define SETPIV_INS 0xfd60103e
#define SCLU_INSTR 0xfa20100a
#define SCL_INSTR 0xfa30100a
void testit(int *);
char *opcodeName[] = {
"qmul", "qdiv", "qfrac", "qsqrt", "qrotate", "qvector", "qlog", "qexp",
"muxq", "blnpix", "mixpix", "sclu", "scl"
};
int instruct[] = {
0x0d000000, 0x0d100000, 0x0d200000, 0x0d300000, 0x0d400000, 0x0d500000, 0x0d60000e, 0x0d60000f,
0x09f00000, 0x0a500000, 0x0a580000, 0x06040000, 0x06040000
};
int snum[] = { NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES, 1, 1,
NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES};
int dnum[] = { NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES, 38, 38,
NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES};
int qnum[] = { 1, NUM_VALUES, NUM_VALUES, NUM_VALUES, 1, NUM_VALUES, 1, 1,
NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES, NUM_VALUES};
int inst[] = { SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR, SETQ_INSTR,
SETQ_INSTR, SETPIV_INS, SETPIX_INS, SCLU_INSTR, SCL_INSTR};
int test_values[38] = { 0, 1, 2, 0x7fffffff, 0x80000000, 0x80000001, 0xfffffffe, 0xffffffff,
4, 8, 0x10, 0x20, 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000,
0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000,
0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000};
int mailbox[6];
void alu(int opcode, int S, int D, int C, int Z, int opcode1, int Q, int *alu_r, int *alu_c, int *alu_z, int *alu_x, int *alu_y)
{
mailbox[0] = opcode;
mailbox[1] = D;
mailbox[2] = S;
mailbox[3] = (Z << 1) | C;
mailbox[4] = opcode1;
mailbox[5] = Q;
testit(mailbox);
*alu_r = mailbox[1];
*alu_c = mailbox[3] & 1;
*alu_z = (mailbox[3] >> 1) & 1;
*alu_x = mailbox[4];
*alu_y = mailbox[5];
}
void writeTest(int index)
{
int instr, instr1;
int testnum = 0;
int s1, d1, q1, S, D, C, Z, Q;
int alu_r, alu_c, alu_z, alu_x, alu_y;
char name[20];
strcpy(name, " ");
memcpy(name, opcodeName[index], strlen(opcodeName[index]));
#if 0
printf("%s", name);
#else
printf("instr ");
#endif
#ifdef PRINT_INPUT_VALUES
printf(" ---D---- ---S---- CZ ---Q---- = ");
#endif
printf("---R---- CZ ---X---- ---Y----\n");
if (snum[index] <= 2)
instr = instruct[index] | 0xf0001200;
else
instr = instruct[index] | 0xf000120a;
instr1 = inst[index];
for (q1 = 0; q1 < qnum[index]; q1++)
{
Q = test_values[q1];
for (s1 = 0; s1 < snum[index]; s1++)
{
S = test_values[s1];
for (d1 = 0; d1 < dnum[index]; d1++)
{
D = test_values[d1];
for (C = 0; C < 1; C++)
{
for (Z = 0; Z < 1; Z++)
{
alu(instr, S, D, C, Z, instr1, Q, &alu_r, &alu_c, &alu_z, &alu_x, &alu_y);
#if 0
printf("%02x %03x", index, testnum++);
#else
printf(name);
#endif
#ifdef PRINT_INPUT_VALUES
printf(" %08x %08x %1x%1x", D, S, C, Z);
printf(" %08x =", Q);
#endif
printf(" %08x %x%x", alu_r, alu_c, alu_z);
printf(" %08x %08x\n", alu_x, alu_y);
}
}
}
}
}
}
int main(void)
{
int j;
sleep(1);
for (j = 0; j < 13; j++)
{
if (j == 1 || j == 2 || j == 4 || j == 5) continue;
writeTest(j);
}
return 0;
}
void testit(int *list)
{
__asm__(" rdlong r1, r0");
__asm__(" wrlong r1, ##instruct");
__asm__(" add r0, #4");
__asm__(" rdlong r2, r0");
__asm__(" add r0, #4");
__asm__(" rdlong r3, r0");
__asm__(" add r0, #4");
__asm__(" rdlong r1, r0");
__asm__(" shr r1, #1 wc");
__asm__(" and r1, #1");
__asm__(" xor r1, #1 wz");
__asm__(" add r0, #4");
__asm__(" rdlong r1, r0");
__asm__(" wrlong r1, ##instruct0");
__asm__(" add r0, #4");
__asm__(" rdlong r1, r0");
__asm__(" jmp #instruct0");
__asm__("instruct0 setq r1");
__asm__("instruct add r2, r3 wcz");
__asm__(" 'add r0, #4");
__asm__(" sub r0, #4");
__asm__(" getqx r1");
__asm__(" wrlong r1, r0");
__asm__(" add r0, #4");
__asm__(" getqy r1");
__asm__(" wrlong r1, r0");
__asm__(" sub r0, #8");
__asm__(" if_nz_and_nc mov r1, #0");
__asm__(" if_nz_and_c mov r1, #1");
__asm__(" if_z_and_nc mov r1, #2");
__asm__(" if_z_and_c mov r1, #3");
__asm__(" wrlong r1, r0");
__asm__(" sub r0, #8");
__asm__(" wrlong r2, r0");
}