Mike Kohn's naken_asm
Re: Mike Kohn's naken_asm
All good points, the problem is that it doesn't know the difference between 01 and 0001, so this is the safer default route I think.
Before I had addresses below 256 use zp instructions, but that broke trying to index into the stack from zp because of the wrapping. I can probably add a directive of some sort (what would you call it?).
Before I had addresses below 256 use zp instructions, but that broke trying to index into the stack from zp because of the wrapping. I can probably add a directive of some sort (what would you call it?).
-
teamtempest
- Posts: 443
- Joined: 08 Nov 2009
- Location: Minnesota
- Contact:
Re: Mike Kohn's naken_asm
In my HXA assembler I decided to permit address mode forcing by use of an assembler directive called "ASSUME", rather than the usual method of "decorating" the expression with a sort of pseudo-operator. I did this partly because I imagined that HXA might be ported to other processors that had no use for address mode forcing, so I created the "ASSUME" directive as a handy place to put all processor-specific directives.
HXA evaluates all expressions as 32-bit, but in the case of the 65xx family compares the result to the mnemonic and tries to select the most appropriate bits out of that result to emit as code. "ASSUME" essentially tells HXA in advance which bits to select. It only applies to the next expression encountered, ie., for one line. So something like:
assembles as "BD FE 00" instead of "B5 FE".
So that's one way to do it. Plus I find it easier to read than expression decoration.
HXA evaluates all expressions as 32-bit, but in the case of the 65xx family compares the result to the mnemonic and tries to select the most appropriate bits out of that result to emit as code. "ASSUME" essentially tells HXA in advance which bits to select. It only applies to the next expression encountered, ie., for one line. So something like:
Code: Select all
.assume absolute
lda $FE,X
So that's one way to do it. Plus I find it easier to read than expression decoration.
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Mike Kohn's naken_asm
Hi teamtempest,
I find your method to be acceptable/agreeable. It wasn't a huge effort for you to implement that feature, was it?
Without getting into the gory details, would you mind explaining briefly, in general terms, how someone would go about doing something like this, for the benefit of all of us, including joe7?
Thanks,
Mike
I find your method to be acceptable/agreeable. It wasn't a huge effort for you to implement that feature, was it?
Without getting into the gory details, would you mind explaining briefly, in general terms, how someone would go about doing something like this, for the benefit of all of us, including joe7?
Thanks,
Mike
Re: Mike Kohn's naken_asm
You can always use macros to force an addressing mode:
Code: Select all
00fe = zp: equ $fe
ldax macro ;lda abs,x - forced abs
db $bd ;opcode
dw \1 ;absolute address
endm
0000 : b5fe lda zp,x
ldax zp
0002 : bd > db $bd ;opcode
0003 : fe00 > dw zp ;absolute address
6502 sources on GitHub: https://github.com/Klaus2m5
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Mike Kohn's naken_asm
BitWise wrote:
The WDC assembler (and mine) uses an address prefix character to force a particular mode. So |addr or !addr forces an absolute mode, <addr is always zero page and >addr is the 65816 long absolute. You can add the index suffixes after the address as usual (e.g |addr,X).
Very useful when you want to force a particular mode or if the assember can't work out the mode because the value is imported from a different relocatable module.
Very useful when you want to force a particular mode or if the assember can't work out the mode because the value is imported from a different relocatable module.
x86? We ain't got no x86. We don't NEED no stinking x86!
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Mike Kohn's naken_asm
joe7 wrote:
All good points, the problem is that it doesn't know the difference between 01 and 0001, so this is the safer default route I think.
Quote:
Before I had addresses below 256 use zp instructions, but that broke trying to index into the stack from zp because of the wrapping. I can probably add a directive of some sort (what would you call it?).
The default addressing mode for addresses below $100 really needs to be ZP, but there's nothing wrong with having an operator that forces abs for the rare occasions it might be needed.
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: Mike Kohn's naken_asm
It's been decades since I was actually paid to write 6502 assembly code, so in my naivety I feel I must ask: Why doesn't the assembler know the difference between 0001 and 01(or, rather, as I prefer: $0001 and $01)? Because back then the 6502 assembler I used did. If it's so that my memory isn't accurate about the 6502 assembler then certainly assemblers for other architectures I programmed back then and not as far back _did_ know the difference between $0001 and $01 and treated one as 16-bit and the other as 8-bit.
-Tor
-Tor
Re: Mike Kohn's naken_asm
Quote:
Now it sounds like you're trying to do negative indexing into the stack which is dangerous if you have interrupts, as they will overwrite values you wanted to read.
The default addressing mode for addresses below $100 really needs to be ZP, but there's nothing wrong with having an operator that forces abs for the rare occasions it might be needed.
The default addressing mode for addresses below $100 really needs to be ZP, but there's nothing wrong with having an operator that forces abs for the rare occasions it might be needed.
Quote:
It's been decades since I was actually paid to write 6502 assembly code, so in my naivety I feel I must ask: Why doesn't the assembler know the difference between 0001 and 01(or, rather, as I prefer: $0001 and $01)? Because back then the 6502 assembler I used did. If it's so that my memory isn't accurate about the 6502 assembler then certainly assemblers for other architectures I programmed back then and not as far back _did_ know the difference between $0001 and $01 and treated one as 16-bit and the other as 8-bit.
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Mike Kohn's naken_asm
GARTHWILSON wrote:
Now it sounds like you're trying to do negative indexing into the stack which is dangerous if you have interrupts, as they will overwrite values you wanted to read.
Mike
-
teamtempest
- Posts: 443
- Joined: 08 Nov 2009
- Location: Minnesota
- Contact:
Re: Mike Kohn's naken_asm
Quote:
Without getting into the gory details, would you mind explaining briefly, in general terms, how someone would go about doing something like this,
It's not really all that difficult if you stop to think about it. All "ASSUME [somemode]" really has to do is set a flag. Whenever an instruction mnemonic is processed, the flag is checked at some point to see if address forcing is active. Before the end of processing every mnemonic the flag is always cleared, so the forcing only applies for one line.
The implemention details come down to things like how many checks are made. For some time HXA has done it by first determining that the expression following a mnemonic describes a legal address mode for that mnemonic, then checking that any forcing is also legal.
The earliest versions checked only that the forced mode was legal for the particular mnemonic, which made it possible that an otherwise "illegal" mode (as determined by examining the expression) could be forced to a legal one. That eventually struck me as an undetected error that really ought to be, so I changed it.
BTW, I agree that address wrapping is the proper way to go on the 6502, but I wonder if the same behavior is necessary in systems where direct and stack pages are not necessarily adjacent. The C128 had (has?) hardware that could relocate them to arbitrary pages, for instance. I suppose there some advantage to consistent behavior, though!
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Mike Kohn's naken_asm
teamtempest wrote:
The C128 had (has?) hardware that could relocate them to arbitrary pages, for instance. I suppose there some advantage to consistent behavior, though!
Ditto for a relocated zero page. For example, a write to the page to which ZP had been relocated would end up in the physical ZP.
The C-128 relocation method isn't anything like relocating direct page or the stack with the 65C816, so in my mind it was a feature of limited value. I never did find a good use for it.
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: Mike Kohn's naken_asm
Ok, the current state of the project is that addresses 1-255 will use zp instructions again. However address 0 in particular cannot be resolved because on the first pass labels have an address of 0 also. Therefore, if address 0 is used it will default to abs, absx, absy modes and print a warning.
There is one other possible solution, during pass 2 it could change to zp instructions, and pad the instruction with a NOP. (Pass 1 and 2 must line up, or label addresses will be off..)
Fixed a couple of table problems which may have affected the disassembler/simulator. Have used the assembler extensively in recent weeks with no issues, but let me know if there is a problem.
Latest source here:
https://github.com/mikeakohn/naken_asm
There is one other possible solution, during pass 2 it could change to zp instructions, and pad the instruction with a NOP. (Pass 1 and 2 must line up, or label addresses will be off..)
Fixed a couple of table problems which may have affected the disassembler/simulator. Have used the assembler extensively in recent weeks with no issues, but let me know if there is a problem.
Latest source here:
https://github.com/mikeakohn/naken_asm
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Mike Kohn's naken_asm
joe7 wrote:
Ok, the current state of the project is that addresses 1-255 will use zp instructions again. However address 0 in particular cannot be resolved because on the first pass labels have an address of 0 also.
Quote:
There is one other possible solution, during pass 2 it could change to zp instructions, and pad the instruction with a NOP. (Pass 1 and 2 must line up, or label addresses will be off..)
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?
-
teamtempest
- Posts: 443
- Joined: 08 Nov 2009
- Location: Minnesota
- Contact:
Re: Mike Kohn's naken_asm
Quote:
However address 0 in particular cannot be resolved because on the first pass labels have an address of 0 also
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Mike Kohn's naken_asm
... or, if teamtempest's suggestions wind up taking more effort than you're willing to expend right now, how about $ffff for un-initialized labels? That way, un-initialized references in pass 1 would default to absolute, but zero-page would still be completely available, by simply equating before reference in the source. So your $00ff,x example could be implemented with L00FF,x throughout your code, and L00FF = 0xff at the end of your source.
You're laying the op-codes down during the first pass, right?
I'm not a fan of the NOP idea, for the same reasons stated by Garth.
Mike
You're laying the op-codes down during the first pass, right?
I'm not a fan of the NOP idea, for the same reasons stated by Garth.
Mike