Hi, thanks for reply, i dont need much x86 asm help, but famicom/nes tech advice. I can develop in asm, but my knowledge of nes is limited, and i believe this is correct place for nes info
For example, im writting a mapper 69 for loopynes, i can load batman return joker until intro, but hangs before load a level, i read mapper69 data tech but i cant really understand how it works veryt well, then i write code without all the info
Code: Select all
.486p
.model flat
.code
PRG_BANKS equ 32
include empty.h
include kb.h
include file.h
include 6502.h
include ppu.h
include data.h
include equates.h
include debug.h
include memory.h
include map00.h
public mapperinit69
public hook69
public write0, write1, write2, write3
; --------------------------------------------------------------------------
; Mapper69 data layout
; --------------------------------------------------------------------------
latch0 equ mapperdata+0 ; CHR latch low (0..255)
latch1 equ mapperdata+1 ; CHR latch high (0..255)
irq_enable equ mapperdata+2 ; byte
irq_counter equ mapperdata+3 ; word (2 bytes)
reg_prg0 equ mapperdata+64 ; PRG bank $8000
reg_prg1 equ mapperdata+65 ; PRG bank $A000
reg_prg2 equ mapperdata+66 ; PRG bank $C000
mirroring equ mapperdata+68
total_prg equ mapperdata+69 ; ultimo banco PRG
cmd_byte equ mapperdata+70 ; command byte
write_toggle equ mapperdata+71 ; reservado
; --------------------------------------------------------------------------
mapperinit69:
; --------------------------------------------------------------------------
; Inicializa PRG banks
mov byte ptr [reg_prg0], 0
mov byte ptr [reg_prg1], 1
mov byte ptr [reg_prg2], 2
mov byte ptr [total_prg], (PRG_BANKS-1)
; Inicializa IRQ
mov byte ptr [irq_enable], 0
mov word ptr [irq_counter], 0
; Latches neutros (no FD/FE) ?¿
mov [latch0], 0
mov [latch1], 0
; Mirroring horizontal por defecto
mov byte ptr [mirroring], 0
; Byte command inicial
mov byte ptr [cmd_byte], 0
; Setup write handlers
mov [write_tbl+4*4], offset write0 ; $8000-$9FFF -> command byte
mov [write_tbl+5*4], offset write1 ; $A000-$BFFF -> param
mov [write_tbl+6*4], offset write2 ; $C000-$DFFF -> param
mov [write_tbl+7*4], offset write3 ; $E000-$FFFF -> param
; Map initial PRG banks
call romswitch69
; Scanline hook
mov [scanlinehook], offset hook69
ret
; --------------------------------------------------------------------------
; PRG bank switching
; --------------------------------------------------------------------------
romswitch69:
mov al, [reg_prg0]
call map89
mov al, [reg_prg1]
call mapAB
mov al, [reg_prg2]
call mapCD
mov al, [total_prg]
call mapEF
ret
; --------------------------------------------------------------------------
; CHR latch update
; --------------------------------------------------------------------------
chrswap:
push eax
push edi
; Latch0 -> bloques 0..3
mov al, [latch0]
movzx eax, al
shl eax, 12 ; << 12 = bank * 0x1000 (4KB pages) <-- ¿?
and eax, [chrmask]
add eax, [chr_ptr]
mov [chr_map+0], eax
add eax,1000h
mov [chr_map+4], eax
add eax,1000h
mov [chr_map+8], eax
add eax,1000h
mov [chr_map+12], eax
; Latch1 -> bloques 4..7
mov al, [latch1]
movzx eax, al
shl eax, 12 ; << 12 tambien aca?¿
and eax, [chrmask]
add eax, [chr_ptr]
mov [chr_map+16], eax
add eax,1000h
mov [chr_map+20], eax
add eax,1000h
mov [chr_map+24], eax
add eax,1000h
mov [chr_map+28], eax
call newchrmap
pop edi
pop eax
ret
; --------------------------------------------------------------------------
; Scanline IRQ hook (mejorada)
; --------------------------------------------------------------------------
hook69:
test [ctrl1], CR1_BG+CR1_OBJ ; si PPU desactivado, no tocar nada
jz h69_end
cmp [scanline],239
ja h69_end
; Solo procesar IRQ si esta habilitado
cmp byte ptr [irq_enable], 0
je h69_end
; decrement counter
mov ax, word ptr [irq_counter]
dec ax
mov word ptr [irq_counter], ax
jnz h69_end
; disparar IRQ si llego a 0
or [int_flags], IRQ
h69_end:
ret
; --------------------------------------------------------------------------
; Execute command
; --------------------------------------------------------------------------
do_command69:
push eax
push ebx
mov bl, [cmd_byte]
cmp bl, 8
jb .is_chr_command
; PRG / mirroring / IRQ commands
cmp bl, 9
je .cmd_9_prg8000
cmp bl, 0Ah
je .cmd_A_prgA000
cmp bl, 0Bh
je .cmd_B_prgC000
cmp bl, 0Ch
je .cmd_C_mirroring
cmp bl, 0Dh
je .cmd_D_irqcontrol
cmp bl, 0Eh
je .cmd_E_irq_low
cmp bl, 0Fh
je .cmd_F_irq_high
jmp .done
.is_chr_command:
cmp bl, 4
jb .set_latch0
mov [latch1], al
jmp .done_unpush
.set_latch0:
mov [latch0], al
.done_unpush:
call chrswap
.done:
pop ebx
pop eax
ret
; --------------------------------------------------------------------------
; Writes
; --------------------------------------------------------------------------
write0:
and al,0Fh
mov [cmd_byte], al
ret
write1:
call do_command69
ret
write2:
call do_command69
ret
write3:
call do_command69
ret
; --------------------------------------------------------------------------
; PRG commands
; --------------------------------------------------------------------------
.cmd_9_prg8000:
mov [reg_prg0], al
call romswitch69
jmp .done
.cmd_A_prgA000:
mov [reg_prg1], al
call romswitch69
jmp .done
.cmd_B_prgC000:
mov [reg_prg2], al
call romswitch69
jmp .done
.cmd_C_mirroring:
and al,03h
mov [mirroring], al
jmp .done
.cmd_D_irqcontrol:
mov [irq_enable], al
jmp .done
.cmd_E_irq_low:
movzx eax, al
mov bx, word ptr [irq_counter]
and bx, 0FF00h
or bx, ax
mov word ptr [irq_counter], bx
jmp .done
.cmd_F_irq_high:
movzx eax, al
shl eax, 8
mov bx, word ptr [irq_counter]
and bx, 0FFh
or bx, ax
mov word ptr [irq_counter], bx
jmp .done
end