FastGUI SPIN 2 Address Confusion
potatohead
Posts: 10,261
I'm looking to move some all PASM code to SPIN+PASM and I am having trouble locating a file at a specific address in hub RAM.
Simple code attached.
I thought I could do this:
Then some SPIN code:
Follow that with PASM I want to launch in various cogs:
Followed by data in higher RAM:
Turns out, the actual location in the HUB of the $DEADBEEF targeted at $2000 above is $2574, and that varies depending on how much SPIN I write in main. It does not appear to be affected by code added in the DAT section containing PASM. <-- This is wrong. I just added another PASM DAT block, and the address target $2000 did move.
(Thanks for the awesome listing file feature Eric! It reloads on recompile and keeps cursor / display window position. Love it. It's the little things that help.)
How can I specify where I want something in the HUB? I gotta be missing something basic. What is it? I have messed with this for a little too long.
Simple code attached.
I thought I could do this:
CON bitmap = $1_0000 'bitmap buffer start
Then some SPIN code:
PUB Main | x clkset(_clkmode, _clkfreq) waitcnt(clkfreq + cnt) coginit(HDMIDSP,@pgm_hdmi, 0) repeat 500 x := x + $10 'code added here adds to bitmap address
Follow that with PASM I want to launch in various cogs:
' HDMI Display Bitmap @ bitmap DAT org pgm_hdmi setcmod #$100 'enable HDMI mode drvl #7<<6 + hdmi_base 'enable HDMI pins wrpin ##%001001<<8,#7<<6 + hdmi_base 'set 1 mA drive on HDMI pins setxfrq ##$0CCCCCCC+1 'set streamer freq to 1/10th clk (25 MHz) rdfast ##640*480/64,##bitmap 'set rdfast to wrap on 300KB bitmap [some code omitted for clarity] m_vi long $70810000 + hdmi_base<<17 + 640 'visible m_rf long $B0820000 + hdmi_base<<17 + 640 'visible rfbyte luma8 i long 1 hsync0 long 1 hsync1 long 1 'end of cog driver code
Followed by data in higher RAM:
orgh $2000 byte $DE, $AD, $BE, $EF orgh bitmap - $436 'justify pixels at $1000, pallete at $1000-$400 file "bitmap.bmp"
Turns out, the actual location in the HUB of the $DEADBEEF targeted at $2000 above is $2574, and that varies depending on how much SPIN I write in main. It does not appear to be affected by code added in the DAT section containing PASM. <-- This is wrong. I just added another PASM DAT block, and the address target $2000 did move.
(Thanks for the awesome listing file feature Eric! It reloads on recompile and keeps cursor / display window position. Love it. It's the little things that help.)
02574 | 02574 | orgh $2000 02574 DE AD BE EF 02578 00 00 00 00 0257c 00 00 00 00 02580 00 00 00 00 | byte $DE, $AD, $BE, $EF
How can I specify where I want something in the HUB? I gotta be missing something basic. What is it? I have messed with this for a little too long.
Comments
orgh with explicit origin does not work if Spin methods are present
That's the thing I'm missing. Just didn't see it. That light orange color went right past me. I added another file, and saw two of those messages. Guess that's what it takes late at night to get my attention!
Any workarounds?
Second question @ersmith : Will this be supported eventually?
I’m trying to remember... think just pass @ or @ @ to assembly... one of those...
The best solution is to replace with and then everywhere you used to use "$2000" use "@my_base_addr". You may also need to change things like "$1FFF" to "@my_base_addr - 1" and such as well.
This is much cleaner because now your object is relocatable.
The other alternative, which I would strongly suggest avoiding unless you really need it, is to remove the FILE data from your code and instead to use loadp2 to load your data file directly at $2000, something like: That will only work if your program plus all the libraries will fit in the memory below $2000.
Short answer: probably not.
Longer answer: besides the technical difficulties involved in trying to support letting the user put data wherever they want, regardless of what the Spin compiler is doing with memory, what does it even mean if two objects both try to do "orgh $2000" simultaneously?
For sake of discussion, the answer to the question could be as simple as, "Error: duplicate orgh found"
And does that imply a structure, or process not currently part of FastGUI?
Just wanting to understand those difficulties.
Secondly, it's not an object I'm wanting to declare. It's data.
Should I then pack the data in before the objects? Your workaround would be valid then, because the references to the data would be present prior to the objects needing them. This is not as readable, but...
Or, can I make a sort of data object? Maybe that's more readable.
This one may come up from Prop Tool users, who would do this kind of thing once they see "orgh" Well, I did!
The general idea here is Spin 1 sort of ignored higher memory. Declaring buffers and such up there made sense. We didn't have a big PASM model and no orgh... Would be super nice to drop some data somewhere.
Thanks again. In every other way I've used it so far, FastGUI is exemplary. Great work. I'm just whining. No worries.
Rayman, I'll go give your code a look. Was attempting to do the usual, one file Spin thing. Looks like I still can, but need to think about it differently.
Really, what we did with Spin 1, when working this way, was to pass addresses into assembly programs, and then abuse high memory with buffers, dynamically generated data, whatever. We did just declare those.
Orgh is new, and this seems an obvious use, given we now can make PASM outside the COG scope.
I'm not saying it should be done. I am saying it would be awful nice if it could. I feel it's a logical extension of how hubexec allows one to work in RAM. I could just make this project a PASM one too.
I do not want to use the load at address facility Eric mentioned. PITA, but I'm glad that is there.
Padding was expected.
And there is one trade-off right there! I really was not thinking about the mix 'n match aspect in all of this. Eric is right. If people sprinkled them throughout...
Messy. That's helping me understand. Appreciated.
But, it seems SO easy in the "stuff it in one file" and go scenario too. Ah well, everything costs something and doing this appears increasingly expensive, unless it's confined to a very narrow set of use cases, and doing that is expensive too.
Another is to declare a variable array, string, or series of bytes as a data block. The only downside is the binary image has this variable data pre-initialized. So in other words the binary reflects the total memory being used.
Is there a third option to tell the linker to reserve these memory blocks at the end, while still advancing the orgh address, so to say that this can be snipped off, but these memory areas are definitely in use?
If we're taking 512 kB, is this really an issue though?
Definitely. Original intent was "one file" just write it in much the same way one would do with PASM. Really, it was just about including data to be located at a specific place in RAM, ideally above all the active program.
We can do the third option pretty much now. Just specify the address and go. That's about buffers and such, not so much locating bits of code all over the place.
That’s what I do to call the ROM code.
Not sure if this helps, but it’s a better way than hard coding a constant. You can test to ensure your code is below that address.
I guess it does mean that the data has to be initialized, which is perhaps a bit of a pain. Maybe we could create something like "res" but which is guaranteed to be after all the program and data. Would that solve your use case?
From C, you can
Is there possibly something similar that could be done from FastGUI? Add a "myfile.bin" to a project and have _myfile_start become an available global symbol?
Yeah, it's initialized data, and some of it isn't intended to be mutable. Media assets would be the main use case. Pictures, sounds, scores. Later, with bigger programs, external RAM, SD storage, it either won't come up, as those things will be dynamically loaded into defined buffers, or will be referenced where they are.
This is a simple, stupid case. Maybe we should not worry about it.
All I really want to do is say, "put this blob right here." And using orgh for that, in all the other multi-file, reuse cases, makes for a big potential mess. Bummer. I totally don't want to be the one who started that.
Maybe the loader option is easy?
I think the sticking point is making a plan for the RAM, PASM style.
Maybe just me too. Wanting things to be too lean. I need to explore all the options.
When I get a chance, I will do exactly that.
For done reason, I thought it did not work for me, but I could be wrong, did not actually do that, or did it incorrectly too.
We will know in a bit.
Well, we don't have "projects" in FlexGUI. You can certainly include binary data into a .spin file though via: or you could do the same in C with:
For example, a program to print itself is:
Eric, this works. It's not actually doing what I would prefer, which is to just put a dataset at an address. But, I also don't care. What I can do is get it into the P2, and just move it, should that address matter for some reason or other, or work with it where it is.
I'm happy. No worries, though I do think if we can just declare some buffer in upper memory for some reason, we should also just be able to put data there for some reason. Either scenario could require a refactor should the code find it's way into some other code body. I also think we've got a zillion other worries that are more important too. Thanks to the people who explained things to me.
On another note, I've got an HDMI TV here that I cannot reliably drive. I think I'm going to maybe start a thread where we can post displays and what worked.