DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/hardware/vga_pc98_crtc.cpp
00001 /*
00002  *  Copyright (C) 2018  Jon Campbell
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 #include "dosbox.h"
00020 #include "setup.h"
00021 #include "video.h"
00022 #include "pic.h"
00023 #include "vga.h"
00024 #include "inout.h"
00025 #include "programs.h"
00026 #include "support.h"
00027 #include "setup.h"
00028 #include "timer.h"
00029 #include "mem.h"
00030 #include "util_units.h"
00031 #include "control.h"
00032 #include "pc98_cg.h"
00033 #include "pc98_dac.h"
00034 #include "pc98_gdc.h"
00035 #include "pc98_gdc_const.h"
00036 #include "mixer.h"
00037 
00038 extern bool                 pc98_attr4_graphic;
00039 extern bool                 pc98_graphics_hide_odd_raster_200line;
00040 
00041 bool                        gdc_5mhz_mode = false;
00042 bool                        enable_pc98_egc = true;
00043 bool                        enable_pc98_grcg = true;
00044 bool                        enable_pc98_16color = true;
00045 bool                        enable_pc98_188usermod = true;
00046 bool                        GDC_vsync_interrupt = false;
00047 uint8_t                     GDC_display_plane_wait_for_vsync = false;
00048 uint8_t                     GDC_display_plane_pending = false;
00049 uint8_t                     GDC_display_plane = false;
00050 
00051 uint8_t                     pc98_gdc_tile_counter=0;
00052 uint8_t                     pc98_gdc_modereg=0;
00053 uint8_t                     pc98_gdc_vramop=0;
00054 egc_quad                    pc98_gdc_tiles;
00055 
00056 extern unsigned char        pc98_text_first_row_scanline_start;  /* port 70h */
00057 extern unsigned char        pc98_text_first_row_scanline_end;    /* port 72h */
00058 extern unsigned char        pc98_text_row_scanline_blank_at;     /* port 74h */
00059 extern unsigned char        pc98_text_row_scroll_lines;          /* port 76h */
00060 extern unsigned char        pc98_text_row_scroll_count_start;    /* port 78h */
00061 extern unsigned char        pc98_text_row_scroll_num_lines;      /* port 7Ah */
00062 
00063 void pc98_crtc_write(Bitu port,Bitu val,Bitu iolen) {
00064     (void)iolen;//UNUSED
00065     switch (port&0xE) {
00066         case 0x00:      // 0x70: Character row, CG start scanline
00067             pc98_text_first_row_scanline_start = (unsigned char)val & 0x1F;
00068             break;
00069         case 0x02:      // 0x72: Character row, CG end scanline
00070             pc98_text_first_row_scanline_end = (unsigned char)val & 0x1F;
00071             break;
00072         case 0x04:      // 0x74: Character row, number of CG scanlines to display
00073             pc98_text_row_scanline_blank_at = (unsigned char)val & 0x1F;
00074             break;
00075         case 0x06:
00076             pc98_text_row_scroll_lines = (unsigned char)val & 0x1F;
00077             break;
00078         case 0x08:
00079             pc98_text_row_scroll_count_start = (unsigned char)val & 0x1F;
00080             break;
00081         case 0x0A:
00082             pc98_text_row_scroll_num_lines = (unsigned char)val & 0x1F;
00083             break;
00084         case 0x0C:      // 0x7C: mode reg / vram operation mode (also, reset tile counter)
00085             if (enable_pc98_grcg) {
00086                 pc98_gdc_tile_counter = 0;
00087                 pc98_gdc_modereg = val;
00088                 pc98_gdc_vramop &= ~(3 << VOPBIT_GRCG);
00089                 pc98_gdc_vramop |= (val & 0xC0) >> (6 - VOPBIT_GRCG);
00090             }
00091             break;
00092         case 0x0E:      // 0x7E: tile data
00093             if (enable_pc98_grcg) {
00094                 pc98_gdc_tiles[pc98_gdc_tile_counter].b[0] = val;
00095                 pc98_gdc_tiles[pc98_gdc_tile_counter].b[1] = val;
00096                 pc98_gdc_tile_counter = (pc98_gdc_tile_counter + 1) & 3;
00097             }
00098             break;
00099         default:
00100             LOG_MSG("PC98 CRTC w: port=0x%02X val=0x%02X unknown",(unsigned int)port,(unsigned int)val);
00101             break;
00102     };
00103 }
00104 
00105 Bitu pc98_crtc_read(Bitu port,Bitu iolen) {
00106     (void)iolen;//UNUSED
00107     switch (port&0xE) {
00108         case 0x00:      // 0x70: Character row, CG start scanline
00109             return pc98_text_first_row_scanline_start;
00110         case 0x02:      // 0x72: Character row, CG end scanline
00111             return pc98_text_first_row_scanline_end;
00112         case 0x04:      // 0x74: Character row, number of CG scanlines to display
00113             return pc98_text_row_scanline_blank_at;
00114         case 0x06:
00115             return pc98_text_row_scroll_lines;
00116         case 0x08:
00117             return pc98_text_row_scroll_count_start;
00118         case 0x0A:
00119             return pc98_text_row_scroll_num_lines;
00120         default:
00121             LOG_MSG("PC98 CRTC r: port=0x%02X unknown",(unsigned int)port);
00122             break;
00123     }
00124 
00125     return ~0ul;
00126 }
00127 
00128 /* Port 0x6A command handling */
00129 void pc98_port6A_command_write(unsigned char b) {
00130     switch (b) {
00131         case 0x00: // 16-color (analog) disable
00132             gdc_analog = false;
00133             pc98_gdc_vramop &= ~(1 << VOPBIT_ANALOG);
00134             VGA_SetupHandlers();   // confirmed on real hardware: this disables access to E000:0000
00135             pc98_update_palette(); // Testing on real hardware shows that the "digital" and "analog" palettes are completely different.
00136                                    // They're both there in hardware, but one or another is active depending on analog enable.
00137                                    // Also, the 4th bitplane at E000:0000 disappears when switched off from the display and from CPU access.
00138             break;
00139         case 0x01: // or enable
00140             if (enable_pc98_16color) {
00141                 gdc_analog = true;
00142                 pc98_gdc_vramop |= (1 << VOPBIT_ANALOG);
00143                 VGA_SetupHandlers();   // confirmed on real hardware: this enables access to E000:0000
00144                 pc98_update_palette(); // Testing on real hardware shows that the "digital" and "analog" palettes are completely different.
00145                                        // They're both there in hardware, but one or another is active depending on analog enable.
00146                                        // Also, the 4th bitplane at E000:0000 disappears when switched off from the display and from CPU access.
00147             }
00148             break;
00149         case 0x04:
00150             pc98_gdc_vramop &= ~(1 << VOPBIT_EGC);
00151             break;
00152         case 0x05:
00153             if (enable_pc98_egc) pc98_gdc_vramop |= (1 << VOPBIT_EGC);
00154             break;
00155         case 0x06: // TODO
00156         case 0x07: // TODO
00157             // TODO
00158             break;
00159         case 0x0A: // TODO
00160         case 0x0B: // TODO
00161             // TODO
00162             break;
00163         default:
00164             LOG_MSG("PC-98 port 6Ah unknown command 0x%02x",b);
00165             break;
00166     };
00167 }
00168 
00169 /* Port 0x68 command handling */
00170 void pc98_port68_command_write(unsigned char b) {
00171     switch (b) {
00172         case 0x00: // text screeen attribute bit 4 meaning: 0=vertical line
00173         case 0x01: //                                       1=simple graphic
00174             pc98_attr4_graphic = !!(b&1);
00175             break;
00176         case 0x08: // 200-line mode: show odd raster
00177         case 0x09: //                don't show odd raster
00178             pc98_graphics_hide_odd_raster_200line = !!(b&1);
00179             break;
00180         case 0x0A: // TODO
00181         case 0x0B: // TODO
00182             // TODO
00183             break;
00184         default:
00185             LOG_MSG("PC-98 port 68h unknown command 0x%02x",b);
00186             break;
00187     };
00188 }
00189