1
0
mirror of https://github.com/mist-devel/mist-board.git synced 2026-02-07 00:17:07 +00:00

[Gameboy] Add GBC support

This commit is contained in:
Gyorgy Szombathelyi
2019-02-13 00:42:57 +01:00
parent da29f15118
commit 072f355849
6 changed files with 340 additions and 43 deletions

View File

@@ -187,6 +187,7 @@ set_global_assignment -name VERILOG_FILE sprite.v
set_global_assignment -name VERILOG_FILE sprite_sort.v
set_global_assignment -name VERILOG_FILE timer.v
set_global_assignment -name QIP_FILE boot_rom.qip
set_global_assignment -name QIP_FILE gbc_bios.qip
set_global_assignment -name VHDL_FILE t80/T80.vhd
set_global_assignment -name VHDL_FILE t80/Z80.vhd
set_global_assignment -name VHDL_FILE t80/T80_Reg.vhd

View File

@@ -68,17 +68,19 @@ wire [7:0] joystick_1;
// the configuration string is returned to the io controller to allow
// it to control the menu on the OSD
parameter CONF_STR = {
"GAMEBOY;GB;",
"GAMEBOY;;",
"F,GBCGB ,Load;",
"O1,LCD color,white,yellow;",
"O2,Boot,Normal,Fast;",
"T3,Reset"
};
parameter CONF_STR_LEN = 11+26+20+8;
parameter CONF_STR_LEN = 9+14+26+20+8;
// the status register is controlled by the on screen display (OSD)
wire [7:0] status;
wire [1:0] buttons;
wire isGBC = dio_index[7:6] == 0;
// include user_io module for arm controller communication
user_io #(.STRLEN(CONF_STR_LEN)) user_io (
@@ -145,6 +147,7 @@ wire dio_download;
wire [23:0] dio_addr;
wire [15:0] dio_data;
wire dio_write;
wire [7:0] dio_index;
// TODO: RAM bank
// http://fms.komkon.org/GameBoy/Tech/Carts.html
@@ -202,7 +205,7 @@ wire [3:0] mbc5_ram_bank = mbc_ram_bank_reg & ram_mask;
// in mode 0 (16/8 mode) the ram bank select signals are the upper rom address lines
// in mode 1 (4/32 mode) the upper two rom address lines are 2'b00
wire [6:0] mbc1_rom_bank_mode = { mbc1_mode?2'b00:mbc_ram_bank_reg, mbc_rom_bank_reg};
wire [6:0] mbc1_rom_bank_mode = { mbc1_mode?2'b00:mbc_ram_bank_reg[1:0], mbc_rom_bank_reg[4:0]};
// mask address lines to enable proper mirroring
wire [6:0] mbc1_rom_bank = mbc1_rom_bank_mode & rom_mask[6:0];
wire [3:0] mbc2_rom_bank = mbc_rom_bank_reg[3:0] & rom_mask[3:0]; //16
@@ -265,6 +268,8 @@ end
reg [7:0] cart_mbc_type;
reg [7:0] cart_rom_size;
reg [7:0] cart_ram_size;
reg [7:0] cart_cgb_flag;
wire isGBC_game = (cart_cgb_flag == 8'h80 || cart_cgb_flag == 8'hC0);
// only write sdram if the write attept comes from the cart ram area
wire cart_ram_wr = cart_wr && mbc_ram_enable && ((cart_addr[15:13] == 3'b101 && ~mbc2) || (cart_addr[15:9] == 7'b1010000 && mbc2));
@@ -317,10 +322,12 @@ always @(posedge clk64) begin
cart_mbc_type <= 8'h00;
cart_rom_size <= 8'h00;
cart_ram_size <= 8'h00;
cart_cgb_flag <= 8'h00;
end else begin
if(dio_download && dio_write) begin
// cart is stored in 16 bit wide sdram, so addresses are shifted right
case(dio_addr)
24'h142: cart_cgb_flag <= dio_data[15:8];
24'ha3: cart_mbc_type <= dio_data[7:0]; // $147
24'ha4: { cart_rom_size, cart_ram_size } <= dio_data; // $148/$149
endcase
@@ -340,6 +347,7 @@ data_io data_io (
// external ram interface
.ioctl_clkref ( clk8 ),
.ioctl_index ( dio_index ),
.ioctl_wr ( dio_write ),
.ioctl_addr ( dio_addr ),
.ioctl_dout ( dio_data )
@@ -353,13 +361,22 @@ wire cart_rd;
wire cart_wr;
wire lcd_clkena;
wire [1:0] lcd_data;
wire [14:0] lcd_data;
wire [1:0] lcd_mode;
wire lcd_on;
wire [15:0] audio_left;
wire [15:0] audio_right;
wire [11:0] bios_addr;
wire [7:0] bios_do;
gbc_bios gbc_bios (
.clock ( clk64 ),
.address ( bios_addr ),
.q ( bios_do )
);
// the gameboy itself
gb gb (
.reset ( reset ),
@@ -368,6 +385,8 @@ gb gb (
.fast_boot ( status[2] ),
.joystick ( joystick ),
.isGBC ( isGBC ),
.isGBC_game ( isGBC_game ),
// interface to the "external" game cartridge
.cart_addr ( cart_addr ),
@@ -376,6 +395,10 @@ gb gb (
.cart_do ( cart_do ),
.cart_di ( cart_di ),
//gbc bios interface
.gbc_bios_addr ( bios_addr ),
.gbc_bios_do ( bios_do ),
// audio
.audio_l ( audio_left ),
.audio_r ( audio_right ),
@@ -400,11 +423,12 @@ wire [5:0] video_r, video_g, video_b;
wire video_hs, video_vs;
lcd lcd (
.clk64 ( clk64 ),
.clk ( clk64 ),
.pclk_en( ce_pix ),
.clk ( clk4 ),
.clk4_en( clk4 ),
.tint ( status[1] ),
.isGBC ( isGBC ),
// serial interface
.clkena ( lcd_clkena ),

107
cores/gameboy/gbc_bios.mif Normal file
View File

@@ -0,0 +1,107 @@
-- http://srecord.sourceforge.net/
--
-- Generated automatically by srec_cat -o --mif
--
DEPTH = 2304;
WIDTH = 8;
ADDRESS_RADIX = HEX;
DATA_RADIX = HEX;
CONTENT BEGIN
0000: 31 FE FF 3E 02 C3 7C 00 D3 00 98 A0 12 D3 00 80 00 40 1E 53 D0 00 1F 42;
0018: 1C 00 14 2A 4D 19 8C 7E 00 7C 31 6E 4A 45 52 4A 00 00 FF 53 1F 7C FF 03;
0030: 1F 00 FF 1F A7 00 EF 1B 1F 00 EF 1B 00 7C 00 00 FF 03 CE ED 66 66 CC 0D;
0048: 00 0B 03 73 00 83 00 0C 00 0D 00 08 11 1F 88 89 00 0E DC CC 6E E6 DD DD;
0060: D9 99 BB BB 67 63 6E 0E EC CC DD DC 99 9F BB B9 33 3E 3C 42 B9 A5 B9 A5;
0078: 42 3C 58 43 E0 70 3E FC E0 47 CD 75 02 CD 00 02 26 D0 CD 03 02 21 00 FE;
0090: 0E A0 AF 22 0D 20 FC 11 04 01 21 10 80 4C 1A E2 0C CD C6 03 CD C7 03 13;
00A8: 7B FE 34 20 F1 11 72 00 06 08 1A 13 22 23 05 20 F9 CD F0 03 3E 01 E0 4F;
00C0: 3E 91 E0 40 21 B2 98 06 4E 0E 44 CD 91 02 AF E0 4F 0E 80 21 42 00 06 18;
00D8: F2 0C BE 20 FE 23 05 20 F7 21 34 01 06 19 78 86 2C 05 20 FB 86 20 FE CD;
00F0: 1C 03 18 02 00 00 CD D0 05 AF E0 70 3E 11 E0 50 00 00 00 00 00 00 00 00;
0108: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00;
0120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00;
0138: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00;
0150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00;
0168: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00;
0180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00;
0198: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00;
01B0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00;
01C8: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00;
01E0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00;
01F8: 00 00 00 00 00 00 00 00 21 00 80 AF 22 CB 6C 28 FB C9 2A 12 13 0D 20 FA;
0210: C9 E5 21 0F FF CB 86 CB 46 28 FC E1 C9 11 00 FF 21 03 D0 0E 0F 3E 30 12;
0228: 3E 20 12 1A 2F A1 CB 37 47 3E 10 12 1A 2F A1 B0 4F 7E A9 E6 F0 47 2A A9;
0240: A1 B0 32 47 79 77 3E 30 12 C9 3E 80 E0 68 E0 6A 0E 6B 2A E2 05 20 FB 4A;
0258: 09 43 0E 69 2A E2 05 20 FB C9 C5 D5 E5 21 00 D8 06 01 16 3F 1E 40 CD 4A;
0270: 02 E1 D1 C1 C9 3E 80 E0 26 E0 11 3E F3 E0 12 E0 25 3E 77 E0 24 21 30 FF;
0288: AF 0E 10 22 2F 0D 20 FB C9 CD 11 02 CD 62 02 79 FE 38 20 14 E5 AF E0 4F;
02A0: 21 A7 99 3E 38 22 3C FE 3F 20 FA 3E 01 E0 4F E1 C5 E5 21 43 01 CB 7E CC;
02B8: 89 05 E1 C1 CD 11 02 79 D6 30 D2 06 03 79 FE 01 CA 06 03 7D FE D1 28 21;
02D0: C5 06 03 0E 01 16 03 7E E6 F8 B1 22 15 20 F8 0C 79 FE 06 20 F0 11 11 00;
02E8: 19 05 20 E7 11 A1 FF 19 C1 04 78 1E 83 FE 62 28 06 1E C1 FE 64 20 07 7B;
0300: E0 13 3E 87 E0 14 FA 02 D0 FE 00 28 0A 3D EA 02 D0 79 FE 01 CA 91 02 0D;
0318: C2 91 02 C9 0E 26 CD 4A 03 CD 11 02 CD 62 02 0D 20 F4 CD 11 02 3E 01 E0;
0330: 4F CD 3E 03 CD 41 03 AF E0 4F CD 3E 03 C9 21 08 00 11 51 FF 0E 05 CD 0A;
0348: 02 C9 C5 D5 E5 21 40 D8 0E 20 7E E6 1F FE 1F 28 01 3C 57 2A 07 07 07 E6;
0360: 07 47 3A 07 07 07 E6 18 B0 FE 1F 28 01 3C 0F 0F 0F 47 E6 E0 B2 22 78 E6;
0378: 03 5F 7E 0F 0F E6 1F FE 1F 28 01 3C 07 07 B3 22 0D 20 C7 E1 D1 C1 C9 0E;
0390: 00 1A E6 F0 CB 49 28 02 CB 37 47 23 7E B0 22 1A E6 0F CB 49 20 02 CB 37;
03A8: 47 23 7E B0 22 13 CB 41 28 0D D5 11 F8 FF CB 49 28 03 11 08 00 19 D1 0C;
03C0: 79 FE 18 20 CC C9 47 D5 16 04 58 CB 10 17 CB 13 17 15 20 F6 D1 22 23 22;
03D8: 23 C9 3E 19 EA 10 99 21 2F 99 0E 0C 3D 28 08 32 0D 20 F9 2E 0F 18 F3 C9;
03F0: 3E 01 E0 4F CD 00 02 11 07 06 21 80 80 0E C0 1A 22 23 22 23 13 0D 20 F7;
0408: 11 04 01 CD 8F 03 01 A8 FF 09 CD 8F 03 01 F8 FF 09 11 72 00 0E 08 23 1A;
0420: 22 13 0D 20 F9 21 C2 98 06 08 3E 08 0E 10 22 0D 20 FC 11 10 00 19 05 20;
0438: F3 AF E0 4F 21 C2 98 3E 08 22 3C FE 18 20 02 2E E2 FE 28 20 03 21 02 99;
0450: FE 38 20 ED 21 D8 08 11 40 D8 06 08 3E FF 12 13 12 13 0E 02 CD 0A 02 3E;
0468: 00 12 13 12 13 13 13 05 20 EA CD 62 02 21 4B 01 7E FE 33 20 0B 2E 44 1E;
0480: 30 2A BB 20 49 1C 18 04 2E 4B 1E 01 2A BB 20 3E 2E 34 01 10 00 2A 80 47;
0498: 0D 20 FA EA 00 D0 21 C7 06 0E 00 2A B8 28 08 0C 79 FE 4F 20 F6 18 1F 79;
04B0: D6 41 38 1C 21 16 07 16 00 5F 19 FA 37 01 57 7E BA 28 0D 11 0E 00 19 79;
04C8: 83 4F D6 5E 38 ED 0E 00 21 33 07 06 00 09 7E E6 1F EA 08 D0 7E E6 E0 07;
04E0: 07 07 EA 0B D0 CD E9 04 C9 11 91 07 21 00 D9 FA 0B D0 47 0E 1E CB 40 20;
04F8: 02 13 13 1A 22 20 02 1B 1B CB 48 20 02 13 13 1A 22 13 13 20 02 1B 1B CB;
0510: 50 28 05 1B 2B 1A 22 13 1A 22 13 0D 20 D7 21 00 D9 11 00 DA CD 64 05 C9;
0528: 21 12 00 FA 05 D0 07 07 06 00 4F 09 11 40 D8 06 08 E5 0E 02 CD 0A 02 13;
0540: 13 13 13 13 13 E1 05 20 F0 11 42 D8 0E 02 CD 0A 02 11 4A D8 0E 02 CD 0A;
0558: 02 2B 2B 11 44 D8 0E 02 CD 0A 02 C9 0E 60 2A E5 C5 21 E8 07 06 00 4F 09;
0570: 0E 08 CD 0A 02 C1 E1 0D 20 EC C9 FA 08 D0 11 18 00 3C 3D 28 03 19 20 FA;
0588: C9 CD 1D 02 78 E6 FF 28 0F 21 E4 08 06 00 2A B9 28 08 04 78 FE 0C 20 F6;
05A0: 18 2D 78 EA 05 D0 3E 1E EA 02 D0 11 0B 00 19 56 7A E6 1F 5F 21 08 D0 3A;
05B8: 22 7B 77 7A E6 E0 07 07 07 5F 21 0B D0 3A 22 7B 77 CD E9 04 CD 28 05 C9;
05D0: CD 11 02 FA 43 01 CB 7F 28 04 E0 4C 18 28 3E 04 E0 4C 3E 01 E0 6C 21 00;
05E8: DA CD 7B 05 06 10 16 00 1E 08 CD 4A 02 21 7A 00 FA 00 D0 47 0E 02 2A B8;
0600: CC DA 03 0D 20 F8 C9 01 0F 3F 7E FF FF C0 00 C0 F0 F1 03 7C FC FE FE 03;
0618: 07 07 0F E0 E0 F0 F0 1E 3E 7E FE 0F 0F 1F 1F FF FF 00 00 01 01 01 03 FF;
0630: FF E1 E0 C0 F0 F9 FB 1F 7F F8 E0 F3 FD 3E 1E E0 F0 F9 7F 3E 7C F8 E0 F8;
0648: F0 F0 F8 00 00 7F 7F 07 0F 9F BF 9E 1F FF FF 0F 1E 3E 3C F1 FB 7F 7F FE;
0660: DE DF 9F 1F 3F 3E 3C F8 F8 00 00 03 03 07 07 FF FF C1 C0 F3 E7 F7 F3 C0;
0678: C0 C0 C0 1F 1F 1E 3E 3F 1F 3E 3E 80 00 00 00 7C 1F 07 00 0F FF FE 00 7C;
0690: F8 F0 00 1F 0F 0F 00 7C F8 F8 00 3F 3E 1C 00 0F 0F 0F 00 7C FF FF 00 00;
06A8: F8 F8 00 07 0F 0F 00 81 FF FF 00 F3 E1 80 00 E0 FF 7F 00 FC F0 C0 00 3E;
06C0: 7C 7C 00 00 00 00 00 00 88 16 36 D1 DB F2 3C 8C 92 3D 5C 58 C9 3E 70 1D;
06D8: 59 69 19 35 A8 14 AA 75 95 99 34 6F 15 FF 97 4B 90 17 10 39 F7 F6 A2 49;
06F0: 4E 43 68 E0 8B F0 CE 0C 29 E8 B7 86 9A 52 01 9D;
0700: 71 9C BD 5D 6D 67 3F 6B B3 46 28 A5 C6 D3 27 61 18 66 6A BF 0D F4 42 45;
0718: 46 41 41 52 42 45 4B 45 4B 20 52 2D 55 52 41 52 20 49 4E 41 49 4C 49 43;
0730: 45 20 52 7C 08 12 A3 A2 07 87 4B 20 12 65 A8 16 A9 86 B1 68 A0 87 66 12;
0748: A1 30 3C 12 85 12 64 1B 07 06 6F 6E 6E AE AF 6F B2 AF B2 A8 AB 6F AF 86;
0760: AE A2 A2 12 AF 13 12 A1 6E AF AF AD 06 4C 6E AF AF 12 7C AC A8 6A 6E 13;
0778: A0 2D A8 2B AC 64 AC 6D 87 BC 60 B4 13 72 7C B5 AE AE 7C 7C 65 A2 6C 64;
0790: 85 80 B0 40 88 20 68 DE 00 70 DE 20 78 20 20 38 20 B0 90 20 B0 A0 E0 B0;
07A8: C0 98 B6 48 80 E0 50 1E 1E 58 20 B8 E0 88 B0 10 20 00 10 20 E0 18 E0 18;
07C0: 00 18 E0 20 A8 E0 20 18 E0 00 20 18 D8 C8 18 E0 00 E0 40 28 28 28 18 E0;
07D8: 60 20 18 E0 00 00 08 E0 18 30 D0 D0 D0 20 E0 E8 FF 7F BF 32 D0 00 00 00;
07F0: 9F 63 79 42 B0 15 CB 04 FF 7F 31 6E 4A 45 00 00 FF 7F EF 1B 00 02 00 00;
0808: FF 7F 1F 42 F2 1C 00 00 FF 7F 94 52 4A 29 00 00 FF 7F FF 03 2F 01 00 00;
0820: FF 7F EF 03 D6 01 00 00 FF 7F B5 42 C8 3D 00 00 74 7E FF 03 80 01 00 00;
0838: FF 67 AC 77 13 1A 6B 2D D6 7E FF 4B 75 21 00 00 FF 53 5F 4A 52 7E 00 00;
0850: FF 4F D2 7E 4C 3A E0 1C ED 03 FF 7F 5F 25 00 00 6A 03 1F 02 FF 03 FF 7F;
0868: FF 7F DF 01 12 01 00 00 1F 23 5F 03 F2 00 09 00 FF 7F EA 03 1F 01 00 00;
0880: 9F 29 1A 00 0C 00 00 00 FF 7F 7F 02 1F 00 00 00 FF 7F E0 03 06 02 20 01;
0898: FF 7F EB 7E 1F 00 00 7C FF 7F FF 3F 00 7E 1F 00 FF 7F FF 03 1F 00 00 00;
08B0: FF 03 1F 00 0C 00 00 00 FF 7F 3F 03 93 01 00 00 00 00 00 42 7F 03 FF 7F;
08C8: FF 7F 8C 7E 00 7C 00 00 FF 7F EF 1B 80 61 00 00 FF 7F 00 7C E0 03 1F 7C;
08E0: 1F 00 FF 03 40 41 42 20 21 22 80 81 82 10 11 12 12 B0 79 B8 AD 16 17 07;
08F8: BA 05 7C 13 00 00 00 00;
END;

View File

@@ -0,0 +1,3 @@
set_global_assignment -name IP_TOOL_NAME "ROM: 1-PORT"
set_global_assignment -name IP_TOOL_VERSION "13.1"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "gbc_bios.v"]

159
cores/gameboy/gbc_bios.v Normal file
View File

@@ -0,0 +1,159 @@
// megafunction wizard: %ROM: 1-PORT%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altsyncram
// ============================================================
// File Name: gbc_bios.v
// Megafunction Name(s):
// altsyncram
//
// Simulation Library Files(s):
// altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 13.1.4 Build 182 03/12/2014 SJ Web Edition
// ************************************************************
//Copyright (C) 1991-2014 Altera Corporation
//Your use of Altera Corporation's design tools, logic functions
//and other software and tools, and its AMPP partner logic
//functions, and any output files from any of the foregoing
//(including device programming or simulation files), and any
//associated documentation or information are expressly subject
//to the terms and conditions of the Altera Program License
//Subscription Agreement, Altera MegaCore Function License
//Agreement, or other applicable license agreement, including,
//without limitation, that your use is for the sole purpose of
//programming logic devices manufactured by Altera and sold by
//Altera or its authorized distributors. Please refer to the
//applicable agreement for further details.
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module gbc_bios (
address,
clock,
q);
input [11:0] address;
input clock;
output [7:0] q;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
tri1 clock;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif
wire [7:0] sub_wire0;
wire [7:0] q = sub_wire0[7:0];
altsyncram altsyncram_component (
.address_a (address),
.clock0 (clock),
.q_a (sub_wire0),
.aclr0 (1'b0),
.aclr1 (1'b0),
.address_b (1'b1),
.addressstall_a (1'b0),
.addressstall_b (1'b0),
.byteena_a (1'b1),
.byteena_b (1'b1),
.clock1 (1'b1),
.clocken0 (1'b1),
.clocken1 (1'b1),
.clocken2 (1'b1),
.clocken3 (1'b1),
.data_a ({8{1'b1}}),
.data_b (1'b1),
.eccstatus (),
.q_b (),
.rden_a (1'b1),
.rden_b (1'b1),
.wren_a (1'b0),
.wren_b (1'b0));
defparam
altsyncram_component.address_aclr_a = "NONE",
altsyncram_component.clock_enable_input_a = "BYPASS",
altsyncram_component.clock_enable_output_a = "BYPASS",
altsyncram_component.init_file = "gbc_bios.mif",
altsyncram_component.intended_device_family = "Cyclone III",
altsyncram_component.lpm_hint = "ENABLE_RUNTIME_MOD=NO",
altsyncram_component.lpm_type = "altsyncram",
altsyncram_component.numwords_a = 4096,
altsyncram_component.operation_mode = "ROM",
altsyncram_component.outdata_aclr_a = "NONE",
altsyncram_component.outdata_reg_a = "CLOCK0",
altsyncram_component.widthad_a = 12,
altsyncram_component.width_a = 8,
altsyncram_component.width_byteena_a = 1;
endmodule
// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
// Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
// Retrieval info: PRIVATE: AclrByte NUMERIC "0"
// Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
// Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
// Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
// Retrieval info: PRIVATE: Clken NUMERIC "0"
// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
// Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
// Retrieval info: PRIVATE: MIFfilename STRING "gbc_bios.mif"
// Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "4096"
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
// Retrieval info: PRIVATE: RegAddr NUMERIC "1"
// Retrieval info: PRIVATE: RegOutput NUMERIC "1"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: SingleClock NUMERIC "1"
// Retrieval info: PRIVATE: UseDQRAM NUMERIC "0"
// Retrieval info: PRIVATE: WidthAddr NUMERIC "12"
// Retrieval info: PRIVATE: WidthData NUMERIC "8"
// Retrieval info: PRIVATE: rden NUMERIC "0"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE"
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
// Retrieval info: CONSTANT: INIT_FILE STRING "gbc_bios.mif"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone III"
// Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "4096"
// Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM"
// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "CLOCK0"
// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "12"
// Retrieval info: CONSTANT: WIDTH_A NUMERIC "8"
// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
// Retrieval info: USED_PORT: address 0 0 12 0 INPUT NODEFVAL "address[11..0]"
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
// Retrieval info: USED_PORT: q 0 0 8 0 OUTPUT NODEFVAL "q[7..0]"
// Retrieval info: CONNECT: @address_a 0 0 12 0 address 0 0 12 0
// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
// Retrieval info: CONNECT: q 0 0 8 0 @q_a 0 0 8 0
// Retrieval info: GEN_FILE: TYPE_NORMAL gbc_bios.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL gbc_bios.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL gbc_bios.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL gbc_bios.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL gbc_bios_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL gbc_bios_bb.v FALSE
// Retrieval info: LIB_FILE: altera_mf

View File

@@ -4,24 +4,25 @@
// The gameboy lcd runs from a shift register which is filled at 4194304 pixels/sec
module lcd (
input clk64,
input clk,
input clk4_en,
input clkena,
input [1:0] data,
input [14:0] data,
input [1:0] mode,
input isGBC,
input tint,
// pixel clock
input pclk_en,
input on,
// VGA output
output reg hs,
output reg vs,
output [5:0] r,
output [5:0] g,
output [5:0] b
// VGA output
output reg hs,
output reg vs,
output [5:0] r,
output [5:0] g,
output [5:0] b
);
// Mode 00: h-blank
@@ -30,25 +31,27 @@ module lcd (
// Mode 11: oam and vram
// space for 2*160 pixel
reg [7:0] shift_reg_wptr;
reg [8:0] shift_reg_wptr;
reg p_toggle;
reg [1:0] shift_reg [511:0];
reg [14:0] shift_reg [511:0];
reg [1:0] last_mode_in;
// shift register input
always @(posedge clk) begin
last_mode_in <= mode;
// end of vsync
if(clkena) begin
shift_reg[{p_toggle, shift_reg_wptr}] <= data;
shift_reg_wptr <= shift_reg_wptr + 8'd1;
end
// reset write pointer at end of hsync phase
if((mode != 2'b00) && (last_mode_in == 2'b00)) begin
shift_reg_wptr <= 8'd0;
p_toggle <= !p_toggle;
if(clk4_en) begin
if(clkena) begin
shift_reg[shift_reg_wptr] <= data;
shift_reg_wptr <= {p_toggle, shift_reg_wptr[7:0] + 1'd1};
end
last_mode_in <= mode;
// reset write pointer at end of hsync phase
if((mode != 2'b00) && (last_mode_in == 2'b00)) begin
shift_reg_wptr <= 0;
p_toggle <= !p_toggle;
end
end
end
@@ -70,12 +73,12 @@ reg[9:0] v_cnt; // vertical pixel counter
// horizontal pixel counter
reg [1:0] last_mode_h;
always@(posedge clk64) begin
always@(posedge clk) begin
if (pclk_en) begin
last_mode_h <= mode;
if(h_cnt==H+HFP+HS+HBP-1) h_cnt <= 0;
else h_cnt <= h_cnt + 1;
else h_cnt <= h_cnt + 1'd1;
// generate negative hsync signal
if(h_cnt == H+HFP) hs <= 1'b0;
@@ -90,12 +93,12 @@ end
// veritical pixel counter
reg [1:0] last_mode_v;
always@(posedge clk64) begin
always@(posedge clk) begin
if (pclk_en) begin
// the vertical counter is processed at the begin of each hsync
if(h_cnt == H+HFP+HS+HBP-1) begin
if(v_cnt==VS+VFP+V+VBP-1) v_cnt <= 0;
else v_cnt <= v_cnt + 1;
else v_cnt <= v_cnt + 1'd1;
// generate positive vsync signal
if(v_cnt == V+VFP) vs <= 1'b1;
@@ -107,7 +110,7 @@ always@(posedge clk64) begin
// end of mode 01 (vblank)
// make and offset of - 4 for the 4 line delay of the scandoubler
if((mode != 2'b01) && (last_mode_v == 2'b01))
v_cnt <= 616-4;
v_cnt <= 10'd616-10'd4;
end
end
end
@@ -116,24 +119,24 @@ end
// ------------------------------- pixel generator -------------------------------
// -------------------------------------------------------------------------------
reg blank;
reg [1:0] pixel_reg;
reg [7:0] shift_reg_rptr;
reg [14:0] pixel_reg;
reg [8:0] shift_reg_rptr;
always@(posedge clk64) begin
always@(posedge clk) begin
if (pclk_en) begin
// visible area?
if((v_cnt < V) && (h_cnt < H)) begin
blank <= 1'b0;
pixel_reg <= shift_reg[{!p_toggle, shift_reg_rptr}];
shift_reg_rptr <= shift_reg_rptr + 8'd1;
pixel_reg <= shift_reg[shift_reg_rptr];
shift_reg_rptr <= {!p_toggle, shift_reg_rptr[7:0] + 1'd1};
end else begin
blank <= 1'b1;
shift_reg_rptr <= 8'd0;
shift_reg_rptr <= 0;
end
end
end
wire [1:0] pixel = on?pixel_reg:2'b00;
wire [14:0] pixel = on?pixel_reg:15'd0;
// gameboy "color" palette
wire [5:0] yellow_r = (pixel==0)?6'b100111:(pixel==1)?6'b100000: // 1:100011
@@ -146,8 +149,8 @@ wire [5:0] yellow_b = (pixel==0)?6'b000100:(pixel==1)?6'b000010: // 1:000100
// greyscale
wire [5:0] grey = (pixel==0)?6'd63:(pixel==1)?6'd42:(pixel==2)?6'd24:6'd0;
assign r = blank?6'b000000:tint?yellow_r:grey;
assign g = blank?6'b000000:tint?yellow_g:grey;
assign b = blank?6'b000000:tint?yellow_b:grey;
assign r = blank?6'b000000:isGBC ? {pixel_reg [4: 0], 1'b0} : (tint?yellow_r:grey);
assign g = blank?6'b000000:isGBC ? {pixel_reg [9: 5], 1'b0} : (tint?yellow_g:grey);
assign b = blank?6'b000000:isGBC ? {pixel_reg[14:10], 1'b0} : (tint?yellow_b:grey);
endmodule