Updates for tranZPUter SW
This commit is contained in:
@@ -99,15 +99,21 @@ static t_asciiMap asciiMap[] = {
|
||||
{ 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 }, { 0x20 } // 0XFF
|
||||
};
|
||||
|
||||
// This method is called everytime an active irq triggers on Port D. For this design, this means the IORQ line.
|
||||
// Store all the ports as they are needed to capture the Address and Data of the asserted z80 I/O transaction.
|
||||
// This method is called everytime an active irq triggers on Port E. For this design, this means the two IO CS
|
||||
// lines, TZ_SVCREQ and TZ_SYSREQ. The SVCREQ is used when the Z80 requires a service, the SYSREQ is yet to
|
||||
// be utilised.
|
||||
//
|
||||
static void __attribute((naked, noinline)) irqPortD(void)
|
||||
//
|
||||
static void __attribute((naked, noinline)) irqPortE(void)
|
||||
{
|
||||
// Save register we use.
|
||||
asm volatile ("push {r0-r6,lr}");
|
||||
|
||||
// Short circuit interrupt when not needed.
|
||||
//asm volatile goto("b %l0" :::: irqPortE_Exit);
|
||||
|
||||
// Capture GPIO ports - this is necessary in order to make a clean capture and then decode.
|
||||
#if DECODE_Z80_IO == 1
|
||||
asm volatile ("ldr r5, =0x400ff010"); // GPIOA_PDIR
|
||||
asm volatile ("ldr r0, [r5, #0]");
|
||||
asm volatile ("ldr r5, =0x400ff050"); // GPIOB_PDIR
|
||||
@@ -116,15 +122,76 @@ static void __attribute((naked, noinline)) irqPortD(void)
|
||||
asm volatile ("ldr r2, [r5, #0]");
|
||||
asm volatile ("ldr r5, =0x400ff0d0"); // GPIOD_PDIR
|
||||
asm volatile ("ldr r3, [r5, #0]");
|
||||
#endif
|
||||
asm volatile ("ldr r5, =0x400ff110"); // GPIOE_PDIR
|
||||
asm volatile ("ldr r4, [r5, #0]");
|
||||
|
||||
// Now save the GPIO values into the structure.
|
||||
#if DECODE_Z80_IO == 1
|
||||
asm volatile ("str r0, %0" : "+m" (z80Control.portA) :: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12");
|
||||
asm volatile ("str r1, %0" : "+m" (z80Control.portB) :: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12");
|
||||
asm volatile ("str r2, %0" : "+m" (z80Control.portC) :: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12");
|
||||
asm volatile ("str r3, %0" : "+m" (z80Control.portD) :: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12");
|
||||
asm volatile ("str r4, %0" : "+m" (z80Control.portE) :: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12");
|
||||
#endif
|
||||
|
||||
// Is TZ_SVCREQ (E10) active (low), set flag and exit if it is.
|
||||
asm volatile ("movs r3, #1");
|
||||
asm volatile ("ror r4, r4, #11" );
|
||||
asm volatile goto("bmi %l0" ::: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12" : ebr0);
|
||||
asm volatile ("strb r3, %0" : "+m" (z80Control.svcRequest) :: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12");
|
||||
|
||||
ebr0:
|
||||
// Is TZ_SYSREQ (E11) active (low), set flag and exit if it is.
|
||||
asm volatile ("rrx r4, r4" );
|
||||
asm volatile goto("bcs %l0" ::: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12" : irqPortE_Exit);
|
||||
asm volatile ("strb r3, %0" : "+m" (z80Control.sysRequest) :: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12");
|
||||
|
||||
irqPortE_Exit:
|
||||
// Reset the interrupt, PORTE_ISFR <= PORTE_ISFR
|
||||
asm volatile ("ldr r3, =0x4004d0a0");
|
||||
asm volatile ("ldr r2, [r3, #0]");
|
||||
asm volatile ("str r2, [r3, #0]");
|
||||
|
||||
asm volatile ("pop {r0-r6,pc}");
|
||||
return;
|
||||
}
|
||||
|
||||
// This method is called everytime an active irq triggers on Port D. For this design, this means the IORQ line.
|
||||
// Store all the ports as they are needed to capture the Address and Data of the asserted z80 I/O transaction.
|
||||
//
|
||||
static void __attribute((naked, noinline)) irqPortD(void)
|
||||
{
|
||||
// Save register we use.
|
||||
asm volatile ("push {r0-r6,lr}");
|
||||
|
||||
// Short circuit interrupt when not needed.
|
||||
//asm volatile goto("b %l0" :::: irqPortC_Exit);
|
||||
|
||||
// Capture GPIO ports - this is necessary in order to make a clean capture and then decode.
|
||||
#if DECODE_Z80_IO == 1
|
||||
asm volatile ("ldr r5, =0x400ff010"); // GPIOA_PDIR
|
||||
asm volatile ("ldr r0, [r5, #0]");
|
||||
asm volatile ("ldr r5, =0x400ff050"); // GPIOB_PDIR
|
||||
asm volatile ("ldr r1, [r5, #0]");
|
||||
asm volatile ("ldr r5, =0x400ff090"); // GPIOC_PDIR
|
||||
asm volatile ("ldr r2, [r5, #0]");
|
||||
#endif
|
||||
asm volatile ("ldr r5, =0x400ff0d0"); // GPIOD_PDIR
|
||||
asm volatile ("ldr r3, [r5, #0]");
|
||||
#if DECODE_Z80_IO == 1
|
||||
asm volatile ("ldr r5, =0x400ff110"); // GPIOE_PDIR
|
||||
asm volatile ("ldr r4, [r5, #0]");
|
||||
#endif
|
||||
|
||||
// Now save the GPIO values into the structure.
|
||||
#if DECODE_Z80_IO == 1
|
||||
asm volatile ("str r0, %0" : "+m" (z80Control.portA) :: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12");
|
||||
asm volatile ("str r1, %0" : "+m" (z80Control.portB) :: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12");
|
||||
asm volatile ("str r2, %0" : "+m" (z80Control.portC) :: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12");
|
||||
asm volatile ("str r3, %0" : "+m" (z80Control.portD) :: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12");
|
||||
asm volatile ("str r4, %0" : "+m" (z80Control.portE) :: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12");
|
||||
#endif
|
||||
|
||||
// Is Z80_RESET active, set flag and exit.
|
||||
asm volatile ("lsls r5, r3, #16" );
|
||||
@@ -134,6 +201,7 @@ static void __attribute((naked, noinline)) irqPortD(void)
|
||||
asm volatile goto("b %l0" :::: irqPortD_Exit);
|
||||
|
||||
cbr0:
|
||||
#if DECODE_Z80_IO == 1
|
||||
// Convert lower 8 address bits into a byte and store.
|
||||
asm volatile ("lsrs r3, r1, #4"); // (z80Control.portB >> 4)&0x80)
|
||||
asm volatile ("and.w r3, r3, #128");
|
||||
@@ -160,9 +228,9 @@ cbr0:
|
||||
asm volatile ("orrs r3, r5");
|
||||
|
||||
// Ignore IO requests which arent service related.
|
||||
asm volatile ("movw r5, " XSTR(IO_TZ_SVCREQ) "");
|
||||
asm volatile ("cmp r3, r5");
|
||||
asm volatile goto("bne %l0" :::: irqPortD_Exit);
|
||||
//asm volatile ("movw r5, " XSTR(IO_TZ_SVCREQ) "");
|
||||
//asm volatile ("cmp r3, r5");
|
||||
//asm volatile goto("bne %l0" :::: irqPortD_Exit);
|
||||
|
||||
// Not memory mode so store the address.
|
||||
asm volatile ("str r3, %0" : "=m" (z80Control.ioAddr) :: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12");
|
||||
@@ -197,6 +265,7 @@ cbr0:
|
||||
// Process the IO request by setting the ioEvent flag.
|
||||
asm volatile ("movs r3, #1");
|
||||
asm volatile ("str r3, %0" : "=m" (z80Control.ioEvent) :: "r0","r1","r2","r3","r4","r5","r7","r8","r9","r10","r11","r12");
|
||||
#endif
|
||||
|
||||
irqPortD_Exit:
|
||||
// Reset the interrupt, PORTD_ISFR <= PORTD_ISFR
|
||||
@@ -217,8 +286,9 @@ static void __attribute((naked, noinline)) irqPortC(void)
|
||||
asm volatile ("push {r0-r6,lr}");
|
||||
|
||||
// Short circuit interrupt when not needed.
|
||||
asm volatile goto("b %l0" :::: irqPortC_Exit);
|
||||
//asm volatile goto("b %l0" :::: irqPortC_Exit);
|
||||
|
||||
#if DECODE_Z80_IO == 1
|
||||
// Capture GPIO ports - this is necessary in order to make a clean capture and then decode.
|
||||
asm volatile ("ldr r5, =0x400ff010"); // GPIOA_PDIR
|
||||
asm volatile ("ldr r0, [r5, #0]");
|
||||
@@ -356,6 +426,8 @@ br5:
|
||||
asm volatile ("strb r0, %0" : "+m" (z80Control.scroll) :: "r0");
|
||||
|
||||
irqPortC_Exit:
|
||||
#endif
|
||||
|
||||
// Reset the interrupt, PORTC_ISFR <= PORTC_ISFR
|
||||
asm volatile ("ldr r3, =0x4004b0a0");
|
||||
asm volatile ("ldr r2, [r3, #0]");
|
||||
@@ -370,19 +442,30 @@ irqPortC_Exit:
|
||||
//
|
||||
static void setupIRQ(void)
|
||||
{
|
||||
__disable_irq();
|
||||
__disable_irq();
|
||||
// Install the method to be called when PortE triggers.
|
||||
_VectorsRam[IRQ_PORTE + 16] = irqPortE;
|
||||
|
||||
// Install the method to be called when PortD triggers.
|
||||
_VectorsRam[IRQ_PORTD + 16] = irqPortD;
|
||||
|
||||
// Install the method to be called when PortC triggers.
|
||||
_VectorsRam[IRQ_PORTC + 16] = irqPortC;
|
||||
__enable_irq();
|
||||
__enable_irq();
|
||||
|
||||
// Setup the IRQ for TZ_SVCREQ.
|
||||
installIRQ(TZ_SVCREQ, IRQ_MASK_FALLING);
|
||||
|
||||
// Setup the IRQ for TZ_SYSREQ.
|
||||
installIRQ(TZ_SYSREQ, IRQ_MASK_FALLING);
|
||||
|
||||
#if DECODE_Z80_IO == 1
|
||||
// Setup the IRQ for Z80_IORQ.
|
||||
installIRQ(Z80_IORQ, IRQ_MASK_FALLING);
|
||||
|
||||
// Setup the IRQ for Z80_MREQ.
|
||||
//installIRQ(Z80_MREQ, IRQ_MASK_FALLING);
|
||||
installIRQ(Z80_MREQ, IRQ_MASK_FALLING);
|
||||
#endif
|
||||
|
||||
// Setup the IRQ for Z80_RESET.
|
||||
installIRQ(Z80_RESET, IRQ_MASK_FALLING);
|
||||
@@ -392,11 +475,19 @@ static void setupIRQ(void)
|
||||
//
|
||||
static void restoreIRQ(void)
|
||||
{
|
||||
// Setup the IRQ for TZ_SVCREQ.
|
||||
installIRQ(TZ_SVCREQ, IRQ_MASK_FALLING);
|
||||
|
||||
// Setup the IRQ for TZ_SYSREQ.
|
||||
installIRQ(TZ_SYSREQ, IRQ_MASK_FALLING);
|
||||
|
||||
#if DECODE_Z80_IO == 1
|
||||
// Setup the IRQ for Z80_IORQ.
|
||||
installIRQ(Z80_IORQ, IRQ_MASK_FALLING);
|
||||
|
||||
// Setup the IRQ for Z80_MREQ.
|
||||
installIRQ(Z80_MREQ, IRQ_MASK_FALLING);
|
||||
#endif
|
||||
|
||||
// Setup the IRQ for Z80_RESET.
|
||||
installIRQ(Z80_RESET, IRQ_MASK_FALLING);
|
||||
@@ -417,7 +508,6 @@ void setupZ80Pins(uint8_t initTeensy, volatile uint32_t *millisecondTick)
|
||||
//
|
||||
if(firstCall == 1)
|
||||
{
|
||||
printf("FirstCall\n");
|
||||
if(initTeensy)
|
||||
_init_Teensyduino_internal_();
|
||||
|
||||
@@ -474,6 +564,8 @@ printf("FirstCall\n");
|
||||
pinMap[Z80_RESET] = Z80_RESET_PIN;
|
||||
pinMap[MB_SYSCLK] = SYSCLK_PIN;
|
||||
pinMap[TZ_BUSACK] = TZ_BUSACK_PIN;
|
||||
pinMap[TZ_SVCREQ] = TZ_SVCREQ_PIN;
|
||||
pinMap[TZ_SYSREQ] = TZ_SYSREQ_PIN;
|
||||
|
||||
pinMap[CTL_BUSACK] = CTL_BUSACK_PIN;
|
||||
pinMap[CTL_BUSRQ] = CTL_BUSRQ_PIN;
|
||||
@@ -526,12 +618,16 @@ printf("FirstCall\n");
|
||||
// Control structure elements only in zOS.
|
||||
//
|
||||
z80Control.resetEvent = 0;
|
||||
z80Control.svcRequest = 0;
|
||||
z80Control.sysRequest = 0;
|
||||
#if DECODE_Z80_IO == 1
|
||||
z80Control.ioAddr = 0;
|
||||
z80Control.ioData = 0;
|
||||
z80Control.ioEvent = 0;
|
||||
z80Control.memorySwap = 0;
|
||||
z80Control.crtMode = 0;
|
||||
z80Control.scroll = 0;
|
||||
#endif
|
||||
|
||||
// Setup the Interrupts for IORQ and MREQ.
|
||||
setupIRQ();
|
||||
@@ -1857,23 +1953,33 @@ uint8_t isZ80Reset(void)
|
||||
// Method to test to see if the main memory has been swapped from 0000-0FFF to C000-CFFF
|
||||
uint8_t isZ80MemorySwapped(void)
|
||||
{
|
||||
#if DECODE_Z80_IO == 1
|
||||
// Return the value which would have been updated in the interrupt routine.
|
||||
return(z80Control.memorySwap == 1);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Method to get an IO instruction event should one have occurred since last poll.
|
||||
//
|
||||
uint8_t getZ80IO(uint8_t *addr, uint8_t *data)
|
||||
uint8_t getZ80IO(uint8_t *addr)
|
||||
{
|
||||
// Locals.
|
||||
uint8_t retcode = z80Control.ioEvent;
|
||||
uint8_t retcode = 1;
|
||||
|
||||
// Load up the variables if an event has occurred.
|
||||
if(retcode == 1)
|
||||
if(z80Control.svcRequest == 1)
|
||||
{
|
||||
*addr = z80Control.ioAddr;
|
||||
*data = z80Control.ioData;
|
||||
z80Control.ioEvent = 0;
|
||||
*addr = IO_TZ_SVCREQ;
|
||||
z80Control.svcRequest = 0;
|
||||
} else
|
||||
if(z80Control.sysRequest == 1)
|
||||
{
|
||||
*addr = IO_TZ_SYSREQ;
|
||||
z80Control.sysRequest = 0;
|
||||
} else
|
||||
{
|
||||
retcode = 0;
|
||||
}
|
||||
|
||||
return(retcode);
|
||||
@@ -2022,11 +2128,7 @@ static uint32_t getNextChar(const char** ptr)
|
||||
uint8_t chr;
|
||||
|
||||
// Get a byte
|
||||
do {
|
||||
chr = (uint8_t)*(*ptr)++;
|
||||
|
||||
// Skip over CR.
|
||||
} while(chr == 0x0D);
|
||||
chr = (uint8_t)*(*ptr)++;
|
||||
|
||||
// To upper ASCII char
|
||||
if(islower(chr)) chr -= 0x20;
|
||||
@@ -2091,6 +2193,9 @@ static int matchFileWithWildcard(const char *pattern, const char *fileName, int
|
||||
// Get a name char
|
||||
nc = getNextChar(&np);
|
||||
|
||||
// Sharp uses null or CR to terminate a pattern and a filename, which is not determinate!
|
||||
if((pc == 0x00 || pc == 0x0d) && (nc == 0x00 || nc == 0x0d)) return 1;
|
||||
|
||||
// Branch mismatched?
|
||||
if (pc != nc) break;
|
||||
|
||||
@@ -2102,7 +2207,7 @@ static int matchFileWithWildcard(const char *pattern, const char *fileName, int
|
||||
getNextChar(&fileName);
|
||||
|
||||
/* Retry until end of name if infinite search is specified */
|
||||
} while (infinite && nc != 0x00 && nc != 0x0d);
|
||||
} while (infinite && nc != 0x00 && nc != 0x0d && (np - fileName) < MZF_FILENAME_LEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
// Configurable constants.
|
||||
//
|
||||
#define DECODE_Z80_IO 0 // Flag to enable code, via interrupt, to capture Z80 actions on I/O ports an Memory mapped I/O.
|
||||
#define REFRESH_BYTE_COUNT 8 // This constant controls the number of bytes read/written to the z80 bus before a refresh cycle is needed.
|
||||
#define RFSH_BYTE_CNT 256 // Number of bytes we can write before needing a full refresh for the DRAM.
|
||||
|
||||
@@ -65,6 +66,7 @@
|
||||
#define IO_TZ_SET2MHZ 0x64 // Switch to system CPU frequency.
|
||||
#define IO_TZ_CLKSELRD 0x66 // Read the status of the clock select, ie. which clock is connected to the CPU.
|
||||
#define IO_TZ_SVCREQ 0x68 // Service request from the Z80 to be provided by the K64F.
|
||||
#define IO_TZ_SYSREQ 0x6A // System request from the Z80 to be provided by the K64F.
|
||||
|
||||
// Sharp MZ80A constants.
|
||||
//
|
||||
@@ -129,8 +131,8 @@
|
||||
#define TZSVC_DEFAULT_EXT "MZF" // Default file extension for MZF files.
|
||||
#define TZSVC_DEFAULT_WILDCARD "*" // Default wildcard file matching.
|
||||
#define TZSVC_RESULT_OFFSET 0x01 // Offset into structure of the result byte.
|
||||
#define TZSVC_DIRNAME_SIZE 8 // Limit is size of FAT32 directory name.
|
||||
#define TZSVC_WILDCARD_SIZE 8 // Very basic pattern matching so small size.
|
||||
#define TZSVC_DIRNAME_SIZE 20 // Limit is size of FAT32 directory name.
|
||||
#define TZSVC_WILDCARD_SIZE 20 // Very basic pattern matching so small size.
|
||||
#define TZSVC_FILENAME_SIZE MZF_FILENAME_LEN // Length of a Sharp MZF filename.
|
||||
#define TZSVC_SECTOR_SIZE 512 // SD Card sector buffer size.
|
||||
#define TZSVC_STATUS_OK 0x00 // Flag to indicate the K64F processing completed successfully.
|
||||
@@ -155,7 +157,7 @@
|
||||
|
||||
// Pin Constants - Pins assigned at the hardware level to specific tasks/signals.
|
||||
//
|
||||
#define MAX_TRANZPUTER_PINS 50
|
||||
#define MAX_TRANZPUTER_PINS 52
|
||||
#define Z80_MEM0_PIN 46
|
||||
#define Z80_MEM1_PIN 47
|
||||
#define Z80_MEM2_PIN 48
|
||||
@@ -206,6 +208,8 @@
|
||||
#define CTL_CLK_PIN 14
|
||||
#define CTL_CLKSLCT_PIN 19
|
||||
#define TZ_BUSACK_PIN 55
|
||||
#define TZ_SVCREQ_PIN 56
|
||||
#define TZ_SYSREQ_PIN 57
|
||||
|
||||
// IRQ mask values for the different types of IRQ trigger.
|
||||
//
|
||||
@@ -348,14 +352,16 @@ enum pinIdxToPinNumMap {
|
||||
Z80_RESET = 40,
|
||||
MB_SYSCLK = 41,
|
||||
TZ_BUSACK = 42,
|
||||
TZ_SVCREQ = 43,
|
||||
TZ_SYSREQ = 44,
|
||||
|
||||
CTL_BUSACK = 43,
|
||||
CTL_BUSRQ = 44,
|
||||
CTL_RFSH = 45,
|
||||
CTL_HALT = 46,
|
||||
CTL_M1 = 47,
|
||||
CTL_CLK = 48,
|
||||
CTL_CLKSLCT = 49
|
||||
CTL_BUSACK = 45,
|
||||
CTL_BUSRQ = 46,
|
||||
CTL_RFSH = 47,
|
||||
CTL_HALT = 48,
|
||||
CTL_M1 = 49,
|
||||
CTL_CLK = 50,
|
||||
CTL_CLKSLCT = 51
|
||||
};
|
||||
|
||||
// Possible control modes that the K64F can be in, do nothing where the Z80 runs normally, control the Z80 and mainboard, or control the Z80 and tranZPUter.
|
||||
@@ -449,6 +455,9 @@ typedef struct {
|
||||
enum BUS_DIRECTION busDir; // Direction the bus has been configured for.
|
||||
|
||||
uint8_t resetEvent; // A Z80_RESET event occurred, probably user pressing RESET button.
|
||||
uint8_t svcRequest; // A service request has been made by the Z80 (1).
|
||||
uint8_t sysRequest; // A system request has been made by the Z80 (1).
|
||||
#if DECODE_Z80_IO == 1
|
||||
uint8_t ioAddr; // Address of a Z80 IO instruction.
|
||||
uint8_t ioData; // Data of a Z80 IO instruction.
|
||||
uint8_t ioEvent; // Event flag to indicate that an IO instruction was captured.
|
||||
@@ -458,6 +467,7 @@ typedef struct {
|
||||
volatile uint32_t portA; // ISR store of GPIO Port A used for signal decoding.
|
||||
volatile uint32_t portB; // ISR store of GPIO Port B used for signal decoding.
|
||||
volatile uint32_t portC; // ISR store of GPIO Port C used for signal decoding.
|
||||
#endif
|
||||
volatile uint32_t portD; // ISR store of GPIO Port D used for signal decoding.
|
||||
volatile uint32_t portE; // ISR store of GPIO Port E used for signal decoding.
|
||||
#endif
|
||||
@@ -566,7 +576,7 @@ FRESULT loadMZFZ80Memory(const char *, uint32_t, uint8_t, uint8_t);
|
||||
// Getter/Setter methods!
|
||||
uint8_t isZ80Reset(void);
|
||||
uint8_t isZ80MemorySwapped(void);
|
||||
uint8_t getZ80IO(uint8_t *, uint8_t *);
|
||||
uint8_t getZ80IO(uint8_t *);
|
||||
void clearZ80Reset(void);
|
||||
void convertSharpFilenameToAscii(char *, char *, uint8_t);
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -239,7 +239,6 @@ void tranZPUterControl(void)
|
||||
{
|
||||
// Locals.
|
||||
uint8_t ioAddr;
|
||||
uint8_t ioData;
|
||||
|
||||
// Loop waiting on events and processing.
|
||||
//
|
||||
@@ -262,12 +261,8 @@ void tranZPUterControl(void)
|
||||
|
||||
// Has there been an IO instruction for a service request?
|
||||
//
|
||||
if(getZ80IO(&ioAddr, &ioData) == 1)
|
||||
if(getZ80IO(&ioAddr) == 1)
|
||||
{
|
||||
// Interrupt triggering has artifcats, ignore them!
|
||||
if(ioData == 0xff)
|
||||
continue;
|
||||
|
||||
switch(ioAddr)
|
||||
{
|
||||
// Service request. Actual data about the request is stored in the Z80 memory, so read the request and process.
|
||||
|
||||
Reference in New Issue
Block a user