~ubuntu-branches/debian/sid/mame/sid

« back to all changes in this revision

Viewing changes to mess/src/mess/audio/ted7360.c

  • Committer: Package Import Robot
  • Author(s): Jordi Mallach, Jordi Mallach, Emmanuel Kasper
  • Date: 2011-12-19 22:56:27 UTC
  • mfrom: (0.1.2)
  • Revision ID: package-import@ubuntu.com-20111219225627-ub5oga1oys4ogqzm
Tags: 0.144-1
[ Jordi Mallach ]
* Fix syntax errors in DEP5 copyright file (lintian).
* Use a versioned copyright Format specification field.
* Update Vcs-* URLs.
* Move transitional packages to the new metapackages section, and make
  them priority extra.
* Remove references to GNU/Linux and MESS sources from copyright.
* Add build variables for s390x.
* Use .xz tarballs as it cuts 4MB for the upstream sources.
* Add nplayers.ini as a patch. Update copyright file to add CC-BY-SA-3.0.

[ Emmanuel Kasper ]
* New upstream release. Closes: #651538.
* Add Free Desktop compliant png icons of various sizes taken from
  the hydroxygen iconset
* Mess is now built from a new source package, to avoid possible source
  incompatibilities between mame and the mess overlay.
* Mame-tools are not built from the mame source package anymore, but
  from the mess source package

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/***************************************************************************
2
 
 
3
 
    TExt Display 7360
4
 
    PeT mess@utanet.at
5
 
 
6
 
 
7
 
    2010-02: Converted to be a device and merged video/audio emulation
8
 
 
9
 
    TODO:
10
 
      - Plenty of clean-ups
11
 
 
12
 
***************************************************************************/
13
 
/*
14
 
Metal Oxid Semicontuctor MOS
15
 
Commodore Business Machine CBM
16
 
Textured Display Ted7360
17
 
------------------------
18
 
 
19
 
7360/8360 (NTSC-M, PAL-B by same chip ?)
20
 
8365 PAL-N
21
 
8366 PAL-M
22
 
 
23
 
Ted7360 used in Commodore C16
24
 
Ted8360 used in Commodore C116/Plus4
25
 
 should be 100% software compatible with Ted7360
26
 
 
27
 
video unit (without sprites), dram controller seams to be much like vic6567
28
 
 
29
 
PAL/NTSC variants
30
 
 
31
 
functions of this chip:
32
 
 memory controller
33
 
 dram controller
34
 
 cpu clock generation with single and double clock switching
35
 
 3 timer
36
 
 1 8bit latched input
37
 
 2 channel sound/noise generator
38
 
 video controller
39
 
 interrupt controller for timer and video
40
 
 
41
 
Reasons for this document:
42
 
 document state in mess c16/plus4 emulator
43
 
 base to discuss ted7360 with others (i have no c16 computer anymore)
44
 
 
45
 
pal:
46
 
 clock 17734470
47
 
 divided by 5 for base clock (pixel clock changing edges?)
48
 
 312 lines
49
 
 50 hertz vertical refresh
50
 
 
51
 
ntsc:
52
 
 clock 14318180
53
 
 divided by 4 for base clock (pixel clock changing edges?)
54
 
 262 lines
55
 
 60 hertz vertical refresh
56
 
 
57
 
registers:
58
 
 0xff00 timer 1 low byte
59
 
 0xff01 timer 1 high byte
60
 
 0xff02 timer 2 low byte
61
 
 0xff03 timer 2 high byte
62
 
 0xff04 timer 3 low byte
63
 
 0xff05 timer 3 high byte
64
 
 0xff06
65
 
  bit 7 test?
66
 
  bit 6 ecm on
67
 
  bit 5 hires on
68
 
  bit 4 screen on
69
 
  bit 3 25 raws (0 24 raws)
70
 
  bit 2-0 vertical position
71
 
 0xff07
72
 
  bit 7 reverse off (0 on)
73
 
  bit 6 read only NTSC (0 PAL)
74
 
  bit 5 freeze horicontal position?
75
 
  bit 4 multicolor on
76
 
  bit 3 40 columns (0 38 columns)
77
 
  bit 2-0 horicontal pos
78
 
 0xff08 input latch (0 input low), write reloads latch
79
 
 0xff09 interrupt request
80
 
  7: interrupt
81
 
  6: timer 3
82
 
  5: ?
83
 
  4: timer 2
84
 
  3: timer 1
85
 
  2: lightpen
86
 
  1: rasterline
87
 
  0: 1 (asl quitting)
88
 
 0xff0a interrupt enable
89
 
  7: ?
90
 
  6: timer 3
91
 
  5: ?
92
 
  4: timer 2
93
 
  3: timer 1
94
 
  2: lightpen
95
 
  1: rasterline
96
 
  0: irq rasterline bit 8
97
 
 0xff0b
98
 
  7-0: irq rasterline 7-0
99
 
 0xff0c
100
 
  7-2: 1?
101
 
  1,0: cursorpos bit 9,8
102
 
 0xff0d cursorpos bit 7-0
103
 
 0xff0e tone channel 1: frequency 7-0
104
 
 0xff0f tone channel 2: frequency 7-0
105
 
 0xff10
106
 
  7-2: ?
107
 
  1,0: tone channel 2 bit 9,8
108
 
 0xff11
109
 
  7: sound reload
110
 
  6: tone 2 noise on (tone 2 must be off for noise)
111
 
  5: tone 2 tone on
112
 
  4: tone 1 on
113
 
  3-0: volume 8?-0
114
 
 0xff12
115
 
  7,6: ?
116
 
  5-3: bitmap address bit 15-13
117
 
  2: bitmapmemory?, charactermemory in rom (0 ram)
118
 
  1,0: tone 1 frequency bit 9,8
119
 
 0xff13
120
 
  7-2: chargen address bit 15-11
121
 
  2: chargen address bit 10 (only used when reverse is off)
122
 
  1: single clock in overscan area (0 double clock)
123
 
  0: ram (0)/rom status
124
 
 0xff14
125
 
  7-2: video address bit 15-10
126
 
  1,0: ?
127
 
 0xff15
128
 
  7: ?
129
 
  6-0: backgroundcolor
130
 
 0xff16
131
 
  7: ?
132
 
  6-0: color1
133
 
 0xff17
134
 
  7: ?
135
 
  6-0: color2
136
 
 0xff18
137
 
  7: ?
138
 
  6-0: color3
139
 
 0xff19
140
 
  7: ?
141
 
  6-0: framecolor
142
 
 0xff1a
143
 
  7-2: ?
144
 
  1,0: bitmap reload(cursorpos2) bit 9-8
145
 
 0xff1b bitmap reload bit 7-0
146
 
 0xff1c
147
 
  7-1: 1? (matrix expects this)
148
 
  0: current rasterline bit 8
149
 
 0xff1d current rasterline bit 7-0
150
 
 0xff1e
151
 
  7-0: current rastercolumn /2 (0 begin visible area?)
152
 
 0xff1f cursorblink?
153
 
  7: ?
154
 
  6-3: blink counter
155
 
  2-0: vsub
156
 
 0xff3e write switches to rom
157
 
 0xff3f write switches to dram
158
 
 
159
 
memory controller
160
 
 0x8000-0xfcff, 0xff20-0xffff
161
 
  read selection between dram and rom
162
 
 0xff3e-0xff3f write nothing (would change main memory in 16k ram c16)
163
 
 
164
 
clock generator
165
 
 in displayed area ted need 3 memory cycles to get data for video chip
166
 
 memory system runs at approximately 4 megahertz
167
 
 so only 1 megahertz is available for the cpu
168
 
 in the other area the clock can be doubled for the cpu
169
 
 
170
 
dram controller
171
 
 generator of refresh cycles
172
 
 when are these occuring?
173
 
 vic6567 in each rasterline reads 5 refresh addresses
174
 
 
175
 
sound generator
176
 
 2 channels
177
 
 channel 2 can be switched to generate noise
178
 
 volume control (0-8?)
179
 
 tone reload bit?
180
 
 samples ton/noise?
181
 
 frequency=(base clock/32)/(1024-value)
182
 
 
183
 
timer
184
 
 timer count down
185
 
 when reaching 0
186
 
  they restart from 0xffff
187
 
  set the interrupt request flag
188
 
 writing to low byte stops timer
189
 
 writing to high byte restarts timer with current value
190
 
 
191
 
interrupt controller
192
 
 interrupt sources must be enabled in the enable register to generate
193
 
 an interrupt
194
 
 request flag are set also when not enabled
195
 
 interrupt is generated when rising edge on request and enable
196
 
 quitting of interrupt is done via writing 1 to the request bit
197
 
 what happens with request interrupts when the are enabled?
198
 
 
199
 
Video part
200
 
 colors
201
 
  bit 3-0 color
202
 
   black, white, red, cyan
203
 
   purple, green, blue, yellow
204
 
   orange, light orange, pink, light cyan,
205
 
   light violett, light green, light blue, light yellow
206
 
  bit 6-4 luminance (0 dark)
207
 
  r,g,b values from 0 to 127
208
 
   taken from digitized tv screen shot
209
 
   0x06,0x01,0x03, 0x2b,0x2b,0x2b, 0x67,0x0e,0x0f, 0x00,0x3f,0x42,
210
 
   0x57,0x00,0x6d, 0x00,0x4e,0x00, 0x19,0x1c,0x94, 0x38,0x38,0x00,
211
 
   0x56,0x20,0x00, 0x4b,0x28,0x00, 0x16,0x48,0x00, 0x69,0x07,0x2f,
212
 
   0x00,0x46,0x26, 0x06,0x2a,0x80, 0x2a,0x14,0x9b, 0x0b,0x49,0x00,
213
 
 
214
 
   0x00,0x03,0x02, 0x3d,0x3d,0x3d, 0x75,0x1e,0x20, 0x00,0x50,0x4f,
215
 
   0x6a,0x10,0x78, 0x04,0x5c,0x00, 0x2a,0x2a,0xa3, 0x4c,0x47,0x00,
216
 
   0x69,0x2f,0x00, 0x59,0x38,0x00, 0x26,0x56,0x00, 0x75,0x15,0x41,
217
 
   0x00,0x58,0x3d, 0x15,0x3d,0x8f, 0x39,0x22,0xae, 0x19,0x59,0x00,
218
 
 
219
 
   0x00,0x03,0x04, 0x42,0x42,0x42, 0x7b,0x28,0x20, 0x02,0x56,0x59,
220
 
   0x6f,0x1a,0x82, 0x0a,0x65,0x09, 0x30,0x34,0xa7, 0x50,0x51,0x00,
221
 
   0x6e,0x36,0x00, 0x65,0x40,0x00, 0x2c,0x5c,0x00, 0x7d,0x1e,0x45,
222
 
   0x01,0x61,0x45, 0x1c,0x45,0x99, 0x42,0x2d,0xad, 0x1d,0x62,0x00,
223
 
 
224
 
   0x05,0x00,0x02, 0x56,0x55,0x5a, 0x90,0x3c,0x3b, 0x17,0x6d,0x72,
225
 
   0x87,0x2d,0x99, 0x1f,0x7b,0x15, 0x46,0x49,0xc1, 0x66,0x63,0x00,
226
 
   0x84,0x4c,0x0d, 0x73,0x55,0x00, 0x40,0x72,0x00, 0x91,0x33,0x5e,
227
 
   0x19,0x74,0x5c, 0x32,0x59,0xae, 0x59,0x3f,0xc3, 0x32,0x76,0x00,
228
 
 
229
 
   0x02,0x01,0x06, 0x84,0x7e,0x85, 0xbb,0x67,0x68, 0x45,0x96,0x96,
230
 
   0xaf,0x58,0xc3, 0x4a,0xa7,0x3e, 0x73,0x73,0xec, 0x92,0x8d,0x11,
231
 
   0xaf,0x78,0x32, 0xa1,0x80,0x20, 0x6c,0x9e,0x12, 0xba,0x5f,0x89,
232
 
   0x46,0x9f,0x83, 0x61,0x85,0xdd, 0x84,0x6c,0xef, 0x5d,0xa3,0x29,
233
 
 
234
 
   0x02,0x00,0x0a, 0xb2,0xac,0xb3, 0xe9,0x92,0x92, 0x6c,0xc3,0xc1,
235
 
   0xd9,0x86,0xf0, 0x79,0xd1,0x76, 0x9d,0xa1,0xff, 0xbd,0xbe,0x40,
236
 
   0xdc,0xa2,0x61, 0xd1,0xa9,0x4c, 0x93,0xc8,0x3d, 0xe9,0x8a,0xb1,
237
 
   0x6f,0xcd,0xab, 0x8a,0xb4,0xff, 0xb2,0x9a,0xff, 0x88,0xcb,0x59,
238
 
 
239
 
   0x02,0x00,0x0a, 0xc7,0xca,0xc9, 0xff,0xac,0xac, 0x85,0xd8,0xe0,
240
 
   0xf3,0x9c,0xff, 0x92,0xea,0x8a, 0xb7,0xba,0xff, 0xd6,0xd3,0x5b,
241
 
   0xf3,0xbe,0x79, 0xe6,0xc5,0x65, 0xb0,0xe0,0x57, 0xff,0xa4,0xcf,
242
 
   0x89,0xe5,0xc8, 0xa4,0xca,0xff, 0xca,0xb3,0xff, 0xa2,0xe5,0x7a,
243
 
 
244
 
   0x01,0x01,0x01, 0xff,0xff,0xff, 0xff,0xf6,0xf2, 0xd1,0xff,0xff,
245
 
   0xff,0xe9,0xff, 0xdb,0xff,0xd3, 0xfd,0xff,0xff, 0xff,0xff,0xa3,
246
 
   0xff,0xff,0xc1, 0xff,0xff,0xb2, 0xfc,0xff,0xa2, 0xff,0xee,0xff,
247
 
   0xd1,0xff,0xff, 0xeb,0xff,0xff, 0xff,0xf8,0xff, 0xed,0xff,0xbc
248
 
 
249
 
 video generation
250
 
  column counter from 0 to 39
251
 
  line counter from 0 to 199
252
 
 
253
 
  character pointer position/hires: color 0-15 position
254
 
   videoaddr+0x400+(line/8)*40+column
255
 
  color position/hires: color luminance position
256
 
   videoaddr+(line/8)*40+column
257
 
  character bitmap position
258
 
   chargenaddr+(character pointer)+(line&7)
259
 
  bitmap position
260
 
   bitmapaddr+(line/8)*40+column+(line&7)
261
 
 
262
 
 normal text mode (reverse off, ecm off, multicolor off, hires off)
263
 
  character pointer based
264
 
   fetch character pointer, fetch character bitmap, fetch color
265
 
  pixel on color (color)&0x7f
266
 
  pixel off color backgroundcolor
267
 
  blinking (synchron to cursor) (color&0x80)
268
 
 reverse text mode (reverse on, ecm off, multicolor off, hires off)
269
 
  character pointer &0x7f
270
 
  character pointer bit 7
271
 
   set
272
 
    pixel off color attribut &0x7f
273
 
    pixel on color backgroundcolor
274
 
   clear
275
 
    like normal text mode
276
 
  blinking (synchron to cursor) (color&0x80)
277
 
 multicolor text mode (ecm off, multicolor on, hires off)
278
 
  reverse ?
279
 
  attribut bit 3 character in multicolor (else monocolor character)
280
 
  pixel on color attribut 0x77
281
 
  0 backgroundcolor
282
 
  1 color1
283
 
  2 color2
284
 
  3 attribut &0x77
285
 
  (color&0x80) ?
286
 
 ecm text mode (ecm on)
287
 
  reverse ?
288
 
  multicolor ? (c64/vic6567 black display?)
289
 
  hires ? (c64/vic6567 black display?)
290
 
  character pointer &0x3f
291
 
  character pointer bit 7,6 select pixel off color
292
 
   0 backgroundcolor ?
293
 
   1 color1?
294
 
   2 color2?
295
 
   3 color3?
296
 
  (color&0x80)?
297
 
 hires (ecm off, multicolor off, hires on)
298
 
  bitmap based
299
 
   fetch bitmap, fetch color, fetch color luminance
300
 
  reverse ?
301
 
  pixel on color
302
 
   6-4: (color luminance) bit 2-0
303
 
   3-0: (color) bit 7-4
304
 
  pixel off color
305
 
   6-4: (color luminance) bit 6-4
306
 
   3-0: (color) bit 3-0
307
 
  (color) bit 7?
308
 
  (color luminance) bit 7?
309
 
 hires multicolor (ecm off, multicolor on, hires on)
310
 
  reverse ?
311
 
  0 backgroundcolor
312
 
  1
313
 
   6-4: (color luminance) bit 2-0
314
 
   3-0: (color) bit 7-4
315
 
  2
316
 
   6-4: (color luminance) bit 6-4
317
 
   3-0: (color) bit 3-0
318
 
  3 color1
319
 
  (color) bit 7?
320
 
  (color luminance) bit 7?
321
 
 scrolling support
322
 
  visible part of the display in fixed position
323
 
  columns 38 mode left 7 and right 9 pixel less displayed
324
 
   but line generation start at the same position as in columns 40 mode
325
 
  lines25 flag top and bottom 4 pixel less displayed ?
326
 
  horicontal scrolling support
327
 
   in columns 38 mode
328
 
    horicontal position 1-7: pixel later started line generation
329
 
    horicontal position 0: 8 pixels later started line generation
330
 
   in columns 40 mode ?
331
 
  vertical scrolling support
332
 
   in lines 24 mode
333
 
    vertical position 1-7: lines later started line generation
334
 
    vertical position 0: 8 lines later started line generation
335
 
   in lines 25 mode?
336
 
    vertial position 3: for correct display
337
 
 
338
 
 hardware cursor
339
 
  full 8x8 in (color) color
340
 
  flashing when in multicolor, hires ?
341
 
  flashes with about 1 hertz
342
 
  bitmap reload?
343
 
 
344
 
 rasterline/rastercolumn
345
 
  values in registers begin visible area 0
346
 
  vic 6567
347
 
   pal line 0 beginning of vertical refresh
348
 
   ntsc line 0 in bottom frame
349
 
    beginning of 25 lines screen 0x33 (24 lines screen 0x37)
350
 
    beginning of 40 columns line 0x18 (38 columns 0x1f)
351
 
 
352
 
 lightpen
353
 
  (where to store values?)
354
 
  i found a lightpen hardware description with a demo and drawing program
355
 
  lightpen must be connected to joy0 (button)
356
 
  demo program:
357
 
   disables interrupt, polles joy0 button (0xfd0d? plus 4 related???)
358
 
   and reads the rasterline value!
359
 
   so i no exact column value reachable!
360
 
*/
361
 
#include "emu.h"
362
 
#include "audio/ted7360.h"
363
 
 
364
 
 
365
 
typedef struct _ted7360_state ted7360_state;
366
 
struct _ted7360_state
367
 
{
368
 
        ted_type  type;
369
 
 
370
 
        screen_device *screen;                  // screen which sets bitmap properties
371
 
 
372
 
        UINT8 reg[0x20];
373
 
 
374
 
        bitmap_t *bitmap;
375
 
 
376
 
        int rom;
377
 
 
378
 
        int frame_count;
379
 
 
380
 
        int lines;
381
 
        int timer1_active, timer2_active, timer3_active;
382
 
        emu_timer *timer1, *timer2, *timer3;
383
 
        int cursor1;
384
 
 
385
 
        ted7360_dma_read         dma_read;
386
 
        ted7360_dma_read_rom     dma_read_rom;
387
 
        ted7360_irq              interrupt;             // c16_interrupt
388
 
        ted7360_key_cb           keyboard_cb;   // c16_read_keyboard
389
 
 
390
 
        int chargenaddr, bitmapaddr, videoaddr;
391
 
 
392
 
        int x_begin, x_end;
393
 
        int y_begin, y_end;
394
 
 
395
 
        UINT16 c16_bitmap[2], bitmapmulti[4], mono[2], monoinversed[2], multi[4], ecmcolor[2], colors[5];
396
 
 
397
 
        int rasterline, lastline;
398
 
        double rastertime;
399
 
 
400
 
 
401
 
        /* sound part */
402
 
        int tone1pos, tone2pos,
403
 
        tone1samples, tone2samples,
404
 
        noisesize,                /* number of samples */
405
 
        noisepos,         /* pos of tone */
406
 
        noisesamples;     /* count of samples to give out per tone */
407
 
 
408
 
        sound_stream *channel;
409
 
        UINT8 *noise;
410
 
};
411
 
 
412
 
/*****************************************************************************
413
 
    CONSTANTS
414
 
*****************************************************************************/
415
 
 
416
 
 
417
 
#define VERBOSE_LEVEL 0
418
 
#define DBG_LOG(N,M,A) \
419
 
        do { \
420
 
                if(VERBOSE_LEVEL >= N) \
421
 
                { \
422
 
                        if( M ) \
423
 
                                logerror("%11.6f: %-24s", device->machine().time().as_double(), (char*) M ); \
424
 
                        logerror A; \
425
 
                } \
426
 
        } while(0)
427
 
 
428
 
 
429
 
#define VREFRESHINLINES 28
430
 
 
431
 
#define TIMER1HELPER (ted7360->reg[0] | (ted7360->reg[1] << 8))
432
 
#define TIMER2HELPER (ted7360->reg[2] | (ted7360->reg[3] << 8))
433
 
#define TIMER3HELPER (ted7360->reg[4] | (ted7360->reg[5] << 8))
434
 
#define TIMER1 (TIMER1HELPER ? TIMER1HELPER : 0x10000)
435
 
#define TIMER2 (TIMER2HELPER ? TIMER2HELPER : 0x10000)
436
 
#define TIMER3 (TIMER3HELPER ? TIMER3HELPER : 0x10000)
437
 
 
438
 
#define TED7360_YPOS            40
439
 
#define RASTERLINE_2_C16(a)    ((a + ted7360->lines - TED7360_YPOS - 5) % ted7360->lines)
440
 
#define C16_2_RASTERLINE(a)    ((a + TED7360_YPOS + 5) % ted7360->lines)
441
 
#define XPOS 8
442
 
#define YPOS 8
443
 
 
444
 
#define SCREENON               (ted7360->reg[6] & 0x10)
445
 
#define TEST                   (ted7360->reg[6] & 0x80)
446
 
#define VERTICALPOS            (ted7360->reg[6] & 0x07)
447
 
#define HORICONTALPOS          (ted7360->reg[7] & 0x07)
448
 
#define ECMON                  (ted7360->reg[6] & 0x40)
449
 
#define HIRESON                (ted7360->reg[6] & 0x20)
450
 
#define MULTICOLORON           (ted7360->reg[7] & 0x10)
451
 
#define REVERSEON              (!(ted7360->reg[7] & 0x80))
452
 
 
453
 
/* hardware inverts character when bit 7 set (character taken &0x7f) */
454
 
/* instead of fetching character with higher number! */
455
 
#define LINES25     (ted7360->reg[6] & 0x08)     /* else 24 Lines */
456
 
#define LINES       (LINES25 ? 25 : 24)
457
 
#define YSIZE       (LINES * 8)
458
 
#define COLUMNS40   (ted7360->reg[7] & 0x08)     /* else 38 Columns */
459
 
#define COLUMNS     (COLUMNS40 ? 40 : 38)
460
 
#define XSIZE       (COLUMNS * 8)
461
 
 
462
 
#define INROM       (ted7360->reg[0x12] & 0x04)
463
 
#define CHARGENADDR (REVERSEON && !HIRESON && !MULTICOLORON ? ((ted7360->reg[0x13] & 0xfc) << 8) : ((ted7360->reg[0x13] & 0xf8) << 8))
464
 
#define BITMAPADDR  ((ted7360->reg[0x12] & 0x38) << 10)
465
 
#define VIDEOADDR   ((ted7360->reg[0x14] & 0xf8) << 8)
466
 
 
467
 
#define RASTERLINE  (((ted7360->reg[0xa] & 0x01) << 8) | ted7360->reg[0xb])
468
 
#define CURSOR1POS  (ted7360->reg[0xd] | ((ted7360->reg[0xc] & 0x03) << 8))
469
 
#define CURSOR2POS  (ted7360->reg[0x1b] | ((ted7360->reg[0x1a] & 0x03) << 8))
470
 
#define CURSORRATE  ((ted7360->reg[0x1f] & 0x7c) >> 2)
471
 
 
472
 
#define BACKGROUNDCOLOR (ted7360->reg[0x15] & 0x7f)
473
 
#define FOREGROUNDCOLOR (ted7360->reg[0x16] & 0x7f)
474
 
#define MULTICOLOR1     (ted7360->reg[0x17] & 0x7f)
475
 
#define MULTICOLOR2     (ted7360->reg[0x18] & 0x7f)
476
 
#define FRAMECOLOR      (ted7360->reg[0x19] & 0x7f)
477
 
 
478
 
#define TED7360_VRETRACERATE ((ted7360->type == TED7360_PAL) ? TED7360PAL_VRETRACERATE : TED7360NTSC_VRETRACERATE)
479
 
#define TED7360_CLOCK        (((ted7360->type == TED7360_PAL) ? TED7360PAL_CLOCK : TED7360NTSC_CLOCK) / 4)
480
 
#define TED7360_LINES        ((ted7360->type == TED7360_PAL) ? TED7360PAL_LINES : TED7360NTSC_LINES)
481
 
 
482
 
static attotime TEDTIME_IN_CYCLES(int pal, int cycles)
483
 
{
484
 
        double d = (double)(cycles) / (pal ? TED7360PAL_CLOCK : TED7360NTSC_CLOCK);
485
 
        return attotime::from_double(d);
486
 
}
487
 
 
488
 
static int TEDTIME_TO_CYCLES(int pal, attotime t)
489
 
{
490
 
        double d = t.as_double();
491
 
        return (int)((d) * (pal ? TED7360PAL_CLOCK : TED7360NTSC_CLOCK));
492
 
}
493
 
 
494
 
/*****************************************************************************
495
 
    INLINE FUNCTIONS
496
 
*****************************************************************************/
497
 
 
498
 
INLINE ted7360_state *get_safe_token( device_t *device )
499
 
{
500
 
        assert(device != NULL);
501
 
        assert(device->type() == TED7360);
502
 
 
503
 
        return (ted7360_state *)downcast<legacy_device_base *>(device)->token();
504
 
}
505
 
 
506
 
INLINE const ted7360_interface *get_interface( device_t *device )
507
 
{
508
 
        assert(device != NULL);
509
 
        assert(device->type() == TED7360);
510
 
 
511
 
        return (const ted7360_interface *) device->static_config();
512
 
}
513
 
 
514
 
/*****************************************************************************
515
 
    IMPLEMENTATION
516
 
*****************************************************************************/
517
 
 
518
 
static void ted7360_soundport_w( device_t *device, int offset, int data );
519
 
 
520
 
static void ted7360_set_interrupt( running_machine &machine, int mask, ted7360_state *ted7360 )
521
 
{
522
 
        /* kernel itself polls for timer 2 shot (interrupt disabled!) when cassette loading */
523
 
        ted7360->reg[9] |= mask;
524
 
        if ((ted7360->reg[0xa] & ted7360->reg[9] & 0x5e))
525
 
        {
526
 
                if (!(ted7360->reg[9] & 0x80))
527
 
                {
528
 
                        //DBG_LOG(1, "ted7360", ("irq start %.2x\n", mask));
529
 
                        ted7360->reg[9] |= 0x80;
530
 
                        ted7360->interrupt(machine, 1);
531
 
                }
532
 
        }
533
 
        ted7360->reg[9] |= mask;
534
 
}
535
 
 
536
 
static void ted7360_clear_interrupt( device_t *device, int mask )
537
 
{
538
 
        ted7360_state *ted7360 = get_safe_token(device);
539
 
 
540
 
        ted7360->reg[9] &= ~mask;
541
 
        if ((ted7360->reg[9] & 0x80) && !(ted7360->reg[9] & ted7360->reg[0xa] & 0x5e))
542
 
        {
543
 
                DBG_LOG(1, "ted7360", ("irq end %.2x\n", mask));
544
 
                ted7360->reg[9] &= ~0x80;
545
 
                ted7360->interrupt(device->machine(), 0);
546
 
        }
547
 
}
548
 
 
549
 
static int ted7360_rastercolumn( device_t *device )
550
 
{
551
 
        ted7360_state *ted7360 = get_safe_token(device);
552
 
        return (int) ((device->machine().time().as_double() - ted7360->rastertime) * TED7360_VRETRACERATE * ted7360->lines * 57 * 8 + 0.5);
553
 
}
554
 
 
555
 
static TIMER_CALLBACK(ted7360_timer_timeout)
556
 
{
557
 
        ted7360_state *ted7360 = (ted7360_state *)ptr;
558
 
        int which = param;
559
 
 
560
 
        //DBG_LOG(3, "ted7360 ", ("timer %d timeout\n", which));
561
 
        switch (which)
562
 
        {
563
 
        case 1:
564
 
                // proved by digisound of several intros like eoroidpro
565
 
                ted7360->timer1->adjust(TEDTIME_IN_CYCLES((ted7360->type == TED7360_PAL), TIMER1), 1);
566
 
                ted7360->timer1_active = 1;
567
 
                ted7360_set_interrupt(machine, 0x08, ted7360);
568
 
                break;
569
 
        case 2:
570
 
                ted7360->timer2->adjust(TEDTIME_IN_CYCLES((ted7360->type == TED7360_PAL), 0x10000), 2);
571
 
                ted7360->timer2_active = 1;
572
 
                ted7360_set_interrupt(machine, 0x10, ted7360);
573
 
                break;
574
 
        case 3:
575
 
                ted7360->timer3->adjust(TEDTIME_IN_CYCLES((ted7360->type == TED7360_PAL), 0x10000), 3);
576
 
                ted7360->timer3_active = 1;
577
 
                ted7360_set_interrupt(machine, 0x40, ted7360);
578
 
                break;
579
 
        }
580
 
}
581
 
 
582
 
static void ted7360_draw_character( device_t *device, int ybegin, int yend, int ch, int yoff, int xoff, UINT16 *color )
583
 
{
584
 
        ted7360_state *ted7360 = get_safe_token(device);
585
 
        int y, code;
586
 
 
587
 
        for (y = ybegin; y <= yend; y++)
588
 
        {
589
 
                if (INROM)
590
 
                        code = ted7360->dma_read_rom(device->machine(), ted7360->chargenaddr + ch * 8 + y);
591
 
                else
592
 
                        code = ted7360->dma_read(device->machine(), ted7360->chargenaddr + ch * 8 + y);
593
 
 
594
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 0 + xoff) = color[code >> 7];
595
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 1 + xoff) = color[(code >> 6) & 1];
596
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 2 + xoff) = color[(code >> 5) & 1];
597
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 3 + xoff) = color[(code >> 4) & 1];
598
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 4 + xoff) = color[(code >> 3) & 1];
599
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 5 + xoff) = color[(code >> 2) & 1];
600
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 6 + xoff) = color[(code >> 1) & 1];
601
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 7 + xoff) = color[code & 1];
602
 
        }
603
 
}
604
 
 
605
 
static void ted7360_draw_character_multi( device_t *device, int ybegin, int yend, int ch, int yoff, int xoff )
606
 
{
607
 
        ted7360_state *ted7360 = get_safe_token(device);
608
 
        int y, code;
609
 
 
610
 
        for (y = ybegin; y <= yend; y++)
611
 
        {
612
 
                if (INROM)
613
 
                        code = ted7360->dma_read_rom(device->machine(), ted7360->chargenaddr + ch * 8 + y);
614
 
                else
615
 
                        code = ted7360->dma_read(device->machine(), ted7360->chargenaddr + ch * 8 + y);
616
 
 
617
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 0 + xoff) =
618
 
                        *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 1 + xoff) = ted7360->multi[code >> 6];
619
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 2 + xoff) =
620
 
                        *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 3 + xoff) = ted7360->multi[(code >> 4) & 3];
621
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 4 + xoff) =
622
 
                        *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 5 + xoff) = ted7360->multi[(code >> 2) & 3];
623
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 6 + xoff) =
624
 
                        *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 7 + xoff) = ted7360->multi[code & 3];
625
 
        }
626
 
}
627
 
 
628
 
static void ted7360_draw_bitmap( device_t *device, int ybegin, int yend, int ch, int yoff, int xoff )
629
 
{
630
 
        ted7360_state *ted7360 = get_safe_token(device);
631
 
        int y, code;
632
 
 
633
 
        for (y = ybegin; y <= yend; y++)
634
 
        {
635
 
                code = ted7360->dma_read(device->machine(), ted7360->bitmapaddr + ch * 8 + y);
636
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 0 + xoff) = ted7360->c16_bitmap[code >> 7];
637
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 1 + xoff) = ted7360->c16_bitmap[(code >> 6) & 1];
638
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 2 + xoff) = ted7360->c16_bitmap[(code >> 5) & 1];
639
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 3 + xoff) = ted7360->c16_bitmap[(code >> 4) & 1];
640
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 4 + xoff) = ted7360->c16_bitmap[(code >> 3) & 1];
641
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 5 + xoff) = ted7360->c16_bitmap[(code >> 2) & 1];
642
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 6 + xoff) = ted7360->c16_bitmap[(code >> 1) & 1];
643
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 7 + xoff) = ted7360->c16_bitmap[code & 1];
644
 
        }
645
 
}
646
 
 
647
 
static void ted7360_draw_bitmap_multi( device_t *device, int ybegin, int yend, int ch, int yoff, int xoff )
648
 
{
649
 
        ted7360_state *ted7360 = get_safe_token(device);
650
 
        int y, code;
651
 
 
652
 
        for (y = ybegin; y <= yend; y++)
653
 
        {
654
 
                code = ted7360->dma_read(device->machine(), ted7360->bitmapaddr + ch * 8 + y);
655
 
 
656
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 0 + xoff) =
657
 
                        *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 1 + xoff) = ted7360->bitmapmulti[code >> 6];
658
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 2 + xoff) =
659
 
                        *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 3 + xoff) = ted7360->bitmapmulti[(code >> 4) & 3];
660
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 4 + xoff) =
661
 
                        *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 5 + xoff) = ted7360->bitmapmulti[(code >> 2) & 3];
662
 
                *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 6 + xoff) =
663
 
                        *BITMAP_ADDR16(ted7360->bitmap, y + yoff, 7 + xoff) = ted7360->bitmapmulti[code & 3];
664
 
        }
665
 
}
666
 
 
667
 
#ifndef memset16
668
 
static void *memset16 (void *dest, int value, size_t size)
669
 
{
670
 
        register int i;
671
 
 
672
 
        for (i = 0; i < size; i++)
673
 
                ((short *) dest)[i] = value;
674
 
        return dest;
675
 
}
676
 
#endif
677
 
 
678
 
static void ted7360_draw_cursor( device_t *device, int ybegin, int yend, int yoff, int xoff, int color )
679
 
{
680
 
        ted7360_state *ted7360 = get_safe_token(device);
681
 
        int y;
682
 
 
683
 
        for (y = ybegin; y <= yend; y++)
684
 
        {
685
 
                memset16(BITMAP_ADDR16(ted7360->bitmap, yoff + y, xoff), color, 8);
686
 
        }
687
 
}
688
 
 
689
 
static void ted7360_drawlines( device_t *device, int first, int last )
690
 
{
691
 
        ted7360_state *ted7360 = get_safe_token(device);
692
 
        int line, vline, end;
693
 
        int attr, ch, c1, c2, ecm;
694
 
        int offs, yoff, xoff, ybegin, yend, xbegin, xend;
695
 
        int i;
696
 
 
697
 
        ted7360->lastline = last;
698
 
 
699
 
        /* top part of display not rastered */
700
 
        first -= TED7360_YPOS;
701
 
        last -= TED7360_YPOS;
702
 
        if ((first >= last) || (last <= 0))
703
 
                return;
704
 
        if (first < 0)
705
 
                first = 0;
706
 
 
707
 
        if (!SCREENON)
708
 
        {
709
 
                for (line = first; (line < last) && (line < ted7360->bitmap->height); line++)
710
 
                        memset16(BITMAP_ADDR16(ted7360->bitmap, line, 0), 0, ted7360->bitmap->width);
711
 
                return;
712
 
        }
713
 
 
714
 
        if (COLUMNS40)
715
 
                xbegin = XPOS, xend = xbegin + 320;
716
 
        else
717
 
                xbegin = XPOS + 7, xend = xbegin + 304;
718
 
 
719
 
        if (last < ted7360->y_begin)
720
 
                end = last;
721
 
        else
722
 
                end = ted7360->y_begin + YPOS;
723
 
        {
724
 
                for (line = first; line < end; line++)
725
 
                        memset16(BITMAP_ADDR16(ted7360->bitmap, line, 0), FRAMECOLOR, ted7360->bitmap->width);
726
 
        }
727
 
        if (LINES25)
728
 
                vline = line - ted7360->y_begin - YPOS;
729
 
        else
730
 
                vline = line - ted7360->y_begin - YPOS + 8 - VERTICALPOS;
731
 
 
732
 
        if (last < ted7360->y_end + YPOS)
733
 
                end = last;
734
 
        else
735
 
                end = ted7360->y_end + YPOS;
736
 
 
737
 
        for (; line < end; vline = (vline + 8) & ~7, line = line + 1 + yend - ybegin)
738
 
        {
739
 
                offs = (vline >> 3) * 40;
740
 
                ybegin = vline & 7;
741
 
                yoff = line - ybegin;
742
 
                yend = (yoff + 7 < end) ? 7 : (end - yoff - 1);
743
 
                /* rendering 39 characters */
744
 
                /* left and right borders are overwritten later */
745
 
 
746
 
                for (xoff = ted7360->x_begin + XPOS; xoff < ted7360->x_end + XPOS; xoff += 8, offs++)
747
 
                {
748
 
                        if (HIRESON)
749
 
                        {
750
 
                                ch = ted7360->dma_read(device->machine(), (ted7360->videoaddr | 0x400) + offs);
751
 
                                attr = ted7360->dma_read(device->machine(), ted7360->videoaddr + offs);
752
 
                                c1 = ((ch >> 4) & 0xf) | (attr << 4);
753
 
                                c2 = (ch & 0xf) | (attr & 0x70);
754
 
                                ted7360->bitmapmulti[1] = ted7360->c16_bitmap[1] = c1 & 0x7f;
755
 
                                ted7360->bitmapmulti[2] = ted7360->c16_bitmap[0] = c2 & 0x7f;
756
 
                                if (MULTICOLORON)
757
 
                                {
758
 
                                        ted7360_draw_bitmap_multi(device, ybegin, yend, offs, yoff, xoff);
759
 
                                }
760
 
                                else
761
 
                                {
762
 
                                        ted7360_draw_bitmap(device, ybegin, yend, offs, yoff, xoff);
763
 
                                }
764
 
                        }
765
 
                        else
766
 
                        {
767
 
                                ch = ted7360->dma_read(device->machine(), (ted7360->videoaddr | 0x400) + offs);
768
 
                                attr = ted7360->dma_read(device->machine(), ted7360->videoaddr + offs);
769
 
                                // levente harsfalvi's docu says cursor off in ecm and multicolor
770
 
                                if (ECMON)
771
 
                                {
772
 
                                        // hardware reverse off
773
 
                                        ecm = ch >> 6;
774
 
                                        ted7360->ecmcolor[0] = ted7360->colors[ecm];
775
 
                                        ted7360->ecmcolor[1] = attr & 0x7f;
776
 
                                        ted7360_draw_character(device, ybegin, yend, ch & ~0xc0, yoff, xoff, ted7360->ecmcolor);
777
 
                                }
778
 
                                else if (MULTICOLORON)
779
 
                                {
780
 
                                        // hardware reverse off
781
 
                                        if (attr & 8)
782
 
                                        {
783
 
                                                ted7360->multi[3] = attr & 0x77;
784
 
                                                ted7360_draw_character_multi(device, ybegin, yend, ch, yoff, xoff);
785
 
                                        }
786
 
                                        else
787
 
                                        {
788
 
                                                ted7360->mono[1] = attr & 0x7f;
789
 
                                                ted7360_draw_character(device, ybegin, yend, ch, yoff, xoff, ted7360->mono);
790
 
                                        }
791
 
                                }
792
 
                                else if (ted7360->cursor1 && (offs == CURSOR1POS))
793
 
                                {
794
 
                                        ted7360_draw_cursor(device, ybegin, yend, yoff, xoff, attr & 0x7f);
795
 
                                }
796
 
                                else if (REVERSEON && (ch & 0x80))
797
 
                                {
798
 
                                        ted7360->monoinversed[0] = attr & 0x7f;
799
 
                                        if (ted7360->cursor1 && (attr & 0x80))
800
 
                                                ted7360_draw_cursor(device, ybegin, yend, yoff, xoff, ted7360->monoinversed[0]);
801
 
                                        else
802
 
                                                ted7360_draw_character(device, ybegin, yend, ch & ~0x80, yoff, xoff, ted7360->monoinversed);
803
 
                                }
804
 
                                else
805
 
                                {
806
 
                                        ted7360->mono[1] = attr & 0x7f;
807
 
                                        if (ted7360->cursor1 && (attr & 0x80))
808
 
                                                ted7360_draw_cursor(device, ybegin, yend, yoff, xoff, ted7360->mono[0]);
809
 
                                        else
810
 
                                                ted7360_draw_character(device, ybegin, yend, ch, yoff, xoff, ted7360->mono);
811
 
                                }
812
 
                        }
813
 
                }
814
 
 
815
 
                for (i = ybegin; i <= yend; i++)
816
 
                {
817
 
                        memset16(BITMAP_ADDR16(ted7360->bitmap, yoff + i, 0), FRAMECOLOR, xbegin);
818
 
                        memset16(BITMAP_ADDR16(ted7360->bitmap, yoff + i, xend), FRAMECOLOR, ted7360->bitmap->width - xend);
819
 
                }
820
 
        }
821
 
 
822
 
        if (last < ted7360->bitmap->height)
823
 
                end = last;
824
 
        else
825
 
                end = ted7360->bitmap->height;
826
 
 
827
 
        for (; line < end; line++)
828
 
        {
829
 
                memset16(BITMAP_ADDR16(ted7360->bitmap, line, 0), FRAMECOLOR, ted7360->bitmap->width);
830
 
        }
831
 
}
832
 
 
833
 
 
834
 
WRITE8_DEVICE_HANDLER( ted7360_port_w )
835
 
