diff --git a/CPLD/SW/tranZPUterSW.vhd b/CPLD/SW/tranZPUterSW.vhd index 0644e7d..1285ad5 100644 --- a/CPLD/SW/tranZPUterSW.vhd +++ b/CPLD/SW/tranZPUterSW.vhd @@ -36,6 +36,9 @@ -- mux lines. -- Mar 2021 - Many changes to cater for the MZ-800. The machine has different memory -- modes and maps so extensive changes needed. +-- Apr 2021 - Removed the v2.1 frequency generator as 2.1 no longer supported. Fixed +-- issues with adding the MZ-800 using too many resources, made +-- compilation conditional. -- --------------------------------------------------------------------------------------------------------- -- This source file is free software: you can redistribute it and-or modify @@ -265,10 +268,14 @@ architecture rtl of cpld512 is signal MB_MREQn : std_logic; signal MB_BUSRQn : std_logic; signal MB_ADDR : std_logic_vector(15 downto 0); - signal MB_DELAY_TICKS : unsigned(11 downto 0); - signal MB_DELAY_MS : unsigned(7 downto 0); signal MB_STATE : integer range 0 to 7; signal MB_WAITn : std_logic; + signal MB_DELAY_MS : unsigned(7 downto 0); + + -- Millisecond timer signals. + signal DELAY_TICKS : unsigned(3 downto 0); + signal DELAY_US : unsigned(9 downto 0); + signal DELAY_MS_CLK : std_logic; function to_std_logic(L: boolean) return std_logic is begin @@ -394,7 +401,7 @@ begin end if; -- On the MZ800 host capture and action the gate array command as it changes the mode. - if CS_GDG_CMD = '0' and Z80_WRn = '0' then + if CPLD_HOST_HW = MODE_MZ800 and CS_GDG_CMD = '0' and Z80_WRn = '0' then -- Mode 700 command? if Z80_DATA(3 downto 0) = "1000" then @@ -423,432 +430,476 @@ begin end if; end process; - -- Memory mode latch. This latch stores the current memory mode (or Bank Paging Scheme) according to the running software. + -- MZ-80A/MZ-700 target hardware, generate the original memory management mode logic. -- - MEMORYMODE: process( Z80_CLKi, Z80_RESETn, SYSRESETn, CS_MEM_CFGn, Z80_IORQn, Z80_WRn, Z80_ADDR, Z80_DATA, CPLD_CFG_DATA, MODE_640x200 ) - variable mz700_LOWER_RAM : std_logic; - variable mz700_UPPER_RAM : std_logic; - variable mz700_INHIBIT : std_logic; - variable MODE_CPLD_LAST : std_logic_vector(2 downto 0); - begin + MEMORYMODE80A: if CPLD_HOST_HW = MODE_MZ80A or CPLD_HOST_HW = MODE_MZ700 generate - if(Z80_RESETn = '0') then --- -- On power up reset, default to original configuration. --- if CPLD_CFG_DATA(7) = '0' then --- -- Default to MZ-700/MZ-80A --- MEM_MODE_LATCH <= std_logic_vector(to_unsigned(TZMM_ORIG, MEM_MODE_LATCH'length)); --- --- -- MZ-800 mode --- --elsif CPLD_HOST_HW = MODE_MZ800 then --- -- MEM_MODE_LATCH <= std_logic_vector(to_unsigned(TZMM_MZ800, MEM_MODE_LATCH'length)); --- end if; - mz700_LOWER_RAM := '0'; - mz700_UPPER_RAM := '0'; - mz700_INHIBIT := '0'; + MEMORYMODE: process( Z80_CLKi, Z80_RESETn, SYSRESETn, CS_MEM_CFGn, Z80_IORQn, Z80_WRn, Z80_ADDR, Z80_DATA, CPLD_CFG_DATA, MODE_640x200 ) + variable mz700_LOWER_RAM : std_logic; + variable mz700_UPPER_RAM : std_logic; + variable mz700_INHIBIT : std_logic; + variable MODE_CPLD_LAST : std_logic_vector(2 downto 0); + begin - -- Setup MZ-800 control on reset to MZ-800 startup memory map. - MAP_0000_0FFF_ROM <= '1'; - MAP_1000_1FFF_CGROM <= '1'; - MAP_2000_2FFF_DRAM <= '1'; - MAP_3000_3FFF_DRAM <= '1'; - MAP_4000_4FFF_DRAM <= '1'; - MAP_5000_5FFF_DRAM <= '1'; - MAP_6000_6FFF_DRAM <= '1'; - MAP_7000_7FFF_DRAM <= '1'; - MAP_A000_AFFF_DRAM <= not MODE_640x200; - MAP_B000_BFFF_DRAM <= not MODE_640x200; - MAP_C000_CFFF_DRAM <= '1'; - MAP_D000_DFFF_DRAM <= '1'; - MAP_8000_8FFF_VRAM <= '1'; - MAP_9000_9FFF_VRAM <= '1'; - MAP_A000_AFFF_VRAM <= MODE_640x200; - MAP_B000_BFFF_VRAM <= MODE_640x200; - MAP_E000_EFFF_ROM <= '1'; - MAP_F000_FFFF_ROM <= '1'; - -- Clear remaining flags. - MAP_0000_0FFF_DRAM <= '0'; - MAP_1000_1FFF_DRAM <= '0'; - MAP_8000_8FFF_DRAM <= '0'; - MAP_9000_9FFF_DRAM <= '0'; - MAP_E000_EFFF_DRAM <= '0'; - MAP_F000_FFFF_DRAM <= '0'; - MAP_C000_CFFF_VRAM <= '0'; - MAP_D000_DFFF_VRAM <= '0'; - MAP_E000_E00F_IO <= '0'; - MAP_INHIBIT <= '0'; + if(Z80_RESETn = '0') then + mz700_LOWER_RAM := '0'; + mz700_UPPER_RAM := '0'; + mz700_INHIBIT := '0'; + MODE_CPLD_LAST := std_logic_vector(to_unsigned(CPLD_HOST_HW, MODE_CPLD_LAST'length)); - MODE_CPLD_LAST := std_logic_vector(to_unsigned(CPLD_HOST_HW, MODE_CPLD_LAST'length)); + -- On power up reset, default to original configuration. + elsif SYSRESETn = '0' and CPLD_CFG_DATA(7) = '0' then + -- Default to MZ-700/MZ-80A + MEM_MODE_LATCH <= std_logic_vector(to_unsigned(TZMM_ORIG, MEM_MODE_LATCH'length)); - -- On power up reset, default to original configuration. - elsif SYSRESETn = '0' and CPLD_CFG_DATA(7) = '0' then - -- Default to MZ-700/MZ-80A - MEM_MODE_LATCH <= std_logic_vector(to_unsigned(TZMM_ORIG, MEM_MODE_LATCH'length)); + -- A direct write to the memory latch stores the required memory mode into the latch. + elsif (CS_MEM_CFGn = '0' and Z80_WRn = '0') then + MEM_MODE_LATCH <= Z80_DATA(4 downto 0); - -- MZ-800 mode - --elsif CPLD_HOST_HW = MODE_MZ800 then - -- MEM_MODE_LATCH <= std_logic_vector(to_unsigned(TZMM_MZ800, MEM_MODE_LATCH'length)); - + elsif(Z80_CLKi'event and Z80_CLKi = '1') then - -- A direct write to the memory latch stores the required memory mode into the latch. - elsif (CS_MEM_CFGn = '0' and Z80_WRn = '0') then - MEM_MODE_LATCH <= Z80_DATA(4 downto 0); + -- Each clock remember the current mode to detect a change. + MODE_CPLD_LAST := CPLD_CFG_DATA(2 downto 0); - elsif(Z80_CLKi'event and Z80_CLKi = '1') then + -- Check for MZ700 Mode memory changes and adjust current memory mode setting. + -- + if(MODE_CPLD_MZ700 = '1' and Z80_IORQn = '0' and Z80_M1n = '1' and Z80_ADDR(7 downto 3) = "11100") then - -- Cater for mode switches made by software between the MZ800 and MZ700 modes. - --. --- if MODE_CPLD_LAST = MODE_MZ700 and MODE_CPLD_MZ800 = '1' then --- MAP_0000_0FFF_ROM <= '1'; --- MAP_1000_1FFF_CGROM <= '1'; --- MAP_2000_2FFF_DRAM <= '1'; --- MAP_3000_3FFF_DRAM <= '1'; --- MAP_4000_4FFF_DRAM <= '1'; --- MAP_5000_5FFF_DRAM <= '1'; --- MAP_6000_6FFF_DRAM <= '1'; --- MAP_7000_7FFF_DRAM <= '1'; --- MAP_A000_AFFF_DRAM <= not MODE_640x200; --- MAP_B000_BFFF_DRAM <= not MODE_640x200; --- MAP_C000_CFFF_DRAM <= '1'; --- MAP_D000_DFFF_DRAM <= '1'; --- MAP_8000_8FFF_VRAM <= '1'; --- MAP_9000_9FFF_VRAM <= '1'; --- MAP_A000_AFFF_VRAM <= MODE_640x200; --- MAP_B000_BFFF_VRAM <= MODE_640x200; --- MAP_E000_EFFF_ROM <= '1'; --- MAP_F000_FFFF_ROM <= '1'; --- -- Clear remaining flags. --- MAP_0000_0FFF_DRAM <= '0'; --- MAP_1000_1FFF_DRAM <= '0'; --- MAP_8000_8FFF_DRAM <= '0'; --- MAP_9000_9FFF_DRAM <= '0'; --- MAP_E000_EFFF_DRAM <= '0'; --- MAP_F000_FFFF_DRAM <= '0'; --- MAP_C000_CFFF_VRAM <= '0'; --- MAP_D000_DFFF_VRAM <= '0'; --- MAP_E000_E00F_IO <= '0'; --- MAP_INHIBIT <= '0'; --- --- elsif MODE_CPLD_LAST = MODE_MZ800 and MODE_CPLD_MZ700 = '1' then --- MAP_0000_0FFF_ROM <= '1'; --- MAP_1000_1FFF_DRAM <= '1'; --- MAP_2000_2FFF_DRAM <= '1'; --- MAP_3000_3FFF_DRAM <= '1'; --- MAP_4000_4FFF_DRAM <= '1'; --- MAP_5000_5FFF_DRAM <= '1'; --- MAP_6000_6FFF_DRAM <= '1'; --- MAP_7000_7FFF_DRAM <= '1'; --- MAP_8000_8FFF_DRAM <= '1'; --- MAP_9000_9FFF_DRAM <= '1'; --- MAP_A000_AFFF_DRAM <= '1'; --- MAP_B000_BFFF_DRAM <= '1'; --- MAP_C000_CFFF_DRAM <= '1'; --- MAP_D000_DFFF_VRAM <= '1'; --- MAP_E000_E00F_IO <= '1'; --- MAP_E000_EFFF_ROM <= '1'; --- MAP_F000_FFFF_ROM <= '1'; --- -- Clear remaining flags. --- MAP_1000_1FFF_CGROM <= '0'; --- MAP_0000_0FFF_DRAM <= '0'; --- MAP_D000_DFFF_DRAM <= '0'; --- MAP_E000_EFFF_DRAM <= '0'; --- MAP_F000_FFFF_DRAM <= '0'; --- MAP_8000_8FFF_VRAM <= '0'; --- MAP_9000_9FFF_VRAM <= '0'; --- MAP_A000_AFFF_VRAM <= '0'; --- MAP_B000_BFFF_VRAM <= '0'; --- MAP_C000_CFFF_VRAM <= '0'; --- MAP_INHIBIT <= '0'; --- --- end if; + -- MZ700 memory mode switch? + -- 0x0000:0x0FFF 0xD000:0xFFFF + -- 0xE0 = DRAM + -- 0xE1 = DRAM + -- 0xE2 = MONITOR + -- 0xE3 = Memory Mapped I/O + -- 0xE4 = MONITOR Memory Mapped I/O + -- 0xE5 = Inhibit + -- 0xE6 = Return to state prior to 0xE5 + case Z80_ADDR(2 downto 0) is + -- 0xE0 + when "000" => + mz700_LOWER_RAM := '1'; - -- Each clock remember the current mode to detect a change. - MODE_CPLD_LAST := CPLD_CFG_DATA(2 downto 0); + -- 0xE1 + when "001" => + mz700_UPPER_RAM := '1'; - -- 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 = | | | | | | | | | | | | - -- IN 0xE0 = | |CGROM* | |VRAM* | | |CGROM | |VRAM | | | - -- IN 0xE1 = | |DRAM | |DRAM | | | | |DRAM | | | - -- - -- = Return to the state prior to the complimentary command being invoked. - -- * = MZ-800 host only. + -- 0xE2 + when "010" => + mz700_LOWER_RAM := '0'; - -- On MZ-800 hardware the MZ-700 mode is not quite the same so I've elected to use seperate decoding. You thus have MZ700/MZ800 modes on MZ800 hardware and MZ700 modes on - -- MZ700/MZ-80A hardware. - -- - if(CPLD_HOST_HW = MODE_MZ800 and (MODE_CPLD_MZ700 = '1' or MODE_CPLD_MZ800 = '1') and Z80_IORQn = '0' and Z80_M1n = '1' and Z80_ADDR(7 downto 3) = "11100") then + -- 0xE3 + when "011" => + mz700_UPPER_RAM := '0'; - case Z80_ADDR(2 downto 0) is - -- 0xE0 - when "000" => - -- To cater for the CGROM being paged into the address space we use an override rather than a seperate memory mode. - if Z80_RDn = '0' then - MAP_1000_1FFF_DRAM <= '0'; - MAP_1000_1FFF_CGROM <= '1'; - if MODE_CPLD_MZ800 = '1' then - MAP_8000_8FFF_VRAM <= '1'; - MAP_9000_9FFF_VRAM <= '1'; - MAP_A000_AFFF_VRAM <= MODE_640x200; - MAP_B000_BFFF_VRAM <= MODE_640x200; - MAP_8000_8FFF_DRAM <= '0'; - MAP_9000_9FFF_DRAM <= '0'; - MAP_A000_AFFF_DRAM <= not MODE_640x200; - MAP_B000_BFFF_DRAM <= not MODE_640x200; - else - MAP_C000_CFFF_VRAM <= '1'; - MAP_C000_CFFF_DRAM <= '0'; - end if; + -- 0xE4 + when "100" => + mz700_LOWER_RAM := '0'; + mz700_UPPER_RAM := '0'; - elsif MODE_CPLD_MZ800 = '1' then - MAP_0000_0FFF_DRAM <= '1'; - MAP_1000_1FFF_DRAM <= '1'; - MAP_2000_2FFF_DRAM <= '1'; - MAP_3000_3FFF_DRAM <= '1'; - MAP_4000_4FFF_DRAM <= '1'; - MAP_5000_5FFF_DRAM <= '1'; - MAP_6000_6FFF_DRAM <= '1'; - MAP_7000_7FFF_DRAM <= '1'; - MAP_0000_0FFF_ROM <= '0'; - MAP_1000_1FFF_CGROM <= '0'; - else - MAP_0000_0FFF_DRAM <= '1'; - MAP_1000_1FFF_DRAM <= '1'; - MAP_2000_2FFF_DRAM <= '1'; - MAP_3000_3FFF_DRAM <= '1'; - MAP_4000_4FFF_DRAM <= '1'; - MAP_5000_5FFF_DRAM <= '1'; - MAP_6000_6FFF_DRAM <= '1'; - MAP_7000_7FFF_DRAM <= '1'; - MAP_8000_8FFF_DRAM <= '1'; - MAP_9000_9FFF_DRAM <= '1'; - MAP_A000_AFFF_DRAM <= '1'; - MAP_B000_BFFF_DRAM <= '1'; - MAP_C000_CFFF_DRAM <= '1'; - MAP_0000_0FFF_ROM <= '0'; - MAP_1000_1FFF_CGROM <= '0'; - end if; + -- 0xE5 + when "101" => + mz700_INHIBIT := '1'; - -- 0xE1 - when "001" => - if Z80_RDn = '0' then - MAP_1000_1FFF_DRAM <= '1'; - MAP_1000_1FFF_CGROM <= '0'; + -- 0xE6 + when "110" => + mz700_INHIBIT := '0'; - if MODE_CPLD_MZ800 = '1' then - MAP_8000_8FFF_DRAM <= '1'; - MAP_9000_9FFF_DRAM <= '1'; - MAP_A000_AFFF_DRAM <= '1'; - MAP_B000_BFFF_DRAM <= '1'; - MAP_8000_8FFF_VRAM <= '0'; - MAP_9000_9FFF_VRAM <= '0'; - MAP_A000_AFFF_VRAM <= '0'; - MAP_B000_BFFF_VRAM <= '0'; - else - MAP_C000_CFFF_DRAM <= '1'; - MAP_C000_CFFF_VRAM <= '0'; - end if; + -- 0xE7 + when "111" => + end case; - elsif MODE_CPLD_MZ800 = '1' then - MAP_E000_EFFF_DRAM <= '1'; - MAP_F000_FFFF_DRAM <= '1'; - MAP_E000_EFFF_ROM <= '0'; - MAP_F000_FFFF_ROM <= '0'; - MAP_E000_E00F_IO <= '0'; - else - MAP_D000_DFFF_DRAM <= '1'; - MAP_E000_EFFF_DRAM <= '1'; - MAP_F000_FFFF_DRAM <= '1'; - MAP_D000_DFFF_VRAM <= '0'; - MAP_E000_EFFF_ROM <= '0'; - MAP_F000_FFFF_ROM <= '0'; - MAP_E000_E00F_IO <= '0'; - end if; + if(mz700_INHIBIT = '0' and mz700_LOWER_RAM = '0' and mz700_UPPER_RAM = '0') then + MEM_MODE_LATCH(4 downto 0) <= std_logic_vector(to_unsigned(TZMM_TZFS, MEM_MODE_LATCH'length)); - -- 0xE2 - when "010" => - MAP_0000_0FFF_ROM <= '1'; - MAP_0000_0FFF_DRAM <= '0'; + elsif(mz700_INHIBIT = '0' and mz700_LOWER_RAM = '1' and mz700_UPPER_RAM = '0') then + MEM_MODE_LATCH(4 downto 0) <= std_logic_vector(to_unsigned(TZMM_MZ700_0, MEM_MODE_LATCH'length)); - -- 0xE3 - when "011" => - if MODE_CPLD_MZ800 = '1' then - MAP_E000_EFFF_ROM <= '1'; - MAP_F000_FFFF_ROM <= '1'; - MAP_E000_E00F_IO <= '0'; - MAP_E000_EFFF_DRAM <= '0'; - MAP_F000_FFFF_DRAM <= '0'; - else - MAP_D000_DFFF_VRAM <= '1'; - MAP_E000_E00F_IO <= '1'; - MAP_E000_EFFF_ROM <= '1'; - MAP_F000_FFFF_ROM <= '1'; - end if; + elsif(mz700_INHIBIT = '0' and mz700_LOWER_RAM = '0' and mz700_UPPER_RAM = '1') then + MEM_MODE_LATCH(4 downto 0) <= std_logic_vector(to_unsigned(TZMM_MZ700_1, MEM_MODE_LATCH'length)); - -- 0xE4 - when "100" => - if MODE_CPLD_MZ800 = '1' then - MAP_0000_0FFF_ROM <= '1'; - MAP_1000_1FFF_CGROM <= '1'; - MAP_2000_2FFF_DRAM <= '1'; - MAP_3000_3FFF_DRAM <= '1'; - MAP_4000_4FFF_DRAM <= '1'; - MAP_5000_5FFF_DRAM <= '1'; - MAP_6000_6FFF_DRAM <= '1'; - MAP_7000_7FFF_DRAM <= '1'; - MAP_A000_AFFF_DRAM <= not MODE_640x200; - MAP_B000_BFFF_DRAM <= not MODE_640x200; - MAP_C000_CFFF_DRAM <= '1'; - MAP_D000_DFFF_DRAM <= '1'; - MAP_8000_8FFF_VRAM <= '1'; - MAP_9000_9FFF_VRAM <= '1'; - MAP_A000_AFFF_VRAM <= MODE_640x200; - MAP_B000_BFFF_VRAM <= MODE_640x200; - MAP_E000_EFFF_ROM <= '1'; - MAP_F000_FFFF_ROM <= '1'; - -- Clear remaining flags. - MAP_0000_0FFF_DRAM <= '0'; - MAP_1000_1FFF_DRAM <= '0'; - MAP_8000_8FFF_DRAM <= '0'; - MAP_9000_9FFF_DRAM <= '0'; - MAP_E000_EFFF_DRAM <= '0'; - MAP_F000_FFFF_DRAM <= '0'; - MAP_C000_CFFF_VRAM <= '0'; - MAP_D000_DFFF_VRAM <= '0'; - MAP_E000_E00F_IO <= '0'; - MAP_INHIBIT <= '0'; + elsif(mz700_INHIBIT = '0' and mz700_LOWER_RAM = '1' and mz700_UPPER_RAM = '1') then + MEM_MODE_LATCH(4 downto 0) <= std_logic_vector(to_unsigned(TZMM_MZ700_2, MEM_MODE_LATCH'length)); - else - MAP_0000_0FFF_ROM <= '1'; - MAP_1000_1FFF_DRAM <= '1'; - MAP_2000_2FFF_DRAM <= '1'; - MAP_3000_3FFF_DRAM <= '1'; - MAP_4000_4FFF_DRAM <= '1'; - MAP_5000_5FFF_DRAM <= '1'; - MAP_6000_6FFF_DRAM <= '1'; - MAP_7000_7FFF_DRAM <= '1'; - MAP_8000_8FFF_DRAM <= '1'; - MAP_9000_9FFF_DRAM <= '1'; - MAP_A000_AFFF_DRAM <= '1'; - MAP_B000_BFFF_DRAM <= '1'; - MAP_C000_CFFF_DRAM <= '1'; - MAP_D000_DFFF_VRAM <= '1'; - MAP_E000_E00F_IO <= '1'; - MAP_E000_EFFF_ROM <= '1'; - MAP_F000_FFFF_ROM <= '1'; - -- Clear remaining flags. - MAP_0000_0FFF_DRAM <= '0'; - MAP_1000_1FFF_CGROM <= '0'; - MAP_D000_DFFF_DRAM <= '0'; - MAP_E000_EFFF_DRAM <= '0'; - MAP_F000_FFFF_DRAM <= '0'; - MAP_8000_8FFF_VRAM <= '0'; - MAP_9000_9FFF_VRAM <= '0'; - MAP_A000_AFFF_VRAM <= '0'; - MAP_B000_BFFF_VRAM <= '0'; - MAP_C000_CFFF_VRAM <= '0'; - MAP_INHIBIT <= '0'; - end if; + elsif(mz700_INHIBIT = '1' and mz700_LOWER_RAM = '0') then + MEM_MODE_LATCH(4 downto 0) <= std_logic_vector(to_unsigned(TZMM_MZ700_3, MEM_MODE_LATCH'length)); - -- 0xE5 - when "101" => - MAP_INHIBIT <= '1'; + elsif(mz700_INHIBIT = '1' and mz700_LOWER_RAM = '1') then + MEM_MODE_LATCH(4 downto 0) <= std_logic_vector(to_unsigned(TZMM_MZ700_4, MEM_MODE_LATCH'length)); + else + null; + end if; - -- 0xE6 - when "110" => - MAP_INHIBIT <= '0'; - - -- 0xE7 - when "111" => - end case; - - -- Single memory map mode to handle the MZ-800, decoding is done in the memory management process. - if MODE_HOST_DEFAULT = '0' then - MEM_MODE_LATCH(4 downto 0) <= std_logic_vector(to_unsigned(TZMM_MZ800, MEM_MODE_LATCH'length)); - end if; - - -- Check for MZ700 Mode memory changes and adjust current memory mode setting. - -- - elsif((CPLD_HOST_HW = MODE_MZ700 or CPLD_HOST_HW = MODE_MZ80A) and MODE_CPLD_MZ700 = '1' and Z80_IORQn = '0' and Z80_M1n = '1' and Z80_ADDR(7 downto 3) = "11100") then - - -- MZ700 memory mode switch? - -- 0x0000:0x0FFF 0xD000:0xFFFF - -- 0xE0 = DRAM - -- 0xE1 = DRAM - -- 0xE2 = MONITOR - -- 0xE3 = Memory Mapped I/O - -- 0xE4 = MONITOR Memory Mapped I/O - -- 0xE5 = Inhibit - -- 0xE6 = Return to state prior to 0xE5 - case Z80_ADDR(2 downto 0) is - -- 0xE0 - when "000" => - mz700_LOWER_RAM := '1'; - - -- 0xE1 - when "001" => - mz700_UPPER_RAM := '1'; - - -- 0xE2 - when "010" => - mz700_LOWER_RAM := '0'; - - -- 0xE3 - when "011" => - mz700_UPPER_RAM := '0'; - - -- 0xE4 - when "100" => - mz700_LOWER_RAM := '0'; - mz700_UPPER_RAM := '0'; - - -- 0xE5 - when "101" => - mz700_INHIBIT := '1'; - - -- 0xE6 - when "110" => - mz700_INHIBIT := '0'; - - -- 0xE7 - when "111" => - end case; - - if(mz700_INHIBIT = '0' and mz700_LOWER_RAM = '0' and mz700_UPPER_RAM = '0') then - MEM_MODE_LATCH(4 downto 0) <= std_logic_vector(to_unsigned(TZMM_TZFS, MEM_MODE_LATCH'length)); - - elsif(mz700_INHIBIT = '0' and mz700_LOWER_RAM = '1' and mz700_UPPER_RAM = '0') then - MEM_MODE_LATCH(4 downto 0) <= std_logic_vector(to_unsigned(TZMM_MZ700_0, MEM_MODE_LATCH'length)); - - elsif(mz700_INHIBIT = '0' and mz700_LOWER_RAM = '0' and mz700_UPPER_RAM = '1') then - MEM_MODE_LATCH(4 downto 0) <= std_logic_vector(to_unsigned(TZMM_MZ700_1, MEM_MODE_LATCH'length)); - - elsif(mz700_INHIBIT = '0' and mz700_LOWER_RAM = '1' and mz700_UPPER_RAM = '1') then - MEM_MODE_LATCH(4 downto 0) <= std_logic_vector(to_unsigned(TZMM_MZ700_2, MEM_MODE_LATCH'length)); - - elsif(mz700_INHIBIT = '1' and mz700_LOWER_RAM = '0') then - MEM_MODE_LATCH(4 downto 0) <= std_logic_vector(to_unsigned(TZMM_MZ700_3, MEM_MODE_LATCH'length)); - - elsif(mz700_INHIBIT = '1' and mz700_LOWER_RAM = '1') then - MEM_MODE_LATCH(4 downto 0) <= std_logic_vector(to_unsigned(TZMM_MZ700_4, MEM_MODE_LATCH'length)); + -- Unknown event! else null; end if; - - -- Unknown event! - else - null; end if; - end if; - end process; + end process; + end generate; + + -- MZ-800 target hardware, generate the newer memory management mode logic. + -- + MEMORYMODE800: if CPLD_HOST_HW = MODE_MZ800 generate + + -- Memory mode latch. This latch stores the current memory mode (or Bank Paging Scheme) according to the running software. + -- + MEMORYMODE: process( Z80_CLKi, Z80_RESETn, SYSRESETn, CS_MEM_CFGn, Z80_IORQn, Z80_WRn, Z80_ADDR, Z80_DATA, CPLD_CFG_DATA, MODE_640x200 ) + variable mz700_LOWER_RAM : std_logic; + variable mz700_UPPER_RAM : std_logic; + variable mz700_INHIBIT : std_logic; + variable MODE_CPLD_LAST : std_logic_vector(2 downto 0); + begin + + if(Z80_RESETn = '0') then + -- -- On power up reset, default to original configuration. + -- if CPLD_CFG_DATA(7) = '0' then + -- -- Default to MZ-700/MZ-80A + -- MEM_MODE_LATCH <= std_logic_vector(to_unsigned(TZMM_ORIG, MEM_MODE_LATCH'length)); + -- + -- -- MZ-800 mode + -- --elsif CPLD_HOST_HW = MODE_MZ800 then + -- -- MEM_MODE_LATCH <= std_logic_vector(to_unsigned(TZMM_MZ800, MEM_MODE_LATCH'length)); + -- end if; + mz700_LOWER_RAM := '0'; + mz700_UPPER_RAM := '0'; + mz700_INHIBIT := '0'; + + -- Setup MZ-800 control on reset to MZ-800 startup memory map. + MAP_0000_0FFF_ROM <= '1'; + MAP_1000_1FFF_CGROM <= '1'; + MAP_2000_2FFF_DRAM <= '1'; + MAP_3000_3FFF_DRAM <= '1'; + MAP_4000_4FFF_DRAM <= '1'; + MAP_5000_5FFF_DRAM <= '1'; + MAP_6000_6FFF_DRAM <= '1'; + MAP_7000_7FFF_DRAM <= '1'; + MAP_A000_AFFF_DRAM <= not MODE_640x200; + MAP_B000_BFFF_DRAM <= not MODE_640x200; + MAP_C000_CFFF_DRAM <= '1'; + MAP_D000_DFFF_DRAM <= '1'; + MAP_8000_8FFF_VRAM <= '1'; + MAP_9000_9FFF_VRAM <= '1'; + MAP_A000_AFFF_VRAM <= MODE_640x200; + MAP_B000_BFFF_VRAM <= MODE_640x200; + MAP_E000_EFFF_ROM <= '1'; + MAP_F000_FFFF_ROM <= '1'; + -- Clear remaining flags. + MAP_0000_0FFF_DRAM <= '0'; + MAP_1000_1FFF_DRAM <= '0'; + MAP_8000_8FFF_DRAM <= '0'; + MAP_9000_9FFF_DRAM <= '0'; + MAP_E000_EFFF_DRAM <= '0'; + MAP_F000_FFFF_DRAM <= '0'; + MAP_C000_CFFF_VRAM <= '0'; + MAP_D000_DFFF_VRAM <= '0'; + MAP_E000_E00F_IO <= '0'; + MAP_INHIBIT <= '0'; + + MODE_CPLD_LAST := std_logic_vector(to_unsigned(CPLD_HOST_HW, MODE_CPLD_LAST'length)); + + -- On power up reset, default to original configuration. + elsif SYSRESETn = '0' and CPLD_CFG_DATA(7) = '0' then + -- Default to MZ-700/MZ-80A + MEM_MODE_LATCH <= std_logic_vector(to_unsigned(TZMM_ORIG, MEM_MODE_LATCH'length)); + + -- MZ-800 mode + --elsif CPLD_HOST_HW = MODE_MZ800 then + -- MEM_MODE_LATCH <= std_logic_vector(to_unsigned(TZMM_MZ800, MEM_MODE_LATCH'length)); + + + -- A direct write to the memory latch stores the required memory mode into the latch. + elsif (CS_MEM_CFGn = '0' and Z80_WRn = '0') then + MEM_MODE_LATCH <= Z80_DATA(4 downto 0); + + elsif(Z80_CLKi'event and Z80_CLKi = '1') then + + -- Cater for mode switches made by software between the MZ800 and MZ700 modes. + --. + -- if MODE_CPLD_LAST = MODE_MZ700 and MODE_CPLD_MZ800 = '1' then + -- MAP_0000_0FFF_ROM <= '1'; + -- MAP_1000_1FFF_CGROM <= '1'; + -- MAP_2000_2FFF_DRAM <= '1'; + -- MAP_3000_3FFF_DRAM <= '1'; + -- MAP_4000_4FFF_DRAM <= '1'; + -- MAP_5000_5FFF_DRAM <= '1'; + -- MAP_6000_6FFF_DRAM <= '1'; + -- MAP_7000_7FFF_DRAM <= '1'; + -- MAP_A000_AFFF_DRAM <= not MODE_640x200; + -- MAP_B000_BFFF_DRAM <= not MODE_640x200; + -- MAP_C000_CFFF_DRAM <= '1'; + -- MAP_D000_DFFF_DRAM <= '1'; + -- MAP_8000_8FFF_VRAM <= '1'; + -- MAP_9000_9FFF_VRAM <= '1'; + -- MAP_A000_AFFF_VRAM <= MODE_640x200; + -- MAP_B000_BFFF_VRAM <= MODE_640x200; + -- MAP_E000_EFFF_ROM <= '1'; + -- MAP_F000_FFFF_ROM <= '1'; + -- -- Clear remaining flags. + -- MAP_0000_0FFF_DRAM <= '0'; + -- MAP_1000_1FFF_DRAM <= '0'; + -- MAP_8000_8FFF_DRAM <= '0'; + -- MAP_9000_9FFF_DRAM <= '0'; + -- MAP_E000_EFFF_DRAM <= '0'; + -- MAP_F000_FFFF_DRAM <= '0'; + -- MAP_C000_CFFF_VRAM <= '0'; + -- MAP_D000_DFFF_VRAM <= '0'; + -- MAP_E000_E00F_IO <= '0'; + -- MAP_INHIBIT <= '0'; + -- + -- elsif MODE_CPLD_LAST = MODE_MZ800 and MODE_CPLD_MZ700 = '1' then + -- MAP_0000_0FFF_ROM <= '1'; + -- MAP_1000_1FFF_DRAM <= '1'; + -- MAP_2000_2FFF_DRAM <= '1'; + -- MAP_3000_3FFF_DRAM <= '1'; + -- MAP_4000_4FFF_DRAM <= '1'; + -- MAP_5000_5FFF_DRAM <= '1'; + -- MAP_6000_6FFF_DRAM <= '1'; + -- MAP_7000_7FFF_DRAM <= '1'; + -- MAP_8000_8FFF_DRAM <= '1'; + -- MAP_9000_9FFF_DRAM <= '1'; + -- MAP_A000_AFFF_DRAM <= '1'; + -- MAP_B000_BFFF_DRAM <= '1'; + -- MAP_C000_CFFF_DRAM <= '1'; + -- MAP_D000_DFFF_VRAM <= '1'; + -- MAP_E000_E00F_IO <= '1'; + -- MAP_E000_EFFF_ROM <= '1'; + -- MAP_F000_FFFF_ROM <= '1'; + -- -- Clear remaining flags. + -- MAP_1000_1FFF_CGROM <= '0'; + -- MAP_0000_0FFF_DRAM <= '0'; + -- MAP_D000_DFFF_DRAM <= '0'; + -- MAP_E000_EFFF_DRAM <= '0'; + -- MAP_F000_FFFF_DRAM <= '0'; + -- MAP_8000_8FFF_VRAM <= '0'; + -- MAP_9000_9FFF_VRAM <= '0'; + -- MAP_A000_AFFF_VRAM <= '0'; + -- MAP_B000_BFFF_VRAM <= '0'; + -- MAP_C000_CFFF_VRAM <= '0'; + -- MAP_INHIBIT <= '0'; + -- + -- end if; + + -- Each clock remember the current mode to detect a change. + MODE_CPLD_LAST := CPLD_CFG_DATA(2 downto 0); + + -- 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 = | | | | | | | | | | | | + -- IN 0xE0 = | |CGROM* | |VRAM* | | |CGROM | |VRAM | | | + -- IN 0xE1 = | |DRAM | |DRAM | | | | |DRAM | | | + -- + -- = Return to the state prior to the complimentary command being invoked. + -- * = MZ-800 host only. + + -- On MZ-800 hardware the MZ-700 mode is not quite the same so I've elected to use seperate decoding. You thus have MZ700/MZ800 modes on MZ800 hardware and MZ700 modes on + -- MZ700/MZ-80A hardware. + -- + if((MODE_CPLD_MZ700 = '1' or MODE_CPLD_MZ800 = '1') and Z80_IORQn = '0' and Z80_M1n = '1' and Z80_ADDR(7 downto 3) = "11100") then + + case Z80_ADDR(2 downto 0) is + -- 0xE0 + when "000" => + -- To cater for the CGROM being paged into the address space we use an override rather than a seperate memory mode. + if Z80_RDn = '0' then + MAP_1000_1FFF_DRAM <= '0'; + MAP_1000_1FFF_CGROM <= '1'; + if MODE_CPLD_MZ800 = '1' then + MAP_8000_8FFF_VRAM <= '1'; + MAP_9000_9FFF_VRAM <= '1'; + MAP_A000_AFFF_VRAM <= MODE_640x200; + MAP_B000_BFFF_VRAM <= MODE_640x200; + MAP_8000_8FFF_DRAM <= '0'; + MAP_9000_9FFF_DRAM <= '0'; + MAP_A000_AFFF_DRAM <= not MODE_640x200; + MAP_B000_BFFF_DRAM <= not MODE_640x200; + else + MAP_C000_CFFF_VRAM <= '1'; + MAP_C000_CFFF_DRAM <= '0'; + end if; + + elsif MODE_CPLD_MZ800 = '1' then + MAP_0000_0FFF_DRAM <= '1'; + MAP_1000_1FFF_DRAM <= '1'; + MAP_2000_2FFF_DRAM <= '1'; + MAP_3000_3FFF_DRAM <= '1'; + MAP_4000_4FFF_DRAM <= '1'; + MAP_5000_5FFF_DRAM <= '1'; + MAP_6000_6FFF_DRAM <= '1'; + MAP_7000_7FFF_DRAM <= '1'; + MAP_0000_0FFF_ROM <= '0'; + MAP_1000_1FFF_CGROM <= '0'; + else + MAP_0000_0FFF_DRAM <= '1'; + MAP_1000_1FFF_DRAM <= '1'; + MAP_2000_2FFF_DRAM <= '1'; + MAP_3000_3FFF_DRAM <= '1'; + MAP_4000_4FFF_DRAM <= '1'; + MAP_5000_5FFF_DRAM <= '1'; + MAP_6000_6FFF_DRAM <= '1'; + MAP_7000_7FFF_DRAM <= '1'; + MAP_8000_8FFF_DRAM <= '1'; + MAP_9000_9FFF_DRAM <= '1'; + MAP_A000_AFFF_DRAM <= '1'; + MAP_B000_BFFF_DRAM <= '1'; + MAP_C000_CFFF_DRAM <= '1'; + MAP_0000_0FFF_ROM <= '0'; + MAP_1000_1FFF_CGROM <= '0'; + end if; + + -- 0xE1 + when "001" => + if Z80_RDn = '0' then + MAP_1000_1FFF_DRAM <= '1'; + MAP_1000_1FFF_CGROM <= '0'; + + if MODE_CPLD_MZ800 = '1' then + MAP_8000_8FFF_DRAM <= '1'; + MAP_9000_9FFF_DRAM <= '1'; + MAP_A000_AFFF_DRAM <= '1'; + MAP_B000_BFFF_DRAM <= '1'; + MAP_8000_8FFF_VRAM <= '0'; + MAP_9000_9FFF_VRAM <= '0'; + MAP_A000_AFFF_VRAM <= '0'; + MAP_B000_BFFF_VRAM <= '0'; + else + MAP_C000_CFFF_DRAM <= '1'; + MAP_C000_CFFF_VRAM <= '0'; + end if; + + elsif MODE_CPLD_MZ800 = '1' then + MAP_E000_EFFF_DRAM <= '1'; + MAP_F000_FFFF_DRAM <= '1'; + MAP_E000_EFFF_ROM <= '0'; + MAP_F000_FFFF_ROM <= '0'; + MAP_E000_E00F_IO <= '0'; + else + MAP_D000_DFFF_DRAM <= '1'; + MAP_E000_EFFF_DRAM <= '1'; + MAP_F000_FFFF_DRAM <= '1'; + MAP_D000_DFFF_VRAM <= '0'; + MAP_E000_EFFF_ROM <= '0'; + MAP_F000_FFFF_ROM <= '0'; + MAP_E000_E00F_IO <= '0'; + end if; + + -- 0xE2 + when "010" => + MAP_0000_0FFF_ROM <= '1'; + MAP_0000_0FFF_DRAM <= '0'; + + -- 0xE3 + when "011" => + if MODE_CPLD_MZ800 = '1' then + MAP_E000_EFFF_ROM <= '1'; + MAP_F000_FFFF_ROM <= '1'; + MAP_E000_E00F_IO <= '0'; + MAP_E000_EFFF_DRAM <= '0'; + MAP_F000_FFFF_DRAM <= '0'; + else + MAP_D000_DFFF_VRAM <= '1'; + MAP_E000_E00F_IO <= '1'; + MAP_E000_EFFF_ROM <= '1'; + MAP_F000_FFFF_ROM <= '1'; + end if; + + -- 0xE4 + when "100" => + if MODE_CPLD_MZ800 = '1' then + MAP_0000_0FFF_ROM <= '1'; + MAP_1000_1FFF_CGROM <= '1'; + MAP_2000_2FFF_DRAM <= '1'; + MAP_3000_3FFF_DRAM <= '1'; + MAP_4000_4FFF_DRAM <= '1'; + MAP_5000_5FFF_DRAM <= '1'; + MAP_6000_6FFF_DRAM <= '1'; + MAP_7000_7FFF_DRAM <= '1'; + MAP_A000_AFFF_DRAM <= not MODE_640x200; + MAP_B000_BFFF_DRAM <= not MODE_640x200; + MAP_C000_CFFF_DRAM <= '1'; + MAP_D000_DFFF_DRAM <= '1'; + MAP_8000_8FFF_VRAM <= '1'; + MAP_9000_9FFF_VRAM <= '1'; + MAP_A000_AFFF_VRAM <= MODE_640x200; + MAP_B000_BFFF_VRAM <= MODE_640x200; + MAP_E000_EFFF_ROM <= '1'; + MAP_F000_FFFF_ROM <= '1'; + -- Clear remaining flags. + MAP_0000_0FFF_DRAM <= '0'; + MAP_1000_1FFF_DRAM <= '0'; + MAP_8000_8FFF_DRAM <= '0'; + MAP_9000_9FFF_DRAM <= '0'; + MAP_E000_EFFF_DRAM <= '0'; + MAP_F000_FFFF_DRAM <= '0'; + MAP_C000_CFFF_VRAM <= '0'; + MAP_D000_DFFF_VRAM <= '0'; + MAP_E000_E00F_IO <= '0'; + MAP_INHIBIT <= '0'; + + else + MAP_0000_0FFF_ROM <= '1'; + MAP_1000_1FFF_DRAM <= '1'; + MAP_2000_2FFF_DRAM <= '1'; + MAP_3000_3FFF_DRAM <= '1'; + MAP_4000_4FFF_DRAM <= '1'; + MAP_5000_5FFF_DRAM <= '1'; + MAP_6000_6FFF_DRAM <= '1'; + MAP_7000_7FFF_DRAM <= '1'; + MAP_8000_8FFF_DRAM <= '1'; + MAP_9000_9FFF_DRAM <= '1'; + MAP_A000_AFFF_DRAM <= '1'; + MAP_B000_BFFF_DRAM <= '1'; + MAP_C000_CFFF_DRAM <= '1'; + MAP_D000_DFFF_VRAM <= '1'; + MAP_E000_E00F_IO <= '1'; + MAP_E000_EFFF_ROM <= '1'; + MAP_F000_FFFF_ROM <= '1'; + -- Clear remaining flags. + MAP_0000_0FFF_DRAM <= '0'; + MAP_1000_1FFF_CGROM <= '0'; + MAP_D000_DFFF_DRAM <= '0'; + MAP_E000_EFFF_DRAM <= '0'; + MAP_F000_FFFF_DRAM <= '0'; + MAP_8000_8FFF_VRAM <= '0'; + MAP_9000_9FFF_VRAM <= '0'; + MAP_A000_AFFF_VRAM <= '0'; + MAP_B000_BFFF_VRAM <= '0'; + MAP_C000_CFFF_VRAM <= '0'; + MAP_INHIBIT <= '0'; + end if; + + -- 0xE5 + when "101" => + MAP_INHIBIT <= '1'; + + -- 0xE6 + when "110" => + MAP_INHIBIT <= '0'; + + -- 0xE7 + when "111" => + end case; + + -- Single memory map mode to handle the MZ-800, decoding is done in the memory management process. + if MODE_HOST_DEFAULT = '0' then + MEM_MODE_LATCH(4 downto 0) <= std_logic_vector(to_unsigned(TZMM_MZ800, MEM_MODE_LATCH'length)); + end if; + + -- Unknown event! + else + null; + end if; + end if; + end process; + end generate; -- Process to map host keyboard to realise compatibility with other Sharp machines. -- Currently the host can be a Sharp MZ-80A or MZ-800. Target (emulated) machines will be mapped accordingly. @@ -856,6 +907,7 @@ begin USEKEYMAPPER: if CPLD_HOST_HW = MODE_MZ80A generate KEYMAPPER: process( Z80_CLKi, Z80_RESETn, CS_MEM_CFGn, Z80_IORQn, Z80_ADDR, Z80_DATA ) + variable DELAY_MS_CLK_LAST : std_logic; begin if Z80_RESETn = '0' then @@ -868,7 +920,6 @@ begin MB_READ_KEYS <= '0'; MB_WAITn <= '1'; MB_ADDR <= (others => '0'); - MB_DELAY_TICKS <= (others => '1'); MB_DELAY_MS <= (others => '0'); MB_KEY_STROBE <= (others => '0'); KEY_STROBE <= (others => '0'); @@ -876,9 +927,17 @@ begin elsif Z80_CLKi'event and Z80_CLKi = '1' then + -- Millisecond down counter. + if DELAY_MS_CLK = '1' and DELAY_MS_CLK_LAST = '0' then + if MB_DELAY_MS /= 0 then + MB_DELAY_MS <= MB_DELAY_MS - 1; + end if; + end if; + DELAY_MS_CLK_LAST := DELAY_MS_CLK; + -- When inactive, wait for a Z80 I/O transaction that needs writeback. -- - if CPLD_HOST_HW = MODE_MZ80A and MODE_CPLD_MZ700 = '1' then + if MODE_CPLD_MZ700 = '1' then -- Auto scanning state machine. When the MZ700 isnt scanning the keys this FSM scans them to be ready -- to respond to events such as BREAK key detection. Normally the FSM wont run as the MZ700 scans the keys in @@ -886,14 +945,7 @@ begin -- Under these circumstances the FSM will make a full sweep of the keys. -- -- Configurable delay, a tick by tick timer and a millisecond timer, halts all actions whilst the timer > 0. - if MB_DELAY_TICKS /= 0 or MB_DELAY_MS /= 0 then - - if MB_DELAY_TICKS = 0 and MB_DELAY_MS /= 0 then - MB_DELAY_TICKS <= X"DFC"; -- 1ms with a 3.58MHz clock. - MB_DELAY_MS <= MB_DELAY_MS - 1; - else - MB_DELAY_TICKS <= MB_DELAY_TICKS - 1; - end if; + if MB_DELAY_MS /= 0 then -- If the Z80 Bus has not been requested and we need to make a key sweep, request the bus and start the sweep. elsif Z80_MREQn = '1' and MB_BUSRQn = '1' and MB_WAITn = '1' and KEY_SWEEP = '1' and KEY_SUBSTITUTE = '0' then @@ -990,7 +1042,7 @@ begin -- Remember last key strobe as we need to detect a scan to the same row more than once, this is typically used for BREAK detection or single key detection. -- In these cases we make an automated sweep of the entire keyboard as keys on the host are spread out on different strobe lines whereas the machine we are mapping to -- has them on one strobe line. - KEY_STROBE_LAST <= KEY_STROBE; + KEY_STROBE_LAST <= KEY_STROBE; if KEY_STROBE_LAST = KEY_STROBE and KEY_SWEEP = '0' then KEY_SWEEP <= '1'; end if; @@ -1054,31 +1106,36 @@ begin end generate; - -- Secondary clock source. If the K64F processor is installed, then use its clock output as the secondary clock as it is more finely programmable. If the K64F - -- is not available, use the onboard oscillator. + -- An approximate millisecond generator. -- - CTLCLKSRC: if USE_K64F_CTL_CLOCK = 1 generate - CTLCLKi <= CTLCLK; - else generate - process(Z80_RESETn, CTLCLK) - variable FREQDIVCTR : unsigned(3 downto 0); - begin - if Z80_RESETn = '0' then - FREQDIVCTR := (others => '0'); - CTLCLKi <= '0'; + process(Z80_RESETn, CTLCLKi) + begin + if Z80_RESETn = '0' then + DELAY_TICKS <= (others => '1'); + DELAY_US <= (others => '0'); + DELAY_MS_CLK <= '0'; - elsif CTLCLK'event and CTLCLK = '1' then + elsif rising_edge(CTLCLKi) then - FREQDIVCTR := FREQDIVCTR + 1; - - -- MZ700 => 3.58MHz, MZ80A => 12.5MHz - if (FREQDIVCTR = 7 and MODE_CPLD_MZ700 = '1') or (FREQDIVCTR = 2 and MODE_CPLD_MZ80A = '1') then - CTLCLKi <= not CTLCLKi; - FREQDIVCTR := (others => '0'); + -- An approximate uS timer, the CTLCLK is taken to be 3.58MHz in MZ-700 mode or 2MHz in MZ-80A mode. + if DELAY_TICKS = 0 then + DELAY_US <= DELAY_US + 1; + if MODE_CPLD_MZ700 = '1' then + DELAY_TICKS <= to_unsigned(4, DELAY_TICKS'length); + elsif MODE_CPLD_MZ80A = '1' then + DELAY_TICKS <= to_unsigned(2, DELAY_TICKS'length); + else + DELAY_TICKS <= to_unsigned(15, DELAY_TICKS'length); end if; + else + DELAY_TICKS <= DELAY_TICKS - 1; end if; - end process; - end generate; + if DELAY_US >= to_unsigned(500, DELAY_US'length) then + DELAY_MS_CLK <= not DELAY_MS_CLK; + DELAY_US <= (others => '0'); + end if; + end if; + end process; -- D type Flip Flops used for the CPU frequency switching circuit. The changeover of frequencies occurs on the high level, the output clock remaining -- high until the falling edge of the clock being switched into. @@ -1391,7 +1448,11 @@ begin -- DRAM elsif(unsigned(Z80_ADDR(15 downto 0)) >= X"1000" and unsigned(Z80_ADDR(15 downto 0)) < X"D000") then - Z80_HI_ADDRi <= "00000110"; + if CPLD_HOST_HW = MODE_MZ800 then + Z80_HI_ADDRi<= "00000110"; + else + Z80_HI_ADDRi<= "00000000"; + end if; Z80_RA_ADDRi <= Z80_ADDR(15 downto 12); DISABLE_BUSn <= '0'; CS_VIDEO_MEMn <= '1'; @@ -1440,7 +1501,11 @@ begin -- DRAM elsif(unsigned(Z80_ADDR(15 downto 0)) >= X"1000" and unsigned(Z80_ADDR(15 downto 0)) < X"D000") then - Z80_HI_ADDRi <= "00000110"; + if CPLD_HOST_HW = MODE_MZ800 then + Z80_HI_ADDRi<= "00000110"; + else + Z80_HI_ADDRi<= "00000000"; + end if; Z80_RA_ADDRi <= Z80_ADDR(15 downto 12); DISABLE_BUSn <= '0'; CS_VIDEO_MEMn <= '1'; @@ -1489,7 +1554,11 @@ begin -- DRAM elsif(unsigned(Z80_ADDR(15 downto 0)) >= X"1000" and unsigned(Z80_ADDR(15 downto 0)) < X"D000") then - Z80_HI_ADDRi <= "00000110"; + if CPLD_HOST_HW = MODE_MZ800 then + Z80_HI_ADDRi<= "00000110"; + else + Z80_HI_ADDRi<= "00000000"; + end if; Z80_RA_ADDRi <= Z80_ADDR(15 downto 12); DISABLE_BUSn <= '0'; CS_VIDEO_MEMn <= '1'; @@ -1538,7 +1607,11 @@ begin -- DRAM elsif(unsigned(Z80_ADDR(15 downto 0)) >= X"1000" and unsigned(Z80_ADDR(15 downto 0)) < X"D000") then - Z80_HI_ADDRi <= "00000110"; + if CPLD_HOST_HW = MODE_MZ800 then + Z80_HI_ADDRi<= "00000110"; + else + Z80_HI_ADDRi<= "00000000"; + end if; Z80_RA_ADDRi <= Z80_ADDR(15 downto 12); DISABLE_BUSn <= '0'; CS_VIDEO_MEMn <= '1'; @@ -1852,99 +1925,102 @@ begin -- differs to that used for the MZ700 which in hindsight the MZ700 should use but the MZ700 mode comes from the -- early tranZPUter SW developments which used a Flash RAM decoder. when TZMM_MZ800 => - -- Defaults. - RAM_CSni <= '0'; - RAM_WEni <= '1'; - RAM_OEni <= '1'; - Z80_HI_ADDRi <= "00000110"; -- Bank 6 = DRAM - Z80_RA_ADDRi <= Z80_ADDR(15 downto 12); - DISABLE_BUSn <= '1'; - CS_VIDEO_MEMn <= '1'; - - -- Memory area inhibited? - if( MAP_INHIBIT = '1' and - ((unsigned(Z80_ADDR(15 downto 0)) >= X"D000" and unsigned(Z80_ADDR(15 downto 0)) <= X"FFFF" and MODE_CPLD_MZ700 = '1') or - (unsigned(Z80_ADDR(15 downto 0)) >= X"E000" and unsigned(Z80_ADDR(15 downto 0)) <= X"FFFF" and MODE_CPLD_MZ800 = '1') )) then - - -- CGROM override? Used for copying the CGROM into the PCG at startup. - elsif( (unsigned(Z80_ADDR(15 downto 0)) >= X"1000" and unsigned(Z80_ADDR(15 downto 0)) <= X"1FFF") and MAP_1000_1FFF_CGROM = '1') then - - -- No action necessary, the region is locked out. - - -- Monitor ROM at 0000 enabled? If so, setup to access tranZPUter RAM acting as ROM. - elsif(((unsigned(Z80_ADDR(15 downto 0)) >= X"0000" and unsigned(Z80_ADDR(15 downto 0)) < X"1000")) and MAP_0000_0FFF_ROM = '1') then - - -- Setup to access tranZPUter RAM. Default to Bank 0 64K RAM block. - DISABLE_BUSn <= '0'; - RAM_OEni <= Z80_RDn; - RAM_WEni <= '1'; - - -- Chose RAM bank according to mode, Original = Bank 7 IPL ROMs, TZFS = Bank 0 ROMs. - if MAP_TZFS_BANK = '1' then - Z80_HI_ADDRi<= "00000000"; - else - Z80_HI_ADDRi<= "00000111"; + -- Dont compile the MZ-800 HDL for non MZ-800 target hardware. Generate would be better but not currently possible! + if CPLD_HOST_HW = MODE_MZ800 then + -- Defaults. + RAM_CSni <= '0'; + RAM_WEni <= '1'; + RAM_OEni <= '1'; + Z80_HI_ADDRi <= "00000110"; -- Bank 6 = DRAM + Z80_RA_ADDRi <= Z80_ADDR(15 downto 12); + DISABLE_BUSn <= '1'; + CS_VIDEO_MEMn <= '1'; + + -- Memory area inhibited? + if( MAP_INHIBIT = '1' and + ((unsigned(Z80_ADDR(15 downto 0)) >= X"D000" and unsigned(Z80_ADDR(15 downto 0)) <= X"FFFF" and MODE_CPLD_MZ700 = '1') or + (unsigned(Z80_ADDR(15 downto 0)) >= X"E000" and unsigned(Z80_ADDR(15 downto 0)) <= X"FFFF" and MODE_CPLD_MZ800 = '1') )) then + + -- CGROM override? Used for copying the CGROM into the PCG at startup. + elsif( (unsigned(Z80_ADDR(15 downto 0)) >= X"1000" and unsigned(Z80_ADDR(15 downto 0)) <= X"1FFF") and MAP_1000_1FFF_CGROM = '1') then + + -- No action necessary, the region is locked out. + + -- Monitor ROM at 0000 enabled? If so, setup to access tranZPUter RAM acting as ROM. + elsif(((unsigned(Z80_ADDR(15 downto 0)) >= X"0000" and unsigned(Z80_ADDR(15 downto 0)) < X"1000")) and MAP_0000_0FFF_ROM = '1') then + + -- Setup to access tranZPUter RAM. Default to Bank 0 64K RAM block. + DISABLE_BUSn <= '0'; + RAM_OEni <= Z80_RDn; + RAM_WEni <= '1'; + + -- Chose RAM bank according to mode, Original = Bank 7 IPL ROMs, TZFS = Bank 0 ROMs. + if MAP_TZFS_BANK = '1' then + Z80_HI_ADDRi<= "00000000"; + else + Z80_HI_ADDRi<= "00000111"; + end if; + + -- Monitor ROM enabled at E000:FFFF or E010:FFFF? If so, setup to access tranZPUter RAM acting as ROM. + elsif( ((unsigned(Z80_ADDR(15 downto 0)) >= X"E000" and unsigned(Z80_ADDR(15 downto 0)) <= X"E00F" and MAP_E000_E00F_IO = '0' and MAP_E000_EFFF_ROM = '1')) or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"E010" and unsigned(Z80_ADDR(15 downto 0)) <= X"EFFF" and MAP_E000_EFFF_ROM = '1')) or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"F000" and unsigned(Z80_ADDR(15 downto 0)) <= X"FFFF" and MAP_F000_FFFF_ROM = '1')) ) then + + -- Setup to access tranZPUter RAM. Default to Bank 0 64K RAM block. + DISABLE_BUSn <= '0'; + RAM_OEni <= Z80_RDn; + RAM_WEni <= Z80_WRn; + + -- Chose RAM bank according to mode, Original = Bank 7 IPL ROMs, TZFS = Bank 0 ROMs. + if MAP_TZFS_BANK = '1' then + Z80_HI_ADDRi<= "00000000"; + else + Z80_HI_ADDRi<= "00000111"; + end if; + + -- Memory I/O region mapped in during MZ-700 mode. + elsif( (unsigned(Z80_ADDR(15 downto 0)) >= X"E000" and unsigned(Z80_ADDR(15 downto 0)) <= X"E00F" and MAP_E000_E00F_IO = '1')) then + + -- Defaults apply, accessing a mainboard resource and the mainboard decode logic will activate. + + -- Video RAM enabled in region: 8000:9FFF, A000:BFFF, D000:DFFF? If so, setup to access mainboard Video RAM. + elsif( ((unsigned(Z80_ADDR(15 downto 0)) >= X"8000" and unsigned(Z80_ADDR(15 downto 0)) <= X"8FFF") and MAP_8000_8FFF_VRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"9000" and unsigned(Z80_ADDR(15 downto 0)) <= X"9FFF") and MAP_9000_9FFF_VRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"A000" and unsigned(Z80_ADDR(15 downto 0)) <= X"AFFF") and MAP_A000_AFFF_VRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"B000" and unsigned(Z80_ADDR(15 downto 0)) <= X"BFFF") and MAP_B000_BFFF_VRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"C000" and unsigned(Z80_ADDR(15 downto 0)) <= X"CFFF") and MAP_C000_CFFF_VRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"D000" and unsigned(Z80_ADDR(15 downto 0)) <= X"DFFF") and MAP_D000_DFFF_VRAM = '1') ) then + + -- Defaults apply, accessing a mainboard resource and the mainboard decode logic will activate. + + -- DRAM enabled in region: 0000:FFFF enabled in 4K blocks. If one is active, select the correct tranZPUter RAM bank. + elsif( ((unsigned(Z80_ADDR(15 downto 0)) >= X"0000" and unsigned(Z80_ADDR(15 downto 0)) <= X"0FFF") and MAP_0000_0FFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"1000" and unsigned(Z80_ADDR(15 downto 0)) <= X"1FFF") and MAP_1000_1FFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"2000" and unsigned(Z80_ADDR(15 downto 0)) <= X"2FFF") and MAP_2000_2FFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"3000" and unsigned(Z80_ADDR(15 downto 0)) <= X"3FFF") and MAP_3000_3FFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"4000" and unsigned(Z80_ADDR(15 downto 0)) <= X"4FFF") and MAP_4000_4FFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"5000" and unsigned(Z80_ADDR(15 downto 0)) <= X"5FFF") and MAP_5000_5FFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"6000" and unsigned(Z80_ADDR(15 downto 0)) <= X"6FFF") and MAP_6000_6FFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"7000" and unsigned(Z80_ADDR(15 downto 0)) <= X"7FFF") and MAP_7000_7FFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"8000" and unsigned(Z80_ADDR(15 downto 0)) <= X"8FFF") and MAP_8000_8FFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"9000" and unsigned(Z80_ADDR(15 downto 0)) <= X"9FFF") and MAP_9000_9FFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"A000" and unsigned(Z80_ADDR(15 downto 0)) <= X"AFFF") and MAP_A000_AFFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"B000" and unsigned(Z80_ADDR(15 downto 0)) <= X"BFFF") and MAP_B000_BFFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"C000" and unsigned(Z80_ADDR(15 downto 0)) <= X"CFFF") and MAP_C000_CFFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"D000" and unsigned(Z80_ADDR(15 downto 0)) <= X"DFFF") and MAP_D000_DFFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"E000" and unsigned(Z80_ADDR(15 downto 0)) <= X"EFFF") and MAP_E000_EFFF_DRAM = '1') or + ((unsigned(Z80_ADDR(15 downto 0)) >= X"F000" and unsigned(Z80_ADDR(15 downto 0)) <= X"FFFF") and MAP_F000_FFFF_DRAM = '1') ) then + + -- Setup to access tranZPUter RAM. Default to Bank 6 64K RAM block. + DISABLE_BUSn <= '0'; + -- if (unsigned(Z80_ADDR(15 downto 0)) >= X"0000" and unsigned(Z80_ADDR(15 downto 0)) <= X"0FFF") or (unsigned(Z80_ADDR(15 downto 0)) >= X"D000" and unsigned(Z80_ADDR(15 downto 0)) <= X"FFFF") then + -- else + -- Z80_HI_ADDRi<= "00000000"; + -- end if; + RAM_OEni <= Z80_RDn; + RAM_WEni <= Z80_WRn; + end if; - - -- Monitor ROM enabled at E000:FFFF or E010:FFFF? If so, setup to access tranZPUter RAM acting as ROM. - elsif( ((unsigned(Z80_ADDR(15 downto 0)) >= X"E000" and unsigned(Z80_ADDR(15 downto 0)) <= X"E00F" and MAP_E000_E00F_IO = '0' and MAP_E000_EFFF_ROM = '1')) or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"E010" and unsigned(Z80_ADDR(15 downto 0)) <= X"EFFF" and MAP_E000_EFFF_ROM = '1')) or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"F000" and unsigned(Z80_ADDR(15 downto 0)) <= X"FFFF" and MAP_F000_FFFF_ROM = '1')) ) then - - -- Setup to access tranZPUter RAM. Default to Bank 0 64K RAM block. - DISABLE_BUSn <= '0'; - RAM_OEni <= Z80_RDn; - RAM_WEni <= Z80_WRn; - - -- Chose RAM bank according to mode, Original = Bank 7 IPL ROMs, TZFS = Bank 0 ROMs. - if MAP_TZFS_BANK = '1' then - Z80_HI_ADDRi<= "00000000"; - else - Z80_HI_ADDRi<= "00000111"; - end if; - - -- Memory I/O region mapped in during MZ-700 mode. - elsif( (unsigned(Z80_ADDR(15 downto 0)) >= X"E000" and unsigned(Z80_ADDR(15 downto 0)) <= X"E00F" and MAP_E000_E00F_IO = '1')) then - - -- Defaults apply, accessing a mainboard resource and the mainboard decode logic will activate. - - -- Video RAM enabled in region: 8000:9FFF, A000:BFFF, D000:DFFF? If so, setup to access mainboard Video RAM. - elsif( ((unsigned(Z80_ADDR(15 downto 0)) >= X"8000" and unsigned(Z80_ADDR(15 downto 0)) <= X"8FFF") and MAP_8000_8FFF_VRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"9000" and unsigned(Z80_ADDR(15 downto 0)) <= X"9FFF") and MAP_9000_9FFF_VRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"A000" and unsigned(Z80_ADDR(15 downto 0)) <= X"AFFF") and MAP_A000_AFFF_VRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"B000" and unsigned(Z80_ADDR(15 downto 0)) <= X"BFFF") and MAP_B000_BFFF_VRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"C000" and unsigned(Z80_ADDR(15 downto 0)) <= X"CFFF") and MAP_C000_CFFF_VRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"D000" and unsigned(Z80_ADDR(15 downto 0)) <= X"DFFF") and MAP_D000_DFFF_VRAM = '1') ) then - - -- Defaults apply, accessing a mainboard resource and the mainboard decode logic will activate. - - -- DRAM enabled in region: 0000:FFFF enabled in 4K blocks. If one is active, select the correct tranZPUter RAM bank. - elsif( ((unsigned(Z80_ADDR(15 downto 0)) >= X"0000" and unsigned(Z80_ADDR(15 downto 0)) <= X"0FFF") and MAP_0000_0FFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"1000" and unsigned(Z80_ADDR(15 downto 0)) <= X"1FFF") and MAP_1000_1FFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"2000" and unsigned(Z80_ADDR(15 downto 0)) <= X"2FFF") and MAP_2000_2FFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"3000" and unsigned(Z80_ADDR(15 downto 0)) <= X"3FFF") and MAP_3000_3FFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"4000" and unsigned(Z80_ADDR(15 downto 0)) <= X"4FFF") and MAP_4000_4FFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"5000" and unsigned(Z80_ADDR(15 downto 0)) <= X"5FFF") and MAP_5000_5FFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"6000" and unsigned(Z80_ADDR(15 downto 0)) <= X"6FFF") and MAP_6000_6FFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"7000" and unsigned(Z80_ADDR(15 downto 0)) <= X"7FFF") and MAP_7000_7FFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"8000" and unsigned(Z80_ADDR(15 downto 0)) <= X"8FFF") and MAP_8000_8FFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"9000" and unsigned(Z80_ADDR(15 downto 0)) <= X"9FFF") and MAP_9000_9FFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"A000" and unsigned(Z80_ADDR(15 downto 0)) <= X"AFFF") and MAP_A000_AFFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"B000" and unsigned(Z80_ADDR(15 downto 0)) <= X"BFFF") and MAP_B000_BFFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"C000" and unsigned(Z80_ADDR(15 downto 0)) <= X"CFFF") and MAP_C000_CFFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"D000" and unsigned(Z80_ADDR(15 downto 0)) <= X"DFFF") and MAP_D000_DFFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"E000" and unsigned(Z80_ADDR(15 downto 0)) <= X"EFFF") and MAP_E000_EFFF_DRAM = '1') or - ((unsigned(Z80_ADDR(15 downto 0)) >= X"F000" and unsigned(Z80_ADDR(15 downto 0)) <= X"FFFF") and MAP_F000_FFFF_DRAM = '1') ) then - - -- Setup to access tranZPUter RAM. Default to Bank 6 64K RAM block. - DISABLE_BUSn <= '0'; --- if (unsigned(Z80_ADDR(15 downto 0)) >= X"0000" and unsigned(Z80_ADDR(15 downto 0)) <= X"0FFF") or (unsigned(Z80_ADDR(15 downto 0)) >= X"D000" and unsigned(Z80_ADDR(15 downto 0)) <= X"FFFF") then - -- else - -- Z80_HI_ADDRi<= "00000000"; --- end if; - RAM_OEni <= Z80_RDn; - RAM_WEni <= Z80_WRn; - end if; -- Set 21 - Access the FPGA memory by passing through the full 24bit Z80 address, typically from the K64F. @@ -2124,6 +2200,8 @@ begin -- the mainboard) and the programmable frequency generated by the K64F timers. Z80_CLKi <= (SYSCLK or SYSCLK_Q) and (CTLCLKi or CTLCLK_Q); Z80_CLK <= Z80_CLKi; + CTLCLKi <= CTLCLK; + -- Wait states, added by the video circuitry or the K64F. Z80_WAITn <= '0' when SYS_WAITn = '0' or CTL_WAITn = '0' or MB_WAITn = '0' @@ -2274,16 +2352,19 @@ begin -- MZ80B/MZ2000 I/O Registers E0-EB, CS_80B_PIOn <= '0' when CS_IO_EXXn = '0' and Z80_ADDR(3 downto 2) = "10" and MODE_VIDEO_MZ80B = '1' else '1'; + -- MZ-800 Custom gate array control signals. - -- 0xCC - CS_GDG_GWF <= '0' when CS_IO_CXXn = '0' and Z80_ADDR(3 downto 0) = "1100" and CPLD_HOST_HW = MODE_MZ800 + GDGSIGNALS: if CPLD_HOST_HW = MODE_MZ800 generate + -- 0xCC + CS_GDG_GWF <= '0' when CS_IO_CXXn = '0' and Z80_ADDR(3 downto 0) = "1100" and CPLD_HOST_HW = MODE_MZ800 else '1'; - -- 0xCD - CS_GDG_GRF <= '0' when CS_IO_CXXn = '0' and Z80_ADDR(3 downto 0) = "1101" and CPLD_HOST_HW = MODE_MZ800 + -- 0xCD + CS_GDG_GRF <= '0' when CS_IO_CXXn = '0' and Z80_ADDR(3 downto 0) = "1101" and CPLD_HOST_HW = MODE_MZ800 else '1'; - -- 0xCE - CS_GDG_CMD <= '0' when CS_IO_CXXn = '0' and Z80_ADDR(3 downto 0) = "1110" and CPLD_HOST_HW = MODE_MZ800 + -- 0xCE + CS_GDG_CMD <= '0' when CS_IO_CXXn = '0' and Z80_ADDR(3 downto 0) = "1110" and CPLD_HOST_HW = MODE_MZ800 else '1'; + end generate; -- Select for video based on the memory being accessed, the mode and control signals. diff --git a/CPLD/SW/tranZPUterSW_pkg.vhd b/CPLD/SW/tranZPUterSW_pkg.vhd index 608eb36..068384f 100644 --- a/CPLD/SW/tranZPUterSW_pkg.vhd +++ b/CPLD/SW/tranZPUterSW_pkg.vhd @@ -12,6 +12,11 @@ -- -- History: June 2020 - Initial creation. -- Mar 2021 - Updated to enable better compatibility with the Sharp MZ-800. +-- Mar 2021 - Many changes to cater for the MZ-800. The machine has different memory +-- modes and maps so extensive changes needed. +-- Apr 2021 - Removed the v2.1 frequency generator as 2.1 no longer supported. Fixed +-- issues with adding the MZ-800 using too many resources, made +-- compilation conditional. -- --------------------------------------------------------------------------------------------------------- -- This source file is free software: you can redistribute it and-or modify @@ -95,8 +100,8 @@ package tranZPUterSW_pkg is -- Configurable parameters. ------------------------------------------------------------ -- Target hardware. - constant CPLD_HOST_HW : integer := MODE_MZ800; - --constant CPLD_HOST_HW : integer := MODE_MZ80A; + --constant CPLD_HOST_HW : integer := MODE_MZ800; + constant CPLD_HOST_HW : integer := MODE_MZ80A; -- Target video hardware. constant CPLD_HAS_FPGA_VIDEO : std_logic := '0'; @@ -104,10 +109,6 @@ package tranZPUterSW_pkg is -- Version of hdl. constant CPLD_VERSION : integer := 1; - -- 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 ------------------------------------------------------------ diff --git a/devices/sysbus/BRAM/TZSW_DualPortBootBRAM.vhd b/devices/sysbus/BRAM/TZSW_DualPortBootBRAM.vhd index baf667c..4d79fe7 100644 --- a/devices/sysbus/BRAM/TZSW_DualPortBootBRAM.vhd +++ b/devices/sysbus/BRAM/TZSW_DualPortBootBRAM.vhd @@ -14994,7 +14994,7 @@ architecture arch of DualPortBootBRAM is 14923 => x"30", 14924 => x"30", 14925 => x"00", - 14926 => x"31", + 14926 => x"32", 14927 => x"00", 14928 => x"55", 14929 => x"65", @@ -51403,7 +51403,7 @@ architecture arch of DualPortBootBRAM is 14920 => x"4f", 14921 => x"2a", 14922 => x"20", - 14923 => x"31", + 14923 => x"37", 14924 => x"2f", 14925 => x"31", 14926 => x"31", @@ -69610,10 +69610,10 @@ architecture arch of DualPortBootBRAM is 14921 => x"2a", 14922 => x"73", 14923 => x"31", - 14924 => x"33", + 14924 => x"34", 14925 => x"32", 14926 => x"76", - 14927 => x"6b", + 14927 => x"00", 14928 => x"20", 14929 => x"2c", 14930 => x"76", diff --git a/devices/sysbus/BRAM/TZSW_SinglePortBootBRAM.vhd b/devices/sysbus/BRAM/TZSW_SinglePortBootBRAM.vhd index d206624..9fbb703 100644 --- a/devices/sysbus/BRAM/TZSW_SinglePortBootBRAM.vhd +++ b/devices/sysbus/BRAM/TZSW_SinglePortBootBRAM.vhd @@ -14989,7 +14989,7 @@ architecture arch of SinglePortBootBRAM is 14923 => x"30", 14924 => x"30", 14925 => x"00", - 14926 => x"31", + 14926 => x"32", 14927 => x"00", 14928 => x"55", 14929 => x"65", @@ -51398,7 +51398,7 @@ architecture arch of SinglePortBootBRAM is 14920 => x"4f", 14921 => x"2a", 14922 => x"20", - 14923 => x"31", + 14923 => x"37", 14924 => x"2f", 14925 => x"31", 14926 => x"31", @@ -69605,10 +69605,10 @@ architecture arch of SinglePortBootBRAM is 14921 => x"2a", 14922 => x"73", 14923 => x"31", - 14924 => x"33", + 14924 => x"34", 14925 => x"32", 14926 => x"76", - 14927 => x"6b", + 14927 => x"00", 14928 => x"20", 14929 => x"2c", 14930 => x"76", diff --git a/software/asm/BASIC.asm b/software/asm/MSBASIC.asm similarity index 97% rename from software/asm/BASIC.asm rename to software/asm/MSBASIC.asm index ab59cfa..4525ede 100644 --- a/software/asm/BASIC.asm +++ b/software/asm/MSBASIC.asm @@ -23,12 +23,13 @@ ; Original source is: (C) 1978 Microsoft ; Updates (some reversed out): Grant Searle, http://searle.hostei.com/grant/index.html ; eMail: home.micros01@btinternet.com -; All other updates (C) Philip Smart, 2020. http://www.eaw.app philip.smart\@net2net.org +; All other updates (C) Philip Smart, 2020-21. http://www.eaw.app philip.smart\@net2net.org ;----------------------------------------------------------------------------------------------- ; Bring in additional resources. - INCLUDE "BASIC_Definitions.asm" + INCLUDE "MSBASIC_BuildVersion.asm" + INCLUDE "MSBASIC_Definitions.asm" INCLUDE "Macros.asm" ; Sharp MZ-80A Tape Format Header - used by all software including RFS/TZFS @@ -38,26 +39,34 @@ DB 01h ; Code Type, 01 = Machine Code. HEADER1: IF BUILD_MZ80A = 1 - DB "MZ80A BASIC V1.1", 0DH ; Title/Name (17 bytes). + DB "MS-BASIC(MZ-80A)", 0DH ; Title/Name (17 bytes). DW CODEEND - CODESTART ; Size of program. DW CODESTART ; Load address of program. DW CODESTART ; Exec address of program. ENDIF -HEADER2: IF BUILD_RFS = 1 - DB "RFS BASIC V1.1" , 0DH, 0DH, 0DH ; Title/Name (17 bytes). - DW (CODEEND - CODESTART) + (RELOCEND - RELOC) + (RELOCRFS2END - RELOCRFS2) ; Size of program. - DW 01200H ; Load address of program. - DW RELOCRFS ; Exec address of program. - ENDIF - -HEADER3: IF BUILD_TZFS = 1 - DB "TZFS BASIC V1.3", 0DH, 0DH ; Title/Name (17 bytes). +HEADER2: IF BUILD_MZ700 = 1 + DB "MS-BASIC(MZ700)", 0DH, 0DH, 0DH, 0DH ; Title/Name (17 bytes). DW (CODEEND - CODESTART) + (RELOCEND - RELOC) ; Size of program. DW 01200H ; Load address of program. DW RELOC ; Exec address of program. ENDIF +HEADER3: IF BUILD_TZFS = 1 + IF BUILD_80C = 0 + DB "MS-BASIC(TZFS40)", 0DH ; Title/Name (17 bytes). + DW (CODEEND - CODESTART) + (RELOCEND - RELOC) ; Size of program. + DW 01200H ; Load address of program. + DW RELOC ; Exec address of program. + ELSE + IF BUILD_80C = 1 + DB "MS-BASIC(TZFS80)", 0DH ; Title/Name (17 bytes). + DW (CODEEND - CODESTART) + (RELOCEND - RELOC) ; Size of program. + DW 01200H ; Load address of program. + DW RELOC ; Exec address of program. + ENDIF + ENDIF + DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h ; Comment (104 bytes). DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h DB 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h, 00h @@ -68,11 +77,15 @@ HEADER3: IF BUILD_TZFS = 1 ; Load address of this program when first loaded. ; -BUILD1: IF BUILD_MZ80A = 1 +BUILD1: IF BUILD_MZ80A = 1 ORG 1200H ENDIF -BUILD2: IF BUILD_TZFS+BUILD_RFS > 0 +BUILD2: IF BUILD_MZ700 = 1 + ORG 0000H + ENDIF + +BUILD3: IF BUILD_TZFS = 1 ORG 0000H ENDIF @@ -88,7 +101,7 @@ STARTB: DW ABPASS ; Return integer in AB -VECTORS: IF BUILD_TZFS+BUILD_RFS > 0 +VECTORS: IF BUILD_MZ700+BUILD_TZFS > 1 ALIGN 0038H ORG 0038H INTVEC: DS 3 ; Space for the Interrupt vector. @@ -102,7 +115,7 @@ CSTART: DI ; Disable Interrupts and sat mode. NB. IM 1 LD SP,STACK ; Start of workspace RAM -MEMSW0: IF BUILD_TZFS+BUILD_RFS > 0 +MEMSW0: IF BUILD_MZ700+BUILD_TZFS > 1 LD A,TZMM_MZ700_0 ; Ensure the top part of RAM is set to use the mainboard as we need to configure hardware. OUT (MMCFG),A ENDIF @@ -122,6 +135,12 @@ INIT1: LD (HL),D ; Clear variable memory including stack JR NZ,INIT1 ; CALL MODE ; Configure 8255 port C, set Motor Off, VGATE to 1 (off) and INTMSK to 0 (interrupts disabled). + LD A,000H ; Clear the screen buffer. + LD HL,SCRN + CALL CLR8 + LD A,017H ; Blue background, white characters in colour mode. + LD HL,ARAM + CALL CLR8 LD A,004H LD (TEMPW),A ; Setup the tempo for sound output. @@ -145,34 +164,45 @@ INIT3: ; Setup keyboard buffer control. LD A,080H ; Cursor on (Bit D7=1). LD (FLASHCTL),A -INIT80CHAR: IF BUILD_VIDEOMODULE = 1 - IN A, (CPLDINFO) ; Get hardware information. - BIT 3,A - JR Z, INIT40CHAR ; If no video module present then need to use 40 char mode. - AND 007H - LD D, A - OR MODE_VIDEO_FPGA ; Ensure the video hardware is enabled. - OUT (CPLDCFG),A - LD A, D - OR MODE_80CHAR ; Enable 80 char display. - LD C, A - IN A, (VMCTRL) ; Get current graphics mode and vga mode. - AND 0C0H ; Mask out all but VGA mode. - OR C ; Add in new hardware/80char mode. - OUT (VMCTRL),A ; Activate. - LD A, D - CP MODE_MZ80A ; Check to see if this is the MZ80A, if so, change BUS speed. - JR NZ, INIT80END - LD A, SYSMODE_MZ80B ; Set bus and default CPU speed to 4MHz - OUT (SYSCTRL),A ; Activate. - JR INIT80END +INIT80CVM: IF BUILD_VIDEOMODULE = 1 + IN A, (CPLDINFO) ; Get hardware information. + BIT 3,A + JR Z, INIT80CHAR ; If no video module present then need to use 40 char mode. + AND 007H + LD D, A + OR MODE_VIDEO_FPGA ; Ensure the video hardware is enabled. + OUT (CPLDCFG),A + LD A, D + OR MODE_80CHAR ; Enable 80 char display. + LD C, A + IN A, (VMCTRL) ; Get current graphics mode and vga mode. + AND 0C0H ; Mask out all but VGA mode. + OR C ; Add in new hardware/80char mode. + OUT (VMCTRL),A ; Activate. + LD A, D + CP MODE_MZ80A ; Check to see if this is the MZ80A, if so, change BUS speed. + JR NZ, INIT80END + LD A, SYSMODE_MZ80B ; Set bus and default CPU speed to 4MHz + OUT (SYSCTRL),A ; Activate. + JR INIT80END + + ; If no Video module installed but 80C configured, attempt to initialise the 40/80 Colour Card. +INIT80CHAR: IF BUILD_80C = 1 + ; Change to 80 character mode. + LD HL,DSPCTL ; Setup address of display control register latch. + LD A, 128 ; 80 char mode. + LD E,(HL) ; Dummy operation to enable latch write via multivibrator. + LD (HL), A + ENDIF -INIT40CHAR: LD A, 40 ; Set BASIC to 40 column width. - LD (INITABW),A ELSE - ; Change to 80 character mode on the 40/80 Char Colour board v1.0. - LD A, 128 ; 80 char mode. - LD (DSPCTL), A + + ; Default falls through to 40 column mode. +INIT40CHAR: LD A, 40 ; Set BASIC to 40 column width. + LD (INITABW),A + XOR A ; As we call RFS for SD services, specifically DIR listing, we have to ensure RFS is configured for 40 column output mode. + LD (SCRNMODE), A + LD (SPAGE), A ENDIF ; INIT80END: LD A,000H ; Clear the screen buffer. @@ -182,13 +212,15 @@ INIT80END: LD A,000H ; Clear the screen buffer. LD HL,ARAM CALL CLR8 ; + LD A,COLW + LD (LWIDTH),A ; Setup the initial terminal width. CALL MLDSP CALL BEL ; Beep to indicate startup - for cases where screen is slow to startup. LD A,0FFH LD (SWRK),A INITANSI: IF INCLUDE_ANSITERM = 1 ; If the ansi terminal emulator is builtin, enable it as default. - LD (ANSIENABLE),A + LD (ANSIENABLE),A ENDIF ; Setup timer interrupts @@ -201,18 +233,18 @@ INITANSI: IF INCLUDE_ANSITERM = 1 ; If the ansi terminal emulator is buil LD A,05H ; Enable interrupts at hardware level, this must be done before switching memory mode. LD (KEYPF),A ; -MEMSW1: IF BUILD_TZFS+BUILD_RFS > 0 - LD A,TZMM_MZ700_2 ; Enable the full 64K memory range before starting BASIC initialisation. - OUT (MMCFG),A +MEMSW1: IF BUILD_MZ700+BUILD_TZFS > 0 + LD A,TZMM_MZ700_2 ; Enable the full 64K memory range before starting BASIC initialisation. + OUT (MMCFG),A ENDIF ; Clear memory LD HL,WRKSPC MEMSZ1: IF BUILD_MZ80A = 1 - LD BC,MAXMEM - WRKSPC ; Clear to top of physical RAM. + LD BC,MAXMEM - WRKSPC ; Clear to top of physical RAM. ENDIF -MEMSZ2: IF BUILD_TZFS+BUILD_RFS > 0 - LD BC,10000H - WRKSPC ; Clear to top of physical RAM. +MEMSZ2: IF BUILD_MZ700+BUILD_TZFS > 0 + LD BC,10000H - WRKSPC ; Clear to top of physical RAM. ENDIF LD E,00H INIT4: LD (HL),E @@ -347,16 +379,18 @@ OPTIONS0: IF BUILD_TZFS = 1 DB 'D'+80H,"IR" ; 0xa8 DB 'C'+80H,"D" ; 0xa9 ENDIF - IF BUILD_RFS = 1 - DB 'C'+80H,"LOAD" ; 0xa3 - DB 'C'+80H,"SAVE" ; 0xa4 +OPTIONS1: IF BUILD_MZ700 = 1 + ;DB 'C'+80H,"LOAD" ; 0xa3 + ;DB 'C'+80H,"SAVE" ; 0xa4 + DB 'R'+80H,"EM" ; 0xa3 + DB 'R'+80H,"EM" ; 0xa4 DB 'R'+80H,"EM" ; 0xa5 DB 'R'+80H,"EM" ; 0xa6 DB 'R'+80H,"EM" ; 0xa7 DB 'R'+80H,"EM" ; 0xa8 DB 'R'+80H,"EM" ; 0xa9 ENDIF - IF BUILD_MZ80A = 1 +OPTIONS2: IF BUILD_MZ80A = 1 DB 'C'+80H,"LOAD" ; 0xa3 DB 'C'+80H,"SAVE" ; 0xa4 DB 'R'+80H,"EM" ; 0xa5 @@ -477,7 +511,7 @@ WORDTB: DW PEND DW SETANSITERM ; Enable/disable the ANSI Terminal Emulator. ; Optional commands to be builtin when a tranZPUter board is present. -OPTIONS1: IF BUILD_TZFS = 1 +OPTIONS1A: IF BUILD_TZFS = 1 DW CLOADTZ ; Load tokenised BASIC program. DW CSAVETZ ; Save tokenised BASIC program. DW LOAD ; Load ASCII text BASIC program. @@ -486,7 +520,7 @@ OPTIONS1: IF BUILD_TZFS = 1 DW DIRSDCARD ; List out the SD directory. DW SETDIR ; Change directory for all load and save operations. ENDIF -OPTIONS2: IF BUILD_RFS = 1 +OPTIONS2A: IF BUILD_MZ700 = 1 DW CLOAD80A ; Load tokenised BASIC program from tape. DW CSAVE80A ; Save tokenised BASIC program to tape. DW REM @@ -495,7 +529,7 @@ OPTIONS2: IF BUILD_RFS = 1 DW REM DW REM ENDIF -OPTIONS3: IF BUILD_MZ80A = 1 +OPTIONS3A: IF BUILD_MZ80A = 1 DW CLOAD80A ; Load tokenised BASIC program from tape. DW CSAVE80A ; Save tokenised BASIC program to tape. DW REM @@ -652,7 +686,11 @@ INITAB: JP WARMST ; Warm start jump DB 1 ; POS (x) number (1) INITABW: DB COLW ; Terminal width - DB 28 ; Width for commas (3 columns) + IF BUILD_80C = 1 + DB 28 ; Width for commas (3 columns) + ELSE + DB 14 ; Width for commas (3 columns) + ENDIF DB 0 ; No nulls after input bytes DB 0 ; Output enabled (^O off) @@ -1077,6 +1115,7 @@ ECHDEL: DEC B ; Count bytes in buffer DELCHR: DEC B ; Count bytes in buffer DEC HL ; Back space buffer + JR Z,GETLIN ; End of buffer, start again CALL OUTC ; Output character in A JP NZ,MORINP ; Not end - Get more OTKLN: CALL OUTC ; Output character in A @@ -1091,7 +1130,7 @@ TTYLIN: LD HL,BUFFER ; Get a line by character MORINP: CALL CLOTST ; Get character and test ^O LD C,A ; Save character in C CP DELETE ; Delete character? - JP Z,DODEL ; Yes - Process it + JP Z,DELCHR ;DODEL ; Yes - Process it LD A,(NULFLG) ; Get null flag OR A ; Test null flag status JP Z,PROCES ; Reset - Process character @@ -5240,9 +5279,9 @@ FREQDEF: DB "Set to default.", C ENDIF ; End of optional commands for use when a tranZPUter board is present. ;---------------------------------------- - ; RFS Commands. + ; MZ-700 Commands. ;---------------------------------------- -OPTIONS2C: IF BUILD_RFS = 1 +OPTIONS2C: IF BUILD_MZ700 = 1 ;-------------------------------------- @@ -5270,19 +5309,20 @@ RFSMSGLOAD: DB "Loading", N RFSMSGOK: DB "Saved", CR, NUL ;---------------------------------------- - ; End of Options2 Code - RFS Build + ; End of Options2 Code - MZ-700 Build ;---------------------------------------- ENDIF ; End of optional commands for use when a tranZPUter board is present. ;---------------------------------------- ; MZ80A Commands. ;---------------------------------------- -OPTIONS3C: IF BUILD_MZ80A+BUILD_RFS > 0 +OPTIONS3C: IF BUILD_MZ80A+BUILD_MZ700 > 0 ; Method to load a cassette image (tokenised basic script). ; -CLOAD80A: LD A,CTAPELOAD ; Set the type of operatiom into the flag var. -CLOAD0: LD (TPFLAG),A +CLOAD80A: CALL CURSOROFF + LD A,CTAPELOAD ; Set the type of operatiom into the flag var. + LD (TPFLAG),A LD A,(HL) ; Get byte after "CLOAD" ; CP ZTIMES ; "*" token? ("CLOAD*") ; JP Z,ARRLD1 ; Yes - Array load @@ -5307,7 +5347,7 @@ CLOAD0: LD (TPFLAG),A CALL EVAL ; Evaluate expression CALL GTFLNM ; Get file name ; -CLOAD80A_0: LD HL,NAME ; Set the filename to be loaded. + LD HL,NAME ; Set the filename to be loaded. LD A,(TMSTPL) CP TZSVCFILESZ ; Check size of filename, cant be more than an MZF name of 17 chars. JP NC,CMTFNTG @@ -5324,6 +5364,10 @@ CLOAD80A_2: CALL CLRPTR ; Initialise memory to NEW state ready ; CALL ?RDI JP C,CMTLDER + LD A,(ATRB) + CP ATR_BASIC_MSCAS ; Verify this is a NASCOM Cassette BASIC image. + JP NZ,CMTATER + ; LD DE,CMTMSGLOAD ; Show we are loading a program. CALL MONPRTSTR LD DE,NAME @@ -5350,11 +5394,13 @@ CLOAD80A_2: CALL CLRPTR ; Initialise memory to NEW state ready CMTVERF: CMTLOADE: LD HL,OKMSG ; "Ok" message CALL PRS ; Output string + CALL CURSORON JP SETPTR ; Set up line pointers ; Method to save a cassette image (tokenised basic script). ; -CSAVE80A: LD A,CTAPESAVE ; Set the type of operatiom into the flag var. +CSAVE80A: CALL CURSOROFF + LD A,CTAPESAVE ; Set the type of operatiom into the flag var. LD (TPFLAG),A ; LD B,1 ; Flag "CSAVE" @@ -5377,7 +5423,7 @@ CSAVE80A_1: LD A,(DE) ; Copy filename into service record. XOR A LD (HL),A ; Terminate filename. ; - LD A,ATR_BASIC_PROG ; Set attribute: BASIC + LD A,ATR_BASIC_MSCAS ; Set attribute: MS BASIC Cassette LD (ATRB),A LD HL,(PROGND) ; Get the actual program size. LD BC,(BASTXT) ; Get start of program memory. @@ -5395,6 +5441,7 @@ CSAVE80A_1: LD A,(DE) ; Copy filename into service record. JR C,CMTSVER LD HL,CMTMSGOK ; 'OK!' CALL PRS + CALL CURSORON POP DE POP HL RET @@ -5408,12 +5455,15 @@ OPTIONS3B: IF BUILD_MZ80A = 1 ;-------------------------------------- CMTNONAM: LD HL,CMTBADFN ; Must give a name for SD card load and save. CMTERR: CALL PRS + CALL CURSORON POP AF ; Waste return address. JP ERRIN CMTFNTG: LD HL,CMTFNTOOG JR CMTERR CMTLDER: LD HL,CMTLOADERR JR CMTERR +CMTATER: LD HL,CMTATTRERR + JR CMTERR CMTSVER: LD HL,CMTSAVEERR JR CMTERR @@ -5424,6 +5474,7 @@ CMTBADFN: DB "Filename missing!", C CMTFNTOOG: DB "Filename too long!", CR, NUL CMTLOADERR: DB "File loading error!", CR, NUL CMTSAVEERR: DB "File save error!", CR, NUL +CMTATTRERR: DB "Not an MS-BASIC cassette file error!", CR, NUL CMTMSGLOAD: DB "Loading \"", NUL CMTMSGLOAD2:DB "\"", CR, NUL CMTMSGOK: DB "Saved", CR, NUL @@ -5435,7 +5486,7 @@ CMTMSGOK: DB "Saved", C MONITR: -MONITR2 IF BUILD_TZFS+BUILD_RFS > 0 +MONITR2 IF BUILD_MZ700+BUILD_TZFS > 0 ; Switch memory back to TZFS mode. LD A, TZMM_TZFS OUT (MMCFG),A @@ -5456,7 +5507,7 @@ TIMIN: LD (SPISRSAVE),SP ; Use a PUSH DE PUSH HL ; -MEMSW2: IF BUILD_TZFS+BUILD_RFS > 0 +MEMSW2: IF BUILD_MZ700+BUILD_TZFS > 0 LD A,TZMM_MZ700_0 ; We meed to be in memory mode 10 to process the interrupts as this allows us access to the hardware. OUT (MMCFG),A ENDIF @@ -5688,7 +5739,7 @@ ISRKEYRPT: LD A,(KEYCOUNT) ; Get c LD (KEYWRITE),HL ; Store updated pointer. ; ISREXIT: -MEMSW3: IF BUILD_TZFS+BUILD_RFS > 0 +MEMSW3: IF BUILD_MZ700+BUILD_TZFS > 0 LD A,TZMM_MZ700_2 ; Return to the full 64K memory mode. OUT (MMCFG),A ENDIF @@ -6212,7 +6263,7 @@ ISRKEYRPT: LD A,(KEYCOUNT) ; Get c LD (KEYWRITE),HL ; Store updated pointer. ; ISREXIT -MEMSW3: IF BUILD_TZFS+BUILD_RFS > 0 +MEMSW3: IF BUILD_MZ700+BUILD_TZFS > 0 LD A,TZMM_MZ700_2 ; Return to the full 64K memory mode. OUT (MMCFG),A ENDIF @@ -6633,6 +6684,7 @@ KTBLC: ; CONTROL CODE ;------------------------------------------------------------------------------- ; SERVICE COMMAND METHODS ;------------------------------------------------------------------------------- +SVC_CMD: IF BUILD_TZFS = 1 ; Method to send a command to the I/O processor and verify it is being acted upon. ; THe method, after sending the command, polls the service structure result to see if the I/O processor has updated it. If it doesnt update the result @@ -6645,7 +6697,7 @@ KTBLC: ; CONTROL CODE ; A = 0 - Success, command being processed. ; A = 1 - Failure, no contact with I/O processor. ; A = 2 - Failure, no result from I/O processor, it could have crashed or SD card removed! -SVC_CMD: PUSH BC + PUSH BC LD (TZSVCCMD), A ; Load up the command into the service record. LD A,TZSVC_STATUS_REQUEST LD (TZSVCRESULT),A ; Set the service structure result to REQUEST, if this changes then the K64 is processing. @@ -6705,6 +6757,7 @@ SVC_CMD6: XOR A ; Succe POP BC RET + ENDIF ;------------------------------------------------------------------------------- ; END OF SERVICE COMMAND METHODS ;------------------------------------------------------------------------------- @@ -6989,14 +7042,14 @@ TIMESET: LD (TIMESEC),HL ; Load TIMESET1: IF BUILD_MZ80A = 1 LD (01039H),IX ENDIF -TIMESET2: IF BUILD_TZFS+BUILD_RFS > 0 +TIMESET2: IF BUILD_MZ700+BUILD_TZFS > 0 LD (00039H),IX ENDIF RET ; Time Read; ; Returns BC:DE:HL where HL is lower 16bits, DE is middle 16bits and BC is upper 16bits of milliseconds since 01/01/1980. -TIMEREAD: LD HL,(TIMESEC+4) +TIMEREAD: LD HL,(TIMESEC+4) PUSH HL POP BC LD HL,(TIMESEC+2) @@ -7317,29 +7370,33 @@ L098C: SUB 00AH ; Delete a character on screen. DELETECHR: LD A,0C7H CALL DPCT - JR PRNT1 + JP PRNT1 NEWLINE: CALL NL - JR PRNT1 + JP PRNT1 ; ; Function to disable the cursor display. ; -CURSOROFF: DI +CURSOROFF: PUSH HL + DI CALL CURSRSTR ; Restore character under the cursor. LD HL,FLASHCTL ; Indicate cursor is now off. RES 7,(HL) EI + POP HL RET ; ; Function to enable the cursor display. ; -CURSORON: DI +CURSORON: PUSH HL + DI CALL DSPXYTOADDR ; Update the screen address for where the cursor should appear. LD HL,FLASHCTL ; Indicate cursor is now on. SET 7,(HL) EI + POP HL RET ; @@ -7393,7 +7450,7 @@ PRNT: DI LD (SPISRSAVE),SP ; Share the interrupt stack for banked access as the BASIC stack goes out of scope. LD SP,ISRSTACK ; Interrupts are disabled so we can safely use this stack. ; -MEMSW4: IF BUILD_TZFS+BUILD_RFS > 0 +MEMSW4: IF BUILD_MZ700+BUILD_TZFS > 0 PUSH AF LD A,TZMM_MZ700_0 ; Enable access to the hardware by paging out the upper bank. OUT (MMCFG),A @@ -7408,7 +7465,7 @@ MEMSW4: IF BUILD_TZFS+BUILD_RFS > 0 CP 07FH JR Z,DELETECHR CP BACKS - JR Z,DELETECHR + JP Z,DELETECHR PUSH BC LD C,A LD B,A @@ -7417,7 +7474,7 @@ MEMSW4: IF BUILD_TZFS+BUILD_RFS > 0 POP BC PRNT1: CALL DSPXYTOADDR ; -MEMSW5: IF BUILD_TZFS+BUILD_RFS > 0 +MEMSW5: IF BUILD_MZ700+BUILD_TZFS > 0 LD A,TZMM_MZ700_2 ; Enable access to the hardware by paging out the upper bank. OUT (MMCFG),A ENDIF @@ -7436,7 +7493,10 @@ PRNTSTR: LD A,(DE) CALL CURSRSTR ; Restore char under cursor. CP 00DH JR NZ,PRNTSTR2 -PRNTSTR1: LD A,0CDH +PRNTSTR1: LD A,(DPRNT) + OR A + JR Z,PRNTSTR5 + LD A,0CDH CALL DPCT JR PRNTSTR5 PRNTSTR2: CP 00AH @@ -7611,14 +7671,15 @@ CLRS: LD HL,MANG LD B,01BH CALL CLER LD HL,SCRN + ;PUSH HL CALL CLR8Z - IF MODE80C = 0 - LD A,071H ; Black background, white characters. Bit 7 is clear as a write to bit 7 @ DFFFH selects 40Char mode. + ;POP HL + IF BUILD_80C = 0 + LD A,071H ; Black background, white characters. Bit 7 is clear as a write to bit 7 @ DFFFH selects 40Char mode. ELSE - LD A,071H ; Blue background, white characters in colour mode. Bit 7 is set as a write to bit 7 @ DFFFH selects 80Char mode. + LD A,071H ; Blue background, white characters in colour mode. Bit 7 is set as a write to bit 7 @ DFFFH selects 80Char mode. ENDIF CALL CLR8 ; D800H-DFFFH CLEAR - CLRS1: LD A,(SCLDSP) HOM0: LD HL,00000H JP CURS3 @@ -8128,7 +8189,7 @@ WTAP3: POP HL LD BC,00080H LD HL,IBUFE RD1: DI -MEMSWRT0: IF BUILD_TZFS+BUILD_RFS > 0 +MEMSWRT0: IF BUILD_MZ700+BUILD_TZFS > 0 LD (SPISRSAVE),SP ; Share the interrupt stack whilst accessing hardware as the BASIC stack goes out of scope. LD SP,ISRSTACK ; Interrupts are disabled so we can safely use this stack. LD A,TZMM_MZ700_0 ; We meed to be in memory mode 10 to access the tape hardware. @@ -8177,7 +8238,7 @@ RTP2: CALL EDGE RTP3: CALL RBYTE JP C,RTP6 ; For TZFS/RFS page in top bank of memory for potential data store. -MEMSWRT1: IF BUILD_TZFS+BUILD_RFS > 0 +MEMSWRT1: IF BUILD_MZ700+BUILD_TZFS > 0 EX AF,AF' LD A,TZMM_MZ700_2 OUT (MMCFG),A @@ -8207,7 +8268,7 @@ MEMSWRT1: IF BUILD_TZFS+BUILD_RFS > 0 JP NZ,RTP5 RTP8: XOR A RET2: CALL MSTOP -MEMSWRT4: IF BUILD_TZFS+BUILD_RFS > 0 +MEMSWRT4: IF BUILD_MZ700+BUILD_TZFS > 0 EX AF,AF' LD A,TZMM_MZ700_2 ; Return to the full 64K memory mode. OUT (MMCFG),A @@ -9019,7 +9080,7 @@ CALC3: POP DE ; BC = length CLRSCRN: DI ; -MEMSW6: IF BUILD_TZFS+BUILD_RFS > 0 +MEMSW6: IF BUILD_MZ700+BUILD_TZFS > 0 LD A,TZMM_MZ700_0 ; Enable access to the hardware by paging out the upper bank. OUT (MMCFG),A ENDIF @@ -9044,7 +9105,7 @@ MEMSW6: IF BUILD_TZFS+BUILD_RFS > 0 LD (HL),A LDIR -MEMSW7: IF BUILD_TZFS+BUILD_RFS > 0 +MEMSW7: IF BUILD_MZ700+BUILD_TZFS > 0 LD A,TZMM_MZ700_2 ; Enable access to the hardware by paging out the upper bank. OUT (MMCFG),A ENDIF @@ -9228,7 +9289,7 @@ COLOUR EQU 0 REBOOT: DI -REBOOTTZ: IF BUILD_TZFS +BUILD_RFS > 0 +REBOOTTZ: IF BUILD_MZ700+BUILD_TZFS > 0 LD A,TZMM_TZFS OUT (MMCFG),A ENDIF @@ -9259,9 +9320,21 @@ REBOOT80A: IF BUILD_MZ80A = 1 ;-------------------------------------- BFREE: DB " Bytes free",CR,LF,0,0 -SIGNON: DB "MZ-80A BASIC Ver 4.7b",CR,LF - DB "Copyright ",40,"C",41 - DB " 1978 by Microsoft",CR,LF,0,0 +SIGNON: IF BUILD_TZFS = 1 + DB "Microsoft Basic (TZFS) Ver 4.7b",CR,LF + DB "Copyright ",40,"C",41 + DB " 1978 by Microsoft",CR,LF,0,0 + ENDIF + IF BUILD_MZ700 = 1 + DB "Microsoft Basic (MZ-700) Ver 4.7b",CR,LF + DB "Copyright ",40,"C",41 + DB " 1978 by Microsoft",CR,LF,0,0 + ENDIF + IF BUILD_MZ80A = 1 + DB "Microsoft Basic (MZ-80A) Ver 4.7b",CR,LF + DB "Copyright ",40,"C",41 + DB " 1978 by Microsoft",CR,LF,0,0 + ENDIF SVCRESPERR: DB "I/O Response Error, time out!", CR, NUL SVCIOERR: DB "I/O Error, time out!", CR, NUL MSGRECORD: DB CR, "Press RECORD+PLAY", CR, NUL @@ -9459,7 +9532,7 @@ CODEEND: ; For TZFS builds the image needs to be relocated from 0x1200 to 0x0000 on startup after switching the memory mode. -RELOCSTART: IF BUILD_TZFS+BUILD_RFS > 0 +RELOCSTART: IF BUILD_MZ700+BUILD_TZFS > 0 ORG $ + 1200H ; Switch memory. @@ -9473,50 +9546,50 @@ RELOC: LD A, TZMM_MZ700_0 ; Switc LDIR JP 0000H - ; For RFS builds a two stage relocation is needed, a) relocate to tranzputer RAM, b) run the TZFS relocation code. -RELOC_RFS: IF BUILD_RFS = 1 - - ; Switch memory. -RELOCRFS: LD A, TZMM_BOOT ; Go to boot mode, copy the relocation code to EC80H and execute. - OUT (MMCFG),A - - ; Move the relocation code to EC80H. - LD DE, 0EC80H - LD HL, RELOCRFS2 - LD BC, RELOCRFS2END - RELOCRFS2 - LDIR - JP 0EC80H ; Run the relocation code. - - ENDIF +; ; For RFS builds a two stage relocation is needed, a) relocate to tranzputer RAM, b) run the TZFS relocation code. +;RELOC_RFS: IF BUILD_RFS = 1 +; +; ; Switch memory. +;RELOCRFS: LD A, TZMM_BOOT ; Go to boot mode, copy the relocation code to EC80H and execute. +; OUT (MMCFG),A +; +; ; Move the relocation code to EC80H. +; LD DE, 0EC80H +; LD HL, RELOCRFS2 +; LD BC, RELOCRFS2END - RELOCRFS2 +; LDIR +; JP 0EC80H ; Run the relocation code. +; +; ENDIF RELOCEND: - -RELOCRFS2: ; Move the image down into tranZPUter memory and then start the real relocation. - LD HL, 01200H - LD BC, (CODEEND - CODESTART) + (RELOCEND - RELOC) ; Size of program. - - ; Fetch a byte from main DRAM and write it into Bank 0 same location. -RELOCRFS2_1:LD A,TZMM_BOOT - OUT (MMCFG),A - LD A,(HL) - ; - EX AF,AF' - LD A,TZMM_TZFS - OUT (MMCFG),A - EX AF,AF' - ; - LD (HL),A - INC HL - DEC BC - LD A,B - OR C - JR NZ, RELOCRFS2_1 - ; - LD DE, 00000H ; Copy the reboot handler into Bank 0 at 00000H. - LD HL, 0EC80H + (REBOOTRFS - RELOCRFS2) - LD BC, RELOCRFS2END - REBOOTRFS - LDIR - ; - JP RELOC ; Jump into the original TZFS relocation code. +; +;RELOCRFS2: ; Move the image down into tranZPUter memory and then start the real relocation. +; LD HL, 01200H +; LD BC, (CODEEND - CODESTART) + (RELOCEND - RELOC) ; Size of program. +; +; ; Fetch a byte from main DRAM and write it into Bank 0 same location. +;RELOCRFS2_1:LD A,TZMM_BOOT +; OUT (MMCFG),A +; LD A,(HL) +; ; +; EX AF,AF' +; LD A,TZMM_TZFS +; OUT (MMCFG),A +; EX AF,AF' +; ; +; LD (HL),A +; INC HL +; DEC BC +; LD A,B +; OR C +; JR NZ, RELOCRFS2_1 +; ; +; LD DE, 00000H ; Copy the reboot handler into Bank 0 at 00000H. +; LD HL, 0EC80H + (REBOOTRFS - RELOCRFS2) +; LD BC, RELOCRFS2END - REBOOTRFS +; LDIR +; ; +; JP RELOC ; Jump into the original TZFS relocation code. ; Reboot handler for RFS mode. This code is transferred into RAM bank 0 at 0000H as this is not used for BASIC ; and executed when a return to the Monitor ROM is needed. Location 004AH in the Monitor ROM is the startup vector. @@ -9541,7 +9614,12 @@ KEYREAD: DS virtual 2 ; Point KEYLAST: DS virtual 1 ; Last key value KEYRPT: DS virtual 1 ; Key repeat counter +MONVARSTRT: EQU $ + ; For MZ80A or MZ80A with RFS we share the original monitor variable space. + IF BUILD_MZ80A > 0 + ORG 010F0H + ENDIF SPV: IBUFE: ; TAPE BUFFER (128 BYTES) ATRB: DS virtual 1 ; ATTRIBUTE @@ -9565,17 +9643,26 @@ ROLEND: DS virtual 1 ; ROLL FLASH: DS virtual 1 ; FLASHING DATA SFTLK: DS virtual 1 ; SHIFT LOCK REVFLG: DS virtual 1 ; REVERSE FLAG +SPAGE: DS virtual 1 ; PAGE CHANGE FLSDT: DS virtual 1 ; CURSOR DATA STRGF: DS virtual 1 ; STRING FLAG DPRNT: DS virtual 1 ; TAB COUNTER TMCNT: DS virtual 2 ; TAPE MARK COUNTER SUMDT: DS virtual 2 ; CHECK SUM DATA CSMDT: DS virtual 2 ; FOR COMPARE SUM DATA +AMPM: DS virtual 1 ; AMPM DATA +TIMFG: DS virtual 1 ; TIME FLAG SWRK: DS virtual 1 ; KEY SOUND FLAG TEMPW: DS virtual 1 ; TEMPO WORK ONTYO: DS virtual 1 ; ONTYO WORK OCTV: DS virtual 1 ; OCTAVE WORK RATIO: DS virtual 2 ; ONPU RATIO + + ; Remaining variables inside MS-BASIC variable space. + IF BUILD_MZ80A > 0 + ORG MONVARSTRT + ENDIF + DSPXYADDR: DS virtual 2 ; Address of last known position. FLASHCTL: DS virtual 1 ; CURSOR FLASH CONTROL. BIT 0 = Cursor On/Off, BIT 1 = Cursor displayed. diff --git a/software/asm/cbios.asm b/software/asm/cbios.asm index 480b1b3..dee833c 100644 --- a/software/asm/cbios.asm +++ b/software/asm/cbios.asm @@ -35,6 +35,7 @@ ;-------------------------------------------------------------------------------------------------------- ; Bring in additional macros. + INCLUDE "CPM_BuildVersion.asm" INCLUDE "CPM_Definitions.asm" INCLUDE "Macros.asm" diff --git a/software/asm/cbiosII.asm b/software/asm/cbiosII.asm index 5d1a6d0..48d8e8f 100644 --- a/software/asm/cbiosII.asm +++ b/software/asm/cbiosII.asm @@ -258,33 +258,37 @@ INIT3: ; Setup keyboard buffer control. LD A,080H ; Cursor on (Bit D7=1). LD (FLASHCTL),A -INIT80CHAR: IF BUILD_VIDEOMODULE = 1 - IN A, (CPLDINFO) ; Get hardware information. - BIT 3,A - JR Z, INIT40CHAR ; If no video module present then need to use 40 char mode. - AND 007H - LD D, A - OR MODE_VIDEO_FPGA ; Ensure the video hardware is enabled. - OUT (CPLDCFG),A - LD A, D - OR MODE_80CHAR ; Enable 80 char display. - LD C, A - IN A, (VMCTRL) ; Get current graphics mode and vga mode. - AND 0C0H ; Mask out all but VGA mode. - OR C ; Add in new hardware/80char mode. - OUT (VMCTRL),A ; Activate. - LD A, D - CP MODE_MZ80A ; Check to see if this is the MZ80A, if so, change BUS speed. - JR NZ, INIT80END - ; LD A, SYSMODE_MZ80B ; Set bus and default CPU speed to 4MHz - ; OUT (SYSCTRL),A ; Activate. - JR INIT80END -INIT40CHAR: ; Currently nothing to do! - ELSE - ; Change to 80 character mode on the 40/80 Char Colour board v1.0. - LD A, 128 ; 80 char mode. - LD (DSPCTL), A + ; Initialise the display, either the Video Module, 40/80 Colour Card or standard 40 column display. + IF BUILD_VIDEOMODULE = 1 + IN A, (CPLDINFO) ; Get hardware information. + BIT 3,A + JR Z, INIT80CHAR ; If no video module present then see if the 40/80 column board installed else need to use 40 char mode. + AND 007H + LD D, A + OR MODE_VIDEO_FPGA ; Ensure the video hardware is enabled. + OUT (CPLDCFG),A + LD A, D + OR MODE_80CHAR ; Enable 80 char display. + LD C, A + IN A, (VMCTRL) ; Get current graphics mode and vga mode. + AND 0C0H ; Mask out all but VGA mode. + OR C ; Add in new hardware/80char mode. + OUT (VMCTRL),A ; Activate. + LD A, D + CP MODE_MZ80A ; Check to see if this is the MZ80A, if so, change BUS speed. + JR NZ, INIT80END + ; LD A, SYSMODE_MZ80B ; Set bus and default CPU speed to 4MHz + ; OUT (SYSCTRL),A ; Activate. + JR INIT80END ENDIF +INIT80CHAR: IF BUILD_80C = 1 + LD HL,DSPCTL ; Setup address of display control register latch. + LD A, 128 ; 80 char mode. + LD E,(HL) ; Dummy operation to enable latch write via multivibrator. + LD (HL), A + ENDIF + ; + ; If no video module and no 40/80 Colour Card then the default will be 40 column display. ; INIT80END: LD A,016H CALL PRNT @@ -306,34 +310,37 @@ INIT80END: LD A,016H LD (IOBYT),A LD (CDISK),A + ; DRVAVAIL flag definition. Version 1.25 - removed ROM Drives and RAM drives as they provided no speed or use benefit compared with SD drives. + ; + ; 1 = Active. + ; + ; 7 6 5 4 3 2 1 0 + ; ^ ^ ^ ^ ^ ^ ^ ^ + ; | | | | | | | |-- Floppy Drive Present + ; | | | | | | |---- ROM Drive Present + ; | | | | | |------ SD Card Present + ; | | | | |-------- RAM Drive Present + ; | | | |---------- + ; | | |------------ + ; | |-------------- + ; |---------------- Drives present ; ; Initialise the disk subsystem. ; LD A,0 ; No drives yet detected so zero available mask. SET 2,A ; The SD Card is always present on the I/O processor, we cant run without it.. ; - PUSH AF ; Output indicator that SDC drives are available. LD DE,SDAVAIL - CALL MONPRTSTR - POP AF - SET 7,A - LD (DRVAVAIL),A + CALL PRTSTRTMSG + ; CALL DSKINIT ; Initialise the floppy disk subsystem. JR NZ,STRT5 LD A,(DRVAVAIL) SET 0,A ; Indicate Floppy drives are available. - PUSH AF ; Output indicator that FDC drives are available. - BIT 7,A - JR Z,STRT4 - LD A,',' - CALL PRNT -STRT4: LD DE,FDCAVAIL - CALL MONPRTSTR - POP AF - SET 7,A - LD (DRVAVAIL),A + LD DE,FDCAVAIL ; Output indicator that FDC drives are available. + CALL PRTSTRTMSG ; STRT5: LD DE,CBIOSIGNEND ; Terminate the signon message which now includes list of drives detected. CALL MONPRTSTR @@ -347,63 +354,18 @@ STRT5: LD DE,CBIOSIGNEND ; Termi LD (CDIRBUF),A LD HL,CSVALVMEM LD (CDIRBUF+1),HL - ; - ; 16MB SD Card Drives. - ; - LD BC,0 ; Setup CSV/ALV parameters for a 16MB SD Card drive. - LD (CDIRBUF+3),BC - LD BC,257 ; 2048/8 + 1 - LD (CDIRBUF+5),BC - LD BC,DPB4 - LD (CDIRBUF+7),BC ; Address of Disk Parameters -STRT7: LD A,(CDIRBUF) - CP MAXDISKS - 2 ; Make sure we have parameter table entries available to add further drives, ensuring slots for the FDC. - JR Z,STRT8 - ; - LD (TZSVC_FILE_NO),A ; Indicate the drive number the file will be attached to. - LD A,TZSVC_CMD_ADDSDDRIVE ; I/O processor command to attach a CPM drive to the file number given. - CALL SVC_CMD - OR A - JP NZ, STRT8 ; No drive available, skip. - ; - CALL COPYDPB ; Copy parameters for this disk. - ; - ; Now add as many additional SD drives as we have RAM - ; and config tables available within the CBIOS. - ; - LD BC,(CDIRBUF+1) - LD HL,CSVALVEND - 2048/8 + 1 ; Subtract the size of the ALV (CSV has no size for a fixed SD drive) - OR A - SBC HL,BC - JR C,STRT8 ; If there is no more space, exit. - JR STRT7 ; Add another, keep on adding until there is no more ALV Memory free. - ; + + ; Add as many SD Drives as RAM permits. +STRT6: CALL ADDSDDRIVE ; Add a drive, NZ return means error, memory limit or max disks reached. + JR NZ,STRT8 + JR STRT6 + ; Setup the 1.44MB Floppy Disk Drives. ; -STRT8: LD A,(DRVAVAIL) - BIT 0,A - JR Z,STRT10 ; No Floppy drives available then skip. +STRT8: CALL ADDFLPYDRV + CALL ADDFLPYDRV ; No Floppy drives available then skip. ; - LD BC,128/4 ; Setup CSV/ALV parameters for a 1.4MB Floppy drive. - LD (CDIRBUF+3),BC - LD BC,91 ; 720/8 + 1 - LD (CDIRBUF+5),BC - LD BC,DPB3 - LD (CDIRBUF+7),BC ; Address of Disk Parameters -STRT9: LD A,(CDIRBUF) - CP MAXDISKS ; Use the disk count to ensure we only add upto 2 FDC drives. - JR Z,STRT10 - ; - LD BC,(CDIRBUF+1) ; Make sure there is memory available for the FDC drives. - LD HL,CSVALVEND - 720/8 + 1 - OR A - SBC HL,BC - JR C,STRT10 ; If there is no more space, exit. - ; - CALL COPYDPB ; Setup the FDC. - JR STRT9 - ; -STRT10: LD A,(CDIRBUF) + LD A,(CDIRBUF) LD (NDISKS),A ; Setup max number of system disks found on this boot up. ; Setup timer interrupts @@ -460,6 +422,84 @@ CPMINIT2: CALL SETDRVMAP ; Refre LD C, A ; C = current User/Disk for CCP jump (UUUUDDDD) JP BOOT_ ; Cold boot CPM now that most initialisation is complete. This is a direct jump to the fixed bios area 0xF000 + ; Method to add an SD drive into the CPM disk definitions. + ; If the SD controller hasnt been detected the routine exits without configuration. +ADDSDDRIVE: LD A,(DRVAVAIL) + BIT 2,A + JR Z,ADDSDDRVEX ; No SD interface so skip. + ; + ; 16MB SD Card Drives. + ; + LD BC,0 ; Setup CSV/ALV parameters for a 16MB SD Card drive. + LD (CDIRBUF+3),BC + LD BC,257 ; 2048/8 + 1 + LD (CDIRBUF+5),BC + LD BC,DPB4 + LD (CDIRBUF+7),BC ; Address of Disk Parameters + + LD A,(CDIRBUF) + CP MAXDISKS - 2 ; Make sure we have parameter table entries available to add further drives, ensuring slots for the FDC. + JR Z,ADDSDDRVEX + ; + LD (TZSVC_FILE_NO),A ; Indicate the drive number the file will be attached to. + LD A,TZSVC_CMD_ADDSDDRIVE ; I/O processor command to attach a CPM drive to the file number given. + CALL SVC_CMD + OR A + JR NZ,ADDSDDRVEX ; No drive available, skip. + ; + ; Check that RAM is available to add this drive. + ; + LD BC,(CDIRBUF+1) + LD HL,CSVALVEND - 2048/8 + 1 ; Subtract the size of the ALV (CSV has no size for a fixed SD drive) + OR A + SBC HL,BC + JR C,ADDSDDRVEX ; If there is no more space, exit. + + CALL COPYDPB ; Add in an SD drive. + XOR A + RET +ADDSDDRVEX: LD A,1 + OR A + RET + + ; Method to add a Floppy drive into the CPM disk definitions table. + ; If the Floppy controller hasnt been detected then skip without configuration. +ADDFLPYDRV: LD A,(DRVAVAIL) + BIT 0,A + JR Z,ADDSDDRVEX ; No Floppy drives available then skip. + + LD A,(CDIRBUF) + CP MAXDISKS ; Use the disk count to ensure we only add upto 2 FDC drives. + JR Z,ADDSDDRVEX + + LD BC,128/4 ; Setup CSV/ALV parameters for a 1.4MB Floppy drive. + LD (CDIRBUF+3),BC + LD BC,91 ; 720/8 + 1 + LD (CDIRBUF+5),BC + LD BC,DPB3 + LD (CDIRBUF+7),BC ; Address of Disk Parameters + + LD BC,(CDIRBUF+1) ; Make sure there is memory available for the FDC drives. + LD HL,CSVALVEND - 720/8 + 1 + OR A + SBC HL,BC + JR C,ADDSDDRVEX ; If there is no more space, exit. + CALL COPYDPB ; Add in a floppy drive. + + XOR A + RET + + ; Helper method to print a message with a comma if Bit 7 of A is set. +PRTSTRTMSG: PUSH AF + BIT 7,A + JR Z,PRTCOMMA1 + LD A,',' + CALL PRNT +PRTCOMMA1: CALL MONPRTSTR + POP AF + SET 7,A + LD (DRVAVAIL),A + RET ;------------------------------------------------------------------------------- ; WBOOT @@ -2066,15 +2106,18 @@ REBOOT: LD A,TZMM_TZFS ; Switch machine back to default state. IF BUILD_VIDEOMODULE = 1 - IN A,(VMCTRL) ; Get current display mode. - AND ~MODE_80CHAR ; Disable 80 char display. - OUT (VMCTRL),A ; Activate. - ; LD A, SYSMODE_MZ80A ; Set bus and default CPU speed to 2MHz - ; OUT (SYSCTRL),A ; Activate. + IN A,(VMCTRL) ; Get current display mode. + AND ~MODE_80CHAR ; Disable 80 char display. + OUT (VMCTRL),A ; Activate. + ; LD A, SYSMODE_MZ80A ; Set bus and default CPU speed to 2MHz + ; OUT (SYSCTRL),A ; Activate. ELSE - ; Change to 40 character mode on the 40/80 Char Colour board v1.0. - LD A, 0 ; 40 char mode. - LD (DSPCTL), A + ; Change to 40 character mode on the 40/80 Char Colour board v1.0. + LD (DSPCTL), A + LD HL,DSPCTL ; Setup address of display control register latch. + LD A, 0 ; 40 char mode. + LD E,(HL) ; Dummy operation to enable latch write via multivibrator. + LD (HL), A ENDIF ; JP MROMADDR ; Now restart in the SA1510 monitor. @@ -2146,8 +2189,10 @@ PRCKY6: CP DBLZERO ; 00 JR PRCKYX PRCKY7: CP BREAKKEY ; Break key processing. JR NZ,PRCKY8 - -PRCKY8: + JR PRCKYE +PRCKY8: CP DELETE + JR NZ,PRCKYX + LD A,BACKS ; Map DELETE to BACKSPACE, BACKSPACE is Rubout, DELETE is echo in CPM. PRCKYX: PRCKYE: POP HL @@ -2188,7 +2233,7 @@ PRCKYE: LDIR LD B,COLW ; ONE LINE EX DE,HL - IF MODE80C = 0 + IF BUILD_80C = 0 LD A,071H ; Black background, white characters. Bit 7 is clear as a write to bit 7 @ DFFFH selects 40Char mode. ELSE LD A,071H ; Blue background, white characters in colour mode. Bit 7 is set as a write to bit 7 @ DFFFH selects 80Char mode. @@ -2530,7 +2575,7 @@ CLRS: LD HL,MANG LD HL,SCRN PUSH HL CALL CLR8Z - IF MODE80C = 0 + IF BUILD_80C = 0 LD A,071H ; Black background, white characters. Bit 7 is clear as a write to bit 7 @ DFFFH selects 40Char mode. ELSE LD A,071H ; Blue background, white characters in colour mode. Bit 7 is set as a write to bit 7 @ DFFFH selects 80Char mode. @@ -3577,9 +3622,22 @@ DPBTMPL: DW 0000H, 0000H, 0000H, 0000H, CDIRBUF ; Test Message table ;-------------------------------------- -CBIOSSIGNON:DB "** C-BIOS v1.10, (C) P.D. Smart, 2020. Drives:", NUL -CBIOSIGNEND:DB " **", CR, NUL -CPMSIGNON: DB "CP/M v2.23 (64K) COPYRIGHT(C) 1979, DIGITAL RESEARCH", CR, LF, NUL +CBIOSSIGNON:IF BUILD_80C = 1 + DB "** CBIOS v1.12, (C) P.D. Smart, 2019-21. Drives:", NUL + ELSE + DB "CBIOS v1.12, (C) P.D. Smart, 2019-21.", CR + DB "Drives:", NUL + ENDIF +CBIOSIGNEND:IF BUILD_80C = 1 + DB " **", CR, NUL + ELSE + DB CR, NUL + ENDIF +CPMSIGNON: IF BUILD_80C = 1 + DB "CP/M v2.23 (64K) Copyright(c) 1979 by Digital Research", CR, LF, NUL + ELSE + DB "CP/M v2.23 (c) 1979 by Digital Research", CR, LF, NUL + ENDIF SDAVAIL: DB "SD", NUL FDCAVAIL: DB "FDC", NUL NOBDOS: DB "I/O Processor failed to load BDOS, aborting!", CR, LF, NUL diff --git a/software/asm/cpm22.asm b/software/asm/cpm22.asm index 63eb630..96661a6 100644 --- a/software/asm/cpm22.asm +++ b/software/asm/cpm22.asm @@ -7,6 +7,11 @@ ;* by Clark A. Calkins ;* ;************************************************************** + + ; Bring in definitions and macros. + INCLUDE "CPM_BuildVersion.asm" + INCLUDE "CPM_Definitions.asm" + INCLUDE "Macros.asm" ; ; Set memory limit here. This is the amount of contigeous ; ram starting from 0000. CP/M will reside at the end of this space. @@ -59,12 +64,16 @@ CCPFIRS EQU CBASE + 8 ; Address of the first charater of the CCP in ; INBUFF: DB 127 ;length of input buffer. DB 0 ;current length of contents. - DB "Copyright" - DB " 1979 (c) by Digital Research " - DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + IF BUILD_80C = 1 + DB "CP/M v2.23 (64K) Copyright(c) 1979 by Digital Research", 00DH, 00AH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; 68 chars + ELSE + DB "CP/M v2.23 (c) 1979 by Digital Research", 00DH, 00AH, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; 68 chars + ENDIF + ;DB "Copyright" + ;DB " 1979 (c) by Digital Research " + DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 INPOINT:DW INBUFF+2 ;input line pointer NAMEPNT:DW 0 ;input line pointer used for error message. Points to ; ;start of name in error. @@ -831,7 +840,11 @@ DIRECT3:JP Z,DIRECT9 ;terminate if no more names. LD A,E ;bump name count. INC E PUSH DE - AND 03H ;at end of line? + IF BUILD_80C = 1 + AND 03H ;at end of line? + ELSE + AND 01H ;at end of line? + ENDIF PUSH AF JP NZ,DIRECT4 CALL CRLF ;yes, end this line and start another. @@ -3742,8 +3755,7 @@ CKSUMTBL: DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; MZ-80A CPM BIOS STUB - Main Logic in CBIOS.ASM ;----------------------------------------------------------------------- - INCLUDE "Macros.asm" - INCLUDE "CPM_Definitions.asm" + ; Bring in the CBIOS stub, has the bootstrap code and DPB place markers. INCLUDE "cpm22-bios.asm" ALIGN_NOPS CBIOSSTART diff --git a/software/asm/include/CPM_BuildVersion.asm b/software/asm/include/CPM_BuildVersion.asm new file mode 100644 index 0000000..cdc5619 --- /dev/null +++ b/software/asm/include/CPM_BuildVersion.asm @@ -0,0 +1 @@ +BUILD_VERSION EQU 2 diff --git a/software/asm/include/CPM_Definitions.asm b/software/asm/include/CPM_Definitions.asm index 5936add..0f0cfd9 100644 --- a/software/asm/include/CPM_Definitions.asm +++ b/software/asm/include/CPM_Definitions.asm @@ -14,6 +14,7 @@ ; additional and different hardware. The SPI is now onboard the PCB and ; not using the printer interface card. ; May 2020 - Cut from the RFS version of CPM for the tranZPUter SW board. +;- Apr 2021 - Updates backported from the RFS version of CPM. ;- ;-------------------------------------------------------------------------------------------------------- ;- This source file is free software: you can redistribute it and-or modify @@ -33,9 +34,59 @@ ;----------------------------------------------- ; Features. ;----------------------------------------------- -BUILD_VIDEOMODULE EQU 1 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0 -BUILD_MZ80A EQU 0 ; Build for the Sharp MZ-80A base hardware. -BUILD_MZ700 EQU 1 ; Build for the Sharp MZ-700 base hardware. + ; CPM for MZ-700 with with Video Module and 80 Columns display. + IF BUILD_VERSION = 0 +BUILD_VIDEOMODULE EQU 1 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0 +BUILD_MZ80A EQU 0 ; Build for the Sharp MZ-80A base hardware. +BUILD_MZ700 EQU 1 ; Build for the Sharp MZ-700 base hardware. +BUILD_80C EQU 1 ; Build for an 80 column (Video Module or 40/80 Colour Card) equipped machine, 0 = standard 40 column. + ENDIF + ; CPM for MZ-80A with with Video Module (if not present expects 40/80 Colour Board) and 80 Columns display. + IF BUILD_VERSION = 1 +BUILD_VIDEOMODULE EQU 1 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0 +BUILD_MZ80A EQU 1 ; Build for the Sharp MZ-80A base hardware. +BUILD_MZ700 EQU 0 ; Build for the Sharp MZ-700 base hardware. +BUILD_80C EQU 1 ; Build for an 80 column (Video Module or 40/80 Colour Card) equipped machine, 0 = standard 40 column. + ENDIF + ; CPM for MZ-80A with with standard 40 column display. + IF BUILD_VERSION = 2 +BUILD_VIDEOMODULE EQU 0 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0 +BUILD_MZ80A EQU 1 ; Build for the Sharp MZ-80A base hardware. +BUILD_MZ700 EQU 0 ; Build for the Sharp MZ-700 base hardware. +BUILD_80C EQU 0 ; Build for an 80 column (Video Module or 40/80 Colour Card) equipped machine, 0 = standard 40 column. + ENDIF + +;----------------------------------------------- +; Configurable settings. +;----------------------------------------------- +MAXRDRETRY EQU 002h +MAXWRRETRY EQU 002h +BLKSIZ EQU 4096 ; CP/M allocation size +HSTSIZ EQU 512 ; host disk sector size +HSTSPT EQU 32 ; host disk sectors/trk +HSTBLK EQU HSTSIZ/128 ; CP/M sects/host buff +CPMSPT EQU HSTBLK * HSTSPT ; CP/M sectors/track +SECMSK EQU HSTBLK-1 ; sector mask +WRALL EQU 0 ; write to allocated +WRDIR EQU 1 ; write to directory +WRUAL EQU 2 ; write to unallocated +TMRTICKINTV EQU 5 ; Number of 0.010mSec ticks per interrupt, ie. resolution of RTC. +MTROFFMSECS EQU 100 ; Time from last access to motor being switched off in seconds in TMRTICKINTV ticks. + IF BUILD_80C = 1 +COLW EQU 80 ; Width of the display screen (ie. columns). + ELSE +COLW EQU 40 ; Width of the display screen (ie. columns). + ENDIF +ROW EQU 25 ; Number of rows on display screen. +SCRNSZ EQU COLW * ROW ; Total size, in bytes, of the screen display area. +SCRLW EQU COLW / 8 ; Number of 8 byte regions in a line for hardware scroll. + +; BIOS equates +MAXDISKS EQU 7 ; Max number of Drives supported +KEYBUFSIZE EQU 64 ; Ensure this is a power of 2, max size 256. + +; Debugging +ENADEBUG EQU 1 ; Enable debugging logic, 1 = enable, 0 = disable ;----------------------------------------------- ; Entry/compilation start points. @@ -46,6 +97,7 @@ CPMCCP EQU CBASE ; CP/M CPMBDOS EQU CPMCCP + 0806H ; BDOS entry CPMBIOS EQU CPMCCP + 01600H ; Original CPM22 BIOS entry CBIOSSTART EQU CPMBIOS ; Start of the actual CBIOS code. +CPMCOPYRMSG EQU CBASE+8 ; Copyright message stored in CP/M binary. BOOT EQU CBIOSSTART + 0 WBOOT EQU CBIOSSTART + 3 WBOOTE EQU CBIOSSTART + 3 @@ -83,36 +135,6 @@ FDCJMP2BLK EQU 0F7FEH ; The m FDCJMP2 EQU 0F7FEH ; ROM paged vector 2. -;----------------------------------------------- -; Configurable settings. -;----------------------------------------------- -MAXRDRETRY EQU 002h -MAXWRRETRY EQU 002h -BLKSIZ EQU 4096 ; CP/M allocation size -HSTSIZ EQU 512 ; host disk sector size -HSTSPT EQU 32 ; host disk sectors/trk -HSTBLK EQU HSTSIZ/128 ; CP/M sects/host buff -CPMSPT EQU HSTBLK * HSTSPT ; CP/M sectors/track -SECMSK EQU HSTBLK-1 ; sector mask -WRALL EQU 0 ; write to allocated -WRDIR EQU 1 ; write to directory -WRUAL EQU 2 ; write to unallocated -TMRTICKINTV EQU 5 ; Number of 0.010mSec ticks per interrupt, ie. resolution of RTC. -MTROFFMSECS EQU 100 ; Time from last access to motor being switched off in seconds in TMRTICKINTV ticks. -COLW: EQU 80 ; Width of the display screen (ie. columns). -ROW: EQU 25 ; Number of rows on display screen. -SCRNSZ: EQU COLW * ROW ; Total size, in bytes, of the screen display area. -SCRLW: EQU COLW / 8 ; Number of 8 byte regions in a line for hardware scroll. -MODE80C: EQU 1 - - -; BIOS equates -MAXDISKS EQU 7 ; Max number of Drives supported -KEYBUFSIZE EQU 64 ; Ensure this is a power of 2, max size 256. - -; Debugging -ENADEBUG EQU 1 ; Enable debugging logic, 1 = enable, 0 = disable - ;----------------------------------------------- ; Memory mapped ports in hardware. ;----------------------------------------------- @@ -138,6 +160,58 @@ NRMDSP: EQU 0E015H SCLDSP: EQU 0E200H SCLBASE: EQU 0E2H +;----------------------------------------------- +; IO ports in hardware and values. +;----------------------------------------------- +MMCFG EQU 060H ; Memory management configuration latch. +SETXMHZ EQU 062H ; Select the alternate clock frequency. +SET2MHZ EQU 064H ; Select the system 2MHz clock frequency. +CLKSELRD EQU 066H ; Read clock selected setting, 0 = 2MHz, 1 = XMHz +SVCREQ EQU 068H ; I/O Processor service request. +CPUCFG EQU 06CH ; Version 2.2 CPU configuration register. +CPUSTATUS EQU 06CH ; Version 2.2 CPU runtime status register. +CPUINFO EQU 06DH ; Version 2.2 CPU information register. +CPLDCFG EQU 06EH ; Version 2.1 CPLD configuration register. +CPLDSTATUS EQU 06EH ; Version 2.1 CPLD status register. +CPLDINFO EQU 06FH ; Version 2.1 CPLD version information register. +GDCRTC EQU 0CFH ; MZ-800 CRTC control register +GDCMD EQU 0CEH ; MZ-800 CRTC Mode register +GDGRF EQU 0CDH ; MZ-800 read format register +GDGWF EQU 0CCH ; MZ-800 write format register +PALSLCTOFF EQU 0D3H ; set the palette slot Off position to be adjusted. +PALSLCTON EQU 0D4H ; set the palette slot On position to be adjusted. +PALSETRED EQU 0D5H ; set the red palette value according to the PALETTE_PARAM_SEL address. +PALSETGREEN EQU 0D6H ; set the green palette value according to the PALETTE_PARAM_SEL address. +PALSETBLUE EQU 0D7H ; set the blue palette value according to the PALETTE_PARAM_SEL address. +MMIO0 EQU 0E0H ; MZ-700/MZ-800 Memory Management Set 0 +MMIO1 EQU 0E1H ; MZ-700/MZ-800 Memory Management Set 1 +MMIO2 EQU 0E2H ; MZ-700/MZ-800 Memory Management Set 2 +MMIO3 EQU 0E3H ; MZ-700/MZ-800 Memory Management Set 3 +MMIO4 EQU 0E4H ; MZ-700/MZ-800 Memory Management Set 4 +MMIO5 EQU 0E5H ; MZ-700/MZ-800 Memory Management Set 5 +MMIO6 EQU 0E6H ; MZ-700/MZ-800 Memory Management Set 6 +MMIO7 EQU 0E7H ; MZ-700/MZ-800 Memory Management Set 7 +;SYSCTRL EQU 0F0H ; System board control register. [2:0] - 000 MZ80A Mode, 2MHz CPU/Bus, 001 MZ80B Mode, 4MHz CPU/Bus, 010 MZ700 Mode, 3.54MHz CPU/Bus. +VMBORDER EQU 0F3H ; Select VGA Border colour attributes. Bit 2 = Red, 1 = Green, 0 = Blue. +;GRAMMODE EQU 0F4H ; MZ80B Graphics mode. Bit 0 = 0, Write to Graphics RAM I, Bit 0 = 1, Write to Graphics RAM II. Bit 1 = 1, blend Graphics RAM I output on display, Bit 2 = 1, blend Graphics RAM II output on display. +;VMPALETTE EQU 0F5H ; Select Palette: +; ; 0xF5 sets the palette. The Video Module supports 4 bit per colour output but there is only enough RAM for 1 bit per colour so the pallette is used to change the colours output. +; ; Bits [7:0] defines the pallete number. This indexes a lookup table which contains the required 4bit output per 1bit input. +; ; GPU: +;GPUPARAM EQU 0F6H ; 0xF6 set parameters. Store parameters in a long word to be used by the graphics command processor. +; ; The parameter word is 128 bit and each write to the parameter word shifts left by 8 bits and adds the new byte at bits 7:0. +;GPUCMD EQU 0F7H ; 0xF7 set the graphics processor unit commands. +;GPUSTATUS EQU 0F7H ; [7;1] - FSM state, [0] - 1 = busy, 0 = idle +; ; Bits [5:0] - 0 = Reset parameters. +; ; 1 = Clear to val. Start Location (16 bit), End Location (16 bit), Red Filter, Green Filter, Blue Filter +; ; +VMCTRL EQU 0F8H ; Video Module control register. [2:0] - 000 (default) = MZ80A, 001 = MZ-700, 010 = MZ800, 011 = MZ80B, 100 = MZ80K, 101 = MZ80C, 110 = MZ1200, 111 = MZ2000. [3] = 0 - 40 col, 1 - 80 col. +VMGRMODE EQU 0F9H ; Video Module graphics mode. 7/6 = Operator (00=OR,01=AND,10=NAND,11=XOR), 5=GRAM Output Enable, 4 = VRAM Output Enable, 3/2 = Write mode (00=Page 1:Red, 01=Page 2:Green, 10=Page 3:Blue, 11=Indirect), 1/0=Read mode (00=Page 1:Red, 01=Page2:Green, 10=Page 3:Blue, 11=Not used). +VMREDMASK EQU 0FAH ; Video Module Red bit mask (1 bit = 1 pixel, 8 pixels per byte). +VMGREENMASK EQU 0FBH ; Video Module Green bit mask (1 bit = 1 pixel, 8 pixels per byte). +VMBLUEMASK EQU 0FCH ; Video Module Blue bit mask (1 bit = 1 pixel, 8 pixels per byte). +VMPAGE EQU 0FDH ; Video Module memory page register. [1:0] switches in 1 16Kb page (3 pages) of graphics ram to C000 - FFFF. Bits [1:0] = page, 00 = off, 01 = Red, 10 = Green, 11 = Blue. This overrides all MZ700/MZ80B page switching functions. [7] 0 - normal, 1 - switches in CGROM for upload at D000:DFFF. + ;----------------------------------------------- ; IO Registers ;----------------------------------------------- @@ -251,59 +325,9 @@ CT_BLOCK EQU 008H ; Block DSKTYP_FDC EQU 0 ; Type of disk is a Floppy disk and handled by the FDC controller. ;DSKTYP_ROM EQU 1 ; Type of disk is a ROM and handled by the ROM methods. DSKTYP_SDC EQU 2 ; Type of disk is an SD Card and handled by the SD Card methods. +DSKTYP_RAM EQU 3 ; Type of disk is a RAM Drive handled by ROM/RAM methods. -;----------------------------------------------- -; IO ports in hardware and values. -;----------------------------------------------- -MMCFG EQU 060H ; Memory management configuration latch. -SETXMHZ EQU 062H ; Select the alternate clock frequency. -SET2MHZ EQU 064H ; Select the system 2MHz clock frequency. -CLKSELRD EQU 066H ; Read clock selected setting, 0 = 2MHz, 1 = XMHz -SVCREQ EQU 068H ; I/O Processor service request. -CPUCFG EQU 06CH ; Version 2.2 CPU configuration register. -CPUSTATUS EQU 06CH ; Version 2.2 CPU runtime status register. -CPUINFO EQU 06DH ; Version 2.2 CPU information register. -CPLDCFG EQU 06EH ; Version 2.1 CPLD configuration register. -CPLDSTATUS EQU 06EH ; Version 2.1 CPLD status register. -CPLDINFO EQU 06FH ; Version 2.1 CPLD version information register. -GDCRTC EQU 0CFH ; MZ-800 CRTC control register -GDCMD EQU 0CEH ; MZ-800 CRTC Mode register -GDGRF EQU 0CDH ; MZ-800 read format register -GDGWF EQU 0CCH ; MZ-800 write format register -PALSLCTOFF EQU 0D3H ; set the palette slot Off position to be adjusted. -PALSLCTON EQU 0D4H ; set the palette slot On position to be adjusted. -PALSETRED EQU 0D5H ; set the red palette value according to the PALETTE_PARAM_SEL address. -PALSETGREEN EQU 0D6H ; set the green palette value according to the PALETTE_PARAM_SEL address. -PALSETBLUE EQU 0D7H ; set the blue palette value according to the PALETTE_PARAM_SEL address. -MMIO0 EQU 0E0H ; MZ-700/MZ-800 Memory Management Set 0 -MMIO1 EQU 0E1H ; MZ-700/MZ-800 Memory Management Set 1 -MMIO2 EQU 0E2H ; MZ-700/MZ-800 Memory Management Set 2 -MMIO3 EQU 0E3H ; MZ-700/MZ-800 Memory Management Set 3 -MMIO4 EQU 0E4H ; MZ-700/MZ-800 Memory Management Set 4 -MMIO5 EQU 0E5H ; MZ-700/MZ-800 Memory Management Set 5 -MMIO6 EQU 0E6H ; MZ-700/MZ-800 Memory Management Set 6 -MMIO7 EQU 0E7H ; MZ-700/MZ-800 Memory Management Set 7 -;SYSCTRL EQU 0F0H ; System board control register. [2:0] - 000 MZ80A Mode, 2MHz CPU/Bus, 001 MZ80B Mode, 4MHz CPU/Bus, 010 MZ700 Mode, 3.54MHz CPU/Bus. -VMBORDER EQU 0F3H ; Select VGA Border colour attributes. Bit 2 = Red, 1 = Green, 0 = Blue. -;GRAMMODE EQU 0F4H ; MZ80B Graphics mode. Bit 0 = 0, Write to Graphics RAM I, Bit 0 = 1, Write to Graphics RAM II. Bit 1 = 1, blend Graphics RAM I output on display, Bit 2 = 1, blend Graphics RAM II output on display. -;VMPALETTE EQU 0F5H ; Select Palette: -; ; 0xF5 sets the palette. The Video Module supports 4 bit per colour output but there is only enough RAM for 1 bit per colour so the pallette is used to change the colours output. -; ; Bits [7:0] defines the pallete number. This indexes a lookup table which contains the required 4bit output per 1bit input. -; ; GPU: -;GPUPARAM EQU 0F6H ; 0xF6 set parameters. Store parameters in a long word to be used by the graphics command processor. -; ; The parameter word is 128 bit and each write to the parameter word shifts left by 8 bits and adds the new byte at bits 7:0. -;GPUCMD EQU 0F7H ; 0xF7 set the graphics processor unit commands. -;GPUSTATUS EQU 0F7H ; [7;1] - FSM state, [0] - 1 = busy, 0 = idle -; ; Bits [5:0] - 0 = Reset parameters. -; ; 1 = Clear to val. Start Location (16 bit), End Location (16 bit), Red Filter, Green Filter, Blue Filter -; ; -VMCTRL EQU 0F8H ; Video Module control register. [2:0] - 000 (default) = MZ80A, 001 = MZ-700, 010 = MZ800, 011 = MZ80B, 100 = MZ80K, 101 = MZ80C, 110 = MZ1200, 111 = MZ2000. [3] = 0 - 40 col, 1 - 80 col. -VMGRMODE EQU 0F9H ; Video Module graphics mode. 7/6 = Operator (00=OR,01=AND,10=NAND,11=XOR), 5=GRAM Output Enable, 4 = VRAM Output Enable, 3/2 = Write mode (00=Page 1:Red, 01=Page 2:Green, 10=Page 3:Blue, 11=Indirect), 1/0=Read mode (00=Page 1:Red, 01=Page2:Green, 10=Page 3:Blue, 11=Not used). -VMREDMASK EQU 0FAH ; Video Module Red bit mask (1 bit = 1 pixel, 8 pixels per byte). -VMGREENMASK EQU 0FBH ; Video Module Green bit mask (1 bit = 1 pixel, 8 pixels per byte). -VMBLUEMASK EQU 0FCH ; Video Module Blue bit mask (1 bit = 1 pixel, 8 pixels per byte). -VMPAGE EQU 0FDH ; Video Module memory page register. [1:0] switches in 1 16Kb page (3 pages) of graphics ram to C000 - FFFF. Bits [1:0] = page, 00 = off, 01 = Red, 10 = Green, 11 = Blue. This overrides all MZ700/MZ80B page switching functions. [7] 0 - normal, 1 - switches in CGROM for upload at D000:DFFF. - +; ;----------------------------------------------- ; CPLD Configuration constants. ;----------------------------------------------- diff --git a/software/asm/include/MSBASIC_BuildVersion.asm b/software/asm/include/MSBASIC_BuildVersion.asm new file mode 100644 index 0000000..cdc5619 --- /dev/null +++ b/software/asm/include/MSBASIC_BuildVersion.asm @@ -0,0 +1 @@ +BUILD_VERSION EQU 2 diff --git a/software/asm/include/BASIC_Definitions.asm b/software/asm/include/MSBASIC_Definitions.asm similarity index 91% rename from software/asm/include/BASIC_Definitions.asm rename to software/asm/include/MSBASIC_Definitions.asm index 9c8daaa..1cd2bfa 100644 --- a/software/asm/include/BASIC_Definitions.asm +++ b/software/asm/include/MSBASIC_Definitions.asm @@ -1,6 +1,6 @@ ;-------------------------------------------------------------------------------------------------------- ;- -;- Name: BASIC_Definitions.asm +;- Name: MSBASIC_Definitions.asm ;- Created: June 2020 ;- Author(s): Philip Smart ;- Description: Sharp MZ series CPM v2.23 @@ -14,6 +14,7 @@ ; additional and different hardware. The SPI is now onboard the PCB and ; not using the printer interface card. ; Jun 2020 - Copied and strpped from TZFS for BASIC. +; Mar 2021 - Updates to backport changes from the RFS version after v2.1 hw changes. ; ;-------------------------------------------------------------------------------------------------------- ;- This source file is free software: you can redistribute it and-or modify @@ -33,29 +34,69 @@ ;----------------------------------------------- ; Features. ;----------------------------------------------- -BUILD_VIDEOMODULE EQU 1 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0 -BUILD_MZ80A EQU 0 ; Build for the standard Sharp MZ80A, no lower memory. Manually change MAXMEM above. -BUILD_MZ700 EQU 1 ; Build for the Sharp MZ-700 base hardware. -BUILD_RFS EQU 0 ; Build for RFS where the tranZPUter board is available without the K64F and running under RFS. -BUILD_TZFS EQU 1 ; Build for TZFS where extended memory is available. -INCLUDE_ANSITERM EQU 1 ; Include the Ansi terminal emulation processor in the build. ;----------------------------------------------- ;----------------------------------------------- ; Configurable settings. ;----------------------------------------------- +; Build options. Set just one to '1' the rest to '0'. +; NB: As there are now 4 versions and 1 or more need to be built, ie. MZ-80A and RFS version for RFS, a flag is set in the file +; BASIC_build.asm which configures the equates below for the correct build. + + ; MZ-80A Standard Machine Configuration. + IF BUILD_VERSION = 0 +BUILD_MZ80A EQU 1 ; Build for the standard Sharp MZ80A, no lower memory. Manually change MAXMEM above. +BUILD_MZ700 EQU 0 ; Build for the Sharp MZ-700 base hardware. +BUILD_TZFS EQU 0 ; Build for TZFS where extended memory is available. +BUILD_VIDEOMODULE EQU 0 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0 +BUILD_80C EQU 0 +INCLUDE_ANSITERM EQU 1 ; Include the Ansi terminal emulation processor in the build. + ENDIF + ; MZ-700 Standard Machine Configuration. + IF BUILD_VERSION = 1 +BUILD_MZ80A EQU 0 +BUILD_MZ700 EQU 1 ; Build for the Sharp MZ-700 base hardware. +BUILD_TZFS EQU 0 +BUILD_VIDEOMODULE EQU 0 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0 +BUILD_80C EQU 0 +INCLUDE_ANSITERM EQU 1 ; Include the Ansi terminal emulation processor in the build. + ENDIF + ; TZFS Enhanced MZ-80A with no video card upgrade. + IF BUILD_VERSION = 2 +BUILD_MZ80A EQU 0 +BUILD_MZ700 EQU 0 ; Build for the Sharp MZ-700 base hardware. +BUILD_TZFS EQU 1 +BUILD_VIDEOMODULE EQU 0 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0 +BUILD_80C EQU 0 +INCLUDE_ANSITERM EQU 1 ; Include the Ansi terminal emulation processor in the build. + ENDIF + ; TZFS Enhanced MZ-80A/MZ-700 with VideoModule (or 40/80 Colour Board on MZ-80A). + IF BUILD_VERSION = 3 +BUILD_MZ700 EQU 0 ; Build for the Sharp MZ-700 base hardware. +BUILD_MZ80A EQU 0 +BUILD_TZFS EQU 1 +BUILD_VIDEOMODULE EQU 1 ; Build for the Video Module v2 board (=1) otherwise build for the 80Char Colour Board v1.0 +BUILD_80C EQU 1 +INCLUDE_ANSITERM EQU 1 ; Include the Ansi terminal emulation processor in the build. + ENDIF + IF BUILD_80C = 1 +COLW: EQU 80 ; Width of the display screen (ie. columns). + ELSE +COLW: EQU 40 ; Width of the display screen (ie. columns). + ENDIF TMRTICKINTV EQU 5 ; Number of 0.010mSec ticks per interrupt, ie. resolution of RTC. -COLW: EQU 80 ; Width of the display screen (ie. columns). ROW: EQU 25 ; Number of rows on display screen. SCRNSZ: EQU COLW * ROW ; Total size, in bytes, of the screen display area. SCRLW: EQU COLW / 8 ; Number of 8 byte regions in a line for hardware scroll. -MODE80C: EQU 1 ; BIOS equates KEYBUFSIZE EQU 64 ; Ensure this is a power of 2, max size 256. -MAXMEM EQU 10000H - TZSVCSIZE ; Top of RAM on the tranZPUter/ -;MAXMEM EQU 0CFFFH ; Top of RAM on a standard Sharp MZ80A. + IF BUILD_MZ80A = 1 +MAXMEM EQU 0CFFFH ; Top of RAM on a standard Sharp MZ80A. + ELSE +MAXMEM EQU 10000H - TZSVCSIZE ; Top of RAM on the tranZPUter/ + ENDIF ; Tape load/save modes. Used as a flag to enable common code. TAPELOAD EQU 1 @@ -74,8 +115,12 @@ ATR_BASIC_PROG EQU 2 ATR_BASIC_DATA EQU 3 ATR_SRC_FILE EQU 4 ATR_RELOC_FILE EQU 5 +ATR_BASIC_MSCAS EQU 07EH +ATR_BASIC_MSTXT EQU 07FH ATR_PASCAL_PROG EQU 0A0H ATR_PASCAL_DATA EQU 0A1H +CMTATRB EQU 010F0H +CMTNAME EQU 010F1H ;------------------------------------------------------- ; Function entry points in the standard SA-1510 Monitor. diff --git a/software/asm/include/TZFS_Definitions.asm b/software/asm/include/TZFS_Definitions.asm index 88b49e0..2be84a2 100644 --- a/software/asm/include/TZFS_Definitions.asm +++ b/software/asm/include/TZFS_Definitions.asm @@ -400,13 +400,13 @@ OBJCD EQU 001H ; MZF c BTX1CD EQU 002H ; MZF contains a BASIC program. BTX2CD EQU 005H ; MZF contains a BASIC program. TZOBJCD0 EQU 0F8H ; MZF contains a TZFS binary object for page 0. -TZOBJCD1 EQU 0F8H -TZOBJCD2 EQU 0F8H -TZOBJCD3 EQU 0F8H -TZOBJCD4 EQU 0F8H -TZOBJCD5 EQU 0F8H -TZOBJCD6 EQU 0F8H -TZOBJCD7 EQU 0F8H ; MZF contains a TZFS binary object for page 7. +TZOBJCD1 EQU 0F9H +TZOBJCD2 EQU 0FAH +TZOBJCD3 EQU 0FBH +TZOBJCD4 EQU 0FCH +TZOBJCD5 EQU 0FDH +TZOBJCD6 EQU 0FEH +TZOBJCD7 EQU 0FFH ; MZF contains a TZFS binary object for page 7. ;----------------------------------------------- ; SA-1510 MONITOR WORK AREA (MZ80A) diff --git a/software/asm/tzfs.asm b/software/asm/tzfs.asm index 2e01b88..9358808 100644 --- a/software/asm/tzfs.asm +++ b/software/asm/tzfs.asm @@ -23,6 +23,7 @@ ;- Mar 2021 - Bug fixes - MZ-700/MZ-80A address differences. ;- - Added optional machine model code on load command to enable 700/800 ;- programs to be loaded without changing the MZ800 mode switch. +;- Apr 2021 - Added 40/80 Colour Card control. Reorganised to free up space. ;- ;-------------------------------------------------------------------------------------------------------- ;- This source file is free software: you can redistribute it and-or modify @@ -145,7 +146,8 @@ MONITOR: LD A, (SCRNMODE) OR MODE_VIDEO_FPGA ; Set the tranZPUter CPLD hardware to enable FPGA video. OUT (CPLDCFG),A ; -MONITOR1: LD A, C ; Recall screen mode. +MONITOR1: LD HL,DSPCTL ; Control register address for the 40/80 Colour Card. + LD A, C ; Recall screen mode. BIT 0, A JR NZ, SET80CHAR ; @@ -168,13 +170,19 @@ SET40CHAR: IN A,(CPLDINFO) ; Get c SET40_0: AND 0C0H OR D OUT (VMCTRL),A ; Activate. -SET40_1: LD A, 0 + JR SET40_2 + ; +SET40_1: XOR A ; 40 char mode. + LD E,(HL) ; Dummy operation to enable latch write via multivibrator. + LD (HL), A + ; +SET40_2: XOR A LD (SPAGE), A ; Allow MZ80A scrolling JR SIGNON ; SET80CHAR: IN A,(CPLDINFO) ; Get configuration of hardware. BIT 3,A - JR Z,SET40_1 ; No hardware so cannot set 80 char mode. + JR Z,SET80_1 ; No FPGA hardware so try and set set 80 char mode on the assumption the 40/80 Colour Card is installed. ; AND 007H OR MODE_80CHAR ; Set 80 char flag. @@ -197,8 +205,13 @@ SET80_0: AND 0C0H ; Get t LD A, C ; Indicate we are using the FPGA video hardware. SET 1, A LD (SCRNMODE), A + JR SET80_2 ; -SET80_1: LD A, 0FFH +SET80_1: LD A, 128 ; 80 char mode. + LD E,(HL) ; Dummy operation to enable latch write via multivibrator. + LD (HL), A + ; +SET80_2: LD A, 0FFH LD (SPAGE), A ; MZ80K Scrolling in 80 column mode for time being. ; SIGNON: LD A,0C4h ; Move cursor left to overwrite part of SA-1510/monitor banner. @@ -270,142 +283,6 @@ CMDNOCMP: LD DE,MSGBADCMD CALL ?PRINTMSG CMDCMPEND: JP ST1X - ; Monitor command table. This table contains the list of recognised commands along with the - ; handler function and bank in which it is located. - ; - ; 7 6 5:3 2:0 - ; END MATCH UNUSED SIZE -CMDTABLE: DB 000H | 000H | 000H | 003H - DB "40A" ; Switch to the 40char Sharp MZ-80A compatbile mode. - DW SETMODE40A - DB 000H | 000H | 000H | 003H - DB "80A" ; Switch to the 80char Sharp MZ-80A compatbile mode. - DW SETMODE80A - DB 000H | 000H | 000H | 003H - DB "80B" ; Switch to the Sharp MZ-80B compatbile mode. - DW SETMODE80B - DB 000H | 000H | 000H | 001H ; Bit 2:0 = Command Size, 5:3 = Bank, 6 = Command match, 7 = Command table end. - DB '4' ; 40 Char screen mode. - DW SETMODE40 - DB 000H | 000H | 000H | 001H - DB '8' ; 80 Char screen mode. - DW SETMODE80 - DB 000H | 000H | 000H | 004H - DB "7008" ; Switch to 80 column MZ700 mode. - DW SETMODE7008 - DB 000H | 000H | 000H | 003H - DB "700" ; Switch to 40 column MZ700 mode. - DW SETMODE700 - DB 000H | 000H | 000H | 005H - DB "BASIC" ; Load and run BASIC SA-5510. - DW LOADBASIC - DB 000H | 000H | 000H | 001H - DB 'B' ; Bell. - DW SGX - DB 000H | 000H | 000H | 003H - DB "CPM" ; Load and run CPM. - DW LOADCPM - DB 000H | 000H | 000H | 001H - DB 'C' ; Clear Memory. - DW ?INITMEMX - DB 000H | 000H | 000H | 001H - DB 'D' ; Dump Memory. - DW ?DUMPX - DB 000H | 000H | 000H | 002H - DB "EC" ; Erase file. - DW ERASESD - DB 000H | 000H | 000H | 002H - DB "EX" ; Exit out of TZFS to original Monitor. - DW EXITTZFS - DB 000H | 000H | 000H | 004H - DB "FREQ" ; Set or change the CPU frequency. - DW ?SETFREQ - DB 000H | 000H | 000H | 001H - DB 'F' ; RFS Floppy boot code. - DW FLOPPY - DB 000H | 000H | 000H | 001H - DB 'H' ; Help screen. - DW ?HELP - DB 000H | 000H | 000H | 002H - DB "IC" ; List SD Card directory. - DW DIRSDCARD - DB 000H | 000H | 000H | 001H - DB 'J' ; Jump to address. - DW GOTOX - DB 000H | 000H | 000H | 004H - DB "LTNX" ; Load from CMT without auto execution. - DW LOADTAPENX - DB 000H | 000H | 000H | 002H - DB "LT" ; Load from CMT - DW LOADTAPE - DB 000H | 000H | 000H | 004H - DB "LCNX" ; Load from SDCARD without auto execution. - DW LOADSDCARDX - DB 000H | 000H | 000H | 002H - DB "LC" ; Load from SD CARD - DW LOADSDCARD - DB 000H | 000H | 000H | 001H - DB "L" ; Original Load from CMT - DW LOADTAPE - DB 000H | 000H | 000H | 001H - DB 'M' ; Edit Memory. - DW ?MCORX - DB 000H | 000H | 000H | 001H - DB 'P' ; Printer test. - DW ?PTESTX - DB 000H | 000H | 000H | 001H - DB 'R' ; Memory test. - DW MEMTEST - DB 000H | 000H | 000H | 004H - DB "SD2T" ; Copy SD Card to Tape. - DW SD2TAPE - DB 000H | 000H | 000H | 003H - DB "SDD" ; SD Card Directory change command. - DW CHGSDDIR - DB 000H | 000H | 000H | 002H - DB "SC" ; Save to SD CARD - DW SAVESDCARD - DB 000H | 000H | 000H | 002H - DB "ST" ; Save to CMT - DW SAVEX - DB 000H | 000H | 000H | 001H - DB 'S' ; Save to CMT - DW SAVEX - DB 000H | 000H | 000H | 004H - DB "TEST" ; A test function used in debugging. - DW LOCALTEST - DB 000H | 000H | 000H | 005H - DB "T2SDB" ; Copy Tape to SD Card in bulk mode. - DW TAPE2SDBULK - DB 000H | 000H | 000H | 004H - DB "T2SD" ; Copy Tape to SD Card. - DW TAPE2SD - DB 000H | 000H | 000H | 003H - DB "T80" ; Switch to soft T80 CPU. - DW ?SETT80 - DB 000H | 000H | 000H | 001H - DB 'T' ; Timer test. - DW ?TIMERTST - DB 000H | 000H | 000H | 007H - DB "VBORDER" ; Set VGA border colour. - DW ?SETVBORDER - DB 000H | 000H | 000H | 005H - DB "VMODE" ; Set VGA mode. - DW ?SETVMODE - DB 000H | 000H | 000H | 003H - DB "VGA" ; Set VGA mode. - DW ?SETVGAMODE - DB 000H | 000H | 000H | 001H - DB 'V' ; Verify CMT Save. - DW VRFYX - DB 000H | 000H | 000H | 003H - DB "Z80" ; Switch to soft Z80 CPU. - DW ?SETZ80 - DB 000H | 000H | 000H | 003H - DB "ZPU" ; Switch to soft ZPU Evolution CPU. - DW ?SETZPUEVO - DB 000H | 000H | 000H | 001H - ;------------------------------------------------------------------------------- ; END OF TZFS INITIALISATION AND COMMAND ENTRY PROCESSOR FUNCTIONALITY. @@ -2188,9 +2065,10 @@ LOCALTEST: LD A,0 OUT (C),A RET - ; Quick load program names. -CPMFILENAME:DB "CPM223", 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H -BASICFILENM:DB "BASIC SA-5510", 000H + ; Quick load prgram names. +CPMFILENAME:DB 0 ; "CPM223", 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H, 000H +BASICFILENM:DB 0 ; "BASIC SA-5510", 000H + ; Error tone. ERRTONE: DB "A0", 0D7H, "ARA", 0D7H, "AR", 00DH @@ -2201,6 +2079,143 @@ DSKID: DB 002H, "IPLPRO" ; Parameter block to indicate configuration and load area. PRMBLK: DB 000H, 000H, 000H, 000H, 001H, 000H, 0CEH, 000H, 000H, 000H, 000H + ; Monitor command table. This table contains the list of recognised commands along with the + ; handler function and bank in which it is located. + ; + ; 7 6 5:3 2:0 + ; END MATCH UNUSED SIZE +CMDTABLE: DB 000H | 000H | 000H | 003H + DB "40A" ; Switch to the 40char Sharp MZ-80A compatbile mode. + DW SETMODE40A + DB 000H | 000H | 000H | 003H + DB "80A" ; Switch to the 80char Sharp MZ-80A compatbile mode. + DW SETMODE80A + DB 000H | 000H | 000H | 003H + DB "80B" ; Switch to the Sharp MZ-80B compatbile mode. + DW SETMODE80B + DB 000H | 000H | 000H | 001H ; Bit 2:0 = Command Size, 5:3 = Bank, 6 = Command match, 7 = Command table end. + DB '4' ; 40 Char screen mode. + DW SETMODE40 + DB 000H | 000H | 000H | 001H + DB '8' ; 80 Char screen mode. + DW SETMODE80 + DB 000H | 000H | 000H | 004H + DB "7008" ; Switch to 80 column MZ700 mode. + DW SETMODE7008 + DB 000H | 000H | 000H | 003H + DB "700" ; Switch to 40 column MZ700 mode. + DW SETMODE700 + DB 000H | 000H | 000H | 005H + DB "BASIC" ; Load and run BASIC SA-5510. + DW LOADBASIC + DB 000H | 000H | 000H | 001H + DB 'B' ; Bell. + DW SGX + DB 000H | 000H | 000H | 003H + DB "CPM" ; Load and run CPM. + DW LOADCPM + DB 000H | 000H | 000H | 002H + DB "CD" ; SD Card Directory change command. + DW CHGSDDIR + DB 000H | 000H | 000H | 001H + DB 'C' ; Clear Memory. + DW ?INITMEMX + DB 000H | 000H | 000H | 003H + DB "DIR" ; List SD Card directory. + DW DIRSDCARD + DB 000H | 000H | 000H | 001H + DB 'D' ; Dump Memory. + DW ?DUMPX + DB 000H | 000H | 000H | 002H + DB "EC" ; Erase file. + DW ERASESD + DB 000H | 000H | 000H | 002H + DB "EX" ; Exit out of TZFS to original Monitor. + DW EXITTZFS + DB 000H | 000H | 000H | 004H + DB "FREQ" ; Set or change the CPU frequency. + DW ?SETFREQ + DB 000H | 000H | 000H | 001H + DB 'F' ; RFS Floppy boot code. + DW FLOPPY + DB 000H | 000H | 000H | 001H + DB 'H' ; Help screen. + DW ?HELP + DB 000H | 000H | 000H | 001H + DB 'J' ; Jump to address. + DW GOTOX + DB 000H | 000H | 000H | 004H + DB "LTNX" ; Load from CMT without auto execution. + DW LOADTAPENX + DB 000H | 000H | 000H | 002H + DB "LT" ; Load from CMT + DW LOADTAPE + DB 000H | 000H | 000H | 004H + DB "LCNX" ; Load from SDCARD without auto execution. + DW LOADSDCARDX + DB 000H | 000H | 000H | 002H + DB "LC" ; Load from SD CARD + DW LOADSDCARD + DB 000H | 000H | 000H | 001H + DB "L" ; Original Load from CMT + DW LOADTAPE + DB 000H | 000H | 000H | 001H + DB 'M' ; Edit Memory. + DW ?MCORX + DB 000H | 000H | 000H | 001H + DB 'P' ; Printer test. + DW ?PTESTX + DB 000H | 000H | 000H | 001H + DB 'R' ; Memory test. + DW MEMTEST + DB 000H | 000H | 000H | 004H + DB "SD2T" ; Copy SD Card to Tape. + DW SD2TAPE + DB 000H | 000H | 000H | 002H + DB "SC" ; Save to SD CARD + DW SAVESDCARD + DB 000H | 000H | 000H | 002H + DB "ST" ; Save to CMT + DW SAVEX + DB 000H | 000H | 000H | 001H + DB 'S' ; Save to CMT + DW SAVEX + DB 000H | 000H | 000H | 004H + DB "TEST" ; A test function used in debugging. + DW LOCALTEST + DB 000H | 000H | 000H | 005H + DB "T2SDB" ; Copy Tape to SD Card in bulk mode. + DW TAPE2SDBULK + DB 000H | 000H | 000H | 004H + DB "T2SD" ; Copy Tape to SD Card. + DW TAPE2SD + DB 000H | 000H | 000H | 003H + DB "T80" ; Switch to soft T80 CPU. + DW ?SETT80 + DB 000H | 000H | 000H | 001H + DB 'T' ; Timer test. + DW ?TIMERTST + DB 000H | 000H | 000H | 007H + DB "VBORDER" ; Set VGA border colour. + DW ?SETVBORDER + DB 000H | 000H | 000H | 005H + DB "VMODE" ; Set VGA mode. + DW ?SETVMODE + DB 000H | 000H | 000H | 003H + DB "VGA" ; Set VGA mode. + DW ?SETVGAMODE + DB 000H | 000H | 000H | 001H + DB 'V' ; Verify CMT Save. + DW VRFYX + DB 000H | 000H | 000H | 003H + DB "Z80" ; Switch to soft Z80 CPU. + DW ?SETZ80 + DB 000H | 000H | 000H | 003H + DB "ZPU" ; Switch to soft ZPU Evolution CPU. + DW ?SETZPUEVO + DB 000H | 000H | 000H | 001H + + ;------------------------------------------------------------------------------- ; END OF TZFS COMMAND FUNCTIONS. diff --git a/software/asm/tzfs_bank2.asm b/software/asm/tzfs_bank2.asm index e5e09c3..03dc3e8 100644 --- a/software/asm/tzfs_bank2.asm +++ b/software/asm/tzfs_bank2.asm @@ -419,14 +419,15 @@ HELPSCR: ; "--------- 40 column width -------------" DB "B - toggle keyboard bell.", 00DH DB "BASIC - load BASIC SA-5510.", 00DH DB "C[b] - clear memory $1200-$D000.", 00DH + DB "CD[d] - switch to SD directory [d].", 00DH DB "CPM - load CPM.", 00DH DB "DXXXX[YYYY] - dump mem XXXX to YYYY.", 00DH + DB "DIR[wc]- SD dir listing, wc=wildcard.", 00DH DB "ECfn - erase file, fn=No or Filename", 00DH DB "EX - exit TZFS, reset as original.", 00DH DB "Fx - boot fd drive x.", 00DH DB "FREQn -set CPU to nKHz, 0 default.", 00DH DB "H - this help screen.", 00DH - DB "IC[wc] - SD dir listing, wc=wildcard.", 00DH DB "JXXXX - jump to location XXXX.", 00DH DB "LTfn- load tape, fn=Filename", 00DH DB "LCfn[,M]- load from SD, fn=No or FileN", 00DH diff --git a/software/hdr/cpm22_MZ700_80C.HDR b/software/hdr/cpm22_MZ700_80C.HDR new file mode 100644 index 0000000..7f8213e Binary files /dev/null and b/software/hdr/cpm22_MZ700_80C.HDR differ diff --git a/software/hdr/cpm22_MZ80A_80C.HDR b/software/hdr/cpm22_MZ80A_80C.HDR new file mode 100644 index 0000000..6cf8f1f Binary files /dev/null and b/software/hdr/cpm22_MZ80A_80C.HDR differ diff --git a/software/hdr/cpm22_MZ80A_STD.HDR b/software/hdr/cpm22_MZ80A_STD.HDR new file mode 100644 index 0000000..d717043 Binary files /dev/null and b/software/hdr/cpm22_MZ80A_STD.HDR differ diff --git a/software/roms/CPM223.BIN b/software/roms/CPM223.BIN index eb23477..8f6ba8c 100644 Binary files a/software/roms/CPM223.BIN and b/software/roms/CPM223.BIN differ diff --git a/software/roms/CPM223_MZ700_80C.BIN b/software/roms/CPM223_MZ700_80C.BIN new file mode 100644 index 0000000..e7fc3b7 Binary files /dev/null and b/software/roms/CPM223_MZ700_80C.BIN differ diff --git a/software/roms/CPM223_MZ80A_80C.BIN b/software/roms/CPM223_MZ80A_80C.BIN new file mode 100644 index 0000000..6af870f Binary files /dev/null and b/software/roms/CPM223_MZ80A_80C.BIN differ diff --git a/software/roms/CPM223_MZ80A_STD.BIN b/software/roms/CPM223_MZ80A_STD.BIN new file mode 100644 index 0000000..bdbc6d9 Binary files /dev/null and b/software/roms/CPM223_MZ80A_STD.BIN differ diff --git a/software/roms/tzfs.rom b/software/roms/tzfs.rom index 6f683cc..59bccd6 100644 Binary files a/software/roms/tzfs.rom and b/software/roms/tzfs.rom differ diff --git a/software/tools/assemble_cpm.sh b/software/tools/assemble_cpm.sh index cd7721d..f5007b2 100755 --- a/software/tools/assemble_cpm.sh +++ b/software/tools/assemble_cpm.sh @@ -13,7 +13,7 @@ ## History: January 2020 - Initial script written. ## ######################################################################################################### -## This source file is free software: you can redistribute it and#or modify +## 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. @@ -32,40 +32,44 @@ TOOLDIR=${ROOTDIR}/software/tools JARDIR=${ROOTDIR}/software/tools ASM=glass.jar BUILDROMLIST="cbios cpm22" -BUILDMZFLIST="" ASMDIR=${ROOTDIR}/software/asm ASMTMPDIR=${ROOTDIR}/software/tmp INCDIR=${ROOTDIR}/software/asm/include ROMDIR=${ROOTDIR}/software/roms # Compiled or source ROM files. HDRDIR=${ROOTDIR}/software/hdr # MZF headers directory. MZFDIR=${ROOTDIR}/software/MZF/Common # MZF Format source files. +CPMVERSIONS="MZ700_80C:0 MZ80A_80C:1 MZ80A_STD:2" -# Go through list and build images. -# -for f in ${BUILDROMLIST} ${BUILDMZFLIST} +# As the tranZPUter project has eveolved different variants of CP/M are needed, so this loop along with the CPMVERSIONS string builds the versions as needed. +for ver in ${CPMVERSIONS} do - echo "Assembling: $f..." + # Setup the version to be built. + FILEEXT=`echo ${ver} |cut -d: -f1` + BUILDVER=`echo ${ver}|cut -d: -f2` + echo "BUILD_VERSION EQU ${BUILDVER}" > ${INCDIR}/CPM_BuildVersion.asm - # Assemble the source. - echo "java -jar ${JARDIR}/${ASM} ${ASMDIR}/${f}.asm ${ASMTMPDIR}/${f}.obj ${ASMTMPDIR}/${f}.sym" - java -jar ${JARDIR}/${ASM} ${ASMDIR}/${f}.asm ${ASMTMPDIR}/${f}.obj ${ASMTMPDIR}/${f}.sym -I ${INCDIR} - - # On successful compile, perform post actions else go onto next build. + # Go through list and build images. # - if [ $? = 0 ] - then - # The object file is binary, no need to link, copy according to build group. - if [[ ${BUILDROMLIST} = *"${f}"* ]]; then + for f in ${BUILDROMLIST} + do + echo "Assembling: $f..." + + # Assemble the source. + echo "java -jar ${JARDIR}/${ASM} ${ASMDIR}/${f}.asm ${ASMTMPDIR}/${f}.obj ${ASMTMPDIR}/${f}.sym" + java -jar ${JARDIR}/${ASM} ${ASMDIR}/${f}.asm ${ASMTMPDIR}/${f}.obj ${ASMTMPDIR}/${f}.sym -I ${INCDIR} + + # On successful compile, perform post actions else go onto next build. + # + if [ $? = 0 ] + then + # The object file is binary, no need to link, copy according to build group. echo "Copy ${ASMDIR}/${f}.obj to ${ROMDIR}/${f}.bin" cp ${ASMTMPDIR}/${f}.obj ${ROMDIR}/${f}.bin - else - echo "Copy ${ASMDIR}/${f}.obj to ${MZFDIR}/${f}.mzf" - cp ${ASMTMPDIR}/${f}.obj ${MZFDIR}/${f}.mzf fi - fi -done + done -# Manual tinkering to produce the loadable MZF file... -# -cat ${ROMDIR}/cpm22.bin ${ROMDIR}/cbios.bin > ${ROMDIR}/CPM223.BIN -cat ${HDRDIR}/cpm22.HDR ${ROMDIR}/CPM223.BIN > ${MZFDIR}/CPM223.MZF + # Manual tinkering to produce the loadable MZF file... + # + cat ${ROMDIR}/cpm22.bin ${ROMDIR}/cbios.bin > ${ROMDIR}/CPM223_${FILEEXT}.BIN + cat ${HDRDIR}/cpm22_${FILEEXT}.HDR ${ROMDIR}/CPM223_${FILEEXT}.BIN > ${MZFDIR}/CPM223_${FILEEXT}.MZF +done diff --git a/software/tools/assemble_roms.sh b/software/tools/assemble_roms.sh index a312e34..d572d86 100755 --- a/software/tools/assemble_roms.sh +++ b/software/tools/assemble_roms.sh @@ -9,10 +9,11 @@ ## into a ROM file using the GLASS Z80 assembler. ## ## Credits: -## Copyright: (c) 2018 Philip Smart +## Copyright: (c) 2018-21 Philip Smart ## ## History: August 2018 - Initial script written. ## March 2021 - Added MZ-800 IPL +## March 2021 - Updated to compile different versions of Microsoft BASIC. ## ######################################################################################################### ## This source file is free software: you can redistribute it and#or modify @@ -35,7 +36,7 @@ JARDIR=${ROOTDIR}/software/tools ASM=glass-0.5.jar BUILDROMLIST="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="hi-ramcheck sharpmz-test" -BUILDMZFLIST="5Z009-1B BASIC sharpmz-test" +BUILDMZFLIST="5Z009-1B MSBASIC_MZ80A MSBASIC_MZ700 MSBASIC_TZFS sharpmz-test" ASMDIR=${ROOTDIR}/software/asm ASMTMPDIR=${ROOTDIR}/software/tmp INCDIR=${ROOTDIR}/software/asm/include @@ -48,21 +49,53 @@ for f in ${BUILDROMLIST} ${BUILDMZFLIST} do echo "Assembling: $f..." + SRCNAME=${f} + ASMNAME=${f}.asm + OBJNAME=${f}.obj + SYMNAME=${f}.sym + ROMNAME=${f}.rom + MZFNAME=${f}.MZF + + # Special handling for the 4 version of MS BASIC. + if [[ ${SRCNAME} = "MSBASIC_MZ80A" ]]; then + ASMNAME="MSBASIC.asm" + echo "BUILD_VERSION EQU 0" > ${INCDIR}/MSBASIC_BuildVersion.asm + elif [[ ${SRCNAME} = "MSBASIC_MZ700" ]]; then + ASMNAME="MSBASIC.asm" + echo "BUILD_VERSION EQU 1" > ${INCDIR}/MSBASIC_BuildVersion.asm + elif [[ ${SRCNAME} = "MSBASIC_TZFS" ]]; then + ASMNAME="MSBASIC.asm" + echo "BUILD_VERSION EQU 2" > ${INCDIR}/MSBASIC_BuildVersion.asm + fi + # Assemble the source. - echo "java -jar ${JARDIR}/${ASM} ${ASMDIR}/${f}.asm ${ASMTMPDIR}/${f}.obj ${ASMTMPDIR}/${f}.sym" - java -jar ${JARDIR}/${ASM} ${ASMDIR}/${f}.asm ${ASMTMPDIR}/${f}.obj ${ASMTMPDIR}/${f}.sym -I ${INCDIR} + echo "java -jar ${JARDIR}/${ASM} ${ASMDIR}/${ASMNAME} ${ASMTMPDIR}/${OBJNAME} ${ASMTMPDIR}/${SYMNAME}" + java -jar ${JARDIR}/${ASM} ${ASMDIR}/${ASMNAME} ${ASMTMPDIR}/${OBJNAME} ${ASMTMPDIR}/${SYMNAME} -I ${INCDIR} # On successful compile, perform post actions else go onto next build. # if [ $? = 0 ] then # The object file is binary, no need to link, copy according to build group. - if [[ ${BUILDROMLIST} = *"${f}"* ]]; then - echo "Copy ${ASMDIR}/${f}.obj to ${ROMDIR}/${f}.rom" - cp ${ASMTMPDIR}/${f}.obj ${ROMDIR}/${f}.rom + if [[ ${BUILDROMLIST} = *"${SRCNAME}"* ]]; then + echo "Copy ${ASMTMPDIR}/${OBJNAME} to ${ROMDIR}/${ROMNAME}" + cp ${ASMTMPDIR}/${OBJNAME} ${ROMDIR}/${ROMNAME} else - echo "Copy ${ASMDIR}/${f}.obj to ${MZFDIR}/${f}.mzf" - cp ${ASMTMPDIR}/${f}.obj ${MZFDIR}/${f}.MZF + # Build standard MZF files for inclusion in the SD Drive. + echo "Copy ${ASMTMPDIR}/${OBJNAME} to ${MZFDIR}/${MZFNAME}" + cp ${ASMTMPDIR}/${OBJNAME} ${MZFDIR}/${MZFNAME} + + # Create sectored versions of file for inclusion into the ROM Drives. + for BLOCKSIZE in ${BLOCKSIZELIST} + do + FILESIZE=$(stat -c%s "${ASMTMPDIR}/${OBJNAME}") + if [ $((${FILESIZE} % ${BLOCKSIZE})) -ne 0 ]; then + FILESIZE=$(( ((${FILESIZE} / ${BLOCKSIZE})+1 ) * ${BLOCKSIZE} )) + fi + + dd if=/dev/zero ibs=1 count=${FILESIZE} 2>/dev/null | tr "\000" "\377" > "${MZBDIR}/${SRCNAME}.${BLOCKSIZE}.bin" + dd if="${ASMTMPDIR}/${OBJNAME}" of="${MZBDIR}/${SRCNAME}.${BLOCKSIZE}.bin" conv=notrunc 2>/dev/null + done fi fi done diff --git a/software/tools/copytosd.sh b/software/tools/copytosd.sh index 8da4e1b..0a5f761 100755 --- a/software/tools/copytosd.sh +++ b/software/tools/copytosd.sh @@ -179,24 +179,23 @@ if [ ! -d "${rootdir}/${softwaredir}/MZF/${target}" ]; then Fatal "-t < target host> is invalid, this should be one of: MZ-80K, MZ-80A, MZ-700, MZ-800, MZ-1500, MZ-2000" fi if [ ! -d "${media}" ]; then - Fatal "-m < root path > is invalid, this should be the directory where the tranZPUter project directory is located." + Fatal "-M < media path > is invalid, this should be the mounted SD card directory." fi -# Create necessary directories on the SD card. -mkdir -p $media/TZFS/; -mkdir -p $media/MZF/; -mkdir -p $media/CPM/; -mkdir -p $media/BAS; -mkdir -p $media/CAS; +# Create necessary directories on the SD card and clean them out. +#for dir in TZFS MZF MZ80K MZ80A MZ80B MZ700 MZ800 MZ1500 MZ2000 CPM MSBAS MSCAS +for dir in TZFS MZF MZ80A MZ700 CPM MSBAS MSCAS +do + # Clean out the directories to avoid old files being used. + if [[ "${media}x" != "x" ]]; then + mkdir -p $media/${dir}/; + if [ -d $media/${dir} ]; then + rm -f $media/${dir}/*; + fi + fi +done -# Clean out the directories to avoid old files being used. -rm $media/TZFS/*; -rm $media/MZF/*; -rm $media/CPM/*; -rm $media/BAS/*; -rm $media/CAS/*; - -# Copy required files. +# Manually copy required files. cp ${rootdir}/${softwaredir}/roms/tzfs.rom $media/TZFS/; cp ${rootdir}/${softwaredir}/roms/monitor_SA1510.rom $media/TZFS/SA1510.rom; cp ${rootdir}/${softwaredir}/roms/monitor_80c_SA1510.rom $media/TZFS/SA1510-8.rom; @@ -209,10 +208,15 @@ cp ${rootdir}/${softwaredir}/roms/MZ800_* $media/TZFS/; cp ${rootdir}/${softwaredir}/roms/cpm22.bin $media/CPM/; cp ${rootdir}/${softwaredir}/CPM/SDC16M/RAW/* $media/CPM/; cp ${rootdir}/${softwaredir}/MZF/Common/* $media/MZF/; -cp ${rootdir}/${softwaredir}/MZF/${target}/* $media/MZF/; -cp ${rootdir}/${softwaredir}/MZF/MZ-80K/* $media/MZF/; -cp ${rootdir}/${softwaredir}/BAS/* $media/BAS/; -cp ${rootdir}/${softwaredir}/CAS/* $media/CAS/ +#cp ${rootdir}/${softwaredir}/MZF/MZ-80K/* $media/MZ80K/; +cp ${rootdir}/${softwaredir}/MZF/MZ-80A/* $media/MZ80A/; +#cp ${rootdir}/${softwaredir}/MZF/MZ-80B/* $media/MZ80B/; +cp ${rootdir}/${softwaredir}/MZF/MZ-700/* $media/MZ700/; +#cp ${rootdir}/${softwaredir}/MZF/MZ-800/* $media/MZ800/; +#cp ${rootdir}/${softwaredir}/MZF/MZ-1500/* $media/MZ1500/; +#cp ${rootdir}/${softwaredir}/MZF/MZ-2000/* $media/MZ2000/; +cp ${rootdir}/${softwaredir}/BAS/* $media/MSBAS/; +cp ${rootdir}/${softwaredir}/CAS/* $media/MSCAS/ echo "Done, TZFS, CPM and host programs copied to SD card." exit 0