gtBASIC

Using, learning, programming and modding the Gigatron and anything related.
Forum rules
Be nice. No drama.
wbushby
Posts: 48
Joined: 16 Jul 2021, 10:59

Re: gtBASIC

Post by wbushby »

ok, thank you. In the meantime I think I can progress by just keeping an eye out for that fault. If I can get it to be on 2 unused variables that would work.
at67
Posts: 384
Joined: 14 May 2018, 08:29

Re: gtBASIC

Post by at67 »

I found the bug, it was in the optimiser, (I found a couple of other similar ones as well), basically the optimiser was not relocating code correctly for edge case array accesses.

Just replace optimiser.cpp with this version and re-compile:
optimiser.cpp
(65.17 KiB) Downloaded 9 times
Here's the patch for reference:

Code: Select all

888a889,890
>                                 uint16_t offset = 15;
>                                 
893a896,897
>                                     if(savedLD._opcode.find("LDWI") != std::string::npos) offset += 1;
>                                     
897c901
<                                     savedLD._address += 15; // LD<X> is moved 15 bytes
---
>                                     savedLD._address += offset; // LD<X> is moved 15bytes, LDWI is moved 16 bytes
906,908c910,925
<                                     itVasm = Compiler::getCodeLines()[i]._vasm.insert(itVasm, savedLD);
<                                     adjustLabelAddresses(i, firstLine - 1, -4);
<                                     adjustVasmAddresses(i, firstLine - 1, -4);
---
>                                     if(offset == 15)
>                                     {
>                                         itVasm = Compiler::getCodeLines()[i]._vasm.insert(itVasm, savedLD);
>                                         adjustLabelAddresses(i, firstLine - 1, -4);
>                                         adjustVasmAddresses(i, firstLine - 1, -4);
>                                     }
>                                     // LDW is replaced with LDWI so push everything forward starting at the last LDW by 1 more byte
>                                     else
>                                     {
>                                         itVasm = Compiler::getCodeLines()[i]._vasm.insert(itVasm, savedLD);
>                                         adjustLabelAddresses(i, firstLine - 1, -5);
>                                         adjustVasmAddresses(i, firstLine - 1, -5);
>                                         adjustLabelAddresses(i, firstLine + 5, 1);
>                                         adjustVasmAddresses(i, firstLine + 5, 1);
>                                     }
> 
936a954,955
>                                 uint16_t offset = 17;
>                                 
942c961,963
<                                     // Migrate LD<X>'s label to LDWI
---
>                                     if(savedLD._opcode.find("LDWI") != std::string::npos) offset += 1;
>                                     
>                                     // Discard it's label, (it's no longer needed), and adjust it's address
945c966
<                                     savedLD._address += 17; // LD<X> is moved 17 bytes
---
>                                     savedLD._address += offset; // LD<X> is moved 17bytes, LDWI is moved 18 bytes
954,956c975,990
<                                     itVasm = Compiler::getCodeLines()[i]._vasm.insert(itVasm, savedLD);
<                                     adjustLabelAddresses(i, firstLine - 1, -4);
<                                     adjustVasmAddresses(i, firstLine - 1, -4);
---
>                                     if(offset == 17)
>                                     {
>                                         itVasm = Compiler::getCodeLines()[i]._vasm.insert(itVasm, savedLD);
>                                         adjustLabelAddresses(i, firstLine - 1, -4);
>                                         adjustVasmAddresses(i, firstLine - 1, -4);
>                                     }
>                                     // LDW is replaced with LDWI so push everything forward starting at the last LDW by 1 more byte
>                                     else
>                                     {
>                                         itVasm = Compiler::getCodeLines()[i]._vasm.insert(itVasm, savedLD);
>                                         adjustLabelAddresses(i, firstLine - 1, -5);
>                                         adjustVasmAddresses(i, firstLine - 1, -5);
>                                         adjustLabelAddresses(i, firstLine + 6, 1);
>                                         adjustVasmAddresses(i, firstLine + 6, 1);
>                                     }
> 
wbushby
Posts: 48
Joined: 16 Jul 2021, 10:59

Re: gtBASIC

Post by wbushby »

worked. thank you again.
wbushby
Posts: 48
Joined: 16 Jul 2021, 10:59

Re: gtBASIC

Post by wbushby »

Found an interesting situation from the label being associated to a return off the stack. I had a subroutine translated from ASM to Basic that did this:

LOOP1:
DO SUBROUTINE2

SUBROUTINELABEL: ' (Label for external call to subroutine)
DO SOMETHING
X = X-1
IF X > 0 THEN GOTO LOOP1

