Re-organisation of video emulation.

This commit is contained in:
TomW 2013-06-24 20:42:35 +01:00
commit 58085bcc87
86 changed files with 8087 additions and 7229 deletions

View file

@ -1,436 +1,487 @@
/*Olivetti M24 video emulation
Essentially double-res CGA*/
#include <stdlib.h>
#include "ibm.h"
#include "device.h"
#include "io.h"
#include "mem.h"
#include "timer.h"
#include "video.h"
#include "vid_olivetti_m24.h"
void m24_recalctimings();
static uint8_t m24_ctrl;
static uint32_t m24_base;
void m24_out(uint16_t addr, uint8_t val, void *priv)
typedef struct m24_t
{
uint8_t crtc[32];
int crtcreg;
uint8_t *vram;
uint8_t charbuffer[256];
uint8_t ctrl;
uint32_t base;
uint8_t cgamode, cgacol;
uint8_t stat;
int linepos, displine;
int sc, vc;
int con, coff, cursoron, blink;
int vsynctime, vadj;
int lineff;
uint16_t ma, maback;
int dispon;
int dispontime, dispofftime, vidtime;
int firstline, lastline;
} m24_t;
static uint8_t crtcmask[32] =
{
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
void m24_recalctimings(m24_t *m24);
void m24_out(uint16_t addr, uint8_t val, void *p)
{
m24_t *m24 = (m24_t *)p;
uint8_t old;
pclog("m24_out %04X %02X\n", addr, val);
switch (addr)
{
case 0x3D4:
crtcreg = val & 31;
case 0x3d4:
m24->crtcreg = val & 31;
return;
case 0x3D5:
old = crtc[crtcreg];
crtc[crtcreg] = val & crtcmask[crtcreg];
case 0x3d5:
old = m24->crtc[m24->crtcreg];
m24->crtc[m24->crtcreg] = val & crtcmask[m24->crtcreg];
if (old != val)
{
if (crtcreg < 0xE || crtcreg > 0x10)
if (m24->crtcreg < 0xe || m24->crtcreg > 0x10)
{
fullchange = changeframecount;
m24_recalctimings();
m24_recalctimings(m24);
}
}
return;
case 0x3D8:
cgamode = val;
case 0x3d8:
m24->cgamode = val;
return;
case 0x3D9:
cgacol = val;
case 0x3d9:
m24->cgacol = val;
return;
case 0x3de:
m24_ctrl = val;
m24_base = (val & 0x08) ? 0x4000 : 0;
m24->ctrl = val;
m24->base = (val & 0x08) ? 0x4000 : 0;
return;
}
}
uint8_t m24_in(uint16_t addr, void *priv)
uint8_t m24_in(uint16_t addr, void *p)
{
m24_t *m24 = (m24_t *)p;
switch (addr)
{
case 0x3D4:
return crtcreg;
case 0x3D5:
return crtc[crtcreg];
case 0x3DA:
return cgastat;
case 0x3d4:
return m24->crtcreg;
case 0x3d5:
return m24->crtc[m24->crtcreg];
case 0x3da:
return m24->stat;
}
return 0xFF;
return 0xff;
}
static uint8_t charbuffer[256];
void m24_write(uint32_t addr, uint8_t val, void *priv)
void m24_write(uint32_t addr, uint8_t val, void *p)
{
vram[addr & 0x7FFF]=val;
charbuffer[ ((int)(((dispontime - vidtime) * 2) / (CGACONST / 2))) & 0xfc] = val;
charbuffer[(((int)(((dispontime - vidtime) * 2) / (CGACONST / 2))) & 0xfc) | 1] = val;
m24_t *m24 = (m24_t *)p;
m24->vram[addr & 0x7FFF]=val;
m24->charbuffer[ ((int)(((m24->dispontime - m24->vidtime) * 2) / (CGACONST / 2))) & 0xfc] = val;
m24->charbuffer[(((int)(((m24->dispontime - m24->vidtime) * 2) / (CGACONST / 2))) & 0xfc) | 1] = val;
}
uint8_t m24_read(uint32_t addr, void *priv)
uint8_t m24_read(uint32_t addr, void *p)
{
return vram[addr & 0x7FFF];
m24_t *m24 = (m24_t *)p;
return m24->vram[addr & 0x7FFF];
}
void m24_recalctimings()
void m24_recalctimings(m24_t *m24)
{
double _dispontime, _dispofftime;
if (cgamode & 1)
double _dispontime, _dispofftime, disptime;
if (m24->cgamode & 1)
{
disptime = crtc[0] + 1;
_dispontime = crtc[1];
disptime = m24->crtc[0] + 1;
_dispontime = m24->crtc[1];
}
else
{
disptime = (crtc[0] + 1) << 1;
_dispontime = crtc[1] << 1;
disptime = (m24->crtc[0] + 1) << 1;
_dispontime = m24->crtc[1] << 1;
}
_dispofftime = disptime - _dispontime;
// printf("%i %f %f %f %i %i\n",cgamode&1,disptime,dispontime,dispofftime,crtc[0],crtc[1]);
_dispontime *= CGACONST / 2;
_dispofftime *= CGACONST / 2;
// printf("Timings - on %f off %f frame %f second %f\n",dispontime,dispofftime,(dispontime+dispofftime)*262.0,(dispontime+dispofftime)*262.0*59.92);
dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
m24->dispontime = (int)(_dispontime * (1 << TIMER_SHIFT));
m24->dispofftime = (int)(_dispofftime * (1 << TIMER_SHIFT));
}
static int linepos,displine;
static int sc,vc;
static int cgadispon;
static int con,coff,cursoron,cgablink;
static int vsynctime,vadj;
static int m24_lineff = 0;
static uint16_t ma,maback;
void m24_poll()
void m24_poll(void *p)
{
uint16_t ca=(crtc[15]|(crtc[14]<<8))&0x3FFF;
m24_t *m24 = (m24_t *)p;
uint16_t ca = (m24->crtc[15] | (m24->crtc[14] << 8)) & 0x3fff;
int drawcursor;
int x,c;
int x, c;
int oldvc;
uint8_t chr,attr;
uint16_t dat,dat2;
uint8_t chr, attr;
uint16_t dat, dat2;
int cols[4];
int col;
int oldsc;
if (!linepos)
if (!m24->linepos)
{
// pclog("Line poll %i %i %i %i - %04X %i %i %i\n", m24_lineff, vc, sc, vadj, ma, firstline, lastline, displine);
vidtime+=dispofftime;
cgastat|=1;
linepos=1;
oldsc=sc;
if ((crtc[8]&3)==3) sc=(sc<<1)&7;
if (cgadispon)
m24->vidtime += m24->dispofftime;
m24->stat |= 1;
m24->linepos = 1;
oldsc = m24->sc;
if ((m24->crtc[8] & 3) == 3)
m24->sc = (m24->sc << 1) & 7;
if (m24->dispon)
{
if (displine<firstline)
pclog("dispon %i\n", m24->linepos);
if (m24->displine < m24->firstline)
{
firstline=displine;
m24->firstline = m24->displine;
// printf("Firstline %i\n",firstline);
}
lastline=displine;
for (c=0;c<8;c++)
m24->lastline = m24->displine;
for (c = 0; c < 8; c++)
{
if ((cgamode&0x12)==0x12)
if ((m24->cgamode & 0x12) == 0x12)
{
buffer->line[displine][c]=0;
if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=0;
else buffer->line[displine][c+(crtc[1]<<4)+8]=0;
buffer->line[m24->displine][c] = 0;
if (m24->cgamode & 1) buffer->line[m24->displine][c + (m24->crtc[1] << 3) + 8] = 0;
else buffer->line[m24->displine][c + (m24->crtc[1] << 4) + 8] = 0;
}
else
{
buffer->line[displine][c]=(cgacol&15)+16;
if (cgamode&1) buffer->line[displine][c+(crtc[1]<<3)+8]=(cgacol&15)+16;
else buffer->line[displine][c+(crtc[1]<<4)+8]=(cgacol&15)+16;
buffer->line[m24->displine][c] = (m24->cgacol & 15) + 16;
if (m24->cgamode & 1) buffer->line[m24->displine][c + (m24->crtc[1] << 3) + 8] = (m24->cgacol & 15) + 16;
else buffer->line[m24->displine][c + (m24->crtc[1] << 4) + 8] = (m24->cgacol & 15) + 16;
}
}
if (cgamode&1)
if (m24->cgamode & 1)
{
for (x=0;x<crtc[1];x++)
for (x = 0; x < m24->crtc[1]; x++)
{
chr = charbuffer[ x << 1];
attr = charbuffer[(x << 1) + 1];
drawcursor=((ma==ca) && con && cursoron);
if (cgamode&0x20)
chr = m24->charbuffer[ x << 1];
attr = m24->charbuffer[(x << 1) + 1];
drawcursor = ((m24->ma == ca) && m24->con && m24->cursoron);
if (m24->cgamode & 0x20)
{
cols[1]=(attr&15)+16;
cols[0]=((attr>>4)&7)+16;
if ((cgablink&16) && (attr&0x80) && !drawcursor) cols[1]=cols[0];
cols[1] = (attr & 15) + 16;
cols[0] = ((attr >> 4) & 7) + 16;
if ((m24->blink & 16) && (attr & 0x80) && !drawcursor)
cols[1] = cols[0];
}
else
{
cols[1]=(attr&15)+16;
cols[0]=(attr>>4)+16;
cols[1] = (attr & 15) + 16;
cols[0] = (attr >> 4) + 16;
}
if (drawcursor)
{
for (c=0;c<8;c++)
buffer->line[displine][(x<<3)+c+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0]^15;
for (c = 0; c < 8; c++)
buffer->line[m24->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
}
else
{
for (c=0;c<8;c++)
buffer->line[displine][(x<<3)+c+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0];
for (c = 0; c < 8; c++)
buffer->line[m24->displine][(x << 3) + c + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0];
}
ma++;
m24->ma++;
}
}
else if (!(cgamode&2))
else if (!(m24->cgamode & 2))
{
for (x=0;x<crtc[1];x++)
for (x = 0; x < m24->crtc[1]; x++)
{
chr=vram[((ma<<1)&0x3FFF) + m24_base];
attr=vram[(((ma<<1)+1)&0x3FFF) + m24_base];
drawcursor=((ma==ca) && con && cursoron);
if (cgamode&0x20)
chr = m24->vram[((m24->ma << 1) & 0x3fff) + m24->base];
attr = m24->vram[(((m24->ma << 1) + 1) & 0x3fff) + m24->base];
drawcursor = ((m24->ma == ca) && m24->con && m24->cursoron);
if (m24->cgamode & 0x20)
{
cols[1]=(attr&15)+16;
cols[0]=((attr>>4)&7)+16;
if ((cgablink&16) && (attr&0x80)) cols[1]=cols[0];
cols[1] = (attr & 15) + 16;
cols[0] = ((attr >> 4) & 7) + 16;
if ((m24->blink & 16) && (attr & 0x80))
cols[1] = cols[0];
}
else
{
cols[1]=(attr&15)+16;
cols[0]=(attr>>4)+16;
cols[1] = (attr & 15) + 16;
cols[0] = (attr >> 4) + 16;
}
ma++;
m24->ma++;
if (drawcursor)
{
for (c=0;c<8;c++)
buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0]^15;
for (c = 0; c < 8; c++)
buffer->line[m24->displine][(x << 4) + (c << 1) + 8] =
buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
}
else
{
for (c=0;c<8;c++)
buffer->line[displine][(x<<4)+(c<<1)+8]=buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[(fontdatm[chr][((sc & 7) << 1) | m24_lineff]&(1<<(c^7)))?1:0];
for (c = 0; c < 8; c++)
buffer->line[m24->displine][(x << 4) + (c << 1) + 8] =
buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr][((m24->sc & 7) << 1) | m24->lineff] & (1 << (c ^ 7))) ? 1 : 0];
}
}
}
else if (!(cgamode&16))
else if (!(m24->cgamode & 16))
{
cols[0]=(cgacol&15)|16;
col=(cgacol&16)?24:16;
if (cgamode&4)
cols[0] = (m24->cgacol & 15) | 16;
col = (m24->cgacol & 16) ? 24 : 16;
if (m24->cgamode & 4)
{
cols[1]=col|3;
cols[2]=col|4;
cols[3]=col|7;
cols[1] = col | 3;
cols[2] = col | 4;
cols[3] = col | 7;
}
else if (cgacol&32)
else if (m24->cgacol & 32)
{
cols[1]=col|3;
cols[2]=col|5;
cols[3]=col|7;
cols[1] = col | 3;
cols[2] = col | 5;
cols[3] = col | 7;
}
else
{
cols[1]=col|2;
cols[2]=col|4;
cols[3]=col|6;
cols[1] = col | 2;
cols[2] = col | 4;
cols[3] = col | 6;
}
for (x=0;x<crtc[1];x++)
for (x = 0; x < m24->crtc[1]; x++)
{
dat=(vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000) + m24_base]<<8)|vram[((ma<<1)&0x1FFF)+((sc&1)*0x2000)+1 + m24_base];
ma++;
for (c=0;c<8;c++)
dat = (m24->vram[((m24->ma << 1) & 0x1fff) + ((m24->sc & 1) * 0x2000) + m24->base] << 8) |
m24->vram[((m24->ma << 1) & 0x1fff) + ((m24->sc & 1) * 0x2000) + 1 + m24->base];
m24->ma++;
for (c = 0; c < 8; c++)
{
buffer->line[displine][(x<<4)+(c<<1)+8]=
buffer->line[displine][(x<<4)+(c<<1)+1+8]=cols[dat>>14];
dat<<=2;
buffer->line[m24->displine][(x << 4) + (c << 1) + 8] =
buffer->line[m24->displine][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
dat <<= 2;
}
}
}
else
{
if (m24_ctrl & 1)
if (m24->ctrl & 1)
{
dat2 = ((sc & 1) * 0x4000) | (m24_lineff * 0x2000);
cols[0]=0; cols[1]=/*(cgacol&15)*/15+16;
dat2 = ((m24->sc & 1) * 0x4000) | (m24->lineff * 0x2000);
cols[0] = 0; cols[1] = /*(m24->cgacol & 15)*/15 + 16;
}
else
{
dat2 = (sc & 1) * 0x2000;
cols[0]=0; cols[1]=(cgacol&15)+16;
dat2 = (m24->sc & 1) * 0x2000;
cols[0] = 0; cols[1] = (m24->cgacol & 15) + 16;
}
for (x=0;x<crtc[1];x++)
for (x = 0; x < m24->crtc[1]; x++)
{
dat=(vram[((ma<<1)&0x1FFF) + dat2]<<8) | vram[((ma<<1)&0x1FFF) + dat2 + 1];
ma++;
for (c=0;c<16;c++)
dat = (m24->vram[((m24->ma << 1) & 0x1fff) + dat2] << 8) | m24->vram[((m24->ma << 1) & 0x1fff) + dat2 + 1];
m24->ma++;
for (c = 0; c < 16; c++)
{
buffer->line[displine][(x<<4)+c+8]=cols[dat>>15];
dat<<=1;
buffer->line[m24->displine][(x << 4) + c + 8] = cols[dat >> 15];
dat <<= 1;
}
}
}
}
else
{
cols[0]=((cgamode&0x12)==0x12)?0:(cgacol&15)+16;
if (cgamode&1) hline(buffer,0,displine,(crtc[1]<<3)+16,cols[0]);
else hline(buffer,0,displine,(crtc[1]<<4)+16,cols[0]);
cols[0] = ((m24->cgamode & 0x12) == 0x12) ? 0 : (m24->cgacol & 15) + 16;
if (m24->cgamode & 1) hline(buffer, 0, m24->displine, (m24->crtc[1] << 3) + 16, cols[0]);
else hline(buffer, 0, m24->displine, (m24->crtc[1] << 4) + 16, cols[0]);
}
if (cgamode&1) x=(crtc[1]<<3)+16;
else x=(crtc[1]<<4)+16;
if (m24->cgamode & 1) x = (m24->crtc[1] << 3) + 16;
else x = (m24->crtc[1] << 4) + 16;
sc=oldsc;
if (vc==crtc[7] && !sc)
cgastat|=8;
displine++;
if (displine>=720) displine=0;
m24->sc = oldsc;
if (m24->vc == m24->crtc[7] && !m24->sc)
m24->stat |= 8;
m24->displine++;
if (m24->displine >= 720) m24->displine = 0;
}
else
{
// pclog("Line poll %i %i %i %i\n", m24_lineff, vc, sc, vadj);
vidtime+=dispontime;
if (cgadispon) cgastat&=~1;
linepos=0;
m24_lineff ^= 1;
if (m24_lineff)
m24->vidtime += m24->dispontime;
if (m24->dispon) m24->stat &= ~1;
m24->linepos = 0;
m24->lineff ^= 1;
if (m24->lineff)
{
ma = maback;
m24->ma = m24->maback;
}
else
{
if (vsynctime)
if (m24->vsynctime)
{
vsynctime--;
if (!vsynctime)
cgastat&=~8;
m24->vsynctime--;
if (!m24->vsynctime)
m24->stat &= ~8;
}
if (sc==(crtc[11]&31) || ((crtc[8]&3)==3 && sc==((crtc[11]&31)>>1))) { con=0; coff=1; }
if (vadj)
if (m24->sc == (m24->crtc[11] & 31) || ((m24->crtc[8] & 3) == 3 && m24->sc == ((m24->crtc[11] & 31) >> 1)))
{
m24->con = 0;
m24->coff = 1;
}
if (m24->vadj)
{
sc++;
sc&=31;
ma=maback;
vadj--;
if (!vadj)
m24->sc++;
m24->sc &= 31;
m24->ma = m24->maback;
m24->vadj--;
if (!m24->vadj)
{
cgadispon=1;
ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
sc=0;
m24->dispon = 1;
m24->ma = m24->maback = (m24->crtc[13] | (m24->crtc[12] << 8)) & 0x3fff;
m24->sc = 0;
}
}
else if (sc==crtc[9] || ((crtc[8]&3)==3 && sc==(crtc[9]>>1)))
else if (m24->sc == m24->crtc[9] || ((m24->crtc[8] & 3) == 3 && m24->sc == (m24->crtc[9] >> 1)))
{
maback=ma;
sc=0;
oldvc=vc;
vc++;
vc&=127;
m24->maback = m24->ma;
m24->sc = 0;
oldvc = m24->vc;
m24->vc++;
m24->vc &= 127;
if (vc==crtc[6])
cgadispon=0;
if (m24->vc == m24->crtc[6])
m24->dispon=0;
if (oldvc==crtc[4])
if (oldvc == m24->crtc[4])
{
vc=0;
vadj=crtc[5];
if (!vadj) cgadispon=1;
if (!vadj) ma=maback=(crtc[13]|(crtc[12]<<8))&0x3FFF;
if ((crtc[10]&0x60)==0x20) cursoron=0;
else cursoron=cgablink&16;
m24->vc = 0;
m24->vadj = m24->crtc[5];
if (!m24->vadj) m24->dispon = 1;
if (!m24->vadj) m24->ma = m24->maback = (m24->crtc[13] | (m24->crtc[12] << 8)) & 0x3fff;
if ((m24->crtc[10] & 0x60) == 0x20) m24->cursoron = 0;
else m24->cursoron = m24->blink & 16;
}
if (vc==crtc[7])
if (m24->vc == m24->crtc[7])
{
cgadispon=0;
displine=0;
vsynctime=(crtc[3]>>4)+1;
if (crtc[7])
m24->dispon = 0;
m24->displine = 0;
m24->vsynctime = (m24->crtc[3] >> 4) + 1;
if (m24->crtc[7])
{
if (cgamode&1) x=(crtc[1]<<3)+16;
else x=(crtc[1]<<4)+16;
lastline++;
if (x!=xsize || (lastline-firstline)!=ysize)
if (m24->cgamode & 1) x = (m24->crtc[1] << 3) + 16;
else x = (m24->crtc[1] << 4) + 16;
m24->lastline++;
if (x != xsize || (m24->lastline - m24->firstline) != ysize)
{
xsize=x;
ysize=lastline-firstline;
if (xsize<64) xsize=656;
if (ysize<32) ysize=200;
xsize = x;
ysize = m24->lastline - m24->firstline;
if (xsize < 64) xsize = 656;
if (ysize < 32) ysize = 200;
updatewindowsize(xsize, ysize + 16);
}
startblit();
video_blit_memtoscreen_8(0, firstline - 8, xsize, (lastline - firstline) + 16);
if (readflash) rectfill(screen,winsizex-40,8,winsizex-8,14,0xFFFFFFFF);
readflash=0;
pclog("m24 blit %i %i\n", m24->firstline, m24->lastline);
video_blit_memtoscreen_8(0, m24->firstline - 8, xsize, (m24->lastline - m24->firstline) + 16);
if (readflash) rectfill(screen, winsizex - 40, 8, winsizex - 8, 14, 0xFFFFFFFF);
readflash = 0;
frames++;
endblit();
video_res_x = xsize - 16;
video_res_y = ysize;
if (cgamode & 1)
if (m24->cgamode & 1)
{
video_res_x /= 8;
video_res_y /= (crtc[9] + 1) * 2;
video_res_y /= (m24->crtc[9] + 1) * 2;
video_bpp = 0;
}
else if (!(cgamode & 2))
else if (!(m24->cgamode & 2))
{
video_res_x /= 16;
video_res_y /= (crtc[9] + 1) * 2;
video_res_y /= (m24->crtc[9] + 1) * 2;
video_bpp = 0;
}
else if (!(cgamode&16))
else if (!(m24->cgamode & 16))
{
video_res_x /= 2;
video_res_y /= 2;
video_bpp = 2;
}
else if (!(m24_ctrl & 1))
else if (!(m24->ctrl & 1))
{
video_res_y /= 2;
video_bpp = 1;
}
}
firstline=1000;
lastline=0;
cgablink++;
m24->firstline = 1000;
m24->lastline = 0;
m24->blink++;
}
}
else
{
sc++;
sc&=31;
ma=maback;
m24->sc++;
m24->sc &= 31;
m24->ma = m24->maback;
}
if ((sc==(crtc[10]&31) || ((crtc[8]&3)==3 && sc==((crtc[10]&31)>>1)))) con=1;
if ((m24->sc == (m24->crtc[10] & 31) || ((m24->crtc[8] & 3) == 3 && m24->sc == ((m24->crtc[10] & 31) >> 1))))
m24->con = 1;
}
if (cgadispon && (cgamode&1))
if (m24->dispon && (m24->cgamode & 1))
{
for (x=0;x<(crtc[1]<<1);x++)
charbuffer[x]=vram[(((ma<<1)+x)&0x3FFF) + m24_base];
for (x = 0; x < (m24->crtc[1] << 1); x++)
m24->charbuffer[x] = m24->vram[(((m24->ma << 1) + x) & 0x3fff) + m24->base];
}
}
}
int m24_init()
void *m24_init()
{
mem_sethandler(0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, NULL);
return 0;
int c;
m24_t *m24 = malloc(sizeof(m24_t));
memset(m24, 0, sizeof(m24_t));
m24->vram = malloc(0x8000);
timer_add(m24_poll, &m24->vidtime, TIMER_ALWAYS_ENABLED, m24);
mem_sethandler(0xb8000, 0x08000, m24_read, NULL, NULL, m24_write, NULL, NULL, m24);
io_sethandler(0x03d0, 0x0010, m24_in, NULL, NULL, m24_out, NULL, NULL, m24);
return m24;
}
GFXCARD vid_m24 =
void m24_close(void *p)
{
m24_t *m24 = (m24_t *)p;
free(m24->vram);
free(m24);
}
void m24_speed_changed(void *p)
{
m24_t *m24 = (m24_t *)p;
m24_recalctimings(m24);
}
device_t m24_device =
{
"Olivetti M24 (video)",
m24_init,
/*IO at 3Cx/3Dx*/
m24_out,
m24_in,
/*IO at 3Ax/3Bx*/
video_out_null,
video_in_null,
m24_poll,
m24_recalctimings,
video_write_null,
video_write_null,
m24_write,
video_read_null,
video_read_null,
m24_read
m24_close,
m24_speed_changed,
NULL
};