Jump to content
IGNORED

bB Tutorial


SeaGtGruff

Recommended Posts

Okay, I've screwed around long enough, so I'll just jump in... but not tonight. I've got M-Network bankswitching working in bB, and I'm putting together a package that contains

 

- bB version 0.35, slightly modified;

- 2600IDE version 0.4.1;

- DASM version 2.20.10b for MS-DOS;

- Stella for Windows from the October 5, 2005 nightly build;

- z26 version 2.13 for Windows;

- the postprocess program that I wrote (with the source code); and

- the PDF version of the Stella Programmer's Guide.

 

I've fixed the pfvline bug; I posted the corrected pf_drawing.asm file in the "Bug Report Thread" some weeks ago, but I don't think anyone besides batari noticed it. I've modified some of the include files to allow M-Network bankswitching if desired. I've organized everything into subdirectories. And I've changed the batch files to work with the subdirectories and compile correctly regardless of the desired game format-- standard 2K ROM image, standard 4K ROM image, or 16K ROM image for M-Network bankswitching.

 

I need to finish revising the readme and installation instructions, then later tonight I'll post my "all-in-one 2600bB package" in this thread-- but I won't try to explain it yet, aside from what's in the readme. Then I'll start posting tutorial stuff in this thread tomorrow night. Rather than trying to write "the perfect tutorial," I'll just write and post some lessons, and proceed from there based on the feedback I get. I plan to include information on using bankswitching and assembly programming with the "bB for beginners" instructions.

 

Michael Rideout

Link to comment
Share on other sites

. . . or 16K ROM image for M-Network bankswitching.

943638[/snapback]

Thanks. Does that just mean we'll have more room for code or are there other benefits or limitations? If that means going from a 4K limitation to 16K, even people like me who have a hard time chopping down our bloated code could make something worth playing.

 

 

I've fixed the pfvline bug; I posted the corrected pf_drawing.asm file in the "Bug Report Thread" some weeks ago, but I don't think anyone besides batari noticed it.

943638[/snapback]

I hope most people will know to use your fixed version after you post it. Having a fixed pfvline will be helpful. Now all we need is a fixed pfread and we'll be all set.

Link to comment
Share on other sites

. . . or 16K ROM image for M-Network bankswitching.

943638[/snapback]

Thanks. Does that just mean we'll have more room for code or are there other benefits or limitations? If that means going from a 4K limitation to 16K, even people like me who have a hard time chopping down our bloated code could make something worth playing.

 

 

I've fixed the pfvline bug; I posted the corrected pf_drawing.asm file in the "Bug Report Thread" some weeks ago, but I don't think anyone besides batari noticed it.

943638[/snapback]

I hope most people will know to use your fixed version after you post it. Having a fixed pfvline will be helpful. Now all we need is a fixed pfread and we'll be all set.

943677[/snapback]

Well, until more support is added to the bB compiler itself, the potential with bankswitching can't fully be realized.

 

Some limitations I think exist now are:

Data tables must be in same bank as code which accesses them

graphics must all be in same bank as kernel

subroutines must be in same bank as code that calls them

 

There's no mechanism in place yet to assure that the above is done automatically. There will be sooner or later, though.

 

When I do get to adding bankswitching support, however, I will probably start small, like with the F8 scheme. This doesn't add RAM as the M-Network does, but does give you 8k to play with. Other schemes will follow sooner or later.

 

BTW I'm getting caught up with work-related stuff so I'll dive back in and update bB shortly. I am having fun with the SI clone for now though - plus doing coding myself lets me see what other features I'd like to have in bB (and I have found a couple of bugs too.)

Link to comment
Share on other sites

. . . or 16K ROM image for M-Network bankswitching.

943638[/snapback]

Thanks. Does that just mean we'll have more room for code or are there other benefits or limitations? If that means going from a 4K limitation to 16K, even people like me who have a hard time chopping down our bloated code could make something worth playing.

943677[/snapback]

Yes, you'll have more room for code, at least in the lower bank area. bB will take up most of bank 7 in the upper bank area, so you'll have very little room left in bank 7 for your program.

 

You'll also have an extra 2K of RAM to work with, but it needs a little explaining before you try to use it, and I don't want to get too much into bankswitching yet, until after I get rolling with the tutorial (since I've kept putting it off).

I've fixed the pfvline bug; I posted the corrected pf_drawing.asm file in the "Bug Report Thread" some weeks ago, but I don't think anyone besides batari noticed it.

943638[/snapback]

I hope most people will know to use your fixed version after you post it. Having a fixed pfvline will be helpful. Now all we need is a fixed pfread and we'll be all set.

943677[/snapback]

I didn't look at the includes to see where pfread is and if I could fix it easily; I'll check into it this weekend.

 

Michael Rideout

Link to comment
Share on other sites

. . . or 16K ROM image for M-Network bankswitching.

943638[/snapback]

Thanks. Does that just mean we'll have more room for code or are there other benefits or limitations? If that means going from a 4K limitation to 16K, even people like me who have a hard time chopping down our bloated code could make something worth playing.

943677[/snapback]

Yes, you'll have more room for code, at least in the lower bank area. bB will take up most of bank 7 in the upper bank area, so you'll have very little room left in bank 7 for your program.

 

You'll also have an extra 2K of RAM to work with, but it needs a little explaining before you try to use it, and I don't want to get too much into bankswitching yet, until after I get rolling with the tutorial (since I've kept putting it off).

I've fixed the pfvline bug; I posted the corrected pf_drawing.asm file in the "Bug Report Thread" some weeks ago, but I don't think anyone besides batari noticed it.

943638[/snapback]

I hope most people will know to use your fixed version after you post it. Having a fixed pfvline will be helpful. Now all we need is a fixed pfread and we'll be all set.

943677[/snapback]

I didn't look at the includes to see where pfread is and if I could fix it easily; I'll check into it this weekend.

 

Michael Rideout

943715[/snapback]

I'm not sure it's possible to fix it by just modifying the .asm file. I think i remember that "if pfread(x,y) then linenumber" doesn't work but "if pfread(x,y) then goto linenumber" does. So fixing it to work with the first case would break the second case.

 

The problem is likely in the compiler itself :x I wonder if I should put out another maintenance release (like 0.37) before going into some of the big stuff that will take a lot of time.

Link to comment
Share on other sites

. . . or 16K ROM image for M-Network bankswitching.

943638[/snapback]

Thanks. Does that just mean we'll have more room for code or are there other benefits or limitations? If that means going from a 4K limitation to 16K, even people like me who have a hard time chopping down our bloated code could make something worth playing.

 

 

I've fixed the pfvline bug; I posted the corrected pf_drawing.asm file in the "Bug Report Thread" some weeks ago, but I don't think anyone besides batari noticed it.

943638[/snapback]

I hope most people will know to use your fixed version after you post it. Having a fixed pfvline will be helpful. Now all we need is a fixed pfread and we'll be all set.

943677[/snapback]

Well, until more support is added to the bB compiler itself, the potential with bankswitching can't fully be realized.

 

Some limitations I think exist now are:

Data tables must be in same bank as code which accesses them

graphics must all be in same bank as kernel

subroutines must be in same bank as code that calls them

943714[/snapback]

Actually, those things aren't necessarily true with schemes like E7 (M-Network) that divide the cartridge ROM area into two or more bank areas.

 

For example, ROM bank 7 is always in the upper bank area, so any data in that bank area will be accessible to ROM bank 7, as well as to any ROM bank selected for the lower bank area. Also, I've come up with ideas about how to handle the data problem with other cases, like copying the data into any bank that needs it, at the same location-- a little tricky, but not impossible.

 

Likewise, with E7 graphics can be in any of the ROM banks, and the kernel in ROM bank 7 will have access to them as long as the appropriate bank is selected in the lower 2K bank area.

 

Subroutines could be called between banks if handled cleverly, such as with a routine like the "do_it" routine I had posted (which you gave a better solution for, since it uses an indirect JMP).

 

These sorts of issues definitely exist with bankswitching, with or without bB, but bB does complicate the issue a bit because the bB routines need to be available. And these issues are especially tricky with schemes like F8 or F6 that switch the entire 4K ROM area, and throwing bB into the mix will make it even trickier-- which is why I stuck with just the E7 scheme for now.

There's no mechanism in place yet to assure that the above is done automatically.  There will be sooner or later, though.

 

When I do get to adding bankswitching support, however, I will probably start small, like with the F8 scheme.  This doesn't add RAM as the M-Network does, but does give you 8k to play with.  Other schemes will follow sooner or later.

 

BTW I'm getting caught up with work-related stuff so I'll dive back in and update bB shortly.  I am having fun with the SI clone for now though - plus doing coding myself lets me see what other features I'd like to have in bB (and I have found a couple of bugs too.)

943714[/snapback]

I think F8 and similar 4K-switching schemes would be much more difficult to do in bB, but if that's what you're most familiar with, then I guess I can understand why you think of it as "starting small." :) For me, it would be "starting big," since I've never tried to use F8! ;)

 

Michael Rideout

Link to comment
Share on other sites

I'm not sure it's possible to fix it by just modifying the .asm file.  I think i remember that "if pfread(x,y) then linenumber" doesn't work but "if pfread(x,y) then goto linenumber" does.  So fixing it to work with the first case would break the second case.

 

The problem is likely in the compiler itself :x I wonder if I should put out another maintenance release (like 0.37) before going into some of the big stuff that will take a lot of time.

943720[/snapback]

Yes, that's what I thought-- that the bit-operations code is generated by the bB compiler itself, rather than contained in the .asm includes. I know I searched all the include files for some of the instructions, and couldn't find them anywhere, otherwise I would have tried to fix them as I was able to do with the pfvline bug.

 

Michael Rideout

Link to comment
Share on other sites

Actually, those things aren't necessarily true with schemes like E7 (M-Network) that divide the cartridge ROM area into two or more bank areas.

I see what you're saying, and you're right - some of those issues are much easier to deal with in E7.

I think F8 and similar 4K-switching schemes would be much more difficult to do in bB, but if that's what you're most familiar with, then I guess I can understand why you think of it as "starting small." :) For me, it would be "starting big," since I've never tried to use F8! ;)

