Page 1 of 1

Weird Assembler Issue

Posted: Tue Jan 13, 2026 1:56 am
by kellymcdonald78
Had my "Hello World", code running successfully the other day. Added some additional functionality to initialize my ACIA and output data to the serial port. However now my assembled hex dump doesn't seem to make sense. I normally start things off by setting the stack pointer LDX #FF and STX opcode, but for some reason my rom file keeps starting with $9C (which is STZ). I comment out my stack code and re-assemble (including deleting my old .bin and doing a make clean) and no change.

I'm using dhirsch1138's c65 container running under Docker Desktop

Re: Weird Assembler Issue

Posted: Tue Jan 13, 2026 6:19 am
by barnacle
Can you show a list file?

(And did you mean 'TXS'?)

Neil

Re: Weird Assembler Issue

Posted: Tue Jan 13, 2026 4:12 pm
by kellymcdonald78
;PURPOSE - This is the code which will written to ROM at $0000 (but will be referenced as $8000)
;
;
;The first difference we'll see is the inclusion of other source files (note they do not have .s extensions, we do not want
;them assembled as their own objects).
; ca65 documentation: https://cc65.github.io/doc/ca65.html#ss11.66
;
;Include the via import file (defining the imports there and keeping this source clean)
.include "via.s_imports"
;Include the acia (serial) import file
.include "acia.s_imports"
;Include the reset and interrupt vector definitions
.include "reset.s_interrupts"
.include "lcd.s_imports"


.code


setmode:
ldx #$FF
txs

clc ; Clear carry to set addition mode
xce ; Switch to native mode
sei ; Disable interrupts
cld ; Clear decimal mode
; Now in native mode with interrupts disabled and stack set


sep #%00110000 ; Set to 8-bit accumulator and index registers


jsr via_init ;Initialize VIA
jsr acia_init ;Initialize ACIA (serial)
jsr lcd_init ;Initialize LCD
jsr print_hello ;Print "Hello, World!" to the LCD




main:
nop ; dummy instruction
nop ; dummy instruction
nop ; dummy instruction
lda #'H'
jsr acia_putchar
jmp main ; Infinite loop to keep the program running;

00000000 9c 91 7f a9 1a 8d 93 7f a9 19 8d 92 7f 60 aa 8e |.............`..|
00000010 90 7f 84 ff 88 d0 fd 60 a9 08 2c 91 7f f0 fb ad |.......`..,.....|
00000020 90 7f 60 18 fb 78 d8 e2 30 20 3b 81 20 00 80 20 |..`..x..0 ;. .. |
00000030 82 80 20 40 80 ea ea ea a9 48 20 0e 80 4c 35 80 |.. @.....H ..L5.|
00000040 a9 48 20 c1 80 a9 65 20 c1 80 a9 6c 20 c1 80 a9 |.H ...e ...l ...|
00000050 6c 20 c1 80 a9 6f 20 c1 80 a9 2c 20 c1 80 a9 20 |l ...o ..., ... |
00000060 20 c1 80 a9 57 20 c1 80 a9 6f 20 c1 80 a9 72 20 | ...W ...o ...r |
00000070 c1 80 a9 6c 20 c1 80 a9 64 20 c1 80 a9 21 20 c1 |...l ...d ...! .|
00000080 80 60 a9 01 20 97 80 a9 38 20 97 80 a9 0f 20 97 |.`.. ...8 .... .|
00000090 80 a9 06 20 97 80 60 48 20 12 81 fa ad 81 7f 29 |... ..`H ......)|
000000a0 f8 8d 81 7f 8e 80 7f a2 ff 8e 82 7f 09 01 8d 81 |................|
000000b0 7f 29 f8 8d 81 7f a9 00 8d 80 7f a9 ff 8d 82 7f |.)..............|
000000c0 60 48 20 12 81 fa ad 81 7f 29 fc 09 04 8d 81 7f |`H ......)......|
000000d0 8e 80 7f a2 ff 8e 82 7f 09 05 8d 81 7f 29 f8 8d |.............)..|
000000e0 81 7f a9 00 8d 80 7f a9 ff 8d 82 7f 60 ad 81 7f |............`...|
000000f0 a9 00 8d 82 7f 29 fa 09 02 8d 81 7f 09 03 8d 81 |.....)..........|
00000100 7f ae 81 7f 29 f8 8d 81 7f 8a 29 7f a2 ff 8e 82 |....).....).....|
00000110 7f 60 ae 81 7f 8a a9 00 8d 82 7f 29 fa 09 02 8d |.`.........)....|
00000120 81 7f 09 03 8d 81 7f aa ad 80 7f 89 80 d0 e6 8a |................|
00000130 29 f8 8d 81 7f a9 ff 8d 82 7f 60 a9 00 8d 81 7f |).........`.....|
00000140 a9 00 8d 80 7f a9 ff 8d 83 7f a9 ff 8d 82 7f a9 |................|
00000150 cc 8d 8c 7f 60 00 00 00 00 00 00 00 00 00 00 00 |....`...........|
00000160 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|

