diff --git a/src/video/vid_ps55da2.c b/src/video/vid_ps55da2.c index 98db5f9fa..7abdae157 100644 --- a/src/video/vid_ps55da2.c +++ b/src/video/vid_ps55da2.c @@ -66,7 +66,7 @@ #define DA2_MASK_VRAM 0xfffff /* 0xFFFFF */ #define DA2_MASK_VRAMPLANE 0x1ffff /* 0x1FFFF */ #define DA2_PIXELCLOCK 29000000.0 /* 58 MHz interlaced */ -#define DA2_BLT_MEMSIZE 0x100 +#define DA2_BLT_MEMSIZE 0x10 #define DA2_BLT_REGSIZE 0x40 #define DA2_DEBUG_BLTLOG_SIZE (DA2_BLT_REGSIZE + 1) #define DA2_DEBUG_BLTLOG_MAX (256 * 1024) @@ -112,18 +112,26 @@ EFD8h * Display Adapter/J [Atlas-SP2] [Japanese DOS and Display Adapter compatibility] - | POS ID | Adapter Name | K3.31 | J4.04 | J4.08 | OS2 J1.3 | Win3 | - |------------|-----------------------------|:-----:|:-----:|:-----:|:--------:|:----:| - | EFFFh | Display Adapter | X | | | | | - | FFEDh | ? [Atlas EVT] | X | | | | | - | FFFDh | ? [LDT EVT] | X | | | | | - | EFFEh | Display Adapter II,III,V,B2 | X | X | X | X | X | - | E013h | ? [LDT] | X | X | X | X | | - | ECCEh | Display Adapter IV | | X | X | X | | - | ECECh | Display Adapter IV,B1 | | X | X | X | X | - | 9000-901Fh | Display Adapter A1,A2 | | X | X | | X | - | EFD8h | Display Adapter /J | | | X | X | X | -*/ + | | | 5605JBK | 5605PAA | 5605PCA | 5605PDE | 5605PAW | 5605PXB | + | POS ID | Adapter Name | K3.31 | J4.05 | J4.08 | J1.33 | 3.02 | 2.0 | + |------------|-----------------------------|:-------:|:-------:|:-------:|:-------:|:-------:|:-------:| + | EFFFh | Display Adapter | X | | | | | | + | FFEDh | ? [Atlas EVT] | X | | | | | | + | FFFDh | ? [LDT EVT] | X | | | | | | + | EFFEh | Display Adapter II,III,V,B2 | X | X | X | X | X | X | + | E013h | ? [LDT] | X | X | X | X | | X | + | ECCEh | Display Adapter IV | | X | X | X | | X | + | ECECh | Display Adapter IV,B1 | | X | X | X | X | X | + | 9000-901Fh | Display Adapter A1,A2 | | X | X | | X | X | + | EFD8h | Display Adapter /J | | | X | X | X | X | + + - 5605JBK : Japanese DOS K3.3, K3.4 (for PS/55 model 55xx-S, T, V, Z) + - 5605PAA : DOS J4.0 + - 5605PCA : DOS J4.0 (with MKK) + - 5605PDE : OS/2 Extended Edition J1.3 + - 5605PAW : Japanese Microsoft Windows 3.0 (IBMJ OEM) + - 5605PXB : DOS/V Extension V2.0 + */ /* IO 3E0/3E1:0Ah Hardware Configuration Value L (imported from OS/2 DDK) */ #define OldLSI 0x20 /* 1 = DA-2, 0 = DA-3 */ // #define Mon_ID3 0x10 @@ -162,8 +170,10 @@ #define LF_INDEX 0x3e2 #define LF_DATA 0x3e3 #define LF_MMIO_SEL 0x08 /* added */ +#define LF_MMIO_09 0x09 /* added */ #define LF_MMIO_ADDR 0x0A /* added */ #define LF_MMIO_MODE 0x0B /* added */ +#define LF_PD_RESET 0x18 /* added */ #define LC_INDEX 0x3E4 #define LC_DATA 0x3E5 #define LC_HORIZONTAL_TOTAL 0x00 @@ -254,8 +264,8 @@ #endif #ifdef ENABLE_DA2_LOG -// # define ENABLE_DA2_DEBUGIO 1 -// # define ENABLE_DA2_DEBUGBLT 1 +# define ENABLE_DA2_DEBUGIO 1 +# define ENABLE_DA2_DEBUGBLT 1 // # define ENABLE_DA2_DEBUGVRAM 1 // # define ENABLE_DA2_DEBUGFULLSCREEN 1 // # define ENABLE_DA2_DEBUGMONWAIT 1 @@ -282,8 +292,15 @@ da2_log(const char *fmt, ...) #endif #ifdef ENABLE_DA2_DEBUGBLT # define da2_bltlog da2_log +# define ENABLE_DA2_DEBUGBLT_DETAIL 1 +# ifdef ENABLE_DA2_DEBUGBLT_DETAIL +# define da2_bltreglog da2_log +# else +# define da2_bltreglog(fmt, ...) +# endif #else # define da2_bltlog(fmt, ...) +# define da2_bltreglog(fmt, ...) #endif typedef struct da2_t { @@ -291,7 +308,9 @@ typedef struct da2_t { uint8_t ioctl[16]; uint8_t fctl[32]; - uint16_t crtc[128]; + uint16_t crtc[32]; + uint16_t crtc_vpreg[128]; + uint8_t crtc_vpsel; uint8_t gdcreg[64]; uint8_t reg3ee[16]; int gdcaddr; @@ -327,7 +346,7 @@ typedef struct da2_t { int vtotal, dispend, vsyncstart, split, vblankstart; int hdisp, htotal, hdisp_time, rowoffset; - int lowres, interlace; + int lowres; int rowcount; double clock; uint32_t ma_latch, ca_adj; @@ -342,7 +361,7 @@ typedef struct da2_t { uint32_t ma, maback, ca; int vc; int sc; - int linepos, vslines, linecountff, oddeven; + int linepos, vslines, linecountff; int con, cursoron, blink, blinkconf; int scrollcache; int char_width; @@ -380,6 +399,7 @@ typedef struct da2_t { int raster_op; uint8_t payload[DA2_BLT_MEMSIZE]; int payload_addr; + int payload_opsize; int32_t reg[DA2_BLT_REGSIZE]; // must be signed int #ifdef ENABLE_DA2_DEBUGBLT int32_t *debug_reg; // for debug @@ -403,6 +423,7 @@ typedef struct da2_t { int32_t maskl, maskr; int32_t count; int32_t d; + int8_t destoption; int octdir; int x, y, wx1, wx2, wy1, wy2; } bitblt; @@ -428,12 +449,12 @@ static void da2_bitblt_exec(void *p); static void da2_updatevidselector(da2_t *da2); static void da2_reset_ioctl(da2_t *da2); static void da2_reset(void *priv); -static uint16_t rightRotate(uint16_t data, uint8_t count); +static uint16_t da2_rightrotate(uint16_t data, uint8_t count); typedef union { uint32_t d; uint8_t b[4]; -} DA2_VidSeq32; +} vidseq32; typedef struct { uint32_t p8[8]; @@ -441,7 +462,7 @@ typedef struct { /* safety read for internal functions */ static uint32_t -DA2_vram_r(uint32_t addr, da2_t *da2) +da2_vram_r(uint32_t addr, da2_t *da2) { if (addr & ~DA2_MASK_VRAM) return DA2_INVALIDACCESS32; @@ -449,16 +470,49 @@ DA2_vram_r(uint32_t addr, da2_t *da2) } /* safety write for internal functions */ static void -DA2_vram_w(uint32_t addr, uint8_t val, da2_t *da2) +da2_vram_w(uint32_t addr, uint8_t val, da2_t *da2) { if (addr & ~DA2_MASK_VRAM) return; da2->vram[addr] = val; return; } + +/* +Param Desc +01 Color +03 Bit Shift +04 Select plane? +05 Direction (1000h or 1100h) + Command? (40 or 48) +08 Mask Left +09 Mask Right +0A Plane Mask? +0B ROP + 2000 NOT Source + 200 Source / Pattern + 20 NOT Dest + 10 NOT Pattern + 8 ? + 0-3 Bit op (0 None, 1 AND, 2 OR, 3 XOR) +0D +20 Exec (1) or Exec without reset regs? (21h) +21 Dest Pitch +22 Src Pitch +23 Tile W +28 Tile H +29 Dest Addr +2A Src Addr +2B Tile Addr +2D Octant for line drawing +2F Dest Write Option +32 wx1, Dest X +33 wx2, Size W +34 wy1, Dest Y +35 wy2, Size H +*/ /* write pixel data with rop (Note: bitmask must be in big endian) */ static void -DA2_WritePlaneDataWithBitmask(uint32_t destaddr, const uint16_t mask, pixel32 *srcpx, da2_t *da2) +da2_WritePlaneDataWithBitmask(uint32_t destaddr, const uint16_t mask, pixel32 *srcpx, da2_t *da2) { uint32_t writepx[8]; destaddr &= 0xfffffffe; /* align to word address to work bit shift correctly */ @@ -467,20 +521,25 @@ DA2_WritePlaneDataWithBitmask(uint32_t destaddr, const uint16_t mask, pixel32 *s destaddr <<= 3; /* read destination data with big endian order */ for (int i = 0; i < 8; i++) - writepx[i] = DA2_vram_r((destaddr + 24) | i, da2) - | (DA2_vram_r((destaddr + 16) | i, da2) << 8) - | (DA2_vram_r((destaddr + 8) | i, da2) << 16) - | (DA2_vram_r((destaddr + 0) | i, da2) << 24); + writepx[i] = da2_vram_r((destaddr + 24) | i, da2) + | (da2_vram_r((destaddr + 16) | i, da2) << 8) + | (da2_vram_r((destaddr + 8) | i, da2) << 16) + | (da2_vram_r((destaddr + 0) | i, da2) << 24); - DA2_VidSeq32 mask32in; + vidseq32 mask32in; mask32in.d = (uint32_t) mask; - DA2_VidSeq32 mask32; + vidseq32 mask32; mask32.b[3] = mask32in.b[0]; mask32.b[2] = mask32in.b[1]; mask32.d &= 0xffff0000; for (int i = 0; i < 8; i++) { if (da2->bitblt.bitshift_destr > 0) srcpx->p8[i] <<= 16 - da2->bitblt.bitshift_destr; +// #ifdef ENABLE_DA2_DEBUGBLT +// if (i == 0) { +// pclog("writeplane: src %08X mask %08X dest %08X\n", srcpx->p8[i], mask32.d, writepx[i]); +// } +// #endif if (da2->bitblt.raster_op & 0x2010) /* NOT Src or NOT Pattern */ srcpx->p8[i] = ~srcpx->p8[i] & mask32.d; if (da2->bitblt.raster_op & 0x20) /* Dest NOT */ @@ -502,98 +561,135 @@ DA2_WritePlaneDataWithBitmask(uint32_t destaddr, const uint16_t mask, pixel32 *s } } for (int i = 0; i < 8; i++) { - DA2_vram_w(destaddr | i, (writepx[i] >> 24) & 0xff, da2); - DA2_vram_w((destaddr + 8) | i, (writepx[i] >> 16) & 0xff, da2); + da2_vram_w(destaddr | i, (writepx[i] >> 24) & 0xff, da2); + da2_vram_w((destaddr + 8) | i, (writepx[i] >> 16) & 0xff, da2); } } static void -DA2_DrawColorWithBitmask(uint32_t destaddr, uint8_t color, uint16_t mask, da2_t *da2) +da2_DrawColorWithBitmask(uint32_t destaddr, uint8_t color, uint16_t mask, da2_t *da2) { pixel32 srcpx; /* fill data with input color */ for (int i = 0; i < 8; i++) srcpx.p8[i] = (color & (1 << i)) ? 0xffffffff : 0; /* read in word */ - DA2_WritePlaneDataWithBitmask(destaddr, mask, &srcpx, da2); + da2_WritePlaneDataWithBitmask(destaddr, mask, &srcpx, da2); } -/* -Param Desc -01 Color -03 Bit Shift -04 Select plane? -05 Dir(1000h or 1100h) + Command?(40 or 48) -08 Mask Left -09 Mask Right -0A Plane Mask? -0B ROP - 2000 NOT Source - 200 Source / Pattern - 20 NOT Dest - 10 NOT Pattern - 8 ? - 0-3 Bit op (0 None, 1 AND, 2 OR, 3 XOR) -0D -20 Exec (1) or Exec without reset regs? (21h) -21 ? -22 ? -23 Tile W -28 Tile H -29 Dest Addr -2A Src Addr -2B Tile Addr -33 Size W -35 Size H -*/ static void -DA2_CopyPlaneDataWithBitmask(uint32_t srcaddr, uint32_t destaddr, uint16_t mask, da2_t *da2) +da2_CopyPlaneDataWithBitmask(uint32_t srcaddr, uint32_t destaddr, uint16_t mask, da2_t *da2) { pixel32 srcpx; srcaddr &= 0xfffffffe; srcaddr <<= 3; for (int i = 0; i < 8; i++) - srcpx.p8[i] = DA2_vram_r((srcaddr + 24) | i, da2) - | (DA2_vram_r((srcaddr + 16) | i, da2) << 8) - | (DA2_vram_r((srcaddr + 8) | i, da2) << 16) - | (DA2_vram_r((srcaddr + 0) | i, da2) << 24); + srcpx.p8[i] = da2_vram_r((srcaddr + 24) | i, da2) + | (da2_vram_r((srcaddr + 16) | i, da2) << 8) + | (da2_vram_r((srcaddr + 8) | i, da2) << 16) + | (da2_vram_r((srcaddr + 0) | i, da2) << 24); - DA2_WritePlaneDataWithBitmask(destaddr, mask, &srcpx, da2); + da2_WritePlaneDataWithBitmask(destaddr, mask, &srcpx, da2); +} +/* get font data for bitblt operation */ +static uint32_t +getRAMFont(int32_t code, int line, int x, void *p) +{ + da2_t *da2 = (da2_t *) p; + uint32_t font = 0; + int fline = line - 2; /* Start line of drawing character (line >= 1 AND line < 24 + 1 ) */ + if (code < 0x100) { /* SBCS 13x29 */ + code *= 0x40; + code += DA2_GAIJIRAM_SBCS + (line * 2) + x; + font = da2->mmio.ram[code]; + font <<= 8; + font |= da2->mmio.ram[code + 1]; + font <<= 16; + } else if ((code >= 0xb000) && (code <= 0xb75f)) { /* DBCS 26x29 */ + /* convert code->address in gaiji memory */ + code -= 0xb000; + code = (code * 0x80) + (line * 4) + x; + font = da2->mmio.ram[code]; + font <<= 8; + font |= da2->mmio.ram[code + 1]; + font <<= 8; + font |= da2->mmio.ram[code + 2]; + font <<= 8; + font |= da2->mmio.ram[code + 3]; + } + else + font = 0; + return font; +} +/* Reverse the bit order of attribute code IBGR to IRGB(used in Mode 3 and Cursor Color) */ +static int8_t +IBGRtoIRGB(uint8_t attr) +{ + attr = ((attr & 0x01) << 6) | ((attr & 0x02) << 4) | ((attr & 0x04) << 2) | ((attr & 0x08) << 4); + return attr >>= 4; } static void -DA2_PutcharWithBitmask(uint32_t srcaddr, uint32_t destaddr, uint16_t mask, da2_t *da2) +da2_PutcharWithBitmask(uint32_t codeIBMJ, int width, uint16_t attr, int line, uint32_t destaddr, uint16_t maskl, uint16_t maskr, da2_t *da2) { pixel32 srcpx; - if (srcaddr >= DA2_FONTROM_SIZE) { - da2_log("DA2 Putchar Addr Error %x\n", srcaddr); - return; + uint8_t fg = (~attr >> 8) & 0x0f; + uint8_t bg = (~attr >> 12) & 0x0f; + uint32_t font = getRAMFont(codeIBMJ, line, 0, da2); + uint32_t fontinv; + if (width <= 2) { + fontinv = ~font; + for (int i = 0; i < 8; i++) { + srcpx.p8[i] = (fg & (1 << i)) ? font >> 16 : 0; + srcpx.p8[i] |= (bg & (1 << i)) ? fontinv >> 16 : 0; + } + da2_WritePlaneDataWithBitmask(destaddr, maskl, &srcpx, da2); + for (int i = 0; i < 8; i++) { + srcpx.p8[i] = (fg & (1 << i)) ? font : 0; + srcpx.p8[i] |= (bg & (1 << i)) ? fontinv : 0; + } + da2_WritePlaneDataWithBitmask(destaddr + 2, maskr, &srcpx, da2); + } else { + font = (font & 0xfff80000) | ((font & 0x0000ffff) << 3); + fontinv = ~font; + for (int i = 0; i < 8; i++) { + srcpx.p8[i] = (fg & (1 << i)) ? font >> 16 : 0; + srcpx.p8[i] |= (bg & (1 << i)) ? fontinv >> 16 : 0; + } + da2_WritePlaneDataWithBitmask(destaddr, maskl, &srcpx, da2); + for (int i = 0; i < 8; i++) { + srcpx.p8[i] = (fg & (1 << i)) ? font : 0; + srcpx.p8[i] |= (bg & (1 << i)) ? fontinv : 0; + } + if (da2->bitblt.destoption & 0x20) { + da2_WritePlaneDataWithBitmask(destaddr + 2, maskr, &srcpx, da2); + } else { + da2_WritePlaneDataWithBitmask(destaddr + 2, 0xffff, &srcpx, da2); + for (int i = 0; i < 8; i++) { + srcpx.p8[i] = (fg & (1 << i)) ? font << 16 : 0; + srcpx.p8[i] |= (bg & (1 << i)) ? fontinv << 16 : 0; + } + da2_WritePlaneDataWithBitmask(destaddr + 4, maskr, &srcpx, da2); + } } - for (int i = 0; i < 8; i++) - srcpx.p8[i] = ((uint32_t) da2->mmio.font[srcaddr] << 24) - | ((uint32_t) da2->mmio.font[srcaddr + 1] << 16) - | ((uint32_t) da2->mmio.font[srcaddr + 2] << 8) - | ((uint32_t) da2->mmio.font[srcaddr + 3] << 0); - - DA2_WritePlaneDataWithBitmask(destaddr, mask, &srcpx, da2); } #ifdef ENABLE_DA2_DEBUGBLT -uint8_t +static uint8_t pixel1tohex(uint32_t addr, int index, da2_t *da2) { uint8_t pixeldata = 0; for (int j = 0; j < 8; j++) { - if (DA2_vram_r(((addr << 3) | j) & (1 << (7 - index)), da2)) + if (da2_vram_r(((addr << 3) | j) & (1 << (7 - index)), da2)) pixeldata++; } return pixeldata; } -void +static void print_pixelbyte(uint32_t addr, da2_t *da2) { for (int i = 0; i < 8; i++) { pclog("%X", pixel1tohex(addr, i, da2)); } } -void +static void print_bytetobin(uint8_t b) { for (int i = 0; i < 8; i++) { @@ -605,17 +701,17 @@ print_bytetobin(uint8_t b) } } /* Convert internal char code to Shift JIS code */ -inline int +static int isKanji1(uint8_t chr) { return (chr >= 0x81 && chr <= 0x9f) || (chr >= 0xe0 && chr <= 0xfc); } -inline int +static int isKanji2(uint8_t chr) { return (chr >= 0x40 && chr <= 0x7e) || (chr >= 0x80 && chr <= 0xfc); } -uint16_t +static uint16_t IBMJtoSJIS(uint16_t knj) { if (knj < 0x100) @@ -646,241 +742,237 @@ IBMJtoSJIS(uint16_t knj) return knj; } #endif + static void -da2_bitblt_load(da2_t *da2) +da2_bitblt_parse(da2_t *da2) { uint32_t value32; uint64_t value64; -#ifdef ENABLE_DA2_DEBUGBLT - da2_log("bltload: loading params\n"); - da2_log("BitBlt memory:\n"); - if (da2->bitblt.payload[0] != 0) - for (int j = 0; j < DA2_BLT_MEMSIZE / 8; j++) - { - int i = j * 8; - da2_log("%02x %02x %02x %02x %02x %02x %02x %02x \n", da2->bitblt.payload[i], da2->bitblt.payload[i + 1], da2->bitblt.payload[i + 2], da2->bitblt.payload[i + 3], - da2->bitblt.payload[i + 4], da2->bitblt.payload[i + 5], da2->bitblt.payload[i + 6], da2->bitblt.payload[i + 7]); - } -#endif - int i = 0; - while (i < da2->bitblt.payload_addr) { - if (da2->bitblt.reg[0x20] & 0x1) + switch (da2->bitblt.payload[0]) { + case 0x88: + case 0x89: + case 0x95: + value32 = da2->bitblt.payload[3]; + value32 <<= 8; + value32 |= da2->bitblt.payload[2]; + da2_bltreglog("[%02x] %02x: %04x (%d)\n", da2->bitblt.payload[0], da2->bitblt.payload[1], value32, value32); + da2->bitblt.reg[da2->bitblt.payload[1]] = value32; + break; + case 0x91: + value32 = da2->bitblt.payload[5]; + value32 <<= 8; + value32 |= da2->bitblt.payload[4]; + value32 <<= 8; + value32 |= da2->bitblt.payload[3]; + value32 <<= 8; + value32 |= da2->bitblt.payload[2]; + da2_bltreglog("[%02x] %02x: %08x (%d)\n", da2->bitblt.payload[0], da2->bitblt.payload[1], value32, value32); + da2->bitblt.reg[da2->bitblt.payload[1]] = value32; + break; + case 0x99: + value64 = da2->bitblt.payload[7]; + value64 <<= 8; + value64 = da2->bitblt.payload[6]; + value64 <<= 8; + value64 = da2->bitblt.payload[5]; + value64 <<= 8; + value64 |= da2->bitblt.payload[4]; + value64 <<= 8; + value64 |= da2->bitblt.payload[3]; + value64 <<= 8; + value64 |= da2->bitblt.payload[2]; + da2_bltreglog("[%02x] %02x: %02x %02x %02x %02x %02x %02x\n", da2->bitblt.payload[0], da2->bitblt.payload[1], da2->bitblt.payload[2], da2->bitblt.payload[3], + da2->bitblt.payload[4], da2->bitblt.payload[5], da2->bitblt.payload[6], da2->bitblt.payload[7]); + da2->bitblt.reg[da2->bitblt.payload[1]] = value64; + break; + case 0xa1: + value64 = da2->bitblt.payload[9]; + value64 <<= 8; + value64 |= da2->bitblt.payload[8]; + value64 <<= 8; + value64 |= da2->bitblt.payload[7]; + value64 <<= 8; + value64 |= da2->bitblt.payload[6]; + value64 <<= 8; + value64 |= da2->bitblt.payload[5]; + value64 <<= 8; + value64 |= da2->bitblt.payload[4]; + value64 <<= 8; + value64 |= da2->bitblt.payload[3]; + value64 <<= 8; + value64 |= da2->bitblt.payload[2]; + da2_bltreglog("[%02x] %02x: %02x %02x %02x %02x %02x %02x %02x %02x\n", da2->bitblt.payload[0], da2->bitblt.payload[1], da2->bitblt.payload[2], da2->bitblt.payload[3], + da2->bitblt.payload[4], da2->bitblt.payload[5], da2->bitblt.payload[6], da2->bitblt.payload[7], da2->bitblt.payload[8], da2->bitblt.payload[9]); + da2->bitblt.reg[da2->bitblt.payload[1]] = value64; + break; + case 0x00: /* Win 3.0 Clock writes invalid zero data. */ + break; + default: + da2_log("bltload: Unknown PreOP!\n"); break; - switch (da2->bitblt.payload[i]) { - case 0x88: - case 0x89: - case 0x95: - value32 = da2->bitblt.payload[i + 3]; - value32 <<= 8; - value32 |= da2->bitblt.payload[i + 2]; - da2_bltlog("[%02x] %02x: %04x (%d)\n", da2->bitblt.payload[i], da2->bitblt.payload[i + 1], value32, value32); - da2->bitblt.reg[da2->bitblt.payload[i + 1]] = value32; - // da2->gdcreg[da2->bitblt.payload[i + 1]] = value32; - i += 3; - break; - case 0x91: - value32 = da2->bitblt.payload[i + 5]; - value32 <<= 8; - value32 |= da2->bitblt.payload[i + 4]; - value32 <<= 8; - value32 |= da2->bitblt.payload[i + 3]; - value32 <<= 8; - value32 |= da2->bitblt.payload[i + 2]; - da2_bltlog("[%02x] %02x: %08x (%d)\n", da2->bitblt.payload[i], da2->bitblt.payload[i + 1], value32, value32); - da2->bitblt.reg[da2->bitblt.payload[i + 1]] = value32; - // da2->gdcreg[da2->bitblt.payload[i + 1]] = value32; - i += 5; - break; - case 0x99: - value64 = da2->bitblt.payload[i + 7]; - value64 <<= 8; - value64 = da2->bitblt.payload[i + 6]; - value64 <<= 8; - value64 = da2->bitblt.payload[i + 5]; - value64 <<= 8; - value64 |= da2->bitblt.payload[i + 4]; - value64 <<= 8; - value64 |= da2->bitblt.payload[i + 3]; - value64 <<= 8; - value64 |= da2->bitblt.payload[i + 2]; - da2_bltlog("[%02x] %02x: %02x %02x %02x %02x %02x %02x\n", da2->bitblt.payload[i], da2->bitblt.payload[i + 1], da2->bitblt.payload[i + 2], da2->bitblt.payload[i + 3], - da2->bitblt.payload[i + 4], da2->bitblt.payload[i + 5], da2->bitblt.payload[i + 6], da2->bitblt.payload[i + 7]); - da2->bitblt.reg[da2->bitblt.payload[i + 1]] = value64; - // da2->gdcreg[da2->bitblt.payload[i + 1]] = value64; - i += 7; - break; - case 0x00: - break; - default: - da2_log("bltload: Unknown PreOP!\n"); - break; - } - i++; } - da2->bitblt.exec = DA2_BLT_CIDLE; + if (da2->bitblt.reg[0x20] & 0x01) { /* Execute Bitblt immediately (for OS/2 J1.3) */ + da2->bitblt.exec = DA2_BLT_CLOAD; + da2_bitblt_exec(da2); + } /* clear payload memory */ memset(da2->bitblt.payload, 0x00, DA2_BLT_MEMSIZE); da2->bitblt.payload_addr = 0; - /* [89] 20: 0001 (1) then execute payload */ - if (da2->bitblt.reg[0x20] & 0x1) { -#ifdef ENABLE_DA2_DEBUGBLT - for (i = 0; i < DA2_DEBUG_BLTLOG_SIZE; i++) { - da2->bitblt.debug_reg[DA2_DEBUG_BLTLOG_SIZE * da2->bitblt.debug_reg_ip + i] = da2->bitblt.reg[i]; - } - da2->bitblt.debug_reg[DA2_DEBUG_BLTLOG_SIZE * (da2->bitblt.debug_reg_ip + 1) - 1] = 0; - da2->bitblt.debug_reg_ip++; - if ((DA2_DEBUG_BLTLOG_SIZE * da2->bitblt.debug_reg_ip) >= DA2_DEBUG_BLTLOG_MAX) - da2->bitblt.debug_reg_ip = 0; - da2->bitblt.debug_exesteps = 0; -#endif - da2_log("bltload_exec: %x, rop: %x CS:PC=%4x:%4x\n", da2->bitblt.reg[0x5], da2->bitblt.reg[0x0b], CS, cpu_state.pc); - da2->bitblt.bitshift_destr = ((da2->bitblt.reg[0x3] >> 4) & 0x0f); /* set bit shift */ - da2->bitblt.raster_op = da2->bitblt.reg[0x0b]; - da2->bitblt.destaddr = da2->bitblt.reg[0x29]; - da2->bitblt.size_x = da2->bitblt.reg[0x33]; - da2->bitblt.size_y = da2->bitblt.reg[0x35]; - da2->bitblt.destpitch = da2->bitblt.reg[0x21]; - da2->bitblt.srcpitch = da2->bitblt.reg[0x22]; - if (da2->bitblt.reg[0x2F] == 0x90) /* destaddr -= 2, length += 1; */ - { - da2->bitblt.destaddr -= 2; - da2->bitblt.size_x += 1; - da2->bitblt.destpitch -= 2; - da2->bitblt.srcpitch -= 2; - } - da2->bitblt.fcolor = da2->bitblt.reg[0x0]; - da2->bitblt.maskl = da2->bitblt.reg[0x8]; - da2->bitblt.maskr = da2->bitblt.reg[0x9]; - da2->bitblt.x = 0; - da2->bitblt.y = 0; - da2->bitblt.exec = DA2_BLT_CDONE; + da2->bitblt.indata = 0; +} - /* Put DBCS char used by OS/2 (i'm not sure what the condition is) */ - if (da2->bitblt.reg[0x10] == 0xbc04) { - da2->bitblt.exec = DA2_BLT_CPUTCHAR; - /* Todo: addressing */ - // if (da2->bitblt.reg[0x2F] == 0x90) /* destaddr -= 2, length += 1; */ - //{ - // da2->bitblt.destaddr += 2; - // da2->bitblt.size_x -= 1; - // da2->bitblt.destpitch += 2; - // da2->bitblt.srcpitch += 2; - // } - da2->bitblt.srcaddr = da2->bitblt.reg[0x12] * 72 + 2; - da2->bitblt.destaddr += 2; - da2->bitblt.srcpitch = 0; - da2->bitblt.bitshift_destr += 1; +static void +da2_bitblt_load(da2_t *da2) +{ + da2->bitblt.reg[0x20] = 0; /* need to stop execution */ #ifdef ENABLE_DA2_DEBUGBLT - uint32_t sjis_h = IBMJtoSJIS(da2->bitblt.reg[0x12]) >> 8; - uint32_t sjis_l = IBMJtoSJIS(da2->bitblt.reg[0x12]) & 0xff; - da2_log("put char src=%x, dest=%x, x=%d, y=%d, w=%d, h=%d, c=%c%c\n", - da2->bitblt.srcaddr, da2->bitblt.destaddr, - da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), - da2->bitblt.size_x, da2->bitblt.size_y, sjis_h, sjis_l); + for (int i = 0; i < DA2_DEBUG_BLTLOG_SIZE; i++) { + da2->bitblt.debug_reg[DA2_DEBUG_BLTLOG_SIZE * da2->bitblt.debug_reg_ip + i] = da2->bitblt.reg[i]; + } + da2->bitblt.debug_reg[DA2_DEBUG_BLTLOG_SIZE * (da2->bitblt.debug_reg_ip + 1) - 1] = 0; + da2->bitblt.debug_reg_ip++; + if ((DA2_DEBUG_BLTLOG_SIZE * da2->bitblt.debug_reg_ip) >= DA2_DEBUG_BLTLOG_MAX) + da2->bitblt.debug_reg_ip = 0; + da2->bitblt.debug_exesteps = 0; #endif - } - /* Put SBCS char used by OS/2 */ - else if (da2->bitblt.reg[0x10] == 0x0004 || da2->bitblt.reg[0x10] == 0x0E04) { - da2->bitblt.exec = DA2_BLT_CPUTCHAR; - da2->bitblt.srcaddr = da2->bitblt.reg[0x12] * 64 + 2 + DA2_FONTROM_BASESBCS; - da2->bitblt.destaddr += 2; - da2->bitblt.srcpitch = 0; - da2->bitblt.bitshift_destr += 1; + da2->bitblt.bitshift_destr = ((da2->bitblt.reg[0x03] >> 4) & 0x0f); /* set bit shift */ + da2->bitblt.raster_op = da2->bitblt.reg[0x0b]; + da2->bitblt.destaddr = da2->bitblt.reg[0x29]; + da2->bitblt.size_x = da2->bitblt.reg[0x33]; + da2->bitblt.size_y = da2->bitblt.reg[0x35]; + da2->bitblt.destpitch = da2->bitblt.reg[0x21]; + da2->bitblt.srcpitch = da2->bitblt.reg[0x22]; + /* + DOS/V Extension 1040x725 some DBCS uses 0xB0 others 0x90 + */ + da2->bitblt.destoption = da2->bitblt.reg[0x2F]; + if (da2->bitblt.destoption & 0x10) /* destaddr -= 2, length += 1; */ + { + da2->bitblt.destaddr -= 2; + da2->bitblt.size_x += 1; + da2->bitblt.destpitch -= 2; + da2->bitblt.srcpitch -= 2; + } + da2->bitblt.fcolor = da2->bitblt.reg[0x0]; + da2->bitblt.maskl = da2->bitblt.reg[0x8]; + da2->bitblt.maskr = da2->bitblt.reg[0x9]; + da2->bitblt.x = 0; + da2->bitblt.y = 0; + da2->bitblt.exec = DA2_BLT_CDONE; + + /* Put DBCS char used by OS/2 and DOS/V Extension */ + if (!(da2->bitblt.reg[0xb] & 0x08)) { + da2->bitblt.exec = DA2_BLT_CPUTCHAR; + da2->bitblt.fcolor = da2->bitblt.reg[0x1]; + da2->bitblt.srcaddr = da2->bitblt.reg[0x12]; + da2->bitblt.destaddr += 2; #ifdef ENABLE_DA2_DEBUGBLT - uint32_t sjis_h = IBMJtoSJIS(da2->bitblt.reg[0x12]) >> 8; - uint32_t sjis_l = IBMJtoSJIS(da2->bitblt.reg[0x12]) & 0xff; - da2_log("put char src=%x, dest=%x, x=%d, y=%d, w=%d, h=%d, c=%c%c\n", - da2->bitblt.srcaddr, da2->bitblt.destaddr, - da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), - da2->bitblt.size_x, da2->bitblt.size_y, sjis_h, sjis_l); + uint8_t sjis_h = IBMJtoSJIS(da2->bitblt.reg[0x12]) >> 8; + uint8_t sjis_l = IBMJtoSJIS(da2->bitblt.reg[0x12]) & 0xff; + if (da2->bitblt.reg[0x12] < 0x100) { + sjis_h = 0x20; + sjis_l = da2->bitblt.reg[0x12]; + } else { + if (!(isKanji1(sjis_h))) + sjis_h = 0x3f; + if (!(isKanji2(sjis_l))) + sjis_l = 0x3f; + } + da2_log("put char src=%x, dest=%x, x=%d, y=%d, w=%d, h=%d, c=%c%c\n", + da2->bitblt.srcaddr, da2->bitblt.destaddr, + da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), + da2->bitblt.size_x, da2->bitblt.size_y, sjis_h, sjis_l); +#else + da2_log("put char src=%x, dest=%x, x=%d, y=%d, w=%d, h=%d\n", + da2->bitblt.srcaddr, da2->bitblt.destaddr, + da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), + da2->bitblt.size_x, da2->bitblt.size_y); #endif - } - /* Draw a line */ - else if (da2->bitblt.reg[0x5] == 0x43) { - da2->bitblt.exec = DA2_BLT_CLINE; - da2->bitblt.dest_x = (da2->bitblt.reg[0x32] & 0xffff); - da2->bitblt.dest_y = (da2->bitblt.reg[0x34] & 0xffff); - da2->bitblt.wx1 = (da2->bitblt.reg[0x32]) >> 16; - da2->bitblt.wx2 = (da2->bitblt.reg[0x33]) >> 16; - da2->bitblt.wy1 = (da2->bitblt.reg[0x34]) >> 16; - da2->bitblt.wy2 = (da2->bitblt.reg[0x35]) >> 16; - da2->bitblt.size_x = abs((int16_t)(da2->bitblt.reg[0x33] & 0xffff) - da2->bitblt.dest_x); - da2->bitblt.size_y = abs((int16_t)(da2->bitblt.reg[0x35] & 0xffff) - da2->bitblt.dest_y); - da2->bitblt.count = 0; - da2->bitblt.octdir = da2->bitblt.reg[0x2D]; - da2->bitblt.bitshift_destr = 0; - if (da2->bitblt.octdir & 0x04) /* dX > dY */ - da2->bitblt.d = 2 * da2->bitblt.size_y - da2->bitblt.size_x; - else - da2->bitblt.d = 2 * da2->bitblt.size_x - da2->bitblt.size_y; - da2->bitblt.x = da2->bitblt.dest_x; - da2->bitblt.y = da2->bitblt.dest_y; - da2_log("drawline x=%d, y=%d, dx=%d, dy=%d, oct=%dn", - da2->bitblt.dest_x, da2->bitblt.dest_y, - da2->bitblt.size_x, da2->bitblt.size_y, da2->bitblt.octdir); - da2_log(" x1=%d, x2=%d, y1=%d, y2=%d\n", - da2->bitblt.reg[0x32] & 0x7ff, da2->bitblt.reg[0x33] & 0x7ff, - da2->bitblt.reg[0x34] & 0x7ff, da2->bitblt.reg[0x35] & 0x7ff); - da2_log(" ux1=%d,ux2=%d,uy1=%d,uy2=%d\n", - (da2->bitblt.reg[0x32] >> 16) & 0x7ff, (da2->bitblt.reg[0x33] >> 16) & 0x7ff, - (da2->bitblt.reg[0x34] >> 16) & 0x7ff, (da2->bitblt.reg[0x35] >> 16) & 0x7ff); - } - /* Fill a rectangle (or draw a horizontal / vertical line) */ - else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x40 && da2->bitblt.reg[0x3D] == 0) { - da2_log("fillrect x=%d, y=%d, w=%d, h=%d, c=%d, 2f=%x, rowcount=%x\n", - da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), - da2->bitblt.size_x, da2->bitblt.size_y, da2->bitblt.reg[0x0], da2->bitblt.reg[0x2F], da2->rowoffset * 2); - da2->bitblt.exec = DA2_BLT_CFILLRECT; - da2->bitblt.destaddr += 2; - } - /* Tiling a rectangle ??(transfer tile data multiple times) os/2 only */ - else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x0040 && da2->bitblt.reg[0x3D] == 0x40) { - da2->bitblt.exec = DA2_BLT_CFILLTILE; - da2->bitblt.destaddr += 2; - da2->bitblt.srcaddr = da2->bitblt.reg[0x2B]; - da2->bitblt.tile_w = da2->bitblt.reg[0x28]; - da2_log("copy tile src=%x, dest=%x, x1=%d, y1=%d, x2=%d, y2=%d, w=%d, h=%d\n", - da2->bitblt.srcaddr, da2->bitblt.destaddr, - da2->bitblt.reg[0x2B] % (da2->rowoffset * 2), da2->bitblt.reg[0x2B] / (da2->rowoffset * 2), - da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), - da2->bitblt.size_x, da2->bitblt.size_y); - } - /* Tiling a rectangle (transfer tile data multiple times) */ - else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x1040 && da2->bitblt.reg[0x3D] == 0x40) { - da2->bitblt.exec = DA2_BLT_CFILLTILE; - da2->bitblt.destaddr += 2; - da2->bitblt.srcaddr = da2->bitblt.reg[0x2B]; - da2->bitblt.tile_w = da2->bitblt.reg[0x28]; - da2_log("copy tile src=%x, dest=%x, x1=%d, y1=%d, x2=%d, y2=%d, w=%d, h=%d\n", - da2->bitblt.srcaddr, da2->bitblt.destaddr, - da2->bitblt.reg[0x2B] % (da2->rowoffset * 2), da2->bitblt.reg[0x2B] / (da2->rowoffset * 2), - da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), - da2->bitblt.size_x, da2->bitblt.size_y); - } - /* Block copy */ - else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x1040 && da2->bitblt.reg[0x3D] == 0x00) { - da2->bitblt.exec = DA2_BLT_CCOPYF; - da2->bitblt.srcaddr = da2->bitblt.reg[0x2A]; - da2->bitblt.destaddr += 2; - da2_log("copy block src=%x, dest=%x, x1=%d, y1=%d, x2=%d, y2=%d, w=%d, h=%d\n", - da2->bitblt.srcaddr, da2->bitblt.destaddr, - da2->bitblt.reg[0x2A] % (da2->rowoffset * 2), da2->bitblt.reg[0x2A] / (da2->rowoffset * 2), - da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), - da2->bitblt.size_x, da2->bitblt.size_y); - } - /* Block copy but reversed direction */ - else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x1140 && da2->bitblt.reg[0x3D] == 0x00) { - da2->bitblt.exec = DA2_BLT_CCOPYR; - da2->bitblt.srcaddr = da2->bitblt.reg[0x2A]; - da2->bitblt.destaddr -= 2; - da2->bitblt.srcaddr -= 2; - da2_log("copy blockR src=%x, dest=%x, x1=%d, y1=%d, x2=%d, y2=%d, w=%d, h=%d\n", - da2->bitblt.srcaddr, da2->bitblt.destaddr, - da2->bitblt.reg[0x2A] % (da2->rowoffset * 2), da2->bitblt.reg[0x2A] / (da2->rowoffset * 2), - da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), - da2->bitblt.size_x, da2->bitblt.size_y); - // da2_log(" mask8=%x, mask9=%x\n", da2->bitblt.reg[0x8], da2->bitblt.reg[0x9]); - } + } + /* Draw a line */ + else if (da2->bitblt.reg[0x5] == 0x43) { + da2->bitblt.exec = DA2_BLT_CLINE; + da2->bitblt.dest_x = (da2->bitblt.reg[0x32] & 0xffff); + da2->bitblt.dest_y = (da2->bitblt.reg[0x34] & 0xffff); + da2->bitblt.wx1 = (da2->bitblt.reg[0x32]) >> 16; + da2->bitblt.wx2 = (da2->bitblt.reg[0x33]) >> 16; + da2->bitblt.wy1 = (da2->bitblt.reg[0x34]) >> 16; + da2->bitblt.wy2 = (da2->bitblt.reg[0x35]) >> 16; + da2->bitblt.size_x = abs((int16_t) (da2->bitblt.reg[0x33] & 0xffff) - da2->bitblt.dest_x); + da2->bitblt.size_y = abs((int16_t) (da2->bitblt.reg[0x35] & 0xffff) - da2->bitblt.dest_y); + da2->bitblt.count = 0; + da2->bitblt.octdir = da2->bitblt.reg[0x2D]; + da2->bitblt.bitshift_destr = 0; + if (da2->bitblt.octdir & 0x04) /* dX > dY */ + da2->bitblt.d = 2 * da2->bitblt.size_y - da2->bitblt.size_x; + else + da2->bitblt.d = 2 * da2->bitblt.size_x - da2->bitblt.size_y; + da2->bitblt.x = da2->bitblt.dest_x; + da2->bitblt.y = da2->bitblt.dest_y; + da2_log("drawline x=%d, y=%d, dx=%d, dy=%d, oct=%dn", + da2->bitblt.dest_x, da2->bitblt.dest_y, + da2->bitblt.size_x, da2->bitblt.size_y, da2->bitblt.octdir); + da2_log(" x1=%d, x2=%d, y1=%d, y2=%d\n", + da2->bitblt.reg[0x32] & 0x7ff, da2->bitblt.reg[0x33] & 0x7ff, + da2->bitblt.reg[0x34] & 0x7ff, da2->bitblt.reg[0x35] & 0x7ff); + da2_log(" ux1=%d,ux2=%d,uy1=%d,uy2=%d\n", + (da2->bitblt.reg[0x32] >> 16) & 0x7ff, (da2->bitblt.reg[0x33] >> 16) & 0x7ff, + (da2->bitblt.reg[0x34] >> 16) & 0x7ff, (da2->bitblt.reg[0x35] >> 16) & 0x7ff); + } + /* Fill a rectangle (or draw a horizontal / vertical line) */ + else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x40 && da2->bitblt.reg[0x3D] == 0) { + da2_log("fillrect x=%d, y=%d, w=%d, h=%d, c=%d, 2f=%x, rowcount=%x\n", + da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), + da2->bitblt.size_x, da2->bitblt.size_y, da2->bitblt.reg[0x0], da2->bitblt.reg[0x2F], da2->rowoffset * 2); + da2->bitblt.exec = DA2_BLT_CFILLRECT; + da2->bitblt.destaddr += 2; + } + /* Tiling a rectangle ??(transfer tile data multiple times) os/2 only */ + else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x0040 && da2->bitblt.reg[0x3D] == 0x40) { + da2->bitblt.exec = DA2_BLT_CFILLTILE; + da2->bitblt.destaddr += 2; + da2->bitblt.srcaddr = da2->bitblt.reg[0x2B]; + da2->bitblt.tile_w = da2->bitblt.reg[0x28]; + da2_log("copy tile src=%x, dest=%x, x1=%d, y1=%d, x2=%d, y2=%d, w=%d, h=%d\n", + da2->bitblt.srcaddr, da2->bitblt.destaddr, + da2->bitblt.reg[0x2B] % (da2->rowoffset * 2), da2->bitblt.reg[0x2B] / (da2->rowoffset * 2), + da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), + da2->bitblt.size_x, da2->bitblt.size_y); + } + /* Tiling a rectangle (transfer tile data multiple times) */ + else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x1040 && da2->bitblt.reg[0x3D] == 0x40) { + da2->bitblt.exec = DA2_BLT_CFILLTILE; + da2->bitblt.destaddr += 2; + da2->bitblt.srcaddr = da2->bitblt.reg[0x2B]; + da2->bitblt.tile_w = da2->bitblt.reg[0x28]; + da2_log("copy tile src=%x, dest=%x, x1=%d, y1=%d, x2=%d, y2=%d, w=%d, h=%d\n", + da2->bitblt.srcaddr, da2->bitblt.destaddr, + da2->bitblt.reg[0x2B] % (da2->rowoffset * 2), da2->bitblt.reg[0x2B] / (da2->rowoffset * 2), + da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), + da2->bitblt.size_x, da2->bitblt.size_y); + } + /* Block copy */ + else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x1040 && da2->bitblt.reg[0x3D] == 0x00) { + da2->bitblt.exec = DA2_BLT_CCOPYF; + da2->bitblt.srcaddr = da2->bitblt.reg[0x2A]; + da2->bitblt.destaddr += 2; + da2_log("copy block src=%x, dest=%x, x1=%d, y1=%d, x2=%d, y2=%d, w=%d, h=%d\n", + da2->bitblt.srcaddr, da2->bitblt.destaddr, + da2->bitblt.reg[0x2A] % (da2->rowoffset * 2), da2->bitblt.reg[0x2A] / (da2->rowoffset * 2), + da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), + da2->bitblt.size_x, da2->bitblt.size_y); + } + /* Block copy but reversed direction */ + else if ((da2->bitblt.reg[0x5] & 0xfff0) == 0x1140 && da2->bitblt.reg[0x3D] == 0x00) { + da2->bitblt.exec = DA2_BLT_CCOPYR; + da2->bitblt.srcaddr = da2->bitblt.reg[0x2A]; + da2->bitblt.destaddr -= 2; + da2->bitblt.srcaddr -= 2; + da2_log("copy blockR src=%x, dest=%x, x1=%d, y1=%d, x2=%d, y2=%d, w=%d, h=%d\n", + da2->bitblt.srcaddr, da2->bitblt.destaddr, + da2->bitblt.reg[0x2A] % (da2->rowoffset * 2), da2->bitblt.reg[0x2A] / (da2->rowoffset * 2), + da2->bitblt.reg[0x29] % (da2->rowoffset * 2), da2->bitblt.reg[0x29] / (da2->rowoffset * 2), + da2->bitblt.size_x, da2->bitblt.size_y); } } static void @@ -888,10 +980,12 @@ da2_bitblt_exec(void *p) { da2_t *da2 = (da2_t *) p; // timer_set_delay_u64(&da2->bitblt.timer, da2->bitblt.timerspeed); -#ifdef ENABLE_DA2_DEBUGBLT - if(!(da2->bitblt.debug_exesteps & 0xff)) +#ifdef ENABLE_DA2_DEBUGBLT_DETAIL + if (!(da2->bitblt.debug_exesteps & 0xff)) da2_log("bitblt_exec: %d %d\n", da2->bitblt.exec, da2->bitblt.debug_exesteps); da2->bitblt.debug_exesteps++; +#else + da2_log("bltload_exec: %x, CS:PC=%4x:%4x\n", da2->bitblt.exec, CS, cpu_state.pc); #endif switch (da2->bitblt.exec) { case DA2_BLT_CIDLE: @@ -899,69 +993,69 @@ da2_bitblt_exec(void *p) break; case DA2_BLT_CLOAD: da2_bitblt_load(da2); - da2->bitblt.indata = 0; + // da2->bitblt.indata = 0; break; case DA2_BLT_CLINE: - /* Draw a dot */ - // outb(0x680, da2->bitblt.octdir); - da2_bltlog("point: %d %d %d %d %d\n", da2->bitblt.x, da2->bitblt.y, da2->bitblt.d, da2->bitblt.x, da2->bitblt.y); - int destaddr = da2->bitblt.y * (da2->rowoffset * 2) + da2->bitblt.x / 8; - int pixelmask = da2->bitblt.x % 16; - if (pixelmask >= 8) - pixelmask = (0x8000 >> (pixelmask - 8)); - else - pixelmask = (0x80 >> pixelmask); - - /* check the current position is inside the window */ - if (da2->bitblt.x < da2->bitblt.wx1 || da2->bitblt.x > da2->bitblt.wx2 - || da2->bitblt.y < da2->bitblt.wy1 || da2->bitblt.y > da2->bitblt.wy2) - ; - else - DA2_DrawColorWithBitmask(destaddr, da2->bitblt.fcolor, pixelmask, da2); - // da2_log("draw: %x %x %x\n", destaddr, da2->bitblt.fcolor, pixelmask); - da2->bitblt.count++; + { + /* Draw a dot */ + da2_bltlog("point: %d %d %d %d %d\n", da2->bitblt.x, da2->bitblt.y, da2->bitblt.d, da2->bitblt.x, da2->bitblt.y); + int destaddr = da2->bitblt.y * (da2->rowoffset * 2) + da2->bitblt.x / 8; + int pixelmask = da2->bitblt.x % 16; + if (pixelmask >= 8) + pixelmask = (0x8000 >> (pixelmask - 8)); + else + pixelmask = (0x80 >> pixelmask); - /* calculate the next position with Bresenham's line algorithm */ - if (da2->bitblt.octdir & 0x04) { /* dX > dY */ - if (da2->bitblt.octdir & 0x02) { - da2->bitblt.x++; - } else { - da2->bitblt.x--; - } - if (da2->bitblt.d >= 0) { - da2->bitblt.d -= (2 * da2->bitblt.size_x); - if (da2->bitblt.octdir & 0x01) { - da2->bitblt.y++; - } else { - da2->bitblt.y--; - } - } - da2->bitblt.d += (2 * da2->bitblt.size_y); - if (da2->bitblt.count >= da2->bitblt.size_x) - da2->bitblt.exec = DA2_BLT_CDONE; - } else { - if (da2->bitblt.octdir & 0x01) { - da2->bitblt.y++; - } else { - da2->bitblt.y--; - } - if (da2->bitblt.d >= 0) { - da2->bitblt.d -= (2 * da2->bitblt.size_y); + /* check the current position is inside the window */ + if (da2->bitblt.x < da2->bitblt.wx1 || da2->bitblt.x > da2->bitblt.wx2 + || da2->bitblt.y < da2->bitblt.wy1 || da2->bitblt.y > da2->bitblt.wy2) + ; + else + da2_DrawColorWithBitmask(destaddr, da2->bitblt.fcolor, pixelmask, da2); + da2->bitblt.count++; + + /* calculate the next position with Bresenham's line algorithm */ + if (da2->bitblt.octdir & 0x04) { /* dX > dY */ if (da2->bitblt.octdir & 0x02) { da2->bitblt.x++; } else { da2->bitblt.x--; } + if (da2->bitblt.d >= 0) { + da2->bitblt.d -= (2 * da2->bitblt.size_x); + if (da2->bitblt.octdir & 0x01) { + da2->bitblt.y++; + } else { + da2->bitblt.y--; + } + } + da2->bitblt.d += (2 * da2->bitblt.size_y); + if (da2->bitblt.count >= da2->bitblt.size_x) + da2->bitblt.exec = DA2_BLT_CDONE; + } else { + if (da2->bitblt.octdir & 0x01) { + da2->bitblt.y++; + } else { + da2->bitblt.y--; + } + if (da2->bitblt.d >= 0) { + da2->bitblt.d -= (2 * da2->bitblt.size_y); + if (da2->bitblt.octdir & 0x02) { + da2->bitblt.x++; + } else { + da2->bitblt.x--; + } + } + da2->bitblt.d += (2 * da2->bitblt.size_x); + if (da2->bitblt.count >= da2->bitblt.size_y) + da2->bitblt.exec = DA2_BLT_CDONE; } - da2->bitblt.d += (2 * da2->bitblt.size_x); - if (da2->bitblt.count >= da2->bitblt.size_y) - da2->bitblt.exec = DA2_BLT_CDONE; + break; } - break; case DA2_BLT_CFILLRECT: // da2_log("%x %x %x\n", da2->bitblt.destaddr, da2->bitblt.x, da2->bitblt.y); if (da2->bitblt.x >= da2->bitblt.size_x - 1) { - DA2_DrawColorWithBitmask(da2->bitblt.destaddr, da2->bitblt.fcolor, da2->bitblt.maskr, da2); + da2_DrawColorWithBitmask(da2->bitblt.destaddr, da2->bitblt.fcolor, da2->bitblt.maskr, da2); if (da2->bitblt.y >= da2->bitblt.size_y - 1) { da2->bitblt.exec = DA2_BLT_CDONE; } @@ -969,36 +1063,38 @@ da2_bitblt_exec(void *p) da2->bitblt.y++; da2->bitblt.destaddr += da2->bitblt.destpitch + 2; } else if (da2->bitblt.x == 0) { - DA2_DrawColorWithBitmask(da2->bitblt.destaddr, da2->bitblt.fcolor, da2->bitblt.maskl, da2); + da2_DrawColorWithBitmask(da2->bitblt.destaddr, da2->bitblt.fcolor, da2->bitblt.maskl, da2); da2->bitblt.x++; } else { - DA2_DrawColorWithBitmask(da2->bitblt.destaddr, da2->bitblt.fcolor, 0xffff, da2); + da2_DrawColorWithBitmask(da2->bitblt.destaddr, da2->bitblt.fcolor, 0xffff, da2); da2->bitblt.x++; } da2->bitblt.destaddr += 2; break; - case DA2_BLT_CFILLTILE: { - int32_t tileaddr = da2->bitblt.srcaddr + (da2->bitblt.y % da2->bitblt.tile_w) * 2; - if (da2->bitblt.x >= da2->bitblt.size_x - 1) { - DA2_CopyPlaneDataWithBitmask(tileaddr, da2->bitblt.destaddr, da2->bitblt.maskr, da2); - if (da2->bitblt.y >= da2->bitblt.size_y - 1) { - da2->bitblt.exec = DA2_BLT_CDONE; + case DA2_BLT_CFILLTILE: + { + int32_t tileaddr = da2->bitblt.srcaddr + (da2->bitblt.y % da2->bitblt.tile_w) * 2; + if (da2->bitblt.x >= da2->bitblt.size_x - 1) { + da2_CopyPlaneDataWithBitmask(tileaddr, da2->bitblt.destaddr, da2->bitblt.maskr, da2); + if (da2->bitblt.y >= da2->bitblt.size_y - 1) { + da2->bitblt.exec = DA2_BLT_CDONE; + } + da2->bitblt.x = 0; + da2->bitblt.y++; + da2->bitblt.destaddr += da2->bitblt.destpitch + 2; + } else if (da2->bitblt.x == 0) { + da2_CopyPlaneDataWithBitmask(tileaddr, da2->bitblt.destaddr, da2->bitblt.maskl, da2); + da2->bitblt.x++; + } else { + da2_CopyPlaneDataWithBitmask(tileaddr, da2->bitblt.destaddr, 0xffff, da2); + da2->bitblt.x++; } - da2->bitblt.x = 0; - da2->bitblt.y++; - da2->bitblt.destaddr += da2->bitblt.destpitch + 2; - } else if (da2->bitblt.x == 0) { - DA2_CopyPlaneDataWithBitmask(tileaddr, da2->bitblt.destaddr, da2->bitblt.maskl, da2); - da2->bitblt.x++; - } else { - DA2_CopyPlaneDataWithBitmask(tileaddr, da2->bitblt.destaddr, 0xffff, da2); - da2->bitblt.x++; + da2->bitblt.destaddr += 2; + break; } - da2->bitblt.destaddr += 2; - break; - } case DA2_BLT_CCOPYF: + case DA2_BLT_CCOPYF: if (da2->bitblt.x >= da2->bitblt.size_x - 1) { - DA2_CopyPlaneDataWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, da2->bitblt.maskr, da2); + da2_CopyPlaneDataWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, da2->bitblt.maskr, da2); if (da2->bitblt.y >= da2->bitblt.size_y - 1) { da2->bitblt.exec = DA2_BLT_CDONE; } @@ -1007,10 +1103,10 @@ da2_bitblt_exec(void *p) da2->bitblt.destaddr += da2->bitblt.destpitch + 2; da2->bitblt.srcaddr += da2->bitblt.srcpitch + 2; } else if (da2->bitblt.x == 0) { - DA2_CopyPlaneDataWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, da2->bitblt.maskl, da2); + da2_CopyPlaneDataWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, da2->bitblt.maskl, da2); da2->bitblt.x++; } else { - DA2_CopyPlaneDataWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, 0xffff, da2); + da2_CopyPlaneDataWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, 0xffff, da2); da2->bitblt.x++; } da2->bitblt.destaddr += 2; @@ -1018,7 +1114,7 @@ da2_bitblt_exec(void *p) break; case DA2_BLT_CCOPYR: if (da2->bitblt.x >= da2->bitblt.size_x - 1) { - DA2_CopyPlaneDataWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, da2->bitblt.maskr, da2); + da2_CopyPlaneDataWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, da2->bitblt.maskr, da2); if (da2->bitblt.y >= da2->bitblt.size_y - 1) { da2->bitblt.exec = DA2_BLT_CDONE; } @@ -1029,64 +1125,37 @@ da2_bitblt_exec(void *p) da2->bitblt.destaddr -= 2; da2->bitblt.srcaddr -= 2; } else if (da2->bitblt.x == 0) { - DA2_CopyPlaneDataWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, da2->bitblt.maskl, da2); + da2_CopyPlaneDataWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, da2->bitblt.maskl, da2); da2->bitblt.x++; } else { - DA2_CopyPlaneDataWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, 0xffff, da2); + da2_CopyPlaneDataWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, 0xffff, da2); da2->bitblt.x++; } da2->bitblt.destaddr -= 2; da2->bitblt.srcaddr -= 2; break; case DA2_BLT_CPUTCHAR: /* used in OS/2 J1.3 wo ROM patch. TODO: still not work */ - // da2->bitblt.y += 2; - da2->bitblt.destaddr = da2->bitblt.reg[0x29] + da2->bitblt.x * 2 + da2->bitblt.y * 130 + 0 + 260; - // pclog("scr %x dest %x :", da2->bitblt.srcaddr, da2->bitblt.destaddr); - // da2->bitblt.srcaddr += 2; - if (da2->bitblt.reg[0x12] < 0x100) - da2->bitblt.srcaddr = DA2_FONTROM_BASESBCS + da2->bitblt.reg[0x12] * 64 + (da2->bitblt.x * 2) + (da2->bitblt.y * 2) - 2; - else - da2->bitblt.srcaddr = da2->bitblt.reg[0x12] * 72 + (da2->bitblt.x * 2) + (da2->bitblt.y * 3) - 2; - // print_bytetobin(da2->mmio.font[da2->bitblt.srcaddr + 2]); - // print_bytetobin(da2->mmio.font[da2->bitblt.srcaddr + 3]); - // pclog("\n"); - if (da2->bitblt.x >= da2->bitblt.size_x - 1) { - // if (1) { - DA2_PutcharWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, da2->bitblt.maskr, da2); - if (da2->bitblt.y >= da2->bitblt.size_y - 3) { - da2->bitblt.exec = DA2_BLT_CDONE; - } - da2->bitblt.x = 0; - da2->bitblt.y++; - da2->bitblt.destaddr += 130; - // da2->bitblt.destaddr += da2->bitblt.destpitch + 2; - // da2->bitblt.srcaddr += -1; - } else if (da2->bitblt.x == 0) { - DA2_PutcharWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, da2->bitblt.maskl, da2); - da2->bitblt.x++; - // da2->bitblt.x++; + // pclog("scr %x dest %x x %x y %x\n", da2->bitblt.srcaddr, da2->bitblt.destaddr, da2->bitblt.x, da2->bitblt.y); + if (da2->bitblt.y >= da2->bitblt.size_y) { + da2->bitblt.exec = DA2_BLT_CDONE; } else { - DA2_PutcharWithBitmask(da2->bitblt.srcaddr, da2->bitblt.destaddr, 0xffff, da2); - da2->bitblt.x++; - // da2->bitblt.x++; + da2_PutcharWithBitmask(da2->bitblt.srcaddr, da2->bitblt.size_x, da2->bitblt.fcolor, da2->bitblt.y, da2->bitblt.destaddr, da2->bitblt.maskl, da2->bitblt.maskr, da2); } - // da2->bitblt.destaddr = da2->bitblt.reg[0x29] + da2->bitblt.x + da2->bitblt.y * 130 + 2; - ////da2->bitblt.srcaddr += 2; - // da2->bitblt.srcaddr = da2->bitblt.reg[0x12] * 72 + (da2->bitblt.x * 2 ) + (da2->bitblt.y * 3) + 2; + da2->bitblt.y++; + da2->bitblt.destaddr += da2->bitblt.size_x * 2 + da2->bitblt.destpitch + 2; break; case DA2_BLT_CDONE: - if (!(da2->bitblt.reg[0x20] & 0x20)) { - /* initialize regs and set magic value for debug dump */ - for (int i = 0; i < DA2_BLT_REGSIZE; i++) { - if (da2->bitblt.reg[i] != DA2_DEBUG_BLT_NEVERUSED) - da2->bitblt.reg[i] = DA2_DEBUG_BLT_USEDRESET; - } - } else /* without init regs */ - da2->bitblt.reg[0x20] = 0; /* need to stop execution */ - if (da2->bitblt.indata) - da2->bitblt.exec = DA2_BLT_CLOAD; - else - da2->bitblt.exec = DA2_BLT_CIDLE; + // if (!(da2->bitblt.reg[0x20] & 0x20)) { + // /* initialize regs and set magic value for debug dump */ + // for (int i = 0; i < DA2_BLT_REGSIZE; i++) { + // if (da2->bitblt.reg[i] != DA2_DEBUG_BLT_NEVERUSED) + // da2->bitblt.reg[i] = DA2_DEBUG_BLT_USEDRESET; + // } + // } else /* without init regs */ + // if (da2->bitblt.indata) + // da2->bitblt.exec = DA2_BLT_CLOAD; + // else + da2->bitblt.exec = DA2_BLT_CIDLE; break; } } @@ -1099,13 +1168,54 @@ da2_bitblt_dopayload(void *priv) if (da2->bitblt.exec != DA2_BLT_CIDLE) { while (da2->bitblt.exec != DA2_BLT_CIDLE) /* this disables async operation */ da2_bitblt_exec(da2); - } else if (da2->bitblt.indata && !(da2->ioctl[LS_MMIO] & 0x10) && (da2->bitblt.exec == DA2_BLT_CIDLE)) { + } else if ((da2->bitblt.reg[0x20] & 0x01) && (da2->bitblt.exec == DA2_BLT_CIDLE)) { da2->bitblt.exec = DA2_BLT_CLOAD; da2_bitblt_exec(da2); } else { // timer_disable(&da2->bitblt.timer); } } +static void +da2_bitblt_addpayload(uint8_t val, void *p) +{ + da2_t *da2 = (da2_t *) p; + da2->bitblt.indata = 1; + if (da2->bitblt.payload_addr >= DA2_BLT_MEMSIZE) + da2_log("da2_mmio_write payload overflow! addr %x, val %x\n", da2->bitblt.payload_addr, val); + else { + if (da2->bitblt.payload_addr == 0) { + da2->bitblt.payload[da2->bitblt.payload_addr] = val; + da2->bitblt.payload_addr++; + switch (val) { + case 0x88: + case 0x89: + case 0x95: + da2->bitblt.payload_opsize = 3; + break; + case 0x91: + da2->bitblt.payload_opsize = 5; + break; + case 0x99: + da2->bitblt.payload_opsize = 7; + break; + case 0xa1: + da2->bitblt.payload_opsize = 9; + break; + default: + da2_log("addpayload: Unknown PreOP! %x\n", val); + da2->bitblt.payload_addr = 0; /* ignore input */ + break; + } + } else if (da2->bitblt.payload_addr < da2->bitblt.payload_opsize) { + da2->bitblt.payload[da2->bitblt.payload_addr] = val; + da2->bitblt.payload_addr++; + } else if (da2->bitblt.payload_addr == da2->bitblt.payload_opsize) { + da2->bitblt.payload[da2->bitblt.payload_addr] = val; + da2->bitblt.payload_opsize = 0; /* reset */ + da2_bitblt_parse(da2); + } + } +} static void da2_out(uint16_t addr, uint16_t val, void *p) @@ -1192,6 +1302,10 @@ da2_out(uint16_t addr, uint16_t val, void *p) da2->fctl[da2->fctladdr] = val; if (da2->fctladdr == 0 && oldval != val) { da2_iolog("DA2 Out FCTL addr %03X idx %02X val %02X %04X:%04X\n", addr, da2->fctladdr, val, cs >> 4, cpu_state.pc); + } else if ((da2->fctladdr == LF_PD_RESET) && ((val & 0x7) == 7)) { + /* Reset Bitblt busy */ + da2->bitblt.indata = 0; + da2->bitblt.exec = DA2_BLT_CIDLE; } break; case LC_INDEX: @@ -1212,12 +1326,6 @@ da2_out(uint16_t addr, uint16_t val, void *p) if (!(da2->ioctl[LS_MODE] & 0x01)) /* 16 or 256 color graphics mode */ val = 0; break; - case LC_START_ADDRESS_HIGH: - case LC_START_ADDRESS_LOW: - /* The DOS J4.0 MODE 4 command and OS/2 driver write 0xFF00. - OS/2 DOS MODE 1 setup reads this to set the base line, but it causes the screen glitch. */ - val = 0; - break; case LC_VERTICAL_TOTALJ: /* Vertical Total */ case LC_VERTICAL_SYNC_START: /* Vertical Retrace Start Register */ case LC_V_DISPLAY_ENABLE_END: /* Vertical Display End Register */ @@ -1226,24 +1334,43 @@ da2_out(uint16_t addr, uint16_t val, void *p) val = 0x400; /* for debugging bitblt in Win 3.x */ #endif break; - case LC_VIEWPORT_SELECT: /* ViewPort Select? */ - // return; - break; - case LC_VIEWPORT_NUMBER: /* Compatibility? */ - break; } da2->crtc[da2->crtcaddr] = val; + switch (da2->crtcaddr) { + // case LC_START_ADDRESS_HIGH: + // case LC_START_ADDRESS_LOW: + /* The DOS J4.0 MODE 4 command and OS/2 driver write 0xFF00. + OS/2 DOS MODE 1 setup reads this to set the base line, but it causes the screen glitch. */ + // outb(0x680, da2->crtc[LC_START_ADDRESS_LOW]); + // outb(0x680, da2->crtc[LC_START_ADDRESS_HIGH]); + // break; + case LC_VIEWPORT_SELECT: + /* backup some current crtc regs */ + for (int i = LC_START_ADDRESS_HIGH; i <= LC_START_ADDRESS_LOW; i++) { + da2->crtc_vpreg[(da2->crtc_vpsel * 0x20) + i] = da2->crtc[i]; + } + da2->crtc_vpsel = (val >> 6) & 3; + /* restore crtc regs */ + for (int i = LC_START_ADDRESS_HIGH; i <= LC_START_ADDRESS_LOW; i++) { + da2->crtc[i] = da2->crtc_vpreg[(da2->crtc_vpsel * 0x20) + i]; + } + break; + default: + break; + } switch (da2->crtcaddr) { case LC_H_DISPLAY_ENABLE_END: case LC_VERTICAL_TOTALJ: case LC_MAXIMUM_SCAN_LINE: - // case LC_START_ADDRESS_HIGH: - // case LC_START_ADDRESS_LOW: + case LC_START_ADDRESS_HIGH: + case LC_START_ADDRESS_LOW: case LC_VERTICAL_SYNC_START: case LC_V_DISPLAY_ENABLE_END: case LC_START_VERTICAL_BLANK: + case LC_LINE_COMPAREJ: case LC_START_H_DISPLAY_ENAB: case LC_START_V_DISPLAY_ENAB: + case LC_VIEWPORT_SELECT: case LC_VIEWPORT_PRIORITY: da2->fullchange = changeframecount; da2_recalctimings(da2); @@ -1255,7 +1382,6 @@ da2_out(uint16_t addr, uint16_t val, void *p) case LV_PORT: // da2_iolog("DA2 Out addr %03X val %02X ff %d %04X:%04X\n", addr, val, da2->attrff,cs >> 4, cpu_state.pc); if (!da2->attrff) { - // da2->attraddr = val & 31; da2->attraddr = val & 0x3f; if ((val & 0x20) != (da2->attr_palette_enable & 0x20)) { da2->fullchange = 3; @@ -1423,15 +1549,9 @@ da2_in(uint16_t addr, void *p) // if (da2->bitblt.indata) /* for OS/2 J1.3 command prompt scrolling */ // da2_bitblt_dopayload(da2); if (da2->bitblt.exec != DA2_BLT_CIDLE) { - // da2_iolog("exec:%x\n", da2->bitblt.exec); - temp |= 0x01; /* wait (bit 3 + bit 0) ? need verify */ - // if (!da2->bitblt.timer.enabled) - //{ - // da2_iolog("bitblt timer restarted!! %04X:%04X\n", cs >> 4, cpu_state.pc); - // timer_advance_u64(&da2->bitblt.timer, da2->bitblt.timerspeed); - // } + temp |= 0x09; /* wait (bit 3 + bit 0) ? need verify */ } - if (da2->bitblt.indata) temp |= 0x08; + // if (da2->bitblt.indata) temp |= 0x08; #ifdef ENABLE_DA2_DEBUGMONWAIT da2_iolog("DA2 In %04X(%02X) %04X %04X:%04X\n", addr, da2->ioctladdr, temp, cs >> 4, cpu_state.pc); #endif @@ -1463,6 +1583,10 @@ da2_in(uint16_t addr, void *p) da2->cgastat &= ~0x30; else da2->cgastat ^= 0x30; /* toggle */ + if (da2->cgastat & 0x08) + da2->cgastat &= ~0x08; + else + da2->cgastat ^= 0x08; /* toggle */ temp = da2->cgastat; } else temp = da2->attrc[da2->attraddr]; @@ -1495,7 +1619,7 @@ static void da2_outb(uint16_t addr, uint8_t val, void *p) { da2_t *da2 = (da2_t *) p; - // da2_iolog("DA2 Outb addr %03X val %02X %04X:%04X es:di=%x:%x ds:si=%x:%x\n", addr, val, cs >> 4, cpu_state.pc, ES, DI, DS, SI); + da2_iolog("DA2 Outb addr %03X val %02X %04X:%04X es:di=%x:%x ds:si=%x:%x\n", addr, val, cs >> 4, cpu_state.pc, ES, DI, DS, SI); da2->inflipflop = 0; switch (addr) { case LS_DATA: @@ -1546,9 +1670,6 @@ da2_outw(uint16_t addr, uint16_t val, void *p) break; case 0x3EC: // da2_iolog("DA2 Outw addr %03X val %04X %04X:%04X\n", addr, val, cs >> 4, cpu_state.pc); - da2_iolog(" "); - // val = rightRotate(val, 8); - // da2_out(LG_DATA, val, da2); da2_out(LG_DATA, val >> 8, da2); /* reset masks for compatibility with Win 3.1 solitaire */ if (da2->gdcaddr == LG_MODE) { @@ -1976,9 +2097,9 @@ da2_render_textm3(da2_t *da2) int chr_wide = 0; // da2_log("\nda2ma: %x, da2sc: %x\n", da2->ma, da2->sc); for (x = 0; x < da2->hdisp; x += 13) { - chr = DA2_vram_r(DA2_VM03_BASECHR + da2->ma, da2); - attr = DA2_vram_r(DA2_VM03_BASECHR + da2->ma + 1, da2); - extattr = DA2_vram_r(DA2_VM03_BASEEXATTR + da2->ma + 1, da2); + chr = da2_vram_r(DA2_VM03_BASECHR + da2->ma, da2); + attr = da2_vram_r(DA2_VM03_BASECHR + da2->ma + 1, da2); + extattr = da2_vram_r(DA2_VM03_BASEEXATTR + da2->ma + 1, da2); // if(chr!=0x20) da2_log("addr: %x, chr: %x, attr: %x ", (DA2_VM03_BASECHR + da2->ma << 1) & da2->vram_mask, chr, attr); bg = attr >> 4; // if (da2->blink) bg &= ~0x8; @@ -1996,7 +2117,7 @@ da2_render_textm3(da2_t *da2) /* Stay drawing if the char code is DBCS and not at last column. */ if (chr_wide) { /* Get high DBCS code from the next video address */ - chr_dbcs = DA2_vram_r(DA2_VM03_BASECHR + da2->ma + 2, da2); + chr_dbcs = da2_vram_r(DA2_VM03_BASECHR + da2->ma + 2, da2); chr_dbcs <<= 8; chr_dbcs |= chr; /* Get the font pattern */ @@ -2194,17 +2315,11 @@ da2_recalctimings(da2_t *da2) double crtcconst; double _dispontime, _dispofftime, disptime; - /* if output disabled or VGA passthrough */ - if (da2->ioctl[LS_MODE] & 0x02 || !(da2->attrc[LV_COMPATIBILITY] & 0x08)) { - da2->render = da2_render_blank; - return; - } - da2->vtotal = da2->crtc[LC_VERTICAL_TOTALJ] & 0xfff; da2->dispend = da2->crtc[LC_V_DISPLAY_ENABLE_END] & 0xfff; da2->vsyncstart = da2->crtc[LC_VERTICAL_SYNC_START] & 0xfff; da2->split = da2->crtc[LC_LINE_COMPAREJ] & 0xfff; - da2->split = 0xfff; + da2->split -= 1; da2->vblankstart = da2->crtc[LC_START_VERTICAL_BLANK] & 0xfff; da2->hdisp = da2->crtc[LC_H_DISPLAY_ENABLE_END]; @@ -2220,21 +2335,29 @@ da2_recalctimings(da2_t *da2) da2->clock = da2->da2const; - // da2->lowres = da2->attrc[LV_MODE_CONTROL] & 0x40; + if (da2->vtotal == 0) + da2->vtotal = da2->vsyncstart = da2->vblankstart = 256; + if (da2->htotal == 0) + da2->htotal = da2->dispend = da2->hdisp = 64; + if (da2->rowoffset == 0) + da2->rowoffset = 64 * 2; /* To avoid causing a DBZ error */ + if (da2->split == 0) /* To avoid a glitch in MODE 1 of OS/2 J1.3 DOSBox. */ + da2->ma_latch = 0; + else + da2->ma_latch = ((da2->crtc[LC_START_ADDRESS_HIGH] & 0x3ff) << 8) | da2->crtc[LC_START_ADDRESS_LOW]; - // da2->interlace = 0; - - // da2->ma_latch = ((da2->crtc[LC_START_ADDRESS_HIGH] & 0x3ff) << 8) | da2->crtc[LC_START_ADDRESS_LOW];//w + b da2->ca_adj = 0; - da2->rowcount = da2->crtc[LC_MAXIMUM_SCAN_LINE]; - da2->hdisp_time = da2->hdisp; da2->render = da2_render_blank; /* determine display mode */ // if (da2->attr_palette_enable && (da2->attrc[0x1f] & 0x08)) + /* if output disabled or VGA passthrough */ + if (da2->ioctl[LS_MODE] & 0x02 || !(da2->attrc[LV_COMPATIBILITY] & 0x08)) { + da2->render = da2_render_blank; + // return; /* 16 color graphics mode */ - if (!(da2->ioctl[LS_MODE] & 0x01)) { + } else if (!(da2->ioctl[LS_MODE] & 0x01)) { da2->hdisp *= 16; da2->char_width = 13; if (da2->crtc[LC_VIEWPORT_PRIORITY] & 0x80) { @@ -2260,15 +2383,6 @@ da2_recalctimings(da2_t *da2) da2->hdisp *= 13; da2->char_width = 13; } - // if (!da2->scrblank && da2->attr_palette_enable) - //{ - // da2->render = da2_draw_text; - //} - - // da2_log("da2_render %08X : %08X %08X %08X %08X %08X %i %i %02X %i %i\n", da2_render, da2_render_text_40, da2_render_text_80, da2_render_8bpp_lowres, da2_render_8bpp_highres, da2_render_blank, scrblank,gdcreg[6]&1,gdcreg[5]&0x60,bpp,seqregs[1]&8); - - // if (da2->recalctimings_ex) - // da2->recalctimings_ex(da2); if (da2->vblankstart < da2->dispend) da2->dispend = da2->vblankstart; @@ -2279,7 +2393,7 @@ da2_recalctimings(da2_t *da2) _dispontime = da2->hdisp_time; da2_log("Disptime %f dispontime %f hdisp %i\n", disptime, _dispontime, da2->hdisp); - // if (da2->seqregs[1] & 8) { disptime *= 2; _dispontime *= 2; } + _dispofftime = disptime - _dispontime; _dispontime *= crtcconst; _dispofftime *= crtcconst; @@ -2293,7 +2407,7 @@ da2_recalctimings(da2_t *da2) da2_log("da2 horiz total %i display end %i vidclock %f\n", da2->crtc[0], da2->crtc[1], da2->clock); da2_log("da2 vert total %i display end %i max row %i vsync %i\n",da2->vtotal,da2->dispend,(da2->crtc[9]&31)+1,da2->vsyncstart); da2_log("da2 dispon %lu dispoff %lu on(us) %f off(us) %f\n",da2->dispontime, da2->dispofftime, (double)da2->dispontime / (double)cpuclock / (double) (1ULL << 32) * 1000000.0, (double)da2->dispofftime / (double)cpuclock / (double) (1ULL << 32) * 1000000.0); - // da2_log("da2->render %08X\n", da2->render); + da2_log("da2 linecompare %d\n", da2->split); } static void @@ -2374,19 +2488,19 @@ da2_gdcropB(uint32_t addr,uint8_t bitmask, da2_t *da2) case 0: /*Set*/ // da2->vram[addr | i] = (da2->gdcinput[i] & bitmask) | (da2->gdcsrc[i] & ~bitmask); // da2->vram[addr | i] = (da2->gdcinput[i] & bitmask) | (da2->vram[addr | i] & ~bitmask); - DA2_vram_w(addr | i, (da2->gdcinput[i] & bitmask) | (da2->vram[addr | i] & ~bitmask), da2); + da2_vram_w(addr | i, (da2->gdcinput[i] & bitmask) | (da2->vram[addr | i] & ~bitmask), da2); break; case 1: /*AND*/ // da2->vram[addr | i] = (da2->gdcinput[i] | ~bitmask) & da2->gdcsrc[i]; - DA2_vram_w(addr | i, ((da2->gdcinput[i] & da2->gdcsrc[i]) & bitmask) | (da2->vram[addr | i] & ~bitmask), da2); + da2_vram_w(addr | i, ((da2->gdcinput[i] & da2->gdcsrc[i]) & bitmask) | (da2->vram[addr | i] & ~bitmask), da2); break; case 2: /*OR*/ // da2->vram[addr | i] = (da2->gdcinput[i] & bitmask) | da2->gdcsrc[i]; - DA2_vram_w(addr | i, ((da2->gdcinput[i] | da2->gdcsrc[i]) & bitmask) | (da2->vram[addr | i] & ~bitmask), da2); + da2_vram_w(addr | i, ((da2->gdcinput[i] | da2->gdcsrc[i]) & bitmask) | (da2->vram[addr | i] & ~bitmask), da2); break; case 3: /*XOR*/ // da2->vram[addr | i] = (da2->gdcinput[i] & bitmask) ^ da2->gdcsrc[i]; - DA2_vram_w(addr | i, ((da2->gdcinput[i] ^ da2->gdcsrc[i]) & bitmask) | (da2->vram[addr | i] & ~bitmask), da2); + da2_vram_w(addr | i, ((da2->gdcinput[i] ^ da2->gdcsrc[i]) & bitmask) | (da2->vram[addr | i] & ~bitmask), da2); break; } } @@ -2396,8 +2510,8 @@ da2_gdcropB(uint32_t addr,uint8_t bitmask, da2_t *da2) static void da2_gdcropW(uint32_t addr, uint16_t bitmask, da2_t *da2) { - if((addr & 8) && !(da2->gdcreg[LG_COMMAND] & 0x08)) bitmask = rightRotate(bitmask, 8); - // if((addr & 8)) bitmask = rightRotate(bitmask, 8); + if((addr & 8) && !(da2->gdcreg[LG_COMMAND] & 0x08)) bitmask = da2_rightrotate(bitmask, 8); + // if((addr & 8)) bitmask = da2_rightrotate(bitmask, 8); uint8_t bitmask_l = bitmask & 0xff; uint8_t bitmask_h = bitmask >> 8; for (int i = 0; i < 8; i++) { @@ -2407,29 +2521,29 @@ da2_gdcropW(uint32_t addr, uint16_t bitmask, da2_t *da2) case 0: /*Set*/ // da2->vram[addr | i] = (da2->gdcinput[i] & bitmask_l) | (da2->gdcsrc[i] & ~bitmask_l); // da2->vram[(addr + 8) | i] = ((da2->gdcinput[i] >> 8) & bitmask_h) | ((da2->gdcsrc[i] >> 8) & ~bitmask_h); - DA2_vram_w(addr | i, (da2->gdcinput[i] & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l), da2); - DA2_vram_w((addr + 8) | i, ((da2->gdcinput[i] >> 8) & bitmask_h) + da2_vram_w(addr | i, (da2->gdcinput[i] & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l), da2); + da2_vram_w((addr + 8) | i, ((da2->gdcinput[i] >> 8) & bitmask_h) | (da2->vram[(addr + 8) | i] & ~bitmask_h), da2); break; case 1: /*AND*/ // da2->vram[addr | i] = (da2->gdcinput[i] | ~bitmask_l) & da2->gdcsrc[i]; // da2->vram[(addr + 8) | i] = ((da2->gdcinput[i] >> 8) | ~bitmask_h) & (da2->gdcsrc[i] >> 8); - DA2_vram_w(addr | i, ((da2->gdcinput[i] & da2->gdcsrc[i]) & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l), da2); - DA2_vram_w((addr + 8) | i, (((da2->gdcinput[i] >> 8) & (da2->gdcsrc[i] >> 8)) & bitmask_h) + da2_vram_w(addr | i, ((da2->gdcinput[i] & da2->gdcsrc[i]) & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l), da2); + da2_vram_w((addr + 8) | i, (((da2->gdcinput[i] >> 8) & (da2->gdcsrc[i] >> 8)) & bitmask_h) | (da2->vram[(addr + 8) | i] & ~bitmask_h), da2); break; case 2: /*OR*/ // da2->vram[addr | i] = (da2->gdcinput[i] & bitmask_l) | da2->gdcsrc[i]; // da2->vram[(addr + 8) | i] = ((da2->gdcinput[i] >> 8) & bitmask_h) | (da2->gdcsrc[i] >> 8); - DA2_vram_w(addr | i, ((da2->gdcinput[i] | da2->gdcsrc[i]) & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l), da2); - DA2_vram_w((addr + 8) | i, (((da2->gdcinput[i] >> 8) | (da2->gdcsrc[i] >> 8)) & bitmask_h) + da2_vram_w(addr | i, ((da2->gdcinput[i] | da2->gdcsrc[i]) & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l), da2); + da2_vram_w((addr + 8) | i, (((da2->gdcinput[i] >> 8) | (da2->gdcsrc[i] >> 8)) & bitmask_h) | (da2->vram[(addr + 8) | i] & ~bitmask_h), da2); break; case 3: /*XOR*/ // da2->vram[addr | i] = (da2->gdcinput[i] & bitmask_l) ^ da2->gdcsrc[i]; // da2->vram[(addr + 8) | i] = ((da2->gdcinput[i] >> 8) & bitmask_h) ^ (da2->gdcsrc[i] >> 8); - DA2_vram_w(addr | i, ((da2->gdcinput[i] ^ da2->gdcsrc[i]) & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l), da2); - DA2_vram_w((addr + 8) | i, (((da2->gdcinput[i] >> 8) ^ (da2->gdcsrc[i] >> 8)) & bitmask_h) + da2_vram_w(addr | i, ((da2->gdcinput[i] ^ da2->gdcsrc[i]) & bitmask_l) | (da2->vram[addr | i] & ~bitmask_l), da2); + da2_vram_w((addr + 8) | i, (((da2->gdcinput[i] >> 8) ^ (da2->gdcsrc[i] >> 8)) & bitmask_h) | (da2->vram[(addr + 8) | i] & ~bitmask_h), da2); break; } @@ -2441,6 +2555,7 @@ static uint8_t da2_mmio_read(uint32_t addr, void *p) { da2_t *da2 = (da2_t *) p; + uint32_t index = 0; addr &= DA2_MASK_MMIO; if (da2->ioctl[LS_MMIO] & 0x10) { if (da2->fctl[LF_MMIO_SEL] == 0x80) @@ -2448,14 +2563,14 @@ da2_mmio_read(uint32_t addr, void *p) addr |= ((uint32_t) da2->fctl[LF_MMIO_ADDR] << 17); else { /* 64k bank switch access */ - uint32_t index = da2->fctl[LF_MMIO_MODE] & 0x0f; + index = da2->fctl[LF_MMIO_MODE] & 0x0f; index <<= 8; index |= da2->fctl[LF_MMIO_ADDR]; - addr += index * 0x40; } // da2_log("PS55_MemHnd: Read from mem %x, bank %x, addr %x\n", da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr); switch (da2->fctl[LF_MMIO_MODE] & 0xf0) { case 0xb0: /* Gaiji RAM */ + addr += index * 0x80; addr &= DA2_MASK_GAIJIRAM; /* safety access */ // da2_log("PS55_MemHnd_G: Read from mem %x, bank %x, chr %x (%x), val %x\n", da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr / 128, addr, da2->mmio.font[addr]); return da2->mmio.ram[addr]; @@ -2473,7 +2588,13 @@ da2_mmio_read(uint32_t addr, void *p) // da2_log("PS55_MemHnd: Read from mem %x, bank %x, chr %x (%x), val %x\n", da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr / 72, addr, da2->mmio.font[addr]); return da2->mmio.font[addr]; break; + case 0x00: /* SBCS in Gaiji RAM (used in the downward writing mode of DOS/V Extension) */ + addr += DA2_GAIJIRAM_SBCS + index * 0x40; + addr &= DA2_MASK_GAIJIRAM; + return da2->mmio.ram[addr]; + break; default: + da2_log("PS55_MemHnd: Invalid read mem %x, bank %x, chr %x (%x), val %x\n", da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr / 72, addr, da2->mmio.font[addr]); return DA2_INVALIDACCESS8; /* invalid memory access */ break; } @@ -2548,52 +2669,46 @@ da2_mmio_readw(uint32_t addr, void *p) return (uint16_t) da2_mmio_read(addr, da2) | (uint16_t) (da2_mmio_read(addr + 1, da2) << 8); } } - static void da2_mmio_write(uint32_t addr, uint8_t val, void *p) { da2_t *da2 = (da2_t *) p; + uint32_t index = 0; // da2_log("da2_mmio_write %x %x\n", addr, val); // if ((addr & ~DA2_MASK_MMIO) != 0xA0000) // return; addr &= DA2_MASK_MMIO; - if (da2->ioctl[LS_MMIO] & 0x10) { + if (da2->ioctl[LS_MMIO] == 0x1f) {/* write bitblt fifo data */ + da2_bitblt_addpayload(val, da2); + } + else if (da2->ioctl[LS_MMIO] & 0x10) { /* access to gaiji ram */ // if(da2->ioctl[LS_MMIO] == 0x1f) da2_log("mw mem %x, addr %x, val %x, ESDI %x:%x DSSI %x:%x\n", da2->fctl[LF_MMIO_MODE], addr, val, ES, DI, DS, SI); /* Gaiji RAM */ if (da2->fctl[LF_MMIO_SEL] == 0x80) addr |= ((uint32_t) da2->fctl[LF_MMIO_ADDR] << 17); /* xxxy yyyy yyyy yyyy yyyy */ - else { - uint32_t index = da2->fctl[LF_MMIO_MODE] & 0x0f; + else { + index = da2->fctl[LF_MMIO_MODE] & 0x0f; index <<= 8; index |= da2->fctl[LF_MMIO_ADDR]; - addr += index * 0x40; + // da2_log("da2_mmio_w io %x, sl %x, 09 %x, ad %x, mm %x, addr %x, val %x\n", da2->ioctl[LS_MMIO],da2->fctl[LF_MMIO_SEL], + // da2->fctl[LF_MMIO_09],da2->fctl[LF_MMIO_ADDR], da2->fctl[LF_MMIO_MODE], addr, val); } - switch (da2->fctl[LF_MMIO_MODE]) { - case 0xb0: /* Gaiji RAM 1011 0000 */ + switch (da2->fctl[LF_MMIO_MODE] & 0xf0) { + case 0xb0: /* Gaiji RAM 1011 0000 */ + addr += index * 0x80; da2->mmio.ram[addr & DA2_MASK_GAIJIRAM] = val; break; case 0x10: /* Font ROM 0001 0000 */ /* Read-Only */ break; - case 0x00: + case 0x00: /* SBCS in Gaiji RAM (used by DOS/V Extension DSPXDA2 driver) */ + addr += index * 0x40; + da2->mmio.ram[(DA2_GAIJIRAM_SBCS + addr) & DA2_MASK_GAIJIRAM] = val; // da2_log("da2_mmio_write %x %x %04X:%04X\n", addr, val, CS, cpu_state.pc); - // addr &= 0x7f;/* OS/2 write addr 1cf80-1cfc3, val xx */ - // if (addr >= DA2_BLT_MEMSIZE) - //{ - // da2_log("da2_mmio_write failed mem %x, addr %x, val %x\n", da2->fctl[LF_MMIO_MODE], addr, val); - // return; - // } - da2->bitblt.indata = 1; - if (da2->bitblt.payload_addr >= DA2_BLT_MEMSIZE) - da2_log("da2_mmio_write payload overflow! mem %x, addr %x, val %x\n", da2->fctl[LF_MMIO_MODE], addr, val); - else { - da2->bitblt.payload[da2->bitblt.payload_addr] = val; - da2->bitblt.payload_addr++; - } break; default: - da2_log("da2_mmio_write failed mem %x, addr %x, val %x\n", da2->fctl[LF_MMIO_MODE], addr, val); + da2_log("da2_mmio_write failed io %x, mm %x, addr %x, val %x\n", da2->ioctl[LS_MMIO] ,da2->fctl[LF_MMIO_MODE], addr, val); break; } } else if (!(da2->ioctl[LS_MODE] & 1)) { /* 16 color or 256 color mode */ @@ -2654,7 +2769,7 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) case 2: /* equiv to vga write mode 1 */ for (int i = 0; i < 8; i++) if (da2->planemask & (1 << i)) - DA2_vram_w(addr | i, da2->gdcsrc[i], da2); + da2_vram_w(addr | i, da2->gdcsrc[i], da2); break; case 0:/* equiv to vga write mode 0 */ if (da2->gdcreg[LG_DATA_ROTATION] & 7) @@ -2662,7 +2777,7 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) if (bitmask == 0xff && !(da2->gdcreg[LG_COMMAND] & 0x03) && (!da2->gdcreg[LG_ENABLE_SRJ])) { for (int i = 0; i < 8; i++) if (da2->planemask & (1 << i)) - DA2_vram_w(addr | i, val, da2); + da2_vram_w(addr | i, val, da2); } else { for (int i = 0; i < 8; i++) if (da2->gdcreg[LG_ENABLE_SRJ] & (1 << i)) @@ -2689,12 +2804,12 @@ da2_mmio_write(uint32_t addr, uint8_t val, void *p) } } else { /* mode 3h text */ cycles -= video_timing_write_b; - DA2_vram_w(addr, val, da2); + da2_vram_w(addr, val, da2); da2->fullchange = 2; } } static uint16_t -rightRotate(uint16_t data, uint8_t count) +da2_rightrotate(uint16_t data, uint8_t count) { return (data >> count) | (data << (sizeof(data) * 8 - count)); } @@ -2752,18 +2867,18 @@ da2_mmio_gc_writeW(uint32_t addr, uint16_t val, void *p) case 2: for (int i = 0; i < 8; i++) if (da2->planemask & (1 << i)) { - DA2_vram_w(addr | i, da2->gdcsrc[i] & 0xff, da2); - DA2_vram_w((addr + 8) | i, da2->gdcsrc[i] >> 8, da2); + da2_vram_w(addr | i, da2->gdcsrc[i] & 0xff, da2); + da2_vram_w((addr + 8) | i, da2->gdcsrc[i] >> 8, da2); } break; case 0: if (da2->gdcreg[LG_DATA_ROTATION] & 15) - val = rightRotate(val, da2->gdcreg[LG_DATA_ROTATION] & 15); + val = da2_rightrotate(val, da2->gdcreg[LG_DATA_ROTATION] & 15); if (bitmask == 0xffff && !(da2->gdcreg[LG_COMMAND] & 0x03) && (!da2->gdcreg[LG_ENABLE_SRJ])) { for (int i = 0; i < 8; i++) if (da2->planemask & (1 << i)) { - DA2_vram_w(addr | i, val & 0xff, da2); - DA2_vram_w((addr + 8) | i, val >> 8, da2); + da2_vram_w(addr | i, val & 0xff, da2); + da2_vram_w((addr + 8) | i, val >> 8, da2); } } else { for (int i = 0; i < 8; i++) @@ -2782,7 +2897,7 @@ da2_mmio_gc_writeW(uint32_t addr, uint16_t val, void *p) break; case 3: if (da2->gdcreg[LG_DATA_ROTATION] & 15) - val = rightRotate(val, da2->gdcreg[LG_DATA_ROTATION] & 15); + val = da2_rightrotate(val, da2->gdcreg[LG_DATA_ROTATION] & 15); bitmask &= val; for (int i = 0; i < 8; i++) @@ -2801,15 +2916,21 @@ da2_mmio_writew(uint32_t addr, uint16_t val, void *p) // return; // if ((addr & ~0x1ffff) != 0xA0000) return; if (da2->ioctl[LS_MMIO] & 0x10) { - // da2_log("da2_mmio_writeW %x %x %x %x %x %x\n", da2->ioctl[LS_MMIO], da2->fctl[LF_MMIO_SEL], da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr, val); +#ifdef ENABLE_DA2_DEBUGVRAM + da2_log("da2_mmio_writeW %x %x %x %x %x %x\n", da2->ioctl[LS_MMIO], da2->fctl[LF_MMIO_SEL], da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr, val); +#endif da2_mmio_write(addr, val & 0xff, da2); da2_mmio_write(addr + 1, val >> 8, da2); } else if (!(da2->ioctl[LS_MODE] & 1)) { /* 16 color or 256 color mode */ - // da2_log("da2_mmio_writeGW %x %x %x %x %x %x\n", da2->ioctl[LS_MMIO], da2->fctl[LF_MMIO_SEL], da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr, val); +#ifdef ENABLE_DA2_DEBUGVRAM + da2_log("da2_mmio_writeGW %x %x %x %x %x %x\n", da2->ioctl[LS_MMIO], da2->fctl[LF_MMIO_SEL], da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr, val); +#endif da2_mmio_gc_writeW(addr, val, da2); } else { /* mode 3h text */ +#ifdef ENABLE_DA2_DEBUGVRAM // if (addr & 0xff00 == 0) da2_log("da2_mmio_write %x %x %04X:%04X\n", addr, val, CS, cpu_state.pc); - // da2_log("da2_mmio_writeGW %x %x %x %x %x %x\n", da2->ioctl[LS_MMIO], da2->fctl[LF_MMIO_SEL], da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr, val); + da2_log("da2_mmio_write3W %x %x %x %x %x %x\n", da2->ioctl[LS_MMIO], da2->fctl[LF_MMIO_SEL], da2->fctl[LF_MMIO_MODE], da2->fctl[LF_MMIO_ADDR], addr, val); +#endif da2_mmio_write(addr, val & 0xff, da2); da2_mmio_write(addr + 1, val >> 8, da2); } @@ -2835,7 +2956,7 @@ da2_code_writeb(uint32_t addr, uint8_t val, void *p) static void da2_code_writew(uint32_t addr, uint16_t val, void *p) { - // da2_log("DA2_code_writew: Write to %x, val %x\n", addr, val); + // da2_log("DA2_code_writ ew: Write to %x, val %x\n", addr, val); da2_t *da2 = (da2_t *) p; cycles -= video_timing_write_w; da2_code_write(addr, val & 0xff, da2); @@ -2915,8 +3036,6 @@ da2_poll(void *priv) // da2_log("%03i %06X %06X\n", da2->displine, da2->ma,da2->vram_display_mask); da2->displine++; - // if (da2->interlace) - // da2->displine++; if ((da2->cgastat & 8) && ((da2->displine & 0xf) == (da2->crtc[LC_VERTICAL_SYNC_END] & 0xf)) && da2->vslines) { // da2_log("Vsync off at line %i\n",displine); da2->cgastat &= ~8; @@ -2930,7 +3049,6 @@ da2_poll(void *priv) // da2_log("VC %i ma %05X\n", da2->vc, da2->ma); timer_advance_u64(&da2->timer, da2->dispontime); - // if (output) printf("Display on %f\n",vidtime); if (da2->dispon) da2->cgastat &= ~1; da2->hdisp_on = 0; @@ -2944,8 +3062,6 @@ da2_poll(void *priv) da2->sc = 0; da2->maback += (da2->rowoffset << 1); /* color = 0x50(80), mono = 0x40(64) */ - if (da2->interlace) - da2->maback += (da2->rowoffset << 1); da2->maback &= da2->vram_display_mask; da2->ma = da2->maback; } else { @@ -2958,6 +3074,13 @@ da2_poll(void *priv) da2->vc++; da2->vc &= 2047; + if (da2->vc == da2->split) { + // da2->ma = da2->maback = da2->hblank_sub; + da2->ma = da2->maback = 0; + da2->sc = 0; + // da2->displine = 0; + } + if (da2->vc == da2->dispend) { da2->dispon = 0; // if (da2->crtc[10] & 0x20) da2->cursoron = 0; @@ -3001,13 +3124,11 @@ da2_poll(void *priv) da2->firstline_draw = 2000; da2->lastline_draw = 0; - da2->oddeven ^= 1; - - changeframecount = da2->interlace ? 3 : 2; + changeframecount = 2; da2->vslines = 0; da2->ma - = da2->maback = da2->ma_latch; + = da2->maback = da2->ma_latch << 1; da2->ca = ((da2->crtc[LC_CURSOR_LOC_HIGH] << 8) | da2->crtc[LC_CURSOR_LOC_LOWJ]) + da2->ca_adj; da2->ca <<= 1; @@ -3019,7 +3140,7 @@ da2_poll(void *priv) da2->vc = 0; da2->sc = da2->crtc[LC_PRESET_ROW_SCANJ] & 0x1f; da2->dispon = 1; - da2->displine = (da2->interlace && da2->oddeven) ? 1 : 0; + da2->displine = 0; da2->scrollcache = da2->attrc[LV_PANNING] & 7; } if (da2->sc == (da2->crtc[LC_CURSOR_ROW_START] & 31)) @@ -3110,7 +3231,6 @@ da2_reset(void *priv) da2->crtc[LC_HORIZONTAL_TOTAL] = 63; /* Horizontal Total */ da2->crtc[LC_VERTICAL_TOTALJ] = 255; /* Vertical Total (These two must be set before the timer starts.) */ da2->ma_latch = 0; - da2->interlace = 0; da2->attrc[LV_CURSOR_CONTROL] = 0x13; /* cursor options */ da2->attr_palette_enable = 0; /* disable attribute generator */ @@ -3242,8 +3362,18 @@ da2_close(void *p) fprintf(f, "3eb(gcr) %02X: %4X\n", i, da2->gdcreg[i]); for (int i = 0; i < 0x10; i++) fprintf(f, "3ee(?) %02X: %4X\n", i, da2->reg3ee[i]); + for (int i = 0; i < 0x20; i++) { + fprintf(f, "vp %02X: %4X %4X %4X %4X\n", i, + da2->crtc_vpreg[0 + i], da2->crtc_vpreg[0x20 + i], da2->crtc_vpreg[0x40 + i], da2->crtc_vpreg[0x60 + i]); + } fclose(f); } + f = fopen("ram_low.dmp", "wb"); + if (f != NULL) { + fwrite(&ram[0x0], 0x100000, 1, f); + fclose(f); + } + pclog("closed %04X:%04X DS %04X\n", cs >> 4, cpu_state.pc, DS); #endif #ifdef ENABLE_DA2_DEBUGBLT f = fopen("da2_bltdump.csv", "w"); @@ -3261,8 +3391,16 @@ da2_close(void *p) ; else if (da2->bitblt.debug_reg[x * DA2_DEBUG_BLTLOG_SIZE + y] == DA2_DEBUG_BLT_USEDRESET) fprintf(f, "\"\"\t"); - else + else { fprintf(f, "\"%X\"\t", da2->bitblt.debug_reg[x * DA2_DEBUG_BLTLOG_SIZE + y]); + if (y == 0x12) { + int chr = da2->bitblt.debug_reg[x * DA2_DEBUG_BLTLOG_SIZE + 0x12]; + if ((chr >= 0x20) && (chr < 0x7f)) + fprintf(f, "\"%c\"\t", chr); + else + fprintf(f, "\"\"\t"); + } + } } fprintf(f, "\n"); }