943721[/snapback]

When I do get F8 support in, it might be possible to use some of the same mechanisms for F8 to help along with E7. I will certainly need to make the compiler separate user subroutines, data from data statements and graphics, and I could add an option to write these to separate files so one could deal with them in a post-processor if needed.

Edited by batari
Link to comment
Share on other sites

Here is the "2600bB" package that I put together, which includes the modifications for F7 or M-Network bankswitching. The package is intended to be installed in a set of directories off of C: root, as follows:

 

C:\2600bB

C:\2600bB\Docs

C:\2600bB\Includes

C:\2600bB\Projects

C:\2600bB\Stella

C:\2600bB\Tutorial

C:\2600bB\z26

 

Download the 2600bB1.zip and 2600bB2.zip files and put them in C: root (C:\). (I had to split the zip file in two because I couldn't upload it as a single file.) Then unzip them, using the option to preserve the directory structure so all the files will be placed into their proper folders. After you've successfully installed them, you can delete the 2600bB1.zip and 2600bB2.zip files.

 

I've also created two desktop shortcuts for convenience with using bB. Download the shortcuts.zip file and put it on your desktop, then unzip its contents to the desktop. I couldn't add shortcuts, or .lnk files, into the zip file, so I renamed them to have .com extensions, just to get them into the zip file. I made a rename.bat to rename them back with the .lnk extensions after they're unzipped. So once you've unzipped the shortcuts.zip file to your desktop, doubleclick the rename.bat to fix the shortcut file names, then you can delete the shortcuts.zip and rename.bat files.

 

The "batari BASIC" shortcut will start the 2600IDE program, and will also set the current working directory to C:\2600bB\Projects. That way, when you go to open a file, 2600IDE will automatically be looking in the Projects folder, which is where you're expected to save your bB programs.

 

The "bB Tutorial" shortcut doesn't work right now, because I haven't posted the C:\2600bB\Tutorial\default.htm file yet, since I won't start posting anything in the tutorial until late tomorrow night at the earliest.

 

The C:\2600bB\Docs folder includes a 2600bB_readme.txt file, which contains a little bit of information about the package itself, including a few brief instructions on how to use the E7 bankswitching in your bB programs-- not a full explanation by any means, but hopefully just enough to help eager beavers get started! :)

 

By the way, I included the Stella "nightly build" from October 5, 2005, but it won't work on my rickety old Windows 95 computer (the SDL.DLL isn't compatible, at least that's the problem I have with Stella 1.4.2). I can get Stella 1.4.2 to work if I copy the SDL.DLL from Stella 1.4.1 into my Stella 1.4.2 directory, but I couldn't get the October 5, 2005 build to work when I tried that-- but it might also be due to some other problem. I did try to pare down some of the included programs by removing anything I thought was unnecessary. For example, I downloaded DASM 2.20.10b to include in 2600bB, but then I deleted all the other versions (Unix, Linux, Mac, Amiga, etc.). Anyway, if you want to use a different version of Stella, or of z26, or download a different emulator, feel free to do so! I was just trying to create an "all-in-one" package for beginners, to keep them from having to search the web for everything and then try to figure out how to organize everything on their computers.

 

Michael Rideout

shortcuts.zip

2600bB1.zip

2600bB2.zip

Link to comment
Share on other sites

I think F8 and similar 4K-switching schemes would be much more difficult to do in bB, but if that's what you're most familiar with, then I guess I can understand why you think of it as "starting small." :) For me, it would be "starting big," since I've never tried to use F8! ;)

943721[/snapback]

 

In most games, the kernel code needs to access graphics tables, but nothing else; non-kernel code doesn't need to access those graphics tables. It's thus pretty easy to split the program into two halves each of which can be up to 4K. If one bank gets full, using extra space from the other one may be tricky, but the basic 'split' is pretty straightforward. I would expect splitting things that way would be the dominant approach among 8K "single-screen" games, though parts of the screen (e.g. the score readout) may use a kernel that's in the same bank as the "main program" or certain data which is used only occasionally by the main program (e.g. level data that's loaded into RAM at the start of a level) may be in the kernel bank.

Link to comment
Share on other sites

I think F8 and similar 4K-switching schemes would be much more difficult to do in bB, but if that's what you're most familiar with, then I guess I can understand why you think of it as "starting small." :) For me, it would be "starting big," since I've never tried to use F8! ;)

943721[/snapback]

 

In most games, the kernel code needs to access graphics tables, but nothing else; non-kernel code doesn't need to access those graphics tables. It's thus pretty easy to split the program into two halves each of which can be up to 4K. If one bank gets full, using extra space from the other one may be tricky, but the basic 'split' is pretty straightforward. I would expect splitting things that way would be the dominant approach among 8K "single-screen" games, though parts of the screen (e.g. the score readout) may use a kernel that's in the same bank as the "main program" or certain data which is used only occasionally by the main program (e.g. level data that's loaded into RAM at the start of a level) may be in the kernel bank.

943763[/snapback]

That would work, but the current kernel is only about 1k and few games will have 3k of graphics to fill the space.

 

Therefore, I plan to put the kernel, gfx, and all subroutines in the same bank. If done this way, both banks can be filled to capacity if there are enough subroutines. The issue with subroutines in F8 bankswitching is the entry points are at the next PC address, and it's hard to keep the code aligned.

 

However, the kernel itself is a subroutine, and would require a routine for custom entry points anyway. Some old Atari games got by the entry point problem by copying code to RAM. But bB doesn't have enough RAM to do this.

 

However, there is a solution. There was some talk about how to do custom entry points with minimal RAM a while ago, and someone came up with some really clever code. I'm planning to use a modified version of it. The gist of it is that you put all bB code in bank 0, and subs in bank 1. Then instead of "jsr SomeRoutine" you use this:

     jsr     SwapBank1
      .word   SomeRoutine-1

It only takes two more bytes per sub so it doesn't add much overhead. It requires some support code, around 20 bytes or so, as shown here:

SwapBank1:
      tsx
      lda #$FF
      pha
      lda #$F6
      pha
      inc     $02,x         ; shift routine adress pointer to low byte ($ff will roll over!)
      lda     ($01,x)       ; load low byte of routine address
      tay                   ; store it in y
      inc     $02,x         ; shift routine adress pointer to high byte
      lda     ($01,x)       ; load high byte of routine address
      pha
      tya
      pha
      bit $1FF9; switches banks

bank 1 needs an RTS located at the next address, which will jump to the subroutine. It also needs this:

LFFF7:
      rts

RTS does a dummy fetch of PC+1, so the rts at FFF7 will do a dummy fetch of FFF8 and switch banks, then return to the mainline program in bank 0. This trick uses 4 extra stack bytes, but I'm pretty sure I reserved enough (I think I reserved 10 bytes for the stack.)

Link to comment
Share on other sites

By the way, I included the Stella "nightly build" from October 5, 2005, but it won't work on my rickety old Windows 95 computer (the SDL.DLL isn't compatible, at least that's the problem I have with Stella 1.4.2). I can get Stella 1.4.2 to work if I copy the SDL.DLL from Stella 1.4.1 into my Stella 1.4.2 directory, but I couldn't get the October 5, 2005 build to work when I tried that-- but it might also be due to some other problem.

Interesting. The only thing that changed from 1.4.1 to 1.4.2 (SDL-wise) is that the SDL.dll from 1.4.2 is directly from the SDL webpage, whereas the former one was built by me (using VC++ 6.0).

 

Other people have reported problems with SDL and Win95. We may just have to mark it as no longer supported.

 

Also, the Stella nightlies are compiled from Linux with a cross-compiler. Maybe that's introducing some problems. I can send you a link to a version compiled directly in Windows if you like. If so, please send me an email address to send the link to, and I'll get it done sometime this evening.

Link to comment
Share on other sites

Interesting.  The only thing that changed from 1.4.1 to 1.4.2 (SDL-wise) is that the SDL.dll from 1.4.2 is directly from the SDL webpage, whereas the former one was built by me (using VC++ 6.0).

 

Other people have reported problems with SDL and Win95.  We may just have to mark it as no longer supported.

 

Also, the Stella nightlies are compiled from Linux with a cross-compiler.  Maybe that's introducing some problems.  I can send you a link to a version compiled directly in Windows if you like.  If so, please send me an email address to send the link to, and I'll get it done sometime this evening.

943803[/snapback]

My email is SeaGtGruff@aol.com. Thanks!

 

Michael Rideout

Link to comment
Share on other sites

Other people have reported problems with SDL and Win95.  We may just have to mark it as no longer supported.

943803[/snapback]

The changelog for SDL 1.2.9 (which was released in August) says that the SDL.DLL was fixed to work in Win95 again. So there probably only was a problem with how SDL.DLL 1.2.8 was compiled.

 

 

Ciao, Eckhard Stolberg

Link to comment
Share on other sites

Hi there!

 

The changelog for SDL 1.2.9 (which was released in August) says that the SDL.DLL was fixed to work in Win95 again. So there probably only was a problem with how SDL.DLL 1.2.8 was compiled.

 

Stella and Z26 still both deadlock on W98 with my old joypad connected to the game port, no improvement here :sad:

 

Greetings,

Manuel

Link to comment
Share on other sites

Other people have reported problems with SDL and Win95.  We may just have to mark it as no longer supported.

943803[/snapback]

The changelog for SDL 1.2.9 (which was released in August) says that the SDL.DLL was fixed to work in Win95 again. So there probably only was a problem with how SDL.DLL 1.2.8 was compiled.

 

 

Ciao, Eckhard Stolberg

944064[/snapback]

