mirror of
https://github.com/86Box/86Box.git
synced 2026-02-21 17:15:32 -07:00
Merge branch '86Box:master' into nec-v20
This commit is contained in:
@@ -903,7 +903,7 @@ then
|
||||
|
||||
# Now patch a 64-bit Mach-O header (0xFEEDFACF, little endian), either at
|
||||
# the beginning or as a sub-header within a fat binary as parsed above.
|
||||
if [ "$(dd if="$line" bs=1 seek=$macho_offset count=8 status=none)" = "$(printf '\xCF\xFA\xED\xFE\x07\x00\x00\x01')" ]
|
||||
if [ "$(dd if="$line" bs=1 skip=$macho_offset count=8 status=none)" = "$(printf '\xCF\xFA\xED\xFE\x07\x00\x00\x01')" ]
|
||||
then
|
||||
# Change CPU subtype in the Mach-O header from ALL (0x00000003) to H (0x00000008).
|
||||
printf '\x08\x00\x00\x00' | dd of="$line" bs=1 seek=$((macho_offset + 8)) count=4 conv=notrunc status=none
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/machine.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/agpgart.h>
|
||||
|
||||
|
||||
enum
|
||||
@@ -59,7 +59,7 @@ typedef struct
|
||||
uint8_t mem_state[256];
|
||||
int type;
|
||||
smram_t *smram_low, *smram_high;
|
||||
void *agpgart;
|
||||
agpgart_t *agpgart;
|
||||
void (*write_drbs)(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit);
|
||||
} i4x0_t;
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <86box/pci.h>
|
||||
#include <86box/chipset.h>
|
||||
#include <86box/spd.h>
|
||||
#include <86box/video.h>
|
||||
#include <86box/agpgart.h>
|
||||
|
||||
#define VIA_585 0x05851000
|
||||
#define VIA_595 0x05950000
|
||||
@@ -50,8 +50,8 @@ typedef struct via_apollo_t
|
||||
uint8_t drb_unit;
|
||||
uint8_t pci_conf[256];
|
||||
|
||||
smram_t *smram;
|
||||
void *agpgart;
|
||||
smram_t *smram;
|
||||
agpgart_t *agpgart;
|
||||
} via_apollo_t;
|
||||
|
||||
|
||||
|
||||
@@ -291,7 +291,7 @@ config_detect_bom(char *fn)
|
||||
#endif
|
||||
if (f == NULL)
|
||||
return (0);
|
||||
fread(bom, 1, 3, f);
|
||||
(void) !fread(bom, 1, 3, f);
|
||||
if (bom[0] == 0xEF && bom[1] == 0xBB && bom[2] == 0xBF) {
|
||||
fclose(f);
|
||||
return 1;
|
||||
@@ -357,7 +357,7 @@ config_read(char *fn)
|
||||
#ifdef __HAIKU__
|
||||
config_fgetws(buff, sizeof_w(buff), f);
|
||||
#else
|
||||
fgetws(buff, sizeof_w(buff), f);
|
||||
(void) !fgetws(buff, sizeof_w(buff), f);
|
||||
#endif
|
||||
if (feof(f))
|
||||
break;
|
||||
@@ -387,7 +387,7 @@ config_read(char *fn)
|
||||
c++;
|
||||
d = 0;
|
||||
while (buff[c] != L']' && buff[c])
|
||||
wctomb(&(sname[d++]), buff[c++]);
|
||||
(void) !wctomb(&(sname[d++]), buff[c++]);
|
||||
sname[d] = L'\0';
|
||||
|
||||
/* Is the section name properly terminated? */
|
||||
@@ -408,7 +408,7 @@ config_read(char *fn)
|
||||
/* Get the variable name. */
|
||||
d = 0;
|
||||
while ((buff[c] != L'=') && (buff[c] != L' ') && buff[c])
|
||||
wctomb(&(ename[d++]), buff[c++]);
|
||||
(void) !wctomb(&(ename[d++]), buff[c++]);
|
||||
ename[d] = L'\0';
|
||||
|
||||
/* Skip incomplete lines. */
|
||||
|
||||
@@ -119,12 +119,12 @@ cart_image_load(int drive, char *fn)
|
||||
if (size & 0x00000fff) {
|
||||
size -= 0x00000200;
|
||||
fseek(f, 0x000001ce, SEEK_SET);
|
||||
fread(&base, 1, 2, f);
|
||||
(void) !fread(&base, 1, 2, f);
|
||||
base <<= 4;
|
||||
fseek(f, 0x00000200, SEEK_SET);
|
||||
carts[drive].buf = (uint8_t *) malloc(size);
|
||||
memset(carts[drive].buf, 0x00, size);
|
||||
fread(carts[drive].buf, 1, size, f);
|
||||
(void) !fread(carts[drive].buf, 1, size, f);
|
||||
fclose(f);
|
||||
} else {
|
||||
base = drive ? 0xe0000 : 0xd0000;
|
||||
@@ -133,7 +133,7 @@ cart_image_load(int drive, char *fn)
|
||||
fseek(f, 0x00000000, SEEK_SET);
|
||||
carts[drive].buf = (uint8_t *) malloc(size);
|
||||
memset(carts[drive].buf, 0x00, size);
|
||||
fread(carts[drive].buf, 1, size, f);
|
||||
(void) !fread(carts[drive].buf, 1, size, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
||||
@@ -112,7 +112,7 @@ lm78_nvram(lm78_t *dev, uint8_t save)
|
||||
if (save)
|
||||
fwrite(&dev->as99127f.nvram, sizeof(dev->as99127f.nvram), 1, f);
|
||||
else
|
||||
fread(&dev->as99127f.nvram, sizeof(dev->as99127f.nvram), 1, f);
|
||||
(void) !fread(&dev->as99127f.nvram, sizeof(dev->as99127f.nvram), 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ MVHDMeta* mvhd_convert_to_vhd_sparse(const char* utf8_raw_path, const char* utf8
|
||||
copy_sect = total_sectors - i;
|
||||
memset(buff, 0, sizeof buff);
|
||||
}
|
||||
fread(buff, MVHD_SECTOR_SIZE, copy_sect, raw_img);
|
||||
(void) !fread(buff, MVHD_SECTOR_SIZE, copy_sect, raw_img);
|
||||
/* Only write data if there's data to write, to take advantage of the sparse VHD format */
|
||||
if (memcmp(buff, empty_buff, sizeof buff) != 0) {
|
||||
mvhd_write_sectors(vhdm, i, copy_sect, buff);
|
||||
|
||||
@@ -214,7 +214,7 @@ MVHDMeta* mvhd_create_fixed_raw(const char* path, FILE* raw_img, uint64_t size_i
|
||||
mvhd_gen_footer(&vhdm->footer, raw_size, geom, MVHD_TYPE_FIXED, 0);
|
||||
mvhd_fseeko64(raw_img, 0, SEEK_SET);
|
||||
for (s = 0; s < size_sectors; s++) {
|
||||
fread(img_data, sizeof img_data, 1, raw_img);
|
||||
(void) !fread(img_data, sizeof img_data, 1, raw_img);
|
||||
fwrite(img_data, sizeof img_data, 1, f);
|
||||
if (progress_callback)
|
||||
progress_callback(s + 1, size_sectors);
|
||||
|
||||
@@ -62,7 +62,7 @@ void mvhd_write_empty_sectors(FILE* f, int sector_count) {
|
||||
static void mvhd_read_sect_bitmap(MVHDMeta* vhdm, int blk) {
|
||||
if (vhdm->block_offset[blk] != MVHD_SPARSE_BLK) {
|
||||
mvhd_fseeko64(vhdm->f, (uint64_t)vhdm->block_offset[blk] * MVHD_SECTOR_SIZE, SEEK_SET);
|
||||
fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f);
|
||||
(void) !fread(vhdm->bitmap.curr_bitmap, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE, 1, vhdm->f);
|
||||
} else {
|
||||
memset(vhdm->bitmap.curr_bitmap, 0, vhdm->bitmap.sector_count * MVHD_SECTOR_SIZE);
|
||||
}
|
||||
@@ -113,12 +113,12 @@ static void mvhd_create_block(MVHDMeta* vhdm, int blk) {
|
||||
uint8_t footer[MVHD_FOOTER_SIZE];
|
||||
/* Seek to where the footer SHOULD be */
|
||||
mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END);
|
||||
fread(footer, sizeof footer, 1, vhdm->f);
|
||||
(void) !fread(footer, sizeof footer, 1, vhdm->f);
|
||||
mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END);
|
||||
if (!mvhd_is_conectix_str(footer)) {
|
||||
/* Oh dear. We use the header instead, since something has gone wrong at the footer */
|
||||
mvhd_fseeko64(vhdm->f, 0, SEEK_SET);
|
||||
fread(footer, sizeof footer, 1, vhdm->f);
|
||||
(void) !fread(footer, sizeof footer, 1, vhdm->f);
|
||||
mvhd_fseeko64(vhdm->f, 0, SEEK_END);
|
||||
}
|
||||
int64_t abs_offset = mvhd_ftello64(vhdm->f);
|
||||
@@ -150,7 +150,7 @@ int mvhd_fixed_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out_
|
||||
mvhd_check_sectors(offset, num_sectors, total_sectors, &transfer_sectors, &truncated_sectors);
|
||||
addr = (int64_t)offset * MVHD_SECTOR_SIZE;
|
||||
mvhd_fseeko64(vhdm->f, addr, SEEK_SET);
|
||||
fread(out_buff, transfer_sectors*MVHD_SECTOR_SIZE, 1, vhdm->f);
|
||||
(void) !fread(out_buff, transfer_sectors*MVHD_SECTOR_SIZE, 1, vhdm->f);
|
||||
return truncated_sectors;
|
||||
}
|
||||
|
||||
@@ -178,7 +178,7 @@ int mvhd_sparse_read(MVHDMeta* vhdm, uint32_t offset, int num_sectors, void* out
|
||||
}
|
||||
}
|
||||
if (VHD_TESTBIT(vhdm->bitmap.curr_bitmap, sib)) {
|
||||
fread(buff, MVHD_SECTOR_SIZE, 1, vhdm->f);
|
||||
(void) !fread(buff, MVHD_SECTOR_SIZE, 1, vhdm->f);
|
||||
} else {
|
||||
memset(buff, 0, MVHD_SECTOR_SIZE);
|
||||
mvhd_fseeko64(vhdm->f, MVHD_SECTOR_SIZE, SEEK_CUR);
|
||||
|
||||
@@ -45,7 +45,7 @@ static int mvhd_init_sector_bitmap(MVHDMeta* vhdm, MVHDError* err);
|
||||
static void mvhd_read_footer(MVHDMeta* vhdm) {
|
||||
uint8_t buffer[MVHD_FOOTER_SIZE];
|
||||
mvhd_fseeko64(vhdm->f, -MVHD_FOOTER_SIZE, SEEK_END);
|
||||
fread(buffer, sizeof buffer, 1, vhdm->f);
|
||||
(void) !fread(buffer, sizeof buffer, 1, vhdm->f);
|
||||
mvhd_buffer_to_footer(&vhdm->footer, buffer);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ static void mvhd_read_footer(MVHDMeta* vhdm) {
|
||||
static void mvhd_read_sparse_header(MVHDMeta* vhdm) {
|
||||
uint8_t buffer[MVHD_SPARSE_SIZE];
|
||||
mvhd_fseeko64(vhdm->f, vhdm->footer.data_offset, SEEK_SET);
|
||||
fread(buffer, sizeof buffer, 1, vhdm->f);
|
||||
(void) !fread(buffer, sizeof buffer, 1, vhdm->f);
|
||||
mvhd_buffer_to_header(&vhdm->sparse, buffer);
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ static int mvhd_read_bat(MVHDMeta *vhdm, MVHDError* err) {
|
||||
}
|
||||
mvhd_fseeko64(vhdm->f, vhdm->sparse.bat_offset, SEEK_SET);
|
||||
for (uint32_t i = 0; i < vhdm->sparse.max_bat_ent; i++) {
|
||||
fread(&vhdm->block_offset[i], sizeof *vhdm->block_offset, 1, vhdm->f);
|
||||
(void) !fread(&vhdm->block_offset[i], sizeof *vhdm->block_offset, 1, vhdm->f);
|
||||
vhdm->block_offset[i] = mvhd_from_be32(vhdm->block_offset[i]);
|
||||
}
|
||||
return 0;
|
||||
@@ -254,7 +254,7 @@ static char* mvhd_get_diff_parent_path(MVHDMeta* vhdm, int* err) {
|
||||
goto paths_cleanup;
|
||||
}
|
||||
mvhd_fseeko64(vhdm->f, vhdm->sparse.par_loc_entry[i].plat_data_offset, SEEK_SET);
|
||||
fread(paths->tmp_src_path, sizeof (uint8_t), utf_inlen, vhdm->f);
|
||||
(void) !fread(paths->tmp_src_path, sizeof (uint8_t), utf_inlen, vhdm->f);
|
||||
/* Note, the W2*u parent locators are UTF-16LE, unlike the filename field previously obtained,
|
||||
which is UTF-16BE */
|
||||
utf_ret = UTF16LEToUTF8(loc_path, &utf_outlen, (const unsigned char*)paths->tmp_src_path, &utf_inlen);
|
||||
@@ -322,7 +322,7 @@ bool mvhd_file_is_vhd(FILE* f) {
|
||||
if (f) {
|
||||
uint8_t con_str[8];
|
||||
mvhd_fseeko64(f, -MVHD_FOOTER_SIZE, SEEK_END);
|
||||
fread(con_str, sizeof con_str, 1, f);
|
||||
(void) !fread(con_str, sizeof con_str, 1, f);
|
||||
return mvhd_is_conectix_str(con_str);
|
||||
} else {
|
||||
return false;
|
||||
|
||||
@@ -2923,13 +2923,13 @@ d86f_read_track(int drive, int track, int thin_track, int side, uint16_t *da, ui
|
||||
}
|
||||
} else
|
||||
dev->extra_bit_cells[side] = 0;
|
||||
fread(&(dev->index_hole_pos[side]), 4, 1, dev->f);
|
||||
(void) !fread(&(dev->index_hole_pos[side]), 4, 1, dev->f);
|
||||
} else
|
||||
fseek(dev->f, dev->track_offset[logical_track] + d86f_track_header_size(drive), SEEK_SET);
|
||||
array_size = d86f_get_array_size(drive, side, 0);
|
||||
fread(da, 1, array_size, dev->f);
|
||||
(void) !fread(da, 1, array_size, dev->f);
|
||||
if (d86f_has_surface_desc(drive))
|
||||
fread(sa, 1, array_size, dev->f);
|
||||
(void) !fread(sa, 1, array_size, dev->f);
|
||||
} else {
|
||||
if (! thin_track) {
|
||||
switch((dev->disk_flags >> 1) & 3) {
|
||||
@@ -3529,7 +3529,7 @@ d86f_load(int drive, char *fn)
|
||||
len = ftell(dev->f);
|
||||
fseek(dev->f, 0, SEEK_SET);
|
||||
|
||||
fread(&magic, 4, 1, dev->f);
|
||||
(void) !fread(&magic, 4, 1, dev->f);
|
||||
|
||||
if (len < 16) {
|
||||
/* File is WAY too small, abort. */
|
||||
@@ -3570,7 +3570,7 @@ d86f_load(int drive, char *fn)
|
||||
d86f_log("86F: Recognized file version: %i.%02i\n", dev->version >> 8, dev->version & 0xff);
|
||||
}
|
||||
|
||||
fread(&(dev->disk_flags), 2, 1, dev->f);
|
||||
(void) !fread(&(dev->disk_flags), 2, 1, dev->f);
|
||||
|
||||
if (d86f_has_surface_desc(drive)) {
|
||||
for (i = 0; i < 2; i++)
|
||||
@@ -3719,7 +3719,7 @@ d86f_load(int drive, char *fn)
|
||||
|
||||
fseek(dev->f, 8, SEEK_SET);
|
||||
|
||||
fread(dev->track_offset, 1, d86f_get_track_table_size(drive), dev->f);
|
||||
(void) !fread(dev->track_offset, 1, d86f_get_track_table_size(drive), dev->f);
|
||||
|
||||
if (! (dev->track_offset[0])) {
|
||||
/* File has no track 0 side 0, abort. */
|
||||
|
||||
@@ -684,12 +684,12 @@ img_load(int drive, char *fn)
|
||||
/* This is a Japanese FDI image, so let's read the header */
|
||||
img_log("img_load(): File is a Japanese FDI image...\n");
|
||||
fseek(dev->f, 0x10, SEEK_SET);
|
||||
(void)fread(&bpb_bps, 1, 2, dev->f);
|
||||
(void) !fread(&bpb_bps, 1, 2, dev->f);
|
||||
fseek(dev->f, 0x0C, SEEK_SET);
|
||||
(void)fread(&size, 1, 4, dev->f);
|
||||
(void) !fread(&size, 1, 4, dev->f);
|
||||
bpb_total = size / bpb_bps;
|
||||
fseek(dev->f, 0x08, SEEK_SET);
|
||||
(void)fread(&(dev->base), 1, 4, dev->f);
|
||||
(void) !fread(&(dev->base), 1, 4, dev->f);
|
||||
fseek(dev->f, dev->base + 0x15, SEEK_SET);
|
||||
bpb_mid = fgetc(dev->f);
|
||||
if (bpb_mid < 0xF0)
|
||||
@@ -729,7 +729,7 @@ img_load(int drive, char *fn)
|
||||
dev->disk_at_once = 1;
|
||||
|
||||
fseek(dev->f, 0x50, SEEK_SET);
|
||||
(void)fread(&dev->tracks, 1, 4, dev->f);
|
||||
(void) !fread(&dev->tracks, 1, 4, dev->f);
|
||||
|
||||
/* Decode the entire file - pass 1, no write to buffer, determine length. */
|
||||
fseek(dev->f, 0x80, SEEK_SET);
|
||||
@@ -740,10 +740,10 @@ img_load(int drive, char *fn)
|
||||
if (! track_bytes) {
|
||||
/* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */
|
||||
first_byte = fgetc(dev->f);
|
||||
fread(&track_bytes, 1, 2, dev->f);
|
||||
(void) !fread(&track_bytes, 1, 2, dev->f);
|
||||
img_log("Block header: %02X %04X ", first_byte, track_bytes);
|
||||
/* Read the length of encoded data block. */
|
||||
fread(&track_bytes, 1, 2, dev->f);
|
||||
(void) !fread(&track_bytes, 1, 2, dev->f);
|
||||
img_log("%04X\n", track_bytes);
|
||||
}
|
||||
|
||||
@@ -765,7 +765,7 @@ img_load(int drive, char *fn)
|
||||
/* Literal. */
|
||||
track_bytes -= (run & 0x7f);
|
||||
literal = (uint8_t *)malloc(run & 0x7f);
|
||||
fread(literal, 1, (run & 0x7f), dev->f);
|
||||
(void) !fread(literal, 1, (run & 0x7f), dev->f);
|
||||
free(literal);
|
||||
}
|
||||
size += (run & 0x7f);
|
||||
@@ -775,7 +775,7 @@ img_load(int drive, char *fn)
|
||||
/* Literal block. */
|
||||
size += (track_bytes - fdf_suppress_final_byte);
|
||||
literal = (uint8_t *)malloc(track_bytes);
|
||||
fread(literal, 1, track_bytes, dev->f);
|
||||
(void) !fread(literal, 1, track_bytes, dev->f);
|
||||
free(literal);
|
||||
track_bytes = 0;
|
||||
}
|
||||
@@ -794,10 +794,10 @@ img_load(int drive, char *fn)
|
||||
if (! track_bytes) {
|
||||
/* Skip first 3 bytes - their meaning is unknown to us but could be a checksum. */
|
||||
first_byte = fgetc(dev->f);
|
||||
fread(&track_bytes, 1, 2, dev->f);
|
||||
(void) !fread(&track_bytes, 1, 2, dev->f);
|
||||
img_log("Block header: %02X %04X ", first_byte, track_bytes);
|
||||
/* Read the length of encoded data block. */
|
||||
fread(&track_bytes, 1, 2, dev->f);
|
||||
(void) !fread(&track_bytes, 1, 2, dev->f);
|
||||
img_log("%04X\n", track_bytes);
|
||||
}
|
||||
|
||||
@@ -824,7 +824,7 @@ img_load(int drive, char *fn)
|
||||
/* Literal. */
|
||||
track_bytes -= real_run;
|
||||
literal = (uint8_t *) malloc(real_run);
|
||||
fread(literal, 1, real_run, dev->f);
|
||||
(void) !fread(literal, 1, real_run, dev->f);
|
||||
if (! track_bytes)
|
||||
real_run -= fdf_suppress_final_byte;
|
||||
if (run & 0x7f)
|
||||
@@ -835,7 +835,7 @@ img_load(int drive, char *fn)
|
||||
} else {
|
||||
/* Literal block. */
|
||||
literal = (uint8_t *) malloc(track_bytes);
|
||||
fread(literal, 1, track_bytes, dev->f);
|
||||
(void) !fread(literal, 1, track_bytes, dev->f);
|
||||
memcpy(bpos, literal, track_bytes - fdf_suppress_final_byte);
|
||||
free(literal);
|
||||
bpos += (track_bytes - fdf_suppress_final_byte);
|
||||
@@ -865,10 +865,10 @@ img_load(int drive, char *fn)
|
||||
dev->f = plat_fopen(fn, "rb");
|
||||
|
||||
fseek(dev->f, 0x03, SEEK_SET);
|
||||
fread(&bpb_bps, 1, 2, dev->f);
|
||||
(void) !fread(&bpb_bps, 1, 2, dev->f);
|
||||
#if 0
|
||||
fseek(dev->f, 0x0B, SEEK_SET);
|
||||
fread(&bpb_total, 1, 2, dev->f);
|
||||
(void) !fread(&bpb_total, 1, 2, dev->f);
|
||||
#endif
|
||||
fseek(dev->f, 0x10, SEEK_SET);
|
||||
bpb_sectors = fgetc(dev->f);
|
||||
@@ -888,7 +888,7 @@ img_load(int drive, char *fn)
|
||||
memset(dev->disk_data, 0xf6, ((uint32_t) bpb_total) * ((uint32_t) bpb_bps));
|
||||
|
||||
fseek(dev->f, 0x6F, SEEK_SET);
|
||||
fread(&comment_len, 1, 2, dev->f);
|
||||
(void) !fread(&comment_len, 1, 2, dev->f);
|
||||
|
||||
fseek(dev->f, -1, SEEK_END);
|
||||
size = ftell(dev->f) + 1;
|
||||
@@ -898,7 +898,7 @@ img_load(int drive, char *fn)
|
||||
cur_pos = 0;
|
||||
|
||||
while(! feof(dev->f)) {
|
||||
fread(&block_len, 1, 2, dev->f);
|
||||
(void) !fread(&block_len, 1, 2, dev->f);
|
||||
|
||||
if (! feof(dev->f)) {
|
||||
if (block_len < 0) {
|
||||
@@ -915,10 +915,10 @@ img_load(int drive, char *fn)
|
||||
} else if (block_len > 0) {
|
||||
if ((cur_pos + block_len) > ((uint32_t) bpb_total) * ((uint32_t) bpb_bps)) {
|
||||
block_len = ((uint32_t) bpb_total) * ((uint32_t) bpb_bps) - cur_pos;
|
||||
fread(dev->disk_data + cur_pos, 1, block_len, dev->f);
|
||||
(void) !fread(dev->disk_data + cur_pos, 1, block_len, dev->f);
|
||||
break;
|
||||
} else {
|
||||
fread(dev->disk_data + cur_pos, 1, block_len, dev->f);
|
||||
(void) !fread(dev->disk_data + cur_pos, 1, block_len, dev->f);
|
||||
cur_pos += block_len;
|
||||
}
|
||||
}
|
||||
@@ -939,9 +939,9 @@ img_load(int drive, char *fn)
|
||||
} else
|
||||
img_log("img_load(): File is a raw image...\n");
|
||||
fseek(dev->f, dev->base + 0x0B, SEEK_SET);
|
||||
fread(&bpb_bps, 1, 2, dev->f);
|
||||
(void) !fread(&bpb_bps, 1, 2, dev->f);
|
||||
fseek(dev->f, dev->base + 0x13, SEEK_SET);
|
||||
fread(&bpb_total, 1, 2, dev->f);
|
||||
(void) !fread(&bpb_total, 1, 2, dev->f);
|
||||
fseek(dev->f, dev->base + 0x15, SEEK_SET);
|
||||
bpb_mid = fgetc(dev->f);
|
||||
fseek(dev->f, dev->base + 0x18, SEEK_SET);
|
||||
@@ -1112,7 +1112,7 @@ jump_if_fdf:
|
||||
/* The image is a Japanese FDI, therefore we read the number of tracks from the header. */
|
||||
if (fseek(dev->f, 0x1C, SEEK_SET) == -1)
|
||||
fatal("Japanese FDI: Failed when seeking to 0x1C\n");
|
||||
fread(&(dev->tracks), 1, 4, dev->f);
|
||||
(void) !fread(&(dev->tracks), 1, 4, dev->f);
|
||||
} else {
|
||||
if (!cqm && !fdf) {
|
||||
/* Number of tracks = number of total sectors divided by sides times sectors per track. */
|
||||
|
||||
@@ -645,7 +645,7 @@ td0_initialize(int drive)
|
||||
}
|
||||
|
||||
fseek(dev->f, 0, SEEK_SET);
|
||||
fread(header, 1, 12, dev->f);
|
||||
(void) !fread(header, 1, 12, dev->f);
|
||||
head_count = header[9];
|
||||
|
||||
if (header[0] == 't') {
|
||||
|
||||
@@ -20,11 +20,18 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#ifdef _WIN32
|
||||
# ifndef __clang__
|
||||
# include <unistd.h>
|
||||
# else
|
||||
# include <io.h>
|
||||
# define ssize_t long
|
||||
# define strtok_r(a, b, c) strtok_s(a, b, c)
|
||||
# endif
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# include <arpa/inet.h>
|
||||
# include <sys/socket.h>
|
||||
# include <errno.h>
|
||||
@@ -706,6 +713,8 @@ gdbstub_client_read_reg(int index, uint8_t *buf)
|
||||
static void
|
||||
gdbstub_client_packet(gdbstub_client_t *client)
|
||||
{
|
||||
gdbstub_breakpoint_t *breakpoint, *prev_breakpoint = NULL, **first_breakpoint = NULL;
|
||||
|
||||
#ifdef GDBSTUB_CHECK_CHECKSUM /* msys2 gdb 11.1 transmits qSupported and H with invalid checksum... */
|
||||
uint8_t rcv_checksum = 0, checksum = 0;
|
||||
#endif
|
||||
@@ -1202,7 +1211,6 @@ unknown:
|
||||
|
||||
case 'z': /* remove break/watchpoint */
|
||||
case 'Z': /* insert break/watchpoint */
|
||||
gdbstub_breakpoint_t *breakpoint, *prev_breakpoint = NULL, **first_breakpoint;
|
||||
|
||||
/* Parse breakpoint type. */
|
||||
switch (client->packet[1]) {
|
||||
|
||||
35
src/include/86box/agpgart.h
Normal file
35
src/include/86box/agpgart.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||
* running old operating systems and software designed for IBM
|
||||
* PC systems and compatibles from 1981 through fairly recent
|
||||
* system designs based on the PCI bus.
|
||||
*
|
||||
* This file is part of the 86Box distribution.
|
||||
*
|
||||
* AGP Graphics Address Remapping Table remapping emulation.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Authors: RichardG, <richardg867@gmail.com>
|
||||
*
|
||||
* Copyright 2021 RichardG.
|
||||
*/
|
||||
|
||||
#ifndef EMU_AGPGART_H
|
||||
#define EMU_AGPGART_H
|
||||
|
||||
typedef struct agpgart_s {
|
||||
int aperture_enable;
|
||||
uint32_t aperture_base, aperture_size, aperture_mask, gart_base;
|
||||
mem_mapping_t aperture_mapping;
|
||||
} agpgart_t;
|
||||
|
||||
extern void agpgart_set_aperture(agpgart_t *dev, uint32_t base, uint32_t size, int enable);
|
||||
extern void agpgart_set_gart(agpgart_t *dev, uint32_t base);
|
||||
|
||||
#ifdef EMU_DEVICE_H
|
||||
/* AGP GART */
|
||||
extern const device_t agpgart_device;
|
||||
#endif
|
||||
|
||||
#endif /*EMU_AGPGART_H*/
|
||||
@@ -361,9 +361,9 @@
|
||||
#define IDM_ACTION_END_TRACE 40019
|
||||
#define IDM_ACTION_TRACE 40020
|
||||
#endif
|
||||
#define IDM_CONFIG 40020
|
||||
#define IDM_VID_HIDE_STATUS_BAR 40021
|
||||
#define IDM_VID_HIDE_TOOLBAR 40022
|
||||
#define IDM_CONFIG 40021
|
||||
#define IDM_VID_HIDE_STATUS_BAR 40022
|
||||
#define IDM_VID_HIDE_TOOLBAR 40023
|
||||
#define IDM_UPDATE_ICONS 40030
|
||||
#define IDM_SND_GAIN 40031
|
||||
#define IDM_VID_RESIZE 40040
|
||||
|
||||
@@ -258,9 +258,6 @@ extern int get_actual_size_y(void);
|
||||
|
||||
extern uint32_t video_color_transform(uint32_t color);
|
||||
|
||||
extern void agpgart_set_aperture(void *handle, uint32_t base, uint32_t size, int enable);
|
||||
extern void agpgart_set_gart(void *handle, uint32_t base);
|
||||
|
||||
#define video_inform(type, video_timings_ptr) video_inform_monitor(type, video_timings_ptr, monitor_index_global)
|
||||
#define video_get_type() video_get_type_monitor(0)
|
||||
#define video_blend(x, y) video_blend_monitor(x, y, monitor_index_global)
|
||||
@@ -532,8 +529,6 @@ extern const device_t velocity_100_agp_device;
|
||||
/* Wyse 700 */
|
||||
extern const device_t wy700_device;
|
||||
|
||||
/* AGP GART */
|
||||
extern const device_t agpgart_device;
|
||||
#endif
|
||||
|
||||
#endif /*EMU_VIDEO_H*/
|
||||
|
||||
@@ -1041,7 +1041,7 @@ t1000_emsboard_load(void)
|
||||
if (mem_size > 512) {
|
||||
f = plat_fopen(nvr_path("t1000_ems.nvr"), "rb");
|
||||
if (f != NULL) {
|
||||
fread(&ram[512 * 1024], 1024, (mem_size - 512), f);
|
||||
(void) !fread(&ram[512 * 1024], 1024, (mem_size - 512), f);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ catalyst_flash_init(const device_t *info)
|
||||
|
||||
f = nvr_fopen(flash_path, "rb");
|
||||
if (f) {
|
||||
fread(dev->array, 0x20000, 1, f);
|
||||
(void) !fread(dev->array, 0x20000, 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
||||
@@ -518,16 +518,16 @@ intel_flash_init(const device_t *info)
|
||||
|
||||
f = nvr_fopen(flash_path, "rb");
|
||||
if (f) {
|
||||
fread(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f);
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN1]]), dev->block_len[BLOCK_MAIN1], 1, f);
|
||||
if (dev->block_len[BLOCK_MAIN2])
|
||||
fread(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f);
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN2]]), dev->block_len[BLOCK_MAIN2], 1, f);
|
||||
if (dev->block_len[BLOCK_MAIN3])
|
||||
fread(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, f);
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN3]]), dev->block_len[BLOCK_MAIN3], 1, f);
|
||||
if (dev->block_len[BLOCK_MAIN4])
|
||||
fread(&(dev->array[dev->block_start[BLOCK_MAIN4]]), dev->block_len[BLOCK_MAIN4], 1, f);
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_MAIN4]]), dev->block_len[BLOCK_MAIN4], 1, f);
|
||||
|
||||
fread(&(dev->array[dev->block_start[BLOCK_DATA1]]), dev->block_len[BLOCK_DATA1], 1, f);
|
||||
fread(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f);
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_DATA1]]), dev->block_len[BLOCK_DATA1], 1, f);
|
||||
(void) !fread(&(dev->array[dev->block_start[BLOCK_DATA2]]), dev->block_len[BLOCK_DATA2], 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,9 +30,9 @@
|
||||
#include <pthread.h>
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdatomic.h>
|
||||
#endif
|
||||
|
||||
#include <stdatomic.h>
|
||||
#include <minitrace/minitrace.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
@@ -293,8 +293,13 @@ void mtr_start() {
|
||||
#ifndef MTR_ENABLED
|
||||
return;
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
pthread_cond_init(&buffer_not_full_cond);
|
||||
pthread_cond_init(&buffer_full_cond);
|
||||
#else
|
||||
pthread_cond_init(&buffer_not_full_cond, NULL);
|
||||
pthread_cond_init(&buffer_full_cond, NULL);
|
||||
#endif
|
||||
atomic_store(&is_tracing, TRUE);
|
||||
init_flushing_thread();
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ net_event_init(net_evt_t *event)
|
||||
#ifdef _WIN32
|
||||
event->handle = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
#else
|
||||
(void)pipe(event->fds);
|
||||
(void) !pipe(event->fds);
|
||||
setup_fd(event->fds[0]);
|
||||
setup_fd(event->fds[1]);
|
||||
#endif
|
||||
@@ -35,7 +35,7 @@ net_event_set(net_evt_t *event)
|
||||
#ifdef _WIN32
|
||||
SetEvent(event->handle);
|
||||
#else
|
||||
(void)write(event->fds[1], "a", 1);
|
||||
(void) !write(event->fds[1], "a", 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ net_event_clear(net_evt_t *event)
|
||||
/* Do nothing on WIN32 since we use an auto-reset event */
|
||||
#else
|
||||
char dummy[1];
|
||||
(void)read(event->fds[0], &dummy, sizeof(dummy));
|
||||
(void) !read(event->fds[0], &dummy, sizeof(dummy));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +182,12 @@ if(WIN32)
|
||||
enable_language(RC)
|
||||
target_sources(86Box PUBLIC ../win/86Box-qt.rc)
|
||||
target_sources(plat PRIVATE win_dynld.c)
|
||||
target_sources(plat PRIVATE win_joystick_rawinput.c)
|
||||
if(DINPUT)
|
||||
target_sources(plat PRIVATE win_joystick.cpp)
|
||||
target_link_libraries(86Box dinput8)
|
||||
else()
|
||||
target_sources(plat PRIVATE win_joystick_rawinput.c)
|
||||
endif()
|
||||
target_sources(ui PRIVATE qt_d3d9renderer.hpp qt_d3d9renderer.cpp)
|
||||
target_link_libraries(86Box hid d3d9)
|
||||
|
||||
|
||||
@@ -289,7 +289,7 @@ MediaHistoryManager::removeMissingImages(device_index_list_t &device_history)
|
||||
continue;
|
||||
}
|
||||
// For this check, explicitly prepend `usr_path` to relative paths to account for $CWD platform variances
|
||||
QFileInfo absolute_path = file_info.isRelative() ? getUsrPath().append(file_info.filePath()) : file_info;
|
||||
QFileInfo absolute_path = file_info.isRelative() ? QFileInfo(getUsrPath().append(file_info.filePath())) : file_info;
|
||||
if(!absolute_path.exists()) {
|
||||
qWarning("Image file %s does not exist - removing from history", qPrintable(file_info.filePath()));
|
||||
checked_path = "";
|
||||
|
||||
@@ -758,11 +758,11 @@ aha_setbios(x54x_t *dev)
|
||||
|
||||
/* Load first chunk of BIOS (which is the main BIOS, aka ROM1.) */
|
||||
dev->rom1 = malloc(ROM_SIZE);
|
||||
(void)fread(dev->rom1, ROM_SIZE, 1, f);
|
||||
(void) !fread(dev->rom1, ROM_SIZE, 1, f);
|
||||
temp -= ROM_SIZE;
|
||||
if (temp > 0) {
|
||||
dev->rom2 = malloc(ROM_SIZE);
|
||||
(void)fread(dev->rom2, ROM_SIZE, 1, f);
|
||||
(void) !fread(dev->rom2, ROM_SIZE, 1, f);
|
||||
temp -= ROM_SIZE;
|
||||
} else {
|
||||
dev->rom2 = NULL;
|
||||
@@ -875,10 +875,10 @@ aha_setmcode(x54x_t *dev)
|
||||
}
|
||||
aha1542cp_pnp_rom = (uint8_t *) malloc(dev->pnp_len + 7);
|
||||
fseek(f, dev->pnp_offset, SEEK_SET);
|
||||
(void)fread(aha1542cp_pnp_rom, dev->pnp_len, 1, f);
|
||||
(void) !fread(aha1542cp_pnp_rom, dev->pnp_len, 1, f);
|
||||
memset(&(aha1542cp_pnp_rom[4]), 0x00, 5);
|
||||
fseek(f, dev->pnp_offset + 4, SEEK_SET);
|
||||
(void)fread(&(aha1542cp_pnp_rom[9]), dev->pnp_len - 4, 1, f);
|
||||
(void) !fread(&(aha1542cp_pnp_rom[9]), dev->pnp_len - 4, 1, f);
|
||||
/* Even the real AHA-1542CP microcode seem to be flipping bit
|
||||
4 to not erroneously indicate there is a range length. */
|
||||
aha1542cp_pnp_rom[0x87] |= 0x04;
|
||||
@@ -889,7 +889,7 @@ aha_setmcode(x54x_t *dev)
|
||||
|
||||
/* Load the SCSISelect decompression code. */
|
||||
fseek(f, dev->cmd_33_offset, SEEK_SET);
|
||||
(void)fread(dev->cmd_33_buf, dev->cmd_33_len, 1, f);
|
||||
(void) !fread(dev->cmd_33_buf, dev->cmd_33_len, 1, f);
|
||||
|
||||
(void)fclose(f);
|
||||
}
|
||||
|
||||
@@ -1747,7 +1747,7 @@ buslogic_init(const device_t *info)
|
||||
if (has_autoscsi_rom) {
|
||||
f = rom_fopen(autoscsi_rom_name, "rb");
|
||||
if (f) {
|
||||
fread(bl->AutoSCSIROM, 1, autoscsi_rom_size, f);
|
||||
(void) !fread(bl->AutoSCSIROM, 1, autoscsi_rom_size, f);
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
}
|
||||
@@ -1756,7 +1756,7 @@ buslogic_init(const device_t *info)
|
||||
if (has_scam_rom) {
|
||||
f = rom_fopen(scam_rom_name, "rb");
|
||||
if (f) {
|
||||
fread(bl->SCAMData, 1, scam_rom_size, f);
|
||||
(void) !fread(bl->SCAMData, 1, scam_rom_size, f);
|
||||
fclose(f);
|
||||
f = NULL;
|
||||
}
|
||||
|
||||
@@ -1464,7 +1464,7 @@ ncr53c8xx_eeprom(ncr53c8xx_t *dev, uint8_t save)
|
||||
if (save)
|
||||
fwrite(&dev->nvram, sizeof(dev->nvram), 1, f);
|
||||
else
|
||||
fread(&dev->nvram, sizeof(dev->nvram), 1, f);
|
||||
(void) !fread(&dev->nvram, sizeof(dev->nvram), 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -156,7 +156,7 @@ cs423x_nvram(cs423x_t *dev, uint8_t save)
|
||||
if (save)
|
||||
fwrite(dev->eeprom_data, sizeof(dev->eeprom_data), 1, f);
|
||||
else
|
||||
fread(dev->eeprom_data, sizeof(dev->eeprom_data), 1, f);
|
||||
(void) !fread(dev->eeprom_data, sizeof(dev->eeprom_data), 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,14 +23,7 @@
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
#include <86box/mem.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
int aperture_enable;
|
||||
uint32_t aperture_base, aperture_size, aperture_mask, gart_base;
|
||||
mem_mapping_t aperture_mapping;
|
||||
} agpgart_t;
|
||||
|
||||
#include <86box/agpgart.h>
|
||||
|
||||
#ifdef ENABLE_AGPGART_LOG
|
||||
int agpgart_do_log = ENABLE_AGPGART_LOG;
|
||||
@@ -41,51 +34,45 @@ agpgart_log(const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
if (agpgart_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define agpgart_log(fmt, ...)
|
||||
# define agpgart_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
agpgart_set_aperture(void *handle, uint32_t base, uint32_t size, int enable)
|
||||
agpgart_set_aperture(agpgart_t *dev, uint32_t base, uint32_t size, int enable)
|
||||
{
|
||||
agpgart_t *dev = (agpgart_t *) handle;
|
||||
|
||||
agpgart_log("AGP GART: set_aperture(%08X, %d, %d)\n", base, size, enable);
|
||||
|
||||
/* Disable old aperture mapping. */
|
||||
mem_mapping_disable(&dev->aperture_mapping);
|
||||
|
||||
/* Set new aperture base address, size and mask. */
|
||||
/* Set new aperture base address, size, mask and enable. */
|
||||
dev->aperture_base = base;
|
||||
dev->aperture_size = size;
|
||||
dev->aperture_mask = size - 1;
|
||||
dev->aperture_enable = enable;
|
||||
|
||||
/* Enable new aperture mapping if requested. */
|
||||
if (dev->aperture_base && dev->aperture_size && dev->aperture_enable) {
|
||||
mem_mapping_set_addr(&dev->aperture_mapping, dev->aperture_base, dev->aperture_size);
|
||||
mem_mapping_enable(&dev->aperture_mapping);
|
||||
mem_mapping_set_addr(&dev->aperture_mapping, dev->aperture_base, dev->aperture_size);
|
||||
mem_mapping_enable(&dev->aperture_mapping);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
agpgart_set_gart(void *handle, uint32_t base)
|
||||
agpgart_set_gart(agpgart_t *dev, uint32_t base)
|
||||
{
|
||||
agpgart_t *dev = (agpgart_t *) handle;
|
||||
|
||||
agpgart_log("AGP GART: set_gart(%08X)\n", base);
|
||||
|
||||
/* Set GART base address. */
|
||||
dev->gart_base = base;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
agpgart_translate(uint32_t addr, agpgart_t *dev)
|
||||
{
|
||||
@@ -99,7 +86,6 @@ agpgart_translate(uint32_t addr, agpgart_t *dev)
|
||||
return gart_ptr | (addr & 0x00000fff);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
agpgart_aperture_readb(uint32_t addr, void *priv)
|
||||
{
|
||||
@@ -107,7 +93,6 @@ agpgart_aperture_readb(uint32_t addr, void *priv)
|
||||
return mem_readb_phys(agpgart_translate(addr, dev));
|
||||
}
|
||||
|
||||
|
||||
static uint16_t
|
||||
agpgart_aperture_readw(uint32_t addr, void *priv)
|
||||
{
|
||||
@@ -115,7 +100,6 @@ agpgart_aperture_readw(uint32_t addr, void *priv)
|
||||
return mem_readw_phys(agpgart_translate(addr, dev));
|
||||
}
|
||||
|
||||
|
||||
static uint32_t
|
||||
agpgart_aperture_readl(uint32_t addr, void *priv)
|
||||
{
|
||||
@@ -123,7 +107,6 @@ agpgart_aperture_readl(uint32_t addr, void *priv)
|
||||
return mem_readl_phys(agpgart_translate(addr, dev));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
agpgart_aperture_writeb(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
@@ -131,7 +114,6 @@ agpgart_aperture_writeb(uint32_t addr, uint8_t val, void *priv)
|
||||
mem_writeb_phys(agpgart_translate(addr, dev), val);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
agpgart_aperture_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
{
|
||||
@@ -139,7 +121,6 @@ agpgart_aperture_writew(uint32_t addr, uint16_t val, void *priv)
|
||||
mem_writew_phys(agpgart_translate(addr, dev), val);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
agpgart_aperture_writel(uint32_t addr, uint32_t val, void *priv)
|
||||
{
|
||||
@@ -147,7 +128,6 @@ agpgart_aperture_writel(uint32_t addr, uint32_t val, void *priv)
|
||||
mem_writel_phys(agpgart_translate(addr, dev), val);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
agpgart_init(const device_t *info)
|
||||
{
|
||||
@@ -158,14 +138,13 @@ agpgart_init(const device_t *info)
|
||||
|
||||
/* Create aperture mapping. */
|
||||
mem_mapping_add(&dev->aperture_mapping, 0, 0,
|
||||
agpgart_aperture_readb, agpgart_aperture_readw, agpgart_aperture_readl,
|
||||
agpgart_aperture_writeb, agpgart_aperture_writew, agpgart_aperture_writel,
|
||||
NULL, MEM_MAPPING_EXTERNAL, dev);
|
||||
agpgart_aperture_readb, agpgart_aperture_readw, agpgart_aperture_readl,
|
||||
agpgart_aperture_writeb, agpgart_aperture_writew, agpgart_aperture_writel,
|
||||
NULL, MEM_MAPPING_EXTERNAL, dev);
|
||||
|
||||
return dev;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
agpgart_close(void *priv)
|
||||
{
|
||||
@@ -180,15 +159,15 @@ agpgart_close(void *priv)
|
||||
}
|
||||
|
||||
const device_t agpgart_device = {
|
||||
.name = "AGP Graphics Address Remapping Table",
|
||||
.name = "AGP Graphics Address Remapping Table",
|
||||
.internal_name = "agpgart",
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = agpgart_init,
|
||||
.close = agpgart_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_PCI,
|
||||
.local = 0,
|
||||
.init = agpgart_init,
|
||||
.close = agpgart_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -32,296 +32,293 @@
|
||||
#include <86box/vid_svga.h>
|
||||
#include <86box/vid_svga_render.h>
|
||||
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_VGAWONDER)
|
||||
#define BIOS_ROM_PATH_WONDER "roms/video/ati18800/VGA_Wonder_V3-1.02.bin"
|
||||
# define BIOS_ROM_PATH_WONDER "roms/video/ati18800/VGA_Wonder_V3-1.02.bin"
|
||||
#endif
|
||||
#define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin"
|
||||
#define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi"
|
||||
#define BIOS_ROM_PATH_VGA88 "roms/video/ati18800/vga88.bin"
|
||||
#define BIOS_ROM_PATH_EDGE16 "roms/video/ati18800/vgaedge16.vbi"
|
||||
|
||||
enum {
|
||||
#if defined(DEV_BRANCH) && defined(USE_VGAWONDER)
|
||||
ATI18800_WONDER = 0,
|
||||
ATI18800_VGA88,
|
||||
ATI18800_EDGE16
|
||||
ATI18800_WONDER = 0,
|
||||
ATI18800_VGA88,
|
||||
ATI18800_EDGE16
|
||||
#else
|
||||
ATI18800_VGA88 = 0,
|
||||
ATI18800_EDGE16
|
||||
ATI18800_VGA88 = 0,
|
||||
ATI18800_EDGE16
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef struct ati18800_t {
|
||||
svga_t svga;
|
||||
ati_eeprom_t eeprom;
|
||||
|
||||
typedef struct ati18800_t
|
||||
{
|
||||
svga_t svga;
|
||||
ati_eeprom_t eeprom;
|
||||
rom_t bios_rom;
|
||||
|
||||
rom_t bios_rom;
|
||||
|
||||
uint8_t regs[256];
|
||||
int index;
|
||||
uint8_t regs[256];
|
||||
int index;
|
||||
} ati18800_t;
|
||||
|
||||
static video_timings_t timing_ati18800 = {VIDEO_ISA, 8, 16, 32, 8, 16, 32};
|
||||
static video_timings_t timing_ati18800 = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
|
||||
|
||||
|
||||
static void ati18800_out(uint16_t addr, uint8_t val, void *p)
|
||||
static void
|
||||
ati18800_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
ati18800_t *ati18800 = (ati18800_t *)p;
|
||||
svga_t *svga = &ati18800->svga;
|
||||
uint8_t old;
|
||||
ati18800_t *ati18800 = (ati18800_t *) p;
|
||||
svga_t *svga = &ati18800->svga;
|
||||
uint8_t old;
|
||||
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x1ce:
|
||||
ati18800->index = val;
|
||||
break;
|
||||
case 0x1cf:
|
||||
ati18800->regs[ati18800->index] = val;
|
||||
switch (ati18800->index)
|
||||
{
|
||||
case 0xb0:
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
case 0xb2:
|
||||
case 0xbe:
|
||||
if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/
|
||||
{
|
||||
svga->read_bank = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000;
|
||||
svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000;
|
||||
}
|
||||
else /*Single bank mode*/
|
||||
svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000;
|
||||
break;
|
||||
case 0xb3:
|
||||
ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
switch (addr) {
|
||||
case 0x1ce:
|
||||
ati18800->index = val;
|
||||
break;
|
||||
case 0x1cf:
|
||||
ati18800->regs[ati18800->index] = val;
|
||||
switch (ati18800->index) {
|
||||
case 0xb0:
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
case 0xb2:
|
||||
case 0xbe:
|
||||
if (ati18800->regs[0xbe] & 8) /*Read/write bank mode*/
|
||||
{
|
||||
svga->read_bank = ((ati18800->regs[0xb2] >> 5) & 7) * 0x10000;
|
||||
svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000;
|
||||
} else /*Single bank mode*/
|
||||
svga->read_bank = svga->write_bank = ((ati18800->regs[0xb2] >> 1) & 7) * 0x10000;
|
||||
break;
|
||||
case 0xb3:
|
||||
ati_eeprom_write(&ati18800->eeprom, val & 8, val & 2, val & 1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3D4:
|
||||
svga->crtcreg = val & 0x3f;
|
||||
case 0x3D4:
|
||||
svga->crtcreg = val & 0x3f;
|
||||
return;
|
||||
case 0x3D5:
|
||||
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80) && !(ati18800->regs[0xb4] & 0x80))
|
||||
return;
|
||||
case 0x3D5:
|
||||
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80) && !(ati18800->regs[0xb4] & 0x80))
|
||||
return;
|
||||
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80) && !(ati18800->regs[0xb4] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val)
|
||||
{
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
|
||||
{
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80) && !(ati18800->regs[0xb4] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val) {
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
static uint8_t ati18800_in(uint16_t addr, void *p)
|
||||
static uint8_t
|
||||
ati18800_in(uint16_t addr, void *p)
|
||||
{
|
||||
ati18800_t *ati18800 = (ati18800_t *)p;
|
||||
svga_t *svga = &ati18800->svga;
|
||||
uint8_t temp = 0xff;
|
||||
ati18800_t *ati18800 = (ati18800_t *) p;
|
||||
svga_t *svga = &ati18800->svga;
|
||||
uint8_t temp = 0xff;
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout&1)) addr ^= 0x60;
|
||||
if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x1ce:
|
||||
temp = ati18800->index;
|
||||
break;
|
||||
case 0x1cf:
|
||||
switch (ati18800->index)
|
||||
{
|
||||
case 0xb7:
|
||||
temp = ati18800->regs[ati18800->index] & ~8;
|
||||
if (ati_eeprom_read(&ati18800->eeprom))
|
||||
temp |= 8;
|
||||
break;
|
||||
default:
|
||||
temp = ati18800->regs[ati18800->index];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3D4:
|
||||
temp = svga->crtcreg;
|
||||
break;
|
||||
case 0x3D5:
|
||||
temp = svga->crtc[svga->crtcreg];
|
||||
break;
|
||||
switch (addr) {
|
||||
case 0x1ce:
|
||||
temp = ati18800->index;
|
||||
break;
|
||||
case 0x1cf:
|
||||
switch (ati18800->index) {
|
||||
case 0xb7:
|
||||
temp = ati18800->regs[ati18800->index] & ~8;
|
||||
if (ati_eeprom_read(&ati18800->eeprom))
|
||||
temp |= 8;
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
}
|
||||
return temp;
|
||||
temp = ati18800->regs[ati18800->index];
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3D4:
|
||||
temp = svga->crtcreg;
|
||||
break;
|
||||
case 0x3D5:
|
||||
temp = svga->crtc[svga->crtcreg];
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
static void ati18800_recalctimings(svga_t *svga)
|
||||
static void
|
||||
ati18800_recalctimings(svga_t *svga)
|
||||
{
|
||||
ati18800_t *ati18800 = (ati18800_t *)svga->p;
|
||||
ati18800_t *ati18800 = (ati18800_t *) svga->p;
|
||||
|
||||
if(svga->crtc[0x17] & 4)
|
||||
{
|
||||
svga->vtotal <<= 1;
|
||||
svga->dispend <<= 1;
|
||||
svga->vsyncstart <<= 1;
|
||||
svga->split <<= 1;
|
||||
svga->vblankstart <<= 1;
|
||||
}
|
||||
if (svga->crtc[0x17] & 4) {
|
||||
svga->vtotal <<= 1;
|
||||
svga->dispend <<= 1;
|
||||
svga->vsyncstart <<= 1;
|
||||
svga->split <<= 1;
|
||||
svga->vblankstart <<= 1;
|
||||
}
|
||||
|
||||
if (!svga->scrblank && ((ati18800->regs[0xb0] & 0x02) || (ati18800->regs[0xb0] & 0x04))) /*Extended 256 colour modes*/
|
||||
{
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
svga->bpp = 8;
|
||||
svga->rowoffset <<= 1;
|
||||
svga->ma <<= 1;
|
||||
}
|
||||
if (!svga->scrblank && ((ati18800->regs[0xb0] & 0x02) || (ati18800->regs[0xb0] & 0x04))) /*Extended 256 colour modes*/
|
||||
{
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
svga->bpp = 8;
|
||||
svga->rowoffset <<= 1;
|
||||
svga->ma <<= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void *ati18800_init(const device_t *info)
|
||||
static void *
|
||||
ati18800_init(const device_t *info)
|
||||
{
|
||||
ati18800_t *ati18800 = malloc(sizeof(ati18800_t));
|
||||
memset(ati18800, 0, sizeof(ati18800_t));
|
||||
ati18800_t *ati18800 = malloc(sizeof(ati18800_t));
|
||||
memset(ati18800, 0, sizeof(ati18800_t));
|
||||
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati18800);
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ati18800);
|
||||
|
||||
switch (info->local) {
|
||||
switch (info->local) {
|
||||
#if defined(DEV_BRANCH) && defined(USE_VGAWONDER)
|
||||
case ATI18800_WONDER:
|
||||
case ATI18800_WONDER:
|
||||
#endif
|
||||
default:
|
||||
default:
|
||||
#if defined(DEV_BRANCH) && defined(USE_VGAWONDER)
|
||||
rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_WONDER, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
break;
|
||||
rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_WONDER, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
break;
|
||||
#endif
|
||||
case ATI18800_VGA88:
|
||||
rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_VGA88, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
break;
|
||||
case ATI18800_EDGE16:
|
||||
rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_EDGE16, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
break;
|
||||
};
|
||||
case ATI18800_VGA88:
|
||||
rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_VGA88, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
break;
|
||||
case ATI18800_EDGE16:
|
||||
rom_init(&ati18800->bios_rom, BIOS_ROM_PATH_EDGE16, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
break;
|
||||
};
|
||||
|
||||
if (info->local == ATI18800_EDGE16) {
|
||||
svga_init(info, &ati18800->svga, ati18800, 1 << 18, /*256kb*/
|
||||
ati18800_recalctimings,
|
||||
ati18800_in, ati18800_out,
|
||||
NULL,
|
||||
NULL);
|
||||
} else {
|
||||
svga_init(info, &ati18800->svga, ati18800, 1 << 19, /*512kb*/
|
||||
ati18800_recalctimings,
|
||||
ati18800_in, ati18800_out,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
if (info->local == ATI18800_EDGE16) {
|
||||
svga_init(info, &ati18800->svga, ati18800, 1 << 18, /*256kb*/
|
||||
ati18800_recalctimings,
|
||||
ati18800_in, ati18800_out,
|
||||
NULL,
|
||||
NULL);
|
||||
} else {
|
||||
svga_init(info, &ati18800->svga, ati18800, 1 << 19, /*512kb*/
|
||||
ati18800_recalctimings,
|
||||
ati18800_in, ati18800_out,
|
||||
NULL,
|
||||
NULL);
|
||||
}
|
||||
|
||||
io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800);
|
||||
io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800);
|
||||
io_sethandler(0x01ce, 0x0002, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800);
|
||||
io_sethandler(0x03c0, 0x0020, ati18800_in, NULL, NULL, ati18800_out, NULL, NULL, ati18800);
|
||||
|
||||
ati18800->svga.miscout = 1;
|
||||
ati18800->svga.miscout = 1;
|
||||
|
||||
ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0);
|
||||
ati_eeprom_load(&ati18800->eeprom, "ati18800.nvr", 0);
|
||||
|
||||
return ati18800;
|
||||
return ati18800;
|
||||
}
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_VGAWONDER)
|
||||
static int ati18800_wonder_available(void)
|
||||
static int
|
||||
ati18800_wonder_available(void)
|
||||
{
|
||||
return rom_present(BIOS_ROM_PATH_WONDER);
|
||||
return rom_present(BIOS_ROM_PATH_WONDER);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ati18800_vga88_available(void)
|
||||
static int
|
||||
ati18800_vga88_available(void)
|
||||
{
|
||||
return rom_present(BIOS_ROM_PATH_VGA88);
|
||||
return rom_present(BIOS_ROM_PATH_VGA88);
|
||||
}
|
||||
|
||||
static int ati18800_available(void)
|
||||
static int
|
||||
ati18800_available(void)
|
||||
{
|
||||
return rom_present(BIOS_ROM_PATH_EDGE16);
|
||||
return rom_present(BIOS_ROM_PATH_EDGE16);
|
||||
}
|
||||
|
||||
static void ati18800_close(void *p)
|
||||
static void
|
||||
ati18800_close(void *p)
|
||||
{
|
||||
ati18800_t *ati18800 = (ati18800_t *)p;
|
||||
ati18800_t *ati18800 = (ati18800_t *) p;
|
||||
|
||||
svga_close(&ati18800->svga);
|
||||
svga_close(&ati18800->svga);
|
||||
|
||||
free(ati18800);
|
||||
free(ati18800);
|
||||
}
|
||||
|
||||
static void ati18800_speed_changed(void *p)
|
||||
static void
|
||||
ati18800_speed_changed(void *p)
|
||||
{
|
||||
ati18800_t *ati18800 = (ati18800_t *)p;
|
||||
ati18800_t *ati18800 = (ati18800_t *) p;
|
||||
|
||||
svga_recalctimings(&ati18800->svga);
|
||||
svga_recalctimings(&ati18800->svga);
|
||||
}
|
||||
|
||||
static void ati18800_force_redraw(void *p)
|
||||
static void
|
||||
ati18800_force_redraw(void *p)
|
||||
{
|
||||
ati18800_t *ati18800 = (ati18800_t *)p;
|
||||
ati18800_t *ati18800 = (ati18800_t *) p;
|
||||
|
||||
ati18800->svga.fullchange = changeframecount;
|
||||
ati18800->svga.fullchange = changeframecount;
|
||||
}
|
||||
|
||||
#if defined(DEV_BRANCH) && defined(USE_VGAWONDER)
|
||||
const device_t ati18800_wonder_device = {
|
||||
.name = "ATI-18800",
|
||||
.name = "ATI-18800",
|
||||
.internal_name = "ati18800w",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = ATI18800_WONDER,
|
||||
.init = ati18800_init,
|
||||
.close = ati18800_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = ATI18800_WONDER,
|
||||
.init = ati18800_init,
|
||||
.close = ati18800_close,
|
||||
.reset = NULL,
|
||||
{ .available = ati18800_wonder_available },
|
||||
.speed_changed = ati18800_speed_changed,
|
||||
.force_redraw = ati18800_force_redraw,
|
||||
.config = NULL
|
||||
.force_redraw = ati18800_force_redraw,
|
||||
.config = NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
const device_t ati18800_vga88_device =
|
||||
{
|
||||
.name = "ATI-18800-1",
|
||||
const device_t ati18800_vga88_device = {
|
||||
.name = "ATI-18800-1",
|
||||
.internal_name = "ati18800v",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = ATI18800_VGA88,
|
||||
.init = ati18800_init,
|
||||
.close = ati18800_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = ATI18800_VGA88,
|
||||
.init = ati18800_init,
|
||||
.close = ati18800_close,
|
||||
.reset = NULL,
|
||||
{ .available = ati18800_vga88_available },
|
||||
.speed_changed = ati18800_speed_changed,
|
||||
.force_redraw = ati18800_force_redraw,
|
||||
.config = NULL
|
||||
.force_redraw = ati18800_force_redraw,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t ati18800_device =
|
||||
{
|
||||
.name = "ATI-18800-5",
|
||||
const device_t ati18800_device = {
|
||||
.name = "ATI-18800-5",
|
||||
.internal_name = "ati18800",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = ATI18800_EDGE16,
|
||||
.init = ati18800_init,
|
||||
.close = ati18800_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = ATI18800_EDGE16,
|
||||
.init = ati18800_init,
|
||||
.close = ati18800_close,
|
||||
.reset = NULL,
|
||||
{ .available = ati18800_available },
|
||||
.speed_changed = ati18800_speed_changed,
|
||||
.force_redraw = ati18800_force_redraw,
|
||||
.config = NULL
|
||||
.force_redraw = ati18800_force_redraw,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -49,111 +49,112 @@
|
||||
#include <86box/vid_svga.h>
|
||||
#include <86box/vid_svga_render.h>
|
||||
|
||||
|
||||
typedef struct ati68860_ramdac_t
|
||||
{
|
||||
typedef struct ati68860_ramdac_t {
|
||||
uint8_t regs[16];
|
||||
void (*render)(struct svga_t *svga);
|
||||
|
||||
int dac_addr, dac_pos;
|
||||
int dac_r, dac_g;
|
||||
PALETTE pal;
|
||||
int dac_addr, dac_pos;
|
||||
int dac_r, dac_g;
|
||||
PALETTE pal;
|
||||
uint32_t pallook[2];
|
||||
|
||||
int ramdac_type;
|
||||
} ati68860_ramdac_t;
|
||||
|
||||
|
||||
void
|
||||
ati68860_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
|
||||
{
|
||||
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p;
|
||||
|
||||
switch (addr) {
|
||||
case 0:
|
||||
svga_out(0x3c8, val, svga);
|
||||
break;
|
||||
case 1:
|
||||
svga_out(0x3c9, val, svga);
|
||||
break;
|
||||
case 2:
|
||||
svga_out(0x3c6, val, svga);
|
||||
break;
|
||||
case 3:
|
||||
svga_out(0x3c7, val, svga);
|
||||
break;
|
||||
default:
|
||||
ramdac->regs[addr & 0xf] = val;
|
||||
switch (addr & 0xf) {
|
||||
case 0x4:
|
||||
ramdac->dac_addr = val;
|
||||
ramdac->dac_pos = 0;
|
||||
break;
|
||||
case 0x5:
|
||||
switch (ramdac->dac_pos) {
|
||||
case 0:
|
||||
ramdac->dac_r = val;
|
||||
ramdac->dac_pos++;
|
||||
break;
|
||||
case 1:
|
||||
ramdac->dac_g = val;
|
||||
ramdac->dac_pos++;
|
||||
break;
|
||||
case 2:
|
||||
if (ramdac->dac_addr > 1)
|
||||
break;
|
||||
ramdac->pal[ramdac->dac_addr].r = ramdac->dac_r;
|
||||
ramdac->pal[ramdac->dac_addr].g = ramdac->dac_g;
|
||||
ramdac->pal[ramdac->dac_addr].b = val;
|
||||
if (ramdac->ramdac_type == RAMDAC_8BIT)
|
||||
ramdac->pallook[ramdac->dac_addr] = makecol32(ramdac->pal[ramdac->dac_addr].r,
|
||||
ramdac->pal[ramdac->dac_addr].g,
|
||||
ramdac->pal[ramdac->dac_addr].b);
|
||||
else
|
||||
ramdac->pallook[ramdac->dac_addr] = makecol32(video_6to8[ramdac->pal[ramdac->dac_addr].r & 0x3f],
|
||||
video_6to8[ramdac->pal[ramdac->dac_addr].g & 0x3f],
|
||||
video_6to8[ramdac->pal[ramdac->dac_addr].b & 0x3f]);
|
||||
ramdac->dac_pos = 0;
|
||||
ramdac->dac_addr = (ramdac->dac_addr + 1) & 255;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0xb:
|
||||
switch (val) {
|
||||
case 0x82:
|
||||
ramdac->render = svga_render_4bpp_highres;
|
||||
break;
|
||||
case 0x83:
|
||||
ramdac->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
case 0xa0: case 0xb0:
|
||||
ramdac->render = svga_render_15bpp_highres;
|
||||
break;
|
||||
case 0xa1: case 0xb1:
|
||||
ramdac->render = svga_render_16bpp_highres;
|
||||
break;
|
||||
case 0xc0: case 0xd0:
|
||||
ramdac->render = svga_render_24bpp_highres;
|
||||
break;
|
||||
case 0xe2: case 0xf7:
|
||||
ramdac->render = svga_render_32bpp_highres;
|
||||
break;
|
||||
case 0xe3:
|
||||
ramdac->render = svga_render_ABGR8888_highres;
|
||||
break;
|
||||
case 0xf2:
|
||||
ramdac->render = svga_render_RGBA8888_highres;
|
||||
break;
|
||||
default:
|
||||
ramdac->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0xc:
|
||||
svga_set_ramdac_type(svga, (val & 1) ? RAMDAC_6BIT : RAMDAC_8BIT);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0:
|
||||
svga_out(0x3c8, val, svga);
|
||||
break;
|
||||
case 1:
|
||||
svga_out(0x3c9, val, svga);
|
||||
break;
|
||||
case 2:
|
||||
svga_out(0x3c6, val, svga);
|
||||
break;
|
||||
case 3:
|
||||
svga_out(0x3c7, val, svga);
|
||||
break;
|
||||
default:
|
||||
ramdac->regs[addr & 0xf] = val;
|
||||
switch (addr & 0xf) {
|
||||
case 0x4:
|
||||
ramdac->dac_addr = val;
|
||||
ramdac->dac_pos = 0;
|
||||
break;
|
||||
case 0x5:
|
||||
switch (ramdac->dac_pos) {
|
||||
case 0:
|
||||
ramdac->dac_r = val;
|
||||
ramdac->dac_pos++;
|
||||
break;
|
||||
case 1:
|
||||
ramdac->dac_g = val;
|
||||
ramdac->dac_pos++;
|
||||
break;
|
||||
case 2:
|
||||
if (ramdac->dac_addr > 1)
|
||||
break;
|
||||
ramdac->pal[ramdac->dac_addr].r = ramdac->dac_r;
|
||||
ramdac->pal[ramdac->dac_addr].g = ramdac->dac_g;
|
||||
ramdac->pal[ramdac->dac_addr].b = val;
|
||||
if (ramdac->ramdac_type == RAMDAC_8BIT)
|
||||
ramdac->pallook[ramdac->dac_addr] = makecol32(ramdac->pal[ramdac->dac_addr].r,
|
||||
ramdac->pal[ramdac->dac_addr].g,
|
||||
ramdac->pal[ramdac->dac_addr].b);
|
||||
else
|
||||
ramdac->pallook[ramdac->dac_addr] = makecol32(video_6to8[ramdac->pal[ramdac->dac_addr].r & 0x3f],
|
||||
video_6to8[ramdac->pal[ramdac->dac_addr].g & 0x3f],
|
||||
video_6to8[ramdac->pal[ramdac->dac_addr].b & 0x3f]);
|
||||
ramdac->dac_pos = 0;
|
||||
ramdac->dac_addr = (ramdac->dac_addr + 1) & 255;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0xb:
|
||||
switch (val) {
|
||||
case 0x82:
|
||||
ramdac->render = svga_render_4bpp_highres;
|
||||
break;
|
||||
case 0x83:
|
||||
ramdac->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
case 0xa0:
|
||||
case 0xb0:
|
||||
ramdac->render = svga_render_15bpp_highres;
|
||||
break;
|
||||
case 0xa1:
|
||||
case 0xb1:
|
||||
ramdac->render = svga_render_16bpp_highres;
|
||||
break;
|
||||
case 0xc0:
|
||||
case 0xd0:
|
||||
ramdac->render = svga_render_24bpp_highres;
|
||||
break;
|
||||
case 0xe2:
|
||||
case 0xf7:
|
||||
ramdac->render = svga_render_32bpp_highres;
|
||||
break;
|
||||
case 0xe3:
|
||||
ramdac->render = svga_render_ABGR8888_highres;
|
||||
break;
|
||||
case 0xf2:
|
||||
ramdac->render = svga_render_RGBA8888_highres;
|
||||
break;
|
||||
default:
|
||||
ramdac->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0xc:
|
||||
svga_set_ramdac_type(svga, (val & 1) ? RAMDAC_6BIT : RAMDAC_8BIT);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,61 +162,61 @@ uint8_t
|
||||
ati68860_ramdac_in(uint16_t addr, void *p, svga_t *svga)
|
||||
{
|
||||
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p;
|
||||
uint8_t temp = 0;
|
||||
uint8_t temp = 0;
|
||||
|
||||
switch (addr) {
|
||||
case 0:
|
||||
temp = svga_in(0x3c8, svga);
|
||||
break;
|
||||
case 1:
|
||||
temp = svga_in(0x3c9, svga);
|
||||
break;
|
||||
case 2:
|
||||
temp = svga_in(0x3c6, svga);
|
||||
break;
|
||||
case 3:
|
||||
temp = svga_in(0x3c7, svga);
|
||||
break;
|
||||
case 4: case 8:
|
||||
temp = 2;
|
||||
break;
|
||||
case 6: case 0xa:
|
||||
temp = 0x1d;
|
||||
break;
|
||||
case 0xf:
|
||||
temp = 0xd0;
|
||||
break;
|
||||
case 0:
|
||||
temp = svga_in(0x3c8, svga);
|
||||
break;
|
||||
case 1:
|
||||
temp = svga_in(0x3c9, svga);
|
||||
break;
|
||||
case 2:
|
||||
temp = svga_in(0x3c6, svga);
|
||||
break;
|
||||
case 3:
|
||||
temp = svga_in(0x3c7, svga);
|
||||
break;
|
||||
case 4:
|
||||
case 8:
|
||||
temp = 2;
|
||||
break;
|
||||
case 6:
|
||||
case 0xa:
|
||||
temp = 0x1d;
|
||||
break;
|
||||
case 0xf:
|
||||
temp = 0xd0;
|
||||
break;
|
||||
|
||||
default:
|
||||
temp = ramdac->regs[addr & 0xf];
|
||||
break;
|
||||
default:
|
||||
temp = ramdac->regs[addr & 0xf];
|
||||
break;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ati68860_set_ramdac_type(void *p, int type)
|
||||
{
|
||||
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) p;
|
||||
int c;
|
||||
int c;
|
||||
|
||||
if (ramdac->ramdac_type != type) {
|
||||
ramdac->ramdac_type = type;
|
||||
ramdac->ramdac_type = type;
|
||||
|
||||
for (c = 0; c < 2; c++) {
|
||||
if (ramdac->ramdac_type == RAMDAC_8BIT)
|
||||
ramdac->pallook[c] = makecol32(ramdac->pal[c].r, ramdac->pal[c].g,
|
||||
ramdac->pal[c].b);
|
||||
else
|
||||
ramdac->pallook[c] = makecol32(video_6to8[ramdac->pal[c].r & 0x3f], video_6to8[ramdac->pal[c].g & 0x3f],
|
||||
video_6to8[ramdac->pal[c].b & 0x3f]);
|
||||
}
|
||||
for (c = 0; c < 2; c++) {
|
||||
if (ramdac->ramdac_type == RAMDAC_8BIT)
|
||||
ramdac->pallook[c] = makecol32(ramdac->pal[c].r, ramdac->pal[c].g,
|
||||
ramdac->pal[c].b);
|
||||
else
|
||||
ramdac->pallook[c] = makecol32(video_6to8[ramdac->pal[c].r & 0x3f], video_6to8[ramdac->pal[c].g & 0x3f],
|
||||
video_6to8[ramdac->pal[c].b & 0x3f]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ati68860_ramdac_init(const device_t *info)
|
||||
{
|
||||
@@ -227,7 +228,6 @@ ati68860_ramdac_init(const device_t *info)
|
||||
return ramdac;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ati68860_ramdac_set_render(void *p, svga_t *svga)
|
||||
{
|
||||
@@ -236,7 +236,6 @@ ati68860_ramdac_set_render(void *p, svga_t *svga)
|
||||
svga->render = ramdac->render;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ati68860_ramdac_set_pallook(void *p, int i, uint32_t col)
|
||||
{
|
||||
@@ -245,57 +244,63 @@ ati68860_ramdac_set_pallook(void *p, int i, uint32_t col)
|
||||
ramdac->pallook[i] = col;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ati68860_hwcursor_draw(svga_t *svga, int displine)
|
||||
{
|
||||
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) svga->ramdac;
|
||||
int x, offset;
|
||||
uint8_t dat;
|
||||
uint32_t col0 = ramdac->pallook[0];
|
||||
uint32_t col1 = ramdac->pallook[1];
|
||||
int x, offset;
|
||||
uint8_t dat;
|
||||
uint32_t col0 = ramdac->pallook[0];
|
||||
uint32_t col1 = ramdac->pallook[1];
|
||||
|
||||
offset = svga->dac_hwcursor_latch.xoff;
|
||||
for (x = 0; x < 64 - svga->dac_hwcursor_latch.xoff; x += 4) {
|
||||
dat = svga->vram[svga->dac_hwcursor_latch.addr + (offset >> 2)];
|
||||
if (!(dat & 2)) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add] = (dat & 1) ? col1 : col0;
|
||||
else if ((dat & 3) == 3) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
if (!(dat & 2)) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 1] = (dat & 1) ? col1 : col0;
|
||||
else if ((dat & 3) == 3) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 1] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
if (!(dat & 2)) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 2] = (dat & 1) ? col1 : col0;
|
||||
else if ((dat & 3) == 3) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 2] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
if (!(dat & 2)) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 3] = (dat & 1) ? col1 : col0;
|
||||
else if ((dat & 3) == 3) buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 3] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
offset += 4;
|
||||
dat = svga->vram[svga->dac_hwcursor_latch.addr + (offset >> 2)];
|
||||
if (!(dat & 2))
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add] = (dat & 1) ? col1 : col0;
|
||||
else if ((dat & 3) == 3)
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
if (!(dat & 2))
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 1] = (dat & 1) ? col1 : col0;
|
||||
else if ((dat & 3) == 3)
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 1] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
if (!(dat & 2))
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 2] = (dat & 1) ? col1 : col0;
|
||||
else if ((dat & 3) == 3)
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 2] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
if (!(dat & 2))
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 3] = (dat & 1) ? col1 : col0;
|
||||
else if ((dat & 3) == 3)
|
||||
buffer32->line[displine][svga->dac_hwcursor_latch.x + x + svga->x_add + 3] ^= 0xFFFFFF;
|
||||
dat >>= 2;
|
||||
offset += 4;
|
||||
}
|
||||
|
||||
svga->dac_hwcursor_latch.addr += 16;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ati68860_ramdac_close(void *priv)
|
||||
{
|
||||
ati68860_ramdac_t *ramdac = (ati68860_ramdac_t *) priv;
|
||||
|
||||
if (ramdac)
|
||||
free(ramdac);
|
||||
free(ramdac);
|
||||
}
|
||||
|
||||
const device_t ati68860_ramdac_device = {
|
||||
.name = "ATI-68860 RAMDAC",
|
||||
.name = "ATI-68860 RAMDAC",
|
||||
.internal_name = "ati68860_ramdac",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = ati68860_ramdac_init,
|
||||
.close = ati68860_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = ati68860_ramdac_init,
|
||||
.close = ati68860_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -27,184 +27,168 @@
|
||||
#include <86box/nvr.h>
|
||||
#include <86box/vid_ati_eeprom.h>
|
||||
|
||||
|
||||
void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type)
|
||||
void
|
||||
ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type)
|
||||
{
|
||||
FILE *f;
|
||||
int size;
|
||||
eeprom->type = type;
|
||||
strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1);
|
||||
f = nvr_fopen(eeprom->fn, "rb");
|
||||
size = eeprom->type ? 512 : 128;
|
||||
if (!f) {
|
||||
memset(eeprom->data, 0xff, size);
|
||||
return;
|
||||
}
|
||||
if (fread(eeprom->data, 1, size, f) != size)
|
||||
memset(eeprom->data, 0, size);
|
||||
fclose(f);
|
||||
FILE *f;
|
||||
int size;
|
||||
eeprom->type = type;
|
||||
strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1);
|
||||
f = nvr_fopen(eeprom->fn, "rb");
|
||||
size = eeprom->type ? 512 : 128;
|
||||
if (!f) {
|
||||
memset(eeprom->data, 0xff, size);
|
||||
return;
|
||||
}
|
||||
if (fread(eeprom->data, 1, size, f) != size)
|
||||
memset(eeprom->data, 0, size);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void ati_eeprom_save(ati_eeprom_t *eeprom)
|
||||
void
|
||||
ati_eeprom_save(ati_eeprom_t *eeprom)
|
||||
{
|
||||
FILE *f = nvr_fopen(eeprom->fn, "wb");
|
||||
if (!f) return;
|
||||
fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f);
|
||||
fclose(f);
|
||||
FILE *f = nvr_fopen(eeprom->fn, "wb");
|
||||
if (!f)
|
||||
return;
|
||||
fwrite(eeprom->data, 1, eeprom->type ? 512 : 128, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat)
|
||||
void
|
||||
ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat)
|
||||
{
|
||||
int c;
|
||||
if (!ena)
|
||||
{
|
||||
eeprom->out = 1;
|
||||
}
|
||||
if (clk && !eeprom->oldclk)
|
||||
{
|
||||
if (ena && !eeprom->oldena)
|
||||
{
|
||||
eeprom->state = EEPROM_WAIT;
|
||||
eeprom->opcode = 0;
|
||||
eeprom->count = 3;
|
||||
eeprom->out = 1;
|
||||
}
|
||||
else if (ena)
|
||||
{
|
||||
switch (eeprom->state)
|
||||
{
|
||||
case EEPROM_WAIT:
|
||||
if (!dat)
|
||||
int c;
|
||||
if (!ena) {
|
||||
eeprom->out = 1;
|
||||
}
|
||||
if (clk && !eeprom->oldclk) {
|
||||
if (ena && !eeprom->oldena) {
|
||||
eeprom->state = EEPROM_WAIT;
|
||||
eeprom->opcode = 0;
|
||||
eeprom->count = 3;
|
||||
eeprom->out = 1;
|
||||
} else if (ena) {
|
||||
switch (eeprom->state) {
|
||||
case EEPROM_WAIT:
|
||||
if (!dat)
|
||||
break;
|
||||
eeprom->state = EEPROM_OPCODE;
|
||||
/* fall through */
|
||||
case EEPROM_OPCODE:
|
||||
eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0);
|
||||
eeprom->count--;
|
||||
if (!eeprom->count) {
|
||||
switch (eeprom->opcode) {
|
||||
case EEPROM_OP_WRITE:
|
||||
eeprom->count = eeprom->type ? 24 : 22;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
case EEPROM_OP_READ:
|
||||
eeprom->count = eeprom->type ? 8 : 6;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
case EEPROM_OP_EW:
|
||||
eeprom->count = 2;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
case EEPROM_OP_ERASE:
|
||||
eeprom->count = eeprom->type ? 8 : 6;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case EEPROM_INPUT:
|
||||
eeprom->dat = (eeprom->dat << 1) | (dat ? 1 : 0);
|
||||
eeprom->count--;
|
||||
if (!eeprom->count) {
|
||||
switch (eeprom->opcode) {
|
||||
case EEPROM_OP_WRITE:
|
||||
if (!eeprom->wp) {
|
||||
eeprom->data[(eeprom->dat >> 16) & (eeprom->type ? 255 : 63)] = eeprom->dat & 0xffff;
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_READ:
|
||||
eeprom->count = 17;
|
||||
eeprom->state = EEPROM_OUTPUT;
|
||||
eeprom->dat = eeprom->data[eeprom->dat];
|
||||
break;
|
||||
case EEPROM_OP_EW:
|
||||
switch (eeprom->dat) {
|
||||
case EEPROM_OP_EWDS:
|
||||
eeprom->wp = 1;
|
||||
break;
|
||||
eeprom->state = EEPROM_OPCODE;
|
||||
/* fall through */
|
||||
case EEPROM_OPCODE:
|
||||
eeprom->opcode = (eeprom->opcode << 1) | (dat ? 1 : 0);
|
||||
eeprom->count--;
|
||||
if (!eeprom->count)
|
||||
{
|
||||
switch (eeprom->opcode)
|
||||
{
|
||||
case EEPROM_OP_WRITE:
|
||||
eeprom->count = eeprom->type ? 24 : 22;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
case EEPROM_OP_READ:
|
||||
eeprom->count = eeprom->type ? 8 : 6;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
case EEPROM_OP_EW:
|
||||
eeprom->count = 2;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
case EEPROM_OP_ERASE:
|
||||
eeprom->count = eeprom->type ? 8 : 6;
|
||||
eeprom->state = EEPROM_INPUT;
|
||||
eeprom->dat = 0;
|
||||
break;
|
||||
case EEPROM_OP_WRAL:
|
||||
eeprom->opcode = EEPROM_OP_WRALMAIN;
|
||||
eeprom->count = 20;
|
||||
break;
|
||||
case EEPROM_OP_ERAL:
|
||||
if (!eeprom->wp) {
|
||||
memset(eeprom->data, 0xff, 128);
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
break;
|
||||
case EEPROM_OP_EWEN:
|
||||
eeprom->wp = 0;
|
||||
break;
|
||||
}
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_INPUT:
|
||||
eeprom->dat = (eeprom->dat << 1) | (dat ? 1 : 0);
|
||||
eeprom->count--;
|
||||
if (!eeprom->count)
|
||||
{
|
||||
switch (eeprom->opcode)
|
||||
{
|
||||
case EEPROM_OP_WRITE:
|
||||
if (!eeprom->wp)
|
||||
{
|
||||
eeprom->data[(eeprom->dat >> 16) & (eeprom->type ? 255 : 63)] = eeprom->dat & 0xffff;
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_READ:
|
||||
eeprom->count = 17;
|
||||
eeprom->state = EEPROM_OUTPUT;
|
||||
eeprom->dat = eeprom->data[eeprom->dat];
|
||||
break;
|
||||
case EEPROM_OP_EW:
|
||||
switch (eeprom->dat)
|
||||
{
|
||||
case EEPROM_OP_EWDS:
|
||||
eeprom->wp = 1;
|
||||
break;
|
||||
case EEPROM_OP_WRAL:
|
||||
eeprom->opcode = EEPROM_OP_WRALMAIN;
|
||||
eeprom->count = 20;
|
||||
break;
|
||||
case EEPROM_OP_ERAL:
|
||||
if (!eeprom->wp)
|
||||
{
|
||||
memset(eeprom->data, 0xff, 128);
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
break;
|
||||
case EEPROM_OP_EWEN:
|
||||
eeprom->wp = 0;
|
||||
break;
|
||||
}
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_ERASE:
|
||||
if (!eeprom->wp)
|
||||
{
|
||||
eeprom->data[eeprom->dat] = 0xffff;
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_WRALMAIN:
|
||||
if (!eeprom->wp)
|
||||
{
|
||||
for (c = 0; c < 256; c++)
|
||||
eeprom->data[c] = eeprom->dat;
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
}
|
||||
case EEPROM_OP_ERASE:
|
||||
if (!eeprom->wp) {
|
||||
eeprom->data[eeprom->dat] = 0xffff;
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
|
||||
case EEPROM_OP_WRALMAIN:
|
||||
if (!eeprom->wp) {
|
||||
for (c = 0; c < 256; c++)
|
||||
eeprom->data[c] = eeprom->dat;
|
||||
ati_eeprom_save(eeprom);
|
||||
}
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
eeprom->out = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
eeprom->oldena = ena;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (!clk && eeprom->oldclk)
|
||||
{
|
||||
if (ena)
|
||||
{
|
||||
switch (eeprom->state)
|
||||
{
|
||||
case EEPROM_OUTPUT:
|
||||
eeprom->out = (eeprom->dat & 0x10000) ? 1 : 0;
|
||||
eeprom->dat <<= 1;
|
||||
eeprom->count--;
|
||||
if (!eeprom->count)
|
||||
{
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
eeprom->oldena = ena;
|
||||
} else if (!clk && eeprom->oldclk) {
|
||||
if (ena) {
|
||||
switch (eeprom->state) {
|
||||
case EEPROM_OUTPUT:
|
||||
eeprom->out = (eeprom->dat & 0x10000) ? 1 : 0;
|
||||
eeprom->dat <<= 1;
|
||||
eeprom->count--;
|
||||
if (!eeprom->count) {
|
||||
eeprom->state = EEPROM_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
eeprom->oldclk = clk;
|
||||
}
|
||||
eeprom->oldclk = clk;
|
||||
}
|
||||
|
||||
int ati_eeprom_read(ati_eeprom_t *eeprom)
|
||||
int
|
||||
ati_eeprom_read(ati_eeprom_t *eeprom)
|
||||
{
|
||||
return eeprom->out;
|
||||
return eeprom->out;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,131 +28,126 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int type;
|
||||
int state;
|
||||
int type;
|
||||
int state;
|
||||
uint8_t ctrl;
|
||||
} att49x_ramdac_t;
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
ATT_490 = 0,
|
||||
ATT_491,
|
||||
ATT_492
|
||||
enum {
|
||||
ATT_490 = 0,
|
||||
ATT_491,
|
||||
ATT_492
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
att49x_ramdac_control(uint8_t val, void *p, svga_t *svga)
|
||||
{
|
||||
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p;
|
||||
ramdac->ctrl = val;
|
||||
switch ((ramdac->ctrl >> 5) & 7) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 6:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 7:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
if (ramdac->type == ATT_490 || ramdac->type == ATT_491)
|
||||
svga_set_ramdac_type(svga, (val & 2) ? RAMDAC_8BIT : RAMDAC_6BIT);
|
||||
svga_recalctimings(svga);
|
||||
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p;
|
||||
ramdac->ctrl = val;
|
||||
switch ((ramdac->ctrl >> 5) & 7) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 6:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 7:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
if (ramdac->type == ATT_490 || ramdac->type == ATT_491)
|
||||
svga_set_ramdac_type(svga, (val & 2) ? RAMDAC_8BIT : RAMDAC_6BIT);
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
|
||||
void
|
||||
att49x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
|
||||
{
|
||||
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
uint8_t rs = (addr & 0x03);
|
||||
rs |= ((!!rs2) << 2);
|
||||
|
||||
switch (rs) {
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x07:
|
||||
svga_out(addr, val, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
switch (ramdac->state) {
|
||||
case 4:
|
||||
att49x_ramdac_control(val, ramdac, svga);
|
||||
break;
|
||||
default:
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x06:
|
||||
att49x_ramdac_control(val, ramdac, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x07:
|
||||
svga_out(addr, val, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
switch (ramdac->state) {
|
||||
case 4:
|
||||
att49x_ramdac_control(val, ramdac, svga);
|
||||
break;
|
||||
default:
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x06:
|
||||
att49x_ramdac_control(val, ramdac, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
att49x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga)
|
||||
{
|
||||
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) p;
|
||||
uint8_t temp = 0xff;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
uint8_t temp = 0xff;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
rs |= ((!!rs2) << 2);
|
||||
|
||||
switch (rs) {
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x07:
|
||||
temp = svga_in(addr, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
switch (ramdac->state) {
|
||||
case 1:
|
||||
case 2: case 3:
|
||||
temp = 0x00;
|
||||
ramdac->state++;
|
||||
break;
|
||||
case 4:
|
||||
temp = ramdac->ctrl;
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
ramdac->state++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x06:
|
||||
temp = ramdac->ctrl;
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x07:
|
||||
temp = svga_in(addr, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
switch (ramdac->state) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
temp = 0x00;
|
||||
ramdac->state++;
|
||||
break;
|
||||
case 4:
|
||||
temp = ramdac->ctrl;
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
ramdac->state++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x06:
|
||||
temp = ramdac->ctrl;
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
att49x_ramdac_init(const device_t *info)
|
||||
{
|
||||
@@ -164,54 +159,53 @@ att49x_ramdac_init(const device_t *info)
|
||||
return ramdac;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
att49x_ramdac_close(void *priv)
|
||||
{
|
||||
att49x_ramdac_t *ramdac = (att49x_ramdac_t *) priv;
|
||||
|
||||
if (ramdac)
|
||||
free(ramdac);
|
||||
free(ramdac);
|
||||
}
|
||||
|
||||
const device_t att490_ramdac_device = {
|
||||
.name = "AT&T 20c490 RAMDAC",
|
||||
.name = "AT&T 20c490 RAMDAC",
|
||||
.internal_name = "att490_ramdac",
|
||||
.flags = 0,
|
||||
.local = ATT_490,
|
||||
.init = att49x_ramdac_init,
|
||||
.close = att49x_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = ATT_490,
|
||||
.init = att49x_ramdac_init,
|
||||
.close = att49x_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t att491_ramdac_device = {
|
||||
.name = "AT&T 20c491 RAMDAC",
|
||||
.name = "AT&T 20c491 RAMDAC",
|
||||
.internal_name = "att491_ramdac",
|
||||
.flags = 0,
|
||||
.local = ATT_491,
|
||||
.init = att49x_ramdac_init,
|
||||
.close = att49x_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = ATT_491,
|
||||
.init = att49x_ramdac_init,
|
||||
.close = att49x_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t att492_ramdac_device = {
|
||||
.name = "AT&T 20c492 RAMDAC",
|
||||
.name = "AT&T 20c492 RAMDAC",
|
||||
.internal_name = "att492_ramdac",
|
||||
.flags = 0,
|
||||
.local = ATT_492,
|
||||
.init = att49x_ramdac_init,
|
||||
.close = att49x_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = ATT_492,
|
||||
.init = att49x_ramdac_init,
|
||||
.close = att49x_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -28,133 +28,130 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int type;
|
||||
int state;
|
||||
int loop;
|
||||
int type;
|
||||
int state;
|
||||
int loop;
|
||||
uint8_t ctrl;
|
||||
} att498_ramdac_t;
|
||||
|
||||
static void
|
||||
att498_ramdac_control(uint8_t val, void *p, svga_t *svga)
|
||||
{
|
||||
att498_ramdac_t *ramdac = (att498_ramdac_t *) p;
|
||||
ramdac->ctrl = val;
|
||||
att498_ramdac_t *ramdac = (att498_ramdac_t *) p;
|
||||
ramdac->ctrl = val;
|
||||
|
||||
if (val == 0xff)
|
||||
return;
|
||||
if (val == 0xff)
|
||||
return;
|
||||
|
||||
switch ((ramdac->ctrl >> 4) & 0x0f) {
|
||||
default:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 1:
|
||||
if (ramdac->ctrl & 4)
|
||||
svga->bpp = 15;
|
||||
else
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 3:
|
||||
case 6:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 5:
|
||||
case 7:
|
||||
svga->bpp = 32;
|
||||
break;
|
||||
case 0x0e:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
switch ((ramdac->ctrl >> 4) & 0x0f) {
|
||||
default:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 1:
|
||||
if (ramdac->ctrl & 4)
|
||||
svga->bpp = 15;
|
||||
else
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 3:
|
||||
case 6:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 5:
|
||||
case 7:
|
||||
svga->bpp = 32;
|
||||
break;
|
||||
case 0x0e:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
|
||||
svga_set_ramdac_type(svga, (ramdac->ctrl & 2) ? RAMDAC_8BIT : RAMDAC_6BIT);
|
||||
svga_recalctimings(svga);
|
||||
svga_set_ramdac_type(svga, (ramdac->ctrl & 2) ? RAMDAC_8BIT : RAMDAC_6BIT);
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
|
||||
void
|
||||
att498_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
|
||||
{
|
||||
att498_ramdac_t *ramdac = (att498_ramdac_t *) p;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
uint8_t rs = (addr & 0x03);
|
||||
rs |= ((!!rs2) << 2);
|
||||
|
||||
switch (rs) {
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x07:
|
||||
svga_out(addr, val, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
switch (ramdac->state) {
|
||||
case 4:
|
||||
att498_ramdac_control(val, ramdac, svga);
|
||||
break;
|
||||
default:
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x06:
|
||||
att498_ramdac_control(val, ramdac, svga);
|
||||
break;
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x07:
|
||||
svga_out(addr, val, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
switch (ramdac->state) {
|
||||
case 4:
|
||||
att498_ramdac_control(val, ramdac, svga);
|
||||
break;
|
||||
default:
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x06:
|
||||
att498_ramdac_control(val, ramdac, svga);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
att498_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga)
|
||||
{
|
||||
att498_ramdac_t *ramdac = (att498_ramdac_t *) p;
|
||||
uint8_t temp = 0xff;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
uint8_t temp = 0xff;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
rs |= ((!!rs2) << 2);
|
||||
|
||||
switch (rs) {
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x07:
|
||||
temp = svga_in(addr, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
switch (ramdac->state) {
|
||||
case 4:
|
||||
temp = ramdac->ctrl;
|
||||
ramdac->state++;
|
||||
break;
|
||||
case 5:
|
||||
temp = 0x84;
|
||||
ramdac->state++;
|
||||
break;
|
||||
case 6:
|
||||
temp = ramdac->ctrl;
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
ramdac->state++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x06:
|
||||
temp = ramdac->ctrl;
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x07:
|
||||
temp = svga_in(addr, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
switch (ramdac->state) {
|
||||
case 4:
|
||||
temp = ramdac->ctrl;
|
||||
ramdac->state++;
|
||||
break;
|
||||
case 5:
|
||||
temp = 0x84;
|
||||
ramdac->state++;
|
||||
break;
|
||||
case 6:
|
||||
temp = ramdac->ctrl;
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
ramdac->state++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x06:
|
||||
temp = ramdac->ctrl;
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
att498_ramdac_init(const device_t *info)
|
||||
{
|
||||
@@ -166,26 +163,25 @@ att498_ramdac_init(const device_t *info)
|
||||
return ramdac;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
att498_ramdac_close(void *priv)
|
||||
{
|
||||
att498_ramdac_t *ramdac = (att498_ramdac_t *) priv;
|
||||
|
||||
if (ramdac)
|
||||
free(ramdac);
|
||||
free(ramdac);
|
||||
}
|
||||
|
||||
const device_t att498_ramdac_device = {
|
||||
.name = "AT&T 22c498 RAMDAC",
|
||||
.name = "AT&T 22c498 RAMDAC",
|
||||
.internal_name = "att498_ramdac",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = att498_ramdac_init,
|
||||
.close = att498_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = att498_ramdac_init,
|
||||
.close = att498_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -28,65 +28,62 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
|
||||
|
||||
float
|
||||
av9194_getclock(int clock, void *p)
|
||||
{
|
||||
float ret = 0.0;
|
||||
|
||||
switch (clock & 0x0f)
|
||||
{
|
||||
case 0:
|
||||
ret = 25175000.0;
|
||||
break;
|
||||
case 1:
|
||||
ret = 28322000.0;
|
||||
break;
|
||||
case 2:
|
||||
ret = 40000000.0;
|
||||
break;
|
||||
case 4:
|
||||
ret = 50000000.0;
|
||||
break;
|
||||
case 5:
|
||||
ret = 77000000.0;
|
||||
break;
|
||||
case 6:
|
||||
ret = 36000000.0;
|
||||
break;
|
||||
case 7:
|
||||
ret = 44900000.0;
|
||||
break;
|
||||
case 8:
|
||||
ret = 130000000.0;
|
||||
break;
|
||||
case 9:
|
||||
ret = 120000000.0;
|
||||
break;
|
||||
case 0xa:
|
||||
ret = 80000000.0;
|
||||
break;
|
||||
case 0xb:
|
||||
ret = 31500000.0;
|
||||
break;
|
||||
case 0xc:
|
||||
ret = 110000000.0;
|
||||
break;
|
||||
case 0xd:
|
||||
ret = 65000000.0;
|
||||
break;
|
||||
case 0xe:
|
||||
ret = 75000000.0;
|
||||
break;
|
||||
case 0xf:
|
||||
ret = 94500000.0;
|
||||
break;
|
||||
switch (clock & 0x0f) {
|
||||
case 0:
|
||||
ret = 25175000.0;
|
||||
break;
|
||||
case 1:
|
||||
ret = 28322000.0;
|
||||
break;
|
||||
case 2:
|
||||
ret = 40000000.0;
|
||||
break;
|
||||
case 4:
|
||||
ret = 50000000.0;
|
||||
break;
|
||||
case 5:
|
||||
ret = 77000000.0;
|
||||
break;
|
||||
case 6:
|
||||
ret = 36000000.0;
|
||||
break;
|
||||
case 7:
|
||||
ret = 44900000.0;
|
||||
break;
|
||||
case 8:
|
||||
ret = 130000000.0;
|
||||
break;
|
||||
case 9:
|
||||
ret = 120000000.0;
|
||||
break;
|
||||
case 0xa:
|
||||
ret = 80000000.0;
|
||||
break;
|
||||
case 0xb:
|
||||
ret = 31500000.0;
|
||||
break;
|
||||
case 0xc:
|
||||
ret = 110000000.0;
|
||||
break;
|
||||
case 0xd:
|
||||
ret = 65000000.0;
|
||||
break;
|
||||
case 0xe:
|
||||
ret = 75000000.0;
|
||||
break;
|
||||
case 0xf:
|
||||
ret = 94500000.0;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
av9194_init(const device_t *info)
|
||||
{
|
||||
@@ -94,17 +91,16 @@ av9194_init(const device_t *info)
|
||||
return (void *) &av9194_device;
|
||||
}
|
||||
|
||||
|
||||
const device_t av9194_device = {
|
||||
.name = "AV9194 Clock Generator",
|
||||
.name = "AV9194 Clock Generator",
|
||||
.internal_name = "av9194",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = av9194_init,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = av9194_init,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -29,324 +29,319 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PALETTE extpal;
|
||||
uint32_t extpallook[256];
|
||||
uint8_t cursor32_data[256];
|
||||
uint8_t cursor64_data[1024];
|
||||
int hwc_y, hwc_x;
|
||||
uint8_t cmd_r0;
|
||||
uint8_t cmd_r1;
|
||||
uint8_t cmd_r2;
|
||||
uint8_t cmd_r3;
|
||||
uint8_t cmd_r4;
|
||||
uint8_t status;
|
||||
uint8_t type;
|
||||
PALETTE extpal;
|
||||
uint32_t extpallook[256];
|
||||
uint8_t cursor32_data[256];
|
||||
uint8_t cursor64_data[1024];
|
||||
int hwc_y, hwc_x;
|
||||
uint8_t cmd_r0;
|
||||
uint8_t cmd_r1;
|
||||
uint8_t cmd_r2;
|
||||
uint8_t cmd_r3;
|
||||
uint8_t cmd_r4;
|
||||
uint8_t status;
|
||||
uint8_t type;
|
||||
} bt48x_ramdac_t;
|
||||
|
||||
|
||||
enum {
|
||||
BT484 = 0,
|
||||
ATT20C504,
|
||||
BT485,
|
||||
ATT20C505,
|
||||
BT485A
|
||||
BT484 = 0,
|
||||
ATT20C504,
|
||||
BT485,
|
||||
ATT20C505,
|
||||
BT485A
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
bt48x_set_bpp(bt48x_ramdac_t *ramdac, svga_t *svga)
|
||||
{
|
||||
if ((!(ramdac->cmd_r2 & 0x20)) || ((ramdac->type >= BT485A) && ((ramdac->cmd_r3 & 0x60) == 0x60)))
|
||||
svga->bpp = 8;
|
||||
svga->bpp = 8;
|
||||
else if ((ramdac->type >= BT485A) && ((ramdac->cmd_r3 & 0x60) == 0x40))
|
||||
svga->bpp = 24;
|
||||
else switch (ramdac->cmd_r1 & 0x60) {
|
||||
case 0x00:
|
||||
svga->bpp = 32;
|
||||
break;
|
||||
case 0x20:
|
||||
if (ramdac->cmd_r1 & 0x08)
|
||||
svga->bpp = 16;
|
||||
else
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 0x40:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 0x60:
|
||||
svga->bpp = 4;
|
||||
break;
|
||||
}
|
||||
svga->bpp = 24;
|
||||
else
|
||||
switch (ramdac->cmd_r1 & 0x60) {
|
||||
case 0x00:
|
||||
svga->bpp = 32;
|
||||
break;
|
||||
case 0x20:
|
||||
if (ramdac->cmd_r1 & 0x08)
|
||||
svga->bpp = 16;
|
||||
else
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 0x40:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 0x60:
|
||||
svga->bpp = 4;
|
||||
break;
|
||||
}
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bt48x_ramdac_out(uint16_t addr, int rs2, int rs3, uint8_t val, void *p, svga_t *svga)
|
||||
{
|
||||
bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p;
|
||||
uint32_t o32;
|
||||
uint8_t *cd;
|
||||
uint16_t index;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
uint16_t da_mask = 0x03ff;
|
||||
uint32_t o32;
|
||||
uint8_t *cd;
|
||||
uint16_t index;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
uint16_t da_mask = 0x03ff;
|
||||
rs |= (!!rs2 << 2);
|
||||
rs |= (!!rs3 << 3);
|
||||
if (ramdac->type < BT485)
|
||||
da_mask = 0x00ff;
|
||||
da_mask = 0x00ff;
|
||||
|
||||
switch (rs) {
|
||||
case 0x00: /* Palette Write Index Register (RS value = 0000) */
|
||||
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
|
||||
case 0x03:
|
||||
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
|
||||
svga->dac_pos = 0;
|
||||
svga->dac_status = addr & 0x03;
|
||||
svga->dac_addr = val;
|
||||
if (ramdac->type >= BT485)
|
||||
svga->dac_addr |= ((int) (ramdac->cmd_r3 & 0x03) << 8);
|
||||
if (svga->dac_status)
|
||||
svga->dac_addr = (svga->dac_addr + 1) & da_mask;
|
||||
break;
|
||||
case 0x01: /* Palette Data Register (RS value = 0001) */
|
||||
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
case 0x05: /* Ext Palette Data Register (RS value = 0101) */
|
||||
svga->dac_status = 0;
|
||||
svga->fullchange = changeframecount;
|
||||
switch (svga->dac_pos) {
|
||||
case 0:
|
||||
svga->dac_r = val;
|
||||
svga->dac_pos++;
|
||||
break;
|
||||
case 1:
|
||||
svga->dac_g = val;
|
||||
svga->dac_pos++;
|
||||
break;
|
||||
case 2:
|
||||
index = svga->dac_addr & 3;
|
||||
ramdac->extpal[index].r = svga->dac_r;
|
||||
ramdac->extpal[index].g = svga->dac_g;
|
||||
ramdac->extpal[index].b = val;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
ramdac->extpallook[index] = makecol32(ramdac->extpal[index].r, ramdac->extpal[index].g, ramdac->extpal[index].b);
|
||||
else
|
||||
ramdac->extpallook[index] = makecol32(video_6to8[ramdac->extpal[index].r & 0x3f], video_6to8[ramdac->extpal[index].g & 0x3f], video_6to8[ramdac->extpal[index].b & 0x3f]);
|
||||
case 0x00: /* Palette Write Index Register (RS value = 0000) */
|
||||
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
|
||||
case 0x03:
|
||||
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
|
||||
svga->dac_pos = 0;
|
||||
svga->dac_status = addr & 0x03;
|
||||
svga->dac_addr = val;
|
||||
if (ramdac->type >= BT485)
|
||||
svga->dac_addr |= ((int) (ramdac->cmd_r3 & 0x03) << 8);
|
||||
if (svga->dac_status)
|
||||
svga->dac_addr = (svga->dac_addr + 1) & da_mask;
|
||||
break;
|
||||
case 0x01: /* Palette Data Register (RS value = 0001) */
|
||||
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
case 0x05: /* Ext Palette Data Register (RS value = 0101) */
|
||||
svga->dac_status = 0;
|
||||
svga->fullchange = changeframecount;
|
||||
switch (svga->dac_pos) {
|
||||
case 0:
|
||||
svga->dac_r = val;
|
||||
svga->dac_pos++;
|
||||
break;
|
||||
case 1:
|
||||
svga->dac_g = val;
|
||||
svga->dac_pos++;
|
||||
break;
|
||||
case 2:
|
||||
index = svga->dac_addr & 3;
|
||||
ramdac->extpal[index].r = svga->dac_r;
|
||||
ramdac->extpal[index].g = svga->dac_g;
|
||||
ramdac->extpal[index].b = val;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
ramdac->extpallook[index] = makecol32(ramdac->extpal[index].r, ramdac->extpal[index].g, ramdac->extpal[index].b);
|
||||
else
|
||||
ramdac->extpallook[index] = makecol32(video_6to8[ramdac->extpal[index].r & 0x3f], video_6to8[ramdac->extpal[index].g & 0x3f], video_6to8[ramdac->extpal[index].b & 0x3f]);
|
||||
|
||||
if (svga->ext_overscan && !index) {
|
||||
o32 = svga->overscan_color;
|
||||
svga->overscan_color = ramdac->extpallook[0];
|
||||
if (o32 != svga->overscan_color)
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
svga->dac_addr = (svga->dac_addr + 1) & 0xff;
|
||||
svga->dac_pos = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x06: /* Command Register 0 (RS value = 0110) */
|
||||
ramdac->cmd_r0 = val;
|
||||
svga->ramdac_type = (val & 0x02) ? RAMDAC_8BIT : RAMDAC_6BIT;
|
||||
break;
|
||||
case 0x08: /* Command Register 1 (RS value = 1000) */
|
||||
ramdac->cmd_r1 = val;
|
||||
bt48x_set_bpp(ramdac, svga);
|
||||
break;
|
||||
case 0x09: /* Command Register 2 (RS value = 1001) */
|
||||
ramdac->cmd_r2 = val;
|
||||
svga->dac_hwcursor.ena = !!(val & 0x03);
|
||||
bt48x_set_bpp(ramdac, svga);
|
||||
break;
|
||||
case 0x0a:
|
||||
if ((ramdac->type >= BT485) && (ramdac->cmd_r0 & 0x80)) {
|
||||
switch ((svga->dac_addr & ((ramdac->type >= BT485A) ? 0xff : 0x3f))) {
|
||||
case 0x01:
|
||||
/* Command Register 3 (RS value = 1010) */
|
||||
ramdac->cmd_r3 = val;
|
||||
if (ramdac->type >= BT485A)
|
||||
bt48x_set_bpp(ramdac, svga);
|
||||
svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = (val & 4) ? 64 : 32;
|
||||
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
|
||||
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
|
||||
svga->dac_addr = (svga->dac_addr & 0x00ff) | ((val & 0x03) << 8);
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
if (ramdac->type != BT485A)
|
||||
break;
|
||||
else if (svga->dac_addr == 2) {
|
||||
ramdac->cmd_r4 = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
|
||||
index = svga->dac_addr & da_mask;
|
||||
if ((ramdac->type >= BT485) && (svga->dac_hwcursor.cur_xsize == 64))
|
||||
cd = (uint8_t *) ramdac->cursor64_data;
|
||||
else {
|
||||
index &= 0xff;
|
||||
cd = (uint8_t *) ramdac->cursor32_data;
|
||||
}
|
||||
if (svga->ext_overscan && !index) {
|
||||
o32 = svga->overscan_color;
|
||||
svga->overscan_color = ramdac->extpallook[0];
|
||||
if (o32 != svga->overscan_color)
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
svga->dac_addr = (svga->dac_addr + 1) & 0xff;
|
||||
svga->dac_pos = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x06: /* Command Register 0 (RS value = 0110) */
|
||||
ramdac->cmd_r0 = val;
|
||||
svga->ramdac_type = (val & 0x02) ? RAMDAC_8BIT : RAMDAC_6BIT;
|
||||
break;
|
||||
case 0x08: /* Command Register 1 (RS value = 1000) */
|
||||
ramdac->cmd_r1 = val;
|
||||
bt48x_set_bpp(ramdac, svga);
|
||||
break;
|
||||
case 0x09: /* Command Register 2 (RS value = 1001) */
|
||||
ramdac->cmd_r2 = val;
|
||||
svga->dac_hwcursor.ena = !!(val & 0x03);
|
||||
bt48x_set_bpp(ramdac, svga);
|
||||
break;
|
||||
case 0x0a:
|
||||
if ((ramdac->type >= BT485) && (ramdac->cmd_r0 & 0x80)) {
|
||||
switch ((svga->dac_addr & ((ramdac->type >= BT485A) ? 0xff : 0x3f))) {
|
||||
case 0x01:
|
||||
/* Command Register 3 (RS value = 1010) */
|
||||
ramdac->cmd_r3 = val;
|
||||
if (ramdac->type >= BT485A)
|
||||
bt48x_set_bpp(ramdac, svga);
|
||||
svga->dac_hwcursor.cur_xsize = svga->dac_hwcursor.cur_ysize = (val & 4) ? 64 : 32;
|
||||
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
|
||||
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
|
||||
svga->dac_addr = (svga->dac_addr & 0x00ff) | ((val & 0x03) << 8);
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
if (ramdac->type != BT485A)
|
||||
break;
|
||||
else if (svga->dac_addr == 2) {
|
||||
ramdac->cmd_r4 = val;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
|
||||
index = svga->dac_addr & da_mask;
|
||||
if ((ramdac->type >= BT485) && (svga->dac_hwcursor.cur_xsize == 64))
|
||||
cd = (uint8_t *) ramdac->cursor64_data;
|
||||
else {
|
||||
index &= 0xff;
|
||||
cd = (uint8_t *) ramdac->cursor32_data;
|
||||
}
|
||||
|
||||
cd[index] = val;
|
||||
cd[index] = val;
|
||||
|
||||
svga->dac_addr = (svga->dac_addr + 1) & da_mask;
|
||||
break;
|
||||
case 0x0c: /* Cursor X Low Register (RS value = 1100) */
|
||||
ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val;
|
||||
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
|
||||
break;
|
||||
case 0x0d: /* Cursor X High Register (RS value = 1101) */
|
||||
ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | ((val & 0x0f) << 8);
|
||||
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
|
||||
break;
|
||||
case 0x0e: /* Cursor Y Low Register (RS value = 1110) */
|
||||
ramdac->hwc_y = (ramdac->hwc_y & 0x0f00) | val;
|
||||
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
|
||||
break;
|
||||
case 0x0f: /* Cursor Y High Register (RS value = 1111) */
|
||||
ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8);
|
||||
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
|
||||
break;
|
||||
svga->dac_addr = (svga->dac_addr + 1) & da_mask;
|
||||
break;
|
||||
case 0x0c: /* Cursor X Low Register (RS value = 1100) */
|
||||
ramdac->hwc_x = (ramdac->hwc_x & 0x0f00) | val;
|
||||
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
|
||||
break;
|
||||
case 0x0d: /* Cursor X High Register (RS value = 1101) */
|
||||
ramdac->hwc_x = (ramdac->hwc_x & 0x00ff) | ((val & 0x0f) << 8);
|
||||
svga->dac_hwcursor.x = ramdac->hwc_x - svga->dac_hwcursor.cur_xsize;
|
||||
break;
|
||||
case 0x0e: /* Cursor Y Low Register (RS value = 1110) */
|
||||
ramdac->hwc_y = (ramdac->hwc_y & 0x0f00) | val;
|
||||
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
|
||||
break;
|
||||
case 0x0f: /* Cursor Y High Register (RS value = 1111) */
|
||||
ramdac->hwc_y = (ramdac->hwc_y & 0x00ff) | ((val & 0x0f) << 8);
|
||||
svga->dac_hwcursor.y = ramdac->hwc_y - svga->dac_hwcursor.cur_ysize;
|
||||
break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
bt48x_ramdac_in(uint16_t addr, int rs2, int rs3, void *p, svga_t *svga)
|
||||
{
|
||||
bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) p;
|
||||
uint8_t temp = 0xff;
|
||||
uint8_t *cd;
|
||||
uint16_t index;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
uint16_t da_mask = 0x03ff;
|
||||
uint8_t temp = 0xff;
|
||||
uint8_t *cd;
|
||||
uint16_t index;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
uint16_t da_mask = 0x03ff;
|
||||
rs |= (!!rs2 << 2);
|
||||
rs |= (!!rs3 << 3);
|
||||
if (ramdac->type < BT485)
|
||||
da_mask = 0x00ff;
|
||||
da_mask = 0x00ff;
|
||||
|
||||
switch (rs) {
|
||||
case 0x00: /* Palette Write Index Register (RS value = 0000) */
|
||||
case 0x01: /* Palette Data Register (RS value = 0001) */
|
||||
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
|
||||
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
case 0x03: /* Palette Read Index Register (RS value = 0011) */
|
||||
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
|
||||
temp = svga->dac_addr & 0xff;
|
||||
break;
|
||||
case 0x05: /* Ext Palette Data Register (RS value = 0101) */
|
||||
index = (svga->dac_addr - 1) & 3;
|
||||
svga->dac_status = 3;
|
||||
switch (svga->dac_pos) {
|
||||
case 0:
|
||||
svga->dac_pos++;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
temp = ramdac->extpal[index].r;
|
||||
else
|
||||
temp = ramdac->extpal[index].r & 0x3f;
|
||||
break;
|
||||
case 1:
|
||||
svga->dac_pos++;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
temp = ramdac->extpal[index].g;
|
||||
else
|
||||
temp = ramdac->extpal[index].g & 0x3f;
|
||||
break;
|
||||
case 2:
|
||||
svga->dac_pos=0;
|
||||
svga->dac_addr = svga->dac_addr + 1;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
temp = ramdac->extpal[index].b;
|
||||
else
|
||||
temp = ramdac->extpal[index].b & 0x3f;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x06: /* Command Register 0 (RS value = 0110) */
|
||||
temp = ramdac->cmd_r0;
|
||||
break;
|
||||
case 0x08: /* Command Register 1 (RS value = 1000) */
|
||||
temp = ramdac->cmd_r1;
|
||||
break;
|
||||
case 0x09: /* Command Register 2 (RS value = 1001) */
|
||||
temp = ramdac->cmd_r2;
|
||||
break;
|
||||
case 0x0a:
|
||||
if ((ramdac->type >= BT485) && (ramdac->cmd_r0 & 0x80)) {
|
||||
switch ((svga->dac_addr & ((ramdac->type >= BT485A) ? 0xff : 0x3f))) {
|
||||
case 0x00:
|
||||
default:
|
||||
temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00);
|
||||
break;
|
||||
case 0x01:
|
||||
temp = ramdac->cmd_r3 & 0xfc;
|
||||
temp |= (svga->dac_addr & 0x300) >> 8;
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
if (ramdac->type != BT485A)
|
||||
break;
|
||||
else if (svga->dac_addr == 2) {
|
||||
temp = ramdac->cmd_r4;
|
||||
break;
|
||||
} else {
|
||||
/* TODO: Red, Green, and Blue Signature Analysis Registers */
|
||||
temp = 0xff;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else
|
||||
temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00);
|
||||
break;
|
||||
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
|
||||
index = (svga->dac_addr - 1) & da_mask;
|
||||
if ((ramdac->type >= BT485) && (svga->dac_hwcursor.cur_xsize == 64))
|
||||
cd = (uint8_t *) ramdac->cursor64_data;
|
||||
else {
|
||||
index &= 0xff;
|
||||
cd = (uint8_t *) ramdac->cursor32_data;
|
||||
}
|
||||
case 0x00: /* Palette Write Index Register (RS value = 0000) */
|
||||
case 0x01: /* Palette Data Register (RS value = 0001) */
|
||||
case 0x02: /* Pixel Read Mask Register (RS value = 0010) */
|
||||
case 0x04: /* Ext Palette Write Index Register (RS value = 0100) */
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
case 0x03: /* Palette Read Index Register (RS value = 0011) */
|
||||
case 0x07: /* Ext Palette Read Index Register (RS value = 0111) */
|
||||
temp = svga->dac_addr & 0xff;
|
||||
break;
|
||||
case 0x05: /* Ext Palette Data Register (RS value = 0101) */
|
||||
index = (svga->dac_addr - 1) & 3;
|
||||
svga->dac_status = 3;
|
||||
switch (svga->dac_pos) {
|
||||
case 0:
|
||||
svga->dac_pos++;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
temp = ramdac->extpal[index].r;
|
||||
else
|
||||
temp = ramdac->extpal[index].r & 0x3f;
|
||||
break;
|
||||
case 1:
|
||||
svga->dac_pos++;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
temp = ramdac->extpal[index].g;
|
||||
else
|
||||
temp = ramdac->extpal[index].g & 0x3f;
|
||||
break;
|
||||
case 2:
|
||||
svga->dac_pos = 0;
|
||||
svga->dac_addr = svga->dac_addr + 1;
|
||||
if (svga->ramdac_type == RAMDAC_8BIT)
|
||||
temp = ramdac->extpal[index].b;
|
||||
else
|
||||
temp = ramdac->extpal[index].b & 0x3f;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x06: /* Command Register 0 (RS value = 0110) */
|
||||
temp = ramdac->cmd_r0;
|
||||
break;
|
||||
case 0x08: /* Command Register 1 (RS value = 1000) */
|
||||
temp = ramdac->cmd_r1;
|
||||
break;
|
||||
case 0x09: /* Command Register 2 (RS value = 1001) */
|
||||
temp = ramdac->cmd_r2;
|
||||
break;
|
||||
case 0x0a:
|
||||
if ((ramdac->type >= BT485) && (ramdac->cmd_r0 & 0x80)) {
|
||||
switch ((svga->dac_addr & ((ramdac->type >= BT485A) ? 0xff : 0x3f))) {
|
||||
case 0x00:
|
||||
default:
|
||||
temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00);
|
||||
break;
|
||||
case 0x01:
|
||||
temp = ramdac->cmd_r3 & 0xfc;
|
||||
temp |= (svga->dac_addr & 0x300) >> 8;
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x20:
|
||||
case 0x21:
|
||||
case 0x22:
|
||||
if (ramdac->type != BT485A)
|
||||
break;
|
||||
else if (svga->dac_addr == 2) {
|
||||
temp = ramdac->cmd_r4;
|
||||
break;
|
||||
} else {
|
||||
/* TODO: Red, Green, and Blue Signature Analysis Registers */
|
||||
temp = 0xff;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else
|
||||
temp = ramdac->status | (svga->dac_status ? 0x04 : 0x00);
|
||||
break;
|
||||
case 0x0b: /* Cursor RAM Data Register (RS value = 1011) */
|
||||
index = (svga->dac_addr - 1) & da_mask;
|
||||
if ((ramdac->type >= BT485) && (svga->dac_hwcursor.cur_xsize == 64))
|
||||
cd = (uint8_t *) ramdac->cursor64_data;
|
||||
else {
|
||||
index &= 0xff;
|
||||
cd = (uint8_t *) ramdac->cursor32_data;
|
||||
}
|
||||
|
||||
temp = cd[index];
|
||||
temp = cd[index];
|
||||
|
||||
svga->dac_addr = (svga->dac_addr + 1) & da_mask;
|
||||
break;
|
||||
case 0x0c: /* Cursor X Low Register (RS value = 1100) */
|
||||
temp = ramdac->hwc_x & 0xff;
|
||||
break;
|
||||
case 0x0d: /* Cursor X High Register (RS value = 1101) */
|
||||
temp = (ramdac->hwc_x >> 8) & 0xff;
|
||||
break;
|
||||
case 0x0e: /* Cursor Y Low Register (RS value = 1110) */
|
||||
temp = ramdac->hwc_y & 0xff;
|
||||
break;
|
||||
case 0x0f: /* Cursor Y High Register (RS value = 1111) */
|
||||
temp = (ramdac->hwc_y >> 8) & 0xff;
|
||||
break;
|
||||
svga->dac_addr = (svga->dac_addr + 1) & da_mask;
|
||||
break;
|
||||
case 0x0c: /* Cursor X Low Register (RS value = 1100) */
|
||||
temp = ramdac->hwc_x & 0xff;
|
||||
break;
|
||||
case 0x0d: /* Cursor X High Register (RS value = 1101) */
|
||||
temp = (ramdac->hwc_x >> 8) & 0xff;
|
||||
break;
|
||||
case 0x0e: /* Cursor Y Low Register (RS value = 1110) */
|
||||
temp = ramdac->hwc_y & 0xff;
|
||||
break;
|
||||
case 0x0f: /* Cursor Y High Register (RS value = 1111) */
|
||||
temp = (ramdac->hwc_y >> 8) & 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bt48x_recalctimings(void *p, svga_t *svga)
|
||||
{
|
||||
@@ -354,19 +349,18 @@ bt48x_recalctimings(void *p, svga_t *svga)
|
||||
|
||||
svga->interlace = ramdac->cmd_r2 & 0x08;
|
||||
if (ramdac->cmd_r3 & 0x08)
|
||||
svga->hdisp *= 2; /* x2 clock multiplier */
|
||||
svga->hdisp *= 2; /* x2 clock multiplier */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
bt48x_hwcursor_draw(svga_t *svga, int displine)
|
||||
{
|
||||
int x, xx, comb, b0, b1;
|
||||
uint16_t dat[2];
|
||||
int offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff;
|
||||
int pitch, bppl, mode, x_pos, y_pos;
|
||||
uint32_t clr1, clr2, clr3, *p;
|
||||
uint8_t *cd;
|
||||
int x, xx, comb, b0, b1;
|
||||
uint16_t dat[2];
|
||||
int offset = svga->dac_hwcursor_latch.x - svga->dac_hwcursor_latch.xoff;
|
||||
int pitch, bppl, mode, x_pos, y_pos;
|
||||
uint32_t clr1, clr2, clr3, *p;
|
||||
uint8_t *cd;
|
||||
bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) svga->ramdac;
|
||||
|
||||
clr1 = ramdac->extpallook[1];
|
||||
@@ -376,85 +370,82 @@ bt48x_hwcursor_draw(svga_t *svga, int displine)
|
||||
/* The planes come in two parts, and each plane is 1bpp,
|
||||
so a 32x32 cursor has 4 bytes per line, and a 64x64
|
||||
cursor has 8 bytes per line. */
|
||||
pitch = (svga->dac_hwcursor_latch.cur_xsize >> 3); /* Bytes per line. */
|
||||
pitch = (svga->dac_hwcursor_latch.cur_xsize >> 3); /* Bytes per line. */
|
||||
/* A 32x32 cursor has 128 bytes per line, and a 64x64
|
||||
cursor has 512 bytes per line. */
|
||||
bppl = (pitch * svga->dac_hwcursor_latch.cur_ysize); /* Bytes per plane. */
|
||||
bppl = (pitch * svga->dac_hwcursor_latch.cur_ysize); /* Bytes per plane. */
|
||||
mode = ramdac->cmd_r2 & 0x03;
|
||||
|
||||
if (svga->interlace && svga->dac_hwcursor_oddeven)
|
||||
svga->dac_hwcursor_latch.addr += pitch;
|
||||
svga->dac_hwcursor_latch.addr += pitch;
|
||||
|
||||
if (svga->dac_hwcursor_latch.cur_xsize == 64)
|
||||
cd = (uint8_t *) ramdac->cursor64_data;
|
||||
cd = (uint8_t *) ramdac->cursor64_data;
|
||||
else
|
||||
cd = (uint8_t *) ramdac->cursor32_data;
|
||||
cd = (uint8_t *) ramdac->cursor32_data;
|
||||
|
||||
for (x = 0; x < svga->dac_hwcursor_latch.cur_xsize; x += 16) {
|
||||
dat[0] = (cd[svga->dac_hwcursor_latch.addr] << 8) |
|
||||
cd[svga->dac_hwcursor_latch.addr + 1];
|
||||
dat[1] = (cd[svga->dac_hwcursor_latch.addr + bppl] << 8) |
|
||||
cd[svga->dac_hwcursor_latch.addr + bppl + 1];
|
||||
dat[0] = (cd[svga->dac_hwcursor_latch.addr] << 8) | cd[svga->dac_hwcursor_latch.addr + 1];
|
||||
dat[1] = (cd[svga->dac_hwcursor_latch.addr + bppl] << 8) | cd[svga->dac_hwcursor_latch.addr + bppl + 1];
|
||||
|
||||
for (xx = 0; xx < 16; xx++) {
|
||||
b0 = (dat[0] >> (15 - xx)) & 1;
|
||||
b1 = (dat[1] >> (15 - xx)) & 1;
|
||||
comb = (b0 | (b1 << 1));
|
||||
for (xx = 0; xx < 16; xx++) {
|
||||
b0 = (dat[0] >> (15 - xx)) & 1;
|
||||
b1 = (dat[1] >> (15 - xx)) & 1;
|
||||
comb = (b0 | (b1 << 1));
|
||||
|
||||
y_pos = displine;
|
||||
x_pos = offset + svga->x_add;
|
||||
p = buffer32->line[y_pos];
|
||||
y_pos = displine;
|
||||
x_pos = offset + svga->x_add;
|
||||
p = buffer32->line[y_pos];
|
||||
|
||||
if (offset >= svga->dac_hwcursor_latch.x) {
|
||||
switch (mode) {
|
||||
case 1: /* Three Color */
|
||||
switch (comb) {
|
||||
case 1:
|
||||
p[x_pos] = clr1;
|
||||
break;
|
||||
case 2:
|
||||
p[x_pos] = clr2;
|
||||
break;
|
||||
case 3:
|
||||
p[x_pos] = clr3;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2: /* PM/Windows */
|
||||
switch (comb) {
|
||||
case 0:
|
||||
p[x_pos] = clr1;
|
||||
break;
|
||||
case 1:
|
||||
p[x_pos] = clr2;
|
||||
break;
|
||||
case 3:
|
||||
p[x_pos] ^= 0xffffff;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3: /* X-Windows */
|
||||
switch (comb) {
|
||||
case 2:
|
||||
p[x_pos] = clr1;
|
||||
break;
|
||||
case 3:
|
||||
p[x_pos] = clr2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
svga->dac_hwcursor_latch.addr += 2;
|
||||
if (offset >= svga->dac_hwcursor_latch.x) {
|
||||
switch (mode) {
|
||||
case 1: /* Three Color */
|
||||
switch (comb) {
|
||||
case 1:
|
||||
p[x_pos] = clr1;
|
||||
break;
|
||||
case 2:
|
||||
p[x_pos] = clr2;
|
||||
break;
|
||||
case 3:
|
||||
p[x_pos] = clr3;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2: /* PM/Windows */
|
||||
switch (comb) {
|
||||
case 0:
|
||||
p[x_pos] = clr1;
|
||||
break;
|
||||
case 1:
|
||||
p[x_pos] = clr2;
|
||||
break;
|
||||
case 3:
|
||||
p[x_pos] ^= 0xffffff;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3: /* X-Windows */
|
||||
switch (comb) {
|
||||
case 2:
|
||||
p[x_pos] = clr1;
|
||||
break;
|
||||
case 3:
|
||||
p[x_pos] = clr2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
svga->dac_hwcursor_latch.addr += 2;
|
||||
}
|
||||
|
||||
if (svga->interlace && !svga->dac_hwcursor_oddeven)
|
||||
svga->dac_hwcursor_latch.addr += pitch;
|
||||
svga->dac_hwcursor_latch.addr += pitch;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
bt48x_ramdac_init(const device_t *info)
|
||||
{
|
||||
@@ -465,106 +456,105 @@ bt48x_ramdac_init(const device_t *info)
|
||||
|
||||
/* Set the RAM DAC status byte to the correct ID bits.
|
||||
|
||||
Both the BT484 and BT485 datasheets say this:
|
||||
SR7-SR6: These bits are identification values. SR7=0 and SR6=1.
|
||||
But all other sources seem to assume SR7=1 and SR6=0. */
|
||||
Both the BT484 and BT485 datasheets say this:
|
||||
SR7-SR6: These bits are identification values. SR7=0 and SR6=1.
|
||||
But all other sources seem to assume SR7=1 and SR6=0. */
|
||||
switch (ramdac->type) {
|
||||
case BT484:
|
||||
ramdac->status = 0x40;
|
||||
break;
|
||||
case ATT20C504:
|
||||
ramdac->status = 0x40;
|
||||
break;
|
||||
case BT485:
|
||||
ramdac->status = 0x60;
|
||||
break;
|
||||
case ATT20C505:
|
||||
ramdac->status = 0xd0;
|
||||
break;
|
||||
case BT485A:
|
||||
ramdac->status = 0x20;
|
||||
break;
|
||||
case BT484:
|
||||
ramdac->status = 0x40;
|
||||
break;
|
||||
case ATT20C504:
|
||||
ramdac->status = 0x40;
|
||||
break;
|
||||
case BT485:
|
||||
ramdac->status = 0x60;
|
||||
break;
|
||||
case ATT20C505:
|
||||
ramdac->status = 0xd0;
|
||||
break;
|
||||
case BT485A:
|
||||
ramdac->status = 0x20;
|
||||
break;
|
||||
}
|
||||
|
||||
return ramdac;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
bt48x_ramdac_close(void *priv)
|
||||
{
|
||||
bt48x_ramdac_t *ramdac = (bt48x_ramdac_t *) priv;
|
||||
|
||||
if (ramdac)
|
||||
free(ramdac);
|
||||
free(ramdac);
|
||||
}
|
||||
|
||||
const device_t bt484_ramdac_device = {
|
||||
.name = "Brooktree Bt484 RAMDAC",
|
||||
.name = "Brooktree Bt484 RAMDAC",
|
||||
.internal_name = "bt484_ramdac",
|
||||
.flags = 0,
|
||||
.local = BT484,
|
||||
.init = bt48x_ramdac_init,
|
||||
.close = bt48x_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = BT484,
|
||||
.init = bt48x_ramdac_init,
|
||||
.close = bt48x_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t att20c504_ramdac_device = {
|
||||
.name = "AT&T 20c504 RAMDAC",
|
||||
.name = "AT&T 20c504 RAMDAC",
|
||||
.internal_name = "att20c504_ramdac",
|
||||
.flags = 0,
|
||||
.local = ATT20C504,
|
||||
.init = bt48x_ramdac_init,
|
||||
.close = bt48x_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = ATT20C504,
|
||||
.init = bt48x_ramdac_init,
|
||||
.close = bt48x_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t bt485_ramdac_device = {
|
||||
.name = "Brooktree Bt485 RAMDAC",
|
||||
.name = "Brooktree Bt485 RAMDAC",
|
||||
.internal_name = "bt485_ramdac",
|
||||
.flags = 0,
|
||||
.local = BT485,
|
||||
.init = bt48x_ramdac_init,
|
||||
.close = bt48x_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = BT485,
|
||||
.init = bt48x_ramdac_init,
|
||||
.close = bt48x_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t att20c505_ramdac_device = {
|
||||
.name = "AT&T 20c505 RAMDAC",
|
||||
.name = "AT&T 20c505 RAMDAC",
|
||||
.internal_name = "att20c505_ramdac",
|
||||
.flags = 0,
|
||||
.local = ATT20C505,
|
||||
.init = bt48x_ramdac_init,
|
||||
.close = bt48x_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = ATT20C505,
|
||||
.init = bt48x_ramdac_init,
|
||||
.close = bt48x_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t bt485a_ramdac_device = {
|
||||
.name = "Brooktree Bt485A RAMDAC",
|
||||
.name = "Brooktree Bt485A RAMDAC",
|
||||
.internal_name = "bt485a_ramdac",
|
||||
.flags = 0,
|
||||
.local = BT485A,
|
||||
.init = bt48x_ramdac_init,
|
||||
.close = bt48x_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = BT485A,
|
||||
.init = bt48x_ramdac_init,
|
||||
.close = bt48x_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -34,68 +34,64 @@
|
||||
#include <86box/vid_cga.h>
|
||||
#include <86box/vid_cga_comp.h>
|
||||
|
||||
|
||||
#define CGA_RGB 0
|
||||
#define CGA_RGB 0
|
||||
#define CGA_COMPOSITE 1
|
||||
|
||||
#define COMPOSITE_OLD 0
|
||||
#define COMPOSITE_NEW 1
|
||||
|
||||
static uint8_t crtcmask[32] =
|
||||
{
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
static uint8_t crtcmask[32] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static video_timings_t timing_cga = {VIDEO_ISA, 8, 16, 32, 8, 16, 32};
|
||||
static video_timings_t timing_cga = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
|
||||
|
||||
void cga_recalctimings(cga_t *cga);
|
||||
|
||||
|
||||
void
|
||||
cga_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
cga_t *cga = (cga_t *) p;
|
||||
cga_t *cga = (cga_t *) p;
|
||||
uint8_t old;
|
||||
|
||||
if ((addr >= 0x3d0) && (addr <= 0x3d7))
|
||||
addr = (addr & 0xff9) | 0x004;
|
||||
addr = (addr & 0xff9) | 0x004;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3D4:
|
||||
cga->crtcreg = val & 31;
|
||||
return;
|
||||
case 0x3D5:
|
||||
old = cga->crtc[cga->crtcreg];
|
||||
cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg];
|
||||
if (old != val) {
|
||||
if ((cga->crtcreg < 0xe) || (cga->crtcreg > 0x10)) {
|
||||
cga->fullchange = changeframecount;
|
||||
cga_recalctimings(cga);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case 0x3D8:
|
||||
old = cga->cgamode;
|
||||
cga->cgamode = val;
|
||||
case 0x3D4:
|
||||
cga->crtcreg = val & 31;
|
||||
return;
|
||||
case 0x3D5:
|
||||
old = cga->crtc[cga->crtcreg];
|
||||
cga->crtc[cga->crtcreg] = val & crtcmask[cga->crtcreg];
|
||||
if (old != val) {
|
||||
if ((cga->crtcreg < 0xe) || (cga->crtcreg > 0x10)) {
|
||||
cga->fullchange = changeframecount;
|
||||
cga_recalctimings(cga);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case 0x3D8:
|
||||
old = cga->cgamode;
|
||||
cga->cgamode = val;
|
||||
|
||||
if (old ^ val) {
|
||||
if ((old ^ val) & 0x05)
|
||||
update_cga16_color(val);
|
||||
if (old ^ val) {
|
||||
if ((old ^ val) & 0x05)
|
||||
update_cga16_color(val);
|
||||
|
||||
cga_recalctimings(cga);
|
||||
}
|
||||
return;
|
||||
case 0x3D9:
|
||||
old = cga->cgacol;
|
||||
cga->cgacol = val;
|
||||
if (old ^ val)
|
||||
cga_recalctimings(cga);
|
||||
return;
|
||||
cga_recalctimings(cga);
|
||||
}
|
||||
return;
|
||||
case 0x3D9:
|
||||
old = cga->cgacol;
|
||||
cga->cgacol = val;
|
||||
if (old ^ val)
|
||||
cga_recalctimings(cga);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
cga_in(uint16_t addr, void *p)
|
||||
{
|
||||
@@ -104,35 +100,33 @@ cga_in(uint16_t addr, void *p)
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if ((addr >= 0x3d0) && (addr <= 0x3d7))
|
||||
addr = (addr & 0xff9) | 0x004;
|
||||
addr = (addr & 0xff9) | 0x004;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3D4:
|
||||
ret = cga->crtcreg;
|
||||
break;
|
||||
case 0x3D5:
|
||||
ret = cga->crtc[cga->crtcreg];
|
||||
break;
|
||||
case 0x3DA:
|
||||
ret = cga->cgastat;
|
||||
break;
|
||||
case 0x3D4:
|
||||
ret = cga->crtcreg;
|
||||
break;
|
||||
case 0x3D5:
|
||||
ret = cga->crtc[cga->crtcreg];
|
||||
break;
|
||||
case 0x3DA:
|
||||
ret = cga->cgastat;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cga_waitstates(void *p)
|
||||
{
|
||||
int ws_array[16] = {3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8};
|
||||
int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 };
|
||||
int ws;
|
||||
|
||||
ws = ws_array[cycles & 0xf];
|
||||
cycles -= ws;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cga_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
@@ -140,14 +134,13 @@ cga_write(uint32_t addr, uint8_t val, void *p)
|
||||
|
||||
cga->vram[addr & 0x3fff] = val;
|
||||
if (cga->snow_enabled) {
|
||||
int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc;
|
||||
cga->charbuffer[offset] = cga->vram[addr & 0x3fff];
|
||||
cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff];
|
||||
int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc;
|
||||
cga->charbuffer[offset] = cga->vram[addr & 0x3fff];
|
||||
cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff];
|
||||
}
|
||||
cga_waitstates(cga);
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
cga_read(uint32_t addr, void *p)
|
||||
{
|
||||
@@ -155,14 +148,13 @@ cga_read(uint32_t addr, void *p)
|
||||
|
||||
cga_waitstates(cga);
|
||||
if (cga->snow_enabled) {
|
||||
int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc;
|
||||
cga->charbuffer[offset] = cga->vram[addr & 0x3fff];
|
||||
cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff];
|
||||
int offset = ((timer_get_remaining_u64(&cga->timer) / CGACONST) * 2) & 0xfc;
|
||||
cga->charbuffer[offset] = cga->vram[addr & 0x3fff];
|
||||
cga->charbuffer[offset | 1] = cga->vram[addr & 0x3fff];
|
||||
}
|
||||
return cga->vram[addr & 0x3fff];
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cga_recalctimings(cga_t *cga)
|
||||
{
|
||||
@@ -170,354 +162,331 @@ cga_recalctimings(cga_t *cga)
|
||||
double _dispontime, _dispofftime;
|
||||
|
||||
if (cga->cgamode & 1) {
|
||||
disptime = (double) (cga->crtc[0] + 1);
|
||||
_dispontime = (double) cga->crtc[1];
|
||||
disptime = (double) (cga->crtc[0] + 1);
|
||||
_dispontime = (double) cga->crtc[1];
|
||||
} else {
|
||||
disptime = (double) ((cga->crtc[0] + 1) << 1);
|
||||
_dispontime = (double) (cga->crtc[1] << 1);
|
||||
disptime = (double) ((cga->crtc[0] + 1) << 1);
|
||||
_dispontime = (double) (cga->crtc[1] << 1);
|
||||
}
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime = _dispontime * CGACONST;
|
||||
_dispofftime = _dispofftime * CGACONST;
|
||||
cga->dispontime = (uint64_t)(_dispontime);
|
||||
cga->dispofftime = (uint64_t)(_dispofftime);
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime = _dispontime * CGACONST;
|
||||
_dispofftime = _dispofftime * CGACONST;
|
||||
cga->dispontime = (uint64_t) (_dispontime);
|
||||
cga->dispofftime = (uint64_t) (_dispofftime);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cga_poll(void *p)
|
||||
{
|
||||
cga_t *cga = (cga_t *)p;
|
||||
uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x, c, xs_temp, ys_temp;
|
||||
int oldvc;
|
||||
uint8_t chr, attr;
|
||||
uint8_t border;
|
||||
cga_t *cga = (cga_t *) p;
|
||||
uint16_t ca = (cga->crtc[15] | (cga->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x, c, xs_temp, ys_temp;
|
||||
int oldvc;
|
||||
uint8_t chr, attr;
|
||||
uint8_t border;
|
||||
uint16_t dat;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
|
||||
if (!cga->linepos) {
|
||||
timer_advance_u64(&cga->timer, cga->dispofftime);
|
||||
cga->cgastat |= 1;
|
||||
cga->linepos = 1;
|
||||
oldsc = cga->sc;
|
||||
if ((cga->crtc[8] & 3) == 3)
|
||||
cga->sc = ((cga->sc << 1) + cga->oddeven) & 7;
|
||||
if (cga->cgadispon) {
|
||||
if (cga->displine < cga->firstline) {
|
||||
cga->firstline = cga->displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
cga->lastline = cga->displine;
|
||||
for (c = 0; c < 8; c++) {
|
||||
if ((cga->cgamode & 0x12) == 0x12) {
|
||||
buffer32->line[(cga->displine << 1)][c] =
|
||||
buffer32->line[(cga->displine << 1) + 1][c] = 0;
|
||||
if (cga->cgamode & 1) {
|
||||
buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 3) + 8] =
|
||||
buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = 0;
|
||||
} else {
|
||||
buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 4) + 8] =
|
||||
buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = 0;
|
||||
}
|
||||
} else {
|
||||
buffer32->line[(cga->displine << 1)][c] =
|
||||
buffer32->line[(cga->displine << 1) + 1][c] = (cga->cgacol & 15) + 16;
|
||||
if (cga->cgamode & 1) {
|
||||
buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 3) + 8] =
|
||||
buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16;
|
||||
} else {
|
||||
buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 4) + 8] =
|
||||
buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cga->cgamode & 1) {
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
if (cga->cgamode & 8) {
|
||||
chr = cga->charbuffer[x << 1];
|
||||
attr = cga->charbuffer[(x << 1) + 1];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
|
||||
cols[1] = (attr & 15) + 16;
|
||||
if (cga->cgamode & 0x20) {
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[(cga->displine << 1)][(x << 3) + c + 8] =
|
||||
buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] =
|
||||
cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[(cga->displine << 1)][(x << 3) + c + 8] =
|
||||
buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] =
|
||||
cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
cga->ma++;
|
||||
}
|
||||
} else if (!(cga->cgamode & 2)) {
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
if (cga->cgamode & 8) {
|
||||
chr = cga->vram[((cga->ma << 1) & 0x3fff)];
|
||||
attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
|
||||
cols[1] = (attr & 15) + 16;
|
||||
if (cga->cgamode & 0x20) {
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((cga->cgablink & 8) && (attr & 0x80))
|
||||
cols[1] = cols[0];
|
||||
} else
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
cga->ma++;
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 8] =
|
||||
buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 1 + 8] =
|
||||
buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] =
|
||||
buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] =
|
||||
cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 8] =
|
||||
buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 1 + 8] =
|
||||
buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] =
|
||||
buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] =
|
||||
cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!(cga->cgamode & 16)) {
|
||||
cols[0] = (cga->cgacol & 15) | 16;
|
||||
col = (cga->cgacol & 16) ? 24 : 16;
|
||||
if (cga->cgamode & 4) {
|
||||
cols[1] = col | 3; /* Cyan */
|
||||
cols[2] = col | 4; /* Red */
|
||||
cols[3] = col | 7; /* White */
|
||||
} else if (cga->cgacol & 32) {
|
||||
cols[1] = col | 3; /* Cyan */
|
||||
cols[2] = col | 5; /* Magenta */
|
||||
cols[3] = col | 7; /* White */
|
||||
} else {
|
||||
cols[1] = col | 2; /* Green */
|
||||
cols[2] = col | 4; /* Red */
|
||||
cols[3] = col | 6; /* Yellow */
|
||||
}
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
if (cga->cgamode & 8)
|
||||
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
|
||||
else
|
||||
dat = 0;
|
||||
cga->ma++;
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 8] =
|
||||
buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 1 + 8] =
|
||||
buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] =
|
||||
buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] =
|
||||
cols[dat >> 14];
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cols[0] = 0; cols[1] = (cga->cgacol & 15) + 16;
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
if (cga->cgamode & 8)
|
||||
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
|
||||
else
|
||||
dat = 0;
|
||||
cga->ma++;
|
||||
for (c = 0; c < 16; c++) {
|
||||
buffer32->line[(cga->displine << 1)][(x << 4) + c + 8] =
|
||||
buffer32->line[(cga->displine << 1) + 1][(x << 4) + c + 8] =
|
||||
cols[dat >> 15];
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16;
|
||||
if (cga->cgamode & 1) {
|
||||
hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 3) + 16) << 2, cols[0]);
|
||||
hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 3) + 16) << 2, cols[0]);
|
||||
} else {
|
||||
hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 4) + 16) << 2, cols[0]);
|
||||
hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 4) + 16) << 2, cols[0]);
|
||||
}
|
||||
}
|
||||
timer_advance_u64(&cga->timer, cga->dispofftime);
|
||||
cga->cgastat |= 1;
|
||||
cga->linepos = 1;
|
||||
oldsc = cga->sc;
|
||||
if ((cga->crtc[8] & 3) == 3)
|
||||
cga->sc = ((cga->sc << 1) + cga->oddeven) & 7;
|
||||
if (cga->cgadispon) {
|
||||
if (cga->displine < cga->firstline) {
|
||||
cga->firstline = cga->displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
cga->lastline = cga->displine;
|
||||
for (c = 0; c < 8; c++) {
|
||||
if ((cga->cgamode & 0x12) == 0x12) {
|
||||
buffer32->line[(cga->displine << 1)][c] = buffer32->line[(cga->displine << 1) + 1][c] = 0;
|
||||
if (cga->cgamode & 1) {
|
||||
buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 3) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = 0;
|
||||
} else {
|
||||
buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 4) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = 0;
|
||||
}
|
||||
} else {
|
||||
buffer32->line[(cga->displine << 1)][c] = buffer32->line[(cga->displine << 1) + 1][c] = (cga->cgacol & 15) + 16;
|
||||
if (cga->cgamode & 1) {
|
||||
buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 3) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 3) + 8] = (cga->cgacol & 15) + 16;
|
||||
} else {
|
||||
buffer32->line[(cga->displine << 1)][c + (cga->crtc[1] << 4) + 8] = buffer32->line[(cga->displine << 1) + 1][c + (cga->crtc[1] << 4) + 8] = (cga->cgacol & 15) + 16;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cga->cgamode & 1) {
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
if (cga->cgamode & 8) {
|
||||
chr = cga->charbuffer[x << 1];
|
||||
attr = cga->charbuffer[(x << 1) + 1];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
|
||||
cols[1] = (attr & 15) + 16;
|
||||
if (cga->cgamode & 0x20) {
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((cga->cgablink & 8) && (attr & 0x80) && !cga->drawcursor)
|
||||
cols[1] = cols[0];
|
||||
} else
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[(cga->displine << 1)][(x << 3) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[(cga->displine << 1)][(x << 3) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 3) + c + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
cga->ma++;
|
||||
}
|
||||
} else if (!(cga->cgamode & 2)) {
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
if (cga->cgamode & 8) {
|
||||
chr = cga->vram[((cga->ma << 1) & 0x3fff)];
|
||||
attr = cga->vram[(((cga->ma << 1) + 1) & 0x3fff)];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
drawcursor = ((cga->ma == ca) && cga->con && cga->cursoron);
|
||||
cols[1] = (attr & 15) + 16;
|
||||
if (cga->cgamode & 0x20) {
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((cga->cgablink & 8) && (attr & 0x80))
|
||||
cols[1] = cols[0];
|
||||
} else
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
cga->ma++;
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
}
|
||||
} else {
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdat[chr + cga->fontbase][cga->sc & 7] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!(cga->cgamode & 16)) {
|
||||
cols[0] = (cga->cgacol & 15) | 16;
|
||||
col = (cga->cgacol & 16) ? 24 : 16;
|
||||
if (cga->cgamode & 4) {
|
||||
cols[1] = col | 3; /* Cyan */
|
||||
cols[2] = col | 4; /* Red */
|
||||
cols[3] = col | 7; /* White */
|
||||
} else if (cga->cgacol & 32) {
|
||||
cols[1] = col | 3; /* Cyan */
|
||||
cols[2] = col | 5; /* Magenta */
|
||||
cols[3] = col | 7; /* White */
|
||||
} else {
|
||||
cols[1] = col | 2; /* Green */
|
||||
cols[2] = col | 4; /* Red */
|
||||
cols[3] = col | 6; /* Yellow */
|
||||
}
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
if (cga->cgamode & 8)
|
||||
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
|
||||
else
|
||||
dat = 0;
|
||||
cga->ma++;
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1)][(x << 4) + (c << 1) + 1 + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + (c << 1) + 1 + 8] = cols[dat >> 14];
|
||||
dat <<= 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cols[0] = 0;
|
||||
cols[1] = (cga->cgacol & 15) + 16;
|
||||
for (x = 0; x < cga->crtc[1]; x++) {
|
||||
if (cga->cgamode & 8)
|
||||
dat = (cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000)] << 8) | cga->vram[((cga->ma << 1) & 0x1fff) + ((cga->sc & 1) * 0x2000) + 1];
|
||||
else
|
||||
dat = 0;
|
||||
cga->ma++;
|
||||
for (c = 0; c < 16; c++) {
|
||||
buffer32->line[(cga->displine << 1)][(x << 4) + c + 8] = buffer32->line[(cga->displine << 1) + 1][(x << 4) + c + 8] = cols[dat >> 15];
|
||||
dat <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cols[0] = ((cga->cgamode & 0x12) == 0x12) ? 0 : (cga->cgacol & 15) + 16;
|
||||
if (cga->cgamode & 1) {
|
||||
hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 3) + 16) << 2, cols[0]);
|
||||
hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 3) + 16) << 2, cols[0]);
|
||||
} else {
|
||||
hline(buffer32, 0, (cga->displine << 1), ((cga->crtc[1] << 4) + 16) << 2, cols[0]);
|
||||
hline(buffer32, 0, (cga->displine << 1) + 1, ((cga->crtc[1] << 4) + 16) << 2, cols[0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (cga->cgamode & 1)
|
||||
x = (cga->crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (cga->crtc[1] << 4) + 16;
|
||||
if (cga->cgamode & 1)
|
||||
x = (cga->crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (cga->crtc[1] << 4) + 16;
|
||||
|
||||
if (cga->composite) {
|
||||
if (cga->cgamode & 0x10)
|
||||
border = 0x00;
|
||||
else
|
||||
border = cga->cgacol & 0x0f;
|
||||
if (cga->composite) {
|
||||
if (cga->cgamode & 0x10)
|
||||
border = 0x00;
|
||||
else
|
||||
border = cga->cgacol & 0x0f;
|
||||
|
||||
Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[(cga->displine << 1)]);
|
||||
Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[(cga->displine << 1) + 1]);
|
||||
}
|
||||
Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[(cga->displine << 1)]);
|
||||
Composite_Process(cga->cgamode, border, x >> 2, buffer32->line[(cga->displine << 1) + 1]);
|
||||
}
|
||||
|
||||
cga->sc = oldsc;
|
||||
if (cga->vc == cga->crtc[7] && !cga->sc)
|
||||
cga->cgastat |= 8;
|
||||
cga->displine++;
|
||||
if (cga->displine >= 360)
|
||||
cga->displine = 0;
|
||||
cga->sc = oldsc;
|
||||
if (cga->vc == cga->crtc[7] && !cga->sc)
|
||||
cga->cgastat |= 8;
|
||||
cga->displine++;
|
||||
if (cga->displine >= 360)
|
||||
cga->displine = 0;
|
||||
} else {
|
||||
timer_advance_u64(&cga->timer, cga->dispontime);
|
||||
cga->linepos = 0;
|
||||
if (cga->vsynctime) {
|
||||
cga->vsynctime--;
|
||||
if (!cga->vsynctime)
|
||||
cga->cgastat &= ~8;
|
||||
}
|
||||
if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) {
|
||||
cga->con = 0;
|
||||
cga->coff = 1;
|
||||
}
|
||||
if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1))
|
||||
cga->maback = cga->ma;
|
||||
if (cga->vadj) {
|
||||
cga->sc++;
|
||||
cga->sc &= 31;
|
||||
cga->ma = cga->maback;
|
||||
cga->vadj--;
|
||||
if (!cga->vadj) {
|
||||
cga->cgadispon = 1;
|
||||
cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
|
||||
cga->sc = 0;
|
||||
}
|
||||
} else if (cga->sc == cga->crtc[9]) {
|
||||
cga->maback = cga->ma;
|
||||
cga->sc = 0;
|
||||
oldvc = cga->vc;
|
||||
cga->vc++;
|
||||
cga->vc &= 127;
|
||||
timer_advance_u64(&cga->timer, cga->dispontime);
|
||||
cga->linepos = 0;
|
||||
if (cga->vsynctime) {
|
||||
cga->vsynctime--;
|
||||
if (!cga->vsynctime)
|
||||
cga->cgastat &= ~8;
|
||||
}
|
||||
if (cga->sc == (cga->crtc[11] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[11] & 31) >> 1))) {
|
||||
cga->con = 0;
|
||||
cga->coff = 1;
|
||||
}
|
||||
if ((cga->crtc[8] & 3) == 3 && cga->sc == (cga->crtc[9] >> 1))
|
||||
cga->maback = cga->ma;
|
||||
if (cga->vadj) {
|
||||
cga->sc++;
|
||||
cga->sc &= 31;
|
||||
cga->ma = cga->maback;
|
||||
cga->vadj--;
|
||||
if (!cga->vadj) {
|
||||
cga->cgadispon = 1;
|
||||
cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
|
||||
cga->sc = 0;
|
||||
}
|
||||
} else if (cga->sc == cga->crtc[9]) {
|
||||
cga->maback = cga->ma;
|
||||
cga->sc = 0;
|
||||
oldvc = cga->vc;
|
||||
cga->vc++;
|
||||
cga->vc &= 127;
|
||||
|
||||
if (cga->vc == cga->crtc[6])
|
||||
cga->cgadispon = 0;
|
||||
if (cga->vc == cga->crtc[6])
|
||||
cga->cgadispon = 0;
|
||||
|
||||
if (oldvc == cga->crtc[4]) {
|
||||
cga->vc = 0;
|
||||
cga->vadj = cga->crtc[5];
|
||||
if (!cga->vadj) {
|
||||
cga->cgadispon = 1;
|
||||
cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
|
||||
}
|
||||
switch (cga->crtc[10] & 0x60) {
|
||||
case 0x20:
|
||||
cga->cursoron = 0;
|
||||
break;
|
||||
case 0x60:
|
||||
cga->cursoron = cga->cgablink & 0x10;
|
||||
break;
|
||||
default:
|
||||
cga->cursoron = cga->cgablink & 0x08;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (oldvc == cga->crtc[4]) {
|
||||
cga->vc = 0;
|
||||
cga->vadj = cga->crtc[5];
|
||||
if (!cga->vadj) {
|
||||
cga->cgadispon = 1;
|
||||
cga->ma = cga->maback = (cga->crtc[13] | (cga->crtc[12] << 8)) & 0x3fff;
|
||||
}
|
||||
switch (cga->crtc[10] & 0x60) {
|
||||
case 0x20:
|
||||
cga->cursoron = 0;
|
||||
break;
|
||||
case 0x60:
|
||||
cga->cursoron = cga->cgablink & 0x10;
|
||||
break;
|
||||
default:
|
||||
cga->cursoron = cga->cgablink & 0x08;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cga->vc == cga->crtc[7]) {
|
||||
cga->cgadispon = 0;
|
||||
cga->displine = 0;
|
||||
cga->vsynctime = 16;
|
||||
if (cga->crtc[7]) {
|
||||
if (cga->cgamode & 1)
|
||||
x = (cga->crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (cga->crtc[1] << 4) + 16;
|
||||
cga->lastline++;
|
||||
if (cga->vc == cga->crtc[7]) {
|
||||
cga->cgadispon = 0;
|
||||
cga->displine = 0;
|
||||
cga->vsynctime = 16;
|
||||
if (cga->crtc[7]) {
|
||||
if (cga->cgamode & 1)
|
||||
x = (cga->crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (cga->crtc[1] << 4) + 16;
|
||||
cga->lastline++;
|
||||
|
||||
xs_temp = x;
|
||||
ys_temp = (cga->lastline - cga->firstline) << 1;
|
||||
xs_temp = x;
|
||||
ys_temp = (cga->lastline - cga->firstline) << 1;
|
||||
|
||||
if ((xs_temp > 0) && (ys_temp > 0)) {
|
||||
if (xs_temp < 64) xs_temp = 656;
|
||||
if (ys_temp < 32) ys_temp = 400;
|
||||
if (!enable_overscan)
|
||||
xs_temp -= 16;
|
||||
if ((xs_temp > 0) && (ys_temp > 0)) {
|
||||
if (xs_temp < 64)
|
||||
xs_temp = 656;
|
||||
if (ys_temp < 32)
|
||||
ys_temp = 400;
|
||||
if (!enable_overscan)
|
||||
xs_temp -= 16;
|
||||
|
||||
if ((cga->cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0));
|
||||
if ((cga->cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0));
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
|
||||
if (enable_overscan) {
|
||||
if (cga->composite)
|
||||
video_blit_memtoscreen(0, (cga->firstline - 4) << 1,
|
||||
xsize, ((cga->lastline - cga->firstline) + 8) << 1);
|
||||
else
|
||||
video_blit_memtoscreen_8(0, (cga->firstline - 4) << 1,
|
||||
xsize, ((cga->lastline - cga->firstline) + 8) << 1);
|
||||
} else {
|
||||
if (cga->composite)
|
||||
video_blit_memtoscreen(8, cga->firstline << 1,
|
||||
xsize, (cga->lastline - cga->firstline) << 1);
|
||||
else
|
||||
video_blit_memtoscreen_8(8, cga->firstline << 1,
|
||||
xsize, (cga->lastline - cga->firstline) << 1);
|
||||
}
|
||||
}
|
||||
if (enable_overscan) {
|
||||
if (cga->composite)
|
||||
video_blit_memtoscreen(0, (cga->firstline - 4) << 1,
|
||||
xsize, ((cga->lastline - cga->firstline) + 8) << 1);
|
||||
else
|
||||
video_blit_memtoscreen_8(0, (cga->firstline - 4) << 1,
|
||||
xsize, ((cga->lastline - cga->firstline) + 8) << 1);
|
||||
} else {
|
||||
if (cga->composite)
|
||||
video_blit_memtoscreen(8, cga->firstline << 1,
|
||||
xsize, (cga->lastline - cga->firstline) << 1);
|
||||
else
|
||||
video_blit_memtoscreen_8(8, cga->firstline << 1,
|
||||
xsize, (cga->lastline - cga->firstline) << 1);
|
||||
}
|
||||
}
|
||||
|
||||
frames++;
|
||||
frames++;
|
||||
|
||||
video_res_x = xsize;
|
||||
video_res_y = ysize;
|
||||
if (cga->cgamode & 1) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= cga->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(cga->cgamode & 2)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= cga->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(cga->cgamode & 16)) {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
} else
|
||||
video_bpp = 1;
|
||||
}
|
||||
cga->firstline = 1000;
|
||||
cga->lastline = 0;
|
||||
cga->cgablink++;
|
||||
cga->oddeven ^= 1;
|
||||
}
|
||||
} else {
|
||||
cga->sc++;
|
||||
cga->sc &= 31;
|
||||
cga->ma = cga->maback;
|
||||
}
|
||||
if (cga->cgadispon)
|
||||
cga->cgastat &= ~1;
|
||||
if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1))))
|
||||
cga->con = 1;
|
||||
if (cga->cgadispon && (cga->cgamode & 1)) {
|
||||
for (x = 0; x < (cga->crtc[1] << 1); x++)
|
||||
cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)];
|
||||
}
|
||||
video_res_x = xsize;
|
||||
video_res_y = ysize;
|
||||
if (cga->cgamode & 1) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= cga->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(cga->cgamode & 2)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= cga->crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(cga->cgamode & 16)) {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
} else
|
||||
video_bpp = 1;
|
||||
}
|
||||
cga->firstline = 1000;
|
||||
cga->lastline = 0;
|
||||
cga->cgablink++;
|
||||
cga->oddeven ^= 1;
|
||||
}
|
||||
} else {
|
||||
cga->sc++;
|
||||
cga->sc &= 31;
|
||||
cga->ma = cga->maback;
|
||||
}
|
||||
if (cga->cgadispon)
|
||||
cga->cgastat &= ~1;
|
||||
if ((cga->sc == (cga->crtc[10] & 31) || ((cga->crtc[8] & 3) == 3 && cga->sc == ((cga->crtc[10] & 31) >> 1))))
|
||||
cga->con = 1;
|
||||
if (cga->cgadispon && (cga->cgamode & 1)) {
|
||||
for (x = 0; x < (cga->crtc[1] << 1); x++)
|
||||
cga->charbuffer[x] = cga->vram[(((cga->ma << 1) + x) & 0x3fff)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cga_init(cga_t *cga)
|
||||
{
|
||||
@@ -525,19 +494,18 @@ cga_init(cga_t *cga)
|
||||
cga->composite = 0;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
cga_standalone_init(const device_t *info)
|
||||
{
|
||||
int display_type;
|
||||
int display_type;
|
||||
cga_t *cga = malloc(sizeof(cga_t));
|
||||
|
||||
memset(cga, 0, sizeof(cga_t));
|
||||
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_cga);
|
||||
|
||||
display_type = device_get_config_int("display_type");
|
||||
cga->composite = (display_type != CGA_RGB);
|
||||
cga->revision = device_get_config_int("composite_type");
|
||||
display_type = device_get_config_int("display_type");
|
||||
cga->composite = (display_type != CGA_RGB);
|
||||
cga->revision = device_get_config_int("composite_type");
|
||||
cga->snow_enabled = device_get_config_int("snow_enabled");
|
||||
|
||||
cga->vram = malloc(0x4000);
|
||||
@@ -550,13 +518,12 @@ cga_standalone_init(const device_t *info)
|
||||
overscan_x = overscan_y = 16;
|
||||
|
||||
cga->rgb_type = device_get_config_int("rgb_type");
|
||||
cga_palette = (cga->rgb_type << 1);
|
||||
cga_palette = (cga->rgb_type << 1);
|
||||
cgapal_rebuild();
|
||||
|
||||
return cga;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cga_close(void *p)
|
||||
{
|
||||
@@ -566,7 +533,6 @@ cga_close(void *p)
|
||||
free(cga);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cga_speed_changed(void *p)
|
||||
{
|
||||
@@ -659,15 +625,15 @@ const device_config_t cga_config[] = {
|
||||
// clang-format on
|
||||
|
||||
const device_t cga_device = {
|
||||
.name = "CGA",
|
||||
.name = "CGA",
|
||||
.internal_name = "cga",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = cga_standalone_init,
|
||||
.close = cga_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = cga_standalone_init,
|
||||
.close = cga_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = cga_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = cga_config
|
||||
.force_redraw = NULL,
|
||||
.config = cga_config
|
||||
};
|
||||
|
||||
@@ -29,14 +29,12 @@
|
||||
#include <86box/vid_cga.h>
|
||||
#include <86box/vid_cga_comp.h>
|
||||
|
||||
|
||||
int CGA_Composite_Table[1024];
|
||||
|
||||
|
||||
static double brightness = 0;
|
||||
static double contrast = 100;
|
||||
static double contrast = 100;
|
||||
static double saturation = 100;
|
||||
static double sharpness = 0;
|
||||
static double sharpness = 0;
|
||||
static double hue_offset = 0;
|
||||
|
||||
/* New algorithm by reenigne
|
||||
@@ -45,6 +43,7 @@ static double hue_offset = 0;
|
||||
static const double tau = 6.28318531; /* == 2*pi */
|
||||
|
||||
static unsigned char chroma_multiplexer[256] = {
|
||||
// clang-format off
|
||||
2, 2, 2, 2, 114,174, 4, 3, 2, 1,133,135, 2,113,150, 4,
|
||||
133, 2, 1, 99, 151,152, 2, 1, 3, 2, 96,136, 151,152,151,152,
|
||||
2, 56, 62, 4, 111,250,118, 4, 0, 51,207,137, 1,171,209, 5,
|
||||
@@ -60,12 +59,15 @@ static unsigned char chroma_multiplexer[256] = {
|
||||
78, 4, 0, 75, 166,180, 20, 38, 78, 1,143,246, 42,113,156, 37,
|
||||
252, 4, 1,188, 175,129, 1, 37, 118, 4, 88,249, 202,150,145,200,
|
||||
61, 59, 60, 60, 228,252,117, 77, 60, 58,248,251, 81,212,254,107,
|
||||
198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252};
|
||||
198, 59, 58,169, 250,251, 81, 80, 100, 58,154,250, 251,252,252,252
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static double intensity[4] = {
|
||||
77.175381, 88.654656, 166.564623, 174.228438};
|
||||
77.175381, 88.654656, 166.564623, 174.228438
|
||||
};
|
||||
|
||||
#define NEW_CGA(c,i,r,g,b) (((c)/0.72)*0.29 + ((i)/0.28)*0.32 + ((r)/0.28)*0.1 + ((g)/0.28)*0.22 + ((b)/0.28)*0.07)
|
||||
#define NEW_CGA(c, i, r, g, b) (((c) / 0.72) * 0.29 + ((i) / 0.28) * 0.32 + ((r) / 0.28) * 0.1 + ((g) / 0.28) * 0.22 + ((b) / 0.28) * 0.07)
|
||||
|
||||
double mode_brightness;
|
||||
double mode_contrast;
|
||||
@@ -74,272 +76,291 @@ double min_v;
|
||||
double max_v;
|
||||
|
||||
double video_ri, video_rq, video_gi, video_gq, video_bi, video_bq;
|
||||
int video_sharpness;
|
||||
int tandy_mode_control = 0;
|
||||
int video_sharpness;
|
||||
int tandy_mode_control = 0;
|
||||
|
||||
static bool new_cga = 0;
|
||||
|
||||
void update_cga16_color(uint8_t cgamode) {
|
||||
int x;
|
||||
double c, i, v;
|
||||
double q, a, s, r;
|
||||
double iq_adjust_i, iq_adjust_q;
|
||||
double i0, i3, mode_saturation;
|
||||
void
|
||||
update_cga16_color(uint8_t cgamode)
|
||||
{
|
||||
int x;
|
||||
double c, i, v;
|
||||
double q, a, s, r;
|
||||
double iq_adjust_i, iq_adjust_q;
|
||||
double i0, i3, mode_saturation;
|
||||
|
||||
static const double ri = 0.9563;
|
||||
static const double rq = 0.6210;
|
||||
static const double gi = -0.2721;
|
||||
static const double gq = -0.6474;
|
||||
static const double bi = -1.1069;
|
||||
static const double bq = 1.7046;
|
||||
static const double ri = 0.9563;
|
||||
static const double rq = 0.6210;
|
||||
static const double gi = -0.2721;
|
||||
static const double gq = -0.6474;
|
||||
static const double bi = -1.1069;
|
||||
static const double bq = 1.7046;
|
||||
|
||||
if (!new_cga) {
|
||||
min_v = chroma_multiplexer[0] + intensity[0];
|
||||
max_v = chroma_multiplexer[255] + intensity[3];
|
||||
if (!new_cga) {
|
||||
min_v = chroma_multiplexer[0] + intensity[0];
|
||||
max_v = chroma_multiplexer[255] + intensity[3];
|
||||
} else {
|
||||
i0 = intensity[0];
|
||||
i3 = intensity[3];
|
||||
min_v = NEW_CGA(chroma_multiplexer[0], i0, i0, i0, i0);
|
||||
max_v = NEW_CGA(chroma_multiplexer[255], i3, i3, i3, i3);
|
||||
}
|
||||
mode_contrast = 256 / (max_v - min_v);
|
||||
mode_brightness = -min_v * mode_contrast;
|
||||
if ((cgamode & 3) == 1)
|
||||
mode_hue = 14;
|
||||
else
|
||||
mode_hue = 4;
|
||||
|
||||
mode_contrast *= contrast * (new_cga ? 1.2 : 1) / 100; /* new CGA: 120% */
|
||||
mode_brightness += (new_cga ? brightness - 10 : brightness) * 5; /* new CGA: -10 */
|
||||
mode_saturation = (new_cga ? 4.35 : 2.9) * saturation / 100; /* new CGA: 150% */
|
||||
|
||||
for (x = 0; x < 1024; ++x) {
|
||||
int phase = x & 3;
|
||||
int right = (x >> 2) & 15;
|
||||
int left = (x >> 6) & 15;
|
||||
int rc = right;
|
||||
int lc = left;
|
||||
if ((cgamode & 4) != 0) {
|
||||
rc = (right & 8) | ((right & 7) != 0 ? 7 : 0);
|
||||
lc = (left & 8) | ((left & 7) != 0 ? 7 : 0);
|
||||
}
|
||||
c = chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase];
|
||||
i = intensity[(left >> 3) | ((right >> 2) & 2)];
|
||||
if (!new_cga)
|
||||
v = c + i;
|
||||
else {
|
||||
i0 = intensity[0];
|
||||
i3 = intensity[3];
|
||||
min_v = NEW_CGA(chroma_multiplexer[0], i0, i0, i0, i0);
|
||||
max_v = NEW_CGA(chroma_multiplexer[255], i3, i3, i3, i3);
|
||||
double r = intensity[((left >> 2) & 1) | ((right >> 1) & 2)];
|
||||
double g = intensity[((left >> 1) & 1) | (right & 2)];
|
||||
double b = intensity[(left & 1) | ((right << 1) & 2)];
|
||||
v = NEW_CGA(c, i, r, g, b);
|
||||
}
|
||||
mode_contrast = 256/(max_v - min_v);
|
||||
mode_brightness = -min_v*mode_contrast;
|
||||
if ((cgamode & 3) == 1)
|
||||
mode_hue = 14;
|
||||
else
|
||||
mode_hue = 4;
|
||||
CGA_Composite_Table[x] = (int) (v * mode_contrast + mode_brightness);
|
||||
}
|
||||
|
||||
mode_contrast *= contrast * (new_cga ? 1.2 : 1)/100; /* new CGA: 120% */
|
||||
mode_brightness += (new_cga ? brightness-10 : brightness)*5; /* new CGA: -10 */
|
||||
mode_saturation = (new_cga ? 4.35 : 2.9)*saturation/100; /* new CGA: 150% */
|
||||
i = CGA_Composite_Table[6 * 68] - CGA_Composite_Table[6 * 68 + 2];
|
||||
q = CGA_Composite_Table[6 * 68 + 1] - CGA_Composite_Table[6 * 68 + 3];
|
||||
|
||||
for (x = 0; x < 1024; ++x) {
|
||||
int phase = x & 3;
|
||||
int right = (x >> 2) & 15;
|
||||
int left = (x >> 6) & 15;
|
||||
int rc = right;
|
||||
int lc = left;
|
||||
if ((cgamode & 4) != 0) {
|
||||
rc = (right & 8) | ((right & 7) != 0 ? 7 : 0);
|
||||
lc = (left & 8) | ((left & 7) != 0 ? 7 : 0);
|
||||
}
|
||||
c = chroma_multiplexer[((lc & 7) << 5) | ((rc & 7) << 2) | phase];
|
||||
i = intensity[(left >> 3) | ((right >> 2) & 2)];
|
||||
if (!new_cga)
|
||||
v = c + i;
|
||||
else {
|
||||
double r = intensity[((left >> 2) & 1) | ((right >> 1) & 2)];
|
||||
double g = intensity[((left >> 1) & 1) | (right & 2)];
|
||||
double b = intensity[(left & 1) | ((right << 1) & 2)];
|
||||
v = NEW_CGA(c, i, r, g, b);
|
||||
}
|
||||
CGA_Composite_Table[x] = (int) (v*mode_contrast + mode_brightness);
|
||||
}
|
||||
a = tau * (33 + 90 + hue_offset + mode_hue) / 360.0;
|
||||
c = cos(a);
|
||||
s = sin(a);
|
||||
r = 256 * mode_saturation / sqrt(i * i + q * q);
|
||||
|
||||
i = CGA_Composite_Table[6*68] - CGA_Composite_Table[6*68 + 2];
|
||||
q = CGA_Composite_Table[6*68 + 1] - CGA_Composite_Table[6*68 + 3];
|
||||
iq_adjust_i = -(i * c + q * s) * r;
|
||||
iq_adjust_q = (q * c - i * s) * r;
|
||||
|
||||
a = tau*(33 + 90 + hue_offset + mode_hue)/360.0;
|
||||
c = cos(a);
|
||||
s = sin(a);
|
||||
r = 256*mode_saturation/sqrt(i*i+q*q);
|
||||
|
||||
iq_adjust_i = -(i*c + q*s)*r;
|
||||
iq_adjust_q = (q*c - i*s)*r;
|
||||
|
||||
video_ri = (int) (ri*iq_adjust_i + rq*iq_adjust_q);
|
||||
video_rq = (int) (-ri*iq_adjust_q + rq*iq_adjust_i);
|
||||
video_gi = (int) (gi*iq_adjust_i + gq*iq_adjust_q);
|
||||
video_gq = (int) (-gi*iq_adjust_q + gq*iq_adjust_i);
|
||||
video_bi = (int) (bi*iq_adjust_i + bq*iq_adjust_q);
|
||||
video_bq = (int) (-bi*iq_adjust_q + bq*iq_adjust_i);
|
||||
video_sharpness = (int) (sharpness*256/100);
|
||||
video_ri = (int) (ri * iq_adjust_i + rq * iq_adjust_q);
|
||||
video_rq = (int) (-ri * iq_adjust_q + rq * iq_adjust_i);
|
||||
video_gi = (int) (gi * iq_adjust_i + gq * iq_adjust_q);
|
||||
video_gq = (int) (-gi * iq_adjust_q + gq * iq_adjust_i);
|
||||
video_bi = (int) (bi * iq_adjust_i + bq * iq_adjust_q);
|
||||
video_bq = (int) (-bi * iq_adjust_q + bq * iq_adjust_i);
|
||||
video_sharpness = (int) (sharpness * 256 / 100);
|
||||
}
|
||||
|
||||
static Bit8u byte_clamp(int v) {
|
||||
v >>= 13;
|
||||
return v < 0 ? 0 : (v > 255 ? 255 : v);
|
||||
static Bit8u
|
||||
byte_clamp(int v)
|
||||
{
|
||||
v >>= 13;
|
||||
return v < 0 ? 0 : (v > 255 ? 255 : v);
|
||||
}
|
||||
|
||||
/* 2048x1536 is the maximum we can possibly support. */
|
||||
#define SCALER_MAXWIDTH 2048
|
||||
|
||||
static int temp[SCALER_MAXWIDTH + 10]={0};
|
||||
static int atemp[SCALER_MAXWIDTH + 2]={0};
|
||||
static int btemp[SCALER_MAXWIDTH + 2]={0};
|
||||
static int temp[SCALER_MAXWIDTH + 10] = { 0 };
|
||||
static int atemp[SCALER_MAXWIDTH + 2] = { 0 };
|
||||
static int btemp[SCALER_MAXWIDTH + 2] = { 0 };
|
||||
|
||||
Bit32u * Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks/*, bool doublewidth*/, Bit32u *TempLine)
|
||||
Bit32u *
|
||||
Composite_Process(uint8_t cgamode, Bit8u border, Bit32u blocks /*, bool doublewidth*/, Bit32u *TempLine)
|
||||
{
|
||||
int x;
|
||||
Bit32u x2;
|
||||
int x;
|
||||
Bit32u x2;
|
||||
|
||||
int w = blocks*4;
|
||||
int w = blocks * 4;
|
||||
|
||||
int *o;
|
||||
Bit32u *rgbi;
|
||||
int *b;
|
||||
int *i;
|
||||
Bit32u* srgb;
|
||||
int *ap, *bp;
|
||||
int *o;
|
||||
Bit32u *rgbi;
|
||||
int *b;
|
||||
int *i;
|
||||
Bit32u *srgb;
|
||||
int *ap, *bp;
|
||||
|
||||
#define COMPOSITE_CONVERT(I, Q) do { \
|
||||
i[1] = (i[1]<<3) - ap[1]; \
|
||||
a = ap[0]; \
|
||||
b = bp[0]; \
|
||||
c = i[0]+i[0]; \
|
||||
d = i[-1]+i[1]; \
|
||||
y = ((c+d)<<8) + video_sharpness*(c-d); \
|
||||
rr = y + video_ri*(I) + video_rq*(Q); \
|
||||
gg = y + video_gi*(I) + video_gq*(Q); \
|
||||
bb = y + video_bi*(I) + video_bq*(Q); \
|
||||
++i; \
|
||||
++ap; \
|
||||
++bp; \
|
||||
*srgb = (byte_clamp(rr)<<16) | (byte_clamp(gg)<<8) | byte_clamp(bb); \
|
||||
++srgb; \
|
||||
} while (0)
|
||||
#define COMPOSITE_CONVERT(I, Q) \
|
||||
do { \
|
||||
i[1] = (i[1] << 3) - ap[1]; \
|
||||
a = ap[0]; \
|
||||
b = bp[0]; \
|
||||
c = i[0] + i[0]; \
|
||||
d = i[-1] + i[1]; \
|
||||
y = ((c + d) << 8) + video_sharpness * (c - d); \
|
||||
rr = y + video_ri * (I) + video_rq * (Q); \
|
||||
gg = y + video_gi * (I) + video_gq * (Q); \
|
||||
bb = y + video_bi * (I) + video_bq * (Q); \
|
||||
++i; \
|
||||
++ap; \
|
||||
++bp; \
|
||||
*srgb = (byte_clamp(rr) << 16) | (byte_clamp(gg) << 8) | byte_clamp(bb); \
|
||||
++srgb; \
|
||||
} while (0)
|
||||
|
||||
#define OUT(v) do { *o = (v); ++o; } while (0)
|
||||
#define OUT(v) \
|
||||
do { \
|
||||
*o = (v); \
|
||||
++o; \
|
||||
} while (0)
|
||||
|
||||
/* Simulate CGA composite output */
|
||||
o = temp;
|
||||
rgbi = TempLine;
|
||||
b = &CGA_Composite_Table[border*68];
|
||||
for (x = 0; x < 4; ++x)
|
||||
OUT(b[(x+3)&3]);
|
||||
OUT(CGA_Composite_Table[(border<<6) | ((*rgbi & 0x0f)<<2) | 3]);
|
||||
for (x = 0; x < w-1; ++x) {
|
||||
OUT(CGA_Composite_Table[((rgbi[0] & 0x0f)<<6) | ((rgbi[1] & 0x0f)<<2) | (x&3)]);
|
||||
++rgbi;
|
||||
/* Simulate CGA composite output */
|
||||
o = temp;
|
||||
rgbi = TempLine;
|
||||
b = &CGA_Composite_Table[border * 68];
|
||||
for (x = 0; x < 4; ++x)
|
||||
OUT(b[(x + 3) & 3]);
|
||||
OUT(CGA_Composite_Table[(border << 6) | ((*rgbi & 0x0f) << 2) | 3]);
|
||||
for (x = 0; x < w - 1; ++x) {
|
||||
OUT(CGA_Composite_Table[((rgbi[0] & 0x0f) << 6) | ((rgbi[1] & 0x0f) << 2) | (x & 3)]);
|
||||
++rgbi;
|
||||
}
|
||||
OUT(CGA_Composite_Table[((*rgbi & 0x0f) << 6) | (border << 2) | 3]);
|
||||
for (x = 0; x < 5; ++x)
|
||||
OUT(b[x & 3]);
|
||||
|
||||
if ((cgamode & 4) != 0) {
|
||||
/* Decode */
|
||||
i = temp + 5;
|
||||
srgb = (Bit32u *) TempLine;
|
||||
for (x2 = 0; x2 < blocks * 4; ++x2) {
|
||||
int c = (i[0] + i[0]) << 3;
|
||||
int d = (i[-1] + i[1]) << 3;
|
||||
int y = ((c + d) << 8) + video_sharpness * (c - d);
|
||||
++i;
|
||||
*srgb = byte_clamp(y) * 0x10101;
|
||||
++srgb;
|
||||
}
|
||||
OUT(CGA_Composite_Table[((*rgbi & 0x0f)<<6) | (border<<2) | 3]);
|
||||
for (x = 0; x < 5; ++x)
|
||||
OUT(b[x&3]);
|
||||
|
||||
if ((cgamode & 4) != 0) {
|
||||
/* Decode */
|
||||
i = temp + 5;
|
||||
srgb = (Bit32u *)TempLine;
|
||||
for (x2 = 0; x2 < blocks*4; ++x2) {
|
||||
int c = (i[0]+i[0])<<3;
|
||||
int d = (i[-1]+i[1])<<3;
|
||||
int y = ((c+d)<<8) + video_sharpness*(c-d);
|
||||
++i;
|
||||
*srgb = byte_clamp(y)*0x10101;
|
||||
++srgb;
|
||||
}
|
||||
} else {
|
||||
/* Store chroma */
|
||||
i = temp + 4;
|
||||
ap = atemp + 1;
|
||||
bp = btemp + 1;
|
||||
for (x = -1; x < w + 1; ++x) {
|
||||
ap[x] = i[-4] - ((i[-2] - i[0] + i[2]) << 1) + i[4];
|
||||
bp[x] = (i[-3] - i[-1] + i[1] - i[3]) << 1;
|
||||
++i;
|
||||
}
|
||||
else {
|
||||
/* Store chroma */
|
||||
i = temp + 4;
|
||||
ap = atemp + 1;
|
||||
bp = btemp + 1;
|
||||
for (x = -1; x < w + 1; ++x) {
|
||||
ap[x] = i[-4]-((i[-2]-i[0]+i[2])<<1)+i[4];
|
||||
bp[x] = (i[-3]-i[-1]+i[1]-i[3])<<1;
|
||||
++i;
|
||||
}
|
||||
|
||||
/* Decode */
|
||||
i = temp + 5;
|
||||
i[-1] = (i[-1]<<3) - ap[-1];
|
||||
i[0] = (i[0]<<3) - ap[0];
|
||||
srgb = (Bit32u *)TempLine;
|
||||
for (x2 = 0; x2 < blocks; ++x2) {
|
||||
int y,a,b,c,d,rr,gg,bb;
|
||||
COMPOSITE_CONVERT(a, b);
|
||||
COMPOSITE_CONVERT(-b, a);
|
||||
COMPOSITE_CONVERT(-a, -b);
|
||||
COMPOSITE_CONVERT(b, -a);
|
||||
}
|
||||
/* Decode */
|
||||
i = temp + 5;
|
||||
i[-1] = (i[-1] << 3) - ap[-1];
|
||||
i[0] = (i[0] << 3) - ap[0];
|
||||
srgb = (Bit32u *) TempLine;
|
||||
for (x2 = 0; x2 < blocks; ++x2) {
|
||||
int y, a, b, c, d, rr, gg, bb;
|
||||
COMPOSITE_CONVERT(a, b);
|
||||
COMPOSITE_CONVERT(-b, a);
|
||||
COMPOSITE_CONVERT(-a, -b);
|
||||
COMPOSITE_CONVERT(b, -a);
|
||||
}
|
||||
}
|
||||
#undef COMPOSITE_CONVERT
|
||||
#undef OUT
|
||||
|
||||
return TempLine;
|
||||
return TempLine;
|
||||
}
|
||||
|
||||
void IncreaseHue(uint8_t cgamode)
|
||||
void
|
||||
IncreaseHue(uint8_t cgamode)
|
||||
{
|
||||
hue_offset += 5.0;
|
||||
hue_offset += 5.0;
|
||||
|
||||
update_cga16_color(cgamode);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void DecreaseHue(uint8_t cgamode)
|
||||
void
|
||||
DecreaseHue(uint8_t cgamode)
|
||||
{
|
||||
hue_offset -= 5.0;
|
||||
hue_offset -= 5.0;
|
||||
|
||||
update_cga16_color(cgamode);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void IncreaseSaturation(uint8_t cgamode)
|
||||
void
|
||||
IncreaseSaturation(uint8_t cgamode)
|
||||
{
|
||||
saturation += 5;
|
||||
saturation += 5;
|
||||
|
||||
update_cga16_color(cgamode);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void DecreaseSaturation(uint8_t cgamode)
|
||||
void
|
||||
DecreaseSaturation(uint8_t cgamode)
|
||||
{
|
||||
saturation -= 5;
|
||||
saturation -= 5;
|
||||
|
||||
update_cga16_color(cgamode);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void IncreaseContrast(uint8_t cgamode)
|
||||
void
|
||||
IncreaseContrast(uint8_t cgamode)
|
||||
{
|
||||
contrast += 5;
|
||||
contrast += 5;
|
||||
|
||||
update_cga16_color(cgamode);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void DecreaseContrast(uint8_t cgamode)
|
||||
void
|
||||
DecreaseContrast(uint8_t cgamode)
|
||||
{
|
||||
contrast -= 5;
|
||||
contrast -= 5;
|
||||
|
||||
update_cga16_color(cgamode);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void IncreaseBrightness(uint8_t cgamode)
|
||||
void
|
||||
IncreaseBrightness(uint8_t cgamode)
|
||||
{
|
||||
brightness += 5;
|
||||
brightness += 5;
|
||||
|
||||
update_cga16_color(cgamode);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void DecreaseBrightness(uint8_t cgamode)
|
||||
void
|
||||
DecreaseBrightness(uint8_t cgamode)
|
||||
{
|
||||
brightness -= 5;
|
||||
brightness -= 5;
|
||||
|
||||
update_cga16_color(cgamode);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void IncreaseSharpness(uint8_t cgamode)
|
||||
void
|
||||
IncreaseSharpness(uint8_t cgamode)
|
||||
{
|
||||
sharpness += 10;
|
||||
sharpness += 10;
|
||||
|
||||
update_cga16_color(cgamode);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void DecreaseSharpness(uint8_t cgamode)
|
||||
void
|
||||
DecreaseSharpness(uint8_t cgamode)
|
||||
{
|
||||
sharpness -= 10;
|
||||
sharpness -= 10;
|
||||
|
||||
update_cga16_color(cgamode);
|
||||
update_cga16_color(cgamode);
|
||||
}
|
||||
|
||||
void cga_comp_init(int revision)
|
||||
void
|
||||
cga_comp_init(int revision)
|
||||
{
|
||||
new_cga = revision;
|
||||
new_cga = revision;
|
||||
|
||||
/* Making sure this gets reset after reset. */
|
||||
brightness = 0;
|
||||
contrast = 100;
|
||||
saturation = 100;
|
||||
sharpness = 0;
|
||||
hue_offset = 0;
|
||||
/* Making sure this gets reset after reset. */
|
||||
brightness = 0;
|
||||
contrast = 100;
|
||||
saturation = 100;
|
||||
sharpness = 0;
|
||||
hue_offset = 0;
|
||||
|
||||
update_cga16_color(0);
|
||||
update_cga16_color(0);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -35,400 +35,350 @@
|
||||
#include <86box/vid_colorplus.h>
|
||||
#include <86box/vid_cga_comp.h>
|
||||
|
||||
|
||||
/* Bits in the colorplus control register: */
|
||||
#define COLORPLUS_PLANE_SWAP 0x40 /* Swap planes at 0000h and 4000h */
|
||||
#define COLORPLUS_640x200_MODE 0x20 /* 640x200x4 mode active */
|
||||
#define COLORPLUS_320x200_MODE 0x10 /* 320x200x16 mode active */
|
||||
#define COLORPLUS_EITHER_MODE 0x30 /* Either mode active */
|
||||
#define COLORPLUS_PLANE_SWAP 0x40 /* Swap planes at 0000h and 4000h */
|
||||
#define COLORPLUS_640x200_MODE 0x20 /* 640x200x4 mode active */
|
||||
#define COLORPLUS_320x200_MODE 0x10 /* 320x200x16 mode active */
|
||||
#define COLORPLUS_EITHER_MODE 0x30 /* Either mode active */
|
||||
|
||||
/* Bits in the CGA graphics mode register */
|
||||
#define CGA_GRAPHICS_MODE 0x02 /* CGA graphics mode selected? */
|
||||
#define CGA_GRAPHICS_MODE 0x02 /* CGA graphics mode selected? */
|
||||
|
||||
#define CGA_RGB 0
|
||||
#define CGA_COMPOSITE 1
|
||||
#define CGA_RGB 0
|
||||
#define CGA_COMPOSITE 1
|
||||
|
||||
#define COMPOSITE_OLD 0
|
||||
#define COMPOSITE_NEW 1
|
||||
|
||||
|
||||
video_timings_t timing_colorplus = {VIDEO_ISA, 8, 16, 32, 8, 16, 32};
|
||||
#define COMPOSITE_OLD 0
|
||||
#define COMPOSITE_NEW 1
|
||||
|
||||
video_timings_t timing_colorplus = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
|
||||
|
||||
void cga_recalctimings(cga_t *cga);
|
||||
|
||||
void colorplus_out(uint16_t addr, uint8_t val, void *p)
|
||||
void
|
||||
colorplus_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
colorplus_t *colorplus = (colorplus_t *)p;
|
||||
colorplus_t *colorplus = (colorplus_t *) p;
|
||||
|
||||
if (addr == 0x3DD)
|
||||
{
|
||||
colorplus->control = val & 0x70;
|
||||
}
|
||||
else
|
||||
{
|
||||
cga_out(addr, val, &colorplus->cga);
|
||||
}
|
||||
if (addr == 0x3DD) {
|
||||
colorplus->control = val & 0x70;
|
||||
} else {
|
||||
cga_out(addr, val, &colorplus->cga);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t colorplus_in(uint16_t addr, void *p)
|
||||
uint8_t
|
||||
colorplus_in(uint16_t addr, void *p)
|
||||
{
|
||||
colorplus_t *colorplus = (colorplus_t *)p;
|
||||
colorplus_t *colorplus = (colorplus_t *) p;
|
||||
|
||||
return cga_in(addr, &colorplus->cga);
|
||||
return cga_in(addr, &colorplus->cga);
|
||||
}
|
||||
|
||||
void colorplus_write(uint32_t addr, uint8_t val, void *p)
|
||||
void
|
||||
colorplus_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
colorplus_t *colorplus = (colorplus_t *)p;
|
||||
colorplus_t *colorplus = (colorplus_t *) p;
|
||||
|
||||
if ((colorplus->control & COLORPLUS_PLANE_SWAP) &&
|
||||
(colorplus->control & COLORPLUS_EITHER_MODE) &&
|
||||
(colorplus->cga.cgamode & CGA_GRAPHICS_MODE))
|
||||
{
|
||||
addr ^= 0x4000;
|
||||
}
|
||||
else if (!(colorplus->control & COLORPLUS_EITHER_MODE))
|
||||
{
|
||||
addr &= 0x3FFF;
|
||||
}
|
||||
colorplus->cga.vram[addr & 0x7fff] = val;
|
||||
if (colorplus->cga.snow_enabled)
|
||||
if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) {
|
||||
addr ^= 0x4000;
|
||||
} else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) {
|
||||
addr &= 0x3FFF;
|
||||
}
|
||||
colorplus->cga.vram[addr & 0x7fff] = val;
|
||||
if (colorplus->cga.snow_enabled) {
|
||||
int offset = ((timer_get_remaining_u64(&colorplus->cga.timer) / CGACONST) * 2) & 0xfc;
|
||||
colorplus->cga.charbuffer[offset] = colorplus->cga.vram[addr & 0x7fff];
|
||||
colorplus->cga.charbuffer[offset | 1] = colorplus->cga.vram[addr & 0x7fff];
|
||||
}
|
||||
cycles -= 4;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
colorplus_read(uint32_t addr, void *p)
|
||||
{
|
||||
colorplus_t *colorplus = (colorplus_t *) p;
|
||||
|
||||
if ((colorplus->control & COLORPLUS_PLANE_SWAP) && (colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE)) {
|
||||
addr ^= 0x4000;
|
||||
} else if (!(colorplus->control & COLORPLUS_EITHER_MODE)) {
|
||||
addr &= 0x3FFF;
|
||||
}
|
||||
cycles -= 4;
|
||||
if (colorplus->cga.snow_enabled) {
|
||||
int offset = ((timer_get_remaining_u64(&colorplus->cga.timer) / CGACONST) * 2) & 0xfc;
|
||||
colorplus->cga.charbuffer[offset] = colorplus->cga.vram[addr & 0x7fff];
|
||||
colorplus->cga.charbuffer[offset | 1] = colorplus->cga.vram[addr & 0x7fff];
|
||||
}
|
||||
return colorplus->cga.vram[addr & 0x7fff];
|
||||
}
|
||||
|
||||
void
|
||||
colorplus_recalctimings(colorplus_t *colorplus)
|
||||
{
|
||||
cga_recalctimings(&colorplus->cga);
|
||||
}
|
||||
|
||||
void
|
||||
colorplus_poll(void *p)
|
||||
{
|
||||
colorplus_t *colorplus = (colorplus_t *) p;
|
||||
int x, c;
|
||||
int oldvc;
|
||||
uint16_t dat0, dat1;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
static const int cols16[16] = { 0x10, 0x12, 0x14, 0x16,
|
||||
0x18, 0x1A, 0x1C, 0x1E,
|
||||
0x11, 0x13, 0x15, 0x17,
|
||||
0x19, 0x1B, 0x1D, 0x1F };
|
||||
uint8_t *plane0 = colorplus->cga.vram;
|
||||
uint8_t *plane1 = colorplus->cga.vram + 0x4000;
|
||||
|
||||
/* If one of the extra modes is not selected, drop down to the CGA
|
||||
* drawing code. */
|
||||
if (!((colorplus->control & COLORPLUS_EITHER_MODE) && (colorplus->cga.cgamode & CGA_GRAPHICS_MODE))) {
|
||||
cga_poll(&colorplus->cga);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!colorplus->cga.linepos) {
|
||||
timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispofftime);
|
||||
colorplus->cga.cgastat |= 1;
|
||||
colorplus->cga.linepos = 1;
|
||||
oldsc = colorplus->cga.sc;
|
||||
if ((colorplus->cga.crtc[8] & 3) == 3)
|
||||
colorplus->cga.sc = ((colorplus->cga.sc << 1) + colorplus->cga.oddeven) & 7;
|
||||
if (colorplus->cga.cgadispon) {
|
||||
if (colorplus->cga.displine < colorplus->cga.firstline) {
|
||||
colorplus->cga.firstline = colorplus->cga.displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
colorplus->cga.lastline = colorplus->cga.displine;
|
||||
/* Left / right border */
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[colorplus->cga.displine][c] = buffer32->line[colorplus->cga.displine][c + (colorplus->cga.crtc[1] << 4) + 8] = (colorplus->cga.cgacol & 15) + 16;
|
||||
}
|
||||
if (colorplus->control & COLORPLUS_320x200_MODE) {
|
||||
for (x = 0; x < colorplus->cga.crtc[1]; x++) {
|
||||
dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1];
|
||||
dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1];
|
||||
colorplus->cga.ma++;
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[colorplus->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[colorplus->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols16[(dat0 >> 14) | ((dat1 >> 14) << 2)];
|
||||
dat0 <<= 2;
|
||||
dat1 <<= 2;
|
||||
}
|
||||
}
|
||||
} else if (colorplus->control & COLORPLUS_640x200_MODE) {
|
||||
cols[0] = (colorplus->cga.cgacol & 15) | 16;
|
||||
col = (colorplus->cga.cgacol & 16) ? 24 : 16;
|
||||
if (colorplus->cga.cgamode & 4) {
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 7;
|
||||
} else if (colorplus->cga.cgacol & 32) {
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 5;
|
||||
cols[3] = col | 7;
|
||||
} else {
|
||||
cols[1] = col | 2;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 6;
|
||||
}
|
||||
for (x = 0; x < colorplus->cga.crtc[1]; x++) {
|
||||
dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1];
|
||||
dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) | plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1];
|
||||
colorplus->cga.ma++;
|
||||
for (c = 0; c < 16; c++) {
|
||||
buffer32->line[colorplus->cga.displine][(x << 4) + c + 8] = cols[(dat0 >> 15) | ((dat1 >> 15) << 1)];
|
||||
dat0 <<= 1;
|
||||
dat1 <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else /* Top / bottom border */
|
||||
{
|
||||
int offset = ((timer_get_remaining_u64(&colorplus->cga.timer) / CGACONST) * 2) & 0xfc;
|
||||
colorplus->cga.charbuffer[offset] = colorplus->cga.vram[addr & 0x7fff];
|
||||
colorplus->cga.charbuffer[offset | 1] = colorplus->cga.vram[addr & 0x7fff];
|
||||
cols[0] = (colorplus->cga.cgacol & 15) + 16;
|
||||
hline(buffer32, 0, colorplus->cga.displine, (colorplus->cga.crtc[1] << 4) + 16, cols[0]);
|
||||
}
|
||||
cycles -= 4;
|
||||
}
|
||||
|
||||
uint8_t colorplus_read(uint32_t addr, void *p)
|
||||
{
|
||||
colorplus_t *colorplus = (colorplus_t *)p;
|
||||
x = (colorplus->cga.crtc[1] << 4) + 16;
|
||||
|
||||
if ((colorplus->control & COLORPLUS_PLANE_SWAP) &&
|
||||
(colorplus->control & COLORPLUS_EITHER_MODE) &&
|
||||
(colorplus->cga.cgamode & CGA_GRAPHICS_MODE))
|
||||
{
|
||||
addr ^= 0x4000;
|
||||
}
|
||||
else if (!(colorplus->control & COLORPLUS_EITHER_MODE))
|
||||
{
|
||||
addr &= 0x3FFF;
|
||||
}
|
||||
cycles -= 4;
|
||||
if (colorplus->cga.snow_enabled)
|
||||
{
|
||||
int offset = ((timer_get_remaining_u64(&colorplus->cga.timer) / CGACONST) * 2) & 0xfc;
|
||||
colorplus->cga.charbuffer[offset] = colorplus->cga.vram[addr & 0x7fff];
|
||||
colorplus->cga.charbuffer[offset | 1] = colorplus->cga.vram[addr & 0x7fff];
|
||||
if (colorplus->cga.composite)
|
||||
Composite_Process(colorplus->cga.cgamode, 0, x >> 2, buffer32->line[colorplus->cga.displine]);
|
||||
|
||||
colorplus->cga.sc = oldsc;
|
||||
if (colorplus->cga.vc == colorplus->cga.crtc[7] && !colorplus->cga.sc)
|
||||
colorplus->cga.cgastat |= 8;
|
||||
colorplus->cga.displine++;
|
||||
if (colorplus->cga.displine >= 360)
|
||||
colorplus->cga.displine = 0;
|
||||
} else {
|
||||
timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispontime);
|
||||
colorplus->cga.linepos = 0;
|
||||
if (colorplus->cga.vsynctime) {
|
||||
colorplus->cga.vsynctime--;
|
||||
if (!colorplus->cga.vsynctime)
|
||||
colorplus->cga.cgastat &= ~8;
|
||||
}
|
||||
return colorplus->cga.vram[addr & 0x7fff];
|
||||
}
|
||||
|
||||
void colorplus_recalctimings(colorplus_t *colorplus)
|
||||
{
|
||||
cga_recalctimings(&colorplus->cga);
|
||||
}
|
||||
|
||||
void colorplus_poll(void *p)
|
||||
{
|
||||
colorplus_t *colorplus = (colorplus_t *)p;
|
||||
int x, c;
|
||||
int oldvc;
|
||||
uint16_t dat0, dat1;
|
||||
int cols[4];
|
||||
int col;
|
||||
int oldsc;
|
||||
static const int cols16[16] = { 0x10,0x12,0x14,0x16,
|
||||
0x18,0x1A,0x1C,0x1E,
|
||||
0x11,0x13,0x15,0x17,
|
||||
0x19,0x1B,0x1D,0x1F };
|
||||
uint8_t *plane0 = colorplus->cga.vram;
|
||||
uint8_t *plane1 = colorplus->cga.vram + 0x4000;
|
||||
|
||||
/* If one of the extra modes is not selected, drop down to the CGA
|
||||
* drawing code. */
|
||||
if (!((colorplus->control & COLORPLUS_EITHER_MODE) &&
|
||||
(colorplus->cga.cgamode & CGA_GRAPHICS_MODE)))
|
||||
{
|
||||
cga_poll(&colorplus->cga);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!colorplus->cga.linepos)
|
||||
{
|
||||
timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispofftime);
|
||||
colorplus->cga.cgastat |= 1;
|
||||
colorplus->cga.linepos = 1;
|
||||
oldsc = colorplus->cga.sc;
|
||||
if ((colorplus->cga.crtc[8] & 3) == 3)
|
||||
colorplus->cga.sc = ((colorplus->cga.sc << 1) + colorplus->cga.oddeven) & 7;
|
||||
if (colorplus->cga.cgadispon)
|
||||
{
|
||||
if (colorplus->cga.displine < colorplus->cga.firstline)
|
||||
{
|
||||
colorplus->cga.firstline = colorplus->cga.displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
colorplus->cga.lastline = colorplus->cga.displine;
|
||||
/* Left / right border */
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
buffer32->line[colorplus->cga.displine][c] =
|
||||
buffer32->line[colorplus->cga.displine][c + (colorplus->cga.crtc[1] << 4) + 8] =
|
||||
(colorplus->cga.cgacol & 15) + 16;
|
||||
}
|
||||
if (colorplus->control & COLORPLUS_320x200_MODE)
|
||||
{
|
||||
for (x = 0; x < colorplus->cga.crtc[1]; x++)
|
||||
{
|
||||
dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) |
|
||||
plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1];
|
||||
dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) |
|
||||
plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1];
|
||||
colorplus->cga.ma++;
|
||||
for (c = 0; c < 8; c++)
|
||||
{
|
||||
buffer32->line[colorplus->cga.displine][(x << 4) + (c << 1) + 8] =
|
||||
buffer32->line[colorplus->cga.displine][(x << 4) + (c << 1) + 1 + 8] =
|
||||
cols16[(dat0 >> 14) | ((dat1 >> 14) << 2)];
|
||||
dat0 <<= 2;
|
||||
dat1 <<= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (colorplus->control & COLORPLUS_640x200_MODE)
|
||||
{
|
||||
cols[0] = (colorplus->cga.cgacol & 15) | 16;
|
||||
col = (colorplus->cga.cgacol & 16) ? 24 : 16;
|
||||
if (colorplus->cga.cgamode & 4)
|
||||
{
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 7;
|
||||
}
|
||||
else if (colorplus->cga.cgacol & 32)
|
||||
{
|
||||
cols[1] = col | 3;
|
||||
cols[2] = col | 5;
|
||||
cols[3] = col | 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
cols[1] = col | 2;
|
||||
cols[2] = col | 4;
|
||||
cols[3] = col | 6;
|
||||
}
|
||||
for (x = 0; x < colorplus->cga.crtc[1]; x++)
|
||||
{
|
||||
dat0 = (plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) |
|
||||
plane0[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1];
|
||||
dat1 = (plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000)] << 8) |
|
||||
plane1[((colorplus->cga.ma << 1) & 0x1fff) + ((colorplus->cga.sc & 1) * 0x2000) + 1];
|
||||
colorplus->cga.ma++;
|
||||
for (c = 0; c < 16; c++)
|
||||
{
|
||||
buffer32->line[colorplus->cga.displine][(x << 4) + c + 8] =
|
||||
cols[(dat0 >> 15) | ((dat1 >> 15) << 1)];
|
||||
dat0 <<= 1;
|
||||
dat1 <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* Top / bottom border */
|
||||
{
|
||||
cols[0] = (colorplus->cga.cgacol & 15) + 16;
|
||||
hline(buffer32, 0, colorplus->cga.displine, (colorplus->cga.crtc[1] << 4) + 16, cols[0]);
|
||||
}
|
||||
|
||||
x = (colorplus->cga.crtc[1] << 4) + 16;
|
||||
|
||||
if (colorplus->cga.composite)
|
||||
Composite_Process(colorplus->cga.cgamode, 0, x >> 2, buffer32->line[colorplus->cga.displine]);
|
||||
|
||||
colorplus->cga.sc = oldsc;
|
||||
if (colorplus->cga.vc == colorplus->cga.crtc[7] && !colorplus->cga.sc)
|
||||
colorplus->cga.cgastat |= 8;
|
||||
colorplus->cga.displine++;
|
||||
if (colorplus->cga.displine >= 360)
|
||||
colorplus->cga.displine = 0;
|
||||
if (colorplus->cga.sc == (colorplus->cga.crtc[11] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[11] & 31) >> 1))) {
|
||||
colorplus->cga.con = 0;
|
||||
colorplus->cga.coff = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
timer_advance_u64(&colorplus->cga.timer, colorplus->cga.dispontime);
|
||||
colorplus->cga.linepos = 0;
|
||||
if (colorplus->cga.vsynctime)
|
||||
{
|
||||
colorplus->cga.vsynctime--;
|
||||
if (!colorplus->cga.vsynctime)
|
||||
colorplus->cga.cgastat &= ~8;
|
||||
}
|
||||
if (colorplus->cga.sc == (colorplus->cga.crtc[11] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[11] & 31) >> 1)))
|
||||
{
|
||||
colorplus->cga.con = 0;
|
||||
colorplus->cga.coff = 1;
|
||||
}
|
||||
if ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == (colorplus->cga.crtc[9] >> 1))
|
||||
colorplus->cga.maback = colorplus->cga.ma;
|
||||
if (colorplus->cga.vadj)
|
||||
{
|
||||
colorplus->cga.sc++;
|
||||
colorplus->cga.sc &= 31;
|
||||
colorplus->cga.ma = colorplus->cga.maback;
|
||||
colorplus->cga.vadj--;
|
||||
if (!colorplus->cga.vadj)
|
||||
{
|
||||
colorplus->cga.cgadispon = 1;
|
||||
colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff;
|
||||
colorplus->cga.sc = 0;
|
||||
}
|
||||
}
|
||||
else if (colorplus->cga.sc == colorplus->cga.crtc[9])
|
||||
{
|
||||
colorplus->cga.maback = colorplus->cga.ma;
|
||||
colorplus->cga.sc = 0;
|
||||
oldvc = colorplus->cga.vc;
|
||||
colorplus->cga.vc++;
|
||||
colorplus->cga.vc &= 127;
|
||||
if ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == (colorplus->cga.crtc[9] >> 1))
|
||||
colorplus->cga.maback = colorplus->cga.ma;
|
||||
if (colorplus->cga.vadj) {
|
||||
colorplus->cga.sc++;
|
||||
colorplus->cga.sc &= 31;
|
||||
colorplus->cga.ma = colorplus->cga.maback;
|
||||
colorplus->cga.vadj--;
|
||||
if (!colorplus->cga.vadj) {
|
||||
colorplus->cga.cgadispon = 1;
|
||||
colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff;
|
||||
colorplus->cga.sc = 0;
|
||||
}
|
||||
} else if (colorplus->cga.sc == colorplus->cga.crtc[9]) {
|
||||
colorplus->cga.maback = colorplus->cga.ma;
|
||||
colorplus->cga.sc = 0;
|
||||
oldvc = colorplus->cga.vc;
|
||||
colorplus->cga.vc++;
|
||||
colorplus->cga.vc &= 127;
|
||||
|
||||
if (colorplus->cga.vc == colorplus->cga.crtc[6])
|
||||
colorplus->cga.cgadispon = 0;
|
||||
if (colorplus->cga.vc == colorplus->cga.crtc[6])
|
||||
colorplus->cga.cgadispon = 0;
|
||||
|
||||
if (oldvc == colorplus->cga.crtc[4])
|
||||
{
|
||||
colorplus->cga.vc = 0;
|
||||
colorplus->cga.vadj = colorplus->cga.crtc[5];
|
||||
if (!colorplus->cga.vadj) colorplus->cga.cgadispon = 1;
|
||||
if (!colorplus->cga.vadj) colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff;
|
||||
if ((colorplus->cga.crtc[10] & 0x60) == 0x20) colorplus->cga.cursoron = 0;
|
||||
else colorplus->cga.cursoron = colorplus->cga.cgablink & 8;
|
||||
}
|
||||
|
||||
if (colorplus->cga.vc == colorplus->cga.crtc[7])
|
||||
{
|
||||
colorplus->cga.cgadispon = 0;
|
||||
colorplus->cga.displine = 0;
|
||||
colorplus->cga.vsynctime = 16;
|
||||
if (colorplus->cga.crtc[7])
|
||||
{
|
||||
if (colorplus->cga.cgamode & 1) x = (colorplus->cga.crtc[1] << 3) + 16;
|
||||
else x = (colorplus->cga.crtc[1] << 4) + 16;
|
||||
colorplus->cga.lastline++;
|
||||
if (x != xsize || (colorplus->cga.lastline - colorplus->cga.firstline) != ysize)
|
||||
{
|
||||
xsize = x;
|
||||
ysize = colorplus->cga.lastline - colorplus->cga.firstline;
|
||||
if (xsize < 64) xsize = 656;
|
||||
if (ysize < 32) ysize = 200;
|
||||
set_screen_size(xsize, (ysize << 1) + 16);
|
||||
}
|
||||
|
||||
if (colorplus->cga.composite)
|
||||
video_blit_memtoscreen(0, colorplus->cga.firstline - 4, xsize, (colorplus->cga.lastline - colorplus->cga.firstline) + 8);
|
||||
else
|
||||
video_blit_memtoscreen_8(0, colorplus->cga.firstline - 4, xsize, (colorplus->cga.lastline - colorplus->cga.firstline) + 8);
|
||||
frames++;
|
||||
|
||||
video_res_x = xsize - 16;
|
||||
video_res_y = ysize;
|
||||
if (colorplus->cga.cgamode & 1)
|
||||
{
|
||||
video_res_x /= 8;
|
||||
video_res_y /= colorplus->cga.crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
}
|
||||
else if (!(colorplus->cga.cgamode & 2))
|
||||
{
|
||||
video_res_x /= 16;
|
||||
video_res_y /= colorplus->cga.crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
}
|
||||
else if (!(colorplus->cga.cgamode & 16))
|
||||
{
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
video_bpp = 1;
|
||||
}
|
||||
}
|
||||
colorplus->cga.firstline = 1000;
|
||||
colorplus->cga.lastline = 0;
|
||||
colorplus->cga.cgablink++;
|
||||
colorplus->cga.oddeven ^= 1;
|
||||
}
|
||||
}
|
||||
if (oldvc == colorplus->cga.crtc[4]) {
|
||||
colorplus->cga.vc = 0;
|
||||
colorplus->cga.vadj = colorplus->cga.crtc[5];
|
||||
if (!colorplus->cga.vadj)
|
||||
colorplus->cga.cgadispon = 1;
|
||||
if (!colorplus->cga.vadj)
|
||||
colorplus->cga.ma = colorplus->cga.maback = (colorplus->cga.crtc[13] | (colorplus->cga.crtc[12] << 8)) & 0x3fff;
|
||||
if ((colorplus->cga.crtc[10] & 0x60) == 0x20)
|
||||
colorplus->cga.cursoron = 0;
|
||||
else
|
||||
{
|
||||
colorplus->cga.sc++;
|
||||
colorplus->cga.sc &= 31;
|
||||
colorplus->cga.ma = colorplus->cga.maback;
|
||||
}
|
||||
if (colorplus->cga.cgadispon)
|
||||
colorplus->cga.cgastat &= ~1;
|
||||
if ((colorplus->cga.sc == (colorplus->cga.crtc[10] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[10] & 31) >> 1))))
|
||||
colorplus->cga.con = 1;
|
||||
if (colorplus->cga.cgadispon && (colorplus->cga.cgamode & 1))
|
||||
{
|
||||
for (x = 0; x < (colorplus->cga.crtc[1] << 1); x++)
|
||||
colorplus->cga.charbuffer[x] = colorplus->cga.vram[(((colorplus->cga.ma << 1) + x) & 0x3fff)];
|
||||
colorplus->cga.cursoron = colorplus->cga.cgablink & 8;
|
||||
}
|
||||
|
||||
if (colorplus->cga.vc == colorplus->cga.crtc[7]) {
|
||||
colorplus->cga.cgadispon = 0;
|
||||
colorplus->cga.displine = 0;
|
||||
colorplus->cga.vsynctime = 16;
|
||||
if (colorplus->cga.crtc[7]) {
|
||||
if (colorplus->cga.cgamode & 1)
|
||||
x = (colorplus->cga.crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (colorplus->cga.crtc[1] << 4) + 16;
|
||||
colorplus->cga.lastline++;
|
||||
if (x != xsize || (colorplus->cga.lastline - colorplus->cga.firstline) != ysize) {
|
||||
xsize = x;
|
||||
ysize = colorplus->cga.lastline - colorplus->cga.firstline;
|
||||
if (xsize < 64)
|
||||
xsize = 656;
|
||||
if (ysize < 32)
|
||||
ysize = 200;
|
||||
set_screen_size(xsize, (ysize << 1) + 16);
|
||||
}
|
||||
|
||||
if (colorplus->cga.composite)
|
||||
video_blit_memtoscreen(0, colorplus->cga.firstline - 4, xsize, (colorplus->cga.lastline - colorplus->cga.firstline) + 8);
|
||||
else
|
||||
video_blit_memtoscreen_8(0, colorplus->cga.firstline - 4, xsize, (colorplus->cga.lastline - colorplus->cga.firstline) + 8);
|
||||
frames++;
|
||||
|
||||
video_res_x = xsize - 16;
|
||||
video_res_y = ysize;
|
||||
if (colorplus->cga.cgamode & 1) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= colorplus->cga.crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(colorplus->cga.cgamode & 2)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= colorplus->cga.crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(colorplus->cga.cgamode & 16)) {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
} else {
|
||||
video_bpp = 1;
|
||||
}
|
||||
}
|
||||
colorplus->cga.firstline = 1000;
|
||||
colorplus->cga.lastline = 0;
|
||||
colorplus->cga.cgablink++;
|
||||
colorplus->cga.oddeven ^= 1;
|
||||
}
|
||||
} else {
|
||||
colorplus->cga.sc++;
|
||||
colorplus->cga.sc &= 31;
|
||||
colorplus->cga.ma = colorplus->cga.maback;
|
||||
}
|
||||
if (colorplus->cga.cgadispon)
|
||||
colorplus->cga.cgastat &= ~1;
|
||||
if ((colorplus->cga.sc == (colorplus->cga.crtc[10] & 31) || ((colorplus->cga.crtc[8] & 3) == 3 && colorplus->cga.sc == ((colorplus->cga.crtc[10] & 31) >> 1))))
|
||||
colorplus->cga.con = 1;
|
||||
if (colorplus->cga.cgadispon && (colorplus->cga.cgamode & 1)) {
|
||||
for (x = 0; x < (colorplus->cga.crtc[1] << 1); x++)
|
||||
colorplus->cga.charbuffer[x] = colorplus->cga.vram[(((colorplus->cga.ma << 1) + x) & 0x3fff)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void colorplus_init(colorplus_t *colorplus)
|
||||
void
|
||||
colorplus_init(colorplus_t *colorplus)
|
||||
{
|
||||
cga_init(&colorplus->cga);
|
||||
cga_init(&colorplus->cga);
|
||||
}
|
||||
|
||||
void *colorplus_standalone_init(const device_t *info)
|
||||
void *
|
||||
colorplus_standalone_init(const device_t *info)
|
||||
{
|
||||
int display_type;
|
||||
int display_type;
|
||||
|
||||
colorplus_t *colorplus = malloc(sizeof(colorplus_t));
|
||||
memset(colorplus, 0, sizeof(colorplus_t));
|
||||
colorplus_t *colorplus = malloc(sizeof(colorplus_t));
|
||||
memset(colorplus, 0, sizeof(colorplus_t));
|
||||
|
||||
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_colorplus);
|
||||
video_inform(VIDEO_FLAG_TYPE_CGA, &timing_colorplus);
|
||||
|
||||
/* Copied from the CGA init. Ideally this would be done by
|
||||
* calling a helper function rather than duplicating code */
|
||||
display_type = device_get_config_int("display_type");
|
||||
colorplus->cga.composite = (display_type != CGA_RGB);
|
||||
colorplus->cga.revision = device_get_config_int("composite_type");
|
||||
colorplus->cga.snow_enabled = device_get_config_int("snow_enabled");
|
||||
/* Copied from the CGA init. Ideally this would be done by
|
||||
* calling a helper function rather than duplicating code */
|
||||
display_type = device_get_config_int("display_type");
|
||||
colorplus->cga.composite = (display_type != CGA_RGB);
|
||||
colorplus->cga.revision = device_get_config_int("composite_type");
|
||||
colorplus->cga.snow_enabled = device_get_config_int("snow_enabled");
|
||||
|
||||
colorplus->cga.vram = malloc(0x8000);
|
||||
colorplus->cga.vram = malloc(0x8000);
|
||||
|
||||
cga_comp_init(colorplus->cga.revision);
|
||||
timer_add(&colorplus->cga.timer, colorplus_poll, colorplus, 1);
|
||||
mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, colorplus);
|
||||
io_sethandler(0x03d0, 0x0010, colorplus_in, NULL, NULL, colorplus_out, NULL, NULL, colorplus);
|
||||
cga_comp_init(colorplus->cga.revision);
|
||||
timer_add(&colorplus->cga.timer, colorplus_poll, colorplus, 1);
|
||||
mem_mapping_add(&colorplus->cga.mapping, 0xb8000, 0x08000, colorplus_read, NULL, NULL, colorplus_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, colorplus);
|
||||
io_sethandler(0x03d0, 0x0010, colorplus_in, NULL, NULL, colorplus_out, NULL, NULL, colorplus);
|
||||
|
||||
lpt3_init(0x3BC);
|
||||
lpt3_init(0x3BC);
|
||||
|
||||
return colorplus;
|
||||
return colorplus;
|
||||
}
|
||||
|
||||
void colorplus_close(void *p)
|
||||
void
|
||||
colorplus_close(void *p)
|
||||
{
|
||||
colorplus_t *colorplus = (colorplus_t *)p;
|
||||
colorplus_t *colorplus = (colorplus_t *) p;
|
||||
|
||||
free(colorplus->cga.vram);
|
||||
free(colorplus);
|
||||
free(colorplus->cga.vram);
|
||||
free(colorplus);
|
||||
}
|
||||
|
||||
void colorplus_speed_changed(void *p)
|
||||
void
|
||||
colorplus_speed_changed(void *p)
|
||||
{
|
||||
colorplus_t *colorplus = (colorplus_t *)p;
|
||||
colorplus_t *colorplus = (colorplus_t *) p;
|
||||
|
||||
cga_recalctimings(&colorplus->cga);
|
||||
cga_recalctimings(&colorplus->cga);
|
||||
}
|
||||
|
||||
static const device_config_t colorplus_config[] = {
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
{
|
||||
.name = "display_type",
|
||||
.description = "Display type",
|
||||
@@ -479,17 +429,16 @@ static const device_config_t colorplus_config[] = {
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
const device_t colorplus_device =
|
||||
{
|
||||
.name = "Colorplus",
|
||||
const device_t colorplus_device = {
|
||||
.name = "Colorplus",
|
||||
.internal_name = "plantronics",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = colorplus_standalone_init,
|
||||
.close = colorplus_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = colorplus_standalone_init,
|
||||
.close = colorplus_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = colorplus_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = colorplus_config
|
||||
.force_redraw = NULL,
|
||||
.config = colorplus_config
|
||||
};
|
||||
|
||||
@@ -36,378 +36,375 @@
|
||||
#include <86box/vid_cga.h>
|
||||
#include <86box/vid_cga_comp.h>
|
||||
|
||||
|
||||
#define CGA_RGB 0
|
||||
#define CGA_RGB 0
|
||||
#define CGA_COMPOSITE 1
|
||||
|
||||
static uint32_t vflags;
|
||||
static uint8_t mdaattr[256][2][2];
|
||||
|
||||
static uint32_t vflags;
|
||||
static uint8_t mdaattr[256][2][2];
|
||||
|
||||
|
||||
typedef struct compaq_cga_t
|
||||
{
|
||||
typedef struct compaq_cga_t {
|
||||
cga_t cga;
|
||||
} compaq_cga_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_COMPAQ_CGA_LOG
|
||||
int compaq_cga_do_log = ENABLE_COMPAQ_CGA_LOG;
|
||||
|
||||
|
||||
static void
|
||||
compaq_cga_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (compaq_cga_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define compaq_cga_log(fmt, ...)
|
||||
# define compaq_cga_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
compaq_cga_recalctimings(compaq_cga_t *self)
|
||||
{
|
||||
double _dispontime, _dispofftime, disptime;
|
||||
disptime = self->cga.crtc[0] + 1;
|
||||
|
||||
_dispontime = self->cga.crtc[1];
|
||||
_dispontime = self->cga.crtc[1];
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= MDACONST;
|
||||
_dispofftime *= MDACONST;
|
||||
self->cga.dispontime = (uint64_t)(_dispontime);
|
||||
self->cga.dispofftime = (uint64_t)(_dispofftime);
|
||||
self->cga.dispontime = (uint64_t) (_dispontime);
|
||||
self->cga.dispofftime = (uint64_t) (_dispofftime);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
compaq_cga_poll(void *p)
|
||||
{
|
||||
compaq_cga_t *self = (compaq_cga_t *)p;
|
||||
uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x, c, xs_temp, ys_temp;
|
||||
int oldvc;
|
||||
uint8_t chr, attr;
|
||||
uint8_t border;
|
||||
uint8_t cols[4];
|
||||
int oldsc;
|
||||
int underline = 0;
|
||||
int blink = 0;
|
||||
compaq_cga_t *self = (compaq_cga_t *) p;
|
||||
uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x, c, xs_temp, ys_temp;
|
||||
int oldvc;
|
||||
uint8_t chr, attr;
|
||||
uint8_t border;
|
||||
uint8_t cols[4];
|
||||
int oldsc;
|
||||
int underline = 0;
|
||||
int blink = 0;
|
||||
|
||||
/* If in graphics mode or character height is not 13, behave as CGA */
|
||||
if ((self->cga.cgamode & 0x12) || (self->cga.crtc[9] != 13)) {
|
||||
overscan_x = overscan_y = 16;
|
||||
cga_poll(&self->cga);
|
||||
return;
|
||||
overscan_x = overscan_y = 16;
|
||||
cga_poll(&self->cga);
|
||||
return;
|
||||
} else
|
||||
overscan_x = overscan_y = 0;
|
||||
overscan_x = overscan_y = 0;
|
||||
|
||||
/* We are in Compaq 350-line CGA territory */
|
||||
if (!self->cga.linepos) {
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispofftime);
|
||||
self->cga.cgastat |= 1;
|
||||
self->cga.linepos = 1;
|
||||
oldsc = self->cga.sc;
|
||||
if ((self->cga.crtc[8] & 3) == 3)
|
||||
self->cga.sc = ((self->cga.sc << 1) + self->cga.oddeven) & 7;
|
||||
if (self->cga.cgadispon) {
|
||||
if (self->cga.displine < self->cga.firstline) {
|
||||
self->cga.firstline = self->cga.displine;
|
||||
video_wait_for_buffer();
|
||||
compaq_cga_log("Firstline %i\n", firstline);
|
||||
}
|
||||
self->cga.lastline = self->cga.displine;
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispofftime);
|
||||
self->cga.cgastat |= 1;
|
||||
self->cga.linepos = 1;
|
||||
oldsc = self->cga.sc;
|
||||
if ((self->cga.crtc[8] & 3) == 3)
|
||||
self->cga.sc = ((self->cga.sc << 1) + self->cga.oddeven) & 7;
|
||||
if (self->cga.cgadispon) {
|
||||
if (self->cga.displine < self->cga.firstline) {
|
||||
self->cga.firstline = self->cga.displine;
|
||||
video_wait_for_buffer();
|
||||
compaq_cga_log("Firstline %i\n", firstline);
|
||||
}
|
||||
self->cga.lastline = self->cga.displine;
|
||||
|
||||
cols[0] = (self->cga.cgacol & 15) + 16;
|
||||
cols[0] = (self->cga.cgacol & 15) + 16;
|
||||
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[self->cga.displine][c] = cols[0];
|
||||
if (self->cga.cgamode & 1)
|
||||
buffer32->line[self->cga.displine][c + (self->cga.crtc[1] << 3) + 8] = cols[0];
|
||||
else
|
||||
buffer32->line[self->cga.displine][c + (self->cga.crtc[1] << 4) + 8] = cols[0];
|
||||
}
|
||||
for (c = 0; c < 8; c++) {
|
||||
buffer32->line[self->cga.displine][c] = cols[0];
|
||||
if (self->cga.cgamode & 1)
|
||||
buffer32->line[self->cga.displine][c + (self->cga.crtc[1] << 3) + 8] = cols[0];
|
||||
else
|
||||
buffer32->line[self->cga.displine][c + (self->cga.crtc[1] << 4) + 8] = cols[0];
|
||||
}
|
||||
|
||||
if (self->cga.cgamode & 1) {
|
||||
for (x = 0; x < self->cga.crtc[1]; x++) {
|
||||
chr = self->cga.charbuffer[x << 1];
|
||||
attr = self->cga.charbuffer[(x << 1) + 1];
|
||||
drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron);
|
||||
if (self->cga.cgamode & 1) {
|
||||
for (x = 0; x < self->cga.crtc[1]; x++) {
|
||||
chr = self->cga.charbuffer[x << 1];
|
||||
attr = self->cga.charbuffer[(x << 1) + 1];
|
||||
drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron);
|
||||
|
||||
if (vflags) {
|
||||
underline = 0;
|
||||
blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
}
|
||||
if (vflags) {
|
||||
underline = 0;
|
||||
blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
}
|
||||
|
||||
if (vflags && (self->cga.cgamode & 0x80)) {
|
||||
cols[0] = mdaattr[attr][blink][0];
|
||||
cols[1] = mdaattr[attr][blink][1];
|
||||
if (vflags && (self->cga.cgamode & 0x80)) {
|
||||
cols[0] = mdaattr[attr][blink][0];
|
||||
cols[1] = mdaattr[attr][blink][1];
|
||||
|
||||
if ((self->cga.sc == 12) && ((attr & 7) == 1))
|
||||
underline = 1;
|
||||
} else if (self->cga.cgamode & 0x20) {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if ((self->cga.sc == 12) && ((attr & 7) == 1))
|
||||
underline = 1;
|
||||
} else if (self->cga.cgamode & 0x20) {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
|
||||
if (vflags) {
|
||||
if (blink)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor)
|
||||
cols[1] = cols[0];
|
||||
}
|
||||
} else {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
if (vflags) {
|
||||
if (blink)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor)
|
||||
cols[1] = cols[0];
|
||||
}
|
||||
} else {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
|
||||
if (vflags && underline) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c + 8] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
self->cga.ma++;
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < self->cga.crtc[1]; x++) {
|
||||
chr = self->cga.vram[((self->cga.ma << 1) & 0x3fff)];
|
||||
attr = self->cga.vram[(((self->cga.ma << 1) + 1) & 0x3fff)];
|
||||
drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron);
|
||||
if (vflags && underline) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c + 8] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 3) + c + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
self->cga.ma++;
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < self->cga.crtc[1]; x++) {
|
||||
chr = self->cga.vram[((self->cga.ma << 1) & 0x3fff)];
|
||||
attr = self->cga.vram[(((self->cga.ma << 1) + 1) & 0x3fff)];
|
||||
drawcursor = ((self->cga.ma == ca) && self->cga.con && self->cga.cursoron);
|
||||
|
||||
if (vflags) {
|
||||
underline = 0;
|
||||
blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
}
|
||||
if (vflags) {
|
||||
underline = 0;
|
||||
blink = ((self->cga.cgablink & 8) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
}
|
||||
|
||||
if (vflags && (self->cga.cgamode & 0x80)) {
|
||||
cols[0] = mdaattr[attr][blink][0];
|
||||
cols[1] = mdaattr[attr][blink][1];
|
||||
if (self->cga.sc == 12 && (attr & 7) == 1) underline = 1;
|
||||
} else if (self->cga.cgamode & 0x20) {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
if (vflags && (self->cga.cgamode & 0x80)) {
|
||||
cols[0] = mdaattr[attr][blink][0];
|
||||
cols[1] = mdaattr[attr][blink][1];
|
||||
if (self->cga.sc == 12 && (attr & 7) == 1)
|
||||
underline = 1;
|
||||
} else if (self->cga.cgamode & 0x20) {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = ((attr >> 4) & 7) + 16;
|
||||
|
||||
if (vflags) {
|
||||
if (blink)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor)
|
||||
cols[1] = cols[0];
|
||||
}
|
||||
} else {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
self->cga.ma++;
|
||||
if (vflags) {
|
||||
if (blink)
|
||||
cols[1] = cols[0];
|
||||
} else {
|
||||
if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor)
|
||||
cols[1] = cols[0];
|
||||
}
|
||||
} else {
|
||||
cols[1] = (attr & 15) + 16;
|
||||
cols[0] = (attr >> 4) + 16;
|
||||
}
|
||||
self->cga.ma++;
|
||||
|
||||
if (vflags && underline) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4)+(c << 1) + 8] =
|
||||
buffer32->line[self->cga.displine][(x << 4)+(c << 1) + 9] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4)+(c << 1) + 8] =
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1 + 8] =
|
||||
cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] =
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1 + 8] =
|
||||
cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cols[0] = (self->cga.cgacol & 15) + 16;
|
||||
if (vflags && underline) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 9] = mdaattr[attr][blink][1];
|
||||
} else if (drawcursor) {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0] ^ 15;
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 8] = buffer32->line[self->cga.displine][(x << 4) + (c << 1) + 1 + 8] = cols[(fontdatm[chr + self->cga.fontbase][self->cga.sc & 15] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
cols[0] = (self->cga.cgacol & 15) + 16;
|
||||
|
||||
if (self->cga.cgamode & 1) hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 3) + 16, cols[0]);
|
||||
else hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 4) + 16, cols[0]);
|
||||
}
|
||||
if (self->cga.cgamode & 1)
|
||||
hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 3) + 16, cols[0]);
|
||||
else
|
||||
hline(buffer32, 0, self->cga.displine, (self->cga.crtc[1] << 4) + 16, cols[0]);
|
||||
}
|
||||
|
||||
if (self->cga.cgamode & 1) x = (self->cga.crtc[1] << 3) + 16;
|
||||
else x = (self->cga.crtc[1] << 4) + 16;
|
||||
if (self->cga.cgamode & 1)
|
||||
x = (self->cga.crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (self->cga.crtc[1] << 4) + 16;
|
||||
|
||||
if (self->cga.composite) {
|
||||
if (self->cga.cgamode & 0x10)
|
||||
border = 0x00;
|
||||
else
|
||||
border = self->cga.cgacol & 0x0f;
|
||||
if (self->cga.composite) {
|
||||
if (self->cga.cgamode & 0x10)
|
||||
border = 0x00;
|
||||
else
|
||||
border = self->cga.cgacol & 0x0f;
|
||||
|
||||
if (vflags)
|
||||
Composite_Process(self->cga.cgamode & 0x7f, border, x >> 2, buffer32->line[self->cga.displine]);
|
||||
else
|
||||
Composite_Process(self->cga.cgamode, border, x >> 2, buffer32->line[self->cga.displine]);
|
||||
}
|
||||
if (vflags)
|
||||
Composite_Process(self->cga.cgamode & 0x7f, border, x >> 2, buffer32->line[self->cga.displine]);
|
||||
else
|
||||
Composite_Process(self->cga.cgamode, border, x >> 2, buffer32->line[self->cga.displine]);
|
||||
}
|
||||
|
||||
self->cga.sc = oldsc;
|
||||
if (self->cga.vc == self->cga.crtc[7] && !self->cga.sc)
|
||||
self->cga.cgastat |= 8;
|
||||
self->cga.displine++;
|
||||
if (self->cga.displine >= 500)
|
||||
self->cga.displine = 0;
|
||||
self->cga.sc = oldsc;
|
||||
if (self->cga.vc == self->cga.crtc[7] && !self->cga.sc)
|
||||
self->cga.cgastat |= 8;
|
||||
self->cga.displine++;
|
||||
if (self->cga.displine >= 500)
|
||||
self->cga.displine = 0;
|
||||
} else {
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispontime);
|
||||
self->cga.linepos = 0;
|
||||
if (self->cga.vsynctime) {
|
||||
self->cga.vsynctime--;
|
||||
if (!self->cga.vsynctime)
|
||||
self->cga.cgastat &= ~8;
|
||||
}
|
||||
timer_advance_u64(&self->cga.timer, self->cga.dispontime);
|
||||
self->cga.linepos = 0;
|
||||
if (self->cga.vsynctime) {
|
||||
self->cga.vsynctime--;
|
||||
if (!self->cga.vsynctime)
|
||||
self->cga.cgastat &= ~8;
|
||||
}
|
||||
|
||||
if (self->cga.sc == (self->cga.crtc[11] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[11] & 31) >> 1))) {
|
||||
self->cga.con = 0;
|
||||
self->cga.coff = 1;
|
||||
}
|
||||
if ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == (self->cga.crtc[9] >> 1))
|
||||
self->cga.maback = self->cga.ma;
|
||||
if (self->cga.vadj) {
|
||||
self->cga.sc++;
|
||||
self->cga.sc &= 31;
|
||||
self->cga.ma = self->cga.maback;
|
||||
self->cga.vadj--;
|
||||
if (!self->cga.vadj) {
|
||||
self->cga.cgadispon = 1;
|
||||
self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff;
|
||||
self->cga.sc = 0;
|
||||
}
|
||||
} else if (self->cga.sc == self->cga.crtc[9]) {
|
||||
self->cga.maback = self->cga.ma;
|
||||
self->cga.sc = 0;
|
||||
oldvc = self->cga.vc;
|
||||
self->cga.vc++;
|
||||
self->cga.vc &= 127;
|
||||
if (self->cga.sc == (self->cga.crtc[11] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[11] & 31) >> 1))) {
|
||||
self->cga.con = 0;
|
||||
self->cga.coff = 1;
|
||||
}
|
||||
if ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == (self->cga.crtc[9] >> 1))
|
||||
self->cga.maback = self->cga.ma;
|
||||
if (self->cga.vadj) {
|
||||
self->cga.sc++;
|
||||
self->cga.sc &= 31;
|
||||
self->cga.ma = self->cga.maback;
|
||||
self->cga.vadj--;
|
||||
if (!self->cga.vadj) {
|
||||
self->cga.cgadispon = 1;
|
||||
self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff;
|
||||
self->cga.sc = 0;
|
||||
}
|
||||
} else if (self->cga.sc == self->cga.crtc[9]) {
|
||||
self->cga.maback = self->cga.ma;
|
||||
self->cga.sc = 0;
|
||||
oldvc = self->cga.vc;
|
||||
self->cga.vc++;
|
||||
self->cga.vc &= 127;
|
||||
|
||||
if (self->cga.vc == self->cga.crtc[6])
|
||||
self->cga.cgadispon = 0;
|
||||
if (self->cga.vc == self->cga.crtc[6])
|
||||
self->cga.cgadispon = 0;
|
||||
|
||||
if (oldvc == self->cga.crtc[4]) {
|
||||
self->cga.vc = 0;
|
||||
self->cga.vadj = self->cga.crtc[5];
|
||||
if (oldvc == self->cga.crtc[4]) {
|
||||
self->cga.vc = 0;
|
||||
self->cga.vadj = self->cga.crtc[5];
|
||||
|
||||
if (!self->cga.vadj) self->cga.cgadispon = 1;
|
||||
if (!self->cga.vadj)
|
||||
self->cga.cgadispon = 1;
|
||||
|
||||
if (!self->cga.vadj) self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff;
|
||||
if (!self->cga.vadj)
|
||||
self->cga.ma = self->cga.maback = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x3fff;
|
||||
|
||||
if ((self->cga.crtc[10] & 0x60) == 0x20)
|
||||
self->cga.cursoron = 0;
|
||||
else
|
||||
self->cga.cursoron = self->cga.cgablink & 8;
|
||||
}
|
||||
if ((self->cga.crtc[10] & 0x60) == 0x20)
|
||||
self->cga.cursoron = 0;
|
||||
else
|
||||
self->cga.cursoron = self->cga.cgablink & 8;
|
||||
}
|
||||
|
||||
if (self->cga.vc == self->cga.crtc[7]) {
|
||||
self->cga.cgadispon = 0;
|
||||
self->cga.displine = 0;
|
||||
self->cga.vsynctime = 16;
|
||||
if (self->cga.vc == self->cga.crtc[7]) {
|
||||
self->cga.cgadispon = 0;
|
||||
self->cga.displine = 0;
|
||||
self->cga.vsynctime = 16;
|
||||
|
||||
if (self->cga.crtc[7]) {
|
||||
compaq_cga_log("Lastline %i Firstline %i %i\n", self->cga.lastline,
|
||||
self->cga.firstline ,self->cga.lastline - self->cga.firstline);
|
||||
if (self->cga.crtc[7]) {
|
||||
compaq_cga_log("Lastline %i Firstline %i %i\n", self->cga.lastline,
|
||||
self->cga.firstline, self->cga.lastline - self->cga.firstline);
|
||||
|
||||
if (self->cga.cgamode & 1) x = (self->cga.crtc[1] << 3) + 16;
|
||||
else x = (self->cga.crtc[1] << 4) + 16;
|
||||
if (self->cga.cgamode & 1)
|
||||
x = (self->cga.crtc[1] << 3) + 16;
|
||||
else
|
||||
x = (self->cga.crtc[1] << 4) + 16;
|
||||
|
||||
self->cga.lastline++;
|
||||
self->cga.lastline++;
|
||||
|
||||
xs_temp = x;
|
||||
ys_temp = (self->cga.lastline - self->cga.firstline);
|
||||
xs_temp = x;
|
||||
ys_temp = (self->cga.lastline - self->cga.firstline);
|
||||
|
||||
if ((xs_temp > 0) && (ys_temp > 0)) {
|
||||
if (xs_temp < 64) xs_temp = 656;
|
||||
if (ys_temp < 32) ys_temp = 400;
|
||||
if (!enable_overscan)
|
||||
xs_temp -= 16;
|
||||
if ((xs_temp > 0) && (ys_temp > 0)) {
|
||||
if (xs_temp < 64)
|
||||
xs_temp = 656;
|
||||
if (ys_temp < 32)
|
||||
ys_temp = 400;
|
||||
if (!enable_overscan)
|
||||
xs_temp -= 16;
|
||||
|
||||
if ((self->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0));
|
||||
if ((self->cga.cgamode & 8) && ((xs_temp != xsize) || (ys_temp != ysize) || video_force_resize_get())) {
|
||||
xsize = xs_temp;
|
||||
ysize = ys_temp;
|
||||
set_screen_size(xsize, ysize + (enable_overscan ? 16 : 0));
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
|
||||
if (enable_overscan) {
|
||||
if (self->cga.composite)
|
||||
video_blit_memtoscreen(0, self->cga.firstline - 8, xsize, (self->cga.lastline - self->cga.firstline) + 16);
|
||||
else
|
||||
video_blit_memtoscreen_8(0, self->cga.firstline - 8, xsize, (self->cga.lastline - self->cga.firstline) + 16);
|
||||
} else {
|
||||
if (self->cga.composite)
|
||||
video_blit_memtoscreen(8, self->cga.firstline, xsize, self->cga.lastline - self->cga.firstline);
|
||||
else
|
||||
video_blit_memtoscreen_8(8, self->cga.firstline, xsize, self->cga.lastline - self->cga.firstline);
|
||||
}
|
||||
}
|
||||
if (enable_overscan) {
|
||||
if (self->cga.composite)
|
||||
video_blit_memtoscreen(0, self->cga.firstline - 8, xsize, (self->cga.lastline - self->cga.firstline) + 16);
|
||||
else
|
||||
video_blit_memtoscreen_8(0, self->cga.firstline - 8, xsize, (self->cga.lastline - self->cga.firstline) + 16);
|
||||
} else {
|
||||
if (self->cga.composite)
|
||||
video_blit_memtoscreen(8, self->cga.firstline, xsize, self->cga.lastline - self->cga.firstline);
|
||||
else
|
||||
video_blit_memtoscreen_8(8, self->cga.firstline, xsize, self->cga.lastline - self->cga.firstline);
|
||||
}
|
||||
}
|
||||
|
||||
frames++;
|
||||
frames++;
|
||||
|
||||
video_res_x = xsize;
|
||||
if (enable_overscan)
|
||||
xsize -= 16;
|
||||
video_res_y = ysize;
|
||||
if (self->cga.cgamode & 1) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= self->cga.crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(self->cga.cgamode & 2)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= self->cga.crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(self->cga.cgamode & 16)) {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
} else
|
||||
video_bpp = 1;
|
||||
}
|
||||
video_res_x = xsize;
|
||||
if (enable_overscan)
|
||||
xsize -= 16;
|
||||
video_res_y = ysize;
|
||||
if (self->cga.cgamode & 1) {
|
||||
video_res_x /= 8;
|
||||
video_res_y /= self->cga.crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(self->cga.cgamode & 2)) {
|
||||
video_res_x /= 16;
|
||||
video_res_y /= self->cga.crtc[9] + 1;
|
||||
video_bpp = 0;
|
||||
} else if (!(self->cga.cgamode & 16)) {
|
||||
video_res_x /= 2;
|
||||
video_bpp = 2;
|
||||
} else
|
||||
video_bpp = 1;
|
||||
}
|
||||
|
||||
self->cga.firstline = 1000;
|
||||
self->cga.lastline = 0;
|
||||
self->cga.cgablink++;
|
||||
self->cga.oddeven ^= 1;
|
||||
}
|
||||
} else {
|
||||
self->cga.sc++;
|
||||
self->cga.sc &= 31;
|
||||
self->cga.ma = self->cga.maback;
|
||||
}
|
||||
self->cga.firstline = 1000;
|
||||
self->cga.lastline = 0;
|
||||
self->cga.cgablink++;
|
||||
self->cga.oddeven ^= 1;
|
||||
}
|
||||
} else {
|
||||
self->cga.sc++;
|
||||
self->cga.sc &= 31;
|
||||
self->cga.ma = self->cga.maback;
|
||||
}
|
||||
|
||||
if (self->cga.cgadispon)
|
||||
self->cga.cgastat &= ~1;
|
||||
if (self->cga.cgadispon)
|
||||
self->cga.cgastat &= ~1;
|
||||
|
||||
if ((self->cga.sc == (self->cga.crtc[10] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[10] & 31) >> 1))))
|
||||
self->cga.con = 1;
|
||||
if ((self->cga.sc == (self->cga.crtc[10] & 31) || ((self->cga.crtc[8] & 3) == 3 && self->cga.sc == ((self->cga.crtc[10] & 31) >> 1))))
|
||||
self->cga.con = 1;
|
||||
|
||||
if (self->cga.cgadispon && (self->cga.cgamode & 1)) {
|
||||
for (x = 0; x < (self->cga.crtc[1] << 1); x++)
|
||||
self->cga.charbuffer[x] = self->cga.vram[(((self->cga.ma << 1) + x) & 0x3fff)];
|
||||
}
|
||||
if (self->cga.cgadispon && (self->cga.cgamode & 1)) {
|
||||
for (x = 0; x < (self->cga.crtc[1] << 1); x++)
|
||||
self->cga.charbuffer[x] = self->cga.vram[(((self->cga.ma << 1) + x) & 0x3fff)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
compaq_cga_init(const device_t *info)
|
||||
{
|
||||
int display_type;
|
||||
int c;
|
||||
int display_type;
|
||||
int c;
|
||||
compaq_cga_t *self = malloc(sizeof(compaq_cga_t));
|
||||
memset(self, 0, sizeof(compaq_cga_t));
|
||||
|
||||
display_type = device_get_config_int("display_type");
|
||||
self->cga.composite = (display_type != CGA_RGB);
|
||||
self->cga.revision = device_get_config_int("composite_type");
|
||||
display_type = device_get_config_int("display_type");
|
||||
self->cga.composite = (display_type != CGA_RGB);
|
||||
self->cga.revision = device_get_config_int("composite_type");
|
||||
self->cga.snow_enabled = device_get_config_int("snow_enabled");
|
||||
|
||||
self->cga.vram = malloc(0x4000);
|
||||
@@ -418,24 +415,26 @@ compaq_cga_init(const device_t *info)
|
||||
io_sethandler(0x03d0, 0x0010, cga_in, NULL, NULL, cga_out, NULL, NULL, self);
|
||||
|
||||
if (info->local) {
|
||||
for (c = 0; c < 256; c++) {
|
||||
mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16;
|
||||
if (c & 8) mdaattr[c][0][1] = 15 + 16;
|
||||
else mdaattr[c][0][1] = 7 + 16;
|
||||
}
|
||||
for (c = 0; c < 256; c++) {
|
||||
mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16;
|
||||
if (c & 8)
|
||||
mdaattr[c][0][1] = 15 + 16;
|
||||
else
|
||||
mdaattr[c][0][1] = 7 + 16;
|
||||
}
|
||||
|
||||
mdaattr[0x70][0][1] = 16;
|
||||
mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15;
|
||||
mdaattr[0xF0][0][1] = 16;
|
||||
mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15;
|
||||
mdaattr[0x78][0][1] = 16 + 7;
|
||||
mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15;
|
||||
mdaattr[0xF8][0][1] = 16 + 7;
|
||||
mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15;
|
||||
mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16;
|
||||
mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16;
|
||||
mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16;
|
||||
mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16;
|
||||
mdaattr[0x70][0][1] = 16;
|
||||
mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15;
|
||||
mdaattr[0xF0][0][1] = 16;
|
||||
mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15;
|
||||
mdaattr[0x78][0][1] = 16 + 7;
|
||||
mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15;
|
||||
mdaattr[0xF8][0][1] = 16 + 7;
|
||||
mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15;
|
||||
mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16;
|
||||
mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16;
|
||||
mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16;
|
||||
mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16;
|
||||
}
|
||||
|
||||
vflags = info->local;
|
||||
@@ -443,7 +442,7 @@ compaq_cga_init(const device_t *info)
|
||||
overscan_x = overscan_y = 16;
|
||||
|
||||
self->cga.rgb_type = device_get_config_int("rgb_type");
|
||||
cga_palette = (self->cga.rgb_type << 1);
|
||||
cga_palette = (self->cga.rgb_type << 1);
|
||||
cgapal_rebuild();
|
||||
|
||||
self->cga.crtc[9] = 13;
|
||||
@@ -451,55 +450,52 @@ compaq_cga_init(const device_t *info)
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
compaq_cga_close(void *p)
|
||||
{
|
||||
compaq_cga_t *self = (compaq_cga_t *)p;
|
||||
compaq_cga_t *self = (compaq_cga_t *) p;
|
||||
|
||||
free(self->cga.vram);
|
||||
free(self);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
compaq_cga_speed_changed(void *p)
|
||||
{
|
||||
compaq_cga_t *self = (compaq_cga_t *)p;
|
||||
compaq_cga_t *self = (compaq_cga_t *) p;
|
||||
|
||||
if (self->cga.crtc[9] == 13) /* Character height */
|
||||
compaq_cga_recalctimings(self);
|
||||
if (self->cga.crtc[9] == 13) /* Character height */
|
||||
compaq_cga_recalctimings(self);
|
||||
else
|
||||
cga_recalctimings(&self->cga);
|
||||
cga_recalctimings(&self->cga);
|
||||
}
|
||||
|
||||
|
||||
extern const device_config_t cga_config[];
|
||||
|
||||
const device_t compaq_cga_device = {
|
||||
.name = "Compaq CGA",
|
||||
.name = "Compaq CGA",
|
||||
.internal_name = "compaq_cga",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = compaq_cga_init,
|
||||
.close = compaq_cga_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = compaq_cga_init,
|
||||
.close = compaq_cga_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = compaq_cga_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = cga_config
|
||||
.force_redraw = NULL,
|
||||
.config = cga_config
|
||||
};
|
||||
|
||||
const device_t compaq_cga_2_device = {
|
||||
.name = "Compaq CGA 2",
|
||||
.name = "Compaq CGA 2",
|
||||
.internal_name = "compaq_cga_2",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 1,
|
||||
.init = compaq_cga_init,
|
||||
.close = compaq_cga_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 1,
|
||||
.init = compaq_cga_init,
|
||||
.close = compaq_cga_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = compaq_cga_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = cga_config
|
||||
.force_redraw = NULL,
|
||||
.config = cga_config
|
||||
};
|
||||
|
||||
@@ -24,30 +24,30 @@
|
||||
#include <86box/86box.h>
|
||||
#include <86box/i2c.h>
|
||||
|
||||
|
||||
#define PIXEL_MM(px) ((uint16_t) (((px) * 25.4) / 96))
|
||||
#define STANDARD_TIMING(slot, width, aspect_ratio, refresh) do { \
|
||||
edid->slot.horiz_pixels = ((width) >> 3) - 31; \
|
||||
edid->slot.aspect_ratio_refresh_rate = ((aspect_ratio) << 6) | ((refresh) - 60); \
|
||||
} while (0)
|
||||
#define DETAILED_TIMING(slot, clk, width, height, hblank, vblank, hfp, hsp, vfp, vsp) do { \
|
||||
edid->slot.pixel_clock_lsb = ((clk) / 10) & 0xff; \
|
||||
edid->slot.pixel_clock_msb = ((clk) / 10) >> 8; \
|
||||
edid->slot.h_active_lsb = (width) & 0xff; \
|
||||
edid->slot.h_blank_lsb = (hblank) & 0xff; \
|
||||
edid->slot.h_active_blank_msb = (((width) >> 4) & 0xf0) | (((hblank) >> 8) & 0x0f); \
|
||||
edid->slot.v_active_lsb = (height) & 0xff; \
|
||||
edid->slot.v_blank_lsb = (vblank) & 0xff; \
|
||||
edid->slot.v_active_blank_msb = (((height) >> 4) & 0xf0) | (((vblank) >> 8) & 0x0f); \
|
||||
edid->slot.h_front_porch_lsb = (hfp) & 0xff; \
|
||||
edid->slot.h_sync_pulse_lsb = (hsp) & 0xff; \
|
||||
edid->slot.v_front_porch_sync_pulse_lsb = (((vfp) & 0x0f) << 4) | ((vsp) & 0x0f); \
|
||||
edid->slot.hv_front_porch_sync_pulse_msb = (((hfp) >> 2) & 0xc0) | (((hsp) >> 4) & 0x30) | (((vfp) >> 2) & 0x0c) | (((vsp) >> 4) & 0x03); \
|
||||
edid->slot.h_size_lsb = horiz_mm & 0xff; \
|
||||
edid->slot.v_size_lsb = vert_mm & 0xff; \
|
||||
edid->slot.hv_size_msb = ((horiz_mm >> 4) & 0xf0) | ((vert_mm >> 8) & 0x0f); \
|
||||
} while (0)
|
||||
|
||||
#define PIXEL_MM(px) ((uint16_t) (((px) *25.4) / 96))
|
||||
#define STANDARD_TIMING(slot, width, aspect_ratio, refresh) \
|
||||
do { \
|
||||
edid->slot.horiz_pixels = ((width) >> 3) - 31; \
|
||||
edid->slot.aspect_ratio_refresh_rate = ((aspect_ratio) << 6) | ((refresh) -60); \
|
||||
} while (0)
|
||||
#define DETAILED_TIMING(slot, clk, width, height, hblank, vblank, hfp, hsp, vfp, vsp) \
|
||||
do { \
|
||||
edid->slot.pixel_clock_lsb = ((clk) / 10) & 0xff; \
|
||||
edid->slot.pixel_clock_msb = ((clk) / 10) >> 8; \
|
||||
edid->slot.h_active_lsb = (width) &0xff; \
|
||||
edid->slot.h_blank_lsb = (hblank) &0xff; \
|
||||
edid->slot.h_active_blank_msb = (((width) >> 4) & 0xf0) | (((hblank) >> 8) & 0x0f); \
|
||||
edid->slot.v_active_lsb = (height) &0xff; \
|
||||
edid->slot.v_blank_lsb = (vblank) &0xff; \
|
||||
edid->slot.v_active_blank_msb = (((height) >> 4) & 0xf0) | (((vblank) >> 8) & 0x0f); \
|
||||
edid->slot.h_front_porch_lsb = (hfp) &0xff; \
|
||||
edid->slot.h_sync_pulse_lsb = (hsp) &0xff; \
|
||||
edid->slot.v_front_porch_sync_pulse_lsb = (((vfp) &0x0f) << 4) | ((vsp) &0x0f); \
|
||||
edid->slot.hv_front_porch_sync_pulse_msb = (((hfp) >> 2) & 0xc0) | (((hsp) >> 4) & 0x30) | (((vfp) >> 2) & 0x0c) | (((vsp) >> 4) & 0x03); \
|
||||
edid->slot.h_size_lsb = horiz_mm & 0xff; \
|
||||
edid->slot.v_size_lsb = vert_mm & 0xff; \
|
||||
edid->slot.hv_size_msb = ((horiz_mm >> 4) & 0xf0) | ((vert_mm >> 8) & 0x0f); \
|
||||
} while (0)
|
||||
|
||||
enum {
|
||||
STD_ASPECT_16_10 = 0x0,
|
||||
@@ -57,76 +57,75 @@ enum {
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t horiz_pixels, aspect_ratio_refresh_rate;
|
||||
uint8_t horiz_pixels, aspect_ratio_refresh_rate;
|
||||
} edid_standard_timing_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t pixel_clock_lsb, pixel_clock_msb, h_active_lsb, h_blank_lsb,
|
||||
h_active_blank_msb, v_active_lsb, v_blank_lsb, v_active_blank_msb,
|
||||
h_front_porch_lsb, h_sync_pulse_lsb, v_front_porch_sync_pulse_lsb,
|
||||
hv_front_porch_sync_pulse_msb, h_size_lsb, v_size_lsb, hv_size_msb,
|
||||
h_border, v_border, features;
|
||||
uint8_t pixel_clock_lsb, pixel_clock_msb, h_active_lsb, h_blank_lsb,
|
||||
h_active_blank_msb, v_active_lsb, v_blank_lsb, v_active_blank_msb,
|
||||
h_front_porch_lsb, h_sync_pulse_lsb, v_front_porch_sync_pulse_lsb,
|
||||
hv_front_porch_sync_pulse_msb, h_size_lsb, v_size_lsb, hv_size_msb,
|
||||
h_border, v_border, features;
|
||||
} edid_detailed_timing_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t magic[2], reserved, tag, range_limit_offsets;
|
||||
uint8_t magic[2], reserved, tag, range_limit_offsets;
|
||||
union {
|
||||
char ascii[13];
|
||||
struct {
|
||||
uint8_t min_v_field, max_v_field, min_h_line, max_h_line, max_pixel_clock,
|
||||
timing_type;
|
||||
union {
|
||||
uint8_t padding[7];
|
||||
struct {
|
||||
uint8_t reserved, gtf_start_freq, gtf_c, gtf_m_lsb, gtf_m_msb,
|
||||
gtf_k, gtf_j;
|
||||
};
|
||||
struct {
|
||||
uint8_t cvt_version, add_clock_precision, max_active_pixels,
|
||||
aspect_ratios, aspect_ratio_pref, scaling_support,
|
||||
refresh_pref;
|
||||
};
|
||||
};
|
||||
} range_limits;
|
||||
struct {
|
||||
edid_standard_timing_t timings[6];
|
||||
uint8_t padding;
|
||||
} ext_standard_timings;
|
||||
struct {
|
||||
uint8_t version;
|
||||
struct {
|
||||
uint8_t lines_lsb, lines_msb_aspect_ratio, refresh_rate;
|
||||
} timings[4];
|
||||
} cvt_timings;
|
||||
struct {
|
||||
uint8_t version, timings[6], reserved[6];
|
||||
} established_timings3;
|
||||
char ascii[13];
|
||||
struct {
|
||||
uint8_t min_v_field, max_v_field, min_h_line, max_h_line, max_pixel_clock,
|
||||
timing_type;
|
||||
union {
|
||||
uint8_t padding[7];
|
||||
struct {
|
||||
uint8_t reserved, gtf_start_freq, gtf_c, gtf_m_lsb, gtf_m_msb,
|
||||
gtf_k, gtf_j;
|
||||
};
|
||||
struct {
|
||||
uint8_t cvt_version, add_clock_precision, max_active_pixels,
|
||||
aspect_ratios, aspect_ratio_pref, scaling_support,
|
||||
refresh_pref;
|
||||
};
|
||||
};
|
||||
} range_limits;
|
||||
struct {
|
||||
edid_standard_timing_t timings[6];
|
||||
uint8_t padding;
|
||||
} ext_standard_timings;
|
||||
struct {
|
||||
uint8_t version;
|
||||
struct {
|
||||
uint8_t lines_lsb, lines_msb_aspect_ratio, refresh_rate;
|
||||
} timings[4];
|
||||
} cvt_timings;
|
||||
struct {
|
||||
uint8_t version, timings[6], reserved[6];
|
||||
} established_timings3;
|
||||
};
|
||||
} edid_descriptor_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t magic[8], mfg[2], mfg_product[2], serial[4], mfg_week, mfg_year,
|
||||
edid_version, edid_rev;
|
||||
uint8_t input_params, horiz_size, vert_size, gamma, features;
|
||||
uint8_t red_green_lsb, blue_white_lsb, red_x_msb, red_y_msb, green_x_msb,
|
||||
green_y_msb, blue_x_msb, blue_y_msb, white_x_msb, white_y_msb;
|
||||
uint8_t established_timings[3];
|
||||
uint8_t magic[8], mfg[2], mfg_product[2], serial[4], mfg_week, mfg_year,
|
||||
edid_version, edid_rev;
|
||||
uint8_t input_params, horiz_size, vert_size, gamma, features;
|
||||
uint8_t red_green_lsb, blue_white_lsb, red_x_msb, red_y_msb, green_x_msb,
|
||||
green_y_msb, blue_x_msb, blue_y_msb, white_x_msb, white_y_msb;
|
||||
uint8_t established_timings[3];
|
||||
edid_standard_timing_t standard_timings[8];
|
||||
union {
|
||||
edid_detailed_timing_t detailed_timings[4];
|
||||
edid_descriptor_t descriptors[4];
|
||||
edid_detailed_timing_t detailed_timings[4];
|
||||
edid_descriptor_t descriptors[4];
|
||||
};
|
||||
uint8_t extensions, checksum;
|
||||
uint8_t extensions, checksum;
|
||||
|
||||
uint8_t ext_tag, ext_rev, ext_dtd_offset, ext_native_dtds;
|
||||
uint8_t ext_tag, ext_rev, ext_dtd_offset, ext_native_dtds;
|
||||
union {
|
||||
edid_detailed_timing_t ext_detailed_timings[6];
|
||||
edid_descriptor_t ext_descriptors[6];
|
||||
edid_detailed_timing_t ext_detailed_timings[6];
|
||||
edid_descriptor_t ext_descriptors[6];
|
||||
};
|
||||
uint8_t padding[15], checksum2;
|
||||
uint8_t padding[15], checksum2;
|
||||
} edid_t;
|
||||
|
||||
|
||||
void *
|
||||
ddc_init(void *i2c)
|
||||
{
|
||||
@@ -138,60 +137,60 @@ ddc_init(void *i2c)
|
||||
|
||||
memset(&edid->magic[1], 0xff, sizeof(edid->magic) - 2);
|
||||
|
||||
edid->mfg[0] = 0x09; /* manufacturer "BOX" (apparently unassigned by UEFI) */
|
||||
edid->mfg[1] = 0xf8;
|
||||
edid->mfg_week = 48;
|
||||
edid->mfg_year = 2020 - 1990;
|
||||
edid->mfg[0] = 0x09; /* manufacturer "BOX" (apparently unassigned by UEFI) */
|
||||
edid->mfg[1] = 0xf8;
|
||||
edid->mfg_week = 48;
|
||||
edid->mfg_year = 2020 - 1990;
|
||||
edid->edid_version = 0x01;
|
||||
edid->edid_rev = 0x03; /* EDID 1.3 */
|
||||
edid->edid_rev = 0x03; /* EDID 1.3 */
|
||||
|
||||
edid->input_params = 0x0e; /* analog input; separate sync; composite sync; sync on green */
|
||||
edid->horiz_size = horiz_mm / 10;
|
||||
edid->vert_size = vert_mm / 10;
|
||||
edid->features = 0xeb; /* DPMS standby/suspend/active-off; RGB color; first timing is preferred; GTF/CVT */
|
||||
edid->horiz_size = horiz_mm / 10;
|
||||
edid->vert_size = vert_mm / 10;
|
||||
edid->features = 0xeb; /* DPMS standby/suspend/active-off; RGB color; first timing is preferred; GTF/CVT */
|
||||
|
||||
edid->red_green_lsb = 0x81;
|
||||
edid->red_green_lsb = 0x81;
|
||||
edid->blue_white_lsb = 0xf1;
|
||||
edid->red_x_msb = 0xa3;
|
||||
edid->red_y_msb = 0x57;
|
||||
edid->green_x_msb = 0x53;
|
||||
edid->green_y_msb = 0x9f;
|
||||
edid->blue_x_msb = 0x27;
|
||||
edid->blue_y_msb = 0x0a;
|
||||
edid->white_x_msb = 0x50;
|
||||
edid->white_y_msb = 0x00;
|
||||
edid->red_x_msb = 0xa3;
|
||||
edid->red_y_msb = 0x57;
|
||||
edid->green_x_msb = 0x53;
|
||||
edid->green_y_msb = 0x9f;
|
||||
edid->blue_x_msb = 0x27;
|
||||
edid->blue_y_msb = 0x0a;
|
||||
edid->white_x_msb = 0x50;
|
||||
edid->white_y_msb = 0x00;
|
||||
|
||||
memset(&edid->established_timings, 0xff, sizeof(edid->established_timings)); /* all enabled */
|
||||
|
||||
/* 60 Hz timings */
|
||||
STANDARD_TIMING(standard_timings[0], 1280, STD_ASPECT_16_9, 60); /* 1280x720 */
|
||||
STANDARD_TIMING(standard_timings[0], 1280, STD_ASPECT_16_9, 60); /* 1280x720 */
|
||||
STANDARD_TIMING(standard_timings[1], 1280, STD_ASPECT_16_10, 60); /* 1280x800 */
|
||||
STANDARD_TIMING(standard_timings[2], 1366, STD_ASPECT_16_9, 60); /* 1360x768 (closest to 1366x768) */
|
||||
STANDARD_TIMING(standard_timings[2], 1366, STD_ASPECT_16_9, 60); /* 1360x768 (closest to 1366x768) */
|
||||
STANDARD_TIMING(standard_timings[3], 1440, STD_ASPECT_16_10, 60); /* 1440x900 */
|
||||
STANDARD_TIMING(standard_timings[4], 1600, STD_ASPECT_16_9, 60); /* 1600x900 */
|
||||
STANDARD_TIMING(standard_timings[4], 1600, STD_ASPECT_16_9, 60); /* 1600x900 */
|
||||
STANDARD_TIMING(standard_timings[5], 1680, STD_ASPECT_16_10, 60); /* 1680x1050 */
|
||||
STANDARD_TIMING(standard_timings[6], 1920, STD_ASPECT_16_9, 60); /* 1920x1080 */
|
||||
STANDARD_TIMING(standard_timings[7], 2048, STD_ASPECT_4_3, 60); /* 2048x1536 */
|
||||
STANDARD_TIMING(standard_timings[6], 1920, STD_ASPECT_16_9, 60); /* 1920x1080 */
|
||||
STANDARD_TIMING(standard_timings[7], 2048, STD_ASPECT_4_3, 60); /* 2048x1536 */
|
||||
|
||||
/* Detailed timing for the preferred mode of 800x600 @ 60 Hz */
|
||||
DETAILED_TIMING(detailed_timings[0], 40000, 800, 600, 256, 28, 40, 128, 1, 4);
|
||||
|
||||
edid->descriptors[1].tag = 0xf7; /* established timings 3 */
|
||||
edid->descriptors[1].tag = 0xf7; /* established timings 3 */
|
||||
edid->descriptors[1].established_timings3.version = 0x0a;
|
||||
memset(&edid->descriptors[1].established_timings3.timings, 0xff, sizeof(edid->descriptors[1].established_timings3.timings)); /* all enabled */
|
||||
edid->descriptors[1].established_timings3.timings[5] &= 0xf0; /* reserved bits */
|
||||
edid->descriptors[1].established_timings3.timings[5] &= 0xf0; /* reserved bits */
|
||||
|
||||
edid->descriptors[2].tag = 0xfd; /* range limits */
|
||||
edid->descriptors[2].range_limits.min_v_field = 45;
|
||||
edid->descriptors[2].range_limits.max_v_field = 125;
|
||||
edid->descriptors[2].range_limits.min_h_line = 30; /* 640x480 = ~31.5 KHz */
|
||||
edid->descriptors[2].range_limits.max_h_line = 115; /* 1920x1440 = 112.5 KHz */
|
||||
edid->descriptors[2].range_limits.max_pixel_clock = 30; /* 1920x1440 = 297 MHz */
|
||||
edid->descriptors[2].range_limits.timing_type = 0x00; /* default GTF */
|
||||
edid->descriptors[2].range_limits.padding[0] = 0x0a;
|
||||
edid->descriptors[2].tag = 0xfd; /* range limits */
|
||||
edid->descriptors[2].range_limits.min_v_field = 45;
|
||||
edid->descriptors[2].range_limits.max_v_field = 125;
|
||||
edid->descriptors[2].range_limits.min_h_line = 30; /* 640x480 = ~31.5 KHz */
|
||||
edid->descriptors[2].range_limits.max_h_line = 115; /* 1920x1440 = 112.5 KHz */
|
||||
edid->descriptors[2].range_limits.max_pixel_clock = 30; /* 1920x1440 = 297 MHz */
|
||||
edid->descriptors[2].range_limits.timing_type = 0x00; /* default GTF */
|
||||
edid->descriptors[2].range_limits.padding[0] = 0x0a;
|
||||
memset(&edid->descriptors[2].range_limits.padding[1], 0x20, sizeof(edid->descriptors[2].range_limits.padding) - 1);
|
||||
|
||||
edid->descriptors[3].tag = 0xfc; /* display name */
|
||||
edid->descriptors[3].tag = 0xfc; /* display name */
|
||||
memcpy(&edid->descriptors[3].ascii, "86Box Monitor", 13); /* exactly 13 characters (would otherwise require LF termination and space padding) */
|
||||
|
||||
edid->extensions = 1;
|
||||
@@ -199,10 +198,10 @@ ddc_init(void *i2c)
|
||||
edid->checksum += edid_bytes[c];
|
||||
edid->checksum = 256 - edid->checksum;
|
||||
|
||||
edid->ext_tag = 0x02;
|
||||
edid->ext_rev = 0x03;
|
||||
edid->ext_tag = 0x02;
|
||||
edid->ext_rev = 0x03;
|
||||
edid->ext_native_dtds = 0x80; /* underscans IT; no native extended modes */
|
||||
edid->ext_dtd_offset = 0x04;
|
||||
edid->ext_dtd_offset = 0x04;
|
||||
|
||||
/* Detailed timing for 1366x768 */
|
||||
DETAILED_TIMING(ext_detailed_timings[0], 85500, 1366, 768, 426, 30, 70, 143, 3, 3);
|
||||
@@ -210,12 +209,12 @@ ddc_init(void *i2c)
|
||||
/* High refresh rate timings (VGA is limited to 85 Hz) */
|
||||
edid->ext_descriptors[1].tag = 0xfa; /* standard timing identifiers */
|
||||
#define ext_standard_timings0 ext_descriptors[1].ext_standard_timings.timings
|
||||
STANDARD_TIMING(ext_standard_timings0[0], 640, STD_ASPECT_4_3, 90); /* 640x480 @ 90 Hz */
|
||||
STANDARD_TIMING(ext_standard_timings0[1], 640, STD_ASPECT_4_3, 120); /* 640x480 @ 120 Hz */
|
||||
STANDARD_TIMING(ext_standard_timings0[2], 800, STD_ASPECT_4_3, 90); /* 800x600 @ 90 Hz */
|
||||
STANDARD_TIMING(ext_standard_timings0[3], 800, STD_ASPECT_4_3, 120); /* 800x600 @ 120 Hz */
|
||||
STANDARD_TIMING(ext_standard_timings0[4], 1024, STD_ASPECT_4_3, 90); /* 1024x768 @ 90 Hz */
|
||||
STANDARD_TIMING(ext_standard_timings0[5], 1280, STD_ASPECT_5_4, 90); /* 1280x1024 @ 90 Hz */
|
||||
STANDARD_TIMING(ext_standard_timings0[0], 640, STD_ASPECT_4_3, 90); /* 640x480 @ 90 Hz */
|
||||
STANDARD_TIMING(ext_standard_timings0[1], 640, STD_ASPECT_4_3, 120); /* 640x480 @ 120 Hz */
|
||||
STANDARD_TIMING(ext_standard_timings0[2], 800, STD_ASPECT_4_3, 90); /* 800x600 @ 90 Hz */
|
||||
STANDARD_TIMING(ext_standard_timings0[3], 800, STD_ASPECT_4_3, 120); /* 800x600 @ 120 Hz */
|
||||
STANDARD_TIMING(ext_standard_timings0[4], 1024, STD_ASPECT_4_3, 90); /* 1024x768 @ 90 Hz */
|
||||
STANDARD_TIMING(ext_standard_timings0[5], 1280, STD_ASPECT_5_4, 90); /* 1280x1024 @ 90 Hz */
|
||||
edid->ext_descriptors[1].ext_standard_timings.padding = 0x0a;
|
||||
|
||||
for (uint8_t c = 128; c < 255; c++)
|
||||
@@ -225,7 +224,6 @@ ddc_init(void *i2c)
|
||||
return i2c_eeprom_init(i2c, 0x50, edid_bytes, sizeof(edid_t), 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ddc_close(void *eeprom)
|
||||
{
|
||||
|
||||
1694
src/video/vid_ega.c
1694
src/video/vid_ega.c
File diff suppressed because it is too large
Load Diff
@@ -29,174 +29,172 @@
|
||||
#include <86box/vid_ega.h>
|
||||
#include <86box/vid_ega_render_remap.h>
|
||||
|
||||
|
||||
int
|
||||
ega_display_line(ega_t *ega)
|
||||
{
|
||||
int y_add = (enable_overscan) ? (overscan_y >> 1) : 0;
|
||||
unsigned int dl = ega->displine;
|
||||
int y_add = (enable_overscan) ? (overscan_y >> 1) : 0;
|
||||
unsigned int dl = ega->displine;
|
||||
|
||||
if (ega->crtc[9] & 0x1f)
|
||||
dl -= (ega->crtc[8] & 0x1f);
|
||||
dl -= (ega->crtc[8] & 0x1f);
|
||||
|
||||
dl += y_add;
|
||||
dl &= 0x7ff;
|
||||
return dl;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ega_render_blank(ega_t *ega)
|
||||
{
|
||||
int x, xx;
|
||||
|
||||
if ((ega->displine + ega->y_add) < 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
for (x = 0; x < (ega->hdisp + ega->scrollcache); x++) {
|
||||
switch (ega->seqregs[1] & 9) {
|
||||
case 0:
|
||||
for (xx = 0; xx < 9; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 9) + xx] = 0;
|
||||
break;
|
||||
case 1:
|
||||
for (xx = 0; xx < 8; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 8) + xx] = 0;
|
||||
break;
|
||||
case 8:
|
||||
for (xx = 0; xx < 18; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 18) + xx] = 0;
|
||||
break;
|
||||
case 9:
|
||||
for (xx = 0; xx < 16; xx++) buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 16) + xx] = 0;
|
||||
break;
|
||||
}
|
||||
switch (ega->seqregs[1] & 9) {
|
||||
case 0:
|
||||
for (xx = 0; xx < 9; xx++)
|
||||
buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 9) + xx] = 0;
|
||||
break;
|
||||
case 1:
|
||||
for (xx = 0; xx < 8; xx++)
|
||||
buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 8) + xx] = 0;
|
||||
break;
|
||||
case 8:
|
||||
for (xx = 0; xx < 18; xx++)
|
||||
buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 18) + xx] = 0;
|
||||
break;
|
||||
case 9:
|
||||
for (xx = 0; xx < 16; xx++)
|
||||
buffer32->line[ega->displine + ega->y_add][ega->x_add + (x * 16) + xx] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ega_render_overscan_left(ega_t *ega)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((ega->displine + ega->y_add) < 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (ega->scrblank || (ega->hdisp == 0))
|
||||
return;
|
||||
return;
|
||||
|
||||
for (i = 0; i < ega->x_add; i++)
|
||||
buffer32->line[ega->displine + ega->y_add][i] = ega->overscan_color;
|
||||
buffer32->line[ega->displine + ega->y_add][i] = ega->overscan_color;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ega_render_overscan_right(ega_t *ega)
|
||||
{
|
||||
int i, right;
|
||||
|
||||
if ((ega->displine + ega->y_add) < 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (ega->scrblank || (ega->hdisp == 0))
|
||||
return;
|
||||
return;
|
||||
|
||||
right = (overscan_x >> 1) + ega->scrollcache;
|
||||
for (i = 0; i < right; i++)
|
||||
buffer32->line[ega->displine + ega->y_add][ega->x_add + ega->hdisp + i] = ega->overscan_color;
|
||||
buffer32->line[ega->displine + ega->y_add][ega->x_add + ega->hdisp + i] = ega->overscan_color;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ega_render_text_40(ega_t *ega)
|
||||
{
|
||||
uint32_t *p;
|
||||
int x, xx;
|
||||
int drawcursor, xinc;
|
||||
uint8_t chr, attr, dat;
|
||||
uint32_t charaddr;
|
||||
int fg, bg;
|
||||
uint32_t addr;
|
||||
int x, xx;
|
||||
int drawcursor, xinc;
|
||||
uint8_t chr, attr, dat;
|
||||
uint32_t charaddr;
|
||||
int fg, bg;
|
||||
uint32_t addr;
|
||||
|
||||
if ((ega->displine + ega->y_add) < 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (ega->firstline_draw == 2000)
|
||||
ega->firstline_draw = ega->displine;
|
||||
ega->firstline_draw = ega->displine;
|
||||
ega->lastline_draw = ega->displine;
|
||||
|
||||
if (ega->fullchange) {
|
||||
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
|
||||
xinc = (ega->seqregs[1] & 1) ? 16 : 18;
|
||||
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
|
||||
xinc = (ega->seqregs[1] & 1) ? 16 : 18;
|
||||
|
||||
for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) {
|
||||
addr = ega->remap_func(ega, ega->ma) & ega->vrammask;
|
||||
for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) {
|
||||
addr = ega->remap_func(ega, ega->ma) & ega->vrammask;
|
||||
|
||||
drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron);
|
||||
drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron);
|
||||
|
||||
if (ega->crtc[0x17] & 0x80) {
|
||||
chr = ega->vram[addr];
|
||||
attr = ega->vram[addr + 1];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
if (ega->crtc[0x17] & 0x80) {
|
||||
chr = ega->vram[addr];
|
||||
attr = ega->vram[addr + 1];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
|
||||
if (attr & 8)
|
||||
charaddr = ega->charsetb + ((chr * 0x80));
|
||||
else
|
||||
charaddr = ega->charseta + ((chr * 0x80));
|
||||
if (attr & 8)
|
||||
charaddr = ega->charsetb + ((chr * 0x80));
|
||||
else
|
||||
charaddr = ega->charseta + ((chr * 0x80));
|
||||
|
||||
if (drawcursor) {
|
||||
bg = ega->pallook[ega->egapal[attr & 0x0f]];
|
||||
fg = ega->pallook[ega->egapal[attr >> 4]];
|
||||
} else {
|
||||
fg = ega->pallook[ega->egapal[attr & 0x0f]];
|
||||
bg = ega->pallook[ega->egapal[attr >> 4]];
|
||||
if (drawcursor) {
|
||||
bg = ega->pallook[ega->egapal[attr & 0x0f]];
|
||||
fg = ega->pallook[ega->egapal[attr >> 4]];
|
||||
} else {
|
||||
fg = ega->pallook[ega->egapal[attr & 0x0f]];
|
||||
bg = ega->pallook[ega->egapal[attr >> 4]];
|
||||
|
||||
if ((attr & 0x80) && ega->attrregs[0x10] & 8) {
|
||||
bg = ega->pallook[ega->egapal[(attr >> 4) & 7]];
|
||||
if (ega->blink & 0x10)
|
||||
fg = bg;
|
||||
}
|
||||
}
|
||||
if ((attr & 0x80) && ega->attrregs[0x10] & 8) {
|
||||
bg = ega->pallook[ega->egapal[(attr >> 4) & 7]];
|
||||
if (ega->blink & 0x10)
|
||||
fg = bg;
|
||||
}
|
||||
}
|
||||
|
||||
dat = ega->vram[charaddr + (ega->sc << 2)];
|
||||
if (ega->seqregs[1] & 1) {
|
||||
for (xx = 0; xx < 16; xx += 2)
|
||||
p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg;
|
||||
} else {
|
||||
for (xx = 0; xx < 16; xx += 2)
|
||||
p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg;
|
||||
if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4))
|
||||
p[16] = p[17] = bg;
|
||||
else
|
||||
p[16] = p[17] = (dat & 1) ? fg : bg;
|
||||
}
|
||||
ega->ma += 4;
|
||||
p += xinc;
|
||||
}
|
||||
ega->ma &= ega->vrammask;
|
||||
dat = ega->vram[charaddr + (ega->sc << 2)];
|
||||
if (ega->seqregs[1] & 1) {
|
||||
for (xx = 0; xx < 16; xx += 2)
|
||||
p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg;
|
||||
} else {
|
||||
for (xx = 0; xx < 16; xx += 2)
|
||||
p[xx] = p[xx + 1] = (dat & (0x80 >> (xx >> 1))) ? fg : bg;
|
||||
if ((chr & ~0x1f) != 0xc0 || !(ega->attrregs[0x10] & 4))
|
||||
p[16] = p[17] = bg;
|
||||
else
|
||||
p[16] = p[17] = (dat & 1) ? fg : bg;
|
||||
}
|
||||
ega->ma += 4;
|
||||
p += xinc;
|
||||
}
|
||||
ega->ma &= ega->vrammask;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ega_render_text_80(ega_t *ega)
|
||||
{
|
||||
uint32_t *p;
|
||||
int x, xx;
|
||||
int drawcursor, xinc;
|
||||
uint8_t chr, attr, dat;
|
||||
uint32_t charaddr;
|
||||
int fg, bg;
|
||||
uint32_t addr;
|
||||
int x, xx;
|
||||
int drawcursor, xinc;
|
||||
uint8_t chr, attr, dat;
|
||||
uint32_t charaddr;
|
||||
int fg, bg;
|
||||
uint32_t addr;
|
||||
|
||||
if ((ega->displine + ega->y_add) < 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (ega->firstline_draw == 2000)
|
||||
ega->firstline_draw = ega->displine;
|
||||
ega->firstline_draw = ega->displine;
|
||||
ega->lastline_draw = ega->displine;
|
||||
|
||||
if (ega->fullchange) {
|
||||
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
|
||||
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
|
||||
xinc = (ega->seqregs[1] & 1) ? 8 : 9;
|
||||
|
||||
for (x = 0; x < (ega->hdisp + ega->scrollcache); x += xinc) {
|
||||
@@ -205,8 +203,8 @@ ega_render_text_80(ega_t *ega)
|
||||
drawcursor = ((ega->ma == ega->ca) && ega->con && ega->cursoron);
|
||||
|
||||
if (ega->crtc[0x17] & 0x80) {
|
||||
chr = ega->vram[addr];
|
||||
attr = ega->vram[addr + 1];
|
||||
chr = ega->vram[addr];
|
||||
attr = ega->vram[addr + 1];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
|
||||
@@ -229,7 +227,7 @@ ega_render_text_80(ega_t *ega)
|
||||
}
|
||||
|
||||
dat = ega->vram[charaddr + (ega->sc << 2)];
|
||||
if (ega->seqregs[1] & 1) {
|
||||
if (ega->seqregs[1] & 1) {
|
||||
for (xx = 0; xx < 8; xx++)
|
||||
p[xx] = (dat & (0x80 >> xx)) ? fg : bg;
|
||||
} else {
|
||||
@@ -247,16 +245,15 @@ ega_render_text_80(ega_t *ega)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ega_render_2bpp_lowres(ega_t *ega)
|
||||
{
|
||||
int x;
|
||||
uint8_t dat[2];
|
||||
int x;
|
||||
uint8_t dat[2];
|
||||
uint32_t addr, *p;
|
||||
|
||||
if ((ega->displine + ega->y_add) < 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
|
||||
|
||||
@@ -277,11 +274,11 @@ ega_render_2bpp_lowres(ega_t *ega)
|
||||
ega->ma &= ega->vrammask;
|
||||
|
||||
if (ega->crtc[0x17] & 0x80) {
|
||||
p[0] = p[1] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]];
|
||||
p[2] = p[3] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]];
|
||||
p[4] = p[5] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]];
|
||||
p[6] = p[7] = ega->pallook[ega->egapal[dat[0] & 3]];
|
||||
p[8] = p[9] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]];
|
||||
p[0] = p[1] = ega->pallook[ega->egapal[(dat[0] >> 6) & 3]];
|
||||
p[2] = p[3] = ega->pallook[ega->egapal[(dat[0] >> 4) & 3]];
|
||||
p[4] = p[5] = ega->pallook[ega->egapal[(dat[0] >> 2) & 3]];
|
||||
p[6] = p[7] = ega->pallook[ega->egapal[dat[0] & 3]];
|
||||
p[8] = p[9] = ega->pallook[ega->egapal[(dat[1] >> 6) & 3]];
|
||||
p[10] = p[11] = ega->pallook[ega->egapal[(dat[1] >> 4) & 3]];
|
||||
p[12] = p[13] = ega->pallook[ega->egapal[(dat[1] >> 2) & 3]];
|
||||
p[14] = p[15] = ega->pallook[ega->egapal[dat[1] & 3]];
|
||||
@@ -292,16 +289,15 @@ ega_render_2bpp_lowres(ega_t *ega)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ega_render_2bpp_highres(ega_t *ega)
|
||||
{
|
||||
int x;
|
||||
uint8_t dat[2];
|
||||
int x;
|
||||
uint8_t dat[2];
|
||||
uint32_t addr, *p;
|
||||
|
||||
if ((ega->displine + ega->y_add) < 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
|
||||
|
||||
@@ -337,16 +333,15 @@ ega_render_2bpp_highres(ega_t *ega)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ega_render_4bpp_lowres(ega_t *ega)
|
||||
{
|
||||
int x, oddeven;
|
||||
uint8_t dat, edat[4];
|
||||
int x, oddeven;
|
||||
uint8_t dat, edat[4];
|
||||
uint32_t addr, *p;
|
||||
|
||||
if ((ega->displine + ega->y_add) < 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
|
||||
|
||||
@@ -355,32 +350,32 @@ ega_render_4bpp_lowres(ega_t *ega)
|
||||
ega->lastline_draw = ega->displine;
|
||||
|
||||
for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 16) {
|
||||
addr = ega->remap_func(ega, ega->ma);
|
||||
addr = ega->remap_func(ega, ega->ma);
|
||||
oddeven = 0;
|
||||
|
||||
if (ega->seqregs[1] & 4) {
|
||||
oddeven = (addr & 4) ? 1 : 0;
|
||||
edat[0] = ega->vram[addr | oddeven];
|
||||
edat[2] = ega->vram[addr | oddeven | 0x2];
|
||||
edat[1] = edat[3] = 0;
|
||||
edat[1] = edat[3] = 0;
|
||||
ega->ma += 2;
|
||||
} else {
|
||||
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&ega->vram[addr]);
|
||||
*(uint32_t *) (&edat[0]) = *(uint32_t *) (&ega->vram[addr]);
|
||||
ega->ma += 4;
|
||||
}
|
||||
ega->ma &= ega->vrammask;
|
||||
|
||||
if (ega->crtc[0x17] & 0x80) {
|
||||
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
|
||||
p[0] = p[1] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
|
||||
p[2] = p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
|
||||
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
|
||||
p[4] = p[5] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
|
||||
p[6] = p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
|
||||
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
|
||||
p[8] = p[9] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
|
||||
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
|
||||
p[0] = p[1] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
|
||||
p[2] = p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
|
||||
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
|
||||
p[4] = p[5] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
|
||||
p[6] = p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
|
||||
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
|
||||
p[8] = p[9] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
|
||||
p[10] = p[11] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
|
||||
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
|
||||
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
|
||||
p[12] = p[13] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
|
||||
p[14] = p[15] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
|
||||
} else
|
||||
@@ -390,16 +385,15 @@ ega_render_4bpp_lowres(ega_t *ega)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ega_render_4bpp_highres(ega_t *ega)
|
||||
{
|
||||
int x, oddeven;
|
||||
uint8_t dat, edat[4];
|
||||
int x, oddeven;
|
||||
uint8_t dat, edat[4];
|
||||
uint32_t addr, *p;
|
||||
|
||||
if ((ega->displine + ega->y_add) < 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
p = &buffer32->line[ega->displine + ega->y_add][ega->x_add];
|
||||
|
||||
@@ -408,32 +402,32 @@ ega_render_4bpp_highres(ega_t *ega)
|
||||
ega->lastline_draw = ega->displine;
|
||||
|
||||
for (x = 0; x <= (ega->hdisp + ega->scrollcache); x += 8) {
|
||||
addr = ega->remap_func(ega, ega->ma);
|
||||
addr = ega->remap_func(ega, ega->ma);
|
||||
oddeven = 0;
|
||||
|
||||
if (ega->seqregs[1] & 4) {
|
||||
oddeven = (addr & 4) ? 1 : 0;
|
||||
edat[0] = ega->vram[addr | oddeven];
|
||||
edat[2] = ega->vram[addr | oddeven | 0x2];
|
||||
edat[1] = edat[3] = 0;
|
||||
edat[1] = edat[3] = 0;
|
||||
ega->ma += 2;
|
||||
} else {
|
||||
*(uint32_t *)(&edat[0]) = *(uint32_t *)(&ega->vram[addr]);
|
||||
*(uint32_t *) (&edat[0]) = *(uint32_t *) (&ega->vram[addr]);
|
||||
ega->ma += 4;
|
||||
}
|
||||
ega->ma &= ega->vrammask;
|
||||
|
||||
if (ega->crtc[0x17] & 0x80) {
|
||||
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
|
||||
dat = edatlookup[edat[0] >> 6][edat[1] >> 6] | (edatlookup[edat[2] >> 6][edat[3] >> 6] << 2);
|
||||
p[0] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
|
||||
p[1] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
|
||||
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
|
||||
dat = edatlookup[(edat[0] >> 4) & 3][(edat[1] >> 4) & 3] | (edatlookup[(edat[2] >> 4) & 3][(edat[3] >> 4) & 3] << 2);
|
||||
p[2] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
|
||||
p[3] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
|
||||
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
|
||||
dat = edatlookup[(edat[0] >> 2) & 3][(edat[1] >> 2) & 3] | (edatlookup[(edat[2] >> 2) & 3][(edat[3] >> 2) & 3] << 2);
|
||||
p[4] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
|
||||
p[5] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
|
||||
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
|
||||
dat = edatlookup[edat[0] & 3][edat[1] & 3] | (edatlookup[edat[2] & 3][edat[3] & 3] << 2);
|
||||
p[6] = ega->pallook[ega->egapal[(dat >> 4) & ega->plane_mask]];
|
||||
p[7] = ega->pallook[ega->egapal[dat & ega->plane_mask]];
|
||||
} else
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -33,9 +33,7 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_hercules.h>
|
||||
|
||||
|
||||
static video_timings_t timing_hercules = {VIDEO_ISA, 8, 16, 32, 8, 16, 32};
|
||||
|
||||
static video_timings_t timing_hercules = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
|
||||
|
||||
static void
|
||||
recalc_timings(hercules_t *dev)
|
||||
@@ -43,196 +41,190 @@ recalc_timings(hercules_t *dev)
|
||||
double disptime;
|
||||
double _dispontime, _dispofftime;
|
||||
|
||||
disptime = dev->crtc[0] + 1;
|
||||
disptime = dev->crtc[0] + 1;
|
||||
_dispontime = dev->crtc[1];
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= HERCCONST;
|
||||
_dispontime *= HERCCONST;
|
||||
_dispofftime *= HERCCONST;
|
||||
|
||||
dev->dispontime = (uint64_t)(_dispontime);
|
||||
dev->dispofftime = (uint64_t)(_dispofftime);
|
||||
dev->dispontime = (uint64_t) (_dispontime);
|
||||
dev->dispofftime = (uint64_t) (_dispofftime);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t crtcmask[32] =
|
||||
{
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
static uint8_t crtcmask[32] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static void
|
||||
hercules_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
hercules_t *dev = (hercules_t *)priv;
|
||||
uint8_t old;
|
||||
hercules_t *dev = (hercules_t *) priv;
|
||||
uint8_t old;
|
||||
|
||||
VIDEO_MONITOR_PROLOGUE()
|
||||
switch (addr) {
|
||||
case 0x03b0:
|
||||
case 0x03b2:
|
||||
case 0x03b4:
|
||||
case 0x03b6:
|
||||
dev->crtcreg = val & 31;
|
||||
break;
|
||||
case 0x03b0:
|
||||
case 0x03b2:
|
||||
case 0x03b4:
|
||||
case 0x03b6:
|
||||
dev->crtcreg = val & 31;
|
||||
break;
|
||||
|
||||
case 0x03b1:
|
||||
case 0x03b3:
|
||||
case 0x03b5:
|
||||
case 0x03b7:
|
||||
old = dev->crtc[dev->crtcreg];
|
||||
dev->crtc[dev->crtcreg] = val & crtcmask[dev->crtcreg];
|
||||
case 0x03b1:
|
||||
case 0x03b3:
|
||||
case 0x03b5:
|
||||
case 0x03b7:
|
||||
old = dev->crtc[dev->crtcreg];
|
||||
dev->crtc[dev->crtcreg] = val & crtcmask[dev->crtcreg];
|
||||
|
||||
/*
|
||||
* Fix for Generic Turbo XT BIOS, which
|
||||
* sets up cursor registers wrong.
|
||||
*/
|
||||
if (dev->crtc[10] == 6 && dev->crtc[11] == 7) {
|
||||
dev->crtc[10] = 0xb;
|
||||
dev->crtc[11] = 0xc;
|
||||
}
|
||||
/*
|
||||
* Fix for Generic Turbo XT BIOS, which
|
||||
* sets up cursor registers wrong.
|
||||
*/
|
||||
if (dev->crtc[10] == 6 && dev->crtc[11] == 7) {
|
||||
dev->crtc[10] = 0xb;
|
||||
dev->crtc[11] = 0xc;
|
||||
}
|
||||
|
||||
if (old != val) {
|
||||
if ((dev->crtcreg < 0xe) || (dev->crtcreg > 0x10)) {
|
||||
dev->fullchange = changeframecount;
|
||||
recalc_timings(dev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
if (old != val) {
|
||||
if ((dev->crtcreg < 0xe) || (dev->crtcreg > 0x10)) {
|
||||
dev->fullchange = changeframecount;
|
||||
recalc_timings(dev);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x03b8:
|
||||
old = dev->ctrl;
|
||||
case 0x03b8:
|
||||
old = dev->ctrl;
|
||||
|
||||
/* Prevent setting of bits if they are disabled in CTRL2. */
|
||||
if ((old & 0x02) && !(val & 0x02))
|
||||
dev->ctrl &= 0xfd;
|
||||
else if ((val & 0x02) && (dev->ctrl2 & 0x01))
|
||||
dev->ctrl |= 0x02;
|
||||
/* Prevent setting of bits if they are disabled in CTRL2. */
|
||||
if ((old & 0x02) && !(val & 0x02))
|
||||
dev->ctrl &= 0xfd;
|
||||
else if ((val & 0x02) && (dev->ctrl2 & 0x01))
|
||||
dev->ctrl |= 0x02;
|
||||
|
||||
if ((old & 0x80) && !(val & 0x80))
|
||||
dev->ctrl &= 0x7f;
|
||||
else if ((val & 0x80) && (dev->ctrl2 & 0x02))
|
||||
dev->ctrl |= 0x80;
|
||||
if ((old & 0x80) && !(val & 0x80))
|
||||
dev->ctrl &= 0x7f;
|
||||
else if ((val & 0x80) && (dev->ctrl2 & 0x02))
|
||||
dev->ctrl |= 0x80;
|
||||
|
||||
dev->ctrl = (dev->ctrl & 0x82) | (val & 0x7d);
|
||||
dev->ctrl = (dev->ctrl & 0x82) | (val & 0x7d);
|
||||
|
||||
if (old ^ val)
|
||||
recalc_timings(dev);
|
||||
break;
|
||||
if (old ^ val)
|
||||
recalc_timings(dev);
|
||||
break;
|
||||
|
||||
case 0x03b9:
|
||||
case 0x03bb:
|
||||
dev->lp_ff = !(addr & 0x0002);
|
||||
break;
|
||||
case 0x03b9:
|
||||
case 0x03bb:
|
||||
dev->lp_ff = !(addr & 0x0002);
|
||||
break;
|
||||
|
||||
case 0x03bf:
|
||||
old = dev->ctrl2;
|
||||
dev->ctrl2 = val;
|
||||
/* According to the Programmer's guide to the Hercules graphics cars
|
||||
by David B. Doty from 1988, the CTRL2 modes (bits 1,0) are as follow:
|
||||
- 00: DIAG: Text mode only, only page 0 accessible;
|
||||
- 01: HALF: Graphics mode allowed, only page 0 accessible;
|
||||
- 11: FULL: Graphics mode allowed, both pages accessible. */
|
||||
if (val & 0x01)
|
||||
mem_mapping_set_exec(&dev->mapping, dev->vram);
|
||||
else
|
||||
mem_mapping_set_exec(&dev->mapping, NULL);
|
||||
if (val & 0x02)
|
||||
mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x10000);
|
||||
else
|
||||
mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x08000);
|
||||
if (old ^ val)
|
||||
recalc_timings(dev);
|
||||
break;
|
||||
case 0x03bf:
|
||||
old = dev->ctrl2;
|
||||
dev->ctrl2 = val;
|
||||
/* According to the Programmer's guide to the Hercules graphics cars
|
||||
by David B. Doty from 1988, the CTRL2 modes (bits 1,0) are as follow:
|
||||
- 00: DIAG: Text mode only, only page 0 accessible;
|
||||
- 01: HALF: Graphics mode allowed, only page 0 accessible;
|
||||
- 11: FULL: Graphics mode allowed, both pages accessible. */
|
||||
if (val & 0x01)
|
||||
mem_mapping_set_exec(&dev->mapping, dev->vram);
|
||||
else
|
||||
mem_mapping_set_exec(&dev->mapping, NULL);
|
||||
if (val & 0x02)
|
||||
mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x10000);
|
||||
else
|
||||
mem_mapping_set_addr(&dev->mapping, 0xb0000, 0x08000);
|
||||
if (old ^ val)
|
||||
recalc_timings(dev);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
VIDEO_MONITOR_EPILOGUE()
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
hercules_in(uint16_t addr, void *priv)
|
||||
{
|
||||
hercules_t *dev = (hercules_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
hercules_t *dev = (hercules_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x03b0:
|
||||
case 0x03b2:
|
||||
case 0x03b4:
|
||||
case 0x03b6:
|
||||
ret = dev->crtcreg;
|
||||
break;
|
||||
case 0x03b0:
|
||||
case 0x03b2:
|
||||
case 0x03b4:
|
||||
case 0x03b6:
|
||||
ret = dev->crtcreg;
|
||||
break;
|
||||
|
||||
case 0x03b1:
|
||||
case 0x03b3:
|
||||
case 0x03b5:
|
||||
case 0x03b7:
|
||||
if (dev->crtcreg == 0x0c)
|
||||
ret = (dev->ma >> 8) & 0x3f;
|
||||
else if (dev->crtcreg == 0x0d)
|
||||
ret = dev->ma & 0xff;
|
||||
else
|
||||
ret = dev->crtc[dev->crtcreg];
|
||||
break;
|
||||
case 0x03b1:
|
||||
case 0x03b3:
|
||||
case 0x03b5:
|
||||
case 0x03b7:
|
||||
if (dev->crtcreg == 0x0c)
|
||||
ret = (dev->ma >> 8) & 0x3f;
|
||||
else if (dev->crtcreg == 0x0d)
|
||||
ret = dev->ma & 0xff;
|
||||
else
|
||||
ret = dev->crtc[dev->crtcreg];
|
||||
break;
|
||||
|
||||
case 0x03ba:
|
||||
ret = 0x70; /* Hercules ident */
|
||||
ret |= (dev->lp_ff ? 2 : 0);
|
||||
ret |= (dev->stat & 0x01);
|
||||
if (dev->stat & 0x08)
|
||||
ret |= 0x80;
|
||||
if ((ret & 0x81) == 0x80)
|
||||
ret |= 0x08;
|
||||
break;
|
||||
case 0x03ba:
|
||||
ret = 0x70; /* Hercules ident */
|
||||
ret |= (dev->lp_ff ? 2 : 0);
|
||||
ret |= (dev->stat & 0x01);
|
||||
if (dev->stat & 0x08)
|
||||
ret |= 0x80;
|
||||
if ((ret & 0x81) == 0x80)
|
||||
ret |= 0x08;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hercules_waitstates(void *p)
|
||||
{
|
||||
int ws_array[16] = {3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8};
|
||||
int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 };
|
||||
int ws;
|
||||
|
||||
ws = ws_array[cycles & 0xf];
|
||||
cycles -= ws;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hercules_write(uint32_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
hercules_t *dev = (hercules_t *)priv;
|
||||
hercules_t *dev = (hercules_t *) priv;
|
||||
|
||||
if (dev->ctrl2 & 0x01)
|
||||
addr &= 0xffff;
|
||||
addr &= 0xffff;
|
||||
else
|
||||
addr &= 0x0fff;
|
||||
addr &= 0x0fff;
|
||||
|
||||
dev->vram[addr] = val;
|
||||
|
||||
hercules_waitstates(dev);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
hercules_read(uint32_t addr, void *priv)
|
||||
{
|
||||
hercules_t *dev = (hercules_t *)priv;
|
||||
uint8_t ret = 0xff;
|
||||
hercules_t *dev = (hercules_t *) priv;
|
||||
uint8_t ret = 0xff;
|
||||
|
||||
if (dev->ctrl2 & 0x01)
|
||||
addr &= 0xffff;
|
||||
addr &= 0xffff;
|
||||
else
|
||||
addr &= 0x0fff;
|
||||
addr &= 0x0fff;
|
||||
|
||||
hercules_waitstates(dev);
|
||||
|
||||
@@ -241,333 +233,325 @@ hercules_read(uint32_t addr, void *priv)
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hercules_render_overscan_left(hercules_t *dev)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
uint32_t width;
|
||||
|
||||
if (dev->ctrl & 0x02)
|
||||
width = (((uint32_t) dev->crtc[1]) << 4);
|
||||
width = (((uint32_t) dev->crtc[1]) << 4);
|
||||
else
|
||||
width = (((uint32_t) dev->crtc[1]) * 9);
|
||||
width = (((uint32_t) dev->crtc[1]) * 9);
|
||||
|
||||
if ((dev->displine + 14) < 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (width == 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
buffer32->line[dev->displine + 14][i] = 0x00000000;
|
||||
buffer32->line[dev->displine + 14][i] = 0x00000000;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hercules_render_overscan_right(hercules_t *dev)
|
||||
{
|
||||
int i;
|
||||
int i;
|
||||
uint32_t width;
|
||||
|
||||
if (dev->ctrl & 0x02)
|
||||
width = (((uint32_t) dev->crtc[1]) << 4);
|
||||
width = (((uint32_t) dev->crtc[1]) << 4);
|
||||
else
|
||||
width = (((uint32_t) dev->crtc[1]) * 9);
|
||||
width = (((uint32_t) dev->crtc[1]) * 9);
|
||||
|
||||
if ((dev->displine + 14) < 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (width == 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
buffer32->line[dev->displine + 14][8 + width + i] = 0x00000000;
|
||||
buffer32->line[dev->displine + 14][8 + width + i] = 0x00000000;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hercules_poll(void *priv)
|
||||
{
|
||||
hercules_t *dev = (hercules_t *)priv;
|
||||
uint8_t chr, attr;
|
||||
uint16_t ca, dat;
|
||||
uint16_t pa;
|
||||
int oldsc, blink;
|
||||
int x, xx, y, yy, c, oldvc;
|
||||
int drawcursor;
|
||||
uint32_t *p;
|
||||
hercules_t *dev = (hercules_t *) priv;
|
||||
uint8_t chr, attr;
|
||||
uint16_t ca, dat;
|
||||
uint16_t pa;
|
||||
int oldsc, blink;
|
||||
int x, xx, y, yy, c, oldvc;
|
||||
int drawcursor;
|
||||
uint32_t *p;
|
||||
|
||||
VIDEO_MONITOR_PROLOGUE()
|
||||
ca = (dev->crtc[15] | (dev->crtc[14] << 8)) & 0x3fff;
|
||||
|
||||
if (! dev->linepos) {
|
||||
timer_advance_u64(&dev->timer, dev->dispofftime);
|
||||
dev->stat |= 1;
|
||||
dev->linepos = 1;
|
||||
oldsc = dev->sc;
|
||||
if (!dev->linepos) {
|
||||
timer_advance_u64(&dev->timer, dev->dispofftime);
|
||||
dev->stat |= 1;
|
||||
dev->linepos = 1;
|
||||
oldsc = dev->sc;
|
||||
|
||||
if ((dev->crtc[8] & 3) == 3)
|
||||
dev->sc = (dev->sc << 1) & 7;
|
||||
if ((dev->crtc[8] & 3) == 3)
|
||||
dev->sc = (dev->sc << 1) & 7;
|
||||
|
||||
if (dev->dispon) {
|
||||
if (dev->displine < dev->firstline) {
|
||||
dev->firstline = dev->displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
dev->lastline = dev->displine;
|
||||
if (dev->dispon) {
|
||||
if (dev->displine < dev->firstline) {
|
||||
dev->firstline = dev->displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
dev->lastline = dev->displine;
|
||||
|
||||
hercules_render_overscan_left(dev);
|
||||
hercules_render_overscan_left(dev);
|
||||
|
||||
if (dev->ctrl & 0x02) {
|
||||
ca = (dev->sc & 3) * 0x2000;
|
||||
if (dev->ctrl & 0x80)
|
||||
ca += 0x8000;
|
||||
if (dev->ctrl & 0x02) {
|
||||
ca = (dev->sc & 3) * 0x2000;
|
||||
if (dev->ctrl & 0x80)
|
||||
ca += 0x8000;
|
||||
|
||||
for (x = 0; x < dev->crtc[1]; x++) {
|
||||
if (dev->ctrl & 8)
|
||||
dat = (dev->vram[((dev->ma << 1) & 0x1fff) + ca] << 8) | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 1];
|
||||
else
|
||||
dat = 0;
|
||||
dev->ma++;
|
||||
for (c = 0; c < 16; c++)
|
||||
buffer32->line[dev->displine + 14][(x << 4) + c + 8] = (dat & (32768 >> c)) ? 7 : 0;
|
||||
for (c = 0; c < 16; c += 8)
|
||||
video_blend((x << 4) + c + 8, dev->displine + 14);
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < dev->crtc[1]; x++) {
|
||||
if (dev->ctrl & 8) {
|
||||
/* Undocumented behavior: page 1 in text mode means characters are read
|
||||
from page 1 and attributes from page 0. */
|
||||
chr = dev->charbuffer[x << 1];
|
||||
attr = dev->charbuffer[(x << 1) + 1];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron);
|
||||
blink = ((dev->blink & 16) && (dev->ctrl & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
for (x = 0; x < dev->crtc[1]; x++) {
|
||||
if (dev->ctrl & 8)
|
||||
dat = (dev->vram[((dev->ma << 1) & 0x1fff) + ca] << 8) | dev->vram[((dev->ma << 1) & 0x1fff) + ca + 1];
|
||||
else
|
||||
dat = 0;
|
||||
dev->ma++;
|
||||
for (c = 0; c < 16; c++)
|
||||
buffer32->line[dev->displine + 14][(x << 4) + c + 8] = (dat & (32768 >> c)) ? 7 : 0;
|
||||
for (c = 0; c < 16; c += 8)
|
||||
video_blend((x << 4) + c + 8, dev->displine + 14);
|
||||
}
|
||||
} else {
|
||||
for (x = 0; x < dev->crtc[1]; x++) {
|
||||
if (dev->ctrl & 8) {
|
||||
/* Undocumented behavior: page 1 in text mode means characters are read
|
||||
from page 1 and attributes from page 0. */
|
||||
chr = dev->charbuffer[x << 1];
|
||||
attr = dev->charbuffer[(x << 1) + 1];
|
||||
} else
|
||||
chr = attr = 0;
|
||||
drawcursor = ((dev->ma == ca) && dev->con && dev->cursoron);
|
||||
blink = ((dev->blink & 16) && (dev->ctrl & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
|
||||
if (dev->sc == 12 && ((attr & 7) == 1)) {
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][1];
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][(fontdatm[chr][dev->sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
if (dev->sc == 12 && ((attr & 7) == 1)) {
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][1];
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[dev->displine + 14][(x * 9) + c + 8] = dev->cols[attr][blink][(fontdatm[chr][dev->sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
|
||||
if ((chr & ~0x1f) == 0xc0)
|
||||
buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][fontdatm[chr][dev->sc] & 1];
|
||||
else
|
||||
buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][0];
|
||||
}
|
||||
if (dev->ctrl2 & 0x01)
|
||||
dev->ma = (dev->ma + 1) & 0x3fff;
|
||||
else
|
||||
dev->ma = (dev->ma + 1) & 0x7ff;
|
||||
if ((chr & ~0x1f) == 0xc0)
|
||||
buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][fontdatm[chr][dev->sc] & 1];
|
||||
else
|
||||
buffer32->line[dev->displine + 14][(x * 9) + 8 + 8] = dev->cols[attr][blink][0];
|
||||
}
|
||||
if (dev->ctrl2 & 0x01)
|
||||
dev->ma = (dev->ma + 1) & 0x3fff;
|
||||
else
|
||||
dev->ma = (dev->ma + 1) & 0x7ff;
|
||||
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer32->line[dev->displine + 14][(x * 9) + c + 8] ^= dev->cols[attr][0][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer32->line[dev->displine + 14][(x * 9) + c + 8] ^= dev->cols[attr][0][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hercules_render_overscan_right(dev);
|
||||
}
|
||||
dev->sc = oldsc;
|
||||
hercules_render_overscan_right(dev);
|
||||
}
|
||||
dev->sc = oldsc;
|
||||
|
||||
if (dev->vc == dev->crtc[7] && !dev->sc)
|
||||
dev->stat |= 8;
|
||||
dev->displine++;
|
||||
if (dev->displine >= 500)
|
||||
dev->displine = 0;
|
||||
if (dev->vc == dev->crtc[7] && !dev->sc)
|
||||
dev->stat |= 8;
|
||||
dev->displine++;
|
||||
if (dev->displine >= 500)
|
||||
dev->displine = 0;
|
||||
} else {
|
||||
timer_advance_u64(&dev->timer, dev->dispontime);
|
||||
timer_advance_u64(&dev->timer, dev->dispontime);
|
||||
|
||||
if (dev->dispon)
|
||||
dev->stat &= ~1;
|
||||
if (dev->dispon)
|
||||
dev->stat &= ~1;
|
||||
|
||||
dev->linepos = 0;
|
||||
if (dev->vsynctime) {
|
||||
dev->vsynctime--;
|
||||
if (! dev->vsynctime)
|
||||
dev->stat &= ~8;
|
||||
}
|
||||
dev->linepos = 0;
|
||||
if (dev->vsynctime) {
|
||||
dev->vsynctime--;
|
||||
if (!dev->vsynctime)
|
||||
dev->stat &= ~8;
|
||||
}
|
||||
|
||||
if (dev->sc == (dev->crtc[11] & 31) ||
|
||||
((dev->crtc[8] & 3)==3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) {
|
||||
dev->con = 0;
|
||||
dev->coff = 1;
|
||||
}
|
||||
if (dev->sc == (dev->crtc[11] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[11] & 31) >> 1))) {
|
||||
dev->con = 0;
|
||||
dev->coff = 1;
|
||||
}
|
||||
|
||||
if (dev->vadj) {
|
||||
dev->sc++;
|
||||
dev->sc &= 31;
|
||||
dev->ma = dev->maback;
|
||||
dev->vadj--;
|
||||
if (! dev->vadj) {
|
||||
dev->dispon = 1;
|
||||
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
dev->sc = 0;
|
||||
}
|
||||
} else if (((dev->crtc[8] & 3) != 3 && dev->sc == dev->crtc[9]) || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) {
|
||||
dev->maback = dev->ma;
|
||||
dev->sc = 0;
|
||||
oldvc = dev->vc;
|
||||
dev->vc++;
|
||||
dev->vc &= 127;
|
||||
if (dev->vadj) {
|
||||
dev->sc++;
|
||||
dev->sc &= 31;
|
||||
dev->ma = dev->maback;
|
||||
dev->vadj--;
|
||||
if (!dev->vadj) {
|
||||
dev->dispon = 1;
|
||||
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
dev->sc = 0;
|
||||
}
|
||||
} else if (((dev->crtc[8] & 3) != 3 && dev->sc == dev->crtc[9]) || ((dev->crtc[8] & 3) == 3 && dev->sc == (dev->crtc[9] >> 1))) {
|
||||
dev->maback = dev->ma;
|
||||
dev->sc = 0;
|
||||
oldvc = dev->vc;
|
||||
dev->vc++;
|
||||
dev->vc &= 127;
|
||||
|
||||
if (dev->vc == dev->crtc[6])
|
||||
dev->dispon = 0;
|
||||
if (dev->vc == dev->crtc[6])
|
||||
dev->dispon = 0;
|
||||
|
||||
if (oldvc == dev->crtc[4]) {
|
||||
dev->vc = 0;
|
||||
dev->vadj = dev->crtc[5];
|
||||
if (! dev->vadj) {
|
||||
dev->dispon = 1;
|
||||
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
}
|
||||
switch (dev->crtc[10] & 0x60) {
|
||||
case 0x20:
|
||||
dev->cursoron = 0;
|
||||
break;
|
||||
case 0x60:
|
||||
dev->cursoron = dev->blink & 0x10;
|
||||
break;
|
||||
default:
|
||||
dev->cursoron = dev->blink & 0x08;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (oldvc == dev->crtc[4]) {
|
||||
dev->vc = 0;
|
||||
dev->vadj = dev->crtc[5];
|
||||
if (!dev->vadj) {
|
||||
dev->dispon = 1;
|
||||
dev->ma = dev->maback = (dev->crtc[13] | (dev->crtc[12] << 8)) & 0x3fff;
|
||||
}
|
||||
switch (dev->crtc[10] & 0x60) {
|
||||
case 0x20:
|
||||
dev->cursoron = 0;
|
||||
break;
|
||||
case 0x60:
|
||||
dev->cursoron = dev->blink & 0x10;
|
||||
break;
|
||||
default:
|
||||
dev->cursoron = dev->blink & 0x08;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dev->vc == dev->crtc[7]) {
|
||||
dev->dispon = 0;
|
||||
dev->displine = 0;
|
||||
if ((dev->crtc[8] & 3) == 3)
|
||||
dev->vsynctime = ((int32_t)dev->crtc[4] * ((dev->crtc[9] >> 1) + 1)) + dev->crtc[5] - dev->crtc[7] + 1;
|
||||
else
|
||||
dev->vsynctime = ((int32_t)dev->crtc[4] * (dev->crtc[9] + 1)) + dev->crtc[5] - dev->crtc[7] + 1;
|
||||
if (dev->crtc[7]) {
|
||||
if (dev->ctrl & 0x02)
|
||||
x = dev->crtc[1] << 4;
|
||||
else
|
||||
x = dev->crtc[1] * 9;
|
||||
if (dev->vc == dev->crtc[7]) {
|
||||
dev->dispon = 0;
|
||||
dev->displine = 0;
|
||||
if ((dev->crtc[8] & 3) == 3)
|
||||
dev->vsynctime = ((int32_t) dev->crtc[4] * ((dev->crtc[9] >> 1) + 1)) + dev->crtc[5] - dev->crtc[7] + 1;
|
||||
else
|
||||
dev->vsynctime = ((int32_t) dev->crtc[4] * (dev->crtc[9] + 1)) + dev->crtc[5] - dev->crtc[7] + 1;
|
||||
if (dev->crtc[7]) {
|
||||
if (dev->ctrl & 0x02)
|
||||
x = dev->crtc[1] << 4;
|
||||
else
|
||||
x = dev->crtc[1] * 9;
|
||||
|
||||
dev->lastline++;
|
||||
y = (dev->lastline - dev->firstline);
|
||||
dev->lastline++;
|
||||
y = (dev->lastline - dev->firstline);
|
||||
|
||||
if ((dev->ctrl & 8) && x && y && ((x != xsize) || (y != ysize) || video_force_resize_get())) {
|
||||
xsize = x;
|
||||
ysize = y;
|
||||
if (xsize < 64) xsize = enable_overscan ? 640 : 656;
|
||||
if (ysize < 32) ysize = 200;
|
||||
if ((dev->ctrl & 8) && x && y && ((x != xsize) || (y != ysize) || video_force_resize_get())) {
|
||||
xsize = x;
|
||||
ysize = y;
|
||||
if (xsize < 64)
|
||||
xsize = enable_overscan ? 640 : 656;
|
||||
if (ysize < 32)
|
||||
ysize = 200;
|
||||
|
||||
set_screen_size(xsize + (enable_overscan ? 16 : 0), ysize + (enable_overscan ? 28 : 0));
|
||||
set_screen_size(xsize + (enable_overscan ? 16 : 0), ysize + (enable_overscan ? 28 : 0));
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
|
||||
if ((x >= 160) && ((y + 1) >= 120)) {
|
||||
/* Draw (overscan_size) lines of overscan on top and bottom. */
|
||||
for (yy = 0; yy < 14; yy++) {
|
||||
p = &(buffer32->line[(dev->firstline + yy) & 0x7ff][0]);
|
||||
if ((x >= 160) && ((y + 1) >= 120)) {
|
||||
/* Draw (overscan_size) lines of overscan on top and bottom. */
|
||||
for (yy = 0; yy < 14; yy++) {
|
||||
p = &(buffer32->line[(dev->firstline + yy) & 0x7ff][0]);
|
||||
|
||||
for (xx = 0; xx < (x + 16); xx++)
|
||||
p[xx] = 0x00000000;
|
||||
}
|
||||
for (xx = 0; xx < (x + 16); xx++)
|
||||
p[xx] = 0x00000000;
|
||||
}
|
||||
|
||||
for (yy = 0; yy < 14; yy++) {
|
||||
p = &(buffer32->line[(dev->firstline + 14 + y + yy) & 0x7ff][0]);
|
||||
for (yy = 0; yy < 14; yy++) {
|
||||
p = &(buffer32->line[(dev->firstline + 14 + y + yy) & 0x7ff][0]);
|
||||
|
||||
for (xx = 0; xx < (x + 16); xx++)
|
||||
p[xx] = 0x00000000;
|
||||
}
|
||||
}
|
||||
for (xx = 0; xx < (x + 16); xx++)
|
||||
p[xx] = 0x00000000;
|
||||
}
|
||||
}
|
||||
|
||||
if (enable_overscan)
|
||||
video_blit_memtoscreen_8(0, dev->firstline, xsize + 16, ysize + 28);
|
||||
else
|
||||
video_blit_memtoscreen_8(8, dev->firstline + 14, xsize, ysize);
|
||||
frames++;
|
||||
// if ((dev->ctrl & 2) && (dev->ctrl2 & 1)) {
|
||||
if (dev->ctrl & 0x02) {
|
||||
video_res_x = dev->crtc[1] * 16;
|
||||
video_res_y = dev->crtc[6] * 4;
|
||||
video_bpp = 1;
|
||||
} else {
|
||||
video_res_x = dev->crtc[1];
|
||||
video_res_y = dev->crtc[6];
|
||||
video_bpp = 0;
|
||||
}
|
||||
}
|
||||
dev->firstline = 1000;
|
||||
dev->lastline = 0;
|
||||
dev->blink++;
|
||||
}
|
||||
} else {
|
||||
dev->sc++;
|
||||
dev->sc &= 31;
|
||||
dev->ma = dev->maback;
|
||||
}
|
||||
if (enable_overscan)
|
||||
video_blit_memtoscreen_8(0, dev->firstline, xsize + 16, ysize + 28);
|
||||
else
|
||||
video_blit_memtoscreen_8(8, dev->firstline + 14, xsize, ysize);
|
||||
frames++;
|
||||
// if ((dev->ctrl & 2) && (dev->ctrl2 & 1)) {
|
||||
if (dev->ctrl & 0x02) {
|
||||
video_res_x = dev->crtc[1] * 16;
|
||||
video_res_y = dev->crtc[6] * 4;
|
||||
video_bpp = 1;
|
||||
} else {
|
||||
video_res_x = dev->crtc[1];
|
||||
video_res_y = dev->crtc[6];
|
||||
video_bpp = 0;
|
||||
}
|
||||
}
|
||||
dev->firstline = 1000;
|
||||
dev->lastline = 0;
|
||||
dev->blink++;
|
||||
}
|
||||
} else {
|
||||
dev->sc++;
|
||||
dev->sc &= 31;
|
||||
dev->ma = dev->maback;
|
||||
}
|
||||
|
||||
if ((dev->sc == (dev->crtc[10] & 31) ||
|
||||
((dev->crtc[8] & 3)==3 && dev->sc == ((dev->crtc[10] & 31) >> 1))))
|
||||
dev->con = 1;
|
||||
if (dev->dispon && !(dev->ctrl & 0x02)) {
|
||||
for (x = 0; x < (dev->crtc[1] << 1); x++) {
|
||||
pa = (dev->ctrl & 0x80) ? ((x & 1) ? 0x0000 : 0x8000) : 0x0000;
|
||||
dev->charbuffer[x] = dev->vram[(((dev->ma << 1) + x) & 0x3fff) + pa];
|
||||
}
|
||||
}
|
||||
if ((dev->sc == (dev->crtc[10] & 31) || ((dev->crtc[8] & 3) == 3 && dev->sc == ((dev->crtc[10] & 31) >> 1))))
|
||||
dev->con = 1;
|
||||
if (dev->dispon && !(dev->ctrl & 0x02)) {
|
||||
for (x = 0; x < (dev->crtc[1] << 1); x++) {
|
||||
pa = (dev->ctrl & 0x80) ? ((x & 1) ? 0x0000 : 0x8000) : 0x0000;
|
||||
dev->charbuffer[x] = dev->vram[(((dev->ma << 1) + x) & 0x3fff) + pa];
|
||||
}
|
||||
}
|
||||
}
|
||||
VIDEO_MONITOR_EPILOGUE()
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
hercules_init(const device_t *info)
|
||||
{
|
||||
hercules_t *dev;
|
||||
int c;
|
||||
int c;
|
||||
|
||||
dev = (hercules_t *)malloc(sizeof(hercules_t));
|
||||
dev = (hercules_t *) malloc(sizeof(hercules_t));
|
||||
memset(dev, 0x00, sizeof(hercules_t));
|
||||
dev->monitor_index = monitor_index_global;
|
||||
|
||||
overscan_x = 16;
|
||||
overscan_y = 28;
|
||||
|
||||
dev->vram = (uint8_t *)malloc(0x10000);
|
||||
dev->vram = (uint8_t *) malloc(0x10000);
|
||||
|
||||
timer_add(&dev->timer, hercules_poll, dev, 1);
|
||||
|
||||
mem_mapping_add(&dev->mapping, 0xb0000, 0x08000,
|
||||
hercules_read,NULL,NULL, hercules_write,NULL,NULL,
|
||||
NULL /*dev->vram*/, MEM_MAPPING_EXTERNAL, dev);
|
||||
hercules_read, NULL, NULL, hercules_write, NULL, NULL,
|
||||
NULL /*dev->vram*/, MEM_MAPPING_EXTERNAL, dev);
|
||||
|
||||
io_sethandler(0x03b0, 16,
|
||||
hercules_in,NULL,NULL, hercules_out,NULL,NULL, dev);
|
||||
hercules_in, NULL, NULL, hercules_out, NULL, NULL, dev);
|
||||
|
||||
for (c = 0; c < 256; c++) {
|
||||
dev->cols[c][0][0] = dev->cols[c][1][0] = dev->cols[c][1][1] = 16;
|
||||
dev->cols[c][0][0] = dev->cols[c][1][0] = dev->cols[c][1][1] = 16;
|
||||
|
||||
if (c & 0x08)
|
||||
dev->cols[c][0][1] = 15 + 16;
|
||||
else
|
||||
dev->cols[c][0][1] = 7 + 16;
|
||||
if (c & 0x08)
|
||||
dev->cols[c][0][1] = 15 + 16;
|
||||
else
|
||||
dev->cols[c][0][1] = 7 + 16;
|
||||
}
|
||||
dev->cols[0x70][0][1] = 16;
|
||||
dev->cols[0x70][0][0] = dev->cols[0x70][1][0] =
|
||||
dev->cols[0x70][1][1] = 16 + 15;
|
||||
dev->cols[0xF0][0][1] = 16;
|
||||
dev->cols[0xF0][0][0] = dev->cols[0xF0][1][0] =
|
||||
dev->cols[0xF0][1][1] = 16 + 15;
|
||||
dev->cols[0x78][0][1] = 16 + 7;
|
||||
dev->cols[0x78][0][0] = dev->cols[0x78][1][0] =
|
||||
dev->cols[0x78][1][1] = 16 + 15;
|
||||
dev->cols[0xF8][0][1] = 16 + 7;
|
||||
dev->cols[0xF8][0][0] = dev->cols[0xF8][1][0] =
|
||||
dev->cols[0xF8][1][1] = 16 + 15;
|
||||
dev->cols[0x70][0][0] = dev->cols[0x70][1][0] = dev->cols[0x70][1][1] = 16 + 15;
|
||||
dev->cols[0xF0][0][1] = 16;
|
||||
dev->cols[0xF0][0][0] = dev->cols[0xF0][1][0] = dev->cols[0xF0][1][1] = 16 + 15;
|
||||
dev->cols[0x78][0][1] = 16 + 7;
|
||||
dev->cols[0x78][0][0] = dev->cols[0x78][1][0] = dev->cols[0x78][1][1] = 16 + 15;
|
||||
dev->cols[0xF8][0][1] = 16 + 7;
|
||||
dev->cols[0xF8][0][0] = dev->cols[0xF8][1][0] = dev->cols[0xF8][1][1] = 16 + 15;
|
||||
dev->cols[0x00][0][1] = dev->cols[0x00][1][1] = 16;
|
||||
dev->cols[0x08][0][1] = dev->cols[0x08][1][1] = 16;
|
||||
dev->cols[0x80][0][1] = dev->cols[0x80][1][1] = 16;
|
||||
@@ -577,7 +561,7 @@ hercules_init(const device_t *info)
|
||||
|
||||
cga_palette = device_get_config_int("rgb_type") << 1;
|
||||
if (cga_palette > 6)
|
||||
cga_palette = 0;
|
||||
cga_palette = 0;
|
||||
cgapal_rebuild();
|
||||
|
||||
herc_blend = device_get_config_int("blend");
|
||||
@@ -587,35 +571,33 @@ hercules_init(const device_t *info)
|
||||
/* Force the LPT3 port to be enabled. */
|
||||
lpt3_init(0x3BC);
|
||||
|
||||
return(dev);
|
||||
return (dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hercules_close(void *priv)
|
||||
{
|
||||
hercules_t *dev = (hercules_t *)priv;
|
||||
hercules_t *dev = (hercules_t *) priv;
|
||||
|
||||
if (!dev)
|
||||
return;
|
||||
return;
|
||||
|
||||
if (dev->vram)
|
||||
free(dev->vram);
|
||||
free(dev->vram);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
speed_changed(void *priv)
|
||||
{
|
||||
hercules_t *dev = (hercules_t *)priv;
|
||||
hercules_t *dev = (hercules_t *) priv;
|
||||
|
||||
recalc_timings(dev);
|
||||
}
|
||||
|
||||
static const device_config_t hercules_config[] = {
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
{
|
||||
.name = "rgb_type",
|
||||
.description = "Display type",
|
||||
@@ -656,15 +638,15 @@ static const device_config_t hercules_config[] = {
|
||||
};
|
||||
|
||||
const device_t hercules_device = {
|
||||
.name = "Hercules",
|
||||
.name = "Hercules",
|
||||
.internal_name = "hercules",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = hercules_init,
|
||||
.close = hercules_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = hercules_init,
|
||||
.close = hercules_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = hercules_config
|
||||
.force_redraw = NULL,
|
||||
.config = hercules_config
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -28,37 +28,32 @@
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
|
||||
|
||||
typedef struct icd2061_t
|
||||
{
|
||||
typedef struct icd2061_t {
|
||||
float freq[3];
|
||||
|
||||
int count, bit_count,
|
||||
unlocked, state;
|
||||
unlocked, state;
|
||||
uint32_t data, ctrl;
|
||||
} icd2061_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_ICD2061_LOG
|
||||
int icd2061_do_log = ENABLE_ICD2061_LOG;
|
||||
|
||||
|
||||
static void
|
||||
icd2061_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (icd2061_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define icd2061_log(fmt, ...)
|
||||
# define icd2061_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
icd2061_write(void *p, int val)
|
||||
{
|
||||
@@ -67,81 +62,79 @@ icd2061_write(void *p, int val)
|
||||
int nd, oc, nc;
|
||||
int a, qa, q, pa, p_, m, ps;
|
||||
|
||||
nd = (val & 2) >> 1; /* Old data. */
|
||||
oc = icd2061->state & 1; /* Old clock. */
|
||||
nc = val & 1; /* New clock. */
|
||||
nd = (val & 2) >> 1; /* Old data. */
|
||||
oc = icd2061->state & 1; /* Old clock. */
|
||||
nc = val & 1; /* New clock. */
|
||||
|
||||
icd2061->state = val;
|
||||
|
||||
if (nc && !oc) { /* Low-to-high transition of CLK. */
|
||||
if (!icd2061->unlocked) {
|
||||
if (nd) { /* DATA high. */
|
||||
icd2061->count++;
|
||||
icd2061_log("Low-to-high transition of CLK with DATA high, %i total\n", icd2061->count);
|
||||
} else { /* DATA low. */
|
||||
if (icd2061->count >= 5) {
|
||||
icd2061->unlocked = 1;
|
||||
icd2061->bit_count = icd2061->data = 0;
|
||||
if (nc && !oc) { /* Low-to-high transition of CLK. */
|
||||
if (!icd2061->unlocked) {
|
||||
if (nd) { /* DATA high. */
|
||||
icd2061->count++;
|
||||
icd2061_log("Low-to-high transition of CLK with DATA high, %i total\n", icd2061->count);
|
||||
} else { /* DATA low. */
|
||||
if (icd2061->count >= 5) {
|
||||
icd2061->unlocked = 1;
|
||||
icd2061->bit_count = icd2061->data = 0;
|
||||
#ifdef ENABLE_ICD2061_LOG
|
||||
icd2061_log("ICD2061 unlocked\n");
|
||||
icd2061_log("ICD2061 unlocked\n");
|
||||
#endif
|
||||
} else {
|
||||
icd2061->count = 0;
|
||||
} else {
|
||||
icd2061->count = 0;
|
||||
#ifdef ENABLE_ICD2061_LOG
|
||||
icd2061_log("ICD2061 locked\n");
|
||||
icd2061_log("ICD2061 locked\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else if (nc) {
|
||||
icd2061->data |= (nd << icd2061->bit_count);
|
||||
icd2061->bit_count++;
|
||||
}
|
||||
}
|
||||
} else if (nc) {
|
||||
icd2061->data |= (nd << icd2061->bit_count);
|
||||
icd2061->bit_count++;
|
||||
|
||||
if (icd2061->bit_count == 26) {
|
||||
icd2061_log("26 bits received, data = %08X\n", icd2061->data);
|
||||
if (icd2061->bit_count == 26) {
|
||||
icd2061_log("26 bits received, data = %08X\n", icd2061->data);
|
||||
|
||||
a = ((icd2061->data >> 22) & 0x07); /* A */
|
||||
icd2061_log("A = %01X\n", a);
|
||||
a = ((icd2061->data >> 22) & 0x07); /* A */
|
||||
icd2061_log("A = %01X\n", a);
|
||||
|
||||
if (a < 3) {
|
||||
pa = ((icd2061->data >> 11) & 0x7f); /* P' (ICD2061) / N' (ICS9161) */
|
||||
m = ((icd2061->data >> 8) & 0x07); /* M (ICD2061) / R (ICS9161) */
|
||||
qa = ((icd2061->data >> 1) & 0x7f); /* Q' (ICD2061) / M' (ICS9161) */
|
||||
if (a < 3) {
|
||||
pa = ((icd2061->data >> 11) & 0x7f); /* P' (ICD2061) / N' (ICS9161) */
|
||||
m = ((icd2061->data >> 8) & 0x07); /* M (ICD2061) / R (ICS9161) */
|
||||
qa = ((icd2061->data >> 1) & 0x7f); /* Q' (ICD2061) / M' (ICS9161) */
|
||||
|
||||
p_ = pa + 3; /* P (ICD2061) / N (ICS9161) */
|
||||
m = 1 << m;
|
||||
q = qa + 2; /* Q (ICD2061) / M (ICS9161) */
|
||||
ps = (icd2061->ctrl & (1 << a)) ? 4 : 2; /* Prescale */
|
||||
p_ = pa + 3; /* P (ICD2061) / N (ICS9161) */
|
||||
m = 1 << m;
|
||||
q = qa + 2; /* Q (ICD2061) / M (ICS9161) */
|
||||
ps = (icd2061->ctrl & (1 << a)) ? 4 : 2; /* Prescale */
|
||||
|
||||
icd2061->freq[a] = ((float)(p_ * ps) / (float)(q * m)) * 14318184.0f;
|
||||
icd2061->freq[a] = ((float) (p_ * ps) / (float) (q * m)) * 14318184.0f;
|
||||
|
||||
icd2061_log("P = %02X, M = %01X, Q = %02X, freq[%i] = %f\n", p_, m, q, a, icd2061->freq[a]);
|
||||
} else if (a == 6) {
|
||||
icd2061->ctrl = ((icd2061->data >> 13) & 0xff);
|
||||
icd2061_log("ctrl = %02X\n", icd2061->ctrl);
|
||||
}
|
||||
icd2061->count = icd2061->bit_count = icd2061->data = 0;
|
||||
icd2061->unlocked = 0;
|
||||
icd2061_log("P = %02X, M = %01X, Q = %02X, freq[%i] = %f\n", p_, m, q, a, icd2061->freq[a]);
|
||||
} else if (a == 6) {
|
||||
icd2061->ctrl = ((icd2061->data >> 13) & 0xff);
|
||||
icd2061_log("ctrl = %02X\n", icd2061->ctrl);
|
||||
}
|
||||
icd2061->count = icd2061->bit_count = icd2061->data = 0;
|
||||
icd2061->unlocked = 0;
|
||||
#ifdef ENABLE_ICD2061_LOG
|
||||
icd2061_log("ICD2061 locked\n");
|
||||
icd2061_log("ICD2061 locked\n");
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
icd2061_getclock(int clock, void *p)
|
||||
{
|
||||
icd2061_t *icd2061 = (icd2061_t *) p;
|
||||
|
||||
if (clock > 2)
|
||||
clock = 2;
|
||||
clock = 2;
|
||||
|
||||
return icd2061->freq[clock];
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
icd2061_init(const device_t *info)
|
||||
{
|
||||
@@ -155,40 +148,39 @@ icd2061_init(const device_t *info)
|
||||
return icd2061;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
icd2061_close(void *priv)
|
||||
{
|
||||
icd2061_t *icd2061 = (icd2061_t *) priv;
|
||||
|
||||
if (icd2061)
|
||||
free(icd2061);
|
||||
free(icd2061);
|
||||
}
|
||||
|
||||
const device_t icd2061_device = {
|
||||
.name = "ICD2061 Clock Generator",
|
||||
.name = "ICD2061 Clock Generator",
|
||||
.internal_name = "icd2061",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = icd2061_init,
|
||||
.close = icd2061_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = icd2061_init,
|
||||
.close = icd2061_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t ics9161_device = {
|
||||
.name = "ICS9161 Clock Generator",
|
||||
.name = "ICS9161 Clock Generator",
|
||||
.internal_name = "ics9161",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = icd2061_init,
|
||||
.close = icd2061_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = icd2061_init,
|
||||
.close = icd2061_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -24,45 +24,39 @@
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
|
||||
|
||||
typedef struct ics2494_t
|
||||
{
|
||||
typedef struct ics2494_t {
|
||||
float freq[16];
|
||||
} ics2494_t;
|
||||
|
||||
|
||||
#ifdef ENABLE_ics2494_LOG
|
||||
int ics2494_do_log = ENABLE_ics2494_LOG;
|
||||
|
||||
|
||||
static void
|
||||
ics2494_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (ics2494_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define ics2494_log(fmt, ...)
|
||||
# define ics2494_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
float
|
||||
ics2494_getclock(int clock, void *p)
|
||||
{
|
||||
ics2494_t *ics2494 = (ics2494_t *) p;
|
||||
|
||||
if (clock > 16)
|
||||
clock = 16;
|
||||
clock = 16;
|
||||
|
||||
return ics2494->freq[clock];
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ics2494_init(const device_t *info)
|
||||
{
|
||||
@@ -70,50 +64,49 @@ ics2494_init(const device_t *info)
|
||||
memset(ics2494, 0, sizeof(ics2494_t));
|
||||
|
||||
switch (info->local) {
|
||||
case 305:
|
||||
/* ICS2494A(N)-205 for S3 86C924 */
|
||||
ics2494->freq[0x0] = 25175000.0;
|
||||
ics2494->freq[0x1] = 28322000.0;
|
||||
ics2494->freq[0x2] = 40000000.0;
|
||||
ics2494->freq[0x3] = 0.0;
|
||||
ics2494->freq[0x4] = 50000000.0;
|
||||
ics2494->freq[0x5] = 77000000.0;
|
||||
ics2494->freq[0x6] = 36000000.0;
|
||||
ics2494->freq[0x7] = 44889000.0;
|
||||
ics2494->freq[0x8] = 130000000.0;
|
||||
ics2494->freq[0x9] = 120000000.0;
|
||||
ics2494->freq[0xa] = 80000000.0;
|
||||
ics2494->freq[0xb] = 31500000.0;
|
||||
ics2494->freq[0xc] = 110000000.0;
|
||||
ics2494->freq[0xd] = 65000000.0;
|
||||
ics2494->freq[0xe] = 75000000.0;
|
||||
ics2494->freq[0xf] = 94500000.0;
|
||||
break;
|
||||
case 305:
|
||||
/* ICS2494A(N)-205 for S3 86C924 */
|
||||
ics2494->freq[0x0] = 25175000.0;
|
||||
ics2494->freq[0x1] = 28322000.0;
|
||||
ics2494->freq[0x2] = 40000000.0;
|
||||
ics2494->freq[0x3] = 0.0;
|
||||
ics2494->freq[0x4] = 50000000.0;
|
||||
ics2494->freq[0x5] = 77000000.0;
|
||||
ics2494->freq[0x6] = 36000000.0;
|
||||
ics2494->freq[0x7] = 44889000.0;
|
||||
ics2494->freq[0x8] = 130000000.0;
|
||||
ics2494->freq[0x9] = 120000000.0;
|
||||
ics2494->freq[0xa] = 80000000.0;
|
||||
ics2494->freq[0xb] = 31500000.0;
|
||||
ics2494->freq[0xc] = 110000000.0;
|
||||
ics2494->freq[0xd] = 65000000.0;
|
||||
ics2494->freq[0xe] = 75000000.0;
|
||||
ics2494->freq[0xf] = 94500000.0;
|
||||
break;
|
||||
}
|
||||
|
||||
return ics2494;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ics2494_close(void *priv)
|
||||
{
|
||||
ics2494_t *ics2494 = (ics2494_t *) priv;
|
||||
|
||||
if (ics2494)
|
||||
free(ics2494);
|
||||
free(ics2494);
|
||||
}
|
||||
|
||||
const device_t ics2494an_305_device = {
|
||||
.name = "ICS2494AN-305 Clock Generator",
|
||||
.name = "ICS2494AN-305 Clock Generator",
|
||||
.internal_name = "ics2494an_305",
|
||||
.flags = 0,
|
||||
.local = 305,
|
||||
.init = ics2494_init,
|
||||
.close = ics2494_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 305,
|
||||
.init = ics2494_init,
|
||||
.close = ics2494_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -24,9 +24,7 @@
|
||||
#include <86box/86box.h>
|
||||
#include <86box/device.h>
|
||||
|
||||
|
||||
typedef struct ics2595_t
|
||||
{
|
||||
typedef struct ics2595_t {
|
||||
int oldfs3, oldfs2;
|
||||
int dat;
|
||||
int pos, state;
|
||||
@@ -35,57 +33,52 @@ typedef struct ics2595_t
|
||||
double output_clock;
|
||||
} ics2595_t;
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
ICS2595_IDLE = 0,
|
||||
ICS2595_WRITE,
|
||||
ICS2595_READ
|
||||
enum {
|
||||
ICS2595_IDLE = 0,
|
||||
ICS2595_WRITE,
|
||||
ICS2595_READ
|
||||
};
|
||||
|
||||
|
||||
static int ics2595_div[4] = {8, 4, 2, 1};
|
||||
|
||||
static int ics2595_div[4] = { 8, 4, 2, 1 };
|
||||
|
||||
void
|
||||
ics2595_write(void *p, int strobe, int dat)
|
||||
{
|
||||
ics2595_t *ics2595 = (ics2595_t *) p;
|
||||
int d, n;
|
||||
int l;
|
||||
int d, n;
|
||||
int l;
|
||||
|
||||
if (strobe) {
|
||||
if ((dat & 8) && !ics2595->oldfs3) { /*Data clock*/
|
||||
switch (ics2595->state) {
|
||||
case ICS2595_IDLE:
|
||||
ics2595->state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE;
|
||||
ics2595->pos = 0;
|
||||
break;
|
||||
case ICS2595_WRITE:
|
||||
ics2595->dat = (ics2595->dat >> 1);
|
||||
if (dat & 4)
|
||||
ics2595->dat |= (1 << 19);
|
||||
ics2595->pos++;
|
||||
if (ics2595->pos == 20) {
|
||||
l = (ics2595->dat >> 2) & 0xf;
|
||||
n = ((ics2595->dat >> 7) & 255) + 257;
|
||||
d = ics2595_div[(ics2595->dat >> 16) & 3];
|
||||
if ((dat & 8) && !ics2595->oldfs3) { /*Data clock*/
|
||||
switch (ics2595->state) {
|
||||
case ICS2595_IDLE:
|
||||
ics2595->state = (dat & 4) ? ICS2595_WRITE : ICS2595_IDLE;
|
||||
ics2595->pos = 0;
|
||||
break;
|
||||
case ICS2595_WRITE:
|
||||
ics2595->dat = (ics2595->dat >> 1);
|
||||
if (dat & 4)
|
||||
ics2595->dat |= (1 << 19);
|
||||
ics2595->pos++;
|
||||
if (ics2595->pos == 20) {
|
||||
l = (ics2595->dat >> 2) & 0xf;
|
||||
n = ((ics2595->dat >> 7) & 255) + 257;
|
||||
d = ics2595_div[(ics2595->dat >> 16) & 3];
|
||||
|
||||
ics2595->clocks[l] = (14318181.8 * ((double)n / 46.0)) / (double)d;
|
||||
ics2595->state = ICS2595_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
ics2595->clocks[l] = (14318181.8 * ((double) n / 46.0)) / (double) d;
|
||||
ics2595->state = ICS2595_IDLE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ics2595->oldfs2 = dat & 4;
|
||||
ics2595->oldfs3 = dat & 8;
|
||||
ics2595->oldfs2 = dat & 4;
|
||||
ics2595->oldfs3 = dat & 8;
|
||||
}
|
||||
|
||||
ics2595->output_clock = ics2595->clocks[dat];
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
ics2595_init(const device_t *info)
|
||||
{
|
||||
@@ -95,17 +88,15 @@ ics2595_init(const device_t *info)
|
||||
return ics2595;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
ics2595_close(void *priv)
|
||||
{
|
||||
ics2595_t *ics2595 = (ics2595_t *) priv;
|
||||
|
||||
if (ics2595)
|
||||
free(ics2595);
|
||||
free(ics2595);
|
||||
}
|
||||
|
||||
|
||||
double
|
||||
ics2595_getclock(void *p)
|
||||
{
|
||||
@@ -114,7 +105,6 @@ ics2595_getclock(void *p)
|
||||
return ics2595->output_clock;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ics2595_setclock(void *p, double clock)
|
||||
{
|
||||
@@ -124,15 +114,15 @@ ics2595_setclock(void *p, double clock)
|
||||
}
|
||||
|
||||
const device_t ics2595_device = {
|
||||
.name = "ICS2595 clock chip",
|
||||
.name = "ICS2595 clock chip",
|
||||
.internal_name = "ics2595",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = ics2595_init,
|
||||
.close = ics2595_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = ics2595_init,
|
||||
.close = ics2595_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -34,305 +34,310 @@
|
||||
|
||||
static int mdacols[256][2][2];
|
||||
|
||||
static video_timings_t timing_mda = {VIDEO_ISA, 8, 16, 32, 8, 16, 32};
|
||||
static video_timings_t timing_mda = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
|
||||
|
||||
void mda_recalctimings(mda_t *mda);
|
||||
|
||||
void mda_out(uint16_t addr, uint8_t val, void *p)
|
||||
void
|
||||
mda_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *)p;
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6:
|
||||
mda->crtcreg = val & 31;
|
||||
return;
|
||||
case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7:
|
||||
mda->crtc[mda->crtcreg] = val;
|
||||
if (mda->crtc[10] == 6 && mda->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
|
||||
{
|
||||
mda->crtc[10] = 0xb;
|
||||
mda->crtc[11] = 0xc;
|
||||
mda_t *mda = (mda_t *) p;
|
||||
switch (addr) {
|
||||
case 0x3b0:
|
||||
case 0x3b2:
|
||||
case 0x3b4:
|
||||
case 0x3b6:
|
||||
mda->crtcreg = val & 31;
|
||||
return;
|
||||
case 0x3b1:
|
||||
case 0x3b3:
|
||||
case 0x3b5:
|
||||
case 0x3b7:
|
||||
mda->crtc[mda->crtcreg] = val;
|
||||
if (mda->crtc[10] == 6 && mda->crtc[11] == 7) /*Fix for Generic Turbo XT BIOS, which sets up cursor registers wrong*/
|
||||
{
|
||||
mda->crtc[10] = 0xb;
|
||||
mda->crtc[11] = 0xc;
|
||||
}
|
||||
mda_recalctimings(mda);
|
||||
return;
|
||||
case 0x3b8:
|
||||
mda->ctrl = val;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t
|
||||
mda_in(uint16_t addr, void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *) p;
|
||||
switch (addr) {
|
||||
case 0x3b0:
|
||||
case 0x3b2:
|
||||
case 0x3b4:
|
||||
case 0x3b6:
|
||||
return mda->crtcreg;
|
||||
case 0x3b1:
|
||||
case 0x3b3:
|
||||
case 0x3b5:
|
||||
case 0x3b7:
|
||||
return mda->crtc[mda->crtcreg];
|
||||
case 0x3ba:
|
||||
return mda->stat | 0xF0;
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void
|
||||
mda_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *) p;
|
||||
mda->vram[addr & 0xfff] = val;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
mda_read(uint32_t addr, void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *) p;
|
||||
return mda->vram[addr & 0xfff];
|
||||
}
|
||||
|
||||
void
|
||||
mda_recalctimings(mda_t *mda)
|
||||
{
|
||||
double _dispontime, _dispofftime, disptime;
|
||||
disptime = mda->crtc[0] + 1;
|
||||
_dispontime = mda->crtc[1];
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= MDACONST;
|
||||
_dispofftime *= MDACONST;
|
||||
mda->dispontime = (uint64_t) (_dispontime);
|
||||
mda->dispofftime = (uint64_t) (_dispofftime);
|
||||
}
|
||||
|
||||
void
|
||||
mda_poll(void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *) p;
|
||||
uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x, c;
|
||||
int oldvc;
|
||||
uint8_t chr, attr;
|
||||
int oldsc;
|
||||
int blink;
|
||||
|
||||
VIDEO_MONITOR_PROLOGUE()
|
||||
if (!mda->linepos) {
|
||||
timer_advance_u64(&mda->timer, mda->dispofftime);
|
||||
mda->stat |= 1;
|
||||
mda->linepos = 1;
|
||||
oldsc = mda->sc;
|
||||
if ((mda->crtc[8] & 3) == 3)
|
||||
mda->sc = (mda->sc << 1) & 7;
|
||||
if (mda->dispon) {
|
||||
if (mda->displine < mda->firstline) {
|
||||
mda->firstline = mda->displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
mda->lastline = mda->displine;
|
||||
for (x = 0; x < mda->crtc[1]; x++) {
|
||||
chr = mda->vram[(mda->ma << 1) & 0xfff];
|
||||
attr = mda->vram[((mda->ma << 1) + 1) & 0xfff];
|
||||
drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron);
|
||||
blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
if (mda->sc == 12 && ((attr & 7) == 1)) {
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][1];
|
||||
} else {
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][mda->sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
if ((chr & ~0x1f) == 0xc0)
|
||||
buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][mda->sc] & 1];
|
||||
else
|
||||
buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][0];
|
||||
}
|
||||
mda_recalctimings(mda);
|
||||
return;
|
||||
case 0x3b8:
|
||||
mda->ctrl = val;
|
||||
return;
|
||||
mda->ma++;
|
||||
if (drawcursor) {
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer32->line[mda->displine][(x * 9) + c] ^= mdacols[attr][0][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t mda_in(uint16_t addr, void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *)p;
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3b0: case 0x3b2: case 0x3b4: case 0x3b6:
|
||||
return mda->crtcreg;
|
||||
case 0x3b1: case 0x3b3: case 0x3b5: case 0x3b7:
|
||||
return mda->crtc[mda->crtcreg];
|
||||
case 0x3ba:
|
||||
return mda->stat | 0xF0;
|
||||
mda->sc = oldsc;
|
||||
if (mda->vc == mda->crtc[7] && !mda->sc) {
|
||||
mda->stat |= 8;
|
||||
}
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
void mda_write(uint32_t addr, uint8_t val, void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *)p;
|
||||
mda->vram[addr & 0xfff] = val;
|
||||
}
|
||||
|
||||
uint8_t mda_read(uint32_t addr, void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *)p;
|
||||
return mda->vram[addr & 0xfff];
|
||||
}
|
||||
|
||||
void mda_recalctimings(mda_t *mda)
|
||||
{
|
||||
double _dispontime, _dispofftime, disptime;
|
||||
disptime = mda->crtc[0] + 1;
|
||||
_dispontime = mda->crtc[1];
|
||||
_dispofftime = disptime - _dispontime;
|
||||
_dispontime *= MDACONST;
|
||||
_dispofftime *= MDACONST;
|
||||
mda->dispontime = (uint64_t)(_dispontime);
|
||||
mda->dispofftime = (uint64_t)(_dispofftime);
|
||||
}
|
||||
|
||||
void mda_poll(void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *)p;
|
||||
uint16_t ca = (mda->crtc[15] | (mda->crtc[14] << 8)) & 0x3fff;
|
||||
int drawcursor;
|
||||
int x, c;
|
||||
int oldvc;
|
||||
uint8_t chr, attr;
|
||||
int oldsc;
|
||||
int blink;
|
||||
|
||||
VIDEO_MONITOR_PROLOGUE()
|
||||
if (!mda->linepos)
|
||||
{
|
||||
timer_advance_u64(&mda->timer, mda->dispofftime);
|
||||
mda->stat |= 1;
|
||||
mda->linepos = 1;
|
||||
oldsc = mda->sc;
|
||||
if ((mda->crtc[8] & 3) == 3)
|
||||
mda->sc = (mda->sc << 1) & 7;
|
||||
if (mda->dispon)
|
||||
{
|
||||
if (mda->displine < mda->firstline)
|
||||
{
|
||||
mda->firstline = mda->displine;
|
||||
video_wait_for_buffer();
|
||||
}
|
||||
mda->lastline = mda->displine;
|
||||
for (x = 0; x < mda->crtc[1]; x++)
|
||||
{
|
||||
chr = mda->vram[(mda->ma << 1) & 0xfff];
|
||||
attr = mda->vram[((mda->ma << 1) + 1) & 0xfff];
|
||||
drawcursor = ((mda->ma == ca) && mda->con && mda->cursoron);
|
||||
blink = ((mda->blink & 16) && (mda->ctrl & 0x20) && (attr & 0x80) && !drawcursor);
|
||||
if (mda->sc == 12 && ((attr & 7) == 1))
|
||||
{
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][1];
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c = 0; c < 8; c++)
|
||||
buffer32->line[mda->displine][(x * 9) + c] = mdacols[attr][blink][(fontdatm[chr][mda->sc] & (1 << (c ^ 7))) ? 1 : 0];
|
||||
if ((chr & ~0x1f) == 0xc0) buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][fontdatm[chr][mda->sc] & 1];
|
||||
else buffer32->line[mda->displine][(x * 9) + 8] = mdacols[attr][blink][0];
|
||||
}
|
||||
mda->ma++;
|
||||
if (drawcursor)
|
||||
{
|
||||
for (c = 0; c < 9; c++)
|
||||
buffer32->line[mda->displine][(x * 9) + c] ^= mdacols[attr][0][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
mda->sc = oldsc;
|
||||
if (mda->vc == mda->crtc[7] && !mda->sc)
|
||||
{
|
||||
mda->stat |= 8;
|
||||
}
|
||||
mda->displine++;
|
||||
if (mda->displine >= 500)
|
||||
mda->displine=0;
|
||||
mda->displine++;
|
||||
if (mda->displine >= 500)
|
||||
mda->displine = 0;
|
||||
} else {
|
||||
timer_advance_u64(&mda->timer, mda->dispontime);
|
||||
if (mda->dispon)
|
||||
mda->stat &= ~1;
|
||||
mda->linepos = 0;
|
||||
if (mda->vsynctime) {
|
||||
mda->vsynctime--;
|
||||
if (!mda->vsynctime) {
|
||||
mda->stat &= ~8;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
timer_advance_u64(&mda->timer, mda->dispontime);
|
||||
if (mda->dispon) mda->stat&=~1;
|
||||
mda->linepos=0;
|
||||
if (mda->vsynctime)
|
||||
{
|
||||
mda->vsynctime--;
|
||||
if (!mda->vsynctime)
|
||||
{
|
||||
mda->stat&=~8;
|
||||
}
|
||||
}
|
||||
if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1)))
|
||||
{
|
||||
mda->con = 0;
|
||||
mda->coff = 1;
|
||||
}
|
||||
if (mda->vadj)
|
||||
{
|
||||
mda->sc++;
|
||||
mda->sc &= 31;
|
||||
mda->ma = mda->maback;
|
||||
mda->vadj--;
|
||||
if (!mda->vadj)
|
||||
{
|
||||
mda->dispon = 1;
|
||||
mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff;
|
||||
mda->sc = 0;
|
||||
}
|
||||
}
|
||||
else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1)))
|
||||
{
|
||||
mda->maback = mda->ma;
|
||||
mda->sc = 0;
|
||||
oldvc = mda->vc;
|
||||
mda->vc++;
|
||||
mda->vc &= 127;
|
||||
if (mda->vc == mda->crtc[6])
|
||||
mda->dispon=0;
|
||||
if (oldvc == mda->crtc[4])
|
||||
{
|
||||
mda->vc = 0;
|
||||
mda->vadj = mda->crtc[5];
|
||||
if (!mda->vadj) mda->dispon = 1;
|
||||
if (!mda->vadj) mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff;
|
||||
if ((mda->crtc[10] & 0x60) == 0x20) mda->cursoron = 0;
|
||||
else mda->cursoron = mda->blink & 16;
|
||||
}
|
||||
if (mda->vc == mda->crtc[7])
|
||||
{
|
||||
mda->dispon = 0;
|
||||
mda->displine = 0;
|
||||
mda->vsynctime = 16;
|
||||
if (mda->crtc[7])
|
||||
{
|
||||
x = mda->crtc[1] * 9;
|
||||
mda->lastline++;
|
||||
if ((x != xsize) || ((mda->lastline - mda->firstline) != ysize) || video_force_resize_get())
|
||||
{
|
||||
xsize = x;
|
||||
ysize = mda->lastline - mda->firstline;
|
||||
if (xsize < 64) xsize = 656;
|
||||
if (ysize < 32) ysize = 200;
|
||||
set_screen_size(xsize, ysize);
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
video_blit_memtoscreen_8(0, mda->firstline, xsize, ysize);
|
||||
frames++;
|
||||
video_res_x = mda->crtc[1];
|
||||
video_res_y = mda->crtc[6];
|
||||
video_bpp = 0;
|
||||
}
|
||||
mda->firstline = 1000;
|
||||
mda->lastline = 0;
|
||||
mda->blink++;
|
||||
}
|
||||
}
|
||||
if (mda->sc == (mda->crtc[11] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[11] & 31) >> 1))) {
|
||||
mda->con = 0;
|
||||
mda->coff = 1;
|
||||
}
|
||||
if (mda->vadj) {
|
||||
mda->sc++;
|
||||
mda->sc &= 31;
|
||||
mda->ma = mda->maback;
|
||||
mda->vadj--;
|
||||
if (!mda->vadj) {
|
||||
mda->dispon = 1;
|
||||
mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff;
|
||||
mda->sc = 0;
|
||||
}
|
||||
} else if (mda->sc == mda->crtc[9] || ((mda->crtc[8] & 3) == 3 && mda->sc == (mda->crtc[9] >> 1))) {
|
||||
mda->maback = mda->ma;
|
||||
mda->sc = 0;
|
||||
oldvc = mda->vc;
|
||||
mda->vc++;
|
||||
mda->vc &= 127;
|
||||
if (mda->vc == mda->crtc[6])
|
||||
mda->dispon = 0;
|
||||
if (oldvc == mda->crtc[4]) {
|
||||
mda->vc = 0;
|
||||
mda->vadj = mda->crtc[5];
|
||||
if (!mda->vadj)
|
||||
mda->dispon = 1;
|
||||
if (!mda->vadj)
|
||||
mda->ma = mda->maback = (mda->crtc[13] | (mda->crtc[12] << 8)) & 0x3fff;
|
||||
if ((mda->crtc[10] & 0x60) == 0x20)
|
||||
mda->cursoron = 0;
|
||||
else
|
||||
{
|
||||
mda->sc++;
|
||||
mda->sc &= 31;
|
||||
mda->ma = mda->maback;
|
||||
}
|
||||
if ((mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1))))
|
||||
{
|
||||
mda->con = 1;
|
||||
mda->cursoron = mda->blink & 16;
|
||||
}
|
||||
if (mda->vc == mda->crtc[7]) {
|
||||
mda->dispon = 0;
|
||||
mda->displine = 0;
|
||||
mda->vsynctime = 16;
|
||||
if (mda->crtc[7]) {
|
||||
x = mda->crtc[1] * 9;
|
||||
mda->lastline++;
|
||||
if ((x != xsize) || ((mda->lastline - mda->firstline) != ysize) || video_force_resize_get()) {
|
||||
xsize = x;
|
||||
ysize = mda->lastline - mda->firstline;
|
||||
if (xsize < 64)
|
||||
xsize = 656;
|
||||
if (ysize < 32)
|
||||
ysize = 200;
|
||||
set_screen_size(xsize, ysize);
|
||||
|
||||
if (video_force_resize_get())
|
||||
video_force_resize_set(0);
|
||||
}
|
||||
video_blit_memtoscreen_8(0, mda->firstline, xsize, ysize);
|
||||
frames++;
|
||||
video_res_x = mda->crtc[1];
|
||||
video_res_y = mda->crtc[6];
|
||||
video_bpp = 0;
|
||||
}
|
||||
mda->firstline = 1000;
|
||||
mda->lastline = 0;
|
||||
mda->blink++;
|
||||
}
|
||||
} else {
|
||||
mda->sc++;
|
||||
mda->sc &= 31;
|
||||
mda->ma = mda->maback;
|
||||
}
|
||||
VIDEO_MONITOR_EPILOGUE();
|
||||
}
|
||||
|
||||
void mda_init(mda_t *mda)
|
||||
{
|
||||
int c;
|
||||
|
||||
for (c = 0; c < 256; c++)
|
||||
{
|
||||
mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16;
|
||||
if (c & 8) mdacols[c][0][1] = 15 + 16;
|
||||
else mdacols[c][0][1] = 7 + 16;
|
||||
if ((mda->sc == (mda->crtc[10] & 31) || ((mda->crtc[8] & 3) == 3 && mda->sc == ((mda->crtc[10] & 31) >> 1)))) {
|
||||
mda->con = 1;
|
||||
}
|
||||
mdacols[0x70][0][1] = 16;
|
||||
mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15;
|
||||
mdacols[0xF0][0][1] = 16;
|
||||
mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15;
|
||||
mdacols[0x78][0][1] = 16 + 7;
|
||||
mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15;
|
||||
mdacols[0xF8][0][1] = 16 + 7;
|
||||
mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15;
|
||||
mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16;
|
||||
mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16;
|
||||
mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16;
|
||||
mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16;
|
||||
|
||||
overscan_x = overscan_y = 0;
|
||||
mda->monitor_index = monitor_index_global;
|
||||
|
||||
cga_palette = device_get_config_int("rgb_type") << 1;
|
||||
if (cga_palette > 6)
|
||||
{
|
||||
cga_palette = 0;
|
||||
}
|
||||
cgapal_rebuild();
|
||||
|
||||
timer_add(&mda->timer, mda_poll, mda, 1);
|
||||
}
|
||||
VIDEO_MONITOR_EPILOGUE();
|
||||
}
|
||||
|
||||
void *mda_standalone_init(const device_t *info)
|
||||
void
|
||||
mda_init(mda_t *mda)
|
||||
{
|
||||
mda_t *mda = malloc(sizeof(mda_t));
|
||||
memset(mda, 0, sizeof(mda_t));
|
||||
video_inform(VIDEO_FLAG_TYPE_MDA, &timing_mda);
|
||||
int c;
|
||||
|
||||
mda->vram = malloc(0x1000);
|
||||
for (c = 0; c < 256; c++) {
|
||||
mdacols[c][0][0] = mdacols[c][1][0] = mdacols[c][1][1] = 16;
|
||||
if (c & 8)
|
||||
mdacols[c][0][1] = 15 + 16;
|
||||
else
|
||||
mdacols[c][0][1] = 7 + 16;
|
||||
}
|
||||
mdacols[0x70][0][1] = 16;
|
||||
mdacols[0x70][0][0] = mdacols[0x70][1][0] = mdacols[0x70][1][1] = 16 + 15;
|
||||
mdacols[0xF0][0][1] = 16;
|
||||
mdacols[0xF0][0][0] = mdacols[0xF0][1][0] = mdacols[0xF0][1][1] = 16 + 15;
|
||||
mdacols[0x78][0][1] = 16 + 7;
|
||||
mdacols[0x78][0][0] = mdacols[0x78][1][0] = mdacols[0x78][1][1] = 16 + 15;
|
||||
mdacols[0xF8][0][1] = 16 + 7;
|
||||
mdacols[0xF8][0][0] = mdacols[0xF8][1][0] = mdacols[0xF8][1][1] = 16 + 15;
|
||||
mdacols[0x00][0][1] = mdacols[0x00][1][1] = 16;
|
||||
mdacols[0x08][0][1] = mdacols[0x08][1][1] = 16;
|
||||
mdacols[0x80][0][1] = mdacols[0x80][1][1] = 16;
|
||||
mdacols[0x88][0][1] = mdacols[0x88][1][1] = 16;
|
||||
|
||||
mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, mda);
|
||||
io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda);
|
||||
overscan_x = overscan_y = 0;
|
||||
mda->monitor_index = monitor_index_global;
|
||||
|
||||
mda_init(mda);
|
||||
cga_palette = device_get_config_int("rgb_type") << 1;
|
||||
if (cga_palette > 6) {
|
||||
cga_palette = 0;
|
||||
}
|
||||
cgapal_rebuild();
|
||||
|
||||
lpt3_init(0x3BC);
|
||||
|
||||
return mda;
|
||||
timer_add(&mda->timer, mda_poll, mda, 1);
|
||||
}
|
||||
|
||||
void mda_setcol(int chr, int blink, int fg, uint8_t cga_ink)
|
||||
void *
|
||||
mda_standalone_init(const device_t *info)
|
||||
{
|
||||
mdacols[chr][blink][fg] = 16 + cga_ink;
|
||||
mda_t *mda = malloc(sizeof(mda_t));
|
||||
memset(mda, 0, sizeof(mda_t));
|
||||
video_inform(VIDEO_FLAG_TYPE_MDA, &timing_mda);
|
||||
|
||||
mda->vram = malloc(0x1000);
|
||||
|
||||
mem_mapping_add(&mda->mapping, 0xb0000, 0x08000, mda_read, NULL, NULL, mda_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, mda);
|
||||
io_sethandler(0x03b0, 0x0010, mda_in, NULL, NULL, mda_out, NULL, NULL, mda);
|
||||
|
||||
mda_init(mda);
|
||||
|
||||
lpt3_init(0x3BC);
|
||||
|
||||
return mda;
|
||||
}
|
||||
|
||||
void mda_close(void *p)
|
||||
void
|
||||
mda_setcol(int chr, int blink, int fg, uint8_t cga_ink)
|
||||
{
|
||||
mda_t *mda = (mda_t *)p;
|
||||
|
||||
free(mda->vram);
|
||||
free(mda);
|
||||
mdacols[chr][blink][fg] = 16 + cga_ink;
|
||||
}
|
||||
|
||||
void mda_speed_changed(void *p)
|
||||
void
|
||||
mda_close(void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *)p;
|
||||
mda_t *mda = (mda_t *) p;
|
||||
|
||||
mda_recalctimings(mda);
|
||||
free(mda->vram);
|
||||
free(mda);
|
||||
}
|
||||
|
||||
void
|
||||
mda_speed_changed(void *p)
|
||||
{
|
||||
mda_t *mda = (mda_t *) p;
|
||||
|
||||
mda_recalctimings(mda);
|
||||
}
|
||||
|
||||
static const device_config_t mda_config[] = {
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
{
|
||||
.name = "rgb_type",
|
||||
.description = "Display type",
|
||||
@@ -367,15 +372,15 @@ static const device_config_t mda_config[] = {
|
||||
};
|
||||
|
||||
const device_t mda_device = {
|
||||
.name = "MDA",
|
||||
.name = "MDA",
|
||||
.internal_name = "mda",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = mda_standalone_init,
|
||||
.close = mda_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = mda_standalone_init,
|
||||
.close = mda_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = mda_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
.config = mda_config
|
||||
.force_redraw = NULL,
|
||||
.config = mda_config
|
||||
};
|
||||
|
||||
7982
src/video/vid_mga.c
7982
src/video/vid_mga.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -30,19 +30,18 @@
|
||||
#include <86box/vid_svga.h>
|
||||
#include <86box/vid_svga_render.h>
|
||||
|
||||
#define BIOS_037C_PATH "roms/video/oti/bios.bin"
|
||||
#define BIOS_067_AMA932J_PATH "roms/machines/ama932j/OTI067.BIN"
|
||||
#define BIOS_067_M300_08_PATH "roms/machines/m30008/EVC_BIOS.ROM"
|
||||
#define BIOS_067_M300_15_PATH "roms/machines/m30015/EVC_BIOS.ROM"
|
||||
#define BIOS_077_PATH "roms/video/oti/oti077.vbi"
|
||||
|
||||
#define BIOS_037C_PATH "roms/video/oti/bios.bin"
|
||||
#define BIOS_067_AMA932J_PATH "roms/machines/ama932j/OTI067.BIN"
|
||||
#define BIOS_067_M300_08_PATH "roms/machines/m30008/EVC_BIOS.ROM"
|
||||
#define BIOS_067_M300_15_PATH "roms/machines/m30015/EVC_BIOS.ROM"
|
||||
#define BIOS_077_PATH "roms/video/oti/oti077.vbi"
|
||||
|
||||
enum {
|
||||
OTI_037C,
|
||||
OTI_067 = 2,
|
||||
OTI_067_AMA932J,
|
||||
OTI_067_M300 = 4,
|
||||
OTI_077 = 5
|
||||
OTI_077 = 5
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@@ -50,7 +49,7 @@ typedef struct {
|
||||
|
||||
rom_t bios_rom;
|
||||
|
||||
int index;
|
||||
int index;
|
||||
uint8_t regs[32];
|
||||
|
||||
uint8_t chip_id;
|
||||
@@ -62,396 +61,400 @@ typedef struct {
|
||||
uint32_t vram_mask;
|
||||
} oti_t;
|
||||
|
||||
static video_timings_t timing_oti = {VIDEO_ISA, 6, 8,16, 6, 8,16};
|
||||
|
||||
static video_timings_t timing_oti = { .type = VIDEO_ISA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 };
|
||||
|
||||
static void
|
||||
oti_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
oti_t *oti = (oti_t *)p;
|
||||
oti_t *oti = (oti_t *) p;
|
||||
svga_t *svga = &oti->svga;
|
||||
uint8_t old;
|
||||
uint8_t idx, enable;
|
||||
|
||||
if (!oti->chip_id && !(oti->enable_register & 1) && (addr != 0x3C3))
|
||||
return;
|
||||
return;
|
||||
|
||||
if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) &&
|
||||
!(svga->miscout & 1)) addr ^= 0x60;
|
||||
if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3C3:
|
||||
if (!oti->chip_id) {
|
||||
oti->enable_register = val & 1;
|
||||
return;
|
||||
} else
|
||||
break;
|
||||
break;
|
||||
case 0x3C3:
|
||||
if (!oti->chip_id) {
|
||||
oti->enable_register = val & 1;
|
||||
return;
|
||||
} else
|
||||
break;
|
||||
break;
|
||||
|
||||
case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9:
|
||||
if (oti->chip_id == OTI_077)
|
||||
sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga);
|
||||
else
|
||||
svga_out(addr, val, svga);
|
||||
return;
|
||||
case 0x3c6:
|
||||
case 0x3c7:
|
||||
case 0x3c8:
|
||||
case 0x3c9:
|
||||
if (oti->chip_id == OTI_077)
|
||||
sc1148x_ramdac_out(addr, 0, val, svga->ramdac, svga);
|
||||
else
|
||||
svga_out(addr, val, svga);
|
||||
return;
|
||||
|
||||
case 0x3D4:
|
||||
if (oti->chip_id)
|
||||
svga->crtcreg = val & 0x3f;
|
||||
else
|
||||
svga->crtcreg = val; /* FIXME: The BIOS wants to set the test bit? */
|
||||
return;
|
||||
case 0x3D4:
|
||||
if (oti->chip_id)
|
||||
svga->crtcreg = val & 0x3f;
|
||||
else
|
||||
svga->crtcreg = val; /* FIXME: The BIOS wants to set the test bit? */
|
||||
return;
|
||||
|
||||
case 0x3D5:
|
||||
if (oti->chip_id && (svga->crtcreg & 0x20))
|
||||
return;
|
||||
idx = svga->crtcreg;
|
||||
if (!oti->chip_id)
|
||||
idx &= 0x1f;
|
||||
if ((idx < 7) && (svga->crtc[0x11] & 0x80))
|
||||
return;
|
||||
if ((idx == 7) && (svga->crtc[0x11] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
old = svga->crtc[idx];
|
||||
svga->crtc[idx] = val;
|
||||
if (old != val) {
|
||||
if ((idx < 0x0e) || (idx > 0x10)) {
|
||||
if (idx == 0x0c || idx == 0x0d) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x3D5:
|
||||
if (oti->chip_id && (svga->crtcreg & 0x20))
|
||||
return;
|
||||
idx = svga->crtcreg;
|
||||
if (!oti->chip_id)
|
||||
idx &= 0x1f;
|
||||
if ((idx < 7) && (svga->crtc[0x11] & 0x80))
|
||||
return;
|
||||
if ((idx == 7) && (svga->crtc[0x11] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
old = svga->crtc[idx];
|
||||
svga->crtc[idx] = val;
|
||||
if (old != val) {
|
||||
if ((idx < 0x0e) || (idx > 0x10)) {
|
||||
if (idx == 0x0c || idx == 0x0d) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3DE:
|
||||
if (oti->chip_id)
|
||||
oti->index = val & 0x1f;
|
||||
else
|
||||
oti->index = val;
|
||||
return;
|
||||
case 0x3DE:
|
||||
if (oti->chip_id)
|
||||
oti->index = val & 0x1f;
|
||||
else
|
||||
oti->index = val;
|
||||
return;
|
||||
|
||||
case 0x3DF:
|
||||
idx = oti->index;
|
||||
if (!oti->chip_id)
|
||||
idx &= 0x1f;
|
||||
oti->regs[idx] = val;
|
||||
switch (idx) {
|
||||
case 0xD:
|
||||
if (oti->chip_id == OTI_067) {
|
||||
svga->vram_display_mask = (val & 0x0c) ? oti->vram_mask : 0x3ffff;
|
||||
if (!(val & 0x80))
|
||||
svga->vram_display_mask = 0x3ffff;
|
||||
case 0x3DF:
|
||||
idx = oti->index;
|
||||
if (!oti->chip_id)
|
||||
idx &= 0x1f;
|
||||
oti->regs[idx] = val;
|
||||
switch (idx) {
|
||||
case 0xD:
|
||||
if (oti->chip_id == OTI_067) {
|
||||
svga->vram_display_mask = (val & 0x0c) ? oti->vram_mask : 0x3ffff;
|
||||
if (!(val & 0x80))
|
||||
svga->vram_display_mask = 0x3ffff;
|
||||
|
||||
if ((val & 0x80) && oti->vram_size == 256)
|
||||
mem_mapping_disable(&svga->mapping);
|
||||
else
|
||||
mem_mapping_enable(&svga->mapping);
|
||||
} else if (oti->chip_id == OTI_077) {
|
||||
svga->vram_display_mask = (val & 0x0c) ? oti->vram_mask : 0x3ffff;
|
||||
if ((val & 0x80) && oti->vram_size == 256)
|
||||
mem_mapping_disable(&svga->mapping);
|
||||
else
|
||||
mem_mapping_enable(&svga->mapping);
|
||||
} else if (oti->chip_id == OTI_077) {
|
||||
svga->vram_display_mask = (val & 0x0c) ? oti->vram_mask : 0x3ffff;
|
||||
|
||||
switch ((val & 0xc0) >> 6) {
|
||||
case 0x00: /* 256 kB of memory */
|
||||
default:
|
||||
enable = (oti->vram_size >= 256);
|
||||
if (val & 0x0c)
|
||||
svga->vram_display_mask = MIN(oti->vram_mask, 0x3ffff);
|
||||
break;
|
||||
case 0x01: /* 1 MB of memory */
|
||||
case 0x03:
|
||||
enable = (oti->vram_size >= 1024);
|
||||
if (val & 0x0c)
|
||||
svga->vram_display_mask = MIN(oti->vram_mask, 0xfffff);
|
||||
break;
|
||||
case 0x02: /* 512 kB of memory */
|
||||
enable = (oti->vram_size >= 512);
|
||||
if (val & 0x0c)
|
||||
svga->vram_display_mask = MIN(oti->vram_mask, 0x7ffff);
|
||||
break;
|
||||
}
|
||||
switch ((val & 0xc0) >> 6) {
|
||||
case 0x00: /* 256 kB of memory */
|
||||
default:
|
||||
enable = (oti->vram_size >= 256);
|
||||
if (val & 0x0c)
|
||||
svga->vram_display_mask = MIN(oti->vram_mask, 0x3ffff);
|
||||
break;
|
||||
case 0x01: /* 1 MB of memory */
|
||||
case 0x03:
|
||||
enable = (oti->vram_size >= 1024);
|
||||
if (val & 0x0c)
|
||||
svga->vram_display_mask = MIN(oti->vram_mask, 0xfffff);
|
||||
break;
|
||||
case 0x02: /* 512 kB of memory */
|
||||
enable = (oti->vram_size >= 512);
|
||||
if (val & 0x0c)
|
||||
svga->vram_display_mask = MIN(oti->vram_mask, 0x7ffff);
|
||||
break;
|
||||
}
|
||||
|
||||
if (enable)
|
||||
mem_mapping_enable(&svga->mapping);
|
||||
else
|
||||
mem_mapping_disable(&svga->mapping);
|
||||
} else {
|
||||
if (val & 0x80)
|
||||
mem_mapping_disable(&svga->mapping);
|
||||
else
|
||||
mem_mapping_enable(&svga->mapping);
|
||||
}
|
||||
break;
|
||||
if (enable)
|
||||
mem_mapping_enable(&svga->mapping);
|
||||
else
|
||||
mem_mapping_disable(&svga->mapping);
|
||||
} else {
|
||||
if (val & 0x80)
|
||||
mem_mapping_disable(&svga->mapping);
|
||||
else
|
||||
mem_mapping_enable(&svga->mapping);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x11:
|
||||
svga->read_bank = (val & 0xf) * 65536;
|
||||
svga->write_bank = (val >> 4) * 65536;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
case 0x11:
|
||||
svga->read_bank = (val & 0xf) * 65536;
|
||||
svga->write_bank = (val >> 4) * 65536;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
oti_in(uint16_t addr, void *p)
|
||||
{
|
||||
oti_t *oti = (oti_t *)p;
|
||||
oti_t *oti = (oti_t *) p;
|
||||
svga_t *svga = &oti->svga;
|
||||
uint8_t idx, temp;
|
||||
|
||||
if (!oti->chip_id && !(oti->enable_register & 1) && (addr != 0x3C3))
|
||||
return 0xff;
|
||||
return 0xff;
|
||||
|
||||
if ((((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && addr < 0x3de) &&
|
||||
!(svga->miscout & 1)) addr ^= 0x60;
|
||||
if ((((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && addr < 0x3de) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3C2:
|
||||
if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50)
|
||||
temp = 0;
|
||||
else
|
||||
temp = 0x10;
|
||||
break;
|
||||
case 0x3C2:
|
||||
if ((svga->vgapal[0].r + svga->vgapal[0].g + svga->vgapal[0].b) >= 0x50)
|
||||
temp = 0;
|
||||
else
|
||||
temp = 0x10;
|
||||
break;
|
||||
|
||||
case 0x3C3:
|
||||
if (oti->chip_id)
|
||||
temp = svga_in(addr, svga);
|
||||
else
|
||||
temp = oti->enable_register;
|
||||
break;
|
||||
case 0x3C3:
|
||||
if (oti->chip_id)
|
||||
temp = svga_in(addr, svga);
|
||||
else
|
||||
temp = oti->enable_register;
|
||||
break;
|
||||
|
||||
case 0x3c6: case 0x3c7: case 0x3c8: case 0x3c9:
|
||||
if (oti->chip_id == OTI_077)
|
||||
return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga);
|
||||
return svga_in(addr, svga);
|
||||
case 0x3c6:
|
||||
case 0x3c7:
|
||||
case 0x3c8:
|
||||
case 0x3c9:
|
||||
if (oti->chip_id == OTI_077)
|
||||
return sc1148x_ramdac_in(addr, 0, svga->ramdac, svga);
|
||||
return svga_in(addr, svga);
|
||||
|
||||
case 0x3CF:
|
||||
return svga->gdcreg[svga->gdcaddr & 0xf];
|
||||
case 0x3CF:
|
||||
return svga->gdcreg[svga->gdcaddr & 0xf];
|
||||
|
||||
case 0x3D4:
|
||||
temp = svga->crtcreg;
|
||||
break;
|
||||
case 0x3D4:
|
||||
temp = svga->crtcreg;
|
||||
break;
|
||||
|
||||
case 0x3D5:
|
||||
if (oti->chip_id) {
|
||||
if (svga->crtcreg & 0x20)
|
||||
temp = 0xff;
|
||||
else
|
||||
temp = svga->crtc[svga->crtcreg];
|
||||
} else
|
||||
temp = svga->crtc[svga->crtcreg & 0x1f];
|
||||
break;
|
||||
case 0x3D5:
|
||||
if (oti->chip_id) {
|
||||
if (svga->crtcreg & 0x20)
|
||||
temp = 0xff;
|
||||
else
|
||||
temp = svga->crtc[svga->crtcreg];
|
||||
} else
|
||||
temp = svga->crtc[svga->crtcreg & 0x1f];
|
||||
break;
|
||||
|
||||
case 0x3DA:
|
||||
if (oti->chip_id) {
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
}
|
||||
case 0x3DA:
|
||||
if (oti->chip_id) {
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
}
|
||||
|
||||
svga->attrff = 0;
|
||||
/*The OTI-037C BIOS waits for bits 0 and 3 in 0x3da to go low, then reads 0x3da again
|
||||
and expects the diagnostic bits to equal the current border colour. As I understand
|
||||
it, the 0x3da active enable status does not include the border time, so this may be
|
||||
an area where OTI-037C is not entirely VGA compatible.*/
|
||||
svga->cgastat &= ~0x30;
|
||||
/* copy color diagnostic info from the overscan color register */
|
||||
switch (svga->attrregs[0x12] & 0x30)
|
||||
{
|
||||
case 0x00: /* P0 and P2 */
|
||||
if (svga->attrregs[0x11] & 0x01)
|
||||
svga->cgastat |= 0x10;
|
||||
if (svga->attrregs[0x11] & 0x04)
|
||||
svga->cgastat |= 0x20;
|
||||
break;
|
||||
case 0x10: /* P4 and P5 */
|
||||
if (svga->attrregs[0x11] & 0x10)
|
||||
svga->cgastat |= 0x10;
|
||||
if (svga->attrregs[0x11] & 0x20)
|
||||
svga->cgastat |= 0x20;
|
||||
break;
|
||||
case 0x20: /* P1 and P3 */
|
||||
if (svga->attrregs[0x11] & 0x02)
|
||||
svga->cgastat |= 0x10;
|
||||
if (svga->attrregs[0x11] & 0x08)
|
||||
svga->cgastat |= 0x20;
|
||||
break;
|
||||
case 0x30: /* P6 and P7 */
|
||||
if (svga->attrregs[0x11] & 0x40)
|
||||
svga->cgastat |= 0x10;
|
||||
if (svga->attrregs[0x11] & 0x80)
|
||||
svga->cgastat |= 0x20;
|
||||
break;
|
||||
}
|
||||
temp = svga->cgastat;
|
||||
break;
|
||||
svga->attrff = 0;
|
||||
/*The OTI-037C BIOS waits for bits 0 and 3 in 0x3da to go low, then reads 0x3da again
|
||||
and expects the diagnostic bits to equal the current border colour. As I understand
|
||||
it, the 0x3da active enable status does not include the border time, so this may be
|
||||
an area where OTI-037C is not entirely VGA compatible.*/
|
||||
svga->cgastat &= ~0x30;
|
||||
/* copy color diagnostic info from the overscan color register */
|
||||
switch (svga->attrregs[0x12] & 0x30) {
|
||||
case 0x00: /* P0 and P2 */
|
||||
if (svga->attrregs[0x11] & 0x01)
|
||||
svga->cgastat |= 0x10;
|
||||
if (svga->attrregs[0x11] & 0x04)
|
||||
svga->cgastat |= 0x20;
|
||||
break;
|
||||
case 0x10: /* P4 and P5 */
|
||||
if (svga->attrregs[0x11] & 0x10)
|
||||
svga->cgastat |= 0x10;
|
||||
if (svga->attrregs[0x11] & 0x20)
|
||||
svga->cgastat |= 0x20;
|
||||
break;
|
||||
case 0x20: /* P1 and P3 */
|
||||
if (svga->attrregs[0x11] & 0x02)
|
||||
svga->cgastat |= 0x10;
|
||||
if (svga->attrregs[0x11] & 0x08)
|
||||
svga->cgastat |= 0x20;
|
||||
break;
|
||||
case 0x30: /* P6 and P7 */
|
||||
if (svga->attrregs[0x11] & 0x40)
|
||||
svga->cgastat |= 0x10;
|
||||
if (svga->attrregs[0x11] & 0x80)
|
||||
svga->cgastat |= 0x20;
|
||||
break;
|
||||
}
|
||||
temp = svga->cgastat;
|
||||
break;
|
||||
|
||||
case 0x3DE:
|
||||
temp = oti->index;
|
||||
if (oti->chip_id)
|
||||
temp |= (oti->chip_id << 5);
|
||||
break;
|
||||
case 0x3DE:
|
||||
temp = oti->index;
|
||||
if (oti->chip_id)
|
||||
temp |= (oti->chip_id << 5);
|
||||
break;
|
||||
|
||||
case 0x3DF:
|
||||
idx = oti->index;
|
||||
if (!oti->chip_id)
|
||||
idx &= 0x1f;
|
||||
if (idx == 0x10)
|
||||
temp = oti->dipswitch_val;
|
||||
else
|
||||
temp = oti->regs[idx];
|
||||
break;
|
||||
case 0x3DF:
|
||||
idx = oti->index;
|
||||
if (!oti->chip_id)
|
||||
idx &= 0x1f;
|
||||
if (idx == 0x10)
|
||||
temp = oti->dipswitch_val;
|
||||
else
|
||||
temp = oti->regs[idx];
|
||||
break;
|
||||
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
}
|
||||
|
||||
return(temp);
|
||||
return (temp);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
oti_pos_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
oti_t *oti = (oti_t *)p;
|
||||
oti_t *oti = (oti_t *) p;
|
||||
|
||||
if ((val ^ oti->pos) & 8) {
|
||||
if (val & 8)
|
||||
io_sethandler(0x03c0, 32, oti_in, NULL, NULL,
|
||||
oti_out, NULL, NULL, oti);
|
||||
else
|
||||
io_removehandler(0x03c0, 32, oti_in, NULL, NULL,
|
||||
oti_out, NULL, NULL, oti);
|
||||
if (val & 8)
|
||||
io_sethandler(0x03c0, 32, oti_in, NULL, NULL,
|
||||
oti_out, NULL, NULL, oti);
|
||||
else
|
||||
io_removehandler(0x03c0, 32, oti_in, NULL, NULL,
|
||||
oti_out, NULL, NULL, oti);
|
||||
}
|
||||
|
||||
oti->pos = val;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
oti_pos_in(uint16_t addr, void *p)
|
||||
{
|
||||
oti_t *oti = (oti_t *)p;
|
||||
oti_t *oti = (oti_t *) p;
|
||||
|
||||
return(oti->pos);
|
||||
return (oti->pos);
|
||||
}
|
||||
|
||||
|
||||
static float
|
||||
oti_getclock(int clock)
|
||||
{
|
||||
float ret = 0.0;
|
||||
|
||||
switch (clock) {
|
||||
case 0:
|
||||
default:
|
||||
ret = 25175000.0;
|
||||
break;
|
||||
case 1:
|
||||
ret = 28322000.0;
|
||||
break;
|
||||
case 4:
|
||||
ret = 14318000.0;
|
||||
break;
|
||||
case 5:
|
||||
ret = 16257000.0;
|
||||
break;
|
||||
case 7:
|
||||
ret = 35500000.0;
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
ret = 25175000.0;
|
||||
break;
|
||||
case 1:
|
||||
ret = 28322000.0;
|
||||
break;
|
||||
case 4:
|
||||
ret = 14318000.0;
|
||||
break;
|
||||
case 5:
|
||||
ret = 16257000.0;
|
||||
break;
|
||||
case 7:
|
||||
ret = 35500000.0;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
oti_recalctimings(svga_t *svga)
|
||||
{
|
||||
oti_t *oti = (oti_t *)svga->p;
|
||||
int clk_sel = ((svga->miscout >> 2) & 3) | ((oti->regs[0x0d] & 0x20) >> 3);
|
||||
oti_t *oti = (oti_t *) svga->p;
|
||||
int clk_sel = ((svga->miscout >> 2) & 3) | ((oti->regs[0x0d] & 0x20) >> 3);
|
||||
|
||||
svga->clock = (cpuclock * (double)(1ull << 32)) / oti_getclock(clk_sel);
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / oti_getclock(clk_sel);
|
||||
|
||||
if (oti->chip_id > 0) {
|
||||
if (oti->regs[0x14] & 0x08) svga->ma_latch |= 0x10000;
|
||||
if (oti->regs[0x16] & 0x08) svga->ma_latch |= 0x20000;
|
||||
if (oti->regs[0x14] & 0x08)
|
||||
svga->ma_latch |= 0x10000;
|
||||
if (oti->regs[0x16] & 0x08)
|
||||
svga->ma_latch |= 0x20000;
|
||||
|
||||
if (oti->regs[0x14] & 0x01) svga->vtotal += 0x400;
|
||||
if (oti->regs[0x14] & 0x02) svga->dispend += 0x400;
|
||||
if (oti->regs[0x14] & 0x04) svga->vsyncstart += 0x400;
|
||||
if (oti->regs[0x14] & 0x01)
|
||||
svga->vtotal += 0x400;
|
||||
if (oti->regs[0x14] & 0x02)
|
||||
svga->dispend += 0x400;
|
||||
if (oti->regs[0x14] & 0x04)
|
||||
svga->vsyncstart += 0x400;
|
||||
|
||||
svga->interlace = oti->regs[0x14] & 0x80;
|
||||
svga->interlace = oti->regs[0x14] & 0x80;
|
||||
}
|
||||
|
||||
if ((oti->regs[0x0d] & 0x0c) && !(oti->regs[0x0d] & 0x10)) svga->rowoffset <<= 1;
|
||||
if ((oti->regs[0x0d] & 0x0c) && !(oti->regs[0x0d] & 0x10))
|
||||
svga->rowoffset <<= 1;
|
||||
|
||||
if (svga->bpp == 16) {
|
||||
svga->render = svga_render_16bpp_highres;
|
||||
svga->hdisp >>= 1;
|
||||
svga->render = svga_render_16bpp_highres;
|
||||
svga->hdisp >>= 1;
|
||||
} else if (svga->bpp == 15) {
|
||||
svga->render = svga_render_15bpp_highres;
|
||||
svga->hdisp >>= 1;
|
||||
svga->render = svga_render_15bpp_highres;
|
||||
svga->hdisp >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
oti_init(const device_t *info)
|
||||
{
|
||||
oti_t *oti = malloc(sizeof(oti_t));
|
||||
char *romfn = NULL;
|
||||
oti_t *oti = malloc(sizeof(oti_t));
|
||||
char *romfn = NULL;
|
||||
|
||||
memset(oti, 0x00, sizeof(oti_t));
|
||||
oti->chip_id = info->local;
|
||||
|
||||
oti->dipswitch_val = 0x18;
|
||||
|
||||
switch(oti->chip_id) {
|
||||
case OTI_037C:
|
||||
romfn = BIOS_037C_PATH;
|
||||
oti->vram_size = 256;
|
||||
oti->regs[0] = 0x08; /* FIXME: The BIOS wants to read this at index 0? This index is undocumented. */
|
||||
/* io_sethandler(0x03c0, 32,
|
||||
oti_in, NULL, NULL, oti_out, NULL, NULL, oti); */
|
||||
break;
|
||||
switch (oti->chip_id) {
|
||||
case OTI_037C:
|
||||
romfn = BIOS_037C_PATH;
|
||||
oti->vram_size = 256;
|
||||
oti->regs[0] = 0x08; /* FIXME: The BIOS wants to read this at index 0? This index is undocumented. */
|
||||
/* io_sethandler(0x03c0, 32,
|
||||
oti_in, NULL, NULL, oti_out, NULL, NULL, oti); */
|
||||
break;
|
||||
|
||||
case OTI_067_AMA932J:
|
||||
romfn = BIOS_067_AMA932J_PATH;
|
||||
oti->chip_id = 2;
|
||||
oti->vram_size = device_get_config_int("memory");
|
||||
oti->dipswitch_val |= 0x20;
|
||||
oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */
|
||||
io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti);
|
||||
break;
|
||||
case OTI_067_AMA932J:
|
||||
romfn = BIOS_067_AMA932J_PATH;
|
||||
oti->chip_id = 2;
|
||||
oti->vram_size = device_get_config_int("memory");
|
||||
oti->dipswitch_val |= 0x20;
|
||||
oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */
|
||||
io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti);
|
||||
break;
|
||||
|
||||
case OTI_067_M300:
|
||||
if (rom_present(BIOS_067_M300_15_PATH))
|
||||
romfn = BIOS_067_M300_15_PATH;
|
||||
else
|
||||
romfn = BIOS_067_M300_08_PATH;
|
||||
oti->vram_size = device_get_config_int("memory");
|
||||
oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */
|
||||
io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti);
|
||||
break;
|
||||
case OTI_067_M300:
|
||||
if (rom_present(BIOS_067_M300_15_PATH))
|
||||
romfn = BIOS_067_M300_15_PATH;
|
||||
else
|
||||
romfn = BIOS_067_M300_08_PATH;
|
||||
oti->vram_size = device_get_config_int("memory");
|
||||
oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */
|
||||
io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti);
|
||||
break;
|
||||
|
||||
case OTI_067:
|
||||
case OTI_077:
|
||||
romfn = BIOS_077_PATH;
|
||||
oti->vram_size = device_get_config_int("memory");
|
||||
oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */
|
||||
io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti);
|
||||
break;
|
||||
case OTI_067:
|
||||
case OTI_077:
|
||||
romfn = BIOS_077_PATH;
|
||||
oti->vram_size = device_get_config_int("memory");
|
||||
oti->pos = 0x08; /* Tell the BIOS the I/O ports are already enabled to avoid a double I/O handler mess. */
|
||||
io_sethandler(0x46e8, 1, oti_pos_in, NULL, NULL, oti_pos_out, NULL, NULL, oti);
|
||||
break;
|
||||
}
|
||||
|
||||
if (romfn != NULL) {
|
||||
rom_init(&oti->bios_rom, romfn,
|
||||
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
rom_init(&oti->bios_rom, romfn,
|
||||
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
}
|
||||
|
||||
oti->vram_mask = (oti->vram_size << 10) - 1;
|
||||
@@ -459,78 +462,71 @@ oti_init(const device_t *info)
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_oti);
|
||||
|
||||
svga_init(info, &oti->svga, oti, oti->vram_size << 10,
|
||||
oti_recalctimings, oti_in, oti_out, NULL, NULL);
|
||||
oti_recalctimings, oti_in, oti_out, NULL, NULL);
|
||||
|
||||
if (oti->chip_id == OTI_077)
|
||||
oti->svga.ramdac = device_add(&sc11487_ramdac_device); /*Actually a 82c487, probably a clone.*/
|
||||
if (oti->chip_id == OTI_077)
|
||||
oti->svga.ramdac = device_add(&sc11487_ramdac_device); /*Actually a 82c487, probably a clone.*/
|
||||
|
||||
io_sethandler(0x03c0, 32,
|
||||
oti_in, NULL, NULL, oti_out, NULL, NULL, oti);
|
||||
oti_in, NULL, NULL, oti_out, NULL, NULL, oti);
|
||||
|
||||
oti->svga.miscout = 1;
|
||||
oti->svga.packed_chain4 = 1;
|
||||
oti->svga.miscout = 1;
|
||||
oti->svga.packed_chain4 = 1;
|
||||
|
||||
return(oti);
|
||||
return (oti);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
oti_close(void *p)
|
||||
{
|
||||
oti_t *oti = (oti_t *)p;
|
||||
oti_t *oti = (oti_t *) p;
|
||||
|
||||
svga_close(&oti->svga);
|
||||
|
||||
free(oti);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
oti_speed_changed(void *p)
|
||||
{
|
||||
oti_t *oti = (oti_t *)p;
|
||||
oti_t *oti = (oti_t *) p;
|
||||
|
||||
svga_recalctimings(&oti->svga);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
oti_force_redraw(void *p)
|
||||
{
|
||||
oti_t *oti = (oti_t *)p;
|
||||
oti_t *oti = (oti_t *) p;
|
||||
|
||||
oti->svga.fullchange = changeframecount;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
oti037c_available(void)
|
||||
{
|
||||
return(rom_present(BIOS_037C_PATH));
|
||||
return (rom_present(BIOS_037C_PATH));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
oti067_ama932j_available(void)
|
||||
{
|
||||
return(rom_present(BIOS_067_AMA932J_PATH));
|
||||
return (rom_present(BIOS_067_AMA932J_PATH));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
oti067_077_available(void)
|
||||
{
|
||||
return(rom_present(BIOS_077_PATH));
|
||||
return (rom_present(BIOS_077_PATH));
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
oti067_m300_available(void)
|
||||
{
|
||||
if (rom_present(BIOS_067_M300_15_PATH))
|
||||
return(rom_present(BIOS_067_M300_15_PATH));
|
||||
return (rom_present(BIOS_067_M300_15_PATH));
|
||||
else
|
||||
return(rom_present(BIOS_067_M300_08_PATH));
|
||||
return (rom_present(BIOS_067_M300_08_PATH));
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
@@ -615,71 +611,71 @@ static const device_config_t oti077_config[] = {
|
||||
// clang-format on
|
||||
|
||||
const device_t oti037c_device = {
|
||||
.name = "Oak OTI-037C",
|
||||
.name = "Oak OTI-037C",
|
||||
.internal_name = "oti037c",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = oti_init,
|
||||
.close = oti_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = oti_init,
|
||||
.close = oti_close,
|
||||
.reset = NULL,
|
||||
{ .available = oti037c_available },
|
||||
.speed_changed = oti_speed_changed,
|
||||
.force_redraw = oti_force_redraw,
|
||||
.config = NULL
|
||||
.force_redraw = oti_force_redraw,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t oti067_device = {
|
||||
.name = "Oak OTI-067",
|
||||
.name = "Oak OTI-067",
|
||||
.internal_name = "oti067",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 2,
|
||||
.init = oti_init,
|
||||
.close = oti_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 2,
|
||||
.init = oti_init,
|
||||
.close = oti_close,
|
||||
.reset = NULL,
|
||||
{ .available = oti067_077_available },
|
||||
.speed_changed = oti_speed_changed,
|
||||
.force_redraw = oti_force_redraw,
|
||||
.config = oti067_config
|
||||
.force_redraw = oti_force_redraw,
|
||||
.config = oti067_config
|
||||
};
|
||||
|
||||
const device_t oti067_m300_device = {
|
||||
.name = "Oak OTI-067 (Olivetti M300-08/15)",
|
||||
.name = "Oak OTI-067 (Olivetti M300-08/15)",
|
||||
.internal_name = "oti067_m300",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 4,
|
||||
.init = oti_init,
|
||||
.close = oti_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 4,
|
||||
.init = oti_init,
|
||||
.close = oti_close,
|
||||
.reset = NULL,
|
||||
{ .available = oti067_m300_available },
|
||||
.speed_changed = oti_speed_changed,
|
||||
.force_redraw = oti_force_redraw,
|
||||
.config = oti067_config
|
||||
.force_redraw = oti_force_redraw,
|
||||
.config = oti067_config
|
||||
};
|
||||
|
||||
const device_t oti067_ama932j_device = {
|
||||
.name = "Oak OTI-067 (AMA-932J)",
|
||||
.name = "Oak OTI-067 (AMA-932J)",
|
||||
.internal_name = "oti067_ama932j",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 3,
|
||||
.init = oti_init,
|
||||
.close = oti_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 3,
|
||||
.init = oti_init,
|
||||
.close = oti_close,
|
||||
.reset = NULL,
|
||||
{ .available = oti067_ama932j_available },
|
||||
.speed_changed = oti_speed_changed,
|
||||
.force_redraw = oti_force_redraw,
|
||||
.config = oti067_ama932j_config
|
||||
.force_redraw = oti_force_redraw,
|
||||
.config = oti067_ama932j_config
|
||||
};
|
||||
|
||||
const device_t oti077_device = {
|
||||
.name = "Oak OTI-077",
|
||||
.name = "Oak OTI-077",
|
||||
.internal_name = "oti077",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 5,
|
||||
.init = oti_init,
|
||||
.close = oti_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 5,
|
||||
.init = oti_init,
|
||||
.close = oti_close,
|
||||
.reset = NULL,
|
||||
{ .available = oti067_077_available },
|
||||
.speed_changed = oti_speed_changed,
|
||||
.force_redraw = oti_force_redraw,
|
||||
.config = oti077_config
|
||||
.force_redraw = oti_force_redraw,
|
||||
.config = oti077_config
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
2218
src/video/vid_pgc.c
2218
src/video/vid_pgc.c
File diff suppressed because it is too large
Load Diff
@@ -29,86 +29,84 @@
|
||||
#include <86box/vid_svga.h>
|
||||
#include <86box/vid_svga_render.h>
|
||||
|
||||
|
||||
#define BIOS_ROM_PATH "roms/video/rtg/realtekrtg3106.BIN"
|
||||
#define BIOS_ROM_PATH "roms/video/rtg/realtekrtg3106.BIN"
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int type;
|
||||
const char *name;
|
||||
int type;
|
||||
|
||||
svga_t svga;
|
||||
svga_t svga;
|
||||
|
||||
rom_t bios_rom;
|
||||
rom_t bios_rom;
|
||||
|
||||
uint8_t bank3d6,
|
||||
bank3d7;
|
||||
uint8_t bank3d6,
|
||||
bank3d7;
|
||||
|
||||
uint32_t vram_size,
|
||||
vram_mask;
|
||||
uint32_t vram_size,
|
||||
vram_mask;
|
||||
} rtg_t;
|
||||
|
||||
static video_timings_t timing_rtg_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 };
|
||||
|
||||
static video_timings_t timing_rtg_isa = {VIDEO_ISA, 3, 3, 6, 5, 5, 10};
|
||||
|
||||
static void rtg_recalcbanking(rtg_t *dev)
|
||||
static void
|
||||
rtg_recalcbanking(rtg_t *dev)
|
||||
{
|
||||
svga_t *svga = &dev->svga;
|
||||
svga_t *svga = &dev->svga;
|
||||
|
||||
svga->write_bank = (dev->bank3d7 & 0x0f) * 65536;
|
||||
svga->write_bank = (dev->bank3d7 & 0x0f) * 65536;
|
||||
|
||||
if (svga->gdcreg[0x0f] & 4)
|
||||
svga->read_bank = (dev->bank3d6 & 0x0f) * 65536;
|
||||
else
|
||||
svga->read_bank = svga->write_bank;
|
||||
if (svga->gdcreg[0x0f] & 4)
|
||||
svga->read_bank = (dev->bank3d6 & 0x0f) * 65536;
|
||||
else
|
||||
svga->read_bank = svga->write_bank;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
rtg_in(uint16_t addr, void *priv)
|
||||
{
|
||||
rtg_t *dev = (rtg_t *)priv;
|
||||
rtg_t *dev = (rtg_t *) priv;
|
||||
svga_t *svga = &dev->svga;
|
||||
uint8_t ret = 0;
|
||||
uint8_t ret = 0;
|
||||
|
||||
if (((addr & 0xfff0) == 0x3d0 ||
|
||||
(addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60;
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3ce:
|
||||
return svga->gdcaddr;
|
||||
case 0x3ce:
|
||||
return svga->gdcaddr;
|
||||
|
||||
case 0x3cf:
|
||||
if (svga->gdcaddr == 0x0c)
|
||||
return svga->gdcreg[0x0c] | 4;
|
||||
else if ((svga->gdcaddr > 8) && (svga->gdcaddr != 0x0c))
|
||||
return svga->gdcreg[svga->gdcaddr];
|
||||
break;
|
||||
case 0x3cf:
|
||||
if (svga->gdcaddr == 0x0c)
|
||||
return svga->gdcreg[0x0c] | 4;
|
||||
else if ((svga->gdcaddr > 8) && (svga->gdcaddr != 0x0c))
|
||||
return svga->gdcreg[svga->gdcaddr];
|
||||
break;
|
||||
|
||||
case 0x3d4:
|
||||
return svga->crtcreg;
|
||||
case 0x3d4:
|
||||
return svga->crtcreg;
|
||||
|
||||
case 0x3d5:
|
||||
if (!(svga->crtc[0x1e] & 0x80) && (svga->crtcreg > 0x18))
|
||||
return 0xff;
|
||||
if (svga->crtcreg == 0x1a)
|
||||
return dev->type << 6;
|
||||
if (svga->crtcreg == 0x1e) {
|
||||
if (dev->vram_size == 1024)
|
||||
ret = 2;
|
||||
else if (dev->vram_size == 512)
|
||||
ret = 1;
|
||||
else
|
||||
ret = 0;
|
||||
return svga->crtc[0x1e] | ret;
|
||||
}
|
||||
return svga->crtc[svga->crtcreg];
|
||||
case 0x3d5:
|
||||
if (!(svga->crtc[0x1e] & 0x80) && (svga->crtcreg > 0x18))
|
||||
return 0xff;
|
||||
if (svga->crtcreg == 0x1a)
|
||||
return dev->type << 6;
|
||||
if (svga->crtcreg == 0x1e) {
|
||||
if (dev->vram_size == 1024)
|
||||
ret = 2;
|
||||
else if (dev->vram_size == 512)
|
||||
ret = 1;
|
||||
else
|
||||
ret = 0;
|
||||
return svga->crtc[0x1e] | ret;
|
||||
}
|
||||
return svga->crtc[svga->crtcreg];
|
||||
|
||||
case 0x3d6:
|
||||
return dev->bank3d6;
|
||||
case 0x3d6:
|
||||
return dev->bank3d6;
|
||||
|
||||
case 0x3d7:
|
||||
return dev->bank3d7;
|
||||
}
|
||||
case 0x3d7:
|
||||
return dev->bank3d7;
|
||||
}
|
||||
|
||||
return svga_in(addr, svga);
|
||||
}
|
||||
@@ -116,81 +114,80 @@ rtg_in(uint16_t addr, void *priv)
|
||||
static void
|
||||
rtg_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
rtg_t *dev = (rtg_t *)priv;
|
||||
rtg_t *dev = (rtg_t *) priv;
|
||||
svga_t *svga = &dev->svga;
|
||||
uint8_t old;
|
||||
|
||||
if (((addr & 0xfff0) == 0x3d0 ||
|
||||
(addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) addr ^= 0x60;
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3ce:
|
||||
svga->gdcaddr = val;
|
||||
return;
|
||||
case 0x3ce:
|
||||
svga->gdcaddr = val;
|
||||
return;
|
||||
|
||||
case 0x3cf:
|
||||
if (svga->gdcaddr > 8) {
|
||||
svga->gdcreg[svga->gdcaddr] = val;
|
||||
case 0x3cf:
|
||||
if (svga->gdcaddr > 8) {
|
||||
svga->gdcreg[svga->gdcaddr] = val;
|
||||
|
||||
switch (svga->gdcaddr) {
|
||||
case 0x0b:
|
||||
case 0x0c:
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
switch (svga->gdcaddr) {
|
||||
case 0x0b:
|
||||
case 0x0c:
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
|
||||
case 0x0f:
|
||||
rtg_recalcbanking(dev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x0f:
|
||||
rtg_recalcbanking(dev);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3d4:
|
||||
svga->crtcreg = val & 0x3f;
|
||||
return;
|
||||
case 0x3d4:
|
||||
svga->crtcreg = val & 0x3f;
|
||||
return;
|
||||
|
||||
case 0x3d5:
|
||||
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
|
||||
return;
|
||||
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
case 0x3d5:
|
||||
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
|
||||
return;
|
||||
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
|
||||
if (svga->crtc[0x1e] & 0x80) {
|
||||
switch (svga->crtcreg) {
|
||||
case 0x19:
|
||||
svga->vram_display_mask = (val & 0x20) ? dev->vram_mask : 0x3ffff;
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (svga->crtc[0x1e] & 0x80) {
|
||||
switch (svga->crtcreg) {
|
||||
case 0x19:
|
||||
svga->vram_display_mask = (val & 0x20) ? dev->vram_mask : 0x3ffff;
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (old != val) {
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
|
||||
{
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
if (old != val) {
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3d6:
|
||||
dev->bank3d6 = val;
|
||||
rtg_recalcbanking(dev);
|
||||
return;
|
||||
case 0x3d6:
|
||||
dev->bank3d6 = val;
|
||||
rtg_recalcbanking(dev);
|
||||
return;
|
||||
|
||||
case 0x3d7:
|
||||
dev->bank3d7 = val;
|
||||
rtg_recalcbanking(dev);
|
||||
return;
|
||||
case 0x3d7:
|
||||
dev->bank3d7 = val;
|
||||
rtg_recalcbanking(dev);
|
||||
return;
|
||||
}
|
||||
|
||||
svga_out(addr, val, svga);
|
||||
@@ -199,159 +196,156 @@ rtg_out(uint16_t addr, uint8_t val, void *priv)
|
||||
static void
|
||||
rtg_recalctimings(svga_t *svga)
|
||||
{
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->ma_latch |= ((svga->crtc[0x19] & 0x10) << 16) | ((svga->crtc[0x19] & 0x40) << 17);
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
svga->ma_latch |= ((svga->crtc[0x19] & 0x10) << 16) | ((svga->crtc[0x19] & 0x40) << 17);
|
||||
|
||||
svga->interlace = (svga->crtc[0x19] & 1);
|
||||
svga->interlace = (svga->crtc[0x19] & 1);
|
||||
|
||||
svga->lowres = svga->attrregs[0x10] & 0x40;
|
||||
svga->lowres = svga->attrregs[0x10] & 0x40;
|
||||
|
||||
/*Clock table not available, currently a guesswork*/
|
||||
switch (((svga->miscout >> 2) & 3) | ((svga->gdcreg[0x0c] & 0x20) >> 3)) {
|
||||
case 0:
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0;
|
||||
break;
|
||||
case 3:
|
||||
svga->clock = (cpuclock * (double)(1ull << 32)) / 65100000.0;
|
||||
break;
|
||||
case 4:
|
||||
svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0;
|
||||
break;
|
||||
case 5:
|
||||
svga->clock = (cpuclock * (double)(1ull << 32)) / 50000000.0;
|
||||
break;
|
||||
case 6:
|
||||
svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0;
|
||||
break;
|
||||
case 7:
|
||||
svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0;
|
||||
break;
|
||||
}
|
||||
/*Clock table not available, currently a guesswork*/
|
||||
switch (((svga->miscout >> 2) & 3) | ((svga->gdcreg[0x0c] & 0x20) >> 3)) {
|
||||
case 0:
|
||||
case 1:
|
||||
break;
|
||||
case 2:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 36000000.0;
|
||||
break;
|
||||
case 3:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 65100000.0;
|
||||
break;
|
||||
case 4:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0;
|
||||
break;
|
||||
case 5:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 50000000.0;
|
||||
break;
|
||||
case 6:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 80000000.0;
|
||||
break;
|
||||
case 7:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 75000000.0;
|
||||
break;
|
||||
}
|
||||
|
||||
switch (svga->gdcreg[0x0c] & 3) {
|
||||
case 1:
|
||||
svga->clock /= 1.5;
|
||||
break;
|
||||
case 2:
|
||||
svga->clock /= 2;
|
||||
break;
|
||||
case 3:
|
||||
svga->clock /= 4;
|
||||
break;
|
||||
}
|
||||
switch (svga->gdcreg[0x0c] & 3) {
|
||||
case 1:
|
||||
svga->clock /= 1.5;
|
||||
break;
|
||||
case 2:
|
||||
svga->clock /= 2;
|
||||
break;
|
||||
case 3:
|
||||
svga->clock /= 4;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
|
||||
switch (svga->gdcreg[5] & 0x60) {
|
||||
case 0x00:
|
||||
if (svga->seqregs[1] & 8) /*Low res (320)*/
|
||||
svga->render = svga_render_4bpp_lowres;
|
||||
else {
|
||||
svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5);
|
||||
svga->hdisp++;
|
||||
svga->hdisp *= 8;
|
||||
if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) {
|
||||
switch (svga->gdcreg[5] & 0x60) {
|
||||
case 0x00:
|
||||
if (svga->seqregs[1] & 8) /*Low res (320)*/
|
||||
svga->render = svga_render_4bpp_lowres;
|
||||
else {
|
||||
svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5);
|
||||
svga->hdisp++;
|
||||
svga->hdisp *= 8;
|
||||
|
||||
if (svga->hdisp == 1280)
|
||||
svga->rowoffset >>= 1;
|
||||
if (svga->hdisp == 1280)
|
||||
svga->rowoffset >>= 1;
|
||||
|
||||
svga->render = svga_render_4bpp_highres;
|
||||
}
|
||||
break;
|
||||
case 0x20: /*4 colours*/
|
||||
if (svga->seqregs[1] & 8) /*Low res (320)*/
|
||||
svga->render = svga_render_2bpp_lowres;
|
||||
else
|
||||
svga->render = svga_render_2bpp_highres;
|
||||
break;
|
||||
case 0x40: case 0x60:
|
||||
svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5);
|
||||
svga->hdisp++;
|
||||
svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8;
|
||||
if (svga->crtc[0x19] & 2) {
|
||||
if (svga->hdisp == 1280) {
|
||||
svga->hdisp >>= 1;
|
||||
} else
|
||||
svga->rowoffset <<= 1;
|
||||
svga->render = svga_render_4bpp_highres;
|
||||
}
|
||||
break;
|
||||
case 0x20: /*4 colours*/
|
||||
if (svga->seqregs[1] & 8) /*Low res (320)*/
|
||||
svga->render = svga_render_2bpp_lowres;
|
||||
else
|
||||
svga->render = svga_render_2bpp_highres;
|
||||
break;
|
||||
case 0x40:
|
||||
case 0x60:
|
||||
svga->hdisp = svga->crtc[1] - ((svga->crtc[5] & 0x60) >> 5);
|
||||
svga->hdisp++;
|
||||
svga->hdisp *= (svga->seqregs[1] & 8) ? 16 : 8;
|
||||
if (svga->crtc[0x19] & 2) {
|
||||
if (svga->hdisp == 1280) {
|
||||
svga->hdisp >>= 1;
|
||||
} else
|
||||
svga->rowoffset <<= 1;
|
||||
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
} else {
|
||||
if (svga->lowres)
|
||||
svga->render = svga_render_8bpp_lowres;
|
||||
else
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
} else {
|
||||
if (svga->lowres)
|
||||
svga->render = svga_render_8bpp_lowres;
|
||||
else
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
rtg_init(const device_t *info)
|
||||
{
|
||||
const char *fn;
|
||||
rtg_t *dev;
|
||||
rtg_t *dev;
|
||||
|
||||
dev = (rtg_t *)malloc(sizeof(rtg_t));
|
||||
dev = (rtg_t *) malloc(sizeof(rtg_t));
|
||||
memset(dev, 0x00, sizeof(rtg_t));
|
||||
dev->name = info->name;
|
||||
dev->type = info->local;
|
||||
fn = BIOS_ROM_PATH;
|
||||
fn = BIOS_ROM_PATH;
|
||||
|
||||
switch(dev->type) {
|
||||
case 2: /* ISA RTG3106 */
|
||||
dev->vram_size = device_get_config_int("memory") << 10;
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_rtg_isa);
|
||||
svga_init(info, &dev->svga, dev, dev->vram_size,
|
||||
rtg_recalctimings, rtg_in, rtg_out,
|
||||
NULL, NULL);
|
||||
io_sethandler(0x03c0, 32,
|
||||
rtg_in,NULL,NULL, rtg_out,NULL,NULL, dev);
|
||||
break;
|
||||
switch (dev->type) {
|
||||
case 2: /* ISA RTG3106 */
|
||||
dev->vram_size = device_get_config_int("memory") << 10;
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_rtg_isa);
|
||||
svga_init(info, &dev->svga, dev, dev->vram_size,
|
||||
rtg_recalctimings, rtg_in, rtg_out,
|
||||
NULL, NULL);
|
||||
io_sethandler(0x03c0, 32,
|
||||
rtg_in, NULL, NULL, rtg_out, NULL, NULL, dev);
|
||||
break;
|
||||
}
|
||||
|
||||
dev->svga.bpp = 8;
|
||||
dev->svga.miscout = 1;
|
||||
dev->svga.bpp = 8;
|
||||
dev->svga.miscout = 1;
|
||||
|
||||
dev->vram_mask = dev->vram_size - 1;
|
||||
|
||||
rom_init(&dev->bios_rom, (char *) fn,
|
||||
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
return(dev);
|
||||
return (dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rtg_close(void *priv)
|
||||
{
|
||||
rtg_t *dev = (rtg_t *)priv;
|
||||
rtg_t *dev = (rtg_t *) priv;
|
||||
|
||||
svga_close(&dev->svga);
|
||||
|
||||
free(dev);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rtg_speed_changed(void *priv)
|
||||
{
|
||||
rtg_t *dev = (rtg_t *)priv;
|
||||
rtg_t *dev = (rtg_t *) priv;
|
||||
|
||||
svga_recalctimings(&dev->svga);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
rtg_force_redraw(void *priv)
|
||||
{
|
||||
rtg_t *dev = (rtg_t *)priv;
|
||||
rtg_t *dev = (rtg_t *) priv;
|
||||
|
||||
dev->svga.fullchange = changeframecount;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
rtg_available(void)
|
||||
{
|
||||
@@ -359,7 +353,7 @@ rtg_available(void)
|
||||
}
|
||||
|
||||
static const device_config_t rtg_config[] = {
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
{
|
||||
.name = "memory",
|
||||
.description = "Memory size",
|
||||
@@ -390,15 +384,15 @@ static const device_config_t rtg_config[] = {
|
||||
};
|
||||
|
||||
const device_t realtek_rtg3106_device = {
|
||||
.name = "Realtek RTG3106 (ISA)",
|
||||
.name = "Realtek RTG3106 (ISA)",
|
||||
.internal_name = "rtg3106",
|
||||
.flags = DEVICE_ISA | DEVICE_AT,
|
||||
.local = 2,
|
||||
.init = rtg_init,
|
||||
.close = rtg_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA | DEVICE_AT,
|
||||
.local = 2,
|
||||
.init = rtg_init,
|
||||
.close = rtg_close,
|
||||
.reset = NULL,
|
||||
{ .available = rtg_available },
|
||||
.speed_changed = rtg_speed_changed,
|
||||
.force_redraw = rtg_force_redraw,
|
||||
.config = rtg_config
|
||||
.force_redraw = rtg_force_redraw,
|
||||
.config = rtg_config
|
||||
};
|
||||
|
||||
15340
src/video/vid_s3.c
15340
src/video/vid_s3.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -28,104 +28,103 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int type;
|
||||
int state;
|
||||
int rs2;
|
||||
int type;
|
||||
int state;
|
||||
int rs2;
|
||||
uint8_t ctrl;
|
||||
} sc1148x_ramdac_t;
|
||||
|
||||
|
||||
void
|
||||
sc1148x_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
|
||||
{
|
||||
sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p;
|
||||
uint8_t rs = (addr & 0x03) | ((!!rs2) << 2);
|
||||
int oldbpp = 0;
|
||||
uint8_t rs = (addr & 0x03) | ((!!rs2) << 2);
|
||||
int oldbpp = 0;
|
||||
|
||||
switch (rs) {
|
||||
case 2: case 6:
|
||||
switch (ramdac->state) {
|
||||
case 4:
|
||||
ramdac->state = 0;
|
||||
if (val == 0xff)
|
||||
break;
|
||||
ramdac->ctrl = val;
|
||||
ramdac->ctrl = (ramdac->ctrl & ~1) | ((((val >> 2) ^ val) & (val & 0x20)) >> 5);
|
||||
oldbpp = svga->bpp;
|
||||
switch (ramdac->type) {
|
||||
case 0: /* Sierra Mark 2 (11483)*/
|
||||
case 2: /* Sierra Mark 2 (11484)*/
|
||||
case 3: /* Sierra Mark 1 (11486)*/
|
||||
if (val & 0xa0) {
|
||||
svga->bpp = 15;
|
||||
} else if (val == 0x00)
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 1: /* Sierra Mark 3 (11487)*/
|
||||
if (val & 0xa0) {
|
||||
if (val & 0x40)
|
||||
svga->bpp = 16;
|
||||
else
|
||||
svga->bpp = 15;
|
||||
} else if (val == 0x00)
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
}
|
||||
if (oldbpp != svga->bpp)
|
||||
svga_recalctimings(svga);
|
||||
return;
|
||||
default:
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case 6:
|
||||
switch (ramdac->state) {
|
||||
case 4:
|
||||
ramdac->state = 0;
|
||||
if (val == 0xff)
|
||||
break;
|
||||
ramdac->ctrl = val;
|
||||
ramdac->ctrl = (ramdac->ctrl & ~1) | ((((val >> 2) ^ val) & (val & 0x20)) >> 5);
|
||||
oldbpp = svga->bpp;
|
||||
switch (ramdac->type) {
|
||||
case 0: /* Sierra Mark 2 (11483)*/
|
||||
case 2: /* Sierra Mark 2 (11484)*/
|
||||
case 3: /* Sierra Mark 1 (11486)*/
|
||||
if (val & 0xa0) {
|
||||
svga->bpp = 15;
|
||||
} else if (val == 0x00)
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 1: /* Sierra Mark 3 (11487)*/
|
||||
if (val & 0xa0) {
|
||||
if (val & 0x40)
|
||||
svga->bpp = 16;
|
||||
else
|
||||
svga->bpp = 15;
|
||||
} else if (val == 0x00)
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
}
|
||||
if (oldbpp != svga->bpp)
|
||||
svga_recalctimings(svga);
|
||||
return;
|
||||
default:
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ramdac->state = 0;
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
default:
|
||||
ramdac->state = 0;
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
sc1148x_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga)
|
||||
{
|
||||
sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) p;
|
||||
uint8_t ret = 0xff, rs = (addr & 0x03) | ((!!rs2) << 2);
|
||||
uint8_t ret = 0xff, rs = (addr & 0x03) | ((!!rs2) << 2);
|
||||
|
||||
switch (rs) {
|
||||
case 2: case 6:
|
||||
switch (ramdac->state) {
|
||||
case 1:
|
||||
case 2: case 3:
|
||||
ret = 0x00;
|
||||
ramdac->state++;
|
||||
break;
|
||||
case 4:
|
||||
ret = ramdac->ctrl;
|
||||
ret = (ret & ~0x18) | (svga->dac_mask & 0x18);
|
||||
break;
|
||||
default:
|
||||
ret = svga_in(addr, svga);
|
||||
ramdac->state++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
case 6:
|
||||
switch (ramdac->state) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
ret = 0x00;
|
||||
ramdac->state++;
|
||||
break;
|
||||
case 4:
|
||||
ret = ramdac->ctrl;
|
||||
ret = (ret & ~0x18) | (svga->dac_mask & 0x18);
|
||||
break;
|
||||
default:
|
||||
ret = svga_in(addr, svga);
|
||||
ramdac->state++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = svga_in(addr, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
default:
|
||||
ret = svga_in(addr, svga);
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
sc1148x_ramdac_init(const device_t *info)
|
||||
{
|
||||
@@ -137,68 +136,67 @@ sc1148x_ramdac_init(const device_t *info)
|
||||
return ramdac;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sc1148x_ramdac_close(void *priv)
|
||||
{
|
||||
sc1148x_ramdac_t *ramdac = (sc1148x_ramdac_t *) priv;
|
||||
|
||||
if (ramdac)
|
||||
free(ramdac);
|
||||
free(ramdac);
|
||||
}
|
||||
|
||||
const device_t sc11483_ramdac_device = {
|
||||
.name = "Sierra SC11483 RAMDAC",
|
||||
.name = "Sierra SC11483 RAMDAC",
|
||||
.internal_name = "sc11483_ramdac",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = sc1148x_ramdac_init,
|
||||
.close = sc1148x_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = sc1148x_ramdac_init,
|
||||
.close = sc1148x_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sc11487_ramdac_device = {
|
||||
.name = "Sierra SC11487 RAMDAC",
|
||||
.name = "Sierra SC11487 RAMDAC",
|
||||
.internal_name = "sc11487_ramdac",
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = sc1148x_ramdac_init,
|
||||
.close = sc1148x_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 1,
|
||||
.init = sc1148x_ramdac_init,
|
||||
.close = sc1148x_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sc11484_nors2_ramdac_device = {
|
||||
.name = "Sierra SC11484 RAMDAC (no RS2 signal)",
|
||||
.name = "Sierra SC11484 RAMDAC (no RS2 signal)",
|
||||
.internal_name = "sc11484_nors2_ramdac",
|
||||
.flags = 0,
|
||||
.local = 2,
|
||||
.init = sc1148x_ramdac_init,
|
||||
.close = sc1148x_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 2,
|
||||
.init = sc1148x_ramdac_init,
|
||||
.close = sc1148x_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sc11486_ramdac_device = {
|
||||
.name = "Sierra SC11486 RAMDAC",
|
||||
.name = "Sierra SC11486 RAMDAC",
|
||||
.internal_name = "sc11486_ramdac",
|
||||
.flags = 0,
|
||||
.local = 3,
|
||||
.init = sc1148x_ramdac_init,
|
||||
.close = sc1148x_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 3,
|
||||
.init = sc1148x_ramdac_init,
|
||||
.close = sc1148x_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -30,110 +30,106 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int state;
|
||||
int state;
|
||||
uint8_t ctrl;
|
||||
} sc1502x_ramdac_t;
|
||||
|
||||
|
||||
void
|
||||
sc1502x_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
|
||||
{
|
||||
sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) p;
|
||||
int oldbpp = 0;
|
||||
int oldbpp = 0;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3C6:
|
||||
if (ramdac->state == 4) {
|
||||
ramdac->state = 0;
|
||||
if (val == 0xFF)
|
||||
break;
|
||||
ramdac->ctrl = val;
|
||||
oldbpp = svga->bpp;
|
||||
switch ((val & 1) | ((val & 0xc0) >> 5)) {
|
||||
case 0:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
switch (val & 0x20) {
|
||||
case 0x00:
|
||||
svga->bpp = 32;
|
||||
break;
|
||||
case 0x20:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 6:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 7:
|
||||
if (val & 4) {
|
||||
switch (val & 0x20) {
|
||||
case 0x00:
|
||||
svga->bpp = 32;
|
||||
break;
|
||||
case 0x20:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (oldbpp != svga->bpp)
|
||||
svga_recalctimings(svga);
|
||||
return;
|
||||
}
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x3C7:
|
||||
case 0x3C8:
|
||||
case 0x3C9:
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x3C6:
|
||||
if (ramdac->state == 4) {
|
||||
ramdac->state = 0;
|
||||
if (val == 0xFF)
|
||||
break;
|
||||
ramdac->ctrl = val;
|
||||
oldbpp = svga->bpp;
|
||||
switch ((val & 1) | ((val & 0xc0) >> 5)) {
|
||||
case 0:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
switch (val & 0x20) {
|
||||
case 0x00:
|
||||
svga->bpp = 32;
|
||||
break;
|
||||
case 0x20:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
case 5:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 6:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 7:
|
||||
if (val & 4) {
|
||||
switch (val & 0x20) {
|
||||
case 0x00:
|
||||
svga->bpp = 32;
|
||||
break;
|
||||
case 0x20:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (oldbpp != svga->bpp)
|
||||
svga_recalctimings(svga);
|
||||
return;
|
||||
}
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x3C7:
|
||||
case 0x3C8:
|
||||
case 0x3C9:
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
sc1502x_ramdac_in(uint16_t addr, void *p, svga_t *svga)
|
||||
{
|
||||
sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) p;
|
||||
uint8_t temp = svga_in(addr, svga);
|
||||
uint8_t temp = svga_in(addr, svga);
|
||||
|
||||
switch (addr) {
|
||||
case 0x3C6:
|
||||
if (ramdac->state == 4) {
|
||||
ramdac->state = 0;
|
||||
temp = ramdac->ctrl;
|
||||
break;
|
||||
}
|
||||
ramdac->state++;
|
||||
break;
|
||||
case 0x3C7:
|
||||
case 0x3C8:
|
||||
case 0x3C9:
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x3C6:
|
||||
if (ramdac->state == 4) {
|
||||
ramdac->state = 0;
|
||||
temp = ramdac->ctrl;
|
||||
break;
|
||||
}
|
||||
ramdac->state++;
|
||||
break;
|
||||
case 0x3C7:
|
||||
case 0x3C8:
|
||||
case 0x3C9:
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
sc1502x_ramdac_init(const device_t *info)
|
||||
{
|
||||
@@ -143,26 +139,25 @@ sc1502x_ramdac_init(const device_t *info)
|
||||
return ramdac;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sc1502x_ramdac_close(void *priv)
|
||||
{
|
||||
sc1502x_ramdac_t *ramdac = (sc1502x_ramdac_t *) priv;
|
||||
|
||||
if (ramdac)
|
||||
free(ramdac);
|
||||
free(ramdac);
|
||||
}
|
||||
|
||||
const device_t sc1502x_ramdac_device = {
|
||||
.name = "Sierra SC1502x RAMDAC",
|
||||
.name = "Sierra SC1502x RAMDAC",
|
||||
.internal_name = "sc1502x_ramdac",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = sc1502x_ramdac_init,
|
||||
.close = sc1502x_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = sc1502x_ramdac_init,
|
||||
.close = sc1502x_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -28,9 +28,7 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
enum {
|
||||
ICS_5300 = 0,
|
||||
ICS_5301,
|
||||
ICS_5340,
|
||||
@@ -38,247 +36,238 @@ enum
|
||||
ICS_5342
|
||||
};
|
||||
|
||||
#define ICS_S3_MASK 7
|
||||
#define ICS_S3 8
|
||||
|
||||
#define ICS_S3_MASK 7
|
||||
#define ICS_S3 8
|
||||
#define S3_86C708 (ICS_5300 | ICS_S3)
|
||||
#define S3_86C716 (ICS_5342 | ICS_S3)
|
||||
|
||||
#define S3_86C708 (ICS_5300 | ICS_S3)
|
||||
#define S3_86C716 (ICS_5342 | ICS_S3)
|
||||
|
||||
|
||||
typedef struct sdac_ramdac_t
|
||||
{
|
||||
typedef struct sdac_ramdac_t {
|
||||
uint16_t regs[256];
|
||||
int magic_count,
|
||||
windex, rindex,
|
||||
reg_ff, rs2;
|
||||
int magic_count,
|
||||
windex, rindex,
|
||||
reg_ff, rs2;
|
||||
uint8_t type, command;
|
||||
} sdac_ramdac_t;
|
||||
|
||||
|
||||
static void
|
||||
sdac_control_write(sdac_ramdac_t *ramdac, svga_t *svga, uint8_t val)
|
||||
{
|
||||
ramdac->command = val;
|
||||
|
||||
switch (ramdac->type & ICS_S3_MASK) {
|
||||
case ICS_5300:
|
||||
case ICS_5301:
|
||||
switch (val >> 5) {
|
||||
case 0x00:
|
||||
default:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 0x01:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 0x03:
|
||||
case 0x06:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x07:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICS_5340:
|
||||
case ICS_5341:
|
||||
case ICS_5342:
|
||||
switch (val >> 4) {
|
||||
case 0x00:
|
||||
case 0x01: /* This is actually 8bpp with two pixels read at a time. */
|
||||
default:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x08:
|
||||
case 0x0a:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x0c:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 0x04:
|
||||
case 0x09:
|
||||
case 0x0e:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
case 0x07:
|
||||
svga->bpp = 32;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICS_5300:
|
||||
case ICS_5301:
|
||||
switch (val >> 5) {
|
||||
case 0x00:
|
||||
default:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 0x01:
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 0x03:
|
||||
case 0x06:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x07:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ICS_5340:
|
||||
case ICS_5341:
|
||||
case ICS_5342:
|
||||
switch (val >> 4) {
|
||||
case 0x00:
|
||||
case 0x01: /* This is actually 8bpp with two pixels read at a time. */
|
||||
default:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 0x02:
|
||||
case 0x03:
|
||||
case 0x08:
|
||||
case 0x0a:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x0c:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 0x04:
|
||||
case 0x09:
|
||||
case 0x0e:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
case 0x07:
|
||||
svga->bpp = 32;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sdac_reg_write(sdac_ramdac_t *ramdac, int reg, uint8_t val)
|
||||
{
|
||||
if ((reg >= 2 && reg <= 7) || (reg == 0xa) || (reg == 0xe)) {
|
||||
if (!ramdac->reg_ff)
|
||||
ramdac->regs[reg] = (ramdac->regs[reg] & 0xff00) | val;
|
||||
else
|
||||
ramdac->regs[reg] = (ramdac->regs[reg] & 0x00ff) | (val << 8);
|
||||
if (!ramdac->reg_ff)
|
||||
ramdac->regs[reg] = (ramdac->regs[reg] & 0xff00) | val;
|
||||
else
|
||||
ramdac->regs[reg] = (ramdac->regs[reg] & 0x00ff) | (val << 8);
|
||||
}
|
||||
ramdac->reg_ff = !ramdac->reg_ff;
|
||||
if (!ramdac->reg_ff)
|
||||
ramdac->windex++;
|
||||
ramdac->windex++;
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
sdac_reg_read(sdac_ramdac_t *ramdac, int reg)
|
||||
{
|
||||
uint8_t temp;
|
||||
|
||||
if (!ramdac->reg_ff)
|
||||
temp = ramdac->regs[reg] & 0xff;
|
||||
temp = ramdac->regs[reg] & 0xff;
|
||||
else
|
||||
temp = ramdac->regs[reg] >> 8;
|
||||
temp = ramdac->regs[reg] >> 8;
|
||||
ramdac->reg_ff = !ramdac->reg_ff;
|
||||
if (!ramdac->reg_ff)
|
||||
ramdac->rindex++;
|
||||
ramdac->rindex++;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sdac_ramdac_out(uint16_t addr, int rs2, uint8_t val, void *p, svga_t *svga)
|
||||
{
|
||||
sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
uint8_t rs = (addr & 0x03);
|
||||
rs |= ((!!rs2) << 2);
|
||||
|
||||
if (rs != 0x02)
|
||||
ramdac->magic_count = 0;
|
||||
ramdac->magic_count = 0;
|
||||
|
||||
switch (rs) {
|
||||
case 0x02:
|
||||
switch (ramdac->magic_count) {
|
||||
case 4:
|
||||
sdac_control_write(ramdac, svga, val);
|
||||
ramdac->magic_count = 0;
|
||||
break;
|
||||
default:
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
case 0x04:
|
||||
ramdac->windex = val;
|
||||
ramdac->reg_ff = 0;
|
||||
break;
|
||||
case 0x05:
|
||||
sdac_reg_write(ramdac, ramdac->windex & 0xff, val);
|
||||
break;
|
||||
case 0x06:
|
||||
sdac_control_write(ramdac, svga, val);
|
||||
break;
|
||||
case 0x07:
|
||||
ramdac->rindex = val;
|
||||
ramdac->reg_ff = 0;
|
||||
break;
|
||||
case 0x02:
|
||||
switch (ramdac->magic_count) {
|
||||
case 4:
|
||||
sdac_control_write(ramdac, svga, val);
|
||||
ramdac->magic_count = 0;
|
||||
break;
|
||||
default:
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
svga_out(addr, val, svga);
|
||||
break;
|
||||
case 0x04:
|
||||
ramdac->windex = val;
|
||||
ramdac->reg_ff = 0;
|
||||
break;
|
||||
case 0x05:
|
||||
sdac_reg_write(ramdac, ramdac->windex & 0xff, val);
|
||||
break;
|
||||
case 0x06:
|
||||
sdac_control_write(ramdac, svga, val);
|
||||
break;
|
||||
case 0x07:
|
||||
ramdac->rindex = val;
|
||||
ramdac->reg_ff = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
sdac_ramdac_in(uint16_t addr, int rs2, void *p, svga_t *svga)
|
||||
{
|
||||
sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p;
|
||||
uint8_t temp = 0xff;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
uint8_t temp = 0xff;
|
||||
uint8_t rs = (addr & 0x03);
|
||||
rs |= ((!!rs2) << 2);
|
||||
|
||||
if (rs != 0x02)
|
||||
ramdac->magic_count = 0;
|
||||
ramdac->magic_count = 0;
|
||||
|
||||
switch (rs) {
|
||||
case 0x02:
|
||||
switch (ramdac->magic_count) {
|
||||
case 1: case 2:
|
||||
temp = 0x00;
|
||||
ramdac->magic_count++;
|
||||
break;
|
||||
case 3:
|
||||
temp = (ramdac->type & ICS_S3) ? 0x70 : 0x00;
|
||||
ramdac->magic_count++;
|
||||
break;
|
||||
case 4:
|
||||
temp = ramdac->command;
|
||||
ramdac->magic_count = 0;
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
ramdac->magic_count++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
case 0x04:
|
||||
temp = ramdac->windex;
|
||||
break;
|
||||
case 0x05:
|
||||
temp = sdac_reg_read(ramdac, ramdac->rindex & 0xff);
|
||||
break;
|
||||
case 0x06:
|
||||
temp = ramdac->command;
|
||||
break;
|
||||
case 0x07:
|
||||
temp = ramdac->rindex;
|
||||
break;
|
||||
case 0x02:
|
||||
switch (ramdac->magic_count) {
|
||||
case 1:
|
||||
case 2:
|
||||
temp = 0x00;
|
||||
ramdac->magic_count++;
|
||||
break;
|
||||
case 3:
|
||||
temp = (ramdac->type & ICS_S3) ? 0x70 : 0x00;
|
||||
ramdac->magic_count++;
|
||||
break;
|
||||
case 4:
|
||||
temp = ramdac->command;
|
||||
ramdac->magic_count = 0;
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
ramdac->magic_count++;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x00:
|
||||
case 0x01:
|
||||
case 0x03:
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
case 0x04:
|
||||
temp = ramdac->windex;
|
||||
break;
|
||||
case 0x05:
|
||||
temp = sdac_reg_read(ramdac, ramdac->rindex & 0xff);
|
||||
break;
|
||||
case 0x06:
|
||||
temp = ramdac->command;
|
||||
break;
|
||||
case 0x07:
|
||||
temp = ramdac->rindex;
|
||||
break;
|
||||
}
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
sdac_getclock(int clock, void *p)
|
||||
{
|
||||
sdac_ramdac_t *ramdac = (sdac_ramdac_t *)p;
|
||||
float t;
|
||||
int m, n1, n2;
|
||||
sdac_ramdac_t *ramdac = (sdac_ramdac_t *) p;
|
||||
float t;
|
||||
int m, n1, n2;
|
||||
|
||||
if (ramdac->regs[0xe] & (1 << 5))
|
||||
clock = ramdac->regs[0xe] & 7;
|
||||
clock = ramdac->regs[0xe] & 7;
|
||||
|
||||
clock &= 7;
|
||||
|
||||
if (clock == 0)
|
||||
return 25175000.0;
|
||||
return 25175000.0;
|
||||
if (clock == 1)
|
||||
return 28322000.0;
|
||||
return 28322000.0;
|
||||
|
||||
m = (ramdac->regs[clock] & 0x7f) + 2;
|
||||
n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2;
|
||||
m = (ramdac->regs[clock] & 0x7f) + 2;
|
||||
n1 = ((ramdac->regs[clock] >> 8) & 0x1f) + 2;
|
||||
n2 = ((ramdac->regs[clock] >> 13) & 0x07);
|
||||
n2 = (1 << n2);
|
||||
t = (14318184.0f * (float)m) / (float)(n1 * n2);
|
||||
t = (14318184.0f * (float) m) / (float) (n1 * n2);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
sdac_ramdac_init(const device_t *info)
|
||||
{
|
||||
@@ -293,68 +282,67 @@ sdac_ramdac_init(const device_t *info)
|
||||
return ramdac;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sdac_ramdac_close(void *priv)
|
||||
{
|
||||
sdac_ramdac_t *ramdac = (sdac_ramdac_t *) priv;
|
||||
|
||||
if (ramdac)
|
||||
free(ramdac);
|
||||
free(ramdac);
|
||||
}
|
||||
|
||||
const device_t gendac_ramdac_device = {
|
||||
.name = "S3 GENDAC 86c708 RAMDAC",
|
||||
.name = "S3 GENDAC 86c708 RAMDAC",
|
||||
.internal_name = "gendac_ramdac",
|
||||
.flags = 0,
|
||||
.local = S3_86C708,
|
||||
.init = sdac_ramdac_init,
|
||||
.close = sdac_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = S3_86C708,
|
||||
.init = sdac_ramdac_init,
|
||||
.close = sdac_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t tseng_ics5301_ramdac_device = {
|
||||
.name = "Tseng ICS5301 GENDAC RAMDAC",
|
||||
.name = "Tseng ICS5301 GENDAC RAMDAC",
|
||||
.internal_name = "tseng_ics5301_ramdac",
|
||||
.flags = 0,
|
||||
.local = ICS_5301,
|
||||
.init = sdac_ramdac_init,
|
||||
.close = sdac_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = ICS_5301,
|
||||
.init = sdac_ramdac_init,
|
||||
.close = sdac_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t tseng_ics5341_ramdac_device = {
|
||||
.name = "Tseng ICS5341 GENDAC RAMDAC",
|
||||
.name = "Tseng ICS5341 GENDAC RAMDAC",
|
||||
.internal_name = "tseng_ics5341_ramdac",
|
||||
.flags = 0,
|
||||
.local = ICS_5341,
|
||||
.init = sdac_ramdac_init,
|
||||
.close = sdac_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = ICS_5341,
|
||||
.init = sdac_ramdac_init,
|
||||
.close = sdac_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t sdac_ramdac_device = {
|
||||
.name = "S3 SDAC 86c716 RAMDAC",
|
||||
.name = "S3 SDAC 86c716 RAMDAC",
|
||||
.internal_name = "sdac_ramdac",
|
||||
.flags = 0,
|
||||
.local = S3_86C716,
|
||||
.init = sdac_ramdac_init,
|
||||
.close = sdac_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = S3_86C716,
|
||||
.init = sdac_ramdac_init,
|
||||
.close = sdac_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -28,205 +28,199 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
|
||||
|
||||
typedef struct stg_ramdac_t
|
||||
{
|
||||
int magic_count, index;
|
||||
typedef struct stg_ramdac_t {
|
||||
int magic_count, index;
|
||||
uint8_t regs[256];
|
||||
uint8_t command;
|
||||
} stg_ramdac_t;
|
||||
|
||||
|
||||
|
||||
static int stg_state_read[2][8] = {{1,2,3,4,0,0,0,0}, {1,2,3,4,5,6,7,7}};
|
||||
static int stg_state_write[8] = {0,0,0,0,0,6,7,7};
|
||||
|
||||
static int stg_state_read[2][8] = {
|
||||
{1, 2, 3, 4, 0, 0, 0, 0},
|
||||
{ 1, 2, 3, 4, 5, 6, 7, 7}
|
||||
};
|
||||
static int stg_state_write[8] = { 0, 0, 0, 0, 0, 6, 7, 7 };
|
||||
|
||||
void
|
||||
stg_ramdac_set_bpp(svga_t *svga, stg_ramdac_t *ramdac)
|
||||
{
|
||||
if (ramdac->command & 0x8) {
|
||||
switch (ramdac->regs[3]) {
|
||||
case 0:
|
||||
case 5:
|
||||
case 7:
|
||||
default:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 8:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 3:
|
||||
case 6:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 4:
|
||||
case 9:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
case 0:
|
||||
case 5:
|
||||
case 7:
|
||||
default:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
case 8:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 3:
|
||||
case 6:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 4:
|
||||
case 9:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (ramdac->command >> 5) {
|
||||
case 0:
|
||||
default:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 5:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 6:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 7:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
switch (ramdac->command >> 5) {
|
||||
case 0:
|
||||
default:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 5:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 6:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
case 7:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
stg_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
|
||||
{
|
||||
stg_ramdac_t *ramdac = (stg_ramdac_t *) p;
|
||||
int didwrite, old;
|
||||
int didwrite, old;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3c6:
|
||||
switch (ramdac->magic_count) {
|
||||
/* 0 = PEL mask register */
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
break;
|
||||
case 4: /* REG06 */
|
||||
old = ramdac->command;
|
||||
ramdac->command = val;
|
||||
if ((old ^ val) & 8)
|
||||
stg_ramdac_set_bpp(svga, ramdac);
|
||||
else {
|
||||
if ((old ^ val) & 0xE0)
|
||||
stg_ramdac_set_bpp(svga, ramdac);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
ramdac->index = (ramdac->index & 0xff00) | val;
|
||||
break;
|
||||
case 6:
|
||||
ramdac->index = (ramdac->index & 0xff) | (val << 8);
|
||||
break;
|
||||
case 7:
|
||||
if (ramdac->index < 0x100)
|
||||
ramdac->regs[ramdac->index] = val;
|
||||
if ((ramdac->index == 3) && (ramdac->command & 8))
|
||||
stg_ramdac_set_bpp(svga, ramdac);
|
||||
ramdac->index++;
|
||||
break;
|
||||
}
|
||||
didwrite = (ramdac->magic_count >= 4);
|
||||
ramdac->magic_count = stg_state_write[ramdac->magic_count & 7];
|
||||
if (didwrite)
|
||||
return;
|
||||
break;
|
||||
case 0x3c7:
|
||||
case 0x3c8:
|
||||
case 0x3c9:
|
||||
ramdac->magic_count=0;
|
||||
break;
|
||||
case 0x3c6:
|
||||
switch (ramdac->magic_count) {
|
||||
/* 0 = PEL mask register */
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
break;
|
||||
case 4: /* REG06 */
|
||||
old = ramdac->command;
|
||||
ramdac->command = val;
|
||||
if ((old ^ val) & 8)
|
||||
stg_ramdac_set_bpp(svga, ramdac);
|
||||
else {
|
||||
if ((old ^ val) & 0xE0)
|
||||
stg_ramdac_set_bpp(svga, ramdac);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
ramdac->index = (ramdac->index & 0xff00) | val;
|
||||
break;
|
||||
case 6:
|
||||
ramdac->index = (ramdac->index & 0xff) | (val << 8);
|
||||
break;
|
||||
case 7:
|
||||
if (ramdac->index < 0x100)
|
||||
ramdac->regs[ramdac->index] = val;
|
||||
if ((ramdac->index == 3) && (ramdac->command & 8))
|
||||
stg_ramdac_set_bpp(svga, ramdac);
|
||||
ramdac->index++;
|
||||
break;
|
||||
}
|
||||
didwrite = (ramdac->magic_count >= 4);
|
||||
ramdac->magic_count = stg_state_write[ramdac->magic_count & 7];
|
||||
if (didwrite)
|
||||
return;
|
||||
break;
|
||||
case 0x3c7:
|
||||
case 0x3c8:
|
||||
case 0x3c9:
|
||||
ramdac->magic_count = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
stg_ramdac_in(uint16_t addr, void *p, svga_t *svga)
|
||||
{
|
||||
stg_ramdac_t *ramdac = (stg_ramdac_t *) p;
|
||||
uint8_t temp = 0xff;
|
||||
uint8_t temp = 0xff;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3c6:
|
||||
switch (ramdac->magic_count) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
temp = 0xff;
|
||||
break;
|
||||
case 4:
|
||||
temp = ramdac->command;
|
||||
break;
|
||||
case 5:
|
||||
temp = ramdac->index & 0xff;
|
||||
break;
|
||||
case 6:
|
||||
temp = ramdac->index >> 8;
|
||||
break;
|
||||
case 7:
|
||||
switch (ramdac->index) {
|
||||
case 0:
|
||||
temp = 0x44;
|
||||
break;
|
||||
case 1:
|
||||
temp = 0x03;
|
||||
break;
|
||||
case 7:
|
||||
temp = 0x88;
|
||||
break;
|
||||
default:
|
||||
if (ramdac->index < 0x100)
|
||||
temp = ramdac->regs[ramdac->index];
|
||||
else
|
||||
temp = 0xff;
|
||||
break;
|
||||
}
|
||||
ramdac->index++;
|
||||
break;
|
||||
}
|
||||
ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7];
|
||||
return temp;
|
||||
case 0x3c7:
|
||||
case 0x3c8:
|
||||
case 0x3c9:
|
||||
ramdac->magic_count=0;
|
||||
break;
|
||||
case 0x3c6:
|
||||
switch (ramdac->magic_count) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
temp = 0xff;
|
||||
break;
|
||||
case 4:
|
||||
temp = ramdac->command;
|
||||
break;
|
||||
case 5:
|
||||
temp = ramdac->index & 0xff;
|
||||
break;
|
||||
case 6:
|
||||
temp = ramdac->index >> 8;
|
||||
break;
|
||||
case 7:
|
||||
switch (ramdac->index) {
|
||||
case 0:
|
||||
temp = 0x44;
|
||||
break;
|
||||
case 1:
|
||||
temp = 0x03;
|
||||
break;
|
||||
case 7:
|
||||
temp = 0x88;
|
||||
break;
|
||||
default:
|
||||
if (ramdac->index < 0x100)
|
||||
temp = ramdac->regs[ramdac->index];
|
||||
else
|
||||
temp = 0xff;
|
||||
break;
|
||||
}
|
||||
ramdac->index++;
|
||||
break;
|
||||
}
|
||||
ramdac->magic_count = stg_state_read[(ramdac->command & 0x10) ? 1 : 0][ramdac->magic_count & 7];
|
||||
return temp;
|
||||
case 0x3c7:
|
||||
case 0x3c8:
|
||||
case 0x3c9:
|
||||
ramdac->magic_count = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return svga_in(addr, svga);
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
stg_getclock(int clock, void *p)
|
||||
{
|
||||
stg_ramdac_t *ramdac = (stg_ramdac_t *)p;
|
||||
float t;
|
||||
int m, n, n2;
|
||||
uint16_t *c;
|
||||
stg_ramdac_t *ramdac = (stg_ramdac_t *) p;
|
||||
float t;
|
||||
int m, n, n2;
|
||||
uint16_t *c;
|
||||
|
||||
if (clock == 0)
|
||||
return 25175000.0;
|
||||
return 25175000.0;
|
||||
if (clock == 1)
|
||||
return 28322000.0;
|
||||
return 28322000.0;
|
||||
|
||||
clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/
|
||||
c = (uint16_t *) &ramdac->regs[0x20 + (clock << 1)];
|
||||
m = (*c & 0xff) + 2; /* B+2 */
|
||||
n = ((*c >> 8) & 0x1f) + 2; /* N1+2 */
|
||||
n2 = ((*c >> 13) & 0x07); /* D */
|
||||
clock ^= 1; /*Clocks 2 and 3 seem to be reversed*/
|
||||
c = (uint16_t *) &ramdac->regs[0x20 + (clock << 1)];
|
||||
m = (*c & 0xff) + 2; /* B+2 */
|
||||
n = ((*c >> 8) & 0x1f) + 2; /* N1+2 */
|
||||
n2 = ((*c >> 13) & 0x07); /* D */
|
||||
n2 = (1 << n2);
|
||||
t = (14318184.0f * (float)m) / (float)(n * n2);
|
||||
t = (14318184.0f * (float) m) / (float) (n * n2);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
stg_ramdac_init(const device_t *info)
|
||||
{
|
||||
@@ -236,26 +230,25 @@ stg_ramdac_init(const device_t *info)
|
||||
return ramdac;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
stg_ramdac_close(void *priv)
|
||||
{
|
||||
stg_ramdac_t *ramdac = (stg_ramdac_t *) priv;
|
||||
|
||||
if (ramdac)
|
||||
free(ramdac);
|
||||
free(ramdac);
|
||||
}
|
||||
|
||||
const device_t stg_ramdac_device = {
|
||||
.name = "SGS-Thompson STG170x RAMDAC",
|
||||
.name = "SGS-Thompson STG170x RAMDAC",
|
||||
.internal_name = "stg_ramdac",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = stg_ramdac_init,
|
||||
.close = stg_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = stg_ramdac_init,
|
||||
.close = stg_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
2139
src/video/vid_svga.c
2139
src/video/vid_svga.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -37,47 +37,45 @@
|
||||
#include <86box/vid_colorplus.h>
|
||||
#include <86box/vid_mda.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
const device_t *device;
|
||||
int flags;
|
||||
const device_t *device;
|
||||
int flags;
|
||||
} VIDEO_CARD;
|
||||
|
||||
|
||||
static video_timings_t timing_default = {VIDEO_ISA, 8, 16, 32, 8, 16, 32};
|
||||
static video_timings_t timing_default = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 };
|
||||
|
||||
static int was_reset = 0;
|
||||
|
||||
static const device_t vid_none_device = {
|
||||
.name = "None",
|
||||
.name = "None",
|
||||
.internal_name = "none",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
static const device_t vid_internal_device = {
|
||||
.name = "Internal",
|
||||
.name = "Internal",
|
||||
.internal_name = "internal",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = NULL,
|
||||
.close = NULL,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
static const VIDEO_CARD
|
||||
video_cards[] = {
|
||||
// clang-format off
|
||||
{ &vid_none_device },
|
||||
{ &vid_internal_device },
|
||||
{ &atiega_device },
|
||||
@@ -252,30 +250,27 @@ video_cards[] = {
|
||||
{ &voodoo_3_2000_agp_device },
|
||||
{ &voodoo_3_3000_agp_device },
|
||||
{ NULL }
|
||||
// clang-format off
|
||||
};
|
||||
|
||||
// clang-format on
|
||||
|
||||
#ifdef ENABLE_VID_TABLE_LOG
|
||||
int vid_table_do_log = ENABLE_VID_TABLE_LOG;
|
||||
|
||||
|
||||
static void
|
||||
vid_table_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (vid_table_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define vid_table_log(fmt, ...)
|
||||
# define vid_table_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
video_reset_close(void)
|
||||
{
|
||||
@@ -287,14 +282,13 @@ video_reset_close(void)
|
||||
was_reset = 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
video_prepare(void)
|
||||
{
|
||||
/* Reset (deallocate) the video font arrays. */
|
||||
if (fontdatksc5601) {
|
||||
free(fontdatksc5601);
|
||||
fontdatksc5601 = NULL;
|
||||
free(fontdatksc5601);
|
||||
fontdatksc5601 = NULL;
|
||||
}
|
||||
|
||||
/* Reset the blend. */
|
||||
@@ -302,7 +296,8 @@ video_prepare(void)
|
||||
|
||||
for (int i = 0; i < MONITORS_NUM; i++) {
|
||||
/* Reset the CGA palette. */
|
||||
if (monitors[i].mon_cga_palette) *monitors[i].mon_cga_palette = 0;
|
||||
if (monitors[i].mon_cga_palette)
|
||||
*monitors[i].mon_cga_palette = 0;
|
||||
cgapal_rebuild_monitor(i);
|
||||
|
||||
/* Do an inform on the default values, so that that there's some sane values initialized
|
||||
@@ -311,38 +306,34 @@ video_prepare(void)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_pre_reset(int card)
|
||||
{
|
||||
if ((card == VID_NONE) || \
|
||||
(card == VID_INTERNAL) || machine_has_flags(machine, MACHINE_VIDEO_ONLY))
|
||||
video_prepare();
|
||||
if ((card == VID_NONE) || (card == VID_INTERNAL) || machine_has_flags(machine, MACHINE_VIDEO_ONLY))
|
||||
video_prepare();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
video_reset(int card)
|
||||
{
|
||||
/* This is needed to avoid duplicate resets. */
|
||||
if ((video_get_type() != VIDEO_FLAG_TYPE_NONE) && was_reset)
|
||||
return;
|
||||
return;
|
||||
|
||||
vid_table_log("VIDEO: reset (gfxcard=%d, internal=%d)\n",
|
||||
card, machine_has_flags(machine, MACHINE_VIDEO) ? 1 : 0);
|
||||
card, machine_has_flags(machine, MACHINE_VIDEO) ? 1 : 0);
|
||||
|
||||
monitor_index_global = 0;
|
||||
loadfont("roms/video/mda/mda.rom", 0);
|
||||
|
||||
/* Do not initialize internal cards here. */
|
||||
if (!(card == VID_NONE) && \
|
||||
!(card == VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) {
|
||||
vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].name);
|
||||
if (!(card == VID_NONE) && !(card == VID_INTERNAL) && !machine_has_flags(machine, MACHINE_VIDEO_ONLY)) {
|
||||
vid_table_log("VIDEO: initializing '%s'\n", video_cards[card].name);
|
||||
|
||||
video_prepare();
|
||||
video_prepare();
|
||||
|
||||
/* Initialize the video card. */
|
||||
device_add(video_cards[card].device);
|
||||
/* Initialize the video card. */
|
||||
device_add(video_cards[card].device);
|
||||
}
|
||||
|
||||
if (!(card == VID_NONE)
|
||||
@@ -358,19 +349,18 @@ video_reset(int card)
|
||||
|
||||
/* Enable the Voodoo if configured. */
|
||||
if (voodoo_enabled)
|
||||
device_add(&voodoo_device);
|
||||
device_add(&voodoo_device);
|
||||
|
||||
was_reset = 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
video_card_available(int card)
|
||||
{
|
||||
if (video_cards[card].device)
|
||||
return(device_available(video_cards[card].device));
|
||||
return (device_available(video_cards[card].device));
|
||||
|
||||
return(1);
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -382,55 +372,50 @@ video_card_get_flags(int card)
|
||||
const device_t *
|
||||
video_card_getdevice(int card)
|
||||
{
|
||||
return(video_cards[card].device);
|
||||
return (video_cards[card].device);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
video_card_has_config(int card)
|
||||
{
|
||||
if (video_cards[card].device == NULL) return(0);
|
||||
if (video_cards[card].device == NULL)
|
||||
return (0);
|
||||
|
||||
return(device_has_config(video_cards[card].device) ? 1 : 0);
|
||||
return (device_has_config(video_cards[card].device) ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
video_get_internal_name(int card)
|
||||
{
|
||||
return device_get_internal_name(video_cards[card].device);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
video_get_video_from_internal_name(char *s)
|
||||
{
|
||||
int c = 0;
|
||||
|
||||
while (video_cards[c].device != NULL) {
|
||||
if (!strcmp((char *) video_cards[c].device->internal_name, s))
|
||||
return(c);
|
||||
c++;
|
||||
if (!strcmp((char *) video_cards[c].device->internal_name, s))
|
||||
return (c);
|
||||
c++;
|
||||
}
|
||||
|
||||
return(0);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
video_is_mda(void)
|
||||
{
|
||||
return (video_get_type() == VIDEO_FLAG_TYPE_MDA);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
video_is_cga(void)
|
||||
{
|
||||
return (video_get_type() == VIDEO_FLAG_TYPE_CGA);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
video_is_ega_vga(void)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -66,30 +66,28 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
svga_t svga;
|
||||
svga_t svga;
|
||||
|
||||
rom_t bios_rom;
|
||||
rom_t bios_rom;
|
||||
|
||||
int enabled;
|
||||
int enabled;
|
||||
|
||||
uint32_t vram_size;
|
||||
uint32_t vram_size;
|
||||
|
||||
uint8_t banking;
|
||||
uint8_t reg_2100;
|
||||
uint8_t reg_210a;
|
||||
uint8_t banking;
|
||||
uint8_t reg_2100;
|
||||
uint8_t reg_210a;
|
||||
} tivga_t;
|
||||
|
||||
static video_timings_t timing_ti_cf62011 = {VIDEO_ISA, 6, 8,16, 6, 8,16};
|
||||
|
||||
static video_timings_t timing_ti_cf62011 = { .type = VIDEO_ISA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 };
|
||||
|
||||
static void
|
||||
vid_out(uint16_t addr, uint8_t val, void *priv)
|
||||
{
|
||||
tivga_t *ti = (tivga_t *)priv;
|
||||
svga_t *svga = &ti->svga;
|
||||
uint8_t old;
|
||||
tivga_t *ti = (tivga_t *) priv;
|
||||
svga_t *svga = &ti->svga;
|
||||
uint8_t old;
|
||||
|
||||
#if 0
|
||||
if (((addr & 0xfff0) == 0x03d0 || (addr & 0xfff0) == 0x03b0) &&
|
||||
@@ -97,60 +95,59 @@ vid_out(uint16_t addr, uint8_t val, void *priv)
|
||||
#endif
|
||||
|
||||
switch (addr) {
|
||||
case 0x0102:
|
||||
ti->enabled = (val & 0x01);
|
||||
return;
|
||||
case 0x0102:
|
||||
ti->enabled = (val & 0x01);
|
||||
return;
|
||||
|
||||
case 0x03d4:
|
||||
svga->crtcreg = val & 0x3f;
|
||||
return;
|
||||
case 0x03d4:
|
||||
svga->crtcreg = val & 0x3f;
|
||||
return;
|
||||
|
||||
case 0x03d5:
|
||||
if (svga->crtcreg & 0x20)
|
||||
return;
|
||||
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
|
||||
return;
|
||||
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val) {
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x03d5:
|
||||
if (svga->crtcreg & 0x20)
|
||||
return;
|
||||
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
|
||||
return;
|
||||
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val) {
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x2100:
|
||||
ti->reg_2100 = val;
|
||||
if ((val & 7) < 4)
|
||||
svga->read_bank = svga->write_bank = 0;
|
||||
else
|
||||
svga->read_bank = svga->write_bank = (ti->banking & 0x7) * 0x10000;
|
||||
break;
|
||||
case 0x2100:
|
||||
ti->reg_2100 = val;
|
||||
if ((val & 7) < 4)
|
||||
svga->read_bank = svga->write_bank = 0;
|
||||
else
|
||||
svga->read_bank = svga->write_bank = (ti->banking & 0x7) * 0x10000;
|
||||
break;
|
||||
|
||||
case 0x2108:
|
||||
if ((ti->reg_2100 & 7) >= 4)
|
||||
svga->read_bank = svga->write_bank = (val & 0x7) * 0x10000;
|
||||
ti->banking = val;
|
||||
break;
|
||||
case 0x2108:
|
||||
if ((ti->reg_2100 & 7) >= 4)
|
||||
svga->read_bank = svga->write_bank = (val & 0x7) * 0x10000;
|
||||
ti->banking = val;
|
||||
break;
|
||||
|
||||
case 0x210a:
|
||||
ti->reg_210a = val;
|
||||
break;
|
||||
case 0x210a:
|
||||
ti->reg_210a = val;
|
||||
break;
|
||||
}
|
||||
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
|
||||
static uint8_t
|
||||
vid_in(uint16_t addr, void *priv)
|
||||
{
|
||||
tivga_t *ti = (tivga_t *)priv;
|
||||
svga_t *svga = &ti->svga;
|
||||
uint8_t ret;
|
||||
tivga_t *ti = (tivga_t *) priv;
|
||||
svga_t *svga = &ti->svga;
|
||||
uint8_t ret;
|
||||
|
||||
#if 0
|
||||
if (((addr & 0xfff0) == 0x03d0 || (addr & 0xfff0) == 0x03b0) &&
|
||||
@@ -158,120 +155,116 @@ vid_in(uint16_t addr, void *priv)
|
||||
#endif
|
||||
|
||||
switch (addr) {
|
||||
case 0x0100:
|
||||
ret = 0xfe;
|
||||
break;
|
||||
case 0x0100:
|
||||
ret = 0xfe;
|
||||
break;
|
||||
|
||||
case 0x0101:
|
||||
ret = 0xe8;
|
||||
break;
|
||||
case 0x0101:
|
||||
ret = 0xe8;
|
||||
break;
|
||||
|
||||
case 0x0102:
|
||||
ret = ti->enabled;
|
||||
break;
|
||||
case 0x0102:
|
||||
ret = ti->enabled;
|
||||
break;
|
||||
|
||||
case 0x03d4:
|
||||
ret = svga->crtcreg;
|
||||
break;
|
||||
case 0x03d4:
|
||||
ret = svga->crtcreg;
|
||||
break;
|
||||
|
||||
case 0x03d5:
|
||||
if (svga->crtcreg & 0x20)
|
||||
ret = 0xff;
|
||||
else
|
||||
ret = svga->crtc[svga->crtcreg];
|
||||
break;
|
||||
case 0x03d5:
|
||||
if (svga->crtcreg & 0x20)
|
||||
ret = 0xff;
|
||||
else
|
||||
ret = svga->crtc[svga->crtcreg];
|
||||
break;
|
||||
|
||||
case 0x2100:
|
||||
ret = ti->reg_2100;
|
||||
break;
|
||||
case 0x2100:
|
||||
ret = ti->reg_2100;
|
||||
break;
|
||||
|
||||
case 0x2108:
|
||||
ret = ti->banking;
|
||||
break;
|
||||
case 0x2108:
|
||||
ret = ti->banking;
|
||||
break;
|
||||
|
||||
case 0x210a:
|
||||
ret = ti->reg_210a;
|
||||
break;
|
||||
case 0x210a:
|
||||
ret = ti->reg_210a;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = svga_in(addr, svga);
|
||||
break;
|
||||
default:
|
||||
ret = svga_in(addr, svga);
|
||||
break;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vid_speed_changed(void *priv)
|
||||
{
|
||||
tivga_t *ti = (tivga_t *)priv;
|
||||
tivga_t *ti = (tivga_t *) priv;
|
||||
|
||||
svga_recalctimings(&ti->svga);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vid_force_redraw(void *priv)
|
||||
{
|
||||
tivga_t *ti = (tivga_t *)priv;
|
||||
tivga_t *ti = (tivga_t *) priv;
|
||||
|
||||
ti->svga.fullchange = changeframecount;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
vid_close(void *priv)
|
||||
{
|
||||
tivga_t *ti = (tivga_t *)priv;
|
||||
tivga_t *ti = (tivga_t *) priv;
|
||||
|
||||
svga_close(&ti->svga);
|
||||
|
||||
free(ti);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
vid_init(const device_t *info)
|
||||
{
|
||||
tivga_t *ti;
|
||||
|
||||
/* Allocate control block and initialize. */
|
||||
ti = (tivga_t *)malloc(sizeof(tivga_t));
|
||||
ti = (tivga_t *) malloc(sizeof(tivga_t));
|
||||
memset(ti, 0x00, sizeof(tivga_t));
|
||||
|
||||
/* Set amount of VRAM in KB. */
|
||||
if (info->local == 0)
|
||||
ti->vram_size = device_get_config_int("vram_size");
|
||||
ti->vram_size = device_get_config_int("vram_size");
|
||||
else
|
||||
ti->vram_size = info->local;
|
||||
ti->vram_size = info->local;
|
||||
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ti_cf62011);
|
||||
|
||||
svga_init(info, &ti->svga, ti,
|
||||
ti->vram_size<<10,
|
||||
NULL, vid_in, vid_out, NULL, NULL);
|
||||
ti->vram_size << 10,
|
||||
NULL, vid_in, vid_out, NULL, NULL);
|
||||
|
||||
io_sethandler(0x0100, 2, vid_in, NULL, NULL, NULL, NULL, NULL, ti);
|
||||
io_sethandler(0x03c0, 32, vid_in, NULL, NULL, vid_out, NULL, NULL, ti);
|
||||
io_sethandler(0x2100, 16, vid_in, NULL, NULL, vid_out, NULL, NULL, ti);
|
||||
|
||||
ti->svga.bpp = 8;
|
||||
ti->svga.bpp = 8;
|
||||
ti->svga.miscout = 1;
|
||||
|
||||
return(ti);
|
||||
return (ti);
|
||||
}
|
||||
|
||||
const device_t ibm_ps1_2121_device = {
|
||||
.name = "IBM PS/1 Model 2121 SVGA",
|
||||
.name = "IBM PS/1 Model 2121 SVGA",
|
||||
.internal_name = "ibm_ps1_2121",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 512,
|
||||
.init = vid_init,
|
||||
.close = vid_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 512,
|
||||
.init = vid_init,
|
||||
.close = vid_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = vid_speed_changed,
|
||||
.force_redraw = vid_force_redraw,
|
||||
.config = NULL
|
||||
.force_redraw = vid_force_redraw,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -28,76 +28,71 @@
|
||||
#include <86box/video.h>
|
||||
#include <86box/vid_svga.h>
|
||||
|
||||
|
||||
typedef struct tkd8001_ramdac_t
|
||||
{
|
||||
int state;
|
||||
typedef struct tkd8001_ramdac_t {
|
||||
int state;
|
||||
uint8_t ctrl;
|
||||
} tkd8001_ramdac_t;
|
||||
|
||||
|
||||
void
|
||||
tkd8001_ramdac_out(uint16_t addr, uint8_t val, void *p, svga_t *svga)
|
||||
{
|
||||
tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) p;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3C6:
|
||||
if (ramdac->state == 4) {
|
||||
ramdac->state = 0;
|
||||
ramdac->ctrl = val;
|
||||
switch (val >> 5) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 5:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 6:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
case 7:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x3C7:
|
||||
case 0x3C8:
|
||||
case 0x3C9:
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x3C6:
|
||||
if (ramdac->state == 4) {
|
||||
ramdac->state = 0;
|
||||
ramdac->ctrl = val;
|
||||
switch (val >> 5) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
svga->bpp = 8;
|
||||
break;
|
||||
case 5:
|
||||
svga->bpp = 15;
|
||||
break;
|
||||
case 6:
|
||||
svga->bpp = 24;
|
||||
break;
|
||||
case 7:
|
||||
svga->bpp = 16;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 0x3C7:
|
||||
case 0x3C8:
|
||||
case 0x3C9:
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
|
||||
uint8_t
|
||||
tkd8001_ramdac_in(uint16_t addr, void *p, svga_t *svga)
|
||||
{
|
||||
tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) p;
|
||||
|
||||
switch (addr) {
|
||||
case 0x3C6:
|
||||
if (ramdac->state == 4)
|
||||
return ramdac->ctrl;
|
||||
ramdac->state++;
|
||||
break;
|
||||
case 0x3C7:
|
||||
case 0x3C8:
|
||||
case 0x3C9:
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
case 0x3C6:
|
||||
if (ramdac->state == 4)
|
||||
return ramdac->ctrl;
|
||||
ramdac->state++;
|
||||
break;
|
||||
case 0x3C7:
|
||||
case 0x3C8:
|
||||
case 0x3C9:
|
||||
ramdac->state = 0;
|
||||
break;
|
||||
}
|
||||
return svga_in(addr, svga);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
tkd8001_ramdac_init(const device_t *info)
|
||||
{
|
||||
@@ -107,26 +102,25 @@ tkd8001_ramdac_init(const device_t *info)
|
||||
return ramdac;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
tkd8001_ramdac_close(void *priv)
|
||||
{
|
||||
tkd8001_ramdac_t *ramdac = (tkd8001_ramdac_t *) priv;
|
||||
|
||||
if (ramdac)
|
||||
free(ramdac);
|
||||
free(ramdac);
|
||||
}
|
||||
|
||||
const device_t tkd8001_ramdac_device = {
|
||||
.name = "Trident TKD8001 RAMDAC",
|
||||
.name = "Trident TKD8001 RAMDAC",
|
||||
.internal_name = "tkd8001_ramdac",
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = tkd8001_ramdac_init,
|
||||
.close = tkd8001_ramdac_close,
|
||||
.reset = NULL,
|
||||
.flags = 0,
|
||||
.local = 0,
|
||||
.init = tkd8001_ramdac_init,
|
||||
.close = tkd8001_ramdac_close,
|
||||
.reset = NULL,
|
||||
{ .available = NULL },
|
||||
.speed_changed = NULL,
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
.force_redraw = NULL,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
@@ -31,420 +31,453 @@
|
||||
#include <86box/vid_svga.h>
|
||||
#include <86box/vid_svga_render.h>
|
||||
|
||||
#define TVGA8900B_ID 0x03
|
||||
#define TVGA9000B_ID 0x23
|
||||
#define TVGA8900CLD_ID 0x33
|
||||
#define TVGA8900B_ID 0x03
|
||||
#define TVGA9000B_ID 0x23
|
||||
#define TVGA8900CLD_ID 0x33
|
||||
|
||||
#define ROM_TVGA_8900B "roms/video/tvga/tvga8900b.vbi"
|
||||
#define ROM_TVGA_8900CLD "roms/video/tvga/trident.bin"
|
||||
#define ROM_TVGA_9000B "roms/video/tvga/tvga9000b.bin"
|
||||
#define ROM_TVGA_8900B "roms/video/tvga/tvga8900b.vbi"
|
||||
#define ROM_TVGA_8900CLD "roms/video/tvga/trident.bin"
|
||||
#define ROM_TVGA_9000B "roms/video/tvga/tvga9000b.bin"
|
||||
|
||||
typedef struct tvga_t
|
||||
{
|
||||
mem_mapping_t linear_mapping;
|
||||
mem_mapping_t accel_mapping;
|
||||
typedef struct tvga_t {
|
||||
mem_mapping_t linear_mapping;
|
||||
mem_mapping_t accel_mapping;
|
||||
|
||||
svga_t svga;
|
||||
svga_t svga;
|
||||
|
||||
rom_t bios_rom;
|
||||
uint8_t card_id;
|
||||
rom_t bios_rom;
|
||||
uint8_t card_id;
|
||||
|
||||
uint8_t tvga_3d8, tvga_3d9;
|
||||
int oldmode;
|
||||
uint8_t oldctrl1;
|
||||
uint8_t oldctrl2, newctrl2;
|
||||
uint8_t tvga_3d8, tvga_3d9;
|
||||
int oldmode;
|
||||
uint8_t oldctrl1;
|
||||
uint8_t oldctrl2, newctrl2;
|
||||
|
||||
int vram_size;
|
||||
uint32_t vram_mask;
|
||||
int vram_size;
|
||||
uint32_t vram_mask;
|
||||
} tvga_t;
|
||||
|
||||
video_timings_t timing_tvga8900 = {VIDEO_ISA, 3, 3, 6, 8, 8, 12};
|
||||
video_timings_t timing_tvga9000 = {VIDEO_ISA, 7, 7, 12, 7, 7, 12};
|
||||
video_timings_t timing_tvga8900 = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 8, .read_w = 8, .read_l = 12 };
|
||||
video_timings_t timing_tvga9000 = { .type = VIDEO_ISA, .write_b = 7, .write_w = 7, .write_l = 12, .read_b = 7, .read_w = 7, .read_l = 12 };
|
||||
|
||||
static uint8_t crtc_mask[0x40] =
|
||||
{
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x7f, 0xff, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xef,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x7f, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x03,
|
||||
0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
static uint8_t crtc_mask[0x40] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x7f, 0xff, 0x3f, 0x7f, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xef,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x7f, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x03,
|
||||
0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
static void tvga_recalcbanking(tvga_t *tvga);
|
||||
void tvga_out(uint16_t addr, uint8_t val, void *p)
|
||||
void
|
||||
tvga_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
tvga_t *tvga = (tvga_t *)p;
|
||||
svga_t *svga = &tvga->svga;
|
||||
tvga_t *tvga = (tvga_t *) p;
|
||||
svga_t *svga = &tvga->svga;
|
||||
|
||||
uint8_t old;
|
||||
uint8_t old;
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60;
|
||||
if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3C5:
|
||||
switch (svga->seqaddr & 0xf)
|
||||
{
|
||||
case 0xB:
|
||||
tvga->oldmode=1;
|
||||
break;
|
||||
case 0xC:
|
||||
if (svga->seqregs[0xe] & 0x80)
|
||||
svga->seqregs[0xc] = val;
|
||||
break;
|
||||
case 0xd:
|
||||
if (tvga->oldmode)
|
||||
tvga->oldctrl2 = val;
|
||||
else
|
||||
{
|
||||
tvga->newctrl2 = val;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
break;
|
||||
case 0xE:
|
||||
if (tvga->oldmode)
|
||||
tvga->oldctrl1 = val;
|
||||
else
|
||||
{
|
||||
svga->seqregs[0xe] = val ^ 2;
|
||||
tvga->tvga_3d8 = svga->seqregs[0xe] & 0xf;
|
||||
tvga_recalcbanking(tvga);
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
if (tvga->card_id != TVGA9000B_ID) {
|
||||
tkd8001_ramdac_out(addr, val, svga->ramdac, svga);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3CF:
|
||||
switch (svga->gdcaddr & 15)
|
||||
{
|
||||
case 0x6:
|
||||
old = svga->gdcreg[6];
|
||||
svga_out(addr, val, svga);
|
||||
if ((old & 0xc) != 0 && (val & 0xc) == 0)
|
||||
{
|
||||
/*override mask - TVGA supports linear 128k at A0000*/
|
||||
svga->banked_mask = 0x1ffff;
|
||||
}
|
||||
return;
|
||||
case 0xE:
|
||||
svga->gdcreg[0xe] = val ^ 2;
|
||||
tvga->tvga_3d9 = svga->gdcreg[0xe] & 0xf;
|
||||
tvga_recalcbanking(tvga);
|
||||
break;
|
||||
case 0xF:
|
||||
svga->gdcreg[0xf] = val;
|
||||
tvga_recalcbanking(tvga);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x3D4:
|
||||
svga->crtcreg = val & 0x3f;
|
||||
return;
|
||||
case 0x3D5:
|
||||
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
|
||||
return;
|
||||
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
val &= crtc_mask[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val) {
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
|
||||
{
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (svga->crtcreg) {
|
||||
case 0x1e:
|
||||
svga->vram_display_mask = (val & 0x80) ? tvga->vram_mask : 0x3ffff;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
case 0x3D8:
|
||||
if (svga->gdcreg[0xf] & 4) {
|
||||
tvga->tvga_3d8 = val;
|
||||
tvga_recalcbanking(tvga);
|
||||
}
|
||||
return;
|
||||
case 0x3D9:
|
||||
if (svga->gdcreg[0xf] & 4) {
|
||||
tvga->tvga_3d9 = val;
|
||||
tvga_recalcbanking(tvga);
|
||||
}
|
||||
return;
|
||||
case 0x3DB:
|
||||
if (tvga->card_id != TVGA9000B_ID) {
|
||||
/*3db appears to be a 4 bit clock select register on 8900D*/
|
||||
svga->miscout = (svga->miscout & ~0x0c) | ((val & 3) << 2);
|
||||
tvga->newctrl2 = (tvga->newctrl2 & ~0x01) | ((val & 4) >> 2);
|
||||
tvga->oldctrl1 = (tvga->oldctrl1 & ~0x10) | ((val & 8) << 1);
|
||||
switch (addr) {
|
||||
case 0x3C5:
|
||||
switch (svga->seqaddr & 0xf) {
|
||||
case 0xB:
|
||||
tvga->oldmode = 1;
|
||||
break;
|
||||
case 0xC:
|
||||
if (svga->seqregs[0xe] & 0x80)
|
||||
svga->seqregs[0xc] = val;
|
||||
break;
|
||||
case 0xd:
|
||||
if (tvga->oldmode)
|
||||
tvga->oldctrl2 = val;
|
||||
else {
|
||||
tvga->newctrl2 = val;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
break;
|
||||
case 0xE:
|
||||
if (tvga->oldmode)
|
||||
tvga->oldctrl1 = val;
|
||||
else {
|
||||
svga->seqregs[0xe] = val ^ 2;
|
||||
tvga->tvga_3d8 = svga->seqregs[0xe] & 0xf;
|
||||
tvga_recalcbanking(tvga);
|
||||
}
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3C6:
|
||||
case 0x3C7:
|
||||
case 0x3C8:
|
||||
case 0x3C9:
|
||||
if (tvga->card_id != TVGA9000B_ID) {
|
||||
tkd8001_ramdac_out(addr, val, svga->ramdac, svga);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3CF:
|
||||
switch (svga->gdcaddr & 15) {
|
||||
case 0x6:
|
||||
old = svga->gdcreg[6];
|
||||
svga_out(addr, val, svga);
|
||||
if ((old & 0xc) != 0 && (val & 0xc) == 0) {
|
||||
/*override mask - TVGA supports linear 128k at A0000*/
|
||||
svga->banked_mask = 0x1ffff;
|
||||
}
|
||||
return;
|
||||
case 0xE:
|
||||
svga->gdcreg[0xe] = val ^ 2;
|
||||
tvga->tvga_3d9 = svga->gdcreg[0xe] & 0xf;
|
||||
tvga_recalcbanking(tvga);
|
||||
break;
|
||||
case 0xF:
|
||||
svga->gdcreg[0xf] = val;
|
||||
tvga_recalcbanking(tvga);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x3D4:
|
||||
svga->crtcreg = val & 0x3f;
|
||||
return;
|
||||
case 0x3D5:
|
||||
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
|
||||
return;
|
||||
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
val &= crtc_mask[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val) {
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
switch (svga->crtcreg) {
|
||||
case 0x1e:
|
||||
svga->vram_display_mask = (val & 0x80) ? tvga->vram_mask : 0x3ffff;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
case 0x3D8:
|
||||
if (svga->gdcreg[0xf] & 4) {
|
||||
tvga->tvga_3d8 = val;
|
||||
tvga_recalcbanking(tvga);
|
||||
}
|
||||
return;
|
||||
case 0x3D9:
|
||||
if (svga->gdcreg[0xf] & 4) {
|
||||
tvga->tvga_3d9 = val;
|
||||
tvga_recalcbanking(tvga);
|
||||
}
|
||||
return;
|
||||
case 0x3DB:
|
||||
if (tvga->card_id != TVGA9000B_ID) {
|
||||
/*3db appears to be a 4 bit clock select register on 8900D*/
|
||||
svga->miscout = (svga->miscout & ~0x0c) | ((val & 3) << 2);
|
||||
tvga->newctrl2 = (tvga->newctrl2 & ~0x01) | ((val & 4) >> 2);
|
||||
tvga->oldctrl1 = (tvga->oldctrl1 & ~0x10) | ((val & 8) << 1);
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t tvga_in(uint16_t addr, void *p)
|
||||
uint8_t
|
||||
tvga_in(uint16_t addr, void *p)
|
||||
{
|
||||
tvga_t *tvga = (tvga_t *)p;
|
||||
svga_t *svga = &tvga->svga;
|
||||
tvga_t *tvga = (tvga_t *) p;
|
||||
svga_t *svga = &tvga->svga;
|
||||
|
||||
if (((addr&0xFFF0) == 0x3D0 || (addr&0xFFF0) == 0x3B0) && !(svga->miscout & 1)) addr ^= 0x60;
|
||||
if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3C5:
|
||||
if ((svga->seqaddr & 0xf) == 0xb)
|
||||
{
|
||||
tvga->oldmode = 0;
|
||||
return tvga->card_id; /*Must be at least a TVGA8900*/
|
||||
}
|
||||
if ((svga->seqaddr & 0xf) == 0xd)
|
||||
{
|
||||
if (tvga->oldmode) return tvga->oldctrl2;
|
||||
return tvga->newctrl2;
|
||||
}
|
||||
if ((svga->seqaddr & 0xf) == 0xe)
|
||||
{
|
||||
if (tvga->oldmode)
|
||||
return tvga->oldctrl1;
|
||||
}
|
||||
break;
|
||||
case 0x3C6: case 0x3C7: case 0x3C8: case 0x3C9:
|
||||
if (tvga->card_id != TVGA9000B_ID) {
|
||||
return tkd8001_ramdac_in(addr, svga->ramdac, svga);
|
||||
}
|
||||
break;
|
||||
case 0x3D4:
|
||||
return svga->crtcreg;
|
||||
case 0x3D5:
|
||||
if (svga->crtcreg > 0x18 && svga->crtcreg < 0x1e)
|
||||
return 0xff;
|
||||
return svga->crtc[svga->crtcreg];
|
||||
case 0x3d8:
|
||||
return tvga->tvga_3d8;
|
||||
case 0x3d9:
|
||||
return tvga->tvga_3d9;
|
||||
}
|
||||
return svga_in(addr, svga);
|
||||
switch (addr) {
|
||||
case 0x3C5:
|
||||
if ((svga->seqaddr & 0xf) == 0xb) {
|
||||
tvga->oldmode = 0;
|
||||
return tvga->card_id; /*Must be at least a TVGA8900*/
|
||||
}
|
||||
if ((svga->seqaddr & 0xf) == 0xd) {
|
||||
if (tvga->oldmode)
|
||||
return tvga->oldctrl2;
|
||||
return tvga->newctrl2;
|
||||
}
|
||||
if ((svga->seqaddr & 0xf) == 0xe) {
|
||||
if (tvga->oldmode)
|
||||
return tvga->oldctrl1;
|
||||
}
|
||||
break;
|
||||
case 0x3C6:
|
||||
case 0x3C7:
|
||||
case 0x3C8:
|
||||
case 0x3C9:
|
||||
if (tvga->card_id != TVGA9000B_ID) {
|
||||
return tkd8001_ramdac_in(addr, svga->ramdac, svga);
|
||||
}
|
||||
break;
|
||||
case 0x3D4:
|
||||
return svga->crtcreg;
|
||||
case 0x3D5:
|
||||
if (svga->crtcreg > 0x18 && svga->crtcreg < 0x1e)
|
||||
return 0xff;
|
||||
return svga->crtc[svga->crtcreg];
|
||||
case 0x3d8:
|
||||
return tvga->tvga_3d8;
|
||||
case 0x3d9:
|
||||
return tvga->tvga_3d9;
|
||||
}
|
||||
return svga_in(addr, svga);
|
||||
}
|
||||
|
||||
static void tvga_recalcbanking(tvga_t *tvga)
|
||||
static void
|
||||
tvga_recalcbanking(tvga_t *tvga)
|
||||
{
|
||||
svga_t *svga = &tvga->svga;
|
||||
svga_t *svga = &tvga->svga;
|
||||
|
||||
svga->write_bank = (tvga->tvga_3d8 & 0x1f) * 65536;
|
||||
svga->write_bank = (tvga->tvga_3d8 & 0x1f) * 65536;
|
||||
|
||||
if (svga->gdcreg[0xf] & 1)
|
||||
svga->read_bank = (tvga->tvga_3d9 & 0x1f) * 65536;
|
||||
else
|
||||
svga->read_bank = svga->write_bank;
|
||||
if (svga->gdcreg[0xf] & 1)
|
||||
svga->read_bank = (tvga->tvga_3d9 & 0x1f) * 65536;
|
||||
else
|
||||
svga->read_bank = svga->write_bank;
|
||||
}
|
||||
|
||||
void tvga_recalctimings(svga_t *svga)
|
||||
void
|
||||
tvga_recalctimings(svga_t *svga)
|
||||
{
|
||||
tvga_t *tvga = (tvga_t *)svga->p;
|
||||
int clksel;
|
||||
int high_res_256 = 0;
|
||||
tvga_t *tvga = (tvga_t *) svga->p;
|
||||
int clksel;
|
||||
int high_res_256 = 0;
|
||||
|
||||
if (!svga->rowoffset) svga->rowoffset = 0x100; /*This is the only sensible way I can see this being handled,
|
||||
given that TVGA8900D has no overflow bits.
|
||||
Some sort of overflow is required for 320x200x24 and 1024x768x16*/
|
||||
if (svga->crtc[0x29] & 0x10)
|
||||
svga->rowoffset += 0x100;
|
||||
if (!svga->rowoffset)
|
||||
svga->rowoffset = 0x100; /*This is the only sensible way I can see this being handled,
|
||||
given that TVGA8900D has no overflow bits.
|
||||
Some sort of overflow is required for 320x200x24 and 1024x768x16*/
|
||||
if (svga->crtc[0x29] & 0x10)
|
||||
svga->rowoffset += 0x100;
|
||||
|
||||
if (svga->bpp == 24)
|
||||
svga->hdisp = (svga->crtc[1] + 1) * 8;
|
||||
if (svga->bpp == 24)
|
||||
svga->hdisp = (svga->crtc[1] + 1) * 8;
|
||||
|
||||
if ((svga->crtc[0x1e] & 0xA0) == 0xA0) svga->ma_latch |= 0x10000;
|
||||
if ((svga->crtc[0x27] & 0x01) == 0x01) svga->ma_latch |= 0x20000;
|
||||
if ((svga->crtc[0x27] & 0x02) == 0x02) svga->ma_latch |= 0x40000;
|
||||
if ((svga->crtc[0x1e] & 0xA0) == 0xA0)
|
||||
svga->ma_latch |= 0x10000;
|
||||
if ((svga->crtc[0x27] & 0x01) == 0x01)
|
||||
svga->ma_latch |= 0x20000;
|
||||
if ((svga->crtc[0x27] & 0x02) == 0x02)
|
||||
svga->ma_latch |= 0x40000;
|
||||
|
||||
if (tvga->oldctrl2 & 0x10)
|
||||
{
|
||||
svga->rowoffset <<= 1;
|
||||
svga->ma_latch <<= 1;
|
||||
}
|
||||
if (tvga->oldctrl2 & 0x10) {
|
||||
svga->rowoffset <<= 1;
|
||||
svga->ma_latch <<= 1;
|
||||
}
|
||||
|
||||
if (svga->gdcreg[0xf] & 0x08)
|
||||
{
|
||||
svga->htotal *= 2;
|
||||
svga->hdisp *= 2;
|
||||
svga->hdisp_time *= 2;
|
||||
}
|
||||
if (svga->gdcreg[0xf] & 0x08) {
|
||||
svga->htotal *= 2;
|
||||
svga->hdisp *= 2;
|
||||
svga->hdisp_time *= 2;
|
||||
}
|
||||
|
||||
svga->interlace = (svga->crtc[0x1e] & 4);
|
||||
svga->interlace = (svga->crtc[0x1e] & 4);
|
||||
|
||||
if (svga->interlace)
|
||||
svga->rowoffset >>= 1;
|
||||
|
||||
if (tvga->card_id == TVGA8900CLD_ID)
|
||||
clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->oldctrl1 & 0x10) >> 1);
|
||||
else
|
||||
clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->newctrl2 & 0x40) >> 3);
|
||||
|
||||
switch (clksel) {
|
||||
case 0x2:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0;
|
||||
break;
|
||||
case 0x3:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 36000000.0;
|
||||
break;
|
||||
case 0x4:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 57272000.0;
|
||||
break;
|
||||
case 0x5:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 65000000.0;
|
||||
break;
|
||||
case 0x6:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 50350000.0;
|
||||
break;
|
||||
case 0x7:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 40000000.0;
|
||||
break;
|
||||
case 0x8:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 88000000.0;
|
||||
break;
|
||||
case 0x9:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 98000000.0;
|
||||
break;
|
||||
case 0xa:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 118800000.0;
|
||||
break;
|
||||
case 0xb:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 108000000.0;
|
||||
break;
|
||||
case 0xc:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 72000000.0;
|
||||
break;
|
||||
case 0xd:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 77000000.0;
|
||||
break;
|
||||
case 0xe:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 80000000.0;
|
||||
break;
|
||||
case 0xf:
|
||||
svga->clock = (cpuclock * (double) (1ull << 32)) / 75000000.0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (tvga->card_id != TVGA8900CLD_ID) {
|
||||
/*TVGA9000 doesn't seem to have support for a 'high res' 256 colour mode
|
||||
(without the VGA pixel doubling). Instead it implements these modes by
|
||||
doubling the horizontal pixel count and pixel clock. Hence we use a
|
||||
basic heuristic to detect this*/
|
||||
if (svga->interlace)
|
||||
svga->rowoffset >>= 1;
|
||||
high_res_256 = (svga->htotal * 8) > (svga->vtotal * 4);
|
||||
else
|
||||
high_res_256 = (svga->htotal * 8) > (svga->vtotal * 2);
|
||||
}
|
||||
|
||||
if (tvga->card_id == TVGA8900CLD_ID)
|
||||
clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->oldctrl1 & 0x10) >> 1);
|
||||
else
|
||||
clksel = ((svga->miscout >> 2) & 3) | ((tvga->newctrl2 & 0x01) << 2) | ((tvga->newctrl2 & 0x40) >> 3);
|
||||
|
||||
switch (clksel) {
|
||||
case 0x2: svga->clock = (cpuclock * (double)(1ull << 32)) / 44900000.0; break;
|
||||
case 0x3: svga->clock = (cpuclock * (double)(1ull << 32)) / 36000000.0; break;
|
||||
case 0x4: svga->clock = (cpuclock * (double)(1ull << 32)) / 57272000.0; break;
|
||||
case 0x5: svga->clock = (cpuclock * (double)(1ull << 32)) / 65000000.0; break;
|
||||
case 0x6: svga->clock = (cpuclock * (double)(1ull << 32)) / 50350000.0; break;
|
||||
case 0x7: svga->clock = (cpuclock * (double)(1ull << 32)) / 40000000.0; break;
|
||||
case 0x8: svga->clock = (cpuclock * (double)(1ull << 32)) / 88000000.0; break;
|
||||
case 0x9: svga->clock = (cpuclock * (double)(1ull << 32)) / 98000000.0; break;
|
||||
case 0xa: svga->clock = (cpuclock * (double)(1ull << 32)) / 118800000.0; break;
|
||||
case 0xb: svga->clock = (cpuclock * (double)(1ull << 32)) / 108000000.0; break;
|
||||
case 0xc: svga->clock = (cpuclock * (double)(1ull << 32)) / 72000000.0; break;
|
||||
case 0xd: svga->clock = (cpuclock * (double)(1ull << 32)) / 77000000.0; break;
|
||||
case 0xe: svga->clock = (cpuclock * (double)(1ull << 32)) / 80000000.0; break;
|
||||
case 0xf: svga->clock = (cpuclock * (double)(1ull << 32)) / 75000000.0; break;
|
||||
}
|
||||
|
||||
if (tvga->card_id != TVGA8900CLD_ID) {
|
||||
/*TVGA9000 doesn't seem to have support for a 'high res' 256 colour mode
|
||||
(without the VGA pixel doubling). Instead it implements these modes by
|
||||
doubling the horizontal pixel count and pixel clock. Hence we use a
|
||||
basic heuristic to detect this*/
|
||||
if (svga->interlace)
|
||||
high_res_256 = (svga->htotal * 8) > (svga->vtotal * 4);
|
||||
else
|
||||
high_res_256 = (svga->htotal * 8) > (svga->vtotal * 2);
|
||||
}
|
||||
|
||||
if ((tvga->oldctrl2 & 0x10) || high_res_256)
|
||||
{
|
||||
if (high_res_256)
|
||||
svga->hdisp /= 2;
|
||||
switch (svga->bpp)
|
||||
{
|
||||
case 8:
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
case 15:
|
||||
svga->render = svga_render_15bpp_highres;
|
||||
svga->hdisp /= 2;
|
||||
break;
|
||||
case 16:
|
||||
svga->render = svga_render_16bpp_highres;
|
||||
svga->hdisp /= 2;
|
||||
break;
|
||||
case 24:
|
||||
svga->render = svga_render_24bpp_highres;
|
||||
svga->hdisp /= 3;
|
||||
break;
|
||||
}
|
||||
svga->lowres = 0;
|
||||
if ((tvga->oldctrl2 & 0x10) || high_res_256) {
|
||||
if (high_res_256)
|
||||
svga->hdisp /= 2;
|
||||
switch (svga->bpp) {
|
||||
case 8:
|
||||
svga->render = svga_render_8bpp_highres;
|
||||
break;
|
||||
case 15:
|
||||
svga->render = svga_render_15bpp_highres;
|
||||
svga->hdisp /= 2;
|
||||
break;
|
||||
case 16:
|
||||
svga->render = svga_render_16bpp_highres;
|
||||
svga->hdisp /= 2;
|
||||
break;
|
||||
case 24:
|
||||
svga->render = svga_render_24bpp_highres;
|
||||
svga->hdisp /= 3;
|
||||
break;
|
||||
}
|
||||
svga->lowres = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void *tvga_init(const device_t *info)
|
||||
static void *
|
||||
tvga_init(const device_t *info)
|
||||
{
|
||||
const char *bios_fn;
|
||||
tvga_t *tvga = malloc(sizeof(tvga_t));
|
||||
memset(tvga, 0, sizeof(tvga_t));
|
||||
const char *bios_fn;
|
||||
tvga_t *tvga = malloc(sizeof(tvga_t));
|
||||
memset(tvga, 0, sizeof(tvga_t));
|
||||
|
||||
if (info->local == TVGA9000B_ID) {
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga9000);
|
||||
tvga->vram_size = 512 << 10;
|
||||
} else {
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga8900);
|
||||
tvga->vram_size = device_get_config_int("memory") << 10;
|
||||
}
|
||||
if (info->local == TVGA9000B_ID) {
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga9000);
|
||||
tvga->vram_size = 512 << 10;
|
||||
} else {
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_tvga8900);
|
||||
tvga->vram_size = device_get_config_int("memory") << 10;
|
||||
}
|
||||
|
||||
tvga->vram_mask = tvga->vram_size - 1;
|
||||
tvga->vram_mask = tvga->vram_size - 1;
|
||||
|
||||
tvga->card_id = info->local;
|
||||
tvga->card_id = info->local;
|
||||
|
||||
switch (info->local)
|
||||
{
|
||||
case TVGA8900B_ID:
|
||||
bios_fn = ROM_TVGA_8900B;
|
||||
break;
|
||||
case TVGA8900CLD_ID:
|
||||
bios_fn = ROM_TVGA_8900CLD;
|
||||
break;
|
||||
case TVGA9000B_ID:
|
||||
bios_fn = ROM_TVGA_9000B;
|
||||
break;
|
||||
default:
|
||||
free(tvga);
|
||||
return NULL;
|
||||
}
|
||||
switch (info->local) {
|
||||
case TVGA8900B_ID:
|
||||
bios_fn = ROM_TVGA_8900B;
|
||||
break;
|
||||
case TVGA8900CLD_ID:
|
||||
bios_fn = ROM_TVGA_8900CLD;
|
||||
break;
|
||||
case TVGA9000B_ID:
|
||||
bios_fn = ROM_TVGA_9000B;
|
||||
break;
|
||||
default:
|
||||
free(tvga);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
rom_init(&tvga->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
rom_init(&tvga->bios_rom, (char *) bios_fn, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
svga_init(info, &tvga->svga, tvga, tvga->vram_size,
|
||||
tvga_recalctimings,
|
||||
tvga_in, tvga_out,
|
||||
NULL,
|
||||
NULL);
|
||||
svga_init(info, &tvga->svga, tvga, tvga->vram_size,
|
||||
tvga_recalctimings,
|
||||
tvga_in, tvga_out,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (info->local != TVGA9000B_ID)
|
||||
tvga->svga.ramdac = device_add(&tkd8001_ramdac_device);
|
||||
if (info->local != TVGA9000B_ID)
|
||||
tvga->svga.ramdac = device_add(&tkd8001_ramdac_device);
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga);
|
||||
io_sethandler(0x03c0, 0x0020, tvga_in, NULL, NULL, tvga_out, NULL, NULL, tvga);
|
||||
|
||||
return tvga;
|
||||
return tvga;
|
||||
}
|
||||
|
||||
static int tvga8900b_available(void)
|
||||
static int
|
||||
tvga8900b_available(void)
|
||||
{
|
||||
return rom_present(ROM_TVGA_8900B);
|
||||
return rom_present(ROM_TVGA_8900B);
|
||||
}
|
||||
|
||||
static int tvga8900d_available(void)
|
||||
static int
|
||||
tvga8900d_available(void)
|
||||
{
|
||||
return rom_present(ROM_TVGA_8900CLD);
|
||||
return rom_present(ROM_TVGA_8900CLD);
|
||||
}
|
||||
|
||||
static int tvga9000b_available(void)
|
||||
static int
|
||||
tvga9000b_available(void)
|
||||
{
|
||||
return rom_present(ROM_TVGA_9000B);
|
||||
return rom_present(ROM_TVGA_9000B);
|
||||
}
|
||||
|
||||
void tvga_close(void *p)
|
||||
void
|
||||
tvga_close(void *p)
|
||||
{
|
||||
tvga_t *tvga = (tvga_t *)p;
|
||||
tvga_t *tvga = (tvga_t *) p;
|
||||
|
||||
svga_close(&tvga->svga);
|
||||
svga_close(&tvga->svga);
|
||||
|
||||
free(tvga);
|
||||
free(tvga);
|
||||
}
|
||||
|
||||
void tvga_speed_changed(void *p)
|
||||
void
|
||||
tvga_speed_changed(void *p)
|
||||
{
|
||||
tvga_t *tvga = (tvga_t *)p;
|
||||
tvga_t *tvga = (tvga_t *) p;
|
||||
|
||||
svga_recalctimings(&tvga->svga);
|
||||
svga_recalctimings(&tvga->svga);
|
||||
}
|
||||
|
||||
void tvga_force_redraw(void *p)
|
||||
void
|
||||
tvga_force_redraw(void *p)
|
||||
{
|
||||
tvga_t *tvga = (tvga_t *)p;
|
||||
tvga_t *tvga = (tvga_t *) p;
|
||||
|
||||
tvga->svga.fullchange = changeframecount;
|
||||
tvga->svga.fullchange = changeframecount;
|
||||
}
|
||||
|
||||
static const device_config_t tvga_config[] = {
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
{
|
||||
.name = "memory",
|
||||
.description = "Memory size",
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,194 +31,195 @@
|
||||
#include <86box/vid_svga.h>
|
||||
#include <86box/vid_vga.h>
|
||||
|
||||
static video_timings_t timing_ps1_svga_isa = { .type = VIDEO_ISA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 };
|
||||
static video_timings_t timing_ps1_svga_mca = { .type = VIDEO_MCA, .write_b = 6, .write_w = 8, .write_l = 16, .read_b = 6, .read_w = 8, .read_l = 16 };
|
||||
|
||||
static video_timings_t timing_ps1_svga_isa = {VIDEO_ISA, 6, 8, 16, 6, 8, 16};
|
||||
static video_timings_t timing_ps1_svga_mca = {VIDEO_MCA, 6, 8, 16, 6, 8, 16};
|
||||
|
||||
void vga_out(uint16_t addr, uint8_t val, void *p)
|
||||
void
|
||||
vga_out(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
vga_t *vga = (vga_t *)p;
|
||||
svga_t *svga = &vga->svga;
|
||||
uint8_t old;
|
||||
vga_t *vga = (vga_t *) p;
|
||||
svga_t *svga = &vga->svga;
|
||||
uint8_t old;
|
||||
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D4:
|
||||
svga->crtcreg = val & 0x3f;
|
||||
switch (addr) {
|
||||
case 0x3D4:
|
||||
svga->crtcreg = val & 0x3f;
|
||||
return;
|
||||
case 0x3D5:
|
||||
if (svga->crtcreg & 0x20)
|
||||
return;
|
||||
case 0x3D5:
|
||||
if (svga->crtcreg & 0x20)
|
||||
return;
|
||||
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
|
||||
return;
|
||||
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val)
|
||||
{
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
|
||||
{
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80))
|
||||
return;
|
||||
if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80))
|
||||
val = (svga->crtc[7] & ~0x10) | (val & 0x10);
|
||||
old = svga->crtc[svga->crtcreg];
|
||||
svga->crtc[svga->crtcreg] = val;
|
||||
if (old != val) {
|
||||
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) {
|
||||
if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) {
|
||||
svga->fullchange = 3;
|
||||
svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5);
|
||||
} else {
|
||||
svga->fullchange = changeframecount;
|
||||
svga_recalctimings(svga);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
break;
|
||||
}
|
||||
svga_out(addr, val, svga);
|
||||
}
|
||||
|
||||
uint8_t vga_in(uint16_t addr, void *p)
|
||||
uint8_t
|
||||
vga_in(uint16_t addr, void *p)
|
||||
{
|
||||
vga_t *vga = (vga_t *)p;
|
||||
svga_t *svga = &vga->svga;
|
||||
uint8_t temp;
|
||||
vga_t *vga = (vga_t *) p;
|
||||
svga_t *svga = &vga->svga;
|
||||
uint8_t temp;
|
||||
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1))
|
||||
addr ^= 0x60;
|
||||
|
||||
switch (addr)
|
||||
{
|
||||
case 0x3D4:
|
||||
temp = svga->crtcreg;
|
||||
break;
|
||||
case 0x3D5:
|
||||
if (svga->crtcreg & 0x20)
|
||||
temp = 0xff;
|
||||
else
|
||||
temp = svga->crtc[svga->crtcreg];
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
}
|
||||
return temp;
|
||||
switch (addr) {
|
||||
case 0x3D4:
|
||||
temp = svga->crtcreg;
|
||||
break;
|
||||
case 0x3D5:
|
||||
if (svga->crtcreg & 0x20)
|
||||
temp = 0xff;
|
||||
else
|
||||
temp = svga->crtc[svga->crtcreg];
|
||||
break;
|
||||
default:
|
||||
temp = svga_in(addr, svga);
|
||||
break;
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
|
||||
static void *vga_init(const device_t *info)
|
||||
static void *
|
||||
vga_init(const device_t *info)
|
||||
{
|
||||
vga_t *vga = malloc(sizeof(vga_t));
|
||||
memset(vga, 0, sizeof(vga_t));
|
||||
vga_t *vga = malloc(sizeof(vga_t));
|
||||
memset(vga, 0, sizeof(vga_t));
|
||||
|
||||
rom_init(&vga->bios_rom, "roms/video/vga/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL);
|
||||
rom_init(&vga->bios_rom, "roms/video/vga/ibm_vga.bin", 0xc0000, 0x8000, 0x7fff, 0x2000, MEM_MAPPING_EXTERNAL);
|
||||
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_vga);
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_vga);
|
||||
|
||||
svga_init(info, &vga->svga, vga, 1 << 18, /*256kb*/
|
||||
NULL,
|
||||
vga_in, vga_out,
|
||||
NULL,
|
||||
NULL);
|
||||
svga_init(info, &vga->svga, vga, 1 << 18, /*256kb*/
|
||||
NULL,
|
||||
vga_in, vga_out,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga);
|
||||
io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga);
|
||||
|
||||
vga->svga.bpp = 8;
|
||||
vga->svga.miscout = 1;
|
||||
vga->svga.bpp = 8;
|
||||
vga->svga.miscout = 1;
|
||||
|
||||
return vga;
|
||||
return vga;
|
||||
}
|
||||
|
||||
|
||||
/*PS/1 uses a standard VGA controller, but with no option ROM*/
|
||||
void *ps1vga_init(const device_t *info)
|
||||
void *
|
||||
ps1vga_init(const device_t *info)
|
||||
{
|
||||
vga_t *vga = malloc(sizeof(vga_t));
|
||||
memset(vga, 0, sizeof(vga_t));
|
||||
vga_t *vga = malloc(sizeof(vga_t));
|
||||
memset(vga, 0, sizeof(vga_t));
|
||||
|
||||
if (info->flags & DEVICE_MCA)
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ps1_svga_mca);
|
||||
else
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ps1_svga_isa);
|
||||
if (info->flags & DEVICE_MCA)
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ps1_svga_mca);
|
||||
else
|
||||
video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_ps1_svga_isa);
|
||||
|
||||
svga_init(info, &vga->svga, vga, 1 << 18, /*256kb*/
|
||||
NULL,
|
||||
vga_in, vga_out,
|
||||
NULL,
|
||||
NULL);
|
||||
svga_init(info, &vga->svga, vga, 1 << 18, /*256kb*/
|
||||
NULL,
|
||||
vga_in, vga_out,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga);
|
||||
io_sethandler(0x03c0, 0x0020, vga_in, NULL, NULL, vga_out, NULL, NULL, vga);
|
||||
|
||||
vga->svga.bpp = 8;
|
||||
vga->svga.miscout = 1;
|
||||
vga->svga.bpp = 8;
|
||||
vga->svga.miscout = 1;
|
||||
|
||||
return vga;
|
||||
return vga;
|
||||
}
|
||||
|
||||
static int vga_available(void)
|
||||
static int
|
||||
vga_available(void)
|
||||
{
|
||||
return rom_present("roms/video/vga/ibm_vga.bin");
|
||||
return rom_present("roms/video/vga/ibm_vga.bin");
|
||||
}
|
||||
|
||||
void vga_close(void *p)
|
||||
void
|
||||
vga_close(void *p)
|
||||
{
|
||||
vga_t *vga = (vga_t *)p;
|
||||
vga_t *vga = (vga_t *) p;
|
||||
|
||||
svga_close(&vga->svga);
|
||||
svga_close(&vga->svga);
|
||||
|
||||
free(vga);
|
||||
free(vga);
|
||||
}
|
||||
|
||||
void vga_speed_changed(void *p)
|
||||
void
|
||||
vga_speed_changed(void *p)
|
||||
{
|
||||
vga_t *vga = (vga_t *)p;
|
||||
vga_t *vga = (vga_t *) p;
|
||||
|
||||
svga_recalctimings(&vga->svga);
|
||||
svga_recalctimings(&vga->svga);
|
||||
}
|
||||
|
||||
void vga_force_redraw(void *p)
|
||||
void
|
||||
vga_force_redraw(void *p)
|
||||
{
|
||||
vga_t *vga = (vga_t *)p;
|
||||
vga_t *vga = (vga_t *) p;
|
||||
|
||||
vga->svga.fullchange = changeframecount;
|
||||
vga->svga.fullchange = changeframecount;
|
||||
}
|
||||
|
||||
const device_t vga_device = {
|
||||
.name = "VGA",
|
||||
.name = "VGA",
|
||||
.internal_name = "vga",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = vga_init,
|
||||
.close = vga_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = vga_init,
|
||||
.close = vga_close,
|
||||
.reset = NULL,
|
||||
{ .available = vga_available },
|
||||
.speed_changed = vga_speed_changed,
|
||||
.force_redraw = vga_force_redraw,
|
||||
.config = NULL
|
||||
.force_redraw = vga_force_redraw,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t ps1vga_device = {
|
||||
.name = "PS/1 VGA",
|
||||
.name = "PS/1 VGA",
|
||||
.internal_name = "ps1vga",
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = ps1vga_init,
|
||||
.close = vga_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_ISA,
|
||||
.local = 0,
|
||||
.init = ps1vga_init,
|
||||
.close = vga_close,
|
||||
.reset = NULL,
|
||||
{ .available = vga_available },
|
||||
.speed_changed = vga_speed_changed,
|
||||
.force_redraw = vga_force_redraw,
|
||||
.config = NULL
|
||||
.force_redraw = vga_force_redraw,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
const device_t ps1vga_mca_device = {
|
||||
.name = "PS/1 VGA",
|
||||
.name = "PS/1 VGA",
|
||||
.internal_name = "ps1vga_mca",
|
||||
.flags = DEVICE_MCA,
|
||||
.local = 0,
|
||||
.init = ps1vga_init,
|
||||
.close = vga_close,
|
||||
.reset = NULL,
|
||||
.flags = DEVICE_MCA,
|
||||
.local = 0,
|
||||
.init = ps1vga_init,
|
||||
.close = vga_close,
|
||||
.reset = NULL,
|
||||
{ .available = vga_available },
|
||||
.speed_changed = vga_speed_changed,
|
||||
.force_redraw = vga_force_redraw,
|
||||
.config = NULL
|
||||
.force_redraw = vga_force_redraw,
|
||||
.config = NULL
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -39,519 +39,479 @@
|
||||
#include <86box/vid_voodoo_regs.h>
|
||||
#include <86box/vid_voodoo_render.h>
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
BLIT_COMMAND_SCREEN_TO_SCREEN = 0,
|
||||
BLIT_COMMAND_CPU_TO_SCREEN = 1,
|
||||
BLIT_COMMAND_RECT_FILL = 2,
|
||||
BLIT_COMMAND_SGRAM_FILL = 3
|
||||
enum {
|
||||
BLIT_COMMAND_SCREEN_TO_SCREEN = 0,
|
||||
BLIT_COMMAND_CPU_TO_SCREEN = 1,
|
||||
BLIT_COMMAND_RECT_FILL = 2,
|
||||
BLIT_COMMAND_SGRAM_FILL = 3
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
BLIT_SRC_1BPP = (0 << 3),
|
||||
BLIT_SRC_1BPP_BYTE_PACKED = (1 << 3),
|
||||
BLIT_SRC_16BPP = (2 << 3),
|
||||
BLIT_SRC_24BPP = (3 << 3),
|
||||
BLIT_SRC_24BPP_DITHER_2X2 = (4 << 3),
|
||||
BLIT_SRC_24BPP_DITHER_4X4 = (5 << 3)
|
||||
enum {
|
||||
BLIT_SRC_1BPP = (0 << 3),
|
||||
BLIT_SRC_1BPP_BYTE_PACKED = (1 << 3),
|
||||
BLIT_SRC_16BPP = (2 << 3),
|
||||
BLIT_SRC_24BPP = (3 << 3),
|
||||
BLIT_SRC_24BPP_DITHER_2X2 = (4 << 3),
|
||||
BLIT_SRC_24BPP_DITHER_4X4 = (5 << 3)
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
BLIT_SRC_RGB_ARGB = (0 << 6),
|
||||
BLIT_SRC_RGB_ABGR = (1 << 6),
|
||||
BLIT_SRC_RGB_RGBA = (2 << 6),
|
||||
BLIT_SRC_RGB_BGRA = (3 << 6)
|
||||
enum {
|
||||
BLIT_SRC_RGB_ARGB = (0 << 6),
|
||||
BLIT_SRC_RGB_ABGR = (1 << 6),
|
||||
BLIT_SRC_RGB_RGBA = (2 << 6),
|
||||
BLIT_SRC_RGB_BGRA = (3 << 6)
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
BLIT_COMMAND_MASK = 7,
|
||||
BLIT_SRC_FORMAT = (7 << 3),
|
||||
BLIT_SRC_RGB_FORMAT = (3 << 6),
|
||||
BLIT_SRC_CHROMA = (1 << 10),
|
||||
BLIT_DST_CHROMA = (1 << 12),
|
||||
BLIT_CLIPPING_ENABLED = (1 << 16)
|
||||
enum {
|
||||
BLIT_COMMAND_MASK = 7,
|
||||
BLIT_SRC_FORMAT = (7 << 3),
|
||||
BLIT_SRC_RGB_FORMAT = (3 << 6),
|
||||
BLIT_SRC_CHROMA = (1 << 10),
|
||||
BLIT_DST_CHROMA = (1 << 12),
|
||||
BLIT_CLIPPING_ENABLED = (1 << 16)
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
BLIT_ROP_DST_PASS = (1 << 0),
|
||||
BLIT_ROP_SRC_PASS = (1 << 1)
|
||||
enum {
|
||||
BLIT_ROP_DST_PASS = (1 << 0),
|
||||
BLIT_ROP_SRC_PASS = (1 << 1)
|
||||
};
|
||||
|
||||
|
||||
#ifdef ENABLE_VOODOOBLT_LOG
|
||||
int voodooblt_do_log = ENABLE_VOODOOBLT_LOG;
|
||||
|
||||
|
||||
static void
|
||||
voodooblt_log(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (voodooblt_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define voodooblt_log(fmt, ...)
|
||||
# define voodooblt_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
#define MIX(src_dat, dst_dat, rop) \
|
||||
switch (rop) { \
|
||||
case 0x0: \
|
||||
dst_dat = 0; \
|
||||
break; \
|
||||
case 0x1: \
|
||||
dst_dat = ~(src_dat | dst_dat); \
|
||||
break; \
|
||||
case 0x2: \
|
||||
dst_dat = ~src_dat & dst_dat; \
|
||||
break; \
|
||||
case 0x3: \
|
||||
dst_dat = ~src_dat; \
|
||||
break; \
|
||||
case 0x4: \
|
||||
dst_dat = src_dat & ~dst_dat; \
|
||||
break; \
|
||||
case 0x5: \
|
||||
dst_dat = ~dst_dat; \
|
||||
break; \
|
||||
case 0x6: \
|
||||
dst_dat = src_dat ^ dst_dat; \
|
||||
break; \
|
||||
case 0x7: \
|
||||
dst_dat = ~(src_dat & dst_dat); \
|
||||
break; \
|
||||
case 0x8: \
|
||||
dst_dat = src_dat & dst_dat; \
|
||||
break; \
|
||||
case 0x9: \
|
||||
dst_dat = ~(src_dat ^ dst_dat); \
|
||||
break; \
|
||||
case 0xa: \
|
||||
dst_dat = dst_dat; \
|
||||
break; \
|
||||
case 0xb: \
|
||||
dst_dat = ~src_dat | dst_dat; \
|
||||
break; \
|
||||
case 0xc: \
|
||||
dst_dat = src_dat; \
|
||||
break; \
|
||||
case 0xd: \
|
||||
dst_dat = src_dat | ~dst_dat; \
|
||||
break; \
|
||||
case 0xe: \
|
||||
dst_dat = src_dat | dst_dat; \
|
||||
break; \
|
||||
case 0xf: \
|
||||
dst_dat = 0xffff; \
|
||||
break; \
|
||||
}
|
||||
|
||||
#define MIX(src_dat, dst_dat, rop) \
|
||||
switch (rop) \
|
||||
{ \
|
||||
case 0x0: dst_dat = 0; break; \
|
||||
case 0x1: dst_dat = ~(src_dat | dst_dat); break; \
|
||||
case 0x2: dst_dat = ~src_dat & dst_dat; break; \
|
||||
case 0x3: dst_dat = ~src_dat; break; \
|
||||
case 0x4: dst_dat = src_dat & ~dst_dat; break; \
|
||||
case 0x5: dst_dat = ~dst_dat; break; \
|
||||
case 0x6: dst_dat = src_dat ^ dst_dat; break; \
|
||||
case 0x7: dst_dat = ~(src_dat & dst_dat); break; \
|
||||
case 0x8: dst_dat = src_dat & dst_dat; break; \
|
||||
case 0x9: dst_dat = ~(src_dat ^ dst_dat); break; \
|
||||
case 0xa: dst_dat = dst_dat; break; \
|
||||
case 0xb: dst_dat = ~src_dat | dst_dat; break; \
|
||||
case 0xc: dst_dat = src_dat; break; \
|
||||
case 0xd: dst_dat = src_dat | ~dst_dat; break; \
|
||||
case 0xe: dst_dat = src_dat | dst_dat; break; \
|
||||
case 0xf: dst_dat = 0xffff; break; \
|
||||
}
|
||||
|
||||
void voodoo_v2_blit_start(voodoo_t *voodoo)
|
||||
void
|
||||
voodoo_v2_blit_start(voodoo_t *voodoo)
|
||||
{
|
||||
uint64_t dat64;
|
||||
int size_x = ABS(voodoo->bltSizeX), size_y = ABS(voodoo->bltSizeY);
|
||||
int x_dir = (voodoo->bltSizeX > 0) ? 1 : -1;
|
||||
int y_dir = (voodoo->bltSizeY > 0) ? 1 : -1;
|
||||
int dst_x;
|
||||
int src_y = voodoo->bltSrcY & 0x7ff, dst_y = voodoo->bltDstY & 0x7ff;
|
||||
int src_stride = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcXYStride & 0x3f) * 32*2) : (voodoo->bltSrcXYStride & 0xff8);
|
||||
int dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32*2) : (voodoo->bltDstXYStride & 0xff8);
|
||||
uint32_t src_base_addr = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcBaseAddr & 0x3ff) << 12) : (voodoo->bltSrcBaseAddr & 0x3ffff8);
|
||||
uint32_t dst_base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8);
|
||||
int x, y;
|
||||
uint64_t dat64;
|
||||
int size_x = ABS(voodoo->bltSizeX), size_y = ABS(voodoo->bltSizeY);
|
||||
int x_dir = (voodoo->bltSizeX > 0) ? 1 : -1;
|
||||
int y_dir = (voodoo->bltSizeY > 0) ? 1 : -1;
|
||||
int dst_x;
|
||||
int src_y = voodoo->bltSrcY & 0x7ff, dst_y = voodoo->bltDstY & 0x7ff;
|
||||
int src_stride = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcXYStride & 0x3f) * 32 * 2) : (voodoo->bltSrcXYStride & 0xff8);
|
||||
int dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32 * 2) : (voodoo->bltDstXYStride & 0xff8);
|
||||
uint32_t src_base_addr = (voodoo->bltCommand & BLTCMD_SRC_TILED) ? ((voodoo->bltSrcBaseAddr & 0x3ff) << 12) : (voodoo->bltSrcBaseAddr & 0x3ffff8);
|
||||
uint32_t dst_base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8);
|
||||
int x, y;
|
||||
|
||||
/* voodooblt_log("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n",
|
||||
voodoo->bltCommand, voodoo->bltSrcX, voodoo->bltSrcY, voodoo->bltDstX, voodoo->bltDstY, voodoo->bltSizeX, voodoo->bltSizeY, voodoo->bltColorFg, voodoo->bltColorBg);*/
|
||||
/* voodooblt_log("blit_start: command=%08x srcX=%i srcY=%i dstX=%i dstY=%i sizeX=%i sizeY=%i color=%04x,%04x\n",
|
||||
voodoo->bltCommand, voodoo->bltSrcX, voodoo->bltSrcY, voodoo->bltDstX, voodoo->bltDstY, voodoo->bltSizeX, voodoo->bltSizeY, voodoo->bltColorFg, voodoo->bltColorBg);*/
|
||||
|
||||
voodoo_wait_for_render_thread_idle(voodoo);
|
||||
voodoo_wait_for_render_thread_idle(voodoo);
|
||||
|
||||
switch (voodoo->bltCommand & BLIT_COMMAND_MASK)
|
||||
{
|
||||
case BLIT_COMMAND_SCREEN_TO_SCREEN:
|
||||
for (y = 0; y <= size_y; y++)
|
||||
{
|
||||
uint16_t *src = (uint16_t *)&voodoo->fb_mem[src_base_addr + src_y*src_stride];
|
||||
uint16_t *dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y*dst_stride];
|
||||
int src_x = voodoo->bltSrcX, dst_x = voodoo->bltDstX;
|
||||
switch (voodoo->bltCommand & BLIT_COMMAND_MASK) {
|
||||
case BLIT_COMMAND_SCREEN_TO_SCREEN:
|
||||
for (y = 0; y <= size_y; y++) {
|
||||
uint16_t *src = (uint16_t *) &voodoo->fb_mem[src_base_addr + src_y * src_stride];
|
||||
uint16_t *dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + dst_y * dst_stride];
|
||||
int src_x = voodoo->bltSrcX, dst_x = voodoo->bltDstX;
|
||||
|
||||
for (x = 0; x <= size_x; x++)
|
||||
{
|
||||
uint16_t src_dat = src[src_x];
|
||||
uint16_t dst_dat = dst[dst_x];
|
||||
int rop = 0;
|
||||
for (x = 0; x <= size_x; x++) {
|
||||
uint16_t src_dat = src[src_x];
|
||||
uint16_t dst_dat = dst[dst_x];
|
||||
int rop = 0;
|
||||
|
||||
if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED)
|
||||
{
|
||||
if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight ||
|
||||
dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY)
|
||||
goto skip_pixel_blit;
|
||||
}
|
||||
if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) {
|
||||
if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY)
|
||||
goto skip_pixel_blit;
|
||||
}
|
||||
|
||||
if (voodoo->bltCommand & BLIT_SRC_CHROMA)
|
||||
{
|
||||
int r = (src_dat >> 11);
|
||||
int g = (src_dat >> 5) & 0x3f;
|
||||
int b = src_dat & 0x1f;
|
||||
if (voodoo->bltCommand & BLIT_SRC_CHROMA) {
|
||||
int r = (src_dat >> 11);
|
||||
int g = (src_dat >> 5) & 0x3f;
|
||||
int b = src_dat & 0x1f;
|
||||
|
||||
if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR &&
|
||||
g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG &&
|
||||
b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB)
|
||||
rop |= BLIT_ROP_SRC_PASS;
|
||||
}
|
||||
if (voodoo->bltCommand & BLIT_DST_CHROMA)
|
||||
{
|
||||
int r = (dst_dat >> 11);
|
||||
int g = (dst_dat >> 5) & 0x3f;
|
||||
int b = dst_dat & 0x1f;
|
||||
if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB)
|
||||
rop |= BLIT_ROP_SRC_PASS;
|
||||
}
|
||||
if (voodoo->bltCommand & BLIT_DST_CHROMA) {
|
||||
int r = (dst_dat >> 11);
|
||||
int g = (dst_dat >> 5) & 0x3f;
|
||||
int b = dst_dat & 0x1f;
|
||||
|
||||
if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR &&
|
||||
g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG &&
|
||||
b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB)
|
||||
rop |= BLIT_ROP_DST_PASS;
|
||||
}
|
||||
if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB)
|
||||
rop |= BLIT_ROP_DST_PASS;
|
||||
}
|
||||
|
||||
MIX(src_dat, dst_dat, voodoo->bltRop[rop]);
|
||||
MIX(src_dat, dst_dat, voodoo->bltRop[rop]);
|
||||
|
||||
dst[dst_x] = dst_dat;
|
||||
dst[dst_x] = dst_dat;
|
||||
skip_pixel_blit:
|
||||
src_x += x_dir;
|
||||
dst_x += x_dir;
|
||||
}
|
||||
|
||||
src_y += y_dir;
|
||||
dst_y += y_dir;
|
||||
src_x += x_dir;
|
||||
dst_x += x_dir;
|
||||
}
|
||||
break;
|
||||
|
||||
case BLIT_COMMAND_CPU_TO_SCREEN:
|
||||
voodoo->blt.dst_x = voodoo->bltDstX;
|
||||
voodoo->blt.dst_y = voodoo->bltDstY;
|
||||
voodoo->blt.cur_x = 0;
|
||||
voodoo->blt.size_x = size_x;
|
||||
voodoo->blt.size_y = size_y;
|
||||
voodoo->blt.x_dir = x_dir;
|
||||
voodoo->blt.y_dir = y_dir;
|
||||
voodoo->blt.dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32*2) : (voodoo->bltDstXYStride & 0xff8);
|
||||
break;
|
||||
src_y += y_dir;
|
||||
dst_y += y_dir;
|
||||
}
|
||||
break;
|
||||
|
||||
case BLIT_COMMAND_RECT_FILL:
|
||||
for (y = 0; y <= size_y; y++)
|
||||
{
|
||||
uint16_t *dst;
|
||||
int dst_x = voodoo->bltDstX;
|
||||
case BLIT_COMMAND_CPU_TO_SCREEN:
|
||||
voodoo->blt.dst_x = voodoo->bltDstX;
|
||||
voodoo->blt.dst_y = voodoo->bltDstY;
|
||||
voodoo->blt.cur_x = 0;
|
||||
voodoo->blt.size_x = size_x;
|
||||
voodoo->blt.size_y = size_y;
|
||||
voodoo->blt.x_dir = x_dir;
|
||||
voodoo->blt.y_dir = y_dir;
|
||||
voodoo->blt.dst_stride = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstXYStride & 0x3f) * 32 * 2) : (voodoo->bltDstXYStride & 0xff8);
|
||||
break;
|
||||
|
||||
if (SLI_ENABLED)
|
||||
{
|
||||
if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) ||
|
||||
((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1)))
|
||||
goto skip_line_fill;
|
||||
dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + (dst_y >> 1) * dst_stride];
|
||||
}
|
||||
else
|
||||
dst = (uint16_t *)&voodoo->fb_mem[dst_base_addr + dst_y*dst_stride];
|
||||
case BLIT_COMMAND_RECT_FILL:
|
||||
for (y = 0; y <= size_y; y++) {
|
||||
uint16_t *dst;
|
||||
int dst_x = voodoo->bltDstX;
|
||||
|
||||
for (x = 0; x <= size_x; x++)
|
||||
{
|
||||
if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED)
|
||||
{
|
||||
if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight ||
|
||||
dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY)
|
||||
goto skip_pixel_fill;
|
||||
}
|
||||
if (SLI_ENABLED) {
|
||||
if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1)))
|
||||
goto skip_line_fill;
|
||||
dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + (dst_y >> 1) * dst_stride];
|
||||
} else
|
||||
dst = (uint16_t *) &voodoo->fb_mem[dst_base_addr + dst_y * dst_stride];
|
||||
|
||||
dst[dst_x] = voodoo->bltColorFg;
|
||||
for (x = 0; x <= size_x; x++) {
|
||||
if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) {
|
||||
if (dst_x < voodoo->bltClipLeft || dst_x >= voodoo->bltClipRight || dst_y < voodoo->bltClipLowY || dst_y >= voodoo->bltClipHighY)
|
||||
goto skip_pixel_fill;
|
||||
}
|
||||
|
||||
dst[dst_x] = voodoo->bltColorFg;
|
||||
skip_pixel_fill:
|
||||
dst_x += x_dir;
|
||||
}
|
||||
dst_x += x_dir;
|
||||
}
|
||||
skip_line_fill:
|
||||
dst_y += y_dir;
|
||||
dst_y += y_dir;
|
||||
}
|
||||
break;
|
||||
|
||||
case BLIT_COMMAND_SGRAM_FILL:
|
||||
/*32x32 tiles - 2kb*/
|
||||
dst_y = voodoo->bltDstY & 0x3ff;
|
||||
size_x = voodoo->bltSizeX & 0x1ff; // 512*8 = 4kb
|
||||
size_y = voodoo->bltSizeY & 0x3ff;
|
||||
|
||||
dat64 = voodoo->bltColorFg | ((uint64_t) voodoo->bltColorFg << 16) | ((uint64_t) voodoo->bltColorFg << 32) | ((uint64_t) voodoo->bltColorFg << 48);
|
||||
|
||||
for (y = 0; y <= size_y; y++) {
|
||||
uint64_t *dst;
|
||||
|
||||
/*This may be wrong*/
|
||||
if (!y) {
|
||||
dst_x = voodoo->bltDstX & 0x1ff;
|
||||
size_x = 511 - dst_x;
|
||||
} else if (y < size_y) {
|
||||
dst_x = 0;
|
||||
size_x = 511;
|
||||
} else {
|
||||
dst_x = 0;
|
||||
size_x = voodoo->bltSizeX & 0x1ff;
|
||||
}
|
||||
break;
|
||||
|
||||
case BLIT_COMMAND_SGRAM_FILL:
|
||||
/*32x32 tiles - 2kb*/
|
||||
dst_y = voodoo->bltDstY & 0x3ff;
|
||||
size_x = voodoo->bltSizeX & 0x1ff; //512*8 = 4kb
|
||||
size_y = voodoo->bltSizeY & 0x3ff;
|
||||
dst = (uint64_t *) &voodoo->fb_mem[(dst_y * 512 * 8 + dst_x * 8) & voodoo->fb_mask];
|
||||
|
||||
dat64 = voodoo->bltColorFg | ((uint64_t)voodoo->bltColorFg << 16) |
|
||||
((uint64_t)voodoo->bltColorFg << 32) | ((uint64_t)voodoo->bltColorFg << 48);
|
||||
for (x = 0; x <= size_x; x++)
|
||||
dst[x] = dat64;
|
||||
|
||||
for (y = 0; y <= size_y; y++)
|
||||
{
|
||||
uint64_t *dst;
|
||||
dst_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
/*This may be wrong*/
|
||||
if (!y)
|
||||
{
|
||||
dst_x = voodoo->bltDstX & 0x1ff;
|
||||
size_x = 511 - dst_x;
|
||||
}
|
||||
else if (y < size_y)
|
||||
{
|
||||
dst_x = 0;
|
||||
size_x = 511;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst_x = 0;
|
||||
size_x = voodoo->bltSizeX & 0x1ff;
|
||||
}
|
||||
|
||||
dst = (uint64_t *)&voodoo->fb_mem[(dst_y*512*8 + dst_x*8) & voodoo->fb_mask];
|
||||
|
||||
for (x = 0; x <= size_x; x++)
|
||||
dst[x] = dat64;
|
||||
|
||||
dst_y++;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("bad blit command %08x\n", voodoo->bltCommand);
|
||||
}
|
||||
default:
|
||||
fatal("bad blit command %08x\n", voodoo->bltCommand);
|
||||
}
|
||||
}
|
||||
|
||||
void voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data)
|
||||
void
|
||||
voodoo_v2_blit_data(voodoo_t *voodoo, uint32_t data)
|
||||
{
|
||||
int src_bits = 32;
|
||||
uint32_t base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8);
|
||||
uint32_t addr;
|
||||
uint16_t *dst;
|
||||
int src_bits = 32;
|
||||
uint32_t base_addr = (voodoo->bltCommand & BLTCMD_DST_TILED) ? ((voodoo->bltDstBaseAddr & 0x3ff) << 12) : (voodoo->bltDstBaseAddr & 0x3ffff8);
|
||||
uint32_t addr;
|
||||
uint16_t *dst;
|
||||
|
||||
if ((voodoo->bltCommand & BLIT_COMMAND_MASK) != BLIT_COMMAND_CPU_TO_SCREEN)
|
||||
return;
|
||||
if ((voodoo->bltCommand & BLIT_COMMAND_MASK) != BLIT_COMMAND_CPU_TO_SCREEN)
|
||||
return;
|
||||
|
||||
if (SLI_ENABLED)
|
||||
{
|
||||
addr = base_addr + (voodoo->blt.dst_y >> 1) * voodoo->blt.dst_stride;
|
||||
dst = (uint16_t *)&voodoo->fb_mem[addr];
|
||||
}
|
||||
else
|
||||
{
|
||||
addr = base_addr + voodoo->blt.dst_y*voodoo->blt.dst_stride;
|
||||
dst = (uint16_t *)&voodoo->fb_mem[addr];
|
||||
}
|
||||
if (SLI_ENABLED) {
|
||||
addr = base_addr + (voodoo->blt.dst_y >> 1) * voodoo->blt.dst_stride;
|
||||
dst = (uint16_t *) &voodoo->fb_mem[addr];
|
||||
} else {
|
||||
addr = base_addr + voodoo->blt.dst_y * voodoo->blt.dst_stride;
|
||||
dst = (uint16_t *) &voodoo->fb_mem[addr];
|
||||
}
|
||||
|
||||
if (addr >= voodoo->front_offset && voodoo->row_width)
|
||||
{
|
||||
int y = (addr - voodoo->front_offset) / voodoo->row_width;
|
||||
if (y < voodoo->v_disp)
|
||||
voodoo->dirty_line[y] = 2;
|
||||
}
|
||||
if (addr >= voodoo->front_offset && voodoo->row_width) {
|
||||
int y = (addr - voodoo->front_offset) / voodoo->row_width;
|
||||
if (y < voodoo->v_disp)
|
||||
voodoo->dirty_line[y] = 2;
|
||||
}
|
||||
|
||||
while (src_bits && voodoo->blt.cur_x <= voodoo->blt.size_x)
|
||||
{
|
||||
int r = 0, g = 0, b = 0;
|
||||
uint16_t src_dat = 0, dst_dat;
|
||||
int x = (voodoo->blt.x_dir > 0) ? (voodoo->blt.dst_x + voodoo->blt.cur_x) : (voodoo->blt.dst_x - voodoo->blt.cur_x);
|
||||
int rop = 0;
|
||||
while (src_bits && voodoo->blt.cur_x <= voodoo->blt.size_x) {
|
||||
int r = 0, g = 0, b = 0;
|
||||
uint16_t src_dat = 0, dst_dat;
|
||||
int x = (voodoo->blt.x_dir > 0) ? (voodoo->blt.dst_x + voodoo->blt.cur_x) : (voodoo->blt.dst_x - voodoo->blt.cur_x);
|
||||
int rop = 0;
|
||||
|
||||
switch (voodoo->bltCommand & BLIT_SRC_FORMAT)
|
||||
{
|
||||
case BLIT_SRC_1BPP: case BLIT_SRC_1BPP_BYTE_PACKED:
|
||||
src_dat = (data & 1) ? voodoo->bltColorFg : voodoo->bltColorBg;
|
||||
data >>= 1;
|
||||
src_bits--;
|
||||
switch (voodoo->bltCommand & BLIT_SRC_FORMAT) {
|
||||
case BLIT_SRC_1BPP:
|
||||
case BLIT_SRC_1BPP_BYTE_PACKED:
|
||||
src_dat = (data & 1) ? voodoo->bltColorFg : voodoo->bltColorBg;
|
||||
data >>= 1;
|
||||
src_bits--;
|
||||
break;
|
||||
case BLIT_SRC_16BPP:
|
||||
switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) {
|
||||
case BLIT_SRC_RGB_ARGB:
|
||||
case BLIT_SRC_RGB_RGBA:
|
||||
src_dat = data & 0xffff;
|
||||
break;
|
||||
case BLIT_SRC_16BPP:
|
||||
switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT)
|
||||
{
|
||||
case BLIT_SRC_RGB_ARGB: case BLIT_SRC_RGB_RGBA:
|
||||
src_dat = data & 0xffff;
|
||||
break;
|
||||
case BLIT_SRC_RGB_ABGR: case BLIT_SRC_RGB_BGRA:
|
||||
src_dat = ((data & 0xf800) >> 11) | (data & 0x07c0) | ((data & 0x0038) << 11);
|
||||
break;
|
||||
}
|
||||
data >>= 16;
|
||||
src_bits -= 16;
|
||||
break;
|
||||
case BLIT_SRC_24BPP: case BLIT_SRC_24BPP_DITHER_2X2: case BLIT_SRC_24BPP_DITHER_4X4:
|
||||
switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT)
|
||||
{
|
||||
case BLIT_SRC_RGB_ARGB:
|
||||
r = (data >> 16) & 0xff;
|
||||
g = (data >> 8) & 0xff;
|
||||
b = data & 0xff;
|
||||
break;
|
||||
case BLIT_SRC_RGB_ABGR:
|
||||
r = data & 0xff;
|
||||
g = (data >> 8) & 0xff;
|
||||
b = (data >> 16) & 0xff;
|
||||
break;
|
||||
case BLIT_SRC_RGB_RGBA:
|
||||
r = (data >> 24) & 0xff;
|
||||
g = (data >> 16) & 0xff;
|
||||
b = (data >> 8) & 0xff;
|
||||
break;
|
||||
case BLIT_SRC_RGB_BGRA:
|
||||
r = (data >> 8) & 0xff;
|
||||
g = (data >> 16) & 0xff;
|
||||
b = (data >> 24) & 0xff;
|
||||
break;
|
||||
}
|
||||
switch (voodoo->bltCommand & BLIT_SRC_FORMAT)
|
||||
{
|
||||
case BLIT_SRC_24BPP:
|
||||
src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8);
|
||||
break;
|
||||
case BLIT_SRC_24BPP_DITHER_2X2:
|
||||
r = dither_rb2x2[r][voodoo->blt.dst_y & 1][x & 1];
|
||||
g = dither_g2x2[g][voodoo->blt.dst_y & 1][x & 1];
|
||||
b = dither_rb2x2[b][voodoo->blt.dst_y & 1][x & 1];
|
||||
src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8);
|
||||
break;
|
||||
case BLIT_SRC_24BPP_DITHER_4X4:
|
||||
r = dither_rb[r][voodoo->blt.dst_y & 3][x & 3];
|
||||
g = dither_g[g][voodoo->blt.dst_y & 3][x & 3];
|
||||
b = dither_rb[b][voodoo->blt.dst_y & 3][x & 3];
|
||||
src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8);
|
||||
break;
|
||||
}
|
||||
src_bits = 0;
|
||||
case BLIT_SRC_RGB_ABGR:
|
||||
case BLIT_SRC_RGB_BGRA:
|
||||
src_dat = ((data & 0xf800) >> 11) | (data & 0x07c0) | ((data & 0x0038) << 11);
|
||||
break;
|
||||
}
|
||||
|
||||
if (SLI_ENABLED)
|
||||
{
|
||||
if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) ||
|
||||
((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1)))
|
||||
goto skip_pixel;
|
||||
data >>= 16;
|
||||
src_bits -= 16;
|
||||
break;
|
||||
case BLIT_SRC_24BPP:
|
||||
case BLIT_SRC_24BPP_DITHER_2X2:
|
||||
case BLIT_SRC_24BPP_DITHER_4X4:
|
||||
switch (voodoo->bltCommand & BLIT_SRC_RGB_FORMAT) {
|
||||
case BLIT_SRC_RGB_ARGB:
|
||||
r = (data >> 16) & 0xff;
|
||||
g = (data >> 8) & 0xff;
|
||||
b = data & 0xff;
|
||||
break;
|
||||
case BLIT_SRC_RGB_ABGR:
|
||||
r = data & 0xff;
|
||||
g = (data >> 8) & 0xff;
|
||||
b = (data >> 16) & 0xff;
|
||||
break;
|
||||
case BLIT_SRC_RGB_RGBA:
|
||||
r = (data >> 24) & 0xff;
|
||||
g = (data >> 16) & 0xff;
|
||||
b = (data >> 8) & 0xff;
|
||||
break;
|
||||
case BLIT_SRC_RGB_BGRA:
|
||||
r = (data >> 8) & 0xff;
|
||||
g = (data >> 16) & 0xff;
|
||||
b = (data >> 24) & 0xff;
|
||||
break;
|
||||
}
|
||||
|
||||
if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED)
|
||||
{
|
||||
if (x < voodoo->bltClipLeft || x >= voodoo->bltClipRight ||
|
||||
voodoo->blt.dst_y < voodoo->bltClipLowY || voodoo->blt.dst_y >= voodoo->bltClipHighY)
|
||||
goto skip_pixel;
|
||||
switch (voodoo->bltCommand & BLIT_SRC_FORMAT) {
|
||||
case BLIT_SRC_24BPP:
|
||||
src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8);
|
||||
break;
|
||||
case BLIT_SRC_24BPP_DITHER_2X2:
|
||||
r = dither_rb2x2[r][voodoo->blt.dst_y & 1][x & 1];
|
||||
g = dither_g2x2[g][voodoo->blt.dst_y & 1][x & 1];
|
||||
b = dither_rb2x2[b][voodoo->blt.dst_y & 1][x & 1];
|
||||
src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8);
|
||||
break;
|
||||
case BLIT_SRC_24BPP_DITHER_4X4:
|
||||
r = dither_rb[r][voodoo->blt.dst_y & 3][x & 3];
|
||||
g = dither_g[g][voodoo->blt.dst_y & 3][x & 3];
|
||||
b = dither_rb[b][voodoo->blt.dst_y & 3][x & 3];
|
||||
src_dat = (b >> 3) | ((g & 0xfc) << 3) | ((r & 0xf8) << 8);
|
||||
break;
|
||||
}
|
||||
src_bits = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
dst_dat = dst[x];
|
||||
if (SLI_ENABLED) {
|
||||
if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (voodoo->blt.dst_y & 1)) || ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(voodoo->blt.dst_y & 1)))
|
||||
goto skip_pixel;
|
||||
}
|
||||
|
||||
if (voodoo->bltCommand & BLIT_SRC_CHROMA)
|
||||
{
|
||||
r = (src_dat >> 11);
|
||||
g = (src_dat >> 5) & 0x3f;
|
||||
b = src_dat & 0x1f;
|
||||
if (voodoo->bltCommand & BLIT_CLIPPING_ENABLED) {
|
||||
if (x < voodoo->bltClipLeft || x >= voodoo->bltClipRight || voodoo->blt.dst_y < voodoo->bltClipLowY || voodoo->blt.dst_y >= voodoo->bltClipHighY)
|
||||
goto skip_pixel;
|
||||
}
|
||||
|
||||
if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR &&
|
||||
g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG &&
|
||||
b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB)
|
||||
rop |= BLIT_ROP_SRC_PASS;
|
||||
}
|
||||
if (voodoo->bltCommand & BLIT_DST_CHROMA)
|
||||
{
|
||||
r = (dst_dat >> 11);
|
||||
g = (dst_dat >> 5) & 0x3f;
|
||||
b = dst_dat & 0x1f;
|
||||
dst_dat = dst[x];
|
||||
|
||||
if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR &&
|
||||
g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG &&
|
||||
b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB)
|
||||
rop |= BLIT_ROP_DST_PASS;
|
||||
}
|
||||
if (voodoo->bltCommand & BLIT_SRC_CHROMA) {
|
||||
r = (src_dat >> 11);
|
||||
g = (src_dat >> 5) & 0x3f;
|
||||
b = src_dat & 0x1f;
|
||||
|
||||
MIX(src_dat, dst_dat, voodoo->bltRop[rop]);
|
||||
if (r >= voodoo->bltSrcChromaMinR && r <= voodoo->bltSrcChromaMaxR && g >= voodoo->bltSrcChromaMinG && g <= voodoo->bltSrcChromaMaxG && b >= voodoo->bltSrcChromaMinB && b <= voodoo->bltSrcChromaMaxB)
|
||||
rop |= BLIT_ROP_SRC_PASS;
|
||||
}
|
||||
if (voodoo->bltCommand & BLIT_DST_CHROMA) {
|
||||
r = (dst_dat >> 11);
|
||||
g = (dst_dat >> 5) & 0x3f;
|
||||
b = dst_dat & 0x1f;
|
||||
|
||||
dst[x] = dst_dat;
|
||||
if (r >= voodoo->bltDstChromaMinR && r <= voodoo->bltDstChromaMaxR && g >= voodoo->bltDstChromaMinG && g <= voodoo->bltDstChromaMaxG && b >= voodoo->bltDstChromaMinB && b <= voodoo->bltDstChromaMaxB)
|
||||
rop |= BLIT_ROP_DST_PASS;
|
||||
}
|
||||
|
||||
MIX(src_dat, dst_dat, voodoo->bltRop[rop]);
|
||||
|
||||
dst[x] = dst_dat;
|
||||
|
||||
skip_pixel:
|
||||
voodoo->blt.cur_x++;
|
||||
}
|
||||
voodoo->blt.cur_x++;
|
||||
}
|
||||
|
||||
if (voodoo->blt.cur_x > voodoo->blt.size_x)
|
||||
{
|
||||
voodoo->blt.size_y--;
|
||||
if (voodoo->blt.size_y >= 0)
|
||||
{
|
||||
voodoo->blt.cur_x = 0;
|
||||
voodoo->blt.dst_y += voodoo->blt.y_dir;
|
||||
}
|
||||
if (voodoo->blt.cur_x > voodoo->blt.size_x) {
|
||||
voodoo->blt.size_y--;
|
||||
if (voodoo->blt.size_y >= 0) {
|
||||
voodoo->blt.cur_x = 0;
|
||||
voodoo->blt.dst_y += voodoo->blt.y_dir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params)
|
||||
void
|
||||
voodoo_fastfill(voodoo_t *voodoo, voodoo_params_t *params)
|
||||
{
|
||||
int y;
|
||||
int low_y, high_y;
|
||||
int y;
|
||||
int low_y, high_y;
|
||||
|
||||
if (params->fbzMode & (1 << 17))
|
||||
{
|
||||
int y_origin = (voodoo->type >= VOODOO_BANSHEE) ? (voodoo->y_origin_swap+1) : voodoo->v_disp;
|
||||
if (params->fbzMode & (1 << 17)) {
|
||||
int y_origin = (voodoo->type >= VOODOO_BANSHEE) ? (voodoo->y_origin_swap + 1) : voodoo->v_disp;
|
||||
|
||||
high_y = y_origin - params->clipLowY;
|
||||
low_y = y_origin - params->clipHighY;
|
||||
}
|
||||
else
|
||||
{
|
||||
low_y = params->clipLowY;
|
||||
high_y = params->clipHighY;
|
||||
}
|
||||
high_y = y_origin - params->clipLowY;
|
||||
low_y = y_origin - params->clipHighY;
|
||||
} else {
|
||||
low_y = params->clipLowY;
|
||||
high_y = params->clipHighY;
|
||||
}
|
||||
|
||||
if (params->fbzMode & FBZ_RGB_WMASK)
|
||||
{
|
||||
int r, g, b;
|
||||
uint16_t col;
|
||||
if (params->fbzMode & FBZ_RGB_WMASK) {
|
||||
int r, g, b;
|
||||
uint16_t col;
|
||||
|
||||
r = ((params->color1 >> 16) >> 3) & 0x1f;
|
||||
g = ((params->color1 >> 8) >> 2) & 0x3f;
|
||||
b = (params->color1 >> 3) & 0x1f;
|
||||
col = b | (g << 5) | (r << 11);
|
||||
r = ((params->color1 >> 16) >> 3) & 0x1f;
|
||||
g = ((params->color1 >> 8) >> 2) & 0x3f;
|
||||
b = (params->color1 >> 3) & 0x1f;
|
||||
col = b | (g << 5) | (r << 11);
|
||||
|
||||
if (SLI_ENABLED)
|
||||
{
|
||||
for (y = low_y; y < high_y; y += 2)
|
||||
{
|
||||
uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask];
|
||||
int x;
|
||||
if (SLI_ENABLED) {
|
||||
for (y = low_y; y < high_y; y += 2) {
|
||||
uint16_t *cbuf = (uint16_t *) &voodoo->fb_mem[(params->draw_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask];
|
||||
int x;
|
||||
|
||||
for (x = params->clipLeft; x < params->clipRight; x++)
|
||||
cbuf[x] = col;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = low_y; y < high_y; y++)
|
||||
{
|
||||
if (voodoo->col_tiled)
|
||||
{
|
||||
uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + (y >> 5) * voodoo->row_width + (y & 31) * 128) & voodoo->fb_mask];
|
||||
int x;
|
||||
|
||||
for (x = params->clipLeft; x < params->clipRight; x++)
|
||||
{
|
||||
int x2 = (x & 63) | ((x >> 6) * 128*32/2);
|
||||
cbuf[x2] = col;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t *cbuf = (uint16_t *)&voodoo->fb_mem[(params->draw_offset + y * voodoo->row_width) & voodoo->fb_mask];
|
||||
int x;
|
||||
|
||||
for (x = params->clipLeft; x < params->clipRight; x++)
|
||||
cbuf[x] = col;
|
||||
}
|
||||
}
|
||||
for (x = params->clipLeft; x < params->clipRight; x++)
|
||||
cbuf[x] = col;
|
||||
}
|
||||
} else {
|
||||
for (y = low_y; y < high_y; y++) {
|
||||
if (voodoo->col_tiled) {
|
||||
uint16_t *cbuf = (uint16_t *) &voodoo->fb_mem[(params->draw_offset + (y >> 5) * voodoo->row_width + (y & 31) * 128) & voodoo->fb_mask];
|
||||
int x;
|
||||
|
||||
for (x = params->clipLeft; x < params->clipRight; x++) {
|
||||
int x2 = (x & 63) | ((x >> 6) * 128 * 32 / 2);
|
||||
cbuf[x2] = col;
|
||||
}
|
||||
} else {
|
||||
uint16_t *cbuf = (uint16_t *) &voodoo->fb_mem[(params->draw_offset + y * voodoo->row_width) & voodoo->fb_mask];
|
||||
int x;
|
||||
|
||||
for (x = params->clipLeft; x < params->clipRight; x++)
|
||||
cbuf[x] = col;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (params->fbzMode & FBZ_DEPTH_WMASK)
|
||||
{
|
||||
if (SLI_ENABLED)
|
||||
{
|
||||
for (y = low_y; y < high_y; y += 2)
|
||||
{
|
||||
uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask];
|
||||
int x;
|
||||
}
|
||||
if (params->fbzMode & FBZ_DEPTH_WMASK) {
|
||||
if (SLI_ENABLED) {
|
||||
for (y = low_y; y < high_y; y += 2) {
|
||||
uint16_t *abuf = (uint16_t *) &voodoo->fb_mem[(params->aux_offset + (y >> 1) * voodoo->row_width) & voodoo->fb_mask];
|
||||
int x;
|
||||
|
||||
for (x = params->clipLeft; x < params->clipRight; x++)
|
||||
abuf[x] = params->zaColor & 0xffff;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (y = low_y; y < high_y; y++)
|
||||
{
|
||||
if (voodoo->aux_tiled)
|
||||
{
|
||||
uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + (y >> 5) * voodoo->aux_row_width + (y & 31) * 128) & voodoo->fb_mask];
|
||||
int x;
|
||||
|
||||
for (x = params->clipLeft; x < params->clipRight; x++)
|
||||
{
|
||||
int x2 = (x & 63) | ((x >> 6) * 128*32/2);
|
||||
abuf[x2] = params->zaColor & 0xffff;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16_t *abuf = (uint16_t *)&voodoo->fb_mem[(params->aux_offset + y * voodoo->aux_row_width) & voodoo->fb_mask];
|
||||
int x;
|
||||
|
||||
for (x = params->clipLeft; x < params->clipRight; x++)
|
||||
abuf[x] = params->zaColor & 0xffff;
|
||||
}
|
||||
}
|
||||
for (x = params->clipLeft; x < params->clipRight; x++)
|
||||
abuf[x] = params->zaColor & 0xffff;
|
||||
}
|
||||
} else {
|
||||
for (y = low_y; y < high_y; y++) {
|
||||
if (voodoo->aux_tiled) {
|
||||
uint16_t *abuf = (uint16_t *) &voodoo->fb_mem[(params->aux_offset + (y >> 5) * voodoo->aux_row_width + (y & 31) * 128) & voodoo->fb_mask];
|
||||
int x;
|
||||
|
||||
for (x = params->clipLeft; x < params->clipRight; x++) {
|
||||
int x2 = (x & 63) | ((x >> 6) * 128 * 32 / 2);
|
||||
abuf[x2] = params->zaColor & 0xffff;
|
||||
}
|
||||
} else {
|
||||
uint16_t *abuf = (uint16_t *) &voodoo->fb_mem[(params->aux_offset + y * voodoo->aux_row_width) & voodoo->fb_mask];
|
||||
int x;
|
||||
|
||||
for (x = params->clipLeft; x < params->clipRight; x++)
|
||||
abuf[x] = params->zaColor & 0xffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,6 @@
|
||||
#include <86box/vid_voodoo_render.h>
|
||||
#include <86box/vid_voodoo_fb.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_VOODOO_FB_LOG
|
||||
int voodoo_fb_do_log = ENABLE_VOODOO_FB_LOG;
|
||||
|
||||
@@ -48,447 +47,402 @@ voodoo_fb_log(const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
if (voodoo_fb_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define voodoo_fb_log(fmt, ...)
|
||||
# define voodoo_fb_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
uint16_t voodoo_fb_readw(uint32_t addr, void *p)
|
||||
uint16_t
|
||||
voodoo_fb_readw(uint32_t addr, void *p)
|
||||
{
|
||||
voodoo_t *voodoo = (voodoo_t *)p;
|
||||
int x, y;
|
||||
uint32_t read_addr;
|
||||
uint16_t temp;
|
||||
voodoo_t *voodoo = (voodoo_t *) p;
|
||||
int x, y;
|
||||
uint32_t read_addr;
|
||||
uint16_t temp;
|
||||
|
||||
if (voodoo->type >= VOODOO_BANSHEE)
|
||||
{
|
||||
x = addr & 0xffe;
|
||||
y = (addr >> 12) & 0x3ff;
|
||||
}
|
||||
if (voodoo->type >= VOODOO_BANSHEE) {
|
||||
x = addr & 0xffe;
|
||||
y = (addr >> 12) & 0x3ff;
|
||||
} else {
|
||||
x = addr & 0x7fe;
|
||||
y = (addr >> 11) & 0x3ff;
|
||||
}
|
||||
|
||||
if (SLI_ENABLED) {
|
||||
voodoo_set_t *set = voodoo->set;
|
||||
|
||||
if (y & 1)
|
||||
voodoo = set->voodoos[1];
|
||||
else
|
||||
{
|
||||
x = addr & 0x7fe;
|
||||
y = (addr >> 11) & 0x3ff;
|
||||
}
|
||||
voodoo = set->voodoos[0];
|
||||
|
||||
if (SLI_ENABLED)
|
||||
{
|
||||
voodoo_set_t *set = voodoo->set;
|
||||
y >>= 1;
|
||||
}
|
||||
|
||||
if (y & 1)
|
||||
voodoo = set->voodoos[1];
|
||||
else
|
||||
voodoo = set->voodoos[0];
|
||||
if (voodoo->col_tiled)
|
||||
read_addr = voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
|
||||
else
|
||||
read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width);
|
||||
|
||||
y >>= 1;
|
||||
}
|
||||
if (read_addr > voodoo->fb_mask)
|
||||
return 0xffff;
|
||||
|
||||
if (voodoo->col_tiled)
|
||||
read_addr = voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
|
||||
else
|
||||
read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width);
|
||||
temp = *(uint16_t *) (&voodoo->fb_mem[read_addr & voodoo->fb_mask]);
|
||||
|
||||
if (read_addr > voodoo->fb_mask)
|
||||
return 0xffff;
|
||||
|
||||
temp = *(uint16_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]);
|
||||
|
||||
// voodoo_fb_log("voodoo_fb_readw : %08X %08X %i %i %08X %08X %08x:%08x %i\n", addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++);
|
||||
return temp;
|
||||
// voodoo_fb_log("voodoo_fb_readw : %08X %08X %i %i %08X %08X %08x:%08x %i\n", addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++);
|
||||
return temp;
|
||||
}
|
||||
uint32_t voodoo_fb_readl(uint32_t addr, void *p)
|
||||
uint32_t
|
||||
voodoo_fb_readl(uint32_t addr, void *p)
|
||||
{
|
||||
voodoo_t *voodoo = (voodoo_t *)p;
|
||||
int x, y;
|
||||
uint32_t read_addr;
|
||||
uint32_t temp;
|
||||
voodoo_t *voodoo = (voodoo_t *) p;
|
||||
int x, y;
|
||||
uint32_t read_addr;
|
||||
uint32_t temp;
|
||||
|
||||
if (voodoo->type >= VOODOO_BANSHEE)
|
||||
{
|
||||
x = addr & 0xffe;
|
||||
y = (addr >> 12) & 0x3ff;
|
||||
}
|
||||
if (voodoo->type >= VOODOO_BANSHEE) {
|
||||
x = addr & 0xffe;
|
||||
y = (addr >> 12) & 0x3ff;
|
||||
} else {
|
||||
x = addr & 0x7fe;
|
||||
y = (addr >> 11) & 0x3ff;
|
||||
}
|
||||
|
||||
if (SLI_ENABLED) {
|
||||
voodoo_set_t *set = voodoo->set;
|
||||
|
||||
if (y & 1)
|
||||
voodoo = set->voodoos[1];
|
||||
else
|
||||
{
|
||||
x = addr & 0x7fe;
|
||||
y = (addr >> 11) & 0x3ff;
|
||||
}
|
||||
voodoo = set->voodoos[0];
|
||||
|
||||
if (SLI_ENABLED)
|
||||
{
|
||||
voodoo_set_t *set = voodoo->set;
|
||||
y >>= 1;
|
||||
}
|
||||
|
||||
if (y & 1)
|
||||
voodoo = set->voodoos[1];
|
||||
else
|
||||
voodoo = set->voodoos[0];
|
||||
if (voodoo->col_tiled)
|
||||
read_addr = voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
|
||||
else
|
||||
read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width);
|
||||
|
||||
y >>= 1;
|
||||
}
|
||||
if (read_addr > voodoo->fb_mask)
|
||||
return 0xffffffff;
|
||||
|
||||
if (voodoo->col_tiled)
|
||||
read_addr = voodoo->fb_read_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
|
||||
else
|
||||
read_addr = voodoo->fb_read_offset + x + (y * voodoo->row_width);
|
||||
temp = *(uint32_t *) (&voodoo->fb_mem[read_addr & voodoo->fb_mask]);
|
||||
|
||||
if (read_addr > voodoo->fb_mask)
|
||||
return 0xffffffff;
|
||||
|
||||
temp = *(uint32_t *)(&voodoo->fb_mem[read_addr & voodoo->fb_mask]);
|
||||
|
||||
// voodoo_fb_log("voodoo_fb_readl : %08X %08x %08X x=%i y=%i %08X %08X %08x:%08x %i ro=%08x rw=%i\n", addr, read_addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++, voodoo->fb_read_offset, voodoo->row_width);
|
||||
return temp;
|
||||
// voodoo_fb_log("voodoo_fb_readl : %08X %08x %08X x=%i y=%i %08X %08X %08x:%08x %i ro=%08x rw=%i\n", addr, read_addr, temp, x, y, read_addr, *(uint32_t *)(&voodoo->fb_mem[4]), cs, pc, fb_reads++, voodoo->fb_read_offset, voodoo->row_width);
|
||||
return temp;
|
||||
}
|
||||
|
||||
static inline uint16_t do_dither(voodoo_params_t *params, rgba8_t col, int x, int y)
|
||||
static inline uint16_t
|
||||
do_dither(voodoo_params_t *params, rgba8_t col, int x, int y)
|
||||
{
|
||||
int r, g, b;
|
||||
int r, g, b;
|
||||
|
||||
if (dither)
|
||||
{
|
||||
if (dither2x2)
|
||||
{
|
||||
r = dither_rb2x2[col.r][y & 1][x & 1];
|
||||
g = dither_g2x2[col.g][y & 1][x & 1];
|
||||
b = dither_rb2x2[col.b][y & 1][x & 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
r = dither_rb[col.r][y & 3][x & 3];
|
||||
g = dither_g[col.g][y & 3][x & 3];
|
||||
b = dither_rb[col.b][y & 3][x & 3];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
r = col.r >> 3;
|
||||
g = col.g >> 2;
|
||||
b = col.b >> 3;
|
||||
if (dither) {
|
||||
if (dither2x2) {
|
||||
r = dither_rb2x2[col.r][y & 1][x & 1];
|
||||
g = dither_g2x2[col.g][y & 1][x & 1];
|
||||
b = dither_rb2x2[col.b][y & 1][x & 1];
|
||||
} else {
|
||||
r = dither_rb[col.r][y & 3][x & 3];
|
||||
g = dither_g[col.g][y & 3][x & 3];
|
||||
b = dither_rb[col.b][y & 3][x & 3];
|
||||
}
|
||||
} else {
|
||||
r = col.r >> 3;
|
||||
g = col.g >> 2;
|
||||
b = col.b >> 3;
|
||||
}
|
||||
|
||||
return b | (g << 5) | (r << 11);
|
||||
return b | (g << 5) | (r << 11);
|
||||
}
|
||||
|
||||
void voodoo_fb_writew(uint32_t addr, uint16_t val, void *p)
|
||||
void
|
||||
voodoo_fb_writew(uint32_t addr, uint16_t val, void *p)
|
||||
{
|
||||
voodoo_t *voodoo = (voodoo_t *)p;
|
||||
voodoo_params_t *params = &voodoo->params;
|
||||
int x, y;
|
||||
uint32_t write_addr, write_addr_aux;
|
||||
rgba8_t colour_data;
|
||||
uint16_t depth_data;
|
||||
uint8_t alpha_data;
|
||||
int write_mask = 0;
|
||||
voodoo_t *voodoo = (voodoo_t *) p;
|
||||
voodoo_params_t *params = &voodoo->params;
|
||||
int x, y;
|
||||
uint32_t write_addr, write_addr_aux;
|
||||
rgba8_t colour_data;
|
||||
uint16_t depth_data;
|
||||
uint8_t alpha_data;
|
||||
int write_mask = 0;
|
||||
|
||||
colour_data.r = colour_data.g = colour_data.b = colour_data.a = 0;
|
||||
colour_data.r = colour_data.g = colour_data.b = colour_data.a = 0;
|
||||
|
||||
depth_data = voodoo->params.zaColor & 0xffff;
|
||||
alpha_data = voodoo->params.zaColor >> 24;
|
||||
depth_data = voodoo->params.zaColor & 0xffff;
|
||||
alpha_data = voodoo->params.zaColor >> 24;
|
||||
|
||||
// while (!RB_EMPTY)
|
||||
// thread_reset_event(voodoo->not_full_event);
|
||||
// while (!RB_EMPTY)
|
||||
// thread_reset_event(voodoo->not_full_event);
|
||||
|
||||
// voodoo_fb_log("voodoo_fb_writew : %08X %04X\n", addr, val);
|
||||
// voodoo_fb_log("voodoo_fb_writew : %08X %04X\n", addr, val);
|
||||
|
||||
switch (voodoo->lfbMode & LFB_FORMAT_MASK) {
|
||||
case LFB_FORMAT_RGB565:
|
||||
colour_data = rgb565[val];
|
||||
alpha_data = 0xff;
|
||||
write_mask = LFB_WRITE_COLOUR;
|
||||
break;
|
||||
case LFB_FORMAT_RGB555:
|
||||
colour_data = argb1555[val];
|
||||
alpha_data = 0xff;
|
||||
write_mask = LFB_WRITE_COLOUR;
|
||||
break;
|
||||
case LFB_FORMAT_ARGB1555:
|
||||
colour_data = argb1555[val];
|
||||
alpha_data = colour_data.a;
|
||||
write_mask = LFB_WRITE_COLOUR;
|
||||
break;
|
||||
case LFB_FORMAT_DEPTH:
|
||||
depth_data = val;
|
||||
write_mask = LFB_WRITE_DEPTH;
|
||||
break;
|
||||
|
||||
switch (voodoo->lfbMode & LFB_FORMAT_MASK)
|
||||
default:
|
||||
fatal("voodoo_fb_writew : bad LFB format %08X\n", voodoo->lfbMode);
|
||||
}
|
||||
|
||||
if (voodoo->type >= VOODOO_BANSHEE) {
|
||||
x = addr & 0xffe;
|
||||
y = (addr >> 12) & 0x3ff;
|
||||
} else {
|
||||
x = addr & 0x7fe;
|
||||
y = (addr >> 11) & 0x3ff;
|
||||
}
|
||||
|
||||
if (SLI_ENABLED) {
|
||||
if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1)))
|
||||
return;
|
||||
y >>= 1;
|
||||
}
|
||||
|
||||
if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048)
|
||||
voodoo->dirty_line[y] = 1;
|
||||
|
||||
if (voodoo->col_tiled)
|
||||
write_addr = voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
|
||||
else
|
||||
write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width);
|
||||
if (voodoo->aux_tiled)
|
||||
write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
|
||||
else
|
||||
write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width);
|
||||
|
||||
// voodoo_fb_log("fb_writew %08x %i %i %i %08x\n", addr, x, y, voodoo->row_width, write_addr);
|
||||
|
||||
if (voodoo->lfbMode & 0x100) {
|
||||
{
|
||||
case LFB_FORMAT_RGB565:
|
||||
colour_data = rgb565[val];
|
||||
alpha_data = 0xff;
|
||||
write_mask = LFB_WRITE_COLOUR;
|
||||
break;
|
||||
case LFB_FORMAT_RGB555:
|
||||
colour_data = argb1555[val];
|
||||
alpha_data = 0xff;
|
||||
write_mask = LFB_WRITE_COLOUR;
|
||||
break;
|
||||
case LFB_FORMAT_ARGB1555:
|
||||
colour_data = argb1555[val];
|
||||
alpha_data = colour_data.a;
|
||||
write_mask = LFB_WRITE_COLOUR;
|
||||
break;
|
||||
case LFB_FORMAT_DEPTH:
|
||||
depth_data = val;
|
||||
write_mask = LFB_WRITE_DEPTH;
|
||||
break;
|
||||
rgba8_t write_data = colour_data;
|
||||
uint16_t new_depth = depth_data;
|
||||
|
||||
default:
|
||||
fatal("voodoo_fb_writew : bad LFB format %08X\n", voodoo->lfbMode);
|
||||
}
|
||||
if (params->fbzMode & FBZ_DEPTH_ENABLE) {
|
||||
uint16_t old_depth = *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]);
|
||||
|
||||
if (voodoo->type >= VOODOO_BANSHEE)
|
||||
{
|
||||
x = addr & 0xffe;
|
||||
y = (addr >> 12) & 0x3ff;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = addr & 0x7fe;
|
||||
y = (addr >> 11) & 0x3ff;
|
||||
}
|
||||
DEPTH_TEST(new_depth);
|
||||
}
|
||||
|
||||
if (SLI_ENABLED)
|
||||
{
|
||||
if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) ||
|
||||
((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1)))
|
||||
return;
|
||||
y >>= 1;
|
||||
}
|
||||
if ((params->fbzMode & FBZ_CHROMAKEY) && write_data.r == params->chromaKey_r && write_data.g == params->chromaKey_g && write_data.b == params->chromaKey_b)
|
||||
goto skip_pixel;
|
||||
|
||||
if (params->fogMode & FOG_ENABLE) {
|
||||
int32_t z = new_depth << 12;
|
||||
int64_t w_depth = (int64_t) (int32_t) new_depth;
|
||||
int32_t ia = alpha_data << 12;
|
||||
|
||||
if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048)
|
||||
voodoo->dirty_line[y] = 1;
|
||||
APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth);
|
||||
}
|
||||
|
||||
if (voodoo->col_tiled)
|
||||
write_addr = voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
|
||||
else
|
||||
write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width);
|
||||
if (voodoo->aux_tiled)
|
||||
write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
|
||||
else
|
||||
write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width);
|
||||
if (params->alphaMode & 1)
|
||||
ALPHA_TEST(alpha_data);
|
||||
|
||||
// voodoo_fb_log("fb_writew %08x %i %i %i %08x\n", addr, x, y, voodoo->row_width, write_addr);
|
||||
if (params->alphaMode & (1 << 4)) {
|
||||
uint16_t dat = *(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]);
|
||||
int dest_r, dest_g, dest_b, dest_a;
|
||||
|
||||
if (voodoo->lfbMode & 0x100)
|
||||
{
|
||||
{
|
||||
rgba8_t write_data = colour_data;
|
||||
uint16_t new_depth = depth_data;
|
||||
dest_r = (dat >> 8) & 0xf8;
|
||||
dest_g = (dat >> 3) & 0xfc;
|
||||
dest_b = (dat << 3) & 0xf8;
|
||||
dest_r |= (dest_r >> 5);
|
||||
dest_g |= (dest_g >> 6);
|
||||
dest_b |= (dest_b >> 5);
|
||||
dest_a = 0xff;
|
||||
|
||||
if (params->fbzMode & FBZ_DEPTH_ENABLE)
|
||||
{
|
||||
uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]);
|
||||
ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data);
|
||||
}
|
||||
|
||||
DEPTH_TEST(new_depth);
|
||||
}
|
||||
|
||||
if ((params->fbzMode & FBZ_CHROMAKEY) &&
|
||||
write_data.r == params->chromaKey_r &&
|
||||
write_data.g == params->chromaKey_g &&
|
||||
write_data.b == params->chromaKey_b)
|
||||
goto skip_pixel;
|
||||
|
||||
if (params->fogMode & FOG_ENABLE)
|
||||
{
|
||||
int32_t z = new_depth << 12;
|
||||
int64_t w_depth = (int64_t)(int32_t)new_depth;
|
||||
int32_t ia = alpha_data << 12;
|
||||
|
||||
APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth);
|
||||
}
|
||||
|
||||
if (params->alphaMode & 1)
|
||||
ALPHA_TEST(alpha_data);
|
||||
|
||||
if (params->alphaMode & (1 << 4))
|
||||
{
|
||||
uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]);
|
||||
int dest_r, dest_g, dest_b, dest_a;
|
||||
|
||||
dest_r = (dat >> 8) & 0xf8;
|
||||
dest_g = (dat >> 3) & 0xfc;
|
||||
dest_b = (dat << 3) & 0xf8;
|
||||
dest_r |= (dest_r >> 5);
|
||||
dest_g |= (dest_g >> 6);
|
||||
dest_b |= (dest_b >> 5);
|
||||
dest_a = 0xff;
|
||||
|
||||
ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data);
|
||||
}
|
||||
|
||||
if (params->fbzMode & FBZ_RGB_WMASK)
|
||||
*(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, x >> 1, y);
|
||||
if (params->fbzMode & FBZ_DEPTH_WMASK)
|
||||
*(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth;
|
||||
if (params->fbzMode & FBZ_RGB_WMASK)
|
||||
*(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, x >> 1, y);
|
||||
if (params->fbzMode & FBZ_DEPTH_WMASK)
|
||||
*(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth;
|
||||
|
||||
skip_pixel:
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (write_mask & LFB_WRITE_COLOUR)
|
||||
*(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data, x >> 1, y);
|
||||
if (write_mask & LFB_WRITE_DEPTH)
|
||||
*(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (write_mask & LFB_WRITE_COLOUR)
|
||||
*(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data, x >> 1, y);
|
||||
if (write_mask & LFB_WRITE_DEPTH)
|
||||
*(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void voodoo_fb_writel(uint32_t addr, uint32_t val, void *p)
|
||||
void
|
||||
voodoo_fb_writel(uint32_t addr, uint32_t val, void *p)
|
||||
{
|
||||
voodoo_t *voodoo = (voodoo_t *)p;
|
||||
voodoo_params_t *params = &voodoo->params;
|
||||
int x, y;
|
||||
uint32_t write_addr, write_addr_aux;
|
||||
rgba8_t colour_data[2];
|
||||
uint16_t depth_data[2];
|
||||
uint8_t alpha_data[2];
|
||||
int write_mask = 0, count = 1;
|
||||
voodoo_t *voodoo = (voodoo_t *) p;
|
||||
voodoo_params_t *params = &voodoo->params;
|
||||
int x, y;
|
||||
uint32_t write_addr, write_addr_aux;
|
||||
rgba8_t colour_data[2];
|
||||
uint16_t depth_data[2];
|
||||
uint8_t alpha_data[2];
|
||||
int write_mask = 0, count = 1;
|
||||
|
||||
depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff;
|
||||
alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24;
|
||||
// while (!RB_EMPTY)
|
||||
// thread_reset_event(voodoo->not_full_event);
|
||||
depth_data[0] = depth_data[1] = voodoo->params.zaColor & 0xffff;
|
||||
alpha_data[0] = alpha_data[1] = voodoo->params.zaColor >> 24;
|
||||
// while (!RB_EMPTY)
|
||||
// thread_reset_event(voodoo->not_full_event);
|
||||
|
||||
// voodoo_fb_log("voodoo_fb_writel : %08X %08X\n", addr, val);
|
||||
// voodoo_fb_log("voodoo_fb_writel : %08X %08X\n", addr, val);
|
||||
|
||||
switch (voodoo->lfbMode & LFB_FORMAT_MASK)
|
||||
{
|
||||
case LFB_FORMAT_RGB565:
|
||||
colour_data[0] = rgb565[val & 0xffff];
|
||||
colour_data[1] = rgb565[val >> 16];
|
||||
write_mask = LFB_WRITE_COLOUR;
|
||||
count = 2;
|
||||
break;
|
||||
case LFB_FORMAT_RGB555:
|
||||
colour_data[0] = argb1555[val & 0xffff];
|
||||
colour_data[1] = argb1555[val >> 16];
|
||||
write_mask = LFB_WRITE_COLOUR;
|
||||
count = 2;
|
||||
break;
|
||||
case LFB_FORMAT_ARGB1555:
|
||||
colour_data[0] = argb1555[val & 0xffff];
|
||||
alpha_data[0] = colour_data[0].a;
|
||||
colour_data[1] = argb1555[val >> 16];
|
||||
alpha_data[1] = colour_data[1].a;
|
||||
write_mask = LFB_WRITE_COLOUR;
|
||||
count = 2;
|
||||
break;
|
||||
switch (voodoo->lfbMode & LFB_FORMAT_MASK) {
|
||||
case LFB_FORMAT_RGB565:
|
||||
colour_data[0] = rgb565[val & 0xffff];
|
||||
colour_data[1] = rgb565[val >> 16];
|
||||
write_mask = LFB_WRITE_COLOUR;
|
||||
count = 2;
|
||||
break;
|
||||
case LFB_FORMAT_RGB555:
|
||||
colour_data[0] = argb1555[val & 0xffff];
|
||||
colour_data[1] = argb1555[val >> 16];
|
||||
write_mask = LFB_WRITE_COLOUR;
|
||||
count = 2;
|
||||
break;
|
||||
case LFB_FORMAT_ARGB1555:
|
||||
colour_data[0] = argb1555[val & 0xffff];
|
||||
alpha_data[0] = colour_data[0].a;
|
||||
colour_data[1] = argb1555[val >> 16];
|
||||
alpha_data[1] = colour_data[1].a;
|
||||
write_mask = LFB_WRITE_COLOUR;
|
||||
count = 2;
|
||||
break;
|
||||
|
||||
case LFB_FORMAT_ARGB8888:
|
||||
colour_data[0].b = val & 0xff;
|
||||
colour_data[0].g = (val >> 8) & 0xff;
|
||||
colour_data[0].r = (val >> 16) & 0xff;
|
||||
alpha_data[0] = (val >> 24) & 0xff;
|
||||
write_mask = LFB_WRITE_COLOUR;
|
||||
addr >>= 1;
|
||||
break;
|
||||
case LFB_FORMAT_ARGB8888:
|
||||
colour_data[0].b = val & 0xff;
|
||||
colour_data[0].g = (val >> 8) & 0xff;
|
||||
colour_data[0].r = (val >> 16) & 0xff;
|
||||
alpha_data[0] = (val >> 24) & 0xff;
|
||||
write_mask = LFB_WRITE_COLOUR;
|
||||
addr >>= 1;
|
||||
break;
|
||||
|
||||
case LFB_FORMAT_DEPTH:
|
||||
depth_data[0] = val;
|
||||
depth_data[1] = val >> 16;
|
||||
write_mask = LFB_WRITE_DEPTH;
|
||||
count = 2;
|
||||
break;
|
||||
case LFB_FORMAT_DEPTH:
|
||||
depth_data[0] = val;
|
||||
depth_data[1] = val >> 16;
|
||||
write_mask = LFB_WRITE_DEPTH;
|
||||
count = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("voodoo_fb_writel : bad LFB format %08X\n", voodoo->lfbMode);
|
||||
}
|
||||
default:
|
||||
fatal("voodoo_fb_writel : bad LFB format %08X\n", voodoo->lfbMode);
|
||||
}
|
||||
|
||||
if (voodoo->type >= VOODOO_BANSHEE)
|
||||
{
|
||||
x = addr & 0xffe;
|
||||
y = (addr >> 12) & 0x3ff;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = addr & 0x7fe;
|
||||
y = (addr >> 11) & 0x3ff;
|
||||
}
|
||||
if (voodoo->type >= VOODOO_BANSHEE) {
|
||||
x = addr & 0xffe;
|
||||
y = (addr >> 12) & 0x3ff;
|
||||
} else {
|
||||
x = addr & 0x7fe;
|
||||
y = (addr >> 11) & 0x3ff;
|
||||
}
|
||||
|
||||
if (SLI_ENABLED)
|
||||
{
|
||||
if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) ||
|
||||
((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1)))
|
||||
return;
|
||||
y >>= 1;
|
||||
}
|
||||
if (SLI_ENABLED) {
|
||||
if ((!(voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && (y & 1)) || ((voodoo->initEnable & INITENABLE_SLI_MASTER_SLAVE) && !(y & 1)))
|
||||
return;
|
||||
y >>= 1;
|
||||
}
|
||||
|
||||
if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048)
|
||||
voodoo->dirty_line[y] = 1;
|
||||
if (voodoo->fb_write_offset == voodoo->params.front_offset && y < 2048)
|
||||
voodoo->dirty_line[y] = 1;
|
||||
|
||||
if (voodoo->col_tiled)
|
||||
write_addr = voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
|
||||
else
|
||||
write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width);
|
||||
if (voodoo->aux_tiled)
|
||||
write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128*32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
|
||||
else
|
||||
write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width);
|
||||
if (voodoo->col_tiled)
|
||||
write_addr = voodoo->fb_write_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
|
||||
else
|
||||
write_addr = voodoo->fb_write_offset + x + (y * voodoo->row_width);
|
||||
if (voodoo->aux_tiled)
|
||||
write_addr_aux = voodoo->params.aux_offset + (x & 127) + (x >> 7) * 128 * 32 + (y & 31) * 128 + (y >> 5) * voodoo->row_width;
|
||||
else
|
||||
write_addr_aux = voodoo->params.aux_offset + x + (y * voodoo->row_width);
|
||||
|
||||
// voodoo_fb_log("fb_writel %08x x=%i y=%i rw=%i %08x wo=%08x\n", addr, x, y, voodoo->row_width, write_addr, voodoo->fb_write_offset);
|
||||
// voodoo_fb_log("fb_writel %08x x=%i y=%i rw=%i %08x wo=%08x\n", addr, x, y, voodoo->row_width, write_addr, voodoo->fb_write_offset);
|
||||
|
||||
if (voodoo->lfbMode & 0x100)
|
||||
{
|
||||
int c;
|
||||
if (voodoo->lfbMode & 0x100) {
|
||||
int c;
|
||||
|
||||
for (c = 0; c < count; c++)
|
||||
{
|
||||
rgba8_t write_data = colour_data[c];
|
||||
uint16_t new_depth = depth_data[c];
|
||||
for (c = 0; c < count; c++) {
|
||||
rgba8_t write_data = colour_data[c];
|
||||
uint16_t new_depth = depth_data[c];
|
||||
|
||||
if (params->fbzMode & FBZ_DEPTH_ENABLE)
|
||||
{
|
||||
uint16_t old_depth = *(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]);
|
||||
if (params->fbzMode & FBZ_DEPTH_ENABLE) {
|
||||
uint16_t old_depth = *(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]);
|
||||
|
||||
DEPTH_TEST(new_depth);
|
||||
}
|
||||
DEPTH_TEST(new_depth);
|
||||
}
|
||||
|
||||
if ((params->fbzMode & FBZ_CHROMAKEY) &&
|
||||
write_data.r == params->chromaKey_r &&
|
||||
write_data.g == params->chromaKey_g &&
|
||||
write_data.b == params->chromaKey_b)
|
||||
goto skip_pixel;
|
||||
if ((params->fbzMode & FBZ_CHROMAKEY) && write_data.r == params->chromaKey_r && write_data.g == params->chromaKey_g && write_data.b == params->chromaKey_b)
|
||||
goto skip_pixel;
|
||||
|
||||
if (params->fogMode & FOG_ENABLE)
|
||||
{
|
||||
int32_t z = new_depth << 12;
|
||||
int64_t w_depth = new_depth;
|
||||
int32_t ia = alpha_data[c] << 12;
|
||||
if (params->fogMode & FOG_ENABLE) {
|
||||
int32_t z = new_depth << 12;
|
||||
int64_t w_depth = new_depth;
|
||||
int32_t ia = alpha_data[c] << 12;
|
||||
|
||||
APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth);
|
||||
}
|
||||
APPLY_FOG(write_data.r, write_data.g, write_data.b, z, ia, w_depth);
|
||||
}
|
||||
|
||||
if (params->alphaMode & 1)
|
||||
ALPHA_TEST(alpha_data[c]);
|
||||
if (params->alphaMode & 1)
|
||||
ALPHA_TEST(alpha_data[c]);
|
||||
|
||||
if (params->alphaMode & (1 << 4))
|
||||
{
|
||||
uint16_t dat = *(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]);
|
||||
int dest_r, dest_g, dest_b, dest_a;
|
||||
if (params->alphaMode & (1 << 4)) {
|
||||
uint16_t dat = *(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]);
|
||||
int dest_r, dest_g, dest_b, dest_a;
|
||||
|
||||
dest_r = (dat >> 8) & 0xf8;
|
||||
dest_g = (dat >> 3) & 0xfc;
|
||||
dest_b = (dat << 3) & 0xf8;
|
||||
dest_r |= (dest_r >> 5);
|
||||
dest_g |= (dest_g >> 6);
|
||||
dest_b |= (dest_b >> 5);
|
||||
dest_a = 0xff;
|
||||
dest_r = (dat >> 8) & 0xf8;
|
||||
dest_g = (dat >> 3) & 0xfc;
|
||||
dest_b = (dat << 3) & 0xf8;
|
||||
dest_r |= (dest_r >> 5);
|
||||
dest_g |= (dest_g >> 6);
|
||||
dest_b |= (dest_b >> 5);
|
||||
dest_a = 0xff;
|
||||
|
||||
ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data[c]);
|
||||
}
|
||||
ALPHA_BLEND(write_data.r, write_data.g, write_data.b, alpha_data[c]);
|
||||
}
|
||||
|
||||
if (params->fbzMode & FBZ_RGB_WMASK)
|
||||
*(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, (x >> 1) + c, y);
|
||||
if (params->fbzMode & FBZ_DEPTH_WMASK)
|
||||
*(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth;
|
||||
if (params->fbzMode & FBZ_RGB_WMASK)
|
||||
*(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, write_data, (x >> 1) + c, y);
|
||||
if (params->fbzMode & FBZ_DEPTH_WMASK)
|
||||
*(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = new_depth;
|
||||
|
||||
skip_pixel:
|
||||
write_addr += 2;
|
||||
write_addr_aux += 2;
|
||||
}
|
||||
write_addr += 2;
|
||||
write_addr_aux += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
int c;
|
||||
} else {
|
||||
int c;
|
||||
|
||||
for (c = 0; c < count; c++)
|
||||
{
|
||||
if (write_mask & LFB_WRITE_COLOUR)
|
||||
*(uint16_t *)(&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data[c], (x >> 1) + c, y);
|
||||
if (write_mask & LFB_WRITE_DEPTH)
|
||||
*(uint16_t *)(&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data[c];
|
||||
for (c = 0; c < count; c++) {
|
||||
if (write_mask & LFB_WRITE_COLOUR)
|
||||
*(uint16_t *) (&voodoo->fb_mem[write_addr & voodoo->fb_mask]) = do_dither(&voodoo->params, colour_data[c], (x >> 1) + c, y);
|
||||
if (write_mask & LFB_WRITE_DEPTH)
|
||||
*(uint16_t *) (&voodoo->fb_mem[write_addr_aux & voodoo->fb_mask]) = depth_data[c];
|
||||
|
||||
write_addr += 2;
|
||||
write_addr_aux += 2;
|
||||
}
|
||||
write_addr += 2;
|
||||
write_addr_aux += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include <86box/vid_voodoo_render.h>
|
||||
#include <86box/vid_voodoo_texture.h>
|
||||
|
||||
|
||||
#ifdef ENABLE_VOODOO_FIFO_LOG
|
||||
int voodoo_fifo_do_log = ENABLE_VOODOO_FIFO_LOG;
|
||||
|
||||
@@ -51,497 +50,461 @@ voodoo_fifo_log(const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
if (voodoo_fifo_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define voodoo_fifo_log(fmt, ...)
|
||||
# define voodoo_fifo_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
#define WAKE_DELAY (TIMER_USEC * 100)
|
||||
void voodoo_wake_fifo_thread(voodoo_t *voodoo)
|
||||
void
|
||||
voodoo_wake_fifo_thread(voodoo_t *voodoo)
|
||||
{
|
||||
if (!timer_is_enabled(&voodoo->wake_timer))
|
||||
{
|
||||
/*Don't wake FIFO thread immediately - if we do that it will probably
|
||||
process one word and go back to sleep, requiring it to be woken on
|
||||
almost every write. Instead, wait a short while so that the CPU
|
||||
emulation writes more data so we have more batched-up work.*/
|
||||
timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY);
|
||||
}
|
||||
if (!timer_is_enabled(&voodoo->wake_timer)) {
|
||||
/*Don't wake FIFO thread immediately - if we do that it will probably
|
||||
process one word and go back to sleep, requiring it to be woken on
|
||||
almost every write. Instead, wait a short while so that the CPU
|
||||
emulation writes more data so we have more batched-up work.*/
|
||||
timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY);
|
||||
}
|
||||
}
|
||||
|
||||
void voodoo_wake_fifo_thread_now(voodoo_t *voodoo)
|
||||
void
|
||||
voodoo_wake_fifo_thread_now(voodoo_t *voodoo)
|
||||
{
|
||||
thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/
|
||||
thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/
|
||||
}
|
||||
|
||||
void voodoo_wake_timer(void *p)
|
||||
void
|
||||
voodoo_wake_timer(void *p)
|
||||
{
|
||||
voodoo_t *voodoo = (voodoo_t *)p;
|
||||
voodoo_t *voodoo = (voodoo_t *) p;
|
||||
|
||||
thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/
|
||||
thread_set_event(voodoo->wake_fifo_thread); /*Wake up FIFO thread if moving from idle*/
|
||||
}
|
||||
|
||||
void voodoo_queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val)
|
||||
void
|
||||
voodoo_queue_command(voodoo_t *voodoo, uint32_t addr_type, uint32_t val)
|
||||
{
|
||||
fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_write_idx & FIFO_MASK];
|
||||
fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_write_idx & FIFO_MASK];
|
||||
|
||||
while (FIFO_FULL)
|
||||
{
|
||||
thread_reset_event(voodoo->fifo_not_full_event);
|
||||
if (FIFO_FULL)
|
||||
{
|
||||
thread_wait_event(voodoo->fifo_not_full_event, 1); /*Wait for room in ringbuffer*/
|
||||
if (FIFO_FULL)
|
||||
voodoo_wake_fifo_thread_now(voodoo);
|
||||
}
|
||||
}
|
||||
|
||||
fifo->val = val;
|
||||
fifo->addr_type = addr_type;
|
||||
|
||||
voodoo->fifo_write_idx++;
|
||||
|
||||
if (FIFO_ENTRIES > 0xe000)
|
||||
voodoo_wake_fifo_thread(voodoo);
|
||||
}
|
||||
|
||||
void voodoo_flush(voodoo_t *voodoo)
|
||||
{
|
||||
voodoo->flush = 1;
|
||||
while (!FIFO_EMPTY)
|
||||
{
|
||||
while (FIFO_FULL) {
|
||||
thread_reset_event(voodoo->fifo_not_full_event);
|
||||
if (FIFO_FULL) {
|
||||
thread_wait_event(voodoo->fifo_not_full_event, 1); /*Wait for room in ringbuffer*/
|
||||
if (FIFO_FULL)
|
||||
voodoo_wake_fifo_thread_now(voodoo);
|
||||
thread_wait_event(voodoo->fifo_not_full_event, 1);
|
||||
}
|
||||
voodoo_wait_for_render_thread_idle(voodoo);
|
||||
voodoo->flush = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void voodoo_wake_fifo_threads(voodoo_set_t *set, voodoo_t *voodoo)
|
||||
{
|
||||
fifo->val = val;
|
||||
fifo->addr_type = addr_type;
|
||||
|
||||
voodoo->fifo_write_idx++;
|
||||
|
||||
if (FIFO_ENTRIES > 0xe000)
|
||||
voodoo_wake_fifo_thread(voodoo);
|
||||
if (SLI_ENABLED && voodoo->type != VOODOO_2 && set->voodoos[0] == voodoo)
|
||||
voodoo_wake_fifo_thread(set->voodoos[1]);
|
||||
}
|
||||
|
||||
void voodoo_wait_for_swap_complete(voodoo_t *voodoo)
|
||||
void
|
||||
voodoo_flush(voodoo_t *voodoo)
|
||||
{
|
||||
while (voodoo->swap_pending)
|
||||
{
|
||||
thread_wait_event(voodoo->wake_fifo_thread, -1);
|
||||
thread_reset_event(voodoo->wake_fifo_thread);
|
||||
voodoo->flush = 1;
|
||||
while (!FIFO_EMPTY) {
|
||||
voodoo_wake_fifo_thread_now(voodoo);
|
||||
thread_wait_event(voodoo->fifo_not_full_event, 1);
|
||||
}
|
||||
voodoo_wait_for_render_thread_idle(voodoo);
|
||||
voodoo->flush = 0;
|
||||
}
|
||||
|
||||
thread_wait_mutex(voodoo->swap_mutex);
|
||||
if ((voodoo->swap_pending && voodoo->flush) || FIFO_FULL)
|
||||
{
|
||||
/*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/
|
||||
memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line));
|
||||
voodoo->front_offset = voodoo->params.front_offset;
|
||||
if (voodoo->swap_count > 0)
|
||||
voodoo->swap_count--;
|
||||
voodoo->swap_pending = 0;
|
||||
thread_release_mutex(voodoo->swap_mutex);;
|
||||
break;
|
||||
}
|
||||
else
|
||||
thread_release_mutex(voodoo->swap_mutex);;
|
||||
void
|
||||
voodoo_wake_fifo_threads(voodoo_set_t *set, voodoo_t *voodoo)
|
||||
{
|
||||
voodoo_wake_fifo_thread(voodoo);
|
||||
if (SLI_ENABLED && voodoo->type != VOODOO_2 && set->voodoos[0] == voodoo)
|
||||
voodoo_wake_fifo_thread(set->voodoos[1]);
|
||||
}
|
||||
|
||||
void
|
||||
voodoo_wait_for_swap_complete(voodoo_t *voodoo)
|
||||
{
|
||||
while (voodoo->swap_pending) {
|
||||
thread_wait_event(voodoo->wake_fifo_thread, -1);
|
||||
thread_reset_event(voodoo->wake_fifo_thread);
|
||||
|
||||
thread_wait_mutex(voodoo->swap_mutex);
|
||||
if ((voodoo->swap_pending && voodoo->flush) || FIFO_FULL) {
|
||||
/*Main thread is waiting for FIFO to empty, so skip vsync wait and just swap*/
|
||||
memset(voodoo->dirty_line, 1, sizeof(voodoo->dirty_line));
|
||||
voodoo->front_offset = voodoo->params.front_offset;
|
||||
if (voodoo->swap_count > 0)
|
||||
voodoo->swap_count--;
|
||||
voodoo->swap_pending = 0;
|
||||
thread_release_mutex(voodoo->swap_mutex);
|
||||
;
|
||||
break;
|
||||
} else
|
||||
thread_release_mutex(voodoo->swap_mutex);
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
cmdfifo_get(voodoo_t *voodoo)
|
||||
{
|
||||
uint32_t val;
|
||||
|
||||
if (!voodoo->cmdfifo_in_sub) {
|
||||
while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr) {
|
||||
thread_wait_event(voodoo->wake_fifo_thread, -1);
|
||||
thread_reset_event(voodoo->wake_fifo_thread);
|
||||
}
|
||||
}
|
||||
|
||||
val = *(uint32_t *) &voodoo->fb_mem[voodoo->cmdfifo_rp & voodoo->fb_mask];
|
||||
|
||||
if (!voodoo->cmdfifo_in_sub)
|
||||
voodoo->cmdfifo_depth_rd++;
|
||||
voodoo->cmdfifo_rp += 4;
|
||||
|
||||
// voodoo_fifo_log(" CMDFIFO get %08x\n", val);
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
static uint32_t cmdfifo_get(voodoo_t *voodoo)
|
||||
static inline float
|
||||
cmdfifo_get_f(voodoo_t *voodoo)
|
||||
{
|
||||
uint32_t val;
|
||||
union {
|
||||
uint32_t i;
|
||||
float f;
|
||||
} tempif;
|
||||
|
||||
if (!voodoo->cmdfifo_in_sub) {
|
||||
while (voodoo->cmdfifo_depth_rd == voodoo->cmdfifo_depth_wr)
|
||||
{
|
||||
thread_wait_event(voodoo->wake_fifo_thread, -1);
|
||||
thread_reset_event(voodoo->wake_fifo_thread);
|
||||
}
|
||||
}
|
||||
|
||||
val = *(uint32_t *)&voodoo->fb_mem[voodoo->cmdfifo_rp & voodoo->fb_mask];
|
||||
|
||||
if (!voodoo->cmdfifo_in_sub)
|
||||
voodoo->cmdfifo_depth_rd++;
|
||||
voodoo->cmdfifo_rp += 4;
|
||||
|
||||
// voodoo_fifo_log(" CMDFIFO get %08x\n", val);
|
||||
return val;
|
||||
tempif.i = cmdfifo_get(voodoo);
|
||||
return tempif.f;
|
||||
}
|
||||
|
||||
static inline float cmdfifo_get_f(voodoo_t *voodoo)
|
||||
{
|
||||
union
|
||||
{
|
||||
uint32_t i;
|
||||
float f;
|
||||
} tempif;
|
||||
enum {
|
||||
CMDFIFO3_PC_MASK_RGB = (1 << 10),
|
||||
CMDFIFO3_PC_MASK_ALPHA = (1 << 11),
|
||||
CMDFIFO3_PC_MASK_Z = (1 << 12),
|
||||
CMDFIFO3_PC_MASK_Wb = (1 << 13),
|
||||
CMDFIFO3_PC_MASK_W0 = (1 << 14),
|
||||
CMDFIFO3_PC_MASK_S0_T0 = (1 << 15),
|
||||
CMDFIFO3_PC_MASK_W1 = (1 << 16),
|
||||
CMDFIFO3_PC_MASK_S1_T1 = (1 << 17),
|
||||
|
||||
tempif.i = cmdfifo_get(voodoo);
|
||||
return tempif.f;
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
CMDFIFO3_PC_MASK_RGB = (1 << 10),
|
||||
CMDFIFO3_PC_MASK_ALPHA = (1 << 11),
|
||||
CMDFIFO3_PC_MASK_Z = (1 << 12),
|
||||
CMDFIFO3_PC_MASK_Wb = (1 << 13),
|
||||
CMDFIFO3_PC_MASK_W0 = (1 << 14),
|
||||
CMDFIFO3_PC_MASK_S0_T0 = (1 << 15),
|
||||
CMDFIFO3_PC_MASK_W1 = (1 << 16),
|
||||
CMDFIFO3_PC_MASK_S1_T1 = (1 << 17),
|
||||
|
||||
CMDFIFO3_PC = (1 << 28)
|
||||
CMDFIFO3_PC = (1 << 28)
|
||||
};
|
||||
|
||||
void voodoo_fifo_thread(void *param)
|
||||
void
|
||||
voodoo_fifo_thread(void *param)
|
||||
{
|
||||
voodoo_t *voodoo = (voodoo_t *)param;
|
||||
voodoo_t *voodoo = (voodoo_t *) param;
|
||||
|
||||
while (voodoo->fifo_thread_run)
|
||||
{
|
||||
while (voodoo->fifo_thread_run) {
|
||||
thread_set_event(voodoo->fifo_not_full_event);
|
||||
thread_wait_event(voodoo->wake_fifo_thread, -1);
|
||||
thread_reset_event(voodoo->wake_fifo_thread);
|
||||
voodoo->voodoo_busy = 1;
|
||||
while (!FIFO_EMPTY) {
|
||||
uint64_t start_time = plat_timer_read();
|
||||
uint64_t end_time;
|
||||
fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
|
||||
|
||||
switch (fifo->addr_type & FIFO_TYPE) {
|
||||
case FIFO_WRITEL_REG:
|
||||
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_REG) {
|
||||
voodoo_reg_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo);
|
||||
fifo->addr_type = FIFO_INVALID;
|
||||
voodoo->fifo_read_idx++;
|
||||
if (FIFO_EMPTY)
|
||||
break;
|
||||
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
|
||||
}
|
||||
break;
|
||||
case FIFO_WRITEW_FB:
|
||||
voodoo_wait_for_render_thread_idle(voodoo);
|
||||
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEW_FB) {
|
||||
voodoo_fb_writew(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo);
|
||||
fifo->addr_type = FIFO_INVALID;
|
||||
voodoo->fifo_read_idx++;
|
||||
if (FIFO_EMPTY)
|
||||
break;
|
||||
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
|
||||
}
|
||||
break;
|
||||
case FIFO_WRITEL_FB:
|
||||
voodoo_wait_for_render_thread_idle(voodoo);
|
||||
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_FB) {
|
||||
voodoo_fb_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo);
|
||||
fifo->addr_type = FIFO_INVALID;
|
||||
voodoo->fifo_read_idx++;
|
||||
if (FIFO_EMPTY)
|
||||
break;
|
||||
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
|
||||
}
|
||||
break;
|
||||
case FIFO_WRITEL_TEX:
|
||||
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_TEX) {
|
||||
if (!(fifo->addr_type & 0x400000))
|
||||
voodoo_tex_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo);
|
||||
fifo->addr_type = FIFO_INVALID;
|
||||
voodoo->fifo_read_idx++;
|
||||
if (FIFO_EMPTY)
|
||||
break;
|
||||
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
|
||||
}
|
||||
break;
|
||||
case FIFO_WRITEL_2DREG:
|
||||
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_2DREG) {
|
||||
voodoo_2d_reg_writel(voodoo, fifo->addr_type & FIFO_ADDR, fifo->val);
|
||||
fifo->addr_type = FIFO_INVALID;
|
||||
voodoo->fifo_read_idx++;
|
||||
if (FIFO_EMPTY)
|
||||
break;
|
||||
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("Unknown fifo entry %08x\n", fifo->addr_type);
|
||||
}
|
||||
|
||||
if (FIFO_ENTRIES > 0xe000)
|
||||
thread_set_event(voodoo->fifo_not_full_event);
|
||||
thread_wait_event(voodoo->wake_fifo_thread, -1);
|
||||
thread_reset_event(voodoo->wake_fifo_thread);
|
||||
voodoo->voodoo_busy = 1;
|
||||
while (!FIFO_EMPTY)
|
||||
{
|
||||
uint64_t start_time = plat_timer_read();
|
||||
uint64_t end_time;
|
||||
fifo_entry_t *fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
|
||||
|
||||
switch (fifo->addr_type & FIFO_TYPE)
|
||||
{
|
||||
case FIFO_WRITEL_REG:
|
||||
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_REG)
|
||||
{
|
||||
voodoo_reg_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo);
|
||||
fifo->addr_type = FIFO_INVALID;
|
||||
voodoo->fifo_read_idx++;
|
||||
if (FIFO_EMPTY)
|
||||
break;
|
||||
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
|
||||
}
|
||||
break;
|
||||
case FIFO_WRITEW_FB:
|
||||
voodoo_wait_for_render_thread_idle(voodoo);
|
||||
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEW_FB)
|
||||
{
|
||||
voodoo_fb_writew(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo);
|
||||
fifo->addr_type = FIFO_INVALID;
|
||||
voodoo->fifo_read_idx++;
|
||||
if (FIFO_EMPTY)
|
||||
break;
|
||||
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
|
||||
}
|
||||
break;
|
||||
case FIFO_WRITEL_FB:
|
||||
voodoo_wait_for_render_thread_idle(voodoo);
|
||||
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_FB)
|
||||
{
|
||||
voodoo_fb_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo);
|
||||
fifo->addr_type = FIFO_INVALID;
|
||||
voodoo->fifo_read_idx++;
|
||||
if (FIFO_EMPTY)
|
||||
break;
|
||||
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
|
||||
}
|
||||
break;
|
||||
case FIFO_WRITEL_TEX:
|
||||
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_TEX)
|
||||
{
|
||||
if (!(fifo->addr_type & 0x400000))
|
||||
voodoo_tex_writel(fifo->addr_type & FIFO_ADDR, fifo->val, voodoo);
|
||||
fifo->addr_type = FIFO_INVALID;
|
||||
voodoo->fifo_read_idx++;
|
||||
if (FIFO_EMPTY)
|
||||
break;
|
||||
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
|
||||
}
|
||||
break;
|
||||
case FIFO_WRITEL_2DREG:
|
||||
while ((fifo->addr_type & FIFO_TYPE) == FIFO_WRITEL_2DREG)
|
||||
{
|
||||
voodoo_2d_reg_writel(voodoo, fifo->addr_type & FIFO_ADDR, fifo->val);
|
||||
fifo->addr_type = FIFO_INVALID;
|
||||
voodoo->fifo_read_idx++;
|
||||
if (FIFO_EMPTY)
|
||||
break;
|
||||
fifo = &voodoo->fifo[voodoo->fifo_read_idx & FIFO_MASK];
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("Unknown fifo entry %08x\n", fifo->addr_type);
|
||||
}
|
||||
|
||||
if (FIFO_ENTRIES > 0xe000)
|
||||
thread_set_event(voodoo->fifo_not_full_event);
|
||||
|
||||
end_time = plat_timer_read();
|
||||
voodoo->time += end_time - start_time;
|
||||
}
|
||||
|
||||
while (voodoo->cmdfifo_enabled && (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr || voodoo->cmdfifo_in_sub))
|
||||
{
|
||||
uint64_t start_time = plat_timer_read();
|
||||
uint64_t end_time;
|
||||
uint32_t header = cmdfifo_get(voodoo);
|
||||
uint32_t addr;
|
||||
uint32_t mask;
|
||||
int smode;
|
||||
int num;
|
||||
int num_verticies;
|
||||
int v_num;
|
||||
|
||||
// voodoo_fifo_log(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp);
|
||||
|
||||
switch (header & 7)
|
||||
{
|
||||
case 0:
|
||||
// voodoo_fifo_log("CMDFIFO0\n");
|
||||
switch ((header >> 3) & 7)
|
||||
{
|
||||
case 0: /*NOP*/
|
||||
break;
|
||||
|
||||
case 1: /*JSR*/
|
||||
// voodoo_fifo_log("JSR %08x\n", (header >> 4) & 0xfffffc);
|
||||
voodoo->cmdfifo_ret_addr = voodoo->cmdfifo_rp;
|
||||
voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc;
|
||||
voodoo->cmdfifo_in_sub = 1;
|
||||
break;
|
||||
|
||||
case 2: /*RET*/
|
||||
voodoo->cmdfifo_rp = voodoo->cmdfifo_ret_addr;
|
||||
voodoo->cmdfifo_in_sub = 0;
|
||||
break;
|
||||
|
||||
case 3: /*JMP local frame buffer*/
|
||||
voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc;
|
||||
// voodoo_fifo_log("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("Bad CMDFIFO0 %08x\n", header);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
num = header >> 16;
|
||||
addr = (header & 0x7ff8) >> 1;
|
||||
// voodoo_fifo_log("CMDFIFO1 addr=%08x\n",addr);
|
||||
while (num--)
|
||||
{
|
||||
uint32_t val = cmdfifo_get(voodoo);
|
||||
if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE)
|
||||
{
|
||||
// if (voodoo->type != VOODOO_BANSHEE)
|
||||
// fatal("CMDFIFO1: Not Banshee\n");
|
||||
// voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val);
|
||||
voodoo_2d_reg_writel(voodoo, addr, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD ||
|
||||
(addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD)
|
||||
voodoo->cmd_written_fifo++;
|
||||
|
||||
if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD)
|
||||
voodoo->cmd_written_fifo++;
|
||||
voodoo_reg_writel(addr, val, voodoo);
|
||||
}
|
||||
|
||||
if (header & (1 << 15))
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (voodoo->type < VOODOO_BANSHEE)
|
||||
fatal("CMDFIFO2: Not Banshee\n");
|
||||
mask = (header >> 3);
|
||||
addr = 8;
|
||||
while (mask)
|
||||
{
|
||||
if (mask & 1)
|
||||
{
|
||||
uint32_t val = cmdfifo_get(voodoo);
|
||||
|
||||
voodoo_2d_reg_writel(voodoo, addr, val);
|
||||
}
|
||||
|
||||
addr += 4;
|
||||
mask >>= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
num = (header >> 29) & 7;
|
||||
mask = header;//(header >> 10) & 0xff;
|
||||
smode = (header >> 22) & 0xf;
|
||||
voodoo_reg_writel(SST_sSetupMode, ((header >> 10) & 0xff) | (smode << 16), voodoo);
|
||||
num_verticies = (header >> 6) & 0xf;
|
||||
v_num = 0;
|
||||
if (((header >> 3) & 7) == 2)
|
||||
v_num = 1;
|
||||
// voodoo_fifo_log("CMDFIFO3: num=%i verts=%i mask=%02x\n", num, num_verticies, (header >> 10) & 0xff);
|
||||
// voodoo_fifo_log("CMDFIFO3 %02x %i\n", (header >> 10), (header >> 3) & 7);
|
||||
|
||||
while (num_verticies--)
|
||||
{
|
||||
voodoo->verts[3].sVx = cmdfifo_get_f(voodoo);
|
||||
voodoo->verts[3].sVy = cmdfifo_get_f(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_RGB)
|
||||
{
|
||||
if (header & CMDFIFO3_PC)
|
||||
{
|
||||
uint32_t val = cmdfifo_get(voodoo);
|
||||
voodoo->verts[3].sBlue = (float)(val & 0xff);
|
||||
voodoo->verts[3].sGreen = (float)((val >> 8) & 0xff);
|
||||
voodoo->verts[3].sRed = (float)((val >> 16) & 0xff);
|
||||
voodoo->verts[3].sAlpha = (float)((val >> 24) & 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
voodoo->verts[3].sRed = cmdfifo_get_f(voodoo);
|
||||
voodoo->verts[3].sGreen = cmdfifo_get_f(voodoo);
|
||||
voodoo->verts[3].sBlue = cmdfifo_get_f(voodoo);
|
||||
}
|
||||
}
|
||||
if ((mask & CMDFIFO3_PC_MASK_ALPHA) && !(header & CMDFIFO3_PC))
|
||||
voodoo->verts[3].sAlpha = cmdfifo_get_f(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_Z)
|
||||
voodoo->verts[3].sVz = cmdfifo_get_f(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_Wb)
|
||||
voodoo->verts[3].sWb = cmdfifo_get_f(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_W0)
|
||||
voodoo->verts[3].sW0 = cmdfifo_get_f(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_S0_T0)
|
||||
{
|
||||
voodoo->verts[3].sS0 = cmdfifo_get_f(voodoo);
|
||||
voodoo->verts[3].sT0 = cmdfifo_get_f(voodoo);
|
||||
}
|
||||
if (mask & CMDFIFO3_PC_MASK_W1)
|
||||
voodoo->verts[3].sW1 = cmdfifo_get_f(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_S1_T1)
|
||||
{
|
||||
voodoo->verts[3].sS1 = cmdfifo_get_f(voodoo);
|
||||
voodoo->verts[3].sT1 = cmdfifo_get_f(voodoo);
|
||||
}
|
||||
if (v_num)
|
||||
voodoo_reg_writel(SST_sDrawTriCMD, 0, voodoo);
|
||||
else
|
||||
voodoo_reg_writel(SST_sBeginTriCMD, 0, voodoo);
|
||||
v_num++;
|
||||
if (v_num == 3 && ((header >> 3) & 7) == 0)
|
||||
v_num = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
num = (header >> 29) & 7;
|
||||
mask = (header >> 15) & 0x3fff;
|
||||
addr = (header & 0x7ff8) >> 1;
|
||||
// voodoo_fifo_log("CMDFIFO4 addr=%08x\n",addr);
|
||||
while (mask)
|
||||
{
|
||||
if (mask & 1)
|
||||
{
|
||||
uint32_t val = cmdfifo_get(voodoo);
|
||||
|
||||
if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE)
|
||||
{
|
||||
if (voodoo->type < VOODOO_BANSHEE)
|
||||
fatal("CMDFIFO1: Not Banshee\n");
|
||||
// voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val);
|
||||
voodoo_2d_reg_writel(voodoo, addr, val);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD ||
|
||||
(addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD)
|
||||
voodoo->cmd_written_fifo++;
|
||||
|
||||
if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD)
|
||||
voodoo->cmd_written_fifo++;
|
||||
voodoo_reg_writel(addr, val, voodoo);
|
||||
}
|
||||
}
|
||||
|
||||
addr += 4;
|
||||
mask >>= 1;
|
||||
}
|
||||
while (num--)
|
||||
cmdfifo_get(voodoo);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// if (header & 0x3fc00000)
|
||||
// fatal("CMDFIFO packet 5 has byte disables set %08x\n", header);
|
||||
num = (header >> 3) & 0x7ffff;
|
||||
addr = cmdfifo_get(voodoo) & 0xffffff;
|
||||
if (!num)
|
||||
num = 1;
|
||||
// voodoo_fifo_log("CMDFIFO5 addr=%08x num=%i\n", addr, num);
|
||||
switch (header >> 30)
|
||||
{
|
||||
case 0: /*Linear framebuffer (Banshee)*/
|
||||
case 1: /*Planar YUV*/
|
||||
if (voodoo->texture_present[0][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT])
|
||||
{
|
||||
// voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT);
|
||||
flush_texture_cache(voodoo, addr & voodoo->texture_mask, 0);
|
||||
}
|
||||
if (voodoo->texture_present[1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT])
|
||||
{
|
||||
// voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT);
|
||||
flush_texture_cache(voodoo, addr & voodoo->texture_mask, 1);
|
||||
}
|
||||
while (num--)
|
||||
{
|
||||
uint32_t val = cmdfifo_get(voodoo);
|
||||
if (addr <= voodoo->fb_mask)
|
||||
*(uint32_t *)&voodoo->fb_mem[addr] = val;
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
case 2: /*Framebuffer*/
|
||||
while (num--)
|
||||
{
|
||||
uint32_t val = cmdfifo_get(voodoo);
|
||||
voodoo_fb_writel(addr, val, voodoo);
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
case 3: /*Texture*/
|
||||
while (num--)
|
||||
{
|
||||
uint32_t val = cmdfifo_get(voodoo);
|
||||
voodoo_tex_writel(addr, val, voodoo);
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("CMDFIFO packet 5 bad space %08x %08x\n", header, voodoo->cmdfifo_rp);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp);
|
||||
}
|
||||
|
||||
end_time = plat_timer_read();
|
||||
voodoo->time += end_time - start_time;
|
||||
}
|
||||
voodoo->voodoo_busy = 0;
|
||||
end_time = plat_timer_read();
|
||||
voodoo->time += end_time - start_time;
|
||||
}
|
||||
|
||||
while (voodoo->cmdfifo_enabled && (voodoo->cmdfifo_depth_rd != voodoo->cmdfifo_depth_wr || voodoo->cmdfifo_in_sub)) {
|
||||
uint64_t start_time = plat_timer_read();
|
||||
uint64_t end_time;
|
||||
uint32_t header = cmdfifo_get(voodoo);
|
||||
uint32_t addr;
|
||||
uint32_t mask;
|
||||
int smode;
|
||||
int num;
|
||||
int num_verticies;
|
||||
int v_num;
|
||||
|
||||
// voodoo_fifo_log(" CMDFIFO header %08x at %08x\n", header, voodoo->cmdfifo_rp);
|
||||
|
||||
switch (header & 7) {
|
||||
case 0:
|
||||
// voodoo_fifo_log("CMDFIFO0\n");
|
||||
switch ((header >> 3) & 7) {
|
||||
case 0: /*NOP*/
|
||||
break;
|
||||
|
||||
case 1: /*JSR*/
|
||||
// voodoo_fifo_log("JSR %08x\n", (header >> 4) & 0xfffffc);
|
||||
voodoo->cmdfifo_ret_addr = voodoo->cmdfifo_rp;
|
||||
voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc;
|
||||
voodoo->cmdfifo_in_sub = 1;
|
||||
break;
|
||||
|
||||
case 2: /*RET*/
|
||||
voodoo->cmdfifo_rp = voodoo->cmdfifo_ret_addr;
|
||||
voodoo->cmdfifo_in_sub = 0;
|
||||
break;
|
||||
|
||||
case 3: /*JMP local frame buffer*/
|
||||
voodoo->cmdfifo_rp = (header >> 4) & 0xfffffc;
|
||||
// voodoo_fifo_log("JMP to %08x %04x\n", voodoo->cmdfifo_rp, header);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("Bad CMDFIFO0 %08x\n", header);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
num = header >> 16;
|
||||
addr = (header & 0x7ff8) >> 1;
|
||||
// voodoo_fifo_log("CMDFIFO1 addr=%08x\n",addr);
|
||||
while (num--) {
|
||||
uint32_t val = cmdfifo_get(voodoo);
|
||||
if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) {
|
||||
// if (voodoo->type != VOODOO_BANSHEE)
|
||||
// fatal("CMDFIFO1: Not Banshee\n");
|
||||
// voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val);
|
||||
voodoo_2d_reg_writel(voodoo, addr, val);
|
||||
} else {
|
||||
if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD)
|
||||
voodoo->cmd_written_fifo++;
|
||||
|
||||
if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD)
|
||||
voodoo->cmd_written_fifo++;
|
||||
voodoo_reg_writel(addr, val, voodoo);
|
||||
}
|
||||
|
||||
if (header & (1 << 15))
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (voodoo->type < VOODOO_BANSHEE)
|
||||
fatal("CMDFIFO2: Not Banshee\n");
|
||||
mask = (header >> 3);
|
||||
addr = 8;
|
||||
while (mask) {
|
||||
if (mask & 1) {
|
||||
uint32_t val = cmdfifo_get(voodoo);
|
||||
|
||||
voodoo_2d_reg_writel(voodoo, addr, val);
|
||||
}
|
||||
|
||||
addr += 4;
|
||||
mask >>= 1;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
num = (header >> 29) & 7;
|
||||
mask = header; //(header >> 10) & 0xff;
|
||||
smode = (header >> 22) & 0xf;
|
||||
voodoo_reg_writel(SST_sSetupMode, ((header >> 10) & 0xff) | (smode << 16), voodoo);
|
||||
num_verticies = (header >> 6) & 0xf;
|
||||
v_num = 0;
|
||||
if (((header >> 3) & 7) == 2)
|
||||
v_num = 1;
|
||||
// voodoo_fifo_log("CMDFIFO3: num=%i verts=%i mask=%02x\n", num, num_verticies, (header >> 10) & 0xff);
|
||||
// voodoo_fifo_log("CMDFIFO3 %02x %i\n", (header >> 10), (header >> 3) & 7);
|
||||
|
||||
while (num_verticies--) {
|
||||
voodoo->verts[3].sVx = cmdfifo_get_f(voodoo);
|
||||
voodoo->verts[3].sVy = cmdfifo_get_f(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_RGB) {
|
||||
if (header & CMDFIFO3_PC) {
|
||||
uint32_t val = cmdfifo_get(voodoo);
|
||||
voodoo->verts[3].sBlue = (float) (val & 0xff);
|
||||
voodoo->verts[3].sGreen = (float) ((val >> 8) & 0xff);
|
||||
voodoo->verts[3].sRed = (float) ((val >> 16) & 0xff);
|
||||
voodoo->verts[3].sAlpha = (float) ((val >> 24) & 0xff);
|
||||
} else {
|
||||
voodoo->verts[3].sRed = cmdfifo_get_f(voodoo);
|
||||
voodoo->verts[3].sGreen = cmdfifo_get_f(voodoo);
|
||||
voodoo->verts[3].sBlue = cmdfifo_get_f(voodoo);
|
||||
}
|
||||
}
|
||||
if ((mask & CMDFIFO3_PC_MASK_ALPHA) && !(header & CMDFIFO3_PC))
|
||||
voodoo->verts[3].sAlpha = cmdfifo_get_f(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_Z)
|
||||
voodoo->verts[3].sVz = cmdfifo_get_f(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_Wb)
|
||||
voodoo->verts[3].sWb = cmdfifo_get_f(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_W0)
|
||||
voodoo->verts[3].sW0 = cmdfifo_get_f(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_S0_T0) {
|
||||
voodoo->verts[3].sS0 = cmdfifo_get_f(voodoo);
|
||||
voodoo->verts[3].sT0 = cmdfifo_get_f(voodoo);
|
||||
}
|
||||
if (mask & CMDFIFO3_PC_MASK_W1)
|
||||
voodoo->verts[3].sW1 = cmdfifo_get_f(voodoo);
|
||||
if (mask & CMDFIFO3_PC_MASK_S1_T1) {
|
||||
voodoo->verts[3].sS1 = cmdfifo_get_f(voodoo);
|
||||
voodoo->verts[3].sT1 = cmdfifo_get_f(voodoo);
|
||||
}
|
||||
if (v_num)
|
||||
voodoo_reg_writel(SST_sDrawTriCMD, 0, voodoo);
|
||||
else
|
||||
voodoo_reg_writel(SST_sBeginTriCMD, 0, voodoo);
|
||||
v_num++;
|
||||
if (v_num == 3 && ((header >> 3) & 7) == 0)
|
||||
v_num = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
num = (header >> 29) & 7;
|
||||
mask = (header >> 15) & 0x3fff;
|
||||
addr = (header & 0x7ff8) >> 1;
|
||||
// voodoo_fifo_log("CMDFIFO4 addr=%08x\n",addr);
|
||||
while (mask) {
|
||||
if (mask & 1) {
|
||||
uint32_t val = cmdfifo_get(voodoo);
|
||||
|
||||
if ((addr & (1 << 13)) && voodoo->type >= VOODOO_BANSHEE) {
|
||||
if (voodoo->type < VOODOO_BANSHEE)
|
||||
fatal("CMDFIFO1: Not Banshee\n");
|
||||
// voodoo_fifo_log("CMDFIFO1: write %08x %08x\n", addr, val);
|
||||
voodoo_2d_reg_writel(voodoo, addr, val);
|
||||
} else {
|
||||
if ((addr & 0x3ff) == SST_triangleCMD || (addr & 0x3ff) == SST_ftriangleCMD || (addr & 0x3ff) == SST_fastfillCMD || (addr & 0x3ff) == SST_nopCMD)
|
||||
voodoo->cmd_written_fifo++;
|
||||
|
||||
if (voodoo->type >= VOODOO_BANSHEE && (addr & 0x3ff) == SST_swapbufferCMD)
|
||||
voodoo->cmd_written_fifo++;
|
||||
voodoo_reg_writel(addr, val, voodoo);
|
||||
}
|
||||
}
|
||||
|
||||
addr += 4;
|
||||
mask >>= 1;
|
||||
}
|
||||
while (num--)
|
||||
cmdfifo_get(voodoo);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// if (header & 0x3fc00000)
|
||||
// fatal("CMDFIFO packet 5 has byte disables set %08x\n", header);
|
||||
num = (header >> 3) & 0x7ffff;
|
||||
addr = cmdfifo_get(voodoo) & 0xffffff;
|
||||
if (!num)
|
||||
num = 1;
|
||||
// voodoo_fifo_log("CMDFIFO5 addr=%08x num=%i\n", addr, num);
|
||||
switch (header >> 30) {
|
||||
case 0: /*Linear framebuffer (Banshee)*/
|
||||
case 1: /*Planar YUV*/
|
||||
if (voodoo->texture_present[0][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) {
|
||||
// voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT);
|
||||
flush_texture_cache(voodoo, addr & voodoo->texture_mask, 0);
|
||||
}
|
||||
if (voodoo->texture_present[1][(addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT]) {
|
||||
// voodoo_fifo_log("texture_present at %08x %i\n", addr, (addr & voodoo->texture_mask) >> TEX_DIRTY_SHIFT);
|
||||
flush_texture_cache(voodoo, addr & voodoo->texture_mask, 1);
|
||||
}
|
||||
while (num--) {
|
||||
uint32_t val = cmdfifo_get(voodoo);
|
||||
if (addr <= voodoo->fb_mask)
|
||||
*(uint32_t *) &voodoo->fb_mem[addr] = val;
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
case 2: /*Framebuffer*/
|
||||
while (num--) {
|
||||
uint32_t val = cmdfifo_get(voodoo);
|
||||
voodoo_fb_writel(addr, val, voodoo);
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
case 3: /*Texture*/
|
||||
while (num--) {
|
||||
uint32_t val = cmdfifo_get(voodoo);
|
||||
voodoo_tex_writel(addr, val, voodoo);
|
||||
addr += 4;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("CMDFIFO packet 5 bad space %08x %08x\n", header, voodoo->cmdfifo_rp);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("Bad CMDFIFO packet %08x %08x\n", header, voodoo->cmdfifo_rp);
|
||||
}
|
||||
|
||||
end_time = plat_timer_read();
|
||||
voodoo->time += end_time - start_time;
|
||||
}
|
||||
voodoo->voodoo_busy = 0;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -46,216 +46,190 @@ voodoo_setup_log(const char *fmt, ...)
|
||||
va_list ap;
|
||||
|
||||
if (voodoo_setup_do_log) {
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
va_start(ap, fmt);
|
||||
pclog_ex(fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define voodoo_setup_log(fmt, ...)
|
||||
# define voodoo_setup_log(fmt, ...)
|
||||
#endif
|
||||
|
||||
|
||||
void voodoo_triangle_setup(voodoo_t *voodoo)
|
||||
void
|
||||
voodoo_triangle_setup(voodoo_t *voodoo)
|
||||
{
|
||||
float dxAB, dxBC, dyAB, dyBC;
|
||||
float area;
|
||||
int va = 0, vb = 1, vc = 2;
|
||||
vert_t verts[3];
|
||||
float dxAB, dxBC, dyAB, dyBC;
|
||||
float area;
|
||||
int va = 0, vb = 1, vc = 2;
|
||||
vert_t verts[3];
|
||||
|
||||
verts[0] = voodoo->verts[0];
|
||||
verts[1] = voodoo->verts[1];
|
||||
verts[2] = voodoo->verts[2];
|
||||
verts[0] = voodoo->verts[0];
|
||||
verts[1] = voodoo->verts[1];
|
||||
verts[2] = voodoo->verts[2];
|
||||
|
||||
if (verts[0].sVy < verts[1].sVy)
|
||||
{
|
||||
if (verts[1].sVy < verts[2].sVy)
|
||||
{
|
||||
/* V1>V0, V2>V1, V2>V1>V0*/
|
||||
va = 0; /*OK*/
|
||||
vb = 1;
|
||||
vc = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* V1>V0, V1>V2*/
|
||||
if (verts[0].sVy < verts[2].sVy)
|
||||
{
|
||||
/* V1>V0, V1>V2, V2>V0, V1>V2>V0*/
|
||||
va = 0;
|
||||
vb = 2;
|
||||
vc = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* V1>V0, V1>V2, V0>V2, V1>V0>V2*/
|
||||
va = 2;
|
||||
vb = 0;
|
||||
vc = 1;
|
||||
}
|
||||
}
|
||||
if (verts[0].sVy < verts[1].sVy) {
|
||||
if (verts[1].sVy < verts[2].sVy) {
|
||||
/* V1>V0, V2>V1, V2>V1>V0*/
|
||||
va = 0; /*OK*/
|
||||
vb = 1;
|
||||
vc = 2;
|
||||
} else {
|
||||
/* V1>V0, V1>V2*/
|
||||
if (verts[0].sVy < verts[2].sVy) {
|
||||
/* V1>V0, V1>V2, V2>V0, V1>V2>V0*/
|
||||
va = 0;
|
||||
vb = 2;
|
||||
vc = 1;
|
||||
} else {
|
||||
/* V1>V0, V1>V2, V0>V2, V1>V0>V2*/
|
||||
va = 2;
|
||||
vb = 0;
|
||||
vc = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (verts[1].sVy < verts[2].sVy)
|
||||
{
|
||||
/* V0>V1, V2>V1*/
|
||||
if (verts[0].sVy < verts[2].sVy)
|
||||
{
|
||||
/* V0>V1, V2>V1, V2>V0, V2>V0>V1*/
|
||||
va = 1;
|
||||
vb = 0;
|
||||
vc = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* V0>V1, V2>V1, V0>V2, V0>V2>V1*/
|
||||
va = 1;
|
||||
vb = 2;
|
||||
vc = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*V0>V1>V2*/
|
||||
va = 2;
|
||||
vb = 1;
|
||||
vc = 0;
|
||||
}
|
||||
} else {
|
||||
if (verts[1].sVy < verts[2].sVy) {
|
||||
/* V0>V1, V2>V1*/
|
||||
if (verts[0].sVy < verts[2].sVy) {
|
||||
/* V0>V1, V2>V1, V2>V0, V2>V0>V1*/
|
||||
va = 1;
|
||||
vb = 0;
|
||||
vc = 2;
|
||||
} else {
|
||||
/* V0>V1, V2>V1, V0>V2, V0>V2>V1*/
|
||||
va = 1;
|
||||
vb = 2;
|
||||
vc = 0;
|
||||
}
|
||||
} else {
|
||||
/*V0>V1>V2*/
|
||||
va = 2;
|
||||
vb = 1;
|
||||
vc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
dxAB = verts[0].sVx - verts[1].sVx;
|
||||
dxBC = verts[1].sVx - verts[2].sVx;
|
||||
dyAB = verts[0].sVy - verts[1].sVy;
|
||||
dyBC = verts[1].sVy - verts[2].sVy;
|
||||
dxAB = verts[0].sVx - verts[1].sVx;
|
||||
dxBC = verts[1].sVx - verts[2].sVx;
|
||||
dyAB = verts[0].sVy - verts[1].sVy;
|
||||
dyBC = verts[1].sVy - verts[2].sVy;
|
||||
|
||||
area = dxAB * dyBC - dxBC * dyAB;
|
||||
area = dxAB * dyBC - dxBC * dyAB;
|
||||
|
||||
if (area == 0.0)
|
||||
return;
|
||||
if (area == 0.0)
|
||||
return;
|
||||
|
||||
if (voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE)
|
||||
{
|
||||
int cull_sign = voodoo->sSetupMode & SETUPMODE_CULLING_SIGN;
|
||||
int sign = (area < 0.0);
|
||||
if (voodoo->sSetupMode & SETUPMODE_CULLING_ENABLE) {
|
||||
int cull_sign = voodoo->sSetupMode & SETUPMODE_CULLING_SIGN;
|
||||
int sign = (area < 0.0);
|
||||
|
||||
if ((voodoo->sSetupMode & (SETUPMODE_CULLING_ENABLE | SETUPMODE_DISABLE_PINGPONG))
|
||||
== SETUPMODE_CULLING_ENABLE && voodoo->cull_pingpong)
|
||||
cull_sign = !cull_sign;
|
||||
if ((voodoo->sSetupMode & (SETUPMODE_CULLING_ENABLE | SETUPMODE_DISABLE_PINGPONG))
|
||||
== SETUPMODE_CULLING_ENABLE
|
||||
&& voodoo->cull_pingpong)
|
||||
cull_sign = !cull_sign;
|
||||
|
||||
if (cull_sign && sign)
|
||||
return;
|
||||
if (!cull_sign && !sign)
|
||||
return;
|
||||
}
|
||||
if (cull_sign && sign)
|
||||
return;
|
||||
if (!cull_sign && !sign)
|
||||
return;
|
||||
}
|
||||
|
||||
dxAB = verts[va].sVx - verts[vb].sVx;
|
||||
dxBC = verts[vb].sVx - verts[vc].sVx;
|
||||
dyAB = verts[va].sVy - verts[vb].sVy;
|
||||
dyBC = verts[vb].sVy - verts[vc].sVy;
|
||||
|
||||
dxAB = verts[va].sVx - verts[vb].sVx;
|
||||
dxBC = verts[vb].sVx - verts[vc].sVx;
|
||||
dyAB = verts[va].sVy - verts[vb].sVy;
|
||||
dyBC = verts[vb].sVy - verts[vc].sVy;
|
||||
area = dxAB * dyBC - dxBC * dyAB;
|
||||
|
||||
area = dxAB * dyBC - dxBC * dyAB;
|
||||
dxAB /= area;
|
||||
dxBC /= area;
|
||||
dyAB /= area;
|
||||
dyBC /= area;
|
||||
|
||||
dxAB /= area;
|
||||
dxBC /= area;
|
||||
dyAB /= area;
|
||||
dyBC /= area;
|
||||
voodoo->params.vertexAx = (int32_t) (int16_t) ((int32_t) (verts[va].sVx * 16.0f) & 0xffff);
|
||||
voodoo->params.vertexAy = (int32_t) (int16_t) ((int32_t) (verts[va].sVy * 16.0f) & 0xffff);
|
||||
voodoo->params.vertexBx = (int32_t) (int16_t) ((int32_t) (verts[vb].sVx * 16.0f) & 0xffff);
|
||||
voodoo->params.vertexBy = (int32_t) (int16_t) ((int32_t) (verts[vb].sVy * 16.0f) & 0xffff);
|
||||
voodoo->params.vertexCx = (int32_t) (int16_t) ((int32_t) (verts[vc].sVx * 16.0f) & 0xffff);
|
||||
voodoo->params.vertexCy = (int32_t) (int16_t) ((int32_t) (verts[vc].sVy * 16.0f) & 0xffff);
|
||||
|
||||
if (voodoo->params.vertexAy > voodoo->params.vertexBy || voodoo->params.vertexBy > voodoo->params.vertexCy) {
|
||||
voodoo_setup_log("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, voodoo->params.vertexCy);
|
||||
return;
|
||||
}
|
||||
|
||||
if (voodoo->sSetupMode & SETUPMODE_RGB) {
|
||||
voodoo->params.startR = (int32_t) (verts[va].sRed * 4096.0f);
|
||||
voodoo->params.dRdX = (int32_t) (((verts[va].sRed - verts[vb].sRed) * dyBC - (verts[vb].sRed - verts[vc].sRed) * dyAB) * 4096.0f);
|
||||
voodoo->params.dRdY = (int32_t) (((verts[vb].sRed - verts[vc].sRed) * dxAB - (verts[va].sRed - verts[vb].sRed) * dxBC) * 4096.0f);
|
||||
voodoo->params.startG = (int32_t) (verts[va].sGreen * 4096.0f);
|
||||
voodoo->params.dGdX = (int32_t) (((verts[va].sGreen - verts[vb].sGreen) * dyBC - (verts[vb].sGreen - verts[vc].sGreen) * dyAB) * 4096.0f);
|
||||
voodoo->params.dGdY = (int32_t) (((verts[vb].sGreen - verts[vc].sGreen) * dxAB - (verts[va].sGreen - verts[vb].sGreen) * dxBC) * 4096.0f);
|
||||
voodoo->params.startB = (int32_t) (verts[va].sBlue * 4096.0f);
|
||||
voodoo->params.dBdX = (int32_t) (((verts[va].sBlue - verts[vb].sBlue) * dyBC - (verts[vb].sBlue - verts[vc].sBlue) * dyAB) * 4096.0f);
|
||||
voodoo->params.dBdY = (int32_t) (((verts[vb].sBlue - verts[vc].sBlue) * dxAB - (verts[va].sBlue - verts[vb].sBlue) * dxBC) * 4096.0f);
|
||||
}
|
||||
if (voodoo->sSetupMode & SETUPMODE_ALPHA) {
|
||||
voodoo->params.startA = (int32_t) (verts[va].sAlpha * 4096.0f);
|
||||
voodoo->params.dAdX = (int32_t) (((verts[va].sAlpha - verts[vb].sAlpha) * dyBC - (verts[vb].sAlpha - verts[vc].sAlpha) * dyAB) * 4096.0f);
|
||||
voodoo->params.dAdY = (int32_t) (((verts[vb].sAlpha - verts[vc].sAlpha) * dxAB - (verts[va].sAlpha - verts[vb].sAlpha) * dxBC) * 4096.0f);
|
||||
}
|
||||
if (voodoo->sSetupMode & SETUPMODE_Z) {
|
||||
voodoo->params.startZ = (int32_t) (verts[va].sVz * 4096.0f);
|
||||
voodoo->params.dZdX = (int32_t) (((verts[va].sVz - verts[vb].sVz) * dyBC - (verts[vb].sVz - verts[vc].sVz) * dyAB) * 4096.0f);
|
||||
voodoo->params.dZdY = (int32_t) (((verts[vb].sVz - verts[vc].sVz) * dxAB - (verts[va].sVz - verts[vb].sVz) * dxBC) * 4096.0f);
|
||||
}
|
||||
if (voodoo->sSetupMode & SETUPMODE_Wb) {
|
||||
voodoo->params.startW = (int64_t) (verts[va].sWb * 4294967296.0f);
|
||||
voodoo->params.dWdX = (int64_t) (((verts[va].sWb - verts[vb].sWb) * dyBC - (verts[vb].sWb - verts[vc].sWb) * dyAB) * 4294967296.0f);
|
||||
voodoo->params.dWdY = (int64_t) (((verts[vb].sWb - verts[vc].sWb) * dxAB - (verts[va].sWb - verts[vb].sWb) * dxBC) * 4294967296.0f);
|
||||
voodoo->params.tmu[0].startW = voodoo->params.tmu[1].startW = voodoo->params.startW;
|
||||
voodoo->params.tmu[0].dWdX = voodoo->params.tmu[1].dWdX = voodoo->params.dWdX;
|
||||
voodoo->params.tmu[0].dWdY = voodoo->params.tmu[1].dWdY = voodoo->params.dWdY;
|
||||
}
|
||||
if (voodoo->sSetupMode & SETUPMODE_W0) {
|
||||
voodoo->params.tmu[0].startW = (int64_t) (verts[va].sW0 * 4294967296.0f);
|
||||
voodoo->params.tmu[0].dWdX = (int64_t) (((verts[va].sW0 - verts[vb].sW0) * dyBC - (verts[vb].sW0 - verts[vc].sW0) * dyAB) * 4294967296.0f);
|
||||
voodoo->params.tmu[0].dWdY = (int64_t) (((verts[vb].sW0 - verts[vc].sW0) * dxAB - (verts[va].sW0 - verts[vb].sW0) * dxBC) * 4294967296.0f);
|
||||
voodoo->params.tmu[1].startW = voodoo->params.tmu[0].startW;
|
||||
voodoo->params.tmu[1].dWdX = voodoo->params.tmu[0].dWdX;
|
||||
voodoo->params.tmu[1].dWdY = voodoo->params.tmu[0].dWdY;
|
||||
}
|
||||
if (voodoo->sSetupMode & SETUPMODE_S0_T0) {
|
||||
voodoo->params.tmu[0].startS = (int64_t) (verts[va].sS0 * 4294967296.0f);
|
||||
voodoo->params.tmu[0].dSdX = (int64_t) (((verts[va].sS0 - verts[vb].sS0) * dyBC - (verts[vb].sS0 - verts[vc].sS0) * dyAB) * 4294967296.0f);
|
||||
voodoo->params.tmu[0].dSdY = (int64_t) (((verts[vb].sS0 - verts[vc].sS0) * dxAB - (verts[va].sS0 - verts[vb].sS0) * dxBC) * 4294967296.0f);
|
||||
voodoo->params.tmu[0].startT = (int64_t) (verts[va].sT0 * 4294967296.0f);
|
||||
voodoo->params.tmu[0].dTdX = (int64_t) (((verts[va].sT0 - verts[vb].sT0) * dyBC - (verts[vb].sT0 - verts[vc].sT0) * dyAB) * 4294967296.0f);
|
||||
voodoo->params.tmu[0].dTdY = (int64_t) (((verts[vb].sT0 - verts[vc].sT0) * dxAB - (verts[va].sT0 - verts[vb].sT0) * dxBC) * 4294967296.0f);
|
||||
voodoo->params.tmu[1].startS = voodoo->params.tmu[0].startS;
|
||||
voodoo->params.tmu[1].dSdX = voodoo->params.tmu[0].dSdX;
|
||||
voodoo->params.tmu[1].dSdY = voodoo->params.tmu[0].dSdY;
|
||||
voodoo->params.tmu[1].startT = voodoo->params.tmu[0].startT;
|
||||
voodoo->params.tmu[1].dTdX = voodoo->params.tmu[0].dTdX;
|
||||
voodoo->params.tmu[1].dTdY = voodoo->params.tmu[0].dTdY;
|
||||
}
|
||||
if (voodoo->sSetupMode & SETUPMODE_W1) {
|
||||
voodoo->params.tmu[1].startW = (int64_t) (verts[va].sW1 * 4294967296.0f);
|
||||
voodoo->params.tmu[1].dWdX = (int64_t) (((verts[va].sW1 - verts[vb].sW1) * dyBC - (verts[vb].sW1 - verts[vc].sW1) * dyAB) * 4294967296.0f);
|
||||
voodoo->params.tmu[1].dWdY = (int64_t) (((verts[vb].sW1 - verts[vc].sW1) * dxAB - (verts[va].sW1 - verts[vb].sW1) * dxBC) * 4294967296.0f);
|
||||
}
|
||||
if (voodoo->sSetupMode & SETUPMODE_S1_T1) {
|
||||
voodoo->params.tmu[1].startS = (int64_t) (verts[va].sS1 * 4294967296.0f);
|
||||
voodoo->params.tmu[1].dSdX = (int64_t) (((verts[va].sS1 - verts[vb].sS1) * dyBC - (verts[vb].sS1 - verts[vc].sS1) * dyAB) * 4294967296.0f);
|
||||
voodoo->params.tmu[1].dSdY = (int64_t) (((verts[vb].sS1 - verts[vc].sS1) * dxAB - (verts[va].sS1 - verts[vb].sS1) * dxBC) * 4294967296.0f);
|
||||
voodoo->params.tmu[1].startT = (int64_t) (verts[va].sT1 * 4294967296.0f);
|
||||
voodoo->params.tmu[1].dTdX = (int64_t) (((verts[va].sT1 - verts[vb].sT1) * dyBC - (verts[vb].sT1 - verts[vc].sT1) * dyAB) * 4294967296.0f);
|
||||
voodoo->params.tmu[1].dTdY = (int64_t) (((verts[vb].sT1 - verts[vc].sT1) * dxAB - (verts[va].sT1 - verts[vb].sT1) * dxBC) * 4294967296.0f);
|
||||
}
|
||||
|
||||
voodoo->params.vertexAx = (int32_t)(int16_t)((int32_t)(verts[va].sVx * 16.0f) & 0xffff);
|
||||
voodoo->params.vertexAy = (int32_t)(int16_t)((int32_t)(verts[va].sVy * 16.0f) & 0xffff);
|
||||
voodoo->params.vertexBx = (int32_t)(int16_t)((int32_t)(verts[vb].sVx * 16.0f) & 0xffff);
|
||||
voodoo->params.vertexBy = (int32_t)(int16_t)((int32_t)(verts[vb].sVy * 16.0f) & 0xffff);
|
||||
voodoo->params.vertexCx = (int32_t)(int16_t)((int32_t)(verts[vc].sVx * 16.0f) & 0xffff);
|
||||
voodoo->params.vertexCy = (int32_t)(int16_t)((int32_t)(verts[vc].sVy * 16.0f) & 0xffff);
|
||||
voodoo->params.sign = (area < 0.0);
|
||||
|
||||
if (voodoo->params.vertexAy > voodoo->params.vertexBy || voodoo->params.vertexBy > voodoo->params.vertexCy) {
|
||||
voodoo_setup_log("triangle_setup wrong order %d %d %d\n", voodoo->params.vertexAy, voodoo->params.vertexBy, voodoo->params.vertexCy);
|
||||
return;
|
||||
}
|
||||
if (voodoo->ncc_dirty[0])
|
||||
voodoo_update_ncc(voodoo, 0);
|
||||
if (voodoo->ncc_dirty[1])
|
||||
voodoo_update_ncc(voodoo, 1);
|
||||
voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0;
|
||||
|
||||
if (voodoo->sSetupMode & SETUPMODE_RGB)
|
||||
{
|
||||
voodoo->params.startR = (int32_t)(verts[va].sRed * 4096.0f);
|
||||
voodoo->params.dRdX = (int32_t)(((verts[va].sRed - verts[vb].sRed) * dyBC - (verts[vb].sRed - verts[vc].sRed) * dyAB) * 4096.0f);
|
||||
voodoo->params.dRdY = (int32_t)(((verts[vb].sRed - verts[vc].sRed) * dxAB - (verts[va].sRed - verts[vb].sRed) * dxBC) * 4096.0f);
|
||||
voodoo->params.startG = (int32_t)(verts[va].sGreen * 4096.0f);
|
||||
voodoo->params.dGdX = (int32_t)(((verts[va].sGreen - verts[vb].sGreen) * dyBC - (verts[vb].sGreen - verts[vc].sGreen) * dyAB) * 4096.0f);
|
||||
voodoo->params.dGdY = (int32_t)(((verts[vb].sGreen - verts[vc].sGreen) * dxAB - (verts[va].sGreen - verts[vb].sGreen) * dxBC) * 4096.0f);
|
||||
voodoo->params.startB = (int32_t)(verts[va].sBlue * 4096.0f);
|
||||
voodoo->params.dBdX = (int32_t)(((verts[va].sBlue - verts[vb].sBlue) * dyBC - (verts[vb].sBlue - verts[vc].sBlue) * dyAB) * 4096.0f);
|
||||
voodoo->params.dBdY = (int32_t)(((verts[vb].sBlue - verts[vc].sBlue) * dxAB - (verts[va].sBlue - verts[vb].sBlue) * dxBC) * 4096.0f);
|
||||
}
|
||||
if (voodoo->sSetupMode & SETUPMODE_ALPHA)
|
||||
{
|
||||
voodoo->params.startA = (int32_t)(verts[va].sAlpha * 4096.0f);
|
||||
voodoo->params.dAdX = (int32_t)(((verts[va].sAlpha - verts[vb].sAlpha) * dyBC - (verts[vb].sAlpha - verts[vc].sAlpha) * dyAB) * 4096.0f);
|
||||
voodoo->params.dAdY = (int32_t)(((verts[vb].sAlpha - verts[vc].sAlpha) * dxAB - (verts[va].sAlpha - verts[vb].sAlpha) * dxBC) * 4096.0f);
|
||||
}
|
||||
if (voodoo->sSetupMode & SETUPMODE_Z)
|
||||
{
|
||||
voodoo->params.startZ = (int32_t)(verts[va].sVz * 4096.0f);
|
||||
voodoo->params.dZdX = (int32_t)(((verts[va].sVz - verts[vb].sVz) * dyBC - (verts[vb].sVz - verts[vc].sVz) * dyAB) * 4096.0f);
|
||||
voodoo->params.dZdY = (int32_t)(((verts[vb].sVz - verts[vc].sVz) * dxAB - (verts[va].sVz - verts[vb].sVz) * dxBC) * 4096.0f);
|
||||
}
|
||||
if (voodoo->sSetupMode & SETUPMODE_Wb)
|
||||
{
|
||||
voodoo->params.startW = (int64_t)(verts[va].sWb * 4294967296.0f);
|
||||
voodoo->params.dWdX = (int64_t)(((verts[va].sWb - verts[vb].sWb) * dyBC - (verts[vb].sWb - verts[vc].sWb) * dyAB) * 4294967296.0f);
|
||||
voodoo->params.dWdY = (int64_t)(((verts[vb].sWb - verts[vc].sWb) * dxAB - (verts[va].sWb - verts[vb].sWb) * dxBC) * 4294967296.0f);
|
||||
voodoo->params.tmu[0].startW = voodoo->params.tmu[1].startW = voodoo->params.startW;
|
||||
voodoo->params.tmu[0].dWdX = voodoo->params.tmu[1].dWdX = voodoo->params.dWdX;
|
||||
voodoo->params.tmu[0].dWdY = voodoo->params.tmu[1].dWdY = voodoo->params.dWdY;
|
||||
}
|
||||
if (voodoo->sSetupMode & SETUPMODE_W0)
|
||||
{
|
||||
voodoo->params.tmu[0].startW = (int64_t)(verts[va].sW0 * 4294967296.0f);
|
||||
voodoo->params.tmu[0].dWdX = (int64_t)(((verts[va].sW0 - verts[vb].sW0) * dyBC - (verts[vb].sW0 - verts[vc].sW0) * dyAB) * 4294967296.0f);
|
||||
voodoo->params.tmu[0].dWdY = (int64_t)(((verts[vb].sW0 - verts[vc].sW0) * dxAB - (verts[va].sW0 - verts[vb].sW0) * dxBC) * 4294967296.0f);
|
||||
voodoo->params.tmu[1].startW = voodoo->params.tmu[0].startW;
|
||||
voodoo->params.tmu[1].dWdX = voodoo->params.tmu[0].dWdX;
|
||||
voodoo->params.tmu[1].dWdY = voodoo->params.tmu[0].dWdY;
|
||||
}
|
||||
if (voodoo->sSetupMode & SETUPMODE_S0_T0)
|
||||
{
|
||||
voodoo->params.tmu[0].startS = (int64_t)(verts[va].sS0 * 4294967296.0f);
|
||||
voodoo->params.tmu[0].dSdX = (int64_t)(((verts[va].sS0 - verts[vb].sS0) * dyBC - (verts[vb].sS0 - verts[vc].sS0) * dyAB) * 4294967296.0f);
|
||||
voodoo->params.tmu[0].dSdY = (int64_t)(((verts[vb].sS0 - verts[vc].sS0) * dxAB - (verts[va].sS0 - verts[vb].sS0) * dxBC) * 4294967296.0f);
|
||||
voodoo->params.tmu[0].startT = (int64_t)(verts[va].sT0 * 4294967296.0f);
|
||||
voodoo->params.tmu[0].dTdX = (int64_t)(((verts[va].sT0 - verts[vb].sT0) * dyBC - (verts[vb].sT0 - verts[vc].sT0) * dyAB) * 4294967296.0f);
|
||||
voodoo->params.tmu[0].dTdY = (int64_t)(((verts[vb].sT0 - verts[vc].sT0) * dxAB - (verts[va].sT0 - verts[vb].sT0) * dxBC) * 4294967296.0f);
|
||||
voodoo->params.tmu[1].startS = voodoo->params.tmu[0].startS;
|
||||
voodoo->params.tmu[1].dSdX = voodoo->params.tmu[0].dSdX;
|
||||
voodoo->params.tmu[1].dSdY = voodoo->params.tmu[0].dSdY;
|
||||
voodoo->params.tmu[1].startT = voodoo->params.tmu[0].startT;
|
||||
voodoo->params.tmu[1].dTdX = voodoo->params.tmu[0].dTdX;
|
||||
voodoo->params.tmu[1].dTdY = voodoo->params.tmu[0].dTdY;
|
||||
}
|
||||
if (voodoo->sSetupMode & SETUPMODE_W1)
|
||||
{
|
||||
voodoo->params.tmu[1].startW = (int64_t)(verts[va].sW1 * 4294967296.0f);
|
||||
voodoo->params.tmu[1].dWdX = (int64_t)(((verts[va].sW1 - verts[vb].sW1) * dyBC - (verts[vb].sW1 - verts[vc].sW1) * dyAB) * 4294967296.0f);
|
||||
voodoo->params.tmu[1].dWdY = (int64_t)(((verts[vb].sW1 - verts[vc].sW1) * dxAB - (verts[va].sW1 - verts[vb].sW1) * dxBC) * 4294967296.0f);
|
||||
}
|
||||
if (voodoo->sSetupMode & SETUPMODE_S1_T1)
|
||||
{
|
||||
voodoo->params.tmu[1].startS = (int64_t)(verts[va].sS1 * 4294967296.0f);
|
||||
voodoo->params.tmu[1].dSdX = (int64_t)(((verts[va].sS1 - verts[vb].sS1) * dyBC - (verts[vb].sS1 - verts[vc].sS1) * dyAB) * 4294967296.0f);
|
||||
voodoo->params.tmu[1].dSdY = (int64_t)(((verts[vb].sS1 - verts[vc].sS1) * dxAB - (verts[va].sS1 - verts[vb].sS1) * dxBC) * 4294967296.0f);
|
||||
voodoo->params.tmu[1].startT = (int64_t)(verts[va].sT1 * 4294967296.0f);
|
||||
voodoo->params.tmu[1].dTdX = (int64_t)(((verts[va].sT1 - verts[vb].sT1) * dyBC - (verts[vb].sT1 - verts[vc].sT1) * dyAB) * 4294967296.0f);
|
||||
voodoo->params.tmu[1].dTdY = (int64_t)(((verts[vb].sT1 - verts[vc].sT1) * dxAB - (verts[va].sT1 - verts[vb].sT1) * dxBC) * 4294967296.0f);
|
||||
}
|
||||
|
||||
voodoo->params.sign = (area < 0.0);
|
||||
|
||||
if (voodoo->ncc_dirty[0])
|
||||
voodoo_update_ncc(voodoo, 0);
|
||||
if (voodoo->ncc_dirty[1])
|
||||
voodoo_update_ncc(voodoo, 1);
|
||||
voodoo->ncc_dirty[0] = voodoo->ncc_dirty[1] = 0;
|
||||
|
||||
voodoo_queue_triangle(voodoo, &voodoo->params);
|
||||
voodoo_queue_triangle(voodoo, &voodoo->params);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1071
src/video/vid_xga.c
1071
src/video/vid_xga.c
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user