<commit_before>
#include <i86.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <stdint.h>

#include <hw/vga2/vga2.h>

#if defined(TARGET_PC98)
static char tmp[256];

void my_pc98_write_str(unsigned int r,unsigned int c,const char *s) {
    VGA2_ALPHA_PTR p = vga2_alpharowcol_ptr(r,c);
    char cc;

    /* this won't do Shift JIS decoding, sorry */
    while ((cc = *s++) != 0) {
        p[0] = (unsigned char)cc;
        p[VGA2_PC98_ATTR_OFFSC] = VGA2_ALPHA_ATTR_NOTSECRET | VGA2_ALPHA_ATTR_COLOR(7);
        p++;
    }
}
#endif

void cls(void) {
    VGA2_ALPHA_PTR p = vga2_alpha_ptr();
    unsigned int c = vga2_alpha_base.width * vga2_alpha_base.height;

    while (c > 0) {
#if defined(TARGET_PC98)
        p[0] = 0x20;
        p[VGA2_PC98_ATTR_OFFSC] = VGA2_ALPHA_ATTR_NOTSECRET | VGA2_ALPHA_ATTR_COLOR(7);
        p++;
#else
        *p++ = VGA2_ALPHA_ATTR_FGBGCOLOR(7,0) | 0x20;
#endif
        c--;
    }
}

#if defined(TARGET_PC98)

static inline void vga2_pc98_text_gdc_write_command(const unsigned char cmd) {
    while (inp(0x60) & 0x02); /* while FIFO full */
    outp(0x60+2,cmd); // write command
}

static inline void vga2_pc98_text_gdc_write_data(const unsigned char d) {
    while (inp(0x60) & 0x02); /* while FIFO full */
    outp(0x60,d); // write data
}

/* PC-98 only */
void vga2_set_alpha_stride_pc98(unsigned int w) {
    vga2_pc98_text_gdc_write_command(0x47/*Pitch specification*/);
    vga2_pc98_text_gdc_write_data(w);
    vga2_alpha_base.width = w; /* even values only */
}
#else
/* EGA/VGA only! */
void vga2_set_alpha_stride_egavga(unsigned int w) {
    const uint16_t port = vga2_bios_crtc_io();
    outp(port+0,0x13);
    outp(port+1,w>>1u); /* offset register, even values only */
    vga2_alpha_base.width = w & ~1u; /* even values only */
    *vga2_bda_w(0x4A) = w & ~1u; /* update BIOS too */
}

/* EGA only (VGA requires consideration of CRTC write protect) */
void vga2_set_alpha_display_width_ega(unsigned int w) {
    const uint16_t port = vga2_bios_crtc_io();
    w &= ~1u; /* EGA/VGA can only allow even number of columns. Horizontal display end CAN allow it but offset register cannot */
    outp(port+0,0x01);
    outp(port+1,w-1u); /* horizontal display end */
    outp(port+0,0x02);
    outp(port+1,w+1u); /* start horizontal blanking. between active and blanking exists the overscan border */
    /* affects display width, not stride */
}

/* VGA only (write protect in the way) */
void vga2_set_alpha_display_width_vga(unsigned int w) {
    const uint16_t port = vga2_bios_crtc_io();
    uint8_t p;
    outp(port+0,0x11); /* vertical retrace end / bandwith / protect */
    p = inp(port+1);
    outp(port+1,p & 0x7Fu); /* unlock */
    w &= ~1u; /* EGA/VGA can only allow even number of columns. Horizontal display end CAN allow it but offset register cannot */
    outp(port+0,0x01);
    outp(port+1,w-1u); /* horizontal display end */
    outp(port+0,0x02);
    outp(port+1,w+1u); /* start horizontal blanking. between active and blanking exists the overscan border */
    /* affects display width, not stride */
    outp(port+0,0x11); /* vertical retrace end / bandwith / protect */
    outp(port+1,p); /* restore */
}

