How to access all RAM pages without a mapper?

By saccopharynx

Supporter (13)

saccopharynx's picture

08-02-2012, 12:45

Hello,

I'm turning a 48Kb ROM game into 3 binary files. Everything works just fine if I use a mapper, but not when I set the standard MSX 1 memory configuration (No mapper present). I'm trying the default "MSX" profile on BlueMSX and I would like to know if it is possible to gain access to each of the RAM pages. The configuration is as follows:

Slot            Address            Type                        ROM Image

0                0000-7fff            Normal                    MSX.rom
2                4000-bfff            Disk Controller        PHILIPDISK.rom
3                0000-ffff            64 kb. Normal RAM

When I run the emulator and the game starts, RAM pages 2 and 3 are respectively loaded at ranges 8000-bfff and c000-ffff of the visible memory. I can also gain access to page 1 by making use of the ENASLT MSX BIOS call #0024 to select the same slot in page 1 as I have in page 3 (SYSTEM RAM). At this stage, the disk controller is of course swept away from page 1.

However, at some point, the game "temporarily" needs to load some data in Page 0 by removing the BIOS. The thing is I haven't succeeded at selecting Page 0 of RAM into the Z80 Visible Memory. I would basically like, if possible, to use ENASLT to select slot 3 and Page 0 of Normal RAM into page 0 of visible RAM, but every attempt ends up with Page 1 of Normal RAM loaded in Page 0 of visible RAM.

Any idea how to do this?

Thanks,

S

Login or register to post comments

By Jipe

Paladin (689)

Jipe's picture

08-02-2012, 14:54

for the bank 0000h acces use the A8 port
exemple for a 16k game
F3 DI
3E FF LD A,FFh
D3 A8 OUT (A8),A
21 00 90 LD HL,9000h
11 00 00 LD DE,0000h
01 00 40 LD BC,4000h
ED B0 LDIR
2A 02 00 LD HL,(0002h)
E9 JP  (HL)

By Google

By saccopharynx

Supporter (13)

saccopharynx's picture

08-02-2012, 15:03

Thank you Jipe. A few minutes ago I realised that the value of reg A must be FFh, which makes, as you exactly described, the bank 0000h accessible. Does it imply that there is no way to access bank 0000h unless the other ones are also in visible memory?

Thanks for your help.

S

By snakepow

Master (212)

snakepow's picture

08-02-2012, 16:22

Hello, I haven't tried it using ENASLT. First, working with 64 kb normal RAM, you can't talk about pages on fisical RAM , i.e., Z80 visible memory (memory space) keep having pages, but fisical RAM is a plain RAM. I mean, on Z80 memory space (visible addresses) 0000-3FFF  (page 0 of visible RAM) you only can access to fisical RAM 's 0000-3FFF, Z80 's 4000-7FFF only can access to RAM's 4000-7FFF, and so on.

Once this aclaration is made, I haven't tried what you want to do using BIOS (Enaslt) , but perhaps there's any problem because ENALST is on this Page 0 you want to change. Perhaps this can't be done using BIOS. Other way to access memory is not using ENALST, working directly with PPI register A that changes Z80 Visible memory. You must change register value (Hex) #A8 of input/output space. This register contains every primary slot number assigned to every Z80 visible memory access.

                                            #A8 register  :    bit7 bit6 bit5 bit4 bit3 bit2 bit1 bit0

                                            bit7 bit6 : defines primary slot number to be assigned at C000-FFFF Z80 visible memory
                                            bit5 bit4 : defines primary slot number to be assigned at 8000-BFFF Z80 visible memory
                                            bit3 bit2 : defines primary slot number to be assigned at 4000-7FFF Z80 visible memory
                                            bit1 bit0 : defines primary slot number to be assigned at 0000-3FFF Z80 visible memory

So for access your Slot 3's RAM on 0000-3FFF Z80 memory space, you must put bit1 bit0 with value 3, it is bit1=1, bit0=1. But the rest of A8's bits must keep its value (or can be set to the value you want).

For example, suppose your 48k ROM game is in slot 1 and starts at address #4000. When MSX boots and starts this ROM game, the initial execution point of your game is in address #4000, where Z80 visible memory's page 0 (#0000 to #3FFF) is set to the slot where BIOS is ( slot 0 in most cases), page 1 (#4000-7FFF) is set where ROM game is (in this case slot 1) and finally page 2 and page 3 (8FFF to FFFF) is set in the slot where RAM is. Once your game just starts its exeution, you can change page 0 to access RAM instead of BIOS. If you don't need use of BIOS in your game, and your game only needs 16K of RAM to work, you can set when your game starts, Z80 visible memory page 0 to the slot where RAM is, and page 1 , page 2, page 3 to the slot where ROM game is (in our supposed case, slot 1). In ASM this will be the following code:
                                        org #4010  // our program / ROM game starts at address 4010 Hex

                                                                     
                                        // first put in page 0 the slot where RAM is. I put on bits 1 - 0 the same value than bits 7 - 6
                                        in A,#A8
                                        and #FC  //put bits 1 - 0 to value 0 because they will be changed
                                        ld B,A    //save value on B
                                        and #C0  // put all bits to 0 except bits 7 - 6
                                        rrca   // rotate bits right until bits 7 - 6 are placed in bits 1 - 0
                                        rrca
                                        rrca
                                        rrca
                                        rrca
                                        rrca
                                        or B
                                        out (#A8),A    // now page 0 has the same slot than page 3 , i.e., RAM

                                        // second : put in page 2 the slot where ROM game is , i.e. , slot 1 in our example but I make a more generical case because I know  bits 3-2 are the slot where ROM game is.
                                        in A,(#A8)
                                        and #CF  //put bits 5 - 4 to value 0 because they will be changed
                                        ld B,A    //save value on B
                                        and #0C  // put all bits to 0 except bits 3 - 2
                                        rlca   // rotate bits left until bits 3 - 2 are placed in bits 5 - 4
                                        rrca
                                        or B
                                        out (#A8),A    // now page 2 has the same slot than page 1 , i.e., ROM game

Note: Never change the slot corresponding to page where execution code is, because execution code will be lost. In this example code before, I have changed page 0 's slot and page 2's slot , because I'm working from page 1 (i.e. code I'm executing is in page 1). If I changed page 1's slot , where Z80 continued its execution ?

    

                                               
                                       

By retrocanada76

Champion (418)

retrocanada76's picture

08-02-2012, 18:03

Keep in mind that there are 2 or more msx2 computers with non memory mapped ram and those 32k ram banks reside in two different slots! So using the same slot as page 3 DOES NOT guarantee it will work on all machines.
If your code does need the disk driver, then you can get the RAM pages slots from RAMAD0-RAMAD3 #F341-#F344.  The diskrom slot is located at #F348 address. 

Don't forget the subslot selector address #FFFF. Also don't forget you can only change the subslot of the current slot in use in page 3 so you will need relocatable code in different pages to allow swapping all pages.

Accessing directly the diskrom is not another good thing. Turbo-R and machines with diskrom2 won't work either. Go for documentation, all diskrom functions are accessed through working area hooks.

By RetroTechie

Paladin (697)

RetroTechie's picture

08-02-2012, 18:21

You can't use ENASLT to put RAM in page 0, because that pages out the BIOS slot-switch routines permanently. So even if RAM gets switched into page 0, execution of ENASLT (probably) wouldn't finish properly. For same reason RAM enabled this way would be of little use to run code, since interrupt entry point 0038h & BIOS routines are gone then.

But you could use it fine to store data, and use the other slot-switch routines to access it. Best suited for large chunks of data you can copy smaller parts of as needed: level maps, music data, etc. May I suggest this procedure:

  1. Use WRSLT to put in a very short piece of machine code. Something like "LDIR; RET" might be sufficient.
  2. Set up HL, DE and BC registers as desired.
  3. Use CALSLT to call those few bytes you put in at step 1). The ending "RET" will restore BIOS ROM back in page 0 and return to calling routine.

You could use RDSLT/WRSLT for all read/write operations, but that would be extremely slow.

IMPORTANT: If you plan to release software, don't assume RAM = slot 3 (or any slot)! At least use same slot that's in page 2 or 3, that only fails on machines which have 64K split over several slots (read: machines which are very problematic software-wise anyway). Or do a proper search to determine which slot(s) have RAM in page 0. Using the BIOS routines makes it easy to support expanded slots too. Which is useful, for eg. Philips VG8020/20 is a very common MSX1 with RAM in an expanded slot.

By saccopharynx

Supporter (13)

saccopharynx's picture

09-02-2012, 00:15

I really appreciate the help provided by all of you. Besides, as many of you properly predicted, the execution of ENASLT didn't finish when I switched RAM into page 0. That's a fact indeed. Thanks everyone.

S.

My MSX profile