Schrijver
| PCM player using SCC
|
dvik msx master Berichten: 1339 | Geplaatst: 22 Oktober 2007, 18:51   |
Here is a first version of the rom. It plays pretty well in official versions of openMSX, blueMSX and a real MSX. I need to do some more tests before I'm ready to post the source but its coming soon.
http://www.bluemsx.com/demos/sccplay.zip
|
|
ARTRAG msx master Berichten: 1737 | Geplaatst: 22 Oktober 2007, 18:58   |
GREAT!!!
You made it work on the existing BLUMSX, and on OPENMSX and on the real thing, ALL in one FILE!!!
This despite of the differences in the SCC implementation!
You're a THE MASTER!!
(going to disassembe it right now :-)
|
|
nikodr msx addict Berichten: 491 | Geplaatst: 22 Oktober 2007, 18:58   |
PERFECT!!!It works on the mega flash!Scc card plays the sample on my msx2 perfect!,i was amazed by this...  |
|
dvik msx master Berichten: 1339 | Geplaatst: 22 Oktober 2007, 19:10   |
ARTRAG. Here is the current source. Still a bit work in progress but its just minor timing issues I think:
I modified the code so it also compiles with tniasm. Shouldn't be hard to also make it work with asmsx.
EDIT: You may need to make minor mods to make it work with sjASM again, like the endian of the "AB" header.
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
fname "sccplay.rom"
org 4000h
dw "AB",START,0,0,0,0,0,0
Bank1: equ 05000h
Bank2: equ 07000h
Bank3: equ 09000h
Bank4: equ 0B000h
SampleFrequency: equ 11025
Period: equ 3579545 / 11025
;-------------------------------------
; Entry point
;-------------------------------------
START:
call powerup
xor a
call 005Fh
di
ld a,3Fh
LD (Bank3),A
;RRB000XX
ld a,00100000b ; Reset the sample counters (done on next write of period)
ld (98E0h),a
ld hl,Period
ld (9880h),hl
ld (9886h),hl
ld (9888h),hl
ld a,15
ld (988Ah),a ; volume ch1
xor a
ld (988Bh),a ; volume ch2
ld (988Ch),a ; volume ch3
ld (988Dh),a ; volume ch4
ld (988Eh),a ; volume ch5
ld a,00011111b ; ALL channels active
ld (988Fh),a
ld hl,9800h+32*3 ; counter in channel 4
ld bc,32*256
.counter:
ld (hl),c
inc hl
inc c
djnz .counter
;RRB000XX
ld a,10000000b ; Rotate only CH4 & CH5 common waveform. Waveform will be rotated with CH4 freq.
ld (98E0h),a
.REWIND:
xor a
.LOOP:
inc a
ld (Bank2),a
ld hl, SAMPLE_START
ex af,af'
ld b,0
.page:
push bc
;;;;;;;;;;;;;;;;;;;;;;
;
; do your stuff here
; in less than 32 / F_sample ch1 seconds
; but in more than 1 / F_sample ch1 seconds
; ld b,170
;.inner:
; ld a,r
; out(99h),a
; ld a,128+7
; out(99h),a
; djnz .inner
;
;;;;;;;;;;;;;;;;;;;;;;
ex de,hl
ld hl,9800h+32*3+4
xor a
.wait:
cp (hl)
jr nz,.wait ; wait for a complete rotation on ch 4
ex de,hl
ld de,9800h ; wavetable ch1
IF 1
;; The wave data should be pre calculated with the correct
;; format. This code converts 8-bit unsigned PCM to 8-bit
;; signed samples which is what the SCC operates on.
ld bc,2080h
.cploop:
ld a,(hl)
sub c
ld (de),a
inc hl
inc e
djnz .cploop
ELSE
ld bc,20h
ldir
ENDIF
pop bc
djnz .page
ex af,af'
cp (SAMPLE_END - SAMPLE_START + 1FFFh)/2000h
jr nz,.LOOP
jr .REWIND
ret
;-------------------------------------
; Powerup routine for non-Z180 code.
; set pages and subslot
;-------------------------------------
powerup:
call 0x138
rrca
rrca
and 0x03
ld c,a
ld b,0
ld hl,0xfcc1
add hl,bc
or (hl)
ld b,a
inc hl
inc hl
inc hl
inc hl
ld a,(hl)
and 0x0c
or b
ld h,0x80
call 0x24
ret
;-------------------------------------
; To make rom guesseres happy
;-------------------------------------
dummy:
xor a
ld (Bank1),a
ld (Bank3),a
ld (Bank1),a
ld (Bank3),a
ret
;-------------------------------------
; Padding for rom player
;-------------------------------------
DS (6000h - $)
;-------------------------------------
; Sample data
;-------------------------------------
SAMPLE_START:
incbin "handel4.wav",44, (56+64+128)*1024
SAMPLE_END:
;-------------------------------------
; Padding, align rom image to a power of two.
;-------------------------------------
SAMPLE_LENGTH: equ SAMPLE_END - SAMPLE_START
IF (SAMPLE_LENGTH <= 6000h)
DS (6000h - SAMPLE_LENGTH)
ELSE
IF (SAMPLE_LENGTH <= 10000h-2000h)
DS (E000h - SAMPLE_LENGTH)
ELSE
IF (SAMPLE_LENGTH <= 1E000h)
DS (1E000h - SAMPLE_LENGTH)
ELSE
IF (SAMPLE_LENGTH <= 3E000h)
DS (3E000h - SAMPLE_LENGTH)
ELSE
IF (SAMPLE_LENGTH <= 7E000h)
DS (7E000h - SAMPLE_LENGTH)
ELSE
DS (FE000h - SAMPLE_LENGTH)
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
FINISH:
|
|
NYYRIKKI msx master Berichten: 1525 | Geplaatst: 22 Oktober 2007, 19:10   |
Quote:
| Quote:
| I just checked: the info in NYYRIKKI's post seems to match the implementation in openMSX. Except for RR=11, in that case only channels 1-3 rotate and all channels are read-only.
|
I think that I might be wrong here. The documentation that I wrote here does not match what I remember I wrote down to my self... I'll check my memos again when I'm at home...
|
Yes, I made an error while converting notes to documentation... %11 is really CH1,CH2&CH3 rotating...
|
|
dvik msx master Berichten: 1339 | Geplaatst: 22 Oktober 2007, 19:13   |
So NYYRIKKI, can you post a new summary (just to get everything correct).
|
|
ARTRAG msx master Berichten: 1737 | Geplaatst: 22 Oktober 2007, 19:26   |
Actually the sole part I do not understand is the way in witch periods are computed and used.
Quote:
|
SampleFrequency: equ 11025
Period: equ 3579545 / 11025
|
I was relaying on WIKI info about SCC, now I see that WIKI is totally unreliable ....
http://en.wikipedia.org/wiki/Konami_SCC
They report that the period is divided by 32 !!! |
|
dvik msx master Berichten: 1339 | Geplaatst: 22 Oktober 2007, 19:26   |
Here is a summary of the changes I made:
1. The SCC samples are signed bytes, not unsigned
2. The sample counters need to be reset
3. The period of the rotation is the same as for playback (not 32x)
4. Some minor timing on when the full rotation is detected (to start transferring new samples)
5. The period calculation. And as ARTRAG I'm not entirely sure why this is correct.
6. The code needs to run with interrupts disabled because the bios int handler takes too long to
run. With lower sample frequencies it may not be required.
Item #4 is what I'm not entirely done with. It was timed correctly at one point but then I changed the code a bit and it may be off by one or two samples which will add noise.
|
|
ARTRAG msx master Berichten: 1737 | Geplaatst: 22 Oktober 2007, 19:37   |
Daniel,
have you tested how long does it take to do a complete rotation of the waveform in ch4?
not being anymore sure about periods, it could be nice to verify if this loop
.wait:
cp (hl)
jr nz,.wait ; wait for a complete rotation on ch 4
is actually lasting 32/11025 secs or far less
|
|
dvik msx master Berichten: 1339 | Geplaatst: 22 Oktober 2007, 19:39   |
Yes I verified that its ok. Can make it jp nz instead to save two cycles.
The loop should be good for sample frequencies up to 180kHz.
|
|
ARTRAG msx master Berichten: 1737 | Geplaatst: 22 Oktober 2007, 20:04   |
I guess that at 180KHz (!!) this offset
ex de,hl
ld hl,9800h+32*3+4
xor a
of +4 will pass to +1e6
Anyway still confused by the period thing ....
   |
|
nikodr msx addict Berichten: 491 | Geplaatst: 22 Oktober 2007, 20:06   |
Could this decoding of samples be used for games?Example is an adventure game,that could be installed on hard disk to have samples there...Would it work?In that way games could have speech or other cool effects...
|
|
dvik msx master Berichten: 1339 | Geplaatst: 22 Oktober 2007, 20:10   |
nikodr, Yes it can. NYYRIKKI gave some preliminary numbers that show that with sample frequencies around 3kHz its possible to use line interrupts to play the samples and there will be quite a lot of cycles left for actual game.
I was thinking of it yesterday and it would be possible to do a simple re-player that can play sampled music on one channel and sfx on another. More advanced replayers, like mod players is also possible but then I don't think it will be as much cpu left for the actual game.
|
|
nikodr msx addict Berichten: 491 | Geplaatst: 22 Oktober 2007, 20:13   |
For a turbo-r would those numbers be different?
|
|
dvik msx master Berichten: 1339 | Geplaatst: 22 Oktober 2007, 20:21   |
probably not. when you want to use an interrupt driven player, the main limitation is the region in VBLANK when you can't issue line interrupts.
When it comes to more advanced replayers, such as mod players, a TR would of course be beneficial.
|
|
|
|
|