I get no response (no message, no nothing) when I try to play a compiled game with Stella October 5, 2005 build via the 2600IDE program. But if I try to run Stella by itself (doubleclicking on the icon in the folder), it says STELLA.EXE is linked to missing export KERNEL32.DLL:GetFileAttributesExA, which apparently is available only in Win98 and up.

 

Michael Rideout

Link to comment
Share on other sites

Hi there!

 

I get no response (no message, no nothing) when I try to play a compiled game with Stella October 5, 2005 build via the 2600IDE program. But if I try to run Stella by itself (doubleclicking on the icon in the folder), it says STELLA.EXE is linked to missing export KERNEL32.DLL:GetFileAttributesExA, which apparently is available only in Win98 and up.

 

This should be easy to fix, just include NewAPIs.h before the GetFileAttributesEx call. It'll provide a wrapper executing GetFileAttributesEx with API functions available on Win95 :)

 

Greetings,

Manuel

Link to comment
Share on other sites

subroutines must be in same bank as code that calls them

943714[/snapback]

Subroutines could be called between banks if handled cleverly, such as with a routine like the "do_it" routine I had posted (which you gave a better solution for, since it uses an indirect JMP).

943721[/snapback]

Actually, I'm going back to the indirect JMP, because the bytes that hold the JMP vector are in zero-page RAM, and we know they aren't sitting on a page boundary, since I was using temp1 and temp2 for the vector bytes. The code to store the registers in the vector bytes uses three more bytes than the code that pushes the registers on the stack, but it also uses three *less* machine cycles. So I'd like to keep bB's ability to nest subroutines up to three deep.

 

I'm also going to be revising the way I store the return information, because I can put two bank numbers (plus a flag for each) in one byte:

 

bit 7 = is there a bank number in bits 4-6? (0=n, 1=y) *

bits 4-6 = bank number to return to (0 to 6, or %000 to %110) **

bit 3 = is there a bank number in bits 0-2?

bits 0-2 = bank number to return to

* %000 in bits 4-6 (or bits 0-3) could be a bank number, so we need a flag to say whether or not the nibble has a bank number in it.

** bank 7 is fixed at $F800-$FFFF, so subroutine calls to or from bank 7 just use a JSR and RTS, no tricks needed.

 

Or maybe it would be better to arrange them like this:

 

bit 7 = is a bank number in bits 3-5?

bit 6 = is a bank number in bits 0-2?

bits 3-5 = bank number

bits 0-2 = bank number

 

That way, bits 6 and 7 could be tested with BIT.

 

Likewise, I can put four bank numbers in two bytes, but I only need three, since bB can't handle nested subroutines more than three deep. If I use two bytes for a bank return stack, I'll have four bits free in one byte for something else. I'm not sure what I'd do with them, but one idea is to keep track of which bank is currently selected, like this:

 

%0000 = ROM bank 0

%0001 = ROM bank 1

%0010 = ROM bank 2

%0011 = ROM bank 3

%0100 = ROM bank 4

%0101 = ROM bank 5

%0110 = ROM bank 6

%0111 = RAM bank 0

%1000 = RAM bank 1

%1001 = RAM bank 2

%1010 = RAM bank 3

%1011 = RAM bank 4

 

On the other hand, we really need five bits to track the selected banks-- three to track which bank is in the lower bank area, and two to track which 256-byte RAM bank is in the upper bank area:

 

%xx000 through %xx111 = bank selected in lower area

%00xxx through %11xxx = RAM selected in upper area

 

Anyway, I'm thinking of reworking the bank-jumping routines, I just haven't got it all planned out yet, since the only unused zero-page byte was $DA, and I'd rather not steal any of the 26 user variables, or use any bB variables that are likely to be destroyed when a bB routine is called. I'm thinking of passing two bank numbers in the Y register (the originating bank number plus the destination bank number), rather than having the user stick the return bank number in temp7, and have the bank-switching routine move the return bank (if there is one) onto the bank return stack. Bit 7 of the Y register would specify whether the user wants to return or not. For example,

 

LDA #<target_routine

LDX #>target_routine

LDY #$06

JMP do_it

 

would mean jump to target_routine in bank 6, and don't save a return bank number on the bank return stack, whereas

 

LDY #$86

 

would mean jump to target_routine in bank 6, but save a return bank number of 0 on the bank return stack.

 

But I'm not going to change anything yet, since I need to work on the tutorial.

 

By the way, my experiments with E7 bankswitching on the z26 emulator show that a routine located at the hotspots can be executed, I believe without affecting which bank is selected. Thus, the twelve hotspot bytes can contain a routine, plus they can be used to switch banks using a fake read or fake write.

 

Also, the 256 bytes of ROM that are "underneath" the extra RAM at $F800 through $F8FF can be executed, or used for ROM data tables, plus the RAM can be written to at those addresses. But the ROM at $F900 through $F9FF is totally unusable.

 

I haven't verified this behavior on other emulators, and most importantly I've no way of knowing if it works that way on a real 2600 running an M-Network E7-style cartridge, but I left $F800 through $F8FF, and $FFE0 through $FFEE, available in the mnetworkheader.asm and mnetworkfooter.asm include files.

 

