mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-03-10 20:33:41 +00:00
Convert Apple 2 WXEDA -> MiST
This commit is contained in:
30
Apple - 2_MiST/AppleII_MiST.qpf
Normal file
30
Apple - 2_MiST/AppleII_MiST.qpf
Normal file
@@ -0,0 +1,30 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 1991-2013 Altera Corporation
|
||||
# Your use of Altera Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License
|
||||
# Subscription Agreement, Altera MegaCore Function License
|
||||
# Agreement, or other applicable license agreement, including,
|
||||
# without limitation, that your use is for the sole purpose of
|
||||
# programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the
|
||||
# applicable agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus II 64-Bit
|
||||
# Version 13.1.0 Build 162 10/23/2013 SJ Web Edition
|
||||
# Date created = 14:22:52 May 18, 2018
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
QUARTUS_VERSION = "13.1"
|
||||
DATE = "14:22:52 May 18, 2018"
|
||||
|
||||
# Revisions
|
||||
|
||||
PROJECT_REVISION = "AppleII_MiST"
|
||||
203
Apple - 2_MiST/AppleII_MiST.qsf
Normal file
203
Apple - 2_MiST/AppleII_MiST.qsf
Normal file
@@ -0,0 +1,203 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 1991-2013 Altera Corporation
|
||||
# Your use of Altera Corporation's design tools, logic functions
|
||||
# and other software and tools, and its AMPP partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License
|
||||
# Subscription Agreement, Altera MegaCore Function License
|
||||
# Agreement, or other applicable license agreement, including,
|
||||
# without limitation, that your use is for the sole purpose of
|
||||
# programming logic devices manufactured by Altera and sold by
|
||||
# Altera or its authorized distributors. Please refer to the
|
||||
# applicable agreement for further details.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus II 64-Bit
|
||||
# Version 13.1.0 Build 162 10/23/2013 SJ Web Edition
|
||||
# Date created = 14:29:19 May 18, 2018
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Notes:
|
||||
#
|
||||
# 1) The default values for assignments are stored in the file:
|
||||
# AppleII_MiST_assignment_defaults.qdf
|
||||
# If this file doesn't exist, see file:
|
||||
# assignment_defaults.qdf
|
||||
#
|
||||
# 2) Altera recommends that you do not modify this file. This
|
||||
# file is updated automatically by the Quartus II software
|
||||
# and any changes you make may be lost or overwritten.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
|
||||
|
||||
# Project-Wide Assignments
|
||||
# ========================
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1
|
||||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "19:15:38 MAY 09, 2018"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION 13.1
|
||||
set_global_assignment -name VHDL_FILE rtl/video_generator.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/vga_controller.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/timing_generator.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/spi_controller.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/PS2_Ctrl.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/main_roms.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/keyboard.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/disk_ii_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/disk_ii.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/cpu6502.vhd
|
||||
set_global_assignment -name QIP_FILE rtl/CLK28MPLL.qip
|
||||
set_global_assignment -name VHDL_FILE rtl/character_rom.vhd
|
||||
set_global_assignment -name VHDL_FILE rtl/apple2.vhd
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
set_global_assignment -name VERILOG_FILE rtl/pll.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/video_mixer.sv
|
||||
set_global_assignment -name VERILOG_FILE rtl/scandoubler.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/osd.v
|
||||
set_global_assignment -name VERILOG_FILE rtl/mist_io.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/hq2x.sv
|
||||
set_global_assignment -name VHDL_FILE rtl/dac.vhd
|
||||
set_global_assignment -name QIP_FILE rtl/ram.qip
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE rtl/AppleII_MiST.sv
|
||||
|
||||
# Pin & Location Assignments
|
||||
# ==========================
|
||||
set_location_assignment PIN_7 -to LED
|
||||
set_location_assignment PIN_54 -to CLOCK_27
|
||||
set_location_assignment PIN_144 -to VGA_R[5]
|
||||
set_location_assignment PIN_143 -to VGA_R[4]
|
||||
set_location_assignment PIN_142 -to VGA_R[3]
|
||||
set_location_assignment PIN_141 -to VGA_R[2]
|
||||
set_location_assignment PIN_137 -to VGA_R[1]
|
||||
set_location_assignment PIN_135 -to VGA_R[0]
|
||||
set_location_assignment PIN_133 -to VGA_B[5]
|
||||
set_location_assignment PIN_132 -to VGA_B[4]
|
||||
set_location_assignment PIN_125 -to VGA_B[3]
|
||||
set_location_assignment PIN_121 -to VGA_B[2]
|
||||
set_location_assignment PIN_120 -to VGA_B[1]
|
||||
set_location_assignment PIN_115 -to VGA_B[0]
|
||||
set_location_assignment PIN_114 -to VGA_G[5]
|
||||
set_location_assignment PIN_113 -to VGA_G[4]
|
||||
set_location_assignment PIN_112 -to VGA_G[3]
|
||||
set_location_assignment PIN_111 -to VGA_G[2]
|
||||
set_location_assignment PIN_110 -to VGA_G[1]
|
||||
set_location_assignment PIN_106 -to VGA_G[0]
|
||||
set_location_assignment PIN_136 -to VGA_VS
|
||||
set_location_assignment PIN_119 -to VGA_HS
|
||||
set_location_assignment PIN_65 -to AUDIO_L
|
||||
set_location_assignment PIN_80 -to AUDIO_R
|
||||
set_location_assignment PIN_105 -to SPI_DO
|
||||
set_location_assignment PIN_88 -to SPI_DI
|
||||
set_location_assignment PIN_126 -to SPI_SCK
|
||||
set_location_assignment PIN_127 -to SPI_SS2
|
||||
set_location_assignment PIN_91 -to SPI_SS3
|
||||
set_location_assignment PIN_13 -to CONF_DATA0
|
||||
set_location_assignment PIN_49 -to SDRAM_A[0]
|
||||
set_location_assignment PIN_44 -to SDRAM_A[1]
|
||||
set_location_assignment PIN_42 -to SDRAM_A[2]
|
||||
set_location_assignment PIN_39 -to SDRAM_A[3]
|
||||
set_location_assignment PIN_4 -to SDRAM_A[4]
|
||||
set_location_assignment PIN_6 -to SDRAM_A[5]
|
||||
set_location_assignment PIN_8 -to SDRAM_A[6]
|
||||
set_location_assignment PIN_10 -to SDRAM_A[7]
|
||||
set_location_assignment PIN_11 -to SDRAM_A[8]
|
||||
set_location_assignment PIN_28 -to SDRAM_A[9]
|
||||
set_location_assignment PIN_50 -to SDRAM_A[10]
|
||||
set_location_assignment PIN_30 -to SDRAM_A[11]
|
||||
set_location_assignment PIN_32 -to SDRAM_A[12]
|
||||
set_location_assignment PIN_83 -to SDRAM_DQ[0]
|
||||
set_location_assignment PIN_79 -to SDRAM_DQ[1]
|
||||
set_location_assignment PIN_77 -to SDRAM_DQ[2]
|
||||
set_location_assignment PIN_76 -to SDRAM_DQ[3]
|
||||
set_location_assignment PIN_72 -to SDRAM_DQ[4]
|
||||
set_location_assignment PIN_71 -to SDRAM_DQ[5]
|
||||
set_location_assignment PIN_69 -to SDRAM_DQ[6]
|
||||
set_location_assignment PIN_68 -to SDRAM_DQ[7]
|
||||
set_location_assignment PIN_86 -to SDRAM_DQ[8]
|
||||
set_location_assignment PIN_87 -to SDRAM_DQ[9]
|
||||
set_location_assignment PIN_98 -to SDRAM_DQ[10]
|
||||
set_location_assignment PIN_99 -to SDRAM_DQ[11]
|
||||
set_location_assignment PIN_100 -to SDRAM_DQ[12]
|
||||
set_location_assignment PIN_101 -to SDRAM_DQ[13]
|
||||
set_location_assignment PIN_103 -to SDRAM_DQ[14]
|
||||
set_location_assignment PIN_104 -to SDRAM_DQ[15]
|
||||
set_location_assignment PIN_58 -to SDRAM_BA[0]
|
||||
set_location_assignment PIN_51 -to SDRAM_BA[1]
|
||||
set_location_assignment PIN_85 -to SDRAM_DQMH
|
||||
set_location_assignment PIN_67 -to SDRAM_DQML
|
||||
set_location_assignment PIN_60 -to SDRAM_nRAS
|
||||
set_location_assignment PIN_64 -to SDRAM_nCAS
|
||||
set_location_assignment PIN_66 -to SDRAM_nWE
|
||||
set_location_assignment PIN_59 -to SDRAM_nCS
|
||||
set_location_assignment PIN_33 -to SDRAM_CKE
|
||||
set_location_assignment PIN_43 -to SDRAM_CLK
|
||||
set_location_assignment PLL_1 -to "pll:pll|altpll:altpll_component"
|
||||
|
||||
# Classic Timing Assignments
|
||||
# ==========================
|
||||
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
|
||||
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
|
||||
set_global_assignment -name TIMEQUEST_MULTICORNER_ANALYSIS ON
|
||||
set_global_assignment -name TIMEQUEST_DO_CCPP_REMOVAL ON
|
||||
|
||||
# Analysis & Synthesis Assignments
|
||||
# ================================
|
||||
set_global_assignment -name FAMILY "Cyclone III"
|
||||
set_global_assignment -name TOP_LEVEL_ENTITY AppleII_MiST
|
||||
set_global_assignment -name DEVICE_FILTER_PIN_COUNT 144
|
||||
set_global_assignment -name DEVICE_FILTER_SPEED_GRADE 8
|
||||
|
||||
# Fitter Assignments
|
||||
# ==================
|
||||
set_global_assignment -name DEVICE EP3C25E144C8
|
||||
set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL"
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN OFF
|
||||
set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON
|
||||
set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVTTL"
|
||||
set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "USE AS REGULAR IO"
|
||||
|
||||
# Assembler Assignments
|
||||
# =====================
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE OFF
|
||||
set_global_assignment -name GENERATE_RBF_FILE ON
|
||||
|
||||
# Power Estimation Assignments
|
||||
# ============================
|
||||
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"
|
||||
set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
|
||||
|
||||
# Advanced I/O Timing Assignments
|
||||
# ===============================
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_NEAR_END_VMEAS "HALF VCCIO" -fall
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -rise
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_FAR_END_VMEAS "HALF SIGNAL SWING" -fall
|
||||
|
||||
# --------------------------
|
||||
# start ENTITY(AppleII_MiST)
|
||||
|
||||
# start DESIGN_PARTITION(Top)
|
||||
# ---------------------------
|
||||
|
||||
# Incremental Compilation Assignments
|
||||
# ===================================
|
||||
set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
||||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
|
||||
# end DESIGN_PARTITION(Top)
|
||||
# -------------------------
|
||||
|
||||
# end ENTITY(AppleII_MiST)
|
||||
# ------------------------
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
197
Apple - 2_MiST/README.MD
Normal file
197
Apple - 2_MiST/README.MD
Normal file
@@ -0,0 +1,197 @@
|
||||
Apple II on MiST
|
||||
|
||||
|
||||
This is a reconstruction of an 1980s-era Apple ][+ implemented in VHDL for
|
||||
FPGAs.
|
||||
|
||||
Stephen A. Edwards, sedwards@cs.columbia.edu
|
||||
http://www1.cs.columbia.edu/~sedwards
|
||||
------------------------------
|
||||
The current implementation uses the Altera DE1/DE2 board and takes
|
||||
advantage of its off-chip SRAM, VGA DAC, SD card, audio CODEC, and
|
||||
PS/2 keyboard interface.
|
||||
|
||||
It was designed to be fairly easy to port: the apple2.vhd file should
|
||||
be implementation-agnostic: it only assumes the external availability
|
||||
of 48K of RAM and a keyboard.
|
||||
|
||||
It contains a simple read-only Disk II emulator that expects
|
||||
"nibblized" disk images written raw onto an SD or MMC card (i.e., it
|
||||
does not use a FAT or any other type of filesystem).
|
||||
|
||||
The VGA controller (not part of an original Apple) doubles each line
|
||||
and interprets the Apple's NTSC-compatible color signals to produce a color
|
||||
640 X 480 VGA display with non-standard dot timing.
|
||||
------------------------------
|
||||
To compile under Altera's Quartus software, open the
|
||||
apple2fpga_DE1.qpf or apple2fpga_DE2.qpf project file and compile.
|
||||
------------------------------
|
||||
VHDL files, in order of elaboration:
|
||||
|
||||
timing_generator.vhd Timing signal generation, video counters
|
||||
character_rom.vhd The beautiful 5 X 8 uppercase-only text font
|
||||
video_generator.vhd Text, lores, and hires mode shift registers
|
||||
main_roms.vhd D000-FFFF ROMs: Applesoft and the Monitor
|
||||
cpu6502.vhd The 6502 CPU core
|
||||
apple2.vhd Top-level of the Apple: mostly address decode
|
||||
disk_ii_rom.vhd C600-C6FF ROM: Disk II bootstrap ROM
|
||||
disk_ii.vhd Read-only Disk II emulator
|
||||
vga_controller.vhd NTSC-to-VGA color interpolation, line doubler
|
||||
PS2_Ctrl.vhd Low-level PS/2 keyboard interface
|
||||
keyboard.vhd PS/2 keyboard-to-Apple interface
|
||||
spi_controller.vhd SD/MMC card controller: reads raw tracks
|
||||
i2c_controller.vhd Simple I2C bus driver; initializes the codec
|
||||
wm8731_audio.vhd Controller for the Wolfson WM8731 audio codec
|
||||
DE1_TOP.vhd Top-level entity for the Altera DE1 board
|
||||
DE2_TOP.vhd Top-level entity for the Altera DE2 board
|
||||
CLK28MPLL.vhd Altera-specific configuration for 28 MHz PLL
|
||||
|
||||
Other files:
|
||||
|
||||
dsk2nib.c Converts a 140K .dsk image file to the raw 228K
|
||||
.nib format used by the Disk II emulator
|
||||
|
||||
dsknib.sln Visual C++ Express 2008 solution file for
|
||||
generating dsknib.exe under Windows
|
||||
|
||||
dsknib.vcproj Visual C++ Express 2008 project file for
|
||||
generating dsknib.exe under Windows
|
||||
|
||||
makenibs A shell (e.g., bash) script that assembles
|
||||
collections of .dsk files into a file suitable
|
||||
for directly writing onto an SD card
|
||||
|
||||
rom2vhdl Script to convert raw ROM files into
|
||||
synthesizable VHDL code. Used to produce main_roms.vhd
|
||||
|
||||
apple2fpga_DE1.qpf DE1 board project file for Altera's Quartus
|
||||
apple2fpga_DE2.qpf DE2 board project file for Altera's Quartus
|
||||
DE1_TOP.qsf Mostly pin assignments for Altera's Quartus
|
||||
DE1_TOP.sof A compiled bitstream for the DE1 board: the
|
||||
result of compiling all the VHDL files in
|
||||
Quartus; suitable for programming if you have a
|
||||
DE1 board.
|
||||
DE2_TOP.qsf Mostly pin assignments for Altera's Quartus
|
||||
DE2_TOP.sof A compiled bitstream for the DE2 board: the
|
||||
result of compiling all the VHDL files in
|
||||
Quartus; suitable for programming if you have a
|
||||
DE2 board.
|
||||
|
||||
dos33master.nib Bootable disk image: Apple DOS 3.3 system master
|
||||
|
||||
bios.a65 6502 assembly source for a "fake" BIOS
|
||||
bios.rom Binary data for the "fake" BIOS
|
||||
|
||||
Makefile Rules for creating the .zip, .vhd files, etc.
|
||||
------------------------------
|
||||
Disk images
|
||||
|
||||
The system expects a sequence of "nibblized" (227K) disk images on the
|
||||
SD card starting at block 0. Switches on the DE1/DE2 board selects
|
||||
which image appears to be in the drive; the image number is displayed
|
||||
in hex on two of the seven-segment displays.
|
||||
|
||||
Most Apple II disk images are in 140K .dsk files, which stores only
|
||||
the disk's logical data, i.e., is not encoded. dsk2nib.c is a small C
|
||||
program that expands .dsk files to .nib files.
|
||||
|
||||
I used the "makenibs" script to find all the .dsk files in a tree of
|
||||
directories, assemble them into an image suitable for downloading to
|
||||
the SD card, and print an image number/file name cross-listing.
|
||||
|
||||
To write .nib images to an SD/MMC card under Linux, I use
|
||||
|
||||
dd if=dos33master.nib of=/dev/sdd
|
||||
|
||||
Of course, your card may appear as something other than /dev/sdd.
|
||||
|
||||
Under Windows, you can use dd.exe (http://www.chrysocome.net/dd):
|
||||
|
||||
dd.exe if=dos33master.nib of=\\?\Device\Harddiskx\Partition0
|
||||
|
||||
where the correct "Harddiskx" can be determined using the dd.exe
|
||||
"--list" option:
|
||||
|
||||
dd.exe --list
|
||||
|
||||
------------------------------
|
||||
ROMs
|
||||
|
||||
This archive does NOT include a copy of the Apple ][+'s ROMs, which
|
||||
are copyright Apple Computer. Instead, it includes a very trivial
|
||||
BIOS that beeps, displays a text screen, then cycles through some
|
||||
lores and hires graphics patterns when keys are pressed. This should
|
||||
be enough to verify the graphics, sound, and keyboard are working (but
|
||||
not the disk emulator). Source for this BIOS is in the bios.a65 file,
|
||||
which I assembled using the xa65 cross-assembler.
|
||||
|
||||
The system requires two ROM images: a 12K image of the system roms
|
||||
(memory from 0xD000 - 0xFFFF) and a 256-byte image of the Disk II
|
||||
controller bootstrap ROM (memory from 0xc600 - 0xc6ff if the card is
|
||||
in the usual slot 6).
|
||||
|
||||
Once you obtain them, run the "rom2vhdl" script to convert the binary
|
||||
files into .vhd files that hold the data. The Makefile contains rules
|
||||
for doing this.
|
||||
------------------------------
|
||||
Operation
|
||||
|
||||
For the DE1 board:
|
||||
KEY[3] Reset
|
||||
KEY[2..0] Game Port
|
||||
SW[9] B&W/Color Display
|
||||
SW[8..0] Disk Image # (0 to 511)
|
||||
HEX[2..3] Disk Image # (0 to 255 => 00 to FF hex)
|
||||
HEX[1..0] Track # (0 to 35 => 00 to 23 hex)
|
||||
LEDR[9..0] PC[15..6] (CPU Program Counter in 64-byte page unit)
|
||||
LEDG[3] Unused
|
||||
LEDG[2] Disk Drive #2 Activity
|
||||
LEDG[1] Disk Drive #1 Activity
|
||||
LEDG[0] Speaker Activity
|
||||
|
||||
For the DE2 board:
|
||||
KEY[3] Reset
|
||||
KEY[2..0] Game Port
|
||||
SW[17] B&W/Color Display
|
||||
SW[16..10] Unused
|
||||
SW[9..0] Disk Image # (0 to 1023)
|
||||
HEX[7..6] Disk Image # (0 to 255 => 00 to FF hex)
|
||||
HEX[5..4] Track # (0 to 35 => 00 to 23 hex)
|
||||
HEX[3..0] PC[15..0] (CPU Program Counter, 0000 to FFFF hex)
|
||||
LEDR[17..16] Unused
|
||||
LEDR[15..0] PC[15..12] (CPU Program Counter in 4Kbyte page unit decoded)
|
||||
LEDG[8] Disk Drive #1 Activity
|
||||
LEDG[7..4] Analog Joystick Activity
|
||||
LEDG[3..1] Unused
|
||||
LEDG[0] Speaker Activity
|
||||
|
||||
------------------------------
|
||||
Credits:
|
||||
|
||||
Peter Wendrich supplied the 6502 core:
|
||||
|
||||
-- cpu65xx_fast.vhdl, part of FPGA-64, is made available strictly for personal
|
||||
-- educational purposes. Distributed with apple2fgpa with permission.
|
||||
--
|
||||
-- Copyright 2005-2008 by Peter Wendrich (pwsoft@syntiac.com).
|
||||
-- All rights reserved.
|
||||
-- http://www.syntiac.com/fpga64.html
|
||||
|
||||
The low-level PS/2 keyboard controller is from ALSE:
|
||||
|
||||
-- PS2_Ctrl.vhd
|
||||
-- ------------------------------------------------
|
||||
-- Simplified PS/2 Controller (kbd, mouse...)
|
||||
-- ------------------------------------------------
|
||||
-- Only the Receive function is implemented !
|
||||
-- (c) ALSE. http://www.alse-fr.com
|
||||
|
||||
Michel Stempin (michel.stempin@wanadoo.fr):
|
||||
- ported apple2fpga to the Altera DE1 board
|
||||
- added SD/SDHC to MMC Flash disk comptatibility
|
||||
- added i18n + French keymap
|
||||
|
||||
I adapted the Apple ][ keyboard emulation from Alex Freed's FPGApple:
|
||||
http://mirrow.com/FPGApple/
|
||||
|
||||
|
||||
38
Apple - 2_MiST/clean.bat
Normal file
38
Apple - 2_MiST/clean.bat
Normal file
@@ -0,0 +1,38 @@
|
||||
@echo off
|
||||
del /s *.bak
|
||||
del /s *.orig
|
||||
del /s *.rej
|
||||
del /s *~
|
||||
rmdir /s /q db
|
||||
rmdir /s /q incremental_db
|
||||
rmdir /s /q output_files
|
||||
rmdir /s /q simulation
|
||||
rmdir /s /q greybox_tmp
|
||||
rmdir /s /q hc_output
|
||||
rmdir /s /q .qsys_edit
|
||||
rmdir /s /q hps_isw_handoff
|
||||
rmdir /s /q sys\.qsys_edit
|
||||
rmdir /s /q sys\vip
|
||||
cd sys
|
||||
for /d %%i in (*_sim) do rmdir /s /q "%%~nxi"
|
||||
cd ..
|
||||
for /d %%i in (*_sim) do rmdir /s /q "%%~nxi"
|
||||
del build_id.v
|
||||
del c5_pin_model_dump.txt
|
||||
del PLLJ_PLLSPE_INFO.txt
|
||||
del /s *.qws
|
||||
del /s *.ppf
|
||||
del /s *.ddb
|
||||
del /s *.csv
|
||||
del /s *.cmp
|
||||
del /s *.sip
|
||||
del /s *.spd
|
||||
del /s *.bsf
|
||||
del /s *.f
|
||||
del /s *.sopcinfo
|
||||
del /s *.xml
|
||||
del *.cdf
|
||||
del *.rpt
|
||||
del /s new_rtl_netlist
|
||||
del /s old_rtl_netlist
|
||||
pause
|
||||
193
Apple - 2_MiST/rtl/AppleII_MiST.sv
Normal file
193
Apple - 2_MiST/rtl/AppleII_MiST.sv
Normal file
@@ -0,0 +1,193 @@
|
||||
module AppleII_MiST (
|
||||
output LED,
|
||||
output [5:0] VGA_R,
|
||||
output [5:0] VGA_G,
|
||||
output [5:0] VGA_B,
|
||||
output VGA_HS,
|
||||
output VGA_VS,
|
||||
output AUDIO_L,
|
||||
output AUDIO_R,
|
||||
input SPI_SCK,
|
||||
output SPI_DO,
|
||||
input SPI_DI,
|
||||
input SPI_SS2,
|
||||
input SPI_SS3,
|
||||
input CONF_DATA0,
|
||||
input CLOCK_27
|
||||
);
|
||||
|
||||
`include "rtl\build_id.v"
|
||||
|
||||
localparam CONF_STR = {
|
||||
"Apple II;;",
|
||||
"O12,Screen Type , Green, White, Color;",
|
||||
"O34,Scandoubler Fx,None,HQ2x,CRT 25%,CRT 50%;",
|
||||
"T6,Reset;",
|
||||
"V,v1.00.",`BUILD_DATE
|
||||
};
|
||||
|
||||
wire CLK_28M, CLK_14M, CLK_7M;
|
||||
wire pll_locked;
|
||||
|
||||
pll pll
|
||||
(
|
||||
.inclk0(CLOCK_27),
|
||||
.areset(0),
|
||||
.c0(CLK_28M),
|
||||
.c1(CLK_14M),
|
||||
.c2(CLK_7M),
|
||||
.locked(pll_locked)
|
||||
);
|
||||
|
||||
wire [31:0] status;
|
||||
wire [1:0] buttons;
|
||||
wire [1:0] switches;
|
||||
wire power_on_reset;
|
||||
wire reset = power_on_reset | status[0] | status[6] | buttons[1];
|
||||
wire [22:0] flash_clk;
|
||||
wire scandoubler_disable;
|
||||
wire ypbpr;
|
||||
wire ps2_kbd_clk, ps2_kbd_data;
|
||||
wire [9:0] audio;
|
||||
wire hsync,vsync;
|
||||
assign LED = 1;
|
||||
wire blankn = ~(hblank | vblank);
|
||||
wire hblank, vblank;
|
||||
wire hs, vs;
|
||||
wire VIDEO, COLOR_LINE, LD194, speaker;
|
||||
wire read;
|
||||
wire [7:0] K;
|
||||
wire [9:0] r,g,b;
|
||||
|
||||
|
||||
always @(CLK_14M) begin
|
||||
if (flash_clk[22] == 1'b1) power_on_reset = 1'b0;
|
||||
end
|
||||
|
||||
always @(CLK_14M) begin
|
||||
//rising_edge(CLK_14M) then flash_clk <= flash_clk + 1;
|
||||
end
|
||||
|
||||
video_mixer #(.LINE_LENGTH(640), .HALF_DEPTH(0)) video_mixer (
|
||||
.clk_sys(CLK_28M),
|
||||
.ce_pix(CLK_7M),
|
||||
.ce_pix_actual(CLK_7M),
|
||||
.SPI_SCK(SPI_SCK),
|
||||
.SPI_SS3(SPI_SS3),
|
||||
.SPI_DI(SPI_DI),
|
||||
.R(status[2:1] ? r[9:4] : 5'b0),
|
||||
.G(g[9:4]),
|
||||
.B(status[2:1] ? b[9:4] : 5'b0),
|
||||
.HSync(hs),
|
||||
.VSync(vs),
|
||||
.VGA_R(VGA_R),
|
||||
.VGA_G(VGA_G),
|
||||
.VGA_B(VGA_B),
|
||||
.VGA_VS(VGA_VS),
|
||||
.VGA_HS(VGA_HS),
|
||||
.scandoubler_disable(1'b1),
|
||||
.scanlines(scandoubler_disable ? 2'b00 : {status[4:3] == 3, status[4:3] == 2}),
|
||||
.hq2x(status[4:3]==1),
|
||||
.ypbpr_full(1),
|
||||
.line_start(0),
|
||||
.mono(0)
|
||||
);
|
||||
|
||||
mist_io #(.STRLEN(($size(CONF_STR)>>3))) mist_io (
|
||||
.clk_sys (CLK_28M ),
|
||||
.conf_str (CONF_STR ),
|
||||
.SPI_SCK (SPI_SCK ),
|
||||
.CONF_DATA0 (CONF_DATA0 ),
|
||||
.SPI_SS2 (SPI_SS2 ),
|
||||
.SPI_DO (SPI_DO ),
|
||||
.SPI_DI (SPI_DI ),
|
||||
.buttons (buttons ),
|
||||
.switches (switches ),
|
||||
.scandoubler_disable(scandoubler_disable),
|
||||
.ypbpr (ypbpr ),
|
||||
.ps2_kbd_clk (ps2_kbd_clk ),
|
||||
.ps2_kbd_data (ps2_kbd_data ),
|
||||
.status (status )
|
||||
);
|
||||
|
||||
wire ram_we;
|
||||
wire [13:0]ram_address;
|
||||
wire [7:0]ram_data;
|
||||
wire [7:0]ram_q;
|
||||
|
||||
ram ram(
|
||||
.clock(CLK_14M),
|
||||
.address(ram_address),
|
||||
.data(ram_data),
|
||||
.q(ram_q),
|
||||
.wren(ram_we)
|
||||
);
|
||||
|
||||
apple2 apple2 (
|
||||
.CLK_14M (CLK_14M),
|
||||
.CLK_2M (),//: out std_logic;
|
||||
.PRE_PHASE_ZERO (),//: out std_logic;
|
||||
.FLASH_CLK (),//: in std_logic; -- approx. 2 Hz flashing char clock
|
||||
.reset (reset),
|
||||
.ADDR (),//: out unsigned(15 downto 0); -- CPU address
|
||||
.ram_addr (ram_address),//: out unsigned(15 downto 0); -- RAM address
|
||||
.D (ram_data),//: out unsigned(7 downto 0); -- Data to RAM
|
||||
.ram_do (ram_q),//: in unsigned(7 downto 0); -- Data from RAM
|
||||
.PD (),//: in unsigned(7 downto 0); -- Data to CPU from peripherals
|
||||
.ram_we (ram_we),//: out std_logic; -- RAM write enable
|
||||
.VIDEO (VIDEO),
|
||||
.COLOR_LINE (COLOR_LINE),
|
||||
.HBL (hblank),
|
||||
.VBL (vblank),
|
||||
.LD194 (LD194),
|
||||
.K (K),
|
||||
.READ_KEY (read),
|
||||
.AN (),//: out std_logic_vector(3 downto 0); -- Annunciator outputs
|
||||
// GAMEPORT input bits:
|
||||
// 7 6 5 4 3 2 1 0
|
||||
// pdl3 pdl2 pdl1 pdl0 pb3 pb2 pb1 casette
|
||||
.GAMEPORT (),//: in std_logic_vector(7 downto 0);
|
||||
.PDL_STROBE (),//: out std_logic; -- Pulses high when C07x read
|
||||
.STB (),//: out std_logic; -- Pulses high when C04x read
|
||||
.IO_SELECT (),//: out std_logic_vector(7 downto 0);
|
||||
.DEVICE_SELECT (),//: out std_logic_vector(7 downto 0);
|
||||
.pcDebugOut (),//: out unsigned(15 downto 0);
|
||||
.opcodeDebugOut (),//: out unsigned(7 downto 0);
|
||||
.speaker (speaker)
|
||||
);
|
||||
|
||||
keyboard keyboard (
|
||||
.PS2_Clk (ps2_kbd_clk),
|
||||
.PS2_Data (ps2_kbd_data),
|
||||
.CLK_14M (CLK_14M),
|
||||
.reset (reset),
|
||||
.read (read),
|
||||
.K (K),
|
||||
);
|
||||
|
||||
vga_controller vga_controller (
|
||||
.CLK_28M (CLK_28M),
|
||||
.VIDEO (VIDEO),
|
||||
.COLOR_LINE (COLOR_LINE),
|
||||
.COLOR (status[2:1]==2),
|
||||
.HBL (hblank),
|
||||
.VBL (vblank),
|
||||
.LD194 (LD194),
|
||||
.VGA_HS (hs),
|
||||
.VGA_VS (vs),
|
||||
.VGA_R (r),
|
||||
.VGA_G (g),
|
||||
.VGA_B (b),
|
||||
);
|
||||
|
||||
dac dac (
|
||||
.CLK_DAC (CLK_28M),
|
||||
.RST (),
|
||||
.IN_DAC (speaker & 15'b0),
|
||||
.OUT_DAC (AUDIO_L)
|
||||
);
|
||||
|
||||
assign AUDIO_R = AUDIO_L;
|
||||
|
||||
|
||||
endmodule
|
||||
5
Apple - 2_MiST/rtl/CLK28MPLL.qip
Normal file
5
Apple - 2_MiST/rtl/CLK28MPLL.qip
Normal file
@@ -0,0 +1,5 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
|
||||
set_global_assignment -name IP_TOOL_VERSION "8.0"
|
||||
set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "CLK28MPLL.vhd"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "CLK28MPLL.cmp"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "CLK28MPLL.ppf"]
|
||||
376
Apple - 2_MiST/rtl/CLK28MPLL.vhd
Normal file
376
Apple - 2_MiST/rtl/CLK28MPLL.vhd
Normal file
@@ -0,0 +1,376 @@
|
||||
-- megafunction wizard: %ALTPLL%
|
||||
-- GENERATION: STANDARD
|
||||
-- VERSION: WM1.0
|
||||
-- MODULE: altpll
|
||||
|
||||
-- ============================================================
|
||||
-- File Name: CLK28MPLL.vhd
|
||||
-- Megafunction Name(s):
|
||||
-- altpll
|
||||
--
|
||||
-- Simulation Library Files(s):
|
||||
-- altera_mf
|
||||
-- ============================================================
|
||||
-- ************************************************************
|
||||
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
--
|
||||
-- 8.0 Build 215 05/29/2008 SJ Full Version
|
||||
-- ************************************************************
|
||||
|
||||
|
||||
--Copyright (C) 1991-2008 Altera Corporation
|
||||
--Your use of Altera Corporation's design tools, logic functions
|
||||
--and other software and tools, and its AMPP partner logic
|
||||
--functions, and any output files from any of the foregoing
|
||||
--(including device programming or simulation files), and any
|
||||
--associated documentation or information are expressly subject
|
||||
--to the terms and conditions of the Altera Program License
|
||||
--Subscription Agreement, Altera MegaCore Function License
|
||||
--Agreement, or other applicable license agreement, including,
|
||||
--without limitation, that your use is for the sole purpose of
|
||||
--programming logic devices manufactured by Altera and sold by
|
||||
--Altera or its authorized distributors. Please refer to the
|
||||
--applicable agreement for further details.
|
||||
|
||||
|
||||
LIBRARY ieee;
|
||||
USE ieee.std_logic_1164.all;
|
||||
|
||||
LIBRARY altera_mf;
|
||||
USE altera_mf.all;
|
||||
|
||||
ENTITY CLK28MPLL IS
|
||||
PORT
|
||||
(
|
||||
inclk0 : IN STD_LOGIC := '0';
|
||||
c0 : OUT STD_LOGIC ;
|
||||
c1 : OUT STD_LOGIC
|
||||
);
|
||||
END CLK28MPLL;
|
||||
|
||||
|
||||
ARCHITECTURE SYN OF clk28mpll IS
|
||||
|
||||
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (5 DOWNTO 0);
|
||||
SIGNAL sub_wire1 : STD_LOGIC ;
|
||||
SIGNAL sub_wire2 : STD_LOGIC ;
|
||||
SIGNAL sub_wire3 : STD_LOGIC ;
|
||||
SIGNAL sub_wire4 : STD_LOGIC_VECTOR (1 DOWNTO 0);
|
||||
SIGNAL sub_wire5_bv : BIT_VECTOR (0 DOWNTO 0);
|
||||
SIGNAL sub_wire5 : STD_LOGIC_VECTOR (0 DOWNTO 0);
|
||||
|
||||
|
||||
|
||||
COMPONENT altpll
|
||||
GENERIC (
|
||||
clk0_divide_by : NATURAL;
|
||||
clk0_duty_cycle : NATURAL;
|
||||
clk0_multiply_by : NATURAL;
|
||||
clk0_phase_shift : STRING;
|
||||
clk1_divide_by : NATURAL;
|
||||
clk1_duty_cycle : NATURAL;
|
||||
clk1_multiply_by : NATURAL;
|
||||
clk1_phase_shift : STRING;
|
||||
compensate_clock : STRING;
|
||||
inclk0_input_frequency : NATURAL;
|
||||
intended_device_family : STRING;
|
||||
lpm_hint : STRING;
|
||||
lpm_type : STRING;
|
||||
operation_mode : STRING;
|
||||
port_activeclock : STRING;
|
||||
port_areset : STRING;
|
||||
port_clkbad0 : STRING;
|
||||
port_clkbad1 : STRING;
|
||||
port_clkloss : STRING;
|
||||
port_clkswitch : STRING;
|
||||
port_configupdate : STRING;
|
||||
port_fbin : STRING;
|
||||
port_inclk0 : STRING;
|
||||
port_inclk1 : STRING;
|
||||
port_locked : STRING;
|
||||
port_pfdena : STRING;
|
||||
port_phasecounterselect : STRING;
|
||||
port_phasedone : STRING;
|
||||
port_phasestep : STRING;
|
||||
port_phaseupdown : STRING;
|
||||
port_pllena : STRING;
|
||||
port_scanaclr : STRING;
|
||||
port_scanclk : STRING;
|
||||
port_scanclkena : STRING;
|
||||
port_scandata : STRING;
|
||||
port_scandataout : STRING;
|
||||
port_scandone : STRING;
|
||||
port_scanread : STRING;
|
||||
port_scanwrite : STRING;
|
||||
port_clk0 : STRING;
|
||||
port_clk1 : STRING;
|
||||
port_clk2 : STRING;
|
||||
port_clk3 : STRING;
|
||||
port_clk4 : STRING;
|
||||
port_clk5 : STRING;
|
||||
port_clkena0 : STRING;
|
||||
port_clkena1 : STRING;
|
||||
port_clkena2 : STRING;
|
||||
port_clkena3 : STRING;
|
||||
port_clkena4 : STRING;
|
||||
port_clkena5 : STRING;
|
||||
port_extclk0 : STRING;
|
||||
port_extclk1 : STRING;
|
||||
port_extclk2 : STRING;
|
||||
port_extclk3 : STRING
|
||||
);
|
||||
PORT (
|
||||
inclk : IN STD_LOGIC_VECTOR (1 DOWNTO 0);
|
||||
clk : OUT STD_LOGIC_VECTOR (5 DOWNTO 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
BEGIN
|
||||
sub_wire5_bv(0 DOWNTO 0) <= "0";
|
||||
sub_wire5 <= To_stdlogicvector(sub_wire5_bv);
|
||||
sub_wire2 <= sub_wire0(1);
|
||||
sub_wire1 <= sub_wire0(0);
|
||||
c0 <= sub_wire1;
|
||||
c1 <= sub_wire2;
|
||||
sub_wire3 <= inclk0;
|
||||
sub_wire4 <= sub_wire5(0 DOWNTO 0) & sub_wire3;
|
||||
|
||||
altpll_component : altpll
|
||||
GENERIC MAP (
|
||||
clk0_divide_by => 250,
|
||||
clk0_duty_cycle => 50,
|
||||
clk0_multiply_by => 143,
|
||||
clk0_phase_shift => "0",
|
||||
clk1_divide_by => 500,
|
||||
clk1_duty_cycle => 50,
|
||||
clk1_multiply_by => 143,
|
||||
clk1_phase_shift => "0",
|
||||
compensate_clock => "CLK0",
|
||||
inclk0_input_frequency => 20000,
|
||||
intended_device_family => "Cyclone II",
|
||||
lpm_hint => "CBX_MODULE_PREFIX=CLK28MPLL",
|
||||
lpm_type => "altpll",
|
||||
operation_mode => "NORMAL",
|
||||
port_activeclock => "PORT_UNUSED",
|
||||
port_areset => "PORT_UNUSED",
|
||||
port_clkbad0 => "PORT_UNUSED",
|
||||
port_clkbad1 => "PORT_UNUSED",
|
||||
port_clkloss => "PORT_UNUSED",
|
||||
port_clkswitch => "PORT_UNUSED",
|
||||
port_configupdate => "PORT_UNUSED",
|
||||
port_fbin => "PORT_UNUSED",
|
||||
port_inclk0 => "PORT_USED",
|
||||
port_inclk1 => "PORT_UNUSED",
|
||||
port_locked => "PORT_UNUSED",
|
||||
port_pfdena => "PORT_UNUSED",
|
||||
port_phasecounterselect => "PORT_UNUSED",
|
||||
port_phasedone => "PORT_UNUSED",
|
||||
port_phasestep => "PORT_UNUSED",
|
||||
port_phaseupdown => "PORT_UNUSED",
|
||||
port_pllena => "PORT_UNUSED",
|
||||
port_scanaclr => "PORT_UNUSED",
|
||||
port_scanclk => "PORT_UNUSED",
|
||||
port_scanclkena => "PORT_UNUSED",
|
||||
port_scandata => "PORT_UNUSED",
|
||||
port_scandataout => "PORT_UNUSED",
|
||||
port_scandone => "PORT_UNUSED",
|
||||
port_scanread => "PORT_UNUSED",
|
||||
port_scanwrite => "PORT_UNUSED",
|
||||
port_clk0 => "PORT_USED",
|
||||
port_clk1 => "PORT_USED",
|
||||
port_clk2 => "PORT_UNUSED",
|
||||
port_clk3 => "PORT_UNUSED",
|
||||
port_clk4 => "PORT_UNUSED",
|
||||
port_clk5 => "PORT_UNUSED",
|
||||
port_clkena0 => "PORT_UNUSED",
|
||||
port_clkena1 => "PORT_UNUSED",
|
||||
port_clkena2 => "PORT_UNUSED",
|
||||
port_clkena3 => "PORT_UNUSED",
|
||||
port_clkena4 => "PORT_UNUSED",
|
||||
port_clkena5 => "PORT_UNUSED",
|
||||
port_extclk0 => "PORT_UNUSED",
|
||||
port_extclk1 => "PORT_UNUSED",
|
||||
port_extclk2 => "PORT_UNUSED",
|
||||
port_extclk3 => "PORT_UNUSED"
|
||||
)
|
||||
PORT MAP (
|
||||
inclk => sub_wire4,
|
||||
clk => sub_wire0
|
||||
);
|
||||
|
||||
|
||||
|
||||
END SYN;
|
||||
|
||||
-- ============================================================
|
||||
-- CNX file retrieval info
|
||||
-- ============================================================
|
||||
-- Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
|
||||
-- Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "0"
|
||||
-- Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
|
||||
-- Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
|
||||
-- Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
|
||||
-- Retrieval info: PRIVATE: BANDWIDTH_USE_CUSTOM STRING "0"
|
||||
-- Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
|
||||
-- Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "1"
|
||||
-- Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
|
||||
-- Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
|
||||
-- Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "e0"
|
||||
-- Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "6"
|
||||
-- Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "18"
|
||||
-- Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
|
||||
-- Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
|
||||
-- Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
|
||||
-- Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
|
||||
-- Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
|
||||
-- Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "1"
|
||||
-- Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
|
||||
-- Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
|
||||
-- Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "50.000"
|
||||
-- Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
|
||||
-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
|
||||
-- Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
|
||||
-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
|
||||
-- Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
|
||||
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
|
||||
-- Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
|
||||
-- Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
|
||||
-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
|
||||
-- Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
-- Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "ps"
|
||||
-- Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
|
||||
-- Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
|
||||
-- Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
|
||||
-- Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "5"
|
||||
-- Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "28.60000000"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "14.30000000"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "1"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "1"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
|
||||
-- Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
|
||||
-- Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "0"
|
||||
-- Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
|
||||
-- Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
|
||||
-- Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
-- Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "ps"
|
||||
-- Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: PLL_ENA_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
|
||||
-- Retrieval info: PRIVATE: RECONFIG_FILE STRING "CLK14MPLL.mif"
|
||||
-- Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
|
||||
-- Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "0"
|
||||
-- Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
|
||||
-- Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
|
||||
-- Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
|
||||
-- Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
|
||||
-- Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
|
||||
-- Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
|
||||
-- Retrieval info: PRIVATE: SPREAD_USE STRING "0"
|
||||
-- Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
|
||||
-- Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
|
||||
-- Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
|
||||
-- Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
|
||||
-- Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
|
||||
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
-- Retrieval info: PRIVATE: USE_CLK0 STRING "1"
|
||||
-- Retrieval info: PRIVATE: USE_CLK1 STRING "1"
|
||||
-- Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
|
||||
-- Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
|
||||
-- Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
|
||||
-- Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
|
||||
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
-- Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "250"
|
||||
-- Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
|
||||
-- Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "143"
|
||||
-- Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
|
||||
-- Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "500"
|
||||
-- Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
|
||||
-- Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "143"
|
||||
-- Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"
|
||||
-- Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
|
||||
-- Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "20000"
|
||||
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone II"
|
||||
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
|
||||
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
|
||||
-- Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
|
||||
-- Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
|
||||
-- Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
|
||||
-- Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
|
||||
-- Retrieval info: USED_PORT: @clk 0 0 6 0 OUTPUT_CLK_EXT VCC "@clk[5..0]"
|
||||
-- Retrieval info: USED_PORT: @extclk 0 0 4 0 OUTPUT_CLK_EXT VCC "@extclk[3..0]"
|
||||
-- Retrieval info: USED_PORT: @inclk 0 0 2 0 INPUT_CLK_EXT VCC "@inclk[1..0]"
|
||||
-- Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
|
||||
-- Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
|
||||
-- Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
|
||||
-- Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
|
||||
-- Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
|
||||
-- Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
|
||||
-- Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL CLK28MPLL.vhd TRUE FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL CLK28MPLL.ppf TRUE FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL CLK28MPLL.inc FALSE FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL CLK28MPLL.cmp TRUE FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL CLK28MPLL.bsf FALSE FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL CLK28MPLL_inst.vhd FALSE FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL CLK28MPLL_waveforms.html FALSE FALSE
|
||||
-- Retrieval info: GEN_FILE: TYPE_NORMAL CLK28MPLL_wave*.jpg FALSE FALSE
|
||||
-- Retrieval info: LIB_FILE: altera_mf
|
||||
-- Retrieval info: CBX_MODULE_PREFIX: ON
|
||||
147
Apple - 2_MiST/rtl/PS2_Ctrl.vhd
Normal file
147
Apple - 2_MiST/rtl/PS2_Ctrl.vhd
Normal file
@@ -0,0 +1,147 @@
|
||||
-- PS2_Ctrl.vhd
|
||||
-- ------------------------------------------------
|
||||
-- Simplified PS/2 Controller (kbd, mouse...)
|
||||
-- ------------------------------------------------
|
||||
-- Only the Receive function is implemented !
|
||||
-- (c) ALSE. http://www.alse-fr.com
|
||||
|
||||
library IEEE;
|
||||
use IEEE.Std_Logic_1164.all;
|
||||
use IEEE.Numeric_Std.all;
|
||||
|
||||
-- --------------------------------------
|
||||
Entity PS2_Ctrl is
|
||||
-- --------------------------------------
|
||||
generic (FilterSize : positive := 8);
|
||||
port( Clk : in std_logic; -- System Clock
|
||||
Reset : in std_logic; -- System Reset
|
||||
PS2_Clk : in std_logic; -- Keyboard Clock Line
|
||||
PS2_Data : in std_logic; -- Keyboard Data Line
|
||||
DoRead : in std_logic; -- From outside when reading the scan code
|
||||
Scan_Err : out std_logic; -- To outside : Parity or Overflow error
|
||||
Scan_DAV : out std_logic; -- To outside when a scan code has arrived
|
||||
Scan_Code : out unsigned(7 downto 0) -- Eight bits Data Out
|
||||
);
|
||||
end PS2_Ctrl;
|
||||
|
||||
-- --------------------------------------
|
||||
Architecture ALSE_RTL of PS2_Ctrl is
|
||||
-- --------------------------------------
|
||||
-- (c) ALSE. http://www.alse-fr.com
|
||||
-- Author : Bert Cuzeau.
|
||||
-- Fully synchronous solution, same Filter on PS2_Clk.
|
||||
-- Still as compact as "Plain_wrong"...
|
||||
-- Possible improvement : add TIMEOUT on PS2_Clk while shifting
|
||||
-- Note: PS2_Data is resynchronized though this should not be
|
||||
-- necessary (qualified by Fall_Clk and does not change at that time).
|
||||
-- Note the tricks to correctly interpret 'H' as '1' in RTL simulation.
|
||||
|
||||
signal PS2_Datr : std_logic;
|
||||
|
||||
subtype Filter_t is std_logic_vector(FilterSize-1 downto 0);
|
||||
signal Filter : Filter_t;
|
||||
signal Fall_Clk : std_logic;
|
||||
signal Bit_Cnt : unsigned(3 downto 0);
|
||||
signal Parity : std_logic;
|
||||
signal Scan_DAVi : std_logic;
|
||||
|
||||
signal S_Reg : unsigned(8 downto 0);
|
||||
|
||||
signal PS2_Clk_f : std_logic;
|
||||
|
||||
Type State_t is (Idle, Shifting);
|
||||
signal State : State_t;
|
||||
|
||||
begin
|
||||
|
||||
Scan_DAV <= Scan_DAVi;
|
||||
|
||||
-- This filters digitally the raw clock signal coming from the keyboard :
|
||||
-- * Eight consecutive PS2_Clk=1 makes the filtered_clock go high
|
||||
-- * Eight consecutive PS2_Clk=0 makes the filtered_clock go low
|
||||
-- Implies a (FilterSize+1) x Tsys_clock delay on Fall_Clk wrt Data
|
||||
-- Also in charge of the re-synchronization of PS2_Data
|
||||
|
||||
process (Clk,Reset)
|
||||
begin
|
||||
if Reset='1' then
|
||||
PS2_Datr <= '0';
|
||||
PS2_Clk_f <= '0';
|
||||
Filter <= (others=>'0');
|
||||
Fall_Clk <= '0';
|
||||
elsif rising_edge (Clk) then
|
||||
PS2_Datr <= PS2_Data and PS2_Data; -- also turns 'H' into '1'
|
||||
Fall_Clk <= '0';
|
||||
Filter <= (PS2_Clk and PS2_CLK) & Filter(Filter'high downto 1);
|
||||
if Filter = Filter_t'(others=>'1') then
|
||||
PS2_Clk_f <= '1';
|
||||
elsif Filter = Filter_t'(others=>'0') then
|
||||
PS2_Clk_f <= '0';
|
||||
if PS2_Clk_f = '1' then
|
||||
Fall_Clk <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
-- This simple State Machine reads in the Serial Data
|
||||
-- coming from the PS/2 peripheral.
|
||||
|
||||
process(Clk,Reset)
|
||||
begin
|
||||
|
||||
if Reset='1' then
|
||||
State <= Idle;
|
||||
Bit_Cnt <= (others => '0');
|
||||
S_Reg <= (others => '0');
|
||||
Scan_Code <= (others => '0');
|
||||
Parity <= '0';
|
||||
Scan_Davi <= '0';
|
||||
Scan_Err <= '0';
|
||||
|
||||
elsif rising_edge (Clk) then
|
||||
|
||||
if DoRead='1' then
|
||||
Scan_Davi <= '0'; -- note: this assgnmnt can be overriden
|
||||
end if;
|
||||
|
||||
case State is
|
||||
|
||||
when Idle =>
|
||||
Parity <= '0';
|
||||
Bit_Cnt <= (others => '0');
|
||||
-- note that we dont need to clear the Shift Register
|
||||
if Fall_Clk='1' and PS2_Datr='0' then -- Start bit
|
||||
Scan_Err <= '0';
|
||||
State <= Shifting;
|
||||
end if;
|
||||
|
||||
when Shifting =>
|
||||
if Bit_Cnt >= 9 then
|
||||
if Fall_Clk='1' then -- Stop Bit
|
||||
-- Error is (wrong Parity) or (Stop='0') or Overflow
|
||||
Scan_Err <= (not Parity) or (not PS2_Datr) or Scan_DAVi;
|
||||
Scan_Davi <= '1';
|
||||
Scan_Code <= S_Reg(7 downto 0);
|
||||
State <= Idle;
|
||||
end if;
|
||||
elsif Fall_Clk='1' then
|
||||
Bit_Cnt <= Bit_Cnt + 1;
|
||||
S_Reg <= PS2_Datr & S_Reg (S_Reg'high downto 1); -- Shift right
|
||||
Parity <= Parity xor PS2_Datr;
|
||||
end if;
|
||||
|
||||
when others => -- never reached
|
||||
State <= Idle;
|
||||
|
||||
end case;
|
||||
|
||||
--Scan_Err <= '0'; -- to create an on-purpose error on Scan_Err !
|
||||
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
end ALSE_RTL;
|
||||
|
||||
286
Apple - 2_MiST/rtl/apple2.vhd
Normal file
286
Apple - 2_MiST/rtl/apple2.vhd
Normal file
@@ -0,0 +1,286 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Top level of an Apple ][+
|
||||
--
|
||||
-- Stephen A. Edwards, sedwards@cs.columbia.edu
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity apple2 is
|
||||
port (
|
||||
CLK_14M : in std_logic; -- 14.31818 MHz master clock
|
||||
CLK_2M : out std_logic;
|
||||
PRE_PHASE_ZERO : out std_logic;
|
||||
FLASH_CLK : in std_logic; -- approx. 2 Hz flashing char clock
|
||||
reset : in std_logic;
|
||||
ADDR : out unsigned(15 downto 0); -- CPU address
|
||||
ram_addr : out unsigned(15 downto 0); -- RAM address
|
||||
D : out unsigned(7 downto 0); -- Data to RAM
|
||||
ram_do : in unsigned(7 downto 0); -- Data from RAM
|
||||
PD : in unsigned(7 downto 0); -- Data to CPU from peripherals
|
||||
ram_we : out std_logic; -- RAM write enable
|
||||
VIDEO : out std_logic;
|
||||
COLOR_LINE : out std_logic;
|
||||
HBL : out std_logic;
|
||||
VBL : out std_logic;
|
||||
LD194 : out std_logic;
|
||||
K : in unsigned(7 downto 0); -- Keyboard data
|
||||
READ_KEY : out std_logic; -- Processor has read key
|
||||
AN : out std_logic_vector(3 downto 0); -- Annunciator outputs
|
||||
-- GAMEPORT input bits:
|
||||
-- 7 6 5 4 3 2 1 0
|
||||
-- pdl3 pdl2 pdl1 pdl0 pb3 pb2 pb1 casette
|
||||
GAMEPORT : in std_logic_vector(7 downto 0);
|
||||
PDL_STROBE : out std_logic; -- Pulses high when C07x read
|
||||
STB : out std_logic; -- Pulses high when C04x read
|
||||
IO_SELECT : out std_logic_vector(7 downto 0);
|
||||
DEVICE_SELECT : out std_logic_vector(7 downto 0);
|
||||
pcDebugOut : out unsigned(15 downto 0);
|
||||
opcodeDebugOut : out unsigned(7 downto 0);
|
||||
speaker : out std_logic -- One-bit speaker output
|
||||
);
|
||||
end apple2;
|
||||
|
||||
architecture rtl of apple2 is
|
||||
|
||||
-- Clocks
|
||||
signal CLK_7M : std_logic;
|
||||
signal Q3, RAS_N, CAS_N, AX : std_logic;
|
||||
signal PHASE_ZERO, PRE_PHASE_ZERO_sig : std_logic;
|
||||
signal COLOR_REF : std_logic;
|
||||
|
||||
-- From the timing generator
|
||||
signal VIDEO_ADDRESS : unsigned(15 downto 0);
|
||||
signal LDPS_N : std_logic;
|
||||
signal H0, VA, VB, VC, V2, V4 : std_logic;
|
||||
signal BLANK, LD194_I : std_logic;
|
||||
|
||||
signal HIRES : std_logic; -- from video generator B11 p6
|
||||
|
||||
-- Soft switches
|
||||
signal soft_switches : std_logic_vector(7 downto 0) := "00000000";
|
||||
signal TEXT_MODE : std_logic;
|
||||
signal MIXED_MODE : std_logic;
|
||||
signal PAGE2 : std_logic;
|
||||
signal HIRES_MODE : std_logic;
|
||||
|
||||
-- CPU signals
|
||||
signal D_IN : unsigned(7 downto 0);
|
||||
signal A : unsigned(15 downto 0);
|
||||
signal we : std_logic;
|
||||
|
||||
-- Main ROM signals
|
||||
signal rom_out : unsigned(7 downto 0);
|
||||
signal rom_addr : unsigned(13 downto 0);
|
||||
|
||||
-- Address decoder signals
|
||||
signal RAM_SELECT : std_logic := '1';
|
||||
signal KEYBOARD_SELECT : std_logic := '0';
|
||||
signal SPEAKER_SELECT : std_logic;
|
||||
signal SOFTSWITCH_SELECT : std_logic;
|
||||
signal ROM_SELECT : std_logic;
|
||||
signal GAMEPORT_SELECT : std_logic;
|
||||
signal IO_STROBE : std_logic;
|
||||
|
||||
-- Speaker signal
|
||||
signal speaker_sig : std_logic := '0';
|
||||
|
||||
signal DL : unsigned(7 downto 0); -- Latched RAM data
|
||||
|
||||
begin
|
||||
|
||||
CLK_2M <= Q3;
|
||||
PRE_PHASE_ZERO <= PRE_PHASE_ZERO_sig;
|
||||
|
||||
ram_addr <= A when PHASE_ZERO = '1' else VIDEO_ADDRESS;
|
||||
ram_we <= we and not RAS_N when PHASE_ZERO = '1' else '0';
|
||||
|
||||
-- Latch RAM data on the rising edge of RAS
|
||||
RAM_data_latch : process (CLK_14M)
|
||||
begin
|
||||
if rising_edge(CLK_14M) then
|
||||
if AX = '1' and CAS_N = '0' and RAS_N = '0' then
|
||||
DL <= ram_do;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
ADDR <= A;
|
||||
|
||||
-- Address decoding
|
||||
rom_addr <= (A(13) and A(12)) & (not A(12)) & A(11 downto 0);
|
||||
|
||||
address_decoder: process (A)
|
||||
begin
|
||||
ROM_SELECT <= '0';
|
||||
RAM_SELECT <= '0';
|
||||
KEYBOARD_SELECT <= '0';
|
||||
READ_KEY <= '0';
|
||||
SPEAKER_SELECT <= '0';
|
||||
SOFTSWITCH_SELECT <= '0';
|
||||
GAMEPORT_SELECT <= '0';
|
||||
PDL_STROBE <= '0';
|
||||
STB <= '0';
|
||||
IO_SELECT <= (others => '0');
|
||||
DEVICE_SELECT <= (others => '0');
|
||||
IO_STROBE <= '0';
|
||||
case A(15 downto 14) is
|
||||
when "00" | "01" | "10" => -- 0000 - BFFF
|
||||
RAM_SELECT <= '1';
|
||||
when "11" => -- C000 - FFFF
|
||||
case A(13 downto 12) is
|
||||
when "00" => -- C000 - CFFF
|
||||
case A(11 downto 8) is
|
||||
when x"0" => -- C000 - C0FF
|
||||
case A(7 downto 4) is
|
||||
when x"0" => -- C000 - C00F
|
||||
KEYBOARD_SELECT <= '1';
|
||||
when x"1" => -- C010 - C01F
|
||||
READ_KEY <= '1';
|
||||
when x"3" => -- C030 - C03F
|
||||
SPEAKER_SELECT <= '1';
|
||||
when x"4" =>
|
||||
STB <= '1';
|
||||
when x"5" => -- C050 - C05F
|
||||
SOFTSWITCH_SELECT <= '1';
|
||||
when x"6" => -- C060 - C06F
|
||||
GAMEPORT_SELECT <= '1';
|
||||
when x"7" => -- C070 - C07F
|
||||
PDL_STROBE <= '1';
|
||||
when x"8" | x"9" | x"A" | -- C080 - C0FF
|
||||
x"B" | x"C" | x"D" | x"E" | x"F" =>
|
||||
DEVICE_SELECT(TO_INTEGER(A(6 downto 4))) <= '1';
|
||||
when others => null;
|
||||
end case;
|
||||
when x"1" | x"2" | x"3" | -- C100 - C7FF
|
||||
x"4" | x"5" | x"6" | x"7" =>
|
||||
IO_SELECT(TO_INTEGER(A(10 downto 8))) <= '1';
|
||||
when x"8" | x"9" | x"A" | -- C800 - CFFF
|
||||
x"B" | x"C" | x"D" | x"E" | x"F" =>
|
||||
IO_STROBE <= '1';
|
||||
when others => null;
|
||||
end case;
|
||||
when "01" | "10" | "11" => -- D000 - FFFF
|
||||
ROM_SELECT <= '1';
|
||||
when others =>
|
||||
null;
|
||||
end case;
|
||||
when others => null;
|
||||
end case;
|
||||
end process address_decoder;
|
||||
|
||||
speaker_ctrl: process (Q3)
|
||||
begin
|
||||
if rising_edge(Q3) then
|
||||
if PRE_PHASE_ZERO_sig = '1' and SPEAKER_SELECT = '1' then
|
||||
speaker_sig <= not speaker_sig;
|
||||
end if;
|
||||
end if;
|
||||
end process speaker_ctrl;
|
||||
|
||||
softswitches: process (Q3)
|
||||
begin
|
||||
if rising_edge(Q3) then
|
||||
if PRE_PHASE_ZERO_sig = '1' and SOFTSWITCH_SELECT = '1' then
|
||||
soft_switches(TO_INTEGER(A(3 downto 1))) <= A(0);
|
||||
end if;
|
||||
end if;
|
||||
end process softswitches;
|
||||
|
||||
TEXT_MODE <= soft_switches(0);
|
||||
MIXED_MODE <= soft_switches(1);
|
||||
PAGE2 <= soft_switches(2);
|
||||
HIRES_MODE <= soft_switches(3);
|
||||
AN <= soft_switches(7 downto 4);
|
||||
|
||||
speaker <= speaker_sig;
|
||||
|
||||
D_IN <= DL when RAM_SELECT = '1' else -- RAM
|
||||
K when KEYBOARD_SELECT = '1' else -- Keyboard
|
||||
GAMEPORT(TO_INTEGER(A(2 downto 0))) & "0000000" -- Gameport
|
||||
when GAMEPORT_SELECT = '1' else
|
||||
rom_out when ROM_SELECT = '1' else -- ROMs
|
||||
PD; -- Peripherals
|
||||
|
||||
LD194 <= LD194_I;
|
||||
|
||||
timing : entity work.timing_generator port map (
|
||||
CLK_14M => CLK_14M,
|
||||
CLK_7M => CLK_7M,
|
||||
CAS_N => CAS_N,
|
||||
RAS_N => RAS_N,
|
||||
Q3 => Q3,
|
||||
AX => AX,
|
||||
PHI0 => PHASE_ZERO,
|
||||
PRE_PHI0 => PRE_PHASE_ZERO_sig,
|
||||
COLOR_REF => COLOR_REF,
|
||||
TEXT_MODE => TEXT_MODE,
|
||||
PAGE2 => PAGE2,
|
||||
HIRES => HIRES,
|
||||
VIDEO_ADDRESS => VIDEO_ADDRESS,
|
||||
H0 => H0,
|
||||
VA => VA,
|
||||
VB => VB,
|
||||
VC => VC,
|
||||
V2 => V2,
|
||||
V4 => V4,
|
||||
VBL => VBL,
|
||||
HBL => HBL,
|
||||
BLANK => BLANK,
|
||||
LDPS_N => LDPS_N,
|
||||
LD194 => LD194_I);
|
||||
|
||||
video_display : entity work.video_generator port map (
|
||||
CLK_14M => CLK_14M,
|
||||
CLK_7M => CLK_7M,
|
||||
AX => AX,
|
||||
CAS_N => CAS_N,
|
||||
TEXT_MODE => TEXT_MODE,
|
||||
PAGE2 => PAGE2,
|
||||
HIRES_MODE => HIRES_MODE,
|
||||
MIXED_MODE => MIXED_MODE,
|
||||
H0 => H0,
|
||||
VA => VA,
|
||||
VB => VB,
|
||||
VC => VC,
|
||||
V2 => V2,
|
||||
V4 => V4,
|
||||
BLANK => BLANK,
|
||||
DL => DL,
|
||||
LDPS_N => LDPS_N,
|
||||
LD194 => LD194_I,
|
||||
FLASH_CLK => FLASH_CLK,
|
||||
HIRES => HIRES,
|
||||
VIDEO => VIDEO,
|
||||
COLOR_LINE => COLOR_LINE);
|
||||
|
||||
cpu : entity work.cpu65xx
|
||||
generic map (
|
||||
pipelineOpcode => false,
|
||||
pipelineAluMux => false,
|
||||
pipelineAluOut => false)
|
||||
port map (
|
||||
clk => Q3,
|
||||
enable => not PRE_PHASE_ZERO_sig,
|
||||
reset => reset,
|
||||
nmi_n => '1',
|
||||
irq_n => '1',
|
||||
di => D_IN,
|
||||
do => D,
|
||||
addr => A,
|
||||
we => we,
|
||||
debugPc => pcDebugOut,
|
||||
debugOpcode => opcodeDebugOut
|
||||
);
|
||||
|
||||
-- Original Apple had asynchronous ROMs. We use a synchronous ROM
|
||||
-- that needs its address earlier, hence the odd clock.
|
||||
roms : entity work.main_roms port map (
|
||||
addr => rom_addr,
|
||||
clk => CLK_14M,
|
||||
dout => rom_out);
|
||||
|
||||
end rtl;
|
||||
35
Apple - 2_MiST/rtl/build_id.tcl
Normal file
35
Apple - 2_MiST/rtl/build_id.tcl
Normal file
@@ -0,0 +1,35 @@
|
||||
# ================================================================================
|
||||
#
|
||||
# Build ID Verilog Module Script
|
||||
# Jeff Wiencrot - 8/1/2011
|
||||
#
|
||||
# Generates a Verilog module that contains a timestamp,
|
||||
# from the current build. These values are available from the build_date, build_time,
|
||||
# physical_address, and host_name output ports of the build_id module in the build_id.v
|
||||
# Verilog source file.
|
||||
#
|
||||
# ================================================================================
|
||||
|
||||
proc generateBuildID_Verilog {} {
|
||||
|
||||
# Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html)
|
||||
set buildDate [ clock format [ clock seconds ] -format %y%m%d ]
|
||||
set buildTime [ clock format [ clock seconds ] -format %H%M%S ]
|
||||
|
||||
# Create a Verilog file for output
|
||||
set outputFileName "rtl/build_id.v"
|
||||
set outputFile [open $outputFileName "w"]
|
||||
|
||||
# Output the Verilog source
|
||||
puts $outputFile "`define BUILD_DATE \"$buildDate\""
|
||||
puts $outputFile "`define BUILD_TIME \"$buildTime\""
|
||||
close $outputFile
|
||||
|
||||
# Send confirmation message to the Messages window
|
||||
post_message "Generated build identification Verilog module: [pwd]/$outputFileName"
|
||||
post_message "Date: $buildDate"
|
||||
post_message "Time: $buildTime"
|
||||
}
|
||||
|
||||
# Comment out this line to prevent the process from automatically executing when the file is sourced:
|
||||
generateBuildID_Verilog
|
||||
2
Apple - 2_MiST/rtl/build_id.v
Normal file
2
Apple - 2_MiST/rtl/build_id.v
Normal file
@@ -0,0 +1,2 @@
|
||||
`define BUILD_DATE "180506"
|
||||
`define BUILD_TIME "191822"
|
||||
539
Apple - 2_MiST/rtl/character_rom.vhd
Normal file
539
Apple - 2_MiST/rtl/character_rom.vhd
Normal file
@@ -0,0 +1,539 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity character_rom is
|
||||
|
||||
port (
|
||||
addr : in unsigned(8 downto 0);
|
||||
clk : in std_logic;
|
||||
dout : out unsigned(4 downto 0));
|
||||
end character_rom;
|
||||
|
||||
architecture rtl of character_rom is
|
||||
type rom_array is array (0 to 511) of unsigned(4 downto 0);
|
||||
|
||||
constant ROM : rom_array := (
|
||||
"01110",
|
||||
"10001",
|
||||
"10101",
|
||||
"11101",
|
||||
"01101",
|
||||
"00001",
|
||||
"11110",
|
||||
"00000",
|
||||
"00100",
|
||||
"01010",
|
||||
"10001",
|
||||
"10001",
|
||||
"11111",
|
||||
"10001",
|
||||
"10001",
|
||||
"00000",
|
||||
"01111",
|
||||
"10001",
|
||||
"10001",
|
||||
"01111",
|
||||
"10001",
|
||||
"10001",
|
||||
"01111",
|
||||
"00000",
|
||||
"01110",
|
||||
"10001",
|
||||
"00001",
|
||||
"00001",
|
||||
"00001",
|
||||
"10001",
|
||||
"01110",
|
||||
"00000",
|
||||
"01111",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"01111",
|
||||
"00000",
|
||||
"11111",
|
||||
"00001",
|
||||
"00001",
|
||||
"01111",
|
||||
"00001",
|
||||
"00001",
|
||||
"11111",
|
||||
"00000",
|
||||
"11111",
|
||||
"00001",
|
||||
"00001",
|
||||
"01111",
|
||||
"00001",
|
||||
"00001",
|
||||
"00001",
|
||||
"00000",
|
||||
"11110",
|
||||
"00001",
|
||||
"00001",
|
||||
"00001",
|
||||
"11001",
|
||||
"10001",
|
||||
"11110",
|
||||
"00000",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"11111",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"00000",
|
||||
"01110",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"01110",
|
||||
"00000",
|
||||
"10000",
|
||||
"10000",
|
||||
"10000",
|
||||
"10000",
|
||||
"10000",
|
||||
"10001",
|
||||
"01110",
|
||||
"00000",
|
||||
"10001",
|
||||
"01001",
|
||||
"00101",
|
||||
"00011",
|
||||
"00101",
|
||||
"01001",
|
||||
"10001",
|
||||
"00000",
|
||||
"00001",
|
||||
"00001",
|
||||
"00001",
|
||||
"00001",
|
||||
"00001",
|
||||
"00001",
|
||||
"11111",
|
||||
"00000",
|
||||
"10001",
|
||||
"11011",
|
||||
"10101",
|
||||
"10101",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"00000",
|
||||
"10001",
|
||||
"10001",
|
||||
"10011",
|
||||
"10101",
|
||||
"11001",
|
||||
"10001",
|
||||
"10001",
|
||||
"00000",
|
||||
"01110",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"01110",
|
||||
"00000",
|
||||
"01111",
|
||||
"10001",
|
||||
"10001",
|
||||
"01111",
|
||||
"00001",
|
||||
"00001",
|
||||
"00001",
|
||||
"00000",
|
||||
"01110",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"10101",
|
||||
"01001",
|
||||
"10110",
|
||||
"00000",
|
||||
"01111",
|
||||
"10001",
|
||||
"10001",
|
||||
"01111",
|
||||
"00101",
|
||||
"01001",
|
||||
"10001",
|
||||
"00000",
|
||||
"01110",
|
||||
"10001",
|
||||
"00001",
|
||||
"01110",
|
||||
"10000",
|
||||
"10001",
|
||||
"01110",
|
||||
"00000",
|
||||
"11111",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"00000",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"01110",
|
||||
"00000",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"01010",
|
||||
"00100",
|
||||
"00000",
|
||||
"10001",
|
||||
"10001",
|
||||
"10001",
|
||||
"10101",
|
||||
"10101",
|
||||
"11011",
|
||||
"10001",
|
||||
"00000",
|
||||
"10001",
|
||||
"10001",
|
||||
"01010",
|
||||
"00100",
|
||||
"01010",
|
||||
"10001",
|
||||
"10001",
|
||||
"00000",
|
||||
"10001",
|
||||
"10001",
|
||||
"01010",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"00000",
|
||||
"11111",
|
||||
"10000",
|
||||
"01000",
|
||||
"00100",
|
||||
"00010",
|
||||
"00001",
|
||||
"11111",
|
||||
"00000",
|
||||
"11111",
|
||||
"00011",
|
||||
"00011",
|
||||
"00011",
|
||||
"00011",
|
||||
"00011",
|
||||
"11111",
|
||||
"00000",
|
||||
"00000",
|
||||
"00001",
|
||||
"00010",
|
||||
"00100",
|
||||
"01000",
|
||||
"10000",
|
||||
"00000",
|
||||
"00000",
|
||||
"11111",
|
||||
"11000",
|
||||
"11000",
|
||||
"11000",
|
||||
"11000",
|
||||
"11000",
|
||||
"11111",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00100",
|
||||
"01010",
|
||||
"10001",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"11111",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"00000",
|
||||
"00100",
|
||||
"00000",
|
||||
"01010",
|
||||
"01010",
|
||||
"01010",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"01010",
|
||||
"01010",
|
||||
"11111",
|
||||
"01010",
|
||||
"11111",
|
||||
"01010",
|
||||
"01010",
|
||||
"00000",
|
||||
"00100",
|
||||
"11110",
|
||||
"00101",
|
||||
"01110",
|
||||
"10100",
|
||||
"01111",
|
||||
"00100",
|
||||
"00000",
|
||||
"00011",
|
||||
"10011",
|
||||
"01000",
|
||||
"00100",
|
||||
"00010",
|
||||
"11001",
|
||||
"11000",
|
||||
"00000",
|
||||
"00010",
|
||||
"00101",
|
||||
"00101",
|
||||
"00010",
|
||||
"10101",
|
||||
"01001",
|
||||
"10110",
|
||||
"00000",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00100",
|
||||
"00010",
|
||||
"00001",
|
||||
"00001",
|
||||
"00001",
|
||||
"00010",
|
||||
"00100",
|
||||
"00000",
|
||||
"00100",
|
||||
"01000",
|
||||
"10000",
|
||||
"10000",
|
||||
"10000",
|
||||
"01000",
|
||||
"00100",
|
||||
"00000",
|
||||
"00100",
|
||||
"10101",
|
||||
"01110",
|
||||
"00100",
|
||||
"01110",
|
||||
"10101",
|
||||
"00100",
|
||||
"00000",
|
||||
"00000",
|
||||
"00100",
|
||||
"00100",
|
||||
"11111",
|
||||
"00100",
|
||||
"00100",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00100",
|
||||
"00100",
|
||||
"00010",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"11111",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00100",
|
||||
"00000",
|
||||
"00000",
|
||||
"10000",
|
||||
"01000",
|
||||
"00100",
|
||||
"00010",
|
||||
"00001",
|
||||
"00000",
|
||||
"00000",
|
||||
"01110",
|
||||
"10001",
|
||||
"11001",
|
||||
"10101",
|
||||
"10011",
|
||||
"10001",
|
||||
"01110",
|
||||
"00000",
|
||||
"00100",
|
||||
"00110",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"00100",
|
||||
"01110",
|
||||
"00000",
|
||||
"01110",
|
||||
"10001",
|
||||
"10000",
|
||||
"01100",
|
||||
"00010",
|
||||
"00001",
|
||||
"11111",
|
||||
"00000",
|
||||
"11111",
|
||||
"10000",
|
||||
"01000",
|
||||
"01100",
|
||||
"10000",
|
||||
"10001",
|
||||
"01110",
|
||||
"00000",
|
||||
"01000",
|
||||
"01100",
|
||||
"01010",
|
||||
"01001",
|
||||
"11111",
|
||||
"01000",
|
||||
"01000",
|
||||
"00000",
|
||||
"11111",
|
||||
"00001",
|
||||
"01111",
|
||||
"10000",
|
||||
"10000",
|
||||
"10001",
|
||||
"01110",
|
||||
"00000",
|
||||
"11100",
|
||||
"00010",
|
||||
"00001",
|
||||
"01111",
|
||||
"10001",
|
||||
"10001",
|
||||
"01110",
|
||||
"00000",
|
||||
"11111",
|
||||
"10000",
|
||||
"01000",
|
||||
"00100",
|
||||
"00010",
|
||||
"00010",
|
||||
"00010",
|
||||
"00000",
|
||||
"01110",
|
||||
"10001",
|
||||
"10001",
|
||||
"01110",
|
||||
"10001",
|
||||
"10001",
|
||||
"01110",
|
||||
"00000",
|
||||
"01110",
|
||||
"10001",
|
||||
"10001",
|
||||
"11110",
|
||||
"10000",
|
||||
"01000",
|
||||
"00111",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00100",
|
||||
"00000",
|
||||
"00100",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00100",
|
||||
"00000",
|
||||
"00100",
|
||||
"00100",
|
||||
"00010",
|
||||
"00000",
|
||||
"01000",
|
||||
"00100",
|
||||
"00010",
|
||||
"00001",
|
||||
"00010",
|
||||
"00100",
|
||||
"01000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"11111",
|
||||
"00000",
|
||||
"11111",
|
||||
"00000",
|
||||
"00000",
|
||||
"00000",
|
||||
"00010",
|
||||
"00100",
|
||||
"01000",
|
||||
"10000",
|
||||
"01000",
|
||||
"00100",
|
||||
"00010",
|
||||
"00000",
|
||||
"01110",
|
||||
"10001",
|
||||
"01000",
|
||||
"00100",
|
||||
"00100",
|
||||
"00000",
|
||||
"00100",
|
||||
"00000");
|
||||
|
||||
begin
|
||||
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
dout <= ROM(TO_INTEGER(addr));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end rtl;
|
||||
1598
Apple - 2_MiST/rtl/cpu6502.vhd
Normal file
1598
Apple - 2_MiST/rtl/cpu6502.vhd
Normal file
File diff suppressed because it is too large
Load Diff
65
Apple - 2_MiST/rtl/dac.vhd
Normal file
65
Apple - 2_MiST/rtl/dac.vhd
Normal file
@@ -0,0 +1,65 @@
|
||||
--
|
||||
-- DAC.vhd
|
||||
--
|
||||
-- Digital to analog convertor.
|
||||
--
|
||||
-- Copyright (C)2001 SEILEBOST
|
||||
-- All rights reserved.
|
||||
--
|
||||
-- $Id: DAC.vhd, v0.2 2001/11/02 00:00:00 SEILEBOST $
|
||||
--
|
||||
-- from XAPP154.pdf & XAPP154.ZIP (XILINX APPLICATION)
|
||||
--
|
||||
-- DAC 8 Bits ( method : sigma delta)
|
||||
-- 2^N clock to convert with N = width of input
|
||||
-- Ex : Bus 8 bits => 256 CLOCK master to convert an value.
|
||||
-- Theorem Shannon : 2 x Fmax x 256 =< 16 MHz => Fmax = 31250 Hz
|
||||
-- band of sound : 0 -> 20000 Hz : Ok !!
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.STD_LOGIC_ARITH.ALL;
|
||||
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
||||
|
||||
entity DAC is
|
||||
Port ( CLK_DAC : in std_logic;
|
||||
RST : in std_logic;
|
||||
IN_DAC : in std_logic_vector(7 downto 0);
|
||||
OUT_DAC : out std_logic );
|
||||
end DAC;
|
||||
|
||||
architecture Behavioral of DAC is
|
||||
|
||||
signal DeltaAdder : std_logic_vector(9 downto 0);
|
||||
signal SigmaAdder : std_logic_vector(9 downto 0);
|
||||
signal SigmaLatch : std_logic_vector(9 downto 0);
|
||||
signal DeltaB : std_logic_vector(9 downto 0);
|
||||
|
||||
begin
|
||||
PROCESS(SigmaLatch, DeltaB)
|
||||
BEGIN
|
||||
DeltaB <= TRANSPORT ( SigmaLatch(9) & SigmaLatch(9) & "00000000");
|
||||
END PROCESS;
|
||||
|
||||
PROCESS(IN_DAC, DeltaB, DeltaAdder)
|
||||
BEGIN
|
||||
DeltaAdder <= IN_DAC + DeltaB;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS(DeltaAdder, SigmaLatch)
|
||||
BEGIN
|
||||
SigmaAdder <= DeltaAdder + SigmaLatch;
|
||||
END PROCESS;
|
||||
|
||||
PROCESS(CLK_DAC, RST)
|
||||
BEGIN
|
||||
if (RST = '1') then
|
||||
SigmaLatch <= "0100000000";
|
||||
OUT_DAC <= '1';
|
||||
elsif (CLK_DAC'event and CLK_DAC = '1') then
|
||||
SigmaLatch <= SigmaAdder;
|
||||
OUT_DAC <= SigmaLatch(9);
|
||||
end if;
|
||||
END PROCESS;
|
||||
|
||||
end Behavioral;
|
||||
288
Apple - 2_MiST/rtl/disk_ii.vhd
Normal file
288
Apple - 2_MiST/rtl/disk_ii.vhd
Normal file
@@ -0,0 +1,288 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Disk II emulator
|
||||
--
|
||||
-- This is read-only and only feeds "pre-nibblized" data to the processor
|
||||
-- It has a single-track buffer and only supports one drive (1).
|
||||
--
|
||||
-- Stephen A. Edwards, sedwards@cs.columbia.edu
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Each track is represented as 0x1A00 bytes
|
||||
-- Each disk image consists of 35 * 0x1A00 bytes = 0x38A00 (227.5 K)
|
||||
--
|
||||
-- X = $60 for slot 6
|
||||
--
|
||||
-- Off On
|
||||
-- C080,X C081,X Phase 0 Head Stepper Motor Control
|
||||
-- C082,X C083,X Phase 1
|
||||
-- C084,X C085,X Phase 2
|
||||
-- C086,X C087,X Phase 3
|
||||
-- C088,X C089,X Motor On
|
||||
-- C08A,X C08B,X Select Drive 2 (select drive 1 when off)
|
||||
-- C08C,X C08D,X Q6 (Shift/load?)
|
||||
-- C08E,X C08F,X Q7 (Write request to drive)
|
||||
--
|
||||
--
|
||||
-- Q7 Q6
|
||||
-- 0 0 Read
|
||||
-- 0 1 Sense write protect
|
||||
-- 1 0 Write
|
||||
-- 1 1 Load Write Latch
|
||||
--
|
||||
-- Reading a byte:
|
||||
-- LDA $C08E,X set read mode
|
||||
-- ...
|
||||
-- READ LDA $C08C,X
|
||||
-- BPL READ
|
||||
--
|
||||
-- Sense write protect:
|
||||
-- LDA $C08D,X
|
||||
-- LDA $C08E,X
|
||||
-- BMI PROTECTED
|
||||
--
|
||||
-- Writing
|
||||
-- STA $C08F,X set write mode
|
||||
-- ..
|
||||
-- LDA DATA
|
||||
-- STA $C08D,X load byte to write
|
||||
-- STA $C08C,X write byte to disk
|
||||
--
|
||||
-- Data bytes must be written in 32 cycle loops.
|
||||
--
|
||||
-- There are 70 phases for the head stepper and and 35 tracks,
|
||||
-- i.e., two phase changes per track.
|
||||
--
|
||||
-- The disk spins at 300 rpm; one new bit arrives every 4 us
|
||||
-- The processor's clock is 1 MHz = 1 us, so it takes 8 * 4 = 32 cycles
|
||||
-- for a new byte to arrive
|
||||
--
|
||||
-- This corresponds to dividing the 2 MHz signal by 64 to get the byte clock
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity disk_ii is
|
||||
port (
|
||||
CLK_14M : in std_logic;
|
||||
CLK_2M : in std_logic;
|
||||
PRE_PHASE_ZERO : in std_logic;
|
||||
IO_SELECT : in std_logic; -- e.g., C600 - C6FF ROM
|
||||
DEVICE_SELECT : in std_logic; -- e.g., C0E0 - C0EF I/O locations
|
||||
RESET : in std_logic;
|
||||
A : in unsigned(15 downto 0);
|
||||
D_IN : in unsigned(7 downto 0); -- From 6502
|
||||
D_OUT : out unsigned(7 downto 0); -- To 6502
|
||||
TRACK : out unsigned(5 downto 0); -- Current track (0-34)
|
||||
track_addr : out unsigned(13 downto 0);
|
||||
D1_ACTIVE : out std_logic; -- Disk 1 motor on
|
||||
D2_ACTIVE : out std_logic; -- Disk 2 motor on
|
||||
ram_write_addr : in unsigned(13 downto 0); -- Address for track RAM
|
||||
ram_di : in unsigned(7 downto 0); -- Data to track RAM
|
||||
ram_we : in std_logic -- RAM write enable
|
||||
);
|
||||
end disk_ii;
|
||||
|
||||
architecture rtl of disk_ii is
|
||||
|
||||
signal motor_phase : std_logic_vector(3 downto 0);
|
||||
signal drive_on : std_logic;
|
||||
signal drive2_select : std_logic;
|
||||
signal q6, q7 : std_logic;
|
||||
|
||||
signal rom_dout : unsigned(7 downto 0);
|
||||
|
||||
-- Current phase of the head. This is in half-steps to assign
|
||||
-- a unique position to the case, say, when both phase 0 and phase 1 are
|
||||
-- on simultaneously. phase(7 downto 2) is the track number
|
||||
signal phase : unsigned(7 downto 0); -- 0 - 139
|
||||
|
||||
-- Storage for one track worth of data in "nibblized" form
|
||||
type track_ram is array(0 to 6655) of unsigned(7 downto 0);
|
||||
-- Double-ported RAM for holding a track
|
||||
signal track_memory : track_ram;
|
||||
signal ram_do : unsigned(7 downto 0);
|
||||
|
||||
-- Lower bit indicates whether disk data is "valid" or not
|
||||
-- RAM address is track_byte_addr(14 downto 1)
|
||||
-- This makes it look to the software like new data is constantly
|
||||
-- being read into the shift register, which indicates the data is
|
||||
-- not yet ready.
|
||||
signal track_byte_addr : unsigned(14 downto 0);
|
||||
signal read_disk : std_logic; -- When C08C accessed
|
||||
|
||||
begin
|
||||
|
||||
interpret_io : process (CLK_2M)
|
||||
begin
|
||||
if rising_edge(CLK_2M) then
|
||||
if reset = '1' then
|
||||
motor_phase <= (others => '0');
|
||||
drive_on <= '0';
|
||||
drive2_select <= '0';
|
||||
q6 <= '0';
|
||||
q7 <= '0';
|
||||
else
|
||||
if PRE_PHASE_ZERO = '1' and DEVICE_SELECT = '1' then
|
||||
if A(3) = '0' then -- C080 - C087
|
||||
motor_phase(TO_INTEGER(A(2 downto 1))) <= A(0);
|
||||
else
|
||||
case A(2 downto 1) is
|
||||
when "00" => drive_on <= A(0); -- C088 - C089
|
||||
when "01" => drive2_select <= A(0); -- C08A - C08B
|
||||
when "10" => q6 <= A(0); -- C08C - C08D
|
||||
when "11" => q7 <= A(0); -- C08E - C08F
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
D1_ACTIVE <= drive_on and not drive2_select;
|
||||
D2_ACTIVE <= drive_on and drive2_select;
|
||||
|
||||
-- There are two cases:
|
||||
--
|
||||
-- Current phase is odd (between two poles)
|
||||
-- |
|
||||
-- V
|
||||
-- -3-2-1 0 1 2 3
|
||||
-- X X X X
|
||||
-- 0 1 2 3
|
||||
--
|
||||
--
|
||||
-- Current phase is even (under a pole)
|
||||
-- |
|
||||
-- V
|
||||
-- -4-3-2-1 0 1 2 3 4
|
||||
-- X X X X X
|
||||
-- 0 1 2 3 0
|
||||
--
|
||||
|
||||
update_phase : process (CLK_14M)
|
||||
variable phase_change : integer;
|
||||
variable new_phase : integer;
|
||||
variable rel_phase : std_logic_vector(3 downto 0);
|
||||
begin
|
||||
if rising_edge(CLK_14M) then
|
||||
if reset = '1' then
|
||||
phase <= TO_UNSIGNED(70, 8); -- Deliberately odd to test reset
|
||||
else
|
||||
phase_change := 0;
|
||||
new_phase := TO_INTEGER(phase);
|
||||
rel_phase := motor_phase;
|
||||
case phase(2 downto 1) is
|
||||
when "00" =>
|
||||
rel_phase := rel_phase(1 downto 0) & rel_phase(3 downto 2);
|
||||
when "01" =>
|
||||
rel_phase := rel_phase(2 downto 0) & rel_phase(3);
|
||||
when "10" => null;
|
||||
when "11" =>
|
||||
rel_phase := rel_phase(0) & rel_phase(3 downto 1);
|
||||
when others => null;
|
||||
end case;
|
||||
|
||||
if phase(0) = '1' then -- Phase is odd
|
||||
case rel_phase is
|
||||
when "0000" => phase_change := 0;
|
||||
when "0001" => phase_change := -3;
|
||||
when "0010" => phase_change := -1;
|
||||
when "0011" => phase_change := -2;
|
||||
when "0100" => phase_change := 1;
|
||||
when "0101" => phase_change := -1;
|
||||
when "0110" => phase_change := 0;
|
||||
when "0111" => phase_change := -1;
|
||||
when "1000" => phase_change := 3;
|
||||
when "1001" => phase_change := 0;
|
||||
when "1010" => phase_change := 1;
|
||||
when "1011" => phase_change := -3;
|
||||
when "1111" => phase_change := 0;
|
||||
when others => null;
|
||||
end case;
|
||||
else -- Phase is even
|
||||
case rel_phase is
|
||||
when "0000" => phase_change := 0;
|
||||
when "0001" => phase_change := -2;
|
||||
when "0010" => phase_change := 0;
|
||||
when "0011" => phase_change := -1;
|
||||
when "0100" => phase_change := 2;
|
||||
when "0101" => phase_change := 0;
|
||||
when "0110" => phase_change := 1;
|
||||
when "0111" => phase_change := 0;
|
||||
when "1000" => phase_change := 0;
|
||||
when "1001" => phase_change := 1;
|
||||
when "1010" => phase_change := 2;
|
||||
when "1011" => phase_change := -2;
|
||||
when "1111" => phase_change := 0;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
|
||||
if new_phase + phase_change <= 0 then
|
||||
new_phase := 0;
|
||||
elsif new_phase + phase_change > 139 then
|
||||
new_phase := 139;
|
||||
else
|
||||
new_phase := new_phase + phase_change;
|
||||
end if;
|
||||
phase <= TO_UNSIGNED(new_phase, 8);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
TRACK <= phase(7 downto 2);
|
||||
|
||||
-- Dual-ported RAM holding the contents of the track
|
||||
track_storage : process (CLK_14M)
|
||||
begin
|
||||
if rising_edge(CLK_14M) then
|
||||
if ram_we = '1' then
|
||||
track_memory(to_integer(ram_write_addr)) <= ram_di;
|
||||
end if;
|
||||
ram_do <= track_memory(to_integer(track_byte_addr(14 downto 1)));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Go to the next byte when the disk is accessed or if the counter times out
|
||||
read_head : process (CLK_2M)
|
||||
variable byte_delay : unsigned(5 downto 0); -- Accounts for disk spin rate
|
||||
begin
|
||||
if rising_edge(CLK_2M) then
|
||||
if reset = '1' then
|
||||
track_byte_addr <= (others => '0');
|
||||
byte_delay := (others => '0');
|
||||
else
|
||||
byte_delay := byte_delay - 1;
|
||||
if (read_disk = '1' and PRE_PHASE_ZERO = '1') or byte_delay = 0 then
|
||||
byte_delay := (others => '0');
|
||||
if track_byte_addr = X"33FE" then
|
||||
track_byte_addr <= (others => '0');
|
||||
else
|
||||
track_byte_addr <= track_byte_addr + 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
rom : entity work.disk_ii_rom port map (
|
||||
addr => A(7 downto 0),
|
||||
clk => CLK_14M,
|
||||
dout => rom_dout);
|
||||
|
||||
read_disk <= '1' when DEVICE_SELECT = '1' and A(3 downto 0) = x"C" else
|
||||
'0'; -- C08C
|
||||
|
||||
D_OUT <= rom_dout when IO_SELECT = '1' else
|
||||
ram_do when read_disk = '1' and track_byte_addr(0) = '0' else
|
||||
(others => '0');
|
||||
|
||||
track_addr <= track_byte_addr(14 downto 1);
|
||||
|
||||
end rtl;
|
||||
58
Apple - 2_MiST/rtl/disk_ii_rom.vhd
Normal file
58
Apple - 2_MiST/rtl/disk_ii_rom.vhd
Normal file
@@ -0,0 +1,58 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity disk_ii_rom is
|
||||
port (
|
||||
addr : in unsigned(7 downto 0);
|
||||
clk : in std_logic;
|
||||
dout : out unsigned(7 downto 0));
|
||||
end disk_ii_rom;
|
||||
|
||||
architecture rtl of disk_ii_rom is
|
||||
type rom_array is array(0 to 255) of unsigned(7 downto 0);
|
||||
|
||||
constant ROM : rom_array := (
|
||||
X"a2", X"20", X"a0", X"00", X"a2", X"03", X"86", X"3c",
|
||||
X"8a", X"0a", X"24", X"3c", X"f0", X"10", X"05", X"3c",
|
||||
X"49", X"ff", X"29", X"7e", X"b0", X"08", X"4a", X"d0",
|
||||
X"fb", X"98", X"9d", X"56", X"03", X"c8", X"e8", X"10",
|
||||
X"e5", X"20", X"58", X"ff", X"ba", X"bd", X"00", X"01",
|
||||
X"0a", X"0a", X"0a", X"0a", X"85", X"2b", X"aa", X"bd",
|
||||
X"8e", X"c0", X"bd", X"8c", X"c0", X"bd", X"8a", X"c0",
|
||||
X"bd", X"89", X"c0", X"a0", X"50", X"bd", X"80", X"c0",
|
||||
X"98", X"29", X"03", X"0a", X"05", X"2b", X"aa", X"bd",
|
||||
X"81", X"c0", X"a9", X"56", X"20", X"a8", X"fc", X"88",
|
||||
X"10", X"eb", X"85", X"26", X"85", X"3d", X"85", X"41",
|
||||
X"a9", X"08", X"85", X"27", X"18", X"08", X"bd", X"8c",
|
||||
X"c0", X"10", X"fb", X"49", X"d5", X"d0", X"f7", X"bd",
|
||||
X"8c", X"c0", X"10", X"fb", X"c9", X"aa", X"d0", X"f3",
|
||||
X"ea", X"bd", X"8c", X"c0", X"10", X"fb", X"c9", X"96",
|
||||
X"f0", X"09", X"28", X"90", X"df", X"49", X"ad", X"f0",
|
||||
X"25", X"d0", X"d9", X"a0", X"03", X"85", X"40", X"bd",
|
||||
X"8c", X"c0", X"10", X"fb", X"2a", X"85", X"3c", X"bd",
|
||||
X"8c", X"c0", X"10", X"fb", X"25", X"3c", X"88", X"d0",
|
||||
X"ec", X"28", X"c5", X"3d", X"d0", X"be", X"a5", X"40",
|
||||
X"c5", X"41", X"d0", X"b8", X"b0", X"b7", X"a0", X"56",
|
||||
X"84", X"3c", X"bc", X"8c", X"c0", X"10", X"fb", X"59",
|
||||
X"d6", X"02", X"a4", X"3c", X"88", X"99", X"00", X"03",
|
||||
X"d0", X"ee", X"84", X"3c", X"bc", X"8c", X"c0", X"10",
|
||||
X"fb", X"59", X"d6", X"02", X"a4", X"3c", X"91", X"26",
|
||||
X"c8", X"d0", X"ef", X"bc", X"8c", X"c0", X"10", X"fb",
|
||||
X"59", X"d6", X"02", X"d0", X"87", X"a0", X"00", X"a2",
|
||||
X"56", X"ca", X"30", X"fb", X"b1", X"26", X"5e", X"00",
|
||||
X"03", X"2a", X"5e", X"00", X"03", X"2a", X"91", X"26",
|
||||
X"c8", X"d0", X"ee", X"e6", X"27", X"e6", X"3d", X"a5",
|
||||
X"3d", X"cd", X"00", X"08", X"a6", X"2b", X"90", X"db",
|
||||
X"4c", X"01", X"08", X"00", X"00", X"00", X"00", X"00");
|
||||
|
||||
begin
|
||||
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
dout <= ROM(TO_INTEGER(addr));
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end rtl;
|
||||
454
Apple - 2_MiST/rtl/hq2x.sv
Normal file
454
Apple - 2_MiST/rtl/hq2x.sv
Normal file
@@ -0,0 +1,454 @@
|
||||
//
|
||||
//
|
||||
// Copyright (c) 2012-2013 Ludvig Strigeus
|
||||
// Copyright (c) 2017 Sorgelig
|
||||
//
|
||||
// This program is GPL Licensed. See COPYING for the full license.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
|
||||
`define BITS_TO_FIT(N) ( \
|
||||
N <= 2 ? 0 : \
|
||||
N <= 4 ? 1 : \
|
||||
N <= 8 ? 2 : \
|
||||
N <= 16 ? 3 : \
|
||||
N <= 32 ? 4 : \
|
||||
N <= 64 ? 5 : \
|
||||
N <= 128 ? 6 : \
|
||||
N <= 256 ? 7 : \
|
||||
N <= 512 ? 8 : \
|
||||
N <=1024 ? 9 : 10 )
|
||||
|
||||
module hq2x_in #(parameter LENGTH, parameter DWIDTH)
|
||||
(
|
||||
input clk,
|
||||
|
||||
input [AWIDTH:0] rdaddr,
|
||||
input rdbuf,
|
||||
output[DWIDTH:0] q,
|
||||
|
||||
input [AWIDTH:0] wraddr,
|
||||
input wrbuf,
|
||||
input [DWIDTH:0] data,
|
||||
input wren
|
||||
);
|
||||
|
||||
localparam AWIDTH = `BITS_TO_FIT(LENGTH);
|
||||
wire [DWIDTH:0] out[2];
|
||||
assign q = out[rdbuf];
|
||||
|
||||
hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]);
|
||||
hq2x_buf #(.NUMWORDS(LENGTH), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]);
|
||||
endmodule
|
||||
|
||||
|
||||
module hq2x_out #(parameter LENGTH, parameter DWIDTH)
|
||||
(
|
||||
input clk,
|
||||
|
||||
input [AWIDTH:0] rdaddr,
|
||||
input [1:0] rdbuf,
|
||||
output[DWIDTH:0] q,
|
||||
|
||||
input [AWIDTH:0] wraddr,
|
||||
input [1:0] wrbuf,
|
||||
input [DWIDTH:0] data,
|
||||
input wren
|
||||
);
|
||||
|
||||
localparam AWIDTH = `BITS_TO_FIT(LENGTH*2);
|
||||
wire [DWIDTH:0] out[4];
|
||||
assign q = out[rdbuf];
|
||||
|
||||
hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf0(clk,data,rdaddr,wraddr,wren && (wrbuf == 0),out[0]);
|
||||
hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf1(clk,data,rdaddr,wraddr,wren && (wrbuf == 1),out[1]);
|
||||
hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf2(clk,data,rdaddr,wraddr,wren && (wrbuf == 2),out[2]);
|
||||
hq2x_buf #(.NUMWORDS(LENGTH*2), .AWIDTH(AWIDTH), .DWIDTH(DWIDTH)) buf3(clk,data,rdaddr,wraddr,wren && (wrbuf == 3),out[3]);
|
||||
endmodule
|
||||
|
||||
|
||||
module hq2x_buf #(parameter NUMWORDS, parameter AWIDTH, parameter DWIDTH)
|
||||
(
|
||||
input clock,
|
||||
input [DWIDTH:0] data,
|
||||
input [AWIDTH:0] rdaddress,
|
||||
input [AWIDTH:0] wraddress,
|
||||
input wren,
|
||||
output [DWIDTH:0] q
|
||||
);
|
||||
|
||||
altsyncram altsyncram_component (
|
||||
.address_a (wraddress),
|
||||
.clock0 (clock),
|
||||
.data_a (data),
|
||||
.wren_a (wren),
|
||||
.address_b (rdaddress),
|
||||
.q_b(q),
|
||||
.aclr0 (1'b0),
|
||||
.aclr1 (1'b0),
|
||||
.addressstall_a (1'b0),
|
||||
.addressstall_b (1'b0),
|
||||
.byteena_a (1'b1),
|
||||
.byteena_b (1'b1),
|
||||
.clock1 (1'b1),
|
||||
.clocken0 (1'b1),
|
||||
.clocken1 (1'b1),
|
||||
.clocken2 (1'b1),
|
||||
.clocken3 (1'b1),
|
||||
.data_b ({(DWIDTH+1){1'b1}}),
|
||||
.eccstatus (),
|
||||
.q_a (),
|
||||
.rden_a (1'b1),
|
||||
.rden_b (1'b1),
|
||||
.wren_b (1'b0));
|
||||
defparam
|
||||
altsyncram_component.address_aclr_b = "NONE",
|
||||
altsyncram_component.address_reg_b = "CLOCK0",
|
||||
altsyncram_component.clock_enable_input_a = "BYPASS",
|
||||
altsyncram_component.clock_enable_input_b = "BYPASS",
|
||||
altsyncram_component.clock_enable_output_b = "BYPASS",
|
||||
altsyncram_component.intended_device_family = "Cyclone III",
|
||||
altsyncram_component.lpm_type = "altsyncram",
|
||||
altsyncram_component.numwords_a = NUMWORDS,
|
||||
altsyncram_component.numwords_b = NUMWORDS,
|
||||
altsyncram_component.operation_mode = "DUAL_PORT",
|
||||
altsyncram_component.outdata_aclr_b = "NONE",
|
||||
altsyncram_component.outdata_reg_b = "UNREGISTERED",
|
||||
altsyncram_component.power_up_uninitialized = "FALSE",
|
||||
altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE",
|
||||
altsyncram_component.widthad_a = AWIDTH+1,
|
||||
altsyncram_component.widthad_b = AWIDTH+1,
|
||||
altsyncram_component.width_a = DWIDTH+1,
|
||||
altsyncram_component.width_b = DWIDTH+1,
|
||||
altsyncram_component.width_byteena_a = 1;
|
||||
|
||||
endmodule
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module DiffCheck
|
||||
(
|
||||
input [17:0] rgb1,
|
||||
input [17:0] rgb2,
|
||||
output result
|
||||
);
|
||||
|
||||
wire [5:0] r = rgb1[5:1] - rgb2[5:1];
|
||||
wire [5:0] g = rgb1[11:7] - rgb2[11:7];
|
||||
wire [5:0] b = rgb1[17:13] - rgb2[17:13];
|
||||
wire [6:0] t = $signed(r) + $signed(b);
|
||||
wire [6:0] gx = {g[5], g};
|
||||
wire [7:0] y = $signed(t) + $signed(gx);
|
||||
wire [6:0] u = $signed(r) - $signed(b);
|
||||
wire [7:0] v = $signed({g, 1'b0}) - $signed(t);
|
||||
|
||||
// if y is inside (-24..24)
|
||||
wire y_inside = (y < 8'h18 || y >= 8'he8);
|
||||
|
||||
// if u is inside (-4, 4)
|
||||
wire u_inside = (u < 7'h4 || u >= 7'h7c);
|
||||
|
||||
// if v is inside (-6, 6)
|
||||
wire v_inside = (v < 8'h6 || v >= 8'hfA);
|
||||
assign result = !(y_inside && u_inside && v_inside);
|
||||
endmodule
|
||||
|
||||
module InnerBlend
|
||||
(
|
||||
input [8:0] Op,
|
||||
input [5:0] A,
|
||||
input [5:0] B,
|
||||
input [5:0] C,
|
||||
output [5:0] O
|
||||
);
|
||||
|
||||
function [8:0] mul6x3;
|
||||
input [5:0] op1;
|
||||
input [2:0] op2;
|
||||
begin
|
||||
mul6x3 = 9'd0;
|
||||
if(op2[0]) mul6x3 = mul6x3 + op1;
|
||||
if(op2[1]) mul6x3 = mul6x3 + {op1, 1'b0};
|
||||
if(op2[2]) mul6x3 = mul6x3 + {op1, 2'b00};
|
||||
end
|
||||
endfunction
|
||||
|
||||
wire OpOnes = Op[4];
|
||||
wire [8:0] Amul = mul6x3(A, Op[7:5]);
|
||||
wire [8:0] Bmul = mul6x3(B, {Op[3:2], 1'b0});
|
||||
wire [8:0] Cmul = mul6x3(C, {Op[1:0], 1'b0});
|
||||
wire [8:0] At = Amul;
|
||||
wire [8:0] Bt = (OpOnes == 0) ? Bmul : {3'b0, B};
|
||||
wire [8:0] Ct = (OpOnes == 0) ? Cmul : {3'b0, C};
|
||||
wire [9:0] Res = {At, 1'b0} + Bt + Ct;
|
||||
assign O = Op[8] ? A : Res[9:4];
|
||||
endmodule
|
||||
|
||||
module Blend
|
||||
(
|
||||
input [5:0] rule,
|
||||
input disable_hq2x,
|
||||
input [17:0] E,
|
||||
input [17:0] A,
|
||||
input [17:0] B,
|
||||
input [17:0] D,
|
||||
input [17:0] F,
|
||||
input [17:0] H,
|
||||
output [17:0] Result
|
||||
);
|
||||
|
||||
reg [1:0] input_ctrl;
|
||||
reg [8:0] op;
|
||||
localparam BLEND0 = 9'b1_xxx_x_xx_xx; // 0: A
|
||||
localparam BLEND1 = 9'b0_110_0_10_00; // 1: (A * 12 + B * 4) >> 4
|
||||
localparam BLEND2 = 9'b0_100_0_10_10; // 2: (A * 8 + B * 4 + C * 4) >> 4
|
||||
localparam BLEND3 = 9'b0_101_0_10_01; // 3: (A * 10 + B * 4 + C * 2) >> 4
|
||||
localparam BLEND4 = 9'b0_110_0_01_01; // 4: (A * 12 + B * 2 + C * 2) >> 4
|
||||
localparam BLEND5 = 9'b0_010_0_11_11; // 5: (A * 4 + (B + C) * 6) >> 4
|
||||
localparam BLEND6 = 9'b0_111_1_xx_xx; // 6: (A * 14 + B + C) >> 4
|
||||
localparam AB = 2'b00;
|
||||
localparam AD = 2'b01;
|
||||
localparam DB = 2'b10;
|
||||
localparam BD = 2'b11;
|
||||
wire is_diff;
|
||||
DiffCheck diff_checker(rule[1] ? B : H, rule[0] ? D : F, is_diff);
|
||||
|
||||
always @* begin
|
||||
case({!is_diff, rule[5:2]})
|
||||
1,17: {op, input_ctrl} = {BLEND1, AB};
|
||||
2,18: {op, input_ctrl} = {BLEND1, DB};
|
||||
3,19: {op, input_ctrl} = {BLEND1, BD};
|
||||
4,20: {op, input_ctrl} = {BLEND2, DB};
|
||||
5,21: {op, input_ctrl} = {BLEND2, AB};
|
||||
6,22: {op, input_ctrl} = {BLEND2, AD};
|
||||
|
||||
8: {op, input_ctrl} = {BLEND0, 2'bxx};
|
||||
9: {op, input_ctrl} = {BLEND0, 2'bxx};
|
||||
10: {op, input_ctrl} = {BLEND0, 2'bxx};
|
||||
11: {op, input_ctrl} = {BLEND1, AB};
|
||||
12: {op, input_ctrl} = {BLEND1, AB};
|
||||
13: {op, input_ctrl} = {BLEND1, AB};
|
||||
14: {op, input_ctrl} = {BLEND1, DB};
|
||||
15: {op, input_ctrl} = {BLEND1, BD};
|
||||
|
||||
24: {op, input_ctrl} = {BLEND2, DB};
|
||||
25: {op, input_ctrl} = {BLEND5, DB};
|
||||
26: {op, input_ctrl} = {BLEND6, DB};
|
||||
27: {op, input_ctrl} = {BLEND2, DB};
|
||||
28: {op, input_ctrl} = {BLEND4, DB};
|
||||
29: {op, input_ctrl} = {BLEND5, DB};
|
||||
30: {op, input_ctrl} = {BLEND3, BD};
|
||||
31: {op, input_ctrl} = {BLEND3, DB};
|
||||
default: {op, input_ctrl} = 11'bx;
|
||||
endcase
|
||||
|
||||
// Setting op[8] effectively disables HQ2X because blend will always return E.
|
||||
if (disable_hq2x) op[8] = 1;
|
||||
end
|
||||
|
||||
// Generate inputs to the inner blender. Valid combinations.
|
||||
// 00: E A B
|
||||
// 01: E A D
|
||||
// 10: E D B
|
||||
// 11: E B D
|
||||
wire [17:0] Input1 = E;
|
||||
wire [17:0] Input2 = !input_ctrl[1] ? A :
|
||||
!input_ctrl[0] ? D : B;
|
||||
|
||||
wire [17:0] Input3 = !input_ctrl[0] ? B : D;
|
||||
InnerBlend inner_blend1(op, Input1[5:0], Input2[5:0], Input3[5:0], Result[5:0]);
|
||||
InnerBlend inner_blend2(op, Input1[11:6], Input2[11:6], Input3[11:6], Result[11:6]);
|
||||
InnerBlend inner_blend3(op, Input1[17:12], Input2[17:12], Input3[17:12], Result[17:12]);
|
||||
endmodule
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module Hq2x #(parameter LENGTH, parameter HALF_DEPTH)
|
||||
(
|
||||
input clk,
|
||||
input ce_x4,
|
||||
input [DWIDTH:0] inputpixel,
|
||||
input mono,
|
||||
input disable_hq2x,
|
||||
input reset_frame,
|
||||
input reset_line,
|
||||
input [1:0] read_y,
|
||||
input [AWIDTH+1:0] read_x,
|
||||
output [DWIDTH:0] outpixel
|
||||
);
|
||||
|
||||
|
||||
localparam AWIDTH = `BITS_TO_FIT(LENGTH);
|
||||
localparam DWIDTH = HALF_DEPTH ? 8 : 17;
|
||||
|
||||
wire [5:0] hqTable[256] = '{
|
||||
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39,
|
||||
19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 35, 35, 23, 15, 7, 35,
|
||||
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43,
|
||||
19, 19, 26, 58, 19, 19, 26, 58, 23, 15, 51, 35, 23, 15, 7, 43,
|
||||
19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 35, 35, 23, 61, 51, 35,
|
||||
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35,
|
||||
19, 19, 26, 11, 19, 19, 26, 11, 23, 61, 7, 35, 23, 61, 7, 43,
|
||||
19, 19, 26, 11, 19, 19, 26, 58, 23, 15, 51, 35, 23, 61, 7, 43,
|
||||
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 47, 35, 23, 15, 55, 39,
|
||||
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 35,
|
||||
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 55, 39, 23, 15, 51, 43,
|
||||
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 39, 23, 15, 7, 43,
|
||||
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 51, 39,
|
||||
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 35,
|
||||
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 51, 35, 23, 15, 7, 43,
|
||||
19, 19, 26, 11, 19, 19, 26, 11, 23, 15, 7, 35, 23, 15, 7, 43
|
||||
};
|
||||
|
||||
reg [17:0] Prev0, Prev1, Prev2, Curr0, Curr1, Next0, Next1, Next2;
|
||||
reg [17:0] A, B, D, F, G, H;
|
||||
reg [7:0] pattern, nextpatt;
|
||||
reg [1:0] i;
|
||||
reg [7:0] y;
|
||||
|
||||
wire curbuf = y[0];
|
||||
reg prevbuf = 0;
|
||||
wire iobuf = !curbuf;
|
||||
|
||||
wire diff0, diff1;
|
||||
DiffCheck diffcheck0(Curr1, (i == 0) ? Prev0 : (i == 1) ? Curr0 : (i == 2) ? Prev2 : Next1, diff0);
|
||||
DiffCheck diffcheck1(Curr1, (i == 0) ? Prev1 : (i == 1) ? Next0 : (i == 2) ? Curr2 : Next2, diff1);
|
||||
|
||||
wire [7:0] new_pattern = {diff1, diff0, pattern[7:2]};
|
||||
|
||||
wire [17:0] X = (i == 0) ? A : (i == 1) ? Prev1 : (i == 2) ? Next1 : G;
|
||||
wire [17:0] blend_result;
|
||||
Blend blender(hqTable[nextpatt], disable_hq2x, Curr0, X, B, D, F, H, blend_result);
|
||||
|
||||
reg Curr2_addr1;
|
||||
reg [AWIDTH:0] Curr2_addr2;
|
||||
wire [17:0] Curr2 = HALF_DEPTH ? h2rgb(Curr2tmp) : Curr2tmp;
|
||||
wire [DWIDTH:0] Curr2tmp;
|
||||
|
||||
reg [AWIDTH:0] wrin_addr2;
|
||||
reg [DWIDTH:0] wrpix;
|
||||
reg wrin_en;
|
||||
|
||||
function [17:0] h2rgb;
|
||||
input [8:0] v;
|
||||
begin
|
||||
h2rgb = mono ? {v[5:3],v[2:0], v[5:3],v[2:0], v[5:3],v[2:0]} : {v[8:6],v[8:6],v[5:3],v[5:3],v[2:0],v[2:0]};
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [8:0] rgb2h;
|
||||
input [17:0] v;
|
||||
begin
|
||||
rgb2h = mono ? {3'b000, v[17:15], v[14:12]} : {v[17:15], v[11:9], v[5:3]};
|
||||
end
|
||||
endfunction
|
||||
|
||||
hq2x_in #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_in
|
||||
(
|
||||
.clk(clk),
|
||||
|
||||
.rdaddr(Curr2_addr2),
|
||||
.rdbuf(Curr2_addr1),
|
||||
.q(Curr2tmp),
|
||||
|
||||
.wraddr(wrin_addr2),
|
||||
.wrbuf(iobuf),
|
||||
.data(wrpix),
|
||||
.wren(wrin_en)
|
||||
);
|
||||
|
||||
reg [1:0] wrout_addr1;
|
||||
reg [AWIDTH+1:0] wrout_addr2;
|
||||
reg wrout_en;
|
||||
reg [DWIDTH:0] wrdata;
|
||||
|
||||
hq2x_out #(.LENGTH(LENGTH), .DWIDTH(DWIDTH)) hq2x_out
|
||||
(
|
||||
.clk(clk),
|
||||
|
||||
.rdaddr(read_x),
|
||||
.rdbuf(read_y),
|
||||
.q(outpixel),
|
||||
|
||||
.wraddr(wrout_addr2),
|
||||
.wrbuf(wrout_addr1),
|
||||
.data(wrdata),
|
||||
.wren(wrout_en)
|
||||
);
|
||||
|
||||
always @(posedge clk) begin
|
||||
reg [AWIDTH:0] offs;
|
||||
reg old_reset_line;
|
||||
reg old_reset_frame;
|
||||
|
||||
wrout_en <= 0;
|
||||
wrin_en <= 0;
|
||||
|
||||
if(ce_x4) begin
|
||||
|
||||
pattern <= new_pattern;
|
||||
|
||||
if(~&offs) begin
|
||||
if (i == 0) begin
|
||||
Curr2_addr1 <= prevbuf;
|
||||
Curr2_addr2 <= offs;
|
||||
end
|
||||
if (i == 1) begin
|
||||
Prev2 <= Curr2;
|
||||
Curr2_addr1 <= curbuf;
|
||||
Curr2_addr2 <= offs;
|
||||
end
|
||||
if (i == 2) begin
|
||||
Next2 <= HALF_DEPTH ? h2rgb(inputpixel) : inputpixel;
|
||||
wrpix <= inputpixel;
|
||||
wrin_addr2 <= offs;
|
||||
wrin_en <= 1;
|
||||
end
|
||||
if (i == 3) begin
|
||||
offs <= offs + 1'd1;
|
||||
end
|
||||
|
||||
if(HALF_DEPTH) wrdata <= rgb2h(blend_result);
|
||||
else wrdata <= blend_result;
|
||||
|
||||
wrout_addr1 <= {curbuf, i[1]};
|
||||
wrout_addr2 <= {offs, i[1]^i[0]};
|
||||
wrout_en <= 1;
|
||||
end
|
||||
|
||||
if(i==3) begin
|
||||
nextpatt <= {new_pattern[7:6], new_pattern[3], new_pattern[5], new_pattern[2], new_pattern[4], new_pattern[1:0]};
|
||||
{A, G} <= {Prev0, Next0};
|
||||
{B, F, H, D} <= {Prev1, Curr2, Next1, Curr0};
|
||||
{Prev0, Prev1} <= {Prev1, Prev2};
|
||||
{Curr0, Curr1} <= {Curr1, Curr2};
|
||||
{Next0, Next1} <= {Next1, Next2};
|
||||
end else begin
|
||||
nextpatt <= {nextpatt[5], nextpatt[3], nextpatt[0], nextpatt[6], nextpatt[1], nextpatt[7], nextpatt[4], nextpatt[2]};
|
||||
{B, F, H, D} <= {F, H, D, B};
|
||||
end
|
||||
|
||||
i <= i + 1'b1;
|
||||
if(old_reset_line && ~reset_line) begin
|
||||
old_reset_frame <= reset_frame;
|
||||
offs <= 0;
|
||||
i <= 0;
|
||||
y <= y + 1'd1;
|
||||
prevbuf <= curbuf;
|
||||
if(old_reset_frame & ~reset_frame) begin
|
||||
y <= 0;
|
||||
prevbuf <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
old_reset_line <= reset_line;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule // Hq2x
|
||||
390
Apple - 2_MiST/rtl/keyboard.vhd
Normal file
390
Apple - 2_MiST/rtl/keyboard.vhd
Normal file
@@ -0,0 +1,390 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- PS/2 Keyboard interface for the Apple ][
|
||||
--
|
||||
-- Stephen A. Edwards, sedwards@cs.columbia.edu
|
||||
-- After an original by Alex Freed
|
||||
-- i18n & French keyboard by Michel Stempin
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity keyboard is
|
||||
|
||||
generic (
|
||||
KEYMAP : string := "EN-us" -- English US keymap
|
||||
-- KEYMAP : string := "FR-fr" -- French keymap
|
||||
);
|
||||
|
||||
port (
|
||||
PS2_Clk : in std_logic; -- From PS/2 port
|
||||
PS2_Data : in std_logic; -- From PS/2 port
|
||||
CLK_14M : in std_logic;
|
||||
read : in std_logic; -- Read strobe
|
||||
reset : in std_logic;
|
||||
K : out unsigned(7 downto 0) -- Latched, decoded keyboard data
|
||||
);
|
||||
end keyboard;
|
||||
|
||||
architecture rtl of keyboard is
|
||||
|
||||
signal code, latched_code : unsigned(7 downto 0);
|
||||
signal code_available : std_logic;
|
||||
signal ascii : unsigned(7 downto 0); -- decoded
|
||||
signal shifted_code : unsigned(11 downto 0);
|
||||
|
||||
signal key_pressed : std_logic; -- Key pressed & not read
|
||||
signal ctrl, shift, alt : std_logic;
|
||||
|
||||
-- Special PS/2 keyboard codes
|
||||
constant KEY_UP_CODE : unsigned(7 downto 0) := X"F0";
|
||||
constant EXTENDED_CODE : unsigned(7 downto 0) := X"E0";
|
||||
constant LEFT_SHIFT : unsigned(7 downto 0) := X"12";
|
||||
constant RIGHT_SHIFT : unsigned(7 downto 0) := X"59";
|
||||
constant LEFT_CTRL : unsigned(7 downto 0) := X"14";
|
||||
constant ALT_GR : unsigned(7 downto 0) := X"11";
|
||||
|
||||
type states is (IDLE,
|
||||
HAVE_CODE,
|
||||
DECODE,
|
||||
GOT_KEY_UP_CODE,
|
||||
GOT_KEY_UP2,
|
||||
GOT_KEY_UP3,
|
||||
KEY_UP,
|
||||
NORMAL_KEY
|
||||
);
|
||||
|
||||
signal state, next_state : states;
|
||||
|
||||
begin
|
||||
|
||||
ps2_controller : entity work.PS2_Ctrl port map (
|
||||
Clk => CLK_14M,
|
||||
Reset => reset,
|
||||
PS2_Clk => PS2_Clk,
|
||||
PS2_Data => PS2_Data,
|
||||
DoRead => code_available,
|
||||
Scan_DAV => code_available,
|
||||
Scan_Code => code);
|
||||
|
||||
K <= key_pressed & "00" & ascii(4 downto 0) when ctrl = '1' else
|
||||
key_pressed & ascii(6 downto 0);
|
||||
|
||||
shift_ctrl : process (CLK_14M, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
shift <= '0';
|
||||
ctrl <= '0';
|
||||
elsif rising_edge(CLK_14M) then
|
||||
if state = HAVE_CODE then
|
||||
if code = LEFT_SHIFT or code = RIGHT_SHIFT then
|
||||
shift <= '1';
|
||||
elsif code = LEFT_CTRL then
|
||||
ctrl <= '1';
|
||||
elsif code = ALT_GR then
|
||||
alt <= '1';
|
||||
end if;
|
||||
elsif state = KEY_UP then
|
||||
if code = LEFT_SHIFT or code = RIGHT_SHIFT then
|
||||
shift <= '0';
|
||||
elsif code = LEFT_CTRL then
|
||||
ctrl <= '0';
|
||||
elsif code = ALT_GR then
|
||||
alt <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process shift_ctrl;
|
||||
|
||||
fsm : process (CLK_14M, reset)
|
||||
begin
|
||||
if reset = '1' then
|
||||
state <= IDLE;
|
||||
latched_code <= (others => '0');
|
||||
key_pressed <= '0';
|
||||
elsif rising_edge(CLK_14M) then
|
||||
state <= next_state;
|
||||
if read = '1' then key_pressed <= '0'; end if;
|
||||
if state = NORMAL_KEY then
|
||||
latched_code <= code ;
|
||||
key_pressed <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process fsm;
|
||||
|
||||
fsm_next_state : process (code, code_available, state)
|
||||
begin
|
||||
next_state <= state;
|
||||
case state is
|
||||
when IDLE =>
|
||||
if code_available = '1' then next_state <= HAVE_CODE; end if;
|
||||
|
||||
when HAVE_CODE =>
|
||||
next_state <= DECODE;
|
||||
|
||||
when DECODE =>
|
||||
if code = KEY_UP_CODE then
|
||||
next_state <= GOT_KEY_UP_CODE;
|
||||
elsif code = EXTENDED_CODE then -- Treat extended codes as normal
|
||||
next_state <= IDLE;
|
||||
elsif code = LEFT_SHIFT or code = RIGHT_SHIFT or code = LEFT_CTRL then
|
||||
next_state <= IDLE;
|
||||
else
|
||||
next_state <= NORMAL_KEY;
|
||||
end if;
|
||||
|
||||
when GOT_KEY_UP_CODE =>
|
||||
next_state <= GOT_KEY_UP2;
|
||||
|
||||
when GOT_KEY_UP2 =>
|
||||
next_state <= GOT_KEY_UP3;
|
||||
|
||||
when GOT_KEY_UP3 =>
|
||||
if code_available = '1' then
|
||||
next_state <= KEY_UP;
|
||||
end if;
|
||||
|
||||
when KEY_UP | NORMAL_KEY =>
|
||||
next_state <= IDLE;
|
||||
end case;
|
||||
end process fsm_next_state;
|
||||
|
||||
-- PS/2 scancode to ASCII translation
|
||||
|
||||
shifted_code <= "00" & alt & shift & latched_code;
|
||||
|
||||
EN_us: if KEYMAP = "EN-us" generate
|
||||
with shifted_code select
|
||||
ascii <=
|
||||
X"08" when X"066", -- Backspace ("backspace" key)
|
||||
X"08" when X"166", -- Backspace ("backspace" key)
|
||||
X"09" when X"00d", -- Horizontal Tab
|
||||
X"09" when X"10d", -- Horizontal Tab
|
||||
X"0d" when X"05a", -- Carriage return ("enter" key)
|
||||
X"0d" when X"15a", -- Carriage return ("enter" key)
|
||||
X"1b" when X"076", -- Escape ("esc" key)
|
||||
X"1b" when X"176", -- Escape ("esc" key)
|
||||
X"20" when X"029", -- Space
|
||||
X"20" when X"129", -- Space
|
||||
X"21" when X"116", -- !
|
||||
X"22" when X"152", -- "
|
||||
X"23" when X"126", -- #
|
||||
X"24" when X"125", -- $
|
||||
X"25" when X"12e", --
|
||||
X"26" when X"13d", --
|
||||
X"27" when X"052", --
|
||||
X"28" when X"146", --
|
||||
X"29" when X"145", --
|
||||
X"2a" when X"13e", -- *
|
||||
X"2b" when X"155", -- +
|
||||
X"2c" when X"041", -- ,
|
||||
X"2d" when X"04e", -- -
|
||||
X"2e" when X"049", -- .
|
||||
X"2f" when X"04a", -- /
|
||||
X"30" when X"045", -- 0
|
||||
X"31" when X"016", -- 1
|
||||
X"32" when X"01e", -- 2
|
||||
X"33" when X"026", -- 3
|
||||
X"34" when X"025", -- 4
|
||||
X"35" when X"02e", -- 5
|
||||
X"36" when X"036", -- 6
|
||||
X"37" when X"03d", -- 7
|
||||
X"38" when X"03e", -- 8
|
||||
X"39" when X"046", -- 9
|
||||
X"3a" when X"14c", -- :
|
||||
X"3b" when X"04c", -- ;
|
||||
X"3c" when X"141", -- <
|
||||
X"3d" when X"055", -- =
|
||||
X"3e" when X"149", -- >
|
||||
X"3f" when X"14a", -- ?
|
||||
X"40" when X"11e", -- @
|
||||
X"41" when X"11c", -- A
|
||||
X"42" when X"132", -- B
|
||||
X"43" when X"121", -- C
|
||||
X"44" when X"123", -- D
|
||||
X"45" when X"124", -- E
|
||||
X"46" when X"12b", -- F
|
||||
X"47" when X"134", -- G
|
||||
X"48" when X"133", -- H
|
||||
X"49" when X"143", -- I
|
||||
X"4a" when X"13b", -- J
|
||||
X"4b" when X"142", -- K
|
||||
X"4c" when X"14b", -- L
|
||||
X"4d" when X"13a", -- M
|
||||
X"4e" when X"131", -- N
|
||||
X"4f" when X"144", -- O
|
||||
X"50" when X"14d", -- P
|
||||
X"51" when X"115", -- Q
|
||||
X"52" when X"12d", -- R
|
||||
X"53" when X"11b", -- S
|
||||
X"54" when X"12c", -- T
|
||||
X"55" when X"13c", -- U
|
||||
X"56" when X"12a", -- V
|
||||
X"57" when X"11d", -- W
|
||||
X"58" when X"122", -- X
|
||||
X"59" when X"135", -- Y
|
||||
X"5a" when X"11a", -- Z
|
||||
X"5b" when X"054", -- [
|
||||
X"5c" when X"05d", -- \
|
||||
X"5d" when X"05b", -- ]
|
||||
X"5e" when X"136", -- ^
|
||||
X"5f" when X"14e", -- _
|
||||
X"60" when X"00e", -- `
|
||||
X"41" when X"01c", -- A
|
||||
X"42" when X"032", -- B
|
||||
X"43" when X"021", -- C
|
||||
X"44" when X"023", -- D
|
||||
X"45" when X"024", -- E
|
||||
X"46" when X"02b", -- F
|
||||
X"47" when X"034", -- G
|
||||
X"48" when X"033", -- H
|
||||
X"49" when X"043", -- I
|
||||
X"4a" when X"03b", -- J
|
||||
X"4b" when X"042", -- K
|
||||
X"4c" when X"04b", -- L
|
||||
X"4d" when X"03a", -- M
|
||||
X"4e" when X"031", -- N
|
||||
X"4f" when X"044", -- O
|
||||
X"50" when X"04d", -- P
|
||||
X"51" when X"015", -- Q
|
||||
X"52" when X"02d", -- R
|
||||
X"53" when X"01b", -- S
|
||||
X"54" when X"02c", -- T
|
||||
X"55" when X"03c", -- U
|
||||
X"56" when X"02a", -- V
|
||||
X"57" when X"01d", -- W
|
||||
X"58" when X"022", -- X
|
||||
X"59" when X"035", -- Y
|
||||
X"5a" when X"01a", -- Z
|
||||
X"7b" when X"154", -- {
|
||||
X"7c" when X"15d", -- |
|
||||
X"7d" when X"15b", -- }
|
||||
X"7e" when X"10e", -- ~
|
||||
X"7f" when X"071", -- (Delete OR DEL on numeric keypad)
|
||||
X"15" when X"074", -- right arrow (cntrl U)
|
||||
X"08" when X"06b", -- left arrow (BS)
|
||||
X"0B" when X"075", -- (up arrow)
|
||||
X"0A" when X"072", -- (down arrow, ^J, LF)
|
||||
X"7f" when X"171", -- (Delete OR DEL on numeric keypad)
|
||||
X"00" when others;
|
||||
end generate EN_us;
|
||||
|
||||
FR_fr: if KEYMAP = "FR-fr" generate
|
||||
with shifted_code select
|
||||
ascii <=
|
||||
X"08" when X"066", -- Backspace ("backspace" key)
|
||||
X"08" when X"166", -- Backspace ("backspace" key)
|
||||
X"09" when X"00d", -- Horizontal Tab
|
||||
X"09" when X"10d", -- Horizontal Tab
|
||||
X"0d" when X"05a", -- Carriage return ("enter" key)
|
||||
X"0d" when X"15a", -- Carriage return ("enter" key)
|
||||
X"1b" when X"076", -- Escape ("esc" key)
|
||||
X"1b" when X"176", -- Escape ("esc" key)
|
||||
X"20" when X"029", -- Space
|
||||
X"20" when X"129", -- Space
|
||||
X"21" when X"04a", -- !
|
||||
X"22" when X"026", -- "
|
||||
X"23" when X"226", -- #
|
||||
X"24" when X"05b", -- $
|
||||
X"25" when X"152", -- %
|
||||
X"26" when X"016", -- &
|
||||
X"27" when X"025", -- '
|
||||
X"28" when X"02e", -- (
|
||||
X"29" when X"04e", -- )
|
||||
X"2a" when X"05d", -- *
|
||||
X"2b" when X"155", -- +
|
||||
X"2c" when X"03a", -- ,
|
||||
X"2d" when X"036", -- -
|
||||
X"2e" when X"141", -- .
|
||||
X"2f" when X"149", -- /
|
||||
X"30" when X"145", -- 0
|
||||
X"31" when X"116", -- 1
|
||||
X"32" when X"11e", -- 2
|
||||
X"33" when X"126", -- 3
|
||||
X"34" when X"125", -- 4
|
||||
X"35" when X"12e", -- 5
|
||||
X"36" when X"136", -- 6
|
||||
X"37" when X"13d", -- 7
|
||||
X"38" when X"13e", -- 8
|
||||
X"39" when X"146", -- 9
|
||||
X"3a" when X"049", -- :
|
||||
X"3b" when X"041", -- ;
|
||||
X"3c" when X"061", -- <
|
||||
X"3d" when X"055", -- =
|
||||
X"3e" when X"161", -- >
|
||||
X"3f" when X"13a", -- ?
|
||||
X"40" when X"245", -- @
|
||||
X"41" when X"115", -- A
|
||||
X"42" when X"132", -- B
|
||||
X"43" when X"121", -- C
|
||||
X"44" when X"123", -- D
|
||||
X"45" when X"124", -- E
|
||||
X"46" when X"12b", -- F
|
||||
X"47" when X"134", -- G
|
||||
X"48" when X"133", -- H
|
||||
X"49" when X"143", -- I
|
||||
X"4a" when X"13b", -- J
|
||||
X"4b" when X"142", -- K
|
||||
X"4c" when X"14b", -- L
|
||||
X"4d" when X"14c", -- M
|
||||
X"4e" when X"131", -- N
|
||||
X"4f" when X"144", -- O
|
||||
X"50" when X"14d", -- P
|
||||
X"51" when X"11c", -- Q
|
||||
X"52" when X"12d", -- R
|
||||
X"53" when X"11b", -- S
|
||||
X"54" when X"12c", -- T
|
||||
X"55" when X"13c", -- U
|
||||
X"56" when X"12a", -- V
|
||||
X"57" when X"11a", -- W
|
||||
X"58" when X"122", -- X
|
||||
X"59" when X"135", -- Y
|
||||
X"5a" when X"11d", -- Z
|
||||
X"5b" when X"22e", -- [
|
||||
X"5c" when X"23e", -- \
|
||||
X"5d" when X"24e", -- ]
|
||||
X"5e" when X"054", -- ^
|
||||
X"5f" when X"03e", -- _
|
||||
X"60" when X"23d", -- `
|
||||
X"41" when X"015", -- A
|
||||
X"42" when X"032", -- B
|
||||
X"43" when X"021", -- C
|
||||
X"44" when X"023", -- D
|
||||
X"45" when X"024", -- E
|
||||
X"46" when X"02b", -- F
|
||||
X"47" when X"034", -- G
|
||||
X"48" when X"033", -- H
|
||||
X"49" when X"043", -- I
|
||||
X"4a" when X"03b", -- J
|
||||
X"4b" when X"042", -- K
|
||||
X"4c" when X"04b", -- L
|
||||
X"4d" when X"04c", -- M
|
||||
X"4e" when X"031", -- N
|
||||
X"4f" when X"044", -- O
|
||||
X"50" when X"04d", -- P
|
||||
X"51" when X"01c", -- Q
|
||||
X"52" when X"02d", -- R
|
||||
X"53" when X"01b", -- S
|
||||
X"54" when X"02c", -- T
|
||||
X"55" when X"03c", -- U
|
||||
X"56" when X"02a", -- V
|
||||
X"57" when X"01a", -- W
|
||||
X"58" when X"022", -- X
|
||||
X"59" when X"035", -- Y
|
||||
X"5a" when X"01d", -- Z
|
||||
X"7b" when X"225", -- {
|
||||
X"7c" when X"236", -- |
|
||||
X"7d" when X"255", -- }
|
||||
X"7e" when X"21e", -- ~
|
||||
X"7f" when X"071", -- (Delete OR DEL on numeric keypad)
|
||||
X"15" when X"074", -- right arrow (cntrl U)
|
||||
X"08" when X"06b", -- left arrow (BS)
|
||||
X"0B" when X"075", -- (up arrow)
|
||||
X"0A" when X"072", -- (down arrow, ^J, LF)
|
||||
X"7f" when X"171", -- (Delete OR DEL on numeric keypad)
|
||||
X"00" when others;
|
||||
end generate FR_fr;
|
||||
|
||||
end rtl;
|
||||
2075
Apple - 2_MiST/rtl/main_roms.vhd
Normal file
2075
Apple - 2_MiST/rtl/main_roms.vhd
Normal file
File diff suppressed because it is too large
Load Diff
491
Apple - 2_MiST/rtl/mist_io.v
Normal file
491
Apple - 2_MiST/rtl/mist_io.v
Normal file
@@ -0,0 +1,491 @@
|
||||
//
|
||||
// mist_io.v
|
||||
//
|
||||
// mist_io for the MiST board
|
||||
// http://code.google.com/p/mist-board/
|
||||
//
|
||||
// Copyright (c) 2014 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// Use buffer to access SD card. It's time-critical part.
|
||||
// Made module synchroneous with 2 clock domains: clk_sys and SPI_SCK
|
||||
// (Sorgelig)
|
||||
//
|
||||
// for synchronous projects default value for PS2DIV is fine for any frequency of system clock.
|
||||
// clk_ps2 = clk_sys/(PS2DIV*2)
|
||||
//
|
||||
|
||||
module mist_io #(parameter STRLEN=0, parameter PS2DIV=100)
|
||||
(
|
||||
|
||||
// parameter STRLEN and the actual length of conf_str have to match
|
||||
input [(8*STRLEN)-1:0] conf_str,
|
||||
|
||||
// Global clock. It should be around 100MHz (higher is better).
|
||||
input clk_sys,
|
||||
|
||||
// Global SPI clock from ARM. 24MHz
|
||||
input SPI_SCK,
|
||||
|
||||
input CONF_DATA0,
|
||||
input SPI_SS2,
|
||||
output SPI_DO,
|
||||
input SPI_DI,
|
||||
|
||||
output reg [7:0] joystick_0,
|
||||
output reg [7:0] joystick_1,
|
||||
output reg [15:0] joystick_analog_0,
|
||||
output reg [15:0] joystick_analog_1,
|
||||
output [1:0] buttons,
|
||||
output [1:0] switches,
|
||||
output scandoubler_disable,
|
||||
output ypbpr,
|
||||
|
||||
output reg [31:0] status,
|
||||
|
||||
// SD config
|
||||
input sd_conf,
|
||||
input sd_sdhc,
|
||||
output img_mounted, // signaling that new image has been mounted
|
||||
output reg [31:0] img_size, // size of image in bytes
|
||||
|
||||
// SD block level access
|
||||
input [31:0] sd_lba,
|
||||
input sd_rd,
|
||||
input sd_wr,
|
||||
output reg sd_ack,
|
||||
output reg sd_ack_conf,
|
||||
|
||||
// SD byte level access. Signals for 2-PORT altsyncram.
|
||||
output reg [8:0] sd_buff_addr,
|
||||
output reg [7:0] sd_buff_dout,
|
||||
input [7:0] sd_buff_din,
|
||||
output reg sd_buff_wr,
|
||||
|
||||
// ps2 keyboard emulation
|
||||
output ps2_kbd_clk,
|
||||
output reg ps2_kbd_data,
|
||||
output ps2_mouse_clk,
|
||||
output reg ps2_mouse_data,
|
||||
input ps2_caps_led,
|
||||
|
||||
// ARM -> FPGA download
|
||||
output reg ioctl_download = 0, // signal indicating an active download
|
||||
output reg [7:0] ioctl_index, // menu index used to upload the file
|
||||
output ioctl_wr,
|
||||
output reg [24:0] ioctl_addr,
|
||||
output reg [7:0] ioctl_dout
|
||||
);
|
||||
|
||||
reg [7:0] b_data;
|
||||
reg [6:0] sbuf;
|
||||
reg [7:0] cmd;
|
||||
reg [2:0] bit_cnt; // counts bits 0-7 0-7 ...
|
||||
reg [9:0] byte_cnt; // counts bytes
|
||||
reg [7:0] but_sw;
|
||||
reg [2:0] stick_idx;
|
||||
|
||||
reg mount_strobe = 0;
|
||||
assign img_mounted = mount_strobe;
|
||||
|
||||
assign buttons = but_sw[1:0];
|
||||
assign switches = but_sw[3:2];
|
||||
assign scandoubler_disable = but_sw[4];
|
||||
assign ypbpr = but_sw[5];
|
||||
|
||||
wire [7:0] spi_dout = { sbuf, SPI_DI};
|
||||
|
||||
// this variant of user_io is for 8 bit cores (type == a4) only
|
||||
wire [7:0] core_type = 8'ha4;
|
||||
|
||||
// command byte read by the io controller
|
||||
wire [7:0] sd_cmd = { 4'h5, sd_conf, sd_sdhc, sd_wr, sd_rd };
|
||||
|
||||
reg spi_do;
|
||||
assign SPI_DO = CONF_DATA0 ? 1'bZ : spi_do;
|
||||
|
||||
wire [7:0] kbd_led = { 2'b01, 4'b0000, ps2_caps_led, 1'b1};
|
||||
|
||||
// drive MISO only when transmitting core id
|
||||
always@(negedge SPI_SCK) begin
|
||||
if(!CONF_DATA0) begin
|
||||
// first byte returned is always core type, further bytes are
|
||||
// command dependent
|
||||
if(byte_cnt == 0) begin
|
||||
spi_do <= core_type[~bit_cnt];
|
||||
|
||||
end else begin
|
||||
case(cmd)
|
||||
// reading config string
|
||||
8'h14: begin
|
||||
// returning a byte from string
|
||||
if(byte_cnt < STRLEN + 1) spi_do <= conf_str[{STRLEN - byte_cnt,~bit_cnt}];
|
||||
else spi_do <= 0;
|
||||
end
|
||||
|
||||
// reading sd card status
|
||||
8'h16: begin
|
||||
if(byte_cnt == 1) spi_do <= sd_cmd[~bit_cnt];
|
||||
else if((byte_cnt >= 2) && (byte_cnt < 6)) spi_do <= sd_lba[{5-byte_cnt, ~bit_cnt}];
|
||||
else spi_do <= 0;
|
||||
end
|
||||
|
||||
// reading sd card write data
|
||||
8'h18:
|
||||
spi_do <= b_data[~bit_cnt];
|
||||
|
||||
// reading keyboard LED status
|
||||
8'h1f:
|
||||
spi_do <= kbd_led[~bit_cnt];
|
||||
|
||||
default:
|
||||
spi_do <= 0;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg b_wr2,b_wr3;
|
||||
always @(negedge clk_sys) begin
|
||||
b_wr3 <= b_wr2;
|
||||
sd_buff_wr <= b_wr3;
|
||||
end
|
||||
|
||||
// SPI receiver
|
||||
always@(posedge SPI_SCK or posedge CONF_DATA0) begin
|
||||
|
||||
if(CONF_DATA0) begin
|
||||
b_wr2 <= 0;
|
||||
bit_cnt <= 0;
|
||||
byte_cnt <= 0;
|
||||
sd_ack <= 0;
|
||||
sd_ack_conf <= 0;
|
||||
end else begin
|
||||
b_wr2 <= 0;
|
||||
|
||||
sbuf <= spi_dout[6:0];
|
||||
bit_cnt <= bit_cnt + 1'd1;
|
||||
if(bit_cnt == 5) begin
|
||||
if (byte_cnt == 0) sd_buff_addr <= 0;
|
||||
if((byte_cnt != 0) & (sd_buff_addr != 511)) sd_buff_addr <= sd_buff_addr + 1'b1;
|
||||
if((byte_cnt == 1) & ((cmd == 8'h17) | (cmd == 8'h19))) sd_buff_addr <= 0;
|
||||
end
|
||||
|
||||
// finished reading command byte
|
||||
if(bit_cnt == 7) begin
|
||||
if(~&byte_cnt) byte_cnt <= byte_cnt + 8'd1;
|
||||
if(byte_cnt == 0) begin
|
||||
cmd <= spi_dout;
|
||||
|
||||
if(spi_dout == 8'h19) begin
|
||||
sd_ack_conf <= 1;
|
||||
sd_buff_addr <= 0;
|
||||
end
|
||||
if((spi_dout == 8'h17) || (spi_dout == 8'h18)) begin
|
||||
sd_ack <= 1;
|
||||
sd_buff_addr <= 0;
|
||||
end
|
||||
if(spi_dout == 8'h18) b_data <= sd_buff_din;
|
||||
|
||||
mount_strobe <= 0;
|
||||
|
||||
end else begin
|
||||
|
||||
case(cmd)
|
||||
// buttons and switches
|
||||
8'h01: but_sw <= spi_dout;
|
||||
8'h02: joystick_0 <= spi_dout;
|
||||
8'h03: joystick_1 <= spi_dout;
|
||||
|
||||
// store incoming ps2 mouse bytes
|
||||
8'h04: begin
|
||||
ps2_mouse_fifo[ps2_mouse_wptr] <= spi_dout;
|
||||
ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1;
|
||||
end
|
||||
|
||||
// store incoming ps2 keyboard bytes
|
||||
8'h05: begin
|
||||
ps2_kbd_fifo[ps2_kbd_wptr] <= spi_dout;
|
||||
ps2_kbd_wptr <= ps2_kbd_wptr + 1'd1;
|
||||
end
|
||||
|
||||
8'h15: status[7:0] <= spi_dout;
|
||||
|
||||
// send SD config IO -> FPGA
|
||||
// flag that download begins
|
||||
// sd card knows data is config if sd_dout_strobe is asserted
|
||||
// with sd_ack still being inactive (low)
|
||||
8'h19,
|
||||
// send sector IO -> FPGA
|
||||
// flag that download begins
|
||||
8'h17: begin
|
||||
sd_buff_dout <= spi_dout;
|
||||
b_wr2 <= 1;
|
||||
end
|
||||
|
||||
8'h18: b_data <= sd_buff_din;
|
||||
|
||||
// joystick analog
|
||||
8'h1a: begin
|
||||
// first byte is joystick index
|
||||
if(byte_cnt == 1) stick_idx <= spi_dout[2:0];
|
||||
else if(byte_cnt == 2) begin
|
||||
// second byte is x axis
|
||||
if(stick_idx == 0) joystick_analog_0[15:8] <= spi_dout;
|
||||
else if(stick_idx == 1) joystick_analog_1[15:8] <= spi_dout;
|
||||
end else if(byte_cnt == 3) begin
|
||||
// third byte is y axis
|
||||
if(stick_idx == 0) joystick_analog_0[7:0] <= spi_dout;
|
||||
else if(stick_idx == 1) joystick_analog_1[7:0] <= spi_dout;
|
||||
end
|
||||
end
|
||||
|
||||
// notify image selection
|
||||
8'h1c: mount_strobe <= 1;
|
||||
|
||||
// send image info
|
||||
8'h1d: if(byte_cnt<5) img_size[(byte_cnt-1)<<3 +:8] <= spi_dout;
|
||||
|
||||
// status, 32bit version
|
||||
8'h1e: if(byte_cnt<5) status[(byte_cnt-1)<<3 +:8] <= spi_dout;
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
/////////////////////////////// PS2 ///////////////////////////////
|
||||
// 8 byte fifos to store ps2 bytes
|
||||
localparam PS2_FIFO_BITS = 3;
|
||||
|
||||
reg clk_ps2;
|
||||
always @(negedge clk_sys) begin
|
||||
integer cnt;
|
||||
cnt <= cnt + 1'd1;
|
||||
if(cnt == PS2DIV) begin
|
||||
clk_ps2 <= ~clk_ps2;
|
||||
cnt <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
// keyboard
|
||||
reg [7:0] ps2_kbd_fifo[1<<PS2_FIFO_BITS];
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_kbd_wptr;
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_kbd_rptr;
|
||||
|
||||
// ps2 transmitter state machine
|
||||
reg [3:0] ps2_kbd_tx_state;
|
||||
reg [7:0] ps2_kbd_tx_byte;
|
||||
reg ps2_kbd_parity;
|
||||
|
||||
assign ps2_kbd_clk = clk_ps2 || (ps2_kbd_tx_state == 0);
|
||||
|
||||
// ps2 transmitter
|
||||
// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
|
||||
reg ps2_kbd_r_inc;
|
||||
always@(posedge clk_sys) begin
|
||||
reg old_clk;
|
||||
old_clk <= clk_ps2;
|
||||
if(~old_clk & clk_ps2) begin
|
||||
ps2_kbd_r_inc <= 0;
|
||||
|
||||
if(ps2_kbd_r_inc) ps2_kbd_rptr <= ps2_kbd_rptr + 1'd1;
|
||||
|
||||
// transmitter is idle?
|
||||
if(ps2_kbd_tx_state == 0) begin
|
||||
// data in fifo present?
|
||||
if(ps2_kbd_wptr != ps2_kbd_rptr) begin
|
||||
// load tx register from fifo
|
||||
ps2_kbd_tx_byte <= ps2_kbd_fifo[ps2_kbd_rptr];
|
||||
ps2_kbd_r_inc <= 1;
|
||||
|
||||
// reset parity
|
||||
ps2_kbd_parity <= 1;
|
||||
|
||||
// start transmitter
|
||||
ps2_kbd_tx_state <= 1;
|
||||
|
||||
// put start bit on data line
|
||||
ps2_kbd_data <= 0; // start bit is 0
|
||||
end
|
||||
end else begin
|
||||
|
||||
// transmission of 8 data bits
|
||||
if((ps2_kbd_tx_state >= 1)&&(ps2_kbd_tx_state < 9)) begin
|
||||
ps2_kbd_data <= ps2_kbd_tx_byte[0]; // data bits
|
||||
ps2_kbd_tx_byte[6:0] <= ps2_kbd_tx_byte[7:1]; // shift down
|
||||
if(ps2_kbd_tx_byte[0])
|
||||
ps2_kbd_parity <= !ps2_kbd_parity;
|
||||
end
|
||||
|
||||
// transmission of parity
|
||||
if(ps2_kbd_tx_state == 9) ps2_kbd_data <= ps2_kbd_parity;
|
||||
|
||||
// transmission of stop bit
|
||||
if(ps2_kbd_tx_state == 10) ps2_kbd_data <= 1; // stop bit is 1
|
||||
|
||||
// advance state machine
|
||||
if(ps2_kbd_tx_state < 11) ps2_kbd_tx_state <= ps2_kbd_tx_state + 1'd1;
|
||||
else ps2_kbd_tx_state <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// mouse
|
||||
reg [7:0] ps2_mouse_fifo[1<<PS2_FIFO_BITS];
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_mouse_wptr;
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_mouse_rptr;
|
||||
|
||||
// ps2 transmitter state machine
|
||||
reg [3:0] ps2_mouse_tx_state;
|
||||
reg [7:0] ps2_mouse_tx_byte;
|
||||
reg ps2_mouse_parity;
|
||||
|
||||
assign ps2_mouse_clk = clk_ps2 || (ps2_mouse_tx_state == 0);
|
||||
|
||||
// ps2 transmitter
|
||||
// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
|
||||
reg ps2_mouse_r_inc;
|
||||
always@(posedge clk_sys) begin
|
||||
reg old_clk;
|
||||
old_clk <= clk_ps2;
|
||||
if(~old_clk & clk_ps2) begin
|
||||
ps2_mouse_r_inc <= 0;
|
||||
|
||||
if(ps2_mouse_r_inc) ps2_mouse_rptr <= ps2_mouse_rptr + 1'd1;
|
||||
|
||||
// transmitter is idle?
|
||||
if(ps2_mouse_tx_state == 0) begin
|
||||
// data in fifo present?
|
||||
if(ps2_mouse_wptr != ps2_mouse_rptr) begin
|
||||
// load tx register from fifo
|
||||
ps2_mouse_tx_byte <= ps2_mouse_fifo[ps2_mouse_rptr];
|
||||
ps2_mouse_r_inc <= 1;
|
||||
|
||||
// reset parity
|
||||
ps2_mouse_parity <= 1;
|
||||
|
||||
// start transmitter
|
||||
ps2_mouse_tx_state <= 1;
|
||||
|
||||
// put start bit on data line
|
||||
ps2_mouse_data <= 0; // start bit is 0
|
||||
end
|
||||
end else begin
|
||||
|
||||
// transmission of 8 data bits
|
||||
if((ps2_mouse_tx_state >= 1)&&(ps2_mouse_tx_state < 9)) begin
|
||||
ps2_mouse_data <= ps2_mouse_tx_byte[0]; // data bits
|
||||
ps2_mouse_tx_byte[6:0] <= ps2_mouse_tx_byte[7:1]; // shift down
|
||||
if(ps2_mouse_tx_byte[0])
|
||||
ps2_mouse_parity <= !ps2_mouse_parity;
|
||||
end
|
||||
|
||||
// transmission of parity
|
||||
if(ps2_mouse_tx_state == 9) ps2_mouse_data <= ps2_mouse_parity;
|
||||
|
||||
// transmission of stop bit
|
||||
if(ps2_mouse_tx_state == 10) ps2_mouse_data <= 1; // stop bit is 1
|
||||
|
||||
// advance state machine
|
||||
if(ps2_mouse_tx_state < 11) ps2_mouse_tx_state <= ps2_mouse_tx_state + 1'd1;
|
||||
else ps2_mouse_tx_state <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
/////////////////////////////// DOWNLOADING ///////////////////////////////
|
||||
|
||||
reg [7:0] data_w;
|
||||
reg [24:0] addr_w;
|
||||
reg rclk = 0;
|
||||
|
||||
localparam UIO_FILE_TX = 8'h53;
|
||||
localparam UIO_FILE_TX_DAT = 8'h54;
|
||||
localparam UIO_FILE_INDEX = 8'h55;
|
||||
|
||||
// data_io has its own SPI interface to the io controller
|
||||
always@(posedge SPI_SCK, posedge SPI_SS2) begin
|
||||
reg [6:0] sbuf;
|
||||
reg [7:0] cmd;
|
||||
reg [4:0] cnt;
|
||||
reg [24:0] addr;
|
||||
|
||||
if(SPI_SS2) cnt <= 0;
|
||||
else begin
|
||||
rclk <= 0;
|
||||
|
||||
// don't shift in last bit. It is evaluated directly
|
||||
// when writing to ram
|
||||
if(cnt != 15) sbuf <= { sbuf[5:0], SPI_DI};
|
||||
|
||||
// increase target address after write
|
||||
if(rclk) addr <= addr + 1'd1;
|
||||
|
||||
// count 0-7 8-15 8-15 ...
|
||||
if(cnt < 15) cnt <= cnt + 1'd1;
|
||||
else cnt <= 8;
|
||||
|
||||
// finished command byte
|
||||
if(cnt == 7) cmd <= {sbuf, SPI_DI};
|
||||
|
||||
// prepare/end transmission
|
||||
if((cmd == UIO_FILE_TX) && (cnt == 15)) begin
|
||||
// prepare
|
||||
if(SPI_DI) begin
|
||||
addr <= 0;
|
||||
ioctl_download <= 1;
|
||||
end else begin
|
||||
addr_w <= addr;
|
||||
ioctl_download <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
// command 0x54: UIO_FILE_TX
|
||||
if((cmd == UIO_FILE_TX_DAT) && (cnt == 15)) begin
|
||||
addr_w <= addr;
|
||||
data_w <= {sbuf, SPI_DI};
|
||||
rclk <= 1;
|
||||
end
|
||||
|
||||
// expose file (menu) index
|
||||
if((cmd == UIO_FILE_INDEX) && (cnt == 15)) ioctl_index <= {sbuf, SPI_DI};
|
||||
end
|
||||
end
|
||||
|
||||
assign ioctl_wr = |ioctl_wrd;
|
||||
reg [1:0] ioctl_wrd;
|
||||
|
||||
always@(negedge clk_sys) begin
|
||||
reg rclkD, rclkD2;
|
||||
|
||||
rclkD <= rclk;
|
||||
rclkD2 <= rclkD;
|
||||
ioctl_wrd<= {ioctl_wrd[0],1'b0};
|
||||
|
||||
if(rclkD & ~rclkD2) begin
|
||||
ioctl_dout <= data_w;
|
||||
ioctl_addr <= addr_w;
|
||||
ioctl_wrd <= 2'b11;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
179
Apple - 2_MiST/rtl/osd.v
Normal file
179
Apple - 2_MiST/rtl/osd.v
Normal file
@@ -0,0 +1,179 @@
|
||||
// A simple OSD implementation. Can be hooked up between a cores
|
||||
// VGA output and the physical VGA pins
|
||||
|
||||
module osd (
|
||||
// OSDs pixel clock, should be synchronous to cores pixel clock to
|
||||
// avoid jitter.
|
||||
input clk_sys,
|
||||
|
||||
// SPI interface
|
||||
input SPI_SCK,
|
||||
input SPI_SS3,
|
||||
input SPI_DI,
|
||||
|
||||
// VGA signals coming from core
|
||||
input [5:0] R_in,
|
||||
input [5:0] G_in,
|
||||
input [5:0] B_in,
|
||||
input HSync,
|
||||
input VSync,
|
||||
|
||||
// VGA signals going to video connector
|
||||
output [5:0] R_out,
|
||||
output [5:0] G_out,
|
||||
output [5:0] B_out
|
||||
);
|
||||
|
||||
parameter OSD_X_OFFSET = 10'd0;
|
||||
parameter OSD_Y_OFFSET = 10'd0;
|
||||
parameter OSD_COLOR = 3'd0;
|
||||
|
||||
localparam OSD_WIDTH = 10'd256;
|
||||
localparam OSD_HEIGHT = 10'd128;
|
||||
|
||||
// *********************************************************************************
|
||||
// spi client
|
||||
// *********************************************************************************
|
||||
|
||||
// this core supports only the display related OSD commands
|
||||
// of the minimig
|
||||
reg osd_enable;
|
||||
(* ramstyle = "no_rw_check" *) reg [7:0] osd_buffer[2047:0]; // the OSD buffer itself
|
||||
|
||||
// the OSD has its own SPI interface to the io controller
|
||||
always@(posedge SPI_SCK, posedge SPI_SS3) begin
|
||||
reg [4:0] cnt;
|
||||
reg [10:0] bcnt;
|
||||
reg [7:0] sbuf;
|
||||
reg [7:0] cmd;
|
||||
|
||||
if(SPI_SS3) begin
|
||||
cnt <= 0;
|
||||
bcnt <= 0;
|
||||
end else begin
|
||||
sbuf <= {sbuf[6:0], SPI_DI};
|
||||
|
||||
// 0:7 is command, rest payload
|
||||
if(cnt < 15) cnt <= cnt + 1'd1;
|
||||
else cnt <= 8;
|
||||
|
||||
if(cnt == 7) begin
|
||||
cmd <= {sbuf[6:0], SPI_DI};
|
||||
|
||||
// lower three command bits are line address
|
||||
bcnt <= {sbuf[1:0], SPI_DI, 8'h00};
|
||||
|
||||
// command 0x40: OSDCMDENABLE, OSDCMDDISABLE
|
||||
if(sbuf[6:3] == 4'b0100) osd_enable <= SPI_DI;
|
||||
end
|
||||
|
||||
// command 0x20: OSDCMDWRITE
|
||||
if((cmd[7:3] == 5'b00100) && (cnt == 15)) begin
|
||||
osd_buffer[bcnt] <= {sbuf[6:0], SPI_DI};
|
||||
bcnt <= bcnt + 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// *********************************************************************************
|
||||
// video timing and sync polarity anaylsis
|
||||
// *********************************************************************************
|
||||
|
||||
// horizontal counter
|
||||
reg [9:0] h_cnt;
|
||||
reg [9:0] hs_low, hs_high;
|
||||
wire hs_pol = hs_high < hs_low;
|
||||
wire [9:0] dsp_width = hs_pol ? hs_low : hs_high;
|
||||
|
||||
// vertical counter
|
||||
reg [9:0] v_cnt;
|
||||
reg [9:0] vs_low, vs_high;
|
||||
wire vs_pol = vs_high < vs_low;
|
||||
wire [9:0] dsp_height = vs_pol ? vs_low : vs_high;
|
||||
|
||||
wire doublescan = (dsp_height>350);
|
||||
|
||||
reg ce_pix;
|
||||
always @(negedge clk_sys) begin
|
||||
integer cnt = 0;
|
||||
integer pixsz, pixcnt;
|
||||
reg hs;
|
||||
|
||||
cnt <= cnt + 1;
|
||||
hs <= HSync;
|
||||
|
||||
pixcnt <= pixcnt + 1;
|
||||
if(pixcnt == pixsz) pixcnt <= 0;
|
||||
ce_pix <= !pixcnt;
|
||||
|
||||
if(hs && ~HSync) begin
|
||||
cnt <= 0;
|
||||
pixsz <= (cnt >> 9) - 1;
|
||||
pixcnt <= 0;
|
||||
ce_pix <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
reg hsD, hsD2;
|
||||
reg vsD, vsD2;
|
||||
|
||||
if(ce_pix) begin
|
||||
// bring hsync into local clock domain
|
||||
hsD <= HSync;
|
||||
hsD2 <= hsD;
|
||||
|
||||
// falling edge of HSync
|
||||
if(!hsD && hsD2) begin
|
||||
h_cnt <= 0;
|
||||
hs_high <= h_cnt;
|
||||
end
|
||||
|
||||
// rising edge of HSync
|
||||
else if(hsD && !hsD2) begin
|
||||
h_cnt <= 0;
|
||||
hs_low <= h_cnt;
|
||||
v_cnt <= v_cnt + 1'd1;
|
||||
end else begin
|
||||
h_cnt <= h_cnt + 1'd1;
|
||||
end
|
||||
|
||||
vsD <= VSync;
|
||||
vsD2 <= vsD;
|
||||
|
||||
// falling edge of VSync
|
||||
if(!vsD && vsD2) begin
|
||||
v_cnt <= 0;
|
||||
vs_high <= v_cnt;
|
||||
end
|
||||
|
||||
// rising edge of VSync
|
||||
else if(vsD && !vsD2) begin
|
||||
v_cnt <= 0;
|
||||
vs_low <= v_cnt;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// area in which OSD is being displayed
|
||||
wire [9:0] h_osd_start = ((dsp_width - OSD_WIDTH)>> 1) + OSD_X_OFFSET;
|
||||
wire [9:0] h_osd_end = h_osd_start + OSD_WIDTH;
|
||||
wire [9:0] v_osd_start = ((dsp_height- (OSD_HEIGHT<<doublescan))>> 1) + OSD_Y_OFFSET;
|
||||
wire [9:0] v_osd_end = v_osd_start + (OSD_HEIGHT<<doublescan);
|
||||
wire [9:0] osd_hcnt = h_cnt - h_osd_start + 1'd1; // one pixel offset for osd_byte register
|
||||
wire [9:0] osd_vcnt = v_cnt - v_osd_start;
|
||||
|
||||
wire osd_de = osd_enable &&
|
||||
(HSync != hs_pol) && (h_cnt >= h_osd_start) && (h_cnt < h_osd_end) &&
|
||||
(VSync != vs_pol) && (v_cnt >= v_osd_start) && (v_cnt < v_osd_end);
|
||||
|
||||
reg [7:0] osd_byte;
|
||||
always @(posedge clk_sys) if(ce_pix) osd_byte <= osd_buffer[{doublescan ? osd_vcnt[7:5] : osd_vcnt[6:4], osd_hcnt[7:0]}];
|
||||
|
||||
wire osd_pixel = osd_byte[doublescan ? osd_vcnt[4:2] : osd_vcnt[3:1]];
|
||||
|
||||
assign R_out = !osd_de ? R_in : {osd_pixel, osd_pixel, OSD_COLOR[2], R_in[5:3]};
|
||||
assign G_out = !osd_de ? G_in : {osd_pixel, osd_pixel, OSD_COLOR[1], G_in[5:3]};
|
||||
assign B_out = !osd_de ? B_in : {osd_pixel, osd_pixel, OSD_COLOR[0], B_in[5:3]};
|
||||
|
||||
endmodule
|
||||
4
Apple - 2_MiST/rtl/pll.qip
Normal file
4
Apple - 2_MiST/rtl/pll.qip
Normal file
@@ -0,0 +1,4 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "ALTPLL"
|
||||
set_global_assignment -name IP_TOOL_VERSION "13.1"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pll.v"]
|
||||
set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pll.ppf"]
|
||||
376
Apple - 2_MiST/rtl/pll.v
Normal file
376
Apple - 2_MiST/rtl/pll.v
Normal file
@@ -0,0 +1,376 @@
|
||||
// megafunction wizard: %ALTPLL%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altpll
|
||||
|
||||
// ============================================================
|
||||
// File Name: pll.v
|
||||
// Megafunction Name(s):
|
||||
// altpll
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
// altera_mf
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 13.1.0 Build 162 10/23/2013 SJ Web Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 1991-2013 Altera Corporation
|
||||
//Your use of Altera Corporation's design tools, logic functions
|
||||
//and other software and tools, and its AMPP partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Altera Program License
|
||||
//Subscription Agreement, Altera MegaCore Function License
|
||||
//Agreement, or other applicable license agreement, including,
|
||||
//without limitation, that your use is for the sole purpose of
|
||||
//programming logic devices manufactured by Altera and sold by
|
||||
//Altera or its authorized distributors. Please refer to the
|
||||
//applicable agreement for further details.
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module pll (
|
||||
areset,
|
||||
inclk0,
|
||||
c0,
|
||||
c1,
|
||||
c2,
|
||||
locked);
|
||||
|
||||
input areset;
|
||||
input inclk0;
|
||||
output c0;
|
||||
output c1;
|
||||
output c2;
|
||||
output locked;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_off
|
||||
`endif
|
||||
tri0 areset;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_on
|
||||
`endif
|
||||
|
||||
wire [4:0] sub_wire0;
|
||||
wire sub_wire2;
|
||||
wire [0:0] sub_wire7 = 1'h0;
|
||||
wire [2:2] sub_wire4 = sub_wire0[2:2];
|
||||
wire [0:0] sub_wire3 = sub_wire0[0:0];
|
||||
wire [1:1] sub_wire1 = sub_wire0[1:1];
|
||||
wire c1 = sub_wire1;
|
||||
wire locked = sub_wire2;
|
||||
wire c0 = sub_wire3;
|
||||
wire c2 = sub_wire4;
|
||||
wire sub_wire5 = inclk0;
|
||||
wire [1:0] sub_wire6 = {sub_wire7, sub_wire5};
|
||||
|
||||
altpll altpll_component (
|
||||
.areset (areset),
|
||||
.inclk (sub_wire6),
|
||||
.clk (sub_wire0),
|
||||
.locked (sub_wire2),
|
||||
.activeclock (),
|
||||
.clkbad (),
|
||||
.clkena ({6{1'b1}}),
|
||||
.clkloss (),
|
||||
.clkswitch (1'b0),
|
||||
.configupdate (1'b0),
|
||||
.enable0 (),
|
||||
.enable1 (),
|
||||
.extclk (),
|
||||
.extclkena ({4{1'b1}}),
|
||||
.fbin (1'b1),
|
||||
.fbmimicbidir (),
|
||||
.fbout (),
|
||||
.fref (),
|
||||
.icdrclk (),
|
||||
.pfdena (1'b1),
|
||||
.phasecounterselect ({4{1'b1}}),
|
||||
.phasedone (),
|
||||
.phasestep (1'b1),
|
||||
.phaseupdown (1'b1),
|
||||
.pllena (1'b1),
|
||||
.scanaclr (1'b0),
|
||||
.scanclk (1'b0),
|
||||
.scanclkena (1'b1),
|
||||
.scandata (1'b0),
|
||||
.scandataout (),
|
||||
.scandone (),
|
||||
.scanread (1'b0),
|
||||
.scanwrite (1'b0),
|
||||
.sclkout0 (),
|
||||
.sclkout1 (),
|
||||
.vcooverrange (),
|
||||
.vcounderrange ());
|
||||
defparam
|
||||
altpll_component.bandwidth_type = "AUTO",
|
||||
altpll_component.clk0_divide_by = 33,
|
||||
altpll_component.clk0_duty_cycle = 50,
|
||||
altpll_component.clk0_multiply_by = 35,
|
||||
altpll_component.clk0_phase_shift = "0",
|
||||
altpll_component.clk1_divide_by = 66,
|
||||
altpll_component.clk1_duty_cycle = 50,
|
||||
altpll_component.clk1_multiply_by = 35,
|
||||
altpll_component.clk1_phase_shift = "0",
|
||||
altpll_component.clk2_divide_by = 132,
|
||||
altpll_component.clk2_duty_cycle = 50,
|
||||
altpll_component.clk2_multiply_by = 35,
|
||||
altpll_component.clk2_phase_shift = "0",
|
||||
altpll_component.compensate_clock = "CLK0",
|
||||
altpll_component.inclk0_input_frequency = 37037,
|
||||
altpll_component.intended_device_family = "Cyclone III",
|
||||
altpll_component.lpm_hint = "CBX_MODULE_PREFIX=pll",
|
||||
altpll_component.lpm_type = "altpll",
|
||||
altpll_component.operation_mode = "NORMAL",
|
||||
altpll_component.pll_type = "AUTO",
|
||||
altpll_component.port_activeclock = "PORT_UNUSED",
|
||||
altpll_component.port_areset = "PORT_USED",
|
||||
altpll_component.port_clkbad0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkbad1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkloss = "PORT_UNUSED",
|
||||
altpll_component.port_clkswitch = "PORT_UNUSED",
|
||||
altpll_component.port_configupdate = "PORT_UNUSED",
|
||||
altpll_component.port_fbin = "PORT_UNUSED",
|
||||
altpll_component.port_inclk0 = "PORT_USED",
|
||||
altpll_component.port_inclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_locked = "PORT_USED",
|
||||
altpll_component.port_pfdena = "PORT_UNUSED",
|
||||
altpll_component.port_phasecounterselect = "PORT_UNUSED",
|
||||
altpll_component.port_phasedone = "PORT_UNUSED",
|
||||
altpll_component.port_phasestep = "PORT_UNUSED",
|
||||
altpll_component.port_phaseupdown = "PORT_UNUSED",
|
||||
altpll_component.port_pllena = "PORT_UNUSED",
|
||||
altpll_component.port_scanaclr = "PORT_UNUSED",
|
||||
altpll_component.port_scanclk = "PORT_UNUSED",
|
||||
altpll_component.port_scanclkena = "PORT_UNUSED",
|
||||
altpll_component.port_scandata = "PORT_UNUSED",
|
||||
altpll_component.port_scandataout = "PORT_UNUSED",
|
||||
altpll_component.port_scandone = "PORT_UNUSED",
|
||||
altpll_component.port_scanread = "PORT_UNUSED",
|
||||
altpll_component.port_scanwrite = "PORT_UNUSED",
|
||||
altpll_component.port_clk0 = "PORT_USED",
|
||||
altpll_component.port_clk1 = "PORT_USED",
|
||||
altpll_component.port_clk2 = "PORT_USED",
|
||||
altpll_component.port_clk3 = "PORT_UNUSED",
|
||||
altpll_component.port_clk4 = "PORT_UNUSED",
|
||||
altpll_component.port_clk5 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena0 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena1 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena2 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena3 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena4 = "PORT_UNUSED",
|
||||
altpll_component.port_clkena5 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk0 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk1 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk2 = "PORT_UNUSED",
|
||||
altpll_component.port_extclk3 = "PORT_UNUSED",
|
||||
altpll_component.self_reset_on_loss_lock = "OFF",
|
||||
altpll_component.width_clock = 5;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: ACTIVECLK_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH STRING "1.000"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_FREQ_UNIT STRING "MHz"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_PRESET STRING "Low"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_USE_AUTO STRING "1"
|
||||
// Retrieval info: PRIVATE: BANDWIDTH_USE_PRESET STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKBAD_SWITCHOVER_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKLOSS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CLKSWITCH_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CNX_NO_COMPENSATE_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: CREATE_CLKBAD_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CREATE_INCLK1_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: CUR_DEDICATED_CLK STRING "c0"
|
||||
// Retrieval info: PRIVATE: CUR_FBIN_CLK STRING "c0"
|
||||
// Retrieval info: PRIVATE: DEVICE_SPEED_GRADE STRING "8"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR0 NUMERIC "33"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR1 NUMERIC "66"
|
||||
// Retrieval info: PRIVATE: DIV_FACTOR2 NUMERIC "132"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE0 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE1 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: DUTY_CYCLE2 STRING "50.00000000"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE0 STRING "28.636364"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE1 STRING "14.318182"
|
||||
// Retrieval info: PRIVATE: EFF_OUTPUT_FREQ_VALUE2 STRING "7.159091"
|
||||
// Retrieval info: PRIVATE: EXPLICIT_SWITCHOVER_COUNTER STRING "0"
|
||||
// Retrieval info: PRIVATE: EXT_FEEDBACK_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_COUNTER_EDIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: GLOCKED_FEATURE_ENABLED STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCKED_MODE_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: GLOCK_COUNTER_EDIT NUMERIC "1048575"
|
||||
// Retrieval info: PRIVATE: HAS_MANUAL_SWITCHOVER STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK0_FREQ_EDIT STRING "27.000"
|
||||
// Retrieval info: PRIVATE: INCLK0_FREQ_UNIT_COMBO STRING "MHz"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT STRING "100.000"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_EDIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_CHANGED STRING "1"
|
||||
// Retrieval info: PRIVATE: INCLK1_FREQ_UNIT_COMBO STRING "MHz"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||||
// Retrieval info: PRIVATE: INT_FEEDBACK__MODE_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: LOCKED_OUTPUT_CHECK STRING "1"
|
||||
// Retrieval info: PRIVATE: LONG_SCAN_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE STRING "Not Available"
|
||||
// Retrieval info: PRIVATE: LVDS_MODE_DATA_RATE_DIRTY NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT1 STRING "ps"
|
||||
// Retrieval info: PRIVATE: LVDS_PHASE_SHIFT_UNIT2 STRING "ps"
|
||||
// Retrieval info: PRIVATE: MIG_DEVICE_SPEED_GRADE STRING "Any"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK0 STRING "0"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK1 STRING "0"
|
||||
// Retrieval info: PRIVATE: MIRROR_CLK2 STRING "0"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR0 NUMERIC "35"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR1 NUMERIC "35"
|
||||
// Retrieval info: PRIVATE: MULT_FACTOR2 NUMERIC "35"
|
||||
// Retrieval info: PRIVATE: NORMAL_MODE_RADIO STRING "1"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ0 STRING "28.63636000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ1 STRING "14.31818000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ2 STRING "7.15909000"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE0 STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE1 STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_MODE2 STRING "0"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT0 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT1 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: OUTPUT_FREQ_UNIT2 STRING "MHz"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: PHASE_RECONFIG_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT0 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT1 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT2 STRING "0.00000000"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_STEP_ENABLED_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT0 STRING "deg"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT1 STRING "ps"
|
||||
// Retrieval info: PRIVATE: PHASE_SHIFT_UNIT2 STRING "ps"
|
||||
// Retrieval info: PRIVATE: PLL_ADVANCED_PARAM_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_ARESET_CHECK STRING "1"
|
||||
// Retrieval info: PRIVATE: PLL_AUTOPLL_CHECK NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: PLL_ENHPLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_FASTPLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_FBMIMIC_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_LVDS_PLL_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PLL_PFDENA_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: PLL_TARGET_HARCOPY_CHECK NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: PRIMARY_CLK_COMBO STRING "inclk0"
|
||||
// Retrieval info: PRIVATE: RECONFIG_FILE STRING "pll.mif"
|
||||
// Retrieval info: PRIVATE: SACN_INPUTS_CHECK STRING "0"
|
||||
// Retrieval info: PRIVATE: SCAN_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SELF_RESET_LOCK_LOSS STRING "0"
|
||||
// Retrieval info: PRIVATE: SHORT_SCAN_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: SPREAD_FEATURE_ENABLED STRING "0"
|
||||
// Retrieval info: PRIVATE: SPREAD_FREQ STRING "50.000"
|
||||
// Retrieval info: PRIVATE: SPREAD_FREQ_UNIT STRING "KHz"
|
||||
// Retrieval info: PRIVATE: SPREAD_PERCENT STRING "0.500"
|
||||
// Retrieval info: PRIVATE: SPREAD_USE STRING "0"
|
||||
// Retrieval info: PRIVATE: SRC_SYNCH_COMP_RADIO STRING "0"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK0 STRING "1"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK1 STRING "1"
|
||||
// Retrieval info: PRIVATE: STICKY_CLK2 STRING "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_COUNT_EDIT NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: SWITCHOVER_FEATURE_ENABLED STRING "1"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLK0 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLK1 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLK2 STRING "1"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA0 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA1 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_CLKENA2 STRING "0"
|
||||
// Retrieval info: PRIVATE: USE_MIL_SPEED_GRADE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: ZERO_DELAY_RADIO STRING "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: BANDWIDTH_TYPE STRING "AUTO"
|
||||
// Retrieval info: CONSTANT: CLK0_DIVIDE_BY NUMERIC "33"
|
||||
// Retrieval info: CONSTANT: CLK0_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK0_MULTIPLY_BY NUMERIC "35"
|
||||
// Retrieval info: CONSTANT: CLK0_PHASE_SHIFT STRING "0"
|
||||
// Retrieval info: CONSTANT: CLK1_DIVIDE_BY NUMERIC "66"
|
||||
// Retrieval info: CONSTANT: CLK1_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK1_MULTIPLY_BY NUMERIC "35"
|
||||
// Retrieval info: CONSTANT: CLK1_PHASE_SHIFT STRING "0"
|
||||
// Retrieval info: CONSTANT: CLK2_DIVIDE_BY NUMERIC "132"
|
||||
// Retrieval info: CONSTANT: CLK2_DUTY_CYCLE NUMERIC "50"
|
||||
// Retrieval info: CONSTANT: CLK2_MULTIPLY_BY NUMERIC "35"
|
||||
// Retrieval info: CONSTANT: CLK2_PHASE_SHIFT STRING "0"
|
||||
// Retrieval info: CONSTANT: COMPENSATE_CLOCK STRING "CLK0"
|
||||
// Retrieval info: CONSTANT: INCLK0_INPUT_FREQUENCY NUMERIC "37037"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "altpll"
|
||||
// Retrieval info: CONSTANT: OPERATION_MODE STRING "NORMAL"
|
||||
// Retrieval info: CONSTANT: PLL_TYPE STRING "AUTO"
|
||||
// Retrieval info: CONSTANT: PORT_ACTIVECLOCK STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_ARESET STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKBAD0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKBAD1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKLOSS STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CLKSWITCH STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_CONFIGUPDATE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_FBIN STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_INCLK0 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_INCLK1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_LOCKED STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_PFDENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASECOUNTERSELECT STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASEDONE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASESTEP STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PHASEUPDOWN STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_PLLENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANACLR STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANCLK STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANCLKENA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDATA STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDATAOUT STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANDONE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANREAD STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_SCANWRITE STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk0 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk1 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk2 STRING "PORT_USED"
|
||||
// Retrieval info: CONSTANT: PORT_clk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clk5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena4 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_clkena5 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk0 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk1 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk2 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: PORT_extclk3 STRING "PORT_UNUSED"
|
||||
// Retrieval info: CONSTANT: SELF_RESET_ON_LOSS_LOCK STRING "OFF"
|
||||
// Retrieval info: CONSTANT: WIDTH_CLOCK NUMERIC "5"
|
||||
// Retrieval info: USED_PORT: @clk 0 0 5 0 OUTPUT_CLK_EXT VCC "@clk[4..0]"
|
||||
// Retrieval info: USED_PORT: areset 0 0 0 0 INPUT GND "areset"
|
||||
// Retrieval info: USED_PORT: c0 0 0 0 0 OUTPUT_CLK_EXT VCC "c0"
|
||||
// Retrieval info: USED_PORT: c1 0 0 0 0 OUTPUT_CLK_EXT VCC "c1"
|
||||
// Retrieval info: USED_PORT: c2 0 0 0 0 OUTPUT_CLK_EXT VCC "c2"
|
||||
// Retrieval info: USED_PORT: inclk0 0 0 0 0 INPUT_CLK_EXT GND "inclk0"
|
||||
// Retrieval info: USED_PORT: locked 0 0 0 0 OUTPUT GND "locked"
|
||||
// Retrieval info: CONNECT: @areset 0 0 0 0 areset 0 0 0 0
|
||||
// Retrieval info: CONNECT: @inclk 0 0 1 1 GND 0 0 0 0
|
||||
// Retrieval info: CONNECT: @inclk 0 0 1 0 inclk0 0 0 0 0
|
||||
// Retrieval info: CONNECT: c0 0 0 0 0 @clk 0 0 1 0
|
||||
// Retrieval info: CONNECT: c1 0 0 0 0 @clk 0 0 1 1
|
||||
// Retrieval info: CONNECT: c2 0 0 0 0 @clk 0 0 1 2
|
||||
// Retrieval info: CONNECT: locked 0 0 0 0 @locked 0 0 0 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.ppf TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL pll_bb.v FALSE
|
||||
// Retrieval info: LIB_FILE: altera_mf
|
||||
// Retrieval info: CBX_MODULE_PREFIX: ON
|
||||
3
Apple - 2_MiST/rtl/ram.qip
Normal file
3
Apple - 2_MiST/rtl/ram.qip
Normal file
@@ -0,0 +1,3 @@
|
||||
set_global_assignment -name IP_TOOL_NAME "RAM: 1-PORT"
|
||||
set_global_assignment -name IP_TOOL_VERSION "13.1"
|
||||
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "ram.v"]
|
||||
172
Apple - 2_MiST/rtl/ram.v
Normal file
172
Apple - 2_MiST/rtl/ram.v
Normal file
@@ -0,0 +1,172 @@
|
||||
// megafunction wizard: %RAM: 1-PORT%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altsyncram
|
||||
|
||||
// ============================================================
|
||||
// File Name: ram.v
|
||||
// Megafunction Name(s):
|
||||
// altsyncram
|
||||
//
|
||||
// Simulation Library Files(s):
|
||||
// altera_mf
|
||||
// ============================================================
|
||||
// ************************************************************
|
||||
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
|
||||
//
|
||||
// 13.1.0 Build 162 10/23/2013 SJ Web Edition
|
||||
// ************************************************************
|
||||
|
||||
|
||||
//Copyright (C) 1991-2013 Altera Corporation
|
||||
//Your use of Altera Corporation's design tools, logic functions
|
||||
//and other software and tools, and its AMPP partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Altera Program License
|
||||
//Subscription Agreement, Altera MegaCore Function License
|
||||
//Agreement, or other applicable license agreement, including,
|
||||
//without limitation, that your use is for the sole purpose of
|
||||
//programming logic devices manufactured by Altera and sold by
|
||||
//Altera or its authorized distributors. Please refer to the
|
||||
//applicable agreement for further details.
|
||||
|
||||
|
||||
// synopsys translate_off
|
||||
`timescale 1 ps / 1 ps
|
||||
// synopsys translate_on
|
||||
module ram (
|
||||
address,
|
||||
clock,
|
||||
data,
|
||||
wren,
|
||||
q);
|
||||
|
||||
input [13:0] address;
|
||||
input clock;
|
||||
input [15:0] data;
|
||||
input wren;
|
||||
output [15:0] q;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_off
|
||||
`endif
|
||||
tri1 clock;
|
||||
`ifndef ALTERA_RESERVED_QIS
|
||||
// synopsys translate_on
|
||||
`endif
|
||||
|
||||
wire [15:0] sub_wire0;
|
||||
wire [15:0] q = sub_wire0[15:0];
|
||||
|
||||
altsyncram altsyncram_component (
|
||||
.address_a (address),
|
||||
.clock0 (clock),
|
||||
.data_a (data),
|
||||
.wren_a (wren),
|
||||
.q_a (sub_wire0),
|
||||
.aclr0 (1'b0),
|
||||
.aclr1 (1'b0),
|
||||
.address_b (1'b1),
|
||||
.addressstall_a (1'b0),
|
||||
.addressstall_b (1'b0),
|
||||
.byteena_a (1'b1),
|
||||
.byteena_b (1'b1),
|
||||
.clock1 (1'b1),
|
||||
.clocken0 (1'b1),
|
||||
.clocken1 (1'b1),
|
||||
.clocken2 (1'b1),
|
||||
.clocken3 (1'b1),
|
||||
.data_b (1'b1),
|
||||
.eccstatus (),
|
||||
.q_b (),
|
||||
.rden_a (1'b1),
|
||||
.rden_b (1'b1),
|
||||
.wren_b (1'b0));
|
||||
defparam
|
||||
altsyncram_component.clock_enable_input_a = "BYPASS",
|
||||
altsyncram_component.clock_enable_output_a = "BYPASS",
|
||||
altsyncram_component.intended_device_family = "Cyclone III",
|
||||
altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO",
|
||||
altsyncram_component.lpm_type = "altsyncram",
|
||||
altsyncram_component.numwords_a = 16384,
|
||||
altsyncram_component.operation_mode = "SINGLE_PORT",
|
||||
altsyncram_component.outdata_aclr_a = "NONE",
|
||||
altsyncram_component.outdata_reg_a = "CLOCK0",
|
||||
altsyncram_component.power_up_uninitialized = "FALSE",
|
||||
altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ",
|
||||
altsyncram_component.widthad_a = 14,
|
||||
altsyncram_component.width_a = 16,
|
||||
altsyncram_component.width_byteena_a = 1;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
// ============================================================
|
||||
// CNX file retrieval info
|
||||
// ============================================================
|
||||
// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AclrByte NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AclrData NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
|
||||
// Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: Clken NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: DataBusSeparated NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
|
||||
// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||||
// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
|
||||
// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: MIFfilename STRING ""
|
||||
// Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "16384"
|
||||
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "3"
|
||||
// Retrieval info: PRIVATE: RegAddr NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: RegData NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: RegOutput NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
|
||||
// Retrieval info: PRIVATE: SingleClock NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: UseDQRAM NUMERIC "1"
|
||||
// Retrieval info: PRIVATE: WRCONTROL_ACLR_A NUMERIC "0"
|
||||
// Retrieval info: PRIVATE: WidthAddr NUMERIC "14"
|
||||
// Retrieval info: PRIVATE: WidthData NUMERIC "16"
|
||||
// Retrieval info: PRIVATE: rden NUMERIC "0"
|
||||
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
|
||||
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
|
||||
// Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
|
||||
// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
|
||||
// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "16384"
|
||||
// Retrieval info: CONSTANT: OPERATION_MODE STRING "SINGLE_PORT"
|
||||
// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
|
||||
// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0"
|
||||
// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
|
||||
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_NO_NBE_READ"
|
||||
// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "14"
|
||||
// Retrieval info: CONSTANT: WIDTH_A NUMERIC "16"
|
||||
// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
|
||||
// Retrieval info: USED_PORT: address 0 0 14 0 INPUT NODEFVAL "address[13..0]"
|
||||
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
|
||||
// Retrieval info: USED_PORT: data 0 0 16 0 INPUT NODEFVAL "data[15..0]"
|
||||
// Retrieval info: USED_PORT: q 0 0 16 0 OUTPUT NODEFVAL "q[15..0]"
|
||||
// Retrieval info: USED_PORT: wren 0 0 0 0 INPUT NODEFVAL "wren"
|
||||
// Retrieval info: CONNECT: @address_a 0 0 14 0 address 0 0 14 0
|
||||
// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
|
||||
// Retrieval info: CONNECT: @data_a 0 0 16 0 data 0 0 16 0
|
||||
// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren 0 0 0 0
|
||||
// Retrieval info: CONNECT: q 0 0 16 0 @q_a 0 0 16 0
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram.v TRUE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram.inc FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram.cmp FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram.bsf FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_inst.v FALSE
|
||||
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_bb.v FALSE
|
||||
// Retrieval info: LIB_FILE: altera_mf
|
||||
BIN
Apple - 2_MiST/rtl/roms/apple_II.rom
Normal file
BIN
Apple - 2_MiST/rtl/roms/apple_II.rom
Normal file
Binary file not shown.
255
Apple - 2_MiST/rtl/roms/bios.a65
Normal file
255
Apple - 2_MiST/rtl/roms/bios.a65
Normal file
@@ -0,0 +1,255 @@
|
||||
; Trivial BIOS for an Apple II+ -- just enough to show the hardware works
|
||||
;
|
||||
; Stephen A. Edwards
|
||||
;
|
||||
; Assemble with "xa -A 53248 -bt 53248 ..." to start the code at $D000
|
||||
|
||||
gbasl = $26
|
||||
gbash = $27
|
||||
basl = $28
|
||||
bash = $29
|
||||
|
||||
text = $400 ; start of text/lores screen memory
|
||||
bhires = $2000 ; start of hires screen memory
|
||||
line8 = $428
|
||||
line9 = $4A8
|
||||
line10 = $528
|
||||
line11 = $5A8
|
||||
|
||||
line23 = $7D0
|
||||
|
||||
keyboard = $C000
|
||||
key_strobe = $C010
|
||||
|
||||
spkr = $C030
|
||||
grset = $C050
|
||||
txtset = $C051
|
||||
nomix = $C052
|
||||
mix = $C053
|
||||
page1 = $C054
|
||||
page2 = $C055
|
||||
lores = $C056
|
||||
hires = $C057
|
||||
|
||||
nmi_vector = $FFFA
|
||||
nmi = reset
|
||||
irq = reset
|
||||
|
||||
reset:
|
||||
cld
|
||||
lda txtset
|
||||
lda page1
|
||||
|
||||
; Clear the text screen
|
||||
|
||||
lda #<text
|
||||
sta gbasl
|
||||
lda #>text
|
||||
sta gbash
|
||||
ldy #0
|
||||
ldx #4
|
||||
lda #$A0 ; Normal space
|
||||
l0
|
||||
sta (gbasl),y
|
||||
dey
|
||||
bne l0
|
||||
inc gbash
|
||||
dex
|
||||
bne l0
|
||||
|
||||
; Play three tones
|
||||
|
||||
ldy #0
|
||||
tone1
|
||||
lda #15
|
||||
jsr wait
|
||||
sta spkr
|
||||
dey
|
||||
bne tone1
|
||||
|
||||
tone2
|
||||
lda #12
|
||||
jsr wait
|
||||
sta spkr
|
||||
dey
|
||||
bne tone2
|
||||
|
||||
tone3
|
||||
lda #8
|
||||
jsr wait
|
||||
sta spkr
|
||||
dey
|
||||
bne tone3
|
||||
|
||||
; Print some messages
|
||||
lda #<text+15
|
||||
sta gbasl
|
||||
lda #>text
|
||||
sta gbash
|
||||
lda #<hello
|
||||
sta basl
|
||||
lda #>hello
|
||||
sta bash
|
||||
jsr write_string
|
||||
|
||||
lda #<line8+8
|
||||
sta gbasl
|
||||
lda #<roms1
|
||||
sta basl
|
||||
lda #>roms1
|
||||
sta bash
|
||||
jsr write_string
|
||||
|
||||
lda #<line10
|
||||
sta gbasl
|
||||
lda #>line10
|
||||
sta gbash
|
||||
lda #<roms2
|
||||
sta basl
|
||||
lda #>roms2
|
||||
sta bash
|
||||
jsr write_string
|
||||
|
||||
lda #<line11
|
||||
sta gbasl
|
||||
lda #>line11
|
||||
sta gbash
|
||||
lda #<roms3
|
||||
sta basl
|
||||
lda #>roms3
|
||||
sta bash
|
||||
jsr write_string
|
||||
|
||||
lda #<line23
|
||||
sta gbasl
|
||||
lda #>line23
|
||||
sta gbash
|
||||
lda #<press
|
||||
sta basl
|
||||
lda #>press
|
||||
sta bash
|
||||
jsr write_string
|
||||
|
||||
wait_for_key
|
||||
bit keyboard
|
||||
bpl wait_for_key
|
||||
sta key_strobe
|
||||
|
||||
; Set lores mode
|
||||
sta lores
|
||||
sta nomix
|
||||
sta grset
|
||||
|
||||
; Fill the screen with colors
|
||||
lda #0
|
||||
fill
|
||||
ldx #<text
|
||||
stx gbasl
|
||||
ldx #>text
|
||||
stx gbash
|
||||
ldy #0
|
||||
ldx #4
|
||||
l2
|
||||
sta (gbasl),y
|
||||
adc #1
|
||||
dey
|
||||
bne l2
|
||||
inc gbash
|
||||
dex
|
||||
bne l2
|
||||
|
||||
adc #1
|
||||
|
||||
bit keyboard
|
||||
bpl fill
|
||||
sta key_strobe
|
||||
|
||||
; Wait for another keypress
|
||||
|
||||
wait_key1
|
||||
bit keyboard
|
||||
bpl wait_key1
|
||||
sta key_strobe
|
||||
|
||||
; Set hires mode
|
||||
sta hires
|
||||
|
||||
; Fill the screen with colors
|
||||
lda #0
|
||||
fillh
|
||||
ldx #<bhires
|
||||
stx gbasl
|
||||
ldx #>bhires
|
||||
stx gbash
|
||||
ldy #0
|
||||
ldx #$20
|
||||
l3
|
||||
sta (gbasl),y
|
||||
adc #1
|
||||
dey
|
||||
bne l3
|
||||
inc gbash
|
||||
dex
|
||||
bne l3
|
||||
|
||||
adc #1
|
||||
|
||||
bit keyboard
|
||||
bpl fillh
|
||||
sta key_strobe
|
||||
|
||||
; Wait for another keypress
|
||||
|
||||
wait_key2
|
||||
bit keyboard
|
||||
bpl wait_key2
|
||||
sta key_strobe
|
||||
|
||||
jmp reset
|
||||
|
||||
done
|
||||
rts
|
||||
write_string
|
||||
ldy #0
|
||||
l1
|
||||
lda (basl),y
|
||||
beq done
|
||||
ora #$80
|
||||
sta (gbasl),y
|
||||
iny
|
||||
bne l1
|
||||
rts
|
||||
|
||||
; A quadratic delay
|
||||
|
||||
wait sec
|
||||
wait2 pha
|
||||
wait3 sbc #1
|
||||
bne wait3
|
||||
pla
|
||||
sbc #1
|
||||
bne wait2
|
||||
rts
|
||||
|
||||
|
||||
hello .asc "APPLE2FPGA"
|
||||
.byt 0
|
||||
|
||||
roms1 .asc "THIS IS NOT APPLE'S BIOS"
|
||||
.byt 0
|
||||
|
||||
roms2 .asc "TO RUN APPLE PROGRAMS, GET A COPY OF THE"
|
||||
.byt 0
|
||||
|
||||
roms3 .asc "ACTUAL APPLE II ROMS (D000-FFFF)"
|
||||
.byt 0
|
||||
|
||||
press .asc "PRESS ANY KEY TO ADVANCE"
|
||||
.byt 0
|
||||
|
||||
; Pad to the start of the NMI vector
|
||||
here .dsb (nmi_vector - here)
|
||||
|
||||
.word nmi
|
||||
.word reset
|
||||
.word irq
|
||||
BIN
Apple - 2_MiST/rtl/roms/bios.rom
Normal file
BIN
Apple - 2_MiST/rtl/roms/bios.rom
Normal file
Binary file not shown.
BIN
Apple - 2_MiST/rtl/roms/slot6.rom
Normal file
BIN
Apple - 2_MiST/rtl/roms/slot6.rom
Normal file
Binary file not shown.
229
Apple - 2_MiST/rtl/scan_converter.vhd
Normal file
229
Apple - 2_MiST/rtl/scan_converter.vhd
Normal file
@@ -0,0 +1,229 @@
|
||||
-- (c) 2012 d18c7db(a)hotmail
|
||||
--
|
||||
-- This program is free software; you can redistribute it and/or modify it under
|
||||
-- the terms of the GNU General Public License version 3 or, at your option,
|
||||
-- any later version as published by the Free Software Foundation.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
--
|
||||
-- For full details, see the GNU General Public License at www.gnu.org/licenses
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
-- Video scan converter
|
||||
--
|
||||
-- Horizonal Timing
|
||||
-- _____________ ______________________ _____________________
|
||||
-- VIDEO (last) |____________| VIDEO |____________| VIDEO (next)
|
||||
-- -hD----------|-hA-|hB|-hC-|----------hD----------|-hA-|hB|-hC-|----------hD---------
|
||||
-- __________________| |________________________________| |__________________________
|
||||
-- HSYNC |__| HSYNC |__| HSYNC
|
||||
|
||||
-- Vertical Timing
|
||||
-- _____________ ______________________ _____________________
|
||||
-- VIDEO (last)||____________||||||||||VIDEO|||||||||____________||||||||||VIDEO (next)
|
||||
-- -vD----------|-vA-|vB|-vC-|----------vD----------|-vA-|vB|-vC-|----------vD---------
|
||||
-- __________________| |________________________________| |__________________________
|
||||
-- VSYNC |__| VSYNC |__| VSYNC
|
||||
|
||||
-- Scan converter input and output timings compared to standard VGA
|
||||
-- Resolution - Frame | Pixel | Front | HSYNC | Back | Active | HSYNC | Front | VSYNC | Back | Active | VSYNC
|
||||
-- - Rate | Clock | Porch hA | Pulse hB | Porch hC | Video hD | Polarity | Porch vA | Pulse vB | Porch vC | Video vD | Polarity
|
||||
-------------------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
-- In 256x224 - 59.18Hz | 6.000 MHz | 38 pixels | 32 pixels | 58 pixels | 256 pixels | negative | 16 lines | 8 lines | 16 lines | 224 lines | negative
|
||||
-- Out 640x480 - 59.18Hz | 24.000 MHz | 2 pixels | 92 pixels | 34 pixels | 640 pixels | negative | 17 lines | 2 lines | 29 lines | 480 lines | negative
|
||||
-- VGA 640x480 - 59.94Hz | 25.175 MHz | 16 pixels | 96 pixels | 48 pixels | 640 pixels | negative | 10 lines | 2 lines | 33 lines | 480 lines | negative
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_unsigned.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
--pragma translate_off
|
||||
use ieee.std_logic_textio.all;
|
||||
use std.textio.all;
|
||||
--pragma translate_on
|
||||
|
||||
entity VGA_SCANCONV is
|
||||
generic (
|
||||
cstart : integer range 0 to 1023 := 144; -- composite sync start
|
||||
clength : integer range 0 to 1023 := 640; -- composite sync length
|
||||
|
||||
hA : integer range 0 to 1023 := 16; -- h front porch
|
||||
hB : integer range 0 to 1023 := 96; -- h sync
|
||||
hC : integer range 0 to 1023 := 48; -- h back porch
|
||||
hD : integer range 0 to 1023 := 640; -- visible video
|
||||
|
||||
-- vA : integer range 0 to 1023 := 16; -- v front porch
|
||||
vB : integer range 0 to 1023 := 2; -- v sync
|
||||
vC : integer range 0 to 1023 := 33; -- v back porch
|
||||
vD : integer range 0 to 1023 := 480; -- visible video
|
||||
|
||||
hpad : integer range 0 to 1023 := 0; -- H black border
|
||||
vpad : integer range 0 to 1023 := 0 -- V black border
|
||||
);
|
||||
port (
|
||||
I_VIDEO : in std_logic_vector(15 downto 0);
|
||||
I_HSYNC : in std_logic;
|
||||
I_VSYNC : in std_logic;
|
||||
--
|
||||
O_VIDEO : out std_logic_vector(15 downto 0);
|
||||
O_HSYNC : out std_logic;
|
||||
O_VSYNC : out std_logic;
|
||||
O_CMPBLK_N : out std_logic;
|
||||
--
|
||||
CLK : in std_logic;
|
||||
CLK_x2 : in std_logic
|
||||
);
|
||||
end;
|
||||
|
||||
architecture RTL of VGA_SCANCONV is
|
||||
--
|
||||
-- input timing
|
||||
--
|
||||
signal ivsync_last_x2 : std_logic := '1';
|
||||
signal ihsync_last : std_logic := '1';
|
||||
signal hpos_i : std_logic_vector( 9 downto 0) := (others => '0');
|
||||
|
||||
--
|
||||
-- output timing
|
||||
--
|
||||
signal hpos_o : std_logic_vector(9 downto 0) := (others => '0');
|
||||
|
||||
signal vcnt : integer range 0 to 1023 := 0;
|
||||
signal hcnt : integer range 0 to 1023 := 0;
|
||||
signal hcnti : integer range 0 to 1023 := 0;
|
||||
|
||||
signal CLK_x2_n : std_logic := '1';
|
||||
|
||||
begin
|
||||
-- dual port line buffer, max line of 1024 pixels
|
||||
u_ram : entity work.RAMB16_S18_S18
|
||||
-- generic map (INIT_A => X"00000", INIT_B => X"00000", SIM_COLLISION_CHECK => "ALL") -- "NONE", "WARNING", "GENERATE_X_ONLY", "ALL"
|
||||
port map (
|
||||
-- input
|
||||
q_a => open,
|
||||
data_a => I_VIDEO,
|
||||
|
||||
|
||||
address_a => hpos_i,
|
||||
wren_a => '1',
|
||||
rden_a => CLK,
|
||||
|
||||
clock_a => CLK_x2,
|
||||
|
||||
-- output
|
||||
q_b => O_VIDEO,
|
||||
data_b => x"0000",
|
||||
|
||||
|
||||
address_b => hpos_o,
|
||||
wren_b => '0',
|
||||
rden_b => '1',
|
||||
|
||||
clock_b => CLK_x2_n
|
||||
);
|
||||
|
||||
CLK_x2_n <= not CLK_x2;
|
||||
|
||||
-- horizontal counter for input video
|
||||
p_hcounter : process
|
||||
begin
|
||||
wait until rising_edge(CLK_x2);
|
||||
if CLK = '0' then
|
||||
ihsync_last <= I_HSYNC;
|
||||
|
||||
-- trigger off rising hsync
|
||||
if I_HSYNC = '1' and ihsync_last = '0' then
|
||||
hcnti <= 0;
|
||||
else
|
||||
hcnti <= hcnti + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- increment write position during active video
|
||||
p_ram_in : process
|
||||
begin
|
||||
wait until rising_edge(CLK_x2);
|
||||
if CLK = '0' then
|
||||
if (hcnti < cstart) or (hcnti >= (cstart + clength)) then
|
||||
hpos_i <= (others => '0');
|
||||
else
|
||||
hpos_i <= hpos_i + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- VGA H and V counters, synchronized to input frame V sync, then H sync
|
||||
p_out_ctrs : process
|
||||
variable trigger : boolean;
|
||||
begin
|
||||
wait until rising_edge(CLK_x2);
|
||||
ivsync_last_x2 <= I_VSYNC;
|
||||
|
||||
if (I_VSYNC = '0') and (ivsync_last_x2 = '1') then
|
||||
trigger := true;
|
||||
elsif trigger and I_HSYNC = '0' then
|
||||
trigger := false;
|
||||
hcnt <= 0;
|
||||
vcnt <= 0;
|
||||
else
|
||||
hcnt <= hcnt + 1;
|
||||
if hcnt = (hA+hB+hC+hD+hpad+hpad-1) then
|
||||
hcnt <= 0;
|
||||
vcnt <= vcnt + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- generate hsync
|
||||
p_gen_hsync : process
|
||||
begin
|
||||
wait until rising_edge(CLK_x2);
|
||||
-- H sync timing
|
||||
if (hcnt < hB) then
|
||||
O_HSYNC <= '0';
|
||||
else
|
||||
O_HSYNC <= '1';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- generate vsync
|
||||
p_gen_vsync : process
|
||||
begin
|
||||
wait until rising_edge(CLK_x2);
|
||||
-- V sync timing
|
||||
if (vcnt < vB) then
|
||||
O_VSYNC <= '0';
|
||||
else
|
||||
O_VSYNC <= '1';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- generate active output video
|
||||
p_gen_active_vid : process
|
||||
begin
|
||||
wait until rising_edge(CLK_x2);
|
||||
-- visible video area doubled from the original game
|
||||
if ((hcnt >= (hB + hC + hpad)) and (hcnt < (hB + hC + hD + hpad))) and ((vcnt > 2*(vB + vC + vpad)) and (vcnt <= 2*(vB + vC + vD + vpad))) then
|
||||
hpos_o <= hpos_o + 1;
|
||||
else
|
||||
hpos_o <= (others => '0');
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- generate blanking signal including additional borders to pad the input signal to standard VGA resolution
|
||||
p_gen_blank : process
|
||||
begin
|
||||
wait until rising_edge(CLK_X2);
|
||||
-- active video area 640x480 (VGA) after padding with blank borders
|
||||
if ((hcnt >= (hB + hC)) and (hcnt < (hB + hC + hD + 2*hpad))) and ((vcnt > 2*(vB + vC)) and (vcnt <= 2*(vB + vC + vD + 2*vpad))) then
|
||||
O_CMPBLK_N <= '1';
|
||||
else
|
||||
O_CMPBLK_N <= '0';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture RTL;
|
||||
195
Apple - 2_MiST/rtl/scandoubler.v
Normal file
195
Apple - 2_MiST/rtl/scandoubler.v
Normal file
@@ -0,0 +1,195 @@
|
||||
//
|
||||
// scandoubler.v
|
||||
//
|
||||
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
||||
// Copyright (c) 2017 Sorgelig
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// TODO: Delay vsync one line
|
||||
|
||||
module scandoubler #(parameter LENGTH, parameter HALF_DEPTH)
|
||||
(
|
||||
// system interface
|
||||
input clk_sys,
|
||||
input ce_pix,
|
||||
input ce_pix_actual,
|
||||
|
||||
input hq2x,
|
||||
|
||||
// shifter video interface
|
||||
input hs_in,
|
||||
input vs_in,
|
||||
input line_start,
|
||||
|
||||
input [DWIDTH:0] r_in,
|
||||
input [DWIDTH:0] g_in,
|
||||
input [DWIDTH:0] b_in,
|
||||
input mono,
|
||||
|
||||
// output interface
|
||||
output reg hs_out,
|
||||
output vs_out,
|
||||
output [DWIDTH:0] r_out,
|
||||
output [DWIDTH:0] g_out,
|
||||
output [DWIDTH:0] b_out
|
||||
);
|
||||
|
||||
|
||||
localparam DWIDTH = HALF_DEPTH ? 2 : 5;
|
||||
|
||||
assign vs_out = vs_in;
|
||||
|
||||
reg [2:0] phase;
|
||||
reg [2:0] ce_div;
|
||||
reg [7:0] pix_len = 0;
|
||||
wire [7:0] pl = pix_len + 1'b1;
|
||||
|
||||
reg ce_x1, ce_x4;
|
||||
reg req_line_reset;
|
||||
wire ls_in = hs_in | line_start;
|
||||
always @(negedge clk_sys) begin
|
||||
reg old_ce;
|
||||
reg [2:0] ce_cnt;
|
||||
|
||||
reg [7:0] pixsz2, pixsz4 = 0;
|
||||
|
||||
old_ce <= ce_pix;
|
||||
if(~&pix_len) pix_len <= pix_len + 1'd1;
|
||||
|
||||
ce_x4 <= 0;
|
||||
ce_x1 <= 0;
|
||||
|
||||
// use such odd comparison to place c_x4 evenly if master clock isn't multiple 4.
|
||||
if((pl == pixsz4) || (pl == pixsz2) || (pl == (pixsz2+pixsz4))) begin
|
||||
phase <= phase + 1'd1;
|
||||
ce_x4 <= 1;
|
||||
end
|
||||
|
||||
if(~old_ce & ce_pix) begin
|
||||
pixsz2 <= {1'b0, pl[7:1]};
|
||||
pixsz4 <= {2'b00, pl[7:2]};
|
||||
ce_x1 <= 1;
|
||||
ce_x4 <= 1;
|
||||
pix_len <= 0;
|
||||
phase <= phase + 1'd1;
|
||||
|
||||
ce_cnt <= ce_cnt + 1'd1;
|
||||
if(ce_pix_actual) begin
|
||||
phase <= 0;
|
||||
ce_div <= ce_cnt + 1'd1;
|
||||
ce_cnt <= 0;
|
||||
req_line_reset <= 0;
|
||||
end
|
||||
|
||||
if(ls_in) req_line_reset <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
reg ce_sd;
|
||||
always @(*) begin
|
||||
case(ce_div)
|
||||
2: ce_sd = !phase[0];
|
||||
4: ce_sd = !phase[1:0];
|
||||
default: ce_sd <= 1;
|
||||
endcase
|
||||
end
|
||||
|
||||
`define BITS_TO_FIT(N) ( \
|
||||
N <= 2 ? 0 : \
|
||||
N <= 4 ? 1 : \
|
||||
N <= 8 ? 2 : \
|
||||
N <= 16 ? 3 : \
|
||||
N <= 32 ? 4 : \
|
||||
N <= 64 ? 5 : \
|
||||
N <= 128 ? 6 : \
|
||||
N <= 256 ? 7 : \
|
||||
N <= 512 ? 8 : \
|
||||
N <=1024 ? 9 : 10 )
|
||||
|
||||
localparam AWIDTH = `BITS_TO_FIT(LENGTH);
|
||||
Hq2x #(.LENGTH(LENGTH), .HALF_DEPTH(HALF_DEPTH)) Hq2x
|
||||
(
|
||||
.clk(clk_sys),
|
||||
.ce_x4(ce_x4 & ce_sd),
|
||||
.inputpixel({b_in,g_in,r_in}),
|
||||
.mono(mono),
|
||||
.disable_hq2x(~hq2x),
|
||||
.reset_frame(vs_in),
|
||||
.reset_line(req_line_reset),
|
||||
.read_y(sd_line),
|
||||
.read_x(sd_h_actual),
|
||||
.outpixel({b_out,g_out,r_out})
|
||||
);
|
||||
|
||||
reg [10:0] sd_h_actual;
|
||||
always @(*) begin
|
||||
case(ce_div)
|
||||
2: sd_h_actual = sd_h[10:1];
|
||||
4: sd_h_actual = sd_h[10:2];
|
||||
default: sd_h_actual = sd_h;
|
||||
endcase
|
||||
end
|
||||
|
||||
reg [10:0] sd_h;
|
||||
reg [1:0] sd_line;
|
||||
always @(posedge clk_sys) begin
|
||||
|
||||
reg [11:0] hs_max,hs_rise,hs_ls;
|
||||
reg [10:0] hcnt;
|
||||
reg [11:0] sd_hcnt;
|
||||
|
||||
reg hs, hs2, vs, ls;
|
||||
|
||||
if(ce_x1) begin
|
||||
hs <= hs_in;
|
||||
ls <= ls_in;
|
||||
|
||||
if(ls && !ls_in) hs_ls <= {hcnt,1'b1};
|
||||
|
||||
// falling edge of hsync indicates start of line
|
||||
if(hs && !hs_in) begin
|
||||
hs_max <= {hcnt,1'b1};
|
||||
hcnt <= 0;
|
||||
if(ls && !ls_in) hs_ls <= {10'd0,1'b1};
|
||||
end else begin
|
||||
hcnt <= hcnt + 1'd1;
|
||||
end
|
||||
|
||||
// save position of rising edge
|
||||
if(!hs && hs_in) hs_rise <= {hcnt,1'b1};
|
||||
|
||||
vs <= vs_in;
|
||||
if(vs && ~vs_in) sd_line <= 0;
|
||||
end
|
||||
|
||||
if(ce_x4) begin
|
||||
hs2 <= hs_in;
|
||||
|
||||
// output counter synchronous to input and at twice the rate
|
||||
sd_hcnt <= sd_hcnt + 1'd1;
|
||||
sd_h <= sd_h + 1'd1;
|
||||
if(hs2 && !hs_in) sd_hcnt <= hs_max;
|
||||
if(sd_hcnt == hs_max) sd_hcnt <= 0;
|
||||
|
||||
// replicate horizontal sync at twice the speed
|
||||
if(sd_hcnt == hs_max) hs_out <= 0;
|
||||
if(sd_hcnt == hs_rise) hs_out <= 1;
|
||||
|
||||
if(sd_hcnt == hs_ls) sd_h <= 0;
|
||||
if(sd_hcnt == hs_ls) sd_line <= sd_line + 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
471
Apple - 2_MiST/rtl/spi_controller.vhd
Normal file
471
Apple - 2_MiST/rtl/spi_controller.vhd
Normal file
@@ -0,0 +1,471 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- SD/MMC interface (SPI-style) for the Apple ][ Emulator
|
||||
--
|
||||
-- Michel Stempin (michel.stempin@wanadoo.fr)
|
||||
-- Working with MMC/SD/SDHC cards
|
||||
--
|
||||
-- From previous work by:
|
||||
-- Stephen A. Edwards (sedwards@cs.columbia.edu)
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity spi_controller is
|
||||
generic (
|
||||
BLOCK_SIZE : natural := 512;
|
||||
BLOCK_BITS : natural := 9;
|
||||
TRACK_SIZE : natural := 16#1A00#
|
||||
);
|
||||
|
||||
port (
|
||||
-- Card Interface ---------------------------------------------------------
|
||||
CS_N : out std_logic; -- MMC chip select
|
||||
MOSI : out std_logic; -- Data to card (master out slave in)
|
||||
MISO : in std_logic; -- Data from card (master in slave out)
|
||||
SCLK : out std_logic; -- Card clock
|
||||
-- Track buffer Interface -------------------------------------------------
|
||||
ram_write_addr : out unsigned(13 downto 0);
|
||||
ram_di : out unsigned(7 downto 0);
|
||||
ram_we : out std_logic;
|
||||
track : in unsigned(5 downto 0); -- Track number (0-34)
|
||||
image : in unsigned(9 downto 0); -- Which disk image to read
|
||||
-- System Interface -------------------------------------------------------
|
||||
CLK_14M : in std_logic; -- System clock
|
||||
reset : in std_logic
|
||||
);
|
||||
|
||||
end spi_controller;
|
||||
|
||||
architecture rtl of spi_controller is
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- States of the combined MMC/SD/SDHC reset, track and command FSM
|
||||
--
|
||||
type states is (
|
||||
-- Reset FSM
|
||||
POWER_UP,
|
||||
RAMP_UP,
|
||||
CHECK_CMD0,
|
||||
CHECK_CMD8,
|
||||
CHECK_CMD55,
|
||||
CHECK_ACMD41,
|
||||
CHECK_CMD1,
|
||||
CHECK_CMD58,
|
||||
CHECK_SET_BLOCKLEN,
|
||||
ERROR,
|
||||
-- Track read FSM
|
||||
IDLE,
|
||||
READ_TRACK,
|
||||
READ_BLOCK_WAIT,
|
||||
READ_BLOCK_DATA,
|
||||
READ_BLOCK_CRC,
|
||||
-- SD command embedded FSM
|
||||
WAIT_NRC,
|
||||
SEND_CMD,
|
||||
RECEIVE_BYTE_WAIT,
|
||||
RECEIVE_BYTE);
|
||||
--
|
||||
signal state, return_state : states;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
signal slow_clk : boolean := true;
|
||||
signal spi_clk : std_logic;
|
||||
signal sclk_sig : std_logic;
|
||||
|
||||
signal current_track : unsigned(5 downto 0);
|
||||
signal current_image : unsigned(9 downto 0);
|
||||
signal write_addr : unsigned(13 downto 0);
|
||||
|
||||
signal command : std_logic_vector(5 downto 0);
|
||||
signal argument : std_logic_vector(31 downto 0);
|
||||
signal crc7 : std_logic_vector(6 downto 0);
|
||||
signal command_out : std_logic_vector(55 downto 0);
|
||||
signal recv_bytes : unsigned(39 downto 0);
|
||||
type versions is (MMC, SD1x, SD2x);
|
||||
signal version : versions;
|
||||
signal high_capacity : boolean;
|
||||
|
||||
begin
|
||||
|
||||
ram_write_addr <= write_addr;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process var_clkgen
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the variable speed clock for MMC compatibility.
|
||||
-- If slow_clk is false, spi_clk == CLK_14M, thus SCLK = 7M
|
||||
-- If slow_clk is true, spi_clk = CLK_14M / 32 and SCLK = 223.214kHz, which
|
||||
-- is between 100kHz and 400kHz, as required for MMC compatibility.
|
||||
--
|
||||
var_clkgen : process (CLK_14M, slow_clk)
|
||||
variable var_clk : unsigned(4 downto 0) := (others => '0');
|
||||
begin
|
||||
if slow_clk then
|
||||
spi_clk <= var_clk(4);
|
||||
if rising_edge(CLK_14M) then
|
||||
var_clk := var_clk + 1;
|
||||
end if;
|
||||
else
|
||||
spi_clk <= CLK_14M;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
SCLK <= sclk_sig;
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
-- Process sd_fsm
|
||||
--
|
||||
-- Purpose:
|
||||
-- Implements the combined "SD Card init", "track read" and "command" FSMs.
|
||||
--
|
||||
sd_fsm : process(spi_clk)
|
||||
subtype cmd_t is std_logic_vector(5 downto 0);
|
||||
constant CMD0 : cmd_t := std_logic_vector(to_unsigned(0, 6));
|
||||
constant CMD1 : cmd_t := std_logic_vector(to_unsigned(1, 6));
|
||||
constant CMD8 : cmd_t := std_logic_vector(to_unsigned(8, 6));
|
||||
constant CMD16 : cmd_t := std_logic_vector(to_unsigned(16, 6));
|
||||
constant CMD17 : cmd_t := std_logic_vector(to_unsigned(17, 6));
|
||||
constant CMD55 : cmd_t := std_logic_vector(to_unsigned(55, 6));
|
||||
constant CMD58 : cmd_t := std_logic_vector(to_unsigned(58, 6));
|
||||
constant ACMD41 : cmd_t := std_logic_vector(to_unsigned(41, 6));
|
||||
variable counter : unsigned(7 downto 0);
|
||||
variable byte_counter : unsigned(BLOCK_BITS - 1 downto 0);
|
||||
variable lba : unsigned(31 downto 0);
|
||||
|
||||
begin
|
||||
if rising_edge(spi_clk) then
|
||||
ram_we <= '0';
|
||||
if reset = '1' then
|
||||
state <= POWER_UP;
|
||||
-- Deliberately out of range
|
||||
current_track <= (others => '1');
|
||||
current_image <= (others => '1');
|
||||
sclk_sig <= '0';
|
||||
slow_clk <= true;
|
||||
CS_N <= '1';
|
||||
command <= (others => '0');
|
||||
argument <= (others => '0');
|
||||
crc7 <= (others => '0');
|
||||
command_out <= (others => '1');
|
||||
counter := TO_UNSIGNED(0, 8);
|
||||
byte_counter := TO_UNSIGNED(0, BLOCK_BITS);
|
||||
write_addr <= (others => '0');
|
||||
high_capacity <= false;
|
||||
version <= MMC;
|
||||
lba := (others => '0');
|
||||
else
|
||||
case state is
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- SD Card init FSM
|
||||
---------------------------------------------------------------------
|
||||
when POWER_UP =>
|
||||
counter := TO_UNSIGNED(224, 8);
|
||||
state <= RAMP_UP;
|
||||
|
||||
-- Output a series of 74 clock signals (or 1ms delay, whichever is
|
||||
-- greater) to wake up the card
|
||||
when RAMP_UP =>
|
||||
if counter = 0 then
|
||||
CS_N <= '0';
|
||||
command <= CMD0;
|
||||
argument <= (others => '0');
|
||||
crc7 <= "1001010";
|
||||
return_state <= CHECK_CMD0;
|
||||
state <= WAIT_NRC;
|
||||
else
|
||||
counter := counter - 1;
|
||||
sclk_sig <= not sclk_sig;
|
||||
end if;
|
||||
|
||||
-- CMD0: GO_IDLE_STATE ----------------------------------------------
|
||||
when CHECK_CMD0 =>
|
||||
if recv_bytes(7 downto 0) = x"01" then
|
||||
command <= CMD8;
|
||||
-- Propose 2.7-3.6V operating voltage and a "10101010" test pattern
|
||||
argument <= x"000001aa";
|
||||
crc7 <= "1000011";
|
||||
return_state <= CHECK_CMD8;
|
||||
state <= WAIT_NRC;
|
||||
else
|
||||
state <= ERROR;
|
||||
end if;
|
||||
|
||||
-- CMD8: SEND_IF_COND -----------------------------------------------
|
||||
when CHECK_CMD8 =>
|
||||
argument <= (others => '0');
|
||||
crc7 <= (others => '0');
|
||||
if recv_bytes(39 downto 32) <= x"01" then
|
||||
-- This is an SD 2.x/3.x Card
|
||||
version <= SD2x;
|
||||
if recv_bytes(11 downto 8) /= "0001" or recv_bytes(7 downto 0) /= x"aa" then
|
||||
-- Operating voltage or pattern check failure
|
||||
state <= ERROR;
|
||||
else
|
||||
command <= CMD55;
|
||||
high_capacity <= true;
|
||||
return_state <= CHECK_CMD55;
|
||||
state <= WAIT_NRC;
|
||||
end if;
|
||||
else
|
||||
-- This is an MMC Card or an SD 1.x Card
|
||||
version <= SD1x;
|
||||
high_capacity <= false;
|
||||
command <= CMD55;
|
||||
return_state <= CHECK_CMD55;
|
||||
state <= WAIT_NRC;
|
||||
end if;
|
||||
|
||||
-- CMD55: APP_CMD ---------------------------------------------------
|
||||
when CHECK_CMD55 =>
|
||||
if recv_bytes(7 downto 0) = x"01" then
|
||||
-- This is an SD Card
|
||||
command <= ACMD41;
|
||||
if high_capacity then
|
||||
-- Ask for HCS (High Capacity Support)
|
||||
argument <= x"40000000";
|
||||
end if;
|
||||
return_state <= CHECK_ACMD41;
|
||||
state <= WAIT_NRC;
|
||||
else
|
||||
-- This is an MMC Card
|
||||
version <= MMC;
|
||||
command <= CMD1;
|
||||
return_state <= CHECK_CMD1;
|
||||
state <= WAIT_NRC;
|
||||
end if;
|
||||
|
||||
-- ACMD41: SEND_OP_CMD (SD Card) ------------------------------------
|
||||
when CHECK_ACMD41 =>
|
||||
if recv_bytes(7 downto 0) = x"00" then
|
||||
if version = SD2x then
|
||||
-- This is an SD 2.x/3.x Card, read OCR
|
||||
command <= CMD58;
|
||||
argument <= (others => '0');
|
||||
return_state <= CHECK_CMD58;
|
||||
state <= WAIT_NRC;
|
||||
else
|
||||
-- This is an SD 1.x Card, no HCS
|
||||
command <= CMD16;
|
||||
argument <= std_logic_vector(to_unsigned(BLOCK_SIZE, 32));
|
||||
return_state <= CHECK_SET_BLOCKLEN;
|
||||
state <= WAIT_NRC;
|
||||
end if;
|
||||
elsif recv_bytes(7 downto 0) = x"01" then
|
||||
-- Wait until the card goes out of idle state
|
||||
command <= CMD55;
|
||||
argument <= (others => '0');
|
||||
return_state <= CHECK_CMD55;
|
||||
state <= WAIT_NRC;
|
||||
else
|
||||
-- Found an MMC card that understands CMD55, but not ACMD41
|
||||
command <= CMD1;
|
||||
return_state <= CHECK_CMD1;
|
||||
state <= WAIT_NRC;
|
||||
end if;
|
||||
|
||||
-- CMD1: SEND_OP_CMD (MMC Card) -------------------------------------
|
||||
when CHECK_CMD1 =>
|
||||
if recv_bytes(7 downto 0) <= x"01" then
|
||||
command <= CMD16;
|
||||
argument <= std_logic_vector(to_unsigned(BLOCK_SIZE, 32));
|
||||
return_state <= CHECK_SET_BLOCKLEN;
|
||||
state <= WAIT_NRC;
|
||||
else
|
||||
-- Wait until the card goes out of idle state
|
||||
command <= CMD1;
|
||||
return_state <= CHECK_CMD1;
|
||||
state <= WAIT_NRC;
|
||||
end if;
|
||||
|
||||
-- CMD58: READ_OCR --------------------------------------------------
|
||||
when CHECK_CMD58 =>
|
||||
if recv_bytes(7 downto 0) = x"00" then
|
||||
if recv_bytes(30) = '1' then
|
||||
high_capacity <= true;
|
||||
else
|
||||
high_capacity <= false;
|
||||
end if;
|
||||
command <= CMD16;
|
||||
argument <= std_logic_vector(to_unsigned(BLOCK_SIZE, 32));
|
||||
return_state <= CHECK_SET_BLOCKLEN;
|
||||
state <= WAIT_NRC;
|
||||
else
|
||||
state <= ERROR;
|
||||
end if;
|
||||
|
||||
-- CMD16: SET_BLOCKLEN (BLOCK_SIZE) ---------------------------------
|
||||
when CHECK_SET_BLOCKLEN =>
|
||||
if recv_bytes(7 downto 0) = x"00" then
|
||||
slow_clk <= false;
|
||||
state <= IDLE;
|
||||
else
|
||||
state <= ERROR;
|
||||
end if;
|
||||
|
||||
-- Error state ------------------------------------------------------
|
||||
when ERROR =>
|
||||
sclk_sig <= '0';
|
||||
slow_clk <= true;
|
||||
CS_N <= '1';
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- Embedded "read track" FSM
|
||||
---------------------------------------------------------------------
|
||||
-- Idle state where we sit waiting for user image/track requests ----
|
||||
when IDLE =>
|
||||
if track /= current_track or image /= current_image then
|
||||
-- Compute the LBA (Logical Block Address) from the given
|
||||
-- image/track numbers.
|
||||
-- Each Apple ][ floppy image contains 35 tracks, each consisting of
|
||||
-- 16 x 256-byte sectors.
|
||||
-- However, because of inter-sector gaps and address fields in
|
||||
-- raw mode, the actual length is set to 0x1A00, so each image is
|
||||
-- actually $1A00 bytes * 0x23 tracks = 0x38E00 bytes.
|
||||
-- So: lba = image * 0x38E00 + track * 0x1A00
|
||||
-- In order to avoid multiplications by constants, we replace
|
||||
-- them by direct add/sub of shifted image/track values:
|
||||
-- 0x38E00 = 0011 1000 1110 0000 0000
|
||||
-- = 0x40000 - 0x8000 + 0x1000 - 0x200
|
||||
-- 0x01A00 = 0000 0001 1010 0000 0000
|
||||
-- = 0x1000 + 0x800 + 0x200
|
||||
lba := ("0000" & image & "000000000000000000") -
|
||||
( image & "000000000000000") +
|
||||
( image & "000000000000") -
|
||||
( image & "000000000") +
|
||||
( track & "000000000") +
|
||||
( track & "00000000000") +
|
||||
( track & "000000000000");
|
||||
if high_capacity then
|
||||
-- For SDHC, blocks are addressed by blocks, not bytes
|
||||
lba := lba srl BLOCK_BITS;
|
||||
end if;
|
||||
write_addr <= (others => '0');
|
||||
CS_N <= '0';
|
||||
state <= READ_TRACK;
|
||||
current_track <= track;
|
||||
current_image <= image;
|
||||
else
|
||||
CS_N <= '1';
|
||||
sclk_sig <= '1';
|
||||
end if;
|
||||
|
||||
-- Read in a whole track into buffer memory -------------------------
|
||||
when READ_TRACK =>
|
||||
if write_addr = TRACK_SIZE then
|
||||
state <= IDLE;
|
||||
else
|
||||
command <= CMD17;
|
||||
argument <= std_logic_vector(lba);
|
||||
return_state <= READ_BLOCK_WAIT;
|
||||
state <= WAIT_NRC;
|
||||
end if;
|
||||
|
||||
-- Wait for a 0 bit to signal the start of the block ----------------
|
||||
when READ_BLOCK_WAIT =>
|
||||
if sclk_sig = '1' and MISO = '0' then
|
||||
state <= READ_BLOCK_DATA;
|
||||
byte_counter := TO_UNSIGNED(BLOCK_SIZE - 1, BLOCK_BITS);
|
||||
counter := TO_UNSIGNED(7, 8);
|
||||
return_state <= READ_BLOCK_DATA;
|
||||
state <= RECEIVE_BYTE;
|
||||
end if;
|
||||
sclk_sig <= not sclk_sig;
|
||||
|
||||
-- Read a block of data ---------------------------------------------
|
||||
when READ_BLOCK_DATA =>
|
||||
ram_we <= '1';
|
||||
write_addr <= write_addr + 1;
|
||||
if byte_counter = 0 then
|
||||
counter := TO_UNSIGNED(7, 8);
|
||||
return_state <= READ_BLOCK_CRC;
|
||||
state <= RECEIVE_BYTE;
|
||||
else
|
||||
byte_counter := byte_counter - 1;
|
||||
counter := TO_UNSIGNED(7, 8);
|
||||
return_state <= READ_BLOCK_DATA;
|
||||
state <= RECEIVE_BYTE;
|
||||
end if;
|
||||
|
||||
-- Read the block CRC -----------------------------------------------
|
||||
when READ_BLOCK_CRC =>
|
||||
counter := TO_UNSIGNED(7, 8);
|
||||
return_state <= READ_TRACK;
|
||||
if high_capacity then
|
||||
lba := lba + 1;
|
||||
else
|
||||
lba := lba + BLOCK_SIZE;
|
||||
end if;
|
||||
state <= RECEIVE_BYTE;
|
||||
|
||||
---------------------------------------------------------------------
|
||||
-- Embedded "command" FSM
|
||||
---------------------------------------------------------------------
|
||||
-- Wait for card response in front of host command ------------------
|
||||
when WAIT_NRC =>
|
||||
counter := TO_UNSIGNED(63, 8);
|
||||
command_out <= "11111111" & "01" & command & argument & crc7 & "1";
|
||||
sclk_sig <= not sclk_sig;
|
||||
state <= SEND_CMD;
|
||||
|
||||
-- Send a command to the card ---------------------------------------
|
||||
when SEND_CMD =>
|
||||
if sclk_sig = '1' then
|
||||
if counter = 0 then
|
||||
state <= RECEIVE_BYTE_WAIT;
|
||||
else
|
||||
counter := counter - 1;
|
||||
command_out <= command_out(54 downto 0) & "1";
|
||||
end if;
|
||||
end if;
|
||||
sclk_sig <= not sclk_sig;
|
||||
|
||||
-- Wait for a "0", indicating the first bit of a response -----------
|
||||
when RECEIVE_BYTE_WAIT =>
|
||||
if sclk_sig = '1' then
|
||||
if MISO = '0' then
|
||||
recv_bytes <= (others => '0');
|
||||
if command = CMD8 or command = CMD58 then
|
||||
-- This is an R7 response, but we already have read bit 39
|
||||
counter := TO_UNSIGNED(38,8);
|
||||
else
|
||||
-- This is a data byte or an r1 response, but we already read
|
||||
-- bit 7
|
||||
counter := TO_UNSIGNED(6, 8);
|
||||
end if;
|
||||
state <= RECEIVE_BYTE;
|
||||
end if;
|
||||
end if;
|
||||
sclk_sig <= not sclk_sig;
|
||||
|
||||
-- Receive a byte ---------------------------------------------------
|
||||
when RECEIVE_BYTE =>
|
||||
if sclk_sig = '1' then
|
||||
recv_bytes <= recv_bytes(38 downto 0) & MISO;
|
||||
if counter = 0 then
|
||||
state <= return_state;
|
||||
ram_di <= recv_bytes(6 downto 0) & MISO;
|
||||
else
|
||||
counter := counter - 1;
|
||||
end if;
|
||||
end if;
|
||||
sclk_sig <= not sclk_sig;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
end process sd_fsm;
|
||||
|
||||
MOSI <= command_out(55);
|
||||
|
||||
end rtl;
|
||||
150
Apple - 2_MiST/rtl/timing_generator.vhd
Normal file
150
Apple - 2_MiST/rtl/timing_generator.vhd
Normal file
@@ -0,0 +1,150 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Apple ][ Timing logic
|
||||
--
|
||||
-- Stephen A. Edwards, sedwards@cs.columbia.edu
|
||||
--
|
||||
-- Taken more-or-less verbatim from the schematics in the
|
||||
-- Apple ][ reference manual
|
||||
--
|
||||
-- This takes a 14.31818 MHz master clock and divides it down to generate
|
||||
-- the various lower-frequency signals (e.g., 7M, phase 0, colorburst)
|
||||
-- as well as horizontal and vertical blanking and sync signals for the video
|
||||
-- and the video addresses.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity timing_generator is
|
||||
|
||||
port (
|
||||
CLK_14M : in std_logic; -- 14.31818 MHz master clock
|
||||
CLK_7M : buffer std_logic := '0';
|
||||
Q3 : buffer std_logic := '0'; -- 2 MHz signal in phase with PHI0
|
||||
RAS_N : buffer std_logic := '0';
|
||||
CAS_N : buffer std_logic := '0';
|
||||
AX : buffer std_logic := '0';
|
||||
PHI0 : buffer std_logic := '0'; -- 1.0 MHz processor clock
|
||||
PRE_PHI0 : buffer std_logic := '0'; -- One 14M cycle before
|
||||
COLOR_REF : buffer std_logic := '0'; -- 3.579545 MHz colorburst
|
||||
|
||||
TEXT_MODE : in std_logic;
|
||||
PAGE2 : in std_logic;
|
||||
HIRES : in std_logic;
|
||||
|
||||
VIDEO_ADDRESS : out unsigned(15 downto 0);
|
||||
H0 : out std_logic;
|
||||
VA : out std_logic; -- Character row address
|
||||
VB : out std_logic;
|
||||
VC : out std_logic;
|
||||
V2 : out std_logic;
|
||||
V4 : out std_logic;
|
||||
HBL : buffer std_logic; -- Horizontal blanking
|
||||
VBL : buffer std_logic; -- Vertical blanking
|
||||
BLANK : out std_logic; -- Composite blanking
|
||||
LDPS_N : out std_logic;
|
||||
LD194 : out std_logic
|
||||
);
|
||||
|
||||
end timing_generator;
|
||||
|
||||
architecture rtl of timing_generator is
|
||||
|
||||
signal H : unsigned(6 downto 0) := "0000000";
|
||||
signal V : unsigned(8 downto 0) := "011111010";
|
||||
signal COLOR_DELAY_N : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
-- To generate the once-a-line hiccup: D1 pin 6
|
||||
COLOR_DELAY_N <=
|
||||
not (not COLOR_REF and (not AX and not CAS_N) and PHI0 and not H(6));
|
||||
|
||||
-- The DRAM signal generator
|
||||
C2_74S195: process (CLK_14M)
|
||||
begin
|
||||
if rising_edge(CLK_14M) then
|
||||
if Q3 = '1' then -- shift
|
||||
(Q3, CAS_N, AX, RAS_N) <=
|
||||
unsigned'(CAS_N, AX, RAS_N, '0');
|
||||
else -- load
|
||||
(Q3, CAS_N, AX, RAS_N) <=
|
||||
unsigned'(RAS_N, AX, COLOR_DELAY_N, AX);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- The main clock signal generator
|
||||
B1_74S175 : process (CLK_14M)
|
||||
begin
|
||||
if rising_edge(CLK_14M) then
|
||||
COLOR_REF <= CLK_7M xor COLOR_REF;
|
||||
CLK_7M <= not CLK_7M;
|
||||
PHI0 <= PRE_PHI0;
|
||||
if AX = '1' then
|
||||
PRE_PHI0 <= not (Q3 xor PHI0); -- B1 pin 10
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
LDPS_N <= not (PHI0 and not AX and not CAS_N);
|
||||
LD194 <= not (PHI0 and not AX and not CAS_N and not CLK_7M);
|
||||
|
||||
-- Four four-bit presettable binary counters
|
||||
-- Seven-bit horizontal counter counts 0, 40, 41, ..., 7F (65 states)
|
||||
-- Nine-bit vertical counter counts $FA .. $1FF (262 states)
|
||||
D11D12D13D14_74LS161 : process (CLK_14M)
|
||||
begin
|
||||
if rising_edge(CLK_14M) then
|
||||
-- True the cycle before the rising edge of LDPS_N: emulates
|
||||
-- the effects of using LDPS_N as the clock for the video counters
|
||||
if (PHI0 and not AX and ((Q3 and RAS_N) or
|
||||
(not Q3 and COLOR_DELAY_N))) = '1' then
|
||||
if H(6) = '0' then H <= "1000000";
|
||||
else
|
||||
H <= H + 1;
|
||||
if H = "1111111" then
|
||||
V <= V + 1;
|
||||
if V = "111111111" then V <= "011111010"; end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
H0 <= H(0);
|
||||
VA <= V(0);
|
||||
VB <= V(1);
|
||||
VC <= V(2);
|
||||
V2 <= V(5);
|
||||
V4 <= V(7);
|
||||
|
||||
HBL <= not (H(5) or (H(3) and H(4)));
|
||||
VBL <= V(6) and V(7);
|
||||
|
||||
BLANK <= HBL or VBL;
|
||||
|
||||
-- V_SYNC <= VBL and V(5) and not V(4) and not V(3) and
|
||||
-- not V(2) and (H(4) or H(3) or H(5));
|
||||
-- H_SYNC <= HBL and H(3) and not H(2);
|
||||
|
||||
-- SYNC <= not (V_SYNC or H_SYNC);
|
||||
-- COLOR_BURST <= HBL and H(2) and H(3) and (COLOR_REF or TEXT_MODE);
|
||||
|
||||
-- Video address calculation
|
||||
VIDEO_ADDRESS(2 downto 0) <= H(2 downto 0);
|
||||
VIDEO_ADDRESS(6 downto 3) <= (not H(5) & V(6) & H(4) & H(3)) +
|
||||
( V(7) & not H(5) & V(7) & '1') +
|
||||
( "000" & V(6));
|
||||
VIDEO_ADDRESS(9 downto 7) <= V(5 downto 3);
|
||||
VIDEO_ADDRESS(14 downto 10) <=
|
||||
( "00" & HBL & PAGE2 & not PAGE2) when HIRES = '0' else
|
||||
(PAGE2 & not PAGE2 & V(2 downto 0));
|
||||
|
||||
VIDEO_ADDRESS(15) <= '0';
|
||||
|
||||
end rtl;
|
||||
291
Apple - 2_MiST/rtl/vga_controller.vhd
Normal file
291
Apple - 2_MiST/rtl/vga_controller.vhd
Normal file
@@ -0,0 +1,291 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- A VGA line-doubler for an Apple ][
|
||||
--
|
||||
-- Stephen A. Edwards, sedwards@cs.columbia.edu
|
||||
--
|
||||
--
|
||||
-- FIXME: This is all wrong
|
||||
--
|
||||
-- The Apple ][ uses a 14.31818 MHz master clock. It outputs a new
|
||||
-- horizontal line every 65 * 14 + 2 = 912 14M cycles. The extra two
|
||||
-- are from the "extended cycle" used to keep the 3.579545 MHz
|
||||
-- colorburst signal in sync. Of these, 40 * 14 = 560 are active video.
|
||||
--
|
||||
-- In graphics mode, the Apple effectively generates 140 four-bit pixels
|
||||
-- output serially (i.e., with 3.579545 MHz pixel clock). In text mode,
|
||||
-- it generates 280 one-bit pixels (i.e., with a 7.15909 MHz pixel clock).
|
||||
--
|
||||
-- We capture 140 four-bit nibbles for each line and interpret them in
|
||||
-- one of the two modes. In graphics mode, each is displayed as a
|
||||
-- single pixel of one of 16 colors. In text mode, each is displayed
|
||||
-- as two black or white pixels.
|
||||
--
|
||||
-- The VGA display is nominally 640 X 480, but we use a 14.31818 MHz
|
||||
-- dot clock. To stay in sync with the Apple, we generate a new line
|
||||
-- every 912 / 2 = 456 14M cycles= 31.8 us, a 31.4 kHz horizontal
|
||||
-- refresh rate. Of these, 280 will be active video.
|
||||
--
|
||||
-- One set of suggested VGA timings:
|
||||
--
|
||||
-- ______________________ ________
|
||||
-- ________| VIDEO |________| VIDEO
|
||||
-- |-C-|----------D-----------|-E-|
|
||||
-- __ ______________________________ ___________
|
||||
-- |_| |_|
|
||||
-- |B|
|
||||
-- |---------------A----------------|
|
||||
--
|
||||
-- A = 31.77 us Scanline time
|
||||
-- B = 3.77 us Horizontal sync time
|
||||
-- C = 1.89 us Back porch
|
||||
-- D = 25.17 us Active video
|
||||
-- E = 0.94 us Front porch
|
||||
--
|
||||
-- We use A = 456 / 14.31818 MHz = 31.84 us
|
||||
-- B = 54 / 14.31818 MHz = 3.77 us
|
||||
-- C = 106 / 14.31818 MHz = 7.40 us
|
||||
-- D = 280 / 14.31818 MHz = 19.56 us
|
||||
-- E = 16 / 14.31818 MHz = 1.12 us
|
||||
-------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity vga_controller is
|
||||
|
||||
port (
|
||||
CLK_28M : in std_logic; -- 14.31818 MHz master clock
|
||||
|
||||
VIDEO : in std_logic; -- from the Apple video generator
|
||||
COLOR_LINE : in std_logic;
|
||||
COLOR : in std_logic;
|
||||
HBL : in std_logic;
|
||||
VBL : in std_logic;
|
||||
LD194 : in std_logic;
|
||||
|
||||
VGA_CLK : out std_logic;
|
||||
VGA_HS : out std_logic; -- Active low
|
||||
VGA_VS : out std_logic; -- Active low
|
||||
VGA_BLANK : out std_logic;
|
||||
VGA_R : out unsigned(9 downto 0);
|
||||
VGA_G : out unsigned(9 downto 0);
|
||||
VGA_B : out unsigned(9 downto 0)
|
||||
);
|
||||
|
||||
end vga_controller;
|
||||
|
||||
architecture rtl of vga_controller is
|
||||
|
||||
-- Double-ported RAM (one read port, one write port)
|
||||
-- that holds two lines of 560 pixels
|
||||
type line_memory_t is array (0 to 2047) of std_logic;
|
||||
signal line_memory : line_memory_t;
|
||||
|
||||
-- RGB values from Linards Ticmanis,
|
||||
-- http://newsgroups.derkeiler.com/Archive/Comp/comp.sys.apple2/2005-09/msg00534.html
|
||||
|
||||
type basis_color is array(0 to 3) of unsigned(7 downto 0);
|
||||
constant basis_r : basis_color := ( X"88", X"38", X"07", X"38" );
|
||||
constant basis_g : basis_color := ( X"22", X"24", X"67", X"52" );
|
||||
constant basis_b : basis_color := ( X"2C", X"A0", X"2C", X"07" );
|
||||
|
||||
signal ram_write_addr : unsigned(10 downto 0);
|
||||
signal ram_we : std_logic;
|
||||
signal ram_read_addr : unsigned(10 downto 0);
|
||||
signal ram_data_out : std_logic;
|
||||
|
||||
signal shift_reg : unsigned(5 downto 0); -- Last six pixels
|
||||
|
||||
signal last_hbl : std_logic;
|
||||
signal hcount : unsigned(10 downto 0);
|
||||
signal hcount2 : unsigned(10 downto 0);
|
||||
signal vcount : unsigned(5 downto 0);
|
||||
signal even_line : std_logic;
|
||||
signal hactive, hactive_early2, hactive_early1 : std_logic;
|
||||
|
||||
constant VGA_SCANLINE : integer := 456*2; -- Must be 456*2 (set by the Apple)
|
||||
|
||||
constant VGA_HSYNC : integer := 54 * 2;
|
||||
constant VGA_BACK_PORCH : integer := 66 * 2;
|
||||
constant VGA_ACTIVE : integer := 282 * 2;
|
||||
constant VGA_FRONT_PORCH : integer := 54 * 2;
|
||||
|
||||
-- VGA_HSYNC + VGA_BACK_PORCH + VGA_ACTIVE + VGA_FRONT_PORCH = VGA_SCANLINE
|
||||
|
||||
constant VBL_TO_VSYNC : integer := 33;
|
||||
constant VGA_VSYNC_LINES : integer := 3;
|
||||
|
||||
signal VGA_VS_I, VGA_HS_I : std_logic;
|
||||
|
||||
signal video_active : std_logic;
|
||||
signal vbl_delayed, vbl_delayed2 : std_logic;
|
||||
signal hbl_delayed : std_logic;
|
||||
signal color_line_delayed_1, color_line_delayed_2 : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
delay_hbl : process (CLK_28M)
|
||||
begin
|
||||
if rising_edge(CLK_28M) then
|
||||
if LD194 = '0' then
|
||||
hbl_delayed <= HBL;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
hcount_vcount_control : process (CLK_28M)
|
||||
begin
|
||||
if rising_edge(CLK_28M) then
|
||||
if last_hbl = '1' and hbl_delayed = '0' then -- Falling edge
|
||||
color_line_delayed_2 <= color_line_delayed_1;
|
||||
color_line_delayed_1 <= COLOR;
|
||||
hcount <= (others => '0');
|
||||
vbl_delayed2 <= vbl_delayed;
|
||||
vbl_delayed <= VBL;
|
||||
if vbl_delayed = '1' then
|
||||
even_line <= '0';
|
||||
vcount <= vcount + 1;
|
||||
else
|
||||
vcount <= (others => '0');
|
||||
even_line <= not even_line;
|
||||
end if;
|
||||
else
|
||||
hcount <= hcount + 1;
|
||||
end if;
|
||||
last_hbl <= hbl_delayed;
|
||||
end if;
|
||||
end process hcount_vcount_control;
|
||||
|
||||
hsync_gen : process (CLK_28M)
|
||||
begin
|
||||
if rising_edge(CLK_28M) then
|
||||
if hcount = VGA_ACTIVE + VGA_FRONT_PORCH or
|
||||
hcount = VGA_SCANLINE + VGA_ACTIVE + VGA_FRONT_PORCH then
|
||||
VGA_HS_I <= '0';
|
||||
elsif hcount = VGA_ACTIVE + VGA_FRONT_PORCH + VGA_HSYNC or
|
||||
hcount = VGA_SCANLINE + VGA_ACTIVE + VGA_FRONT_PORCH + VGA_HSYNC then
|
||||
VGA_HS_I <= '1';
|
||||
end if;
|
||||
|
||||
hactive <= hactive_early1;
|
||||
hactive_early1 <= hactive_early2;
|
||||
|
||||
if hcount = VGA_SCANLINE - 1 or
|
||||
hcount = VGA_SCANLINE + VGA_SCANLINE - 1 then
|
||||
hactive_early2 <= '1';
|
||||
elsif hcount = VGA_ACTIVE or
|
||||
hcount = VGA_ACTIVE + VGA_SCANLINE then
|
||||
hactive_early2 <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process hsync_gen;
|
||||
|
||||
VGA_HS <= VGA_HS_I;
|
||||
|
||||
vsync_gen : process (CLK_28M)
|
||||
begin
|
||||
if rising_edge(CLK_28M) then
|
||||
if vcount = VBL_TO_VSYNC then
|
||||
VGA_VS_I <= '0';
|
||||
elsif vcount = VBL_TO_VSYNC + VGA_VSYNC_LINES then
|
||||
VGA_VS_I <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process vsync_gen;
|
||||
|
||||
VGA_VS <= VGA_VS_I;
|
||||
|
||||
hcount2 <= hcount - VGA_SCANLINE;
|
||||
|
||||
ram_read_addr <=
|
||||
even_line & hcount(9 downto 0) when hcount < VGA_SCANLINE else
|
||||
even_line & hcount2(9 downto 0);
|
||||
|
||||
shifter: process (CLK_28M)
|
||||
begin
|
||||
if rising_edge(CLK_28M) then
|
||||
shift_reg <= ram_data_out & shift_reg(5 downto 1);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
ram_write_addr <= (not even_line) & hcount(10 downto 1);
|
||||
ram_we <= '1' when hcount(0) = '1' else '0';
|
||||
|
||||
video_active <= hactive and not vbl_delayed2;
|
||||
|
||||
pixel_generator: process (CLK_28M)
|
||||
variable r, g, b : unsigned(7 downto 0);
|
||||
begin
|
||||
if rising_edge(CLK_28M) then
|
||||
r := X"00";
|
||||
g := X"00";
|
||||
b := X"00";
|
||||
if video_active = '1' then
|
||||
|
||||
if color_line_delayed_2 = '0' then -- Monochrome mode
|
||||
|
||||
if shift_reg(2) = '1' then
|
||||
r := X"FF"; g := X"FF"; b := X"FF";
|
||||
end if;
|
||||
|
||||
elsif shift_reg(0) = shift_reg(4) and shift_reg(5) = shift_reg(1) then
|
||||
|
||||
-- Tint of adjacent pixels is consistent : display the color
|
||||
|
||||
if shift_reg(1) = '1' then
|
||||
r := r + basis_r(to_integer(hcount + 1));
|
||||
g := g + basis_g(to_integer(hcount + 1));
|
||||
b := b + basis_b(to_integer(hcount + 1));
|
||||
end if;
|
||||
if shift_reg(2) = '1' then
|
||||
r := r + basis_r(to_integer(hcount + 2));
|
||||
g := g + basis_g(to_integer(hcount + 2));
|
||||
b := b + basis_b(to_integer(hcount + 2));
|
||||
end if;
|
||||
if shift_reg(3) = '1' then
|
||||
r := r + basis_r(to_integer(hcount + 3));
|
||||
g := g + basis_g(to_integer(hcount + 3));
|
||||
b := b + basis_b(to_integer(hcount + 3));
|
||||
end if;
|
||||
if shift_reg(4) = '1' then
|
||||
r := r + basis_r(to_integer(hcount));
|
||||
g := g + basis_g(to_integer(hcount));
|
||||
b := b + basis_b(to_integer(hcount));
|
||||
end if;
|
||||
else
|
||||
|
||||
-- Tint is changing: display only black, gray, or white
|
||||
|
||||
case shift_reg(3 downto 2) is
|
||||
when "11" => r := X"FF"; g := X"FF"; b := X"FF";
|
||||
when "01" | "10" => r := X"80"; g := X"80"; b := X"80";
|
||||
when others => r := X"00"; g := X"00"; b := X"00";
|
||||
end case;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
|
||||
VGA_R <= r & r(7 downto 6);
|
||||
VGA_G <= g & g(7 downto 6);
|
||||
VGA_B <= b & b(7 downto 6);
|
||||
|
||||
end if;
|
||||
end process pixel_generator;
|
||||
|
||||
-- The two-port RAM that stores the line data
|
||||
line_storage : process (CLK_28M)
|
||||
begin
|
||||
if rising_edge(CLK_28M) then
|
||||
if ram_we = '1' then
|
||||
line_memory(to_integer(ram_write_addr)) <= VIDEO;
|
||||
end if;
|
||||
ram_data_out <= line_memory(to_integer(ram_read_addr));
|
||||
end if;
|
||||
end process line_storage;
|
||||
|
||||
VGA_CLK <= CLK_28M;
|
||||
|
||||
VGA_BLANK <= video_active;
|
||||
|
||||
end rtl;
|
||||
221
Apple - 2_MiST/rtl/video_generator.vhd
Normal file
221
Apple - 2_MiST/rtl/video_generator.vhd
Normal file
@@ -0,0 +1,221 @@
|
||||
-------------------------------------------------------------------------------
|
||||
--
|
||||
-- Apple ][ Video Generation Logic
|
||||
--
|
||||
-- Stephen A. Edwards, sedwards@cs.columbia.edu
|
||||
--
|
||||
-- This takes data from memory and various mode switches to produce the
|
||||
-- serial one-bit video data stream.
|
||||
--
|
||||
-------------------------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity video_generator is
|
||||
|
||||
port (
|
||||
CLK_14M : in std_logic; -- 14.31818 MHz master clock
|
||||
CLK_7M : in std_logic;
|
||||
AX : in std_logic;
|
||||
CAS_N : in std_logic;
|
||||
TEXT_MODE : in std_logic;
|
||||
PAGE2 : in std_logic;
|
||||
HIRES_MODE : in std_logic;
|
||||
MIXED_MODE : in std_logic;
|
||||
H0 : in std_logic;
|
||||
VA : in std_logic;
|
||||
VB : in std_logic;
|
||||
VC : in std_logic;
|
||||
V2 : in std_logic;
|
||||
V4 : in std_logic;
|
||||
BLANK : in std_logic;
|
||||
DL : in unsigned(7 downto 0); -- Data from RAM
|
||||
LDPS_N : in std_logic;
|
||||
LD194 : in std_logic;
|
||||
FLASH_CLK : in std_logic; -- Low-frequency flashing text clock
|
||||
HIRES : out std_logic;
|
||||
VIDEO : out std_logic;
|
||||
COLOR_LINE : out std_logic
|
||||
);
|
||||
|
||||
end video_generator;
|
||||
|
||||
architecture rtl of video_generator is
|
||||
|
||||
signal char_rom_addr : unsigned(8 downto 0);
|
||||
signal char_rom_out : unsigned(4 downto 0);
|
||||
signal text_shiftreg : unsigned(5 downto 0);
|
||||
signal invert_character : std_logic;
|
||||
signal text_pixel : std_logic; -- B2 p11
|
||||
signal blank_delayed : std_logic;
|
||||
signal video_sig : std_logic; -- output of B10 p5
|
||||
signal graph_shiftreg : unsigned(7 downto 0);
|
||||
signal graphics_time_1, graphics_time_2,
|
||||
graphics_time_3 : std_logic; -- B5 p2, B8 p15, B8 p2
|
||||
signal lores_time : std_logic; -- A11 p6
|
||||
signal pixel_select : std_logic_vector(1 downto 0); -- A10 p14, A10 p15
|
||||
signal hires_delayed : std_logic; -- A11 p9
|
||||
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
--
|
||||
-- Text Mode Circuitry
|
||||
--
|
||||
-- The character ROM drives a parallel-to-serial shift register
|
||||
-- whose output is selectively inverted by inverted or flashing text
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
char_rom_addr <= DL(5 downto 0) & VC & VB & VA;
|
||||
|
||||
thecharrom : entity work.character_rom
|
||||
port map(
|
||||
addr => char_rom_addr,
|
||||
clk => CLK_14M, -- FIXME: a lower frequency?
|
||||
dout => char_rom_out
|
||||
);
|
||||
|
||||
-- Parallel-to-serial shifter for text mode
|
||||
-- The Apple actually used LDPS_N as the clock, not 14M; this is equivalent
|
||||
A3_74166: process (CLK_14M)
|
||||
begin
|
||||
if rising_edge(CLK_14M) then
|
||||
if CLK_7M = '0' then
|
||||
if LDPS_N = '0' then -- load
|
||||
text_shiftreg <= char_rom_out & "0";
|
||||
else -- shift
|
||||
text_shiftreg <= '0' & text_shiftreg(5 downto 1);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Latch and decoder for flashing/inverted text
|
||||
-- Comprises part of B11, B13, and A10
|
||||
flash_invert : process (CLK_14M)
|
||||
begin
|
||||
if rising_edge(CLK_14M) then
|
||||
if LD194 = '0' then
|
||||
invert_character <= not (DL(7) or (DL(6) and FLASH_CLK));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
text_pixel <= text_shiftreg(0) xor invert_character;
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
--
|
||||
-- Lores and Hires Mode Circuitry
|
||||
--
|
||||
-- An eight-bit shift register that either shifts (hires mode) or rotates
|
||||
-- the two nibbles (lores) followed by a mux that selects the video
|
||||
-- data from the text mode display, the hires shift register (possibly
|
||||
-- delayed by a 14M clock pulse), or one of the bits in the lores shift
|
||||
-- register.
|
||||
--
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
-- Original Apple clocked this shift register on the rising edge of RAS_N
|
||||
B5B8_74LS174 : process (CLK_14M)
|
||||
begin
|
||||
if rising_edge(CLK_14M) then
|
||||
if AX = '1' and CAS_N = '0' then
|
||||
graphics_time_3 <= graphics_time_2;
|
||||
graphics_time_2 <= graphics_time_1;
|
||||
graphics_time_1 <= not (TEXT_MODE or (V2 and V4 and MIXED_MODE));
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
COLOR_LINE <= graphics_time_1;
|
||||
|
||||
HIRES <= HIRES_MODE and graphics_time_3; -- to address generator
|
||||
|
||||
lores_time <= not HIRES_MODE and graphics_time_3;
|
||||
|
||||
A8A10_74LS194 : process (CLK_14M)
|
||||
begin
|
||||
if rising_edge(CLK_14M) then
|
||||
if LD194 = '0' then
|
||||
if lores_time = '1' then -- LORES mode
|
||||
pixel_select <= VC & H0;
|
||||
else -- HIRES mode
|
||||
pixel_select <= graphics_time_1 & DL(7);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Shift hires pixels by one 14M cycle to get orange and blue
|
||||
A11_74LS74 : process (CLK_14M)
|
||||
begin
|
||||
if rising_edge(CLK_14M) then
|
||||
hires_delayed <= graph_shiftreg(0);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- A pair of four-bit universal shift registers that either
|
||||
-- shift the whole byte (hires mode) or rotate the two nibbles (lores mode)
|
||||
B4B9_74LS194 : process (CLK_14M)
|
||||
begin
|
||||
if rising_edge(CLK_14M) then
|
||||
if LD194 = '0' then
|
||||
graph_shiftreg <= DL;
|
||||
else
|
||||
if lores_time = '1' then -- LORES configuration
|
||||
graph_shiftreg <= graph_shiftreg(4) & graph_shiftreg(7 downto 5) &
|
||||
graph_shiftreg(0) & graph_shiftreg(3 downto 1);
|
||||
else -- HIRES configuration
|
||||
if CLK_7M = '0' then
|
||||
graph_shiftreg <= graph_shiftreg(4) & graph_shiftreg(7 downto 1);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Synchronize BLANK to LD194
|
||||
A10_74LS194: process (CLK_14M)
|
||||
begin
|
||||
if rising_edge(CLK_14M) then
|
||||
if LD194 = '0' then
|
||||
blank_delayed <= BLANK;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Video output mux and flip-flop
|
||||
A9B10_74LS151 : process (CLK_14M)
|
||||
begin
|
||||
if rising_edge(CLK_14M) then
|
||||
if blank_delayed = '0' then
|
||||
if lores_time = '1' then -- LORES mode
|
||||
case pixel_select is
|
||||
when "00" => video_sig <= graph_shiftreg(0);
|
||||
when "01" => video_sig <= graph_shiftreg(2);
|
||||
when "10" => video_sig <= graph_shiftreg(4);
|
||||
when "11" => video_sig <= graph_shiftreg(6);
|
||||
when others => video_sig <= 'X';
|
||||
end case;
|
||||
else
|
||||
if pixel_select(1) = '0' then -- TEXT mode
|
||||
video_sig <= text_pixel;
|
||||
else -- HIRES mode
|
||||
if pixel_select(0) = '1' then
|
||||
video_sig <= hires_delayed;
|
||||
else
|
||||
video_sig <= graph_shiftreg(0);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
else
|
||||
video_sig <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
VIDEO <= video_sig;
|
||||
|
||||
end rtl;
|
||||
242
Apple - 2_MiST/rtl/video_mixer.sv
Normal file
242
Apple - 2_MiST/rtl/video_mixer.sv
Normal file
@@ -0,0 +1,242 @@
|
||||
//
|
||||
//
|
||||
// Copyright (c) 2017 Sorgelig
|
||||
//
|
||||
// This program is GPL Licensed. See COPYING for the full license.
|
||||
//
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
//
|
||||
// LINE_LENGTH: Length of display line in pixels
|
||||
// Usually it's length from HSync to HSync.
|
||||
// May be less if line_start is used.
|
||||
//
|
||||
// HALF_DEPTH: If =1 then color dept is 3 bits per component
|
||||
// For half depth 6 bits monochrome is available with
|
||||
// mono signal enabled and color = {G, R}
|
||||
|
||||
module video_mixer
|
||||
#(
|
||||
parameter LINE_LENGTH = 768,
|
||||
parameter HALF_DEPTH = 0,
|
||||
|
||||
parameter OSD_COLOR = 3'd4,
|
||||
parameter OSD_X_OFFSET = 10'd0,
|
||||
parameter OSD_Y_OFFSET = 10'd0
|
||||
)
|
||||
(
|
||||
// master clock
|
||||
// it should be multiple by (ce_pix*4).
|
||||
input clk_sys,
|
||||
|
||||
// Pixel clock or clock_enable (both are accepted).
|
||||
input ce_pix,
|
||||
|
||||
// Some systems have multiple resolutions.
|
||||
// ce_pix_actual should match ce_pix where every second or fourth pulse is enabled,
|
||||
// thus half or qurter resolutions can be used without brake video sync while switching resolutions.
|
||||
// For fixed single resolution (or when video sync stability isn't required) ce_pix_actual = ce_pix.
|
||||
input ce_pix_actual,
|
||||
|
||||
// OSD SPI interface
|
||||
input SPI_SCK,
|
||||
input SPI_SS3,
|
||||
input SPI_DI,
|
||||
|
||||
// scanlines (00-none 01-25% 10-50% 11-75%)
|
||||
input [1:0] scanlines,
|
||||
|
||||
// 0 = HVSync 31KHz, 1 = CSync 15KHz
|
||||
input scandoubler_disable,
|
||||
|
||||
// High quality 2x scaling
|
||||
input hq2x,
|
||||
|
||||
// YPbPr always uses composite sync
|
||||
input ypbpr,
|
||||
|
||||
// 0 = 16-240 range. 1 = 0-255 range. (only for YPbPr color space)
|
||||
input ypbpr_full,
|
||||
|
||||
// color
|
||||
input [DWIDTH:0] R,
|
||||
input [DWIDTH:0] G,
|
||||
input [DWIDTH:0] B,
|
||||
|
||||
// Monochrome mode (for HALF_DEPTH only)
|
||||
input mono,
|
||||
|
||||
// interlace sync. Positive pulses.
|
||||
input HSync,
|
||||
input VSync,
|
||||
|
||||
// Falling of this signal means start of informative part of line.
|
||||
// It can be horizontal blank signal.
|
||||
// This signal can be used to reduce amount of required FPGA RAM for HQ2x scan doubler
|
||||
// If FPGA RAM is not an issue, then simply set it to 0 for whole line processing.
|
||||
// Keep in mind: due to algo first and last pixels of line should be black to avoid side artefacts.
|
||||
// Thus, if blank signal is used to reduce the line, make sure to feed at least one black (or paper) pixel
|
||||
// before first informative pixel.
|
||||
input line_start,
|
||||
|
||||
// MiST video output signals
|
||||
output [5:0] VGA_R,
|
||||
output [5:0] VGA_G,
|
||||
output [5:0] VGA_B,
|
||||
output VGA_VS,
|
||||
output VGA_HS
|
||||
);
|
||||
|
||||
localparam DWIDTH = HALF_DEPTH ? 2 : 5;
|
||||
|
||||
wire [DWIDTH:0] R_sd;
|
||||
wire [DWIDTH:0] G_sd;
|
||||
wire [DWIDTH:0] B_sd;
|
||||
wire hs_sd, vs_sd;
|
||||
|
||||
scandoubler #(.LENGTH(LINE_LENGTH), .HALF_DEPTH(HALF_DEPTH)) scandoubler
|
||||
(
|
||||
.*,
|
||||
.hs_in(HSync),
|
||||
.vs_in(VSync),
|
||||
.r_in(R),
|
||||
.g_in(G),
|
||||
.b_in(B),
|
||||
|
||||
.hs_out(hs_sd),
|
||||
.vs_out(vs_sd),
|
||||
.r_out(R_sd),
|
||||
.g_out(G_sd),
|
||||
.b_out(B_sd)
|
||||
);
|
||||
|
||||
wire [DWIDTH:0] rt = (scandoubler_disable ? R : R_sd);
|
||||
wire [DWIDTH:0] gt = (scandoubler_disable ? G : G_sd);
|
||||
wire [DWIDTH:0] bt = (scandoubler_disable ? B : B_sd);
|
||||
|
||||
generate
|
||||
if(HALF_DEPTH) begin
|
||||
wire [5:0] r = mono ? {gt,rt} : {rt,rt};
|
||||
wire [5:0] g = mono ? {gt,rt} : {gt,gt};
|
||||
wire [5:0] b = mono ? {gt,rt} : {bt,bt};
|
||||
end else begin
|
||||
wire [5:0] r = rt;
|
||||
wire [5:0] g = gt;
|
||||
wire [5:0] b = bt;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
wire hs = (scandoubler_disable ? HSync : hs_sd);
|
||||
wire vs = (scandoubler_disable ? VSync : vs_sd);
|
||||
|
||||
reg scanline = 0;
|
||||
always @(posedge clk_sys) begin
|
||||
reg old_hs, old_vs;
|
||||
|
||||
old_hs <= hs;
|
||||
old_vs <= vs;
|
||||
|
||||
if(old_hs && ~hs) scanline <= ~scanline;
|
||||
if(old_vs && ~vs) scanline <= 0;
|
||||
end
|
||||
|
||||
wire [5:0] r_out, g_out, b_out;
|
||||
always @(*) begin
|
||||
case(scanlines & {scanline, scanline})
|
||||
1: begin // reduce 25% = 1/2 + 1/4
|
||||
r_out = {1'b0, r[5:1]} + {2'b00, r[5:2]};
|
||||
g_out = {1'b0, g[5:1]} + {2'b00, g[5:2]};
|
||||
b_out = {1'b0, b[5:1]} + {2'b00, b[5:2]};
|
||||
end
|
||||
|
||||
2: begin // reduce 50% = 1/2
|
||||
r_out = {1'b0, r[5:1]};
|
||||
g_out = {1'b0, g[5:1]};
|
||||
b_out = {1'b0, b[5:1]};
|
||||
end
|
||||
|
||||
3: begin // reduce 75% = 1/4
|
||||
r_out = {2'b00, r[5:2]};
|
||||
g_out = {2'b00, g[5:2]};
|
||||
b_out = {2'b00, b[5:2]};
|
||||
end
|
||||
|
||||
default: begin
|
||||
r_out = r;
|
||||
g_out = g;
|
||||
b_out = b;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
wire [5:0] red, green, blue;
|
||||
osd #(OSD_X_OFFSET, OSD_Y_OFFSET, OSD_COLOR) osd
|
||||
(
|
||||
.*,
|
||||
|
||||
.R_in(r_out),
|
||||
.G_in(g_out),
|
||||
.B_in(b_out),
|
||||
.HSync(hs),
|
||||
.VSync(vs),
|
||||
|
||||
.R_out(red),
|
||||
.G_out(green),
|
||||
.B_out(blue)
|
||||
);
|
||||
|
||||
wire [5:0] yuv_full[225] = '{
|
||||
6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1,
|
||||
6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4,
|
||||
6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6,
|
||||
6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8,
|
||||
6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11,
|
||||
6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13,
|
||||
6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15,
|
||||
6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17,
|
||||
6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20,
|
||||
6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22,
|
||||
6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24,
|
||||
6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27,
|
||||
6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29,
|
||||
6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31,
|
||||
6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33,
|
||||
6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36,
|
||||
6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38,
|
||||
6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40,
|
||||
6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42,
|
||||
6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45,
|
||||
6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47,
|
||||
6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49,
|
||||
6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52,
|
||||
6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54,
|
||||
6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56,
|
||||
6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58,
|
||||
6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61,
|
||||
6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63,
|
||||
6'd63
|
||||
};
|
||||
|
||||
// http://marsee101.blog19.fc2.com/blog-entry-2311.html
|
||||
// Y = 16 + 0.257*R + 0.504*G + 0.098*B (Y = 0.299*R + 0.587*G + 0.114*B)
|
||||
// Pb = 128 - 0.148*R - 0.291*G + 0.439*B (Pb = -0.169*R - 0.331*G + 0.500*B)
|
||||
// Pr = 128 + 0.439*R - 0.368*G - 0.071*B (Pr = 0.500*R - 0.419*G - 0.081*B)
|
||||
|
||||
wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0});
|
||||
wire [18:0] pb_8 = 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0});
|
||||
wire [18:0] pr_8 = 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0});
|
||||
|
||||
wire [7:0] y = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8];
|
||||
wire [7:0] pb = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8];
|
||||
wire [7:0] pr = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8];
|
||||
|
||||
assign VGA_R = ypbpr ? (ypbpr_full ? yuv_full[pr-8'd16] : pr[7:2]) : red;
|
||||
assign VGA_G = ypbpr ? (ypbpr_full ? yuv_full[y -8'd16] : y[7:2]) : green;
|
||||
assign VGA_B = ypbpr ? (ypbpr_full ? yuv_full[pb-8'd16] : pb[7:2]) : blue;
|
||||
assign VGA_VS = (scandoubler_disable | ypbpr) ? 1'b1 : ~vs_sd;
|
||||
assign VGA_HS = scandoubler_disable ? ~(HSync ^ VSync) : ypbpr ? ~(hs_sd ^ vs_sd) : ~hs_sd;
|
||||
|
||||
endmodule
|
||||
BIN
Apple - 2_MiST/snapshot/AppleII_MiST.rbf
Normal file
BIN
Apple - 2_MiST/snapshot/AppleII_MiST.rbf
Normal file
Binary file not shown.
Reference in New Issue
Block a user