Dim Shared map1reg(3), map1bitpos, map1accum As UByte

Sub SwapPRG(ByVal banknum As UInteger, ByVal newchunk As UInteger, ByVal banksize As UInteger)
	Dim tmpbank As UInteger
	newchunk = (newchunk * banksize)
	For tmpbank = ((banknum*banksize) Shr 10) To ((banknum*banksize) Shr 10) + (banksize Shr 10) - 1
		prgbank(tmpbank) = newchunk
		newchunk = newchunk + 1024
	Next tmpbank
End Sub

Sub SwapCHR(ByVal banknum As UInteger, ByVal newchunk As UInteger, ByVal banksize As UInteger)
	Dim tmpbank As UInteger
	If ROM.chrcount = 0 Then Exit Sub
	newchunk = (newchunk * banksize)
	For tmpbank = ((banknum*banksize) Shr 10) To ((banknum*banksize) Shr 10) + (banksize Shr 10) - 1
		chrbank(tmpbank) = newchunk
		newchunk = newchunk + 1024
	Next tmpbank
End Sub

#Macro map1calc()
	Select Case As Const (map1reg(0) And 3)
		Case 0
			ntmap(0) = &h2000
			ntmap(1) = &h2000
			ntmap(2) = &h2000
			ntmap(3) = &h2000
		Case 1
			ntmap(0) = &h2400
			ntmap(1) = &h2400
			ntmap(2) = &h2400
			ntmap(3) = &h2400
		Case 2
			ntmap(0) = &h2000
			ntmap(1) = &h2400
			ntmap(2) = &h2000
			ntmap(3) = &h2400
		Case 3
			ntmap(0) = &h2000
			ntmap(1) = &h2000
			ntmap(2) = &h2400
			ntmap(3) = &h2400
	End Select
	If (map1reg(0) And 8) Then
		If (map1reg(0) And 4) Then
			SwapPRG(0, map1reg(3) And &hF, 16384)
			SwapPRG(1, (ROM.prgcount\16)-1, 16384)
		Else
			SwapPRG(0, 0, 16384)
			SwapPRG(1, map1reg(3) And &hF, 16384)
		End If
	Else
		SwapPRG(0, (map1reg(3) And &hF) Shr 1, 32768)
	End If
	If (map1reg(0) And 16) Then
		SwapCHR(0, map1reg(1), 4096)
		SwapCHR(1, map1reg(2), 4096)
	Else
		SwapCHR(0, map1reg(1) Shr 1, 8192)
	End If
#EndMacro

Sub mapperwrite(ByVal addr As UInteger, ByVal value As UInteger)
	Select Case As Const ROM.mapper
		Case 1 'MMC1
			If addr >= &h8000 Then
				If (value And 128) = 128 Then
					map1reg(0) = (map1reg(0) And &hF3)+&hC
					map1bitpos = 0: map1accum = 0
					Exit Sub
				End If
				map1accum = map1accum Or ((value And 1) Shl map1bitpos)
				If map1bitpos = 4 Then
					If (addr >= &hE000) Then
						map1reg(3) = map1accum
					ElseIf (addr >= &hC000) Then
						map1reg(2) = map1accum
					ElseIf (addr >= &hA000) Then
						map1reg(1) = map1accum
					Else
						map1reg(0) = map1accum
					End If
					map1calc()
					map1bitpos = 0: map1accum = 0
					Exit Sub
				End If
				map1bitpos = (map1bitpos + 1) Mod 5
			End If
		Case 2
			If addr >= &h8000 Then SwapPRG(0, value, 16384)
		Case 7 'AOROM
			Select Case addr
				Case Is >= &h8000
					SwapPRG(0, value And 15, 32768)
			End Select
	End Select
End Sub

#Macro SetupMapper()
	For n = 0 To 7
		chrbank(n) = n*1024
	Next n
	Select Case As Const ROM.mapper
		Case 0, 2
			SwapPRG(0, 0, 16384)
			SwapPRG(1, (ROM.prgcount \ 16)-1, 16384)
		Case 1
			Write6502(&h8000, 128)
			SwapPRG(0, 0, 16384)
			SwapPRG(1, (ROM.prgcount \ 16)-1, 16384)
		Case 7 'Nina-1
			SwapPRG(0, 0, 32768)
			SwapCHR(0, 0, 8192)
	End Select
#EndMacro
