6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 24, 2024 12:18 pm

All times are UTC




Post new topic Reply to topic  [ 44 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
 Post subject:
PostPosted: Fri Dec 30, 2005 11:37 pm 
Offline
User avatar

Joined: Thu Mar 11, 2004 7:42 am
Posts: 362
kc5tja wrote:
This I consider to be a "local optimization," because you can make this substitution only if you know a priori what the class the object is ahead of time.


Hmm, if knowing _do_method_entry_point always tells you where vtable is going to be, then it might be okay. In your original code, vtable is 3 bytes beyond _do_method_entry_point, so if _do_method_entry_point+3 (rather than _do_method_entry_point) -- which is the same as vtable -- is stored at [obj], _do_method_entry_point is no longer needed. Obviously, you'll know where _do_method_entry_point+3 is at the same time you know where _do_method_entry_point is. Now, where vtable is located relative to _do_method_entry_point may be another question.

kc5tja wrote:
As I recall, JSR(abs,X) only fetches its addresses from bank 0, no?


No. (abs) gets the (intermediate) address from bank 0; (abs,X) gets the address from bank K (the PBR) rather than B (the DBR), which means vtable would have to be in the bank of calling code, which pretty much confines you to 64k for all the code and address tables.

I should offer the disclaimer that I am just speculating here with all of this, and I may be overlooking something that I'd encounter if I were actually writing and experimenting with code.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Aug 21, 2010 9:26 am 
Offline

Joined: Sat Aug 21, 2010 9:21 am
Posts: 1
<spammer's post content deleted, but post retained as a place keeper>


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Aug 21, 2010 11:35 am 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1043
Location: near Heidelberg, Germany
BTW: is it only me who can't really understand the 65816 addressing mode descriptions in the 65816 datasheet from WDC?

I tried to find some addressing mode that for a jump, would fetch a two byte address from $00FFFC, and then jump to this address in bank 0, preferably in emulation mode (I think you guess what I want to do...) but I couldn't even decipher what the JML (ABS) resp. JMP (ABS) do.

So I actually store a "JMP ($FFFC)" (resp. a JMP directly to the address read from $00FFFC/D) somewhere in bank 0 and do a long jump there (can't do a direct long jump to ($00FFFC) via self-modifying code, as code runs in ROM). But that's absolutely not elegant...

André


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Aug 21, 2010 3:55 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
fachat, that's all you can do. And that is precisely why the 65xx architecture is not suitable for object oriented or functional programming at all, for both styles rely heavily on polymorphism implemented through such mechanisms.

BRK and COP are perhaps the only instructions implementing an "addressing mode" anywhere near what you're looking for, despite having its operand address hard-wired.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sat Aug 21, 2010 6:54 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
Quote:
but I couldn't even decipher what the JML (ABS) resp. JMP (ABS) do.

I don't know if you saw them, but the diagrams for JMP (addr,X) and JMP (addr) are on pages 291-292 of the current programming manual version online (but pages 382-383 of the paper one I bought before it was online) and show that both will result in the program pointer ending up somewhere in the current program bank, but that "addr" in JMP(addr) is always in bank 0, and that with JMP(addr,X) the addr is in the current program bank.

They are also described on page 165 of the online manual (page 212 of my paper one):

Quote:
Code:
      On the 65816, a jump-indirect operand is in bank zero, but a jump-indexed-indirect operand is in the
program bank.  There is a different assumption for each mode.  Jump indirect assumes that the indirect address
to be jumped to was stored by the program in a variable memory cell; such variables are generally in bank zero.
Jump indexed indirect, on the other hand, assumes that a table of locations of routines would be part of the
program itself and would be loaded, right along with the routines, into the bank holding the program.  So,

   6C3412      JMP   ($1234)      jump to address stored at $00:1234.1235

assumes $1234 is in a double-byte cell in bank zero.  But

   7C3412      JMP   (1234,X)      jump to address stored at pb:$1234,X

assumes $1234 is in the program bank, the bank in which the code currently being executed resides.
      The indirect addresses stored in the table are absolute addresses also assumed to be in the current
program bank.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Aug 22, 2010 4:03 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8514
Location: Midwestern USA
fachat wrote:
BTW: is it only me who can't really understand the 65816 addressing mode descriptions in the 65816 datasheet from WDC?

I understand them but only because I've run different sorts of code on my POC to see just what happens (reaching for the reset button on occasion).

The language used in the data sheet leaves something to be desired in clarity and even contains some outright errors. Not sure who does that documentation at WDC, but it's probably safe to say that the documentation work doesn't have a lot of priority around there.

Quote:
I tried to find some addressing mode that for a jump, would fetch a two byte address from $00FFFC, and then jump to this address in bank 0, preferably in emulation mode (I think you guess what I want to do...) but I couldn't even decipher what the JML (ABS) resp. JMP (ABS) do.

So I actually store a "JMP ($FFFC)" (resp. a JMP directly to the address read from $00FFFC/D) somewhere in bank 0 and do a long jump there (can't do a direct long jump to ($00FFFC) via self-modifying code, as code runs in ROM). But that's absolutely not elegant...

André

Perhaps the following may be of some help:

Code:
4C 76 98     JMP $9876         ;jump to $9876 in current bank, same as 65(C)02

5C 76 98 12  JMP $129876       ;jump to $9876 in bank $12, 65C816 only

6C 76 98     JMP ($9876)       ;jump to 16 bit address stored at $9876, staying in current bank, same as 65(C)02, but no page crossing bug

7C 76 98     JMP ($9876,X)     ;same as JMP ($9876) but indexed by .X, same as 65C02

DC 76 98     JMP [$9876]       ;jump to 24 bit address stored at $9876, byte at $9876+2 is the bank, 65C816 only

DC 76 98     JML ($9876)       ;same as JMP [$9876]

In JMP (ADDR), ADDR is stored in bank $00 RAM, but the actual jump is into the current program bank defined in the MPU's PBR. With JMP [ADDR], ADDR is also in bank $00 RAM, but the jump occurs to the bank specified at ADDR+2.

As you can see, JMP [ADDR] and JML (ADDR) accomplish the same thing. Syntactically, JML is an oddity, as the addressing mode symbology doesn't conform with other representations for indirect long addressing (e.g., LDA [ADDR]). My suggestion is to ignore the JML instruction, as it acts as an alias that is analogous to using INA as an alternative to coding INC A.

Incidentally, if JML ADDR is used in the WDC assembler in place of JMP ADDR you will end up with a 24 bit operand instead of 16 bit, even if the target address is entered as 16 bits. That is, JML $1234 will generate:

Code:
5C 34 12 00

using up four bytes and four clocks to do what three and three would accomplish with JMP $1234.

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Aug 22, 2010 10:55 am 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1043
Location: near Heidelberg, Germany
@Garth, thanks, that explains it. I've only been looking at the general 65816 data sheet so far, which is ungrokable.

@BDD, it seems you missed the point with the indirect address as pointed to by the opcode being in program bank with (ABS,X) addressing vs. being in zero bank with (ABS)...

Good to see I'm not the only one being confused, but I'll have a closer look at the programming manual, that was a good pointer!

But on the other hand, what opcodes or addressing modes would you like to see on a "new" version to support object-oriented or functional programming?

André


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Aug 23, 2010 4:11 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8514
Location: Midwestern USA
fachat wrote:
@BDD, it seems you missed the point with the indirect address as pointed to by the opcode being in program bank with (ABS,X) addressing vs. being in zero bank with (ABS)...

I'm confused. Which point did I miss?

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Aug 23, 2010 7:32 am 
Offline

Joined: Tue Jul 05, 2005 7:08 pm
Posts: 1043
Location: near Heidelberg, Germany
BigDumbDinosaur wrote:
fachat wrote:
@BDD, it seems you missed the point with the indirect address as pointed to by the opcode being in program bank with (ABS,X) addressing vs. being in zero bank with (ABS)...

I'm confused. Which point did I miss?


Sorry, maybe it's me but I did not read from your explanation, that with
JMP (ABS), ABS is an address in bank0, and with JMP (ABS,X), ABS is an address in the program bank.

André


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Aug 23, 2010 1:58 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8514
Location: Midwestern USA
fachat wrote:
Sorry, maybe it's me but I did not read from your explanation, that with
JMP (ABS), ABS is an address in bank0, and with JMP (ABS,X), ABS is an address in the program bank.

BigDumbDinosaur wrote:
In JMP (ADDR), ADDR is stored in bank $00 RAM, but the actual jump is into the current program bank defined in the MPU's PBR. With JMP [ADDR], ADDR is also in bank $00 RAM, but the jump occurs to the bank specified at ADDR+2.

I did say that about JMP (ADDR) and JMP [ADDR].

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Aug 23, 2010 4:48 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
JMP (ADDR,X) pulls the vector from bank K, not bank 0. Contrast this with JMP (ADDR) which pulls the vector from bank 0 only. That is the source of everyone's confusion.

Consider, without pulling from bank K, the following code cannot work:
Code:
  JMP (table,X)
table:
  .DW proc1, proc2, proc3

proc1:
  LDA #0
  RTS

proc2:
  LDA #$FF
  RTS

proc3:
  LDA #$AA
  RTS


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Aug 23, 2010 8:40 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8514
Location: Midwestern USA
kc5tja wrote:
JMP (ADDR,X) pulls the vector from bank K, not bank 0. Contrast this with JMP (ADDR) which pulls the vector from bank 0 only. That is the source of everyone's confusion.

I'm not confused with how it works. Apparently the confusion was in the translation. :)

_________________
x86?  We ain't got no x86.  We don't NEED no stinking x86!


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Oct 27, 2010 2:16 pm 
Offline

Joined: Wed Oct 27, 2010 1:28 pm
Posts: 25
Location: Valladolid (Spain)
I don't think the 6502 is a pipelined processor at all. Even the NOP instruction takes 2 clock cycles (fetch + Execute). If it were pipelined it would take only 1 cycle.

And the instruction decoder uses a PLA, so, it looks more like microprogramming.

But, I must agree, the instruction set is, indeed, reduced. (missing ADD_without_carry, for instance)

TMorita wrote:
Well, the 6502 was created way before the concept of RISC processors was imagined, so it's basically pre-RISC.

It does embody some of the basic tenets of RISC processors, though:

o simpler instructions
o hardwired instruction decoder
o pipelined execution of instructions

It doesn't have these characteristics:

o interchangeable registers
o orthogonal addressing modes

Toshi


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Oct 27, 2010 5:28 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
jesari,

Actually there is a little bit of true pipelining, and a lot of instructions do finish up while the next one is being fetched.  An example given in WDC's programming manual (page 40 in my edition) is ADC#, which requires 5 distinct steps, but only two clocks' time:
Step 1: Fetch the instruction opcode ADC.
Step 2: Interpret the opcode to be ADC of a constant.
Step 3: Fetch the operand, the constant to be added.
Step 4: Add the constant to the accumulator contents.
Step 5: Store the result back to the accumulator.

Steps 2 and 3 both happen in a single clock.  The processor fetches the next byte not knowing yet if it will need it or what it will be for.  Steps 4 and 5 occur during the next instruction's step 1, eliminating the need for two more clocks.  It cannot do steps 3 and 4 in one clock because the memory being read may not have the data valid and stable any more than a small set-up time before phase 2 falls and the data actually gets taken into the processor; so step 4 cannot begin until after step 3 is totally finished.  But doing 2 and 3 simultaneously, and then doing 4 and 5 simultaneous with step 1 of the next instruction makes the whole 5-step process appear to take only 2 clocks.

Another part of the pipelining is the reason why operands are low-byte-first.  The processor starts fetching the operand's low byte before the instruction decode has figured out how many bytes the instruction will have (1, 2, or 3).  In the case of indexing before or without any indirection, the low byte needs to be added to the index register first anyway, so the 6502 gets that going before the high byte has finished arriving at the processor.  In the case of something like LDA(abs), the first indirect address is fetched before the carry from the low-byte addition is added to the high byte.  Then if it finds out there was no carry generated, it already has what it needs, and there's no need to add another cycle to read another address 256 bytes higher in the memory map.  This way the whole 7-step instruction process requires only 4 clocks. (This is from the next page of the same programming manual.)

The 2-clock NOP has to do with the 2-clock minimum for the instruction step counter.  I don't know why that is, but maybe the visual6502 website would help.  Commodore had a patent on a process they used in the 65CE02 that allowed them to eliminate virtually all the dead bus cycles and make at least 30 op codes take just one clock.  There were not very many 65CE02's made, and the '816 was a better upgrade to the 65c02 than the CE02 was, so I'm glad to have that.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Oct 27, 2010 9:40 pm 
Offline

Joined: Wed Oct 27, 2010 1:28 pm
Posts: 25
Location: Valladolid (Spain)
Thanks for the explanation about the 6502 pipelining. I must admit there is some pipelining: last steps of execution in parallel with next instruction fetch. I think this is not always possible, but it can be done on some instructions, and is far from those pipelines found on typical RISC processors.

I don't want to look as being too critic about the old 6502. It was a remarkable design. Probably the best MIPS/$ and MIPS/#transistor of its time.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 44 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC


Who is online

Users browsing this forum: rwiker and 56 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: