From 49723d04946c7ba5a2eabc59aeefef95490a7997 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Nov 2019 23:17:37 +0100 Subject: [PATCH 01/26] Changes to the DirectDraw and Direct3D renderers. --- src/win/win_d3d.cpp | 302 +++++++----------------------------------- src/win/win_ddraw.cpp | 147 +++++++------------- 2 files changed, 95 insertions(+), 354 deletions(-) diff --git a/src/win/win_d3d.cpp b/src/win/win_d3d.cpp index 974b17341..cb5942ab7 100644 --- a/src/win/win_d3d.cpp +++ b/src/win/win_d3d.cpp @@ -8,7 +8,7 @@ * * Rendering module for Microsoft Direct3D 9. * - * Version: @(#)win_d3d.cpp 1.0.13 2019/10/12 + * Version: @(#)win_d3d.cpp 1.0.14 2019/11/01 * * Authors: Sarah Walker, * Miran Grca, @@ -43,8 +43,8 @@ static LPDIRECT3DTEXTURE9 d3dTexture = NULL; static D3DPRESENT_PARAMETERS d3dpp; static HWND d3d_hwnd; static HWND d3d_device_window; -static int d3d_w, - d3d_h; +static int d3d_w, d3d_h; +static int d3d_fs; static volatile int d3d_enabled = 0; static CUSTOMVERTEX d3d_verts[] = { @@ -143,17 +143,15 @@ d3d_size(RECT w_rect, double *l, double *t, double *r, double *b, int w, int h) static void -d3d_blit_fs(int x, int y, int y1, int y2, int w, int h) +d3d_blit(int x, int y, int y1, int y2, int w, int h) { -#if 0 HRESULT hr = D3D_OK; HRESULT hbsr = D3D_OK; VOID* pVoid; D3DLOCKED_RECT dr; - RECT w_rect; + RECT r; int yy; - double l = 0, t = 0, r = 0, b = 0; - RECT lock_rect; + double l = 0, t = 0, rr = 0, b = 0; /* FS_ONLY */ if (!d3d_enabled) { video_blit_complete(); @@ -165,19 +163,21 @@ d3d_blit_fs(int x, int y, int y1, int y2, int w, int h) return; /*Nothing to do*/ } - lock_rect.top = y1; - lock_rect.left = 0; - lock_rect.bottom = y2; - lock_rect.right = 2047; + r.top = y1; + r.left = 0; + r.bottom = y2; + r.right = 2047; - hr = d3dTexture->LockRect(0, &dr, &lock_rect, 0); - if (hr == D3D_OK) { + hr = d3dTexture->LockRect(0, &dr, &r, 0); + if (hr == D3D_OK) { for (yy = y1; yy < y2; yy++) { if (buffer32) { - if (video_grayscale || invert_display) - video_transform_copy((uint32_t *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w); - else - memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w * 4); + if ((y + yy) >= 0 && (y + yy) < buffer32->h) { + if (video_grayscale || invert_display) + video_transform_copy((uint32_t *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w); + else + memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w * 4); + } } } @@ -188,8 +188,8 @@ d3d_blit_fs(int x, int y, int y1, int y2, int w, int h) return; } - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0; - d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0; + d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; + d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = @@ -197,32 +197,35 @@ d3d_blit_fs(int x, int y, int y1, int y2, int w, int h) d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; - GetClientRect(d3d_device_window, &w_rect); - d3d_size(w_rect, &l, &t, &r, &b, w, h); - - d3d_verts[0].x = l; - d3d_verts[0].y = t; - d3d_verts[1].x = r; - d3d_verts[1].y = b; - d3d_verts[2].x = l; - d3d_verts[2].y = b; - d3d_verts[3].x = l; - d3d_verts[3].y = t; - d3d_verts[4].x = r; - d3d_verts[4].y = t; - d3d_verts[5].x = r; - d3d_verts[5].y = b; - d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = r - 40.5; - d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = t + 8.5; - d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = r - 8.5; - d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = t + 14.5; + if (d3d_fs) { + GetClientRect(d3d_device_window, &r); + d3d_size(r, &l, &t, &rr, &b, w, h); + d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = l; + d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = t; + d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = rr; + d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = b; + d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = rr - 40.5; + d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = t + 8.5; + d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = rr - 8.5; + d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = t + 14.5; + } else { + GetClientRect(d3d_hwnd, &r); + d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; + d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5; + d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right-r.left)-0.5; + d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom-r.top)-0.5; + d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = (r.right-r.left)-40.5; + d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = 8.5; + d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = (r.right-r.left)-8.5; + d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = 14.5; + } if (hr == D3D_OK) - hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); + hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer if (hr == D3D_OK) - memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); + memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer if (hr == D3D_OK) - hr = v_buffer->Unlock(); + hr = v_buffer->Unlock(); // unlock the vertex buffer if (hr == D3D_OK) hbsr = hr = d3ddev->BeginScene(); @@ -253,217 +256,6 @@ d3d_blit_fs(int x, int y, int y1, int y2, int w, int h) if (hr == D3D_OK) hr = d3ddev->Present(NULL, NULL, d3d_device_window, NULL); - if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) - PostMessage(hwndMain, WM_RESETD3D, 0, 0); -#else - HRESULT hr = D3D_OK; - HRESULT hbsr = D3D_OK; - VOID* pVoid; - D3DLOCKED_RECT dr; - RECT r, w_rect; - int yy; - double l = 0, t = 0, rr = 0, b = 0; - - if (!d3d_enabled) { - video_blit_complete(); - return; - } - - if ((y1 == y2) || (h <= 0)) { - video_blit_complete(); - return; /*Nothing to do*/ - } - - r.top = y1; - r.left = 0; - r.bottom = y2; - r.right = 2047; - - hr = d3dTexture->LockRect(0, &dr, &r, 0); - if (hr == D3D_OK) { - for (yy = y1; yy < y2; yy++) { - if (buffer32) { - if ((y + yy) >= 0 && (y + yy) < buffer32->h) { - if (video_grayscale || invert_display) - video_transform_copy((uint32_t *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w); - else - memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w * 4); - } - } - } - - video_blit_complete(); - d3dTexture->UnlockRect(0); - } else { - video_blit_complete(); - return; - } - - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; - d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; - d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; - d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; - d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = - d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color = - d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = - d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; - - GetClientRect(d3d_device_window, &w_rect); - d3d_size(w_rect, &l, &t, &rr, &b, w, h); - - d3d_verts[0].x = l; - d3d_verts[0].y = t; - d3d_verts[1].x = rr; - d3d_verts[1].y = b; - d3d_verts[2].x = l; - d3d_verts[2].y = b; - d3d_verts[3].x = l; - d3d_verts[3].y = t; - d3d_verts[4].x = rr; - d3d_verts[4].y = t; - d3d_verts[5].x = rr; - d3d_verts[5].y = b; - d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = rr - 40.5; - d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = t + 8.5; - d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = rr - 8.5; - d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = t + 14.5; - - if (hr == D3D_OK) - hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer - if (hr == D3D_OK) - memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer - if (hr == D3D_OK) - hr = v_buffer->Unlock(); // unlock the vertex buffer - - if (hr == D3D_OK) - hbsr = hr = d3ddev->BeginScene(); - - if (hr == D3D_OK) { - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, d3dTexture); - - if (hr == D3D_OK) - hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); - - if (hr == D3D_OK) - hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); - - if (hr == D3D_OK) - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, NULL); - } - - if (hbsr == D3D_OK) - hr = d3ddev->EndScene(); - - if (hr == D3D_OK) - hr = d3ddev->Present(NULL, NULL, d3d_device_window, NULL); - - if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) - PostMessage(d3d_hwnd, WM_RESETD3D, 0, 0); -#endif -} - - -static void -d3d_blit(int x, int y, int y1, int y2, int w, int h) -{ - HRESULT hr = D3D_OK; - HRESULT hbsr = D3D_OK; - VOID* pVoid; - D3DLOCKED_RECT dr; - RECT r; - int yy; - - if (!d3d_enabled) { - video_blit_complete(); - return; - } - - if ((y1 == y2) || (h <= 0)) { - video_blit_complete(); - return; /*Nothing to do*/ - } - - r.top = y1; - r.left = 0; - r.bottom = y2; - r.right = 2047; - - hr = d3dTexture->LockRect(0, &dr, &r, 0); - if (hr == D3D_OK) { - for (yy = y1; yy < y2; yy++) { - if (buffer32) { - if ((y + yy) >= 0 && (y + yy) < buffer32->h) { - if (video_grayscale || invert_display) - video_transform_copy((uint32_t *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w); - else - memcpy((void *)((uintptr_t)dr.pBits + ((yy - y1) * dr.Pitch)), &(buffer32->line[yy + y][x]), w * 4); - } - } - } - - video_blit_complete(); - d3dTexture->UnlockRect(0); - } else { - video_blit_complete(); - return; - } - - d3d_verts[0].tu = d3d_verts[2].tu = d3d_verts[3].tu = 0;//0.5 / 2048.0; - d3d_verts[0].tv = d3d_verts[3].tv = d3d_verts[4].tv = 0;//0.5 / 2048.0; - d3d_verts[1].tu = d3d_verts[4].tu = d3d_verts[5].tu = (float)w / 2048.0; - d3d_verts[1].tv = d3d_verts[2].tv = d3d_verts[5].tv = (float)h / 2048.0; - d3d_verts[0].color = d3d_verts[1].color = d3d_verts[2].color = - d3d_verts[3].color = d3d_verts[4].color = d3d_verts[5].color = - d3d_verts[6].color = d3d_verts[7].color = d3d_verts[8].color = - d3d_verts[9].color = d3d_verts[10].color = d3d_verts[11].color = 0xffffff; - - GetClientRect(d3d_hwnd, &r); - d3d_verts[0].x = d3d_verts[2].x = d3d_verts[3].x = -0.5; - d3d_verts[0].y = d3d_verts[3].y = d3d_verts[4].y = -0.5; - d3d_verts[1].x = d3d_verts[4].x = d3d_verts[5].x = (r.right-r.left)-0.5; - d3d_verts[1].y = d3d_verts[2].y = d3d_verts[5].y = (r.bottom-r.top)-0.5; - d3d_verts[6].x = d3d_verts[8].x = d3d_verts[9].x = (r.right-r.left)-40.5; - d3d_verts[6].y = d3d_verts[9].y = d3d_verts[10].y = 8.5; - d3d_verts[7].x = d3d_verts[10].x = d3d_verts[11].x = (r.right-r.left)-8.5; - d3d_verts[7].y = d3d_verts[8].y = d3d_verts[11].y = 14.5; - - if (hr == D3D_OK) - hr = v_buffer->Lock(0, 0, (void**)&pVoid, 0); // lock the vertex buffer - if (hr == D3D_OK) - memcpy(pVoid, d3d_verts, sizeof(d3d_verts)); // copy the vertices to the locked buffer - if (hr == D3D_OK) - hr = v_buffer->Unlock(); // unlock the vertex buffer - - if (hr == D3D_OK) - hbsr = hr = d3ddev->BeginScene(); - - if (hr == D3D_OK) { - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, d3dTexture); - - if (hr == D3D_OK) - hr = d3ddev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1); - - if (hr == D3D_OK) - hr = d3ddev->SetStreamSource(0, v_buffer, 0, sizeof(CUSTOMVERTEX)); - - if (hr == D3D_OK) - hr = d3ddev->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2); - - if (hr == D3D_OK) - hr = d3ddev->SetTexture(0, NULL); - } - - if (hbsr == D3D_OK) - hr = d3ddev->EndScene(); - - if (hr == D3D_OK) - hr = d3ddev->Present(NULL, NULL, d3d_hwnd, NULL); - if (hr == D3DERR_DEVICELOST || hr == D3DERR_INVALIDCALL) PostMessage(d3d_hwnd, WM_RESETD3D, 0, 0); } @@ -557,6 +349,7 @@ d3d_init(HWND h) video_setblit(d3d_blit); + d3d_fs = 0; d3d_enabled = 1; return(1); @@ -629,8 +422,9 @@ d3d_init_fs(HWND h) mouse_capture = 1; - video_setblit(d3d_blit_fs); + video_setblit(d3d_blit); + d3d_fs = 1; d3d_enabled = 1; return(1); diff --git a/src/win/win_ddraw.cpp b/src/win/win_ddraw.cpp index 35772613c..f7f97ff35 100644 --- a/src/win/win_ddraw.cpp +++ b/src/win/win_ddraw.cpp @@ -11,7 +11,7 @@ * NOTES: This code should be re-merged into a single init() with a * 'fullscreen' argument, indicating FS mode is requested. * - * Version: @(#)win_ddraw.cpp 1.0.15 2019/10/12 + * Version: @(#)win_ddraw.cpp 1.0.16 2019/11/01 * * Authors: Sarah Walker, * Miran Grca, @@ -48,6 +48,7 @@ static LPDIRECTDRAWCLIPPER lpdd_clipper = NULL; static DDSURFACEDESC2 ddsd; static HWND ddraw_hwnd; static int ddraw_w, ddraw_h; +static int ddraw_fs; static volatile int ddraw_enabled = 0; @@ -148,97 +149,17 @@ ddraw_fs_size(RECT w_rect, RECT *r_dest, int w, int h) } -static void -ddraw_blit_fs(int x, int y, int y1, int y2, int w, int h) -{ - RECT r_src; - RECT r_dest; - RECT w_rect; - int yy; - HRESULT hr; - DDBLTFX ddbltfx; - - if (!ddraw_enabled) { - video_blit_complete(); - return; - } - - if (lpdds_back == NULL) { - video_blit_complete(); - return; /*Nothing to do*/ - } - - if ((y1 == y2) || (h <= 0)) { - video_blit_complete(); - return; - } - - memset(&ddsd, 0, sizeof(ddsd)); - ddsd.dwSize = sizeof(ddsd); - - hr = lpdds_back->Lock(NULL, &ddsd, - DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - if (hr == DDERR_SURFACELOST) { - lpdds_back->Restore(); - lpdds_back->Lock(NULL, &ddsd, - DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL); - device_force_redraw(); - } - if (! ddsd.lpSurface) { - video_blit_complete(); - return; - } - - for (yy = y1; yy < y2; yy++) { - if (buffer32) { - if (video_grayscale || invert_display) - video_transform_copy((uint32_t *)((uintptr_t)ddsd.lpSurface + (yy * ddsd.lPitch)), &(buffer32->line[y + yy][x]), w); - else - memcpy((void *)((uintptr_t)ddsd.lpSurface + (yy * ddsd.lPitch)), &(buffer32->line[y + yy][x]), w * 4); - } - } - video_blit_complete(); - lpdds_back->Unlock(NULL); - - w_rect.left = 0; - w_rect.top = 0; - w_rect.right = ddraw_w; - w_rect.bottom = ddraw_h; - ddraw_fs_size(w_rect, &r_dest, w, h); - - r_src.left = 0; - r_src.top = 0; - r_src.right = w; - r_src.bottom = h; - - ddbltfx.dwSize = sizeof(ddbltfx); - ddbltfx.dwFillColor = 0; - - lpdds_back2->Blt(&w_rect, NULL, NULL, - DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); - - hr = lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); - if (hr == DDERR_SURFACELOST) { - lpdds_back2->Restore(); - lpdds_back2->Blt(&r_dest, lpdds_back, &r_src, DDBLT_WAIT, NULL); - } - - hr = lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); - if (hr == DDERR_SURFACELOST) { - lpdds_pri->Restore(); - lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); - } -} - - static void ddraw_blit(int x, int y, int y1, int y2, int w, int h) { RECT r_src; RECT r_dest; POINT po; - HRESULT hr; + RECT w_rect; int yy; + HRESULT hr; + DDBLTFX ddbltfx; + RECT *r_tgt = ddraw_fs ? &r_dest : &r_src; if (!ddraw_enabled) { video_blit_complete(); @@ -286,29 +207,53 @@ ddraw_blit(int x, int y, int y1, int y2, int w, int h) video_blit_complete(); lpdds_back->Unlock(NULL); - po.x = po.y = 0; - - ClientToScreen(ddraw_hwnd, &po); - GetClientRect(ddraw_hwnd, &r_dest); - OffsetRect(&r_dest, po.x, po.y); - + if (ddraw_fs) { + w_rect.left = 0; + w_rect.top = 0; + w_rect.right = ddraw_w; + w_rect.bottom = ddraw_h; + ddraw_fs_size(w_rect, &r_dest, w, h); + } else { + po.x = po.y = 0; + + ClientToScreen(ddraw_hwnd, &po); + GetClientRect(ddraw_hwnd, &r_dest); + OffsetRect(&r_dest, po.x, po.y); + } + r_src.left = 0; r_src.top = 0; r_src.right = w; r_src.bottom = h; - hr = lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); - if (hr == DDERR_SURFACELOST) { - lpdds_back2->Restore(); - lpdds_back2->Blt(&r_src, lpdds_back, &r_src, DDBLT_WAIT, NULL); + if (ddraw_fs) { + ddbltfx.dwSize = sizeof(ddbltfx); + ddbltfx.dwFillColor = 0; + + lpdds_back2->Blt(&w_rect, NULL, NULL, + DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx); + } + + hr = lpdds_back2->Blt(r_tgt, lpdds_back, &r_src, DDBLT_WAIT, NULL); + if (hr == DDERR_SURFACELOST) { + lpdds_back2->Restore(); + lpdds_back2->Blt(r_tgt, lpdds_back, &r_src, DDBLT_WAIT, NULL); + } + + if (ddraw_fs) + hr = lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); + else { + lpdds_back2->Unlock(NULL); + + hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); } - lpdds_back2->Unlock(NULL); - - hr = lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); if (hr == DDERR_SURFACELOST) { lpdds_pri->Restore(); - lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); + if (ddraw_fs) + lpdds_pri->Flip(NULL, DDFLIP_NOVSYNC); + else + lpdds_pri->Blt(&r_dest, lpdds_back2, &r_src, DDBLT_WAIT, NULL); } } @@ -373,6 +318,7 @@ ddraw_init(HWND h) video_setblit(ddraw_blit); + ddraw_fs = 0; ddraw_enabled = 1; return(1); @@ -429,8 +375,9 @@ ddraw_init_fs(HWND h) ddraw_hwnd = h; - video_setblit(ddraw_blit_fs); + video_setblit(ddraw_blit); + ddraw_fs = 1; ddraw_enabled = 1; return(1); From ee77bc1471fbb1ce6a82a363e2f5a2603d8532ed Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 1 Nov 2019 23:29:39 +0100 Subject: [PATCH 02/26] Updated the notes in the header of machine/m_amstrad.c. --- src/machine/m_amstrad.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 377666611..6491d9e44 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -22,15 +22,12 @@ * PC200: CGA with some NMI stuff. But we don't need that as it's only * used for TV and LCD displays, and we're emulating a CRT. * + * PPC512/640: Portable with both CGA-compatible and MDA-compatible monitors. + * * TODO: This module is not complete yet: * - * PC1512: The BIOS assumes 512K RAM, because I cannot figure out how to - * read the status of the LK4 jumper on the mainboard, which is - * somehow linked to the bus gate array on the NDMACS line... - * - * PC1612: EGA mode does not seem to work in the PC1640; it works fine - * in alpha mode, but in highres ("ECD350") mode, it displays - * some semi-random junk. Video-memory pointer maybe? + * All models: The internal mouse controller does not work correctly with + * version 7.04 of the mouse driver. * * Version: @(#)m_amstrad.c 1.0.20 2019/03/09 * From 7807548be65a75a8811d8fd65de2c4fc3cb92931 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 2 Nov 2019 16:18:18 +0100 Subject: [PATCH 03/26] Reworked the behavior of the shutdown status message, and the virtual machine and manager window messages are now paused in case of a message box issued by a command from the manager. --- src/win/win.c | 32 +++++++++++++++++--------------- src/win/win.h | 6 +++--- src/win/win_settings.c | 6 +++--- src/win/win_ui.c | 40 ++++++++++++++++++++++++++++++---------- 4 files changed, 53 insertions(+), 31 deletions(-) diff --git a/src/win/win.c b/src/win/win.c index ac91ac436..8afaa3c27 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -8,7 +8,7 @@ * * Platform main support module for Windows. * - * Version: @(#)win.c 1.0.58 2019/10/19 + * Version: @(#)win.c 1.0.59 2019/11/02 * * Authors: Sarah Walker, * Miran Grca, @@ -197,11 +197,6 @@ set_language(int id) /* Load the strings table for this ID. */ LoadCommonStrings(); - -#if 0 - /* Update the menus for this ID. */ - MenuUpdate(); -#endif } } @@ -344,6 +339,14 @@ ProcessCommandLine(wchar_t ***argw) } +static void +shutdown_notify(void) +{ + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSDSTATUS, (WPARAM) 1, (LPARAM) hwndMain); +} + + /* For the Windows platform, this is the start of the application. */ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) @@ -381,6 +384,10 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) if (! pc_init(argc, argw)) { /* Detach from console. */ CreateConsole(0); + + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSDSTATUS, (WPARAM) 1, (LPARAM) hwndMain); + return(1); } @@ -391,6 +398,8 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) /* Handle our GUI. */ i = ui_init(nCmdShow); + atexit(shutdown_notify); + return(i); } @@ -428,6 +437,8 @@ do_stop(void) plat_delay_ms(100); + shutdown_notify(); + pc_close(thMain); thMain = NULL; @@ -627,7 +638,6 @@ plat_dir_check(wchar_t *path) int plat_dir_create(wchar_t *path) { - // return((int)CreateDirectory(path, NULL)); return((int)SHCreateDirectory(hwndMain, path)); } @@ -696,10 +706,6 @@ plat_vidapi_name(int api) break; case 2: -#if 0 - /* Direct3D is default. */ - name = "d3d"; -#endif break; case 3: @@ -707,10 +713,6 @@ plat_vidapi_name(int api) break; #else case 1: -#if 0 - /* Direct3D is default. */ - name = "d3d"; -#endif break; case 2: diff --git a/src/win/win.h b/src/win/win.h index 747c8c616..554e7b40e 100644 --- a/src/win/win.h +++ b/src/win/win.h @@ -8,7 +8,7 @@ * * Platform support defintions for Win32. * - * Version: @(#)win.h 1.0.26 2019/11/01 + * Version: @(#)win.h 1.0.27 2019/11/02 * * Authors: Sarah Walker, * Miran Grca, @@ -57,8 +57,8 @@ #define WM_SENDSTATUS 0x8895 /* Settings status: WPARAM = 1 for open, 0 for closed. */ #define WM_SENDSSTATUS 0x8896 -/* Emulator shut down. */ -#define WM_SHUTDOWN_DONE 0x8897 +/* Emulator shut down status: WPARAM = 1 for user said yes, 0 for use said no. */ +#define WM_SENDSDSTATUS 0x8897 #ifdef USE_VNC #ifdef USE_D2D diff --git a/src/win/win_settings.c b/src/win/win_settings.c index ab5a5baa8..7c60ec5b1 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.57 2019/11/01 + * Version: @(#)win_settings.c 1.0.58 2019/11/02 * * Authors: Miran Grca, * David Hrdlička, @@ -4502,7 +4502,7 @@ win_settings_confirm(HWND hdlg, int button) DestroyWindow(hwndChildDialog); EndDialog(hdlg, 0); - plat_pause(0); + plat_pause(dopause); win_settings_communicate_closure(); return button ? TRUE : FALSE; @@ -4555,7 +4555,7 @@ win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) case IDCANCEL: DestroyWindow(hwndChildDialog); EndDialog(hdlg, 0); - plat_pause(0); + plat_pause(dopause); win_settings_communicate_closure(); return TRUE; } diff --git a/src/win/win_ui.c b/src/win/win_ui.c index a23d74361..f15cea020 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -8,7 +8,7 @@ * * user Interface module for WinAPI on Windows. * - * Version: @(#)win_ui.c 1.0.41 2019/11/01 + * Version: @(#)win_ui.c 1.0.42 2019/11/02 * * Authors: Sarah Walker, * Miran Grca, @@ -64,7 +64,7 @@ WCHAR wopenfilestring[260]; /* Local data. */ static wchar_t wTitle[512]; static HHOOK hKeyboardHook; -static int hook_enabled = 0; +static int hook_enabled = 0, manager_wm = 0; static int save_window_pos = 0; @@ -309,8 +309,6 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case IDM_ACTION_EXIT: i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); if (i == 0) { - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SHUTDOWN_DONE, (WPARAM) 0, (LPARAM) hwndMain); UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); @@ -673,8 +671,6 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_CLOSE: i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); if (i == 0) { - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SHUTDOWN_DONE, (WPARAM) 0, (LPARAM) hwndMain); UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); @@ -682,41 +678,65 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case WM_DESTROY: - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SHUTDOWN_DONE, (WPARAM) 0, (LPARAM) hwndMain); UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); break; case WM_SHOWSETTINGS: + if (manager_wm) + break; + manager_wm = 1; win_settings_open(hwnd); + manager_wm = 0; break; case WM_PAUSE: + if (manager_wm) + break; + manager_wm = 1; plat_pause(dopause ^ 1); CheckMenuItem(menuMain, IDM_ACTION_PAUSE, dopause ? MF_CHECKED : MF_UNCHECKED); + plat_pause(dopause); + manager_wm = 0; break; case WM_HARDRESET: + if (manager_wm) + break; + manager_wm = 1; + plat_pause(1); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2121); + plat_pause(dopause); if (i == 0) pc_reset(1); + manager_wm = 0; break; case WM_SHUTDOWN: + if (manager_wm) + break; + manager_wm = 1; + plat_pause(1); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); + plat_pause(dopause); if (i == 0) { - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SHUTDOWN_DONE, (WPARAM) 0, (LPARAM) hwndMain); UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); + } else { + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSDSTATUS, (WPARAM) 0, (LPARAM) hwndMain); } + manager_wm = 0; break; case WM_CTRLALTDEL: + if (manager_wm) + break; + manager_wm = 1; pc_reset(0); + manager_wm = 0; break; case WM_SYSCOMMAND: From f6f86c1f9a1e2349672f407edc12318778c5d06f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 2 Nov 2019 16:33:00 +0100 Subject: [PATCH 04/26] The virtual machine and manager window messages are now also paused during emulator-initiated hard reset and shutdown message boxes. --- src/win/win_ui.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/src/win/win_ui.c b/src/win/win_ui.c index f15cea020..7908cbd43 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -8,7 +8,7 @@ * * user Interface module for WinAPI on Windows. * - * Version: @(#)win_ui.c 1.0.42 2019/11/02 + * Version: @(#)win_ui.c 1.0.43 2019/11/02 * * Authors: Sarah Walker, * Miran Grca, @@ -297,9 +297,13 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_ACTION_HRESET: + manager_wm = 1; + plat_pause(1); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2121); if (i == 0) pc_reset(1); + plat_pause(dopause); + manager_wm = 0; break; case IDM_ACTION_RESET_CAD: @@ -307,12 +311,16 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_ACTION_EXIT: + manager_wm = 1; + plat_pause(1); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); if (i == 0) { UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); - } + } else + plat_pause(dopause); + manager_wm = 0; break; case IDM_ACTION_CTRL_ALT_ESC: @@ -669,12 +677,16 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) return(0); case WM_CLOSE: + manager_wm = 1; + plat_pause(1); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); if (i == 0) { UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); - } + } else + plat_pause(dopause); + manager_wm = 0; break; case WM_DESTROY: @@ -707,9 +719,9 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) manager_wm = 1; plat_pause(1); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2121); - plat_pause(dopause); if (i == 0) pc_reset(1); + plat_pause(dopause); manager_wm = 0; break; @@ -719,7 +731,6 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) manager_wm = 1; plat_pause(1); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); - plat_pause(dopause); if (i == 0) { UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); @@ -727,6 +738,7 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) } else { if (source_hwnd) PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSDSTATUS, (WPARAM) 0, (LPARAM) hwndMain); + plat_pause(dopause); } manager_wm = 0; break; From 4262b2023563490c1aa9db18f6dafaf9aa893b25 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 3 Nov 2019 03:18:30 +0100 Subject: [PATCH 05/26] Finalized the Window Message protocol for communicating with the 86Box Manager. --- src/win/win.c | 15 ++------- src/win/win.h | 20 ++++++++---- src/win/win_settings.c | 21 +++---------- src/win/win_ui.c | 71 +++++++++++++++++++++++++----------------- 4 files changed, 63 insertions(+), 64 deletions(-) diff --git a/src/win/win.c b/src/win/win.c index 8afaa3c27..f4481feed 100644 --- a/src/win/win.c +++ b/src/win/win.c @@ -339,14 +339,6 @@ ProcessCommandLine(wchar_t ***argw) } -static void -shutdown_notify(void) -{ - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSDSTATUS, (WPARAM) 1, (LPARAM) hwndMain); -} - - /* For the Windows platform, this is the start of the application. */ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) @@ -386,7 +378,7 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) CreateConsole(0); if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSDSTATUS, (WPARAM) 1, (LPARAM) hwndMain); + PostMessage((HWND) (uintptr_t) source_hwnd, WM_HAS_SHUTDOWN, (WPARAM) 0, (LPARAM) hwndMain); return(1); } @@ -398,8 +390,6 @@ WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpszArg, int nCmdShow) /* Handle our GUI. */ i = ui_init(nCmdShow); - atexit(shutdown_notify); - return(i); } @@ -437,7 +427,8 @@ do_stop(void) plat_delay_ms(100); - shutdown_notify(); + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_HAS_SHUTDOWN, (WPARAM) 0, (LPARAM) hwndMain); pc_close(thMain); diff --git a/src/win/win.h b/src/win/win.h index 554e7b40e..05ce73978 100644 --- a/src/win/win.h +++ b/src/win/win.h @@ -8,7 +8,7 @@ * * Platform support defintions for Win32. * - * Version: @(#)win.h 1.0.27 2019/11/02 + * Version: @(#)win.h 1.0.28 2019/11/02 * * Authors: Sarah Walker, * Miran Grca, @@ -43,7 +43,12 @@ #define SB_MENU_NAME L"StatusBarMenu" #define FS_CLASS_NAME L"86BoxFullScreen" -/* Application-specific window messages. */ +/* Application-specific window messages. + + A dialog sends 0x8895 with WPARAM = 1 followed by 0x8896 with WPARAM = 1 on open, + and 0x8895 with WPARAM = followed by 0x8896 with WPARAM = 0. + + All shutdowns will send an 0x8897. */ #define WM_RESETD3D WM_USER #define WM_LEAVEFULLSCREEN WM_USER+1 #define WM_SAVESETTINGS 0x8888 @@ -55,10 +60,10 @@ #define WM_CTRLALTDEL 0x8894 /* Pause/resume status: WPARAM = 1 for paused, 0 for resumed. */ #define WM_SENDSTATUS 0x8895 -/* Settings status: WPARAM = 1 for open, 0 for closed. */ -#define WM_SENDSSTATUS 0x8896 -/* Emulator shut down status: WPARAM = 1 for user said yes, 0 for use said no. */ -#define WM_SENDSDSTATUS 0x8897 +/* Dialog (Settings or message box) status: WPARAM = 1 for open, 0 for closed. */ +#define WM_SENDDLGSTATUS 0x8896 +/* The emulator has shut down. */ +#define WM_HAS_SHUTDOWN 0x8897 #ifdef USE_VNC #ifdef USE_D2D @@ -118,6 +123,9 @@ extern void win_mouse_close(void); extern void win_mouse_handle(LPARAM lParam, int infocus); #endif +extern void win_notify_dlg_open(void); +extern void win_notify_dlg_closed(void); + extern LPARAM win_get_string(int id); extern intptr_t fdd_type_to_icon(int type); diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 7c60ec5b1..5fda27cf3 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.58 2019/11/02 + * Version: @(#)win_settings.c 1.0.60 2019/11/02 * * Authors: Miran Grca, * David Hrdlička, @@ -4477,14 +4477,6 @@ win_settings_main_insert_categories(HWND hwndList) -static void -win_settings_communicate_closure(void) -{ - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSSTATUS, (WPARAM) 0, (LPARAM) hwndMain); -} - - #if defined(__amd64__) || defined(__aarch64__) static LRESULT CALLBACK #else @@ -4502,8 +4494,7 @@ win_settings_confirm(HWND hdlg, int button) DestroyWindow(hwndChildDialog); EndDialog(hdlg, 0); - plat_pause(dopause); - win_settings_communicate_closure(); + win_notify_dlg_closed(); return button ? TRUE : FALSE; } else @@ -4555,8 +4546,7 @@ win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) case IDCANCEL: DestroyWindow(hwndChildDialog); EndDialog(hdlg, 0); - plat_pause(dopause); - win_settings_communicate_closure(); + win_notify_dlg_closed(); return TRUE; } break; @@ -4571,10 +4561,7 @@ win_settings_main_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) void win_settings_open_ex(HWND hwnd, int category) { - plat_pause(1); - - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSSTATUS, (WPARAM) 1, (LPARAM) hwndMain); + win_notify_dlg_open(); first_cat = category; DialogBox(hinstance, (LPCWSTR)DLG_CONFIG, hwnd, win_settings_main_proc); diff --git a/src/win/win_ui.c b/src/win/win_ui.c index 7908cbd43..312a76826 100644 --- a/src/win/win_ui.c +++ b/src/win/win_ui.c @@ -8,7 +8,7 @@ * * user Interface module for WinAPI on Windows. * - * Version: @(#)win_ui.c 1.0.43 2019/11/02 + * Version: @(#)win_ui.c 1.0.44 2019/11/02 * * Authors: Sarah Walker, * Miran Grca, @@ -65,7 +65,7 @@ WCHAR wopenfilestring[260]; static wchar_t wTitle[512]; static HHOOK hKeyboardHook; static int hook_enabled = 0, manager_wm = 0; -static int save_window_pos = 0; +static int save_window_pos = 0, pause_state = 0; static int vis = -1; @@ -270,6 +270,27 @@ LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) } +void +win_notify_dlg_open(void) +{ + manager_wm = 1; + pause_state = dopause; + plat_pause(1); + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDDLGSTATUS, (WPARAM) 1, (LPARAM) hwndMain); +} + + +void +win_notify_dlg_closed(void) +{ + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDDLGSTATUS, (WPARAM) 0, (LPARAM) hwndMain); + plat_pause(pause_state); + manager_wm = 0; +} + + static LRESULT CALLBACK MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { @@ -297,13 +318,11 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_ACTION_HRESET: - manager_wm = 1; - plat_pause(1); + win_notify_dlg_open(); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2121); if (i == 0) pc_reset(1); - plat_pause(dopause); - manager_wm = 0; + win_notify_dlg_closed(); break; case IDM_ACTION_RESET_CAD: @@ -311,16 +330,14 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) break; case IDM_ACTION_EXIT: - manager_wm = 1; - plat_pause(1); + win_notify_dlg_open(); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); if (i == 0) { UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); - } else - plat_pause(dopause); - manager_wm = 0; + } + win_notify_dlg_closed(); break; case IDM_ACTION_CTRL_ALT_ESC: @@ -677,16 +694,14 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) return(0); case WM_CLOSE: - manager_wm = 1; - plat_pause(1); + win_notify_dlg_open(); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); if (i == 0) { UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); - } else - plat_pause(dopause); - manager_wm = 0; + } + win_notify_dlg_closed(); break; case WM_DESTROY: @@ -709,38 +724,30 @@ MainWindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) manager_wm = 1; plat_pause(dopause ^ 1); CheckMenuItem(menuMain, IDM_ACTION_PAUSE, dopause ? MF_CHECKED : MF_UNCHECKED); - plat_pause(dopause); manager_wm = 0; break; case WM_HARDRESET: if (manager_wm) break; - manager_wm = 1; - plat_pause(1); + win_notify_dlg_open(); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2121); if (i == 0) pc_reset(1); - plat_pause(dopause); - manager_wm = 0; + win_notify_dlg_closed(); break; case WM_SHUTDOWN: if (manager_wm) break; - manager_wm = 1; - plat_pause(1); + win_notify_dlg_open(); i = ui_msgbox(MBX_QUESTION_YN, (wchar_t *)IDS_2122); if (i == 0) { UnhookWindowsHookEx(hKeyboardHook); KillTimer(hwnd, TIMER_1SEC); PostQuitMessage(0); - } else { - if (source_hwnd) - PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSDSTATUS, (WPARAM) 0, (LPARAM) hwndMain); - plat_pause(dopause); } - manager_wm = 0; + win_notify_dlg_closed(); break; case WM_CTRLALTDEL: @@ -1071,7 +1078,13 @@ plat_pause(int p) p = get_vidpause(); /* If already so, done. */ - if (dopause == p) return; + if (dopause == p) { + /* Send the WM to a manager if needed. */ + if (source_hwnd) + PostMessage((HWND) (uintptr_t) source_hwnd, WM_SENDSTATUS, (WPARAM) !!dopause, (LPARAM) hwndMain); + + return; + } if (p) { wcscpy(oldtitle, ui_window_title(NULL)); From ca58ed44563b1db1e38ec792188a02883f1d1e6c Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 4 Nov 2019 22:14:47 +0100 Subject: [PATCH 06/26] Fixed a bug in the PGC/Image Manager 1024 text modes. --- src/video/vid_pgc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index 637709c1a..6addc20b1 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -44,7 +44,7 @@ * * This is expected to be done shortly. * - * Version: @(#)vid_pgc.c 1.0.3 2019/09/28 + * Version: @(#)vid_pgc.c 1.0.4 2019/11/04 * * Authors: Fred N. van Kempen, * John Elliott, @@ -2311,7 +2311,7 @@ pgc_cga_text(pgc_t *dev, int w) uint32_t val; int cw = (w == 80) ? 8 : 16; - addr = &dev->cga_vram[(((ma << 1) + ((dev->displine / pitch)*w)) * 2) & 0x3ffe]; + addr = &dev->cga_vram[((ma + ((dev->displine / pitch) * w)) * 2) & 0x3ffe]; ma += (dev->displine / pitch) * w; for (x = 0; x < w; x++) { From 1a9b46b829d45d7cee28c46d881aaff5bc0386ba Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 4 Nov 2019 22:18:13 +0100 Subject: [PATCH 07/26] Removed the empty config structures for the PGC and the Image Manager 1024. --- src/video/vid_im1024.c | 11 ++--------- src/video/vid_pgc.c | 11 ++--------- 2 files changed, 4 insertions(+), 18 deletions(-) diff --git a/src/video/vid_im1024.c b/src/video/vid_im1024.c index 0f276a103..0a8ca6e6c 100644 --- a/src/video/vid_im1024.c +++ b/src/video/vid_im1024.c @@ -38,7 +38,7 @@ * This is implemented by holding a FIFO of unlimited depth in * the IM1024 to receive the data. * - * Version: @(#)vid_im1024.c 1.0.3 2019/03/03 + * Version: @(#)vid_im1024.c 1.0.4 2019/11/04 * * Authors: Fred N. van Kempen, * John Elliott, @@ -1008,13 +1008,6 @@ im1024_speed_changed(void *priv) } -static const device_config_t im1024_config[] = { - { - "", "", -1 - } -}; - - const device_t im1024_device = { "ImageManager 1024", DEVICE_ISA, 0, @@ -1022,5 +1015,5 @@ const device_t im1024_device = { im1024_available, im1024_speed_changed, NULL, - im1024_config + NULL }; diff --git a/src/video/vid_pgc.c b/src/video/vid_pgc.c index 6addc20b1..e8ccbee4b 100644 --- a/src/video/vid_pgc.c +++ b/src/video/vid_pgc.c @@ -44,7 +44,7 @@ * * This is expected to be done shortly. * - * Version: @(#)vid_pgc.c 1.0.4 2019/11/04 + * Version: @(#)vid_pgc.c 1.0.5 2019/11/04 * * Authors: Fred N. van Kempen, * John Elliott, @@ -2698,13 +2698,6 @@ pgc_standalone_init(const device_t *info) } -static const device_config_t pgc_config[] = { - { - "", "", -1 - } -}; - - const device_t pgc_device = { "PGC", DEVICE_ISA, 0, @@ -2714,5 +2707,5 @@ const device_t pgc_device = { NULL, pgc_speed_changed, NULL, - pgc_config + NULL }; From 3b209c301540cfa39ce90520a620027ba0a8cafd Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 6 Nov 2019 05:04:44 +0100 Subject: [PATCH 08/26] Reimplemented IDE reset and DRIVE DIAGNOSTICS command in accordance with the ATA-3 specification and changed their callback timings, fixes IDE on the SPC-4200P. --- src/disk/hdc_ide.c | 97 ++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 43 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 28f5ef7ae..6a408bf50 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdc_ide.c 1.0.63 2019/11/01 + * Version: @(#)hdc_ide.c 1.0.64 2019/11/06 * * Authors: Sarah Walker, * Miran Grca, @@ -1156,18 +1156,9 @@ static void dev_reset(ide_t *ide) { ide_set_signature(ide); - ide->error = 1; /*No error detected*/ - if (ide->type == IDE_ATAPI) { - ide->sc->status = 0; - ide->sc->error = 1; - ide_irq_raise(ide); - if (ide->stop) - ide->stop(ide->sc); - } else { - ide->atastat = DRDY_STAT | DSC_STAT; - ide->error = 1; - } + if ((ide->type == IDE_ATAPI) && ide->stop) + ide->stop(ide->sc); } @@ -1189,30 +1180,47 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv) return; dev->diag = 0; - + if ((val & 4) && !(ide->fdisk & 4)) { /* Reset toggled from 0 to 1, initiate reset procedure. */ if (ide->type == IDE_ATAPI) ide->sc->callback = 0.0; ide_set_callback(ide->board, 0.0); - ide->atastat = BSY_STAT; - if (ide->type == IDE_ATAPI) - ide->sc->status = BSY_STAT; - dev_reset(ide); } else if (!(val & 4) && (ide->fdisk & 4)) { /* Reset toggled from 1 to 0. */ if (!(ch & 1)) { - /* Currently active device is 0, fire the timer. */ - if (ide->type == IDE_ATAPI) - ide->sc->callback = 0.4; - ide_set_callback(ide->board, 0.4); + /* Currently active device is 0, use the device 0 reset protocol. */ + /* Device 0. */ + dev_reset(ide); + ide->atastat = BSY_STAT; + ide->error = 1; + if (ide->type == IDE_ATAPI) { + ide->sc->status = BSY_STAT; + ide->sc->error = 1; + } + + /* Device 1. */ + dev_reset(ide_other); + ide_other->atastat = BSY_STAT; + ide_other->error = 1; + if (ide_other->type == IDE_ATAPI) { + ide_other->sc->status = BSY_STAT; + ide_other->sc->error = 1; + } + + /* Fire the timer. */ + dev->diag = 0; ide->reset = 1; + ide_set_callback(ide->board, 500 * IDE_TIME); } else { /* Currently active device is 1, simply reset the status and the active device. */ - ide->atastat = 0x50; - if (ide->type == IDE_ATAPI) - ide->sc->status = DRDY_STAT | DSC_STAT; + dev_reset(ide); ide->atastat = DRDY_STAT | DSC_STAT; + ide->error = 1; + if (ide->type == IDE_ATAPI) { + ide->sc->status = DRDY_STAT | DSC_STAT; + ide->sc->error = 1; + } dev->cur_dev &= ~1; } } @@ -1494,18 +1502,32 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) return; case WIN_DRIVE_DIAGNOSTICS: /* Execute Drive Diagnostics */ - ide->atastat = BSY_STAT; - dev_reset(ide); - if (!(ch & 1)) - dev_reset(ide_other); - dev->diag = 1; + dev->cur_dev &= ~1; + ide = ide_drives[ch & ~1]; + ide_other = ide_drives[ch | 1]; + /* Device 0. */ + dev_reset(ide); + ide->atastat = BSY_STAT; + ide->error = 1; if (ide->type == IDE_ATAPI) { ide->sc->status = BSY_STAT; - ide->sc->callback = 0.4; + ide->sc->error = 1; } - ide_set_callback(ide->board, 0.4); + + /* Device 1. */ + dev_reset(ide_other); + ide_other->atastat = BSY_STAT; + ide_other->error = 1; + if (ide_other->type == IDE_ATAPI) { + ide_other->sc->status = BSY_STAT; + ide_other->sc->error = 1; + } + + /* Fire the timer. */ + dev->diag = 1; ide->reset = 1; + ide_set_callback(ide->board, 200 * IDE_TIME); return; case WIN_PIDENTIFY: /* Identify Packet Device */ @@ -1825,12 +1847,6 @@ ide_callback(void *priv) if (ide->reset) { ide_log("CALLBACK RESET %i %i\n", ide->reset,ch); - ide = ide_drives[ch & ~1]; - ide_other = ide_drives[ch | 1]; - - if (!dev->diag) - dev_reset(ide_other); - ide->atastat = DRDY_STAT | DSC_STAT; if (ide->type == IDE_ATAPI) ide->sc->status = DRDY_STAT | DSC_STAT; @@ -1845,13 +1861,8 @@ ide_callback(void *priv) dev->diag = 0; ide_irq_raise(ide); } - - if (ide->type == IDE_ATAPI) - ide->sc->callback = 0.0; - if (ide_other->type == IDE_ATAPI) - ide_other->sc->callback = 0.0; - ide_set_callback(ide->board, 0.0); ide->reset = 0; + ide_set_callback(ide->board, 0.0); return; } From 9c8c9361a6e0b0d406fc5896b7612be707633bcf Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 6 Nov 2019 05:15:17 +0100 Subject: [PATCH 09/26] IDE now updates IRQ when needed. --- src/disk/hdc_ide.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 6a408bf50..bd1931222 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -261,10 +261,10 @@ ide_irq_raise(ide_t *ide) /* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ - if (!(ide->fdisk & 2) && (ide_boards[ide->board]->irq != -1)) { + if (!(ide->fdisk & 2)) { if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq) ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); - else + else if (ide_boards[ide->board]->irq != -1) picint(1 << ide_boards[ide->board]->irq); } @@ -281,14 +281,39 @@ ide_irq_lower(ide_t *ide) /* ide_log("Lowering IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ - if ((ide_boards[ide->board]->irq != -1) && ide->irqstat) { + if (ide->irqstat) { if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq) ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); - else + else if (ide_boards[ide->board]->irq != -1) picintc(1 << ide_boards[ide->board]->irq); } - ide->irqstat=0; + ide->irqstat = 0; +} + + +static void +ide_irq_update(ide_t *ide) +{ + if (!ide_boards[ide->board]) + return; + + /* ide_log("Raising IRQ %i (board %i)\n", ide_boards[ide->board]->irq, ide->board); */ + + if (!(ide->fdisk & 2) && ide->irqstat) { + if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq) { + ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); + ide_bm[ide->board]->set_irq(ide->board | 0x40, ide_bm[ide->board]->priv); + } else if (ide_boards[ide->board]->irq != -1) { + picintc(1 << ide_boards[ide->board]->irq); + picint(1 << ide_boards[ide->board]->irq); + } + } else if (ide->fdisk & 2) { + if (ide_bm[ide->board] && ide_bm[ide->board]->set_irq) + ide_bm[ide->board]->set_irq(ide->board, ide_bm[ide->board]->priv); + else if (ide_boards[ide->board]->irq != -1) + picintc(1 << ide_boards[ide->board]->irq); + } } @@ -1169,6 +1194,7 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv) ide_t *ide, *ide_other; int ch; + uint8_t old; ch = dev->cur_dev; ide = ide_drives[ch]; @@ -1225,7 +1251,10 @@ ide_write_devctl(uint16_t addr, uint8_t val, void *priv) } } + old = ide->fdisk; ide->fdisk = ide_other->fdisk = val; + if (!(val & 0x02) && (old & 0x02) && ide->irqstat) + ide_irq_update(ide); } @@ -1365,6 +1394,8 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide->lba_addr = (ide->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24); ide_other->lba_addr = (ide_other->lba_addr & 0x0FFFFFF)|((val & 0xF) << 24); + + ide_irq_update(ide); return; case 0x7: /* Command register */ From 56a8da6cf534d9df4805162905ca43742ef44d31 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 8 Nov 2019 08:06:02 +0100 Subject: [PATCH 10/26] PCI Reset Control register now forces bit 4 to be written as 0, fixes resets through this register from the second soft reset onwards. --- src/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pci.c b/src/pci.c index 1e27becdf..05519cc2e 100644 --- a/src/pci.c +++ b/src/pci.c @@ -8,7 +8,7 @@ * * Implementation the PCI bus. * - * Version: @(#)pci.c 1.0.3 2019/10/30 + * Version: @(#)pci.c 1.0.4 2019/11/06 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -635,7 +635,7 @@ trc_write(uint16_t port, uint8_t val, void *priv) if (!(trc_reg & 4) && (val & 4)) trc_reset(val); - trc_reg = val & 0xfd; + trc_reg = val & 0xfb; } From cc8ab094c77f3bb5dd173c81422364f646a60e23 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 8 Nov 2019 22:00:29 +0100 Subject: [PATCH 11/26] The 86F handler now returns randomly generated noise for physical holes, rather than always 0. --- src/floppy/fdd_86f.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/floppy/fdd_86f.c b/src/floppy/fdd_86f.c index f456272a0..d9224686b 100644 --- a/src/floppy/fdd_86f.c +++ b/src/floppy/fdd_86f.c @@ -10,13 +10,13 @@ * data in the form of FM/MFM-encoded transitions) which also * forms the core of the emulator's floppy disk emulation. * - * Version: @(#)fdd_86f.c 1.0.17 2018/11/12 + * Version: @(#)fdd_86f.c 1.0.18 2019/11/08 * - * Authors: Fred N. van Kempen, - * Miran Grca, + * Authors: Miran Grca, + * Fred N. van Kempen, * - * Copyright 2018 Fred N. van Kempen. - * Copyright 2016-2018 Miran Grca. + * Copyright 2016-2019 Miran Grca. + * Copyright 2018,2019 Fred N. van Kempen. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1140,10 +1140,8 @@ d86f_get_bit(int drive, int side) if (! surface_bit) dev->last_word[side] |= current_bit; else { - if (current_bit) { - /* Bit is 1 and is set to fuzzy, we randomly generate it. */ - dev->last_word[side] |= (random_generate() & 1); - } + /* Bit is either 0 or 1 and is set to fuzzy, we randomly generate it. */ + dev->last_word[side] |= (random_generate() & 1); } } else dev->last_word[side] |= current_bit; From d3bdee4ae19199469419038ade473ebaf8c7cb2b Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 8 Nov 2019 23:45:05 +0100 Subject: [PATCH 12/26] Fixed the video RAM addresses in the text modes on the Sigma Color 400. --- src/video/vid_sigma.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/vid_sigma.c b/src/video/vid_sigma.c index 39d314ea8..3ad4a2a54 100644 --- a/src/video/vid_sigma.c +++ b/src/video/vid_sigma.c @@ -8,7 +8,7 @@ * * Sigma Color 400 emulation. * - * Version: @(#)vid_sigma.c 1.0.4 2019/05/23 + * Version: @(#)vid_sigma.c 1.0.5 2019/11/08 * * Authors: John Elliott, * @@ -422,7 +422,7 @@ static void sigma_text80(sigma_t *sigma) uint16_t ma = ((sigma->ma << 1) & 0x3FFF); int drawcursor; uint32_t cols[4]; - uint8_t *vram = sigma->vram + ((ma << 1) % 4000); + uint8_t *vram = sigma->vram + (ma & 0x3FFF); ca = ca << 1; if (sigma->sigma_ctl & CTL_CURSOR) @@ -475,10 +475,10 @@ sigma_text40(sigma_t *sigma) int x, c; uint8_t chr, attr; uint16_t ca = (sigma->crtc[15] | (sigma->crtc[14] << 8)); - uint16_t ma = ((sigma->ma & 0x3FFF) << 1); + uint16_t ma = ((sigma->ma << 1) & 0x3FFF); int drawcursor; uint32_t cols[4]; - uint8_t *vram = sigma->vram + ((ma << 1) & 0x3FFF); + uint8_t *vram = sigma->vram + (ma & 0x3FFF); ca = ca << 1; if (sigma->sigma_ctl & CTL_CURSOR) From fa4890c9db396b03b5f8186bad6c92892fd2d92a Mon Sep 17 00:00:00 2001 From: OBattler Date: Mon, 11 Nov 2019 06:07:50 +0100 Subject: [PATCH 13/26] Some fixes to the PC speaker - fixes amplitude in mode 1 (the intro of Perestroika now works correctly at least on the 8088 4.77 MHz) and makes the parameters consistent with the rest of the PC speaker emulation. --- src/sound/snd_speaker.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/sound/snd_speaker.c b/src/sound/snd_speaker.c index 9c40d5e89..799614fea 100644 --- a/src/sound/snd_speaker.c +++ b/src/sound/snd_speaker.c @@ -1,3 +1,21 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the PC speaker. + * + * Version: @(#)snd_speaker.c 1.0.0 2019/11/11 + * + * Authors: Sarah Walker, + * Miran Grca, + * + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. + */ #include #include #include @@ -23,20 +41,31 @@ void speaker_update(void) { int32_t val; + double timer2_count, amplitude; + + timer2_count = pit.l[2] ? ((double) pit.l[2]) : 65536.0; + amplitude = ((timer2_count / 64.0) * 10240.0) - 5120.0; + + if (amplitude > 5120.0) + amplitude = 5120.0; if (speaker_pos >= sound_pos_global) return; for (; speaker_pos < sound_pos_global; speaker_pos++) { if (speaker_gated && was_speaker_enable) { - if (!pit.m[2] || pit.m[2]==4) - val = speakval; + if ((pit.m[2] == 0) || (pit.m[2] == 4)) + val = (int32_t) amplitude; else if (pit.l[2] < 0x40) val = 0xa00; else val = speakon ? 0x1400 : 0; - } else - val = was_speaker_enable ? 0x1400 : 0; + } else { + if (pit.m[2] == 1) + val = was_speaker_enable ? (int32_t) amplitude : 0; + else + val = was_speaker_enable ? 0x1400 : 0; + } if (!speaker_enable) was_speaker_enable = 0; From 6cb88c27bd21286c08176a51b0a2f62cec489201 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 14 Nov 2019 06:14:48 +0100 Subject: [PATCH 14/26] Fixed the readback of the PC/XT FPU installed switch. --- src/keyboard_xt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/keyboard_xt.c b/src/keyboard_xt.c index 3bd7c6c8e..554b35b56 100644 --- a/src/keyboard_xt.c +++ b/src/keyboard_xt.c @@ -8,7 +8,7 @@ * * Implementation of the XT-style keyboard. * - * Version: @(#)keyboard_xt.c 1.0.17 2019/03/05 + * Version: @(#)keyboard_xt.c 1.0.18 2019/11/14 * * Authors: Sarah Walker, * Miran Grca, @@ -532,7 +532,7 @@ kbd_read(uint16_t port, void *priv) switch (port) { case 0x60: if ((kbd->type <= 1) && (kbd->pb & 0x80)) - ret = kbd->pd; + ret = (kbd->pd & ~0x02) | (hasfpu ? 0x02 : 0x00); else if (((kbd->type == 2) || (kbd->type == 3)) && (kbd->pb & 0x80)) ret = 0xff; /* According to Ruud on the PCem forum, this is supposed to return 0xFF on the XT. */ else @@ -559,10 +559,10 @@ kbd_read(uint16_t port, void *priv) LaserXT/3 = Bit 0: set = 512k, clear = 256k. */ #if defined(DEV_BRANCH) && defined(USE_LASERXT) if (kbd->type == 6) - ret = (mem_size == 512) ? 0x0d : 0x0c; + ret = ((mem_size == 512) ? 0x0d : 0x0c) | (hasfpu ? 0x02 : 0x00); else #endif - ret = kbd->pd & 0x0f; + ret = (kbd->pd & 0x0d) | (hasfpu ? 0x02 : 0x00); } } ret |= (ppispeakon ? 0x20 : 0); From 9912cc10fe454bda2933b9e5679f75478dcfdc61 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 14 Nov 2019 20:59:51 +0100 Subject: [PATCH 15/26] Added the ability to pause and resume the network thread's reception. --- src/network/net_pcap.c | 9 ++++++--- src/network/net_slirp.c | 6 +++--- src/network/network.c | 12 ++++++++++-- src/network/network.h | 7 +++++-- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index 60d2b07a4..e704d1b00 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -8,11 +8,11 @@ * * Handle WinPcap library processing. * - * Version: @(#)net_pcap.c 1.0.9 2018/10/19 + * Version: @(#)net_pcap.c 1.0.10 2019/11/14 * * Author: Fred N. van Kempen, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -185,7 +185,10 @@ poll_thread(void *arg) if (pcap == NULL) break; /* Wait for the next packet to arrive. */ - data = (uint8_t *)f_pcap_next((void *)pcap, &h); + if (network_wait) + data = NULL; + else + data = (uint8_t *)f_pcap_next((void *)pcap, &h); if (data != NULL) { // ui_sb_update_icon(SB_NETWORK, 1); diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index ec7bb1b09..a726d133d 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -8,11 +8,11 @@ * * Handle SLiRP library processing. * - * Version: @(#)net_slirp.c 1.0.8 2018/10/19 + * Version: @(#)net_slirp.c 1.0.9 2019/11/14 * * Author: Fred N. van Kempen, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -148,7 +148,7 @@ poll_thread(void *arg) /* Wait for the next packet to arrive. */ data_valid = 0; - if (QueuePeek(slirpq) != 0) { + if (!network_wait && (QueuePeek(slirpq) != 0)) { /* Grab a packet from the queue. */ // ui_sb_update_icon(SB_NETWORK, 1); diff --git a/src/network/network.c b/src/network/network.c index 0db312a39..a36d64b9d 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -12,11 +12,11 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.10 2018/11/18 + * Version: @(#)network.c 1.0.11 2019/11/14 * * Author: Fred N. van Kempen, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -99,6 +99,7 @@ static netcard_t net_cards[] = { int network_type; int network_ndev; int network_card; +volatile int network_wait; char network_host[522]; netdev_t network_devs[32]; #ifdef ENABLE_NIC_LOG @@ -442,3 +443,10 @@ network_card_get_from_internal_name(char *s) return(-1); } + + +void +network_set_wait(int wait) +{ + network_wait = wait; +} diff --git a/src/network/network.h b/src/network/network.h index bdd4beb54..e5c72ce5e 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -8,11 +8,11 @@ * * Definitions for the network module. * - * Version: @(#)network.h 1.0.2 2018/03/15 + * Version: @(#)network.h 1.0.3 2019/11/14 * * Author: Fred N. van Kempen, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * * Redistribution and use in source and binary forms, with * or without modification, are permitted provided that the @@ -89,6 +89,7 @@ extern "C" { /* Global variables. */ extern int nic_do_log; /* config */ extern int network_ndev; +extern volatile int network_wait; extern netdev_t network_devs[32]; @@ -124,6 +125,8 @@ extern char *network_card_get_internal_name(int); extern int network_card_get_from_internal_name(char *); extern const device_t *network_card_getdevice(int); +extern void network_set_wait(int wait); + #ifdef __cplusplus } #endif From aed984c265089a3c9ee63178728a15323c52ef45 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 14 Nov 2019 21:00:52 +0100 Subject: [PATCH 16/26] Fixed the state of network_wait. --- src/network/network.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/network/network.c b/src/network/network.c index a36d64b9d..869da50b3 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -12,7 +12,7 @@ * it should be malloc'ed and then linked to the NETCARD def. * Will be done later. * - * Version: @(#)network.c 1.0.11 2019/11/14 + * Version: @(#)network.c 1.0.12 2019/11/14 * * Author: Fred N. van Kempen, * @@ -99,7 +99,7 @@ static netcard_t net_cards[] = { int network_type; int network_ndev; int network_card; -volatile int network_wait; +volatile int network_wait = 0; char network_host[522]; netdev_t network_devs[32]; #ifdef ENABLE_NIC_LOG @@ -221,6 +221,8 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) net_cards[network_card].rx = rx; network_mac = mac; + network_wait = 0; + /* Create the network events. */ poll_data.wake_poll_thread = thread_create_event(); poll_data.poll_complete = thread_create_event(); From 841a1f67dafc78d3ea3fd54c6ead2438f8280880 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 14 Nov 2019 21:22:54 +0100 Subject: [PATCH 17/26] Fixed newly-introduced compile-breaking bugs in the network code. --- src/network/net_pcap.c | 2 +- src/network/net_slirp.c | 2 +- src/network/network.c | 20 +++++++++++++++++--- src/network/network.h | 2 +- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/src/network/net_pcap.c b/src/network/net_pcap.c index e704d1b00..5acc9c170 100644 --- a/src/network/net_pcap.c +++ b/src/network/net_pcap.c @@ -185,7 +185,7 @@ poll_thread(void *arg) if (pcap == NULL) break; /* Wait for the next packet to arrive. */ - if (network_wait) + if (network_get_wait()) data = NULL; else data = (uint8_t *)f_pcap_next((void *)pcap, &h); diff --git a/src/network/net_slirp.c b/src/network/net_slirp.c index a726d133d..8b8304854 100644 --- a/src/network/net_slirp.c +++ b/src/network/net_slirp.c @@ -148,7 +148,7 @@ poll_thread(void *arg) /* Wait for the next packet to arrive. */ data_valid = 0; - if (!network_wait && (QueuePeek(slirpq) != 0)) { + if (!network_get_wait() && (QueuePeek(slirpq) != 0)) { /* Grab a packet from the queue. */ // ui_sb_update_icon(SB_NETWORK, 1); diff --git a/src/network/network.c b/src/network/network.c index 869da50b3..6cff7945d 100644 --- a/src/network/network.c +++ b/src/network/network.c @@ -99,7 +99,7 @@ static netcard_t net_cards[] = { int network_type; int network_ndev; int network_card; -volatile int network_wait = 0; +static volatile int net_wait = 0; char network_host[522]; netdev_t network_devs[32]; #ifdef ENABLE_NIC_LOG @@ -221,7 +221,7 @@ network_attach(void *dev, uint8_t *mac, NETRXCB rx) net_cards[network_card].rx = rx; network_mac = mac; - network_wait = 0; + network_set_wait(0); /* Create the network events. */ poll_data.wake_poll_thread = thread_create_event(); @@ -450,5 +450,19 @@ network_card_get_from_internal_name(char *s) void network_set_wait(int wait) { - network_wait = wait; + network_wait(1); + net_wait = wait; + network_wait(0); +} + + +int +network_get_wait(void) +{ + int ret; + + network_wait(1); + ret = net_wait; + network_wait(0); + return ret; } diff --git a/src/network/network.h b/src/network/network.h index e5c72ce5e..feae064ee 100644 --- a/src/network/network.h +++ b/src/network/network.h @@ -89,7 +89,6 @@ extern "C" { /* Global variables. */ extern int nic_do_log; /* config */ extern int network_ndev; -extern volatile int network_wait; extern netdev_t network_devs[32]; @@ -126,6 +125,7 @@ extern int network_card_get_from_internal_name(char *); extern const device_t *network_card_getdevice(int); extern void network_set_wait(int wait); +extern int network_get_wait(void); #ifdef __cplusplus } From e4408bc84db9460ad541d6e3e635d4b37fd97542 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 19 Nov 2019 04:35:54 +0100 Subject: [PATCH 18/26] Fixed CD-ROM timings on the NCR 53x8xx SCSI controllers, the IDE_TIME, CDROM_TIME, and ZIP_TIME values, and the delay added to the CD-ROM READ SUBCHANNEL command, fixes slowdowns on several games that use CD Audio, such as Tomb Raider II. --- src/disk/hdc_ide.c | 61 +++++++++++++++++++++++++-------------- src/disk/hdc_ide.h | 7 +++-- src/disk/zip.c | 32 +++++++++++++++----- src/disk/zip.h | 6 ++-- src/scsi/scsi_cdrom.c | 18 +++++++----- src/scsi/scsi_cdrom.h | 6 ++-- src/scsi/scsi_ncr53c8xx.c | 25 ++++++++-------- 7 files changed, 97 insertions(+), 58 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index bd1931222..a9d1e8e59 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -9,7 +9,7 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdc_ide.c 1.0.64 2019/11/06 + * Version: @(#)hdc_ide.c 1.0.65 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -109,7 +109,7 @@ #define FEATURE_DISABLE_IRQ_OVERLAPPED 0xdd #define FEATURE_DISABLE_IRQ_SERVICE 0xde -#define IDE_TIME 20.0 / 3.0 +#define IDE_TIME 10.0 typedef struct { @@ -175,70 +175,72 @@ ide_get_drive(int ch) double ide_get_period(ide_t *ide, int size) { - double period = 10.0 / 3.0; + double period = (10.0 / 3.0); + /* We assume that 1 MB = 1000000 B in this case, so we have as + many B/us as there are MB/s because 1 s = 1000000 us. */ switch(ide->mdma_mode & 0x300) { case 0x000: /* PIO */ switch(ide->mdma_mode & 0xff) { case 0: - period = 10.0 / 3.0; + period = (10.0 / 3.0); break; case 1: - period = (period * 600.0) / 383.0; + period = (20.0 / 3.83); break; case 2: - period = 25.0 / 3.0; + period = (25.0 / 3.0); break; case 3: - period = 100.0 / 9.0; + period = (100.0 / 9.0); break; case 4: - period = 50.0 / 3.0; + period = (50.0 / 3.0); break; } break; case 0x100: /* Single Word DMA */ switch(ide->mdma_mode & 0xff) { case 0: - period = 25.0 / 12.0; + period = (25.0 / 12.0); break; case 1: - period = 25.0 / 6.0; + period = (25.0 / 6.0); break; case 2: - period = 25.0 / 3.0; + period = (25.0 / 3.0); break; } break; case 0x200: /* Multiword DMA */ switch(ide->mdma_mode & 0xff) { case 0: - period = 25.0 / 6.0; + period = (25.0 / 6.0); break; case 1: - period = 40.0 / 3.0; + period = (40.0 / 3.0); break; case 2: - period = 50.0 / 3.0; + period = (50.0 / 3.0); break; } break; case 0x300: /* Ultra DMA */ switch(ide->mdma_mode & 0xff) { case 0: - period = 50.0 / 3.0; + period = (50.0 / 3.0); break; case 1: period = 25.0; break; case 2: - period = 100.0 / 3.0; + period = (100.0 / 3.0); break; case 3: - period = 400.0 / 9.0; + period = (400.0 / 9.0); break; case 4: - period = 200.0 / 3.0; + period = (200.0 / 3.0); break; case 5: period = 100.0; @@ -247,9 +249,26 @@ ide_get_period(ide_t *ide, int size) break; } - period *= 1048576.0; /* period * MB - get bytes per second */ - period = ((double) size) / period; /* size / period to get seconds */ - return period * 1000000.0; /* return seconds * 1000000 to convert to us */ + period = (10.0 / 3.0); + + period = (1.0 / period); /* get us for 1 byte */ + return period * ((double) size); /* multiply by bytes to get period for the entire transfer */ +} + + +double +ide_atapi_get_period(uint8_t channel) +{ + ide_t *ide = ide_drives[channel]; + + ide_log("ide_atapi_get_period(%i)\n", channel); + + if (!ide) { + ide_log("Get period failed\n"); + return -1.0; + } + + return ide_get_period(ide, 1); } diff --git a/src/disk/hdc_ide.h b/src/disk/hdc_ide.h index b2f96807a..b1e172748 100644 --- a/src/disk/hdc_ide.h +++ b/src/disk/hdc_ide.h @@ -9,12 +9,12 @@ * Implementation of the IDE emulation for hard disks and ATAPI * CD-ROM devices. * - * Version: @(#)hdd_ide.h 1.0.15 2018/10/31 + * Version: @(#)hdd_ide.h 1.0.16 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, - * Copyright 2008-2018 Sarah Walker. - * Copyright 2016-2018 Miran Grca. + * Copyright 2008-2019 Sarah Walker. + * Copyright 2016-2019 Miran Grca. */ #ifndef EMU_IDE_H # define EMU_IDE_H @@ -130,6 +130,7 @@ extern void ide_pri_disable(void); extern void ide_sec_enable(void); extern void ide_sec_disable(void); +extern double ide_atapi_get_period(uint8_t channel); extern void ide_set_callback(uint8_t channel, double callback); extern void ide_padstr(char *str, const char *src, int len); diff --git a/src/disk/zip.c b/src/disk/zip.c index 2da62f4af..60c775810 100644 --- a/src/disk/zip.c +++ b/src/disk/zip.c @@ -9,11 +9,11 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.c 1.0.37 2018/11/02 + * Version: @(#)zip.c 1.0.38 2019/11/19 * * Author: Miran Grca, * - * Copyright 2018 Miran Grca. + * Copyright 2018,2019 Miran Grca. */ #include #include @@ -854,6 +854,26 @@ zip_update_request_length(zip_t *dev, int len, int block_len) } +static double +zip_bus_speed(zip_t *dev) +{ + double ret = -1.0; + + if (dev->drv->bus_type == ZIP_BUS_SCSI) { + dev->callback = -1.0; /* Speed depends on SCSI controller */ + return 0.0; + } else { + if (dev && dev->drv) + ret = ide_atapi_get_period(dev->drv->ide_channel); + if (ret == -1.0) { + dev->callback = -1.0; + return 0.0; + } else + return ret * 1000000.0; + } +} + + static void zip_command_common(zip_t *dev) { @@ -868,12 +888,8 @@ zip_command_common(zip_t *dev) if (dev->drv->bus_type == ZIP_BUS_SCSI) { dev->callback = -1.0; /* Speed depends on SCSI controller */ return; - } else { - if (zip_current_mode(dev) == 2) - bytes_per_second = 66666666.666666666666666; /* 66 MB/s MDMA-2 speed */ - else - bytes_per_second = 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ - } + } else + bytes_per_second = zip_bus_speed(dev); period = 1000000.0 / bytes_per_second; dev->callback = period * (double) (dev->packet_len); diff --git a/src/disk/zip.h b/src/disk/zip.h index b36b7e6bd..02c355472 100644 --- a/src/disk/zip.h +++ b/src/disk/zip.h @@ -9,11 +9,11 @@ * Implementation of the Iomega ZIP drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)zip.h 1.0.9 2018/10/31 + * Version: @(#)zip.h 1.0.10 2019/11/19 * * Author: Miran Grca, * - * Copyright 2018 Miran Grca. + * Copyright 2018,2019 Miran Grca. */ #ifndef EMU_ZIP_H #define EMU_ZIP_H @@ -23,7 +23,7 @@ #define BUF_SIZE 32768 -#define ZIP_TIME 500.0 +#define ZIP_TIME 10.0 #define ZIP_SECTORS (96*2048) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index 846ef8ef7..045c78fa9 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -9,7 +9,7 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)scsi_cdrom.c 1.0.71 2019/09/26 + * Version: @(#)scsi_cdrom.c 1.0.72 2019/11/19 * * Author: Miran Grca, * @@ -604,15 +604,19 @@ scsi_cdrom_update_request_length(scsi_cdrom_t *dev, int len, int block_len) static double scsi_cdrom_bus_speed(scsi_cdrom_t *dev) { + double ret = -1.0; + if (dev->drv->bus_type == CDROM_BUS_SCSI) { dev->callback = -1.0; /* Speed depends on SCSI controller */ return 0.0; } else { - /* TODO: Get the actual selected speed from IDE. */ - if (scsi_cdrom_current_mode(dev) == 2) - return 66666666.666666666666666; /* 66 MB/s MDMA-2 speed */ - else - return 8333333.333333333333333; /* 8.3 MB/s PIO-2 speed */ + if (dev && dev->drv) + ret = ide_atapi_get_period(dev->drv->ide_channel); + if (ret == -1.0) { + dev->callback = -1.0; + return 0.0; + } else + return ret * 1000000.0; } } @@ -663,7 +667,7 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) case 0xb9: case 0xbe: if (dev->current_cdb[0] == 0x42) - dev->callback += 200.0 * CDROM_TIME; + dev->callback += 40.0; /* Account for seek time. */ bytes_per_second = 176.0 * 1024.0; bytes_per_second *= (double) dev->drv->cur_speed; diff --git a/src/scsi/scsi_cdrom.h b/src/scsi/scsi_cdrom.h index f83c6457c..1c8be1382 100644 --- a/src/scsi/scsi_cdrom.h +++ b/src/scsi/scsi_cdrom.h @@ -9,17 +9,17 @@ * Implementation of the CD-ROM drive with SCSI(-like) * commands, for both ATAPI and SCSI usage. * - * Version: @(#)scsi_cdrom.h 1.0.1 2018/10/17 + * Version: @(#)scsi_cdrom.h 1.0.2 2019/11/19 * * Author: Miran Grca, * - * Copyright 2018 Miran Grca. + * Copyright 2018,2019 Miran Grca. */ #ifndef EMU_SCSI_CDROM_H #define EMU_SCSI_CDROM_H -#define CDROM_TIME 500.0 +#define CDROM_TIME 10.0 #ifdef SCSI_DEVICE_H diff --git a/src/scsi/scsi_ncr53c8xx.c b/src/scsi/scsi_ncr53c8xx.c index 65b680483..56af023a1 100644 --- a/src/scsi/scsi_ncr53c8xx.c +++ b/src/scsi/scsi_ncr53c8xx.c @@ -13,7 +13,7 @@ * To do: Identify the type of serial EEPROM used and its * interface. * - * Version: @(#)scsi_ncr53c8xx.c 1.0.17 2018/10/30 + * Version: @(#)scsi_ncr53c8xx.c 1.0.18 2019/11/19 * * Authors: Paul Brook (QEMU) * Artyom Tarasenko (QEMU) @@ -705,10 +705,12 @@ ncr53c8xx_add_msg_byte(ncr53c8xx_t *dev, uint8_t data) static void ncr53c8xx_timer_on(ncr53c8xx_t *dev, scsi_device_t *sd, double p) { - if (p <= 0) - timer_on_auto(&dev->timer, ((double) sd->buffer_length) * 0.1); /* Fast SCSI: 10000000 bytes per second */ - else - timer_on_auto(&dev->timer, p); + double period; + + /* Fast SCSI: 10000000 bytes per second */ + period = (p > 0.0) ? p : (((double) sd->buffer_length) * 0.1); + + timer_on_auto(&dev->timer, period + 40.0); } @@ -1023,11 +1025,12 @@ again: /* If we receive an empty opcode increment the DSP by 4 bytes instead of 8 and execute the next opcode at that location */ dev->dsp += 4; - timer_on_auto(&dev->timer, 10.0); if (insn_processed < 100) goto again; - else + else { + timer_on_auto(&dev->timer, 10.0); return; + } } addr = read_dword(dev, dev->dsp + 4); ncr53c8xx_log("SCRIPTS dsp=%08x opcode %08x arg %08x\n", dev->dsp, insn, addr); @@ -1093,8 +1096,6 @@ again: dev->dfifo = dev->dbc & 0xff; dev->ctest5 = (dev->ctest5 & 0xfc) | ((dev->dbc >> 8) & 3); - timer_on_auto(&dev->timer, 40.0); - if (dev->dcntl & NCR_DCNTL_SSM) ncr53c8xx_script_dma_interrupt(dev, NCR_DSTAT_SSI); return; @@ -1363,8 +1364,6 @@ again: ncr53c8xx_log("%02X: Unknown command\n", (uint8_t) (insn >> 30)); } - timer_on_auto(&dev->timer, 40.0); - ncr53c8xx_log("instructions processed %i\n", insn_processed); if (insn_processed > 10000 && !dev->waiting) { /* Some windows drivers make the device spin waiting for a memory @@ -1393,6 +1392,8 @@ again: ncr53c8xx_log("NCR 810: SCRIPTS: Waiting\n"); } + timer_on_auto(&dev->timer, 40.0); + ncr53c8xx_log("SCRIPTS execution stopped\n"); } @@ -1419,8 +1420,6 @@ ncr53c8xx_callback(void *p) if (dev->sstop) timer_stop(&dev->timer); - else - timer_on_auto(&dev->timer, 10.0); } From b5ba9eafe30d1a6fa91e03f7ed30fb2534f0aaf4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 19 Nov 2019 04:41:42 +0100 Subject: [PATCH 19/26] The Award 286 Clone no longer has on-board IDE - the machine technically has it, but it can be disabled, so the easiest way to do it on the emulator is to make the user choose the IDE controller if they need it, and tell the BIOS to use it. --- src/machine/m_at_286_386sx.c | 4 +--- src/machine/machine_table.c | 4 ++-- src/machine/machine_table_new.c | 4 ++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/machine/m_at_286_386sx.c b/src/machine/m_at_286_386sx.c index 4ff2476ae..c2730db1c 100644 --- a/src/machine/m_at_286_386sx.c +++ b/src/machine/m_at_286_386sx.c @@ -8,7 +8,7 @@ * * Implementation of 286 and 386SX machines. * - * Version: @(#)m_at_286_386sx.c 1.0.1 2019/11/01 + * Version: @(#)m_at_286_386sx.c 1.0.2 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -203,8 +203,6 @@ machine_at_award286_init(const machine_t *model) machine_at_scat_init(model, 0); - device_add(&ide_isa_device); - return ret; } diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 5f173e3f4..eb4786c07 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -11,7 +11,7 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.49 2019/11/01 + * Version: @(#)machine_table.c 1.0.50 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -86,7 +86,7 @@ const machine_t machines[] = { #endif { "[286 ISA] AMI 286 clone", "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL }, - { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_award286_init, NULL }, + { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_award286_init, NULL }, { "[286 ISA] Commodore PC 30 III", "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL }, { "[286 ISA] Compaq Portable II", "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_portableii_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_PORTABLE3) diff --git a/src/machine/machine_table_new.c b/src/machine/machine_table_new.c index 016f2fb8b..e598db7da 100644 --- a/src/machine/machine_table_new.c +++ b/src/machine/machine_table_new.c @@ -11,7 +11,7 @@ * NOTES: OpenAT wip for 286-class machine with open BIOS. * PS2_M80-486 wip, pending receipt of TRM's for machine. * - * Version: @(#)machine_table.c 1.0.49 2019/11/01 + * Version: @(#)machine_table.c 1.0.50 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -73,7 +73,7 @@ const machine_t machines[] = { #endif { "[286 ISA] AMI 286 clone", "ami286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512, 8192, 128, 127, machine_at_neat_ami_init, NULL }, - { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT | MACHINE_HDC, 512,16384, 128, 127, machine_at_award286_init, NULL }, + { "[286 ISA] Award 286 clone", "award286", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 512,16384, 128, 127, machine_at_award286_init, NULL }, { "[286 ISA] Commodore PC 30 III", "cmdpc30", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_cmdpc_init, NULL }, { "[286 ISA] Compaq Portable II", "portableii", {{"", cpus_286}, {"", NULL}, {"", NULL}, {"", NULL}, {"", NULL}}, MACHINE_ISA | MACHINE_AT, 640,16384, 128, 127, machine_at_portableii_init, NULL }, #if defined(DEV_BRANCH) && defined(USE_PORTABLE3) From 0d97fadb6e143ce0eaf9b70415430ba240342afe Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 19 Nov 2019 04:44:43 +0100 Subject: [PATCH 20/26] Some quick fixes for the IBM PS/2 Model 30-286. The hard disk controller is the same as the PS/1 one, and will be properly fixed in v2.10. --- src/machine/m_ps2_isa.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index a9699ba5b..cf1cb45d2 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -57,7 +57,8 @@ static uint8_t ps2_read(uint16_t port, void *p) return ps2_105; case 0x190: return ps2_190; - + +#ifdef FIXME case 0x322: temp = ps2_hd.status; break; @@ -65,6 +66,7 @@ static uint8_t ps2_read(uint16_t port, void *p) temp = ps2_hd.int_status; ps2_hd.int_status &= ~0x02; break; +#endif default: temp = 0xff; @@ -116,7 +118,8 @@ static void ps2_write(uint16_t port, uint8_t val, void *p) case 0x190: ps2_190 = val; break; - + +#ifdef FIXME case 0x322: ps2_hd.ctrl = val; if (val & 0x80) @@ -127,6 +130,7 @@ static void ps2_write(uint16_t port, uint8_t val, void *p) if (ps2_hd.attention) ps2_hd.status = 0x14; break; +#endif } } @@ -137,15 +141,17 @@ static void ps2board_init(void) io_sethandler(0x0094, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); io_sethandler(0x0102, 0x0004, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); io_sethandler(0x0190, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); +#ifdef FIXME io_sethandler(0x0320, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); io_sethandler(0x0322, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); io_sethandler(0x0324, 0x0001, ps2_read, NULL, NULL, ps2_write, NULL, NULL, NULL); +#endif device_add(&port_92_device); ps2_190 = 0; - ps2_uart = device_add_inst(&i8250_device, 1); + ps2_uart = device_add_inst(&i16450_device, 1); lpt1_init(0x3bc); From 26009044d735b8dab89a8d3e28a6b953ab0e852f Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 19 Nov 2019 04:47:00 +0100 Subject: [PATCH 21/26] Some changes to the (AT) NVR code. --- src/nvr.c | 4 +-- src/nvr_at.c | 93 ++++++++++++++++++++-------------------------------- 2 files changed, 38 insertions(+), 59 deletions(-) diff --git a/src/nvr.c b/src/nvr.c index fe0cfd006..53376295f 100644 --- a/src/nvr.c +++ b/src/nvr.c @@ -8,7 +8,7 @@ * * Implement a generic NVRAM/CMOS/RTC device. * - * Version: @(#)nvr.c 1.0.18 2019/03/16 + * Version: @(#)nvr.c 1.0.19 2019/11/19 * * Authors: Fred N. van Kempen, , * David Hrdlička, @@ -156,7 +156,7 @@ onesec_timer(void *priv) nvr->onesec_cnt = 0; } - timer_advance_u64(&nvr->onesec_time, (10000ULL * TIMER_USEC)); + timer_advance_u64(&nvr->onesec_time, (uint64_t)(10000ULL * TIMER_USEC)); } diff --git a/src/nvr_at.c b/src/nvr_at.c index b023ca332..967f14018 100644 --- a/src/nvr_at.c +++ b/src/nvr_at.c @@ -189,7 +189,7 @@ * including the later update (DS12887A) which implemented a * "century" register to be compatible with Y2K. * - * Version: @(#)nvr_at.c 1.0.15 2019/03/16 + * Version: @(#)nvr_at.c 1.0.16 2019/11/19 * * Authors: Fred N. van Kempen, * Miran Grca, @@ -292,6 +292,8 @@ typedef struct { uint8_t addr; + int16_t count, state; + uint64_t ecount, rtc_time; pc_timer_t update_timer, @@ -450,43 +452,29 @@ timer_update(void *priv) } -static double -timer_nvr_period(nvr_t *nvr) +static void +timer_load_count(nvr_t *nvr) { - double dusec = (double) TIMER_USEC; + int c = nvr->regs[RTC_REGA] & REGA_RS; + local_t *local = (local_t *) nvr->data; - switch (nvr->regs[RTC_REGA] & REGA_RS) { + if ((nvr->regs[RTC_REGA] & 0x70) != 0x20) { + local->state = 0; + return; + } + + local->state = 1; + + switch (c) { case 0: + local->state = 0; + break; + case 1: case 2: + local->count = 1 << (c + 6); + break; default: - return 0.0; - case 1: - case 8: - return 3906.25 * dusec; - case 2: - case 9: - return 7812.5 * dusec; - case 3: - return 122.070 * dusec; - case 4: - return 244.141 * dusec; - case 5: - return 488.281 * dusec; - case 6: - return 976.5625 * dusec; - case 7: - return 1953.125 * dusec; - case 10: - return 15625.0 * dusec; - case 11: - return 31250.0 * dusec; - case 12: - return 62500.0 * dusec; - case 13: - return 125000.0 * dusec; - case 14: - return 250000.0 * dusec; - case 15: - return 500000.0 * dusec; + local->count = 1 << (c - 1); + break; } } @@ -497,13 +485,16 @@ timer_intr(void *priv) nvr_t *nvr = (nvr_t *)priv; local_t *local = (local_t *)nvr->data; - if (nvr->regs[RTC_REGA] & REGA_RS) { - local->rtc_time = timer_nvr_period(nvr); - timer_advance_u64(&local->rtc_timer, (uint64_t) local->rtc_time); - } else { - local->rtc_time = 0ULL; + timer_advance_u64(&local->rtc_timer, RTCCONST); + + if (local->state == 1) { + local->count--; + if (local->count == 0) + timer_load_count(nvr); + else + return; + } else return; - } nvr->regs[RTC_REGC] |= REGC_PF; if (nvr->regs[RTC_REGB] & REGB_PIE) { @@ -536,20 +527,6 @@ timer_tick(nvr_t *nvr) } -static void -nvr_pie_start(nvr_t *nvr) -{ - local_t *local = (local_t *)nvr->data; - - local->rtc_time = 0ULL; - timer_disable(&local->rtc_timer); - if ((nvr->regs[RTC_REGA] & REGA_RS) && ((nvr->regs[RTC_REGA] & 0x70) == 0x20)) { - local->rtc_time = timer_nvr_period(nvr); - timer_set_delay_u64(&local->rtc_timer, local->rtc_time); - } -} - - /* Write to one of the NVR registers. */ static void nvr_write(uint16_t addr, uint8_t val, void *priv) @@ -566,7 +543,7 @@ nvr_write(uint16_t addr, uint8_t val, void *priv) switch(local->addr) { case RTC_REGA: nvr->regs[RTC_REGA] = val; - nvr_pie_start(nvr); + timer_load_count(nvr); break; case RTC_REGB: @@ -704,8 +681,7 @@ nvr_at_speed_changed(void *priv) local_t *local = (local_t *) nvr->data; timer_disable(&local->rtc_timer); - if (local->rtc_time > 0ULL) - timer_set_delay_u64(&local->rtc_timer, local->rtc_time); + timer_set_delay_u64(&local->rtc_timer, RTCCONST); timer_disable(&local->update_timer); if (local->ecount > 0ULL) @@ -774,7 +750,10 @@ nvr_at_init(const device_t *info) /* Start the timers. */ timer_add(&local->update_timer, timer_update, nvr, 0); + timer_add(&local->rtc_timer, timer_intr, nvr, 0); + timer_load_count(nvr); + timer_set_delay_u64(&local->rtc_timer, RTCCONST); /* Set up the I/O handler for this device. */ io_sethandler(0x0070, 2, From 4d39da9cfe0d1f0df099fed9e33ce866c66e5e6b Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 19 Nov 2019 04:52:24 +0100 Subject: [PATCH 22/26] Applied Ryuzaki's fixes for the New Floppy/ZIP Image and Settings dialog progress bars, those now work correctly. --- src/win/win_new_floppy.c | 8 +++++++- src/win/win_settings.c | 26 ++++++++++++++++---------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/win/win_new_floppy.c b/src/win/win_new_floppy.c index b6d4e5f64..0dff080c9 100644 --- a/src/win/win_new_floppy.c +++ b/src/win/win_new_floppy.c @@ -8,7 +8,7 @@ * * Handle the New Floppy Image dialog. * - * Version: @(#)win_new_floppy.c 1.0.12 2019/10/22 + * Version: @(#)win_new_floppy.c 1.0.13 2019/11/19 * * Authors: Miran Grca, * @@ -302,6 +302,7 @@ create_zip_sector_image(WCHAR *file_name, disk_size_t disk_size, uint8_t is_zdi, uint16_t base = 0x1000; uint32_t pbar_max = 0; uint32_t i; + MSG msg; f = plat_fopen(file_name, L"wb"); if (!f) @@ -496,6 +497,11 @@ create_zip_sector_image(WCHAR *file_name, disk_size_t disk_size, uint8_t is_zdi, for (i = 0; i < pbar_max; i++) { fwrite(&empty[i << 11], 1, 2048, f); SendMessage(h, PBM_SETPOS, (WPARAM) i + 2, (LPARAM) 0); + + while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } } free(empty); diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 5fda27cf3..480b55163 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.60 2019/11/02 + * Version: @(#)win_settings.c 1.0.61 2019/11/19 * * Authors: Miran Grca, * David Hrdlička, @@ -2515,6 +2515,7 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM uint8_t id = 0; wchar_t *twcs; vhd_footer_t *vft = NULL; + MSG msg; switch (message) { case WM_INITDIALOG: @@ -2672,7 +2673,8 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM fwrite(&zero, 1, 4, f); /* 00000004: [Translation] Heads per cylinder */ } - memset(buf, 0, 512); + big_buf = (char *) malloc(1048576); + memset(big_buf, 0, 1048576); temp_size = size; @@ -2703,19 +2705,23 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM ShowWindow(h, SW_SHOW); } + h = GetDlgItem(hdlg, IDC_PBAR_IMG_CREATE); + if (size) { - fwrite(buf, 1, size, f); + fwrite(big_buf, 1, size, f); SendMessage(h, PBM_SETPOS, (WPARAM) 1, (LPARAM) 0); } if (r) { - big_buf = (char *) malloc(1048576); - memset(big_buf, 0, 1048576); for (i = 0; i < r; i++) { fwrite(big_buf, 1, 1048576, f); SendMessage(h, PBM_SETPOS, (WPARAM) (size + 1), (LPARAM) 0); + + while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } } - free(big_buf); } if (image_is_vhd(hd_file_name, 0)) { @@ -2727,14 +2733,14 @@ win_settings_hard_disks_add_proc(HWND hdlg, UINT message, WPARAM wParam, LPARAM vft->geom.heads = hpc; vft->geom.spt = spt; generate_vhd_checksum(vft); - memset(buf, 0, 512); - vhd_footer_to_bytes((uint8_t *) buf, vft); - fwrite(buf, 1, 512, f); - memset(buf, 0, 512); + vhd_footer_to_bytes((uint8_t *) big_buf, vft); + fwrite(big_buf, 1, 512, f); free(vft); vft = NULL; } + free(big_buf); + fclose(f); settings_msgbox(MBX_INFO, (wchar_t *)IDS_4113); } From 3cc320d2b20c3a22154d304a6330dca250e3e41b Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 19 Nov 2019 07:48:49 +0100 Subject: [PATCH 23/26] Increased maximum ESDI sectors 99 and fixed the cylinders truncation in config.c. --- src/config.c | 9 +++++++-- src/win/win_settings.c | 12 ++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/config.c b/src/config.c index 361458c16..51a5a70d6 100644 --- a/src/config.c +++ b/src/config.c @@ -8,7 +8,7 @@ * * Configuration file handler. * - * Version: @(#)config.c 1.0.63 2019/10/21 + * Version: @(#)config.c 1.0.64 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -837,13 +837,18 @@ load_hard_disks(void) max_tracks = 1023; break; - case HDD_BUS_ESDI: case HDD_BUS_XTA: max_spt = 63; max_hpc = 16; max_tracks = 1023; break; + case HDD_BUS_ESDI: + max_spt = 99; + max_hpc = 16; + max_tracks = 266305; + break; + case HDD_BUS_IDE: max_spt = 63; max_hpc = 16; diff --git a/src/win/win_settings.c b/src/win/win_settings.c index 480b55163..ed6747d5a 100644 --- a/src/win/win_settings.c +++ b/src/win/win_settings.c @@ -8,7 +8,7 @@ * * Windows 86Box Settings dialog handler. * - * Version: @(#)win_settings.c 1.0.61 2019/11/19 + * Version: @(#)win_settings.c 1.0.62 2019/11/19 * * Authors: Miran Grca, * David Hrdlička, @@ -3061,16 +3061,16 @@ hdd_add_file_open_error: max_hpc = 15; max_tracks = 1023; break; - case HDD_BUS_ESDI: - max_spt = 43; /* ESDI drives usually had 32 to 43 sectors per track. */ - max_hpc = 16; - max_tracks = 266305; - break; case HDD_BUS_XTA: max_spt = 63; max_hpc = 16; max_tracks = 1023; break; + case HDD_BUS_ESDI: + max_spt = 99; /* ESDI drives usually had 32 to 43 sectors per track. */ + max_hpc = 16; + max_tracks = 266305; + break; case HDD_BUS_IDE: max_spt = 63; max_hpc = 255; From ac0a1ee327de845bcfe193778c24780839310b7f Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 19 Nov 2019 19:18:44 +0100 Subject: [PATCH 24/26] Fixed EGA and (S)VGA pel panning, fixes games like Supaplex. --- src/video/vid_ega.c | 12 +++++++--- src/video/vid_ega_render.c | 16 ++++++------- src/video/vid_svga.c | 30 +++++++++++++++-------- src/video/vid_svga_render.c | 48 ++++++++++++++++++------------------- 4 files changed, 61 insertions(+), 45 deletions(-) diff --git a/src/video/vid_ega.c b/src/video/vid_ega.c index fac75e163..acda3edde 100644 --- a/src/video/vid_ega.c +++ b/src/video/vid_ega.c @@ -9,7 +9,7 @@ * Emulation of the EGA and Chips & Technologies SuperEGA * graphics cards. * - * Version: @(#)vid_ega.c 1.0.22 2019/10/03 + * Version: @(#)vid_ega.c 1.0.23 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -389,9 +389,13 @@ ega_poll(void *p) ega->displine <<= 1; ega->y_add <<= 1; - ega_render_overscan_left(ega); ega->render(ega); + + ega->x_add = (overscan_x >> 1); + ega_render_overscan_left(ega); ega_render_overscan_right(ega); + ega->x_add = (overscan_x >> 1) - ega->scrollcache; + ega->displine++; ega->ma = old_ma; @@ -454,8 +458,10 @@ ega_poll(void *p) if (ega->vc == ega->split) { ega->ma = ega->maback = 0; ega->sc = 0; - if (ega->attrregs[0x10] & 0x20) + if (ega->attrregs[0x10] & 0x20) { ega->scrollcache = 0; + ega->x_add = (overscan_x >> 1); + } } if (ega->vc == ega->dispend) { ega->dispon = 0; diff --git a/src/video/vid_ega_render.c b/src/video/vid_ega_render.c index e5bcc9fb0..cf5ec7d50 100644 --- a/src/video/vid_ega_render.c +++ b/src/video/vid_ega_render.c @@ -8,7 +8,7 @@ * * EGA renderers. * - * Version: @(#)vid_ega_render.c 1.0.6 2019/10/03 + * Version: @(#)vid_ega_render.c 1.0.7 2019/11/19 * * Author: Sarah Walker, * Miran Grca, @@ -53,7 +53,7 @@ ega_render_blank(ega_t *ega) if ((ega->displine + ega->y_add) < 0) return; - for (x = 0; x < ega->hdisp; x++) { + for (x = 0; x < (ega->hdisp + ega->scrollcache); x++) { switch (ega->seqregs[1] & 9) { case 0: for (xx = 0; xx < 9; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 9) + xx] = 0; @@ -120,7 +120,7 @@ ega_render_text_40(ega_t *ega) p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; xinc = (ega->seqregs[1] & 1) ? 16 : 18; - for (x = 0; x < ega->hdisp; x += xinc) { + for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) { drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); chr = ega->vram[(ega->ma << 1) & ega->vrammask]; attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; @@ -183,7 +183,7 @@ ega_render_text_80(ega_t *ega) p = &buffer32->line[ega->displine + ega->y_add][ega->x_add]; xinc = (ega->seqregs[1] & 1) ? 8 : 9; - for (x = 0; x < ega->hdisp; x += xinc) { + for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) { drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron); chr = ega->vram[(ega->ma << 1) & ega->vrammask]; attr = ega->vram[((ega->ma << 1) + 1) & ega->vrammask]; @@ -240,7 +240,7 @@ ega_render_2bpp_lowres(ega_t *ega) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; - for (x = 0; x <= ega->hdisp; x += 16) { + for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) { addr = ega->ma; if (!(ega->crtc[0x17] & 0x40)) { @@ -299,7 +299,7 @@ ega_render_2bpp_highres(ega_t *ega) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; - for (x = 0; x <= ega->hdisp; x += 8) { + for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) { addr = ega->ma; if (!(ega->crtc[0x17] & 0x40)) { @@ -358,7 +358,7 @@ ega_render_4bpp_lowres(ega_t *ega) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; - for (x = 0; x <= ega->hdisp; x += 16) { + for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) { addr = ega->ma; oddeven = 0; @@ -431,7 +431,7 @@ ega_render_4bpp_highres(ega_t *ega) ega->firstline_draw = ega->displine; ega->lastline_draw = ega->displine; - for (x = 0; x <= ega->hdisp; x += 8) { + for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) { addr = ega->ma; oddeven = 0; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index c3c31ef59..d2f7e45a3 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -11,7 +11,7 @@ * This is intended to be used by another SVGA driver, * and not as a card in it's own right. * - * Version: @(#)vid_svga.c 1.0.37 2019/10/21 + * Version: @(#)vid_svga.c 1.0.38 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -530,10 +530,13 @@ svga_recalctimings(svga_t *svga) overscan_y = 16; } - overscan_x = (svga->seqregs[1] & 1) ? 16 : 18; + if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { + overscan_x = (svga->seqregs[1] & 1) ? 16 : 18; - if (svga->seqregs[1] & 8) - overscan_x <<= 1; + if (svga->seqregs[1] & 8) + overscan_x <<= 1; + } else + overscan_x = 16; if (svga->recalctimings_ex) svga->recalctimings_ex(svga); @@ -553,6 +556,7 @@ svga_recalctimings(svga_t *svga) disptime *= 2; _dispontime *= 2; } + _dispofftime = disptime - _dispontime; _dispontime *= crtcconst; _dispofftime *= crtcconst; @@ -572,6 +576,7 @@ svga_poll(void *p) svga_t *svga = (svga_t *)p; uint32_t x, blink_delay; int wx, wy; + int skip = (svga->crtc[8] >> 5) & 0x03; if (!svga->linepos) { if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) { @@ -625,9 +630,12 @@ svga_poll(void *p) } if (!svga->override) { - svga_render_overscan_left(svga); svga->render(svga); + + svga->x_add = (overscan_x >> 1); + svga_render_overscan_left(svga); svga_render_overscan_right(svga); + svga->x_add = (overscan_x >> 1) - svga->scrollcache; } if (svga->overlay_on) { @@ -702,8 +710,10 @@ svga_poll(void *p) if (svga->vc == svga->split) { svga->ma = svga->maback = 0; svga->sc = 0; - if (svga->attrregs[0x10] & 0x20) + if (svga->attrregs[0x10] & 0x20) { svga->scrollcache = 0; + svga->x_add = (overscan_x >> 1); + } } if (svga->vc == svga->dispend) { if (svga->vblank_start) @@ -761,9 +771,9 @@ svga_poll(void *p) svga->ma = svga->maback = svga->ma_latch; svga->ca = (svga->crtc[0xe] << 8) | svga->crtc[0xf]; - svga->ma <<= 2; - svga->maback <<= 2; - svga->ca <<= 2; + svga->ma = (svga->ma << 2) + (skip << 2); + svga->maback = (svga->maback << 2) + (skip << 2); + svga->ca = (svga->ca << 2) + (skip << 2); } if (svga->vc == svga->vtotal) { svga->vc = 0; @@ -786,7 +796,7 @@ svga_poll(void *p) else svga->scrollcache = (svga->scrollcache & 0x06) >> 1; - if (svga->seqregs[1] & 8) + if ((svga->seqregs[1] & 8) || (svga->render == svga_render_8bpp_lowres)) svga->scrollcache <<= 1; svga->x_add = (overscan_x >> 1) - svga->scrollcache; diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 04a1f7219..2448bd1fb 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -8,7 +8,7 @@ * * SVGA renderers. * - * Version: @(#)vid_svga_render.c 1.0.13 2019/03/08 + * Version: @(#)vid_svga_render.c 1.0.14 2019/11/19 * * Authors: Sarah Walker, * Miran Grca, @@ -40,7 +40,7 @@ svga_render_blank(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x < svga->hdisp; x++) { + for (x = 0; x < (svga->hdisp + svga->scrollcache); x++) { switch (svga->seqregs[1] & 9) { case 0: for (xx = 0; xx < 9; xx++) @@ -84,7 +84,7 @@ svga_render_overscan_right(svga_t *svga) if (svga->scrblank || (svga->hdisp == 0)) return; - right = (overscan_x >> 1) + svga->scrollcache; + right = (overscan_x >> 1); for (i = 0; i < right; i++) buffer32->line[svga->displine + svga->y_add][svga->x_add + svga->hdisp + i] = svga->overscan_color; } @@ -111,7 +111,7 @@ svga_render_text_40(svga_t *svga) p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; xinc = (svga->seqregs[1] & 1) ? 16 : 18; - for (x = 0; x < svga->hdisp; x += xinc) { + for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; @@ -174,7 +174,7 @@ svga_render_text_80(svga_t *svga) p = &buffer32->line[svga->displine + svga->y_add][svga->x_add]; xinc = (svga->seqregs[1] & 1) ? 8 : 9; - for (x = 0; x < svga->hdisp; x += xinc) { + for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; attr = svga->vram[((svga->ma << 1) + 1) & svga->vram_display_mask]; @@ -237,7 +237,7 @@ svga_render_text_80_ksc5601(svga_t *svga) xinc = (svga->seqregs[1] & 1) ? 8 : 9; - for (x = 0; x < svga->hdisp; x += xinc) { + for (x = 0; x < (svga->hdisp + svga->scrollcache); x += xinc) { drawcursor = ((svga->ma == svga->ca) && svga->con && svga->cursoron); chr = svga->vram[(svga->ma << 1) & svga->vram_display_mask]; nextchr = svga->vram[((svga->ma + 4) << 1) & svga->vram_display_mask]; @@ -348,7 +348,7 @@ svga_render_2bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 16) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { addr = svga->ma; if (!(svga->crtc[0x17] & 0x40)) { @@ -411,7 +411,7 @@ svga_render_2bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { addr = svga->ma; if (!(svga->crtc[0x17] & 0x40)) { @@ -473,7 +473,7 @@ svga_render_4bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 16) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 16) { addr = svga->ma; oddeven = 0; @@ -547,7 +547,7 @@ svga_render_4bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { addr = svga->ma; oddeven = 0; @@ -617,7 +617,7 @@ svga_render_8bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); p[0] = p[1] = svga->map8[dat & 0xff]; @@ -650,7 +650,7 @@ svga_render_8bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { + for (x = 0; x <= (svga->hdisp/* + svga->scrollcache*/); x += 8) { dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); p[0] = svga->map8[dat & 0xff]; p[1] = svga->map8[(dat >> 8) & 0xff]; @@ -688,7 +688,7 @@ svga_render_15bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[(x << 1)] = p[(x << 1) + 1] = video_15to32[dat & 0xffff]; @@ -724,7 +724,7 @@ svga_render_15bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[x] = video_15to32[dat & 0xffff]; p[x + 1] = video_15to32[dat >> 16]; @@ -764,7 +764,7 @@ svga_render_15bpp_mix_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[(x << 1)] = p[(x << 1) + 1] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; @@ -800,7 +800,7 @@ svga_render_15bpp_mix_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[x] = (dat & 0x00008000) ? svga->pallook[dat & 0xff] : video_15to32[dat & 0xffff]; dat >>= 16; @@ -844,7 +844,7 @@ svga_render_16bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[(x << 1)] = p[(x << 1) + 1] = video_16to32[dat & 0xffff]; p[(x << 1) + 2] = p[(x << 1) + 3] = video_16to32[dat >> 16]; @@ -875,7 +875,7 @@ svga_render_16bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 8) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 8) { uint32_t dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 1)) & svga->vram_display_mask]); p[x] = video_16to32[dat & 0xffff]; p[x + 1] = video_16to32[dat >> 16]; @@ -912,7 +912,7 @@ svga_render_24bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); svga->ma += 3; svga->ma &= svga->vram_display_mask; @@ -940,7 +940,7 @@ svga_render_24bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x += 4) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x += 4) { dat = *(uint32_t *)(&svga->vram[svga->ma & svga->vram_display_mask]); p[x] = dat & 0xffffff; @@ -974,7 +974,7 @@ svga_render_32bpp_lowres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { fg = svga->vram[svga->ma] | (svga->vram[svga->ma + 1] << 8) | (svga->vram[svga->ma + 2] << 16); svga->ma += 4; svga->ma &= svga->vram_display_mask; @@ -1002,7 +1002,7 @@ svga_render_32bpp_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); p[x] = dat & 0xffffff; } @@ -1029,7 +1029,7 @@ svga_render_ABGR8888_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); p[x] = ((dat & 0xff0000) >> 16) | (dat & 0x00ff00) | ((dat & 0x0000ff) << 16); } @@ -1056,7 +1056,7 @@ svga_render_RGBA8888_highres(svga_t *svga) svga->firstline_draw = svga->displine; svga->lastline_draw = svga->displine; - for (x = 0; x <= svga->hdisp; x++) { + for (x = 0; x <= (svga->hdisp + svga->scrollcache); x++) { dat = *(uint32_t *)(&svga->vram[(svga->ma + (x << 2)) & svga->vram_display_mask]); p[x] = dat >> 8; } From d48ebb0c2753279181dda32b58c7a67bca1c5e3a Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 20 Nov 2019 00:43:23 +0100 Subject: [PATCH 25/26] 86Box v2.07 Stable/Final release. --- src/86box.h | 6 +++--- src/win/86Box.rc | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/86box.h b/src/86box.h index 260b6976d..8baa0de37 100644 --- a/src/86box.h +++ b/src/86box.h @@ -8,7 +8,7 @@ * * Main include file for the application. * - * Version: @(#)86box.h 1.0.34 2019/11/01 + * Version: @(#)86box.h 1.0.35 2019/11/19 * * Authors: Miran Grca, *f Fred N. van Kempen, @@ -30,8 +30,8 @@ #define EMU_NAME "86Box" #define EMU_NAME_W L"86Box" #ifdef RELEASE_BUILD -#define EMU_VERSION "2.06" -#define EMU_VERSION_W L"2.06" +#define EMU_VERSION "2.07" +#define EMU_VERSION_W L"2.07" #else #define EMU_VERSION "2.10" #define EMU_VERSION_W L"2.10" diff --git a/src/win/86Box.rc b/src/win/86Box.rc index 49c941934..d28c34767 100644 --- a/src/win/86Box.rc +++ b/src/win/86Box.rc @@ -8,7 +8,7 @@ * * Application resource script for Windows. * - * Version: @(#)86Box.rc 1.0.53 2019/11/01 + * Version: @(#)86Box.rc 1.0.54 2019/11/19 * * Authors: Miran Grca, * Fred N. van Kempen, @@ -225,7 +225,7 @@ BEGIN DEFPUSHBUTTON "OK",IDOK,129,94,71,12 ICON 100,IDC_ABOUT_ICON,7,7,20,20 #ifdef RELEASE_BUILD - LTEXT "86Box v2.06 - An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", + LTEXT "86Box v2.07 - An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", IDC_ABOUT_ICON,54,7,146,73 #else LTEXT "86Box v2.10 - An emulator of old computers\n\nAuthors: Sarah Walker, Miran Grca, Fred N. van Kempen (waltje), SA1988, MoochMcGee, reenigne, leilei, JohnElliott, greatpsycho, and others.\n\nReleased under the GNU General Public License version 2. See LICENSE for more information.", @@ -980,8 +980,8 @@ END VS_VERSION_INFO VERSIONINFO #ifdef RELEASE_BUILD - FILEVERSION 2,6,0,0 - PRODUCTVERSION 2,6,0,0 + FILEVERSION 2,7,0,0 + PRODUCTVERSION 2,7,0,0 #else FILEVERSION 2,10,0,0 PRODUCTVERSION 2,10,0,0 @@ -1004,7 +1004,7 @@ BEGIN VALUE "CompanyName", "IRC #SoftHistory\0" VALUE "FileDescription", "86Box - an emulator for X86-based systems\0" #ifdef RELEASE_BUILD - VALUE "FileVersion", "2.06\0" + VALUE "FileVersion", "2.07\0" #else VALUE "FileVersion", "2.10\0" #endif @@ -1015,7 +1015,7 @@ BEGIN VALUE "PrivateBuild", "\0" VALUE "ProductName", "86Box Emulator\0" #ifdef RELEASE_BUILD - VALUE "ProductVersion", "2.06\0" + VALUE "ProductVersion", "2.07\0" #else VALUE "ProductVersion", "2.10\0" #endif From 56192504331ce1435d13c024b6e491b9cef5937a Mon Sep 17 00:00:00 2001 From: OBattler Date: Wed, 20 Nov 2019 00:48:11 +0100 Subject: [PATCH 26/26] Fixed a compile-breaking mistake in machine/m_ps2_isa.c. --- src/machine/m_ps2_isa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/machine/m_ps2_isa.c b/src/machine/m_ps2_isa.c index cf1cb45d2..9c0f6e8a1 100644 --- a/src/machine/m_ps2_isa.c +++ b/src/machine/m_ps2_isa.c @@ -151,7 +151,7 @@ static void ps2board_init(void) ps2_190 = 0; - ps2_uart = device_add_inst(&i16450_device, 1); + ps2_uart = device_add_inst(&ns16450_device, 1); lpt1_init(0x3bc);