Jump to content
IGNORED

IntyBASIC compiler v1.2.9: The good things are now better!


Recommended Posts

Copying this from another thread, because I think it may be useful to IntyBASIC programmers. TL;DR: With the attached tweaks to IntyBASIC 1.2.5's intybasic_prologue.asm, intybasic_epilogue.asm and the new file intybasic_cart.mac, you have a cleaner alternative to ORG statements for large games. The assembler will also detect ROM overflows and tell you just how much room is left in every ROM segment. This is a lightly-tested proof of concept, and I think it's a great starting point for extending IntyBASIC to make it easier to make games larger than 8K words if nanochess and others want to run with it.

 

_____________________________

 

Ok, I did a quick conversion of IntyBASIC to cart.mac again, and wrote up an example based on the existing 42K.BAS example in the contrib folder. When you assemble this example, you'll get a summary from the assembler:

.

$ as1600 -o 40k_cartmac.bin -l 40k_cartmac.lst 40k_cartmac.asm 
=================================================================
          Program size:        $0375 (885 dec) words
          ROM available:       $9A8B (39563 dec) words
-----------------------------------------------------------------
       Range    Start    End           :     Used    Avail
         0:     $5000 - $6FFF          :    $026F    $1D91
         1:     $8100 - $BFFF          :    $0084    $3E7C
         2:     $C100 - $FFFF          :    $0082    $3E7E
=================================================================
 ERROR SUMMARY - ERRORS DETECTED 0
               -  WARNINGS       0

.

If I did everything correctly, the assembler will put all of the library code in intybasic_epilog.asm into the ROM segments where there's room, automatically. No more "leaving some room in the last segment" trickery.

 

To change ROM segments, you just insert the statement "asm ROMSEG x", where x is 0, 1 or 2, to start assembling in that segment. You can switch ROM segments as often as you like; the ROMSEG directive keeps track of how full each segment is, and won't assemble over any existing code.

 

And, if you overflow the memory map, you'll get an error at assembly time, rather than a silent crash.

 

This is an update to an earlier tweak I had made of this form. This time, I used IntyBASIC 1.2.5 as my base, so you should be able to drop in these files on a fresh IntyBASIC 1.2.5 folder and start experimenting.

 

All this is released to the public domain / free for everyone to use for whatever purpose. It can be extended to other memory maps, better integrated in IntyBASIC and so on. This is just a good starting point. :-)

 

Please, try it and let me know how it works for you.

 

 

EDIT: There was a big bug in the version I posted a few minutes ago. I think I've fixed it. Please download it again.

intybasic_cartmac.zip

Edited by intvnut
Link to comment
Share on other sites

I think this is a bug in the manual, in the area discussing PRINT:

 

 

I think bit 2 and bit 3 are reversed here. Both from what I know, plus explicit testing. I had this backwards at some point too, so I wonder if there's a STIC guide out there with the wrong register details.

Welll spotted! Why aren't you using constants.bas where this is all taken care of ;) :P.

Link to comment
Share on other sites

I think bit 2 and bit 3 are reversed here. Both from what I know, plus explicit testing. I had this backwards at some point too, so I wonder if there's a STIC guide out there with the wrong register details.

 

Well, even without an incorrect guide out there, it is a goofy bit ordering. I know it's tripped me up once or twice even.

 

I just checked stic.txt, and it gets it right. So does the page I wrote at the Wiki, including this handy graphic I drew:

 

Stic_fgbg_word.png

 

It's such a goofy ordering, though, that it's easy to see how someone might get it backward.

 

¯\_(ツ)_/¯

Link to comment
Share on other sites

 

Why do any of you still code in ASM, when IntyBASIC takes care of everything for you? :P

Like GroovyBee said, not everything. And even those things of which it takes care, most do not conform to my mental model of game programming.

 

In my own high-level-ish framework, I go for a more object-oriented and event-driven model, deferring to the framework to handle decoding, timing, system events, and dispatching.

 

dZ.

Edited by DZ-Jay
Link to comment
Share on other sites

I like how .lst is a good back-up copy of your source code. :thumbsup: Mad Bomber was corrupted past line 3439. Mad Bomber source code was open and the computer would shut off occasionally in sleep mode when the hard drive locks up or stop working. The hard drive was on its last leg back in October when I had the file open. Last January, had all of my data cloned on to the new hard drive. And the issue is solved, and I don't have to worry about my computer not booting up ever again with a dead hard drive.

 

So I had this idea at work, why not look at the .lst file and see if your source is there and the line number. I was able to extract and repair the 300 lines I had. I don't have to redraw the big mad bomber sprite or figure out what intycolor tile information is needed in the source code. I can resume this project soon, when I get in the mood.

Link to comment
Share on other sites

I like how .lst is a good back-up copy of your source code. :thumbsup: Mad Bomber was corrupted past line 3439. Mad Bomber source code was open and the computer would shut off occasionally in sleep mode when the hard drive locks up or stop working. The hard drive was on its last leg back in October when I had the file open. Last January, had all of my data cloned on to the new hard drive. And the issue is solved, and I don't have to worry about my computer not booting up ever again with a dead hard drive.

 

So I had this idea at work, why not look at the .lst file and see if your source is there and the line number. I was able to extract and repair the 300 lines I had. I don't have to redraw the big mad bomber sprite or figure out what intycolor tile information is needed in the source code. I can resume this project soon, when I get in the mood.

 

Just a suggestion but... couldn't you just make a copy of the ".bas" source file and place it in the same location as your ".lst" listing file? ;)

 

-dZ.

  • Like 1
Link to comment
Share on other sites

I usually make a copy of a source code if I'm adding new features or a major rewrite. The old source code doesn't have the gravity feature, and introduction scenes. .lst file saved my butt.

Here's a sample of the .lst file

			;	SRCFILE "KaboomArray.bas",3717
				; macro must be non-empty, but a comment works fine.
				;[3718] OUTSIDECARD:
			;	SRCFILE "KaboomArray.bas",3718
				; macro must be non-empty, but a comment works fine.
				; OUTSIDECARD
0xE884                  Q19:	;[3719] 	DATA $0054,$0054,$0054,$0054
			;	SRCFILE "KaboomArray.bas",3719
				; macro must be non-empty, but a comment works fine.
E884 0054 			DECLE 84
E885 0054 			DECLE 84
E886 0054 			DECLE 84
E887 0054 			DECLE 84

It show what I have written after the [3719]. I can crop out my code.

  • Like 1
Link to comment
Share on other sites

  • 4 weeks later...

nanochess/intvnut: I'm (finally!) setting my system up "properly", in terms of file pathing. Not just cramming everything into one spot. Took me a while to get it working, however.

 

Because I obviously don't want these files in my current working directory now, intybasic_linux requires that I specify the path to the prologue/epilogue in its command. And jzintv requires exec/grom/ecs in /usr/local/share/jzintv/rom.

 

Silly question, perhaps, but why don't these look in my $PATH for these files? I can work around this, it's just a bit of extra setup that I wasn't expecting. Disclaimer: it's early on a Saturday and I may well just be being stupid :P

Link to comment
Share on other sites

nanochess/intvnut: I'm (finally!) setting my system up "properly", in terms of file pathing. Not just cramming everything into one spot. Took me a while to get it working, however.

 

I think you meant me, since even nanochess originally advocated for a single centralized folder for everything. :P

 

I'm obsessive enough that I created the "DZ-Special Edition" before the SDK, with all files organized in folders.

 

Because I obviously don't want these files in my current working directory now, intybasic_linux requires that I specify the path to the prologue/epilogue in its command. And jzintv requires exec/grom/ecs in /usr/local/share/jzintv/rom.

 

jzIntv supports the "JZINTV_ROM_PATH" environment, so you just set that up and copy your base ROMs in there. IntyBASIC doesn't support an environment variable yet, so you'll have to set the "library" path in the command line.

 

Personally, I create shell scripts for those, which is what lead to the SDK. (Actually, I use Perl, not Bash, but hey!)

 

Below are my scripts, in case they interest you. The IntyBASIC one uses a custom environment variable, but you can set the path manually in the script header.

 

jzIntv:

 

 

#!/usr/bin/perl

# -------------------------------------------------------------------
# PROGRAM:      runintv.pl
# AUTHOR:       James Pujals (a.k.a. DZ-Jay)
# DESCRIPTION:  Executes an Intellivision ROM using jzIntv emulator.
# LAST UPDATED: 2015-02-24
#
# LICENSE:      This crappy "program" has been released to the public
#               domain by the author.  No claims of ownership are
#               made.  In fact, I regret putting my name on it. 
# -------------------------------------------------------------------

# -------------------------------------------------------------------
# CONFIGURATION
# -------------------------------------------------------------------
my $INTV_ROM_PATH = "~/Intellivision/jzintv/rom"; # Path to base ROMs
my $DISPLAY_SIZE  = 3                             # 640x480x8bpp

# -------------------------------------------------------------------
# EXECUTE ROM
# -------------------------------------------------------------------
my $flags    = '';
my $filename = pop(@ARGV) or usage();   # The last argument should be the filename to execute
   $filename =~ s/\.(bin|asm|rom)$//;

$flags = join(' ', "-e ${ INTV_ROM_PATH }/exec.bin",            # Exec ROM
                   "-E ${ INTV_ROM_PATH }/ecs.bin",             # ECS ROM
                   "-g ${ INTV_ROM_PATH }/grom.bin",            # GROM
                   "--displaysize=${ DISPLAY_SIZE }",           # 3 (640x480x8bpp)
                   @ARGV);                                      # User-provided arguments

$command = "jzintv ${ flags } ${ filename }";
exec($command);
exit;

# -------------------------------------------------------------------
# SUBROUTINES
# -------------------------------------------------------------------
sub usage()
{
    my ($prog) = ($0 =~ /.*\/(.+)/);
    die("Usage: $prog [flags] filename\n");
}
 

 

 

 

 

IntyBASIC:

 

 

#!/usr/bin/perl

# -------------------------------------------------------------------
# PROGRAM:      intbas.pl
# AUTHOR:       James Pujals (a.k.a. DZ-Jay)
# DESCRIPTION:  Compiles a BASIC source file using IntvBasic compiler
#               and then assembles it using AS-1600 assembler.
# LAST UPDATED: 2014-10-24
#
# LICENSE:      This crappy "program" has been released to the public
#               domain by the author.  No claims of ownership are
#               made.  In fact, I regret putting my name on it. 
# -------------------------------------------------------------------

use Cwd;

my $ASSEMBLER= 'as1600';
my $COMPILER = 'intybasic';
my $PROLOGUE = 'intybasic_prologue.asm';
my $EPILOGUE = 'intybasic_epilogue.asm';            # MAKE SURE TO CONFIGURE THESE:
my $SDK_PATH = $ENV{'INTV_SDK_PATH'  };             #   Base path to the SDK-1600 installation.
my $BAS_PATH = $ENV{'INTV_BASIC_PATH'};             #   Base path to the IntyBasic installation.
my $LIB_PATH = $BAS_PATH . "/lib";                  #   Location of prologue and epilogue files.
my $COM_PATH = $BAS_PATH . "/bin";                  #   Location of IntyBasic binaries
my $ASM_PATH = $SDK_PATH . "/bin";                  #   Location of SDK binaries

# -------------------------------------------------------------------
# PROCESS INPUT
# -------------------------------------------------------------------
my $src_path = shift(@ARGV) or usage();
my ($path,
    $fullname,
    $name,
    $ext)    = ($src_path =~ m/^(.+\/)?(([^\/]+)\.([\w]+))$/i);
my $asm_dir  = $path . "asm";
my $bin_dir  = $path . "bin";
my $asm_file = "${ name }.asm";

# -------------------------------------------------------------------
# VALIDATE INPUT
# -------------------------------------------------------------------
    usage('Bad extension' ) unless ($ext eq 'bas');
    usage('Bad file path' ) unless ($fullname);
    usage('file not found') unless (!$path || -e $path);

    usage("Prologue not found in library path \"${ LIB_PATH }\"") unless (-e "${ LIB_PATH }/${ PROLOGUE }");
    usage("Epilogue not found in library path \"${ LIB_PATH }\"") unless (-e "${ LIB_PATH }/${ EPILOGUE }");
    usage("Compiler not found in binary path \"${ COM_PATH }\"") unless (-e "${ COM_PATH }/${ COMPILER }");
    usage("Assembler not found in binary path \"${ ASM_PATH }\"") unless (-e "${ ASM_PATH }/${ ASSEMBLER }");
    check_dirs($asm_dir, $bin_dir);

