aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Serpell <daniel.serpell@gmail.com>2020-05-03 20:01:45 -0400
committerDaniel Serpell <daniel.serpell@gmail.com>2020-05-03 20:01:45 -0400
commite34c1c68e0d9c5aaed928b588335fa624d4ab9f1 (patch)
tree1138ea9e06d75fbd34ff901dc7a4b0c8a8debc4c
parente3673b20e32aae8f6cbcb3606f09a7b030675cf2 (diff)
downloademu2-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.c9
-rw-r--r--src/video.c34
-rw-r--r--src/video.h5
3 files changed, 45 insertions, 3 deletions
diff --git a/src/main.c b/src/main.c
index 74eabda..0a6ada3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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);
Un proyecto texto-plano.xyz