Jump to content

Photo

IntyBASIC and Memory Ordering?


17 replies to this topic

#1 First Spear OFFLINE  

First Spear

    Stargunner

  • 1,260 posts
  • Location:Somewhere in Uptown

Posted Thu Nov 16, 2017 7:46 PM

In 42k.bas, the ROM segments are arranged this way:

REM SEGMENT ADDRESS RANGE  SIZE  NOTES
REM ======= ============== ===== =====
REM    0    $5000 to $6FFF $2000 - Default segment
REM    1    $A000 to $BFFF $2000
REM    2    $C040 to $FFFF $3FC0 - Avoid STIC aliasing.
REM    3    $2100 to $2FFF $0F00
REM    4    $7100 to $7FFF $0F00 - Avoid EXEC's ECS ROM probe.
REM    5    $4810 to $4FFF $0800 - Account for game's ECS ROM mapping out code.
REM -------------------------------------------------------------------------

Shouldn't they be ordered this way?

REM SEGMENT ADDRESS RANGE  SIZE  NOTES
REM ======= ============== ===== =====
REM    0    $2100 to $2FFF $0F00   
REM    1    $4810 to $4FFF $0800 - Account for game ECS ROM mapping out code.  
REM    2    $5000 to $6FFF $2000 - Default segment  
REM    3    $7100 to $7FFF $0F00 - Avoid EXEC ECS ROM probe.
REM    4    $A000 to $BFFF $2000
REM    5    $C040 to $FFFF $3FC0 - Avoid STIC aliasing.
REM -------------------------------------------------------------------------

Edited by First Spear, Thu Nov 16, 2017 7:50 PM.


#2 intvnut OFFLINE  

intvnut

    River Patroller

  • 3,025 posts
  • Location:@R6 (top of stack)

Posted Thu Nov 16, 2017 8:31 PM

The numbering is arbitrary.  $5000 gets front row because that's where the ROM header lives.  That's where the EXEC looks for it, at least.



#3 carlsson ONLINE  

carlsson

    Metagalactic Mule

  • 7,084 posts
  • Location:Västerås, Sweden

Posted Fri Nov 17, 2017 2:52 AM

I suppose the segments are ordered by default and size, with an exception to areas where you have to avoid a few bytes that actually are in use. It seems logical to me to access those $2000 and $3FC0 sized areas prior to carving into the $0F00 and $0800 sized areas.



#4 artrag OFFLINE  

artrag

    Stargunner

  • 1,020 posts

Posted Mon Mar 5, 2018 1:51 AM

Are those segments kilowords?
I was expecting that doing in this way:


ASM ORG $C000

' The chunks of sound data

#sound_data:
INCLUDE "output.bas"
data $0000
end_file:

ASM ORG $A000

would have allowed to fully use 32Kilobytes of rom for data in output.bas
I have instead strange troubles when passing the 16kiblobytes (i.e. 8 kilowords) in segment at c000h
From the .lst file all the intybasic code is in other segments

Any hint of what could be wrong?


Edited by artrag, Mon Mar 5, 2018 4:20 PM.


#5 Kiwi OFFLINE  

Kiwi

    Stargunner

  • 1,564 posts

Posted Mon Mar 5, 2018 5:13 AM

Are those segments kilowords?
I was expecting that doing in this way:


ASM ORG $C000

' The chunks of sound data

#sound_data:
INCLUDE "output.bas"
data $0000
end_file:

ASM ORG $A000

would have allowed to fully use 32Kilobytes of rom for data in output.bas
I have instead strange troubles when passing the 16kiblobytes (i.e. 8 kilowords) in segment at c000h
From the. lst file all the intybasic code is in other segments

Any hint of what could be wrong?

There are alias at $c000-$c040.  I would put ASM ORG $C100. That space $C100- $FFFF is 16127 16-bit word.  32254 bytes.


Edited by Kiwi, Mon Mar 5, 2018 5:14 AM.


#6 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 10,865 posts
  • Triple-Stripe Mo' Bro
  • Location:NC, USA

Posted Mon Mar 5, 2018 6:05 AM

Are those segments kilowords?
I was expecting that doing in this way:


ASM ORG $C000

' The chunks of sound data

#sound_data:
INCLUDE "output.bas"
data $0000
end_file:

