Figured I'd make an informational post since I had to piece this together from documentation and just some plain old experimentation. Sim65 is the 6502 simulator packaged with the cc65 development suite, and at least in my experience, a tad bit more tinkering was required than just what is described at https://cc65.github.io/doc/sim65.html to get a working test built using just asm.
So to start, the linker script is found at /usr/share/cc65/cfg/sim6502.cfg on my install, local install paths may vary. This configuration is requested by passing "-t sim6502" on the linker command line. This is documented above, but what I found I needed to also do is include the sim6502.lib file for, among other things, the "exit" routine described therein.
Additionally, the documentation indicates that a 12 byte header is needed to properly assemble a test case, but doesn't indicate directly that this must be in a segment "EXEHDR" and labeled "__EXEHDR__". Attempting to link without this will spit out the necessary warning and error about the missing segment and missing export respectively. In addition, suggested, but not required, is that the main entry point should be in a "STARTUP" segment.
Pulling it all together, a minimal test that actually assembles, links, and runs correctly looks something like:
Presuming this is named test.s, the command lines
Should return whatever value is set at "status".
This was a little tricky for a few reasons. The documentation describes the header format, but does not note that you have to create this header yourself nor what segment and label it must be created under. Perhaps this is to be gleaned from documentation of other parts of the cc65 toolchain, but in any case, isn't included right there in the sim65 documentation. Additionally the target does require inclusion of the library explicitly. I'm not sure if it's common practice to include a <foo>.lib any time you request "-t <foo>" with ld65, but in any case, this step is crucial to getting the exit routine in place. The documentation implies you can also just return from _main and the byte in the accumulator will be your return value, but if I don't use exit, I get an illegal opcode error instead. Not sure if this implies the linking above also expects you to manually go pull a crt0 in, but in any case, it isn't clear from the sim65 documentation alone.
Just to review, to use this in the narrowest sense:
So to start, the linker script is found at /usr/share/cc65/cfg/sim6502.cfg on my install, local install paths may vary. This configuration is requested by passing "-t sim6502" on the linker command line. This is documented above, but what I found I needed to also do is include the sim6502.lib file for, among other things, the "exit" routine described therein.
Additionally, the documentation indicates that a 12 byte header is needed to properly assemble a test case, but doesn't indicate directly that this must be in a segment "EXEHDR" and labeled "__EXEHDR__". Attempting to link without this will spit out the necessary warning and error about the missing segment and missing export respectively. In addition, suggested, but not required, is that the main entry point should be in a "STARTUP" segment.
Pulling it all together, a minimal test that actually assembles, links, and runs correctly looks something like:
Code:
.segment "EXEHDR" .export __EXEHDR____EXEHDR__: .byte "sim65"; magic number .byte 2; simulator version: 2 = current .byte 0; CPU version: 0 = 6502, 1 = 65c02 .byte $FF; initial SP .addr _main ; load address .addr _main ; start address (these are the same if _main is first in STARTUP) .segment "STARTUP" .export _main_main: lda status jmp exit .segment "RODATA" .export statusstatus: .byte 0
Code:
ca65 -U -o test.o test.sld65 -t sim6502 -o test.bin test.o sim6502.libsim65 test.binecho $?
This was a little tricky for a few reasons. The documentation describes the header format, but does not note that you have to create this header yourself nor what segment and label it must be created under. Perhaps this is to be gleaned from documentation of other parts of the cc65 toolchain, but in any case, isn't included right there in the sim65 documentation. Additionally the target does require inclusion of the library explicitly. I'm not sure if it's common practice to include a <foo>.lib any time you request "-t <foo>" with ld65, but in any case, this step is crucial to getting the exit routine in place. The documentation implies you can also just return from _main and the byte in the accumulator will be your return value, but if I don't use exit, I get an illegal opcode error instead. Not sure if this implies the linking above also expects you to manually go pull a crt0 in, but in any case, it isn't clear from the sim65 documentation alone.
Just to review, to use this in the narrowest sense:
- Add an EXEHDR segment with an __EXEHDR__ label followed by the data described in Section 5
- Place _main first in the STARTUP segment (or ensure the load address is the first symbol loaded into the MAIN memory segment)
- Ensure that main exits with a "jmp exit" with desired return value in a
- Include sim6502.lib in the linker call
Statistics: Posted by segaloco — Wed Mar 27, 2024 9:53 pm — Replies 4 — Views 169