Skip to content

Commit

Permalink
Merge pull request #12 from DnCraptor/master
Browse files Browse the repository at this point in the history
Recover pico-build after merged
  • Loading branch information
xrip authored Nov 27, 2023
2 parents 3ff4eb0 + 404d6e5 commit b9ca56e
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 76 deletions.
7 changes: 4 additions & 3 deletions src/a20.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,8 @@ uint8_t set_a20(bool i) {
}

void i15_87h(uint16_t words_to_move, uint32_t gdt_far) {
uint8_t prev_a20_enable = set_a20(1); // enable A20 line if not
bool prev_a20_enable = is_a20_enabled; // enable A20 line if not
is_a20_enabled = true;
uint16_t source_segment_szb = readw86(gdt_far + 0x10); // (2*CX-1) or grater
uint32_t linear_source_addr24 = read86(gdt_far + 0x14);; // 24 bit addrss of source
linear_source_addr24 = (linear_source_addr24 << 8) + read86(gdt_far + 0x13);
Expand All @@ -157,10 +158,10 @@ void i15_87h(uint16_t words_to_move, uint32_t gdt_far) {
uint16_t d = readw86(linear_source_addr24 + offset);
writew86(linear_dest_addr24 + offset, d);
}
set_a20(prev_a20_enable); // restore prev. A20 line state
is_a20_enabled = prev_a20_enable; // restore prev. A20 line state
}

