#include #include #include #include "vga_emulator.h" /* technically bigger than 320x200 but some code writes off edge... */ /* in theory 16-bit pointer can't write beyond this */ unsigned char framebuffer[65536]; static SDL_Surface *sdl_screen=NULL; static struct palette pal; static int debug=0; static int xsize=320,ysize=200,scale=1; int mode13h_graphics_init(char *name, int new_scale) { int mode; scale=new_scale; xsize=320*scale; ysize=200*scale; mode=SDL_SWSURFACE|SDL_HWPALETTE|SDL_HWSURFACE; if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); return -1; } /* Clean up on exit */ atexit(SDL_Quit); /* assume 32-bit color */ sdl_screen = SDL_SetVideoMode(xsize, ysize, 32, mode); if ( sdl_screen == NULL ) { fprintf(stderr, "ERROR! Couldn't set %dx%d video mode: %s\n", xsize,ysize,SDL_GetError()); return -1; } SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL); if (name==NULL) { SDL_WM_SetCaption("Linux/C/SDL","unknown"); } else { SDL_WM_SetCaption(name,name); } return 0; } int mode13h_graphics_update(void) { unsigned int *t_pointer; int x,y,temp,in_ptr,out_ptr,i,j; /* point to SDL output pixels */ t_pointer=((Uint32 *)sdl_screen->pixels); out_ptr=0; for(y=0;y<200;y++) { for(j=0;j320*200)) return; framebuffer[real_addr]=value; } void framebuffer_write(int address, int value) { if (debug) { if ((address<0) || (address>320*200)) { fprintf(stderr, "Error! Framebuffer write of 0x%x (%d,%d) " "out of bounds\n", address,address%320,address/320); return; } } framebuffer[address]=value; } static int dac_write_address=0,dac_write_which=0; static int dac_read_address=0,dac_read_which=0; void outp(short address, int value) { switch(address) { /* DAC read address */ case 0x3c7: if (debug) fprintf(stderr,"Setting read address to %d\n",value); dac_read_address=value; dac_read_which=0; break; /* DAC write address */ case 0x3c8: if (debug) fprintf(stderr,"Setting write address to %d\n",value); dac_write_address=value; dac_write_which=0; break; /* PEL/DAC data */ /* Note colors are 0..63 */ case 0x3c9: if (dac_write_which==0) { pal.red[dac_write_address]=value*4; if (debug) fprintf(stderr,"Color %d R=0x%x ", dac_write_address,value); } if (dac_write_which==1) { pal.green[dac_write_address]=value*4; if (debug) fprintf(stderr,"G=0x%x ",value); } if (dac_write_which==2) { pal.blue[dac_write_address]=value*4; if (debug) fprintf(stderr,"B=0x%x\n",value); } dac_write_which++; if (dac_write_which==3) { dac_write_address++; dac_write_which=0; if (dac_write_address>255) { if (debug) fprintf(stderr,"Palette overflow!\n"); dac_write_address=0; /* FIXME: is this right? */ } } break; default: printf("outp to unknown port 0x%x\n",address); } } int inp(short address) { int retval=0; switch(address) { /* DAC read address */ case 0x3c9: if (dac_read_which==0) { retval=pal.red[dac_read_address]/4; if (debug) fprintf(stderr,"Color %d R=0x%x ", dac_read_address,retval); } if (dac_read_which==1) { retval=pal.green[dac_read_address]/4; if (debug) fprintf(stderr,"G=0x%x ",retval); } if (dac_read_which==2) { retval=pal.blue[dac_read_address]/4; if (debug) fprintf(stderr,"B=0x%x\n",retval); } dac_read_which++; if (dac_read_which==3) { dac_read_address++; dac_read_which=0; if (dac_read_address>255) { if (debug) fprintf(stderr,"Palette overflow!\n"); dac_read_address=0; /* FIXME: is this right? */ } } break; default: printf("inp from unknown port 0x%x\n",address); } return retval; }