Re: Weird Assembler Issue

Posted: Tue Jan 13, 2026 8:06 pm
by BigDumbDinosaur
kellymcdonald78 wrote:
;PURPOSE - This is the code which will written to ROM at $0000 (but will be referenced as $8000)...
When inserting code into your post, you can use CODE tags to force the text to monospace, like this:

Code: Select all

;
;
;The first difference we'll see is the inclusion of other source files (note they do not have .s extensions, we do not want
;them assembled as their own objects). 
; ca65 documentation: https://cc65.github.io/doc/ca65.html#ss11.66
;
;Include the via import file (defining the imports there and keeping this source clean)
.include "via.s_imports"
;Include the acia (serial) import file 
.include "acia.s_imports"
;Include the reset and interrupt vector definitions
.include "reset.s_interrupts"
.include "lcd.s_imports"


.code


setmode:
    ldx #$FF
    txs
   
    clc             ; Clear carry to set addition mode  
    xce             ; Switch to native mode
    sei             ; Disable interrupts
    cld             ; Clear decimal mode
    ; Now in native mode with interrupts disabled and stack set


    sep #%00110000  ; Set to 8-bit accumulator and index registers


    jsr via_init    ;Initialize VIA
    jsr acia_init   ;Initialize ACIA (serial)
    jsr lcd_init    ;Initialize LCD
    jsr print_hello ;Print "Hello, World!" to the LCD
   



main:
    nop ; dummy instruction
    nop ; dummy instruction
    nop ; dummy instruction
    lda #'H'
    jsr acia_putchar
    jmp main ; Infinite loop to keep the program running;