# -------------------------------------------------------------------
# COMPILE BASIC PROGRAM SOURCE
# -------------------------------------------------------------------
{
    # IntyBASIC now accepts a library path for the
    # Prologue and Epilogue modules, so we don't
    # need to make symbolic links anymore! YAY!

    my $intybasic = "${ COM_PATH }/${ COMPILER }";
    my $cmd_line  = "${ intybasic } ${ fullname } asm/${ asm_file } ${ LIB_PATH }";
    my $curr_dir = cwd();

    # Go to the source directory
    if ($path)
        {
        chdir "${ path }" or usage($!);
        }

        $result = `${ cmd_line }`;      # Compile..!

    # Return to whence we came
    if ($path)
        {
        chdir "${ curr_dir }" or usage($!);
        }
}

# -------------------------------------------------------------------
# ASSEMBLE ROM BINARY
# -------------------------------------------------------------------
{
    my $as1600    = $"${ ASM_PATH }/${ ASSEMBLER }";
    my $cmd_line  = "${ as1600 } -o ${ bin_dir }/${ name } -l ${ bin_dir }/${ name }.ls -s ${ bin_dir }/${ name }.sym -j ${ bin_dir }/${ name }.map ${ asm_dir }/${ asm_file }";

    $result = `${ cmd_line }`;
}

print "Done.\n";
exit;

# -------------------------------------------------------------------
# SUBROUTINES
# -------------------------------------------------------------------

sub usage
{
    my $err = shift(@_);

    print "ERROR: ${ err }\n" if ($err);

    my ($prog) = ($0 =~ /.*\/(.+)/);
    die("Usage: $prog source.bas\n");
}

sub check_dirs
{
    my ($asm, $bin) = @_;

    # Ensure we have an "asm" directory
    unless (-e $asm)
        {
        mkdir($asm) or usage($!);
        }

    # Ensure we have a "bin" directory
    unless (-e $bin)
        {
        mkdir($bin) or usage($!);
        }
}

 

 

 

Note that these are most definitely "quick-and-dirty," and were made some time ago to get the job done. The fancy stuff came later in the SDK, but these were the roots of it. Please don't judge me. :lol:

 

 

Silly question, perhaps, but why don't these look in my $PATH for these files? I can work around this, it's just a bit of extra setup that I wasn't expecting. Disclaimer: it's early on a Saturday and I may well just be being stupid :P

 

As mentioned above, the jzIntv emulator looks in its own environment variable for the default location of ROMs. Nanochess said he would consider doing something similar for IntyBASIC, but he hasn't had a chance to do so.

 

He at least added the ability to add the library path in the command line -- prior to that, you had to place EVERYTHING in the same path. In those days, my script made symlinks of the libraries to maintain its organized structure. This is why there's a celebratory comment pointing out that we didn't need to do this anymore. :)

 

-dZ.

Edited by DZ-Jay
Link to comment
Share on other sites

You might want to consider setting up OneDrive or even Dropbox to get some free GB of storage, and installing Git on your local dev system, and set the "repository" to a local path that is mirrored to OneDrive. That way, you can always go back to previous commits, and since it is in the cloud if you have a disaster you have full offsite coverage. For the total investment of zero dollars.

 

 

I usually make a copy of a source code if I'm adding new features or a major rewrite. The old source code doesn't have the gravity feature, and introduction scenes. .lst file saved my butt.

Here's a sample of the .lst file

			;	SRCFILE "KaboomArray.bas",3717
				; macro must be non-empty, but a comment works fine.
				;[3718] OUTSIDECARD:
			;	SRCFILE "KaboomArray.bas",3718
				; macro must be non-empty, but a comment works fine.
				; OUTSIDECARD
0xE884                  Q19:	;[3719] 	DATA $0054,$0054,$0054,$0054
			;	SRCFILE "KaboomArray.bas",3719
				; macro must be non-empty, but a comment works fine.
E884 0054 			DECLE 84
E885 0054 			DECLE 84
E886 0054 			DECLE 84
E887 0054 			DECLE 84

It show what I have written after the [3719]. I can crop out my code.

Link to comment
Share on other sites

Silly question, perhaps, but why don't these look in my $PATH for these files? I can work around this, it's just a bit of extra setup that I wasn't expecting. Disclaimer: it's early on a Saturday and I may well just be being stupid :P

 

 

