6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Tue May 07, 2024 7:21 pm

All times are UTC




Post new topic Reply to topic  [ 23 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Thu Dec 09, 2010 3:44 pm 
Offline

Joined: Thu Dec 09, 2010 3:37 pm
Posts: 12
Location: France
Hi there,

I'm completely new to the 6502 world, and I'm coding an emulator for this microprocessor. I already read a lot of things on it, but I get stuck with one little thing at this moment :
- How the processor know where to start the Program Counter ?

I saw some sources with .ORG 4000 or .ORG 0801, but does this command put something like "push 4000 in PC" at address 0 (where PC is initialized for example) ?

I saw other sources in SREC format like this one :
Code:
S1234000D8182022403820224000414F4B62696E61727900F8182022403820224000414F34
S12340204B0008A90085A085A128082077400885A26885A32808206C400885A4C5A2D014F7
S12340406885A5C5A3F01B00466661696C20666C6167730000466661696C20726573756C1B
S12340607400E6A0D0C3E6A1D0BF2860A5A149FF85A6A5A0E5A660A5A065A160A90085A3AC
S1114080A5A065A10885A29002E6A3286060B1
How can the processor could guess where to start ? Or, by loading this file, it put the PC to the first address encountered (0x4000 here) ?

Hoping this is not a too much stupid question...

_________________
Mindiell
-----------------------
French coder of a new 6502 simulator


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Dec 09, 2010 5:03 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 9:02 pm
Posts: 1685
Location: Sacramento, CA
welcome!

That is a good question. On reset, the processor will read address $FFFC and $FFFD (called the reset vector) and load the program counter (PC) with their content.

For example, if $FFFC = $00 and $FFFD = $10, then the PC will get loaded with $1000 and execution will start there. However, most 6502 systems contain ROM in the upper address region, say $E000-$FFFF so it's likely that the reset vector will point to a location there.

Most systems have an OS of some sorts - ranging from a simple machine language monitor, BASIC interpreter, even GUI interfaces such as Contiki.

Your OS must have a method of loading the programs generated from an assembler or compiler into RAM. It must also have a method of executing code in RAM.

For simplicity, lets say you have a simple command line promt and you can load a program using the "LOAD Example.obj, $1000" command.

This will load the program named Example.obj into RAM at address $1000.
Next, from the command prompt, you would type "Exec $1000" which would move the address $1000 into the PC register and begin executing your program.

You must have some sort of OS capable of doing these two steps in order to load and execute programs.

I hope that helps!

Daryl


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Dec 09, 2010 8:02 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8432
Location: Southern California
The ".ORG" is a directive for the assembler, telling the assembler what to do, not the target processor. .ORG 4000 tells the assembler to start laying down code at the address 4000. It does not mean the processor will start there unless you make your reset vector (in address FFFC-FFFD) point there. You can have more than one occurrence of .ORG in your code. At a minimum, you will usually have one to start the code, and, at the end, a .ORG FFFA to start laying down your three vectors.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Dec 09, 2010 9:24 pm 
Offline

Joined: Thu Dec 09, 2010 3:37 pm
Posts: 12
Location: France
Thank you,

So, if I understand well, the processor will, at start and at each reset, set the PC register to what it found in the reset vector ($FFFC-$FFFD) ?

Actually, what I want to do is doing Atari2600 emulation and I'm trying to emulate (or simulate I think) the 6502. So, right now I want to test some codes in order to verify that my simulator is doing well. So I'm loading some small asm programs in is memory. But since I'm initializing everything at 0, the PC is at 0 at the start. I think I will change that in order to set the PC to the first address found in the loading procedure.

D'ont know if this is the best, but it's just for testing right now, I'll change this later.

By the way, I saw the P register being initialized at $20. Why the useless bit is set ? Why isn't it clear ? (I saw this in a thread and in an other simulator)

Thank you again,

_________________
Mindiell
-----------------------
French coder of a new 6502 simulator


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Dec 09, 2010 10:23 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8432
Location: Southern California
Quote:
So, if I understand well, the processor will, at start and at each reset, set the PC register to what it found in the reset vector ($FFFC-$FFFD) ?

Right. The reset vector is read during the reset sequence.
Quote:
(or simulate I think)

Right again. If it's software only, it's a simulator.
Quote:
But since I'm initializing everything at 0, the PC is at 0 at the start. I think I will change that in order to set the PC to the first address found in the loading procedure.

We recently discussed this somewhere else, but it will take me awhile to think of what to search for to find it. The reset is a type of interrupt, and at least some of the 6502 variations (all 65c02, I think) start the reset sequence with stacking the current PC, so theoretically you could use that in a crash recovery to find out where it was. After stacking the PC, it loads it with the reset vector.
Quote:
By the way, I saw the P register being initialized at $20. Why the useless bit is set ? Why isn't it clear ?

I don't know, but at least add 04 to that. It should come up with the interrupt-disable bit set.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Dec 09, 2010 11:24 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
Unused bits are typically set because of internal pull-up resistors (or their MOS equivalents). These enforce a known-good logic level on unused signal lines, so that gates don't go into latch-up, draw excessive power, etc.

The choice of a logic-high versus logic-low is usually conventional in nature, and probably depends on which power rail is closest in the chip.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 10, 2010 2:59 am 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8176
Location: Midwestern USA
GARTHWILSON wrote:
Quote:
By the way, I saw the P register being initialized at $20. Why the useless bit is set ? Why isn't it clear ?

I don't know, but at least add 04 to that. It should come up with the interrupt-disable bit set.

$20 represents the unused status register bit in the 65(c)xx, which is always set. In the 65C816, that bit is used to set the width of memory and accummulator operations.

Code:
65(c)xx Status Register
-----------------------
xx0xxxxx
|| |||||
|| ||||+---> 1 = arithmetic carry
|| |||+----> 1 = arithmetic zero
|| ||+-----> 0 = interrupt request enabled
|| ||        1 = interrupt request disabled
|| |+------> 0 = binary mode enable
|| |         1 = decimal mode enabled
|| +-------> 1 = forced break detected
|+---------> 1 = arithmetic sign overflow
+----------> 1 = arithmetic negative


65C816 Status Register (native mode)
------------------------------------
xxxxxxxx
||||||||
|||||||+---> 1 = arithmetic carry
||||||+----> 1 = arithmetic zero
|||||+-----> 0 = interrupt request enabled
|||||        1 = interrupt request disabled
||||+------> 0 = binary mode enable
||||         1 = decimal mode enabled
|||+-------> 0 = 16 bit index registers
|||          1 = 8 bit index registers
||+--------> 0 = 16 bit accummulator
||           1 = 8 bit accummulator
|+---------> 1 = arithmetic sign overflow
+----------> 1 = arithmetic negative


BRK does not require differentiation in the 65C816 because it has its own vector. Also note that the BRK bit is meaningless unless a BRK opcode was actually executed, in which case the MPU will push the status register onto the stack with bit 5 set. An IRQ will do the same but with bit 5 clear, which is how you tell if an interrupt request was hardware or software:
Code:
tsx                    ;get stack pointer
lda $0101,X            ;get copy of status register
and #%00100000         ;check if BRK bit is set
bne goto_brk_handler

beq goto_irq_handler

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


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 10, 2010 8:40 am 
Offline

Joined: Thu Dec 09, 2010 3:37 pm
Posts: 12
Location: France
Great ! I was certain there was a hardware explanation and kc5tja explained very well.

Thanks for all this information. I'll try to do my best now.

Oh, and as I'm here, a last question :)
Do you know where I can find a 6502 compiler with which I can take a source and obtain the binary result ?
I had a look at the Michal Kowalski which is great for test my own simulator, as I can compile a source code and test the result, but I can't grab the binary in order to use it in my own simulator : I don't want to do a compiler, just a simulator ;)

EDIT :
By the way, after verification. When compilig and debugging a simple code source like this :
Code:
   .ORG $4000
start:
; EXPECTED FINAL RESULTS: $0210 = FF
; (any other number will be the
;  test that failed)

; initialize:
   LDA #$00
   STA $0210
   ; store each test's expected
   LDA #$55
   STA $0200
   LDA #$AA
   STA $0201
   LDA #$FF
   STA $0202
   LDA #$6E
   STA $0203
   LDA #$42
   STA $0204
   LDA #$33
   STA $0205
   LDA #$9D
   STA $0206
   LDA #$7F
   STA $0207
   LDA #$A5
   STA $0208
   LDA #$1F
   STA $0209
   LDA #$CE
   STA $020A
   LDA #$29
   STA $020B
   LDA #$42
   STA $020C
   LDA #$6C
   STA $020D
   LDA #$42
   STA $020E
This simulator (the one by Michal Kowalski) is initializing everything to a 0 value apart :
- the Processor Status : $20 no problem
- the Stack Pointer : $FF ok, this is the top of the stack
- the Program Counter : $4000, strange, because all vectors are empty (from $FFFA to $FFFF)

So, I guess loading the binary inside this simulator tends to use the first ORG to initialize the PC...

EDIT 2 :
I found this in the programmingmanual.pdf :
page 71 wrote:
The code generated by the assembler, when linked, will begin at the default origin location, $2000.
Is it possible to verify this default value by using a real hardware processorand just read the PC value without programming anything ? (maybe reading on some pin I guess... But I'm not an electronic scientist, just a poor computer developer)

_________________
Mindiell
-----------------------
French coder of a new 6502 simulator


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 10, 2010 10:38 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8432
Location: Southern California
Quote:
Oh, and as I'm here, a last question

Ask as many as you wish. There are no limits (except when we can see someone asks without putting out any effort, as happened recently).

Quote:
Do you know where I can find a 6502 compiler with which I can take a source and obtain the binary result ?

It sounds like you just want an assembler. Almost any assembler should work. Most have several options for output format.

Quote:
- the Stack Pointer : $FF ok, this is the top of the stack

You should normally initialize this in your reset routine. The most common sequence is LDX#FF, TXS.

Quote:
I found this in the programmingmanual.pdf :
page 71 wrote:
The code generated by the assembler, when linked, will begin at the default origin location, $2000.
Is it possible to verify this default value by using a real hardware processor and just read the PC value without programming anything ?

The processor absolutely will not automatically start at $2000 or $4000 or anything predictable without loading the vector into the PC. The assembler might have an implied .ORG $2000, but the assembler is not the processor. The only sensible and normal way to start the processor will be with a reset which will make the processor start at the address the reset vector points to.

Your code says, "; EXPECTED FINAL RESULTS: $0210 = FF"; but the only value written to $0210 is 0, so that's what will be there at the end. A better way to write those numbers to memory might be with a loop and a table though, and start at the end and go backwards for the easiest and most-efficient indexing:
Code:
TABLE:  DFB $55, $AA, $FF, $6E, $42, $33, $9D, $7F, $A5, $1F, $CE, $29, $42, $6C, $42

INIT:   STZ    $210
        LDX    #$0E
LOOP:     LDA  TABLE,X
          STA  $200,X
          DEX
        BPL    LOOP

I normally use the assembler directive "RADIX HEX" also so I don't have to keep writing the "$".


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 10, 2010 1:36 pm 
Offline

Joined: Thu Dec 09, 2010 3:37 pm
Posts: 12
Location: France
GARTHWILSON wrote:
Ask as many as you wish. There are no limits (except when we can see someone asks without putting out any effort, as happened recently).
Thank you so much, but next time I'll do another thread in order to make it easier for someone else looking for the same information ;)

GARTHWILSON wrote:
It sounds like you just want an assembler. Almost any assembler should work. Most have several options for output format.
Great, I had a look in your Development Tools: Assemblers and Disassemblers and the link to TASM is bad : it's linked to the fasm archive but the tasm archive is existing. I don't know who can change this link :)

