cog/Frameworks/libsidplay/sidplay-residfp-code/libsidplayfp/src/psiddrv.a65

188 lines
4.7 KiB
Plaintext

/*
* This file is part of libsidplayfp, a SID player engine.
*
* Copyright 2014 Leandro Nini <drfiemost@users.sourceforge.net>
* Copyright 2001-2004 Simon White
* Copyright 2000 Dag Lem
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/***************************************************************************
* psiddrv.a65 - C64 Sid Player
*
* written by Dag Lem
* modified by Simon White for use in the sidplayer SIDPlay2.
*
* Build with:
* xa -R -G psiddrv.a65 -o psiddrv.o65
* od -v -An -w8 -tx1 psiddrv.o65 | sed -re 's/[[:alnum:]]+/0x&,/g' > psiddrv.bin
***************************************************************************/
; entry address
coldvec .word cold
; initial user interrupt vectors
irqusr .word irqret
; These should never run
brkusr .word exception
nmiusr .word exception
; redirect basic restart vector
; to finish the init sequence
; (hooks in via stop function)
stopusr .word setiomap
playnum .byte 0
speed .byte 0
initvec .word 0
playvec .word 0
initiomap .byte 0
playiomap .byte 0
video .byte 0
clock .byte 0
flags .byte 0
; init/play PSID
play jmp (playvec)
init jmp (initvec)
; cold start
cold sei
; turn interrupts off and
; clear any pending irqs
lda #$00
sta $d01a
lda $d019
sta $d019
lda #$7f
sta $dc0d
sta $dd0d
lda $dc0d
lda $dd0d
; setup hardware
; maximum volume
lda #$0f
sta $d418
; set CIA 1 Timer A to 50/60 Hz
lda video
beq ntsc
pal ldx #$25
ldy #$40
jmp timer
ntsc ldx #$95
ldy #$42
timer stx $dc04
sty $dc05
; set VICII raster to line 311 for RSIDs
ldx #$9b
ldy #$37
; we should use the proper values for
; the default raster, however if the tune
; is playing at the wrong speed (e.g.
; PAL at NTSC) use the compatibility
; raster instead to try make it work
eor clock
ora initiomap
beq vicinit
; set VICII raster to line 0 for PSIDs
; (compatibility raster)
ldx #$1b
ldy #$00
vicinit stx $d011
sty $d012
; don't override default irq handler for RSIDs
lda initiomap
beq irqinit
; if play address, override default irq vector so
; we reach our routine to handle play routine
lda playiomap
beq irqinit
ldx #<irqjob
stx $0314
; 0 indicates VIC timing (PSIDs only)
; else it's from CIA
irqinit lda speed
bne ciainit
; enable VICII raster interrupt
lda #$81
sta $d01a
jmp setiomap
; enable CIA 1 timer A interrupt
ciainit lda #$81
ldx #$01
sta $dc0d
stx $dc0e
; set I/O map and call song init routine
setiomap lda initiomap
bne setbank
; only release interrupt mask for real
; C64 tunes (initiomap = 0) thus
; providing a more realistic environment
lda #$37
setbank sta $01
setregs lda flags
pha
lda playnum
plp
jsr init
lda initiomap
beq idle
lda playiomap
beq run
lda #$37
sta $01
run cli
idle jmp idle
irqjob lda $01
pha
lda playiomap
sta $01
lda #0
jsr play
pla
sta $01
dec $d019
irqret lda $dc0d
pla
tay
pla
tax
pla
rti
; HLT
exception .byte $02
.end