Update to Dave Hein's version 0.97.
This commit is contained in:
parent
66915a7ad1
commit
c33ed7cf35
4
Makefile
4
Makefile
|
@ -21,7 +21,7 @@ endif
|
||||||
|
|
||||||
TARGET = $(BUILD)/spinsim$(EXT)
|
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)
|
ifneq ($(OS),msys)
|
||||||
SOURCES += conion.c
|
SOURCES += conion.c
|
||||||
|
@ -47,5 +47,5 @@ $(BUILD)/%.o: %.c
|
||||||
$(CC) $(CFLAGS) $< -o $@
|
$(CC) $(CFLAGS) $< -o $@
|
||||||
|
|
||||||
clean: FORCE
|
clean: FORCE
|
||||||
rm -f $(BUILD)
|
rm -rf $(BUILD)
|
||||||
FORCE:
|
FORCE:
|
||||||
|
|
115
README.md
115
README.md
|
@ -1,38 +1,44 @@
|
||||||
Spinsim 0.75
|
Spinsim 0.97
|
||||||
|
|
||||||
This version of spinsim supports about two-thirds of the opcodes in the P2
|
This version of spinsim supports most of the opcodes in the P2 v20 instruction
|
||||||
instruction set. The list of implemented opcodes is shown below, along with
|
set. The opcodes that are not supported are as follows:
|
||||||
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
|
xzero xinit xcont clkset setdacs setxfrq getxcos getxsin
|
||||||
with the code located at $E00. A simulated serial port is supported by using
|
setbrk setcy setci setcq setcfrq setcmod getrnd xoro32
|
||||||
the -b option. The default baud rate is 115,200, but other rates can be used
|
skip skipf execf
|
||||||
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
|
skip, skipf and execf have been partially implemented, but do not handle jumps
|
||||||
built and run it under Cygwin and Ubuntu Linux.
|
or interrupts correctly.
|
||||||
|
|
||||||
The sample program, pfth.spin can be run by building it with the PNut P2
|
Spinsim runs in the P1 mode by default. It can be set to run in the P2 mode
|
||||||
assembler. PNut is contained in the Terasic_Prop2_Emulation zip file,
|
with the -t parameter. In the P2 mode, spinsim will load a P2 binary file into
|
||||||
which can be downloaded from the first post in the "HUB EXEC Update Here"
|
hub RAM, and start cog 0 with the code located at $000. A simulated serial
|
||||||
thread in the Propeller 2 forum.
|
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.
|
||||||
|
|
||||||
There are two demo programs, which are the pfth Forth interpreter and the
|
Spinsim is built under Linux, MinGW or Cygwin by using the Makefile, and typing
|
||||||
p1spin Spin interpreter that runs P1 Spin binaries on the P2 processor.
|
make. The Windows executable, spinsim.exe is included with this distribution.
|
||||||
The pfth program is run under spinsim as follows:
|
|
||||||
|
|
||||||
./spinsim -t -b pfth.obj
|
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.
|
||||||
|
|
||||||
p1spin runs at a baud rate of 57600, so it is run as follows:
|
A test program can be run by going into the verify directory and typing
|
||||||
|
|
||||||
./spinsim -t -b57600 p1spin.obj
|
../spinsim -t -b testopsa.bin
|
||||||
|
|
||||||
Spinsim supports execution from cog memory and hub execution, but it does not
|
The output can be redirected to a file and compared with the hardware file
|
||||||
support multi-tasking. Only the core processor is supported, and none of the
|
to verify that spinsim matches the hardware.
|
||||||
counters, video hardware or cordic hardware is simulated. Support for multi-
|
|
||||||
tasking, peripheral hardware and cordic instructions will be added later.
|
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
|
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
|
option. The debugger prints the prompt "DEBUG>" to indicate that it is ready
|
||||||
|
@ -48,6 +54,8 @@ verbose # - Set verbosity level
|
||||||
reboot - Reboot the Prop
|
reboot - Reboot the Prop
|
||||||
setbr cog addr - Set breakpoint for cog to addr
|
setbr cog addr - Set breakpoint for cog to addr
|
||||||
state cog - Dump cog state
|
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
|
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.
|
non-executing cycles until it encounters an instruction that is executed.
|
||||||
|
@ -78,58 +86,3 @@ 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
|
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
|
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.
|
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
|
|
||||||
|
|
136
conio.spin
136
conio.spin
|
@ -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. |
|
|
||||||
+------------------------------------------------------------------------------------------------------------------------------+
|
|
||||||
}}
|
|
56
conion.c
56
conion.c
|
@ -1,4 +1,3 @@
|
||||||
#ifdef LINUX
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "conion.h"
|
#include "conion.h"
|
||||||
|
|
||||||
|
@ -15,59 +14,50 @@ int kbhit(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char getch(void)
|
|
||||||
{
|
|
||||||
return getchar();
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
#include <termios.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <termios.h>
|
||||||
|
#include <sys/select.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
static struct termios oldt;
|
|
||||||
static int oldf;
|
|
||||||
static int lastkey = EOF;
|
|
||||||
static int initialized = 0;
|
static int initialized = 0;
|
||||||
|
static struct termios oldt;
|
||||||
|
|
||||||
void initialize_console_io()
|
void initialize_console_io(void)
|
||||||
{
|
{
|
||||||
struct termios newt;
|
struct termios newt;
|
||||||
|
|
||||||
|
if (initialized) return;
|
||||||
tcgetattr(STDIN_FILENO, &oldt);
|
tcgetattr(STDIN_FILENO, &oldt);
|
||||||
newt = oldt;
|
newt = oldt;
|
||||||
newt.c_lflag &= ~(ICANON | ECHO);
|
newt.c_lflag &= ~(ICANON | ECHO | ISIG);
|
||||||
|
newt.c_iflag &= ~(ICRNL | INLCR);
|
||||||
|
newt.c_oflag &= ~OPOST;
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
||||||
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
|
|
||||||
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
|
|
||||||
initialized = 1;
|
initialized = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void restore_console_io()
|
void restore_console_io(void)
|
||||||
{
|
{
|
||||||
if (initialized)
|
if (!initialized) return;
|
||||||
{
|
|
||||||
initialized = 0;
|
|
||||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||||||
fcntl(STDIN_FILENO, F_SETFL, oldf);
|
initialized = 0;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int kbhit(void)
|
int kbhit(void)
|
||||||
{
|
{
|
||||||
if (lastkey == EOF)
|
fd_set set;
|
||||||
lastkey = getchar();
|
struct timeval tv;
|
||||||
|
|
||||||
return (lastkey != EOF);
|
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
|
||||||
|
|
||||||
char getch(void)
|
int getch(void)
|
||||||
{
|
{
|
||||||
int ch;
|
return getchar();
|
||||||
|
|
||||||
while (!kbhit());
|
|
||||||
ch = lastkey;
|
|
||||||
lastkey = EOF;
|
|
||||||
return ch;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
2
conion.h
2
conion.h
|
@ -4,7 +4,7 @@
|
||||||
#undef STD_CONSOLE_INPUT
|
#undef STD_CONSOLE_INPUT
|
||||||
|
|
||||||
int kbhit(void);
|
int kbhit(void);
|
||||||
char getch(void);
|
int getch(void);
|
||||||
void initialize_console_io(void);
|
void initialize_console_io(void);
|
||||||
void restore_console_io(void);
|
void restore_console_io(void);
|
||||||
|
|
||||||
|
|
63
conion.new
Executable file
63
conion.new
Executable 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
71
conion.old
Executable 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
83
debug.c
|
@ -9,14 +9,9 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#ifdef LINUX
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include "conion.h"
|
#include "conion.h"
|
||||||
#else
|
|
||||||
#include <conio.h>
|
|
||||||
#include <direct.h>
|
|
||||||
#endif
|
|
||||||
#include "interp.h"
|
#include "interp.h"
|
||||||
#include "spindebug.h"
|
#include "spindebug.h"
|
||||||
#include "eeprom.h"
|
#include "eeprom.h"
|
||||||
|
@ -29,22 +24,26 @@ extern int32_t eeprom;
|
||||||
extern char *hubram;
|
extern char *hubram;
|
||||||
extern int32_t printbreak;
|
extern int32_t printbreak;
|
||||||
extern PasmVarsT PasmVars[8];
|
extern PasmVarsT PasmVars[8];
|
||||||
|
extern SerialT serial_in;
|
||||||
|
extern SerialT serial_out;
|
||||||
|
|
||||||
void GetDebugString(char *ptr);
|
void GetDebugString(char *ptr);
|
||||||
int32_t RunProp(int32_t maxloops);
|
int32_t RunProp(int32_t maxloops);
|
||||||
|
|
||||||
void Help(void)
|
void Help(void)
|
||||||
{
|
{
|
||||||
printf("Debug Commands\n");
|
printf("Debug Commands%s", NEW_LINE);
|
||||||
printf("help - Print command list\n");
|
printf("help - Print command list%s", NEW_LINE);
|
||||||
printf("exit - Exit spinsim\n");
|
printf("exit - Exit spinsim%s", NEW_LINE);
|
||||||
printf("step - Run one cycle\n");
|
printf("step - Run one cycle%s", NEW_LINE);
|
||||||
printf("stepx - Run next executed instruction\n");
|
printf("stepx - Run next executed instruction%s", NEW_LINE);
|
||||||
printf("run - Run continuously\n");
|
printf("run - Run continuously%s", NEW_LINE);
|
||||||
printf("verbose # - Set verbosity level\n");
|
printf("verbose # - Set verbosity level%s", NEW_LINE);
|
||||||
printf("reboot - Reboot the Prop\n");
|
printf("reboot - Reboot the Prop%s", NEW_LINE);
|
||||||
printf("setbr cog addr - Set breakpoint for cog to addr\n");
|
printf("setbr cog addr - Set breakpoint for cog to addr%s", NEW_LINE);
|
||||||
printf("state cog - Dump cog state\n");
|
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)
|
char *SkipChar(char *str, int value)
|
||||||
|
@ -59,15 +58,15 @@ char *SkipChar(char *str, int value)
|
||||||
|
|
||||||
void DumpState(PasmVarsT *pasmvars)
|
void DumpState(PasmVarsT *pasmvars)
|
||||||
{
|
{
|
||||||
printf("cflag = %d, zflag = %d, waitflag = %d\n",
|
printf("cflag = %d, zflag = %d, waitflag = %d%s",
|
||||||
pasmvars->cflag, pasmvars->zflag, pasmvars->waitflag);
|
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\n",
|
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->ptra, pasmvars->ptra, pasmvars->ptrx,
|
||||||
pasmvars->ptry, pasmvars->inda, pasmvars->indb);
|
pasmvars->ptry, pasmvars->inda, pasmvars->indb, NEW_LINE);
|
||||||
printf("pc1 = %8.8x, instruct1 = %8.8x\n", pasmvars->pc1, pasmvars->instruct1);
|
printf("pc1 = %8.8x, instruct1 = %8.8x%s", pasmvars->pc1, pasmvars->instruct1, NEW_LINE);
|
||||||
printf("pc2 = %8.8x, instruct2 = %8.8x\n", pasmvars->pc2, pasmvars->instruct2);
|
printf("pc2 = %8.8x, instruct2 = %8.8x%s", pasmvars->pc2, pasmvars->instruct2, NEW_LINE);
|
||||||
printf("pc3 = %8.8x, instruct3 = %8.8x\n", pasmvars->pc3, pasmvars->instruct3);
|
printf("pc3 = %8.8x, instruct3 = %8.8x%s", pasmvars->pc3, pasmvars->instruct3, NEW_LINE);
|
||||||
printf("pc4 = %8.8x, instruct4 = %8.8x\n", pasmvars->pc4, pasmvars->instruct4);
|
printf("pc4 = %8.8x, instruct4 = %8.8x%s", pasmvars->pc4, pasmvars->instruct4, NEW_LINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debug(void)
|
void Debug(void)
|
||||||
|
@ -84,7 +83,7 @@ void Debug(void)
|
||||||
{
|
{
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
printf("\nDEBUG> ");
|
printf("%sDEBUG> ", NEW_LINE);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
GetDebugString(buffer);
|
GetDebugString(buffer);
|
||||||
if (buffer[0] == 0) strcpy(buffer, lastcmd);
|
if (buffer[0] == 0) strcpy(buffer, lastcmd);
|
||||||
|
@ -139,9 +138,21 @@ void Debug(void)
|
||||||
{
|
{
|
||||||
int cognum, address;
|
int cognum, address;
|
||||||
sscanf(buffer+6, "%x %x", &cognum, &address);
|
sscanf(buffer+6, "%x %x", &cognum, &address);
|
||||||
PasmVars[cognum&7].breakpnt = address;
|
PasmVars[cognum&15].breakpnt = address;
|
||||||
LONG(SYS_DEBUG) = printflag;
|
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"))
|
else if (!strcmp(buffer, "reboot"))
|
||||||
{
|
{
|
||||||
RebootProp();
|
RebootProp();
|
||||||
|
@ -152,7 +163,7 @@ void Debug(void)
|
||||||
DumpState(&PasmVars[cognum]);
|
DumpState(&PasmVars[cognum]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
printf("?\n");
|
printf("?%s", NEW_LINE);
|
||||||
}
|
}
|
||||||
if (runflag) RunProp(maxloops);
|
if (runflag) RunProp(maxloops);
|
||||||
if (stepflag)
|
if (stepflag)
|
||||||
|
@ -168,6 +179,7 @@ void Debug(void)
|
||||||
void GetDebugString(char *ptr)
|
void GetDebugString(char *ptr)
|
||||||
{
|
{
|
||||||
int value;
|
int value;
|
||||||
|
char *ptr0 = ptr;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
@ -175,12 +187,25 @@ void GetDebugString(char *ptr)
|
||||||
while (!kbhit());
|
while (!kbhit());
|
||||||
#endif
|
#endif
|
||||||
value = getch();
|
value = getch();
|
||||||
putchx(value);
|
if (value == 8 || value == 0x7f)
|
||||||
|
{
|
||||||
|
if (ptr != ptr0)
|
||||||
|
{
|
||||||
|
ptr--;
|
||||||
|
putchx(8);
|
||||||
|
putchx(' ');
|
||||||
|
putchx(8);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (value == 13 || value == 10)
|
if (value == 13 || value == 10)
|
||||||
{
|
{
|
||||||
|
putchx(13);
|
||||||
|
putchx(10);
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
putchx(value);
|
||||||
*ptr++ = value;
|
*ptr++ = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,8 +220,8 @@ int32_t RunProp(int32_t maxloops)
|
||||||
CheckCommand();
|
CheckCommand();
|
||||||
if (baudrate)
|
if (baudrate)
|
||||||
{
|
{
|
||||||
CheckSerialOut();
|
CheckSerialOut(&serial_out);
|
||||||
if (CheckSerialIn()) return 1;
|
if (CheckSerialIn(&serial_in)) return 1;
|
||||||
}
|
}
|
||||||
if (eeprom)
|
if (eeprom)
|
||||||
CheckEEProm();
|
CheckEEProm();
|
||||||
|
|
12
eeprom.c
12
eeprom.c
|
@ -6,12 +6,12 @@
|
||||||
'******************************************************************************/
|
'******************************************************************************/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include "spinsim.h"
|
#include "spinsim.h"
|
||||||
|
|
||||||
extern int32_t pin_val;
|
extern int32_t pin_val_a;
|
||||||
extern int32_t eeprom;
|
extern int32_t eeprom;
|
||||||
|
|
||||||
static int32_t scl_prev = 1;
|
static int32_t scl_prev = 1;
|
||||||
|
@ -28,8 +28,8 @@ static unsigned char memory[256*256];
|
||||||
|
|
||||||
void CheckEEProm()
|
void CheckEEProm()
|
||||||
{
|
{
|
||||||
int32_t scl = (pin_val >> 28) & 1;
|
int32_t scl = (pin_val_a >> 28) & 1;
|
||||||
int32_t sda = (pin_val >> 29) & 1;
|
int32_t sda = (pin_val_a >> 29) & 1;
|
||||||
|
|
||||||
if (!eeprom) return;
|
if (!eeprom) return;
|
||||||
|
|
||||||
|
@ -136,7 +136,7 @@ void CheckEEProm()
|
||||||
}
|
}
|
||||||
if (drivepin)
|
if (drivepin)
|
||||||
{
|
{
|
||||||
pin_val = (pin_val & (~(1 << 29))) | (driveval << 29);
|
pin_val_a = (pin_val_a & (~(1 << 29))) | (driveval << 29);
|
||||||
sda = driveval;
|
sda = driveval;
|
||||||
}
|
}
|
||||||
scl_prev = scl;
|
scl_prev = scl;
|
||||||
|
@ -148,7 +148,7 @@ static FILE *OpenFile(char *fname, char *mode)
|
||||||
FILE *file = fopen(fname, mode);
|
FILE *file = fopen(fname, mode);
|
||||||
if (!file)
|
if (!file)
|
||||||
{
|
{
|
||||||
printf("Could not open %s\n", fname);
|
printf("Could not open %s%s", fname, NEW_LINE);
|
||||||
spinsim_exit(1);
|
spinsim_exit(1);
|
||||||
}
|
}
|
||||||
return file;
|
return file;
|
||||||
|
|
189
fileio.spin
189
fileio.spin
|
@ -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
6
gdb.c
|
@ -8,14 +8,9 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#ifdef LINUX
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include "conion.h"
|
#include "conion.h"
|
||||||
#else
|
|
||||||
#include <conio.h>
|
|
||||||
#include <direct.h>
|
|
||||||
#endif
|
|
||||||
#include "interp.h"
|
#include "interp.h"
|
||||||
#include "spinsim.h"
|
#include "spinsim.h"
|
||||||
|
|
||||||
|
@ -27,7 +22,6 @@ extern FILE *cmdfile;
|
||||||
extern PasmVarsT PasmVars[8];
|
extern PasmVarsT PasmVars[8];
|
||||||
extern char *hubram;
|
extern char *hubram;
|
||||||
char cmd[1028];
|
char cmd[1028];
|
||||||
extern int32_t proptwo;
|
|
||||||
extern int32_t profile;
|
extern int32_t profile;
|
||||||
extern int32_t loopcount;
|
extern int32_t loopcount;
|
||||||
|
|
||||||
|
|
100
interp.h
100
interp.h
|
@ -19,6 +19,16 @@
|
||||||
|
|
||||||
#define INVALIDATE_INSTR 0x80000000
|
#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
|
// This struct is used by the PASM simulator
|
||||||
typedef struct PasmVarsS {
|
typedef struct PasmVarsS {
|
||||||
int32_t mem[512];
|
int32_t mem[512];
|
||||||
|
@ -31,6 +41,7 @@ typedef struct PasmVarsS {
|
||||||
int32_t waitmode;
|
int32_t waitmode;
|
||||||
int32_t breakpnt;
|
int32_t breakpnt;
|
||||||
// P2 variables
|
// P2 variables
|
||||||
|
int32_t lut[512];
|
||||||
int32_t instruct1;
|
int32_t instruct1;
|
||||||
int32_t instruct2;
|
int32_t instruct2;
|
||||||
int32_t instruct3;
|
int32_t instruct3;
|
||||||
|
@ -39,10 +50,16 @@ typedef struct PasmVarsS {
|
||||||
int32_t pc2;
|
int32_t pc2;
|
||||||
int32_t pc3;
|
int32_t pc3;
|
||||||
int32_t pc4;
|
int32_t pc4;
|
||||||
int32_t dcachehubaddr;
|
int32_t str_fifo_buffer[16];
|
||||||
int32_t dcachecogaddr;
|
int32_t str_fifo_rindex;
|
||||||
int32_t icachehubaddr[4];
|
int32_t str_fifo_windex;
|
||||||
int32_t icachenotused[4];
|
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 ptra;
|
||||||
int32_t ptra0;
|
int32_t ptra0;
|
||||||
int32_t ptrb;
|
int32_t ptrb;
|
||||||
|
@ -61,23 +78,64 @@ typedef struct PasmVarsS {
|
||||||
int32_t repbot;
|
int32_t repbot;
|
||||||
int32_t reptop;
|
int32_t reptop;
|
||||||
int32_t repforever;
|
int32_t repforever;
|
||||||
int32_t dcache[8];
|
int32_t retstack[8];
|
||||||
int32_t icache[4][8];
|
|
||||||
int32_t retstack[4];
|
|
||||||
int32_t auxram[256];
|
|
||||||
int32_t printflag;
|
int32_t printflag;
|
||||||
int32_t retptr;
|
int32_t retptr;
|
||||||
int32_t divq;
|
int32_t memflag;
|
||||||
int32_t divr;
|
int32_t qreg;
|
||||||
int32_t divisor;
|
int32_t qxreg;
|
||||||
int32_t mulcount;
|
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 augsvalue;
|
||||||
int32_t augsflag;
|
int32_t augsflag;
|
||||||
int32_t augdvalue;
|
int32_t augdvalue;
|
||||||
int32_t augdflag;
|
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 prefetch;
|
||||||
int32_t sqrt;
|
int32_t sqrt;
|
||||||
int32_t lastd;
|
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 acca;
|
||||||
int64_t accb;
|
int64_t accb;
|
||||||
int64_t mul;
|
int64_t mul;
|
||||||
|
@ -125,13 +183,21 @@ void RebootProp(void);
|
||||||
int32_t GetCnt(void);
|
int32_t GetCnt(void);
|
||||||
void UpdatePins(void);
|
void UpdatePins(void);
|
||||||
int32_t MAP_ADDR(int32_t addr);
|
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);
|
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 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 |
|
| TERMS OF USE: MIT License |
|
||||||
|
|
Binary file not shown.
|
@ -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)
|
|
2069
p1spin/p1spin.spin
2069
p1spin/p1spin.spin
File diff suppressed because it is too large
Load Diff
351
p1spin/spasm.txt
351
p1spin/spasm.txt
|
@ -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.
|
@ -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)
|
|
10
pasmdebug.c
10
pasmdebug.c
|
@ -9,7 +9,7 @@
|
||||||
#include "interp.h"
|
#include "interp.h"
|
||||||
|
|
||||||
char *FindChar(char *str, int32_t val);
|
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 char *hubram;
|
||||||
extern int32_t memsize;
|
extern int32_t memsize;
|
||||||
|
@ -168,7 +168,7 @@ void DebugPasmInstruction(PasmVarsT *pasmvars)
|
||||||
{
|
{
|
||||||
if (opcode <= 0x07) // hubop
|
if (opcode <= 0x07) // hubop
|
||||||
{
|
{
|
||||||
if (CheckWaitFlag(pasmvars, 3)) xflag = 2;
|
if (CheckWaitFlag1(pasmvars, 3)) xflag = 2;
|
||||||
}
|
}
|
||||||
else if (opcode == 0x3e) // waitcnt
|
else if (opcode == 0x3e) // waitcnt
|
||||||
{
|
{
|
||||||
|
@ -202,15 +202,9 @@ void DebugPasmInstruction(PasmVarsT *pasmvars)
|
||||||
while (i < 7) opstr[i++] = ' ';
|
while (i < 7) opstr[i++] = ' ';
|
||||||
opstr[i] = 0;
|
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,
|
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,
|
instruct, xstr[xflag], condnames[cond], opstr, dstaddr,
|
||||||
istr[zcri & 1], srcaddr, wzstr, wcstr, wrstr);
|
istr[zcri & 1], srcaddr, wzstr, wcstr, wrstr);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
+------------------------------------------------------------------------------------------------------------------------------+
|
+------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
|
389
pasmdebug2.c
389
pasmdebug2.c
|
@ -9,7 +9,7 @@
|
||||||
#include "interp.h"
|
#include "interp.h"
|
||||||
#include "spinsim.h"
|
#include "spinsim.h"
|
||||||
|
|
||||||
#define REG_PINA 0x1f4
|
#define ADDR_MASK 0xfffff
|
||||||
|
|
||||||
extern char *hubram;
|
extern char *hubram;
|
||||||
extern int32_t memsize;
|
extern int32_t memsize;
|
||||||
|
@ -19,249 +19,18 @@ extern int32_t pin_val;
|
||||||
|
|
||||||
extern FILE *tracefile;
|
extern FILE *tracefile;
|
||||||
|
|
||||||
static char *condnames[16] = {
|
void Disassemble2(int instruct, int pc, char *debugstr, int *errflag);
|
||||||
"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 ", " "};
|
|
||||||
|
|
||||||
char *opcodes_lower[64] = {
|
void StartPasmCog2(PasmVarsT *pasmvars, int32_t par, int32_t addr, int32_t cogid, int32_t hubexec)
|
||||||
"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)
|
|
||||||
{
|
{
|
||||||
int32_t i;
|
int32_t i;
|
||||||
|
|
||||||
// printf("\nStartPasmCog2: %8.8x, %8.8x, %d\n", par, addr, cogid);
|
//printf("\nStartPasmCog2: %8.8x, %8.8x, %d, %d\n", par, addr, cogid, hubexec);
|
||||||
par &= 0x3ffff;
|
par &= ADDR_MASK;
|
||||||
addr &= 0x3fffc;
|
addr &= ADDR_MASK;
|
||||||
pasmvars->waitflag = 0;
|
pasmvars->waitflag = 0;
|
||||||
pasmvars->cflag = 0;
|
pasmvars->cflag = 0;
|
||||||
pasmvars->zflag = 0;
|
pasmvars->zflag = 0;
|
||||||
pasmvars->pc = 0;
|
|
||||||
pasmvars->cogid = cogid;
|
pasmvars->cogid = cogid;
|
||||||
pasmvars->state = 5;
|
pasmvars->state = 5;
|
||||||
pasmvars->ptra = par;
|
pasmvars->ptra = par;
|
||||||
|
@ -278,8 +47,6 @@ void StartPasmCog2(PasmVarsT *pasmvars, int32_t par, int32_t addr, int32_t cogid
|
||||||
pasmvars->repbot = 0;
|
pasmvars->repbot = 0;
|
||||||
pasmvars->reptop = 0;
|
pasmvars->reptop = 0;
|
||||||
pasmvars->repforever = 0;
|
pasmvars->repforever = 0;
|
||||||
pasmvars->dcachehubaddr = 0xffffffff;
|
|
||||||
pasmvars->dcachecogaddr = 0xffffffff;
|
|
||||||
pasmvars->instruct1 = 0;
|
pasmvars->instruct1 = 0;
|
||||||
pasmvars->instruct2 = 0;
|
pasmvars->instruct2 = 0;
|
||||||
pasmvars->instruct3 = 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->retptr = 0;
|
||||||
pasmvars->acca = 0;
|
pasmvars->acca = 0;
|
||||||
pasmvars->accb = 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->breakpnt = -1;
|
||||||
pasmvars->augsflag = 0;
|
pasmvars->augsflag = 0;
|
||||||
pasmvars->augsvalue = 0;
|
pasmvars->augsvalue = 0;
|
||||||
pasmvars->augdflag = 0;
|
pasmvars->augdflag = 0;
|
||||||
pasmvars->augdvalue = 0;
|
pasmvars->augdvalue = 0;
|
||||||
pasmvars->icachehubaddr[0] = 0xffffffff;
|
pasmvars->altsflag = 0;
|
||||||
pasmvars->icachehubaddr[1] = 0xffffffff;
|
pasmvars->altsvalue = 0;
|
||||||
pasmvars->icachehubaddr[2] = 0xffffffff;
|
pasmvars->altdflag = 0;
|
||||||
pasmvars->icachehubaddr[3] = 0xffffffff;
|
pasmvars->altdvalue = 0;
|
||||||
pasmvars->icachenotused[0] = 0;
|
pasmvars->altrflag = 0;
|
||||||
pasmvars->icachenotused[1] = 0;
|
pasmvars->altrvalue = 0;
|
||||||
pasmvars->icachenotused[2] = 0;
|
pasmvars->altiflag = 0;
|
||||||
pasmvars->icachenotused[3] = 0;
|
pasmvars->altivalue = 0;
|
||||||
pasmvars->prefetch = 1;
|
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;
|
||||||
|
|
||||||
|
if (!hubexec)
|
||||||
|
{
|
||||||
for (i = 0; i < 0x1f4; i++)
|
for (i = 0; i < 0x1f4; i++)
|
||||||
{
|
{
|
||||||
pasmvars->mem[i] = LONG(addr);
|
pasmvars->mem[i] = LONG(addr);
|
||||||
addr += 4;
|
addr += 4;
|
||||||
}
|
}
|
||||||
|
pasmvars->pc = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pasmvars->pc = addr;
|
||||||
for (i = 0x1f4; i < 512; i++) pasmvars->mem[i] = 0;
|
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 cflag = pasmvars->cflag;
|
||||||
int32_t zflag = pasmvars->zflag;
|
int32_t zflag = pasmvars->zflag;
|
||||||
int32_t instruct, pc, cond, xflag;
|
int32_t instruct, pc, cond, xflag;
|
||||||
int32_t opcode, zci;
|
|
||||||
int32_t srcaddr, dstaddr;
|
|
||||||
char *wzstr = "";
|
|
||||||
char *wcstr = "";
|
|
||||||
char opstr[20];
|
char opstr[20];
|
||||||
char *istr[3] = {" ", "#", "@"};
|
char *xstr[12] = {" ", "X", "I", "H", "C", "P", "W", "F", "w", "E", "?", "S"};
|
||||||
char *xstr[8] = {" ", "X", "I", "H", "C", "P", "W", "?"};
|
|
||||||
int zci_mask;
|
|
||||||
int32_t sflag, dflag, indirect, opcode_zci;
|
|
||||||
|
|
||||||
// Fetch the instruction
|
// Fetch the instruction
|
||||||
pc = pasmvars->pc4;
|
pc = pasmvars->pc2;
|
||||||
instruct = pasmvars->instruct4;
|
instruct = pasmvars->instruct2;
|
||||||
cond = (instruct >> 18) & 15;
|
cond = (instruct >> 28) & 15;
|
||||||
|
if (cond == 0 && instruct != 0) cond = 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;
|
|
||||||
xflag = ((cond >> ((cflag << 1) | zflag)) & 1);
|
xflag = ((cond >> ((cflag << 1) | zflag)) & 1);
|
||||||
xflag ^= 1;
|
xflag ^= 1;
|
||||||
|
|
||||||
|
@ -381,15 +160,17 @@ void DebugPasmInstruction2(PasmVarsT *pasmvars)
|
||||||
xflag = 5;
|
xflag = 5;
|
||||||
else if (pasmvars->waitmode == WAIT_HUB)
|
else if (pasmvars->waitmode == WAIT_HUB)
|
||||||
xflag = 3;
|
xflag = 3;
|
||||||
|
else if (pasmvars->waitmode == WAIT_FLAG)
|
||||||
|
xflag = 8;
|
||||||
|
else if (pasmvars->waitmode == WAIT_CORDIC)
|
||||||
|
xflag = 9;
|
||||||
else
|
else
|
||||||
xflag = 7;
|
xflag = 10;
|
||||||
}
|
}
|
||||||
|
else if (pasmvars->phase == 0)
|
||||||
strcpy(opstr, GetOpname2(instruct, &zci_mask));
|
xflag = 7;
|
||||||
|
else if (pasmvars->skip_mask & 1)
|
||||||
zci &= zci_mask;
|
xflag = 11;
|
||||||
if (zci & 4) wzstr = " wz";
|
|
||||||
if (zci & 2) wcstr = " wc";
|
|
||||||
|
|
||||||
i = strlen(opstr);
|
i = strlen(opstr);
|
||||||
while (i < 7) opstr[i++] = ' ';
|
while (i < 7) opstr[i++] = ' ';
|
||||||
|
@ -403,31 +184,21 @@ void DebugPasmInstruction2(PasmVarsT *pasmvars)
|
||||||
strcpy(opstr, "nop ");
|
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)
|
if (pasmvars->printflag - 2 < xflag && xflag != 0)
|
||||||
{
|
{
|
||||||
pasmvars->printflag = 0;
|
pasmvars->printflag = 0;
|
||||||
return;
|
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,
|
int errflag;
|
||||||
instruct, xstr[xflag], condnames[cond], opstr, istr[dflag], dstaddr,
|
char debugstr[100];
|
||||||
istr[sflag], srcaddr, wzstr, wcstr);
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
+------------------------------------------------------------------------------------------------------------------------------+
|
+------------------------------------------------------------------------------------------------------------------------------+
|
||||||
|
|
34
pasmsim.c
34
pasmsim.c
|
@ -9,22 +9,21 @@
|
||||||
|
|
||||||
extern char *hubram;
|
extern char *hubram;
|
||||||
extern int32_t memsize;
|
extern int32_t memsize;
|
||||||
extern char lockstate[8];
|
extern char lockstate[16];
|
||||||
extern char lockalloc[8];
|
extern char lockalloc[16];
|
||||||
extern PasmVarsT PasmVars[8];
|
extern PasmVarsT PasmVars[8];
|
||||||
extern int32_t pasmspin;
|
extern int32_t pasmspin;
|
||||||
extern int32_t cycleaccurate;
|
extern int32_t cycleaccurate;
|
||||||
extern int32_t loopcount;
|
extern int32_t loopcount;
|
||||||
extern int32_t proptwo;
|
extern int32_t pin_val_a;
|
||||||
extern int32_t pin_val;
|
|
||||||
|
|
||||||
extern FILE *tracefile;
|
extern FILE *tracefile;
|
||||||
|
|
||||||
void PrintResults(int32_t zcri, int32_t zflag, int32_t cflag, int32_t result)
|
void PrintResults(int32_t zcri, int32_t zflag, int32_t cflag, int32_t result)
|
||||||
{
|
{
|
||||||
if (zcri & 8) printf(" Z=%d", zflag);
|
if (zcri & 8) fprintf(tracefile, " Z=%d", zflag);
|
||||||
if (zcri & 4) printf(" C=%d", cflag);
|
if (zcri & 4) fprintf(tracefile, " C=%d", cflag);
|
||||||
if (zcri & 2) printf(" R=%8.8x", result);
|
if (zcri & 2) fprintf(tracefile, " R=%8.8x", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int32_t parity(int32_t val)
|
static int32_t parity(int32_t val)
|
||||||
|
@ -42,7 +41,7 @@ static int32_t abs(int32_t val)
|
||||||
return val < 0 ? -val : 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 hubmode = mode & 1;
|
||||||
int32_t debugmode = mode & 2;
|
int32_t debugmode = mode & 2;
|
||||||
|
@ -54,17 +53,11 @@ int32_t CheckWaitFlag(PasmVarsT *pasmvars, int mode)
|
||||||
}
|
}
|
||||||
else if (hubmode)
|
else if (hubmode)
|
||||||
{
|
{
|
||||||
if (proptwo)
|
|
||||||
waitflag = (pasmvars->cogid - loopcount) & 7;
|
|
||||||
else
|
|
||||||
waitflag = ((pasmvars->cogid >> 1) - loopcount) & 3;
|
waitflag = ((pasmvars->cogid >> 1) - loopcount) & 3;
|
||||||
waitflag++;
|
waitflag++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (proptwo)
|
|
||||||
waitflag = 2;
|
|
||||||
else
|
|
||||||
waitflag = 1;
|
waitflag = 1;
|
||||||
}
|
}
|
||||||
if (!debugmode)
|
if (!debugmode)
|
||||||
|
@ -127,7 +120,7 @@ int32_t ExecutePasmInstruction(PasmVarsT *pasmvars)
|
||||||
// Check for a hub wait
|
// Check for a hub wait
|
||||||
if (cycleaccurate && !(instruct & 0xe0000000))
|
if (cycleaccurate && !(instruct & 0xe0000000))
|
||||||
{
|
{
|
||||||
if (CheckWaitFlag(pasmvars, 1)) return 0;
|
if (CheckWaitFlag1(pasmvars, 1)) return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Extract parameters from the instruction
|
// Extract parameters from the instruction
|
||||||
|
@ -143,7 +136,7 @@ int32_t ExecutePasmInstruction(PasmVarsT *pasmvars)
|
||||||
else if (srcaddr == 0x1f1)
|
else if (srcaddr == 0x1f1)
|
||||||
value2 = GetCnt();
|
value2 = GetCnt();
|
||||||
else if (srcaddr == 0x1f2)
|
else if (srcaddr == 0x1f2)
|
||||||
value2 = pin_val;
|
value2 = pin_val_a;
|
||||||
else
|
else
|
||||||
value2 = pasmvars->mem[srcaddr];
|
value2 = pasmvars->mem[srcaddr];
|
||||||
|
|
||||||
|
@ -570,7 +563,7 @@ int32_t ExecutePasmInstruction(PasmVarsT *pasmvars)
|
||||||
|
|
||||||
case 1: // cmpsx
|
case 1: // cmpsx
|
||||||
result = value1 - value2 - cflag;
|
result = value1 - value2 - cflag;
|
||||||
cflag = value1 < (value2 + cflag);
|
cflag = value1 < ((int64_t)value2 + cflag);
|
||||||
zflag = (result == 0) & zflag;
|
zflag = (result == 0) & zflag;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -620,7 +613,8 @@ int32_t ExecutePasmInstruction(PasmVarsT *pasmvars)
|
||||||
case 0: // cmpsub
|
case 0: // cmpsub
|
||||||
cflag = (((uint32_t)value1) >= ((uint32_t)value2));
|
cflag = (((uint32_t)value1) >= ((uint32_t)value2));
|
||||||
result = cflag ? value1 - value2 : value1;
|
result = cflag ? value1 - value2 : value1;
|
||||||
zflag = (result == 0);
|
//zflag = (result == 0) & cflag;
|
||||||
|
zflag = (value1 == value2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // djnz
|
case 1: // djnz
|
||||||
|
@ -645,7 +639,7 @@ int32_t ExecutePasmInstruction(PasmVarsT *pasmvars)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: // waitpeq - result, zflag and cflag not validated
|
case 4: // waitpeq - result, zflag and cflag not validated
|
||||||
result = (pin_val & value2) ^ value1;
|
result = (pin_val_a & value2) ^ value1;
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
//pasmvars->state = 6;
|
//pasmvars->state = 6;
|
||||||
|
@ -662,7 +656,7 @@ int32_t ExecutePasmInstruction(PasmVarsT *pasmvars)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 5: // waitpne - result, zflag and cflag not validated
|
case 5: // waitpne - result, zflag and cflag not validated
|
||||||
result = (pin_val & value2) ^ value1;
|
result = (pin_val_a & value2) ^ value1;
|
||||||
if (!result)
|
if (!result)
|
||||||
{
|
{
|
||||||
//pasmvars->state = 6;
|
//pasmvars->state = 6;
|
||||||
|
|
6569
pasmsim2.c
6569
pasmsim2.c
File diff suppressed because it is too large
Load Diff
|
@ -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 ;
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -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 ;
|
|
|
@ -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!
|
|
||||||
;
|
|
||||||
|
|
|
@ -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
|
|
||||||
;
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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.
|
|
||||||
+------------------------------------------------------------------
|
|
|
@ -1 +0,0 @@
|
||||||
Object "pfth.spin" Interface:
Program: 0 Longs
Variable: 0 Longs
|
|
Binary file not shown.
1606
pfth103_p2/pfth.spin
1606
pfth103_p2/pfth.spin
File diff suppressed because it is too large
Load Diff
|
@ -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
|
|
||||||
;
|
|
||||||
|
|
|
@ -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!
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
||||||
;
|
|
|
@ -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 / . ;
|
|
||||||
|
|
|
@ -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
|
|
|
@ -1,2 +0,0 @@
|
||||||
: TIME CNT@ 100000 BEGIN 1 - DUP 0 = UNTIL DROP CNT@ SWAP - 8000 / . ;
|
|
||||||
|
|
|
@ -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 ;
|
|
||||||
|
|
27
spindebug.c
27
spindebug.c
|
@ -7,14 +7,11 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef LINUX
|
|
||||||
#include "conion.h"
|
#include "conion.h"
|
||||||
#else
|
|
||||||
#include <conio.h>
|
|
||||||
#endif
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include "interp.h"
|
#include "interp.h"
|
||||||
#include "opcodes.h"
|
#include "opcodes.h"
|
||||||
|
#include "spinsim.h"
|
||||||
|
|
||||||
#define OP_NONE 0
|
#define OP_NONE 0
|
||||||
#define OP_UNSIGNED_OBJ_OFFSET 1
|
#define OP_UNSIGNED_OBJ_OFFSET 1
|
||||||
|
@ -106,7 +103,7 @@ void ProcessRet(void)
|
||||||
{
|
{
|
||||||
if (!symflag) return;
|
if (!symflag) return;
|
||||||
methodlev--;
|
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];
|
static char linebuf[200];
|
||||||
|
@ -135,7 +132,7 @@ void ProcessCall(int32_t subnum, int32_t mode)
|
||||||
methnum++;
|
methnum++;
|
||||||
if (methnum == subnum)
|
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);
|
fclose(infile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -152,7 +149,7 @@ void ProcessCall(int32_t subnum, int32_t mode)
|
||||||
methnum++;
|
methnum++;
|
||||||
if (methnum == subnum)
|
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);
|
fclose(infile);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -270,7 +267,7 @@ void PrintOp(SpinVarsT *spinvars)
|
||||||
int32_t opcode;
|
int32_t opcode;
|
||||||
int32_t opform = 0;
|
int32_t opform = 0;
|
||||||
char *opstr;
|
char *opstr;
|
||||||
int exop1, exop2;
|
//int exop1, exop2;
|
||||||
int32_t val;
|
int32_t val;
|
||||||
int32_t operand;
|
int32_t operand;
|
||||||
char *regop[] = {"ldreg", "streg", "exreg", "??reg"};
|
char *regop[] = {"ldreg", "streg", "exreg", "??reg"};
|
||||||
|
@ -281,8 +278,8 @@ void PrintOp(SpinVarsT *spinvars)
|
||||||
if (spinvars->state != 1) return;
|
if (spinvars->state != 1) return;
|
||||||
|
|
||||||
opcode = BYTE(pcurr);
|
opcode = BYTE(pcurr);
|
||||||
exop1 = GetOpIndex(opcode);
|
//exop1 = GetOpIndex(opcode);
|
||||||
exop2 = -1;
|
//exop2 = -1;
|
||||||
opstr = FindOpcode(pcurr, &opform, 0);
|
opstr = FindOpcode(pcurr, &opform, 0);
|
||||||
|
|
||||||
memset(bytestr, ' ', 40);
|
memset(bytestr, ' ', 40);
|
||||||
|
@ -418,7 +415,7 @@ void PrintOp(SpinVarsT *spinvars)
|
||||||
{
|
{
|
||||||
char *loadstr = "";
|
char *loadstr = "";
|
||||||
opcode = BYTE(pcurr);
|
opcode = BYTE(pcurr);
|
||||||
exop2 = GetExOpIndex(opcode);
|
//exop2 = GetExOpIndex(opcode);
|
||||||
if (opcode & 0x80)
|
if (opcode & 0x80)
|
||||||
{
|
{
|
||||||
loadstr = "load";
|
loadstr = "load";
|
||||||
|
@ -453,7 +450,7 @@ void PrintOp(SpinVarsT *spinvars)
|
||||||
pcurr++;
|
pcurr++;
|
||||||
}
|
}
|
||||||
bytestr[strlen(bytestr)] = ' ';
|
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);
|
//fprintf(tracefile, "%s [%2d,%2d] %s\n", bytestr, exop1, exop2, symstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -561,14 +558,14 @@ void PrintStats(void)
|
||||||
}
|
}
|
||||||
exname = optable[k].opname;
|
exname = optable[k].opname;
|
||||||
}
|
}
|
||||||
fprintf(tracefile, "%10d, %2.2x:%2.2x, %s:%s\n",
|
fprintf(tracefile, "%10d, %2.2x:%2.2x, %s:%s%s",
|
||||||
exopcount[opindex][j], i, exop, opname, exname);
|
exopcount[opindex][j], i, exop, opname, exname, NEW_LINE);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
37
spininterp.c
37
spininterp.c
|
@ -7,14 +7,11 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#ifdef LINUX
|
|
||||||
#include "conion.h"
|
#include "conion.h"
|
||||||
#else
|
|
||||||
#include <conio.h>
|
|
||||||
#endif
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <sys/timeb.h>
|
#include <sys/timeb.h>
|
||||||
#include "interp.h"
|
#include "interp.h"
|
||||||
|
#include "spinsim.h"
|
||||||
|
|
||||||
extern int32_t printflag;
|
extern int32_t printflag;
|
||||||
extern PasmVarsT PasmVars[8];
|
extern PasmVarsT PasmVars[8];
|
||||||
|
@ -22,11 +19,11 @@ extern char *hubram;
|
||||||
extern int32_t memsize;
|
extern int32_t memsize;
|
||||||
extern int32_t loopcount;
|
extern int32_t loopcount;
|
||||||
extern int32_t cycleaccurate;
|
extern int32_t cycleaccurate;
|
||||||
extern int32_t proptwo;
|
extern int32_t propmode;
|
||||||
extern int32_t pin_val;
|
extern int32_t pin_val_a;
|
||||||
|
|
||||||
extern char lockstate[8];
|
extern char lockstate[16];
|
||||||
extern char lockalloc[8];
|
extern char lockalloc[16];
|
||||||
|
|
||||||
extern FILE *tracefile;
|
extern FILE *tracefile;
|
||||||
|
|
||||||
|
@ -48,8 +45,12 @@ int32_t MAP_ADDR(int32_t addr)
|
||||||
}
|
}
|
||||||
else if (((uint32_t)addr) >= memsize)
|
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;
|
addr = memsize + 12;
|
||||||
|
#else
|
||||||
|
addr &= memsize - 1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
//fprintf(tracefile, "MAP_ADDR: %8.8x %8.8x\n", addr, ((uint32_t *)hubram)[addr>>2]);
|
//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 (cycleaccurate)
|
||||||
{
|
{
|
||||||
if (proptwo)
|
if (propmode >= 2)
|
||||||
cycles = loopcount;
|
cycles = loopcount;
|
||||||
else
|
else
|
||||||
cycles = loopcount * 4;
|
cycles = loopcount * 4;
|
||||||
|
@ -98,7 +99,7 @@ void UpdatePins(void)
|
||||||
mask |= mask1;
|
mask |= mask1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pin_val = (~mask) | val;
|
pin_val_a = (~mask) | val;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t GetSignedOffset(int32_t *ppcurr)
|
int32_t GetSignedOffset(int32_t *ppcurr)
|
||||||
|
@ -398,7 +399,7 @@ void ExecuteLowerOp(SpinVarsT *spinvars)
|
||||||
pcurr = 0xfffc;
|
pcurr = 0xfffc;
|
||||||
}
|
}
|
||||||
else
|
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)
|
else if (opcode >= 0x16 && opcode <= 0x23)
|
||||||
{
|
{
|
||||||
|
@ -729,7 +730,7 @@ void ExecuteLowerOp(SpinVarsT *spinvars)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(tracefile, "NOT PROCESSED\n");
|
fprintf(tracefile, "NOT PROCESSED%s", NEW_LINE);
|
||||||
}
|
}
|
||||||
spinvars->pcurr = pcurr;
|
spinvars->pcurr = pcurr;
|
||||||
spinvars->dcurr = dcurr;
|
spinvars->dcurr = dcurr;
|
||||||
|
@ -787,7 +788,7 @@ void ExecuteRegisterOp(SpinVarsT *spinvars, int32_t operand, int32_t msb, int32_
|
||||||
if (operand == 0x11) // cnt = $1f1
|
if (operand == 0x11) // cnt = $1f1
|
||||||
parm1 = GetCnt();
|
parm1 = GetCnt();
|
||||||
else if (operand == 0x12) // ina = $1f2
|
else if (operand == 0x12) // ina = $1f2
|
||||||
parm1 = pin_val;
|
parm1 = pin_val_a;
|
||||||
else
|
else
|
||||||
parm1 = reg[operand];
|
parm1 = reg[operand];
|
||||||
parm1 = (parm1 >> lsb) & mask;
|
parm1 = (parm1 >> lsb) & mask;
|
||||||
|
@ -804,7 +805,7 @@ void ExecuteRegisterOp(SpinVarsT *spinvars, int32_t operand, int32_t msb, int32_
|
||||||
if (operand == 0x11) // cnt = $1f1
|
if (operand == 0x11) // cnt = $1f1
|
||||||
parm1 = GetCnt();
|
parm1 = GetCnt();
|
||||||
else if (operand == 0x12) // ina = $1f2
|
else if (operand == 0x12) // ina = $1f2
|
||||||
parm1 = pin_val;
|
parm1 = pin_val_a;
|
||||||
else
|
else
|
||||||
parm1 = reg[operand];
|
parm1 = reg[operand];
|
||||||
}
|
}
|
||||||
|
@ -825,7 +826,7 @@ void ExecuteRegisterOp(SpinVarsT *spinvars, int32_t operand, int32_t msb, int32_
|
||||||
dcurr = spinvars->dcurr;
|
dcurr = spinvars->dcurr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fprintf(tracefile, "Undefined register operation\n");
|
fprintf(tracefile, "Undefined register operation%s", NEW_LINE);
|
||||||
|
|
||||||
spinvars->pcurr = pcurr;
|
spinvars->pcurr = pcurr;
|
||||||
spinvars->dcurr = dcurr;
|
spinvars->dcurr = dcurr;
|
||||||
|
@ -1040,7 +1041,7 @@ int32_t ExecuteExtraOp(SpinVarsT *spinvars, int32_t opcode, int32_t parm1, int32
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf(tracefile, "NOT IMPLEMENTED\n");
|
fprintf(tracefile, "NOT IMPLEMENTED%s", NEW_LINE);
|
||||||
parm2 = 0;
|
parm2 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1264,7 +1265,7 @@ int32_t ExecuteMathOp(SpinVarsT *spinvars, int32_t opcode, int32_t parm1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fprintf(tracefile, "NOT PROCESSED\n");
|
fprintf(tracefile, "NOT PROCESSED%s", NEW_LINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push the result back to the stack
|
// Push the result back to the stack
|
||||||
|
|
316
spinsim.c
316
spinsim.c
|
@ -1,34 +1,23 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
' Author: Dave Hein
|
' Author: Dave Hein
|
||||||
' Version 0.75
|
' Version 0.97
|
||||||
' Copyright (c) 2010 - 2014
|
' Copyright (c) 2010 - 2017
|
||||||
' See end of file for terms of use.
|
' See end of file for terms of use.
|
||||||
'******************************************************************************/
|
'******************************************************************************/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#ifdef LINUX
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
#include "spinsim.h"
|
||||||
#include "conion.h"
|
#include "conion.h"
|
||||||
#else
|
|
||||||
#include <conio.h>
|
|
||||||
#include <direct.h>
|
|
||||||
#endif
|
|
||||||
#include "interp.h"
|
#include "interp.h"
|
||||||
#include "rom.h"
|
#include "rom.h"
|
||||||
#include "spindebug.h"
|
#include "spindebug.h"
|
||||||
#include "eeprom.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_PUTCH 1
|
||||||
#define SYS_CON_GETCH 2
|
#define SYS_CON_GETCH 2
|
||||||
#define SYS_FILE_OPEN 3
|
#define SYS_FILE_OPEN 3
|
||||||
|
@ -57,8 +46,8 @@ char *extram[4];
|
||||||
int32_t extmemsize[4];
|
int32_t extmemsize[4];
|
||||||
uint32_t extmembase[4];
|
uint32_t extmembase[4];
|
||||||
int32_t extmemnum = 0;
|
int32_t extmemnum = 0;
|
||||||
char lockstate[8];
|
char lockstate[16];
|
||||||
char lockalloc[8];
|
char lockalloc[16];
|
||||||
|
|
||||||
char objname[100][20];
|
char objname[100][20];
|
||||||
int32_t methodnum[100];
|
int32_t methodnum[100];
|
||||||
|
@ -71,19 +60,26 @@ int32_t profile = 0;
|
||||||
int32_t memsize = 64;
|
int32_t memsize = 64;
|
||||||
int32_t cycleaccurate = 0;
|
int32_t cycleaccurate = 0;
|
||||||
int32_t loopcount = 0;
|
int32_t loopcount = 0;
|
||||||
int32_t proptwo = 0;
|
int32_t propmode = 0;
|
||||||
int32_t baudrate = 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 gdbmode = 0;
|
||||||
int32_t eeprom = 0;
|
int32_t eeprom = 0;
|
||||||
int32_t debugmode = 0;
|
int32_t debugmode = 0;
|
||||||
int32_t printbreak = 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 *logfile = NULL;
|
||||||
FILE *tracefile = NULL;
|
FILE *tracefile = NULL;
|
||||||
FILE *cmdfile = NULL;
|
FILE *cmdfile = NULL;
|
||||||
|
|
||||||
PasmVarsT PasmVars[8];
|
PasmVarsT PasmVars[16];
|
||||||
|
|
||||||
void PrintOp(SpinVarsT *spinvars);
|
void PrintOp(SpinVarsT *spinvars);
|
||||||
void ExecuteOp(SpinVarsT *spinvars);
|
void ExecuteOp(SpinVarsT *spinvars);
|
||||||
|
@ -91,17 +87,19 @@ char *FindChar(char *str, int32_t val);
|
||||||
void Debug(void);
|
void Debug(void);
|
||||||
int32_t RunProp(int32_t maxloops);
|
int32_t RunProp(int32_t maxloops);
|
||||||
void gdb(void);
|
void gdb(void);
|
||||||
|
void UpdateRWlongFlags(void);
|
||||||
|
|
||||||
void spinsim_exit(int32_t exitcode)
|
void spinsim_exit(int32_t exitcode)
|
||||||
{
|
{
|
||||||
// dbetz: not defined for Windows and a nop for anything else
|
#ifndef __MINGW32__
|
||||||
// restore_console_io();
|
restore_console_io();
|
||||||
|
#endif
|
||||||
exit(exitcode);
|
exit(exitcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void usage(void)
|
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, "usage: spinsim [options] file\n");
|
||||||
fprintf(stderr, "The options are as follows:\n");
|
fprintf(stderr, "The options are as follows:\n");
|
||||||
fprintf(stderr, " -v# Set verbosity level\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, " -P Profile Spin opcode usage\n");
|
||||||
fprintf(stderr, " -m# Set the hub memory size to # K-bytes\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, " -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, " -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, " -gdb Operate as a GDB target over stdin/stdout\n");
|
||||||
fprintf(stderr, " -L <filename> Log GDB remote comm to <filename>\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, " -x# Set the external memory size to # K-bytes\n");
|
||||||
fprintf(stderr, " -e Use eeprom.dat\n");
|
fprintf(stderr, " -e Use eeprom.dat\n");
|
||||||
fprintf(stderr, " -d Use debugger\n");
|
fprintf(stderr, " -d Use debugger\n");
|
||||||
|
fprintf(stderr, " -pst Use PST mode\n");
|
||||||
spinsim_exit(1);
|
spinsim_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,6 +128,7 @@ void putchx(int32_t val)
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
int32_t getchx(void)
|
int32_t getchx(void)
|
||||||
{
|
{
|
||||||
uint8_t val = 0;
|
uint8_t val = 0;
|
||||||
|
@ -137,6 +137,7 @@ int32_t getchx(void)
|
||||||
if (val == 10) val = 13;
|
if (val == 10) val = 13;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
char *FindExtMem(uint32_t addr, int32_t num)
|
char *FindExtMem(uint32_t addr, int32_t num)
|
||||||
{
|
{
|
||||||
|
@ -269,7 +270,7 @@ void CheckCommand(void)
|
||||||
pdirent = readdir(pdir);
|
pdirent = readdir(pdir);
|
||||||
if (pdirent)
|
if (pdirent)
|
||||||
{
|
{
|
||||||
#ifdef LINUX
|
#if 1
|
||||||
FILE *infile;
|
FILE *infile;
|
||||||
int32_t d_size = 0;
|
int32_t d_size = 0;
|
||||||
int32_t d_attr = 0;
|
int32_t d_attr = 0;
|
||||||
|
@ -321,7 +322,6 @@ void CheckCommand(void)
|
||||||
{
|
{
|
||||||
char *path = (char *)&BYTE(parm);
|
char *path = (char *)&BYTE(parm);
|
||||||
char fullpath[200];
|
char fullpath[200];
|
||||||
char *ptr;
|
|
||||||
if (path[0] == '/')
|
if (path[0] == '/')
|
||||||
{
|
{
|
||||||
strcpy(fullpath, rootdir);
|
strcpy(fullpath, rootdir);
|
||||||
|
@ -330,8 +330,8 @@ void CheckCommand(void)
|
||||||
else
|
else
|
||||||
strcpy(fullpath, path);
|
strcpy(fullpath, path);
|
||||||
|
|
||||||
ptr = fullpath;
|
#if 0
|
||||||
#ifndef LINUX
|
char *ptr = fullpath;
|
||||||
while (*ptr)
|
while (*ptr)
|
||||||
{
|
{
|
||||||
if (*ptr == '/') *ptr = 0x5c;
|
if (*ptr == '/') *ptr = 0x5c;
|
||||||
|
@ -343,20 +343,15 @@ void CheckCommand(void)
|
||||||
}
|
}
|
||||||
else if (command == SYS_FILE_GETCWD)
|
else if (command == SYS_FILE_GETCWD)
|
||||||
{
|
{
|
||||||
char *ptr;
|
|
||||||
char *str = (char *)&BYTE(LONG(parm));
|
char *str = (char *)&BYTE(LONG(parm));
|
||||||
int32_t num = LONG(parm+4);
|
int32_t num = LONG(parm+4);
|
||||||
ptr = getcwd(str, num);
|
getcwd(str, num);
|
||||||
LONG(SYS_PARM) = LONG(parm);
|
LONG(SYS_PARM) = LONG(parm);
|
||||||
}
|
}
|
||||||
else if (command == SYS_FILE_MKDIR)
|
else if (command == SYS_FILE_MKDIR)
|
||||||
{
|
{
|
||||||
//char *fname = (char *)&BYTE(parm);
|
|
||||||
#ifdef LINUX
|
|
||||||
#if 0
|
#if 0
|
||||||
LONG(SYS_PARM) = mkdir(fname, S_IRWXU | S_IRWXG | S_IRWXO);
|
char *fname = (char *)&BYTE(parm);
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
LONG(SYS_PARM) = mkdir(fname);
|
LONG(SYS_PARM) = mkdir(fname);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -372,7 +367,7 @@ void CheckCommand(void)
|
||||||
if (!pdirent) break;
|
if (!pdirent) break;
|
||||||
if (strcmp(pdirent->d_name, fname) == 0)
|
if (strcmp(pdirent->d_name, fname) == 0)
|
||||||
{
|
{
|
||||||
#ifdef LINUX
|
#if 1
|
||||||
#if 0
|
#if 0
|
||||||
int32_t d_type = pdirent->d_type;
|
int32_t d_type = pdirent->d_type;
|
||||||
attrib = 0;
|
attrib = 0;
|
||||||
|
@ -461,141 +456,130 @@ void CheckCommand(void)
|
||||||
WORD(SYS_COMMAND) = 0;
|
WORD(SYS_COMMAND) = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CheckSerialIn(void)
|
void SerialInit(SerialT *serial, int pin_num, int bitcycles, int mode)
|
||||||
{
|
{
|
||||||
static int state = 0;
|
serial->flag = 0;
|
||||||
static int count = 0;
|
serial->state = 0;
|
||||||
static int val;
|
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();
|
serial->value |= 0x300;
|
||||||
if (val == 0x1d) return 1;
|
serial->count = serial->bitcycles;
|
||||||
val |= 0x300;
|
portval = (portval & ~(1 << pin_num)) | (flipbit << pin_num);
|
||||||
if (proptwo)
|
serial->state = 1;
|
||||||
count = 80000000 / baudrate;
|
//printf("portval = %8.8x\n", portval);
|
||||||
else
|
|
||||||
{
|
|
||||||
count = LONG(0) / baudrate;
|
|
||||||
count >>= 2;
|
|
||||||
}
|
|
||||||
//if (!proptwo) count >>= 2;
|
|
||||||
pin_val &= 0x7fffffff;
|
|
||||||
state = 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
pin_val = (pin_val & 0x7fffffff) | ((val & 1) << 31);
|
bitval = (serial->value & 1) ^ flipbit;
|
||||||
val >>= 1;
|
portval = (portval & ~(1 << pin_num)) | (bitval << pin_num);
|
||||||
#if 0
|
serial->value >>= 1;
|
||||||
count = LONG(0) / baudrate;
|
serial->count = serial->bitcycles;
|
||||||
if (!proptwo) count >>= 2;
|
//printf("portval = %8.8x\n", portval);
|
||||||
#endif
|
}
|
||||||
if (proptwo)
|
}
|
||||||
count = 80000000 / baudrate;
|
return portval;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CheckSerialIn(SerialT *serial)
|
||||||
|
{
|
||||||
|
int value;
|
||||||
|
|
||||||
|
if (propmode == 2)
|
||||||
|
pin_val_b = SerialSend(serial, pin_val_b);
|
||||||
else
|
else
|
||||||
|
pin_val_a = SerialSend(serial, pin_val_a);
|
||||||
|
if (!serial->flag && kbhit1())
|
||||||
{
|
{
|
||||||
count = LONG(0) / baudrate;
|
value = getch();
|
||||||
count >>= 2;
|
//printf("CheckSerialIn: value = %x\n", value);
|
||||||
}
|
if (value == 0x1d) return 1;
|
||||||
}
|
serial->flag = 1;
|
||||||
|
serial->value = value;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckSerialOut(void)
|
void SerialReceive(SerialT *serial, int portval)
|
||||||
{
|
{
|
||||||
int txbit = 0;
|
int bitval = ((portval >> serial->pin_num) & 1) ^ (serial->mode & 1);
|
||||||
static int val;
|
|
||||||
static int state = -2;
|
|
||||||
static int count;
|
|
||||||
//static int txbit0 = 0;
|
|
||||||
|
|
||||||
txbit = (pin_val >> 30) & 1;
|
if (serial->state == 0)
|
||||||
|
|
||||||
//if (txbit != txbit0) fprintf(stderr, "txbit = %d, loopcount = %d\n", txbit, loopcount);
|
|
||||||
//txbit0 = txbit;
|
|
||||||
|
|
||||||
|
|
||||||
if (state == -2)
|
|
||||||
{
|
{
|
||||||
if (txbit)
|
if (bitval)
|
||||||
{
|
serial->state = 1;
|
||||||
state = -1;
|
|
||||||
//fprintf(stderr, "Start Serial\n");
|
|
||||||
}
|
}
|
||||||
}
|
else if (serial->state == 1)
|
||||||
else if (state == -1)
|
|
||||||
{
|
{
|
||||||
if (!txbit)
|
if (!bitval)
|
||||||
{
|
{
|
||||||
val = 0;
|
serial->value = 0;
|
||||||
state = 0;
|
serial->state = 2;
|
||||||
#if 0
|
serial->count = serial->bitcycles;
|
||||||
count = LONG(0) / baudrate;
|
serial->count += serial->count >> 1;
|
||||||
if (!proptwo) count >>= 2;
|
|
||||||
#endif
|
|
||||||
if (proptwo)
|
|
||||||
count = 80000000 / baudrate;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
count = LONG(0) / baudrate;
|
|
||||||
count >>= 2;
|
|
||||||
}
|
|
||||||
count += count >> 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (--count <= 0)
|
if (--serial->count <= 0)
|
||||||
{
|
{
|
||||||
if (state > 7)
|
if (serial->state > 9)
|
||||||
{
|
{
|
||||||
state = -1;
|
serial->flag = 1;
|
||||||
#if 1
|
serial->state = 1;
|
||||||
if (val == 13)
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
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);
|
putchx(10);
|
||||||
else
|
else
|
||||||
putchx(val);
|
putchx(serial->value);
|
||||||
#else
|
|
||||||
printf("<%2.2x>\n", val);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
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++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintStack(SpinVarsT *spinvars)
|
void PrintStack(SpinVarsT *spinvars)
|
||||||
{
|
{
|
||||||
int32_t dcurr = spinvars->dcurr;
|
int32_t dcurr = spinvars->dcurr;
|
||||||
printf("PrintStack: %4.4x %8.8x %8.8x %8.8x\n",
|
printf("PrintStack: %4.4x %8.8x %8.8x %8.8x%s",
|
||||||
dcurr, LONG(dcurr-4), LONG(dcurr-8), LONG(dcurr-12));
|
dcurr, LONG(dcurr-4), LONG(dcurr-8), LONG(dcurr-12), NEW_LINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *bootfile;
|
char *bootfile;
|
||||||
|
@ -606,10 +590,11 @@ void RebootProp(void)
|
||||||
int32_t dbase;
|
int32_t dbase;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
FILE *infile;
|
FILE *infile;
|
||||||
|
int32_t bitcycles;
|
||||||
|
|
||||||
if (!proptwo) memset(hubram, 0, 32768);
|
if (!propmode) memset(hubram, 0, 32768);
|
||||||
memset(lockstate, 0, 8);
|
memset(lockstate, 0, 16);
|
||||||
memset(lockalloc, 0, 8);
|
memset(lockalloc, 0, 16);
|
||||||
|
|
||||||
chdir(rootdir);
|
chdir(rootdir);
|
||||||
|
|
||||||
|
@ -625,12 +610,12 @@ void RebootProp(void)
|
||||||
spinsim_exit(1);
|
spinsim_exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
i = fread(hubram, 1, 32768, infile);
|
i = fread(hubram, 1, memsize, infile);
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy in the ROM contents
|
// Copy in the ROM contents
|
||||||
if (!proptwo)
|
if (!propmode)
|
||||||
{
|
{
|
||||||
memcpy(hubram + 32768, romdata, 32768);
|
memcpy(hubram + 32768, romdata, 32768);
|
||||||
dbase = WORD(10);
|
dbase = WORD(10);
|
||||||
|
@ -643,12 +628,15 @@ void RebootProp(void)
|
||||||
WORD(SYS_LOCKNUM) = 1;
|
WORD(SYS_LOCKNUM) = 1;
|
||||||
lockalloc[0] = 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 (pasmspin)
|
||||||
{
|
{
|
||||||
if (proptwo)
|
if (propmode == 2)
|
||||||
StartPasmCog2(&PasmVars[0], 0, 0x0e00, 0);
|
{
|
||||||
|
//StartPasmCog2(&PasmVars[0], 0, 0x0e00, 0);
|
||||||
|
StartPasmCog2(&PasmVars[0], 0, 0x0000, 0, 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
StartPasmCog(&PasmVars[0], 0x0004, 0xf004, 0);
|
StartPasmCog(&PasmVars[0], 0x0004, 0xf004, 0);
|
||||||
}
|
}
|
||||||
|
@ -677,6 +665,16 @@ void RebootProp(void)
|
||||||
methodlev = 1;
|
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;
|
//LONG(SYS_DEBUG) = printflag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -687,7 +685,8 @@ int step_chip(void)
|
||||||
int runflag = 0;
|
int runflag = 0;
|
||||||
int breakflag = 0;
|
int breakflag = 0;
|
||||||
SpinVarsT *spinvars;
|
SpinVarsT *spinvars;
|
||||||
for (i = 0; i < 8; i++)
|
if (propmode == 2) UpdateRWlongFlags();
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
{
|
{
|
||||||
state = PasmVars[i].state;
|
state = PasmVars[i].state;
|
||||||
PasmVars[i].printflag = (LONG(SYS_DEBUG) >> (i*4)) & 15;
|
PasmVars[i].printflag = (LONG(SYS_DEBUG) >> (i*4)) & 15;
|
||||||
|
@ -695,22 +694,22 @@ int step_chip(void)
|
||||||
{
|
{
|
||||||
if (PasmVars[i].printflag && state == 5)
|
if (PasmVars[i].printflag && state == 5)
|
||||||
{
|
{
|
||||||
if (!proptwo)
|
if (!propmode)
|
||||||
{
|
{
|
||||||
fprintf(tracefile, "Cog %d: ", i);
|
fprintf(tracefile, "Cog %d: ", i);
|
||||||
DebugPasmInstruction(&PasmVars[i]);
|
DebugPasmInstruction(&PasmVars[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (proptwo)
|
if (propmode == 2)
|
||||||
{
|
{
|
||||||
breakflag = ExecutePasmInstruction2(&PasmVars[i]);
|
breakflag = ExecutePasmInstruction2(&PasmVars[i]);
|
||||||
if (PasmVars[i].printflag && state == 5)
|
if (PasmVars[i].printflag && state == 5)
|
||||||
fprintf(tracefile, "\n");
|
fprintf(tracefile, NEW_LINE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ExecutePasmInstruction(&PasmVars[i]);
|
ExecutePasmInstruction(&PasmVars[i]);
|
||||||
if (PasmVars[i].printflag && state == 5) printf("\n");
|
if (PasmVars[i].printflag && state == 5) fprintf(tracefile, NEW_LINE);
|
||||||
}
|
}
|
||||||
if (!breakflag &&
|
if (!breakflag &&
|
||||||
!(printbreak && PasmVars[i].printflag && state == 5))
|
!(printbreak && PasmVars[i].printflag && state == 5))
|
||||||
|
@ -736,13 +735,12 @@ int step_chip(void)
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *ptr;
|
|
||||||
char *fname = 0;
|
char *fname = 0;
|
||||||
int32_t i;
|
int32_t i;
|
||||||
int32_t maxloops = -1;
|
int32_t maxloops = -1;
|
||||||
|
|
||||||
tracefile = stdout;
|
tracefile = stdout;
|
||||||
ptr = getcwd(rootdir, 100);
|
getcwd(rootdir, 100);
|
||||||
|
|
||||||
for (i = 1; i < argc; i++)
|
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]);
|
fprintf(stderr, "Unable to open trace file %s.\n", argv[i]);
|
||||||
spinsim_exit(1);
|
spinsim_exit(1);
|
||||||
}
|
}
|
||||||
} else if (strcmp(argv[i], "-t") == 0)
|
}
|
||||||
|
else if (strncmp(argv[i], "-t", 2) == 0)
|
||||||
{
|
{
|
||||||
proptwo = 1;
|
propmode = 2;
|
||||||
pasmspin = 1;
|
pasmspin = 1;
|
||||||
memsize = 256;
|
memsize = 512;
|
||||||
cycleaccurate = 1;
|
cycleaccurate = 1;
|
||||||
|
fjmpflag = argv[i][2] & 1;
|
||||||
|
nohubslots = (argv[i][2] & 2) >> 1;
|
||||||
}
|
}
|
||||||
else if (strcmp(argv[i], "-p") == 0)
|
else if (strcmp(argv[i], "-p") == 0)
|
||||||
{
|
{
|
||||||
pasmspin = 1;
|
pasmspin = 1;
|
||||||
cycleaccurate = 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)
|
else if (strcmp(argv[i], "-s") == 0)
|
||||||
symflag = 1;
|
symflag = 1;
|
||||||
else if (strcmp(argv[i], "-P") == 0)
|
else if (strcmp(argv[i], "-P") == 0)
|
||||||
|
@ -891,15 +896,18 @@ int main(int argc, char **argv)
|
||||||
if (!fname && !gdbmode && !eeprom) usage();
|
if (!fname && !gdbmode && !eeprom) usage();
|
||||||
|
|
||||||
RebootProp();
|
RebootProp();
|
||||||
// dbetz: not defined for Windows and a nop for anything else
|
#ifndef __MINGW32__
|
||||||
// initialize_console_io();
|
initialize_console_io();
|
||||||
|
#endif
|
||||||
if (gdbmode)
|
if (gdbmode)
|
||||||
gdb();
|
gdb();
|
||||||
else if (debugmode)
|
else if (debugmode)
|
||||||
Debug();
|
Debug();
|
||||||
else
|
else
|
||||||
RunProp(maxloops);
|
RunProp(maxloops);
|
||||||
// restore_console_io();
|
#ifndef __MINGW32__
|
||||||
|
restore_console_io();
|
||||||
|
#endif
|
||||||
if (eeprom) EEPromClose();
|
if (eeprom) EEPromClose();
|
||||||
if (profile) PrintStats();
|
if (profile) PrintStats();
|
||||||
return 0;
|
return 0;
|
||||||
|
|
14
spinsim.h
14
spinsim.h
|
@ -1,13 +1,21 @@
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
int step_chip(void);
|
int step_chip(void);
|
||||||
int CheckSerialIn(void);
|
//int CheckSerialIn(SerialT *serial);
|
||||||
void CheckCommand(void);
|
void CheckCommand(void);
|
||||||
void putchx(int32_t val);
|
void putchx(int32_t val);
|
||||||
void CheckSerialOut(void);
|
//void CheckSerialOut(SerialT *serial);
|
||||||
void spinsim_exit(int32_t exitcode);
|
void spinsim_exit(int32_t exitcode);
|
||||||
|
|
||||||
#define WAIT_CNT 01
|
#define WAIT_CNT 01
|
||||||
#define WAIT_MULT 02
|
#define WAIT_CORDIC 02
|
||||||
#define WAIT_PIN 03
|
#define WAIT_PIN 03
|
||||||
#define WAIT_HUB 16
|
#define WAIT_HUB 16
|
||||||
#define WAIT_CACHE 17
|
#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
18504
verify/testhdw.txt
Executable file
File diff suppressed because it is too large
Load Diff
16448
verify/testhdw1.txt
Executable file
16448
verify/testhdw1.txt
Executable file
File diff suppressed because it is too large
Load Diff
1216
verify/testhdwa.txt
Executable file
1216
verify/testhdwa.txt
Executable file
File diff suppressed because it is too large
Load Diff
2448
verify/testhdwd.txt
Executable file
2448
verify/testhdwd.txt
Executable file
File diff suppressed because it is too large
Load Diff
3221
verify/testhdwq.txt
Executable file
3221
verify/testhdwq.txt
Executable file
File diff suppressed because it is too large
Load Diff
BIN
verify/testops.bin
Executable file
BIN
verify/testops.bin
Executable file
Binary file not shown.
130
verify/testops.c
Executable file
130
verify/testops.c
Executable 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
BIN
verify/testops1.bin
Executable file
Binary file not shown.
127
verify/testops1.c
Executable file
127
verify/testops1.c
Executable 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
BIN
verify/testopsa.bin
Executable file
Binary file not shown.
167
verify/testopsa.c
Executable file
167
verify/testopsa.c
Executable 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
BIN
verify/testopsd.bin
Executable file
Binary file not shown.
124
verify/testopsd.c
Executable file
124
verify/testopsd.c
Executable 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
BIN
verify/testopsq.bin
Executable file
Binary file not shown.
171
verify/testopsq.c
Executable file
171
verify/testopsq.c
Executable 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");
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user