Bộ tổng hợp âm thanh 8-bit NES
Loading...
NES 6502 8-bit Synthesizer

NES 6502: Bộ tổng hợp âm 8-bit

Màn trình diễn điên rồ nhất: Biến Nintendo thành nhạc cụ (Theremin) sử dụng chip APU.

synth.asm
; ---------------------------------------------------------
; NES 8-BIT SYNTHESIZER / THEREMIN
; Promeni starou konzoli NES na plne funkcni hudebni nastroj.
; A = Square Wave, B = Noise
; Up/Down = Pitch, Left/Right = Noise textury
; Obrazovka stroboskopicky pulzuje s frekvenci zvuku
; ---------------------------------------------------------

.org $C000

RESET:
  SEI
  CLD
  LDX #$40
  STX $4017    ; Vypnout APU frame IRQ
  LDX #$FF
  TXS          ; Inicializace zasobniku
  INX
  STX $2000    ; Vypnout NMI
  STX $2001    ; Vypnout renderovani (PPU)
  STX $4010    ; Vypnout DMC IRQ

  ; Zapnuti APU kanalu: Pulse 1 a Noise
  LDA #$09
  STA $4015

  ; Pocatecni promenne ulozene do RAM
  LDA #$80
  STA $00      ; Pulse 1 frekvence (Low)
  LDA #$02
  STA $01      ; Pulse 1 frekvence (High)
  LDA #$05
  STA $02      ; Noise perioda
  LDA #$30
  STA $03      ; Pocatecni barva pozadi

MainLoop:
WaitVblank:
  BIT $2002
  BPL WaitVblank

  ; Latch ovladace
  LDA #$01
  STA $4016
  LDA #$00
  STA $4016

  ; -------------------------
  ; Tlacitko A (Square Wave)
  ; -------------------------
  LDA $4016
  AND #$01
  BEQ A_NotPressed
  LDA #$BF     ; Hlasitost MAX, Duty cycle 50%
  STA $4000
  JMP ReadB
A_NotPressed:
  LDA #$B0     ; Hlasitost 0
  STA $4000

  ; -------------------------
  ; Tlacitko B (Noise)
  ; -------------------------
ReadB:
  LDA $4016
  AND #$01
  BEQ B_NotPressed
  LDA #$3F     ; Hlasitost Noise MAX
  STA $400C
  JMP ReadSelect
B_NotPressed:
  LDA #$30     ; Hlasitost Noise 0
  STA $400C

ReadSelect:
  LDA $4016    ; Ignorovat Select
  LDA $4016    ; Ignorovat Start

  ; -------------------------
  ; D-Pad ovladani
  ; -------------------------
ReadUp:
  LDA $4016
  AND #$01
  BEQ ReadDown
  DEC $00      ; Snizit periodu pulsu -> Vyssí tón

ReadDown:
  LDA $4016
  AND #$01
  BEQ ReadLeft
  INC $00      ; Zvysit periodu pulsu -> Nizsi tón

ReadLeft:
  LDA $4016
  AND #$01
  BEQ ReadRight
  DEC $02      ; Snizit periodu sumu

ReadRight:
  LDA $4016
  AND #$01
  BEQ UpdateAPU
  INC $02      ; Zvysit periodu sumu

  ; -------------------------
  ; Zapis do HW registru
  ; -------------------------
UpdateAPU:
  ; Zapis Pulse 1 pitch do zvukoveho cipu
  LDA $00
  STA $4002
  LDA $01
  STA $4003

  ; Zapis Noise pitch
  LDA $02
  AND #$0F
  STA $400E
  LDA #$08
  STA $400F

  ; -------------------------
  ; Audio-Reaktivni vizualizace
  ; -------------------------
  ; Vypocet barvy pozadi z vysky tonu ($00)
  LDA $00
  LSR A
  LSR A
  LSR A
  LSR A        ; Vydelit 16 (ziskame hodnotu 0-15)
  CLC
  ADC #$11     ; Pridat offset k palete barev
  STA $03      ; Ulozit novou barvu

  ; Zapis barvy do grafickeho cipu (PPU)
  LDA #$3F
  STA $2006
  LDA #$00
  STA $2006
  LDA $03
  STA $2007

  ; Zapnout zobrazeni obrazu
  LDA #$1E
  STA $2001

  JMP MainLoop

NMI:
IRQ:
  RTI

; --- VECTORY ($FFFA) ---
.org $FFFA
.dw NMI
.dw RESET
.dw IRQ

Đoạn mã này là Assembly 6502 được viết thủ công. Nó ghi các lệnh trực tiếp vào chip âm thanh (APU) của Nintendo và tạo ra âm thanh thủ tục. Nút A = âm sóng vuông. Nút B = Noise (nhiễu). Phím mũi tên Lên/Xuống thay đổi cao độ (Pitch). Phím mũi tên Trái/Phải thay đổi kết cấu nhiễu. Màn hình nhấp nháy theo tần số.

Nhận ROM .nes cho phần cứng thật:

  • Đây không phải trò đùa. Ứng dụng đã tự tay sắp xếp các byte (Hex) tương ứng với các lệnh 6502 và tạo ra ROM hợp lệ bao gồm cả header iNES.
  • Nhấn nút để tải về một nhạc cụ hoàn chỉnh dưới dạng băng NES 16KB.
  • Tải nó lên phần cứng thật (flashcart) hoặc thử trên bất kỳ trình giả lập nào. Mỗi lần bạn nhấn phím mũi tên, bạn đang ghi đè các thanh ghi APU tại địa chỉ $4002 và $400E.