ASM ORG $A000

would have allowed to fully use 32Kilobytes of rom for data in output.bas
I have instead strange troubles when passing the 16kiblobytes (i.e. 8 kilowords) in segment at c000h
From the. lst file all the intybasic code is in other segments

Any hint of what could be wrong?

 
Yes, the "K" in the Intellivision nomenclature is typically 16-bit Kilo-words.
 
The available blocks of memory for program use on the Intellivision is scattered across the entire memory map.  This is due to technical constraints of the hardware, as well as allocated blocks for dedicated peripherals.
 
The typical memory map for cartridge use is as follows, taken from the latest SDK-1600 CART.MAC macro library:

                ; --------------------------------------
                ; Memory map for 42K ROM cartridge
                ; --------------------------------------
                ;   SEGMENT     RANGE
                ;      0        $5000 - $6FFF :  8K
                ;      1        $A000 - $BFFF :  8K
                ;      2        $C040 - $FFFF : 16K
                ;      3        $2100 - $2FFF :  4K
                ;      4        $7100 - $7FFF :  4K
                ;      5        $4800 - $4FFF :  2K
                ;
                ;      CARTRAM  $8040 - $9EFF :  8K
                ; --------------------------------------

You can find a description of the full memory map in memory_map.txt file included in the SDK-1600 documentation folder.  I've attached it for your convenience.

 

As alluded by Kiwi and confirmed in that document, the block in the range 0xC000 - 0xC03F is reserved for STIC register aliases during VBLANK.

 

   -dZ.



#7 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 10,865 posts
  • Triple-Stripe Mo' Bro
  • Location:NC, USA

Posted Mon Mar 5, 2018 6:13 AM

By the way, this is the reason the "ASM" statement is allowed for the "ORG" instruction in the contest, and why this particular manual technique of memory alignment is recommended:  because the memory map is fragmented and because IntyBASIC compiles into Assembly Language and has no linker, it has no access to the actual memory locations consumed by its code.  Consequently, it cannot automatically allocate the code throughout the memory map, and the programmer must do it himself.

 

   -dZ.



#8 artrag OFFLINE  

artrag

    Stargunner

  • 1,020 posts

Posted Mon Mar 5, 2018 9:06 AM

Bug solved, it was a problem in my data and moving the epilogue at A000h is fine.


Edited by artrag, Mon Mar 5, 2018 4:20 PM.


#9 intvnut OFFLINE  

intvnut

    River Patroller

  • 3,025 posts
  • Location:@R6 (top of stack)

Posted Thu Mar 8, 2018 6:52 PM

By the way, this is the reason the "ASM" statement is allowed for the "ORG" instruction in the contest, and why this particular manual technique of memory alignment is recommended:  because the memory map is fragmented and because IntyBASIC compiles into Assembly Language and has no linker, it has no access to the actual memory locations consumed by its code.  Consequently, it cannot automatically allocate the code throughout the memory map, and the programmer must do it himself.

 

It's unfortunate that the contest mandates using the stock intybasic_prologue.asm and intybasic_epilogue.asm.  Otherwise, you could use the versions I've posted previously that integrated it w/ cart.mac.  This at least does a better job of managing the memory map, and it even will split up the epilogue code and fit it into holes in the memory map for you.  With the cart.mac modification, you don't have to care quite as much about your ROM segments, and you get a nice clean report after assembling of where you have space, where you don't, and whether you've overflowed any segments.

 

I understand the goal is to ensure the entire game is written in IntyBASIC and not in assembly.  It's too bad it rules out such a useful tool, though.



#10 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 10,865 posts
  • Triple-Stripe Mo' Bro
  • Location:NC, USA

Posted Fri Mar 9, 2018 4:06 AM

 

It's unfortunate that the contest mandates using the stock intybasic_prologue.asm and intybasic_epilogue.asm.  Otherwise, you could use the versions I've posted previously that integrated it w/ cart.mac.  This at least does a better job of managing the memory map, and it even will split up the epilogue code and fit it into holes in the memory map for you.  With the cart.mac modification, you don't have to care quite as much about your ROM segments, and you get a nice clean report after assembling of where you have space, where you don't, and whether you've overflowed any segments.

 

