Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - Bankswitching: Making a 64k game

Reply to topic Goto page 1, 2  Next
Author Message
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Bankswitching: Making a 64k game
Post Posted: Mon Apr 09, 2018 4:56 am
So I want to make a game larger than 32k. Reading some old posts I made, it seems as though what I want (a 64k or larger) game would be easy. Only trouble is, I don't know how to bankswitch. Here's my header as it currently stands:

.memorymap
 defaultslot 0
 slotsize $c000 ; 48KB (ROM)
 slot 0 $0000
 slotsize $2000 ; 8KB (RAM)
 slot 1 $c000
 slotsize $4000 ; ROM
 slot 2 $8000
 slotsize $100 ; RAM
 slot 3 $dd00

.endme
.rombankmap
bankstotal 1
banksize $8000 ; 32KB
banks 1
.endro

Do I need to change anything besides just changing the bankstotal and banks #s from 1 to 2? Or what do I need to do here to get a 64k game? I am under the impression that I must have 4 16k banks for a 64k game. Or is that not true? I need some help here.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Mon Apr 09, 2018 6:02 am
So I went ahead and changed the bank numbers to 2 and it gave me a 64k file that works perfectly on an Everdrive. So now I have a question: How does saving includes files work? At the end of my code I have all the .include statements. Would all these go in the first bank or can I direct them to the second bank if I wanted to?
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14745
  • Location: London
Reply with quote
Post Posted: Mon Apr 09, 2018 9:15 am
Put the memory map at the start. You need to change it to the 16KB map that is part of the WLA DX examples.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3827
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Apr 09, 2018 11:48 am
if 48 KB is enough for you, you really don't need bankswitching.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Mon Apr 09, 2018 1:25 pm
Maxim wrote
Put the memory map at the start. You need to change it to the 16KB map that is part of the WLA DX examples.

I went ahead and did that. The game still works fine. The memory map is at the start. But how does saving .include files work? Do they all go in one bank or can you make it so they can go in different ones?

.memorymap
 defaultslot 0
 slotsize $4000 ; 48KB (ROM)
 slot 0 $0000
 slotsize $2000 ; 8KB (RAM)
 slot 1 $c000
 slotsize $4000 ; ROM
 slot 2 $8000
 slotsize $100 ; RAM
 slot 3 $dd00

.endme
.rombankmap
bankstotal 4
banksize $4000 ; 16KB
banks 4
.endro
  View user's profile Send private message Visit poster's website
  • Joined: 14 Mar 2018
  • Posts: 19
Reply with quote
Post Posted: Mon Apr 09, 2018 3:14 pm
Well you save them with a Ctrl+S or Cmd+S like any other file ;)

They are included in the ROM wherever you tell WLA-DX to include them. Which will depend upon which Section you include them in. Or if your includes define the section they are in then they will go into the section mentioned in the included file. All included does is say "copy the contents of file X to here" So it will get everything in the included file and then write it out into one big file in memory and then parse it. There is nothing special about them.
so if you have
A
; This is line A
B
; This is line B
and C is
.include "B"
.include "A"

WLA-DX will then "see"
; This is line B
; This is line A
  View user's profile Send private message
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Mon Apr 09, 2018 3:44 pm
I've been trying to get my program to jump to different banks without any success. Look at my second bank:

.bank 1

get_level_1
       ld hl,$0000         ; first tile @ index 0.
       call vrampr         ; prepare vram.
       ld hl,level1tile        ; title screen tile data.
       ld bc,143*32         ; 128 tiles, each tiles is 32 bytes.
       call vramwr         ; write title screen tiles to vram.

       ld hl,$3800         ; point to name table.
       call vrampr         ; prepare vram.
       ld hl,level1map         ; title screen tile map data.
       ld bc,32*24*2       ; 32 x 24 tiles, each is 2 bytes.
       call vramwr         ; write name table to vram.

       ld hl,$c000         ; color bank 1, color 0.    (bg)
       call vrampr         ; prepare vram.
       ld hl,level1palette         ; background palette.
       ld bc,32           ; 4 colors.
       call vramwr         ; set background palette.

       ret

level1tile      .include "level1a (tiles).inc"
level1map       .include "level1a (tilemap).inc"
level1palette       .include "level1a (palette).inc"


Now how would I get the program (which would currently be in bank 0) to tell it to call this code in another bank (bank 1)?
Looking at the examples in wla.txt, one would surmise to use this:

       LD   a, 2
       CALL   get_level_1

