Init routines.

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Init routines.

Post by Movax12 »

A simple idea for CA65.

In every library that would benefit from initialization, one could use this macro code rather than explicitly doing so for each library.
For example, in an included file:setLibraryInitRoutine initFoo
Another file:setLibraryInitRoutine initBar
Then, somewhere suitable in the main calling code (somewhere after reset): executeLibraryInitRoutines

Code: Select all


.ifndef _INIT_LIB_H_
_INIT_LIB_H_ = 1

.scope initialize
    initCounter .set 0    
.endscope


.macro setLibraryInitRoutine proc

    initialize::initCounter .set initialize::initCounter + 1   ; first entry starts at 1
    initialize::.ident(.sprintf("%s%d","_Library_Init_List_", initialize::initCounter)) = proc

.endmacro

.macro executeLibraryInitRoutines

    .if .not initialize::initCounter
        .exitmacro ; if none, do nothing
    .endif
    
    .repeat initialize::initCounter, I
        jsr initialize::.ident(.sprintf("%s%d","_Library_Init_List_", I+1))
    .endrepeat
    
.endmacro
.endif
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Init routines.

Post by tepples »

I wonder if the constructor and destructor system built into ca65 might help you implement something like this.
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: Init routines.

Post by Movax12 »

Probably, but I don't really understand how they work.
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: Init routines.

Post by Movax12 »

I looked into using the built-in functions, and they would probably work fine, but they seem overly complex for what I want to accomplish.
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Re: Init routines.

Post by blargg »

I thought that ca65 could allow each module to denote an constructor and destructor routine, and then at runtime you can get a list of 16-bit pointers to these to iterate over.
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: Init routines.

Post by Movax12 »

Pretty much. I may still try it, it's pretty close to what I am doing, but the linker generates the list and passes you an address to the list (of constructors). Then you have to write code to jump to the list of address, which will require RAM usage to do so. A small list of JSR seems effective enough (as long as it stays small).
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Re: Init routines.

Post by blargg »

I don't think it uses any RAM. It should put the list of routine addresses in ROM. I'm not sure how it could use any RAM anyway.
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Init routines.

Post by rainwarrior »

Any global non-const statics will use RAM that must be initialized at startup. Other than that, it should just be calling the requisite code, which should all be in ROM.

If you look at crt0.s it should give you an idea of what it does.

For my own purposes, though, I just rewrote crt0 and got rid of all setup except the RAM initialization. I had cut the CRT down so much that nothing in it needed init code anyway.
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: Init routines.

Post by Movax12 »

What I was trying to say and obviously failed to communicate properly was that the code that's going to walk the list of addresses is going to somehow have to use RAM, since when using only CA65 you have to write the code to call the list of constructors. The default routine uses quite a bit of RAM and self modifying code. (condes.s) Here.
Last edited by Movax12 on Wed Apr 03, 2013 9:34 pm, edited 1 time in total.
lidnariq
Posts: 10677
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Init routines.

Post by lidnariq »

I'm pretty certain the RTS trick would let you get away with just using temporary bits of stack for walking the array. At least as long as you have fewer than 128 or 256 function pointers. You're talking about JSR, so you're already positing a functional stack.
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: Init routines.

Post by Movax12 »

It's not a big deal, I could use a bit of RAM, I just see it as more complex that is needed, though it does have the advantage of working across different modules. (A pre-compiled obj file could have it's init routine called from another source.)

But to argue the point, I don't see how to code such a routine that is not going to have to use RAM to create a pointer to get the pointers. EDIT: Disregard that, something like this might work:

Code: Select all

ldy #0

loop:

tya
pha

lda __CONSTRUCTOR_TABLE__,y
pha
iny
lda __CONSTRUCTOR_TABLE__,y
pha

rts

pla
tay
iny
iny
cmp #<(__CONSTRUCTOR_COUNT__*2)
bcc loop
EDIT2: For the sake of clarity: I think the list is intended to be called from the bottom (load y first and decrement it).
Last edited by Movax12 on Wed Apr 03, 2013 9:54 pm, edited 1 time in total.
User avatar
blargg
Posts: 3717
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Re: Init routines.

Post by blargg »

How about this? (untested) Only uses the stack (which is pretty much a given as it's calling init routines which end in RTS).

Code: Select all

call_ctors:
        lda #<(__CONSTRUCTOR_COUNT__*2)
        beq @none

@loop:  sec
        sbc #2
        pha
        jsr @call
        pla
        bne @loop
@none:  rts

@call:  tay
        lda __CONSTRUCTOR_TABLE__+1,y
        pha
        lda __CONSTRUCTOR_TABLE__,y
        pha
        php
        rti
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: Init routines.

Post by Movax12 »

Okay I'll give it a try in my actual code, since there are some nice advantages.
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Init routines.

Post by rainwarrior »

Ah, yeah I didn't realize condes.s did that (as I said, I threw it away anyway). I dunno if I'd call that "quite a bit" of RAM, but it's definitely more than trivial. Seems a strange way to go about that, but I guess it was probably written with an architecture more like C64 in mind.
User avatar
Movax12
Posts: 529
Joined: Sun Jan 02, 2011 11:50 am

Re: Init routines.

Post by Movax12 »

blargg, your code works fine. I only tested it on one "constructor" but I see no reason it wouldn't work for more.
Post Reply