6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Wed Jun 05, 2024 1:52 am

All times are UTC




Post new topic Reply to topic  [ 22 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Sun Dec 09, 2012 9:34 pm 
Offline

Joined: Fri Oct 14, 2011 5:15 am
Posts: 7
Hello,

I'm writing a 6502 processor emulator and I'm facing a problem related to the program counter initialization. I'm trying to run this code to test my emulator. Everything runs ok until line 396 ("JMP jump1"). JMP instruction takes an absolute address as argument, that's being set by the assembler to jump1 address. The problem is that my code (and the program counter) wasn't loaded starting at $4000.

This topic helped me figuring out how to initialize program counter, using the address from reset vectors at $FFFC and $FFFD. Also, I understood that the first line (".ORG $4000") is putting the code at $4000, but it doesn't have nothing to do with the reset vector value. So how the processor is supposed to know to start reading instructions at $4000 if the ".ORG $4000" is only a directive for the assembler (and not the processor) and it doesn't mess with reset vectors?

What am I missing to start loading the code at the correct address, set the program counter correctly and therefore get my JMP instructions to work?

Thanks,

Pedro


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 09, 2012 9:50 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8453
Location: Southern California
At the end you'll have something like:
Code:
        ORG  $FFFA
        DW   <NMI addr>
        DW   start           ; (your label where you want the processor to start executing immediately after reset)
        DW   <IRQ addr>

        END

This doesn't really have anything to do with the JMP instructions though.

_________________
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  
PostPosted: Sun Dec 09, 2012 9:55 pm 
Offline

Joined: Fri Oct 14, 2011 5:15 am
Posts: 7
What I'm missing is HOW the .ORG and DW instructions affect the processor. I mean, what (in the compiled code) is telling me to load things at $4000 if .ORG and DW doesn't change the reset vector? Also, the code I'm trying to run doesn't have DW and it runs ok in other emulators. Why?


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 09, 2012 10:23 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8453
Location: Southern California
ORG tells the assembler where to start laying down the next bytes, whether they're code, data, a table, whatever. You can have lots of ORG's in your source code. ORG $FFFA tells it to go out to the vector area to lay the following addresses down. The second DW there does lay down the reset vector, at addresses FFFC-FFFD.

The processor doesn't care how the code was assembled or what the source looked like. It just fetches the $FFFC-FFFD address upon reset to find out where to start executing. In your case you'll put the $4000 address in bytes $FFFC-FFFD to tell it that $4000 is where you want to begin execution.

The Program-Writing: Where Do I Start? section of the 6502 primer might help.

_________________
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  
PostPosted: Sun Dec 09, 2012 10:32 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3363
Location: Ontario, Canada
Quote:
The problem is that my code (and the program counter) wasn't loaded starting at $4000.
Hi Pedro. Your options are to either put the code where it's expected or else alter the ORG statement and reassemble. Coming out of reset, the processor will read the reset vector and "go" there. That's how we get the ball rolling! But the vector needs to contain the correct address, which is what Garth's code snippet ensures.

But it seems you've already been running the code, so did you manually set up the Program Counter in order to get started?

cheers
Jeff

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 09, 2012 10:47 pm 
Offline

Joined: Fri Oct 14, 2011 5:15 am
Posts: 7
Dr Jefyll wrote:
But the vector needs to contain the correct address, which is what Garth's code snippet ensures.


So this means the code I'm trying to run is "wrong" because it doesn't set the reset vectors? But how other emulators can run this code the way it is? I believe they interpret the assembly and read the .ORG instruction to set the program counter if the reset vectors are not set.

Dr Jefyll wrote:
But it seems you've already been running the code, so did you manually set up the Program Counter in order to get started?


Yes. I'm setting the program counter manually for now.


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 09, 2012 11:00 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3363
Location: Ontario, Canada
Quote:
So this means the code I'm trying to run is "wrong" because it doesn't set the reset vectors?
I'm a bit puzzled. We have the assembler, which creates the binary executable, and your emulator -- which runs it. But what goes in between? What is it that loads the file before your emulator begins? Is that also some code of your own? I suspect the file is not being loaded properly.

Quote:
how other emulators can run this code the way it is?
Only by manually setting the PC. Otherwise the reset vector would have to be set -- and it isn't. That's what Garth's snippet does: lays down a vector that'll eventually land in memory up at $FFFA.
Code:
        ORG  $FFFA
        DW   <NMI addr>
        DW   start           ; (your label where you want the processor to start executing immediately after reset)
        DW   <IRQ addr>

        END

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Last edited by Dr Jefyll on Sun Dec 09, 2012 11:14 pm, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 09, 2012 11:12 pm 
Offline

Joined: Fri Oct 14, 2011 5:15 am
Posts: 7
Quote:
I'm a bit puzzled. We have the assembler, which creates the binary executable, and your emulator -- which runs it. But what goes in between? What is it that loads the file before your emulator begins? Is that also some code of your own? I suspect the file is not being loaded properly.


The emulator I tried to run this code was actually an assembler + emulator, so I think it interprets the .ORG instruction somehow.


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 09, 2012 11:15 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8453
Location: Southern California
Quote:
So this means the code I'm trying to run is "wrong" because it doesn't set the reset vectors?

Perhaps not wrong, just incomplete.

Quote:
But how other emulators can run this code the way it is? I believe they interpret the assembly and read the .ORG instruction to set the program counter if the reset vectors are not set.

Is it that the assembler associated with the simulator looks for a label called "start" or "reset" if no reset vector is specified, and it puts that in the vector?

Let me make a little correction in terminology though. If it's software only, it's a simulator. An emulator involves hardware, like the ones in a couple of other current topics where a microcontroller is being used to emulate the actual processor and it gets plugged into the circuit with actual I/O and memory. Depending on the level of sophistication, an emulator can be very helpful for debugging hardware, not just software. A simulator, if it has an assembler at least partially integrated, can look for that start label. A true emulator will just pick up whatever is in FFFC-FFFD without any regard for whether anything was ever stored there, or how it got there.

_________________
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  
PostPosted: Mon Dec 10, 2012 7:10 am 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
There's two key things to understand here.

First, your simulator has some way of managing memory. For a simple simulator, it's easy to start with 64K of RAM and perhaps a few special locations to handle terminal input and output. More sophisticated simulators will have other I/O devices, or perhaps ROM areas that can not be changed, or all sorts of other things.

Once your simulator has its memory structure, the next task is how to load machine code in to the simulator.

This burden falls upon you as the simulator author, but it also depends on what kinds of format that you wish to support as input in to your simulator.

In my case, my simulator understands the Intel HEX format. This is a very simple format, and a key aspect of it is that each record specifies the starting address for that data. As you load the records, you simply stuff the data in to the address specified by each record (and increment for each byte represented in the record).

It's easy to have a single file that represents discontinuous data blocks. For example, you could have a single file that loads in 2K of data. The first 1K starting at $1000, and the second 1K starting at $4000.

The .ORG command of the assembler is one way to represent where code and data lies within the memory of the computer. For simple assembler and simple programs, it's pretty much the only way to do so.

You can see something like this:

Code:
    .ORG $1000
L1  LDA #00
    RTS

    .ORG $2000
    LDX $FF
    JMP L1


This creates this assembly listing:

Code:
0000 1000               .ORG $1000
0001 1000 a9 00    L1    LDA #$00
0002 1002 60             RTS
0003 1003
0004 2000               .ORG $2000
0005 2000 a2 ff          LDX #$FF
0006 2002 4c 00 10       JMP L1
0007 2005


You'll note that on the left, the base address changes at the ORG statements, 1000 for the LDA, and 2000 for the LDX. And you see how the fact that L1 is the same at $1000 because the ORG statement tells it where it belongs.

This spits out a HEX file that looks like this:

Code:
:03100000a90060ff
:05200000a2ff4c0010ff
:00000001FF


This first line says "There's 03 bytes, starting at 1000, record type 00, with bytes a9, 00, 60, with FF as a checksum" (I don't implement the checksum). 00 is a simple data record type.

The second line says "There's 05 bytes, starting at 2000, record type 00, with bytes a2, ff, 4c, 00, 10, and FF as a checksum".

Finally, there's the terminator row, 0 bytes, address 0000, record type 01, checksum FF. 01 is the end of file record. The address, 0000, can be the runtime start address.

When this file is loaded, it will only change 8 bytes of memory: 1000-1002 and 2000-2004. None of memory before (<1000), in-between (1003-1FFF), or after (>2004) those blocks will be changed by the loader.

So, this shows you how the .ORG command can affect the output of the assembler. But different assemblers support different output files and formats. It all depends on the toolchain. You'll need to figure out what your toolchain supports (it may support several) and the learn how to load the data to the proper places.


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 11, 2012 2:56 pm 
Offline

Joined: Tue Jul 24, 2012 2:27 am
Posts: 672
In a nutshell, the value at $FFFC has to be prepared before the CPU even starts.

Real systems generally do this by having ROM in that range. Loading your memory image during emulator startup should cover that address range to set the start vector. So if you want to run something at $4000, having a memory image that spans $4000-$FFFF will contain both your program and the CPU vectors ready to go.

_________________
WFDis Interactive 6502 Disassembler
AcheronVM: A Reconfigurable 16-bit Virtual CPU for the 6502 Microprocessor


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 11, 2012 4:20 pm 
Offline

Joined: Tue Nov 18, 2003 8:41 pm
Posts: 250
I would assume he want's something like Michal Kowalski's simulator.

If you assemble something and run it in the debugger, it doesn't need
code at the reset/interupt vectors.

How it does that I don't know, presumably it just starts running at the
first bit of code in memory?


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 11, 2012 4:27 pm 
Offline

Joined: Fri Oct 14, 2011 5:15 am
Posts: 7
White Flame wrote:
So if you want to run something at $4000, having a memory image that spans $4000-$FFFF will contain both your program and the CPU vectors ready to go.


The point is: how would I know my program wants to run something at $4000 if the reset vectors aren't set? Should I assume the program is "incomplete" because it doesn't set the reset vectors?


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 11, 2012 4:32 pm 
Offline

Joined: Fri Oct 14, 2011 5:15 am
Posts: 7
GARTHWILSON wrote:
Perhaps not wrong, just incomplete.


Understood, but how my program can change the reset vectors (executing something like "STA #$55; LDA $FFFC") if the processor doesn't know where to start running the instructions to configure the reset vectors?

GARTHWILSON wrote:
Let me make a little correction in terminology though. If it's software only, it's a simulator.


Thanks for your correction! :) I always get confused with these terms.


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 11, 2012 4:40 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3363
Location: Ontario, Canada
Quote:
Understood, but how my program can change the reset vectors (executing something like "STA #$55; LDA $FFFC") if the processor doesn't know where to start running the instructions to configure the reset vectors?
LOL! :D You're right -- that is a "chicken or the egg" situation. The answer has to do with how things get loaded into memory.
What assembler is being used? How does its output get loaded into the simulator you wrote? These are key questions. Please explain the situation!

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 13 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: