Questions about 6502 assemblers
Re: Questions about 6502 assemblers
Oh, I see. Yes, if you implement your assembler as a series of transformations, it might well make sense to transform all values into decimal strings. (There's an amusingly extreme historical precedent, IBM's 63-pass Fortran compiler.)
Re: Questions about 6502 assemblers
Ok, thanks!
I just realized that I may encounter some problems with the labels.
Let's say I'm trying to assemble this piece of code:
lda could either be a 1 byte instruction or a 2 bytes instruction depending on wether label is a zeropage address or not.
I have to determine the address of "label" to know the length of the instruction. But to so I have to know the length of the instruction.
It's kind of problematic.
I just realized that I may encounter some problems with the labels.
Let's say I'm trying to assemble this piece of code:
Code: Select all
lda label
...
label:
...
I have to determine the address of "label" to know the length of the instruction. But to so I have to know the length of the instruction.
It's kind of problematic.
Re: Questions about 6502 assemblers
secamline wrote:
Ok, thanks!
I just realized that I may encounter some problems with the labels.
Let's say I'm trying to assemble this piece of code:
lda could either be a 1 byte instruction or a 2 bytes instruction depending on wether label is a zeropage address or not.
I have to determine the address of "label" to know the length of the instruction. But to so I have to know the length of the instruction.
It's kind of problematic.
I just realized that I may encounter some problems with the labels.
Let's say I'm trying to assemble this piece of code:
Code: Select all
lda label
...
label:
...
I have to determine the address of "label" to know the length of the instruction. But to so I have to know the length of the instruction.
It's kind of problematic.
Code: Select all
000000r 1
000000r 1 .org $FC
0000FC 1 AD FF 00 lda label
0000FF 1 00 label: .byte 0
000100 1
000100 1 .org $FD
0000FD 1 AD 00 01 lda label2
000100 1 00 label2: .byte 0
000100 1 Code: Select all
foo.s(3): Warning: Didn't use zeropage addressing for 'label'-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Questions about 6502 assemblers
When you write the code, you'll normally put ZP assignments before the code that uses them; so that code will know, on first pass, that they're only 8-bit addresses.
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: Questions about 6502 assemblers
So if an instruction other than a branching condition happens to contain a label, I can just treat it as an absolute address. What a relief!
By the way, I've already started rewriting the code from scratch. I replaced the regex dictionnary with a new "Instruction" class that parses the opcode, the operand (or the label if we only want to get the instruction's size) and the addressing mode (represented by an arbitrary numerical constant). Then I guess I can simply use the opcode and the addressing mode to fetch the actual instruction number in a list or a dictionnary.
I hope I've done things the right way this time.
By the way, I've already started rewriting the code from scratch. I replaced the regex dictionnary with a new "Instruction" class that parses the opcode, the operand (or the label if we only want to get the instruction's size) and the addressing mode (represented by an arbitrary numerical constant). Then I guess I can simply use the opcode and the addressing mode to fetch the actual instruction number in a list or a dictionnary.
I hope I've done things the right way this time.
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Questions about 6502 assemblers
secamline wrote:
So if an instruction other than a branching condition happens to contain a label, I can just treat it as an absolute address. What a relief!
Yes, the vast majority of the cases should be pretty simple in that regard. If there really is no way for the assembler to know, on first pass, whether to do the absolute or ZP version, and it happens to get it wrong, it will find phase errors when it does the second pass, and it should do a third pass to resolve them (or as many passes as necessary).
Quote:
By the way, I've already started rewriting the code from scratch. I replaced the regex dictionary with a new "Instruction" class that parses the opcode, the operand (or the label if we only want to get the instruction's size) and the addressing mode (represented by an arbitrary numerical constant). Then I guess I can simply use the opcode and the addressing mode to fetch the actual instruction number in a list or a dictionary.
I'm not sure what you mean here. The op code is the two-digit hex number that tells the instruction and the addressing mode. Maybe you meant "parses the mnemonic," rather than the op code? The mnemonic is the three-letter abbreviation for the instruction. (Other processors have differing numbers of letters, or even varying numbers of letters, like PIC's BSF, CALL, MOVLW, CLRWDT, etc., different lengths.) The parser will need to be able to figure out the addressing mode from things like # (for immediate), parentheses (for indirects), and a comma (for indexing), with also the ability to figure out other things that may need to be computed such as adding to an array's base address
Code: Select all
LDA table + $10Code: Select all
LDY # SomeAddress & $FFIt will also need to be able to figure out assembler directives, like EQUates, ORiGin (ie, what address the subsequent code will start at), laying down strings or data bytes or words, reserving a specified number of bytes for data not yet known, etc..
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Questions about 6502 assemblers
secamline wrote:
Ok, thanks!
I just realized that I may encounter some problems with the labels.
Let's say I'm trying to assemble this piece of code:
lda could either be a 1 byte instruction or a 2 bytes instruction depending on wether label is a zeropage address or not.
I have to determine the address of "label" to know the length of the instruction. But to so I have to know the length of the instruction.
It's kind of problematic.
I just realized that I may encounter some problems with the labels.
Let's say I'm trying to assemble this piece of code:
Code: Select all
lda label
...
label:
...
I have to determine the address of "label" to know the length of the instruction. But to so I have to know the length of the instruction.
It's kind of problematic.
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: Questions about 6502 assemblers
secamline wrote:
Ok, thanks!
Code: Select all
lda label
...
label:
...
There's another catch:
Code: Select all
lda label
...
label = 10
Your method of replacing the text of a label with the text of its value could make this difficult. My previous assemblers always have a struct for labels, with flags carrying information like this: is the value known? was the value assumed to be 16 bit? On the first pass, a use of an undefined label will create a struct with the value marked as unknown. When it gets defined later, that struct gets updated instead of creating a new one. On the second pass, all labels that are used must have known values; using one that's undefined or unknown is an error.
My current assembler has to take a more complicated approach, which Garth described earlier in the thread: allow instructions to change size when more information becomes available, and keep repeating passes until things stop changing. I had to do it this way, as this assembler is for an extension of the 6502 that has branches with one and two byte offsets. You really want short forward branches to use the small offset, and it's not possible to insist that the destination label be defined before the instruction that uses it.
It's possible to set up a situation where these changes oscillate and it will never reach stability. To avoid that, each decision can be changed in only one direction: I start by assuming that every operand is one byte, and if one pass sees a value that won't fit in a byte, that instruction gets switched to a two byte operand. But it can never switch back. That has worked well.
But as I said, I only did it this way because I had to. A simpler assembler for a simpler CPU can get away with two passes, insisting that the label has to be defined first if you want zero page.
Re: Questions about 6502 assemblers
Quote:
It's possible to set up a situation where these changes oscillate and it will never reach stability. To avoid that, each decision can be changed in only one direction: I start by assuming that every operand is one byte, and if one pass sees a value that won't fit in a byte, that instruction gets switched to a two byte operand. But it can never switch back. That has worked well.
Re: Questions about 6502 assemblers
So far I'm back to where I stopped when using regex, the assembler does work with all addressing modes, decimal, hex, binary, and the labels are resolved correctly. You've all submitted many ideas, now where should I start? I guess I should implement the basic "org", "db" and "dw" pseudo instructions.