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);
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -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");
|
||||||
|
}
|
Binary file not shown.
|
@ -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");
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
|
@ -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");
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
|
@ -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");
|
||||||
|
}
|
||||||
|
|
Binary file not shown.
|
@ -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