Add DDC/plug and play monitor support to S3 ViRGE.
This commit is contained in:
parent
5eb6f4d168
commit
7e2c6a5344
3 changed files with 40 additions and 3 deletions
|
|
@ -251,6 +251,12 @@ void ddc_i2c_change(int new_clock, int new_data)
|
||||||
case I2C_TRANSMIT_START:
|
case I2C_TRANSMIT_START:
|
||||||
if (!i2c.clock && new_clock)
|
if (!i2c.clock && new_clock)
|
||||||
i2c.state = I2C_TRANSMIT;
|
i2c.state = I2C_TRANSMIT;
|
||||||
|
if (i2c.clock && new_clock && !i2c.last_data && new_data) /*Stop bit*/
|
||||||
|
{
|
||||||
|
// pclog("Stop bit received\n");
|
||||||
|
i2c.state = I2C_IDLE;
|
||||||
|
prom_stop();
|
||||||
|
}
|
||||||
case I2C_TRANSMIT:
|
case I2C_TRANSMIT:
|
||||||
if (!i2c.clock && new_clock)
|
if (!i2c.clock && new_clock)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
BIN
src/vid_ddc.o
BIN
src/vid_ddc.o
Binary file not shown.
|
|
@ -8,6 +8,7 @@
|
||||||
#include "rom.h"
|
#include "rom.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
#include "vid_ddc.h"
|
||||||
#include "vid_s3_virge.h"
|
#include "vid_s3_virge.h"
|
||||||
#include "vid_svga.h"
|
#include "vid_svga.h"
|
||||||
#include "vid_svga_render.h"
|
#include "vid_svga_render.h"
|
||||||
|
|
@ -235,6 +236,8 @@ typedef struct virge_t
|
||||||
int virge_busy;
|
int virge_busy;
|
||||||
|
|
||||||
uint8_t subsys_stat, subsys_cntl;
|
uint8_t subsys_stat, subsys_cntl;
|
||||||
|
|
||||||
|
uint8_t serialport;
|
||||||
} virge_t;
|
} virge_t;
|
||||||
|
|
||||||
static inline void wake_fifo_thread(virge_t *virge)
|
static inline void wake_fifo_thread(virge_t *virge)
|
||||||
|
|
@ -306,6 +309,11 @@ enum
|
||||||
#define INT_3DF_EMP (1 << 6)
|
#define INT_3DF_EMP (1 << 6)
|
||||||
#define INT_MASK 0xff
|
#define INT_MASK 0xff
|
||||||
|
|
||||||
|
#define SERIAL_PORT_SCW (1 << 0)
|
||||||
|
#define SERIAL_PORT_SDW (1 << 1)
|
||||||
|
#define SERIAL_PORT_SCR (1 << 2)
|
||||||
|
#define SERIAL_PORT_SDR (1 << 3)
|
||||||
|
|
||||||
static void s3_virge_update_irqs(virge_t *virge)
|
static void s3_virge_update_irqs(virge_t *virge)
|
||||||
{
|
{
|
||||||
if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & virge->subsys_cntl & INT_MASK))
|
if ((virge->svga.crtc[0x32] & 0x10) && (virge->subsys_stat & virge->subsys_cntl & INT_MASK))
|
||||||
|
|
@ -786,6 +794,14 @@ static uint8_t s3_virge_mmio_read(uint32_t addr, void *p)
|
||||||
case 0x83d8: case 0x83d9: case 0x83da: case 0x83db:
|
case 0x83d8: case 0x83d9: case 0x83da: case 0x83db:
|
||||||
case 0x83dc: case 0x83dd: case 0x83de: case 0x83df:
|
case 0x83dc: case 0x83dd: case 0x83de: case 0x83df:
|
||||||
return s3_virge_in(addr & 0x3ff, p);
|
return s3_virge_in(addr & 0x3ff, p);
|
||||||
|
|
||||||
|
case 0xff20: case 0xff21:
|
||||||
|
ret = virge->serialport & ~(SERIAL_PORT_SCR | SERIAL_PORT_SDR);
|
||||||
|
if ((virge->serialport & SERIAL_PORT_SCW) && ddc_read_clock())
|
||||||
|
ret |= SERIAL_PORT_SCR;
|
||||||
|
if ((virge->serialport & SERIAL_PORT_SDW) && ddc_read_data())
|
||||||
|
ret |= SERIAL_PORT_SDR;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
return 0xff;
|
return 0xff;
|
||||||
}
|
}
|
||||||
|
|
@ -1355,9 +1371,12 @@ static void s3_virge_mmio_write(uint32_t addr, uint8_t val, void *p)
|
||||||
case 0x83dc: case 0x83dd: case 0x83de: case 0x83df:
|
case 0x83dc: case 0x83dd: case 0x83de: case 0x83df:
|
||||||
s3_virge_out(addr & 0x3ff, val, p);
|
s3_virge_out(addr & 0x3ff, val, p);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
case 0xff20:
|
||||||
|
virge->serialport = val;
|
||||||
|
ddc_i2c_change((val & SERIAL_PORT_SCW) ? 1 : 0, (val & SERIAL_PORT_SDW) ? 1 : 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p)
|
static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p)
|
||||||
{
|
{
|
||||||
|
|
@ -1374,6 +1393,10 @@ static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p)
|
||||||
s3_virge_mmio_write(addr, val, p);
|
s3_virge_mmio_write(addr, val, p);
|
||||||
s3_virge_mmio_write(addr + 1, val >> 8, p);
|
s3_virge_mmio_write(addr + 1, val >> 8, p);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0xff20:
|
||||||
|
s3_virge_mmio_write(addr, val, p);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
|
static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
|
||||||
|
|
@ -1817,6 +1840,10 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p)
|
||||||
|
|
||||||
// s3_virge_triangle(virge);
|
// s3_virge_triangle(virge);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0xff20:
|
||||||
|
s3_virge_mmio_write(addr, val, p);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3916,6 +3943,8 @@ static void *s3_virge_init()
|
||||||
virge->fifo_not_full_event = thread_create_event();
|
virge->fifo_not_full_event = thread_create_event();
|
||||||
virge->fifo_thread = thread_create(fifo_thread, virge);
|
virge->fifo_thread = thread_create(fifo_thread, virge);
|
||||||
|
|
||||||
|
ddc_init();
|
||||||
|
|
||||||
return virge;
|
return virge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -4012,7 +4041,9 @@ static void *s3_virge_375_init()
|
||||||
virge->wake_fifo_thread = thread_create_event();
|
virge->wake_fifo_thread = thread_create_event();
|
||||||
virge->fifo_not_full_event = thread_create_event();
|
virge->fifo_not_full_event = thread_create_event();
|
||||||
virge->fifo_thread = thread_create(fifo_thread, virge);
|
virge->fifo_thread = thread_create(fifo_thread, virge);
|
||||||
|
|
||||||
|
ddc_init();
|
||||||
|
|
||||||
return virge;
|
return virge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue