/** fMSX: portable MSX emulator ******************************/ /** **/ /** Unix.c **/ /** **/ /** This file contains Unix/X-dependent subroutines and **/ /** drivers. It includes common drivers from Common.h. **/ /** **/ /** Copyright (C) Marat Fayzullin 1994,1995,1996 **/ /** Elan Feingold 1995 **/ /** Ville Hallik 1996 **/ /** You are not allowed to distribute this software **/ /** commercially. Please, notify me, if you make any **/ /** changes to this file. **/ /*************************************************************/ /** Standard Playstation #includes ********************************/ #include #include "pad.h" #include #include #include #include "MSX.h" #define WIDTH 256 #define HEIGHT 256 int IFreq=50; u_long *XBuf,*SBuf; short XPal[16]; byte Pal[16][3]; long ColBuf[16*256]; int ColCnt=0; // low-level pad buffers: never need to touch volatile u_char *bb0, *bb1; /** PUTIMAGE: macro copying image buffer into a window ********/ void PutImage(void) { RECT rect; int outputBufferIndex; // which side are we working on ? outputBufferIndex = GsGetActiveBuff(); DrawSync(0); // wait for V_BLANK interrupt VSync(0); // swap double buffers GsSwapDispBuff(); if(outputBufferIndex==0){ setRECT(&rect,0,0,256,256); }else{ setRECT(&rect,0,256,256,512); } LoadImage(&rect,XBuf); } /** Screen Mode Handlers [number of screens + 1] *************/ struct { /* Screen mode handlers: */ int (*Init)(); /* Initialize screen */ void (*Colors)(); /* Update colors/palette */ void (*Refresh)(byte Y1,byte Y2);/* Refresh screen */ } SCR[MAXSCREEN+2] = /* Number of screens + 1 */ { { InitScrF,ColorsScrF,RefreshScr0 }, /* SCR 0:TEXT 40x24 */ { InitScrF,ColorsScrF,RefreshScr1 }, /* SCR 1:TEXT 32x24 */ { InitScrF,ColorsScrF,RefreshScr2 }, /* SCR 2:BLK 256x192 */ { InitScrF,ColorsScrF,RefreshScr3 }, /* SCR 3:64x48x16 */ { InitScrF,ColorsScrF,RefreshScr4 }, /* SCR 4:BLK 256x192 */ { InitScrF,ColorsScrF,RefreshScr5 }, /* SCR 5:256x192x16 */ { InitScrF,ColorsScrF,RefreshScr6 }, /* SCR 6:512x192x4 */ { InitScrF,ColorsScrF,RefreshScr7 }, /* SCR 7:512x192x16 */ { InitScrF,ColorsScrF,RefreshScr8 }, /* SCR 8:256x192x256 */ { InitScrF,ColorsScrF,RefreshTx80 } /* SCR 0:TEXT 80x24 */ }; /** TrashMachine *********************************************/ /** Deallocate all resources taken by InitMachine(). **/ /*************************************************************/ void TrashMachine(void) { free(XBuf); free(SBuf); if(Verbose) printf("Shutting down...\n"); } /** InitMachine **********************************************/ /** Allocate resources needed by Playstation dependent code.**/ /*************************************************************/ int InitMachine(void) { if(Verbose) printf("OK\n"); // for our control pad .. GetPadBuf(&bb0, &bb1); // memory allocation for buffers.. SBuf=malloc(2*256*212); XBuf=malloc(2*WIDTH*HEIGHT); SetVideoMode( MODE_PAL ); // PAL mode ResetGraph(0); GsInitGraph(256 ,256, GsOFSGPU|GsNONINTER, 0, 0); GsDefDispBuff(0, 0, 0, 256); // install callback for double buffer swapping //VSyncCallback(ImageCallback); return(1); } /** Keyboard *************************************************/ /** Check for keyboard events, parse them, and modify MSX **/ /** keyboard matrix. **/ /*************************************************************/ void Keyboard(void) { u_long PadStatus=0; register byte keystatus=KeyMap[8]; // pad checking code here ! PadStatus=(~(*(bb0+3) | *(bb0+2) << 8 | *(bb1+3) << 16 | *(bb1+2) << 24)); // exit ? if(PadStatus & PADselect)exit(0); // crude pause button if(PadStatus & PADstart){ // wait for depress do{ PadStatus=(~(*(bb0+3) | *(bb0+2) << 8 | *(bb1+3) << 16 | *(bb1+2) << 24)); }while(PadStatus & PADstart); // loop until pressed again for(;;){ PadStatus=(~(*(bb0+3) | *(bb0+2) << 8 | *(bb1+3) << 16 | *(bb1+2) << 24)); if(PadStatus & PADstart)break; } } // modify keyboard status byte if(PadStatus & PADLup){ // pressed is 0 keystatus&=~0x20; }else{ // depressed is 1 keystatus|=0x20; } if(PadStatus & PADLdown){ // pressed is 0 keystatus&=~0x40; }else{ // depressed is 1 keystatus|=0x40; } if(PadStatus & PADLleft){ // pressed is 0 keystatus&=~0x10; }else{ // depressed is 1 keystatus|=0x10; } if(PadStatus & PADLright){ // pressed is 0 keystatus&=~0x80; }else{ // depressed is 1 keystatus|=0x80; } if(PadStatus & PADRdown){ // pressed is 0 keystatus&=~0x01; }else{ // depressed is 1 keystatus|=0x01; } // send it to MSX keymap matrix KeyMap[8]=keystatus; } /** InitScrF *************************************************/ /** Generic function to be called when screen is changed. **/ /*************************************************************/ int InitScrF(void) { if(Verbose&0x02) printf("Screen %d initialized\n",ScrMode); return(1); } /** ColorScrF ************************************************/ /** Generic function to be called when colors are changed. **/ /*************************************************************/ void ColorsScrF(void) { // Palette is our default color palette, we 'allocate' the colors // a little different than under X :) int N; byte J; byte XPal0; XPal[0]=XPal0; printf("change colors called!\n"); for(J=0;(J<16)&&(ColCnt<16*256);J++){ // Color.red=(word)Palette[J][0]<<8; // Color.green=(word)Palette[J][1]<<8; // Color.blue=(word)Palette[J][2]<<8; XPal[J]=(((short)Palette[J][2]>>3)<<10)+((short)(Palette[J][1]>>3)<<5)+((short)(Palette[J][0]>>3)); // XPal[J]=(Palette[J][2])<<10+(Palette[J][1])<<5+(Palette[J][0]); } } /** Part of the code common for Unix/X and MSDOS drivers *****/ #include "Common.h" /** RefreshScr6 **********************************************/ /** Function to be called to update SCREEN 6. **/ /*************************************************************/ void RefreshScr6(register byte Y1,register byte Y2) { if(EndOfFrame) PutImage(); } /** RefreshScr7 **********************************************/ /** Function to be called to update SCREEN 7. **/ /*************************************************************/ void RefreshScr7(register byte Y1,register byte Y2) { if(EndOfFrame) PutImage(); } /** RefreshScr8 **********************************************/ /** Function to be called to update SCREEN 8. **/ /*************************************************************/ void RefreshScr8(register byte Y1,register byte Y2) { if(EndOfFrame) PutImage(); } /** RefreshTx80 **********************************************/ /** Function to be called to update TEXT80. **/ /*************************************************************/ void RefreshTx80(register byte Y1,register byte Y2) { if(EndOfFrame) PutImage(); }