6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Fri Nov 22, 2024 12:23 pm

All times are UTC




Post new topic Reply to topic  [ 9 posts ] 
Author Message
 Post subject: ORA ($xx,X)
PostPosted: Mon Mar 15, 2010 8:55 am 
Offline
User avatar

Joined: Fri Dec 12, 2003 7:22 am
Posts: 259
Location: Heerlen, NL
Hallo allemaal,


Working on my program that should fill the various EEPROM's, I accidently found some routines belonging to the hardware I discarded last week. I found these routines in ORA ($xx,X). Discarding these routines and trying to get ORA ($xx,X) to work only using the rest of the hardware, I ran into a problem:
- I first have to write "$xx + X" and "$xx + X + 1" to a register that can output data to the address bus. But it should be able to be increased as well.
- The two bytes found at this address and the next one should also be written to a register that can output data to the address bus as well.

IMHO this implies that I need TWO extra 16-bit registers beside the Program Counter. I have only one. This one is made out of 74191's plus 74541's, which means I cannot store new data while still outputting the old address that still has to be increased. And I have no other means to output data to the address bus.

My question: is there anybody who has a brilliant idea that enables me to do the trick without extra hardware?

If not, I have to restore the old idea, the "Address adder", a 16-bit register that is capable of outputting data to the address bus plus as an extra it can add an 8-bit number to the loaded data. Thus no ALU needed, which can save cycles.

_________________
Code:
    ___
   / __|__
  / /  |_/     Groetjes, Ruud
  \ \__|_\
   \___|       URL: www.baltissen.org



Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Mar 15, 2010 4:11 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
Hi Ruud

I don't suppose you have a block diagram for your design? (I haven't yet found a drawing program I'm happy with for this purpose, so wouldn't be surprised if you haven't. I'd be interested in any recommendation.)

Referring to the trusty 6502 block diagram and the cycle-by-cycle descriptions from VICE, I'd say
- the 6502 only has PCH and PCL, and ABH and ABL, for 16-bit data
- cycle 1, fetch opcode
- cycle 2, fetch operand
- cycle 3, operand saved in ABL, ABH set to 0, dummy access. Operand and X into ALU for address calculation
- cycle 4, ALU output to ABL, ABH still 0, no carry allowed, read low byte of pointer, set carry-in to ALU for the second addition.
- cycle 5, ALU output to ABL, ABH still 0, no carry allowed, read high byte of pointer. Not sure where the low byte is held. Perhaps it passes through the ALU as an add-zero no-op?
- cycle 6, perform the read using both pointer bytes. At the beginning of this cycle, ABL and ABH must both have been updated. Is this why the SB (special bus) must be decoupled by the pass transistors from the ADH (address high) bus? Both halves of this bus are in use for this case.
- cycle 7 or 1, fetch next opcode, perform ALU operation

(Looks like the box towards top right labelled Open Drain Mosfets produces the 0 or 1 to the high address byte for zero page and for stack accesses. As the bus is pre-charged high, only conditional pull-downs are needed.)

From the VICE team:
Code:
  Indexed indirect addressing

     Read instructions (LDA, ORA, EOR, AND, ADC, CMP, SBC, LAX)

        #    address   R/W description
       --- ----------- --- ------------------------------------------
        1      PC       R  fetch opcode, increment PC
        2      PC       R  fetch pointer address, increment PC
        3    pointer    R  read from the address, add X to it
        4   pointer+X   R  fetch effective address low
        5  pointer+X+1  R  fetch effective address high
        6    address    R  read from effective address


Last edited by BigEd on Mon Mar 15, 2010 4:26 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Mar 15, 2010 4:25 pm 
Offline
User avatar

Joined: Fri Dec 12, 2003 7:22 am
Posts: 259
Location: Heerlen, NL
BigEd wrote:
Edit: Noticing your need for "$xx + X + 1" I realise I've got the wrong example. Hold on a tick while I fix up my story.

OK, I'll wait. But to be sure: you are talking about ORA $xx,X while I'm talking about ORA ($xx,X).

BigEd wrote:
I'd be interested in any recommendation.

The few times I needed a block diagram, I used Eagle.

BigEd wrote:
From the VICE team:...