Michael Rideout

Link to comment
Share on other sites

Subroutines could be called between banks if handled cleverly, such as with a routine like the "do_it" routine I had posted (which you gave a better solution for, since it uses an indirect JMP).

943721[/snapback]

Actually, I'm going back to the indirect JMP, because the bytes that hold the JMP vector are in zero-page RAM, and we know they aren't sitting on a page boundary, since I was using temp1 and temp2 for the vector bytes. The code to store the registers in the vector bytes uses three more bytes than the code that pushes the registers on the stack, but it also uses three *less* machine cycles. So I'd like to keep bB's ability to nest subroutines up to three deep.

944306[/snapback]

Right now this is true, but there's no guarantee that users won't move variables out of zero-page to free up space there, so the page boundary issue can creep up.

 

If you want a way around this and still want to use indirect jumps, you should have DASM catch page wraps. I think this would work:

 

if (<temp1) == $ff

echo "warning - indirect jump crosses a page boundary"

endif

 

Actually, you might use something other than temp1 and temp2 anyway, like maybe some reserved space in E7 RAM, as the temp variables are often used to pass values to a subroutine.

Edited by batari
Link to comment
Share on other sites

I get no response (no message, no nothing) when I try to play a compiled game with Stella October 5, 2005 build via the 2600IDE program. But if I try to run Stella by itself (doubleclicking on the icon in the folder), it says STELLA.EXE is linked to missing export KERNEL32.DLL:GetFileAttributesExA, which apparently is available only in Win98 and up.

944261[/snapback]

I think the Stella nightly builds still come with SDL.DLL version 1.2.8. Did you try to go to www.libsdl.org and download SDL.DLL version 1.2.9 and see if it works better with Stella on Win95?

 

By the way, my experiments with E7 bankswitching on the z26 emulator show that a routine located at the hotspots can be executed, I believe without affecting which bank is selected. Thus, the twelve hotspot bytes can contain a routine, plus they can be used to switch banks using a fake read or fake write.

 

This should work on real hardware, since the ROM bank at the hotspots is fixed and wouldn't change when the hotspots get accessed.

 

Also, the 256 bytes of ROM that are "underneath" the extra RAM at $F800 through $F8FF can be executed, or used for ROM data tables, plus the RAM can be written to at those addresses. But the ROM at $F900 through $F9FF is totally unusable.

944306[/snapback]

This won't work on real hardware and it probably will not work in fututre versions of z26 either. In the emulator we have to handle read and write accesses seperately. No E7 game tried to write to the extra RAM by read accesses to the write hotspots. Therefore we didn't implement a handler for this case in the E7 handler for read accesses. This is why you can still read from the ROM there. On real hardware there is no difference between read and write accesses. So a cartridge shouldn't return anything on an access to the extra-RAM write addresses.

 

 

Ciao, Eckhard Stolberg

Link to comment
Share on other sites

Subroutines could be called between banks if handled cleverly, such as with a routine like the "do_it" routine I had posted (which you gave a better solution for, since it uses an indirect JMP).

943721[/snapback]

Actually, I'm going back to the indirect JMP, because the bytes that hold the JMP vector are in zero-page RAM, and we know they aren't sitting on a page boundary, since I was using temp1 and temp2 for the vector bytes. The code to store the registers in the vector bytes uses three more bytes than the code that pushes the registers on the stack, but it also uses three *less* machine cycles. So I'd like to keep bB's ability to nest subroutines up to three deep.

944306[/snapback]

Right now this is true, but there's no guarantee that users won't move variables out of zero-page to free up space there, so the page boundary issue can creep up.

 

If you want a way around this and still want to use indirect jumps, you should have DASM catch page wraps. I think this would work:

 

if (<temp1) == $ff

echo "warning - indirect jump crosses a page boundary"

endif

944319[/snapback]

I'm not going to worry about someone relocating the temp1 and temp2 variables, since there's no way I could control that, but your idea about a compiler warning is great. I'll try relocating temp1 myself, and see if I can get that to work.

Actually, you might use something other than temp1 and temp2 anyway, like maybe some reserved space in E7 RAM, as the temp variables are often used to pass values to a subroutine.

944319[/snapback]

I'd rather not use any of the extra RAM for that, since I need to assume that a user might want to use all of the extra RAM for his/her own purposes, and I don't want to change an extra RAM location after they've stored something there. As for bB's use of the temp variables, it's my understanding that the danger of trying to use temp1 through temp6 in our own programs is that bB is likely to wipe them out, especially when drawscreen is executed, so there's no danger that my use of temp1 and temp2 will interfere with bB, rather it's the other way around. And I'm using temp1 and temp2 as soon as I set them, without calling any bB routines in between, plus I don't care if they get trashed by bB after I've done the indirect JMP, so it should be okay to use them.

 

Michael Rideout

Link to comment
Share on other sites

So a cartridge shouldn't return anything on an access to the extra-RAM write addresses.

 

