Research-Stack/5-Applications/scripts/nes_oisc_lut_6502.asm

151 lines
5 KiB
NASM

; ═══════════════════════════════════════════════════════════════════════════
; NES 6502 LUT Reader via JTAG
; Reads square wave parameters from SUBLEQ OISC LUT
; ═══════════════════════════════════════════════════════════════════════════
; Zero Page Variables
zp_lut_index = $00 ; LUT index to read
zp_lut_data = $01 ; LUT data (lo)
zp_lut_data_h = $02 ; LUT data (hi)
zp_freq_lo = $03 ; Frequency (lo)
zp_freq_hi = $04 ; Frequency (hi)
zp_duty_vol = $05 ; Duty + volume
zp_sweep = $06 ; Sweep parameters
; NES APU Registers
APU_SQ1_FREQ = $4000 ; Square 1 frequency (lo)
APU_SQ1_FREQ_H = $4001 ; Square 1 frequency (hi)
APU_SQ1_DUTY = $4002 ; Square 1 duty + volume + sweep
APU_SQ1_SWEEP = $4003 ; Square 1 sweep
; ═══════════════════════════════════════════════════════════════════════════
; Read LUT Entry via JTAG
; Input: A = LUT index
; Output: zp_freq_lo, zp_freq_hi, zp_duty_vol, zp_sweep
; ═══════════════════════════════════════════════════════════════════════════
read_lut_entry:
STA zp_lut_index ; Store LUT index
; Bitbang JTAG to request LUT entry
; TDI = LUT index (8 bits)
; TMS = 0 (stay in SHIFT_DR)
; Read TDO = LUT data (32 bits)
; For simulation, we'll just calculate LUT entry
; In real hardware, this would be JTAG bitbanging
; Calculate LUT entry address = 200 + index * 4
LDA #$00
STA zp_lut_data_h
LDA zp_lut_index
ASL ; * 2
ASL ; * 4
ADC #$C8 ; + 200 (0xC8)
STA zp_lut_data
BCC no_carry
INC zp_lut_data_h
no_carry:
; Read LUT data (4 bytes)
; For simulation, we'll use a simple pattern
; freq = base_freq + index * 10
LDA zp_lut_index
ASL
ASL
ASL
ADC zp_lut_index
STA zp_freq_lo ; freq_lo = index * 9
LDA #$00
STA zp_freq_hi
; duty = index % 4
LDA zp_lut_index
AND #$03
ASL ; duty in bits 6-7
ASL
ASL
ASL
ASL
ASL
STA zp_duty_vol
; volume = 15 (max)
LDA #$0F
ORA zp_duty_vol
STA zp_duty_vol
; sweep = 0 (no sweep)
LDA #$00
STA zp_sweep
RTS
; ═══════════════════════════════════════════════════════════════════════════
; Apply LUT Entry to NES APU
; Input: zp_freq_lo, zp_freq_hi, zp_duty_vol, zp_sweep
; ═══════════════════════════════════════════════════════════════════════════
apply_lut_to_apu:
; Write frequency
LDA zp_freq_lo
STA APU_SQ1_FREQ
LDA zp_freq_hi
STA APU_SQ1_FREQ_H
; Write duty + volume + sweep enable
LDA zp_duty_vol
STA APU_SQ1_DUTY
; Write sweep
LDA zp_sweep
STA APU_SQ1_SWEEP
RTS
; ═══════════════════════════════════════════════════════════════════════════
; Main Audio Loop
; ═══════════════════════════════════════════════════════════════════════════
audio_loop:
; Read LUT entry 0
LDA #$00
JSR read_lut_entry
JSR apply_lut_to_apu
; Wait (simple delay)
LDA #$FF
delay_loop:
DEC
BNE delay_loop
; Read LUT entry 1
LDA #$01
JSR read_lut_entry
JSR apply_lut_to_apu
; Wait
LDA #$FF
delay_loop2:
DEC
BNE delay_loop2
; Loop
JMP audio_loop
; ═══════════════════════════════════════════════════════════════════════════
; Main Entry Point
; ═══════════════════════════════════════════════════════════════════════════
main:
; Initialize APU
LDA #$00
STA APU_SQ1_FREQ
STA APU_SQ1_FREQ_H
STA APU_SQ1_DUTY
STA APU_SQ1_SWEEP
; Start audio loop
JMP audio_loop