Adding MZ-1500 host
This commit is contained in:
BIN
software/FusionX/bin/k64fcpu
vendored
BIN
software/FusionX/bin/k64fcpu
vendored
Binary file not shown.
BIN
software/FusionX/bin/sharpbiter
vendored
BIN
software/FusionX/bin/sharpbiter
vendored
Binary file not shown.
BIN
software/FusionX/bin/z80ctrl
vendored
BIN
software/FusionX/bin/z80ctrl
vendored
Binary file not shown.
BIN
software/FusionX/modules/ttymzdrv.ko
vendored
BIN
software/FusionX/modules/ttymzdrv.ko
vendored
Binary file not shown.
BIN
software/FusionX/modules/z80drv.ko
vendored
BIN
software/FusionX/modules/z80drv.ko
vendored
Binary file not shown.
5
software/FusionX/src/ttymz/Makefile
vendored
5
software/FusionX/src/ttymz/Makefile
vendored
@@ -1,5 +1,6 @@
|
||||
# Select the target host.
|
||||
#MODEL := MZ2000
|
||||
#MODEL := MZ1500
|
||||
#MODEL := MZ700
|
||||
#MODEL := MZ80A
|
||||
#MODEL := PCW8XXX
|
||||
@@ -26,6 +27,7 @@ all:
|
||||
|
||||
MZ80A: MODEL_MZ80A
|
||||
MZ700: MODEL_MZ700
|
||||
MZ1500: MODEL_MZ1500
|
||||
MZ2000: MODEL_MZ2000
|
||||
PCW8XXX: MODEL_PCW8XXX
|
||||
PCW9XXX: MODEL_PCW9XXX
|
||||
@@ -34,6 +36,8 @@ MODEL_MZ80A:
|
||||
$(MAKE) MODEL=MZ80A BUILD_MZ80A
|
||||
MODEL_MZ700:
|
||||
$(MAKE) MODEL=MZ700 BUILD_MZ700
|
||||
MODEL_MZ1500:
|
||||
$(MAKE) MODEL=MZ1500 BUILD_MZ1500
|
||||
MODEL_MZ2000:
|
||||
$(MAKE) MODEL=MZ2000 BUILD_MZ2000
|
||||
MODEL_PCW8XXX:
|
||||
@@ -43,6 +47,7 @@ MODEL_PCW9XXX:
|
||||
|
||||
BUILD_MZ80A: kmod
|
||||
BUILD_MZ700: kmod
|
||||
BUILD_MZ1500: kmod
|
||||
BUILD_MZ2000: kmod
|
||||
BUILD_PCW8XXX: kmod
|
||||
BUILD_PCW9XXX: kmod
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
72
software/FusionX/src/ttymz/sharpmz.h
vendored
72
software/FusionX/src/ttymz/sharpmz.h
vendored
@@ -12,6 +12,8 @@
|
||||
// Copyright: (c) 2019-2023 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: v1.0 Feb 2023 - Initial write of the Sharp MZ series hardware interface software.
|
||||
// v1.01 Mar 2023 - Bug fixes and additional ESC sequence processing.
|
||||
// v1.02 May 2023 - Updates to accommodate MZ-1500 host.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -37,36 +39,47 @@
|
||||
#endif
|
||||
|
||||
// Build time target. Overrides if compile time definition given.
|
||||
#if defined(TARGET_HOST_MZ700)
|
||||
#define TARGET_HOST_MZ700 1
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ2000)
|
||||
#define TARGET_HOST_MZ2000 1
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ80A)
|
||||
#if defined(TARGET_HOST_MZ80A)
|
||||
#define TARGET_HOST_MZ80A 1
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ700)
|
||||
#define TARGET_HOST_MZ700 1
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ1500)
|
||||
#define TARGET_HOST_MZ1500 1
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ2000)
|
||||
#define TARGET_HOST_MZ2000 1
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_PCW8XXX) || defined(TARGET_HOST_PCW9XXX)
|
||||
#define TARGET_HOST_PCW 1
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#else
|
||||
#define TARGET_HOST_MZ700 0 // Target compilation for an MZ700
|
||||
#define TARGET_HOST_MZ2000 0 // MZ2000
|
||||
#define TARGET_HOST_MZ80A 0 // MZ80A
|
||||
#define TARGET_HOST_MZ1500 0 // MZ1500
|
||||
#define TARGET_HOST_MZ2000 0 // MZ2000
|
||||
#define TARGET_HOST_PCW 0 // Amstrad PCW8XXX/9XXX
|
||||
#endif
|
||||
|
||||
// Video display constants.
|
||||
#define VC_MAX_ROWS 25 // Maximum number of rows on display.
|
||||
#if (TARGET_HOST_MZ700 == 1)
|
||||
#if (TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
#define VC_MAX_COLUMNS 40 // Maximum number of columns on display.
|
||||
#else
|
||||
#define VC_MAX_COLUMNS 80 // Maximum number of columns on display.
|
||||
@@ -79,12 +92,12 @@
|
||||
#define KEYB_AUTOREPEAT_TIME 100 // Time in milliseconds between auto repeating characters.
|
||||
#define KEYB_FLASH_TIME 350 // Time in milliseconds for the cursor flash change.
|
||||
#define MAX_KEYB_BUFFER_SIZE 32 // Maximum size of the keyboard buffer.
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
#define KEY_SCAN_ROWS 10 // Number of rows on keyboard to scan.
|
||||
#define CURSOR_CHR_THICK_BLOCK 0x43 // Thick block cursor for Shift Lock.
|
||||
#define CURSOR_CHR_BLOCK 0xEF // Block cursor for CAPS Lock.
|
||||
#define CURSOR_CHR_BLOCK 0xD0 // Block cursor for CAPS Lock.
|
||||
#define CURSOR_CHR_GRAPH 0xFF // Graphic cursor for GRAPH mode.
|
||||
#define CURSOR_CHR_UNDERLINE 0x3E // Underline for lower case CAPS OFF.
|
||||
#define CURSOR_CHR_UNDERLINE 0x3C // Underline for lower case CAPS OFF.
|
||||
#elif (TARGET_HOST_MZ2000 == 1)
|
||||
#define KEY_SCAN_ROWS 12
|
||||
#define CURSOR_CHR_THICK_BLOCK 0x1E // Thick block cursor for Shift Lock.
|
||||
@@ -96,6 +109,7 @@
|
||||
// Audio constants.
|
||||
#define TIMER_8253_MZ80A_FREQ 2000000 // Base input frequency of Timer 0 for square wave generation.
|
||||
#define TIMER_8253_MZ700_FREQ 768000 // Base input frequency of Timer 0 for square wave generation.
|
||||
#define TIMER_8253_MZ1500_FREQ 768000 // Base input frequency of Timer 0 for square wave generation.
|
||||
|
||||
// Base addresses and sizes within the Video Controller.
|
||||
#define VIDEO_BASE_ADDR 0x000000 // Base address of the Video Controller.
|
||||
@@ -165,6 +179,20 @@
|
||||
#define MBADDR_SCLDSP 0xE200 // Hardware scroll, a read to each location adds 8 to the start of the video access address therefore creating hardware scroll. 00 - reset to power up
|
||||
#define MBADDR_SCLBASE 0xE2 // High byte scroll base.
|
||||
#define MBADDR_DSPCTL 0xDFFF // Display 40/80 select register (bit 7)
|
||||
#define IO_ADDR_E0 0xE0
|
||||
#define IO_ADDR_E1 0xE1
|
||||
#define IO_ADDR_E2 0xE2
|
||||
#define IO_ADDR_E3 0xE3
|
||||
#define IO_ADDR_E4 0xE4
|
||||
#define IO_ADDR_E5 0xE5
|
||||
#define IO_ADDR_E6 0xE6
|
||||
#define IO_ADDR_E7 0xE7
|
||||
#define IO_ADDR_E8 0xE8
|
||||
#define IO_PSG_BOTH 0xE9
|
||||
#define IO_ADDR_EA 0xEA
|
||||
#define IO_ADDR_EB 0xEB
|
||||
#define IO_PCG_PRIO 0xF0
|
||||
#define IO_PALETTE 0xF1
|
||||
|
||||
// Sharp MZ-2000 constants.
|
||||
#define MBADDR_FDC 0x0D8 // MB8866 IO Region 0D8h - 0DBh
|
||||
@@ -332,7 +360,7 @@
|
||||
display.hwVideoMode = (display.hwVideoMode & 0x3F);\
|
||||
WRITE_HARDWARE_IO(0, MBADDR_PIOA, display.hwVideoMode);\
|
||||
}
|
||||
#define WRITE_VRAM_CHAR(__addr__,__data__) WRITE_HARDWARE(0,__addr__,__data__)
|
||||
#define WRITE_VRAM_CHAR(__addr__,__data__,__xlat__) WRITE_HARDWARE(0,__addr__,__data__)
|
||||
#define WRITE_VRAM_ATTRIBUTE(__addr__,__data__) {}
|
||||
#define WRITE_KEYB_STROBE(__data__)\
|
||||
{\
|
||||
@@ -344,9 +372,9 @@
|
||||
#else
|
||||
#define ENABLE_VIDEO() {}
|
||||
#define DISABLE_VIDEO() {}
|
||||
#define WRITE_VRAM_CHAR(__addr__,__data__) WRITE_HARDWARE(0,__addr__,dispCodeMap[__data__].dispCode)
|
||||
#define WRITE_VRAM_ATTRIBUTE(__addr__,__data__) WRITE_HARDWARE(0,__addr__,__data__)
|
||||
#define WRITE_KEYB_STROBE(__data__) WRITE_HARDWARE(0, MBADDR_KEYPA, __data__)
|
||||
#define WRITE_VRAM_CHAR(__addr__,__data__,__xlat__) WRITE_HARDWARE(0,__addr__,(__xlat__ == 1 ? dispCodeMap[(int)__data__].dispCode : __data__))
|
||||
#define WRITE_VRAM_ATTRIBUTE(__addr__,__data__) WRITE_HARDWARE(0,__addr__,__data__)
|
||||
#define WRITE_KEYB_STROBE(__data__) WRITE_HARDWARE(0, MBADDR_KEYPA, __data__)
|
||||
#define READ_KEYB_INIT() READ_HARDWARE_INIT(0, MBADDR_KEYPB)
|
||||
#define READ_KEYB() READ_HARDWARE()
|
||||
#endif
|
||||
|
||||
5
software/FusionX/src/z80drv/Makefile
vendored
5
software/FusionX/src/z80drv/Makefile
vendored
@@ -1,4 +1,5 @@
|
||||
#MODEL := MZ2000
|
||||
#MODEL := MZ1500
|
||||
#MODEL := MZ700
|
||||
#MODEL := MZ80A
|
||||
#MODEL := PCW8XXX
|
||||
@@ -23,6 +24,7 @@ all:
|
||||
|
||||
MZ80A: MODEL_MZ80A
|
||||
MZ700: MODEL_MZ700
|
||||
MZ1500: MODEL_MZ1500
|
||||
MZ2000: MODEL_MZ2000
|
||||
PCW8XXX: MODEL_PCW8XXX
|
||||
PCW9XXX: MODEL_PCW9XXX
|
||||
@@ -31,6 +33,8 @@ MODEL_MZ80A:
|
||||
$(MAKE) MODEL=MZ80A BUILD_MZ80A
|
||||
MODEL_MZ700:
|
||||
$(MAKE) MODEL=MZ700 BUILD_MZ700
|
||||
MODEL_MZ1500:
|
||||
$(MAKE) MODEL=MZ1500 BUILD_MZ1500
|
||||
MODEL_MZ2000:
|
||||
$(MAKE) MODEL=MZ2000 BUILD_MZ2000
|
||||
MODEL_PCW8XXX:
|
||||
@@ -40,6 +44,7 @@ MODEL_PCW9XXX:
|
||||
|
||||
BUILD_MZ80A: sharpbiter k64fcpu kmod z80ctrl
|
||||
BUILD_MZ700: sharpbiter k64fcpu kmod z80ctrl
|
||||
BUILD_MZ1500: sharpbiter k64fcpu kmod z80ctrl
|
||||
BUILD_MZ2000: sharpbiter k64fcpu kmod z80ctrl
|
||||
BUILD_PCW8XXX: kmod z80ctrl
|
||||
BUILD_PCW9XXX: kmod z80ctrl
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
// out all low level control methods.
|
||||
// v1.01 - Updates to make compatible with the TZFS changes.
|
||||
// Apr v1.02 - Updates to add MZ-2000 servicing.
|
||||
// May v1.03 - Updates to add MZ-1500 servicing.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -2329,6 +2330,13 @@ void loadTranZPUterDefaultROMS(uint8_t cpuConfig)
|
||||
}
|
||||
break;
|
||||
|
||||
case HW_MZ1500:
|
||||
#if(DEBUG_ENABLED & 0x2)
|
||||
if(Z80Ctrl->debug >= 2) printf("Loading 1Z_009B\n");
|
||||
#endif
|
||||
result = loadTZFS(MZ_ROM_1Z_009B_40C, MZ_MROM_ADDR);
|
||||
break;
|
||||
|
||||
case HW_MZ80B:
|
||||
//result = loadBIOS(MZ_ROM_MZ80B_IPL, MZ80B, MZ_MROM_ADDR);
|
||||
result = loadBIOS(MZ_ROM_MZ80B_IPL, MZ_MROM_ADDR);
|
||||
@@ -2946,6 +2954,8 @@ int main(int argc, char *argv[])
|
||||
z80Control.hostType = HW_MZ80A;
|
||||
#elif (TARGET_HOST_MZ700 == 1)
|
||||
z80Control.hostType = HW_MZ700;
|
||||
#elif (TARGET_HOST_MZ1500 == 1)
|
||||
z80Control.hostType = HW_MZ1500;
|
||||
#elif (TARGET_HOST_MZ2000 == 1)
|
||||
z80Control.hostType = HW_MZ2000;
|
||||
#else
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
//
|
||||
// History: Feb 2023 v1.0 - Initial write.
|
||||
// Apr 2023 v1.1 - Updates to include MZ-2000.
|
||||
// Apr 2023 v1.2 - Updates to include MZ-1500.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -338,12 +339,15 @@ int main(int argc, char *argv[])
|
||||
#if(TARGET_HOST_MZ80A == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ700 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ1500 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#endif
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_RFS80;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
@@ -356,10 +360,12 @@ int main(int argc, char *argv[])
|
||||
ioctlCmd.cmd = IOCTL_CMD_ADD_DEVICE;
|
||||
#if(TARGET_HOST_MZ80A == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A;
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
#elif(TARGET_HOST_MZ700 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700;
|
||||
#elif(TARGET_HOST_MZ1500 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500;
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
#endif
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
@@ -382,12 +388,15 @@ int main(int argc, char *argv[])
|
||||
#if(TARGET_HOST_MZ80A == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ700 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ1500 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#endif
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_RFS80;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
@@ -419,12 +428,15 @@ int main(int argc, char *argv[])
|
||||
#if(TARGET_HOST_MZ80A == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ700 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ1500 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#endif
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_RFS80;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
@@ -450,12 +462,15 @@ int main(int argc, char *argv[])
|
||||
#if(TARGET_HOST_MZ80A == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ80A;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ700 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ1500 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#elif(TARGET_HOST_MZ2000 == 1)
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
#endif
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_RFS80;
|
||||
ioctl(arbCtrl.fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
7
software/FusionX/src/z80drv/src/tzpu.h
vendored
7
software/FusionX/src/z80drv/src/tzpu.h
vendored
@@ -50,6 +50,8 @@
|
||||
#define OS_BASE_DIR "/apps/FusionX/host/MZ-80A/" // Linux base directory where all the files are stored. On a real tranZPUter this would be the SD card root dir.
|
||||
#elif (TARGET_HOST_MZ700 == 1)
|
||||
#define OS_BASE_DIR "/apps/FusionX/host/MZ-700/"
|
||||
#elif (TARGET_HOST_MZ1500 == 1)
|
||||
#define OS_BASE_DIR "/apps/FusionX/host/MZ-1500/"
|
||||
#elif (TARGET_HOST_MZ2000 == 1)
|
||||
#define OS_BASE_DIR "/apps/FusionX/host/MZ-2000/"
|
||||
#endif
|
||||
@@ -203,7 +205,7 @@
|
||||
// CPLD Configuration constants.
|
||||
#define HWMODE_MZ80K 0x00 // Hardware mode = MZ80K
|
||||
#define HWMODE_MZ80C 0x01 // Hardware mode = MZ80C
|
||||
#define HWMODE_MZ1200 0x02 // Hardware mode = MZ1200
|
||||
#define HWMODE_MZ1500 0x02 // Hardware mode = MZ1500
|
||||
#define HWMODE_MZ80A 0x03 // Hardware mode = MZ80A
|
||||
#define HWMODE_MZ700 0x04 // Hardware mode = MZ700
|
||||
#define HWMODE_MZ800 0x05 // Hardware mode = MZ800
|
||||
@@ -421,6 +423,7 @@
|
||||
#define MZ_ROM_1Z_013A_KM_40C "1Z-013A-KM.rom" // Original 40 character Monitor ROM for the Sharp MZ700 with keyboard remapped for the MZ80A.
|
||||
#define MZ_ROM_1Z_013A_KM_80C "1Z-013A-KM-8.rom" // Original Monitor ROM patched for the Sharp MZ700 with keyboard remapped for the MZ80A and patched for 80 column mode.
|
||||
#define MZ_ROM_1Z_013A_2000 "1Z-013A-2000.rom" // Original 40 character Monitor ROM for the Sharp MZ700 modified to run on an MZ-2000.
|
||||
#define MZ_ROM_1Z_009B_40C "1Z-009B.rom" // Original 40 character MZ-1500 Monitor ROM.
|
||||
#define MZ_ROM_9Z_504M_COMBINED "MZ800_IPL.rom" // Original MZ-800 BIOS which comprises the 1Z_013B BIOS, 9Z_504M IPL, CGROM and IOCS.
|
||||
#define MZ_ROM_9Z_504M "MZ800_9Z_504M.rom" // Modified MZ-800 9Z_504M IPL to contain a select TZFS option.
|
||||
#define MZ_ROM_1Z_013B "MZ800_1Z_013B.rom" // Original MZ-800 1Z_013B MZ-700 compatible BIOS.
|
||||
@@ -481,7 +484,7 @@ enum TARGETS {
|
||||
enum MACHINE_HW_TYPES {
|
||||
HW_MZ80K = HWMODE_MZ80K, // Host hardware = MZ-80K.
|
||||
HW_MZ80C = HWMODE_MZ80C, // Host hardware = MZ-80C.
|
||||
HW_MZ1200 = HWMODE_MZ1200, // Host hardware = MZ-1200.
|
||||
HW_MZ1500 = HWMODE_MZ1500, // Host hardware = MZ-1500.
|
||||
HW_MZ80A = HWMODE_MZ80A, // Host hardware = MZ-80A.
|
||||
HW_MZ700 = HWMODE_MZ700, // Host hardware = MZ-700.
|
||||
HW_MZ800 = HWMODE_MZ800, // Host hardware = MZ-800.
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
//
|
||||
// History: Oct 2022 v1.0 - v1.Initial write of the z80 kernel driver software.
|
||||
// Feb 2023 v1.1 - Extended to allow Rom upload for RFS and other drivers.
|
||||
// May 2023 v1.2 - Extended to accommodate MZ-1500 host.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -54,7 +55,7 @@
|
||||
#include <Z80.h>
|
||||
#include "z80driver.h"
|
||||
|
||||
#define VERSION "1.1"
|
||||
#define VERSION "1.2"
|
||||
#define AUTHOR "P.D.Smart"
|
||||
#define COPYRIGHT "(c) 2018-23"
|
||||
|
||||
@@ -436,7 +437,7 @@ int z80load(int fdZ80, char *fileName, uint32_t memLoadAddr, long fileOffset, lo
|
||||
}
|
||||
else
|
||||
{
|
||||
#if(TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ80A)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
if(mzfHeader.loadAddr > 0x1000)
|
||||
{
|
||||
#endif
|
||||
@@ -446,7 +447,7 @@ int z80load(int fdZ80, char *fileName, uint32_t memLoadAddr, long fileOffset, lo
|
||||
// Now read in the data.
|
||||
fread(&Z80RAM[mzfHeader.loadAddr], mzfHeader.fileSize, 1, ptr);
|
||||
printf("Loaded %s, Size:%04x, Addr:%04x, Exec:%04x\n", fileName, mzfHeader.fileSize, mzfHeader.loadAddr, mzfHeader.execAddr);
|
||||
#if(TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ80A)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -459,7 +460,7 @@ int z80load(int fdZ80, char *fileName, uint32_t memLoadAddr, long fileOffset, lo
|
||||
// Set PC to 2 (NST) which switches to RUN mode and executes at 0000H
|
||||
ioctlCmd.z80.pc = 2;
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ80A)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
// MZ-700 or MZ-80A just use the MZF header exec address.
|
||||
ioctlCmd.z80.pc = mzfHeader.execAddr;
|
||||
#endif
|
||||
@@ -601,6 +602,10 @@ int ctrlCmd(int fdZ80, enum CTRL_COMMANDS cmd, long param1, long param2, long pa
|
||||
{
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700;
|
||||
}
|
||||
else if(strcasecmp((char *)param1, "MZ1500") == 0)
|
||||
{
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500;
|
||||
}
|
||||
else if(strcasecmp((char *)param1, "MZ2000") == 0)
|
||||
{
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
@@ -638,6 +643,10 @@ int ctrlCmd(int fdZ80, enum CTRL_COMMANDS cmd, long param1, long param2, long pa
|
||||
{
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ700;
|
||||
}
|
||||
else if(strcasecmp((char *)param1, "MZ1500") == 0)
|
||||
{
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ1500;
|
||||
}
|
||||
else if(strcasecmp((char *)param1, "MZ2000") == 0)
|
||||
{
|
||||
ioctlCmd.vdev.device = VIRTUAL_DEVICE_MZ2000;
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
// if same as the target machine. This then allows the z80 driver to be
|
||||
// a vanilla Z80 or customisations for hosts pulled in.
|
||||
// Apr 2023 - v1.4.1 Completed MZ2000 mode to work with arbiter and ttymz.
|
||||
// May 2023 - v1.5 Added MZ1500 modes.
|
||||
//
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
@@ -118,12 +119,15 @@ static DEFINE_MUTEX(Z80DRV_MUTEX);
|
||||
#if(TARGET_HOST_MZ80A == 1)
|
||||
#include "z80vhw_mz80a.c"
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
#include "z80vhw_rfs.c"
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ700 == 1)
|
||||
#include "z80vhw_mz700.c"
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
#include "z80vhw_mz1500.c"
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
#include "z80vhw_mz2000.c"
|
||||
#endif
|
||||
@@ -162,13 +166,19 @@ static inline void decodeMemoryMapSetup(zuint16 address, zuint8 data, uint8_t io
|
||||
mz700DecodeMemoryMapSetup(address, data, ioFlag, readFlag);
|
||||
} else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ1500)
|
||||
{
|
||||
mz1500DecodeMemoryMapSetup(address, data, ioFlag, readFlag);
|
||||
} else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ2000)
|
||||
{
|
||||
mz2000DecodeMemoryMapSetup(address, data, ioFlag, readFlag);
|
||||
} else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_RFS)
|
||||
{
|
||||
rfsDecodeMemoryMapSetup(address, data, ioFlag, readFlag);
|
||||
@@ -214,6 +224,12 @@ static inline zuint8 readVirtual(zuint16 address, uint8_t ioFlag)
|
||||
data = mz700Read(address, ioFlag);
|
||||
} else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ1500)
|
||||
{
|
||||
data = mz1500Read(address, ioFlag);
|
||||
} else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ2000)
|
||||
{
|
||||
@@ -227,7 +243,7 @@ static inline zuint8 readVirtual(zuint16 address, uint8_t ioFlag)
|
||||
} else
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
// RFS only has memory mapped registers.
|
||||
if((Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_RFS) && ioFlag == 0)
|
||||
{
|
||||
@@ -268,6 +284,12 @@ static inline void writeVirtual(zuint16 address, zuint8 data, uint8_t ioFlag)
|
||||
mz700Write(address, data, ioFlag);
|
||||
} else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ1500)
|
||||
{
|
||||
mz1500Write(address, data, ioFlag);
|
||||
} else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ2000)
|
||||
{
|
||||
@@ -281,7 +303,7 @@ static inline void writeVirtual(zuint16 address, zuint8 data, uint8_t ioFlag)
|
||||
} else
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
// RFS only has memory mapped registers.
|
||||
if((Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_RFS) && ioFlag == 0)
|
||||
{
|
||||
@@ -458,6 +480,10 @@ static zuint8 z80_read(void *context, zuint16 address)
|
||||
// Only read if the address is in physical RAM.
|
||||
#if(TARGET_HOST_PCW == 0)
|
||||
if(isPhysical(address))
|
||||
#elif(TARGET_HOST_MZ1500 == 1)
|
||||
// MZ-1500 take into account PCG being active, always go to hardware when active. Cannot use the map because
|
||||
// this can change during PCG active mode and must be reflected when PCG is deactivated.
|
||||
if(isPhysicalHW(address) || (Z80Ctrl->pcgMode == 1 && address >= 0xD000))
|
||||
#else
|
||||
if(isPhysicalHW(address))
|
||||
#endif
|
||||
@@ -527,6 +553,26 @@ static zuint8 z80_read(void *context, zuint16 address)
|
||||
Z80Ctrl->keyportTrigger = 0;
|
||||
}
|
||||
}
|
||||
#elif (TARGET_HOST_MZ1500 == 1)
|
||||
// Keyport data? Store.
|
||||
if(isHW(address) && address == 0xE001 && (Z80Ctrl->keyportStrobe & 0x0f) == 8)
|
||||
{
|
||||
Z80Ctrl->keyportShiftCtrl = (data & 0x40) == 0 ? 0x01 : 0x00;
|
||||
} else
|
||||
if(isHW(address) && address == 0xE001 && Z80Ctrl->keyportShiftCtrl == 1)
|
||||
{
|
||||
if((Z80Ctrl->keyportStrobe & 0x0f) == 5 && (data & 0xF0) != 0xF0)
|
||||
{
|
||||
Z80Ctrl->keyportHotKey = (data & 0x80) == 0 ? HOTKEY_ORIGINAL :
|
||||
(data & 0x40) == 0 ? HOTKEY_RFS40 :
|
||||
(data & 0x20) == 0 ? HOTKEY_TZFS :
|
||||
(data & 0x10) == 0 ? HOTKEY_LINUX : 0x00;
|
||||
Z80Ctrl->keyportTrigger = Z80Ctrl->keyportHotKey;
|
||||
} else
|
||||
{
|
||||
Z80Ctrl->keyportTrigger = 0;
|
||||
}
|
||||
}
|
||||
#elif (TARGET_HOST_MZ2000 == 1)
|
||||
|
||||
#endif
|
||||
@@ -548,7 +594,7 @@ static void z80_write(void *context, zuint16 address, zuint8 data)
|
||||
// Locals.
|
||||
Z_UNUSED(context)
|
||||
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
// To detect Hotkey presses, we need to store the keyboard strobe data and on keydata read.
|
||||
if(isHW(address) && address == 0xE000)
|
||||
{
|
||||
@@ -563,8 +609,15 @@ static void z80_write(void *context, zuint16 address, zuint8 data)
|
||||
if(isPhysicalRAM(address))
|
||||
writeVirtualRAM(address, data);
|
||||
Z80Ctrl->ioReadAhead = 0;
|
||||
}
|
||||
else if(isPhysical(address))
|
||||
} else
|
||||
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
// MZ-1500 take into account PCG being active, always go to hardware when active. Cannot use the map because
|
||||
// this can change during PCG active mode and must be reflected when PCG is deactivated.
|
||||
if(isPhysical(address) || (Z80Ctrl->pcgMode == 1 && address >= 0xD000))
|
||||
#else
|
||||
if(isPhysical(address))
|
||||
#endif
|
||||
{
|
||||
// Commence cycle to write the data to real RAM.
|
||||
SPI_SEND_32(address, data << 8 | CPLD_CMD_WRITE_ADDR);
|
||||
@@ -1057,7 +1110,7 @@ int thread_z80(void * thread_nr)
|
||||
if(Z80RunMode == Z80_RUNNING) canRun=1; else canRun=0;
|
||||
mutex_unlock(&Z80RunModeMutex);
|
||||
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ2000 == 1)
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1 || TARGET_HOST_MZ2000 == 1)
|
||||
// Hotkey pressed? Bring up user menu.
|
||||
if(Z80Ctrl->keyportTrigger != 0x00 && Z80Ctrl->keyportTriggerLast == 0)
|
||||
{
|
||||
@@ -1411,13 +1464,18 @@ void setupMemory(enum Z80_MEMORY_PROFILE mode)
|
||||
mz700SetupMemory(mode);
|
||||
else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ1500)
|
||||
mz1500SetupMemory(mode);
|
||||
else
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_MZ2000)
|
||||
mz2000SetupMemory(mode);
|
||||
else
|
||||
#endif
|
||||
// RFS board only works in an MZ-80A at present.
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
// RFS board only works on an MZ-80A/MZ-700/MZ-1500 at present.
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500)
|
||||
if(Z80Ctrl->virtualDeviceBitMap & VIRTUAL_DEVICE_RFS)
|
||||
rfsSetupMemory(mode);
|
||||
else
|
||||
@@ -1442,6 +1500,11 @@ void setupMemory(enum Z80_MEMORY_PROFILE mode)
|
||||
|
||||
// Inhibit mode disabled.
|
||||
Z80Ctrl->inhibitMode = 0;
|
||||
|
||||
#if defined(TARGET_HOST_MZ1500)
|
||||
// Flag to indicate PCG active, all memory accesses from D000:FFFF are sent to hardware.
|
||||
Z80Ctrl->pcgMode = 0;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1675,10 +1738,10 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
if(idx < Z80Ctrl->virtualDeviceCnt)
|
||||
break;
|
||||
|
||||
#if(TARGET_HOST_MZ80A == 0 && TARGET_HOST_MZ700 == 0)
|
||||
#if(TARGET_HOST_MZ80A == 0 && TARGET_HOST_MZ700 == 0 && TARGET_HOST_MZ1500 == 0)
|
||||
if(ioctlCmd.vdev.device & VIRTUAL_DEVICE_RFS)
|
||||
{
|
||||
pr_info("RFS Board currently supported on MZ-80A/MZ-700 Hosts only.\n");
|
||||
pr_info("RFS Board currently supported on MZ-80A/MZ-700/MZ-1500 Hosts only.\n");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
@@ -1700,7 +1763,7 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
case VIRTUAL_DEVICE_RFS40:
|
||||
case VIRTUAL_DEVICE_RFS80:
|
||||
Z80Ctrl->virtualDevice[Z80Ctrl->virtualDeviceCnt++] = ioctlCmd.vdev.device;
|
||||
@@ -1717,6 +1780,14 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
case VIRTUAL_DEVICE_MZ1500:
|
||||
Z80Ctrl->virtualDevice[Z80Ctrl->virtualDeviceCnt++] = ioctlCmd.vdev.device;
|
||||
Z80Ctrl->virtualDeviceBitMap |= ioctlCmd.vdev.device;
|
||||
mz1500Init(0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
case VIRTUAL_DEVICE_MZ2000:
|
||||
Z80Ctrl->virtualDevice[Z80Ctrl->virtualDeviceCnt++] = ioctlCmd.vdev.device;
|
||||
@@ -1791,7 +1862,7 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if(TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
case VIRTUAL_DEVICE_RFS40:
|
||||
case VIRTUAL_DEVICE_RFS80:
|
||||
Z80Ctrl->virtualDeviceBitMap &= ~ioctlCmd.vdev.device;
|
||||
@@ -1806,6 +1877,13 @@ static long int z80drv_ioctl(struct file *file, unsigned cmd, unsigned long arg)
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
case VIRTUAL_DEVICE_MZ1500:
|
||||
Z80Ctrl->virtualDeviceBitMap &= ~ioctlCmd.vdev.device;
|
||||
mz1500Remove();
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
case VIRTUAL_DEVICE_MZ2000:
|
||||
Z80Ctrl->virtualDeviceBitMap &= ~ioctlCmd.vdev.device;
|
||||
@@ -2067,7 +2145,7 @@ static int __init ModuleInit(void)
|
||||
Z80Ctrl->ioReadAhead = 0;
|
||||
Z80Ctrl->ioWriteAhead = 0;
|
||||
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1)
|
||||
#if (TARGET_HOST_MZ80A == 1 || TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1 || TARGET_HOST_MZ2000 == 1)
|
||||
// Initialse hotkey detection variables.
|
||||
Z80Ctrl->keyportStrobe = 0x00;
|
||||
Z80Ctrl->keyportShiftCtrl = 0x00;
|
||||
|
||||
102
software/FusionX/src/z80drv/src/z80driver.h
vendored
102
software/FusionX/src/z80drv/src/z80driver.h
vendored
@@ -16,6 +16,7 @@
|
||||
// Jan 2023 - v1.1 Added MZ-2000/MZ-80A modes.
|
||||
// Feb 2023 - v1.2 Added RFS virtual driver.
|
||||
// Apr 2023 - v1.4.1 Completed MZ2000 mode to work with arbiter and ttymz.
|
||||
// May 2023 - v1.5 Added MZ1500 modes.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
@@ -40,26 +41,37 @@
|
||||
#if defined(TARGET_HOST_MZ700)
|
||||
#define TARGET_HOST_MZ700 1
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ2000)
|
||||
#define TARGET_HOST_MZ2000 1
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ1500)
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_MZ1500 1
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_MZ80A)
|
||||
#define TARGET_HOST_MZ80A 1
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_PCW 0
|
||||
#elif defined(TARGET_HOST_PCW8XXX) || defined(TARGET_HOST_PCW9XXX)
|
||||
#define TARGET_HOST_PCW 1
|
||||
#define TARGET_HOST_MZ2000 0
|
||||
#define TARGET_HOST_MZ1500 0
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ80A 0
|
||||
#else
|
||||
#define TARGET_HOST_MZ700 0 // Target compilation for an MZ700
|
||||
#define TARGET_HOST_MZ2000 0 // MZ2000
|
||||
#define TARGET_HOST_MZ1500 0 // MZ1500
|
||||
#define TARGET_HOST_MZ80A 0 // MZ80A
|
||||
#define TARGET_HOST_PCW 0 // Amstrad PCW8XXX/9XXX
|
||||
#endif
|
||||
@@ -68,8 +80,8 @@
|
||||
#define DRIVER_LICENSE "GPL"
|
||||
#define DRIVER_AUTHOR "Philip D Smart"
|
||||
#define DRIVER_DESCRIPTION "Z80 CPU Emulator and Hardware Interface Driver"
|
||||
#define DRIVER_VERSION "v1.4.1"
|
||||
#define DRIVER_VERSION_DATE "Apr 2023"
|
||||
#define DRIVER_VERSION "v1.5"
|
||||
#define DRIVER_VERSION_DATE "May 2023"
|
||||
#define DRIVER_COPYRIGHT "(C) 2018-2023"
|
||||
#define Z80_VIRTUAL_ROM_SIZE (65536 * 32) // Sized to maximum Kernel contiguous allocation size, 2M which is 4x512K ROMS.
|
||||
#define Z80_VIRTUAL_RAM_SIZE (65536 * 32) // Sized to maximum Kernel contiguous allocation size, 2M.
|
||||
@@ -173,6 +185,82 @@
|
||||
#define INSTRUCTION_EQUIV_FREQ_448MHZ 448000000
|
||||
#define INSTRUCTION_GOVERNOR_IO_SKIP 10
|
||||
|
||||
enum Z80_INSTRUCTION_DELAY {
|
||||
ROM_DELAY_NORMAL = INSTRUCTION_DELAY_ROM_3_54MHZ,
|
||||
ROM_DELAY_X2 = INSTRUCTION_DELAY_ROM_7MHZ,
|
||||
ROM_DELAY_X4 = INSTRUCTION_DELAY_ROM_14MHZ,
|
||||
ROM_DELAY_X8 = INSTRUCTION_DELAY_ROM_28MHZ,
|
||||
ROM_DELAY_X16 = INSTRUCTION_DELAY_ROM_56MHZ,
|
||||
ROM_DELAY_X32 = INSTRUCTION_DELAY_ROM_112MHZ,
|
||||
ROM_DELAY_X64 = INSTRUCTION_DELAY_ROM_224MHZ,
|
||||
ROM_DELAY_X128 = INSTRUCTION_DELAY_ROM_448MHZ,
|
||||
RAM_DELAY_NORMAL = INSTRUCTION_DELAY_RAM_3_54MHZ,
|
||||
RAM_DELAY_X2 = INSTRUCTION_DELAY_RAM_7MHZ,
|
||||
RAM_DELAY_X4 = INSTRUCTION_DELAY_RAM_14MHZ,
|
||||
RAM_DELAY_X8 = INSTRUCTION_DELAY_RAM_28MHZ,
|
||||
RAM_DELAY_X16 = INSTRUCTION_DELAY_RAM_56MHZ,
|
||||
RAM_DELAY_X32 = INSTRUCTION_DELAY_RAM_112MHZ,
|
||||
RAM_DELAY_X64 = INSTRUCTION_DELAY_RAM_224MHZ,
|
||||
RAM_DELAY_X128 = INSTRUCTION_DELAY_RAM_448MHZ,
|
||||
CPU_FREQUENCY_NORMAL = INSTRUCTION_EQUIV_FREQ_3_54MHZ,
|
||||
CPU_FREQUENCY_X2 = INSTRUCTION_EQUIV_FREQ_7MHZ,
|
||||
CPU_FREQUENCY_X4 = INSTRUCTION_EQUIV_FREQ_14MHZ,
|
||||
CPU_FREQUENCY_X8 = INSTRUCTION_EQUIV_FREQ_28MHZ,
|
||||
CPU_FREQUENCY_X16 = INSTRUCTION_EQUIV_FREQ_56MHZ,
|
||||
CPU_FREQUENCY_X32 = INSTRUCTION_EQUIV_FREQ_112MHZ,
|
||||
CPU_FREQUENCY_X64 = INSTRUCTION_EQUIV_FREQ_224MHZ,
|
||||
CPU_FREQUENCY_X128 = INSTRUCTION_EQUIV_FREQ_448MHZ,
|
||||
};
|
||||
#endif
|
||||
//
|
||||
// MZ-1500
|
||||
#if(TARGET_HOST_MZ1500 == 1)
|
||||
#if(DEBUG_ENABLED > 0)
|
||||
#define INSTRUCTION_DELAY_ROM_3_54MHZ 253
|
||||
#define INSTRUCTION_DELAY_ROM_7MHZ 126
|
||||
#define INSTRUCTION_DELAY_ROM_14MHZ 63
|
||||
#define INSTRUCTION_DELAY_ROM_28MHZ 32
|
||||
#define INSTRUCTION_DELAY_ROM_56MHZ 16
|
||||
#define INSTRUCTION_DELAY_ROM_112MHZ 8
|
||||
#define INSTRUCTION_DELAY_ROM_224MHZ 4
|
||||
#define INSTRUCTION_DELAY_ROM_448MHZ 1
|
||||
#define INSTRUCTION_DELAY_RAM_3_54MHZ 253
|
||||
#define INSTRUCTION_DELAY_RAM_7MHZ 126
|
||||
#define INSTRUCTION_DELAY_RAM_14MHZ 63
|
||||
#define INSTRUCTION_DELAY_RAM_28MHZ 32
|
||||
#define INSTRUCTION_DELAY_RAM_56MHZ 16
|
||||
#define INSTRUCTION_DELAY_RAM_112MHZ 8
|
||||
#define INSTRUCTION_DELAY_RAM_224MHZ 4
|
||||
#define INSTRUCTION_DELAY_RAM_448MHZ 1
|
||||
#endif
|
||||
#if(DEBUG_ENABLED == 0)
|
||||
#define INSTRUCTION_DELAY_ROM_3_54MHZ 253
|
||||
#define INSTRUCTION_DELAY_ROM_7MHZ 126
|
||||
#define INSTRUCTION_DELAY_ROM_14MHZ 63
|
||||
#define INSTRUCTION_DELAY_ROM_28MHZ 32
|
||||
#define INSTRUCTION_DELAY_ROM_56MHZ 16
|
||||
#define INSTRUCTION_DELAY_ROM_112MHZ 8
|
||||
#define INSTRUCTION_DELAY_ROM_224MHZ 4
|
||||
#define INSTRUCTION_DELAY_ROM_448MHZ 1
|
||||
#define INSTRUCTION_DELAY_RAM_3_54MHZ 253
|
||||
#define INSTRUCTION_DELAY_RAM_7MHZ 126
|
||||
#define INSTRUCTION_DELAY_RAM_14MHZ 63
|
||||
#define INSTRUCTION_DELAY_RAM_28MHZ 32
|
||||
#define INSTRUCTION_DELAY_RAM_56MHZ 16
|
||||
#define INSTRUCTION_DELAY_RAM_112MHZ 8
|
||||
#define INSTRUCTION_DELAY_RAM_224MHZ 4
|
||||
#define INSTRUCTION_DELAY_RAM_448MHZ 1
|
||||
#endif
|
||||
#define INSTRUCTION_EQUIV_FREQ_3_54MHZ 3540000
|
||||
#define INSTRUCTION_EQUIV_FREQ_7MHZ 7000000
|
||||
#define INSTRUCTION_EQUIV_FREQ_14MHZ 14000000
|
||||
#define INSTRUCTION_EQUIV_FREQ_28MHZ 28000000
|
||||
#define INSTRUCTION_EQUIV_FREQ_56MHZ 56000000
|
||||
#define INSTRUCTION_EQUIV_FREQ_112MHZ 112000000
|
||||
#define INSTRUCTION_EQUIV_FREQ_224MHZ 224000000
|
||||
#define INSTRUCTION_EQUIV_FREQ_448MHZ 448000000
|
||||
#define INSTRUCTION_GOVERNOR_IO_SKIP 10
|
||||
|
||||
enum Z80_INSTRUCTION_DELAY {
|
||||
ROM_DELAY_NORMAL = INSTRUCTION_DELAY_ROM_3_54MHZ,
|
||||
ROM_DELAY_X2 = INSTRUCTION_DELAY_ROM_7MHZ,
|
||||
@@ -612,8 +700,9 @@ enum VIRTUAL_DEVICE {
|
||||
VIRTUAL_DEVICE_NONE = 0x00000000,
|
||||
VIRTUAL_DEVICE_MZ80A = 0x00000001,
|
||||
VIRTUAL_DEVICE_MZ700 = 0x00000002,
|
||||
VIRTUAL_DEVICE_MZ2000 = 0x00000004,
|
||||
VIRTUAL_DEVICE_PCW = 0x00000008,
|
||||
VIRTUAL_DEVICE_MZ1500 = 0x00000004,
|
||||
VIRTUAL_DEVICE_MZ2000 = 0x00000008,
|
||||
VIRTUAL_DEVICE_PCW = 0x00000010,
|
||||
VIRTUAL_DEVICE_RFS40 = 0x01000000,
|
||||
VIRTUAL_DEVICE_RFS80 = 0x02000000,
|
||||
VIRTUAL_DEVICE_RFS = 0x03000000,
|
||||
@@ -674,6 +763,11 @@ typedef struct {
|
||||
// blocks actions which arent allowed during inhibit.
|
||||
uint8_t inhibitMode;
|
||||
|
||||
#if defined(TARGET_HOST_MZ1500)
|
||||
// Flag to indicate PCG active, all memory accesses from D000:FFFF are sent to hardware.
|
||||
uint8_t pcgMode;
|
||||
#endif
|
||||
|
||||
// I/O lookahead flags - to overcome SSD202 io slowness.
|
||||
uint8_t ioReadAhead;
|
||||
uint8_t ioWriteAhead;
|
||||
|
||||
458
software/FusionX/src/z80drv/src/z80vhw_mz1500.c
Normal file
458
software/FusionX/src/z80drv/src/z80vhw_mz1500.c
Normal file
@@ -0,0 +1,458 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: z80vhw_mz1500.c
|
||||
// Created: May 2023
|
||||
// Author(s): Philip Smart
|
||||
// Description: Z80 Virtual Hardware Driver - MZ-1500
|
||||
// This file contains the methods used to emulate the original Sharp MZ-1500 without
|
||||
// any additions, such as the RFS or TZFS boards.
|
||||
//
|
||||
// These drivers are intended to be instantiated inline to reduce overhead of a call
|
||||
// and as such, they are included like header files rather than C linked object files.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2023 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: May 2023 v1.0 - Initial write based on the MZ700 module.
|
||||
//
|
||||
// Notes: See Makefile to enable/disable conditional components
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// This source file is free software: you can redistribute it and#or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mm.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/time.h>
|
||||
#include "z80io.h"
|
||||
|
||||
#include <gpio_table.h>
|
||||
#include <asm/io.h>
|
||||
#include <infinity2m/gpio.h>
|
||||
#include <infinity2m/registers.h>
|
||||
|
||||
// Device constants.
|
||||
#define RAM_BASE_ADDR 0x00000 // Base address of the 512K RAM.
|
||||
|
||||
// PCW control.
|
||||
typedef struct {
|
||||
uint8_t regCtrl; // Control register.
|
||||
} t_MZ1500Ctrl;
|
||||
|
||||
// RFS Board control.
|
||||
static t_MZ1500Ctrl MZ1500Ctrl;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Method to setup the memory page config to reflect the PCW configuration.
|
||||
void mz1500SetupMemory(enum Z80_MEMORY_PROFILE mode)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t idx;
|
||||
|
||||
// Setup defaults.
|
||||
MZ1500Ctrl.regCtrl = 0x00;
|
||||
|
||||
// Setup default mode according to run mode, ie. Physical run or Virtual run.
|
||||
//
|
||||
if(mode == USE_PHYSICAL_RAM)
|
||||
{
|
||||
// Initialise the page pointers and memory to use physical RAM.
|
||||
for(idx=0x0000; idx < MEMORY_PAGE_SIZE; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
if(idx >= 0 && idx < 0x1000)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_ROM, idx);
|
||||
}
|
||||
else if(idx >= 0x1000 && idx < 0xD000)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_RAM, idx);
|
||||
}
|
||||
else if(idx >= 0xD000 && idx < 0xE000)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_VRAM, idx);
|
||||
}
|
||||
else if(idx >= 0xE000 && idx < 0xE800)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_HW, idx);
|
||||
}
|
||||
else if(idx >= 0xE800 && idx < 0x10000)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_ROM, idx);
|
||||
} else
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_RAM, idx);
|
||||
}
|
||||
}
|
||||
for(idx=0x0000; idx < IO_PAGE_SIZE; idx++)
|
||||
{
|
||||
Z80Ctrl->iopage[idx] = idx | IO_TYPE_PHYSICAL_HW;
|
||||
}
|
||||
// Cancel refresh as using physical RAM for program automatically refreshes DRAM.
|
||||
Z80Ctrl->refreshDRAM = 0;
|
||||
}
|
||||
else if(mode == USE_VIRTUAL_RAM)
|
||||
{
|
||||
// Initialise the page pointers and memory to use virtual RAM.
|
||||
for(idx=0x0000; idx < MEMORY_PAGE_SIZE; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
if(idx >= 0 && idx < 0x1000)
|
||||
{
|
||||
setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
else if(idx >= 0x1000 && idx < 0xD000)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx);
|
||||
}
|
||||
else if(idx >= 0xD000 && idx < 0xE000)
|
||||
{
|
||||
setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_PHYSICAL_VRAM, idx);
|
||||
}
|
||||
else if(idx >= 0xE000 && idx < 0xE800)
|
||||
{
|
||||
setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_PHYSICAL_HW, idx);
|
||||
}
|
||||
else if(idx >= 0xE800 && idx < 0xF000)
|
||||
{
|
||||
setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
else if(idx >= 0xF000 && idx < 0x10000)
|
||||
{
|
||||
setMemoryType((idx/MEMORY_BLOCK_GRANULARITY), MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
}
|
||||
for(idx=0x0000; idx < IO_PAGE_SIZE; idx++)
|
||||
{
|
||||
Z80Ctrl->iopage[idx] = idx | IO_TYPE_PHYSICAL_HW;
|
||||
}
|
||||
// Enable refresh as using virtual RAM stops refresh of host DRAM.
|
||||
Z80Ctrl->refreshDRAM = 2;
|
||||
}
|
||||
|
||||
// Reset memory paging to default.
|
||||
SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR);
|
||||
|
||||
pr_info("MZ-1500 Memory Setup complete.\n");
|
||||
}
|
||||
|
||||
// Method to load a ROM image into the RAM memory.
|
||||
//
|
||||
uint8_t mz1500LoadROM(const char* romFileName, uint32_t loadAddr, uint32_t loadSize)
|
||||
{
|
||||
// Locals.
|
||||
uint8_t result = 0;
|
||||
long noBytes;
|
||||
struct file *fp;
|
||||
|
||||
fp = filp_open(romFileName, O_RDONLY, 0);
|
||||
if(IS_ERR(fp))
|
||||
{
|
||||
pr_info("Error opening ROM Image:%s\n:", romFileName);
|
||||
result = 1;
|
||||
} else
|
||||
{
|
||||
vfs_llseek(fp, 0, SEEK_SET);
|
||||
noBytes = kernel_read(fp, fp->f_pos, &Z80Ctrl->ram[loadAddr], loadSize);
|
||||
if(noBytes < loadSize)
|
||||
{
|
||||
pr_info("Short load, ROM Image:%s, bytes loaded:%08x\n:", romFileName, loadSize);
|
||||
}
|
||||
filp_close(fp,NULL);
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Perform any setup operations, such as variable initialisation, to enable use of this module.
|
||||
void mz1500Init(uint8_t mode)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t idx;
|
||||
|
||||
// Reset memory paging to default.
|
||||
SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR);
|
||||
|
||||
// Initialise the virtual RAM from the HOST DRAM. This is to maintain compatibility as some applications (in my experience) have
|
||||
// bugs, which Im putting down to not initialising variables. The host DRAM is in a pattern of 0x00..0x00, 0xFF..0xFF repeating
|
||||
// when first powered on.
|
||||
pr_info("Sync Host RAM to virtual RAM.\n");
|
||||
for(idx=0; idx < Z80_VIRTUAL_RAM_SIZE; idx++)
|
||||
{
|
||||
if(idx >= 0x1000 && idx < 0xD000)
|
||||
{
|
||||
SPI_SEND32((uint32_t)idx << 16 | CPLD_CMD_READ_ADDR);
|
||||
while(CPLD_READY() == 0);
|
||||
Z80Ctrl->ram[idx] = z80io_PRL_Read8(1);
|
||||
} else
|
||||
{
|
||||
Z80Ctrl->ram[idx] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
// Original mode, ie. no virtual devices active, copy the host BIOS into the Virtual ROM and initialise remainder of ROM memory
|
||||
// such that the host behaves as per original spec.
|
||||
pr_info("Sync Host BIOS to virtual ROM.\n");
|
||||
for(idx=0; idx < Z80_VIRTUAL_ROM_SIZE; idx++)
|
||||
{
|
||||
// Copy BIOS and any add-on ROMS.
|
||||
if((idx >= 0x0000 && idx < 0x1000) || (idx >= 0xE800 && idx < 0x10000))
|
||||
{
|
||||
SPI_SEND32((uint32_t)idx << 16 | CPLD_CMD_READ_ADDR);
|
||||
while(CPLD_READY() == 0);
|
||||
Z80Ctrl->rom[idx] = z80io_PRL_Read8(1);
|
||||
} else
|
||||
{
|
||||
Z80Ctrl->rom[idx] = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
// Initial memory config.
|
||||
mz1500SetupMemory(Z80Ctrl->defaultPageMode);
|
||||
|
||||
pr_info("Enabling MZ-1500 driver.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Perform any de-initialisation when the driver is removed.
|
||||
void mz1500Remove(void)
|
||||
{
|
||||
pr_info("Removing MZ-1500 driver.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Method to decode an address and make any system memory map changes as required.
|
||||
//
|
||||
static inline void mz1500DecodeMemoryMapSetup(zuint16 address, zuint8 data, uint8_t ioFlag, uint8_t readFlag)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t idx;
|
||||
|
||||
// Decoding memory address or I/O address?
|
||||
if(ioFlag == 0)
|
||||
{
|
||||
// #if(DEBUG_ENABLED & 1)
|
||||
// if(Z80Ctrl->debug >= 2)
|
||||
// {
|
||||
// pr_info("MEM:%04x,%02x,%d,%d\n", address, data, ioFlag, readFlag);
|
||||
// }
|
||||
// #endif
|
||||
// Certain machines have memory mapped I/O, these need to be handled in-situ as some reads may change the memory map.
|
||||
// These updates are made whilst waiting for the CPLD to retrieve the requested byte.
|
||||
//
|
||||
// 0000 - 0FFF : MZ80K/A/700 = Monitor ROM or RAM (MZ80A rom swap)
|
||||
// 1000 - CFFF : MZ80K/A/700 = RAM
|
||||
// C000 - CFFF : MZ80A = Monitor ROM (MZ80A rom swap)
|
||||
// D000 - D7FF : MZ80K/A/700 = VRAM
|
||||
// D800 - DFFF : MZ1500 = Colour VRAM (MZ1500)
|
||||
// E000 - E003 : MZ80K/A/700 = 8255
|
||||
// E004 - E007 : MZ80K/A/700 = 8254
|
||||
// E008 - E00B : MZ80K/A/700 = LS367
|
||||
// E00C - E00F : MZ80A = Memory Swap (MZ80A)
|
||||
// E010 - E013 : MZ80A = Reset Memory Swap (MZ80A)
|
||||
// E014 : MZ80A/700 = Normat CRT display
|
||||
// E015 : MZ80A/700 = Reverse CRT display
|
||||
// E200 - E2FF : MZ80A/700 = VRAM roll up/roll down.
|
||||
// E800 - EFFF : MZ80K/A/700 = User ROM socket or DD Eprom (MZ1500)
|
||||
// F000 - F7FF : MZ80K/A/700 = Floppy Disk interface.
|
||||
// F800 - FFFF : MZ80K/A/700 = Floppy Disk interface.
|
||||
switch(address)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
// #if(DEBUG_ENABLED & 1)
|
||||
// if(Z80Ctrl->debug >= 2)
|
||||
// {
|
||||
// pr_info("IO:%04x,%02x,%d,%d\n", address, data, ioFlag, readFlag);
|
||||
// }
|
||||
// #endif
|
||||
|
||||
// Determine if this is a memory management port and update the memory page if required.
|
||||
switch(address & 0x00FF)
|
||||
{
|
||||
// MZ1500 memory mode switch.
|
||||
//
|
||||
// MZ-1500
|
||||
// |0000:0FFF|1000:CFFF|D000:FFFF
|
||||
// ------------------------------
|
||||
// OUT 0xE0 = |DRAM | |
|
||||
// OUT 0xE1 = | | |DRAM
|
||||
// OUT 0xE2 = |MONITOR | |
|
||||
// OUT 0xE3 = | | |Memory Mapped I/O
|
||||
// OUT 0xE4 = |MONITOR |DRAM |Memory Mapped I/O
|
||||
// OUT 0xE5 = | | |PCG Enable
|
||||
// OUT 0xE6 = | | |PCG Disable
|
||||
//
|
||||
// <return> = Return to the state prior to the complimentary command being invoked.
|
||||
// Enable lower 4K block as DRAM
|
||||
case IO_ADDR_E0:
|
||||
for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx);
|
||||
}
|
||||
break;
|
||||
|
||||
// Enable upper 12K block, including Video/Memory Mapped peripherals area, as DRAM.
|
||||
case IO_ADDR_E1:
|
||||
if(!Z80Ctrl->inhibitMode)
|
||||
{
|
||||
for(idx=0xD000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
// MZ-1500 mode we only work in first 64K block.
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_RAM, idx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Enable MOnitor ROM in lower 4K block
|
||||
case IO_ADDR_E2:
|
||||
for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
break;
|
||||
|
||||
// Enable Video RAM and Memory mapped peripherals in upper 12K block.
|
||||
case IO_ADDR_E3:
|
||||
if(!Z80Ctrl->inhibitMode)
|
||||
{
|
||||
for(idx=0xD000; idx < 0xE000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_VRAM, idx);
|
||||
}
|
||||
for(idx=0xE000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_HW, idx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// Reset to power on condition memory map.
|
||||
case IO_ADDR_E4:
|
||||
// Lower 4K set to Monitor ROM.
|
||||
for(idx=0x0000; idx < 0x1000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_VIRTUAL_ROM, idx);
|
||||
}
|
||||
if(!Z80Ctrl->inhibitMode)
|
||||
{
|
||||
// Upper 12K to hardware.
|
||||
for(idx=0xD000; idx < 0xE000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_VRAM, idx);
|
||||
}
|
||||
for(idx=0xE000; idx < 0x10000; idx+=MEMORY_BLOCK_GRANULARITY)
|
||||
{
|
||||
setMemoryType(idx/MEMORY_BLOCK_GRANULARITY, MEMORY_TYPE_PHYSICAL_HW, idx);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// PCG Bank Switching.
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// 0 0 - CGROM
|
||||
// 0 1 - PCG Blue Plane
|
||||
// 1 0 - PCG Red Plane
|
||||
// 1 1 - PCG Green Plane
|
||||
case IO_ADDR_E5:
|
||||
// Any PCG access goes to hardware, set flag and access occurs in primary read/write routines.
|
||||
Z80Ctrl->pcgMode = 1;
|
||||
break;
|
||||
|
||||
// Disable PCG Bank Switching.
|
||||
case IO_ADDR_E6:
|
||||
// Disable PCG mode.
|
||||
Z80Ctrl->pcgMode = 0;
|
||||
break;
|
||||
|
||||
// Port is not a memory management port.
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method to read from either the memory mapped registers if enabled else the RAM.
|
||||
static inline uint8_t mz1500Read(zuint16 address, uint8_t ioFlag)
|
||||
{
|
||||
// Locals.
|
||||
uint8_t data = 0xFF;
|
||||
|
||||
// I/O Operation?
|
||||
if(ioFlag)
|
||||
{
|
||||
switch(address)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
switch(address)
|
||||
{
|
||||
default:
|
||||
if(isVirtualMemory(address))
|
||||
{
|
||||
// Retrieve data from virtual memory.
|
||||
data = isVirtualROM(address) ? readVirtualROM(address) : readVirtualRAM(address);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(data);
|
||||
}
|
||||
|
||||
// Method to handle writes.
|
||||
static inline void mz1500Write(zuint16 address, zuint8 data, uint8_t ioFlag)
|
||||
{
|
||||
// Locals.
|
||||
// uint32_t idx;
|
||||
|
||||
// I/O Operation?
|
||||
if(ioFlag)
|
||||
{
|
||||
switch(address)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else
|
||||
{
|
||||
switch(address)
|
||||
{
|
||||
default:
|
||||
if(isVirtualRAM(address))
|
||||
{
|
||||
// Update virtual memory.
|
||||
writeVirtualRAM(address, data);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -95,6 +95,8 @@
|
||||
#define ROM_DIR "/apps/FusionX/host/MZ-80A/RFS/"
|
||||
#elif(TARGET_HOST_MZ700 == 1)
|
||||
#define ROM_DIR "/apps/FusionX/host/MZ-700/RFS/"
|
||||
#elif(TARGET_HOST_MZ1500 == 1)
|
||||
#define ROM_DIR "/apps/FusionX/host/MZ-1500/RFS/"
|
||||
#else
|
||||
#error "Unknown host configured."
|
||||
#endif
|
||||
@@ -255,9 +257,14 @@ void rfsSetupMemory(enum Z80_MEMORY_PROFILE mode)
|
||||
// Enable refresh as using virtual RAM stops refresh of host DRAM.
|
||||
Z80Ctrl->refreshDRAM = 2;
|
||||
|
||||
#if (TARGET_HOST_MZ700 == 1)
|
||||
#if (TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
// Reset memory paging to default.
|
||||
SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR);
|
||||
|
||||
#if (TARGET_HOST_MZ1500 == 1)
|
||||
// MZ-1500, E4 reset closes the PCG access.
|
||||
Z80Ctrl->pcgMode = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// No I/O Ports on the RFS board.
|
||||
@@ -312,9 +319,14 @@ void rfsInit(uint8_t mode80c)
|
||||
Z80Ctrl->rom[idx+(Z80_VIRTUAL_ROM_SIZE-0x10000)] = z80io_PRL_Read8(1);
|
||||
}
|
||||
|
||||
#if (TARGET_HOST_MZ700 == 1)
|
||||
#if (TARGET_HOST_MZ700 == 1 || TARGET_HOST_MZ1500 == 1)
|
||||
// Reset memory paging to default.
|
||||
SPI_SEND_32(0x00e4, 0x00 << 8 | CPLD_CMD_WRITEIO_ADDR);
|
||||
|
||||
#if (TARGET_HOST_MZ1500 == 1)
|
||||
// MZ-1500, E4 reset closes the PCG access.
|
||||
Z80Ctrl->pcgMode = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pr_info("Enabling RFS(%d) driver.\n", mode80c == 1 ? 80 : 40);
|
||||
|
||||
Reference in New Issue
Block a user