From c528ebc2f1ad023c7912c5c260df15da12d7b5e1 Mon Sep 17 00:00:00 2001 From: sorgelig Date: Sun, 19 Jul 2020 06:04:36 +0800 Subject: [PATCH] ao486: variable CPU clock, 256MB RAM. --- support/x86/x86.cpp | 107 +++++++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 47 deletions(-) diff --git a/support/x86/x86.cpp b/support/x86/x86.cpp index 7bc00b6..8baaf18 100644 --- a/support/x86/x86.cpp +++ b/support/x86/x86.cpp @@ -37,8 +37,7 @@ #include "../../user_io.h" #include "../../file_io.h" #include "../../fpga_io.h" - -uint32_t cpu_clock; +#include "x86_share.h" #define FLOPPY0_BASE 0x8800 #define HDD0_BASE 0x8840 @@ -67,6 +66,7 @@ typedef struct static x86_config config; +static uint32_t old_cpu_clock = 0; static uint32_t cpu_get_clock() { uint32_t clock; @@ -77,7 +77,7 @@ static uint32_t cpu_get_clock() clock = (spi_w(0) << 16) | clock; DisableIO(); - return clock ? clock : 90000000; + return clock ? clock : 90500000; } static uint8_t dma_sdio(int status) @@ -254,6 +254,56 @@ static void cmos_set(uint addr, uint8_t val) } */ +static int floppy_wait_cycles; + +static void set_clock() +{ + uint32_t cpu_clock = cpu_get_clock(); + old_cpu_clock = cpu_clock; + + IOWR(FLOPPY0_BASE, 0x7, (int)(floppy_wait_cycles / (1000000000.0 / cpu_clock))); + IOWR(FLOPPY0_BASE, 0x8, (int)(1000000.0 / (1000000000.0 / cpu_clock))); + IOWR(FLOPPY0_BASE, 0x9, (int)(1666666.0 / (1000000000.0 / cpu_clock))); + IOWR(FLOPPY0_BASE, 0xA, (int)(2000000.0 / (1000000000.0 / cpu_clock))); + IOWR(FLOPPY0_BASE, 0xB, (int)(500000.0 / (1000000000.0 / cpu_clock))); + + IOWR(VGA_BASE, 0, cpu_clock); + + //-------------------------------------------------------------------------- sound + /* + 0-255.[15:0]: cycles in period + 256.[12:0]: cycles in 80us + 257.[9:0]: cycles in 1 sample: 96000 Hz + */ + + double cycle_in_ns = (1000000000.0 / cpu_clock); //33.333333; + for (int i = 0; i < 256; i++) + { + double f = 1000000.0 / (256.0 - i); + + double cycles_in_period = 1000000000.0 / (f * cycle_in_ns); + IOWR(SOUND_BASE, i, (int)cycles_in_period); + } + + IOWR(SOUND_BASE, 256, (int)(80000.0 / (1000000000.0 / cpu_clock))); + IOWR(SOUND_BASE, 257, (int)((1000000000.0 / 96000.0) / (1000000000.0 / cpu_clock))); + + //-------------------------------------------------------------------------- pit + /* + 0.[7:0]: cycles in sysclock 1193181 Hz + */ + + IOWR(PIT_BASE, 0, (int)((1000000000.0 / 1193181.0) / (1000000000.0 / cpu_clock))); + + /* + 128.[26:0]: cycles in second + 129.[12:0]: cycles in 122.07031 us + */ + + IOWR(RTC_BASE, 128, (int)(1000000000.0 / (1000000000.0 / cpu_clock))); + IOWR(RTC_BASE, 129, (int)(122070.0 / (1000000000.0 / cpu_clock))); +} + static int fdd_set(char* filename) { floppy_is_160k = false; @@ -317,7 +367,7 @@ static int fdd_set(char* filename) int floppy_cylinders = (floppy_is_2_88m || floppy_is_1_68m || floppy_is_1_44m || floppy_is_1_2m || floppy_is_720k) ? 80 : 40; int floppy_heads = (floppy_is_160k || floppy_is_180k) ? 1 : 2; int floppy_total_sectors = floppy_spt * floppy_heads * floppy_cylinders; - int floppy_wait_cycles = 200000000 / floppy_spt; + floppy_wait_cycles = 200000000 / floppy_spt; int floppy_media = (!floppy) ? 0x20 : @@ -338,13 +388,10 @@ static int fdd_set(char* filename) IOWR(FLOPPY0_BASE, 0x4, floppy_total_sectors); IOWR(FLOPPY0_BASE, 0x5, floppy_heads); IOWR(FLOPPY0_BASE, 0x6, 0); // base LBA - IOWR(FLOPPY0_BASE, 0x7, (int)(floppy_wait_cycles / (1000000000.0 / cpu_clock))); - IOWR(FLOPPY0_BASE, 0x8, (int)(1000000.0 / (1000000000.0 / cpu_clock))); - IOWR(FLOPPY0_BASE, 0x9, (int)(1666666.0 / (1000000000.0 / cpu_clock))); - IOWR(FLOPPY0_BASE, 0xA, (int)(2000000.0 / (1000000000.0 / cpu_clock))); - IOWR(FLOPPY0_BASE, 0xB, (int)(500000.0 / (1000000000.0 / cpu_clock))); IOWR(FLOPPY0_BASE, 0xC, floppy_media); + set_clock(); + //cmos_set(0x10, CMOS_FDD_TYPE); return floppy; } @@ -521,9 +568,6 @@ void x86_init() { user_io_8bit_set_status(UIO_STATUS_RESET, UIO_STATUS_RESET); - cpu_clock = cpu_get_clock(); - IOWR(VGA_BASE, 0, cpu_clock); - const char *home = HomeDir(); load_bios(user_io_make_filepath(home, "boot0.rom"), 0); @@ -532,32 +576,6 @@ void x86_init() IOWR(PC_BUS_BASE, 0, 0x00FFF0EA); IOWR(PC_BUS_BASE, 1, 0x000000F0); - //-------------------------------------------------------------------------- sound - /* - 0-255.[15:0]: cycles in period - 256.[12:0]: cycles in 80us - 257.[9:0]: cycles in 1 sample: 96000 Hz - */ - - double cycle_in_ns = (1000000000.0 / cpu_clock); //33.333333; - for(int i=0; i<256; i++) - { - double f = 1000000.0 / (256.0-i); - - double cycles_in_period = 1000000000.0 / (f * cycle_in_ns); - IOWR(SOUND_BASE, i, (int)cycles_in_period); - } - - IOWR(SOUND_BASE, 256, (int)(80000.0 / (1000000000.0 / cpu_clock))); - IOWR(SOUND_BASE, 257, (int)((1000000000.0/96000.0) / (1000000000.0 / cpu_clock))); - - //-------------------------------------------------------------------------- pit - /* - 0.[7:0]: cycles in sysclock 1193181 Hz - */ - - IOWR(PIT_BASE, 0, (int)((1000000000.0/1193181.0) / (1000000000.0 / cpu_clock))); - //-------------------------------------------------------------------------- floppy fdd_set(config.fdd_name); @@ -569,14 +587,6 @@ void x86_init() //-------------------------------------------------------------------------- rtc - /* - 128.[26:0]: cycles in second - 129.[12:0]: cycles in 122.07031 us - */ - - IOWR(RTC_BASE, 128, (int)(1000000000.0 / (1000000000.0 / cpu_clock))); - IOWR(RTC_BASE, 129, (int)(122070.0 / (1000000000.0 / cpu_clock))); - unsigned char translate_mode = 1; //LBA translate_mode = (translate_mode << 6) | (translate_mode << 4) | (translate_mode << 2) | translate_mode; @@ -646,7 +656,7 @@ void x86_init() 0x00, //0x33: ? 0x00, //0x34: memory size above 16m in 64k LSB - 0x07, //0x35: memory size above 16m in 64k MSB; 128 MB + 0x0F, //0x35: memory size above 16m in 64k MSB; 256 MB 0x00, //0x36: ? 0x20, //0x37: IBM PS/2 century @@ -697,6 +707,9 @@ void x86_poll() int res = 0; static uint32_t secbuf[128 * 4]; + uint32_t cpu_clock = cpu_get_clock(); + if (cpu_clock != old_cpu_clock) set_clock(); + char sd_req = dma_sdio(0); if (sd_req == 1) {