2 // Megadrive's VDP C++ module
9 int md_vdp::get_screen_info(struct dgen_sinfo
*si
)
11 // Release the pointers to vdp Data to an external function
12 si
->vram
=vram
; si
->cram
=cram
; si
->vsram
=vsram
;
14 // NB - if you change anything, remember to set 'dirt' accordingly
22 rw_mode
=0x00; rw_addr
=0; rw_dma
=0;
23 memset(mem
,0,0x10100);
25 memset(dirt
,0xff,0x35); // mark everything as changed
32 belongs
=0; // Don't know which megadrive vdp belongs to yet
34 mem
=vram
=cram
=vsram
=NULL
;
35 mem
=new unsigned char[0x10100+0x35]; //0x20+0x10+0x4+1 for dirt
37 vram
=mem
+0x00000; cram
=mem
+0x10000; vsram
=mem
+0x10080;
38 dirt
=mem
+0x10100; // VRAM/CRAM/Reg dirty buffer bitfield
39 // Also in 0x34 are global dirt flags (inclduing VSRAM this time)
41 highpal
=new unsigned int[64]; if (highpal
==0) return;
53 mem
=vram
=cram
=vsram
=NULL
;
58 { return (reg
[0x14]<<8)+reg
[0x13]; }
60 int md_vdp::dma_addr()
63 addr
=(reg
[0x17]&0x7f)<<17;
70 // DMA can read from anywhere
71 unsigned char md_vdp::dma_mem_read(int addr
)
73 return belongs
->misc_readbyte(addr
);
76 // Must go through these calls to update the dirty flags
77 int md_vdp::poke_vram(int addr
,unsigned char d
)
79 // Keeping GCC happy over unused vars. [PKH]
84 // Store dirty information down to 256 byte level in bits
86 byt
=addr
>>8; bit
=byt
&7; byt
>>=3; byt
&=0x1f;
87 dirt
[0x00+byt
]|=(1<<bit
); dirt
[0x34]|=1;
92 int md_vdp::poke_cram(int addr
,unsigned char d
)
98 // Store dirty information down to 1byte level in bits
100 byt
=addr
; bit
=byt
&7; byt
>>=3; byt
&=0x0f;
101 dirt
[0x20+byt
]|=(1<<bit
); dirt
[0x34]|=2;
107 int md_vdp::poke_vsram(int addr
,unsigned char d
)
112 { dirt
[0x34]|=4; vsram
[addr
]=d
; }
116 int md_vdp::putword(unsigned short d
)
119 // Called by dma or a straight write
122 case 0x04: poke_vram (rw_addr
+0,d
>>8); poke_vram (rw_addr
+1,d
&0xff); break;
123 case 0x0c: poke_cram (rw_addr
+0,d
>>8); poke_cram (rw_addr
+1,d
&0xff); break;
124 case 0x14: poke_vsram(rw_addr
+0,d
>>8); poke_vsram(rw_addr
+1,d
&0xff); break;
130 int md_vdp::putbyte(unsigned char d
)
133 // Called by dma or a straight write
136 case 0x04: poke_vram (rw_addr
,d
>>8); break;
137 case 0x0c: poke_cram (rw_addr
,d
>>8); break;
138 case 0x14: poke_vsram(rw_addr
,d
>>8); break;
146 unsigned short md_vdp::readword()
148 // Called by a straight read only
149 unsigned short result
=0x0000;
152 case 0x00: result
=( vram
[(rw_addr
+0)&0xffff]<<8)+
153 vram
[(rw_addr
+1)&0xffff]; break;
154 case 0x20: result
=( cram
[(rw_addr
+0)&0x007f]<<8)+
155 cram
[(rw_addr
+1)&0x007f]; break;
156 case 0x10: result
=(vsram
[(rw_addr
+0)&0x007f]<<8)+
157 vsram
[(rw_addr
+1)&0x007f]; break;
163 unsigned char md_vdp::readbyte()
165 // Called by a straight read only
166 unsigned char result
=0x00;
169 case 0x00: result
= vram
[(rw_addr
+0)&0xffff]; break;
170 case 0x20: result
= cram
[(rw_addr
+0)&0x007f]; break;
171 case 0x10: result
=vsram
[(rw_addr
+0)&0x007f]; break;
178 int md_vdp::command(unsigned int cmd
)
180 // Decode 32-bit VDP command
181 rw_dma
=((cmd
&0x80)==0x80);
182 rw_mode
= cmd
&0x00000070;
183 rw_mode
|=(cmd
&0xc0000000)>>28;
184 // mode writes: 04=VRAM 0C=CRAM 14=VSRAM
185 // mode reads: 00=VRAM 20=CRAM 10=VSRAM
186 rw_addr
= (cmd
&0x00000003)<<14;
187 rw_addr
|=(cmd
&0x3fff0000)>>16;
188 // If not dma (or we need a fill),
189 // we are set up to write any data sent to vdp data reg
191 // if it's a dma request do it straight away
194 int mode
=(reg
[0x17]>>6)&3;
195 int s
=0,d
=0,i
=0,len
=0;
196 s
=dma_addr(); d
=rw_addr
; len
=dma_len();
203 val
= dma_mem_read(s
++); val
<<=8;
204 val
|=dma_mem_read(s
++); putword(val
);
214 val
= vram
[(s
++)&0xffff]; val
<<=8;
215 val
|=vram
[(s
++)&0xffff]; putword(val
);
224 int md_vdp::writeword(unsigned short d
)
228 // This is the 'done later on' bit for words
229 // Do a dma fill if it's set up:
230 if (((reg
[0x17]>>6)&3)==2)
247 int md_vdp::writebyte(unsigned char d
)
251 // This is the 'done later on' bit for bytes
252 // Do a dma fill if it's set up:
253 if (((reg
[0x17]>>6)&3)==2)