Previous 199869 Revisions Next

r40550 Sunday 30th August, 2015 at 12:06:06 UTC by Sergey Svishchev
New skeleton: dvk_kcgd (colour graphics display controller for DVK series)
[scripts/target/mame]mess.lua
[src/mame]mess.lst
[src/mess/drivers]dvk_kcgd.c*

trunk/scripts/target/mame/mess.lua
r249061r249062
14431443   MAME_DIR .. "src/mess/drivers/bk.c",
14441444   MAME_DIR .. "src/mess/machine/bk.c",
14451445   MAME_DIR .. "src/mess/video/bk.c",
1446   MAME_DIR .. "src/mess/drivers/dvk_kcgd.c",
14461447   MAME_DIR .. "src/mess/drivers/dvk_ksm.c",
14471448   MAME_DIR .. "src/mess/machine/ms7004.c",
14481449   MAME_DIR .. "src/mess/drivers/mk85.c",
trunk/src/mame/mess.lst
r249061r249062
26522652vax785
26532653ms0515
26542654ie15
2655dvk_kcgd
26552656dvk_ksm
26562657dvk_ksm01
26572658asmapro
trunk/src/mess/drivers/dvk_kcgd.c
r0r249062
1/***************************************************************************
2
3    KCGD (Kontroller Cvetnogo Graficheskogo Displeya = Colour Graphics
4    Display Controller), a replacement for KSM (dvk_ksm.c) in later
5    models of DVK desktops.
6
7    MPI (Q-Bus clone) board. Interfaces with MS7004 (DEC LK201 workalike)
8    keyboard, mouse, and monochrome or color CRT.
9
10    To do:
11    - K1801VM2 CPU core (interrupts and EVNT pin, full EIS set, other insns)
12    - Everything else :-)
13
14****************************************************************************/
15
16#include "emu.h"
17
18#include "bus/rs232/rs232.h"
19#include "cpu/t11/t11.h"
20#include "machine/clock.h"
21#include "machine/ms7004.h"
22
23#define KCGD_TOTAL_HORZ 1000   // XXX verify
24#define KCGD_DISP_HORZ  800
25#define KCGD_HORZ_START 200   // XXX verify
26
27#define KCGD_TOTAL_VERT 600   // XXX verify
28#define KCGD_DISP_VERT  480
29#define KCGD_VERT_START 100   // XXX verify
30
31#define KCGD_STATUS_PAGE   0
32#define KCGD_STATUS_INTERLACE   1
33#define KCGD_STATUS_TIMER_INT   5
34#define KCGD_STATUS_MODE_INT   6
35#define KCGD_STATUS_MODE_LAST   7
36#define KCGD_STATUS_TIMER_VAL   15
37
38#define KCGD_PAGE_0   015574
39#define KCGD_PAGE_1   005574
40
41#define VERBOSE_DBG 1       /* general debug messages */
42
43#define DBG_LOG(N,M,A) \
44   do { \
45      if(VERBOSE_DBG>=N) \
46      { \
47         if( M ) \
48            logerror("%11.6f at %s: %-24s",machine().time().as_double(),machine().describe_context(),(char*)M ); \
49         logerror A; \
50      } \
51   } while (0)
52
53
54class kcgd_state : public driver_device
55{
56public:
57   kcgd_state(const machine_config &mconfig, device_type type, const char *tag) :
58      driver_device(mconfig, type, tag),
59      m_maincpu(*this, "maincpu"),
60//      m_ms7004(*this, "ms7004"),
61      m_palette(*this, "palette"),
62      m_screen(*this, "screen")
63   { }
64
65   virtual void machine_reset();
66   virtual void video_start();
67   UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
68   TIMER_DEVICE_CALLBACK_MEMBER(scanline_callback);
69   DECLARE_PALETTE_INIT(kcgd);
70
71   enum
72   {
73      TIMER_ID_VSYNC_ON,
74      TIMER_ID_VSYNC_OFF,
75      TIMER_ID_500HZ
76   };
77   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
78
79   DECLARE_WRITE_LINE_MEMBER(write_keyboard_clock);
80   DECLARE_WRITE_LINE_MEMBER(write_line_clock);
81
82   DECLARE_READ16_MEMBER(vram_addr_r);
83   DECLARE_READ16_MEMBER(vram_data_r);
84   DECLARE_READ16_MEMBER(vram_mmap_r);
85   DECLARE_WRITE16_MEMBER(vram_addr_w);
86   DECLARE_WRITE16_MEMBER(vram_data_w);
87   DECLARE_WRITE16_MEMBER(vram_mmap_w);
88   DECLARE_READ16_MEMBER(status_r);
89   DECLARE_WRITE16_MEMBER(status_w);
90   DECLARE_READ8_MEMBER(palette_index_r);
91   DECLARE_READ8_MEMBER(palette_data_r);
92   DECLARE_WRITE8_MEMBER(palette_index_w);
93   DECLARE_WRITE8_MEMBER(palette_data_w);
94
95   emu_timer *m_vsync_on_timer;
96   emu_timer *m_vsync_off_timer;
97   emu_timer *m_500hz_timer;
98
99private:
100   void draw_scanline(UINT16 *p, UINT16 offset);
101   rectangle m_tmpclip;
102   bitmap_ind16 m_tmpbmp;
103
104   struct {
105      UINT16 status;   // 167770
106      UINT8 control;   // 167772
107      int palette_index, vram_addr;
108      UINT8 palette[16];
109   } m_video;
110   UINT32 *m_videoram;
111
112protected:
113   required_device<cpu_device> m_maincpu;
114//   required_device<ms7004_device> m_ms7004;
115   required_device<palette_device> m_palette;
116   required_device<screen_device> m_screen;
117};
118
119static ADDRESS_MAP_START( kcgd_mem, AS_PROGRAM, 16, kcgd_state )
120   ADDRESS_MAP_UNMAP_HIGH
121   AM_RANGE (0000000, 0077777) AM_READWRITE(vram_mmap_r, vram_mmap_w)
122   AM_RANGE (0100000, 0157777) AM_ROM
123   AM_RANGE (0160000, 0160001) AM_MIRROR(03774) AM_READWRITE(vram_addr_r, vram_addr_w)
124   AM_RANGE (0160002, 0160003) AM_MIRROR(03774) AM_READWRITE(vram_data_r, vram_data_w)
125   AM_RANGE (0167770, 0167771) AM_READWRITE(status_r, status_w)
126   AM_RANGE (0167772, 0167773) AM_READWRITE8(palette_index_r, palette_index_w, 0x00ff)   // reads always return 0
127   AM_RANGE (0167772, 0167773) AM_READWRITE8(palette_data_r, palette_data_w, 0xff00)
128//   AM_RANGE (0176560, 0176567) AM_RAM   // USART2 -- host
129//   AM_RANGE (0177560, 0177567) AM_RAM   // USART3 -- keyboard
130ADDRESS_MAP_END
131
132void kcgd_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
133{
134   switch (id)
135   {
136/*
137   case TIMER_ID_VSYNC_ON:
138      m_maincpu->set_input_line(INPUT_LINE_EVNT, ASSERT_LINE);
139      break;
140
141   case TIMER_ID_VSYNC_OFF:
142      m_maincpu->set_input_line(INPUT_LINE_EVNT, CLEAR_LINE);
143      break;
144*/
145   case TIMER_ID_500HZ:
146      m_video.status ^= (1 << KCGD_STATUS_TIMER_VAL);
147      break;
148   }
149}
150
151void kcgd_state::machine_reset()
152{
153   memset(&m_video, 0, sizeof(m_video));
154}
155
156void kcgd_state::video_start()
157{
158//   screen_device *screen = machine().device<screen_device>("screen");
159
160   // 64 kwords, word size is 17 bits
161   m_videoram = auto_alloc_array(machine(), UINT32, 65536);
162
163   m_tmpclip = rectangle(0, KCGD_DISP_HORZ-1, 0, KCGD_DISP_VERT-1);
164   m_tmpbmp.allocate(KCGD_DISP_HORZ, KCGD_DISP_VERT);
165/*
166   m_vsync_on_timer = timer_alloc(TIMER_ID_VSYNC_ON);
167   m_vsync_on_timer->adjust(screen->time_until_pos(0, 0), 0, screen->frame_period());
168
169   m_vsync_off_timer = timer_alloc(TIMER_ID_VSYNC_OFF);
170   m_vsync_off_timer->adjust(screen->time_until_pos(16, 0), 0, screen->frame_period());
171*/
172   m_500hz_timer = timer_alloc(TIMER_ID_500HZ);
173   m_500hz_timer->adjust(attotime::from_hz(500), 0, attotime::from_hz(500));
174}
175
176PALETTE_INIT_MEMBER(kcgd_state, kcgd)
177{
178   for (int i = 0; i < 16; i++)
179   {
180      palette.set_pen_color(i, i?i:255, i?i:255, i?i:255);
181   }
182}
183
184/*
185   VRAM is 128K and is word-addressable, so address fits into 16 bits.
186   Low 32K of VRAM are not used to store pixel data -- XXX.
187*/
188WRITE16_MEMBER(kcgd_state::vram_addr_w)
189{
190   DBG_LOG(3,"VRAM WA", ("%06o\n", data));
191   m_video.vram_addr = data;
192}
193
194READ16_MEMBER(kcgd_state::vram_addr_r)
195{
196   DBG_LOG(3,"VRAM RA", ("\n"));
197   return m_video.vram_addr;
198}
199
200WRITE16_MEMBER(kcgd_state::vram_data_w)
201{
202   DBG_LOG(1,"VRAM W2", ("%06o <- %04XH\n", m_video.vram_addr, data));
203   m_videoram[m_video.vram_addr] = data | (BIT(m_video.control, 7) << 16);
204}
205
206READ16_MEMBER(kcgd_state::vram_data_r)
207{
208   DBG_LOG(2,"VRAM R2", ("%06o\n", m_video.vram_addr));
209   m_video.status = (m_video.status & 0xff7f) | (BIT(m_videoram[m_video.vram_addr], 16) << 7);
210   return (UINT16) (m_videoram[m_video.vram_addr] & 0xffff);
211}
212
213WRITE16_MEMBER(kcgd_state::vram_mmap_w)
214{
215   DBG_LOG(3,"VRAM W1", ("%06o <- %04XH\n", offset, data));
216   m_videoram[offset] = data | (BIT(m_video.control, 7) << 16);
217}
218
219READ16_MEMBER(kcgd_state::vram_mmap_r)
220{
221   DBG_LOG(3,"VRAM R1", ("%06o\n", offset));
222   return (UINT16) (m_videoram[offset] & 0xffff);
223}
224
225WRITE16_MEMBER(kcgd_state::status_w)
226{
227   DBG_LOG(1,"Status W", ("data %04XH (useful %02XH)\n", data, data & 0x63));
228   // bits 7 and 15 are read-only
229   m_video.status = (m_video.status & 0x8080) | (data & 0x7f7f);
230}
231
232READ16_MEMBER(kcgd_state::status_r)
233{
234   UINT16 data = m_video.status ^ (BIT(m_video.control, 6) << 7);
235   DBG_LOG(1,"Status R", ("data %04X index %d\n", data, m_video.palette_index));
236   return data;
237}
238
239WRITE8_MEMBER(kcgd_state::palette_index_w)
240{
241   m_video.control = data;
242   m_video.palette_index = ((data >> 2) & 15);
243   DBG_LOG(1,"Palette index, Control W", ("data %02XH index %d\n", data, m_video.palette_index));
244}
245
246WRITE8_MEMBER(kcgd_state::palette_data_w)
247{
248   DBG_LOG(1,"Palette data W", ("data %02XH index %d\n", data, m_video.palette_index));
249   m_video.palette[m_video.palette_index] = data;
250   m_palette->set_pen_color(m_video.palette_index,
251      85*(data & 3), 85*((data >> 2) & 3), 85*((data >> 4) & 3));
252}
253
254READ8_MEMBER(kcgd_state::palette_index_r)
255{
256   return 0;
257}
258
259READ8_MEMBER(kcgd_state::palette_data_r)
260{
261   DBG_LOG(1,"Palette data R", ("index %d\n", m_video.palette_index));
262   return m_video.palette[m_video.palette_index];
263}
264
265/*
266    Raster sizes are:
267    - 800(400)x480 in hires(lores) 60 Hz interlaced mode
268    - 800(400)x240 in hires(lores) 30 Hz progressive mode
269
270    Video memory is 17 bits wide (bit 16 indicates hi/lo res mode for each word,
271    host writes it separately (via bit 7 in 167772).
272*/
273
274void kcgd_state::draw_scanline(UINT16 *p, UINT16 offset)
275{
276   int i;
277
278   for ( i = 0; i < 100; i++ )
279   {
280      UINT32 data = m_videoram[ offset++ ];
281      if (BIT(data, 16)) {
282         *p = ( data >> 12) & 0x0F; p++;
283         *p = ( data >> 12) & 0x0F; p++;
284         *p = ( data >> 8 ) & 0x0F; p++;
285         *p = ( data >> 8 ) & 0x0F; p++;
286         *p = ( data >> 4 ) & 0x0F; p++;
287         *p = ( data >> 4 ) & 0x0F; p++;
288         *p =   data        & 0x0F; p++;
289         *p =   data        & 0x0F; p++;
290      } else {
291         *p = 5*(( data >> 14) & 0x03); p++;
292         *p = 5*(( data >> 12) & 0x03); p++;
293         *p = 5*(( data >> 10) & 0x03); p++;
294         *p = 5*(( data >> 8 ) & 0x03); p++;
295         *p = 5*(( data >> 6 ) & 0x03); p++;
296         *p = 5*(( data >> 4 ) & 0x03); p++;
297         *p = 5*(( data >> 2 ) & 0x03); p++;
298         *p = 5*(  data        & 0x03); p++;
299      }
300   }
301}
302
303TIMER_DEVICE_CALLBACK_MEMBER(kcgd_state::scanline_callback)
304{
305   UINT16 y = m_screen->vpos(), offset;
306
307   if (y < KCGD_VERT_START) return;
308   y -= KCGD_VERT_START;
309   if (y >= KCGD_DISP_VERT) return;
310
311   offset = BIT(m_video.status, KCGD_STATUS_PAGE) ? (KCGD_PAGE_1 >> 1) : (KCGD_PAGE_0 >> 1);
312
313   DBG_LOG(2,"scanline_cb", ("frame %d y %.3d page %d offset %04X *offset %04X\n",
314      m_screen->frame_number(), BIT(m_video.status, KCGD_STATUS_PAGE),
315      y, offset + y, m_videoram[offset + y]));
316
317   draw_scanline(&m_tmpbmp.pix16(y), m_videoram[offset + (KCGD_DISP_VERT-1) - y]);
318}
319
320UINT32 kcgd_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
321{
322   copybitmap(bitmap, m_tmpbmp, 0, 0, KCGD_HORZ_START, KCGD_VERT_START, cliprect);
323   return 0;
324}
325
326/* F4 Character Displayer */
327static const gfx_layout kcgd_charlayout =
328{
329   8, 10,                  /* 8x10 pixels */
330   256,                    /* 256 characters */
331   1,                      /* 1 bits per pixel */
332   { 0 },                  /* no bitplanes */
333   /* x offsets */
334   { 0, 1, 2, 3, 4, 5, 6, 7 },
335   /* y offsets */
336   { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8, 8*8, 9*8 },
337   8*10                    /* every char takes 10 bytes */
338};
339
340static GFXDECODE_START( kcgd )
341   GFXDECODE_ENTRY("maincpu", 0112236, kcgd_charlayout, 0, 1)
342GFXDECODE_END
343
344static MACHINE_CONFIG_START( kcgd, kcgd_state )
345   MCFG_CPU_ADD("maincpu", K1801VM2, XTAL_30_8MHz/4)
346   MCFG_CPU_PROGRAM_MAP(kcgd_mem)
347   MCFG_T11_INITIAL_MODE(0100000)
348
349   MCFG_TIMER_DRIVER_ADD_PERIODIC("scantimer", kcgd_state, scanline_callback, attotime::from_hz(50*28*11)) // XXX verify
350   MCFG_TIMER_START_DELAY(attotime::from_hz(XTAL_30_8MHz/KCGD_HORZ_START))
351
352   MCFG_SCREEN_ADD("screen", RASTER)
353   MCFG_SCREEN_UPDATE_DRIVER(kcgd_state, screen_update)
354   MCFG_SCREEN_RAW_PARAMS(XTAL_30_8MHz, KCGD_TOTAL_HORZ, KCGD_HORZ_START,
355      KCGD_HORZ_START+KCGD_DISP_HORZ, KCGD_TOTAL_VERT, KCGD_VERT_START,
356      KCGD_VERT_START+KCGD_DISP_VERT);
357
358   MCFG_SCREEN_PALETTE("palette")
359   MCFG_PALETTE_ADD("palette", 16)
360   MCFG_PALETTE_INIT_OWNER(kcgd_state, kcgd)
361
362   MCFG_GFXDECODE_ADD("gfxdecode", "palette", kcgd)
363#if 0
364   MCFG_DEVICE_ADD("ms7004", MS7004, 0)
365   MCFG_MS7004_TX_HANDLER(DEVWRITELINE("i8251kbd", i8251_device, write_rxd))
366
367   MCFG_DEVICE_ADD("keyboard_clock", CLOCK, 4800*16)
368   MCFG_CLOCK_SIGNAL_HANDLER(WRITELINE(kcgd_state, write_keyboard_clock))
369#endif
370MACHINE_CONFIG_END
371
372ROM_START( dvk_kcgd )
373   ROM_REGION16_BE(0x100000,"maincpu", ROMREGION_ERASE00)
374   ROM_DEFAULT_BIOS("181")
375   ROM_SYSTEM_BIOS(0, "181", "mask 181")
376   ROMX_LOAD("kr1801re2-181.bin", 0100000, 020000, CRC(acac124f) SHA1(412c3eb71bece6f791fc5a9d707cf4692fd0b45b), ROM_BIOS(1))
377   ROM_SYSTEM_BIOS(1, "182", "mask 182")
378   ROMX_LOAD("kr1801re2-182.bin", 0100000, 020000, CRC(3ca2921a) SHA1(389b30c40ed7e41dae71d58c7bff630359a48153), ROM_BIOS(2))
379ROM_END
380
381/* Driver */
382
383/*    YEAR  NAME      PARENT  COMPAT   MACHINE    INPUT    INIT                      COMPANY     FULLNAME       FLAGS */
384COMP( 1987, dvk_kcgd, 0,      0,       kcgd,      0,       driver_device,     0,     "USSR",     "DVK KCGD",    MACHINE_NOT_WORKING | MACHINE_NO_SOUND_HW )


Previous 199869 Revisions Next


© 1997-2024 The MAME Team