├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── BUG_REPORT.yml │ └── QUESTION.yml ├── PULL_REQUEST_TEMPLATE.md └── workflows │ └── build-pocket.yml ├── .gitignore ├── AUTHORS ├── LICENSE ├── docs ├── CODE_OF_CONDUCT.md ├── Manual-Schematics │ ├── Green Beret [Operators Manual].pdf │ ├── Green Beret [Schematics] [English].pdf │ ├── gberet-pcb.png │ └── rushatck-pcb.png ├── Print │ ├── gberet-flyer-b.png │ ├── gberet-flyer.png │ ├── rushatck-flyer.png │ └── rushatck-marquee.png ├── README.md ├── gberet-logo.png └── git-social.jpg ├── gateware.json ├── modules ├── cpu-t80 │ ├── GBse.vhd │ ├── README.md │ ├── T16450.vhd │ ├── T80.vhd │ ├── T8080se.vhd │ ├── T80_ALU.vhd │ ├── T80_MCode.vhd │ ├── T80_Pack.vhd │ ├── T80_Reg.vhd │ ├── T80a.vhd │ ├── T80as.vhd │ ├── T80pa.vhd │ ├── T80s.vhd │ ├── T80se.vhd │ ├── T80sed.vhd │ ├── Z80.vhd │ └── index.qip ├── general-sync_fifo │ ├── index.qip │ └── sync_fifo.sv ├── pocket-dataloader │ ├── data_loader.sv │ ├── data_unloader.sv │ └── index.qip ├── pocket-i2s │ ├── index.qip │ └── pocket_i2s.sv ├── pocket-joypad │ ├── index.qip │ └── joypad.v ├── pocket-video │ ├── index.qip │ └── pocket_video.sv └── sound-sn76496 │ ├── SN76496.v │ └── index.qip ├── pkg ├── pocket │ ├── Assets │ │ └── gberet │ │ │ ├── boogermann.gberet │ │ │ ├── Green Beret.json │ │ │ ├── Mr. Goemon.json │ │ │ └── Rush'n Attack.json │ │ │ └── common │ │ │ └── .gitkeep │ ├── Cores │ │ └── boogermann.gberet │ │ │ ├── audio.json │ │ │ ├── core.json │ │ │ ├── data.json │ │ │ ├── icon.bin │ │ │ ├── icon.png │ │ │ ├── info.txt │ │ │ ├── input.json │ │ │ ├── interact.json │ │ │ ├── variants.json │ │ │ └── video.json │ ├── Platforms │ │ ├── _images │ │ │ ├── gberet.bin │ │ │ └── gberet.png │ │ └── gberet.json │ └── Presets │ │ └── boogermann.gberet │ │ └── Interact │ │ └── gberet │ │ └── boogermann.gberet │ │ ├── Green Beret.json │ │ ├── Mr. Goemon.json │ │ └── Rush'n Attack.json └── rom-recipes │ ├── Assets │ └── gberet │ │ └── common │ │ └── checklist.md5 │ ├── roms │ └── _PUT_YOUR_ROMS_HERE │ ├── tools │ ├── make_roms.ps1 │ └── make_roms.sh │ └── xml │ ├── Green Beret.mra │ ├── Mr. Goemon.mra │ └── Rush'n Attack (US).mra ├── platform └── pocket │ ├── apf.qip │ ├── apf_constraints.sdc │ ├── apf_top.v │ ├── build_cdf.tcl │ ├── build_id_gen.tcl │ ├── common.v │ ├── io_bridge_peripheral.v │ ├── io_pad_controller.v │ ├── mf_datatable.qip │ ├── mf_datatable.v │ ├── mf_ddio_bidir_12.qip │ ├── mf_ddio_bidir_12.v │ └── pocket.tcl ├── projects ├── gberet_pocket.qip ├── gberet_pocket.qpf ├── gberet_pocket.qsf └── gberet_pocket.sdc ├── rtl ├── DPRAM1024_4.qip ├── DPRAM1024_4.v ├── DPRAMs.v ├── GreenBeret.v ├── GreenBeret_MAIN.v ├── GreenBeret_SOUND.v ├── GreenBeret_VIDEO.v ├── HIDDEF.vh ├── HVGEN.v ├── ROMS.v └── gberet.qip └── target └── pocket ├── core.qip ├── core_bridge_cmd.v ├── core_constraints.sdc ├── core_top.sv ├── mf_pllbase.ppf ├── mf_pllbase.qip ├── mf_pllbase.v ├── mf_pllbase ├── mf_pllbase_0002.qip └── mf_pllbase_0002.v ├── pin_ddio_clk.ppf ├── pin_ddio_clk.qip ├── pin_ddio_clk.v └── stp1.stp /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ##################################################################### 2 | # SPDX-License-Identifier: CC0-1.0 3 | # SPDX-FileType: OTHER 4 | # SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors 5 | ##################################################################### 6 | custom: ["https://www.paypal.com/donate/?hosted_button_id=N7HXKEL8VJ9CN"] 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/BUG_REPORT.yml: -------------------------------------------------------------------------------- 1 | ##################################################################### 2 | # SPDX-License-Identifier: CC0-1.0 3 | # SPDX-FileType: OTHER 4 | # SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors 5 | ##################################################################### 6 | name: "Bug Report" 7 | description: "Let us know about an unexpected error, a crash, or an incorrect behavior." 8 | title: 'Title of your Bug Report' 9 | labels: 10 | - bug 11 | assignees: 12 | - boogermann 13 | body: 14 | - type: markdown 15 | attributes: 16 | value: | 17 | Hi there, 18 | 19 | Thank you for opening an issue. Please note that we try to keep the issue tracker reserved for bug reports. 20 | Make sure to [search for existing issues](https://github.com/opengateware/arcade-gberet/issues?q=label%3Abug) before filing a new one! 21 | 22 | - type: input 23 | id: version 24 | attributes: 25 | label: Version (or build number) 26 | placeholder: "1.0.0" 27 | description: | 28 | You can find the version in the about dialog. 29 | 30 | If you are not running the latest version, please try upgrading because your issue may have already been fixed. 31 | validations: 32 | required: true 33 | 34 | - type: textarea 35 | id: steps 36 | attributes: 37 | label: Steps to reproduce 38 | description: | 39 | Please list the full steps required to reproduce the issue 40 | placeholder: | 41 | - Be precise 42 | - Include exact data used during testing for easy reference 43 | - The steps have to be in the exact order 44 | - Mention pre-requisites when applicable 45 | validations: 46 | required: false 47 | 48 | - type: textarea 49 | id: expected_behavior 50 | attributes: 51 | label: Expected Behavior 52 | description: If you want to include screenshots, paste them into the markdown editor below or follow up with a separate comment. 53 | placeholder: What were you expecting? 54 | validations: 55 | required: false 56 | 57 | - type: textarea 58 | id: actual_behavior 59 | attributes: 60 | label: Actual Behavior 61 | placeholder: What happened instead? 62 | validations: 63 | required: true 64 | 65 | - type: textarea 66 | id: bug_context 67 | attributes: 68 | label: Additional Context 69 | description: | 70 | Are there anything atypical about your situation that we should know? 71 | validations: 72 | required: false 73 | 74 | - type: input 75 | id: bug_firmware 76 | attributes: 77 | label: Opened Issues and Pull Requests 78 | placeholder: "#1234" 79 | description: | 80 | Are there any other GitHub issues (open or closed) or Pull Requests that should be linked here? For example: #1234 81 | validations: 82 | required: false 83 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/QUESTION.yml: -------------------------------------------------------------------------------- 1 | ##################################################################### 2 | # SPDX-License-Identifier: CC0-1.0 3 | # SPDX-FileType: OTHER 4 | # SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors 5 | ##################################################################### 6 | name: "Question" 7 | description: "Ask a question about the project." 8 | title: 'Title of your Question' 9 | labels: 10 | - question 11 | assignees: 12 | - boogermann 13 | body: 14 | - type: markdown 15 | attributes: 16 | value: | 17 | Hi there, 18 | 19 | Please note that we try to keep the issue tracker reserved for bug reports. 20 | Make sure to [search for existing questions](https://github.com/opengateware/arcade-gberet/issues?q=label%3Aquestion) before filing a new one! 21 | 22 | - type: textarea 23 | id: question 24 | attributes: 25 | label: Ask a question about Green Beret Compatible Gateware IP Core 26 | placeholder: | 27 | Ask your question here! Please keep the questions related to the FPGA Core only. 28 | validations: 29 | required: true 30 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | ## What does this do / why do we need it? 8 | 9 | 14 | 15 | {Please write here} 16 | 17 | Fixes # (issue) 18 | 19 | ## Type of change 20 | 21 | 24 | 25 | - [ ] Bug fix (non-breaking change which fixes an issue) 26 | - [ ] New feature (non-breaking change which adds functionality) 27 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) 28 | - [ ] This change requires a documentation update 29 | - [ ] Coding style (indentation, etc) 30 | - [ ] {Please write custom change here} 31 | 32 | ## What should a reviewer look out for in this PR? 33 | 34 | 39 | 40 | {Please write here} 41 | 42 | ## Additional Comments (if any) 43 | 44 | {Please write here} 45 | -------------------------------------------------------------------------------- /.github/workflows/build-pocket.yml: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # SPDX-License-Identifier: CC0-1.0 3 | # SPDX-FileType: OTHER 4 | # SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors 5 | ################################################################################ 6 | name: Build/Release 7 | ################################################################################ 8 | # How to create a tag to launch the workflow 9 | # git tag -a "0.1.0" -m "Release v0.1.0" 10 | # git push origin --tags 11 | ################################################################################ 12 | on: 13 | push: 14 | tags: 15 | - "[0-9]+.[0-9]+.[0-9]+" 16 | ################################################################################ 17 | jobs: 18 | synthesis: 19 | runs-on: ubuntu-latest 20 | env: 21 | CORE: gberet 22 | DISPLAY_NAME: "Konami Green Beret" 23 | CATEGORY: arcade 24 | AUTHOR: boogermann 25 | TARGET: pocket 26 | STAGE_FOLDER: staging 27 | RELEASE_FOLDER: release 28 | RECIPE_FOLDER: rom-recipes 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | RAETRO_WEBHOOK: ${{ secrets.RAETRO_WEBHOOK }} 31 | FPGAGAMING_WEBHOOK: ${{ secrets.FPGAGAMING_WEBHOOK }} 32 | 33 | steps: 34 | - name: "🧰 Checkout Repository" 35 | uses: actions/checkout@v3 36 | 37 | - name: "🏗️ Compile Design" 38 | run: | 39 | docker run --rm -v ${{ github.workspace }}:/build raetro/quartus:pocket \ 40 | quartus_sh --flow compile projects/${CORE}_${TARGET}.qpf 41 | 42 | - name: "🟦 Staging Files for Release" 43 | if: startsWith(github.ref, 'refs/tags/') 44 | id: stage 45 | run: | 46 | ############################################################ 47 | # Create Tags 48 | ############################################################ 49 | VERSION=${GITHUB_REF#refs/*/} 50 | DATE=$(date +'%Y-%m-%d') 51 | CORE_FOLDER=${AUTHOR}.${CORE} 52 | RBF_FILE=${CORE}_${TARGET}.rbf 53 | echo ::set-output name=VERSION::${VERSION} 54 | echo ::set-output name=REPO::${CATEGORY}-${CORE} 55 | echo ::set-output name=TITLE::${DISPLAY_NAME} 56 | echo ::set-output name=RELEASE_FOLDER::${RELEASE_FOLDER} 57 | echo ::set-output name=RELEASE_FILE::${CORE_FOLDER}_${TARGET}-${VERSION}.zip 58 | echo ::set-output name=RECIPE_FILE::${CORE_FOLDER}_rom-recipes-${VERSION}.zip 59 | ############################################################ 60 | # Clear/Create Folders 61 | ############################################################ 62 | rm -rf ${STAGE_FOLDER} ${RELEASE_FOLDER} 63 | mkdir -p ${STAGE_FOLDER} ${RELEASE_FOLDER} 64 | ############################################################ 65 | # Copy Packaging Folder 66 | ############################################################ 67 | cp -R pkg/${TARGET}/* ${STAGE_FOLDER} 68 | ############################################################ 69 | # Clear git and png source files 70 | ############################################################ 71 | find ./${STAGE_FOLDER} -type f \( -name "*.png*" -o -name "*.gitkeep*" \) -delete; 72 | ############################################################ 73 | # Update core.json Version and Release Date 74 | ############################################################ 75 | sed -i -e "s/<%- VERSION %>/${VERSION}/g" -e "s/<%- RELEASE_DATE %>/${DATE}/g" ${STAGE_FOLDER}/Cores/${CORE_FOLDER}/core.json 76 | ############################################################ 77 | # Reverse Bitstream 78 | ############################################################ 79 | wget https://gist.githubusercontent.com/boogermann/fba1f59c87f9c8c9404cc68878b4eb1a/raw/7e93a3560902e0136dcb29fa6c41d06f06d78fb2/reverse_bits.c 80 | g++ reverse_bits.c -o reverse_bits 81 | ./reverse_bits projects/output_files/${RBF_FILE} ${STAGE_FOLDER}/Cores/${CORE_FOLDER}/bitstream.rbf_r 82 | 83 | - name: "📦 Create Distribution Files" 84 | if: startsWith(github.ref, 'refs/tags/') 85 | id: zip 86 | run: | 87 | pushd ./${STAGE_FOLDER} 88 | zip -r ../${RELEASE_FOLDER}/${{ steps.stage.outputs.RELEASE_FILE }} . 89 | popd 90 | pushd ./pkg/${RECIPE_FOLDER} 91 | zip -r ../../${RELEASE_FOLDER}/${{ steps.stage.outputs.RECIPE_FILE }} . 92 | popd 93 | 94 | - name: "🚀 Create a new GitHub Release" 95 | uses: softprops/action-gh-release@v0.1.14 96 | if: startsWith(github.ref, 'refs/tags/') 97 | with: 98 | name: Release v${{ steps.stage.outputs.VERSION }} 99 | files: | 100 | ${{ steps.stage.outputs.RELEASE_FOLDER }}/* 101 | 102 | - name: "📢 Send Discord Announcements" 103 | if: startsWith(github.ref, 'refs/tags/') 104 | run: | 105 | declare -a StringArray=("${RAETRO_WEBHOOK}" "${FPGAGAMING_WEBHOOK}") 106 | for webhook_url in ${StringArray[@]}; do 107 | curl \ 108 | -H "Content-Type: application/json" \ 109 | -d '{ 110 | "username": "OpenGateware", 111 | "avatar_url": "https://avatars.githubusercontent.com/u/112050328", 112 | "embeds": [{ 113 | "color": 2021216, 114 | "title": "A new core stable release is available for the Pocket", 115 | "thumbnail": { "url": "https://github.com/opengateware/${{ steps.stage.outputs.REPO }}/raw/master/docs/git-social.jpg" }, 116 | "fields": [ 117 | { "name": "Title", "value": "[${{ steps.stage.outputs.TITLE }}](https://github.com/opengateware/${{ steps.stage.outputs.REPO }}/)", "inline": true }, 118 | { "name": "Version", "value": "[${{ steps.stage.outputs.VERSION }}](https://github.com/opengateware/${{ steps.stage.outputs.REPO }}/releases/tag/${{ steps.stage.outputs.VERSION }})", "inline": true }, 119 | { "name": "Category", "value": "Arcade" }, 120 | { "name": "Developer", "value": "[Boogermann](https://github.com/boogermann)" }, 121 | { "name": "Download Core", "value": "[${{ steps.stage.outputs.RELEASE_FILE }}](https://github.com/opengateware/${{ steps.stage.outputs.REPO }}/releases/download/${{ steps.stage.outputs.VERSION }}/${{ steps.stage.outputs.RELEASE_FILE }})" }, 122 | { "name": "Download ROM Recipes", "value": "[${{ steps.stage.outputs.RECIPE_FILE }}](https://github.com/opengateware/${{ steps.stage.outputs.REPO }}/releases/download/${{ steps.stage.outputs.VERSION }}/${{ steps.stage.outputs.RECIPE_FILE }})" }, 123 | { "name": "Previous Releases", "value": "[https://github.com/opengateware/${{ steps.stage.outputs.REPO }}/releases](https://github.com/opengateware/${{ steps.stage.outputs.REPO }}/releases)" } 124 | ] 125 | }] 126 | }' \ 127 | $webhook_url 128 | done 129 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | db 2 | greybox_tmp 3 | hps_isw_handoff 4 | incremental_db 5 | output_files 6 | PLLJ_PLLSPE_INFO.txt 7 | simulation 8 | vip 9 | .qsys_edit 10 | *_netlist 11 | *_sim 12 | *.bak 13 | *.bsf 14 | *.cdf 15 | *.cmp 16 | *.csv 17 | *.done 18 | *.f 19 | *.pin 20 | *.pof 21 | *.ptf.* 22 | *.qar 23 | *.qarlog 24 | *.qdf 25 | *.qws 26 | *.rbf 27 | *.rbf_r 28 | *.rpt 29 | *.sip 30 | *.sld 31 | *.smsg 32 | *.sof 33 | *.sopc_builder 34 | *.sopcinfo 35 | *.spd 36 | *.summary 37 | *.txt 38 | *.xml 39 | *~ 40 | **/.DS_Store 41 | build_id.mif 42 | build_id.v 43 | c5_pin_model_dump.txt 44 | cr_ie_info.json 45 | # Gateman directories and files 46 | !.gateman/* 47 | !gateware.json 48 | !/pkg/* 49 | /pkg/**/*.rom 50 | /pkg/**/*.zip 51 | /staging/* 52 | /release/* 53 | # Editor directories and files 54 | .vscode/* 55 | !.vscode/extensions.json 56 | .idea 57 | *.suo 58 | *.ntvs* 59 | *.njsproj 60 | *.sln 61 | *.sw? 62 | 63 | # Pocket directories and files 64 | !info.txt 65 | 66 | # ROMS Checklist 67 | !checklist.sha1 68 | !checklist.md5 69 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | ##################################################################### 2 | # SPDX-License-Identifier: CC0-1.0 3 | # SPDX-FileType: OTHER 4 | # SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors 5 | ##################################################################### 6 | # Names should be added to this file as: 7 | # Name or Organization 8 | # 9 | # Core Team Members 10 | # Current project authors, maintainers and contributors. 11 | ##################################################################### 12 | Marcus Andrade 13 | 14 | ##################################################################### 15 | # Partial list of people who authored and/or contributed code in 16 | # other iterations or versions of the project. 17 | # 18 | # Thanks to all for their valuable 19 | # time/code/hints/fixes/discussions and contributions. 20 | ##################################################################### 21 | Alan Steremberg 22 | Kuba Winnicki 23 | Jim Gregory 24 | MiSTer-X -------------------------------------------------------------------------------- /docs/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code Of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as contributors and leaders pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level or type of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation. 6 | Note, however, that religion, political party, or other ideological affiliation provide no exemptions for the behavior we outline as unacceptable in this Code of Conduct. 7 | 8 | ## Our Standards 9 | 10 | We are committed to providing a friendly, safe and welcoming environment for all. 11 | 12 | Examples of behavior that contributes to creating a positive environment include: 13 | 14 | - Be kind and courteous to others 15 | - Using welcoming and inclusive language 16 | - Being respectful of differing viewpoints and experiences 17 | - Collaborating with other community members 18 | - Gracefully accepting constructive criticism 19 | - Focusing on what is best for the community 20 | - Showing empathy towards other community members 21 | 22 | Examples of unacceptable behavior by participants include: 23 | 24 | - The use of sexualized language or imagery and sexual attention or advances 25 | - The use of inappropriate images, including in a community member's avatar 26 | - The use of inappropriate language, including in a community member's nickname 27 | - Any spamming, flaming, baiting or other attention-stealing behavior 28 | - Excessive or unwelcome helping; answering outside the scope of the question asked 29 | - Trolling, insulting/derogatory comments, and personal or political attacks 30 | - Public or private harassment 31 | - Publishing others' private information, such as a physical or electronic address, without explicit permission 32 | - Other conduct which could reasonably be considered inappropriate 33 | 34 | The goal of the standards and moderation guidelines outlined here is to build and maintain a respectful community. We ask that you don’t just aim to be "technically unimpeachable", but rather try to be your best self. 35 | 36 | We value many things beyond technical expertise, including collaboration and supporting others within our community. Providing a positive experience for other community members can have a much more significant impact than simply providing the correct answer. 37 | 38 | ## Our Responsibilities 39 | 40 | Project leaders are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. 41 | 42 | Project leaders respect all people who contribute through reporting issues, posting feature requests, updating documentation, metadata, artwork, manuals, videos, submitting pull requests or patches, and other activities. But also have the right and responsibility to remove, edit, or reject messages, comments, commits, code, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any community member for other behaviors that they deem inappropriate, threatening, offensive, or harmful. 43 | 44 | ## Scope 45 | 46 | This Code of Conduct and the enforcement policies listed above apply to all Rætro Community venues. This includes but is not limited to any community spaces (both public and private), the entire Rætro Discord server, and all Rætro associated GitHub repositories. Examples of Rætro Community spaces include but are not limited to meet-ups, audio chats on the Rætro Discord, or interaction at a conference. 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. As a community member, you are representing our community, and are expected to behave accordingly. 49 | 50 | ## Enforcement 51 | 52 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at or contact [community@raetro.org][conduct-email]. 53 | All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. 54 | The project team is obligated to maintain confidentiality with regard to the reporter of an incident. 55 | Further details of specific enforcement policies may be posted separately. 56 | 57 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. 58 | 59 | ## Attribution 60 | 61 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html, and the Rust Code of Conduct, available at https://www.rust-lang.org/en-US/conduct.html and the Adafruit Community Code of Conduct, available at https://github.com/adafruit/Adafruit_Community_Code_of_Conduct. 62 | 63 | [homepage]: https://www.contributor-covenant.org 64 | [conduct-email]: mailto:community@raetro.org 65 | -------------------------------------------------------------------------------- /docs/Manual-Schematics/Green Beret [Operators Manual].pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/docs/Manual-Schematics/Green Beret [Operators Manual].pdf -------------------------------------------------------------------------------- /docs/Manual-Schematics/Green Beret [Schematics] [English].pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/docs/Manual-Schematics/Green Beret [Schematics] [English].pdf -------------------------------------------------------------------------------- /docs/Manual-Schematics/gberet-pcb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/docs/Manual-Schematics/gberet-pcb.png -------------------------------------------------------------------------------- /docs/Manual-Schematics/rushatck-pcb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/docs/Manual-Schematics/rushatck-pcb.png -------------------------------------------------------------------------------- /docs/Print/gberet-flyer-b.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/docs/Print/gberet-flyer-b.png -------------------------------------------------------------------------------- /docs/Print/gberet-flyer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/docs/Print/gberet-flyer.png -------------------------------------------------------------------------------- /docs/Print/rushatck-flyer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/docs/Print/rushatck-flyer.png -------------------------------------------------------------------------------- /docs/Print/rushatck-marquee.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/docs/Print/rushatck-marquee.png -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | [![Green Beret Logo](gberet-logo.png)](#) 2 | 3 | --- 4 | 5 | [![Active Development](https://img.shields.io/badge/Maintenance%20Level-Actively%20Developed-brightgreen.svg)](#status-of-features) 6 | [![Build](https://github.com/opengateware/arcade-gberet/actions/workflows/build-pocket.yml/badge.svg)](https://github.com/opengateware/arcade-gberet/actions/workflows/build-pocket.yml) 7 | [![release](https://img.shields.io/github/release/opengateware/arcade-gberet.svg)](https://github.com/opengateware/arcade-gberet/releases) 8 | [![license](https://img.shields.io/github/license/opengateware/arcade-gberet.svg?label=License&color=yellow)](#legal-notices) 9 | [![issues](https://img.shields.io/github/issues/opengateware/arcade-gberet.svg?label=Issues&color=red)](https://github.com/opengateware/arcade-gberet/issues) 10 | [![stars](https://img.shields.io/github/stars/opengateware/arcade-gberet.svg?label=Project%20Stars)](https://github.com/opengateware/arcade-gberet/stargazers) 11 | [![discord](https://img.shields.io/discord/676418475635507210.svg?logo=discord&logoColor=white&label=Discord&color=5865F2)](https://chat.raetro.org) 12 | [![Twitter Follow](https://img.shields.io/twitter/follow/marcusjordan?style=social)](https://twitter.com/marcusjordan) 13 | 14 | ## Konami [Green Beret] Compatible Gateware IP Core 15 | 16 | This Implementation of a compatible Green Beret arcade hardware in HDL is the work of [MiSTer-X]. 17 | 18 | > This game is known in US as "Rush'n Attack". 19 | 20 | ## Overview 21 | 22 | Green Beret is a sideways-scrolling action/platform game set during the Cold War, in which a US Special Forces Marine must infiltrate a Russian military base to save four POW's from being executed by firing squad. 23 | 24 | Initially, the soldier is armed with only a combat knife, but by killing the certain enemy troops, players can obtain either a three-shot flamethrower, a four-shot RPG, or a three-pack of hand grenades. 25 | 26 | ## Technical specifications 27 | 28 | - **Game ID:** GX577 29 | - **Main CPU:** Zilog Z80 @ 3.72 MHz 30 | - **Sound CPU:** SN76489A @ 1.536 MHz 31 | - **Resolution:** 240x224, 4096 colors 32 | - **Aspect Ratio:** 15:14 33 | - **Orientation:** Horizontal 34 | 35 | ## Compatible Platforms 36 | 37 | - Analogue Pocket 38 | 39 | ## Compatible Games 40 | 41 | > **ROMs NOT INCLUDED:** By using this gateware you agree to provide your own roms. 42 | 43 | | **Game** | Region | Status | 44 | | :------------------------------ | :----: | :----: | 45 | | Green Beret | JPN | ✅ | 46 | | Rush'n Attack | USA | ✅ | 47 | | Mr. Goemon | JPN | ✅ | 48 | 49 | ### ROM Instructions 50 | 51 | 1. Download and Install [ORCA](https://github.com/opengateware/tools-orca/releases/latest) (Open ROM Conversion Assistant) 52 | 2. Download the [ROM Recipes](https://github.com/opengateware/arcade-gberet/releases/latest) and extract to your computer. 53 | 3. Copy the required MAME `.zip` file(s) into the `roms` folder. 54 | 4. Inside the `tools` folder execute the script related to your system. 55 | 1. **Windows:** right click `make_roms.ps1` and select `Run with Powershell`. 56 | 2. **Linux and MacOS:** run script `make_roms.sh`. 57 | 5. After the conversion is completed, copy the `Assets` folder to the Root of your SD Card. 58 | 6. **Optional:** an `.md5` file is included to verify if the hash of the ROMs are valid. (eg: `md5sum -c checklist.md5`) 59 | 60 | > **Note:** Make sure your `.rom` files are in the `Assets/gberet/common` directory. 61 | 62 | ## Status of Features 63 | 64 | > **WARNING**: This repository is in active development. There are no guarantees about stability. Breaking changes might occur until a stable release is made and announced. 65 | 66 | - [x] Dip Switches 67 | - [x] Pause 68 | - [ ] Hi-Score Save 69 | 70 | ## Credits and acknowledgment 71 | 72 | - [Alan Steremberg](https://github.com/alanswx) 73 | - [Daniel Wallner](https://opencores.org/projects/t80) 74 | - [Jim Gregory](https://github.com/JimmyStones) 75 | - [Kuba Winnicki](https://github.com/blackwine) 76 | - [MiSTer-X] 77 | - [Murray Aickin](https://github.com/Mazamars312) 78 | 79 | ## Powered by Open-Source Software 80 | 81 | This project borrowed and use code from several other projects. A great thanks to their efforts! 82 | 83 | | Modules | Copyright/Developer | 84 | | :----------------------------- | :---------------------- | 85 | | [Green Beret RTL] | 2013 (c) MiSTer-X | 86 | | [Data Loader] | 2022 (c) Adam Gastineau | 87 | | [T80] | 2001 (c) Daniel Wallner | 88 | 89 | ## Legal Notices 90 | 91 | Green Beret, Rush'n Attack © 1985 Konami. Mr. Goemon © 1986 Konami. All rights reserved. 92 | All other trademarks, logos, and copyrights are property of their respective owners. 93 | 94 | The authors and contributors or any of its maintainers are in no way associated with or endorsed by Konami. 95 | 96 | [Green Beret]: https://en.wikipedia.org/wiki/Rush%27n_Attack 97 | [Data Loader]: https://github.com/agg23/analogue-pocket-utils 98 | [Green Beret RTL]: https://github.com/MiSTer-devel/Arcade-RushnAttack_MiSTer/tree/master/rtl 99 | [T80]: https://opencores.org/projects/t80 100 | 101 | [MiSTer-X]: https://github.com/MrX-8B 102 | -------------------------------------------------------------------------------- /docs/gberet-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/docs/gberet-logo.png -------------------------------------------------------------------------------- /docs/git-social.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/docs/git-social.jpg -------------------------------------------------------------------------------- /gateware.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gberet", 3 | "displayName": "gberet", 4 | "description": "Green Beret/Rush n' Attack Compatible Gateware IP Core for FPGA", 5 | "author": "boogermann", 6 | "version": "0.1.0", 7 | "license": "GPL-3.0-or-later", 8 | "repository": "https://github.com/opengateware/arcade-gberet", 9 | "keywords": [ 10 | "ecosystem:gateman" 11 | ], 12 | "scripts": { 13 | "verilator": "echo \"Error: no simulation specified\" && exit 1" 14 | }, 15 | "hardware": { 16 | "id": "green-beret", 17 | "name": "Green Beret", 18 | "year": 1985, 19 | "manufacturer": "Konami" 20 | }, 21 | "platforms": { 22 | "pocket": "1.1.0" 23 | }, 24 | "modules": { 25 | "cpu-t80": "3.5.1", 26 | "general-sync_fifo": "0.1.0", 27 | "pocket-dataloader": "1.0.0", 28 | "pocket-i2s": "1.0.0", 29 | "pocket-joypad": "1.0.0", 30 | "pocket-video": "1.0.0", 31 | "sound-sn76496": "0.1.0" 32 | } 33 | } -------------------------------------------------------------------------------- /modules/cpu-t80/GBse.vhd: -------------------------------------------------------------------------------- 1 | -- **** 2 | -- T80(b) core. In an effort to merge and maintain bug fixes .... 3 | -- 4 | -- 5 | -- Ver 300 started tidyup 6 | -- MikeJ March 2005 7 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) 8 | -- 9 | -- **** 10 | -- 11 | -- Z80 compatible microprocessor core, synchronous top level with clock enable 12 | -- Different timing than the original z80 13 | -- Inputs needs to be synchronous and outputs may glitch 14 | -- 15 | -- Version : 0240 16 | -- 17 | -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) 18 | -- 19 | -- All rights reserved 20 | -- 21 | -- Redistribution and use in source and synthezised forms, with or without 22 | -- modification, are permitted provided that the following conditions are met: 23 | -- 24 | -- Redistributions of source code must retain the above copyright notice, 25 | -- this list of conditions and the following disclaimer. 26 | -- 27 | -- Redistributions in synthesized form must reproduce the above copyright 28 | -- notice, this list of conditions and the following disclaimer in the 29 | -- documentation and/or other materials provided with the distribution. 30 | -- 31 | -- Neither the name of the author nor the names of other contributors may 32 | -- be used to endorse or promote products derived from this software without 33 | -- specific prior written permission. 34 | -- 35 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 36 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 37 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 39 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 40 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 41 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 42 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 43 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 44 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 45 | -- POSSIBILITY OF SUCH DAMAGE. 46 | -- 47 | -- Please report bugs to the author, but before you do so, please 48 | -- make sure that this is not a derivative work and that 49 | -- you have the latest version of this file. 50 | -- 51 | -- The latest version of this file can be found at: 52 | -- http://www.opencores.org/cvsweb.shtml/t80/ 53 | -- 54 | -- Limitations : 55 | -- 56 | -- File history : 57 | -- 58 | -- 0235 : First release 59 | -- 60 | -- 0236 : Added T2Write generic 61 | -- 62 | -- 0237 : Fixed T2Write with wait state 63 | -- 64 | -- 0238 : Updated for T80 interface change 65 | -- 66 | -- 0240 : Updated for T80 interface change 67 | -- 68 | -- 0242 : Updated for T80 interface change 69 | -- 70 | library IEEE; 71 | use IEEE.std_logic_1164.all; 72 | use IEEE.numeric_std.all; 73 | use work.T80_Pack.all; 74 | 75 | entity GBse is 76 | generic( 77 | T2Write : integer := 1; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 78 | IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle 79 | ); 80 | port( 81 | RESET_n : in std_logic; 82 | CLK_n : in std_logic; 83 | CLKEN : in std_logic; 84 | WAIT_n : in std_logic; 85 | INT_n : in std_logic; 86 | NMI_n : in std_logic; 87 | BUSRQ_n : in std_logic; 88 | M1_n : out std_logic; 89 | MREQ_n : out std_logic; 90 | IORQ_n : out std_logic; 91 | RD_n : out std_logic; 92 | WR_n : out std_logic; 93 | RFSH_n : out std_logic; 94 | HALT_n : out std_logic; 95 | BUSAK_n : out std_logic; 96 | STOP : out std_logic; 97 | A : out std_logic_vector(15 downto 0); 98 | DI : in std_logic_vector(7 downto 0); 99 | DO : out std_logic_vector(7 downto 0) 100 | ); 101 | end GBse; 102 | 103 | architecture rtl of GBse is 104 | 105 | signal IntCycle_n : std_logic; 106 | signal NoRead : std_logic; 107 | signal Write : std_logic; 108 | signal IORQ : std_logic; 109 | signal DI_Reg : std_logic_vector(7 downto 0); 110 | signal MCycle : std_logic_vector(2 downto 0); 111 | signal TState : std_logic_vector(2 downto 0); 112 | 113 | begin 114 | 115 | u0 : T80 116 | generic map( 117 | Mode => 3, 118 | IOWait => IOWait, 119 | Flag_S => 0, 120 | Flag_P => 0, 121 | Flag_X => 0, 122 | Flag_Y => 0, 123 | Flag_C => 4, 124 | Flag_H => 5, 125 | Flag_N => 6, 126 | Flag_Z => 7 127 | ) 128 | port map( 129 | CEN => CLKEN, 130 | M1_n => M1_n, 131 | IORQ => IORQ, 132 | NoRead => NoRead, 133 | Write => Write, 134 | RFSH_n => RFSH_n, 135 | HALT_n => HALT_n, 136 | Stop => STOP, 137 | WAIT_n => Wait_n, 138 | INT_n => INT_n, 139 | NMI_n => NMI_n, 140 | RESET_n => RESET_n, 141 | BUSRQ_n => BUSRQ_n, 142 | BUSAK_n => BUSAK_n, 143 | CLK_n => CLK_n, 144 | A => A, 145 | DInst => DI, 146 | DI => DI_Reg, 147 | DO => DO, 148 | MC => MCycle, 149 | TS => TState, 150 | IntCycle_n => IntCycle_n); 151 | 152 | process (RESET_n, CLK_n) 153 | begin 154 | if RESET_n = '0' then 155 | RD_n <= '1'; 156 | WR_n <= '1'; 157 | IORQ_n <= '1'; 158 | MREQ_n <= '1'; 159 | DI_Reg <= "00000000"; 160 | elsif CLK_n'event and CLK_n = '1' then 161 | if CLKEN = '1' then 162 | RD_n <= '1'; 163 | WR_n <= '1'; 164 | IORQ_n <= '1'; 165 | MREQ_n <= '1'; 166 | if MCycle = "001" then 167 | if TState = "001" or (TState = "010" and Wait_n = '0') then 168 | RD_n <= not IntCycle_n; 169 | MREQ_n <= not IntCycle_n; 170 | end if; 171 | if TState = "011" then 172 | MREQ_n <= '0'; 173 | end if; 174 | elsif MCycle = "011" and IntCycle_n = '0' then 175 | if TState = "001" then 176 | IORQ_n <= '0'; -- Acknowledge IRQ 177 | end if; 178 | else 179 | if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then 180 | RD_n <= '0'; 181 | IORQ_n <= not IORQ; 182 | MREQ_n <= IORQ; 183 | end if; 184 | if T2Write = 0 then 185 | if TState = "010" and Write = '1' then 186 | WR_n <= '0'; 187 | IORQ_n <= not IORQ; 188 | MREQ_n <= IORQ; 189 | end if; 190 | else 191 | if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then 192 | WR_n <= '0'; 193 | IORQ_n <= not IORQ; 194 | MREQ_n <= IORQ; 195 | end if; 196 | end if; 197 | end if; 198 | if TState = "010" and Wait_n = '1' then 199 | DI_Reg <= DI; 200 | end if; 201 | end if; 202 | end if; 203 | end process; 204 | 205 | end; 206 | -------------------------------------------------------------------------------- /modules/cpu-t80/README.md: -------------------------------------------------------------------------------- 1 | # T80 a Z80 Compatible Microprocessor Gateware IP Core 2 | 3 | Attempt to finish all undocumented features and provide accurate timings. 4 | 5 | ## Changelog 6 | 7 | - 3.5.1 8 | - Merged Gameboy fixes from Bruno Duarte Gouveia (brNX) 9 | - Passes Blargg's test ROMs 10 | - 3.5.0 11 | - Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr 12 | - (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as correct implementation is still unclear. 13 | - 3.0.3 14 | - Add undocumented DDCB and FDCB opcodes by TobiFlex 20.04.2010 15 | - 3.0.1 16 | - Parity flag is just parity for 8080, also overflow for Z80, by Sean Riddle 17 | - 3.0.0 18 | - Started tidyup 19 | - 2.5.0 20 | - Unknown History before this point 21 | 22 | Contributors: 23 | 24 | ```txt 25 | Copyright (c) 2021 Bruno Duarte Gouveia 26 | Copyright (c) 2018 Sorgelig 27 | Copyright (c) 2010 TobiFlex 28 | Copyright (c) 20xx Sean Riddle 29 | Copyright (c) 2005 MikeJ 30 | ``` 31 | 32 | ```txt 33 | Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) 34 | All rights reserved. 35 | 36 | Redistributions in synthesized form must reproduce the above copyright 37 | notice, this list of conditions and the following disclaimer in the 38 | documentation and/or other materials provided with the distribution. 39 | 40 | Neither the name of the author nor the names of other contributors may 41 | be used to endorse or promote products derived from this software without 42 | specific prior written permission. 43 | 44 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 45 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 46 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 47 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 48 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 49 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 50 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 51 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 52 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 53 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 54 | POSSIBILITY OF SUCH DAMAGE. 55 | ``` 56 | -------------------------------------------------------------------------------- /modules/cpu-t80/T8080se.vhd: -------------------------------------------------------------------------------- 1 | -- **** 2 | -- T80(b) core. In an effort to merge and maintain bug fixes .... 3 | -- 4 | -- 5 | -- Ver 300 started tidyup 6 | -- MikeJ March 2005 7 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) 8 | -- 9 | -- **** 10 | -- 11 | -- 8080 compatible microprocessor core, synchronous top level with clock enable 12 | -- Different timing than the original 8080 13 | -- Inputs needs to be synchronous and outputs may glitch 14 | -- 15 | -- Version : 0242 16 | -- 17 | -- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) 18 | -- 19 | -- All rights reserved 20 | -- 21 | -- Redistribution and use in source and synthezised forms, with or without 22 | -- modification, are permitted provided that the following conditions are met: 23 | -- 24 | -- Redistributions of source code must retain the above copyright notice, 25 | -- this list of conditions and the following disclaimer. 26 | -- 27 | -- Redistributions in synthesized form must reproduce the above copyright 28 | -- notice, this list of conditions and the following disclaimer in the 29 | -- documentation and/or other materials provided with the distribution. 30 | -- 31 | -- Neither the name of the author nor the names of other contributors may 32 | -- be used to endorse or promote products derived from this software without 33 | -- specific prior written permission. 34 | -- 35 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 36 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 37 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 39 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 40 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 41 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 42 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 43 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 44 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 45 | -- POSSIBILITY OF SUCH DAMAGE. 46 | -- 47 | -- Please report bugs to the author, but before you do so, please 48 | -- make sure that this is not a derivative work and that 49 | -- you have the latest version of this file. 50 | -- 51 | -- The latest version of this file can be found at: 52 | -- http://www.opencores.org/cvsweb.shtml/t80/ 53 | -- 54 | -- Limitations : 55 | -- STACK status output not supported 56 | -- 57 | -- File history : 58 | -- 59 | -- 0237 : First version 60 | -- 61 | -- 0238 : Updated for T80 interface change 62 | -- 63 | -- 0240 : Updated for T80 interface change 64 | -- 65 | -- 0242 : Updated for T80 interface change 66 | -- 67 | 68 | library IEEE; 69 | use IEEE.std_logic_1164.all; 70 | use IEEE.numeric_std.all; 71 | use work.T80_Pack.all; 72 | 73 | entity T8080se is 74 | generic( 75 | Mode : integer := 2; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB 76 | T2Write : integer := 0 -- 0 => WR_n active in T3, /=0 => WR_n active in T2 77 | ); 78 | port( 79 | RESET_n : in std_logic; 80 | CLK : in std_logic; 81 | CLKEN : in std_logic; 82 | READY : in std_logic; 83 | HOLD : in std_logic; 84 | INT : in std_logic; 85 | INTE : out std_logic; 86 | DBIN : out std_logic; 87 | SYNC : out std_logic; 88 | VAIT : out std_logic; 89 | HLDA : out std_logic; 90 | WR_n : out std_logic; 91 | A : out std_logic_vector(15 downto 0); 92 | DI : in std_logic_vector(7 downto 0); 93 | DO : out std_logic_vector(7 downto 0) 94 | ); 95 | end T8080se; 96 | 97 | architecture rtl of T8080se is 98 | 99 | signal IntCycle_n : std_logic; 100 | signal NoRead : std_logic; 101 | signal Write : std_logic; 102 | signal IORQ : std_logic; 103 | signal INT_n : std_logic; 104 | signal HALT_n : std_logic; 105 | signal BUSRQ_n : std_logic; 106 | signal BUSAK_n : std_logic; 107 | signal DO_i : std_logic_vector(7 downto 0); 108 | signal DI_Reg : std_logic_vector(7 downto 0); 109 | signal MCycle : std_logic_vector(2 downto 0); 110 | signal TState : std_logic_vector(2 downto 0); 111 | signal One : std_logic; 112 | 113 | begin 114 | 115 | INT_n <= not INT; 116 | BUSRQ_n <= HOLD; 117 | HLDA <= not BUSAK_n; 118 | SYNC <= '1' when TState = "001" else '0'; 119 | VAIT <= '1' when TState = "010" else '0'; 120 | One <= '1'; 121 | 122 | DO(0) <= not IntCycle_n when TState = "001" else DO_i(0); -- INTA 123 | DO(1) <= Write when TState = "001" else DO_i(1); -- WO_n 124 | DO(2) <= DO_i(2); -- STACK not supported !!!!!!!!!! 125 | DO(3) <= not HALT_n when TState = "001" else DO_i(3); -- HLTA 126 | DO(4) <= IORQ and Write when TState = "001" else DO_i(4); -- OUT 127 | DO(5) <= DO_i(5) when TState /= "001" else '1' when MCycle = "001" else '0'; -- M1 128 | DO(6) <= IORQ and not Write when TState = "001" else DO_i(6); -- INP 129 | DO(7) <= not IORQ and not Write and IntCycle_n when TState = "001" else DO_i(7); -- MEMR 130 | 131 | u0 : T80 132 | generic map( 133 | Mode => Mode, 134 | IOWait => 0) 135 | port map( 136 | CEN => CLKEN, 137 | M1_n => open, 138 | IORQ => IORQ, 139 | NoRead => NoRead, 140 | Write => Write, 141 | RFSH_n => open, 142 | HALT_n => HALT_n, 143 | WAIT_n => READY, 144 | INT_n => INT_n, 145 | NMI_n => One, 146 | RESET_n => RESET_n, 147 | BUSRQ_n => One, 148 | BUSAK_n => BUSAK_n, 149 | CLK_n => CLK, 150 | A => A, 151 | DInst => DI, 152 | DI => DI_Reg, 153 | DO => DO_i, 154 | MC => MCycle, 155 | TS => TState, 156 | IntCycle_n => IntCycle_n, 157 | IntE => INTE); 158 | 159 | process (RESET_n, CLK) 160 | begin 161 | if RESET_n = '0' then 162 | DBIN <= '0'; 163 | WR_n <= '1'; 164 | DI_Reg <= "00000000"; 165 | elsif CLK'event and CLK = '1' then 166 | if CLKEN = '1' then 167 | DBIN <= '0'; 168 | WR_n <= '1'; 169 | if MCycle = "001" then 170 | if TState = "001" or (TState = "010" and READY = '0') then 171 | DBIN <= IntCycle_n; 172 | end if; 173 | else 174 | if (TState = "001" or (TState = "010" and READY = '0')) and NoRead = '0' and Write = '0' then 175 | DBIN <= '1'; 176 | end if; 177 | if T2Write = 0 then 178 | if TState = "010" and Write = '1' then 179 | WR_n <= '0'; 180 | end if; 181 | else 182 | if (TState = "001" or (TState = "010" and READY = '0')) and Write = '1' then 183 | WR_n <= '0'; 184 | end if; 185 | end if; 186 | end if; 187 | if TState = "010" and READY = '1' then 188 | DI_Reg <= DI; 189 | end if; 190 | end if; 191 | end if; 192 | end process; 193 | 194 | end; 195 | -------------------------------------------------------------------------------- /modules/cpu-t80/T80_Reg.vhd: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- 2 | -- **** 3 | -- T80(c) core. Attempt to finish all undocumented features and provide 4 | -- accurate timings. 5 | -- Version 350. 6 | -- Copyright (c) 2018 Sorgelig 7 | -- Test passed: ZEXDOC, ZEXALL, Z80Full(*), Z80memptr 8 | -- (*) Currently only SCF and CCF instructions aren't passed X/Y flags check as 9 | -- correct implementation is still unclear. 10 | -- 11 | -- **** 12 | -- T80(b) core. In an effort to merge and maintain bug fixes .... 13 | -- 14 | -- 15 | -- Ver 300 started tidyup 16 | -- MikeJ March 2005 17 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) 18 | -- 19 | -- **** 20 | -- 21 | -- T80 Registers, technology independent 22 | -- 23 | -- Version : 0244 24 | -- 25 | -- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org) 26 | -- 27 | -- All rights reserved 28 | -- 29 | -- Redistribution and use in source and synthezised forms, with or without 30 | -- modification, are permitted provided that the following conditions are met: 31 | -- 32 | -- Redistributions of source code must retain the above copyright notice, 33 | -- this list of conditions and the following disclaimer. 34 | -- 35 | -- Redistributions in synthesized form must reproduce the above copyright 36 | -- notice, this list of conditions and the following disclaimer in the 37 | -- documentation and/or other materials provided with the distribution. 38 | -- 39 | -- Neither the name of the author nor the names of other contributors may 40 | -- be used to endorse or promote products derived from this software without 41 | -- specific prior written permission. 42 | -- 43 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 44 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 45 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 46 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 47 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 48 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 49 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 50 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 51 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 52 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 53 | -- POSSIBILITY OF SUCH DAMAGE. 54 | -- 55 | -- Please report bugs to the author, but before you do so, please 56 | -- make sure that this is not a derivative work and that 57 | -- you have the latest version of this file. 58 | -- 59 | -- The latest version of this file can be found at: 60 | -- http://www.opencores.org/cvsweb.shtml/t51/ 61 | -- 62 | -- Limitations : 63 | -- 64 | -- File history : 65 | -- 66 | -- 0242 : Initial release 67 | -- 68 | -- 0244 : Changed to single register file 69 | -- 70 | 71 | library IEEE; 72 | use IEEE.std_logic_1164.all; 73 | use IEEE.numeric_std.all; 74 | 75 | entity T80_Reg is 76 | port( 77 | Clk : in std_logic; 78 | CEN : in std_logic; 79 | WEH : in std_logic; 80 | WEL : in std_logic; 81 | AddrA : in std_logic_vector(2 downto 0); 82 | AddrB : in std_logic_vector(2 downto 0); 83 | AddrC : in std_logic_vector(2 downto 0); 84 | DIH : in std_logic_vector(7 downto 0); 85 | DIL : in std_logic_vector(7 downto 0); 86 | DOAH : out std_logic_vector(7 downto 0); 87 | DOAL : out std_logic_vector(7 downto 0); 88 | DOBH : out std_logic_vector(7 downto 0); 89 | DOBL : out std_logic_vector(7 downto 0); 90 | DOCH : out std_logic_vector(7 downto 0); 91 | DOCL : out std_logic_vector(7 downto 0); 92 | DOR : out std_logic_vector(127 downto 0); 93 | DIRSet : in std_logic; 94 | DIR : in std_logic_vector(127 downto 0) 95 | ); 96 | end T80_Reg; 97 | 98 | architecture rtl of T80_Reg is 99 | 100 | type Register_Image is array (natural range <>) of std_logic_vector(7 downto 0); 101 | signal RegsH : Register_Image(0 to 7); 102 | signal RegsL : Register_Image(0 to 7); 103 | 104 | begin 105 | 106 | process (Clk) 107 | begin 108 | if rising_edge(Clk) then 109 | if DIRSet = '1' then 110 | RegsL(0) <= DIR( 7 downto 0); 111 | RegsH(0) <= DIR( 15 downto 8); 112 | 113 | RegsL(1) <= DIR( 23 downto 16); 114 | RegsH(1) <= DIR( 31 downto 24); 115 | 116 | RegsL(2) <= DIR( 39 downto 32); 117 | RegsH(2) <= DIR( 47 downto 40); 118 | 119 | RegsL(3) <= DIR( 55 downto 48); 120 | RegsH(3) <= DIR( 63 downto 56); 121 | 122 | RegsL(4) <= DIR( 71 downto 64); 123 | RegsH(4) <= DIR( 79 downto 72); 124 | 125 | RegsL(5) <= DIR( 87 downto 80); 126 | RegsH(5) <= DIR( 95 downto 88); 127 | 128 | RegsL(6) <= DIR(103 downto 96); 129 | RegsH(6) <= DIR(111 downto 104); 130 | 131 | RegsL(7) <= DIR(119 downto 112); 132 | RegsH(7) <= DIR(127 downto 120); 133 | elsif CEN = '1' then 134 | if WEH = '1' then 135 | RegsH(to_integer(unsigned(AddrA))) <= DIH; 136 | end if; 137 | if WEL = '1' then 138 | RegsL(to_integer(unsigned(AddrA))) <= DIL; 139 | end if; 140 | end if; 141 | end if; 142 | end process; 143 | 144 | DOAH <= RegsH(to_integer(unsigned(AddrA))); 145 | DOAL <= RegsL(to_integer(unsigned(AddrA))); 146 | DOBH <= RegsH(to_integer(unsigned(AddrB))); 147 | DOBL <= RegsL(to_integer(unsigned(AddrB))); 148 | DOCH <= RegsH(to_integer(unsigned(AddrC))); 149 | DOCL <= RegsL(to_integer(unsigned(AddrC))); 150 | DOR <= RegsH(7) & RegsL(7) & RegsH(6) & RegsL(6) & RegsH(5) & RegsL(5) & RegsH(4) & RegsL(4) & RegsH(3) & RegsL(3) & RegsH(2) & RegsL(2) & RegsH(1) & RegsL(1) & RegsH(0) & RegsL(0); 151 | 152 | end; 153 | -------------------------------------------------------------------------------- /modules/cpu-t80/T80as.vhd: -------------------------------------------------------------------------------- 1 | ------------------------------------------------------------------------------ 2 | -- 2004.10.18 WR_n active was changed from T2 to T3. 3 | -- modification by Katsumi Degawa 4 | ------------------------------------------------------------------------------ 5 | -- t80as.vhd : The non-tristate signal edition of t80a.vhd 6 | -- 7 | -- 2003.2.7 non-tristate modification by Tatsuyuki Satoh 8 | -- 9 | -- 1.separate 'D' to 'DO' and 'DI'. 10 | -- 2.added 'DOE' to 'DO' enable signal.(data direction) 11 | -- 3.MREQ_n,IORQ_n,RD_n,WR_n,RFSH_n,A doesn't become the condition of 'Z'. 12 | -- 13 | -- There is a mark of "--AS" in all the change points. 14 | -- 15 | ------------------------------------------------------------------------------ 16 | 17 | -- 18 | -- Z80 compatible microprocessor core, asynchronous top level 19 | -- 20 | -- Version : 0247 21 | -- 22 | -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) 23 | -- 24 | -- All rights reserved 25 | -- 26 | -- Redistribution and use in source and synthezised forms, with or without 27 | -- modification, are permitted provided that the following conditions are met: 28 | -- 29 | -- Redistributions of source code must retain the above copyright notice, 30 | -- this list of conditions and the following disclaimer. 31 | -- 32 | -- Redistributions in synthesized form must reproduce the above copyright 33 | -- notice, this list of conditions and the following disclaimer in the 34 | -- documentation and/or other materials provided with the distribution. 35 | -- 36 | -- Neither the name of the author nor the names of other contributors may 37 | -- be used to endorse or promote products derived from this software without 38 | -- specific prior written permission. 39 | -- 40 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 41 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 42 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 44 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 45 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 46 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 47 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 48 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 49 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 50 | -- POSSIBILITY OF SUCH DAMAGE. 51 | -- 52 | -- Please report bugs to the author, but before you do so, please 53 | -- make sure that this is not a derivative work and that 54 | -- you have the latest version of this file. 55 | -- 56 | -- The latest version of this file can be found at: 57 | -- http://www.opencores.org/cvsweb.shtml/t80/ 58 | -- 59 | -- Limitations : 60 | -- 61 | -- File history : 62 | -- 63 | -- 0208 : First complete release 64 | -- 65 | -- 0211 : Fixed interrupt cycle 66 | -- 67 | -- 0235 : Updated for T80 interface change 68 | -- 69 | -- 0238 : Updated for T80 interface change 70 | -- 71 | -- 0240 : Updated for T80 interface change 72 | -- 73 | -- 0242 : Updated for T80 interface change 74 | -- 75 | -- 0247 : Fixed bus req/ack cycle 76 | -- 77 | 78 | library IEEE; 79 | use IEEE.std_logic_1164.all; 80 | use IEEE.numeric_std.all; 81 | use work.T80_Pack.all; 82 | 83 | entity T80as is 84 | generic( 85 | Mode : integer := 0 -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB 86 | ); 87 | port( 88 | RESET_n : in std_logic; 89 | CLK_n : in std_logic; 90 | WAIT_n : in std_logic; 91 | INT_n : in std_logic; 92 | NMI_n : in std_logic; 93 | BUSRQ_n : in std_logic; 94 | M1_n : out std_logic; 95 | MREQ_n : out std_logic; 96 | IORQ_n : out std_logic; 97 | RD_n : out std_logic; 98 | WR_n : out std_logic; 99 | RFSH_n : out std_logic; 100 | HALT_n : out std_logic; 101 | BUSAK_n : out std_logic; 102 | A : out std_logic_vector(15 downto 0); 103 | --AS-- D : inout std_logic_vector(7 downto 0) 104 | --AS>> 105 | DI : in std_logic_vector(7 downto 0); 106 | DO : out std_logic_vector(7 downto 0); 107 | DOE : out std_logic 108 | --< 'Z'); 151 | --AS-- D <= DO when Write = '1' and BUSAK_n_i = '1' else (others => 'Z'); 152 | --AS>> 153 | MREQ_n <= MREQ_n_i; 154 | IORQ_n <= IORQ_n_i; 155 | RD_n <= RD_n_i; 156 | WR_n <= WR_n_i; 157 | RFSH_n <= RFSH_n_i; 158 | A <= A_i; 159 | DOE <= Write when BUSAK_n_i = '1' else '0'; 160 | --< Mode, 173 | IOWait => 1) 174 | port map( 175 | CEN => CEN, 176 | M1_n => M1_n, 177 | IORQ => IORQ, 178 | NoRead => NoRead, 179 | Write => Write, 180 | RFSH_n => RFSH_n_i, 181 | HALT_n => HALT_n, 182 | WAIT_n => Wait_s, 183 | INT_n => INT_n, 184 | NMI_n => NMI_n, 185 | RESET_n => Reset_s, 186 | BUSRQ_n => BUSRQ_n, 187 | BUSAK_n => BUSAK_n_i, 188 | CLK_n => CLK_n, 189 | A => A_i, 190 | -- DInst => D, 191 | DInst => DI, 192 | DI => DI_Reg, 193 | DO => DO, 194 | MC => MCycle, 195 | TS => TState, 196 | IntCycle_n => IntCycle_n); 197 | 198 | process (CLK_n) 199 | begin 200 | if CLK_n'event and CLK_n = '0' then 201 | Wait_s <= WAIT_n; 202 | if TState = "011" and BUSAK_n_i = '1' then 203 | --AS-- DI_Reg <= to_x01(D); 204 | --AS>> 205 | DI_Reg <= to_x01(DI); 206 | --< Z80, 1 => Fast Z80, 2 => 8080, 3 => GB 64 | ); 65 | port( 66 | RESET_n : in std_logic; 67 | CLK : in std_logic; 68 | CEN_p : in std_logic := '1'; 69 | CEN_n : in std_logic := '1'; 70 | WAIT_n : in std_logic := '1'; 71 | INT_n : in std_logic := '1'; 72 | NMI_n : in std_logic := '1'; 73 | BUSRQ_n : in std_logic := '1'; 74 | M1_n : out std_logic; 75 | MREQ_n : out std_logic; 76 | IORQ_n : out std_logic; 77 | RD_n : out std_logic; 78 | WR_n : out std_logic; 79 | RFSH_n : out std_logic; 80 | HALT_n : out std_logic; 81 | BUSAK_n : out std_logic; 82 | OUT0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 83 | A : out std_logic_vector(15 downto 0); 84 | DI : in std_logic_vector(7 downto 0); 85 | DO : out std_logic_vector(7 downto 0); 86 | R800_mode : in std_logic := '0'; 87 | REG : out std_logic_vector(211 downto 0); -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A 88 | DIRSet : in std_logic := '0'; 89 | DIR : in std_logic_vector(211 downto 0) := (others => '0') -- IFF2, IFF1, IM, IY, HL', DE', BC', IX, HL, DE, BC, PC, SP, R, I, F', A', F, A 90 | ); 91 | end T80pa; 92 | 93 | architecture rtl of T80pa is 94 | 95 | signal IntCycle_n : std_logic; 96 | signal IntCycleD_n : std_logic_vector(1 downto 0); 97 | signal IORQ : std_logic; 98 | signal NoRead : std_logic; 99 | signal Write : std_logic; 100 | signal BUSAK : std_logic; 101 | signal DI_Reg : std_logic_vector (7 downto 0); -- Input synchroniser 102 | signal MCycle : std_logic_vector(2 downto 0); 103 | signal TState : std_logic_vector(2 downto 0); 104 | signal CEN_pol : std_logic; 105 | signal CEN : std_logic; 106 | begin 107 | 108 | CEN <= CEN_p and not CEN_pol; 109 | BUSAK_n <= BUSAK; 110 | 111 | u0 : T80 112 | generic map( 113 | Mode => Mode, 114 | IOWait => 1 115 | ) 116 | port map( 117 | CEN => CEN, 118 | M1_n => M1_n, 119 | IORQ => IORQ, 120 | NoRead => NoRead, 121 | Write => Write, 122 | RFSH_n => RFSH_n, 123 | HALT_n => HALT_n, 124 | WAIT_n => '1', 125 | INT_n => INT_n, 126 | NMI_n => NMI_n, 127 | RESET_n => RESET_n, 128 | BUSRQ_n => BUSRQ_n, 129 | BUSAK_n => BUSAK, 130 | CLK_n => CLK, 131 | A => A, 132 | DInst => DI, -- valid at beginning of T3 133 | DI => DI_Reg, -- latched at middle of T3 134 | DO => DO, 135 | REG => REG, 136 | MC => MCycle, 137 | TS => TState, 138 | OUT0 => OUT0, 139 | R800_mode => R800_mode, 140 | IntCycle_n => IntCycle_n, 141 | DIRSet => DIRSet, 142 | DIR => DIR 143 | ); 144 | 145 | process(CLK) 146 | begin 147 | if rising_edge(CLK) then 148 | if RESET_n = '0' then 149 | WR_n <= '1'; 150 | RD_n <= '1'; 151 | IORQ_n <= '1'; 152 | MREQ_n <= '1'; 153 | DI_Reg <= "00000000"; 154 | CEN_pol <= '0'; 155 | elsif CEN_p = '1' and CEN_pol = '0' then 156 | CEN_pol <= '1'; 157 | if MCycle = "001" then 158 | if TState = "010" then 159 | IORQ_n <= '1'; 160 | MREQ_n <= '1'; 161 | RD_n <= '1'; 162 | end if; 163 | else 164 | if TState = "001" and IORQ = '1' then 165 | WR_n <= not Write; 166 | RD_n <= Write; 167 | IORQ_n <= '0'; 168 | end if; 169 | end if; 170 | elsif CEN_n = '1' and CEN_pol = '1' then 171 | if TState = "010" then 172 | CEN_pol <= not WAIT_n; 173 | else 174 | CEN_pol <= '0'; 175 | end if; 176 | if TState = "011" and BUSAK = '1' then 177 | DI_Reg <= DI; 178 | end if; 179 | if MCycle = "001" then 180 | if TState = "001" then 181 | IntCycleD_n <= IntCycleD_n(0) & IntCycle_n; 182 | RD_n <= not IntCycle_n; 183 | MREQ_n <= not IntCycle_n; 184 | IORQ_n <= IntCycleD_n(1); 185 | end if; 186 | if TState = "011" then 187 | IntCycleD_n <= "11"; 188 | RD_n <= '1'; 189 | MREQ_n <= '0'; 190 | end if; 191 | if TState = "100" then 192 | MREQ_n <= '1'; 193 | end if; 194 | else 195 | if NoRead = '0' and IORQ = '0' then 196 | if TState = "001" then 197 | RD_n <= Write; 198 | MREQ_n <= '0'; 199 | end if; 200 | end if; 201 | if TState = "010" then 202 | WR_n <= not Write; 203 | end if; 204 | if TState = "011" then 205 | WR_n <= '1'; 206 | RD_n <= '1'; 207 | IORQ_n <= '1'; 208 | MREQ_n <= '1'; 209 | end if; 210 | end if; 211 | end if; 212 | end if; 213 | end process; 214 | end; 215 | -------------------------------------------------------------------------------- /modules/cpu-t80/T80s.vhd: -------------------------------------------------------------------------------- 1 | -- 2 | -- Z80 compatible microprocessor core, synchronous top level 3 | -- Different timing than the original z80 4 | -- Inputs needs to be synchronous and outputs may glitch 5 | -- 6 | -- Version : 0242 7 | -- 8 | -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) 9 | -- 10 | -- All rights reserved 11 | -- 12 | -- Redistribution and use in source and synthezised forms, with or without 13 | -- modification, are permitted provided that the following conditions are met: 14 | -- 15 | -- Redistributions of source code must retain the above copyright notice, 16 | -- this list of conditions and the following disclaimer. 17 | -- 18 | -- Redistributions in synthesized form must reproduce the above copyright 19 | -- notice, this list of conditions and the following disclaimer in the 20 | -- documentation and/or other materials provided with the distribution. 21 | -- 22 | -- Neither the name of the author nor the names of other contributors may 23 | -- be used to endorse or promote products derived from this software without 24 | -- specific prior written permission. 25 | -- 26 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 27 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 28 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 30 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 | -- POSSIBILITY OF SUCH DAMAGE. 37 | -- 38 | -- Please report bugs to the author, but before you do so, please 39 | -- make sure that this is not a derivative work and that 40 | -- you have the latest version of this file. 41 | -- 42 | -- The latest version of this file can be found at: 43 | -- http://www.opencores.org/cvsweb.shtml/t80/ 44 | -- 45 | -- Limitations : 46 | -- 47 | -- File history : 48 | -- 49 | -- 0208 : First complete release 50 | -- 51 | -- 0210 : Fixed read with wait 52 | -- 53 | -- 0211 : Fixed interrupt cycle 54 | -- 55 | -- 0235 : Updated for T80 interface change 56 | -- 57 | -- 0236 : Added T2Write generic 58 | -- 59 | -- 0237 : Fixed T2Write with wait state 60 | -- 61 | -- 0238 : Updated for T80 interface change 62 | -- 63 | -- 0240 : Updated for T80 interface change 64 | -- 65 | -- 0242 : Updated for T80 interface change 66 | -- 67 | 68 | library IEEE; 69 | use IEEE.std_logic_1164.all; 70 | use IEEE.numeric_std.all; 71 | use IEEE.STD_LOGIC_UNSIGNED.all; 72 | use work.T80_Pack.all; 73 | 74 | entity T80s is 75 | generic( 76 | Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB 77 | T2Write : integer := 1; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 78 | IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle 79 | ); 80 | port( 81 | RESET_n : in std_logic; 82 | CLK : in std_logic; 83 | CEN : in std_logic := '1'; 84 | WAIT_n : in std_logic := '1'; 85 | INT_n : in std_logic := '1'; 86 | NMI_n : in std_logic := '1'; 87 | BUSRQ_n : in std_logic := '1'; 88 | M1_n : out std_logic; 89 | MREQ_n : out std_logic; 90 | IORQ_n : out std_logic; 91 | RD_n : out std_logic; 92 | WR_n : out std_logic; 93 | RFSH_n : out std_logic; 94 | HALT_n : out std_logic; 95 | BUSAK_n : out std_logic; 96 | OUT0 : in std_logic := '0'; -- 0 => OUT(C),0, 1 => OUT(C),255 97 | A : out std_logic_vector(15 downto 0); 98 | DI : in std_logic_vector(7 downto 0); 99 | DO : out std_logic_vector(7 downto 0) 100 | ); 101 | end T80s; 102 | 103 | architecture rtl of T80s is 104 | 105 | signal IntCycle_n : std_logic; 106 | signal NoRead : std_logic; 107 | signal Write : std_logic; 108 | signal IORQ : std_logic; 109 | signal DI_Reg : std_logic_vector(7 downto 0); 110 | signal MCycle : std_logic_vector(2 downto 0); 111 | signal TState : std_logic_vector(2 downto 0); 112 | 113 | begin 114 | 115 | u0 : T80 116 | generic map( 117 | Mode => Mode, 118 | IOWait => IOWait) 119 | port map( 120 | CEN => CEN, 121 | M1_n => M1_n, 122 | IORQ => IORQ, 123 | NoRead => NoRead, 124 | Write => Write, 125 | RFSH_n => RFSH_n, 126 | HALT_n => HALT_n, 127 | WAIT_n => Wait_n, 128 | INT_n => INT_n, 129 | NMI_n => NMI_n, 130 | RESET_n => RESET_n, 131 | BUSRQ_n => BUSRQ_n, 132 | BUSAK_n => BUSAK_n, 133 | CLK_n => CLK, 134 | A => A, 135 | DInst => DI, 136 | DI => DI_Reg, 137 | DO => DO, 138 | MC => MCycle, 139 | TS => TState, 140 | OUT0 => OUT0, 141 | IntCycle_n => IntCycle_n 142 | ); 143 | 144 | process (RESET_n, CLK) 145 | begin 146 | if RESET_n = '0' then 147 | RD_n <= '1'; 148 | WR_n <= '1'; 149 | IORQ_n <= '1'; 150 | MREQ_n <= '1'; 151 | DI_Reg <= "00000000"; 152 | elsif rising_edge(CLK) then 153 | if CEN = '1' then 154 | RD_n <= '1'; 155 | WR_n <= '1'; 156 | IORQ_n <= '1'; 157 | MREQ_n <= '1'; 158 | if MCycle = 1 then 159 | if TState = 1 or (TState = 2 and Wait_n = '0') then 160 | RD_n <= not IntCycle_n; 161 | MREQ_n <= not IntCycle_n; 162 | IORQ_n <= IntCycle_n; 163 | end if; 164 | if TState = 3 then 165 | MREQ_n <= '0'; 166 | end if; 167 | else 168 | if (TState = 1 or (TState = 2 and Wait_n = '0')) and NoRead = '0' and Write = '0' then 169 | RD_n <= '0'; 170 | IORQ_n <= not IORQ; 171 | MREQ_n <= IORQ; 172 | end if; 173 | if T2Write = 0 then 174 | if TState = 2 and Write = '1' then 175 | WR_n <= '0'; 176 | IORQ_n <= not IORQ; 177 | MREQ_n <= IORQ; 178 | end if; 179 | else 180 | if (TState = 1 or (TState = 2 and Wait_n = '0')) and Write = '1' then 181 | WR_n <= '0'; 182 | IORQ_n <= not IORQ; 183 | MREQ_n <= IORQ; 184 | end if; 185 | end if; 186 | end if; 187 | if TState = 2 and Wait_n = '1' then 188 | DI_Reg <= DI; 189 | end if; 190 | end if; 191 | end if; 192 | end process; 193 | end; 194 | -------------------------------------------------------------------------------- /modules/cpu-t80/T80se.vhd: -------------------------------------------------------------------------------- 1 | -- **** 2 | -- T80(b) core. In an effort to merge and maintain bug fixes .... 3 | -- 4 | -- 5 | -- Ver 300 started tidyup 6 | -- MikeJ March 2005 7 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) 8 | -- 9 | -- **** 10 | -- 11 | -- Z80 compatible microprocessor core, synchronous top level with clock enable 12 | -- Different timing than the original z80 13 | -- Inputs needs to be synchronous and outputs may glitch 14 | -- 15 | -- Version : 0240 16 | -- 17 | -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) 18 | -- 19 | -- All rights reserved 20 | -- 21 | -- Redistribution and use in source and synthezised forms, with or without 22 | -- modification, are permitted provided that the following conditions are met: 23 | -- 24 | -- Redistributions of source code must retain the above copyright notice, 25 | -- this list of conditions and the following disclaimer. 26 | -- 27 | -- Redistributions in synthesized form must reproduce the above copyright 28 | -- notice, this list of conditions and the following disclaimer in the 29 | -- documentation and/or other materials provided with the distribution. 30 | -- 31 | -- Neither the name of the author nor the names of other contributors may 32 | -- be used to endorse or promote products derived from this software without 33 | -- specific prior written permission. 34 | -- 35 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 36 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 37 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 39 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 40 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 41 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 42 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 43 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 44 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 45 | -- POSSIBILITY OF SUCH DAMAGE. 46 | -- 47 | -- Please report bugs to the author, but before you do so, please 48 | -- make sure that this is not a derivative work and that 49 | -- you have the latest version of this file. 50 | -- 51 | -- The latest version of this file can be found at: 52 | -- http://www.opencores.org/cvsweb.shtml/t80/ 53 | -- 54 | -- Limitations : 55 | -- 56 | -- File history : 57 | -- 58 | -- 0235 : First release 59 | -- 60 | -- 0236 : Added T2Write generic 61 | -- 62 | -- 0237 : Fixed T2Write with wait state 63 | -- 64 | -- 0238 : Updated for T80 interface change 65 | -- 66 | -- 0240 : Updated for T80 interface change 67 | -- 68 | -- 0242 : Updated for T80 interface change 69 | -- 70 | library IEEE; 71 | use IEEE.std_logic_1164.all; 72 | use IEEE.numeric_std.all; 73 | use work.T80_Pack.all; 74 | 75 | entity T80se is 76 | generic( 77 | Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB 78 | T2Write : integer := 0; -- 0 => WR_n active in T3, /=0 => WR_n active in T2 79 | IOWait : integer := 1 -- 0 => Single cycle I/O, 1 => Std I/O cycle 80 | ); 81 | port( 82 | RESET_n : in std_logic; 83 | CLK_n : in std_logic; 84 | CLKEN : in std_logic; 85 | WAIT_n : in std_logic; 86 | INT_n : in std_logic; 87 | NMI_n : in std_logic; 88 | BUSRQ_n : in std_logic; 89 | M1_n : out std_logic; 90 | MREQ_n : out std_logic; 91 | IORQ_n : out std_logic; 92 | RD_n : out std_logic; 93 | WR_n : out std_logic; 94 | RFSH_n : out std_logic; 95 | HALT_n : out std_logic; 96 | BUSAK_n : out std_logic; 97 | A : out std_logic_vector(15 downto 0); 98 | DI : in std_logic_vector(7 downto 0); 99 | DO : out std_logic_vector(7 downto 0) 100 | ); 101 | end T80se; 102 | 103 | architecture rtl of T80se is 104 | 105 | signal IntCycle_n : std_logic; 106 | signal NoRead : std_logic; 107 | signal Write : std_logic; 108 | signal IORQ : std_logic; 109 | signal DI_Reg : std_logic_vector(7 downto 0); 110 | signal MCycle : std_logic_vector(2 downto 0); 111 | signal TState : std_logic_vector(2 downto 0); 112 | 113 | begin 114 | 115 | u0 : T80 116 | generic map( 117 | Mode => Mode, 118 | IOWait => IOWait) 119 | port map( 120 | CEN => CLKEN, 121 | M1_n => M1_n, 122 | IORQ => IORQ, 123 | NoRead => NoRead, 124 | Write => Write, 125 | RFSH_n => RFSH_n, 126 | HALT_n => HALT_n, 127 | WAIT_n => Wait_n, 128 | INT_n => INT_n, 129 | NMI_n => NMI_n, 130 | RESET_n => RESET_n, 131 | BUSRQ_n => BUSRQ_n, 132 | BUSAK_n => BUSAK_n, 133 | CLK_n => CLK_n, 134 | A => A, 135 | DInst => DI, 136 | DI => DI_Reg, 137 | DO => DO, 138 | MC => MCycle, 139 | TS => TState, 140 | IntCycle_n => IntCycle_n); 141 | 142 | process (RESET_n, CLK_n) 143 | begin 144 | if RESET_n = '0' then 145 | RD_n <= '1'; 146 | WR_n <= '1'; 147 | IORQ_n <= '1'; 148 | MREQ_n <= '1'; 149 | DI_Reg <= "00000000"; 150 | elsif CLK_n'event and CLK_n = '1' then 151 | if CLKEN = '1' then 152 | RD_n <= '1'; 153 | WR_n <= '1'; 154 | IORQ_n <= '1'; 155 | MREQ_n <= '1'; 156 | if MCycle = "001" then 157 | if TState = "001" or (TState = "010" and Wait_n = '0') then 158 | RD_n <= not IntCycle_n; 159 | MREQ_n <= not IntCycle_n; 160 | IORQ_n <= IntCycle_n; 161 | end if; 162 | if TState = "011" then 163 | MREQ_n <= '0'; 164 | end if; 165 | else 166 | if (TState = "001" or (TState = "010" and Wait_n = '0')) and NoRead = '0' and Write = '0' then 167 | RD_n <= '0'; 168 | IORQ_n <= not IORQ; 169 | MREQ_n <= IORQ; 170 | end if; 171 | if T2Write = 0 then 172 | if TState = "010" and Write = '1' then 173 | WR_n <= '0'; 174 | IORQ_n <= not IORQ; 175 | MREQ_n <= IORQ; 176 | end if; 177 | else 178 | if (TState = "001" or (TState = "010" and Wait_n = '0')) and Write = '1' then 179 | WR_n <= '0'; 180 | IORQ_n <= not IORQ; 181 | MREQ_n <= IORQ; 182 | end if; 183 | end if; 184 | end if; 185 | if TState = "010" and Wait_n = '1' then 186 | DI_Reg <= DI; 187 | end if; 188 | end if; 189 | end if; 190 | end process; 191 | 192 | end; 193 | -------------------------------------------------------------------------------- /modules/cpu-t80/T80sed.vhd: -------------------------------------------------------------------------------- 1 | -- **** 2 | -- T80(b) core. In an effort to merge and maintain bug fixes .... 3 | -- 4 | -- 5 | -- Ver 300 started tidyup 6 | -- MikeJ March 2005 7 | -- Latest version from www.fpgaarcade.com (original www.opencores.org) 8 | -- 9 | -- **** 10 | -- ** CUSTOM 2 CLOCK MEMORY ACCESS FOR PACMAN, MIKEJ ** 11 | -- 12 | -- Z80 compatible microprocessor core, synchronous top level with clock enable 13 | -- Different timing than the original z80 14 | -- Inputs needs to be synchronous and outputs may glitch 15 | -- 16 | -- Version : 0238 17 | -- 18 | -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) 19 | -- 20 | -- All rights reserved 21 | -- 22 | -- Redistribution and use in source and synthezised forms, with or without 23 | -- modification, are permitted provided that the following conditions are met: 24 | -- 25 | -- Redistributions of source code must retain the above copyright notice, 26 | -- this list of conditions and the following disclaimer. 27 | -- 28 | -- Redistributions in synthesized form must reproduce the above copyright 29 | -- notice, this list of conditions and the following disclaimer in the 30 | -- documentation and/or other materials provided with the distribution. 31 | -- 32 | -- Neither the name of the author nor the names of other contributors may 33 | -- be used to endorse or promote products derived from this software without 34 | -- specific prior written permission. 35 | -- 36 | -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 37 | -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 38 | -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 39 | -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 40 | -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 41 | -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 42 | -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 43 | -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 44 | -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45 | -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 46 | -- POSSIBILITY OF SUCH DAMAGE. 47 | -- 48 | -- Please report bugs to the author, but before you do so, please 49 | -- make sure that this is not a derivative work and that 50 | -- you have the latest version of this file. 51 | -- 52 | -- The latest version of this file can be found at: 53 | -- http://www.opencores.org/cvsweb.shtml/t80/ 54 | -- 55 | -- Limitations : 56 | -- 57 | -- File history : 58 | -- 59 | -- 0235 : First release 60 | -- 61 | -- 0236 : Added T2Write generic 62 | -- 63 | -- 0237 : Fixed T2Write with wait state 64 | -- 65 | -- 0238 : Updated for T80 interface change 66 | -- 67 | -- 0242 : Updated for T80 interface change 68 | -- 69 | 70 | library IEEE; 71 | use IEEE.std_logic_1164.all; 72 | use IEEE.numeric_std.all; 73 | use work.T80_Pack.all; 74 | 75 | entity T80sed is 76 | port( 77 | RESET_n : in std_logic; 78 | CLK_n : in std_logic; 79 | CLKEN : in std_logic; 80 | WAIT_n : in std_logic; 81 | INT_n : in std_logic; 82 | NMI_n : in std_logic; 83 | BUSRQ_n : in std_logic; 84 | M1_n : out std_logic; 85 | MREQ_n : out std_logic; 86 | IORQ_n : out std_logic; 87 | RD_n : out std_logic; 88 | WR_n : out std_logic; 89 | RFSH_n : out std_logic; 90 | HALT_n : out std_logic; 91 | BUSAK_n : out std_logic; 92 | A : out std_logic_vector(15 downto 0); 93 | DI : in std_logic_vector(7 downto 0); 94 | DO : out std_logic_vector(7 downto 0) 95 | ); 96 | end T80sed; 97 | 98 | architecture rtl of T80sed is 99 | 100 | signal IntCycle_n : std_logic; 101 | signal NoRead : std_logic; 102 | signal Write : std_logic; 103 | signal IORQ : std_logic; 104 | signal DI_Reg : std_logic_vector(7 downto 0); 105 | signal MCycle : std_logic_vector(2 downto 0); 106 | signal TState : std_logic_vector(2 downto 0); 107 | 108 | begin 109 | 110 | u0 : T80 111 | generic map( 112 | Mode => 0, 113 | IOWait => 1) 114 | port map( 115 | CEN => CLKEN, 116 | M1_n => M1_n, 117 | IORQ => IORQ, 118 | NoRead => NoRead, 119 | Write => Write, 120 | RFSH_n => RFSH_n, 121 | HALT_n => HALT_n, 122 | WAIT_n => Wait_n, 123 | INT_n => INT_n, 124 | NMI_n => NMI_n, 125 | RESET_n => RESET_n, 126 | BUSRQ_n => BUSRQ_n, 127 | BUSAK_n => BUSAK_n, 128 | CLK_n => CLK_n, 129 | A => A, 130 | DInst => DI, 131 | DI => DI_Reg, 132 | DO => DO, 133 | MC => MCycle, 134 | TS => TState, 135 | IntCycle_n => IntCycle_n); 136 | 137 | process (RESET_n, CLK_n) 138 | begin 139 | if RESET_n = '0' then 140 | RD_n <= '1'; 141 | WR_n <= '1'; 142 | IORQ_n <= '1'; 143 | MREQ_n <= '1'; 144 | DI_Reg <= "00000000"; 145 | elsif CLK_n'event and CLK_n = '1' then 146 | if CLKEN = '1' then 147 | RD_n <= '1'; 148 | WR_n <= '1'; 149 | IORQ_n <= '1'; 150 | MREQ_n <= '1'; 151 | if MCycle = "001" then 152 | if TState = "001" or (TState = "010" and Wait_n = '0') then 153 | RD_n <= not IntCycle_n; 154 | MREQ_n <= not IntCycle_n; 155 | IORQ_n <= IntCycle_n; 156 | end if; 157 | if TState = "011" then 158 | MREQ_n <= '0'; 159 | end if; 160 | else 161 | if (TState = "001" or TState = "010") and NoRead = '0' and Write = '0' then 162 | RD_n <= '0'; 163 | IORQ_n <= not IORQ; 164 | MREQ_n <= IORQ; 165 | end if; 166 | if ((TState = "001") or (TState = "010")) and Write = '1' then 167 | WR_n <= '0'; 168 | IORQ_n <= not IORQ; 169 | MREQ_n <= IORQ; 170 | end if; 171 | end if; 172 | if TState = "010" and Wait_n = '1' then 173 | DI_Reg <= DI; 174 | end if; 175 | end if; 176 | end if; 177 | end process; 178 | 179 | end; 180 | -------------------------------------------------------------------------------- /modules/cpu-t80/Z80.vhd: -------------------------------------------------------------------------------- 1 | library IEEE; 2 | use IEEE.std_logic_1164.all; 3 | library work; 4 | use work.T80_Pack.all; 5 | 6 | entity Z80 is port 7 | ( 8 | clk : in std_logic; 9 | clk_en : in std_logic; 10 | reset : in std_logic; 11 | 12 | addr : out std_logic_vector(15 downto 0); 13 | datai : in std_logic_vector(7 downto 0); 14 | datao : out std_logic_vector(7 downto 0); 15 | 16 | m1 : out std_logic; 17 | mem_rd : out std_logic; 18 | mem_wr : out std_logic; 19 | io_rd : out std_logic; 20 | io_wr : out std_logic; 21 | 22 | wait_n : in std_logic := '1'; 23 | busrq_n : in std_logic := '1'; 24 | intreq : in std_logic := '0'; 25 | intvec : in std_logic_vector(7 downto 0); 26 | intack : out std_logic; 27 | nmi : in std_logic := '0' 28 | ); 29 | end Z80; 30 | 31 | architecture SYN of Z80 is 32 | 33 | component T80se is 34 | generic 35 | ( 36 | Mode : integer := 0; -- 0 => Z80, 1 => Fast Z80, 2 => 8080, 3 => GB 37 | T2Write : integer := 1 -- 0 => WR_n active in T3, /=0 => WR_n active in T2 38 | ); 39 | port 40 | ( 41 | RESET_n : in std_logic; 42 | CLK_n : in std_logic; 43 | CLKEN : in std_logic; 44 | WAIT_n : in std_logic; 45 | INT_n : in std_logic; 46 | NMI_n : in std_logic; 47 | BUSRQ_n : in std_logic; 48 | M1_n : out std_logic; 49 | MREQ_n : out std_logic; 50 | IORQ_n : out std_logic; 51 | RD_n : out std_logic; 52 | WR_n : out std_logic; 53 | RFSH_n : out std_logic; 54 | HALT_n : out std_logic; 55 | BUSAK_n : out std_logic; 56 | A : out std_logic_vector(15 downto 0); 57 | DI : in std_logic_vector(7 downto 0); 58 | DO : out std_logic_vector(7 downto 0) 59 | ); 60 | end component T80se; 61 | 62 | -- Signal Declarations 63 | 64 | signal reset_n : std_logic; 65 | signal int_n : std_logic; 66 | signal nmi_n : std_logic; 67 | 68 | signal z80_m1 : std_logic; 69 | signal z80_memreq : std_logic; 70 | signal z80_ioreq : std_logic; 71 | signal z80_rd : std_logic; 72 | signal z80_wr : std_logic; 73 | signal z80_datai : std_logic_vector(7 downto 0); 74 | 75 | -- derived signals (outputs we need to read) 76 | signal z80_memrd : std_logic; 77 | signal z80_iord : std_logic; 78 | signal fetch : std_logic; 79 | 80 | begin 81 | 82 | -- simple inversions 83 | reset_n <= not reset; 84 | int_n <= not intreq; 85 | nmi_n <= not nmi; 86 | 87 | -- direct-connect (outputs we need to read) 88 | m1 <= z80_m1; 89 | mem_rd <= z80_memrd; 90 | io_rd <= z80_iord; 91 | 92 | -- memory signals 93 | z80_memrd <= z80_memreq nor z80_rd; 94 | mem_wr <= z80_memreq nor z80_wr; 95 | 96 | -- io signals 97 | z80_iord <= z80_ioreq nor z80_rd; 98 | io_wr <= z80_ioreq nor z80_wr; 99 | 100 | -- other signals 101 | fetch <= z80_m1 nor z80_memreq; 102 | intack <= z80_m1 nor z80_ioreq; 103 | 104 | -- data in mux 105 | z80_datai <= intvec when ((z80_memrd or z80_iord) = '0') else 106 | datai; 107 | 108 | Z80_uP : T80se 109 | generic map 110 | ( 111 | Mode => 0 -- Z80 112 | ) 113 | port map 114 | ( 115 | RESET_n => reset_n, 116 | CLK_n => clk, 117 | CLKEN => clk_en, 118 | WAIT_n => wait_n, 119 | INT_n => int_n, 120 | NMI_n => nmi_n, 121 | BUSRQ_n => busrq_n, 122 | M1_n => z80_m1, 123 | MREQ_n => z80_memreq, 124 | IORQ_n => z80_ioreq, 125 | RD_n => z80_rd, 126 | WR_n => z80_wr, 127 | RFSH_n => open, 128 | HALT_n => open, 129 | BUSAK_n => open, 130 | A => addr, 131 | DI => z80_datai, 132 | DO => datao 133 | ); 134 | 135 | end architecture SYN; 136 | -------------------------------------------------------------------------------- /modules/cpu-t80/index.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "GBse.vhd"] 2 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80pa.vhd"] 3 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80s.vhd"] 4 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80se.vhd"] 5 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80a.vhd"] 6 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80as.vhd"] 7 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80sed.vhd"] 8 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T8080se.vhd"] 9 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80_Reg.vhd"] 10 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80_MCode.vhd"] 11 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80_ALU.vhd"] 12 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80.vhd"] 13 | set_global_assignment -name VHDL_FILE [file join $::quartus(qip_path) "T80_Pack.vhd"] -------------------------------------------------------------------------------- /modules/general-sync_fifo/index.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "sync_fifo.sv"] 2 | -------------------------------------------------------------------------------- /modules/general-sync_fifo/sync_fifo.sv: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // SPDX-License-Identifier: MIT 3 | // SPDX-FileType: SOURCE 4 | // SPDX-FileCopyrightText: (c) 2022 Adam Gastineau 5 | //------------------------------------------------------------------------------ 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | //------------------------------------------------------------------------------ 24 | // Easily reusable method for synchronizing multiple bits across clock domains 25 | // Uses a shallow depth (4 entries) FIFO, so make sure to empty it quickly 26 | //------------------------------------------------------------------------------ 27 | 28 | module sync_fifo #( 29 | parameter WIDTH = 2 30 | ) ( 31 | input wire clk_write, 32 | input wire clk_read, 33 | 34 | input wire write_en, 35 | input wire [WIDTH - 1:0] data_in, 36 | output reg [WIDTH - 1:0] data_out = 0 37 | ); 38 | 39 | reg read_req = 0; 40 | wire empty; 41 | 42 | wire [WIDTH - 1:0] fifo_out; 43 | 44 | dcfifo dcfifo_component ( 45 | .data(data_in), 46 | .rdclk(clk_read), 47 | .rdreq(read_req), 48 | .wrclk(clk_write), 49 | .wrreq(write_en), 50 | .q(fifo_out), 51 | .rdempty(empty), 52 | .aclr(), 53 | .eccstatus(), 54 | .rdfull(), 55 | .rdusedw(), 56 | .wrempty(), 57 | .wrfull(), 58 | .wrusedw() 59 | ); 60 | 61 | defparam dcfifo_component.intended_device_family = "Cyclone V", 62 | dcfifo_component.lpm_numwords = 4, 63 | dcfifo_component.lpm_showahead = "OFF", 64 | dcfifo_component.lpm_type = "dcfifo", 65 | dcfifo_component.lpm_width = 32, 66 | dcfifo_component.lpm_widthu = 2, 67 | dcfifo_component.overflow_checking = "ON", 68 | dcfifo_component.rdsync_delaypipe = 5, 69 | dcfifo_component.underflow_checking = "ON", 70 | dcfifo_component.use_eab = "ON", 71 | dcfifo_component.wrsync_delaypipe = 5; 72 | 73 | reg [1:0] read_state = 0; 74 | localparam READ_DELAY = 1; 75 | localparam READ_WRITE = 2; 76 | 77 | always @(posedge clk_read) begin 78 | read_req <= 0; 79 | 80 | if (~empty) begin 81 | read_state <= READ_DELAY; 82 | read_req <= 1; 83 | end 84 | 85 | case (read_state) 86 | READ_DELAY: begin 87 | read_state <= READ_WRITE; 88 | end 89 | READ_WRITE: begin 90 | read_state <= 0; 91 | data_out <= fifo_out; 92 | end 93 | endcase 94 | end 95 | 96 | endmodule 97 | -------------------------------------------------------------------------------- /modules/pocket-dataloader/data_loader.sv: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // SPDX-License-Identifier: MIT 3 | // SPDX-FileType: SOURCE 4 | // SPDX-FileCopyrightText: (c) 2022 Adam Gastineau 5 | //------------------------------------------------------------------------------ 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | //------------------------------------------------------------------------------ 24 | // 25 | // A data loader for consuming APF bridge writes and directing them to some storage medium 26 | // 27 | // This takes the 32 bit words from APF, and splits it into four / OUTPUT_WORD_SIZE words (4 separate bytes, or 2 16-bit words). 28 | // You can configure the cycle delay by setting WRITE_MEM_CLOCK_DELAY 29 | // 30 | //------------------------------------------------------------------------------ 31 | 32 | module data_loader #( 33 | // Upper 4 bits of address 34 | parameter ADDRESS_MASK_UPPER_4 = 0, 35 | parameter ADDRESS_SIZE = 28, 36 | 37 | // Number of clk_memory cycles to delay each write output 38 | // Min 4. Component will assert this value is within the valid range 39 | // Be aware that APF sends data every ~75 74MHz cycles, so you cannot send data slower than this 40 | parameter WRITE_MEM_CLOCK_DELAY = 4, 41 | 42 | // Number of clk_memory cycles to hold the write_en signal high 43 | // Min 1. Component will assert this value is within the valid range 44 | parameter WRITE_MEM_EN_CYCLE_LENGTH = 1, 45 | 46 | // Word size in number of bytes. Can either be 1 (output 8 bits), or 2 (output 16 bits) 47 | // Component will assert this value is within the valid range 48 | parameter OUTPUT_WORD_SIZE = 1 49 | ) ( 50 | input wire clk_74a, 51 | input wire clk_memory, 52 | 53 | input wire bridge_wr, 54 | input wire bridge_endian_little, 55 | input wire [31:0] bridge_addr, 56 | input wire [31:0] bridge_wr_data, 57 | 58 | // These outputs are synced to the memory clock 59 | output reg write_en = 0, 60 | output reg [ADDRESS_SIZE-1:0] write_addr = 0, 61 | output reg [8 * OUTPUT_WORD_SIZE - 1:0] write_data = 0 62 | ); 63 | 64 | `define MAX(x, y) ((x > y) ? x : y) 65 | 66 | localparam WORD_SIZE = 8 * OUTPUT_WORD_SIZE; 67 | // Only use the lower 28 bits of the address 68 | localparam FIFO_SIZE = WORD_SIZE + 28; 69 | 70 | wire mem_empty; 71 | 72 | wire [FIFO_SIZE - 1:0] fifo_out; 73 | 74 | reg read_req = 0; 75 | reg write_req = 0; 76 | reg [31:0] shift_data; 77 | reg [27:0] buff_bridge_addr; 78 | 79 | wire [FIFO_SIZE - 1:0] fifo_in = {shift_data[WORD_SIZE-1:0], buff_bridge_addr[27:0]}; 80 | 81 | dcfifo dcfifo_component ( 82 | .data(fifo_in), 83 | .rdclk(clk_memory), 84 | .rdreq(read_req), 85 | .wrclk(clk_74a), 86 | .wrreq(write_req), 87 | .q(fifo_out), 88 | .rdempty(mem_empty) 89 | // .wrempty(), 90 | // .aclr(), 91 | // .eccstatus(), 92 | // .rdfull(), 93 | // .rdusedw(), 94 | // .wrfull(), 95 | // .wrusedw() 96 | ); 97 | 98 | defparam dcfifo_component.clocks_are_synchronized = "FALSE", 99 | dcfifo_component.intended_device_family = "Cyclone V", 100 | dcfifo_component.lpm_numwords = 4, 101 | dcfifo_component.lpm_showahead = "OFF", 102 | dcfifo_component.lpm_type = "dcfifo", 103 | dcfifo_component.lpm_width = FIFO_SIZE, 104 | dcfifo_component.lpm_widthu = 2, 105 | dcfifo_component.overflow_checking = "OFF", 106 | dcfifo_component.rdsync_delaypipe = 5, 107 | dcfifo_component.underflow_checking = "OFF", 108 | dcfifo_component.use_eab = "OFF", 109 | dcfifo_component.wrsync_delaypipe = 5; 110 | 111 | /// APF to Mem clock 112 | reg prev_bridge_wr = 0; 113 | reg [2:0] write_count = 0; 114 | reg [2:0] write_state = 0; 115 | 116 | localparam WRITE_START = 1; 117 | localparam WRITE_REQ_SHIFT = 2; 118 | 119 | // Receive APF writes and buffer them into the memory clock domain 120 | always @(posedge clk_74a) begin 121 | prev_bridge_wr <= bridge_wr; 122 | 123 | if (~prev_bridge_wr && bridge_wr && bridge_addr[31:28] == ADDRESS_MASK_UPPER_4) begin 124 | // Beginning APF write to core 125 | write_state <= WRITE_REQ_SHIFT; 126 | write_req <= 1; 127 | write_count <= 0; 128 | 129 | shift_data <= bridge_endian_little ? bridge_wr_data : { 130 | bridge_wr_data[7:0], bridge_wr_data[15:8], bridge_wr_data[23:16], bridge_wr_data[31:24] 131 | }; 132 | 133 | buff_bridge_addr <= bridge_addr[27:0]; 134 | end 135 | 136 | case (write_state) 137 | WRITE_START: begin 138 | write_req <= 1; 139 | 140 | write_state <= WRITE_REQ_SHIFT; 141 | end 142 | WRITE_REQ_SHIFT: begin 143 | write_req <= 0; 144 | 145 | // We will be writing again in the next cycle 146 | shift_data <= {8'h0, shift_data[31:WORD_SIZE]}; 147 | buff_bridge_addr <= buff_bridge_addr + OUTPUT_WORD_SIZE; 148 | 149 | write_count <= write_count + 1; 150 | 151 | if (write_count == (4 / OUTPUT_WORD_SIZE) - 1) begin 152 | // Finished write 153 | write_state <= 0; 154 | end 155 | else begin 156 | write_state <= WRITE_START; 157 | end 158 | end 159 | endcase 160 | end 161 | 162 | /// Mem clock to core 163 | 164 | reg [5:0] read_state = 0; 165 | 166 | localparam READ_DELAY = 1; 167 | localparam READ_WRITE = 2; 168 | localparam READ_WRITE_EN_CYCLE_OFF = READ_WRITE + WRITE_MEM_EN_CYCLE_LENGTH; 169 | localparam READ_WRITE_END_DEFAULT = WRITE_MEM_CLOCK_DELAY - 1; 170 | // Must use max to prevent READ_WRITE_END from being the same as READ_WRITE_EN_CYCLE_OFF 171 | localparam READ_WRITE_END = `MAX(READ_WRITE_END_DEFAULT, READ_WRITE_EN_CYCLE_OFF + 1); 172 | localparam HAS_DELAY = READ_WRITE_END_DEFAULT > READ_WRITE_EN_CYCLE_OFF; 173 | 174 | always @(posedge clk_memory) begin 175 | if (read_state != 0) begin 176 | read_state <= read_state + 1; 177 | end 178 | else if (~mem_empty) begin 179 | // Start read 180 | read_state <= READ_DELAY; 181 | read_req <= 1; 182 | end 183 | 184 | case (read_state) 185 | READ_DELAY: begin 186 | read_req <= 0; 187 | write_en <= 0; 188 | end 189 | READ_WRITE: begin 190 | // Read data is available 191 | write_en <= 1; 192 | // Lowest 28 bits are the address 193 | write_addr <= fifo_out[27:0]; 194 | write_data <= fifo_out[WORD_SIZE+27:28]; 195 | read_req <= 0; 196 | end 197 | READ_WRITE_EN_CYCLE_OFF: begin 198 | write_en <= 0; 199 | if (!HAS_DELAY) begin 200 | // No extra delay, immediately go back to start 201 | read_state <= 0; 202 | end 203 | end 204 | READ_WRITE_END: begin 205 | read_state <= 0; 206 | end 207 | endcase 208 | end 209 | 210 | initial begin 211 | // Verify parameters 212 | if (WRITE_MEM_CLOCK_DELAY < 4) begin 213 | $error("WRITE_MEM_CLOCK_DELAY has a minimum value of 4. Received %d", WRITE_MEM_CLOCK_DELAY); 214 | end 215 | if (WRITE_MEM_EN_CYCLE_LENGTH < 1 || WRITE_MEM_EN_CYCLE_LENGTH >= WRITE_MEM_CLOCK_DELAY - 2) begin 216 | $error("WRITE_MEM_EN_CYCLE_LENGTH must be between 1 and %d (inclusive, based off of WRITE_MEM_CLOCK_DELAY). Received %d", WRITE_MEM_CLOCK_DELAY - 2 - 1, WRITE_MEM_EN_CYCLE_LENGTH); 217 | end 218 | if (OUTPUT_WORD_SIZE < 1 || OUTPUT_WORD_SIZE > 2) begin 219 | $error("OUTPUT_WORD_SIZE must be 1 or 2. Received %d", OUTPUT_WORD_SIZE); 220 | end 221 | end 222 | 223 | endmodule 224 | -------------------------------------------------------------------------------- /modules/pocket-dataloader/index.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "data_loader.sv"] 2 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "data_unloader.sv"] 3 | -------------------------------------------------------------------------------- /modules/pocket-i2s/index.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "pocket_i2s.sv"] 2 | -------------------------------------------------------------------------------- /modules/pocket-i2s/pocket_i2s.sv: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // SPDX-License-Identifier: MIT 3 | // SPDX-FileType: SOURCE 4 | // SPDX-FileCopyrightText: (c) 2022 Adam Gastineau 5 | //------------------------------------------------------------------------------ 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to deal 8 | // in the Software without restriction, including without limitation the rights 9 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | // copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | // SOFTWARE. 23 | //------------------------------------------------------------------------------ 24 | // A very simple audio i2s bridge to APF, based on their example code 25 | //------------------------------------------------------------------------------ 26 | 27 | module sound_i2s #( 28 | parameter CHANNEL_WIDTH = 15, 29 | parameter SIGNED_INPUT = 0 30 | ) ( 31 | input wire clk_74a, 32 | input wire clk_audio, 33 | 34 | // Left and Right channels. Can be in an arbitrary clock domain 35 | input wire [CHANNEL_WIDTH - 1:0] audio_l, 36 | input wire [CHANNEL_WIDTH - 1:0] audio_r, 37 | 38 | output reg audio_mclk, 39 | output reg audio_lrck, 40 | output reg audio_dac 41 | ); 42 | 43 | // 44 | // audio i2s generator 45 | // 46 | reg audgen_nextsamp; 47 | 48 | // generate MCLK = 12.288mhz with fractional accumulator 49 | reg [21:0] audgen_accum = 0; 50 | parameter [20:0] CYCLE_48KHZ = 21'd122880 * 2; 51 | 52 | always @(posedge clk_74a) begin 53 | audgen_accum <= audgen_accum + CYCLE_48KHZ; 54 | if (audgen_accum >= 21'd742500) begin 55 | audio_mclk <= ~audio_mclk; 56 | audgen_accum <= audgen_accum - 21'd742500 + CYCLE_48KHZ; 57 | end 58 | end 59 | 60 | // generate SCLK = 3.072mhz by dividing MCLK by 4 61 | reg [1:0] aud_mclk_divider; 62 | reg prev_audio_mclk; 63 | wire audgen_sclk = aud_mclk_divider[1] /* synthesis keep */; 64 | 65 | always @(posedge clk_74a) begin 66 | if (audio_mclk && ~prev_audio_mclk) begin 67 | aud_mclk_divider <= aud_mclk_divider + 1'b1; 68 | end 69 | 70 | prev_audio_mclk <= audio_mclk; 71 | end 72 | 73 | // Shift out audio data as I2S 74 | // 32 total bits per channel, but only 16 active bits at the start and then 16 dummy bits 75 | // 76 | // Synchronize audio samples coming from the core 77 | localparam CHANNEL_LEFT_HIGH = SIGNED_INPUT ? 16 : 15; 78 | localparam CHANNEL_RIGHT_HIGH = 16 + CHANNEL_LEFT_HIGH; 79 | 80 | // Width of channel with signed component 81 | localparam SIGNED_CHANNEL_WIDTH = SIGNED_INPUT ? CHANNEL_WIDTH : CHANNEL_WIDTH + 1; 82 | 83 | wire [31:0] audgen_sampdata; 84 | 85 | assign audgen_sampdata[CHANNEL_LEFT_HIGH-1:CHANNEL_LEFT_HIGH-CHANNEL_WIDTH] = audio_l; 86 | assign audgen_sampdata[CHANNEL_RIGHT_HIGH-1:CHANNEL_RIGHT_HIGH-CHANNEL_WIDTH] = audio_r; 87 | 88 | generate 89 | if (!SIGNED_INPUT) begin 90 | // If not signed, make sure high bit is 0 91 | assign audgen_sampdata[31] = 0; 92 | assign audgen_sampdata[15] = 0; 93 | end 94 | endgenerate 95 | 96 | generate 97 | if (15 - SIGNED_CHANNEL_WIDTH > 0) begin 98 | assign audgen_sampdata[31-SIGNED_CHANNEL_WIDTH:16] = 0; 99 | assign audgen_sampdata[15-SIGNED_CHANNEL_WIDTH:0] = 0; 100 | end 101 | endgenerate 102 | 103 | sync_fifo #(.WIDTH(32)) 104 | sync_fifo ( 105 | .clk_write(clk_audio), 106 | .clk_read (clk_74a), 107 | 108 | .write_en(write_en), 109 | .data_in (audgen_sampdata), 110 | .data_out(audgen_sampdata_s) 111 | ); 112 | 113 | reg write_en = 0; 114 | reg [CHANNEL_WIDTH - 1:0] prev_left; 115 | reg [CHANNEL_WIDTH - 1:0] prev_right; 116 | // Mark write when necessary 117 | always @(posedge clk_audio) begin 118 | prev_left <= audio_l; 119 | prev_right <= audio_r; 120 | 121 | write_en <= 0; 122 | 123 | if (audio_l != prev_left || audio_r != prev_right) begin 124 | write_en <= 1; 125 | end 126 | end 127 | 128 | wire [31:0] audgen_sampdata_s; 129 | reg [31:0] audgen_sampshift; 130 | reg [4:0] audio_lrck_cnt; 131 | reg prev_audgen_sclk; 132 | always @(posedge clk_74a) begin 133 | if (prev_audgen_sclk && ~audgen_sclk) begin 134 | audio_dac <= audgen_sampshift[31]; // Output the next bit 135 | audio_lrck_cnt <= audio_lrck_cnt + 1'b1; // 48khz * 64 136 | if (audio_lrck_cnt == 31) begin 137 | audio_lrck <= ~audio_lrck; // Switch channels 138 | if (~audio_lrck) begin 139 | audgen_sampshift <= audgen_sampdata_s; // Reload sample shifter 140 | end 141 | end 142 | else if (audio_lrck_cnt < 16) begin 143 | audgen_sampshift <= {audgen_sampshift[30:0], 1'b0}; // Only shift for 16 clocks per channel 144 | end 145 | end 146 | 147 | prev_audgen_sclk <= audgen_sclk; 148 | end 149 | 150 | // Verify parameters 151 | initial begin 152 | if (CHANNEL_WIDTH > 16) begin 153 | $error("CHANNEL_WIDTH must be <= 16. Received %d", CHANNEL_WIDTH); 154 | end 155 | 156 | if (SIGNED_INPUT != 0 && SIGNED_INPUT != 1) begin 157 | $error("SIGNED_INPUT must be 0 or 1. Received %d", SIGNED_INPUT); 158 | end 159 | 160 | if (CHANNEL_WIDTH == 16 && SIGNED_INPUT == 0) begin 161 | $error("Cannot have CHANNEL_WIDTH of 16 and an unsigned input"); 162 | end 163 | end 164 | 165 | endmodule 166 | -------------------------------------------------------------------------------- /modules/pocket-joypad/index.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "joypad.v"] 2 | -------------------------------------------------------------------------------- /modules/pocket-joypad/joypad.v: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // SPDX-License-Identifier: MPL-2.0 3 | // SPDX-FileType: SOURCE 4 | // SPDX-FileCopyrightText: (c) 2022 Marcus Andrade 5 | //------------------------------------------------------------------------------ 6 | // 7 | // This Source Code Form is subject to the terms of the Mozilla Public 8 | // License, v. 2.0. If a copy of the MPL was not distributed with this file, 9 | // You can obtain one at https://mozilla.org/MPL/2.0/. 10 | // 11 | //------------------------------------------------------------------------------ 12 | // Generic Gamepad interface for the Analogue Pocket 13 | //------------------------------------------------------------------------------ 14 | 15 | module pocket_gamepad 16 | ( 17 | input iCLK, 18 | input [15:0] iJOY, 19 | 20 | output wire PAD_U, 21 | output wire PAD_D, 22 | output wire PAD_L, 23 | output wire PAD_R, 24 | 25 | output wire BTN_A, 26 | output wire BTN_B, 27 | output wire BTN_X, 28 | output wire BTN_Y, 29 | 30 | output wire BTN_L1, 31 | output wire BTN_R1, 32 | 33 | output wire BTN_L2, 34 | output wire BTN_R2, 35 | 36 | output wire BTN_L3, 37 | output wire BTN_R3, 38 | 39 | output wire BTN_SE, 40 | output wire BTN_ST 41 | ); 42 | 43 | assign PAD_U = joy_keys_s[0]; 44 | assign PAD_D = joy_keys_s[1]; 45 | assign PAD_L = joy_keys_s[2]; 46 | assign PAD_R = joy_keys_s[3]; 47 | 48 | assign BTN_A = joy_keys_s[4]; 49 | assign BTN_B = joy_keys_s[5]; 50 | assign BTN_X = joy_keys_s[6]; 51 | assign BTN_Y = joy_keys_s[7]; 52 | 53 | assign BTN_L1 = joy_keys_s[8]; 54 | assign BTN_R1 = joy_keys_s[9]; 55 | 56 | assign BTN_L2 = joy_keys_s[10]; 57 | assign BTN_R2 = joy_keys_s[11]; 58 | 59 | assign BTN_L3 = joy_keys_s[12]; 60 | assign BTN_R3 = joy_keys_s[13]; 61 | 62 | assign BTN_SE = joy_keys_s[14]; 63 | assign BTN_ST = joy_keys_s[15]; 64 | 65 | reg [15:0] joy_keys_s; 66 | 67 | // Sync Joystick to Core Clock 68 | always @ (posedge iCLK) begin 69 | joy_keys_s <= iJOY; 70 | end 71 | 72 | endmodule 73 | -------------------------------------------------------------------------------- /modules/pocket-video/index.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "pocket_video.sv"] 2 | -------------------------------------------------------------------------------- /modules/pocket-video/pocket_video.sv: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // SPDX-License-Identifier: MPL-2.0 3 | // SPDX-FileType: SOURCE 4 | // SPDX-FileCopyrightText: (c) 2022 Marcus Andrade 5 | //------------------------------------------------------------------------------ 6 | // 7 | // This Source Code Form is subject to the terms of the Mozilla Public 8 | // License, v. 2.0. If a copy of the MPL was not distributed with this file, 9 | // You can obtain one at https://mozilla.org/MPL/2.0/. 10 | // 11 | //------------------------------------------------------------------------------ 12 | // Generic Video Interface for the Analogue Pocket Display 13 | // 14 | // Note: APF scaler requires HSync and VSync to last for a single clock, and 15 | // video_rgb to be 0 when video_de is low 16 | //------------------------------------------------------------------------------ 17 | 18 | module pocket_video 19 | ( 20 | input iPCLK, //! Display Pixel Clock 21 | input iPCLK_90D, //! Display Pixel Clock 90º Phase Shift 22 | 23 | input [23:0] iRGB, //! Core: RGB Video 24 | input iVS, //! Core: Vsync 25 | input iHS, //! Core: Hsync 26 | input iDE, //! Core: Data Enable 27 | 28 | output reg [23:0] oRGB, //! Pixel color: Red[23:16] Green[15:8] Blue[7:0] 29 | output reg oVS, //! Frame Vsync Active high 30 | output reg oHS, //! Frame Hsync Active high 31 | output reg oDE, //! Data enable Active high 32 | 33 | output wire oPCLK, //! Display Pixel Clock 34 | output wire oPCLK_90D //! Display Pixel Clock 90º Phase Shift 35 | ); 36 | 37 | assign oPCLK = iPCLK; 38 | assign oPCLK_90D = iPCLK_90D; 39 | 40 | reg [23:0] rRGB; 41 | reg rHS; 42 | reg rVS; 43 | reg rDE; 44 | 45 | always @(posedge iPCLK) begin 46 | oDE <= 0; 47 | oRGB <= 24'h0; 48 | if (rDE) begin 49 | oDE <= 1; 50 | oRGB <= rRGB; 51 | end 52 | // Set HSync and VSync to be high for a single cycle on the rising edge of the HSync and VSync coming out of the core 53 | oHS <= ~rHS && iHS; 54 | oVS <= ~rVS && iVS; 55 | rVS <= iVS; 56 | rHS <= iHS; 57 | rDE <= iDE; 58 | rRGB <= iRGB; 59 | end 60 | 61 | endmodule 62 | -------------------------------------------------------------------------------- /modules/sound-sn76496/SN76496.v: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | // SPDX-FileType: SOURCE 4 | // SPDX-FileCopyrightText: (c) 2010 MiSTer-X 5 | //------------------------------------------------------------------------------ 6 | // HDL Implimentation of Texas Instruments SN76489 7 | // 8 | // The SN76489 Digital Complex Sound Generator (DCSG) is a TTL-compatible 9 | // programmable sound generator chip from Texas Instruments. 10 | // 11 | // It contains: 12 | // - 3 square wave tone generators. 13 | // - A wide range of frequencies. 14 | // - 16 different volume levels. 15 | // - 1 noise generator. 16 | // - 2 types (white noise and periodic). 17 | // - 3 different frequencies. 18 | // - 16 different volume levels. 19 | // 20 | // Its main application was the generation of music and sound effects in game 21 | // consoles, arcade games and home computers (such as the TI-99/4A, BBC Micro, 22 | // ColecoVision, IBM PCjr, and Tandy 1000), competing with the similar 23 | // General Instrument AY-3-8910. 24 | // 25 | // Pinout of the standard Texas Instruments SN76489 chip. 26 | // The packaging is a standard 16-pin DIP. 27 | // _____________ 28 | // _| |_ 29 | // D5 |_|1 16|_| VCC 30 | // _| |_ 31 | // D6 |_|2 15|_| D4 32 | // _| |_ 33 | // D7 |_|3 14|_| CLOCK 34 | // _| |_ 35 | // READY |_|4 13|_| D3 36 | // _| |_ 37 | // /WE |_|5 12|_| D2 38 | // _| |_ 39 | // /OE |_|6 11|_| D1 40 | // _| |_ 41 | // SND OUT|_|7 10|_| D0 42 | // _| |_ 43 | // GND |_|8 9|_| NC 44 | // |_____________| 45 | // 46 | //------------------------------------------------------------------------------ 47 | 48 | module SN76496 49 | ( 50 | input clk, 51 | input cpuclk, 52 | input reset, 53 | input ce, 54 | input we, 55 | input [7:0] data, 56 | input [3:0] chmsk, 57 | output reg [7:0] sndout, 58 | output reg [3:0] chactv, 59 | output reg [2:0] lreg 60 | ); 61 | 62 | `define RNGINI 16'h0F35 63 | `define RNGFB0 16'h4000 64 | `define RNGFB1 16'h8100 65 | 66 | function [5:0] voltbl; 67 | input [3:0] idx; 68 | case (idx) 69 | 4'h0: voltbl = 63; 70 | 4'h1: voltbl = 50; 71 | 4'h2: voltbl = 40; 72 | 4'h3: voltbl = 32; 73 | 4'h4: voltbl = 25; 74 | 4'h5: voltbl = 20; 75 | 4'h6: voltbl = 16; 76 | 4'h7: voltbl = 13; 77 | 4'h8: voltbl = 10; 78 | 4'h9: voltbl = 8; 79 | 4'hA: voltbl = 6; 80 | 4'hB: voltbl = 5; 81 | 4'hC: voltbl = 4; 82 | 4'hD: voltbl = 3; 83 | 4'hE: voltbl = 2; 84 | 4'hF: voltbl = 0; 85 | endcase 86 | endfunction 87 | 88 | reg [3:0] clks; 89 | reg [2:0] nzc; 90 | reg [9:0] fq0, fq1, fq2; 91 | reg [9:0] fc0, fc1, fc2; 92 | reg [5:0] fv0, fv1, fv2, fv3; 93 | reg [5:0] _fv0,_fv1,_fv2,_fv3; 94 | reg fo0, fo1, fo2; 95 | 96 | reg [15:0] rng = `RNGINI; 97 | wire [15:0] rfb = rng[0] ? ( nzc[2] ? `RNGFB1 : `RNGFB0 ) : 16'h0; 98 | 99 | wire [1:0] nfq = nzc[1:0]; 100 | wire [10:0] fq3 = ( nfq == 2'b00 ) ? 11'd64 : 101 | ( nfq == 2'b01 ) ? 11'd128 : 102 | ( nfq == 2'b10 ) ? 11'd256 : fq2; 103 | 104 | reg [10:0] fc3; 105 | wire fo3 = rng[0]; 106 | 107 | wire [7:0] o0 = ( fo0 & chmsk[0] ) ? { 1'b0, fv0, 1'b0 } : 8'h0; 108 | wire [7:0] o1 = ( fo1 & chmsk[1] ) ? { 1'b0, fv1, 1'b0 } : 8'h0; 109 | wire [7:0] o2 = ( fo2 & chmsk[2] ) ? { 1'b0, fv2, 1'b0 } : 8'h0; 110 | wire [7:0] o3 = ( fo3 & chmsk[3] ) ? { 1'b0, fv3, 1'b0 } : 8'h0; 111 | 112 | wire [8:0] sndmix = o0 + o1 + o2 + o3; 113 | 114 | always @( posedge cpuclk or posedge reset ) 115 | begin 116 | if ( reset ) 117 | begin 118 | lreg <= 0; 119 | _fv0 <= 0; 120 | _fv1 <= 0; 121 | _fv2 <= 0; 122 | _fv3 <= 0; 123 | fq0 <= 0; 124 | fq1 <= 0; 125 | fq2 <= 0; 126 | nzc <= 0; 127 | chactv <= 0; 128 | end 129 | else 130 | begin 131 | // Register write 132 | if ( ce & we ) 133 | begin 134 | if ( data[7] ) 135 | begin 136 | lreg <= data[6:4]; 137 | case ( data[6:4] ) 138 | 3'h0: fq0[3:0] <= data[3:0]; 139 | 3'h2: fq1[3:0] <= data[3:0]; 140 | 3'h4: fq2[3:0] <= data[3:0]; 141 | 3'h1: 142 | begin 143 | _fv0 <= voltbl(data[3:0]); 144 | chactv[0] <= (~data[3]); 145 | end 146 | 3'h3: 147 | begin 148 | _fv1 <= voltbl(data[3:0]); 149 | chactv[1] <= (~data[3]); 150 | end 151 | 3'h5: 152 | begin 153 | _fv2 <= voltbl(data[3:0]); 154 | chactv[2] <= (~data[3]); 155 | end 156 | 3'h7: 157 | begin 158 | _fv3 <= voltbl(data[3:0]); 159 | chactv[3] <= (~data[3]); 160 | end 161 | 3'h6: 162 | begin 163 | nzc <= data[2:0]; 164 | end 165 | endcase 166 | end 167 | else 168 | begin 169 | case ( lreg ) 170 | 3'h0: fq0[9:4] <= data[5:0]; 171 | 3'h2: fq1[9:4] <= data[5:0]; 172 | 3'h4: fq2[9:4] <= data[5:0]; 173 | default: 174 | begin 175 | end 176 | endcase 177 | end 178 | end 179 | end 180 | end 181 | 182 | always @( posedge clk or posedge reset ) 183 | begin 184 | // Reset 185 | if ( reset ) 186 | begin 187 | sndout <= 0; 188 | fv0 <= 0; 189 | fv1 <= 0; 190 | fv2 <= 0; 191 | fv3 <= 0; 192 | fc0 <= 0; 193 | fc1 <= 0; 194 | fc2 <= 0; 195 | fc3 <= 0; 196 | fo0 <= 0; 197 | fo1 <= 0; 198 | fo2 <= 0; 199 | clks <= 0; 200 | rng <= `RNGINI; 201 | end 202 | // OSCs update 203 | else 204 | begin 205 | clks <= clks+3'd1; 206 | if ( clks == 0 ) 207 | begin 208 | fv0 <= _fv0; 209 | fv1 <= _fv1; 210 | fv2 <= _fv2; 211 | fv3 <= _fv3; 212 | 213 | if ( fc0 == 0 ) 214 | begin 215 | fc0 <= fq0; 216 | fo0 <= ~fo0; 217 | end 218 | else 219 | fc0 <= fc0-10'd1; 220 | 221 | if ( fc1 == 0 ) 222 | begin 223 | fc1 <= fq1; 224 | fo1 <= ~fo1; 225 | end 226 | else 227 | fc1 <= fc1-10'd1; 228 | 229 | if ( fc2 == 0 ) 230 | begin 231 | fc2 <= fq2; 232 | fo2 <= ~fo2; 233 | end 234 | else 235 | fc2 <= fc2-10'd1; 236 | 237 | // NoiseGen update 238 | if ( fc3 == 0 ) 239 | begin 240 | fc3 <= fq3; 241 | rng <= { 1'b0, rng[15:1] } ^ rfb; 242 | end 243 | else 244 | fc3 <= fc3-11'd1; 245 | 246 | // Sound update 247 | sndout <= {8{sndmix[8]}}|(sndmix[7:0]); 248 | 249 | end 250 | 251 | end 252 | end 253 | 254 | endmodule 255 | -------------------------------------------------------------------------------- /modules/sound-sn76496/index.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "SN76496.v"] 2 | -------------------------------------------------------------------------------- /pkg/pocket/Assets/gberet/boogermann.gberet/Green Beret.json: -------------------------------------------------------------------------------- 1 | { 2 | "instance": { 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 777, 6 | "select": false 7 | }, 8 | "data_slots": [ 9 | { 10 | "id": 1, 11 | "filename": "gberet.rom" 12 | } 13 | ], 14 | "memory_writes": [ 15 | { 16 | "address": "0xF1000000", 17 | "data": "0x00034aff" 18 | }, 19 | { 20 | "address": "0xF2000000", 21 | "data": "0x01" 22 | } 23 | ] 24 | } 25 | } -------------------------------------------------------------------------------- /pkg/pocket/Assets/gberet/boogermann.gberet/Mr. Goemon.json: -------------------------------------------------------------------------------- 1 | { 2 | "instance": { 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 777, 6 | "select": false 7 | }, 8 | "data_slots": [ 9 | { 10 | "id": 1, 11 | "filename": "mrgoemon.rom" 12 | } 13 | ], 14 | "memory_writes": [ 15 | { 16 | "address": "0xF1000000", 17 | "data": "0x00075aff" 18 | }, 19 | { 20 | "address": "0xF2000000", 21 | "data": "0x02" 22 | } 23 | ] 24 | } 25 | } -------------------------------------------------------------------------------- /pkg/pocket/Assets/gberet/boogermann.gberet/Rush'n Attack.json: -------------------------------------------------------------------------------- 1 | { 2 | "instance": { 3 | "magic": "APF_VER_1", 4 | "variant_select": { 5 | "id": 777, 6 | "select": false 7 | }, 8 | "data_slots": [ 9 | { 10 | "id": 1, 11 | "filename": "rushatck.rom" 12 | } 13 | ], 14 | "memory_writes": [ 15 | { 16 | "address": "0xF1000000", 17 | "data": "0x00034aff" 18 | }, 19 | { 20 | "address": "0xF2000000", 21 | "data": "0x01" 22 | } 23 | ] 24 | } 25 | } -------------------------------------------------------------------------------- /pkg/pocket/Assets/gberet/common/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/pkg/pocket/Assets/gberet/common/.gitkeep -------------------------------------------------------------------------------- /pkg/pocket/Cores/boogermann.gberet/audio.json: -------------------------------------------------------------------------------- 1 | { 2 | "audio": { 3 | "magic": "APF_VER_1" 4 | } 5 | } -------------------------------------------------------------------------------- /pkg/pocket/Cores/boogermann.gberet/core.json: -------------------------------------------------------------------------------- 1 | { 2 | "core": { 3 | "magic": "APF_VER_1", 4 | "metadata": { 5 | "platform_ids": [ 6 | "gberet" 7 | ], 8 | "shortname": "gberet", 9 | "description": "Green Beret/Rush n' Attack Compatible Gateware IP Core for FPGA", 10 | "author": "boogermann", 11 | "url": "https://github.com/opengateware/arcade-gberet", 12 | "version": "<%- VERSION %>", 13 | "date_release": "<%- RELEASE_DATE %>" 14 | }, 15 | "framework": { 16 | "target_product": "Analogue Pocket", 17 | "version_required": "1.1", 18 | "sleep_supported": false, 19 | "dock": { 20 | "supported": true, 21 | "analog_output": false 22 | }, 23 | "hardware": { 24 | "link_port": false, 25 | "cartridge_adapter": -1 26 | } 27 | }, 28 | "cores": [ 29 | { 30 | "name": "default", 31 | "id": 0, 32 | "filename": "bitstream.rbf_r" 33 | } 34 | ] 35 | } 36 | } -------------------------------------------------------------------------------- /pkg/pocket/Cores/boogermann.gberet/data.json: -------------------------------------------------------------------------------- 1 | { 2 | "data": { 3 | "magic": "APF_VER_1", 4 | "data_slots": [ 5 | { 6 | "name": "Arcade Game", 7 | "id": 0, 8 | "required": true, 9 | "parameters": "0x113", 10 | "extensions": [ 11 | "json" 12 | ] 13 | }, 14 | { 15 | "name": "ROM", 16 | "id": 1, 17 | "required": true, 18 | "parameters": 0, 19 | "extensions": [ 20 | "rom" 21 | ], 22 | "address": "0x00000000" 23 | } 24 | ] 25 | } 26 | } -------------------------------------------------------------------------------- /pkg/pocket/Cores/boogermann.gberet/icon.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/pkg/pocket/Cores/boogermann.gberet/icon.bin -------------------------------------------------------------------------------- /pkg/pocket/Cores/boogermann.gberet/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/pkg/pocket/Cores/boogermann.gberet/icon.png -------------------------------------------------------------------------------- /pkg/pocket/Cores/boogermann.gberet/info.txt: -------------------------------------------------------------------------------- 1 | Green Beret © 1985 Konami. 2 | 3 | Green Beret is a sideways-scrolling action/platform game set during the Cold War, in which a US Special Forces Marine must infiltrate a Russian military base to save four POW's from being executed by firing squad. 4 | This game is known in US as "Rush'n Attack". 5 | 6 | Initially, the soldier is armed with only a combat knife, but by killing the certain enemy troops, players can obtain either a three-shot flamethrower, a four-shot RPG, or a three-pack of hand grenades. 7 | The game has four stages in total: a missile base, a harbour, an air Base and a Siberian POW Camp. At the end of each stage the Marine will face a group of enemies specific to that stage. 8 | 9 | Note: You must provide your own roms to use this core. 10 | 11 | Developer(s) 12 | Konami 13 | Publisher(s) 14 | Konami 15 | Designer(s) 16 | Kiyohiro Sada 17 | Shinya Sakamoto 18 | Iku Mizutani 19 | Satoe Terashima 20 | Masanori Adachi 21 | Release 22 | 1985 23 | 24 | This Implementation of a compatible Green Beret/Rush'n Attack arcade hardware in HDL is the work of MiSTer-X 25 | 26 | Analogue Pocket port by Marcus Andrade (Boogermann) 27 | 28 | All trademarks, logos, and copyrights are property of their respective owners. 29 | 30 | The authors and contributors or any of its maintainers are in no way associated with or endorsed by Konami. 31 | -------------------------------------------------------------------------------- /pkg/pocket/Cores/boogermann.gberet/input.json: -------------------------------------------------------------------------------- 1 | { 2 | "input": { 3 | "magic": "APF_VER_1" 4 | } 5 | } -------------------------------------------------------------------------------- /pkg/pocket/Cores/boogermann.gberet/interact.json: -------------------------------------------------------------------------------- 1 | { 2 | "interact": { 3 | "magic": "APF_VER_1", 4 | "variables": [], 5 | "messages": [] 6 | } 7 | } -------------------------------------------------------------------------------- /pkg/pocket/Cores/boogermann.gberet/variants.json: -------------------------------------------------------------------------------- 1 | { 2 | "variants": { 3 | "magic": "APF_VER_1", 4 | "variant_list": [] 5 | } 6 | } -------------------------------------------------------------------------------- /pkg/pocket/Cores/boogermann.gberet/video.json: -------------------------------------------------------------------------------- 1 | { 2 | "video": { 3 | "magic": "APF_VER_1", 4 | "scaler_modes": [ 5 | { 6 | "width": 240, 7 | "height": 224, 8 | "aspect_w": 15, 9 | "aspect_h": 14, 10 | "rotation": 0, 11 | "mirror": 0 12 | } 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /pkg/pocket/Platforms/_images/gberet.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/pkg/pocket/Platforms/_images/gberet.bin -------------------------------------------------------------------------------- /pkg/pocket/Platforms/_images/gberet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/pkg/pocket/Platforms/_images/gberet.png -------------------------------------------------------------------------------- /pkg/pocket/Platforms/gberet.json: -------------------------------------------------------------------------------- 1 | { 2 | "platform": { 3 | "category": "Arcade", 4 | "name": "Green Beret", 5 | "manufacturer": "Konami", 6 | "year": 1985 7 | } 8 | } -------------------------------------------------------------------------------- /pkg/rom-recipes/Assets/gberet/common/checklist.md5: -------------------------------------------------------------------------------- 1 | 886c929e6db35548e44cfdd8d168bdb1 gberet.rom 2 | bb85714cd6fe34f3c812183d6f7ca0a0 mrgoemon.rom 3 | 77c3e9fb3763204f8e118a7442991c6e rushatck.rom 4 | -------------------------------------------------------------------------------- /pkg/rom-recipes/roms/_PUT_YOUR_ROMS_HERE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/opengateware/arcade-gberet/6ba4d4fa2fa82f6711692d3570274e5a6f3790d2/pkg/rom-recipes/roms/_PUT_YOUR_ROMS_HERE -------------------------------------------------------------------------------- /pkg/rom-recipes/tools/make_roms.ps1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/pwsh -Command 2 | 3 | $coreName = "gberet" 4 | $currentPath = $(Get-Item $($MyInvocation.MyCommand.Path)).DirectoryName 5 | $fileNames = Get-ChildItem -Path "$currentPath\..\xml" -Recurse -Include *.mra 6 | 7 | try { 8 | foreach ($f in $fileNames){ 9 | $outfile = $f.FullName 10 | Write-Host "Converting $outfile ..." 11 | orca.exe -z ..\roms -O ..\Assets\$coreName\common $outfile 12 | } 13 | } catch { 14 | Write-Host "Error: $($_.Exception.Message)" 15 | exit 1 16 | } finally { 17 | Write-Host "Done." 18 | Write-Host "Copy your rom files to Assets/$coreName/common" 19 | Write-Host "Enjoy!" 20 | timeout /t 10 21 | } 22 | 23 | exit 0 24 | -------------------------------------------------------------------------------- /pkg/rom-recipes/tools/make_roms.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CORE=gberet 4 | PARENT=$(dirname $PWD) 5 | XML=$PARENT/xml 6 | ROMS=$PARENT/roms 7 | ASSETS=$PARENT/Assets/$CORE/common 8 | 9 | find ${XML} -name '*.mra' | while read line; do 10 | echo "Processing file '$line'" 11 | orca -z ${ROMS} -O ${ASSETS} "$line" 12 | done 13 | 14 | exit 0 -------------------------------------------------------------------------------- /pkg/rom-recipes/xml/Green Beret.mra: -------------------------------------------------------------------------------- 1 | 2 | Green Beret 3 | no 4 | no 5 | gberet 6 | 0240 7 | 8 | 01 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /pkg/rom-recipes/xml/Mr. Goemon.mra: -------------------------------------------------------------------------------- 1 | 2 | Mr. Goemon 3 | no 4 | no 5 | 0240 6 | mrgoemon 7 | 8 | 02 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /pkg/rom-recipes/xml/Rush'n Attack (US).mra: -------------------------------------------------------------------------------- 1 | 2 | Rush'n Attack 3 | no 4 | no 5 | 0240 6 | rushatck 7 | 8 | 01 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /platform/pocket/apf.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "apf_top.v"] 2 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "common.v"] 3 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "io_bridge_peripheral.v"] 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "io_pad_controller.v"] 5 | set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) "apf_constraints.sdc"] 6 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "mf_ddio_bidir_12.qip"] 7 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "mf_datatable.qip"] 8 | -------------------------------------------------------------------------------- /platform/pocket/apf_constraints.sdc: -------------------------------------------------------------------------------- 1 | # 2 | # APF constraints 3 | # Do not edit this file. 4 | # 5 | # Add your own constraints in the \core_constraints.sdc in the core directory, which will also be loaded. 6 | 7 | create_clock -name clk_74a -period 13.468 [get_ports clk_74a] 8 | create_clock -name clk_74b -period 13.468 [get_ports clk_74b] 9 | create_clock -name bridge_spiclk -period 13.468 [get_ports bridge_spiclk] 10 | 11 | # autogenerate PLL clock names for use down below 12 | derive_pll_clocks 13 | -------------------------------------------------------------------------------- /platform/pocket/build_cdf.tcl: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # SPDX-License-Identifier: CC0-1.0 3 | # SPDX-FileType: SOURCE 4 | # SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors 5 | # ============================================================================== 6 | # @file: build_cd.h 7 | # @brief: Generate a JTAG Chain Description File. 8 | # Create a .cdf file to be used with Quartus Prime Programmer 9 | # ============================================================================== 10 | proc createChainDescriptionFile {revision device outpath project_name} { 11 | set outputFileName "$project_name.cdf" 12 | set outputFile [open $outputFileName "w"] 13 | 14 | puts $outputFile "JedecChain;" 15 | puts $outputFile " FileRevision(JESD32A);" 16 | puts $outputFile " DefaultMfr(6E);" 17 | puts $outputFile "" 18 | puts $outputFile " P ActionCode(Cfg)" 19 | puts $outputFile " Device PartName($device) Path(\"$outpath/\") File(\"$revision.sof\") MfrSpec(OpMask(1));" 20 | puts $outputFile "ChainEnd;" 21 | puts $outputFile "" 22 | puts $outputFile "AlteraBegin;" 23 | puts $outputFile " ChainType(JTAG);" 24 | puts $outputFile "AlteraEnd;" 25 | } 26 | 27 | set project_name [lindex $quartus(args) 1] 28 | set revision [lindex $quartus(args) 2] 29 | 30 | if {[project_exists $project_name]} { 31 | if {[string equal "" $revision]} { 32 | project_open $project_name -revision [get_current_revision $project_name] 33 | } else { 34 | project_open $project_name -revision $revision 35 | } 36 | } else { 37 | post_message -type error "Project $project_name does not exist" 38 | exit 39 | } 40 | 41 | set device [get_global_assignment -name DEVICE] 42 | set outpath [get_global_assignment -name PROJECT_OUTPUT_DIRECTORY] 43 | 44 | if [is_project_open] { 45 | project_close 46 | } 47 | 48 | createChainDescriptionFile $revision $device $outpath $project_name 49 | -------------------------------------------------------------------------------- /platform/pocket/build_id_gen.tcl: -------------------------------------------------------------------------------- 1 | # ================================================================================ 2 | # (c) 2011 Altera Corporation. All rights reserved. 3 | # Altera products are protected under numerous U.S. and foreign patents, maskwork 4 | # rights, copyrights and other intellectual property laws. 5 | # 6 | # This reference design file, and your use thereof, is subject to and governed 7 | # by the terms and conditions of the applicable Altera Reference Design License 8 | # Agreement (either as signed by you, agreed by you upon download or as a 9 | # "click-through" agreement upon installation andor found at www.altera.com). 10 | # By using this reference design file, you indicate your acceptance of such terms 11 | # and conditions between you and Altera Corporation. In the event that you do 12 | # not agree with such terms and conditions, you may not use the reference design 13 | # file and please promptly destroy any copies you have made. 14 | # 15 | # This reference design file is being provided on an "as-is" basis and as an 16 | # accommodation and therefore all warranties, representations or guarantees of 17 | # any kind (whether express, implied or statutory) including, without limitation, 18 | # warranties of merchantability, non-infringement, or fitness for a particular 19 | # purpose, are specifically disclaimed. By making this reference design file 20 | # available, Altera expressly does not recommend, suggest or require that this 21 | # reference design file be used in combination with any other product not 22 | # provided by Altera. 23 | # ================================================================================ 24 | # 25 | # Build ID Verilog Module Script 26 | # Jeff Wiencrot - 8/1/2011 27 | # 28 | # Generates a Verilog module that contains a timestamp, physical address, and host name 29 | # from the current build. These values are available from the build_date, build_time, 30 | # physical_address, and host_name output ports of the build_id module in the build_id.v 31 | # Verilog source file. 32 | # 33 | # The format for each value is as follows: 34 | # Date - 32-bit decimal number of the format mmddyyyy 35 | # Time - 32-bit decimal number of the format hhmmss 36 | # Phyiscal Address - 48-bit hexadecimal number 37 | # Host name - 120-bit hexadecimal number with pairs of digits equal to the 38 | # hexadecimal code for the first 15 ASCII characters of the host 39 | # name. For added clarity, host names that have fewer than 30 40 | # hexadecimal digits (15 characters) are padded on the left with 41 | # zeros. 42 | # 43 | # Usage: 44 | # 45 | # To manually execute this script, source this file using the following Tcl commands: 46 | # source build_id_verilog.tcl 47 | # 48 | # To have this script automatically execute each time your project is built, use the 49 | # following command (see: http://www.altera.com/support/examples/tcl/auto_processing.html): 50 | # set_global_assignment -name PRE_FLOW_SCRIPT_FILE quartus_sh:build_id_verilog.tcl 51 | # 52 | # Comment out the last line to prevent the process from automatically executing when 53 | # the file is sourced. The process can then be executed with the following command: 54 | # generateBuildID_Verilog 55 | # 56 | # 57 | # For more information, see "build_identification.pdf" 58 | # 59 | # ================================================================================ 60 | # 61 | # 2021-01-21 Analogue 62 | # 63 | # Only care about generating build date/time, so the rest was removed. 64 | # The original can be downloaded from the Intel resource page 65 | # 66 | 67 | proc generateBuildID_Verilog {} { 68 | 69 | # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html) 70 | set buildDate [ clock format [ clock seconds ] -format %Y%m%d ] 71 | set buildTime [ clock format [ clock seconds ] -format %H%M%S ] 72 | 73 | # Create a Verilog file for output 74 | set outputFileName "../platform/pocket/build_id.v" 75 | set outputFile [open $outputFileName "w"] 76 | 77 | # Output the Verilog source 78 | puts $outputFile "// Build ID Verilog Module" 79 | puts $outputFile "//" 80 | puts $outputFile "// Note - these are stored as binary coded decimal" 81 | puts $outputFile "// Date: $buildDate" 82 | puts $outputFile "// Time: $buildTime" 83 | puts $outputFile "" 84 | puts $outputFile "module build_id" 85 | puts $outputFile "(" 86 | puts $outputFile " output \[31:0\] build_date," 87 | puts $outputFile " output \[31:0\] build_time" 88 | puts $outputFile ");" 89 | puts $outputFile "" 90 | puts $outputFile " assign build_date = 32'h$buildDate;" 91 | puts $outputFile " assign build_time = 32'h$buildTime;" 92 | puts $outputFile "" 93 | puts $outputFile "endmodule" 94 | close $outputFile 95 | 96 | 97 | 98 | # Send confirmation message to the Messages window 99 | #post_message "APF core build date/time generated: [pwd]/$outputFileName" 100 | #post_message "Date: $buildDate" 101 | #post_message "Time: $buildTime" 102 | } 103 | 104 | 105 | proc generateBuildID_MIF {} { 106 | 107 | # Get the timestamp (see: http://www.altera.com/support/examples/tcl/tcl-date-time-stamp.html) 108 | set buildDate [ clock format [ clock seconds ] -format %Y%m%d ] 109 | set buildTime [ clock format [ clock seconds ] -format %H%M%S ] 110 | set buildUnique [expr {int(rand()*(4294967295))}] 111 | 112 | set buildDateNoLeadingZeros [string trimleft $buildDate "0"] 113 | set buildTimeNoLeadingZeros [string trimleft $buildTime "0"] 114 | set buildDate4Byte [format "%08d" $buildDateNoLeadingZeros] 115 | set buildTime4Byte [format "%08d" $buildTimeNoLeadingZeros] 116 | set buildUnique4Byte [format "%08x" $buildUnique] 117 | 118 | #set buildDate4Byte \ 119 | [concat [string range $buildDate 0 1] \ 120 | [string range $buildDate 2 3] \ 121 | [string range $buildDate 4 5] \ 122 | [string range $buildDate 6 7] ] 123 | 124 | 125 | set buildDateNumBytes 4 126 | set buildTimeNumBytes 4 127 | 128 | # Calculate depth of the memory (8-bit) words 129 | set memoryDepth [expr $buildDateNumBytes + $buildTimeNumBytes] 130 | 131 | # Create a Memory Initialization File for output 132 | set outputFileName "../platform/pocket/build_id.mif" 133 | set outputFile [open $outputFileName "w"] 134 | 135 | # Output the MIF header (see: http://quartushelp.altera.com/current/mergedProjects/reference/glossary/def_mif.htm) 136 | puts $outputFile "-- Build ID Memory Initialization File" 137 | puts $outputFile "--" 138 | puts $outputFile "" 139 | puts $outputFile "DEPTH = 256;" 140 | puts $outputFile "WIDTH = 32;" 141 | puts $outputFile "ADDRESS_RADIX = HEX;" 142 | puts $outputFile "DATA_RADIX = HEX;" 143 | puts $outputFile "" 144 | puts $outputFile "CONTENT" 145 | puts $outputFile "BEGIN" 146 | puts $outputFile "" 147 | puts $outputFile " 0E0 : $buildDate4Byte;" 148 | puts $outputFile " 0E1 : $buildTime4Byte;" 149 | puts $outputFile " 0E2 : $buildUnique4Byte;" 150 | puts $outputFile "" 151 | puts $outputFile "END;" 152 | 153 | # Close file to complete write 154 | close $outputFile 155 | 156 | # Send confirmation message to the Messages window 157 | post_message "APF core build date/time generated: [pwd]/$outputFileName" 158 | } 159 | 160 | generateBuildID_MIF 161 | 162 | # 2021-01-21 Analogue 163 | # 164 | # There are some circumstances where you want all parts of a FPGA flow to be deterministic, especially 165 | # when trying to hash out timing issues. 166 | # You should comment this line out and temporarily bypass buildid generation so that synthesis/par 167 | # have consistent working input. MIF bram contents like above won't affect the random seed or trigger 168 | # recompilation. 169 | # Don't forget to re-enable before you release. 170 | # 171 | # generateBuildID_Verilog 172 | -------------------------------------------------------------------------------- /platform/pocket/common.v: -------------------------------------------------------------------------------- 1 | // Software License Agreement 2 | 3 | // The software supplied herewith by Analogue Enterprises Limited (the "Company”), 4 | // the Analogue Pocket Framework (“APF”), is provided and licensed to you, the 5 | // Company's customer, solely for use in designing, testing and creating 6 | // applications for use with Company's Products or Services. The software is 7 | // owned by the Company and/or its licensors, and is protected under applicable 8 | // laws, including, but not limited to, U.S. copyright law. All rights are 9 | // reserved. By using the APF code you are agreeing to the terms of the End User 10 | // License Agreement (“EULA”) located at [https://www.analogue.link/pocket-eula] 11 | // and incorporated herein by reference. 12 | 13 | // THE SOFTWARE IS PROVIDED "AS-IS" AND WE EXPRESSLY DISCLAIM ANY IMPLIED 14 | // WARRANTIES TO THE FULLEST EXTENT PROVIDED BY LAW, INCLUDING BUT NOT LIMITED TO, 15 | // ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE OR 16 | // NON-INFRINGEMENT. TO THE EXTENT APPLICABLE LAWS PROHIBIT TERMS OF USE FROM 17 | // DISCLAIMING ANY IMPLIED WARRANTY, SUCH IMPLIED WARRANTY SHALL BE LIMITED TO THE 18 | // MINIMUM WARRANTY PERIOD REQUIRED BY LAW, AND IF NO SUCH PERIOD IS REQUIRED, 19 | // THEN THIRTY (30) DAYS FROM FIRST USE OF THE SOFTWARE. WE CANNOT GUARANTEE AND 20 | // DO NOT PROMISE ANY SPECIFIC RESULTS FROM USE OF THE SOFTWARE. WITHOUT LIMITING 21 | // THE FOREGOING, WE DO NOT WARRANT THAT THE SOFTWARE WILL BE UNINTERRUPTED OR 22 | // ERROR-FREE. IN NO EVENT WILL WE BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY 23 | // INDIRECT, CONSEQUENTIAL, EXEMPLARY, INCIDENTAL, SPECIAL OR PUNITIVE DAMAGES, 24 | // INCLUDING BUT NOT LIMITED TO, LOST PROFITS ARISING OUT OF YOUR USE, OR 25 | // INABILITY TO USE, THE SOFTWARE, EVEN IF WE HAVE BEEN ADVISED OF THE POSSIBILITY 26 | // OF SUCH DAMAGES. UNDER NO CIRCUMSTANCES SHALL OUR LIABILITY TO YOU FOR ANY 27 | // CLAIM OR CAUSE OF ACTION WHATSOEVER, AND REGARDLESS OF THE FORM OF THE ACTION, 28 | // WHETHER ARISING IN CONTRACT, TORT OR OTHERWISE, EXCEED THE AMOUNT PAID BY YOU 29 | // TO US, IF ANY, DURING THE 90 DAY PERIOD IMMEDIATELY PRECEDING THE DATE ON WHICH 30 | // YOU FIRST ASSERT ANY SUCH CLAIM. THE FOREGOING LIMITATIONS SHALL APPLY TO THE 31 | // FULLEST EXTENT PERMITTED BY APPLICABLE LAW. 32 | // 33 | // 2-stage synchronizer 34 | // 35 | module synch_2 #(parameter WIDTH = 1) ( 36 | input wire [WIDTH-1:0] i, // input signal 37 | output reg [WIDTH-1:0] o, // synchronized output 38 | input wire clk, // clock to synchronize on 39 | output wire rise, // one-cycle rising edge pulse 40 | output wire fall // one-cycle falling edge pulse 41 | ); 42 | 43 | reg [WIDTH-1:0] stage_1; 44 | reg [WIDTH-1:0] stage_2; 45 | reg [WIDTH-1:0] stage_3; 46 | 47 | assign rise = (WIDTH == 1) ? (o & ~stage_2) : 1'b0; 48 | assign fall = (WIDTH == 1) ? (~o & stage_2) : 1'b0; 49 | always @(posedge clk) 50 | {stage_2, o, stage_1} <= {o, stage_1, i}; 51 | 52 | endmodule 53 | 54 | 55 | // 56 | // 3-stage synchronizer 57 | // 58 | module synch_3 #(parameter WIDTH = 1) ( 59 | input wire [WIDTH-1:0] i, // input signal 60 | output reg [WIDTH-1:0] o, // synchronized output 61 | input wire clk, // clock to synchronize on 62 | output wire rise, // one-cycle rising edge pulse 63 | output wire fall // one-cycle falling edge pulse 64 | ); 65 | 66 | reg [WIDTH-1:0] stage_1; 67 | reg [WIDTH-1:0] stage_2; 68 | reg [WIDTH-1:0] stage_3; 69 | 70 | assign rise = (WIDTH == 1) ? (o & ~stage_3) : 1'b0; 71 | assign fall = (WIDTH == 1) ? (~o & stage_3) : 1'b0; 72 | always @(posedge clk) 73 | {stage_3, o, stage_2, stage_1} <= {o, stage_2, stage_1, i}; 74 | 75 | endmodule 76 | 77 | 78 | module bram_block_dp #( 79 | parameter DATA = 32, 80 | parameter ADDR = 7 81 | ) ( 82 | input wire a_clk, 83 | input wire a_wr, 84 | input wire [ADDR-1:0] a_addr, 85 | input wire [DATA-1:0] a_din, 86 | output reg [DATA-1:0] a_dout, 87 | 88 | input wire b_clk, 89 | input wire b_wr, 90 | input wire [ADDR-1:0] b_addr, 91 | input wire [DATA-1:0] b_din, 92 | output reg [DATA-1:0] b_dout 93 | ); 94 | 95 | reg [DATA-1:0] mem [(2**ADDR)-1:0]; 96 | 97 | always @(posedge a_clk) begin 98 | if(a_wr) begin 99 | a_dout <= a_din; 100 | mem[a_addr] <= a_din; 101 | end else 102 | a_dout <= mem[a_addr]; 103 | end 104 | 105 | always @(posedge b_clk) begin 106 | if(b_wr) begin 107 | b_dout <= b_din; 108 | mem[b_addr] <= b_din; 109 | end else 110 | b_dout <= mem[b_addr]; 111 | end 112 | 113 | endmodule 114 | 115 | 116 | module bram_block_dp_nonstd #( 117 | parameter DATA = 32, 118 | parameter ADDR = 7, 119 | parameter DEPTH = 128 120 | ) ( 121 | input wire a_clk, 122 | input wire a_wr, 123 | input wire [ADDR-1:0] a_addr, 124 | input wire [DATA-1:0] a_din, 125 | output reg [DATA-1:0] a_dout, 126 | 127 | input wire b_clk, 128 | input wire b_wr, 129 | input wire [ADDR-1:0] b_addr, 130 | input wire [DATA-1:0] b_din, 131 | output reg [DATA-1:0] b_dout 132 | ); 133 | 134 | reg [DATA-1:0] mem [DEPTH-1:0]; 135 | 136 | always @(posedge a_clk) begin 137 | if(a_wr) begin 138 | a_dout <= a_din; 139 | mem[a_addr] <= a_din; 140 | end else 141 | a_dout <= mem[a_addr]; 142 | end 143 | 144 | always @(posedge b_clk) begin 145 | if(b_wr) begin 146 | b_dout <= b_din; 147 | mem[b_addr] <= b_din; 148 | end else 149 | b_dout <= mem[b_addr]; 150 | end 151 | 152 | endmodule 153 | -------------------------------------------------------------------------------- /platform/pocket/mf_datatable.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT" 2 | set_global_assignment -name IP_TOOL_VERSION "18.1" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "mf_datatable.v"] 5 | -------------------------------------------------------------------------------- /platform/pocket/mf_ddio_bidir_12.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTDDIO_BIDIR" 2 | set_global_assignment -name IP_TOOL_VERSION "18.1" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "mf_ddio_bidir_12.v"] 5 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "mf_ddio_bidir_12.ppf"] 6 | -------------------------------------------------------------------------------- /platform/pocket/mf_ddio_bidir_12.v: -------------------------------------------------------------------------------- 1 | // megafunction wizard: %ALTDDIO_BIDIR% 2 | // GENERATION: STANDARD 3 | // VERSION: WM1.0 4 | // MODULE: ALTDDIO_BIDIR 5 | 6 | // ============================================================ 7 | // File Name: mf_ddio_bidir_12.v 8 | // Megafunction Name(s): 9 | // ALTDDIO_BIDIR 10 | // 11 | // Simulation Library Files(s): 12 | // altera_mf 13 | // ============================================================ 14 | // ************************************************************ 15 | // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! 16 | // 17 | // 18.1.1 Build 646 04/11/2019 SJ Lite Edition 18 | // ************************************************************ 19 | 20 | 21 | //Copyright (C) 2019 Intel Corporation. All rights reserved. 22 | //Your use of Intel Corporation's design tools, logic functions 23 | //and other software and tools, and any partner logic 24 | //functions, and any output files from any of the foregoing 25 | //(including device programming or simulation files), and any 26 | //associated documentation or information are expressly subject 27 | //to the terms and conditions of the Intel Program License 28 | //Subscription Agreement, the Intel Quartus Prime License Agreement, 29 | //the Intel FPGA IP License Agreement, or other applicable license 30 | //agreement, including, without limitation, that your use is for 31 | //the sole purpose of programming logic devices manufactured by 32 | //Intel and sold by Intel or its authorized distributors. Please 33 | //refer to the applicable agreement for further details, at 34 | //https://fpgasoftware.intel.com/eula. 35 | 36 | 37 | // synopsys translate_off 38 | `timescale 1 ps / 1 ps 39 | // synopsys translate_on 40 | module mf_ddio_bidir_12 ( 41 | datain_h, 42 | datain_l, 43 | inclock, 44 | oe, 45 | outclock, 46 | dataout_h, 47 | dataout_l, 48 | padio); 49 | 50 | input [11:0] datain_h; 51 | input [11:0] datain_l; 52 | input inclock; 53 | input oe; 54 | input outclock; 55 | output [11:0] dataout_h; 56 | output [11:0] dataout_l; 57 | inout [11:0] padio; 58 | 59 | wire [11:0] sub_wire0; 60 | wire [11:0] sub_wire1; 61 | wire [11:0] dataout_h = sub_wire0[11:0]; 62 | wire [11:0] dataout_l = sub_wire1[11:0]; 63 | 64 | altddio_bidir ALTDDIO_BIDIR_component ( 65 | .datain_h (datain_h), 66 | .datain_l (datain_l), 67 | .inclock (inclock), 68 | .oe (oe), 69 | .outclock (outclock), 70 | .padio (padio), 71 | .dataout_h (sub_wire0), 72 | .dataout_l (sub_wire1), 73 | .aclr (1'b0), 74 | .aset (1'b0), 75 | .combout (), 76 | .dqsundelayedout (), 77 | .inclocken (1'b1), 78 | .oe_out (), 79 | .outclocken (1'b1), 80 | .sclr (1'b0), 81 | .sset (1'b0)); 82 | defparam 83 | ALTDDIO_BIDIR_component.extend_oe_disable = "OFF", 84 | ALTDDIO_BIDIR_component.implement_input_in_lcell = "OFF", 85 | ALTDDIO_BIDIR_component.intended_device_family = "Cyclone V", 86 | ALTDDIO_BIDIR_component.invert_output = "OFF", 87 | ALTDDIO_BIDIR_component.lpm_hint = "UNUSED", 88 | ALTDDIO_BIDIR_component.lpm_type = "altddio_bidir", 89 | ALTDDIO_BIDIR_component.oe_reg = "UNREGISTERED", 90 | ALTDDIO_BIDIR_component.power_up_high = "OFF", 91 | ALTDDIO_BIDIR_component.width = 12; 92 | 93 | 94 | endmodule 95 | 96 | // ============================================================ 97 | // CNX file retrieval info 98 | // ============================================================ 99 | // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all 100 | // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V" 101 | // Retrieval info: CONSTANT: EXTEND_OE_DISABLE STRING "OFF" 102 | // Retrieval info: CONSTANT: IMPLEMENT_INPUT_IN_LCELL STRING "OFF" 103 | // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V" 104 | // Retrieval info: CONSTANT: INVERT_OUTPUT STRING "OFF" 105 | // Retrieval info: CONSTANT: LPM_HINT STRING "UNUSED" 106 | // Retrieval info: CONSTANT: LPM_TYPE STRING "altddio_bidir" 107 | // Retrieval info: CONSTANT: OE_REG STRING "UNREGISTERED" 108 | // Retrieval info: CONSTANT: POWER_UP_HIGH STRING "OFF" 109 | // Retrieval info: CONSTANT: WIDTH NUMERIC "12" 110 | // Retrieval info: USED_PORT: datain_h 0 0 12 0 INPUT NODEFVAL "datain_h[11..0]" 111 | // Retrieval info: CONNECT: @datain_h 0 0 12 0 datain_h 0 0 12 0 112 | // Retrieval info: USED_PORT: datain_l 0 0 12 0 INPUT NODEFVAL "datain_l[11..0]" 113 | // Retrieval info: CONNECT: @datain_l 0 0 12 0 datain_l 0 0 12 0 114 | // Retrieval info: USED_PORT: dataout_h 0 0 12 0 OUTPUT NODEFVAL "dataout_h[11..0]" 115 | // Retrieval info: CONNECT: dataout_h 0 0 12 0 @dataout_h 0 0 12 0 116 | // Retrieval info: USED_PORT: dataout_l 0 0 12 0 OUTPUT NODEFVAL "dataout_l[11..0]" 117 | // Retrieval info: CONNECT: dataout_l 0 0 12 0 @dataout_l 0 0 12 0 118 | // Retrieval info: USED_PORT: inclock 0 0 0 0 INPUT_CLK_EXT NODEFVAL "inclock" 119 | // Retrieval info: CONNECT: @inclock 0 0 0 0 inclock 0 0 0 0 120 | // Retrieval info: USED_PORT: oe 0 0 0 0 INPUT NODEFVAL "oe" 121 | // Retrieval info: CONNECT: @oe 0 0 0 0 oe 0 0 0 0 122 | // Retrieval info: USED_PORT: outclock 0 0 0 0 INPUT_CLK_EXT NODEFVAL "outclock" 123 | // Retrieval info: CONNECT: @outclock 0 0 0 0 outclock 0 0 0 0 124 | // Retrieval info: USED_PORT: padio 0 0 12 0 BIDIR NODEFVAL "padio[11..0]" 125 | // Retrieval info: CONNECT: padio 0 0 12 0 @padio 0 0 12 0 126 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.v TRUE FALSE 127 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.qip TRUE FALSE 128 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.bsf FALSE TRUE 129 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12_inst.v FALSE TRUE 130 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12_bb.v FALSE TRUE 131 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.inc FALSE TRUE 132 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.cmp FALSE TRUE 133 | // Retrieval info: GEN_FILE: TYPE_NORMAL mf_ddio_bidir_12.ppf TRUE FALSE 134 | // Retrieval info: LIB_FILE: altera_mf 135 | -------------------------------------------------------------------------------- /projects/gberet_pocket.qip: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # Platform Specific Modules 3 | # ============================================================================== 4 | set_global_assignment -name QIP_FILE "../modules/general-sync_fifo/index.qip" 5 | set_global_assignment -name QIP_FILE "../modules/pocket-i2s/index.qip" 6 | set_global_assignment -name QIP_FILE "../modules/pocket-joypad/index.qip" 7 | set_global_assignment -name QIP_FILE "../modules/pocket-dataloader/index.qip" 8 | set_global_assignment -name QIP_FILE "../modules/pocket-video/index.qip" -------------------------------------------------------------------------------- /projects/gberet_pocket.qpf: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # Quartus Prime Project File 3 | # Generated by OpenGateware - Gateman CLI v0.1.0 4 | # ============================================================================== 5 | 6 | QUARTUS_VERSION = "18.1" 7 | DATE = "04:05:32 September 25, 2022" 8 | 9 | # Revisions 10 | 11 | PROJECT_REVISION = "gberet_pocket" 12 | -------------------------------------------------------------------------------- /projects/gberet_pocket.qsf: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # Quartus Prime Settings File 3 | # Generated by OpenGateware - Gateman CLI v0.1.0 4 | # ============================================================================== 5 | # WARNING: DO NOT ADD FILES TO THE PROJECT VIA THE QUARTUS IDE! 6 | # Add them manually to gberet_pocket.qip or Quartus will overwrite this file. 7 | # ============================================================================== 8 | # Project Assignments 9 | # ============================================================================== 10 | set_global_assignment -name ORIGINAL_QUARTUS_VERSION 18.1.1 11 | set_global_assignment -name LAST_QUARTUS_VERSION "17.1.0 Standard Edition" 12 | set_global_assignment -name TOP_LEVEL_ENTITY apf_top 13 | set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top 14 | set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top 15 | set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top 16 | set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files 17 | set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL 18 | set_global_assignment -name OPTIMIZATION_MODE "HIGH PERFORMANCE EFFORT" 19 | set_global_assignment -name SAVE_DISK_SPACE OFF 20 | set_global_assignment -name SEED 1 21 | set_global_assignment -name SMART_RECOMPILE ON 22 | set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP ON 23 | set_global_assignment -name MUX_RESTRUCTURE OFF 24 | set_global_assignment -name OPTIMIZATION_TECHNIQUE SPEED 25 | set_global_assignment -name PRE_MAPPING_RESYNTHESIS ON 26 | set_global_assignment -name SAFE_STATE_MACHINE ON 27 | set_global_assignment -name SYNTH_PROTECT_SDC_CONSTRAINT ON 28 | set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_100MHZ 29 | set_global_assignment -name CRC_ERROR_OPEN_DRAIN ON 30 | set_global_assignment -name ECO_OPTIMIZE_TIMING ON 31 | set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 256 32 | set_global_assignment -name FITTER_EFFORT "AUTO FIT" 33 | set_global_assignment -name PERIPHERY_TO_CORE_PLACEMENT_AND_ROUTING_OPTIMIZATION ON 34 | set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING ON 35 | set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC ON 36 | set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION ON 37 | set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING ON 38 | set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS ON 39 | set_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION ON 40 | set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "PASSIVE SERIAL" 41 | 42 | # ============================================================================== 43 | # Platform Specific 44 | # ============================================================================== 45 | set_global_assignment -name QIP_FILE gberet_pocket.qip 46 | set_global_assignment -name SDC_FILE gberet_pocket.sdc 47 | 48 | # ============================================================================== 49 | # File Assignments 50 | # ============================================================================== 51 | source ../platform/pocket/pocket.tcl 52 | set_global_assignment -name QIP_FILE ../rtl/gberet.qip 53 | 54 | set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top -------------------------------------------------------------------------------- /projects/gberet_pocket.sdc: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # Quartus Prime Synopsys Design Constraint File 3 | # Generated by OpenGateware - Gateman CLI v0.1.0 4 | # ============================================================================== 5 | # pocket SDC settings 6 | # Users are recommended to modify this file to match users logic. 7 | # Put your clock groups in here as well as any net assignments. 8 | # ============================================================================== 9 | 10 | # ============================================================================== 11 | # Time Information 12 | # ============================================================================== 13 | 14 | # ============================================================================== 15 | # Create Clock 16 | # ============================================================================== 17 | 18 | # ============================================================================== 19 | # Create Generated Clock 20 | # ============================================================================== 21 | 22 | # ============================================================================== 23 | # Set Clock Latency 24 | # ============================================================================== 25 | 26 | # ============================================================================== 27 | # Set Clock Uncertainty 28 | # ============================================================================== 29 | 30 | # ============================================================================== 31 | # Set Input Delay 32 | # ============================================================================== 33 | 34 | # ============================================================================== 35 | # Set Output Delay 36 | # ============================================================================== 37 | 38 | # ============================================================================== 39 | # Set Clock Groups 40 | # ============================================================================== 41 | 42 | # ============================================================================== 43 | # Set False Path 44 | # ============================================================================== 45 | 46 | # ============================================================================== 47 | # Set Multicycle Path 48 | # ============================================================================== 49 | 50 | # ============================================================================== 51 | # Set Maximum Delay 52 | # ============================================================================== 53 | 54 | # ============================================================================== 55 | # Set Minimum Delay 56 | # ============================================================================== 57 | 58 | # ============================================================================== 59 | # Set Input Transition 60 | # ============================================================================== 61 | 62 | -------------------------------------------------------------------------------- /rtl/DPRAM1024_4.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT" 2 | set_global_assignment -name IP_TOOL_VERSION "18.0" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "DPRAM1024_4.v"] 5 | -------------------------------------------------------------------------------- /rtl/DPRAMs.v: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | // SPDX-FileType: SOURCE 4 | // SPDX-FileCopyrightText: (c) 2013-2019 MiSTer-X 5 | //------------------------------------------------------------------------------ 6 | // FPGA Implimentation of "Green Beret" (Dual-Port RAM for VIDEO) 7 | //------------------------------------------------------------------------------ 8 | 9 | module VRAM4096 10 | ( 11 | input cl, 12 | input [11:0] ad, 13 | input en, 14 | input wr, 15 | input [7:0] id, 16 | output reg [7:0] od, 17 | 18 | input clv, 19 | input [11:0] adv, 20 | output reg [7:0] odv 21 | ); 22 | 23 | reg [7:0] core [0:4095]; 24 | 25 | always @( posedge cl ) begin 26 | if (en) begin 27 | if (wr) 28 | core[ad] <= id; 29 | else 30 | od <= core[ad]; 31 | end 32 | end 33 | 34 | always @( posedge clv ) begin 35 | odv <= core[adv]; 36 | end 37 | 38 | endmodule 39 | 40 | module VRAM2048 41 | ( 42 | input cl, 43 | input [10:0] ad, 44 | input en, 45 | input wr, 46 | input [7:0] id, 47 | output reg [7:0] od, 48 | 49 | input clv, 50 | input [10:0] adv, 51 | output reg [7:0] odv 52 | ); 53 | 54 | reg [7:0] core [0:2047]; 55 | 56 | always @( posedge cl ) begin 57 | if (en) begin 58 | if (wr) 59 | core[ad] <= id; 60 | else 61 | od <= core[ad]; 62 | end 63 | end 64 | 65 | always @( posedge clv ) begin 66 | odv <= core[adv]; 67 | end 68 | 69 | endmodule 70 | 71 | module VRAM32 72 | ( 73 | input cl, 74 | input [4:0] ad, 75 | input en, 76 | input wr, 77 | input [7:0] id, 78 | output reg [7:0] od, 79 | 80 | input clv, 81 | input [4:0] adv, 82 | output reg [7:0] odv 83 | ); 84 | 85 | reg [7:0] core [0:31]; 86 | 87 | always @( posedge cl ) begin 88 | if (en) begin 89 | if (wr) 90 | core[ad] <= id; 91 | else 92 | od <= core[ad]; 93 | end 94 | end 95 | 96 | always @( posedge clv ) begin 97 | odv <= core[adv]; 98 | end 99 | 100 | endmodule 101 | 102 | module LineBuf 103 | ( 104 | input WCL, 105 | input WEN, 106 | input [9:0] WAD, 107 | input [3:0] WDT, 108 | 109 | input RCL, 110 | input RWE, 111 | input [9:0] RAD, 112 | output [3:0] RDT 113 | ); 114 | 115 | wire [3:0] dum; 116 | 117 | DPRAM1024_4 ramcore 118 | ( 119 | WAD, RAD, 120 | WCL, RCL, 121 | WDT, 4'h0, 122 | WEN, RWE, 123 | dum, RDT 124 | ); 125 | 126 | endmodule 127 | -------------------------------------------------------------------------------- /rtl/GreenBeret.v: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | // SPDX-FileType: SOURCE 4 | // SPDX-FileCopyrightText: (c) 2013-2019 MiSTer-X 5 | //------------------------------------------------------------------------------ 6 | // FPGA Implimentation of "Green Beret" (Top Module) 7 | //------------------------------------------------------------------------------ 8 | 9 | module FPGA_GreenBeret 10 | ( 11 | input clk48M, 12 | input reset, 13 | 14 | input [5:0] INP0, // Control Panel 15 | input [5:0] INP1, 16 | input [3:0] INP2, 17 | 18 | input [7:0] DSW0, // DipSWs 19 | input [7:0] DSW1, 20 | input [7:0] DSW2, 21 | 22 | 23 | input [8:0] PH, // PIXEL H 24 | input [8:0] PV, // PIXEL V 25 | output PCLK, // PIXEL CLOCK (to VGA encoder) 26 | output [11:0] POUT, // PIXEL OUT 27 | 28 | output [7:0] SND, // Sound Out 29 | 30 | input ROMCL, // Downloaded ROM image 31 | input [17:0] ROMAD, 32 | input [7:0] ROMDT, 33 | input ROMEN, 34 | 35 | input [7:0] title, 36 | input pause, 37 | 38 | input [15:0] hs_address, 39 | input [7:0] hs_data_in, 40 | output [7:0] hs_data_out, 41 | input hs_write, 42 | input hs_access 43 | ); 44 | 45 | // Clocks 46 | wire clk24M, clk12M, clk6M, clk3M; 47 | CLKGEN clks(clk48M, pause, clk24M, clk12M, clk6M, clk3M); 48 | 49 | wire VCLKx8 = clk48M; 50 | wire VCLKx4 = clk24M; 51 | wire VCLKx2 = clk12M; 52 | wire VCLK = clk6M; 53 | 54 | wire CPUCLK = clk3M; 55 | wire CPUCL = ~clk3M; 56 | 57 | // Main 58 | wire CPUMX, CPUWR, VIDDV; 59 | wire [7:0] CPUWD, VIDRD; 60 | wire [15:0] CPUAD; 61 | 62 | MAIN cpu 63 | ( 64 | CPUCLK, reset, 65 | PH,PV, 66 | INP0,INP1,INP2, 67 | DSW0,DSW1,DSW2, 68 | 69 | CPUMX, CPUAD, 70 | CPUWR, CPUWD, 71 | VIDDV, VIDRD, 72 | 73 | ROMCL,ROMAD,ROMDT,ROMEN, 74 | 75 | title, 76 | pause 77 | ); 78 | 79 | 80 | // Video 81 | VIDEO vid ( 82 | .VCLKx8 ( VCLKx8 ), 83 | .VCLKx4 ( VCLKx4 ), 84 | .VCLKx2 ( VCLKx2 ), 85 | .VCLK ( VCLK ), 86 | .HP ( PH ), 87 | .VP ( PV ), 88 | .PALD ( 1'b0 ), 89 | .CPUD ( 1'b0 ), 90 | .PCLK ( PCLK ), 91 | .POUT ( POUT ), 92 | .CPUCL ( CPUCL ), 93 | .CPUMX ( CPUMX ), 94 | .CPUAD ( CPUAD ), 95 | .CPUWR ( CPUWR ), 96 | .CPUWD ( CPUWD ), 97 | .CPUDV ( VIDDV ), 98 | .CPURD ( VIDRD ), 99 | .DLCL ( ROMCL ), 100 | .DLAD ( ROMAD ), 101 | .DLDT ( ROMDT ), 102 | .DLEN ( ROMEN ), 103 | .hs_address ( hs_address ), 104 | .hs_data_in ( hs_data_in ), 105 | .hs_data_out ( hs_data_out ), 106 | .hs_write ( hs_write ), 107 | .hs_access ( hs_access ) 108 | ); 109 | 110 | // Sound 111 | SOUND snd ( 112 | .dacclk ( clk48M ), 113 | .reset ( reset ), 114 | .SNDOUT ( SND ), 115 | .CPUCL ( CPUCL ), 116 | .CPUMX ( CPUMX ), 117 | .CPUAD ( CPUAD ), 118 | .CPUWR ( CPUWR ), 119 | .CPUWD ( CPUWD ), 120 | .pause ( pause ) 121 | ); 122 | 123 | endmodule 124 | 125 | //---------------------------------- 126 | // Clock Generator 127 | //---------------------------------- 128 | module CLKGEN 129 | ( 130 | input clk48M, 131 | input pause, 132 | 133 | output clk24M, 134 | output clk12M, 135 | output clk6M, 136 | output clk3M 137 | ); 138 | 139 | reg [3:0] clkdiv; 140 | 141 | always @( posedge clk48M ) begin 142 | clkdiv <= clkdiv+4'd1; 143 | end 144 | 145 | assign clk24M = clkdiv[0]; 146 | assign clk12M = clkdiv[1]; 147 | assign clk6M = clkdiv[2]; 148 | assign clk3M = clkdiv[3]; 149 | 150 | endmodule 151 | -------------------------------------------------------------------------------- /rtl/GreenBeret_MAIN.v: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | // SPDX-FileType: SOURCE 4 | // SPDX-FileCopyrightText: (c) 2013-2019 MiSTer-X 5 | //------------------------------------------------------------------------------ 6 | // FPGA Implimentation of "Green Beret" (Main Part) 7 | //------------------------------------------------------------------------------ 8 | 9 | module MAIN 10 | ( 11 | input CPUCL, 12 | input RESET, 13 | 14 | input [8:0] PH, 15 | input [8:0] PV, 16 | 17 | input [5:0] INP0, 18 | input [5:0] INP1, 19 | input [3:0] INP2, 20 | 21 | input [7:0] DSW0, 22 | input [7:0] DSW1, 23 | input [7:0] DSW2, 24 | 25 | output CPUMX, 26 | output [15:0] CPUAD, 27 | output CPUWR, 28 | output [7:0] CPUWD, 29 | 30 | input VIDDV, 31 | input [7:0] VIDRD, 32 | 33 | 34 | input DLCL, 35 | input [17:0] DLAD, 36 | input [7:0] DLDT, 37 | input DLEN, 38 | 39 | input [3:0] title, 40 | input pause 41 | ); 42 | 43 | // 44 | // Z80 SoftCore 45 | // 46 | wire [7:0] CPUID; 47 | wire cpu_irq, cpu_nmi; 48 | wire iCPUMX, iCPUWR; 49 | 50 | T80s z80( 51 | .CLK(CPUCL), 52 | .RESET_n(~RESET), 53 | .A(CPUAD), 54 | .DI(CPUID), 55 | .DO(CPUWD), 56 | .INT_n(~cpu_irq), 57 | .NMI_n(~cpu_nmi), 58 | .MREQ_n(iCPUMX), 59 | .WR_n(iCPUWR), 60 | .BUSRQ_n(1'b1), 61 | .WAIT_n(~pause) 62 | ); 63 | 64 | assign CPUMX = ~iCPUMX; 65 | assign CPUWR = ~iCPUWR; 66 | 67 | // Instruction ROMs (Banked) 68 | wire [2:0] ROMBK; 69 | wire [7:0] ROMDT; 70 | wire ROMDV; 71 | 72 | MAIN_ROM 73 | irom( 74 | .CL ( ~CPUCL ), 75 | .MX ( CPUMX ), 76 | .AD ( CPUAD ), 77 | .BK ( ROMBK ), 78 | .DV ( ROMDV ), 79 | .DT ( ROMDT ), 80 | .DLCL ( DLCL ), 81 | .DLAD ( DLAD ), 82 | .DLDT ( DLDT ), 83 | .DLEN ( DLEN ) 84 | ); 85 | 86 | // Input Ports (HID & DIPSWs) 87 | wire CS_ISYS = (CPUAD[15:0] == 16'hF603) & CPUMX; 88 | wire CS_IP01 = (CPUAD[15:0] == 16'hF602) & CPUMX; 89 | wire CS_IP02 = (CPUAD[15:0] == 16'hF601) & CPUMX; 90 | wire CS_DSW2 = (CPUAD[15:0] == 16'hF600) & CPUMX; 91 | wire CS_DSW0 = (CPUAD[15:8] == 8'hF2 ) & CPUMX; 92 | wire CS_DSW1 = (CPUAD[15:8] == 8'hF4 ) & CPUMX; 93 | 94 | `include "HIDDEF.vh" 95 | 96 | wire [7:0] ISYS = ~{`none,`none,`none,`P2ST,`P1ST,`none,`COIN2,`COIN1}; 97 | wire [7:0] IP01 = ~{`none,`none,`P1TB,`P1TA,`P1DW,`P1UP,`P1RG,`P1LF}; 98 | wire [7:0] IP02 = ~{`none,`none,`P2TB,`P2TA,`P2DW,`P2UP,`P2RG,`P2LF}; 99 | 100 | // 101 | // CPU Input Data Selector 102 | // 103 | DSEL9 dsel( 104 | CPUID, 105 | VIDDV,VIDRD, 106 | ROMDV,ROMDT, 107 | CS_ISYS,ISYS, 108 | CS_IP01,IP01, 109 | CS_IP02,IP02, 110 | CS_DSW0,DSW0, 111 | CS_DSW1,DSW1, 112 | CS_DSW2,DSW2 113 | ); 114 | 115 | 116 | // 117 | // Interrupt Generator & ROM Bank Selector 118 | // 119 | IRQGEN irqg( 120 | RESET,PH,PV, 121 | CPUCL,CPUAD,CPUWD,CPUMX & CPUWR, 122 | cpu_irq,cpu_nmi, 123 | ROMBK, 124 | title 125 | ); 126 | 127 | 128 | endmodule 129 | 130 | module IRQGEN 131 | ( 132 | input RESET, 133 | input [8:0] PH, 134 | input [8:0] PV, 135 | 136 | input CPUCL, 137 | input [15:0] CPUAD, 138 | input [7:0] CPUWD, 139 | input CPUWE, 140 | 141 | output reg cpu_irq, 142 | output reg cpu_nmi, 143 | 144 | output reg [2:0] ROMBK, 145 | 146 | input [3:0] title 147 | ); 148 | 149 | wire CS_FSCW = (CPUAD[15:0] == 16'hE044) & CPUWE; 150 | wire CS_CCTW = (CPUAD[15:0] == 16'hF000) & CPUWE; 151 | 152 | reg [2:0] irqmask; 153 | reg [8:0] tick; 154 | wire [8:0] irqs = (~tick) & (tick+9'd1); 155 | reg [8:0] pPV; 156 | reg sync; 157 | 158 | always @( negedge CPUCL ) begin 159 | if (RESET) begin 160 | ROMBK <= 0; 161 | irqmask <= 0; 162 | cpu_nmi <= 0; 163 | cpu_irq <= 0; 164 | tick <= 0; 165 | pPV <= 1; 166 | sync <= 1; 167 | end 168 | else begin 169 | if ( CS_CCTW ) 170 | ROMBK <= CPUWD[7:5]; 171 | if ( CS_FSCW ) begin 172 | irqmask <= CPUWD[2:0]; 173 | if (~CPUWD[0]) 174 | cpu_nmi <= 0; 175 | if (~CPUWD[1]) 176 | cpu_irq <= 0; 177 | else if (~CPUWD[2]) 178 | cpu_irq <= 0; 179 | end 180 | else if (pPV != PV) begin 181 | if (PV[3:0]==0) begin 182 | // Mitigate screen tearing by initializing tick value 183 | if (sync & (PV==9'd0)) begin 184 | tick <= (title == 2) ? 24 : 48; 185 | sync <= 0; 186 | end 187 | else 188 | tick <= (tick+9'd1); 189 | 190 | cpu_nmi <= irqs[0] & irqmask[0]; 191 | cpu_irq <=(irqs[3] & irqmask[1]) | (irqs[4] & irqmask[2]); 192 | pPV <= PV; 193 | end 194 | end 195 | end 196 | end 197 | 198 | endmodule 199 | 200 | module DSEL9 201 | ( 202 | output [7:0] out, 203 | input en0, input [7:0] in0, 204 | input en1, input [7:0] in1, 205 | input en2, input [7:0] in2, 206 | input en3, input [7:0] in3, 207 | input en4, input [7:0] in4, 208 | input en5, input [7:0] in5, 209 | input en6, input [7:0] in6, 210 | input en7, input [7:0] in7, 211 | input en8, input [7:0] in8 212 | ); 213 | 214 | assign out = en0 ? in0 : 215 | en1 ? in1 : 216 | en2 ? in2 : 217 | en3 ? in3 : 218 | en4 ? in4 : 219 | en5 ? in5 : 220 | en6 ? in6 : 221 | en7 ? in7 : 222 | en8 ? in8 : 223 | 8'h00; 224 | 225 | endmodule 226 | -------------------------------------------------------------------------------- /rtl/GreenBeret_SOUND.v: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | // SPDX-FileType: SOURCE 4 | // SPDX-FileCopyrightText: (c) 2013-2019 MiSTer-X 5 | //------------------------------------------------------------------------------ 6 | // FPGA Implimentation of "Green Beret" (Sound Part) 7 | //------------------------------------------------------------------------------ 8 | 9 | module SOUND 10 | ( 11 | input dacclk, 12 | input reset, 13 | 14 | output [7:0] SNDOUT, 15 | 16 | input CPUCL, 17 | input CPUMX, 18 | input [15:0] CPUAD, 19 | input CPUWR, 20 | input [7:0] CPUWD, 21 | input pause 22 | ); 23 | 24 | wire CS_SNDLC = ( CPUAD[15:8] == 8'hF2 ) & CPUMX & CPUWR; 25 | wire CS_SNDWR = ( CPUAD[15:8] == 8'hF4 ) & CPUMX; 26 | 27 | reg [7:0] SNDLATCH; 28 | always @( posedge CPUCL or posedge reset ) 29 | begin 30 | if (reset) 31 | SNDLATCH <= 0; 32 | else 33 | begin 34 | if ( CS_SNDLC ) 35 | SNDLATCH <= CPUWD; 36 | end 37 | end 38 | 39 | wire sndclk; 40 | sndclkgen scgen( dacclk, sndclk ); 41 | 42 | 43 | wire [3:0] sndmask = pause ? 4'b0000 : 4'b1111; 44 | SN76496 sgn( sndclk, CPUCL, reset, CS_SNDWR, CPUWR, SNDLATCH, sndmask, SNDOUT ); 45 | 46 | endmodule 47 | 48 | /** 49 | * Clock Generator 50 | * in: 50000000Hz -> out: 1600000Hz 51 | */ 52 | module sndclkgen( input in, output reg out ); 53 | reg [6:0] count; 54 | always @( posedge in ) 55 | begin 56 | if (count > 7'd117) 57 | begin 58 | count <= count - 7'd117; 59 | out <= ~out; 60 | end 61 | else 62 | count <= count + 7'd8; 63 | end 64 | endmodule 65 | -------------------------------------------------------------------------------- /rtl/GreenBeret_VIDEO.v: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | // SPDX-FileType: SOURCE 4 | // SPDX-FileCopyrightText: (c) 2013-2019 MiSTer-X 5 | //------------------------------------------------------------------------------ 6 | // FPGA Implimentation of "Green Beret" (Video Part) 7 | //------------------------------------------------------------------------------ 8 | 9 | module VIDEO 10 | ( 11 | input VCLKx8, 12 | input VCLKx4, 13 | input VCLKx2, 14 | input VCLK, 15 | 16 | input [8:0] HP, 17 | input [8:0] VP, 18 | 19 | input PALD, 20 | input CPUD, 21 | 22 | output PCLK, 23 | output [11:0] POUT, 24 | 25 | input CPUCL, 26 | input CPUMX, 27 | input [15:0] CPUAD, 28 | input CPUWR, 29 | input [7:0] CPUWD, 30 | output CPUDV, 31 | output [7:0] CPURD, 32 | 33 | 34 | input DLCL, 35 | input [17:0] DLAD, 36 | input [7:0] DLDT, 37 | input DLEN, 38 | 39 | input [15:0] hs_address, 40 | input [7:0] hs_data_in, 41 | output [7:0] hs_data_out, 42 | input hs_write, 43 | input hs_access 44 | ); 45 | 46 | // Video RAMs 47 | wire CS_CRAM = ( CPUAD[15:11] == 5'b1100_0 ) & CPUMX; // $C000-$C7FF 48 | wire CS_VRAM = ( CPUAD[15:11] == 5'b1100_1 ) & CPUMX; // $C800-$CFFF 49 | wire CS_MRAM = ( CPUAD[15:12] == 4'b1101 ) & CPUMX; // $D000-$DFFF 50 | wire CS_ZRM0 = ( CPUAD[15: 5] == 11'b1110_0000_000 ) & CPUMX; // $E000-$E01F 51 | wire CS_ZRM1 = ( CPUAD[15: 5] == 11'b1110_0000_001 ) & CPUMX; // $E020-$E03F 52 | wire CS_SPRB = ( CPUAD[15: 0] == 16'b1110_0000_0100_0011 ) & CPUMX; // $E043 53 | 54 | wire [7:0] OD_CRAM, OD_VRAM; 55 | wire [7:0] OD_MRAM; 56 | wire [7:0] OD_ZRM0, OD_ZRM1; 57 | 58 | assign CPUDV = CS_CRAM | CS_VRAM | CS_MRAM | CS_ZRM0 | CS_ZRM1 ; 59 | 60 | assign CPURD = CS_CRAM ? OD_CRAM : 61 | CS_VRAM ? OD_VRAM : 62 | CS_MRAM ? OD_MRAM : 63 | CS_ZRM0 ? OD_ZRM0 : 64 | CS_ZRM1 ? OD_ZRM1 : 65 | 8'h0; 66 | 67 | wire [10:0] BGVA; 68 | wire [7:0] BGCR, BGVR; 69 | 70 | reg SPRB; 71 | wire [7:0] SATA; 72 | wire [7:0] SATD; 73 | wire [11:0] SAAD = {3'b000,SPRB,SATA}; 74 | 75 | always @( posedge CPUCL ) 76 | if ( CS_SPRB & CPUWR ) 77 | SPRB <= ~CPUWD[3]; 78 | 79 | wire [4:0] ZRMA; 80 | wire [7:0] ZRM0, ZRM1; 81 | wire [15:0] ZRMD = {ZRM1,ZRM0}; 82 | 83 | // Hiscore mux 84 | wire mram_clk = hs_access ? DLCL : CPUCL; 85 | wire [11:0] mram_addr = hs_access ? hs_address[11:0] : CPUAD[11:0]; 86 | wire mram_cs = hs_access ? 1'b1 : CS_MRAM; 87 | wire mram_we = hs_access ? hs_write : CPUWR; 88 | wire [7:0] mram_di = hs_access ? hs_data_in : CPUWD; 89 | wire [7:0] mram_do; 90 | 91 | assign OD_MRAM = hs_access ? 8'b0 : mram_do; 92 | assign hs_data_out = hs_access ? mram_do : 8'b0; 93 | 94 | VRAM2048 cram( CPUCL, CPUAD[10:0], CS_CRAM, CPUWR, CPUWD, OD_CRAM, VCLKx4, BGVA, BGCR ); 95 | VRAM2048 vram( CPUCL, CPUAD[10:0], CS_VRAM, CPUWR, CPUWD, OD_VRAM, VCLKx4, BGVA, BGVR ); 96 | VRAM4096 mram( mram_clk, mram_addr, mram_cs, mram_we, mram_di, mram_do,~VCLKx8, SAAD, SATD ); 97 | VRAM32 zrm0( CPUCL, CPUAD[ 4:0], CS_ZRM0, CPUWR, CPUWD, OD_ZRM0, VCLKx4, ZRMA, ZRM0 ); 98 | VRAM32 zrm1( CPUCL, CPUAD[ 4:0], CS_ZRM1, CPUWR, CPUWD, OD_ZRM1, VCLKx4, ZRMA, ZRM1 ); 99 | 100 | // BG Scanline Generator 101 | wire [8:0] BGVP = VP+9'd16; 102 | wire [8:0] BGHP = HP+9'd8+(ZRMD[8:0]); 103 | 104 | assign ZRMA = BGVP[7:3]; 105 | assign BGVA = {BGVP[7:3],BGHP[8:3]}; 106 | wire [8:0] BGCH = {BGCR[6],BGVR}; 107 | wire [3:0] BGCL = BGCR[3:0]; 108 | wire [1:0] BGFL = BGCR[5:4]; 109 | 110 | wire [2:0] BGHH = BGHP[2:0]^{3{BGFL[0]}}; 111 | wire [2:0] BGVV = BGVP[2:0]^{3{BGFL[1]}}; 112 | wire [13:0] BGCA = {BGCH,BGVV[2:0],BGHH[2:1]}; 113 | wire [0:7] BGCD; 114 | BGCHIP_ROM bgchip( VCLKx2, BGCA, BGCD, DLCL,DLAD,DLDT,DLEN ); 115 | 116 | wire [7:0] BGCT = {BGCL,(BGHH[0] ? BGCD[4:7]:BGCD[0:3])}; 117 | wire [3:0] BGPT; 118 | BGCLUT_ROM bgclut( ~VCLK, BGCT, BGPT, DLCL,DLAD,DLDT,DLEN ); 119 | 120 | reg BGHI; 121 | always @( negedge VCLK ) BGHI <= ~BGCR[7]; 122 | 123 | // Sprite Scanline Generator 124 | wire [8:0] SPHP = HP+9'd9; 125 | wire [8:0] SPVP = VP+9'd18; 126 | wire [3:0] SPPT; 127 | SPRRENDER spr( VCLKx8,VCLK, SPHP,SPVP,SATA,SATD, SPPT, DLCL,DLAD,DLDT,DLEN ); 128 | 129 | // Color Mixer 130 | wire [4:0] COLMIX = (BGHI & (|BGPT)) ? {1'b1,BGPT} : (|SPPT) ? {1'b0,SPPT} : {1'b1,BGPT}; 131 | 132 | // Palette 133 | wire [4:0] PALIN = PALD ? VP[6:2] : COLMIX; 134 | wire [7:0] PALET; 135 | PALET_ROM palet( VCLK, PALIN, PALET, DLCL,DLAD,DLDT,DLEN ); 136 | wire [7:0] PALOT = PALD ? ( (|VP[8:7]) ? 8'h0 : PALET ) : PALET; 137 | 138 | // Pixel Output 139 | assign PCLK = ~VCLK; 140 | assign POUT = {PALOT[7:6],2'b00,PALOT[5:3],1'b0,PALOT[2:0],1'b0}; 141 | 142 | endmodule 143 | 144 | 145 | //---------------------------------- 146 | // Sprite Render 147 | //---------------------------------- 148 | module SPRRENDER 149 | ( 150 | input VCLKx8, 151 | input VCLK, 152 | 153 | input [8:0] SPHP, 154 | input [8:0] SPVP, 155 | 156 | output [7:0] SATA, 157 | input [7:0] SATD, 158 | 159 | output reg [3:0] SPPT, 160 | 161 | 162 | input DLCL, 163 | input [17:0] DLAD, 164 | input [7:0] DLDT, 165 | input DLEN 166 | ); 167 | 168 | reg [5:0] sano; 169 | reg [1:0] saof; 170 | reg [7:0] sat0, sat1, sat2, sat3; 171 | 172 | reg [2:0] phase; 173 | 174 | wire [8:0] px = {1'b0,sat2} - {sat1[7],8'h0}; 175 | wire [7:0] py = (phase==1) ? SATD : sat3; 176 | wire fx = sat1[4]; 177 | wire fy = sat1[5]; 178 | wire [8:0] code = {sat1[6],sat0}; 179 | wire [3:0] color = sat1[3:0]; 180 | 181 | wire [8:0] ht = {1'b0,py}-SPVP; 182 | wire hy = (py!=0) & (ht[8:4]==5'b11111); 183 | 184 | reg [4:0] xcnt; 185 | wire [3:0] lx = xcnt[3:0]^{4{ fx}}; 186 | wire [3:0] ly = ht[3:0]^{4{~fy}}; 187 | 188 | wire [15:0] SPCA = {code,ly[3],lx[3],ly[2:0],lx[2:1]}; 189 | wire [0:7] SPCD; 190 | SPCHIP_ROM spchip( ~VCLKx8, SPCA, SPCD, DLCL,DLAD,DLDT,DLEN ); 191 | 192 | wire [7:0] pix = {color,(lx[0] ? SPCD[4:7]:SPCD[0:3])}; 193 | 194 | 195 | `define SPRITES 8'h30 196 | 197 | always @( posedge VCLKx8 ) 198 | begin 199 | if (SPHP==0) 200 | begin 201 | xcnt <= 0; 202 | sano <= 0; 203 | saof <= 3; 204 | phase <= 1; 205 | end 206 | else 207 | case (phase) 208 | 0: /* empty */ ; 209 | 1: 210 | begin 211 | if (sano >= `SPRITES) 212 | phase <= 0; 213 | else 214 | begin 215 | if (hy) 216 | begin 217 | sat3 <= SATD; 218 | saof <= 2; 219 | phase <= phase+3'd1; 220 | end 221 | else 222 | sano <= sano+6'd1; 223 | end 224 | end 225 | 2: 226 | begin 227 | sat2 <= SATD; 228 | saof <= 1; 229 | phase <= phase+3'd1; 230 | end 231 | 3: 232 | begin 233 | sat1 <= SATD; 234 | saof <= 0; 235 | phase <= phase+3'd1; 236 | end 237 | 4: 238 | begin 239 | sat0 <= SATD; 240 | saof <= 3; 241 | sano <= sano+6'd1; 242 | xcnt <= 5'b1_0000; 243 | phase <= phase+3'd1; 244 | end 245 | 5: 246 | begin 247 | xcnt <= xcnt+5'd1; 248 | phase <= wre ? phase : 3'd1; 249 | end 250 | default: ; 251 | endcase 252 | end 253 | 254 | assign SATA = {sano,saof}; 255 | 256 | wire wre = xcnt[4]; 257 | wire sid = SPVP[0]; 258 | wire [8:0] wpx = px+xcnt[3:0]; 259 | 260 | // CLUT 261 | reg [9:0] lbad; 262 | reg [3:0] lbdt; 263 | reg lbwe; 264 | always @(posedge VCLKx8) 265 | begin 266 | lbad <= {~sid,wpx}; 267 | lbwe <= wre; 268 | end 269 | wire [3:0] opix; 270 | SPCLUT_ROM spclut(VCLKx8, pix, opix, DLCL,DLAD,DLDT,DLEN ); 271 | always @(negedge VCLKx8) lbdt <= opix; 272 | 273 | // Line-Buffer 274 | reg [9:0] radr0=0,radr1=1; 275 | wire [3:0] ispt; 276 | always @(negedge VCLK) radr0 <= {sid,SPHP}; 277 | always @(posedge VCLK) 278 | begin 279 | if (radr0!=radr1) 280 | SPPT <= ispt; 281 | radr1 <= radr0; 282 | end 283 | LineBuf lbuf(VCLKx8,lbwe & (lbdt!=0),lbad,lbdt, VCLKx8,(radr0==radr1),radr0,ispt); 284 | 285 | endmodule 286 | -------------------------------------------------------------------------------- /rtl/HIDDEF.vh: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | // SPDX-FileType: SOURCE 4 | // SPDX-FileCopyrightText: (c) 2013-2019 MiSTer-X 5 | //------------------------------------------------------------------------------ 6 | 7 | `ifndef __HID_DEFINITION 8 | `define __HID_DEFINITION 9 | 10 | `define none 1'b0 11 | 12 | `define COIN2 INP2[3] 13 | `define COIN1 INP2[2] 14 | `define P1ST INP2[0] 15 | `define P2ST INP2[1] 16 | 17 | `define P1UP INP0[0] 18 | `define P1DW INP0[2] 19 | `define P1LF INP0[3] 20 | `define P1RG INP0[1] 21 | `define P1TA INP0[4] 22 | `define P1TB INP0[5] 23 | 24 | `define P2UP INP1[0] 25 | `define P2DW INP1[2] 26 | `define P2LF INP1[3] 27 | `define P2RG INP1[1] 28 | `define P2TA INP1[4] 29 | `define P2TB INP1[5] 30 | 31 | `endif 32 | -------------------------------------------------------------------------------- /rtl/HVGEN.v: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | // SPDX-FileType: SOURCE 4 | // SPDX-FileCopyrightText: (c) 2013-2019 MiSTer-X 5 | //------------------------------------------------------------------------------ 6 | // FPGA Implimentation of "Green Beret" (Video Timing Part) 7 | //------------------------------------------------------------------------------ 8 | module HVGEN 9 | ( 10 | input iPCLK, 11 | output [8:0] HPOS, 12 | output [8:0] VPOS, 13 | input [11:0] iRGB, 14 | 15 | output reg [11:0] oRGB, 16 | output reg HBLK = 0, 17 | output reg VBLK = 0, 18 | output reg HSYN = 1, 19 | output reg VSYN = 1, 20 | output reg oBLKN, 21 | 22 | input signed [4:0] HOFFS, 23 | input signed [3:0] VOFFS 24 | ); 25 | 26 | // 396x256. V-sync: 60.(60)Hz, H-Sync 15.(51)KHz, Pixel Clock: 6.144MHz 27 | 28 | localparam [8:0] width = 396; 29 | 30 | reg [8:0] hcnt = 0; 31 | reg [7:0] vcnt = 0; 32 | 33 | assign HPOS = hcnt-9'd24; 34 | assign VPOS = vcnt; 35 | 36 | wire [8:0] HS_B = 320 + HOFFS; 37 | wire [8:0] HS_E = 31 + HS_B; 38 | 39 | wire [8:0] VS_B = 226 + VOFFS; 40 | wire [8:0] VS_E = 5 + VS_B; 41 | 42 | 43 | always @(posedge iPCLK) begin 44 | if (hcnt < width-1) 45 | hcnt <= hcnt+9'd1; 46 | else begin 47 | vcnt <= vcnt+9'd1; 48 | hcnt <= 0; 49 | end 50 | HBLK <= (hcnt < 25) | (hcnt >= 265); 51 | HSYN <= (hcnt >= HS_B) & (hcnt < HS_E); 52 | VBLK <= (vcnt >= 224) & (vcnt < 256); 53 | VSYN <= (vcnt >= VS_B) & (vcnt < VS_E); 54 | oRGB <= (HBLK|VBLK) ? 12'h0 : iRGB; 55 | oBLKN <= ~(HBLK|VBLK); 56 | end 57 | 58 | endmodule 59 | -------------------------------------------------------------------------------- /rtl/ROMS.v: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // SPDX-License-Identifier: GPL-3.0-or-later 3 | // SPDX-FileType: SOURCE 4 | // SPDX-FileCopyrightText: (c) 2013-2019 MiSTer-X 5 | //------------------------------------------------------------------------------ 6 | // FPGA Implimentation of "Green Beret" (ROMS part) 7 | //------------------------------------------------------------------------------ 8 | 9 | module DLROM #( 10 | parameter AW, 11 | parameter DW 12 | ) ( 13 | input CL0, 14 | input [(AW-1):0] AD0, 15 | output reg [(DW-1):0] DO0, 16 | 17 | input CL1, 18 | input [(AW-1):0] AD1, 19 | input [(DW-1):0] DI1, 20 | input WE1 21 | ); 22 | 23 | reg [(DW-1):0] core[0:((2**AW)-1)]; 24 | 25 | always @(posedge CL0) 26 | DO0 <= core[AD0]; 27 | always @(posedge CL1) 28 | if (WE1) 29 | core[AD1] <= DI1; 30 | 31 | endmodule 32 | 33 | module MAIN_ROM 34 | ( 35 | input CL, 36 | input MX, 37 | input [15:0] AD, 38 | input [2:0] BK, 39 | output DV, 40 | output [7:0] DT, 41 | 42 | input DLCL, 43 | input [17:0] DLAD, 44 | input [7:0] DLDT, 45 | input DLEN 46 | ); 47 | 48 | wire [14:0] AD1 = (AD[15:11] == 5'b11111) ? {1'b1,BK,AD[10:0]} : {1'b0,AD[13:0]}; 49 | 50 | wire [7:0] DT0, DT1; 51 | DLROM #(15,8) r0(CL,AD[14:0],DT0, DLCL,DLAD,DLDT,DLEN & (DLAD[17:15]==3'b00_0)); 52 | DLROM #(15,8) r1(CL, AD1,DT1, DLCL,DLAD,DLDT,DLEN & (DLAD[17:15]==3'b00_1)); 53 | 54 | assign DV = ((AD[15:11] == 5'b11111)|(AD[15:14] != 2'b11)) & MX; 55 | assign DT = AD[15] ? DT1 : DT0; 56 | 57 | endmodule 58 | 59 | module SPCHIP_ROM 60 | ( 61 | input CL, 62 | input [15:0] AD, 63 | output [7:0] DT, 64 | 65 | input DLCL, 66 | input [17:0] DLAD, 67 | input [7:0] DLDT, 68 | input DLEN 69 | ); 70 | DLROM #(16,8) r(CL,AD,DT, DLCL,DLAD,DLDT,DLEN & (DLAD[17:16]==2'b01)); 71 | endmodule 72 | 73 | module BGCHIP_ROM 74 | ( 75 | input CL, 76 | input [13:0] AD, 77 | output [7:0] DT, 78 | 79 | input DLCL, 80 | input [17:0] DLAD, 81 | input [7:0] DLDT, 82 | input DLEN 83 | ); 84 | DLROM #(14,8) r(CL,AD,DT, DLCL,DLAD,DLDT,DLEN & (DLAD[17:14]==4'b10_00)); 85 | endmodule 86 | 87 | module SPCLUT_ROM 88 | ( 89 | input CL, 90 | input [7:0] AD, 91 | output [7:0] DT, 92 | 93 | input DLCL, 94 | input [17:0] DLAD, 95 | input [7:0] DLDT, 96 | input DLEN 97 | ); 98 | DLROM #(8,8) r(CL,AD,DT, DLCL,DLAD,DLDT,DLEN & (DLAD[17:8]==10'b10_0100_0000)); 99 | endmodule 100 | 101 | module BGCLUT_ROM 102 | ( 103 | input CL, 104 | input [7:0] AD, 105 | output [7:0] DT, 106 | 107 | input DLCL, 108 | input [17:0] DLAD, 109 | input [7:0] DLDT, 110 | input DLEN 111 | ); 112 | DLROM #(8,8) r(CL,AD,DT, DLCL,DLAD,DLDT,DLEN & (DLAD[17:8]==10'b10_0100_0001)); 113 | endmodule 114 | 115 | module PALET_ROM 116 | ( 117 | input CL, 118 | input [4:0] AD, 119 | output [7:0] DT, 120 | 121 | input DLCL, 122 | input [17:0] DLAD, 123 | input [7:0] DLDT, 124 | input DLEN 125 | ); 126 | DLROM #(5,8) r(CL,AD,DT, DLCL,DLAD,DLDT,DLEN & (DLAD[17:5]==13'b10_0100_0010_000)); 127 | endmodule 128 | -------------------------------------------------------------------------------- /rtl/gberet.qip: -------------------------------------------------------------------------------- 1 | # ============================================================================== 2 | # RTL 3 | # ============================================================================== 4 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "DPRAM1024_4.qip"] 5 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "DPRAMs.v"] 6 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "GreenBeret.v"] 7 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "GreenBeret_MAIN.v"] 8 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "GreenBeret_SOUND.v"] 9 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "GreenBeret_VIDEO.v"] 10 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "HVGEN.v"] 11 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "ROMS.v"] 12 | 13 | # ============================================================================== 14 | # MODULES 15 | # ============================================================================== 16 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "../modules/cpu-t80/index.qip"] 17 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "../modules/sound-sn76496/index.qip"] 18 | -------------------------------------------------------------------------------- /target/pocket/core.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name SYSTEMVERILOG_FILE [file join $::quartus(qip_path) "core_top.sv"] 2 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "core_bridge_cmd.v"] 3 | set_global_assignment -name SDC_FILE [file join $::quartus(qip_path) "core_constraints.sdc"] 4 | set_global_assignment -name QIP_FILE [file join $::quartus(qip_path) "mf_pllbase.qip"] 5 | set_global_assignment -name SIGNALTAP_FILE [file join $::quartus(qip_path) "stp1.stp"] 6 | -------------------------------------------------------------------------------- /target/pocket/core_constraints.sdc: -------------------------------------------------------------------------------- 1 | # 2 | # user core constraints 3 | # 4 | # put your clock groups in here as well as any net assignments 5 | # 6 | 7 | set_clock_groups -asynchronous \ 8 | -group { bridge_spiclk } \ 9 | -group { clk_74a } \ 10 | -group { clk_74b } \ 11 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[0].gpll~PLL_OUTPUT_COUNTER|divclk } \ 12 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[1].gpll~PLL_OUTPUT_COUNTER|divclk } \ 13 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[2].gpll~PLL_OUTPUT_COUNTER|divclk } \ 14 | -group { ic|mp1|mf_pllbase_inst|altera_pll_i|general[3].gpll~PLL_OUTPUT_COUNTER|divclk } 15 | -------------------------------------------------------------------------------- /target/pocket/mf_pllbase.ppf: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /target/pocket/mf_pllbase/mf_pllbase_0002.qip: -------------------------------------------------------------------------------- 1 | set_instance_assignment -name PLL_COMPENSATION_MODE NORMAL -to "*mf_pllbase_0002*|altera_pll:altera_pll_i*|*" 2 | set_instance_assignment -name PLL_CHANNEL_SPACING "0.0 KHz" -to "*mf_pllbase_0002*|altera_pll:altera_pll_i*|*" 3 | set_instance_assignment -name PLL_AUTO_RESET OFF -to "*mf_pllbase_0002*|altera_pll:altera_pll_i*|*" 4 | set_instance_assignment -name PLL_BANDWIDTH_PRESET AUTO -to "*mf_pllbase_0002*|altera_pll:altera_pll_i*|*" 5 | -------------------------------------------------------------------------------- /target/pocket/mf_pllbase/mf_pllbase_0002.v: -------------------------------------------------------------------------------- 1 | `timescale 1ns/10ps 2 | module mf_pllbase_0002( 3 | 4 | // interface 'refclk' 5 | input wire refclk, 6 | 7 | // interface 'reset' 8 | input wire rst, 9 | 10 | // interface 'outclk0' 11 | output wire outclk_0, 12 | 13 | // interface 'outclk1' 14 | output wire outclk_1, 15 | 16 | // interface 'outclk2' 17 | output wire outclk_2, 18 | 19 | // interface 'locked' 20 | output wire locked 21 | ); 22 | 23 | altera_pll #( 24 | .fractional_vco_multiplier("true"), 25 | .reference_clock_frequency("74.25 MHz"), 26 | .operation_mode("normal"), 27 | .number_of_clocks(3), 28 | .output_clock_frequency0("49.152000 MHz"), 29 | .phase_shift0("0 ps"), 30 | .duty_cycle0(50), 31 | .output_clock_frequency1("6.144000 MHz"), 32 | .phase_shift1("0 ps"), 33 | .duty_cycle1(50), 34 | .output_clock_frequency2("6.144000 MHz"), 35 | .phase_shift2("40690 ps"), 36 | .duty_cycle2(50), 37 | .output_clock_frequency3("0 MHz"), 38 | .phase_shift3("0 ps"), 39 | .duty_cycle3(50), 40 | .output_clock_frequency4("0 MHz"), 41 | .phase_shift4("0 ps"), 42 | .duty_cycle4(50), 43 | .output_clock_frequency5("0 MHz"), 44 | .phase_shift5("0 ps"), 45 | .duty_cycle5(50), 46 | .output_clock_frequency6("0 MHz"), 47 | .phase_shift6("0 ps"), 48 | .duty_cycle6(50), 49 | .output_clock_frequency7("0 MHz"), 50 | .phase_shift7("0 ps"), 51 | .duty_cycle7(50), 52 | .output_clock_frequency8("0 MHz"), 53 | .phase_shift8("0 ps"), 54 | .duty_cycle8(50), 55 | .output_clock_frequency9("0 MHz"), 56 | .phase_shift9("0 ps"), 57 | .duty_cycle9(50), 58 | .output_clock_frequency10("0 MHz"), 59 | .phase_shift10("0 ps"), 60 | .duty_cycle10(50), 61 | .output_clock_frequency11("0 MHz"), 62 | .phase_shift11("0 ps"), 63 | .duty_cycle11(50), 64 | .output_clock_frequency12("0 MHz"), 65 | .phase_shift12("0 ps"), 66 | .duty_cycle12(50), 67 | .output_clock_frequency13("0 MHz"), 68 | .phase_shift13("0 ps"), 69 | .duty_cycle13(50), 70 | .output_clock_frequency14("0 MHz"), 71 | .phase_shift14("0 ps"), 72 | .duty_cycle14(50), 73 | .output_clock_frequency15("0 MHz"), 74 | .phase_shift15("0 ps"), 75 | .duty_cycle15(50), 76 | .output_clock_frequency16("0 MHz"), 77 | .phase_shift16("0 ps"), 78 | .duty_cycle16(50), 79 | .output_clock_frequency17("0 MHz"), 80 | .phase_shift17("0 ps"), 81 | .duty_cycle17(50), 82 | .pll_type("General"), 83 | .pll_subtype("General") 84 | ) altera_pll_i ( 85 | .rst (rst), 86 | .outclk ({outclk_2, outclk_1, outclk_0}), 87 | .locked (locked), 88 | .fboutclk ( ), 89 | .fbclk (1'b0), 90 | .refclk (refclk) 91 | ); 92 | endmodule 93 | 94 | -------------------------------------------------------------------------------- /target/pocket/pin_ddio_clk.ppf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /target/pocket/pin_ddio_clk.qip: -------------------------------------------------------------------------------- 1 | set_global_assignment -name IP_TOOL_NAME "ALTDDIO_OUT" 2 | set_global_assignment -name IP_TOOL_VERSION "18.1" 3 | set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{Cyclone V}" 4 | set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "pin_ddio_clk.v"] 5 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pin_ddio_clk_inst.v"] 6 | set_global_assignment -name MISC_FILE [file join $::quartus(qip_path) "pin_ddio_clk.ppf"] 7 | -------------------------------------------------------------------------------- /target/pocket/pin_ddio_clk.v: -------------------------------------------------------------------------------- 1 | // megafunction wizard: %ALTDDIO_OUT% 2 | // GENERATION: STANDARD 3 | // VERSION: WM1.0 4 | // MODULE: ALTDDIO_OUT 5 | 6 | // ============================================================ 7 | // File Name: pin_ddio_clk.v 8 | // Megafunction Name(s): 9 | // ALTDDIO_OUT 10 | // 11 | // Simulation Library Files(s): 12 | // altera_mf 13 | // ============================================================ 14 | // ************************************************************ 15 | // THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE! 16 | // 17 | // 18.1.1 Build 646 04/11/2019 SJ Lite Edition 18 | // ************************************************************ 19 | 20 | 21 | //Copyright (C) 2019 Intel Corporation. All rights reserved. 22 | //Your use of Intel Corporation's design tools, logic functions 23 | //and other software and tools, and any partner logic 24 | //functions, and any output files from any of the foregoing 25 | //(including device programming or simulation files), and any 26 | //associated documentation or information are expressly subject 27 | //to the terms and conditions of the Intel Program License 28 | //Subscription Agreement, the Intel Quartus Prime License Agreement, 29 | //the Intel FPGA IP License Agreement, or other applicable license 30 | //agreement, including, without limitation, that your use is for 31 | //the sole purpose of programming logic devices manufactured by 32 | //Intel and sold by Intel or its authorized distributors. Please 33 | //refer to the applicable agreement for further details, at 34 | //https://fpgasoftware.intel.com/eula. 35 | 36 | 37 | // synopsys translate_off 38 | `timescale 1 ps / 1 ps 39 | // synopsys translate_on 40 | module pin_ddio_clk ( 41 | datain_h, 42 | datain_l, 43 | outclock, 44 | dataout); 45 | 46 | input [0:0] datain_h; 47 | input [0:0] datain_l; 48 | input outclock; 49 | output [0:0] dataout; 50 | 51 | wire [0:0] sub_wire0; 52 | wire [0:0] dataout = sub_wire0[0:0]; 53 | 54 | altddio_out ALTDDIO_OUT_component ( 55 | .datain_h (datain_h), 56 | .datain_l (datain_l), 57 | .outclock (outclock), 58 | .dataout (sub_wire0), 59 | .aclr (1'b0), 60 | .aset (1'b0), 61 | .oe (1'b1), 62 | .oe_out (), 63 | .outclocken (1'b1), 64 | .sclr (1'b0), 65 | .sset (1'b0)); 66 | defparam 67 | ALTDDIO_OUT_component.extend_oe_disable = "OFF", 68 | ALTDDIO_OUT_component.intended_device_family = "Cyclone V", 69 | ALTDDIO_OUT_component.invert_output = "OFF", 70 | ALTDDIO_OUT_component.lpm_hint = "UNUSED", 71 | ALTDDIO_OUT_component.lpm_type = "altddio_out", 72 | ALTDDIO_OUT_component.oe_reg = "UNREGISTERED", 73 | ALTDDIO_OUT_component.power_up_high = "OFF", 74 | ALTDDIO_OUT_component.width = 1; 75 | 76 | 77 | endmodule 78 | 79 | // ============================================================ 80 | // CNX file retrieval info 81 | // ============================================================ 82 | // Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all 83 | // Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone V" 84 | // Retrieval info: CONSTANT: EXTEND_OE_DISABLE STRING "OFF" 85 | // Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone V" 86 | // Retrieval info: CONSTANT: INVERT_OUTPUT STRING "OFF" 87 | // Retrieval info: CONSTANT: LPM_HINT STRING "UNUSED" 88 | // Retrieval info: CONSTANT: LPM_TYPE STRING "altddio_out" 89 | // Retrieval info: CONSTANT: OE_REG STRING "UNREGISTERED" 90 | // Retrieval info: CONSTANT: POWER_UP_HIGH STRING "OFF" 91 | // Retrieval info: CONSTANT: WIDTH NUMERIC "1" 92 | // Retrieval info: USED_PORT: datain_h 0 0 1 0 INPUT NODEFVAL "datain_h[0..0]" 93 | // Retrieval info: CONNECT: @datain_h 0 0 1 0 datain_h 0 0 1 0 94 | // Retrieval info: USED_PORT: datain_l 0 0 1 0 INPUT NODEFVAL "datain_l[0..0]" 95 | // Retrieval info: CONNECT: @datain_l 0 0 1 0 datain_l 0 0 1 0 96 | // Retrieval info: USED_PORT: dataout 0 0 1 0 OUTPUT NODEFVAL "dataout[0..0]" 97 | // Retrieval info: CONNECT: dataout 0 0 1 0 @dataout 0 0 1 0 98 | // Retrieval info: USED_PORT: outclock 0 0 0 0 INPUT_CLK_EXT NODEFVAL "outclock" 99 | // Retrieval info: CONNECT: @outclock 0 0 0 0 outclock 0 0 0 0 100 | // Retrieval info: GEN_FILE: TYPE_NORMAL pin_ddio_clk.v TRUE FALSE 101 | // Retrieval info: GEN_FILE: TYPE_NORMAL pin_ddio_clk.qip TRUE FALSE 102 | // Retrieval info: GEN_FILE: TYPE_NORMAL pin_ddio_clk.bsf FALSE TRUE 103 | // Retrieval info: GEN_FILE: TYPE_NORMAL pin_ddio_clk_inst.v TRUE TRUE 104 | // Retrieval info: GEN_FILE: TYPE_NORMAL pin_ddio_clk_bb.v FALSE TRUE 105 | // Retrieval info: GEN_FILE: TYPE_NORMAL pin_ddio_clk.inc FALSE TRUE 106 | // Retrieval info: GEN_FILE: TYPE_NORMAL pin_ddio_clk.cmp FALSE TRUE 107 | // Retrieval info: GEN_FILE: TYPE_NORMAL pin_ddio_clk.ppf TRUE FALSE 108 | // Retrieval info: LIB_FILE: altera_mf 109 | --------------------------------------------------------------------------------