diff options
author | Daniel Serpell <daniel.serpell@gmail.com> | 2020-05-03 20:01:45 -0400 |
---|---|---|
committer | Daniel Serpell <daniel.serpell@gmail.com> | 2020-05-03 20:01:45 -0400 |
commit | e34c1c68e0d9c5aaed928b588335fa624d4ab9f1 (patch) | |
tree | 1138ea9e06d75fbd34ff901dc7a4b0c8a8debc4c | |
parent | e3673b20e32aae8f6cbcb3606f09a7b030675cf2 (diff) | |
download | emu2-e34c1c68e0d9c5aaed928b588335fa624d4ab9f1.tar.gz |
Add minimal emulation of CRTC registers.
This is needed for some programs to properly detect CGA/VGA video.
-rw-r--r-- | src/main.c | 9 | ||||
-rw-r--r-- | src/video.c | 34 | ||||
-rw-r--r-- | src/video.h | 5 |
3 files changed, 45 insertions, 3 deletions
@@ -27,8 +27,8 @@ uint8_t read_port(unsigned port) retrace++; return retrace & 0x09; } - else if(port == 0x3D5) - return 0; + else if(port == 0x3D4 || port == 0x3D5) + return video_crtc_read(port); else if(port >= 0x40 && port <= 0x43) return port_timer_read(port); else if(port >= 0x60 && port <= 0x65) @@ -41,7 +41,10 @@ void write_port(unsigned port, uint8_t value) { if(port >= 0x40 && port <= 0x43) return port_timer_write(port, value); - debug(debug_port, "port write %04x <- %02x\n", port, value); + else if(port == 0x03D4 || port == 0x03D5) + return video_crtc_write(port, value); + else + debug(debug_port, "port write %04x <- %02x\n", port, value); } void emulator_update(void) diff --git a/src/video.c b/src/video.c index d6e405b..5a42484 100644 --- a/src/video.c +++ b/src/video.c @@ -608,3 +608,37 @@ void int10() debug(debug_video, "UNHANDLED INT 10, AX=%04x\n", ax); } } + +// CRTC port emulation, some software use it to fix "snow" in CGA modes. +static uint8_t crtc_port; +static uint16_t crtc_cursor_loc; + +uint8_t video_crtc_read(int port) +{ + if(port & 1) + { + if( crtc_port == 0x0E ) + return crtc_cursor_loc >> 8; + if( crtc_port == 0x0F ) + return crtc_cursor_loc; + else + return 0; + } + else + return crtc_port; +} + +void video_crtc_write(int port, uint8_t value) +{ + if(port & 1) + { + if( crtc_port == 0x0E ) + crtc_cursor_loc = (crtc_cursor_loc & 0xFF) | (value << 8); + if( crtc_port == 0x0F ) + crtc_cursor_loc = (crtc_cursor_loc & 0xFF00) | (value); + else + debug(debug_video, "CRTC port write [%02x] <- %02x\n", crtc_port, value); + } + else + crtc_port = value; +} diff --git a/src/video.h b/src/video.h index a24a529..7661223 100644 --- a/src/video.h +++ b/src/video.h @@ -1,5 +1,7 @@ #pragma once +#include <stdint.h> + void int10(void); // Redraws terminal screen void check_screen(void); @@ -7,3 +9,6 @@ void check_screen(void); int video_active(void); // Writes a character to the video screen void video_putch(char ch); +// CRTC port read/write +uint8_t video_crtc_read(int port); +void video_crtc_write(int port, uint8_t value); |