Oops, I completely forgot to thank you for that one. I have used it years ago but completely forgot about it.

_________________
Code:
    ___
   / __|__
  / /  |_/     Groetjes, Ruud
  \ \__|_\
   \___|       URL: www.baltissen.org



Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Mon Mar 15, 2010 4:28 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
OK, I think I've fixed my post. I was indeed trying to explain indexed instead of indexed indirect.

Thanks, I'll have a try using Eagle for block diagrams. I didn't find the bus editting very straightforward for schematics: we ended up using Verilog and writing a translater to eagle script.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Mar 16, 2010 6:29 am 
Offline
User avatar

Joined: Fri Dec 12, 2003 7:22 am
Posts: 259
Location: Heerlen, NL
BigEd wrote:
Not sure where the low byte is held.

Ah, you ran into the same problem!

Having found no solution myself, I installed this "address adder" again. Having lots of room on this Eurocard left, I placed a 6116, 2K*8 SRAM on it as well. It gives me 64 extra registers for future us. I also expanded the Stack pointer so it can cover 64KB. In native mode the high byte outputs $01 of course.

_________________
Code:
    ___
   / __|__
  / /  |_/     Groetjes, Ruud
  \ \__|_\
   \___|       URL: www.baltissen.org



Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Mar 16, 2010 10:45 pm 
Offline
User avatar

Joined: Sun Feb 13, 2005 9:58 am
Posts: 85
maybe i didnt get the point, but i think that the main problem is where to store one tmp byte, because it's seem easy to get the first byte $xx+X, which is to be stored somewhere (but near the adl) before getting the second byte.
the address of the second byte, imo, doesnt need a special adder if the alu is used, and maybe it's possible also solve the tmp byte problem looking at the two input registers.
so loading the abhr with this second byte and transferring (maybe with a zero add) the tmp byte in the ablr, we can proceed

it's only a piece of idea, not really verified.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Mar 17, 2010 6:34 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
passing through the ALU seems right to me. Not only should it work as a temporary store, but it feels similar to what would have to happen for ($zp),Y calculation. Doing similar actions would simplify the decoding. Then again, in that case the addition happens in cycle 4, not 5:

Code:
 Indirect indexed addressing

     Read instructions (LDA, EOR, AND, ORA, ADC, SBC, CMP)

        #    address   R/W description
       --- ----------- --- ------------------------------------------
        1      PC       R  fetch opcode, increment PC
        2      PC       R  fetch pointer address, increment PC
        3    pointer    R  fetch effective address low
        4   pointer+1   R  fetch effective address high,
                           add Y to low byte of effective address
        5   address+Y*  R  read from effective address,
                           fix high byte of effective address
        6+  address+Y   R  read from effective address


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Mar 18, 2010 12:56 pm 
Offline
User avatar

Joined: Fri Dec 12, 2003 7:22 am
Posts: 259
Location: Heerlen, NL
ptorric wrote:
the address of the second byte, imo, doesnt need a special adder if the alu is used

This address adder simplifies calculations and, most important, it is connected to the address bus as well. 1) It gives me the third register I need anyway, your "which is to be stored somewhere". 2) Using this "address adder" instead of the ALU can also save me one cycle.

_________________
Code:
    ___
   / __|__
  / /  |_/     Groetjes, Ruud
  \ \__|_\
   \___|       URL: www.baltissen.org



Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Mar 18, 2010 7:39 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10985
Location: England
To save a cycle, have you done the addition of X to the pointer in the same cycle that you output the pointer address to the address bus?

I've been thinking about the 6502, and how it's really a latch-based design whereas I'm used to register-based design. There are a few situations where the data read in the previous cycle is output to the address bus in the next cycle. You can't do that if you have registered input from the databus and registered output on the address bus. If you kept the registered outputs, you'd have to mux the databus into the address register inputs. That would slightly tighten your memory access time spec.

But if you do arithmetic on the way out to the address bus, you're also tightening the access time spec, because the address will be valid a little later.

I think I convinced myself that the 65816 has to do this kind of thing, which helped to explain the delay on the address outputs. The address outputs come from a latch, not a register, therefore the outputs can be a bit late.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 9 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google [Bot] and 24 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: