Previous 199869 Revisions Next

r30902 Monday 9th June, 2014 at 00:42:53 UTC by Tafoid
rainbow.c: New floppy code - uses more reliable 'wd_fdc'. [Bavarese]

i86.c: Four new 8086 opcode aliases: 0xc0 is 0xc2; 0xc1 = 0xc3; 0xc8 = 0xca; 0xc9 = 0xcb as documented at OS 2 Museum. [Bavarese]

rx50_dsk.h/c: Rainbow specific; The RX50 _disk drive_ was used in different architectures.  Floppy format used by Rainbow-100 and -190. Track layout (post-amble, some positions) yet unverified. Currently only raw 400 K disk dumps are supported (*.img).  [Bavarese]
[src/emu/cpu/i86]i86.c
[src/lib]lib.mak
[src/lib/formats]rx50_dsk.c* rx50_dsk.h*
[src/mess/drivers]rainbow.c
[src/mess/machine]dec_lk201.c

trunk/src/emu/cpu/i86/i86.c
r30901r30902
11381138         break;
11391139
11401140// 8086 'invalid opcodes', as documented at http://www.os2museum.com/wp/?p=2147
1141//      0x60 - 0x6f are an alias to 0x70 - 0x7f.
1142//       These instructions are used in the boot sector for some versions of
1143//      MS-DOS 2.01   (e.g. the DEC Rainbow version).
1144      case 0x60:
1141// - 0x60 - 0x6f are an alias to 0x70 - 0x7f.
1142// - 0xc0,  0xc1, 0xc8, 0xc9 are also aliases where the CPU ignores BIT 1 (*).
1143//
1144//       Instructions are used in the boot sector for some versions of
1145//      MS-DOS  (e.g. the DEC Rainbow-100 version of DOS 2.x)
1146//      case 0x60:
11451147      case 0x70: // i_jo
11461148         JMP( OF);
11471149         break;
r30901r30902
16701672         CLK(MOV_RI16);
16711673         break;
16721674
1673
1675        case 0xc0: // 0xc0 is 0xc2 - see (*)
16741676      case 0xc2: // i_ret_d16
16751677         {
16761678            UINT32 count = fetch_word();
r30901r30902
16801682         }
16811683         break;
16821684
1685      case 0xc1: //  0xc1 is 0xc3 - see (*)
16831686      case 0xc3: // i_ret
16841687         m_ip = POP();
16851688         CLK(RET_NEAR);
r30901r30902
17111714         CLKM(MOV_RI16,MOV_MI16);
17121715         break;
17131716
1714
1717      case 0xc8:  // 0xc8 = 0xca - see (*)
17151718      case 0xca: // i_retf_d16
17161719         {
17171720            UINT32 count = fetch_word();
r30901r30902
17221725         }
17231726         break;
17241727
1728        case 0xc9:  // 0xc9 = 0xcb  - see (*)
17251729      case 0xcb: // i_retf
17261730         m_ip = POP();
17271731         m_sregs[CS] = POP();
trunk/src/lib/formats/rx50_dsk.c
r0r30902
1/**********************************************************************
2
3   formats/rx50_dsk.c
4   Floppies used by Rainbow 100 and 190.
5
6   The RX50 drive: 5.25" format; 300 rpm; MFM 250 kbps; 96 - 100 tpi
7   - single sided with two disk slots (1 drive motor served both).
8
9   DEC used the RX50 in entirely different architectures (Pro / PDP-11).
10   Native Rainbow 100 format:
11   - SSQD - 80 tracks with 10 sectors per track (512 byte sectors)
12   - first two tracks are reserved for loader code (DOS / CPM / custom)
13   - FAT and root directory began immediately on track 2.
14   - 2:1 sector interleave pattern - except in tracks 0 and 1.
15   NOTE: PUTR tends to interleave loader tracks 0 + 1. Not recommended!
16
17   Jeff's RBIMG is first choice for preservation, TeleDisk is second.
18   Always check the track layout. Both have problems with weak disks.
19
20   A container to handle copy protected RX 50 disks is needed. Some info
21   can be derived from Mark Hittinger's RBACKUP (CP/M source from Nov-94).
22
23   TODO: improve code to accept 40 T / single sided / 9 or 8 sector disks:
24     a) disks from VT180 (9 sectors; READ ONLY - enforced by BIOS)
25
26     b) 8 sector 160k MS-DOS disks (READ + WRITE support on DEC)
27        FORMAT A: /F:160 on DOS; turn MEDIACHK ON
28************************************************************************/
29
30#include "emu.h"
31#include "flopimg.h"
32#include "formats/rx50_dsk.h"
33
34// Controller: WD1793
35// TRACK LAYOUT IS UNVERIFED. SEE SOURCES:
36// - 'esq_dsk16' (uses WD 1772)
37// - SDC-RX50 Floppy Controller Manual
38// - 'PC 100 SYSTEM SPEC' 4.3 - page 42. (*)
39const floppy_image_format_t::desc_e rx50img_format::rx50_10_desc[] = {
40   {   MFM, 0x4e, 80 },          // (*)   GAP (1)
41   {   MFM, 0x00, 12 },          // Value from (*). (?? = unverified)
42   {   RAW, 0x5224, 3 },
43   {   MFM, 0xfc, 1 },
44   {   MFM, 0x4e, 50 },
45   { MFM, 0x00, 12 },
46   { SECTOR_LOOP_START, 0, 9 }, // 0 ... f.sector_count-1 
47   {   CRC_CCITT_START, 1 },
48   {     RAW, 0x4489, 3 },
49   {     MFM, 0xfe, 1 },   
50   {     TRACK_ID },
51   {     HEAD_ID },
52   {     SECTOR_ID },
53   {     SIZE_ID },
54   {   CRC_END, 1 },
55   {   CRC, 1 },
56   {   MFM, 0x4e, 22 },   // (*) POST-ID GAP (2)
57   {   MFM, 0x00, 12 },   // (*)
58   {   CRC_CCITT_START, 2 },
59   {     RAW, 0x4489, 3 },
60   {     MFM, 0xfb, 1 },   
61   {     SECTOR_DATA, -1 },
62   {   CRC_END, 2 },
63   {   CRC, 2 },
64   {   MFM, 0x4e, 48 },   // GAP (3) - taken from RBACKUP source.
65   {   MFM, 0x00, 12 },
66   { SECTOR_LOOP_END },     
67   { MFM, 0x4e, 1 },    // UNVERIFIED - ('esq_16' has 170 x $4e)
68   { END }
69};
70
71rx50img_format::rx50img_format()
72{
73}
74
75const char *rx50img_format::name() const
76{
77   return "img";
78}
79
80const char *rx50img_format::description() const
81{
82   return "DEC Rainbow 100 floppy image";
83}
84
85const char *rx50img_format::extensions() const
86{
87   return "img";
88}
89
90bool rx50img_format::supports_save() const
91{
92   return true;
93}
94
95void rx50img_format::find_size(io_generic *io, UINT8 &track_count, UINT8 &head_count, UINT8 &sector_count)
96{
97   head_count = 1;
98
99   UINT32 expected_size = 0;
100   UINT64 size = io_generic_size(io);
101
102   track_count = 80;
103   sector_count = 10;
104   expected_size = 512 * track_count * head_count * sector_count;
105
106   if (size == expected_size) // standard format has 409600 byte
107      return;
108/*
109   track_count = 40;
110   sector_count = 9; // [VT 180]
111   expected_size = 512 * track_count * head_count * sector_count;
112   if (size == expected_size)
113      return;
114
115   track_count = 40;
116   sector_count = 8; // [DOS]
117   expected_size = 512 * track_count * head_count * sector_count;
118   if (size == expected_size)
119      return;
120*/
121   track_count = head_count = sector_count = 0;
122}
123
124int rx50img_format::identify(io_generic *io, UINT32 form_factor)
125{
126   UINT8 track_count, head_count, sector_count;
127   find_size(io, track_count, head_count, sector_count);
128
129   if(track_count)
130      return 50;
131   return 0;
132}
133
134 //  /* Sectors are numbered 1 to 10 */
135bool rx50img_format::load(io_generic *io, UINT32 form_factor, floppy_image *image)
136{
137   UINT8 track_count, head_count, sector_count;
138   find_size(io, track_count, head_count, sector_count);
139   if(track_count == 0)
140      return false;
141
142   UINT8 sectdata[10*512];
143   desc_s sectors[10];
144   for(int i=0; i<sector_count; i++) {
145      sectors[i].data = sectdata + 512*i;
146      sectors[i].size = 512;
147      sectors[i].sector_id = i + 1; // SECTOR_ID +1  <===
148   }
149
150   int track_size = sector_count*512;
151   for(int track=0; track < track_count; track++) {
152      for(int head=0; head < head_count; head++) {
153         io_generic_read(io, sectdata, (track*head_count + head)*track_size, track_size);
154         generate_track(rx50_10_desc, track, head, sectors, sector_count, 102064, image);  // 98480
155      }
156   }
157
158   image->set_variant(floppy_image::SSQD);
159
160   return true;
161}
162
163bool rx50img_format::save(io_generic *io, floppy_image *image)
164{
165   int track_count, head_count, sector_count;
166   get_geometry_mfm_pc(image, 2000, track_count, head_count, sector_count);
167
168   if(track_count != 80)
169      track_count = 80;
170
171   // Happens for a fully unformatted floppy
172   if(!head_count)
173      head_count = 1;
174
175   if(sector_count == 9) // [VT180] 9 sector format : no save!
176      return false;
177
178   if(sector_count != 10) // either 8 or 10 sectors
179      sector_count = 10; // [STANDARD]
180
181   /*
182   if(sector_count != 10) // either 8 or 10 sectors
183   {
184     if(sector_count == 8)   
185     {
186        track_count = 40;  // [DOS]
187     } else
188     {
189          sector_count = 10; // [STANDARD]
190     }
191   }
192*/
193   UINT8 sectdata[11*512];
194   int track_size = sector_count*512;
195
196   for(int track=0; track < track_count; track++) {
197      for(int head=0; head < head_count; head++) {
198         get_track_data_mfm_pc(track, head, image, 2000, 512, sector_count, sectdata);
199         io_generic_write(io, sectdata, (track*head_count + head)*track_size, track_size);
200      }
201   }
202   return true;
203}
204
205const floppy_format_type FLOPPY_RX50IMG_FORMAT = &floppy_image_format_creator<rx50img_format>;
206
207
208/*
209
210// Native 400K format (80 T * 10 S * 512 bytes) on 'quad density' RX50 drives
211// ( 5.25" single sided; 300 rpm; MFM 250 kbps; 96 - 100 tpi ).
212//
213// The BIOS can also * read * VT-180 disks and access MS-DOS 160 k disks (R + W)
214// ( 40 tracks; single sided with 9 or 8 sectors per track )
215static LEGACY_FLOPPY_OPTIONS_START( dec100_floppy )
216   LEGACY_FLOPPY_OPTION( dec100_floppy, "td0", "Teledisk floppy disk image", td0_dsk_identify, td0_dsk_construct, td0_dsk_destruct, NULL )
217   LEGACY_FLOPPY_OPTION( dec100_floppy, "img", "DEC Rainbow 100", basicdsk_identify_default, basicdsk_construct_default,    NULL,
218      HEADS([1])
219      TRACKS(40/[80])
220      SECTORS(8/9/[10])
221      SECTOR_LENGTH([512])
222      INTERLEAVE([0])
223      FIRST_SECTOR_ID([1])
224                  )
225LEGACY_FLOPPY_OPTIONS_END
226
227*/
No newline at end of file
Property changes on: trunk/src/lib/formats/rx50_dsk.c
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/lib/formats/rx50_dsk.h
r0r30902
1/*********************************************************************
2
3    formats/rx50_dsk.h
4
5    Format for DEC RX50 floppy drive used e.g. by Rainbow 100 and 190
6
7    Disk is PC MFM, 80 tracks, single sided, with 10 sectors per track
8
9based on lib/formats/esq16_dsk.h
10
11*********************************************************************/
12
13#ifndef RX50_DSK_H_
14#define RX50_DSK_H_
15
16#include "flopimg.h"
17
18class rx50img_format : public floppy_image_format_t
19{
20public:
21   rx50img_format();
22
23   virtual int identify(io_generic *io, UINT32 form_factor);
24   virtual bool load(io_generic *io, UINT32 form_factor, floppy_image *image);
25   virtual bool save(io_generic *io, floppy_image *image);
26
27   virtual const char *name() const;
28   virtual const char *description() const;
29   virtual const char *extensions() const;
30   virtual bool supports_save() const;
31
32   static const desc_e rx50_10_desc[];
33
34private:
35   void find_size(io_generic *io, UINT8 &track_count, UINT8 &head_count, UINT8 &sector_count);
36};
37
38extern const floppy_format_type FLOPPY_RX50IMG_FORMAT;
39
40#endif /* RX50_DSK_H_ */
Property changes on: trunk/src/lib/formats/rx50_dsk.h
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native
trunk/src/lib/lib.mak
r30901r30902
185185   $(LIBOBJ)/formats/pyldin_dsk.o  \
186186   $(LIBOBJ)/formats/ql_dsk.o      \
187187   $(LIBOBJ)/formats/rk_cas.o      \
188   $(LIBOBJ)/formats/rx50_dsk.o    \
188189   $(LIBOBJ)/formats/sc3000_bit.o  \
189190   $(LIBOBJ)/formats/sf7000_dsk.o  \
190191   $(LIBOBJ)/formats/smx_dsk.o     \
trunk/src/mess/drivers/rainbow.c
r30901r30902
44    Driver-in-progress by R. Belmont and Miodrag Milanovic.
55    Portions (2013-2014) by Karl-Ludwig Deisenhofer (VT attributes, preliminary floppy, keyboard, DIP switches).
66
7    STATE AS OF APRIL 2014
8    ----------------------
7    STATE AS OF JUNE 2014
8    ---------------------
99    Driver is based entirely on the DEC-100 'B' variant (DEC-190 and DEC-100 A models are treated as clones).
1010    While this is OK for the compatible -190, it doesn't do justice to ancient '100 A' hardware.
1111
12    Currently, there are 2 showstoppers:
13    (1) IRQ logic for 100-B needs further work (text in RBCONVERT.ZIP has details concerning -A versus -B)
14    (2) Keyboard emulation incomplete (inhibits the system from booting with ERROR 50).
12    Currently, there are several issues here:
13    (1) Keyboard emulation incomplete (inhibits the system from booting with ERROR 50).
14    (2) after fixing (1), IRQ logic for 100-B should be verified (text in RBCONVERT.ZIP has details concerning -A versus -B.
15   DMA (needed for 'Extended communication option') or Z80-8088 arbitration is non-existent (E11/E13 dumps anyone?).
16   (3) Read errors when booting CP/M 2.x or DOS 2.x (secondary boot; read errors beyond T >= 2).
17   Seek (+ verify) and a number of signals (TRACK > 43 TG43, INDEX etc.) do not work (diag.disk aborts drive test).
1518
16    - FLOPPY TIMING: 'wd17xx_complete_command' * must * be hard wired to about 13 usecs.
17      Line 1063 in 'wd17xx.c' has to be changed (until legacy code here is removed):
18      -      w->timer_cmd->adjust(attotime::from_usec(usecs));
19      +      w->timer_cmd->adjust(attotime::from_usec(13));
20
2119    - NOT WORKING: serial (ERROR 60).
2220    - NOT WORKING: printer interface (ERROR 40). Like error 60 not mission-critical.
2321
24    - NON-CRITICAL: watchdog logic ('MHFU' triggered after 108 ms without interrupts on original machine) does not work.
22    - NON-CRITICAL: watchdog logic (MHFU - triggered after 108 ms without interrupts on original machine) does not work.
2523                    The timer is reset by TWO sources: the VERT INT L from the DC012, or the MHFU ENB L from the enable flip-flop.
2624                    MHFU gets active if the 8088 has not acknowledged a video processor interrupt within approx. 108 milliseconds
2725
28    - FIXME: warm boot triggers ERROR 16 (watchdog). BIOS assumes proper power-up only if MHFU detection is _disabled_
29      Apart from power-cycling, Ctrl-Setup (within SETUP) appears to be the only way to reboot the DEC-100.
30
3126    - TO BE IMPLEMENTED AS SLOT DEVICES (for now, DIP settings affect 'system_parameter_r' only and are disabled):
3227            * Color graphics option (uses NEC upd7220 GDC).       REFERENCE: Programmer's Reference: AA-AE36A-TV.
3328            Either 384 x 240 x 16 or 800 x 240 x 4 colors (out of 4096). 8 × 64 K video RAM. Pallette limited to 4 colors on 100-A.
3429
35            * Extended communication option (1 of 4 possible BUNDLE_OPTIONs)   REFERENCE: AA-V172A-TV + Addendum AV-Y890A-TV.
30            * Extended communication option (occupies BUNDLE_OPTION ports)   REFERENCE: AA-V172A-TV + Addendum AV-Y890A-TV.
3631            See also NEWCOM1.DOC in RBETECDOC.ZIP.   Board connected to the front rightmost expansion slot (1 of the expansion
3732            ports used by the hard disk controller). Thus can't be added to a system that includes the DEC RD50/51.
3833            => 2 ports, a high-speed RS-422 half-duplex interface (port A) + lower-speed RS-423 full/half-duplex interface
r30901r30902
4742                    Daughterboard, to be plugged into the expansion port where the memory expansion card usually sits.
4843                    If a memory adapter board is present, it has to be plugged into a connector atop the 8087 copro board.
4944                    The 8088 is put into the CPU socket on the coprocessor board.
45               => see MATH test on 'Design Maturity Diagnostics' disk <=
5046
5147            * Suitable Solutions TURBOW286: 12 Mhz, 68-pin, low power AMD N80L286-12 and WAYLAND/EDSUN EL286-88-10-B ( 80286 to 8088 Processor Signal Converter )
52              plus DC 7174 or DT 7174 (barely readable). Add-on card, replaces main 8088 cpu (via ribbon cable). Patched 5.0x BOOT ROM labeled 'TBSS1.3 - 3ED4'.
48              plus DC 7174 or DT 7174 (barely readable). Add-on card, replaces main 8088 cpu (via ribbon cable). Patched V5.03 BOOT ROM labeled 'TBSS1.3 - 3ED4'.
5349
5450            * NEC_V20 (requires modded BOOT ROM because of - at least 2 - hard coded timing loops):
5551                 100A:         100B/100+:                       100B+ ALTERNATE RECOMMENDATION (fixes RAM size auto-detection problems when V20 is in place.
r30901r30902
6965                Hard coded CPU loops are to blame. Try values from the alternate patch (right).
7066             => AAD/AAM - Intel 8088 honors the second byte (operand), NEC V20 ignores it and always uses base 0Ah (10).
7167             => UNDOCUMENTED: NEC V20 does not have "POP CS" (opcode 0F). There are more differences (opcode D6; the 2 byte POP: 8F Cx; FF Fx instructions)
72                Commercial programs had to be patched back then (as was the case with Loderunner for PC).
7368             => NEW OPCODES: REPC, REPNC, CHKIND, PREPARE, DISPOSE; BCD string operations (ADD4S, CMP4S, SUB4S), bit-ops (NOT, SET, TEST, ROL4, ROR4)
7469                WARNING: undoc'd opcodes, INS, EXT and 8080 behaviour are unemulated yet! MESS' CPU source has up-to-date info.
7570
r30901r30902
180175****************************************************************************/
181176
182177// Define standard and maximum RAM sizes (A, then B model):
183//#define BOARD_RAM 0x10000  // 64 K base RAM  (100-A)
178//#define BOARD_RAM 0x0ffff  // 64 K base RAM  (100-A)
184179//#define END_OF_RAM 0xcffff // very last byte (100-A) DO NOT CHANGE.
185180
186181// DEC-100-B probes until a 'flaky' area is found (BOOT ROM around F400:0E04).
187182// It is no longer possible to key in the RAM size from within the 100-B BIOS.
188#define BOARD_RAM 0x20000  // 128 K base RAM (100-B)
183#define BOARD_RAM 0x1ffff  // 128 K base RAM (100-B)
189184#define END_OF_RAM 0xdffff // very last byte (100-B) DO NOT CHANGE.
190185
191186// TROUBLESHOOTING RAM
r30901r30902
194189// can be narrowed down with the Diagnostic Disk and codes from the 'Pocket Service Guide'
195190// EK-PC100-PS-002 (APPENDIX B.2.2); pc100ps2.pdf
196191
197
198// Workaround not valid for 100-A -
192// WORKAROUNDS:
193// (1) FORCE LOGO: - not valid for 100-A ROM -
199194//#define FORCE_RAINBOW_B_LOGO
195// (2) KEYBOARD_WORKAROUND : also requires FORCE...LOGO !
196//#define KEYBOARD_WORKAROUND
197//#define KBD_DELAY 8500
200198
199// ----------------------------------------------------------------------------------------------
201200#include "emu.h"
202201#include "cpu/i86/i86.h"
203202#include "cpu/z80/z80.h"
204203#include "video/vtvideo.h"
205204
206#include "machine/wd17xx.h"
207#include "imagedev/flopdrv.h"
208#include "formats/basicdsk.h"
205#include "machine/wd_fdc.h"
206#include "formats/rx50_dsk.h"
207#include "imagedev/flopdrv.h"
209208
210209#include "machine/i8251.h"
211210#include "machine/clock.h"
r30901r30902
215214#include "rainbow.lh" // BEZEL - LAYOUT with LEDs for diag 1-7, keyboard 8-11 and floppy 20-23
216215
217216#define LK201_TAG   "lk201"
217#define FD1793_TAG  "fd1793x" 
218#define INVALID_DRIVE 255
218219
219220class rainbow_state : public driver_device
220221{
221222public:
222223   rainbow_state(const machine_config &mconfig, device_type type, const char *tag) :
223224      driver_device(mconfig, type, tag),
225#ifdef KEYBOARD_WORKAROUND
226   #include "m_kbd1.c" // KEYBOARD_WORKAROUND
227#endif
224228      m_inp1(*this, "W13"),
225229      m_inp2(*this, "W14"),
226230      m_inp3(*this, "W15"),
r30901r30902
235239      m_crtc(*this, "vt100_video"),
236240      m_i8088(*this, "maincpu"),
237241      m_z80(*this, "subcpu"),
238      m_fdc(*this, "wd1793"),
242      m_fdc(*this, FD1793_TAG),
239243      m_kbd8251(*this, "kbdser"),
240244      m_lk201(*this, LK201_TAG),
241245      m_p_ram(*this, "p_ram"),
r30901r30902
283287
284288   DECLARE_WRITE_LINE_MEMBER(irq_hi_w);
285289
290#ifdef KEYBOARD_WORKAROUND
291   #include "port9x_Ax.c" // KEYBOARD_WORKAROUND
292#endif
286293   UINT32 screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
287294   INTERRUPT_GEN_MEMBER(vblank_irq);
288295   DECLARE_WRITE_LINE_MEMBER(write_keyboard_clock);
289296   TIMER_DEVICE_CALLBACK_MEMBER(motor_tick);
290297
298   DECLARE_FLOPPY_FORMATS( floppy_formats );
291299protected:
292300   virtual void machine_start();
293301
r30901r30902
305313      IRQ_8088_MAX
306314   };
307315
316#ifdef KEYBOARD_WORKAROUND
317   #include "m_kbd2.c" // KEYBOARD_WORKAROUND
318#endif
308319   required_ioport m_inp1;
309320   required_ioport m_inp2;
310321   required_ioport m_inp3;
r30901r30902
315326   required_ioport m_inp8;
316327   required_ioport m_inp9;
317328   required_ioport m_inp10;
318
319329   required_device<rainbow_video_device> m_crtc;
320330   required_device<cpu_device> m_i8088;
321331   required_device<cpu_device> m_z80;
322   required_device<fd1793_device> m_fdc;
332   required_device<fd1793_t> m_fdc;
323333   required_device<i8251_device> m_kbd8251;
324334   required_device<lk201_device> m_lk201;
325335   required_shared_ptr<UINT8> m_p_ram;
r30901r30902
356366   virtual void machine_reset();
357367
358368   int m_unit;
359   legacy_floppy_image_device *m_image[4];
369   floppy_image_device *m_floppy;
360370
361371   int m_irq_high;
362372   UINT32 m_irq_mask;
363373};
364374
375FLOPPY_FORMATS_MEMBER( rainbow_state::floppy_formats )
376   FLOPPY_TD0_FORMAT,
377   FLOPPY_RX50IMG_FORMAT
378FLOPPY_FORMATS_END
365379
380static SLOT_INTERFACE_START( rainbow_floppies )
381   SLOT_INTERFACE( "525qd", FLOPPY_525_SSQD )   // "525ssdd"
382SLOT_INTERFACE_END
383
384
366385void rainbow_state::machine_start()
367386{
368   m_image[0] = subdevice<legacy_floppy_image_device>(FLOPPY_0);
369   m_image[1] = subdevice<legacy_floppy_image_device>(FLOPPY_1);
370   m_image[2] = subdevice<legacy_floppy_image_device>(FLOPPY_2);
371   m_image[3] = subdevice<legacy_floppy_image_device>(FLOPPY_3);
372
387   MOTOR_DISABLE_counter = 2; // soon resets drv.LEDs
373388   COLD_BOOT = 1;
374389
375390   m_SCREEN_BLANK = false;
r30901r30902
386401#ifdef FORCE_RAINBOW_B_LOGO
387402   UINT8 *rom = memregion("maincpu")->base();
388403
404   rom[0xf4000 + 0x364a]= 2 + 8;  // 2 :set ; 4 : reset, 8 : set for 0xf4363 ( 0363 WAIT_FOR_BIT3__loc_35E )
405
406   rom[0xf4000 + 0x0363]= 0x90;
407   rom[0xf4000 + 0x0364]= 0x90;
408
409   // If bit 2 = 1 (Efff9), then a keyboard powerup is necessary (=> will lock up in current state)
410   rom[0xf4000 + 0x3638]= 0x80;  // OR instead of TEST
411   rom[0xf4000 + 0x3639]= 0x0f;  // OR instead of TEST
412   rom[0xf4000 + 0x363a]= 0x08;  // 04 => 08
413
414   rom[0xf4000 + 0x363b]= 0xeb;  // COND => JMPS
415
389416    if (rom[0xf4174] == 0x75)
390417    {   rom[0xf4174] = 0xeb; // jmps  RAINBOW100_LOGO__loc_33D
391418        rom[0xf4175] = 0x08;
r30901r30902
398425        rom[0xf437b] = 0xeb;
399426#endif
400427
428#ifdef KEYBOARD_WORKAROUND
429   #include "rainbow_keyboard0.c"
430#endif
401431}
402432
403433static ADDRESS_MAP_START( rainbow8088_map, AS_PROGRAM, 8, rainbow_state)
r30901r30902
447477   AM_RANGE(0x11, 0x11) AM_DEVREADWRITE("kbdser", i8251_device, status_r, control_w)
448478
449479   // UNMAPPED:
450    // 0x20 - 0x2f ***** EXTENDED COMM. OPTION (option select 1)
451    //  0x27 (RESET EXTENDED COMM OPTION - - see boot ROM @1EA6)
480    // 0x20 -> 0x2f ***** EXTENDED COMM. OPTION / Option Select 1.
481    // See boot rom @1EA6: 0x27 (<- RESET EXTENDED COMM OPTION  )
452482    // ===========================================================
483   // 0x30 -> 0x3f ***** EXTENDED COMM. OPTION / Option Select 3.
484   // ===========================================================
453485    // 0x40  COMMUNICATIONS DATA REGISTER (MPSC) 
454486   // 0x41  PRINTER DATA REGISTER (MPSC)
455487   // 0x42  COMMUNICATIONS CONTROL / STATUS REGISTER (MPSC)
r30901r30902
477509    //  56h   Data written to this port is loaded into the GDC's FIFO
478510    //        Buffer and flagged as a parameter.
479511   // ===========================================================
512   // 0x60 -> 0x6f ***** EXTENDED COMM. OPTION / Option Select 2.
513   // ===========================================================
480514   // TODO: hard disc emulation!
481515   // ------ Rainbow uses 'WD 1010 AL' (Western Digital 1983)
482516   //        Register compatible to WD2010 (present in MESS)
r30901r30902
492526   //   SOFTWARE:
493527   //   - MS-DOS 2 allows a maximum partition size of 16 MB (sizes > 15 MB are incompatible to DOS 3)
494528   //   - MS-DOS 3 has a global 1024 cylinder limit (32 MB).
529   // ===========================================================
530   // 0x70 -> 0x7f ***** EXTENDED COMM. OPTION / Option Select 4.
531   // ===========================================================
532#ifdef KEYBOARD_WORKAROUND
533   #include "am_range_9x_Ax.c" // KEYBOARD_WORKAROUND
534#endif
495535ADDRESS_MAP_END
496536
497537static ADDRESS_MAP_START(rainbowz80_mem, AS_PROGRAM, 8, rainbow_state)
r30901r30902
506546   AM_RANGE(0x20, 0x20) AM_READWRITE(z80_generalstat_r, z80_diskdiag_read_w) // read to port 0x20 used by MS-DOS 2.x diskette loader.
507547   AM_RANGE(0x21, 0x21) AM_READWRITE(z80_generalstat_r, z80_diskdiag_write_w)
508548   AM_RANGE(0x40, 0x40) AM_READWRITE(z80_diskstatus_r, z80_diskcontrol_w)
509   AM_RANGE(0x60, 0x60) AM_DEVREADWRITE("wd1793", fd1793_device ,status_r, command_w)
510   AM_RANGE(0x61, 0x61) AM_DEVREADWRITE("wd1793", fd1793_device, track_r, track_w)
511   AM_RANGE(0x62, 0x62) AM_DEVREADWRITE("wd1793", fd1793_device, sector_r, sector_w)
512   AM_RANGE(0x63, 0x63) AM_DEVREADWRITE("wd1793", fd1793_device, data_r, data_w)
549   AM_RANGE(0x60, 0x63)   AM_DEVREADWRITE(FD1793_TAG, fd1793_t, read, write)
513550ADDRESS_MAP_END
514551
515552/* Input ports */
516553
517554/* DIP switches */
518555static INPUT_PORTS_START( rainbow100b_in )
556
557#ifdef KEYBOARD_WORKAROUND
558   #include "rainbow_ipt.c"
559#endif
519560      PORT_START("MONITOR TYPE")
520561      PORT_DIPNAME( 0x03, 0x03, "MONOCHROME MONITOR")
521562      PORT_DIPSETTING(    0x01, "PAPER WHITE" )
r30901r30902
545586      PORT_DIPNAME( 0x01, 0x01, "FLOPPY CONTROLLER") PORT_TOGGLE
546587        PORT_DIPSETTING(    0x01, DEF_STR( On ) )
547588
548    //   BUNDLE_OPTION: COMM.card or hard disc controller extension (marketed later).
549    //  NOTES: - hard disc and COMM.extension exclude each other.
550    //         - connector J4 has 4 select lines.  Select option 1 = COMM CARD ?
589    //   BUNDLE_OPTION: EXT.COMM.card -or- hard disk controller (marketed later).
590    //         - hard disc and COMM.extension exclude each other!
591    //         - connector J4 has 4 select lines (Option Select 1-4)
551592      PORT_START("BUNDLE OPTION")
552593      PORT_DIPNAME( 0x00, 0x00, "BUNDLE OPTION") PORT_TOGGLE
553594      PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
r30901r30902
586627      PORT_DIPSETTING(    0x02, DEF_STR( On ) )
587628INPUT_PORTS_END
588629
589// Native 400K format (80 T * 10 S * 512 bytes) on 'quad density' RX50 drives
590// ( 5.25" single sided; 300 rpm; MFM 250 kbps; 96 - 100 tpi ).
591//
592// Additionally, the BIOS can *read* VT-180 disks and MS-DOS 160 k disks
593// - MS-DOS: FORMAT A: /F:160 and MEDIACHK ON
594// ( 40 tracks; single sided with 9 or 8 sectors per track )
595static LEGACY_FLOPPY_OPTIONS_START( dec100_floppy )
596   LEGACY_FLOPPY_OPTION( dec100_floppy, "td0", "Teledisk floppy disk image", td0_dsk_identify, td0_dsk_construct, td0_dsk_destruct, NULL )
597   LEGACY_FLOPPY_OPTION( dec100_floppy, "img", "DEC Rainbow 100", basicdsk_identify_default, basicdsk_construct_default,    NULL,
598      HEADS([1])
599      TRACKS(40/[80])
600      SECTORS(8/9/[10])
601      SECTOR_LENGTH([512])
602      INTERLEAVE([0])
603      FIRST_SECTOR_ID([1])
604                  )
605LEGACY_FLOPPY_OPTIONS_END
606630
607631void rainbow_state::machine_reset()
608632{
633   m_unit = INVALID_DRIVE;
634
635   m_fdc->reset();
636   m_fdc->set_floppy(NULL);
637   m_fdc->dden_w(0);
638   //m_fdc->set_force_ready(false);
639
609640   /* configure RAM */
610641   address_space &program = m_maincpu->space(AS_PROGRAM);
611642    if (m_inp8->read() < END_OF_RAM)
612643   {   program.unmap_readwrite(m_inp8->read(), END_OF_RAM);
613644   }
614645
615   if (COLD_BOOT == 1)
646   // BIOS can't handle soft resets (=> triggers ERROR 16).
647   if ( COLD_BOOT == 2 )
648   {   // As a fallback, execute a hard reboot -
649      device().machine().schedule_hard_reset();
650   }
651
652   if ( (COLD_BOOT == 1) )
616653   {
617654      COLD_BOOT = 2;
618655      m_crtc->MHFU(-100); // reset MHFU counter
r30901r30902
647684   output_set_value("led_lock", 0);    // led10
648685   output_set_value("led_hold", 0);    // led11
649686
650   MOTOR_DISABLE_counter = 2; // soon resets drv.LEDs
651   m_unit = 0;
652687   m_irq_mask = 0;
688
689
653690}
654691
692#ifdef KEYBOARD_WORKAROUND
693   #include "rainbow_keyboard2.c"
694#endif
695
655696UINT32 rainbow_state::screen_update_rainbow(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
656697{
657   // TEST-DEBUG: no screen updates during diskette operations!
658698   if (MOTOR_DISABLE_counter)
659699      return 0;
660700
r30901r30902
780820    return   ( ((m_inp5->read() == 1)      ? 0 : 1)  |
781821       ((m_inp6->read() == 1)      ? 0 : 2)  |
782822       ((m_inp7->read() == 1)      ? 0 : 4)  |
783              ((m_inp8->read() > BOARD_RAM)   ? 0 : 8)  |
823              ((m_inp8->read() > BOARD_RAM)   ? 0 : 8)  |
784824              16 | 32 | 64 | 128 // to be verified.
785825      );
786826}
r30901r30902
799839   int data;
800840   if (COLD_BOOT == 2)
801841      data = 0;
802   else
842   else
803843      data = m_crtc->MHFU(1);
804
844   
805845   return (  ( (data > 0) ? 0x00 : 0x20) |// (L): status of MHFU flag => bit pos.5
806846               (   (INT88)    ? 0x00 : 0x40 ) |               // (L)
807847               (   (INTZ80)   ? 0x00 : 0x80 )                 // (L)
r30901r30902
891931D2 : INT88 L: (bit reads the INT88 bit sent by Z80 to interrupt 8088)
892932D1 : INTZ80 L: (bit reads the INTZ80 bit sent by 8088 to interrupt Z80)
893933D0 : ZFLIP L: (read from the diagnostic control register of Z80A)
894
895NOTES: ALL LOW ACTIVE - EXCEPT TR00
896934*/
897   // * TRACK 00 *  signal for current drive
898   int tk00 = ( m_image[m_unit]->floppy_tk00_r()  == CLEAR_LINE ) ? 0x20 : 0x00;
935    static int last_track;
936   int track = m_fdc->track_r( space, 0);
937   int fdc_step = 0;
938   int   fdc_ready =   0;
939   int   tk00 = 0;
899940
900   int fdc_ready = m_image[m_unit]->floppy_drive_get_flag_state( FLOPPY_DRIVE_READY);
941   if(m_unit != INVALID_DRIVE)
942   {
943      if (track != last_track)
944         fdc_step = 1;
945      last_track = track;
901946
902   int data=(   0x80                    |   // (STEP L)
903//           (  (fdc_write_gate) )       |
904            (  (tk00)           )                             |
905//           (   fdc_direction)                                |
906            (  (fdc_ready)? 0x00 : 0x08 )                     |
947      fdc_ready =   m_floppy->ready_r();
948      tk00 = ( m_floppy->trk00_r() != CLEAR_LINE );
949   }
950
951   int last_dir = 0;      // FAKE LAST_DIR + WRITE_GATE FOR NOW.
952   int fdc_write_gate = 1;
953
954    // ***** ALL LOW ACTIVE - EXCEPT tk00 :
955   int data=(
956            (  (fdc_step)             ? 0x00 : 0x80 )        | 
957              (  (fdc_write_gate == 1)  ? 0x00 : 0x40 )         |
958           (  (tk00)                 ? 0x20 : 0x00 )        |
959           (  (last_dir == 1)        ? 0x00 : 0x10 )        |
960           (  (fdc_ready)            ? 0x00 : 0x08 )        |
907961            (   (INT88)    ? 0x00 : 0x04 )                     |
908962            (   (INTZ80)   ? 0x00 : 0x02 )                     |
909963            (  (m_zflip)  ? 0x00 : 0x01 )
r30901r30902
9631017   // D3: MOTOR 0 ON L: 0 = indicates MOTOR 0 ON bit is set in drive  "
9641018
9651019   // D2: TG43 L :  0 = INDICATES TRACK > 43 SIGNAL FROM FDC TO DISK DRIVE.
966   data |= ( track > 43) ? 0x00 : 0x04;
1020   if ( track > 43)
1021      data = data & (255 - 4);
1022   else
1023      data = data | 4;
9671024
9681025   // D1: DS1 H: reflect status of bits 0 and 1 form disk.control reg.
9691026   // D0: DS0 H: "
r30901r30902
9711028}
9721029
9731030// (Z80) : PORT 40H  * WRITE *
974
9751031// RX-50 has head A and head B (1 for each of the 2 disk slots in a RX-50).
976
9771032// TODO: find out how head load and drive select really work.
9781033WRITE8_MEMBER(rainbow_state::z80_diskcontrol_w)
9791034{
9801035   // FORCE_READY = 0 : assert DRIVE READY on FDC (diagnostic override; USED BY BIOS!)
981   //               1 : set ready only if drive is present, disk is in the drive,
982   //                   and disk motor is on - for Amstrad, Spectrum, PCW...
983   int force_ready = ( (data & 4) != 0 ) ? 0 : 1;
1036   //bool force_ready = ( (data & 4) == 0 ) ? true : false;
9841037
9851038   int drive;
9861039   if ( m_inp10->read() && ((data & 3) < 2) )
r30901r30902
9881041   else
9891042      drive = data & 3;
9901043
991   int selected_drive = 255;
1044   int selected_drive = INVALID_DRIVE;
1045   static const char *names[] = { FD1793_TAG ":0", FD1793_TAG ":1", FD1793_TAG ":2", FD1793_TAG ":3" };
9921046
993   if (floppy_get_device( machine(), drive )->flopimg_get_image() != NULL)
994   {   selected_drive = drive;
995      m_fdc->set_drive(selected_drive);
996   }
1047   floppy_connector *con = machine().device<floppy_connector>(names[drive]);
1048   if (con)
1049   {   m_floppy = con->get_device();
1050         if (m_floppy)
1051         { 
1052            selected_drive = drive;
9971053
998   // WD emulation (wd17xx.c) will ignore 'side select' if set to WD1793.
999   // Is it safe to * always assume * single sided 400 K disks?
1000   m_fdc->set_side((data & 20) ? 1 : 0);
1054            m_fdc->set_floppy(m_floppy);  // Sets new  _image device_
1055            m_floppy->set_rpm(300.);
10011056
1002   m_fdc->dden_w(0); /* SEE 'WRITE_TRACK' : 1 = SD; 0 = DD; enable double density */
1057            // RX50 board has additional 'side select' - ignored by WD emulation?
1058            m_floppy->ss_w((data & 20) ? 1 : 0);
1059         }
1060   }
10031061
10041062   output_set_value("driveled0",  (selected_drive == 0) ? 1 : 0 );
10051063   output_set_value("driveled1",  (selected_drive == 1) ? 1 : 0 );
r30901r30902
10111069   {
10121070         m_unit = selected_drive;
10131071
1014         // MOTOR ON flags 1+2 proved to be unreliable in this context.
1015         // So this timeout only disables LEDs.
1016         MOTOR_DISABLE_counter = 10000; // prolonged timeout. DEFAULT: 2400 = 500 ms
1072         if (MOTOR_DISABLE_counter == 0) // "one shot"
1073            MOTOR_DISABLE_counter = 4800; // 2400 = 500 ms
10171074
1075//         m_fdc->set_force_ready(force_ready);
1076   }    else
1077   {
1078//          m_fdc->set_force_ready(false);
1079   }
1080
10181081         for(int f_num=0; f_num <= 3; f_num++)
10191082         {
1020            // Although 1773 does not feature 'motor on' this statement is required:
1021            // CLEAR_LINE = turn motor on -
1022            m_image[f_num]->floppy_mon_w((f_num == selected_drive) ? CLEAR_LINE : ASSERT_LINE);
1083            floppy_connector *con = machine().device<floppy_connector>(names[f_num]);
1084            floppy_image_device *tmp_floppy = con->get_device();
1085            tmp_floppy->mon_w( (f_num == m_unit) ? CLEAR_LINE : ASSERT_LINE );
1086   }
10231087
1024            // Parameters: DRIVE, STATE, FLAG
1025            m_image[f_num]->floppy_drive_set_ready_state(
1026                                    (f_num == selected_drive) ? 1 : 0,
1027                                    (f_num == selected_drive) ? force_ready : 0
1028                                 );
1088   if(m_unit == INVALID_DRIVE)
1089   {   
1090      data = data & (255 -3); 
1091      data = data | 8;  // MOTOR 0 OFF
1092      data = data | 16; // MOTOR 1 OFF
1093   }else
1094   {   data = ( data & (255 -3) ) | m_unit;
1095
1096       if(m_unit < 2)
1097         data = data & (255 - 8); // MOTOR 0 (for A or B)
1098
1099      if(m_unit > 1)
1100         data = data & (255 - 16); // MOTOR 1 (for C or D)
10291101         }
1030   }
1031
10321102   m_z80_diskcontrol = data;
10331103}
10341104
r30901r30902
10651135//    printf("%02x to diag port (PC=%x)\n", data, space.device().safe_pc());
10661136   m_SCREEN_BLANK = (data & 2) ? false : true;
10671137
1068   //  SAVE / PROGRAM NVM: transfer data from volatile memory to NVM
1069   if ( !(data & 0x40)  && (m_diagnostic & 0x40) )
1070      memcpy( m_p_nvram, m_p_vol_ram, 256);
10711138
1072   // READ / RECALL NVM: transfer data from NVM to volatile memory
1073   if ( (data & 0x80)  && !(m_diagnostic & 0x80) )
1074      memcpy( m_p_vol_ram, m_p_nvram, 256);
1075
10761139   if (!(data & 1))
10771140   {
10781141      m_z80->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
r30901r30902
10871150      m_z80->reset();
10881151   }
10891152
1090   /*  Page 197 or 5-13 of formatter description:
1091       ZRESET L : this low input from the 8088 diagnostic write register
1092       resets the formatter controller, loads 03H into the command register,
1093       and resets the not ready (status bit 7).
1153   if(m_unit != INVALID_DRIVE)
1154   {
1155      if ( (m_diagnostic & 1) && !(data & 1) ) 
1156      {       
1157         m_fdc->soft_reset();
1158      }   
10941159
1095       When ZRESET goes high (1), a restore command is executed regardless
1096       of the state of the ready signal from the diskette drive and
1097       01H is loaded into the sector register.
1098   */
1160      if ( !(m_diagnostic & 1) && (data & 1) ) 
1161       {   
1162         m_fdc->soft_reset(); // See formatter description p.197 or 5-13
1163      }
1164   }
1165   // MISSING BITS (* not vital for normal operation, see diag.disk) -
1166   // BIT 2: GRF VID SEL (0 = system module; 1 = graphics option)
1167   // BIT 3: PARITY TEST (1 = enables parity test on memory option board)       
1168   // * BIT 4: DIAG LOOPBACK (0 at power-up; 1 directs RX50 and DC12 output to printer port)
1169   // * BIT 5: PORT LOOPBACK (1 enables loopback for COMM, PRINTER, KEYBOARD ports)
10991170
1100   // reset device when going from high to low,
1101   // restore command when going from low to high :
1102   m_fdc->mr_w((data & 1) ? 1 : 0);
1171   // BIT 6: Transfer data from volatile memory to NVM
1172   if ( !(data & 0x40)  && (m_diagnostic & 0x40) )
1173      memcpy( m_p_nvram, m_p_vol_ram, 256);
1174
1175   // BIT 7: Transfer data from NVM to volatile memory
1176   if ( (data & 0x80)  && !(m_diagnostic & 0x80) )
1177      memcpy( m_p_vol_ram, m_p_nvram, 256);
1178
11031179   m_diagnostic = data;
11041180}
11051181
r30901r30902
11071183// KEYBOARD
11081184void rainbow_state::update_kbd_irq()
11091185{
1186#ifndef KEYBOARD_WORKAROUND
11101187   if ((m_kbd_rx_ready) || (m_kbd_tx_ready))
11111188   {
11121189      raise_8088_irq(IRQ_8088_KBD);
r30901r30902
11151192   {
11161193      lower_8088_irq(IRQ_8088_KBD);
11171194   }
1195#endif
11181196}
11191197
11201198WRITE_LINE_MEMBER(rainbow_state::kbd_tx)
r30901r30902
11931271   GFXDECODE_ENTRY( "chargen", 0x0000, rainbow_charlayout, 0, 1 )
11941272GFXDECODE_END
11951273
1196static const floppy_interface floppy_intf =
1197{
1198   FLOPPY_STANDARD_5_25_SSDD_80,
1199   LEGACY_FLOPPY_OPTIONS_NAME( dec100_floppy ),
1200   "floppy_5_25"
1201};
12021274
12031275static MACHINE_CONFIG_START( rainbow, rainbow_state )
12041276   MCFG_DEFAULT_LAYOUT(layout_rainbow)
r30901r30902
12291301   MCFG_VT_VIDEO_RAM_CALLBACK(READ8(rainbow_state, read_video_ram_r))
12301302   MCFG_VT_VIDEO_CLEAR_VIDEO_INTERRUPT_CALLBACK(WRITELINE(rainbow_state, clear_video_interrupt))
12311303
1232   MCFG_DEVICE_ADD("wd1793", FD1793, 0)
1233   MCFG_WD17XX_DEFAULT_DRIVE4_TAGS
1234   MCFG_LEGACY_FLOPPY_4_DRIVES_ADD(floppy_intf)
1304   MCFG_FD1793x_ADD(FD1793_TAG, XTAL_24_0734MHz / 24) // no separate 1 Mhz quartz
1305   MCFG_WD_FDC_FORCE_READY
1306   MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":0", rainbow_floppies, "525qd", rainbow_state::floppy_formats)
1307   MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":1", rainbow_floppies, "525qd", rainbow_state::floppy_formats)
1308   MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":2", rainbow_floppies, "525qd", rainbow_state::floppy_formats)
1309   MCFG_FLOPPY_DRIVE_ADD(FD1793_TAG ":3", rainbow_floppies, "525qd", rainbow_state::floppy_formats) 
12351310   MCFG_SOFTWARE_LIST_ADD("flop_list","rainbow")
12361311
12371312   MCFG_DEVICE_ADD("kbdser", I8251, 0)
r30901r30902
12941369
12951370// CHANGES: the 'Boot 2.4' manual mentions 'recent ROM changes for MASS 11' in January 1985.
12961371// Older ROMs like 04.03.11 (for PC-100-A) or 05.03 (100-B) obviously do not incorporate these.
1297
12981372// => jump tables (F4000-F40083 and FC000-FC004D) were not extended.
12991373// => absolute addresses of some internal routines have changed.
13001374// => programs that do not rely on specific ROM versions should be compatible.
1375// MASS was a VAX word processor, so changes likely affected terminal emulation.
13011376
13021377// FIXME: ROM names are made up.
13031378// Someone who knows the DEC naming conventions should correct them -
trunk/src/mess/machine/dec_lk201.c
r30901r30902
256256*/
257257
258258INPUT_PORTS_START( lk201 )
259
260#ifndef KEYBOARD_WORKAROUND
259261   PORT_START("KBD0")
260262   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNUSED )
261263   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_UNUSED )
r30901r30902
435437   PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_UNUSED )
436438   PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD ) PORT_NAME("F19")
437439   PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
440
441#endif
438442INPUT_PORTS_END
439443
440444
r30901r30902
600604         // Check for keyboard read strobe
601605         if (((data & 0x40) == 0) && (ports[offset] & 0x40))
602606         {
607#ifndef KEYBOARD_WORKAROUND
603608            if (ports[0] & 0x1) kbd_data = m_kbd0->read();
604609            if (ports[0] & 0x2) kbd_data = m_kbd1->read();
605610            if (ports[0] & 0x4) kbd_data = m_kbd2->read();
r30901r30902
618623            if (ports[1] & 0x80) kbd_data = m_kbd15->read();
619624            if (ports[2] & 0x1) kbd_data = m_kbd16->read();
620625            if (ports[2] & 0x2) kbd_data = m_kbd17->read();
626#endif
621627         }
622628         // Check for LED update strobe
623629         if (((data & 0x80) == 0) && (ports[offset] & 0x80))

Previous 199869 Revisions Next


© 1997-2024 The MAME Team