diff --git a/BootROMs/DamageLogo.1bpp b/BootROMs/DamageLogo.1bpp new file mode 100644 index 0000000..aa53adb Binary files /dev/null and b/BootROMs/DamageLogo.1bpp differ diff --git a/BootROMs/cgb_boot.asm b/BootROMs/cgb_boot.asm index fa826f5..f2e91c4 100644 --- a/BootROMs/cgb_boot.asm +++ b/BootROMs/cgb_boot.asm @@ -549,7 +549,8 @@ TrademarkSymbol: db $3c,$42,$b9,$a5,$b9,$a5,$42,$3c SameboyLogo: - incbin "SameboyLogo.1bpp" + ; incbin "SameboyLogo.1bpp" + incbin "DamageLogo.1bpp" SameboyLogoEnd: AnimationColors: @@ -1174,4 +1175,4 @@ BgPalettes: InputPalette: ds 1 WaitLoopCounter: - ds 1 \ No newline at end of file + ds 1 diff --git a/BootROMs/dmg_boot.asm b/BootROMs/dmg_boot.asm index 46b389a..2cf0591 100644 --- a/BootROMs/dmg_boot.asm +++ b/BootROMs/dmg_boot.asm @@ -89,15 +89,19 @@ Start: ; Wait ~1.15 seconds ld b, 70 call WaitBFrames - + ; Set registers to match the original DMG boot +IF DEF(MGB) ld hl, $01B0 +ELSE + ld hl, $FFB0 +ENDC push hl pop af ld hl, $014D ld bc, $0013 ld de, $00D8 - + ; Boot the game jp BootGame diff --git a/BootROMs/mgb_boot.asm b/BootROMs/mgb_boot.asm new file mode 100644 index 0000000..3a98aef --- /dev/null +++ b/BootROMs/mgb_boot.asm @@ -0,0 +1,2 @@ +MGB EQU 1 +include "dmg_boot.asm" \ No newline at end of file diff --git a/Makefile b/Makefile index 5f46008..5fe32bd 100755 --- a/Makefile +++ b/Makefile @@ -106,9 +106,9 @@ endif cocoa: $(BIN)/SameBoy.app quicklook: $(BIN)/SameBoy.qlgenerator -sdl: $(SDL_TARGET) $(BIN)/SDL/dmg_boot.bin $(BIN)/SDL/cgb_boot.bin $(BIN)/SDL/agb_boot.bin $(BIN)/SDL/sgb_boot.bin $(BIN)/SDL/sgb2_boot.bin $(BIN)/SDL/LICENSE $(BIN)/SDL/registers.sym $(BIN)/SDL/background.bmp $(BIN)/SDL/Shaders -bootroms: $(BIN)/BootROMs/agb_boot.bin $(BIN)/BootROMs/cgb_boot.bin $(BIN)/BootROMs/dmg_boot.bin $(BIN)/BootROMs/sgb_boot.bin $(BIN)/BootROMs/sgb2_boot.bin -tester: $(TESTER_TARGET) $(BIN)/tester/dmg_boot.bin $(BIN)/tester/cgb_boot.bin $(BIN)/tester/agb_boot.bin $(BIN)/tester/sgb_boot.bin $(BIN)/tester/sgb2_boot.bin +sdl: $(SDL_TARGET) $(BIN)/SDL/dmg_boot.bin $(BIN)/SDL/mgb_boot.bin $(BIN)/SDL/cgb_boot.bin $(BIN)/SDL/cgb_boot_fast.bin $(BIN)/SDL/agb_boot.bin $(BIN)/SDL/sgb_boot.bin $(BIN)/SDL/sgb2_boot.bin $(BIN)/SDL/LICENSE $(BIN)/SDL/registers.sym $(BIN)/SDL/background.bmp $(BIN)/SDL/Shaders +bootroms: $(BIN)/BootROMs/agb_boot.bin $(BIN)/BootROMs/cgb_boot.bin $(BIN)/BootROMs/cgb_boot_fast.bin $(BIN)/BootROMs/dmg_boot.bin $(BIN)/BootROMs/mgb_boot.bin $(BIN)/BootROMs/sgb_boot.bin $(BIN)/BootROMs/sgb2_boot.bin +tester: $(TESTER_TARGET) $(BIN)/tester/dmg_boot.bin $(BIN)/tester/mgb_boot.bin $(BIN)/tester/cgb_boot.bin $(BIN)/tester/cgb_boot_fast.bin $(BIN)/tester/agb_boot.bin $(BIN)/tester/sgb_boot.bin $(BIN)/tester/sgb2_boot.bin all: cocoa sdl tester libretro # Get a list of our source files and their respective object file targets @@ -160,12 +160,12 @@ $(OBJ)/Core/%.c.o: Core/%.c $(OBJ)/%.c.o: %.c -@$(MKDIR) -p $(dir $@) $(CC) $(CFLAGS) -c $< -o $@ - + # HexFiend requires more flags $(OBJ)/HexFiend/%.m.o: HexFiend/%.m -@$(MKDIR) -p $(dir $@) $(CC) $(CFLAGS) $(OCFLAGS) -c $< -o $@ -fno-objc-arc -include HexFiend/HexFiend_2_Framework_Prefix.pch - + $(OBJ)/%.m.o: %.m -@$(MKDIR) -p $(dir $@) $(CC) $(CFLAGS) $(OCFLAGS) -c $< -o $@ @@ -178,7 +178,9 @@ $(BIN)/SameBoy.app: $(BIN)/SameBoy.app/Contents/MacOS/SameBoy \ Cocoa/Info.plist \ Misc/registers.sym \ $(BIN)/SameBoy.app/Contents/Resources/dmg_boot.bin \ + $(BIN)/SameBoy.app/Contents/Resources/mgb_boot.bin \ $(BIN)/SameBoy.app/Contents/Resources/cgb_boot.bin \ + $(BIN)/SameBoy.app/Contents/Resources/cgb_boot_fast.bin \ $(BIN)/SameBoy.app/Contents/Resources/agb_boot.bin \ $(BIN)/SameBoy.app/Contents/Resources/sgb_boot.bin \ $(BIN)/SameBoy.app/Contents/Resources/sgb2_boot.bin \ @@ -203,7 +205,7 @@ endif $(BIN)/SameBoy.app/Contents/Resources/Base.lproj/%.nib: Cocoa/%.xib ibtool --compile $@ $^ - + # Quick Look generator $(BIN)/SameBoy.qlgenerator: $(BIN)/SameBoy.qlgenerator/Contents/MacOS/SameBoyQL \ @@ -228,7 +230,7 @@ endif $(BIN)/SameBoy.qlgenerator/Contents/Resources/cgb_boot_fast.bin: $(BIN)/BootROMs/cgb_boot_fast.bin -@$(MKDIR) -p $(dir $@) cp -f $^ $@ - + # SDL Port # Unix versions build only one binary @@ -255,7 +257,7 @@ $(OBJ)/%.o: %.rc else $(OBJ)/%.res: %.rc -@$(MKDIR) -p $(dir $@) - rc /fo $@ /dVERSION=\"$(VERSION)\" $^ + rc /fo $@ /dVERSION=\"$(VERSION)\" $^ %.o: %.res cvtres /OUT:"$@" $^ @@ -282,11 +284,11 @@ $(BIN)/tester/sameboy_tester.exe: $(CORE_OBJECTS) $(SDL_OBJECTS) $(BIN)/SDL/%.bin $(BIN)/tester/%.bin: $(BOOTROMS_DIR)/%.bin -@$(MKDIR) -p $(dir $@) cp -f $^ $@ - + $(BIN)/SameBoy.app/Contents/Resources/%.bin: $(BOOTROMS_DIR)/%.bin -@$(MKDIR) -p $(dir $@) cp -f $^ $@ - + $(BIN)/SDL/LICENSE: LICENSE -@$(MKDIR) -p $(dir $@) cp -f $^ $@ @@ -294,7 +296,7 @@ $(BIN)/SDL/LICENSE: LICENSE $(BIN)/SDL/registers.sym: Misc/registers.sym -@$(MKDIR) -p $(dir $@) cp -f $^ $@ - + $(BIN)/SDL/background.bmp: SDL/background.bmp -@$(MKDIR) -p $(dir $@) cp -f $^ $@ @@ -309,13 +311,13 @@ $(BIN)/BootROMs/%.bin: BootROMs/%.asm -@$(MKDIR) -p $(dir $@) cd BootROMs && rgbasm -o ../$@.tmp ../$< rgblink -o $@.tmp2 $@.tmp - head -c $(if $(findstring dmg,$@)$(findstring sgb,$@), 256, 2304) $@.tmp2 > $@ + head -c $(if $(findstring dmg,$@)$(findstring sgb,$@)$(findstring mgb,$@), 256, 2304) $@.tmp2 > $@ @rm $@.tmp $@.tmp2 # Libretro Core (uses its own build system) libretro: $(MAKE) -C libretro - + # Clean clean: rm -rf build diff --git a/test.pl b/test.pl new file mode 100755 index 0000000..3f91289 --- /dev/null +++ b/test.pl @@ -0,0 +1,188 @@ +#!/usr/bin/perl + +# This script parses Git blame's "porcelain" output format and +# ascertains the oldest lines of code seen. +# +# If you want to perform a custom report, just define your own callback +# function and invoke parse_porcelain() with it. +# +# The expected input format is slightly modified from raw `git blame +# -p`. Here is an example script for producing input: +# +# for f in `git ls-tree -r --name-only HEAD`; do \ +# echo "BEGIN_RECORD $f"; \ +# git blame -l -t -M -C -n -w -p $f; \ +# echo "END_RECORD $f"; \ +# done + +use strict; +use warnings FATAL => "all"; + +use POSIX qw(strftime); + +our @STATES = qw(global header_first header_metadata); + +our $RE_BEGIN_RECORD = qr/^BEGIN_RECORD\s(.*)$/msx; +our $RE_END_RECORD = qr/^END_RECORD\s(.*)$/msx; + +our $RE_LINE_HEADER = qr/ + ^ + ([a-z0-9]{40}) # SHA + \s(\d+) # Original line number + \s(\d+) # Current line number + (?:\s(\d+))? # Number of lines in group (optional) + $/msx; + +our $RE_HEADER_METADATA = qr/^([a-z-]+)\s(.*)$/msx; +our $RE_LINE_DATA = qr/^\t(.*)$/msx; + +# Parses Git blame's porcelain output. +# Calls the supplied $onBlock callback function when a full block of +# code has been parsed. The function receives a hashref describing the +# block. +sub parse_porcelain { + my ($fh, $onBlock) = @_; + + my $state = "global"; + my $metadata = {}; + my @lines; + my ($commit, $original_line, $current_line); + my $current_file; + + my $callOnBlock = sub { + my $data = {}; + $data->{'filename'} = $current_file; + $data->{'lines'} = \@lines; + $data->{'metadata'} = $metadata; + $data->{'commit'} = $commit; + + &$onBlock($data); + + @lines = (); + }; + + while (my $line = <$fh>) { + chomp $line; + + if ($line =~ $RE_BEGIN_RECORD) { + $state eq "global" or die "Parser error. Unexpected BEGIN_RECORD."; + + $current_file = $1; + $state = "header_first"; + + next; + } + elsif ($line =~ $RE_END_RECORD) { + $1 eq $current_file or die "Parser error. END_RECORD mismatch!"; + + if ($onBlock and scalar(@lines)) { + &$callOnBlock(); + } + + $state = "global"; + next; + } + + if ($state eq "header_first") { + $line =~ $RE_LINE_HEADER or die "Invalid initial header line! $line"; + my ($new_commit, $new_original_line, $new_current_line, $block_count); + ($new_commit, $new_original_line, $new_current_line, $block_count) = ($1, $2, $3, $4); + + if ($block_count and $onBlock and scalar(@lines)) { + &$callOnBlock(); + } + + $commit = $new_commit; + $original_line = $new_original_line; + $current_line = $new_current_line; + + $state = "header_metadata"; + next; + } + + if ($state eq "header_metadata") { + # Lines beginning with a tab denote line content. Subsequent line(s) + # will be metadata for that line. + if ($line =~ $RE_LINE_DATA) { + my $content = $1; + + push @lines, [$content, $original_line, $current_line]; + $state = "header_first"; + next; + } + + next if $line eq "boundary"; + + $line =~ $RE_HEADER_METADATA or die "Could not parse header metadata."; + my ($k, $v) = ($1, $2); + + $metadata->{$k} = $v; + next; + } + + die "Unknown state!"; + } +} + +# onBlock callback that collects oldest commit times for blocks. +my $old_lines = {}; +sub collect_times { + my ($data) = @_; + + # We filter non-relevant lines. + my $have_content = 0; + + foreach my $line (@{$data->{'lines'}}) { + my $s = $line->[0]; + + # Skip empty and whitespace. + next if $s =~ m/^\s*$/; + + # Skip things looking like comments. + next if $s =~ m/^\s*(#|\/\/|\/\*|\*\/)/; + + if ($s =~ m/[a-z0-9]/) { + $have_content = 1; + last; + } + } + + if (!$have_content) { + return; + } + + my $time = $data->{'metadata'}->{'committer-time'}; + + my $metadata = {}; + $metadata->{'commit'} = $data->{'commit'}; + $metadata->{'author'} = $data->{'metadata'}->{'author'}; + $metadata->{'filename'} = $data->{'filename'}; + $metadata->{'lines'} = []; + + foreach my $line (@{$data->{'lines'}}) { + push @{$metadata->{'lines'}}, $line->[2]; + } + + push @{$old_lines->{$time}}, $metadata; +} + +sub print_oldest_blocks { + my ($times) = @_; + + foreach my $time (sort { $a <=> $b } keys %$times) { + my $blocks = $times->{$time}; + my $date = strftime("%Y-%m-%d %H:%M:%S", gmtime($time)); + + print "Time: $time ($date)\n"; + foreach my $data (@$blocks) { + print " Commit: " . $data->{'commit'} . "\n"; + print " Author: " . $data->{'author'} . "\n"; + print " Filename: " . $data->{'filename'} . "\n"; + print " Lines: " . join(', ', @{$data->{'lines'}}) . "\n"; + } + } +} + +parse_porcelain(*STDIN, \&collect_times); +print_oldest_blocks($old_lines); + diff --git a/test.sh b/test.sh new file mode 100755 index 0000000..4f60127 --- /dev/null +++ b/test.sh @@ -0,0 +1,7 @@ +#!/bin/sh +for f in `git ls-tree -r --name-only HEAD`; do \ + echo "BEGIN_RECORD $f"; \ + git blame -l -t -M -C -n -w -p "$f"; \ + echo "END_RECORD $f"; \ +done | ./test.pl +