/* MCGA only (write protect in the way). */
/* TODO: Verify this works on real hardware the same as DOSBox-X */
void vga2_set_alpha_display_width_mcga(unsigned int w) {
    const uint16_t port = 0x3D4; /* MCGA is always color, there's no monochrome MCGA that I'm aware of at 3B4h */
    unsigned int fw;
    uint8_t p,q;

    /* MCGA is weird.<commit_msg>Testing complete<commit_after>
#include <i86.h>
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <stdint.h>

#include <hw/vga2/vga2.h>

#if defined(TARGET_PC98)
static char tmp[256];

void my_pc98_write_str(unsigned int r,unsigned int c,const char *s) {
    VGA2_ALPHA_PTR p = vga2_alpharowcol_ptr(r,c);
    char cc;

    /* this won't do Shift JIS decoding, sorry */
    while ((cc = *s++) != 0) {
        p[0] = (unsigned char)cc;
        p[VGA2_PC98_ATTR_OFFSC] = VGA2_ALPHA_ATTR_NOTSECRET | VGA2_ALPHA_ATTR_COLOR(7);
        p++;
    }
}
#endif

void cls(void) {
    VGA2_ALPHA_PTR p = vga2_alpha_ptr();
    unsigned int c = vga2_alpha_base.width * vga2_alpha_base.height;

    while (c > 0) {
#if defined(TARGET_PC98)
        p[0] = 0x20;
        p[VGA2_PC98_ATTR_OFFSC] = VGA2_ALPHA_ATTR_NOTSECRET | VGA2_ALPHA_ATTR_COLOR(7);
        p++;
#else
        *p++ = VGA2_ALPHA_ATTR_FGBGCOLOR(7,0) | 0x20;
#endif
        c--;
    }
}

#if defined(TARGET_PC98)

static inline void vga2_pc98_text_gdc_write_command(const unsigned char cmd) {
    while (inp(0x60) & 0x02); /* while FIFO full */
    outp(0x60+2,cmd); // write command
}

static inline void vga2_pc98_text_gdc_write_data(const unsigned char d) {
    while (inp(0x60) & 0x02); /* while FIFO full */
    outp(0x60,d); // write data
}

/* PC-98 only */
void vga2_set_alpha_stride_pc98(unsigned int w) {
    vga2_pc98_text_gdc_write_command(0x47/*Pitch specification*/);
    vga2_pc98_text_gdc_write_data(w);
    vga2_alpha_base.width = w; /* even values only */
}
#else
/* EGA/VGA only! */
void vga2_set_alpha_stride_egavga(unsigned int w) {
    const uint16_t port = vga2_bios_crtc_io();
    outp(port+0,0x13);
    outp(port+1,w>>1u); /* offset register, even values only */
    vga2_alpha_base.width = w & ~1u; /* even values only */
    *vga2_bda_w(0x4A) = w & ~1u; /* update BIOS too */
}

/* EGA only (VGA requires consideration of CRTC write protect) */
void vga2_set_alpha_display_width_ega(unsigned int w) {
    const uint16_t port = vga2_bios_crtc_io();
    w &= ~1u; /* EGA/VGA can only allow even number of columns. Horizontal display end CAN allow it but offset register cannot */
    outp(port+0,0x01);
    outp(port+1,w-1u); /* horizontal display end */
    outp(port+0,0x02);
    outp(port+1,w+1u); /* start horizontal blanking. between active and blanking exists the overscan border */
    /* affects display width, not stride */
}

/* VGA only (write protect in the way) */
void vga2_set_alpha_display_width_vga(unsigned int w) {
    const uint16_t port = vga2_bios_crtc_io();
    uint8_t p;
    outp(port+0,0x11); /* vertical retrace end / bandwith / protect */
    p = inp(port+1);
    outp(port+1,p & 0x7Fu); /* unlock */
    w &= ~1u; /* EGA/VGA can only allow even number of columns. Horizontal display end CAN allow it but offset register cannot */
    outp(port+0,0x01);
    outp(port+1,w-1u); /* horizontal display end */
    outp(port+0,0x02);
    outp(port+1,w+1u); /* start horizontal blanking. between active and blanking exists the overscan border */
    /* affects display width, not stride */
    outp(port+0,0x11); /* vertical retrace end / bandwith / protect */
    outp(port+1,p); /* restore */
}

/* MCGA only (write protect in the way). */
/* NTS: This code has been tested and confirmed to work on MCGA hardware */
void vga2_set_alpha_display_width_mcga(unsigned int w) {
    const uint16_t port = 0x3D4; /* MCGA is always color, there's no monochrome MCGA that I'm aware of at 3B4h */
    unsigned int fw;
    uint8_t p,q;

    /* MCGA is weird.
{'fraction_non_alphanumeric': 0.12702208468138979, 'fraction_numerical': 0.044732029821353214, 'mean_word_length': 3.4409743910056214, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6837636', 'n_tokens_mistral': 2893, 'n_tokens_neox': 2762, 'n_words': 690}