retroillucid Posted September 5, 2013 Share Posted September 5, 2013 (edited) I usually don't post thread here since I'm not a programmer... However, since we publish games for the CV, sometimes programmer(s) get stuck when it comes to use the ''Bank Switching Sheme'' or call it, the MegaCart So I decided to gather informations I already had and start an official MegaCart FAQ Feel free to make changes and add your informations wich could help other Colecovision programmers out there! MegaCart FAQ V1-2.pdf Edited September 7, 2013 by retroillucid 4 Quote Link to comment Share on other sites More sharing options...
retroillucid Posted September 5, 2013 Author Share Posted September 5, 2013 Albert gave me access to edit this thread so I can update the MegaCart FAQ So, If you have any question(s) about the MegaCart / Bank Switching , post your question here and I'll update the FAQ each time we have new infos Thanks Quote Link to comment Share on other sites More sharing options...
PkK Posted September 5, 2013 Share Posted September 5, 2013 There seems to be a bug in the current (revision #8835) sdcc pephole rules that results in the access being optimized away despite the volatile. Until it is fixed, compile with --no-peep. Also the variable is unnecessary, a simple *((volatile char*)0xFFFF); is sufficient to generate a read access. Philipp Quote Link to comment Share on other sites More sharing options...
PkK Posted September 5, 2013 Share Posted September 5, 2013 A few years ago, I made my own MegaCart. But I never found enough free time to make a game that really required it, and I found the use from sdcc too cumbersome (similart to how this one works). So I started on building support for bank-switching into sdcc. I just had a look at the current state. It would work for bankswitched RAM, but needs a bit of work for the ROM. When I find a bit of time, I'll fix it. Once that is done, using the MegaCart from sdcc should be much simpler. We would use named address spaces (see section 3.6.2 in the sdcc manual, which also contains a small example of how this works for RAM). You just write a function to switch to a particular bank, declare banks for your variables and then just access them normally: void set_bank_a(void) { *((volatile char*)0xffff); } void set_bank_b(void) { *((volatile char*)0xfffe); } __addressmod set_bank_a bank_a; __addressmod set_bank_b bank_b; const bank_a char d = 'c'; // A const char in bank a. const bank_a char *const bank_b c = &d; // A const pointer in bank b that points to a const char in bank a. char f(void) { return *c; // sdcc will automatically insert the calls to set_bank_a() and set_bank_b() as necessary. } Actually, sdcc already generates correct code for the function f() in this example, but messes up the initialization of c and d (sdcc behaves as if they were in RAM). sdcc will try to minimize the calls to the bank selection function, and will only insert the minimum number necessary. Read "Optimal Placement of Bank Selection Instructions in Polynomial Time" for the details. However, it does not yet do inter-procedural analysis, so it doesn't know which bank is active after a function call. Philipp P.S.: All this is about data in banked memory, not calling functions in banked memory. To me, the latter problem seemed less interesting from a theoretical computer science perspective, so I never bothered with it. 1 Quote Link to comment Share on other sites More sharing options...
+nanochess Posted September 5, 2013 Share Posted September 5, 2013 Very useful info, J-F! I was wondering how Megacart was used with C language For Princess Quest and Mecha-8 I'm using assembler, I've found useful the following definitions (TNIasm v0.44): ; For 128K Megacart (for 256K one I start on $fff0 upto SLOT_15 at $ffff) SLOT_0: equ $fff8 SLOT_1: equ $fff9 SLOT_2: equ $fffa SLOT_3: equ $fffb SLOT_4: equ $fffc SLOT_5: equ $fffd SLOT_6: equ $fffe SLOT_7: equ $ffff ; At start of code ld hl,SLOT_0 ; Default slot of Megacart, but set again because user can do a Colecovision RESET call sel_slot ; My typical switching code ld hl,SLOT_3 call sel_slot ; Slot selection sel_slot: ld (slot),hl ; Saves current slot, useful because in NMI routine sometimes I switch slots to play music from OTHER slot ld a,(hl) ret ; In Princess Quest, I tend to keep all code for game in the most upper slot (always mapped in $8000-$BFFF) and some code/data in SLOT_0 (default one, mapped at $C000-$FFBF), then code switches slots as needed to access other data (no code) For Mecha-8 finally I've jumped the bridge and apart from basic SLOT_7/SLOT_0 containing 32K code/data, there is a separate intermediate slot were are contained various routines for bosses, SGM detection and so. 3 Quote Link to comment Share on other sites More sharing options...
retroillucid Posted September 5, 2013 Author Share Posted September 5, 2013 (edited) Very useful info, J-F! I was wondering how Megacart was used with C language For Princess Quest and Mecha-8 I'm using assembler, I've found useful the following definitions (TNIasm v0.44): ; For 128K Megacart (for 256K one I start on $fff0 upto SLOT_15 at $ffff)SLOT_0: equ $fff8SLOT_1: equ $fff9SLOT_2: equ $fffaSLOT_3: equ $fffbSLOT_4: equ $fffcSLOT_5: equ $fffdSLOT_6: equ $fffeSLOT_7: equ $ffff; At start of code ld hl,SLOT_0 ; Default slot of Megacart, but set again because user can do a Colecovision RESET call sel_slot; My typical switching code ld hl,SLOT_3 call sel_slot; Slot selectionsel_slot: ld (slot),hl ; Saves current slot, useful because in NMI routine sometimes I switch slots to play music from OTHER slot ld a,(hl) ret;In Princess Quest, I tend to keep all code for game in the most upper slot (always mapped in $8000-$BFFF) and some code/data in SLOT_0 (default one, mapped at $C000-$FFBF), then code switches slots as needed to access other data (no code) For Mecha-8 finally I've jumped the bridge and apart from basic SLOT_7/SLOT_0 containing 32K code/data, there is a separate intermediate slot were are contained various routines for bosses, SGM detection and so. Awesome! Glad it help! Please, update the FAQ with your informations too! EDIT: Maybe it will be good to have to seperate section, one for C and one for Assembler ? Edited September 5, 2013 by retroillucid Quote Link to comment Share on other sites More sharing options...
+nanochess Posted September 5, 2013 Share Posted September 5, 2013 Awesome! Glad it help! Please, update the FAQ with your informations too! EDIT: Maybe it will be good to have to seperate section, one for C and one for Assembler ? Feel free to use my info in your FAQ 1 Quote Link to comment Share on other sites More sharing options...
Kiwi Posted September 6, 2013 Share Posted September 6, 2013 Thank you for posting the Megacart FAQ. I have some theories how I may do these. Doing and experimenting is going to get me somewhere. Eventually I'll crack the case. 4 Quote Link to comment Share on other sites More sharing options...
retroillucid Posted September 6, 2013 Author Share Posted September 6, 2013 (edited) Quick update And decide to convert it into PDF I'll do my best to make a nice document, with pictures If you have something you think should be in the FAQ, please post it here Thanks Edited September 6, 2013 by retroillucid Quote Link to comment Share on other sites More sharing options...
retroillucid Posted September 7, 2013 Author Share Posted September 7, 2013 Another quick update Quote Link to comment Share on other sites More sharing options...
PkK Posted September 8, 2013 Share Posted September 8, 2013 I fixed the peephole issue and implemented support for named address spaces in ROM. Something like this should work now (sdcc 3.3.1 #8837 or later): void setb0(void) // The function that sets the currently active memory bank to b0 { *((volatile char*)0xffff); } void setb1(void) // The function that sets the currently active memory bank to b1 { *((volatile char*)0xfffe); } __addressmod const setb0 spaceb0; // Declare a named address space called spaceb0 that uses setb0() and reisdes in RAM __addressmod setb1 spaceb1; // Declare a named address space called spaceb1 that uses setb1() and resides in ROM const spaceb0 int x = 42; // An int in address space spaceb0 spaceb1 int *y; // A pointer to an int in address space spaceb1 const spaceb0 int *spaceb1 z; //A pointer in address space sapceb1 that points to a constant int in address space spaceb0 The variables will be placed into areas of the same name, so you can use linker options -b to place the named address spaces into memory. Again, you might also want to have a look at section 3.6.2 of the sdcc manual. Philipp 3 Quote Link to comment Share on other sites More sharing options...
retroillucid Posted September 11, 2013 Author Share Posted September 11, 2013 thanks Philipp! I'll update the FAQ Quote Link to comment Share on other sites More sharing options...
PkK Posted March 17, 2014 Share Posted March 17, 2014 I jut noticed there was a minor mistake in the example I posted. Here's a corrected version: void setb0(void) // The function that sets the currently active memory bank to b0 { *((volatile char*)0xffff); } void setb1(void) // The function that sets the currently active memory bank to b1 { *((volatile char*)0xfffe); } __addressmod setb0 const spaceb0; // Declare a named address space called spaceb0 that uses setb0() and resides in ROM __addressmod setb1 spaceb1; // Declare a named address space called spaceb1 that uses setb1() and resides in RAM const spaceb0 int x = 42; // An int in address space spaceb0 spaceb1 int *y; // A pointer to an int in address space spaceb1 const spaceb0 int *spaceb1 z; //A pointer in address space sapceb1 that points to a constant int in address space spaceb0 1 Quote Link to comment Share on other sites More sharing options...
youki Posted March 18, 2014 Share Posted March 18, 2014 I jut noticed there was a minor mistake in the example I posted. Here's a corrected version: void setb0(void) // The function that sets the currently active memory bank to b0 { *((volatile char*)0xffff); } void setb1(void) // The function that sets the currently active memory bank to b1 { *((volatile char*)0xfffe); } __addressmod setb0 const spaceb0; // Declare a named address space called spaceb0 that uses setb0() and resides in ROM __addressmod setb1 spaceb1; // Declare a named address space called spaceb1 that uses setb1() and resides in RAM const spaceb0 int x = 42; // An int in address space spaceb0 spaceb1 int *y; // A pointer to an int in address space spaceb1 const spaceb0 int *spaceb1 z; //A pointer in address space sapceb1 that points to a constant int in address space spaceb0 Hi Philip , Thanks for the update. You should also correct that in the SDCC documentation (paragraph 3.6.2 ) I will try again tonight. Quote Link to comment Share on other sites More sharing options...
PkK Posted March 18, 2014 Share Posted March 18, 2014 You should also correct that in the SDCC documentation (paragraph 3.6.2 ) Fixed in revision #8961. Philipp Quote Link to comment Share on other sites More sharing options...
digress Posted March 18, 2014 Share Posted March 18, 2014 Cool, I would love to be able to program in C language for the bank switching megacart in the future. Any development to make that easier for me is very welcome. I also would need to locate some megacart pcbs. Please keep up the good work. Quote Link to comment Share on other sites More sharing options...
Pixelboy Posted March 18, 2014 Share Posted March 18, 2014 I just had a look at the PDF posted in the first post of this thread, and I think it needs some work. What is the C code doing in section 1, when it clearly belongs in section 2? And the entire content of section 2 has nothing to do with C language. Furthermore, it's good to know how to switch banks in C, but that's only half of the required knowledge. The second part, which is just as important if not more so, is how to create/compile a 128K or 256K ROM file. Do I need to piece the banks together with an hex editor? Some tips about how to do this would be nice. Quote Link to comment Share on other sites More sharing options...
youki Posted March 18, 2014 Share Posted March 18, 2014 I just had a look at the PDF posted in the first post of this thread, and I think it needs some work. What is the C code doing in section 1, when it clearly belongs in section 2? And the entire content of section 2 has nothing to do with C language. Furthermore, it's good to know how to switch banks in C, but that's only half of the required knowledge. The second part, which is just as important if not more so, is how to create/compile a 128K or 256K ROM file. Do I need to piece the banks together with an hex editor? Some tips about how to do this would be nice. My question would be more , if you have a 256k ROM , said one file of 256k .. how to you put it on a MegaCart? Do we have to split it in 32k part in order to burn each bank on eeprom or what ever used in the cartridge? I think you have experience with that Luc? ... Does Mecha8 comes to you to be burn in one file or multiple files? Quote Link to comment Share on other sites More sharing options...
retroillucid Posted March 18, 2014 Author Share Posted March 18, 2014 My question would be more , if you have a 256k ROM , said one file of 256k .. how to you put it on a MegaCart? Do we have to split it in 32k part in order to burn each bank on eeprom or what ever used in the cartridge? I think you have experience with that Luc? ... Does Mecha8 comes to you to be burn in one file or multiple files? You burn one file into the eprom Quote Link to comment Share on other sites More sharing options...
Pixelboy Posted March 18, 2014 Share Posted March 18, 2014 My question would be more , if you have a 256k ROM , said one file of 256k .. how to you put it on a MegaCart? Do we have to split it in 32k part in order to burn each bank on eeprom or what ever used in the cartridge? I think you have experience with that Luc? ... Does Mecha8 comes to you to be burn in one file or multiple files? 5-11under could answer that question with absolute certainty. Quote Link to comment Share on other sites More sharing options...
retroillucid Posted March 18, 2014 Author Share Posted March 18, 2014 (edited) 5-11under could answer that question with absolute certainty. I've burned all the first batch of Mario eproms by myself There was only 1 file to burn The bankswitching is on 1 eprom ... the banks are NOT located in another eprom(s) Edited March 18, 2014 by retroillucid Quote Link to comment Share on other sites More sharing options...
youki Posted March 18, 2014 Share Posted March 18, 2014 I jut noticed there was a minor mistake in the example I posted. Here's a corrected version: void setb0(void) // The function that sets the currently active memory bank to b0 { *((volatile char*)0xffff); } void setb1(void) // The function that sets the currently active memory bank to b1 { *((volatile char*)0xfffe); } __addressmod setb0 const spaceb0; // Declare a named address space called spaceb0 that uses setb0() and resides in ROM __addressmod setb1 spaceb1; // Declare a named address space called spaceb1 that uses setb1() and resides in RAM const spaceb0 int x = 42; // An int in address space spaceb0 spaceb1 int *y; // A pointer to an int in address space spaceb1 const spaceb0 int *spaceb1 z; //A pointer in address space sapceb1 that points to a constant int in address space spaceb0 Hi Philip, I managed to compile now and link. But the result rom is not usable. In fact, the coleco's cartridge header (0x55 0xAA...etc ) in the rom file is now located at 0x0F8F instead of 0x0000 . Do you have an idea how to fix that? Thanks Quote Link to comment Share on other sites More sharing options...
+5-11under Posted March 18, 2014 Share Posted March 18, 2014 My question would be more , if you have a 256k ROM , said one file of 256k .. how to you put it on a MegaCart? Do we have to split it in 32k part in order to burn each bank on eeprom or what ever used in the cartridge? I think you have experience with that Luc? ... Does Mecha8 comes to you to be burn in one file or multiple files? See page 3 of the FAQ for reference. For the EPROM, bank 0 is at the start (of the EPROM - takes up 16K), followed by bank 1, 2, etc. These get mapped (one at a time, depending on which one is selected) to the upper 16K of memory space in the CV (Cxxx to Fxxx). The final (upper) bank of the EPROM gets mapped to 8xxx to Bxxx of the memory space in the CV. Quote Link to comment Share on other sites More sharing options...
bfg.gamepassion Posted November 22, 2014 Share Posted November 22, 2014 (edited) Hello, can someone make a hellow world example for SDCC with makefile, ctr0 modified is needed and so ? Because i've got the theory in mind, but for the moment i know no one (Youki,Alekmaul and me) succeeding making a megacart rom in SDCC ... :( Edit : forget it, seems like AlekMaul just suceed for Bagman :) Edited November 22, 2014 by bfg.gamepassion 1 Quote Link to comment Share on other sites More sharing options...
+nanochess Posted November 22, 2014 Share Posted November 22, 2014 Here is the link to AlekMaul code for using Megacart with SDCC 3.3.0 http://www.gamopat-forum.com/t75551-colecovision-et-megacart#1945318 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.