trunk/src/lib/formats/m20_dsk.c
| r0 | r19121 | |
| 1 | /********************************************************************* |
| 2 | |
| 3 | formats/m20_dsk.c |
| 4 | |
| 5 | Olivetti M20 floppy-disk images |
| 6 | |
| 7 | Track 0/head 0 is FM, 128 byte sectors. The rest is MFM, |
| 8 | 256 byte sectors. |
| 9 | In image files the sectors of track 0/sector 0 are 256 bytes |
| 10 | long to simplify access. Only the first half of these sectors |
| 11 | contain image data. |
| 12 | |
| 13 | *********************************************************************/ |
| 14 | |
| 15 | #include <string.h> |
| 16 | |
| 17 | #include "m20_dsk.h" |
| 18 | #include "basicdsk.h" |
| 19 | |
| 20 | static FLOPPY_IDENTIFY(m20_dsk_identify) |
| 21 | { |
| 22 | *vote = (floppy_image_size(floppy) == 286720) ? 100 : 0; |
| 23 | return FLOPPY_ERROR_SUCCESS; |
| 24 | } |
| 25 | |
| 26 | static int m20_get_heads_per_disk(floppy_image_legacy *floppy) |
| 27 | { |
| 28 | return 2; |
| 29 | } |
| 30 | |
| 31 | static int m20_get_tracks_per_disk(floppy_image_legacy *floppy) |
| 32 | { |
| 33 | return 35; |
| 34 | } |
| 35 | |
| 36 | static UINT64 m20_translate_offset(floppy_image_legacy *floppy, int track, int head, int sector) |
| 37 | { |
| 38 | return 256*(32*track+16*head+sector); |
| 39 | } |
| 40 | |
| 41 | static floperr_t get_offset(floppy_image_legacy *floppy, int head, int track, int sector, int sector_is_index, UINT64 *offset) |
| 42 | { |
| 43 | UINT64 offs; |
| 44 | /* translate the sector to a raw sector */ |
| 45 | if (!sector_is_index) |
| 46 | { |
| 47 | sector -= 1; |
| 48 | } |
| 49 | |
| 50 | /* check to see if we are out of range */ |
| 51 | if ((head < 0) || (head >= 2) || (track < 0) || (track >= 35) || (sector < 0) || (sector >= 16)) |
| 52 | return FLOPPY_ERROR_SEEKERROR; |
| 53 | |
| 54 | offs = m20_translate_offset(floppy, track, head, sector); |
| 55 | if (offset) |
| 56 | *offset = offs; |
| 57 | return FLOPPY_ERROR_SUCCESS; |
| 58 | } |
| 59 | |
| 60 | |
| 61 | |
| 62 | static floperr_t internal_m20_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, int sector_is_index, void *buffer, size_t buflen) |
| 63 | { |
| 64 | UINT64 offset; |
| 65 | floperr_t err; |
| 66 | |
| 67 | //printf("internal_m20_read_sector: track = %d, head = %d, sector = %d, secisix = %d, buflen = %ld\n", track, head, sector, sector_is_index, (long)buflen); |
| 68 | err = get_offset(floppy, head, track, sector, sector_is_index, &offset); |
| 69 | if (err) |
| 70 | return err; |
| 71 | |
| 72 | floppy_image_read(floppy, buffer, offset, buflen); |
| 73 | return FLOPPY_ERROR_SUCCESS; |
| 74 | } |
| 75 | |
| 76 | |
| 77 | |
| 78 | static floperr_t internal_m20_write_sector(floppy_image_legacy *floppy, int head, int track, int sector, int sector_is_index, const void *buffer, size_t buflen, int ddam) |
| 79 | { |
| 80 | UINT64 offset; |
| 81 | floperr_t err; |
| 82 | |
| 83 | err = get_offset(floppy, head, track, sector, sector_is_index, &offset); |
| 84 | if (err) |
| 85 | return err; |
| 86 | |
| 87 | floppy_image_write(floppy, buffer, offset, buflen); |
| 88 | return FLOPPY_ERROR_SUCCESS; |
| 89 | } |
| 90 | |
| 91 | |
| 92 | |
| 93 | static floperr_t m20_read_sector(floppy_image_legacy *floppy, int head, int track, int sector, void *buffer, size_t buflen) |
| 94 | { |
| 95 | return internal_m20_read_sector(floppy, head, track, sector, FALSE, buffer, buflen); |
| 96 | } |
| 97 | |
| 98 | static floperr_t m20_write_sector(floppy_image_legacy *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam) |
| 99 | { |
| 100 | return internal_m20_write_sector(floppy, head, track, sector, FALSE, buffer, buflen, ddam); |
| 101 | } |
| 102 | |
| 103 | static floperr_t m20_read_indexed_sector(floppy_image_legacy *floppy, int head, int track, int sector, void *buffer, size_t buflen) |
| 104 | { |
| 105 | return internal_m20_read_sector(floppy, head, track, sector, TRUE, buffer, buflen); |
| 106 | } |
| 107 | |
| 108 | static floperr_t m20_write_indexed_sector(floppy_image_legacy *floppy, int head, int track, int sector, const void *buffer, size_t buflen, int ddam) |
| 109 | { |
| 110 | return internal_m20_write_sector(floppy, head, track, sector, TRUE, buffer, buflen, ddam); |
| 111 | } |
| 112 | |
| 113 | static floperr_t m20_get_sector_length(floppy_image_legacy *floppy, int head, int track, int sector, UINT32 *sector_length) |
| 114 | { |
| 115 | floperr_t err; |
| 116 | err = get_offset(floppy, head, track, sector, FALSE, NULL); |
| 117 | if (err) |
| 118 | return err; |
| 119 | |
| 120 | if (sector_length) { |
| 121 | if (track == 0 && head == 0) |
| 122 | *sector_length = 128; |
| 123 | else |
| 124 | *sector_length = 256; |
| 125 | } |
| 126 | return FLOPPY_ERROR_SUCCESS; |
| 127 | } |
| 128 | |
| 129 | |
| 130 | |
| 131 | static floperr_t m20_get_indexed_sector_info(floppy_image_legacy *floppy, int head, int track, int sector_index, int *cylinder, int *side, int *sector, UINT32 *sector_length, unsigned long *flags) |
| 132 | { |
| 133 | sector_index += 1; |
| 134 | if (cylinder) |
| 135 | *cylinder = track; |
| 136 | if (side) |
| 137 | *side = head; |
| 138 | if (sector) |
| 139 | *sector = sector_index; |
| 140 | if (flags) |
| 141 | /* TODO: read DAM or DDAM and determine flags */ |
| 142 | *flags = 0; |
| 143 | return m20_get_sector_length(floppy, head, track, sector_index, sector_length); |
| 144 | } |
| 145 | |
| 146 | |
| 147 | static FLOPPY_CONSTRUCT(m20_dsk_construct) |
| 148 | { |
| 149 | struct FloppyCallbacks *callbacks; |
| 150 | callbacks = floppy_callbacks(floppy); |
| 151 | callbacks->read_sector = m20_read_sector; |
| 152 | callbacks->write_sector = m20_write_sector; |
| 153 | callbacks->read_indexed_sector = m20_read_indexed_sector; |
| 154 | callbacks->write_indexed_sector = m20_write_indexed_sector; |
| 155 | callbacks->get_sector_length = m20_get_sector_length; |
| 156 | callbacks->get_heads_per_disk = m20_get_heads_per_disk; |
| 157 | callbacks->get_tracks_per_disk = m20_get_tracks_per_disk; |
| 158 | callbacks->get_indexed_sector_info = m20_get_indexed_sector_info; |
| 159 | |
| 160 | return FLOPPY_ERROR_SUCCESS; |
| 161 | } |
| 162 | |
| 163 | |
| 164 | |
| 165 | /* ----------------------------------------------------------------------- */ |
| 166 | |
| 167 | LEGACY_FLOPPY_OPTIONS_START( m20 ) |
| 168 | LEGACY_FLOPPY_OPTION(m20_dsk, "img", "M20 disk image", m20_dsk_identify, m20_dsk_construct, NULL, NULL) |
| 169 | LEGACY_FLOPPY_OPTIONS_END |
trunk/src/mess/drivers/m20.c
| r19120 | r19121 | |
| 44 | 44 | #include "machine/pit8253.h" |
| 45 | 45 | #include "machine/pic8259.h" |
| 46 | 46 | #include "imagedev/flopdrv.h" |
| 47 | | #include "formats/basicdsk.h" |
| 47 | #include "formats/m20_dsk.h" |
| 48 | 48 | |
| 49 | 49 | #include "machine/keyboard.h" |
| 50 | 50 | |
| r19120 | r19121 | |
| 307 | 307 | AM_RANGE( 0xa0000, 0xaffff ) AM_RAM |
| 308 | 308 | AM_RANGE( 0xb0000, 0xb3fff ) AM_RAM |
| 309 | 309 | AM_RANGE( 0xc0000, 0xc3fff ) AM_RAM |
| 310 | | // AM_RANGE( 0x34000, 0x37fff ) AM_RAM //extra vram for bitmap mode |
| 311 | | // AM_RANGE( 0x20000, 0x2???? ) //work RAM? |
| 310 | // AM_RANGE( 0x34000, 0x37fff ) AM_RAM //extra vram for color mode |
| 312 | 311 | ADDRESS_MAP_END |
| 313 | 312 | |
| 314 | 313 | static ADDRESS_MAP_START(m20_io, AS_IO, 16, m20_state) |
| r19120 | r19121 | |
| 336 | 335 | |
| 337 | 336 | AM_RANGE(0x140, 0x143) AM_READWRITE(m20_i8259_r, m20_i8259_w) |
| 338 | 337 | |
| 339 | | // 0x21?? / 0x21? - fdc ... seems to control the screen colors??? |
| 340 | 338 | ADDRESS_MAP_END |
| 341 | 339 | |
| 342 | 340 | #if 0 |
| r19120 | r19121 | |
| 418 | 416 | pic8259_ir4_w(machine().device("i8259"), state); |
| 419 | 417 | } |
| 420 | 418 | |
| 421 | | #if 0 |
| 419 | #if 1 |
| 422 | 420 | READ_LINE_MEMBER(m20_state::wd177x_dden_r) |
| 423 | 421 | { |
| 424 | | printf ("wd177x_dden_r called, returning %d\n", !m_port21_sd); |
| 422 | //printf ("wd177x_dden_r called, returning %d\n", !m_port21_sd); |
| 425 | 423 | return !m_port21_sd; |
| 426 | 424 | } |
| 427 | 425 | #endif |
| r19120 | r19121 | |
| 459 | 457 | |
| 460 | 458 | const wd17xx_interface m20_wd17xx_interface = |
| 461 | 459 | { |
| 462 | | DEVCB_NULL, //DEVCB_DRIVER_LINE_MEMBER(m20_state, wd177x_dden_r), |
| 460 | /*DEVCB_NULL,*/ DEVCB_DRIVER_LINE_MEMBER(m20_state, wd177x_dden_r), |
| 463 | 461 | DEVCB_DRIVER_LINE_MEMBER(m20_state, wd177x_intrq_w), |
| 464 | 462 | DEVCB_NULL, |
| 465 | 463 | {FLOPPY_0, FLOPPY_1, NULL, NULL} |
| 466 | 464 | }; |
| 467 | 465 | |
| 468 | | static LEGACY_FLOPPY_OPTIONS_START(m20) |
| 469 | | LEGACY_FLOPPY_OPTION(m20, "img", "M20 disk image", basicdsk_identify_default, basicdsk_construct_default, NULL, |
| 470 | | HEADS([2]) |
| 471 | | TRACKS([35]) |
| 472 | | SECTORS([16]) |
| 473 | | SECTOR_LENGTH([256]) |
| 474 | | FIRST_SECTOR_ID([1])) |
| 475 | | LEGACY_FLOPPY_OPTIONS_END |
| 476 | | |
| 477 | 466 | static const floppy_interface m20_floppy_interface = |
| 478 | 467 | { |
| 479 | 468 | DEVCB_NULL, |
| r19120 | r19121 | |
| 487 | 476 | NULL |
| 488 | 477 | }; |
| 489 | 478 | |
| 479 | static unsigned char kbxlat[] = |
| 480 | { |
| 481 | 0x00, '\\', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', |
| 482 | 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', |
| 483 | '4', '5', '6', '7', '8', '9', '-', '^', '@', '[', ';', ':', ']', ',', '.', '/', |
| 484 | 0x00, '<', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', |
| 485 | 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' |
| 486 | }; |
| 487 | |
| 490 | 488 | WRITE8_MEMBER( m20_state::kbd_put ) |
| 491 | 489 | { |
| 492 | 490 | if (data) { |
| 493 | 491 | if (data == 0xd) data = 0xc1; |
| 492 | else if (data == 0x20) data = 0xc0; |
| 493 | else if (data == 8) data = 0x69; /* ^H */ |
| 494 | else if (data == 3) data = 0x64; /* ^C */ |
| 495 | else if (data >= '0' && data <= '9') data += 0x4c - '0'; |
| 496 | else { |
| 497 | int i; |
| 498 | for (i = 0; i < sizeof(kbxlat); i++) |
| 499 | if (data == kbxlat[i]) { |
| 500 | data = i; |
| 501 | break; |
| 502 | } |
| 503 | } |
| 494 | 504 | printf("kbd_put called with 0x%02X\n", data); |
| 495 | 505 | m_kbdi8251->receive_character(data); |
| 496 | 506 | } |