00000000  9c 91 7f a9 1a 8d 93 7f  a9 19 8d 92 7f 60 aa 8e  |.............`..|
00000010  90 7f 84 ff 88 d0 fd 60  a9 08 2c 91 7f f0 fb ad  |.......`..,.....|
00000020  90 7f 60 18 fb 78 d8 e2  30 20 3b 81 20 00 80 20  |..`..x..0 ;. .. |
00000030  82 80 20 40 80 ea ea ea  a9 48 20 0e 80 4c 35 80  |.. @.....H ..L5.|
00000040  a9 48 20 c1 80 a9 65 20  c1 80 a9 6c 20 c1 80 a9  |.H ...e ...l ...|
00000050  6c 20 c1 80 a9 6f 20 c1  80 a9 2c 20 c1 80 a9 20  |l ...o ..., ... |
00000060  20 c1 80 a9 57 20 c1 80  a9 6f 20 c1 80 a9 72 20  | ...W ...o ...r |
00000070  c1 80 a9 6c 20 c1 80 a9  64 20 c1 80 a9 21 20 c1  |...l ...d ...! .|
00000080  80 60 a9 01 20 97 80 a9  38 20 97 80 a9 0f 20 97  |.`.. ...8 .... .|
00000090  80 a9 06 20 97 80 60 48  20 12 81 fa ad 81 7f 29  |... ..`H ......)|
000000a0  f8 8d 81 7f 8e 80 7f a2  ff 8e 82 7f 09 01 8d 81  |................|
000000b0  7f 29 f8 8d 81 7f a9 00  8d 80 7f a9 ff 8d 82 7f  |.)..............|
000000c0  60 48 20 12 81 fa ad 81  7f 29 fc 09 04 8d 81 7f  |`H ......)......|
000000d0  8e 80 7f a2 ff 8e 82 7f  09 05 8d 81 7f 29 f8 8d  |.............)..|
000000e0  81 7f a9 00 8d 80 7f a9  ff 8d 82 7f 60 ad 81 7f  |............`...|
000000f0  a9 00 8d 82 7f 29 fa 09  02 8d 81 7f 09 03 8d 81  |.....)..........|
00000100  7f ae 81 7f 29 f8 8d 81  7f 8a 29 7f a2 ff 8e 82  |....).....).....|
00000110  7f 60 ae 81 7f 8a a9 00  8d 82 7f 29 fa 09 02 8d  |.`.........)....|
00000120  81 7f 09 03 8d 81 7f aa  ad 80 7f 89 80 d0 e6 8a  |................|
00000130  29 f8 8d 81 7f a9 ff 8d  82 7f 60 a9 00 8d 81 7f  |).........`.....|
00000140  a9 00 8d 80 7f a9 ff 8d  83 7f a9 ff 8d 82 7f a9  |................|
00000150  cc 8d 8c 7f 60 00 00 00  00 00 00 00 00 00 00 00  |....`...........|
00000160  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

As for your program’s intro, I would write it thusly...

Code: Select all

setmode: sei                   ;no IRQs
         sec                   ;default the...
         xce                   ;MPU
         clc                   ;return to...
         xce                   ;native mode
         cld                   ;binary arithmetic
         ...etc...

Your method of initializing the 65C816 is always assuming the MPU is in emulation mode.  That would be the case if powering on or if a hard reset occurs.  However, if your code was called some time after the system came up, such as via a jump into the reset handler, the MPU will already be in native mode.  If so, you can’t assume the width of the registers.  Blindly loading $FF into .X without considering the present MPU state could be fatal if the index registers are set wide.

Also, the very first thing a reset handler should do is disable IRQ servicing.  Yes, that is automatic if coming out of a hard reset (so is reversion to binary arithmetic).  Your reset sequence is switching from emulation to native mode while IRQs are enabled, which depending on what the system was doing when jumping to the reset code, may not result in a pleasant outcome.

Lastly, it is generally not good programming practice to bury “magic numbers,” such as the new stack pointer value, in your code.  Such constants should be defined in an INCLUDE file.  This is especially relevant with the 65C816, since both its direct page and hardware stack can be almost anywhere in bank $00 address space, with either or both being changed by local code within functions.  By defining the global values for DP and SP and using them to reset those registers as required, you avoid the risk of a typo at some point going undetected and setting the stage for an insidious bug.  It’s part of the general process of defensive programming.

Re: Weird Assembler Issue

Posted: Tue Jan 13, 2026 8:17 pm
by BigEd
(Welcome, kellymcdonald78!)

Re: Weird Assembler Issue

Posted: Tue Jan 13, 2026 9:20 pm
by kellymcdonald78
Quote:

Code: Select all

setmode: sei                   ;no IRQs
         sec                   ;default the...
         xce                   ;MPU
         clc                   ;return to...
         xce                   ;native mode
         cld                   ;binary arithmetic
         ...etc...
Your method of initializing the 65C816 is always assuming the MPU is in emulation mode.  That would be the case if powering on or if a hard reset occurs.  However, if your code was called some time after the system came up, such as via a jump into the reset handler, the MPU will already be in native mode.  If so, you can’t assume the width of the registers.  Blindly loading $FF into .X without considering the present MPU state could be fatal if the index registers are set wide.

