diff --git a/pc98.h b/pc98.h index b08c94ed..60c3f3b7 100644 --- a/pc98.h +++ b/pc98.h @@ -60,6 +60,7 @@ typedef unsigned int utram_y_t; #define GLYPH_HALF_W 8 #define GLYPH_FULL_W 16 #define GLYPH_H 16 +#define GLYPH_HALF_H 8 #define shiftjis_w(literal) \ ((sizeof(literal) - 1) * GLYPH_HALF_W) diff --git a/platform/x86real/pc98/font.cpp b/platform/x86real/pc98/font.cpp index 22c58a91..aedb1b66 100644 --- a/platform/x86real/pc98/font.cpp +++ b/platform/x86real/pc98/font.cpp @@ -20,6 +20,27 @@ // in the PC-98HA BIOS). // • Emulators directly implement it in native code. +void font_read(font_glyph_t& glyph, jis_t jis) +{ + _BX = FP_SEG(&glyph); + _CX = FP_OFF(&glyph); + _DX = jis; + _AH = 0x14; + geninterrupt(0x18); + glyph.tag.w *= GLYPH_HALF_W; + glyph.tag.h *= GLYPH_HALF_H; +} + +void font_read(font_glyph_ank_8x8_t& glyph, ank_t ank) +{ + font_read(reinterpret_cast(glyph), static_cast(ank)); +} + +void font_read(font_glyph_ank_8x16_t& glyph, ank_t ank) +{ + font_read(reinterpret_cast(glyph), (0x8000 + ank)); +} + void font_gaiji_write( const dot_rect_t(GLYPH_FULL_W, GLYPH_H)* gaiji, uint16_t count, diff --git a/platform/x86real/pc98/font.hpp b/platform/x86real/pc98/font.hpp index 4159beda..357f07eb 100644 --- a/platform/x86real/pc98/font.hpp +++ b/platform/x86real/pc98/font.hpp @@ -1,12 +1,15 @@ // PC-98 font ROM access // --------------------- -// Structure returned by INT 18h, AH=14h. The amount of bytes returned depends -// on the type of glyph (8×8, 8×16, or 16×16) as indicated by its codepoint, -// so make sure to allocate the correct subclass for it. +// Indicates the size of the glyph (8×8, 8×16, or 16×16), and by extension the +// amount of bytes returned from font_read(). struct font_glyph_header_t { - uint8_t tram_w; - uint8_t h_divided_by_8; + uint8_t h; // in pixels + uint8_t w; // in pixels +}; + +struct font_glyph_ank_8x8_t : public font_glyph_header_t { + dot_rect_t(GLYPH_HALF_W, GLYPH_HALF_H) dots; }; struct font_glyph_ank_8x16_t : public font_glyph_header_t { @@ -17,6 +20,24 @@ struct font_glyph_kanji_t : public font_glyph_header_t { dot_rect_t(GLYPH_FULL_W, GLYPH_H) dots; }; +// Tagged union for all possible glyph sizes returned from font_read(). +struct font_glyph_t { + font_glyph_header_t tag; + union { + dot_rect_t(GLYPH_HALF_W, GLYPH_HALF_H) ank_8x8; + dot_rect_t(GLYPH_HALF_W, GLYPH_H) ank_8x16; + dot_rect_t(GLYPH_FULL_W, GLYPH_H) kanji; + }; +}; + +// Reads the font ROM glyph for the given JIS codepoint. +void font_read(font_glyph_t& glyph, jis_t jis); + +// Strongly-typed, memory-conserving wrappers around font_read() for smaller +// glyphs. +void font_read(font_glyph_ank_8x8_t& glyph, ank_t ank); +void font_read(font_glyph_ank_8x16_t& glyph, ank_t ank); + // Writes user-defined glyphs to the given offset inside the PC-98 gaiji RAM. // The 256 possible gaiji IDs are mapped onto JIS X 0208 codepoints as follows: // diff --git a/shiftjis.hpp b/shiftjis.hpp index b5d2e784..4ae30e12 100644 --- a/shiftjis.hpp +++ b/shiftjis.hpp @@ -1,3 +1,6 @@ +// 1-byte JIS X 0201 codepoint (ASCII, numeric, or halfwidth katakana). +typedef uint8_t ank_t; + // 2-byte JIS X 0208 codepoint. typedef uint16_t jis_t;