#define PC98_GDC_FIFO_SIZE 32 /* taken from Neko Project II, but what is it really? */ #define GDC_COMMAND_BYTE 0x100 enum { GDC_MASTER=0, GDC_SLAVE=1 }; // VOPBIT_* source: Neko Project II // operate: bit0 access page // bit1 egc enable // bit2 grcg bit6 // bit3 grcg bit7 // bit4 analog enable (16/256-color mode). 8-color mode if not. // bit5 pc9821 vga enum { VOPBIT_ACCESS = 0, VOPBIT_EGC = 1, VOPBIT_GRCG = 2, VOPBIT_ANALOG = 4, VOPBIT_VGA = 5, VOPBIT_PEGC_PLANAR = 6 }; union pc98_tile { uint8_t b[2]; uint16_t w; }; struct PC98_GDC_state { PC98_GDC_state(); void reset_fifo(void); void reset_rfifo(void); void flush_fifo_old(void); bool write_fifo(const uint16_t c); bool write_rfifo(const uint8_t c); bool write_fifo_command(const unsigned char c); bool write_fifo_param(const unsigned char c); bool rfifo_has_content(void); uint8_t read_status(void); uint8_t rfifo_read_data(void); void idle_proc(void); void force_fifo_complete(void); void take_cursor_char_setup(unsigned char bi); void take_cursor_pos(unsigned char bi); void take_reset_sync_parameters(void); void cursor_advance(void); void begin_frame(void); void next_line(void); void load_display_partition(void); void next_display_partition(void); size_t fifo_can_read(void); bool fifo_empty(void); uint16_t read_fifo(void); /* NTS: * * We're following the Neko Project II method of FIFO emulation BUT * I wonder if the GDC maintains two FIFOs and allows stacking params * in one and commands in another....? */ uint8_t cmd_parm_tmp[8]; /* temp storage before accepting params */ uint8_t rfifo[PC98_GDC_FIFO_SIZE]; uint8_t rfifo_read,rfifo_write; uint16_t fifo[PC98_GDC_FIFO_SIZE]; /* NTS: Neko Project II uses one big FIFO for command and data, which makes sense to me */ uint8_t fifo_read,fifo_write; uint8_t param_ram[16]; uint8_t param_ram_wptr; uint16_t scan_address; uint8_t row_height; uint8_t row_line; uint8_t display_partition; uint16_t display_partition_rem_lines; uint8_t display_partition_mask; uint16_t active_display_lines; /* AL (translated) */ uint16_t active_display_words_per_line;/* AW bits (translated) */ uint16_t display_pitch; uint8_t horizontal_sync_width; /* HS (translated) */ uint8_t vertical_sync_width; /* VS (translated) */ uint8_t horizontal_front_porch_width;/* HFP (translated) */ uint8_t horizontal_back_porch_width;/* HBP (translated) */ uint8_t vertical_front_porch_width; /* VFP (translated) */ uint8_t vertical_back_porch_width; /* VBP (translated) */ uint8_t display_mode; /* CG bits */ /* CG = 00 = mixed graphics & character * CG = 01 = graphics mode * CG = 10 = character mode * CG = 11 = invalid */ uint8_t video_framing; /* IS bits */ /* IS = 00 = non-interlaced * IS = 01 = invalid * IS = 10 = interlaced repeat field for character displays * IS = 11 = interlaced */ uint8_t current_command; uint8_t proc_step; uint8_t cursor_blink_state; uint8_t cursor_blink_count; /* count from 0 to BR - 1 */ uint8_t cursor_blink_rate; /* BR */ bool draw_only_during_retrace; /* F bits */ bool dynamic_ram_refresh; /* D bits */ bool master_sync; /* master source generation */ bool display_enable; bool cursor_enable; bool cursor_blink; bool IM_bit; /* display partition, IM bit */ bool idle; bool doublescan; /* 200-line as 400-line */ }; typedef union pc98_tile egc_quad[4]; extern bool gdc_analog; extern uint32_t pc98_text_palette[8]; extern struct PC98_GDC_state pc98_gdc[2]; extern egc_quad pc98_gdc_tiles; extern uint8_t pc98_gdc_vramop; extern uint8_t pc98_gdc_modereg;