void i15_89h(uint8_t IDT1, uint8_t IDT2, uint32_t gdt_far) {
set_a20(1);
is_a20_enabled = true;
// TODO: CPU_CR0
}
183 changes: 122 additions & 61 deletions src/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,107 +108,146 @@ void modregrm() {

__inline void write86(uint32_t addr32, uint8_t value) {
#if PICO_ON_DEVICE
if ((PSRAM_AVAILABLE && (addr32) < (RAM_SIZE << 10)) || addr32 < RAM_PAGE_SIZE) {
if ((PSRAM_AVAILABLE && (addr32) < (RAM_SIZE << 10)) || addr32 < RAM_PAGE_SIZE) { // Conventional in RAM size or first block
// do not touch first page
RAM[addr32] = value;
return;
}
if (addr32 >= 0xB8000UL && addr32 < 0xC8000UL) {
#else
if (addr32 < (RAM_SIZE << 10)) {
RAM[addr32] = value;
return;
}
#endif
if (((addr32) >= 0xB8000UL) && ((addr32) < 0xC0000UL)) {
// video RAM range
VRAM[addr32-0xB8000UL] = value;
return;
}
if ((addr32 >> 4) >= PHYSICAL_EMM_SEGMENT && (addr32 >> 4) < PHYSICAL_EMM_SEGMENT_END) {
if (PSRAM_AVAILABLE && (addr32 >> 4) >= PHYSICAL_EMM_SEGMENT && (addr32 >> 4) < PHYSICAL_EMM_SEGMENT_END) { // EMS
uint32_t lba = get_logical_lba_for_physical_lba(addr32);
// char tmp[40]; sprintf(tmp, " W LBA: 0x%X->0x%X", addr32, lba); logMsg(tmp);
if (lba >= (EMM_LBA_SHIFT_KB << 10)) {
PSRAM_AVAILABLE ? psram_write8(&psram_spi, lba, value) : ram_page_write(lba, value);
psram_write8(&psram_spi, lba, value);
return;
}
}
else if ((addr32) > 0xFFFFFUL) {
if (addr32 >= 0x100000UL && addr32 < (ON_BOARD_RAM_KB << 10)) { // Hihg mem
if (get_a20_enabled()) { // A20 line is ON
// char tmp[40]; sprintf(tmp, "HIMEM W LBA: 0x%X", addr32); logMsg(tmp);
ram_page_write(addr32, value);
return;
}
} else if ((addr32) >= 0x100000UL && addr32 < (ON_BOARD_RAM_KB << 10)) { // XMS
if (get_a20_enabled()) { // A20 line is ON
psram_write8(&psram_spi, addr32, value);
return;
}

write86(addr32 - 0x100000UL, value);
return;
}
PSRAM_AVAILABLE ? psram_write8(&psram_spi, addr32, value) : ram_page_write(addr32, value);
#else
if (addr32 < (RAM_SIZE << 10)) {
RAM[addr32] = value;
write86(addr32 - 0x100000UL, value); // Rool back to low addressed
return;
}
if (addr32 >= 0xB8000UL && addr32 < 0xB8000UL + VRAM_SIZE << 10) {
// video RAM range
VRAM[addr32-0xB8000UL] = value;
#if PICO_ON_DEVICE
#if SD_CARD_SWAP
if (addr32 >= RAM_PAGE_SIZE && addr32 < (640 << 10)) { // Conventional
ram_page_write(addr32, value);
return;
}
if ((addr32 >> 4) >= PHYSICAL_EMM_SEGMENT && (addr32 >> 4) < PHYSICAL_EMM_SEGMENT_END) {
if ((addr32 >> 4) >= PHYSICAL_EMM_SEGMENT && (addr32 >> 4) < PHYSICAL_EMM_SEGMENT_END) { // EMS
uint32_t lba = get_logical_lba_for_physical_lba(addr32);
if (lba >= (EMM_LBA_SHIFT_KB << 10)) {
EXTRAM[lba] = value;
PSRAM_AVAILABLE ? psram_write8(&psram_spi, lba, value) : ram_page_write(lba, value);
return;
}
}
if ((addr32) >= 0x100000UL && addr32 < (ON_BOARD_RAM_KB << 10)) { // XMS
if (get_a20_enabled()) { // A20 line is ON
ram_page_write(addr32, value);
return;
}
write86(addr32 - 0x100000UL, value); // Rool back to low addressed
return;
}
#endif
if (PSRAM_AVAILABLE) { // Conentional (out of RAM size)
psram_write8(&psram_spi, addr32, value);
return;
}
#endif
// { char tmp[40]; sprintf(tmp, "ADDR W: 0x%X not found", addr32); logMsg(tmp); }
}

void writew86(uint32_t addr32, uint16_t value) {
bool w = (addr32 & 0xFFFFFFFE) == 0;
#if PICO_ON_DEVICE
if (PSRAM_AVAILABLE && (addr32 > (RAM_SIZE << 10) && addr32 < (640 << 10))) {
if (PSRAM_AVAILABLE && (addr32 > (RAM_SIZE << 10) && addr32 < (640 << 10))) { // Conventional
psram_write16(&psram_spi, addr32, value);
return;
}
if (PSRAM_AVAILABLE && addr32 >= (BASE_X86_KB << 10) && addr32 < (ON_BOARD_RAM_KB << 10) && get_a20_enabled()) { // XMS
psram_write16(&psram_spi, addr32, value);
return;
}
if (PSRAM_AVAILABLE && w && (addr32 >> 4) >= PHYSICAL_EMM_SEGMENT && (addr32 >> 4) < PHYSICAL_EMM_SEGMENT_END) { // EMS
uint32_t lba = get_logical_lba_for_physical_lba(addr32);
if (lba >= (EMM_LBA_SHIFT_KB << 10)) {
psram_write16(&psram_spi, lba, value);
return;
}
}
else
#if SD_CARD_SWAP
if (addr32 >= RAM_PAGE_SIZE && addr32 < (640 << 10) - 1 && w) {
if (w && addr32 >= RAM_PAGE_SIZE && addr32 < (640 << 10)) { // Conventional
ram_page_write16(addr32, value);
} else if (w && addr32 >= (BASE_X86_KB << 10) && addr32 < (ON_BOARD_RAM_KB << 10) && get_a20_enabled()) {
return;
}
if (w && (addr32 >> 4) >= PHYSICAL_EMM_SEGMENT && (addr32 >> 4) < PHYSICAL_EMM_SEGMENT_END) { // EMS
uint32_t lba = get_logical_lba_for_physical_lba(addr32);
if (lba >= (EMM_LBA_SHIFT_KB << 10)) {
ram_page_write16(lba, value);
return;
}
}
if (w && addr32 >= (BASE_X86_KB << 10) && addr32 < (ON_BOARD_RAM_KB << 10) && get_a20_enabled()) { // XMS
ram_page_write16(addr32, value);
return;
}
else // TODO: ROM, VRAM, himiem, ems...
#endif
#endif
{
write86(addr32, (uint8_t)value);
write86(addr32 + 1, (uint8_t)(value >> 8));
}
write86(addr32 , (uint8_t) value );
write86(addr32 + 1, (uint8_t)(value >> 8));
}

// https://docs.huihoo.com/gnu_linux/own_os/appendix-bios_memory_2.htm
__inline uint8_t read86(uint32_t addr32) {
#if PICO_ON_DEVICE
if ((!PSRAM_AVAILABLE && addr32 < (640 << 10)) || PSRAM_AVAILABLE && addr32 < (RAM_SIZE << 10)) {
if (PSRAM_AVAILABLE || addr32 < 4096) {
#if PICO_ON_DEVICE && SD_CARD_SWAP
if ((!PSRAM_AVAILABLE && addr32 < (640 << 10)) || (PSRAM_AVAILABLE && addr32 < (RAM_SIZE << 10))) { // Conentional
#else
if (addr32 < (RAM_SIZE << 10)) {
#endif
// https://docs.huihoo.com/gnu_linux/own_os/appendix-bios_memory_2.htm
#if SD_CARD_SWAP
if (PSRAM_AVAILABLE || addr32 < 4096) { // First page block
// do not touch first 4kb
return RAM[addr32];
}
return ram_page_read(addr32);
}
#else
if (addr32 < (RAM_SIZE << 10)) {
return RAM[addr32];
}
#endif
if ((addr32 >= 0xFE000UL) && (addr32 <= 0xFFFFFUL)) {
if (addr32 == 0xFC000) {
// TANDY graphics hack
return 0x21;
}
else if (addr32 == 0xFC000) {
// TANDY graphics hack
return 0x21;
}
else if ((addr32 >= 0xFE000UL) && (addr32 <= 0xFFFFFUL)) {
// BIOS ROM range
addr32 -= 0xFE000UL;
return BIOS[addr32];
}
if (PSRAM_AVAILABLE && (addr32 >> 4) >= PHYSICAL_EMM_SEGMENT && (addr32 >> 4) < PHYSICAL_EMM_SEGMENT_END) { // EMS
uint32_t lba = get_logical_lba_for_physical_lba(addr32);
if (lba >= (EMM_LBA_SHIFT_KB << 10)) {
return psram_read8(&psram_spi, lba);
}
// BIOS ROM range
return BIOS[addr32-0xFE000UL];
}

#if SD_CARD_SWAP
if ((addr32 >> 4) >= PHYSICAL_EMM_SEGMENT && (addr32 >> 4) < PHYSICAL_EMM_SEGMENT_END) { // Expanded memory paging space D00000-E00000
else if ((addr32 >> 4) >= PHYSICAL_EMM_SEGMENT && (addr32 >> 4) < PHYSICAL_EMM_SEGMENT_END) { // EMS
uint32_t lba = get_logical_lba_for_physical_lba(addr32);
// char tmp[40]; sprintf(tmp, " W LBA: 0x%X->0x%X", addr32, lba); logMsg(tmp);
if (lba >= (EMM_LBA_SHIFT_KB << 10)) {
return PSRAM_AVAILABLE ? psram_read8(&psram_spi, lba) : ram_page_read(lba);
}
Expand All @@ -229,38 +268,60 @@ __inline uint8_t read86(uint32_t addr32) {
addr32 -= 0xFA000UL;
return BASICH[addr32];
}

else if (addr32 >= 0x100000UL && addr32 < (ON_BOARD_RAM_KB << 10)) { // Hihg mem
else if (addr32 >= 0x100000UL && addr32 < (ON_BOARD_RAM_KB << 10)) { // XMS
#if SD_CARD_SWAP
// TODO: PSRAM_AVAILABLE ...
if (get_a20_enabled()) {
// char tmp[40]; sprintf(tmp, "HIMEM LBA: 0x%X", addr32); logMsg(tmp);
return ram_page_read(addr32);
return PSRAM_AVAILABLE ? psram_read8(&psram_spi, addr32) : ram_page_read(addr32);
}
return read86(addr32 - 0x100000UL); // FFFF:0010 -> 0000:0000 rolling address space for case A20 is turned off
#endif
}
#if PICO_ON_DEVICE
if (PSRAM_AVAILABLE) {
return psram_read8(&psram_spi, addr32);
if (PSRAM_AVAILABLE) { // XMS no sd-card swap
if (get_a20_enabled()) {
return psram_read8(&psram_spi, addr32);
}
return read86(addr32 - 0x100000UL); // FFFF:0010 -> 0000:0000 rolling address space for case A20 is turned off
}
#endif
// { char tmp[40]; sprintf(tmp, "ADDR R: 0x%X not found", addr32); logMsg(tmp); }
return 0;
}

uint16_t readw86(uint32_t addr32) {
#if PICO_ON_DEVICE
if (PSRAM_AVAILABLE && (addr32 > (RAM_SIZE << 10) && addr32 < (640 << 10))) {
if (PSRAM_AVAILABLE && (addr32 > (RAM_SIZE << 10) && addr32 < (640 << 10))) { // Coventional > RAM todo: w?
return psram_read16(&psram_spi, addr32);
}
uint32_t w = (addr32 & 0xFFFFFFFE) == 0; // alligned to 16 bit
if (PSRAM_AVAILABLE && w && addr32 >= BASE_X86_KB && addr32 < (ON_BOARD_RAM_KB << 10)) { // XMS
if (get_a20_enabled()) {
return psram_read16(&psram_spi, addr32);
}
return read86(addr32 - BASE_X86_KB);
}
if (PSRAM_AVAILABLE && w && (addr32 >> 4) >= PHYSICAL_EMM_SEGMENT && (addr32 >> 4) < PHYSICAL_EMM_SEGMENT_END) { // EMS
uint32_t lba = get_logical_lba_for_physical_lba(addr32);
if (lba >= (EMM_LBA_SHIFT_KB << 10)) {
return psram_read16(&psram_spi, lba);
}
}
#if SD_CARD_SWAP
uint32_t w = (addr32 & 0xFFFFFFFE) == 0;
if (addr32 >= RAM_PAGE_SIZE && addr32 < (640 << 10) - 1 && w) {
return ram_page_read16(addr32);
} // TODO: ROM, VRAM, ...
if (get_a20_enabled() && addr32 >= 0x100000UL && addr32 < (ON_BOARD_RAM_KB << 10) && w) {
else if (w && (addr32 >> 4) >= PHYSICAL_EMM_SEGMENT && (addr32 >> 4) < PHYSICAL_EMM_SEGMENT_END) { // EMS
uint32_t lba = get_logical_lba_for_physical_lba(addr32);
if (lba >= (EMM_LBA_SHIFT_KB << 10)) {
return ram_page_read16(lba);
}
}
if (addr32 >= RAM_PAGE_SIZE && addr32 < (640 << 10) - 1 && w) { // Conentional (not first 4k)
return ram_page_read16(addr32);
}
if (w && addr32 >= BASE_X86_KB && addr32 < (ON_BOARD_RAM_KB << 10)) { // XMS
if (get_a20_enabled()) {
return ram_page_read16(addr32);
}
return readw86(addr32 - BASE_X86_KB);
}
#endif
#endif
return ((uint16_t)read86(addr32) | (uint16_t)(read86(addr32 + 1) << 8));
Expand Down Expand Up @@ -824,7 +885,7 @@ static void custom_on_board_emm() {
// DX = emm_handle
uint8_t AL = CPU_AL;
CPU_AX = map_unmap_emm_page(CPU_AL, CPU_BX, CPU_DX);
sprintf(tmp, "LIM40 FN %Xh res: phys page %Xh was mapped to %Xh log for %d EMM handler",
sprintf(tmp, "LIM40 FN %Xh res: phys page %d was mapped to %d logical for %d EMM handler",
FN, AL, CPU_BX, CPU_DX); logMsg(tmp);
if (CPU_AX) zf = 1; else zf = 0;
return;
Expand All @@ -833,7 +894,7 @@ static void custom_on_board_emm() {
case 0x45: {
uint16_t emm_handle = CPU_DX;
CPU_AX = deallocate_emm_pages(emm_handle);
sprintf(tmp, "LIM40 FN %Xh res: %Xh - EMM handler dealloc", FN, emm_handle); logMsg(tmp);
sprintf(tmp, "LIM40 FN %Xh res: %Xh - EMM handler %d dealloc", FN, CPU_AX, emm_handle); logMsg(tmp);
if (CPU_AX) zf = 1; else zf = 0;
return;
}
Expand Down
12 changes: 7 additions & 5 deletions src/emm.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ static emm_handler_t handlers[MAX_EMM_HANDLERS] = { 0 };
void init_emm() {
emm_handler_t * h = &handlers[0];
h->handler_in_use = true;
h->pages_acllocated = 4;
h->pages_acllocated = 0;
for (int i = 1; i < MAX_EMM_HANDLERS; ++i) {
h = &handlers[i];
h->handler_in_use = false;
Expand Down Expand Up @@ -273,11 +273,11 @@ uint16_t map_unmap_emm_page(

uint16_t deallocate_emm_pages(uint16_t emm_handle) {
if (emm_handle >= MAX_EMM_HANDLERS) {
return 0x83; // The manager couldn't find the specified EMM handle.
return 0x8300; // The manager couldn't find the specified EMM handle.
}
emm_handler_t * h = &handlers[emm_handle];
if (!h->handler_in_use) {
return 0x83; // The manager couldn't find the specified EMM handle.
return 0x8300; // The manager couldn't find the specified EMM handle.
}
for (int j = 0; j < MAX_SAVED_EMM_TABLES; ++j) {
const emm_saved_table_t * st = &emm_saved_tables[j];
Expand All @@ -294,9 +294,10 @@ uint16_t deallocate_emm_pages(uint16_t emm_handle) {
}
}
for (int i = 0; i < PHYSICAL_EMM_PAGES; ++i) {
const emm_record_t * di = &emm_desc_table[i];
emm_record_t * di = &emm_desc_table[i];
if (di->handler == emm_handle) {
return 0x86 << 8; // The memory manager detected a save or restore page mapping context error.
// return 0x86 << 8; // The memory manager detected a save or restore page mapping context error.
di->handler = 0xFF;
}
}
h->pages_acllocated = 0;
Expand Down Expand Up @@ -331,6 +332,7 @@ uint16_t restore_emm_mapping(uint16_t ext_handler) {
emm_saved_table_t * di = &emm_saved_tables[i];
if (di->ext_handler == ext_handler) {
memcpy(emm_desc_table, di->table, sizeof emm_desc_table);
memset(di->table, 0, sizeof emm_desc_table);
di->ext_handler = 0;
return 0;
}
Expand Down
4 changes: 2 additions & 2 deletions src/emm.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@
#pragma once
#include <inttypes.h>

#define ON_BOARD_RAM_KB (1ul << 10)
#define ON_BOARD_RAM_KB (4ul << 10)
#define BASE_X86_KB 1024ul
#define TOTAL_XMM_KB (ON_BOARD_RAM_KB - BASE_X86_KB)
#define TOTAL_EMM_KB (1ul << 10)
#define TOTAL_EMM_KB (4ul << 10)
#define EMM_LBA_SHIFT_KB ON_BOARD_RAM_KB
#define TOTAL_EMM_PAGES (TOTAL_EMM_KB >> 4)
#define TOTAL_VIRTUAL_MEMORY_KBS (ON_BOARD_RAM_KB + TOTAL_EMM_KB)
Expand Down
5 changes: 4 additions & 1 deletion src/emulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,14 @@ static FATFS fs;

#define BEEPER_PIN 28
#define VRAM_SIZE 64

#ifdef WIN_EXT_RAM
#define EXT_RAM_SIZE 32 << 10 // 32Mb
extern uint8_t EXTRAM[EXT_RAM_SIZE << 10];
#endif

// TODO: no direct access support (for PC mode)
extern uint8_t RAM[RAM_SIZE << 10];
extern uint8_t EXTRAM[EXT_RAM_SIZE << 10];
extern uint8_t VRAM[VRAM_SIZE << 10];
extern bool PSRAM_AVAILABLE;

Expand Down
Loading

0 comments on commit b9ca56e

Please sign in to comment.