From: Joshua Wise <joshua@rebirth.joshuawise.com>
Date: Wed, 7 May 2008 10:08:11 +0000 (-0400)
Subject: Make the boot rom talk a bit more, and wait for you to flip a switch. Make the 'progr... 
X-Git-Url: http://git.joshuawise.com/fpgaboy.git/commitdiff_plain/1eefdc8e89a69963b1c1a084fe4ecec844997293

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.
---

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