geek504 44 Posted November 3, 2020 I am trying to setup a few variables in ZEROPAGE using ca65 and the following does not seem to work... Quote .org $22 ; start of user ZP FPSP: .byte 0 ; stack pointer = 0 FPTEMP: .res 4 ; FP temp SFL: .res FPSTACKSIZE SFH: .res FPSTACKSIZE SIL: .res FPSTACKSIZE SIH: .res FPSTACKSIZE .org $0801 .byte $0C, $08 .byte $0A, $00 .byte $9E .byte $20 .byte $32, $30, $36, $34 .byte $00 .byte $00, $00 .byte $00, $00 ; Padding so code starts at $0810 StoreImm $11ff, r0 jsr PUSH StoreImm $2233, r0 jsr PUSH StoreImm $5599, r0 jsr PUSH StoreImm $6677, r0 jsr PUSH StoreImm $2345, r0 jsr PUSH jsr ADD jsr ADD jsr ADD jsr ADD jsr PULL jsr PrHex16 PrintNewline StoreImm msg, r0 jsr PrString END: rts msg: .asciiz "the end!" <snipped math routines> It seems multiple ".org" doesn't work? Quote Share this post Link to post Share on other sites
0 Getafix 38 Posted November 3, 2020 Instead of .org $22 just use .zeropage. Here's a quick discussion about this: https://www.cc65.org/faq.php#ORG I don't use .org at all. I use .code for the code and I do use .data for variables and .rodata for read-only data (not enforced, just the way I like to organize stuff). Then it's all nice and neat and the linker puts it where it needs to go. here's an example (I saved as main.s): .zeropage myzpptr: .res 2 .code lda #<mystring sta myzpptr lda #>mystring sta myzpptr + 1 ldy #0 : lda (myzpptr), y beq :+ jsr $ffd2 iny bne :- : rts .data mystring: .asciiz "hello, world!" now compile with: cl65 -t cx16 -u __EXEHDR__ main.s -C cx16-asm.cfg and you will have main that you can run in the emulator with: x16emu.exe -prg main -run The -u __EXEHDR__ creates the basic stub (the sys 2061) for you. It's all very neat 1 Quote Share this post Link to post Share on other sites
0 StephenHorn 292 Posted November 3, 2020 Ultimately, the problem is that the assembler is just building a file from the bytes you specify, and when you specify a ".byte 0" directive in your .org $22 section, you're not generating instructions to initialize a variable - you're just telling the assembler to place a byte in the file. A byte of $00. Subsequently specifying .org does not remove or change that byte, it just forces the assembler to assume that any memory addresses it subsequently generates are offset as though that portion of the file, starting from the .org directive, had started at the new address. In other words, you think you're generating a file that starts with 0C 08 0A 00 9E, etc., but you're actually generating a file that starts with 00 0C 08 0A 00 9E, and your attempt to use .org 0801 to re-align the file is instead just adding to the confusion since not only is the file header incorrect, but the subsequent addresses it generates are incorrect. Personally, I like @Getafix's answer: Don't manually use .org for these purposes. First, if you're assembling and linking with the CX16 or C64 as your target platform (instead of explicitly using "none" as the target platform), then the assembler might do something sneaky behind your back that you're not aware of, clobbering your mental model of the computer. Second, even if you've got it right, this is totes for sure the hardest and most obscure way to represent your intent. And I suppose third, why not lean into the features of the assembler and linker to make your life a little easier, especially if you've already done the legwork to learn it the first time? That having been said, you could still use .org to do what you want, but instead of FPSP: .byte 0, you'll want FPSP: .res 1 instead, so you aren't emitting an unintended byte into the file. Your subsequent .org 0801 will then properly align memory addresses, and your subsequent .byte statements with the file header will be placed at the front of the file accordingly. After the padding to $0810, you'd add your own instructions to initialize FPSP to 0, before doing any other work that might depend on the value. 1 Quote Share this post Link to post Share on other sites
0 desertfish 277 Posted November 3, 2020 (edited) In Prog8 I solved this by generating assembly code that explicitly names the locations in ZP via a label declaration, rather than explicitly allocating them like we do with regular variables. The variables in zp are initialized explicitly with code at the start of the program with whatever value they need to have. So we have something like this (for a C-64 program so the available zeropage locations looks different from the cx16): P8ZP_SCRATCH_B1 = 2 P8ZP_SCRATCH_REG = 3 P8ZP_SCRATCH_W1 = 251 ; word P8ZP_SCRATCH_W2 = 253 ; word lines = 4 ; auto zp UWORD score = 9 ; auto zp UWORD xpos = 6 ; auto zp UBYTE ypos = 146 ; auto zp UBYTE nextBlock = 150 ; auto zp UBYTE speedlevel = 249 ; auto zp UBYTE holding = 255 ; auto zp UBYTE holdingAllowed = 11 ; auto zp UBYTE .... init: lda #0 sta lines sta lines+1 sta xpos sta ypos lda #1 sta speedlevel ..... while regular variables that are not in zeropage are just this, which actually allocate bytes into the resulting binary program. currentblock .byte 0 currentline .byte 0 Edited November 10, 2020 by desertfish Quote Share this post Link to post Share on other sites
0 geek504 44 Posted November 10, 2020 On 11/3/2020 at 1:00 AM, Getafix said: Instead of .org $22 just use .zeropage. Out of curiosity, where does ".zeropage" start reserving space? Hopefully not starting from address $0000 since it is prone to corruption of important areas. For X16 it should start at $0022. I assumed it did but now am worried I may have ZP data corruption. Quote Share this post Link to post Share on other sites
0 Getafix 38 Posted November 10, 2020 If you are using the default cx16-asm.cfg then it does indeed start at $22. With cc65 it's a good idea to get to know the .cfg files and how they work. You can do some useful stuff if you need to, such as aligning segments, making your own, etc. Quote Share this post Link to post Share on other sites
I am trying to setup a few variables in ZEROPAGE using ca65 and the following does not seem to work...
It seems multiple ".org" doesn't work?
Share this post
Link to post
Share on other sites