20

I have been investigating the MS-DOS port of the C64's Maniac Mansion game. The original MS-DOS port used the C64-specific character map to draw the various backgrounds in the game. I noticed that each background (i.e. room) has 4 colours.

These four values appear to be read as colours within the ScummVM source code:

void GdiV1::roomChanged(byte *roomptr) {
for (int i = 0; i < 4; i++){
    _V1.colors[i] = roomptr[6 + i];
}

For each room in the game, the first 3 colours always fall within the range of 0x00 and 0x15, corresponding to the original C64 colour palette. For most of the other rooms, the fourth colour almost always falls in this range with a few exceptions.

Originally I assumed the C64 game was running in Multicolor Character Mode. This matched other sources:

This is purely done in multicolor character graphics

If the game runs on the C64 in the Multicolor Character Mode I expect the first 3 colours to be used as the common colours across all characters.

I loaded up Maniac Mansion on the Vice emulator to check the memory settings via the built in monitor tool (ALT+M on Windows). I checked the memory at these addresses:

enter image description here

I was expecting these two addresses to show that the game is running in Multicolor Character Mode:

D011: $7C  0111 1100  
D016: $51  0101 0001  

Using the following source it looks like the following is enabled:

  • Extended Background Color Mode (bit 6 set in D011)
  • Standard Bitmap Mode (bit 5 set in D011)
  • Multicolor Bitmap Mode (bit 4 set in D016)

Assuming the bit numbers are counted in this order:

7 6 5 4 3 2 1 0

In the same source this is known as Extended Background Color Multicolor Bitmap Mode. Refer to mode 7 in the table. The following is stated:

Modes 5-7 are technically feasible, but considered illegal. Although the features expected of modes 5-7 are present (such as collision detection), there is no visible screen output for the user. It is for this reason that they are not utilised.

I checked the addresses for the 3 common background colours:

D021: $16  0001 0110 
D022: $26  0010 0110 
D023: $FB  1111 1011

As you can see, these bytes do not fall within 0x00 to 0x15, nor do they actually correspond to the same values I am reading in the DOS port.

According to this article, the screen switches between 2 character sets to display text on screen:

Another thing of note is that the C64 supports two different character sets (2×256 Characters) and that the second character set consists of a common font, including the inventory arrows. This is one of the reasons that there is no text in the main game screen – they use the second (font) character set for the title line, switch to the primary set to draw the screen, then back to the secondary set for the menu at the bottom.


I want to know if I am using the correct method to determine the graphic mode for the game in question.

Ultimately I want to understand how the room's 4th colour is actually applied.


I have used additional sources to map the C64 memory as well as which addresses I need to check.

10
  • 3
    VICE maybe showing you the RAM that lives "underneath" the device I/O region where the VIC-II chip is mapped. Also it looks from the screen shot the game switches modes, using standard character mode for the top line and one of the multicolour colour modes for the rest.
    – user722
    Commented Nov 17, 2017 at 1:26
  • 4
    It's doing more than just switching fonts, it's also switching modes. The top line uses the C64's standard 8x8 font which only works (unscaled) in either standard character or standard bitmap mode. On the other hand the Manic Mansion logo uses three colours (four if you count the word "START", but that could be a sprite) and double width pixels, which means it's almost certainly using either multicolor character or multicolor bitmap mode.
    – user722
    Commented Nov 17, 2017 at 1:56
  • 1
    In VICE debugger, try using the following command: io $d000. If it wouldn't help, it will at least show VIC config in more readable way than digging hex dumps.
    – lvd
    Commented Nov 17, 2017 at 6:39
  • 3
    @RossRidge You can mix multicolor characters and hires characters, but then you lose half the possible colours which is a pain (because one colour bit is used to toggle the interpretation of the character). I made a game for 2016 7DRL challenge which did exactly that. (dropbox.com/s/fiqwmy9qzm1oz9n/monsters.png?dl=0)
    – tylisirn
    Commented Nov 18, 2017 at 17:48
  • 3
    @camelCase, note that gfx mode can be switched during the ray scanning time. It is a routine practice on C64 to have line interrupts and switch all the things including gfx mode.
    – lvd
    Commented Nov 18, 2017 at 23:51

2 Answers 2

7

I downloaded the ScummVM source code, and debugged any section of code that read from this "4th colour". It appears that before it reads the 4th colour it is overwritten (in a way that appears to match the block of colour ram used in C64's Multicolor Character Mode):

void GdiV1::drawStripV1Background(byte *dst, int dstPitch, int stripnr, int height) {
    int charIdx;
    height /= 8;
    for (int y = 0; y < height; y++) {
        _V1.colors[3] = (_V1.colorMap[y + stripnr * height] & 7); // overwrite
        // Check for room color change in V1 zak
        if (_roomPalette[0] == 255) {
            _V1.colors[2] = _roomPalette[2];
            _V1.colors[1] = _roomPalette[1];
        }

        charIdx = _V1.picMap[y + stripnr * height] * 8;
        for (int i = 0; i < 8; i++) {
            byte c = _V1.charMap[charIdx + i];
            dst[0] = dst[1] = _V1.colors[(c >> 6) & 3];
            dst[2] = dst[3] = _V1.colors[(c >> 4) & 3];
            dst[4] = dst[5] = _V1.colors[(c >> 2) & 3];
            dst[6] = dst[7] = _V1.colors[(c >> 0) & 3]; // read _V1.colors[3]
            dst += dstPitch;
        }
    }
}

The same occurs here:

void GdiV1::drawStripV1Object(byte *dst, int dstPitch, int stripnr, int width, int height) {
    int charIdx;
    height /= 8;
    width /= 8;
    for (int y = 0; y < height; y++) {
        _V1.colors[3] = (_V1.objectMap[(y + height) * width + stripnr] & 7); // overwrite
        charIdx = _V1.objectMap[y * width + stripnr] * 8;
        for (int i = 0; i < 8; i++) {
            byte c = _V1.charMap[charIdx + i];
            dst[0] = dst[1] = _V1.colors[(c >> 6) & 3];
            dst[2] = dst[3] = _V1.colors[(c >> 4) & 3];
            dst[4] = dst[5] = _V1.colors[(c >> 2) & 3];
            dst[6] = dst[7] = _V1.colors[(c >> 0) & 3]; // read _V1.colors[3]
            dst += dstPitch;
        }
    }
}

In terms of the ScummVM emulator, the 4th colour found in the data files is never actually used.

That answers my original question: Ultimately I want to understand how the room's 4th colour is actually applied.

In regards to I want to know if I am using the correct method to determine the graphic mode for the game in question.:

I have used the suggestions in the comments and managed to get meaningful values by using the io command:

(C:$d040) io $d000
VIC-II:
>C:d000  00 fd 00 fd  00 fd 00 fd  00 fd 00 fd  00 fd 27 45   ..............'E
>C:d010  00 9b 37 00  00 ff c9 00  3f 74 f1 00  7f 00 ff 00   ..7.....?t......
>C:d020  f0 f0 fe fa  f1 fa f0 f1  f2 f3 f4 f5  f6 f7 fc ff   ................
>C:d030  ff ff ff ff  ff ff ff ff  ff ff ff ff  ff ff ff ff   ................

Rasterline:   current: 0 IRQ: 41
Display Mode: Standard Hires Text
Colors:       Border:  0 Background:  0
Scroll X/Y:   1/3
Screen Size:  40 x 25

VIC Memory Bank:   $c000 - $ffff

Video Memory:      $cc00
Character Set:     $f800

Sprites:
           Spr.0  Spr.1  Spr.2  Spr.3  Spr.4  Spr.5  Spr.6  Spr.7
Enabled:     yes    yes    yes    yes    yes    yes    yes    yes
Pointer:     $bc    $bd    $be    $bf    $c0    $00    $c0    $c1
Address:   $ef00  $ef40  $ef80  $efc0  $f000  $c000  $f000  $f040
X-Pos:         0      0      0      0      0      0      0     39
Y-Pos:       253    253    253    253    253    253    253     69
X-Expand:     no     no     no     no     no     no     no     no
Y-Expand:     no     no     no     no     no     no     no     no
Priority:    spr    spr    spr    spr    spr    spr    spr    spr
Mode:       muco   muco   muco   muco   muco   muco   muco    std
Color:         1      2      3      4      5      6      7     12
Multi Color 1: 10  Multi Color 2: 0

I'm not sure why there is a different compared to reading the values directly from the memory compared to using the io command. Regardless, the io command allowed me to confirm that 3 of the 4 colours found in the data files is being applied.


Update

Ross Ridge added the following comment to explain the differences seen when reading the values directly from the memory compared to using the io command:

If you'll look at the memory map you linked you'll see that one of three different things can be mapped into the $D000 to $DFFF address range: "I/O Area (memory mapped chip registers), Character ROM or RAM area (4096 bytes); depends on the value of bits #0-#2 of the processor port at memory address $0001". Rather than showing you what the CPU currently sees mapped into that range, the VICE debugger may simply be showing the RAM that can be mapped into that range.

1
  • Add the other comments have mentioned, you can't look at the io registers in an 'instant' because, depending on where the scan-line was when the snapshot was taken, may give different results.
    – Neil
    Commented Sep 14, 2018 at 7:40
0

I don't know what's going on in VICE, but the C64 game definitely uses multicolor character mode for the graphics. (And standard character mode for the text; as others have said, you can have both at once as long as they're on different scanlines). You can tell it's a character mode because the graphics use repeating 8x8 tiles, and because the game moves at more than like 3 FPS (updating the entire screen in bitmap mode was very slow, and basically never used in games outside of 3D sims and title screens); it's multicolor because the pixels are double-wide.

Incidentally, the DOS version does not use the same character map as the C64 version; all the custom characters have been redrawn. The C64's double-wide multicolor-mode pixels are very distinctive; compare screens like this one on the 64 with the same room in CGA or EGA modes in the DOS version.

4
  • 2
    Be aware that there are 2 DOS versions of Maniac Mansion. The early version fits on a single 360K floppy, the later version ("enhanced version") needs two 360K floppies (or a single 720K floppy) and has vastly improved graphics on EGA. Unfortunately, the screenshots you show are so far in the game that I don't feel like playing up to that room to compare the two different DOS versions to the C64 version. Commented Dec 5, 2020 at 11:29
  • 1
    @MichaelKarcher MobyGames has DOS screenshots of both versions jumbled together. Just look for equivalent screenshots where one says "Enhanced version, EGA". Funny enough, ScummVM-Compatible resources for the 360K version can be extracted from the Day of the Tentacle CD and ScummVM-compatible resources for the 720K version can be extracted from Day of the Tentacle Remastered.
    – ssokolow
    Commented Dec 5, 2020 at 16:04
  • 1
    So, comparing mobygames.com/game/c64/maniac-mansion/screenshots/… (C64), mobygames.com/game/dos/maniac-mansion/screenshots/… (original EGA) and mobygames.com/game/dos/maniac-mansion/screenshots/… (enhanced EGA), it looks like in this scene the original EGA graphics is the same as the C64 graphics, whereas the enhanced version upgrades from 160x200 to 320x200. Commented Dec 5, 2020 at 16:41
  • 1
    @MichaelKarcher Fair enough. I spent a while looking at DOS Maniac Mansion screenshots on Google and they all had normal-sized pixels; I guess nobody outside MobyGames keeps the actual originals. Commented Dec 6, 2020 at 0:21

You must log in to answer this question.