2017-10-11 05:40:44 -04:00
/*
2023-01-06 15:36:05 -05:00
* 86 Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus .
2017-10-11 05:40:44 -04:00
*
2023-01-06 15:36:05 -05:00
* This file is part of the 86 Box distribution .
2017-10-11 05:40:44 -04:00
*
2023-01-06 15:36:05 -05:00
* Paradise VGA emulation
* PC2086 , PC3086 use PVGA1A
* MegaPC uses W90C11A
2017-10-11 05:40:44 -04:00
*
2020-03-25 00:46:02 +02:00
*
2017-10-11 05:40:44 -04:00
*
2023-01-06 15:36:29 -05:00
* Authors : Sarah Walker , < https : //pcem-emulator.co.uk/>
2023-01-06 15:36:05 -05:00
* Miran Grca , < mgrca8 @ gmail . com >
2017-10-11 05:40:44 -04:00
*
2023-01-06 15:36:05 -05:00
* Copyright 2008 - 2019 Sarah Walker .
* Copyright 2016 - 2019 Miran Grca .
2017-10-11 05:40:44 -04:00
*/
2017-09-25 04:31:20 -04:00
# include <stdio.h>
# include <stdint.h>
# include <string.h>
2016-06-26 00:34:39 +02:00
# include <stdlib.h>
2017-09-25 04:31:20 -04:00
# include <wchar.h>
2020-03-29 14:24:42 +02:00
# include <86box/86box.h>
# include <86box/io.h>
# include <86box/timer.h>
# include <86box/mem.h>
# include <86box/rom.h>
# include <86box/device.h>
# include <86box/video.h>
# include <86box/vid_svga.h>
# include <86box/vid_svga_render.h>
2016-06-26 00:34:39 +02:00
2022-08-31 19:19:29 -04:00
typedef struct paradise_t {
svga_t svga ;
2017-05-06 17:48:33 +02:00
2022-08-31 19:19:29 -04:00
rom_t bios_rom ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
uint8_t bank_mask ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
enum {
PVGA1A = 0 ,
WD90C11 ,
WD90C30
} type ;
2016-06-26 00:34:39 +02:00
2022-08-31 19:19:29 -04:00
uint32_t vram_mask ;
2021-05-30 01:52:43 +02:00
2022-08-31 19:19:29 -04:00
uint32_t read_bank [ 4 ] , write_bank [ 4 ] ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
int interlace ;
int check , check2 ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
struct {
uint8_t reg_block_ptr ;
uint8_t reg_idx ;
uint8_t disable_autoinc ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
uint16_t int_status ;
uint16_t blt_ctrl1 , blt_ctrl2 ;
uint16_t srclow , srchigh ;
uint16_t dstlow , dsthigh ;
2021-08-17 18:58:37 +02:00
2022-08-31 19:19:29 -04:00
uint32_t srcaddr , dstaddr ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
int invalid_block ;
} accel ;
2016-06-26 00:34:39 +02:00
} paradise_t ;
2022-08-31 19:19:29 -04:00
static video_timings_t timing_paradise_pvga1a = { . type = VIDEO_ISA , . write_b = 6 , . write_w = 8 , . write_l = 16 , . read_b = 6 , . read_w = 8 , . read_l = 16 } ;
static video_timings_t timing_paradise_wd90c = { . type = VIDEO_ISA , . write_b = 3 , . write_w = 3 , . write_l = 6 , . read_b = 5 , . read_w = 5 , . read_l = 10 } ;
2018-09-19 20:13:32 +02:00
2016-06-26 00:34:39 +02:00
void paradise_remap ( paradise_t * paradise ) ;
2022-08-31 19:19:29 -04:00
uint8_t
2023-06-09 23:46:54 -04:00
paradise_in ( uint16_t addr , void * priv )
2022-07-24 05:40:06 +02:00
{
2023-06-09 23:46:54 -04:00
paradise_t * paradise = ( paradise_t * ) priv ;
2022-08-31 19:19:29 -04:00
svga_t * svga = & paradise - > svga ;
if ( ( ( addr & 0xfff0 ) = = 0x3d0 | | ( addr & 0xfff0 ) = = 0x3b0 ) & & ! ( svga - > miscout & 1 ) )
addr ^ = 0x60 ;
switch ( addr ) {
case 0x3c5 :
if ( svga - > seqaddr > 7 ) {
if ( paradise - > type < WD90C11 | | svga - > seqregs [ 6 ] ! = 0x48 )
return 0xff ;
if ( svga - > seqaddr > 0x12 )
return 0xff ;
return svga - > seqregs [ svga - > seqaddr & 0x1f ] ;
}
break ;
case 0x3c6 :
case 0x3c7 :
case 0x3c8 :
case 0x3c9 :
if ( paradise - > type = = WD90C30 )
return sc1148x_ramdac_in ( addr , 0 , svga - > ramdac , svga ) ;
return svga_in ( addr , svga ) ;
case 0x3cf :
if ( svga - > gdcaddr > = 9 & & svga - > gdcaddr < = 0x0e ) {
if ( svga - > gdcreg [ 0x0f ] & 0x10 )
return 0xff ;
}
switch ( svga - > gdcaddr ) {
case 0x0b :
if ( paradise - > type = = WD90C30 ) {
if ( paradise - > vram_mask = = ( ( 512 < < 10 ) - 1 ) ) {
svga - > gdcreg [ 0x0b ] | = 0xc0 ;
svga - > gdcreg [ 0x0b ] & = ~ 0x40 ;
}
}
return svga - > gdcreg [ 0x0b ] ;
2022-07-24 05:40:06 +02:00
2022-08-31 19:19:29 -04:00
case 0x0f :
return ( svga - > gdcreg [ 0x0f ] & 0x17 ) | 0x80 ;
}
break ;
case 0x3D4 :
return svga - > crtcreg ;
case 0x3D5 :
if ( ( paradise - > type = = PVGA1A ) & & ( svga - > crtcreg & 0x20 ) )
return 0xff ;
if ( svga - > crtcreg > 0x29 & & svga - > crtcreg < 0x30 & & ( svga - > crtc [ 0x29 ] & 0x88 ) ! = 0x80 )
return 0xff ;
return svga - > crtc [ svga - > crtcreg ] ;
}
return svga_in ( addr , svga ) ;
2022-07-24 05:40:06 +02:00
}
2022-08-31 19:19:29 -04:00
void
2023-06-09 23:46:54 -04:00
paradise_out ( uint16_t addr , uint8_t val , void * priv )
2016-06-26 00:34:39 +02:00
{
2023-06-09 23:46:54 -04:00
paradise_t * paradise = ( paradise_t * ) priv ;
2022-08-31 19:19:29 -04:00
svga_t * svga = & paradise - > svga ;
uint8_t old ;
if ( paradise - > vram_mask < = ( ( 512 < < 10 ) - 1 ) )
paradise - > bank_mask = 0x7f ;
else
paradise - > bank_mask = 0xff ;
if ( ( ( addr & 0xfff0 ) = = 0x3d0 | | ( addr & 0xfff0 ) = = 0x3b0 ) & & ! ( svga - > miscout & 1 ) )
addr ^ = 0x60 ;
switch ( addr ) {
case 0x3c5 :
if ( svga - > seqaddr > 7 ) {
if ( paradise - > type < WD90C11 | | svga - > seqregs [ 6 ] ! = 0x48 )
return ;
svga - > seqregs [ svga - > seqaddr & 0x1f ] = val ;
if ( svga - > seqaddr = = 0x11 ) {
paradise_remap ( paradise ) ;
2016-06-26 00:34:39 +02:00
}
return ;
2022-08-31 19:19:29 -04:00
}
break ;
case 0x3c6 :
case 0x3c7 :
case 0x3c8 :
case 0x3c9 :
if ( paradise - > type = = WD90C30 )
sc1148x_ramdac_out ( addr , 0 , val , svga - > ramdac , svga ) ;
else
svga_out ( addr , val , svga ) ;
return ;
case 0x3cf :
if ( svga - > gdcaddr > = 9 & & svga - > gdcaddr < = 0x0e ) {
if ( ( svga - > gdcreg [ 0x0f ] & 7 ) ! = 5 )
return ;
}
switch ( svga - > gdcaddr ) {
case 6 :
if ( ( svga - > gdcreg [ 6 ] & 0x0c ) ! = ( val & 0x0c ) ) {
switch ( val & 0x0c ) {
case 0x00 : /*128k at A0000*/
mem_mapping_set_addr ( & svga - > mapping , 0xa0000 , 0x20000 ) ;
svga - > banked_mask = 0xffff ;
break ;
case 0x04 : /*64k at A0000*/
mem_mapping_set_addr ( & svga - > mapping , 0xa0000 , 0x10000 ) ;
svga - > banked_mask = 0xffff ;
break ;
case 0x08 : /*32k at B0000*/
mem_mapping_set_addr ( & svga - > mapping , 0xb0000 , 0x08000 ) ;
svga - > banked_mask = 0x7fff ;
break ;
case 0x0c : /*32k at B8000*/
mem_mapping_set_addr ( & svga - > mapping , 0xb8000 , 0x08000 ) ;
svga - > banked_mask = 0x7fff ;
break ;
2016-06-26 00:34:39 +02:00
}
2022-08-31 19:19:29 -04:00
}
svga - > gdcreg [ 6 ] = val ;
paradise_remap ( paradise ) ;
return ;
case 9 :
case 0x0a :
svga - > gdcreg [ svga - > gdcaddr ] = val & paradise - > bank_mask ;
paradise_remap ( paradise ) ;
return ;
case 0x0b :
svga - > gdcreg [ 0x0b ] = val ;
paradise_remap ( paradise ) ;
return ;
}
break ;
case 0x3D4 :
svga - > crtcreg = val & 0x3f ;
return ;
case 0x3D5 :
if ( ( paradise - > type = = PVGA1A ) & & ( svga - > crtcreg & 0x20 ) )
return ;
if ( ( svga - > crtcreg < 7 ) & & ( svga - > crtc [ 0x11 ] & 0x80 ) )
return ;
if ( ( svga - > crtcreg = = 7 ) & & ( svga - > crtc [ 0x11 ] & 0x80 ) )
val = ( svga - > crtc [ 7 ] & ~ 0x10 ) | ( val & 0x10 ) ;
if ( svga - > crtcreg > 0x29 & & ( svga - > crtc [ 0x29 ] & 7 ) ! = 5 )
return ;
if ( svga - > crtcreg > = 0x31 & & svga - > crtcreg < = 0x37 )
return ;
old = svga - > crtc [ svga - > crtcreg ] ;
svga - > crtc [ svga - > crtcreg ] = val ;
if ( old ! = val ) {
if ( svga - > crtcreg < 0xe | | svga - > crtcreg > 0x10 ) {
if ( ( svga - > crtcreg = = 0xc ) | | ( svga - > crtcreg = = 0xd ) ) {
svga - > fullchange = 3 ;
svga - > ma_latch = ( ( svga - > crtc [ 0xc ] < < 8 ) | svga - > crtc [ 0xd ] ) + ( ( svga - > crtc [ 8 ] & 0x60 ) > > 5 ) ;
} else {
svga - > fullchange = changeframecount ;
svga_recalctimings ( svga ) ;
}
2016-06-26 00:34:39 +02:00
}
2022-08-31 19:19:29 -04:00
}
break ;
case 0x46e8 :
io_removehandler ( 0x03c0 , 0x0020 , paradise_in , NULL , NULL , paradise_out , NULL , NULL , paradise ) ;
mem_mapping_disable ( & paradise - > svga . mapping ) ;
if ( val & 8 ) {
io_sethandler ( 0x03c0 , 0x0020 , paradise_in , NULL , NULL , paradise_out , NULL , NULL , paradise ) ;
mem_mapping_enable ( & paradise - > svga . mapping ) ;
}
break ;
}
2022-07-24 05:40:06 +02:00
2022-08-31 19:19:29 -04:00
svga_out ( addr , val , svga ) ;
2016-06-26 00:34:39 +02:00
}
2022-08-31 19:19:29 -04:00
void
paradise_remap ( paradise_t * paradise )
2016-06-26 00:34:39 +02:00
{
2022-08-31 19:19:29 -04:00
svga_t * svga = & paradise - > svga ;
paradise - > check = 0 ;
if ( svga - > seqregs [ 0x11 ] & 0x80 ) {
paradise - > read_bank [ 0 ] = paradise - > read_bank [ 2 ] = svga - > gdcreg [ 9 ] < < 12 ;
paradise - > read_bank [ 1 ] = paradise - > read_bank [ 3 ] = ( svga - > gdcreg [ 9 ] < < 12 ) + ( ( svga - > gdcreg [ 6 ] & 0x08 ) ? 0 : 0x8000 ) ;
paradise - > write_bank [ 0 ] = paradise - > write_bank [ 2 ] = svga - > gdcreg [ 0x0a ] < < 12 ;
paradise - > write_bank [ 1 ] = paradise - > write_bank [ 3 ] = ( svga - > gdcreg [ 0x0a ] < < 12 ) + ( ( svga - > gdcreg [ 6 ] & 0x08 ) ? 0 : 0x8000 ) ;
} else if ( svga - > gdcreg [ 0x0b ] & 0x08 ) {
if ( svga - > gdcreg [ 6 ] & 0x0c ) {
paradise - > read_bank [ 0 ] = paradise - > read_bank [ 2 ] = svga - > gdcreg [ 0x0a ] < < 12 ;
paradise - > write_bank [ 0 ] = paradise - > write_bank [ 2 ] = svga - > gdcreg [ 0x0a ] < < 12 ;
paradise - > read_bank [ 1 ] = paradise - > read_bank [ 3 ] = ( svga - > gdcreg [ 9 ] < < 12 ) + ( ( svga - > gdcreg [ 6 ] & 0x08 ) ? 0 : 0x8000 ) ;
paradise - > write_bank [ 1 ] = paradise - > write_bank [ 3 ] = ( svga - > gdcreg [ 9 ] < < 12 ) + ( ( svga - > gdcreg [ 6 ] & 0x08 ) ? 0 : 0x8000 ) ;
} else {
paradise - > read_bank [ 0 ] = paradise - > write_bank [ 0 ] = svga - > gdcreg [ 0x0a ] < < 12 ;
paradise - > read_bank [ 1 ] = paradise - > write_bank [ 1 ] = ( svga - > gdcreg [ 0xa ] < < 12 ) + ( ( svga - > gdcreg [ 6 ] & 0x08 ) ? 0 : 0x8000 ) ;
paradise - > read_bank [ 2 ] = paradise - > write_bank [ 2 ] = svga - > gdcreg [ 9 ] < < 12 ;
paradise - > read_bank [ 3 ] = paradise - > write_bank [ 3 ] = ( svga - > gdcreg [ 9 ] < < 12 ) + ( ( svga - > gdcreg [ 6 ] & 0x08 ) ? 0 : 0x8000 ) ;
}
} else {
paradise - > read_bank [ 0 ] = paradise - > read_bank [ 2 ] = svga - > gdcreg [ 9 ] < < 12 ;
paradise - > read_bank [ 1 ] = paradise - > read_bank [ 3 ] = ( svga - > gdcreg [ 9 ] < < 12 ) + ( ( svga - > gdcreg [ 6 ] & 0x08 ) ? 0 : 0x8000 ) ;
paradise - > write_bank [ 0 ] = paradise - > write_bank [ 2 ] = svga - > gdcreg [ 9 ] < < 12 ;
paradise - > write_bank [ 1 ] = paradise - > write_bank [ 3 ] = ( svga - > gdcreg [ 9 ] < < 12 ) + ( ( svga - > gdcreg [ 6 ] & 0x08 ) ? 0 : 0x8000 ) ;
}
2023-06-01 18:32:25 -04:00
if ( ( ( svga - > gdcreg [ 0x0b ] & 0xc0 ) = = 0xc0 ) & & ! svga - > chain4 & & ( svga - > crtc [ 0x14 ] & 0x40 ) & & ( ( svga - > gdcreg [ 6 ] > > 2 ) & 3 ) = = 1 )
2022-08-31 19:19:29 -04:00
paradise - > check = 1 ;
if ( paradise - > bank_mask = = 0x7f ) {
paradise - > read_bank [ 1 ] & = 0x7ffff ;
paradise - > write_bank [ 1 ] & = 0x7ffff ;
}
2016-06-26 00:34:39 +02:00
}
2022-08-31 19:19:29 -04:00
void
paradise_recalctimings ( svga_t * svga )
2016-06-26 00:34:39 +02:00
{
2023-06-09 23:46:54 -04:00
paradise_t * paradise = ( paradise_t * ) svga - > priv ;
2022-08-31 19:19:29 -04:00
svga - > lowres = ! ( svga - > gdcreg [ 0x0e ] & 0x01 ) ;
if ( paradise - > type = = WD90C30 ) {
if ( svga - > crtc [ 0x3e ] & 0x01 )
svga - > vtotal | = 0x400 ;
if ( svga - > crtc [ 0x3e ] & 0x02 )
svga - > dispend | = 0x400 ;
if ( svga - > crtc [ 0x3e ] & 0x04 )
svga - > vsyncstart | = 0x400 ;
if ( svga - > crtc [ 0x3e ] & 0x08 )
svga - > vblankstart | = 0x400 ;
if ( svga - > crtc [ 0x3e ] & 0x10 )
svga - > split | = 0x400 ;
svga - > interlace = ! ! ( svga - > crtc [ 0x2d ] & 0x20 ) ;
if ( ! svga - > interlace & & svga - > lowres & & ( svga - > hdisp > = 1024 ) & & ( ( svga - > gdcreg [ 5 ] & 0x60 ) = = 0 ) & & ( svga - > miscout > = 0x27 ) & & ( svga - > miscout < = 0x2f ) & & ( ( svga - > gdcreg [ 6 ] & 1 ) | | ( svga - > attrregs [ 0x10 ] & 1 ) ) ) { /*Horrible tweak to re-enable the interlace after returning to
a windowed DOS box in Win3 . x */
svga - > interlace = 1 ;
}
}
if ( paradise - > type < WD90C30 ) {
if ( svga - > bpp > = 8 & & ! svga - > lowres ) {
svga - > render = svga_render_8bpp_highres ;
}
} else {
if ( svga - > bpp > = 8 & & ! svga - > lowres ) {
if ( svga - > bpp = = 16 ) {
svga - > render = svga_render_16bpp_highres ;
svga - > hdisp > > = 1 ;
} else if ( svga - > bpp = = 15 ) {
svga - > render = svga_render_15bpp_highres ;
svga - > hdisp > > = 1 ;
} else {
svga - > render = svga_render_8bpp_highres ;
}
}
}
2016-06-26 00:34:39 +02:00
}
2022-08-31 19:19:29 -04:00
static void
2023-06-09 23:46:54 -04:00
paradise_write ( uint32_t addr , uint8_t val , void * priv )
2016-06-26 00:34:39 +02:00
{
2023-06-09 23:46:54 -04:00
paradise_t * paradise = ( paradise_t * ) priv ;
2022-08-31 19:19:29 -04:00
svga_t * svga = & paradise - > svga ;
2023-06-01 18:32:25 -04:00
uint32_t prev_addr ;
uint32_t prev_addr2 ;
2022-08-31 19:19:29 -04:00
addr = ( addr & 0x7fff ) + paradise - > write_bank [ ( addr > > 15 ) & 3 ] ;
/*Could be done in a better way but it works.*/
if ( ! svga - > lowres ) {
if ( paradise - > check ) {
prev_addr = addr & 3 ;
prev_addr2 = addr & 0xfffc ;
if ( ( addr & 3 ) = = 3 ) {
if ( ( addr & 0x30000 ) = = 0x20000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x10000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x00000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
} else if ( ( addr & 3 ) = = 2 ) {
if ( ( addr & 0x30000 ) = = 0x30000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x10000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x00000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
} else if ( ( addr & 3 ) = = 1 ) {
if ( ( addr & 0x30000 ) = = 0x30000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x20000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x00000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
} else if ( ( addr & 3 ) = = 0 ) {
if ( ( addr & 0x30000 ) = = 0x30000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x20000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x10000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
}
}
}
svga_write_linear ( addr , val , svga ) ;
2016-06-26 00:34:39 +02:00
}
2022-08-31 19:19:29 -04:00
static void
2023-06-09 23:46:54 -04:00
paradise_writew ( uint32_t addr , uint16_t val , void * priv )
2018-02-01 03:14:55 +01:00
{
2023-06-09 23:46:54 -04:00
paradise_t * paradise = ( paradise_t * ) priv ;
2022-08-31 19:19:29 -04:00
svga_t * svga = & paradise - > svga ;
2023-06-01 18:32:25 -04:00
uint32_t prev_addr ;
uint32_t prev_addr2 ;
2022-08-31 19:19:29 -04:00
addr = ( addr & 0x7fff ) + paradise - > write_bank [ ( addr > > 15 ) & 3 ] ;
/*Could be done in a better way but it works.*/
if ( ! svga - > lowres ) {
if ( paradise - > check ) {
prev_addr = addr & 3 ;
prev_addr2 = addr & 0xfffc ;
if ( ( addr & 3 ) = = 3 ) {
if ( ( addr & 0x30000 ) = = 0x20000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x10000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x00000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
} else if ( ( addr & 3 ) = = 2 ) {
if ( ( addr & 0x30000 ) = = 0x30000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x10000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x00000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
} else if ( ( addr & 3 ) = = 1 ) {
if ( ( addr & 0x30000 ) = = 0x30000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x20000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x00000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
} else if ( ( addr & 3 ) = = 0 ) {
if ( ( addr & 0x30000 ) = = 0x30000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x20000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x10000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
}
}
}
svga_writew_linear ( addr , val , svga ) ;
2018-02-01 03:14:55 +01:00
}
2016-06-26 00:34:39 +02:00
2022-08-31 19:19:29 -04:00
static uint8_t
2023-06-09 23:46:54 -04:00
paradise_read ( uint32_t addr , void * priv )
2016-06-26 00:34:39 +02:00
{
2023-06-09 23:46:54 -04:00
paradise_t * paradise = ( paradise_t * ) priv ;
2022-08-31 19:19:29 -04:00
svga_t * svga = & paradise - > svga ;
2023-06-01 18:32:25 -04:00
uint32_t prev_addr ;
uint32_t prev_addr2 ;
2022-08-31 19:19:29 -04:00
addr = ( addr & 0x7fff ) + paradise - > read_bank [ ( addr > > 15 ) & 3 ] ;
/*Could be done in a better way but it works.*/
if ( ! svga - > lowres ) {
if ( paradise - > check ) {
prev_addr = addr & 3 ;
prev_addr2 = addr & 0xfffc ;
if ( ( addr & 3 ) = = 3 ) {
if ( ( addr & 0x30000 ) = = 0x20000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x10000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x00000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
} else if ( ( addr & 3 ) = = 2 ) {
if ( ( addr & 0x30000 ) = = 0x30000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x10000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x00000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
} else if ( ( addr & 3 ) = = 1 ) {
if ( ( addr & 0x30000 ) = = 0x30000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x20000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x00000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
} else if ( ( addr & 3 ) = = 0 ) {
if ( ( addr & 0x30000 ) = = 0x30000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x20000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x10000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
}
}
}
return svga_read_linear ( addr , svga ) ;
2016-06-26 00:34:39 +02:00
}
2022-08-31 19:19:29 -04:00
static uint16_t
2023-06-09 23:46:54 -04:00
paradise_readw ( uint32_t addr , void * priv )
2018-02-01 03:14:55 +01:00
{
2023-06-09 23:46:54 -04:00
paradise_t * paradise = ( paradise_t * ) priv ;
2022-08-31 19:19:29 -04:00
svga_t * svga = & paradise - > svga ;
2023-06-01 18:32:25 -04:00
uint32_t prev_addr ;
uint32_t prev_addr2 ;
2022-08-31 19:19:29 -04:00
addr = ( addr & 0x7fff ) + paradise - > read_bank [ ( addr > > 15 ) & 3 ] ;
/*Could be done in a better way but it works.*/
if ( ! svga - > lowres ) {
if ( paradise - > check ) {
prev_addr = addr & 3 ;
prev_addr2 = addr & 0xfffc ;
if ( ( addr & 3 ) = = 3 ) {
if ( ( addr & 0x30000 ) = = 0x20000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x10000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x00000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
} else if ( ( addr & 3 ) = = 2 ) {
if ( ( addr & 0x30000 ) = = 0x30000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x10000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x00000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
} else if ( ( addr & 3 ) = = 1 ) {
if ( ( addr & 0x30000 ) = = 0x30000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x20000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x00000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
} else if ( ( addr & 3 ) = = 0 ) {
if ( ( addr & 0x30000 ) = = 0x30000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x20000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
else if ( ( addr & 0x30000 ) = = 0x10000 )
addr = ( addr > > 16 ) | ( prev_addr < < 16 ) | prev_addr2 ;
}
}
}
return svga_readw_linear ( addr , svga ) ;
2018-02-01 03:14:55 +01:00
}
2017-10-07 00:46:54 -04:00
2022-08-31 19:19:29 -04:00
void *
paradise_init ( const device_t * info , uint32_t memsize )
2017-12-31 06:37:19 +01:00
{
2022-08-31 19:19:29 -04:00
paradise_t * paradise = malloc ( sizeof ( paradise_t ) ) ;
svga_t * svga = & paradise - > svga ;
memset ( paradise , 0 , sizeof ( paradise_t ) ) ;
if ( info - > local = = PVGA1A )
video_inform ( VIDEO_FLAG_TYPE_SPECIAL , & timing_paradise_pvga1a ) ;
else
video_inform ( VIDEO_FLAG_TYPE_SPECIAL , & timing_paradise_wd90c ) ;
switch ( info - > local ) {
case PVGA1A :
svga_init ( info , svga , paradise , memsize , /*256kb*/
paradise_recalctimings ,
paradise_in , paradise_out ,
NULL ,
NULL ) ;
paradise - > vram_mask = memsize - 1 ;
svga - > decode_mask = memsize - 1 ;
break ;
case WD90C11 :
svga_init ( info , svga , paradise , 1 < < 19 , /*512kb*/
paradise_recalctimings ,
paradise_in , paradise_out ,
NULL ,
NULL ) ;
paradise - > vram_mask = ( 1 < < 19 ) - 1 ;
svga - > decode_mask = ( 1 < < 19 ) - 1 ;
break ;
case WD90C30 :
svga_init ( info , svga , paradise , memsize ,
paradise_recalctimings ,
paradise_in , paradise_out ,
NULL ,
NULL ) ;
paradise - > vram_mask = memsize - 1 ;
svga - > decode_mask = memsize - 1 ;
svga - > ramdac = device_add ( & sc11487_ramdac_device ) ; /*Actually a Winbond W82c487-80, probably a clone.*/
break ;
}
mem_mapping_set_handler ( & svga - > mapping , paradise_read , paradise_readw , NULL , paradise_write , paradise_writew , NULL ) ;
mem_mapping_set_p ( & svga - > mapping , paradise ) ;
io_sethandler ( 0x03c0 , 0x0020 , paradise_in , NULL , NULL , paradise_out , NULL , NULL , paradise ) ;
/* Common to all three types. */
svga - > crtc [ 0x31 ] = ' W ' ;
svga - > crtc [ 0x32 ] = ' D ' ;
svga - > crtc [ 0x33 ] = ' 9 ' ;
svga - > crtc [ 0x34 ] = ' 0 ' ;
svga - > crtc [ 0x35 ] = ' C ' ;
switch ( info - > local ) {
case WD90C11 :
svga - > crtc [ 0x36 ] = ' 1 ' ;
svga - > crtc [ 0x37 ] = ' 1 ' ;
io_sethandler ( 0x46e8 , 0x0001 , paradise_in , NULL , NULL , paradise_out , NULL , NULL , paradise ) ;
break ;
case WD90C30 :
svga - > crtc [ 0x36 ] = ' 3 ' ;
svga - > crtc [ 0x37 ] = ' 0 ' ;
break ;
}
svga - > bpp = 8 ;
svga - > miscout = 1 ;
paradise - > type = info - > local ;
return paradise ;
2017-12-31 06:37:19 +01:00
}
2022-08-31 19:19:29 -04:00
static void *
paradise_pvga1a_ncr3302_init ( const device_t * info )
2021-01-23 17:59:02 +01:00
{
2022-08-31 19:19:29 -04:00
paradise_t * paradise = paradise_init ( info , 1 < < 18 ) ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
if ( paradise )
rom_init ( & paradise - > bios_rom , " roms/machines/3302/c000-wd_1987-1989-740011-003058-019c.bin " , 0xc0000 , 0x8000 , 0x7fff , 0 , MEM_MAPPING_EXTERNAL ) ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
return paradise ;
2021-01-23 17:59:02 +01:00
}
2022-08-31 19:19:29 -04:00
static void *
paradise_pvga1a_pc2086_init ( const device_t * info )
2016-06-26 00:34:39 +02:00
{
2022-08-31 19:19:29 -04:00
paradise_t * paradise = paradise_init ( info , 1 < < 18 ) ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
if ( paradise )
rom_init ( & paradise - > bios_rom , " roms/machines/pc2086/40186.ic171 " , 0xc0000 , 0x8000 , 0x7fff , 0 , MEM_MAPPING_EXTERNAL ) ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
return paradise ;
2016-06-26 00:34:39 +02:00
}
2021-01-23 17:59:02 +01:00
2022-08-31 19:19:29 -04:00
static void *
paradise_pvga1a_pc3086_init ( const device_t * info )
2016-06-26 00:34:39 +02:00
{
2022-08-31 19:19:29 -04:00
paradise_t * paradise = paradise_init ( info , 1 < < 18 ) ;
2016-06-26 00:34:39 +02:00
2022-08-31 19:19:29 -04:00
if ( paradise )
rom_init ( & paradise - > bios_rom , " roms/machines/pc3086/c000.bin " , 0xc0000 , 0x8000 , 0x7fff , 0 , MEM_MAPPING_EXTERNAL ) ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
return paradise ;
2016-06-26 00:34:39 +02:00
}
2022-08-31 19:19:29 -04:00
static void *
paradise_pvga1a_standalone_init ( const device_t * info )
2017-12-31 06:37:19 +01:00
{
2022-08-31 19:19:29 -04:00
paradise_t * paradise ;
uint32_t memory = 512 ;
2017-12-31 06:37:19 +01:00
2022-08-31 19:19:29 -04:00
memory = device_get_config_int ( " memory " ) ;
memory < < = 10 ;
2017-12-31 06:37:19 +01:00
2022-08-31 19:19:29 -04:00
paradise = paradise_init ( info , memory ) ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
if ( paradise )
rom_init ( & paradise - > bios_rom , " roms/video/pvga1a/BIOS.BIN " , 0xc0000 , 0x8000 , 0x7fff , 0 , MEM_MAPPING_EXTERNAL ) ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
return paradise ;
2017-12-31 06:37:19 +01:00
}
2022-08-31 19:19:29 -04:00
static int
paradise_pvga1a_standalone_available ( void )
2017-12-31 06:37:19 +01:00
{
2022-08-31 19:19:29 -04:00
return rom_present ( " roms/video/pvga1a/BIOS.BIN " ) ;
2017-12-31 06:37:19 +01:00
}
2022-08-31 19:19:29 -04:00
static void *
paradise_wd90c11_megapc_init ( const device_t * info )
2016-06-26 00:34:39 +02:00
{
2022-08-31 19:19:29 -04:00
paradise_t * paradise = paradise_init ( info , 0 ) ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
if ( paradise )
rom_init_interleaved ( & paradise - > bios_rom ,
" roms/machines/megapc/41651-bios lo.u18 " ,
" roms/machines/megapc/211253-bios hi.u19 " ,
0xc0000 , 0x8000 , 0x7fff , 0 , MEM_MAPPING_EXTERNAL ) ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
return paradise ;
2016-06-26 00:34:39 +02:00
}
2022-08-31 19:19:29 -04:00
static void *
paradise_wd90c11_standalone_init ( const device_t * info )
2017-12-31 06:37:19 +01:00
{
2022-08-31 19:19:29 -04:00
paradise_t * paradise = paradise_init ( info , 0 ) ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
if ( paradise )
rom_init ( & paradise - > bios_rom , " roms/video/wd90c11/WD90C11.VBI " , 0xc0000 , 0x8000 , 0x7fff , 0 , MEM_MAPPING_EXTERNAL ) ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
return paradise ;
2017-12-31 06:37:19 +01:00
}
2022-08-31 19:19:29 -04:00
static int
paradise_wd90c11_standalone_available ( void )
2016-06-26 00:34:39 +02:00
{
2022-08-31 19:19:29 -04:00
return rom_present ( " roms/video/wd90c11/WD90C11.VBI " ) ;
2017-12-31 06:37:19 +01:00
}
2022-08-31 19:19:29 -04:00
static void *
paradise_wd90c30_standalone_init ( const device_t * info )
2017-12-31 06:37:19 +01:00
{
2022-08-31 19:19:29 -04:00
paradise_t * paradise ;
uint32_t memory = 512 ;
2017-12-31 06:37:19 +01:00
2022-08-31 19:19:29 -04:00
memory = device_get_config_int ( " memory " ) ;
memory < < = 10 ;
2017-12-31 06:37:19 +01:00
2022-08-31 19:19:29 -04:00
paradise = paradise_init ( info , memory ) ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
if ( paradise )
rom_init ( & paradise - > bios_rom , " roms/video/wd90c30/90C30-LR.VBI " , 0xc0000 , 0x8000 , 0x7fff , 0 , MEM_MAPPING_EXTERNAL ) ;
2017-12-31 06:37:19 +01:00
2022-08-31 19:19:29 -04:00
return paradise ;
2017-12-31 06:37:19 +01:00
}
2022-08-31 19:19:29 -04:00
static int
paradise_wd90c30_standalone_available ( void )
2017-12-31 06:37:19 +01:00
{
2022-08-31 19:19:29 -04:00
return rom_present ( " roms/video/wd90c30/90C30-LR.VBI " ) ;
2016-06-26 00:34:39 +02:00
}
2022-08-31 19:19:29 -04:00
void
2023-06-09 23:46:54 -04:00
paradise_close ( void * priv )
2016-06-26 00:34:39 +02:00
{
2023-06-09 23:46:54 -04:00
paradise_t * paradise = ( paradise_t * ) priv ;
2016-06-26 00:34:39 +02:00
2022-08-31 19:19:29 -04:00
svga_close ( & paradise - > svga ) ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
free ( paradise ) ;
2016-06-26 00:34:39 +02:00
}
2022-08-31 19:19:29 -04:00
void
2023-06-09 23:46:54 -04:00
paradise_speed_changed ( void * priv )
2016-06-26 00:34:39 +02:00
{
2023-06-09 23:46:54 -04:00
paradise_t * paradise = ( paradise_t * ) priv ;
2022-02-20 02:26:27 -05:00
2022-08-31 19:19:29 -04:00
svga_recalctimings ( & paradise - > svga ) ;
2016-06-26 00:34:39 +02:00
}
2022-08-31 19:19:29 -04:00
void
2023-06-09 23:46:54 -04:00
paradise_force_redraw ( void * priv )
2016-06-26 00:34:39 +02:00
{
2023-06-09 23:46:54 -04:00
paradise_t * paradise = ( paradise_t * ) priv ;
2016-06-26 00:34:39 +02:00
2022-08-31 19:19:29 -04:00
paradise - > svga . fullchange = changeframecount ;
2016-06-26 00:34:39 +02:00
}
2022-04-09 20:09:14 -04:00
const device_t paradise_pvga1a_pc2086_device = {
2022-08-31 19:19:29 -04:00
. name = " Paradise PVGA1A (Amstrad PC2086) " ,
2022-04-09 20:09:14 -04:00
. internal_name = " pvga1a_pc2086 " ,
2022-08-31 19:19:29 -04:00
. flags = 0 ,
. local = PVGA1A ,
. init = paradise_pvga1a_pc2086_init ,
. close = paradise_close ,
. reset = NULL ,
2022-04-09 20:09:14 -04:00
{ . available = NULL } ,
. speed_changed = paradise_speed_changed ,
2022-08-31 19:19:29 -04:00
. force_redraw = paradise_force_redraw ,
. config = NULL
2016-06-26 00:34:39 +02:00
} ;
2021-01-23 17:59:02 +01:00
2022-04-09 20:09:14 -04:00
const device_t paradise_pvga1a_pc3086_device = {
2022-08-31 19:19:29 -04:00
. name = " Paradise PVGA1A (Amstrad PC3086) " ,
2022-04-09 20:09:14 -04:00
. internal_name = " pvga1a_pc3086 " ,
2022-08-31 19:19:29 -04:00
. flags = 0 ,
. local = PVGA1A ,
. init = paradise_pvga1a_pc3086_init ,
. close = paradise_close ,
. reset = NULL ,
2022-04-09 20:09:14 -04:00
{ . available = NULL } ,
. speed_changed = paradise_speed_changed ,
2022-08-31 19:19:29 -04:00
. force_redraw = paradise_force_redraw ,
. config = NULL
2016-06-26 00:34:39 +02:00
} ;
2017-12-31 06:37:19 +01:00
2022-04-09 20:09:14 -04:00
static const device_config_t paradise_pvga1a_config [ ] = {
2022-08-31 19:19:29 -04:00
// clang-format off
2022-04-09 20:09:14 -04:00
{
. name = " memory " ,
. description = " Memory size " ,
. type = CONFIG_SELECTION ,
. default_int = 512 ,
. selection = {
{
. description = " 256 kB " ,
. value = 256
} ,
{
. description = " 512 kB " ,
. value = 512
} ,
{
. description = " "
}
2017-12-31 06:37:19 +01:00
}
2022-04-09 20:09:14 -04:00
} ,
{
. type = CONFIG_END
}
2022-08-31 19:19:29 -04:00
// clang-format on
2017-12-31 06:37:19 +01:00
} ;
2022-04-09 20:09:14 -04:00
const device_t paradise_pvga1a_ncr3302_device = {
2022-08-31 19:19:29 -04:00
. name = " Paradise PVGA1A (NCR 3302) " ,
2022-04-09 20:09:14 -04:00
. internal_name = " pvga1a_ncr3302 " ,
2022-08-31 19:19:29 -04:00
. flags = 0 ,
. local = PVGA1A ,
. init = paradise_pvga1a_ncr3302_init ,
. close = paradise_close ,
. reset = NULL ,
2022-04-09 20:09:14 -04:00
{ . available = NULL } ,
. speed_changed = paradise_speed_changed ,
2022-08-31 19:19:29 -04:00
. force_redraw = paradise_force_redraw ,
. config = paradise_pvga1a_config
2021-01-23 17:59:02 +01:00
} ;
2022-04-09 20:09:14 -04:00
const device_t paradise_pvga1a_device = {
2022-08-31 19:19:29 -04:00
. name = " Paradise PVGA1A " ,
2022-04-09 20:09:14 -04:00
. internal_name = " pvga1a " ,
2022-08-31 19:19:29 -04:00
. flags = DEVICE_ISA ,
. local = PVGA1A ,
. init = paradise_pvga1a_standalone_init ,
. close = paradise_close ,
. reset = NULL ,
2022-04-09 20:09:14 -04:00
{ . available = paradise_pvga1a_standalone_available } ,
. speed_changed = paradise_speed_changed ,
2022-08-31 19:19:29 -04:00
. force_redraw = paradise_force_redraw ,
. config = paradise_pvga1a_config
2017-12-31 06:37:19 +01:00
} ;
2022-04-09 20:09:14 -04:00
const device_t paradise_wd90c11_megapc_device = {
2022-08-31 19:19:29 -04:00
. name = " Paradise WD90C11 (Amstrad MegaPC) " ,
2022-04-09 20:09:14 -04:00
. internal_name = " wd90c11_megapc " ,
2022-08-31 19:19:29 -04:00
. flags = 0 ,
. local = WD90C11 ,
. init = paradise_wd90c11_megapc_init ,
. close = paradise_close ,
. reset = NULL ,
2022-04-09 20:09:14 -04:00
{ . available = NULL } ,
. speed_changed = paradise_speed_changed ,
2022-08-31 19:19:29 -04:00
. force_redraw = paradise_force_redraw ,
. config = NULL
2016-06-26 00:34:39 +02:00
} ;
2022-04-09 20:09:14 -04:00
const device_t paradise_wd90c11_device = {
2022-08-31 19:19:29 -04:00
. name = " Paradise WD90C11-LR " ,
2022-04-09 20:09:14 -04:00
. internal_name = " wd90c11 " ,
2022-08-31 19:19:29 -04:00
. flags = DEVICE_ISA ,
. local = WD90C11 ,
. init = paradise_wd90c11_standalone_init ,
. close = paradise_close ,
. reset = NULL ,
2022-04-09 20:09:14 -04:00
{ . available = paradise_wd90c11_standalone_available } ,
. speed_changed = paradise_speed_changed ,
2022-08-31 19:19:29 -04:00
. force_redraw = paradise_force_redraw ,
. config = NULL
2016-06-26 00:34:39 +02:00
} ;
2017-12-31 06:37:19 +01:00
2022-02-26 23:31:28 -05:00
static const device_config_t paradise_wd90c30_config [ ] = {
2022-08-31 19:19:29 -04:00
// clang-format off
2022-02-26 23:31:28 -05:00
{
2022-04-09 20:09:14 -04:00
. name = " memory " ,
. description = " Memory size " ,
. type = CONFIG_SELECTION ,
. default_int = 1024 ,
. selection = {
{
. description = " 512 kB " ,
. value = 512
} ,
{
. description = " 1 MB " ,
. value = 1024
} ,
{
. description = " "
}
2017-12-31 06:37:19 +01:00
}
2022-02-26 23:31:28 -05:00
} ,
2022-04-09 20:09:14 -04:00
{
. type = CONFIG_END
}
2022-11-19 08:49:04 -05:00
// clang-format on
2017-12-31 06:37:19 +01:00
} ;
2022-03-13 21:43:45 -04:00
const device_t paradise_wd90c30_device = {
2022-08-31 19:19:29 -04:00
. name = " Paradise WD90C30-LR " ,
2022-03-13 21:43:45 -04:00
. internal_name = " wd90c30 " ,
2022-08-31 19:19:29 -04:00
. flags = DEVICE_ISA ,
. local = WD90C30 ,
. init = paradise_wd90c30_standalone_init ,
. close = paradise_close ,
. reset = NULL ,
2022-03-13 21:43:45 -04:00
{ . available = paradise_wd90c30_standalone_available } ,
. speed_changed = paradise_speed_changed ,
2022-08-31 19:19:29 -04:00
. force_redraw = paradise_force_redraw ,
. config = paradise_wd90c30_config
2017-12-31 06:37:19 +01:00
} ;