From cb738190be6abca03d1cd3265440908107168a47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20K=C4=85dzio=C5=82ka?= Date: Sun, 3 May 2020 22:44:13 +0200 Subject: [PATCH] Add a 2bpp CGB boot ROM logo, pending palettes --- BootROMs/SameBoyLogo.png | Bin 14763 -> 479 bytes BootROMs/cgb_boot.asm | 116 ++++++++++++++++++++++++++------------- BootROMs/pb12.py | 68 +++++++++++++++++++++++ Makefile | 13 ++--- 4 files changed, 152 insertions(+), 45 deletions(-) create mode 100644 BootROMs/pb12.py diff --git a/BootROMs/SameBoyLogo.png b/BootROMs/SameBoyLogo.png index 4bc9706080a1d5e161d506f2d2be6d9c8e1446d4..c7cfc087dbf7a26a2969fc463d116b9e28eb58ac 100644 GIT binary patch delta 465 zcmV;?0WSWlbKe7y7=Ho-0000_WgT_^000b7OjJex|Nnn~fBygg000170)~4400E9k zL_t(2&yA8XZo@DPMHzU|sHMA(LKiteI>gABqv&c1I&`dpB6F{x05ZBr`2CFIphJcl zW-MEeXKQ3lQsjN*%!4hpQ&S3sG} z^6VxHz^3k}8BhsS(Jj@7f)Dc4Cz~FVo7>Rf2rx_^Q}w%=4I_(c^4B(0xOv*U`OvMd zuWE)kbmkB!&3|3Hv*;eF4m9Dn!u~ zO32V{^YirP=K~A~#fBD}H?nKUF%Iq4y9kbaYQ6(34paiPDNr^e8o<%(0$d4jOWOm$ zj=5L>FZ$J|Bc1pQc=KLvfL`!fZ&qn_HC(2BxEwLy5=#35u>6jP-U$>M#%2~9leL~x z*UVWtYJLF4^3nnX&}Ra14CW{k86!XU`$=!6=YQ&Hl>c47@!eI<`B+HV00000NkvXX Hu0mjf?upU~ literal 14763 zcmeI3Z)_7~9LEp;L>R#cCPQJ-vp}L?dw1P+TaUJ6w1ZCQoTJDl5V+kv-7ahIj=S61 zO_L2wTtG2om>^;#z5o=>e1nl_l!QP+{1Y%lvWyUvCyV*4SD>(o!B#*4lw5lhSP$6yrGkYelFckP%>l6tF}(lS-*eTLzlZbrYHPhO(_WV28J1(XYB%Q>cwS&xI`?sf zDqs{a#dBt|E+X}i|_CWbh?!HobejwG%v4a$ujHol5hh@r{WGU~_yN#qX zHCbXn5~P4?nb60T^+BYuSl(K8xKygF)3h3T;2q?Mly#c%UL7zkz|^`82{iP;nJg+d zdA(D!G_zBi=DzdY)84(MBnpdDG!?sNS{ukH)7b2utj#Hf>xFfR zB*`jEa>QWu%c3RTPnIHWX&y~h62148rJzJ|$dZuIjFf1Fl$6*37+viMFoi}$>6D$& zsG63jN}w?kf(;%;kp(Fs*Cu!%x@&ljck@1$b&C?uyA$m-{yMP+NIt2~!4Zq0_9>|& zn$&GqelE5AfT>p3Ou#MB%-lr|DZ#ZNi$`rsA9re>qTl1R-$t*tpnSNTPHh` zigUi`qG1Ai`vqN-`!9bW<TSb#(f(3z!Ma{mtdKW1TuC$Hvd`Zvj&<-+0fcINzG`29DQzxwG%Fd9Y>g;z=bLst zb6$8@IHuB`vd*@G)61hqq$6j{t}*go-6?@=D|}{vk1I_6d8N2I@_XnZ2ZcL&$cfQ( zWDt}FHYT{Rh)@B+h0?&r1Q!+&Dj>K}8rYcN!XiQi1Q$vJ8xveuM5ut^LTO-Qf(wfX z6%bq~4QxzsVG*GMf(xaAjR`I+B2++dp){~D!G%SH3J5Ng1~w+Ru!v9r!G+Sm#sn7@ z5h@_KP#V~n;KCw81q2sL0~-@uSVX9R;6iC&V}c8d2o(@qC=F~(aA6Ul0)h*rfsF|+ zEFx4uaG^A?F~NmJgbD~Qlm<2?xUh&&0l|gRz{Ug@77;2SxKJ9{nBc-9LIngDN&_3; z6IVsy4M3p6*Z$J*{k}Iw7w&=Y2GUZrB}P$w@Lj@zw<&7kUwFMnQQa&>UEfMk!iN+! zUmMzTdKJ{(X^hmzGozc%p4k0#ebwokXYXF{E~GCF9sKjqqe};_ZU10k-ppA~y?4qN zd1Bepi)fZq`s#8JI9X?ogR5z*!0Mf_cwl)ur4faY3mu=I6C;s&nthpddy#4 zIeYNp`MYzMpW6M$@R9Ycx0jE6KKtg~TjJwu+?Q8h*{7WJ4d1%W&;9Gn#NR)yT<}X| q|J65BRq~ZvM=n-=HTda`G&Q(G{(bH7&EG-_RAWO^WO(J)9sdD_A1D9- diff --git a/BootROMs/cgb_boot.asm b/BootROMs/cgb_boot.asm index 618e11a..6837615 100644 --- a/BootROMs/cgb_boot.asm +++ b/BootROMs/cgb_boot.asm @@ -87,20 +87,24 @@ ELSE .tilemapRowLoop + call .write_with_palette + + ; Repeat the 3 tiles common between E and B. This saves 27 bytes after + ; compression, with a cost of 17 bytes of code. push af - ; Switch to second VRAM Bank - ld a, 1 - ldh [$4F], a - ld [hl], 8 - ; Switch to back first VRAM Bank - xor a - ldh [$4F], a + sub $20 + sub $3 + jr nc, .notspecial + add $20 + call .write_with_palette + dec c +.notspecial pop af - ldi [hl], a - add d + + add d ; d = 3 for SameBoy logo, d = 1 for Nintendo logo dec c jr nz, .tilemapRowLoop - sub 47 + sub 44 push de ld de, $10 add hl, de @@ -116,6 +120,19 @@ ELSE ld l, $a7 ld bc, $0107 jr .tilemapRowLoop + +.write_with_palette + push af + ; Switch to second VRAM Bank + ld a, 1 + ldh [$4F], a + ld [hl], 8 + ; Switch to back first VRAM Bank + xor a + ldh [$4F], a + pop af + ldi [hl], a + ret .endTilemap ENDC @@ -532,7 +549,7 @@ TrademarkSymbol: db $3c,$42,$b9,$a5,$b9,$a5,$42,$3c SameBoyLogo: - incbin "SameBoyLogo.pb8" + incbin "SameBoyLogo.pb12" AnimationColors: dw $7FFF ; White @@ -634,30 +651,28 @@ ReadCGBLogoHalfTile: ld a, e ret -; LoadTileset using PB8 codec, 2019 Damian Yerrick -; -; The logo is compressed using PB8, a form of RLE with unary-coded -; run lengths. Each block representing 8 bytes consists of a control -; byte, where each bit (MSB to LSB) is 0 for literal or 1 for repeat -; previous, followed by the literals in that block. +; LoadTileset using PB12 codec, 2020 Jakub Kądziołka +; (based on PB8 codec, 2019 Damian Yerrick) SameBoyLogo_dst = $8080 SameBoyLogo_length = (128 * 24) / 64 LoadTileset: ld hl, SameBoyLogo - ld de, SameBoyLogo_dst + ld de, SameBoyLogo_dst - 1 ld c, SameBoyLogo_length -.pb8BlockLoop: - ; Register map for PB8 decompression +.refill + ; Register map for PB12 decompression ; HL: source address in boot ROM ; DE: destination address in VRAM ; A: Current literal value ; B: Repeat bits, terminated by 1000... - ; C: Number of 8-byte blocks left in this block ; Source address in HL lets the repeat bits go straight to B, ; bypassing A and avoiding spilling registers to the stack. ld b, [hl] + dec b + jr z, .sameboyLogoEnd + inc b inc hl ; Shift a 1 into lower bit of shift value. Once this bit @@ -665,26 +680,53 @@ LoadTileset: scf rl b -.pb8BitLoop: +.loop ; If not a repeat, load a literal byte - jr c,.pb8Repeat - ld a, [hli] -.pb8Repeat: - ; Decompressed data uses colors 0 and 1, so write once, inc twice - ld [de], a - inc de - inc de + jr c, .simple_repeat sla b - jr nz, .pb8BitLoop - - dec c - jr nz, .pb8BlockLoop - -; End PB8 decoding. The rest uses HL as the destination - ld h, d - ld l, e + jr c, .shifty_repeat + ld a, [hli] + jr .got_byte +.shifty_repeat + sla b + jr nz, .no_refill_during_shift + ld b, [hl] ; see above. Also, no, factoring it out into a callable + inc hl ; routine doesn't save bytes, even with conditional calls + scf + rl b +.no_refill_during_shift + ld c, a + jr nc, .shift_left + srl a + db $fe ; eat the add a with cp d8 +.shift_left + add a + sla b + jr c, .go_and + or c + db $fe ; eat the and c with cp d8 +.go_and + and c + jr .got_byte +.simple_repeat + sla b + jr c, .got_byte + ; far repeat + dec de + ld a, [de] + inc de +.got_byte + inc de + ld [de], a + sla b + jr nz, .loop + jr .refill +; End PB12 decoding. The rest uses HL as the destination .sameboyLogoEnd + ld h, d + ld l, $80 + ; Copy (unresized) ROM logo ld de, $104 .CGBROMLogoLoop diff --git a/BootROMs/pb12.py b/BootROMs/pb12.py new file mode 100644 index 0000000..0c06538 --- /dev/null +++ b/BootROMs/pb12.py @@ -0,0 +1,68 @@ +import sys + +def opts(byte): + # top bit: 0 = left, 1 = right + # bottom bit: 0 = or, 1 = and + if byte is None: return [] + return [ + byte | (byte << 1) & 0xff, + byte & (byte << 1), + byte | (byte >> 1) & 0xff, + byte & (byte >> 1), + ] + +def pb12(data): + data = iter(data) + + literals = bytearray() + bits = 0 + control = 0 + prev = [None, None] + gotta_end = False + + chunk = bytearray() + while True: + try: + byte = next(data) + except StopIteration: + if bits == 0: break + byte = 0 + chunk.append(byte) + + if byte in prev: + bits += 2 + control <<= 1 + control |= 1 + control <<= 1 + if prev[1] == byte: + control |= 1 # 10 = out[-2], 11 = out[-1] + else: + bits += 2 + control <<= 2 + options = opts(prev[1]) + if byte in options: + # 01 = modify + control |= 1 + + bits += 2 + control <<= 2 + control |= options.index(byte) + else: + # 00 = literal + literals.append(byte) + prev = [prev[1], byte] + if bits >= 8: + outctl = control >> (bits - 8) + assert outctl != 1 # that's the end byte + yield bytes([outctl]) + literals + bits -= 8 + control &= (1 << bits) - 1 + literals = bytearray() + chunk = bytearray() + yield b'\x01' + +_, infile, outfile = sys.argv +with open(infile, 'rb') as f: + data = f.read() +with open(outfile, 'wb') as f: + f.writelines(pb12(data)) diff --git a/Makefile b/Makefile index afc8d89..1f81862 100644 --- a/Makefile +++ b/Makefile @@ -382,21 +382,18 @@ $(BIN)/SDL/Shaders: Shaders # Boot ROMs -$(OBJ)/%.1bpp: %.png +$(OBJ)/%.2bpp: %.png -@$(MKDIR) -p $(dir $@) - rgbgfx -d 1 -h -o $@ $< + rgbgfx -h -u -o $@ $< -$(OBJ)/BootROMs/SameBoyLogo.pb8: $(OBJ)/BootROMs/SameBoyLogo.1bpp $(PB8_COMPRESS) - $(realpath $(PB8_COMPRESS)) -l 384 $< $@ - -$(PB8_COMPRESS): BootROMs/pb8.c - $(CC) $< -o $@ +$(OBJ)/BootROMs/SameBoyLogo.pb12: $(OBJ)/BootROMs/SameBoyLogo.2bpp BootROMs/pb12.py + python3 BootROMs/pb12.py $< $@ $(BIN)/BootROMs/agb_boot.bin: BootROMs/cgb_boot.asm $(BIN)/BootROMs/cgb_boot_fast.bin: BootROMs/cgb_boot.asm $(BIN)/BootROMs/sgb2_boot: BootROMs/sgb_boot.asm -$(BIN)/BootROMs/%.bin: BootROMs/%.asm $(OBJ)/BootROMs/SameBoyLogo.pb8 +$(BIN)/BootROMs/%.bin: BootROMs/%.asm $(OBJ)/BootROMs/SameBoyLogo.pb12 -@$(MKDIR) -p $(dir $@) rgbasm -i $(OBJ)/BootROMs/ -i BootROMs/ -o $@.tmp $< rgblink -o $@.tmp2 $@.tmp