I understand the goal is to ensure the entire game is written in IntyBASIC and not in assembly.  It's too bad it rules out such a useful tool, though.

 

I agree.  Personally, I wouldn't be opposed to nanochess releasing a new version of IntyBASIC in the middle of the contest and letting programmers decide whether they want to use it or not.  It shouldn't give anybody any particular advantage in their games.  A new version of IntyBASIC could include this and whatever features artrag was requesting.

 

I understand that nanochess does not want to introduce changes during the contest, but it is certainly something to consider, and it may not be too bad.  Then again, we want to minimize the expense of scouring through every entry's source code in order to confirm it is valid, and allowing multiple version or prologues/epilogues increases the time and effort involved.

 

I know it was a pain last year to do this, I had to create multiple environments for each version of IntyBASIC available in order to build each game individually.  I imagine it gets worse if a judge had to analyse each version of the included libraries to ensure there was nothing else than cart.mac in there.

 

In any case, we'll always have next year's contest. :)

 

   -dZ.



#11 artrag OFFLINE  

artrag

    Stargunner

  • 1,020 posts

Posted Fri Mar 9, 2018 1:52 PM

Well, the list with feature requests is already long, and even more requests will come as the contest progresses. I think that Oscar wants to have a full picture of needs and proposals before evolving the compiler.

To me, at the moment, there is nothing that I cannot cope with some trick or workaround.

 

Anyway, whatever decision Oscar takes, it will be fine. 

 

About feature requests, I've spotted a possible improvement (another :-) )

Now you can use:

 

on frame gosub 

 

only once in the source.

 

If you try to change the subroutine or just to remove it at all you simply cannot.

The compiler gives error if you try to change ISR and there is no way to point to an empty ISR to disable it.

 

My workaround is to build a large "switch/case" in the unique ISR you are allowed to call and live with it.

 

This can be not efficient, especially if you need many optional subroutines, as the reiterate comparisons cost precious CPU time during the Vblank.

 

Anyway, changing the ISR pointer by using twice or three times the "on frame gosub" command should be possible as usually the hook to the current ISR is in RAM.

So it should be just matter of writing an address in a RAM location.

Or not?

 

:-D



#12 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 10,865 posts
  • Triple-Stripe Mo' Bro
  • Location:NC, USA

Posted Fri Mar 9, 2018 2:27 PM

Well, the list with feature requests is already long, and even more requests will come as the contest progresses. I think that Oscar wants to have a full picture of needs and proposals before evolving the compiler.
To me, at the moment, there is nothing that I cannot cope with some trick or workaround.
 
Anyway, whatever decision Oscar takes, it will be fine. 
 
About feature requests, I've spotted a possible improvement (another :-) )
Now you can use:
 
on frame gosub 
 
only once in the source.
 
If you try to change the subroutine or just to remove it at all you simply cannot.
The compiler gives error if you try to change ISR and there is no way to point to an empty ISR to disable it.
 
My workaround is to build a large "switch/case" in the unique ISR you are allowed to call and live with it.
 
This can be not efficient, especially if you need many optional subroutines, as the reiterate comparisons cost precious CPU time during the Vblank.
 
Anyway, changing the ISR pointer by using twice or three times the "on frame gosub" command should be possible as usually the hook to the current ISR is in RAM.
So it should be just matter of writing an address in a RAM location.
Or not?
 
:-D


I believe that "On Frame Gosub" does not change the actual ISR, which is reserved by IntyBASIC's runtime. It only sets up a call-back to be called after the ISR runs. I further believe it is called outside the context of the ISR itself, so it is outside the VBLANK critical path.

(Oscar, please correct me if my understanding is wrong.)

The problem with the "On Frame Gosub" idiom is that you can only ever have a single one because there is no mechanism to assign a new call-back within the normal flow of the program (think of the idiom not as a statement executed inline, but more like a declarative directive that gets compiled into the global space of the program, like PROC or DATA, which are independent of flow positioning).

Ideally, what you want is a runtime assignment of the frame call-back. I agree that this would be very useful, but it is definitely a different mode of operation.

As for changing the actual ISR, I think that would break many IntyBASIC features, and you wouldn't be able to guarantee the stability of the environment on re-entry.

I guess if you really, really wanted to, you could POKE your way into doing it, though I wouldn't recommend it.

