mirror of
https://github.com/V2RetroComputing/analog.git
synced 2024-11-26 21:51:07 +00:00
d9be2ed9cd
New autodetect routines for Apple II+, IIe (Platinum), IIgs (ROM03). Timing tweaks to improve compatibility on IIgs and IIe. Corrected text rendering on all supported machines. Initial Super HiRes support (not recommended to use at this time) Monochrome DHGR and HGR support activated with IIgs MONOCOLOR or NEWVID registers. 80 Column mode on IIe and IIgs.
260 lines
10 KiB
C
260 lines
10 KiB
C
#include <string.h>
|
|
#include <hardware/pio.h>
|
|
#include "common/config.h"
|
|
#include "abus.pio.h"
|
|
#include "vga/businterface.h"
|
|
#include "vga/vgabuf.h"
|
|
|
|
|
|
volatile uint8_t *videx_page = videx_memory;
|
|
uint32_t a2_first_write = 0;
|
|
|
|
static inline void __time_critical_func(videx_crtc_addr)(uint32_t value) {
|
|
}
|
|
|
|
|
|
static inline void __time_critical_func(videx_crtc_write)(uint32_t value) {
|
|
}
|
|
|
|
|
|
static inline void __time_critical_func(shadow_memory)(uint32_t address, uint32_t value) {
|
|
// Shadow the soft-switches by observing all read & write bus cycles
|
|
if((address & 0xff80) == 0xc000) {
|
|
switch(address & 0x7f) {
|
|
case 0x00:
|
|
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
soft_switches &= ~SOFTSW_80STORE;
|
|
}
|
|
return;
|
|
case 0x01:
|
|
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
soft_switches |= SOFTSW_80STORE;
|
|
}
|
|
return;
|
|
case 0x04:
|
|
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
soft_switches &= ~SOFTSW_AUX_WRITE;
|
|
}
|
|
return;
|
|
case 0x05:
|
|
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
soft_switches |= SOFTSW_AUX_WRITE;
|
|
}
|
|
return;
|
|
case 0x08:
|
|
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
soft_switches &= ~SOFTSW_AUXZP;
|
|
}
|
|
return;
|
|
case 0x09:
|
|
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
soft_switches |= SOFTSW_AUXZP;
|
|
}
|
|
return;
|
|
case 0x0c:
|
|
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
soft_switches &= ~SOFTSW_80COL;
|
|
}
|
|
return;
|
|
case 0x0d:
|
|
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
soft_switches |= SOFTSW_80COL;
|
|
}
|
|
return;
|
|
case 0x0e:
|
|
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
soft_switches &= ~SOFTSW_ALTCHAR;
|
|
}
|
|
return;
|
|
case 0x0f:
|
|
if((soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
soft_switches |= SOFTSW_ALTCHAR;
|
|
}
|
|
return;
|
|
case 0x21:
|
|
if((soft_switches & SOFTSW_IIGS_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
if(value & 0x80) {
|
|
soft_switches |= SOFTSW_MONOCHROME;
|
|
} else {
|
|
soft_switches &= ~SOFTSW_MONOCHROME;
|
|
}
|
|
}
|
|
return;
|
|
case 0x22:
|
|
if((soft_switches & SOFTSW_IIGS_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
terminal_tbcolor = value & 0xff;
|
|
}
|
|
return;
|
|
case 0x29:
|
|
if((soft_switches & SOFTSW_IIGS_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
soft_switches = (soft_switches & ~(SOFTSW_NEWVID_MASK << SOFTSW_NEWVID_SHIFT)) | ((value & SOFTSW_NEWVID_MASK) << SOFTSW_NEWVID_SHIFT);
|
|
}
|
|
return;
|
|
case 0x34:
|
|
if((soft_switches & SOFTSW_IIGS_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
terminal_border = value & 0x0f;
|
|
}
|
|
return;
|
|
case 0x35:
|
|
if((soft_switches & SOFTSW_IIGS_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
soft_switches = (soft_switches & ~(SOFTSW_SHADOW_MASK << SOFTSW_SHADOW_SHIFT)) | ((value & SOFTSW_SHADOW_MASK) << SOFTSW_SHADOW_SHIFT);
|
|
}
|
|
return;
|
|
case 0x50:
|
|
soft_switches &= ~SOFTSW_TEXT_MODE;
|
|
return;
|
|
case 0x51:
|
|
soft_switches |= SOFTSW_TEXT_MODE;
|
|
return;
|
|
case 0x52:
|
|
soft_switches &= ~SOFTSW_MIX_MODE;
|
|
return;
|
|
case 0x53:
|
|
soft_switches |= SOFTSW_MIX_MODE;
|
|
return;
|
|
case 0x54:
|
|
soft_switches &= ~SOFTSW_PAGE_2;
|
|
return;
|
|
case 0x55:
|
|
soft_switches |= SOFTSW_PAGE_2;
|
|
return;
|
|
case 0x56:
|
|
soft_switches &= ~SOFTSW_HIRES_MODE;
|
|
return;
|
|
case 0x57:
|
|
soft_switches |= SOFTSW_HIRES_MODE;
|
|
return;
|
|
case 0x5e:
|
|
if(soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) {
|
|
soft_switches |= SOFTSW_DGR;
|
|
}
|
|
return;
|
|
case 0x5f:
|
|
if(soft_switches & (SOFTSW_IIGS_REGS | SOFTSW_IIE_REGS)) {
|
|
soft_switches &= ~SOFTSW_DGR;
|
|
}
|
|
return;
|
|
case 0x7e:
|
|
if((soft_switches & SOFTSW_IIE_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
soft_switches |= SOFTSW_IOUDIS;
|
|
}
|
|
return;
|
|
case 0x7f:
|
|
if((soft_switches & SOFTSW_IIE_REGS) && ((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0)) {
|
|
soft_switches &= ~SOFTSW_IOUDIS;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Shadow parts of the Apple's memory by observing the bus write cycles
|
|
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) == 0) {
|
|
if((machine == COMPAT_AUTO) && (a2_first_write == 0)) {
|
|
a2_first_write = (address << 16) | (value & 0x3FF);
|
|
if(a2_first_write == 0xC0330100) { // Apple IIgs ROM03 Clock Access
|
|
machine = APPLE_IIGS;
|
|
soft_switches &= ~SOFTSW_IIE_REGS;
|
|
soft_switches |= SOFTSW_IIGS_REGS;
|
|
} else if(a2_first_write == 0x01F901FB) { // Apple II Plus
|
|
machine = APPLE_II;
|
|
soft_switches &= ~(SOFTSW_IIE_REGS | SOFTSW_IIGS_REGS);
|
|
} else if(a2_first_write == 0x01F5018B) { // Apple IIe Platinum
|
|
machine = APPLE_IIE;
|
|
soft_switches |= SOFTSW_IIE_REGS;
|
|
soft_switches &= ~SOFTSW_IIGS_REGS;
|
|
} else {
|
|
a2_first_write = 0;
|
|
}
|
|
}
|
|
|
|
// Mirror Video Memory from MAIN & AUX banks
|
|
if(soft_switches & SOFTSW_LINEARIZE) {
|
|
if((address >= 0x2000) && (address < 0xC000)) {
|
|
private_memory[address] = value & 0xff;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if(soft_switches & SOFTSW_80STORE) {
|
|
if(soft_switches & SOFTSW_PAGE_2) {
|
|
if((address >= 0x400) && (address < 0x800)) {
|
|
private_memory[address] = value & 0xff;
|
|
return;
|
|
} else if((soft_switches & SOFTSW_HIRES_MODE) && (address >= 0x2000) && (address < 0x4000)) {
|
|
private_memory[address] = value & 0xff;
|
|
return;
|
|
}
|
|
}
|
|
} else if(soft_switches & SOFTSW_AUX_WRITE) {
|
|
if((address >= 0x200) && (address < 0xC000)) {
|
|
private_memory[address] = value & 0xff;
|
|
return;
|
|
}
|
|
}
|
|
|
|
if((address >= 0x200) && (address < 0xC000)) {
|
|
apple_memory[address] = value & 0xff;
|
|
return;
|
|
}
|
|
|
|
// Videx 80 Column Card
|
|
if(CARD_SELECT) {
|
|
if((address >= 0xCC00) && (address < 0xD000)) {
|
|
videx_page[(address & 0x3FF)] = value & 0xff;
|
|
}
|
|
|
|
if(CARD_DEVSEL) {
|
|
switch(address & 0x01) {
|
|
case 0x0:
|
|
videx_crtc_addr(value & 0xff);
|
|
break;
|
|
case 0x1:
|
|
videx_crtc_write(value & 0xff);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Config memory in card slot-rom address space
|
|
if(CARD_IOSEL) {
|
|
config_memory[address & 0x1F] = value;
|
|
if((address & 0xFF) == 0xFF)
|
|
config_handler();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Any access to Videx I/O sets the VRAM page visible in 0xCC00-0xD000
|
|
if(CARD_SELECT && CARD_DEVSEL) {
|
|
videx_page = videx_memory + ((address & 0x0C) << 9);
|
|
}
|
|
}
|
|
|
|
|
|
void __time_critical_func(vga_businterface)() {
|
|
while(v2mode == MODE_VGACARD) {
|
|
uint32_t value = pio_sm_get_blocking(CONFIG_ABUS_PIO, ABUS_MAIN_SM);
|
|
uint32_t address = (value >> 10) & 0xffff;
|
|
|
|
if((value & (1u << CONFIG_PIN_APPLEBUS_RW-CONFIG_PIN_APPLEBUS_DATA_BASE)) != 0) {
|
|
if(CARD_SELECT) {
|
|
uint32_t dout;
|
|
switch(address >> 10) {
|
|
case (0xC000 >> 10):
|
|
dout = (address & 1) ? videx_crtc_reg : 0xff;
|
|
break;
|
|
case (0xCC00 >> 10):
|
|
dout = videx_memory[address & 0x3FF];
|
|
break;
|
|
default:
|
|
dout = apple_memory[address];
|
|
}
|
|
|
|
// device read access
|
|
pio_sm_put_blocking(CONFIG_ABUS_PIO, ABUS_DEVICE_READ_SM, dout);
|
|
}
|
|
}
|
|
|
|
shadow_memory(address, value);
|
|
}
|
|
}
|