;DBIOS 1.0 prévu pour SMS1 et à flasher dans un 27E257 ;Pitfall de merde: faire un define d'une variable sur autre chose que la RAM ($000A au lieu de $C00A) .EMPTYFILL $00 .COMPUTESMSCHECKSUM .MEMORYMAP DEFAULTSLOT 0 SLOTSIZE $8000 SLOT 0 $0000 .ENDME .ROMBANKMAP BANKSTOTAL 2 BANKSIZE $4000 BANKS 2 .ENDRO .DEFINE ASCIISTART $40 .DEFINE DELAYLOOP $04 .DEFINE WRAM_Start $C000 .DEFINE LastSRAMError $C001 ; $0000 à $BFFF .DEFINE SelectedSlot $C003 ; 0 à 2 .DEFINE OccupiedSlots $C004 ; 00000etd .DEFINE LastJoypad $C005 .DEFINE ChecksumAddr $C006 .DEFINE CurrentCSum $C008 ; Valeur du checksum en train d'être calculé .DEFINE ChecksumPages $C00A .DEFINE RAMCode $C010 .DEFINE HeaderCopies $C110 .BANK 0 SLOT 0 .org $0000 di im 1 ld sp,$DFF0 jp init .org $0010 ; Out DE sur $BF ld a,e out ($BF),a ld a,d out ($BF),a ret .org $0018 ld a,l ; Out HL sur $BF out ($BF),a ld a,h out ($BF),a ret .org $0038 push af ; Inc ($C000) à chaque VBL in a,($BF) exx rrca jr nc,rli ld hl,$C000 set 0,(hl) call VBLInt rli: exx pop af ei ret .org $0066 jp $0000 ; Reset retn init: in a,($BF) ; ? ld hl,PSGOff ; Volumes à 0 ld bc,$047F otir ld hl,$C000 ; Clear RAM ld (hl),l ld de,$C001 ld bc,$1FFF ldir waitvdpstart: ; Attend que le VDP démarre (voir doc GG) in a,($7E) cp $B0 jr nz,waitvdpstart ld b,DELAYLOOP call Pause ; 4 Ok (port $3E fait rien sinon) ld hl,VDPRegs ; Initialise tous les registres du VDP ld bc,$16BF otir ld de,$4000 ; Vide la VRAM rst $10 ld de,$3FFF ld bc,$00BE ClearVRAM: out (c),b dec de ld a,e or d jr nz,ClearVRAM ; Démarre le slot cartouche si 1P1 est appuyé in a,($DC) bit 4,a jr nz,nofastboot ld a,$01 ld (SelectedSlot),a jp BootSlot nofastboot: ld de,$C000 ; Charge les palettes rst $10 ld hl,PaletteBKG call LDPal ld hl,PaletteSPR call LDPal ld de,$4000 ; Charge les tiles du logo (2BPP) rst $10 ld hl,LogoTiles ld bc,$3A*2*8 LDTiles: ld a,(hl) inc hl out ($BE),a ld a,(hl) inc hl out ($BE),a xor a out ($BE),a out ($BE),a dec bc ld a,c or b jr nz,LDTiles ld de,$4000+(32*64) ; Charge les caractères ASCII (1BPP) rst $10 ld hl,Font ld bc,256*8 LD1Bpp: ld a,(hl) inc hl out ($BE),a xor a out ($BE),a nop out ($BE),a nop out ($BE),a dec bc ld a,c or b jr nz,LD1Bpp ld hl,$7800+(2*(10+(32*1))) ; Map du logo Ligne 1, Colonne 10 rst $18 ld de,LogoMap ld bc,$1A07 call Map ld de,$7800+(2*(0+(32*9))) ; Dessine le tableau rst $10 ld c,$00 ld hl,Columns call Print ld de,$81E0 ; Ecran on rst $10 ;-- SRAM Checking ---------------------------------------------------------------------------- ;ld de,$7800+(2*(4+(32*19))) ;rst $10 ;ld hl,StrCheck ;ld c,$00 ;call Print ;;Charge le testeur de SRAM en RAM ;ld de,RAMCode ;ld hl,SRAMCheck ;ld bc,$00FF ;ldir ;call RAMCode ; Largue l'adresse de la dernière erreur dans ($C001~$C002) ;ld de,$7800+(2*(15+(32*19))) ;rst $10 ;ld hl,(LastSRAMError) ;call Write16Bits ;-- Detection des slots utilisés ------------------------------------------------------------- ;Charge le detecteur de données en RAM ld de,RAMCode ld hl,CheckDiff ld bc,$00FF ldir RunDiffCheck: ld a,$FF ld (SelectedSlot),a call RAMCode ; Execution ld a,(OccupiedSlots) ld c,a ld b,$03 ld de,$7800+(2*(5+(32*11))) ShowUsedSlots: rst 10h ld hl,Yes sla c bit 3,c jr nz,used ld hl,No used: push bc ld c,$00 call Print pop bc ex de,hl ld de,$0040 ; Prochaine ligne add hl,de ex de,hl djnz ShowUsedSlots ;-- Slots header test ---------------------------------------------------------------------------- ;Charge le copieur de headers (128 octets) en RAM ld de,RAMCode ld hl,HeaderCpy ld bc,$0080 ldir call RAMCode ; Copie 16 octets de chaque header à $C100, $C110 et $C120 ld de,$7800+(2*(9+(32*11))) rst $10 ld de,HeaderCopies call WriteHeader ld de,$7800+(2*(9+(32*12))) rst $10 ld de,HeaderCopies+$10 call WriteHeader ld de,$7800+(2*(9+(32*13))) rst $10 ld de,HeaderCopies+$20 call WriteHeader call WriteRegions call WriteSizes ; Checksum lu ld de,$7800+(2*(18+(32*12))) rst $10 ld hl,(HeaderCopies+$1A) call Write16Bits ;-- Checks done ------------------------------------------------------------------------------ ;Sprite ld hl,$7F80 rst $18 ld a,$20 ; X out ($BE),a push ix pop ix ld a,$51 ; CHAR < out ($BE),a ld hl,$7F02 rst $18 ld a,$D0 ; Terminateur out ($BE),a call MajSprite ;-- Checksum calc ---------------------------------------------------------------------------- ld de,$7800+(2*(4+(32*17))) rst $10 ld hl,StrCSum ld c,$00 call Print ld de,RAMCode ld hl,Checksumer ld bc,$00FF ldir ld a,(HeaderCopies+$1F) ; Nat/Taille du slot cartouche sub $0A and $0F push af ld hl,CSumSizeTable ld b,$00 ld c,a add hl,bc ld b,(hl) ld c,$F0 ; Additionne $1000 octets,laisse un VBL passer,etc... ld de,$0000 ; Checksum=0 ld hl,$0000 ; Départ=($0000) call RAMCode pop af sub $04 jr c,NoPages ld b,$00 ld c,a ld hl,CSumPagesTable add hl,bc ld b,(hl) ld a,$02 DoPageCSum: push bc ld (ChecksumPages),a inc a push af ld bc,$4000 ld hl,$8000 ; Départ=($0000) call RAMCode pop af pop bc djnz DoPageCSum NoPages: ei Lp: ld a,($C000) ; Upload démarré sur état bas (il faudrait un front descendant plutot) bit 7,a jr z,Lp di ld de,$7800+(2*(4+(32*20))) rst $10 ld hl,StrUpload ld c,%00001000 call Print ld de,RAMCode ld hl,WriteSRAM ld bc,$00FF ldir call RAMCode ;Crash ici jr Lp CSumSizeTable: .db $1F,$3F,$7F,$BF ; $BF: Reproduit fidèlement le bug du BIOS 1.3 qui fait que le header passe dans le checksum :) .db $7F,$7F,$7F,$7F .db $7F,$7F,$7F,$7F .db $7F,$7F,$7F,$7F CSumPagesTable: .db $02,$06,$0e,$1e,$3e ;(64k,128k,256k,512k,1M) ;-- WriteSRAM: ld a,%11101011 ; RAM et I/O out ($3E),a ld a,%01101011 ; Exp out ($3E),a ;ld a,%11101011 ; RAM et I/O ;out ($3E),a ;ld a,%11100011 ; BIOS ;out ($3E),a ;ret ld bc,$8000 ld de,$0000 LoadByte: call WaitCLKd-WriteSRAM+RAMCode in a,($DC) ;DU...... and %11000000 rlca ;U......D rlca ;......DU ld l,a in a,($DD) ;......RL and %00000011 rlca ;.....RL. rlca ;....RL.. or l ;....RLDU ld l,a call WaitCLKd-WriteSRAM+RAMCode in a,($DC) ;DU...... and %11000000 rrc a ;.DU..... rrc a ;..DU.... or l ;..DURLDU ld l,a in a,($DD) ;......RL and %00000011 rrc a ;L......R rrc a ;RL...... or l ;RLDURLDU ld (de),a ld l,a ld a,$46 out ($BF),a ld a,$78 out ($BF),a call WriteUpl-WriteSRAM+RAMCode inc de dec bc ld a,b or c jr nz,LoadByte ld a,%01101011 ; Exp out ($3E),a jp $0000 WaitCLKd: ; Attends CLK haut WaitCLKUp: in a,($DD) bit 2,a jr z,WaitCLKUp ; Attends CLK bas WaitCLKDown: in a,($DD) bit 2,a jr nz,WaitCLKDown ret WriteUpl: ld a,l call Wrtu-WriteSRAM+RAMCode ld a,e Wrtu: push af and $F0 srl a srl a srl a srl a call CheckHexB-WriteSRAM+RAMCode add a,$70 out ($BE),a push ix pop ix xor a out ($BE),a pop af and $0F call CheckHexB-WriteSRAM+RAMCode add a,$70 out ($BE),a push ix pop ix xor a out ($BE),a ret CheckHexB: cp $0A ret c add a,7 ret ;-- Checksumer: ld a,%11101011 ; RAM et I/O out ($3E),a ld a,%10101011 ; Cart out ($3E),a ld a,(ChecksumPages) ld ($FFFF),a ; !!!! Checksumlp: ld a,e ; DE=DE+(HL) BC fois add a,(hl) ; Fait l'addition que sur E ld e,a ld a,d adc a,$00 ; Ajoute la retenue éventuelle à D ld d,a inc hl dec bc ld a,b or c jr z,Checksumdone ; Ret si BC=0 ld a,b and $0F ; Laisse passer un VBL à chaque fois que C=0 et bits 0,1,2,3 de B =0 (4096 cycles) or c jr nz,Checksumlp ld a,%11101011 ; RAM et I/O out ($3E),a ld a,%11100011 ; BIOS out ($3E),a ld (CurrentCSum),de xor a ld ($C000),a ei wvbl: ld a,($C000) or a jr z,wvbl di jr Checksumer Checksumdone: ld (CurrentCSum),de ld a,%11101011 ; RAM et I/O out ($3E),a ld a,%11100011 ; BIOS out ($3E),a ret ;-- Routine RAM qui detecte les slots occupés ------------------------------- CheckDiff: ld hl,ENSlots-CheckDiff+RAMCode ; Absolutisation du pointeur vers ENSlots ld b,$03 ; 3 Slots à faire ld d,$00 ; indicateur = 0 par défaut TestSlot: ld a,%11101011 ; RAM et I/O out ($3E),a ld a,(hl) ; Slot à tester out ($3E),a sla d ; Décaler l'indicateur de slots utilisés exx ld hl,$0000 ld b,$FF ; *255 ld e,(hl) ; ($0000) = reference pour la comparaison Loop: inc l ; Prochain octet ld a,(hl) cp e jr z,nodiff ld hl,SelectedSlot inc (hl) exx set 0,d ; Différence: bit à 1 exx jr slotdone nodiff: djnz Loop slotdone: exx inc hl ; Prochain slot djnz TestSlot ld a,d ld (OccupiedSlots),a ld a,%11101011 ; RAM et I/O out ($3E),a ld a,%11100011 ; BIOS out ($3E),a ret ENSlots: .db %01101011,%10101011,%11001011 ; Exp, Cart, Card ;-- Routine RAM pour lancer le slot dans B ----------------------------------- SRAMBoot: ld a,%11101011 ; RAM et I/O out ($3E),a ld a,b ld ($C000),a out ($3E),a nop jp $0000 ; Reset ;-- Routine RAM pour le test de la SRAM (48k) -------------------------------- SRAMCheck: ld a,%11101011 ; RAM et I/O out ($3E),a ld a,%01101011 ; Exp out ($3E),a xor a ; Vide le retour d'erreur ld (LastSRAMError),a ld (LastSRAMError+1),a ld d,%00101101 ; Code de test ld hl,$0000 ; Tout début de la SRAM ld bc,$BFFF ; Octets à vérifier (48K) checkbyte: ld (hl),d ; Tente d'écrire nop nop nop nop ld a,(hl) ; Relit et vérifie cp d jr z,byteok ld (LastSRAMError),hl ; Ecriture de l'adresse de l'erreur byteok: inc hl ; Prochain octet dec bc ; Un de moins à faire rrc d ld a,d xor l ld d,a ld a,b or c jr nz,checkbyte ld hl,RAMIS-SRAMCheck+RAMCode ; Position de RAMIS relative à $C010 ($4306-$42AD+$C010=$C069) ld de,$7FF0 ld bc,$0008 ldir ld a,%11101011 ; RAM et I/O out ($3E),a ld a,%11100011 ; BIOS out ($3E),a ret RAMIS: .db "SRAMisOK" ;-- Routine RAM pour copier les headers -------------------------------------- HeaderCpy: ld a,%11101011 ; RAM et I/O out ($3E),a ld a,%01101011 ; Exp out ($3E),a nop ld de,HeaderCopies ld bc,$0010 ld hl,$7FF0 ldir ld a,%10101011 ; Cart out ($3E),a nop ld de,HeaderCopies+$10 ld bc,$0010 ld hl,$7FF0 ldir ld a,%11001011 ; Card out ($3E),a nop ld de,HeaderCopies+$20 ld bc,$0010 ld hl,$7FF0 ldir ld a,%11101011 ; RAM et I/O out ($3E),a ld a,%11100011 ; BIOS out ($3E),a ret VBLInt: ld hl,PSGOff ; Volumes à 0 ld bc,$047F otir ld hl,(CurrentCSum) ld de,$7800+(2*(24+(32*17))) rst $10 call Write16Bits in a,($DD) bit 2,a jr nz,noCLK ; P2-1 à 0 ? > Upload ld a,($C000) set 7,a ld ($C000),a ret noCLK: ld h,a in a,($DC) push af ld l,a ld de,$7800+(2*(24+(32*18))) rst $10 call Write16Bits ld hl,LastJoypad pop af cpl ld c,a xor (hl) ; XOR précedent: trouver la différence ld (hl),c and c ; AND actuel: garder le front montant ret z ; Ret si pas de front bit 0,a jr nz,up bit 1,a jr nz,down bit 4,a jr nz,btn1 ret up: ld a,(SelectedSlot) ; Slot précedent si > 0 or a ret z dec a ld (SelectedSlot),a jp MajSprite down: ld a,(SelectedSlot) ; Slot suivant si < 2 bit 1,a ret nz inc a ld (SelectedSlot),a jp MajSprite btn1: BootSlot: ld de,RAMCode ; Charge la routine d'activation de slot ld hl,SRAMBoot ld bc,$0040 ldir ld b,%01101011 ; Exp ld a,(SelectedSlot) or a jr z,Run ld b,%10101011 ; Cart dec a jr z,Run ld b,%11001011 ; Card Run: jp RAMCode ; Boot MajSprite: ld hl,$7F00 rst $18 ld a,(SelectedSlot) sla a sla a sla a add a,$58 ; Y=(Slot*8)+$58 out ($BE),a ld a,%10010000 out ($7F),a ld a,%10000100 out ($7F),a ld a,%00001000 out ($7F),a ret WriteHeader: ld hl,TMR ld b,$08 Mapt: ld c,$00 ld a,(de) cp (hl) jr z,pass ld c,%0001000 ; Attribut: Palette SPR pass: add a,$40 out ($BE),a push ix pop ix ld a,c out ($BE),a push ix pop ix inc de inc hl djnz Mapt ret ;Environ 160ms Pause: ld de,$4000 ; 10 Wait: dec de ; 6 ld a,e ; 4 or d ; 4 jr nz,Wait ; 12 djnz Pause ; 13 39*$4000 ret ;HL=Text à écrire ;DE=Adresse VRAM ;C=Attribut ;$FF:saut de ligne, $00:fin Print: ld b,$00 ld a,(hl) inc hl or a ret z cp $FF jr nz,nolf ex de,hl push de ld de,$0040 add hl,de rst 18h pop de ex de,hl jr Print nolf: add a,ASCIISTART jr nc,no9thbit set 0,b no9thbit: out ($BE),a push ix pop ix ld a,c or b out ($BE),a jr Print WaitVBL: ei Waitlp: ld a,($C000) or a jr z,Waitlp ld a,($C000) res 0,a ld ($C000),a ret LDPal: ld b,$10 Pal: ld a,(hl) out ($BE),a push ix pop ix inc hl djnz Pal ret TMR: .db "TMR SEGA" StrFail: .db "Fail",$00 WriteRegions: ld de,$7800+(2*(23+(32*11))) rst $10 ld bc,HeaderCopies+$0F call WriteRegion ld de,$7800+(2*(23+(32*12))) rst $10 ld bc,HeaderCopies+$1F call WriteRegion ld de,$7800+(2*(23+(32*13))) rst $10 ld bc,HeaderCopies+$2F WriteRegion: ld hl,Regions ld a,(bc) ; Region sur les 4 MSB and $F0 ; Masquage srl a ; (A>>4)*4=A>>2, le texte est sur 4 octets srl a ld d,$00 ld e,a add hl,de ld c,$00 jp Print ; Call,Ret=Jp WriteSizes: ld de,$7800+(2*(27+(32*11))) rst $10 ld bc,HeaderCopies+$0F call WriteSize ld de,$7800+(2*(27+(32*12))) rst $10 ld bc,HeaderCopies+$1F call WriteSize ld de,$7800+(2*(27+(32*13))) rst $10 ld bc,HeaderCopies+$2F WriteSize: ld hl,Sizes ld a,(bc) ; Taille sur les 4 MSB and $0F ; Masquage ld b,a ; A=A*5=A+(A<<2) sla a sla a add a,b ld d,$00 ld e,a add hl,de ld c,$00 jp Print ; Call,Ret=Jp Write16Bits: ld a,h call Wrt ld a,l Wrt: push af and $F0 srl a srl a srl a srl a call CheckHex add a,$70 out ($BE),a push ix pop ix xor a out ($BE),a pop af and $0F call CheckHex add a,$70 out ($BE),a push ix pop ix xor a out ($BE),a ret CheckHex: cp $0A ret c add a,7 ret Map: push bc Mapl: ld a,(de) out ($BE),a inc de djnz Mapl push de ld de,$0040 add hl,de pop de rst $18 pop bc dec c ld a,c or a jr nz,Map ret VDPRegs: .db %00010110,$80 ; IE1 on .db %10100000,$81 ; 101 Screen off IE on .db $FF,$82 .db $FF,$83 .db $FF,$84 .db $FF,$85 .db $FB,$86 .db $00,$88 .db $00,$89 .db $FF,$8A ; RLI off .db $00,$87 ; Bordure = couleur 0 PSGOff: .db $9F,$BF,$DF,$FF LogoTiles: .incbin "logotiles.bin" LogoMap: .incbin "logomap.bin" Font: .incbin "pcfont256.bin" PaletteBKG: .db $00,$3F,$35,$20 ; Noir, Blanc, Bleu clair, Bleu foncé .db $00,$00,$00,$00,$00,$00 .db %00000011,%00001011,%00001111,%00101000 .db %00110001,%00110010 PaletteSPR: .db $00,$03,$00,$00 ; Noir, Rouge .db $00,$00,$00,$00,$00,$00 .db %00000011,%00001011,%00001111,%00101000 .db %00110001,%00110010 StrCheck: .db "SRAM Check:wait",$00 StrCSum: .db "Calculated checksum:wait",$00 StrUpload: .db "Uploading",$00 Yes: .db "Yes",$00 No: .db "No",$00 Columns: .db "ÉÍÍÍÍDIFÑÍHEADERÍÑCSUMÑLOCÑSIZE»",$FF .db "º ³ ³ ³ ³ º",$FF .db "ºExp ³ ³wait³ ³ º",$FF .db "ºCrt ³ ³wait³ ³ º",$FF .db "ºCrd ³ ³wait³ ³ º",$FF .db "ÈÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍÍÍÍÍÍÏÍÍÍͼ",$00 Regions: .db "$00",$00 .db "$01",$00 .db "$02",$00 .db "MSj",$00 .db "MSe",$00 .db "GGj",$00 .db "GGe",$00 .db "GGi",$00 .db "$08",$00 .db "$09",$00 .db "$0A",$00 .db "$0B",$00 .db "$0C",$00 .db "$0D",$00 .db "$0E",$00 .db "$0F",$00 Sizes: .db "256K",0 .db "512K",0 .db "1M ",0 .db "3(?)",0 .db "4(?)",0 .db "5(?)",0 .db "6(?)",0 .db "7(?)",0 .db "8(?)",0 .db "9(?)",0 .db "8K ",0 .db "16K ",0 .db "32K ",0 .db "48K ",0 .db "64K ",0 .db "128K",0 .BANK 1 SLOT 0 .org $3FF0 .db "DEBUBIOS",$00,$00,$AD,$DE,$FF,$FF,$FF,$4C ;MSe 32K