DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
include/pc98_cg.h
00001 
00002 #include "vga.h" /* uses VGA font RAM as CG ROM */
00003 
00004 /* mapping function from 16-bit WORD to font RAM offset */
00005 /* in: code = 16-bit JIS code word (unshifted)
00006  *     line = scan line within character cell
00007  *     right_half = 1 if right half, 0 if left half (double-wide only)
00008  * out: byte offset in FONT RAM (0x00000-0x7FFFF inclusive)
00009  *
00010  * NTS: Font ROM/RAM in PC-98 is laid out as follows in this emulation:
00011  *
00012  *      0x00 0xAA    ASCII single-wide character AA          offset = (AA * 16)
00013  *      0xHH 0xLL    Double-wide char (HH != 0) number HHLL  offset = ((HH & 0x7F) * 256) + ((LL & 0x7F) * 2) + right_half
00014  *
00015  *      Visual layout:
00016  *
00017  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+................
00018  *      | | | | | | | | | | | | | | | | |................   0x00 to 0xFF, 8-bit wide, at 0x0000
00019  *      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+................
00020  *      |   |   |   |   |   |   |   |   |................   0x0100 to 0x7F7F, 16-bit wide, at 0x0100, lower 7 bits only each byte
00021  *      +---+---+---+---+---+---+---+---+................
00022  *
00023  *      This is not necessarily how the font data is stored in ROM on actual hardware.
00024  *      The hardware appears to accept 16 bits but only use the low 7 bits of each byte for double-wide.
00025  *      0x80 0xAA is NOT an alias of single-wide chars. */
00026 static inline uint32_t pc98_font_char_to_ofs(const uint16_t code,const uint8_t line,const uint8_t right_half) {
00027     if (code & 0xFF00) {
00028         /* double-wide. this maps 0x01-0x7F, 0x80 to 0x80, 0x81-0xFF to 0x01-0x7F */
00029         const uint16_t x_code = (code & 0x7F) + ((((code + 0x7F00) & 0x7F00) + 0x0100) >> 1); /* 16-bit to 14-bit conversion. */
00030         return ((((uint32_t)x_code * (uint32_t)16) + (uint32_t)(line & 0xF)) * (uint32_t)2) + (uint32_t)right_half;
00031     }
00032     else {
00033         /* single-wide */
00034         return ((uint32_t)code * (uint32_t)16) + (line & 0xF);
00035     }
00036 }
00037 
00038 static inline uint8_t pc98_font_char_read(const uint16_t code,const uint8_t line,const uint8_t right_half) {
00039     return vga.draw.font[pc98_font_char_to_ofs(code,line,right_half)];
00040 }
00041 
00042 static inline void pc98_font_char_write(const uint16_t code,const uint8_t line,const uint8_t right_half,const uint8_t byte) {
00043     vga.draw.font[pc98_font_char_to_ofs(code,line,right_half)] = byte;
00044 }
00045