src/mess/drivers/rx78.c
| r8614 | r8615 | |
| 5 | 5 | preliminary driver by Angelo Salese |
| 6 | 6 | |
| 7 | 7 | TODO: |
| 8 | | - Rewrite vram routines, they aren't quite right (we're currently drawing |
| 9 | | stuff from the work ram and not the proper bitmap buffer) |
| 8 | - caps lock doesn't seem quite right; |
| 9 | - implement cmt / printer (hovewer no dumps are available right now) |
| 10 | - implement joystick inputs |
| 10 | 11 | |
| 11 | 12 | ****************************************************************************/ |
| 12 | 13 | |
| r8614 | r8615 | |
| 15 | 16 | #include "sound/sn76496.h" |
| 16 | 17 | #include "devices/cartslot.h" |
| 17 | 18 | |
| 19 | static UINT8 vram_read_bank,vram_write_bank,pal_reg[7],pri_mask; |
| 20 | |
| 18 | 21 | static VIDEO_START( rx78 ) |
| 19 | 22 | { |
| 20 | 23 | } |
| 21 | 24 | |
| 22 | 25 | static VIDEO_UPDATE( rx78 ) |
| 23 | 26 | { |
| 24 | | UINT8 y,ra,chr,gfx; |
| 25 | | UINT16 sy=0,ma=0xe8be,x; |
| 26 | | UINT8 *RAM = memory_region(screen->machine, "maincpu"); |
| 27 | static UINT8 *vram = memory_region(screen->machine,"vram"); |
| 28 | int x,y,count; |
| 27 | 29 | |
| 28 | | /* TODO: screw this up */ |
| 29 | | for (y = 0; y < 23; y++) |
| 30 | bitmap_fill(bitmap, cliprect, screen->machine->pens[0x10]); |
| 31 | |
| 32 | count = 0x2c0; //first 0x2bf bytes aren't used for bitmap drawing apparently |
| 33 | |
| 34 | for(y=0;y<184;y++) |
| 30 | 35 | { |
| 31 | | for (ra = 0; ra < 8; ra++) |
| 36 | for(x=0;x<192;x+=8) |
| 32 | 37 | { |
| 33 | | UINT16 *p = BITMAP_ADDR16(bitmap, sy++, 0); |
| 38 | int color,pen[3],i; |
| 34 | 39 | |
| 35 | | for (x = ma; x < ma+30; x++) |
| 40 | for (i = 0; i < 8; i++) |
| 36 | 41 | { |
| 37 | | chr = RAM[x]; |
| 42 | /* bg color */ |
| 43 | pen[0] = (pri_mask & 0x08) ? (vram[count + 0x6000] >> (i)) : 0x00; |
| 44 | pen[1] = (pri_mask & 0x10) ? (vram[count + 0x8000] >> (i)) : 0x00; |
| 45 | pen[2] = (pri_mask & 0x20) ? (vram[count + 0xa000] >> (i)) : 0x00; |
| 38 | 46 | |
| 39 | | /* get pattern of pixels for that character scanline */ |
| 40 | | gfx = RAM[0x1a27 + (chr<<3) + ra]; |
| 47 | color = ((pen[0] & 1) << 0); |
| 48 | color |= ((pen[1] & 1) << 1); |
| 49 | color |= ((pen[2] & 1) << 2); |
| 41 | 50 | |
| 42 | | /* Display a scanline of a character (8 pixels) */ |
| 43 | | *p = ( gfx & 0x01 ) ? 1 : 0; p++; |
| 44 | | *p = ( gfx & 0x02 ) ? 1 : 0; p++; |
| 45 | | *p = ( gfx & 0x04 ) ? 1 : 0; p++; |
| 46 | | *p = ( gfx & 0x08 ) ? 1 : 0; p++; |
| 47 | | *p = ( gfx & 0x10 ) ? 1 : 0; p++; |
| 48 | | *p = ( gfx & 0x20 ) ? 1 : 0; p++; |
| 49 | | *p = ( gfx & 0x40 ) ? 1 : 0; p++; |
| 50 | | *p = ( gfx & 0x80 ) ? 1 : 0; p++; |
| 51 | if(color) |
| 52 | *BITMAP_ADDR16(bitmap, y, x+i) = screen->machine->pens[color]; |
| 53 | |
| 54 | /* fg color */ |
| 55 | pen[0] = (pri_mask & 0x01) ? (vram[count + 0x0000] >> (i)) : 0x00; |
| 56 | pen[1] = (pri_mask & 0x02) ? (vram[count + 0x2000] >> (i)) : 0x00; |
| 57 | pen[2] = (pri_mask & 0x04) ? (vram[count + 0x4000] >> (i)) : 0x00; |
| 58 | |
| 59 | color = ((pen[0] & 1) << 0); |
| 60 | color |= ((pen[1] & 1) << 1); |
| 61 | color |= ((pen[2] & 1) << 2); |
| 62 | |
| 63 | if(color) |
| 64 | *BITMAP_ADDR16(bitmap, y, x+i) = screen->machine->pens[color]; |
| 51 | 65 | } |
| 66 | count++; |
| 52 | 67 | } |
| 53 | | ma+=30; |
| 54 | 68 | } |
| 69 | |
| 55 | 70 | return 0; |
| 56 | 71 | } |
| 57 | 72 | |
| r8614 | r8615 | |
| 86 | 101 | key_mux = data; |
| 87 | 102 | } |
| 88 | 103 | |
| 104 | static READ8_HANDLER( rx78_vram_r ) |
| 105 | { |
| 106 | static UINT8 *vram = memory_region(space->machine,"vram"); |
| 89 | 107 | |
| 108 | if(vram_read_bank == 0 || vram_read_bank > 6) |
| 109 | return 0xff; |
| 110 | |
| 111 | return vram[offset + ((vram_read_bank - 1) * 0x2000)]; |
| 112 | } |
| 113 | |
| 114 | static WRITE8_HANDLER( rx78_vram_w ) |
| 115 | { |
| 116 | static UINT8 *vram = memory_region(space->machine,"vram"); |
| 117 | |
| 118 | if(vram_write_bank & 0x01) { vram[offset + 0 * 0x2000] = data; } |
| 119 | if(vram_write_bank & 0x02) { vram[offset + 1 * 0x2000] = data; } |
| 120 | if(vram_write_bank & 0x04) { vram[offset + 2 * 0x2000] = data; } |
| 121 | if(vram_write_bank & 0x08) { vram[offset + 3 * 0x2000] = data; } |
| 122 | if(vram_write_bank & 0x10) { vram[offset + 4 * 0x2000] = data; } |
| 123 | if(vram_write_bank & 0x20) { vram[offset + 5 * 0x2000] = data; } |
| 124 | } |
| 125 | |
| 126 | static WRITE8_HANDLER( vram_read_bank_w ) |
| 127 | { |
| 128 | vram_read_bank = data; |
| 129 | } |
| 130 | |
| 131 | static WRITE8_HANDLER( vram_write_bank_w ) |
| 132 | { |
| 133 | vram_write_bank = data; |
| 134 | } |
| 135 | |
| 136 | static WRITE8_HANDLER( vdp_reg_w ) |
| 137 | { |
| 138 | UINT8 r,g,b,res,i; |
| 139 | |
| 140 | pal_reg[offset] = data; |
| 141 | |
| 142 | for(i=0;i<16;i++) |
| 143 | { |
| 144 | res = ((i & 1) ? pal_reg[0 + (i & 8 ? 3 : 0)] : 0) | ((i & 2) ? pal_reg[1 + (i & 8 ? 3 : 0)] : 0) | ((i & 4) ? pal_reg[2 + (i & 8 ? 3 : 0)] : 0); |
| 145 | if(res & pal_reg[6]) //color mask, TODO: check this |
| 146 | res &= pal_reg[6]; |
| 147 | |
| 148 | r = (res & 0x11) == 0x11 ? 0xff : ((res & 0x11) == 0x01 ? 0x7f : 0x00); |
| 149 | g = (res & 0x22) == 0x22 ? 0xff : ((res & 0x22) == 0x02 ? 0x7f : 0x00); |
| 150 | b = (res & 0x44) == 0x44 ? 0xff : ((res & 0x44) == 0x04 ? 0x7f : 0x00); |
| 151 | |
| 152 | palette_set_color(space->machine, i, MAKE_RGB(r,g,b)); |
| 153 | } |
| 154 | } |
| 155 | |
| 156 | static WRITE8_HANDLER( vdp_bg_reg_w ) |
| 157 | { |
| 158 | int r,g,b; |
| 159 | |
| 160 | r = (data & 0x11) == 0x11 ? 0xff : ((data & 0x11) == 0x01 ? 0x7f : 0x00); |
| 161 | g = (data & 0x22) == 0x22 ? 0xff : ((data & 0x22) == 0x02 ? 0x7f : 0x00); |
| 162 | b = (data & 0x44) == 0x44 ? 0xff : ((data & 0x44) == 0x04 ? 0x7f : 0x00); |
| 163 | |
| 164 | palette_set_color(space->machine, 0x10, MAKE_RGB(r,g,b)); |
| 165 | } |
| 166 | |
| 167 | static WRITE8_HANDLER( vdp_pri_mask_w ) |
| 168 | { |
| 169 | pri_mask = data; |
| 170 | } |
| 171 | |
| 90 | 172 | static ADDRESS_MAP_START(rx78_mem, ADDRESS_SPACE_PROGRAM, 8) |
| 91 | 173 | ADDRESS_MAP_UNMAP_HIGH |
| 92 | 174 | AM_RANGE(0x0000, 0x1fff) AM_ROM |
| 93 | 175 | AM_RANGE(0x2000, 0x5fff) AM_ROM AM_REGION("cart_img", 0x0000) |
| 94 | | AM_RANGE(0x6000, 0xffff) AM_RAM AM_REGION("maincpu", 0x6000) |
| 95 | | /* |
| 96 | | base memory map: |
| 97 | | AM_RANGE(0x0000, 0x1fff) AM_ROM |
| 98 | | AM_RANGE(0x2000, 0x5fff) AM_ROM //cart |
| 99 | | AM_RANGE(0x6000, 0xafff) AM_RAM //ext ram |
| 100 | | AM_RANGE(0xb000, 0xebff) AM_RAM //work ram |
| 101 | | AM_RANGE(0xec00, 0xffff) AM_RAM //bitmap vram (banked) |
| 102 | | */ |
| 176 | AM_RANGE(0x6000, 0xafff) AM_RAM //ext RAM |
| 177 | AM_RANGE(0xb000, 0xebff) AM_RAM |
| 178 | AM_RANGE(0xec00, 0xffff) AM_READWRITE(rx78_vram_r, rx78_vram_w) |
| 103 | 179 | ADDRESS_MAP_END |
| 104 | 180 | |
| 105 | 181 | static ADDRESS_MAP_START( rx78_io , ADDRESS_SPACE_IO, 8) |
| r8614 | r8615 | |
| 108 | 184 | // AM_RANGE(0xe2, 0xe2) AM_READNOP AM_WRITENOP //printer |
| 109 | 185 | // AM_RANGE(0xe3, 0xe3) AM_WRITENOP //printer |
| 110 | 186 | // AM_RANGE(0xf0, 0xf0) AM_NOP //cmt |
| 111 | | // AM_RANGE(0xf1, 0xf2) AM_WRITENOP //memory banking |
| 187 | AM_RANGE(0xf1, 0xf1) AM_WRITE(vram_read_bank_w) |
| 188 | AM_RANGE(0xf2, 0xf2) AM_WRITE(vram_write_bank_w) |
| 112 | 189 | AM_RANGE(0xf4, 0xf4) AM_READWRITE(key_r,key_w) //keyboard |
| 113 | | // AM_RANGE(0xf5, 0xfc) AM_WRITENOP //vdp |
| 114 | | // AM_RANGE(0xfe, 0xfe) AM_WRITENOP //vdp pmask |
| 190 | AM_RANGE(0xf5, 0xfb) AM_WRITE(vdp_reg_w) //vdp |
| 191 | AM_RANGE(0xfc, 0xfc) AM_WRITE(vdp_bg_reg_w) //vdp |
| 192 | AM_RANGE(0xfe, 0xfe) AM_WRITE(vdp_pri_mask_w) |
| 115 | 193 | AM_RANGE(0xff, 0xff) AM_DEVWRITE("sn1",sn76496_w) //psg |
| 116 | 194 | ADDRESS_MAP_END |
| 117 | 195 | |
| r8614 | r8615 | |
| 172 | 250 | PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') |
| 173 | 251 | PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') |
| 174 | 252 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("[") PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') |
| 175 | | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("\\") PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') |
| 253 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("\\") PORT_CODE(KEYCODE_BACKSLASH) |
| 176 | 254 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("]") PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') |
| 177 | | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Arrow Up") //??? |
| 178 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Backspace") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) |
| 255 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Up Down Arrow") //??? |
| 256 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Right Left Arrow") //??? |
| 179 | 257 | |
| 180 | 258 | PORT_START("KEY6") |
| 181 | 259 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') |
| r8614 | r8615 | |
| 185 | 263 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT) |
| 186 | 264 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("HOME") PORT_CODE(KEYCODE_HOME) |
| 187 | 265 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_UNUSED ) |
| 188 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("<unknown>") //clear screen? |
| 266 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("INST / DEL") PORT_CODE(KEYCODE_BACKSPACE) |
| 189 | 267 | |
| 190 | 268 | PORT_START("KEY7") |
| 191 | 269 | PORT_BIT(0x07,IP_ACTIVE_HIGH,IPT_UNUSED ) |
| 192 | | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("<unknown>") //0x08, goes to new line |
| 270 | PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("STOP") |
| 193 | 271 | PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_UNUSED ) |
| 194 | 272 | PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("RETURN") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(27) |
| 195 | 273 | PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_UNUSED ) |
| 196 | | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("<unknown>") //0x14, cursor change |
| 274 | PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("SHIFT LOCK") PORT_CODE(KEYCODE_CAPSLOCK) PORT_TOGGLE |
| 197 | 275 | |
| 198 | 276 | PORT_START("KEY8") |
| 199 | 277 | PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) //kana shift? |
| r8614 | r8615 | |
| 254 | 332 | MDRV_SCREEN_REFRESH_RATE(50) |
| 255 | 333 | MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| 256 | 334 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 257 | | MDRV_SCREEN_SIZE(240, 184) |
| 258 | | MDRV_SCREEN_VISIBLE_AREA(0, 240-1, 0, 184-1) |
| 259 | | MDRV_PALETTE_LENGTH(2) |
| 260 | | MDRV_PALETTE_INIT(black_and_white) |
| 335 | MDRV_SCREEN_SIZE(192, 184) |
| 336 | MDRV_SCREEN_VISIBLE_AREA(0, 192-1, 0, 184-1) |
| 337 | MDRV_PALETTE_LENGTH(16+1) //+1 for the background color |
| 338 | // MDRV_PALETTE_INIT(black_and_white) |
| 261 | 339 | MDRV_GFXDECODE(rx78) |
| 262 | 340 | |
| 263 | 341 | MDRV_VIDEO_START(rx78) |
| r8614 | r8615 | |
| 269 | 347 | |
| 270 | 348 | MDRV_SPEAKER_STANDARD_MONO("mono") |
| 271 | 349 | |
| 272 | | MDRV_SOUND_ADD("sn1", SN76489A, 1996800) // unknown clock / divider |
| 350 | MDRV_SOUND_ADD("sn1", SN76489A, 3579545) // unknown divider |
| 273 | 351 | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) |
| 274 | 352 | MACHINE_DRIVER_END |
| 275 | 353 | |
| r8614 | r8615 | |
| 280 | 358 | |
| 281 | 359 | ROM_REGION( 0x4000, "cart_img", ROMREGION_ERASEFF ) |
| 282 | 360 | ROM_CART_LOAD("cart", 0x0000, 0x4000, ROM_OPTIONAL | ROM_NOMIRROR) |
| 361 | |
| 362 | ROM_REGION( 6 * 0x2000, "vram", ROMREGION_ERASE00 ) |
| 283 | 363 | ROM_END |
| 284 | 364 | |
| 285 | 365 | /* Driver */ |