input rd,
input [15:0] addr,
inout [7:0] data,
- output reg serial = 1);
+ output reg serial = 1,
+ input serialrx);
wire data_decode = (addr == `DATA_ADDR);
wire stat_decode = (addr == `STAT_ADDR);
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;
+ reg [3:0] tx_state = 4'b0000;
+ reg tx_busy = 0;
wire tx_newdata = (wr) && (!tx_busy) && data_decode;
- assign data = (rd && stat_latch) ? (tx_busy ? 8'b1 : 8'b0) :
- (rd && data_latch) ? (8'b0) :
+ reg rx_hasdata = 0;
+ reg [15:0] rx_clkdiv = 0;
+ reg [3:0] rx_state = 4'b0000;
+ reg [7:0] rx_data;
+
+ assign data = (stat_latch) ? {6'b0, rx_hasdata, tx_busy} :
+ (data_latch) ? rx_data :
8'bzzzzzzzz;
always @(posedge clk)
begin
data_latch <= rd && data_decode;
stat_latch <= rd && stat_decode;
- /* deal with diqing */
if(tx_newdata) begin
tx_data <= data;
tx_state <= 4'b0000;
+ tx_busy <= 1;
end else if (tx_clkdiv == 0) begin
tx_state <= tx_state + 1;
if (tx_busy)
4'b0111: serial <= tx_data[6];
4'b1000: serial <= tx_data[7];
4'b1001: serial <= 1;
- 4'b1010: serial <= 1;
+ 4'b1010: tx_busy <= 0;
default: $stop;
+ endcase
+ end
+
+ if ((rx_state == 0) && (serialrx == 0) /*&& (rx_hasdata == 0)*/) /* Kick off. */
+ rx_state <= 4'b0001;
+ else if ((rx_state != 4'b0000) && (rx_clkdiv == 0)) begin
+ if (rx_state != 4'b1010)
+ rx_state <= rx_state + 1;
+ else
+ rx_state <= 0;
+ case (rx_state)
+ 4'b0001: begin end /* Twiddle thumbs -- this is the end of the half bit. */
+ 4'b0010: rx_data[0] <= serialrx;
+ 4'b0011: rx_data[1] <= serialrx;
+ 4'b0100: rx_data[2] <= serialrx;
+ 4'b0101: rx_data[3] <= serialrx;
+ 4'b0110: rx_data[4] <= serialrx;
+ 4'b0111: rx_data[5] <= serialrx;
+ 4'b1000: rx_data[6] <= serialrx;
+ 4'b1001: rx_data[7] <= serialrx;
+ 4'b1010: begin end /* Expect a 1 */
endcase
end
+
+ rx_hasdata <= (rx_hasdata && ~(rd && data_decode)) || ((rx_state == 4'b1010) && (tx_clkdiv == 0));
- if((tx_newdata && !tx_busy) || (tx_clkdiv == `CLK_DIV))
+ if(tx_newdata || (tx_clkdiv == `CLK_DIV))
tx_clkdiv <= 0;
else
tx_clkdiv <= tx_clkdiv + 1;
+
+ if ((rx_state == 0) && (serialrx == 0) /*&& (rx_hasdata == 0)*/) /* Wait half a period before advancing. */
+ rx_clkdiv <= `CLK_DIV / 2 + `CLK_DIV / 4;
+ else if (rx_clkdiv == `CLK_DIV)
+ rx_clkdiv <= 0;
+ else
+ rx_clkdiv <= rx_clkdiv + 1;
end
endmodule
ld hl, signon
call puts
- ; Write a little bit to the RAM
- ld hl, $0104
- xor a
- ld [HLI], A
- ld [HLI], A
- ld [HLI], A
- ld [HLI], A
- ld [HLI], A
- ld [HLI], A
- ld [HLI], A
- ld [HLI], A
+.wait: ld a, [$FF53]
+ and $02
+ jr z, .nodata
+ ld a, [$FF52]
+ ld [$FF51], a
- ld A, $FF
- ld [HLI], A
- ld [HLI], A
- ld [HLI], A
- ld [HLI], A
- ld [HLI], A
- ld [HLI], A
- ld [HLI], A
- ld [HLI], A
-
- ld c, $51
-
-.wait: ld a, [c]
+ cp $1B ; Escape
+ jp z, .cbc
+ ld [$FF52], a
+.cbc: call z, bootcmd
+
+.nodata: ld a, [$FF51]
cp $00
jr nz, .wait
+doboot: xor a
ld h, a
ld l, a
ld [hl], $01 ; Select the GB boot rom
rst $00 ; Boot
+signon:
+ db $0D,$0A,$1B,"[1mFPGABoy Boot ROM",$1B,"[0m",$0D,$0A,0
+booting:
+ db "Booting...",$0D,$0A,0
+
putc:
ld c, $53
push af
.waitport:
ld a,[c]
- cp $00
+ and $01
jr nz,.waitport
pop af
ld [$FF52],a
call putc
jr puts
-signon:
- db $0D,$0A,$1B,"[1mFPGABoy Boot ROM",$1B,"[0m",$0D,$0A,0
-booting:
- db "Booting...",$0D,$0A,0
-
+getc:
+ ld a, [$FF53]
+ and $02
+ jr z, getc
+ ld a, [$FF52]
+ ret
+bootcmd:
+ call getc
+ cp $56 ;V
+ jr z,.version
+ cp $41 ;A
+ jr z,.addr
+ cp $44 ;D
+ jr z,.data
+ cp $50 ;P
+ jr z,.prog
+ cp $42 ;B
+ jr z,doboot
+ cp $1B
+ jr z,bootcmd ; If you keep yelling, you're bound to get the thing's attention.
+ ld a, $3f ;?
+ jr putc
+.version:
+ ld hl, .verstr
+ jr puts
+.verstr:
+ db "V1.00",0
+.addr:
+ call getc
+ ld [$FF60], A
+ call getc
+ ld [$FF61], A
+ call getc
+ ld [$FF62], A
+ ld A, $41 ;A
+ jr putc
+.data:
+ call getc ; byte count
+ ld c, a
+.dl: call getc
+ ld [$FF63], A
+ dec c
+ jp nz, .dl
+ ld A, $44 ;D
+ ret
+.prog:
+ ld hl, $FF80
+ ld c, $7F
+.pl: dec c
+ jp z, $FF80
+ call getc
+ ld [hli], a
+ jr .pl
+
SECTION "a", HOME[$100]
nop ; Make sure we don't overflow.
\ No newline at end of file