#include #include "emuapi.h" #include "kbd.h" #include "dcastaway.h" #include "st.h" #include "mem.h" #include "m68k_intrf.h" #include "iopins.h" #ifndef NO_SOUND #include "sound.h" #endif #include "tossw12.h" #ifdef HAS_PSRAM #include "psram_t.h" PSRAM_T psram = PSRAM_T(PSRAM_CS, PSRAM_MOSI, PSRAM_SCLK, PSRAM_MISO); #endif //#define PSRAM_DISK 1 #ifdef ALL_IN_RAM uint8 *mem1base; #else #ifdef PSRAM_FAKE uint8 *mem1base; #endif #endif uint8 *mem2base; uint8 *rombase; int hbl = 0; int end_visible_screen = 264; int hsync = 0; int vsyncpend = 0, hsyncpend = 0; int exmousex=160,exmousey=100,MouseRelease1=0,MouseRelease2=0; int CompleteSndBufIdx; int waitstate=0; int dcastaway_disc_writed[2] = { 0 , 0 }; int dcastaway_disc_for_write[2] = { 0 , 0 }; int draw_border=0, maybe_border=0; unsigned cyclenext=512; unsigned vid_adr_cycleyet=0; static unsigned char vid_cycles_pal[1024]; static unsigned char vid_cycles_ntsc[1024]; unsigned char *vid_cycle=(unsigned char *)&vid_cycles_pal; int readdsk=1; extern unsigned char fdc_motor; #define XRES 320 #define YRES 200 static unsigned short line[XRES]; #define PALMULT8(x) ((x)<<5) #define RGBVAL16(r,g,b) ( (((r>>3)&0x1f)<<11) | (((g>>2)&0x3f)<<5) | (((b>>3)&0x1f)<<0) ) void Redraw16 ( int row, int vid_adr ) { static unsigned short palmap [ 16 ]; //Source address register unsigned long line_i=vid_adr; register unsigned short *line_o= &line[0]; //Build paletter if (vid_flag) { unsigned char i, r, g, b; for (i = 0; i < 16; i++) { b = PALMULT8 ( (vid_col[i] & 0x7) ); g = PALMULT8 ( ((vid_col[i] >> 4) & 0x7) ); r = PALMULT8 ( ((vid_col[i] >> 8) & 0x7) ); palmap [ i ] = RGBVAL16(r,g,b); } vid_flag=0; } register int col; register int bit; for (col=0; col<20; col++) { register unsigned short pl0=ReadW(line_i),pl1=ReadW(line_i+2),pl2=ReadW(line_i+4),pl3=ReadW(line_i+6); line_i += 8; for (bit=15;bit>=0;bit--) { int ind = (pl0 >> bit) & 0x1; ind += ((pl1 >> bit) & 0x1)<<1; ind += ((pl2 >> bit) & 0x1)<<2; ind += ((pl3 >> bit) & 0x1)<<3; *line_o++ = palmap [ ind ]; } } emu_DrawLine16(&line[0], XRES, YRES, row); } void Redraw16_med ( int row, int vid_adr ) { static unsigned short palmap [ 4 ]; //Source address register unsigned long line_i=vid_adr; register unsigned short *line_o= &line[0]; //Build paletter if (vid_flag) { unsigned char i, r, g, b; for (i = 0; i < 4; i++) { b = PALMULT8 ( (vid_col[i] & 0x7) ); g = PALMULT8 ( ((vid_col[i] >> 4) & 0x7) ); r = PALMULT8 ( ((vid_col[i] >> 8) & 0x7) ); palmap [ i ] = RGBVAL16(r,g,b); } vid_flag=0; } register int col; register int bit; for (col=0; col<40; col++) { register unsigned short pl0=ReadW(line_i),pl1=ReadW(line_i+2); line_i += 4; for (bit=15;bit>=0;bit--) { int ind = (pl0 >> bit) & 0x1; ind += ((pl1 >> bit) & 0x1)<<1; if (bit & 0x01) *line_o++ = palmap [ ind ]; } } emu_DrawLine16(&line[0], XRES, YRES, row); } static uint8 disk0[256]; static uint8 disk1[256]; void ast_Init(void) { #ifdef HAS_PSRAM psram.begin(); #endif emu_printf("Allocating RAM"); #ifdef ALL_IN_RAM mem1base = (uint8*) malloc(MEMSIZE); if (!mem1base) emu_printf("malloc mem1 failed\n"); mem2base = &mem1base[RAM1SIZE]; #else if ((MEMSIZE-RAM1SIZE)>0) { mem2base = (uint8*) malloc(MEMSIZE-RAM1SIZE); if (!mem2base) emu_printf("malloc mem2 failed\n"); } #ifdef PSRAM_FAKE if ((RAM1SIZE)>0) { mem1base = (uint8*) malloc(RAM1SIZE); if (!mem1base) emu_printf("malloc mem1 failed\n"); } else { mem1base = mem2base; } #endif #endif rombase = (uint8*)&tos[0]-ROMBASE; #ifdef ALL_IN_RAM memcpy (mem1base, &tos[0], 8); #else //for (int i=0; i= KBD_KEY_F1) && (key <= KBD_KEY_F10) ) keyCode = (key - KBD_KEY_F1) + 0x3b; // Specific keys //153,151,150,152,0x7F 31 //U L R D DEL ESC //else if (key == KBD_KEY_UP) keyCode = 0x99; // 153 //else if (key == KBD_KEY_LEFT) keyCode = 0x97; // 151 //else if (key == KBD_KEY_DOWN) keyCode = 0x98; // 152 //else if (key == KBD_KEY_RIGHT) keyCode = 0x96; // 150 //else if (key == KBD_KEY_BS) keyCode = 0x7F; // 127 //else if (key == KBD_KEY_ESC) keyCode = 0x1F; // 31 else keyCode = keyboardAsciiConv[key & 0x7f]; IkbdKeyPress ( keyCode ); } void emu_KeyboardOnUp(int keymodifer, int key) { int keyCode = INV_KEY; if ( (key >= KBD_KEY_F1) && (key <= KBD_KEY_F10) ) keyCode = (key - KBD_KEY_F1) + 0x3b; // Specific keys //153,151,150,152,0x7F 31 //U L R D DEL ESC //else if (key == KBD_KEY_UP) keyCode = 0x99; // 153 //else if (key == KBD_KEY_LEFT) keyCode = 0x97; // 151 //else if (key == KBD_KEY_DOWN) keyCode = 0x98; // 152 //else if (key == KBD_KEY_RIGHT) keyCode = 0x96; // 150 //else if (key == KBD_KEY_BS) keyCode = 0x7F; // 127 //else if (key == KBD_KEY_ESC) keyCode = 0x1F; // 31 else keyCode = keyboardAsciiConv[key & 0x7f]; IkbdKeyRelease ( keyCode ); } extern void ast_Input(int click) { hk = emu_ReadI2CKeyboard(); k = emu_ReadKeys(); } static void do_events(void) { int bClick = k & ~prev_k; prev_k = k; // Toggle mouse/joystick if (bClick & MASK_KEY_USER1) { if (isMouse) isMouse = false; else isMouse = true; } if (!isMouse) { int j = 0; if (( k & MASK_JOY1_RIGHT) || ( k & MASK_JOY2_RIGHT)) { j |= 0x04; } if (( k & MASK_JOY1_LEFT) || ( k & MASK_JOY2_LEFT)) { j |= 0x08; } if (( k & MASK_JOY1_UP) || ( k & MASK_JOY2_UP)) { j |= 0x01; } if (( k & MASK_JOY1_DOWN) || ( k & MASK_JOY2_DOWN)) { j |= 0x02; } if ( k & MASK_JOY2_BTN) { j |= 0x80; } if (j != prev_j) { IkbdJoystickChange(joynum,j); prev_j = j; } } else { if (( k & MASK_JOY1_LEFT) || ( k & MASK_JOY2_LEFT)) { if ( mouse_x < XRES ) { mouse_x += 2; //Serial.print("r"); IkbdMouseMotion ( mouse_x, mouse_y ); IkbdLoop(); } } else if (( k & MASK_JOY1_RIGHT) || ( k & MASK_JOY2_RIGHT)) { if ( mouse_x > 1 ) { mouse_x -= 2; //Serial.print("l"); IkbdMouseMotion ( mouse_x, mouse_y ); IkbdLoop(); } } else if (( k & MASK_JOY1_UP) || ( k & MASK_JOY2_UP)) { if ( mouse_y > 1 ) { mouse_y -= 2; //Serial.print("u"); IkbdMouseMotion ( mouse_x, mouse_y ); IkbdLoop(); } } else if (( k & MASK_JOY1_DOWN) || ( k & MASK_JOY2_DOWN)) { if ( mouse_y < YRES ) { mouse_y += 2; //Serial.print("d"); IkbdMouseMotion ( mouse_x, mouse_y ); IkbdLoop(); } } int mouseb=0; if ( ( k & MASK_JOY2_BTN) ){ mouseb=1; } if ( (mouseb != prev_mouseb) ){ if (mouseb) IkbdMousePress(2); else IkbdMouseRelease(2); //Serial.println("btoggle"); IkbdLoop(); prev_mouseb = mouseb; } } } void ast_Step(void) { int delay_fdc_motor=0; unsigned long cycleco=0; unsigned long oldpend,newpend; hsync=0; hbl=0; vsyncpend=0; hsyncpend=0; int running = 1; /* Event loop */ while (running) { cycleco=cpu_loop(cyclenext); cycleco+=waitstate; waitstate=0; #ifndef NO_SOUND SoundCycles+=cycleco; #endif //MFP timer A delay mode if (mfp_ascale>1) { mfp_acount-=mfp_ascale*cycleco; if (mfp_acount<=0) { do {mfp_acount+=mfp_tadr;} while (mfp_acount<=0); oldpend=mfp_ipra; newpend=(oldpend|0x20)&mfp_iera; if (newpend!=oldpend) {mfp_ipra=newpend; } } #ifdef USE_SHORT_SLICE cyclenext=4+(mfp_acount/mfp_ascale); #endif } #ifdef USE_SHORT_SLICE else cyclenext=512; #endif //MFP timer B delay mode if (mfp_bscale>1) { mfp_bcount-=mfp_bscale*cycleco; if (mfp_bcount<=0) { do {mfp_bcount+=mfp_tbdr;} while (mfp_bcount<=0); oldpend=mfp_ipra; newpend=(oldpend|0x1)&mfp_iera; if (newpend!=oldpend) {mfp_ipra=newpend; } } #ifdef USE_SHORT_SLICE { int n=4+(mfp_bcount/mfp_bscale); if (n1) { mfp_ccount-=mfp_cscale*cycleco; if (mfp_ccount<=0) { do {mfp_ccount+=mfp_tcdr;} while (mfp_ccount<=0); oldpend=mfp_iprb; newpend=(oldpend|0x20)&mfp_ierb; if (newpend!=oldpend) {mfp_iprb=newpend; } } #ifdef USE_SHORT_SLICE { int n=4+(mfp_ccount/mfp_cscale); if (n1) { mfp_dcount-=mfp_dscale*cycleco; if (mfp_dcount<=0) { do {mfp_dcount+=mfp_tddr;} while (mfp_dcount<=0); oldpend=mfp_iprb; newpend=(oldpend|0x10)&mfp_ierb; if (newpend!=oldpend) {mfp_iprb=newpend; } } #ifdef USE_SHORT_SLICE { int n=4+(mfp_dcount/mfp_dscale); if (n=313) { //delay(15); //emu_DrawVsync(); do_events(); #ifndef NO_SOUND Sound_Update_VBL(); #endif running=0; hbl=0; //Generate vsync interrupt Interrupt(AUTOINT4, 4); //Do fdc spinup if (fdc_motor){ if (delay_fdc_motor>150) { fdc_status &= ~0x80; delay_fdc_motor=0; fdc_motor=0; } else delay_fdc_motor++; } } } //Recalculate interrupts? { int mfp_int; mfp_int=0; if (6>GetI()) { //Mfp interrupt { int n, number; uint16 imr, ipr, isr, irr; int in_request; //Find in_request and in_service imr = (mfp_imra<<8)+mfp_imrb; ipr = (mfp_ipra<<8)+mfp_iprb; irr = imr & ipr; isr = (mfp_isra<<8) + mfp_isrb; //in_request higher than in_service? if (irr>isr) { //Find highest set bit for (in_request = 15; in_request > 0; in_request--) { if (irr & 0x8000) break; irr <<= 1; } isr = 1 << in_request; //Set interrupt in service bits in MFP if (mfp_ivr & 0x8) { mfp_isra |= isr >> 8; mfp_isrb |= isr; }else{ mfp_isra &= (~isr) >> 8; mfp_isrb &= ~isr; } //Clear interrupt pending bits in MFP mfp_ipra &= ~(isr >> 8); mfp_iprb &= ~isr; //Pass interrupt to cpu number = in_request | (mfp_ivr & 0xf0); Interrupt(number, 6); mfp_int=1; } } } } } } #ifdef HAS_PSRAM unsigned char ram_readb(int address) { #ifdef PSRAM_FAKE return mem1base[address]; #else return (psram.psread(address)); #endif } void ram_writeb(int address, unsigned char val) { #ifdef PSRAM_FAKE mem1base[address] = val; #else psram.pswrite(address,val); #endif } unsigned short ram_readw(int address) { #ifdef PSRAM_FAKE return mem1base[address]|(mem1base[address+1]<<8); #else // return psram.psread(address)|(psram.psread(address+1)<<8); return psram.psread_w(address); #endif } void ram_writew(int address, unsigned short val) { #ifdef PSRAM_FAKE mem1base[address] = val; mem1base[address+1] = val>>8; #else psram.pswrite_w(address,val); #endif } #define PSRAM_DISK_OFFSET (2*1024*1024) // disk IO mapped to PSRAM static uint8 read_disk(int address) { return (psram.psread(address+PSRAM_DISK_OFFSET)); } static void write_disk(int address, uint8 val) { psram.pswrite(address+PSRAM_DISK_OFFSET,val); } #endif #ifdef PSRAM_DISK #ifdef HAS_PSRAM static int disksize = 0; static int diskpt = 0; int disk_Size(char * filename) { //emu_printf("disk size"); //emu_printi(disksize); return disksize; } int disk_Open(char * filename) { //emu_printf("disk reset pt"); diskpt = 0; return 1; } int disk_Read(unsigned char * buf, int size) { //emu_printf("disk read"); //emu_printi(size); int i = 0; while ( ( i < size) && (diskpt < disksize) ) { buf[i++] = read_disk(diskpt++); } return i; } int disk_Seek(int seek) { //emu_printf("disk seek"); //emu_printi(seek); diskpt = seek; return diskpt; } #endif #else // disk IO mapped to File static int fd; int disk_Size(char * filename) { return emu_FileSize(filename); } int disk_Open(char * filename) { fd = emu_FileOpen(filename,"r+b"); return fd; } int disk_Read(unsigned char * buf, int size) { return emu_FileRead(buf, size, fd); } int disk_Seek(int seek) { return emu_FileSeek(fd,seek,0); } #endif void ast_Start(char * filename) { emu_printf("init started"); strncpy (disk[0].name, filename, sizeof(disk[0].name)); #ifdef PSRAM_DISK #ifdef HAS_PSRAM char iobuf[512]; int iopos = 0; disksize = 0; int n; int f; if (f = emu_FileOpen(filename, "r+b")) { while ( (n = emu_FileRead(&iobuf[0],sizeof(iobuf), f) ) ) { disksize += n; for (int i=0; i