MSXDOS2 Memory mapper test

Post Reply
bradstallion
Member
Posts: 30
Joined: Wed Mar 13, 2024 12:52 pm

MSXDOS2 Memory mapper test

Post by bradstallion »

Hi All,
I'm playing with MSXDOS2 memory mapper (https://map.grauw.nl/resources/dos2_environment.php#c5). I'm using ASMLIB to access the EXTBIO routines.
While "get" routines work, I have some problem with "put" functions.
I write below a minimal example showing my problem. It first allocate a new segment (using ALL_SEG routine), and then tries to switch it on page 2, and then going back to the old segment.

This can be compiled with:

z88dk.zcc +msx -o min.com msxmapper.c -subtype=msxdos2

As you can see from the screenshot, I put a segment in page 2, then I ask what the current segment is for such page, but a 32 is returned.
Can you help me?
Thanks a lot

Code: Select all

#include <stdio.h>
#include <arch/msx/asm.h>

#define EXTBIO 0xFFCA

// mapper routine MR
#define MR_ALL_SEG 0
#define MR_GET_P2 0x27
#define MR_PUT_P2 0x24

Z80_registers regs;
register_usage usage;


// get routine table address
uint mapper_routine_table() {
  usage = 2;

  regs.Bytes.A = 0;
  regs.Bytes.D = 4;
  regs.Bytes.E = 2;
  AsmCall(EXTBIO, &regs, usage, usage);

  //printf("%d %d %d\n", regs.Bytes.A, regs.Bytes.B, regs.Bytes.C);
  
  return regs.Words.HL;
}

// allocate a new segment (ALL_SEG)
char mapper_allocate() {
  usage = 2;

  uint address = mapper_routine_table() + MR_ALL_SEG;

  regs.Bytes.A = 0;
  regs.Bytes.B = 0;
  AsmCall(address, &regs, usage, usage);
  if (regs.Flags.C) return 0;
  return regs.Bytes.A;
}

// get segment on page 2
char mapper_get_p2() {
  usage = 2;

  uint address = mapper_routine_table() + MR_GET_P2;
  AsmCall(address, &regs, usage, usage);

  //printf("%d %d %d\n", regs.Bytes.A, regs.Bytes.B, regs.Bytes.C);
  
  return regs.Bytes.A;  
}

// get segment on page X (offset required)
char mapper_get_seg(uint page_off) {
  usage = 2;

  uint address = mapper_routine_table() + page_off;
  AsmCall(address, &regs, usage, usage);

  //printf("%d %d %d\n", regs.Bytes.A, regs.Bytes.B, regs.Bytes.C);
  
  return regs.Bytes.A;  
}


// put segment on page 2
void mapper_put_p2(uchar segment) {
  usage = 2;

  regs.Bytes.A = segment;
  uint address = mapper_routine_table() + MR_PUT_P2;
  printf("putting %x in 2 (routine in %x)\n", segment, address);
  AsmCall(address, &regs, usage, usage);
}

void main() {
  // allocate a new segment
  uchar newseg = mapper_allocate();

  printf("Newseg: %d\n", newseg);

  // get current segment in page 2
  uchar oldseg = mapper_get_p2();
  uchar tmpseg;
  
  printf("I want to switch %d <-> %d\n", oldseg, newseg);
  
  // from current seg to another seg...
  mapper_put_p2(newseg);

  //between
  tmpseg = mapper_get_p2();  // get current segment in page 2
  printf("  seg in between is: %d (WHY?)\n", tmpseg);

  // ... and back
  mapper_put_p2(oldseg);  // restore segment

  //before exiting
  tmpseg = mapper_get_p2();  // get current segment in page 2
  printf("    now seg in 2 is: %d (WHY?)\n", tmpseg);  
  
}

You do not have the required permissions to view the files attached to this post.
User avatar
dom
Well known member
Posts: 2142
Joined: Sun Jul 15, 2007 10:01 pm

Re: MSXDOS2 Memory mapper test

Post by dom »

That was a fun one.

Code: Select all

void mapper_put_p2(uchar segment) {
  usage = 2;

  regs.Bytes.A = segment;
  uint address = mapper_routine_table() + MR_PUT_P2;
mapper_routine_table() modifies the regs structure thus corrupting the segment you've just stored.
bradstallion
Member
Posts: 30
Joined: Wed Mar 13, 2024 12:52 pm

Re: MSXDOS2 Memory mapper test

Post by bradstallion »

That was so silly!!!! :rolleyes:
Thanks a lot! :)
Post Reply