It is currently Wed Dec 13, 2017 7:46 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 51 posts ]  Go to page 1, 2, 3, 4  Next
Author Message
PostPosted: Mon Nov 18, 2013 11:05 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19342
Location: NE Indiana, USA (NTSC)
The ca65 assembler comes with a setting for no mnemonics (.setcpu "none") and a rich macro system. I plan to use this to reimplement 6502 instruction syntax the hard way, making each instruction a macro that outputs .byte and .word instructions. You might wonder why one would try this, given that ca65 already supports the 6502. I intend for it to act as an example of how ca65 would be adapted to other instruction sets, such as Z80, GBZ80, SPC700, and MC68000, without a recompile. Or 6502/65816 using x86-style mnemonics (hello nocash) or SPC700 or MC68000 using 6502-style mnemonics (hi byuu).

I started the project yesterday, and I've already got the ALU block (%xxxxxx01) done along with bits and pieces of the control block (%xxxxxx00) and the unofficial RMW+ALU combined block (%xxxxxx11). The biggest hurdle I've found so far is in branches, to determine whether the distance to a future label is more than 129 bytes. The long branch macro pack that comes with ca65 just punts on the issue, making all forward branches long.


Top
 Profile  
 
PostPosted: Mon Nov 18, 2013 12:07 pm 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
ca65 normally chokes on branches that are too far. It is one-pass, so I don't think you can do much about that.

I was interested in .feature ubiquitous_idents documented here: http://www.cc65.org/snapshot-doc/ca65-11.html#ss11.42

It says it allows overloading, but it seems to do the same thing as .setcpu "none"
For your goal, maybe it is worth looking at the C source?


Top
 Profile  
 
PostPosted: Mon Nov 18, 2013 12:43 pm 
Offline
User avatar

Joined: Fri Nov 19, 2004 7:35 pm
Posts: 3968
ASM6 was a three-pass assembler just because of the variable lengths of instructions. Variable length instructions screw over any assembler.

_________________
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!


Top
 Profile  
 
PostPosted: Mon Nov 18, 2013 1:19 pm 
Offline
User avatar

Joined: Wed Oct 15, 2008 11:50 am
Posts: 939
Wow, that certainly is meta Tepples :) I can see how with such a system in place you could develop a very tightly integrated HLA package.


Top
 Profile  
 
PostPosted: Mon Nov 18, 2013 1:42 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19342
Location: NE Indiana, USA (NTSC)
Movax12 wrote:
ca65 normally chokes on branches that are too far.

So if I'm coding a branch's signed relative operand as a .byte, how do I express to ca65 that it is a branch so that it can choke only when too far instead of choking with "Constant expression expected" on every forward branch? Remember that the branch opcodes in one or more of the CPUs that I plan to support aren't necessarily the same values as on a 6502. For example, how would I tell ca65 to range-check forward BBC and BBS (in the x3 column of the SPC700 opcode matrix) branches?

qbradq wrote:
I can see how with such a system in place you could develop a very tightly integrated HLA package.

That's sort of what Movax12's IF macro package is supposed to do.


Top
 Profile  
 
PostPosted: Mon Nov 18, 2013 1:52 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Tepples, if I understand you right, you want to encode a signed byte containing the difference between two addresses, and want an error when the difference can't be represented in a signed byte. If so, can you just put a .if that checks this condition? As I remember, ca65 allows almost anything in a .if, and its evaluation is deferred until link time.


Top
 Profile  
 
PostPosted: Mon Nov 18, 2013 2:52 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19342
Location: NE Indiana, USA (NTSC)
blargg wrote:
Tepples, if I understand you right, you want to encode a signed byte containing the difference between two addresses, and want an error when the difference can't be represented in a signed byte.

Correct. An explicit check with .if works for backward references, but not for forward references. As far as I can tell, the only forward references that get range-checked in this way are the branch instructions of the assembler's predefined instruction sets.

Quote:
As I remember, ca65 allows almost anything in a .if, and its evaluation is deferred until link time.

I thought .if required a constant expression. From the manual:
Quote:
An expression used in the .IF command cannot reference a symbol defined later, because the decision about the .IF must be made at the point when it is read.


Top
 Profile  
 
PostPosted: Mon Nov 18, 2013 3:15 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2982
Location: Tampere, Finland
tepples wrote:
blargg wrote:
Tepples, if I understand you right, you want to encode a signed byte containing the difference between two addresses, and want an error when the difference can't be represented in a signed byte.

Correct. An explicit check with .if works for backward references, but not for forward references. As far as I can tell, the only forward references that get range-checked in this way are the branch instructions of the assembler's predefined instruction sets.

Quote:
As I remember, ca65 allows almost anything in a .if, and its evaluation is deferred until link time.

I thought .if required a constant expression. From the manual:
Quote:
An expression used in the .IF command cannot reference a symbol defined later, because the decision about the .IF must be made at the point when it is read.

Try using .assert. If needed, its evaluation will be deferred until link time.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Mon Nov 18, 2013 3:22 pm 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
Yes; if you are looking to output friendly errors, rather than solve forward branching, you can do so with an .assert statement.


Top
 Profile  
 
PostPosted: Mon Nov 18, 2013 3:39 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
I'm having a lapse because I'm not imagining the problem with this:
Code:
.byte target-*
...
target:

That encodes the branch offset, then you use an assert to verify that it's in range.


Top
 Profile  
 
PostPosted: Mon Nov 18, 2013 4:13 pm 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
I think that should work.


Top
 Profile  
 
PostPosted: Mon Nov 18, 2013 5:43 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19342
Location: NE Indiana, USA (NTSC)
Thanks Movax12 and blargg. This is what I came up with so far for branches:
Code:
.macro NONE02_branch inst, target
  .local distance
  distance = (target) - (* + 2)
  .assert distance >= -128 && distance <= 127, error, "branch out of range"
  .byte inst, <distance
.endmacro

.macro bpl target
  NONE02_branch $10, {target}
.endmacro

.macro bmi target
  NONE02_branch $30, {target}
.endmacro


Right now I'm 25% of the way through the opcode matrix. I'll upload it for all of you to bang on once I reach ISC $FFFF,x.


Last edited by tepples on Mon Nov 18, 2013 7:33 pm, edited 2 times in total.
75%


Top
 Profile  
 
PostPosted: Mon Nov 18, 2013 5:51 pm 
Offline
User avatar

Joined: Sun Jan 02, 2011 11:50 am
Posts: 522
I was considering doing this with my macro code, since I like to represent code like this:
Code:
lda foo+$10,x

as:
Code:
lda foo[ $10 + x]


So I would be interested to know what the performance ends up being like when building a large project. I might look into doing the same thing. Or borrowing your code, tepples. I felt this would be better implemented in source code as an alternative branch of ca65, but if performance is okay, there is no need.


Top
 Profile  
 
 Post subject: Sun++
PostPosted: Mon Nov 18, 2013 8:25 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19342
Location: NE Indiana, USA (NTSC)
I started this project for at least two reasons.

One is that I wanted to see what other 8- and 16-bit assembly languages would look like in 6502 drag. I have an idea of how to do 68K, and it starts by renaming D0-D7 to A-H and A0-A7 to Z-S. This preserves Y (A1) and X (A2) as performing indexing-related operations, and S is conveniently the stack pointer.

The other is that I'm following up on my promise from two years ago. I didn't want to have to require people who build on my libraries to install both ca65 and bass for Super NES projects, and I thought there'd be resistance to implementing other 8- and 16-bit CPUs' assembly languages directly in the source code of ca65. I found a bunch of mentions of a Sunplus CPU whose instruction set is "proprietary and confidential". SPC doesn't stand for "Sunplus chip", does it? Did Sony and Sunplus collaborate?


Attachments:
ca65none.s.zip [3.28 KiB]
Downloaded 104 times
Top
 Profile  
 
PostPosted: Mon Nov 18, 2013 9:43 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
Wow, this is going to be real. I had taken a stab a while back at gb-z80 but got hung up on the foundation macros. I hope we can get gb-z80 and spc-700 into this. No more assembler cocktail.
Code:
.macro nop
  .byte $EA  ; If it's in the game, it's in the game.
.endmacro

Took me a moment. When I was little and saw $EA in disassemblies on the Apple //, I thought it was because it was an EA game and they plastered their initials in unused areas of memory.

EDIT: gave this a try and it assembled its test opcodes so well I had to try it on my library code and a test. After lots of fixes it assembled it as-is and ran fine. It looks like the only issue was that variables in the .zp segment used absolute addressing. I'm seeing whether there is a way to determine this in a macro.

A few places needed an additional .const condition to avoid trying to compare a non-constant.

Many places needed @ prefixes on the .local symbols (you'd think that .local was enough), otherwise they broke @ symbols in the using code. I only changed those needed to compile my code, so there are more (I tried a global search-and-replace, but got some weird errors so backed off).

Very impressed!


Attachments:
File comment: Partly fixed, removed opcode tests so it was usable in real code
ca65none.s.zip [2.16 KiB]
Downloaded 106 times


Last edited by blargg on Mon Nov 18, 2013 10:33 pm, edited 1 time in total.
Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 51 posts ]  Go to page 1, 2, 3, 4  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 4 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:  
Powered by phpBB® Forum Software © phpBB Group