Page 2 of 8

Re: The RTF65002 Core

Posted: Wed Sep 11, 2013 6:40 pm
by enso
What's your FPGA utilization - roughly? Are you using BRAMS internally?

Re: The RTF65002 Core

Posted: Thu Sep 12, 2013 12:49 am
by Rob Finch
Quote:
What's your FPGA utilization - roughly? Are you using BRAMS internally?
The core uses roughly 39% of a xc6slx45 FPGA as of latest synthesis.
10895 LUTs
1112 FF's
25 BRAMs
4 DSP block (for the multiplier)

No, there is no internal BRAM usage except for the caches. It's not a microcoded design so there's no control tables to it.

The core was/is done in a manner to be developed as rapidly as possible. So it's somewhat inefficient in its use of resources.
I'm relying on the tools to do the thinking for me :)

Re: The RTF65002 Core

Posted: Thu Sep 12, 2013 12:58 am
by Rob Finch
Quote:
I think that I read somewhere that Lee used BCD mode in one or two places in EhBasic.
I wasn't going to include BCD mode at first, but decided to add it in. I'm not sure if it matches exactly the results of the 6502 for the unusual cases.

The overflow error is coming from FAC arithmetic. I've looked at several cases where BNE/BCS/BMI are used to indicate overflow but haven't found
a problem yet.

I ran 1,500 line processor test successfully, but still have a problem *somewhere*. Ugh.

Re: The RTF65002 Core

Posted: Fri Sep 13, 2013 7:29 am
by Rob Finch
Quote:
I think that I read somewhere that Lee used BCD mode in one or two places in EhBasic
It turns out that EhBasic, like some other BASIC interpreters uses self modifying code. Which doesn't go well with an instruction cache. I tried disabling the instruction cache and it cleared up many problems. The overflow error is gone, and I get the "Enhanced BASIC 2.22" prompt, But when I try and type in a program nothing lists back.

I also get the message "@@@@ bytes free".

Re: The RTF65002 Core

Posted: Fri Sep 13, 2013 2:04 pm
by barrym95838
Quote:
... The overflow error is gone, and I get the "Enhanced BASIC 2.22" prompt, But when I try and type in a program nothing lists back.

I also get the message "@@@@ bytes free".
Those two problems might be closely related, if the top and bottom pointers didn't get properly initialized. I'm not familiar with EhBASIC, but I assume that you could try an immediate command, like PRINT "50 + 50 = ";50+50 and see if that works.

I was never a big fan of self-modifying techniques, but I believe that it was used in many of the interpreters written for 8-bitters in the 70s. Well, I guess that I have no right to judge, since I never felt the need to squeeze cycles, and was always prouder of my space optimizations, from a hobbyist's perspective. I believe that Woz had a similar philosophy, but I would have to take a closer look at his Integer BASIC to confirm this. dclxvi is an expert on this subject ... perhaps he would like to chime in?

Mike

Re: The RTF65002 Core

Posted: Sat Sep 14, 2013 1:54 am
by Rob Finch
I managed to track the problem down to a faulty sta (d),y instruction. Well I fixed it and EhBASIC seems to work now. It's running! with interrupts occurring switching to 32 bit mode, then returning to eight bit mode successfully.

I had coded in Verilog a compare if (ir==`STA_IY) and I needed to add a bit select on ir like (ir[7:0]==`STA_IY).

Self modifying code is sometimes a substitute for a more powerful instruction set. I used self-modifying code for graphics performance by having the raster op dynamically replaced. AND switched to OR, switched to COPY, etc. So there was no case statements (branches) for the raster op.

The EXEC instruction which usually executes an instruction contained in a register is available on some architectures. The instruction can be used to avoid self-modifying code. Maybe I should add some sort of EXEC to the processor. hmm.

Re: The RTF65002 Core

Posted: Tue Sep 17, 2013 3:02 pm
by barrym95838
Rob Finch wrote:
... Maybe I should add some sort of EXEC to the processor. hmm.
Kind of like a one-instruction subroutine, but without the JSR/RTS? It would be easy on a fixed-length instruction core like my 65m32, where the entire instruction fits neatly inside a single register or memory cell. Several instructions use/modify the instruction pointer ... how do you think that should be treated?

Code: Select all

main    exe  instr
        brk
instr   jsr  foo
        stp
foo     rts
Does this program break or stop? In other words, what return address did jsr push?

Mike

Re: The RTF65002 Core

Posted: Tue Sep 17, 2013 4:54 pm
by Rob Finch
Quote:
Several instructions use/modify the instruction pointer ... how do you think that should be treated?
The exec instruction wouldn't actually perform a call. It would just execute the instruction in a buffer. If that instruction was a JSR for instance, then the processor would return to the code following the EXEC instruction. The EXEC just replaces itself with the instruction to be executed.

Code: Select all

ld ibuf,#SOME_INSTRUCTION
....
EXEC ibuf
....
The EXEC instruction could be used to eliminate test trees in code. (The tree can be hoisted up out of a loop). For instance the following code can be reduced.

Code: Select all

ALOOP:
     CMP #AND
     BNE j1
     AND  r1,r1,r2
     BRA  j2
j1  CMP #OR
     BNE j3
     OR r1,r1,r2
     BRA j4
...
j2
j3
ENDALOOP:
Becomes

Code: Select all

    ld ibuf,#Operation    ; operation is the desire AND/OR/EOR/COPY etc.
 .....
ALOOP:
    EXEC ibuf
...
ENDALOOP
.....

Re: The RTF65002 Core

