/** fMSX: portable MSX emulator ******************************/ /** **/ /** Common.h **/ /** **/ /** This file contains screen refresh drivers which are **/ /** common for both X11 and VGA implementations. It is **/ /** included either from Unix.c or MSDOS.c. **/ /** **/ /** Copyright (C) Marat Fayzullin 1994,1995 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ /*************************************************************/ void Sound(void) { byte J; if(Verbose>1) for(J=0;J<3;J++) if(Volume[J]) printf("CHANNEL %c: F=%d V=%d\n",J+'A',Freq[J],Volume[J]); } void Sprites(void) { register byte N,M,I,J,X,Y,C,H; register byte *P,*T,*S; register int L; for(N=0,S=SprTab;(N<32)&&(S[0]!=208);N++,S+=4); H=ScanLines212? 212:192; M=SolidColor0; if(Sprites16x16) for(S-=4;N;N--,S-=4) { C=S[3]&0x0F;L=S[3]&0x80? S[1]-32:S[1]; if((L<=256-16)&&(L>=0)&&(C||M)) { P=XBuf+WIDTH*(HEIGHT-192)/2+(WIDTH-256)/2+L; T=SprGen+((long)(S[2]&0xFC)<<3); C=XPal[C];Y=S[0]+1; if(YH-16)? H-Y:16; } else { T+=256-Y;Y-=(Y>240)? 240:Y; } for(;Y;Y--,T++,P+=WIDTH-8) for(X=0,J=*T,I=*(T+16);X<8;X++,J<<=1,I<<=1,P++) { if(J&0x80) *P=C; if(I&0x80) *(P+8)=C; } } } else for(S-=4;N;N--,S-=4) { C=S[3]&0x0F;L=S[3]&0x80? S[1]-32:S[1]; if((L<=256-8)&&(L>=0)&&(C||M)) { P=XBuf+WIDTH*(HEIGHT-192)/2+(WIDTH-256)/2+L; T=SprGen+((long)S[2]<<3);C=XPal[C];Y=S[0]+1; if(YH-8)? H-Y:8; } else { T+=256-Y;Y-=(Y>248)? 248:Y; } for(;Y;Y--,T++,P+=WIDTH-8) for(X=0,J=*T;X<8;X++,J<<=1,P++) if(J&0x80) *P=C; } } } void ColorSprites(void) { register byte N,M,I,J,X,Y,C,H; register byte *P,*T,*AT,*PT,*CT; register int L; H=ScanLines212? 212:192; memset(SBuf,0,(word)H<<8); if(SpritesOFF) return; for(N=0,AT=SprTab;(N<32)&&(AT[0]!=216);N++,AT+=4); CT=SprTab-0x0200+((long)N<<4)-16;AT-=4; M=SolidColor0; if(Sprites16x16) for(;N;N--,AT-=4,CT-=16) { P=SBuf;PT=SprGen+((long)(AT[2]&0xFC)<<3);T=CT; Y=AT[0]+1-VDP[23]; if(YH-16)? H-Y:16; } else { Y=256-Y;PT+=Y;T+=Y;Y=(Y<16)? 16-Y:0; } for(;Y;Y--,T++,PT++,P+=256) { L=*T&0x80? AT[1]-32:AT[1];C=*T&0x0F; if((L<=256-16)&&(L>=0)&&(C||M)) { P+=L;J=*PT;I=*(PT+16); if(*T&0x40) for(X=8;X;X--,J<<=1,I<<=1,P++) { if(J&0x80) *P|=C; if(I&0x80) *(P+8)|=C; } else for(C<<=4,X=8;X;X--,J<<=1,I<<=1,P++) { if(J&0x80) *P=(*P&0x0F)|C; if(I&0x80) *(P+8)=(*(P+8)&0x0F)|C; } P-=8+L; } } } else for(;N;N--,AT-=4,CT-=16) { P=SBuf;PT=SprGen+((int)AT[2]<<3);T=CT; Y=AT[0]+1-VDP[23]; if(YH-8)? H-Y:8; } else { Y=256-Y;PT+=Y;T+=Y;Y=(Y<8)? 8-Y:0; } for(;Y;Y--,T++,PT++,P+=256) { L=*T&0x80? AT[1]-32:AT[1];C=*T&0x0F; if((L<=256-8)&&(L>=0)&&(C||M)) { P+=L;J=*PT; if(*T&0x40) for(X=8;X;X--,J<<=1,P++) { if(J&0x80) *P|=C; } else for(C<<=4,X=8;X;X--,J<<=1,P++) { if(J&0x80) *P=(*P&0x0F)|C; } P-=8+L; } } } } void RefreshScrF(register byte Y1,register byte Y2) { if(Verbose>1) printf ( "ScrMODE %d: ChrTab=%X ChrGen=%X ColTab=%X SprTab=%X SprGen=%X\n", ScrMode,ChrTab-VRAM,ChrGen-VRAM,ColTab-VRAM,SprTab-VRAM,SprGen-VRAM ); memset(XBuf+(HEIGHT-192)/2+WIDTH*Y1,XPal[BGColor],(Y2-Y1+1)*WIDTH); } void RefreshScr0(register byte Y1,register byte Y2) { register byte X,Y,J,K,FC,BC; register byte *P,*S,*T; P=XBuf+WIDTH*(HEIGHT-192)/2; if(ScreenON) { BC=XPal[BGColor];FC=XPal[FGColor]; P+=(WIDTH-240)/2;T=ChrTab; for(Y=ScanLines212? 26:24;Y;Y--,P+=WIDTH*8-6*40) for(X=0;X<40;X++,T++) { S=ChrGen+((long)*T<<3); for(J=0;J<8;J++) { K=*S++; *P++=K&0x80? FC:BC;*P++=K&0x40? FC:BC; *P++=K&0x20? FC:BC;*P++=K&0x10? FC:BC; *P++=K&0x08? FC:BC;*P =K&0x04? FC:BC; P+=WIDTH-5; } P+=6-WIDTH*8; } } else memset(P+((word)Y1<<8),XPal[BGColor],(Y2-Y1+1)*WIDTH); if(EndOfFrame) PutImage; } void RefreshScr1(register byte Y1,register byte Y2) { register byte X,Y,K,J,FC,BC; register byte *P,*S,*T; P=XBuf+WIDTH*(HEIGHT-192)/2; if(ScreenON) { P+=(WIDTH-256)/2;T=ChrTab; for(Y=ScanLines212? 26:24;Y;Y--,P+=WIDTH*8-8*32) for(X=0;X<32;X++,T++) { S=ChrGen+((long)*T<<3); BC=*(ColTab+(*T>>3)); FC=XPal[BC>>4];BC=XPal[BC&0x0F]; for(J=0;J<8;J++) { K=*S++; *P++=K&0x80? FC:BC;*P++=K&0x40? FC:BC; *P++=K&0x20? FC:BC;*P++=K&0x10? FC:BC; *P++=K&0x08? FC:BC;*P++=K&0x04? FC:BC; *P++=K&0x02? FC:BC;*P =K&0x01? FC:BC; P+=WIDTH-7; } P+=8-WIDTH*8; } if(!SpritesOFF) Sprites(); } else memset(P+((word)Y1<<8),XPal[BGColor],(Y2-Y1+1)*WIDTH); if(EndOfFrame) PutImage; } void RefreshScr2(register byte Y1,register byte Y2) { register byte X,Y,J,K,M,N,FC,BC; register byte *P,*S,*T,*PGT,*CLT,*C; P=XBuf+WIDTH*(HEIGHT-192)/2; if(ScreenON) { P+=(WIDTH-256)/2; PGT=ChrGen;CLT=ColTab;T=ChrTab; M=ScanLines212? 4:3; for(N=0;N>4];BC=XPal[BC&0x0F]; *P++=K&0x80? FC:BC;*P++=K&0x40? FC:BC; *P++=K&0x20? FC:BC;*P++=K&0x10? FC:BC; *P++=K&0x08? FC:BC;*P++=K&0x04? FC:BC; *P++=K&0x02? FC:BC;*P =K&0x01? FC:BC; P+=WIDTH-7; } P+=8-WIDTH*8; } if(!SpritesOFF) Sprites(); } else memset(P+((word)Y1<<8),XPal[BGColor],(Y2-Y1+1)*WIDTH); if(EndOfFrame) PutImage; } void RefreshScr3(register byte Y1,register byte Y2) { register byte X,Y,J,M,C1,C2; register byte *P,*T,*C; P=XBuf+WIDTH*(HEIGHT-192)/2; if(ScreenON) { P+=(WIDTH-256)/2; T=ChrTab;C=ColTab; M=ScanLines212? 26:24; for(Y=0;Y>4],C2=XPal[*C&15]; for(J=0;J<4;J++,P+=WIDTH-7) { *P++=C1;*P++=C1;*P++=C1;*P++=C1; *P++=C2;*P++=C2;*P++=C2;*P=C2; } C++;C1=XPal[*C>>4],C2=XPal[*C&15]; for(J=0;J<4;J++,P+=WIDTH-7) { *P++=C1;*P++=C1;*P++=C1;*P++=C1; *P++=C2;*P++=C2;*P++=C2;*P=C2; } P+=8-8*WIDTH; } if(!SpritesOFF) Sprites(); } else memset(P+((word)Y1<<8),XPal[BGColor],(Y2-Y1+1)*WIDTH); if(EndOfFrame) PutImage; } void RefreshScr4(register byte Y1,register byte Y2) { register word L; register byte X,I,J,K,N,CF,CB,C; byte *P,*R,*T; P=XBuf+WIDTH*(HEIGHT-192)/2+Y1*WIDTH; if(ScreenON) { ColorSprites(); R=SBuf+((word)Y1<<8); P+=(WIDTH-256)/2; J=VDP[23]+Y1; T=ChrTab+((word)(J&0xF8)<<2); for(;Y1<=Y2;Y1++,J++,P+=WIDTH-256) { if(!J) T=ChrTab; N=J&0x07; for(X=0;X<32;X++,T++) { L=((word)(J&0xC0)<<5)+((word)*T<<3)+N; CB=*(ColTab+L);I=*(ChrGen+L); CF=CB>>4;CB&=0x0F; for(K=0;K<8;K++,I<<=1,R++) { C=((*R>>4)|*R)&0x0F; *P++=XPal[C? C:(I&0x80)? CF:CB]; } } if(N<7) T-=32; } } else memset(P,XPal[BGColor],(Y2-Y1+1)*WIDTH); if(EndOfFrame) PutImage; } void RefreshScr5(register byte Y1,register byte Y2) { register byte X,J,C; register byte *P,*T,*R; P=XBuf+WIDTH*(HEIGHT-192)/2+Y1*WIDTH; if(ScreenON) { ColorSprites(); R=SBuf+((word)Y1<<8); P+=(WIDTH-256)/2; J=VDP[23]+Y1; T=ChrTab+((word)J<<7); for(;Y1<=Y2;Y1++,J++,P+=WIDTH-256) { if(!J) T=ChrTab; for(X=0;X<128;X++,T++) { C=((*R>>4)|*R)&0x0F;R++;*P++=XPal[C? C:*T>>4]; C=((*R>>4)|*R)&0x0F;R++;*P++=XPal[C? C:*T&0x0F]; } } } else memset(P,XPal[BGColor],(Y2-Y1+1)*WIDTH); if(EndOfFrame) PutImage; }