GARTHWILSON wrote:
Your code says
Well, not a code from me, just a soure I used to see how the emulator was working. Thus, thanks for the tip about the table thing. It could be usefull.

_________________
Mindiell
-----------------------
French coder of a new 6502 simulator


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 10, 2010 1:39 pm 
Offline
User avatar

Joined: Tue Mar 02, 2004 8:55 am
Posts: 996
Location: Berkshire, UK
My portable assembler can produce a binary files (and hex and S19).

http://www.obelisk.demon.co.uk/dev65/

_________________
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 10, 2010 1:44 pm 
Offline

Joined: Thu Dec 09, 2010 3:37 pm
Posts: 12
Location: France
Thanks again,

I don't use java right now, but I downloaded the AS65 assembler from "Frank".
By the way, this time I know who to ask to change the link, the AS65 link is broken, and the correct link is : http://www.obelisk.demon.co.uk/6502/as65_111.zip

;)

_________________
Mindiell
-----------------------
French coder of a new 6502 simulator


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 10, 2010 6:06 pm 
Offline

Joined: Fri Aug 30, 2002 2:05 pm
Posts: 347
Location: UK
Quote:
I had a look at the Michal Kowalski which is great for test my own simulator, as I can compile a source code and test the result, but I can't grab the binary in order to use it in my own simulator