RETURN

This created a subroutine that went somewhere weird when it encountered the return.

Personally there is nothing to fix here but it is a warning to other people doing an ASM to Basic translation.
wbushby
Posts: 48
Joined: 16 Jul 2021, 10:59

Re: gtBASIC

Post by wbushby »

The problem you fixed with the optimiser is still there but it doesn't give that overlap error message.
I have 2 variables that have the same address again without any warning and the 11,500 bytes free.
Attachments
collide.jpg
collide.jpg (613.33 KiB) Viewed 153 times
at67
Posts: 384
Joined: 14 May 2018, 08:29

Re: gtBASIC

Post by at67 »

wbushby wrote: 09 Sep 2021, 13:28 The problem you fixed with the optimiser is still there but it doesn't give that overlap error message.
I have 2 variables that have the same address again without any warning and the 11,500 bytes free.
You'll have to send me the code again, just a quick note, the optimiser relocation problem was not causing the overlapping of variables, it was causing code to be relocating incorrectly and then causing the memory manager to try and allocate code RAM that was already allocated. This kind of problem can cause anything to happen, (i.e. undefined behaviour), as some portion of code that was meant to be emitted could not be emitted from the RAM allocation collision. (i.e. When you app tries to execute code that it thinks will be at a certain place in memory, it won't be there and it will try and execute what is there, e.g. random bytes, other code, program data etc).

The variable overlap issue you are currently seeing is in zero page memory, (any address < 256), this can only be caused by two zero page vars allocated to the same address, which can only happen if you have more than the following number of zero page vars in your app:

Code: Select all

'ROM1, ROM2, ROM3, ROM4
(0x80 - 0x30)/2 = 40 zero page vars

'ROM5a or higher without VBlank Interrupt
(0x80 - 0x30)/2 + (0xC0 - 0xD4)/2 = 50 zero page vars

'ROM5a/DEVROM with VBlank Interrupt
(0x80 - 0x36)/2 + (0xC0 - 0xD4)/2 = 47 zero page vars

'ROMvX0 with VBlank Interrupt
(0x80 - 0x38)/2 + (0xC0 - 0xD4)/2 = 46 zero page vars
Are you sure you're not getting any "Compiler::checkIntVar() : '%s:%d' : warning, you have used the maximum number of page zero variables : %s\n" messages?

P.S. I will change the compiler so that warnings stop the compilation process, (which will force the programmer to fix them), rather than ignoring them. The reason these warnings didn't stop the compilation process before today was that I envisaged scenarios where you could code completely isolated sections of code from each other and re-use vars without fear of overlap. e.g. think mutually exclusive levels in a game, level 1 could use all finite resources, (such as zero page vars), then level 2 could re-use all those finite resources, etc. I'll come up with a more explicit way of re-using vars and arrays, (probably an alias keyword), so that the programmer assumes the responsibility for unintended behaviour, rather than the compiler causing it implicitly and only producing ignorable warnings about it.
wbushby
Posts: 48
Joined: 16 Jul 2021, 10:59

Re: gtBASIC

Post by wbushby »

Is there a possibility of having non-zero page integer variables ? That would solve the problem in my case.
at67
Posts: 384
Joined: 14 May 2018, 08:29

Re: gtBASIC

Post by at67 »

There will be for ROMvX0, but not for lower version ROM's.

For lower version ROM's use arrays, (try and limit them to 96 bytes or less, i.e. 48 elements for normal int16 vars, as they will fit in offscreen memory and not abuse your precious less segmented memory), e.g:

Code: Select all

'misc byte array, i.e. uint8
dim misc_u8%(4) = 0, 1, 2, 3, 4
print misc_u8(0)

'misc int16 array
dim misc_i16(4) = 1000, 1001, 1002, 1003, 1004
print misc_i16(0)

'for bonus points use constants
const level = 0
const lives = 1
const score = 2
dim m(2) = 1, 3, 0
print m(level)
print m(lives)
print m(score)
wbushby
Posts: 48
Joined: 16 Jul 2021, 10:59

Re: gtBASIC

Post by wbushby »

well have my 180 variables down to 60. 30 to go...
wbushby
Posts: 48
Joined: 16 Jul 2021, 10:59

Re: gtBASIC

Post by wbushby »

What does this error mean and how do I look for the cause?

'"contains native code or file system error"

I had this once before and it went away after a couple of changes. This time it is sticking around. The compile goes all the way through to writing the GT1 file then fails.
Post Reply