I'd expect a read of the 'write' port would read the last value on the data bus (which would usually be the MSB of the address, except that in the case of an indexed read across a page boundary it would be the value read 256 bytes below). The value read would also be written to the memory in question.

 

Thus, on a 2600 I would expect:

 ldx #$80
 lda $1800,x  ; Read a $18 and stores a $18 into byte $80 of upper RAM area
 lda $5800,x  ; Read a $58 and stores a $58 into byte $80 of upper RAM area
 lda $5880,x  ; Stores a $58 into byte $00 of upper RAM area, then reads it back
 lda $5780,x  ; Reads ROM at $5700 and stores it into byte $00 of upper RAM

On a 7800, some bits of the data bus may get somewhat randomly pulled high (at least on my machine, it takes about a cycle for pullups to change the state of the data bus, so they may or may not 'win'). Note that depending upon timing, the value which gets read by the CPU may not match the value written to RAM except in case #3 above.

Edited by supercat
Link to comment
Share on other sites

I get no response (no message, no nothing) when I try to play a compiled game with Stella October 5, 2005 build via the 2600IDE program. But if I try to run Stella by itself (doubleclicking on the icon in the folder), it says STELLA.EXE is linked to missing export KERNEL32.DLL:GetFileAttributesExA, which apparently is available only in Win98 and up.

944261[/snapback]

I think the Stella nightly builds still come with SDL.DLL version 1.2.8. Did you try to go to www.libsdl.org and download SDL.DLL version 1.2.9 and see if it works better with Stella on Win95?

944437[/snapback]

I did try it with a copy of SDL.DLL that works in Win95, and it still didn't work. But the message I'd gotten from Stella 1.4.2 specifically mentioned a link to a missing export in SDL.DLL, and the message from the nightly build says KERNEL32.DLL instead, so it looks like the problem is with KERNEL32.DLL, not SDL.DLL. Or rather, STELLA.EXE is trying to use GetFileAttributesExA, but no such function exists in the Win95 version of KERNEL32.DLL, so the problem can't be fixed except by replacing Win95's KERNEL32.DLL, or changing STELLA.EXE so it calls a different function that *is* in Win95's KERNEL32.DLL.

By the way, my experiments with E7 bankswitching on the z26 emulator show that a routine located at the hotspots can be executed, I believe without affecting which bank is selected. Thus, the twelve hotspot bytes can contain a routine, plus they can be used to switch banks using a fake read or fake write.

 

This should work on real hardware, since the ROM bank at the hotspots is fixed and wouldn't change when the hotspots get accessed.

944437[/snapback]

Just to be clear, I'm not worried about ROM bank 7 getting switched when a ROM routine at the hotspots is executed, since ROM bank 7 is fixed as you said. Rather, I haven't verified yet (on an emulator) if running a ROM routine at the hotspots constitutes an "access" of the hotspots the way LDA and STA does, thus causing the lower area ($F000-$F7FF) and the extra small RAM area ($F800-$F9FF) to get switched.

Also, the 256 bytes of ROM that are "underneath" the extra RAM at $F800 through $F8FF can be executed, or used for ROM data tables, plus the RAM can be written to at those addresses. But the ROM at $F900 through $F9FF is totally unusable.

944306[/snapback]

This won't work on real hardware and it probably will not work in fututre versions of z26 either. In the emulator we have to handle read and write accesses seperately. No E7 game tried to write to the extra RAM by read accesses to the write hotspots. Therefore we didn't implement a handler for this case in the E7 handler for read accesses. This is why you can still read from the ROM there. On real hardware there is no difference between read and write accesses. So a cartridge shouldn't return anything on an access to the extra-RAM write addresses.

 

 

Ciao, Eckhard Stolberg

944437[/snapback]

If I understand you correctly, you're basically saying that ROM bank 7 is only 1.5K in size, since the first .5K is taken by the extra small RAM area. I was hoping that ROM bank 7 is a full 2K, and that the extra small RAM area is "on top" of it so to speak, as it seems to be in an emulator (z26 at least), since the 256 bytes of ROM at $F800 can be read or executed.

 

I realize that read and write accesses are no different as far as being accesses-- hence a "fake write" to a hotspot works just like a "fake read," except there's no danger of wiping out the contents of the A, X, or Y register (as with using LDA, LDX, or LDY to access a hotspot). But $F800 and $F900 are different addresses, so LDA $F800 should be trying to read $F800 rather than $F900, unless the cartridge is wired(?) such that $F800 and $F900 go to the same place. I can understand why LDA $F800 can't read the RAM there, but it's nice that the ROM that's "underneath" the RAM can still be read or executed there-- at least on the current incarnation of z26, if not on an actual E7 cartridge.

 

My 2600 was stolen long ago (but not my SuperCharger, thank goodness), and my 7800 isn't working right now (hopefully it's just a burned-out power supply), so I currently have no way to test any of this myself with the Cuttle Cart 2 that I just bought. And I don't know if a game loaded into a Cuttle Cart or Krokodile Kart will work exactly the same way as a real E7 cartridge would, anyway. So I guess the only way to actually test these things on a real 2600 would be to reprogram a real E7 cartridge and try it out?

 

