Advertisement
rilo

C64 NMI Digi player

Sep 27th, 2017
947
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. NMI player by Scan/House Designs/DESiRE (Richard Loerakker)
  3.  
  4. This is a small example of playing 8-bit samples at 8000Hz using a Commodore 64
  5.  
  6. Compile using Kick Assembler (http://www.theweb.dk/KickAssembler/)
  7.  
  8. Using Audacity:
  9.     Open some audio file
  10.     Set project frequency at 8000Hz
  11.     Convert audio to mono
  12.     (Apply other fx optionally)
  13.     Select about 6 seconds of data (that's about the most that can fit uncompressed in memory)
  14.     Choose from File menu Export Selected audio
  15.         File type: Other uncompressed files
  16.         Header: RAW (header-less)
  17.         Encoding: Unsigned 8-bit PCM
  18.  
  19. References:
  20.  
  21.     One SID channel digi: http://codebase64.org/doku.php?id=base:vicious_sid_demo_routine_explained
  22.     How I acknowledge and exit NMI: http://codebase64.org/doku.php?id=base:quick_exit_from_interrupt       
  23.     Memory map: http://www.awsm.de/mem64/
  24.     Kernal disassembly: http://unusedino.de/ec64/technical/aay/c64/krnromma.htm
  25.  
  26.  */
  27. .const samplefile = "carachangren.raw"
  28. .const NTSCorPAL = $02a6
  29. .pc = $0801 "Basic UpStart"
  30.                 :BasicUpstart2(start)
  31.  
  32. .pc = * "Entrypoint"
  33. start:         
  34.                 jsr $ff81       // init editor & video chips
  35.                 jsr $ff84       // init io, ports & timers
  36.                 jsr $ff8a       // restore vectors to default
  37.  
  38.                 lda #$00        // turn off screen
  39.                 sta $d011
  40.  
  41.                 sei             // set interrupt flag
  42.  
  43.                 lda #$35        // turn off basic and kernal rom
  44.                 sta $01
  45.  
  46.                 lda #$7f        // turn off cia timers
  47.                 sta $dc0d  
  48.                 sta $dd0d  
  49.  
  50.                 lda $dc0d       // acknowledge possible pending interrupts
  51.                 lda $dd0d  
  52.                 lda $d019
  53.  
  54.                 lda #%00001111  // set generic volume to 15
  55.                 sta $d418
  56.  
  57.                 lda #$00        // ADSR voice 3
  58.                 sta $d413
  59.                 lda #$f0
  60.                 sta $d414
  61.  
  62.                 lda #<nmi       // set NMI vector
  63.                 clc
  64.                 adc NTSCorPAL
  65.                 sta $fffa  
  66.  
  67.                 lda #>nmi
  68.                 sta $fffb
  69.  
  70.                 lda #RTI
  71.                 sta $dd0c      
  72.  
  73.                 lda NTSCorPAL
  74.                 bne isPAL
  75.                 lda #$81
  76.                 bne isNTSC
  77.  
  78. isPAL:          lda #$7a        // set NMI timer to 122 cycles (#$81 for NTSC)
  79. isNTSC:         sta $dd04
  80.                 lda #$00
  81.                 sta $dd05
  82.  
  83.                 lda #$81        // start the NMI timer
  84.                 sta $dd0d
  85.                 lda #$01
  86.                 sta $dd0e
  87.                 cli
  88. !:         
  89. .label wait = * + 1
  90.                 lda #$00        // wait for sample to be finished
  91.                 beq !-
  92.  
  93.                 sei
  94.                 lda #$37        // turn back on basic and kernal rom
  95.                 sta $01
  96.  
  97.                 // wait a little
  98.                 ldy #$30
  99. rep:            ldx #$00
  100. !:              dex
  101.                 bne !-
  102.                 dey
  103.                 bne rep
  104.                 jmp 64738       // reset
  105.  
  106. .pc = * "NMI's"
  107.  
  108. nmi:           
  109.  
  110.                 nop             // wait 6 cycles (otherwise a high-pitched note can be observed)
  111.                 nop             // (add extra nop for NTSC)
  112.                 nop
  113.                 nop
  114.                 sta $ff
  115.  
  116.                 // this is mostly cut and paste stuff from codebase
  117.                 lda #$11        // step 1 (triangle waveform, voice 3 on (ADS cycle)
  118.                 sta $d412
  119.  
  120.                 lda #$09        // step 2 & 3 (voice 3 on, disabled, reset noise generator)
  121.                 sta $d412
  122.  
  123. .label offset = *+1
  124.                 lda sample      // step 4 (set high byte of frequency with sample data)
  125.                 sta $d40f
  126.  
  127.                 lda #$01        // step 5 (voice 3 on, no waveform selected)
  128.                 sta $d412
  129.  
  130.                 inc offset
  131.                 bne notatend
  132.                 inc offset+1
  133.                 lda offset+1
  134.                 cmp #>end_of_sample
  135.                 bne notatend
  136.  
  137.                 inc wait        // <- remove this if you want to loop the sample
  138.                 lda #>sample
  139.                 sta offset+1
  140.  
  141. notatend:       lda $ff
  142.                 jmp $dd0c
  143.  
  144. .align 256
  145. .pc = * "8-bit sample data"
  146. sample:         .import binary samplefile
  147.  
  148. .pc = *
  149. end_of_sample:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement