/
taito_f2.cpp
5666 lines (4548 loc) · 268 KB
/
taito_f2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// license:BSD-3-Clause
// copyright-holders:David Graves, Bryan McPhail, Brad Oliver, Andrew Prime, Brian Troha, Nicola Salmoria
// thanks-to:Richard Bush
/***************************************************************************
Taito F2 System
driver by David Graves, Bryan McPhail, Brad Oliver, Andrew Prime, Brian
Troha, Nicola Salmoria with some initial help from Richard Bush
The Taito F2 system is a fairly flexible hardware platform. The main board
supports three 64x64 tiled scrolling background planes of 8x8 tiles, and a
powerful sprite engine capable of handling all the video chores by itself
(used in e.g. Super Space Invaders). The front tilemap has characters which
are generated in RAM for maximum versatility (fading effects etc.).
The expansion board can have additional gfx chip e.g. for a zooming/rotating
tilemap, or additional tilemap planes.
Sound is handled by a Z80 with a YM2610 connected to it.
The memory map for each of the games is similar but shuffled around.
Notes:
- Metal Black has secret command to select stage.
Start the machine with holding service switch.
Then push 1p start, 1p start, 1p start, service SW, 1p start
while error message is displayed.
(This also works in many of the other games. Use in Don Doko Don to play
an extra set of fifty levels.)
Custom chips
------------
The old version of the F2 main board (larger) has
TC0100SCN (tilemaps)
TC0200OBJ+TC0210FBC (sprites)
TC0140SYT (sound communication & other stuff)
The new version has
TC0100SCN (tilemaps)
TC0540OBN+TC0520TBC (sprites)
TC0530SYC (sound communication & other stuff)
I/O Priority / Palette Additional gfx Other
--------- ------------------- ----------------------- ----------------------------
finalb TC0220IOC TC0110PCR TC0070RGB
dondokod TC0220IOC TC0360PRI TC0260DAR TC0280GRD(x2)(zoom/rot)
megab TC0220IOC TC0360PRI TC0260DAR TC0030CMD(C-Chip protection)
thundfox TC0220IOC TC0360PRI TC0260DAR TC0100SCN (so it has two)
cameltry TC0220IOC TC0360PRI TC0260DAR TC0280GRD(x2)(zoom/rot)
qtorimon TC0220IOC TC0110PCR TC0070RGB
liquidk TC0220IOC TC0360PRI TC0260DAR
quizhq TMP82C265 TC0110PCR TC0070RGB
ssi TC0510NIO TC0260DAR
gunfront TC0510NIO TC0360PRI TC0260DAR
growl TMP82C265 TC0360PRI TC0260DAR TC0190FMC(sprite banking?)
mjnquest TC0110PCR TC0070RGB
footchmp TE7750 TC0360PRI TC0260DAR TC0480SCP(tilemaps) TC0190FMC(sprite banking?)
koshien TC0510NIO TC0360PRI TC0260DAR
yuyugogo TC0510NIO TC0260DAR
ninjak TE7750 TC0360PRI TC0260DAR TC0190FMC(sprite banking?)
solfigtr TMP82C265 TC0360PRI TC0260DAR TC0190FMC(sprite banking?)
qzquest TC0510NIO TC0260DAR
pulirula TC0510NIO TC0360PRI TC0260DAR TC0430GRW(zoom/rot)
metalb TC0510NIO TC0360PRI TC0260DAR TC0480SCP(tilemaps)
qzchikyu TC0510NIO TC0260DAR
yesnoj TMP82C265 TC0260DAR TC8521AP(RTC)
deadconx TE7750 TC0360PRI TC0260DAR TC0480SCP(tilemaps) TC0190FMC(sprite banking?)
dinorex TC0510NIO TC0360PRI TC0260DAR
qjinsei TC0510NIO TC0360PRI TC0260DAR
qcrayon TC0510NIO TC0360PRI TC0260DAR
qcrayon2 TC0510NIO TC0360PRI TC0260DAR
driftout TC0510NIO TC0360PRI TC0260DAR TC0430GRW(zoom/rot)
A complete list of Taito Games can be still accessed with archive.org:
http://web.archive.org/web/20010502131808/www.taito.co.jp/game-history/
F2 Motherboard ( Big ) K1100432A, J1100183A
(Small) K1100608A, J1100242A
Apr.1989 Final Blow (B82, M4300123A, K1100433A)
Jul.1989 Don Doko Don (B95, M4300131A, K1100454A, J1100195A)
Oct.1989 Mega Blast (C11)
Feb.1990 Quiz Torimonochou (C41, K1100554A)
Apr.1990 Cameltry (C38, M4300167A, K1100556A)
Jul.1990 Quiz H.Q. (C53, K1100594A)
Aug.1990 Thunder Fox (C28, M4300181A, K1100580A) (exists in F1 version too)
Sep.1990 Liquid Kids/Mizubaku Daibouken (C49, K1100593A)
Nov.1990 MJ-12/Super Space Invaders (C64, M4300195A, K1100616A, J1100248A)
Jan.1991 Gun Frontier (C71, M4300199A, K1100625A, K1100629A(overseas))
Feb.1991 Growl/Runark (C74, M4300210A, K1100639A)
Mar.1991 Hat Trick Hero/Euro Football Championship (C80, K11J0646A)
Mar.1991 Yuu-yu no Quiz de Go!Go! (C83, K11J0652A)
Apr.1991 Ah Eikou no Koshien (C81, M43J0214A, K11J654A)
Apr.1991 Ninja Kids (C85, M43J0217A, K11J0659A)
May.1991 Mahjong Quest (C77, K1100637A, K1100637B)
Jul.1991 Quiz Quest (C92, K11J0678A)
Sep.1991 Metal Black (D12)
Oct.1991 Drift Out (Visco) (M43X0241A, K11X0695A)
Nov.1991 PuLiRuLa (C98, M43J0225A, K11J0672A)
Feb.1992 Quiz Chikyu Boueigun (D19, K11J0705A)
Jul.1992 Dead Connection (D28, K11J0715A)
Nov.1992 Dinorex (D39, K11J0254A)
Mar.1993 Quiz Jinsei Gekijou (D48, M43J0262A, K11J0742A)
Aug.1993 Quiz Crayon Shinchan (D55, K11J0758A)
Dec.1993 Crayon Shinchan Orato Asobo (D63, M43J0276A, K11J0779A)
Mar.1992 Yes.No. Shinri Tokimeki Chart (Fortune teller machine) (D20, K11J0706B)
Thunder Fox, Drift Out, "Quiz Crayon Shinchan", and "Crayon Shinchan
Orato Asobo" has "Not F2" version PCB.
Foreign version of Cameltry uses different hardware (B89's PLD,
K1100573A, K1100574A).
Sprite extension area types
===========================
These games need a special value for f2_spriteext:
Yuyugogo = 1
Pulirula = 2
Dinorex = 3
Quiz Crayon 1&2 = 3
Quiz Jinsei = 3
(all other games need it to be zero)
TODO Lists
==========
- The sprite system is still partly a mystery, and not an accurate emulation.
A lot of sprite glitches are caused by data in sprite ram not being correct,
part from one frame and part from the previous one. There has to be some
buffering inside the chip but it's not clear how. See below the irq section
for a long list of observations on sprite glitches.
Other limitations include: misplaced tile of the zooming title in Qcrayon
(the one on the yellow background in attract); sprites when you get a home
run in Koshien are often out on x axis by 1 pixel.
- TC0480SCP emulation (footchmp, metalb, deadconx) has slight inaccuracies.
Zoomed layers and zoomed pixel rows are not precisely positioned.
- DIPS, still many unknown
- Restored save states on some games tend to hang.
- All non-quiz games except Solfigtr have 2 country sets dumped: if 1 byte diff
then create the third set.
Don Doko Don
------------
Roz layer is one pixel out vertically when screen flipped.
Cameltry (cameltrya)
--------
Alt version with YM2203 and M6295
Sound frequencies may be incorrect
Gun Frontier
------------
There are mask sprites used on the waterfall in the first round
of attract demo, however it's not clear what they should mask since
there don't seem to be sprites below them. Shadow maybe?
(BM161104 - Fixed)
Pulirula
--------
In level 3, the mask sprites used for the door are misaligned by one pixel to
the left.
(BM100705 - Not a bug - various alignment problems seem to be confirmed from a real pcb).
Shadows appear to have some kind of flicker effect on real pcb - not emulated/understood.
Metal Black
-----------
Tilemap screenflip support has an issue: blue planet early in attract
should be 1 pixel left.
Sprite emulation issues may be responsible for minor glitches on the
"bolts" on round 4 boss ship: some sprite/tilemap lag creeps in.
Missing two blend effects: there's a sun sprite underneath tilemaps
in round 1; and the boss sprite crosses under the tilemaps at start
of round 5 finale.
(BM161104 - Fixed)
Yesnoj
------
Input mapping incomplete. There's a 0x01 one which only seems to be
used in printer [printer test?] mode. It seems to be a printer status
input. With the value currently returned, it sounds an alarm and says
[Japanese trans.] "Error detected on the printer. Call machine operator."
Update (2008.10.09) Printer shall now be correct but it's still not clear
how the inputs are physically connected and what the are supposed to do.
[Coin lockout/ctr?]
Calendar / Time in "test mode" always reset to default settings.
Quiz Crayon 2
-------------
There should be a highlight circle around the player while it moves on the
map. This is done by a sprite which doesn't have priority over the
background. This is probably the same thing as the waterfall in Gun Frontier.
(BM161104 - Fixed)
Driftout
--------
Sprites are 1 pixel too far right in screenflip.
Roz layer is around 4 pixels too far down in screenflip.
PCB Layout
----------
K11T0658A
NINJA KIDS
|----------------------------------------------|
|PAL PAL C85-12*.49 C85-15*.50 DSWA DSWB |
|68000P12 C85-06.49 C85-07.50 OSC1 TE7750 |
| |
| 84256 84256 C85-03.65 |
| MB3771 |
| TC0190FMC TC0100SCN TC51832 |
|C85-02.19 84256 84256 TC51832 J|
|C85-01.17 HM3-65764KS A|
| M|
|TC51832 TC51832 TC0360PRI M|
|TC51832 TC51832 TC0540OBN TC0260DAR A|
|TC51832 TC51832 |
|TC51832 TC51832 TC0520TBC |
|TC51832 TC51832 OSC2 Z80A |
|TC51832 TC51832 TC0530SYC |
|TC51832 TC51832 C85-05.33 C85-14.54 |
| C85-04.31 YM2610 YM3016 |
|----------------------------------------------|
Notes:
OSC1 = 26.686MHz
OSC2 = 24.000MHz
68000 clock: 12.000MHz (24 / 2)
Z80 clock: 4.000MHz (24 / 6)
YM2610 clock: 8.000MHz (24 / 3)
Vsync: 60Hz
***************************************************************************/
#include "emu.h"
#include "taito_f2.h"
#include "taitoipt.h"
#include "taitosnd.h"
#include "cpu/m68000/m68000.h"
#include "cpu/z80/z80.h"
#include "machine/rp5c01.h"
#include "machine/te7750.h"
#include "machine/watchdog.h"
#include "sound/okim6295.h"
#include "sound/ymopn.h"
#include "speaker.h"
/**********************************************************
GAME INPUTS
**********************************************************/
void taitof2_state::coin_nibble_w(u8 data)
{
machine().bookkeeping().coin_lockout_w(0, ~data & 0x01);
machine().bookkeeping().coin_lockout_w(1, ~data & 0x02);
machine().bookkeeping().coin_counter_w(0, data & 0x04);
machine().bookkeeping().coin_counter_w(1, data & 0x08);
}
void taitof2_state::growl_coin_word_w(u8 data)/* what about coins 3&4 ?? */
{
machine().bookkeeping().coin_lockout_w(0, ~data & 0x01);
machine().bookkeeping().coin_lockout_w(1, ~data & 0x02);
machine().bookkeeping().coin_counter_w(0, data & 0x04);
machine().bookkeeping().coin_counter_w(1, data & 0x08);
}
void taitof2_state::_4p_coin_word_w(u8 data)
{
machine().bookkeeping().coin_lockout_w(0, ~data & 0x01);
machine().bookkeeping().coin_lockout_w(1, ~data & 0x02);
machine().bookkeeping().coin_lockout_w(2, ~data & 0x04);
machine().bookkeeping().coin_lockout_w(3, ~data & 0x08);
machine().bookkeeping().coin_counter_w(0, data & 0x10);
machine().bookkeeping().coin_counter_w(1, data & 0x20);
machine().bookkeeping().coin_counter_w(2, data & 0x40);
machine().bookkeeping().coin_counter_w(3, data & 0x80);
}
u16 taitof2_state::cameltry_paddle_r(offs_t offset)
{
int curr, res = 0xff;
switch (offset)
{
case 0x00:
curr = m_io_paddle[0]->read();
res = curr - m_last[0];
m_last[0] = curr;
return res;
case 0x02:
curr = m_io_paddle[1]->read();
res = curr - m_last[1];
m_last[1] = curr;
return res;
}
logerror("CPU #0 PC %06x: warning - read unmapped paddle offset %06x\n", m_maincpu->pc(), offset);
return 0;
}
u16 taitof2_state::mjnquest_dsw_r(offs_t offset)
{
switch (offset)
{
case 0x00:
{
return (m_io_in[5]->read() << 8) + m_io_dswa->read(); /* DSW A + coin */
}
case 0x01:
{
return (m_io_in[6]->read() << 8) + m_io_dswb->read(); /* DSW B + coin */
}
}
logerror("CPU #0 PC %06x: warning - read unmapped dsw_r offset %06x\n", m_maincpu->pc(), offset);
return 0xff;
}
u16 taitof2_state::mjnquest_input_r()
{
switch (m_mjnquest_input)
{
case 0x01:
return m_io_in[0]->read();
case 0x02:
return m_io_in[1]->read();
case 0x04:
return m_io_in[2]->read();
case 0x08:
return m_io_in[3]->read();
case 0x10:
return m_io_in[4]->read();
}
logerror("CPU #0 mjnquest_input %06x: warning - read unknown input %06x\n", m_maincpu->pc(), m_mjnquest_input);
return 0xff;
}
void taitof2_state::mjnquest_inputselect_w(u16 data)
{
m_mjnquest_input = (data >> 6);
}
/******************************************************************
INTERRUPTS (still a WIP)
The are two interrupt request signals: VBL and DMA. DMA comes
from the sprite generator (maybe when it has copied the data to
a private buffer, or rendered the current frame, or who knows what
else).
The requests are mapped through a PAL so no hardwiring, but the PAL
could be the same across all the games. All the games have just two
valid vectors, IRQ5 and IRQ6.
It seems that usually VBL maps to IRQ5 and DMA to IRQ6. However
there are jumpers on the board allowing to swap the two interrupt
request signals, so this could explain a need for certain games to
have them in the opposite order.
There are lots of sprite glitches in many games because the sprite ram
is often updated in two out-of-sync chunks. I am almost sure there is
some partial buffering going on in the sprite chip, and DMA has to
play a part in it.
sprite ctrl regs interrupts & sprites
0006 000a 8006 800a
---------------------- -----------------------------------------------
finalb 8000 0300 0000 0000 Needs partial buffering like dondokod to avoid glitches
dondokod 8000 0000/8 0000 0000 IRQ6 just sets a flag. IRQ5 waits for that flag,
toggles ctrl register 0000<->0008, and copies bytes
0 and 8 *ONLY* of sprite data (code, color, flip,
ctrl). The other bytes of sprite data (coordinates
and zoom) are updated by the main program.
Caching sprite data and using bytes 0 and 8 from
previous frame and the others from *TWO* frames
before is enough to get glitch-free sprites that seem
to be perfectly in sync with scrolling (check the tree
mouths during level change).
thundfox 8000 0000 0000 0000 IRQ6 copies bytes 0 and 8 *ONLY* of sprite data (code,
color, flip, ctrl). The other bytes of sprite data
(coordinates and zoom) are updated (I think) by the
main program.
The same sprite data caching that works for dondokod
improves sprites, but there are still glitches related
to zoom (check third round of attract mode). Those
glitches can be fixed by buffering also the zoom ctrl
byte.
Moreover, sprites are not in perfect sync with the
background (sometimes they are one frame behind, but
not always).
qtorimon 8000 0000 0000 0000 IRQ6 does some stuff but doesn't seem to deal with
sprites. IRQ5 copies bytes 0, 8 *AND ALSO 2* of sprite
data in one routine, and immediately after that the
remaining bytes 4 and 6 in another routine, without
doing, it seems, any waiting inbetween.
Nevertheless, separated sprite data caching like in
dondokod is still required to avoid glitches.
liquidk 8000 0000/8 0000 0000 Same as dondokod. An important difference is that
the sprite ctrl register doesn't toggle every frame
(because the handler can't complete the frame in
time?). This can be seen easily in the attract mode,
where sprite glitches appear.
Correctly handling the ctrl register and sprite data
caching seems to be vital to avoid sprite glitches.
quizhq 8000 0000 0000 0000 Both IRQ5 and IRQ6 do stuff, I haven't investigated.
There is a very subtle sprite glitch if sprite data
buffering is not used: the blinking INSERT COIN in
the right window will get moved as garbage chars on
the left window score and STOCK for one frame when
INSERT COINS disappears from the right. This happens
because bytes 0 and 8 of the sprite data are one
frame behind and haven't been cleared yet.
ssi 8000 0000 0000 0000 IRQ6 does nothing. IRQ5 copies bytes 0 and 8 *ONLY*
of sprite data (code, color, flip, ctrl). The other
bytes of sprite data (coordinates and zoom) are
updated by the main program.
The same sprite data caching that works for dondokod
avoids major glitches, but I'm not sure it's working
right when the big butterfly (time bonus) is on
screen (it flickers on and off every frame).
gunfront 8000 1000/1 8001 1000/1 The toggling bit in the control register selects the
sprite bank used. It normally toggles every frame but
sticks for two frame when lots of action is going on
(see smart bombs in attract mode) and glitches will
appear if it is not respected.
IRQ6 writes the sprite ctrl registers, and also writes
related data to the sprites at 9033e0/90b3e0. The
active one gets 8000/8001 in byte 6 and 1001/1000 in
byte 10, while the other gets 0. Note that the value
in byte 10 is inverted from the active bank, as if it
were a way to tell the sprite hardware "after this, go
to the other bank".
Note also that IRQ6 isn't the only one writing to the
sprite ctrl registers, this is done also in the parts
that actually change the sprite data (I think it's
main program, not interrupt), so it's not clear who's
"in charge". Actually it seems that what IRQ6 writes
is soon overwritten so that what I outlined above
regarding 9033e0/90b3e0 is no longer true, and they
are no longer in sync with the ctrl registers, messing
up smart bombs.
There don't seem to be other glitches even without
sprite data buffering.
growl 8000 0000 8001 0001 IRQ6 just sets a flag. I haven't investigated who
updates the sprite ram.
This game uses sprite banks like gunfront, but unlike
gunfront it doesn't change the ctrl registers. What it
does is change the sprites at 903210/90b210; 8000/8001
is always written in byte 6, while byte 10 receives
the active bank (1000 or 1001). There are also end of
list markers placed before that though, and those seem
to always match what's stored in the ctrl registers
(8000 1000 for the first bank and 8001 1001 for the
second).
There don't seem to be sprite glitches even without
sprite data buffering, but sprites are not in sync with
the background.
mjnquest 8000 0800/8 0000 0000
footchmp 8000 0000 8001 0001 IRQ6 just sets a flag (and writes to an unknown memory
location).
This games uses sprite banks as well, this time it
writes markers at 2033e0/20b3e0, it always writes
1000/1001 to byte 10, while it writes 8000 or 8001 to
byte 6 depending on the active bank. This is the exact
opposite of growl...
hthero
koshien 8000 0000 8001 0001 Another game using banks.The markers are again at
9033e0/90b3e0 but this time byte 6 receives 9000/9001.
Byte 10 is 1000 or 1001 depending on the active bank.
yuyugogo 8000 0800/8 0000 0000
ninjak 8000 0000 8001 0001 uses banks
solfigtr 8000 0000 8001 0001 uses banks
qzquest 8000 0000 0000 0000 Separated sprite data caching like in dondokod is
required to avoid glitches.
pulirula 8000 0000 8001 0001 uses banks
qzchikyu 8000 0000 0000 0000 With this game there are glitches and the sprite data
caching done in dondokod does NOT fix them.
deadconx 8/9000 0000/1 8/9001 0000/1 I guess it's not a surprise that this game uses banks
in yet another different way.
dinorex 8000 0000 8001 0001 uses banks
driftout 8000 0000/8 0000 0000 The first control changes from 8000 to 0000 at the end
of the attract demo and seems to stay that way.
******************************************************************/
TIMER_CALLBACK_MEMBER(taitof2_state::trigger_int6)
{
m_maincpu->set_input_line(6, HOLD_LINE);
}
INTERRUPT_GEN_MEMBER(taitof2_state::interrupt)
{
m_int6_timer->adjust(m_maincpu->cycles_to_attotime(500));
device.execute().set_input_line(5, HOLD_LINE);
}
INTERRUPT_GEN_MEMBER(taitof2_state::megab_interrupt)
{
interrupt(device);
m_cchip->ext_interrupt(ASSERT_LINE);
m_cchip_irq_clear->adjust(attotime::zero);
}
TIMER_DEVICE_CALLBACK_MEMBER(taitof2_state::cchip_irq_clear_cb)
{
m_cchip->ext_interrupt(CLEAR_LINE);
}
/****************************************************************
SOUND
****************************************************************/
void taitof2_state::sound_bankswitch_w(u8 data)
{
m_audiobank->set_entry(data & 7);
#ifdef MAME_DEBUG
if ((data & 7) > 2)
logerror("CPU #1 switch to ROM bank %06x: should only happen if Z80 prg rom is 128K!\n",data & 7);
#endif
}
u8 taitof2_state::driveout_sound_command_r()
{
m_audiocpu->set_input_line(0, CLEAR_LINE);
// logerror("sound IRQ OFF (sound command=%02x)\n", m_driveout_sound_latch);
return m_driveout_sound_latch;
}
void taitof2_state::oki_bank_w(u8 data)
{
if (data & 4)
{
m_okibank->set_entry((data & 3));
}
}
void taitof2_state::driveout_sound_command_w(offs_t offset, u8 data)
{
if (offset == 0)
{
m_nibble = data & 1;
}
else
{
if (m_nibble == 0)
{
m_driveout_sound_latch = (data & 0x0f) | (m_driveout_sound_latch & 0xf0);
}
else
{
m_driveout_sound_latch = ((data << 4) & 0xf0) | (m_driveout_sound_latch & 0x0f);
m_audiocpu->set_input_line(0, ASSERT_LINE);
}
}
}
/***********************************************************
MEMORY STRUCTURES
***********************************************************/
void taitof2_state::finalb_map(address_map &map)
{
map(0x000000, 0x03ffff).rom();
map(0x100000, 0x10ffff).ram();
map(0x200000, 0x200007).rw(m_tc0110pcr, FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::word_w)); /* palette */
map(0x300000, 0x30000f).rw(m_tc0220ioc, FUNC(tc0220ioc_device::read), FUNC(tc0220ioc_device::write)).umask16(0x00ff);
map(0x320001, 0x320001).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x320003, 0x320003).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x800000, 0x80ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x810000, 0x81ffff).nopw(); /* error in game init code ? */
map(0x820000, 0x82000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x900000, 0x90ffff).ram().share("spriteram");
map(0xb00002, 0xb00003).nopw(); /* ?? */
}
void taitof2_state::dondokod_map(address_map &map)
{
map(0x000000, 0x07ffff).rom();
map(0x100000, 0x10ffff).ram();
map(0x200000, 0x201fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x300000, 0x30000f).rw(m_tc0220ioc, FUNC(tc0220ioc_device::read), FUNC(tc0220ioc_device::write)).umask16(0x00ff);
map(0x320000, 0x320000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x320002, 0x320002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x800000, 0x80ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x820000, 0x82000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x900000, 0x90ffff).ram().share("spriteram");
map(0xa00000, 0xa01fff).rw(m_tc0280grd, FUNC(tc0280grd_device::tc0280grd_word_r), FUNC(tc0280grd_device::tc0280grd_word_w)); /* ROZ tilemap */
map(0xa02000, 0xa0200f).w(m_tc0280grd, FUNC(tc0280grd_device::tc0280grd_ctrl_word_w));
map(0xb00000, 0xb0001f).w(m_tc0360pri, FUNC(tc0360pri_device::write)).umask16(0x00ff); /* ?? */
}
void taitof2_state::megab_map(address_map &map)
{
map(0x000000, 0x07ffff).rom();
map(0x100000, 0x100000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x100002, 0x100002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x120000, 0x12000f).rw(m_tc0220ioc, FUNC(tc0220ioc_device::read), FUNC(tc0220ioc_device::write)).umask16(0x00ff);
map(0x180000, 0x1807ff).rw(m_cchip, FUNC(taito_cchip_device::mem68_r), FUNC(taito_cchip_device::mem68_w)).umask16(0x00ff);
map(0x180800, 0x180fff).rw(m_cchip, FUNC(taito_cchip_device::asic_r), FUNC(taito_cchip_device::asic68_w)).umask16(0x00ff);
map(0x200000, 0x20ffff).ram();
map(0x300000, 0x301fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x400000, 0x40001f).w(m_tc0360pri, FUNC(tc0360pri_device::write)).umask16(0x00ff); /* ?? */
map(0x600000, 0x60ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x610000, 0x61ffff).ram(); /* unused? */
map(0x620000, 0x62000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x800000, 0x80ffff).ram().share("spriteram");
}
void taitof2_state::thundfox_map(address_map &map)
{
map(0x000000, 0x07ffff).rom();
map(0x100000, 0x101fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x200000, 0x20000f).rw(m_tc0220ioc, FUNC(tc0220ioc_device::read), FUNC(tc0220ioc_device::write)).umask16(0x00ff);
map(0x220000, 0x220000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x220002, 0x220002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x300000, 0x30ffff).ram();
map(0x400000, 0x40ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x420000, 0x42000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x500000, 0x50ffff).rw(m_tc0100scn[1], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x520000, 0x52000f).rw(m_tc0100scn[1], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x600000, 0x60ffff).ram().share("spriteram");
map(0x800000, 0x80001f).w(m_tc0360pri, FUNC(tc0360pri_device::write)).umask16(0xff00);
}
void taitof2_state::cameltry_map(address_map &map)
{
map(0x000000, 0x03ffff).rom();
map(0x100000, 0x10ffff).ram();
map(0x200000, 0x201fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x300000, 0x30000f).rw(m_tc0220ioc, FUNC(tc0220ioc_device::read), FUNC(tc0220ioc_device::write)).umask16(0x00ff);
map(0x300018, 0x30001f).r(FUNC(taitof2_state::cameltry_paddle_r));
map(0x320000, 0x320000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x320002, 0x320002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x800000, 0x813fff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x820000, 0x82000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x900000, 0x90ffff).ram().share("spriteram");
map(0xa00000, 0xa01fff).rw(m_tc0280grd, FUNC(tc0280grd_device::tc0280grd_word_r), FUNC(tc0280grd_device::tc0280grd_word_w)); /* ROZ tilemap */
map(0xa02000, 0xa0200f).w(m_tc0280grd, FUNC(tc0280grd_device::tc0280grd_ctrl_word_w));
map(0xd00000, 0xd0001f).w(m_tc0360pri, FUNC(tc0360pri_device::write)).umask16(0x00ff); /* ?? */
}
void taitof2_state::driftoutct_map(address_map &map)
{
cameltry_map(map);
map(0x040000, 0x07ffff).rom();
map(0x300018, 0x30001f).unmapr();
map(0x300018, 0x300019).portr("PADDLE1");
map(0x30001a, 0x30001b).portr("PADDLE2");
}
void taitof2_state::cameltrya_map(address_map &map)
{
map(0x000000, 0x03ffff).rom();
map(0x100000, 0x10ffff).ram();
map(0x200000, 0x201fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x300000, 0x30000f).rw(m_tc0220ioc, FUNC(tc0220ioc_device::read), FUNC(tc0220ioc_device::write)).umask16(0x00ff);
map(0x300018, 0x30001f).r(FUNC(taitof2_state::cameltry_paddle_r));
map(0x320000, 0x320000).w("ciu", FUNC(pc060ha_device::master_port_w));
map(0x320002, 0x320002).rw("ciu", FUNC(pc060ha_device::master_comm_r), FUNC(pc060ha_device::master_comm_w));
map(0x800000, 0x813fff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x820000, 0x82000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x900000, 0x90ffff).ram().share("spriteram");
map(0xa00000, 0xa01fff).rw(m_tc0280grd, FUNC(tc0280grd_device::tc0280grd_word_r), FUNC(tc0280grd_device::tc0280grd_word_w)); /* ROZ tilemap */
map(0xa02000, 0xa0200f).w(m_tc0280grd, FUNC(tc0280grd_device::tc0280grd_ctrl_word_w));
map(0xd00000, 0xd0001f).w(m_tc0360pri, FUNC(tc0360pri_device::write)).umask16(0x00ff); /* ?? */
}
void taitof2_state::qtorimon_map(address_map &map)
{
map(0x000000, 0x07ffff).rom();
map(0x100000, 0x10ffff).ram();
map(0x200000, 0x200007).rw(m_tc0110pcr, FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::word_w)); /* palette */
map(0x500000, 0x50000f).rw(m_tc0220ioc, FUNC(tc0220ioc_device::read), FUNC(tc0220ioc_device::write)).umask16(0x00ff);
map(0x600000, 0x600000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x600002, 0x600002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x800000, 0x80ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x820000, 0x82000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x900000, 0x90ffff).ram().share("spriteram");
map(0x910000, 0x9120ff).nopw(); /* error in init code ? */
}
void taitof2_state::liquidk_map(address_map &map)
{
map(0x000000, 0x07ffff).rom();
map(0x100000, 0x10ffff).ram();
map(0x200000, 0x201fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x300000, 0x30000f).rw(m_tc0220ioc, FUNC(tc0220ioc_device::read), FUNC(tc0220ioc_device::write)).umask16(0x00ff);
map(0x320001, 0x320001).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x320003, 0x320003).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x800000, 0x80ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x820000, 0x82000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x900000, 0x90ffff).ram().share("spriteram");
map(0xb00000, 0xb0001f).w(m_tc0360pri, FUNC(tc0360pri_device::write)).umask16(0x00ff); /* ?? */
}
void taitof2_state::quizhq_map(address_map &map)
{
map(0x000000, 0x0bffff).rom();
map(0x100000, 0x10ffff).ram();
map(0x200000, 0x200007).rw(m_tc0110pcr, FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::word_w)); /* palette */
map(0x500005, 0x500005).w(FUNC(taitof2_state::growl_coin_word_w));
map(0x500000, 0x500001).portr("DSWB");
map(0x500002, 0x500003).portr("IN0");
map(0x580000, 0x580001).w("watchdog", FUNC(watchdog_timer_device::reset16_w)); /* ??? */
map(0x580006, 0x580007).nopw(); /* ??? */
map(0x580000, 0x580001).portr("DSWA");
map(0x580002, 0x580003).portr("IN1");
map(0x580004, 0x580005).portr("IN2");
map(0x600001, 0x600001).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x600003, 0x600003).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x680000, 0x680001).nopw(); /* ??? */
map(0x800000, 0x80ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x810000, 0x81ffff).nopw(); /* error in init code ? */
map(0x820000, 0x82000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x900000, 0x90ffff).ram().share("spriteram");
}
void taitof2_state::ssi_map(address_map &map)
{
map(0x000000, 0x07ffff).rom();
map(0x100000, 0x10000f).rw(m_tc0510nio, FUNC(tc0510nio_device::halfword_r), FUNC(tc0510nio_device::halfword_w));
map(0x200000, 0x20ffff).ram();
map(0x300000, 0x301fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x400000, 0x400000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x400002, 0x400002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
// map(0x500000, 0x500001).nopw(); /* ?? */
map(0x600000, 0x60ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps (not used) */
map(0x620000, 0x62000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x800000, 0x80ffff).ram().share("spriteram"); /* sprite ram */
}
void taitof2_state::gunfront_map(address_map &map)
{
map(0x000000, 0x0bffff).rom();
map(0x100000, 0x10ffff).ram();
map(0x200000, 0x201fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x300000, 0x30000f).rw(m_tc0510nio, FUNC(tc0510nio_device::halfword_wordswap_r), FUNC(tc0510nio_device::halfword_wordswap_w));
map(0x320000, 0x320000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x320002, 0x320002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x800000, 0x80ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x820000, 0x82000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x900000, 0x90ffff).ram().share("spriteram");
// map(0xa00000, 0xa00001).nopw(); /* ?? */
map(0xb00000, 0xb0001f).w(m_tc0360pri, FUNC(tc0360pri_device::write)).umask16(0x00ff); /* ?? */
}
void taitof2_state::growl_map(address_map &map)
{
map(0x000000, 0x0fffff).rom();
map(0x100000, 0x10ffff).ram();
map(0x200000, 0x201fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x300005, 0x300005).w(FUNC(taitof2_state::growl_coin_word_w));
map(0x300000, 0x300001).portr("DSWA");
map(0x300002, 0x300003).portr("DSWB");
map(0x320000, 0x320001).portr("IN0");
map(0x320002, 0x320003).portr("IN1");
map(0x320004, 0x320005).portr("IN2");
map(0x340000, 0x340001).w("watchdog", FUNC(watchdog_timer_device::reset16_w));
map(0x400000, 0x400000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x400002, 0x400002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x500000, 0x50000f).w(FUNC(taitof2_state::spritebank_w));
map(0x504000, 0x504001).nopw(); /* unknown... various values */
map(0x508000, 0x50800f).portr("IN3");
map(0x50c000, 0x50c00f).portr("IN4");
map(0x800000, 0x80ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x820000, 0x82000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x900000, 0x90ffff).ram().share("spriteram");
map(0xb00000, 0xb0001f).w(m_tc0360pri, FUNC(tc0360pri_device::write)).umask16(0x00ff); /* ?? */
}
void taitof2_state::mjnquest_map(address_map &map)
{
map(0x000000, 0x0fffff).rom();
map(0x110000, 0x11ffff).ram(); /* "sram" */
map(0x120000, 0x12ffff).ram();
map(0x200000, 0x200007).rw(m_tc0110pcr, FUNC(tc0110pcr_device::word_r), FUNC(tc0110pcr_device::word_w)); /* palette */
map(0x300000, 0x30000f).r(FUNC(taitof2_state::mjnquest_dsw_r));
map(0x310000, 0x310001).r(FUNC(taitof2_state::mjnquest_input_r));
map(0x320000, 0x320001).w(FUNC(taitof2_state::mjnquest_inputselect_w));
map(0x330000, 0x330001).nopw(); /* watchdog ? */
map(0x350000, 0x350001).nopw(); /* watchdog ? */
map(0x360000, 0x360000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x360002, 0x360002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x380001, 0x380001).w(FUNC(taitof2_state::mjnquest_gfxbank_w)); /* scr gfx bank select */
map(0x400000, 0x40ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x420000, 0x42000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x500000, 0x50ffff).ram().share("spriteram");
}
void taitof2_state::footchmp_map(address_map &map)
{
map(0x000000, 0x07ffff).rom();
map(0x100000, 0x10ffff).ram();
map(0x200000, 0x20ffff).ram().share("spriteram");
map(0x300000, 0x30000f).w(FUNC(taitof2_state::spritebank_w)); /* updated at $a6e, off irq5 */
map(0x400000, 0x40ffff).rw(m_tc0480scp, FUNC(tc0480scp_device::ram_r), FUNC(tc0480scp_device::ram_w)); /* tilemaps */
map(0x430000, 0x43002f).rw(m_tc0480scp, FUNC(tc0480scp_device::ctrl_r), FUNC(tc0480scp_device::ctrl_w));
map(0x500000, 0x50001f).w(m_tc0360pri, FUNC(tc0360pri_device::write)).umask16(0x00ff); /* 500002 written like a watchdog?! */
map(0x600000, 0x601fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x700000, 0x70001f).rw("te7750", FUNC(te7750_device::read), FUNC(te7750_device::write)).umask16(0x00ff);
map(0x800000, 0x800001).rw("watchdog", FUNC(watchdog_timer_device::reset16_r), FUNC(watchdog_timer_device::reset16_w)); /* ??? */
map(0xa00001, 0xa00001).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0xa00003, 0xa00003).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
}
void taitof2_state::koshien_map(address_map &map)
{
map(0x000000, 0x0fffff).rom();
map(0x100000, 0x10ffff).ram();
map(0x200000, 0x201fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x300000, 0x30000f).rw(m_tc0510nio, FUNC(tc0510nio_device::halfword_r), FUNC(tc0510nio_device::halfword_w));
map(0x320000, 0x320000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x320002, 0x320002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x800000, 0x80ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x820000, 0x82000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x900000, 0x90ffff).ram().share("spriteram");
map(0xa20000, 0xa20001).w(FUNC(taitof2_state::koshien_spritebank_w));
map(0xb00000, 0xb0001f).w(m_tc0360pri, FUNC(tc0360pri_device::write)).umask16(0xff00);
}
void taitof2_state::yuyugogo_map(address_map &map)
{
map(0x000000, 0x03ffff).rom();
map(0x200000, 0x20000f).rw(m_tc0510nio, FUNC(tc0510nio_device::halfword_r), FUNC(tc0510nio_device::halfword_w));
map(0x400000, 0x400000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x400002, 0x400002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x800000, 0x80ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x820000, 0x82000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x900000, 0x90ffff).ram().share("spriteram");
map(0xa00000, 0xa01fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0xb00000, 0xb10fff).ram(); /* deliberate writes to $b10xxx, I think */
map(0xc00000, 0xc01fff).w(FUNC(taitof2_state::sprite_extension_w)).share("sprite_ext");
map(0xd00000, 0xdfffff).rom().region("extra", 0);
}
void taitof2_state::ninjak_map(address_map &map)
{
map(0x000000, 0x07ffff).rom();
map(0x100000, 0x10ffff).ram();
map(0x200000, 0x201fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x300000, 0x30001f).rw("te7750", FUNC(te7750_device::read), FUNC(te7750_device::write)).umask16(0xff00);
map(0x380000, 0x380001).w("watchdog", FUNC(watchdog_timer_device::reset16_w)); /* ??? */
map(0x400000, 0x400000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x400002, 0x400002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x600000, 0x60000f).w(FUNC(taitof2_state::spritebank_w));
map(0x800000, 0x80ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x820000, 0x82000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x900000, 0x90ffff).ram().share("spriteram");
map(0xb00000, 0xb0001f).w(m_tc0360pri, FUNC(tc0360pri_device::write)).umask16(0x00ff); /* b00002 written like a watchdog?! */
}
void taitof2_state::solfigtr_map(address_map &map)
{
map(0x000000, 0x07ffff).rom();
map(0x100000, 0x10ffff).ram();
map(0x200000, 0x201fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x300005, 0x300005).w(FUNC(taitof2_state::growl_coin_word_w)); /* NOT VERIFIED */
map(0x300000, 0x300001).portr("DSWA");
map(0x300002, 0x300003).portr("DSWB");
map(0x320000, 0x320001).portr("IN0");
map(0x320002, 0x320003).portr("IN1");
map(0x320004, 0x320005).portr("IN2");
map(0x340000, 0x340001).w("watchdog", FUNC(watchdog_timer_device::reset16_w)); /* NOT VERIFIED */
map(0x400000, 0x400000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x400002, 0x400002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x500000, 0x50000f).w(FUNC(taitof2_state::spritebank_w));
map(0x504000, 0x504001).nopw(); /* unknown... various values */
map(0x800000, 0x80ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x820000, 0x82000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x900000, 0x90ffff).ram().share("spriteram");
map(0xb00000, 0xb0001f).w(m_tc0360pri, FUNC(tc0360pri_device::write)).umask16(0x00ff); /* ?? */
}
void taitof2_state::qzquest_map(address_map &map)
{
map(0x000000, 0x17ffff).rom();
map(0x200000, 0x20000f).rw(m_tc0510nio, FUNC(tc0510nio_device::halfword_r), FUNC(tc0510nio_device::halfword_w));
map(0x300001, 0x300001).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x300003, 0x300003).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x400000, 0x401fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x500000, 0x50ffff).ram();
map(0x600000, 0x60ffff).ram().share("spriteram");
map(0x700000, 0x70ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x720000, 0x72000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
}
void taitof2_state::pulirula_map(address_map &map)
{
map(0x000000, 0x0bffff).rom();
map(0x200000, 0x200000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x200002, 0x200002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x300000, 0x30ffff).ram();
map(0x400000, 0x401fff).rw(m_tc0430grw, FUNC(tc0280grd_device::tc0430grw_word_r), FUNC(tc0280grd_device::tc0430grw_word_w)); /* ROZ tilemap */
map(0x402000, 0x40200f).w(m_tc0430grw, FUNC(tc0280grd_device::tc0430grw_ctrl_word_w));
// map(0x500000, 0x500001).nopw(); /* ??? */
map(0x600000, 0x603fff).w(FUNC(taitof2_state::sprite_extension_w)).share("sprite_ext");
map(0x700000, 0x701fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x800000, 0x80ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x820000, 0x82000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x900000, 0x90ffff).ram().share("spriteram");
map(0xa00000, 0xa0001f).w(m_tc0360pri, FUNC(tc0360pri_device::write)).umask16(0xff00);
map(0xb00000, 0xb0000f).rw(m_tc0510nio, FUNC(tc0510nio_device::halfword_r), FUNC(tc0510nio_device::halfword_w));
}
void taitof2_state::metalb_map(address_map &map)
{
map(0x000000, 0x0bffff).rom();
map(0x100000, 0x10ffff).ram();
map(0x300000, 0x30ffff).ram().share("spriteram");
// map(0x42000c, 0x42000f).nopw(); /* zeroed */
map(0x500000, 0x50ffff).rw(m_tc0480scp, FUNC(tc0480scp_device::ram_r), FUNC(tc0480scp_device::ram_w)); /* tilemaps */
map(0x530000, 0x53002f).rw(m_tc0480scp, FUNC(tc0480scp_device::ctrl_r), FUNC(tc0480scp_device::ctrl_w));
map(0x600000, 0x60001f).w(m_tc0360pri, FUNC(tc0360pri_device::write)).umask16(0x00ff);
map(0x700000, 0x703fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x800000, 0x80000f).rw(m_tc0510nio, FUNC(tc0510nio_device::halfword_wordswap_r), FUNC(tc0510nio_device::halfword_wordswap_w));
map(0x900000, 0x900000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x900002, 0x900002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
// map(0xa00000, 0xa00001).nopw(); /* ??? */
}
void taitof2_state::qzchikyu_map(address_map &map)
{
map(0x000000, 0x17ffff).rom();
map(0x200000, 0x20000f).rw(m_tc0510nio, FUNC(tc0510nio_device::halfword_r), FUNC(tc0510nio_device::halfword_w));
map(0x300001, 0x300001).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x300003, 0x300003).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x400000, 0x401fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x500000, 0x50ffff).ram();
map(0x600000, 0x60ffff).ram().share("spriteram");
map(0x700000, 0x70ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x720000, 0x72000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
}
void taitof2_state::yesnoj_map(address_map &map)
{
map(0x000000, 0x07ffff).rom();
map(0x200000, 0x20ffff).ram();
map(0x400000, 0x40ffff).ram().share("spriteram");
map(0x500000, 0x50ffff).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ram_r), FUNC(tc0100scn_device::ram_w)); /* tilemaps */
map(0x520000, 0x52000f).rw(m_tc0100scn[0], FUNC(tc0100scn_device::ctrl_r), FUNC(tc0100scn_device::ctrl_w));
map(0x600000, 0x601fff).ram().w(m_palette, FUNC(palette_device::write16)).share("palette");
map(0x700000, 0x70001f).rw("rtc", FUNC(tc8521_device::read), FUNC(tc8521_device::write)).umask16(0x00ff);
map(0x800000, 0x800000).w("tc0140syt", FUNC(tc0140syt_device::master_port_w));
map(0x800002, 0x800002).rw("tc0140syt", FUNC(tc0140syt_device::master_comm_r), FUNC(tc0140syt_device::master_comm_w));
map(0x900002, 0x900003).nopw(); /* lots of similar writes */
map(0xa00000, 0xa00001).portr("IN0");
map(0xa00002, 0xa00003).portr("IN1");
map(0xa00004, 0xa00005).portr("IN2");
map(0xb00000, 0xb00001).portr("DSWA");