diff options
author | Ian C <ianc@noddybox.co.uk> | 2007-01-30 23:46:49 +0000 |
---|---|---|
committer | Ian C <ianc@noddybox.co.uk> | 2007-01-30 23:46:49 +0000 |
commit | 6fca8cfe0bcbe30767c30ac9b6d9a79e4fa19edc (patch) | |
tree | 303f46557317a8e43524ba7999715f547ab9783e /source | |
parent | ef641589bf763ea12e73abf4bf42e45ac1acd2ff (diff) |
Added pseudo-hires support
Diffstat (limited to 'source')
-rw-r--r-- | source/framebuffer.c | 4 | ||||
-rw-r--r-- | source/keyboard.c | 2 | ||||
-rw-r--r-- | source/main.c | 29 | ||||
-rw-r--r-- | source/tapes.c | 4 | ||||
-rw-r--r-- | source/zx81.c | 218 |
5 files changed, 231 insertions, 26 deletions
diff --git a/source/framebuffer.c b/source/framebuffer.c index 4a4b03d..ef66235 100644 --- a/source/framebuffer.c +++ b/source/framebuffer.c @@ -259,7 +259,7 @@ void FB_Blit(sImage *img, int x, int y) { if (img->width==WIDTH && img->height==HEIGHT) { - dmaCopy(img->data8,buff,SCREEN_WIDTH*SCREEN_HEIGHT*2); + dmaCopy(img->image.data8,buff,SCREEN_WIDTH*SCREEN_HEIGHT*2); } else { @@ -267,7 +267,7 @@ void FB_Blit(sImage *img, int x, int y) for(f=0;f<img->height;f++) { - dmaCopy(img->data16+(f*img->width), + dmaCopy(img->image.data16+(f*img->width), buff+x+(y+f)*WIDTH,img->width*2); } } diff --git a/source/keyboard.c b/source/keyboard.c index eb50310..cb6a932 100644 --- a/source/keyboard.c +++ b/source/keyboard.c @@ -270,7 +270,7 @@ void SK_DisplayKeyboard(uint16 *vram) loadPCX(keyb_bin,&img); image8to16(&img); - dmaCopy(img.data8,vram,SCREEN_WIDTH*SCREEN_HEIGHT*2); + dmaCopy(img.image.data8,vram,SCREEN_WIDTH*SCREEN_HEIGHT*2); } diff --git a/source/main.c b/source/main.c index 29f4448..aed05f5 100644 --- a/source/main.c +++ b/source/main.c @@ -93,6 +93,7 @@ static void Splash(void) int y; int res=FALSE; + ZX81SuspendDisplay(); ZX81DisplayString("10 print '%the zx81 is ace%'\n20 goto 10"); FB_Clear(); @@ -159,6 +160,8 @@ static void Splash(void) { swiWaitForVBlank(); } + + ZX81ResumeDisplay(); } @@ -173,6 +176,8 @@ static void MapJoypad(void) SK_DisplayKeyboard(BG_GFX_SUB); + ZX81SuspendDisplay(); + ZX81DisplayString("press the joypad button you want\n" "to define and then the ZX81 key\n" "you want to use.\n\n" @@ -217,6 +222,8 @@ static void MapJoypad(void) swiWaitForVBlank(); } + + ZX81ResumeDisplay(); } @@ -228,26 +235,34 @@ int main(int argc, char *argv[]) powerON(POWER_ALL_2D); - /* Set up main text screen and load the ROM character data + /* Set up main screen for ZX81 and load the ROM character data */ - videoSetMode(MODE_0_2D | DISPLAY_BG0_ACTIVE); + videoSetMode(MODE_3_2D | DISPLAY_BG0_ACTIVE | DISPLAY_BG3_ACTIVE); - vramSetBankA(VRAM_A_MAIN_BG_0x6000000); - vramSetBankB(VRAM_B_MAIN_BG_0x6020000); + vramSetBankA(VRAM_A_MAIN_BG_0x06000000); + vramSetBankB(VRAM_B_MAIN_BG_0x06020000); - BG0_CR = BG_COLOR_256|BG_MAP_BASE(0)|BG_TILE_BASE(1); + BG0_CR = BG_COLOR_256 | BG_MAP_BASE(0) | BG_TILE_BASE(1) | BG_PRIORITY(0); BG0_X0 = 0; BG0_Y0 = 0; BG_PALETTE[0] = RGB15(31,31,31); BG_PALETTE[1] = RGB15(0,0,0); + BG3_CR = BG_BMP16_256x256 | BG_BMP_BASE(2) | BG_PRIORITY(1); + BG3_XDX = 0x100; + BG3_XDY = 0; + BG3_YDX = 0; + BG3_YDY = 0x100; + BG3_CX = 0; + BG3_CY = 0; + dmaCopy(rom_font_bin,(void *)BG_TILE_RAM(1),rom_font_bin_size); /* Set up the sub-screen for rotation (basically for use as a framebuffer) */ videoSetModeSub(MODE_5_2D | DISPLAY_BG2_ACTIVE); - vramSetBankC(VRAM_C_SUB_BG_0x6200000); + vramSetBankC(VRAM_C_SUB_BG_0x06200000); SUB_BG2_CR = BG_BMP16_256x256; SUB_BG2_XDX = 0x100; @@ -282,7 +297,7 @@ int main(int argc, char *argv[]) GUI_Alert(TRUE,"Failed to initialise\nthe Z80 CPU emulation!"); } - ZX81Init((uint16*)SCREEN_BASE_BLOCK(0), z80); + ZX81Init((uint16*)BG_MAP_RAM(0), (uint16*)BG_BMP_RAM(2), z80); Splash(); diff --git a/source/tapes.c b/source/tapes.c index bc5ac8b..8f141f9 100644 --- a/source/tapes.c +++ b/source/tapes.c @@ -232,6 +232,8 @@ void SelectTape(void) InitTapes(); + ZX81SuspendDisplay(); + while(!done) { uint32 key=0; @@ -272,5 +274,7 @@ void SelectTape(void) done=TRUE; } } + + ZX81ResumeDisplay(); } diff --git a/source/zx81.c b/source/zx81.c index d6edaa0..9a053b5 100644 --- a/source/zx81.c +++ b/source/zx81.c @@ -69,9 +69,15 @@ static Z80Val FRAME_TSTATES=FAST_TSTATES; /* The ZX81 screen and memory */ +static void (*DrawScreen)(Z80 *z80); + static int waitkey=FALSE; static int started=FALSE; +static int hires=FALSE; +static int hires_dfile; +static int last_I; + #define SCR_W 256 #define SCR_H 192 #define TXT_W 32 @@ -95,7 +101,8 @@ static int tape_len; /* GFX vars */ -static uint16 *screen; +static uint16 *txt_screen; +static uint16 *bmp_screen; /* The keyboard */ @@ -330,7 +337,89 @@ static void LoadExternalTape(FILE *tape, Z80 *z80) } -static void DrawScreen(Z80 *z80) +static void ClearBitmap(void) +{ + uint16 *s; + uint16 p; + int f; + + s = bmp_screen; + p = 0x8000|RGB15(31,31,31); + + for(f=0;f<SCREEN_WIDTH*SCREEN_HEIGHT;f++) + { + *s++=p; + } +} + + +static void ClearText(void) +{ + uint16 *s; + int f; + + s = txt_screen; + + for(f=0;f<TXT_W*TXT_H;f++) + { + *s++=0; + } +} + + +static void DrawScreen_HIRES(Z80 *z80) +{ + uint16 *bmp; + Z80Byte *scr; + int x,y; + int table; + + scr = mem + hires_dfile; + bmp = bmp_screen; + table = z80->I << 8; + + /* scr is increment in both loops so that it can skip of the end-of-line + character + */ + for(y=0; y<192; y++) + { + for(x=0; x<32; x++) + { + int c; + int v; + int b; + + c = *scr; + + v = mem[table + (c&0x3f)*8]; + + if (c & 0x80) + { + v ^= 0xff; + } + + for(b=0;b<8;b++) + { + if (v & 0x80) + { + *bmp++ = 0x8000; + } + else + { + *bmp++ = 0xffff; + } + + v=v<<1; + } + + scr++; + } + + scr++; + } +} + +static void DrawScreen_TEXT(Z80 *z80) { Z80Byte *scr=mem+WORD(DFILE); int x,y; @@ -349,11 +438,11 @@ static void DrawScreen(Z80 *z80) if (ch&0x80) { - screen[x+y*32]=(ch&0x3f)|0x40; + txt_screen[x+y*32]=(ch&0x3f)|0x40; } else { - screen[x+y*32]=(ch&0x3f); + txt_screen[x+y*32]=(ch&0x3f); } x++; @@ -369,7 +458,7 @@ static void DrawSnow(Z80 *z80) uint16 *s; int f; - s = screen; + s = txt_screen; for(f=0;f<TXT_W*TXT_H;f++) { @@ -378,6 +467,56 @@ static void DrawSnow(Z80 *z80) } +static void FindHiresDFILE(void) +{ + /* Somewhat based on the code from xz81, an X-based ZX81 emulator, + (C) 1994 Ian Collier. Search the ZX81's RAM until we find what looks + like a hi-res display file. + + Bizarrely the original code used 'f' for a loop counter too... Another + poor soul forever damaged by the ZX81's keyword entry system... + */ + int f; + + for(f=0x8000-(33*192); f>0x4000 ; f--) + { + int v; + + v = mem[f+32]; + + if (v&0x40) + { + int ok = TRUE; + int n; + + for(n=0;n<192 && ok;n++) + { + if (mem[f+33*n]&0x40) + { + ok = FALSE; + } + + if (mem[f+32+33*n] != v) + { + ok = FALSE; + } + } + + if (ok) + { + hires_dfile = f; + return; + } + } + } + + /* All else fails, put the hires dfile at 0x4000 -- at least it should be + obvious that the hires won't work for whatever is being run. + */ + hires_dfile = 0x4000; +} + + /* Perform ZX81 housekeeping functions like updating FRAMES and updating LASTK */ static void ZX81HouseKeeping(Z80 *z80) @@ -464,9 +603,33 @@ static int CheckTimers(Z80 *z80, Z80Val val) { if (val>=FRAME_TSTATES) { + /* Check for hi-res modes + */ + if (z80->I && z80->I != last_I) + { + last_I = z80->I; + + if (z80->I == 0x1e) + { + hires = FALSE; + DrawScreen = DrawScreen_TEXT; + ClearBitmap(); + } + else + { + hires = TRUE; + DrawScreen = DrawScreen_HIRES; + ClearText(); + FindHiresDFILE(); + } + } + Z80ResetCycles(z80,val-FRAME_TSTATES); - if (started && ((mem[CDFLAG] & 0x80) || waitkey)) + /* Kludge warning - We assume that a hires display will not be in + FAST mode! + */ + if (started && ((mem[CDFLAG] & 0x80) || waitkey || hires)) { DrawScreen(z80); FRAME_TSTATES=SLOW_TSTATES; @@ -582,11 +745,19 @@ static int EDCallback(Z80 *z80, Z80Val data) /* ---------------------------------------- EXPORTED INTERFACES */ -void ZX81Init(uint16 *vram, Z80 *z80) +void ZX81Init(uint16 *text_vram, uint16* bitmap_vram, Z80 *z80) { Z80Word f; - screen = vram; + txt_screen = text_vram; + bmp_screen = bitmap_vram; + + hires = FALSE; + hires_dfile = 0; + last_I = 0x1e; + DrawScreen = DrawScreen_TEXT; + + ClearBitmap(); /* Load the ROM */ @@ -602,7 +773,6 @@ void ZX81Init(uint16 *vram, Z80 *z80) */ memcpy(mem+ROMLEN,mem,ROMLEN); - /* Memory size (16K) */ RAMBOT=0x4000; @@ -701,6 +871,7 @@ Z80Byte ZX81ReadPort(Z80 *z80, Z80Word port) break; default: + b = 0xff; /* Idle bus */ break; } @@ -732,6 +903,13 @@ void ZX81Reset(Z80 *z80) Z80ResetCycles(z80,0); started=FALSE; + + hires = FALSE; + hires_dfile = 0; + last_I = 0x1e; + DrawScreen = DrawScreen_TEXT; + + ClearBitmap(); } @@ -748,20 +926,28 @@ void ZX81SetTape(const Z80Byte *image, int len) } +void ZX81SuspendDisplay(void) +{ + ClearBitmap(); + ClearText(); +} + + +void ZX81ResumeDisplay(void) +{ + ClearText(); +} + + void ZX81DisplayString(const char *p) { uint16 *s; uint16 inv=0; int f; - s = screen; - - for(f=0;f<TXT_W*TXT_H;f++) - { - *s++=0; - } + ClearText(); - s = screen; + s = txt_screen; f = 0; while(*p) |