P1 Spin Interpreter for P2
Cluso99
Posts: 18,069
I started from scratch again in converting my faster P1 spin interpreter to run on P2.
What i am after is to run P1 compiled spin on the P2. There will be some things it cannot do such as videeo (waitvid) and some of the timer hardware differences, but overall most code should work.
So, let’s look at the makeup of hub code for the P1 object... (P1 spin on P2 will only use the bottom 64KB of HUB)
$0000(4) clockfreq - initially jump over spin code then updated to clockfreq
$0004(1) clockmode - not used
$0005(1) checksum - not used
$0006(...) spin code - same
* My P2 interpreter uses COG & LUT for extra speed
* PTRA & PTRB are used for pcurr and dcurr respectively
Currently how this works is P1 compiled spin bytecode is copied into the P2 source as bytes with the first 4 bytes replaced with a jump over the bytecode. The bottom 64KB will be reserved for P1 spin bytecode and interpreter.
What i am after is to run P1 compiled spin on the P2. There will be some things it cannot do such as videeo (waitvid) and some of the timer hardware differences, but overall most code should work.
So, let’s look at the makeup of hub code for the P1 object... (P1 spin on P2 will only use the bottom 64KB of HUB)
$0000(4) clockfreq - initially jump over spin code then updated to clockfreq
$0004(1) clockmode - not used
$0005(1) checksum - not used
$0006(...) spin code - same
* My P2 interpreter uses COG & LUT for extra speed
* PTRA & PTRB are used for pcurr and dcurr respectively
Currently how this works is P1 compiled spin bytecode is copied into the P2 source as bytes with the first 4 bytes replaced with a jump over the bytecode. The bottom 64KB will be reserved for P1 spin bytecode and interpreter.
Comments
How were you going to handle PASM? Were you going to translate that from P1 to P2 in your compiler? And which compiler were you going to use?
Just out of curiousity, are you doing this for fun (totally understandable) and/or "because it's there", or do you have a specific use case in mind? If the latter, have you looked at fastspin? It can already compile most P1 Spin programs (the Spin part, that is; I don't try to translate PASM). If we combined that with a P1 PASM to P2 PASM translator would that do everything you want?
Regards,
Eric
2. Because i can run P1 spin code
I am using pre-compiled P1 binaries. I’ve converted my P1 PASM (my Interpreter) to P2. So I am not using any new compilers for the P1 spin.
However, maybe I should take a look at fastspin. Might be fun too
Ah, so your pre-compiled P1 binaries do not have any PASM baked into their DAT sections? Then I guess you should be good to go, once the interpreter is up. Have fun!
(And if you do want to try out fastspin on your Spin code, there are options to compile the binaries to run at different base addresses, so that one program can load another. IIRC one of your use-cases was a small operating system that loads programs from disk, so that might be a way to achieve that.)
I can (and have) put debug code into the interpreter to output (using the ROM Monitor) to display variables etc at certain points in the interpreter.
It’s amazing how much code space i saved when converting pasm from p1 to p2. Those ptra++ and —ptrb save quite a bit on their own
And yes, another reason is for my OS on SD
I translated the DIRx/OUTx/INx registers and implemented PAR and CNT. The pin registers work for both ports A and B.
I rewrote FILL/MOVE bytecodes using REP.
I rewrote the maths routines to use skipf. Wow, what a boost this will be, and much less code too. Its not tested yet though.
BTW we have an extra bytecode available since we don’t have WAITVID, and $3C was unused too.
I looked at XBYTE but not for me just yet anyway.
Might be worth taking a look at openspin with a view to changing the DIR/OUT/IN register addresses, and removing CTR/FRQ/PHS/VID registers and WAITVID to output compiled spin1 for P2. Probably a minor change to highlight errors. I wonder if P2ASM could co-exist with OpenSpin?
Actually I am debugging it with calls inserted into the spin interpreter to output serial messages using the ROM Monitor. Some of those messages pause for serial entry (just a cr) and I also call the monitor too, and return.
I haven't played with the inbuilt debugger on the P2 yet.
I keep finding new instruction toys in P2
I used skip in the ROM SD so I have coded the maths ops in the interpreter to use these extensively.
write down some simple example how to use Monitor/Debugger.
Mike
Have a look at this thread
https://forums.parallax.com/discussion/169842/fun-with-the-p2-rom#latest
They are currently untested. If you see any holes/bugs please comment
Just realised there is an error in some skipf values. The top 1's need to be 0's once all required instructions are skipped
Here are the VAR bytecodes and the table
Note the math_bin & math_un code is not currently in the code and the table
I think this is very cool what you are doing there, sure we still have the problem with PASM1/PASM2 but you are opening up a lot of OBEX P1 stuff for the P2.
I really like fastspin, but it compiles to large binaries, and - yes - I am sure that 512kb will be small soon, needing RAM for HDMI or whatever.
Having a SPIN1 byte code interpreter on the P2 would be nice. @Chip has to come up with Spin2 yet (and hopefully follow @ersmith and his SPIN2 additions)
You said that you will implement port B, as far as I follow the forum, what about the memory size?
I guess 64kb will work with the current byte codes, but - hmm - basically spin bytecodes are relocatable so do you plan/think about/have a Idea for using more then 64kb?
just curious,
Mike
And yes, Ports A & B are supported
Saving a huge amount of clocks as the decode table removes most requirements for testing bytecode bits. This also saves instructions. Same goes for conditional instruction execution.
Also used some of the new instructions like SIGNX, ZEROX, and others.
I’ve been optimising for speed at some instruction code expense.
Been testing out some of the basics. Mathops all seem working fine. Basic repeats working. Register translation working. Waitcnt working. Some of the assignments are working, some not. Maths assignments not done yet - should just be a matter of calling the mathop routine.
It’s interesting to debug. I am displaying the registers, stack, and upcoming bytecode at each bytecode execution.
Yet to do COGINIT tho.
Nice, Cluso99!
How much is left to do Cluso, and what P1 Spin doesn't/can't work beyond WAITVID and the counter stuff in this P1 SPIN interpreter for P2?
Done & To do...
* Bytecodes $00-$3F have been coded. Most opcodes working, some have only rudimentary testing, and a few have not been tested at all. Most coding is done tho'.
- CALL, JMP, jump conditionals, DJNZ work.
- Repeat loops (no parameters) work, but Repeat with parameters (from, to, step) do not.
- COGINIT not coded
- LOCKs coded but untested
- WAITCNT works but actual time not validated
- WAITPEQ & WAITPNE coded but not validated
* Bytecodes VAR $40-$7F types PUSH & POP working, Mathop (Assign-Using) need matho as subroutine, PUSH# coded but not tested
* Bytecodes MEM $80-$DF types PUSH & POP working, Mathop (Assign-Using) need matho as subroutine, PUSH# coded but not tested
* Bytecodes MATHOPS $E0-$FF working, but the mathops being called as a routine needs doing ie the calls from other bytecodes.
* Tricks with the special registers $1F0-$1FF of P1.
- I trap PAR, CNT and read accordingly. I save PTR in a register for this case and GETCT is substituted.
- I translate DIRx/INx/OUTx to their new addresses (both A & B ports work correctly).
- The other special registers read 0 and ignore writes ie the VID & Counter registers. IIRC this works.
* Need to engage XBYTE - currently RDLUT & EXECF are used.
This is so I can debug at this specific point in the interpreter. I output...
- the x, y, a registers
- the bytecode address (pcurr=PTRA) and next 3 bytecodes
- the stack address (dcurr=PTRB) top 3 stack values
@Wuerfel_21 has mentioned the possibility of adding the spin1 interpreter to @ersmith 's flexspin.
To help, here is information that I did a few years ago in converting my P1 Faster Spin Interpreter over to P2.
I searched for the old threads but they appear to be MIA
My ideea was to be able to include P1 binaries as included "file" commands in the P2 source. Of course there are a few things that are not available such as waitvid and the counters.
Attached below is my P1 Spin1 Interpreter for both P1 and P2. I'm not sure how many bugs are in the P2 version.
Thanks, Ray. I hope to take a look at those over the weekend. If the P2 version of the interpreter works (at least partly) then it might be a quick route to getting bytecode working for P2.
The P2 interpreter doesn't compile, unfortunately... there were some missing single quotes on comments, and after I fixed those there were some additional errors:
I guess something in there bit rotted? For now I guess it makes sense for us to look at the P1 interpreter first, although the P2 one has more bang for the buck in the sense that we already have a P1 bytecode back end so it's a quick path to getting bytecode on P2.
Incidentally, Ada's work on the Spin bytecodes has really come along -- she's done a great job. We can run some BASIC and C programs now, with floats and strings.
This bit might be handy for testing (from v305l)
I've posted v305l below as it was the last version that I compiled
Here is the spin bytecode source for the test in v306d
Note that I patched address $001D from $85 to $F5 for testing.
It may be better to start from v305l and implement the sections from v306d one at a time although I haven't looked closely enough to see if this way is possible.