Posted: Tue Sep 17, 2013 6:44 pm
by GARTHWILSON
It's similar to Forth's EXECUTE which executes the word (routine) whose address is at the top of the data stack. PERFORM is the indirect equivalent (which could be defined as @ EXECUTE), where the top data-stack cell tells where to read the address of the word to execute. I can see that having an assembly-language equivalent would have its uses, but I wonder if they would be enough to justify having it.

Re: The RTF65002 Core

Posted: Tue Sep 17, 2013 9:55 pm
by barrym95838
Cool, guys ... I think that I understand, mostly.

Garth, I know that your version of Forth uses absolute addressing for BRANCH, but let's assume that you EXECUTE a fig-Forth style relative branch instruction. Is the target of the branch relative to the IP of the EXECUTE instruction, or relative to the address of the BRANCH instruction? Also, does the relative address literal come directly after the EXECUTE, or directly after the BRANCH?

Mike

Re: The RTF65002 Core

Posted: Tue Sep 17, 2013 10:57 pm
by GARTHWILSON
Quote:
Garth, I know that your version of Forth uses absolute addressing for BRANCH
I don't remember having said that, but yes it is true of my '816 Forth. If/when I ever get my '02 Forth cleaned up for publication, I'm going to have to change a few things that are left that a particular company could claim a copyright on it, and at the same time I want to get rid of that need to add the relative address to the current address to get the target address.
Quote:
but let's assume that you EXECUTE a fig-Forth style relative branch instruction. Is the target of the branch relative to the IP of the EXECUTE instruction, or relative to the address of the BRANCH instruction? Also, does the relative address literal come directly after the EXECUTE, or directly after the BRANCH?
EXECUTE is never relative in 6502 Forth to my knowledge like branch and zbranch sometimes are. (branch and zbranch are internals compiled by things like IF and ELSE.) The absolute address for EXECUTE to execute comes off the top of the data stack. There's never a need to have it immediate, because any word (and I don't mean 16-bit entity, but rather that every type of routine in Forth is called a "word") that you write automatically becomes part of the language, so you just put its name in the source code where you want it executed, for example "FOOBAR" and not "EXECUTE FOOBAR". You could do something like

Code: Select all

   ['] FOOBAR  EXECUTE
which would take the code field address of FOOBAR and compile it as a literal to put on the stack at execution time and do the same thing, but it would be rather pointless and inefficient. But if you want to do something like calculate the offset into a table of word addresses depending on conditions at execution time, you'll end up with the result on the dtat stack and then do @ EXECUTE (or PERFORM). My '816 Forth EXECUTE is:

Code: Select all

         HEADER "EXECUTE", NOT_IMMEDIATE       ; ( addr -- )
EXECUTE: PRIMITIVE
         LDA      0,X     ; Get the address from the top of the data stack
         STA      W       ; and put it in the word pointer.
         INX_INX          ; Drop the top stack item since we're done with it.
         JMP      W-1
 ;-------------------
We get off topic a lot but I guess it applies to the OP.

Re: The RTF65002 Core

Posted: Wed Sep 18, 2013 5:27 am
by barrym95838
GARTHWILSON wrote:
... We get off topic a lot but I guess it applies to the OP.
Yeah, that's my fault. I apologize to Rob for stumbling around in his thread. I'll try to keep my Forth novice questions in the appropriate section.

Or better yet, I could just RTFM first! I have several fig-FORTH sources, but I confess that I only understand how to translate them, not actually use them in any meaningful way, at least not yet.

Mike

Re: The RTF65002 Core

Posted: Wed Sep 18, 2013 7:15 am
by GARTHWILSON
barrym95838 wrote:
Or better yet, I could just RTFM first! I have several fig-FORTH sources, but I confess that I only understand how to translate them, not actually use them in any meaningful way, at least not yet.
Leo Brodie's book "Starting Forth" is still kind of the standard. It is available to read online, free, at http://www.forth.com/starting-forth/index.html with even the original cartoons, but updated with ANS Forth content. I got my paper one before ANS Forth existed, and it had footnotes here and there about the minor differences between fig-Forth, Forth-79, Forth-83, F83, etc. for particular words.

Anyway, although I haven't tried any assembly-language coding with an EXEC instruction to execute a full instruction held in a register, I've been thinking it sounds kind of cool.

Re: The RTF65002 Core

Posted: Thu Sep 19, 2013 8:06 am
by Rob Finch
I decided not to implement an EXEC instruction. I tried it, and it made the whole core bigger and slower. The problem is that the pc increment for each instruction has to be squashed. It's replaced by an increment the size of the EXEC instruction (2 bytes). It's not to bad to do when instructions are the same size and there's only one place the pc is incremented, but I have pc increments of different amount all over the place. It affected things like stacking return addresses on the stack.
The alternative solution was to specify that the EXEC instruction had to be followed by up to seven NOPs, to account for variations in instruction length.

It would take two 32 bit registers to hold an instruction to execute.

I've been thinking about trying to port Forth to the processor, and had a look at the Fig-Forth code.
My assembler isn't compatible with the source code, so there's lots of edits to be done.

Re: The RTF65002 Core

Posted: Thu Sep 19, 2013 12:29 pm
by nyef
Okay, how about having some way to modify the next instruction in the stream by ORing (or XORing) in some bitmask? I've seen this stunt pulled with a microcoded architecture, where the microcode can write to a register that mixes a value into the next microinstruction, it was used for indexed register access, indirect jumps, selecting an ALU operation, all sorts of crazy stuff. I don't know if it's of interest to you, but it's a possible angle.