{
836
 
        ted7360_state *ted7360 = get_safe_token(device);
837
 
        int old;
838
 
 
839
 
        if ((offset != 8) && ((offset < 0x15) || (offset > 0x19)))
840
 
        {
841
 
                DBG_LOG(1, "ted7360_port_w", ("%.2x:%.2x\n", offset, data));
842
 
        }
843
 
 
844
 
        switch (offset)
845
 
        {
846
 
        case 0xe:
847
 
        case 0xf:
848
 
        case 0x10:
849
 
        case 0x11:
850
 
        case 0x12:
851
 
                ted7360_soundport_w(device, offset, data);
852
 
                break;
853
 
        }
854
 
        switch (offset)
855
 
        {
856
 
        case 0:                                            /* stop timer 1 */
857
 
                ted7360->reg[offset] = data;
858
 
 
859
 
                if (ted7360->timer1_active)
860
 
                {
861
 
                        ted7360->reg[1] = TEDTIME_TO_CYCLES((ted7360->type == TED7360_PAL), ted7360->timer1->remaining()) >> 8;
862
 
                        ted7360->timer1->reset();
863
 
                        ted7360->timer1_active = 0;
864
 
                }
865
 
                break;
866
 
        case 1:                                            /* start timer 1 */
867
 
                ted7360->reg[offset] = data;
868
 
                ted7360->timer1->adjust(TEDTIME_IN_CYCLES((ted7360->type == TED7360_PAL), TIMER1), 1);
869
 
                ted7360->timer1_active = 1;
870
 
                break;
871
 
        case 2:                                            /* stop timer 2 */
872
 
                ted7360->reg[offset] = data;
873
 
                if (ted7360->timer2_active)
874
 
                {
875
 
                        ted7360->reg[3] = TEDTIME_TO_CYCLES((ted7360->type == TED7360_PAL), ted7360->timer2->remaining()) >> 8;
876
 
                        ted7360->timer2->reset();
877
 
                        ted7360->timer2_active = 0;
878
 
                }
879
 
                break;
880
 
        case 3:                                            /* start timer 2 */
881
 
                ted7360->reg[offset] = data;
882
 
                ted7360->timer2->adjust(TEDTIME_IN_CYCLES((ted7360->type == TED7360_PAL), TIMER2), 2);
883
 
                ted7360->timer2_active = 1;
884
 
                break;
885
 
        case 4:                                            /* stop timer 3 */
886
 
                ted7360->reg[offset] = data;
887
 
                if (ted7360->timer3_active)
888
 
                {
889
 
                        ted7360->reg[5] = TEDTIME_TO_CYCLES((ted7360->type == TED7360_PAL), ted7360->timer3->remaining()) >> 8;
890
 
                        ted7360->timer3->reset();
891
 
                        ted7360->timer3_active = 0;
892
 
                }
893
 
                break;
894
 
        case 5:                                            /* start timer 3 */
895
 
                ted7360->reg[offset] = data;
896
 
                ted7360->timer3->adjust(TEDTIME_IN_CYCLES((ted7360->type == TED7360_PAL), TIMER3), 3);
897
 
                ted7360->timer3_active = 1;
898
 
                break;
899
 
        case 6:
900
 
                if (ted7360->reg[offset] != data)
901
 
                {
902
 
                        ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
903
 
                        ted7360->reg[offset] = data;
904
 
                        if (LINES25)
905
 
                        {
906
 
                                ted7360->y_begin = 0;
907
 
                                ted7360->y_end = ted7360->y_begin + 200;
908
 
                        }
909
 
                        else
910
 
                        {
911
 
                                ted7360->y_begin = 4;
912
 
                                ted7360->y_end = ted7360->y_begin + 192;
913
 
                        }
914
 
                        ted7360->chargenaddr = CHARGENADDR;
915
 
                }
916
 
                break;
917
 
        case 7:
918
 
                if (ted7360->reg[offset] != data)
919
 
                {
920
 
                        ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
921
 
                        ted7360->reg[offset] = data;
922
 
                        if (COLUMNS40)
923
 
                        {
924
 
                                ted7360->x_begin = 0;
925
 
                                ted7360->x_end = ted7360->x_begin + 320;
926
 
                        }
927
 
                        else
928
 
                        {
929
 
                                ted7360->x_begin = HORICONTALPOS;
930
 
                                ted7360->x_end = ted7360->x_begin + 320;
931
 
                        }
932
 
                        DBG_LOG(3, "ted7360_port_w", ("%s %s\n", data & 0x40 ? "ntsc" : "pal", data & 0x20 ? "hori freeze" : ""));
933
 
                        ted7360->chargenaddr = CHARGENADDR;
934
 
                }
935
 
                break;
936
 
        case 8:
937
 
                ted7360->reg[offset] = ted7360->keyboard_cb(device->machine(), data);
938
 
                break;
939
 
        case 9:
940
 
                if (data & 0x08)
941
 
                        ted7360_clear_interrupt(device, 8);
942
 
                if (data & 0x10)
943
 
                        ted7360_clear_interrupt(device, 0x10);
944
 
                if (data & 0x40)
945
 
                        ted7360_clear_interrupt(device, 0x40);
946
 
                if (data & 0x02)
947
 
                        ted7360_clear_interrupt(device, 2);
948
 
                break;
949
 
        case 0xa:
950
 
                old = data;
951
 
                ted7360->reg[offset] = data | 0xa0;
952
 
#if 0
953
 
                ted7360->reg[9] = (ted7360->reg[9] & 0xa1) | (ted7360->reg[9] & data & 0x5e);
954
 
                if (ted7360->reg[9] & 0x80)
955
 
                        ted7360_clear_interrupt(device, 0);
956
 
#endif
957
 
                if ((data ^ old) & 1)
958
 
                {
959
 
                        /* DBG_LOG(1,"set rasterline hi",("soll:%d\n",RASTERLINE)); */
960
 
                }
961
 
                break;
962
 
        case 0xb:
963
 
                if (data != ted7360->reg[offset])
964
 
                {
965
 
                        ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
966
 
                        ted7360->reg[offset] = data;
967
 
                        /*  DBG_LOG(1,"set rasterline lo",("soll:%d\n",RASTERLINE)); */
968
 
                }
969
 
                break;
970
 
        case 0xc:
971
 
        case 0xd:
972
 
                if (ted7360->reg[offset] != data)
973
 
                {
974
 
                        ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
975
 
                        ted7360->reg[offset] = data;
976
 
                }
977
 
                break;
978
 
        case 0x12:
979
 
                if (ted7360->reg[offset] != data)
980
 
                {
981
 
                        ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
982
 
                        ted7360->reg[offset] = data;
983
 
                        ted7360->bitmapaddr = BITMAPADDR;
984
 
                        ted7360->chargenaddr = CHARGENADDR;
985
 
                        DBG_LOG(3, "ted7360_port_w", ("bitmap %.4x %s\n",  BITMAPADDR, INROM ? "rom" : "ram"));
986
 
                }
987
 
                break;
988
 
        case 0x13:
989
 
                if (ted7360->reg[offset] != data)
990
 
                {
991
 
                        ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
992
 
                        ted7360->reg[offset] = data;
993
 
                        ted7360->chargenaddr = CHARGENADDR;
994
 
                        DBG_LOG(3, "ted7360_port_w", ("chargen %.4x %s %d\n", CHARGENADDR, data & 2 ? "" : "doubleclock", data & 1));
995
 
                }
996
 
                break;
997
 
        case 0x14:
998
 
                if (ted7360->reg[offset] != data)
999
 
                {
1000
 
                        ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
1001
 
                        ted7360->reg[offset] = data;
1002
 
                        ted7360->videoaddr = VIDEOADDR;
1003
 
                        DBG_LOG(3, "ted7360_port_w", ("videoram %.4x\n", VIDEOADDR));
1004
 
                }
1005
 
                break;
1006
 
        case 0x15:                                                 /* backgroundcolor */
1007
 
                if (ted7360->reg[offset] != data)
1008
 
                {
1009
 
                        ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
1010
 
                        ted7360->reg[offset] = data;
1011
 
                        ted7360->monoinversed[1] = ted7360->mono[0] = ted7360->bitmapmulti[0] = ted7360->multi[0] = ted7360->colors[0] = BACKGROUNDCOLOR;
1012
 
                }
1013
 
                break;
1014
 
        case 0x16:                                                 /* foregroundcolor */
1015
 
                if (ted7360->reg[offset] != data)
1016
 
                {
1017
 
                        ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
1018
 
                        ted7360->reg[offset] = data;
1019
 
                        ted7360->bitmapmulti[3] = ted7360->multi[1] = ted7360->colors[1] = FOREGROUNDCOLOR;
1020
 
                }
1021
 
                break;
1022
 
        case 0x17:                                                 /* multicolor 1 */
1023
 
                if (ted7360->reg[offset] != data)
1024
 
                {
1025
 
                        ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
1026
 
                        ted7360->reg[offset] = data;
1027
 
                        ted7360->multi[2] = ted7360->colors[2] = MULTICOLOR1;
1028
 
                }
1029
 
                break;
1030
 
        case 0x18:                                                 /* multicolor 2 */
1031
 
                if (ted7360->reg[offset] != data)
1032
 
                {
1033
 
                        ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
1034
 
                        ted7360->reg[offset] = data;
1035
 
                        ted7360->colors[3] = MULTICOLOR2;
1036
 
                }
1037
 
                break;
1038
 
        case 0x19:                                                 /* framecolor */
1039
 
                if (ted7360->reg[offset] != data)
1040
 
                {
1041
 
                        ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
1042
 
                        ted7360->reg[offset] = data;
1043
 
                        ted7360->colors[4] = FRAMECOLOR;
1044
 
                }
1045
 
                break;
1046
 
        case 0x1c:
1047
 
                ted7360->reg[offset] = data;               /*? */
1048
 
                DBG_LOG(1, "ted7360_port_w", ("write to rasterline high %.2x\n",
1049
 
                                                                           data));
1050
 
                break;
1051
 
        case 0x1f:
1052
 
                ted7360->reg[offset] = data;
1053
 
                DBG_LOG(1, "ted7360_port_w", ("write to cursorblink %.2x\n", data));
1054
 
                break;
1055
 
        default:
1056
 
                ted7360->reg[offset] = data;
1057
 
                break;
1058
 
        }
1059
 
}
1060
 
 
1061
 
READ8_DEVICE_HANDLER( ted7360_port_r )
1062
 
{
1063
 
        ted7360_state *ted7360 = get_safe_token(device);
1064
 
        int val = 0;
1065
 
 
1066
 
        switch (offset)
1067
 
        {
1068
 
        case 0:
1069
 
                if (ted7360->timer1)
1070
 
                        val = TEDTIME_TO_CYCLES((ted7360->type == TED7360_PAL), ted7360->timer1->remaining()) & 0xff;
1071
 
                else
1072
 
                        val = ted7360->reg[offset];
1073
 
                break;
1074
 
        case 1:
1075
 
                if (ted7360->timer1)
1076
 
                        val = TEDTIME_TO_CYCLES((ted7360->type == TED7360_PAL), ted7360->timer1->remaining()) >> 8;
1077
 
                else
1078
 
                        val = ted7360->reg[offset];
1079
 
                break;
1080
 
        case 2:
1081
 
                if (ted7360->timer2)
1082
 
                        val = TEDTIME_TO_CYCLES((ted7360->type == TED7360_PAL), ted7360->timer2->remaining()) & 0xff;
1083
 
                else
1084
 
                        val = ted7360->reg[offset];
1085
 
                break;
1086
 
        case 3:
1087
 
                if (ted7360->timer2)
1088
 
                        val = TEDTIME_TO_CYCLES((ted7360->type == TED7360_PAL), ted7360->timer2->remaining()) >> 8;
1089
 
                else
1090
 
                        val = ted7360->reg[offset];
1091
 
                break;
1092
 
        case 4:
1093
 
                if (ted7360->timer3)
1094
 
                        val = TEDTIME_TO_CYCLES((ted7360->type == TED7360_PAL), ted7360->timer3->remaining()) & 0xff;
1095
 
                else
1096
 
                        val = ted7360->reg[offset];
1097
 
                break;
1098
 
        case 5:
1099
 
                if (ted7360->timer3)
1100
 
                        val = TEDTIME_TO_CYCLES((ted7360->type == TED7360_PAL), ted7360->timer3->remaining()) >> 8;
1101
 
                else
1102
 
                        val = ted7360->reg[offset];
1103
 
                break;
1104
 
        case 7:
1105
 
                val = (ted7360->reg[offset] & ~0x40);
1106
 
                if (ted7360->type == TED7360_NTSC)
1107
 
                        val |= 0x40;
1108
 
                break;
1109
 
        case 9:
1110
 
                val = ted7360->reg[offset] | 1;
1111
 
                break;
1112
 
        case 0xa:
1113
 
                val = ted7360->reg[offset];
1114
 
                break;
1115
 
        case 0xb:
1116
 
                val = ted7360->reg[offset];
1117
 
                break;
1118
 
        case 0x0c:
1119
 
                val = ted7360->reg[offset] |= 0xfc;
1120
 
                break;
1121
 
        case 0x13:
1122
 
                val = ted7360->reg[offset] & ~1;
1123
 
                if (ted7360->rom)
1124
 
                        val |= 1;
1125
 
                break;
1126
 
        case 0x1c:                                                 /*rasterline */
1127
 
                ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
1128
 
                val = ((RASTERLINE_2_C16(ted7360->rasterline) & 0x100) >> 8) | 0xfe;    /* expected by matrix */
1129
 
                break;
1130
 
        case 0x1d:                                                 /*rasterline */
1131
 
                ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
1132
 
                val = RASTERLINE_2_C16(ted7360->rasterline) & 0xff;
1133
 
                break;
1134
 
        case 0x1e:                                                 /*rastercolumn */
1135
 
                val = ted7360_rastercolumn(device) / 2; /* pengo >=0x99 */
1136
 
                break;
1137
 
        case 0x1f:
1138
 
                val = ((ted7360->rasterline & 7) << 4) | (ted7360->reg[offset] & 0x0f);
1139
 
                DBG_LOG(1, "ted7360_port_w", ("read from cursorblink %.2x\n", val));
1140
 
                break;
1141
 
        default:
1142
 
                val = ted7360->reg[offset];
1143
 
                break;
1144
 
        }
1145
 
 
1146
 
        if ((offset != 8) && (offset >= 6) && (offset != 0x1c) && (offset != 0x1d) && (offset != 9) && ((offset < 0x15) || (offset > 0x19)))
1147
 
        {
1148
 
                DBG_LOG(1, "ted7360_port_r", ("%.2x:%.2x\n", offset, val));
1149
 
        }
1150
 
 
1151
 
        return val;
1152
 
}
1153
 
 
1154
 
WRITE_LINE_DEVICE_HANDLER( ted7360_rom_switch_w )
1155
 
{
1156
 
        ted7360_state *ted7360 = get_safe_token(device);
1157
 
        ted7360->rom = state;
1158
 
}
1159
 
 
1160
 
READ_LINE_DEVICE_HANDLER( ted7360_rom_switch_r )
1161
 
{
1162
 
        ted7360_state *ted7360 = get_safe_token(device);
1163
 
        return ted7360->rom;
1164
 
}
1165
 
 
1166
 
void ted7360_frame_interrupt_gen( device_t *device )
1167
 
{
1168
 
        ted7360_state *ted7360 = get_safe_token(device);
1169
 
 
1170
 
        if ((ted7360->reg[0x1f] & 0xf) >= 0x0f)
1171
 
        {
1172
 
                /*  if (ted7360->frame_count >= CURSORRATE) */
1173
 
                ted7360->cursor1 ^= 1;
1174
 
                ted7360->reg[0x1f] &= ~0xf;
1175
 
                ted7360->frame_count = 0;
1176
 
        }
1177
 
        else
1178
 
                ted7360->reg[0x1f]++;
1179
 
}
1180
 
 
1181
 
void ted7360_raster_interrupt_gen( device_t *device )
1182
 
{
1183
 
        ted7360_state *ted7360 = get_safe_token(device);
1184
 
 
1185
 
        ted7360->rasterline++;
1186
 
        ted7360->rastertime = device->machine().time().as_double();
1187
 
        if (ted7360->rasterline >= ted7360->lines)
1188
 
        {
1189
 
                ted7360->rasterline = 0;
1190
 
                ted7360_drawlines(device, ted7360->lastline, TED7360_LINES);
1191
 
                ted7360->lastline = 0;
1192
 
        }
1193
 
 
1194
 
        if (ted7360->rasterline == C16_2_RASTERLINE(RASTERLINE))
1195
 
        {
1196
 
                ted7360_drawlines(device, ted7360->lastline, ted7360->rasterline);
1197
 
                ted7360_set_interrupt(device->machine(), 2, ted7360);
1198
 
        }
1199
 
}
1200
 
 
1201
 
UINT32 ted7360_video_update( device_t *device, bitmap_t *bitmap, const rectangle *cliprect )
1202
 
{
1203
 
        ted7360_state *ted7360 = get_safe_token(device);
1204
 
 
1205
 
        copybitmap(bitmap, ted7360->bitmap, 0, 0, 0, 0, cliprect);
1206
 
        return 0;
1207
 
}
1208
 
 
1209
 
 
1210
 
/* Sound emulation */
1211
 
 
1212
 
#define NOISE_BUFFER_SIZE_SEC 5
1213
 
 
1214
 
#define TONE_ON         (!(ted7360->reg[0x11] & 0x80))          /* or tone update!? */
1215
 
#define TONE1_ON        ((ted7360->reg[0x11] & 0x10))
1216
 
#define TONE1_VALUE     (ted7360->reg[0x0e] | ((ted7360->reg[0x12] & 3) << 8))
1217
 
#define TONE2_ON        ((ted7360->reg[0x11] & 0x20))
1218
 
#define TONE2_VALUE     (ted7360->reg[0x0f] | ((ted7360->reg[0x10] & 3) << 8))
1219
 
#define VOLUME          (ted7360->reg[0x11] & 0x0f)
1220
 
#define NOISE_ON        (ted7360->reg[0x11] & 0x40)
1221
 
 
1222
 
/*
1223
 
 * pal 111860.781
1224
 
 * ntsc 111840.45
1225
 
 */
1226
 
#define TONE_FREQUENCY(reg)         ((TED7360_CLOCK >> 3) / (1024 - reg))
1227
 
#define TONE_FREQUENCY_MIN          (TONE_FREQUENCY(0))
1228
 
#define NOISE_FREQUENCY             (TED7360_CLOCK / 8 / (1024 - TONE2_VALUE))
1229
 
#define NOISE_FREQUENCY_MAX         (TED7360_CLOCK / 8)
1230
 
 
1231
 
 
1232
 
static void ted7360_soundport_w( device_t *device, int offset, int data )
1233
 
{
1234
 
        ted7360_state *ted7360 = get_safe_token(device);
1235
 
 
1236
 
        // int old = ted7360->reg[offset];
1237
 
        ted7360->channel->update();
1238
 
 
1239
 
        switch (offset)
1240
 
        {
1241
 
        case 0x0e:
1242
 
        case 0x12:
1243
 
                if (offset == 0x12)
1244
 
                        ted7360->reg[offset] = (ted7360->reg[offset] & ~3) | (data & 3);
1245
 
                else
1246
 
                        ted7360->reg[offset] = data;
1247
 
 
1248
 
                ted7360->tone1samples = device->machine().sample_rate() / TONE_FREQUENCY (TONE1_VALUE);
1249
 
                DBG_LOG(1, "ted7360", ("tone1 %d %d sample:%d\n", TONE1_VALUE, TONE_FREQUENCY(TONE1_VALUE), ted7360->tone1samples));
1250
 
                break;
1251
 
 
1252
 
        case 0xf:
1253
 
        case 0x10:
1254
 
                ted7360->reg[offset] = data;
1255
 
 
1256
 
                ted7360->tone2samples = device->machine().sample_rate() / TONE_FREQUENCY (TONE2_VALUE);
1257
 
                DBG_LOG (1, "ted7360", ("tone2 %d %d sample:%d\n", TONE2_VALUE, TONE_FREQUENCY(TONE2_VALUE), ted7360->tone2samples));
1258
 
 
1259
 
                ted7360->noisesamples = (int) ((double) NOISE_FREQUENCY_MAX * device->machine().sample_rate() * NOISE_BUFFER_SIZE_SEC / NOISE_FREQUENCY);
1260
 
                DBG_LOG (1, "ted7360", ("noise %d sample:%d\n", NOISE_FREQUENCY, ted7360->noisesamples));
1261
 
 
1262
 
                if (!NOISE_ON || ((double) ted7360->noisepos / ted7360->noisesamples >= 1.0))
1263
 
                        ted7360->noisepos = 0;
1264
 
                break;
1265
 
 
1266
 
        case 0x11:
1267
 
                ted7360->reg[offset] = data;
1268
 
                DBG_LOG(1, "ted7360", ("%s volume %d, %s %s %s\n", TONE_ON?"on":"off",
1269
 
                                       VOLUME, TONE1_ON?"tone1":"", TONE2_ON?"tone2":"", NOISE_ON?"noise":""));
1270
 
 
1271
 
                if (!TONE_ON||!TONE1_ON) ted7360->tone1pos = 0;
1272
 
                if (!TONE_ON||!TONE2_ON) ted7360->tone2pos = 0;
1273
 
                if (!TONE_ON||!NOISE_ON) ted7360->noisepos = 0;
1274
 
                break;
1275
 
        }
1276
 
}
1277
 
 
1278
 
 
1279
 
/************************************/
1280
 
/* Sound handler update             */
1281
 
/************************************/
1282
 
 
1283
 
static STREAM_UPDATE( ted7360_update )
1284
 
{
1285
 
        ted7360_state *ted7360 = get_safe_token(device);
1286
 
        int i, v, a;
1287
 
        stream_sample_t *buffer = outputs[0];
1288
 
 
1289
 
        for (i = 0; i < samples; i++)
1290
 
        {
1291
 
                v = 0;
1292
 
 
1293
 
                if (TONE1_ON)
1294
 
                {
1295
 
                        if (ted7360->tone1pos <= ted7360->tone1samples / 2 || !TONE_ON)
1296
 
                                v += 0x2ff; // depends on the volume between sound and noise
1297
 
 
1298
 
                        ted7360->tone1pos++;
1299
 
 
1300
 
                        if (ted7360->tone1pos > ted7360->tone1samples)
1301
 
                                ted7360->tone1pos = 0;
1302
 
                }
1303
 
 
1304
 
                if (TONE2_ON || NOISE_ON )
1305
 
                {
1306
 
                        if (TONE2_ON)
1307
 
                        {                                                  /*higher priority ?! */
1308
 
                                if (ted7360->tone2pos <= ted7360->tone2samples / 2 || !TONE_ON)
1309
 
                                        v += 0x2ff;
1310
 
 
1311
 
                                ted7360->tone2pos++;
1312
 
 
1313
 
                                if (ted7360->tone2pos > ted7360->tone2samples)
1314
 
                                        ted7360->tone2pos = 0;
1315
 
                        }
1316
 
                        else
1317
 
                        {
1318
 
                                v += ted7360->noise[(int) ((double) ted7360->noisepos * ted7360->noisesize / ted7360->noisesamples)];
1319
 
                                ted7360->noisepos++;
1320
 
 
1321
 
                                if ((double) ted7360->noisepos / ted7360->noisesamples >= 1.0)
1322
 
                                        ted7360->noisepos = 0;
1323
 
                        }
1324
 
                }
1325
 
 
1326
 
                a = VOLUME;
1327
 
                if (a > 8)
1328
 
                        a = 8;
1329
 
 
1330
 
                v = v * a;
1331
 
 
1332
 
                buffer[i] = v;
1333
 
        }
1334
 
}
1335
 
 
1336
 
