55
55
#include <86box/plat_fallthrough.h>
56
56
#include <86box/plat_unused.h>
57
57
58
+ #define ET4000_TYPE_TC6058AF 0 /* ISA ET4000AX (TC6058AF) */
58
59
#define ET4000_TYPE_ISA 1 /* ISA ET4000AX */
59
60
#define ET4000_TYPE_MCA 2 /* MCA ET4000AX */
60
61
#define ET4000_TYPE_KOREAN 3 /* Korean ET4000 */
61
62
#define ET4000_TYPE_TRIGEM 4 /* Trigem 286M ET4000 */
62
63
#define ET4000_TYPE_KASAN 5 /* Kasan ET4000 */
63
64
64
- #define BIOS_ROM_PATH "roms/video/et4000/ET4000.BIN"
65
- #define KOREAN_BIOS_ROM_PATH "roms/video/et4000/tgkorvga.bin"
66
- #define KOREAN_FONT_ROM_PATH "roms/video/et4000/tg_ksc5601.rom"
67
- #define KASAN_BIOS_ROM_PATH "roms/video/et4000/et4000_kasan16.bin"
68
- #define KASAN_FONT_ROM_PATH "roms/video/et4000/kasan_ksc5601.rom"
65
+ #define BIOS_ROM_PATH "roms/video/et4000/ET4000.BIN"
66
+ #define TC6058AF_BIOS_ROM_PATH "roms/video/et4000/Tseng_Labs_VGA-4000_BIOS_V1.1.bin"
67
+ #define KOREAN_BIOS_ROM_PATH "roms/video/et4000/tgkorvga.bin"
68
+ #define KOREAN_FONT_ROM_PATH "roms/video/et4000/tg_ksc5601.rom"
69
+ #define KASAN_BIOS_ROM_PATH "roms/video/et4000/et4000_kasan16.bin"
70
+ #define KASAN_FONT_ROM_PATH "roms/video/et4000/kasan_ksc5601.rom"
69
71
70
72
typedef struct {
71
73
const char * name ;
@@ -115,6 +117,7 @@ et4000_in(uint16_t addr, void *priv)
115
117
{
116
118
et4000_t * dev = (et4000_t * ) priv ;
117
119
svga_t * svga = & dev -> svga ;
120
+ uint8_t ret ;
118
121
119
122
if (((addr & 0xfff0 ) == 0x3d0 || (addr & 0xfff0 ) == 0x3b0 ) && !(svga -> miscout & 1 ))
120
123
addr ^= 0x60 ;
@@ -138,7 +141,8 @@ et4000_in(uint16_t addr, void *priv)
138
141
case 0x3c7 :
139
142
case 0x3c8 :
140
143
case 0x3c9 :
141
- return sc1502x_ramdac_in (addr , svga -> ramdac , svga );
144
+ if (dev -> type >= ET4000_TYPE_ISA )
145
+ return sc1502x_ramdac_in (addr , svga -> ramdac , svga );
142
146
143
147
case 0x3cd : /*Banking*/
144
148
return dev -> banking ;
@@ -149,6 +153,26 @@ et4000_in(uint16_t addr, void *priv)
149
153
case 0x3d5 :
150
154
return svga -> crtc [svga -> crtcreg ];
151
155
156
+ case 0x3da :
157
+ svga -> attrff = 0 ;
158
+
159
+ if (svga -> cgastat & 0x01 )
160
+ svga -> cgastat &= ~0x30 ;
161
+ else
162
+ svga -> cgastat ^= 0x30 ;
163
+
164
+ ret = svga -> cgastat ;
165
+
166
+ if ((svga -> fcr & 0x08 ) && svga -> dispon )
167
+ ret |= 0x08 ;
168
+
169
+ if (ret & 0x08 )
170
+ ret &= 0x7f ;
171
+ else
172
+ ret |= 0x80 ;
173
+
174
+ return ret ;
175
+
152
176
default :
153
177
break ;
154
178
}
@@ -225,12 +249,33 @@ et4000_out(uint16_t addr, uint8_t val, void *priv)
225
249
addr ^= 0x60 ;
226
250
227
251
switch (addr ) {
252
+ case 0x3c5 :
253
+ if (svga -> seqaddr == 4 ) {
254
+ svga -> seqregs [4 ] = val ;
255
+
256
+ svga -> chain2_write = !(val & 4 );
257
+ svga -> chain4 = (svga -> chain4 & ~8 ) | (val & 8 );
258
+ svga -> fast = (svga -> gdcreg [8 ] == 0xff && !(svga -> gdcreg [3 ] & 0x18 ) && !svga -> gdcreg [1 ]) && svga -> chain4 && !(svga -> adv_flags & FLAG_ADDR_BY8 );
259
+ return ;
260
+ } else if (svga -> seqaddr == 0x0e ) {
261
+ svga -> seqregs [0x0e ] = val ;
262
+ svga -> chain4 &= ~0x02 ;
263
+ if (svga -> gdcreg [5 ] & 0x40 )
264
+ svga -> chain4 |= (svga -> seqregs [0x0e ] & 0x02 );
265
+ svga_recalctimings (svga );
266
+ return ;
267
+ }
268
+ break ;
269
+
228
270
case 0x3c6 :
229
271
case 0x3c7 :
230
272
case 0x3c8 :
231
273
case 0x3c9 :
232
- sc1502x_ramdac_out (addr , val , svga -> ramdac , svga );
233
- return ;
274
+ if (dev -> type >= ET4000_TYPE_ISA ) {
275
+ sc1502x_ramdac_out (addr , val , svga -> ramdac , svga );
276
+ return ;
277
+ }
278
+ break ;
234
279
235
280
case 0x3cd : /*Banking*/
236
281
if (!(svga -> crtc [0x36 ] & 0x10 ) && !(svga -> gdcreg [6 ] & 0x08 )) {
@@ -241,7 +286,11 @@ et4000_out(uint16_t addr, uint8_t val, void *priv)
241
286
return ;
242
287
243
288
case 0x3cf :
244
- if ((svga -> gdcaddr & 15 ) == 6 ) {
289
+ if ((svga -> gdcaddr & 15 ) == 5 ) {
290
+ svga -> chain4 &= ~0x02 ;
291
+ if (val & 0x40 )
292
+ svga -> chain4 |= (svga -> seqregs [0x0e ] & 0x02 );
293
+ } else if ((svga -> gdcaddr & 15 ) == 6 ) {
245
294
if (!(svga -> crtc [0x36 ] & 0x10 ) && !(val & 0x08 )) {
246
295
svga -> write_bank = (dev -> banking & 0x0f ) * 0x10000 ;
247
296
svga -> read_bank = ((dev -> banking >> 4 ) & 0x0f ) * 0x10000 ;
@@ -418,7 +467,8 @@ et4000_kasan_out(uint16_t addr, uint8_t val, void *priv)
418
467
break ;
419
468
case 1 :
420
469
case 2 :
421
- et4000 -> kasan_cfg_regs [et4000 -> kasan_cfg_index - 0xF0 ] = val ;
470
+ if ((et4000 -> kasan_cfg_index - 0xF0 ) <= 16 )
471
+ et4000 -> kasan_cfg_regs [et4000 -> kasan_cfg_index - 0xF0 ] = val ;
422
472
io_removehandler (et4000 -> kasan_access_addr , 0x0008 , et4000_kasan_in , NULL , NULL , et4000_kasan_out , NULL , NULL , et4000 );
423
473
et4000 -> kasan_access_addr = (et4000 -> kasan_cfg_regs [2 ] << 8 ) | et4000 -> kasan_cfg_regs [1 ];
424
474
io_sethandler (et4000 -> kasan_access_addr , 0x0008 , et4000_kasan_in , NULL , NULL , et4000_kasan_out , NULL , NULL , et4000 );
@@ -463,7 +513,8 @@ et4000_kasan_out(uint16_t addr, uint8_t val, void *priv)
463
513
case 4 :
464
514
case 5 :
465
515
if (et4000 -> kasan_cfg_regs [0 ] & 1 ) {
466
- et4000 -> kasan_font_data [addr - (((et4000 -> kasan_cfg_regs [2 ] << 8 ) | (et4000 -> kasan_cfg_regs [1 ])) + 3 )] = val ;
516
+ if ((addr - (((et4000 -> kasan_cfg_regs [2 ] << 8 ) | (et4000 -> kasan_cfg_regs [1 ])) + 3 )) <= 4 )
517
+ et4000 -> kasan_font_data [addr - (((et4000 -> kasan_cfg_regs [2 ] << 8 ) | (et4000 -> kasan_cfg_regs [1 ])) + 3 )] = val ;
467
518
}
468
519
break ;
469
520
case 6 :
@@ -562,6 +613,8 @@ et4000_recalctimings(svga_t *svga)
562
613
svga -> rowoffset = 0x100 ;
563
614
if (svga -> crtc [0x3f ] & 1 )
564
615
svga -> htotal += 256 ;
616
+ if (svga -> crtc [0x3f ] & 0x04 )
617
+ svga -> hblankstart += 0x100 ;
565
618
if (svga -> attrregs [0x16 ] & 0x20 )
566
619
svga -> hdisp <<= 1 ;
567
620
@@ -606,6 +659,19 @@ et4000_recalctimings(svga_t *svga)
606
659
}
607
660
}
608
661
662
+ if ((svga -> seqregs [0x0e ] & 0x02 ) && ((svga -> gdcreg [5 ] & 0x60 ) >= 0x40 )) {
663
+ svga -> ma_latch <<= (1 << 0 );
664
+ svga -> rowoffset <<= (1 << 0 );
665
+ svga -> render = svga_render_8bpp_highres ;
666
+ }
667
+
668
+ if (dev -> type == ET4000_TYPE_TC6058AF ) {
669
+ if (svga -> render == svga_render_8bpp_lowres )
670
+ svga -> render = svga_render_8bpp_tseng_lowres ;
671
+ else if (svga -> render == svga_render_8bpp_highres )
672
+ svga -> render = svga_render_8bpp_tseng_highres ;
673
+ }
674
+
609
675
if ((svga -> bpp == 8 ) && ((svga -> gdcreg [5 ] & 0x60 ) >= 0x40 )) {
610
676
svga -> map8 = svga -> pallook ;
611
677
if (svga -> lowres )
@@ -672,6 +738,7 @@ et4000_init(const device_t *info)
672
738
fn = BIOS_ROM_PATH ;
673
739
674
740
switch (dev -> type ) {
741
+ case ET4000_TYPE_TC6058AF : /* ISA ET4000AX (TC6058AF) */
675
742
case ET4000_TYPE_ISA : /* ISA ET4000AX */
676
743
dev -> vram_size = device_get_config_int ("memory" ) << 10 ;
677
744
video_inform (VIDEO_FLAG_TYPE_SPECIAL , & timing_et4000_isa );
@@ -680,6 +747,8 @@ et4000_init(const device_t *info)
680
747
NULL , NULL );
681
748
io_sethandler (0x03c0 , 32 ,
682
749
et4000_in , NULL , NULL , et4000_out , NULL , NULL , dev );
750
+ if (dev -> type == ET4000_TYPE_TC6058AF )
751
+ fn = TC6058AF_BIOS_ROM_PATH ;
683
752
break ;
684
753
685
754
case ET4000_TYPE_MCA : /* MCA ET4000AX */
@@ -759,7 +828,8 @@ et4000_init(const device_t *info)
759
828
break ;
760
829
}
761
830
762
- dev -> svga .ramdac = device_add (& sc1502x_ramdac_device );
831
+ if (dev -> type >= ET4000_TYPE_ISA )
832
+ dev -> svga .ramdac = device_add (& sc1502x_ramdac_device );
763
833
764
834
dev -> vram_mask = dev -> vram_size - 1 ;
765
835
@@ -799,6 +869,12 @@ et4000_force_redraw(void *priv)
799
869
dev -> svga .fullchange = changeframecount ;
800
870
}
801
871
872
+ static int
873
+ et4000_tc6058af_available (void )
874
+ {
875
+ return rom_present (TC6058AF_BIOS_ROM_PATH );
876
+ }
877
+
802
878
static int
803
879
et4000_available (void )
804
880
{
@@ -817,6 +893,33 @@ et4000_kasan_available(void)
817
893
return rom_present (KASAN_BIOS_ROM_PATH ) && rom_present (KASAN_FONT_ROM_PATH );
818
894
}
819
895
896
+ static const device_config_t et4000_tc6058af_config [] = {
897
+ // clang-format off
898
+ {
899
+ .name = "memory" ,
900
+ .description = "Memory size" ,
901
+ .type = CONFIG_SELECTION ,
902
+ .default_int = 512 ,
903
+ .selection = {
904
+ {
905
+ .description = "256 KB" ,
906
+ .value = 256
907
+ },
908
+ {
909
+ .description = "512 KB" ,
910
+ .value = 512
911
+ },
912
+ {
913
+ .description = ""
914
+ }
915
+ }
916
+ },
917
+ {
918
+ .type = CONFIG_END
919
+ }
920
+ // clang-format on
921
+ };
922
+
820
923
static const device_config_t et4000_config [] = {
821
924
// clang-format off
822
925
{
@@ -848,6 +951,20 @@ static const device_config_t et4000_config[] = {
848
951
// clang-format on
849
952
};
850
953
954
+ const device_t et4000_tc6058af_isa_device = {
955
+ .name = "Tseng Labs ET4000AX (TC6058AF) (ISA)" ,
956
+ .internal_name = "et4000ax_tc6058af" ,
957
+ .flags = DEVICE_ISA ,
958
+ .local = 0 ,
959
+ .init = et4000_init ,
960
+ .close = et4000_close ,
961
+ .reset = NULL ,
962
+ { .available = et4000_tc6058af_available },
963
+ .speed_changed = et4000_speed_changed ,
964
+ .force_redraw = et4000_force_redraw ,
965
+ .config = et4000_tc6058af_config
966
+ };
967
+
851
968
const device_t et4000_isa_device = {
852
969
.name = "Tseng Labs ET4000AX (ISA)" ,
853
970
.internal_name = "et4000ax" ,
0 commit comments