Compare commits
10 Commits
813118b3c8
...
a82b03e631
Author | SHA1 | Date |
---|---|---|
David Kuder | a82b03e631 | |
David Kuder | 4bff5c15b5 | |
David Kuder | c8b4ce9631 | |
David Kuder | 89367bca09 | |
David Kuder | 83d737c44e | |
David Kuder | 685ff4f632 | |
David Kuder | 910c644cd7 | |
David Kuder | 6e7d80e916 | |
David Kuder | 3ee0061fdc | |
David Kuder | 4586bb8638 |
|
@ -21,27 +21,27 @@
|
|||
; x - select Data, active low
|
||||
.wrap_target
|
||||
next_bus_cycle:
|
||||
set PINS, 0b011 ; enable AddrHi tranceiver
|
||||
wait 1 GPIO, PHI0_GPIO ; wait for PHI0 to rise. Data propagation through the transceiver should
|
||||
; be complete by the time this happens.
|
||||
set PINS, 0b011 ; disable tranceivers
|
||||
wait 1 GPIO, PHI0_GPIO [5] ; wait for PHI0 to rise.
|
||||
set PINS, 0b011 [5] ; enable AddrHi tranceiver and delay for transceiver propagation delay (24ns)
|
||||
in PINS, 8 ; read AddrHi[7:0]
|
||||
set PINS, 0b101 [12] ; enable AddrLo tranceiver and delay for transceiver propagation delay
|
||||
set PINS, 0b101 [5] ; enable AddrLo tranceiver and delay for transceiver propagation delay (24ns)
|
||||
in PINS, 8 ; read AddrLo[7:0]
|
||||
|
||||
jmp PIN, read_cycle ; jump based on the state of the R/W pin
|
||||
|
||||
write_cycle:
|
||||
; the current time is P0+82ns (P0 + 10ns + 2 clocks (input synchronizers) + 16 instructions)
|
||||
; the current time is P0+92ns (P0 + 10ns + 2 clocks (input synchronizers) + 21 instructions)
|
||||
|
||||
set PINS, 0b110 [31] ; enable Data tranceiver & wait until both ~DEVSEL and the written data are valid (P0+210ns)
|
||||
set PINS, 0b110 [31] ; enable Data tranceiver & wait until both ~DEVSEL and the written data are valid (P0+220ns)
|
||||
in PINS, 10 ; read R/W, ~DEVSEL, and Data[7:0], then autopush
|
||||
wait 0 GPIO, PHI0_GPIO [7] ; wait for PHI0 to fall
|
||||
jmp next_bus_cycle
|
||||
|
||||
read_cycle:
|
||||
; the current time is P0+82ns (P0 + 10ns + 2 clocks (input synchronizers) + 16 instructions)
|
||||
; the current time is P0+92ns (P0 + 10ns + 2 clocks (input synchronizers) + 21 instructions)
|
||||
|
||||
set PINS, 0b110 [4] ; ensure AddrLo transceiver is disabled and delay for ~DEVSEL to become valid (P0+102ns+buffer delay)
|
||||
set PINS, 0b110 [5] ; ensure AddrLo transceiver is disabled and delay for ~DEVSEL to become valid (P0+102ns+buffer delay)
|
||||
in PINS, 10 ; read R/W, ~DEVSEL, and dontcare[7:0], then autopush
|
||||
|
||||
irq set READ_DATA_TRIGGER_IRQ ; trigger the data read state machine to put data on the data bus
|
||||
|
@ -66,26 +66,26 @@ wait_loop:
|
|||
wait 1 irq READ_DATA_TRIGGER_IRQ ; wait for the data portion of a read cycle (from the main SM)
|
||||
jmp PIN, wait_loop ; skip if this device is not being addressed
|
||||
|
||||
; the current time is P0+114ns (P0 + 10ns + 2 clocks (input synchronizers) + 24 instructions) and
|
||||
; the current time is P0+128ns and
|
||||
; this read cycle is addressed to this device.
|
||||
;
|
||||
; Phase 0 is typically 489 ns long.
|
||||
; * Data from peripherals should be valid on the data bus by 45 nanoseconds before the end of phase 0
|
||||
; * Data should be held for 40ns after phase 0 ends
|
||||
; * Data bus should be tri-stated within 60ns after phase 0 ends
|
||||
; * Data should be held for no more than 20ns after phase 0 ends
|
||||
; * Data bus should be tri-stated within 30ns after phase 0 ends
|
||||
|
||||
irq set DATA_BUSY_IRQ
|
||||
|
||||
set PINS, 0b01 [10] ; enable Data tranceiver with output direction [160ns]
|
||||
mov OSR, ~NULL [31] ; [288ns]
|
||||
out PINDIRS, 8 [31] ; set data pins as outputs [416ns]
|
||||
set PINS, 0b01 [7] ; enable Data tranceiver with output direction [P0+164ns]
|
||||
mov OSR, ~NULL [31] ; [P0+292ns]
|
||||
out PINDIRS, 8 [31] ; set data pins as outputs [P0+420ns]
|
||||
|
||||
pull noblock ; pull value from the FIFO as late as possible [420ns]
|
||||
out PINS, 8 ; [424ns]
|
||||
pull noblock ; pull value from the FIFO as late as possible [P0+424ns]
|
||||
out PINS, 8 ; [P0+428ns]
|
||||
|
||||
; the current time is P0+424ns (P0 + 10ns + 2 clocks (input synchronizers) + 101 instructions)
|
||||
; the current time is P0+428ns
|
||||
|
||||
wait 0 GPIO, PHI0_GPIO [7] ; wait for PHI0 to fall then hold for 40ns (2 clocks (input synchronizers) + 7 instructions)
|
||||
wait 0 GPIO, PHI0_GPIO [2] ; wait for PHI0 to fall then hold for 12ns (2 clocks (input synchronizers) + 7 instructions)
|
||||
set PINS, 0b10 ; disable Data tranceiver to tri-state the data bus
|
||||
|
||||
mov OSR, NULL
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
; * IN pins are mapped to ~DEVSEL, R/W, and Data[7:0]
|
||||
; * SET pins are mapped to the transceiver enable signals
|
||||
; * input shift left & autopush @ 26 bits
|
||||
; * run at about 125MHz (8ns/instruction)
|
||||
; * run at about 250MHz (4ns/instruction)
|
||||
;
|
||||
; SET bits for tranceiver control:
|
||||
; 0bxxx
|
||||
|
@ -21,31 +21,31 @@
|
|||
; x - select Data, active low
|
||||
.wrap_target
|
||||
next_bus_cycle:
|
||||
set PINS, 0b011 ; enable AddrHi tranceiver
|
||||
wait 1 GPIO, PHI0_GPIO ; wait for PHI0 to rise. Data propagation through the transceiver should
|
||||
; be complete by the time this happens.
|
||||
set PINS, 0b011 ; disable tranceivers
|
||||
wait 1 GPIO, PHI0_GPIO [2] ; wait for PHI0 to rise.
|
||||
set PINS, 0b011 [2] ; enable AddrHi tranceiver and delay for transceiver propagation delay (24ns)
|
||||
in PINS, 8 ; read AddrHi[7:0]
|
||||
set PINS, 0b101 [2] ; enable AddrLo tranceiver and delay for transceiver propagation delay
|
||||
set PINS, 0b101 [2] ; enable AddrLo tranceiver and delay for transceiver propagation delay (24ns)
|
||||
in PINS, 8 ; read AddrLo[7:0]
|
||||
|
||||
jmp PIN, read_cycle ; jump based on the state of the R/W pin
|
||||
|
||||
write_cycle:
|
||||
; the current time is P0+88ns (P0 + 16ns + 2 clocks (input synchronizers) + 7 instructions)
|
||||
; the current time is P0+98ns (P0 + 10ns + 2 clocks (input synchronizers) + 11 instructions)
|
||||
|
||||
set PINS, 0b110 [15] ; enable Data tranceiver & wait until both ~DEVSEL and the written data are valid (P0+200ns)
|
||||
set PINS, 0b110 [31] ; enable Data tranceiver & wait until both ~DEVSEL and the written data are valid (P0+216ns)
|
||||
in PINS, 10 ; read R/W, ~DEVSEL, and Data[7:0], then autopush
|
||||
wait 0 GPIO, PHI0_GPIO [7] ; wait for PHI0 to fall
|
||||
wait 0 GPIO, PHI0_GPIO [3] ; wait for PHI0 to fall
|
||||
jmp next_bus_cycle
|
||||
|
||||
read_cycle:
|
||||
; the current time is P0+88ns (P0 + 16ns + 2 clocks (input synchronizers) + 7 instructions)
|
||||
; the current time is P0+98ns (P0 + 10ns + 2 clocks (input synchronizers) + 11 instructions)
|
||||
|
||||
set PINS, 0b110 ; ensure AddrLo transceiver is disabled and delay for ~DEVSEL to become valid (P0+63ns+buffer delay)
|
||||
set PINS, 0b110 [2] ; ensure AddrLo transceiver is disabled and delay for ~DEVSEL to become valid (P0+102ns+buffer delay)
|
||||
in PINS, 10 ; read R/W, ~DEVSEL, and dontcare[7:0], then autopush
|
||||
|
||||
irq set READ_DATA_TRIGGER_IRQ ; trigger the data read state machine to put data on the data bus
|
||||
wait 0 GPIO, PHI0_GPIO [7] ; wait for PHI0 to fall
|
||||
wait 0 GPIO, PHI0_GPIO [3] ; wait for PHI0 to fall
|
||||
wait 0 irq DATA_BUSY_IRQ ; wait for the data handling state machine to complete to avoid contention w/transceiver control
|
||||
.wrap
|
||||
|
||||
|
@ -66,32 +66,32 @@ wait_loop:
|
|||
wait 1 irq READ_DATA_TRIGGER_IRQ ; wait for the data portion of a read cycle (from the main SM)
|
||||
jmp PIN, wait_loop ; skip if this device is not being addressed
|
||||
|
||||
; the current time is P0+136ns (P0 + 16ns + 2 clocks (input synchronizers) + 13 instructions) and
|
||||
; the current time is P0+138ns and
|
||||
; this read cycle is addressed to this device.
|
||||
;
|
||||
; Phase 0 is typically 489 ns long.
|
||||
; * Data from peripherals should be valid on the data bus by 45 nanoseconds before the end of phase 0
|
||||
; * Data should be held for 40ns after phase 0 ends
|
||||
; * Data bus should be tri-stated within 60ns after phase 0 ends
|
||||
; * Data should be held for no more than 20ns after phase 0 ends
|
||||
; * Data bus should be tri-stated within 30ns after phase 0 ends
|
||||
|
||||
irq set DATA_BUSY_IRQ
|
||||
|
||||
set PINS, 0b01 ; enable Data tranceiver with output direction
|
||||
mov OSR, ~NULL [4]
|
||||
out PINDIRS, 8 [31] ; set data pins as outputs
|
||||
set PINS, 0b01 [3] ; enable Data tranceiver with output direction [P0+178ns]
|
||||
mov OSR, ~NULL [15] ; [P0+306ns]
|
||||
out PINDIRS, 8 [15] ; set data pins as outputs [P0+434ns]
|
||||
|
||||
pull noblock ; pull value from the FIFO as late as possible
|
||||
out PINS, 8
|
||||
pull noblock ; pull value from the FIFO as late as possible [P0+442ns]
|
||||
out PINS, 8 ; [P0+450ns]
|
||||
|
||||
; the current time is P0+440ns (P0 + 16ns + 2 clocks (input synchronizers) + 51 instructions)
|
||||
; the current time is P0+450ns
|
||||
|
||||
wait 0 GPIO, PHI0_GPIO [2] ; wait for PHI0 to fall then hold for 40ns (2 clocks (input synchronizers) + 2-3 instructions)
|
||||
wait 0 GPIO, PHI0_GPIO [1] ; wait for PHI0 to fall then hold for 16ns (2 clocks (input synchronizers) + 7 instructions)
|
||||
set PINS, 0b10 ; disable Data tranceiver to tri-state the data bus
|
||||
|
||||
mov OSR, NULL
|
||||
out PINDIRS, 8 ; reset data pins as inputs
|
||||
|
||||
pull noblock ; extra late pull to clear out any standing values from the FIFO
|
||||
pull noblock ; extra late pull to clear out any standing values from the FIFO [P1+56ns]
|
||||
|
||||
irq clear DATA_BUSY_IRQ
|
||||
.wrap
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include "buffers.h"
|
||||
|
||||
volatile uint32_t soft_switches = 0;
|
||||
volatile uint32_t internal_flags = IFLAGS_V7_MODE3;
|
||||
volatile uint32_t internal_flags = IFLAGS_OLDCOLOR | IFLAGS_INTERP | IFLAGS_V7_MODE3;
|
||||
|
||||
volatile uint8_t reset_state = 0;
|
||||
|
||||
|
|
|
@ -31,6 +31,9 @@ extern volatile uint8_t *hgr_p4;
|
|||
/* Videx VideoTerm */
|
||||
extern volatile uint8_t *videx_page;
|
||||
|
||||
#define apple_tbcolor apple_memory[0xC022]
|
||||
#define apple_border apple_memory[0xC034]
|
||||
|
||||
#endif
|
||||
|
||||
extern volatile uint8_t *baseio;
|
||||
|
@ -107,6 +110,8 @@ extern volatile uint32_t internal_flags;
|
|||
#define SOFTSW_SHADOW_IO 0x04000000ul
|
||||
|
||||
// V2 Analog specific softswitches
|
||||
#define IFLAGS_INTERP 0x01000000ul
|
||||
#define IFLAGS_GRILL 0x02000000ul
|
||||
#define IFLAGS_VIDEO7 0x04000000ul
|
||||
#define IFLAGS_OLDCOLOR 0x08000000ul
|
||||
#define IFLAGS_TERMINAL 0x10000000ul
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#define BUILDDATE 0x20230502
|
||||
#define BUILDID 0x0182
|
||||
#define BUILDSTR " 2 May 2023 Build 0182"
|
||||
#define BUILDDATE 0x20230504
|
||||
#define BUILDID 0x0187
|
||||
#define BUILDSTR " 4 May 2023 Build 0187"
|
||||
|
||||
#ifdef ANALOG_GS
|
||||
#define HWSTRING " V2 Analog GS Rev1"
|
||||
|
|
|
@ -58,3 +58,6 @@
|
|||
|
||||
#define CFGTOKEN_VIDEO7 0x00003756 // "V7\xXX\x00" Video 7 Enable / Disable
|
||||
#define CFGTOKEN_RGBCOLOR 0x00005043 // "CP\xXX\x04" RGB Palette Entry Override
|
||||
|
||||
#define CFGTOKEN_INTERP 0x00004956 // "VI\x0X\x00" RGB Interpolation
|
||||
#define CFGTOKEN_GRILL 0x00004756 // "VG\x0X\x00" RGB Aperture Grill
|
||||
|
|
|
@ -201,7 +201,15 @@ void DELAYED_COPY_CODE(default_config)() {
|
|||
current_machine = MACHINE_AUTO;
|
||||
internal_flags |= (IFLAGS_IIE_REGS | IFLAGS_IIGS_REGS);
|
||||
#endif
|
||||
#ifdef FUNCTION_VGA
|
||||
apple_tbcolor = 0xf0;
|
||||
apple_border = 0x00;
|
||||
|
||||
terminal_tbcolor = 0xf0;
|
||||
terminal_border = 0x00;
|
||||
|
||||
internal_flags |= IFLAGS_VIDEO7 | IFLAGS_V7_MODE3;
|
||||
#endif
|
||||
}
|
||||
|
||||
int DELAYED_COPY_CODE(make_config)(uint32_t rev) {
|
||||
|
@ -753,10 +761,18 @@ void DELAYED_COPY_CODE(config_handler)() {
|
|||
break;
|
||||
|
||||
case 'R':
|
||||
// Reboot and bypass auto-detection of machine type.
|
||||
cfg_machine = current_machine;
|
||||
write_config(true);
|
||||
flash_reboot();
|
||||
switch(config_cmdbuf[1]) {
|
||||
default:
|
||||
retval = REPLY_ECMD;
|
||||
break;
|
||||
case 'b':
|
||||
// Reboot and bypass auto-detection of machine type.
|
||||
cfg_machine = current_machine;
|
||||
read_config();
|
||||
write_config(true);
|
||||
flash_reboot();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
|
|
|
@ -79,12 +79,15 @@ static void __noinline __time_critical_func(core1_loop)() {
|
|||
}
|
||||
#ifdef FUNCTION_VGA
|
||||
} else if(current_machine == MACHINE_AUTO) {
|
||||
#ifdef ANALOG_GS
|
||||
if(value & 0x08000000) {
|
||||
// Hardware jumpered for IIGS mode.
|
||||
current_machine = MACHINE_IIGS;
|
||||
internal_flags &= ~IFLAGS_IIE_REGS;
|
||||
internal_flags |= IFLAGS_IIGS_REGS;
|
||||
} else if((apple_memory[0x404] == 0xE5) && (apple_memory[0x0403] == 0xD8)) { // ROMXe
|
||||
} else
|
||||
#endif
|
||||
if((apple_memory[0x404] == 0xE5) && (apple_memory[0x0403] == 0xD8)) { // ROMXe
|
||||
current_machine = MACHINE_IIE;
|
||||
internal_flags |= IFLAGS_IIE_REGS;
|
||||
internal_flags &= ~IFLAGS_IIGS_REGS;
|
||||
|
@ -136,7 +139,8 @@ static void __noinline __time_critical_func(core1_loop)() {
|
|||
soft_switches |= SOFTSW_TEXT_MODE;
|
||||
soft_switches &= ~SOFTSW_80COL;
|
||||
soft_switches &= ~SOFTSW_DGR;
|
||||
internal_flags &= ~(IFLAGS_TERMINAL | IFLAGS_TEST | IFLAGS_V7_MODE3);
|
||||
internal_flags &= ~(IFLAGS_TERMINAL | IFLAGS_TEST);
|
||||
internal_flags |= IFLAGS_V7_MODE3;
|
||||
#endif
|
||||
default:
|
||||
reset_state = 0;
|
||||
|
|
|
@ -55,9 +55,12 @@ void __time_critical_func(vga_businterface)(uint32_t address, uint32_t value) {
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Nothing left to do for RAM accesses.
|
||||
if(address < 0xc000) return;
|
||||
|
||||
// Shadow the soft-switches by observing all read & write bus cycles
|
||||
if((address & 0xff80) == 0xc000) {
|
||||
if(address < 0xc080) {
|
||||
switch(address & 0x7f) {
|
||||
case 0x00:
|
||||
if((internal_flags & (IFLAGS_IIGS_REGS | IFLAGS_IIE_REGS)) && ACCESS_WRITE) {
|
||||
|
@ -210,7 +213,7 @@ void __time_critical_func(vga_businterface)(uint32_t address, uint32_t value) {
|
|||
break;
|
||||
}
|
||||
} else if(romx_unlocked == 3) {
|
||||
if((address & 0xFFF0) == 0xF810) {
|
||||
if((address >> 4) == 0xF81) {
|
||||
romx_textbank = address & 0xF;
|
||||
}
|
||||
if(address == 0xF851) {
|
||||
|
@ -237,10 +240,10 @@ void __time_critical_func(vga_businterface)(uint32_t address, uint32_t value) {
|
|||
break;
|
||||
}
|
||||
} else if(romx_unlocked == 3) {
|
||||
if((address & 0xFFF0) == 0xCFD0) {
|
||||
if((address >> 4) == 0xCFD) {
|
||||
romx_textbank = address & 0xF;
|
||||
}
|
||||
if((address & 0xFFF0) == 0xCFE0) {
|
||||
if((address >> 4) == 0xCFE) {
|
||||
romx_changed = 1;
|
||||
romx_unlocked = 0;
|
||||
}
|
||||
|
@ -268,6 +271,16 @@ void __time_critical_func(vga_businterface)(uint32_t address, uint32_t value) {
|
|||
} else {
|
||||
internal_flags &= ~IFLAGS_VIDEO7;
|
||||
}
|
||||
if(value & 2) {
|
||||
internal_flags |= IFLAGS_GRILL;
|
||||
} else {
|
||||
internal_flags &= ~IFLAGS_GRILL;
|
||||
}
|
||||
if(value & 1) {
|
||||
internal_flags |= IFLAGS_INTERP;
|
||||
} else {
|
||||
internal_flags &= ~IFLAGS_INTERP;
|
||||
}
|
||||
apple_memory[address] = value;
|
||||
break;
|
||||
case 0x02:
|
||||
|
@ -289,10 +302,12 @@ void __time_critical_func(vga_businterface)(uint32_t address, uint32_t value) {
|
|||
apple_memory[address] = (terminal_fifo_rdptr - terminal_fifo_wrptr);
|
||||
break;
|
||||
case 0x0B:
|
||||
#if 0
|
||||
if((value & 0xFF) <= 0x27) {
|
||||
romx_textbank = (value & 0xFF);
|
||||
romx_changed = 1;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case 0x0C:
|
||||
apple_memory[address] = value;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
18
vga/render.c
18
vga/render.c
|
@ -100,19 +100,21 @@ void DELAYED_COPY_CODE(update_status_left)(const char *str) {
|
|||
}
|
||||
|
||||
void DELAYED_COPY_CODE(render_init)() {
|
||||
int i;
|
||||
|
||||
switch_font();
|
||||
|
||||
// Initialize "Half-Palette" for aperture grill effect
|
||||
for(int i = 1; i < 15; i++) {
|
||||
half_palette[i] = (dhgr_palette[i] >> 1) & _RGBHALF;
|
||||
lhalf_palette[i] = (lores_palette[i] >> 1) & _RGBHALF;
|
||||
}
|
||||
half_palette[0] = dhgr_palette[0];
|
||||
half_palette[15] = dhgr_palette[15];
|
||||
lhalf_palette[0] = lores_palette[0];
|
||||
lhalf_palette[15] = lores_palette[15];
|
||||
|
||||
if((soft_switches & SOFTSW_MODE_MASK) == 0)
|
||||
internal_flags |= IFLAGS_TEST;
|
||||
|
||||
apple_tbcolor = 0xf0;
|
||||
apple_border = 0x00;
|
||||
|
||||
terminal_tbcolor = 0xf0;
|
||||
terminal_border = 0x00;
|
||||
|
||||
memcpy(terminal_character_rom, (void*)FLASH_VIDEX_BASE, 4096);
|
||||
memset(status_line, 0, sizeof(status_line));
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
// Uncomment to enable test patter generator
|
||||
#define RENDER_TEST_PATTERN
|
||||
|
||||
extern uint16_t lhalf_palette[16];
|
||||
extern uint16_t half_palette[16];
|
||||
extern uint16_t lores_palette[16];
|
||||
extern uint16_t dhgr_palette[16];
|
||||
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
//#define PAGE2SEL (!(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2))
|
||||
#define PAGE2SEL ((soft_switches & (SOFTSW_80STORE | SOFTSW_PAGE_2)) == SOFTSW_PAGE_2)
|
||||
|
||||
extern uint16_t dhgr_palette[16];
|
||||
|
||||
uint8_t DELAYED_COPY_DATA(dgr_dot_pattern)[32] = {
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x08, 0x19, 0x2A, 0x3B, 0x4C, 0x5D, 0x6E, 0x7F,
|
||||
|
@ -16,6 +14,11 @@ uint8_t DELAYED_COPY_DATA(dgr_dot_pattern)[32] = {
|
|||
0x22, 0x66, 0x2A, 0x6E, 0x33, 0x77, 0x3B, 0x7F,
|
||||
};
|
||||
|
||||
extern uint8_t lores_to_dhgr[16];
|
||||
uint8_t dhgr_to_lores[16] = {
|
||||
0,2,4,6,8,10,12,14,1,3,5,7,9,11,13,15
|
||||
};
|
||||
|
||||
static void render_dgr_line(bool p2, uint line);
|
||||
|
||||
void DELAYED_COPY_CODE(render_dgr)() {
|
||||
|
@ -59,9 +62,11 @@ static void DELAYED_COPY_CODE(render_dgr_line)(bool p2, uint line) {
|
|||
sl_pos++;
|
||||
|
||||
i = 0;
|
||||
color1 = 0;
|
||||
color2 = 0;
|
||||
if(mono_rendering) {
|
||||
while(i < 40) {
|
||||
while((dotc <= 18) && (i < 40)) {
|
||||
while((dotc <= 14) && (i < 40)) {
|
||||
color1 |= dgr_dot_pattern[((i & 1) << 4) | (line_bufb[i] & 0xf)] << dotc;
|
||||
color2 |= dgr_dot_pattern[((i & 1) << 4) | ((line_bufb[i] >> 4) & 0xf)] << dotc;
|
||||
dotc += 7;
|
||||
|
@ -88,28 +93,8 @@ static void DELAYED_COPY_CODE(render_dgr_line)(bool p2, uint line) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
// Preload the first 14 subpixels
|
||||
color1 = dgr_dot_pattern[line_bufb[i] & 0xf] << dotc;
|
||||
color2 = dgr_dot_pattern[(line_bufb[i] >> 4) & 0xf] << dotc;
|
||||
dotc += 7;
|
||||
color1 |= dgr_dot_pattern[(line_bufa[i] & 0xf)] << dotc;
|
||||
color2 |= dgr_dot_pattern[((line_bufa[i] >> 4) & 0xf)] << dotc;
|
||||
dotc += 7;
|
||||
i++;
|
||||
|
||||
// First two pixels
|
||||
pixeldata = dhgr_palette[0];
|
||||
pixeldata |= ((dhgr_palette[color1 & 0xf] >> 1) & _RGBHALF) << 16;
|
||||
sl1->data[sl_pos] = pixeldata;
|
||||
|
||||
pixeldata = dhgr_palette[0];
|
||||
pixeldata |= ((dhgr_palette[color1 & 0xf] >> 1) & _RGBHALF) << 16;
|
||||
sl2->data[sl_pos] = pixeldata;
|
||||
sl_pos++;
|
||||
|
||||
while(i < 40) {
|
||||
// Load in as many subpixels as possible
|
||||
while((dotc <= 18) && (i < 40)) {
|
||||
while((dotc <= 14) && (i < 40)) {
|
||||
color1 |= dgr_dot_pattern[((i & 1) << 4) | (line_bufb[i] & 0xf)] << dotc;
|
||||
color2 |= dgr_dot_pattern[((i & 1) << 4) | ((line_bufb[i] >> 4) & 0xf)] << dotc;
|
||||
dotc += 7;
|
||||
|
@ -120,43 +105,43 @@ static void DELAYED_COPY_CODE(render_dgr_line)(bool p2, uint line) {
|
|||
}
|
||||
|
||||
// Consume pixels
|
||||
while(dotc >= 8) {
|
||||
pixeldata = (dhgr_palette[color1 & 0xf]);
|
||||
pixeldata |= ((dhgr_palette[color1 & 0xf] >> 1) & _RGBHALF) << 16;
|
||||
while((dotc >= 8) || ((dotc > 0) && (i == 40))) {
|
||||
color1 &= 0xfffffffe;
|
||||
color1 |= (color1 >> 4) & 1;
|
||||
pixeldata = dhgr_palette[color1 & 0xf];
|
||||
color1 &= 0xfffffffc;
|
||||
color1 |= (color1 >> 4) & 3;
|
||||
pixeldata |= dhgr_palette[color1 & 0xf] << 16;
|
||||
sl1->data[sl_pos] = pixeldata;
|
||||
|
||||
pixeldata = (dhgr_palette[color2 & 0xf]);
|
||||
pixeldata |= ((dhgr_palette[color2 & 0xf] >> 1) & _RGBHALF) << 16;
|
||||
color2 &= 0xfffffffe;
|
||||
color2 |= (color2 >> 4) & 1;
|
||||
pixeldata = dhgr_palette[color2 & 0xf];
|
||||
color2 &= 0xfffffffc;
|
||||
color2 |= (color2 >> 4) & 3;
|
||||
pixeldata |= dhgr_palette[color2 & 0xf] << 16;
|
||||
sl2->data[sl_pos] = pixeldata;
|
||||
|
||||
sl_pos++;
|
||||
|
||||
pixeldata = (dhgr_palette[(color1 & 0xc) | ((color1 & 0x30) >> 4)]);
|
||||
pixeldata |= ((dhgr_palette[(color1 & 0xf0) >> 4] >> 1) & _RGBHALF) << 16;
|
||||
sl1->data[sl_pos] = pixeldata;
|
||||
|
||||
pixeldata = (dhgr_palette[(color2 & 0xc) | ((color2 & 0x30) >> 4)]);
|
||||
pixeldata |= ((dhgr_palette[(color2 & 0xf0) >> 4] >> 1) & _RGBHALF) << 16;
|
||||
sl2->data[sl_pos] = pixeldata;
|
||||
|
||||
|
||||
sl_pos++;
|
||||
|
||||
color1 &= 0xfffffff8;
|
||||
color1 |= (color1 >> 4) & 7;
|
||||
pixeldata = dhgr_palette[color1 & 0xf];
|
||||
color1 >>= 4;
|
||||
pixeldata |= dhgr_palette[color1 & 0xf] << 16;
|
||||
sl1->data[sl_pos] = pixeldata;
|
||||
|
||||
color2 &= 0xfffffff8;
|
||||
color2 |= (color2 >> 4) & 7;
|
||||
pixeldata = dhgr_palette[color2 & 0xf];
|
||||
color2 >>= 4;
|
||||
pixeldata |= dhgr_palette[color2 & 0xf] << 16;
|
||||
sl2->data[sl_pos] = pixeldata;
|
||||
|
||||
sl_pos++;
|
||||
dotc -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Last two pixels
|
||||
pixeldata = (dhgr_palette[color1 & 0xf]);
|
||||
pixeldata |= ((dhgr_palette[color1 & 0xf] >> 1) & _RGBHALF) << 16;
|
||||
sl1->data[sl_pos] = pixeldata;
|
||||
|
||||
pixeldata = (dhgr_palette[color2 & 0xf]);
|
||||
pixeldata |= ((dhgr_palette[color2 & 0xf] >> 1) & _RGBHALF) << 16;
|
||||
sl2->data[sl_pos] = pixeldata;
|
||||
|
||||
sl_pos++;
|
||||
}
|
||||
|
||||
// Pad 40 pixels on the right to center horizontally
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "vga/vgabuf.h"
|
||||
#include "vga/render.h"
|
||||
#include "vga/vgaout.h"
|
||||
#include "vga/dhgr_patterns.h"
|
||||
|
||||
static void render_dhgr_line(bool p2, uint line, bool mono);
|
||||
|
||||
|
@ -14,6 +15,7 @@ uint16_t DELAYED_COPY_DATA(dhgr_palette)[16] = {
|
|||
RGB_MAGENTA, RGB_HVIOLET, RGB_DGRAY, RGB_LBLUE,
|
||||
RGB_HORANGE, RGB_PINK, RGB_YELLOW, RGB_WHITE
|
||||
};
|
||||
uint16_t __attribute__((section(".uninitialized_data."))) half_palette[16];
|
||||
|
||||
//#define PAGE2SEL (!(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2))
|
||||
#define PAGE2SEL ((soft_switches & (SOFTSW_80STORE | SOFTSW_PAGE_2)) == SOFTSW_PAGE_2)
|
||||
|
@ -67,6 +69,9 @@ static void DELAYED_COPY_CODE(render_dhgr_line)(bool p2, uint line, bool mono) {
|
|||
uint32_t dots = 0;
|
||||
uint_fast8_t dotc = 0;
|
||||
uint32_t pixeldata;
|
||||
uint32_t pixelmode = 0;
|
||||
uint16_t white_pixel_count = 0;
|
||||
uint32_t color1, color2, color3, color4;
|
||||
|
||||
i = 0;
|
||||
if(mono) {
|
||||
|
@ -91,7 +96,6 @@ static void DELAYED_COPY_CODE(render_dhgr_line)(bool p2, uint line, bool mono) {
|
|||
}
|
||||
}
|
||||
} else if((internal_flags & IFLAGS_VIDEO7) && ((soft_switches & (SOFTSW_80STORE | SOFTSW_80COL)) == (SOFTSW_80STORE))) {
|
||||
uint32_t color1, color2, color3, color4;
|
||||
int j;
|
||||
|
||||
// Video 7 F/B HiRes
|
||||
|
@ -150,7 +154,118 @@ static void DELAYED_COPY_CODE(render_dhgr_line)(bool p2, uint line, bool mono) {
|
|||
dotc -= 8;
|
||||
}
|
||||
}
|
||||
} else if(internal_flags & IFLAGS_OLDCOLOR) {
|
||||
} else if((internal_flags & (IFLAGS_VIDEO7 | IFLAGS_V7_MODE3)) == (IFLAGS_VIDEO7 | IFLAGS_V7_MODE1)) {
|
||||
// Video-7 Mixed B&W/RGB
|
||||
while(i < 40) {
|
||||
// Load in as many subpixels as possible
|
||||
while((dotc <= 18) && (i < 40)) {
|
||||
dots |= (line_memb[i] & 0x7f) << dotc;
|
||||
pixelmode |= ((line_memb[i] & 0x80) ? 0x7f : 0x00) << dotc;
|
||||
dotc += 7;
|
||||
dots |= (line_mema[i] & 0x7f) << dotc;
|
||||
pixelmode |= ((line_mema[i] & 0x80) ? 0x7f : 0x00) << dotc;
|
||||
dotc += 7;
|
||||
i++;
|
||||
}
|
||||
|
||||
// Consume pixels
|
||||
while(dotc >= 4) {
|
||||
if(pixelmode) {
|
||||
pixeldata = (dhgr_palette[dots & 0xf] | THEN_EXTEND_1);
|
||||
pixeldata |= pixeldata << 16;
|
||||
dots >>= 4;
|
||||
pixelmode >>= 4;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
dotc -= 4;
|
||||
} else {
|
||||
pixeldata = ((dots & 1) ? (text_fore) : (text_back));
|
||||
dots >>= 1;
|
||||
pixelmode >>= 1;
|
||||
pixeldata |= (((dots & 1) ? (text_fore) : (text_back))) << 16;
|
||||
dots >>= 1;
|
||||
pixelmode >>= 1;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
dotc -= 2;
|
||||
pixeldata = ((dots & 1) ? (text_fore) : (text_back));
|
||||
dots >>= 1;
|
||||
pixelmode >>= 1;
|
||||
pixeldata |= (((dots & 1) ? (text_fore) : (text_back))) << 16;
|
||||
dots >>= 1;
|
||||
pixelmode >>= 1;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
dotc -= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if((internal_flags & (IFLAGS_INTERP | IFLAGS_GRILL)) == (IFLAGS_INTERP | IFLAGS_GRILL)) {
|
||||
// Preload black into the sliding window
|
||||
dots = 0;
|
||||
dotc = 4;
|
||||
|
||||
while(i < 40) {
|
||||
// Load in as many subpixels as possible
|
||||
while((dotc <= 18) && (i < 40)) {
|
||||
dots |= (line_memb[i] & 0x7f) << dotc;
|
||||
dotc += 7;
|
||||
dots |= (line_mema[i] & 0x7f) << dotc;
|
||||
dotc += 7;
|
||||
i++;
|
||||
}
|
||||
|
||||
while((dotc >= 8) || ((dotc > 0) && (i == 40))) {
|
||||
dots &= 0xfffffffe;
|
||||
dots |= (dots >> 4) & 1;
|
||||
pixeldata = half_palette[dots & 0xf];
|
||||
dots &= 0xfffffffc;
|
||||
dots |= (dots >> 4) & 3;
|
||||
pixeldata |= dhgr_palette[dots & 0xf] << 16;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
|
||||
dots &= 0xfffffff8;
|
||||
dots |= (dots >> 4) & 7;
|
||||
pixeldata = half_palette[dots & 0xf];
|
||||
dots >>= 4;
|
||||
pixeldata |= dhgr_palette[dots & 0xf] << 16;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
|
||||
dotc -= 4;
|
||||
}
|
||||
}
|
||||
} else if(internal_flags & IFLAGS_INTERP) {
|
||||
// Preload black into the sliding window
|
||||
dots = 0;
|
||||
dotc = 4;
|
||||
|
||||
while(i < 40) {
|
||||
// Load in as many subpixels as possible
|
||||
while((dotc <= 18) && (i < 40)) {
|
||||
dots |= (line_memb[i] & 0x7f) << dotc;
|
||||
dotc += 7;
|
||||
dots |= (line_mema[i] & 0x7f) << dotc;
|
||||
dotc += 7;
|
||||
i++;
|
||||
}
|
||||
|
||||
while((dotc >= 8) || ((dotc > 0) && (i == 40))) {
|
||||
dots &= 0xfffffffe;
|
||||
dots |= (dots >> 4) & 1;
|
||||
pixeldata = dhgr_palette[dots & 0xf];
|
||||
dots &= 0xfffffffc;
|
||||
dots |= (dots >> 4) & 3;
|
||||
pixeldata |= dhgr_palette[dots & 0xf] << 16;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
|
||||
dots &= 0xfffffff8;
|
||||
dots |= (dots >> 4) & 7;
|
||||
pixeldata = dhgr_palette[dots & 0xf];
|
||||
dots >>= 4;
|
||||
pixeldata |= dhgr_palette[dots & 0xf] << 16;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
|
||||
dotc -= 4;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while(i < 40) {
|
||||
// Load in as many subpixels as possible
|
||||
while((dotc <= 18) && (i < 40)) {
|
||||
|
@ -171,46 +286,6 @@ static void DELAYED_COPY_CODE(render_dhgr_line)(bool p2, uint line, bool mono) {
|
|||
dotc -= 8;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Preload the first 14 subpixels
|
||||
dots |= (line_memb[i] & 0x7f) << dotc;
|
||||
dotc += 7;
|
||||
dots |= (line_mema[i] & 0x7f) << dotc;
|
||||
dotc += 7;
|
||||
i++;
|
||||
|
||||
// First two pixels
|
||||
pixeldata = dhgr_palette[0];
|
||||
pixeldata |= ((dhgr_palette[dots & 0xf] >> 1) & _RGBHALF) << 16;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
|
||||
while(i < 40) {
|
||||
// Load in as many subpixels as possible
|
||||
while((dotc <= 18) && (i < 40)) {
|
||||
dots |= (line_memb[i] & 0x7f) << dotc;
|
||||
dotc += 7;
|
||||
dots |= (line_mema[i] & 0x7f) << dotc;
|
||||
dotc += 7;
|
||||
i++;
|
||||
}
|
||||
|
||||
// Consume pixels
|
||||
while(dotc >= 8) {
|
||||
pixeldata = (dhgr_palette[dots & 0xf]);
|
||||
pixeldata |= ((dhgr_palette[dots & 0xf] >> 1) & _RGBHALF) << 16;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
pixeldata = (dhgr_palette[(dots & 0xc) | ((dots & 0x30) >> 4)]);
|
||||
pixeldata |= ((dhgr_palette[(dots & 0xf0) >> 4] >> 1) & _RGBHALF) << 16;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
dots >>= 4;
|
||||
dotc -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Last two pixels
|
||||
pixeldata = (dhgr_palette[dots & 0xf]);
|
||||
pixeldata |= ((dhgr_palette[dots & 0xf] >> 1) & _RGBHALF) << 16;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
}
|
||||
|
||||
if((internal_flags & IFLAGS_VIDEO7) && ((internal_flags & IFLAGS_V7_MODE3) == IFLAGS_V7_MODE2)) {
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
|
||||
//#define PAGE2SEL (!(soft_switches & SOFTSW_80STORE) && (soft_switches & SOFTSW_PAGE_2))
|
||||
#define PAGE2SEL ((soft_switches & (SOFTSW_80STORE | SOFTSW_PAGE_2)) == SOFTSW_PAGE_2)
|
||||
uint16_t __attribute__((section(".uninitialized_data."))) lhalf_palette[16];
|
||||
|
||||
static void render_hires_line(bool p2, uint line);
|
||||
|
||||
|
@ -66,7 +67,7 @@ static void DELAYED_COPY_CODE(render_hires_line)(bool p2, uint line) {
|
|||
dotc -= 2;
|
||||
}
|
||||
}
|
||||
} else if(internal_flags & IFLAGS_OLDCOLOR) {
|
||||
} else {
|
||||
// Each hires byte contains 7 pixels which may be shifted right 1/2 a pixel. That is
|
||||
// represented here by 14 'dots' to precisely describe the half-pixel positioning.
|
||||
//
|
||||
|
@ -109,44 +110,6 @@ static void DELAYED_COPY_CODE(render_hires_line)(bool p2, uint line) {
|
|||
oddness ^= 0x100;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Preload the first 14 subpixels
|
||||
dots = (hires_dot_patterns2[line_mem[i]]);
|
||||
lastmsb = (dotc>0) ? ((line_mem[i] & 0x40)<<2) : 0;
|
||||
i++;
|
||||
dotc = 14;
|
||||
|
||||
// First two pixels
|
||||
pixeldata = lores_palette[0];
|
||||
pixeldata |= ((lores_palette[dots & 0xf] >> 1) & _RGBHALF) << 16;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
|
||||
while(i < 40) {
|
||||
// Load in as many subpixels as possible
|
||||
if((dotc < 18) && (i < 40)) {
|
||||
dots |= (hires_dot_patterns2[lastmsb | line_mem[i]]) << dotc;
|
||||
lastmsb = (dotc>0) ? ((line_mem[i] & 0x40)<<2) : 0;
|
||||
i++;
|
||||
dotc += 14;
|
||||
}
|
||||
|
||||
// Consume pixels
|
||||
while(dotc >= 8) {
|
||||
pixeldata = (lores_palette[dots & 0xf]);
|
||||
pixeldata |= ((lores_palette[dots & 0xf] >> 1) & _RGBHALF) << 16;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
pixeldata = (lores_palette[(dots & 0xc) | ((dots & 0x30) >> 4)]);
|
||||
pixeldata |= ((lores_palette[(dots & 0xf0) >> 4] >> 1) & _RGBHALF) << 16;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
dots >>= 4;
|
||||
dotc -= 4;
|
||||
}
|
||||
}
|
||||
|
||||
// Last two pixels
|
||||
pixeldata = (lores_palette[dots & 0xf]);
|
||||
pixeldata |= ((lores_palette[dots & 0xf] >> 1) & _RGBHALF) << 16;
|
||||
sl->data[sl_pos++] = pixeldata;
|
||||
}
|
||||
|
||||
// Pad 40 pixels on the right to center horizontally
|
||||
|
|
|
@ -17,9 +17,6 @@ extern uint8_t terminal_fifo_rdptr;
|
|||
extern volatile uint8_t terminal_row;
|
||||
extern volatile uint8_t terminal_col;
|
||||
|
||||
#define apple_tbcolor apple_memory[0xC022]
|
||||
#define apple_border apple_memory[0xC034]
|
||||
|
||||
#define APPLE_FORE ((apple_tbcolor>>4) & 0xf)
|
||||
#define APPLE_BACK (apple_tbcolor & 0xf)
|
||||
#define APPLE_BORDER (apple_border & 0xf)
|
||||
|
|
Loading…
Reference in New Issue