trunk/src/mess/drivers/fp200.c
| r21860 | r21861 | |
| 1 | 1 | /*************************************************************************** |
| 2 | 2 | |
| 3 | | Casio FP-200 driver |
| 3 | Casio FP-200 driver |
| 4 | 4 | |
| 5 | |
| 6 | TODO: |
| 7 | - What's the LCDC type? Custom? |
| 8 | |
| 5 | 9 | ***************************************************************************/ |
| 6 | 10 | |
| 7 | 11 | |
| r21860 | r21861 | |
| 21 | 25 | // devices |
| 22 | 26 | required_device<cpu_device> m_maincpu; |
| 23 | 27 | UINT8 m_io_type; |
| 28 | UINT8 *m_chargen; |
| 24 | 29 | |
| 30 | struct{ |
| 31 | UINT8 x; |
| 32 | UINT8 y; |
| 33 | UINT8 status; |
| 34 | UINT8 *vram; |
| 35 | UINT8 *attr; |
| 36 | }m_lcd; |
| 37 | void write_lcd_attr(UINT16 X, UINT16 Y,UINT8 data); |
| 38 | void write_lcd_vram(UINT16 X, UINT16 Y,UINT8 data); |
| 39 | |
| 25 | 40 | // screen updates |
| 26 | 41 | UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 27 | 42 | |
| 28 | 43 | DECLARE_READ8_MEMBER(fp200_io_r); |
| 29 | 44 | DECLARE_WRITE8_MEMBER(fp200_io_w); |
| 45 | DECLARE_READ8_MEMBER(fp200_lcd_r); |
| 46 | DECLARE_WRITE8_MEMBER(fp200_lcd_w); |
| 47 | |
| 30 | 48 | DECLARE_WRITE_LINE_MEMBER(sod_w); |
| 31 | 49 | DECLARE_READ_LINE_MEMBER(sid_r); |
| 32 | 50 | |
| r21860 | r21861 | |
| 41 | 59 | |
| 42 | 60 | void fp200_state::video_start() |
| 43 | 61 | { |
| 62 | m_lcd.vram = auto_alloc_array_clear(machine(), UINT8, 20*64); |
| 63 | m_lcd.attr = auto_alloc_array_clear(machine(), UINT8, 20*64); |
| 44 | 64 | } |
| 45 | 65 | |
| 46 | 66 | UINT32 fp200_state::screen_update( screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect ) |
| 47 | 67 | { |
| 68 | for(int y=cliprect.min_y;y<cliprect.max_y;y++) |
| 69 | { |
| 70 | for(int x=cliprect.min_x;x<cliprect.max_x;x++) |
| 71 | { |
| 72 | if(m_lcd.attr[x/8+y*20] == 0x60) |
| 73 | { |
| 74 | UINT8 vram,pix; |
| 75 | |
| 76 | vram = m_lcd.vram[x/8+y*20]; |
| 77 | pix = ((m_chargen[vram*8+(x & 7)]) >> (7-(y & 7))) & 1; |
| 78 | bitmap.pix16(y,x) = pix; |
| 79 | } |
| 80 | } |
| 81 | } |
| 82 | |
| 48 | 83 | return 0; |
| 49 | 84 | } |
| 50 | 85 | |
| 86 | |
| 51 | 87 | /* |
| 52 | | i/o map: |
| 88 | [8] SSSS --YY Status code (?) / upper part of Y address |
| 89 | [9] YYYY XXXX lower part of Y address / X address |
| 90 | */ |
| 91 | READ8_MEMBER(fp200_state::fp200_lcd_r) |
| 92 | { |
| 93 | UINT8 res; |
| 94 | |
| 95 | res = 0; |
| 96 | |
| 97 | switch(offset) |
| 98 | { |
| 99 | case 1: |
| 100 | printf("%d %d -> (L)\n",m_lcd.x,m_lcd.y); |
| 101 | break; |
| 102 | case 2: |
| 103 | printf("%d %d -> (R)\n",m_lcd.x,m_lcd.y); |
| 104 | break; |
| 105 | case 8: |
| 106 | res = (m_lcd.status & 0xf) << 4; |
| 107 | res |= (m_lcd.y & 0x30) >> 4; |
| 108 | break; |
| 109 | case 9: |
| 110 | res = (m_lcd.y & 0xf) << 4; |
| 111 | res |= (m_lcd.x & 0xf); |
| 112 | break; |
| 113 | } |
| 114 | |
| 115 | |
| 116 | return res; |
| 117 | } |
| 118 | |
| 119 | void fp200_state::write_lcd_attr(UINT16 X, UINT16 Y,UINT8 data) |
| 120 | { |
| 121 | UINT16 base_offs; |
| 122 | |
| 123 | for(int yi=0;yi<8;yi++) |
| 124 | { |
| 125 | base_offs = X+(Y+yi)*20; |
| 126 | |
| 127 | if(base_offs >= 20*64) |
| 128 | return; |
| 129 | |
| 130 | m_lcd.attr[base_offs] = data; |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | void fp200_state::write_lcd_vram(UINT16 X, UINT16 Y,UINT8 data) |
| 135 | { |
| 136 | UINT16 base_offs; |
| 137 | |
| 138 | for(int yi=0;yi<8;yi++) |
| 139 | { |
| 140 | base_offs = X+(Y+yi)*20; |
| 141 | |
| 142 | if(base_offs >= 20*64) |
| 143 | return; |
| 144 | |
| 145 | m_lcd.vram[base_offs] = data; |
| 146 | } |
| 147 | } |
| 148 | |
| 149 | WRITE8_MEMBER(fp200_state::fp200_lcd_w) |
| 150 | { |
| 151 | switch(offset) |
| 152 | { |
| 153 | case 1: |
| 154 | printf("%d %d -> %02x (%c) (L %02x)\n",m_lcd.x,m_lcd.y,data,data,m_lcd.status); |
| 155 | if(m_lcd.status == 0xb) |
| 156 | write_lcd_attr(m_lcd.x,m_lcd.y,data); |
| 157 | else if(m_lcd.status == 1) |
| 158 | write_lcd_vram(m_lcd.x,m_lcd.y,data); |
| 159 | break; |
| 160 | case 2: |
| 161 | printf("%d %d -> %02x (%c) (R %02x)\n",m_lcd.x + 10,m_lcd.y,data,data,m_lcd.status); |
| 162 | if(m_lcd.status == 0xb) |
| 163 | write_lcd_attr(m_lcd.x + 10,m_lcd.y,data); |
| 164 | else if(m_lcd.status == 1) |
| 165 | write_lcd_vram(m_lcd.x + 10,m_lcd.y,data); |
| 166 | break; |
| 167 | case 8: |
| 168 | m_lcd.status = (data & 0xf0) >> 4; |
| 169 | if(m_lcd.status == 0x0b) |
| 170 | m_lcd.y = (m_lcd.y & 0xf) | ((data & 3) << 4); |
| 171 | break; |
| 172 | case 9: |
| 173 | m_lcd.y = (m_lcd.y & 0x30) | ((data & 0xf0) >> 4); |
| 174 | m_lcd.x = data & 0xf; |
| 175 | break; |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | |
| 180 | /* |
| 181 | Annoyingly the i/o map uses the SOD to access different devices, so we need trampolines. |
| 53 | 182 | SOD = 0 |
| 54 | 183 | 0x10 - 0x1f Timer control (RPC05 RTC) |
| 55 | 184 | 0x20 - 0x2f AUTO-POWER OFF |
| r21860 | r21861 | |
| 62 | 191 | 0x40 - 0x4f MT.RS-232C control |
| 63 | 192 | 0x80 - 0x8f Printer (Centronics) |
| 64 | 193 | */ |
| 65 | | |
| 66 | 194 | READ8_MEMBER(fp200_state::fp200_io_r) |
| 67 | 195 | { |
| 68 | 196 | UINT8 res; |
| 69 | | logerror("Unemulated I/O read %02x (%02x)\n",offset,m_io_type); |
| 70 | 197 | |
| 71 | 198 | if(m_io_type == 0) |
| 72 | 199 | { |
| 73 | 200 | res = 0; |
| 201 | logerror("Unemulated I/O read %02x (%02x)\n",offset,m_io_type); |
| 74 | 202 | } |
| 75 | 203 | else |
| 76 | 204 | { |
| 77 | | res = 0; |
| 205 | switch(offset & 0xf0) |
| 206 | { |
| 207 | //case 0x00: return; |
| 208 | case 0x00: res = fp200_lcd_r(space, offset & 0xf); break; |
| 209 | default: res = 0; logerror("Unemulated I/O read %02x (%02x)\n",offset,m_io_type); break; |
| 210 | } |
| 78 | 211 | } |
| 79 | 212 | |
| 80 | 213 | return res; |
| r21860 | r21861 | |
| 82 | 215 | |
| 83 | 216 | WRITE8_MEMBER(fp200_state::fp200_io_w) |
| 84 | 217 | { |
| 85 | | logerror("Unemulated I/O write %02x (%02x) -> %02x\n",offset,m_io_type,data); |
| 86 | 218 | if(m_io_type == 0) |
| 87 | 219 | { |
| 88 | | // .... |
| 220 | switch(offset & 0xf0) |
| 221 | { |
| 222 | default:logerror("Unemulated I/O write %02x (%02x) <- %02x\n",offset,m_io_type,data); break; |
| 223 | } |
| 89 | 224 | } |
| 90 | 225 | else |
| 91 | 226 | { |
| 92 | | // ... |
| 227 | switch(offset & 0xf0) |
| 228 | { |
| 229 | case 0x00: fp200_lcd_w(space, offset & 0xf,data); break; |
| 230 | default:logerror("Unemulated I/O write %02x (%02x) <- %02x\n",offset,m_io_type,data); break; |
| 231 | } |
| 93 | 232 | } |
| 94 | 233 | } |
| 95 | 234 | |
| r21860 | r21861 | |
| 171 | 310 | }; |
| 172 | 311 | |
| 173 | 312 | static GFXDECODE_START( fp200 ) |
| 174 | | GFXDECODE_ENTRY( "gfx1", 0, charlayout, 0, 1 ) |
| 313 | GFXDECODE_ENTRY( "chargen", 0, charlayout, 0, 1 ) |
| 175 | 314 | GFXDECODE_END |
| 176 | 315 | |
| 177 | 316 | |
| 178 | 317 | void fp200_state::machine_start() |
| 179 | 318 | { |
| 319 | UINT8 *raw_gfx = machine().root_device().memregion("raw_gfx")->base(); |
| 320 | m_chargen = memregion("chargen")->base(); |
| 321 | |
| 322 | for(int i=0;i<0x800;i++) |
| 323 | { |
| 324 | m_chargen[i] = raw_gfx[BITSWAP16(i,15,14,13,12,11,6,5,4,3,10,9,8,7,2,1,0)]; |
| 325 | } |
| 180 | 326 | } |
| 181 | 327 | |
| 182 | 328 | void fp200_state::machine_reset() |
| r21860 | r21861 | |
| 186 | 332 | |
| 187 | 333 | void fp200_state::palette_init() |
| 188 | 334 | { |
| 335 | palette_set_color_rgb(machine(), 0, 0xa0, 0xa8, 0xa0); |
| 336 | palette_set_color_rgb(machine(), 1, 0x30, 0x38, 0x10); |
| 189 | 337 | } |
| 190 | 338 | |
| 191 | 339 | WRITE_LINE_MEMBER( fp200_state::sod_w ) |
| r21860 | r21861 | |
| 225 | 373 | |
| 226 | 374 | MCFG_GFXDECODE(fp200) |
| 227 | 375 | |
| 228 | | MCFG_PALETTE_LENGTH(8) |
| 376 | MCFG_PALETTE_LENGTH(2) |
| 229 | 377 | |
| 230 | 378 | /* sound hardware */ |
| 231 | 379 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| r21860 | r21861 | |
| 244 | 392 | ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASE00 ) |
| 245 | 393 | ROM_LOAD( "fp200rom.bin", 0x0000, 0x8000, CRC(dba6e41b) SHA1(c694fa19172eb56585a9503997655bcf9d369c34) ) |
| 246 | 394 | |
| 247 | | ROM_REGION( 0x10000, "gfx1", ROMREGION_ERASE00 ) |
| 395 | ROM_REGION( 0x800, "raw_gfx", ROMREGION_ERASE00 ) |
| 248 | 396 | ROM_LOAD( "chr.bin", 0x0000, 0x800, CRC(2e6501a5) SHA1(6186e25feabe6db851ee7d61dad11e182a6d3a4a) ) |
| 397 | |
| 398 | ROM_REGION( 0x800, "chargen", ROMREGION_ERASE00 ) |
| 249 | 399 | ROM_END |
| 250 | 400 | |
| 251 | 401 | GAME( 1982, fp200, 0, fp200, fp200, driver_device, 0, ROT0, "Casio", "FP-200", GAME_IS_SKELETON ) |