Page 1 of 1

.org directive to assembly (where does it go?)

Posted: Thu Nov 12, 2015 9:52 pm
by Johnny Starr
I was reviewing a hexdump of the Pitfall! binary...
I've been memorizing opcodes and thought I would try my hand at manual disassembly. Mostly for the heck of it.
Up until now, I've always relied on an assembler to handle everything. However, here's what I find when I do a raw hexdump:

Code: Select all

$ hexdump Pitfall.bin | head
0000000 d878 00a2 00a9 0095 e89a fad0 7520 a2fa
...
The source code indicates that the ROM starts off at $F000 as its a 4K ROM. However, as you can see the very first
opcode is D8, which is the CLD instruction. Here's the dissassembly from what I can gather:

Code: Select all

  CLD
  SEI
  BRK
  LDX #00
  LDA #00
  ...
So far, that all makes sense as these are the things you would do at the beginning of an Atari 2600 ROM. However, I don't
see the memory address $F000 anywhere. What am I missing? Also, if you disassemble further, it seems that some of the bytes
are backwards... for instance, 'fad0'... d0 is 'BNE' and 'FA' is not an opcode. Does this mean that 'FA' is stored little endian or something?
I know that BNE $FA would be "branch backwards 6 bytes". I guess there's more than one question here.

Thanks

Re: .org directive to assembly (where does it go?)

Posted: Thu Nov 12, 2015 10:01 pm
by barrym95838
I think that your hunch about 16-bit little-endian display is the likely answer, Johnny. I don't know how to hammer out a quick script to swap them and check to see if it makes more sense, but I'm sure that you or someone like Ed could do it with minimal effort.

Mike B.

Re: .org directive to assembly (where does it go?)

Posted: Thu Nov 12, 2015 10:14 pm
by BigEd
Yes, byteswapping seems to help - try

Code: Select all

xxd -e -g2
and you might see

Code: Select all

00000000: 78d8 a200 a900 9500 9ae8 d0fa 2075 faa2  .x..........u ..
This gets rid of the BRK, which makes it much more plausible.

The data in a ROM starts at the beginning of the ROM, so a dump will by default just show it as starting at 0. When the ROM is in a system, the address decoding hardware will place it at some particular address. In your case, you believe the ROM starts at F000. Probably there's an option to xxd to help show that, if needed.

I did a quick disassembly using lib6502(*):

Code: Select all

F000 78     x   sei 
F001 D8         cld 
F002 A200       ldx #00
F004 A900       lda #00
F006 9500       sta 00,X
F008 9A         txs 
F009 E8         inx 
F00A D0FA       bne F006
F00C 2075FA  u  jsr FA75
F00F A200       ldx #00
It does look plausible.

Edit: Try this to set an offset in your hex dump:

Code: Select all

xxd -g 2 -e -o $(expr 0xf000)
(*) Using

Code: Select all

./run6502 -l f000 /tmp/x -d f000 f012 -x

Re: .org directive to assembly (where does it go?)

Posted: Fri Nov 13, 2015 6:03 am
by BigDumbDinosaur
Johnny Starr wrote:
I was reviewing a hexdump of the Pitfall! binary...
I see where Ed addressed the endianess issue.
Quote:
However, I don't see the memory address $F000 anywhere.
Assuming $F000 is indeed the address at which that code started, it was the source code, specifically, the .org or *= statement, that told the assembler to begin assembling instructions at $F000.

In creating a ROM, the source code is assembled to start at a specific address, such as $00E000 in my POC unit's ROM, that address set by the first .org or *= statement encountered by the assembler. The resulting object code is then burned into the ROM using an offset to the ROM's first cell, which is at $0000. Exactly what that offset would be would depend on how the ROM has been mapped into processor space. Again, using my POC unit as an example, the ROM is mapped in at $00E000. $00E000 accesses the ROM at $0000, $00F000 accesses the ROM at $1000, and so forth. Or, looking at it the other way, address $0000 in the ROM appears at $00E000 and address $1000 in the ROM appears at $00F000.

Re: .org directive to assembly (where does it go?)

Posted: Fri Nov 13, 2015 7:27 am
by Tor
Johnny Starr wrote:

Code: Select all

$ hexdump Pitfall.bin | head
0000000 d878 00a2 00a9 0095 e89a fad0 7520 a2fa
...
[..]Also, if you disassemble further, it seems that some of the bytes
are backwards... for instance, 'fad0'... d0 is 'BNE' and 'FA' is not an opcode. Does this mean that 'FA' is stored little endian or something?
It's just that when hexdump writes 16-bit words it writes them in 'value' format, so for little-endian architectures like x86 and 6502 the value 32768 would be 0x8000 in hex, so even if it is physically stored as 00 80 it will be output as 8000 if you ask hexdump to output the binary values as 16-bit words. If you instead use hexdump -C (telling hexdump to interpret the values as single bytes) you would see

Code: Select all

00000000 78 d8 a2 00 a9 00 95 00  9a e8 d0 fa 20 75 fa a2
and so on.

Re: .org directive to assembly (where does it go?)

Posted: Fri Nov 13, 2015 7:36 am
by barrym95838
@Tor: Ahh! Best (and most helpful, IMO) answer yet!

Mike B.

Re: .org directive to assembly (where does it go?)

Posted: Fri Nov 13, 2015 10:35 am
by BigEd
Ah - I wondered about that, after posting. It turns out xxd (my tool of choice) acts as I'd expect, whereas hexdump likes to deal in two-byte words.

Code: Select all

$ echo abcdef | xxd
0000000: 6162 6364 6566 0a                        abcdef.
$ echo abcdef | hexdump 
0000000 6261 6463 6665 000a                    
0000007
(In both cases they can be asked to operate the other way.)

If I'd read the original post more carefully, I might have thought of that.

Re: .org directive to assembly (where does it go?)

Posted: Fri Nov 13, 2015 3:06 pm
by 8BIT
Johnny Starr wrote:
The source code indicates that the ROM starts off at $F000 as its a 4K ROM.... However, I don't
see the memory address $F000 anywhere. What am I missing?
To verify the code actually starts at $F000, move to address $FFFC ($0FFC in the hex dump, which should be the last 4 bytes at the end). You should see the byte $00. At $FFFD, you should see the byte $F0. This is the 6502 reset vector and contains the jump-to address when the processor is reset. This is likely the only place in the hex dump you will find $F000, unless there is a error catching routine that would send you there.

Hope that answers this question.

Daryl