Also, the very first thing a reset handler should do is disable IRQ servicing.  Yes, that is automatic if coming out of a hard reset (so is reversion to binary arithmetic).  Your reset sequence is switching from emulation to native mode while IRQs are enabled, which depending on what the system was doing when jumping to the reset code, may not result in a pleasant outcome.

Lastly, it is generally not good programming practice to bury “magic numbers,” such as the new stack pointer value, in your code.  Such constants should be defined in an INCLUDE file.  This is especially relevant with the 65C816, since both its direct page and hardware stack can be almost anywhere in bank $00 address space, with either or both being changed by local code within functions.  By defining the global values for DP and SP and using them to reset those registers as required, you avoid the risk of a typo at some point going undetected and setting the stage for an insidious bug.  It’s part of the general process of defensive programming.
Thanks for the feedback, the changes make sense (it's been a LONG time since I did any assembler)

The weird thing is, even after I make these changes and rebuild the binary file, the hex dump still doesn't match

e.g. I'm still getting

00000000 9c 91 7f a9 1a 8d 93 7f a9 19 8d 92 7f 60 aa 8e |.............`..|

Maybe I just need to reboot everything :)

Re: Weird Assembler Issue

Posted: Tue Jan 13, 2026 11:39 pm
by 8BIT
My guess is that one of the include files has executable code or there's a system init file that gets inserted before your code. The funny thing is, your "setmode" code is nowhere in the hex dump you provided. A2 FF 9A ...

An alternative hypothesis: If the hex dump is a separate output file, check the file date/time to make sure you are looking at the current hex dump file. It might be going to another folder.

Daryl

Re: Weird Assembler Issue

Posted: Tue Jan 20, 2026 12:59 am
by NeonGuppy
Greetings,

Friend is using a cc65 based devcontainer: https://github.com/dhirsch1138/cc65_template

8BIT is right on the nose; the make file(s) for link the files in alphabetical order so the bin reflects flat. This is harmless, so long as you don't try to statically address rom addresses yourself (let the linker do that for you). There are several ways reference code in different files, but a simple way is to add more segments. Here is an example that has code segments in many files https://github.com/dhirsch1138/Shrimpy_ ... er.cfg#L38

Re: Weird Assembler Issue

Posted: Tue Jan 20, 2026 3:21 am
by BigDumbDinosaur
NeonGuppy wrote:
Greetings,

Friend is using a cc65 based devcontainer: https://github.com/dhirsch1138/cc65_template

8BIT is right on the nose; the make file(s) for link the files in alphabetical order so the bin reflects flat. This is harmless, so long as you don't try to statically address rom addresses yourself (let the linker do that for you). There are several ways reference code in different files, but a simple way is to add more segments. Here is an example that has code segments in many files https://github.com/dhirsch1138/Shrimpy_ ... er.cfg#L38
I’m trying to figure out how your response relates to what the OP posted.  I believe his code is assembly language, not C.

Re: Weird Assembler Issue

Posted: Tue Jan 20, 2026 6:44 pm
by fachat
The OP is using the assembler and linker from the cc65 toolchain, as provided by a so-called dev container. That's a docker container to run development software as I understand it.

Re: Weird Assembler Issue

Posted: Wed Jan 21, 2026 12:01 am
by NeonGuppy
You are correct fachat. Devcontainers are reproducible development environments; defined in structured json file(s) which are used do build docker images when deployed.

* You can store and share them as git repos, either as templates (https://github.com/dhirsch1138/cc65_template) or full projects (https://github.com/dhirsch1138/Shrimpy_BenEater_6502)
* By keeping everything in a repository (both the code and the devcontainer definition), it makes everything super portable and easy to stand up.
* And since the dev environ is in the container, it doesn't clutter the rest of your system. You can have access to whatever you need even if your system doesn't support those packages natively.

I'm a fan.

Re: Weird Assembler Issue

Posted: Fri Jan 23, 2026 4:01 pm
by 8BIT
To kellymcdonald78,

Did you resolve this issue?

Daryl