/* * SYSTEM 16 ARCADE EMULATOR SOURCE CODE * * Copyright 1996/97 Thierry Lescot */ #include "cpudefs.h" #include "readcpu.h" #include #include "shinobi.h" #define SPR_PAGE 0xF800 // 0xEC00 #define INT_NUMBER 4 // #define DEBUG_INT // #define TEST_CPU_SPEED // #define EMULATE_Z80 #ifdef MAX_MEM_TEST extern UWORD MaximumR[0x100], MaximumW[0x100]; #endif ULONG historique[20]; int phist=0; long frame=2; long icount=0, temps=0, fcount=0, opcodeb=10000; char sync=0, joy=0, joystick_support=1, nouvelle_methode=0; int sx=0, sy=0; char svga=0; char TEMP[0x8000]; char sfx_enabled = 1; char bgm_enabled = 1; char voice_enabled = 0; char last_bgm = 0; #ifdef EMULATE_Z80 char *soundrom[6] = { "shinobi.a7", "ab11671.bin", "ga12390.bin", "ts10562.bin", "ns", "ns"}; extern char ComunicationPort; extern long Ciclos; extern char Texto[80]; extern unsigned short BaseSb, OPL3, BaseDelay, DelayReg, DelayData; char sound_enabled = 1, sound_active = 0; #else char ComunicationPort; #endif #ifdef SEARCH // int valeur_controle=0x410E80; int valeur_controle=0xFFFFECFC; RGB pal_rgb; PALLETE save_palette; UWORD s_old_values[0x10000]; UBYTE s_check[0x10000]; UWORD s_count, s_zone; #endif char ws[80], DeleteMessage_REQ=0, NO_LFB=0; int time_countdown=0; extern UBYTE shinobi_ds1[10], shinobi_ds2[10]; UBYTE *TimerA, *TimerB; char game_basename[9], game_name[20], game=1; char game_to_load=0; int timer_count=0; unsigned int timer_adrs=0xF01C; long total_render=0; UBYTE txt_bank=0x41, vid_bank=0x40, pal_bank=0x84, ext_bank=0x3F, ctr_bank=0xC4; ULONG total_palette=0, total_new_colors=0, total_palette_reset=0; char int_request=0, refresh_request=0; int int_dec=5000, frame_rate=5, frame_number=0; char background_active=1, mode_video=0; int pcx_number=-1; long render_countdown=1; #ifdef RELEASE_BETA long render_cd_start=200; #else long render_cd_start=20000; #endif int int_speed = 200; int z80cycles = 2000; /* screen variables */ BITMAP *vscreen, *vscreen_sub; int sortie=1, strace=0, pause=0; long i, i2, i3, i4, i5, i6; CPTR BreakPoint=0, p; unsigned char sound_buffer[20], sbuf_read = 0, sbuf_write = 0; long sbuf_ptr = (long)&sound_buffer[0]; void pc_int() { int_request++; } END_OF_FUNCTION(pc_int); void Video(int f) { int rx=320, ry=240; switch (svga) { case 1: rx=640; ry=480; break; case 2: rx=640; ry=400; break; case 3: ry=200; break; case 4: rx=400; ry=300; break; } if (f) { mode_video=1; if (set_gfx_mode(GFX_VESA2L, rx, ry, 0, 0)||NO_LFB) { mode_video=2; if (set_gfx_mode(GFX_VESA2B, rx, ry, 0, 0)) { if (svga) { mode_video=4; if (set_gfx_mode(GFX_AUTODETECT, rx, ry, 0, 0)) { allegro_exit(); printf("Error, i can't switch to %dx%d video mode !\n", rx, ry); exit(1); } } else { mode_video=3; if (set_gfx_mode(GFX_MODEX, rx, ry, 0, 0)) { allegro_exit(); printf("Error, i can't switch to %dx%d video mode !\n", rx, ry); exit(1); } } } } } else { set_gfx_mode(GFX_TEXT, 0, 0, 0, 0); } sx=(rx-312)/2; sy=(ry-224)/2; } #ifdef SEARCH void TraceOn() { if (!strace) { get_palette(save_palette); Video(0); strace=1; } } void TraceOff() { if (strace) { Video(1); set_palette(save_palette); strace=0; } if (pause) RenderScreen(); } #endif static void initCPU(void) { int i,j; for (i = 0 ; i < 256 ; i++) { for (j = 0 ; j < 8 ; j++) { if (i & (1 << j)) break; } movem_index1[i] = j; movem_index2[i] = 7-j; movem_next[i] = i & (~(1 << j)); } for (i = 0; i < 256; i++) { intel_flag_lookup[i].flags.c = !!(i & 1); intel_flag_lookup[i].flags.z = !!(i & 64); intel_flag_lookup[i].flags.n = !!(i & 128); intel_flag_lookup[i].flags.v = 0; } } void inline Exception(int nr, CPTR oldpc) { MakeSR(); #ifdef DEBUG_INT TraceOn(); printf("Exception %0x, valeur = %0x, pc = %0x\n", nr, oldpc, m68k_getpc()); printf("Valeur de r‚gistre SR = 0x%0x\n", regs.sr); #endif if(!regs.s) { regs.a[7]=regs.isp; regs.s=1; } regs.a[7] -= 4; put_long (regs.a[7], m68k_getpc ()); regs.a[7] -= 2; put_word (regs.a[7], regs.sr); m68k_setpc(get_long(regs.vbr + 4*nr)); #ifdef DEBUG_INT printf("VBR=%08x , NR=%d , I=%04x \n", regs.vbr, nr, regs.vbr+4*nr); if (strace) printf("int jump 0x%0x\n", regs.pc); #endif regs.t1 = regs.t0 = regs.m = 0; } void inline Interrupt68k(int level) { int ipl=(regs.sr&0xf00)>>8; #ifndef RELEASE_BETA if (strace) printf("appel Interrupt68k : level=%d , ipl=%d\n", level, ipl); #endif if(level>=ipl) Exception(24+level,0); } void MC68000_reset(void) { if (game==3) { put_word(0x3CA2, 0x4E75); } regs.a[7]=get_long(0); m68k_setpc(get_long(4)); #ifndef RELEASE_BETA printf("start PC at %08x\n", get_long(4)); printf("start A7 at %08x\n", get_long(0)); #endif regs.s = 1; regs.m = 0; regs.stopped = 0; regs.t1 = 0; regs.t0 = 0; ZFLG = CFLG = NFLG = VFLG = 0; regs.intmask = 7; regs.vbr = regs.sfc = regs.dfc = 0; regs.fpcr = regs.fpsr = regs.fpiar = 0; } UBYTE *allocmem(long size, UBYTE init_value) { UBYTE *p; p=(UBYTE *)malloc(size); if (!p) { printf("No enough memory !\n"); } return(p); } unsigned short GetSBInfo (void) { char *blaster = getenv("BLASTER"); unsigned short baseport = 0; if (blaster) { strupr (blaster); while (*blaster) { while (*blaster==' ' || *blaster=='\t') ++blaster; switch (*blaster++) { case 'A': baseport = (unsigned short)strtol(blaster,NULL,16); break; /* case 'I': SB_Info.irq=(byte)strtol(blaster,NULL,10); break; case 'D': SB_Info.dma_low=(byte)strtol(blaster,NULL,10); break; case 'H': SB_Info.dma_high=(byte)strtol(blaster,NULL,10); break; case 'T': SB_Info.type=(byte)strtol(blaster,NULL,10); break; case 'E': SB_Info.emu_baseport=(word)strtol(blaster,NULL,16); break; case 'P': SB_Info.mpu_baseport=(word)strtol(blaster,NULL,16); break; */ } while (*blaster && *blaster!=' ' && *blaster!='\t') ++blaster; } } return(baseport); } #ifdef EMULATE_Z80 void Init_Z80SOUND() { PACKFILE *f; printf("Initializing sound.\n"); if ((game == 6)||(game == 3)) { printf("No sound emulation for this game yet !\n"); sound_enabled = 0; return; } if (!(BaseSb = GetSBInfo())) { printf("BLASTER environment variable not found !\n"); sound_enabled = 0; } else { printf("BLASTER environment variable found, SB base port = %03xh\n", BaseSb); } if (f = pack_fopen(soundrom[game - 1], F_READ)) { printf("Loading sound rom %s...\n", soundrom[game - 1]); pack_fread(TEMP, 0x8000, f); pack_fclose(f); printf("Initializing YM2151/Z80 emulator.\n"); Transfer(); InitYM(); Ciclos = z80cycles; ComunicationPort = 0; } else { printf("Error, can't open sound rom %s !\n", soundrom[game - 1]); sound_enabled = 0; } OPL3 = 1; DelayData = 1; DelayReg = 1; BaseDelay = 0x61; } #endif void Initialisation() { int i; LoadAllROMS(); printf("Allocating memory...\n"); RAM[vid_bank]=allocmem(0x10000, 0); RAM[txt_bank]=allocmem(0x10000, 0); RAM[ext_bank]=allocmem(0x10000, 0); RAM[pal_bank]=allocmem(0x10000, 0); RAM[ctr_bank]=allocmem(0x10000, 0x0); RAM[0x20]=allocmem(0x10000, 0); /* temp */ RAM[0x44]=allocmem(0x10000, 0); RAM[0xFE]=allocmem(0x10000, 0); /* temp */ RAM[0xFF]=allocmem(0x10000, 0); RAM[0x1E]=allocmem(0x10000, 0); /* temp */ if (game==6) { RAM[0x7F]=allocmem(0x10000, 0); } /* Load SRAM */ if ((game==6)||(game==2)) { printf("Loading SRAM...\n"); Load_SRAM(); } /* Debug function */ #ifdef MAX_MEM_TEST memset(&MaximumW[0], 0, sizeof(UWORD)*0x100); memset(&MaximumR[0], 0, sizeof(UWORD)*0x100); #endif /* Init 68000 emulator */ printf("Building 68000 emulator...\n"); BuildCPU(); initCPU(); MC68000_reset(); /* Joystick detection */ if ((joystick_support)&&(!initialise_joystick())) { printf("Joystick found !\n"); joy=1; } else joystick_support=0; #ifdef EMULATE_Z80 if (sound_enabled) Init_Z80SOUND(); sound_active = sound_enabled; #endif /* Load a saved game if -load has been specified */ if (game_to_load) Load_GameFromDisk(game_to_load-1); } static void inline make_sound() { #ifdef EMULATE_Z80 if (sound_active) { if (sbuf_write != sbuf_read) { ComunicationPort = sound_buffer[sbuf_read]; if ((++sbuf_read) == 20) sbuf_read = 0; } Z80(); } #endif } /* new version for Emule() used if -regspeed is specified */ void inline NewEmule() { for (i2=0;i2!=opcodeb;i2++) exec_instruction(); if (!int_request) { /* update display if int_request=0 and frame_number=1 */ if (frame_number) frame_number--; if (!frame_number) { RenderScreen(); frame_number=frame; fcount++; } } else { /* make an interrupt 60 call/sec by default */ Interrupt68k(4); int_request--; make_sound(); } } /* old Emule() function */ void inline Emule() { #ifndef RELEASE_BETA if (strace) MC68000_disasm(m68k_getpc(), &p, 1); if (m68k_getpc()==BreakPoint) { TraceOn(); printf("POINT D'ARRET -> "); MC68000_disasm(m68k_getpc(), &p, 1); } #endif #ifdef RELEASE_BETA for (i=100;i;i--) #endif exec_instruction(); icount+=100; #ifndef RELEASE_BETA phist++; if (phist==20) phist=0; historique[phist]=regs.pc; #endif #ifndef TEST_CPU_SPEED if (render_countdown) render_countdown--; else { /* render screen if not in trace mode */ if (!strace) RenderScreen(); render_countdown=render_cd_start; fcount++; } #endif #ifdef RELEASE_BETA if (int_request) { Interrupt68k(4); int_request=0; make_sound(); } #else int_dec--; if (!int_dec) { Interrupt68k(4); int_dec=5000; } #endif } /* SavePCX */ void SauvegardePCX() { char fn[20]; BITMAP *pcx; PALLETE pal; pcx=create_sub_bitmap(screen, 4, 8, 312, 224); get_palette(pal); do { pcx_number++; strcpy(fn, game_basename); sprintf(&fn[6], "%02x.PCX", pcx_number); } while (file_exists(fn, 0, NULL)); save_pcx(fn, pcx, pal); destroy_bitmap(pcx); sprintf(ws, "%s SAVED", fn); message_emul(0, 2, ws); } /* keyboard handler */ void inline Clavier() { int code, cont=1; if (keypressed()) do { if (keypressed()) { code=(readkey()>>8); switch (code) { case KEY_F1: Interface(); int_request=0; cont=pause; break; case KEY_F11: background_active=~(background_active&0x01); RenderScreen(); cont=pause; break; #ifdef EMULATE_Z80 case KEY_TAB: if (sound_enabled) { sound_active = (1 - sound_active); sprintf(ws, "SOUND IS %s", (sound_active)? "ENABLED":"DISABLED"); message_emul(0, 2, ws); } cont = pause; break; #endif case KEY_S: /* CTRL + PRINT SCREEN */ SauvegardePCX(); cont=pause; int_request=0; break; case KEY_ESC: sortie=cont=0; break; #ifndef SEARCH /* cheat keys */ case KEY_F2: RAM[0xFF][0xD79E]=0x01; message_emul(0, 2, "CHEAT: POWER UP !"); cont=pause; break; case KEY_F3: RAM[0xFF][0xD76A]=RAM[0xFF][0xD76B]; message_emul(0,2, "CHEAT: ALL HOSTAGES RESCUED !"); cont=pause; break; case KEY_F4: RAM[0xFF][0xF08E]=0; message_emul(0,2, "CHEAT: GET BONUS !"); cont=pause; break; case KEY_F5: if (game==1) RAM[0xFF][0xD778]=255; if (game==6) RAM[0xFF][0xC41F]=255; message_emul(0,2, "CHEAT: 255 MAGICS !"); cont=pause; break; case KEY_F6: case KEY_F7: case KEY_F8: RAM[0xFF][0xD779]=(code-KEY_F6); message_emul(0,2, "CHEAT: MAGIC CHANGED !"); cont=pause; break; case KEY_F9: RAM[0xFF][0xD79A]++; message_emul(0,2, "CHEAT: ONE MINUTE ADDED !"); cont=pause; break; case KEY_F10: RAM[0xFF][0xD750]++; message_emul(0,2, "CHEAT: ONE LIVE ADDED !"); cont=pause; break; /* case KEY_S: sfx_enabled = (1 - sfx_enabled); sprintf(ws, "FM SFX %s", (sfx_enabled)? "ENABLED":"DISABLED"); message_emul(0, 2, ws); cont = pause; break; case KEY_V: voice_enabled = (1 - voice_enabled); sprintf(ws, "VOICES %s", (voice_enabled)? "ENABLED":"DISABLED"); message_emul(0, 2, ws); cont = pause; break; case KEY_B: bgm_enabled = (1 - bgm_enabled); sprintf(ws, "FM BGM %s", (bgm_enabled)? "ENABLED":"DISABLED"); message_emul(0, 2, ws); ComunicationPort = (bgm_enabled)? last_bgm:0; cont = pause; break; */ /* change the screen position with keypad + and - */ case KEY_PADADD: sy+=2; cont=pause; clear(screen); if (pause) RenderScreen(); break; case KEY_PADSUB: sy-=2; cont=pause; clear(screen); if (pause) RenderScreen(); break; #else case KEY_MENU: i=strace; TraceOn(); remove_keyboard(); printf("entrez le nouvelle valeur :"); scanf("%s", &ws); install_keyboard(); put_word(0xFFD780,hex2int(ws)); if (!i) TraceOff(); cont=pause; break; case KEY_H: TraceOn(); printf("historique PC\n"); i2=phist; do { printf("PC=%08x\n", historique[i2]); i2++; if (i2==20) i2=0; } while (i2!=phist); break; case KEY_T: TraceOn(); break; case KEY_G: TraceOff(); cont=0; clear_keybuf(); break; case KEY_R: m68k_dumpstate(); break; /* display FIXED RAM video $41000-$41FFF */ case KEY_F4: dump_text_video(); cont=pause; break; /* display SCROLL RAM video $40000-$43FFF */ case KEY_F5: dump_video(0x0000); cont=pause; break; /* display SCROLL RAM video $44000-$47FFF */ case KEY_F6: dump_video(0x4000); cont=pause; break; /* display SCROLL RAM video $48000-$4BFFF */ case KEY_F7: dump_video(0x8000); cont=pause; break; /* display SCROLL RAM video $4C000-$4FFFF */ case KEY_F8: dump_video(0xC000); cont=pause; break; /* dump memory */ case KEY_D: TraceOn(); remove_keyboard(); printf("Adresse de d‚part : "); scanf("%s", &ws[0]); i2=hex2int(ws); printf("Adresse de fin : "); scanf("%s", &ws[0]); i3=hex2int(ws); install_keyboard(); i5=0; do { printf("%08x:", i2); for (i4=0;i4!=16;i4++) printf(" %02x", get_byte(i2++)); printf("\n"); if ((++i5)==20) { i5=0; printf("\nAppuyez sur une touche pour continuer\n"); clear_keybuf(); i6=(readkey()>>8); while (key[i6]); clear_keybuf(); } } while (i2s_old_values[i]) s_count++; else s_check[i]=0x00; s_old_values[i]=RAM[0xFF][i]; } } printf("Nombre de valeurs ayant augment‚ : %d\n", s_count); break; case KEY_ENTER: TraceOn(); s_count=0; remove_keyboard(); printf("valeur … recherche : "); scanf("%d", &i2); install_keyboard(); for (i=0;i!=0x10000;i++) { if (s_check[i]) { if (RAM[0xFF][i]==i2) s_count++; else s_check[i]=0x00; s_old_values[i]=RAM[0xFF][i]; } } printf("Nombre de valeurs correspondantes : %d\n", s_count); break; case KEY_PADDIV: TraceOn(); printf("Liste des zones retenues.\n"); for (i=0;i!=0x10000;i++) if (s_check[i]) printf("0x%04x (0x%02x)\n", i, RAM[0xFF][i]); printf("\n"); break; #endif case KEY_P: pause=~pause; cont=pause; int_request=0; if (pause) message_emul(0, 2, "Game paused !"); break; default: cont=0; } } } while (cont); } void pc_int2() { if (time_countdown) { time_countdown--; if (!time_countdown) { DeleteMessage_REQ=1; } } temps++; } END_OF_FUNCTION(pc_int2); void Init_Game() { char *longname[] = { "Shinobi", "Altered Beast", "Golden Axe", "Time Scanner", "Quartet (not working)", "Shadow Dancer" }; char *shortname[] = { "SHINOBI", "ALTBEAST", "GOLDNAXE", "TIMSCANR", "QUARTET", "SHDANCER" }; /* change memory mapping for some games */ switch (game) { case 3: /* Golden Axe */ txt_bank=0x11; vid_bank=0x10; pal_bank=0x14; ext_bank=0x1F; break; case 6: /* Shadow Dancer */ ctr_bank=0xE4; ext_bank=0xC0; break; } strcpy(game_basename, shortname[game-1]); strcpy(game_name, longname[game-1]); printf("\nSelected game : %s\n", game_name); } int CheckArguments(int argc, char **argv) { int i; for (i=1;i!=argc;i++) { if (argv[i][0]=='-') { if (!strcmp(argv[i], "-frame")) { frame=atoi(argv[++i]); if ((frame<1)||(frame>50)) { printf("Bad frame value, only 1 to 10 are allowed!"); return(1); } else { printf("Frame skip value = %d \n", frame); #ifdef RELEASE_BETA render_cd_start=50*frame; #else render_cd_start=5000*frame; #endif } } else if (!strcmp(argv[i], "-int")) { int_speed=atoi(argv[++i]); if ((int_speed<1)||(int_speed>200)) { printf("Bad int value, only 1 to 200 are allowed!"); return(1); } else { printf("Interrupt speed = %d call/second \n", int_speed); } } else if (!strcmp(argv[i], "-game")) { game=atoi(argv[++i]); if ((game<1)||(game>LAST_GAME)) { printf("Bad game number, only 1 to %d are allowed!", LAST_GAME); return(1); } } else if (!strcmp(argv[i], "-load")) { game_to_load=atoi(argv[++i]); if ((game<1)||(game>10)) { printf("Bad save game number, only 1 to 10 are allowed!"); return(1); } } else if (!strcmp(argv[i], "-nolfb")) { NO_LFB=1; } else if (!strcmp(argv[i], "-svga")) { svga=1; } else if (!strcmp(argv[i], "-svga400")) { svga=2; } else if (!strcmp(argv[i], "-vga")) { svga=3; } else if (!strcmp(argv[i], "-special")) { svga=4; } else if (!strcmp(argv[i], "-vsync")) { sync=1; } else if (!strcmp(argv[i], "-nojoy")) { joystick_support=0; } #ifdef EMULATE_Z80 else if (!strcmp(argv[i], "-nosound")) { sound_enabled = 0; } #endif else if (!strcmp(argv[i], "-regspeed")) { nouvelle_methode=1; int_speed=60; if (i!=(argc-1)) { if (argv[i+1][0]!='-') { opcodeb=atoi(argv[i+1]); if (opcodeb<1) { printf("Error, minimum value for -regspeed is 100 !\n"); return(1); } } } } else if (!strcmp(argv[i], "-z80")) { if (i!=(argc-1)) { if (argv[i+1][0]!='-') { z80cycles=atoi(argv[i+1]); if ((z80cycles < 100) || (z80cycles > 2500)) { printf("Error, values range for -z80 is 100-2500 !\n"); return(1); } } } } else { printf("Bad option name : %s !\n", argv[i]); return(1); } } } return(0); } void main(int argc, char **argv) { printf("The System 16 Arcade Emulator v0.53 (Public BETA)\n"); printf("Copyright Thierry Lescot, 1996/1997.\n\n"); #ifdef EMULATE_Z80 printf("%s\n", Texto); #endif if (windows_version) { printf("Windows %d.%d detected ! %s run slower under Windows !\n", windows_version, windows_sub_version, game_name); } if (CheckArguments(argc, argv)) { exit(0); } allegro_init(); install_timer(); install_keyboard(); Init_Game(); #ifdef SON_SIMULE if (install_sound(DIGI_AUTODETECT, MIDI_NONE, argv[0])!=0) { printf("Pas de son (%s) !\n", allegro_error); while (!keypressed()); clear_keybuf(); } else Load_Samples(); #endif; Initialisation(); printf("\nPress any key to continue ...\n"); #ifdef RELEASE_BETA #ifndef TEST_CPU_SPEED while (!keypressed()); clear_keybuf(); printf("\n"); strace=0; for (i = 0; i!=25; i++) printf("\n"); printf("Please, read this !!!\n\n"); printf("READ SYSTEM16.DOC **BEFORE** E-MAILING ME !!!\n\n"); printf("AND DON'T ASK ME FOR ROMS !!!\n\n\nPress a key to continue.\n"); while (keypressed()); clear_keybuf(); while (!keypressed()); clear_keybuf(); #endif #else strace=1; #endif // put_word(0x1DE5C,0x4E71); #ifdef RELEASE_BETA Video(1); #endif vscreen=create_bitmap(512, 400); vscreen_sub=create_sub_bitmap(vscreen, 88, 88, 336, 224); Load_Config(); clear(vscreen_sub); Setup_Asm(); Create_Palette(); LOCK_VARIABLE(int_request); LOCK_VARIABLE(time_countdown); LOCK_VARIABLE(DeleteMessage_REQ); LOCK_VARIABLE(temps); LOCK_FUNCTION(pc_int); LOCK_FUNCTION(pc_int2); install_int_ex(pc_int, 1193181/int_speed); install_int_ex(pc_int2, 1193181); message_emul(0, 5, " Welcome to The System 16 Emulator v0.53"); // message_emul(0, 5, " PRIVATE PRE-RELEASE BETA 0.5"); #ifdef TEST_CPU_SPEED do { Emule(); } while (temps<=30); #else do { if (nouvelle_methode) NewEmule(); else Emule(); if (strace) { clear_keybuf(); while (!keypressed()); } if (DeleteMessage_REQ) DeleteMessage(); Clavier(); } while (!key[KEY_ESC]); #endif #ifdef EMULATE_Z80 ResetYM(); #endif allegro_exit(); if ((game==2)||(game==6)) { printf("Saving SRAM...\n"); Save_SRAM(); } printf("\nVideo mode used = %d (1=LINEAR,2=BANKED,3=XMODE,4=VGA/SVGA)\n", mode_video); if (mode_video==3) { printf("\nFor beter results you can install the SciTech UniVBE 5.3 drivers.\n"); } /* printf("\nValeur de PC=%08x\n", regs.pc); printf("\nAcc‚s … la palette = %d\nTotal new colors = %d\n", total_palette, total_new_colors); printf("\nNombre de Palette Init = %d\n", total_palette_reset); printf("Total render = %d \n", total_render); */ #ifdef MAX_MEM_TEST printf("\nMax mem results :\n"); for (i=0;i!=256;i++) if (MaximumW[i]||MaximumR[i]) printf("bank[%02x] R=%04x W=%04x\n", i, MaximumR[i], MaximumW[i]); #endif #ifdef TEST_CPU_SPEED printf("nombre d'instruction … la seconde = %d\n", icount/30); printf("speed = %d procents\n", (icount/300)/2597); #endif if (temps) printf("Average frame rate = %d FPS\n", fcount/temps); }