CA65: how to get a simple one file binary for a EEPROM/Flash

Programming the 6502 microprocessor and its relatives in assembly and other languages.
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: CA65: how to get a simple one file binary for a EEPROM/F

Post by drogon »

willie68 wrote:
As you can easily see, the individual jumps are not continuously connected. If I now specify the segment for the table, the 1st jump is placed correctly, but the others specified with .org are not. However, everything is correct in the list file. So I suspect that the linker is not configured correctly here. How do I set this up correctly?
I think that part of the issue (and I use cc65/ca65 myself) is that the suite is really intended to be used with a "loader" much like a typical unix-like system where the linker does the job of producing a loadable file that still contains relocation and symbol information, so the loader can then read this information, process it and place the code and data where its intended to go.

When we ask ld65 to make an object file with a command like:

Code: Select all

ld65 -t none -S 0xC000 -vm -m rubyOs.map -o rubyOs $(OBJ)
Then it just lumps it together in one big binary blob without padding between different .org statements. At least this is my
experience, so I live with it and don't have the scenario you describe.

I suspect you might need to not generate a binary blob output file, but generate something that can then be post-processed (by something you'll need to write) to produce the final binary and pad out the gaps.

If you do, please let us know how you solved it.

-Gordon
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
User avatar
willie68
Posts: 54
Joined: 27 Jul 2022
Contact:

Re: CA65: how to get a simple one file binary for a EEPROM/F

Post by willie68 »

it's all because the object code, generated by the assembler, is relocatable. So the linker will than put the code to the right place. But the linker doesn't have the information about the .org directrieve and put the code together, so that later the loader programm on the target machine can pick that apart.
As far as i understand the comment of ProxyPlayerHD (https://github.com/cc65/cc65/issues/184 ... 1228303415) for such a jumpt table you have to fill the gaps in the jumptable with $00 or whatever, example:

Code: Select all

.res 129, $EA

I think i will stick to retroassembler than, because that is more in line with my way of working.
don't count on me, i'm engineer (Animotion)
my arduino pages: http://rcarduino.de
tmr4
Posts: 147
Joined: 19 Feb 2022

Re: CA65: how to get a simple one file binary for a EEPROM/F

Post by tmr4 »

willie68 wrote:
I think i will stick to retroassembler than, because that is more in line with my way of working.
It was the same for me when I switched to ca65 from Retro Assembler, where I also managed code placement with the org directive. I found that letting the ca65 linker handle code placement with segments to be less hassle though for larger projects.

A bug in Retro Assembler ultimately pushed me to ca65. Retro Assembler has an error in resolving the zero page address mode of some instructions if a zero page label is used before it is defined. This is much more likely to occur if your project has multiple files. It appears that on its second pass Retro Assembler corrects the instruction to use the zero page address mode (2 byte instruction vs 3 bytes) but doesn’t adjust the addresses of any labels that were defined after that point in the code.

It took me quite a bit of troubleshooting to find the problem. The Retro Assembler documentation does have a note about defining zero page labels before they’re used but only in reference to having faster code execution with zero page addressing. I think a warning of label used before defined is appropriate at the minimum.

Retro Assembler has been updated once since I switched, so maybe this has been addressed but not noted in the change log.
resman
Posts: 154
Joined: 12 Dec 2015
Location: Lake Tahoe
Contact:

Re: CA65: how to get a simple one file binary for a EEPROM/F

Post by resman »

If you're still interested in using ca65 for your ROM code, you have to use fill bytes to align the addresses, .org will only update the address where the current assembly is generated. Here is how I did it for the ROM code for Apple2Pi: https://github.com/dschmenk/apple2pi/tr ... er/pidrive

Look at the master source file pirom.s and configuration file pirom.cfg in that project directory. Basically, fill from the current address to the destination address (and double check that it is the correct address with .ASSERT):

Code: Select all

;****************************************
;*
;*      PER-SLOT ROM @ $Cx00
;*
;****************************************
	ORG	$C000
; Note: the actual SLOT INDEPENDENT ROM CODE is included 8 times, changing some defines each time. Look at pirom.s
;****************************************
;*
;*   SLOT INDEPENDENT ROM CODE @ $Cn00
;*
;****************************************
CXSLOT	EQU	*
...Code that must be 250 bytes or less goes here

Code: Select all

	.REPEAT CXSLOT+250-*
	DB	$00
	.ENDREP
	DB	SIG		; SIGNATURE
	DW	0		; USE STATUS TO GET SIZE
	DB	$97		; REMOVEABLE, 2 DEVICES, R/W
	DB	<CMDENTRY

;****************************************
;*
;*      OPTION ROM SPACE @ $C800
;*
;****************************************
	.ASSERT	* = $C800, error, "Slot ROM not page aligned"
;	ORG	$C800

	.INCLUDE "c8rom.s"
;*
;* FILL REMAINING ROM WITH 0'S
;*
	.REPEAT $D000-*
	DB	$00
	.ENDREP
	.ASSERT	* = $D000, error, "Code not page size"
User avatar
willie68
Posts: 54
Joined: 27 Jul 2022
Contact:

Re: CA65: how to get a simple one file binary for a EEPROM/F

Post by willie68 »

That was the solution the developer came up,too. But for me as a minimalist this is not handy enough. Maybe this is a good approach for the C Compiler, but for me as a human doing calculations is something I want to avoid. Computer are better in calculations. And as there are other assemblers out there with better support for humans and IDEs (retroassembler can do this very well and has a extension for VS Code) I'm no longer interested in CA65. Maybe later, when I switch doing things in C...
@tmr4: thanks for the hint, good to know...
At the moment all used addresses are defined in the main file or a separated file loaded just before starting the code.
don't count on me, i'm engineer (Animotion)
my arduino pages: http://rcarduino.de
User avatar
BigEd
Posts: 11463
Joined: 11 Dec 2008
Location: England
Contact:

Re: CA65: how to get a simple one file binary for a EEPROM/F

Post by BigEd »

It looks like the use of .REPEAT and a check with .ASSERT should get the macro processor to do the calculation for the number of DB statements.
resman
Posts: 154
Joined: 12 Dec 2015
Location: Lake Tahoe
Contact:

Re: CA65: how to get a simple one file binary for a EEPROM/F

Post by resman »

I won't lie, I switched all my assembly only projects to acme. It is definitely easier to deal for single file projects. I was only providing a solution using ca65, not that it would be my preference, either.
User avatar
willie68
Posts: 54
Joined: 27 Jul 2022
Contact:

Re: CA65: how to get a simple one file binary for a EEPROM/F

Post by willie68 »

.
don't count on me, i'm engineer (Animotion)
my arduino pages: http://rcarduino.de
User avatar
willie68
Posts: 54
Joined: 27 Jul 2022
Contact:

Re: CA65: how to get a simple one file binary for a EEPROM/F

Post by willie68 »

yeah, found it:

main.asm:

Code: Select all

loop2
    lda #$20
    cmp #$20
    bne loop2

lda #$20
sta COUNTER
lda #$40
sta $20

loop1 
    lda #$20
    cmp #$20
    bne loop1

.include "zp_def.asm"
zp_def.asm

Code: Select all

COUNTER .equ $20
generated code:
$0800 a9 20 lda #$20
$0802 c9 20 cmp #$20
$0804 d0 fa bne $0800
$0806 a9 20 lda #$20
$0808 85 20 sta $20
$080a a9 40 lda #$40
$080c 85 20 sta $20
$080e a9 20 lda #$20
$0810 c9 20 cmp #$20
$0812 d0 fb bne $080f

fb should be fa
don't count on me, i'm engineer (Animotion)
my arduino pages: http://rcarduino.de
Post Reply