Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb8f2c230b | ||
|
|
3273152b6e | ||
|
|
4417182fa4 | ||
|
|
e234adee32 | ||
|
|
bea3393432 | ||
|
|
78fddfb2eb | ||
|
|
066e049538 | ||
|
|
e3771cdf9c | ||
|
|
0a0ed14c6c | ||
| 9baeec811b | |||
|
|
75fb464b4d | ||
|
|
dcb308f0df | ||
|
|
5fa8d1fada | ||
|
|
462052140e | ||
|
|
5d0daa838e | ||
|
|
1ff4b558a5 | ||
|
|
b0ad5db6c6 | ||
|
|
2200e233e2 | ||
|
|
bd8cc2e964 | ||
|
|
fe53a4c871 | ||
|
|
09c9f0dadc | ||
|
|
e88777b04b | ||
|
|
582a50dd80 | ||
|
|
a3cfebc7f9 | ||
|
|
652bdd81eb | ||
|
|
db177d2240 | ||
|
|
dfa3dd5a57 | ||
|
|
826783ab79 |
7
.gitattributes
vendored
Normal file
7
.gitattributes
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
* linguist-vendored
|
||||
*.asm linguist-vendored=false
|
||||
*.c linguist-vendored=false
|
||||
*.cpp linguist-vendored=false
|
||||
*.pl linguist-vendored=false
|
||||
*.sh linguist-vendored=false
|
||||
*.vhd linguist-vendored=false
|
||||
113
.gitignore
vendored
113
.gitignore
vendored
@@ -3,18 +3,14 @@
|
||||
**/build/**
|
||||
c5_pin_model_dump.txt
|
||||
_config.yml
|
||||
CPLD
|
||||
CPLD/build/db/
|
||||
CPLD/build/incremental_db/
|
||||
CPLD/build/output_files/
|
||||
CPLD/build/simulation/
|
||||
CPLD/build/tranZPUterSW_constraints.sdc.clk
|
||||
CPLD/mz80b/
|
||||
CPLD/v1.0
|
||||
CPLD/v1.0.bak/
|
||||
CPLD/v1.0/build/greybox_tmp/
|
||||
CPLD/v1.0/MZ2000
|
||||
CPLD/v1.0/MZ2000/build
|
||||
CPLD/v1.0/MZ2000/build/db/
|
||||
CPLD/v1.0/MZ2000/build/greybox_tmp
|
||||
CPLD/v1.0/MZ2000/build/greybox_tmp/
|
||||
@@ -35,8 +31,6 @@ CPLD/v1.0/MZ2000/tranZPUterSW700.vhd.sav3
|
||||
CPLD/v1.0/MZ2000/tranZPUterSW.sav2
|
||||
CPLD/v1.0/MZ2000/tranZPUterSW.vhd.clk
|
||||
CPLD/v1.0/MZ2000/tranZPUterSW.vhd.presweep
|
||||
CPLD/v1.0/MZ700
|
||||
CPLD/v1.0/MZ700/build
|
||||
CPLD/v1.0/MZ700/build/db
|
||||
CPLD/v1.0/MZ700/build/db/
|
||||
CPLD/v1.0/MZ700/build/greybox_tmp
|
||||
@@ -58,8 +52,6 @@ CPLD/v1.0/MZ700/tranZPUterSW.vhd.clk
|
||||
CPLD/v1.0/MZ700/tranZPUterSW.vhd.presweep
|
||||
CPLD/v1.0/MZ700/working
|
||||
CPLD/v1.0/MZ700/working2
|
||||
CPLD/v1.0/MZ80A
|
||||
CPLD/v1.0/MZ80A/build
|
||||
CPLD/v1.0/MZ80A/build/db/
|
||||
CPLD/v1.0/MZ80A/build/emuMZ_ClockII.qip
|
||||
CPLD/v1.0/MZ80A/build/greybox_tmp
|
||||
@@ -341,7 +333,6 @@ software/FusionX/src/driver/Makefile3
|
||||
software/FusionX/src/driver/MZ2000/old/
|
||||
software/FusionX/src/driver/MZ700/old/
|
||||
software/FusionX/src/driver/mz700.rom
|
||||
software/FusionX/src/driver/MZ80A/
|
||||
software/FusionX/src/driver/MZ80A/old/
|
||||
software/FusionX/src/driver/test
|
||||
software/FusionX/src/driver/.tmp_versions
|
||||
@@ -350,6 +341,7 @@ software/FusionX/src/driver/Z80
|
||||
software/FusionX/src/driver/Z80/
|
||||
software/FusionX/src/driver/Z80.c.old
|
||||
software/FusionX/src/driver/z80ctrl
|
||||
software/FusionX/src/driver/k64fcpu
|
||||
software/FusionX/src/driver/Z80.rc.in
|
||||
software/FusionX/src/hello
|
||||
software/FusionX/src/spitools
|
||||
@@ -1668,4 +1660,107 @@ software/linux/kernel/drivers/sstar/emac/modules.order
|
||||
software/linux/kernel/drivers/sstar/netphy/modules.builtin
|
||||
software/linux/kernel/drivers/sstar/netphy/modules.order
|
||||
software/linux/project/release/nvr/i2m/011A/glibc/8.2.1/bin/kernel/spinand/
|
||||
README.md.last
|
||||
software/CPM
|
||||
software/FusionX/history
|
||||
software/FusionX/src/driver.ng/
|
||||
software/FusionX/src/driver/Makefile.old
|
||||
software/FusionX/src/driver/Z80.c.old2
|
||||
software/FusionX/src/driver/Zeta.test/
|
||||
software/FusionX/src/driver/sa1510.orig
|
||||
software/linux/kernel/arch/arm/boot/dts/hold/
|
||||
software/linux/kernel/arch/arm/configs/infinity2m_spinand_fusionx_defconfig.hld2
|
||||
CPLD/v1.0/MZ80A.ng/
|
||||
software/FusionX/src/driver/MZ80A/emumz.c
|
||||
software/FusionX/src/driver/MZ80A/sharpmz.c
|
||||
software/FusionX/src/driver/MZ700/emumz.c
|
||||
software/FusionX/src/driver/MZ700/sharpmz.c
|
||||
software/FusionX/src/driver/MZ2000/emumz.c
|
||||
software/FusionX/src/driver/MZ2000/sharpmz.c
|
||||
software/FusionX/src/driver/MZ80A/z80driver.c.bad
|
||||
software/FusionX/src/driver/MZ80A/z80vhw_rfs.c.bad
|
||||
software/FusionX/disk
|
||||
software/FusionX/roms
|
||||
software/linux/project/FusionX/
|
||||
software/FusionX/src/driver/MZ80A/k64fcpu.c.hld
|
||||
software/linux/buildroot/.config.old
|
||||
software/linux/kernel/scripts/kconfig/.mconf.cmd
|
||||
software/FusionX/src/ttymz/.tmp_versions/
|
||||
software/FusionX/src/ttymz/.ttymzdrv.ko.cmd
|
||||
software/FusionX/src/ttymz/Makefile.orig
|
||||
software/FusionX/src/ttymz/Module.symvers
|
||||
software/FusionX/src/ttymz/modules.order
|
||||
software/FusionX/src/ttymz/ttymzdrv.ko
|
||||
software/FusionX/src/ttymz/ttymzdrv.mod.c
|
||||
software/FusionX/src/z80drv/.tmp_versions/
|
||||
software/FusionX/src/z80drv/.z80drv.ko.cmd
|
||||
software/FusionX/src/z80drv/Kbuild.in
|
||||
software/FusionX/src/z80drv/MZ80A/emumz.c
|
||||
software/FusionX/src/z80drv/MZ80A/k64fcpu.c.hld
|
||||
software/FusionX/src/z80drv/MZ80A/z80driver.c.bad
|
||||
software/FusionX/src/z80drv/MZ80A/z80vhw_rfs.c.bad
|
||||
software/FusionX/src/z80drv/Makefile.old
|
||||
software/FusionX/src/z80drv/Makefile1
|
||||
software/FusionX/src/z80drv/Makefile3
|
||||
software/FusionX/src/z80drv/Module.symvers
|
||||
software/FusionX/src/z80drv/Z80.c.old
|
||||
software/FusionX/src/z80drv/Z80.c.old2
|
||||
software/FusionX/src/z80drv/Z80.rc.in
|
||||
software/FusionX/src/z80drv/Z80.x/
|
||||
software/FusionX/src/z80drv/Zeta.test/
|
||||
software/FusionX/src/z80drv/k64fcpu
|
||||
software/FusionX/src/z80drv/modules.order
|
||||
software/FusionX/src/z80drv/mz700.rom
|
||||
software/FusionX/src/z80drv/sa1510.orig
|
||||
software/FusionX/src/z80drv/test
|
||||
software/FusionX/src/z80drv/x.mzf
|
||||
software/FusionX/src/z80drv/z80ctrl
|
||||
software/FusionX/src/z80drv/z80drv.ko
|
||||
software/FusionX/src/z80drv/z80drv.mod.c
|
||||
software/FusionX/host/
|
||||
software/FusionX/src/z80drv/sharpbiter
|
||||
CPLD/v1.0/MZ2000/tzpuFusionX.vhd.bak
|
||||
CPLD/v1.0/MZ2000/tzpuFusionX.vhd.new
|
||||
CPLD/v1.0/MZ700/tzpuFusionX.vhd.old
|
||||
CPLD/v1.0/MZ80A/tzpuFusionX.vhd.bak
|
||||
software/FusionX/src/ttymz/Makefile.kmod
|
||||
software/FusionX/src/ttymz/z80io.h.old
|
||||
software/FusionX/src/z80drv/1
|
||||
software/FusionX/src/z80drv/2
|
||||
software/FusionX/src/z80drv/Makefile.mod
|
||||
software/FusionX/src/z80drv/Makefile.x
|
||||
software/FusionX/src/z80drv/Z80.c.old3
|
||||
software/FusionX/src/z80drv/Zeta.old3/
|
||||
software/FusionX/src/z80drv/integral.h
|
||||
software/FusionX/src/z80drv/src.mz2000/
|
||||
software/FusionX/src/z80drv/src.mz80a/
|
||||
software/FusionX/src/z80drv/src.pcw/
|
||||
software/FusionX/src/z80drv/src/PCW8256_boot.hex
|
||||
software/FusionX/src/z80drv/src/PCW8256_boot.rom
|
||||
software/FusionX/src/z80drv/src/ccc
|
||||
software/FusionX/src/z80drv/src/k64fcpu.c.hld
|
||||
software/FusionX/src/z80drv/src/z80driver.c.bad
|
||||
software/FusionX/src/z80drv/src/z80vhw_rfs.c.bad
|
||||
CPLD/v1.0/MZ2000.old/
|
||||
|
||||
# Un-ignore files needed for CI/CD builds
|
||||
!software/asm/
|
||||
!software/asm/*.asm
|
||||
!software/asm/include/
|
||||
!software/asm/include/*.asm
|
||||
!software/tools/
|
||||
!software/tools/assemble_*.sh
|
||||
!software/tools/copytosd.sh
|
||||
!software/tools/make_cpmdisks.sh
|
||||
!software/tools/glass*.jar
|
||||
!software/tools/dz80
|
||||
!software/tools/dz80_v20
|
||||
!software/tools/nasconv
|
||||
!software/tools/mzftool.pl
|
||||
!software/tools/flashmmcfg
|
||||
!software/tmp/
|
||||
!software/roms/
|
||||
!software/roms/*.rom
|
||||
!software/roms/*.bin
|
||||
!software/roms/*.BIN
|
||||
!software/roms/*.ori
|
||||
|
||||
11
.gitmodules
vendored
11
.gitmodules
vendored
@@ -1,6 +1,9 @@
|
||||
[submodule "software/FusionX/src/driver/Z80"]
|
||||
path = software/FusionX/src/driver/Z80
|
||||
path = software/FusionX/src/z80drv/Z80
|
||||
url = https://github.com/redcode/Z80.git
|
||||
[submodule "software/FusionX/src/driver/Zeta"]
|
||||
path = software/FusionX/src/driver/Zeta
|
||||
url = https://github.com/redcode/Zeta.git
|
||||
[submodule "software/FusionX/src/driver/6502"]
|
||||
path = software/FusionX/src/z80drv/6502
|
||||
url = https://github.com/redcode/6502.git
|
||||
[submodule "software/FusionX/src/driver/software/FusionX/src/driver/6502"]
|
||||
path = software/FusionX/src/z80drv/software/FusionX/src/driver/6502
|
||||
url = https://github.com/redcode/6502.git
|
||||
|
||||
@@ -127,10 +127,10 @@ set_location_assignment PIN_21 -to VSOM_RSV[1]
|
||||
# SOM Control Signals
|
||||
# ===================
|
||||
set_location_assignment PIN_28 -to VSOM_READY
|
||||
set_location_assignment PIN_18 -to VSOM_LTSTATE
|
||||
set_location_assignment PIN_19 -to VSOM_LTSTATE
|
||||
set_location_assignment PIN_27 -to VSOM_BUSRQ
|
||||
set_location_assignment PIN_26 -to VSOM_BUSACK
|
||||
set_location_assignment PIN_19 -to VSOM_INT
|
||||
set_location_assignment PIN_18 -to VSOM_INT
|
||||
set_location_assignment PIN_22 -to VSOM_NMI
|
||||
set_location_assignment PIN_25 -to VSOM_WAIT
|
||||
set_location_assignment PIN_23 -to VSOM_RESET
|
||||
|
||||
@@ -2,16 +2,17 @@
|
||||
--
|
||||
-- Name: tzpuFusionX.vhd
|
||||
-- Version: MZ-2000
|
||||
-- Created: June 2020
|
||||
-- Created: Jan 2023
|
||||
-- Author(s): Philip Smart
|
||||
-- Description: tzpuFusionX CPLD logic definition file.
|
||||
-- This module contains the definition of the tzpuFusionX project plus enhancements
|
||||
-- for the MZ-2000.
|
||||
--
|
||||
-- Credits:
|
||||
-- Copyright: (c) 2018-22 Philip Smart <philip.smart@net2net.org>
|
||||
-- Copyright: (c) 2018-23 Philip Smart <philip.smart@net2net.org>
|
||||
--
|
||||
-- History: Oct 2022 - Initial write for the MZ-2000.
|
||||
-- History: Jan 2023 v1.0 - Initial write for the MZ-2000.
|
||||
-- Apr 2023 v1.1 - Updates from the PCW8256 development.
|
||||
--
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
-- This source file is free software: you can redistribute it and-or modify
|
||||
@@ -128,7 +129,7 @@ end entity;
|
||||
|
||||
architecture rtl of cpld512 is
|
||||
|
||||
-- Finite State Machine states.
|
||||
-- Z80 Finite State Machine states.
|
||||
type SOMFSMState is
|
||||
(
|
||||
IdleCycle,
|
||||
@@ -174,6 +175,14 @@ architecture rtl of cpld512 is
|
||||
BusReqCycle
|
||||
);
|
||||
|
||||
-- Controller FSM states.
|
||||
type CTRLFSMState is
|
||||
(
|
||||
CTRLCMD_Idle,
|
||||
CTRLCMD_ReadIOWrite,
|
||||
CTRLCMD_ReadIOWrite_1
|
||||
);
|
||||
|
||||
-- CPU Interface internal signals.
|
||||
signal Z80_BUSRQni : std_logic;
|
||||
signal Z80_INTni : std_logic;
|
||||
@@ -185,7 +194,6 @@ architecture rtl of cpld512 is
|
||||
signal Z80_HALTni : std_logic;
|
||||
signal Z80_M1ni : std_logic;
|
||||
signal Z80_RFSHni : std_logic;
|
||||
signal Z80_DATAi : std_logic_vector(7 downto 0);
|
||||
signal Z80_BUSRQ_ACKni : std_logic;
|
||||
|
||||
-- Internal CPU state control.
|
||||
@@ -203,9 +211,10 @@ architecture rtl of cpld512 is
|
||||
|
||||
-- Refresh control.
|
||||
signal FSM_STATE : SOMFSMState := IdleCycle;
|
||||
signal NEW_SPI_CMD : std_logic := '0';
|
||||
signal CTRL_STATE : CTRLFSMState := CTRLCMD_Idle;
|
||||
signal NEW_SPI_DATA : std_logic := '0';
|
||||
signal VCPU_CS_EDGE : std_logic_vector(1 downto 0) := "11";
|
||||
signal AUTOREFRESH_CNT : integer range 0 to 7;
|
||||
signal AUTOREFRESH_CNT : integer range 0 to 63;
|
||||
signal FSM_STATUS : std_logic := '0';
|
||||
signal FSM_CHECK_WAIT : std_logic := '0';
|
||||
signal FSM_WAIT_ACTIVE : std_logic := '0';
|
||||
@@ -229,11 +238,12 @@ architecture rtl of cpld512 is
|
||||
signal SPI_RX_SREG : std_logic_vector(7 downto 0); -- RX Shift Register
|
||||
signal SPI_TX_DATA : std_logic_vector(31 downto 0); -- Data to transmit.
|
||||
signal SPI_RX_DATA : std_logic_vector(31 downto 0); -- Data received.
|
||||
signal SPI_BIT_CNT : integer range 0 to 16; -- Count of bits tx/rx'd.
|
||||
signal SPI_BIT_CNT : integer range 0 to 7; -- Count of bits tx/rx'd.
|
||||
signal SPI_FRAME_CNT : integer range 0 to 4; -- Number of frames received (8bit chunks).
|
||||
|
||||
-- SPI Command interface.
|
||||
signal SOM_CMD : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal SOM_PARAM_CNT : integer range 0 to 3;
|
||||
signal SPI_NEW_DATA : std_logic;
|
||||
signal SPI_PROCESSING : std_logic;
|
||||
signal SPI_CPU_ADDR : std_logic_vector(15 downto 0) := (others => '0');
|
||||
@@ -275,7 +285,7 @@ begin
|
||||
-- On the second edge, if occurring within 1 second of the first, the PM_RESET signal to the SOM is triggered, held low for 1 second,
|
||||
-- forcing the SOM to reboot.
|
||||
SYSRESET: process( Z80_CLKi, Z80_RESETn )
|
||||
variable timer1 : integer range 0 to 354000 := 0;
|
||||
variable timer1 : integer range 0 to 400000 := 0;
|
||||
variable timer100 : integer range 0 to 10 := 0;
|
||||
variable timerPMReset : integer range 0 to 10 := 0;
|
||||
variable resetCount : integer range 0 to 3 := 0;
|
||||
@@ -311,7 +321,7 @@ begin
|
||||
end if;
|
||||
|
||||
-- 100ms interval.
|
||||
if(timer1 = 354000) then
|
||||
if(timer1 = 400000) then
|
||||
timer100 := timer100 + 1;
|
||||
|
||||
if(timer100 >= 10) then
|
||||
@@ -340,8 +350,11 @@ begin
|
||||
-- SPI Slave input. Receive command and data from the SOM.
|
||||
SPI_INPUT : process(VSOM_SPI_CLK)
|
||||
begin
|
||||
-- Chip Select inactive, disable process and reset control flags.
|
||||
if(VSOM_SPI_CSn = '1') then
|
||||
|
||||
-- SPI_CLK_POLARITY='0' => falling edge; SPI_CLK_POLARITY='1' => rising edge
|
||||
if(VSOM_SPI_CLK'event and VSOM_SPI_CLK = SPI_CLK_POLARITY) then
|
||||
elsif(VSOM_SPI_CLK'event and VSOM_SPI_CLK = SPI_CLK_POLARITY) then
|
||||
if(VSOM_SPI_CSn = '0') then
|
||||
SPI_RX_SREG <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
|
||||
|
||||
@@ -356,7 +369,7 @@ begin
|
||||
elsif(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 3 and SPI_BIT_CNT = 0) then
|
||||
SPI_RX_DATA(23 downto 16) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
|
||||
|
||||
elsif(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 4 and SPI_BIT_CNT = 0) then
|
||||
elsif(SPI_FRAME_CNT = 4 and SPI_BIT_CNT = 0) then
|
||||
SPI_RX_DATA(31 downto 24) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
|
||||
end if;
|
||||
end if;
|
||||
@@ -366,18 +379,22 @@ begin
|
||||
-- SPI Slave output. Return the current data set as selected by the input signals XACT.
|
||||
SPI_OUTPUT : process(VSOM_SPI_CLK,VSOM_SPI_CSn,SPI_TX_DATA)
|
||||
begin
|
||||
-- Chip Select inactive, disable process and reset control flags.
|
||||
if(VSOM_SPI_CSn = '1') then
|
||||
SPI_SHIFT_EN <= '0';
|
||||
SPI_BIT_CNT <= 15;
|
||||
SPI_BIT_CNT <= 7;
|
||||
|
||||
-- SPI_CLK_POLARITY='0' => falling edge; SPI_CLK_POLARITY='1' => risinge edge
|
||||
elsif(VSOM_SPI_CLK'event and VSOM_SPI_CLK = not SPI_CLK_POLARITY) then
|
||||
-- Each clock reset the shift enable and done flag in preparation for the next cycle.
|
||||
SPI_SHIFT_EN <= '1';
|
||||
|
||||
-- Bit count decrements to detect when last bit of byte is sent.
|
||||
if(SPI_BIT_CNT > 0) then
|
||||
SPI_BIT_CNT <= SPI_BIT_CNT - 1;
|
||||
end if;
|
||||
|
||||
-- Shift out the next bit.
|
||||
VSOM_SPI_MISO <= SPI_TX_SREG(6);
|
||||
SPI_TX_SREG <= SPI_TX_SREG(5 downto 0) & '0';
|
||||
|
||||
@@ -392,6 +409,7 @@ begin
|
||||
SPI_FRAME_CNT<= 1;
|
||||
VSOM_SPI_MISO<= SPI_TX_DATA(7);
|
||||
SPI_TX_SREG <= SPI_TX_DATA(6 downto 0);
|
||||
-- Increment frame count for each word received. We handle 8bit (1 frame), 16bit (2 frames) or 32bit (4 frames) reception.
|
||||
elsif(SPI_FRAME_CNT = 1) then
|
||||
SPI_FRAME_CNT<= 2;
|
||||
VSOM_SPI_MISO<= SPI_TX_DATA(15);
|
||||
@@ -400,13 +418,14 @@ begin
|
||||
SPI_FRAME_CNT<= 3;
|
||||
VSOM_SPI_MISO<= SPI_TX_DATA(23);
|
||||
SPI_TX_SREG <= SPI_TX_DATA(22 downto 16);
|
||||
else
|
||||
elsif(SPI_FRAME_CNT = 3) then
|
||||
-- Increment frame count for each word received. We handle 8bit (1 frame), 16bit (2 frames) or 32bit (4 frames) reception.
|
||||
SPI_FRAME_CNT<= 4;
|
||||
VSOM_SPI_MISO<= SPI_TX_DATA(31);
|
||||
SPI_TX_SREG <= SPI_TX_DATA(30 downto 24);
|
||||
else
|
||||
SPI_FRAME_CNT<= 0;
|
||||
end if;
|
||||
|
||||
SPI_BIT_CNT <= 7;
|
||||
end if;
|
||||
end if;
|
||||
@@ -424,6 +443,7 @@ begin
|
||||
AUTOREFRESH <= '0';
|
||||
SPI_LOOPBACK_TEST <= '0';
|
||||
SOM_CMD <= (others => '0');
|
||||
SOM_PARAM_CNT <= 0;
|
||||
SPI_CPU_ADDR <= (others => '0');
|
||||
SPI_NEW_DATA <= '0';
|
||||
|
||||
@@ -432,6 +452,7 @@ begin
|
||||
-- for 8bit, 16bit and 32bit transmissions.
|
||||
-- The packet is formatted as follows:
|
||||
--
|
||||
-- < SPI_CPU_ADDR > < SPI_CPU_DATA >< SOM_CMD>
|
||||
-- < SPI_FRAME_CNT=4 >< SPI_FRAME=3 > < SPI_FRAME_CNT=2 >< SPI_FRAME_CNT=1>
|
||||
-- < 16bit Z80 Address > < Z80 Data ><Command=00..80>
|
||||
-- 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|
||||
@@ -441,66 +462,110 @@ begin
|
||||
--
|
||||
elsif(VSOM_SPI_CSn'event and VSOM_SPI_CSn = '1') then
|
||||
|
||||
-- Command is always located in the upper byte of frame 1.
|
||||
SOM_CMD <= SPI_RX_DATA(7 downto 0);
|
||||
-- If active, decrement parameter count. Parameters sent after a command are not considered as commands.
|
||||
if(SOM_PARAM_CNT > 0) then
|
||||
SOM_PARAM_CNT <= SOM_PARAM_CNT - 1;
|
||||
end if;
|
||||
|
||||
-- Toggle flag to indicate new data arrived.
|
||||
SPI_NEW_DATA <= not SPI_NEW_DATA;
|
||||
-- Process if command, store parameters.
|
||||
if(SOM_PARAM_CNT = 0) then
|
||||
-- Command is always located in the upper byte of frame 1.
|
||||
SOM_CMD <= SPI_RX_DATA(7 downto 0);
|
||||
|
||||
-- Process the command. Some commands require the FSM, others can be serviced immediately.
|
||||
case SPI_RX_DATA(7 downto 0) is
|
||||
-- Toggle flag to indicate new data arrived.
|
||||
SPI_NEW_DATA <= not SPI_NEW_DATA;
|
||||
|
||||
-- Z80XACT(0..15): Setup data and address as provided then execute FSM.
|
||||
when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17" | -- Fetch
|
||||
X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" | -- Write
|
||||
X"20" | X"21" | X"22" | X"23" | X"24" | X"25" | X"26" | X"27" | -- Read
|
||||
X"28" | X"29" | X"2A" | X"2B" | X"2C" | X"2D" | X"2E" | X"2F" | -- WriteIO
|
||||
X"30" | X"31" | X"32" | X"33" | X"34" | X"35" | X"36" | X"37" | -- ReadIO
|
||||
X"38" | X"39" | X"3A" | X"3B" | X"3C" | X"3D" | X"3E" | X"3F" | --
|
||||
X"40" | X"41" | X"42" | X"43" | X"44" | X"45" | X"46" | X"47" | --
|
||||
X"48" | X"49" | X"4A" | X"4B" | X"4C" | X"4D" | X"4E" | X"4F" =>
|
||||
-- Process the command. Some commands require the FSM, others can be serviced immediately.
|
||||
case SPI_RX_DATA(7 downto 0) is
|
||||
|
||||
-- Direct address set.
|
||||
if(SPI_FRAME_CNT = 4) then
|
||||
SPI_CPU_ADDR <= SPI_RX_DATA(31 downto 16);
|
||||
else
|
||||
-- if(SPI_CPU_ADDR >= X"D010" and SPI_CPU_ADDR < X"D020") then
|
||||
-- SPI_CPU_ADDR <= std_logic_vector(X"D020" + unsigned(SPI_RX_DATA(2 downto 0)));
|
||||
-- else
|
||||
SPI_CPU_ADDR <= std_logic_vector(unsigned(SPI_CPU_ADDR) + unsigned(SPI_RX_DATA(2 downto 0)));
|
||||
-- end if;
|
||||
end if;
|
||||
-- Z80XACT(0..15): Setup data and address as provided then execute FSM.
|
||||
when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17" | -- Fetch
|
||||
X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" | -- Write
|
||||
X"20" | X"21" | X"22" | X"23" | X"24" | X"25" | X"26" | X"27" | -- Read
|
||||
X"48" | X"49" | X"4A" | X"4B" | X"4C" | X"4D" | X"4E" | X"4F" =>
|
||||
|
||||
if(SPI_FRAME_CNT > 1) then
|
||||
SPI_CPU_DATA <= SPI_RX_DATA(15 downto 8);
|
||||
end if;
|
||||
-- Direct address set.
|
||||
if(SPI_FRAME_CNT = 4) then
|
||||
SPI_CPU_ADDR <= SPI_RX_DATA(31 downto 16);
|
||||
else
|
||||
SPI_CPU_ADDR <= std_logic_vector(unsigned(SPI_CPU_ADDR) + unsigned(SPI_RX_DATA(2 downto 0)));
|
||||
end if;
|
||||
|
||||
-- SETSIGSET1: Set control lines directly.
|
||||
when X"F0" =>
|
||||
VIDEO_SRCi <= SPI_RX_DATA(8);
|
||||
MONO_VIDEO_SRCi <= SPI_RX_DATA(9);
|
||||
AUDIO_SRC_Li <= SPI_RX_DATA(10);
|
||||
AUDIO_SRC_Ri <= SPI_RX_DATA(11);
|
||||
VBUS_ENi <= SPI_RX_DATA(12);
|
||||
VGA_BLANKn <= not SPI_RX_DATA(13);
|
||||
if(SPI_FRAME_CNT > 1) then
|
||||
SPI_CPU_DATA <= SPI_RX_DATA(15 downto 8);
|
||||
end if;
|
||||
|
||||
-- Enable auto refresh DRAM cycle.
|
||||
when X"F1" =>
|
||||
AUTOREFRESH <= '1';
|
||||
when X"28" | X"29" | X"2A" | X"2B" | X"2C" | X"2D" | X"2E" | X"2F" => -- WriteIO
|
||||
|
||||
-- Disable auto refresh DRAM cycle.
|
||||
when X"F2" =>
|
||||
AUTOREFRESH <= '0';
|
||||
-- Direct address set.
|
||||
if(SPI_FRAME_CNT = 4) then
|
||||
SPI_CPU_ADDR <= SPI_RX_DATA(31 downto 16);
|
||||
else
|
||||
SPI_CPU_ADDR <= X"000" & '0' & std_logic_vector(unsigned(SPI_RX_DATA(2 downto 0)));
|
||||
end if;
|
||||
|
||||
-- SETLOOPBACK: Enable loopback test mode.
|
||||
when X"FE" =>
|
||||
SPI_LOOPBACK_TEST<= '1';
|
||||
if(SPI_FRAME_CNT > 1) then
|
||||
SPI_CPU_DATA <= SPI_RX_DATA(15 downto 8);
|
||||
end if;
|
||||
|
||||
-- No action, called to retrieve status.
|
||||
when X"00" | X"FF" =>
|
||||
when X"30" | X"31" | X"32" | X"33" | X"34" | X"35" | X"36" | X"37" | -- ReadIO
|
||||
X"38" | X"39" | X"3A" | X"3B" | X"3C" | X"3D" | X"3E" | X"3F" => -- ReadIO-Write
|
||||
|
||||
when others =>
|
||||
end case;
|
||||
-- Direct address set.
|
||||
if(SPI_FRAME_CNT = 4) then
|
||||
SPI_CPU_ADDR <= SPI_RX_DATA(31 downto 16);
|
||||
elsif(SPI_FRAME_CNT = 2) then
|
||||
SPI_CPU_ADDR <= X"00" & SPI_RX_DATA(15 downto 8);
|
||||
else
|
||||
SPI_CPU_ADDR <= X"000" & '0' & std_logic_vector(unsigned(SPI_RX_DATA(2 downto 0)));
|
||||
end if;
|
||||
|
||||
if(SPI_FRAME_CNT > 1) then
|
||||
SPI_CPU_DATA <= SPI_RX_DATA(15 downto 8);
|
||||
end if;
|
||||
|
||||
-- ReadIO-Write, Read-WriteIO commands require target address, so indicate parameter needed.
|
||||
if(SPI_RX_DATA(7 downto 0) >= X"38" and SPI_RX_DATA(7 downto 0) < X"40") then
|
||||
SOM_PARAM_CNT <= 1;
|
||||
end if;
|
||||
|
||||
-- SETSIGSET1: Set control lines directly.
|
||||
when X"F0" =>
|
||||
VIDEO_SRCi <= SPI_RX_DATA(8);
|
||||
MONO_VIDEO_SRCi <= SPI_RX_DATA(9);
|
||||
AUDIO_SRC_Li <= SPI_RX_DATA(10);
|
||||
AUDIO_SRC_Ri <= SPI_RX_DATA(11);
|
||||
VBUS_ENi <= SPI_RX_DATA(12);
|
||||
VGA_BLANKn <= not SPI_RX_DATA(13);
|
||||
|
||||
-- Enable auto refresh DRAM cycle.
|
||||
when X"F1" =>
|
||||
AUTOREFRESH <= '1';
|
||||
|
||||
-- Disable auto refresh DRAM cycle.
|
||||
when X"F2" =>
|
||||
AUTOREFRESH <= '0';
|
||||
|
||||
-- SETLOOPBACK: Enable loopback test mode.
|
||||
when X"FE" =>
|
||||
SPI_LOOPBACK_TEST<= '1';
|
||||
|
||||
-- No action, called to retrieve status.
|
||||
when X"00" | X"FF" =>
|
||||
|
||||
when others =>
|
||||
end case;
|
||||
else
|
||||
-- Store parameter depending on number of frames, either ADDR+DATA, ADDR or DATA.
|
||||
if(SPI_FRAME_CNT = 4) then
|
||||
SPI_CPU_ADDR <= SPI_RX_DATA(31 downto 16);
|
||||
SPI_CPU_DATA <= SPI_RX_DATA(15 downto 8);
|
||||
elsif(SPI_FRAME_CNT = 2) then
|
||||
SPI_CPU_ADDR <= SPI_RX_DATA(15 downto 0);
|
||||
else
|
||||
SPI_CPU_DATA <= SPI_RX_DATA(7 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
@@ -561,9 +626,9 @@ begin
|
||||
CPU_DATA_EN <= '0';
|
||||
CPU_DATA_IN <= (others => '0');
|
||||
REFRESH_ADDR <= (others => '0');
|
||||
AUTOREFRESH_CNT <= 7;
|
||||
AUTOREFRESH_CNT <= 63;
|
||||
IPAR <= (others => '0');
|
||||
NEW_SPI_CMD <= '0';
|
||||
NEW_SPI_DATA <= '0';
|
||||
VCPU_CS_EDGE <= "11";
|
||||
SPI_PROCESSING <= '0';
|
||||
|
||||
@@ -580,98 +645,12 @@ begin
|
||||
|
||||
-- New command, set flag as the signal is only 1 clock wide.
|
||||
if(SPI_LOOPBACK_TEST = '0' and VSOM_SPI_CSn = '1' and VCPU_CS_EDGE = "01") then
|
||||
NEW_SPI_CMD <= '1';
|
||||
NEW_SPI_DATA <= '1';
|
||||
end if;
|
||||
|
||||
-- Whenever we return to Idle or just prior to Refresh from a Fetch cycle set all control signals to default.
|
||||
if(FSM_STATE = IdleCycle or FSM_STATE = RefreshCycle) then
|
||||
CPU_DATA_EN <= '0';
|
||||
Z80_MREQni <= '1';
|
||||
Z80_IORQni <= '1';
|
||||
Z80_RDni <= '1';
|
||||
Z80_WRni <= '1';
|
||||
Z80_M1ni <= '1';
|
||||
FSM_STATUS <= '0';
|
||||
Z80_RFSHni <= '1';
|
||||
|
||||
-- Auto DRAM refresh cycles. When enabled, every 7 host clock cycles, a 2 cycle refresh period commences.
|
||||
-- This will be overriden if the SPI receives a new command.
|
||||
--
|
||||
if AUTOREFRESH = '1' and FSM_STATE = IdleCycle then
|
||||
AUTOREFRESH_CNT <= AUTOREFRESH_CNT - 1;
|
||||
if(AUTOREFRESH_CNT = 0) then
|
||||
FSM_STATE <= RefreshCycle_3;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- If new command has been given and the FSM enters idle state, load up new command for processing.
|
||||
if(NEW_SPI_CMD = '1' and FSM_STATE = IdleCycle and Z80_CLK_RE = '1') then
|
||||
NEW_SPI_CMD <= '0';
|
||||
|
||||
-- Store new address and data for this command.
|
||||
CPU_ADDR <= SPI_CPU_ADDR;
|
||||
if(SPI_CPU_DATA /= CPU_DATA_OUT) then
|
||||
CPU_DATA_OUT <= SPI_CPU_DATA;
|
||||
end if;
|
||||
|
||||
-- Process the SOM command. The SPI_REGISTER executes non FSM commands and stores FSM
|
||||
-- data prior to this execution block, which fires 1 cycle later on the same control clock.
|
||||
-- If the command is not for the FSM then the READY mechanism is held for one
|
||||
-- further cycle before going inactive.
|
||||
case SOM_CMD is
|
||||
when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17" =>
|
||||
-- Initiate a Fetch Cycle.
|
||||
FSM_STATE <= FetchCycle;
|
||||
|
||||
when X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" =>
|
||||
|
||||
-- Set the Z80 data bus value and initiate a Write Cycle.
|
||||
FSM_STATE <= WriteCycle;
|
||||
|
||||
when X"20" | X"21" | X"22" | X"23" | X"24" | X"25" | X"26" | X"27" =>
|
||||
-- Initiate a Read Cycle.
|
||||
FSM_STATE <= ReadCycle;
|
||||
|
||||
when X"28" | X"29" | X"2A" | X"2B" | X"2C" | X"2D" | X"2E" | X"2F" =>
|
||||
-- Set the Z80 data bus value and initiate an IO Write Cycle.
|
||||
-- The SOM should set 15:8 to the B register value.
|
||||
FSM_STATE <= WriteIOCycle;
|
||||
|
||||
when X"30" | X"31" | X"32" | X"33" | X"34" | X"35" | X"36" | X"37" =>
|
||||
-- Initiate a Read IO Cycle.
|
||||
FSM_STATE <= ReadIOCycle;
|
||||
|
||||
when X"50" =>
|
||||
-- Register a Halt state.
|
||||
FSM_STATE <= HaltCycle;
|
||||
|
||||
when X"51" =>
|
||||
-- Initiate a refresh cycle.
|
||||
FSM_STATE <= RefreshCycle_3;
|
||||
|
||||
when X"E0" =>
|
||||
-- Initiate a Halt Cycle.
|
||||
FSM_STATE <= HaltCycle;
|
||||
|
||||
-- Set the Refresh Address register.
|
||||
when X"E1" =>
|
||||
REFRESH_ADDR <= CPU_DATA_OUT;
|
||||
|
||||
-- Set the Interrupt Page Address Register.
|
||||
when X"E2" =>
|
||||
IPAR <= CPU_DATA_OUT;
|
||||
|
||||
when others =>
|
||||
end case;
|
||||
|
||||
-- Toggle the processing flag to negate the new data flag. Used to indicate device is busy.
|
||||
if(SPI_NEW_DATA /= SPI_PROCESSING) then
|
||||
SPI_PROCESSING <= not SPI_PROCESSING;
|
||||
end if;
|
||||
|
||||
-- FSM Status bit. When processing a command it is set, cleared when idle. Used by SOM to determine command completion.
|
||||
FSM_STATUS <= '1';
|
||||
-- Decrement refresh counter on each Z80 cycle, thus when idle and time expired, a refresh can be performed within parameters (256 cycles in 4ms).
|
||||
if(AUTOREFRESH = '1' and AUTOREFRESH_CNT /= 0 and Z80_CLK_RE = '1') then
|
||||
AUTOREFRESH_CNT <= AUTOREFRESH_CNT - 1;
|
||||
end if;
|
||||
|
||||
-- Refresh status bit. Indicates a Refresh cycle is under way.
|
||||
@@ -686,7 +665,143 @@ begin
|
||||
FSM_WAIT_ACTIVE <= '1';
|
||||
end if;
|
||||
|
||||
-- On each Z80 edge we advance the FSM to recreate the Z80 external signal transactions.
|
||||
-- Whenever we return to Idle or just prior to Refresh from a Fetch cycle set all control signals to default.
|
||||
if((FSM_STATE = IdleCycle or FSM_STATE = RefreshCycle) and Z80_CLK_RE = '1') then
|
||||
CPU_DATA_EN <= '0';
|
||||
Z80_MREQni <= '1';
|
||||
Z80_IORQni <= '1';
|
||||
Z80_RDni <= '1';
|
||||
Z80_WRni <= '1';
|
||||
Z80_M1ni <= '1';
|
||||
FSM_STATUS <= '0';
|
||||
Z80_RFSHni <= '1';
|
||||
|
||||
-- Auto DRAM refresh cycles. When enabled, every 15.6us a refresh period commences.
|
||||
-- This period may be extended if the SPI receives a new command.
|
||||
--
|
||||
if AUTOREFRESH = '1' and FSM_STATE = IdleCycle then
|
||||
if(AUTOREFRESH_CNT = 0) then
|
||||
FSM_STATE <= RefreshCycle_3;
|
||||
FSM_STATUS<= '1';
|
||||
-- 4164 DRAM = 256 cycles in 4ms.
|
||||
AUTOREFRESH_CNT <= 63;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
--------------------------------------------------------------------------------------------
|
||||
-- CPLD Macro Command Finite State Machine.
|
||||
--------------------------------------------------------------------------------------------
|
||||
|
||||
-- Controller state machine.
|
||||
-- When idle, accept and process SPI commands which can lead to a controller macro command.
|
||||
case CTRL_STATE is
|
||||
|
||||
when CTRLCMD_Idle =>
|
||||
-- If new command has been given and the FSM enters idle state, load up new command for processing.
|
||||
if(NEW_SPI_DATA = '1' and FSM_STATE = IdleCycle and Z80_CLK_RE = '1') then
|
||||
|
||||
-- Store new address and data for this command.
|
||||
if(NEW_SPI_DATA = '1') then
|
||||
CPU_ADDR <= SPI_CPU_ADDR;
|
||||
CPU_DATA_OUT <= SPI_CPU_DATA;
|
||||
end if;
|
||||
|
||||
-- Process the SOM command. The SPI_REGISTER executes non FSM commands and stores FSM
|
||||
-- data prior to this execution block, which fires 1 cycle later on the same control clock.
|
||||
-- If the command is not for the FSM then the READY mechanism is held for one
|
||||
-- further cycle before going inactive.
|
||||
case SOM_CMD is
|
||||
when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17" =>
|
||||
-- Initiate a Fetch Cycle.
|
||||
FSM_STATE <= FetchCycle;
|
||||
|
||||
when X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" =>
|
||||
|
||||
-- Set the Z80 data bus value and initiate a Write Cycle.
|
||||
FSM_STATE <= WriteCycle;
|
||||
|
||||
when X"20" | X"21" | X"22" | X"23" | X"24" | X"25" | X"26" | X"27" =>
|
||||
-- Initiate a Read Cycle.
|
||||
FSM_STATE <= ReadCycle;
|
||||
|
||||
when X"28" | X"29" | X"2A" | X"2B" | X"2C" | X"2D" | X"2E" | X"2F" =>
|
||||
-- Set the Z80 data bus value and initiate an IO Write Cycle.
|
||||
-- The SOM should set 15:8 to the B register value.
|
||||
FSM_STATE <= WriteIOCycle;
|
||||
|
||||
when X"30" | X"31" | X"32" | X"33" | X"34" | X"35" | X"36" | X"37" =>
|
||||
-- Initiate a Read IO Cycle.
|
||||
FSM_STATE <= ReadIOCycle;
|
||||
|
||||
when X"38" | X"39" | X"3A" | X"3B" | X"3C" | X"3D" | X"3E" | X"3F" =>
|
||||
-- Initiate a read IO write memory cycle via the controller FSM.
|
||||
CTRL_STATE <= CTRLCMD_ReadIOWrite;
|
||||
FSM_STATE <= ReadIOCycle;
|
||||
|
||||
when X"50" =>
|
||||
-- Register a Halt state.
|
||||
FSM_STATE <= HaltCycle;
|
||||
|
||||
when X"51" =>
|
||||
-- Initiate a refresh cycle.
|
||||
FSM_STATE <= RefreshCycle_3;
|
||||
|
||||
when X"E0" =>
|
||||
-- Initiate a Halt Cycle.
|
||||
FSM_STATE <= HaltCycle;
|
||||
|
||||
-- Set the Refresh Address register.
|
||||
when X"E1" =>
|
||||
REFRESH_ADDR <= CPU_DATA_OUT;
|
||||
|
||||
-- Set the Interrupt Page Address Register.
|
||||
when X"E2" =>
|
||||
IPAR <= CPU_DATA_OUT;
|
||||
|
||||
when others =>
|
||||
end case;
|
||||
|
||||
-- Toggle the processing flag to negate the new data flag. Used to indicate device is busy.
|
||||
if(SPI_NEW_DATA /= SPI_PROCESSING) then
|
||||
SPI_PROCESSING<= not SPI_PROCESSING;
|
||||
end if;
|
||||
|
||||
-- Clear new data flag ready for next cmd/param transfer.
|
||||
NEW_SPI_DATA <= '0';
|
||||
|
||||
-- FSM Status bit. When processing a command it is set, cleared when idle. Used by SOM to determine command completion.
|
||||
FSM_STATUS <= '1';
|
||||
end if;
|
||||
|
||||
when CTRLCMD_ReadIOWrite =>
|
||||
if(NEW_SPI_DATA = '1' and FSM_STATE = IdleCycle and Z80_CLK_RE = '1') then
|
||||
NEW_SPI_DATA <= '0';
|
||||
CPU_DATA_EN <= '0';
|
||||
Z80_IORQni <= '1';
|
||||
Z80_RDni <= '1';
|
||||
Z80_RFSHni <= '1';
|
||||
CPU_ADDR <= SPI_CPU_ADDR;
|
||||
CPU_DATA_OUT <= CPU_DATA_IN;
|
||||
FSM_STATE <= WriteCycle;
|
||||
CTRL_STATE <= CTRLCMD_ReadIOWrite_1;
|
||||
end if;
|
||||
|
||||
when CTRLCMD_ReadIOWrite_1 =>
|
||||
if(FSM_STATE = WriteCycle_31) then
|
||||
CTRL_STATE <= CTRLCMD_Idle;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
CTRL_STATE <= CTRLCMD_Idle;
|
||||
|
||||
end case;
|
||||
|
||||
--------------------------------------------------------------------------------------------
|
||||
-- Z80 Finite State Machine.
|
||||
--------------------------------------------------------------------------------------------
|
||||
|
||||
-- On each Z80 edge we advance the Z80 FSM to recreate the Z80 external signal transactions.
|
||||
if(Z80_CLK_TGL = '1') then
|
||||
|
||||
-- The FSM advances to the next stage on each Z80 edge unless in Idle state.
|
||||
@@ -704,7 +819,7 @@ begin
|
||||
|
||||
when IdleCycle =>
|
||||
CPU_LAST_T_STATE <= '1';
|
||||
-- FSM_STATE <= IdleCycle;
|
||||
FSM_STATUS <= '0';
|
||||
|
||||
-----------------------------
|
||||
-- Z80 Fetch Cycle.
|
||||
@@ -727,7 +842,7 @@ begin
|
||||
|
||||
when FetchCycle_30 =>
|
||||
-- To meet the timing diagrams, just after Rising edge on T3 clear signals. Data wont be available until
|
||||
-- a short period before the falling edge of T3 (could be an MZ-2000 design restriction or the Z80 timing diagrams are a bit out).
|
||||
-- a short period before the falling edge of T3.
|
||||
FSM_STATE <= RefreshCycle;
|
||||
|
||||
-----------------------------
|
||||
@@ -736,18 +851,18 @@ begin
|
||||
when RefreshCycle =>
|
||||
-- Latch data from mainboard.
|
||||
CPU_DATA_IN <= Z80_DATA;
|
||||
FSM_STATUS <= '0';
|
||||
Z80_RFSHni <= '0';
|
||||
|
||||
when RefreshCycle_11 =>
|
||||
-- Falling edge of T3 activates the MREQ line.
|
||||
Z80_MREQni <= '0';
|
||||
FSM_STATUS <= '0';
|
||||
|
||||
when RefreshCycle_20 =>
|
||||
|
||||
when RefreshCycle_21 =>
|
||||
Z80_MREQni <= '1';
|
||||
REFRESH_ADDR(6 downto 0) <= REFRESH_ADDR(6 downto 0) + 1;
|
||||
REFRESH_ADDR <= REFRESH_ADDR + 1;
|
||||
FSM_STATE <= IdleCycle;
|
||||
|
||||
when RefreshCycle_3 =>
|
||||
@@ -769,7 +884,7 @@ begin
|
||||
when WriteCycle_21 =>
|
||||
Z80_WRni <= '0';
|
||||
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
|
||||
FSM_STATE <= WriteCycle_20;
|
||||
FSM_STATE <= WriteCycle_20;
|
||||
end if;
|
||||
|
||||
when WriteCycle_30 =>
|
||||
@@ -794,7 +909,7 @@ begin
|
||||
|
||||
when ReadCycle_21 =>
|
||||
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
|
||||
FSM_STATE <= ReadCycle_20;
|
||||
FSM_STATE <= ReadCycle_20;
|
||||
end if;
|
||||
|
||||
when ReadCycle_30 =>
|
||||
@@ -805,7 +920,6 @@ begin
|
||||
FSM_STATUS <= '0';
|
||||
FSM_STATE <= IdleCycle;
|
||||
|
||||
|
||||
-----------------------------
|
||||
-- Z80 IO Write Cycle.
|
||||
-----------------------------
|
||||
@@ -825,7 +939,7 @@ begin
|
||||
|
||||
when WriteIOCycle_31 =>
|
||||
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
|
||||
FSM_STATE <= WriteIOCycle_20;
|
||||
FSM_STATE <= WriteIOCycle_30;
|
||||
end if;
|
||||
|
||||
when WriteIOCycle_40 =>
|
||||
@@ -854,7 +968,7 @@ begin
|
||||
|
||||
when ReadIOCycle_31 =>
|
||||
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
|
||||
FSM_STATE <= ReadIOCycle_20;
|
||||
FSM_STATE <= ReadIOCycle_30;
|
||||
end if;
|
||||
|
||||
when ReadIOCycle_40 =>
|
||||
@@ -902,8 +1016,6 @@ begin
|
||||
Z80_DATA <= CPU_DATA_OUT when Z80_BUSRQ_ACKni = '1' and CPU_DATA_EN = '1'
|
||||
else
|
||||
(others => 'Z');
|
||||
-- Z80_DATAi <= Z80_DATA when Z80_RDn = '0'
|
||||
-- else (others => '1');
|
||||
Z80_RDn <= Z80_RDni when Z80_BUSRQ_ACKni = '1'
|
||||
else 'Z';
|
||||
Z80_WRn <= Z80_WRni when Z80_BUSRQ_ACKni = '1'
|
||||
@@ -944,7 +1056,7 @@ begin
|
||||
|
||||
-- Signal mirrors.
|
||||
VSOM_READY <= '0' when FSM_STATUS='1' or SPI_NEW_DATA /= SPI_PROCESSING
|
||||
else '1'; -- FSM Ready (1), Busy (0)
|
||||
else '1'; -- FSM Ready (1), Busy (0)
|
||||
VSOM_LTSTATE <= '1' when CPU_LAST_T_STATE = '1' -- Last T-State in current cycle.
|
||||
else '0';
|
||||
VSOM_BUSRQ <= not Z80_BUSRQn; -- Host device requesting Z80 Bus.
|
||||
@@ -981,5 +1093,9 @@ begin
|
||||
-- DAC clocks.
|
||||
--VGA_PXL_CLK <= CLK_50M;
|
||||
MONO_PXL_CLK <= VGA_PXL_CLK;
|
||||
|
||||
-- Currently unassigned.
|
||||
VGA_COLR <= '0';
|
||||
MONO_RSV <= '0';
|
||||
|
||||
end architecture;
|
||||
|
||||
4
CPLD/v1.0/MZ700/build/tzpuFusionX_MZ700.qsf
vendored
4
CPLD/v1.0/MZ700/build/tzpuFusionX_MZ700.qsf
vendored
@@ -127,10 +127,10 @@ set_location_assignment PIN_21 -to VSOM_RSV[1]
|
||||
# SOM Control Signals
|
||||
# ===================
|
||||
set_location_assignment PIN_28 -to VSOM_READY
|
||||
set_location_assignment PIN_18 -to VSOM_LTSTATE
|
||||
set_location_assignment PIN_19 -to VSOM_LTSTATE
|
||||
set_location_assignment PIN_27 -to VSOM_BUSRQ
|
||||
set_location_assignment PIN_26 -to VSOM_BUSACK
|
||||
set_location_assignment PIN_19 -to VSOM_INT
|
||||
set_location_assignment PIN_18 -to VSOM_INT
|
||||
set_location_assignment PIN_22 -to VSOM_NMI
|
||||
set_location_assignment PIN_25 -to VSOM_WAIT
|
||||
set_location_assignment PIN_23 -to VSOM_RESET
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
4
CPLD/v1.0/MZ80A/build/tzpuFusionX_MZ80A.qsf
vendored
4
CPLD/v1.0/MZ80A/build/tzpuFusionX_MZ80A.qsf
vendored
@@ -127,10 +127,10 @@ set_location_assignment PIN_21 -to VSOM_RSV[1]
|
||||
# SOM Control Signals
|
||||
# ===================
|
||||
set_location_assignment PIN_28 -to VSOM_READY
|
||||
set_location_assignment PIN_18 -to VSOM_LTSTATE
|
||||
set_location_assignment PIN_19 -to VSOM_LTSTATE
|
||||
set_location_assignment PIN_27 -to VSOM_BUSRQ
|
||||
set_location_assignment PIN_26 -to VSOM_BUSACK
|
||||
set_location_assignment PIN_19 -to VSOM_INT
|
||||
set_location_assignment PIN_18 -to VSOM_INT
|
||||
set_location_assignment PIN_22 -to VSOM_NMI
|
||||
set_location_assignment PIN_25 -to VSOM_WAIT
|
||||
set_location_assignment PIN_23 -to VSOM_RESET
|
||||
|
||||
@@ -9,9 +9,13 @@
|
||||
-- for the MZ-80A.
|
||||
--
|
||||
-- Credits:
|
||||
-- Copyright: (c) 2018-22 Philip Smart <philip.smart@net2net.org>
|
||||
-- Copyright: (c) 2018-23 Philip Smart <philip.smart@net2net.org>
|
||||
--
|
||||
-- History: Nov 2022 - Initial write for the MZ-2000, adaption to MZ-80A underway.
|
||||
-- History: Nov 2022 v1.0 - Initial write for the MZ-2000, adaption to the MZ-80A.
|
||||
-- Feb 2023 v1.1 - Updates, after numerous tests to try and speed up the Z80 transaction
|
||||
-- from SSD202 issuing a command to data being returned. Source now
|
||||
-- different to the MZ-700/MZ-2000 so will need back porting.
|
||||
-- Apr 2023 v1.2 - Updated from the PCW8256 development.
|
||||
--
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
-- This source file is free software: you can redistribute it and-or modify
|
||||
@@ -128,7 +132,7 @@ end entity;
|
||||
|
||||
architecture rtl of cpld512 is
|
||||
|
||||
-- Finite State Machine states.
|
||||
-- Z80 Finite State Machine states.
|
||||
type SOMFSMState is
|
||||
(
|
||||
IdleCycle,
|
||||
@@ -174,6 +178,14 @@ architecture rtl of cpld512 is
|
||||
BusReqCycle
|
||||
);
|
||||
|
||||
-- Controller FSM states.
|
||||
type CTRLFSMState is
|
||||
(
|
||||
CTRLCMD_Idle,
|
||||
CTRLCMD_ReadIOWrite,
|
||||
CTRLCMD_ReadIOWrite_1
|
||||
);
|
||||
|
||||
-- CPU Interface internal signals.
|
||||
signal Z80_BUSRQni : std_logic;
|
||||
signal Z80_INTni : std_logic;
|
||||
@@ -185,7 +197,6 @@ architecture rtl of cpld512 is
|
||||
signal Z80_HALTni : std_logic;
|
||||
signal Z80_M1ni : std_logic;
|
||||
signal Z80_RFSHni : std_logic;
|
||||
signal Z80_DATAi : std_logic_vector(7 downto 0);
|
||||
signal Z80_BUSRQ_ACKni : std_logic;
|
||||
|
||||
-- Internal CPU state control.
|
||||
@@ -203,14 +214,15 @@ architecture rtl of cpld512 is
|
||||
|
||||
-- Refresh control.
|
||||
signal FSM_STATE : SOMFSMState := IdleCycle;
|
||||
signal NEW_SPI_CMD : std_logic := '0';
|
||||
signal CTRL_STATE : CTRLFSMState := CTRLCMD_Idle;
|
||||
signal NEW_SPI_DATA : std_logic := '0';
|
||||
signal VCPU_CS_EDGE : std_logic_vector(1 downto 0) := "11";
|
||||
signal AUTOREFRESH_CNT : integer range 0 to 7;
|
||||
signal AUTOREFRESH_CNT : integer range 0 to 31;
|
||||
signal FSM_STATUS : std_logic := '0';
|
||||
signal FSM_CHECK_WAIT : std_logic := '0';
|
||||
signal FSM_WAIT_ACTIVE : std_logic := '0';
|
||||
signal RFSH_STATUS : std_logic := '0';
|
||||
signal REFRESH_ADDR : std_logic_vector(7 downto 0);
|
||||
signal REFRESH_ADDR : std_logic_vector(6 downto 0);
|
||||
signal IPAR : std_logic_vector(7 downto 0);
|
||||
signal AUTOREFRESH : std_logic;
|
||||
|
||||
@@ -229,11 +241,12 @@ architecture rtl of cpld512 is
|
||||
signal SPI_RX_SREG : std_logic_vector(7 downto 0); -- RX Shift Register
|
||||
signal SPI_TX_DATA : std_logic_vector(31 downto 0); -- Data to transmit.
|
||||
signal SPI_RX_DATA : std_logic_vector(31 downto 0); -- Data received.
|
||||
signal SPI_BIT_CNT : integer range 0 to 16; -- Count of bits tx/rx'd.
|
||||
signal SPI_BIT_CNT : integer range 0 to 7; -- Count of bits tx/rx'd.
|
||||
signal SPI_FRAME_CNT : integer range 0 to 4; -- Number of frames received (8bit chunks).
|
||||
|
||||
-- SPI Command interface.
|
||||
signal SOM_CMD : std_logic_vector(7 downto 0) := (others => '0');
|
||||
signal SOM_PARAM_CNT : integer range 0 to 3;
|
||||
signal SPI_NEW_DATA : std_logic;
|
||||
signal SPI_PROCESSING : std_logic;
|
||||
signal SPI_CPU_ADDR : std_logic_vector(15 downto 0) := (others => '0');
|
||||
@@ -272,7 +285,7 @@ begin
|
||||
-- On the second edge, if occurring within 1 second of the first, the PM_RESET signal to the SOM is triggered, held low for 1 second,
|
||||
-- forcing the SOM to reboot.
|
||||
SYSRESET: process( Z80_CLKi, Z80_RESETn )
|
||||
variable timer1 : integer range 0 to 354000 := 0;
|
||||
variable timer1 : integer range 0 to 200000 := 0;
|
||||
variable timer100 : integer range 0 to 10 := 0;
|
||||
variable timerPMReset : integer range 0 to 10 := 0;
|
||||
variable resetCount : integer range 0 to 3 := 0;
|
||||
@@ -308,7 +321,7 @@ begin
|
||||
end if;
|
||||
|
||||
-- 100ms interval.
|
||||
if(timer1 = 354000) then
|
||||
if(timer1 = 200000) then
|
||||
timer100 := timer100 + 1;
|
||||
|
||||
if(timer100 >= 10) then
|
||||
@@ -337,8 +350,11 @@ begin
|
||||
-- SPI Slave input. Receive command and data from the SOM.
|
||||
SPI_INPUT : process(VSOM_SPI_CLK)
|
||||
begin
|
||||
-- Chip Select inactive, disable process and reset control flags.
|
||||
if(VSOM_SPI_CSn = '1') then
|
||||
|
||||
-- SPI_CLK_POLARITY='0' => falling edge; SPI_CLK_POLARITY='1' => rising edge
|
||||
if(VSOM_SPI_CLK'event and VSOM_SPI_CLK = SPI_CLK_POLARITY) then
|
||||
elsif(VSOM_SPI_CLK'event and VSOM_SPI_CLK = SPI_CLK_POLARITY) then
|
||||
if(VSOM_SPI_CSn = '0') then
|
||||
SPI_RX_SREG <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
|
||||
|
||||
@@ -353,7 +369,7 @@ begin
|
||||
elsif(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 3 and SPI_BIT_CNT = 0) then
|
||||
SPI_RX_DATA(23 downto 16) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
|
||||
|
||||
elsif(SPI_SHIFT_EN = '1' and SPI_FRAME_CNT = 4 and SPI_BIT_CNT = 0) then
|
||||
elsif(SPI_FRAME_CNT = 4 and SPI_BIT_CNT = 0) then
|
||||
SPI_RX_DATA(31 downto 24) <= SPI_RX_SREG(6 downto 0) & VSOM_SPI_MOSI;
|
||||
end if;
|
||||
end if;
|
||||
@@ -363,18 +379,22 @@ begin
|
||||
-- SPI Slave output. Return the current data set as selected by the input signals XACT.
|
||||
SPI_OUTPUT : process(VSOM_SPI_CLK,VSOM_SPI_CSn,SPI_TX_DATA)
|
||||
begin
|
||||
-- Chip Select inactive, disable process and reset control flags.
|
||||
if(VSOM_SPI_CSn = '1') then
|
||||
SPI_SHIFT_EN <= '0';
|
||||
SPI_BIT_CNT <= 15;
|
||||
SPI_BIT_CNT <= 7;
|
||||
|
||||
-- SPI_CLK_POLARITY='0' => falling edge; SPI_CLK_POLARITY='1' => risinge edge
|
||||
elsif(VSOM_SPI_CLK'event and VSOM_SPI_CLK = not SPI_CLK_POLARITY) then
|
||||
-- Each clock reset the shift enable and done flag in preparation for the next cycle.
|
||||
SPI_SHIFT_EN <= '1';
|
||||
|
||||
-- Bit count decrements to detect when last bit of byte is sent.
|
||||
if(SPI_BIT_CNT > 0) then
|
||||
SPI_BIT_CNT <= SPI_BIT_CNT - 1;
|
||||
end if;
|
||||
|
||||
-- Shift out the next bit.
|
||||
VSOM_SPI_MISO <= SPI_TX_SREG(6);
|
||||
SPI_TX_SREG <= SPI_TX_SREG(5 downto 0) & '0';
|
||||
|
||||
@@ -389,6 +409,7 @@ begin
|
||||
SPI_FRAME_CNT<= 1;
|
||||
VSOM_SPI_MISO<= SPI_TX_DATA(7);
|
||||
SPI_TX_SREG <= SPI_TX_DATA(6 downto 0);
|
||||
-- Increment frame count for each word received. We handle 8bit (1 frame), 16bit (2 frames) or 32bit (4 frames) reception.
|
||||
elsif(SPI_FRAME_CNT = 1) then
|
||||
SPI_FRAME_CNT<= 2;
|
||||
VSOM_SPI_MISO<= SPI_TX_DATA(15);
|
||||
@@ -397,13 +418,14 @@ begin
|
||||
SPI_FRAME_CNT<= 3;
|
||||
VSOM_SPI_MISO<= SPI_TX_DATA(23);
|
||||
SPI_TX_SREG <= SPI_TX_DATA(22 downto 16);
|
||||
else
|
||||
elsif(SPI_FRAME_CNT = 3) then
|
||||
-- Increment frame count for each word received. We handle 8bit (1 frame), 16bit (2 frames) or 32bit (4 frames) reception.
|
||||
SPI_FRAME_CNT<= 4;
|
||||
VSOM_SPI_MISO<= SPI_TX_DATA(31);
|
||||
SPI_TX_SREG <= SPI_TX_DATA(30 downto 24);
|
||||
else
|
||||
SPI_FRAME_CNT<= 0;
|
||||
end if;
|
||||
|
||||
SPI_BIT_CNT <= 7;
|
||||
end if;
|
||||
end if;
|
||||
@@ -421,6 +443,7 @@ begin
|
||||
AUTOREFRESH <= '0';
|
||||
SPI_LOOPBACK_TEST <= '0';
|
||||
SOM_CMD <= (others => '0');
|
||||
SOM_PARAM_CNT <= 0;
|
||||
SPI_CPU_ADDR <= (others => '0');
|
||||
SPI_NEW_DATA <= '0';
|
||||
|
||||
@@ -429,6 +452,7 @@ begin
|
||||
-- for 8bit, 16bit and 32bit transmissions.
|
||||
-- The packet is formatted as follows:
|
||||
--
|
||||
-- < SPI_CPU_ADDR > < SPI_CPU_DATA >< SOM_CMD>
|
||||
-- < SPI_FRAME_CNT=4 >< SPI_FRAME=3 > < SPI_FRAME_CNT=2 >< SPI_FRAME_CNT=1>
|
||||
-- < 16bit Z80 Address > < Z80 Data ><Command=00..80>
|
||||
-- 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
|
||||
@@ -438,66 +462,110 @@ begin
|
||||
--
|
||||
elsif(VSOM_SPI_CSn'event and VSOM_SPI_CSn = '1') then
|
||||
|
||||
-- Command is always located in the upper byte of frame 1.
|
||||
SOM_CMD <= SPI_RX_DATA(7 downto 0);
|
||||
-- If active, decrement parameter count. Parameters sent after a command are not considered as commands.
|
||||
if(SOM_PARAM_CNT > 0) then
|
||||
SOM_PARAM_CNT <= SOM_PARAM_CNT - 1;
|
||||
end if;
|
||||
|
||||
-- Toggle flag to indicate new data arrived.
|
||||
SPI_NEW_DATA <= not SPI_NEW_DATA;
|
||||
-- Process if command, store parameters.
|
||||
if(SOM_PARAM_CNT = 0) then
|
||||
-- Command is always located in the upper byte of frame 1.
|
||||
SOM_CMD <= SPI_RX_DATA(7 downto 0);
|
||||
|
||||
-- Process the command. Some commands require the FSM, others can be serviced immediately.
|
||||
case SPI_RX_DATA(7 downto 0) is
|
||||
-- Toggle flag to indicate new data arrived.
|
||||
SPI_NEW_DATA <= not SPI_NEW_DATA;
|
||||
|
||||
-- Z80XACT(0..15): Setup data and address as provided then execute FSM.
|
||||
when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17" | -- Fetch
|
||||
X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" | -- Write
|
||||
X"20" | X"21" | X"22" | X"23" | X"24" | X"25" | X"26" | X"27" | -- Read
|
||||
X"28" | X"29" | X"2A" | X"2B" | X"2C" | X"2D" | X"2E" | X"2F" | -- WriteIO
|
||||
X"30" | X"31" | X"32" | X"33" | X"34" | X"35" | X"36" | X"37" | -- ReadIO
|
||||
X"38" | X"39" | X"3A" | X"3B" | X"3C" | X"3D" | X"3E" | X"3F" | --
|
||||
X"40" | X"41" | X"42" | X"43" | X"44" | X"45" | X"46" | X"47" | --
|
||||
X"48" | X"49" | X"4A" | X"4B" | X"4C" | X"4D" | X"4E" | X"4F" =>
|
||||
-- Process the command. Some commands require the FSM, others can be serviced immediately.
|
||||
case SPI_RX_DATA(7 downto 0) is
|
||||
|
||||
-- Direct address set.
|
||||
if(SPI_FRAME_CNT = 4) then
|
||||
SPI_CPU_ADDR <= SPI_RX_DATA(31 downto 16);
|
||||
else
|
||||
-- if(SPI_CPU_ADDR >= X"D010" and SPI_CPU_ADDR < X"D020") then
|
||||
-- SPI_CPU_ADDR <= std_logic_vector(X"D020" + unsigned(SPI_RX_DATA(2 downto 0)));
|
||||
-- else
|
||||
SPI_CPU_ADDR <= std_logic_vector(unsigned(SPI_CPU_ADDR) + unsigned(SPI_RX_DATA(2 downto 0)));
|
||||
-- end if;
|
||||
end if;
|
||||
-- Z80XACT(0..15): Setup data and address as provided then execute FSM.
|
||||
when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17" | -- Fetch
|
||||
X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" | -- Write
|
||||
X"20" | X"21" | X"22" | X"23" | X"24" | X"25" | X"26" | X"27" | -- Read
|
||||
X"48" | X"49" | X"4A" | X"4B" | X"4C" | X"4D" | X"4E" | X"4F" =>
|
||||
|
||||
if(SPI_FRAME_CNT > 1) then
|
||||
SPI_CPU_DATA <= SPI_RX_DATA(15 downto 8);
|
||||
end if;
|
||||
-- Direct address set.
|
||||
if(SPI_FRAME_CNT = 4) then
|
||||
SPI_CPU_ADDR <= SPI_RX_DATA(31 downto 16);
|
||||
else
|
||||
SPI_CPU_ADDR <= std_logic_vector(unsigned(SPI_CPU_ADDR) + unsigned(SPI_RX_DATA(2 downto 0)));
|
||||
end if;
|
||||
|
||||
-- SETSIGSET1: Set control lines directly.
|
||||
when X"F0" =>
|
||||
VIDEO_SRCi <= SPI_RX_DATA(8);
|
||||
MONO_VIDEO_SRCi <= SPI_RX_DATA(9);
|
||||
AUDIO_SRC_Li <= SPI_RX_DATA(10);
|
||||
AUDIO_SRC_Ri <= SPI_RX_DATA(11);
|
||||
VBUS_ENi <= SPI_RX_DATA(12);
|
||||
VGA_BLANKn <= not SPI_RX_DATA(13);
|
||||
if(SPI_FRAME_CNT > 1) then
|
||||
SPI_CPU_DATA <= SPI_RX_DATA(15 downto 8);
|
||||
end if;
|
||||
|
||||
-- Enable auto refresh DRAM cycle.
|
||||
when X"F1" =>
|
||||
AUTOREFRESH <= '1';
|
||||
when X"28" | X"29" | X"2A" | X"2B" | X"2C" | X"2D" | X"2E" | X"2F" => -- WriteIO
|
||||
|
||||
-- Disable auto refresh DRAM cycle.
|
||||
when X"F2" =>
|
||||
AUTOREFRESH <= '0';
|
||||
-- Direct address set.
|
||||
if(SPI_FRAME_CNT = 4) then
|
||||
SPI_CPU_ADDR <= SPI_RX_DATA(31 downto 16);
|
||||
else
|
||||
SPI_CPU_ADDR <= X"000" & '0' & std_logic_vector(unsigned(SPI_RX_DATA(2 downto 0)));
|
||||
end if;
|
||||
|
||||
-- SETLOOPBACK: Enable loopback test mode.
|
||||
when X"FE" =>
|
||||
SPI_LOOPBACK_TEST<= '1';
|
||||
if(SPI_FRAME_CNT > 1) then
|
||||
SPI_CPU_DATA <= SPI_RX_DATA(15 downto 8);
|
||||
end if;
|
||||
|
||||
-- No action, called to retrieve status.
|
||||
when X"00" | X"FF" =>
|
||||
when X"30" | X"31" | X"32" | X"33" | X"34" | X"35" | X"36" | X"37" | -- ReadIO
|
||||
X"38" | X"39" | X"3A" | X"3B" | X"3C" | X"3D" | X"3E" | X"3F" => -- ReadIO-Write
|
||||
|
||||
when others =>
|
||||
end case;
|
||||
-- Direct address set.
|
||||
if(SPI_FRAME_CNT = 4) then
|
||||
SPI_CPU_ADDR <= SPI_RX_DATA(31 downto 16);
|
||||
elsif(SPI_FRAME_CNT = 2) then
|
||||
SPI_CPU_ADDR <= X"00" & SPI_RX_DATA(15 downto 8);
|
||||
else
|
||||
SPI_CPU_ADDR <= X"000" & '0' & std_logic_vector(unsigned(SPI_RX_DATA(2 downto 0)));
|
||||
end if;
|
||||
|
||||
if(SPI_FRAME_CNT > 1) then
|
||||
SPI_CPU_DATA <= SPI_RX_DATA(15 downto 8);
|
||||
end if;
|
||||
|
||||
-- ReadIO-Write, Read-WriteIO commands require target address, so indicate parameter needed.
|
||||
if(SPI_RX_DATA(7 downto 0) >= X"38" and SPI_RX_DATA(7 downto 0) < X"40") then
|
||||
SOM_PARAM_CNT <= 1;
|
||||
end if;
|
||||
|
||||
-- SETSIGSET1: Set control lines directly.
|
||||
when X"F0" =>
|
||||
VIDEO_SRCi <= SPI_RX_DATA(8);
|
||||
MONO_VIDEO_SRCi <= SPI_RX_DATA(9);
|
||||
AUDIO_SRC_Li <= SPI_RX_DATA(10);
|
||||
AUDIO_SRC_Ri <= SPI_RX_DATA(11);
|
||||
VBUS_ENi <= SPI_RX_DATA(12);
|
||||
VGA_BLANKn <= not SPI_RX_DATA(13);
|
||||
|
||||
-- Enable auto refresh DRAM cycle.
|
||||
when X"F1" =>
|
||||
AUTOREFRESH <= '1';
|
||||
|
||||
-- Disable auto refresh DRAM cycle.
|
||||
when X"F2" =>
|
||||
AUTOREFRESH <= '0';
|
||||
|
||||
-- SETLOOPBACK: Enable loopback test mode.
|
||||
when X"FE" =>
|
||||
SPI_LOOPBACK_TEST<= '1';
|
||||
|
||||
-- No action, called to retrieve status.
|
||||
when X"00" | X"FF" =>
|
||||
|
||||
when others =>
|
||||
end case;
|
||||
else
|
||||
-- Store parameter depending on number of frames, either ADDR+DATA, ADDR or DATA.
|
||||
if(SPI_FRAME_CNT = 4) then
|
||||
SPI_CPU_ADDR <= SPI_RX_DATA(31 downto 16);
|
||||
SPI_CPU_DATA <= SPI_RX_DATA(15 downto 8);
|
||||
elsif(SPI_FRAME_CNT = 2) then
|
||||
SPI_CPU_ADDR <= SPI_RX_DATA(15 downto 0);
|
||||
else
|
||||
SPI_CPU_DATA <= SPI_RX_DATA(7 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
@@ -558,9 +626,9 @@ begin
|
||||
CPU_DATA_EN <= '0';
|
||||
CPU_DATA_IN <= (others => '0');
|
||||
REFRESH_ADDR <= (others => '0');
|
||||
AUTOREFRESH_CNT <= 7;
|
||||
AUTOREFRESH_CNT <= 31;
|
||||
IPAR <= (others => '0');
|
||||
NEW_SPI_CMD <= '0';
|
||||
NEW_SPI_DATA <= '0';
|
||||
VCPU_CS_EDGE <= "11";
|
||||
SPI_PROCESSING <= '0';
|
||||
|
||||
@@ -577,98 +645,12 @@ begin
|
||||
|
||||
-- New command, set flag as the signal is only 1 clock wide.
|
||||
if(SPI_LOOPBACK_TEST = '0' and VSOM_SPI_CSn = '1' and VCPU_CS_EDGE = "01") then
|
||||
NEW_SPI_CMD <= '1';
|
||||
NEW_SPI_DATA <= '1';
|
||||
end if;
|
||||
|
||||
-- Whenever we return to Idle or just prior to Refresh from a Fetch cycle set all control signals to default.
|
||||
if(FSM_STATE = IdleCycle or FSM_STATE = RefreshCycle) then
|
||||
CPU_DATA_EN <= '0';
|
||||
Z80_MREQni <= '1';
|
||||
Z80_IORQni <= '1';
|
||||
Z80_RDni <= '1';
|
||||
Z80_WRni <= '1';
|
||||
Z80_M1ni <= '1';
|
||||
FSM_STATUS <= '0';
|
||||
Z80_RFSHni <= '1';
|
||||
|
||||
-- Auto DRAM refresh cycles. When enabled, every 7 host clock cycles, a 2 cycle refresh period commences.
|
||||
-- This will be overriden if the SPI receives a new command.
|
||||
--
|
||||
if AUTOREFRESH = '1' and FSM_STATE = IdleCycle then
|
||||
AUTOREFRESH_CNT <= AUTOREFRESH_CNT - 1;
|
||||
if(AUTOREFRESH_CNT = 0) then
|
||||
FSM_STATE <= RefreshCycle_3;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
-- If new command has been given and the FSM enters idle state, load up new command for processing.
|
||||
if(NEW_SPI_CMD = '1' and FSM_STATE = IdleCycle and Z80_CLK_RE = '1') then
|
||||
NEW_SPI_CMD <= '0';
|
||||
|
||||
-- Store new address and data for this command.
|
||||
CPU_ADDR <= SPI_CPU_ADDR;
|
||||
if(SPI_CPU_DATA /= CPU_DATA_OUT) then
|
||||
CPU_DATA_OUT <= SPI_CPU_DATA;
|
||||
end if;
|
||||
|
||||
-- Process the SOM command. The SPI_REGISTER executes non FSM commands and stores FSM
|
||||
-- data prior to this execution block, which fires 1 cycle later on the same control clock.
|
||||
-- If the command is not for the FSM then the READY mechanism is held for one
|
||||
-- further cycle before going inactive.
|
||||
case SOM_CMD is
|
||||
when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17" =>
|
||||
-- Initiate a Fetch Cycle.
|
||||
FSM_STATE <= FetchCycle;
|
||||
|
||||
when X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" =>
|
||||
|
||||
-- Set the Z80 data bus value and initiate a Write Cycle.
|
||||
FSM_STATE <= WriteCycle;
|
||||
|
||||
when X"20" | X"21" | X"22" | X"23" | X"24" | X"25" | X"26" | X"27" =>
|
||||
-- Initiate a Read Cycle.
|
||||
FSM_STATE <= ReadCycle;
|
||||
|
||||
when X"28" | X"29" | X"2A" | X"2B" | X"2C" | X"2D" | X"2E" | X"2F" =>
|
||||
-- Set the Z80 data bus value and initiate an IO Write Cycle.
|
||||
-- The SOM should set 15:8 to the B register value.
|
||||
FSM_STATE <= WriteIOCycle;
|
||||
|
||||
when X"30" | X"31" | X"32" | X"33" | X"34" | X"35" | X"36" | X"37" =>
|
||||
-- Initiate a Read IO Cycle.
|
||||
FSM_STATE <= ReadIOCycle;
|
||||
|
||||
when X"50" =>
|
||||
-- Register a Halt state.
|
||||
FSM_STATE <= HaltCycle;
|
||||
|
||||
when X"51" =>
|
||||
-- Initiate a refresh cycle.
|
||||
FSM_STATE <= RefreshCycle_3;
|
||||
|
||||
when X"E0" =>
|
||||
-- Initiate a Halt Cycle.
|
||||
FSM_STATE <= HaltCycle;
|
||||
|
||||
-- Set the Refresh Address register.
|
||||
when X"E1" =>
|
||||
REFRESH_ADDR <= CPU_DATA_OUT;
|
||||
|
||||
-- Set the Interrupt Page Address Register.
|
||||
when X"E2" =>
|
||||
IPAR <= CPU_DATA_OUT;
|
||||
|
||||
when others =>
|
||||
end case;
|
||||
|
||||
-- Toggle the processing flag to negate the new data flag. Used to indicate device is busy.
|
||||
if(SPI_NEW_DATA /= SPI_PROCESSING) then
|
||||
SPI_PROCESSING <= not SPI_PROCESSING;
|
||||
end if;
|
||||
|
||||
-- FSM Status bit. When processing a command it is set, cleared when idle. Used by SOM to determine command completion.
|
||||
FSM_STATUS <= '1';
|
||||
-- Decrement refresh counter on each Z80 cycle, thus when idle and time expired, a refresh can be performed within parameters (256 cycles in 4ms).
|
||||
if(AUTOREFRESH = '1' and AUTOREFRESH_CNT /= 0 and Z80_CLK_RE = '1') then
|
||||
AUTOREFRESH_CNT <= AUTOREFRESH_CNT - 1;
|
||||
end if;
|
||||
|
||||
-- Refresh status bit. Indicates a Refresh cycle is under way.
|
||||
@@ -683,7 +665,143 @@ begin
|
||||
FSM_WAIT_ACTIVE <= '1';
|
||||
end if;
|
||||
|
||||
-- On each Z80 edge we advance the FSM to recreate the Z80 external signal transactions.
|
||||
-- Whenever we return to Idle or just prior to Refresh from a Fetch cycle set all control signals to default.
|
||||
if((FSM_STATE = IdleCycle or FSM_STATE = RefreshCycle) and Z80_CLK_RE = '1') then
|
||||
CPU_DATA_EN <= '0';
|
||||
Z80_MREQni <= '1';
|
||||
Z80_IORQni <= '1';
|
||||
Z80_RDni <= '1';
|
||||
Z80_WRni <= '1';
|
||||
Z80_M1ni <= '1';
|
||||
FSM_STATUS <= '0';
|
||||
Z80_RFSHni <= '1';
|
||||
|
||||
-- Auto DRAM refresh cycles. When enabled, every 15.6us a refresh period commences.
|
||||
-- This period may be extended if the SPI receives a new command.
|
||||
--
|
||||
if AUTOREFRESH = '1' and FSM_STATE = IdleCycle then
|
||||
if(AUTOREFRESH_CNT = 0) then
|
||||
FSM_STATE <= RefreshCycle_3;
|
||||
FSM_STATUS<= '1';
|
||||
-- 4116 DRAM = 128 cycles in 2ms.
|
||||
AUTOREFRESH_CNT <= 31;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
--------------------------------------------------------------------------------------------
|
||||
-- CPLD Macro Command Finite State Machine.
|
||||
--------------------------------------------------------------------------------------------
|
||||
|
||||
-- Controller state machine.
|
||||
-- When idle, accept and process SPI commands which can lead to a controller macro command.
|
||||
case CTRL_STATE is
|
||||
|
||||
when CTRLCMD_Idle =>
|
||||
-- If new command has been given and the FSM enters idle state, load up new command for processing.
|
||||
if(NEW_SPI_DATA = '1' and FSM_STATE = IdleCycle and Z80_CLK_RE = '1') then
|
||||
|
||||
-- Store new address and data for this command.
|
||||
if(NEW_SPI_DATA = '1') then
|
||||
CPU_ADDR <= SPI_CPU_ADDR;
|
||||
CPU_DATA_OUT <= SPI_CPU_DATA;
|
||||
end if;
|
||||
|
||||
-- Process the SOM command. The SPI_REGISTER executes non FSM commands and stores FSM
|
||||
-- data prior to this execution block, which fires 1 cycle later on the same control clock.
|
||||
-- If the command is not for the FSM then the READY mechanism is held for one
|
||||
-- further cycle before going inactive.
|
||||
case SOM_CMD is
|
||||
when X"10" | X"11" | X"12" | X"13" | X"14" | X"15" | X"16" | X"17" =>
|
||||
-- Initiate a Fetch Cycle.
|
||||
FSM_STATE <= FetchCycle;
|
||||
|
||||
when X"18" | X"19" | X"1A" | X"1B" | X"1C" | X"1D" | X"1E" | X"1F" =>
|
||||
|
||||
-- Set the Z80 data bus value and initiate a Write Cycle.
|
||||
FSM_STATE <= WriteCycle;
|
||||
|
||||
when X"20" | X"21" | X"22" | X"23" | X"24" | X"25" | X"26" | X"27" =>
|
||||
-- Initiate a Read Cycle.
|
||||
FSM_STATE <= ReadCycle;
|
||||
|
||||
when X"28" | X"29" | X"2A" | X"2B" | X"2C" | X"2D" | X"2E" | X"2F" =>
|
||||
-- Set the Z80 data bus value and initiate an IO Write Cycle.
|
||||
-- The SOM should set 15:8 to the B register value.
|
||||
FSM_STATE <= WriteIOCycle;
|
||||
|
||||
when X"30" | X"31" | X"32" | X"33" | X"34" | X"35" | X"36" | X"37" =>
|
||||
-- Initiate a Read IO Cycle.
|
||||
FSM_STATE <= ReadIOCycle;
|
||||
|
||||
when X"38" | X"39" | X"3A" | X"3B" | X"3C" | X"3D" | X"3E" | X"3F" =>
|
||||
-- Initiate a read IO write memory cycle via the controller FSM.
|
||||
CTRL_STATE <= CTRLCMD_ReadIOWrite;
|
||||
FSM_STATE <= ReadIOCycle;
|
||||
|
||||
when X"50" =>
|
||||
-- Register a Halt state.
|
||||
FSM_STATE <= HaltCycle;
|
||||
|
||||
when X"51" =>
|
||||
-- Initiate a refresh cycle.
|
||||
FSM_STATE <= RefreshCycle_3;
|
||||
|
||||
when X"E0" =>
|
||||
-- Initiate a Halt Cycle.
|
||||
FSM_STATE <= HaltCycle;
|
||||
|
||||
-- Set the Refresh Address register.
|
||||
when X"E1" =>
|
||||
REFRESH_ADDR <= CPU_DATA_OUT(6 downto 0);
|
||||
|
||||
-- Set the Interrupt Page Address Register.
|
||||
when X"E2" =>
|
||||
IPAR <= CPU_DATA_OUT;
|
||||
|
||||
when others =>
|
||||
end case;
|
||||
|
||||
-- Toggle the processing flag to negate the new data flag. Used to indicate device is busy.
|
||||
if(SPI_NEW_DATA /= SPI_PROCESSING) then
|
||||
SPI_PROCESSING<= not SPI_PROCESSING;
|
||||
end if;
|
||||
|
||||
-- Clear new data flag ready for next cmd/param transfer.
|
||||
NEW_SPI_DATA <= '0';
|
||||
|
||||
-- FSM Status bit. When processing a command it is set, cleared when idle. Used by SOM to determine command completion.
|
||||
FSM_STATUS <= '1';
|
||||
end if;
|
||||
|
||||
when CTRLCMD_ReadIOWrite =>
|
||||
if(NEW_SPI_DATA = '1' and FSM_STATE = IdleCycle and Z80_CLK_RE = '1') then
|
||||
NEW_SPI_DATA <= '0';
|
||||
CPU_DATA_EN <= '0';
|
||||
Z80_IORQni <= '1';
|
||||
Z80_RDni <= '1';
|
||||
Z80_RFSHni <= '1';
|
||||
CPU_ADDR <= SPI_CPU_ADDR;
|
||||
CPU_DATA_OUT <= CPU_DATA_IN;
|
||||
FSM_STATE <= WriteCycle;
|
||||
CTRL_STATE <= CTRLCMD_ReadIOWrite_1;
|
||||
end if;
|
||||
|
||||
when CTRLCMD_ReadIOWrite_1 =>
|
||||
if(FSM_STATE = WriteCycle_31) then
|
||||
CTRL_STATE <= CTRLCMD_Idle;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
CTRL_STATE <= CTRLCMD_Idle;
|
||||
|
||||
end case;
|
||||
|
||||
--------------------------------------------------------------------------------------------
|
||||
-- Z80 Finite State Machine.
|
||||
--------------------------------------------------------------------------------------------
|
||||
|
||||
-- On each Z80 edge we advance the Z80 FSM to recreate the Z80 external signal transactions.
|
||||
if(Z80_CLK_TGL = '1') then
|
||||
|
||||
-- The FSM advances to the next stage on each Z80 edge unless in Idle state.
|
||||
@@ -701,7 +819,7 @@ begin
|
||||
|
||||
when IdleCycle =>
|
||||
CPU_LAST_T_STATE <= '1';
|
||||
-- FSM_STATE <= IdleCycle;
|
||||
FSM_STATUS <= '0';
|
||||
|
||||
-----------------------------
|
||||
-- Z80 Fetch Cycle.
|
||||
@@ -724,7 +842,7 @@ begin
|
||||
|
||||
when FetchCycle_30 =>
|
||||
-- To meet the timing diagrams, just after Rising edge on T3 clear signals. Data wont be available until
|
||||
-- a short period before the falling edge of T3 (could be an MZ-80A design restriction or the Z80 timing diagrams are a bit out).
|
||||
-- a short period before the falling edge of T3.
|
||||
FSM_STATE <= RefreshCycle;
|
||||
|
||||
-----------------------------
|
||||
@@ -733,18 +851,18 @@ begin
|
||||
when RefreshCycle =>
|
||||
-- Latch data from mainboard.
|
||||
CPU_DATA_IN <= Z80_DATA;
|
||||
FSM_STATUS <= '0';
|
||||
Z80_RFSHni <= '0';
|
||||
|
||||
when RefreshCycle_11 =>
|
||||
-- Falling edge of T3 activates the MREQ line.
|
||||
Z80_MREQni <= '0';
|
||||
FSM_STATUS <= '0';
|
||||
|
||||
when RefreshCycle_20 =>
|
||||
|
||||
when RefreshCycle_21 =>
|
||||
Z80_MREQni <= '1';
|
||||
REFRESH_ADDR(6 downto 0) <= REFRESH_ADDR(6 downto 0) + 1;
|
||||
REFRESH_ADDR <= REFRESH_ADDR + 1;
|
||||
FSM_STATE <= IdleCycle;
|
||||
|
||||
when RefreshCycle_3 =>
|
||||
@@ -766,7 +884,7 @@ begin
|
||||
when WriteCycle_21 =>
|
||||
Z80_WRni <= '0';
|
||||
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
|
||||
FSM_STATE <= WriteCycle_20;
|
||||
FSM_STATE <= WriteCycle_20;
|
||||
end if;
|
||||
|
||||
when WriteCycle_30 =>
|
||||
@@ -791,7 +909,7 @@ begin
|
||||
|
||||
when ReadCycle_21 =>
|
||||
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
|
||||
FSM_STATE <= ReadCycle_20;
|
||||
FSM_STATE <= ReadCycle_20;
|
||||
end if;
|
||||
|
||||
when ReadCycle_30 =>
|
||||
@@ -802,7 +920,6 @@ begin
|
||||
FSM_STATUS <= '0';
|
||||
FSM_STATE <= IdleCycle;
|
||||
|
||||
|
||||
-----------------------------
|
||||
-- Z80 IO Write Cycle.
|
||||
-----------------------------
|
||||
@@ -822,7 +939,7 @@ begin
|
||||
|
||||
when WriteIOCycle_31 =>
|
||||
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
|
||||
FSM_STATE <= WriteIOCycle_20;
|
||||
FSM_STATE <= WriteIOCycle_30;
|
||||
end if;
|
||||
|
||||
when WriteIOCycle_40 =>
|
||||
@@ -851,7 +968,7 @@ begin
|
||||
|
||||
when ReadIOCycle_31 =>
|
||||
if(Z80_WAITn = '0' or FSM_WAIT_ACTIVE = '1') then
|
||||
FSM_STATE <= ReadIOCycle_20;
|
||||
FSM_STATE <= ReadIOCycle_30;
|
||||
end if;
|
||||
|
||||
when ReadIOCycle_40 =>
|
||||
@@ -891,7 +1008,7 @@ begin
|
||||
Z80_CLKi <= not Z80_CLK;
|
||||
|
||||
-- CPU Interface tri-state control based on acknowledged bus request.
|
||||
Z80_ADDR <= IPAR & REFRESH_ADDR when Z80_RFSHni = '0'
|
||||
Z80_ADDR <= IPAR & '0' & REFRESH_ADDR when Z80_RFSHni = '0'
|
||||
else
|
||||
CPU_ADDR when Z80_BUSRQ_ACKni = '1'
|
||||
else
|
||||
@@ -899,8 +1016,6 @@ begin
|
||||
Z80_DATA <= CPU_DATA_OUT when Z80_BUSRQ_ACKni = '1' and CPU_DATA_EN = '1'
|
||||
else
|
||||
(others => 'Z');
|
||||
-- Z80_DATAi <= Z80_DATA when Z80_RDn = '0'
|
||||
-- else (others => '1');
|
||||
Z80_RDn <= Z80_RDni when Z80_BUSRQ_ACKni = '1'
|
||||
else 'Z';
|
||||
Z80_WRn <= Z80_WRni when Z80_BUSRQ_ACKni = '1'
|
||||
@@ -941,7 +1056,7 @@ begin
|
||||
|
||||
-- Signal mirrors.
|
||||
VSOM_READY <= '0' when FSM_STATUS='1' or SPI_NEW_DATA /= SPI_PROCESSING
|
||||
else '1'; -- FSM Ready (1), Busy (0)
|
||||
else '1'; -- FSM Ready (1), Busy (0)
|
||||
VSOM_LTSTATE <= '1' when CPU_LAST_T_STATE = '1' -- Last T-State in current cycle.
|
||||
else '0';
|
||||
VSOM_BUSRQ <= not Z80_BUSRQn; -- Host device requesting Z80 Bus.
|
||||
@@ -978,5 +1093,9 @@ begin
|
||||
-- DAC clocks.
|
||||
--VGA_PXL_CLK <= CLK_50M;
|
||||
MONO_PXL_CLK <= VGA_PXL_CLK;
|
||||
|
||||
-- Currently unassigned.
|
||||
VGA_COLR <= '0';
|
||||
MONO_RSV <= '0';
|
||||
|
||||
end architecture;
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
-- project which targets the MZ-80A host.
|
||||
--
|
||||
-- Credits:
|
||||
-- Copyright: (c) 2018-22 Philip Smart <philip.smart@net2net.org>
|
||||
-- Copyright: (c) 2018-23 Philip Smart <philip.smart@net2net.org>
|
||||
--
|
||||
-- History: Nov 2022 - Snapshot taken from the MZ-2000 version of the tzpuFusionX source.
|
||||
-- History: Nov 2022 v1.0 - Snapshot taken from the MZ-2000 version of the tzpuFusionX source.
|
||||
--
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
-- This source file is free software: you can redistribute it and-or modify
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
-- which targets the MZ-80A host.
|
||||
--
|
||||
-- Credits:
|
||||
-- Copyright: (c) 2018-22 Philip Smart <philip.smart@net2net.org>
|
||||
-- Copyright: (c) 2018-23 Philip Smart <philip.smart@net2net.org>
|
||||
--
|
||||
-- History: Nov 2022 - Snapshot taken from the MZ-2000 version of the tzpuFusionX source.
|
||||
-- History: Nov 2022 v1.0 - Snapshot taken from the MZ-2000 version of the tzpuFusionX source.
|
||||
--
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
-- This source file is free software: you can redistribute it and-or modify
|
||||
|
||||
30
CPLD/v1.0/PCW8256/build/tzpuFusionX_PCW8256.qpf
vendored
Normal file
30
CPLD/v1.0/PCW8256/build/tzpuFusionX_PCW8256.qpf
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 1991-2013 Altera Corporation
|
||||
# Your use of Altera Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License
|
||||
# Subscription Agreement, Altera MegaCore Function License
|
||||
# Agreement, or other applicable license agreement, including,
|
||||
# without limitation, that your use is for the sole purpose of
|
||||
# programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the
|
||||
# applicable agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus II 64-Bit
|
||||
# Version 13.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
|
||||
# Date created = 16:29:32 June 24, 2020
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
QUARTUS_VERSION = "13.0"
|
||||
DATE = "16:29:32 September 10, 2021"
|
||||
|
||||
# Revisions
|
||||
|
||||
PROJECT_REVISION = "tzpuFusionX_PCW8256"
|
||||
243
CPLD/v1.0/PCW8256/build/tzpuFusionX_PCW8256.qsf
vendored
Normal file
243
CPLD/v1.0/PCW8256/build/tzpuFusionX_PCW8256.qsf
vendored
Normal file
@@ -0,0 +1,243 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 1991-2013 Altera Corporation
|
||||
# Your use of Altera Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License
|
||||
# Subscription Agreement, Altera MegaCore Function License
|
||||
# Agreement, or other applicable license agreement, including,
|
||||
# without limitation, that your use is for the sole purpose of
|
||||
# programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the
|
||||
# applicable agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus II 64-Bit
|
||||
# Version 13.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition
|
||||
# Date created = 16:29:32 June 24, 2020
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
# 1) The default values for assignments are stored in the file:
|
||||
# tzpuFusionX.qdf
|
||||
# If this file doesn't exist, see file:
|
||||
# assignment_defaults.qdf
|
||||
#
|
||||
# 2) Altera recommends that you do not modify this file. This
|
||||
# file is updated automatically by the Quartus II software
|
||||
# and any changes you make may be lost or overwritten.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
set_global_assignment -name FAMILY MAX7000AE
|
||||
set_global_assignment -name DEVICE "EPM7512AETC144-10"
|
||||
set_global_assignment -name TOP_LEVEL_ENTITY tzpuFusionX_PCW8256
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION "13.0 SP1"
|
||||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "16:29:32 JUNE 24, 2020"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "13.0 SP1"
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR "-1"
|
||||
set_global_assignment -name EDA_DESIGN_ENTRY_SYNTHESIS_TOOL "<None>"
|
||||
set_global_assignment -name EDA_INPUT_VCC_NAME VCC -section_id eda_design_synthesis
|
||||
set_global_assignment -name EDA_INPUT_DATA_FORMAT EDIF -section_id eda_design_synthesis
|
||||
set_global_assignment -name EDA_SIMULATION_TOOL "ModelSim-Altera (VHDL)"
|
||||
set_global_assignment -name EDA_OUTPUT_DATA_FORMAT VHDL -section_id eda_simulation
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING OFF
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING OFF
|
||||
set_global_assignment -name FITTER_EFFORT "STANDARD FIT"
|
||||
set_global_assignment -name MAX7000_DEVICE_IO_STANDARD LVTTL
|
||||
|
||||
# Z80 Data Bus
|
||||
# ============
|
||||
set_location_assignment PIN_81 -to Z80_DATA[0]
|
||||
set_location_assignment PIN_78 -to Z80_DATA[1]
|
||||
set_location_assignment PIN_87 -to Z80_DATA[2]
|
||||
set_location_assignment PIN_100 -to Z80_DATA[3]
|
||||
set_location_assignment PIN_102 -to Z80_DATA[4]
|
||||
set_location_assignment PIN_93 -to Z80_DATA[5]
|
||||
set_location_assignment PIN_94 -to Z80_DATA[6]
|
||||
set_location_assignment PIN_84 -to Z80_DATA[7]
|
||||
|
||||
# Z80 Control signals.
|
||||
# ====================
|
||||
set_location_assignment PIN_69 -to Z80_INTn
|
||||
set_location_assignment PIN_70 -to Z80_NMIn
|
||||
set_location_assignment PIN_71 -to Z80_HALTn
|
||||
set_location_assignment PIN_68 -to Z80_MREQn
|
||||
set_location_assignment PIN_65 -to Z80_IORQn
|
||||
set_location_assignment PIN_67 -to Z80_RDn
|
||||
set_location_assignment PIN_66 -to Z80_WRn
|
||||
set_location_assignment PIN_63 -to Z80_BUSAKn
|
||||
set_location_assignment PIN_62 -to Z80_WAITn
|
||||
set_location_assignment PIN_61 -to Z80_BUSRQn
|
||||
set_location_assignment PIN_79 -to Z80_RFSHn
|
||||
set_location_assignment PIN_60 -to Z80_M1n
|
||||
set_location_assignment PIN_56 -to Z80_RESETn
|
||||
set_location_assignment PIN_101 -to Z80_CLK
|
||||
|
||||
# Z80 Address Bus
|
||||
# ===============
|
||||
set_location_assignment PIN_80 -to Z80_ADDR[0]
|
||||
set_location_assignment PIN_90 -to Z80_ADDR[1]
|
||||
set_location_assignment PIN_83 -to Z80_ADDR[2]
|
||||
set_location_assignment PIN_86 -to Z80_ADDR[3]
|
||||
set_location_assignment PIN_88 -to Z80_ADDR[4]
|
||||
set_location_assignment PIN_91 -to Z80_ADDR[5]
|
||||
set_location_assignment PIN_92 -to Z80_ADDR[6]
|
||||
set_location_assignment PIN_96 -to Z80_ADDR[7]
|
||||
set_location_assignment PIN_97 -to Z80_ADDR[8]
|
||||
set_location_assignment PIN_98 -to Z80_ADDR[9]
|
||||
set_location_assignment PIN_99 -to Z80_ADDR[10]
|
||||
set_location_assignment PIN_110 -to Z80_ADDR[11]
|
||||
set_location_assignment PIN_108 -to Z80_ADDR[12]
|
||||
set_location_assignment PIN_107 -to Z80_ADDR[13]
|
||||
set_location_assignment PIN_106 -to Z80_ADDR[14]
|
||||
set_location_assignment PIN_103 -to Z80_ADDR[15]
|
||||
|
||||
# SOM SPI
|
||||
# =======
|
||||
set_location_assignment PIN_32 -to VSOM_SPI_CSn
|
||||
set_location_assignment PIN_31 -to VSOM_SPI_CLK
|
||||
set_location_assignment PIN_30 -to VSOM_SPI_MOSI
|
||||
set_location_assignment PIN_29 -to VSOM_SPI_MISO
|
||||
|
||||
# SOM Parallel Bus
|
||||
# ================
|
||||
set_location_assignment PIN_41 -to VSOM_DATA_OUT[0]
|
||||
set_location_assignment PIN_40 -to VSOM_DATA_OUT[1]
|
||||
set_location_assignment PIN_39 -to VSOM_DATA_OUT[2]
|
||||
set_location_assignment PIN_38 -to VSOM_DATA_OUT[3]
|
||||
set_location_assignment PIN_37 -to VSOM_DATA_OUT[4]
|
||||
set_location_assignment PIN_36 -to VSOM_DATA_OUT[5]
|
||||
set_location_assignment PIN_35 -to VSOM_DATA_OUT[6]
|
||||
set_location_assignment PIN_34 -to VSOM_DATA_OUT[7]
|
||||
set_location_assignment PIN_132 -to VSOM_HBYTE
|
||||
|
||||
# SOM Reserved signals.
|
||||
# =====================
|
||||
set_location_assignment PIN_21 -to VSOM_RSV[1]
|
||||
|
||||
# SOM Control Signals
|
||||
# ===================
|
||||
set_location_assignment PIN_28 -to VSOM_READY
|
||||
set_location_assignment PIN_19 -to VSOM_LTSTATE
|
||||
set_location_assignment PIN_27 -to VSOM_BUSRQ
|
||||
set_location_assignment PIN_26 -to VSOM_BUSACK
|
||||
set_location_assignment PIN_18 -to VSOM_INT
|
||||
set_location_assignment PIN_22 -to VSOM_NMI
|
||||
set_location_assignment PIN_25 -to VSOM_WAIT
|
||||
set_location_assignment PIN_23 -to VSOM_RESET
|
||||
set_location_assignment PIN_16 -to PM_RESET
|
||||
|
||||
# VGA_Palette Control
|
||||
# ===================
|
||||
set_location_assignment PIN_133 -to VGA_R[7]
|
||||
set_location_assignment PIN_137 -to VGA_R[8]
|
||||
set_location_assignment PIN_140 -to VGA_R[9]
|
||||
set_location_assignment PIN_134 -to VGA_G[7]
|
||||
set_location_assignment PIN_138 -to VGA_G[8]
|
||||
set_location_assignment PIN_141 -to VGA_G[9]
|
||||
set_location_assignment PIN_136 -to VGA_B[8]
|
||||
set_location_assignment PIN_139 -to VGA_B[9]
|
||||
|
||||
|
||||
# VGA Control Signals
|
||||
# ===================
|
||||
set_location_assignment PIN_142 -to VGA_PXL_CLK
|
||||
set_location_assignment PIN_14 -to VGA_DISPEN
|
||||
set_location_assignment PIN_12 -to VGA_VSYNCn
|
||||
set_location_assignment PIN_11 -to VGA_HSYNCn
|
||||
set_location_assignment PIN_82 -to VGA_COLR
|
||||
set_location_assignment PIN_109 -to VGA_CSYNCn
|
||||
set_location_assignment PIN_143 -to VGA_BLANKn
|
||||
|
||||
# CRT Control Signals
|
||||
# ===================
|
||||
set_location_assignment PIN_15 -to MONO_PXL_CLK
|
||||
set_location_assignment PIN_114 -to MONO_BLANKn
|
||||
set_location_assignment PIN_113 -to MONO_CSYNCn
|
||||
set_location_assignment PIN_116 -to MONO_RSV
|
||||
|
||||
# CRT Lower Chrominance Control
|
||||
# =============================
|
||||
set_location_assignment PIN_1 -to MONO_R[0]
|
||||
set_location_assignment PIN_6 -to MONO_R[1]
|
||||
set_location_assignment PIN_10 -to MONO_R[2]
|
||||
set_location_assignment PIN_2 -to MONO_G[0]
|
||||
set_location_assignment PIN_7 -to MONO_G[1]
|
||||
set_location_assignment PIN_9 -to MONO_G[2]
|
||||
set_location_assignment PIN_5 -to MONO_B[1]
|
||||
set_location_assignment PIN_8 -to MONO_B[2]
|
||||
|
||||
# MUX Control Signals
|
||||
# ===================
|
||||
set_location_assignment PIN_72 -to VIDEO_SRC
|
||||
set_location_assignment PIN_74 -to MONO_VIDEO_SRC
|
||||
set_location_assignment PIN_77 -to AUDIO_SRC_L
|
||||
set_location_assignment PIN_75 -to AUDIO_SRC_R
|
||||
|
||||
# Mainboard Reset Signals
|
||||
# =======================
|
||||
#set_location_assignment PIN_127 -to CPU_RESETn
|
||||
set_location_assignment PIN_122 -to MB_RESETn
|
||||
set_location_assignment PIN_111 -to MB_IPLn
|
||||
|
||||
# USB Power Control
|
||||
# =================
|
||||
set_location_assignment PIN_55 -to VBUS_EN
|
||||
|
||||
# Clocks
|
||||
# ======
|
||||
#set_location_assignment PIN_125 -to CPU_CLK
|
||||
set_location_assignment PIN_128 -to CLK_50M
|
||||
|
||||
# Unused ports
|
||||
# ============
|
||||
#set_location_assignment PIN_42 -to
|
||||
#set_location_assignment PIN_43 -to
|
||||
#set_location_assignment PIN_44 -to
|
||||
#set_location_assignment PIN_45 -to
|
||||
#set_location_assignment PIN_112 -to
|
||||
#set_location_assignment PIN_131 -to
|
||||
#set_location_assignment PIN_117 -to
|
||||
#set_location_assignment PIN_118 -to
|
||||
#set_location_assignment PIN_119 -to
|
||||
#set_location_assignment PIN_120 -to
|
||||
#set_location_assignment PIN_121 -to
|
||||
#set_location_assignment PIN_25 -to
|
||||
#set_location_assignment PIN_53 -to
|
||||
#set_location_assignment PIN_128 -to
|
||||
#set_location_assignment PIN_47 -to
|
||||
#set_location_assignment PIN_54 -to
|
||||
#set_location_assignment PIN_127 -to
|
||||
#set_location_assignment PIN_125 -to
|
||||
#set_location_assignment PIN_48 -to
|
||||
#set_location_assignment PIN_46 -to
|
||||
#set_location_assignment PIN_49 -to
|
||||
|
||||
|
||||
set_global_assignment -name VHDL_FILE ../tzpuFusionX_Toplevel.vhd
|
||||
set_global_assignment -name VHDL_FILE ../tzpuFusionX_pkg.vhd
|
||||
set_global_assignment -name VHDL_FILE ../tzpuFusionX.vhd
|
||||
set_global_assignment -name SDC_FILE tzpuFusionX_PCW8256_constraints.sdc
|
||||
|
||||
set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008
|
||||
set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF
|
||||
|
||||
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS OFF
|
||||
set_global_assignment -name MAX7000_OPTIMIZATION_TECHNIQUE AREA
|
||||
set_global_assignment -name AUTO_RESOURCE_SHARING OFF
|
||||
set_global_assignment -name PRE_MAPPING_RESYNTHESIS OFF
|
||||
set_global_assignment -name USE_LOGICLOCK_CONSTRAINTS_IN_BALANCING OFF
|
||||
|
||||
set_global_assignment -name INFER_RAMS_FROM_RAW_LOGIC OFF
|
||||
set_global_assignment -name AUTO_LCELL_INSERTION ON
|
||||
|
||||
set_global_assignment -name CDF_FILE output_files/tzpuFusionX_PCW8256.cdf
|
||||
324
CPLD/v1.0/PCW8256/build/tzpuFusionX_PCW8256_constraints.sdc
vendored
Normal file
324
CPLD/v1.0/PCW8256/build/tzpuFusionX_PCW8256_constraints.sdc
vendored
Normal file
@@ -0,0 +1,324 @@
|
||||
## Generated SDC file "tzpuFusionX.out.sdc"
|
||||
|
||||
## Copyright (C) 1991-2013 Altera Corporation
|
||||
## Your use of Altera Corporation's design tools, logic functions
|
||||
## and other software and tools, and its AMPP partner logic
|
||||
## functions, and any output files from any of the foregoing
|
||||
## (including device programming or simulation files), and any
|
||||
## associated documentation or information are expressly subject
|
||||
## to the terms and conditions of the Altera Program License
|
||||
## Subscription Agreement, Altera MegaCore Function License
|
||||
## Agreement, or other applicable license agreement, including,
|
||||
## without limitation, that your use is for the sole purpose of
|
||||
## programming logic devices manufactured by Altera and sold by
|
||||
## Altera or its authorized distributors. Please refer to the
|
||||
## applicable agreement for further details.
|
||||
|
||||
|
||||
## VENDOR "Altera"
|
||||
## PROGRAM "Quartus II"
|
||||
## VERSION "Version 13.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition"
|
||||
|
||||
## DATE "Fri Jun 26 22:10:05 2020"
|
||||
|
||||
##
|
||||
## DEVICE "EPM7160STC100-10"
|
||||
##
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Time Information
|
||||
#**************************************************************
|
||||
|
||||
set_time_format -unit ns -decimal_places 3
|
||||
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Create Clock
|
||||
#**************************************************************
|
||||
|
||||
# Standard mainboard clock. If using tzpuFusionX on a different host then set to the host frequency.
|
||||
create_clock -name {Z80_CLK} -period 250.000 -waveform { 0.000 125.000 } [get_ports { Z80_CLK }]
|
||||
|
||||
# For 50MHz crystal.
|
||||
create_clock -name {CLK_50M} -period 20.000 -waveform { 0.000 10.000 } [ get_ports { CLK_50M }]
|
||||
|
||||
# For SPI CSn
|
||||
#create_clock -name {VSOM_SPI_CSn} -period 200.000 -waveform { 160.000 40.000 } [ get_ports { VSOM_SPI_CSn }]
|
||||
|
||||
# For SPI CLK
|
||||
create_clock -name {VSOM_SPI_CLK} -period 14.000 -waveform { 0.000 7.000 } [ get_ports { VSOM_SPI_CLK }]
|
||||
|
||||
# For basic board with oscillator.
|
||||
#create_clock -name {CTLCLK} -period 20.000 -waveform { 0.000 10.000 } [ get_ports { CTLCLK }]
|
||||
#create_clock -name {cpld512:cpldl512Toplevel|CTLCLKi} -period 280.000 -waveform { 0.000 140.000 } [ get_keepers {cpld512:cpldl512Toplevel|CTLCLKi} ]
|
||||
##create_clock -name {Z80_CLK} -period 50.000 -waveform { 0.000 25.000 } [get_ports { CTLCLK }]
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Create Generated Clock
|
||||
#**************************************************************
|
||||
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Set Clock Latency
|
||||
#**************************************************************
|
||||
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Set Clock Uncertainty
|
||||
#**************************************************************
|
||||
|
||||
#derive_clock_uncertainty
|
||||
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Set Input Delay
|
||||
#**************************************************************
|
||||
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CTL_MBSEL}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CTL_BUSRQn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CTL_WAITn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {SYS_BUSRQn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {SYS_WAITn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_ADDR[*]}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_HI_ADDR[*]}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {VZ80_ADDR[*]}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_BUSACKn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_DATA[*]}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_HALTn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_IORQn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_M1n}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_MREQn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_RESETn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_RFSHn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_WRn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {Z80_RDn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {R_IN}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {G_IN}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {B_IN}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {COLR_IN}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CSYNC_IN}]
|
||||
##set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {CVIDEO_IN}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {HSYNC_IN}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {VSYNC_IN}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 1.000 [get_ports {VZ80_DATA[*]}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_MREQn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_IORQn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_WRn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_RDn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_M1n}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_BUSACKn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_INTn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_NMIn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_WAITn}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VWAITn_A21_V_CSYNC}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A20_RFSHn_V_HSYNC}]
|
||||
#set_input_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A19_HALTn_V_VSYNC}]
|
||||
|
||||
#**************************************************************
|
||||
# Set Output Delay
|
||||
#**************************************************************
|
||||
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_BUSACKn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_HALTn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_M1n}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {CTL_RFSHn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_CSn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_CS2n}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_OEn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {RAM_WEn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {SVCREQn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {SYS_BUSACKn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_BUSRQn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_DATA[*]}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_ADDR[*]}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_HI_ADDR[*]}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_RA_ADDR[*]}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_WAITn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_MREQn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_CLK}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_ADDR[*]}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_DATA[*]}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_CLK}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_MREQn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_IORQn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_RDn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_WRn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_M1n}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VIDEO_RDn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VIDEO_WRn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A18_INTn_V_R}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_BUSRQn_V_G}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A16_WAITn_V_B}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A17_NMIn_V_COLR}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VWAITn_A21_V_CSYNC}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A20_RFSHn_V_HSYNC}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {VZ80_A19_HALTn_V_VSYNC}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_HALTn}]
|
||||
#set_output_delay -add_delay -clock [get_clocks {SYSCLK}] 5.000 [get_ports {Z80_RFSHn}]
|
||||
|
||||
# For K64F
|
||||
#set_output_delay -add_delay -clock [get_clocks {CTLCLK}] 5.000 [get_ports {Z80_CLK}]
|
||||
|
||||
# For basic board with oscillator.
|
||||
#set_output_delay -add_delay -clock [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}] 5.000 [get_ports {Z80_CLK}]
|
||||
|
||||
#**************************************************************
|
||||
# Set Max Delay
|
||||
#**************************************************************
|
||||
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_HALTn} 30.000
|
||||
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_IORQn} 30.000
|
||||
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_M1n} 30.000
|
||||
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RDn} 30.000
|
||||
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_WRn} 30.000
|
||||
#set_max_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RFSHn} 30.000
|
||||
#set_max_delay -from [get_ports {VZ80_A19_HALTn_V_VSYNC}] -to {Z80_HALTn} 30.000
|
||||
#set_max_delay -from [get_ports {VZ80_IORQn}] -to {Z80_IORQn} 30.000
|
||||
#set_max_delay -from [get_ports {VZ80_MREQn}] -to {Z80_IORQn} 30.000
|
||||
#set_max_delay -from [get_ports {VZ80_M1n}] -to {Z80_M1n} 30.000
|
||||
#set_max_delay -from [get_ports {VZ80_RDn}] -to {Z80_RDn} 30.000
|
||||
#set_max_delay -from [get_ports {VZ80_WRn}] -to {Z80_WRn} 30.000
|
||||
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_HALTn} 40.000
|
||||
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RFSHn} 40.000
|
||||
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_IORQn} 40.000
|
||||
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_M1n} 30.000
|
||||
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RDn} 30.000
|
||||
#set_max_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_WRn} 30.000
|
||||
#set_max_delay -from [get_ports {VZ80_A20_RFSHn_V_HSYNC}] -to {Z80_RFSHn} 30.000
|
||||
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_HALTn} 30.000
|
||||
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_IORQn} 30.000
|
||||
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_M1n} 30.000
|
||||
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RDn} 30.000
|
||||
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_WRn} 30.000
|
||||
#set_max_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RFSHn} 30.000
|
||||
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_HALTn}] 45.000
|
||||
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_IORQn}] 30.000
|
||||
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_M1n}] 30.000
|
||||
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RDn}] 30.000
|
||||
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RFSHn}] 45.000
|
||||
#set_max_delay -from {Z80_BUSACKn} -to [get_ports {Z80_WRn}] 30.000
|
||||
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 45.000
|
||||
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 50.000
|
||||
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 40.000
|
||||
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 40.000
|
||||
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 40.000
|
||||
#set_max_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 45.000
|
||||
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 60.000
|
||||
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 45.000
|
||||
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 40.000
|
||||
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 40.000
|
||||
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 40.000
|
||||
#set_max_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 60.000
|
||||
|
||||
#**************************************************************
|
||||
# Set Min Delay
|
||||
#**************************************************************
|
||||
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_HALTn} 1.000
|
||||
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_IORQn} 1.000
|
||||
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_M1n} 1.000
|
||||
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RDn} 1.000
|
||||
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_WRn} 1.000
|
||||
#set_min_delay -from [get_ports {CTL_BUSRQn}] -to {Z80_RFSHn} 1.000
|
||||
#set_min_delay -from [get_ports {VZ80_A19_HALTn_V_VSYNC}] -to {Z80_HALTn} 1.000
|
||||
#set_min_delay -from [get_ports {VZ80_IORQn}] -to {Z80_IORQn} 1.000
|
||||
#set_min_delay -from [get_ports {VZ80_MREQn}] -to {Z80_IORQn} 1.000
|
||||
#set_min_delay -from [get_ports {VZ80_M1n}] -to {Z80_M1n} 1.000
|
||||
#set_min_delay -from [get_ports {VZ80_RDn}] -to {Z80_RDn} 1.000
|
||||
#set_min_delay -from [get_ports {VZ80_WRn}] -to {Z80_WRn} 1.000
|
||||
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_HALTn} 1.000
|
||||
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RFSHn} 1.000
|
||||
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_IORQn} 1.000
|
||||
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_M1n} 1.000
|
||||
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_RDn} 1.000
|
||||
#set_min_delay -from [get_ports {VZ80_BUSACKn}] -to {Z80_WRn} 1.000
|
||||
#set_min_delay -from [get_ports {VZ80_A20_RFSHn_V_HSYNC}] -to {Z80_RFSHn} 1.000
|
||||
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_HALTn} 1.000
|
||||
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_IORQn} 1.000
|
||||
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_M1n} 1.000
|
||||
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RDn} 1.000
|
||||
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_WRn} 1.000
|
||||
#set_min_delay -from [get_ports {Z80_BUSACKn}] -to {Z80_RFSHn} 1.000
|
||||
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_HALTn}] 1.000
|
||||
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_IORQn}] 1.000
|
||||
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_M1n}] 1.000
|
||||
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RDn}] 1.000
|
||||
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_RFSHn}] 1.000
|
||||
#set_min_delay -from {Z80_BUSACKn} -to [get_ports {Z80_WRn}] 1.000
|
||||
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 1.000
|
||||
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 1.000
|
||||
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 1.000
|
||||
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 1.000
|
||||
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 1.000
|
||||
#set_min_delay -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 1.000
|
||||
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_HALTn}] 1.000
|
||||
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_IORQn}] 1.000
|
||||
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_M1n}] 1.000
|
||||
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RDn}] 1.000
|
||||
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_WRn}] 1.000
|
||||
#set_min_delay -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to [get_ports {Z80_RFSHn}] 1.000
|
||||
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Set Clock Groups
|
||||
#**************************************************************
|
||||
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Set False Path
|
||||
#**************************************************************
|
||||
|
||||
# For K64F
|
||||
#set_false_path -from [get_clocks {CTLCLK}] -to [get_clocks {SYSCLK}]
|
||||
#set_false_path -from [get_clocks {SYSCLK}] -to [get_clocks {CTLCLK}]
|
||||
|
||||
# For basic board with oscillator.
|
||||
#set_false_path -from [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}] -to [get_clocks {SYSCLK}]
|
||||
#set_false_path -from [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}] -to [get_clocks {CTLCLK}]
|
||||
#set_false_path -from [get_clocks {SYSCLK}] -to [get_clocks {cpld512:cpldl512Toplevel|CTLCLKi}]
|
||||
#set_false_path -from [get_clocks {SYSCLK}] -to [get_clocks {CTLCLK}]
|
||||
|
||||
# For both configurations.
|
||||
#set_false_path -from {cpld512:cpldl512Toplevel|KEY_SUBSTITUTE} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
|
||||
#set_false_path -from {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
|
||||
#set_false_path -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
|
||||
#set_false_path -from {cpld512:cpldl512Toplevel|CPLD_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
|
||||
#set_false_path -from {cpld512:cpldl512Toplevel|MZ80B_VRAM_HI_ADDR} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
|
||||
#set_false_path -from {cpld512:cpldl512Toplevel|MZ80B_VRAM_LO_ADDR} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
|
||||
#set_false_path -from {cpld512:cpldl512Toplevel|MODE_VIDEO_MZ80B} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
|
||||
#set_false_path -from {cpld512:cpldl512Toplevel|GRAM_PAGE_ENABLE} -to {cpld512:cpldl512Toplevel|CTLCLK_Q}
|
||||
|
||||
#**************************************************************
|
||||
# Set Multicycle Path
|
||||
#**************************************************************
|
||||
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|CTLCLK_Q} -setup -end 2
|
||||
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|CTLCLK_Q} -hold -end 1
|
||||
|
||||
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -setup -end 2
|
||||
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CTL_BUSRQni} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -hold -end 1
|
||||
|
||||
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -setup -end 2
|
||||
#set_multicycle_path -from {cpld512:cpldl512Toplevel|CPU_CFG_DATA[*]} -to {cpld512:cpldl512Toplevel|MEM_MODE_LATCH[*]} -hold -end 1
|
||||
|
||||
#**************************************************************
|
||||
# Set Maximum Delay
|
||||
#**************************************************************
|
||||
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Set Minimum Delay
|
||||
#**************************************************************
|
||||
|
||||
|
||||
|
||||
#**************************************************************
|
||||
# Set Input Transition
|
||||
#**************************************************************
|
||||
|
||||
1083
CPLD/v1.0/PCW8256/tzpuFusionX.vhd
Normal file
1083
CPLD/v1.0/PCW8256/tzpuFusionX.vhd
Normal file
File diff suppressed because it is too large
Load Diff
227
CPLD/v1.0/PCW8256/tzpuFusionX_Toplevel.vhd
Normal file
227
CPLD/v1.0/PCW8256/tzpuFusionX_Toplevel.vhd
Normal file
@@ -0,0 +1,227 @@
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
--
|
||||
-- Name: tzpuFusionX_Toplevel.vhd
|
||||
-- Version: Amstrad PCW-8256
|
||||
-- Created: Mar 2023
|
||||
-- Author(s): Philip Smart
|
||||
-- Description: tzpuFusionX CPLD Top Level module.
|
||||
--
|
||||
-- This module contains the basic pin definition of the CPLD<->logic needed in the
|
||||
-- project which targets the MZ-80A host.
|
||||
--
|
||||
-- Credits:
|
||||
-- Copyright: (c) 2018-23 Philip Smart <philip.smart@net2net.org>
|
||||
--
|
||||
-- History: Nov 2022 v1.0 - Initial write for the MZ-2000, adaption to the MZ-80A.
|
||||
-- Feb 2023 v1.1 - Updates, after numerous tests to try and speed up the Z80 transaction
|
||||
-- from SSD202 issuing a command to data being returned. Source now
|
||||
-- different to the MZ-700/MZ-2000 so will need back porting.
|
||||
-- Mar 2023 v1.0 - Snapshot taken from MZ-80A source for the Amstrad PCW-8256 version.
|
||||
-- Version reset to v1.0 for the Amstrad.
|
||||
--
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
-- 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.
|
||||
--
|
||||
-- along with this program. If not, see <http:--www.gnu.org-licenses->.
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
use work.tzpuFusionX_pkg.all;
|
||||
library altera;
|
||||
use altera.altera_syn_attributes.all;
|
||||
|
||||
entity tzpuFusionX_PCW8256 is
|
||||
port (
|
||||
-- Z80 Address Bus
|
||||
Z80_ADDR : inout std_logic_vector(15 downto 0);
|
||||
|
||||
-- Z80 Data Bus
|
||||
Z80_DATA : inout std_logic_vector(7 downto 0);
|
||||
|
||||
-- Z80 Control signals.
|
||||
Z80_BUSRQn : in std_logic;
|
||||
Z80_BUSAKn : out std_logic;
|
||||
Z80_INTn : in std_logic;
|
||||
Z80_IORQn : inout std_logic;
|
||||
Z80_MREQn : inout std_logic;
|
||||
Z80_NMIn : in std_logic;
|
||||
Z80_RDn : inout std_logic;
|
||||
Z80_WRn : inout std_logic;
|
||||
Z80_RESETn : in std_logic; -- Host CPU Reset signal, also CPLD reset.
|
||||
Z80_HALTn : out std_logic;
|
||||
Z80_WAITn : in std_logic;
|
||||
Z80_M1n : inout std_logic;
|
||||
Z80_RFSHn : inout std_logic;
|
||||
|
||||
-- SOM SPI
|
||||
VSOM_SPI_CSn : in std_logic; -- SPI Slave Select
|
||||
VSOM_SPI_CLK : in std_logic; -- SPI Clock
|
||||
VSOM_SPI_MOSI : in std_logic; -- SPI Master Output Slave Input
|
||||
VSOM_SPI_MISO : out std_logic; -- SPI Master Input Slave Output
|
||||
|
||||
-- SOM Parallel Bus.
|
||||
VSOM_DATA_OUT : out std_logic_vector(7 downto 0); -- Address/Data bus for CPLD control registers.
|
||||
VSOM_HBYTE : in std_logic; -- Parallel Bus High (1)/Low (0) byte.
|
||||
VSOM_READY : out std_logic; -- FSM Ready (1), Busy (0)
|
||||
VSOM_LTSTATE : out std_logic; -- Last T-State in current cycle, 1 = active.
|
||||
VSOM_BUSRQ : out std_logic; -- Host device requesting Z80 Bus.
|
||||
VSOM_BUSACK : out std_logic; -- Host device granted Z80 Bus
|
||||
VSOM_INT : out std_logic; -- Z80 INT signal
|
||||
VSOM_NMI : out std_logic; -- Z80 NMI signal
|
||||
VSOM_WAIT : out std_logic; -- Z80 WAIT signal
|
||||
VSOM_RESET : out std_logic; -- Z80 RESET signal
|
||||
VSOM_RSV : out std_logic_vector(1 downto 1); -- Reserved pins.
|
||||
|
||||
-- SOM Control Signals
|
||||
PM_RESET : out std_logic; -- Reset SOM
|
||||
|
||||
-- VGA_Palette Control
|
||||
VGA_R : in std_logic_vector(9 downto 7); -- Signals used for detecting blank or no video output.
|
||||
VGA_G : in std_logic_vector(9 downto 7);
|
||||
VGA_B : in std_logic_vector(9 downto 8);
|
||||
|
||||
-- VGA Control Signals
|
||||
VGA_PXL_CLK : in std_logic; -- VGA Pixel clock for DAC conversion.
|
||||
VGA_DISPEN : in std_logic; -- Displayed Enabled (SOM video output).
|
||||
VGA_VSYNCn : in std_logic; -- SOM VSync.
|
||||
VGA_HSYNCn : in std_logic; -- SOM HSync.
|
||||
VGA_COLR : out std_logic; -- COLR colour carrier frequency.
|
||||
VGA_CSYNCn : out std_logic; -- VGA Composite Sync.
|
||||
VGA_BLANKn : out std_logic; -- VGA Blank detected.
|
||||
|
||||
-- CRT Control Signals
|
||||
MONO_PXL_CLK : out std_logic; -- Mono CRT pixel clock for DAC conversion.
|
||||
MONO_BLANKn : out std_logic; -- Mono CRT Blank (no active pixel) detection.
|
||||
MONO_CSYNCn : out std_logic; -- Mono CRT composite sync.
|
||||
MONO_RSV : out std_logic;
|
||||
|
||||
-- CRT Lower Chrominance Control
|
||||
MONO_R : out std_logic_vector(2 downto 0); -- Signals to fine tune Red level of monochrome chrominance.
|
||||
MONO_G : out std_logic_vector(2 downto 0); -- Signals to fine tune Green level of monochrome chrominance.
|
||||
MONO_B : out std_logic_vector(2 downto 1); -- Signals to fine tune Blue level of monochrome chrominance.
|
||||
|
||||
-- MUX Control Signals
|
||||
VIDEO_SRC : out std_logic; -- Select video source, Mainboard or SOM.
|
||||
MONO_VIDEO_SRC : out std_logic; -- Select crt video source, Mainboard or SOM.
|
||||
AUDIO_SRC_L : out std_logic; -- Select Audio Source Left Channel, Mainboard or SOM.
|
||||
AUDIO_SRC_R : out std_logic; -- Select Audio Source Right Channel, Mainboard or SOM.
|
||||
|
||||
-- Mainboard Reset Signals
|
||||
MB_RESETn : in std_logic; -- Motherboard Reset pressed.
|
||||
MB_IPLn : in std_logic; -- Motherboard IPL pressed.
|
||||
|
||||
-- USB Power Control
|
||||
VBUS_EN : out std_logic; -- USB Enable Power Output
|
||||
|
||||
-- Clocks.
|
||||
Z80_CLK : in std_logic; -- Host CPU Clock
|
||||
CLK_50M : in std_logic -- 50MHz oscillator.
|
||||
);
|
||||
END entity;
|
||||
|
||||
architecture rtl of tzpuFusionX_PCW8256 is
|
||||
|
||||
begin
|
||||
|
||||
cpldl512Toplevel : entity work.cpld512
|
||||
generic map (
|
||||
SPI_CLK_POLARITY => '0'
|
||||
)
|
||||
port map
|
||||
(
|
||||
-- Z80 Address Bus
|
||||
Z80_ADDR => Z80_ADDR,
|
||||
|
||||
-- Z80 Data Bus
|
||||
Z80_DATA => Z80_DATA,
|
||||
|
||||
-- Z80 Control signals.
|
||||
Z80_BUSRQn => Z80_BUSRQn,
|
||||
Z80_BUSAKn => Z80_BUSAKn,
|
||||
Z80_INTn => Z80_INTn,
|
||||
Z80_IORQn => Z80_IORQn,
|
||||
Z80_MREQn => Z80_MREQn,
|
||||
Z80_NMIn => Z80_NMIn,
|
||||
Z80_RDn => Z80_RDn,
|
||||
Z80_WRn => Z80_WRn,
|
||||
Z80_RESETn => Z80_RESETn,
|
||||
Z80_HALTn => Z80_HALTn,
|
||||
Z80_WAITn => Z80_WAITn,
|
||||
Z80_M1n => Z80_M1n,
|
||||
Z80_RFSHn => Z80_RFSHn,
|
||||
|
||||
-- SOM SPI
|
||||
VSOM_SPI_CSn => VSOM_SPI_CSn, -- SPI Slave Select
|
||||
VSOM_SPI_CLK => VSOM_SPI_CLK, -- SPI Clock
|
||||
VSOM_SPI_MOSI => VSOM_SPI_MOSI, -- SPI Master Output Slave Input
|
||||
VSOM_SPI_MISO => VSOM_SPI_MISO, -- SPI Master Input Slave Output
|
||||
|
||||
-- SOM Parallel Bus.
|
||||
VSOM_DATA_OUT => VSOM_DATA_OUT, -- Address/Data bus for CPLD control registers.
|
||||
VSOM_HBYTE => VSOM_HBYTE, -- Parallel Bus High (1)/Low (0) byte.
|
||||
VSOM_READY => VSOM_READY, -- FSM Ready (1), Busy (0)
|
||||
VSOM_LTSTATE => VSOM_LTSTATE, -- Last T-State in current cycle.
|
||||
VSOM_BUSRQ => VSOM_BUSRQ, -- Host device requesting Z80 Bus.
|
||||
VSOM_BUSACK => VSOM_BUSACK, -- Host device granted Z80 Bus
|
||||
VSOM_INT => VSOM_INT, -- Z80 INT signal
|
||||
VSOM_NMI => VSOM_NMI, -- Z80 NMI signal
|
||||
VSOM_WAIT => VSOM_WAIT, -- Z80 WAIT signal
|
||||
VSOM_RESET => VSOM_RESET, -- Z80 RESET signal
|
||||
VSOM_RSV => VSOM_RSV, -- Reserved pins.
|
||||
|
||||
-- SOM Control Signals
|
||||
PM_RESET => PM_RESET, -- Reset SOM
|
||||
|
||||
-- VGA_Palette Control
|
||||
VGA_R => VGA_R, -- Signals used for detecting blank or no video output.
|
||||
VGA_G => VGA_G,
|
||||
VGA_B => VGA_B,
|
||||
|
||||
-- VGA Control Signals
|
||||
VGA_PXL_CLK => VGA_PXL_CLK, -- VGA Pixel clock for DAC conversion.
|
||||
VGA_DISPEN => VGA_DISPEN, -- Displayed Enabled (SOM video output).
|
||||
VGA_VSYNCn => VGA_VSYNCn, -- SOM VSync.
|
||||
VGA_HSYNCn => VGA_HSYNCn, -- SOM HSync.
|
||||
VGA_COLR => VGA_COLR, -- COLR colour carrier frequency.
|
||||
VGA_CSYNCn => VGA_CSYNCn, -- VGA Composite Sync.
|
||||
VGA_BLANKn => VGA_BLANKn, -- VGA Blank detected.
|
||||
|
||||
-- CRT Control Signals
|
||||
MONO_PXL_CLK => MONO_PXL_CLK, -- Mono CRT pixel clock for DAC conversion.
|
||||
MONO_BLANKn => MONO_BLANKn, -- Mono CRT Blank (no active pixel) detection.
|
||||
MONO_CSYNCn => MONO_CSYNCn, -- Mono CRT composite sync.
|
||||
MONO_RSV => MONO_RSV,
|
||||
|
||||
-- CRT Lower Chrominance Control
|
||||
MONO_R => MONO_R, -- Signals to fine tune Red level of monochrome chrominance.
|
||||
MONO_G => MONO_G, -- Signals to fine tune Green level of monochrome chrominance.
|
||||
MONO_B => MONO_B, -- Signals to fine tune Blue level of monochrome chrominance.
|
||||
|
||||
-- MUX Control Signals
|
||||
VIDEO_SRC => VIDEO_SRC, -- Select video source, Mainboard or SOM.
|
||||
MONO_VIDEO_SRC => MONO_VIDEO_SRC, -- Select crt video source, Mainboard or SOM.
|
||||
AUDIO_SRC_L => AUDIO_SRC_L, -- Select Audio Source Left Channel, Mainboard or SOM.
|
||||
AUDIO_SRC_R => AUDIO_SRC_R, -- Select Audio Source Right Channel, Mainboard or SOM.
|
||||
|
||||
-- Mainboard Reset Signals=> MONO_R,
|
||||
MB_RESETn => MB_RESETn, -- Motherboard Reset pressed.
|
||||
MB_IPLn => MB_IPLn, -- Motherboard IPL pressed.
|
||||
|
||||
-- USB Power Control
|
||||
VBUS_EN => VBUS_EN, -- USB Enable Power Output
|
||||
|
||||
-- Clocks.
|
||||
Z80_CLK => Z80_CLK, -- Host CPU Clock
|
||||
CLK_50M => CLK_50M -- 50MHz oscillator.
|
||||
);
|
||||
|
||||
end architecture;
|
||||
227
CPLD/v1.0/PCW8256/tzpuFusionX_pkg.vhd
Normal file
227
CPLD/v1.0/PCW8256/tzpuFusionX_pkg.vhd
Normal file
@@ -0,0 +1,227 @@
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
--
|
||||
-- Name: tzpuFusionX_pkg.vhd
|
||||
-- Created: Mar 2023
|
||||
-- Author(s): Philip Smart
|
||||
-- Description: tzpuFusionX CPLD configuration file.
|
||||
--
|
||||
-- This module contains parameters for the CPLD in the tzpuFusionX project
|
||||
-- which targets the Amstrad PCW8256 host.
|
||||
--
|
||||
-- Credits:
|
||||
-- Copyright: (c) 2018-23 Philip Smart <philip.smart@net2net.org>
|
||||
--
|
||||
-- History: Nov 2022 v1.0 - Initial write for the MZ-2000, adaption to the MZ-80A.
|
||||
-- Feb 2023 v1.1 - Updates, after numerous tests to try and speed up the Z80 transaction
|
||||
-- from SSD202 issuing a command to data being returned. Source now
|
||||
-- different to the MZ-700/MZ-2000 so will need back porting.
|
||||
-- Mar 2023 v1.0 - Snapshot taken from MZ-80A source for the Amstrad PCW-8256 version.
|
||||
-- Version reset to v1.0 for the Amstrad.
|
||||
--
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
-- 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->.
|
||||
---------------------------------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
library pkgs;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.math_real.all;
|
||||
|
||||
package tzpuFusionX_pkg is
|
||||
|
||||
------------------------------------------------------------
|
||||
-- Constants
|
||||
------------------------------------------------------------
|
||||
|
||||
-- Potential logic state constants.
|
||||
constant YES : std_logic := '1';
|
||||
constant NO : std_logic := '0';
|
||||
constant HI : std_logic := '1';
|
||||
constant LO : std_logic := '0';
|
||||
constant ONE : std_logic := '1';
|
||||
constant ZERO : std_logic := '0';
|
||||
constant HIZ : std_logic := 'Z';
|
||||
|
||||
-- CPLD Command instructions.
|
||||
constant CPLD_CMD_RESET_HOST : integer := 1;
|
||||
constant CPLD_CMD_HOLD_HOST_BUS : integer := 2;
|
||||
constant CPLD_CMD_RELEASE_HOST_BUS: integer := 3;
|
||||
|
||||
-- Target hardware modes.
|
||||
constant MODE_MZ80K : integer := 0;
|
||||
constant MODE_MZ80C : integer := 1;
|
||||
constant MODE_MZ1200 : integer := 2;
|
||||
constant MODE_MZ80A : integer := 3;
|
||||
constant MODE_MZ700 : integer := 4;
|
||||
constant MODE_MZ800 : integer := 5;
|
||||
constant MODE_MZ80B : integer := 6;
|
||||
constant MODE_MZ2000 : integer := 7;
|
||||
constant MODE_PCW8256 : integer := 8;
|
||||
|
||||
-- Memory management modes.
|
||||
constant TZMM_ORIG : integer := 00; -- Original Sharp mode, no tranZPUter features are selected except the I/O control registers (default: 0x60-063).
|
||||
constant TZMM_BOOT : integer := 01; -- Original mode but E800-EFFF is mapped to tranZPUter RAM so TZFS can be booted.
|
||||
constant TZMM_TZFS : integer := 02; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-FFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected.
|
||||
constant TZMM_TZFS2 : integer := 03; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 1.
|
||||
constant TZMM_TZFS3 : integer := 04; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 2.
|
||||
constant TZMM_TZFS4 : integer := 05; -- TZFS main memory configuration. all memory is in tranZPUter RAM, E800-EFFF is used by TZFS, SA1510 is at 0000-1000 and RAM is 1000-CFFF, 64K Block 0 selected, F000-FFFF is in 64K Block 3.
|
||||
constant TZMM_CPM : integer := 06; -- CPM main memory configuration, all memory on the tranZPUter board, 64K block 4 selected. Special case for F3C0:F3FF & F7C0:F7FF (floppy disk paging vectors) which resides on the mainboard.
|
||||
constant TZMM_CPM2 : integer := 07; -- CPM main memory configuration, F000-FFFF are on the tranZPUter board in block 4, 0040-CFFF and E800-EFFF are in block 5, mainboard for D000-DFFF (video), E000-E800 (Memory control) selected.
|
||||
-- Special case for 0000:003F (interrupt vectors) which resides in block 4, F3FE:F3FF & F7FE:F7FF (floppy disk paging vectors) which resides on the mainboard.
|
||||
constant TZMM_COMPAT : integer := 08; -- Compatibility monitor mode, monitor ROM on mainboard, RAM on tranZPUter in Block 0 1000-CFFF.
|
||||
constant TZMM_HOSTACCESS : integer := 09; -- Monitor ROM 0000-0FFF and Main DRAM 0x1000-0xD000, video and memory mapped I/O are on the host machine, User/Floppy ROM E800-FFFF are in tranZPUter memory.
|
||||
constant TZMM_MZ700_0 : integer := 10; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the mainboard.
|
||||
constant TZMM_MZ700_1 : integer := 11; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
|
||||
constant TZMM_MZ700_2 : integer := 12; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is on the tranZPUter in block 6.
|
||||
constant TZMM_MZ700_3 : integer := 13; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 0, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
|
||||
constant TZMM_MZ700_4 : integer := 14; -- MZ700 Mode - 0000:0FFF is on the tranZPUter board in block 6, 1000:CFFF is on the tranZPUter board in block 0, D000:FFFF is inaccessible.
|
||||
constant TZMM_MZ800 : integer := 15; -- MZ800 Mode - Running on MZ800 hardware, configuration set according to MZ700/MZ800 mode.
|
||||
constant TZMM_MZ2000 : integer := 16; -- MZ2000 Mode - Running on MZ2000 hardware, configuration set according to runtime configuration registers.
|
||||
constant TZMM_FPGA : integer := 21; -- Open up access for the K64F to the FPGA resources such as memory. All other access to RAM or mainboard is blocked.
|
||||
constant TZMM_TZPUM : integer := 22; -- Everything in on mainboard, no access to tranZPUter memory.
|
||||
constant TZMM_TZPU : integer := 23; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
|
||||
constant TZMM_TZPU0 : integer := 24; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 0 is selected.
|
||||
constant TZMM_TZPU1 : integer := 25; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 1 is selected.
|
||||
constant TZMM_TZPU2 : integer := 26; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 2 is selected.
|
||||
constant TZMM_TZPU3 : integer := 27; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 3 is selected.
|
||||
constant TZMM_TZPU4 : integer := 28; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 4 is selected.
|
||||
constant TZMM_TZPU5 : integer := 29; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 5 is selected.
|
||||
constant TZMM_TZPU6 : integer := 30; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 6 is selected.
|
||||
constant TZMM_TZPU7 : integer := 31; -- Everything is in tranZPUter domain, no access to underlying Sharp mainboard unless memory management mode is switched. tranZPUter RAM 64K block 7 is selected.
|
||||
|
||||
|
||||
|
||||
------------------------------------------------------------
|
||||
-- Configurable parameters.
|
||||
------------------------------------------------------------
|
||||
-- Target hardware.
|
||||
constant CPLD_HOST_HW : integer := MODE_PCW8256;
|
||||
|
||||
-- Target video hardware.
|
||||
constant CPLD_HAS_FPGA_VIDEO : std_logic := '1';
|
||||
|
||||
-- Version of hdl.
|
||||
constant CPLD_VERSION : integer := 2;
|
||||
|
||||
-- Clock source for the secondary clock. If a K64F is installed then enable it otherwise use the onboard oscillator.
|
||||
--
|
||||
constant USE_K64F_CTL_CLOCK : integer := 1;
|
||||
|
||||
------------------------------------------------------------
|
||||
-- Function prototypes
|
||||
------------------------------------------------------------
|
||||
-- Find the maximum of two integers.
|
||||
function IntMax(a : in integer; b : in integer) return integer;
|
||||
|
||||
-- Find the number of bits required to represent an integer.
|
||||
function log2ceil(arg : positive) return natural;
|
||||
|
||||
-- Function to calculate the number of whole 'clock' cycles in a given time period, the period being in ns.
|
||||
function clockTicks(period : in integer; clock : in integer) return integer;
|
||||
|
||||
-- Function to reverse the order of the bits in a standard logic vector.
|
||||
-- ie. 1010 becomes 0101
|
||||
function reverse_vector(slv:std_logic_vector) return std_logic_vector;
|
||||
|
||||
-- Function to convert an integer (0 or 1) into std_logic.
|
||||
--
|
||||
function to_std_logic(i : in integer) return std_logic;
|
||||
|
||||
-- Function to return the value of a bit as an integer for array indexing etc.
|
||||
function bit_to_integer( s : std_logic ) return natural;
|
||||
|
||||
------------------------------------------------------------
|
||||
-- Records
|
||||
------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------
|
||||
-- Components
|
||||
------------------------------------------------------------
|
||||
|
||||
end tzpuFusionX_pkg;
|
||||
|
||||
------------------------------------------------------------
|
||||
-- Function definitions.
|
||||
------------------------------------------------------------
|
||||
package body tzpuFusionX_pkg is
|
||||
|
||||
-- Find the maximum of two integers.
|
||||
function IntMax(a : in integer; b : in integer) return integer is
|
||||
begin
|
||||
if a > b then
|
||||
return a;
|
||||
else
|
||||
return b;
|
||||
end if;
|
||||
return a;
|
||||
end function IntMax;
|
||||
|
||||
-- Find the number of bits required to represent an integer.
|
||||
function log2ceil(arg : positive) return natural is
|
||||
variable tmp : positive := 1;
|
||||
variable log : natural := 0;
|
||||
begin
|
||||
if arg = 1 then
|
||||
return 0;
|
||||
end if;
|
||||
|
||||
while arg > tmp loop
|
||||
tmp := tmp * 2;
|
||||
log := log + 1;
|
||||
end loop;
|
||||
return log;
|
||||
end function;
|
||||
|
||||
-- Function to calculate the number of whole 'clock' cycles in a given time period, the period being in ns.
|
||||
function clockTicks(period : in integer; clock : in integer) return integer is
|
||||
variable ticks : real;
|
||||
variable fracTicks : real;
|
||||
begin
|
||||
ticks := (Real(period) * Real(clock)) / 1000000000.0;
|
||||
fracTicks := ticks - CEIL(ticks);
|
||||
if fracTicks > 0.0001 then
|
||||
return Integer(CEIL(ticks + 1.0));
|
||||
else
|
||||
return Integer(CEIL(ticks));
|
||||
end if;
|
||||
end function;
|
||||
|
||||
function reverse_vector(slv:std_logic_vector) return std_logic_vector is
|
||||
variable target : std_logic_vector(slv'high downto slv'low);
|
||||
begin
|
||||
for idx in slv'high downto slv'low loop
|
||||
target(idx) := slv(slv'low + (slv'high-idx));
|
||||
end loop;
|
||||
return target;
|
||||
end reverse_vector;
|
||||
|
||||
function to_std_logic(i : in integer) return std_logic is
|
||||
begin
|
||||
if i = 0 then
|
||||
return '0';
|
||||
end if;
|
||||
return '1';
|
||||
end function;
|
||||
|
||||
-- Function to return the value of a bit as an integer for array indexing etc.
|
||||
function bit_to_integer( s : std_logic ) return natural is
|
||||
begin
|
||||
if s = '1' then
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
end if;
|
||||
end function;
|
||||
end package body;
|
||||
572
README.md
vendored
572
README.md
vendored
@@ -1,4 +1,10 @@
|
||||
<img src='http://eaw.app/images/FusionX_Wired.png' height='70%' width='70%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
# tzpuFusionX
|
||||
|
||||
**Website:** [engineers@work](https://eaw.app) | **Repository:** [git.eaw.app/eaw/tzpuFusionX](https://git.eaw.app/eaw/tzpuFusionX)
|
||||
|
||||
---
|
||||
|
||||
<img src='../images/FusionX_Wired.png' height='70%' width='70%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
|
||||
## <font style="color: yellow;" size="6">Overview</font>
|
||||
|
||||
@@ -7,7 +13,7 @@ The tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> is a spinoff concept from the tra
|
||||
rapid application loading from SD card and by using a daughter board, better graphics and sound.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The <i>FusionX</i> board can also be used to power alternative CPU's on the host for testing, development and to provide a completely different software platform and applications. It can use the underlying hosts keyboard, monitor, I/O and additionally better graphics and sound provided by the <i>FusionX</i>.
|
||||
The <i>FusionX</i> board can also be used to power alternative CPUs on the host for testing, development and to provide a completely different software platform and applications. It can use the underlying hosts keyboard, monitor, I/O and additionally better graphics and sound provided by the <i>FusionX</i>.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
It shares similarities with the tran<i>ZPU</i>ter<sup><i>Fusion</i></sup> but instead of realising it in hardware via an FPGA it realises
|
||||
@@ -18,7 +24,7 @@ Using the same base design as the tran<i>ZPU</i>ter<sup><i>Fusion</i></sup> it i
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
In Z80 configuration, a Linux Kernel driver instantiates a Z80 emulation which realises a Z80 CPU in software which in turn can command and control the host system. The kernel driver along with a controlling application
|
||||
can provide a wealth of features to the host through this mechanism. The SOM is also connected to an SD Drive and USB 2.0 port so there is no limit to features which can be proivded.
|
||||
can provide a wealth of features to the host through this mechanism. The SOM is also connected to an SD Drive and USB 2.0 port so there is no limit to features which can be provided.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
Like the tran<i>ZPU</i>ter<sup><i>Fusion</i></sup>, the tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> can provide enhanced video and sound to the host. The SOM incorporates dual DAC audio and a 2D GPU with configurable resolutions switched onto the hosts video and audio outputs under software control.
|
||||
@@ -27,8 +33,8 @@ Like the tran<i>ZPU</i>ter<sup><i>Fusion</i></sup>, the tran<i>ZPU</i>ter<sup><i
|
||||
The <i>FusionX</i> board is ideal for any developer wanting to physically program and interact with retro hardware using a Linux platform with Wifi and USB/Serial port connectivity.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
To most retro users, in the early stages of <i>FusionX</i> development, the board wont have much use. As the project matures, a board can be obtained and installed into the Z80 socket of their Sharp or simlar Z80 based system (providing there is sufficient room to accommodate this board) and utilise the upgraded featues, such as:
|
||||
<ul style="line-height: 0.9em;"><font size="3">
|
||||
To most retro users, in the early stages of <i>FusionX</i> development, the board won't have much use. As the project matures, a board can be obtained and installed into the Z80 socket of their Sharp or similar Z80 based system (providing there is sufficient room to accommodate this board) and utilise the upgraded features, such as:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">Original host specifications</font><br>- the machine behaves just as though it had a physical Z80 within. There might be slight differences in the Z80 functionality as it is implemented in software but the Z80 hardware timing is accurate.</li>
|
||||
<li><font style="color: orange;" size="3">Accelerator</font><br>- the Z80 can run at much higher speeds due to the abundance of memory and 1.2GHz dual-core processor, which would typically see performance upto that of a 500MHz Z80.</li>
|
||||
<li><font style="color: orange;" size="3">Emulation</font><br>- emulation of all the Sharp MZ series machines, experiencing it through the host system keyboard, monitor and I/O.</li>
|
||||
@@ -82,13 +88,13 @@ thus the CPLD is able to drive 5V circuitry and with sufficient drive current, 2
|
||||
The CPLD internal state machines are clocked by an external 50MHz oscillator, this allows for adequate sampling and state change for a typical 1MHz - 6MHz Z80 host.
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">Schematic 2 - I/O (Audio, UART, USB)</font>
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The SOM is rich in peripherals and this circuit interfaces some of them for use in the FusionX, these include:
|
||||
|
||||
<ul style="line-height: 0.9em;"><font size="3">
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">Stereo Audio Microphone input</font><br>- a digital microphone input is also available but the pins are used in the CPLD interface.</li>
|
||||
<li><font style="color: orange;" size="3">Stereo Audio DAC output</font><br>- dual digital to analogue converters for sound output which can be clocked at 48KHz.</li>
|
||||
<li><font style="color: orange;" size="3">WiFi Antenna</font><br>- a SSW101B 20/40MHz IEEE 802.11 b/g/n/e/l/n/w WiFi transceiver operating in the 2.4GHz band with a 500M range. The SOM also includes a 100MHz ETH PHY but this is not used in this design as hard wired ethernet is not practical for a board which is
|
||||
@@ -97,12 +103,12 @@ sited inside a retro machine.</li>
|
||||
<li><font style="color: orange;" size="3">USB</font><br>- a Linux connected USB port allowing for device expansion, such as additional storage, mice etc.</li>
|
||||
<li><font style="color: orange;" size="3">Fast UART</font><br>- high speed full duplex with hardware handshake UART.</li>
|
||||
<li><font style="color: orange;" size="3">UART</font><br>- standard 2 pin UART operating upto 500KHz.</li>
|
||||
<li><font style="color: orange;" size="3">SD Card</font><br>- the SOM has inbuilt FlashNAND so can accomodate a simple Linux filesystem, addition of an SD card allows for greater storage of Host applications and Linux utilities. An SD card also makes for ease of upgrades as the SOM will auto upgrade when a suitably prepared SD card is present on boot.</li>
|
||||
<li><font style="color: orange;" size="3">SD Card</font><br>- the SOM has inbuilt FlashNAND so can accommodate a simple Linux filesystem, addition of an SD card allows for greater storage of Host applications and Linux utilities. An SD card also makes for ease of upgrades as the SOM will auto upgrade when a suitably prepared SD card is present on boot.</li>
|
||||
</font></ul>
|
||||
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">Schematic 3 - Video (VideoDAC, Contrast DAC)</font>
|
||||
|
||||
@@ -117,7 +123,7 @@ DAC, as it is sending the video signal with colour information as a voltage cont
|
||||
In order to get true black, the CPLD creates a blanking signal, MONO.BLANK, which is paired with a MUX 0V clamp on the daughter board which drives the monochrome monitor, this sees the RGB332 as 0V when 00000000 is present, then varying between 4.01V-5V when non-zero.
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">Schematic 4 - Power Supply (3.3V, USB)</font>
|
||||
|
||||
@@ -128,7 +134,7 @@ The power supply, for the SOM and CPLD, converts the 5V present on the Z80 socke
|
||||
Additionally, a software controlled USB power switch is installed to enable (and reset if required) +5V power to the USB expansion port.
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">Schematic 5 - CPLD Interface</font>
|
||||
|
||||
@@ -136,70 +142,490 @@ Additionally, a software controlled USB power switch is installed to enable (and
|
||||
The final schematic is the interface between the SOM and the CPLD. Originally this was going to be a bi-directional 16bit bus with Read/Write and Strobe signals but after testing, the setup time for a 16bit signal with tri-state switching was much slower than an SPI connection
|
||||
due to the GPIO register layout and operation within the SOM and the speed of the I/O operations within the SOM.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
The solution used is to have a bidirectional 72MHz SPI bus between the SOM and CPLD for transmitting Z80 transaction requests and an 8bit read only parallel bus for more rapid reading of Z80 Data and seperate Z80 state information.
|
||||
The solution used is to have a bidirectional 72MHz SPI bus between the SOM and CPLD for transmitting Z80 transaction requests and an 8bit read only parallel bus for more rapid reading of Z80 Data and separate Z80 state information.
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
#### <font style="color: yellow;" size="5">PCB
|
||||
#### <font style="color: yellow;" size="5">PCB</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The PCB was designed with minimum size as a primary requirement for the various machines in which it would be installed. It also had to be compatible with the tran<i>ZPU</i>ter<sup><i>Fusion</i></sup> for interchangeability.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
A major concern was heat dissipation as the PCB, when installed within an MZ-700 is very close to existing motherboard components which give off a lot of heat with no air circulation in a sealed compact housing. This meant active components couldnt be sited on the PCB underside
|
||||
A major concern was heat dissipation as the PCB, when installed within an MZ-700 is very close to existing motherboard components which give off a lot of heat with no air circulation in a sealed compact housing. This meant active components couldn't be sited on the PCB underside
|
||||
as heat generation would lead to instability and failure, which in turn led to an increase in the final PCB size.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The smallest components which could be manually assembled where used, ie. 0402/0603 passive devices and 0.5mm IC pitch spacing to reduce overall size and a 4 layer stackup selected to fit all required components.
|
||||
The smallest components which could be manually assembled were used, ie. 0402/0603 passive devices and 0.5mm IC pitch spacing to reduce overall size and a 4 layer stackup selected to fit all required components.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
</div>
|
||||
|
||||
<font style="color: cyan;" size="4">PCB Top Overview</font>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">PCB Bottom Overview</font>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">PCB 4 Layer Routing Overview</font>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">PCB Assembled</font>
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
|
||||
<font style="color: cyan;" size="4">PCB Component Placement and Bill of Materials</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
Click <a href="http://eaw.app/_pages/FusionX_v1_0_BOM.html">here</a> to view an interactive PCB component placement diagram and Bill of Materials.
|
||||
Click <a href="../_pages/FusionX_v1_0_BOM.html">here</a> to view an interactive PCB component placement diagram and Bill of Materials.
|
||||
</div>
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
<a name="cpld" id="cpld"></a>
|
||||
###### <font style="color: yellow;" size="5">CPLD</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> uses an Altera MAX7000AE CPLD — specifically the <b>EPM7512AETC144-10</b> — as the central interface between the SOM and the host Z80 socket. This is a 512-macrocell, 144-pin TQFP device operating at 3.3V LVTTL on its outputs while accepting 5V TTL levels on its inputs, making it directly compatible with vintage Sharp MZ and other Z80-based hardware without any additional level shifting.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The CPLD design is written in VHDL and built with <b>Altera Quartus II 13.0.1 SP1 (Web Edition)</b>. Because each host machine has slightly different bus timing requirements and memory map constraints, a separate VHDL implementation is maintained for each supported host:
|
||||
</div>
|
||||
<div style="padding-top: 0.4em;"></div>
|
||||
|
||||
| VHDL Variant | Host Machine | Directory |
|
||||
|---|---|---|
|
||||
| `tzpuFusionX.vhd` (MZ80A) | Sharp MZ-80A | `CPLD/v1.0/MZ80A/` |
|
||||
| `tzpuFusionX.vhd` (MZ700) | Sharp MZ-700 | `CPLD/v1.0/MZ700/` |
|
||||
| `tzpuFusionX.vhd` (MZ2000) | Sharp MZ-2000 | `CPLD/v1.0/MZ2000/` |
|
||||
| `tzpuFusionX.vhd` (PCW8256) | Amstrad PCW-8256 | `CPLD/v1.0/PCW8256/` |
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="cpld-purpose" id="cpld-purpose"></a>
|
||||
<font style="color: cyan;" size="4">Purpose and Role</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The CPLD performs several functions that would be impractical or impossible to implement directly in software on the SOM:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">Voltage level translation</font><br>— Bridges the 5V TTL Z80 host bus to the 3.3V LVTTL signals used by the SOM. The MAX7000AE is 5V tolerant on inputs and drives outputs at 3.3V, which exceeds the 2.4V switching threshold of 5V TTL receivers, giving up to 25mA drive per pin.</li>
|
||||
<li><font style="color: orange;" size="3">Cycle-accurate Z80 bus timing</font><br>— The CPLD implements a hardware FSM clocked by a 50MHz external oscillator that samples the host Z80 clock and reproduces the precise T-state sequence for every bus cycle type. This offloads all critical timing from the SOM, which only needs to respond with data within the window defined by the CPLD FSM.</li>
|
||||
<li><font style="color: orange;" size="3">SOM interface bridging</font><br>— Converts between the Z80 parallel bus protocol and the SPI + 8-bit GPIO interface used by the SOM kernel module, translating bus events into a format that the SSD202 can service efficiently from a Linux kernel thread.</li>
|
||||
<li><font style="color: orange;" size="3">Video and audio switching</font><br>— Controls multiplexers that select between the host machine's native video/audio output and the SOM video/audio for routing to the monitor and speakers via daughter board connectors. Switching is commanded by the SOM over SPI.</li>
|
||||
<li><font style="color: orange;" size="3">Video sync and clock generation</font><br>— Generates composite sync (<code>VGA_CSYNCn</code>) from the SOM VSync and HSync signals, detects blanking intervals, generates a 25MHz pixel clock for the monochrome DAC (by dividing the 50MHz oscillator), and produces a colour carrier frequency signal (<code>VGA_COLR</code>) for composite colour output.</li>
|
||||
<li><font style="color: orange;" size="3">Reset management</font><br>— Monitors the host Z80 RESET line and implements a dual-press reset protocol: a single reset press asserts a soft reset to the SOM (allowing the Z80 application to reinitialise), while a second press within one second drives the SOM <code>PM_RESET</code> line to force a full SOM power-cycle reboot.</li>
|
||||
<li><font style="color: orange;" size="3">USB power control</font><br>— Controls the USB VBUS power enable signal under SOM command.</li>
|
||||
</font></ul>
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="cpld-fsm" id="cpld-fsm"></a>
|
||||
<font style="color: cyan;" size="4">Z80 Bus FSM</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The heart of the CPLD design is a finite state machine (<code>SOMFSMState</code>) that tracks and reproduces the Z80 bus cycle state at 50MHz resolution. The FSM monitors the host Z80 clock edges and the bus control signals (MREQ, IORQ, RD, WR, M1, RFSH, BUSRQ, HALT, WAIT) to classify each bus cycle and step through the correct T-state sequence:
|
||||
</div>
|
||||
<div style="padding-top: 0.4em;"></div>
|
||||
|
||||
| FSM State | Z80 Bus Cycle | Description |
|
||||
|---|---|---|
|
||||
| `IdleCycle` | — | Bus is idle; waiting for MREQ or IORQ assertion. |
|
||||
| `FetchCycle` | Opcode Fetch (M1) | M1 + MREQ + RD active; address and data phases timed across T1–T3. |
|
||||
| `RefreshCycle` | DRAM Refresh | RFSH + MREQ active; lower 7 bits of address presented for DRAM row refresh. |
|
||||
| `ReadCycle` | Memory Read | MREQ + RD active; address presented T1, data sampled T3. |
|
||||
| `WriteCycle` | Memory Write | MREQ + WR active; address and data presented T1–T2, write strobed T3. |
|
||||
| `ReadIOCycle` | I/O Read | IORQ + RD active; I/O address and data phases with WAIT support. |
|
||||
| `WriteIOCycle` | I/O Write | IORQ + WR active; I/O address and data presented with WAIT support. |
|
||||
| `HaltCycle` | HALT | Z80 HALT assertion detected; repeated NOP fetch cycles suppressed. |
|
||||
| `BusReqCycle` | Bus Request | BUSRQ asserted; BUSACK driven, bus lines tri-stated, SOM notified. |
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
Each state has numbered sub-states (e.g. <code>FetchCycle_11</code>, <code>FetchCycle_20</code>) corresponding to individual half-cycles within the T-state, allowing the CPLD to assert or deassert control signals with sub-clock-cycle precision relative to the host CLK edges.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
A secondary <code>CTRLFSMState</code> FSM handles SPI command processing (<code>CTRLCMD_Idle</code> → <code>CTRLCMD_ReadIOWrite</code>) independently of the main bus cycle FSM, so that SPI transactions from the SOM do not block Z80 bus cycle servicing.
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="cpld-som-interface" id="cpld-som-interface"></a>
|
||||
<font style="color: cyan;" size="4">SOM Interface</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The CPLD presents two distinct interfaces to the SOM:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">SPI slave (write path)</font><br>— A 4-wire SPI slave (<code>VSOM_SPI_CLK</code>, <code>VSOM_SPI_MOSI</code>, <code>VSOM_SPI_MISO</code>, <code>VSOM_SPI_CSn</code>) receives commands and data from the SOM. Up to 4 bytes per frame are shifted in via a serial shift register and decoded into bus control commands (memory write data, I/O write data, video/audio source selection, USB power control). The SPI clock polarity is parameterised (<code>SPI_CLK_POLARITY</code>) to accommodate different SOM SPI configurations.</li>
|
||||
<li><font style="color: orange;" size="3">8-bit parallel bus (read path)</font><br>— An 8-bit output bus (<code>VSOM_DATA_OUT[7:0]</code>) with a <code>VSOM_HBYTE</code> select line presents either the low or high byte of the current Z80 address/data word to the SOM GPIO inputs. Additional single-bit status lines report: <code>VSOM_READY</code> (FSM idle), <code>VSOM_LTSTATE</code> (last T-state of current cycle), <code>VSOM_BUSRQ</code>, <code>VSOM_BUSACK</code>, <code>VSOM_INT</code>, <code>VSOM_NMI</code>, <code>VSOM_WAIT</code>, and <code>VSOM_RESET</code>.</li>
|
||||
</font></ul>
|
||||
|
||||
This split architecture — SPI for writes, GPIO parallel bus for reads — matches the relative performance characteristics of the SSD202: SPI is clocked and reliable for multi-byte writes, while GPIO direct register access gives the lowest possible read latency for sampling bus state within a Z80 T-state window.
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="cpld-build" id="cpld-build"></a>
|
||||
<font style="color: cyan;" size="4">Building the CPLD Image</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The CPLD bitstream is produced using <b>Altera Quartus II 13.0.1 SP1 Web Edition</b>, which is available as a free download from the Intel FPGA (formerly Altera) website. The Web Edition supports all MAX7000AE devices and is sufficient for this project.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
<font style="color: cyan;" size="3">Opening the Project</font><br>
|
||||
|
||||
Each host machine variant has its own Quartus project in the corresponding subdirectory. To build the MZ-80A variant, for example:
|
||||
|
||||
<pre style="font-size: 0.70em; line-height: 1.3em; background: #1a1a1a; padding: 1em; border-radius: 4px; overflow-x: auto;"># Open in Quartus II GUI:
|
||||
File -> Open Project -> CPLD/v1.0/MZ80A/build/tzpuFusionX_MZ80A.qpf
|
||||
|
||||
# Or launch from the command line using the Quartus shell:
|
||||
quartus_sh --flow compile tzpuFusionX_MZ80A
|
||||
</pre>
|
||||
|
||||
The project references three VHDL source files (paths relative to the project <code>build/</code> directory):
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><code>../tzpuFusionX_Toplevel.vhd</code> — top-level entity instantiation and I/O pin definitions</li>
|
||||
<li><code>../tzpuFusionX_pkg.vhd</code> — shared package (types, constants)</li>
|
||||
<li><code>../tzpuFusionX.vhd</code> — main RTL architecture (FSMs, SPI, bus interface, video/audio control)</li>
|
||||
</font></ul>
|
||||
|
||||
<font style="color: cyan;" size="3">Compilation</font><br>
|
||||
|
||||
In the Quartus GUI select <b>Processing → Start Compilation</b> (or press Ctrl+L). The tool runs Analysis & Synthesis, Fitter, Assembler and Timing Analysis in sequence. A successful build produces:
|
||||
|
||||
<pre style="font-size: 0.70em; line-height: 1.3em; background: #1a1a1a; padding: 1em; border-radius: 4px; overflow-x: auto;">build/output_files/tzpuFusionX_MZ80A.pof # Programmer Object File (JTAG programming)
|
||||
build/output_files/tzpuFusionX_MZ80A.fit.rpt # Fitter report (resource usage)
|
||||
build/output_files/tzpuFusionX_MZ80A.sta.rpt # Timing analysis report
|
||||
</pre>
|
||||
|
||||
The <code>.pof</code> file is the binary image used to program the physical CPLD device.
|
||||
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
<font style="color: cyan;" size="3">Programming the CPLD</font><br>
|
||||
|
||||
Programming is performed via JTAG using an Altera USB-Blaster or compatible JTAG adapter connected to the 10-pin JTAG header on the <i>FusionX</i> board:
|
||||
<ol style="line-height: 1.6em;"><font size="3">
|
||||
<li>Connect the USB-Blaster to the <i>FusionX</i> JTAG header and the host PC.</li>
|
||||
<li>Power the <i>FusionX</i> board (the CPLD must be powered during programming).</li>
|
||||
<li>In Quartus II, open <b>Tools → Programmer</b>.</li>
|
||||
<li>Load the chain description file: <code>build/output_files/tzpuFusionX_MZ80A.cdf</code>.</li>
|
||||
<li>Verify the USB-Blaster is detected in the hardware list, then click <b>Start</b>.</li>
|
||||
<li>Programming completes in a few seconds; the CPLD becomes active immediately on completion.</li>
|
||||
</font></ol>
|
||||
|
||||
The CPLD retains its programmed logic indefinitely without power (MAX7000AE uses EEPROM-based configuration cells) so the device only needs to be programmed once per build or when updating to a new bitstream.
|
||||
</div>
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
## <font style="color: yellow;" size="6">Software</font>
|
||||
|
||||
<font size="2">Under construction.</font>
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The <i>FusionX</i> software stack spans from the Linux operating system through to dedicated kernel modules and user-space utilities. The complete software set is built using a customised SigmaStar build environment and loaded onto the SOM's SPI NAND flash. On boot, U-boot initialises the SOM and hands off to the Linux kernel, which loads the Buildroot root filesystem. The <i>FusionX</i> startup script then configures the system and brings the Z80 emulator online.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The software components are:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">Linux OS</font><br>— Kernel 4.9-rt (PREEMPT_RT) with Buildroot root filesystem running on the SigmaStar SSD202 dual-core Cortex-A7.</li>
|
||||
<li><font style="color: orange;" size="3">z80drv.ko</font><br>— Linux kernel module implementing the Z80 CPU emulator and host hardware interface. Runs the Z80 emulation loop on a dedicated CPU core.</li>
|
||||
<li><font style="color: orange;" size="3">ttymzdrv.ko</font><br>— Linux TTY kernel module that presents the Sharp MZ keyboard and display as a standard Linux terminal device (<code>/dev/ttymz0</code>).</li>
|
||||
<li><font style="color: orange;" size="3">z80ctrl</font><br>— User-space command-line utility for controlling the z80drv kernel module: load ROM images, add virtual hardware devices, start/stop emulation and inspect emulated memory.</li>
|
||||
<li><font style="color: orange;" size="3">k64fcpu</font><br>— User-space daemon emulating a K64F virtual CPU. Used in TZFS mode to manage ROM loading and inter-processor communication with the Z80 emulator.</li>
|
||||
<li><font style="color: orange;" size="3">sharpbiter</font><br>— Sharp MZ arbiter daemon, coordinating access to the shared Sharp MZ hardware resources between the Z80 emulator and the Linux TTY driver.</li>
|
||||
</font></ul>
|
||||
|
||||
Startup is handled by <code>start_FusionX.sh</code>, which loads <code>ttymzdrv.ko</code>, starts a getty login session on <code>/dev/ttymz0</code>, pins all Linux processes and IRQs to CPU0, loads <code>z80drv.ko</code> onto the isolated CPU1, then launches the <code>k64fcpu</code> and <code>sharpbiter</code> daemons. Two pre-built startup modes are provided:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">RFS mode</font><br>(<code>startZ80_RFS.sh</code>) — loads the ROM Filing System virtual hardware device and starts the MZ-80A emulator with 40- or 80-column ROM images.</li>
|
||||
<li><font style="color: orange;" size="3">TZFS mode</font><br>(<code>startZ80_TZFS.sh</code>) — loads the tranZPUter SW virtual hardware device and starts the <code>k64fcpu</code> K64F daemon which manages Monitor and TZFS ROM image loading.</li>
|
||||
</font></ul>
|
||||
</div>
|
||||
|
||||
|
||||
<a name="architecture" id="architecture"></a>
|
||||
###### <font style="color: yellow;" size="5">Architecture</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The <i>FusionX</i> software architecture is layered, with each layer handling a distinct responsibility. From the host machine's perspective the flow is entirely transparent — the Z80 socket behaves as a normal Z80 CPU while the SOM is silently intercepting and emulating every bus cycle.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
<pre style="font-size: 0.70em; line-height: 1.3em; background: #1a1a1a; padding: 1em; border-radius: 4px; overflow-x: auto;">
|
||||
Sharp MZ Host
|
||||
+------------------------------------------+
|
||||
| Z80 DIP-40 Socket |
|
||||
+--------------+---------------------------+
|
||||
| Z80 bus (address, data, control)
|
||||
+--------------v---------------------------+
|
||||
| CPLD (Altera MAX 7000A) |
|
||||
| . 5V <-> 3.3V level translation |
|
||||
| . Cycle-accurate Z80 bus timing |
|
||||
| . 50 MHz internal clock |
|
||||
+--------------+---------------------------+
|
||||
| SPI (50 MHz) + 8-bit GPIO bus
|
||||
+--------------v---------------------------+
|
||||
| SSD202 SOM -- CPU1 (dedicated) |
|
||||
| +--------------------------------------+|
|
||||
| | z80drv.ko kernel module ||
|
||||
| | +----------------------------------+||
|
||||
| | | z80io.c (GPIO/SPI HAL) |||
|
||||
| | +----------------------------------+||
|
||||
| | | Zeta Z80 CPU emulator core |||
|
||||
| | +----------------------------------+||
|
||||
| | | Virtual hardware modules |||
|
||||
| | | (z80vhw_*.c, inline) |||
|
||||
| | +----------------------------------+||
|
||||
| +--------------------------------------+|
|
||||
| |
|
||||
| SSD202 SOM -- CPU0 (Linux) |
|
||||
| +--------------------------------------+|
|
||||
| | Linux 4.9-rt / Buildroot rootfs ||
|
||||
| | ttymzdrv.ko --> /dev/ttymz0 ||
|
||||
| | z80ctrl (control utility) ||
|
||||
| | k64fcpu (K64F daemon) ||
|
||||
| | sharpbiter (MZ arbiter) ||
|
||||
| +--------------------------------------+|
|
||||
+------------------------------------------+
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="dual-core-design" id="dual-core-design"></a>
|
||||
<font style="color: cyan;" size="4">Dual-Core Design</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The SSD202's two Cortex-A7 cores operate under a strict separation of responsibility. At startup every Linux process and every hardware IRQ affinity is migrated to CPU0, leaving CPU1 exclusively available to the Z80 emulation kernel thread. The CPU frequency governor is set to performance mode (1.2GHz fixed) after the emulator starts to prevent frequency-scaling transitions from introducing timing variation in the emulation loop.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
<b>CPU0 — Linux and User-Space Services</b><br>
|
||||
Runs the complete Linux 4.9-rt operating system, all user-space daemons and handles all hardware interrupts. Key responsibilities on CPU0 include:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">ttymzdrv.ko</font><br>— Linux TTY kernel module that maps the Sharp MZ keyboard and display to <code>/dev/ttymz0</code>. Supports suspend and resume, enabling the user to switch seamlessly between a Z80 session and a Linux console at the host machine without losing state in either.</li>
|
||||
<li><font style="color: orange;" size="3">z80ctrl utility</font><br>— Command-line tool for runtime control of the Z80 emulator: loading ROM images, registering virtual hardware devices, starting and stopping the emulation loop, and inspecting emulated memory. Communicates with <code>z80drv.ko</code> via a kernel character device.</li>
|
||||
<li><font style="color: orange;" size="3">k64fcpu daemon</font><br>— User-space daemon that emulates a K64F virtual CPU. Active in TZFS mode; it manages Monitor and TZFS ROM image loading into the emulator's memory space and relays inter-processor commands to <code>z80drv.ko</code>.</li>
|
||||
<li><font style="color: orange;" size="3">sharpbiter daemon</font><br>— Sharp MZ arbiter; coordinates access to the shared Sharp MZ keyboard and display hardware between the TTY driver and the Z80 emulator so that both can operate without conflicting on the underlying I/O registers.</li>
|
||||
<li><font style="color: orange;" size="3">WiFi and web server</font><br>— The SOM's integrated 802.11 b/g/n transceiver (SSW101B) provides network connectivity. A lightweight web server on CPU0 can serve configuration and status pages, and the WiFi stack handles OTA firmware delivery via SD card auto-upgrade on boot.</li>
|
||||
</font></ul>
|
||||
|
||||
<b>CPU1 — Z80 Emulator (dedicated)</b><br>
|
||||
Exclusively runs the <code>kthread_z80</code> kernel thread spawned by <code>z80drv.ko</code>. No other process or interrupt is ever scheduled on CPU1 after initialisation. The emulation loop on CPU1:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li>Calls the Zeta Z80 CPU core for each instruction execution step</li>
|
||||
<li>Dispatches each resulting memory or I/O access to the correct handler — physical host hardware, kernel-resident RAM image, or a virtual hardware module function</li>
|
||||
<li>Drives the GPIO and SPI hardware via <code>z80io.c</code> to assert or sample the Z80 bus signals through the CPLD</li>
|
||||
<li>Runs at 1.2GHz with the PREEMPT_RT kernel ensuring minimal interrupt jitter even from CPU0 activity</li>
|
||||
</font></ul>
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="cpld-bus-interface" id="cpld-bus-interface"></a>
|
||||
<font style="color: cyan;" size="4">CPLD Bus Interface</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The hardware path from the SOM to the Z80 host socket passes through an Altera MAX 7000A CPLD. This device serves two essential roles:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">Voltage level translation</font><br>— The CPLD is 5V tolerant on its inputs and drives outputs at 3.3V Low Voltage TTL levels. Since the 5V TTL switching threshold is approximately 2.4V the CPLD can drive 5V host logic directly with up to 25mA per pin, making the board compatible with unmodified vintage Z80 hardware.</li>
|
||||
<li><font style="color: orange;" size="3">Cycle-accurate Z80 bus timing</font><br>— The CPLD embeds state machines clocked by an external 50MHz oscillator. These state machines sample the Z80 host clock and reproduce the precise T-state sequence for each bus cycle (fetch, memory read/write, I/O read/write) as defined in the Z80 state diagrams. This means the SOM kernel module does not need to replicate sub-microsecond Z80 timing in software — the CPLD handles it in hardware.</li>
|
||||
</font></ul>
|
||||
|
||||
The SOM communicates with the CPLD through two parallel channels:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">SPI channel (50MHz)</font><br>— used for writing data and commands to the CPLD. SPI write is used in preference to GPIO for host bus writes because it is clocked and therefore more reliable for multi-byte transfers at speed.</li>
|
||||
<li><font style="color: orange;" size="3">8-bit GPIO bus</font><br>— used by <code>z80io.c</code> for reading bus status and address/data values from the CPLD. Direct register access is used (bypassing the SigmaStar HAL API after initialisation) to minimise read latency. The maximum read throughput achievable via the SSD202 GPIO structure is approximately 2MB/s for an 8-bit byte — fast enough to service Z80 bus cycles at typical host clock rates (1MHz–6MHz) when combined with the CPLD buffering.</li>
|
||||
</font></ul>
|
||||
|
||||
Because the GPIO read throughput sets an upper bound on bus transaction rate, Z80 programs execute from kernel-resident memory images rather than being read from the physical host memory bus on every access. ROM images are loaded into kernel memory at startup, and all memory accesses by the emulated Z80 are serviced from there — the physical host bus is only engaged when a <code>PHYSICAL</code>-type block is encountered (e.g. for host video RAM or hardware registers that must be accessed on the real hardware).
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="memory-architecture" id="memory-architecture"></a>
|
||||
<font style="color: cyan;" size="4">Memory Architecture</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The 128MB DRAM on the SSD202 SOM is shared between the Linux operating system and the Z80 kernel module. The kernel module allocates a contiguous region of physically-addressed kernel memory to hold ROM and RAM images for the emulated Z80. This region is accessed directly by the <code>kthread_z80</code> running on CPU1, with no virtual memory translation overhead in the inner emulation loop.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The emulated Z80 sees a configurable memory map across the standard 64KB (0x0000–0xFFFF) address space. Each region is assigned one of the following access types:
|
||||
</div>
|
||||
<div style="padding-top: 0.4em;"></div>
|
||||
|
||||
| Type | Description |
|
||||
|------|-------------|
|
||||
| `kernel RAM` | Read/write region backed by a kernel-allocated DRAM buffer. Standard RAM for the emulated machine. |
|
||||
| `kernel ROM` | Read-only region in kernel DRAM. Write cycles are silently discarded. Used for Monitor ROMs, BASIC ROMs, User ROMs, TZFS ROM pages. |
|
||||
| `PHYSICAL` | Pass-through to real host hardware — the SOM releases the CPLD bus and the host hardware responds to the cycle directly. Used for host video RAM and I/O registers that must interact with real hardware. |
|
||||
| `VIRTUAL` | Each access triggers a C handler function within the kernel module. Used to emulate peripheral devices (floppy controller, QuickDisk, RFS banking logic) without any real hardware. |
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
ROM images are loaded into kernel memory at startup by <code>z80ctrl --loadrom</code> (or automatically by the active virtual hardware module or the <code>k64fcpu</code> daemon in TZFS mode). Multiple ROM page sets can be resident simultaneously — the RFS virtual hardware module, for example, maintains up to four switchable ROM pages (MROM, User ROM I/II/III) for 40-column and 80-column configurations.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
Machine timing constants for each supported host (MZ-80A, MZ-700, MZ-2000, PCW-8256) are defined in <code>z80driver.h</code> and used by the emulation loop to pace bus cycles at the correct rate relative to the host clock, ensuring that time-sensitive software (tape motor control, serial I/O, delay loops) behaves as it would on original hardware.
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="virtual-hardware-modules" id="virtual-hardware-modules"></a>
|
||||
<font style="color: cyan;" size="4">Virtual Hardware Modules</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
Virtual hardware modules are C source files (<code>z80vhw_*.c</code>) that define the behaviour of a specific host machine or peripheral set. Rather than being compiled as separately-linked objects they are <code>#include</code>d directly into <code>z80driver.c</code>, so their handler functions are inlined into the emulation dispatch path with no function-call overhead.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
Up to five virtual hardware devices can be active simultaneously (<code>MAX_VIRTUAL_DEVICES 5</code>). Devices are registered at runtime before the emulator starts using <code>z80ctrl --adddev --device <name></code>. Each registered device receives memory read, memory write, I/O read and I/O write callbacks for the address ranges it claims, and can optionally install its own ROM images and configure the memory map during initialisation.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The available modules and the host machines they support are:
|
||||
</div>
|
||||
<div style="padding-top: 0.4em;"></div>
|
||||
|
||||
| Module | Host | Role |
|
||||
|--------|------|------|
|
||||
| `z80vhw_mz80a.c` | Sharp MZ-80A | Original MZ-80A memory map, keyboard matrix and display I/O — no extensions. |
|
||||
| `z80vhw_mz700.c` | Sharp MZ-700 | MZ-700 bank-switching, video and keyboard I/O emulation. |
|
||||
| `z80vhw_mz2000.c` | Sharp MZ-2000 | MZ-2000 memory map, extended video modes and I/O. |
|
||||
| `z80vhw_pcw.c` | Amstrad PCW-8256 | PCW-8256 memory/bank paging and peripheral I/O. |
|
||||
| `z80vhw_rfs.c` | MZ-80A + RFS board | ROM Filing System: manages four switchable ROM pages (40-col and 80-col sets), SD-based MZF program loading, bank switching. |
|
||||
| `z80vhw_tzpu.c` | MZ-80A + tranZPUter SW | tranZPUter SW virtual hardware; the kernel-side driver works with the userspace <code>k64fcpu</code> daemon to provide K64F virtual CPU behaviour, TZFS ROM page management and CP/M support. |
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The TZPU module (<code>z80vhw_tzpu.c</code>) is architecturally distinct from the others. Because the K64F co-processor behaviour is complex and stateful, it is split across two components: the <code>z80vhw_tzpu.c</code> kernel-side stub handles fast bus-cycle dispatch while the <code>k64fcpu</code> user-space daemon on CPU0 manages ROM loading, memory bank selection and higher-level K64F command processing. The two halves communicate via a shared memory region in the kernel module.
|
||||
</div>
|
||||
|
||||
|
||||
<a name="build" id="build"></a>
|
||||
###### <font style="color: yellow;" size="5">Build</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The complete <i>FusionX</i> OS and application set is built using the <code>Build_FusionX.sh</code> script, which wraps the SigmaStar SDK build system and produces a ready-to-flash NAND image. Building requires a Linux host with the ARM cross-compiler toolchain installed.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
<font style="color: cyan;" size="4">Prerequisites</font>
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li>ARM cross-compiler: <code>arm-linux-gnueabihf-gcc</code> (e.g. from <code>gcc-arm-linux-gnueabihf</code> package)</li>
|
||||
<li>SigmaStar SDK source tree (kernel, U-boot, Buildroot) in the parent directory structure expected by <code>Build_FusionX.sh</code></li>
|
||||
<li>FusionX application source in the <code>../FusionX</code> directory relative to the linux build directory</li>
|
||||
<li>Standard build tools: <code>make</code>, <code>cmake</code>, <code>bc</code>, <code>libssl-dev</code></li>
|
||||
</font></ul>
|
||||
|
||||
<font style="color: cyan;" size="4">Building the Full OS Image</font>
|
||||
|
||||
The build is launched from the <code>software/linux/</code> directory:
|
||||
|
||||
<pre style="font-size: 0.70em; line-height: 1.3em; background: #1a1a1a; padding: 1em; border-radius: 4px; overflow-x: auto;"># Build full image for FusionX (project 2D06, SPI NAND, SSD202, 256MB flash)
|
||||
./Build_FusionX.sh -f nand -p ssd202 -o 2D06 -m 256
|
||||
</pre>
|
||||
|
||||
This builds in sequence: U-boot bootloader, Linux kernel (using the FusionX custom defconfig <code>infinity2m_spinand_fusionx_defconfig</code>), Buildroot root filesystem and the FusionX application set. Output images are written to <code>project/image/output/images/</code>.
|
||||
|
||||
For the standard SigmaStar reference configuration use project <code>2D07</code> instead.
|
||||
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
<font style="color: cyan;" size="4">Building Kernel Modules Only</font>
|
||||
|
||||
The kernel modules can be rebuilt independently against an already-built kernel tree, which is useful during development:
|
||||
|
||||
<pre style="font-size: 0.70em; line-height: 1.3em; background: #1a1a1a; padding: 1em; border-radius: 4px; overflow-x: auto;"># Build z80drv kernel module
|
||||
cd software/FusionX/src/z80drv/src.mz80a
|
||||
make
|
||||
|
||||
# Build ttymzdrv kernel module
|
||||
cd software/FusionX/src/ttymz
|
||||
make
|
||||
</pre>
|
||||
|
||||
The resulting <code>z80drv.ko</code> and <code>ttymzdrv.ko</code> files can be copied directly to the <code>/apps/FusionX/modules/</code> directory on the running SOM (via SSH or SD card) and loaded with <code>insmod</code>.
|
||||
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
<font style="color: cyan;" size="4">Flashing and Updates</font>
|
||||
|
||||
The flash image produced by the build script is programmed to the SOM SPI NAND via the SigmaStar ISP tool over USB. Once the initial image is installed, subsequent updates can be delivered via SD card — when the SOM boots with a suitably prepared SD card present it will auto-upgrade the NAND image without requiring a USB connection.
|
||||
</div>
|
||||
|
||||
|
||||
###### <font style="color: yellow;" size="5">Linux</font>
|
||||
|
||||
<font size="2">Under construction.</font>
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The Linux platform runs on the SigmaStar SSD202 (Infinity2M) SOM — a 29mm × 29mm stamp module containing a dual-core ARM Cortex-A7 at 1.2GHz, 128MB DRAM, 256MB SPI NAND flash and an integrated 802.11 b/g/n WiFi transceiver. The kernel is Linux 4.9 with the PREEMPT_RT real-time patch applied to minimise scheduling latency, which is essential for responsive Z80 emulation.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The complete OS image — U-boot bootloader, Linux kernel, Buildroot root filesystem and FusionX application set — is assembled using the <code>Build_FusionX.sh</code> script, a customised version of the SigmaStar SDK build system. Two project targets are defined:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><font style="color: orange;" size="3">2D06</font><br>— FusionX custom configuration using the <code>infinity2m_spinand_fusionx_defconfig</code> kernel defconfig.</li>
|
||||
<li><font style="color: orange;" size="3">2D07</font><br>— Standard SigmaStar reference configuration using <code>infinity2m_spinand_ssc011a_s01a_minigui_defconfig</code>.</li>
|
||||
</font></ul>
|
||||
|
||||
The build script is invoked as: <code>Build_FusionX.sh -f nand -p ssd202 -o 2D06 -m 256</code> and produces a full flash image ready for programming to the SOM NAND.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
A key aspect of the Linux configuration is CPU isolation. At startup all Linux processes and hardware IRQs are migrated to CPU0. CPU1 is then dedicated exclusively to the <code>kthread_z80</code> kernel thread which runs the Z80 emulation loop. This CPU affinity separation, combined with the PREEMPT_RT kernel, gives the Z80 emulator the most consistent and lowest-latency access to the host hardware interface. The CPU performance governor is also set to maximum frequency (1.2GHz) after the Z80 emulator is running to avoid frequency scaling causing timing variation in the emulation loop.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The root filesystem is a Buildroot-based minimal Linux environment stored in the SOM NAND flash. An optional SD card can extend storage for Sharp MZ application software, ROM images and additional Linux utilities. When a suitably prepared SD card is present at boot the SOM will auto-upgrade from it, simplifying firmware updates.
|
||||
</div>
|
||||
|
||||
|
||||
###### <font style="color: yellow;" size="5">Z80 Emulator</font>
|
||||
|
||||
<font size="2">Under construction.</font>
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The Z80 emulator is implemented as a Linux kernel module, <code>z80drv.ko</code> (v1.4, April 2023). It uses the <a href="https://github.com/redcode/Z80">Zeta Z80 CPU emulator library</a> by Manuel Sainz de Baranda y Goñi as its Z80 instruction-set core, wrapped in a kernel-space driver that interfaces with the SSD202 GPIO hardware and the CPLD Z80 host interface.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The hardware path from the SOM to the Z80 host socket runs: SSD202 GPIO / SPI → CPLD → Z80 DIP-40 socket. The CPLD handles accurate Z80 bus timing using a 50MHz clock, so the kernel module does not need to reproduce precise T-state timing itself. The GPIO interface is managed by <code>z80io.c</code>, which calls the SigmaStar HAL for initialisation but accesses registers directly for bit-level read/write operations to minimise latency. The practical read throughput of the SSD202 GPIO structure is approximately 2MB/s for an 8-bit byte, which means programs execute from emulated (kernel) memory rather than from the physical host memory over the bus.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The emulator supports the following host machines, each with its own virtual hardware module:
|
||||
<table style="font-size: 0.85em; width: 100%; border-collapse: collapse; margin-top: 0.5em;">
|
||||
<thead>
|
||||
<tr style="background: #2a2a2a;">
|
||||
<th style="padding: 0.4em 0.8em; text-align: left; border: 1px solid #444;">Virtual Hardware Module</th>
|
||||
<th style="padding: 0.4em 0.8em; text-align: left; border: 1px solid #444;">Host Machine</th>
|
||||
<th style="padding: 0.4em 0.8em; text-align: left; border: 1px solid #444;">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td style="padding: 0.4em 0.8em; border: 1px solid #444;"><code>z80vhw_mz80a.c</code></td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">Sharp MZ-80A</td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">Original MZ-80A behaviour, no additions</td></tr>
|
||||
<tr><td style="padding: 0.4em 0.8em; border: 1px solid #444;"><code>z80vhw_mz700.c</code></td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">Sharp MZ-700</td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">Original MZ-700 behaviour, no additions</td></tr>
|
||||
<tr><td style="padding: 0.4em 0.8em; border: 1px solid #444;"><code>z80vhw_mz2000.c</code></td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">Sharp MZ-2000</td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">MZ-2000 emulation</td></tr>
|
||||
<tr><td style="padding: 0.4em 0.8em; border: 1px solid #444;"><code>z80vhw_pcw.c</code></td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">Amstrad PCW-8256</td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">PCW-8256 emulation</td></tr>
|
||||
<tr><td style="padding: 0.4em 0.8em; border: 1px solid #444;"><code>z80vhw_rfs.c</code></td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">MZ-80A + RFS</td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">ROM Filing System virtual hardware for MZ-80A</td></tr>
|
||||
<tr><td style="padding: 0.4em 0.8em; border: 1px solid #444;"><code>z80vhw_tzpu.c</code></td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">MZ-80A + tranZPUter SW</td><td style="padding: 0.4em 0.8em; border: 1px solid #444;">tranZPUter SW virtual hardware; combines kernel driver with userspace <code>k64fcpu</code> daemon</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The virtual hardware modules are compiled inline into <code>z80drv.ko</code> rather than linked as separate objects, which eliminates function call overhead in the emulation hot path. Up to five virtual hardware devices can be active simultaneously (<code>MAX_VIRTUAL_DEVICES 5</code>). Devices are added at runtime using <code>z80ctrl --adddev --device <name></code> before starting the emulator.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The <code>z80ctrl</code> utility provides full runtime control of the emulator from the Linux command line:
|
||||
<ul style="line-height: 1.6em;"><font size="3">
|
||||
<li><code>--adddev --device <name></code> — add a virtual hardware device (rfs, tzpu, mz700, mz80a, mz2000, pcw)</li>
|
||||
<li><code>--start</code> / <code>--stop</code> — start or stop the Z80 emulation loop</li>
|
||||
<li><code>--loadrom --file <path> --addr <hex> --type <n></code> — load a ROM binary into emulated memory</li>
|
||||
<li><code>--mem --addr <hex> --len <n></code> — inspect emulated memory contents</li>
|
||||
<li><code>--cmd <hex></code> — send a command byte directly to the CPLD/Z80 gateway</li>
|
||||
</font></ul>
|
||||
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The <code>ttymzdrv.ko</code> module (<code>ttymz.c</code>, v1.2, July 2023) provides a standard Linux TTY interface on <code>/dev/ttymz0</code> backed by the Sharp MZ keyboard and display hardware. This allows the host machine's console to be used as a Linux terminal — running a getty login session — while also supporting suspend and resume to switch the display between Linux and the Z80 emulation session without losing state. Supported hosts are MZ-80A, MZ-700 and MZ-2000.
|
||||
</div>
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
## <font style="color: yellow;" size="6">Daughter Boards</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The tranZPUter series was initially developed in the Sharp MZ-80A and was primarily a Z80 replacement. As the concept evolved and the tranZPUter SW-700 was developed for the MZ-700 it became more of an integral component of the machine, offering original and upgraded Video and Audio capabilites by intercepting and routing existing signals.
|
||||
The tranZPUter series was initially developed in the Sharp MZ-80A and was primarily a Z80 replacement. As the concept evolved and the tranZPUter SW-700 was developed for the MZ-700 it became more of an integral component of the machine, offering original and upgraded Video and Audio capabilities by intercepting and routing existing signals.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
After significant developments on the tranZPUter SW-700 it became desirable to port it back to the MZ-80A and MZ-2000 but these machines had different CPU orientation and signal requirements, ie. driving an internal and external monitor. This requirement led to the concept of daughter boards, where a specific board would be designed and developed for
|
||||
@@ -207,7 +633,7 @@ the target host and would plug into the tranZPUter SW-700 card. Ideally I wanted
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
During the design of the tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> one of the main requirements was to make the board small, the Z80 orientation changeable and also compatible with the tran<i>ZPU</i>ter<sup><i>Fusion</i></sup> so that it could fit many machines and be interchangeable. As the SW-700 also interfaced to the Video and Audio of the machines
|
||||
and each was quite different, it became apparent that the tran<i>ZPU</i>ter<sup>FusionX</sup> needed to include a concept to allow different video/audio interfaces according to the targetted host. This concept was realised via daughter boards. Two connectors would link the tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> to a daughter board which would be
|
||||
and each was quite different, it became apparent that the tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> needed to include a concept to allow different video/audio interfaces according to the targeted host. This concept was realised via daughter boards. Two connectors would link the tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> to a daughter board which would be
|
||||
specifically designed for the intended host.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
@@ -226,7 +652,7 @@ The purpose of the MZ-700 daughter board is to interface the video/audio circuit
|
||||
is switched between the MZ-700 and <i>FusionX</i> under control of the <i>FusionX</i>.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The original sound circuity of the MZ-700 drives a speaker directly and in order to inject <i>FusionX</i> audio into the MZ-700 speaker, the mainboard speaker output is routed to the daughter board, level converted and switched under control of the <i>FusionX</I>. The <i>FusionX</i> offers stereo sound so this is selectively switched/mixed with the
|
||||
The original sound circuitry of the MZ-700 drives a speaker directly and in order to inject <i>FusionX</i> audio into the MZ-700 speaker, the mainboard speaker output is routed to the daughter board, level converted and switched under control of the <i>FusionX</I>. The <i>FusionX</i> offers stereo sound so this is selectively switched/mixed with the
|
||||
original MZ-700 sound and fed to a Class D amplifier which then drives the internal speaker. Line level stereo output is achieved via an additional 4pin connector and used as required.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
@@ -241,7 +667,7 @@ This setup allows for Linux or emulated machines, whilst running as an applicati
|
||||
The MZ-700 daughter board consists of three 4way SPDT analogue switches to route video and audio signals under <i>FusionX</i> control and a Class D power amplifier.
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">MZ-700 Video Interface PCB</font>
|
||||
|
||||
@@ -251,16 +677,16 @@ The MZ-700 daughter board PCB is small and compact due to the space restrictions
|
||||
|
||||
<div style='content: ""; clear: both; display: table;'>
|
||||
<div style='width: 35%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/VideoInterface_MZ700_v1_0_3D_Top.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/VideoInterface_MZ700_v1_0_3D_Top.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
<div style='width: 39%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/VideoInterface_MZ700_v1_0_3D_Bottom.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/VideoInterface_MZ700_v1_0_3D_Bottom.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style='content: ""; clear: both; display: table;'>
|
||||
<div style='width: 80%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/FusionX_MZ700.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/FusionX_MZ700.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -284,7 +710,7 @@ The video signals from the mainboard are switched with the <i>FusionX</i> video
|
||||
The <i>FusionX</i> RGB output is routed to the MZ-2000 external RGB video socket allowing for upto full HD external colour video display.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The sound circuity of the MZ-2000 is sent to an audio amplifier on the CRT monitor. This signal is intercepted and switched with the <i>FusionX</i> audio which then drives the CRT monitor amplifier. Line level stereo output is achieved via an additional 4pin connector and used as required.
|
||||
The sound circuitry of the MZ-2000 is sent to an audio amplifier on the CRT monitor. This signal is intercepted and switched with the <i>FusionX</i> audio which then drives the CRT monitor amplifier. Line level stereo output is achieved via an additional 4pin connector and used as required.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
</div>
|
||||
@@ -295,26 +721,26 @@ The sound circuity of the MZ-2000 is sent to an audio amplifier on the CRT monit
|
||||
The MZ-2000 daughter board consists of two 4way SPDT analogue switches to route video and audio signals under <i>FusionX</i> control. One SPDT switch is used for creating pure black in the modified video signal generated on the <i>FusionX</i> board.
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">MZ-2000 Video Interface PCB</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The MZ-2000 daughter board PCB is small and compact due to the space restrictions and the number of connectors it must carry. It plugs into the mainboard monitor/IPL male connectors and then presents new CRT monitor, external Video and IPL/RESET switch connectors for all the exising internal cabling.
|
||||
The MZ-2000 daughter board PCB is small and compact due to the space restrictions and the number of connectors it must carry. It plugs into the mainboard monitor/IPL male connectors and then presents new CRT monitor, external Video and IPL/RESET switch connectors for all the existing internal cabling.
|
||||
</div>
|
||||
|
||||
<div style='content: ""; clear: both; display: table;'>
|
||||
<div style='width: 50%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/VideoInterface_MZ2000_v1_0_3D_Top.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/VideoInterface_MZ2000_v1_0_3D_Top.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
<div style='width: 50%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/VideoInterface_MZ2000_v1_0_3D_Bottom.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/VideoInterface_MZ2000_v1_0_3D_Bottom.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style='content: ""; clear: both; display: table;'>
|
||||
<div style='width: 60%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/FusionX_MZ2000.png' height='80%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/FusionX_MZ2000.png' height='80%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -323,7 +749,7 @@ The MZ-2000 daughter board PCB is small and compact due to the space restriction
|
||||
###### <font style="color: yellow;" size="5">MZ-80A Daughter Board</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The purpose of the MZ-80A daughter board is to interface the video/audio/reset circuits of the <i>FusionX</I> board with those of the MZ-80A. The MZ-80A has an internal monochrome CRT, cutouts for and external RGB video socket and internal Audio with an amplifier on the monochrome CRT control board.
|
||||
The purpose of the MZ-80A daughter board is to interface the video/audio/reset circuits of the <i>FusionX</I> board with those of the MZ-80A. The MZ-80A has an internal monochrome CRT, cutouts for an external RGB video socket and internal Audio with an amplifier on the monochrome CRT control board.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The daughter board is designed to plug into the vertical mainboard CRT video connector with a gap so that the data cassette connector can be simultaneously connected. The gap is necessary as the CRT video connector sits close to the rear sidewall so the daughter board must extend forwards towards the keyboard.
|
||||
@@ -332,7 +758,7 @@ The daughter board is designed to plug into the vertical mainboard CRT video con
|
||||
It presents all the required connectors to connect the RESET switch (both in and out), internal monitor and external monitor on the same board.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The RESET input is intercepted on the daughter board and sent to the <i>FusionX</i>. Technically it isnt needed as the <i>FusionX</i> samples the Z80 Reset which is based on this input, but it can be useful, for example, detecting requests to reboot the SOM (double press) rather than the MZ-80A circuitry.
|
||||
The RESET input is intercepted on the daughter board and sent to the <i>FusionX</i>. Technically it isn't needed as the <i>FusionX</i> samples the Z80 Reset which is based on this input, but it can be useful, for example, detecting requests to reboot the SOM (double press) rather than the MZ-80A circuitry.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The video signals from the mainboard are switched with the <i>FusionX</i> video monochrome signals and sent to the internal CRT monitor. This allows for original video output on the CRT monitor or advanced <i>FusionX</i> text and graphics, resolution subject to the timing constraints of the monitor.
|
||||
@@ -341,7 +767,7 @@ The video signals from the mainboard are switched with the <i>FusionX</i> video
|
||||
The <i>FusionX</i> RGB output is routed to the MZ-80A external RGB video socket (if installed) allowing for upto full HD external colour video display.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The sound circuity of the MZ-80A is sent to an audio amplifier on the CRT monitor. This signal is intercepted and switched with the <i>FusionX</i> audio which then drives the CRT monitor amplifier. Line level stereo output is achieved via an additional 4pin connector and used as required.
|
||||
The sound circuitry of the MZ-80A is sent to an audio amplifier on the CRT monitor. This signal is intercepted and switched with the <i>FusionX</i> audio which then drives the CRT monitor amplifier. Line level stereo output is achieved via an additional 4pin connector and used as required.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
</div>
|
||||
@@ -352,20 +778,20 @@ The sound circuity of the MZ-80A is sent to an audio amplifier on the CRT monito
|
||||
The MZ-80A daughter board consists of two 4way SPDT analogue switches to route video and audio signals under <i>FusionX</i> control. One SPDT switch is used for creating pure black in the modified video signal generated on the <i>FusionX</i> board.
|
||||
</div>
|
||||
|
||||

|
||||

|
||||
|
||||
<font style="color: cyan;" size="4">MZ-80A Video Interface PCB</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The MZ-80A daughter board PCB is small and compact with a large punchout to enable connection with the mainboard CRT connector and thru connection of the data cassette signal connector. It plugs into the mainboard CRT monitor connector and then presents new CRT monitor, external Video and RESET In/Out switch connectors to be used with all the exising internal cabling.
|
||||
The MZ-80A daughter board PCB is small and compact with a large punchout to enable connection with the mainboard CRT connector and thru connection of the data cassette signal connector. It plugs into the mainboard CRT monitor connector and then presents new CRT monitor, external Video and RESET In/Out switch connectors to be used with all the existing internal cabling.
|
||||
</div>
|
||||
|
||||
<div style='content: ""; clear: both; display: table;'>
|
||||
<div style='width: 47%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/VideoInterface_MZ80A_V1_0_3D_Top.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/VideoInterface_MZ80A_V1_0_3D_Top.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
<div style='width: 50%; padding: 5px; padding-left: 1em; float: left'>
|
||||
<img src='http://eaw.app/images/VideoInterface_MZ80A_V1_0_3D_Bottom.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
<img src='../images/VideoInterface_MZ80A_V1_0_3D_Bottom.png' height='100%' width='100%' style="margin-left: auto; margin-right: auto; display: block;"/>
|
||||
</div>
|
||||
</div>
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
@@ -384,6 +810,17 @@ The table below contains all the sites referenced in the design and programming
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
<div style="padding-left: 10%;">
|
||||
<font size="4">
|
||||
<style>
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
tr td {
|
||||
padding-top: 0em;
|
||||
}
|
||||
tr:nth-child(4) td {
|
||||
padding-top: 0;
|
||||
}
|
||||
</style>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -438,6 +875,17 @@ The table below contains all the datasheets and manuals referenced in the design
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
<div style="padding-left: 10%;">
|
||||
<font size="4">
|
||||
<style>
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
tr td {
|
||||
padding-top: 0em;
|
||||
}
|
||||
tr:nth-child(4) td {
|
||||
padding-top: 0;
|
||||
}
|
||||
</style>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -548,19 +996,43 @@ The table below contains all the datasheets and manuals referenced in the design
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
## <font style="color: yellow;" size="5">Demonstration Videos</font>
|
||||
<a name="project-preview" id="project-preview"></a>
|
||||
## <font style="color: yellow;" size="6">Project Preview</font>
|
||||
|
||||
<a href="https://t.co/ZP4T3oisrg">MZ-2000 Demo</a>
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
Development progress on the tran<i>ZPU</i>ter<sup><i>FusionX</i></sup> was shared on X (formerly Twitter) as each milestone was reached. The posts below document key stages from the first hardware bring-up through to running RFS, MZ-700 and MZ-2000 emulation:
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
<a href="https://t.co/6lJoGkNuiP">MZ-700 Demo</a>
|
||||
<a href="https://x.com/engineerswork1/status/1579209688495054849" target="_blank">https://x.com/engineerswork1/status/1579209688495054849</a><br>
|
||||
<a href="https://x.com/engineerswork1/status/1583918702415577089" target="_blank">https://x.com/engineerswork1/status/1583918702415577089</a><br>
|
||||
<a href="https://x.com/engineerswork1/status/1596925535787286528" target="_blank">https://x.com/engineerswork1/status/1596925535787286528</a><br>
|
||||
<a href="https://x.com/engineerswork1/status/1616571495957909510" target="_blank">https://x.com/engineerswork1/status/1616571495957909510</a><br>
|
||||
<a href="https://x.com/engineerswork1/status/1630985022604804109" target="_blank">https://x.com/engineerswork1/status/1630985022604804109</a>
|
||||
</div>
|
||||
|
||||
<div style="padding-top: 1.2em;"></div>
|
||||
<a name="demonstration-videos" id="demonstration-videos"></a>
|
||||
<font style="color: yellow;" size="5">Demonstration Videos</font>
|
||||
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
<font style="color: cyan;" size="4">MZ-80A Demo (includes virtual RFS Board)</font>
|
||||
|
||||
<blockquote class="twitter-tweet" data-dnt="true" data-theme="dark"><p lang="en" dir="ltr"> <a href="https://t.co/3gbEHVzS6X">pic.twitter.com/3gbEHVzS6X</a></p>— engineers@work (@engineerswork1) <a href="https://twitter.com/engineerswork1/status/1625281950897303553?ref_src=twsrc%5Etfw">February 13, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
||||
|
||||
<font style="color: cyan;" size="4">MZ-2000 Demo</font>
|
||||
|
||||
<blockquote class="twitter-tweet" data-dnt="true" data-theme="dark"><p lang="zxx" dir="ltr"><a href="https://t.co/ZP4T3oisrg">pic.twitter.com/ZP4T3oisrg</a></p>— engineers@work (@engineerswork1) <a href="https://twitter.com/engineerswork1/status/1596925985592864768?ref_src=twsrc%5Etfw">November 27, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
||||
|
||||
<font style="color: cyan;" size="4">MZ-700 Demo</font>
|
||||
|
||||
<blockquote class="twitter-tweet" data-dnt="true" data-theme="dark"><p lang="en" dir="ltr"> <a href="https://t.co/6lJoGkNuiP">pic.twitter.com/6lJoGkNuiP</a></p>— engineers@work (@engineerswork1) <a href="https://twitter.com/engineerswork1/status/1586864092601630721?ref_src=twsrc%5Etfw">October 30, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
|
||||
|
||||
--------------------------------------------------------------------------------------------------------
|
||||
|
||||
## <font style="color: yellow;" size="5">Credits</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
The Z80 Emulation used in the <i>FusionX</i> is (c) 1999-2022 Manuel Sainz de Baranda y Goñi, which is licensed under the LGPL v3 license, source can be found in <a href="https://github.com/redcode/Z80">github</a>.
|
||||
The Z80 Emulation used in the <i>FusionX</i> is (c) 1999-2022 Manuel Sainz de Baranda y Goñi, which is licensed under the LGPL v3 license, source can be found in <a href="https://github.com/redcode/Z80">Gitea</a>.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
The SSD202/SOM2D0X build system is based on Linux with extensions by SigmaStar and Industio, licensing can be found in their updated source files.
|
||||
@@ -571,7 +1043,7 @@ The SSD202/SOM2D0X build system is based on Linux with extensions by SigmaStar a
|
||||
## <font style="color: yellow;" size="5">Licenses</font>
|
||||
|
||||
<div style="text-align: justify; line-height: 1.4em; font-size: 0.8em; font-family:sans-serif;">
|
||||
This design, hardware and software (attributable components excluding seperately licensed software) is licensed under the GNU Public Licence v3 and free to use, adapt and modify by individuals, groups and educational institutes.
|
||||
This design, hardware and software (attributable components excluding separately licensed software) is licensed under the GNU Public Licence v3 and free to use, adapt and modify by individuals, groups and educational institutes.
|
||||
<div style="padding-top: 0.8em;"></div>
|
||||
|
||||
No commercial use to be made of this design or any hardware/firmware component without express permission from the author.
|
||||
|
||||
492
build.sh
Executable file
492
build.sh
Executable file
@@ -0,0 +1,492 @@
|
||||
#!/bin/bash
|
||||
#########################################################################################################
|
||||
##
|
||||
## Name: build.sh
|
||||
## Created: March 2026
|
||||
## Author(s): Philip Smart
|
||||
## Description: FusionX global build script
|
||||
## Builds all software components for the FusionX tranZPUter board:
|
||||
## - Z80 assembly ROMs (monitor, MS BASIC, CP/M, TZFS)
|
||||
## - Linux kernel modules (z80drv, ttymzdrv) for each target machine
|
||||
## - User-space applications (sharpbiter, k64fcpu, z80ctrl)
|
||||
## - SPI tools (mspi_main)
|
||||
## - CPLD bitstreams for each target machine (requires Quartus Docker)
|
||||
##
|
||||
## Credits:
|
||||
## Copyright: (c) 2019-2026 Philip Smart <philip.smart@net2net.org>
|
||||
##
|
||||
## History: March 2026 - Initial global build script.
|
||||
##
|
||||
#########################################################################################################
|
||||
## 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/>.
|
||||
#########################################################################################################
|
||||
|
||||
# Root directory of the FusionX project.
|
||||
ROOT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
|
||||
# Directories.
|
||||
SOFTDIR="${ROOT_DIR}/software"
|
||||
ASMDIR="${SOFTDIR}/asm"
|
||||
INCDIR="${ASMDIR}/include"
|
||||
TMPDIR="${SOFTDIR}/tmp"
|
||||
ROMDIR="${SOFTDIR}/roms"
|
||||
TOOLDIR="${SOFTDIR}/tools"
|
||||
CPLDDIR="${ROOT_DIR}/CPLD/v1.0"
|
||||
DRVDIR="${SOFTDIR}/FusionX/src/z80drv"
|
||||
TTYDIR="${SOFTDIR}/FusionX/src/ttymz"
|
||||
SPIDIR="${SOFTDIR}/FusionX/src/spitools"
|
||||
BINDIR="${SOFTDIR}/FusionX/bin"
|
||||
MODDIR="${SOFTDIR}/FusionX/modules"
|
||||
|
||||
# Tools.
|
||||
ASM_JAR="${TOOLDIR}/glass-0.5.1.jar"
|
||||
CROSS_PREFIX="arm-linux-gnueabihf-"
|
||||
|
||||
# Build targets.
|
||||
SOFTWARE_TARGETS="MZ80A MZ700 MZ2000"
|
||||
CPLD_TARGETS="MZ80A MZ700 MZ2000 PCW8256"
|
||||
|
||||
# Assembly build lists.
|
||||
BUILDROMLIST="mz2000_ipl_original mz2000_ipl_tzpu mz2000_ipl_fusionx mz800_1z_013b mz800_9z_504m mz800_iocs mz80afi monitor_sa1510 monitor_80c_sa1510 monitor_1z-013a monitor_80c_1z-013a monitor_1z-013a-km monitor_80c_1z-013a-km mz80b_ipl"
|
||||
BUILDMZFLIST="5z009-1b sa-5510_tzfs msbasic_mz80a msbasic_mz700 msbasic_tz40 msbasic_tz80 sharpmz-test"
|
||||
BUILDTZFSROMLIST="tzfs"
|
||||
BUILDTZFSMZFLIST="testtz"
|
||||
CPMVERSIONS="mz700_80c:0 mz80a_80c:1 mz80a_std:2"
|
||||
|
||||
# Counters for summary.
|
||||
PASS=0
|
||||
FAIL=0
|
||||
SKIP=0
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Helper functions.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
log_info() { echo "==> $*"; }
|
||||
log_ok() { echo " [OK] $*"; PASS=$((PASS + 1)); }
|
||||
log_fail() { echo " [FAIL] $*"; FAIL=$((FAIL + 1)); }
|
||||
log_skip() { echo " [SKIP] $*"; SKIP=$((SKIP + 1)); }
|
||||
|
||||
usage() {
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo ""
|
||||
echo "Build all or selected FusionX components."
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " --all Build everything (default)"
|
||||
echo " --asm Build Z80 assembly ROMs only"
|
||||
echo " --tzfs Build TZFS ROM only"
|
||||
echo " --cpm Build CP/M only"
|
||||
echo " --drivers Build kernel modules and user-space apps only"
|
||||
echo " --spi Build SPI tools only"
|
||||
echo " --cpld Build CPLD bitstreams only (requires Quartus Docker)"
|
||||
echo " --image Build Linux SD card image (requires ARM cross-compiler)"
|
||||
echo " --clean Clean all build artifacts"
|
||||
echo " --help Show this help"
|
||||
echo ""
|
||||
echo "Software targets: ${SOFTWARE_TARGETS}"
|
||||
echo "CPLD targets: ${CPLD_TARGETS}"
|
||||
exit 0
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build Z80 Assembly ROMs and MZF files.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_asm_roms() {
|
||||
log_info "Building Z80 Assembly ROMs and MZF files..."
|
||||
|
||||
if ! command -v java &>/dev/null; then
|
||||
log_skip "Java not found - cannot assemble Z80 ROMs"
|
||||
return
|
||||
fi
|
||||
if [ ! -f "${ASM_JAR}" ]; then
|
||||
log_skip "GLASS assembler not found at ${ASM_JAR}"
|
||||
return
|
||||
fi
|
||||
|
||||
mkdir -p "${TMPDIR}" "${ROMDIR}"
|
||||
|
||||
for f in ${BUILDROMLIST} ${BUILDMZFLIST}; do
|
||||
SRCNAME="${f}"
|
||||
ASMNAME="${f}.asm"
|
||||
OBJNAME="${f}.obj"
|
||||
SYMNAME="${f}.sym"
|
||||
ROMNAME="${f}.rom"
|
||||
MZFNAME="${f}.mzf"
|
||||
|
||||
# MS BASIC variant handling.
|
||||
case "${SRCNAME}" in
|
||||
msbasic_mz80a)
|
||||
ASMNAME="msbasic.asm"
|
||||
echo "BUILD_VERSION EQU 0" > "${INCDIR}/MSBASIC_BuildVersion.asm"
|
||||
;;
|
||||
msbasic_mz700)
|
||||
ASMNAME="msbasic.asm"
|
||||
echo "BUILD_VERSION EQU 1" > "${INCDIR}/MSBASIC_BuildVersion.asm"
|
||||
;;
|
||||
msbasic_tz40)
|
||||
ASMNAME="msbasic.asm"
|
||||
echo "BUILD_VERSION EQU 2" > "${INCDIR}/MSBASIC_BuildVersion.asm"
|
||||
;;
|
||||
msbasic_tz80)
|
||||
ASMNAME="msbasic.asm"
|
||||
echo "BUILD_VERSION EQU 3" > "${INCDIR}/MSBASIC_BuildVersion.asm"
|
||||
;;
|
||||
esac
|
||||
|
||||
if java -jar "${ASM_JAR}" "${ASMDIR}/${ASMNAME}" "${TMPDIR}/${OBJNAME}" "${TMPDIR}/${SYMNAME}" -I "${INCDIR}" -I "${ASMDIR}" 2>&1; then
|
||||
if echo "${BUILDROMLIST}" | grep -qw "${SRCNAME}"; then
|
||||
cp "${TMPDIR}/${OBJNAME}" "${ROMDIR}/${ROMNAME}"
|
||||
log_ok "ROM: ${ROMNAME}"
|
||||
else
|
||||
cp "${TMPDIR}/${OBJNAME}" "${ROMDIR}/${MZFNAME}"
|
||||
log_ok "MZF: ${MZFNAME}"
|
||||
fi
|
||||
else
|
||||
log_fail "${SRCNAME}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Composite MZ-800 ROM.
|
||||
if [ -f "${ROMDIR}/mz800_1z_013b.rom" ] && [ -f "${ROMDIR}/mz800_cgrom.ori" ] && \
|
||||
[ -f "${ROMDIR}/mz800_9z_504m.rom" ] && [ -f "${ROMDIR}/mz800_iocs.rom" ]; then
|
||||
cat "${ROMDIR}/mz800_1z_013b.rom" "${ROMDIR}/mz800_cgrom.ori" \
|
||||
"${ROMDIR}/mz800_9z_504m.rom" "${ROMDIR}/mz800_iocs.rom" > "${ROMDIR}/mz800_ipl.rom"
|
||||
log_ok "ROM: mz800_ipl.rom (composite)"
|
||||
fi
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build TZFS ROM for each machine+board combination.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_tzfs() {
|
||||
log_info "Building TZFS ROMs..."
|
||||
|
||||
if ! command -v java &>/dev/null; then
|
||||
log_skip "Java not found - cannot assemble TZFS"
|
||||
return
|
||||
fi
|
||||
|
||||
mkdir -p "${TMPDIR}" "${ROMDIR}"
|
||||
|
||||
local DEFSFILE="${INCDIR}/tzfs_definitions.asm"
|
||||
local MACHINES="MZ80A MZ700 MZ2000"
|
||||
|
||||
for machine in ${MACHINES}; do
|
||||
# Set machine target in definitions.
|
||||
for m in MZ80A MZ700 MZ1500 MZ2000; do
|
||||
local val=0
|
||||
[ "${m}" = "${machine}" ] && val=1
|
||||
sed -i "s/^BUILD_${m}\s\+EQU\s\+[01]/BUILD_${m} EQU ${val}/" "${DEFSFILE}"
|
||||
done
|
||||
|
||||
# Set board to FusionX.
|
||||
sed -i "s/^BUILD_FUSIONX\s\+EQU\s\+[01]/BUILD_FUSIONX EQU 1/" "${DEFSFILE}"
|
||||
sed -i "s/^BUILD_PICOZ80\s\+EQU\s\+[01]/BUILD_PICOZ80 EQU 0/" "${DEFSFILE}"
|
||||
|
||||
for f in ${BUILDTZFSROMLIST} ${BUILDTZFSMZFLIST}; do
|
||||
if java -jar "${ASM_JAR}" "${ASMDIR}/${f}.asm" "${TMPDIR}/${f}.obj" "${TMPDIR}/${f}.sym" -I "${INCDIR}" -I "${ASMDIR}" 2>&1; then
|
||||
local lower_machine=$(echo "${machine}" | tr '[:upper:]' '[:lower:]')
|
||||
if echo "${BUILDTZFSROMLIST}" | grep -qw "${f}"; then
|
||||
cp "${TMPDIR}/${f}.obj" "${ROMDIR}/${f}_${lower_machine}_fusionx.rom"
|
||||
log_ok "TZFS ROM: ${f}_${lower_machine}_fusionx.rom"
|
||||
else
|
||||
cp "${TMPDIR}/${f}.obj" "${ROMDIR}/${f}_${lower_machine}_fusionx.mzf"
|
||||
log_ok "TZFS MZF: ${f}_${lower_machine}_fusionx.mzf"
|
||||
fi
|
||||
else
|
||||
log_fail "TZFS: ${f} (${machine})"
|
||||
fi
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build CP/M for each version.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_cpm() {
|
||||
log_info "Building CP/M variants..."
|
||||
|
||||
if ! command -v java &>/dev/null; then
|
||||
log_skip "Java not found - cannot assemble CP/M"
|
||||
return
|
||||
fi
|
||||
|
||||
mkdir -p "${TMPDIR}" "${ROMDIR}"
|
||||
|
||||
for ver in ${CPMVERSIONS}; do
|
||||
local FILEEXT=$(echo "${ver}" | cut -d: -f1)
|
||||
local BUILDVER=$(echo "${ver}" | cut -d: -f2)
|
||||
echo "BUILD_VERSION EQU ${BUILDVER}" > "${INCDIR}/cpm_buildversion.asm"
|
||||
|
||||
local all_ok=true
|
||||
for f in cbios cpm22; do
|
||||
if java -jar "${ASM_JAR}" "${ASMDIR}/${f}.asm" "${TMPDIR}/${f}.obj" "${TMPDIR}/${f}.sym" -I "${INCDIR}" -I "${ASMDIR}" 2>&1; then
|
||||
cp "${TMPDIR}/${f}.obj" "${ROMDIR}/${f}.bin"
|
||||
else
|
||||
log_fail "CP/M: ${f} (${FILEEXT})"
|
||||
all_ok=false
|
||||
fi
|
||||
done
|
||||
|
||||
if ${all_ok}; then
|
||||
cat "${ROMDIR}/cpm22.bin" "${ROMDIR}/cbios.bin" > "${ROMDIR}/cpm223_${FILEEXT}.bin"
|
||||
log_ok "CP/M: cpm223_${FILEEXT}.bin"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build kernel modules and user-space applications for each target machine.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_drivers() {
|
||||
log_info "Building kernel modules and user-space applications..."
|
||||
|
||||
if ! command -v ${CROSS_PREFIX}gcc &>/dev/null; then
|
||||
log_skip "ARM cross-compiler (${CROSS_PREFIX}gcc) not found"
|
||||
return
|
||||
fi
|
||||
|
||||
local KERNEL_DIR="${SOFTDIR}/linux/kernel"
|
||||
if [ ! -f "${KERNEL_DIR}/Makefile" ]; then
|
||||
log_skip "Kernel source tree not found at ${KERNEL_DIR}"
|
||||
return
|
||||
fi
|
||||
|
||||
for target in ${SOFTWARE_TARGETS}; do
|
||||
log_info " Target: ${target}"
|
||||
|
||||
# Build z80drv kernel module + user-space tools.
|
||||
# Must cd into directory because Makefile uses $(PWD) for kernel path.
|
||||
if [ -f "${DRVDIR}/Makefile" ]; then
|
||||
if (cd "${DRVDIR}" && make "${target}" 2>&1); then
|
||||
(cd "${DRVDIR}" && make install 2>&1) || true
|
||||
log_ok "z80drv + apps (${target})"
|
||||
else
|
||||
log_fail "z80drv (${target})"
|
||||
fi
|
||||
(cd "${DRVDIR}" && make clean 2>&1) || true
|
||||
fi
|
||||
|
||||
# Build ttymzdrv kernel module.
|
||||
if [ -f "${TTYDIR}/Makefile" ]; then
|
||||
if (cd "${TTYDIR}" && make "${target}" 2>&1); then
|
||||
(cd "${TTYDIR}" && make install 2>&1) || true
|
||||
log_ok "ttymzdrv (${target})"
|
||||
else
|
||||
log_fail "ttymzdrv (${target})"
|
||||
fi
|
||||
(cd "${TTYDIR}" && make clean 2>&1) || true
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build SPI tools.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_spi() {
|
||||
log_info "Building SPI tools..."
|
||||
|
||||
if ! command -v ${CROSS_PREFIX}gcc &>/dev/null; then
|
||||
log_skip "ARM cross-compiler (${CROSS_PREFIX}gcc) not found"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -f "${SPIDIR}/Makefile" ]; then
|
||||
if (cd "${SPIDIR}" && make all 2>&1); then
|
||||
log_ok "SPI tools (mspi_main)"
|
||||
else
|
||||
log_fail "SPI tools"
|
||||
fi
|
||||
else
|
||||
log_skip "SPI tools Makefile not found"
|
||||
fi
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build CPLD bitstreams for each target machine.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_cpld() {
|
||||
log_info "Building CPLD bitstreams..."
|
||||
|
||||
if ! command -v quartus_sh &>/dev/null; then
|
||||
log_skip "Quartus not found in PATH (use Quartus Docker: qp130)"
|
||||
return
|
||||
fi
|
||||
|
||||
for target in ${CPLD_TARGETS}; do
|
||||
local BUILDDIR="${CPLDDIR}/${target}/build"
|
||||
local PROJECT="tzpuFusionX_${target}"
|
||||
|
||||
if [ ! -f "${BUILDDIR}/${PROJECT}.qpf" ]; then
|
||||
log_skip "CPLD: No Quartus project for ${target}"
|
||||
continue
|
||||
fi
|
||||
|
||||
log_info " Compiling CPLD: ${target}"
|
||||
if (cd "${BUILDDIR}" && quartus_sh --flow compile "${PROJECT}" 2>&1); then
|
||||
if [ -f "${BUILDDIR}/output_files/${PROJECT}.pof" ]; then
|
||||
log_ok "CPLD: ${PROJECT}.pof"
|
||||
else
|
||||
log_fail "CPLD: ${target} (no .pof output)"
|
||||
fi
|
||||
else
|
||||
log_fail "CPLD: ${target}"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Build Linux SD card image using Build_FusionX.sh.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
build_image() {
|
||||
log_info "Building Linux SD card image..."
|
||||
|
||||
local BUILD_SCRIPT="${SOFTDIR}/linux/Build_FusionX.sh"
|
||||
local IMAGE_OUTPUT="${SOFTDIR}/linux/project/image/output/images"
|
||||
|
||||
if [ ! -f "${BUILD_SCRIPT}" ]; then
|
||||
log_skip "Build_FusionX.sh not found at ${BUILD_SCRIPT}"
|
||||
return
|
||||
fi
|
||||
|
||||
if ! command -v ${CROSS_PREFIX}gcc &>/dev/null; then
|
||||
log_skip "ARM cross-compiler (${CROSS_PREFIX}gcc) not found - cannot build Linux image"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ ! -d "${SOFTDIR}/linux/kernel" ] || [ ! -d "${SOFTDIR}/linux/boot" ]; then
|
||||
log_skip "Linux kernel/boot source tree not found"
|
||||
return
|
||||
fi
|
||||
|
||||
chmod +x "${BUILD_SCRIPT}"
|
||||
log_info " Running Build_FusionX.sh -f nand -p ssd202 -o 2D06 ..."
|
||||
if "${BUILD_SCRIPT}" -f nand -p ssd202 -o 2D06 2>&1; then
|
||||
# Check for output images.
|
||||
local has_output=false
|
||||
if [ -f "${IMAGE_OUTPUT}/sdrootfs.tar.gz" ]; then
|
||||
log_ok "Image: sdrootfs.tar.gz"
|
||||
has_output=true
|
||||
fi
|
||||
if [ -f "${IMAGE_OUTPUT}/SigmastarUpgradeSD.bin" ]; then
|
||||
log_ok "Image: SigmastarUpgradeSD.bin"
|
||||
has_output=true
|
||||
fi
|
||||
if [ -f "${IMAGE_OUTPUT}/SigmastarUpgrade.bin" ]; then
|
||||
log_ok "Image: SigmastarUpgrade.bin"
|
||||
has_output=true
|
||||
fi
|
||||
if ! ${has_output}; then
|
||||
log_fail "Linux image build produced no output files"
|
||||
fi
|
||||
else
|
||||
log_fail "Linux image build (Build_FusionX.sh)"
|
||||
fi
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Clean all build artifacts.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
do_clean() {
|
||||
log_info "Cleaning build artifacts..."
|
||||
|
||||
# Assembly temporaries.
|
||||
rm -f "${TMPDIR}"/*.obj "${TMPDIR}"/*.sym 2>/dev/null
|
||||
|
||||
# Driver build artifacts.
|
||||
if [ -f "${DRVDIR}/Makefile" ]; then
|
||||
(cd "${DRVDIR}" && make clean 2>/dev/null) || true
|
||||
fi
|
||||
if [ -f "${TTYDIR}/Makefile" ]; then
|
||||
(cd "${TTYDIR}" && make clean 2>/dev/null) || true
|
||||
fi
|
||||
if [ -f "${SPIDIR}/Makefile" ]; then
|
||||
(cd "${SPIDIR}" && make clean 2>/dev/null) || true
|
||||
fi
|
||||
|
||||
log_ok "Clean complete"
|
||||
}
|
||||
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
# Main.
|
||||
#-------------------------------------------------------------------------------------------------------
|
||||
|
||||
BUILD_ASM=false
|
||||
BUILD_TZFS=false
|
||||
BUILD_CPM=false
|
||||
BUILD_DRIVERS=false
|
||||
BUILD_SPI=false
|
||||
BUILD_CPLD=false
|
||||
BUILD_IMAGE=false
|
||||
BUILD_ALL=false
|
||||
DO_CLEAN=false
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
BUILD_ALL=true
|
||||
fi
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--all) BUILD_ALL=true ;;
|
||||
--asm) BUILD_ASM=true ;;
|
||||
--tzfs) BUILD_TZFS=true ;;
|
||||
--cpm) BUILD_CPM=true ;;
|
||||
--drivers) BUILD_DRIVERS=true ;;
|
||||
--spi) BUILD_SPI=true ;;
|
||||
--cpld) BUILD_CPLD=true ;;
|
||||
--image) BUILD_IMAGE=true ;;
|
||||
--clean) DO_CLEAN=true ;;
|
||||
--help|-h) usage ;;
|
||||
*) echo "Unknown option: $1"; usage ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
echo "========================================"
|
||||
echo " FusionX Build System"
|
||||
echo "========================================"
|
||||
echo ""
|
||||
|
||||
if ${DO_CLEAN}; then
|
||||
do_clean
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ${BUILD_ALL} || ${BUILD_ASM}; then build_asm_roms; fi
|
||||
if ${BUILD_ALL} || ${BUILD_TZFS}; then build_tzfs; fi
|
||||
if ${BUILD_ALL} || ${BUILD_CPM}; then build_cpm; fi
|
||||
if ${BUILD_ALL} || ${BUILD_DRIVERS}; then build_drivers; fi
|
||||
if ${BUILD_ALL} || ${BUILD_SPI}; then build_spi; fi
|
||||
if ${BUILD_ALL} || ${BUILD_CPLD}; then build_cpld; fi
|
||||
if ${BUILD_ALL} || ${BUILD_IMAGE}; then build_image; fi
|
||||
|
||||
echo ""
|
||||
echo "========================================"
|
||||
echo " Build Summary"
|
||||
echo " Passed: ${PASS} Failed: ${FAIL} Skipped: ${SKIP}"
|
||||
echo "========================================"
|
||||
|
||||
if [ ${FAIL} -gt 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
exit 0
|
||||
BIN
software/FusionX/bin/k64fcpu
vendored
Executable file
BIN
software/FusionX/bin/k64fcpu
vendored
Executable file
Binary file not shown.
BIN
software/FusionX/bin/sharpbiter
vendored
Executable file
BIN
software/FusionX/bin/sharpbiter
vendored
Executable file
Binary file not shown.
BIN
software/FusionX/bin/z80ctrl
vendored
BIN
software/FusionX/bin/z80ctrl
vendored
Binary file not shown.
54
software/FusionX/etc/startZ80_RFS.sh
Executable file
54
software/FusionX/etc/startZ80_RFS.sh
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
|
||||
FUSIONXDIR=/apps/FusionX
|
||||
|
||||
# Setup screen width, used to load correct RFS ROM images.
|
||||
SCREENWIDTH=40
|
||||
if [[ "$#" -ne 0 ]]; then
|
||||
if [[ "$1" -eq 80 ]]; then
|
||||
SCREENWIDTH=80
|
||||
fi
|
||||
fi
|
||||
echo "Screen width set to: ${SCREENWIDTH}"
|
||||
|
||||
# Detach CPU 1 from scheduler and IRQ's as it will be dedicated to the z80drv.
|
||||
for f in `ps -eaf |grep -v kthread_z80 | awk '{print $1}'`
|
||||
do
|
||||
taskset -pc 0 $f >/dev/null 2>/dev/null
|
||||
done
|
||||
|
||||
# Detach IRQ's
|
||||
for I in $(ls /proc/irq)
|
||||
do
|
||||
if [[ -d "/proc/irq/$I" ]]
|
||||
then
|
||||
echo 0 > /proc/irq/$I/smp_affinity_list 2>/dev/null
|
||||
fi
|
||||
done
|
||||
|
||||
# Load the Z80 driver. Small pause to ensure the driver is fully loaded and initialsed prior to loading ROM images.
|
||||
cd ${FUSIONXDIR}/modules
|
||||
rmmod z80drv 2>/dev/null
|
||||
insmod z80drv.ko
|
||||
sleep 1
|
||||
|
||||
# Add the RFS Virtual Hardware to the driver.
|
||||
${FUSIONXDIR}/bin/z80ctrl --adddev --device rfs
|
||||
|
||||
# Load the original RFS ROM images. These are loaded by the RFS driver but here for reference or to load alternate. If
|
||||
# alternate roms are loaded then ensure they are loaded prior to the start command below.
|
||||
#${FUSIONXDIR}/bin/z80ctrl --loadrom --file ${FUSIONXDIR}/rom/MROM_256_${SCREENWIDTH}c.bin --addr 0x000000 --type 1
|
||||
#${FUSIONXDIR}/bin/z80ctrl --loadrom --file ${FUSIONXDIR}/rom/USER_ROM_256_${SCREENWIDTH}c.bin --addr 0x80000 --type 1
|
||||
#${FUSIONXDIR}/bin/z80ctrl --loadrom --file ${FUSIONXDIR}/rom/USER_ROM_II_256_${SCREENWIDTH}c.bin --addr 0x100000 --type 1
|
||||
#${FUSIONXDIR}/bin/z80ctrl --loadrom --file ${FUSIONXDIR}/rom/USER_ROM_III_256_${SCREENWIDTH}c.bin --addr 0x180000 --type 1
|
||||
|
||||
# Start the Z80 (ie. MZ-80A virtual processor).
|
||||
${FUSIONXDIR/bin/z80ctrl --start
|
||||
|
||||
# Ensure the system is set for performance mode with max frequency.
|
||||
# NB: Enabling this prior to starting the Z80 results in a kernel error.
|
||||
echo performance > /sys/devices//system/cpu/cpufreq/policy0/scaling_governor
|
||||
echo 1200000 > /sys/devices//system/cpu/cpufreq/policy0/scaling_min_freq
|
||||
|
||||
# Done.
|
||||
echo "FusionX loaded and configured in RFS mode."
|
||||
54
software/FusionX/etc/startZ80_TZFS.sh
Executable file
54
software/FusionX/etc/startZ80_TZFS.sh
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/bin/sh
|
||||
|
||||
FUSIONXDIR=/apps/FusionX
|
||||
|
||||
# Setup screen width, used to load correct Monitor ROM image.
|
||||
SCREENWIDTH=40
|
||||
if [[ "$#" -ne 0 ]]; then
|
||||
if [[ "$1" -eq 80 ]]; then
|
||||
SCREENWIDTH=80
|
||||
fi
|
||||
fi
|
||||
echo "Screen width set to: ${SCREENWIDTH}"
|
||||
|
||||
# Detach CPU 1 from scheduler and IRQ's as it will be dedicated to the z80drv.
|
||||
for f in `ps -eaf |grep -v kthread_z80 | awk '{print $1}'`
|
||||
do
|
||||
taskset -pc 0 $f >/dev/null 2>/dev/null
|
||||
done
|
||||
|
||||
# Detach IRQ's
|
||||
for I in $(ls /proc/irq)
|
||||
do
|
||||
if [[ -d "/proc/irq/$I" ]]
|
||||
then
|
||||
echo 0 > /proc/irq/$I/smp_affinity_list 2>/dev/null
|
||||
fi
|
||||
done
|
||||
|
||||
# Load the Z80 driver. Small pause to ensure the driver is fully loaded and initialsed prior to loading ROM images.
|
||||
cd ${FUSIONXDIR}/modules
|
||||
rmmod z80drv 2>/dev/null
|
||||
insmod z80drv.ko
|
||||
sleep 1
|
||||
|
||||
# Add the TZPU Virtual Hardware to the driver.
|
||||
${FUSIONXDIR}/bin/z80ctrl --adddev --device tzpu
|
||||
|
||||
# Start the K64F Virtual CPU Emulation.
|
||||
${FUSIONXDIR}/bin/k64fcpu &
|
||||
|
||||
# Load the original Monitor and TZFS ROM images. This is done in the K64F daemon but can be manually enabled.
|
||||
#${FUSIONXDIR}/bin/z80ctrl --loadrom --file ${FUSIONXDIR}/roms/monitor_${SCREENWIDTH}c_sa1510.rom --addr 0x000000 --type 1
|
||||
#${FUSIONXDIR}/bin/z80ctrl --loadrom --file ${FUSIONXDIR}/roms/tzfs.rom --offset 0x000000 --len 0x001800 --addr 0x00E800 --type 1
|
||||
#${FUSIONXDIR}/bin/z80ctrl --loadrom --file ${FUSIONXDIR}/roms/tzfs.rom --offset 0x001800 --len 0x001000 --addr 0x01F000 --type 1
|
||||
#${FUSIONXDIR}/bin/z80ctrl --loadrom --file ${FUSIONXDIR}/roms/tzfs.rom --offset 0x002800 --len 0x001000 --addr 0x02F000 --type 1
|
||||
#${FUSIONXDIR}/bin/z80ctrl --loadrom --file ${FUSIONXDIR}/roms/tzfs.rom --offset 0x003800 --len 0x001000 --addr 0x03F000 --type 1
|
||||
|
||||
# Ensure the system is set for performance mode with max frequency.
|
||||
# NB: Enabling this prior to starting the Z80 results in a kernel error.
|
||||
echo performance > /sys/devices//system/cpu/cpufreq/policy0/scaling_governor
|
||||
echo 1200000 > /sys/devices//system/cpu/cpufreq/policy0/scaling_min_freq
|
||||
|
||||
# Done.
|
||||
echo "FusionX loaded and configured in TZFS mode."
|
||||
@@ -1,8 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
cd /customer
|
||||
./cpuset.sh
|
||||
FUSIONXDIR=/apps/FusionX
|
||||
|
||||
cd ${FUSIONXDIR}/modules
|
||||
${FUSIONXDIR/etc/cpuset.sh
|
||||
rmmod z80drv 2>/dev/null
|
||||
insmod z80drv.ko
|
||||
#echo performance > /sys/devices//system/cpu/cpufreq/policy0/scaling_governor
|
||||
#drvid=`ps -eaf | grep kthread_z80 | grep -v grep | awk '{print $1}'`
|
||||
#taskset -pc 1 $drvid
|
||||
|
||||
BIN
software/FusionX/modules/ttymzdrv.ko
vendored
Normal file
BIN
software/FusionX/modules/ttymzdrv.ko
vendored
Normal file
Binary file not shown.
BIN
software/FusionX/modules/z80drv.ko
vendored
BIN
software/FusionX/modules/z80drv.ko
vendored
Binary file not shown.
@@ -1,794 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: z80ctrl.c
|
||||
// Created: Oct 2022
|
||||
// Author(s): Philip Smart
|
||||
// Description: Z80 Control Interface
|
||||
// This file contains a command line utility tool for controlling the z80drv device
|
||||
// driver. The tool allows manipulation of the emulated Z80, inspection of its
|
||||
// memory and data, transmission of adhoc commands to the underlying CPLD-Z80
|
||||
// gateway and loading/saving of programs and data to/from the Z80 virtual and
|
||||
// host memory.
|
||||
//
|
||||
// Credits: Zilog Z80 CPU Emulator v0.2 written by Manuel Sainz de Baranda y Goñi
|
||||
// The Z80 CPU Emulator is the heart of the Z80 device driver.
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
// (c) 1999-2022 Manuel Sainz de Baranda y Goñi
|
||||
//
|
||||
// History: Oct 2022 - Initial write of the z80 kernel driver software.
|
||||
//
|
||||
// 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/select.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <Z/constants/pointer.h>
|
||||
#include <Z/macros/member.h>
|
||||
#include <Z/macros/array.h>
|
||||
#include <Z80.h>
|
||||
#include "z80driver.h"
|
||||
|
||||
#define VERSION "1.0"
|
||||
#define AUTHOR "P.D.Smart"
|
||||
#define COPYRIGHT "(c) 2018-22"
|
||||
|
||||
// Getopt_long is buggy so we use optparse.
|
||||
#define OPTPARSE_IMPLEMENTATION
|
||||
#define OPTPARSE_API static
|
||||
#include "optparse.h"
|
||||
|
||||
// Device driver name.
|
||||
#define DEVICE_FILENAME "/dev/z80drv"
|
||||
|
||||
// Constants for the Sharp MZ80A MZF file format.
|
||||
#define MZF_HEADER_SIZE 128 // Size of the MZF header.
|
||||
#define MZF_ATTRIBUTE 0x00 // Code Type, 01 = Machine Code.
|
||||
#define MZF_FILENAME 0x01 // Title/Name (17 bytes).
|
||||
#define MZF_FILENAME_LEN 17 // Length of the filename, it is not NULL terminated, generally a CR can be taken as terminator but not guaranteed.
|
||||
#define MZF_FILESIZE 0x12 // Size of program.
|
||||
#define MZF_LOADADDR 0x14 // Load address of program.
|
||||
#define MZF_EXECADDR 0x16 // Exec address of program.
|
||||
#define MZF_COMMENT 0x18 // Comment, used for details of the file or startup code.
|
||||
#define MZF_COMMENT_LEN 104 // Length of the comment field.
|
||||
#define CMT_TYPE_OBJCD 0x001 // MZF contains a binary object.
|
||||
#define CMT_TYPE_BTX1CD 0x002 // MZF contains a BASIC program.
|
||||
#define CMT_TYPE_BTX2CD 0x005 // MZF contains a BASIC program.
|
||||
#define CMT_TYPE_TZOBJCD0 0x0F8 // MZF contains a TZFS binary object for page 0.
|
||||
#define CMT_TYPE_TZOBJCD1 0x0F9
|
||||
#define CMT_TYPE_TZOBJCD2 0x0FA
|
||||
#define CMT_TYPE_TZOBJCD3 0x0FB
|
||||
#define CMT_TYPE_TZOBJCD4 0x0FC
|
||||
#define CMT_TYPE_TZOBJCD5 0x0FD
|
||||
#define CMT_TYPE_TZOBJCD6 0x0FE
|
||||
#define CMT_TYPE_TZOBJCD7 0x0FF // MZF contains a TZFS binary object for page 7.
|
||||
#define MZ_CMT_ADDR 0x10F0
|
||||
|
||||
// Structure to define a Sharp MZ80A MZF directory structure. This header appears at the beginning of every Sharp MZ80A tape (and more recently archived/emulator) images.
|
||||
//
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
uint8_t attr; // MZF attribute describing the file.
|
||||
uint8_t fileName[MZF_FILENAME_LEN]; // Each directory entry is the size of an MZF filename.
|
||||
uint16_t fileSize; // Size of file.
|
||||
uint16_t loadAddr; // Load address for the file.
|
||||
uint16_t execAddr; // Execution address where the Z80 starts processing.
|
||||
uint8_t comment[MZF_COMMENT_LEN]; // Text comment field but often contains a startup machine code program.
|
||||
} t_svcDirEnt;
|
||||
|
||||
// Possible commands to be issued to the Z80 driver.
|
||||
enum CTRL_COMMANDS {
|
||||
Z80_CMD_STOP = 0,
|
||||
Z80_CMD_START = 1,
|
||||
Z80_CMD_PAUSE = 2,
|
||||
Z80_CMD_CONTINUE = 3,
|
||||
Z80_CMD_RESET = 4,
|
||||
Z80_CMD_SPEED = 5,
|
||||
Z80_CMD_HOST_RAM = 6,
|
||||
Z80_CMD_VIRTUAL_RAM = 7,
|
||||
Z80_CMD_DUMP_MEMORY = 8,
|
||||
Z80_CMD_MEMORY_TEST = 9,
|
||||
CPLD_CMD_SEND_CMD = 10,
|
||||
CPLD_CMD_SPI_TEST = 11,
|
||||
CPLD_CMD_PRL_TEST = 12
|
||||
};
|
||||
|
||||
|
||||
// Shared memory between this process and the Z80 driver.
|
||||
static t_Z80Ctrl *Z80Ctrl = NULL;
|
||||
|
||||
// Method to obtain and return the output screen width.
|
||||
//
|
||||
uint8_t getScreenWidth(void)
|
||||
{
|
||||
return(MAX_SCREEN_WIDTH);
|
||||
}
|
||||
|
||||
struct termios orig_termios;
|
||||
|
||||
void reset_terminal_mode()
|
||||
{
|
||||
tcsetattr(0, TCSANOW, &orig_termios);
|
||||
}
|
||||
|
||||
void set_conio_terminal_mode()
|
||||
{
|
||||
struct termios new_termios;
|
||||
|
||||
/* take two copies - one for now, one for later */
|
||||
tcgetattr(0, &orig_termios);
|
||||
memcpy(&new_termios, &orig_termios, sizeof(new_termios));
|
||||
|
||||
/* register cleanup handler, and set the new terminal mode */
|
||||
atexit(reset_terminal_mode);
|
||||
cfmakeraw(&new_termios);
|
||||
tcsetattr(0, TCSANOW, &new_termios);
|
||||
}
|
||||
|
||||
int kbhit()
|
||||
{
|
||||
struct timeval tv = { 0L, 0L };
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(0, &fds);
|
||||
return select(1, &fds, NULL, NULL, &tv) > 0;
|
||||
}
|
||||
|
||||
int getch(uint8_t wait)
|
||||
{
|
||||
int r;
|
||||
unsigned char c;
|
||||
|
||||
if(wait != 0 || (wait == 0 && kbhit()))
|
||||
{
|
||||
if ((r = read(0, &c, sizeof(c))) < 0) {
|
||||
return r;
|
||||
} else {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void delay(int number_of_seconds)
|
||||
{
|
||||
// Converting time into milli_seconds
|
||||
int milli_seconds = 1000 * number_of_seconds;
|
||||
|
||||
// Storing start time
|
||||
clock_t start_time = clock();
|
||||
|
||||
// looping till required time is not achieved
|
||||
while (clock() < start_time + milli_seconds);
|
||||
}
|
||||
|
||||
// Function to dump out a given section of memory via the UART.
|
||||
//
|
||||
int memoryDump(uint32_t memaddr, uint32_t memsize, uint8_t memoryFlag, uint32_t memwidth, uint32_t dispaddr, uint8_t dispwidth)
|
||||
{
|
||||
uint8_t displayWidth = dispwidth;;
|
||||
uint32_t pnt = memaddr;
|
||||
uint32_t endAddr = memaddr + memsize;
|
||||
uint32_t addr = dispaddr;
|
||||
uint32_t i = 0;
|
||||
//uint32_t data;
|
||||
int8_t keyIn;
|
||||
int result = -1;
|
||||
char c = 0;
|
||||
|
||||
// Sanity check. memoryFlag == 0 required kernel driver to dump so we exit as it cannot be performed here.
|
||||
if(memoryFlag == 0)
|
||||
return(-1);
|
||||
|
||||
// Reconfigure terminal to allow non-blocking key input.
|
||||
//
|
||||
set_conio_terminal_mode();
|
||||
|
||||
// If not set, calculate output line width according to connected display width.
|
||||
//
|
||||
if(displayWidth == 0)
|
||||
{
|
||||
switch(getScreenWidth())
|
||||
{
|
||||
case 40:
|
||||
displayWidth = 8;
|
||||
break;
|
||||
case 80:
|
||||
displayWidth = 16;
|
||||
break;
|
||||
default:
|
||||
displayWidth = 32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
printf("%08lX", addr); // print address
|
||||
printf(": ");
|
||||
|
||||
// print hexadecimal data
|
||||
for (i=0; i < displayWidth; )
|
||||
{
|
||||
switch(memwidth)
|
||||
{
|
||||
case 16:
|
||||
if(pnt+i < endAddr)
|
||||
printf("%04X", memoryFlag == 1 ? (uint16_t)Z80Ctrl->memory[pnt+i] : memoryFlag == 2 ? (uint16_t)Z80Ctrl->page[pnt+i] : (uint16_t)Z80Ctrl->iopage[pnt+i]);
|
||||
else
|
||||
printf(" ");
|
||||
i++;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
if(pnt+i < endAddr)
|
||||
printf("%08lX", memoryFlag == 1 ? (uint32_t)Z80Ctrl->memory[pnt+i] : memoryFlag == 2 ? (uint32_t)Z80Ctrl->page[pnt+i] : (uint32_t)Z80Ctrl->iopage[pnt+i]);
|
||||
else
|
||||
printf(" ");
|
||||
i++;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
default:
|
||||
if(pnt+i < endAddr)
|
||||
printf("%02X", memoryFlag == 1 ? (uint8_t)Z80Ctrl->memory[pnt+i] : memoryFlag == 2 ? (uint8_t)Z80Ctrl->page[pnt+i] : (uint8_t)Z80Ctrl->iopage[pnt+i]);
|
||||
else
|
||||
printf(" ");
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
fputc((char)' ', stdout);
|
||||
}
|
||||
|
||||
// print ascii data
|
||||
printf(" |");
|
||||
|
||||
// print single ascii char
|
||||
for (i=0; i < displayWidth; i++)
|
||||
{
|
||||
c = memoryFlag == 1 ? (char)Z80Ctrl->memory[pnt+i] : memoryFlag == 2 ? (char)Z80Ctrl->page[pnt+i] : (char)Z80Ctrl->iopage[pnt+i];
|
||||
if ((pnt+i < endAddr) && (c >= ' ') && (c <= '~'))
|
||||
fputc((char)c, stdout);
|
||||
else
|
||||
fputc((char)' ', stdout);
|
||||
}
|
||||
|
||||
printf("|\r\n");
|
||||
fflush(stdout);
|
||||
|
||||
// Move on one row.
|
||||
pnt += displayWidth;
|
||||
addr += displayWidth;
|
||||
|
||||
// User abort (ESC), pause (Space) or all done?
|
||||
//
|
||||
keyIn = getch(0);
|
||||
if(keyIn == ' ')
|
||||
{
|
||||
do {
|
||||
keyIn = getch(0);
|
||||
} while(keyIn != ' ' && keyIn != 0x1b);
|
||||
}
|
||||
// Escape key pressed, exit with 0 to indicate this to caller.
|
||||
if (keyIn == 0x1b)
|
||||
{
|
||||
sleep(1);
|
||||
result = 0;
|
||||
goto memoryDumpExit;
|
||||
}
|
||||
|
||||
// End of buffer, exit the loop.
|
||||
if(pnt >= (memaddr + memsize))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Normal exit, return -1 to show no key pressed.
|
||||
memoryDumpExit:
|
||||
reset_terminal_mode();
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Method to load a program or data file into the Z80 memory. First load into Virtual memory and then trigger a sync to bring Host RAM in line.
|
||||
//
|
||||
int z80load(int fdZ80, char *fileName)
|
||||
{
|
||||
// Locals.
|
||||
struct ioctlCmd ioctlCmd;
|
||||
int ret = 0;
|
||||
t_svcDirEnt mzfHeader;
|
||||
|
||||
// Pause the Z80.
|
||||
//
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_PAUSE;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
// Open the file and read directly into the Virtual memory via the share.
|
||||
FILE *ptr;
|
||||
ptr = fopen(fileName, "rb");
|
||||
if(ptr)
|
||||
{
|
||||
// First the header.
|
||||
fread((uint8_t *)&mzfHeader, MZF_HEADER_SIZE, 1, ptr);
|
||||
|
||||
#if(TARGET_HOST_MZ700 == 1)
|
||||
if(mzfHeader.loadAddr > 0x1000)
|
||||
{
|
||||
#endif
|
||||
// Copy in the header.
|
||||
memcpy((uint8_t *)&Z80Ctrl->memory[MZ_CMT_ADDR], (uint8_t *)&mzfHeader, MZF_HEADER_SIZE);
|
||||
|
||||
// Now read in the data.
|
||||
fread(&Z80Ctrl->memory[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)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Sync the loaded image from Virtual memory to hard memory.
|
||||
ioctlCmd.cmd = IOCTL_CMD_SYNC_TO_HOST_RAM;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
// Set PC to 2 (NST) which switches to RUN mode and executes at 0000H
|
||||
ioctlCmd.z80.pc = 2;
|
||||
#endif
|
||||
#if(TARGET_HOST_MZ700 == 1)
|
||||
// MZ-700 just use the MZF header exec address.
|
||||
ioctlCmd.z80.pc = mzfHeader.execAddr;
|
||||
#endif
|
||||
|
||||
// Set PC to required setting ready for run.
|
||||
ioctlCmd.cmd = IOCTL_CMD_SETPC;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
// Resume Z80 processing.
|
||||
//
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_CONTINUE;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
}
|
||||
else
|
||||
printf("Couldnt open file\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Method to request basic Z80 operations.
|
||||
//
|
||||
int ctrlCmd(int fdZ80, enum CTRL_COMMANDS cmd, long param1, long param2, long param3)
|
||||
{
|
||||
// Locals.
|
||||
struct ioctlCmd ioctlCmd;
|
||||
uint32_t idx;
|
||||
int ret = 0;
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
case Z80_CMD_STOP:
|
||||
// Use IOCTL to request Z80 to Stop (power off) processing.
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_STOP;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_START:
|
||||
// Use IOCTL to request Z80 to Start (power on) processing.
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_START;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_PAUSE:
|
||||
// Use IOCTL to request Z80 to pause processing.
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_PAUSE;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_CONTINUE:
|
||||
// Use IOCTL to request Z80 continue processing.
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_CONTINUE;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_RESET:
|
||||
// Use IOCTL to request Z80 reset.
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_RESET;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_SPEED:
|
||||
// Check value is in range.
|
||||
for(idx=1; idx < 256; idx+=idx)
|
||||
{
|
||||
if((uint32_t)param1 == idx) break;
|
||||
}
|
||||
if(idx == 256)
|
||||
{
|
||||
printf("Speed factor is illegal. It must be a multiple value of the original CPU clock, ie. 1x, 2x, 4x etc\n");
|
||||
ret = -1;
|
||||
} else
|
||||
{
|
||||
// Use IOCTL to request Z80 cpu freq change.
|
||||
ioctlCmd.speed.speedMultiplier = (uint32_t)param1;
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_CPU_FREQ;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
}
|
||||
break;
|
||||
case CPLD_CMD_SEND_CMD:
|
||||
// Build up the IOCTL command to request the given data is sent to the CPLD.
|
||||
ioctlCmd.cmd = IOCTL_CMD_CPLD_CMD;
|
||||
ioctlCmd.cpld.cmd = (uint32_t)param1;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_DUMP_MEMORY:
|
||||
// If virtual memory, we can dump it via the shared memory segment.
|
||||
if((uint8_t)param1)
|
||||
{
|
||||
memoryDump((uint32_t)param2, (uint32_t)param3, (uint8_t)param1, (uint8_t)param1 == 2 || (uint8_t)param1 == 3 ? 32 : 8, (uint32_t)param2, 0);
|
||||
} else
|
||||
{
|
||||
// Build an IOCTL command to get the driver to dump the memory.
|
||||
ioctlCmd.cmd = IOCTL_CMD_DUMP_MEMORY;
|
||||
ioctlCmd.addr.start = (uint32_t)param2;
|
||||
ioctlCmd.addr.end = (uint32_t)param2+(uint32_t)param3;
|
||||
ioctlCmd.addr.size = (uint32_t)param3;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
}
|
||||
break;
|
||||
case Z80_CMD_HOST_RAM:
|
||||
// Use IOCTL to request change to host RAM.
|
||||
ioctlCmd.cmd = IOCTL_CMD_USE_HOST_RAM;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_VIRTUAL_RAM:
|
||||
// Use IOCTL to request change to host RAM.
|
||||
ioctlCmd.cmd = IOCTL_CMD_USE_VIRTUAL_RAM;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_MEMORY_TEST:
|
||||
// Send command to test the SPI.
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_MEMTEST;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case CPLD_CMD_PRL_TEST:
|
||||
// Send command to test the SPI.
|
||||
ioctlCmd.cmd = IOCTL_CMD_PRL_TEST;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case CPLD_CMD_SPI_TEST:
|
||||
// Send command to test the SPI.
|
||||
ioctlCmd.cmd = IOCTL_CMD_SPI_TEST;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Command not supported!\n");
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Method to perform some simple tests on the Z80 emulator.
|
||||
//
|
||||
int z80test(int fdZ80)
|
||||
{
|
||||
// Locals.
|
||||
struct ioctlCmd ioctlCmd;
|
||||
int ret = 0;
|
||||
|
||||
// Stop the Z80.
|
||||
//
|
||||
printf("Send STOP\n");
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_STOP;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
FILE *ptr;
|
||||
ptr = fopen("/customer/mz700.rom", "rb");
|
||||
if(ptr)
|
||||
{
|
||||
fread(&Z80Ctrl->memory, 65536, 1, ptr);
|
||||
} else printf("Couldnt open file\n");
|
||||
|
||||
// Configure the Z80.
|
||||
//
|
||||
printf("Send SETPC\n");
|
||||
ioctlCmd.z80.pc = 0;
|
||||
ioctl(fdZ80, IOCTL_CMD_SETPC, &ioctlCmd);
|
||||
|
||||
memoryDump(0 , 65536, 1, 8, 0, 0);
|
||||
|
||||
// Start the Z80.
|
||||
//
|
||||
printf("Send START\n");
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_START;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
delay(10);
|
||||
|
||||
printf("Send STOP\n");
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_STOP;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
memoryDump(0, 65536, 1, 8, 0, 0);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Output usage screen. So mamy commands you do need to be prompted!!
|
||||
void showArgs(char *progName, struct optparse *options)
|
||||
{
|
||||
printf("%s %s %s %s\n\n", progName, VERSION, COPYRIGHT, AUTHOR);
|
||||
printf("Synopsis:\n");
|
||||
printf("%s --help # This help screen.\n", progName);
|
||||
printf(" --cmd <command> = RESET # Reset the Z80\n");
|
||||
printf(" = STOP # Stop and power off the Z80\n");
|
||||
printf(" = START # Power on and start the Z80\n");
|
||||
printf(" = PAUSE # Pause running Z80\n");
|
||||
printf(" = CONTINUE # Continue Z80 execution\n");
|
||||
printf(" = HOSTRAM # Use HOST DRAM\n");
|
||||
printf(" = VIRTRAM # Use Virtual RAM\n");
|
||||
printf(" = SPEED --speed <1, 2, 4, 8, 16, 32, 64, 128> # In Virtual RAM mode, set CPU speed to base clock x factor.\n");
|
||||
printf(" = LOADMZF --file <mzf filename> # Load MZF file into memory.\n");
|
||||
printf(" = DUMP --addr <24bit addr> --end <24bit addr> [--size <24bit>]--virtual <0 - Host RAM, 1 = Virtual RAM, 2 = PageTable, 3 = IOPageTable>\n");
|
||||
printf(" = CPLDCMD --data <32bit command> # Send adhoc 32bit command to CPLD.\n");
|
||||
printf(" = Z80TEST # Perform various debugging tests\n");
|
||||
printf(" = SPITEST # Perform SPI testing\n");
|
||||
printf(" = PRLTEST # Perform Parallel Bus testing\n");
|
||||
printf(" = Z80MEMTEST # Perform HOST memory tests.\n");
|
||||
printf(" --<cmd> # Some commands can be abbreviated.\n");
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int fdZ80;
|
||||
char buff[64];
|
||||
char cmd[64] = { 0 };
|
||||
char fileName[256] = { 0 };
|
||||
int opt;
|
||||
uint32_t hexData = 0;
|
||||
long speedMultiplier = 1;
|
||||
long startAddr = 0x0000;
|
||||
long endAddr = 0x1000;
|
||||
int virtualMemory = 0;
|
||||
int helpFlag = 0;
|
||||
int verboseFlag = 0;
|
||||
|
||||
// Define parameters to be processed.
|
||||
struct optparse options;
|
||||
static struct optparse_long long_options[] =
|
||||
{
|
||||
{"help", 'h', OPTPARSE_NONE},
|
||||
{"cmd", 'c', OPTPARSE_REQUIRED},
|
||||
{"file", 'f', OPTPARSE_REQUIRED},
|
||||
{"data", 'd', OPTPARSE_REQUIRED},
|
||||
{"speed", 'S', OPTPARSE_REQUIRED},
|
||||
{"virtual", 'V', OPTPARSE_REQUIRED},
|
||||
{"addr", 'a', OPTPARSE_REQUIRED},
|
||||
{"end", 'e', OPTPARSE_REQUIRED},
|
||||
{"size", 's', OPTPARSE_REQUIRED},
|
||||
{"verbose", 'v', OPTPARSE_NONE},
|
||||
{"dump", '1', OPTPARSE_NONE},
|
||||
{"loadmzf", '2', OPTPARSE_NONE},
|
||||
{"reset", '3', OPTPARSE_NONE},
|
||||
{"stop", '4', OPTPARSE_NONE},
|
||||
{"start", '5', OPTPARSE_NONE},
|
||||
{"pause", '6', OPTPARSE_NONE},
|
||||
{"continue", '7', OPTPARSE_NONE},
|
||||
{"speed", '8', OPTPARSE_NONE},
|
||||
{"cpldcmd", '9', OPTPARSE_NONE},
|
||||
{0}
|
||||
};
|
||||
|
||||
// Parse the command line options.
|
||||
//
|
||||
optparse_init(&options, argv);
|
||||
while((opt = optparse_long(&options, long_options, NULL)) != -1)
|
||||
{
|
||||
switch(opt)
|
||||
{
|
||||
// Hex data.
|
||||
case 'd':
|
||||
// hexData = (uint32_t)strtol(options.optarg, NULL, 0);
|
||||
sscanf(options.optarg, "0x%08x", &hexData);
|
||||
printf("Hex data:%08x\n", hexData);
|
||||
break;
|
||||
|
||||
// Start address for memory operations.
|
||||
case 'a':
|
||||
startAddr = strtol(options.optarg, NULL, 0);
|
||||
//printf("Start Addr:%04x\n", startAddr);
|
||||
break;
|
||||
|
||||
// Speed multiplication factor for CPU governor when running in virtual memory.
|
||||
case 'S':
|
||||
speedMultiplier = strtol(options.optarg, NULL, 0);
|
||||
//printf("Speed = base freq x %d\n", speedFactor);
|
||||
break;
|
||||
|
||||
// End address for memory operations.
|
||||
case 'e':
|
||||
endAddr = strtol(options.optarg, NULL, 0);
|
||||
//printf("End Addr:%04x\n", endAddr);
|
||||
break;
|
||||
|
||||
// Size instead of end address for memory operations.
|
||||
case 's':
|
||||
endAddr = startAddr + strtol(options.optarg, NULL, 0);
|
||||
//printf("End Addr:%04x\n", endAddr);
|
||||
break;
|
||||
|
||||
// Virtual memory flag, 0 = host, 1 = virtual memory, 2 = page table, 3 = iopage table.
|
||||
case 'V':
|
||||
virtualMemory = atoi(options.optarg);
|
||||
break;
|
||||
|
||||
// Filename.
|
||||
case 'f':
|
||||
strcpy(fileName, options.optarg);
|
||||
break;
|
||||
|
||||
// Command to execute.
|
||||
case 'c':
|
||||
strcpy(cmd, options.optarg);
|
||||
break;
|
||||
|
||||
// Quick command flags.
|
||||
case '1':
|
||||
strcpy(cmd, "DUMP");
|
||||
break;
|
||||
case '2':
|
||||
strcpy(cmd, "LOADMZF");
|
||||
break;
|
||||
case '3':
|
||||
strcpy(cmd, "RESET");
|
||||
break;
|
||||
case '4':
|
||||
strcpy(cmd, "STOP");
|
||||
break;
|
||||
case '5':
|
||||
strcpy(cmd, "START");
|
||||
break;
|
||||
case '6':
|
||||
strcpy(cmd, "PAUSE");
|
||||
break;
|
||||
case '7':
|
||||
strcpy(cmd, "CONTINUE");
|
||||
break;
|
||||
case '8':
|
||||
strcpy(cmd, "SPEED");
|
||||
break;
|
||||
case '9':
|
||||
strcpy(cmd, "CPLDCMD");
|
||||
break;
|
||||
|
||||
// Verbose mode.
|
||||
case 'v':
|
||||
verboseFlag = 1;
|
||||
break;
|
||||
|
||||
// Command help needed.
|
||||
case 'h':
|
||||
helpFlag = 1;
|
||||
showArgs(argv[0], &options);
|
||||
break;
|
||||
|
||||
// Unrecognised, show synopsis.
|
||||
case '?':
|
||||
showArgs(argv[0], &options);
|
||||
printf("%s: %s\n", argv[0], options.errmsg);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Open the z80drv driver and attach to its shared memory, basically the Z80 control structure which includes the virtual Z80 memory.
|
||||
fdZ80 = open(DEVICE_FILENAME, O_RDWR|O_NDELAY);
|
||||
if(fdZ80 >= 0)
|
||||
{
|
||||
Z80Ctrl = (t_Z80Ctrl *)mmap(0, sizeof(t_Z80Ctrl), PROT_READ | PROT_WRITE, MAP_SHARED, fdZ80, 0);
|
||||
if(Z80Ctrl == (void *)-1)
|
||||
{
|
||||
printf("Failed to attach to the Z80 Control structure, cannot continue, exitting....\n");
|
||||
close(fdZ80);
|
||||
exit(1);
|
||||
}
|
||||
} else
|
||||
{
|
||||
printf("Failed to open the Z80 Driver, exitting...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Basic string to method mapping. Started off with just 1 or two but has grown, may need a table!
|
||||
if(strcasecmp(cmd, "LOADMZF") == 0)
|
||||
{
|
||||
z80load(fdZ80, fileName);
|
||||
} else
|
||||
if(strcasecmp(cmd, "RESET") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_RESET, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "STOP") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_STOP, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "START") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_START, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "PAUSE") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_PAUSE, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "CONTINUE") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_CONTINUE, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "SPEED") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_SPEED, speedMultiplier, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "DUMP") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_DUMP_MEMORY, virtualMemory, startAddr, (endAddr - startAddr));
|
||||
} else
|
||||
if(strcasecmp(cmd, "HOSTRAM") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_HOST_RAM, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "VIRTRAM") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_VIRTUAL_RAM, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "CPLDCMD") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, CPLD_CMD_SEND_CMD, hexData, 0, 0);
|
||||
} else
|
||||
|
||||
// Test methods, if the code is built-in to the driver.
|
||||
if(strcasecmp(cmd, "Z80TEST") == 0)
|
||||
{
|
||||
z80test(fdZ80);
|
||||
} else
|
||||
if(strcasecmp(cmd, "SPITEST") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, CPLD_CMD_SPI_TEST, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "PRLTEST") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, CPLD_CMD_PRL_TEST, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "Z80MEMTEST") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_MEMORY_TEST, 0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
showArgs(argv[0], &options);
|
||||
printf("No command given, nothing done!\n");
|
||||
}
|
||||
|
||||
// Unmap shared memory and close the device.
|
||||
munmap(Z80Ctrl, sizeof(t_Z80Ctrl));
|
||||
close(fdZ80);
|
||||
|
||||
return(0);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
326
software/FusionX/src/driver/MZ2000/z80driver.h
vendored
326
software/FusionX/src/driver/MZ2000/z80driver.h
vendored
@@ -1,326 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: z80driver.h
|
||||
// Created: Oct 2022
|
||||
// Author(s): Philip Smart
|
||||
// Description: Z80 Driver
|
||||
// This file contains the declarations used in the z80drv device driver.
|
||||
//
|
||||
// Credits: Zilog Z80 CPU Emulator v0.2 written by Manuel Sainz de Baranda y Goñi
|
||||
// The Z80 CPU Emulator is the heart of this driver and in all ways, is compatible with
|
||||
// the original Z80.
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
// (c) 1999-2022 Manuel Sainz de Baranda y Goñi
|
||||
//
|
||||
// History: Oct 2022 - Initial write of the z80 kernel driver software.
|
||||
//
|
||||
// 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/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef Z80DRIVER_H
|
||||
#define Z80DRIVER_H
|
||||
|
||||
// Constants.
|
||||
#define TARGET_HOST_MZ700 0
|
||||
#define TARGET_HOST_MZ2000 1
|
||||
#define Z80_VIRTUAL_ROM_SIZE 16384 // Sized to maximum ROM which is the MZ-800 ROM.
|
||||
#define Z80_VIRTUAL_RAM_SIZE (65536 * 8) // (PAGE_SIZE * 2) // max size mmaped to userspace
|
||||
#define Z80_VIRTUAL_MEMORY_SIZE Z80_VIRTUAL_RAM_SIZE + Z80_VIRTUAL_ROM_SIZE
|
||||
#define Z80_MEMORY_PAGE_SIZE 16
|
||||
#define MAX_SCREEN_WIDTH 132
|
||||
#define DEVICE_NAME "z80drv"
|
||||
#define CLASS_NAME "mogu"
|
||||
|
||||
// Memory and IO page types. Used to create a memory page which maps type of address space to real address space on host or virtual memory.
|
||||
#define MEMORY_TYPE_VIRTUAL_MASK 0x00FFFFFF
|
||||
#define MEMORY_TYPE_REAL_MASK 0x0000FFFF
|
||||
#define IO_TYPE_MASK 0x0000FFFF
|
||||
#define MEMORY_TYPE_INHIBIT 0x00000000
|
||||
#define MEMORY_TYPE_PHYSICAL_RAM 0x80000000
|
||||
#define MEMORY_TYPE_PHYSICAL_ROM 0x40000000
|
||||
#define MEMORY_TYPE_PHYSICAL_VRAM 0x20000000
|
||||
#define MEMORY_TYPE_PHYSICAL_HW 0x10000000
|
||||
#define MEMORY_TYPE_VIRTUAL_RAM 0x08000000
|
||||
#define MEMORY_TYPE_VIRTUAL_ROM 0x04000000
|
||||
#define MEMORY_TYPE_VIRTUAL_HW 0x02000000
|
||||
#define IO_TYPE_PHYSICAL_HW 0x80000000
|
||||
#define IO_TYPE_VIRTUAL_HW 0x40000000
|
||||
|
||||
|
||||
// Approximate governor delays to regulate emulated CPU speed.
|
||||
// MZ-700
|
||||
#if(TARGET_HOST_MZ700 == 1)
|
||||
#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
|
||||
// MZ-2000
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
#define INSTRUCTION_DELAY_ROM_3_54MHZ 243
|
||||
#define INSTRUCTION_DELAY_ROM_7MHZ 122
|
||||
#define INSTRUCTION_DELAY_ROM_14MHZ 61
|
||||
#define INSTRUCTION_DELAY_ROM_28MHZ 30
|
||||
#define INSTRUCTION_DELAY_ROM_56MHZ 15
|
||||
#define INSTRUCTION_DELAY_ROM_112MHZ 7
|
||||
#define INSTRUCTION_DELAY_ROM_224MHZ 3
|
||||
#define INSTRUCTION_DELAY_ROM_448MHZ 1
|
||||
#define INSTRUCTION_DELAY_RAM_3_54MHZ 218
|
||||
#define INSTRUCTION_DELAY_RAM_7MHZ 112
|
||||
#define INSTRUCTION_DELAY_RAM_14MHZ 56
|
||||
#define INSTRUCTION_DELAY_RAM_28MHZ 28
|
||||
#define INSTRUCTION_DELAY_RAM_56MHZ 14
|
||||
#define INSTRUCTION_DELAY_RAM_112MHZ 7
|
||||
#define INSTRUCTION_DELAY_RAM_224MHZ 3
|
||||
#define INSTRUCTION_DELAY_RAM_448MHZ 1
|
||||
#endif
|
||||
|
||||
// IOCTL commands. Passed from user space using the IOCTL method to command the driver to perform an action.
|
||||
#define IOCTL_CMD_Z80_STOP 's'
|
||||
#define IOCTL_CMD_Z80_START 'S'
|
||||
#define IOCTL_CMD_Z80_PAUSE 'P'
|
||||
#define IOCTL_CMD_Z80_RESET 'R'
|
||||
#define IOCTL_CMD_Z80_CONTINUE 'C'
|
||||
#define IOCTL_CMD_USE_HOST_RAM 'x'
|
||||
#define IOCTL_CMD_USE_VIRTUAL_RAM 'X'
|
||||
#define IOCTL_CMD_DUMP_MEMORY 'M'
|
||||
#define IOCTL_CMD_Z80_CPU_FREQ 'F'
|
||||
#define IOCTL_CMD_CPLD_CMD 'z'
|
||||
#define IOCTL_CMD_SEND _IOW('c', 'c', int32_t *)
|
||||
#define IOCTL_CMD_SETPC _IOW('p', 'p', int32_t *)
|
||||
#define IOCTL_CMD_SYNC_TO_HOST_RAM 'V'
|
||||
#define IOCTL_CMD_SPI_TEST '1'
|
||||
#define IOCTL_CMD_PRL_TEST '2'
|
||||
#define IOCTL_CMD_Z80_MEMTEST '3'
|
||||
|
||||
|
||||
|
||||
// Chip Select map MZ80K-MZ700.
|
||||
//
|
||||
// 0000 - 0FFF = CS_ROMni : R/W : MZ80K/A/700 = Monitor ROM or RAM (MZ80A rom swap)
|
||||
// 1000 - CFFF = CS_RAMni : R/W : MZ80K/A/700 = RAM
|
||||
// C000 - CFFF = CS_ROMni : R/W : MZ80A = Monitor ROM (MZ80A rom swap)
|
||||
// D000 - D7FF = CS_VRAMni : R/W : MZ80K/A/700 = VRAM
|
||||
// D800 - DFFF = CS_VRAMni : R/W : MZ700 = Colour VRAM (MZ700)
|
||||
// E000 - E003 = CS_8255n : R/W : MZ80K/A/700 = 8255
|
||||
// E004 - E007 = CS_8254n : R/W : MZ80K/A/700 = 8254
|
||||
// E008 - E00B = CS_LS367n : R/W : MZ80K/A/700 = LS367
|
||||
// E00C - E00F = CS_ESWPn : R : MZ80A = Memory Swap (MZ80A)
|
||||
// E010 - E013 = CS_ESWPn : R : MZ80A = Reset Memory Swap (MZ80A)
|
||||
// E014 = CS_E5n : R/W : MZ80A/700 = Normal CRT display (in Video Controller)
|
||||
// E015 = CS_E6n : R/W : MZ80A/700 = Reverse CRT display (in Video Controller)
|
||||
// E200 - E2FF = : R/W : MZ80A/700 = VRAM roll up/roll down.
|
||||
// E800 - EFFF = : R/W : MZ80K/A/700 = User ROM socket or DD Eprom (MZ700)
|
||||
// F000 - F7FF = : R/W : MZ80K/A/700 = Floppy Disk interface.
|
||||
// F800 - FFFF = : R/W : MZ80K/A/700 = Floppy Disk interface.
|
||||
//
|
||||
// Chip Select map MZ800
|
||||
//
|
||||
// FC - FF = CS_PIOn : R/W : MZ800/MZ1500 = Z80 PIO Printer Interface
|
||||
// F2 = CS_PSG0n : W : MZ800/MZ1500 = Programable Sound Generator, MZ-800 = Mono, MZ-1500 = Left Channel
|
||||
// F3 = CS_PSG1n : W : MZ1500 = Programable Sound Generator, MZ-1500 = Right Channel
|
||||
// E9 = CS_PSG(X)n: W : MZ1500 = Simultaneous write to both PSG's.
|
||||
// F0 - F1 = CS_JOYSTK : R : MZ800 = Joystick 1 and 2
|
||||
// CC = CS_GWF : W : MZ800 = CRTC GWF Write format Register
|
||||
// CD = CS_GRF : W : MZ800 = CRTC GRF Read format Register
|
||||
// CE = CS_GDMD : W : MZ800 = CRTC GDMD Mode Register
|
||||
// CF = CS_GCRTC : W : MZ800 = CRTC GCRTC Control Register
|
||||
// D4 - D7 = CS
|
||||
// D000 - DFFF
|
||||
|
||||
// MZ700/MZ800 memory mode switch?
|
||||
//
|
||||
// MZ-700 MZ-800
|
||||
// |0000:0FFF|1000:1FFF|1000:CFFF|C000:CFFF|D000:FFFF |0000:7FFF|1000:1FFF|2000:7FFF|8000:BFFF|C000:CFFF|C000:DFFF|E000:FFFF
|
||||
// -------------------------------------------------- ----------------------------------------------------------------------
|
||||
// OUT 0xE0 = |DRAM | | | | |DRAM | | | | | |
|
||||
// OUT 0xE1 = | | | | |DRAM | | | | | | |DRAM
|
||||
// OUT 0xE2 = |MONITOR | | | | |MONITOR | | | | | |
|
||||
// OUT 0xE3 = | | | | |Memory Mapped I/O | | | | | | |Upper MONITOR ROM
|
||||
// OUT 0xE4 = |MONITOR | |DRAM | |Memory Mapped I/O |MONITOR |CGROM |DRAM |VRAM | |DRAM |Upper MONITOR ROM
|
||||
// OUT 0xE5 = | | | | |Inhibit | | | | | | |Inhibit
|
||||
// OUT 0xE6 = | | | | |<return> | | | | | | |<return>
|
||||
// IN 0xE0 = | |CGROM* | |VRAM* | | |CGROM | |VRAM | | |
|
||||
// IN 0xE1 = | |DRAM | |DRAM | | |<return> | |DRAM | | |
|
||||
//
|
||||
// <return> = Return to the state prior to the complimentary command being invoked.
|
||||
// * = MZ-800 host only.
|
||||
|
||||
// Macros to lookup and test to see if a given memory block or IO byte is of a given type. Also macros to read/write to the memory block and IO byte.
|
||||
#define MEMORY_BLOCK_GRANULARITY 0x800
|
||||
#define MEMORY_BLOCK_SLOTS (0x10000 / MEMORY_BLOCK_GRANULARITY)
|
||||
#define MEMORY_BLOCK_MASK (0x10000 - MEMORY_BLOCK_GRANULARITY)
|
||||
#define MEMORY_BLOCK_SHIFT 11
|
||||
#define getPageData(a) (Z80Ctrl->page[(a & 0xF800) >> MEMORY_BLOCK_SHIFT])
|
||||
#define getIOPageData(a) (Z80Ctrl->iopage[(a & 0xFFFF])
|
||||
#define getPageType(a, mask) (getPageData(a) & mask)
|
||||
#define getPageAddr(a, mask) ((getPageData(a) & mask) + (a & (MEMORY_BLOCK_GRANULARITY-1)))
|
||||
#define getIOPageType(a, mask) (getIOPageData(a) & mask)
|
||||
#define getIOPageAddr(a, mask) (getIOPageData(a) & mask)
|
||||
#define realAddress(a) (Z80Ctrl->page[getPageAddr(a, MEMORY_TYPE_REAL_MASK)])
|
||||
#define realPort(a) (Z80Ctrl->iopage[a & 0xFFFF] & IO_TYPE_MASK)
|
||||
#define isPhysicalRAM(a) (getPageType(a, MEMORY_TYPE_PHYSICAL_RAM))
|
||||
#define isPhysicalVRAM(a) (getPageType(a, MEMORY_TYPE_PHYSICAL_VRAM))
|
||||
#define isPhysicalROM(a) (getPageType(a, MEMORY_TYPE_PHYSICAL_ROM))
|
||||
#define isPhysicalMemory(a) (getPageType(a, (MEMORY_TYPE_PHYSICAL_ROM | MEMORY_TYPE_PHYSICAL_RAM | MEMORY_TYPE_PHYSICAL_VRAM))])
|
||||
#define isPhysicalHW(a) (getPageType(a, MEMORY_TYPE_PHYSICAL_HW))
|
||||
#define isPhysical(a) (getPageType(a, (MEMORY_TYPE_PHYSICAL_HW | MEMORY_TYPE_PHYSICAL_ROM | MEMORY_TYPE_PHYSICAL_RAM | MEMORY_TYPE_PHYSICAL_VRAM)))
|
||||
#define isPhysicalIO(a) (Z80Ctrl->iopage[a & 0xFFFF] & IO_TYPE_PHYSICAL_HW)
|
||||
#define isVirtualRAM(a) (getPageType(a, MEMORY_TYPE_VIRTUAL_RAM))
|
||||
#define isVirtualROM(a) (getPageType(a, MEMORY_TYPE_VIRTUAL_ROM))
|
||||
#define isVirtualMemory(a) (getPageType(a, (MEMORY_TYPE_VIRTUAL_ROM | MEMORY_TYPE_VIRTUAL_RAM)))
|
||||
#define isVirtualHW(a) (getPageType(a, MEMORY_TYPE_VIRTUAL_HW))
|
||||
#define isVirtualIO(a) (Z80Ctrl->iopage[a & 0xFFFF] & IO_TYPE_VIRTUAL_HW)
|
||||
#define isHW(a) (getPageType(a, (MEMORY_TYPE_PHYSICAL_HW | MEMORY_TYPE_VIRTUAL_HW)))
|
||||
#define readVirtualRAM(a) (Z80Ctrl->memory[ getPageAddr(a, MEMORY_TYPE_VIRTUAL_MASK) ])
|
||||
#define readVirtualROM(a) (Z80Ctrl->memory[ getPageAddr(a, MEMORY_TYPE_VIRTUAL_MASK) + Z80_VIRTUAL_RAM_SIZE ])
|
||||
#define writeVirtualRAM(a, d) { Z80Ctrl->memory[ getPageAddr(a, MEMORY_TYPE_VIRTUAL_MASK) ] = d; }
|
||||
#define setMemoryType(_block_,_type_,_addr_) { Z80Ctrl->page[_block_] = _type_ | _addr_; }
|
||||
#define backupMemoryType(_block_) { Z80Ctrl->shadowPage[_block_] = Z80Ctrl->page[_block_]; }
|
||||
#define restoreMemoryType(_block_) { Z80Ctrl->page[_block_] = Z80Ctrl->shadowPage[_block_]; }
|
||||
|
||||
#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_ADDR_E9 0xE9
|
||||
#define IO_ADDR_EA 0xEA
|
||||
#define IO_ADDR_EB 0xEB
|
||||
|
||||
|
||||
enum Z80_RUN_STATES {
|
||||
Z80_STOP = 0x00,
|
||||
Z80_STOPPED = 0x01,
|
||||
Z80_PAUSE = 0x02,
|
||||
Z80_PAUSED = 0x03,
|
||||
Z80_CONTINUE = 0x04,
|
||||
Z80_RUNNING = 0x05,
|
||||
};
|
||||
enum Z80_MEMORY_PROFILE {
|
||||
USE_PHYSICAL_RAM = 0x00,
|
||||
USE_VIRTUAL_RAM = 0x01
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
// Main memory, linear but indexed as though it were banks in 1K pages.
|
||||
uint8_t memory[Z80_VIRTUAL_MEMORY_SIZE];
|
||||
|
||||
// Page pointer map.
|
||||
//
|
||||
// Each pointer points to a byte or block of bytes in the Z80 Memory frame, 64K Real + Banked.
|
||||
// This is currently set at a block of size 0x800 per memory pointer for the MZ-700.
|
||||
// The LSB of the pointer is a direct memory index to a byte or block of bytes, the upper byte of the pointer indicates type of memory space.
|
||||
// 0x80<FFFFFF> - physical host RAM
|
||||
// 0x40<FFFFFF> - physical host ROM
|
||||
// 0x20<FFFFFF> - physical host VRAM
|
||||
// 0x10<FFFFFF> - physical host hardware
|
||||
// 0x08<FFFFFF> - virtual host RAM
|
||||
// 0x04<FFFFFF> - virtual host ROM
|
||||
// 0x02<FFFFFF> - virtual host hardware
|
||||
// 16bit Input Address -> map -> Pointer to 24bit memory address + type flag.
|
||||
// -> Pointer+<low bits of address> to 24bit memory address + type flag.
|
||||
uint32_t page[MEMORY_BLOCK_SLOTS];
|
||||
uint32_t shadowPage[MEMORY_BLOCK_SLOTS];
|
||||
|
||||
// I/O Page map.
|
||||
//
|
||||
// This is a map to indicate the use of the I/O page and allow any required remapping.
|
||||
// <0x80>FF<I/O Address> - physical host hardware
|
||||
// <0x40>FF<I/O Address> - virtual host hardware
|
||||
// 16bit Input Address -> map -> Actual 16bit address to use + type flag.
|
||||
uint32_t iopage[65536];
|
||||
|
||||
// Default page mode configured. This value reflects the default page and iotable map.
|
||||
uint8_t defaultPageMode;
|
||||
|
||||
// Refresh DRAM mode. 1 = Refresh, 0 = No refresh. Only applicable when running code in virtual Kernel RAM.
|
||||
uint8_t refreshDRAM;
|
||||
|
||||
// Inhibit mode is where certain memory ranges are inhibitted. The memory page is set to inhibit and this flag
|
||||
// blocks actions which arent allowed during inhibit.
|
||||
uint8_t inhibitMode;
|
||||
|
||||
// Address caching. Used to minimise instruction length sent to CPLD.
|
||||
uint16_t z80PrevAddr;
|
||||
uint16_t z80PrevPort;
|
||||
|
||||
#if(TARGET_HOST_MZ2000 == 1)
|
||||
uint8_t lowMemorySwap;
|
||||
#endif
|
||||
|
||||
// Keyboard strobe and data. Required to detect hotkey press.
|
||||
uint8_t keyportStrobe;
|
||||
uint8_t keyportShiftCtrl;
|
||||
uint8_t keyportHotKey;
|
||||
|
||||
// Governor is the delay in a 32bit loop per Z80 opcode, used to govern execution speed when using virtual memory.
|
||||
// This mechanism will eventually be tied into the M/T-state calculation for a more precise delay, but at the moment,
|
||||
// with the Z80 assigned to an isolated CPU, it allows time sensitive tasks such as the tape recorder to work.
|
||||
// The lower the value the faster the CPU speed. Two values are present as the optimiser, seeing ROM code not changing
|
||||
// is quicker than RAM (both are in the same kernel memory) as a pointer calculation needs to be made.
|
||||
uint32_t cpuGovernorDelayROM;
|
||||
uint32_t cpuGovernorDelayRAM;
|
||||
} t_Z80Ctrl;
|
||||
|
||||
// IOCTL structure for passing data from user space to driver to perform commands.
|
||||
//
|
||||
struct z80_addr {
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
uint32_t size;
|
||||
};
|
||||
struct z80_ctrl {
|
||||
uint16_t pc;
|
||||
};
|
||||
struct speed {
|
||||
uint32_t speedMultiplier;
|
||||
};
|
||||
struct cpld_ctrl {
|
||||
uint32_t cmd;
|
||||
};
|
||||
struct ioctlCmd {
|
||||
int32_t cmd;
|
||||
union {
|
||||
struct z80_addr addr;
|
||||
struct z80_ctrl z80;
|
||||
struct speed speed;
|
||||
struct cpld_ctrl cpld;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Prototypes.
|
||||
void setupMemory(enum Z80_MEMORY_PROFILE mode);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,428 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: z80io.c
|
||||
// Created: Oct 2022
|
||||
// Author(s): Philip Smart
|
||||
// Description: Z80 IO Interface
|
||||
// This file contains the methods used in interfacing the SOM to the Z80 socket
|
||||
// and host hardware via a CPLD.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Oct 2022 - Initial write of the z80 kernel driver software.
|
||||
//
|
||||
// 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 <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <string.h>
|
||||
#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>
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// User space driver access.
|
||||
//
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// Initialise the SOM hardware used to communicate with the z80 socket and host hardware.
|
||||
// The SOM interfaces to a CPLD which provides voltage level translation and also encapsulates the Z80 timing cycles as recreating
|
||||
// them within the SOM is much more tricky.
|
||||
//
|
||||
// As this is an embedded device and performance/latency are priorities, minimal structured code is used to keep call stack and
|
||||
// generated code to a mimimum without relying on the optimiser.
|
||||
int z80io_init(void)
|
||||
{
|
||||
// Locals.
|
||||
int ret = 0;
|
||||
|
||||
// Initialise GPIO. We call the HAL api to minimise time but for actual bit set/reset and read we go directly to registers to save time, increase throughput and minimise latency.
|
||||
// Initialise the HAL.
|
||||
MHal_GPIO_Init();
|
||||
|
||||
// Set the pads as GPIO devices. The HAL takes care of allocating and deallocating the padmux resources.
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_0); // Word (16bit) bidirectional bus. Default is read with data set.
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_1);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_2);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_3);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_4);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_5);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_6);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_7);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_HIGH_BYTE);
|
||||
//MHal_GPIO_Pad_Set(PAD_GPIO8); // SPIO 4wire control lines setup by the spidev driver but controlled directly in this driver.
|
||||
//MHal_GPIO_Pad_Set(PAD_GPIO9);
|
||||
//MHal_GPIO_Pad_Set(PAD_GPIO10);
|
||||
//MHal_GPIO_Pad_Set(PAD_GPIO11);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_READY);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_LTSTATE);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_BUSRQ);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_BUSACK);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_INT);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_NMI);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_WAIT);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_RESET);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_RSV1);
|
||||
#ifdef NOTNEEDED
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_0);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_1);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_2);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_3);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_4);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_5);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_6);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_7);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_WRITE);
|
||||
#endif
|
||||
|
||||
// Set required input pads.
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_0);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_1);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_2);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_3);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_4);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_5);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_6);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_7);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_READY);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_LTSTATE);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_BUSRQ);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_BUSACK);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_INT);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_NMI);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_WAIT);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_RESET);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_RSV1);
|
||||
|
||||
// Set required output pads.
|
||||
#ifdef NOTNEEDED
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_0);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_1);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_2);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_3);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_4);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_5);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_6);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_7);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_WRITE);
|
||||
MHal_GPIO_Pull_High(PAD_Z80IO_WRITE);
|
||||
#endif
|
||||
|
||||
// Control signals.
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_HIGH_BYTE);
|
||||
MHal_GPIO_Pull_High(PAD_Z80IO_HIGH_BYTE);
|
||||
|
||||
// Setup the MSPI0 device.
|
||||
//
|
||||
// Setup control, interrupts are not used.
|
||||
MSPI_WRITE(MSPI_CTRL_OFFSET, MSPI_CPU_CLOCK_1_2 | MSPI_CTRL_CPOL_LOW | MSPI_CTRL_CPHA_HIGH | MSPI_CTRL_RESET | MSPI_CTRL_ENABLE_SPI);
|
||||
|
||||
// Setup LSB First mode.
|
||||
MSPI_WRITE(MSPI_LSB_FIRST_OFFSET, 0x0);
|
||||
|
||||
// Setup clock.
|
||||
CLK_WRITE(MSPI0_CLK_CFG, 0x1100)
|
||||
|
||||
// Setup the frame size (all buffers to 8bits).
|
||||
MSPI_WRITE(MSPI_FRAME_WBIT_OFFSET, 0xfff);
|
||||
MSPI_WRITE(MSPI_FRAME_WBIT_OFFSET+1, 0xfff);
|
||||
MSPI_WRITE(MSPI_FRAME_RBIT_OFFSET, 0xfff);
|
||||
MSPI_WRITE(MSPI_FRAME_RBIT_OFFSET+1, 0xfff);
|
||||
|
||||
// Setup Chip Selects to inactive.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE);
|
||||
|
||||
// Switch Video and Audio to host.
|
||||
z80io_SPI_Send16(0x00f0, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Parallel bus Methods.
|
||||
//--------------------------------------------------------
|
||||
|
||||
// Methods to read data from the parallel bus.
|
||||
// The CPLD returns status and Z80 data on the 8bit bus as it is marginally quicker than retrieving it over the SPI bus.
|
||||
//
|
||||
inline uint8_t z80io_PRL_Read8(uint8_t dataFlag)
|
||||
{
|
||||
// Locals.
|
||||
uint8_t result = 0;
|
||||
|
||||
// Byte according to flag.
|
||||
if(dataFlag)
|
||||
SET_CPLD_READ_DATA()
|
||||
else
|
||||
SET_CPLD_READ_STATUS()
|
||||
|
||||
// Read the input registers and set value accordingly.
|
||||
result = READ_CPLD_DATA_IN();
|
||||
|
||||
// Return 16bit value read from CPLD.
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline uint16_t z80io_PRL_Read16(void)
|
||||
{
|
||||
// Locals.
|
||||
uint16_t result = 0;
|
||||
|
||||
// Low byte first.
|
||||
CLEAR_CPLD_HIGH_BYTE();
|
||||
|
||||
// Read the input registers and set value accordingly.
|
||||
result = (uint16_t)READ_CPLD_DATA_IN();
|
||||
|
||||
// High byte next.
|
||||
SET_CPLD_HIGH_BYTE();
|
||||
|
||||
// Read the input registers and set value accordingly.
|
||||
result |= (uint16_t)(READ_CPLD_DATA_IN() << 8);
|
||||
|
||||
// Return 16bit value read from CPLD.
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
// Parallel Bus methods were tried and tested but due to the GPIO bits being controlled by individual registers per bit, the setup time was longer
|
||||
// than the transmission time of SPI. These methods are thus deprecated and a fusion of SPI and 8bit parallel is now used.
|
||||
#ifdef NOTNEEDED
|
||||
inline uint8_t z80io_PRL_Send8(uint8_t txData)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
|
||||
// Low byte only.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_HIGH_BYTE].r_out) &= (~gpio_table[PAD_Z80IO_HIGH_BYTE ].m_out);
|
||||
|
||||
// Setup data.
|
||||
if(txData & 0x0080) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_7].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_7].m_out); }
|
||||
if(txData & 0x0040) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_6].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_6].m_out); }
|
||||
if(txData & 0x0020) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_5].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_5].m_out); }
|
||||
if(txData & 0x0010) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_4].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_4].m_out); }
|
||||
if(txData & 0x0008) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_3].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_3].m_out); }
|
||||
if(txData & 0x0004) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_2].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_2].m_out); }
|
||||
if(txData & 0x0002) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_1].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_1].m_out); }
|
||||
if(txData & 0x0001) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_0].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_0].m_out); }
|
||||
|
||||
// Clock data.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) &= (~gpio_table[PAD_Z80IO_WRITE ].m_out);
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) |= gpio_table[PAD_Z80IO_WRITE ].m_out;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
inline uint8_t z80io_PRL_Send16(uint16_t txData)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
|
||||
// Low byte first.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_HIGH_BYTE].r_out) &= (~gpio_table[PAD_Z80IO_HIGH_BYTE ].m_out);
|
||||
|
||||
// Setup data.
|
||||
if(txData & 0x0080) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_7].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_7].m_out); }
|
||||
if(txData & 0x0040) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_6].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_6].m_out); }
|
||||
if(txData & 0x0020) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_5].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_5].m_out); }
|
||||
if(txData & 0x0010) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_4].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_4].m_out); }
|
||||
if(txData & 0x0008) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_3].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_3].m_out); }
|
||||
if(txData & 0x0004) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_2].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_2].m_out); }
|
||||
if(txData & 0x0002) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_1].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_1].m_out); }
|
||||
if(txData & 0x0001) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_0].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_0].m_out); }
|
||||
|
||||
// Clock data.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) &= (~gpio_table[PAD_Z80IO_WRITE ].m_out);
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) |= gpio_table[PAD_Z80IO_WRITE ].m_out;
|
||||
|
||||
// High byte next.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_HIGH_BYTE ].r_out) |= gpio_table[PAD_Z80IO_HIGH_BYTE ].m_out;
|
||||
|
||||
// Setup high byte.
|
||||
if(txData & 0x8000) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_7].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_7].m_out); }
|
||||
if(txData & 0x4000) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_6].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_6].m_out); }
|
||||
if(txData & 0x2000) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_5].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_5].m_out); }
|
||||
if(txData & 0x1000) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_4].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_4].m_out); }
|
||||
if(txData & 0x0800) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_3].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_3].m_out); }
|
||||
if(txData & 0x0400) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_2].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_2].m_out); }
|
||||
if(txData & 0x0200) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_1].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_1].m_out); }
|
||||
if(txData & 0x0100) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_0].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_0].m_out); }
|
||||
|
||||
// Clock data.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) &= (~gpio_table[PAD_Z80IO_WRITE ].m_out);
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) |= gpio_table[PAD_Z80IO_WRITE ].m_out;
|
||||
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------------
|
||||
// SPI Methods.
|
||||
//--------------------------------------------------------
|
||||
|
||||
// Methods to send 8,16 or 32 bits. Each method is seperate to minimise logic and execution time, 8bit being most sensitive.
|
||||
// Macros have also been defined for inline inclusion which dont read back the response data.
|
||||
//
|
||||
uint8_t z80io_SPI_Send8(uint8_t txData, uint8_t *rxData)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t timeout = MAX_CHECK_CNT;
|
||||
|
||||
// Insert data into write buffers.
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)txData);
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 1);
|
||||
|
||||
// Enable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE);
|
||||
|
||||
// Send.
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER);
|
||||
|
||||
// Wait for completion.
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0)
|
||||
{
|
||||
if(--timeout == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// Disable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE);
|
||||
|
||||
// Clear flag.
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE);
|
||||
|
||||
// Fetch data.
|
||||
if(rxData != NULL) *rxData = (uint8_t)MSPI_READ(MSPI_FULL_DEPLUX_RD00);
|
||||
|
||||
// Done.
|
||||
return(timeout == 0);
|
||||
}
|
||||
uint8_t z80io_SPI_Send16(uint16_t txData, uint16_t *rxData)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t timeout = MAX_CHECK_CNT;
|
||||
|
||||
// Insert data into write buffers.
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, txData);
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 2);
|
||||
|
||||
// Enable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE);
|
||||
|
||||
// Send.
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER);
|
||||
|
||||
// Wait for completion.
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0)
|
||||
{
|
||||
if(--timeout == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// Disable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE);
|
||||
|
||||
// Clear flag.
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE);
|
||||
|
||||
// Fetch data.
|
||||
if(rxData != NULL) *rxData = MSPI_READ(MSPI_FULL_DEPLUX_RD00);
|
||||
|
||||
// Done.
|
||||
return(timeout == 0);
|
||||
}
|
||||
uint8_t z80io_SPI_Send32(uint32_t txData, uint32_t *rxData)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t timeout = MAX_CHECK_CNT;
|
||||
|
||||
// Insert data into write buffers.
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)txData);
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET+1, (uint16_t)(txData >> 16));
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 4);
|
||||
|
||||
// Enable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE);
|
||||
|
||||
// Send.
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER);
|
||||
|
||||
// Wait for completion.
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0)
|
||||
{
|
||||
if(--timeout == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// Disable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE);
|
||||
|
||||
// Clear flag.
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE);
|
||||
|
||||
// Fetch data.
|
||||
if(rxData != NULL) *rxData = (uint32_t)(MSPI_READ(MSPI_FULL_DEPLUX_RD00) | (MSPI_READ(MSPI_FULL_DEPLUX_RD02) << 16));
|
||||
|
||||
// Done.
|
||||
return(timeout == 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Test Methods.
|
||||
//--------------------------------------------------------
|
||||
#ifdef INCLUDE_TEST_METHODS
|
||||
#include "z80io_test.c"
|
||||
#else
|
||||
uint8_t z80io_Z80_TestMemory(void)
|
||||
{
|
||||
pr_info("Z80 Test Memory functionality not built-in.\n");
|
||||
return(0);
|
||||
}
|
||||
uint8_t z80io_SPI_Test(void)
|
||||
{
|
||||
pr_info("SPI Test functionality not built-in.\n");
|
||||
return(0);
|
||||
}
|
||||
uint8_t z80io_PRL_Test(void)
|
||||
{
|
||||
pr_info("Parallel Bus Test functionality not built-in.\n");
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
483
software/FusionX/src/driver/MZ2000/z80io.h
vendored
483
software/FusionX/src/driver/MZ2000/z80io.h
vendored
@@ -1,483 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: z80io.h
|
||||
// Created: Oct 2022
|
||||
// Author(s): Philip Smart
|
||||
// Description: Z80 IO Interface
|
||||
// This file contains the declarations used in interfacing the SOM to the Z80 socket
|
||||
// and host hardware via a CPLD.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Oct 2022 - Initial write of the z80 kernel driver software.
|
||||
//
|
||||
// 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/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef Z80IO_H
|
||||
#define Z80IO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Definitions to control compilation.
|
||||
#define INCLUDE_TEST_METHODS 1
|
||||
|
||||
// CPLD Commands.
|
||||
#define CPLD_CMD_FETCH_ADDR 0x10
|
||||
#define CPLD_CMD_FETCH_ADDR_P1 0x11
|
||||
#define CPLD_CMD_FETCH_ADDR_P2 0x12
|
||||
#define CPLD_CMD_FETCH_ADDR_P3 0x13
|
||||
#define CPLD_CMD_FETCH_ADDR_P4 0x14
|
||||
#define CPLD_CMD_FETCH_ADDR_P5 0x15
|
||||
#define CPLD_CMD_FETCH_ADDR_P6 0x16
|
||||
#define CPLD_CMD_FETCH_ADDR_P7 0x17
|
||||
#define CPLD_CMD_WRITE_ADDR 0x18
|
||||
#define CPLD_CMD_WRITE_ADDR_P1 0x19
|
||||
#define CPLD_CMD_WRITE_ADDR_P2 0x1A
|
||||
#define CPLD_CMD_WRITE_ADDR_P3 0x1B
|
||||
#define CPLD_CMD_WRITE_ADDR_P4 0x1C
|
||||
#define CPLD_CMD_WRITE_ADDR_P5 0x1D
|
||||
#define CPLD_CMD_WRITE_ADDR_P6 0x1E
|
||||
#define CPLD_CMD_WRITE_ADDR_P7 0x1F
|
||||
#define CPLD_CMD_READ_ADDR 0x20
|
||||
#define CPLD_CMD_READ_ADDR_P1 0x21
|
||||
#define CPLD_CMD_READ_ADDR_P2 0x22
|
||||
#define CPLD_CMD_READ_ADDR_P3 0x23
|
||||
#define CPLD_CMD_READ_ADDR_P4 0x24
|
||||
#define CPLD_CMD_READ_ADDR_P5 0x25
|
||||
#define CPLD_CMD_READ_ADDR_P6 0x26
|
||||
#define CPLD_CMD_READ_ADDR_P7 0x27
|
||||
#define CPLD_CMD_WRITEIO_ADDR 0x28
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P1 0x29
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P2 0x2A
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P3 0x2B
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P4 0x2C
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P5 0x2D
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P6 0x2E
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P7 0x2F
|
||||
#define CPLD_CMD_READIO_ADDR 0x30
|
||||
#define CPLD_CMD_READIO_ADDR_P1 0x31
|
||||
#define CPLD_CMD_READIO_ADDR_P2 0x32
|
||||
#define CPLD_CMD_READIO_ADDR_P3 0x33
|
||||
#define CPLD_CMD_READIO_ADDR_P4 0x34
|
||||
#define CPLD_CMD_READIO_ADDR_P5 0x35
|
||||
#define CPLD_CMD_READIO_ADDR_P6 0x36
|
||||
#define CPLD_CMD_READIO_ADDR_P7 0x37
|
||||
#define CPLD_CMD_HALT 0x50
|
||||
#define CPLD_CMD_REFRESH 0x51
|
||||
#define CPLD_CMD_SET_SIGROUP1 0xF0
|
||||
#define CPLD_CMD_SET_AUTO_REFRESH 0xF1
|
||||
#define CPLD_CMD_CLEAR_AUTO_REFRESH 0xF2
|
||||
#define CPLD_CMD_SET_SPI_LOOPBACK 0xFE
|
||||
#define CPLD_CMD_NOP1 0x00
|
||||
#define CPLD_CMD_NOP2 0xFF
|
||||
|
||||
|
||||
// Pad numbers for using the MHal GPIO library.
|
||||
#define PAD_Z80IO_IN_DATA_0 PAD_GPIO0
|
||||
#define PAD_Z80IO_IN_DATA_1 PAD_GPIO1
|
||||
#define PAD_Z80IO_IN_DATA_2 PAD_GPIO2
|
||||
#define PAD_Z80IO_IN_DATA_3 PAD_GPIO3
|
||||
#define PAD_Z80IO_IN_DATA_4 PAD_GPIO4
|
||||
#define PAD_Z80IO_IN_DATA_5 PAD_GPIO5
|
||||
#define PAD_Z80IO_IN_DATA_6 PAD_GPIO6
|
||||
#define PAD_Z80IO_IN_DATA_7 PAD_GPIO7
|
||||
#define PAD_SPIO_0 PAD_GPIO8
|
||||
#define PAD_SPIO_1 PAD_GPIO9
|
||||
#define PAD_SPIO_2 PAD_GPIO10
|
||||
#define PAD_SPIO_3 PAD_GPIO11
|
||||
#define PAD_Z80IO_HIGH_BYTE PAD_SAR_GPIO2 // Byte requiured, 0 = Low Byte, 1 = High Byte.
|
||||
#define PAD_Z80IO_READY PAD_GPIO12
|
||||
#define PAD_Z80IO_LTSTATE PAD_PM_IRIN // IRIN
|
||||
#define PAD_Z80IO_BUSRQ PAD_GPIO13
|
||||
#define PAD_Z80IO_BUSACK PAD_GPIO14
|
||||
#define PAD_Z80IO_INT PAD_UART0_RX // GPIO47
|
||||
#define PAD_Z80IO_NMI PAD_UART0_TX // GPIO48
|
||||
#define PAD_Z80IO_WAIT PAD_HSYNC_OUT // GPIO85
|
||||
#define PAD_Z80IO_RESET PAD_VSYNC_OUT // GPIO86
|
||||
#define PAD_Z80IO_RSV1 PAD_SATA_GPIO // GPIO90
|
||||
|
||||
// Physical register addresses.
|
||||
#define PAD_Z80IO_IN_DATA_0_ADDR 0x103C00
|
||||
#define PAD_Z80IO_IN_DATA_1_ADDR 0x103C02
|
||||
#define PAD_Z80IO_IN_DATA_2_ADDR 0x103C04
|
||||
#define PAD_Z80IO_IN_DATA_3_ADDR 0x103C06
|
||||
#define PAD_Z80IO_IN_DATA_4_ADDR 0x103C08
|
||||
#define PAD_Z80IO_IN_DATA_5_ADDR 0x103C0A
|
||||
#define PAD_Z80IO_IN_DATA_6_ADDR 0x103C0C
|
||||
#define PAD_Z80IO_IN_DATA_7_ADDR 0x103C0E
|
||||
#define PAD_SPIO_0_ADDR 0x103C10
|
||||
#define PAD_SPIO_1_ADDR 0x103C12
|
||||
#define PAD_SPIO_2_ADDR 0x103C14
|
||||
#define PAD_SPIO_3_ADDR 0x103C16
|
||||
#define PAD_Z80IO_HIGH_BYTE_ADDR 0x1425
|
||||
#define PAD_Z80IO_READY_ADDR 0x103C18
|
||||
#define PAD_Z80IO_LTSTATE_ADDR 0xF28 // IRIN
|
||||
#define PAD_Z80IO_BUSRQ_ADDR 0x103C1A
|
||||
#define PAD_Z80IO_BUSACK_ADDR 0x103C1C
|
||||
#define PAD_Z80IO_INT_ADDR 0x103C30 // GPIO47
|
||||
#define PAD_Z80IO_NMI_ADDR 0x103C32 // GPIO48
|
||||
#define PAD_Z80IO_WAIT_ADDR 0x103C80 // GPIO85
|
||||
#define PAD_Z80IO_RESET_ADDR 0x103C82 // GPIO86
|
||||
#define PAD_Z80IO_RSV1_ADDR 0x103C8A // GPIO90
|
||||
|
||||
#ifdef NOTNEEDED
|
||||
#define PAD_Z80IO_OUT_DATA_0 PAD_GPIO12
|
||||
#define PAD_Z80IO_OUT_DATA_1 PAD_GPIO13
|
||||
#define PAD_Z80IO_OUT_DATA_2 PAD_GPIO14
|
||||
#define PAD_Z80IO_OUT_DATA_3 PAD_UART0_RX // GPIO47
|
||||
#define PAD_Z80IO_OUT_DATA_4 PAD_UART0_TX // GPIO48
|
||||
#define PAD_Z80IO_OUT_DATA_5 PAD_HSYNC_OUT // GPIO85
|
||||
#define PAD_Z80IO_OUT_DATA_6 PAD_VSYNC_OUT // GPIO86
|
||||
#define PAD_Z80IO_OUT_DATA_7 PAD_SATA_GPIO // GPIO90
|
||||
#define PAD_Z80IO_WRITE PAD_PM_IRIN // Write data clock.
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// The definitions below come from SigmaStar kernel drivers. No header file exists hence the
|
||||
// duplication.
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
#define SUPPORT_SPI_1 0
|
||||
#define MAX_SUPPORT_BITS 16
|
||||
|
||||
#define BANK_TO_ADDR32(b) (b<<9)
|
||||
#define BANK_SIZE 0x200
|
||||
|
||||
#define MS_BASE_REG_RIU_PA 0x1F000000
|
||||
#define gChipBaseAddr 0xFD203C00
|
||||
#define gPmSleepBaseAddr 0xFD001C00
|
||||
#define gSarBaseAddr 0xFD002800
|
||||
#define gRIUBaseAddr 0xFD000000
|
||||
#define gMOVDMAAddr 0xFD201600
|
||||
#define gClkBaseAddr 0xFD207000
|
||||
#define gMspBaseAddr 0xfd222000
|
||||
|
||||
#define MHal_CHIPTOP_REG(addr) (*(volatile U8*)((gChipBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_PM_SLEEP_REG(addr) (*(volatile U8*)((gPmSleepBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_SAR_GPIO_REG(addr) (*(volatile U8*)((gSarBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_RIU_REG(addr) (*(volatile U8*)((gRIUBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
|
||||
|
||||
#define MSPI0_BANK_ADDR 0x1110
|
||||
#define MSPI1_BANK_ADDR 0x1111
|
||||
#define CLK__BANK_ADDR 0x1038
|
||||
#define CHIPTOP_BANK_ADDR 0x101E
|
||||
#define MOVDMA_BANK_ADDR 0x100B
|
||||
|
||||
#define BASE_REG_MSPI0_ADDR MSPI0_BANK_ADDR*0x200 //GET_BASE_ADDR_BY_BANK(IO_ADDRESS(MS_BASE_REG_RIU_PA), 0x111000)
|
||||
#define BASE_REG_MSPI1_ADDR MSPI1_BANK_ADDR*0x200 //GET_BASE_ADDR_BY_BANK(IO_ADDRESS(MS_BASE_REG_RIU_PA), 0x111100)
|
||||
#define BASE_REG_CLK_ADDR CLK__BANK_ADDR*0x200 //GET_BASE_ADDR_BY_BANK(IO_ADDRESS(MS_BASE_REG_RIU_PA), 0x103800)
|
||||
#define BASE_REG_CHIPTOP_ADDR CHIPTOP_BANK_ADDR*0x200 //GET_BASE_ADDR_BY_BANK(IO_ADDRESS(MS_BASE_REG_RIU_PA), 0x101E00)
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Hardware Register Capability
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
#define MSPI_WRITE_BUF_OFFSET 0x40
|
||||
#define MSPI_READ_BUF_OFFSET 0x44
|
||||
#define MSPI_WBF_SIZE_OFFSET 0x48
|
||||
#define MSPI_RBF_SIZE_OFFSET 0x48
|
||||
// read/ write buffer size
|
||||
#define MSPI_RWSIZE_MASK 0xFF
|
||||
#define MSPI_RSIZE_BIT_OFFSET 0x8
|
||||
#define MAX_READ_BUF_SIZE 0x8
|
||||
#define MAX_WRITE_BUF_SIZE 0x8
|
||||
// CLK config
|
||||
#define MSPI_CTRL_OFFSET 0x49
|
||||
#define MSPI_CLK_CLOCK_OFFSET 0x49
|
||||
#define MSPI_CLK_CLOCK_BIT_OFFSET 0x08
|
||||
#define MSPI_CLK_CLOCK_MASK 0xFF
|
||||
#define MSPI_CLK_PHASE_MASK 0x40
|
||||
#define MSPI_CLK_PHASE_BIT_OFFSET 0x06
|
||||
#define MSPI_CLK_POLARITY_MASK 0x80
|
||||
#define MSPI_CLK_POLARITY_BIT_OFFSET 0x07
|
||||
#define MSPI_CLK_PHASE_MAX 0x1
|
||||
#define MSPI_CLK_POLARITY_MAX 0x1
|
||||
#define MSPI_CLK_CLOCK_MAX 0x7
|
||||
#define MSPI_CTRL_CPOL_LOW 0x00
|
||||
#define MSPI_CTRL_CPOL_HIGH 0x80
|
||||
#define MSPI_CTRL_CPHA_LOW 0x00
|
||||
#define MSPI_CTRL_CPHA_HIGH 0x40
|
||||
#define MSPI_CTRL_3WIRE 0x10
|
||||
#define MSPI_CTRL_INTEN 0x04
|
||||
#define MSPI_CTRL_RESET 0x02
|
||||
#define MSPI_CTRL_ENABLE_SPI 0x01
|
||||
// DC config
|
||||
#define MSPI_DC_MASK 0xFF
|
||||
#define MSPI_DC_BIT_OFFSET 0x08
|
||||
#define MSPI_DC_TR_START_OFFSET 0x4A
|
||||
#define MSPI_DC_TRSTART_MAX 0xFF
|
||||
#define MSPI_DC_TR_END_OFFSET 0x4A
|
||||
#define MSPI_DC_TREND_MAX 0xFF
|
||||
#define MSPI_DC_TB_OFFSET 0x4B
|
||||
#define MSPI_DC_TB_MAX 0xFF
|
||||
#define MSPI_DC_TRW_OFFSET 0x4B
|
||||
#define MSPI_DC_TRW_MAX 0xFF
|
||||
// Frame Config
|
||||
#define MSPI_FRAME_WBIT_OFFSET 0x4C
|
||||
#define MSPI_FRAME_RBIT_OFFSET 0x4E
|
||||
#define MSPI_FRAME_BIT_MAX 0x07
|
||||
#define MSPI_FRAME_BIT_MASK 0x07
|
||||
#define MSPI_FRAME_BIT_FIELD 0x03
|
||||
#define MSPI_LSB_FIRST_OFFSET 0x50
|
||||
#define MSPI_TRIGGER_OFFSET 0x5A
|
||||
#define MSPI_DONE_OFFSET 0x5B
|
||||
#define MSPI_DONE_CLEAR_OFFSET 0x5C
|
||||
#define MSPI_CHIP_SELECT_OFFSET 0x5F
|
||||
#define MSPI_CS1_DISABLE 0x01
|
||||
#define MSPI_CS1_ENABLE 0x00
|
||||
#define MSPI_CS2_DISABLE 0x02
|
||||
#define MSPI_CS2_ENABLE 0x00
|
||||
#define MSPI_CS3_DISABLE 0x04
|
||||
#define MSPI_CS3_ENABLE 0x00
|
||||
#define MSPI_CS4_DISABLE 0x08
|
||||
#define MSPI_CS4_ENABLE 0x00
|
||||
#define MSPI_CS5_DISABLE 0x10
|
||||
#define MSPI_CS5_ENABLE 0x00
|
||||
#define MSPI_CS6_DISABLE 0x20
|
||||
#define MSPI_CS6_ENABLE 0x00
|
||||
#define MSPI_CS7_DISABLE 0x40
|
||||
#define MSPI_CS7_ENABLE 0x00
|
||||
#define MSPI_CS8_DISABLE 0x80
|
||||
#define MSPI_CS8_ENABLE 0x00
|
||||
|
||||
#define MSPI_FULL_DEPLUX_RD_CNT (0x77)
|
||||
#define MSPI_FULL_DEPLUX_RD00 (0x78)
|
||||
#define MSPI_FULL_DEPLUX_RD01 (0x78)
|
||||
#define MSPI_FULL_DEPLUX_RD02 (0x79)
|
||||
#define MSPI_FULL_DEPLUX_RD03 (0x79)
|
||||
#define MSPI_FULL_DEPLUX_RD04 (0x7a)
|
||||
#define MSPI_FULL_DEPLUX_RD05 (0x7a)
|
||||
#define MSPI_FULL_DEPLUX_RD06 (0x7b)
|
||||
#define MSPI_FULL_DEPLUX_RD07 (0x7b)
|
||||
|
||||
#define MSPI_FULL_DEPLUX_RD08 (0x7c)
|
||||
#define MSPI_FULL_DEPLUX_RD09 (0x7c)
|
||||
#define MSPI_FULL_DEPLUX_RD10 (0x7d)
|
||||
#define MSPI_FULL_DEPLUX_RD11 (0x7d)
|
||||
#define MSPI_FULL_DEPLUX_RD12 (0x7e)
|
||||
#define MSPI_FULL_DEPLUX_RD13 (0x7e)
|
||||
#define MSPI_FULL_DEPLUX_RD14 (0x7f)
|
||||
#define MSPI_FULL_DEPLUX_RD15 (0x7f)
|
||||
|
||||
//chip select bit map
|
||||
#define MSPI_CHIP_SELECT_MAX 0x07
|
||||
|
||||
// control bit
|
||||
#define MSPI_DONE_FLAG 0x01
|
||||
#define MSPI_TRIGGER 0x01
|
||||
#define MSPI_CLEAR_DONE 0x01
|
||||
#define MSPI_INT_ENABLE 0x04
|
||||
#define MSPI_RESET 0x02
|
||||
#define MSPI_ENABLE 0x01
|
||||
|
||||
// clk_mspi0
|
||||
#define MSPI0_CLK_CFG 0x33 //bit 2 ~bit 3
|
||||
#define MSPI0_CLK_108M 0x00
|
||||
#define MSPI0_CLK_54M 0x04
|
||||
#define MSPI0_CLK_12M 0x08
|
||||
#define MSPI0_CLK_MASK 0x0F
|
||||
|
||||
// clk_mspi1
|
||||
#define MSPI1_CLK_CFG 0x33 //bit 10 ~bit 11
|
||||
#define MSPI1_CLK_108M 0x0000
|
||||
#define MSPI1_CLK_54M 0x0400
|
||||
#define MSPI1_CLK_12M 0x0800
|
||||
#define MSPI1_CLK_MASK 0x0F00
|
||||
|
||||
// clk_mspi
|
||||
#define MSPI_CLK_CFG 0x33
|
||||
#define MSPI_SELECT_0 0x0000
|
||||
#define MSPI_SELECT_1 0x4000
|
||||
#define MSPI_CLK_MASK 0xF000
|
||||
|
||||
// Clock settings
|
||||
#define MSPI_CPU_CLOCK_1_2 0x0000
|
||||
#define MSPI_CPU_CLOCK_1_4 0x0100
|
||||
#define MSPI_CPU_CLOCK_1_8 0x0200
|
||||
#define MSPI_CPU_CLOCK_1_16 0x0300
|
||||
#define MSPI_CPU_CLOCK_1_32 0x0400
|
||||
#define MSPI_CPU_CLOCK_1_64 0x0500
|
||||
#define MSPI_CPU_CLOCK_1_128 0x0600
|
||||
#define MSPI_CPU_CLOCK_1_256 0x0700
|
||||
|
||||
//CHITOP 101E mspi mode select
|
||||
#define MSPI0_MODE 0x0C //bit0~bit1
|
||||
#define MSPI0_MODE_MASK 0x07
|
||||
#define MSPI1_MODE 0x0C //bit4~bit5
|
||||
#define MSPI1_MODE_MASK 0x70
|
||||
#define EJTAG_MODE 0xF
|
||||
#define EJTAG_MODE_1 0x01
|
||||
#define EJTAG_MODE_2 0x02
|
||||
#define EJTAG_MODE_3 0x03
|
||||
#define EJTAG_MODE_MASK 0x03
|
||||
|
||||
//MOVDMA 100B
|
||||
#define MOV_DMA_SRC_ADDR_L 0x03
|
||||
#define MOV_DMA_SRC_ADDR_H 0x04
|
||||
#define MOV_DMA_DST_ADDR_L 0x05
|
||||
#define MOV_DMA_DST_ADDR_H 0x06
|
||||
#define MOV_DMA_BYTE_CNT_L 0x07
|
||||
#define MOV_DMA_BYTE_CNT_H 0x08
|
||||
#define DMA_MOVE0_IRQ_CLR 0x28
|
||||
#define MOV_DMA_IRQ_FINAL_STATUS 0x2A
|
||||
#define DMA_MOVE0_ENABLE 0x00
|
||||
#define DMA_RW 0x50 //0 for dma write to device, 1 for dma read from device
|
||||
#define DMA_READ 0x01
|
||||
#define DMA_WRITE 0x00
|
||||
#define DMA_DEVICE_MODE 0x51
|
||||
#define DMA_DEVICE_SEL 0x52
|
||||
|
||||
//spi dma
|
||||
#define MSPI_DMA_DATA_LENGTH_L 0x30
|
||||
#define MSPI_DMA_DATA_LENGTH_H 0x31
|
||||
#define MSPI_DMA_ENABLE 0x32
|
||||
#define MSPI_DMA_RW_MODE 0x33
|
||||
#define MSPI_DMA_WRITE 0x00
|
||||
#define MSPI_DMA_READ 0x01
|
||||
|
||||
#define MSTAR_SPI_TIMEOUT_MS 30000
|
||||
#define MSTAR_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA /*| SPI_CS_HIGH | SPI_NO_CS | SPI_LSB_FIRST*/)
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Macros
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#define MHal_CHIPTOP_REG(addr) (*(volatile U8*)((gChipBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_PM_SLEEP_REG(addr) (*(volatile U8*)((gPmSleepBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_SAR_GPIO_REG(addr) (*(volatile U8*)((gSarBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_RIU_REG(addr) (*(volatile U8*)((gRIUBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define READ_BYTE(_reg) (*(volatile u8*)(_reg))
|
||||
#define READ_WORD(_reg) (*(volatile u16*)(_reg))
|
||||
#define READ_LONG(_reg) (*(volatile u32*)(_reg))
|
||||
#define WRITE_BYTE(_reg, _val) {(*((volatile u8*)(_reg))) = (u8)(_val); }
|
||||
#define WRITE_WORD(_reg, _val) {(*((volatile u16*)(_reg))) = (u16)(_val); }
|
||||
#define WRITE_LONG(_reg, _val) {(*((volatile u32*)(_reg))) = (u32)(_val); }
|
||||
#define WRITE_WORD_MASK(_reg, _val, _mask) {(*((volatile u16*)(_reg))) = ((*((volatile u16*)(_reg))) & ~(_mask)) | ((u16)(_val) & (_mask)); }
|
||||
#define READ_CPLD_DATA_IN() ((MHal_RIU_REG(PAD_Z80IO_IN_DATA_7_ADDR) & 0x1) << 7 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_6_ADDR) & 0x1) << 6 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_5_ADDR) & 0x1) << 5 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_4_ADDR) & 0x1) << 4 |\
|
||||
(MHal_RIU_REG(PAD_Z80IO_IN_DATA_3_ADDR) & 0x1) << 3 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_2_ADDR) & 0x1) << 2 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_1_ADDR) & 0x1) << 1 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_0_ADDR) & 0x1))
|
||||
#define SET_CPLD_READ_DATA() {MHal_RIU_REG(PAD_Z80IO_HIGH_BYTE_ADDR) |= 0x4;}
|
||||
#define SET_CPLD_READ_STATUS() {MHal_RIU_REG(PAD_Z80IO_HIGH_BYTE_ADDR) &= ~0x4;}
|
||||
#define SET_CPLD_HIGH_BYTE() {MHal_RIU_REG(PAD_Z80IO_HIGH_BYTE_ADDR) |= 0x4;}
|
||||
#define CLEAR_CPLD_HIGH_BYTE() {MHal_RIU_REG(PAD_Z80IO_HIGH_BYTE_ADDR) &= ~0x4;}
|
||||
#define CPLD_READY() (MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1)
|
||||
#define CPLD_RESET() (MHal_RIU_REG(PAD_Z80IO_RESET_ADDR) & 0x1)
|
||||
#define CPLD_LAST_TSTATE() (MHal_RIU_REG(PAD_Z80IO_LTSTATE_ADDR) & 0x4)
|
||||
#define SPI_SEND8(_d_) { uint32_t timeout = MAX_CHECK_CNT; \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)(_d_)); \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 1); \
|
||||
while((MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1) == 0);\
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE);\
|
||||
}
|
||||
#define SPI_SEND16(_d_) { uint32_t timeout = MAX_CHECK_CNT; \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)(_d_)); \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 2); \
|
||||
while((MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1) == 0);\
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE); \
|
||||
}
|
||||
#define SPI_SEND32(_d_) { uint32_t timeout = MAX_CHECK_CNT; \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)(_d_)); \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET+1, (uint16_t)((_d_) >> 16)); \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 4); \
|
||||
while((MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1) == 0);\
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE); \
|
||||
}
|
||||
|
||||
// read 2 byte
|
||||
#define MSPI_READ(_reg_) READ_WORD(gMspBaseAddr + ((_reg_)<<2))
|
||||
// write 2 byte
|
||||
//#define MSPI_WRITE(_reg_, _val_) {pr_info("PDS: MSPI_WRITE(0x%x, 0x%x, 0x%x)\n", _reg_, _val_, gMspBaseAddr + ((_reg_)<<2)); WRITE_WORD(gMspBaseAddr + ((_reg_)<<2), (_val_)); }
|
||||
#define MSPI_WRITE(_reg_, _val_) WRITE_WORD(gMspBaseAddr + ((_reg_)<<2), (_val_));
|
||||
//write 2 byte mask
|
||||
//#define MSPI_WRITE_MASK(_reg_, _val_, mask) {pr_info("PDS: WRITE_LONG(0x%x, 0x%x, mask=0x%x)\n", _reg_, _val_, mask); WRITE_WORD_MASK(gMspBaseAddr + ((_reg_)<<2), (_val_), (mask)); }
|
||||
#define MSPI_WRITE_MASK(_reg_, _val_, mask) WRITE_WORD_MASK(gMspBaseAddr + ((_reg_)<<2), (_val_), (mask));
|
||||
|
||||
#define CLK_READ(_reg_) READ_WORD(gClkBaseAddr + ((_reg_)<<2))
|
||||
//#define CLK_WRITE(_reg_, _val_) {pr_info("PDS: CLK_WRITE(0x%x, 0x%x)\n", _reg_, _val_); WRITE_WORD(gClkBaseAddr + ((_reg_)<<2), (_val_)); }
|
||||
#define CLK_WRITE(_reg_, _val_) WRITE_WORD(gClkBaseAddr + ((_reg_)<<2), (_val_));
|
||||
|
||||
#define CHIPTOP_READ(_reg_) READ_WORD(gChipBaseAddr + ((_reg_)<<2))
|
||||
//#define CHIPTOP_WRITE(_reg_, _val_) {pr_info("PDS: CHIPTOP_WRITE(0x%x, 0x%x)\n", _reg_, _val_); WRITE_WORD(gChipBaseAddr + ((_reg_)<<2), (_val_)); }
|
||||
#define CHIPTOP_WRITE(_reg_, _val_) WRITE_WORD(gChipBaseAddr + ((_reg_)<<2), (_val_));
|
||||
|
||||
#define MOVDMA_READ(_reg_) READ_WORD(gMOVDMAAddr + ((_reg_)<<2))
|
||||
//#define MOVDMA_WRITE(_reg_, _val_) {pr_info("PDS: MOVDMA_WRITE(0x%x, 0x%x)\n", _reg_, _val_); WRITE_WORD(gMOVDMAAddr + ((_reg_)<<2), (_val_)); }
|
||||
#define MOVDMA_WRITE(_reg_, _val_) WRITE_WORD(gMOVDMAAddr + ((_reg_)<<2), (_val_));
|
||||
|
||||
#define _HAL_MSPI_ClearDone() MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET,MSPI_CLEAR_DONE)
|
||||
#define MAX_CHECK_CNT 2000
|
||||
|
||||
#define MSPI_READ_INDEX 0x0
|
||||
#define MSPI_WRITE_INDEX 0x1
|
||||
|
||||
#define SPI_MIU0_BUS_BASE 0x20000000
|
||||
#define SPI_MIU1_BUS_BASE 0xFFFFFFFF
|
||||
|
||||
|
||||
// Function definitions.
|
||||
//
|
||||
int z80io_init(void);
|
||||
uint8_t z80io_SPI_Send8(uint8_t txData, uint8_t *rxData);
|
||||
uint8_t z80io_SPI_Send16(uint16_t txData, uint16_t *rxData);
|
||||
uint8_t z80io_SPI_Send32(uint32_t txData, uint32_t *rxData);
|
||||
#ifdef NOTNEEDED
|
||||
uint8_t z80io_PRL_Send8(uint8_t txData);
|
||||
uint8_t z680io_PRL_Send16(uint16_t txData);
|
||||
#endif
|
||||
uint8_t z80io_PRL_Read8(uint8_t dataFlag);
|
||||
uint16_t z80io_PRL_Read16(void);
|
||||
uint8_t z80io_SPI_Test(void);
|
||||
uint8_t z80io_PRL_Test(void);
|
||||
uint8_t z80io_Z80_TestMemory(void);
|
||||
|
||||
extern void MHal_GPIO_Init(void);
|
||||
extern void MHal_GPIO_Pad_Set(uint8_t u8IndexGPIO);
|
||||
extern int MHal_GPIO_PadGroupMode_Set(uint32_t u32PadMode);
|
||||
extern int MHal_GPIO_PadVal_Set(uint8_t u8IndexGPIO, uint32_t u32PadMode);
|
||||
extern void MHal_GPIO_Pad_Oen(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Pad_Odn(uint8_t u8IndexGPIO);
|
||||
extern uint8_t MHal_GPIO_Pad_Level(uint8_t u8IndexGPIO);
|
||||
extern uint8_t MHal_GPIO_Pad_InOut(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Pull_High(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Pull_Low(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Set_High(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Set_Low(uint8_t u8IndexGPIO);
|
||||
extern void MHal_Enable_GPIO_INT(uint8_t u8IndexGPIO);
|
||||
extern int MHal_GPIO_To_Irq(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Set_POLARITY(uint8_t u8IndexGPIO, uint8_t reverse);
|
||||
extern void MHal_GPIO_Set_Driving(uint8_t u8IndexGPIO, uint8_t setHigh);
|
||||
extern void MHal_GPIO_PAD_32K_OUT(uint8_t u8Enable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // Z80IO_H
|
||||
403
software/FusionX/src/driver/MZ700/optparse.h
vendored
403
software/FusionX/src/driver/MZ700/optparse.h
vendored
@@ -1,403 +0,0 @@
|
||||
/* Optparse --- portable, reentrant, embeddable, getopt-like option parser
|
||||
*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* To get the implementation, define OPTPARSE_IMPLEMENTATION.
|
||||
* Optionally define OPTPARSE_API to control the API's visibility
|
||||
* and/or linkage (static, __attribute__, __declspec).
|
||||
*
|
||||
* The POSIX getopt() option parser has three fatal flaws. These flaws
|
||||
* are solved by Optparse.
|
||||
*
|
||||
* 1) Parser state is stored entirely in global variables, some of
|
||||
* which are static and inaccessible. This means only one thread can
|
||||
* use getopt(). It also means it's not possible to recursively parse
|
||||
* nested sub-arguments while in the middle of argument parsing.
|
||||
* Optparse fixes this by storing all state on a local struct.
|
||||
*
|
||||
* 2) The POSIX standard provides no way to properly reset the parser.
|
||||
* This means for portable code that getopt() is only good for one
|
||||
* run, over one argv with one option string. It also means subcommand
|
||||
* options cannot be processed with getopt(). Most implementations
|
||||
* provide a method to reset the parser, but it's not portable.
|
||||
* Optparse provides an optparse_arg() function for stepping over
|
||||
* subcommands and continuing parsing of options with another option
|
||||
* string. The Optparse struct itself can be passed around to
|
||||
* subcommand handlers for additional subcommand option parsing. A
|
||||
* full reset can be achieved by with an additional optparse_init().
|
||||
*
|
||||
* 3) Error messages are printed to stderr. This can be disabled with
|
||||
* opterr, but the messages themselves are still inaccessible.
|
||||
* Optparse solves this by writing an error message in its errmsg
|
||||
* field. The downside to Optparse is that this error message will
|
||||
* always be in English rather than the current locale.
|
||||
*
|
||||
* Optparse should be familiar with anyone accustomed to getopt(), and
|
||||
* it could be a nearly drop-in replacement. The option string is the
|
||||
* same and the fields have the same names as the getopt() global
|
||||
* variables (optarg, optind, optopt).
|
||||
*
|
||||
* Optparse also supports GNU-style long options with optparse_long().
|
||||
* The interface is slightly different and simpler than getopt_long().
|
||||
*
|
||||
* By default, argv is permuted as it is parsed, moving non-option
|
||||
* arguments to the end. This can be disabled by setting the `permute`
|
||||
* field to 0 after initialization.
|
||||
*/
|
||||
#ifndef OPTPARSE_H
|
||||
#define OPTPARSE_H
|
||||
|
||||
#ifndef OPTPARSE_API
|
||||
# define OPTPARSE_API
|
||||
#endif
|
||||
|
||||
struct optparse {
|
||||
char **argv;
|
||||
int permute;
|
||||
int optind;
|
||||
int optopt;
|
||||
char *optarg;
|
||||
char errmsg[64];
|
||||
int subopt;
|
||||
};
|
||||
|
||||
enum optparse_argtype {
|
||||
OPTPARSE_NONE,
|
||||
OPTPARSE_REQUIRED,
|
||||
OPTPARSE_OPTIONAL
|
||||
};
|
||||
|
||||
struct optparse_long {
|
||||
const char *longname;
|
||||
int shortname;
|
||||
enum optparse_argtype argtype;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the parser state.
|
||||
*/
|
||||
OPTPARSE_API
|
||||
void optparse_init(struct optparse *options, char **argv);
|
||||
|
||||
/**
|
||||
* Read the next option in the argv array.
|
||||
* @param optstring a getopt()-formatted option string.
|
||||
* @return the next option character, -1 for done, or '?' for error
|
||||
*
|
||||
* Just like getopt(), a character followed by no colons means no
|
||||
* argument. One colon means the option has a required argument. Two
|
||||
* colons means the option takes an optional argument.
|
||||
*/
|
||||
OPTPARSE_API
|
||||
int optparse(struct optparse *options, const char *optstring);
|
||||
|
||||
/**
|
||||
* Handles GNU-style long options in addition to getopt() options.
|
||||
* This works a lot like GNU's getopt_long(). The last option in
|
||||
* longopts must be all zeros, marking the end of the array. The
|
||||
* longindex argument may be NULL.
|
||||
*/
|
||||
OPTPARSE_API
|
||||
int optparse_long(struct optparse *options,
|
||||
const struct optparse_long *longopts,
|
||||
int *longindex);
|
||||
|
||||
/**
|
||||
* Used for stepping over non-option arguments.
|
||||
* @return the next non-option argument, or NULL for no more arguments
|
||||
*
|
||||
* Argument parsing can continue with optparse() after using this
|
||||
* function. That would be used to parse the options for the
|
||||
* subcommand returned by optparse_arg(). This function allows you to
|
||||
* ignore the value of optind.
|
||||
*/
|
||||
OPTPARSE_API
|
||||
char *optparse_arg(struct optparse *options);
|
||||
|
||||
/* Implementation */
|
||||
#ifdef OPTPARSE_IMPLEMENTATION
|
||||
|
||||
#define OPTPARSE_MSG_INVALID "invalid option"
|
||||
#define OPTPARSE_MSG_MISSING "option requires an argument"
|
||||
#define OPTPARSE_MSG_TOOMANY "option takes no arguments"
|
||||
|
||||
static int
|
||||
optparse_error(struct optparse *options, const char *msg, const char *data)
|
||||
{
|
||||
unsigned p = 0;
|
||||
const char *sep = " -- '";
|
||||
while (*msg)
|
||||
options->errmsg[p++] = *msg++;
|
||||
while (*sep)
|
||||
options->errmsg[p++] = *sep++;
|
||||
while (p < sizeof(options->errmsg) - 2 && *data)
|
||||
options->errmsg[p++] = *data++;
|
||||
options->errmsg[p++] = '\'';
|
||||
options->errmsg[p++] = '\0';
|
||||
return '?';
|
||||
}
|
||||
|
||||
OPTPARSE_API
|
||||
void
|
||||
optparse_init(struct optparse *options, char **argv)
|
||||
{
|
||||
options->argv = argv;
|
||||
options->permute = 1;
|
||||
options->optind = 1;
|
||||
options->subopt = 0;
|
||||
options->optarg = 0;
|
||||
options->errmsg[0] = '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
optparse_is_dashdash(const char *arg)
|
||||
{
|
||||
return arg != 0 && arg[0] == '-' && arg[1] == '-' && arg[2] == '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
optparse_is_shortopt(const char *arg)
|
||||
{
|
||||
return arg != 0 && arg[0] == '-' && arg[1] != '-' && arg[1] != '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
optparse_is_longopt(const char *arg)
|
||||
{
|
||||
return arg != 0 && arg[0] == '-' && arg[1] == '-' && arg[2] != '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
optparse_permute(struct optparse *options, int index)
|
||||
{
|
||||
char *nonoption = options->argv[index];
|
||||
int i;
|
||||
for (i = index; i < options->optind - 1; i++)
|
||||
options->argv[i] = options->argv[i + 1];
|
||||
options->argv[options->optind - 1] = nonoption;
|
||||
}
|
||||
|
||||
static int
|
||||
optparse_argtype(const char *optstring, char c)
|
||||
{
|
||||
int count = OPTPARSE_NONE;
|
||||
if (c == ':')
|
||||
return -1;
|
||||
for (; *optstring && c != *optstring; optstring++);
|
||||
if (!*optstring)
|
||||
return -1;
|
||||
if (optstring[1] == ':')
|
||||
count += optstring[2] == ':' ? 2 : 1;
|
||||
return count;
|
||||
}
|
||||
|
||||
OPTPARSE_API
|
||||
int
|
||||
optparse(struct optparse *options, const char *optstring)
|
||||
{
|
||||
int type;
|
||||
char *next;
|
||||
char *option = options->argv[options->optind];
|
||||
options->errmsg[0] = '\0';
|
||||
options->optopt = 0;
|
||||
options->optarg = 0;
|
||||
if (option == 0) {
|
||||
return -1;
|
||||
} else if (optparse_is_dashdash(option)) {
|
||||
options->optind++; /* consume "--" */
|
||||
return -1;
|
||||
} else if (!optparse_is_shortopt(option)) {
|
||||
if (options->permute) {
|
||||
int index = options->optind++;
|
||||
int r = optparse(options, optstring);
|
||||
optparse_permute(options, index);
|
||||
options->optind--;
|
||||
return r;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
option += options->subopt + 1;
|
||||
options->optopt = option[0];
|
||||
type = optparse_argtype(optstring, option[0]);
|
||||
next = options->argv[options->optind + 1];
|
||||
switch (type) {
|
||||
case -1: {
|
||||
char str[2] = {0, 0};
|
||||
str[0] = option[0];
|
||||
options->optind++;
|
||||
return optparse_error(options, OPTPARSE_MSG_INVALID, str);
|
||||
}
|
||||
case OPTPARSE_NONE:
|
||||
if (option[1]) {
|
||||
options->subopt++;
|
||||
} else {
|
||||
options->subopt = 0;
|
||||
options->optind++;
|
||||
}
|
||||
return option[0];
|
||||
case OPTPARSE_REQUIRED:
|
||||
options->subopt = 0;
|
||||
options->optind++;
|
||||
if (option[1]) {
|
||||
options->optarg = option + 1;
|
||||
} else if (next != 0) {
|
||||
options->optarg = next;
|
||||
options->optind++;
|
||||
} else {
|
||||
char str[2] = {0, 0};
|
||||
str[0] = option[0];
|
||||
options->optarg = 0;
|
||||
return optparse_error(options, OPTPARSE_MSG_MISSING, str);
|
||||
}
|
||||
return option[0];
|
||||
case OPTPARSE_OPTIONAL:
|
||||
options->subopt = 0;
|
||||
options->optind++;
|
||||
if (option[1])
|
||||
options->optarg = option + 1;
|
||||
else
|
||||
options->optarg = 0;
|
||||
return option[0];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
OPTPARSE_API
|
||||
char *
|
||||
optparse_arg(struct optparse *options)
|
||||
{
|
||||
char *option = options->argv[options->optind];
|
||||
options->subopt = 0;
|
||||
if (option != 0)
|
||||
options->optind++;
|
||||
return option;
|
||||
}
|
||||
|
||||
static int
|
||||
optparse_longopts_end(const struct optparse_long *longopts, int i)
|
||||
{
|
||||
return !longopts[i].longname && !longopts[i].shortname;
|
||||
}
|
||||
|
||||
static void
|
||||
optparse_from_long(const struct optparse_long *longopts, char *optstring)
|
||||
{
|
||||
char *p = optstring;
|
||||
int i;
|
||||
for (i = 0; !optparse_longopts_end(longopts, i); i++) {
|
||||
if (longopts[i].shortname && longopts[i].shortname < 127) {
|
||||
int a;
|
||||
*p++ = longopts[i].shortname;
|
||||
for (a = 0; a < (int)longopts[i].argtype; a++)
|
||||
*p++ = ':';
|
||||
}
|
||||
}
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
/* Unlike strcmp(), handles options containing "=". */
|
||||
static int
|
||||
optparse_longopts_match(const char *longname, const char *option)
|
||||
{
|
||||
const char *a = option, *n = longname;
|
||||
if (longname == 0)
|
||||
return 0;
|
||||
for (; *a && *n && *a != '='; a++, n++)
|
||||
if (*a != *n)
|
||||
return 0;
|
||||
return *n == '\0' && (*a == '\0' || *a == '=');
|
||||
}
|
||||
|
||||
/* Return the part after "=", or NULL. */
|
||||
static char *
|
||||
optparse_longopts_arg(char *option)
|
||||
{
|
||||
for (; *option && *option != '='; option++);
|
||||
if (*option == '=')
|
||||
return option + 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
optparse_long_fallback(struct optparse *options,
|
||||
const struct optparse_long *longopts,
|
||||
int *longindex)
|
||||
{
|
||||
int result;
|
||||
char optstring[96 * 3 + 1]; /* 96 ASCII printable characters */
|
||||
optparse_from_long(longopts, optstring);
|
||||
result = optparse(options, optstring);
|
||||
if (longindex != 0) {
|
||||
*longindex = -1;
|
||||
if (result != -1) {
|
||||
int i;
|
||||
for (i = 0; !optparse_longopts_end(longopts, i); i++)
|
||||
if (longopts[i].shortname == options->optopt)
|
||||
*longindex = i;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
OPTPARSE_API
|
||||
int
|
||||
optparse_long(struct optparse *options,
|
||||
const struct optparse_long *longopts,
|
||||
int *longindex)
|
||||
{
|
||||
int i;
|
||||
char *option = options->argv[options->optind];
|
||||
if (option == 0) {
|
||||
return -1;
|
||||
} else if (optparse_is_dashdash(option)) {
|
||||
options->optind++; /* consume "--" */
|
||||
return -1;
|
||||
} else if (optparse_is_shortopt(option)) {
|
||||
return optparse_long_fallback(options, longopts, longindex);
|
||||
} else if (!optparse_is_longopt(option)) {
|
||||
if (options->permute) {
|
||||
int index = options->optind++;
|
||||
int r = optparse_long(options, longopts, longindex);
|
||||
optparse_permute(options, index);
|
||||
options->optind--;
|
||||
return r;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse as long option. */
|
||||
options->errmsg[0] = '\0';
|
||||
options->optopt = 0;
|
||||
options->optarg = 0;
|
||||
option += 2; /* skip "--" */
|
||||
options->optind++;
|
||||
for (i = 0; !optparse_longopts_end(longopts, i); i++) {
|
||||
const char *name = longopts[i].longname;
|
||||
if (optparse_longopts_match(name, option)) {
|
||||
char *arg;
|
||||
if (longindex)
|
||||
*longindex = i;
|
||||
options->optopt = longopts[i].shortname;
|
||||
arg = optparse_longopts_arg(option);
|
||||
if (longopts[i].argtype == OPTPARSE_NONE && arg != 0) {
|
||||
return optparse_error(options, OPTPARSE_MSG_TOOMANY, name);
|
||||
} if (arg != 0) {
|
||||
options->optarg = arg;
|
||||
} else if (longopts[i].argtype == OPTPARSE_REQUIRED) {
|
||||
options->optarg = options->argv[options->optind];
|
||||
if (options->optarg == 0)
|
||||
return optparse_error(options, OPTPARSE_MSG_MISSING, name);
|
||||
else
|
||||
options->optind++;
|
||||
}
|
||||
return options->optopt;
|
||||
}
|
||||
}
|
||||
return optparse_error(options, OPTPARSE_MSG_INVALID, option);
|
||||
}
|
||||
|
||||
#endif /* OPTPARSE_IMPLEMENTATION */
|
||||
#endif /* OPTPARSE_H */
|
||||
@@ -1,734 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: z80ctrl.c
|
||||
// Created: Oct 2022
|
||||
// Author(s): Philip Smart
|
||||
// Description: Z80 Control Interface
|
||||
// This file contains a command line utility tool for controlling the z80drv device
|
||||
// driver. The tool allows manipulation of the emulated Z80, inspection of its
|
||||
// memory and data, transmission of adhoc commands to the underlying CPLD-Z80
|
||||
// gateway and loading/saving of programs and data to/from the Z80 virtual and
|
||||
// host memory.
|
||||
//
|
||||
// Credits: Zilog Z80 CPU Emulator v0.2 written by Manuel Sainz de Baranda y Goñi
|
||||
// The Z80 CPU Emulator is the heart of the Z80 device driver.
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
// (c) 1999-2022 Manuel Sainz de Baranda y Goñi
|
||||
//
|
||||
// History: Oct 2022 - Initial write of the z80 kernel driver software.
|
||||
//
|
||||
// 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/mman.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/select.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <Z/constants/pointer.h>
|
||||
#include <Z/macros/member.h>
|
||||
#include <Z/macros/array.h>
|
||||
#include <Z80.h>
|
||||
#include "z80driver.h"
|
||||
|
||||
#define VERSION "1.0"
|
||||
#define AUTHOR "P.D.Smart"
|
||||
#define COPYRIGHT "(c) 2018-22"
|
||||
|
||||
// Getopt_long is buggy so we use optparse.
|
||||
#define OPTPARSE_IMPLEMENTATION
|
||||
#define OPTPARSE_API static
|
||||
#include "optparse.h"
|
||||
|
||||
// Device driver name.
|
||||
#define DEVICE_FILENAME "/dev/z80drv"
|
||||
|
||||
// Constants for the Sharp MZ80A MZF file format.
|
||||
#define MZF_HEADER_SIZE 128 // Size of the MZF header.
|
||||
#define MZF_ATTRIBUTE 0x00 // Code Type, 01 = Machine Code.
|
||||
#define MZF_FILENAME 0x01 // Title/Name (17 bytes).
|
||||
#define MZF_FILENAME_LEN 17 // Length of the filename, it is not NULL terminated, generally a CR can be taken as terminator but not guaranteed.
|
||||
#define MZF_FILESIZE 0x12 // Size of program.
|
||||
#define MZF_LOADADDR 0x14 // Load address of program.
|
||||
#define MZF_EXECADDR 0x16 // Exec address of program.
|
||||
#define MZF_COMMENT 0x18 // Comment, used for details of the file or startup code.
|
||||
#define MZF_COMMENT_LEN 104 // Length of the comment field.
|
||||
#define CMT_TYPE_OBJCD 0x001 // MZF contains a binary object.
|
||||
#define CMT_TYPE_BTX1CD 0x002 // MZF contains a BASIC program.
|
||||
#define CMT_TYPE_BTX2CD 0x005 // MZF contains a BASIC program.
|
||||
#define CMT_TYPE_TZOBJCD0 0x0F8 // MZF contains a TZFS binary object for page 0.
|
||||
#define CMT_TYPE_TZOBJCD1 0x0F9
|
||||
#define CMT_TYPE_TZOBJCD2 0x0FA
|
||||
#define CMT_TYPE_TZOBJCD3 0x0FB
|
||||
#define CMT_TYPE_TZOBJCD4 0x0FC
|
||||
#define CMT_TYPE_TZOBJCD5 0x0FD
|
||||
#define CMT_TYPE_TZOBJCD6 0x0FE
|
||||
#define CMT_TYPE_TZOBJCD7 0x0FF // MZF contains a TZFS binary object for page 7.
|
||||
#define MZ_CMT_ADDR 0x10F0
|
||||
|
||||
// Structure to define a Sharp MZ80A MZF directory structure. This header appears at the beginning of every Sharp MZ80A tape (and more recently archived/emulator) images.
|
||||
//
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
uint8_t attr; // MZF attribute describing the file.
|
||||
uint8_t fileName[MZF_FILENAME_LEN]; // Each directory entry is the size of an MZF filename.
|
||||
uint16_t fileSize; // Size of file.
|
||||
uint16_t loadAddr; // Load address for the file.
|
||||
uint16_t execAddr; // Execution address where the Z80 starts processing.
|
||||
uint8_t comment[MZF_COMMENT_LEN]; // Text comment field but often contains a startup machine code program.
|
||||
} t_svcDirEnt;
|
||||
|
||||
// Possible commands to be issued to the Z80 driver.
|
||||
enum CTRL_COMMANDS {
|
||||
Z80_CMD_STOP = 0,
|
||||
Z80_CMD_START = 1,
|
||||
Z80_CMD_PAUSE = 2,
|
||||
Z80_CMD_CONTINUE = 3,
|
||||
Z80_CMD_RESET = 4,
|
||||
Z80_CMD_SPEED = 5,
|
||||
Z80_CMD_HOST_RAM = 6,
|
||||
Z80_CMD_VIRTUAL_RAM = 7,
|
||||
Z80_CMD_DUMP_MEMORY = 8,
|
||||
Z80_CMD_MEMORY_TEST = 9,
|
||||
CPLD_CMD_SEND_CMD = 10,
|
||||
CPLD_CMD_SPI_TEST = 11,
|
||||
CPLD_CMD_PRL_TEST = 12
|
||||
};
|
||||
|
||||
|
||||
// Shared memory between this process and the Z80 driver.
|
||||
static t_Z80Ctrl *Z80Ctrl = NULL;
|
||||
|
||||
// Method to obtain and return the output screen width.
|
||||
//
|
||||
uint8_t getScreenWidth(void)
|
||||
{
|
||||
return(MAX_SCREEN_WIDTH);
|
||||
}
|
||||
|
||||
struct termios orig_termios;
|
||||
|
||||
void reset_terminal_mode()
|
||||
{
|
||||
tcsetattr(0, TCSANOW, &orig_termios);
|
||||
}
|
||||
|
||||
void set_conio_terminal_mode()
|
||||
{
|
||||
struct termios new_termios;
|
||||
|
||||
/* take two copies - one for now, one for later */
|
||||
tcgetattr(0, &orig_termios);
|
||||
memcpy(&new_termios, &orig_termios, sizeof(new_termios));
|
||||
|
||||
/* register cleanup handler, and set the new terminal mode */
|
||||
atexit(reset_terminal_mode);
|
||||
cfmakeraw(&new_termios);
|
||||
tcsetattr(0, TCSANOW, &new_termios);
|
||||
}
|
||||
|
||||
int kbhit()
|
||||
{
|
||||
struct timeval tv = { 0L, 0L };
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(0, &fds);
|
||||
return select(1, &fds, NULL, NULL, &tv) > 0;
|
||||
}
|
||||
|
||||
int getch(uint8_t wait)
|
||||
{
|
||||
int r;
|
||||
unsigned char c;
|
||||
|
||||
if(wait != 0 || (wait == 0 && kbhit()))
|
||||
{
|
||||
if ((r = read(0, &c, sizeof(c))) < 0) {
|
||||
return r;
|
||||
} else {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void delay(int number_of_seconds)
|
||||
{
|
||||
// Converting time into milli_seconds
|
||||
int milli_seconds = 1000 * number_of_seconds;
|
||||
|
||||
// Storing start time
|
||||
clock_t start_time = clock();
|
||||
|
||||
// looping till required time is not achieved
|
||||
while (clock() < start_time + milli_seconds);
|
||||
}
|
||||
|
||||
// Function to dump out a given section of memory via the UART.
|
||||
//
|
||||
int memoryDump(uint32_t memaddr, uint32_t memsize, uint8_t memoryFlag, uint32_t memwidth, uint32_t dispaddr, uint8_t dispwidth)
|
||||
{
|
||||
uint8_t displayWidth = dispwidth;;
|
||||
uint32_t pnt = memaddr;
|
||||
uint32_t endAddr = memaddr + memsize;
|
||||
uint32_t addr = dispaddr;
|
||||
uint32_t i = 0;
|
||||
//uint32_t data;
|
||||
int8_t keyIn;
|
||||
int result = -1;
|
||||
char c = 0;
|
||||
|
||||
// Sanity check. memoryFlag == 0 required kernel driver to dump so we exit as it cannot be performed here.
|
||||
if(memoryFlag == 0)
|
||||
return(-1);
|
||||
|
||||
// Reconfigure terminal to allow non-blocking key input.
|
||||
//
|
||||
set_conio_terminal_mode();
|
||||
|
||||
// If not set, calculate output line width according to connected display width.
|
||||
//
|
||||
if(displayWidth == 0)
|
||||
{
|
||||
switch(getScreenWidth())
|
||||
{
|
||||
case 40:
|
||||
displayWidth = 8;
|
||||
break;
|
||||
case 80:
|
||||
displayWidth = 16;
|
||||
break;
|
||||
default:
|
||||
displayWidth = 32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
printf("%08lX", addr); // print address
|
||||
printf(": ");
|
||||
|
||||
// print hexadecimal data
|
||||
for (i=0; i < displayWidth; )
|
||||
{
|
||||
switch(memwidth)
|
||||
{
|
||||
case 16:
|
||||
if(pnt+i < endAddr)
|
||||
printf("%04X", memoryFlag == 1 ? (uint16_t)Z80Ctrl->memory[pnt+i] : memoryFlag == 2 ? (uint16_t)Z80Ctrl->page[pnt+i] : (uint16_t)Z80Ctrl->iopage[pnt+i]);
|
||||
else
|
||||
printf(" ");
|
||||
i++;
|
||||
break;
|
||||
|
||||
case 32:
|
||||
if(pnt+i < endAddr)
|
||||
printf("%08lX", memoryFlag == 1 ? (uint32_t)Z80Ctrl->memory[pnt+i] : memoryFlag == 2 ? (uint32_t)Z80Ctrl->page[pnt+i] : (uint32_t)Z80Ctrl->iopage[pnt+i]);
|
||||
else
|
||||
printf(" ");
|
||||
i++;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
default:
|
||||
if(pnt+i < endAddr)
|
||||
printf("%02X", memoryFlag == 1 ? (uint8_t)Z80Ctrl->memory[pnt+i] : memoryFlag == 2 ? (uint8_t)Z80Ctrl->page[pnt+i] : (uint8_t)Z80Ctrl->iopage[pnt+i]);
|
||||
else
|
||||
printf(" ");
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
fputc((char)' ', stdout);
|
||||
}
|
||||
|
||||
// print ascii data
|
||||
printf(" |");
|
||||
|
||||
// print single ascii char
|
||||
for (i=0; i < displayWidth; i++)
|
||||
{
|
||||
c = memoryFlag == 1 ? (char)Z80Ctrl->memory[pnt+i] : memoryFlag == 2 ? (char)Z80Ctrl->page[pnt+i] : (char)Z80Ctrl->iopage[pnt+i];
|
||||
if ((pnt+i < endAddr) && (c >= ' ') && (c <= '~'))
|
||||
fputc((char)c, stdout);
|
||||
else
|
||||
fputc((char)' ', stdout);
|
||||
}
|
||||
|
||||
printf("|\r\n");
|
||||
fflush(stdout);
|
||||
|
||||
// Move on one row.
|
||||
pnt += displayWidth;
|
||||
addr += displayWidth;
|
||||
|
||||
// User abort (ESC), pause (Space) or all done?
|
||||
//
|
||||
keyIn = getch(0);
|
||||
if(keyIn == ' ')
|
||||
{
|
||||
do {
|
||||
keyIn = getch(0);
|
||||
} while(keyIn != ' ' && keyIn != 0x1b);
|
||||
}
|
||||
// Escape key pressed, exit with 0 to indicate this to caller.
|
||||
if (keyIn == 0x1b)
|
||||
{
|
||||
sleep(1);
|
||||
result = 0;
|
||||
goto memoryDumpExit;
|
||||
}
|
||||
|
||||
// End of buffer, exit the loop.
|
||||
if(pnt >= (memaddr + memsize))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Normal exit, return -1 to show no key pressed.
|
||||
memoryDumpExit:
|
||||
reset_terminal_mode();
|
||||
return(result);
|
||||
}
|
||||
|
||||
// Method to load a program or data file into the Z80 memory. First load into Virtual memory and then trigger a sync to bring Host RAM in line.
|
||||
//
|
||||
int z80load(int fdZ80, char *fileName)
|
||||
{
|
||||
// Locals.
|
||||
struct ioctlCmd ioctlCmd;
|
||||
int ret = 0;
|
||||
t_svcDirEnt mzfHeader;
|
||||
|
||||
// Pause the Z80.
|
||||
//
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_PAUSE;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
// Open the file and read directly into the Virtual memory via the share.
|
||||
FILE *ptr;
|
||||
ptr = fopen(fileName, "rb");
|
||||
if(ptr)
|
||||
{
|
||||
printf("File:%s\n", fileName);
|
||||
// First the header.
|
||||
fread((uint8_t *)&mzfHeader, MZF_HEADER_SIZE, 1, ptr);
|
||||
printf("Load:%x\n", mzfHeader.loadAddr);
|
||||
if(mzfHeader.loadAddr > 0x1000)
|
||||
{
|
||||
printf("Memcpy:%x,%x\n", mzfHeader.loadAddr, mzfHeader.fileSize);
|
||||
// Copy in the header.
|
||||
memcpy((uint8_t *)&Z80Ctrl->memory[MZ_CMT_ADDR], (uint8_t *)&mzfHeader, MZF_HEADER_SIZE);
|
||||
|
||||
printf("Memcpy:%x,%x\n", mzfHeader.loadAddr, mzfHeader.fileSize);
|
||||
// Now read in the data.
|
||||
fread(&Z80Ctrl->memory[mzfHeader.loadAddr], mzfHeader.fileSize, 1, ptr);
|
||||
printf("Memcpy:%x,%x\n", mzfHeader.loadAddr, mzfHeader.fileSize);
|
||||
printf("Loaded %s, Size:%04x, Addr:%04x, Exec:%04x\n", fileName, mzfHeader.fileSize, mzfHeader.loadAddr, mzfHeader.execAddr);
|
||||
}
|
||||
|
||||
// Sync the loaded image from Virtual memory to hard memory.
|
||||
ioctlCmd.cmd = IOCTL_CMD_SYNC_TO_HOST_RAM;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
// Resume Z80 processing.
|
||||
//
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_CONTINUE;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
}
|
||||
else
|
||||
printf("Couldnt open file\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Method to request basic Z80 operations.
|
||||
//
|
||||
int ctrlCmd(int fdZ80, enum CTRL_COMMANDS cmd, long param1, long param2, long param3)
|
||||
{
|
||||
// Locals.
|
||||
struct ioctlCmd ioctlCmd;
|
||||
uint32_t idx;
|
||||
int ret = 0;
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
case Z80_CMD_STOP:
|
||||
// Use IOCTL to request Z80 to Stop (power off) processing.
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_STOP;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_START:
|
||||
// Use IOCTL to request Z80 to Start (power on) processing.
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_START;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_PAUSE:
|
||||
// Use IOCTL to request Z80 to pause processing.
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_PAUSE;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_CONTINUE:
|
||||
// Use IOCTL to request Z80 continue processing.
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_CONTINUE;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_RESET:
|
||||
// Use IOCTL to request Z80 reset.
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_RESET;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_SPEED:
|
||||
// Check value is in range.
|
||||
for(idx=1; idx < 256; idx+=idx)
|
||||
{
|
||||
if((uint32_t)param1 == idx) break;
|
||||
}
|
||||
if(idx == 256)
|
||||
{
|
||||
printf("Speed factor is illegal. It must be a multiple value of the original CPU clock, ie. 1x, 2x, 4x etc\n");
|
||||
ret = -1;
|
||||
} else
|
||||
{
|
||||
// Use IOCTL to request Z80 cpu freq change.
|
||||
ioctlCmd.speed.speedMultiplier = (uint32_t)param1;
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_CPU_FREQ;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
}
|
||||
break;
|
||||
case CPLD_CMD_SEND_CMD:
|
||||
// Build up the IOCTL command to request the given data is sent to the CPLD.
|
||||
ioctlCmd.cmd = IOCTL_CMD_CPLD_CMD;
|
||||
ioctlCmd.cpld.cmd = (uint32_t)param1;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_DUMP_MEMORY:
|
||||
// If virtual memory, we can dump it via the shared memory segment.
|
||||
if((uint8_t)param1)
|
||||
{
|
||||
memoryDump((uint32_t)param2, (uint32_t)param3, (uint8_t)param1, (uint8_t)param1 == 2 || (uint8_t)param1 == 3 ? 32 : 8, (uint32_t)param2, 0);
|
||||
} else
|
||||
{
|
||||
// Build an IOCTL command to get the driver to dump the memory.
|
||||
ioctlCmd.cmd = IOCTL_CMD_DUMP_MEMORY;
|
||||
ioctlCmd.addr.start = (uint32_t)param2;
|
||||
ioctlCmd.addr.end = (uint32_t)param2+(uint32_t)param3;
|
||||
ioctlCmd.addr.size = (uint32_t)param3;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
}
|
||||
break;
|
||||
case Z80_CMD_HOST_RAM:
|
||||
// Use IOCTL to request change to host RAM.
|
||||
ioctlCmd.cmd = IOCTL_CMD_USE_HOST_RAM;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_VIRTUAL_RAM:
|
||||
// Use IOCTL to request change to host RAM.
|
||||
ioctlCmd.cmd = IOCTL_CMD_USE_VIRTUAL_RAM;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case Z80_CMD_MEMORY_TEST:
|
||||
// Send command to test the SPI.
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_MEMTEST;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case CPLD_CMD_PRL_TEST:
|
||||
// Send command to test the SPI.
|
||||
ioctlCmd.cmd = IOCTL_CMD_PRL_TEST;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
case CPLD_CMD_SPI_TEST:
|
||||
// Send command to test the SPI.
|
||||
ioctlCmd.cmd = IOCTL_CMD_SPI_TEST;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Command not supported!\n");
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Method to perform some simple tests on the Z80 emulator.
|
||||
//
|
||||
int z80test(int fdZ80)
|
||||
{
|
||||
// Locals.
|
||||
struct ioctlCmd ioctlCmd;
|
||||
int ret = 0;
|
||||
|
||||
// Stop the Z80.
|
||||
//
|
||||
printf("Send STOP\n");
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_STOP;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
FILE *ptr;
|
||||
ptr = fopen("/customer/mz700.rom", "rb");
|
||||
if(ptr)
|
||||
{
|
||||
fread(&Z80Ctrl->memory, 65536, 1, ptr);
|
||||
} else printf("Couldnt open file\n");
|
||||
|
||||
// Configure the Z80.
|
||||
//
|
||||
printf("Send SETPC\n");
|
||||
ioctlCmd.z80.pc = 0;
|
||||
ioctl(fdZ80, IOCTL_CMD_SETPC, &ioctlCmd);
|
||||
|
||||
memoryDump(0 , 65536, 1, 8, 0, 0);
|
||||
|
||||
// Start the Z80.
|
||||
//
|
||||
printf("Send START\n");
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_START;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
delay(10);
|
||||
|
||||
printf("Send STOP\n");
|
||||
ioctlCmd.cmd = IOCTL_CMD_Z80_STOP;
|
||||
ioctl(fdZ80, IOCTL_CMD_SEND, &ioctlCmd);
|
||||
|
||||
memoryDump(0, 65536, 1, 8, 0, 0);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Output usage screen. So mamy commands you do need to be prompted!!
|
||||
void showArgs(char *progName, struct optparse *options)
|
||||
{
|
||||
printf("%s %s %s %s\n\n", progName, VERSION, COPYRIGHT, AUTHOR);
|
||||
printf("Synopsis:\n");
|
||||
printf("%s --help # This help screen.\n", progName);
|
||||
printf(" --cmd <command> = RESET # Reset the Z80\n");
|
||||
printf(" = STOP # Stop and power off the Z80\n");
|
||||
printf(" = START # Power on and start the Z80\n");
|
||||
printf(" = PAUSE # Pause running Z80\n");
|
||||
printf(" = CONTINUE # Continue Z80 execution\n");
|
||||
printf(" = HOSTRAM # Use HOST DRAM\n");
|
||||
printf(" = VIRTRAM # Use Virtual RAM\n");
|
||||
printf(" = SPEED --speed <1, 2, 4, 8, 16, 32, 64, 128> # In Virtual RAM mode, set CPU speed to base clock x factor.\n");
|
||||
printf(" = LOADMZF --file <mzf filename> # Load MZF file into memory.\n");
|
||||
printf(" = DUMP --start <24bit addr> --end <24bit addr> --virtual <0 - Host RAM, 1 = Virtual RAM, 2 = PageTable, 3 = IOPageTable>\n");
|
||||
printf(" = CPLDCMD --data <32bit command> # Send adhoc 32bit command to CPLD.\n");
|
||||
printf(" = Z80TEST # Perform various debugging tests\n");
|
||||
printf(" = SPITEST # Perform SPI testing\n");
|
||||
printf(" = PRLTEST # Perform Parallel Bus testing\n");
|
||||
printf(" = Z80MEMTEST # Perform HOST memory tests.\n");
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int fdZ80;
|
||||
char buff[64];
|
||||
char cmd[64] = { 0 };
|
||||
char fileName[256] = { 0 };
|
||||
int opt;
|
||||
long hexData = 0;
|
||||
long speedMultiplier = 1;
|
||||
long startAddr = 0x0000;
|
||||
long endAddr = 0x1000;
|
||||
int virtualMemory = 0;
|
||||
int helpFlag = 0;
|
||||
int verboseFlag = 0;
|
||||
|
||||
// Define parameters to be processed.
|
||||
struct optparse options;
|
||||
static struct optparse_long long_options[] =
|
||||
{
|
||||
{"help", 'h', OPTPARSE_NONE},
|
||||
{"cmd", 'c', OPTPARSE_REQUIRED},
|
||||
{"file", 'f', OPTPARSE_REQUIRED},
|
||||
{"data", 'd', OPTPARSE_REQUIRED},
|
||||
{"speed", 'S', OPTPARSE_REQUIRED},
|
||||
{"virtual", 'V', OPTPARSE_REQUIRED},
|
||||
{"start", 's', OPTPARSE_REQUIRED},
|
||||
{"end", 'e', OPTPARSE_REQUIRED},
|
||||
{"verbose", 'v', OPTPARSE_NONE},
|
||||
{0}
|
||||
};
|
||||
|
||||
// Parse the command line options.
|
||||
//
|
||||
optparse_init(&options, argv);
|
||||
while((opt = optparse_long(&options, long_options, NULL)) != -1)
|
||||
{
|
||||
switch(opt)
|
||||
{
|
||||
// Hex data.
|
||||
case 'd':
|
||||
hexData = strtol(options.optarg, NULL, 0);
|
||||
//printf("Hex data:%08x\n", hexData);
|
||||
break;
|
||||
|
||||
// Start address for memory operations.
|
||||
case 's':
|
||||
startAddr = strtol(options.optarg, NULL, 0);
|
||||
//printf("Start Addr:%04x\n", startAddr);
|
||||
break;
|
||||
|
||||
// Speed multiplication factor for CPU governor when running in virtual memory.
|
||||
case 'S':
|
||||
speedMultiplier = strtol(options.optarg, NULL, 0);
|
||||
//printf("Speed = base freq x %d\n", speedFactor);
|
||||
break;
|
||||
|
||||
// End address for memory operations.
|
||||
case 'e':
|
||||
endAddr = strtol(options.optarg, NULL, 0);
|
||||
//printf("End Addr:%04x\n", endAddr);
|
||||
break;
|
||||
|
||||
// Virtual memory flag, 0 = host, 1 = virtual memory, 2 = page table, 3 = iopage table.
|
||||
case 'V':
|
||||
virtualMemory = atoi(options.optarg);
|
||||
break;
|
||||
|
||||
// Filename.
|
||||
case 'f':
|
||||
strcpy(fileName, options.optarg);
|
||||
break;
|
||||
|
||||
// Command to execute.
|
||||
case 'c':
|
||||
strcpy(cmd, options.optarg);
|
||||
break;
|
||||
|
||||
// Verbose mode.
|
||||
case 'v':
|
||||
verboseFlag = 1;
|
||||
break;
|
||||
|
||||
// Command help needed.
|
||||
case 'h':
|
||||
helpFlag = 1;
|
||||
showArgs(argv[0], &options);
|
||||
break;
|
||||
|
||||
// Unrecognised, show synopsis.
|
||||
case '?':
|
||||
showArgs(argv[0], &options);
|
||||
printf("%s: %s\n", argv[0], options.errmsg);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Open the z80drv driver and attach to its shared memory, basically the Z80 control structure which includes the virtual Z80 memory.
|
||||
fdZ80 = open(DEVICE_FILENAME, O_RDWR|O_NDELAY);
|
||||
if(fdZ80 >= 0)
|
||||
{
|
||||
Z80Ctrl = (t_Z80Ctrl *)mmap(0, sizeof(t_Z80Ctrl), PROT_READ | PROT_WRITE, MAP_SHARED, fdZ80, 0);
|
||||
if(Z80Ctrl == (void *)-1)
|
||||
{
|
||||
printf("Failed to attach to the Z80 Control structure, cannot continue, exitting....\n");
|
||||
close(fdZ80);
|
||||
exit(1);
|
||||
}
|
||||
} else
|
||||
{
|
||||
printf("Failed to open the Z80 Driver, exitting...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Basic string to method mapping. Started off with just 1 or two but has grown, may need a table!
|
||||
if(strcasecmp(cmd, "LOADMZF") == 0)
|
||||
{
|
||||
z80load(fdZ80, fileName);
|
||||
} else
|
||||
if(strcasecmp(cmd, "RESET") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_RESET, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "STOP") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_STOP, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "START") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_START, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "PAUSE") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_PAUSE, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "CONTINUE") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_CONTINUE, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "SPEED") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_SPEED, speedMultiplier, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "DUMP") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_DUMP_MEMORY, virtualMemory, startAddr, (endAddr - startAddr));
|
||||
} else
|
||||
if(strcasecmp(cmd, "HOSTRAM") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_HOST_RAM, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "VIRTRAM") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_VIRTUAL_RAM, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "CPLDCMD") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, CPLD_CMD_SEND_CMD, hexData, 0, 0);
|
||||
} else
|
||||
|
||||
// Test methods, if the code is built-in to the driver.
|
||||
if(strcasecmp(cmd, "Z80TEST") == 0)
|
||||
{
|
||||
z80test(fdZ80);
|
||||
} else
|
||||
if(strcasecmp(cmd, "SPITEST") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, CPLD_CMD_SPI_TEST, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "PRLTEST") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, CPLD_CMD_PRL_TEST, 0, 0, 0);
|
||||
} else
|
||||
if(strcasecmp(cmd, "Z80MEMTEST") == 0)
|
||||
{
|
||||
ctrlCmd(fdZ80, Z80_CMD_MEMORY_TEST, 0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
showArgs(argv[0], &options);
|
||||
printf("No command given, nothing done!\n");
|
||||
}
|
||||
|
||||
// Unmap shared memory and close the device.
|
||||
munmap(Z80Ctrl, sizeof(t_Z80Ctrl));
|
||||
close(fdZ80);
|
||||
|
||||
return(0);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
284
software/FusionX/src/driver/MZ700/z80driver.h
vendored
284
software/FusionX/src/driver/MZ700/z80driver.h
vendored
@@ -1,284 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: z80driver.h
|
||||
// Created: Oct 2022
|
||||
// Author(s): Philip Smart
|
||||
// Description: Z80 Driver
|
||||
// This file contains the declarations used in the z80drv device driver.
|
||||
//
|
||||
// Credits: Zilog Z80 CPU Emulator v0.2 written by Manuel Sainz de Baranda y Goñi
|
||||
// The Z80 CPU Emulator is the heart of this driver and in all ways, is compatible with
|
||||
// the original Z80.
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
// (c) 1999-2022 Manuel Sainz de Baranda y Goñi
|
||||
//
|
||||
// History: Oct 2022 - Initial write of the z80 kernel driver software.
|
||||
//
|
||||
// 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/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef Z80DRIVER_H
|
||||
#define Z80DRIVER_H
|
||||
|
||||
// Constants.
|
||||
#define Z80_VIRTUAL_ROM_SIZE 16384 // Sized to maximum ROM which is the MZ-800 ROM.
|
||||
#define Z80_VIRTUAL_RAM_SIZE (65536 * 8) // (PAGE_SIZE * 2) // max size mmaped to userspace
|
||||
#define Z80_VIRTUAL_MEMORY_SIZE Z80_VIRTUAL_RAM_SIZE + Z80_VIRTUAL_ROM_SIZE
|
||||
#define Z80_MEMORY_PAGE_SIZE 16
|
||||
#define MAX_SCREEN_WIDTH 132
|
||||
#define DEVICE_NAME "z80drv"
|
||||
#define CLASS_NAME "mogu"
|
||||
|
||||
// Memory and IO page types. Used to create a memory page which maps type of address space to real address space on host or virtual memory.
|
||||
#define MEMORY_TYPE_VIRTUAL_MASK 0x00FFFFFF
|
||||
#define MEMORY_TYPE_REAL_MASK 0x0000FFFF
|
||||
#define IO_TYPE_MASK 0x0000FFFF
|
||||
#define MEMORY_TYPE_INHIBIT 0x00000000
|
||||
#define MEMORY_TYPE_PHYSICAL_RAM 0x80000000
|
||||
#define MEMORY_TYPE_PHYSICAL_ROM 0x40000000
|
||||
#define MEMORY_TYPE_PHYSICAL_VRAM 0x20000000
|
||||
#define MEMORY_TYPE_PHYSICAL_HW 0x10000000
|
||||
#define MEMORY_TYPE_VIRTUAL_RAM 0x08000000
|
||||
#define MEMORY_TYPE_VIRTUAL_ROM 0x04000000
|
||||
#define MEMORY_TYPE_VIRTUAL_HW 0x02000000
|
||||
#define IO_TYPE_PHYSICAL_HW 0x80000000
|
||||
#define IO_TYPE_VIRTUAL_HW 0x40000000
|
||||
|
||||
|
||||
// Approximate governor delays to regulate emulated CPU speed.
|
||||
#define MZ700_INSTRUCTION_DELAY_3_54MHZ 253
|
||||
#define MZ700_INSTRUCTION_DELAY_7MHZ 126
|
||||
#define MZ700_INSTRUCTION_DELAY_14MHZ 63
|
||||
#define MZ700_INSTRUCTION_DELAY_28MHZ 32
|
||||
#define MZ700_INSTRUCTION_DELAY_56MHZ 16
|
||||
#define MZ700_INSTRUCTION_DELAY_112MHZ 8
|
||||
#define MZ700_INSTRUCTION_DELAY_224MHZ 4
|
||||
#define MZ700_INSTRUCTION_DELAY_448MHZ 1
|
||||
|
||||
// IOCTL commands. Passed from user space using the IOCTL method to command the driver to perform an action.
|
||||
#define IOCTL_CMD_Z80_STOP 's'
|
||||
#define IOCTL_CMD_Z80_START 'S'
|
||||
#define IOCTL_CMD_Z80_PAUSE 'P'
|
||||
#define IOCTL_CMD_Z80_RESET 'R'
|
||||
#define IOCTL_CMD_Z80_CONTINUE 'C'
|
||||
#define IOCTL_CMD_USE_HOST_RAM 'x'
|
||||
#define IOCTL_CMD_USE_VIRTUAL_RAM 'X'
|
||||
#define IOCTL_CMD_DUMP_MEMORY 'M'
|
||||
#define IOCTL_CMD_Z80_CPU_FREQ 'F'
|
||||
#define IOCTL_CMD_CPLD_CMD 'z'
|
||||
#define IOCTL_CMD_SEND _IOW('c', 'c', int32_t *)
|
||||
#define IOCTL_CMD_SETPC _IOW('p', 'p', int32_t *)
|
||||
#define IOCTL_CMD_SYNC_TO_HOST_RAM 'V'
|
||||
#define IOCTL_CMD_SPI_TEST '1'
|
||||
#define IOCTL_CMD_PRL_TEST '2'
|
||||
#define IOCTL_CMD_Z80_MEMTEST '3'
|
||||
|
||||
|
||||
|
||||
// Chip Select map MZ80K-MZ700.
|
||||
//
|
||||
// 0000 - 0FFF = CS_ROMni : R/W : MZ80K/A/700 = Monitor ROM or RAM (MZ80A rom swap)
|
||||
// 1000 - CFFF = CS_RAMni : R/W : MZ80K/A/700 = RAM
|
||||
// C000 - CFFF = CS_ROMni : R/W : MZ80A = Monitor ROM (MZ80A rom swap)
|
||||
// D000 - D7FF = CS_VRAMni : R/W : MZ80K/A/700 = VRAM
|
||||
// D800 - DFFF = CS_VRAMni : R/W : MZ700 = Colour VRAM (MZ700)
|
||||
// E000 - E003 = CS_8255n : R/W : MZ80K/A/700 = 8255
|
||||
// E004 - E007 = CS_8254n : R/W : MZ80K/A/700 = 8254
|
||||
// E008 - E00B = CS_LS367n : R/W : MZ80K/A/700 = LS367
|
||||
// E00C - E00F = CS_ESWPn : R : MZ80A = Memory Swap (MZ80A)
|
||||
// E010 - E013 = CS_ESWPn : R : MZ80A = Reset Memory Swap (MZ80A)
|
||||
// E014 = CS_E5n : R/W : MZ80A/700 = Normal CRT display (in Video Controller)
|
||||
// E015 = CS_E6n : R/W : MZ80A/700 = Reverse CRT display (in Video Controller)
|
||||
// E200 - E2FF = : R/W : MZ80A/700 = VRAM roll up/roll down.
|
||||
// E800 - EFFF = : R/W : MZ80K/A/700 = User ROM socket or DD Eprom (MZ700)
|
||||
// F000 - F7FF = : R/W : MZ80K/A/700 = Floppy Disk interface.
|
||||
// F800 - FFFF = : R/W : MZ80K/A/700 = Floppy Disk interface.
|
||||
//
|
||||
// Chip Select map MZ800
|
||||
//
|
||||
// FC - FF = CS_PIOn : R/W : MZ800/MZ1500 = Z80 PIO Printer Interface
|
||||
// F2 = CS_PSG0n : W : MZ800/MZ1500 = Programable Sound Generator, MZ-800 = Mono, MZ-1500 = Left Channel
|
||||
// F3 = CS_PSG1n : W : MZ1500 = Programable Sound Generator, MZ-1500 = Right Channel
|
||||
// E9 = CS_PSG(X)n: W : MZ1500 = Simultaneous write to both PSG's.
|
||||
// F0 - F1 = CS_JOYSTK : R : MZ800 = Joystick 1 and 2
|
||||
// CC = CS_GWF : W : MZ800 = CRTC GWF Write format Register
|
||||
// CD = CS_GRF : W : MZ800 = CRTC GRF Read format Register
|
||||
// CE = CS_GDMD : W : MZ800 = CRTC GDMD Mode Register
|
||||
// CF = CS_GCRTC : W : MZ800 = CRTC GCRTC Control Register
|
||||
// D4 - D7 = CS
|
||||
// D000 - DFFF
|
||||
|
||||
// MZ700/MZ800 memory mode switch?
|
||||
//
|
||||
// MZ-700 MZ-800
|
||||
// |0000:0FFF|1000:1FFF|1000:CFFF|C000:CFFF|D000:FFFF |0000:7FFF|1000:1FFF|2000:7FFF|8000:BFFF|C000:CFFF|C000:DFFF|E000:FFFF
|
||||
// -------------------------------------------------- ----------------------------------------------------------------------
|
||||
// OUT 0xE0 = |DRAM | | | | |DRAM | | | | | |
|
||||
// OUT 0xE1 = | | | | |DRAM | | | | | | |DRAM
|
||||
// OUT 0xE2 = |MONITOR | | | | |MONITOR | | | | | |
|
||||
// OUT 0xE3 = | | | | |Memory Mapped I/O | | | | | | |Upper MONITOR ROM
|
||||
// OUT 0xE4 = |MONITOR | |DRAM | |Memory Mapped I/O |MONITOR |CGROM |DRAM |VRAM | |DRAM |Upper MONITOR ROM
|
||||
// OUT 0xE5 = | | | | |Inhibit | | | | | | |Inhibit
|
||||
// OUT 0xE6 = | | | | |<return> | | | | | | |<return>
|
||||
// IN 0xE0 = | |CGROM* | |VRAM* | | |CGROM | |VRAM | | |
|
||||
// IN 0xE1 = | |DRAM | |DRAM | | |<return> | |DRAM | | |
|
||||
//
|
||||
// <return> = Return to the state prior to the complimentary command being invoked.
|
||||
// * = MZ-800 host only.
|
||||
|
||||
// Macros to lookup and test to see if a given memory block or IO byte is of a given type. Also macros to read/write to the memory block and IO byte.
|
||||
#define MEMORY_BLOCK_GRANULARITY 0x800
|
||||
#define MEMORY_BLOCK_SLOTS (0x10000 / MEMORY_BLOCK_GRANULARITY)
|
||||
#define MEMORY_BLOCK_MASK (0x10000 - MEMORY_BLOCK_GRANULARITY)
|
||||
#define MEMORY_BLOCK_SHIFT 11
|
||||
#define getPageData(a) (Z80Ctrl->page[(a & 0xF800) >> MEMORY_BLOCK_SHIFT])
|
||||
#define getIOPageData(a) (Z80Ctrl->iopage[(a & 0xFFFF])
|
||||
#define getPageType(a, mask) (getPageData(a) & mask)
|
||||
#define getPageAddr(a, mask) ((getPageData(a) & mask) + (a & (MEMORY_BLOCK_GRANULARITY-1)))
|
||||
#define getIOPageType(a, mask) (getIOPageData(a) & mask)
|
||||
#define getIOPageAddr(a, mask) (getIOPageData(a) & mask)
|
||||
#define realAddress(a) (Z80Ctrl->page[getPageAddr(a, MEMORY_TYPE_REAL_MASK)])
|
||||
#define realPort(a) (Z80Ctrl->iopage[a & 0xFFFF] & IO_TYPE_MASK)
|
||||
#define isPhysicalRAM(a) (getPageType(a, MEMORY_TYPE_PHYSICAL_RAM))
|
||||
#define isPhysicalVRAM(a) (getPageType(a, MEMORY_TYPE_PHYSICAL_VRAM))
|
||||
#define isPhysicalROM(a) (getPageType(a, MEMORY_TYPE_PHYSICAL_ROM))
|
||||
#define isPhysicalMemory(a) (getPageType(a, (MEMORY_TYPE_PHYSICAL_ROM | MEMORY_TYPE_PHYSICAL_RAM | MEMORY_TYPE_PHYSICAL_VRAM))])
|
||||
#define isPhysicalHW(a) (getPageType(a, MEMORY_TYPE_PHYSICAL_HW))
|
||||
#define isPhysical(a) (getPageType(a, (MEMORY_TYPE_PHYSICAL_HW | MEMORY_TYPE_PHYSICAL_ROM | MEMORY_TYPE_PHYSICAL_RAM | MEMORY_TYPE_PHYSICAL_VRAM)))
|
||||
#define isPhysicalIO(a) (Z80Ctrl->iopage[a & 0xFFFF] & IO_TYPE_PHYSICAL_HW)
|
||||
#define isVirtualRAM(a) (getPageType(a, MEMORY_TYPE_VIRTUAL_RAM))
|
||||
#define isVirtualROM(a) (getPageType(a, MEMORY_TYPE_VIRTUAL_ROM))
|
||||
#define isVirtualMemory(a) (getPageType(a, (MEMORY_TYPE_VIRTUAL_ROM | MEMORY_TYPE_VIRTUAL_RAM)))
|
||||
#define isVirtualHW(a) (getPageType(a, MEMORY_TYPE_VIRTUAL_HW))
|
||||
#define isVirtualIO(a) (Z80Ctrl->iopage[a & 0xFFFF] & IO_TYPE_VIRTUAL_HW)
|
||||
#define isHW(a) (getPageType(a, (MEMORY_TYPE_PHYSICAL_HW | MEMORY_TYPE_VIRTUAL_HW)))
|
||||
#define readVirtualRAM(a) (Z80Ctrl->memory[ getPageAddr(a, MEMORY_TYPE_VIRTUAL_MASK) ])
|
||||
#define readVirtualROM(a) (Z80Ctrl->memory[ getPageAddr(a, MEMORY_TYPE_VIRTUAL_MASK) + Z80_VIRTUAL_RAM_SIZE ])
|
||||
#define writeVirtualRAM(a, d) { Z80Ctrl->memory[ getPageAddr(a, MEMORY_TYPE_VIRTUAL_MASK) ] = d; }
|
||||
#define setMemoryType(_block_,_type_,_addr_) { Z80Ctrl->page[_block_] = _type_ | _addr_; }
|
||||
#define backupMemoryType(_block_) { Z80Ctrl->shadowPage[_block_] = Z80Ctrl->page[_block_]; }
|
||||
#define restoreMemoryType(_block_) { Z80Ctrl->page[_block_] = Z80Ctrl->shadowPage[_block_]; }
|
||||
|
||||
#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
|
||||
|
||||
|
||||
enum Z80_RUN_STATES {
|
||||
Z80_STOP = 0x00,
|
||||
Z80_STOPPED = 0x01,
|
||||
Z80_PAUSE = 0x02,
|
||||
Z80_PAUSED = 0x03,
|
||||
Z80_CONTINUE = 0x04,
|
||||
Z80_RUNNING = 0x05,
|
||||
};
|
||||
enum Z80_MEMORY_PROFILE {
|
||||
USE_PHYSICAL_RAM = 0x00,
|
||||
USE_VIRTUAL_RAM = 0x01
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
// Main memory, linear but indexed as though it were banks in 1K pages.
|
||||
uint8_t memory[Z80_VIRTUAL_MEMORY_SIZE];
|
||||
|
||||
// Page pointer map.
|
||||
//
|
||||
// Each pointer points to a byte or block of bytes in the Z80 Memory frame, 64K Real + Banked.
|
||||
// This is currently set at a block of size 0x800 per memory pointer for the MZ-700.
|
||||
// The LSB of the pointer is a direct memory index to a byte or block of bytes, the upper byte of the pointer indicates type of memory space.
|
||||
// 0x80<FFFFFF> - physical host RAM
|
||||
// 0x40<FFFFFF> - physical host ROM
|
||||
// 0x20<FFFFFF> - physical host VRAM
|
||||
// 0x10<FFFFFF> - physical host hardware
|
||||
// 0x08<FFFFFF> - virtual host RAM
|
||||
// 0x04<FFFFFF> - virtual host ROM
|
||||
// 0x02<FFFFFF> - virtual host hardware
|
||||
// 16bit Input Address -> map -> Pointer to 24bit memory address + type flag.
|
||||
// -> Pointer+<low bits of address> to 24bit memory address + type flag.
|
||||
uint32_t page[MEMORY_BLOCK_SLOTS];
|
||||
uint32_t shadowPage[MEMORY_BLOCK_SLOTS];
|
||||
|
||||
// I/O Page map.
|
||||
//
|
||||
// This is a map to indicate the use of the I/O page and allow any required remapping.
|
||||
// <0x80>FF<I/O Address> - physical host hardware
|
||||
// <0x40>FF<I/O Address> - virtual host hardware
|
||||
// 16bit Input Address -> map -> Actual 16bit address to use + type flag.
|
||||
uint32_t iopage[65536];
|
||||
|
||||
// Default page mode configured. This value reflects the default page and iotable map.
|
||||
uint8_t defaultPageMode;
|
||||
|
||||
// Refresh DRAM mode. 1 = Refresh, 0 = No refresh. Only applicable when running code in virtual Kernel RAM.
|
||||
uint8_t refreshDRAM;
|
||||
|
||||
// Inhibit mode is where certain memory ranges are inhibitted. The memory page is set to inhibit and this flag
|
||||
// blocks actions which arent allowed during inhibit.
|
||||
uint8_t inhibitMode;
|
||||
|
||||
// Address caching. Used to minimise instruction length sent to CPLD.
|
||||
uint16_t z80PrevAddr;
|
||||
uint16_t z80PrevPort;
|
||||
|
||||
// Keyboard strobe and data. Required to detect hotkey press.
|
||||
uint8_t keyportStrobe;
|
||||
uint8_t keyportShiftCtrl;
|
||||
uint8_t keyportHotKey;
|
||||
|
||||
// Governor is the delay in a 32bit loop per Z80 opcode, used to govern execution speed when using virtual memory.
|
||||
// This mechanism will eventually be tied into the M/T-state calculation for a more precise delay, but at the moment,
|
||||
// with the Z80 assigned to an isolated CPU, it allows time sensitive tasks such as the tape recorder to work.
|
||||
// The lower the value the faster the CPU speed.
|
||||
uint32_t cpuGovernorDelay;
|
||||
} t_Z80Ctrl;
|
||||
|
||||
// IOCTL structure for passing data from user space to driver to perform commands.
|
||||
//
|
||||
struct z80_addr {
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
uint32_t size;
|
||||
};
|
||||
struct z80_ctrl {
|
||||
uint16_t pc;
|
||||
};
|
||||
struct speed {
|
||||
uint32_t speedMultiplier;
|
||||
};
|
||||
struct cpld_ctrl {
|
||||
uint32_t cmd;
|
||||
};
|
||||
struct ioctlCmd {
|
||||
int32_t cmd;
|
||||
union {
|
||||
struct z80_addr addr;
|
||||
struct z80_ctrl z80;
|
||||
struct speed speed;
|
||||
struct cpld_ctrl cpld;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
// Prototypes.
|
||||
void setupMemory(enum Z80_MEMORY_PROFILE mode);
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,428 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: z80io.c
|
||||
// Created: Oct 2022
|
||||
// Author(s): Philip Smart
|
||||
// Description: Z80 IO Interface
|
||||
// This file contains the methods used in interfacing the SOM to the Z80 socket
|
||||
// and host hardware via a CPLD.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Oct 2022 - Initial write of the z80 kernel driver software.
|
||||
//
|
||||
// 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 <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <string.h>
|
||||
#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>
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// User space driver access.
|
||||
//
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// Initialise the SOM hardware used to communicate with the z80 socket and host hardware.
|
||||
// The SOM interfaces to a CPLD which provides voltage level translation and also encapsulates the Z80 timing cycles as recreating
|
||||
// them within the SOM is much more tricky.
|
||||
//
|
||||
// As this is an embedded device and performance/latency are priorities, minimal structured code is used to keep call stack and
|
||||
// generated code to a mimimum without relying on the optimiser.
|
||||
int z80io_init(void)
|
||||
{
|
||||
// Locals.
|
||||
int ret = 0;
|
||||
|
||||
// Initialise GPIO. We call the HAL api to minimise time but for actual bit set/reset and read we go directly to registers to save time, increase throughput and minimise latency.
|
||||
// Initialise the HAL.
|
||||
MHal_GPIO_Init();
|
||||
|
||||
// Set the pads as GPIO devices. The HAL takes care of allocating and deallocating the padmux resources.
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_0); // Word (16bit) bidirectional bus. Default is read with data set.
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_1);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_2);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_3);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_4);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_5);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_6);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_7);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_HIGH_BYTE);
|
||||
//MHal_GPIO_Pad_Set(PAD_GPIO8); // SPIO 4wire control lines setup by the spidev driver but controlled directly in this driver.
|
||||
//MHal_GPIO_Pad_Set(PAD_GPIO9);
|
||||
//MHal_GPIO_Pad_Set(PAD_GPIO10);
|
||||
//MHal_GPIO_Pad_Set(PAD_GPIO11);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_READY);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_LTSTATE);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_BUSRQ);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_BUSACK);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_INT);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_NMI);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_WAIT);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_RESET);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_RSV1);
|
||||
#ifdef NOTNEEDED
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_0);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_1);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_2);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_3);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_4);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_5);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_6);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_7);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_WRITE);
|
||||
#endif
|
||||
|
||||
// Set required input pads.
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_0);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_1);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_2);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_3);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_4);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_5);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_6);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_7);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_READY);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_LTSTATE);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_BUSRQ);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_BUSACK);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_INT);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_NMI);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_WAIT);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_RESET);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_RSV1);
|
||||
|
||||
// Set required output pads.
|
||||
#ifdef NOTNEEDED
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_0);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_1);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_2);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_3);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_4);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_5);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_6);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_7);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_WRITE);
|
||||
MHal_GPIO_Pull_High(PAD_Z80IO_WRITE);
|
||||
#endif
|
||||
|
||||
// Control signals.
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_HIGH_BYTE);
|
||||
MHal_GPIO_Pull_High(PAD_Z80IO_HIGH_BYTE);
|
||||
|
||||
// Setup the MSPI0 device.
|
||||
//
|
||||
// Setup control, interrupts are not used.
|
||||
MSPI_WRITE(MSPI_CTRL_OFFSET, MSPI_CPU_CLOCK_1_2 | MSPI_CTRL_CPOL_LOW | MSPI_CTRL_CPHA_HIGH | MSPI_CTRL_RESET | MSPI_CTRL_ENABLE_SPI);
|
||||
|
||||
// Setup LSB First mode.
|
||||
MSPI_WRITE(MSPI_LSB_FIRST_OFFSET, 0x0);
|
||||
|
||||
// Setup clock.
|
||||
CLK_WRITE(MSPI0_CLK_CFG, 0x1100)
|
||||
|
||||
// Setup the frame size (all buffers to 8bits).
|
||||
MSPI_WRITE(MSPI_FRAME_WBIT_OFFSET, 0xfff);
|
||||
MSPI_WRITE(MSPI_FRAME_WBIT_OFFSET+1, 0xfff);
|
||||
MSPI_WRITE(MSPI_FRAME_RBIT_OFFSET, 0xfff);
|
||||
MSPI_WRITE(MSPI_FRAME_RBIT_OFFSET+1, 0xfff);
|
||||
|
||||
// Setup Chip Selects to inactive.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE);
|
||||
|
||||
// Switch Video and Audio to host.
|
||||
z80io_SPI_Send16(0x00f0, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Parallel bus Methods.
|
||||
//--------------------------------------------------------
|
||||
|
||||
// Methods to read data from the parallel bus.
|
||||
// The CPLD returns status and Z80 data on the 8bit bus as it is marginally quicker than retrieving it over the SPI bus.
|
||||
//
|
||||
inline uint8_t z80io_PRL_Read8(uint8_t dataFlag)
|
||||
{
|
||||
// Locals.
|
||||
uint8_t result = 0;
|
||||
|
||||
// Byte according to flag.
|
||||
if(dataFlag)
|
||||
SET_CPLD_READ_DATA()
|
||||
else
|
||||
SET_CPLD_READ_STATUS()
|
||||
|
||||
// Read the input registers and set value accordingly.
|
||||
result = READ_CPLD_DATA_IN();
|
||||
|
||||
// Return 16bit value read from CPLD.
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline uint16_t z80io_PRL_Read16(void)
|
||||
{
|
||||
// Locals.
|
||||
uint16_t result = 0;
|
||||
|
||||
// Low byte first.
|
||||
CLEAR_CPLD_HIGH_BYTE();
|
||||
|
||||
// Read the input registers and set value accordingly.
|
||||
result = (uint16_t)READ_CPLD_DATA_IN();
|
||||
|
||||
// High byte next.
|
||||
SET_CPLD_HIGH_BYTE();
|
||||
|
||||
// Read the input registers and set value accordingly.
|
||||
result |= (uint16_t)(READ_CPLD_DATA_IN() << 8);
|
||||
|
||||
// Return 16bit value read from CPLD.
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
// Parallel Bus methods were tried and tested but due to the GPIO bits being controlled by individual registers per bit, the setup time was longer
|
||||
// than the transmission time of SPI. These methods are thus deprecated and a fusion of SPI and 8bit parallel is now used.
|
||||
#ifdef NOTNEEDED
|
||||
inline uint8_t z80io_PRL_Send8(uint8_t txData)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
|
||||
// Low byte only.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_HIGH_BYTE].r_out) &= (~gpio_table[PAD_Z80IO_HIGH_BYTE ].m_out);
|
||||
|
||||
// Setup data.
|
||||
if(txData & 0x0080) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_7].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_7].m_out); }
|
||||
if(txData & 0x0040) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_6].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_6].m_out); }
|
||||
if(txData & 0x0020) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_5].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_5].m_out); }
|
||||
if(txData & 0x0010) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_4].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_4].m_out); }
|
||||
if(txData & 0x0008) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_3].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_3].m_out); }
|
||||
if(txData & 0x0004) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_2].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_2].m_out); }
|
||||
if(txData & 0x0002) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_1].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_1].m_out); }
|
||||
if(txData & 0x0001) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_0].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_0].m_out); }
|
||||
|
||||
// Clock data.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) &= (~gpio_table[PAD_Z80IO_WRITE ].m_out);
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) |= gpio_table[PAD_Z80IO_WRITE ].m_out;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
inline uint8_t z80io_PRL_Send16(uint16_t txData)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
|
||||
// Low byte first.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_HIGH_BYTE].r_out) &= (~gpio_table[PAD_Z80IO_HIGH_BYTE ].m_out);
|
||||
|
||||
// Setup data.
|
||||
if(txData & 0x0080) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_7].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_7].m_out); }
|
||||
if(txData & 0x0040) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_6].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_6].m_out); }
|
||||
if(txData & 0x0020) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_5].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_5].m_out); }
|
||||
if(txData & 0x0010) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_4].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_4].m_out); }
|
||||
if(txData & 0x0008) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_3].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_3].m_out); }
|
||||
if(txData & 0x0004) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_2].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_2].m_out); }
|
||||
if(txData & 0x0002) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_1].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_1].m_out); }
|
||||
if(txData & 0x0001) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_0].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_0].m_out); }
|
||||
|
||||
// Clock data.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) &= (~gpio_table[PAD_Z80IO_WRITE ].m_out);
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) |= gpio_table[PAD_Z80IO_WRITE ].m_out;
|
||||
|
||||
// High byte next.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_HIGH_BYTE ].r_out) |= gpio_table[PAD_Z80IO_HIGH_BYTE ].m_out;
|
||||
|
||||
// Setup high byte.
|
||||
if(txData & 0x8000) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_7].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_7].m_out); }
|
||||
if(txData & 0x4000) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_6].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_6].m_out); }
|
||||
if(txData & 0x2000) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_5].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_5].m_out); }
|
||||
if(txData & 0x1000) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_4].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_4].m_out); }
|
||||
if(txData & 0x0800) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_3].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_3].m_out); }
|
||||
if(txData & 0x0400) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_2].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_2].m_out); }
|
||||
if(txData & 0x0200) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_1].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_1].m_out); }
|
||||
if(txData & 0x0100) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_0].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_0].m_out); }
|
||||
|
||||
// Clock data.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) &= (~gpio_table[PAD_Z80IO_WRITE ].m_out);
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) |= gpio_table[PAD_Z80IO_WRITE ].m_out;
|
||||
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------------
|
||||
// SPI Methods.
|
||||
//--------------------------------------------------------
|
||||
|
||||
// Methods to send 8,16 or 32 bits. Each method is seperate to minimise logic and execution time, 8bit being most sensitive.
|
||||
// Macros have also been defined for inline inclusion which dont read back the response data.
|
||||
//
|
||||
uint8_t z80io_SPI_Send8(uint8_t txData, uint8_t *rxData)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t timeout = MAX_CHECK_CNT;
|
||||
|
||||
// Insert data into write buffers.
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)txData);
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 1);
|
||||
|
||||
// Enable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE);
|
||||
|
||||
// Send.
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER);
|
||||
|
||||
// Wait for completion.
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0)
|
||||
{
|
||||
if(--timeout == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// Disable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE);
|
||||
|
||||
// Clear flag.
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE);
|
||||
|
||||
// Fetch data.
|
||||
if(rxData != NULL) *rxData = (uint8_t)MSPI_READ(MSPI_FULL_DEPLUX_RD00);
|
||||
|
||||
// Done.
|
||||
return(timeout == 0);
|
||||
}
|
||||
uint8_t z80io_SPI_Send16(uint16_t txData, uint16_t *rxData)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t timeout = MAX_CHECK_CNT;
|
||||
|
||||
// Insert data into write buffers.
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, txData);
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 2);
|
||||
|
||||
// Enable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE);
|
||||
|
||||
// Send.
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER);
|
||||
|
||||
// Wait for completion.
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0)
|
||||
{
|
||||
if(--timeout == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// Disable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE);
|
||||
|
||||
// Clear flag.
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE);
|
||||
|
||||
// Fetch data.
|
||||
if(rxData != NULL) *rxData = MSPI_READ(MSPI_FULL_DEPLUX_RD00);
|
||||
|
||||
// Done.
|
||||
return(timeout == 0);
|
||||
}
|
||||
uint8_t z80io_SPI_Send32(uint32_t txData, uint32_t *rxData)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t timeout = MAX_CHECK_CNT;
|
||||
|
||||
// Insert data into write buffers.
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)txData);
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET+1, (uint16_t)(txData >> 16));
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 4);
|
||||
|
||||
// Enable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE);
|
||||
|
||||
// Send.
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER);
|
||||
|
||||
// Wait for completion.
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0)
|
||||
{
|
||||
if(--timeout == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// Disable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE);
|
||||
|
||||
// Clear flag.
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE);
|
||||
|
||||
// Fetch data.
|
||||
if(rxData != NULL) *rxData = (uint32_t)(MSPI_READ(MSPI_FULL_DEPLUX_RD00) | (MSPI_READ(MSPI_FULL_DEPLUX_RD02) << 16));
|
||||
|
||||
// Done.
|
||||
return(timeout == 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Test Methods.
|
||||
//--------------------------------------------------------
|
||||
#ifdef INCLUDE_TEST_METHODS
|
||||
#include "z80io_test.c"
|
||||
#else
|
||||
uint8_t z80io_Z80_TestMemory(void)
|
||||
{
|
||||
pr_info("Z80 Test Memory functionality not built-in.\n");
|
||||
return(0);
|
||||
}
|
||||
uint8_t z80io_SPI_Test(void)
|
||||
{
|
||||
pr_info("SPI Test functionality not built-in.\n");
|
||||
return(0);
|
||||
}
|
||||
uint8_t z80io_PRL_Test(void)
|
||||
{
|
||||
pr_info("Parallel Bus Test functionality not built-in.\n");
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
483
software/FusionX/src/driver/MZ700/z80io.h
vendored
483
software/FusionX/src/driver/MZ700/z80io.h
vendored
@@ -1,483 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: z80io.h
|
||||
// Created: Oct 2022
|
||||
// Author(s): Philip Smart
|
||||
// Description: Z80 IO Interface
|
||||
// This file contains the declarations used in interfacing the SOM to the Z80 socket
|
||||
// and host hardware via a CPLD.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Oct 2022 - Initial write of the z80 kernel driver software.
|
||||
//
|
||||
// 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/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef Z80IO_H
|
||||
#define Z80IO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Definitions to control compilation.
|
||||
#define INCLUDE_TEST_METHODS 1
|
||||
|
||||
// CPLD Commands.
|
||||
#define CPLD_CMD_FETCH_ADDR 0x10
|
||||
#define CPLD_CMD_FETCH_ADDR_P1 0x11
|
||||
#define CPLD_CMD_FETCH_ADDR_P2 0x12
|
||||
#define CPLD_CMD_FETCH_ADDR_P3 0x13
|
||||
#define CPLD_CMD_FETCH_ADDR_P4 0x14
|
||||
#define CPLD_CMD_FETCH_ADDR_P5 0x15
|
||||
#define CPLD_CMD_FETCH_ADDR_P6 0x16
|
||||
#define CPLD_CMD_FETCH_ADDR_P7 0x17
|
||||
#define CPLD_CMD_WRITE_ADDR 0x18
|
||||
#define CPLD_CMD_WRITE_ADDR_P1 0x19
|
||||
#define CPLD_CMD_WRITE_ADDR_P2 0x1A
|
||||
#define CPLD_CMD_WRITE_ADDR_P3 0x1B
|
||||
#define CPLD_CMD_WRITE_ADDR_P4 0x1C
|
||||
#define CPLD_CMD_WRITE_ADDR_P5 0x1D
|
||||
#define CPLD_CMD_WRITE_ADDR_P6 0x1E
|
||||
#define CPLD_CMD_WRITE_ADDR_P7 0x1F
|
||||
#define CPLD_CMD_READ_ADDR 0x20
|
||||
#define CPLD_CMD_READ_ADDR_P1 0x21
|
||||
#define CPLD_CMD_READ_ADDR_P2 0x22
|
||||
#define CPLD_CMD_READ_ADDR_P3 0x23
|
||||
#define CPLD_CMD_READ_ADDR_P4 0x24
|
||||
#define CPLD_CMD_READ_ADDR_P5 0x25
|
||||
#define CPLD_CMD_READ_ADDR_P6 0x26
|
||||
#define CPLD_CMD_READ_ADDR_P7 0x27
|
||||
#define CPLD_CMD_WRITEIO_ADDR 0x28
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P1 0x29
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P2 0x2A
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P3 0x2B
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P4 0x2C
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P5 0x2D
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P6 0x2E
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P7 0x2F
|
||||
#define CPLD_CMD_READIO_ADDR 0x30
|
||||
#define CPLD_CMD_READIO_ADDR_P1 0x31
|
||||
#define CPLD_CMD_READIO_ADDR_P2 0x32
|
||||
#define CPLD_CMD_READIO_ADDR_P3 0x33
|
||||
#define CPLD_CMD_READIO_ADDR_P4 0x34
|
||||
#define CPLD_CMD_READIO_ADDR_P5 0x35
|
||||
#define CPLD_CMD_READIO_ADDR_P6 0x36
|
||||
#define CPLD_CMD_READIO_ADDR_P7 0x37
|
||||
#define CPLD_CMD_HALT 0x50
|
||||
#define CPLD_CMD_REFRESH 0x51
|
||||
#define CPLD_CMD_SET_SIGROUP1 0xF0
|
||||
#define CPLD_CMD_SET_AUTO_REFRESH 0xF1
|
||||
#define CPLD_CMD_CLEAR_AUTO_REFRESH 0xF2
|
||||
#define CPLD_CMD_SET_SPI_LOOPBACK 0xFE
|
||||
#define CPLD_CMD_NOP1 0x00
|
||||
#define CPLD_CMD_NOP2 0xFF
|
||||
|
||||
|
||||
// Pad numbers for using the MHal GPIO library.
|
||||
#define PAD_Z80IO_IN_DATA_0 PAD_GPIO0
|
||||
#define PAD_Z80IO_IN_DATA_1 PAD_GPIO1
|
||||
#define PAD_Z80IO_IN_DATA_2 PAD_GPIO2
|
||||
#define PAD_Z80IO_IN_DATA_3 PAD_GPIO3
|
||||
#define PAD_Z80IO_IN_DATA_4 PAD_GPIO4
|
||||
#define PAD_Z80IO_IN_DATA_5 PAD_GPIO5
|
||||
#define PAD_Z80IO_IN_DATA_6 PAD_GPIO6
|
||||
#define PAD_Z80IO_IN_DATA_7 PAD_GPIO7
|
||||
#define PAD_SPIO_0 PAD_GPIO8
|
||||
#define PAD_SPIO_1 PAD_GPIO9
|
||||
#define PAD_SPIO_2 PAD_GPIO10
|
||||
#define PAD_SPIO_3 PAD_GPIO11
|
||||
#define PAD_Z80IO_HIGH_BYTE PAD_SAR_GPIO2 // Byte requiured, 0 = Low Byte, 1 = High Byte.
|
||||
#define PAD_Z80IO_READY PAD_GPIO12
|
||||
#define PAD_Z80IO_LTSTATE PAD_PM_IRIN // IRIN
|
||||
#define PAD_Z80IO_BUSRQ PAD_GPIO13
|
||||
#define PAD_Z80IO_BUSACK PAD_GPIO14
|
||||
#define PAD_Z80IO_INT PAD_UART0_RX // GPIO47
|
||||
#define PAD_Z80IO_NMI PAD_UART0_TX // GPIO48
|
||||
#define PAD_Z80IO_WAIT PAD_HSYNC_OUT // GPIO85
|
||||
#define PAD_Z80IO_RESET PAD_VSYNC_OUT // GPIO86
|
||||
#define PAD_Z80IO_RSV1 PAD_SATA_GPIO // GPIO90
|
||||
|
||||
// Physical register addresses.
|
||||
#define PAD_Z80IO_IN_DATA_0_ADDR 0x103C00
|
||||
#define PAD_Z80IO_IN_DATA_1_ADDR 0x103C02
|
||||
#define PAD_Z80IO_IN_DATA_2_ADDR 0x103C04
|
||||
#define PAD_Z80IO_IN_DATA_3_ADDR 0x103C06
|
||||
#define PAD_Z80IO_IN_DATA_4_ADDR 0x103C08
|
||||
#define PAD_Z80IO_IN_DATA_5_ADDR 0x103C0A
|
||||
#define PAD_Z80IO_IN_DATA_6_ADDR 0x103C0C
|
||||
#define PAD_Z80IO_IN_DATA_7_ADDR 0x103C0E
|
||||
#define PAD_SPIO_0_ADDR 0x103C10
|
||||
#define PAD_SPIO_1_ADDR 0x103C12
|
||||
#define PAD_SPIO_2_ADDR 0x103C14
|
||||
#define PAD_SPIO_3_ADDR 0x103C16
|
||||
#define PAD_Z80IO_HIGH_BYTE_ADDR 0x1425
|
||||
#define PAD_Z80IO_READY_ADDR 0x103C18
|
||||
#define PAD_Z80IO_LTSTATE_ADDR 0xF28 // IRIN
|
||||
#define PAD_Z80IO_BUSRQ_ADDR 0x103C1A
|
||||
#define PAD_Z80IO_BUSACK_ADDR 0x103C1C
|
||||
#define PAD_Z80IO_INT_ADDR 0x103C30 // GPIO47
|
||||
#define PAD_Z80IO_NMI_ADDR 0x103C32 // GPIO48
|
||||
#define PAD_Z80IO_WAIT_ADDR 0x103C80 // GPIO85
|
||||
#define PAD_Z80IO_RESET_ADDR 0x103C82 // GPIO86
|
||||
#define PAD_Z80IO_RSV1_ADDR 0x103C8A // GPIO90
|
||||
|
||||
#ifdef NOTNEEDED
|
||||
#define PAD_Z80IO_OUT_DATA_0 PAD_GPIO12
|
||||
#define PAD_Z80IO_OUT_DATA_1 PAD_GPIO13
|
||||
#define PAD_Z80IO_OUT_DATA_2 PAD_GPIO14
|
||||
#define PAD_Z80IO_OUT_DATA_3 PAD_UART0_RX // GPIO47
|
||||
#define PAD_Z80IO_OUT_DATA_4 PAD_UART0_TX // GPIO48
|
||||
#define PAD_Z80IO_OUT_DATA_5 PAD_HSYNC_OUT // GPIO85
|
||||
#define PAD_Z80IO_OUT_DATA_6 PAD_VSYNC_OUT // GPIO86
|
||||
#define PAD_Z80IO_OUT_DATA_7 PAD_SATA_GPIO // GPIO90
|
||||
#define PAD_Z80IO_WRITE PAD_PM_IRIN // Write data clock.
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// The definitions below come from SigmaStar kernel drivers. No header file exists hence the
|
||||
// duplication.
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
#define SUPPORT_SPI_1 0
|
||||
#define MAX_SUPPORT_BITS 16
|
||||
|
||||
#define BANK_TO_ADDR32(b) (b<<9)
|
||||
#define BANK_SIZE 0x200
|
||||
|
||||
#define MS_BASE_REG_RIU_PA 0x1F000000
|
||||
#define gChipBaseAddr 0xFD203C00
|
||||
#define gPmSleepBaseAddr 0xFD001C00
|
||||
#define gSarBaseAddr 0xFD002800
|
||||
#define gRIUBaseAddr 0xFD000000
|
||||
#define gMOVDMAAddr 0xFD201600
|
||||
#define gClkBaseAddr 0xFD207000
|
||||
#define gMspBaseAddr 0xfd222000
|
||||
|
||||
#define MHal_CHIPTOP_REG(addr) (*(volatile U8*)((gChipBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_PM_SLEEP_REG(addr) (*(volatile U8*)((gPmSleepBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_SAR_GPIO_REG(addr) (*(volatile U8*)((gSarBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_RIU_REG(addr) (*(volatile U8*)((gRIUBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
|
||||
|
||||
#define MSPI0_BANK_ADDR 0x1110
|
||||
#define MSPI1_BANK_ADDR 0x1111
|
||||
#define CLK__BANK_ADDR 0x1038
|
||||
#define CHIPTOP_BANK_ADDR 0x101E
|
||||
#define MOVDMA_BANK_ADDR 0x100B
|
||||
|
||||
#define BASE_REG_MSPI0_ADDR MSPI0_BANK_ADDR*0x200 //GET_BASE_ADDR_BY_BANK(IO_ADDRESS(MS_BASE_REG_RIU_PA), 0x111000)
|
||||
#define BASE_REG_MSPI1_ADDR MSPI1_BANK_ADDR*0x200 //GET_BASE_ADDR_BY_BANK(IO_ADDRESS(MS_BASE_REG_RIU_PA), 0x111100)
|
||||
#define BASE_REG_CLK_ADDR CLK__BANK_ADDR*0x200 //GET_BASE_ADDR_BY_BANK(IO_ADDRESS(MS_BASE_REG_RIU_PA), 0x103800)
|
||||
#define BASE_REG_CHIPTOP_ADDR CHIPTOP_BANK_ADDR*0x200 //GET_BASE_ADDR_BY_BANK(IO_ADDRESS(MS_BASE_REG_RIU_PA), 0x101E00)
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Hardware Register Capability
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
#define MSPI_WRITE_BUF_OFFSET 0x40
|
||||
#define MSPI_READ_BUF_OFFSET 0x44
|
||||
#define MSPI_WBF_SIZE_OFFSET 0x48
|
||||
#define MSPI_RBF_SIZE_OFFSET 0x48
|
||||
// read/ write buffer size
|
||||
#define MSPI_RWSIZE_MASK 0xFF
|
||||
#define MSPI_RSIZE_BIT_OFFSET 0x8
|
||||
#define MAX_READ_BUF_SIZE 0x8
|
||||
#define MAX_WRITE_BUF_SIZE 0x8
|
||||
// CLK config
|
||||
#define MSPI_CTRL_OFFSET 0x49
|
||||
#define MSPI_CLK_CLOCK_OFFSET 0x49
|
||||
#define MSPI_CLK_CLOCK_BIT_OFFSET 0x08
|
||||
#define MSPI_CLK_CLOCK_MASK 0xFF
|
||||
#define MSPI_CLK_PHASE_MASK 0x40
|
||||
#define MSPI_CLK_PHASE_BIT_OFFSET 0x06
|
||||
#define MSPI_CLK_POLARITY_MASK 0x80
|
||||
#define MSPI_CLK_POLARITY_BIT_OFFSET 0x07
|
||||
#define MSPI_CLK_PHASE_MAX 0x1
|
||||
#define MSPI_CLK_POLARITY_MAX 0x1
|
||||
#define MSPI_CLK_CLOCK_MAX 0x7
|
||||
#define MSPI_CTRL_CPOL_LOW 0x00
|
||||
#define MSPI_CTRL_CPOL_HIGH 0x80
|
||||
#define MSPI_CTRL_CPHA_LOW 0x00
|
||||
#define MSPI_CTRL_CPHA_HIGH 0x40
|
||||
#define MSPI_CTRL_3WIRE 0x10
|
||||
#define MSPI_CTRL_INTEN 0x04
|
||||
#define MSPI_CTRL_RESET 0x02
|
||||
#define MSPI_CTRL_ENABLE_SPI 0x01
|
||||
// DC config
|
||||
#define MSPI_DC_MASK 0xFF
|
||||
#define MSPI_DC_BIT_OFFSET 0x08
|
||||
#define MSPI_DC_TR_START_OFFSET 0x4A
|
||||
#define MSPI_DC_TRSTART_MAX 0xFF
|
||||
#define MSPI_DC_TR_END_OFFSET 0x4A
|
||||
#define MSPI_DC_TREND_MAX 0xFF
|
||||
#define MSPI_DC_TB_OFFSET 0x4B
|
||||
#define MSPI_DC_TB_MAX 0xFF
|
||||
#define MSPI_DC_TRW_OFFSET 0x4B
|
||||
#define MSPI_DC_TRW_MAX 0xFF
|
||||
// Frame Config
|
||||
#define MSPI_FRAME_WBIT_OFFSET 0x4C
|
||||
#define MSPI_FRAME_RBIT_OFFSET 0x4E
|
||||
#define MSPI_FRAME_BIT_MAX 0x07
|
||||
#define MSPI_FRAME_BIT_MASK 0x07
|
||||
#define MSPI_FRAME_BIT_FIELD 0x03
|
||||
#define MSPI_LSB_FIRST_OFFSET 0x50
|
||||
#define MSPI_TRIGGER_OFFSET 0x5A
|
||||
#define MSPI_DONE_OFFSET 0x5B
|
||||
#define MSPI_DONE_CLEAR_OFFSET 0x5C
|
||||
#define MSPI_CHIP_SELECT_OFFSET 0x5F
|
||||
#define MSPI_CS1_DISABLE 0x01
|
||||
#define MSPI_CS1_ENABLE 0x00
|
||||
#define MSPI_CS2_DISABLE 0x02
|
||||
#define MSPI_CS2_ENABLE 0x00
|
||||
#define MSPI_CS3_DISABLE 0x04
|
||||
#define MSPI_CS3_ENABLE 0x00
|
||||
#define MSPI_CS4_DISABLE 0x08
|
||||
#define MSPI_CS4_ENABLE 0x00
|
||||
#define MSPI_CS5_DISABLE 0x10
|
||||
#define MSPI_CS5_ENABLE 0x00
|
||||
#define MSPI_CS6_DISABLE 0x20
|
||||
#define MSPI_CS6_ENABLE 0x00
|
||||
#define MSPI_CS7_DISABLE 0x40
|
||||
#define MSPI_CS7_ENABLE 0x00
|
||||
#define MSPI_CS8_DISABLE 0x80
|
||||
#define MSPI_CS8_ENABLE 0x00
|
||||
|
||||
#define MSPI_FULL_DEPLUX_RD_CNT (0x77)
|
||||
#define MSPI_FULL_DEPLUX_RD00 (0x78)
|
||||
#define MSPI_FULL_DEPLUX_RD01 (0x78)
|
||||
#define MSPI_FULL_DEPLUX_RD02 (0x79)
|
||||
#define MSPI_FULL_DEPLUX_RD03 (0x79)
|
||||
#define MSPI_FULL_DEPLUX_RD04 (0x7a)
|
||||
#define MSPI_FULL_DEPLUX_RD05 (0x7a)
|
||||
#define MSPI_FULL_DEPLUX_RD06 (0x7b)
|
||||
#define MSPI_FULL_DEPLUX_RD07 (0x7b)
|
||||
|
||||
#define MSPI_FULL_DEPLUX_RD08 (0x7c)
|
||||
#define MSPI_FULL_DEPLUX_RD09 (0x7c)
|
||||
#define MSPI_FULL_DEPLUX_RD10 (0x7d)
|
||||
#define MSPI_FULL_DEPLUX_RD11 (0x7d)
|
||||
#define MSPI_FULL_DEPLUX_RD12 (0x7e)
|
||||
#define MSPI_FULL_DEPLUX_RD13 (0x7e)
|
||||
#define MSPI_FULL_DEPLUX_RD14 (0x7f)
|
||||
#define MSPI_FULL_DEPLUX_RD15 (0x7f)
|
||||
|
||||
//chip select bit map
|
||||
#define MSPI_CHIP_SELECT_MAX 0x07
|
||||
|
||||
// control bit
|
||||
#define MSPI_DONE_FLAG 0x01
|
||||
#define MSPI_TRIGGER 0x01
|
||||
#define MSPI_CLEAR_DONE 0x01
|
||||
#define MSPI_INT_ENABLE 0x04
|
||||
#define MSPI_RESET 0x02
|
||||
#define MSPI_ENABLE 0x01
|
||||
|
||||
// clk_mspi0
|
||||
#define MSPI0_CLK_CFG 0x33 //bit 2 ~bit 3
|
||||
#define MSPI0_CLK_108M 0x00
|
||||
#define MSPI0_CLK_54M 0x04
|
||||
#define MSPI0_CLK_12M 0x08
|
||||
#define MSPI0_CLK_MASK 0x0F
|
||||
|
||||
// clk_mspi1
|
||||
#define MSPI1_CLK_CFG 0x33 //bit 10 ~bit 11
|
||||
#define MSPI1_CLK_108M 0x0000
|
||||
#define MSPI1_CLK_54M 0x0400
|
||||
#define MSPI1_CLK_12M 0x0800
|
||||
#define MSPI1_CLK_MASK 0x0F00
|
||||
|
||||
// clk_mspi
|
||||
#define MSPI_CLK_CFG 0x33
|
||||
#define MSPI_SELECT_0 0x0000
|
||||
#define MSPI_SELECT_1 0x4000
|
||||
#define MSPI_CLK_MASK 0xF000
|
||||
|
||||
// Clock settings
|
||||
#define MSPI_CPU_CLOCK_1_2 0x0000
|
||||
#define MSPI_CPU_CLOCK_1_4 0x0100
|
||||
#define MSPI_CPU_CLOCK_1_8 0x0200
|
||||
#define MSPI_CPU_CLOCK_1_16 0x0300
|
||||
#define MSPI_CPU_CLOCK_1_32 0x0400
|
||||
#define MSPI_CPU_CLOCK_1_64 0x0500
|
||||
#define MSPI_CPU_CLOCK_1_128 0x0600
|
||||
#define MSPI_CPU_CLOCK_1_256 0x0700
|
||||
|
||||
//CHITOP 101E mspi mode select
|
||||
#define MSPI0_MODE 0x0C //bit0~bit1
|
||||
#define MSPI0_MODE_MASK 0x07
|
||||
#define MSPI1_MODE 0x0C //bit4~bit5
|
||||
#define MSPI1_MODE_MASK 0x70
|
||||
#define EJTAG_MODE 0xF
|
||||
#define EJTAG_MODE_1 0x01
|
||||
#define EJTAG_MODE_2 0x02
|
||||
#define EJTAG_MODE_3 0x03
|
||||
#define EJTAG_MODE_MASK 0x03
|
||||
|
||||
//MOVDMA 100B
|
||||
#define MOV_DMA_SRC_ADDR_L 0x03
|
||||
#define MOV_DMA_SRC_ADDR_H 0x04
|
||||
#define MOV_DMA_DST_ADDR_L 0x05
|
||||
#define MOV_DMA_DST_ADDR_H 0x06
|
||||
#define MOV_DMA_BYTE_CNT_L 0x07
|
||||
#define MOV_DMA_BYTE_CNT_H 0x08
|
||||
#define DMA_MOVE0_IRQ_CLR 0x28
|
||||
#define MOV_DMA_IRQ_FINAL_STATUS 0x2A
|
||||
#define DMA_MOVE0_ENABLE 0x00
|
||||
#define DMA_RW 0x50 //0 for dma write to device, 1 for dma read from device
|
||||
#define DMA_READ 0x01
|
||||
#define DMA_WRITE 0x00
|
||||
#define DMA_DEVICE_MODE 0x51
|
||||
#define DMA_DEVICE_SEL 0x52
|
||||
|
||||
//spi dma
|
||||
#define MSPI_DMA_DATA_LENGTH_L 0x30
|
||||
#define MSPI_DMA_DATA_LENGTH_H 0x31
|
||||
#define MSPI_DMA_ENABLE 0x32
|
||||
#define MSPI_DMA_RW_MODE 0x33
|
||||
#define MSPI_DMA_WRITE 0x00
|
||||
#define MSPI_DMA_READ 0x01
|
||||
|
||||
#define MSTAR_SPI_TIMEOUT_MS 30000
|
||||
#define MSTAR_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA /*| SPI_CS_HIGH | SPI_NO_CS | SPI_LSB_FIRST*/)
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Macros
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#define MHal_CHIPTOP_REG(addr) (*(volatile U8*)((gChipBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_PM_SLEEP_REG(addr) (*(volatile U8*)((gPmSleepBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_SAR_GPIO_REG(addr) (*(volatile U8*)((gSarBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_RIU_REG(addr) (*(volatile U8*)((gRIUBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define READ_BYTE(_reg) (*(volatile u8*)(_reg))
|
||||
#define READ_WORD(_reg) (*(volatile u16*)(_reg))
|
||||
#define READ_LONG(_reg) (*(volatile u32*)(_reg))
|
||||
#define WRITE_BYTE(_reg, _val) {(*((volatile u8*)(_reg))) = (u8)(_val); }
|
||||
#define WRITE_WORD(_reg, _val) {(*((volatile u16*)(_reg))) = (u16)(_val); }
|
||||
#define WRITE_LONG(_reg, _val) {(*((volatile u32*)(_reg))) = (u32)(_val); }
|
||||
#define WRITE_WORD_MASK(_reg, _val, _mask) {(*((volatile u16*)(_reg))) = ((*((volatile u16*)(_reg))) & ~(_mask)) | ((u16)(_val) & (_mask)); }
|
||||
#define READ_CPLD_DATA_IN() ((MHal_RIU_REG(PAD_Z80IO_IN_DATA_7_ADDR) & 0x1) << 7 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_6_ADDR) & 0x1) << 6 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_5_ADDR) & 0x1) << 5 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_4_ADDR) & 0x1) << 4 |\
|
||||
(MHal_RIU_REG(PAD_Z80IO_IN_DATA_3_ADDR) & 0x1) << 3 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_2_ADDR) & 0x1) << 2 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_1_ADDR) & 0x1) << 1 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_0_ADDR) & 0x1))
|
||||
#define SET_CPLD_READ_DATA() {MHal_RIU_REG(PAD_Z80IO_HIGH_BYTE_ADDR) |= 0x4;}
|
||||
#define SET_CPLD_READ_STATUS() {MHal_RIU_REG(PAD_Z80IO_HIGH_BYTE_ADDR) &= ~0x4;}
|
||||
#define SET_CPLD_HIGH_BYTE() {MHal_RIU_REG(PAD_Z80IO_HIGH_BYTE_ADDR) |= 0x4;}
|
||||
#define CLEAR_CPLD_HIGH_BYTE() {MHal_RIU_REG(PAD_Z80IO_HIGH_BYTE_ADDR) &= ~0x4;}
|
||||
#define CPLD_READY() (MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1)
|
||||
#define CPLD_RESET() (MHal_RIU_REG(PAD_Z80IO_RESET_ADDR) & 0x1)
|
||||
#define CPLD_LAST_TSTATE() (MHal_RIU_REG(PAD_Z80IO_LTSTATE_ADDR) & 0x4)
|
||||
#define SPI_SEND8(_d_) { uint32_t timeout = MAX_CHECK_CNT; \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)(_d_)); \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 1); \
|
||||
while((MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1) == 0);\
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE);\
|
||||
}
|
||||
#define SPI_SEND16(_d_) { uint32_t timeout = MAX_CHECK_CNT; \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)(_d_)); \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 2); \
|
||||
while((MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1) == 0);\
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE); \
|
||||
}
|
||||
#define SPI_SEND32(_d_) { uint32_t timeout = MAX_CHECK_CNT; \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)(_d_)); \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET+1, (uint16_t)((_d_) >> 16)); \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 4); \
|
||||
while((MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1) == 0);\
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE); \
|
||||
}
|
||||
|
||||
// read 2 byte
|
||||
#define MSPI_READ(_reg_) READ_WORD(gMspBaseAddr + ((_reg_)<<2))
|
||||
// write 2 byte
|
||||
//#define MSPI_WRITE(_reg_, _val_) {pr_info("PDS: MSPI_WRITE(0x%x, 0x%x, 0x%x)\n", _reg_, _val_, gMspBaseAddr + ((_reg_)<<2)); WRITE_WORD(gMspBaseAddr + ((_reg_)<<2), (_val_)); }
|
||||
#define MSPI_WRITE(_reg_, _val_) WRITE_WORD(gMspBaseAddr + ((_reg_)<<2), (_val_));
|
||||
//write 2 byte mask
|
||||
//#define MSPI_WRITE_MASK(_reg_, _val_, mask) {pr_info("PDS: WRITE_LONG(0x%x, 0x%x, mask=0x%x)\n", _reg_, _val_, mask); WRITE_WORD_MASK(gMspBaseAddr + ((_reg_)<<2), (_val_), (mask)); }
|
||||
#define MSPI_WRITE_MASK(_reg_, _val_, mask) WRITE_WORD_MASK(gMspBaseAddr + ((_reg_)<<2), (_val_), (mask));
|
||||
|
||||
#define CLK_READ(_reg_) READ_WORD(gClkBaseAddr + ((_reg_)<<2))
|
||||
//#define CLK_WRITE(_reg_, _val_) {pr_info("PDS: CLK_WRITE(0x%x, 0x%x)\n", _reg_, _val_); WRITE_WORD(gClkBaseAddr + ((_reg_)<<2), (_val_)); }
|
||||
#define CLK_WRITE(_reg_, _val_) WRITE_WORD(gClkBaseAddr + ((_reg_)<<2), (_val_));
|
||||
|
||||
#define CHIPTOP_READ(_reg_) READ_WORD(gChipBaseAddr + ((_reg_)<<2))
|
||||
//#define CHIPTOP_WRITE(_reg_, _val_) {pr_info("PDS: CHIPTOP_WRITE(0x%x, 0x%x)\n", _reg_, _val_); WRITE_WORD(gChipBaseAddr + ((_reg_)<<2), (_val_)); }
|
||||
#define CHIPTOP_WRITE(_reg_, _val_) WRITE_WORD(gChipBaseAddr + ((_reg_)<<2), (_val_));
|
||||
|
||||
#define MOVDMA_READ(_reg_) READ_WORD(gMOVDMAAddr + ((_reg_)<<2))
|
||||
//#define MOVDMA_WRITE(_reg_, _val_) {pr_info("PDS: MOVDMA_WRITE(0x%x, 0x%x)\n", _reg_, _val_); WRITE_WORD(gMOVDMAAddr + ((_reg_)<<2), (_val_)); }
|
||||
#define MOVDMA_WRITE(_reg_, _val_) WRITE_WORD(gMOVDMAAddr + ((_reg_)<<2), (_val_));
|
||||
|
||||
#define _HAL_MSPI_ClearDone() MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET,MSPI_CLEAR_DONE)
|
||||
#define MAX_CHECK_CNT 2000
|
||||
|
||||
#define MSPI_READ_INDEX 0x0
|
||||
#define MSPI_WRITE_INDEX 0x1
|
||||
|
||||
#define SPI_MIU0_BUS_BASE 0x20000000
|
||||
#define SPI_MIU1_BUS_BASE 0xFFFFFFFF
|
||||
|
||||
|
||||
// Function definitions.
|
||||
//
|
||||
int z80io_init(void);
|
||||
uint8_t z80io_SPI_Send8(uint8_t txData, uint8_t *rxData);
|
||||
uint8_t z80io_SPI_Send16(uint16_t txData, uint16_t *rxData);
|
||||
uint8_t z80io_SPI_Send32(uint32_t txData, uint32_t *rxData);
|
||||
#ifdef NOTNEEDED
|
||||
uint8_t z80io_PRL_Send8(uint8_t txData);
|
||||
uint8_t z680io_PRL_Send16(uint16_t txData);
|
||||
#endif
|
||||
uint8_t z80io_PRL_Read8(uint8_t dataFlag);
|
||||
uint16_t z80io_PRL_Read16(void);
|
||||
uint8_t z80io_SPI_Test(void);
|
||||
uint8_t z80io_PRL_Test(void);
|
||||
uint8_t z80io_Z80_TestMemory(void);
|
||||
|
||||
extern void MHal_GPIO_Init(void);
|
||||
extern void MHal_GPIO_Pad_Set(uint8_t u8IndexGPIO);
|
||||
extern int MHal_GPIO_PadGroupMode_Set(uint32_t u32PadMode);
|
||||
extern int MHal_GPIO_PadVal_Set(uint8_t u8IndexGPIO, uint32_t u32PadMode);
|
||||
extern void MHal_GPIO_Pad_Oen(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Pad_Odn(uint8_t u8IndexGPIO);
|
||||
extern uint8_t MHal_GPIO_Pad_Level(uint8_t u8IndexGPIO);
|
||||
extern uint8_t MHal_GPIO_Pad_InOut(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Pull_High(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Pull_Low(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Set_High(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Set_Low(uint8_t u8IndexGPIO);
|
||||
extern void MHal_Enable_GPIO_INT(uint8_t u8IndexGPIO);
|
||||
extern int MHal_GPIO_To_Irq(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Set_POLARITY(uint8_t u8IndexGPIO, uint8_t reverse);
|
||||
extern void MHal_GPIO_Set_Driving(uint8_t u8IndexGPIO, uint8_t setHigh);
|
||||
extern void MHal_GPIO_PAD_32K_OUT(uint8_t u8Enable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // Z80IO_H
|
||||
@@ -1,57 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: z80menu.c
|
||||
// Created: Oct 2022
|
||||
// Author(s): Philip Smart
|
||||
// Description: Z80 User Menu
|
||||
// This file contains the methods used to present a menu of options to a user to aid
|
||||
// in configuration and load/save of applications and data.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Oct 2022 - Initial write of the z80 kernel driver software.
|
||||
//
|
||||
// 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 "z80menu.h"
|
||||
|
||||
#include <gpio_table.h>
|
||||
#include <asm/io.h>
|
||||
#include <infinity2m/gpio.h>
|
||||
#include <infinity2m/registers.h>
|
||||
|
||||
void z80menu(void)
|
||||
{
|
||||
// Locals.
|
||||
|
||||
}
|
||||
44
software/FusionX/src/driver/MZ700/z80menu.h
vendored
44
software/FusionX/src/driver/MZ700/z80menu.h
vendored
@@ -1,44 +0,0 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: z80menu.h
|
||||
// Created: Oct 2022
|
||||
// Author(s): Philip Smart
|
||||
// Description: Z80 User Interface Menu
|
||||
// This file contains the declarations required to provide a menu system allowing a
|
||||
// user to configure and load/save applications/data.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2022 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Oct 2022 - Initial write of the z80 kernel driver software.
|
||||
//
|
||||
// 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/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef Z80MENU_H
|
||||
#define Z80MENU_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Function definitions.
|
||||
//
|
||||
void z80menu(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // Z80MENU_H
|
||||
32
software/FusionX/src/driver/Makefile
vendored
32
software/FusionX/src/driver/Makefile
vendored
@@ -1,32 +0,0 @@
|
||||
MODEL := MZ2000
|
||||
#MODEL := MZ700
|
||||
#MODEL := MZ80A
|
||||
KERNEL := $(PWD)/../../../linux/kernel
|
||||
FUSIONX := $(PWD)/../..
|
||||
CROSS := arm-linux-gnueabihf-
|
||||
ccflags-y += -O2 -I${src}/Zeta/API -I${src}/Z80/API -I${KERNEL}/drivers/sstar/include -I${KERNEL}/drivers/sstar/include/infinity2m -I${KERNEL}/drivers/sstar/gpio/infinity2m
|
||||
CTRLINC += -IZeta/API -IZ80/API
|
||||
|
||||
obj-m += z80drv.o
|
||||
z80drv-objs += $(MODEL)/z80driver.o Z80.o $(MODEL)/z80io.o $(MODEL)/z80menu.o # emumz.o sharpmz.o osd.o
|
||||
z80drv-objs += ../../../linux/kernel/drivers/sstar/gpio/infinity2m/gpio_table.o
|
||||
z80drv-objs += ../../../linux/kernel/drivers/sstar/gpio/infinity2m/mhal_gpio.o
|
||||
z80drv-objs += ../../../linux/kernel/drivers/sstar/gpio/infinity2m/mhal_pinmux.o
|
||||
z80drv-objs += ../../../linux/kernel/drivers/sstar/gpio/infinity2m/padmux_tables.o
|
||||
|
||||
|
||||
all:
|
||||
@echo "Build driver for host: $(MODEL)"
|
||||
@echo ""
|
||||
make -C $(KERNEL) ARCH=arm CROSS_COMPILE=$(CROSS) M="$(PWD)" modules
|
||||
$(CROSS)gcc $(CTRLINC) $(MODEL)/z80ctrl.c -o z80ctrl
|
||||
|
||||
install:
|
||||
@echo "Copy kernel driver..."
|
||||
@cp z80drv.ko $(FUSIONX)/modules/
|
||||
@echo "Copy z80ctrl app..."
|
||||
@cp z80ctrl $(FUSIONX)/bin/
|
||||
|
||||
clean:
|
||||
make -C $(KERNEL) M=$(PWD) clean
|
||||
|
||||
23
software/FusionX/src/driver/README.txt
vendored
23
software/FusionX/src/driver/README.txt
vendored
@@ -1,23 +0,0 @@
|
||||
Development Cycle
|
||||
-----------------
|
||||
|
||||
To avoid changes for one host affecting another the driver is split into seperate hosts containing almost identical code.
|
||||
The idea, after development is complete, is to merge them into a single drive which autodetects, via the CPLD, the host model
|
||||
and selects the code accordingly.
|
||||
|
||||
Please edit Makefile and set the model prior to changing the Model source. In theory this file will be deleted once the source is
|
||||
merged.
|
||||
|
||||
Zeta
|
||||
----
|
||||
The Zeta library includes spaces in the naming of certain header files and directories. The linux kernel module build system kbuild
|
||||
cant work with spaces, at least I have found no work around, so after making a submodule pull on Zeta you need to manually rename or edit the files, ie:
|
||||
|
||||
Manually rename the files:
|
||||
mv Zeta/API/Z/inspection/data\ model Zeta/API/Z/inspection/data_model
|
||||
mv Zeta/API/Z/formats/data\ model Zeta/API/Z/formats/data_model
|
||||
mv Zeta/API/Z/keys/data\ model.h Zeta/API/Z/keys/data_model.h
|
||||
|
||||
Edit the files and change 'data model' to data_mode
|
||||
vi Zeta/API/Z/types/integral.h
|
||||
vi Zeta/API/Z/inspection/data_model.h
|
||||
1
software/FusionX/src/driver/Z80
vendored
1
software/FusionX/src/driver/Z80
vendored
Submodule software/FusionX/src/driver/Z80 deleted from 75d01a9cca
1
software/FusionX/src/driver/Zeta
vendored
1
software/FusionX/src/driver/Zeta
vendored
Submodule software/FusionX/src/driver/Zeta deleted from fb257eb6c0
4
software/FusionX/src/spitools/Makefile
vendored
4
software/FusionX/src/spitools/Makefile
vendored
@@ -42,8 +42,8 @@ ARCH := arm
|
||||
|
||||
#Compilers
|
||||
ifeq ($(ARCH),arm)
|
||||
CPP := /opt/gcc-arm-eabihf/bin/arm-linux-gnueabihf-g++
|
||||
CC := /opt/gcc-arm-eabihf/bin/arm-linux-gnueabihf-gcc
|
||||
CPP := arm-linux-gnueabihf-g++
|
||||
CC := arm-linux-gnueabihf-gcc
|
||||
else
|
||||
CPP := g++
|
||||
CC := gcc
|
||||
|
||||
BIN
software/FusionX/src/spitools/mspi_main
vendored
BIN
software/FusionX/src/spitools/mspi_main
vendored
Binary file not shown.
66
software/FusionX/src/ttymz/Makefile
vendored
Normal file
66
software/FusionX/src/ttymz/Makefile
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
# Select the target host.
|
||||
#MODEL := MZ2000
|
||||
#MODEL := MZ1500
|
||||
#MODEL := MZ700
|
||||
#MODEL := MZ80A
|
||||
#MODEL := PCW8XXX
|
||||
#MODEL := PCW9XXX
|
||||
KERNEL := $(PWD)/../../../linux/kernel
|
||||
FUSIONX := $(PWD)/../..
|
||||
CROSS := arm-linux-gnueabihf-
|
||||
CTRLINC = -IZeta/API -IZ80/API -DTARGET_HOST_$(MODEL)=1
|
||||
|
||||
ccflags-y = -O2 -I${KERNEL}/drivers/sstar/include -I${KERNEL}/drivers/sstar/include/infinity2m -I${KERNEL}/drivers/sstar/gpio/infinity2m -D__KERNEL_DRIVER__ -DTARGET_HOST_$(MODEL)=1 -Wno-error
|
||||
ifeq ($(DEBUG),y)
|
||||
ccflags-y += -DTTYMZ_DEBUG
|
||||
endif
|
||||
obj-m += ttymzdrv.o
|
||||
ttymzdrv-objs += ttymz.o z80io.o sharpmz.o
|
||||
ttymzdrv-objs += ../../../linux/kernel/drivers/sstar/gpio/infinity2m/gpio_table.o
|
||||
ttymzdrv-objs += ../../../linux/kernel/drivers/sstar/gpio/infinity2m/mhal_gpio.o
|
||||
ttymzdrv-objs += ../../../linux/kernel/drivers/sstar/gpio/infinity2m/mhal_pinmux.o
|
||||
ttymzdrv-objs += ../../../linux/kernel/drivers/sstar/gpio/infinity2m/padmux_tables.o
|
||||
|
||||
all:
|
||||
@echo "Specify target host, ie. make <host>"
|
||||
@echo "Supported hosts: MZ80A, MZ700, MZ2000, PCW8XXX, PCW9XXX"
|
||||
|
||||
MZ80A: MODEL_MZ80A
|
||||
MZ700: MODEL_MZ700
|
||||
MZ1500: MODEL_MZ1500
|
||||
MZ2000: MODEL_MZ2000
|
||||
PCW8XXX: MODEL_PCW8XXX
|
||||
PCW9XXX: MODEL_PCW9XXX
|
||||
|
||||
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:
|
||||
$(MAKE) MODEL=PCW8XXX BUILD_PCW8XXX
|
||||
MODEL_PCW9XXX:
|
||||
$(MAKE) MODEL=PCW8XXX BUILD_PCW9XXX
|
||||
|
||||
BUILD_MZ80A: kmod
|
||||
BUILD_MZ700: kmod
|
||||
BUILD_MZ1500: kmod
|
||||
BUILD_MZ2000: kmod
|
||||
BUILD_PCW8XXX: kmod
|
||||
BUILD_PCW9XXX: kmod
|
||||
|
||||
kmod:
|
||||
@echo ""
|
||||
@echo "Build TTYMZ driver for host: $(MODEL)"
|
||||
make -C $(KERNEL) ARCH=arm CROSS_COMPILE=$(CROSS) M="$(PWD)" modules
|
||||
|
||||
install:
|
||||
@echo "Copy kernel driver..."
|
||||
@cp ttymzdrv.ko $(FUSIONX)/modules/
|
||||
|
||||
clean:
|
||||
make -C $(KERNEL) M=$(PWD) clean
|
||||
@rm -f ttymz
|
||||
4687
software/FusionX/src/ttymz/sharpmz.c
Normal file
4687
software/FusionX/src/ttymz/sharpmz.c
Normal file
File diff suppressed because it is too large
Load Diff
593
software/FusionX/src/ttymz/sharpmz.h
vendored
Executable file
593
software/FusionX/src/ttymz/sharpmz.h
vendored
Executable file
@@ -0,0 +1,593 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: sharpmz.c
|
||||
// Created: February 2023
|
||||
// Version: v1.0
|
||||
// Author(s): Philip Smart
|
||||
// Description: Sharp MZ Interface Library.
|
||||
// This file contains methods which allow the Linux TTY driver to access and control the
|
||||
// Sharp MZ series computer hardware.
|
||||
//
|
||||
// Credits:
|
||||
// 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.
|
||||
// v1.2 Jul 2023 - Fixed MZ-1500 ATB Display of lower case characters.
|
||||
//
|
||||
// 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/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef SHARPMZ_H
|
||||
#define SHARPMZ_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Build time target. Overrides if compile time definition given.
|
||||
#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_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_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 || 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.
|
||||
#endif
|
||||
#define VC_MAX_BUFFER_ROWS 50 // Maximum number of backing store rows for scrollback feature.
|
||||
#define VC_DISPLAY_BUFFER_SIZE VC_MAX_COLUMNS * VC_MAX_BUFFER_ROWS // Size of the display buffer for scrollback.
|
||||
|
||||
// Keyboard constants.
|
||||
#define KEYB_AUTOREPEAT_INITIAL_TIME 800 // Time in milliseconds before starting autorepeat.
|
||||
#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 || 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 0xD0 // Block cursor for CAPS Lock.
|
||||
#define CURSOR_CHR_GRAPH 0xFF // Graphic cursor for GRAPH mode.
|
||||
#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.
|
||||
#define CURSOR_CHR_BLOCK 0x82 // Block cursor for CAPS Lock.
|
||||
#define CURSOR_CHR_GRAPH 0x93 // Graphic cursor for GRAPH mode.
|
||||
#define CURSOR_CHR_UNDERLINE 0x1F // Underline for lower case CAPS OFF.
|
||||
#endif
|
||||
|
||||
// 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.
|
||||
#define VIDEO_VRAM_BASE_ADDR VIDEO_BASE_ADDR + 0x00D000 // Base address of the character video RAM using direct addressing.
|
||||
#define VIDEO_VRAM_SIZE 0x800 // Size of the video RAM.
|
||||
#define VIDEO_ARAM_BASE_ADDR VIDEO_BASE_ADDR + 0x00D800 // Base address of the character attribute RAM using direct addressing.
|
||||
#define VIDEO_ARAM_SIZE 0x800 // Size of the attribute RAM.
|
||||
|
||||
// Video Module control bits.
|
||||
#define VMMODE_MASK 0xF8 // Mask to mask out video mode.
|
||||
#define VMMODE_MZ80K 0x00 // Video mode = MZ80K
|
||||
#define VMMODE_MZ80C 0x01 // Video mode = MZ80C
|
||||
#define VMMODE_MZ1200 0x02 // Video mode = MZ1200
|
||||
#define VMMODE_MZ80A 0x03 // Video mode = MZ80A
|
||||
#define VMMODE_MZ700 0x04 // Video mode = MZ700
|
||||
#define VMMODE_MZ800 0x05 // Video mode = MZ800
|
||||
#define VMMODE_MZ1500 0x06 // Video mode = MZ1500
|
||||
#define VMMODE_MZ80B 0x07 // Video mode = MZ80B
|
||||
#define VMMODE_MZ2000 0x08 // Video mode = MZ2000
|
||||
#define VMMODE_MZ2200 0x09 // Video mode = MZ2200
|
||||
#define VMMODE_MZ2500 0x0A // Video mode = MZ2500
|
||||
#define VMMODE_80CHAR 0x80 // Enable 80 character display.
|
||||
#define VMMODE_80CHAR_MASK 0x7F // Mask to filter out display width control bit.
|
||||
#define VMMODE_COLOUR 0x20 // Enable colour display.
|
||||
#define VMMODE_COLOUR_MASK 0xDF // Mask to filter out colour control bit.
|
||||
|
||||
// Sharp MZ colour attributes.
|
||||
#define VMATTR_FG_BLACK 0x00 // Foreground black character attribute.
|
||||
#define VMATTR_FG_BLUE 0x10 // Foreground blue character attribute.
|
||||
#define VMATTR_FG_RED 0x20 // Foreground red character attribute.
|
||||
#define VMATTR_FG_PURPLE 0x30 // Foreground purple character attribute.
|
||||
#define VMATTR_FG_GREEN 0x40 // Foreground green character attribute.
|
||||
#define VMATTR_FG_CYAN 0x50 // Foreground cyan character attribute.
|
||||
#define VMATTR_FG_YELLOW 0x60 // Foreground yellow character attribute.
|
||||
#define VMATTR_FG_WHITE 0x70 // Foreground white character attribute.
|
||||
#define VMATTR_FG_MASKOUT 0x8F // Mask to filter out foreground attribute.
|
||||
#define VMATTR_FG_MASKIN 0x70 // Mask to filter out foreground attribute.
|
||||
#define VMATTR_BG_BLACK 0x00 // Background black character attribute.
|
||||
#define VMATTR_BG_BLUE 0x01 // Background blue character attribute.
|
||||
#define VMATTR_BG_RED 0x02 // Background red character attribute.
|
||||
#define VMATTR_BG_PURPLE 0x03 // Background purple character attribute.
|
||||
#define VMATTR_BG_GREEN 0x04 // Background green character attribute.
|
||||
#define VMATTR_BG_CYAN 0x05 // Background cyan character attribute.
|
||||
#define VMATTR_BG_YELLOW 0x06 // Background yellow character attribute.
|
||||
#define VMATTR_BG_WHITE 0x07 // Background white character attribute.
|
||||
#define VMATTR_BG_MASKOUT 0xF8 // Mask to filter out background attribute.
|
||||
#define VMATTR_BG_MASKIN 0x07 // Mask to filter out background attribute.
|
||||
|
||||
// Sharp MZ-80A/700 constants.
|
||||
//
|
||||
#define MBADDR_KEYPA 0xE000 // Mainboard 8255 Port A
|
||||
#define MBADDR_KEYPB 0xE001 // Mainboard 8255 Port B
|
||||
#define MBADDR_KEYPC 0xE002 // Mainboard 8255 Port C
|
||||
#define MBADDR_KEYPF 0xE003 // Mainboard 8255 Mode Control
|
||||
#define MBADDR_CSTR 0xE002 // Mainboard 8255 Port C
|
||||
#define MBADDR_CSTPT 0xE003 // Mainboard 8255 Mode Control
|
||||
#define MBADDR_CONT0 0xE004 // Mainboard 8253 Counter 0
|
||||
#define MBADDR_CONT1 0xE005 // Mainboard 8253 Counter 1
|
||||
#define MBADDR_CONT2 0xE006 // Mainboard 8253 Counter 1
|
||||
#define MBADDR_CONTF 0xE007 // Mainboard 8253 Mode Control
|
||||
#define MBADDR_SUNDG 0xE008 // Register for reading the tempo timer status (cursor flash). horizontal blank and switching sound on/off.
|
||||
#define MBADDR_TEMP 0xE008 // As above, different name used in original source when writing.
|
||||
#define MBADDR_MEMSW 0xE00C // Memory swap, 0000->C000, C000->0000
|
||||
#define MBADDR_MEMSWR 0xE010 // Reset memory swap.
|
||||
#define MBADDR_NRMDSP 0xE014 // Return display to normal.
|
||||
#define MBADDR_INVDSP 0xE015 // Invert display.
|
||||
#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
|
||||
#define MBADDR_FDC_CR MBADDR_FDC + 0x00 // Command Register
|
||||
#define MBADDR_FDC_STR MBADDR_FDC + 0x00 // Status Register
|
||||
#define MBADDR_FDC_TR MBADDR_FDC + 0x01 // Track Register
|
||||
#define MBADDR_FDC_SCR MBADDR_FDC + 0x02 // Sector Register
|
||||
#define MBADDR_FDC_DR MBADDR_FDC + 0x03 // Data Register
|
||||
#define MBADDR_FDC_MOTOR MBADDR_FDC + 0x04 // DS[0-3] and Motor control. 4 drives DS= BIT 0 -> Bit 2 = Drive number, 2=1,1=0,0=0 DS0, 2=1,1=0,0=1 DS1 etc
|
||||
// bit 7 = 1 MOTOR ON LOW (Active)
|
||||
#define MBADDR_FDC_SIDE MBADDR_FDC + 0x05 // Side select, Bit 0 when set = SIDE SELECT LOW,
|
||||
#define MBADDR_FDC_DDEN MBADDR_FDC + 0x06 // Double density enable, 0 = double density, 1 = single density disks.
|
||||
#define MBADDR_PPIA 0x0E0 // 8255 Port A
|
||||
#define MBADDR_PPIB 0x0E1 // 8255 Port B
|
||||
#define MBADDR_PPIC 0x0E2 // 8255 Port C
|
||||
#define MBADDR_PPICTL 0x0E3 // 8255 Control Port
|
||||
#define MBADDR_PIOA 0x0E8 // Z80 PIO Port A
|
||||
#define MBADDR_PIOCTLA 0x0E9 // Z80 PIO Port A Control Port
|
||||
#define MBADDR_PIOB 0x0EA // Z80 PIO Port B
|
||||
#define MBADDR_PIOCTLB 0x0EB // Z80 PIO Port B Control Port
|
||||
#define MBADDR_CRTBKCOLR 0x0F4 // Configure external CRT background colour.
|
||||
#define MBADDR_CRTGRPHPRIO 0x0F5 // Graphics priority register, character or a graphics colour has front display priority.
|
||||
#define MBADDR_CRTGRPHSEL 0x0F6 // Graphics output select on CRT or external CRT
|
||||
#define MBADDR_GRAMCOLRSEL 0x0F7 // Graphics RAM colour bank select.
|
||||
#define MBADDR_GRAMADDRL 0x0C000 // Graphics RAM base address.
|
||||
|
||||
//Common character definitions.
|
||||
#define SCROLL 0x01 // Set scroll direction UP.
|
||||
#define BELL 0x07
|
||||
#define ENQ 0x05
|
||||
#define SPACE 0x20
|
||||
#define TAB 0x09 // TAB ACROSS (8 SPACES FOR SD-BOARD)
|
||||
#define CR 0x0D
|
||||
#define LF 0x0A
|
||||
#define FF 0x0C
|
||||
#define DELETE 0x7F
|
||||
#define BACKS 0x08
|
||||
#define SOH 0x01 // For XModem etc.
|
||||
#define EOT 0x04
|
||||
#define ACK 0x06
|
||||
#define NAK 0x15
|
||||
#define NUL 0x00
|
||||
//#define NULL 0x00
|
||||
#define CTRL_A 0x01
|
||||
#define CTRL_B 0x02
|
||||
#define CTRL_C 0x03
|
||||
#define CTRL_D 0x04
|
||||
#define CTRL_E 0x05
|
||||
#define CTRL_F 0x06
|
||||
#define CTRL_G 0x07
|
||||
#define CTRL_H 0x08
|
||||
#define CTRL_I 0x09
|
||||
#define CTRL_J 0x0A
|
||||
#define CTRL_K 0x0B
|
||||
#define CTRL_L 0x0C
|
||||
#define CTRL_M 0x0D
|
||||
#define CTRL_N 0x0E
|
||||
#define CTRL_O 0x0F
|
||||
#define CTRL_P 0x10
|
||||
#define CTRL_Q 0x11
|
||||
#define CTRL_R 0x12
|
||||
#define CTRL_S 0x13
|
||||
#define CTRL_T 0x14
|
||||
#define CTRL_U 0x15
|
||||
#define CTRL_V 0x16
|
||||
#define CTRL_W 0x17
|
||||
#define CTRL_X 0x18
|
||||
#define CTRL_Y 0x19
|
||||
#define CTRL_Z 0x1A
|
||||
#define ESC 0x1B
|
||||
#define CTRL_SLASH 0x1C
|
||||
#define CTRL_LB 0x1
|
||||
#define CTRL_RB 0x1D
|
||||
#define CTRL_CAPPA 0x1E
|
||||
#define CTRL_UNDSCR 0x1F
|
||||
#define CTRL_AT 0x00
|
||||
#define FUNC1 0x80
|
||||
#define FUNC2 0x81
|
||||
#define FUNC3 0x82
|
||||
#define FUNC4 0x83
|
||||
#define FUNC5 0x84
|
||||
#define FUNC6 0x85
|
||||
#define FUNC7 0x86
|
||||
#define FUNC8 0x87
|
||||
#define FUNC9 0x88
|
||||
#define FUNC10 0x89
|
||||
#define HOTKEY_ORIGINAL 0xE0
|
||||
#define HOTKEY_RFS80 0xE1
|
||||
#define HOTKEY_RFS40 0xE2
|
||||
#define HOTKEY_TZFS 0xE3
|
||||
#define HOTKEY_LINUX 0xE4
|
||||
#define PAGEUP 0xE8
|
||||
#define PAGEDOWN 0xE9
|
||||
#define CURHOMEKEY 0xEA
|
||||
#define ALPHAGRAPHKEY 0xEB
|
||||
#define SHIFTLOCKKEY 0xEC
|
||||
#define NOKEY 0xF0
|
||||
#define CURSRIGHT 0xF1
|
||||
#define CURSLEFT 0xF2
|
||||
#define CURSUP 0xF3
|
||||
#define CURSDOWN 0xF4
|
||||
#define DBLZERO 0xF5
|
||||
#define INSERT 0xF6
|
||||
#define CLRKEY 0xF7
|
||||
#define HOMEKEY 0xF8
|
||||
#define ENDKEY 0xF9
|
||||
#define ANSITGLKEY 0xFA
|
||||
#define BREAKKEY 0xFB
|
||||
#define GRAPHKEY 0xFC
|
||||
#define ALPHAKEY 0xFD
|
||||
#define DEBUGKEY 0xFE // Special key to enable debug features such as the ANSI emulation.
|
||||
|
||||
// Macros.
|
||||
//
|
||||
// The read/write hardware macros are created in order to allow this module to be used with the zSoft/zOS platform
|
||||
// as well as the FusionX platform. The ZPU writes direct to memory, the FusionX sends via SPI.
|
||||
#define WRITE_HARDWARE(__force__,__addr__,__data__)\
|
||||
{\
|
||||
if(!ctrl.suspendIO || __force__ == 1)\
|
||||
{\
|
||||
SPI_SEND32((uint32_t)__addr__ << 16 | __data__ << 8 | CPLD_CMD_WRITE_ADDR);\
|
||||
}\
|
||||
}
|
||||
#define READ_HARDWARE_INIT(__force__,__addr__)\
|
||||
{\
|
||||
if(!ctrl.suspendIO || __force__ == 1)\
|
||||
{\
|
||||
SPI_SEND32((uint32_t)__addr__ << 16 | 0x00 << 8 | CPLD_CMD_READ_ADDR);\
|
||||
while(CPLD_READY() == 0);\
|
||||
}\
|
||||
}
|
||||
#define READ_HARDWARE() (\
|
||||
z80io_PRL_Read8(1)\
|
||||
)
|
||||
#define WRITE_HARDWARE_IO(__force__,__addr__,__data__)\
|
||||
{\
|
||||
if(!ctrl.suspendIO || __force__ == 1)\
|
||||
{\
|
||||
SPI_SEND32((uint32_t)__addr__ << 16 | __data__ << 8 | CPLD_CMD_WRITEIO_ADDR);\
|
||||
}\
|
||||
}
|
||||
#define READ_HARDWARE_IO_INIT(__force__,__addr__)\
|
||||
{\
|
||||
if(!ctrl.suspendIO || __force__ == 1)\
|
||||
{\
|
||||
SPI_SEND32((uint32_t)__addr__ << 16 | 0x00 << 8 | CPLD_CMD_READIO_ADDR);\
|
||||
while(CPLD_READY() == 0);\
|
||||
}\
|
||||
}
|
||||
#define READ_HARDWARE_IO() (\
|
||||
z80io_PRL_Read8(1)\
|
||||
)
|
||||
// Video memory macros, allows for options based on host hardware - All Sharp MZ series are very similar.
|
||||
#if (TARGET_HOST_MZ2000 == 1)
|
||||
// A7 : H 0xD000:0xD7FF or 0xC000:0xFFFF VRAM paged in.
|
||||
// A6 : H Select Character VRAM (H) or Graphics VRAM (L)
|
||||
// A5 : H Select 80 char mode, 40 char mode = L
|
||||
// A4 : L Select all key strobe lines active, for detection of any key press.
|
||||
// A3-A0: Keyboard strobe lines
|
||||
#define ENABLE_VIDEO() {\
|
||||
display.hwVideoMode = (display.hwVideoMode & 0x3F) | 0xC0;\
|
||||
WRITE_HARDWARE_IO(0, MBADDR_PIOA, display.hwVideoMode);\
|
||||
}
|
||||
#define DISABLE_VIDEO() {\
|
||||
display.hwVideoMode = (display.hwVideoMode & 0x3F);\
|
||||
WRITE_HARDWARE_IO(0, MBADDR_PIOA, display.hwVideoMode);\
|
||||
}
|
||||
#define WRITE_VRAM_CHAR(__addr__,__data__,__xlat__) WRITE_HARDWARE(0,__addr__,__data__)
|
||||
#define WRITE_VRAM_ATTRIBUTE(__addr__,__data__) {}
|
||||
#define WRITE_KEYB_STROBE(__data__)\
|
||||
{\
|
||||
display.hwVideoMode = (display.hwVideoMode & 0xF0) | 0x10 | (__data__ & 0x0F);\
|
||||
WRITE_HARDWARE_IO(0, MBADDR_PIOA, display.hwVideoMode );\
|
||||
}
|
||||
#define READ_KEYB_INIT() READ_HARDWARE_IO_INIT(0, MBADDR_PIOB)
|
||||
#define READ_KEYB() READ_HARDWARE_IO()
|
||||
#elif (TARGET_HOST_MZ1500 ==1)
|
||||
#define ENABLE_VIDEO() {}
|
||||
#define DISABLE_VIDEO() {}
|
||||
#define WRITE_VRAM_CHAR(__addr__,__data__,__xlat__) if(__xlat__ == 1)\
|
||||
{\
|
||||
if(islower(__data__))\
|
||||
{\
|
||||
WRITE_HARDWARE(0,__addr__,(dispCodeMap[(int)(__data__)].dispCode & 0x7F));\
|
||||
READ_HARDWARE_INIT(0,(__addr__+0x800));\
|
||||
WRITE_HARDWARE(0,(__addr__+0x800),(READ_HARDWARE() | 0x80));\
|
||||
} else\
|
||||
{\
|
||||
WRITE_HARDWARE(0,__addr__,dispCodeMap[(int)(__data__)].dispCode);\
|
||||
READ_HARDWARE_INIT(0,(__addr__+0x800));\
|
||||
WRITE_HARDWARE(0,(__addr__+0x800),(READ_HARDWARE() & 0x7F));\
|
||||
}\
|
||||
} else\
|
||||
{\
|
||||
WRITE_HARDWARE(0,__addr__, __data__);\
|
||||
}
|
||||
#define WRITE_VRAM_ATTRIBUTE(__addr__,__data__) {\
|
||||
READ_HARDWARE_INIT(0,(__addr__));\
|
||||
WRITE_HARDWARE(0,__addr__,((READ_HARDWARE() & 0x80) | (__data__ & 0x7F)));\
|
||||
}
|
||||
#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()
|
||||
#else
|
||||
#define ENABLE_VIDEO() {}
|
||||
#define DISABLE_VIDEO() {}
|
||||
#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
|
||||
|
||||
|
||||
|
||||
// Cursor flash mechanism control states.
|
||||
//
|
||||
enum CURSOR_STATES {
|
||||
CURSOR_OFF = 0x00, // Turn the cursor off.
|
||||
CURSOR_ON = 0x01, // Turn the cursor on.
|
||||
CURSOR_RESTORE = 0x02, // Restore the saved cursor character.
|
||||
CURSOR_FLASH = 0x03 // If enabled, flash the cursor.
|
||||
};
|
||||
|
||||
// Cursor positioning states.
|
||||
enum CURSOR_POSITION {
|
||||
CURSOR_UP = 0x00, // Move the cursor up.
|
||||
CURSOR_DOWN = 0x01, // Move the cursor down.
|
||||
CURSOR_LEFT = 0x02, // Move the cursor left.
|
||||
CURSOR_RIGHT = 0x03, // Move the cursor right.
|
||||
CURSOR_COLUMN = 0x04, // Set cursor column to absolute value.
|
||||
CURSOR_NEXT_LINE = 0x05, // Move the cursor to the beginning of the next line.
|
||||
CURSOR_PREV_LINE = 0x06, // Move the cursor to the beginning of the previous line.
|
||||
};
|
||||
|
||||
// Keyboard operating states according to buttons pressed.
|
||||
//
|
||||
enum KEYBOARD_MODES {
|
||||
KEYB_LOWERCASE = 0x00, // Keyboard in lower case mode.
|
||||
KEYB_CAPSLOCK = 0x01, // Keyboard in CAPS lock mode.
|
||||
KEYB_SHIFTLOCK = 0x02, // Keyboard in SHIFT lock mode.
|
||||
KEYB_CTRL = 0x03, // Keyboard in Control mode.
|
||||
KEYB_GRAPHMODE = 0x04, // Keyboard in Graphics mode.
|
||||
};
|
||||
|
||||
// Keyboard dual key modes. This is for hosts whose keyboards dont support the basic key set or when a key needs to have dual functionality.
|
||||
enum KEYBOARD_DUALMODES {
|
||||
KEYB_DUAL_NONE = 0x00, // No dual key modes active.
|
||||
KEYB_DUAL_GRAPH = 0x01, // MZ-80A, no Alpha key, only Graph, so double function required.
|
||||
};
|
||||
|
||||
// Mapping table from Sharp MZ80A Ascii to real Ascii.
|
||||
//
|
||||
typedef struct {
|
||||
uint8_t asciiCode;
|
||||
} t_asciiMap;
|
||||
|
||||
// Mapping table from Ascii to Sharp MZ display code.
|
||||
//
|
||||
typedef struct {
|
||||
uint8_t dispCode;
|
||||
} t_dispCodeMap;
|
||||
|
||||
// Mapping table from keyboard scan codes to Sharp MZ keys.
|
||||
//
|
||||
typedef struct {
|
||||
uint8_t scanCode[KEY_SCAN_ROWS*8];
|
||||
} t_scanCodeMap;
|
||||
|
||||
// Mapping table of a sharp keycode to an ANSI escape sequence string.
|
||||
//
|
||||
typedef struct {
|
||||
uint8_t key;
|
||||
const char* ansiKeySequence;
|
||||
} t_ansiKeyMap;
|
||||
|
||||
// Structure to maintain the Sharp MZ display output parameters and data.
|
||||
//
|
||||
typedef struct {
|
||||
uint8_t displayAttr; // Attributes for each character in the display.
|
||||
uint16_t backingRow; // Maximum backing RAM row, allows for a larger virtual backing display with the physical display acting as a window.
|
||||
|
||||
// Location on the physical display to output data. displayCol is also used in the backing store.
|
||||
uint8_t displayRow;
|
||||
uint8_t displayCol;
|
||||
|
||||
// History and backing display store. The physical display outputs a portion of this backing store.
|
||||
uint8_t displayCharBuf[VC_DISPLAY_BUFFER_SIZE];
|
||||
uint8_t displayAttrBuf[VC_DISPLAY_BUFFER_SIZE];
|
||||
|
||||
// Maxims, dynamic to allow for future changes.
|
||||
uint8_t maxBackingRow;
|
||||
uint8_t maxDisplayRow;
|
||||
uint8_t maxBackingCol;
|
||||
|
||||
// Features.
|
||||
uint8_t lineWrap; // Wrap line at display edge (1) else stop printing at display edge.
|
||||
uint8_t useAnsiTerm; // Enable (1) Ansi Terminal Emulator, (0) disable.
|
||||
uint8_t inDebug; // Prevent recursion when outputting debug information.
|
||||
|
||||
// Working variables.
|
||||
uint8_t hwVideoMode; // Physical configuration of the video control register.
|
||||
} t_displayBuffer;
|
||||
|
||||
// Structure for maintaining the Sharp MZ keyboard parameters and data. Used to retrieve and map a key along with associated
|
||||
// attributes such as cursor flashing.
|
||||
//
|
||||
typedef struct {
|
||||
uint8_t scanbuf[2][KEY_SCAN_ROWS];
|
||||
uint8_t keydown[KEY_SCAN_ROWS];
|
||||
uint8_t keyup[KEY_SCAN_ROWS];
|
||||
uint8_t keyhold[KEY_SCAN_ROWS];
|
||||
uint32_t holdTimer;
|
||||
uint8_t breakKey; // Break key pressed.
|
||||
uint8_t ctrlKey; // Ctrl key pressed.
|
||||
uint8_t shiftKey; // Shift key pressed.
|
||||
uint8_t repeatKey;
|
||||
uint8_t autorepeat;
|
||||
enum KEYBOARD_MODES mode; // Keyboard mode and index into mapping table for a specific map set.
|
||||
enum KEYBOARD_DUALMODES dualmode; // Keyboard dual key override modes.
|
||||
uint8_t keyBuf[MAX_KEYB_BUFFER_SIZE]; // Keyboard buffer.
|
||||
uint8_t keyBufPtr; // Pointer into the keyboard buffer for stored key,
|
||||
uint8_t cursorOn; // Flag to indicate Cursor is switched on.
|
||||
uint8_t displayCursor; // Cursor being displayed = 1
|
||||
uint32_t flashTimer; // Timer to indicate next flash time for cursor.
|
||||
} t_keyboard;
|
||||
|
||||
// Structure for maintaining the Sharp MZ Audio parameters and data.
|
||||
typedef struct {
|
||||
uint32_t audioStopTimer; // Timer to disable audio once elapsed period has expired. Time in ms.
|
||||
} t_audio;
|
||||
|
||||
// Structure for module control parameters.
|
||||
typedef struct {
|
||||
uint8_t suspendIO; // Suspend physical I/O.
|
||||
uint8_t debug; // Enable debugging features.
|
||||
} t_control;
|
||||
|
||||
// Structure to maintain the Ansi Terminal Emulator state and parameters.
|
||||
//
|
||||
typedef struct {
|
||||
enum {
|
||||
ANSITERM_ESC,
|
||||
ANSITERM_BRACKET,
|
||||
ANSITERM_PARSE,
|
||||
} state; // States and current state of the FSM parser.
|
||||
uint8_t charcnt; // Number of characters read into the buffer.
|
||||
uint8_t paramcnt; // Number of parameters parsed and stored.
|
||||
uint8_t setDisplayMode; // Display mode command detected.
|
||||
uint8_t setExtendedMode; // Extended mode command detected.
|
||||
uint8_t charbuf[80]; // Storage for the parameter characters as they are received.
|
||||
uint16_t param[10]; // Parsed parameters.
|
||||
uint8_t saveRow; // Store the current row when requested.
|
||||
uint8_t saveCol; // Store the current column when requested.
|
||||
uint8_t saveDisplayRow; // Store the current display buffer row when requested.
|
||||
} t_AnsiTerm;
|
||||
|
||||
// Application execution constants.
|
||||
//
|
||||
|
||||
// Prototypes.
|
||||
//
|
||||
void sharpmz_init_defaults(void);
|
||||
uint8_t mzInitMBHardware(void);
|
||||
uint8_t mzInit(void);
|
||||
void mzBeep(uint32_t, uint32_t);
|
||||
uint8_t mzMoveCursor(enum CURSOR_POSITION, uint8_t);
|
||||
uint8_t mzSetCursor(uint8_t, uint8_t);
|
||||
int mzPutChar(char);
|
||||
int mzPutRaw(char);
|
||||
uint8_t mzSetAnsiAttribute(uint8_t);
|
||||
int mzAnsiTerm(char);
|
||||
int mzPrintChar(char);
|
||||
uint8_t mzFlashCursor(enum CURSOR_STATES);
|
||||
uint8_t mzPushKey(char *);
|
||||
int mzGetKey(uint8_t);
|
||||
int mzGetChar(void);
|
||||
void mzClearDisplay(uint8_t, uint8_t);
|
||||
void mzClearLine(int, int, int, uint8_t);
|
||||
uint8_t mzGetDisplayWidth(void);
|
||||
uint8_t mzSetDisplayWidth(uint8_t);
|
||||
uint8_t mzSetMachineVideoMode(uint8_t);
|
||||
void mzRefreshDisplay(void);
|
||||
uint8_t mzScrollUp(uint8_t, uint8_t, uint8_t);
|
||||
uint8_t mzScrollDown(uint8_t);
|
||||
void mzDebugOut(uint8_t, uint8_t);
|
||||
void mzSuspendIO(void);
|
||||
void mzResumeIO(void);
|
||||
void mzWriteString(uint8_t, uint8_t, char *, int);
|
||||
void mzService(void);
|
||||
|
||||
// Getter/Setter methods!
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // SHARPMZ_H
|
||||
919
software/FusionX/src/ttymz/ttymz.c
Normal file
919
software/FusionX/src/ttymz/ttymz.c
Normal file
@@ -0,0 +1,919 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: ttymz.c
|
||||
// Created: Feb 2023
|
||||
// Author(s): Philip Smart
|
||||
// Description: Sharp MZ TTY
|
||||
// This file contains the methods used to create a linux tty device driver using the
|
||||
// host Sharp keyboard and screen as input/output.
|
||||
// This driver forms part of the FusionX developments and allows a user sitting at the
|
||||
// Sharp MZ Console to access the underlying FusionX Linux SOM.
|
||||
// Credits: Credits to tiny_tty Greg Kroah-Hartman (greg@kroah.com) and Linux pty which were
|
||||
// used as base and reference in creating this driver.
|
||||
//
|
||||
// Copyright: (c) 2019-2023 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Feb 2023 - v1.0 Initial write of the Sharp MZ tty driver software.
|
||||
// Added suspend I/O logic. This is necessary as I want to enable
|
||||
// switching between a Linux session and a Z80 session, the idea
|
||||
// being the TTY will continue to run within the mirrored framebuffer
|
||||
// and when reselected, refresh the hardware screen.
|
||||
// Apr 2023 - v1.1 Updated to include MZ-2000 mode.
|
||||
// Jul 2023 - v1.2 Updates and bug fixes.
|
||||
//
|
||||
// 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/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/tty_driver.h>
|
||||
#include <linux/tty_flip.h>
|
||||
#include <linux/serial.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/kprobes.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/devpts_fs.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/version.h>
|
||||
#include "z80io.h"
|
||||
#include "sharpmz.h"
|
||||
#include "ttymz.h"
|
||||
|
||||
// Meta Information.
|
||||
MODULE_LICENSE(DRIVER_LICENSE);
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
MODULE_DESCRIPTION(DRIVER_DESCRIPTION);
|
||||
MODULE_VERSION(DRIVER_VERSION);
|
||||
MODULE_INFO(versiondate, DRIVER_VERSION_DATE);
|
||||
MODULE_INFO(copyright, DRIVER_COPYRIGHT);
|
||||
|
||||
// Device control variables.
|
||||
static t_TTYMZ *ttymzConnections[SHARPMZ_TTY_MINORS]; // Initially all NULL, no devices connected.
|
||||
static t_TTYMZCtrl ttymzCtrl;
|
||||
|
||||
// Read method. Keys entered on the host keyboard are sent to the user process via this method.
|
||||
//
|
||||
static void ttymz_read(struct tty_struct *tty, char data)
|
||||
{
|
||||
// Locals.
|
||||
struct tty_port *port;
|
||||
|
||||
// Sanity check.
|
||||
if (!tty)
|
||||
return;
|
||||
|
||||
// Get the port, needed to push data onto the ringbuffer for delivery to the user.
|
||||
port = tty->port;
|
||||
|
||||
// If there is no room, push the characters to the user. Add the new character and push again.
|
||||
if (!tty_buffer_request_room(port, 1))
|
||||
tty_flip_buffer_push(port);
|
||||
tty_insert_flip_char(port, data, TTY_NORMAL);
|
||||
tty_flip_buffer_push(port);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Method to receive data from the user application to be written onto the Sharp or SSD202 framebuffer.
|
||||
//
|
||||
static int ttymz_write(struct tty_struct *tty, const unsigned char *buffer, int count)
|
||||
{
|
||||
t_TTYMZ *ttymz = tty->driver_data;
|
||||
int idx;
|
||||
int retval = count;
|
||||
|
||||
if (!ttymz)
|
||||
return -ENODEV;
|
||||
|
||||
// Lock out other processes.
|
||||
mutex_lock(&ttymz->mutex);
|
||||
|
||||
// Sanity check, ensure port is open.
|
||||
if (!ttymz->open_count)
|
||||
goto exit;
|
||||
|
||||
// Send the characters to the Sharp MZ interface for display.
|
||||
for (idx = 0; idx < count; ++idx)
|
||||
{
|
||||
mzPrintChar(buffer[idx]);
|
||||
}
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ttymz->mutex);
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Method to indicate to the kernel how much buffer space is left in the device.
|
||||
//
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 14, 0))
|
||||
static int ttymz_write_room(struct tty_struct *tty)
|
||||
#else
|
||||
static unsigned int ttymz_write_room(struct tty_struct *tty)
|
||||
#endif
|
||||
{
|
||||
// Locals.
|
||||
t_TTYMZ *ttymz = tty->driver_data;
|
||||
int room = -EINVAL;
|
||||
|
||||
// Sanity check.
|
||||
if(!ttymz)
|
||||
return -ENODEV;
|
||||
|
||||
if(tty->stopped)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&ttymz->mutex);
|
||||
|
||||
if(!ttymz->open_count)
|
||||
{
|
||||
// Port was not opened
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Calculate how much room is left in the device
|
||||
room = 255;
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ttymz->mutex);
|
||||
return room;
|
||||
}
|
||||
|
||||
|
||||
// Timer methods
|
||||
//
|
||||
// Timer to scan the Sharp MZ host keyboard and detect key presses. Any key press detected results
|
||||
// in a character being pushed into the kernel ringbuffer for delivery to the user application.
|
||||
//
|
||||
static void ttymz_keyboardTimer(unsigned long timerAddr)
|
||||
{
|
||||
// Locals.
|
||||
t_TTYMZ *ttymz = (t_TTYMZ *)timerAddr;
|
||||
struct tty_struct *tty;
|
||||
int key;
|
||||
|
||||
// Sanity check.
|
||||
if (!ttymz)
|
||||
return;
|
||||
|
||||
// Once sanitised, get the tty struct from the given physical address, needed to reset the timer and to
|
||||
// push data to the client.
|
||||
tty = ttymz->tty;
|
||||
|
||||
// Scan the Sharp MZ host keyboard, push any character received. Mode 2 = Ansi scan without wait.
|
||||
if((key = mzGetKey(2)) != -1)
|
||||
{
|
||||
switch(key)
|
||||
{
|
||||
// Hotkeys, send to the Arbiter, not the user process.
|
||||
case HOTKEY_ORIGINAL:
|
||||
case HOTKEY_RFS80:
|
||||
case HOTKEY_RFS40:
|
||||
case HOTKEY_TZFS:
|
||||
case HOTKEY_LINUX:
|
||||
//pr_info("Hotkey detected:%02x\n", key);
|
||||
ttymzCtrl.hotkey = (uint32_t)key;
|
||||
sendSignal(ttymzCtrl.arbTask, SIGUSR2);
|
||||
break;
|
||||
|
||||
default:
|
||||
//pr_info("%d, %08x ", key, (size_t)tty->port);
|
||||
ttymz_read(tty, (char)key);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Resubmit the timer again.
|
||||
ttymz->timerKeyboard.expires = jiffies + 1;
|
||||
add_timer(&ttymz->timerKeyboard);
|
||||
}
|
||||
//
|
||||
// Display service timer, used for scheduling tasks within the display driver.
|
||||
//
|
||||
static void ttymz_displayTimer(unsigned long timerAddr)
|
||||
{
|
||||
// Locals.
|
||||
t_TTYMZ *ttymz = (t_TTYMZ *)timerAddr;
|
||||
struct tty_struct *tty;
|
||||
|
||||
// Sanity check.
|
||||
if (!ttymz)
|
||||
return;
|
||||
|
||||
// Once sanitised, get the tty struct from the given physical address, needed to reset the timer and to
|
||||
// push data to the client.
|
||||
tty = ttymz->tty;
|
||||
|
||||
// Call the display service routine.
|
||||
mzService();
|
||||
|
||||
// Resubmit the timer again.
|
||||
ttymz->timerDisplay.expires = jiffies + 1;
|
||||
add_timer(&ttymz->timerDisplay);
|
||||
}
|
||||
|
||||
|
||||
// Device open.
|
||||
//
|
||||
// When a user space application open's the tty device driver, this function is called
|
||||
// to initialise and allocate any required memory or hardware prior to servicing requests from the
|
||||
// user space application.
|
||||
static int ttymz_open(struct tty_struct *tty, struct file *file)
|
||||
{
|
||||
// Locals.
|
||||
t_TTYMZ *ttymz;
|
||||
int index;
|
||||
int ret = 0;
|
||||
struct winsize ws;
|
||||
struct task_struct *task = get_current();
|
||||
|
||||
// Initialize the pointer in case something fails
|
||||
tty->driver_data = NULL;
|
||||
|
||||
// Get the serial object associated with this tty pointer
|
||||
index = tty->index;
|
||||
ttymz = ttymzConnections[index];
|
||||
|
||||
if(ttymz == NULL)
|
||||
{
|
||||
// First time accessing this device, let's create it
|
||||
ttymz = kmalloc(sizeof(*ttymz), GFP_KERNEL);
|
||||
if (!ttymz)
|
||||
return -ENOMEM;
|
||||
|
||||
mutex_init(&ttymz->mutex);
|
||||
ttymz->open_count = 0;
|
||||
|
||||
ttymzConnections[index] = ttymz;
|
||||
}
|
||||
|
||||
mutex_lock(&ttymz->mutex);
|
||||
|
||||
// Save our structure within the tty structure
|
||||
tty->driver_data = ttymz;
|
||||
ttymz->tty = tty;
|
||||
ttymz->tty->port = tty->port;
|
||||
|
||||
// Setup the default terminal size based on compilation (ie. 40/80 cols).
|
||||
ws.ws_row = VC_MAX_ROWS;
|
||||
ws.ws_col = VC_MAX_COLUMNS;
|
||||
tty->winsize = ws;
|
||||
|
||||
// Port opened, perform initialisation.
|
||||
//
|
||||
++ttymz->open_count;
|
||||
if(ttymz->open_count == 1 && tty->index == 0)
|
||||
{
|
||||
// Create the keyboard sweep timer and submit it
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
init_timer(&ttymz->timerKeyboard);
|
||||
ttymz->timerKeyboard.data = (unsigned long)ttymz;
|
||||
ttymz->timerKeyboard.function = ttymz_keyboardTimer;
|
||||
#else
|
||||
timer_setup(timer, (void *)ttymz_keyboardTimer, (unsigned long)ttymz);
|
||||
timer->function = (void *)ttymz_keyboardTimer;
|
||||
#endif
|
||||
// 10 ms sweep timer.
|
||||
ttymz->timerKeyboard.expires = jiffies + 1;
|
||||
add_timer(&ttymz->timerKeyboard);
|
||||
|
||||
// Create the display periodic timer and submit it.
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 15, 0)
|
||||
init_timer(&ttymz->timerDisplay);
|
||||
ttymz->timerDisplay.data = (unsigned long)ttymz;
|
||||
ttymz->timerDisplay.function = ttymz_displayTimer;
|
||||
#else
|
||||
timer_setup(timer, (void *)ttymz_keyboardTimer, (unsigned long)ttymz);
|
||||
timer->function = (void *)ttymz_displayTimer;
|
||||
#endif
|
||||
// 10 ms service interval.
|
||||
ttymz->timerDisplay.expires = jiffies + 1;
|
||||
add_timer(&ttymz->timerDisplay);
|
||||
} else
|
||||
// SSD202 Framebuffer?
|
||||
if(ttymz->open_count == 1 && tty->index == 1)
|
||||
{
|
||||
pr_info("SSD202 Framebuffer not yet implemented.\n");
|
||||
ret = -EBUSY;
|
||||
} else
|
||||
// Control port is just opened, no associated hardware.
|
||||
if(tty->index == 2)
|
||||
{
|
||||
// Arbiter connection?
|
||||
if(ttymzCtrl.arbTask == NULL && strcmp(task->comm, ARBITER_NAME) == 0)
|
||||
{
|
||||
ttymzCtrl.arbTask = task;
|
||||
pr_info("Sharpbiter: Registering Arbiter:%s\n", ttymzCtrl.arbTask->comm);
|
||||
} else
|
||||
if(ttymzCtrl.arbTask != NULL && strcmp(task->comm, ARBITER_NAME) == 0)
|
||||
{
|
||||
pr_info("Arbiter already registered, PID:%d\n", ttymzCtrl.arbTask->pid);
|
||||
ret = -EBUSY;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&ttymz->mutex);
|
||||
return(ret);
|
||||
}
|
||||
|
||||
// Close helper method, performs the actual deallocation of resources for the open port.
|
||||
//
|
||||
static void do_close(t_TTYMZ *ttymz)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t idx;
|
||||
struct task_struct *task = get_current();
|
||||
|
||||
mutex_lock(&ttymz->mutex);
|
||||
|
||||
if(!ttymz->open_count)
|
||||
{
|
||||
// Port was never opened
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// Go through all the connections to find active connection.
|
||||
for(idx = 0; idx < SHARPMZ_TTY_MINORS; idx++)
|
||||
{
|
||||
// Match the handle to find the index.
|
||||
if(ttymz == ttymzConnections[idx])
|
||||
{
|
||||
// Active consoles, ie. host and framebuffer, close hardware and free up timers etc.
|
||||
if(idx < 2)
|
||||
{
|
||||
// Shutdown hardware tasks to exit.
|
||||
// Shut down our timers.
|
||||
del_timer(&ttymz->timerKeyboard);
|
||||
del_timer(&ttymz->timerDisplay);
|
||||
} else
|
||||
if(idx == 2)
|
||||
{
|
||||
// Is this the Arbiter de-registering?
|
||||
if(ttymzCtrl.arbTask == task)
|
||||
{
|
||||
ttymzCtrl.arbTask = NULL;
|
||||
pr_info("Arbiter stopped.\n");
|
||||
}
|
||||
|
||||
// Free up the connection resources.
|
||||
kfree(ttymzConnections[idx]);
|
||||
ttymzConnections[idx] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
mutex_unlock(&ttymz->mutex);
|
||||
}
|
||||
|
||||
// Device close.
|
||||
//
|
||||
// When a user space application terminates or closes the tty device driver, this function is called
|
||||
// to close any open connections, memory and variables required to handle the user space application
|
||||
// requests.
|
||||
static void ttymz_close(struct tty_struct *tty, struct file *file)
|
||||
{
|
||||
// Locals.
|
||||
t_TTYMZ *ttymz = tty->driver_data;
|
||||
|
||||
if (ttymz)
|
||||
do_close(ttymz);
|
||||
}
|
||||
|
||||
#define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
|
||||
static void ttymz_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
|
||||
{
|
||||
// Locals.
|
||||
unsigned int cflag;
|
||||
|
||||
//PRINT_PROC_START();
|
||||
|
||||
cflag = tty->termios.c_cflag;
|
||||
|
||||
// Check that they really want us to change something
|
||||
if (old_termios)
|
||||
{
|
||||
if ((cflag == old_termios->c_cflag) && (RELEVANT_IFLAG(tty->termios.c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// As this is not a serial based TTY, most of the settings are ignored, they are here for reference
|
||||
// and in-place if something is needed in future.
|
||||
|
||||
// Get the byte size
|
||||
switch(cflag & CSIZE)
|
||||
{
|
||||
case CS5:
|
||||
break;
|
||||
case CS6:
|
||||
break;
|
||||
case CS7:
|
||||
break;
|
||||
default:
|
||||
case CS8:
|
||||
break;
|
||||
}
|
||||
|
||||
// Determine the parity
|
||||
if (cflag & PARENB)
|
||||
if (cflag & PARODD)
|
||||
{
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
// Figure out the stop bits requested
|
||||
if (cflag & CSTOPB)
|
||||
{
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
// Figure out the hardware flow control settings
|
||||
if (cflag & CRTSCTS)
|
||||
{
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
// Determine software flow control
|
||||
// if we are implementing XON/XOFF, set the start and
|
||||
// stop character in the device
|
||||
if (I_IXOFF(tty) || I_IXON(tty))
|
||||
{
|
||||
//unsigned char stop_char = STOP_CHAR(tty);
|
||||
//unsigned char start_char = START_CHAR(tty);
|
||||
|
||||
// If we are implementing INBOUND XON/XOFF
|
||||
if(I_IXOFF(tty))
|
||||
{
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
// if we are implementing OUTBOUND XON/XOFF
|
||||
if(I_IXON(tty))
|
||||
{
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the baud rate wanted
|
||||
// baud = tty_get_baud_rate(tty));
|
||||
return;
|
||||
}
|
||||
|
||||
static int ttymz_tiocmget(struct tty_struct *tty)
|
||||
{
|
||||
// Locals.
|
||||
t_TTYMZ *ttymz = tty->driver_data;
|
||||
unsigned int result = 0;
|
||||
unsigned int msr = ttymz->msr;
|
||||
unsigned int mcr = ttymz->mcr;
|
||||
|
||||
//PRINT_PROC_START();
|
||||
|
||||
result = ((mcr & MCR_DTR) ? TIOCM_DTR : 0) | // DTR is set
|
||||
((mcr & MCR_RTS) ? TIOCM_RTS : 0) | // RTS is set
|
||||
((mcr & MCR_LOOP) ? TIOCM_LOOP : 0) | // LOOP is set
|
||||
((msr & MSR_CTS) ? TIOCM_CTS : 0) | // CTS is set
|
||||
((msr & MSR_CD) ? TIOCM_CAR : 0) | // Carrier detect is set
|
||||
((msr & MSR_RI) ? TIOCM_RI : 0) | // Ring Indicator is set
|
||||
((msr & MSR_DSR) ? TIOCM_DSR : 0); // DSR is set
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int ttymz_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear)
|
||||
{
|
||||
// Locals.
|
||||
t_TTYMZ *ttymz = tty->driver_data;
|
||||
unsigned int mcr = ttymz->mcr;
|
||||
|
||||
//PRINT_PROC_START();
|
||||
|
||||
if (set & TIOCM_RTS)
|
||||
mcr |= MCR_RTS;
|
||||
if (set & TIOCM_DTR)
|
||||
mcr |= MCR_RTS;
|
||||
|
||||
if (clear & TIOCM_RTS)
|
||||
mcr &= ~MCR_RTS;
|
||||
if (clear & TIOCM_DTR)
|
||||
mcr &= ~MCR_RTS;
|
||||
|
||||
// Set the new MCR value in the device
|
||||
ttymz->mcr = mcr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define ttymz_ioctl ttymz_ioctl_tiocgserial
|
||||
static int ttymz_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
// Locals.
|
||||
struct serial_struct tmp;
|
||||
t_TTYMZ *ttymz = tty->driver_data;
|
||||
|
||||
//PRINT_PROC_START();
|
||||
|
||||
if(cmd == TIOCGSERIAL)
|
||||
{
|
||||
if (!arg)
|
||||
return -EFAULT;
|
||||
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
|
||||
tmp.type = ttymz->serial.type;
|
||||
tmp.line = ttymz->serial.line;
|
||||
tmp.port = ttymz->serial.port;
|
||||
tmp.irq = ttymz->serial.irq;
|
||||
tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ;
|
||||
tmp.xmit_fifo_size = ttymz->serial.xmit_fifo_size;
|
||||
tmp.baud_base = ttymz->serial.baud_base;
|
||||
tmp.close_delay = 5*HZ;
|
||||
tmp.closing_wait = 30*HZ;
|
||||
tmp.custom_divisor = ttymz->serial.custom_divisor;
|
||||
tmp.hub6 = ttymz->serial.hub6;
|
||||
tmp.io_type = ttymz->serial.io_type;
|
||||
|
||||
if (copy_to_user((void __user *)arg, &tmp, sizeof(struct serial_struct)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
#undef ttymz_ioctl
|
||||
|
||||
#define ttymz_ioctl ttymz_ioctl_tiocmiwait
|
||||
static int ttymz_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
// Locals.
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
struct async_icount cnow;
|
||||
struct async_icount cprev;
|
||||
t_TTYMZ *ttymz = tty->driver_data;
|
||||
|
||||
//PRINT_PROC_START();
|
||||
|
||||
if (cmd == TIOCMIWAIT)
|
||||
{
|
||||
cprev = ttymz->icount;
|
||||
while (1)
|
||||
{
|
||||
add_wait_queue(&ttymz->wait, &wait);
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
schedule();
|
||||
remove_wait_queue(&ttymz->wait, &wait);
|
||||
|
||||
// See if a signal woke us up
|
||||
if (signal_pending(current))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
cnow = ttymz->icount;
|
||||
if(cnow.rng == cprev.rng && cnow.dsr == cprev.dsr && cnow.dcd == cprev.dcd && cnow.cts == cprev.cts)
|
||||
return -EIO; // no change => error
|
||||
if(((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
|
||||
((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
|
||||
((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd)) ||
|
||||
((arg & TIOCM_CTS) && (cnow.cts != cprev.cts)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
cprev = cnow;
|
||||
}
|
||||
|
||||
}
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
#undef ttymz_ioctl
|
||||
|
||||
#define ttymz_ioctl ttymz_ioctl_tiocgicount
|
||||
static int ttymz_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
// Locals.
|
||||
t_TTYMZ *ttymz = tty->driver_data;
|
||||
struct async_icount cnow = ttymz->icount;
|
||||
struct serial_icounter_struct icount;
|
||||
|
||||
//PRINT_PROC_START();
|
||||
|
||||
if(cmd == TIOCGICOUNT)
|
||||
{
|
||||
icount.cts = cnow.cts;
|
||||
icount.dsr = cnow.dsr;
|
||||
icount.rng = cnow.rng;
|
||||
icount.dcd = cnow.dcd;
|
||||
icount.rx = cnow.rx;
|
||||
icount.tx = cnow.tx;
|
||||
icount.frame = cnow.frame;
|
||||
icount.overrun = cnow.overrun;
|
||||
icount.parity = cnow.parity;
|
||||
icount.brk = cnow.brk;
|
||||
icount.buf_overrun = cnow.buf_overrun;
|
||||
|
||||
if (copy_to_user((void __user *)arg, &icount, sizeof(icount)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
#undef ttymz_ioctl
|
||||
|
||||
// IOCTL Method
|
||||
// This method allows User Space application to control the SharpMZ TTY device driver internal functionality.
|
||||
//
|
||||
static int ttymz_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
// Locals.
|
||||
|
||||
//PRINT_PROC_START();
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
case TIOCGSERIAL:
|
||||
return ttymz_ioctl_tiocgserial(tty, cmd, arg);
|
||||
case TIOCMIWAIT:
|
||||
return ttymz_ioctl_tiocmiwait(tty, cmd, arg);
|
||||
case TIOCGICOUNT:
|
||||
return ttymz_ioctl_tiocgicount(tty, cmd, arg);
|
||||
|
||||
// Fetch last hotkey. This method returns any active hotkey to the caller. Normally this is queried after receiving a SIGUSR2 signal.
|
||||
case IOCTL_CMD_FETCH_HOTKEY:
|
||||
if(copy_to_user((int32_t*)arg, &ttymzCtrl.hotkey, sizeof(ttymzCtrl.hotkey)))
|
||||
{
|
||||
pr_err("Failed to send hotkey to user space.\n");
|
||||
}
|
||||
return(0);
|
||||
|
||||
// Suspend control. This method stops all physical hardware updates of the host framebuffer and keyboard
|
||||
// scan whilst maintining the functionality of the tty within the mirrored framebuffer. This mode is
|
||||
// necessary if the user wishes to switch into a Z80 driver and use the host as original.
|
||||
case IOCTL_CMD_SUSPEND_IO:
|
||||
mzSuspendIO();
|
||||
return(0);
|
||||
|
||||
// Resume control. This method re-initialises host hardware, updates the host framebuffer from the mirror
|
||||
// (refresh) and re-enabled hardware access and keyboard scanning.
|
||||
case IOCTL_CMD_RESUME_IO:
|
||||
mzResumeIO();
|
||||
return(0);
|
||||
}
|
||||
|
||||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
|
||||
// Window resize method.
|
||||
// On the Sharp framebuffer this could be 40/80 chars wide.
|
||||
// On the SSD202 framebuffer, tba.
|
||||
static int ttymz_resize(struct tty_struct *tty, struct winsize *ws)
|
||||
{
|
||||
PRINT_PROC_START();
|
||||
|
||||
pr_info("Resize to:%d,%d\n", ws->ws_row, ws->ws_col);
|
||||
|
||||
// Check columns and setup the display according to requirement.
|
||||
if(ws->ws_col == 40)
|
||||
{
|
||||
ws->ws_row = VC_MAX_ROWS;
|
||||
} else
|
||||
if(ws->ws_col == 80)
|
||||
{
|
||||
ws->ws_row = VC_MAX_ROWS;
|
||||
} else
|
||||
{
|
||||
// Ignore all other values.
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
// Setup the hardware to accommodate new column width.
|
||||
mzSetDisplayWidth(ws->ws_col);
|
||||
tty->winsize = *ws;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//static void ttymz_remove(struct tty_driver *driver, struct tty_struct *tty)
|
||||
//{
|
||||
// // Locals.
|
||||
//
|
||||
// PRINT_PROC_START();
|
||||
//}
|
||||
|
||||
static void ttymz_cleanup(struct tty_struct *tty)
|
||||
{
|
||||
// tty_port_put(tty->port);
|
||||
}
|
||||
|
||||
static void ttymz_flush_buffer(struct tty_struct *tty)
|
||||
{
|
||||
// Locals.
|
||||
|
||||
//PRINT_PROC_START();
|
||||
}
|
||||
|
||||
// pty_chars_in_buffer - characters currently in our tx queue
|
||||
//
|
||||
// Report how much we have in the transmit queue. As everything is
|
||||
// instantly at the other end this is easy to implement.
|
||||
//
|
||||
static int ttymz_chars_in_buffer(struct tty_struct *tty)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// The unthrottle routine is called by the line discipline to signal
|
||||
// that it can receive more characters. For PTY's, the TTY_THROTTLED
|
||||
// flag is always set, to force the line discipline to always call the
|
||||
// unthrottle routine when there are fewer than TTY_THRESHOLD_UNTHROTTLE
|
||||
// characters in the queue. This is necessary since each time this
|
||||
// happens, we need to wake up any sleeping processes that could be
|
||||
// (1) trying to send data to the pty, or (2) waiting in wait_until_sent()
|
||||
// for the pty buffer to be drained.
|
||||
//
|
||||
static void ttymz_unthrottle(struct tty_struct *tty)
|
||||
{
|
||||
//PRINT_PROC_START();
|
||||
tty_wakeup(tty->link);
|
||||
set_bit(TTY_THROTTLED, &tty->flags);
|
||||
}
|
||||
|
||||
// Structure to declare public API methods.
|
||||
// Standard Linux device driver structure to declare accessible methods within the driver.
|
||||
static const struct tty_operations serial_ops = {
|
||||
//.install = ttymz_install,
|
||||
.open = ttymz_open,
|
||||
.close = ttymz_close,
|
||||
.write = ttymz_write,
|
||||
.write_room = ttymz_write_room,
|
||||
.flush_buffer = ttymz_flush_buffer,
|
||||
.chars_in_buffer = ttymz_chars_in_buffer,
|
||||
.unthrottle = ttymz_unthrottle,
|
||||
.set_termios = ttymz_set_termios,
|
||||
.tiocmget = ttymz_tiocmget,
|
||||
.tiocmset = ttymz_tiocmset,
|
||||
.ioctl = ttymz_ioctl,
|
||||
.cleanup = ttymz_cleanup,
|
||||
.resize = ttymz_resize,
|
||||
// .remove = ttymz_remove
|
||||
};
|
||||
|
||||
|
||||
// Initialisation.
|
||||
// This is the entry point into the device driver when loaded into the kernel.
|
||||
// The method intialises any required hardware (ie. GPIO's, SPI etc), memory.
|
||||
// It also allocates the Major and Minor device numbers and sets up the device in /dev.
|
||||
static int __init ttymz_init(void)
|
||||
{
|
||||
// Locals.
|
||||
int retval;
|
||||
int i;
|
||||
char buf[80];
|
||||
|
||||
// Initialise the sharpmz module control structures with default values.
|
||||
sharpmz_init_defaults();
|
||||
|
||||
// Allocate the tty driver handles, one per potential device.
|
||||
ttymzCtrl.ttymzDriver = alloc_tty_driver(SHARPMZ_TTY_MINORS);
|
||||
if(!ttymzCtrl.ttymzDriver)
|
||||
return -ENOMEM;
|
||||
|
||||
// Initialize the tty driver
|
||||
ttymzCtrl.ttymzDriver->owner = THIS_MODULE;
|
||||
ttymzCtrl.ttymzDriver->driver_name = DRIVER_NAME;
|
||||
ttymzCtrl.ttymzDriver->name = DEVICE_NAME;
|
||||
ttymzCtrl.ttymzDriver->major = SHARPMZ_TTY_MAJOR,
|
||||
ttymzCtrl.ttymzDriver->type = TTY_DRIVER_TYPE_SERIAL,
|
||||
ttymzCtrl.ttymzDriver->subtype = SERIAL_TYPE_NORMAL,
|
||||
ttymzCtrl.ttymzDriver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV,
|
||||
ttymzCtrl.ttymzDriver->init_termios = tty_std_termios;
|
||||
ttymzCtrl.ttymzDriver->init_termios.c_cflag = B9600 | CS8 | CREAD | HUPCL | CLOCAL;
|
||||
tty_set_operations(ttymzCtrl.ttymzDriver, &serial_ops);
|
||||
for (i = 0; i < SHARPMZ_TTY_MINORS; i++)
|
||||
{
|
||||
tty_port_init(ttymzCtrl.ttymzPort + i);
|
||||
tty_port_link_device(ttymzCtrl.ttymzPort + i, ttymzCtrl.ttymzDriver, i);
|
||||
}
|
||||
|
||||
// Register the tty driver
|
||||
retval = tty_register_driver(ttymzCtrl.ttymzDriver);
|
||||
if(retval)
|
||||
{
|
||||
pr_err("Failed to register SharpMZ tty driver");
|
||||
put_tty_driver(ttymzCtrl.ttymzDriver);
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Register the devices.
|
||||
for (i = 0; i < SHARPMZ_TTY_MINORS; ++i)
|
||||
tty_register_device(ttymzCtrl.ttymzDriver, i, NULL);
|
||||
|
||||
// Initialise the hardware to host interface.
|
||||
z80io_init();
|
||||
|
||||
// Initialise the Sharp MZ interface.
|
||||
mzInit();
|
||||
|
||||
// Sign on.
|
||||
sprintf(buf, "%s %s", DRIVER_TITLE, DRIVER_VERSION); mzWriteString(0, 0, buf, -1);
|
||||
sprintf(buf, "%s %s\n", DRIVER_COPYRIGHT, DRIVER_AUTHOR); mzWriteString(0, 1, buf, -1);
|
||||
|
||||
pr_info(DRIVER_DESCRIPTION " " DRIVER_VERSION "\n");
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
// Exit
|
||||
// This method is called when the device driver is removed from the kernel with the rmmod command.
|
||||
// It is responsible for closing and freeing all allocated memory, disabling hardware and removing
|
||||
// the device from the /dev directory.
|
||||
static void __exit ttymz_exit(void)
|
||||
{
|
||||
// Locals.
|
||||
t_TTYMZ *ttymz;
|
||||
int idx;
|
||||
|
||||
// De-register the devices and driver.
|
||||
for(idx = 0; idx < SHARPMZ_TTY_MINORS; ++idx)
|
||||
{
|
||||
tty_unregister_device(ttymzCtrl.ttymzDriver, idx);
|
||||
tty_port_destroy(ttymzCtrl.ttymzPort + idx);
|
||||
}
|
||||
tty_unregister_driver(ttymzCtrl.ttymzDriver);
|
||||
|
||||
// Shut down all of the timers and free the memory.
|
||||
for(idx = 0; idx < SHARPMZ_TTY_MINORS; ++idx)
|
||||
{
|
||||
ttymz = ttymzConnections[idx];
|
||||
if (ttymz)
|
||||
{
|
||||
// Close the port.
|
||||
while (ttymz->open_count)
|
||||
do_close(ttymz);
|
||||
|
||||
// Shut down our timer and free the memory.
|
||||
del_timer(&ttymz->timerKeyboard);
|
||||
del_timer(&ttymz->timerDisplay);
|
||||
kfree(ttymz);
|
||||
ttymzConnections[idx] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
pr_info("ttymz: unregistered!\n");
|
||||
}
|
||||
|
||||
module_init(ttymz_init);
|
||||
module_exit(ttymz_exit);
|
||||
143
software/FusionX/src/ttymz/ttymz.h
vendored
Normal file
143
software/FusionX/src/ttymz/ttymz.h
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: ttymz.h
|
||||
// Created: Feb 2023
|
||||
// Author(s): Philip Smart
|
||||
// Description: Sharp MZ TTY
|
||||
// This file contains the definitions required by the linux tty device driver ttymz.c.
|
||||
// This driver forms part of the FusionX developments and allows a user sitting at the
|
||||
// Sharp MZ Console to access the underlying FusionX Linux SOM.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2023 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Feb 2023 - v1.0 Initial write of the Sharp MZ tty driver software.
|
||||
// Apr 2023 - v1.1 Updated to include MZ-2000 mode.
|
||||
// Jul 2023 - v1.2 Updates and bug fixes.
|
||||
//
|
||||
// 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/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef TTYMZ_H
|
||||
#define TTYMZ_H
|
||||
|
||||
// Constants.
|
||||
#define DRIVER_LICENSE "GPL"
|
||||
#define DRIVER_AUTHOR "P.D.Smart"
|
||||
#define DRIVER_DESCRIPTION "Sharp MZ TTY Driver"
|
||||
#define DRIVER_VERSION "v1.2"
|
||||
#define DRIVER_VERSION_DATE "July 2023"
|
||||
#define DRIVER_COPYRIGHT "(C) 2018-23"
|
||||
#define DEVICE_NAME "ttymz"
|
||||
#define DRIVER_NAME "SharpMZ_tty"
|
||||
#define DEBUG_ENABLED 0 // 0 = disabled, 1 .. debug level.
|
||||
#define ARBITER_NAME "sharpbiter"
|
||||
#if (TARGET_HOST_MZ80A == 1)
|
||||
#define DRIVER_TITLE "Sharp MZ-80A TTY"
|
||||
#elif (TARGET_HOST_MZ700 == 1)
|
||||
#define DRIVER_TITLE "Sharp MZ-700 TTY"
|
||||
#elif (TARGET_HOST_MZ1500 == 1)
|
||||
#define DRIVER_TITLE "Sharp MZ-1500 TTY"
|
||||
#elif (TARGET_HOST_MZ2000 == 1)
|
||||
#define DRIVER_TITLE "Sharp MZ-2000 TTY"
|
||||
#elif (TARGET_HOST_PCW == 1)
|
||||
#define DRIVER_TITLE "Amstrad PCW-8XXX TTY"
|
||||
#else
|
||||
#define DRIVER_MODEL "not defined"
|
||||
#endif
|
||||
|
||||
// Fake UART values
|
||||
#define MCR_DTR 0x01
|
||||
#define MCR_RTS 0x02
|
||||
#define MCR_LOOP 0x04
|
||||
#define MSR_CTS 0x08
|
||||
#define MSR_CD 0x10
|
||||
#define MSR_RI 0x20
|
||||
#define MSR_DSR 0x40
|
||||
|
||||
// IOCTL commands. Passed from user space using the IOCTL method to command the driver to perform an action.
|
||||
#define IOCTL_CMD_FETCH_HOTKEY _IOW('f', 'f', int32_t *)
|
||||
#define IOCTL_CMD_SUSPEND_IO _IOW('s', 's', int32_t *)
|
||||
#define IOCTL_CMD_RESUME_IO _IOW('r', 'r', int32_t *)
|
||||
|
||||
#define SHARPMZ_TTY_MAJOR 240 // Experimental range
|
||||
#define SHARPMZ_TTY_MINORS 3 // Assign 2 devices, 0) Sharp VRAM, 1) SigmaStar SSD202 Framebuffer, 2) Control.
|
||||
|
||||
// Macros.
|
||||
#define from_timer(var, callback_timer, timer_fieldname) container_of(callback_timer, typeof(*var), timer_fieldname)
|
||||
#define PRINT_PROC_START() do { pr_info("Start: %s\n", __func__); } while (0)
|
||||
#define PRINT_PROC_EXIT() do { pr_info("Finish: %s\n", __func__); } while (0)
|
||||
#define sendSignal(__task__, _signal_) { struct siginfo sigInfo;\
|
||||
if(__task__ != NULL)\
|
||||
{\
|
||||
memset(&sigInfo, 0, sizeof(struct siginfo));\
|
||||
sigInfo.si_signo = _signal_;\
|
||||
sigInfo.si_code = SI_QUEUE;\
|
||||
sigInfo.si_int = 1;\
|
||||
if(send_sig_info(_signal_, &sigInfo, __task__) < 0)\
|
||||
{\
|
||||
pr_info("Error: Failed to send signal:%02x to:%s\n", _signal_, __task__->comm);\
|
||||
}\
|
||||
}\
|
||||
}
|
||||
#define resetZ80() {\
|
||||
sendSignal(Z80Ctrl->ioTask, SIGUSR1); \
|
||||
setupMemory(Z80Ctrl->defaultPageMode);\
|
||||
z80_instant_reset(&Z80CPU);\
|
||||
}
|
||||
|
||||
// TTY control structure, per port.
|
||||
typedef struct {
|
||||
struct tty_struct *tty; // pointer to the tty for this device
|
||||
int open_count; // number of times this port has been opened
|
||||
struct mutex mutex; // locks this structure
|
||||
struct timer_list timerKeyboard; // Keyboard sweep timer.
|
||||
struct timer_list timerDisplay; // Display service timer.
|
||||
|
||||
// for tiocmget and tiocmset functions
|
||||
int msr; // MSR shadow
|
||||
int mcr; // MCR shadow
|
||||
|
||||
// for ioctl
|
||||
struct serial_struct serial;
|
||||
wait_queue_head_t wait;
|
||||
struct async_icount icount;
|
||||
} t_TTYMZ;
|
||||
|
||||
// Driver control variables.
|
||||
typedef struct {
|
||||
struct tty_driver *ttymzDriver;
|
||||
struct tty_port ttymzPort[SHARPMZ_TTY_MINORS];
|
||||
struct task_struct *arbTask;
|
||||
int32_t hotkey;
|
||||
} t_TTYMZCtrl;
|
||||
|
||||
#if(DEBUG_ENABLED != 0)
|
||||
struct debug {
|
||||
uint8_t level;
|
||||
};
|
||||
#endif
|
||||
struct ioctlCmd {
|
||||
int32_t cmd;
|
||||
union {
|
||||
#if(DEBUG_ENABLED != 0)
|
||||
struct debug debug;
|
||||
#endif
|
||||
};
|
||||
};
|
||||
|
||||
// Prototypes.
|
||||
|
||||
#endif
|
||||
452
software/FusionX/src/ttymz/z80io.c
Normal file
452
software/FusionX/src/ttymz/z80io.c
Normal file
@@ -0,0 +1,452 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: z80io.c
|
||||
// Created: Oct 2022
|
||||
// Author(s): Philip Smart
|
||||
// Description: Z80 IO Interface
|
||||
// This file contains the methods used in interfacing the SOM to the Z80 socket
|
||||
// and host hardware via a CPLD.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2023 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Oct 2022 v1.0 - Initial write of the z80 kernel driver software.
|
||||
// Jan 2023 v1.1 - Numerous new tries at increasing throughput to the CPLD failed.
|
||||
// Maximum read throughput of an 8bit byte due to the SSD202 GPIO
|
||||
// structure is approx 2MB/s - or 512K/s for a needed 32bit word.
|
||||
// Write is slower as you have to clock the data so sticking with SPI.
|
||||
//
|
||||
// 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 <stdio.h>
|
||||
//#include <stdlib.h>
|
||||
//#include <string.h>
|
||||
#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>
|
||||
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// User space driver access.
|
||||
//
|
||||
//-------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Initialise the SOM hardware used to communicate with the z80 socket and host hardware.
|
||||
// The SOM interfaces to a CPLD which provides voltage level translation and also encapsulates the Z80 timing cycles as recreating
|
||||
// them within the SOM is much more tricky.
|
||||
//
|
||||
// As this is an embedded device and performance/latency are priorities, minimal structured code is used to keep call stack and
|
||||
// generated code to a mimimum without relying on the optimiser.
|
||||
int z80io_init(void)
|
||||
{
|
||||
// Locals.
|
||||
int ret = 0;
|
||||
|
||||
// Initialise GPIO. We call the HAL api to minimise time but for actual bit set/reset and read we go directly to registers to save time, increase throughput and minimise latency.
|
||||
// Initialise the HAL.
|
||||
MHal_GPIO_Init();
|
||||
|
||||
// Set the pads as GPIO devices. The HAL takes care of allocating and deallocating the padmux resources.
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_0); // Word (16bit) bidirectional bus. Default is read with data set.
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_1);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_2);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_3);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_4);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_5);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_6);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_IN_DATA_7);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_HIGH_BYTE);
|
||||
//MHal_GPIO_Pad_Set(PAD_GPIO8); // SPIO 4wire control lines setup by the spidev driver but controlled directly in this driver.
|
||||
//MHal_GPIO_Pad_Set(PAD_GPIO9);
|
||||
//MHal_GPIO_Pad_Set(PAD_GPIO10);
|
||||
//MHal_GPIO_Pad_Set(PAD_GPIO11);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_READY);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_LTSTATE);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_BUSRQ);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_BUSACK);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_INT);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_NMI);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_WAIT);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_RESET);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_RSV1);
|
||||
#ifdef NOTNEEDED
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_0);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_1);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_2);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_3);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_4);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_5);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_6);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_OUT_DATA_7);
|
||||
MHal_GPIO_Pad_Set(PAD_Z80IO_WRITE);
|
||||
#endif
|
||||
|
||||
// Set required input pads.
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_0);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_1);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_2);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_3);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_4);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_5);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_6);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_IN_DATA_7);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_READY);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_LTSTATE);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_BUSRQ);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_BUSACK);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_INT);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_NMI);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_WAIT);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_RESET);
|
||||
MHal_GPIO_Pad_Odn(PAD_Z80IO_RSV1);
|
||||
|
||||
// Set required output pads.
|
||||
#ifdef NOTNEEDED
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_0);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_1);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_2);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_3);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_4);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_5);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_6);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_OUT_DATA_7);
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_WRITE);
|
||||
MHal_GPIO_Pull_High(PAD_Z80IO_WRITE);
|
||||
#endif
|
||||
|
||||
// Control signals.
|
||||
MHal_GPIO_Pad_Oen(PAD_Z80IO_HIGH_BYTE);
|
||||
MHal_GPIO_Pull_High(PAD_Z80IO_HIGH_BYTE);
|
||||
|
||||
// Setup the MSPI0 device.
|
||||
//
|
||||
// Setup control, interrupts are not used.
|
||||
MSPI_WRITE(MSPI_CTRL_OFFSET, MSPI_CPU_CLOCK_1_2 | MSPI_CTRL_CPOL_LOW | MSPI_CTRL_CPHA_HIGH | MSPI_CTRL_RESET | MSPI_CTRL_ENABLE_SPI);
|
||||
|
||||
// Setup LSB First mode.
|
||||
MSPI_WRITE(MSPI_LSB_FIRST_OFFSET, 0x0);
|
||||
|
||||
// Setup clock.
|
||||
CLK_WRITE(MSPI0_CLK_CFG, 0x1100)
|
||||
|
||||
// Setup the frame size (all buffers to 8bits).
|
||||
MSPI_WRITE(MSPI_FRAME_WBIT_OFFSET, 0xfff);
|
||||
MSPI_WRITE(MSPI_FRAME_WBIT_OFFSET+1, 0xfff);
|
||||
MSPI_WRITE(MSPI_FRAME_RBIT_OFFSET, 0xfff);
|
||||
MSPI_WRITE(MSPI_FRAME_RBIT_OFFSET+1, 0xfff);
|
||||
|
||||
// Setup Chip Selects to inactive.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE);
|
||||
|
||||
// Switch Video and Audio to host.
|
||||
z80io_SPI_Send16(0x00f0, NULL);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Parallel bus Methods.
|
||||
//--------------------------------------------------------
|
||||
|
||||
// Methods to read data from the parallel bus.
|
||||
// The CPLD returns status and Z80 data on the 8bit bus as it is marginally quicker than retrieving it over the SPI bus.
|
||||
//
|
||||
inline uint8_t z80io_PRL_Read8(uint8_t dataFlag)
|
||||
{
|
||||
// Locals.
|
||||
volatile uint8_t result = 0;
|
||||
|
||||
// Byte according to flag.
|
||||
if(dataFlag)
|
||||
SET_CPLD_READ_DATA()
|
||||
else
|
||||
SET_CPLD_READ_STATUS()
|
||||
|
||||
// Read the input registers and set value accordingly.
|
||||
result = READ_CPLD_DATA_IN();
|
||||
|
||||
// Return 16bit value read from CPLD.
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline uint8_t z80io_PRL_Read(void)
|
||||
{
|
||||
// Locals.
|
||||
volatile uint8_t result = 0;
|
||||
volatile uint32_t b7, b6, b5, b4, b3, b2, b1, b0;
|
||||
|
||||
// Read the input registers and set value accordingly. Quicker to read registers and then apply shift/logical operators. The I/O Bus is very slow!
|
||||
b7 = READ_LONG(((gRIUBaseAddr) + (((PAD_Z80IO_IN_DATA_7_ADDR) & ~1)<<1) + (PAD_Z80IO_IN_DATA_7_ADDR & 1)));
|
||||
b6 = READ_LONG(((gRIUBaseAddr) + (((PAD_Z80IO_IN_DATA_6_ADDR) & ~1)<<1) + (PAD_Z80IO_IN_DATA_6_ADDR & 1)));
|
||||
b5 = READ_LONG(((gRIUBaseAddr) + (((PAD_Z80IO_IN_DATA_5_ADDR) & ~1)<<1) + (PAD_Z80IO_IN_DATA_5_ADDR & 1)));
|
||||
b4 = READ_LONG(((gRIUBaseAddr) + (((PAD_Z80IO_IN_DATA_4_ADDR) & ~1)<<1) + (PAD_Z80IO_IN_DATA_4_ADDR & 1)));
|
||||
b3 = READ_LONG(((gRIUBaseAddr) + (((PAD_Z80IO_IN_DATA_3_ADDR) & ~1)<<1) + (PAD_Z80IO_IN_DATA_3_ADDR & 1)));
|
||||
b2 = READ_LONG(((gRIUBaseAddr) + (((PAD_Z80IO_IN_DATA_2_ADDR) & ~1)<<1) + (PAD_Z80IO_IN_DATA_2_ADDR & 1)));
|
||||
b1 = READ_LONG(((gRIUBaseAddr) + (((PAD_Z80IO_IN_DATA_1_ADDR) & ~1)<<1) + (PAD_Z80IO_IN_DATA_1_ADDR & 1)));
|
||||
b0 = READ_LONG(((gRIUBaseAddr) + (((PAD_Z80IO_IN_DATA_0_ADDR) & ~1)<<1) + (PAD_Z80IO_IN_DATA_0_ADDR & 1)));
|
||||
result = (b7 & 0x1) << 7 | (b6 & 0x1) << 6 | (b5 & 0x1) << 5 | (b4 & 0x1) << 4 | (b3 & 0x1) << 3 | (b2 & 0x1) << 2 | (b1 & 0x1) << 1 | (b0 & 0x1);
|
||||
|
||||
// Return 16bit value read from CPLD.
|
||||
return(result);
|
||||
}
|
||||
|
||||
inline uint16_t z80io_PRL_Read16(void)
|
||||
{
|
||||
// Locals.
|
||||
volatile uint16_t result = 0;
|
||||
|
||||
// Low byte first.
|
||||
CLEAR_CPLD_HIGH_BYTE();
|
||||
|
||||
// Read the input registers and set value accordingly.
|
||||
result = (uint16_t)READ_CPLD_DATA_IN();
|
||||
|
||||
// High byte next.
|
||||
SET_CPLD_HIGH_BYTE();
|
||||
|
||||
// Read the input registers and set value accordingly.
|
||||
result |= (uint16_t)(READ_CPLD_DATA_IN() << 8);
|
||||
|
||||
// Return 16bit value read from CPLD.
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
// Parallel Bus methods were tried and tested but due to the GPIO bits being controlled by individual registers per bit, the setup time was longer
|
||||
// than the transmission time of SPI. These methods are thus deprecated and a fusion of SPI and 8bit parallel is now used.
|
||||
#ifdef NOTNEEDED
|
||||
inline uint8_t z80io_PRL_Send8(uint8_t txData)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
|
||||
// Low byte only.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_HIGH_BYTE].r_out) &= (~gpio_table[PAD_Z80IO_HIGH_BYTE ].m_out);
|
||||
|
||||
// Setup data.
|
||||
if(txData & 0x0080) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_7].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_7].m_out); }
|
||||
if(txData & 0x0040) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_6].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_6].m_out); }
|
||||
if(txData & 0x0020) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_5].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_5].m_out); }
|
||||
if(txData & 0x0010) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_4].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_4].m_out); }
|
||||
if(txData & 0x0008) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_3].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_3].m_out); }
|
||||
if(txData & 0x0004) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_2].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_2].m_out); }
|
||||
if(txData & 0x0002) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_1].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_1].m_out); }
|
||||
if(txData & 0x0001) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_0].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_0].m_out); }
|
||||
|
||||
// Clock data.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) &= (~gpio_table[PAD_Z80IO_WRITE ].m_out);
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) |= gpio_table[PAD_Z80IO_WRITE ].m_out;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
inline uint8_t z80io_PRL_Send16(uint16_t txData)
|
||||
{
|
||||
// Locals.
|
||||
//
|
||||
|
||||
// Low byte first.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_HIGH_BYTE].r_out) &= (~gpio_table[PAD_Z80IO_HIGH_BYTE ].m_out);
|
||||
|
||||
// Setup data.
|
||||
if(txData & 0x0080) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_7].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_7].m_out); }
|
||||
if(txData & 0x0040) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_6].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_6].m_out); }
|
||||
if(txData & 0x0020) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_5].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_5].m_out); }
|
||||
if(txData & 0x0010) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_4].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_4].m_out); }
|
||||
if(txData & 0x0008) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_3].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_3].m_out); }
|
||||
if(txData & 0x0004) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_2].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_2].m_out); }
|
||||
if(txData & 0x0002) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_1].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_1].m_out); }
|
||||
if(txData & 0x0001) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_0].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_0].m_out); }
|
||||
|
||||
// Clock data.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) &= (~gpio_table[PAD_Z80IO_WRITE ].m_out);
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) |= gpio_table[PAD_Z80IO_WRITE ].m_out;
|
||||
|
||||
// High byte next.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_HIGH_BYTE ].r_out) |= gpio_table[PAD_Z80IO_HIGH_BYTE ].m_out;
|
||||
|
||||
// Setup high byte.
|
||||
if(txData & 0x8000) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_7].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_7].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_7].m_out); }
|
||||
if(txData & 0x4000) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_6].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_6].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_6].m_out); }
|
||||
if(txData & 0x2000) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_5].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_5].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_5].m_out); }
|
||||
if(txData & 0x1000) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_4].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_4].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_4].m_out); }
|
||||
if(txData & 0x0800) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_3].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_3].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_3].m_out); }
|
||||
if(txData & 0x0400) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_2].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_2].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_2].m_out); }
|
||||
if(txData & 0x0200) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_1].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_1].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_1].m_out); }
|
||||
if(txData & 0x0100) { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) |= gpio_table[PAD_Z80IO_OUT_DATA_0].m_out; } else { MHal_RIU_REG(gpio_table[PAD_Z80IO_OUT_DATA_0].r_out) &= (~gpio_table[PAD_Z80IO_OUT_DATA_0].m_out); }
|
||||
|
||||
// Clock data.
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) &= (~gpio_table[PAD_Z80IO_WRITE ].m_out);
|
||||
MHal_RIU_REG(gpio_table[PAD_Z80IO_WRITE].r_out) |= gpio_table[PAD_Z80IO_WRITE ].m_out;
|
||||
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------------
|
||||
// SPI Methods.
|
||||
//--------------------------------------------------------
|
||||
|
||||
// Methods to send 8,16 or 32 bits. Each method is seperate to minimise logic and execution time, 8bit being most sensitive.
|
||||
// Macros have also been defined for inline inclusion which dont read back the response data.
|
||||
//
|
||||
uint8_t z80io_SPI_Send8(uint8_t txData, uint8_t *rxData)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t timeout = MAX_CHECK_CNT;
|
||||
|
||||
// Insert data into write buffers.
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)txData);
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 1);
|
||||
|
||||
// Enable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE);
|
||||
|
||||
// Send.
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER);
|
||||
|
||||
// Wait for completion.
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0)
|
||||
{
|
||||
if(--timeout == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// Disable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE);
|
||||
|
||||
// Clear flag.
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE);
|
||||
|
||||
// Fetch data.
|
||||
if(rxData != NULL) *rxData = (uint8_t)MSPI_READ(MSPI_FULL_DEPLUX_RD00);
|
||||
|
||||
// Done.
|
||||
return(timeout == 0);
|
||||
}
|
||||
uint8_t z80io_SPI_Send16(uint16_t txData, uint16_t *rxData)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t timeout = MAX_CHECK_CNT;
|
||||
|
||||
// Insert data into write buffers.
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, txData);
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 2);
|
||||
|
||||
// Enable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE);
|
||||
|
||||
// Send.
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER);
|
||||
|
||||
// Wait for completion.
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0)
|
||||
{
|
||||
if(--timeout == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// Disable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE);
|
||||
|
||||
// Clear flag.
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE);
|
||||
|
||||
// Fetch data.
|
||||
if(rxData != NULL) *rxData = MSPI_READ(MSPI_FULL_DEPLUX_RD00);
|
||||
|
||||
// Done.
|
||||
return(timeout == 0);
|
||||
}
|
||||
uint8_t z80io_SPI_Send32(uint32_t txData, uint32_t *rxData)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t timeout = MAX_CHECK_CNT;
|
||||
|
||||
// Insert data into write buffers.
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)txData);
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET+1, (uint16_t)(txData >> 16));
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 4);
|
||||
|
||||
// Enable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE);
|
||||
|
||||
// Send.
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER);
|
||||
|
||||
// Wait for completion.
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0)
|
||||
{
|
||||
if(--timeout == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
// Disable SPI select.
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE);
|
||||
|
||||
// Clear flag.
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE);
|
||||
|
||||
// Fetch data.
|
||||
if(rxData != NULL) *rxData = (uint32_t)(MSPI_READ(MSPI_FULL_DEPLUX_RD00) | (MSPI_READ(MSPI_FULL_DEPLUX_RD02) << 16));
|
||||
|
||||
// Done.
|
||||
return(timeout == 0);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
// Test Methods.
|
||||
//--------------------------------------------------------
|
||||
#if defined(INCLUDE_TEST_METHODS) && INCLUDE_TEST_METHODS == 1
|
||||
#include "z80io_test.c"
|
||||
#else
|
||||
uint8_t z80io_Z80_TestMemory(void)
|
||||
{
|
||||
pr_info("Z80 Test Memory functionality not built-in.\n");
|
||||
return(0);
|
||||
}
|
||||
uint8_t z80io_SPI_Test(void)
|
||||
{
|
||||
pr_info("SPI Test functionality not built-in.\n");
|
||||
return(0);
|
||||
}
|
||||
uint8_t z80io_PRL_Test(void)
|
||||
{
|
||||
pr_info("Parallel Bus Test functionality not built-in.\n");
|
||||
return(0);
|
||||
}
|
||||
#endif
|
||||
562
software/FusionX/src/ttymz/z80io.h
vendored
Executable file
562
software/FusionX/src/ttymz/z80io.h
vendored
Executable file
@@ -0,0 +1,562 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: z80io.h
|
||||
// Created: Oct 2022
|
||||
// Author(s): Philip Smart
|
||||
// Description: Z80 IO Interface
|
||||
// This file contains the declarations used in interfacing the SOM to the Z80 socket
|
||||
// and host hardware via a CPLD.
|
||||
// Credits:
|
||||
// Copyright: (c) 2019-2023 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: Oct 2022 v1.0 - Initial write of the z80 kernel driver software.
|
||||
// Jan 2023 v1.1 - Numerous new tries at increasing throughput to the CPLD failed.
|
||||
// Maximum read throughput of an 8bit byte due to the SSD202 GPIO
|
||||
// structure is approx 2MB/s - or 512K/s for a needed 32bit word.
|
||||
// Write is slower as you have to clock the data so sticking with SPI.
|
||||
//
|
||||
// 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/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
#ifndef Z80IO_H
|
||||
#define Z80IO_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Definitions to control compilation.
|
||||
#define INCLUDE_TEST_METHODS 0
|
||||
|
||||
// CPLD Commands.
|
||||
#define CPLD_CMD_FETCH_ADDR 0x10
|
||||
#define CPLD_CMD_FETCH_ADDR_P1 0x11
|
||||
#define CPLD_CMD_FETCH_ADDR_P2 0x12
|
||||
#define CPLD_CMD_FETCH_ADDR_P3 0x13
|
||||
#define CPLD_CMD_FETCH_ADDR_P4 0x14
|
||||
#define CPLD_CMD_FETCH_ADDR_P5 0x15
|
||||
#define CPLD_CMD_FETCH_ADDR_P6 0x16
|
||||
#define CPLD_CMD_FETCH_ADDR_P7 0x17
|
||||
#define CPLD_CMD_WRITE_ADDR 0x18
|
||||
#define CPLD_CMD_WRITE_ADDR_P1 0x19
|
||||
#define CPLD_CMD_WRITE_ADDR_P2 0x1A
|
||||
#define CPLD_CMD_WRITE_ADDR_P3 0x1B
|
||||
#define CPLD_CMD_WRITE_ADDR_P4 0x1C
|
||||
#define CPLD_CMD_WRITE_ADDR_P5 0x1D
|
||||
#define CPLD_CMD_WRITE_ADDR_P6 0x1E
|
||||
#define CPLD_CMD_WRITE_ADDR_P7 0x1F
|
||||
#define CPLD_CMD_READ_ADDR 0x20
|
||||
#define CPLD_CMD_READ_ADDR_P1 0x21
|
||||
#define CPLD_CMD_READ_ADDR_P2 0x22
|
||||
#define CPLD_CMD_READ_ADDR_P3 0x23
|
||||
#define CPLD_CMD_READ_ADDR_P4 0x24
|
||||
#define CPLD_CMD_READ_ADDR_P5 0x25
|
||||
#define CPLD_CMD_READ_ADDR_P6 0x26
|
||||
#define CPLD_CMD_READ_ADDR_P7 0x27
|
||||
#define CPLD_CMD_WRITEIO_ADDR 0x28
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P1 0x29
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P2 0x2A
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P3 0x2B
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P4 0x2C
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P5 0x2D
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P6 0x2E
|
||||
#define CPLD_CMD_WRITEIO_ADDR_P7 0x2F
|
||||
#define CPLD_CMD_READIO_ADDR 0x30
|
||||
#define CPLD_CMD_READIO_ADDR_P1 0x31
|
||||
#define CPLD_CMD_READIO_ADDR_P2 0x32
|
||||
#define CPLD_CMD_READIO_ADDR_P3 0x33
|
||||
#define CPLD_CMD_READIO_ADDR_P4 0x34
|
||||
#define CPLD_CMD_READIO_ADDR_P5 0x35
|
||||
#define CPLD_CMD_READIO_ADDR_P6 0x36
|
||||
#define CPLD_CMD_READIO_ADDR_P7 0x37
|
||||
#define CPLD_CMD_READIO_WRITE_ADDR 0x38
|
||||
#define CPLD_CMD_READIO_WRITE_ADDR_P1 0x39
|
||||
#define CPLD_CMD_READIO_WRITE_ADDR_P2 0x3A
|
||||
#define CPLD_CMD_READIO_WRITE_ADDR_P3 0x3B
|
||||
#define CPLD_CMD_READIO_WRITE_ADDR_P4 0x3C
|
||||
#define CPLD_CMD_READIO_WRITE_ADDR_P5 0x3D
|
||||
#define CPLD_CMD_READIO_WRITE_ADDR_P6 0x3E
|
||||
#define CPLD_CMD_READIO_WRITE_ADDR_P7 0x3F
|
||||
#define CPLD_CMD_HALT 0x50
|
||||
#define CPLD_CMD_REFRESH 0x51
|
||||
#define CPLD_CMD_SET_SIGROUP1 0xF0
|
||||
#define CPLD_CMD_SET_AUTO_REFRESH 0xF1
|
||||
#define CPLD_CMD_CLEAR_AUTO_REFRESH 0xF2
|
||||
#define CPLD_CMD_SET_SPI_LOOPBACK 0xFE
|
||||
#define CPLD_CMD_NOP1 0x00
|
||||
#define CPLD_CMD_NOP2 0xFF
|
||||
|
||||
|
||||
// Pad numbers for using the MHal GPIO library.
|
||||
#define PAD_Z80IO_IN_DATA_0 PAD_GPIO0
|
||||
#define PAD_Z80IO_IN_DATA_1 PAD_GPIO1
|
||||
#define PAD_Z80IO_IN_DATA_2 PAD_GPIO2
|
||||
#define PAD_Z80IO_IN_DATA_3 PAD_GPIO3
|
||||
#define PAD_Z80IO_IN_DATA_4 PAD_GPIO4
|
||||
#define PAD_Z80IO_IN_DATA_5 PAD_GPIO5
|
||||
#define PAD_Z80IO_IN_DATA_6 PAD_GPIO6
|
||||
#define PAD_Z80IO_IN_DATA_7 PAD_GPIO7
|
||||
#define PAD_SPIO_0 PAD_GPIO8
|
||||
#define PAD_SPIO_1 PAD_GPIO9
|
||||
#define PAD_SPIO_2 PAD_GPIO10
|
||||
#define PAD_SPIO_3 PAD_GPIO11
|
||||
#define PAD_Z80IO_HIGH_BYTE PAD_SAR_GPIO2 // Byte requiured, 0 = Low Byte, 1 = High Byte.
|
||||
#define PAD_Z80IO_READY PAD_GPIO12
|
||||
#define PAD_Z80IO_LTSTATE PAD_UART0_RX // GPIO47
|
||||
#define PAD_Z80IO_BUSRQ PAD_GPIO13
|
||||
#define PAD_Z80IO_BUSACK PAD_GPIO14
|
||||
#define PAD_Z80IO_INT PAD_PM_IRIN // IRIN
|
||||
#define PAD_Z80IO_NMI PAD_UART0_TX // GPIO48
|
||||
#define PAD_Z80IO_WAIT PAD_HSYNC_OUT // GPIO85
|
||||
#define PAD_Z80IO_RESET PAD_VSYNC_OUT // GPIO86
|
||||
#define PAD_Z80IO_RSV1 PAD_SATA_GPIO // GPIO90
|
||||
|
||||
// Physical register addresses.
|
||||
#define PAD_Z80IO_IN_DATA_0_ADDR 0x103C00
|
||||
#define PAD_Z80IO_IN_DATA_1_ADDR 0x103C02
|
||||
#define PAD_Z80IO_IN_DATA_2_ADDR 0x103C04
|
||||
#define PAD_Z80IO_IN_DATA_3_ADDR 0x103C06
|
||||
#define PAD_Z80IO_IN_DATA_4_ADDR 0x103C08
|
||||
#define PAD_Z80IO_IN_DATA_5_ADDR 0x103C0A
|
||||
#define PAD_Z80IO_IN_DATA_6_ADDR 0x103C0C
|
||||
#define PAD_Z80IO_IN_DATA_7_ADDR 0x103C0E
|
||||
#define PAD_SPIO_0_ADDR 0x103C10
|
||||
#define PAD_SPIO_1_ADDR 0x103C12
|
||||
#define PAD_SPIO_2_ADDR 0x103C14
|
||||
#define PAD_SPIO_3_ADDR 0x103C16
|
||||
#define PAD_Z80IO_HIGH_BYTE_ADDR 0x1425
|
||||
#define PAD_Z80IO_READY_ADDR 0x103C18
|
||||
#define PAD_Z80IO_LTSTATE_ADDR 0x103C30 // GPIO47
|
||||
#define PAD_Z80IO_BUSRQ_ADDR 0x103C1A
|
||||
#define PAD_Z80IO_BUSACK_ADDR 0x103C1C
|
||||
#define PAD_Z80IO_INT_ADDR 0xF28 // IRIN
|
||||
#define PAD_Z80IO_NMI_ADDR 0x103C32 // GPIO48
|
||||
#define PAD_Z80IO_WAIT_ADDR 0x103C80 // GPIO85
|
||||
#define PAD_Z80IO_RESET_ADDR 0x103C82 // GPIO86
|
||||
#define PAD_Z80IO_RSV1_ADDR 0x103C8A // GPIO90
|
||||
|
||||
#ifdef NOTNEEDED
|
||||
#define PAD_Z80IO_OUT_DATA_0 PAD_GPIO12
|
||||
#define PAD_Z80IO_OUT_DATA_1 PAD_GPIO13
|
||||
#define PAD_Z80IO_OUT_DATA_2 PAD_GPIO14
|
||||
#define PAD_Z80IO_OUT_DATA_3 PAD_UART0_RX // GPIO47
|
||||
#define PAD_Z80IO_OUT_DATA_4 PAD_UART0_TX // GPIO48
|
||||
#define PAD_Z80IO_OUT_DATA_5 PAD_HSYNC_OUT // GPIO85
|
||||
#define PAD_Z80IO_OUT_DATA_6 PAD_VSYNC_OUT // GPIO86
|
||||
#define PAD_Z80IO_OUT_DATA_7 PAD_SATA_GPIO // GPIO90
|
||||
#define PAD_Z80IO_WRITE PAD_PM_IRIN // Write data clock.
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// The definitions below come from SigmaStar kernel drivers. No header file exists hence the
|
||||
// duplication.
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
#define SUPPORT_SPI_1 0
|
||||
#define MAX_SUPPORT_BITS 16
|
||||
|
||||
#define BANK_TO_ADDR32(b) (b<<9)
|
||||
#define BANK_SIZE 0x200
|
||||
|
||||
#define MS_BASE_REG_RIU_PA 0x1F000000
|
||||
#define gChipBaseAddr 0xFD203C00
|
||||
#define gPmSleepBaseAddr 0xFD001C00
|
||||
#define gSarBaseAddr 0xFD002800
|
||||
#define gRIUBaseAddr 0xFD000000
|
||||
#define gMOVDMAAddr 0xFD201600
|
||||
#define gClkBaseAddr 0xFD207000
|
||||
#define gMspBaseAddr 0xfd222000
|
||||
|
||||
#define MHal_CHIPTOP_REG(addr) (*(volatile U8*)((gChipBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_PM_SLEEP_REG(addr) (*(volatile U8*)((gPmSleepBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_SAR_GPIO_REG(addr) (*(volatile U8*)((gSarBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_RIU_REG(addr) (*(volatile U8*)((gRIUBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
|
||||
|
||||
#define MSPI0_BANK_ADDR 0x1110
|
||||
#define MSPI1_BANK_ADDR 0x1111
|
||||
#define CLK__BANK_ADDR 0x1038
|
||||
#define CHIPTOP_BANK_ADDR 0x101E
|
||||
#define MOVDMA_BANK_ADDR 0x100B
|
||||
|
||||
#define BASE_REG_MSPI0_ADDR MSPI0_BANK_ADDR*0x200 //GET_BASE_ADDR_BY_BANK(IO_ADDRESS(MS_BASE_REG_RIU_PA), 0x111000)
|
||||
#define BASE_REG_MSPI1_ADDR MSPI1_BANK_ADDR*0x200 //GET_BASE_ADDR_BY_BANK(IO_ADDRESS(MS_BASE_REG_RIU_PA), 0x111100)
|
||||
#define BASE_REG_CLK_ADDR CLK__BANK_ADDR*0x200 //GET_BASE_ADDR_BY_BANK(IO_ADDRESS(MS_BASE_REG_RIU_PA), 0x103800)
|
||||
#define BASE_REG_CHIPTOP_ADDR CHIPTOP_BANK_ADDR*0x200 //GET_BASE_ADDR_BY_BANK(IO_ADDRESS(MS_BASE_REG_RIU_PA), 0x101E00)
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Hardware Register Capability
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
#define MSPI_WRITE_BUF_OFFSET 0x40
|
||||
#define MSPI_READ_BUF_OFFSET 0x44
|
||||
#define MSPI_WBF_SIZE_OFFSET 0x48
|
||||
#define MSPI_RBF_SIZE_OFFSET 0x48
|
||||
// read/ write buffer size
|
||||
#define MSPI_RWSIZE_MASK 0xFF
|
||||
#define MSPI_RSIZE_BIT_OFFSET 0x8
|
||||
#define MAX_READ_BUF_SIZE 0x8
|
||||
#define MAX_WRITE_BUF_SIZE 0x8
|
||||
// CLK config
|
||||
#define MSPI_CTRL_OFFSET 0x49
|
||||
#define MSPI_CLK_CLOCK_OFFSET 0x49
|
||||
#define MSPI_CLK_CLOCK_BIT_OFFSET 0x08
|
||||
#define MSPI_CLK_CLOCK_MASK 0xFF
|
||||
#define MSPI_CLK_PHASE_MASK 0x40
|
||||
#define MSPI_CLK_PHASE_BIT_OFFSET 0x06
|
||||
#define MSPI_CLK_POLARITY_MASK 0x80
|
||||
#define MSPI_CLK_POLARITY_BIT_OFFSET 0x07
|
||||
#define MSPI_CLK_PHASE_MAX 0x1
|
||||
#define MSPI_CLK_POLARITY_MAX 0x1
|
||||
#define MSPI_CLK_CLOCK_MAX 0x7
|
||||
#define MSPI_CTRL_CPOL_LOW 0x00
|
||||
#define MSPI_CTRL_CPOL_HIGH 0x80
|
||||
#define MSPI_CTRL_CPHA_LOW 0x00
|
||||
#define MSPI_CTRL_CPHA_HIGH 0x40
|
||||
#define MSPI_CTRL_3WIRE 0x10
|
||||
#define MSPI_CTRL_INTEN 0x04
|
||||
#define MSPI_CTRL_RESET 0x02
|
||||
#define MSPI_CTRL_ENABLE_SPI 0x01
|
||||
// DC config
|
||||
#define MSPI_DC_MASK 0xFF
|
||||
#define MSPI_DC_BIT_OFFSET 0x08
|
||||
#define MSPI_DC_TR_START_OFFSET 0x4A
|
||||
#define MSPI_DC_TRSTART_MAX 0xFF
|
||||
#define MSPI_DC_TR_END_OFFSET 0x4A
|
||||
#define MSPI_DC_TREND_MAX 0xFF
|
||||
#define MSPI_DC_TB_OFFSET 0x4B
|
||||
#define MSPI_DC_TB_MAX 0xFF
|
||||
#define MSPI_DC_TRW_OFFSET 0x4B
|
||||
#define MSPI_DC_TRW_MAX 0xFF
|
||||
// Frame Config
|
||||
#define MSPI_FRAME_WBIT_OFFSET 0x4C
|
||||
#define MSPI_FRAME_RBIT_OFFSET 0x4E
|
||||
#define MSPI_FRAME_BIT_MAX 0x07
|
||||
#define MSPI_FRAME_BIT_MASK 0x07
|
||||
#define MSPI_FRAME_BIT_FIELD 0x03
|
||||
#define MSPI_LSB_FIRST_OFFSET 0x50
|
||||
#define MSPI_TRIGGER_OFFSET 0x5A
|
||||
#define MSPI_DONE_OFFSET 0x5B
|
||||
#define MSPI_DONE_CLEAR_OFFSET 0x5C
|
||||
#define MSPI_CHIP_SELECT_OFFSET 0x5F
|
||||
#define MSPI_CS1_DISABLE 0x01
|
||||
#define MSPI_CS1_ENABLE 0x00
|
||||
#define MSPI_CS2_DISABLE 0x02
|
||||
#define MSPI_CS2_ENABLE 0x00
|
||||
#define MSPI_CS3_DISABLE 0x04
|
||||
#define MSPI_CS3_ENABLE 0x00
|
||||
#define MSPI_CS4_DISABLE 0x08
|
||||
#define MSPI_CS4_ENABLE 0x00
|
||||
#define MSPI_CS5_DISABLE 0x10
|
||||
#define MSPI_CS5_ENABLE 0x00
|
||||
#define MSPI_CS6_DISABLE 0x20
|
||||
#define MSPI_CS6_ENABLE 0x00
|
||||
#define MSPI_CS7_DISABLE 0x40
|
||||
#define MSPI_CS7_ENABLE 0x00
|
||||
#define MSPI_CS8_DISABLE 0x80
|
||||
#define MSPI_CS8_ENABLE 0x00
|
||||
|
||||
#define MSPI_FULL_DEPLUX_RD_CNT (0x77)
|
||||
#define MSPI_FULL_DEPLUX_RD00 (0x78)
|
||||
#define MSPI_FULL_DEPLUX_RD01 (0x78)
|
||||
#define MSPI_FULL_DEPLUX_RD02 (0x79)
|
||||
#define MSPI_FULL_DEPLUX_RD03 (0x79)
|
||||
#define MSPI_FULL_DEPLUX_RD04 (0x7a)
|
||||
#define MSPI_FULL_DEPLUX_RD05 (0x7a)
|
||||
#define MSPI_FULL_DEPLUX_RD06 (0x7b)
|
||||
#define MSPI_FULL_DEPLUX_RD07 (0x7b)
|
||||
|
||||
#define MSPI_FULL_DEPLUX_RD08 (0x7c)
|
||||
#define MSPI_FULL_DEPLUX_RD09 (0x7c)
|
||||
#define MSPI_FULL_DEPLUX_RD10 (0x7d)
|
||||
#define MSPI_FULL_DEPLUX_RD11 (0x7d)
|
||||
#define MSPI_FULL_DEPLUX_RD12 (0x7e)
|
||||
#define MSPI_FULL_DEPLUX_RD13 (0x7e)
|
||||
#define MSPI_FULL_DEPLUX_RD14 (0x7f)
|
||||
#define MSPI_FULL_DEPLUX_RD15 (0x7f)
|
||||
|
||||
//chip select bit map
|
||||
#define MSPI_CHIP_SELECT_MAX 0x07
|
||||
|
||||
// control bit
|
||||
#define MSPI_DONE_FLAG 0x01
|
||||
#define MSPI_TRIGGER 0x01
|
||||
#define MSPI_CLEAR_DONE 0x01
|
||||
#define MSPI_INT_ENABLE 0x04
|
||||
#define MSPI_RESET 0x02
|
||||
#define MSPI_ENABLE 0x01
|
||||
|
||||
// clk_mspi0
|
||||
#define MSPI0_CLK_CFG 0x33 //bit 2 ~bit 3
|
||||
#define MSPI0_CLK_108M 0x00
|
||||
#define MSPI0_CLK_54M 0x04
|
||||
#define MSPI0_CLK_12M 0x08
|
||||
#define MSPI0_CLK_MASK 0x0F
|
||||
|
||||
// clk_mspi1
|
||||
#define MSPI1_CLK_CFG 0x33 //bit 10 ~bit 11
|
||||
#define MSPI1_CLK_108M 0x0000
|
||||
#define MSPI1_CLK_54M 0x0400
|
||||
#define MSPI1_CLK_12M 0x0800
|
||||
#define MSPI1_CLK_MASK 0x0F00
|
||||
|
||||
// clk_mspi
|
||||
#define MSPI_CLK_CFG 0x33
|
||||
#define MSPI_SELECT_0 0x0000
|
||||
#define MSPI_SELECT_1 0x4000
|
||||
#define MSPI_CLK_MASK 0xF000
|
||||
|
||||
// Clock settings
|
||||
#define MSPI_CPU_CLOCK_1_2 0x0000
|
||||
#define MSPI_CPU_CLOCK_1_4 0x0100
|
||||
#define MSPI_CPU_CLOCK_1_8 0x0200
|
||||
#define MSPI_CPU_CLOCK_1_16 0x0300
|
||||
#define MSPI_CPU_CLOCK_1_32 0x0400
|
||||
#define MSPI_CPU_CLOCK_1_64 0x0500
|
||||
#define MSPI_CPU_CLOCK_1_128 0x0600
|
||||
#define MSPI_CPU_CLOCK_1_256 0x0700
|
||||
|
||||
//CHITOP 101E mspi mode select
|
||||
#define MSPI0_MODE 0x0C //bit0~bit1
|
||||
#define MSPI0_MODE_MASK 0x07
|
||||
#define MSPI1_MODE 0x0C //bit4~bit5
|
||||
#define MSPI1_MODE_MASK 0x70
|
||||
#define EJTAG_MODE 0xF
|
||||
#define EJTAG_MODE_1 0x01
|
||||
#define EJTAG_MODE_2 0x02
|
||||
#define EJTAG_MODE_3 0x03
|
||||
#define EJTAG_MODE_MASK 0x03
|
||||
|
||||
//MOVDMA 100B
|
||||
#define MOV_DMA_SRC_ADDR_L 0x03
|
||||
#define MOV_DMA_SRC_ADDR_H 0x04
|
||||
#define MOV_DMA_DST_ADDR_L 0x05
|
||||
#define MOV_DMA_DST_ADDR_H 0x06
|
||||
#define MOV_DMA_BYTE_CNT_L 0x07
|
||||
#define MOV_DMA_BYTE_CNT_H 0x08
|
||||
#define DMA_MOVE0_IRQ_CLR 0x28
|
||||
#define MOV_DMA_IRQ_FINAL_STATUS 0x2A
|
||||
#define DMA_MOVE0_ENABLE 0x00
|
||||
#define DMA_RW 0x50 //0 for dma write to device, 1 for dma read from device
|
||||
#define DMA_READ 0x01
|
||||
#define DMA_WRITE 0x00
|
||||
#define DMA_DEVICE_MODE 0x51
|
||||
#define DMA_DEVICE_SEL 0x52
|
||||
|
||||
//spi dma
|
||||
#define MSPI_DMA_DATA_LENGTH_L 0x30
|
||||
#define MSPI_DMA_DATA_LENGTH_H 0x31
|
||||
#define MSPI_DMA_ENABLE 0x32
|
||||
#define MSPI_DMA_RW_MODE 0x33
|
||||
#define MSPI_DMA_WRITE 0x00
|
||||
#define MSPI_DMA_READ 0x01
|
||||
|
||||
#define MSTAR_SPI_TIMEOUT_MS 30000
|
||||
#define MSTAR_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA /*| SPI_CS_HIGH | SPI_NO_CS | SPI_LSB_FIRST*/)
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// Macros
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#define MHal_CHIPTOP_REG(addr) (*(volatile U8*)((gChipBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_PM_SLEEP_REG(addr) (*(volatile U8*)((gPmSleepBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_SAR_GPIO_REG(addr) (*(volatile U8*)((gSarBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define MHal_RIU_REG(addr) (*(volatile U8*)((gRIUBaseAddr) + (((addr) & ~1)<<1) + (addr & 1)))
|
||||
#define READ_BYTE(_reg) (*(volatile u8*)(_reg))
|
||||
#define READ_WORD(_reg) (*(volatile u16*)(_reg))
|
||||
#define READ_LONG(_reg) (*(volatile u32*)(_reg))
|
||||
#define WRITE_BYTE(_reg, _val) {(*((volatile u8*)(_reg))) = (u8)(_val); }
|
||||
#define WRITE_WORD(_reg, _val) {(*((volatile u16*)(_reg))) = (u16)(_val); }
|
||||
#define WRITE_LONG(_reg, _val) {(*((volatile u32*)(_reg))) = (u32)(_val); }
|
||||
#define WRITE_WORD_MASK(_reg, _val, _mask) {(*((volatile u16*)(_reg))) = ((*((volatile u16*)(_reg))) & ~(_mask)) | ((u16)(_val) & (_mask)); }
|
||||
#define READ_CPLD_DATA_IN() ((MHal_RIU_REG(PAD_Z80IO_IN_DATA_7_ADDR) & 0x1) << 7 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_6_ADDR) & 0x1) << 6 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_5_ADDR) & 0x1) << 5 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_4_ADDR) & 0x1) << 4 |\
|
||||
(MHal_RIU_REG(PAD_Z80IO_IN_DATA_3_ADDR) & 0x1) << 3 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_2_ADDR) & 0x1) << 2 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_1_ADDR) & 0x1) << 1 | (MHal_RIU_REG(PAD_Z80IO_IN_DATA_0_ADDR) & 0x1))
|
||||
#define SET_CPLD_READ_DATA() {MHal_RIU_REG(PAD_Z80IO_HIGH_BYTE_ADDR) |= 0x4;}
|
||||
#define SET_CPLD_READ_STATUS() {MHal_RIU_REG(PAD_Z80IO_HIGH_BYTE_ADDR) &= ~0x4;}
|
||||
#define SET_CPLD_HIGH_BYTE() {MHal_RIU_REG(PAD_Z80IO_HIGH_BYTE_ADDR) |= 0x4;}
|
||||
#define CLEAR_CPLD_HIGH_BYTE() {MHal_RIU_REG(PAD_Z80IO_HIGH_BYTE_ADDR) &= ~0x4;}
|
||||
#define CPLD_READY() (MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1)
|
||||
#define CPLD_RESET() (MHal_RIU_REG(PAD_Z80IO_RESET_ADDR) & 0x1)
|
||||
#define CPLD_LAST_TSTATE() (MHal_RIU_REG(PAD_Z80IO_LTSTATE_ADDR) & 0x4)
|
||||
#define CPLD_Z80_INT() (MHal_RIU_REG(PAD_Z80IO_INT_ADDR) & 0x4)
|
||||
#define CPLD_Z80_NMI() (MHal_RIU_REG(PAD_Z80IO_NMI_ADDR) & 0x4)
|
||||
#define SPI_SEND_8(_d_) { uint32_t timeout = MAX_CHECK_CNT; \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)_d_); \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 1); \
|
||||
while((MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1) == 0);\
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE);\
|
||||
}
|
||||
#define SPI_SEND_I_8(_d_) { uint32_t timeout = MAX_CHECK_CNT; \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)_d_); \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 1); \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE);\
|
||||
}
|
||||
#define SPI_SEND16(_d_) { uint32_t timeout = MAX_CHECK_CNT; \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 2); \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)(_d_)); \
|
||||
while((MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1) == 0);\
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE); \
|
||||
}
|
||||
#define SPI_SEND_16(_d1_) { uint32_t timeout = MAX_CHECK_CNT; \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 2); \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)_d1_); \
|
||||
while((MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1) == 0);\
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE); \
|
||||
}
|
||||
#define SPI_SEND_P_16(_d1_) { uint32_t timeout = MAX_CHECK_CNT; \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 2); \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)_d1_); \
|
||||
while((MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1) != 0);\
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE); \
|
||||
}
|
||||
#define SPI_SET_FRAME_SIZE() { MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 4); \
|
||||
}
|
||||
#define SPI_SEND32(_d_) { uint32_t timeout = MAX_CHECK_CNT*2; \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 4); \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)(_d_)); \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET+1, (uint16_t)((_d_) >> 16)); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE); \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
while((MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1) == 0) { if(--timeout == 0) break; };\
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
}
|
||||
#define SPI_SEND_32(_d1_, _d2_) { uint32_t timeout = MAX_CHECK_CNT*2; \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 4); \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)_d2_); \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET+1, (uint16_t)_d1_); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE); \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
while((MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1) == 0) { if(--timeout == 0) break; };\
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
}
|
||||
#define SPI_SEND_I_32(_d1_, _d2_) { uint32_t timeout = MAX_CHECK_CNT*2; \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 4); \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)_d2_); \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET+1, (uint16_t)_d1_); \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE); \
|
||||
}
|
||||
#define SPI_SEND_48(_d1_, _d2_, _d3_) { uint32_t timeout = MAX_CHECK_CNT*2; \
|
||||
MSPI_WRITE(MSPI_WBF_SIZE_OFFSET, 6); \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET, (uint16_t)_d3_); \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET+1, (uint16_t)_d2_); \
|
||||
MSPI_WRITE(MSPI_WRITE_BUF_OFFSET+2, (uint16_t)_d1_); \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_ENABLE); \
|
||||
while((MHal_RIU_REG(PAD_Z80IO_READY_ADDR) & 0x1) == 0) { if(--timeout == 0) break; };\
|
||||
MSPI_WRITE(MSPI_TRIGGER_OFFSET, MSPI_TRIGGER); \
|
||||
while((MSPI_READ(MSPI_DONE_OFFSET) & MSPI_DONE_FLAG) == 0) { if(--timeout == 0) break; } \
|
||||
MSPI_WRITE(MSPI_CHIP_SELECT_OFFSET, MSPI_CS8_DISABLE | MSPI_CS7_DISABLE | MSPI_CS6_DISABLE | MSPI_CS5_DISABLE | MSPI_CS4_DISABLE | MSPI_CS3_DISABLE | MSPI_CS2_DISABLE | MSPI_CS1_DISABLE); \
|
||||
MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET, MSPI_CLEAR_DONE); \
|
||||
}
|
||||
|
||||
// read 2 byte
|
||||
#define MSPI_READ(_reg_) READ_WORD(gMspBaseAddr + ((_reg_)<<2))
|
||||
// write 2 byte
|
||||
//#define MSPI_WRITE(_reg_, _val_) {pr_info("PDS: MSPI_WRITE(0x%x, 0x%x, 0x%x)\n", _reg_, _val_, gMspBaseAddr + ((_reg_)<<2)); WRITE_WORD(gMspBaseAddr + ((_reg_)<<2), (_val_)); }
|
||||
#define MSPI_WRITE(_reg_, _val_) WRITE_WORD(gMspBaseAddr + ((_reg_)<<2), (_val_));
|
||||
//write 2 byte mask
|
||||
//#define MSPI_WRITE_MASK(_reg_, _val_, mask) {pr_info("PDS: WRITE_LONG(0x%x, 0x%x, mask=0x%x)\n", _reg_, _val_, mask); WRITE_WORD_MASK(gMspBaseAddr + ((_reg_)<<2), (_val_), (mask)); }
|
||||
#define MSPI_WRITE_MASK(_reg_, _val_, mask) WRITE_WORD_MASK(gMspBaseAddr + ((_reg_)<<2), (_val_), (mask));
|
||||
|
||||
#define CLK_READ(_reg_) READ_WORD(gClkBaseAddr + ((_reg_)<<2))
|
||||
//#define CLK_WRITE(_reg_, _val_) {pr_info("PDS: CLK_WRITE(0x%x, 0x%x)\n", _reg_, _val_); WRITE_WORD(gClkBaseAddr + ((_reg_)<<2), (_val_)); }
|
||||
#define CLK_WRITE(_reg_, _val_) WRITE_WORD(gClkBaseAddr + ((_reg_)<<2), (_val_));
|
||||
|
||||
#define CHIPTOP_READ(_reg_) READ_WORD(gChipBaseAddr + ((_reg_)<<2))
|
||||
//#define CHIPTOP_WRITE(_reg_, _val_) {pr_info("PDS: CHIPTOP_WRITE(0x%x, 0x%x)\n", _reg_, _val_); WRITE_WORD(gChipBaseAddr + ((_reg_)<<2), (_val_)); }
|
||||
#define CHIPTOP_WRITE(_reg_, _val_) WRITE_WORD(gChipBaseAddr + ((_reg_)<<2), (_val_));
|
||||
|
||||
#define MOVDMA_READ(_reg_) READ_WORD(gMOVDMAAddr + ((_reg_)<<2))
|
||||
//#define MOVDMA_WRITE(_reg_, _val_) {pr_info("PDS: MOVDMA_WRITE(0x%x, 0x%x)\n", _reg_, _val_); WRITE_WORD(gMOVDMAAddr + ((_reg_)<<2), (_val_)); }
|
||||
#define MOVDMA_WRITE(_reg_, _val_) WRITE_WORD(gMOVDMAAddr + ((_reg_)<<2), (_val_));
|
||||
|
||||
#define _HAL_MSPI_ClearDone() MSPI_WRITE(MSPI_DONE_CLEAR_OFFSET,MSPI_CLEAR_DONE)
|
||||
#define MAX_CHECK_CNT 5000
|
||||
|
||||
#define MSPI_READ_INDEX 0x0
|
||||
#define MSPI_WRITE_INDEX 0x1
|
||||
|
||||
#define SPI_MIU0_BUS_BASE 0x20000000
|
||||
#define SPI_MIU1_BUS_BASE 0xFFFFFFFF
|
||||
|
||||
|
||||
// Function definitions.
|
||||
//
|
||||
int z80io_init(void);
|
||||
uint8_t z80io_SPI_Send8(uint8_t txData, uint8_t *rxData);
|
||||
uint8_t z80io_SPI_Send16(uint16_t txData, uint16_t *rxData);
|
||||
uint8_t z80io_SPI_Send32(uint32_t txData, uint32_t *rxData);
|
||||
#ifdef NOTNEEDED
|
||||
uint8_t z80io_PRL_Send8(uint8_t txData);
|
||||
uint8_t z680io_PRL_Send16(uint16_t txData);
|
||||
#endif
|
||||
uint8_t z80io_PRL_Read(void);
|
||||
uint8_t z80io_PRL_Read8(uint8_t dataFlag);
|
||||
uint16_t z80io_PRL_Read16(void);
|
||||
uint8_t z80io_SPI_Test(void);
|
||||
uint8_t z80io_PRL_Test(void);
|
||||
uint8_t z80io_Z80_TestMemory(void);
|
||||
|
||||
extern void MHal_GPIO_Init(void);
|
||||
extern void MHal_GPIO_Pad_Set(uint8_t u8IndexGPIO);
|
||||
extern int MHal_GPIO_PadGroupMode_Set(uint32_t u32PadMode);
|
||||
extern int MHal_GPIO_PadVal_Set(uint8_t u8IndexGPIO, uint32_t u32PadMode);
|
||||
extern void MHal_GPIO_Pad_Oen(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Pad_Odn(uint8_t u8IndexGPIO);
|
||||
extern uint8_t MHal_GPIO_Pad_Level(uint8_t u8IndexGPIO);
|
||||
extern uint8_t MHal_GPIO_Pad_InOut(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Pull_High(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Pull_Low(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Set_High(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Set_Low(uint8_t u8IndexGPIO);
|
||||
extern void MHal_Enable_GPIO_INT(uint8_t u8IndexGPIO);
|
||||
extern int MHal_GPIO_To_Irq(uint8_t u8IndexGPIO);
|
||||
extern void MHal_GPIO_Set_POLARITY(uint8_t u8IndexGPIO, uint8_t reverse);
|
||||
extern void MHal_GPIO_Set_Driving(uint8_t u8IndexGPIO, uint8_t setHigh);
|
||||
extern void MHal_GPIO_PAD_32K_OUT(uint8_t u8Enable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // Z80IO_H
|
||||
1
software/FusionX/src/z80drv/6502
vendored
Submodule
1
software/FusionX/src/z80drv/6502
vendored
Submodule
Submodule software/FusionX/src/z80drv/6502 added at 8318be6089
90
software/FusionX/src/z80drv/Makefile
vendored
Normal file
90
software/FusionX/src/z80drv/Makefile
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
#MODEL := MZ2000
|
||||
#MODEL := MZ1500
|
||||
#MODEL := MZ700
|
||||
#MODEL := MZ80A
|
||||
#MODEL := PCW8XXX
|
||||
#MODEL := PCW9XXX
|
||||
KERNEL := $(PWD)/../../../linux/kernel
|
||||
FUSIONX := $(PWD)/../..
|
||||
CROSS := arm-linux-gnueabihf-
|
||||
ccflags-y = -O2 -I${src}/Zeta/API -I${src}/Z80/API -I${KERNEL}/drivers/sstar/include -I${KERNEL}/drivers/sstar/include/infinity2m -I${KERNEL}/drivers/sstar/gpio/infinity2m -D__KERNEL_DRIVER__ -DTARGET_HOST_$(MODEL)=1
|
||||
CTRLINC = -IZeta/API -IZ80/API -DTARGET_HOST_$(MODEL)=1
|
||||
|
||||
obj-m += z80drv.o
|
||||
z80drv-objs += src/z80driver.o Z80.o src/z80io.o src/z80menu.o # emumz.o sharpmz.o osd.o
|
||||
z80drv-objs += ../../../linux/kernel/drivers/sstar/gpio/infinity2m/gpio_table.o
|
||||
z80drv-objs += ../../../linux/kernel/drivers/sstar/gpio/infinity2m/mhal_gpio.o
|
||||
z80drv-objs += ../../../linux/kernel/drivers/sstar/gpio/infinity2m/mhal_pinmux.o
|
||||
z80drv-objs += ../../../linux/kernel/drivers/sstar/gpio/infinity2m/padmux_tables.o
|
||||
|
||||
|
||||
all:
|
||||
@echo "Specify target host, ie. make <host>"
|
||||
@echo "Supported hosts: MZ80A, MZ700, MZ2000, PCW8XXX, PCW9XXX"
|
||||
|
||||
MZ80A: MODEL_MZ80A
|
||||
MZ700: MODEL_MZ700
|
||||
MZ1500: MODEL_MZ1500
|
||||
MZ2000: MODEL_MZ2000
|
||||
PCW8XXX: MODEL_PCW8XXX
|
||||
PCW9XXX: MODEL_PCW9XXX
|
||||
|
||||
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:
|
||||
$(MAKE) MODEL=PCW8XXX BUILD_PCW8XXX
|
||||
MODEL_PCW9XXX:
|
||||
$(MAKE) MODEL=PCW8XXX BUILD_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
|
||||
|
||||
|
||||
sharpbiter:
|
||||
@echo ""
|
||||
@echo "Build Sharp MZ Arbiter for host: $(MODEL)"
|
||||
$(CROSS)gcc $(CTRLINC) src/sharpbiter.c -o sharpbiter
|
||||
|
||||
k64fcpu:
|
||||
@echo ""
|
||||
@echo "Build K64F Daemon for host: $(MODEL)"
|
||||
$(CROSS)gcc $(CTRLINC) src/k64fcpu.c -o k64fcpu
|
||||
|
||||
kmod:
|
||||
@echo ""
|
||||
@echo "Build driver for host: $(MODEL)"
|
||||
make -C $(KERNEL) ARCH=arm CROSS_COMPILE=$(CROSS) M="$(PWD)" modules
|
||||
|
||||
z80ctrl:
|
||||
@echo ""
|
||||
@echo "Build z80ctrl tool for host: $(MODEL)"
|
||||
$(CROSS)gcc $(CTRLINC) src/z80ctrl.c -o z80ctrl
|
||||
|
||||
install:
|
||||
@echo "Copy kernel driver..."
|
||||
@cp z80drv.ko $(FUSIONX)/modules/
|
||||
@echo "Copy z80ctrl app..."
|
||||
@cp z80ctrl $(FUSIONX)/bin/
|
||||
@if [ -f sharpbiter ]; then\
|
||||
echo "Copy sharpbiter app...";\
|
||||
cp sharpbiter $(FUSIONX)/bin/;\
|
||||
fi
|
||||
@if [ -f k64fcpu ]; then\
|
||||
echo "Copy k64fcpu app...";\
|
||||
cp k64fcpu $(FUSIONX)/bin/;\
|
||||
fi
|
||||
|
||||
clean:
|
||||
make -C $(KERNEL) M=$(PWD) clean
|
||||
@rm -f sharpbiter k64fcpu z80ctrl
|
||||
|
||||
24
software/FusionX/src/z80drv/README.txt
vendored
Normal file
24
software/FusionX/src/z80drv/README.txt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
Development Cycle
|
||||
-----------------
|
||||
|
||||
z80drv now supports several machines, ie. MZ-80A, MZ-700, MZ-2000, PCW-8256 with more in the pipeline.
|
||||
|
||||
Please edit Makefile and set the model prior to changing the Model source. Alternatively, isse make with the host name, ie. make MZ80A.
|
||||
|
||||
The virtual device concept (ie. an MZ-700 with a tranZPUter SW card) has been incorporated as virtual hardware modules, ie. z80vhw_rfs.c
|
||||
which adds the RFS card to the MZ-700/MZ-80A. These virtual devices are built and added to the target kernel module dependent on supported
|
||||
host.
|
||||
|
||||
Zeta
|
||||
----
|
||||
The Zeta library includes spaces in the naming of certain header files and directories. The linux kernel module build system kbuild
|
||||
cant work with spaces, at least I have found no work around, so after making a submodule pull on Zeta you need to manually rename or edit the files, ie:
|
||||
|
||||
Manually rename the files:
|
||||
mv Zeta/API/Z/inspection/data\ model Zeta/API/Z/inspection/data_model
|
||||
mv Zeta/API/Z/formats/data\ model Zeta/API/Z/formats/data_model
|
||||
mv Zeta/API/Z/keys/data\ model.h Zeta/API/Z/keys/data_model.h
|
||||
|
||||
Edit the files and change 'data model' to data_mode
|
||||
vi Zeta/API/Z/types/integral.h
|
||||
vi Zeta/API/Z/inspection/data_model.h
|
||||
1
software/FusionX/src/z80drv/Z80
vendored
Submodule
1
software/FusionX/src/z80drv/Z80
vendored
Submodule
Submodule software/FusionX/src/z80drv/Z80 added at ada1e2921f
15
software/FusionX/src/z80drv/Zeta/.editorconfig
vendored
Normal file
15
software/FusionX/src/z80drv/Zeta/.editorconfig
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 8
|
||||
indent_style = tab
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.{md,rst}]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[*.yml]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
4
software/FusionX/src/z80drv/Zeta/.github/FUNDING.yml
vendored
Normal file
4
software/FusionX/src/z80drv/Zeta/.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
github: redcode
|
||||
ko_fi: redcode
|
||||
liberapay: redcode
|
||||
patreon: redcode
|
||||
15
software/FusionX/src/z80drv/Zeta/.github/pull_request_template.md
vendored
Normal file
15
software/FusionX/src/z80drv/Zeta/.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
## Description
|
||||
|
||||
_Describe your pull request here._
|
||||
|
||||
## Legal notice (do not delete)
|
||||
|
||||
Thank you for your contribution to the Zeta library.
|
||||
|
||||
It is required that contributors assign copyright to the original author so that he retains full ownership of the project. This makes it easier for other entities to use the software because they only have to deal with one copyright holder. It also gives the original author assurance that he will be able to make decisions in the future without gathering and consulting all contributors.
|
||||
|
||||
While this may seem odd, many open source maintainers practice this.
|
||||
|
||||
By submitting this PR, you agree to the following:
|
||||
|
||||
> You hereby assign copyright in this PR's code to the Zeta library and its copyright holder, Manuel Sainz de Baranda y Goñi, to be licensed under the same terms as the rest of the code. You agree to relinquish any and all copyright interest in the software, to the detriment of your heirs and successors.
|
||||
4
software/FusionX/src/z80drv/Zeta/.gitignore
vendored
Normal file
4
software/FusionX/src/z80drv/Zeta/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
.directory
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
build/
|
||||
4
software/FusionX/src/z80drv/Zeta/.vimrc
vendored
Normal file
4
software/FusionX/src/z80drv/Zeta/.vimrc
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
set noexpandtab
|
||||
set shiftwidth=8
|
||||
set tabstop=8
|
||||
autocmd BufWritePre * %s/\s\+$//e
|
||||
19
software/FusionX/src/z80drv/Zeta/API/Z/classes/Any.hpp
vendored
Normal file
19
software/FusionX/src/z80drv/Zeta/API/Z/classes/Any.hpp
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
/* Zeta API - Z/classes/Any.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Any_HPP
|
||||
#define Z_classes_Any_HPP
|
||||
|
||||
|
||||
namespace Zeta{struct Any {
|
||||
|
||||
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_Any_HPP
|
||||
14
software/FusionX/src/z80drv/Zeta/API/Z/classes/Empty.hpp
vendored
Normal file
14
software/FusionX/src/z80drv/Zeta/API/Z/classes/Empty.hpp
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/* Zeta API - Z/classes/Empty.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Empty_HPP
|
||||
#define Z_classes_Empty_HPP
|
||||
|
||||
namespace Zeta {struct Empty {};}
|
||||
|
||||
#endif // Z_classes_Empty_HPP
|
||||
185
software/FusionX/src/z80drv/Zeta/API/Z/classes/Functor.hpp
vendored
Normal file
185
software/FusionX/src/z80drv/Zeta/API/Z/classes/Functor.hpp
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
/* Zeta API - Z/classes/Functor.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Functor_HPP
|
||||
#define Z_classes_Functor_HPP
|
||||
|
||||
#include <Z/classes/ObjectMemberFunction.hpp>
|
||||
|
||||
#if Z_HAS(ObjectMemberFunction)
|
||||
# ifdef Z_WITH_OBJECTIVE_C_RUNTIME
|
||||
# include <Z/classes/ObjectSelector.hpp>
|
||||
# include <Z/traits/casting.hpp>
|
||||
# endif
|
||||
|
||||
# define Z_HAS_Functor TRUE
|
||||
|
||||
|
||||
namespace Zeta {
|
||||
|
||||
template <class f> class Functor;
|
||||
|
||||
template <class r, class... p> class Functor<r(p...)> {
|
||||
|
||||
private:
|
||||
typedef r (* Call)(const Functor *, typename Type<p>::to_forwardable...);
|
||||
typedef void (* Destroy)(Functor *);
|
||||
|
||||
Call call;
|
||||
Destroy destroy;
|
||||
|
||||
union { r (* function)(p...);
|
||||
|
||||
struct {r (NaT::* function)(p...);
|
||||
NaT *object;
|
||||
} object_member_function;
|
||||
|
||||
# if Z_HAS(ObjectSelector)
|
||||
struct {SEL selector;
|
||||
id object;
|
||||
} object_selector;
|
||||
# endif
|
||||
} target;
|
||||
|
||||
|
||||
struct Callers {
|
||||
|
||||
static Z_INLINE Call function() Z_NOTHROW
|
||||
{
|
||||
return [](const Functor *functor, typename Type<p>::to_forwardable... arguments) -> r
|
||||
{return functor->target.function(arguments...);};
|
||||
}
|
||||
|
||||
|
||||
static Z_INLINE Call object_member_function() Z_NOTHROW
|
||||
{
|
||||
return [](const Functor *functor, typename Type<p>::to_forwardable... arguments) -> r
|
||||
{
|
||||
return (functor->target.object_member_function.object->*
|
||||
functor->target.object_member_function.function)
|
||||
(arguments...);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
# if Z_HAS(ObjectSelector)
|
||||
static Z_INLINE Call object_selector() Z_NOTHROW
|
||||
{
|
||||
return [](const Functor *functor, typename Type<p>::to_forwardable... arguments)
|
||||
{
|
||||
return (cast<r (*)(id, SEL, p...)>(ObjectiveC::send<r>()))(
|
||||
functor->target.object_selector.object,
|
||||
functor->target.object_selector.selector,
|
||||
arguments...);
|
||||
};
|
||||
}
|
||||
# endif
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
|
||||
Z_CT(CPP11) Functor() Z_NOTHROW
|
||||
: call(Z_NULL), destroy(Z_NULL) {}
|
||||
|
||||
|
||||
# ifdef Z_NULLPTR
|
||||
Z_CT(CPP11) Functor(NullPtr) Z_NOTHROW
|
||||
: call(Z_NULL), destroy(Z_NULL) {}
|
||||
# endif
|
||||
|
||||
|
||||
Z_INLINE Functor(r (* function)(p...)) Z_NOTHROW
|
||||
: call(Callers::function()), destroy(Z_NULL)
|
||||
{target.function = function;}
|
||||
|
||||
|
||||
template <class o, class m, class e = typename TypeIf<
|
||||
(Type<o>::is_void || Type<o>::is_class) &&
|
||||
Type<m>::is_member_function_pointer &&
|
||||
TypeIsSame<typename Type<m>::flow::to_function::end::to_unqualified, r(p...)>::value
|
||||
>::type>
|
||||
Z_INLINE Functor(o *object, m function) Z_NOTHROW
|
||||
: call(Callers::object_member_function()), destroy(Z_NULL)
|
||||
{
|
||||
target.object_member_function.function = reinterpret_cast<r (NaT::*)(p...)>(function);
|
||||
target.object_member_function.object = reinterpret_cast<NaT *>(const_cast<typename Type<o>::to_unqualified *>(object));
|
||||
}
|
||||
|
||||
|
||||
template <class o, class m, class e = typename TypeIf<
|
||||
Type<o>::is_class &&
|
||||
Type<m>::is_member_function_pointer &&
|
||||
TypeIsSame<typename Type<m>::flow::to_function::end::to_unqualified, r(p...)>::value
|
||||
>::type>
|
||||
Z_INLINE Functor(const o &object, m function) Z_NOTHROW
|
||||
: call(Callers::object_member_function()), destroy(Z_NULL)
|
||||
{
|
||||
target.object_member_function.function = reinterpret_cast<r (NaT::*)(p...)>(function);
|
||||
target.object_member_function.object = reinterpret_cast<NaT *>(const_cast<typename Type<o>::to_unqualified *>(&object));
|
||||
}
|
||||
|
||||
|
||||
Z_INLINE Functor(const ObjectMemberFunction<r(p...)> &object_member_function) Z_NOTHROW
|
||||
: call(Callers::object_member_function()), destroy(Z_NULL)
|
||||
{
|
||||
target.object_member_function.function = object_member_function.function;
|
||||
target.object_member_function.object = object_member_function.object;
|
||||
}
|
||||
|
||||
|
||||
# if Z_HAS(TypeIsConvertible)
|
||||
|
||||
template <class o, class e = typename TypeIf<
|
||||
Type<o>::is_class &&
|
||||
TypeIsConvertible<o, r(*)(p...)>::value
|
||||
>::type>
|
||||
Z_INLINE Functor(const o &object) Z_NOTHROW
|
||||
: call(Callers::function()), destroy(Z_NULL)
|
||||
{target.function = (r(*)(p...))object;} // TODO: cast
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
# if Z_HAS(ObjectSelector)
|
||||
|
||||
Z_INLINE Functor(id object, SEL selector) Z_NOTHROW
|
||||
: call(Callers::object_selector()), destroy(Z_NULL)
|
||||
{
|
||||
target.object_selector.selector = selector;
|
||||
target.object_selector.object = object;
|
||||
}
|
||||
|
||||
|
||||
Z_INLINE Functor(const ObjectSelector<r(p...)> &object_selector) Z_NOTHROW
|
||||
: call(Callers::object_selector()), destroy(Z_NULL)
|
||||
{
|
||||
target.object_selector.selector = object_selector.selector;
|
||||
target.object_selector.object = object_selector.object;
|
||||
}
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
Z_INLINE ~Functor()
|
||||
{if (destroy) destroy(this);}
|
||||
|
||||
|
||||
Z_CT(CPP11) operator Boolean() const Z_NOTHROW
|
||||
{return call != Z_NULL;}
|
||||
|
||||
|
||||
Z_INLINE r operator ()(typename Type<p>::to_forwardable... arguments) const
|
||||
{return call(this, arguments...);}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif // Z_classes_Functor_HPP
|
||||
45
software/FusionX/src/z80drv/Zeta/API/Z/classes/InitializerList.hpp
vendored
Normal file
45
software/FusionX/src/z80drv/Zeta/API/Z/classes/InitializerList.hpp
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
/* Zeta API - Z/classes/InitializerList.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_InitializerList_HPP
|
||||
#define Z_classes_InitializerList_HPP
|
||||
|
||||
#include <Z/inspection/language.h>
|
||||
|
||||
#if Z_DIALECT_HAS(CPP11, INITIALIZER_LIST)
|
||||
# include <Z/constants/pointer.h>
|
||||
# include <Z/macros/language.hpp>
|
||||
# include <Z/types/integral.hpp>
|
||||
|
||||
# define Z_HAS_InitializerList TRUE
|
||||
|
||||
|
||||
namespace Zeta {template <class t> class InitializerList {
|
||||
public:
|
||||
typedef t value_type;
|
||||
typedef const t& reference;
|
||||
typedef const t& const_reference;
|
||||
typedef USize size_type;
|
||||
typedef const t* iterator;
|
||||
typedef const t* const_iterator;
|
||||
|
||||
private:
|
||||
const t* _data;
|
||||
USize _size;
|
||||
|
||||
public:
|
||||
Z_CT(CPP11) InitializerList() Z_NOTHROW
|
||||
: _data(Z_NULL), _size(0) {}
|
||||
|
||||
Z_CT(CPP11) USize size () const Z_NOTHROW {return _size;}
|
||||
Z_CT(CPP11) const t* begin() const Z_NOTHROW {return _data;}
|
||||
Z_CT(CPP11) const t* end () const Z_NOTHROW {return _data + _size;}
|
||||
};}
|
||||
#endif
|
||||
|
||||
#endif // Z_classes_InitializerList_HPP
|
||||
38
software/FusionX/src/z80drv/Zeta/API/Z/classes/Iterator.hpp
vendored
Normal file
38
software/FusionX/src/z80drv/Zeta/API/Z/classes/Iterator.hpp
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/* Zeta API - Z/classes/Iterator.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Iterator_HPP
|
||||
#define Z_classes_Iterator_HPP
|
||||
|
||||
|
||||
namespace Zeta{template <class t> struct Iterator {
|
||||
t& data_source;
|
||||
typename t::size_type index;
|
||||
|
||||
|
||||
Z_CT(CPP11) Iterator(t &data_source_, typename t::size_type index_)
|
||||
: data_source(data_source_), index(index_) {}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(const Iterator &lhs, const Iterator &rhs) Z_NOTHROW
|
||||
{return lhs.index != rhs.index;}
|
||||
|
||||
|
||||
Z_CT(CPP11) const typename t::element_type &operator *() const Z_NOTHROW
|
||||
{return data_source[index];}
|
||||
|
||||
|
||||
Z_INLINE Iterator const &operator ++() Z_NOTHROW
|
||||
{
|
||||
index++;
|
||||
return *this;
|
||||
}
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_Iterator_HPP
|
||||
85
software/FusionX/src/z80drv/Zeta/API/Z/classes/MemberFunction.hpp
vendored
Normal file
85
software/FusionX/src/z80drv/Zeta/API/Z/classes/MemberFunction.hpp
vendored
Normal file
@@ -0,0 +1,85 @@
|
||||
/* Zeta API - Z/classes/MemberFunction.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_MemberFunction_HPP
|
||||
#define Z_classes_MemberFunction_HPP
|
||||
|
||||
#include <Z/inspection/language.h>
|
||||
|
||||
#if Z_DIALECT_HAS(CPP98, SFINAE) && \
|
||||
Z_DIALECT_HAS(CPP11, VARIADIC_TEMPLATE) && \
|
||||
Z_DIALECT_HAS(CPP11, DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATE)
|
||||
|
||||
# define Z_HAS_MemberFunction TRUE
|
||||
|
||||
# include <Z/constants/pointer.h>
|
||||
# include <Z/traits/type.hpp>
|
||||
|
||||
|
||||
namespace Zeta {
|
||||
template <class f> struct MemberFunction;
|
||||
|
||||
template <class r, class... p> struct MemberFunction<r(p...)> {
|
||||
r (NaT::* function)(p...);
|
||||
|
||||
|
||||
Z_INLINE MemberFunction() Z_NOTHROW
|
||||
Z_DEFAULTED({})
|
||||
|
||||
|
||||
# ifdef Z_NULLPTR
|
||||
Z_CT(CPP11) MemberFunction(NullPtr) Z_NOTHROW
|
||||
: function(nullptr) {};
|
||||
# endif
|
||||
|
||||
|
||||
template <class m, class e = typename TypeIf<
|
||||
Type<m>::is_member_function_pointer &&
|
||||
TypeIsSame<typename Type<m>::flow::to_function::end::to_unqualified, r(p...)>::value
|
||||
>::type>
|
||||
Z_INLINE MemberFunction(m function) Z_NOTHROW
|
||||
: function(reinterpret_cast<r (NaT::*)(p...)>(function)) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) operator Boolean() const Z_NOTHROW
|
||||
{return function != Z_NULL;}
|
||||
|
||||
|
||||
template <class m, class e = typename TypeIf<
|
||||
Type<m>::is_member_function_pointer &&
|
||||
TypeIsSame<typename Type<m>::flow::to_function::end::to_unqualified, r(p...)>::value
|
||||
>::type>
|
||||
Z_INLINE operator m() const Z_NOTHROW
|
||||
{return reinterpret_cast<m>(function);}
|
||||
|
||||
|
||||
template <class m>
|
||||
Z_INLINE typename TypeIf<
|
||||
Type<m>::is_member_function_pointer &&
|
||||
TypeIsSame<typename Type<m>::flow::to_function::end::to_unqualified, r(p...)>::value,
|
||||
MemberFunction &>::type
|
||||
operator =(m rhs) Z_NOTHROW
|
||||
{
|
||||
function = reinterpret_cast<r (NaT::*)(p...)>(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <class o>
|
||||
Z_INLINE r operator ()(o *object, typename Type<p>::to_forwardable... arguments) const
|
||||
{return (reinterpret_cast<NaT *>(object)->*function)(arguments...);}
|
||||
|
||||
|
||||
template <class o>
|
||||
Z_INLINE r operator ()(const o &object, typename Type<p>::to_forwardable... arguments) const
|
||||
{return (const_cast<NaT *>(reinterpret_cast<const NaT *>(&object))->*function)(arguments...);}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // Z_classes_MemberFunction_HPP
|
||||
30
software/FusionX/src/z80drv/Zeta/API/Z/classes/NaT.hpp
vendored
Normal file
30
software/FusionX/src/z80drv/Zeta/API/Z/classes/NaT.hpp
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/* Zeta API - Z/classes/NaT.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_NaT_HPP
|
||||
#define Z_classes_NaT_HPP
|
||||
|
||||
#include <Z/macros/language.hpp>
|
||||
|
||||
|
||||
namespace Zeta {struct NaT Z_FINAL {
|
||||
# if Z_DIALECT_HAS(CPP11, DELETED_FUNCTION)
|
||||
NaT() = delete;
|
||||
NaT(const NaT &) = delete;
|
||||
~NaT() = delete;
|
||||
NaT &operator =(const NaT &) = delete;
|
||||
|
||||
# if Z_DIALECT_HAS(CPP11, RVALUE_REFERENCE)
|
||||
NaT(NaT &&) = delete;
|
||||
NaT &operator =(NaT &&) = delete;
|
||||
# endif
|
||||
# endif
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_NaT_HPP
|
||||
148
software/FusionX/src/z80drv/Zeta/API/Z/classes/ObjectMemberFunction.hpp
vendored
Normal file
148
software/FusionX/src/z80drv/Zeta/API/Z/classes/ObjectMemberFunction.hpp
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
/* Zeta API - Z/classes/ObjectMemberFunction.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_ObjectMemberFunction_HPP
|
||||
#define Z_classes_ObjectMemberFunction_HPP
|
||||
|
||||
#include <Z/inspection/Z.h>
|
||||
#include <Z/classes/MemberFunction.hpp>
|
||||
|
||||
#if Z_HAS(MemberFunction)
|
||||
# define Z_HAS_ObjectMemberFunction TRUE
|
||||
|
||||
|
||||
namespace Zeta {
|
||||
template <class f> struct ObjectMemberFunction;
|
||||
|
||||
template <class r, class... p>
|
||||
struct ObjectMemberFunction<r(p...)> : MemberFunction<r(p...)> {
|
||||
NaT *object;
|
||||
|
||||
|
||||
Z_INLINE ObjectMemberFunction() Z_NOTHROW
|
||||
Z_DEFAULTED({})
|
||||
|
||||
|
||||
# if Z_DIALECT_HAS(CPP11, INHERITING_CONSTRUCTORS)
|
||||
using MemberFunction<r(p...)>::MemberFunction;
|
||||
# else
|
||||
template <class m, class e = typename TypeIf<
|
||||
Type<m>::is_member_function_pointer &&
|
||||
TypeIsSame<typename Type<m>::flow::to_function::end::to_unqualified, r(p...)>::value
|
||||
>::type>
|
||||
Z_INLINE ObjectMemberFunction(m function) Z_NOTHROW
|
||||
: MemberFunction<r(p...)>(function) {}
|
||||
# endif
|
||||
|
||||
|
||||
# ifdef Z_NULLPTR
|
||||
Z_CT(CPP11) ObjectMemberFunction(NullPtr) Z_NOTHROW
|
||||
: MemberFunction<r(p...)>(nullptr), object(nullptr) {};
|
||||
# endif
|
||||
|
||||
|
||||
template <class o, class m, class e = typename TypeIf<
|
||||
(Type<o>::is_void_pointer ||
|
||||
(Type<o>::is_pointer &&
|
||||
Type<o>::flow::pointee_type::is_class)) &&
|
||||
Type<m>::is_member_function_pointer &&
|
||||
TypeIsSame<typename Type<m>::flow::to_function::end::to_unqualified, r(p...)>::value
|
||||
>::type>
|
||||
Z_INLINE ObjectMemberFunction(o object, m function) Z_NOTHROW
|
||||
: MemberFunction<r(p...)>(function), object(reinterpret_cast<NaT *>(object)) {}
|
||||
|
||||
|
||||
template <class o, class m, class e = typename TypeIf<
|
||||
Type<o>::is_class &&
|
||||
Type<m>::is_member_function_pointer &&
|
||||
TypeIsSame<typename Type<m>::flow::to_function::end::to_unqualified, r(p...)>::value
|
||||
>::type>
|
||||
Z_INLINE ObjectMemberFunction(const o &object, m function) Z_NOTHROW
|
||||
: MemberFunction<r(p...)>(function), object(reinterpret_cast<NaT *>(&object)) {}
|
||||
|
||||
|
||||
template <class o, class e = typename TypeIf<Type<o>::is_class>::type>
|
||||
Z_INLINE operator o *() const Z_NOTHROW
|
||||
{return reinterpret_cast<o *>(object);}
|
||||
|
||||
|
||||
template <class o>
|
||||
Z_INLINE typename TypeIf<Type<o>::is_class, ObjectMemberFunction &>::type
|
||||
operator =(o *rhs) Z_NOTHROW
|
||||
{
|
||||
object = reinterpret_cast<NaT *>(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <class o>
|
||||
Z_INLINE typename TypeIf<Type<o>::is_class, ObjectMemberFunction &>::type
|
||||
operator =(const o &rhs) Z_NOTHROW
|
||||
{
|
||||
object = reinterpret_cast<NaT *>(&rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <class m>
|
||||
Z_INLINE typename TypeIf<
|
||||
Type<m>::is_member_function_pointer &&
|
||||
TypeIsSame<typename Type<m>::flow::to_function::end::to_unqualified, r(p...)>::value,
|
||||
ObjectMemberFunction &>::type
|
||||
operator =(m rhs) Z_NOTHROW
|
||||
{
|
||||
this->function = reinterpret_cast<r (NaT::*)(p...)>(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Z_INLINE r operator ()(typename Type<p>::to_forwardable... arguments) const
|
||||
{return (object->*this->function)(arguments...);}
|
||||
|
||||
|
||||
template <class o>
|
||||
Z_INLINE r operator ()(o *object, typename Type<p>::to_forwardable... arguments) const
|
||||
{return (reinterpret_cast<NaT *>(object)->*this->function)(arguments...);}
|
||||
|
||||
|
||||
template <class o>
|
||||
Z_INLINE r operator ()(const o &object, typename Type<p>::to_forwardable... arguments) const
|
||||
{return (reinterpret_cast<NaT *>(&object)->*this->function)(arguments...);}
|
||||
|
||||
|
||||
template <class o, class m>
|
||||
Z_INLINE typename TypeIf<
|
||||
(Type<o>::is_void || Type<o>::is_class) &&
|
||||
Type<m>::is_member_function_pointer &&
|
||||
TypeIsSame<typename Type<m>::flow::to_function::end::to_unqualified, r(p...)>::value,
|
||||
ObjectMemberFunction &>::type
|
||||
set(o *object, m function) Z_NOTHROW
|
||||
{
|
||||
this->function = reinterpret_cast<r (NaT::*)(p...)>(function);
|
||||
this->object = reinterpret_cast<NaT *>(&object);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
template <class o, class m>
|
||||
Z_INLINE typename TypeIf<
|
||||
Type<o>::is_class &&
|
||||
Type<m>::is_member_function_pointer &&
|
||||
TypeIsSame<typename Type<m>::flow::to_function::end::to_unqualified, r(p...)>::value,
|
||||
ObjectMemberFunction &>::type
|
||||
set(const o &object, m function) Z_NOTHROW
|
||||
{
|
||||
this->function = reinterpret_cast<r (NaT::*)(p...)>(function);
|
||||
this->object = const_cast<NaT *>(reinterpret_cast<const NaT *>(&object));
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // Z_classes_ObjectMemberFunction_HPP
|
||||
94
software/FusionX/src/z80drv/Zeta/API/Z/classes/ObjectSelector.hpp
vendored
Normal file
94
software/FusionX/src/z80drv/Zeta/API/Z/classes/ObjectSelector.hpp
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
/* Zeta API - Z/classes/ObjectSelector.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_ObjectSelector_HPP
|
||||
#define Z_classes_ObjectSelector_HPP
|
||||
|
||||
#include <Z/inspection/Z.h>
|
||||
#include <Z/classes/Selector.hpp>
|
||||
|
||||
#if Z_HAS(Selector)
|
||||
# define Z_HAS_ObjectSelector TRUE
|
||||
|
||||
|
||||
namespace Zeta {
|
||||
template <class f> struct ObjectSelector;
|
||||
|
||||
template <class r, class... p>
|
||||
struct ObjectSelector<r(p...)> {
|
||||
typedef r (* Send )(id, SEL, p...);
|
||||
typedef r (* SendSuper)(struct objc_super *, SEL, p...);
|
||||
|
||||
SEL selector;
|
||||
id object;
|
||||
|
||||
|
||||
Z_INLINE ObjectSelector() Z_NOTHROW
|
||||
Z_DEFAULTED({})
|
||||
|
||||
|
||||
Z_INLINE ObjectSelector(id object_, SEL selector_) Z_NOTHROW
|
||||
: object(object_), selector(selector_) {}
|
||||
|
||||
|
||||
Z_INLINE operator id() const Z_NOTHROW
|
||||
{return object;}
|
||||
|
||||
|
||||
Z_INLINE operator SEL() const Z_NOTHROW
|
||||
{return selector;}
|
||||
|
||||
|
||||
Z_INLINE ObjectSelector &operator =(SEL rhs) Z_NOTHROW
|
||||
{selector = rhs; return *this;}
|
||||
|
||||
|
||||
Z_INLINE ObjectSelector &operator =(id rhs) Z_NOTHROW
|
||||
{object = rhs; return *this;}
|
||||
|
||||
|
||||
Z_INLINE r operator ()(typename Type<p>::to_forwardable... arguments) const Z_NOTHROW
|
||||
{return (Send(ObjectiveC::send<r>()))(object, selector, arguments...);}
|
||||
|
||||
|
||||
Z_INLINE r operator ()(id object_, typename Type<p>::to_forwardable... arguments) const Z_NOTHROW
|
||||
{return (Send(ObjectiveC::send<r>()))(object_, selector, arguments...);}
|
||||
|
||||
|
||||
Z_INLINE r super(typename Type<p>::to_forwardable... arguments) const Z_NOTHROW
|
||||
{
|
||||
struct objc_super object_super {object, class_getSuperclass(object_getClass(object))};
|
||||
return (SendSuper(objc_msgSendSuper))(&object_super, this->selector, arguments...);
|
||||
}
|
||||
|
||||
|
||||
Z_INLINE r super(id object, typename Type<p>::to_forwardable... arguments) const Z_NOTHROW
|
||||
{
|
||||
struct objc_super object_super {object, class_getSuperclass(object_getClass(object))};
|
||||
return (SendSuper(objc_msgSendSuper))(&object_super, this->selector, arguments...);
|
||||
}
|
||||
|
||||
|
||||
Z_INLINE r super(const struct objc_super &object_super, typename Type<p>::to_forwardable... arguments) const Z_NOTHROW
|
||||
{
|
||||
return (SendSuper(ObjectiveC::send_super<r>()))
|
||||
(const_cast<struct objc_super *>(&object_super), selector, arguments...);
|
||||
}
|
||||
|
||||
|
||||
Z_INLINE ObjectSelector &set(id object, SEL selector) Z_NOTHROW
|
||||
{
|
||||
this->selector = selector;
|
||||
this->object = object;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // Z_classes_ObjectSelector_HPP
|
||||
30
software/FusionX/src/z80drv/Zeta/API/Z/classes/OpaqueMemberFunctionPointer.hpp
vendored
Normal file
30
software/FusionX/src/z80drv/Zeta/API/Z/classes/OpaqueMemberFunctionPointer.hpp
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/* Zeta API - Z/classes/OpaqueMemberFunctionPointer.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_OpaqueMemberFunctionPointer_HPP
|
||||
#define Z_classes_OpaqueMemberFunctionPointer_HPP
|
||||
|
||||
#include <Z/classes/NaT.hpp>
|
||||
|
||||
|
||||
namespace Zeta {struct OpaqueMemberFunctionPointer {
|
||||
void (NaT::* value)();
|
||||
|
||||
|
||||
template <class m>
|
||||
Z_INLINE OpaqueMemberFunctionPointer(m pointer) Z_NOTHROW
|
||||
: value(reinterpret_cast<void (NaT::*)()>(pointer)) {}
|
||||
|
||||
|
||||
template <class m>
|
||||
Z_INLINE operator m() const Z_NOTHROW
|
||||
{return reinterpret_cast<m>(value);}
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_OpaqueMemberFunctionPointer_HPP
|
||||
13
software/FusionX/src/z80drv/Zeta/API/Z/classes/Optional.hpp
vendored
Normal file
13
software/FusionX/src/z80drv/Zeta/API/Z/classes/Optional.hpp
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/* Zeta API - Z/classes/Optional.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Optional_HPP
|
||||
#define Z_classes_Optional_HPP
|
||||
|
||||
|
||||
#endif // Z_classes_Optional_HPP
|
||||
48
software/FusionX/src/z80drv/Zeta/API/Z/classes/Pair.hpp
vendored
Normal file
48
software/FusionX/src/z80drv/Zeta/API/Z/classes/Pair.hpp
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/* Zeta API - Z/classes/Pair.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Pair_HPP
|
||||
#define Z_classes_Pair_HPP
|
||||
|
||||
#include <Z/macros/language.hpp>
|
||||
#include <Z/types/integral.hpp>
|
||||
|
||||
|
||||
namespace Zeta {template <class t1, class t2 = t1> struct Pair {
|
||||
typedef t1 First;
|
||||
typedef t2 Second;
|
||||
|
||||
t1 first;
|
||||
t2 second;
|
||||
|
||||
Z_INLINE Pair() Z_DEFAULTED({})
|
||||
|
||||
Z_CT(CPP11) Pair(
|
||||
typename Type<t1>::to_forwardable first,
|
||||
typename Type<t2>::to_forwardable second
|
||||
) : first(first), second(second) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean operator ==(const Pair &pair) const
|
||||
{return first == pair.first && second == pair.second;}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean operator !=(const Pair &pair) const
|
||||
{return first != pair.first || second != pair.second;}
|
||||
|
||||
|
||||
/*Z_INLINE void swap(Pair &pair)
|
||||
{
|
||||
Zeta::swap<typename Type<Pair>::to_opaque>(
|
||||
reinterpret_cast<typename Type<Pair>::to_opaque *>(this),
|
||||
reinterpret_cast<typename Type<Pair>::to_opaque *>(&pair));
|
||||
}*/
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_Pair_HPP
|
||||
135
software/FusionX/src/z80drv/Zeta/API/Z/classes/Range.hpp
vendored
Normal file
135
software/FusionX/src/z80drv/Zeta/API/Z/classes/Range.hpp
vendored
Normal file
@@ -0,0 +1,135 @@
|
||||
/* Zeta API - Z/classes/Range.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Range_HPP
|
||||
#define Z_classes_Range_HPP
|
||||
|
||||
#include <Z/functions/math.hpp>
|
||||
|
||||
#if defined(Z_WITH_NS_RANGE) && Z_LANGUAGE_INCLUDES(OBJECTIVE_CPP)
|
||||
# import <Foundation/NSRange.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace Zeta {template <class t> struct Range {
|
||||
t index, size;
|
||||
|
||||
|
||||
Z_INLINE Range() Z_NOTHROW
|
||||
Z_DEFAULTED({})
|
||||
|
||||
|
||||
Z_CT(CPP11) Range(t size_) Z_NOTHROW
|
||||
: index(0), size(size_) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) Range(t index_, t size_) Z_NOTHROW
|
||||
: index(index_), size(size_) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) operator Boolean() const Z_NOTHROW
|
||||
{return !!size;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(const Range &lhs, const Range &rhs) Z_NOTHROW
|
||||
{return lhs.index == rhs.index && lhs.size == rhs.size;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(const Range &lhs, const Range &rhs) Z_NOTHROW
|
||||
{return lhs.index != rhs.index || lhs.size != rhs.size;}
|
||||
|
||||
|
||||
friend Z_CT(CPP14) Range operator &(const Range &lhs, const Range &rhs) Z_NOTHROW
|
||||
{
|
||||
t index = (lhs.index > rhs.index) ? lhs.index : rhs.index;
|
||||
t end = minimum<t>(lhs.end(), rhs.end());
|
||||
|
||||
return end > index ? Range(index, end - index) : Range(0);
|
||||
}
|
||||
|
||||
|
||||
friend Z_CT(CPP14) Range operator |(const Range &lhs, const Range &rhs) Z_NOTHROW
|
||||
{
|
||||
t index = (lhs.index < rhs.index) ? lhs.index : rhs.index;
|
||||
t lhs_end = lhs.end();
|
||||
t rhs_end = rhs.end();
|
||||
|
||||
return Range(index, ((lhs_end > rhs_end) ? lhs_end : rhs_end) - index);
|
||||
}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Range operator +(const Range &lhs, t rhs) Z_NOTHROW
|
||||
{return Range(lhs.index, lhs.size + rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Range operator +(t lhs, const Range &rhs) Z_NOTHROW
|
||||
{return Range(rhs.index, rhs.size + lhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Range operator -(const Range &lhs, t rhs) Z_NOTHROW
|
||||
{return Range(lhs.index, lhs.size - rhs);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Range operator >>(t rhs) const Z_NOTHROW {return Range(index + rhs, size);}
|
||||
Z_CT(CPP11) Range operator <<(t rhs) const Z_NOTHROW {return Range(index - rhs, size);}
|
||||
|
||||
Z_INLINE Range &operator &=(const Range &rhs) Z_NOTHROW {return *this = *this & rhs;}
|
||||
Z_INLINE Range &operator |=(const Range &rhs) Z_NOTHROW {return *this = *this | rhs;}
|
||||
|
||||
Z_INLINE Range &operator +=(t rhs) Z_NOTHROW {return *this = *this + rhs;}
|
||||
Z_INLINE Range &operator -=(t rhs) Z_NOTHROW {return *this = *this - rhs;}
|
||||
Z_INLINE Range &operator >>=(t rhs) Z_NOTHROW {return *this = *this >> rhs;}
|
||||
Z_INLINE Range &operator <<=(t rhs) Z_NOTHROW {return *this = *this << rhs;}
|
||||
|
||||
Z_CT(CPP11) t operator [](t index_) const Z_NOTHROW {return index + index_;}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean contains(const Range &other) const Z_NOTHROW
|
||||
{return other.index >= index && other.end() <= end();}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean contains(t index_) const Z_NOTHROW
|
||||
{return index_ >= index && index_ < end();}
|
||||
|
||||
|
||||
Z_CT(CPP11) t end() const Z_NOTHROW
|
||||
{return index + size;}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean intersects(const Range &other) const Z_NOTHROW
|
||||
{return index < other.end() && other.index < end();}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_zero() const Z_NOTHROW
|
||||
{return !index && !size;}
|
||||
|
||||
|
||||
# if defined(Z_WITH_NS_RANGE) && Z_LANGUAGE_INCLUDES(OBJECTIVE_CPP)
|
||||
|
||||
Z_CT(CPP11) Range(const NSRange &range) Z_NOTHROW
|
||||
: index(t(range.location)), size(t(range.length)) {}
|
||||
|
||||
|
||||
# if Z_DIALECT_HAS(CPP11, COPY_LIST_INITIALIZATION)
|
||||
|
||||
Z_CT(CPP11) operator NSRange() const Z_NOTHROW
|
||||
{return {NSUInteger(index), NSUInteger(size)};}
|
||||
|
||||
# else
|
||||
Z_CT(CPP14) operator NSRange() const Z_NOTHROW
|
||||
{
|
||||
NSRange result = {NSUInteger(index), NSUInteger(size)};
|
||||
return result;
|
||||
}
|
||||
# endif
|
||||
|
||||
# endif
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_Range_HPP
|
||||
737
software/FusionX/src/z80drv/Zeta/API/Z/classes/Rectangle.hpp
vendored
Normal file
737
software/FusionX/src/z80drv/Zeta/API/Z/classes/Rectangle.hpp
vendored
Normal file
@@ -0,0 +1,737 @@
|
||||
/* Zeta API - Z/classes/Rectangle.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Rectangle_HPP
|
||||
#define Z_classes_Rectangle_HPP
|
||||
|
||||
#include <Z/classes/XY.hpp>
|
||||
|
||||
#ifdef Z_WITH_COCOS2D_X
|
||||
# include "cocos2d.h"
|
||||
#endif
|
||||
|
||||
#ifdef Z_WITH_CG_GEOMETRY
|
||||
# include <CoreGraphics/CGGeometry.h>
|
||||
#endif
|
||||
|
||||
#if defined(Z_WITH_NS_GEOMETRY) && Z_LANGUAGE_INCLUDES(OBJECTIVE_CPP)
|
||||
# import <Foundation/NSGeometry.h>
|
||||
#endif
|
||||
|
||||
#ifdef Z_WITH_QT
|
||||
# include <QRect>
|
||||
#endif
|
||||
|
||||
|
||||
namespace Zeta {template <class t> struct Rectangle {
|
||||
XY<t> point, size;
|
||||
|
||||
|
||||
Z_INLINE Rectangle() Z_NOTHROW
|
||||
Z_DEFAULTED({})
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle(const XY<t> &point_, const XY<t> &size_) Z_NOTHROW
|
||||
: point(point_), size(size_) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle(const XY<t> &point_, t size_x, t size_y) Z_NOTHROW
|
||||
: point(point_), size(size_x, size_y) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle(const XY<t> &point_, t size_xy) Z_NOTHROW
|
||||
: point(point_), size(size_xy) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle(t point_x, t point_y, const XY<t> &size_) Z_NOTHROW
|
||||
: point(point_x, point_y), size(size_) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle(t point_x, t point_y, t size_x, t size_y) Z_NOTHROW
|
||||
: point(point_x, point_y), size(size_x, size_y) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle(t point_x, t point_y, t size_xy) Z_NOTHROW
|
||||
: point(point_x, point_y), size(size_xy) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle(t point_xy, const XY<t> &size_) Z_NOTHROW
|
||||
: point(point_xy), size(size_) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle(const XY<t> &size_) Z_NOTHROW
|
||||
: point(t(0)), size(size_) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle(t size_x, t size_y) Z_NOTHROW
|
||||
: point(t(0)), size(size_x, size_y) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle(t size_xy) Z_NOTHROW
|
||||
: point(t(0)), size(size_xy) {}
|
||||
|
||||
|
||||
# if Z_DIALECT_HAS(CPP98, SFINAE) && \
|
||||
Z_DIALECT_HAS(CPP11, DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATE)
|
||||
|
||||
template <class other_t, class e = typename TypeIf<!TypeIsSame<t, other_t>::value>::type>
|
||||
Z_CT(CPP11) Rectangle(const Rectangle<other_t> &other) Z_NOTHROW
|
||||
: point(other.point), size(other.size) {}
|
||||
# endif
|
||||
|
||||
|
||||
static Z_CT(CPP14) Rectangle from_vertices(const XY<t> &a, const XY<t> &b) Z_NOTHROW
|
||||
{
|
||||
XY<t> minimum = a.minimum(b);
|
||||
|
||||
return Rectangle(minimum, a.maximum(b) - minimum);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) operator Boolean() const Z_NOTHROW
|
||||
{return point || size;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(const Rectangle &lhs, const Rectangle &rhs) Z_NOTHROW
|
||||
{return lhs.point == rhs.point && lhs.size == rhs.size;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(const Rectangle &lhs, const Rectangle &rhs) Z_NOTHROW
|
||||
{return lhs.point != rhs.point || lhs.size != rhs.size;}
|
||||
|
||||
|
||||
friend Z_CT(CPP14) Rectangle operator &(const Rectangle &lhs, const Rectangle &rhs) Z_NOTHROW
|
||||
{
|
||||
t x1, x2, y1, y2;
|
||||
|
||||
return (x1 = maximum<t>(lhs.point.x, rhs.point.x)) <
|
||||
(x2 = minimum<t>(lhs.point.x + lhs.size.x, rhs.point.x + rhs.size.x)) &&
|
||||
(y1 = maximum<t>(lhs.point.y, rhs.point.y)) <
|
||||
(y2 = minimum<t>(lhs.point.y + lhs.size.y, rhs.point.y + rhs.size.y))
|
||||
|
||||
? Rectangle(x1, y1, x2 - x1, y2 - y1)
|
||||
: Rectangle(t(0));
|
||||
}
|
||||
|
||||
|
||||
friend Z_CT(CPP14) Rectangle operator |(const Rectangle &lhs, const Rectangle &rhs) Z_NOTHROW
|
||||
{
|
||||
Rectangle result;
|
||||
|
||||
result.point = lhs.point.minimum(rhs.point);
|
||||
result.size = (lhs.point + lhs.size).maximum(rhs.point + rhs.size) - result.point;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Rectangle operator +(const Rectangle &lhs, const XY<t> &rhs) Z_NOTHROW
|
||||
{return Rectangle(lhs.point, lhs.size + rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Rectangle operator +(const XY<t> &lhs, const Rectangle &rhs) Z_NOTHROW
|
||||
{return Rectangle(rhs.point, rhs.size + lhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Rectangle operator +(const Rectangle &lhs, t rhs) Z_NOTHROW
|
||||
{return Rectangle(lhs.point, lhs.size + rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Rectangle operator +(t lhs, const Rectangle &rhs) Z_NOTHROW
|
||||
{return Rectangle(rhs.point, rhs.size + lhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Rectangle operator -(const Rectangle &lhs, const XY<t> &rhs) Z_NOTHROW
|
||||
{return Rectangle(lhs.point, lhs.size - rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Rectangle operator -(const Rectangle &lhs, t rhs) Z_NOTHROW
|
||||
{return Rectangle(lhs.point, lhs.size - rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Rectangle operator *(const Rectangle &lhs, const XY<t> &rhs) Z_NOTHROW
|
||||
{return Rectangle(lhs.point, lhs.size * rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Rectangle operator *(const XY<t> &lhs, const Rectangle &rhs) Z_NOTHROW
|
||||
{return Rectangle(rhs.point, rhs.size * lhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Rectangle operator *(const Rectangle &lhs, t rhs) Z_NOTHROW
|
||||
{return Rectangle(lhs.point, lhs.size * rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Rectangle operator *(t lhs, const Rectangle &rhs) Z_NOTHROW
|
||||
{return Rectangle(rhs.point, rhs.size * lhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Rectangle operator /(const Rectangle &lhs, const XY<t> &rhs) Z_NOTHROW
|
||||
{return Rectangle(lhs.point, lhs.size / rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Rectangle operator /(const Rectangle &lhs, t rhs) Z_NOTHROW
|
||||
{return Rectangle(lhs.point, lhs.size / rhs);}
|
||||
|
||||
|
||||
Z_INLINE Rectangle &operator &=(const Rectangle &rhs) Z_NOTHROW {return *this = *this & rhs;}
|
||||
Z_INLINE Rectangle &operator |=(const Rectangle &rhs) Z_NOTHROW {return *this = *this | rhs;}
|
||||
|
||||
Z_INLINE Rectangle &operator +=(const XY<t> &rhs) Z_NOTHROW {return *this = *this + rhs;}
|
||||
Z_INLINE Rectangle &operator -=(const XY<t> &rhs) Z_NOTHROW {return *this = *this - rhs;}
|
||||
Z_INLINE Rectangle &operator *=(const XY<t> &rhs) Z_NOTHROW {return *this = *this * rhs;}
|
||||
Z_INLINE Rectangle &operator /=(const XY<t> &rhs) Z_NOTHROW {return *this = *this / rhs;}
|
||||
|
||||
Z_INLINE Rectangle &operator +=(t rhs) Z_NOTHROW {return *this = *this + rhs;}
|
||||
Z_INLINE Rectangle &operator -=(t rhs) Z_NOTHROW {return *this = *this - rhs;}
|
||||
Z_INLINE Rectangle &operator *=(t rhs) Z_NOTHROW {return *this = *this * rhs;}
|
||||
Z_INLINE Rectangle &operator /=(t rhs) Z_NOTHROW {return *this = *this / rhs;}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> bottom() const Z_NOTHROW
|
||||
{return XY<t>(point.x + size.x / t(2), point.y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> bottom(t (* round)(t)) const Z_NOTHROW
|
||||
{return XY<t>(round(point.x + size.x / t(2)), point.y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle bottom(const XY<t> &size_) const Z_NOTHROW
|
||||
{return Rectangle(point.x + (size.x - size_.x) / t(2), point.y, size_);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle bottom(const XY<t> &size_, t (* round)(t)) const Z_NOTHROW
|
||||
{return Rectangle(round(point.x + (size.x - size_.x) / t(2)), point.y, size_);}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> bottom_left() const Z_NOTHROW
|
||||
{return point;}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle bottom_left(const XY<t> &size_) const Z_NOTHROW
|
||||
{return Rectangle(point, size_);}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> bottom_right() const Z_NOTHROW
|
||||
{return XY<t>(point.x + size.x, point.y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle bottom_right(const XY<t> &size_) const Z_NOTHROW
|
||||
{return Rectangle(point.x + size.x - size_.x, point.y, size_);}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> center() const Z_NOTHROW
|
||||
{return point + size / t(2);}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> center(t (* round)(t)) const Z_NOTHROW
|
||||
{return XY<t>(round(point.x + size.x / t(2)), round(point.y + size.y / t(2)));}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle center(const XY<t> &size_) const Z_NOTHROW
|
||||
{return Rectangle(point + (size - size_) / t(2), size_);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle center(const XY<t> &size_, t (* round)(t)) const Z_NOTHROW
|
||||
{
|
||||
return Rectangle(
|
||||
round(point.x + (size.x - size_.x) / t(2)),
|
||||
round(point.y + (size.y - size_.y) / t(2)),
|
||||
size);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> left() const Z_NOTHROW
|
||||
{return XY<t>(point.x, point.y + size.y / t(2));}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> left(t (* round)(t)) const Z_NOTHROW
|
||||
{return XY<t>(point.x, round(point.y + size.y / t(2)));}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle left(const XY<t> &size_) const Z_NOTHROW
|
||||
{return Rectangle(point.x, point.y + (size.y - size_.y) / t(2), size_);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle left(const XY<t> &size_, t (* round)(t)) const Z_NOTHROW
|
||||
{return Rectangle(point.x, round(point.y + (size.y - size_.y) / t(2)), size_);}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> right() const Z_NOTHROW
|
||||
{return XY<t>(point.x + size.x, point.y + size.y / t(2));}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> right(t (* round)(t)) const Z_NOTHROW
|
||||
{return XY<t>(point.x + size.x, round(point.y + size.y / t(2)));}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle right(const XY<t> &size_) const Z_NOTHROW
|
||||
{
|
||||
return Rectangle(
|
||||
point.x + size.x - size_.x,
|
||||
point.y + (size.y - size_.y) / t(2),
|
||||
size_);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle right(const XY<t> &size_, t (* round)(t)) const Z_NOTHROW
|
||||
{
|
||||
return Rectangle(
|
||||
point.x + size.x - size_.x,
|
||||
round(point.y + (size.y - size_.y) / t(2)),
|
||||
size_);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> top() const Z_NOTHROW
|
||||
{return XY<t>(point.x + size.x / t(2), point.y + size.y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> top(t (* round)(t)) const Z_NOTHROW
|
||||
{return XY<t>(round(point.x + size.x / t(2)), point.y + size.y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle top(const XY<t> &size_) const Z_NOTHROW
|
||||
{
|
||||
return Rectangle(
|
||||
point.x + (size.x - size_.x) / t(2),
|
||||
point.y + size.y - size_.y,
|
||||
size_);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle top(const XY<t> &size_, t (* round)(t)) const Z_NOTHROW
|
||||
{
|
||||
return Rectangle(
|
||||
round(point.x + (size.x - size_.x) / t(2)),
|
||||
point.y + size.y - size_.y,
|
||||
size_);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> top_left() const Z_NOTHROW
|
||||
{return XY<t>(point.x, point.y + size.y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle top_left(const XY<t> &size_) const Z_NOTHROW
|
||||
{return Rectangle(point.x, point.y + size.y - size_.y, size_);}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> top_right() const Z_NOTHROW
|
||||
{return point + size;}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle top_right(const XY<t> &size_) const Z_NOTHROW
|
||||
{return Rectangle(point + size - size_, size_);}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle bottom_half() const Z_NOTHROW
|
||||
{return Rectangle(point, size.x, size.y / t(2));}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle bottom_left_quarter() const Z_NOTHROW
|
||||
{return Rectangle(point, size / t(2));}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean contains(const Rectangle &other) const Z_NOTHROW
|
||||
{
|
||||
return !other.size.has_zero() &&
|
||||
other.point >= point &&
|
||||
other.point + other.size <= point + size;
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean contains(const XY<t> &point_) const Z_NOTHROW
|
||||
{return point_ >= point && point_ < point + size;}
|
||||
|
||||
|
||||
Z_INLINE Rectangle &correct() Z_NOTHROW
|
||||
{
|
||||
if (size.x < t(0)) point.x -= (size.x = -size.x);
|
||||
if (size.y < t(0)) point.y -= (size.y = -size.y);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP14) Rectangle fit_in_bottom_center(const XY<t> &size_) const Z_NOTHROW
|
||||
{
|
||||
XY<t> fitting_size = size_.fit(size);
|
||||
|
||||
return Rectangle(point.x + (size.x - fitting_size.x) / t(2), point.y, fitting_size);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle fit_in_bottom_left(const XY<t> &size_) const Z_NOTHROW
|
||||
{return Rectangle(point, size_.fit(size));}
|
||||
|
||||
|
||||
Z_CT(CPP14) Rectangle fit_in_bottom_right(const XY<t> &size_) const Z_NOTHROW
|
||||
{
|
||||
XY<t> fitting_size = size_.fit(size);
|
||||
|
||||
return Rectangle(point.x + size.x - fitting_size.x, point.y, fitting_size);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP14) Rectangle fit_in_center(const XY<t> &size_) const Z_NOTHROW
|
||||
{
|
||||
XY<t> fitting_size = size_.fit(size);
|
||||
|
||||
return Rectangle(point + (size - fitting_size) / t(2), fitting_size);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP14) Rectangle fit_in_center_left(const XY<t> &size_) const Z_NOTHROW
|
||||
{
|
||||
XY<t> fitting_size = size_.fit(size);
|
||||
|
||||
return Rectangle(point.x, point.y + (size.y - fitting_size.y) / t(2), fitting_size);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP14) Rectangle fit_in_center_right(const XY<t> &size_) const Z_NOTHROW
|
||||
{
|
||||
XY<t> fitting_size = size_.fit(size);
|
||||
|
||||
return Rectangle(
|
||||
point.x + size.x - fitting_size.x,
|
||||
point.y + (size.y - fitting_size.y) / t(2),
|
||||
fitting_size);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP14) Rectangle fit_in_top_center(const XY<t> &size_) const Z_NOTHROW
|
||||
{
|
||||
XY<t> fitting_size = size_.fit(size);
|
||||
|
||||
return Rectangle(
|
||||
point.x + (size.x - fitting_size.x) / t(2),
|
||||
point.y + size.y - fitting_size.y,
|
||||
fitting_size);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP14) Rectangle fit_in_top_left(const XY<t> &size_) const Z_NOTHROW
|
||||
{
|
||||
XY<t> fitting_size = size_.fit(size);
|
||||
|
||||
return Rectangle(point.x, point.y + size.y - fitting_size.y, fitting_size);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP14) Rectangle fit_in_top_right(const XY<t> &size_) const Z_NOTHROW
|
||||
{
|
||||
XY<t> fitting_size = size_.fit(size);
|
||||
|
||||
return Rectangle(point + size - fitting_size, fitting_size);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_from_bottom_center(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x - delta.x / t(2), point.y, size + delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_from_bottom_left(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point, size + delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_from_bottom_right(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x - delta.x, point.y, size + delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_from_center(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point - delta / t(2), size + delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_from_center_left(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x, point.y - delta.y / t(2), size + delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_from_center_right(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x - delta.x, point.y - delta.y / t(2), size + delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_from_top_center(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x - delta.x / t(2), point.y - delta.y, size + delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_from_top_left(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x, point.y - delta.y, size + delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_from_top_right(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point - delta, size + delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_in_x_from_center(t delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x - delta / t(2), point.y, size.x + delta, size.y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_in_x_from_left(t delta) const Z_NOTHROW
|
||||
{return Rectangle(point, size.x + delta, size.y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_in_x_from_right(t delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x - delta, point.y, size.x + delta, size.y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_in_y_from_bottom(t delta) const Z_NOTHROW
|
||||
{return Rectangle(point, size.x, size.y + delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_in_y_from_center(t delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x, point.y - delta / t(2), size.x, size.y + delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle grow_in_y_from_top(t delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x, point.y - delta, size.x, size.y + delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean intersects(const Rectangle &other) const Z_NOTHROW
|
||||
{
|
||||
return !size.has_zero() &&
|
||||
!other.size.has_zero() &&
|
||||
other.point + other.size > point &&
|
||||
other.point < point + size;
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_zero() const Z_NOTHROW
|
||||
{return point.is_zero() && size.is_zero();}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle left_half () const Z_NOTHROW
|
||||
{return Rectangle(point, size.x / t(2), size.y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) t maximum_x() const Z_NOTHROW {return point.x + size.x;}
|
||||
Z_CT(CPP11) t maximum_y() const Z_NOTHROW {return point.y + size.y;}
|
||||
Z_CT(CPP11) t middle_x () const Z_NOTHROW {return point.x + size.x / t(2);}
|
||||
Z_CT(CPP11) t middle_y () const Z_NOTHROW {return point.y + size.y / t(2);}
|
||||
Z_CT(CPP11) t minimum_x() const Z_NOTHROW {return point.x;}
|
||||
Z_CT(CPP11) t minimum_y() const Z_NOTHROW {return point.y;}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_from_bottom_center(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x + delta.x / t(2), point.y, size - delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_from_bottom_left(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point, size - delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_from_bottom_right(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x + delta.x, point.y, size - delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_from_center(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point + delta / t(2), size - delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_from_center_left(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x, point.y + delta.y / t(2), size - delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_from_center_right(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x + delta.x, point.y + delta.y / t(2), size - delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_from_top_center(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x + delta.x / t(2), point.y + delta.y, size - delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_from_top_left(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x, point.y + delta.y, size - delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_from_top_right(const XY<t> &delta) const Z_NOTHROW
|
||||
{return Rectangle(point + delta, size - delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_in_x_from_center(t delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x + delta / t(2), point.y, size.x - delta, size.y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_in_x_from_left(t delta) const Z_NOTHROW
|
||||
{return Rectangle(point, size.x - delta, size.y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_in_x_from_right(t delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x + delta, point.y, size.x - delta, size.y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_in_y_from_bottom(t delta) const Z_NOTHROW
|
||||
{return Rectangle(point, size.x, size.y - delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_in_y_from_center(t delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x, point.y + delta / t(2), size.x, size.y - delta);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle shrink_in_y_from_top(t delta) const Z_NOTHROW
|
||||
{return Rectangle(point.x, point.y + delta, size.x, size.y - delta);}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> absolute_point_to_unit(const XY<t> &point_) const Z_NOTHROW
|
||||
{return (point_ - point) / size;}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle bottom_right_quarter() const Z_NOTHROW
|
||||
{return Rectangle(point.x + size.x / t(2), point.y, size / t(2));}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle right_half() const Z_NOTHROW
|
||||
{return Rectangle(point.x + size.x / t(2), point.y, size.x / t(2), size.y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle top_half() const Z_NOTHROW
|
||||
{return Rectangle(point.x, point.y + size.y / t(2), size.x, size.y / t(2));}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle top_left_quarter() const Z_NOTHROW
|
||||
{return Rectangle(point.x, point.y + size.y / t(2), size / t(2));}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle top_right_quarter() const Z_NOTHROW
|
||||
{return Rectangle(point + size / t(2), size / t(2));}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY<t> unit_point_to_absolute(const XY<t> &point_) const Z_NOTHROW
|
||||
{return point + point_ * size;}
|
||||
|
||||
|
||||
|
||||
# ifdef Z_WITH_COCOS2D_X
|
||||
|
||||
Z_INLINE Rectangle(const cocos2d::Rect &rectangle)
|
||||
: point(rectangle.origin), size(rectangle.size) {}
|
||||
|
||||
|
||||
Z_INLINE operator cocos2d::Rect() const
|
||||
{return cocos2d::Rect(float(point.x), float(point.y), float(size.x), float(size.y));}
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
# if defined(Z_WITH_CG_GEOMETRY) || defined(Z_WITH_NS_GEOMETRY)
|
||||
|
||||
# define Z__APPLE_CONSTRUCTORS(Prefix) \
|
||||
\
|
||||
Z_CT(CPP11) Rectangle(const Prefix##Rect &rectangle) \
|
||||
: point(rectangle.origin), size(rectangle.size) {} \
|
||||
\
|
||||
\
|
||||
Z_CT(CPP11) Rectangle(const Prefix##Point &point_) \
|
||||
: point(t(0)), size(point_) {} \
|
||||
\
|
||||
\
|
||||
Z_CT(CPP11) Rectangle(const Prefix##Size &size_) \
|
||||
: point(t(0)), size(size_) {}
|
||||
|
||||
|
||||
# if Z_DIALECT_HAS(CPP11, COPY_LIST_INITIALIZATION)
|
||||
|
||||
# define Z__APPLE_OPERATORS(Prefix) \
|
||||
\
|
||||
Z_CT(CPP11) operator Prefix##Rect() const \
|
||||
{ \
|
||||
return {{CGFloat(point.x), CGFloat(point.y)}, \
|
||||
{CGFloat(size.x), CGFloat(size.y)}}; \
|
||||
}
|
||||
|
||||
# else
|
||||
# define Z__APPLE_OPERATORS(Prefix) \
|
||||
\
|
||||
Z_CT(CPP14) operator Prefix##Rect() const \
|
||||
{ \
|
||||
CGRect result = { \
|
||||
{CGFloat(point.x), CGFloat(point.y)}, \
|
||||
{CGFloat(size.x), CGFloat(size.y)} \
|
||||
}; \
|
||||
\
|
||||
return result; \
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
# ifdef Z_WITH_CG_GEOMETRY
|
||||
Z__APPLE_CONSTRUCTORS(CG)
|
||||
Z__APPLE_OPERATORS (CG)
|
||||
# endif
|
||||
|
||||
# if defined(Z_WITH_NS_GEOMETRY) && \
|
||||
Z_LANGUAGE_INCLUDES(OBJECTIVE_CPP) && \
|
||||
(!defined(Z_WITH_CG_GEOMETRY) || \
|
||||
!defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES) || \
|
||||
!NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)
|
||||
|
||||
Z__APPLE_CONSTRUCTORS(NS)
|
||||
Z__APPLE_OPERATORS (NS)
|
||||
# endif
|
||||
|
||||
# undef Z__APPLE_CONSTRUCTORS
|
||||
# undef Z__APPLE_OPERATORS
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
# ifdef Z_WITH_QT
|
||||
|
||||
Z_CT(CPP11) Rectangle(const QRect &rectangle) Z_NOTHROW
|
||||
: point(rectangle.topLeft()), size(rectangle.size()) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle(const QPoint &point_) Z_NOTHROW
|
||||
: point(t(0)), size(point) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) Rectangle(const QSize &size_) Z_NOTHROW
|
||||
: point(t(0)), size(size_) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) operator QRect() const Z_NOTHROW
|
||||
{return QRect(int(point.x), int(point.y), int(size.x), int(size.y));}
|
||||
|
||||
# endif
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_Rectangle_HPP
|
||||
39
software/FusionX/src/z80drv/Zeta/API/Z/classes/Reference.hpp
vendored
Normal file
39
software/FusionX/src/z80drv/Zeta/API/Z/classes/Reference.hpp
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
/* Zeta API - Z/classes/Reference.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Reference_HPP
|
||||
#define Z_classes_Reference_HPP
|
||||
|
||||
#include <Z/macros/language.hpp>
|
||||
|
||||
|
||||
namespace Zeta {template <class t> struct Reference {
|
||||
typedef t type;
|
||||
|
||||
t *value;
|
||||
|
||||
|
||||
Z_CT(CPP11) Reference(t &value_) Z_NOTHROW
|
||||
: value(&value_) {}
|
||||
|
||||
|
||||
# if Z_DIALECT_HAS(CPP11, DELETED_FUNCTION)
|
||||
Z_CT(CPP11) Reference(t &&value_) = delete;
|
||||
# endif
|
||||
|
||||
|
||||
Z_CT(CPP11) operator t &() const Z_NOTHROW
|
||||
{return *value;}
|
||||
|
||||
|
||||
Z_CT(CPP11) t &get() const Z_NOTHROW
|
||||
{return *value;}
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_Span_HPP
|
||||
128
software/FusionX/src/z80drv/Zeta/API/Z/classes/Selector.hpp
vendored
Normal file
128
software/FusionX/src/z80drv/Zeta/API/Z/classes/Selector.hpp
vendored
Normal file
@@ -0,0 +1,128 @@
|
||||
/* Zeta API - Z/classes/Selector.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Selector_HPP
|
||||
#define Z_classes_Selector_HPP
|
||||
|
||||
#include <Z/inspection/language.h>
|
||||
|
||||
#if Z_DIALECT_HAS(CPP98, SFINAE) && \
|
||||
Z_DIALECT_HAS(CPP11, VARIADIC_TEMPLATE) && \
|
||||
Z_DIALECT_HAS(CPP11, DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATE)
|
||||
|
||||
# include <Z/traits/type.hpp>
|
||||
# include <Z/functions/Objective-C.hpp>
|
||||
|
||||
# if Z_DIALECT_HAS(CPP11, RVALUE_REFERENCE)
|
||||
# include <Z/functions/casting.hpp>
|
||||
# endif
|
||||
|
||||
# define Z_HAS_Selector TRUE
|
||||
|
||||
|
||||
namespace Zeta {
|
||||
template <class f> struct Selector;
|
||||
|
||||
|
||||
template <class r, class... p>
|
||||
struct Selector<r(p...)> {
|
||||
typedef r (* Send )(id, SEL, p...);
|
||||
typedef r (* SendSuper)(objc_super *, SEL, p...);
|
||||
|
||||
SEL selector;
|
||||
|
||||
|
||||
Z_INLINE Selector()
|
||||
Z_DEFAULTED({})
|
||||
|
||||
|
||||
Z_INLINE Selector(SEL selector_)
|
||||
: selector(selector_) {}
|
||||
|
||||
|
||||
Z_INLINE operator SEL() const Z_NOTHROW
|
||||
{return selector;}
|
||||
|
||||
|
||||
Z_INLINE r operator ()(id object, typename Type<p>::to_forwardable... arguments) const Z_NOTHROW
|
||||
{
|
||||
return (Send(ObjectiveC::send<r>()))
|
||||
(object, selector, arguments...);
|
||||
}
|
||||
|
||||
|
||||
Z_INLINE r super(id object, typename Type<p>::to_forwardable... arguments) const Z_NOTHROW
|
||||
{
|
||||
objc_super object_super = {object, class_getSuperclass(object_getClass(object))};
|
||||
|
||||
return (SendSuper(ObjectiveC::send_super<r>()))
|
||||
(&object_super, selector, arguments...);
|
||||
}
|
||||
|
||||
|
||||
Z_INLINE r super(const objc_super &object_super, typename Type<p>::to_forwardable... arguments) const Z_NOTHROW
|
||||
{
|
||||
return (SendSuper(ObjectiveC::send_super<r>()))
|
||||
(const_cast<objc_super *>(&object_super), selector, arguments...);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
# if Z_DIALECT_HAS(CPP11, RVALUE_REFERENCE)
|
||||
template <class r, class... p>
|
||||
struct Selector<r(p..., ...)> {
|
||||
typedef r (* Send )(id, SEL, p..., ...);
|
||||
typedef r (* SendSuper)(objc_super *, SEL, p..., ...);
|
||||
|
||||
SEL selector;
|
||||
|
||||
|
||||
Z_INLINE Selector()
|
||||
Z_DEFAULTED({})
|
||||
|
||||
|
||||
Z_INLINE Selector(SEL selector)
|
||||
: selector(selector) {}
|
||||
|
||||
|
||||
Z_INLINE operator SEL() const Z_NOTHROW
|
||||
{return selector;}
|
||||
|
||||
|
||||
template <class... pp>
|
||||
Z_INLINE r operator ()(id object, pp&&... arguments) const Z_NOTHROW
|
||||
{
|
||||
return (Send(ObjectiveC::send<r>()))
|
||||
(object, selector, forwardable<pp>(arguments)...);
|
||||
}
|
||||
|
||||
|
||||
template <class... pp>
|
||||
Z_INLINE r super(id object, pp&&... arguments) const Z_NOTHROW
|
||||
{
|
||||
objc_super object_super = {object, class_getSuperclass(object_getClass(object))};
|
||||
|
||||
return (SendSuper(ObjectiveC::send_super<r>()))
|
||||
(&object_super, selector, forwardable<pp>(arguments)...);
|
||||
}
|
||||
|
||||
|
||||
template <class... pp>
|
||||
Z_INLINE r super(const objc_super &object_super, pp&&... arguments) const Z_NOTHROW
|
||||
{
|
||||
return (SendSuper(ObjectiveC::send_super<r>()))
|
||||
(const_cast<objc_super *>(&object_super), selector, forwardable<pp>(arguments)...);
|
||||
}
|
||||
};
|
||||
# endif
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif // Z_classes_Selector_HPP
|
||||
175
software/FusionX/src/z80drv/Zeta/API/Z/classes/Shared.hpp
vendored
Normal file
175
software/FusionX/src/z80drv/Zeta/API/Z/classes/Shared.hpp
vendored
Normal file
@@ -0,0 +1,175 @@
|
||||
/* Zeta API - Z/classes/Shared.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Shared_HPP
|
||||
#define Z_classes_Shared_HPP
|
||||
|
||||
#include <Z/constants/pointer.h>
|
||||
#include <Z/macros/language.hpp>
|
||||
#include <Z/types/integral.hpp>
|
||||
#include <Z/types/pointer.hpp>
|
||||
|
||||
|
||||
namespace Zeta {template <class t> struct Shared {
|
||||
|
||||
struct Owned {
|
||||
t* data;
|
||||
USize owner_count;
|
||||
|
||||
|
||||
Z_INLINE Owned(t *data) Z_NOTHROW
|
||||
: data(data), owner_count(1) {}
|
||||
|
||||
|
||||
Z_INLINE ~Owned()
|
||||
{delete data;}
|
||||
|
||||
} *owned;
|
||||
|
||||
|
||||
Z_CT(CPP11) Shared() Z_NOTHROW
|
||||
: owned(Z_NULL) {}
|
||||
|
||||
|
||||
Z_INLINE Shared(const Shared &other) Z_NOTHROW
|
||||
{if ((owned = other.owned)) owned->owner_count++;}
|
||||
|
||||
|
||||
Z_INLINE Shared(t *data) Z_NOTHROW
|
||||
{owned = data ? new Owned(data) : Z_NULL;}
|
||||
|
||||
|
||||
Z_INLINE ~Shared()
|
||||
{if (owned && !--owned->owner_count) delete owned;}
|
||||
|
||||
|
||||
Z_INLINE operator Boolean() const Z_NOTHROW
|
||||
{return Boolean(owned);}
|
||||
|
||||
|
||||
Z_INLINE Shared &operator =(const Shared &rhs)
|
||||
{
|
||||
if (owned != rhs.owned)
|
||||
{
|
||||
if (owned && !--owned->owner_count) delete owned;
|
||||
if ((owned = rhs.owned)) owned->owner_count++;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
Z_INLINE Shared &operator =(t *rhs)
|
||||
{
|
||||
if (owned)
|
||||
{
|
||||
if (owned->data == rhs) return *this;
|
||||
if (!--owned->owner_count) delete owned;
|
||||
}
|
||||
|
||||
owned = rhs ? new Owned(rhs) : Z_NULL;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
friend Z_INLINE Boolean operator ==(const Shared &lhs, const Shared &rhs) Z_NOTHROW
|
||||
{return lhs.owned == rhs.owned;}
|
||||
|
||||
|
||||
friend Z_INLINE Boolean operator !=(const Shared &lhs, const Shared &rhs) Z_NOTHROW
|
||||
{return lhs.owned != rhs.owned;}
|
||||
|
||||
|
||||
Z_INLINE t &operator *() const Z_NOTHROW
|
||||
{return *owned->data;}
|
||||
|
||||
|
||||
Z_INLINE t *operator ->() const Z_NOTHROW
|
||||
{return owned->data;}
|
||||
|
||||
|
||||
Z_INLINE t *get() const Z_NOTHROW
|
||||
{return owned ? owned->data : Z_NULL;}
|
||||
|
||||
|
||||
Z_INLINE USize owner_count() const Z_NOTHROW
|
||||
{return owned->owner_count;}
|
||||
|
||||
|
||||
Z_INLINE void reset()
|
||||
{
|
||||
if (owned && !--owned->owner_count) delete owned;
|
||||
owned = Z_NULL;
|
||||
}
|
||||
|
||||
|
||||
Z_INLINE void swap(Shared &other) Z_NOTHROW
|
||||
{
|
||||
Owned *ex = owned;
|
||||
|
||||
owned = other.owned;
|
||||
other.owned = ex;
|
||||
}
|
||||
|
||||
|
||||
# ifdef Z_NULLPTR
|
||||
|
||||
Z_CT(CPP11) Shared(NullPtr) Z_NOTHROW
|
||||
: owned(nullptr) {}
|
||||
|
||||
|
||||
Z_INLINE Shared &operator =(NullPtr)
|
||||
{
|
||||
if (owned && !--owned->owner_count) delete owned;
|
||||
owned = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
friend Z_INLINE Boolean operator ==(const Shared &lhs, NullPtr) Z_NOTHROW
|
||||
{return !lhs.owned;}
|
||||
|
||||
|
||||
friend Z_INLINE Boolean operator ==(NullPtr, const Shared &rhs) Z_NOTHROW
|
||||
{return !rhs.owned;}
|
||||
|
||||
|
||||
friend Z_INLINE Boolean operator !=(const Shared &lhs, NullPtr) Z_NOTHROW
|
||||
{return !!lhs.owned;}
|
||||
|
||||
|
||||
friend Z_INLINE Boolean operator !=(NullPtr, const Shared &rhs) Z_NOTHROW
|
||||
{return !!rhs.owned;}
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
# if Z_DIALECT_HAS(CPP11, RVALUE_REFERENCE)
|
||||
|
||||
Z_INLINE Shared(Shared &&other) Z_NOTHROW
|
||||
: owned(other.owned)
|
||||
{other.owned = Z_NULL;}
|
||||
|
||||
|
||||
Z_INLINE Shared &operator =(Shared &&rhs)
|
||||
{
|
||||
if (owned != rhs.owned)
|
||||
{
|
||||
if (owned && !--owned->owner_count) delete owned;
|
||||
owned = rhs.owned;
|
||||
rhs.owned = Z_NULL;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
# endif
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_Shared_HPP
|
||||
55
software/FusionX/src/z80drv/Zeta/API/Z/classes/SizedString.hpp
vendored
Normal file
55
software/FusionX/src/z80drv/Zeta/API/Z/classes/SizedString.hpp
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/* Zeta API - Z/classes/SizedString.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_SizedString_HPP
|
||||
#define Z_classes_SizedString_HPP
|
||||
|
||||
#include <Z/classes/StringView.hpp>
|
||||
#include <utility>
|
||||
|
||||
|
||||
namespace Zeta{namespace ZetaDetail {
|
||||
|
||||
template <class t, USize s, class = std::make_index_sequence<s - 1> > struct SizedString;
|
||||
|
||||
|
||||
template <class t, USize s, std::size_t... i>
|
||||
struct SizedString<t, s, std::index_sequence<i...> > {
|
||||
t data[s];
|
||||
|
||||
|
||||
Z_CT(CPP11) SizedString(const t (&string)[s]) Z_NOTHROW
|
||||
: data{string[i]..., 0} {}
|
||||
|
||||
|
||||
Z_CT(CPP11) SizedString(const StringView<t> &string_view) Z_NOTHROW
|
||||
: data{string_view.data[i]..., 0} {}
|
||||
};
|
||||
}}
|
||||
|
||||
|
||||
namespace Zeta{template <class t, USize s> struct SizedString : ZetaDetail::SizedString<t, s> {
|
||||
|
||||
Z_CT(CPP11) SizedString(const t (&string)[s]) Z_NOTHROW
|
||||
: ZetaDetail::SizedString<t, s>(string) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) SizedString(const StringView<t> &string_view) Z_NOTHROW
|
||||
: ZetaDetail::SizedString<t, s>(string_view) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) operator const t *() const Z_NOTHROW
|
||||
{return this->data;}
|
||||
|
||||
|
||||
Z_CT(CPP11) const t &operator [](USize index) const Z_NOTHROW
|
||||
{return this->data[index];}
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_SizedString_HPP
|
||||
78
software/FusionX/src/z80drv/Zeta/API/Z/classes/Span.hpp
vendored
Normal file
78
software/FusionX/src/z80drv/Zeta/API/Z/classes/Span.hpp
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/* Zeta API - Z/classes/Span.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Span_HPP
|
||||
#define Z_classes_Span_HPP
|
||||
|
||||
#include <Z/constants/pointer.h>
|
||||
#include <Z/classes/Range.hpp>
|
||||
#include <Z/classes/Iterator.hpp>
|
||||
|
||||
|
||||
namespace Zeta {template <class t> struct Span {
|
||||
typedef const t* const_pointer;
|
||||
typedef const t& const_reference;
|
||||
typedef PtrDiff difference_type;
|
||||
typedef t element_type;
|
||||
// typedef Iterator<Span> iterator;
|
||||
typedef t* pointer;
|
||||
typedef t& reference;
|
||||
// typedef Iterator<t*> reverse_iterator;
|
||||
typedef USize size_type;
|
||||
typedef typename Type<t>::remove_const_volatile value_type;
|
||||
|
||||
t* data;
|
||||
USize size;
|
||||
|
||||
|
||||
Z_CT(CPP11) Span(t *first, USize size_) Z_NOTHROW
|
||||
: data(first), size(size_) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) Span(t *first, t *last) Z_NOTHROW
|
||||
: data(first), size(last - first) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) t &operator [](USize index) const Z_NOTHROW
|
||||
{return data[index];}
|
||||
|
||||
|
||||
Z_CT(CPP11) t &first() const Z_NOTHROW
|
||||
{return data[0];}
|
||||
|
||||
|
||||
Z_CT(CPP11) t &last() const Z_NOTHROW
|
||||
{return data[size - 1];}
|
||||
|
||||
|
||||
Z_CT(CPP11) Span head(USize head_size) const Z_NOTHROW
|
||||
{return Span(data, head_size);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Span tail(USize tail_size) const Z_NOTHROW
|
||||
{return Span(&data[size - tail_size], tail_size);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Span range(USize range_index, USize range_size) const Z_NOTHROW
|
||||
{return Span(&data[range_index], range_size);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Span range(const Range<USize> &range) const Z_NOTHROW
|
||||
{return Span(&data[range.index], range.size);}
|
||||
|
||||
|
||||
/* Z_CT(CPP11) Iterator<Span> begin() const Z_NOTHROW
|
||||
{return Iterator<Span>(*this, 0);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Iterator<Span> end() const Z_NOTHROW
|
||||
{return Iterator<Span>(*this, size);}*/
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_Span_HPP
|
||||
115
software/FusionX/src/z80drv/Zeta/API/Z/classes/Status.hpp
vendored
Normal file
115
software/FusionX/src/z80drv/Zeta/API/Z/classes/Status.hpp
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
/* Zeta API - Z/classes/Status.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Status_HPP
|
||||
#define Z_classes_Status_HPP
|
||||
|
||||
#include <Z/keys/status.h>
|
||||
#include <Z/macros/language.hpp>
|
||||
#include <Z/types/integral.hpp>
|
||||
|
||||
|
||||
namespace Zeta {struct Status {
|
||||
enum {OK = Z_OK};
|
||||
|
||||
struct Error {enum {
|
||||
Unknown = Z_ERROR_UNKNOWN,
|
||||
AlreadyExists = Z_ERROR_ALREADY_EXISTS,
|
||||
AlreadyInUse = Z_ERROR_ALREADY_IN_USE,
|
||||
AlreadyOpen = Z_ERROR_ALREADY_OPEN,
|
||||
AlreadyRunning = Z_ERROR_ALREADY_RUNNING,
|
||||
Busy = Z_ERROR_BUSY,
|
||||
Closed = Z_ERROR_CLOSED,
|
||||
ClosedByPeer = Z_ERROR_CLOSED_BY_PEER,
|
||||
Empty = Z_ERROR_EMPTY,
|
||||
Exception = Z_ERROR_EXCEPTION,
|
||||
Full = Z_ERROR_FULL,
|
||||
LimitReached = Z_ERROR_LIMIT_REACHED,
|
||||
Locked = Z_ERROR_LOCKED,
|
||||
Loop = Z_ERROR_LOOP,
|
||||
InvalidAddress = Z_ERROR_INVALID_ADDRESS,
|
||||
InvalidArgument = Z_ERROR_INVALID_ARGUMENT,
|
||||
InvalidData = Z_ERROR_INVALID_DATA,
|
||||
InvalidFormat = Z_ERROR_INVALID_FORMAT,
|
||||
InvalidIndex = Z_ERROR_INVALID_INDEX,
|
||||
InvalidInterval = Z_ERROR_INVALID_INTERVAL,
|
||||
InvalidIO = Z_ERROR_INVALID_IO,
|
||||
InvalidProtocol = Z_ERROR_INVALID_PROTOCOL,
|
||||
InvalidRange = Z_ERROR_INVALID_RANGE,
|
||||
InvalidRatio = Z_ERROR_INVALID_RATIO,
|
||||
InvalidSize = Z_ERROR_INVALID_SIZE,
|
||||
InvalidType = Z_ERROR_INVALID_TYPE,
|
||||
InvalidValue = Z_ERROR_INVALID_VALUE,
|
||||
NotAvailable = Z_ERROR_NOT_AVAILABLE,
|
||||
NotEnoughMemory = Z_ERROR_NOT_ENOUGH_MEMORY,
|
||||
NotEnoughSpace = Z_ERROR_NOT_ENOUGH_SPACE,
|
||||
NotEnoughResources = Z_ERROR_NOT_ENOUGH_RESOURCES,
|
||||
NotExecutable = Z_ERROR_NOT_EXECUTABLE,
|
||||
NotFinalized = Z_ERROR_NOT_FINALIZED,
|
||||
NotFound = Z_ERROR_NOT_FOUND,
|
||||
NotInitialized = Z_ERROR_NOT_INITIALIZED,
|
||||
NotReadable = Z_ERROR_NOT_READABLE,
|
||||
NotWritable = Z_ERROR_NOT_WRITABLE,
|
||||
NotSupported = Z_ERROR_NOT_SUPPORTED,
|
||||
RaceCondition = Z_ERROR_RACE_CONDITION,
|
||||
Rejected = Z_ERROR_REJECTED,
|
||||
StackOverflow = Z_ERROR_STACK_OVERFLOW,
|
||||
Stalled = Z_ERROR_STALLED,
|
||||
Terminated = Z_ERROR_TERMINATED,
|
||||
TimeOut = Z_ERROR_TIME_OUT,
|
||||
TooBig = Z_ERROR_TOO_BIG,
|
||||
TooSmall = Z_ERROR_TOO_SMALL,
|
||||
Unauthorized = Z_ERROR_UNAUTHORIZED,
|
||||
Unreachable = Z_ERROR_UNREACHABLE
|
||||
};};
|
||||
|
||||
SInt code;
|
||||
|
||||
|
||||
Z_INLINE Status() Z_NOTHROW
|
||||
Z_DEFAULTED({})
|
||||
|
||||
|
||||
Z_CT(CPP11) Status(SInt status) Z_NOTHROW
|
||||
: code(status) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) operator SInt() const Z_NOTHROW
|
||||
{return code;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(const Status &lhs, const Status &rhs) Z_NOTHROW
|
||||
{return lhs.code == rhs.code;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(const Status &lhs, UInt64 rhs) Z_NOTHROW
|
||||
{return lhs.code == rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(UInt64 lhs, const Status &rhs) Z_NOTHROW
|
||||
{return lhs == rhs.code;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(const Status &lhs, const Status &rhs) Z_NOTHROW
|
||||
{return lhs.code != rhs.code;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(const Status &lhs, UInt64 rhs) Z_NOTHROW
|
||||
{return lhs.code != rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(UInt64 lhs, const Status &rhs) Z_NOTHROW
|
||||
{return lhs != rhs.code;}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_error() const Z_NOTHROW
|
||||
{return code < 0;}
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_Status_HPP
|
||||
60
software/FusionX/src/z80drv/Zeta/API/Z/classes/Strid.hpp
vendored
Normal file
60
software/FusionX/src/z80drv/Zeta/API/Z/classes/Strid.hpp
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/* Zeta API - Z/classes/Strid.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Strid_HPP
|
||||
#define Z_classes_Strid_HPP
|
||||
|
||||
#include <Z/functions/hash.hpp>
|
||||
|
||||
|
||||
namespace Zeta {struct Strid {
|
||||
UInt64 hash;
|
||||
|
||||
|
||||
Z_INLINE Strid() Z_NOTHROW
|
||||
Z_DEFAULTED({})
|
||||
|
||||
|
||||
Z_CT(CPP11) Strid(UInt64 hash_) Z_NOTHROW
|
||||
: hash(hash_) {}
|
||||
|
||||
|
||||
Z_CT(CPP14) Strid(const Char *string) Z_NOTHROW
|
||||
: hash(fnv1a_64(string)) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) operator UInt64() const Z_NOTHROW
|
||||
{return hash;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(const Strid &lhs, const Strid &rhs) Z_NOTHROW
|
||||
{return lhs.hash == rhs.hash;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(const Strid &lhs, UInt64 rhs) Z_NOTHROW
|
||||
{return lhs.hash == rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(UInt64 lhs, const Strid &rhs) Z_NOTHROW
|
||||
{return lhs == rhs.hash;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(const Strid &lhs, const Strid &rhs) Z_NOTHROW
|
||||
{return lhs.hash != rhs.hash;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(const Strid &lhs, UInt64 rhs) Z_NOTHROW
|
||||
{return lhs.hash != rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(UInt64 lhs, const Strid &rhs) Z_NOTHROW
|
||||
{return lhs != rhs.hash;}
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_Strid_HPP
|
||||
89
software/FusionX/src/z80drv/Zeta/API/Z/classes/StringView.hpp
vendored
Normal file
89
software/FusionX/src/z80drv/Zeta/API/Z/classes/StringView.hpp
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
/* Zeta API - Z/classes/StringView.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_StringView_HPP
|
||||
#define Z_classes_StringView_HPP
|
||||
|
||||
#include <Z/constants/pointer.h>
|
||||
#include <Z/macros/language.hpp>
|
||||
#include <Z/types/integral.hpp>
|
||||
#include <Z/classes/Iterator.hpp>
|
||||
|
||||
#ifdef Z_WITH_STDCPP
|
||||
# include <cstring>
|
||||
#endif
|
||||
|
||||
namespace Zeta {template <class t> struct StringView {
|
||||
// typedef Iterator<t*> const_iterator;
|
||||
// typedef Iterator<t*> const_reverse_iterator;
|
||||
typedef const t* const_pointer;
|
||||
typedef const t& const_reference;
|
||||
typedef PtrDiff difference_type;
|
||||
// typedef Iterator<t*> iterator;
|
||||
typedef t* pointer;
|
||||
typedef t& reference;
|
||||
// typedef Iterator<t*> reverse_iterator;
|
||||
typedef USize size_type;
|
||||
typedef t value_type;
|
||||
|
||||
const t* data;
|
||||
USize size;
|
||||
|
||||
|
||||
Z_CT(CPP11) StringView() Z_NOTHROW
|
||||
: data(Z_NULL), size(0) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) StringView(const t *data_, USize size_) Z_NOTHROW
|
||||
: data(data_), size(size_) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) const t &operator [](USize index) const Z_NOTHROW
|
||||
{return data[index];}
|
||||
|
||||
|
||||
/* Z_CT(CPP11) iterator begin() const Z_NOTHROW
|
||||
{}
|
||||
|
||||
|
||||
Z_CT(CPP11) iterator end() const Z_NOTHROW
|
||||
{}*/
|
||||
|
||||
|
||||
# ifdef Z_WITH_STDCPP
|
||||
|
||||
friend Z_INLINE Boolean operator ==(const StringView &lhs, const StringView &rhs) Z_NOTHROW
|
||||
{return lhs.size == rhs.size && !std::memcmp(lhs.data, rhs.data, lhs.size * sizeof(t));}
|
||||
|
||||
|
||||
friend Z_INLINE Boolean operator !=(const StringView &lhs, const StringView &rhs) Z_NOTHROW
|
||||
{return lhs.size != rhs.size || std::memcmp(lhs.data, rhs.data, lhs.size * sizeof(t));}
|
||||
|
||||
|
||||
template <USize s>
|
||||
friend Z_INLINE Boolean operator ==(const StringView &lhs, const t (&rhs)[s]) Z_NOTHROW
|
||||
{return lhs.size == (s - 1) && !std::memcmp(lhs.data, rhs, (s - 1) * sizeof(t));}
|
||||
|
||||
|
||||
template <USize s>
|
||||
friend Z_INLINE Boolean operator !=(const StringView &lhs, const t (&rhs)[s]) Z_NOTHROW
|
||||
{return lhs.size != (s - 1) || std::memcmp(lhs.data, rhs, (s - 1) * sizeof(t));}
|
||||
|
||||
|
||||
friend Z_INLINE Boolean operator ==(const StringView &lhs, const t *rhs) Z_NOTHROW
|
||||
{return lhs.size * sizeof(t) == std::strlen(rhs) && !std::memcmp(lhs.data, rhs, lhs.size * sizeof(t));}
|
||||
|
||||
|
||||
friend Z_INLINE Boolean operator !=(const StringView &lhs, const t *rhs) Z_NOTHROW
|
||||
{return lhs.size * sizeof(t) != std::strlen(rhs) || std::memcmp(lhs.data, rhs, lhs.size * sizeof(t));}
|
||||
|
||||
# endif
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_StringView_HPP
|
||||
96
software/FusionX/src/z80drv/Zeta/API/Z/classes/TripleBuffer.hpp
vendored
Normal file
96
software/FusionX/src/z80drv/Zeta/API/Z/classes/TripleBuffer.hpp
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/* Zeta API - Z/classes/TripleBuffer.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_TripleBuffer_HPP
|
||||
#define Z_classes_TripleBuffer_HPP
|
||||
|
||||
#include <Z/constants/pointer.h>
|
||||
#include <Z/macros/language.hpp>
|
||||
#include <Z/types/buffer.h>
|
||||
#include <Z/types/integral.hpp>
|
||||
#include <Z/functions/atomic.h>
|
||||
|
||||
|
||||
namespace Zeta {struct TripleBuffer : ZTripleBuffer {
|
||||
|
||||
Z_INLINE TripleBuffer() Z_NOTHROW
|
||||
Z_DEFAULTED({})
|
||||
|
||||
|
||||
Z_INLINE TripleBuffer(void *data_, USize slot_size) Z_NOTHROW
|
||||
{initialize(data_, slot_size);}
|
||||
|
||||
|
||||
/// @brief Initializes the object.
|
||||
///
|
||||
/// @param data_ A pointer to a buffer.
|
||||
/// @param slot_size The size of the slot.
|
||||
|
||||
Z_INLINE void initialize(void *data_, USize slot_size) Z_NOTHROW
|
||||
{
|
||||
data[0] = data_;
|
||||
data[1] = reinterpret_cast<Char *>(data_) + slot_size;
|
||||
data[2] = reinterpret_cast<Char *>(data_) + slot_size * 2;
|
||||
flags = 6;
|
||||
}
|
||||
|
||||
|
||||
/// @brief Gets a pointer to the production slot.
|
||||
///
|
||||
/// @return A pointer to the current production slot.
|
||||
|
||||
Z_INLINE void *production_slot() const Z_NOTHROW
|
||||
{return data[(flags & 48) >> 4];}
|
||||
|
||||
|
||||
/// @brief Gets a pointer to the consumption slot.
|
||||
///
|
||||
/// @return A pointer to the current consumption slot.
|
||||
|
||||
Z_INLINE void *consumption_slot() const Z_NOTHROW
|
||||
{return data[flags & 3];}
|
||||
|
||||
|
||||
/// @brief Marks the the current production slot as produced.
|
||||
///
|
||||
/// @return A pointer to the new production slot.
|
||||
|
||||
Z_INLINE void *produce() Z_NOTHROW
|
||||
{
|
||||
UChar flags, new_flags;
|
||||
|
||||
do {
|
||||
flags = this->flags;
|
||||
new_flags = UChar(64 | ((flags & 12) << 2) | ((flags & 48) >> 2) | (flags & 3));
|
||||
}
|
||||
while (!z_type_atomic_set_if_equal(UCHAR)(&this->flags, flags, new_flags));
|
||||
|
||||
return data[(new_flags & 48) >> 4];
|
||||
}
|
||||
|
||||
|
||||
/// @brief Marks the current consumption slot as consumed.
|
||||
///
|
||||
/// @return A pointer to the new consumption slot.
|
||||
|
||||
Z_INLINE void *consume() Z_NOTHROW
|
||||
{
|
||||
UChar flags, new_flags;
|
||||
|
||||
do {
|
||||
if (!((flags = this->flags) & 64)) return Z_NULL;
|
||||
new_flags = UChar((flags & 48) | ((flags & 3) << 2) | ((flags & 12) >> 2));
|
||||
}
|
||||
while (!z_type_atomic_set_if_equal(UCHAR)(&this->flags, flags, new_flags));
|
||||
|
||||
return data[new_flags & 3];
|
||||
}
|
||||
};}
|
||||
|
||||
|
||||
#endif // Z_classes_TripleBuffer_HPP
|
||||
140
software/FusionX/src/z80drv/Zeta/API/Z/classes/Tuple.hpp
vendored
Normal file
140
software/FusionX/src/z80drv/Zeta/API/Z/classes/Tuple.hpp
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
/* Zeta API - Z/classes/Tuple.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Tuple_HPP
|
||||
#define Z_classes_Tuple_HPP
|
||||
|
||||
#include <Z/inspection/language.h>
|
||||
|
||||
#if Z_DIALECT_HAS(CPP11, EXTENDED_VARIADIC_TEMPLATE_TEMPLATE_PARAMETERS) /* ¿No es necesario, basta con VARIADIC_TEMPLATE? */
|
||||
# include <Z/traits/type.hpp>
|
||||
|
||||
# define Z_HAS_Tuple TRUE
|
||||
|
||||
|
||||
namespace Zeta {namespace ZetaDetail {namespace Tuple {
|
||||
|
||||
template <class type_list> struct Element;
|
||||
|
||||
|
||||
template <class... t> struct Super {
|
||||
typedef Element<typename TypeListRotateRight<TypeList<t...>, 1>::type> type;
|
||||
};
|
||||
|
||||
|
||||
template <class t0>
|
||||
struct Element<TypeList<t0> > {
|
||||
typedef t0 type;
|
||||
|
||||
type value;
|
||||
|
||||
Z_INLINE Element()
|
||||
Z_DEFAULTED({})
|
||||
|
||||
|
||||
Z_CT(CPP11) Element(typename Zeta::Type<t0>::to_forwardable value)
|
||||
: value(value) {}
|
||||
};
|
||||
|
||||
|
||||
template <class tn, class... t>
|
||||
struct Element<TypeList<tn, t...> > : Super<t...>::type {
|
||||
typedef tn type;
|
||||
|
||||
type value;
|
||||
|
||||
Z_INLINE Element()
|
||||
Z_DEFAULTED({})
|
||||
|
||||
|
||||
Z_CT(CPP11) Element(
|
||||
typename Zeta::Type<t >::to_forwardable... previous,
|
||||
typename Zeta::Type<tn>::to_forwardable value
|
||||
) : Super<t...>::type(previous...), value(value) {}
|
||||
};
|
||||
}}}
|
||||
|
||||
|
||||
namespace Zeta {template <class... t> class Tuple : public ZetaDetail::Tuple::Super<t...>::type {
|
||||
private:
|
||||
typedef typename ZetaDetail::Tuple::Super<t...>::type Super;
|
||||
|
||||
public:
|
||||
template <UInt i> class At {
|
||||
|
||||
private:
|
||||
enum {tail_size = TypeCount<t...>::value - (i + 1)};
|
||||
|
||||
public:
|
||||
typedef ZetaDetail::Tuple::Element<typename TypeListRotateRight<
|
||||
typename TypeListRemoveTail<TypeList<t...>, tail_size>::type, 1
|
||||
>::type> Element;
|
||||
|
||||
typedef typename Element::type type;
|
||||
};
|
||||
|
||||
|
||||
# if !Z_DIALECT_HAS(CPP11, INHERITING_CONSTRUCTORS)
|
||||
using Super::Super;
|
||||
|
||||
# else
|
||||
Z_INLINE Tuple()
|
||||
Z_DEFAULTED({})
|
||||
|
||||
|
||||
Z_CT(CPP11) Tuple(typename Type<t>::to_forwardable... values)
|
||||
: Super(values...) {}
|
||||
# endif
|
||||
|
||||
|
||||
template <UInt index>
|
||||
Z_INLINE typename At<index>::type &at() Z_NOTHROW
|
||||
{return At<index>::Element::value;}
|
||||
|
||||
|
||||
template <UInt index>
|
||||
Z_CT(CPP11) typename Type<typename At<index>::type>::to_forwardable get() const Z_NOTHROW
|
||||
{return At<index>::Element::value;}
|
||||
|
||||
|
||||
template <UInt index>
|
||||
Z_INLINE Tuple &set(typename Type<typename At<index>::type>::to_forwardable value)
|
||||
{
|
||||
At<index>::Element::value = value;
|
||||
return *this;
|
||||
}
|
||||
};}
|
||||
|
||||
|
||||
# if defined(Z_WITH_STD) && Z_DIALECT_HAS(CPP17, STRUCTURED_BINDING) && defined(__has_include) && __has_include(<tuple>)
|
||||
|
||||
# include <tuple>
|
||||
|
||||
# define Z__IMPLEMENTATION(qualifiers) \
|
||||
\
|
||||
template <class... t> \
|
||||
struct std::tuple_size<qualifiers Zeta::Tuple<t...> > { \
|
||||
enum {value = sizeof...(t)}; \
|
||||
}; \
|
||||
\
|
||||
template <std::size_t i, class... t> \
|
||||
struct std::tuple_element<i, qualifiers Zeta::Tuple<t...> > { \
|
||||
typedef typename Zeta::Type<typename Zeta::Tuple<t...>::template At<i>::type>::add_const type; \
|
||||
};
|
||||
|
||||
Z__IMPLEMENTATION(Z_EMPTY )
|
||||
Z__IMPLEMENTATION(const )
|
||||
Z__IMPLEMENTATION(const volatile)
|
||||
Z__IMPLEMENTATION( volatile)
|
||||
|
||||
# undef Z__IMPLEMENTATION
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif // Z_classes_Tuple_HPP
|
||||
13
software/FusionX/src/z80drv/Zeta/API/Z/classes/Unique.hpp
vendored
Normal file
13
software/FusionX/src/z80drv/Zeta/API/Z/classes/Unique.hpp
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
/* Zeta API - Z/classes/Unique.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_Unique_HPP
|
||||
#define Z_classes_Unique_HPP
|
||||
|
||||
|
||||
#endif // Z_classes_Unique_HPP
|
||||
501
software/FusionX/src/z80drv/Zeta/API/Z/classes/XY.hpp
vendored
Normal file
501
software/FusionX/src/z80drv/Zeta/API/Z/classes/XY.hpp
vendored
Normal file
@@ -0,0 +1,501 @@
|
||||
/* Zeta API - Z/classes/XY.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_XY_HPP
|
||||
#define Z_classes_XY_HPP
|
||||
|
||||
#include <Z/functions/math.hpp>
|
||||
|
||||
#ifdef Z_WITH_CG_GEOMETRY
|
||||
# include <CoreGraphics/CGGeometry.h>
|
||||
#endif
|
||||
|
||||
#if defined(Z_WITH_NS_GEOMETRY) && Z_LANGUAGE_INCLUDES(OBJECTIVE_CPP)
|
||||
# import <Foundation/NSGeometry.h>
|
||||
#endif
|
||||
|
||||
#ifdef Z_WITH_COCOS2D_X
|
||||
# include "cocos2d.h"
|
||||
#endif
|
||||
|
||||
#ifdef Z_WITH_QT
|
||||
# include <QPoint>
|
||||
# include <QSize>
|
||||
# include <QRect>
|
||||
#endif
|
||||
|
||||
namespace Zeta {template <class t> struct XYZ;}
|
||||
|
||||
|
||||
namespace Zeta {template <class t> struct XY {
|
||||
t x, y;
|
||||
|
||||
Z_INLINE XY() Z_NOTHROW Z_DEFAULTED({})
|
||||
|
||||
Z_CT(CPP11) XY(t x_, t y_) Z_NOTHROW
|
||||
: x(x_), y(y_) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY(t xy) Z_NOTHROW
|
||||
: x(xy), y(xy) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY(const XYZ<t> &xy) Z_NOTHROW
|
||||
: x(xy.x), y(xy.y) {}
|
||||
|
||||
|
||||
# if Z_DIALECT_HAS(CPP98, SFINAE) && \
|
||||
Z_DIALECT_HAS(CPP11, DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATE)
|
||||
|
||||
template <class other_t, class e = typename TypeIf<!TypeIsSame<t, other_t>::value>::type>
|
||||
Z_CT(CPP11) XY(const XY<other_t> &other) Z_NOTHROW
|
||||
: x(t(other.x)), y(t(other.y)) {}
|
||||
# endif
|
||||
|
||||
|
||||
Z_CT(CPP11) operator Boolean() const Z_NOTHROW
|
||||
{return x != t(0) || y != t(0);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(const XY &lhs, const XY &rhs) Z_NOTHROW
|
||||
{return lhs.x == rhs.x && lhs.y == rhs.y;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(const XY &lhs, const XY &rhs) Z_NOTHROW
|
||||
{return lhs.x != rhs.x || lhs.y != rhs.y;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >=(const XY &lhs, const XY &rhs) Z_NOTHROW
|
||||
{return lhs.x >= rhs.x && lhs.y >= rhs.y;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <=(const XY &lhs, const XY &rhs) Z_NOTHROW
|
||||
{return lhs.x <= rhs.x && lhs.y <= rhs.y;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >(const XY &lhs, const XY &rhs) Z_NOTHROW
|
||||
{return lhs.x > rhs.x && lhs.y > rhs.y;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <(const XY &lhs, const XY &rhs) Z_NOTHROW
|
||||
{return lhs.x < rhs.x && lhs.y < rhs.y;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XY operator +(const XY &lhs, const XY &rhs) Z_NOTHROW
|
||||
{return XY(lhs.x + rhs.x, lhs.y + rhs.y);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XY operator -(const XY &lhs, const XY &rhs) Z_NOTHROW
|
||||
{return XY(lhs.x - rhs.x, lhs.y - rhs.y);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XY operator *(const XY &lhs, const XY &rhs) Z_NOTHROW
|
||||
{return XY(lhs.x * rhs.x, lhs.y * rhs.y);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XY operator /(const XY &lhs, const XY &rhs) Z_NOTHROW
|
||||
{return XY(lhs.x / rhs.x, lhs.y / rhs.y);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(const XY &lhs, t rhs) Z_NOTHROW
|
||||
{return lhs.x == rhs && lhs.y == rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(const XY &lhs, t rhs) Z_NOTHROW
|
||||
{return lhs.x != rhs || lhs.y != rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >=(const XY &lhs, t rhs) Z_NOTHROW
|
||||
{return lhs.x >= rhs && lhs.y >= rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <=(const XY &lhs, t rhs) Z_NOTHROW
|
||||
{return lhs.x <= rhs && lhs.y <= rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >(const XY &lhs, t rhs) Z_NOTHROW
|
||||
{return lhs.x > rhs && lhs.y > rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <(const XY &lhs, t rhs) Z_NOTHROW
|
||||
{return lhs.x < rhs && lhs.y < rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XY operator +(const XY &lhs, t rhs) Z_NOTHROW
|
||||
{return XY(lhs.x + rhs, lhs.y + rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XY operator -(const XY &lhs, t rhs) Z_NOTHROW
|
||||
{return XY(lhs.x - rhs, lhs.y - rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XY operator *(const XY &lhs, t rhs) Z_NOTHROW
|
||||
{return XY(lhs.x * rhs, lhs.y * rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XY operator /(const XY &lhs, t rhs) Z_NOTHROW
|
||||
{return XY(lhs.x / rhs, lhs.y / rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(t lhs, const XY &rhs) Z_NOTHROW
|
||||
{return lhs == rhs.x && lhs == rhs.y;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(t lhs, const XY &rhs) Z_NOTHROW
|
||||
{return lhs != rhs.x || lhs != rhs.y;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >=(t lhs, const XY &rhs) Z_NOTHROW
|
||||
{return lhs >= rhs.x && lhs >= rhs.y;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <=(t lhs, const XY &rhs) Z_NOTHROW
|
||||
{return lhs <= rhs.x && lhs <= rhs.y;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >(t lhs, const XY &rhs) Z_NOTHROW
|
||||
{return lhs > rhs.x && lhs > rhs.y;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <(t lhs, const XY &rhs) Z_NOTHROW
|
||||
{return lhs < rhs.x && lhs < rhs.y;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XY operator +(t lhs, const XY &rhs) Z_NOTHROW
|
||||
{return XY(lhs + rhs.x, lhs + rhs.y);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XY operator *(t lhs, const XY &rhs) Z_NOTHROW
|
||||
{return XY(lhs * rhs.x, lhs * rhs.y);}
|
||||
|
||||
|
||||
Z_INLINE XY &operator +=(const XY &rhs) Z_NOTHROW {return *this = *this + rhs;}
|
||||
Z_INLINE XY &operator -=(const XY &rhs) Z_NOTHROW {return *this = *this - rhs;}
|
||||
Z_INLINE XY &operator *=(const XY &rhs) Z_NOTHROW {return *this = *this * rhs;}
|
||||
Z_INLINE XY &operator /=(const XY &rhs) Z_NOTHROW {return *this = *this / rhs;}
|
||||
|
||||
Z_INLINE XY &operator +=(t rhs) Z_NOTHROW {return *this = *this + rhs;}
|
||||
Z_INLINE XY &operator -=(t rhs) Z_NOTHROW {return *this = *this - rhs;}
|
||||
Z_INLINE XY &operator *=(t rhs) Z_NOTHROW {return *this = *this * rhs;}
|
||||
Z_INLINE XY &operator /=(t rhs) Z_NOTHROW {return *this = *this / rhs;}
|
||||
|
||||
Z_INLINE t operator [](UInt index) const Z_NOTHROW {return ((t *)this)[index];}
|
||||
Z_INLINE t &operator [](UInt index) Z_NOTHROW {return ((t *)this)[index];}
|
||||
|
||||
Z_CT(CPP11) XY yx () const Z_NOTHROW {return XY(y, x);}
|
||||
Z_CT(CPP11) XYZ<t> nxy(t n) const Z_NOTHROW {return XYZ<t>(n, x, y);}
|
||||
Z_CT(CPP11) XYZ<t> nyx(t n) const Z_NOTHROW {return XYZ<t>(n, y, x);}
|
||||
Z_CT(CPP11) XYZ<t> xny(t n) const Z_NOTHROW {return XYZ<t>(x, n, y);}
|
||||
Z_CT(CPP11) XYZ<t> xyn(t n) const Z_NOTHROW {return XYZ<t>(x, y, n);}
|
||||
Z_CT(CPP11) XYZ<t> ynx(t n) const Z_NOTHROW {return XYZ<t>(y, n, x);}
|
||||
Z_CT(CPP11) XYZ<t> yxn(t n) const Z_NOTHROW {return XYZ<t>(y, x, n);}
|
||||
|
||||
|
||||
Z_INLINE XY apply(t (* function)(t)) const Z_NOTHROW
|
||||
{return XY(function(x), function(y));}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY clamp(const XY &minimum, const XY &maximum) const Z_NOTHROW
|
||||
{
|
||||
return XY(
|
||||
Zeta::clamp<t>(x, minimum.x, maximum.x),
|
||||
Zeta::clamp<t>(y, minimum.y, maximum.y));
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY clamp(t minimum, t maximum) const Z_NOTHROW
|
||||
{
|
||||
return XY(
|
||||
Zeta::clamp<t>(x, minimum, maximum),
|
||||
Zeta::clamp<t>(y, minimum, maximum));
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) t cross_product(const XY &other) const Z_NOTHROW
|
||||
{return x * other.y - y * other.x;}
|
||||
|
||||
|
||||
Z_CT(CPP11) t dot_product(const XY &other) const Z_NOTHROW
|
||||
{return x * other.x + y * other.y;}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY fit(const XY &other) const Z_NOTHROW
|
||||
{
|
||||
return y / x > other.y / other.x
|
||||
? XY(x * other.y / y, other.y)
|
||||
: XY(other.x, y * other.x / x);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean has_zero() const Z_NOTHROW
|
||||
{return x == t(0) || y == t(0);}
|
||||
|
||||
|
||||
Z_CT(CPP11) t inner_maximum() const Z_NOTHROW
|
||||
{return Zeta::maximum<t>(x, y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) t inner_middle() const Z_NOTHROW
|
||||
{return (x + y) / t(2);}
|
||||
|
||||
|
||||
Z_CT(CPP11) t inner_minimum() const Z_NOTHROW
|
||||
{return Zeta::minimum<t>(x, y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) t inner_product() const Z_NOTHROW
|
||||
{return x * y;}
|
||||
|
||||
|
||||
Z_CT(CPP11) t inner_sum() const Z_NOTHROW
|
||||
{return x + y;}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_zero() const Z_NOTHROW
|
||||
{return x == t(0) && y == t(0);}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY maximum(const XY &other) const Z_NOTHROW
|
||||
{return XY(Zeta::maximum<t>(x, other.x), Zeta::maximum<t>(y, other.y));}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY middle(const XY &other) const Z_NOTHROW
|
||||
{return XY((x + other.x) / t(2), (y + other.y) / t(2));}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY minimum(const XY &other) const Z_NOTHROW
|
||||
{return XY(Zeta::minimum<t>(x, other.x), Zeta::minimum<t>(y, other.y));}
|
||||
|
||||
|
||||
Z_CT(CPP11) t squared_length() const Z_NOTHROW
|
||||
{return x * x + y * y;}
|
||||
|
||||
|
||||
// MARK: - Signed
|
||||
|
||||
|
||||
Z_CT(CPP11) XY absolute() const Z_NOTHROW
|
||||
{return XY(Zeta::absolute<t>(x), Zeta::absolute<t>(y));}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean has_negative() const Z_NOTHROW
|
||||
{return x < t(0) || y < t(0);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_negative() const Z_NOTHROW
|
||||
{return x < t(0) && y < t(0);}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY negative() const Z_NOTHROW
|
||||
{return XY(-x, -y);}
|
||||
|
||||
|
||||
// MARK: - Integer
|
||||
|
||||
|
||||
// Z_CT(CPP11) Boolean is_perpendicular(const XY &other) const Z_NOTHROW
|
||||
// {return !Zeta::absolute<t>(dot_product(other));}
|
||||
|
||||
|
||||
// MARK: - Real
|
||||
|
||||
|
||||
Z_CT(CPP11) XY clamp_01() const Z_NOTHROW
|
||||
{return XY(Zeta::clamp_01<t>(x), Zeta::clamp_01<t>(y));}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean has_almost_zero() const Z_NOTHROW
|
||||
{return Zeta::is_almost_zero<t>(x) || Zeta::is_almost_zero<t>(y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean has_finite() const Z_NOTHROW
|
||||
{return Zeta::is_finite<t>(x) || Zeta::is_finite<t>(y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean has_infinity() const Z_NOTHROW
|
||||
{return Zeta::is_infinity<t>(x) || Zeta::is_infinity<t>(y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean has_nan() const Z_NOTHROW
|
||||
{return Zeta::is_nan<t>(x) || Zeta::is_nan<t>(y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY inverse_lerp(const XY &other, t v) const Z_NOTHROW
|
||||
{
|
||||
return XY(
|
||||
Zeta::inverse_lerp<t>(x, other.x, v),
|
||||
Zeta::inverse_lerp<t>(y, other.y, v));
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_almost_equal(const XY &other) const Z_NOTHROW
|
||||
{
|
||||
return Zeta::are_almost_equal<t>(x, other.x) &&
|
||||
Zeta::are_almost_equal<t>(y, other.y);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_almost_zero() const Z_NOTHROW
|
||||
{return Zeta::is_almost_zero<t>(x) && Zeta::is_almost_zero<t>(y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_finite() const Z_NOTHROW
|
||||
{return Zeta::is_finite<t>(x) && Zeta::is_finite<t>(y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_infinity() const Z_NOTHROW
|
||||
{return Zeta::is_infinity<t>(x) && Zeta::is_infinity<t>(y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_nan() const Z_NOTHROW
|
||||
{return Zeta::is_nan<t>(x) && Zeta::is_nan<t>(y);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_perpendicular(const XY &other) const Z_NOTHROW
|
||||
{return Zeta::absolute<t>(dot_product(other)) <= Type<t>::epsilon();}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY lerp(const XY &other, t v) const Z_NOTHROW
|
||||
{
|
||||
return XY(
|
||||
Zeta::lerp<t>(x, other.x, v),
|
||||
Zeta::lerp<t>(y, other.y, v));
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY reciprocal() const Z_NOTHROW
|
||||
{return XY(t(1) / x, t(1) / y);}
|
||||
|
||||
|
||||
# if defined(Z_WITH_CG_GEOMETRY) || defined(Z_WITH_NS_GEOMETRY)
|
||||
|
||||
# define Z__APPLE_CONSTRUCTORS(Prefix) \
|
||||
\
|
||||
Z_CT(CPP11) XY(const Prefix##Point &point) Z_NOTHROW \
|
||||
: x(point.x), y(point.y) {} \
|
||||
\
|
||||
\
|
||||
Z_CT(CPP11) XY(const Prefix##Size &size) Z_NOTHROW \
|
||||
: x(size.width), y(size.height) {}
|
||||
|
||||
|
||||
# if Z_DIALECT_HAS(CPP11, COPY_LIST_INITIALIZATION)
|
||||
|
||||
# define Z__APPLE_OPERATORS(Prefix) \
|
||||
\
|
||||
Z_CT(CPP11) operator Prefix##Point() const Z_NOTHROW \
|
||||
{return {CGFloat(x), CGFloat(y)};} \
|
||||
\
|
||||
\
|
||||
Z_CT(CPP11) operator Prefix##Size() const Z_NOTHROW \
|
||||
{return {CGFloat(x), CGFloat(y)};} \
|
||||
\
|
||||
\
|
||||
Z_CT(CPP11) operator Prefix##Rect() const Z_NOTHROW \
|
||||
{return {{0.0, 0.0}, {CGFloat(x), CGFloat(y)}};}
|
||||
|
||||
# else
|
||||
# define Z__APPLE_OPERATORS(Prefix) \
|
||||
\
|
||||
Z_CT(CPP14) operator Prefix##Point() const Z_NOTHROW \
|
||||
{ \
|
||||
Prefix##Point result = {CGFloat(x), CGFloat(y)}; \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
Z_CT(CPP14) operator Prefix##Size() const Z_NOTHROW \
|
||||
{ \
|
||||
Prefix##Size result = {CGFloat(x), CGFloat(y)}; \
|
||||
return result; \
|
||||
} \
|
||||
\
|
||||
\
|
||||
Z_CT(CPP14) operator Prefix##Rect() const Z_NOTHROW \
|
||||
{ \
|
||||
Prefix##Rect result = {CGFloat(0), CGFloat(0), CGFloat(x), CGFloat(y)}; \
|
||||
return result; \
|
||||
}
|
||||
# endif
|
||||
|
||||
|
||||
# ifdef Z_WITH_CG_GEOMETRY
|
||||
Z__APPLE_CONSTRUCTORS(CG)
|
||||
Z__APPLE_OPERATORS (CG)
|
||||
# endif
|
||||
|
||||
# if defined(Z_WITH_NS_GEOMETRY) && \
|
||||
Z_LANGUAGE_INCLUDES(OBJECTIVE_CPP) && \
|
||||
(!defined(Z_WITH_CG_GEOMETRY) || \
|
||||
!defined(NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES) || \
|
||||
!NSGEOMETRY_TYPES_SAME_AS_CGGEOMETRY_TYPES)
|
||||
|
||||
Z__APPLE_CONSTRUCTORS(NS)
|
||||
Z__APPLE_OPERATORS (NS)
|
||||
# endif
|
||||
|
||||
# undef Z__APPLE_CONSTRUCTORS
|
||||
# undef Z__APPLE_OPERATORS
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
# ifdef Z_WITH_COCOS2D_X
|
||||
|
||||
Z_CT(CPP11) XY(const cocos2d::Vec2 &point) Z_NOTHROW
|
||||
: x(point.x), y(point.y) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY(const cocos2d::Size &size) Z_NOTHROW
|
||||
: x(size.width), y(size.height) {}
|
||||
|
||||
|
||||
Z_INLINE operator cocos2d::Vec2() const Z_NOTHROW
|
||||
{return cocos2d::Vec2(float(x), float(y));}
|
||||
|
||||
|
||||
Z_INLINE operator cocos2d::Size() const Z_NOTHROW
|
||||
{return cocos2d::Size(float(x), float(y));}
|
||||
|
||||
|
||||
Z_INLINE operator cocos2d::Rect() const Z_NOTHROW
|
||||
{return cocos2d::Rect(0.0f, 0.0f, float(x), float(y));}
|
||||
|
||||
# endif
|
||||
|
||||
|
||||
# ifdef Z_WITH_QT
|
||||
|
||||
Z_CT(CPP11) XY(const QPoint &point) Z_NOTHROW
|
||||
: x(t(point.x())), y(t(point.y())) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) XY(const QSize &size) Z_NOTHROW
|
||||
: x(t(size.width())), y(t(size.height())) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) operator QPoint() const Z_NOTHROW
|
||||
{return QPoint(int(x), int(y));}
|
||||
|
||||
|
||||
Z_CT(CPP11) operator QSize() const Z_NOTHROW
|
||||
{return QSize(int(x), int(y));}
|
||||
|
||||
|
||||
Z_CT(CPP11) operator QRect() const Z_NOTHROW
|
||||
{return QRect(0, 0, int(x), int(y));}
|
||||
|
||||
# endif
|
||||
};}
|
||||
|
||||
|
||||
#ifndef Z_classes_XYZ_HPP
|
||||
# include <Z/classes/XYZ.hpp>
|
||||
#endif
|
||||
|
||||
#endif // Z_classes_XY_HPP
|
||||
522
software/FusionX/src/z80drv/Zeta/API/Z/classes/XYZ.hpp
vendored
Normal file
522
software/FusionX/src/z80drv/Zeta/API/Z/classes/XYZ.hpp
vendored
Normal file
@@ -0,0 +1,522 @@
|
||||
/* Zeta API - Z/classes/XYZ.hpp
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_classes_XYZ_HPP
|
||||
#define Z_classes_XYZ_HPP
|
||||
|
||||
#ifndef Z_classes_XY_HPP
|
||||
# include <Z/classes/XY.hpp>
|
||||
#endif
|
||||
|
||||
|
||||
namespace Zeta {template <class t> struct XYZ {
|
||||
t x, y, z;
|
||||
|
||||
|
||||
Z_INLINE XYZ() Z_NOTHROW Z_DEFAULTED({})
|
||||
|
||||
Z_CT(CPP11) XYZ(t x_, t y_, t z_) Z_NOTHROW
|
||||
: x(x_), y(y_), z(z_) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ(t x_, t y_) Z_NOTHROW
|
||||
: x(x_), y(y_), z(t(0)) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ(t xyz) Z_NOTHROW
|
||||
: x(xyz), y(xyz) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ(const XY<t> &xy) Z_NOTHROW
|
||||
: x(xy.x), y(xy.y), z(t(0)) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ(const XY<t> &xy, t z_) Z_NOTHROW
|
||||
: x(xy.x), y(xy.y), z(z_) {}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ(t x_, const XY<t> &yz) Z_NOTHROW
|
||||
: x(x_), y(yz.x), z(yz.y) {}
|
||||
|
||||
|
||||
# if Z_DIALECT_HAS(CPP98, SFINAE) && \
|
||||
Z_DIALECT_HAS(CPP11, DEFAULT_TEMPLATE_ARGUMENTS_FOR_FUNCTION_TEMPLATE)
|
||||
|
||||
template <class other_t, class e = typename TypeIf<!TypeIsSame<t, other_t>::value>::type>
|
||||
Z_CT(CPP11) XYZ(const XYZ<other_t> &other) Z_NOTHROW
|
||||
: x(t(other.x)), y(t(other.y), x(t(other.z))) {}
|
||||
# endif
|
||||
|
||||
|
||||
Z_CT(CPP11) operator Boolean() const Z_NOTHROW
|
||||
{return x != t(0) || y != t(0) || z != t(0);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >=(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs.x >= rhs.x && lhs.y >= rhs.y && lhs.z >= rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <=(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs.x <= rhs.x && lhs.y <= rhs.y && lhs.z <= rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs.x > rhs.x && lhs.y > rhs.y && lhs.z > rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs.x < rhs.x && lhs.y < rhs.y && lhs.z < rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator +(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return XYZ(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator -(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return XYZ(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator *(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return XYZ(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator /(const XYZ &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return XYZ(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(const XYZ &lhs, t rhs) Z_NOTHROW
|
||||
{return lhs.x == rhs && lhs.y == rhs && lhs.z == rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(const XYZ &lhs, t rhs) Z_NOTHROW
|
||||
{return lhs.x != rhs || lhs.y != rhs || lhs.z != rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >=(const XYZ &lhs, t rhs) Z_NOTHROW
|
||||
{return lhs.x >= rhs && lhs.y >= rhs && lhs.z >= rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <=(const XYZ &lhs, t rhs) Z_NOTHROW
|
||||
{return lhs.x <= rhs && lhs.y <= rhs && lhs.z <= rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >(const XYZ &lhs, t rhs) Z_NOTHROW
|
||||
{return lhs.x > rhs && lhs.y > rhs && lhs.z > rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <(const XYZ &lhs, t rhs) Z_NOTHROW
|
||||
{return lhs.x < rhs && lhs.y < rhs && lhs.z < rhs;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator +(const XYZ &lhs, t rhs) Z_NOTHROW
|
||||
{return XYZ(lhs.x + rhs, lhs.y + rhs, lhs.z + rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator -(const XYZ &lhs, t rhs) Z_NOTHROW
|
||||
{return XYZ(lhs.x - rhs, lhs.y - rhs, lhs.z - rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator *(const XYZ &lhs, t rhs) Z_NOTHROW
|
||||
{return XYZ(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator /(const XYZ &lhs, t rhs) Z_NOTHROW
|
||||
{return XYZ(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(t lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs == rhs.x && lhs == rhs.y && lhs == rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(t lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs != rhs.x || lhs != rhs.y || lhs != rhs.y;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >=(t lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs >= rhs.x && lhs >= rhs.y && lhs >= rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <=(t lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs <= rhs.x && lhs <= rhs.y && lhs <= rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >(t lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs > rhs.x && lhs > rhs.y && lhs > rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <(t lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs < rhs.x && lhs < rhs.y && lhs < rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator +(t lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return XYZ(lhs + rhs.x, lhs + rhs.y, lhs + rhs.z);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator *(t lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return XYZ(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(const XYZ &lhs, const XY<t> &rhs) Z_NOTHROW
|
||||
{return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == t(0);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(const XYZ &lhs, const XY<t> &rhs) Z_NOTHROW
|
||||
{return lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != t(0);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >=(const XYZ &lhs, const XY<t> &rhs) Z_NOTHROW
|
||||
{return lhs.x >= rhs.x && lhs.y >= rhs.y && lhs.z >= t(0);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <=(const XYZ &lhs, const XY<t> &rhs) Z_NOTHROW
|
||||
{return lhs.x <= rhs.x && lhs.y <= rhs.y && lhs.z <= t(0);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >(const XYZ &lhs, const XY<t> &rhs) Z_NOTHROW
|
||||
{return lhs.x > rhs.x && lhs.y > rhs.y && lhs.z > t(0);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <(const XYZ &lhs, const XY<t> &rhs) Z_NOTHROW
|
||||
{return lhs.x < rhs.x && lhs.y < rhs.y && lhs.z < t(0);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator +(const XYZ &lhs, const XY<t> &rhs) Z_NOTHROW
|
||||
{return XYZ(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator -(const XYZ &lhs, const XY<t> &rhs) Z_NOTHROW
|
||||
{return XYZ(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator *(const XYZ &lhs, const XY<t> &rhs) Z_NOTHROW
|
||||
{return XYZ(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z, t(0));}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator ==(const XY<t> &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs.x == rhs.x && lhs.y == rhs.y && rhs.z == t(0);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator !=(const XY<t> &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs.x != rhs.x || lhs.y != rhs.y || rhs.z != t(0);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >=(const XY<t> &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs.x >= rhs.x && lhs.y >= rhs.y && t(0) >= rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <=(const XY<t> &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs.x <= rhs.x && lhs.y <= rhs.y && t(0) <= rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator >(const XY<t> &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs.x > rhs.x && lhs.y > rhs.y && t(0) > rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) Boolean operator <(const XY<t> &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return lhs.x < rhs.x && lhs.y < rhs.y && t(0) < rhs.z;}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator +(const XY<t> &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return XYZ(lhs.x + rhs.x, lhs.y + rhs.y, rhs.z);}
|
||||
|
||||
|
||||
friend Z_CT(CPP11) XYZ operator *(const XY<t> &lhs, const XYZ &rhs) Z_NOTHROW
|
||||
{return XYZ(lhs.x + rhs.x, lhs.y + rhs.y, rhs.z, t(0));}
|
||||
|
||||
|
||||
Z_INLINE XYZ &operator +=(const XYZ &rhs) Z_NOTHROW {return *this = *this + rhs;}
|
||||
Z_INLINE XYZ &operator -=(const XYZ &rhs) Z_NOTHROW {return *this = *this - rhs;}
|
||||
Z_INLINE XYZ &operator *=(const XYZ &rhs) Z_NOTHROW {return *this = *this * rhs;}
|
||||
Z_INLINE XYZ &operator /=(const XYZ &rhs) Z_NOTHROW {return *this = *this / rhs;}
|
||||
|
||||
Z_INLINE XYZ &operator +=(t rhs) Z_NOTHROW {return *this = *this + rhs;}
|
||||
Z_INLINE XYZ &operator -=(t rhs) Z_NOTHROW {return *this = *this - rhs;}
|
||||
Z_INLINE XYZ &operator *=(t rhs) Z_NOTHROW {return *this = *this * rhs;}
|
||||
Z_INLINE XYZ &operator /=(t rhs) Z_NOTHROW {return *this = *this / rhs;}
|
||||
|
||||
Z_INLINE XY<t> &operator +=(XY<t> rhs) Z_NOTHROW {return *this = *this + rhs;}
|
||||
Z_INLINE XY<t> &operator -=(XY<t> rhs) Z_NOTHROW {return *this = *this - rhs;}
|
||||
Z_INLINE XY<t> &operator *=(XY<t> rhs) Z_NOTHROW {return *this = *this * rhs;}
|
||||
|
||||
Z_INLINE t operator [](UInt index) const Z_NOTHROW {return ((t *)this)[index];}
|
||||
Z_INLINE t &operator [](UInt index) Z_NOTHROW {return ((t *)this)[index];}
|
||||
|
||||
Z_CT(CPP11) XY<t> xy () const Z_NOTHROW {return XY<t>(x, y);}
|
||||
Z_CT(CPP11) XY<t> xz () const Z_NOTHROW {return XY<t>(x, z);}
|
||||
Z_CT(CPP11) XY<t> yx () const Z_NOTHROW {return XY<t>(y, x);}
|
||||
Z_CT(CPP11) XY<t> yz () const Z_NOTHROW {return XY<t>(y, z);}
|
||||
Z_CT(CPP11) XY<t> zx () const Z_NOTHROW {return XY<t>(z, x);}
|
||||
Z_CT(CPP11) XY<t> zy () const Z_NOTHROW {return XY<t>(z, y);}
|
||||
Z_CT(CPP11) XYZ xzy() const Z_NOTHROW {return XYZ(x, z, y);}
|
||||
Z_CT(CPP11) XYZ yxz() const Z_NOTHROW {return XYZ(y, x, z);}
|
||||
Z_CT(CPP11) XYZ yzx() const Z_NOTHROW {return XYZ(y, z, x);}
|
||||
Z_CT(CPP11) XYZ zxy() const Z_NOTHROW {return XYZ(z, x, y);}
|
||||
Z_CT(CPP11) XYZ zyx() const Z_NOTHROW {return XYZ(z, y, x);}
|
||||
|
||||
|
||||
Z_INLINE XYZ apply(t (* function)(t)) const Z_NOTHROW
|
||||
{return XYZ(function(x), function(y), function(z));}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ clamp(const XYZ &minimum, const XYZ &maximum) const Z_NOTHROW
|
||||
{
|
||||
return XYZ(
|
||||
Zeta::clamp<t>(x, minimum.x, maximum.x),
|
||||
Zeta::clamp<t>(y, minimum.y, maximum.y),
|
||||
Zeta::clamp<t>(z, minimum.z, maximum.z));
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ clamp(t minimum, t maximum) const Z_NOTHROW
|
||||
{
|
||||
return XYZ(
|
||||
Zeta::clamp<t>(x, minimum, maximum),
|
||||
Zeta::clamp<t>(y, minimum, maximum),
|
||||
Zeta::clamp<t>(z, minimum, maximum));
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ cross_product(const XYZ &other) const Z_NOTHROW
|
||||
{
|
||||
return XYZ(
|
||||
y * other.z - z * other.y,
|
||||
z * other.x - x * other.z,
|
||||
x * other.y - y * other.x);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) t dot_product(const XYZ &other) const Z_NOTHROW
|
||||
{return x * other.x + y * other.y + z * other.z;}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ fit(const XYZ &other) const Z_NOTHROW
|
||||
{return XYZ(t(0));} /* TODO */
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean has_zero() const Z_NOTHROW
|
||||
{return x == t(0) || y == t(0) || z == t(0);}
|
||||
|
||||
|
||||
Z_CT(CPP11) t inner_maximum() const Z_NOTHROW
|
||||
{return Zeta::maximum<t>(Zeta::maximum<t>(x, y), z);}
|
||||
|
||||
|
||||
Z_CT(CPP11) t inner_middle() const Z_NOTHROW
|
||||
{return (x + y + z) / t(3);}
|
||||
|
||||
|
||||
Z_CT(CPP11) t inner_minimum() const Z_NOTHROW
|
||||
{return Zeta::minimum<t>(Zeta::minimum<t>(x, y), z);}
|
||||
|
||||
|
||||
Z_CT(CPP11) t inner_product() const Z_NOTHROW
|
||||
{return x * y * z;}
|
||||
|
||||
|
||||
Z_CT(CPP11) t inner_sum() const Z_NOTHROW
|
||||
{return x + y + z;}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_zero() const Z_NOTHROW
|
||||
{return x == t(0) && y == t(0) && z == t(0);}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ maximum(const XYZ &other) const Z_NOTHROW
|
||||
{
|
||||
return XYZ(
|
||||
Zeta::maximum<t>(x, other.x),
|
||||
Zeta::maximum<t>(y, other.y),
|
||||
Zeta::maximum<t>(z, other.z));
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ middle(const XYZ &other) const Z_NOTHROW
|
||||
{
|
||||
return XYZ(
|
||||
(x + other.x) / t(2),
|
||||
(y + other.y) / t(2),
|
||||
(z + other.z) / t(2));
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ minimum(const XYZ &other) const Z_NOTHROW
|
||||
{
|
||||
return XYZ(
|
||||
Zeta::minimum<t>(x, other.x),
|
||||
Zeta::minimum<t>(y, other.y),
|
||||
Zeta::minimum<t>(z, other.z));
|
||||
}
|
||||
|
||||
|
||||
/*Z_INLINE XYZ rotate_as_axes(XYZ<SInt8> rotation) const Z_NOTHROW
|
||||
{
|
||||
XYZ result = *this;
|
||||
|
||||
if ((rotation.x % 4) & 1) Zeta::swap<t>(&result.y, &result.z);
|
||||
if ((rotation.y % 4) & 1) Zeta::swap<t>(&result.x, &result.z);
|
||||
if ((rotation.z % 4) & 1) Zeta::swap<t>(&result.x, &result.y);
|
||||
return result;
|
||||
}*/
|
||||
|
||||
|
||||
Z_CT(CPP11) t squared_length() const Z_NOTHROW
|
||||
{return x * x + y * y + z * z;}
|
||||
|
||||
|
||||
// MARK: - Signed
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ absolute() const Z_NOTHROW
|
||||
{
|
||||
return XYZ(
|
||||
Zeta::absolute<t>(x),
|
||||
Zeta::absolute<t>(y),
|
||||
Zeta::absolute<t>(z));
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean has_negative() const Z_NOTHROW
|
||||
{return x < t(0) || y < t(0) || z < t(0);}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_negative() const Z_NOTHROW
|
||||
{return x < t(0) && y < t(0) && z < t(0);}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ negative() const Z_NOTHROW
|
||||
{return XYZ(-x, -y, -z);}
|
||||
|
||||
|
||||
// MARK: - Integer
|
||||
|
||||
|
||||
//Z_CT(CPP11) Boolean is_perpendicular(const XYZ &other) const
|
||||
// {return !Zeta::absolute<t>(dot_product(other));}
|
||||
|
||||
|
||||
// MARK: - Real
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ clamp_01() const Z_NOTHROW
|
||||
{
|
||||
return XYZ(
|
||||
Zeta::clamp_01<t>(x),
|
||||
Zeta::clamp_01<t>(y),
|
||||
Zeta::clamp_01<t>(z));
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean has_almost_zero() const Z_NOTHROW
|
||||
{
|
||||
return Zeta::is_almost_zero<t>(x) ||
|
||||
Zeta::is_almost_zero<t>(y) ||
|
||||
Zeta::is_almost_zero<t>(z);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean has_finite() const Z_NOTHROW
|
||||
{
|
||||
return Zeta::is_finite<t>(x) ||
|
||||
Zeta::is_finite<t>(y) ||
|
||||
Zeta::is_finite<t>(z);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean has_infinity() const Z_NOTHROW
|
||||
{
|
||||
return Zeta::is_infinity<t>(x) ||
|
||||
Zeta::is_infinity<t>(y) ||
|
||||
Zeta::is_infinity<t>(z);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean has_nan() const Z_NOTHROW
|
||||
{
|
||||
return Zeta::is_nan<t>(x) ||
|
||||
Zeta::is_nan<t>(y) ||
|
||||
Zeta::is_nan<t>(z);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ inverse_lerp(const XYZ &other, t v) const Z_NOTHROW
|
||||
{
|
||||
return XYZ(
|
||||
Zeta::inverse_lerp<t>(x, other.x, v),
|
||||
Zeta::inverse_lerp<t>(y, other.y, v),
|
||||
Zeta::inverse_lerp<t>(z, other.z, v));
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_almost_equal(const XYZ &other) const Z_NOTHROW
|
||||
{
|
||||
return Zeta::are_almost_equal<t>(x, other.x) &&
|
||||
Zeta::are_almost_equal<t>(y, other.y) &&
|
||||
Zeta::are_almost_equal<t>(z, other.z);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_almost_zero() const Z_NOTHROW
|
||||
{
|
||||
return Zeta::is_almost_zero<t>(x) &&
|
||||
Zeta::is_almost_zero<t>(y) &&
|
||||
Zeta::is_almost_zero<t>(z);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_finite() const Z_NOTHROW
|
||||
{
|
||||
return Zeta::is_finite<t>(x) &&
|
||||
Zeta::is_finite<t>(y) &&
|
||||
Zeta::is_finite<t>(z);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_infinity() const Z_NOTHROW
|
||||
{
|
||||
return Zeta::is_infinity<t>(x) &&
|
||||
Zeta::is_infinity<t>(y) &&
|
||||
Zeta::is_infinity<t>(z);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_nan() const Z_NOTHROW
|
||||
{
|
||||
return Zeta::is_nan<t>(x) &&
|
||||
Zeta::is_nan<t>(y) &&
|
||||
Zeta::is_nan<t>(z);
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) Boolean is_perpendicular(const XYZ &other) const Z_NOTHROW
|
||||
{return Zeta::absolute<t>(dot_product(other)) <= Type<t>::epsilon();}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ lerp(const XYZ &other, t v) const Z_NOTHROW
|
||||
{
|
||||
return XYZ(
|
||||
Zeta::lerp<t>(x, other.x, v),
|
||||
Zeta::lerp<t>(y, other.y, v),
|
||||
Zeta::lerp<t>(z, other.z, v));
|
||||
}
|
||||
|
||||
|
||||
Z_CT(CPP11) XYZ reciprocal() const Z_NOTHROW
|
||||
{return XYZ(t(1) / x, t(1) / y, t(1) / z);}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // Z_classes_XYZ_HPP
|
||||
20
software/FusionX/src/z80drv/Zeta/API/Z/constants/boolean.h
vendored
Normal file
20
software/FusionX/src/z80drv/Zeta/API/Z/constants/boolean.h
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
/* Zeta API - Z/constants/boolean.h
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_constants_boolean_H
|
||||
#define Z_constants_boolean_H
|
||||
|
||||
#ifndef TRUE
|
||||
# define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
# define FALSE 0
|
||||
#endif
|
||||
|
||||
#endif /* Z_constants_boolean_H */
|
||||
47
software/FusionX/src/z80drv/Zeta/API/Z/constants/build.hpp
vendored
Normal file
47
software/FusionX/src/z80drv/Zeta/API/Z/constants/build.hpp
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
/* Zeta API - Z/constants/build.h
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_constants_build_HPP
|
||||
#define Z_constants_build_HPP
|
||||
|
||||
#include <Z/inspection/language.h>
|
||||
|
||||
#if Z_DIALECT_HAS_SPECIFIER(CPP11, CONSTEXPR)
|
||||
|
||||
namespace Zeta {enum {
|
||||
build_year = (__DATE__[7] - '0') * 1000 + (__DATE__[ 8] - '0') * 100 +
|
||||
(__DATE__[9] - '0') * 10 + (__DATE__[10] - '0'),
|
||||
|
||||
build_month = __DATE__[0] == 'J'
|
||||
? (__DATE__[1] == 'a'
|
||||
? 1
|
||||
: (__DATE__[2] == 'n' ? 6 : 7))
|
||||
: (__DATE__[0] == 'F'
|
||||
? 2
|
||||
: (__DATE__[0] == 'M'
|
||||
? (__DATE__[2] == 'r' ? 3 : 5)
|
||||
: (__DATE__[0] == 'A'
|
||||
? (__DATE__[1] == 'p' ? 4 : 8)
|
||||
: (__DATE__[0] == 'S'
|
||||
? 9
|
||||
: (__DATE__[0] == 'O'
|
||||
? 10
|
||||
: (__DATE__[0] == 'N' ? 11 : 12)))))),
|
||||
|
||||
build_day = (__DATE__[4] == ' '
|
||||
? 0
|
||||
: __DATE__[4] - '0') * 10 + (__DATE__[5] - '0'),
|
||||
|
||||
build_hour = (__TIME__[0] - '0') * 10 + (__TIME__[1] - '0'),
|
||||
build_minutes = (__TIME__[3] - '0') * 10 + (__TIME__[4] - '0'),
|
||||
build_seconds = (__TIME__[6] - '0') * 10 + (__TIME__[7] - '0')
|
||||
};}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* Z_constants_build_HPP */
|
||||
968
software/FusionX/src/z80drv/Zeta/API/Z/constants/numbers.h
vendored
Normal file
968
software/FusionX/src/z80drv/Zeta/API/Z/constants/numbers.h
vendored
Normal file
@@ -0,0 +1,968 @@
|
||||
/* Zeta API - Z/constants/numbers.h
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_constants_numbers_H
|
||||
#define Z_constants_numbers_H
|
||||
|
||||
/* MARK: - Irrational numbers */
|
||||
|
||||
#define Z_ALPHA /* α ~ Feigenbaum's α Constant */ 2.\
|
||||
5029078750958928222839028732182157863812713767271499773361920567\
|
||||
7923546317959020670329964974643383412959523186999585472394218237\
|
||||
7785445179272863314993372578112163594879503744781260997380598671\
|
||||
2397117373289276654044010306698313834600094139322364490657889951\
|
||||
2205843172507873377463087853424285351988587500042358246918740820\
|
||||
4281700901714823051821621619413199856066129382742649709844084470\
|
||||
1008054549677936760888126446406885181552709324007542506497157047\
|
||||
0475419932831783645332562415378693957125097066387979492654623137\
|
||||
6745918909813116752434221110130913127837160951158341230841503716\
|
||||
4997020224681219644081216686527458043026245782561067150138521821\
|
||||
6449532543349873487413352795815351016583605455763513276501810781\
|
||||
1948369459574850237398235452625632779475397269902012891516645793\
|
||||
9420198920248803394051699686551494477396533876979741232354061781\
|
||||
9896112494095990353128997733611849847377946108428833293833903950\
|
||||
9008914086351525626803381414669279913310743349705143545201344643\
|
||||
4264752001621384610729922641994332772918977769053802596851
|
||||
|
||||
#define Z_DELTA /* δ ~ Feigenbaum's δ Constant */ 4.\
|
||||
6692016091029906718532038204662016172581855774757686327456513430\
|
||||
0413433021131473713868974402394801381716598485518981513440862714\
|
||||
2027932522312442988890890859944935463236713411532481714219947455\
|
||||
6443658237932020095610583305754586176522220703854106467494942849\
|
||||
8145339172620056875566595233987560382563722564800409510712838906\
|
||||
1184470277585428541980111344017500242858538249833571552205223608\
|
||||
7250291678860362674527213399057131606875345083433934446103706309\
|
||||
4520191158769724322735898389037949462572512890979489867683346116\
|
||||
2688911656312347446057517953912204556247280709520219819909455858\
|
||||
1946136877445617396074115614074243754435499204869180982648652368\
|
||||
4387027996490173977934251347238087371362116018601281861020563818\
|
||||
1835409759847796417390032893617143215987824078977661439139576403\
|
||||
7760537119096932066998361984288981837003229412030210655743295550\
|
||||
3888458497370347275321219257069584140746618419819610061296401614\
|
||||
8771294441590140546794180019813325337859249336588307045999993837\
|
||||
5411726563553016862529032210862320550634510679399023341675
|
||||
|
||||
#define Z_DELTA_S /* δs ~ Silver Ratio */ 2.\
|
||||
4142135623730950488016887242096980785696718753769480731766797379\
|
||||
9073247846210703885038753432764157
|
||||
|
||||
#define Z_E /* e ~ Euler's Number */ 2.\
|
||||
7182818284590452353602874713526624977572470936999595749669676277\
|
||||
2407663035354759457138217852516642742746639193200305992181741359\
|
||||
6629043572900334295260595630738132328627943490763233829880753195\
|
||||
2510190115738341879307021540891499348841675092447614606680822648\
|
||||
0016847741185374234544243710753907774499206955170276183860626133\
|
||||
1384583000752044933826560297606737113200709328709127443747047230\
|
||||
6969772093101416928368190255151086574637721112523897844250569536\
|
||||
9677078544996996794686445490598793163688923009879312773617821542\
|
||||
4999229576351482208269895193668033182528869398496465105820939239\
|
||||
8294887933203625094431173012381970684161403970198376793206832823\
|
||||
7646480429531180232878250981945581530175671736133206981125099618\
|
||||
1881593041690351598888519345807273866738589422879228499892086805\
|
||||
8257492796104841984443634632449684875602336248270419786232090021\
|
||||
6099023530436994184914631409343173814364054625315209618369088870\
|
||||
7016768396424378140592714563549061303107208510383750510115747704\
|
||||
1718986106873969655212671546889570350354021234078498193343210681
|
||||
|
||||
#define Z_G /* G ~ Catalan's Constant */ 0.\
|
||||
9159655941772190150546035149323841107741493742816721342664981196\
|
||||
21763019776254769479356512926115106248574
|
||||
|
||||
#define Z_GAMMA /* γ ~ Euler–Mascheroni Constant */ 0.\
|
||||
5772156649015328606065120900824024310421593359399235988057672348\
|
||||
8486772677766467093694706329174674951463144724980708248096050401\
|
||||
4486542836224173997644923536253500333742937337737673942792595258\
|
||||
2470949160087352039481656708532331517766115286211995015079847937\
|
||||
4508570574002992135478614669402960432542151905877553526733139925\
|
||||
4012967420513754139549111685102807984234877587205038431093997361\
|
||||
3725530608893312676001724795378367592713515772261027349291394079\
|
||||
8430103417771778088154957066107501016191663340152278935867965497\
|
||||
2520362128792265559536696281763887927268013243101047650596370394\
|
||||
7394957638906572967929601009015125195950922243501409349871228247\
|
||||
9497471956469763185066761290638110518241974448678363808617494551\
|
||||
6989279230187739107294578155431600500218284409605377243420328547\
|
||||
8367015177394398700302370339518328690001558193988042707411542227\
|
||||
8197165230110735658339673487176504919418123000406546931429992977\
|
||||
7956930310050308630341856980323108369164002589297089098548682577\
|
||||
73642882539549258736295961332985747393023734388470703702844129
|
||||
|
||||
#define Z_OMEGA /* Ω ~ W(1) */ 0.\
|
||||
5671432904097838729999686622103555497538157871865125081351310792\
|
||||
2304579308668456669321944696175229455763802497286678978545235846\
|
||||
5940072995608516439289994614311571492959803594376698474635606134\
|
||||
2268461356989570453977624855707865877337063566333012384304556354\
|
||||
2978608509015429081920856055752374819658465950807273089050157336\
|
||||
1831596070667108039283918360149499646349348448317465915933636893\
|
||||
3680971490856983717510093546792166747552889731475588925030572822\
|
||||
4604865124854109688318448770433467727016574464765200627013360494\
|
||||
8057883875774914635983034808686985627342099151198306130250270223\
|
||||
7292838727216542426572698430693890685874829642167823425504200307\
|
||||
1966795220895590936913343950051154949542716768789494702443830337\
|
||||
8784002606637609098563645828787818795338304237475555696975428665\
|
||||
6135480540090110477123732473016808842009334259193374301935466235\
|
||||
3076567270975761218841385994442828002635250684447525596225061138\
|
||||
7848128978427693880472920268889238516484753423844953902789609971\
|
||||
1060547842212061361983111973376227976096491011771088137407049732
|
||||
|
||||
#define Z_P2 /* P₂ ~ Universal Parabolic Constant */ 2.\
|
||||
2955871493926380740342980491894903875978322036385834839299753466\
|
||||
4410966268413312668409442623789761559175
|
||||
|
||||
#define Z_PHI /* φ ~ Divine Proportion, Golden Ratio */ 1.\
|
||||
6180339887498948482045868343656381177203091798057628621354486227\
|
||||
0526046281890244970720720418939113748475408807538689175212663386\
|
||||
2223536931793180060766726354433389086595939582905638322661319928\
|
||||
2902678806752087668925017116962070322210432162695486262963136144\
|
||||
3814975870122034080588795445474924618569536486444924104432077134\
|
||||
4947049565846788509874339442212544877066478091588460749988712400\
|
||||
7652170575179788341662562494075890697040002812104276217711177780\
|
||||
5315317141011704666599146697987317613560067087480710131795236894\
|
||||
2752194843530567830022878569978297783478458782289110976250030269\
|
||||
6156170025046433824377648610283831268330372429267526311653392473\
|
||||
1671112115881863851331620384005222165791286675294654906811317159\
|
||||
9343235973494985090409476213222981017261070596116456299098162905\
|
||||
5520852479035240602017279974717534277759277862561943208275051312\
|
||||
1815628551222480939471234145170223735805772786160086883829523045\
|
||||
9264787801788992199027077690389532196819861514378031499741106926\
|
||||
0886742962267575605231727775203536139362107673893764556060605921
|
||||
|
||||
#define Z_PI /* π */ 3.\
|
||||
1415926535897932384626433832795028841971693993751058209749445923\
|
||||
0781640628620899862803482534211706798214808651328230664709384460\
|
||||
9550582231725359408128481117450284102701938521105559644622948954\
|
||||
9303819644288109756659334461284756482337867831652712019091456485\
|
||||
6692346034861045432664821339360726024914127372458700660631558817\
|
||||
4881520920962829254091715364367892590360011330530548820466521384\
|
||||
1469519415116094330572703657595919530921861173819326117931051185\
|
||||
4807446237996274956735188575272489122793818301194912983367336244\
|
||||
0656643086021394946395224737190702179860943702770539217176293176\
|
||||
7523846748184676694051320005681271452635608277857713427577896091\
|
||||
7363717872146844090122495343014654958537105079227968925892354201\
|
||||
9956112129021960864034418159813629774771309960518707211349999998\
|
||||
3729780499510597317328160963185950244594553469083026425223082533\
|
||||
4468503526193118817101000313783875288658753320838142061717766914\
|
||||
7303598253490428755468731159562863882353787593751957781857780532\
|
||||
1712268066130019278766111959092164201989380952572010654858632788
|
||||
|
||||
#define Z_RHO /* ρ ~ Plastic Number */ 1.\
|
||||
3247179572447460259609088544780973407344040569017333645340150503\
|
||||
0282785124554759405469934798178728032991092099474220742510890263\
|
||||
9045897795594314757096723471754166839038867418751736931584253549\
|
||||
9082466223545337273504589879909568150627745509802486213012169894\
|
||||
1575245745486250756265246103689389048399322699520749759628288685\
|
||||
5690815070451369610985335257728158603344114192782827376529603299\
|
||||
3584674231028483241695239006108543338218508398101808957353870473\
|
||||
9313439673137676460210316527688939639353259439924831031095839537\
|
||||
7519426028877409271862033892820161525553218270947061305676123988\
|
||||
9204637306571962977716886308761533248001117680731166845322774315\
|
||||
6628996072663835722103634707098383715980223371021309824684908631\
|
||||
2969366344392445007154150429000819030670589845339053468872874066\
|
||||
1957756261670617642889193912308379183117162296038861476358807306\
|
||||
3150974837675824592702890131950955155601228003859576154017842151\
|
||||
7618
|
||||
|
||||
#define Z_TAU /* τ ~ Prouhet–Thue–Morse Constant */ 0.\
|
||||
412454033640107597783361
|
||||
|
||||
#define Z_ZETA_3 /* ζ(3) ~ Apéry's Constant */ 1.\
|
||||
2020569031595942853997381615114499907649862923404988817922715553\
|
||||
4183820578631309018645587360933525814619915779526071941849199599\
|
||||
8673283213776396837207900161453941782949360066719191575522242494\
|
||||
2439615639096641032911590957809655146512799184051057152559880154\
|
||||
3710978110203982753256678760352233698494166181105701471577863949\
|
||||
9737523785277937030956025701853182790003076547107563048843320869\
|
||||
7115737423807934450316076253177145354444118311781822497185263570\
|
||||
9182448998796203508335756172022603393785870328131267807990054177\
|
||||
3486911525370656237057440966221712902627320732361492242913040528\
|
||||
5553723410330775777980642420243048828152100091460265382206962715\
|
||||
5202082274335001015294801198690117625951676366998171835575234880\
|
||||
7037195557423472940835952088616662025728537558130792825864872821\
|
||||
7370556619689895266201877681062920081779233813587682842641243243\
|
||||
1480282173674506720693507626895304345939375032966363775750624733\
|
||||
2399234828831077339052768020075798435679371150509005027366047114\
|
||||
0085335034364672248565315181177661810922279191022488396800266606
|
||||
|
||||
#define Z_APERY_CONSTANT Z_ZETA_3
|
||||
|
||||
/* Bernstein's Constant */
|
||||
#define Z_BERNSTEIN_CONSTANT 0.\
|
||||
28016949902386913303643649123067200004248213981236
|
||||
|
||||
/* Cahen's constant */
|
||||
#define Z_CAHEN_CONSTANT 0.\
|
||||
6434105462883380261822543077575647632865878602682395059870309203\
|
||||
0749277646183261084844089555046343195405372900995969467846947098\
|
||||
1802430097780147073963456948247668586823491596555581306050580602\
|
||||
6256306777475500425607601960884398861769982603193090004364305280\
|
||||
6567338111342478976190975546079525373761160043883391348037160666\
|
||||
7849974184079776825402840257413825951159592097430630557408812114\
|
||||
4696101394340462070490073318995421946198637524805100624978738532\
|
||||
6841116944408820095760047244297718746082273520598185316636923727\
|
||||
6790472958772175441607432838562778155230454121621791172401531531\
|
||||
8883239557424569302059076729469550847427091071937146523382004276\
|
||||
6671376387740391112213044251840172373010457848486880087124078290\
|
||||
1457449877274770249676563130590862156100889975149986642474501700\
|
||||
5581154212587814616117557775789114686770822872829465693504467164\
|
||||
0959525956030861979618867444196869756004609746414038853402815847\
|
||||
5936540509205782123128626092476347619412226683926102068711744992\
|
||||
8500177376751575327731991603831036751803975694669235336301908766
|
||||
|
||||
/* Conway's Constant */
|
||||
#define Z_CONWAY_CONSTANT 1.\
|
||||
3035772690342963912570991121525518907307025046594048757548613906\
|
||||
2855088785246155712681576686442522555347139304709490268396284989\
|
||||
3551554347375824856691088977770216576006666613618195758149971416\
|
||||
2117477679231324299325720143046277132953880169252753163112124160\
|
||||
2789744556311221192891765945442844221050348398443048435036597886\
|
||||
1636568696122933005217967812127420727428338418585389780462975362\
|
||||
1113325713155961142841646364930650685182742924915750807604716554\
|
||||
8732899031406796262775210982301850098048676804171127036928277045\
|
||||
5569925410472532552960023967416151761300757699523941470920962729\
|
||||
7796525283812895292399842146646970063628087185984737643242596375\
|
||||
3778614871491804177943882564549629612672676317034139989238683800\
|
||||
1749933916383255041973874337640464423096341637734299996402795347\
|
||||
7812315036938111361969193101105512224328065334872949851635350180\
|
||||
0086189800442695696203908949639604105938945262628974848057200498\
|
||||
9520589408315451152746418415125180247302001937967778366214066091\
|
||||
1047529322875883638588769569619942051649976764376226646605546524
|
||||
|
||||
/* Copeland–Erdős Constant */
|
||||
#define Z_COPELAND_ERDOS_CONSTANT 0.\
|
||||
2357111317192329313741434753596167717379838997101103107109113127\
|
||||
1311371391491511571631671731791811911931971992112232272292332392\
|
||||
4125125726326927127728128329330731131331733133734734935335936737\
|
||||
3379383389397401409419421431433439443449457461463467479487491499\
|
||||
5035095215235415475575635695715775875935996016076136176196316416\
|
||||
4364765365966167367768369170170971972773373974375175776176977378\
|
||||
7797809811821823827829839853857859863877881883887907911919929937\
|
||||
9419479539679719779839919971009101310191021103110331039104910511\
|
||||
0611063106910871091109310971103110911171123112911511153116311711\
|
||||
1811187119312011213121712231229123112371249125912771279128312891\
|
||||
2911297130113031307131913211327136113671373138113991409142314271\
|
||||
4291433143914471451145314591471148114831487148914931499151115231\
|
||||
5311543154915531559156715711579158315971601160716091613161916211\
|
||||
6271637165716631667166916931697169917091721172317331741174717531\
|
||||
7591777178317871789180118111823183118471861186718711873187718791\
|
||||
8891901190719131931193319491951197319791987199319971999200320112
|
||||
|
||||
/* Dubois-Raymond Constant */
|
||||
#define Z_DUBOIS_RAYMOND_CONSTANT 0.\
|
||||
1945280494653251136152137302875039065901577852759236620435639112\
|
||||
6128689803952888169215624253956089738687658063273943306194230184\
|
||||
6390636687239196106699038887450061447803705376851195665473775341\
|
||||
0432909101348239341042021104911276174378712312707073399640646659\
|
||||
4403538165050966894987036499348004765165375766040941184234739651\
|
||||
4956779385722841561961636382301294169998230606424642604839452569\
|
||||
4123319935614068634305323678131896475911139214742172930676438469\
|
||||
3349287600077498007403753598564668470942599861444131812798597054\
|
||||
7933095739935752164198846632305117558156194995005256891703382249\
|
||||
3319463428079109321077886242460055967658105859758658736348984146\
|
||||
7259992527092431598567842973511456278699178055257489684072513882\
|
||||
2403821492552091058527972095893841735642638248904856731252070117\
|
||||
6210793704693341271357851963226482022753143890006555463250692416\
|
||||
7265132318157078023594405882897139317429953835226355968647936199\
|
||||
7993536655407480626554885296765049525164840537710545438813154286\
|
||||
2425019139361380724333725282493692938578755281217194719835697214
|
||||
|
||||
/* Fransén–Robinson Constant */
|
||||
#define Z_FRANSEN_ROBINSON_CONSTANT 2.\
|
||||
8077702420285193652215011865577729323080859209301982912200548095\
|
||||
9710088912190166551018530816819663814187416434292647678607356834\
|
||||
7830897012446742487764751667549180849932709220052990094447342952\
|
||||
0658351475152131155061828050485818763476748076712998234216343271\
|
||||
32839553888361830581061735321115429359987705
|
||||
|
||||
/* Froda Constant */
|
||||
#define Z_FRODA_CONSTANT 6.\
|
||||
5808859910179209708515424038864864915730774383480740051215126610\
|
||||
3130504039582040980102991492610759196856156668455125548138339170\
|
||||
3289202458856954899842363505373271623341799384794496221955199521\
|
||||
9817257192218388867595645961802004143922594049488307254920458946\
|
||||
8453227772258857709537332768570509596095271117425536510662899569\
|
||||
7277185088450012821602790991199992049536662057550853887690385613\
|
||||
7002632531317153051100200863766096686558637839580581513980142957\
|
||||
7334256389687241990566392949483335138446018013413478388302980462\
|
||||
1310697071249342564168139126312706622063772884318204059466632628\
|
||||
8699565585079898698033973449949718559489634828335307265242104748\
|
||||
2135319342734258054306012628140042042969387544936469490135496070\
|
||||
6954953488235435685881195896105422830179666394139001710669418514\
|
||||
8764432569707997421913960662789237104829140068449429415344843421\
|
||||
6682628035399961925125252573981078131758341309762667123525922193\
|
||||
5544343127146165493705806126785444366179457823420514254471624604\
|
||||
1373218142284623260713740224396531435039076042586205557463472653
|
||||
|
||||
/* Gauss-Kuzmin-Wirsing Constant */
|
||||
#define Z_GAUSS_KUZMIN_WIRSING_CONSTANT 0.\
|
||||
3036630028987326585974481219015562331108773522536578951882454814\
|
||||
6722699529424691098434081193436363681109827226371061693847461485\
|
||||
9745801316065265381818237879132446139896476429740950446293759490\
|
||||
4870297728772511058335175922044472408659119650778105589295791867\
|
||||
1475292565364259184412178423449205725529426910040657788006767324\
|
||||
30364396401389692767134073782286711534915435462112848419717968
|
||||
|
||||
/* Glaisher-Kinkelin Constant */
|
||||
#define Z_GLAISHER_KINKELIN_CONSTANT 1.\
|
||||
2824271291006226368753425688697917277676889273250011920637400217\
|
||||
4040630885882646112973649195820237439420646120399000748933157791\
|
||||
3627752804041590725738617275221433432714343978733506791525736685\
|
||||
6907876561146686449997784962754518174312394652761282138081802192\
|
||||
6451685154614391990108357373070350490388812341881367497813305093\
|
||||
7708336822224941158748373480643999788300701255670012869941577054\
|
||||
3205392758540581731588155481762970384743250467775147374600031616\
|
||||
0230466132963429915580958792933634388728870198895346072523318470\
|
||||
2489001091776941712153569193674967261270398013526526688689782188\
|
||||
9740172937584075016747211489528881599666874316451389030696264559\
|
||||
8704695437402530996068008424474175540614901894441393861960891296\
|
||||
8217352879862988434220366989900606980888785849587494085307347117\
|
||||
0901326675675033105234052210541417677615630819191999718523704776\
|
||||
1312315374135304725819814797451761027540834943143849652341394533\
|
||||
7306583232567395495760169225642773692635882169215987077585827469\
|
||||
575162841550648585890834128227556209758
|
||||
|
||||
/* Golomb–Dickman Constant */
|
||||
#define Z_GOLOMB_DICKMAN_CONSTANT 0.\
|
||||
6243299885435508709929363831008372441796426201805292869735519024\
|
||||
9563808885511325446246027619553986886914041039406274314156555911\
|
||||
8325420596284465847978987572474465109280189639441135184902499148\
|
||||
4947232561121165840654419399681097868927028519012517369465
|
||||
|
||||
/* Khinchin-Lévy Constant */
|
||||
#define Z_KHINCHIN_LEVY_CONSTANT 1.\
|
||||
1865691104156254528217229759472371205683565364720543359542542986\
|
||||
5280963205625444330034830110848687594663926374717514798866899462\
|
||||
8858792892048589683500305263953652862648543238996756950630481767\
|
||||
7137897971160075137260514827163656857323386723372834729020622716\
|
||||
7397717492785936707669402534024864255657756897536580928012999629\
|
||||
8097683768221776246950334807687137738646291848495287534547268657\
|
||||
5981454718758041876163312814165488785235808196886092272054841330\
|
||||
0497613271141838825016107202035985960092613178946519602806110533\
|
||||
1471179799737169111649605099218023355663781315651819442304413647\
|
||||
1107321421137880088845327720664931005413077138234468810688679034\
|
||||
4040265903168814806991853006483510887007401837153184162772458809\
|
||||
9463237501503333492577302701015075319588656808653915811854702488\
|
||||
5109994793687122151974779482404010825711270498595566342029575930\
|
||||
5048539691167157693662265797795733855688822243559909166408814653\
|
||||
6378563759581862456361968781886906440464238011566830343822036684\
|
||||
767237417945240901293641495989710341133651272953540904463262571
|
||||
|
||||
/* Lehmer's Constant */
|
||||
#define Z_LEHMER_CONSTANT 0.\
|
||||
5926327182016361971040786049957014690842754071971610710995626081\
|
||||
5824735236416000851066478429710125705118718346542386963492602972\
|
||||
0676068278560798719794374872514034030005836924869155386406146603\
|
||||
4856682341215484563644664283093780498006899118318496569617201211\
|
||||
3759470623436986514577152028677342172295805168234444776889445080\
|
||||
5416320615585123236230643791702235207816036696392763427125248854\
|
||||
5674262839723419486114155544111865660734792387798043466342553169\
|
||||
2753922997364863485871218333767125332765552976528666126066185788\
|
||||
7136229494030890319843139079584054789895099470074892500536563296\
|
||||
9001766440856359838520947830182186895213784898496770578735653738\
|
||||
5497593520672298603936207528576177510978795686629351912784453933\
|
||||
5684548746146679936886718357439373791659084376165704157947507762\
|
||||
0030956011574042760302493993921496419367417172065429695390317552\
|
||||
6951535843439567271915190168880981717597249067581873559990538542\
|
||||
6905758956901623071748479727018609084969996895767596082849838196\
|
||||
9270404195036511309800972643309599823665
|
||||
|
||||
/* Lemniscate Constant */
|
||||
#define Z_LEMNISCATE_CONSTANT 2.\
|
||||
6220575542921198104648395898911194136827549514316231628168217038\
|
||||
0079058707041425023029553296142909344613575267178321805560895690\
|
||||
1393935694701119434775235840422641497164906951936899979932146072\
|
||||
3831213908102062218974296008565545397723053695497102888883255264\
|
||||
8702132901209754083312856851172975222921429669243051396845645553\
|
||||
9432881415381331735108409226312132476667633414509988603429421479\
|
||||
2247144879639078725641895218110272525166299643333846606793336350\
|
||||
9313980852623773940914262648984803480457254147704617542125634212\
|
||||
9955863129980224054609012091499139897885645312480971101149665075\
|
||||
0605420938417238869000402747853896254830305803039463247832195583\
|
||||
2552297303719134191898359219991422953667256910686113093813498072\
|
||||
5552913015093730332611087045814240765781886530766932476940761626\
|
||||
7216362495494800667609613881223224769255910187057757436146489128\
|
||||
7983268666203073137331356210761263637924578580178136410536130609\
|
||||
3563472025022592312041202668270457723044608378953311357002940577\
|
||||
442011806826257962983642671092116198595
|
||||
|
||||
/* Lévy's Constant */
|
||||
#define Z_LEVY_CONSTANT 3.\
|
||||
2758229187218111597876818824538438636084755259823741494051989241\
|
||||
9072321564496035518127754047917452949269852624340163332818980851\
|
||||
1503417099708230466465646703708071290224186139594237720129817924\
|
||||
2510876976149300288068249261705940412908086970544412349223798884\
|
||||
4270897269164098355358548048374785828762526918445007643383703876\
|
||||
7418844594203517000037321222306241936013409165748043544702217325\
|
||||
9938222983822632339151552857798612046849447252148722901480936120\
|
||||
8904543420920995199781624005150390513815387714754291393073946178\
|
||||
0455278382777274148472215134988266729112154482704520186334876500\
|
||||
1974618041826296536528801168151105751350871152301630294274883364\
|
||||
6260993628966063363776317216508834801936111756326698411146757164\
|
||||
6737885366090624367033259688737535781426541959925075527820545637\
|
||||
1594070177616321153570559233923794384292709017743923016374406041\
|
||||
2678496160747830990299680560833690479092323361110349271473790052\
|
||||
5389549165714734199722931676646307641198327646538816962046346297\
|
||||
332994286181358520050377154266892424005731518557308952871781294
|
||||
|
||||
/* Magata's Constant */
|
||||
#define Z_MAGATA_CONSTANT 3.\
|
||||
4070691656272561422194582628271806535540344380150321161910338275\
|
||||
729699387
|
||||
|
||||
/* Mills' Constant */
|
||||
#define Z_MILLS_CONSTANT 1.\
|
||||
3063778838630806904686144926026057129167845851567136443680537599\
|
||||
66434
|
||||
|
||||
/* Alfréd Rényi's Parking Constant */
|
||||
#define Z_PARKING_CONSTANT 0.\
|
||||
7475979202534114351787309438301781730247862640742283766042291634\
|
||||
2516788160295440431243085036931411115
|
||||
|
||||
/* Porter's Constant */
|
||||
#define Z_PORTER_CONSTANT 1.\
|
||||
4670780794339754728977984847072299534499033224148877773996858176\
|
||||
1660674432904480843036932751117401521266484679045379512110834380\
|
||||
0963912989965561898768045389373100175492129255790244549548891509\
|
||||
825064836565770339644748288818978123102459699275573160698353198
|
||||
|
||||
/* Wilbraham-Gibbs Constant */
|
||||
#define Z_WILBRAHAM_GIBBS_CONSTANT 1.\
|
||||
8519370519824661703610533701579913633458097289811549098047837818\
|
||||
7698189016634835853271033650295475770168436164800715700937245079\
|
||||
9901963934227232241416503636507478802775776040700542538704594703\
|
||||
7548070012549126196000327078575312602462781280151598692712625156\
|
||||
6580378191706570498191117142153830172868690950027668919698378356\
|
||||
4878693375929431917536185883987328136153711174160053365028598892\
|
||||
8906414670095488877382247112955736673406636533206353917604135172\
|
||||
0391124030289113514513183861349292577441824075264760309052792077\
|
||||
8214856022187181490425447150146363584277794711774661377560583998\
|
||||
0813601589774035700341407559120370214113987005974964457642432794\
|
||||
5717202979146195145875005521298368008394022754407873371890776002\
|
||||
3337859174819734615441535401375520206534953637077479723223530762\
|
||||
7711101354680926841172462714308267187960091741576168508046447756\
|
||||
2945596278463818094505702063151083460862967611583842446423313950\
|
||||
2651856882443995288504068180671418260092625808323715322324469000\
|
||||
4091924289785349238396416174935955727240494968269552946845809079
|
||||
|
||||
/* MARK: - Irrational numbers (square roots) */
|
||||
|
||||
#define Z_SQUARE_ROOT_2 /* Pythagoras's Constant */ 1.\
|
||||
4142135623730950488016887242096980785696718753769480731766797379\
|
||||
9073247846210703885038753432764157273501384623091229702492483605\
|
||||
5850737212644121497099935831413222665927505592755799950501152782\
|
||||
0605714701095599716059702745345968620147285174186408891986095523\
|
||||
2923048430871432145083976260362799525140798968725339654633180882\
|
||||
9640620615258352395054745750287759961729835575220337531857011354\
|
||||
3746034084988471603868999706990048150305440277903164542478230684\
|
||||
9293691862158057846311159666871301301561856898723723528850926486\
|
||||
1249497715421833420428568606014682472077143585487415565706967765\
|
||||
3720226485447015858801620758474922657226002085584466521458398893\
|
||||
9443709265918003113882464681570826301005948587040031864803421948\
|
||||
9727829064104507263688131373985525611732204024509122770022694112\
|
||||
7573627280495738108967504018369868368450725799364729060762996941\
|
||||
3804756548237289971803268024744206292691248590521810044598421505\
|
||||
9112024944134172853147810580360337107730918286931471017111168391\
|
||||
6581726889419758716582152128229518488472089694633862891562882765
|
||||
|
||||
#define Z_SQUARE_ROOT_3 /* Theodorus' Constant */ 1.\
|
||||
7320508075688772935274463415058723669428052538103806280558069794\
|
||||
5193301690880003708114618675724857567562614141540670302996994509\
|
||||
4998952478811655512094373648528093231902305582067974820101084674\
|
||||
9232650153123432669033228866506722546689218379712270471316603678\
|
||||
6158801904998653737985938946765034750657605075661834812960610094\
|
||||
7602187190325083145829523959832997789824508288714463832917347224\
|
||||
1639845878553976679580638183536661108431737808943783161020883055\
|
||||
2490167002352071114428869599095636579708716849807289949329648428\
|
||||
3020786408603988738697537582317317831395992983007838702877053913\
|
||||
3695633121037072640192491067682311992883756411414220167427521023\
|
||||
7299427083105989845947598766428889779614783795839022885485290357\
|
||||
6033852808064381972344661059689722872865264153822664698420021195\
|
||||
4841552784411812865345070351916500166892944154808460712771439997\
|
||||
6292683462957743836189511012714863874697654598245178855097537901\
|
||||
3880664961911962222957110555242923723192197738262561631468842032\
|
||||
8537166829386496119170497388363954959381457576718533736331259108
|
||||
|
||||
#define Z_SQUARE_ROOT_5 2.\
|
||||
2360679774997896964091736687312762354406183596115257242708972454\
|
||||
1052092563780489941441440837878227496950817615077378350425326772\
|
||||
4447073863586360121533452708866778173191879165811276645322639856\
|
||||
5805357613504175337850034233924140644420864325390972525926272288\
|
||||
7629951740244068161177590890949849237139072972889848208864154268\
|
||||
9894099131693577019748678884425089754132956183176921499977424801\
|
||||
5304341150359576683325124988151781394080005624208552435422355561\
|
||||
0630634282023409333198293395974635227120134174961420263590473788\
|
||||
5504389687061135660045757139956595566956917564578221952500060539\
|
||||
2312340050092867648755297220567662536660744858535052623306784946\
|
||||
3342224231763727702663240768010444331582573350589309813622634319\
|
||||
8686471946989970180818952426445962034522141192232912598196325811\
|
||||
1041704958070481204034559949435068555518555725123886416550102624\
|
||||
3631257102444961878942468290340447471611545572320173767659046091\
|
||||
8529575603577984398054155380779064393639723028756062999482213852\
|
||||
1773485924535151210463455550407072278724215347787529112121211843
|
||||
|
||||
#define Z_SQUARE_ROOT_6 2.\
|
||||
4494897427831780981972840747058913919659474806566701284326925672\
|
||||
5096037745731502653985943310464023481859460122661418912485886545\
|
||||
9837757341625783951237278552828912747527676571247630105270911770\
|
||||
2234813106789866908536324433525456040338088089393745855678465747\
|
||||
2436130414427027021617420183830008158980783801308970072869399363\
|
||||
0837158094400800443738687549164514653939145012044726448133316293\
|
||||
5109447418135132854950444661717266314254976483181245040115660453\
|
||||
6459009343586167931983665666266909131906535863766105258156179366\
|
||||
2361791102946720883545755128835529898324100558690205006415466124\
|
||||
1173533994104310579928984673395325527873604182965517183039103678\
|
||||
0038362316629732330282904977391047426360070512637697546888677006\
|
||||
4099295592571732846450288809151442574630260295296323707552503422\
|
||||
7559915454262812980030646720799424253022878426205340679478600465\
|
||||
9693997993559754061671358654653456248208256276886369280941306372\
|
||||
4335088648015724846337232447379545488144384793363700919741014778\
|
||||
5232875591063159846078310367009535324726423167141887586237415065
|
||||
|
||||
#define Z_SQUARE_ROOT_7 2.\
|
||||
6457513110645905905016157536392604257102591830824501803683344592\
|
||||
0106882323028362776039288647454361061506457833849746309574352988\
|
||||
8627214784427390555880107722717150729728323892299689594865087260\
|
||||
7009780542037238280237159411003419391160015785255963059457410351\
|
||||
5239680271640737379907404158151990440347431945367139973059700505\
|
||||
1399692237545616097119027378154991633288287704000657570674651963\
|
||||
4977520837938181146130908764737865956243305799479812816323070548\
|
||||
3650107715617946361191553454536477494820593090494849834033989002\
|
||||
1047861667332795036939246225717053716492578754832290732492671346\
|
||||
9802989499080377482511092278955688979198088148340908316852513353\
|
||||
5829539172211770714414974576907081989444441458972284741400303502\
|
||||
3532037194870738262931851936409083228059646278376102195979419708\
|
||||
9096354695861341181793067816213608491016778353212556334634900218\
|
||||
9814604225592950366956241869273732771502208752309966469813203212\
|
||||
8189454785680209506359624466285500761905041393504474371234885223\
|
||||
3277362510045059621080672334698120004300514490251206257311759115
|
||||
|
||||
#define Z_SQUARE_ROOT_8 2.\
|
||||
8284271247461900976033774484193961571393437507538961463533594759\
|
||||
8146495692421407770077506865528314547002769246182459404984967211\
|
||||
1701474425288242994199871662826445331855011185511599901002305564\
|
||||
1211429402191199432119405490691937240294570348372817783972191046\
|
||||
5846096861742864290167952520725599050281597937450679309266361765\
|
||||
9281241230516704790109491500575519923459671150440675063714022708\
|
||||
7492068169976943207737999413980096300610880555806329084956461369\
|
||||
8587383724316115692622319333742602603123713797447447057701852972\
|
||||
2498995430843666840857137212029364944154287170974831131413935530\
|
||||
7440452970894031717603241516949845314452004171168933042916797787\
|
||||
8887418531836006227764929363141652602011897174080063729606843897\
|
||||
9455658128209014527376262747971051223464408049018245540045388225\
|
||||
5147254560991476217935008036739736736901451598729458121525993882\
|
||||
7609513096474579943606536049488412585382497181043620089196843011\
|
||||
8224049888268345706295621160720674215461836573862942034222336783\
|
||||
3163453778839517433164304256459036976944179389267725783125765531
|
||||
|
||||
#define Z_SQUARE_ROOT_10 3.\
|
||||
1622776601683793319988935444327185337195551393252168268575048527\
|
||||
9259443863923822134424810837930029518734728415284005514854885603\
|
||||
0453880014690519596700153903344921657179259940659150153474113339\
|
||||
4841240853169295770904715764610443692578790620378086099418283717\
|
||||
1154840632855299911859682456420332696160469131433612894979189026\
|
||||
6529543612676178781350061388186278580463683134952478031143769334\
|
||||
6719738195131856784032312417954022183080458728446146002535775797\
|
||||
0282864402902440797789603454398916334922265261206779265167603104\
|
||||
8436697793756926155720500369894909469421850007358348844643882731\
|
||||
1092891090423480542356534039072740197865437259396417260013069900\
|
||||
0095578446310962679069441833613018130289454170331580773162638639\
|
||||
5193793704654765220632063686587197822049312426053454111609356979\
|
||||
8281324522970007988835237595853285792513629646865114976752171234\
|
||||
5955923803937562512536985519495532509994703884399033646616547064\
|
||||
7234999796132343403021857052187836676345789510732982875157945215\
|
||||
7716521396263244383990184845609357626020316768042407958946934247
|
||||
|
||||
#define Z_SQUARE_ROOT_11 3.\
|
||||
3166247903553998491149327366706866839270885455893535970586821461\
|
||||
1648464260904384670884339912829065090701255784952745659227543978\
|
||||
4857547479779324933044728847302873974828655682577394444612098044\
|
||||
4771931123571441329715210988326604957100372485207381068208074875\
|
||||
8396589499452515931529840068271971051828955724842455676637002050\
|
||||
8129842236770597842039737427437130311226448688072317190977752062\
|
||||
9616099310799036448345876084690325051455517093627372268267160321\
|
||||
0207901919996927385750204334035187564780307139686203097819560584\
|
||||
3725362410405466369580534808247443172811968386717118059036597033\
|
||||
7448997202863169540371541080201902845827165665889629545544234863\
|
||||
9548140847137804628618335608388738384826935918833704592147012515\
|
||||
8427710904925025882797138714982167119273365512547126431962404617\
|
||||
2648548926892536495944124838553075458386858642464148905256510508\
|
||||
2976405813698950347726301882000479106251003209582933018375612614\
|
||||
1859454774457145379132752736187749409863990889436652633890856923\
|
||||
9596152811690656996164370695457708259448190021400820246857635105
|
||||
|
||||
#define Z_SQUARE_ROOT_12 3.\
|
||||
4641016151377545870548926830117447338856105076207612561116139589\
|
||||
0386603381760007416229237351449715135125228283081340605993989018\
|
||||
9997904957623311024188747297056186463804611164135949640202169349\
|
||||
8465300306246865338066457733013445093378436759424540942633207357\
|
||||
2317603809997307475971877893530069501315210151323669625921220189\
|
||||
5204374380650166291659047919665995579649016577428927665834694448\
|
||||
3279691757107953359161276367073322216863475617887566322041766110\
|
||||
4980334004704142228857739198191273159417433699614579898659296856\
|
||||
6041572817207977477395075164634635662791985966015677405754107826\
|
||||
7391266242074145280384982135364623985767512822828440334855042047\
|
||||
4598854166211979691895197532857779559229567591678045770970580715\
|
||||
2067705616128763944689322119379445745730528307645329396840042390\
|
||||
9683105568823625730690140703833000333785888309616921425542879995\
|
||||
2585366925915487672379022025429727749395309196490357710195075802\
|
||||
7761329923823924445914221110485847446384395476525123262937684065\
|
||||
7074333658772992238340994776727909918762915153437067472662518217
|
||||
|
||||
#define Z_SQUARE_ROOT_13 3.\
|
||||
6055512754639892931192212674704959462512965738452462127104530562\
|
||||
2716694829301044520461908201849071767351418202406354037603067826\
|
||||
4697807705163017166892709757742690564274152633233830394962346944\
|
||||
7962732299962880032688564272130721127331690722052975017855588384\
|
||||
4481465386892107539539248256331024468283663873252869681018926331\
|
||||
3049835539921621174410861805701512768903102881214399483179868380\
|
||||
9191329034353620627951223336511358206979573836238526577606890679\
|
||||
2609603184500630561512640198380725552254880439995068063909609144\
|
||||
6317976289163564544719685392169068915669891846759739035394769849\
|
||||
9962247909644289010644441276675481640212983715961814894472819793\
|
||||
8173214447846457811396497056952460736874807030279572211614048803\
|
||||
2881716595571961517619126745071133538732853360545103521380556650\
|
||||
2555494587073292081260347734391582994367395751429587741287176131\
|
||||
4898328491367481982288670670500887357298564518320813595755837452\
|
||||
8748997770498225074491739486122149917346314129778530567936583385\
|
||||
9084923735540651072975297023582252157988378502698942824546906255
|
||||
|
||||
#define Z_SQUARE_ROOT_14 3.\
|
||||
7416573867739413855837487323165493017560198077787269463037454673\
|
||||
2003515630693902797680989519437957150099108872775197754550656536\
|
||||
8164242592660042052551835117407401124474858631911100015230402627\
|
||||
9990638550213390300377330889721284945398105001694377593170299544\
|
||||
7319506049992643849467871984350198478834312631025757959589728144\
|
||||
9423640188510302034929081127343124602795306338103482722099939933\
|
||||
1632325073523166184196678410645529042707896011422412228117857535\
|
||||
3666229821592216114192712401401062892124966991333243644395454349\
|
||||
5761495087928623919979989096898963145846865535325529594557326107\
|
||||
0496315592433061044542370501975004465989191778372841899586982015\
|
||||
8709794801887759510441696284709199101022413286189989722195565414\
|
||||
2721715251914875629353000674583453673567421640048791525684582413\
|
||||
4590381859339872060995709667653664064804204506068932544077875384\
|
||||
0945992448071804734066289369704503299185073788343176149673387719\
|
||||
4520482494319253841618179781624882985315814656755067051262017785\
|
||||
5028030354711313419236714908509541918604246710579888794708646720
|
||||
|
||||
#define Z_SQUARE_ROOT_15 3.\
|
||||
8729833462074168851792653997823996108329217052915908265875737661\
|
||||
1348309193697903351928737685867351791630220686094964701318954043\
|
||||
9163649615679891746121203511068754791013493581283919531228889292\
|
||||
5658464170280625091931734126598648184554646285513159402626176726\
|
||||
4050864630045057781063197288093978192518830035530153001074835443\
|
||||
8098719014432460775585023104811717090606284157397581582901013330\
|
||||
3274447305580667026371791243800477125912479424727638166001355365\
|
||||
2722953567945703078465466105357724026016703376374906204296078718\
|
||||
7206146764349685215198853426648827511094432134918227578894674852\
|
||||
0940721921133583223212180500077532431298433832388736330198673631\
|
||||
2508581503502850494110642412413006178631087545427595823501050197\
|
||||
6880877132399945421214298433563187193571267457433965110883897630\
|
||||
1514122678489583087574339802329960288316221061594612915860282464\
|
||||
6477150647269610878726287509531568836209909087170850054933375711\
|
||||
4169765329150875277299737911463436952970866868642440087090506787\
|
||||
5857643721298543747329634589332214829062724155722750086355049105
|
||||
|
||||
#define Z_SQUARE_ROOT_17 4.\
|
||||
1231056256176605498214098559740770251471992253736204343986335730\
|
||||
9495434633762159358786365081068429668454404093921414161530142084\
|
||||
0415868363079548145746906977677023266436240863087790567572385708\
|
||||
2255213807325630838603091427498046719135293221479787181678157964\
|
||||
7590608056549697390076672138368921210670892102900552026497699722\
|
||||
7788461399259924591373145657819254743622377232515783073400662476\
|
||||
8914608949933141024362794433862805526374750609050808692574826754\
|
||||
0375757692746463166635103309681712291987419586443197105470595848\
|
||||
5725931943603620656058152613585046428067872150064104914222367522\
|
||||
2434867372580470377712749985665712185704321003036026065064871546\
|
||||
9069828154684645956450344184993059763950907861995904333420778303\
|
||||
6732466105002383305603648597891517738125149725101393295630516977\
|
||||
3961561344837040214695495172837747751283320867754324793019645038\
|
||||
5894596773652195702235648129282323237309165004475570946016572174\
|
||||
9143175547451122718361635317492475624065195560022755934398822460\
|
||||
4515186239457694121228445234277642559126704332598083584929486998
|
||||
|
||||
#define Z_SQUARE_ROOT_18 4.\
|
||||
2426406871192851464050661726290942357090156261308442195300392139\
|
||||
7219743538632111655116260298292471820504153869273689107477450816\
|
||||
7552211637932364491299807494239667997782516778267399851503458346\
|
||||
1817144103286799148179108236037905860441855522559226675958286569\
|
||||
8769145292614296435251928781088398575422396906176018963899542648\
|
||||
8921861845775057185164237250863279885189506725661012595571034063\
|
||||
1238102254965414811606999120970144450916320833709493627434692054\
|
||||
7881075586474173538933479000613903904685570696171170586552779458\
|
||||
3748493146265500261285705818044047416231430756462246697120903296\
|
||||
1160679456341047576404862275424767971678006256753399564375196681\
|
||||
8331127797754009341647394044712478903017845761120095594410265846\
|
||||
9183487192313521791064394121956576835196612073527368310068082338\
|
||||
2720881841487214326902512055109605105352177398094187182288990824\
|
||||
1414269644711869915409804074232618878073745771565430133795264517\
|
||||
7336074832402518559443431741081011323192754860794413051333505174\
|
||||
9745180668259276149746456384688555465416269083901588674688648297
|
||||
|
||||
#define Z_SQUARE_ROOT_19 4.\
|
||||
3588989435406735522369819838596156591370039252324449368903441381\
|
||||
5955732820315808565615915585194452690565862129827421362958399278\
|
||||
3826117012156560836417469900977752918879405890061996715663120740\
|
||||
2231024023243567359810484091999315007271878765601001355045664223\
|
||||
6597215798755072654740213348140339529383325316877083080148213289\
|
||||
2551238612636799418213993270206440885128549665158595212562962839\
|
||||
7050658074438389410005683926884800608708853847459490888521365568\
|
||||
2897687595213123671741821514292631858005215674427058607461711815\
|
||||
5313027391249683899068318958451783502733357016401652084179746424\
|
||||
9119887199195969203059693282567695404609647987775117895043783641\
|
||||
5092493623204442923896243349974708299840429604797134370576918442\
|
||||
5627972643810658724900993631178508595844998222091790883188614272\
|
||||
7181833978529354535768671044286487630521371921331655648231766597\
|
||||
9345008389213635130240253829821964016254338391921650785627655996\
|
||||
5090650060052816150475689600376677031529536405227933016338897672\
|
||||
3371709651582983076636407988920374740815704060472903563584299215
|
||||
|
||||
#define Z_SQUARE_ROOT_20 0.4\
|
||||
4721359549995793928183473374625524708812367192230514485417944908\
|
||||
2104185127560979882882881675756454993901635230154756700850653544\
|
||||
8894147727172720243066905417733556346383758331622553290645279713\
|
||||
1610715227008350675700068467848281288841728650781945051852544577\
|
||||
5259903480488136322355181781899698474278145945779696417728308537\
|
||||
9788198263387154039497357768850179508265912366353842999954849603\
|
||||
0608682300719153366650249976303562788160011248417104870844711122\
|
||||
1261268564046818666396586791949270454240268349922840527180947577\
|
||||
1008779374122271320091514279913191133913835129156443905000121078\
|
||||
4624680100185735297510594441135325073321489717070105246613569892\
|
||||
6684448463527455405326481536020888663165146701178619627245268639\
|
||||
7372943893979940361637904852891924069044282384465825196392651622\
|
||||
2083409916140962408069119898870137111037111450247772833100205248\
|
||||
7262514204889923757884936580680894943223091144640347535318092183\
|
||||
7059151207155968796108310761558128787279446057512125998964427704\
|
||||
3546971849070302420926911100814144557448430695575058224242423686
|
||||
|
||||
#define Z_SQUARE_ROOT_21 4.\
|
||||
5825756949558400065880471937280084889844565767679719026072421239\
|
||||
0686842554777088660436155949344503267760090539758574087331189917\
|
||||
0755601963573863362344755370281722824427798191940596904914344920\
|
||||
0907589407063891768364965598654748231477641506627774586518102302\
|
||||
3617481540081394241092573936592199391754224118467149808042185260\
|
||||
7864914105576957812554767761302518635256936196112241897810062910\
|
||||
4930136394500794769783448686170875778719949754100133598746930349\
|
||||
7232710675634826547407841963209655321589895494373754264061908665\
|
||||
0298094580890976956617810617911595220000768142485134230665143669\
|
||||
5554446605650313382719148849087683899267628798139136482473790088\
|
||||
8189170796483375176737417000297190682904936268171676523400834394\
|
||||
2339309104876265524351270370284614919106272664101521171992383656\
|
||||
8917367993395211009062164895819102794521088994407788913640625972\
|
||||
4578658417328751486109851757581404328234441664632974490001787377\
|
||||
2961869702397214029105976389008894920760202937832728984606379406\
|
||||
5965444919348178013459962365934780900907742704128997390722047147
|
||||
|
||||
#define Z_SQUARE_ROOT_22 4.\
|
||||
6904157598234295545656301135444662805882283534117371536057018910\
|
||||
1702463275323972148211559606154313535459589666150860748165195244\
|
||||
0782925621666958709181664447500641262161250754928188331862529999\
|
||||
9547606735605004577761471186401246176232605036362090494527493856\
|
||||
8281756795270303532693227571317120606062561691541530323494743550\
|
||||
5309200200713172534601558297417528194918298027430089141037481791\
|
||||
4120990984295018191164831945523178805176328354177778500806080498\
|
||||
3518565354318050021673153166262609016615771045384513239925669691\
|
||||
2783671255846108434988804201553172568680512142690822589008911929\
|
||||
7301919366967756643487865411179999979426852739982780774547630300\
|
||||
0579761472344263648399737905839299334981849660115492759940947126\
|
||||
7706320024001816123943437823342252060261602573061333660063214842\
|
||||
6550799462989785932504639612108923454456269629026365378382391889\
|
||||
5594959128764376806042909687553399184617386068557664784079261917\
|
||||
5504341699503617915696514044517092560612721096824920432766881292\
|
||||
5020851744085369494907976490160054424569362473428698311315235875
|
||||
|
||||
#define Z_SQUARE_ROOT_23 4.\
|
||||
7958315233127195415974380641626939199967070419041293464853091144\
|
||||
4825723590746408249219144643691886061747456324573686513392890392\
|
||||
1230265488845783794334079664727569671653494343978434561416798721\
|
||||
3151199128895631880449641132459392571845949603945392600435614646\
|
||||
0202152486503532934363086274731937668011877025054737708513330390\
|
||||
3772090443266178015016833535830415070486401794767454104791880465\
|
||||
7855465617661756852445057646538971125395858740433006194113747360\
|
||||
9109976350633040762876386724156939220008934770208711136596906907\
|
||||
1990861472258832971773823771307619381379694156308798460488452356\
|
||||
9769990440305484325289322905572397161711567767993108038428496669\
|
||||
0265902454607543365705389368190995394922917929701618373910486985\
|
||||
6969068133822070893274626509746898482482517803749584860075661414\
|
||||
0813637335815377083815895114543027468556805151334525399288480358\
|
||||
2656451880775953716880018678299314916241332339317904053586692241\
|
||||
7622541983641096572858498556893157253685192802209028187428956944\
|
||||
4281562508597976297795059510410340787752350836307895023173926977
|
||||
|
||||
#define Z_SQUARE_ROOT_24 4.\
|
||||
8989794855663561963945681494117827839318949613133402568653851345\
|
||||
0192075491463005307971886620928046963718920245322837824971773091\
|
||||
9675514683251567902474557105657825495055353142495260210541823540\
|
||||
4469626213579733817072648867050912080676176178787491711356931494\
|
||||
4872260828854054043234840367660016317961567602617940145738798726\
|
||||
1674316188801600887477375098329029307878290024089452896266632587\
|
||||
0218894836270265709900889323434532628509952966362490080231320907\
|
||||
2918018687172335863967331332533818263813071727532210516312358732\
|
||||
4723582205893441767091510257671059796648201117380410012830932248\
|
||||
2347067988208621159857969346790651055747208365931034366078207356\
|
||||
0076724633259464660565809954782094852720141025275395093777354012\
|
||||
8198591185143465692900577618302885149260520590592647415105006845\
|
||||
5119830908525625960061293441598848506045756852410681358957200931\
|
||||
9387995987119508123342717309306912496416512553772738561882612744\
|
||||
8670177296031449692674464894759090976288769586727401839482029557\
|
||||
0465751182126319692156620734019070649452846334283775172474830130
|
||||
|
||||
#define Z_SQUARE_ROOT_26 5.\
|
||||
0990195135927848300282241090227819895637709460995964075849708044\
|
||||
2593363206222419558834885109393200836119025824103991066143177934\
|
||||
1121536299802772626119936813352008233924081586515180609436925028\
|
||||
7447030884686971127028666876703708002538306916010980296796499813\
|
||||
3725782012085081891373043872791237919529532543918015594903365133\
|
||||
4616416621229877754192034707329287784925030350480663776842369164\
|
||||
2206608812846886072692694659774903784270665608067219846088576469\
|
||||
8177000874159382968970286250298437303308342881274293440653810033\
|
||||
7555839668996596880738823334427411886019717837418375236363862704\
|
||||
9538870426232971817793074424158421655398904669052096083958472252\
|
||||
7934332766274069417122115976356457683023641465745914071502665841\
|
||||
3008179744209425479832568063295040590668891451247346186873076700\
|
||||
8181285605275121624649596800874882281186312691873623153426977207\
|
||||
0381441088553192015422188300606801606467615769284725052746178827\
|
||||
1991760051314186821205851032521784571148355455157794144107701300\
|
||||
0658025436220535414630301094467472349730560558777566650504471075
|
||||
|
||||
#define Z_SQUARE_ROOT_27 5.\
|
||||
1961524227066318805823390245176171008284157614311418841674209383\
|
||||
5579905072640011124343856027174572702687842424622010908990983528\
|
||||
4996857436434966536283120945584279695706916746203924460303254024\
|
||||
7697950459370298007099686599520167640067655139136811413949811035\
|
||||
8476405714995961213957816840295104251972815226985504438881830284\
|
||||
2806561570975249437488571879498993369473524866143391498752041672\
|
||||
4919537635661930038741914550609983325295213426831349483062649165\
|
||||
7470501007056213343286608797286909739126150549421869847988945284\
|
||||
9062359225811966216092612746951953494187978949023516108631161740\
|
||||
1086899363111217920577473203046935978651269234242660502282563071\
|
||||
1898281249317969537842796299286669338844351387517068656455871072\
|
||||
8101558424193145917033983179069168618595792461467994095260063586\
|
||||
4524658353235438596035211055749500500678832464425382138314319992\
|
||||
8878050388873231508568533038144591624092963794735536565292613704\
|
||||
1641994885735886668871331665728771169576593214787684894406526098\
|
||||
5611500488159488357511492165091864878144372730155601208993777326
|
||||
|
||||
#define Z_SQUARE_ROOT_28 5.\
|
||||
2915026221291811810032315072785208514205183661649003607366689184\
|
||||
0213764646056725552078577294908722123012915667699492619148705977\
|
||||
7254429568854781111760215445434301459456647784599379189730174521\
|
||||
4019561084074476560474318822006838782320031570511926118914820703\
|
||||
0479360543281474759814808316303980880694863890734279946119401010\
|
||||
2799384475091232194238054756309983266576575408001315141349303926\
|
||||
9955041675876362292261817529475731912486611598959625632646141096\
|
||||
7300215431235892722383106909072954989641186180989699668067978004\
|
||||
2095723334665590073878492451434107432985157509664581464985342693\
|
||||
9605978998160754965022184557911377958396176296681816633705026707\
|
||||
1659078344423541428829949153814163978888882917944569482800607004\
|
||||
7064074389741476525863703872818166456119292556752204391958839417\
|
||||
8192709391722682363586135632427216982033556706425112669269800437\
|
||||
9629208451185900733912483738547465543004417504619932939626406425\
|
||||
6378909571360419012719248932571001523810082787008948742469770446\
|
||||
6554725020090119242161344669396240008601028980502412514623518230
|
||||
|
||||
#define Z_SQUARE_ROOT_29 5.\
|
||||
3851648071345040312507104915403295562951201616447888376803886700\
|
||||
1664596282765869287663378167983548441870482179394576060768862140\
|
||||
1981555626953216728208924528671722526185214681235990013052448016\
|
||||
2903887045278269438713694073940103168871959102567772596508381141\
|
||||
9495584193980826348969417532613403641636123108887427654955512364\
|
||||
7940365882555182273444125300757917124198604125931023584561198054\
|
||||
4795418813126253107293509901068873371670605812467416799303885413\
|
||||
8123742479087954547432014922688011360464232071011737861539855585\
|
||||
7102081717617603810395080111264836278444280815314492214121131843\
|
||||
6341076396213737228822837938481149242915346920084913077991373969\
|
||||
7089097190833461405997944064288657397292411152297722381325560371\
|
||||
7907312501357326363233051587278665098784329901442053725629656985\
|
||||
9172449839218439790049969327370087099206683073256802774244092317\
|
||||
5715419607139287353485337048180789528095729186886136682895069025\
|
||||
3666940455803261056985599438152074440985243814914009730255209859\
|
||||
5681681929637748409740639130952795240525758914068872104537046989
|
||||
|
||||
#define Z_SQUARE_ROOT_E 1.\
|
||||
64872127070012814684865078781416357165377610071014801157507
|
||||
|
||||
#define Z_SQUARE_ROOT_PI 1.\
|
||||
7724538509055160272981674833411451827975494561223871282138077898\
|
||||
5291128459103218137495065673854466541622682362428257066623615286\
|
||||
5724422602525093709602787068462037698653105122849925173028950826\
|
||||
2289320953792679628001746390153514797205167001901852340185854469\
|
||||
7449491264031392177552590621640541933250090639840761373347747515\
|
||||
3433667989789365851836408795451165161738760059067393431791332809\
|
||||
8548462481849020546548521956132515616474675150427387610561079961\
|
||||
2710721006037204448367236529661370809432349883166842421384570960\
|
||||
9120420427785778068694766570005218305685125413396636944654181510\
|
||||
7166938833219429293570622688652244205421499480499207564863988748\
|
||||
3850593064021821402928581123306497894520362114907896228738940324\
|
||||
5978198513134871266512506293260044656382109675026812496930595420\
|
||||
4615607619522173915250702077927580990543329006622230676144696612\
|
||||
4818874306997883520506146444385418530797357425717918563595974995\
|
||||
9952263849242203889103966406447293972841345043002140564233433039\
|
||||
26175613417633632001703765416347632066927654181283576249032690
|
||||
|
||||
/* MARK: - Irrational numbers (cube roots) */
|
||||
|
||||
#define Z_CUBE_ROOT_2 1.\
|
||||
2599210498948731647672106072782283505702514647015079800819751121\
|
||||
5529967651395948372939656243625509415431025603561566525939902404\
|
||||
0613737228459110304269355246960642616625000977474526565480306867\
|
||||
1854055186892458725167641993737096950983827831613991551293136953\
|
||||
6618394746344857657030311909589598474110598116290705359081647801\
|
||||
1473521325484771297880242208582053257972526662202669005665608199\
|
||||
4715628176405060664826773572670419486207621442965694205079319172\
|
||||
4414809204482328401274703219642820812019057141889964599983175038\
|
||||
0188868959420205592202115472997384880260736369741788779215798467\
|
||||
5099539630078260959624203483238660139857363433909737126527995991\
|
||||
9699683779131681681544288502796515292781076797140020406056748039\
|
||||
3856125171835700690798499634197629147404483454026971547622851317\
|
||||
8020643878047649322579052898467085805286258130005429388560720609\
|
||||
7472230406313572349364584065759169169167270601244028967000010690\
|
||||
8103531385290270041508423233623988938649678219414983802707295717\
|
||||
6812879001445746227147702348357151905506722084818485009287239209
|
||||
|
||||
#define Z_CUBE_ROOT_3 1.\
|
||||
4422495703074083823216383107801095883918692534993505775464161945\
|
||||
4168759682999733985475547970564525668683508085448954996642542394\
|
||||
6110259714868950157185237227090332023847598445061085540027260088\
|
||||
1454988727513673553524678660747156884392233189182017038998238223\
|
||||
3212961663550852626734913350166545489578817585527417559336313187\
|
||||
4146720060463846664756937436419755574942490682081094267123590626\
|
||||
5763689646373616178216558425874823856595235871903196104071395306\
|
||||
0281028535084436380351945501338091522239078498975091939480365311\
|
||||
9674345706233811941118355657692483200123107015915332930042827066\
|
||||
6394443820480019012241818057851180278635499201489352352796818010\
|
||||
9006236835327970373724614565173415353390990467105304156937690305\
|
||||
1494958995216166591166333801954227266482814311818441716553576688\
|
||||
1832140589503272799127928026983572135676304667631409826930968622\
|
||||
4764941404644842887133087994684187000204561876902750330462036656\
|
||||
4440717909119698039747478883802670722844748159482087239611601227\
|
||||
1067171066612781813201108139530097227226661910705939909901191206
|
||||
|
||||
/* MARK: - Irrational numbers (other roots) */
|
||||
|
||||
#define Z_12TH_ROOT_2 1.\
|
||||
0594630943592952645618252949463417007792043174941856285592084314\
|
||||
5876164606325572238376837686394556900774076432638281736624173752\
|
||||
0827851039644723985114271115432990470239714933804165425687642097\
|
||||
6329379895947129709947064800938991173847686705520689400326781575\
|
||||
1383303231319955390959014587484595500681806521772802362810455571\
|
||||
3869553201754802640057179595879584537567829830020977379250053687\
|
||||
4403398881937606323435254399006328830846125529480888721482330441\
|
||||
4074184893108198509249979986687035709497917584337029863023761262\
|
||||
5173981919008919366931298054535197982705358773565786048226460447\
|
||||
3090968624372596272293682528044863570700171131799931049836732088\
|
||||
9886403556920267157664120910549625751449398108864973818515174409\
|
||||
2025177988784831666892332928201939743642078982338822600070557879\
|
||||
0103964696887044937701555993149379866153352257152374614051434715\
|
||||
9095506342399653920121443555462612297570882130516983593531956991\
|
||||
7044
|
||||
|
||||
/* MARK: - Integer numbers */
|
||||
|
||||
#define Z_CARMACK_NUMBER 0x5F3759DF
|
||||
#define Z_LOMONT_NUMBER 0x5F375A86
|
||||
|
||||
#endif /* Z_constants_numbers_H */
|
||||
29
software/FusionX/src/z80drv/Zeta/API/Z/constants/pointer.h
vendored
Normal file
29
software/FusionX/src/z80drv/Zeta/API/Z/constants/pointer.h
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/* Zeta API - Z/constants/pointer.h
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_constants_pointer_H
|
||||
#define Z_constants_pointer_H
|
||||
|
||||
#ifdef Z_NULL /* defined by zlib */
|
||||
# undef Z_NULL
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
# include <Z/inspection/language.h>
|
||||
|
||||
# if Z_DIALECT_HAS_LITERAL(CPP11, NULLPTR)
|
||||
# define Z_NULL nullptr
|
||||
# else
|
||||
# define Z_NULL 0
|
||||
# endif
|
||||
|
||||
#else
|
||||
# define Z_NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#endif /* Z_constants_pointer_H */
|
||||
59
software/FusionX/src/z80drv/Zeta/API/Z/formats/archive/TAR.h
vendored
Normal file
59
software/FusionX/src/z80drv/Zeta/API/Z/formats/archive/TAR.h
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/* Zeta API - Z/formats/archive/TAR.h
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_formats_archive_TAR_H
|
||||
#define Z_formats_archive_TAR_H
|
||||
|
||||
#include <Z/macros/language.h>
|
||||
#include <Z/types/integral.h>
|
||||
|
||||
/* http://www.gnu.org/software/tar/manual/html_node/Standard.html */
|
||||
|
||||
#define Z_TAR_BLOCK_SIZE 512
|
||||
|
||||
Z_DEFINE_PACKED_STRUCTURE ({ /* byte offset */
|
||||
zuint8 name[100]; /* 0 */
|
||||
zuint8 mode[8]; /* 100 */
|
||||
zuint8 uid[8]; /* 108 */
|
||||
zuint8 gid[8]; /* 116 */
|
||||
zuint8 size[12]; /* 124 */
|
||||
zuint8 mtime[12]; /* 136 */
|
||||
zuint8 checksum[8]; /* 148 */
|
||||
zuint8 item_type; /* 156 */
|
||||
zuint8 link_name[100]; /* 157 */
|
||||
zuint8 magic[6]; /* 257 */
|
||||
zuint8 version[2]; /* 263 */
|
||||
zuint8 uname[32]; /* 265 */
|
||||
zuint8 gname[32]; /* 297 */
|
||||
zuint8 device_major[8]; /* 329 */
|
||||
zuint8 device_minor[8]; /* 337 */
|
||||
zuint8 prefix[155]; /* 345 */
|
||||
/* 500 */
|
||||
}, Z_TARPOSIXHeader);
|
||||
|
||||
typedef Z_TARPOSIXHeader Z_TARHeader;
|
||||
|
||||
#define Z_TAR_ITEM_TYPE_OLD_REGULAR_FILE 0
|
||||
#define Z_TAR_ITEM_TYPE_REGULAR_FILE 0x30
|
||||
#define Z_TAR_ITEM_TYPE_LINK 0x31
|
||||
#define Z_TAR_ITEM_TYPE_SYMBOLIC_LINK 0x32
|
||||
#define Z_TAR_ITEM_TYPE_CHARACTER_DEVICE 0x33
|
||||
#define Z_TAR_ITEM_TYPE_BLOCK_DEVICE 0x34
|
||||
#define Z_TAR_ITEM_TYPE_DIRECTORY 0x35
|
||||
#define Z_TAR_ITEM_TYPE_FIFO 0x36
|
||||
#define Z_TAR_ITEM_TYPE_CONTIGUOUS_FILE 0x37
|
||||
|
||||
#define Z_TAR_ITEM_TYPE_GNU_DIRECTORY_DUMP 'D' /* file names from dumped directory */
|
||||
#define Z_TAR_ITEM_TYPE_GNU_LONG_LINK 'K' /* long link name */
|
||||
#define Z_TAR_ITEM_TYPE_GNU_LONG_NAME 'L' /* long file name */
|
||||
#define Z_TAR_ITEM_TYPE_GNU_MULTIVOLUME 'M' /* continuation of file from another volume */
|
||||
#define Z_TAR_ITEM_TYPE_GNU_NAMES 'N' /* file name that does not fit into main hdr */
|
||||
#define Z_TAR_ITEM_TYPE_GNU_SPARSE 'S' /* sparse file */
|
||||
#define Z_TAR_ITEM_TYPE_GNU_VOLUME_HEADER 'V' /* tape/volume header */
|
||||
|
||||
#endif /* Z_formats_archive_TAR_H */
|
||||
14
software/FusionX/src/z80drv/Zeta/API/Z/formats/archive/ZIP.h
vendored
Normal file
14
software/FusionX/src/z80drv/Zeta/API/Z/formats/archive/ZIP.h
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
/* Zeta API - Z/formats/archive/ZIP.h
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_formats_archive_ZIP_H
|
||||
#define Z_formats_archive_ZIP_H
|
||||
|
||||
|
||||
|
||||
#endif /* Z_formats_archive_ZIP_H */
|
||||
141
software/FusionX/src/z80drv/Zeta/API/Z/formats/character set/ASCII.h
vendored
Normal file
141
software/FusionX/src/z80drv/Zeta/API/Z/formats/character set/ASCII.h
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
/* Zeta API - Z/formats/character set/ASCII.h
|
||||
______ ____________ ___
|
||||
|__ /| ___|__ __|/ \
|
||||
/ /_| __| | | / * \
|
||||
/_____|_____| |__|/__/ \__\
|
||||
Copyright (C) 2006-2022 Manuel Sainz de Baranda y Goñi.
|
||||
Released under the terms of the GNU Lesser General Public License v3. */
|
||||
|
||||
#ifndef Z_formats_character_set_ASCII_H
|
||||
#define Z_formats_character_set_ASCII_H
|
||||
|
||||
#define Z_ASCII_NULL 0x00
|
||||
#define Z_ASCII_START_OF_HEADING 0x01
|
||||
#define Z_ASCII_START_OF_TEXT 0x02
|
||||
#define Z_ASCII_END_OF_TEXT 0x03
|
||||
#define Z_ASCII_END_OF_TRANSMISSION 0x04
|
||||
#define Z_ASCII_ENQUIRY 0x05
|
||||
#define Z_ASCII_ACKNOWLEDGE 0x06
|
||||
#define Z_ASCII_BELL 0x07
|
||||
#define Z_ASCII_BACKSPACE 0x08
|
||||
#define Z_ASCII_CHARACTER_TABULATION 0x09
|
||||
#define Z_ASCII_LINE_FEED 0x0A
|
||||
#define Z_ASCII_LINE_TABULATION 0x0B
|
||||
#define Z_ASCII_FORM_FEED 0x0C
|
||||
#define Z_ASCII_CARRIAGE_RETURN 0x0D
|
||||
#define Z_ASCII_SHIFT_OUT 0x0E
|
||||
#define Z_ASCII_SHIFT_IN 0x0F
|
||||
#define Z_ASCII_DATA_LINK_ESCAPE 0x10
|
||||
#define Z_ASCII_DEVICE_CONTROL_ONE 0x11
|
||||
#define Z_ASCII_DEVICE_CONTROL_TWO 0x12
|
||||
#define Z_ASCII_DEVICE_CONTROL_THREE 0x13
|
||||
#define Z_ASCII_DEVICE_CONTROL_FOUR 0x14
|
||||
#define Z_ASCII_NEGATIVE_ACKNOWLEDGE 0x15
|
||||
#define Z_ASCII_SYNCHRONOUS_IDLE 0x16
|
||||
#define Z_ASCII_END_OF_TRANSMISSION_BLOCK 0x17
|
||||
#define Z_ASCII_CANCEL 0x18
|
||||
#define Z_ASCII_END_OF_MEDIUM 0x19
|
||||
#define Z_ASCII_SUBSTITUTE 0x1A
|
||||
#define Z_ASCII_ESCAPE 0x1B
|
||||
#define Z_ASCII_INFO_SEPARATOR_FOUR 0x1C
|
||||
#define Z_ASCII_INFO_SEPARATOR_THREE 0x1D
|
||||
#define Z_ASCII_INFO_SEPARATOR_TWO 0x1E
|
||||
#define Z_ASCII_INFO_SEPARATOR_ONE 0x1F
|
||||
#define Z_ASCII_SPACE 0x20
|
||||
#define Z_ASCII_EXCLAMATION_MARK 0x21
|
||||
#define Z_ASCII_QUOTATION_MARK 0x22
|
||||
#define Z_ASCII_NUMBER_SIGN 0x23
|
||||
#define Z_ASCII_DOLLAR_SIGN 0x24
|
||||
#define Z_ASCII_PERCENT_SIGN 0x25
|
||||
#define Z_ASCII_AMPERSAND 0x26
|
||||
#define Z_ASCII_APOSTROPHE 0x27
|
||||
#define Z_ASCII_LEFT_PARENTHESIS 0x28
|
||||
#define Z_ASCII_RIGHT_PARENTHESIS 0x29
|
||||
#define Z_ASCII_ASTERISK 0x2A
|
||||
#define Z_ASCII_PLUS_SIGN 0x2B
|
||||
#define Z_ASCII_COMMA 0x2C
|
||||
#define Z_ASCII_HYPHEN_MINUS 0x2D
|
||||
#define Z_ASCII_FULL_STOP 0x2E
|
||||
#define Z_ASCII_SOLIDUS 0x2F
|
||||
#define Z_ASCII_DIGIT_ZERO 0x30
|
||||
#define Z_ASCII_DIGIT_ONE 0x31
|
||||
#define Z_ASCII_DIGIT_TWO 0x32
|
||||
#define Z_ASCII_DIGIT_THREE 0x33
|
||||
#define Z_ASCII_DIGIT_FOUR 0x34
|
||||
#define Z_ASCII_DIGIT_FIVE 0x35
|
||||
#define Z_ASCII_DIGIT_SIX 0x36
|
||||
#define Z_ASCII_DIGIT_SEVEN 0x37
|
||||
#define Z_ASCII_DIGIT_EIGHT 0x38
|
||||
#define Z_ASCII_DIGIT_NINE 0x39
|
||||
#define Z_ASCII_COLON 0x3A
|
||||
#define Z_ASCII_SEMICOLON 0x3B
|
||||
#define Z_ASCII_LESS_THAN_SIGN 0x3C
|
||||
#define Z_ASCII_EQUALS_SIGN 0x3D
|
||||
#define Z_ASCII_GREATER_THAN_SIGN 0x3E
|
||||
#define Z_ASCII_QUESTION_MARK 0x3F
|
||||
#define Z_ASCII_COMMERCIAL_AT 0x40
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_A 0x41
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_B 0x42
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_C 0x43
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_D 0x44
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_E 0x45
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_F 0x46
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_G 0x47
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_H 0x48
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_I 0x49
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_J 0x4A
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_K 0x4B
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_L 0x4C
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_M 0x4D
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_N 0x4E
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_O 0x4F
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_P 0x50
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_Q 0x51
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_R 0x52
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_S 0x53
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_T 0x54
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_U 0x55
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_V 0x56
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_W 0x57
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_X 0x58
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_Y 0x59
|
||||
#define Z_ASCII_LATIN_CAPITAL_LETTER_Z 0x5A
|
||||
#define Z_ASCII_LEFT_SQUARE_BRACKET 0x5B
|
||||
#define Z_ASCII_REVERSE_SOLIDUS 0x5C
|
||||
#define Z_ASCII_RIGHT_SQUARE_BRACKET 0x5D
|
||||
#define Z_ASCII_CIRCUMFLEX_ACCENT 0x5E
|
||||
#define Z_ASCII_LOW_LINE 0x5F
|
||||
#define Z_ASCII_GRAVE_ACCENT 0x60
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_A 0x61
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_B 0x62
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_C 0x63
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_D 0x64
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_E 0x65
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_F 0x66
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_G 0x67
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_H 0x68
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_I 0x69
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_J 0x6A
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_K 0x6B
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_L 0x6C
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_M 0x6D
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_N 0x6E
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_O 0x6F
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_P 0x70
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_Q 0x71
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_R 0x72
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_S 0x73
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_T 0x74
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_U 0x75
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_V 0x76
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_W 0x77
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_X 0x78
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_Y 0x79
|
||||
#define Z_ASCII_LATIN_SMALL_LETTER_Z 0x7A
|
||||
#define Z_ASCII_LEFT_CURLY_BRACKET 0x7B
|
||||
#define Z_ASCII_VERTICAL_LINE 0x7C
|
||||
#define Z_ASCII_RIGHT_CURLY_BRACKET 0x7D
|
||||
#define Z_ASCII_TILDE 0x7E
|
||||
#define Z_ASCII_DELETE 0x7F
|
||||
|
||||
#endif /* Z_formats_character_set_ASCII_H */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user