From 1eefdc8e89a69963b1c1a084fe4ecec844997293 Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Wed, 7 May 2008 06:08:11 -0400 Subject: [PATCH] Make the boot rom talk a bit more, and wait for you to flip a switch. Make the 'programming interface' autoincrement. Rename UART variables to prepare for rx. --- GBZ80Core.v | 5 +++- System.v | 8 +++++- Uart.v | 72 ++++++++++++++++++++++++++-------------------------- fpgaboot.asm | 60 +++++++++++++++++++++++++++++++++++-------- 4 files changed, 96 insertions(+), 49 deletions(-) diff --git a/GBZ80Core.v b/GBZ80Core.v index e1aa308..3c2f770 100644 --- a/GBZ80Core.v +++ b/GBZ80Core.v @@ -295,8 +295,11 @@ module GBZ80Core( busaddress <= address; buswr <= wr; busrd <= rd; - if (wr) + if (wr) begin buswdata <= wdata; + if (address == 16'hFF50) + bootstrap_enb <= 0; + end end end `STATE_DECODE: begin /* Make sure this only happens for one clock. */ diff --git a/System.v b/System.v index 8c4cf1a..62683d3 100644 --- a/System.v +++ b/System.v @@ -92,6 +92,8 @@ module CellularRAM( reg [7:0] progaddrh, progaddrm, progaddrl; + reg [22:0] progaddr; + assign cr_nADV = 0; /* Addresses are always valid! :D */ assign cr_nCE = 0; /* The chip is enabled */ assign cr_nLB = 0; /* Lower byte is enabled */ @@ -107,7 +109,7 @@ module CellularRAM( assign cr_DQ = (~cr_nOE) ? 16'bzzzzzzzzzzzzzzzz : {8'b0, datalatch}; assign cr_A = (addrlatch[15:14] == 2'b00) ? /* extrom */ {9'b0,addrlatch[13:0]} : (addrlatch[15:13] == 3'b101) ? {1'b1, 9'b0, addrlatch[12:0]} : - (addrlatch == ADDR_PROGDATA) ? {progaddrh[6:0], progaddrm[7:0], progaddrl[7:0]} : + (addrlatch == ADDR_PROGDATA) ? progaddr : 23'b0; reg [7:0] regbuf; @@ -117,6 +119,10 @@ module CellularRAM( ADDR_PROGADDRH: if (wr) progaddrh <= data; ADDR_PROGADDRM: if (wr) progaddrm <= data; ADDR_PROGADDRL: if (wr) progaddrl <= data; + ADDR_PROGDATA: if (rd || wr) begin + progaddr <= {progaddrh[6:0], progaddrm[7:0], progaddr[7:0]}; + {progaddrh[6:0], progaddrm[7:0], progaddr[7:0]} <= {progaddrh[6:0], progaddrm[7:0], progaddr[7:0]} + 23'b1; + end endcase rdlatch <= rd; wrlatch <= wr; diff --git a/Uart.v b/Uart.v index 07f996a..e521304 100644 --- a/Uart.v +++ b/Uart.v @@ -1,7 +1,8 @@ `define IN_CLK 8388608 `define OUT_CLK 57600 `define CLK_DIV `IN_CLK / `OUT_CLK -`define MMAP_ADDR 16'hFF50 +`define DATA_ADDR 16'hFF52 +`define STAT_ADDR 16'hFF53 module UART( input clk, @@ -11,52 +12,51 @@ module UART( inout [7:0] data, output reg serial = 1); - reg rdlatch = 0; - wire decode = (addr == `MMAP_ADDR); + wire data_decode = (addr == `DATA_ADDR); + wire stat_decode = (addr == `STAT_ADDR); + reg data_latch = 0; + reg stat_latch = 0; - wire [7:0] odata; - assign data = rdlatch ? odata : 8'bzzzzzzzz; - - reg [7:0] data_stor = 0; - reg [15:0] clkdiv = 0; - reg have_data = 0; - reg [3:0] diqing = 4'b0000; - - wire newdata = (wr) && (!have_data) && decode; + reg [7:0] tx_data = 0; + reg [15:0] tx_clkdiv = 0; + reg [3:0] tx_state = 4'b1011; // 1011 is the not busy state. + wire tx_busy = tx_state != 4'b1011; + wire tx_newdata = (wr) && (!tx_busy) && data_decode; - assign odata = have_data ? 8'b1 : 8'b0; + assign data = (rd && stat_latch) ? (tx_busy ? 8'b1 : 8'b0) : + (rd && data_latch) ? (8'b0) : + 8'bzzzzzzzz; - always @ (posedge clk) + always @(posedge clk) begin - rdlatch <= rd && decode; + data_latch <= rd && data_decode; + stat_latch <= rd && stat_decode; /* deal with diqing */ - if(newdata) begin - data_stor <= data; - have_data <= 1; - diqing <= 4'b0000; - end else if (clkdiv == 0) begin - diqing <= diqing + 1; - if (have_data) - case (diqing) + if(tx_newdata) begin + tx_data <= data; + tx_state <= 4'b0000; + end else if (tx_clkdiv == 0) begin + tx_state <= tx_state + 1; + if (tx_busy) + case (tx_state) 4'b0000: serial <= 0; - 4'b0001: serial <= data_stor[0]; - 4'b0010: serial <= data_stor[1]; - 4'b0011: serial <= data_stor[2]; - 4'b0100: serial <= data_stor[3]; - 4'b0101: serial <= data_stor[4]; - 4'b0110: serial <= data_stor[5]; - 4'b0111: serial <= data_stor[6]; - 4'b1000: serial <= data_stor[7]; + 4'b0001: serial <= tx_data[0]; + 4'b0010: serial <= tx_data[1]; + 4'b0011: serial <= tx_data[2]; + 4'b0100: serial <= tx_data[3]; + 4'b0101: serial <= tx_data[4]; + 4'b0110: serial <= tx_data[5]; + 4'b0111: serial <= tx_data[6]; + 4'b1000: serial <= tx_data[7]; 4'b1001: serial <= 1; - 4'b1010: have_data <= 0; + 4'b1010: serial <= 1; default: $stop; endcase end - /* deal with clkdiv */ - if((newdata && !have_data) || clkdiv == `CLK_DIV) - clkdiv <= 0; + if((tx_newdata && !tx_busy) || (tx_clkdiv == `CLK_DIV)) + tx_clkdiv <= 0; else - clkdiv <= clkdiv + 1; + tx_clkdiv <= tx_clkdiv + 1; end endmodule diff --git a/fpgaboot.asm b/fpgaboot.asm index a923657..4a1089f 100644 --- a/fpgaboot.asm +++ b/fpgaboot.asm @@ -1,11 +1,15 @@ SECTION "boot", HOME[$0] - ld a, $AA +boot: ld a, $AA ld [$FF51], A ; Poke the LEDs + + ld sp, $FFFE + + ld hl, signon + call puts ; Write a little bit to the RAM - ld H, $01 - ld L, $00 - ld A, $00 + ld hl, $0104 + xor a ld [HLI], A ld [HLI], A ld [HLI], A @@ -15,9 +19,6 @@ ld [HLI], A ld [HLI], A - ld a, $55 - ld [$FF51], A ; Poke the LEDs - ld A, $FF ld [HLI], A ld [HLI], A @@ -28,11 +29,48 @@ ld [HLI], A ld [HLI], A - ld H, $00 - ld L, $00 - ld [HL], $01 ; Select the GB boot rom - rst $00 ; Boot + ld c, $51 +.wait: ld a, [c] + cp $00 + jr nz, .wait + + ld h, a + ld l, a + ld [hl], $01 ; Select the GB boot rom + + ld a, $55 + ld [c], a + + ld hl, booting + call puts + + rst $00 ; Boot + +putc: + ld c, $53 + push af +.waitport: + ld a,[c] + cp $00 + jr nz,.waitport + pop af + ld [$FF52],a + ret + +puts: + ld a, [hli] + cp $00 + ret z + call putc + jr puts + +signon: + db $0D,$0A,$1B,"[1mFPGABoy Boot ROM",$1B,"[0m",$0D,$0A,0 +booting: + db "Booting...",$0D,$0A,0 + + SECTION "a", HOME[$100] nop ; Make sure we don't overflow. \ No newline at end of file -- 2.39.2