e5afcd2ecd86 — Laurens Holst 4 years ago
SCC/SCCPlus: Improve detection.

The old detection had several problems:

1. If the value read from BANK_SELECT equals BANK it would not be found.
   This was an attempt to detect RAM, but fails if the ROM contains that value.
2. If SCC_PLUS_WAVEFORM5 reads 0 it would not be found. On SCC this register
   is not defined, so who knows what it returns. It should test it twice.

The detection is now rewritten to check more simply and hopefully more reliably.
Additionally, it now distinguishes between SCC and SCC+ by enabling SCC+ mode,
so that the SCC+ is accessed at a different address and completely distinct,
rather than relying on the more obscure 5th waveform readback feature.
2 files changed, 63 insertions(+), 82 deletions(-)

M src/drivers/SCC.asm
M src/drivers/SCCPlus.asm
M src/drivers/SCC.asm +41 -40
@@ 6,7 6,6 @@ SCC_WAVEFORM: equ 9800H
 SCC_FREQUENCY: equ 9880H
 SCC_AMPLITUDE: equ 988AH
 SCC_MIXER: equ 988FH
-SCC_PLUS_WAVEFORM5: equ 98A0H
 SCC_DEFORMATION: equ 98E0H
 SCC_BANK_SELECT: equ 9000H
 SCC_BANK: equ 3FH

          
@@ 159,56 158,58 @@ SCC_Detect:
 ; f <- c: found
 SCC_MatchSlot: PROC
 	ex af,af'
-	ld h,80H
+	ld h,SCC_BANK_SELECT >> 8
 	call Memory_GetSlot
-	push af
+	ex af,af'
+	ld h,SCC_BANK_SELECT >> 8
+	call Memory_SetSlot
+	call Test
+	ex af,af'
+	ld h,SCC_BANK_SELECT >> 8
+	call Memory_SetSlot
 	ex af,af'
-	ld h,80H
-	call Memory_SetSlot
-	ld a,(SCC_BANK_SELECT)
-	ld d,a
+	ret
+Test:
+	ld hl,SCC_BANK_SELECT & 0E000H
+	call SCC_TestReadback
+	ret z   ; is RAM
+	ld hl,SCCPlus_MODE & 0E000H
+	call SCC_TestReadback
+	ret z   ; is RAM
+	ld a,SCCPlus_MODE_SCCPLUS
+	ld (SCCPlus_MODE),a
 	ld a,SCC_BANK
 	ld (SCC_BANK_SELECT),a
 	ld hl,SCC_REGISTER_BASE
-	ld e,(hl)
-	xor a
-	ld (hl),a
-	ld a,(hl)
-	or a
-	jr nz,NoSCC
-	dec a
-	ld (hl),a
-	ld a,(hl)
-	inc a
-	jr nz,NoSCC
-	ld a,(SCC_BANK_SELECT)
-	cp SCC_BANK
-	jr z,NoSCC
-CheckSCCPlus:
-	ld a,00H
-	ld (SCC_WAVEFORM + 3 * 20H),a
-	ld a,(SCC_PLUS_WAVEFORM5)
-	cp 00H
-	jr nz,Found
-NoSCC:
-	ld (hl),e
-	ld a,d
-	ld (SCC_BANK_SELECT),a
-	pop af
-	ld h,80H
-	call Memory_SetSlot
-	and a
-	ret
-Found:
+	call SCC_TestReadback
 	ld a,SCC_BANK_DEFAULT
 	ld (SCC_BANK_SELECT),a
-	pop af
-	ld h,80H
-	call Memory_SetSlot
+	ld a,SCCPlus_MODE_SCC
+	ld (SCCPlus_MODE),a
+	ret nz  ; is not SCC
 	scf
 	ret
 	ENDP
 
+; hl = address
+; f <- z: read back, c: not set
+SCC_TestReadback:
+	di
+	ld c,(hl)
+	ld (hl),47H
+	ld a,(hl)
+	ei
+	ld (hl),c
+	xor 47H
+	ret nz
+	di
+	ld (hl),~47H
+	ld a,(hl)
+	ei
+	ld (hl),c
+	xor ~47H
+	ret
+
 ;
 SCC_name:
 	db "Konami SCC",0

          
M src/drivers/SCCPlus.asm +22 -42
@@ 182,52 182,32 @@ SCCPlus_Detect:
 ; f <- c: found
 SCCPlus_MatchSlot: PROC
 	ex af,af'
-	ld h,80H
+	ld h,SCCPlus_BANK_SELECT >> 8
 	call Memory_GetSlot
-	push af
 	ex af,af'
-	ld h,80H
+	ld h,SCCPlus_BANK_SELECT >> 8
+	call Memory_SetSlot
+	call Test
+	ex af,af'
+	ld h,SCCPlus_BANK_SELECT >> 8
 	call Memory_SetSlot
-	ld a,(SCC_BANK_SELECT)
-	ld d,a
-	ld a,SCC_BANK
-	ld (SCC_BANK_SELECT),a
-	ld hl,SCC_REGISTER_BASE
-	ld e,(hl)
-	xor a
-	ld (hl),a
-	ld a,(hl)
-	or a
-	jr nz,NoSCC
-	dec a
-	ld (hl),a
-	ld a,(hl)
-	inc a
-	jr nz,NoSCC
-	ld a,(SCC_BANK_SELECT)
-	cp SCC_BANK
-	jr z,NoSCC
-CheckSCCPlus:
-	ld a,00H
-	ld (SCC_WAVEFORM + 3 * 20H),a
-	ld a,(SCC_PLUS_WAVEFORM5)
-	cp 00H
-	jr z,Found
-NoSCC:
-	ld (hl),e
-	ld a,d
-	ld (SCC_BANK_SELECT),a
-	pop af
-	ld h,80H
-	call Memory_SetSlot
-	and a
+	ex af,af'
 	ret
-Found:
-	ld a,SCC_BANK_DEFAULT
-	ld (SCC_BANK_SELECT),a
-	pop af
-	ld h,80H
-	call Memory_SetSlot
+Test:
+	ld hl,SCCPlus_BANK_SELECT & 0E000H
+	call SCC_TestReadback
+	ret z   ; is RAM
+	ld a,SCCPlus_MODE_SCCPLUS
+	ld (SCCPlus_MODE),a
+	ld a,SCCPlus_BANK
+	ld (SCCPlus_BANK_SELECT),a
+	ld hl,SCCPlus_REGISTER_BASE
+	call SCC_TestReadback
+	ld a,SCCPlus_BANK_DEFAULT
+	ld (SCCPlus_BANK_SELECT),a
+	ld a,SCCPlus_MODE_SCC
+	ld (SCCPlus_MODE),a
+	ret nz  ; is not SCC+
 	scf
 	ret
 	ENDP