Potatohead,
No. The use is inconsistent so it’s a pnut bug.
When I last fell foul of it we were trying to get the rom to onsemi.
We just need a consistent way to override its use.
I don't think this is a PNut bug. It's just a feature that isn't documented very well. First of all, ORGH doesn't force the use of the hubexec mode. It just sets the hub RAM address. If you use ORGH without a parameter it's really not changing anything. If you use ORGH with a parameter it will pad with zeros, and set the hub address to the value of the parameter. However, it doesn't force the hubexec mode unless the address is greater than $3FF.
Note, the hubexec mode can be overridden by an ORG command. This allows generating cog exec code in hub RAM addresses greater than $3FF. This code can be loaded in a cog, and executed from cog memory. PASM symbols have 2 values -- the cog address and the hub address. When you reference a symbol you will get the cog address if it is less than $400, otherwise you will get the hub address. You can force always getting the hub address by preceding the symbol with a "@".
I believe p2asm handles the LOC instruction the same way that PNut does. At least it generates the same binary codes that PNut does for the tests that I've run. p2asm uses the same algorithm for generating the source value for LOC that it uses for JMP. It will generate an absolute value if a "\" is use, or the current address and the target address are not in the same space relative to $400. It will generate a relative value if "\" is not specified, and the current and target addresses are both in the same space.
If you want to ensure that you get an absolute address you should use "\". If you want to ensure that you get a hub address you should use "@ ". Therefore, to ensure getting an absolute hub address use "\@", such as
I looked at the source for p2asm, and it does set the hubexec flag for ORGH even if the hub address is less than $400. I think this will cause symbols defined in hub addresses less than $400 to produce the hub address even without the "@ " prefix. I'll have to run some tests to see if this is consistent with PNut. Anyhow, if you want to ensure that you get the hub address it's safest to use "@".
Anyhow, if you want to ensure that you get the hub address it's safest to use "@".
That works perfectly for branches, branches work well using PC-relative label addressing. It's the building block of re-entrant coding.
But LOC always gets used to generate an absolute address. This is what's special about it. Hence the need to always bundle the two qualifiers together for LOC instructions.
No.
Because I get opposite results with a single "\" vs "@" depending on whether code is below $400. Seems not to matter with ORGH or not.
But I have never seen that "\@" was valid. Perhaps this will fix the problem.
We definitely need a definitive way of declaring absolute and a definitive way of declaring Hub or cog/lut.
Some code was working because it "fell" into the code that was supposed to be used, but when a chunk was moved (a chunk of Hub constants) the code broke. Goodness knows what else was being executed erroneously tho.
I ran a few tests with p2asm, and a symbol defined under ORGH will always have a value of the hub address, even if it is less than $400. However, when p2asm generates the source field for JMP or LOC it tests if the address is less than $400 to determine if it a cog address or a hub address. So there may be a bug there. I don't know if PNut does the same thing. I only have my Linux machine with me right now, so I can't test this with PNut. I'll look into it when I get back home in a week.
Anyhow, as I said earlier, using "\@" will force an absolute hub address so there shouldn't be any problems with that.
Anyhow, as I said earlier, using "\@" will force an absolute hub address so there shouldn't be any problems with that.
Confirming this so. I've commented the addresses that Pnut generates in the below sample code. (First three columns were tests of ORGH only. The final column is the listed test with both ORGH and ORG):
dat
org 0
'+++++++++++++++++++++++++++++++++++++++++ orgh $410 ++ orgh $110 ++ orgh $550 ++ org $030
loc ptra, #palette ' $00410 $0043c $00550 $000bc
loc ptra, #@palette ' $00410 $00438 $00550 $00550
loc ptra, #palette ' $00410 $00434 $00550 $000b4
loc ptra, #\palette ' $00410 $00110 $00550 $00030
loc ptra, #\@palette ' $00410 $00110 $00550 $00550
mov ptra, #palette ' n/a $110 n/a $030
mov ptra, ##palette ' $00410 $00110 $00550 $00030
mov ptra, ##@palette ' $00410 $00110 $00550 $00550
jmp #main
orgh $500
main
'+++++++++++++++++++++++++++++++++++++++++ orgh $410 ++ orgh $110 ++ orgh $550 ++ org $030
loc ptra, #palette ' $fff0c $00110 $0004c $00030
loc ptra, #@palette ' $fff08 $00110 $00048 $00048
loc ptra, #palette ' $fff04 $00110 $00044 $00030
loc ptra, #\palette ' $00410 $00110 $00550 $00030
loc ptra, #\@palette ' $00410 $00110 $00550 $00550
mov ptra, #palette ' n/a $110 n/a $030
mov ptra, ##palette ' $00410 $00110 $00550 $00030
mov ptra, ##@palette ' $00410 $00110 $00550 $00550
jmp #$
orgh $550 ' Binary loaded to $00550 in hubram
org $030 ' Assembled as if for $030 in cogram
'====================================================================
'24 bit color format = rr_gg_bb_00
'====================================================================
palette long 0 'black
long $0000aa00 'blue
long $00aa0000 'green
long $00aaaa00 'cyan
long $aa000000 'red
long $aa00aa00 'magenta
long $aa550000 'brown
long $aaaaaa00 'gray
long $55555500 'dark gray
long $5555ff00 'bright blue
long $55ff5500 'bright green
long $55ffff00 'bright cyan
long $ff555500 'bright red
long $ff55ff00 'bright magenta
long $ffff5500 'yellow
long $ffffff00 'white
'====================================================================
When I wrote the SD & Monitor and ROM code, I called routines that could be in hubexec or in cog. I needed to be able to specify either.
Chip was running his reset pins routine from cog and called from cog, but I call them from hub and run them in hub as they may no longer be in cog.
That is the benefit of relative jumps and calls. But sometimes you just need to override this.
I've never used LOC even once in my own sources. I can't visualise how to apply it in more than a trivial way.
I hadn't either until I worked on other's code. There isn't any in my ROM code, but then again, I don't use PTRx, etc as I tried to leave as much cog resources available to the user as possible so they could call my routines without much trouble. It's goo to load up a PTR though as it contains the full 20bit address within the one instruction. That's probably it's main claim to fame.
LOC is intended to allow relocatable hub code to easily get addresses of its own data in hub. You can always use it from within cog or hub code to just load 20-bit immediate values into PA/PB/PTRA/PTRB.
Right, just looking at Chip's ROM source now - it has "loc ptra,#$FC000" on the very first. As you say, poking a specific address straight into PTRA with a one-liner.
LOC is intended to allow relocatable hub code to easily get addresses of its own data in hub. You can always use it from within cog or hub code to just load 20-bit immediate values into PA/PB/PTRA/PTRB.
Right, so it's not sensibly going to be used for cog addresses.
LOC is intended to allow relocatable hub code to easily get addresses of its own data in hub. You can always use it from within cog or hub code to just load 20-bit immediate values into PA/PB/PTRA/PTRB.
In 68k and 6809 terms, that is similar to LEA, Load Effective Address. Maybe that is a less confusing mnemonic?
LOC is intended to allow relocatable hub code to easily get addresses of its own data in hub. You can always use it from within cog or hub code to just load 20-bit immediate values into PA/PB/PTRA/PTRB.
In 68k and 6809 terms, that is similar to LEA, Load Effective Address. Maybe that is a less confusing mnemonic?
+1 - Always found the 6809 easy to work with even though I did so infrequently. That was mainly due to it's clear mnemonics and orthogonal instruction set.
Comments
I'm happy with the mechanism. Did take me a while though.
The problem is that LOC is special. If it were treated as not having a PC-relative encoding option then everything would come right.
I don't think this is a PNut bug. It's just a feature that isn't documented very well. First of all, ORGH doesn't force the use of the hubexec mode. It just sets the hub RAM address. If you use ORGH without a parameter it's really not changing anything. If you use ORGH with a parameter it will pad with zeros, and set the hub address to the value of the parameter. However, it doesn't force the hubexec mode unless the address is greater than $3FF.
Note, the hubexec mode can be overridden by an ORG command. This allows generating cog exec code in hub RAM addresses greater than $3FF. This code can be loaded in a cog, and executed from cog memory. PASM symbols have 2 values -- the cog address and the hub address. When you reference a symbol you will get the cog address if it is less than $400, otherwise you will get the hub address. You can force always getting the hub address by preceding the symbol with a "@".
I believe p2asm handles the LOC instruction the same way that PNut does. At least it generates the same binary codes that PNut does for the tests that I've run. p2asm uses the same algorithm for generating the source value for LOC that it uses for JMP. It will generate an absolute value if a "\" is use, or the current address and the target address are not in the same space relative to $400. It will generate a relative value if "\" is not specified, and the current and target addresses are both in the same space.
If you want to ensure that you get an absolute address you should use "\". If you want to ensure that you get a hub address you should use "@ ". Therefore, to ensure getting an absolute hub address use "\@", such as
EDIT: Well, I should say it's not crashing or doing anything obviously wrong. I don't really know how to use it yet.
That works perfectly for branches, branches work well using PC-relative label addressing. It's the building block of re-entrant coding.
But LOC always gets used to generate an absolute address. This is what's special about it. Hence the need to always bundle the two qualifiers together for LOC instructions.
..and the examples of exactly why hieroglyphs are not a good idea, just keep on coming... QED
Because I get opposite results with a single "\" vs "@" depending on whether code is below $400. Seems not to matter with ORGH or not.
But I have never seen that "\@" was valid. Perhaps this will fix the problem.
We definitely need a definitive way of declaring absolute and a definitive way of declaring Hub or cog/lut.
Some code was working because it "fell" into the code that was supposed to be used, but when a chunk was moved (a chunk of Hub constants) the code broke. Goodness knows what else was being executed erroneously tho.
It will. Use it with all cases of LOC, no exceptions.
Anyhow, as I said earlier, using "\@" will force an absolute hub address so there shouldn't be any problems with that.
Confirming this so. I've commented the addresses that Pnut generates in the below sample code. (First three columns were tests of ORGH only. The final column is the listed test with both ORGH and ORG):
Chip was running his reset pins routine from cog and called from cog, but I call them from hub and run them in hub as they may no longer be in cog.
That is the benefit of relative jumps and calls. But sometimes you just need to override this.
I hadn't either until I worked on other's code. There isn't any in my ROM code, but then again, I don't use PTRx, etc as I tried to leave as much cog resources available to the user as possible so they could call my routines without much trouble. It's goo to load up a PTR though as it contains the full 20bit address within the one instruction. That's probably it's main claim to fame.
Right, so it's not sensibly going to be used for cog addresses.
EDIT: ie: In cogram, execution addressing has different scale to data addressing.
Okay - so this has been driving me batshiznit insane - I thought I was going mad. At last someone has said what I suspected was really going on(!)
When I compiled this as a test program:
the jmp would properly disassemble in p2dump to:
Yet my own attempts to decode it:
gave me -36 as the encoded value and NOT -8(!)
Even the example in the docs did the exact same thing:
... so it is true that the actual **coded instruction** is still encoded in bytes but its assembly analog is written in longs?
(and the next location of code that should execute after a JMP is (encoded value/4)-1?
In 68k and 6809 terms, that is similar to LEA, Load Effective Address. Maybe that is a less confusing mnemonic?
+1 - Always found the 6809 easy to work with even though I did so infrequently. That was mainly due to it's clear mnemonics and orthogonal instruction set.
Hmmm. P2 emulator target!
I'm pretty sure that was done as part of making sure code can run in both HUB and COG. It is proving hard to find that discussion.
OS9/Niros-9 on the P2? Yes please!