DOSBox-X
|
00001 /* 00002 * Copyright (C) 2018-2020 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 along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 #include <string.h> 00039 #include <stdlib.h> 00040 #include <string> 00041 #include <stdio.h> 00042 00043 /* Character Generator (CG) font access state */ 00044 uint16_t a1_font_load_addr = 0; 00045 uint8_t a1_font_char_offset = 0; 00046 00047 /* Character Generator ports. 00048 * This is in fact officially documented by NEC in 00049 * a 1986 book published about NEC BIOS and BASIC ROM. */ 00050 Bitu pc98_a1_read(Bitu port,Bitu iolen) { 00051 (void)iolen;//UNUSED 00052 switch (port) { 00053 case 0xA9: // an 8-bit I/O port to access font RAM by... 00054 // NOTES: On a PC-9821 Lt2 laptop, the character ROM doesn't seem to latch valid data beyond 00055 // 0xxx5D. Often this reads back as zero, but depending on whatever random data is floating 00056 // on the bus can read back nonzero. This doesn't apply to 0x0000-0x00FF of course (single wide 00057 // characters), but only to the double-wide character set where (c & 0x007F) >= 0x5D. 00058 // This behavior should be emulated. */ 00059 return pc98_font_char_read(a1_font_load_addr,a1_font_char_offset & 0xF,(a1_font_char_offset & 0x20) ? 0 : 1); 00060 default: 00061 break; 00062 } 00063 00064 return ~0ul; 00065 } 00066 00067 /* Character Generator ports. 00068 * This is in fact officially documented by NEC in 00069 * a 1986 book published about NEC BIOS and BASIC ROM. */ 00070 void pc98_a1_write(Bitu port,Bitu val,Bitu iolen) { 00071 (void)iolen;//UNUSED 00072 switch (port) { 00073 /* A3,A1 (out only) two JIS bytes that make up the char code */ 00074 case 0xA1: 00075 a1_font_load_addr &= 0x00FF; 00076 a1_font_load_addr |= (val & 0xFF) << 8; 00077 break; 00078 case 0xA3: 00079 a1_font_load_addr &= 0xFF00; 00080 a1_font_load_addr |= (val & 0xFF); 00081 break; 00082 case 0xA5: 00083 /* From documentation: 00084 * 00085 * bit [7:6] = Dont care 00086 * bit [5] = L/R 00087 * bit [4] = 0 00088 * bit [3:0] = C3-C0 00089 * 00090 * This so far is consistent with real hardware behavior */ 00091 a1_font_char_offset = (uint8_t)val; 00092 break; 00093 case 0xA7: 00094 /* TODO: Various controls for the text layer */ 00095 break; 00096 case 0xA9: // an 8-bit I/O port to access font RAM by... 00097 // this is what Touhou Project uses to load fonts. 00098 // never mind decompiling INT 18h on real hardware shows instead 00099 // a similar sequence with REP MOVSW to A400:0000... 00100 // 00101 // there's a restriction noted with INT 18h AH=1Ah where the only 00102 // codes you can overwrite are 0xxx76 and 0xxx77. I'm guessing that 00103 // having 512KB of RAM out there dedicated to nothing but fonts 00104 // is probably not economical to NEC's bottom line, and this 00105 // restriction makes me wonder if the font is held in ROM except 00106 // for this narrow sliver of codes, which map to about 8KB of RAM 00107 // (128*2*16) * 2 = 8192 bytes 00108 // 00109 // I'm also guessing that this RAM is not involved with the single-wide 00110 // character set, which is why writes to 0x0056/0x0057 are redirected to 00111 // 0x8056/0x8057. Without this hack, Touhou Project 2 will overwrite 00112 // the letter 'W' when loading it's font data (Level 1 will show "Eastern ind" 00113 // instead of "Eastern Wind" for the music title as a result). 00114 // 00115 // On real hardware it seems, attempts to write anywhere outside 0xxx56/0xxx57 00116 // are ignored. They are not remapped. Attempts to write to 0x0056 are ignored 00117 // by the hardware (since that conflicts with single-wide chars) but you can 00118 // write to that cell if you write to 0x8056 instead. 00119 if ((a1_font_load_addr & 0x007E) == 0x0056 && (a1_font_load_addr & 0xFF00) != 0x0000) 00120 pc98_font_char_write(a1_font_load_addr,a1_font_char_offset & 0xF,(a1_font_char_offset & 0x20) ? 0 : 1,(uint8_t)val); 00121 else 00122 LOG_MSG("A1 port attempt to write FONT ROM char 0x%x",a1_font_load_addr); 00123 break; 00124 default: 00125 LOG_MSG("A1 port %lx val %lx unexpected",(unsigned long)port,(unsigned long)val); 00126 break; 00127 } 00128 } 00129