For jzIntv/SDK-1600, I don't look in $PATH from within jzIntv or AS1600, because there's a lot of crap that simply isn't relevant to either program. Instead, I look at two different environment variables:

  • JZINTV_ROM_PATH for all ROM images. The default ROM path varies slightly by system:
    • Linux, Solaris, FreeBSD: ".", "=../rom", and "/usr/local/share/jzintv/rom"
    • Mac, AmigaOS 4: ".", "=../rom"
    • Windows: ".", "=..\rom"
  • AS1600_PATH for all INCLUDE files. It defaults to "empty". AS1600 also always searches ".".

The components in each path are separated by : on Linux and Mac systems, and by ; on Windows systems.

 

AS1600 also understands the -i flag to add directories to your INCLUDE search path. I tend to use the -i file more than AS1600_PATH with AS1600, and only use JZINTV_ROM_PATH for exec.bin/grom.bin/ecs.bin.

 

The special directory "=" expands to the directory containing the jzIntv or AS1600 executable. So "=../rom" is "path/to/jzintv/bin/../rom". And the ".." cancels out "bin", leaving "path/to/jzintv/rom".

 

 

I don't know the best recommendation for IntyBASIC. But, as long as the jzIntv and AS1600 executables are in your path, you have a few options for making those two pieces happy, as noted above.

Edited by intvnut
Link to comment
Share on other sites

 

The special directory "=" expands to the directory containing the jzIntv or AS1600 executable. So "=../rom" is "path/to/jzintv/bin/../rom". And the ".." cancels out "bin", leaving "path/to/jzintv/rom".

 

 

Hm. That's pretty much what I expected, but it's not what I see in Linux. I get an error when trying it.

user@system:/path/to/jzintv-1.0-beta4/bin$ ls jz*
jzintv

user@system:/path/to/jzintv-1.0-beta4/rom$ ls
ecs.bin  exec.bin  grom.bin  README.txt

echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/path/to/jzintv-1.0-beta4/bin

user@system:/path/to/intv_dev/projects/game$ jzintv game.rom
file_read_rom16: No such file or directory
ERROR:  Could not read EXEC image 'exec.bin'

Search path:
  .
  ./../rom
  /usr/local/share/jzintv/rom

I think I'm doing it right? I find jzintv in bin just fine, but it seems to be looking in ./../rom, not /path/to/rom. Maybe I'm misunderstanding.

 

It's not the end of the world - dumping a copy of the ROMs into a usr/local directory is no biggie.

 

 

Thanks in general, to both you and DZ.

Link to comment
Share on other sites

 

Hm. That's pretty much what I expected, but it's not what I see in Linux. I get an error when trying it.

Search path:
  .
  ./../rom
  /usr/local/share/jzintv/rom

I think I'm doing it right? I find jzintv in bin just fine, but it seems to be looking in ./../rom, not /path/to/rom. Maybe I'm misunderstanding.

 

It's not the end of the world - dumping a copy of the ROMs into a usr/local directory is no biggie.

 

Well, you can also change JZINTV_ROM_PATH, but yes, this certainly appears to be a bug. We can take this to PM or email if you like. Are you running Beta 4 or one of the stable dev releases?

 

EDIT: FWIW, here's the 'brilliant' code I'm using to deduce the executable path. This code dates back to 'revision 25' of jzIntv, which dates back to 2006:

.

    /* -------------------------------------------------------------------- */
    /*  Figure out out our executable's path.  If none, assume ".".         */
    /* -------------------------------------------------------------------- */
    {
        char *s;

        exe_path = strdup(argv[0]);

        s = strrchr(exe_path, PATH_SEP);
        if (s)
            *s = 0;
        else
        {
            free(exe_path);
            exe_path = strdup(".");
        }
    }

.

So if it worked at one time, and doesn't work now, it's not because something changed in jzIntv. Hmmm....

 

EDIT 2: argv[0] doesn't seem to pick up the full path to the executable when it's invoked via $PATH:

.

$ cat testing/testargv0.c
#include <stdio.h>

int main(int argc, char *argv[])
{
	puts(argv[0]);
	return 0;
}

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/home/im14u2c/testing

$ ./testing/testargv0 
./testing/testargv0