After assembling go to the File -> Save code... menu or press [CTRL]K to bring up the save code dialog.

Quote:
-the Program Counter : $4000, strange, because all vectors are empty (from $FFFA to $FFFF)

The reset vector will be used if you hit the RST icon or press [CTRL][SHIFT]R otherwise the first .ORG value will be used.

Lee.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Fri Dec 10, 2010 6:13 pm 
Offline
User avatar

Joined: Thu May 28, 2009 9:46 pm
Posts: 8176
Location: Midwestern USA
Mindiell wrote:
Do you know where I can find a 6502 compiler with which I can take a source and obtain the binary result ?

Not to be pedantic about it, but you assemble 65xx machine code, not compile. A compiler translates a higher level language (e.g., C or COBOL) to machine language, usually by first generating an assembly language source file and then assembling the assembly language instructions. Compilers confer a degree of portability between systems (e.g., a program written in C is usually portable between systems for which a native C compiler exists) and insulate the programmer from the raw machine code instruction set of the target system. By definition, assembly language is not portable, as each MPU has its own instruction set and each system has its own unique architecture.

Quote:
I had a look at the Michal Kowalski which is great for test my own simulator, as I can compile a source code and test the result, but I can't grab the binary in order to use it in my own simulator : I don't want to do a compiler, just a simulator ;)

You'd be better off, in my opinion, developing your own simulator from scratch. The Kowalski simulator is a fine piece of software, but deviates from 65xx assembler standards in several ways and also does not correctly implement all features of the NMOS version of the 6502 family (e.g., incorrect handling of .Z when in BCD mode). Also, I have never been able to get the I/O window features to work in it.

Quote:
I found this in the programmingmanual.pdf :
page 71 wrote:
The code generated by the assembler, when linked, will begin at the default origin location, $2000.
Is it possible to verify this default value by using a real hardware processorand just read the PC value without programming anything ? (maybe reading on some pin I guess... But I'm not an electronic scientist, just a poor computer developer)

Start your source code with .ORG <address> or *=<address> to set the starting assembly address. There is seldom a default and the MPU itself goes to $FFFC-$FFFD for the starting address following a hard reset.

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


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Sun Dec 12, 2010 8:02 pm 
Offline

Joined: Thu Dec 09, 2010 3:37 pm
Posts: 12
Location: France
leeeeee : Thank you, I'll have a look at it.

BigDumbDinosaur : GARTHWILSON did correct me, but thanks again for helping me being more precise. Thanks for the help about the starting address.

As I said I want to do a simulator for the Atari 2600 and I'm starting by simulating the 6502. And whithout the informations about the 2600 I sometimes get stuck. By the way, it seems that the 6502 is never used alone and has a minimal OS to set some default like this starting address.

Thanks again everyone !

_________________
Mindiell
-----------------------
French coder of a new 6502 simulator


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

All times are UTC


Who is online

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