src/mess/video/hd44780.c
| r9538 | r9539 | |
| 7 | 7 | - 5x10 chars |
| 8 | 8 | - dump internal CGROM |
| 9 | 9 | |
| 10 | HACKS: |
| 11 | - A00 10 bit chars are tacked onto recreated chrrom at $700 (until internal rom is dumped) |
| 12 | - A00/A02 drawing selected by sizeof romfile, A02 is $800, A00 is $860 |
| 13 | |
| 10 | 14 | ***************************************************************************/ |
| 11 | 15 | |
| 12 | 16 | #include "emu.h" |
| 13 | 17 | #include "video/hd44780.h" |
| 14 | 18 | |
| 15 | | |
| 16 | 19 | //************************************************************************** |
| 17 | 20 | // device configuration |
| 18 | 21 | //************************************************************************** |
| r9538 | r9539 | |
| 26 | 29 | { |
| 27 | 30 | } |
| 28 | 31 | |
| 29 | | |
| 30 | 32 | //------------------------------------------------- |
| 31 | 33 | // static_alloc_device_config - allocate a new |
| 32 | 34 | // configuration object |
| r9538 | r9539 | |
| 130 | 132 | state_save_register_device_item( this, 0, blink); |
| 131 | 133 | state_save_register_device_item_array( this, 0, ddram); |
| 132 | 134 | state_save_register_device_item_array( this, 0, cgram); |
| 135 | |
| 133 | 136 | } |
| 134 | 137 | |
| 135 | 138 | |
| r9538 | r9539 | |
| 141 | 144 | { |
| 142 | 145 | busy_flag = 0; |
| 143 | 146 | |
| 144 | | memset(ddram, 0, ARRAY_LENGTH(ddram)); |
| 147 | memset(ddram, 0x20, ARRAY_LENGTH(ddram)); // can't use 0 here as it would show CGRAM instead of blank space on a soft reset |
| 145 | 148 | memset(cgram, 0, ARRAY_LENGTH(cgram)); |
| 146 | 149 | ac = 0; |
| 147 | 150 | ac_mode = 0; |
| r9538 | r9539 | |
| 152 | 155 | shift_on = 0; |
| 153 | 156 | blink_on = 0; |
| 154 | 157 | direction = 1; |
| 155 | | data_len = 1; |
| 158 | data_len = -1; // must not be 0 or 1 on intial start to pick up first 4/8 bit mode change |
| 156 | 159 | n_line = 0; |
| 157 | 160 | char_size = 0; |
| 158 | 161 | disp_shift = 0; |
| r9538 | r9539 | |
| 237 | 240 | char_pos -= line_size; |
| 238 | 241 | } |
| 239 | 242 | } |
| 240 | | |
| 241 | 243 | for (int y=0; y<8; y++) |
| 242 | 244 | for (int x=0; x<5; x++) |
| 243 | 245 | if (ddram[char_pos] <= 0x10) |
| r9538 | r9539 | |
| 248 | 250 | else |
| 249 | 251 | { |
| 250 | 252 | //draw CGROM characters |
| 251 | | *BITMAP_ADDR16(bitmap, l*9 + y, i*6 + x) = BIT(region()->u8(ddram[char_pos]*8+y), 4-x); |
| 253 | if (region()->bytes() <= 0x800) { |
| 254 | *BITMAP_ADDR16(bitmap, l*9 + y, i*6 + x) = BIT(region()->u8(ddram[char_pos]*8+y), 4-x); |
| 255 | } else { |
| 256 | if(ddram[char_pos] < 0xe0) { |
| 257 | *BITMAP_ADDR16(bitmap, l*9 + y, i*6 + x) = BIT(region()->u8(ddram[char_pos]*8+y), 4-x); |
| 258 | } else { |
| 259 | *BITMAP_ADDR16(bitmap, l*9 + y, i*6 + x) = BIT(region()->u8(0x700+((ddram[char_pos]-0xe0)*11)+y), 4-x); |
| 260 | } |
| 261 | } |
| 252 | 262 | } |
| 253 | 263 | |
| 254 | 264 | // if is the correct position draw cursor and blink |
| r9538 | r9539 | |
| 272 | 282 | |
| 273 | 283 | void hd44780_device::control_write(offs_t offset, UINT8 data) |
| 274 | 284 | { |
| 275 | | if (BIT(data, 7)) |
| 285 | if (BIT(data, 7)) // Set DDRAM Address |
| 276 | 286 | { |
| 277 | 287 | ac_mode = 0; |
| 278 | 288 | ac = data & 0x7f; |
| 279 | | if (data != 0x81) |
| 289 | if (data != 0x81) // not in datasheet spec |
| 280 | 290 | cursor_pos = ac; |
| 281 | 291 | set_busy_flag(37); |
| 282 | 292 | } |
| 283 | | else if (BIT(data, 6)) |
| 293 | else if (BIT(data, 6)) // Set CGRAM Address |
| 284 | 294 | { |
| 285 | 295 | ac_mode = 1; |
| 286 | 296 | ac = data & 0x3f; |
| 287 | 297 | set_busy_flag(37); |
| 288 | 298 | } |
| 289 | | else if (BIT(data, 5)) |
| 299 | else if (BIT(data, 5)) // Function Set |
| 290 | 300 | { |
| 301 | // datasheet says you can't change char size after first function set without altering 4/8 bit mode |
| 302 | if (BIT(data, 4) != data_len) { |
| 303 | char_size = BIT(data, 2); |
| 304 | } |
| 291 | 305 | data_len = BIT(data, 4); |
| 292 | 306 | n_line = BIT(data, 3); |
| 293 | | char_size = BIT(data, 2); |
| 294 | 307 | set_busy_flag(37); |
| 295 | 308 | } |
| 296 | | else if (BIT(data, 4)) |
| 309 | else if (BIT(data, 4)) // Cursor or display shift |
| 297 | 310 | { |
| 298 | 311 | UINT8 direct = (BIT(data, 2)) ? +1 : -1; |
| 299 | 312 | |
| r9538 | r9539 | |
| 307 | 320 | |
| 308 | 321 | set_busy_flag(37); |
| 309 | 322 | } |
| 310 | | else if (BIT(data, 3)) |
| 323 | else if (BIT(data, 3)) // Display on/off Control |
| 311 | 324 | { |
| 312 | 325 | display_on = BIT(data, 2); |
| 313 | 326 | cursor_on = BIT(data, 1); |
| r9538 | r9539 | |
| 315 | 328 | |
| 316 | 329 | set_busy_flag(37); |
| 317 | 330 | } |
| 318 | | else if (BIT(data, 2)) |
| 331 | else if (BIT(data, 2)) // Entry Mode set |
| 319 | 332 | { |
| 320 | 333 | direction = (BIT(data, 1)) ? +1 : -1; |
| 321 | 334 | |
| r9538 | r9539 | |
| 323 | 336 | |
| 324 | 337 | set_busy_flag(37); |
| 325 | 338 | } |
| 326 | | else if (BIT(data, 1)) |
| 339 | else if (BIT(data, 1)) // return home |
| 327 | 340 | { |
| 328 | 341 | ac = 0; |
| 329 | 342 | cursor_pos = 0; |
| 330 | | ac_mode = 0; |
| 343 | ac_mode = 0; // datasheet does not specifically say this but mephisto won't run without it |
| 331 | 344 | direction = 1; |
| 332 | 345 | disp_shift = 0; |
| 333 | 346 | set_busy_flag(1520); |
| 334 | 347 | } |
| 335 | | else if (BIT(data, 0)) |
| 348 | else if (BIT(data, 0)) // clear display |
| 336 | 349 | { |
| 337 | 350 | ac = 0; |
| 338 | 351 | cursor_pos = 0; |
| r9538 | r9539 | |
| 340 | 353 | direction = 1; |
| 341 | 354 | disp_shift = 0; |
| 342 | 355 | memset(ddram, 0x20, ARRAY_LENGTH(ddram)); |
| 343 | | memset(cgram, 0x20, ARRAY_LENGTH(cgram)); |
| 356 | // nothing in datasheet says to clear CGRAM |
| 357 | // memset(cgram, 0x20, ARRAY_LENGTH(cgram)); |
| 344 | 358 | set_busy_flag(1520); |
| 345 | 359 | } |
| 346 | 360 | } |
| r9538 | r9539 | |
| 352 | 366 | |
| 353 | 367 | void hd44780_device::data_write(offs_t offset, UINT8 data) |
| 354 | 368 | { |
| 369 | static int lastac = 0; |
| 370 | if (lastac != ac_mode) { |
| 371 | lastac = ac_mode; |
| 372 | } |
| 373 | |
| 355 | 374 | if (ac_mode == 0) |
| 356 | 375 | ddram[ac] = data; |
| 357 | | else |
| 376 | else { |
| 358 | 377 | cgram[ac] = data; |
| 359 | | |
| 378 | } |
| 360 | 379 | data_bus_flag = 1; |
| 361 | 380 | |
| 362 | 381 | set_busy_flag(41); |
| r9538 | r9539 | |
| 368 | 387 | |
| 369 | 388 | if (ac_mode == 0) |
| 370 | 389 | data = ddram[ac]; |
| 371 | | else |
| 390 | else { |
| 372 | 391 | data = cgram[ac]; |
| 392 | } |
| 373 | 393 | |
| 374 | 394 | data_bus_flag = 2; |
| 375 | 395 | |