$ ~/testing/testargv0 
/home/im14u2c/testing/testargv0

$ testargv0
testargv0

.

I guess I need to find a different, more robust way to find the executable's current directory. :-P I probably never noticed since I set JZINTV_ROM_PATH in my environment and forgot about it.

 

In the meantime... I'll go to the shame cube.

 

giphy.gif

Edited by intvnut
  • Like 1
Link to comment
Share on other sites

Does getcwd help you, or would it rather return the current working directory instead of the directory where the binary was found inside?

 

getcwd gets the current working directory, not the directory holding the executable. Turns out, getting the directory holding the executable is... fun.

  • Like 1
Link to comment
Share on other sites

 

EDIT 2: argv[0] doesn't seem to pick up the full path to the executable when it's invoked via $PATH:

.

.

I guess I need to find a different, more robust way to find the executable's current directory. :-P I probably never noticed since I set JZINTV_ROM_PATH in my environment and forgot about it.

 

 

Arg! (pun intended). I guess all 3 of us who use it in Linux have never stumbled upon this edge case.

 

The more I think about this, I rather like Oscar's solution for IntyBASIC - let the user specify the path as an explicit argument. I tend to bundle all of this up into shell scripts anyway, so adding a parameter there is simple, portable, and is maintained through a system re-image (which is what caused me to get into this in the first place, last week).

 

I have a personal loathing of environment variables, when they're not used for things that are more "universal" (like, for example, PATH). I've had nothing but headaches dealing with vendors and their ridiculous requirements to set up multiple environment variables all to deal with something that in 99.9% of cases, should be a static value - or just not needed at all. Why yes, I'm looking at you, Oracle.

 

Willing to add --rom-path?

Link to comment
Share on other sites

 

Willing to add --rom-path?

 

No, but only because it should already be there. :) It's spelled --rom-path, even.

 

I'm not at work, so I can't try it, but I see it is in the jzintv 1.0 beta4 source I have online. I don't think I would have removed it, though. If it's broken, I'll definitely fix it.

Link to comment
Share on other sites

 

No, but only because it should already be there. :) It's spelled --rom-path, even.

 

I'm not at work, so I can't try it, but I see it is in the jzintv 1.0 beta4 source I have online. I don't think I would have removed it, though. If it's broken, I'll definitely fix it.

 

It works. It's been eons since I've looked at the --help.

 

Thanks! And thanks to nanochess, for letting me once again hijack this thread to figure out jzintv stuff :)

 

"I'm not at work, so I can't test my video game stuff". That just comes out either really wrong, or really awesome.

Link to comment
Share on other sites

"I'm not at work, so I can't test my video game stuff". That just comes out either really wrong, or really awesome.

 

Err... actually, that's just a really silly typo. :) I originally wrote, "I'm not at home," but I realized that that doesn't usually stop me. I'm at work, and I'm strictly enforcing the "no personal code on work machines under any circumstances," even if it's precompiled and downloaded from elsewhere.

  • Like 1
Link to comment
Share on other sites

Once again not entirely sure where this should go....

 

I'm starting to finally play with JLP support in IntyBASIC and jzintv. I've been scratching my head for a few hours and I *think* I might finally know what's causing me grief. When I look at the jzintv output, I see this in its memory map:

 

JLP Support [0x8000...0x9FFF]

Is this where JLP is addressing its extra RAM? I've been shoving code into the $8100-$BFFF range as it gives a nice contiguous block of space to work in. The second I turned on JLP support in anything - my programs started crashing. I think this is the cause?

 

I can sacrifice 8K of ROM without losing too much sleep, it just means more juggling. I'll just have to remember that if I want to use cart saving, I need to give up some ROM in exchange.

Link to comment
Share on other sites

JLP Support [0x8000...0x9FFF]

 

Is this where JLP is addressing its extra RAM?

JLP RAM runs from $8040 - $9EFF

 

I can sacrifice 8K of ROM without losing too much sleep, it just means more juggling. I'll just have to remember that if I want to use cart saving, I need to give up some ROM in exchange.

Your choices are :

  • Juggle, juggle, juggle :P
  • Optimise what you've done so far so its takes less space.
  • Consider moving to a bank switched game.

If you want to optimise first, then post some code and then we can see if can be done in a more efficient way (if you're out of ideas on that).

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...