Michael Rideout

Link to comment
Share on other sites

Just to be clear, I'm not worried about ROM bank 7 getting switched when a ROM routine at the hotspots is executed, since ROM bank 7 is fixed as you said. Rather, I haven't verified yet (on an emulator) if running a ROM routine at the hotspots constitutes an "access" of the hotspots the way LDA and STA does, thus causing the lower area ($F000-$F7FF) and the extra small RAM area ($F800-$F9FF) to get switched.

 

It is a very bad idea to rely upon intricacies such as that unless they are explicitly documented. If a bank switching method "expects" to be used a certain way, using it via other ways may not result in the expected results.

 

For example, in FE bankswitching, an access to $01FF followed by an access to $01FE switches to the secondary bank; an access to $01FE followed by an access to $01FF switches to the primary bank. There are two ways the hardware might implement this:


  •  
  • An access to $01FE or $01FF triggers the primary or secondary bank respectively UNLESS preceded by another access to $01FE or $01FF (in which case it's ignored).
     
  • An access to $01FE or $01FF triggers the secondary or primary bank respectively, even if preceded by another access to $01FE or $01FF.
     

Note that when used as intended, both of these methods will produce identical results. When used with a single access to $01FE or $01FF, however, they'll yield opposite results. I would guess that the former is more likely to be the actual hardware implementation, but I don't know which was actually used.

 

But $F800 and $F900 are different addresses, so LDA $F800 should be trying to read $F800 rather than $F900, unless the cartridge is wired(?) such that $F800 and $F900 go to the same place. I can understand why LDA $F800 can't read the RAM there, but it's nice that the ROM that's "underneath" the RAM can still be read or executed there-- at least on the current incarnation of z26, if not on an actual E7 cartridge.

 

Reading $x800 (x odd) almost certainly won't yield the ROM "underneath" there. If it's going to read anything (other than the prior bus state) it would almost certainly read the RAM at $x900 (though not necessarily reliably). Perhaps a brief tutorial on how the 6507 works might be in order.

 

The 6507 has 23 pins that interest us. A0-A12, D0-D7, R/W, and phi2. Note that the latter two are not available to a cartridge (grr...). Each memory cycle is split into two parts: phase 1 or phase 2.

 

For a memory read, just after the start of phase 1, the 6507 will output the address it wants to read on A0-A12 and will raise the R/W line. At the start of phase 2, it will raise the phi2 line. Then at the end of phase 2, it will latch the contents of D0-D7 (onto which the memory device should have put the data to be read) and lower phi2.

 

For a memory write, just after the start of phase 1, the 6507 will output the address it wants to write on A0-A12 and will assert the R/W line. At the start of phase 2, it will raise the phi2 line and put the data it wants to write onto D0-D7. And the end of phase 2, it will lower phi2. The lowering of phi2 should trigger the memory device to latch the data that was on D0-D7 into the specified address.

 

Depending upon implementation, memory devices may or may not put data on the bus during phase 1. On the Atari 2600 such action is harmless so almost all cartridges will do it (especially since they have no way of knowing when phase 2 starts). On some other machines (especially those with memory-mapped displays), the data bus may be used for other purposes at that time.

 

There is no way for a cartridge to tell whether a particular memory access is a read or a write. Anything that gets put on the data bus during an access to a cartridge's "write port" is going to get written to RAM. It is possible to design a cartridge which allows "natural" reads and writes by splitting each memory cycle into a read part and a write part: during phase 1, read memory onto the data bus and then hold the data 'weakly' on the bus. At the middle of phase 2, write the data on the bus into RAM and then read it back. If the memory cycle was a write, the processor's new data will "win" and will get stored into memory. If the memory cycle was a read, however, the weakly-held data from RAM will "win" and so the RAM will keep whatever value it held. I'm not aware of any cartridge other than my own which does this, however, and I'm not sure it will work on all 7800's.

Link to comment
Share on other sites

Just to be clear, I'm not worried about ROM bank 7 getting switched when a ROM routine at the hotspots is executed, since ROM bank 7 is fixed as you said. Rather, I haven't verified yet (on an emulator) if running a ROM routine at the hotspots constitutes an "access" of the hotspots the way LDA and STA does, thus causing the lower area ($F000-$F7FF) and the extra small RAM area ($F800-$F9FF) to get switched.

 

It is a very bad idea to rely upon intricacies such as that unless they are explicitly documented. If a bank switching method "expects" to be used a certain way, using it via other ways may not result in the expected results.

944742[/snapback]

I agree with Supercat here. I've tried putting data and code in hotspots, and the emulators run it with no problems but it doesn't work properly on all hardware. Others have said the same thing.

 

In ROM dumps of existing games, there is never anything useful in hotspots. The hotspots are usually just filled with zeros, or (in the case of Parker Bros. at least) the author's name in ASCII.

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...