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:
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
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:
(*) 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
I was reviewing a hexdump of the Pitfall! binary...
I see where Ed addressed the endianess issue.
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
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
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