dZ.

#13 nanochess OFFLINE  

nanochess

    Processorus Polyglotus

  • 5,423 posts
  • Coding something good
  • Location:Mexico City

Posted Sat Mar 10, 2018 12:31 PM

The subroutine label used in ON FRAME GOSUB is used by IntyBASIC to insert a CALL inside intybasic_epilogue.asm >inside< the ISR :grin:!

 

Sorry but this was my "smart" way of not using a 16-bits variables and indeed it is fixed.

 

If you need multiple ON FRAME GOSUB then I would recommend to setup your routine like this:

frame_on_gosub:  PROCEDURE
    ON mode GOTO mode_0, mode_1, mode_2
mode_0:
     ...
     RETURN
 
mode_1:
     ...
     RETURN
 
mode_2:
     ...
     RETURN
 
END
 


#14 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 10,865 posts
  • Triple-Stripe Mo' Bro
  • Location:NC, USA

Posted Mon Mar 12, 2018 5:48 AM

 

The subroutine label used in ON FRAME GOSUB is used by IntyBASIC to insert a CALL inside intybasic_epilogue.asm >inside< the ISR :grin:!

 

Sorry but this was my "smart" way of not using a 16-bits variables and indeed it is fixed.

 

 

So... theoretically, if the "ON FRAME GOSUB" subroutine executes for too long without returning, and it calls many subroutines deep, it can cause the ISR to re-enter and potentially blow the stack?   :o

 

(By the way, I see in the epilogue that your "_int_vector" routine PSHR's the return address at the top and then PULR's it back at the end.  You can save a few precious cycles by avoiding the PSHR and just jumping back directly to the EXEC's ISR dispatcher at 0x1014,which is the return address and is constant -- that is, unless there's a chance it is called from somewhere else.)

 

    -dZ.



#15 Kiwi OFFLINE  

Kiwi

    Stargunner

  • 1,564 posts

Posted Mon Mar 12, 2018 11:21 AM

So... theoretically, if the "ON FRAME GOSUB" subroutine executes for too long without returning, and it calls many subroutines deep, it can cause the ISR to re-enter and potentially blow the stack?   :o

    -dZ.



I like this bit in the manual.

 

Also it's your responsibility that the code doesn't take too long, otherwise
video frame interrupts will accumulate and your memory stack will overflow.

He take no responsibility if you blow up your stack. So use ON FRAME GOSUB at your own risk.  No warranties to replace your Intellivision if you happen to blow one up.
 



#16 DZ-Jay OFFLINE  

DZ-Jay

    Quadrunner

  • 10,865 posts
  • Triple-Stripe Mo' Bro
  • Location:NC, USA

Posted Mon Mar 12, 2018 12:29 PM

I like this bit in the manual.

 
He take no responsibility if you blow up your stack. So use ON FRAME GOSUB at your own risk.  No warranties to replace your Intellivision if you happen to blow one up.
 


Sounds fair. :)

I only mention it because the ISR takes 8 words of the stack to store system state. If it re-enters, that's 16 words. This could be mitigated by calling the subroutine outside the context of the ISR (i.e., reducing the potential side-effect of re-entry from 16 to 8 words).

P.S. For those who may take this seriously, "blowing the stack" may cause your program to crash or variables to get corrupted (or both), but does no harm at all to your console. That was a joke.

#17 carlsson ONLINE  

carlsson

    Metagalactic Mule

  • 7,084 posts
  • Location:Västerås, Sweden

Posted Mon Mar 12, 2018 2:14 PM

Actually the other week I pondered if there is a "Killer POKE" on the Intellivision, but I presume not.



#18 intvnut OFFLINE  

intvnut

    River Patroller

  • 3,025 posts
  • Location:@R6 (top of stack)

Posted Tue Mar 13, 2018 3:12 PM

Actually the other week I pondered if there is a "Killer POKE" on the Intellivision, but I presume not.

 

There is none for the Master Component.  It remains to be seen if there's such a thing for the Keyboard Component.  Perhaps you could damage a solenoid in the tape drive if you leave it energized, for example.

 

There's the motor control relay in the ECS, and you can make it buzz by toggling it fast enough.  Presumably you could wear out the relay prematurely if you're bored.






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users