but this does not work.
Help!
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14745
  • Location: London
Reply with quote
Post Posted: Mon Apr 09, 2018 9:52 pm
There's loads of examples of this.

ld a, :label
ld ($ffff), a
call label

...

.section "my paged function" superfree
label:
  // Code here
  ret
.ends


..is how I'd do it, using sections. It's more common to put the data in higher banks rather than code, though.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Tue Apr 10, 2018 2:11 am
So I guess "superfree" isn't going to work since I would like the include files for level 1 in bank 1 and using "superfree" puts them in bank 0. The whole point of me using banks was to put .includes in them so I can put more of them in. So here's what I have now for bank 1:

.bank 1
.org 0

.section "initialize level 1" free

INIT_LEVEL1:
       ld hl,$0000         ; first tile @ index 0.
       call vrampr2         ; prepare vram.
       ld hl,level1tile        ; title screen tile data.
       ld bc,143*32         ; 128 tiles, each tiles is 32 bytes.
       call vramwr2         ; write title screen tiles to vram.

       ld hl,$3800         ; point to name table.
       call vrampr2        ; prepare vram.
       ld hl,level1map         ; title screen tile map data.
       ld bc,32*24*2       ; 32 x 24 tiles, each is 2 bytes.
       call vramwr2         ; write name table to vram.

       ld hl,$c000         ; color bank 1, color 0.    (bg)
       call vrampr2         ; prepare vram.
       ld hl,level1palette         ; background palette.
       ld bc,32           ; 4 colors.
       call vramwr2         ; set background palette.

       ret

vrampr2 push af
       ld a,l
       out ($bf),a
       ld a,h
       or $40
       out ($bf),a
       pop af
       ret

vramwr2 ld a,(hl)
       out ($be),a
       inc hl
       dec bc
       ld a,c
       or b
       jp nz,vramwr2
       ret

level1tile      .include "level1a (tiles).inc"
level1map       .include "level1a (tilemap).inc"
level1palette       .include "level1a (palette).inc"

.ends

But when I try to call to this bank using the following code, it doesn't work.

       ld a, :INIT_LEVEL1
       ld ($ffff), a
       call INIT_LEVEL1

Why won't it work and how do I make it work?
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14745
  • Location: London
Reply with quote
Post Posted: Tue Apr 10, 2018 4:36 am
Superfree will put the section in any place where there is space, it means you don't have to manage the location.

Make sure you put your banks in slot 2.

You should also consider using compression for graphics data, else you may find you have a lot of unused space as the chunks get large.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Tue Apr 10, 2018 6:05 am
I figured it out.
I had to change my memory map to this:

.memorymap
 defaultslot 0
 slotsize $4000 ; 16KB (ROM)
 slot 0 $0000
 slot 1 $4000
 slot 2 $8000
 slot 3 $c000

.endme
.rombankmap
bankstotal 4
banksize $4000 ; 16KB
banks 4
.endro


Then I put the code in slot 1 and used this to get there:

       ld a, :INIT_LEVEL1
       ld ($fffe), a
       call INIT_LEVEL1


But then PSGLib broke and the title screen song wouldn't play any more. That was not fun trying to fix that. I eventually got it back working again. I changed its slot 3 address to $dd00, which it apparently liked.

How do I compress graphic data?
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14745
  • Location: London
Reply with quote
Post Posted: Tue Apr 10, 2018 7:37 am
That's the memory map I referred to earlier. You should avoid using slot 1, slot 2 only is the most compatible way.

You can compress data using BMP2Tile. It includes decompressors. These can often reduce the data size by 60-70% which helps pack data into the 16KB slots. But I suggest you tackle the paging first.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3827
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Apr 10, 2018 7:47 am
Did you read this BTW?
There are useful hints I wrote after I had done Waimanu SMS and also some code you may grab :)
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Tue Apr 10, 2018 11:11 am
Thanks for the tips. This game I'm working on is actually a game for the Game Gear, but I know it and the SMS are very similar. I chose Game Gear because it doesn't have very many games for it, and even fewer homebrews for it. And I love the Game Gear, hence my username.
As for paging, I have selected for my game to be 64k, but from my understanding it's a very odd size?
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3827
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Apr 10, 2018 11:58 am
Last edited by sverx on Tue Apr 10, 2018 3:32 pm; edited 1 time in total
actually not. 32 KB, 64 KB, and 128 KB are very common.

edit: rephrasing - 64 KB is a common size for ROM chips. ;)
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14745
  • Location: London
Reply with quote
Post Posted: Tue Apr 10, 2018 12:50 pm
There are very few 64KB games, but not for any great technical reason.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Thu Apr 12, 2018 7:22 am
I need help again. This time it's displaying sprites that are 16 pixels wide. The closest I ever got was it displaying the first half of the sprite. This is the code I used.

spritey1 ld c,a              ; save hpos in C
       .rept 2             ; wladx: Repeat code four times.
       ld a,c              ; load hpos into A
       ld b,2             ; loop: Repeat four times.
-      ld (hl),a           ; write value to buffer at address.
       inc hl              ; skip over the char code byte.
       inc hl              ; point to next hpos byte in buffer.
       add a,8             ; add 8 (a tile's width in pixels).
       djnz -              ; jump back
       .endr               ; end of wladx repeat directive.
       ret

spritex1   ld c,a              ; save hpos in C
       .rept 2             ; wladx: Repeat code four times.
       ld a,c              ; load hpos into A
       ld b,2              ; loop: Repeat four times.
-      ld (hl),a           ; write value to buffer at address.
       inc hl              ; skip over the char code byte.
       inc hl              ; point to next hpos byte in buffer.
       add a,4             ; add 8 (a tile's width in pixels).
       djnz -              ; jump back
       .endr               ; end of wladx repeat directive.
       ret

layout  .db 16 17
              .db 18 19

But no matter what I do, I can't get the second half to display. I am going mad. Can someone please help?
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3827
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Apr 12, 2018 8:18 am
you don't need to skip the 'char code byte' when writing the Y table, as the Y table is just an array of 64 Y positions, whereas XN table is a table of 64 X and 'char code byte' pairs.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Thu Apr 12, 2018 12:20 pm
I commented that part out, but it still won't work.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Apr 2011
  • Posts: 250
  • Location: Netherlands
Reply with quote
Post Posted: Thu Apr 12, 2018 1:50 pm
Are you sure the sprite pattern numbers are set correct? You are not writing them in this code. Only the x and y positions.

Also, you add 4 pixels to the x offset. not 8:

add a,4             ; add 8 (a tile's width in pixels).


Could you also provide the buffer update routine to VRAM? Possibly there could be an issue too.
  View user's profile Send private message
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Thu Apr 12, 2018 3:25 pm
Here is the buffer updating code:

upbuf
       ld a,(spritey)
       ld hl,spritevp
       call spritey1

       ld a,(spritex)
       ld hl,spritehp
       call spritex1

       ld hl,score
       ld de,scorecc
       ld b,5
-      ld a,(hl)
       add a,64
       ld (de),a
       inc hl
       inc de
       inc de
       djnz -
       ret


Here is the subroutines the above calls.

spritey1 ld c,a
       .rept 2
       ld a,c
       ld b,2
-      ld (hl),a
       inc hl
       add a,8
       djnz -
       .endr
       ret

spritex1   ld c,a
       .rept 4
       ld a,c
       ld b,4
-      ld (hl),a
       inc hl
       inc hl
       add a,8
       djnz -
       .endr
       ret

And here is the map for it:

spritelayout  .db 16 17
              .db 18 19

I'm using Emulicious's sprite and tile viewer and the tiles are loaded in there, but they're just not displaying correctly. This sprite I'm trying to make correct is 16x16 pixels. There is another sprite I want to do that is 16x32 pixels, and a third that's 16x8 pixels, but I haven't tried that yet because I haven't gotten this first one done.
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14745
  • Location: London
Reply with quote
Post Posted: Fri Apr 13, 2018 12:04 am
You need to debug by inspecting your data in RAM and the sprite table in video RAM. You can't fix it very easily just from the code.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Fri Apr 13, 2018 8:09 am
I think I fixed it, although I can't seem to optimize at the moment because still some parts of the code must be screwed up. For example, the 16x32 sprite only displays correctly if I have two blank spaces after the sprte on each row. The first discovery came when I changed the first sprite's y getting code to this:

spritey1 ld b,2       
-      push af         
       push af           
       add a,8           
       djnz -             

       ld de,3           
       add hl,de         
       ld b,4             
-      pop af             
       ld (hl),a       
       dec hl         
       djnz -       
       ret

But I couldn't just double this for the sprite that is double its length. And finally for the third sprite that is 16x8, I did this:

thirdsprite1y  ld b,2             
-      push af       
       push af         
       add a,0     
       djnz -             

       ld de,3         
       add hl,de         
       ld b,4           
-      pop af             
       ld (hl),a       
       dec hl           
       djnz -             
       ret

So I'm thinking that this sprite is actually two overlapping each other, but it looks like one, and it works.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3827
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Apr 13, 2018 8:21 am
Emulicious' "sprite viewer" gives you h/v position of each sprite, so that you can check if they're as you expect them
  View user's profile Send private message Visit poster's website
  • Joined: 23 Mar 2013
  • Posts: 611
  • Location: Copenhagen, Denmark
Reply with quote
Post Posted: Fri Apr 13, 2018 12:02 pm
When these routines (in their original form) work to put cars on the screen in Racer (http://www.smspower.org/Articles/CreateARacingGame), they are coded specifically to expect 32x32 pixel sprites (4x4 tiles). As far as I can see, you have halfway altered them (which is totally great), but these routines were tailored to a very specific layout of the sprite table, and only updating y and x position as far as I remember. When you have duplicated these routines (firstsprite, secondsprite, thridsprite) with different sprite layouts, that might cause trouble.

I suspect that the sprite routines may partly overwrite the same areas of the sprite attribute table, and this causes upredictable output. I second Maxim's suggestion about debugging: Maybe put some breakpoints in after each sprite update routine, and see if the SAT buffer looks like it should.
  View user's profile Send private message Visit poster's website
  • Joined: 01 Feb 2014
  • Posts: 877
Reply with quote
Post Posted: Fri Apr 13, 2018 12:38 pm
First of all: By all means, stop (ab)using hang-on‘s Racer code as a base for new games already! It‘s really taylor-made to do very soecific things that only work within the context of the original Racer game and cannot easily be adapted for other purposes. You will inevitably run into trouble if you‘re trying to get results this way, as you obviously experience right now, and not for the first time, I might add.

Sorry if I sound harsh. I find your persistance admirable, but if you had taken all the time you sunk into poking around in the Racer code in hope of random achievments, and put it to good use by actually trying to understand what‘s going on there, you‘d be pretty much a pro by now and could create games from scratch as you desire.
  View user's profile Send private message
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Fri Apr 13, 2018 1:20 pm
I'm sorry for abusing it. I was only using it because I was too lazy to type out all that stuff anyway, and I learn by examples, anyway. That's how i learned C, from seeing examples and then copying what they did and seeing the results I wanted to see. I don't have to copy anything any more when I want to program a new Virtual Boy game. In fact, I'm programming one right now, and out of the almost 2,000 lines of code in it, 2 are copied/pasted. So, I'm sorry for learning to program this way, I am learning how stuff works this way for the Game Gear too, though.
  View user's profile Send private message Visit poster's website
  • Joined: 01 Feb 2014
  • Posts: 877
Reply with quote
Post Posted: Fri Apr 13, 2018 1:39 pm
I understand, and that‘s generally a good way to learn. The problem in this case is that Racer does many things a lot differently than one would usually approach them, thus being not a very good example to learn from.
  View user's profile Send private message
  • Joined: 01 Feb 2014
  • Posts: 877
Reply with quote
Post Posted: Fri Apr 13, 2018 3:14 pm
Sorry for the double post. Have you, by any chance, looked into using devkitSMS? If you‘re familiar with C you should get good results in no time, much faster than by trying to figure out another person‘s asm code.
  View user's profile Send private message
  • Joined: 18 Dec 2014
  • Posts: 95
  • Location: Canada
Reply with quote
Post Posted: Tue Apr 17, 2018 4:16 pm
It's great that the 2000 lines of code are yours,can you do the same for your projects on game gear?
  View user's profile Send private message
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Wed May 02, 2018 3:17 am
OK, I read this page on bankswitching:
http://www.smspower.org/Development/Mappers
It did not, however, explain how to switch to slot 3. I was thinking putting each slot in each bank: 4 slots in 4 banks, making one 64k game. Or am I missing something?
  View user's profile Send private message Visit poster's website
  • Joined: 14 Oct 2008
  • Posts: 511
Reply with quote
Post Posted: Wed May 02, 2018 5:56 am
If you were able to bank in slot 3, you'd be shutting out the console RAM.
I think that would make it very hard to have a game without that.
  View user's profile Send private message
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Wed May 02, 2018 7:05 am
A quote from said page:
Quote

Most games only use slot 2; very few use slot 0.

So if slot 3 can't be written to, is this an okay memory map?

.memorymap
 defaultslot 0
 slotsize $4000 ; 16KB (ROM)
 slot 0 $0000
 slot 1 $4000
 slotsize $8000
 slot 2 $8000
.endme
.rombankmap
bankstotal 4
banksize $4000 ; 16KB
banks 4
.endro
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14745
  • Location: London
Reply with quote
Post Posted: Wed May 02, 2018 8:17 am
No - use the ones we already recommended. I would suggest slot 2 only is the best option.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3827
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed May 02, 2018 12:38 pm
Gamegearguy wrote
OK, I read this page on bankswitching:
http://www.smspower.org/Development/Mappers
It did not, however, explain how to switch to slot 3. I was thinking putting each slot in each bank: 4 slots in 4 banks, making one 64k game. Or am I missing something?


The matter is that your game will be made up of ROM banks, 16 KB each, and you can map 3 of them at a given time, using Master System's 3 slots. Thus, if you have a 48 KB ROM, you map each of the bank in each of the slots and you don't need any bank-switching at run time. If you do make a ROM bigger than that, for instance a 64 KB ROM, you'll have to page-in/page-out chunks of your ROM, that's what bank-switching is all about.
I again suggest you simply map ROM bank0 to slot0, ROM bank1 to slot1 and you map either bank2 and bank3 to slot 2, according to your needs. If both bank2 and bank3 simply contains assets (graphic, music...) bank-switching will be pretty straightforward (using WLA-BX :label directive, which will give you the number of the bank containing the asset you want to access)
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Wed May 02, 2018 8:30 pm
So if I'm making a 64k game (which I am), and I want to put everything in one slot, I'd have to make that slot big enough for everything, right? Which would mean I would have to change slotsize in the memory map accordingly, right? But if I do that, and you're suggesting I put everything in slot 2, what size and where should the other slots go to?
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14745
  • Location: London
Reply with quote
Post Posted: Wed May 02, 2018 10:07 pm
There are two things in play here. One is the way stuff is put into the ROM. You want 64KB, fine. The Master System can only look at 48KB at once, though. This is what bank switching is for.

You can think of the 48KB as three 16KB slots. You can choose which of the ROM's four 16KB banks appears in each slot. Most commonly, we only swap out one of them, because it's kind of complicated otherwise.

You don't get to choose the slot size, or the bank size, or how many slots there are. You just get to choose what goes in which slot.

There is a WLA DX ROM bank map which pretends the slot sizes are variable. This is a hack to allow some stuff to work while not enforcing a split at the 16KB mark. It's really not that important though. It only works if you don't actually try to use the funny sized slots for other banks. Stick to the 16KB version.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Wed May 02, 2018 10:20 pm
So if I think of the 48KB as 3 slots, what is the other 16KB then? Aren't there supposed to be 4 slots, numbered 0-3?
And so if each slot and each bank are 16k, this is what my memory map now looks like:

.memorymap
 defaultslot 0
 slotsize $4000 ; 16KB
 slot 0 $0000
 slot 1 $4000
 slot 2 $8000
 slot 3 $c000
.endme

.rombankmap
bankstotal 4
banksize $4000 ; 16KB
banks 4
.endro
  View user's profile Send private message Visit poster's website
  • Joined: 25 Feb 2006
  • Posts: 874
  • Location: Belo Horizonte, MG, Brazil
Reply with quote
Post Posted: Thu May 03, 2018 12:23 am
No, there is no fourth slot, since the top 16KB are reserved for internal stuff (mainly RAM); this means that if you want to use more than 48KB of ROM, you will have to use bankswitching.
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14745
  • Location: London
Reply with quote
Post Posted: Thu May 03, 2018 6:04 am
You can consider the RAM to be in a third 8KB slot, and you need to do that to use ramsections. But they aren't interchangeable.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3827
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu May 03, 2018 8:01 am
@Gamegearguy: I'm curious to know how you know you're making a 64 KB game. I mean, how can you be so sure that your game won't fit in 48 KB? How can you be sure that it will surely fit in 64 KB?
You already know the size of your assets so you're doing an educated guess?
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Thu May 03, 2018 10:01 am
This is an experiment to help me through the process of bankswitching. But seeing as though one bank is 1% empty and another is about 20% empty, I doubt I could fit it in 48k.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3827
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu May 03, 2018 3:31 pm
I see. So, if you're using superfree sections, it won't be too hard to add bankswitching.

See this example:


; ********** SUPERFREE ASSETS (in slot 2) **********
.slot 2

.section "DESERT level assets" superfree
BGdesert_palette:
.incbin "inc/BGdesert_palette.bin"
BGdesert_tiles:
.incbin "inc/BGdesert_tiles.psgcompr"
.ends

.section "ROCK level assets" superfree
BGrock_palette:
.incbin "inc/BGrock_palette.bin"
BGrock_tiles:
.incbin "inc/BGrock_tiles.psgcompr"
.ends


here I declared two superfree sections, each containing two assets (one palette and one set of tiles in psgcompr format).

Then, when you need to access the assets in the first section, you do:
ld a,:BGdesert_palette
ld ($ffff),a

this tells the SEGA mapper to map the block that contains the BGdesert_palette label (the first in our case) into slot 2.

If you need to map the other asset instead, you do
ld a,:BGrock_palette
ld ($ffff),a


quite easy, after all.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Mon May 07, 2018 6:32 am
So what if I wanted a 1MBit game? Would I have 8 16k banks like so:

.memorymap
 defaultslot 0
 slotsize $4000 ; 16KB
 slot 0 $0000
 slot 1 $4000
 slot 2 $8000
 slot 3 $c000
.endme

.rombankmap
bankstotal 8
banksize $4000 ; 16KB
banks 8
.endro
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14745
  • Location: London
Reply with quote
Post Posted: Mon May 07, 2018 6:48 am
Yes.

The memory map defines what the Z80 can see (splits the 64KB address space into slots). The ROM bank map defines what's in the ROM (almost unlimited).

You should remove the slot at $c000, or make it smaller if you intend to use RAM sections.
  View user's profile Send private message Visit poster's website
  • Joined: 23 Mar 2013
  • Posts: 611
  • Location: Copenhagen, Denmark
Reply with quote
Post Posted: Mon May 07, 2018 10:51 am
In Astroswab I used the following memorymap with a constant to define the size of the rom:
; -----------------------------------------------------------------------------
.memorymap
; -----------------------------------------------------------------------------
  defaultslot 0
  slotsize $4000
  slot 0 $0000
  slot 1 $4000
  slot 2 $8000
  slotsize $2000
  slot 3 RAM_START
.endme
.if ROMSIZE == 128
  .rombankmap ; 128K rom
    bankstotal 8
    banksize $4000
    banks 8
  .endro
.endif
.if ROMSIZE == 256
  .rombankmap ; 256K rom
    bankstotal 16
    banksize $4000
    banks 16
  .endro
.endif

... and assigned every ramsection to slot 3 like this:
; -----------------------------------------------------------------------------
.ramsection "bluelib global variables" slot 3
; -----------------------------------------------------------------------------
  VDPStatus db
  pause_flag db
  input_ports dw
  tv_type db
  ;
.ends
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Tue May 08, 2018 7:43 am
This is what my ROM header looks like now:

.memorymap
 defaultslot 0
 slotsize $4000 ; 16KB
 slot 0 $0000
 slot 1 $4000
 slot 2 $8000
.endme

.rombankmap
bankstotal 8
banksize $4000 ; 16KB
banks 8
.endro

I tried putting some code into bank 2 but it wouldn't play it, it looped back to the title screen. I'm assuming it's because my slotsize is only 16KB like it says, but I don't know how to make them any bigger. I'm assuming the only valid numbers are $0000-$ffff, but when I look at the compiled message, it mentions $1ffff. Can I make my slots like be 64k wide and use $10000-$1ffff, or what do I do?
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3827
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue May 08, 2018 7:51 am
maps seems right.
as for putting CODE in bank2, I suggest you don't do that.
it's way easier if you put ASSETS in banks 2 & 3, and keep your code in bank 0 and 1, which you won't page out.
  View user's profile Send private message Visit poster's website
  • Joined: 06 Sep 2015
  • Posts: 268
  • Location: United States
Reply with quote
Post Posted: Tue May 08, 2018 8:39 am
How can games be 1MBit yet only use one 16k slot?
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3827
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue May 08, 2018 8:47 am
you're still missing the point of bank switching

the point is: imagine your stereo has 3 audio cassette decks - you can have 100 audio cassettes in your collection but you can put only up to 3 of them at a given time in your stereo.

ROM slots are your decks, ROM banks are your audio cassettes.
  View user's profile Send private message Visit poster's website
Reply to topic Goto page 1, 2  Next



Back to the top of this page

Back to SMS Power!