/** 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,1996 **/ /** John Stiles 1996 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ /*************************************************************/ typedef unsigned long ulong; /****************************************************************/ /*** These dummy functions are called when writes to sound ***/ /*** registers occur. Replace them with the actual functions ***/ /*** generating sound. ***/ /****************************************************************/ void PSGOut(register byte R,register byte V) { } void SCCOut(register byte R,register byte V) { } void PPIOut(register byte Toggle) { } void OPLLOut(register byte R,register byte V) { } /****************************************************************/ /*** The following functions are used to draw sprites. There ***/ /*** is one function for the normal sprites (SCREEN<4) and ***/ /*** one function for the color sprites (SCREEN>3). ***/ /****************************************************************/ void Sprites(void) { register byte N,M,J,Y,C,H; register byte *T,*S; register short *P,K; 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+L/2; //+WIDTH*(HEIGHT-192)/2+(WIDTH-256)/2+L; T=SprGen+((long)(S[2]&0xFC)<<3); K=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) { J=*T; if(J&0x80) P[0]=K;if(J&0x40) P[1]=K; if(J&0x20) P[2]=K;if(J&0x10) P[3]=K; if(J&0x08) P[4]=K;if(J&0x04) P[5]=K; if(J&0x02) P[6]=K;if(J&0x01) P[7]=K; J=*(T+16); if(J&0x80) P[8]=K;if(J&0x40) P[9]=K; if(J&0x20) P[10]=K;if(J&0x10) P[11]=K; if(J&0x08) P[12]=K;if(J&0x04) P[13]=K; if(J&0x02) P[14]=K;if(J&0x01) P[15]=K; } } } else printf("non 16x16 sprite detected !\n"); 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; //+L; //WIDTH*(HEIGHT-192)/2+(WIDTH-256)/2+L; T=SprGen+((long)S[2]<<3);K=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) { J=*T; if(J&0x80) P[0]=K;if(J&0x40) P[1]=K; if(J&0x20) P[2]=K;if(J&0x10) P[3]=K; if(J&0x08) P[4]=K;if(J&0x04) P[5]=K; if(J&0x02) P[6]=K;if(J&0x01) P[7]=K; } } } } void ColorSprites(void) { printf("color sprites not implemented !\n"); } /****************************************************************/ /*** The following are screen refresh functions to be called ***/ /*** to redraw a part or whole screen. Notice the PutImage() ***/ /*** calls needed to copy the offline buffer to a real ***/ /*** display. ***/ /****************************************************************/ void RefreshScrF(register byte Y1,register byte Y2) { 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 ); } void RefreshScr0(register byte Y1,register byte Y2) { register byte X,Y,J,K; register short FC,BC, *P; register byte *S,*T; byte *G; P=XBuf; G=ChrGen; if(ScreenON) { BC=XPal[BGColor];FC=XPal[FGColor]; T=ChrTab; for(Y=ScanLines212? 26:24;Y;Y--,P+=WIDTH*8-6*40) for(X=0;X<40;X++,T++) { S=G+((long)*T<<3); for(J=0;J<8;J++) { K=*S++; P[0]=K&0x80? FC:BC;P[1]=K&0x40? FC:BC; P[2]=K&0x20? FC:BC;P[3]=K&0x10? FC:BC; P[4]=K&0x08? FC:BC;P[5]=K&0x04? FC:BC; P+=WIDTH; } P+=6-WIDTH*8; } } else memset(P+(word)Y1*WIDTH,XPal[BGColor],(Y2-Y1+1)*WIDTH*2); if(EndOfFrame) PutImage(); } void RefreshScr1(register byte Y1,register byte Y2) { static char dummy=0; if(dummy==0){ dummy=1; printf("refreshing screen 1\n"); } if(EndOfFrame) PutImage(); } void RefreshScr2(register byte Y1,register byte Y2) { register byte X,Y,I,K,M,N; register short FC,BC,*P; register byte *S,*T,*PGT,*CLT,*C; P=XBuf; if(ScreenON) { PGT=ChrGen;CLT=ColTab;T=ChrTab; M=ScanLines212? 4:3; for(N=0;N>4];BC=XPal[BC&0x0F]; P[0]=K&0x80? FC:BC;P[1]=K&0x40? FC:BC; P[2]=K&0x20? FC:BC;P[3]=K&0x10? FC:BC; P[4]=K&0x08? FC:BC;P[5]=K&0x04? FC:BC; P[6]=K&0x02? FC:BC;P[7]=K&0x01? FC:BC; P+=WIDTH; } P+=8-WIDTH*8; } if(!SpritesOFF) Sprites(); } else memset(P+(word)Y1*WIDTH,XPal[BGColor],(Y2-Y1+1)*WIDTH); if(EndOfFrame) PutImage(); } void RefreshScr3(register byte Y1,register byte Y2) { static char dummy=0; if(dummy==0){ dummy=1; printf("refreshing screen 3\n"); } if(EndOfFrame) PutImage(); } void RefreshScr4(register byte Y1,register byte Y2) { static char dummy=0; if(dummy==0){ dummy=1; printf("refreshing screen 4\n"); } if(EndOfFrame) PutImage(); } void RefreshScr5(register byte Y1,register byte Y2) { static char dummy=0; if(dummy==0){ dummy=1; printf("refreshing screen 5\n"); } if(EndOfFrame) PutImage(); }