Jump to content
  • 0
geek504

How to Initialize ZP Data

Question

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?

Share this post


Link to post
Share on other sites

5 answers to this question

Recommended Posts

  • 0

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 😀

  • Thanks 1

Share this post


Link to post
Share on other sites
  • 0

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.

  • Like 1

Share this post


Link to post
Share on other sites
  • 0

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 by desertfish

Share this post


Link to post
Share on other sites
  • 0
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.

Share this post


Link to post
Share on other sites
  • 0

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. 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

Please review our Terms of Use