From: Joshua Wise Date: Sat, 19 Apr 2008 09:57:30 +0000 (-0400) Subject: Add bootrom X-Git-Url: http://git.joshuawise.com/fpgaboy.git/commitdiff_plain/6bd4619bee74d76a525f7def9ac56ffcf114a3f4?ds=sidebyside Add bootrom --- diff --git a/Makefile b/Makefile index cf89f73..8b2feed 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ VLOGS = 7seg.v GBZ80Core.v insn_call-callcc.v insn_incdec16.v \ Timer.v LCDC.v insn_ldm8_a.v insn_ldm16_a.v Framebuffer.v \ insn_ldbcde_a.v -all: CoreTop_rom.svf CoreTop_diag.svf CoreTop.twr +all: CoreTop_rom.svf CoreTop_diag.svf CoreTop_bootrom.svf CoreTop.twr CoreTop.ngc: CoreTop.xst CoreTop.prj $(VLOGS) xst -ifn CoreTop.xst -ofn CoreTop.syr diff --git a/System.v b/System.v index dbcfaa4..0e464f5 100644 --- a/System.v +++ b/System.v @@ -15,6 +15,28 @@ module ROM( //assign data = rd ? odata : 8'bzzzzzzzz; endmodule +module MiniRAM( /* XXX will need to go INSIDE the CPU for when we do DMA */ + input [15:0] address, + inout [7:0] data, + input clk, + input wr, rd); + + reg [7:0] ram [127:0]; + + wire decode = (address >= 16'hFF80) && (address <= 16'hFFFE); + reg [7:0] odata; + assign data = (rd && decode) ? odata : 8'bzzzzzzzz; + + always @(negedge clk) + begin + if (decode) // This has to go this way. The only way XST knows how to do + begin // block ram is chip select, write enable, and always + if (wr) // reading. "else if rd" does not cut it ... + ram[address[6:0]] <= data; + odata <= ram[address[6:0]]; + end + end + module InternalRAM( input [15:0] address, inout [7:0] data, @@ -173,6 +195,14 @@ module CoreTop( .wr(wr), .rd(rd) ); + + MiniRAM mram( + .address(addr), + .data(data), + .clk(clk), + .wr(wr), + .rd(rd) + ); Timer tmr( .clk(clk), diff --git a/bootrom.asm b/bootrom.asm new file mode 100644 index 0000000..4f71d5e --- /dev/null +++ b/bootrom.asm @@ -0,0 +1,170 @@ + SECTION "a",HOME[$00] + + LD SP,$fffe ; $0000 Setup Stack + + XOR A ; $0003 Zero the memory from $8000-$9FFF (VRAM) + LD HL,$9fff ; $0004 +Addr_0007: + LD [HLD],A ; $0007 + BIT 7,H ; $0008 + JR NZ, Addr_0007 ; $000a + + LD HL,$ff26 ; $000c Setup Audio + LD C,$11 ; $000f + LD A,$80 ; $0011 + LD [HLD],A ; $0013 + LD [C],A ; $0014 + INC C ; $0015 + LD A,$f3 ; $0016 + LD [C],A ; $0018 + LD [HLD],A ; $0019 + LD A,$77 ; $001a + LD [HLD],A ; $001c + + LD A,$fc ; $001d Setup BG palette + LD [$FF47],A ; $001f + + LD DE,$0104 ; $0021 Convert and load logo data from cart into Video RAM + LD HL,$8010 ; $0024 +Addr_0027: + LD A,[DE] ; $0027 + CALL $0095 ; $0028 + CALL $0096 ; $002b + INC DE ; $002e + LD A,E ; $002f + CP $34 ; $0030 + JR NZ, Addr_0027 ; $0032 + + LD DE,$00d8 ; $0034 Load 8 additional bytes into Video RAM + LD B,$08 ; $0037 +Addr_0039: + LD A,[DE] ; $0039 + INC DE ; $003a + LD [HLI],A ; $003b + INC HL ; $003c + DEC B ; $003d + JR NZ, Addr_0039 ; $003e + + LD A,$19 ; $0040 Setup background tilemap + LD [$9910],A ; $0042 + LD HL,$992f ; $0045 +Addr_0048: + LD C,$0c ; $0048 +Addr_004A: + DEC A ; $004a + JR Z, Addr_0055 ; $004b + LD [HLD],A ; $004d + DEC C ; $004e + JR NZ, Addr_004A ; $004f + LD L,$0f ; $0051 + JR Addr_0048 ; $0053 + + ; === Scroll logo on screen, and play logo sound=== + +Addr_0055: + LD H,A ; $0055 Initialize scroll count, H=0 + LD A,$64 ; $0056 + LD D,A ; $0058 set loop count, D=$64 + LD [$FF42],A ; $0059 Set vertical scroll register + LD A,$91 ; $005b + LD [$FF40],A ; $005d Turn on LCD, showing Background + INC B ; $005f Set B=1 +Addr_0060: + LD E,$02 ; $0060 +Addr_0062: + LD C,$0c ; $0062 +Addr_0064: + LD A,[$FF44] ; $0064 wait for screen frame + CP $90 ; $0066 + JR NZ, Addr_0064 ; $0068 + DEC C ; $006a + JR NZ, Addr_0064 ; $006b + DEC E ; $006d + JR NZ, Addr_0062 ; $006e + + LD C,$13 ; $0070 + INC H ; $0072 increment scroll count + LD A,H ; $0073 + LD E,$83 ; $0074 + CP $62 ; $0076 $62 counts in, play sound #1 + JR Z, Addr_0080 ; $0078 + LD E,$c1 ; $007a + CP $64 ; $007c + JR NZ, Addr_0086 ; $007e $64 counts in, play sound #2 +Addr_0080: + LD A,E ; $0080 play sound + LD [C],A ; $0081 + INC C ; $0082 + LD A,$87 ; $0083 + LD [C],A ; $0085 +Addr_0086: + LD A,[$FF42] ; $0086 + SUB B ; $0088 + LD [$FF42],A ; $0089 scroll logo up if B=1 + DEC D ; $008b + JR NZ, Addr_0060 ; $008c + + DEC B ; $008e set B=0 first time + JR NZ, Addr_00E0 ; $008f ... next time, cause jump to "Nintendo Logo check" + + LD D,$20 ; $0091 use scrolling loop to pause + JR Addr_0060 ; $0093 + + ; ==== Graphic routine ==== + + LD C,A ; $0095 "Double up" all the bits of the graphics data + LD B,$04 ; $0096 and store in Video RAM +Addr_0098: + PUSH BC ; $0098 + RL C ; $0099 + RLA ; $009b + POP BC ; $009c + RL C ; $009d + RLA ; $009f + DEC B ; $00a0 + JR NZ, Addr_0098 ; $00a1 + LD [HLI],A ; $00a3 + INC HL ; $00a4 + LD [HLI],A ; $00a5 + INC HL ; $00a6 + RET ; $00a7 + +Addr_00A8: + ;Nintendo Logo + DB $CE,$ED,$66,$66,$CC,$0D,$00,$0B,$03,$73,$00,$83,$00,$0C,$00,$0D + DB $00,$08,$11,$1F,$88,$89,$00,$0E,$DC,$CC,$6E,$E6,$DD,$DD,$D9,$99 + DB $BB,$BB,$67,$63,$6E,$0E,$EC,$CC,$DD,$DC,$99,$9F,$BB,$B9,$33,$3E + +Addr_00D8: + ;More video data + DB $3C,$42,$B9,$A5,$B9,$A5,$42,$3C + + ; ===== Nintendo logo comparison routine ===== + +Addr_00E0: + LD HL,$0104 ; $00e0 ; point HL to Nintendo logo in cart + LD DE,$00a8 ; $00e3 ; point DE to Nintendo logo in DMG rom + +Addr_00E6: + LD A,[DE] ; $00e6 + INC DE ; $00e7 + CP [HL] ; $00e8 ;compare logo data in cart to DMG rom +.fuq JR NZ,.fuq ; $00e9 ;if not a match, lock up here + INC HL ; $00eb + LD A,L ; $00ec + CP $34 ; $00ed ;do this for $30 bytes + JR NZ, Addr_00E6 ; $00ef + + LD B,$19 ; $00f1 + LD A,B ; $00f3 +Addr_00F4: + ADD [HL] ; $00f4 + INC HL ; $00f5 + DEC B ; $00f6 + JR NZ, Addr_00F4 ; $00f7 + ADD [HL] ; $00f9 +.fuq: JR NZ,.fuq ; $00fa ; if $19 + bytes from $0134-$014D don't add to $00 + ; ... lock up + + LD A,$01 ; $00fc + LD [$FF50],A ; $00fe ;turn off DMG rom diff --git a/opcodes b/opcodes index 5a03850..09f68fb 100644 --- a/opcodes +++ b/opcodes @@ -95,15 +95,6 @@ bits insn notes 1100 1011 0011 0110 SWAP (HL) 1100 1011 0011 0111 SWAP A -1100 1011 0100 0000 BIT imm3, B test bit specified by imm3 -1100 1011 0100 0001 BIT imm3, C -1100 1011 0100 0010 BIT imm3, D -1100 1011 0100 0011 BIT imm3, E -1100 1011 0100 0100 BIT imm3, H -1100 1011 0100 0101 BIT imm3, L -1100 1011 0100 0110 BIT imm3, (HL) -1100 1011 0100 0111 BIT imm3, A - 1100 1011 1000 0000 RES imm3, B reset bit specified by imm3 1100 1011 1000 0001 RES imm3, C 1100 1011 1000 0010 RES imm3, D