/*****************************************************************************
1337
 
    DEVICE INTERFACE
1338
 
*****************************************************************************/
1339
 
 
1340
 
/************************************/
1341
 
/* Sound handler start              */
1342
 
/************************************/
1343
 
 
1344
 
static void ted7360_sound_start( device_t *device )
1345
 
{
1346
 
        ted7360_state *ted7360 = get_safe_token(device);
1347
 
        int i;
1348
 
 
1349
 
        ted7360->channel = device->machine().sound().stream_alloc(*device, 0, 1, device->machine().sample_rate(), 0, ted7360_update);
1350
 
 
1351
 
        /* buffer for fastest played sample for 5 second so we have enough data for min 5 second */
1352
 
        ted7360->noisesize = NOISE_FREQUENCY_MAX * NOISE_BUFFER_SIZE_SEC;
1353
 
        ted7360->noise = auto_alloc_array(device->machine(), UINT8, ted7360->noisesize);
1354
 
 
1355
 
        {
1356
 
                int noiseshift = 0x7ffff8;
1357
 
                UINT8 data;
1358
 
 
1359
 
                for (i = 0; i < ted7360->noisesize; i++)
1360
 
                {
1361
 
                        data = 0;
1362
 
                        if (noiseshift & 0x400000)
1363
 
                                data |= 0x80;
1364
 
                        if (noiseshift & 0x100000)
1365
 
                                data |= 0x40;
1366
 
                        if (noiseshift & 0x010000)
1367
 
                                data |= 0x20;
1368
 
                        if (noiseshift & 0x002000)
1369
 
                                data |= 0x10;
1370
 
                        if (noiseshift & 0x000800)
1371
 
                                data |= 0x08;
1372
 
                        if (noiseshift & 0x000080)
1373
 
                                data |= 0x04;
1374
 
                        if (noiseshift & 0x000010)
1375
 
                                data |= 0x02;
1376
 
                        if (noiseshift & 0x000004)
1377
 
                                data |= 0x01;
1378
 
                        ted7360->noise[i] = data;
1379
 
                        if (((noiseshift & 0x400000) == 0) != ((noiseshift & 0x002000) == 0))
1380
 
                                noiseshift = (noiseshift << 1) | 1;
1381
 
                        else
1382
 
                                noiseshift <<= 1;
1383
 
                }
1384
 
        }
1385
 
}
1386
 
 
1387
 
static DEVICE_START( ted7360 )
1388
 
{
1389
 
        ted7360_state *ted7360 = get_safe_token(device);
1390
 
        const ted7360_interface *intf = (ted7360_interface *)device->static_config();
1391
 
        int width, height;
1392
 
 
1393
 
        ted7360->screen = device->machine().device<screen_device>(intf->screen);
1394
 
        width = ted7360->screen->width();
1395
 
        height = ted7360->screen->height();
1396
 
 
1397
 
        ted7360->bitmap = auto_bitmap_alloc(device->machine(), width, height, BITMAP_FORMAT_INDEXED16);
1398
 
 
1399
 
        ted7360->type = intf->type;
1400
 
 
1401
 
        ted7360->dma_read = intf->dma_read;
1402
 
        ted7360->dma_read_rom = intf->dma_read_rom;
1403
 
        ted7360->interrupt = intf->irq;
1404
 
 
1405
 
        ted7360->keyboard_cb = intf->keyb_cb;
1406
 
 
1407
 
        ted7360->timer1 = device->machine().scheduler().timer_alloc(FUNC(ted7360_timer_timeout), ted7360);
1408
 
        ted7360->timer2 = device->machine().scheduler().timer_alloc(FUNC(ted7360_timer_timeout), ted7360);
1409
 
        ted7360->timer3 = device->machine().scheduler().timer_alloc(FUNC(ted7360_timer_timeout), ted7360);
1410
 
 
1411
 
        ted7360_sound_start(device);
1412
 
 
1413
 
        device->save_item(NAME(ted7360->reg));
1414
 
 
1415
 
        device->save_item(NAME(*ted7360->bitmap));
1416
 
 
1417
 
        device->save_item(NAME(ted7360->rom));
1418
 
        device->save_item(NAME(ted7360->lines));
1419
 
        device->save_item(NAME(ted7360->chargenaddr));
1420
 
        device->save_item(NAME(ted7360->bitmapaddr));
1421
 
        device->save_item(NAME(ted7360->videoaddr));
1422
 
        device->save_item(NAME(ted7360->timer1_active));
1423
 
        device->save_item(NAME(ted7360->timer2_active));
1424
 
        device->save_item(NAME(ted7360->timer3_active));
1425
 
        device->save_item(NAME(ted7360->cursor1));
1426
 
        device->save_item(NAME(ted7360->rasterline));
1427
 
        device->save_item(NAME(ted7360->lastline));
1428
 
        device->save_item(NAME(ted7360->rastertime));
1429
 
        device->save_item(NAME(ted7360->frame_count));
1430
 
        device->save_item(NAME(ted7360->x_begin));
1431
 
        device->save_item(NAME(ted7360->x_end));
1432
 
        device->save_item(NAME(ted7360->y_begin));
1433
 
        device->save_item(NAME(ted7360->y_end));
1434
 
 
1435
 
        device->save_item(NAME(ted7360->c16_bitmap));
1436
 
        device->save_item(NAME(ted7360->bitmapmulti));
1437
 
        device->save_item(NAME(ted7360->mono));
1438
 
        device->save_item(NAME(ted7360->monoinversed));
1439
 
        device->save_item(NAME(ted7360->multi));
1440
 
        device->save_item(NAME(ted7360->ecmcolor));
1441
 
        device->save_item(NAME(ted7360->colors));
1442
 
 
1443
 
        device->save_item(NAME(ted7360->tone1pos));
1444
 
        device->save_item(NAME(ted7360->tone2pos));
1445
 
        device->save_item(NAME(ted7360->tone1samples));
1446
 
        device->save_item(NAME(ted7360->tone2samples));
1447
 
        device->save_item(NAME(ted7360->noisepos));
1448
 
        device->save_item(NAME(ted7360->noisesamples));
1449
 
}
1450
 
 
1451
 
static DEVICE_RESET( ted7360 )
1452
 
{
1453
 
        ted7360_state *ted7360 = get_safe_token(device);
1454
 
 
1455
 
        memset(ted7360->reg, 0, ARRAY_LENGTH(ted7360->reg));
1456
 
 
1457
 
        ted7360->rom = 1;       // FIXME: at start should be RAM or ROM? old c16 code set it to ROM at init: is it correct?
1458
 
 
1459
 
        ted7360->lines = TED7360_LINES;
1460
 
        ted7360->chargenaddr = ted7360->bitmapaddr = ted7360->videoaddr = 0;
1461
 
        ted7360->timer1_active = ted7360->timer2_active = ted7360->timer3_active = 0;
1462
 
        ted7360->cursor1 = 0;
1463
 
 
1464
 
        ted7360->rasterline = 0;
1465
 
        ted7360->lastline = 0;
1466
 
 
1467
 
        ted7360->rastertime = 0.0;
1468
 
 
1469
 
        ted7360->frame_count = 0;
1470
 
 
1471
 
        ted7360->x_begin = 0;
1472
 
        ted7360->x_end = 0;
1473
 
        ted7360->y_begin = 0;
1474
 
        ted7360->y_end = 0;
1475
 
 
1476
 
        memset(ted7360->c16_bitmap, 0, ARRAY_LENGTH(ted7360->c16_bitmap));
1477
 
        memset(ted7360->bitmapmulti, 0, ARRAY_LENGTH(ted7360->bitmapmulti));
1478
 
        memset(ted7360->mono, 0, ARRAY_LENGTH(ted7360->mono));
1479
 
        memset(ted7360->monoinversed, 0, ARRAY_LENGTH(ted7360->monoinversed));
1480
 
        memset(ted7360->multi, 0, ARRAY_LENGTH(ted7360->multi));
1481
 
        memset(ted7360->ecmcolor, 0, ARRAY_LENGTH(ted7360->ecmcolor));
1482
 
        memset(ted7360->colors, 0, ARRAY_LENGTH(ted7360->colors));
1483
 
 
1484
 
        ted7360->tone1pos = 0;
1485
 
        ted7360->tone2pos = 0;
1486
 
        ted7360->tone1samples = 1;
1487
 
        ted7360->tone2samples = 1;
1488
 
        ted7360->noisepos = 0;
1489
 
        ted7360->noisesamples = 1;
1490
 
}
1491
 
 
1492
 
 
1493
 
/*-------------------------------------------------
1494
 
    device definition
1495
 
-------------------------------------------------*/
1496
 
 
1497
 
static const char DEVTEMPLATE_SOURCE[] = __FILE__;
1498
 
 
1499
 
#define DEVTEMPLATE_ID(p,s)                             p##ted7360##s
1500
 
#define DEVTEMPLATE_FEATURES                    DT_HAS_START | DT_HAS_RESET
1501
 
#define DEVTEMPLATE_NAME                                "CBM TED 7360"
1502
 
#define DEVTEMPLATE_FAMILY                              "CBM Text Display Video Chip"
1503
 
#include "devtempl.h"
1504
 
 
1505
 
DEFINE_LEGACY_SOUND_DEVICE(TED7360, ted7360);