A.D.A. Amiga Demoscene Archive

        Welcome guest!

  

  

  

log in with SceneID

  

Demos Amiga Demoscene Archive Forum / Coding / Code to play 4channel mods?

 

Author Message
sdw
Member
#1 - Posted: 27 May 2016 17:31
Reply Quote
I want to play good old normal 4 channel modules in my demo/intro.
In my first little "comeback" on the Amiga scene (http://www.pouet.net/prod.php?which=61596) I wrote everything in pure assembler (like I did back in the 90ies) and reused the same old Noistetracker replay code from Kaktus & Mahoney (C) 1990.
Worked fine, just call mt_init at startup and mt_music every frame and all is OK.

Now I have moved along to a bit more modern way of developing, so I have setup a VBCC+VASM based build system, where my main code is in C and then I call assembler functions where extra speed is needed.
It also works fine, at least until I added music.
The Noisetracker replayer simply does not get along with this new setup, at all.
Somehow just calling mt_init manages to mess up bitplane pointers, and while running mt_music every frame actually plays the music, I get some kind of system error on every exit and have to reboot my (emulated) Amiga.
I have tried looking at the replayer code and see if I can find what is going wrong, but no luck.

Is there any better and easier option to replay 4 channel modules (A500 OCS is my target)?

I looked into P61Play, but that was just way to hard to get going.
1) The code didn't even compile in VASM
2) Looking at page iupon page ofl the strange options I have to setup makes my eyes glaze over. I want to call init, play and that's it.
3) It requires converting the modules from mod to p61.

So, are there any small, quick and easy .mod replayers with source that I can drop in and see if it works better than the Noisetracker replayer?
sdw
Member
#2 - Posted: 27 May 2016 17:34
Reply Quote
Oh, for reference, here's the replay code I am trying to use that isn't working anymore:
;ญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญ
;ญ NoisetrackerV2.0 FASTreplay ญ
;ญ Uses lev6irq - takes 8 rasterlines ญ
;ญ Do not disable Master irq in $dff09a ญ
;ญ Used registers: d0-d3/a0-a7| =INTENA ญ
;ญ Mahoney & Kaktus - (C) E.A.S. 1990 ญ
;ญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญญ

mt_init:lea mt_data,a0
lea mt_mulu(pc),a1
move.l #mt_data+$c,d0
moveq #$1f,d1
moveq #$1e,d3
mt_lop4:move.l d0,(a1)+
add.l d3,d0
dbf d1,mt_lop4

lea $3b8(a0),a1
moveq #$7f,d0
moveq #0,d1
moveq #0,d2
mt_lop2:move.b (a1)+,d1
cmp.b d2,d1
ble.s mt_lop
move.l d1,d2
mt_lop: dbf d0,mt_lop2
addq.w #1,d2

asl.l #8,d2
asl.l #2,d2
lea 4(a1,d2.l),a2
lea mt_samplestarts(pc),a1
add.w #$2a,a0
moveq #$1e,d0
mt_lop3:clr.l (a2)
move.l a2,(a1)+
moveq #0,d1
move.b d1,2(a0)
move.w (a0),d1
asl.l #1,d1
add.l d1,a2
add.l d3,a0
dbf d0,mt_lop3

move.l $78.w,mt_oldirq-mt_samplestarts-$7c(a1)
or.b #2,$bfe001
move.b #6,mt_speed-mt_samplestarts-$7c(a1)
moveq #0,d0
lea $dff000,a0
move.w d0,$a8(a0)
move.w d0,$b8(a0)
move.w d0,$c8(a0)
move.w d0,$d8(a0)
move.b d0,mt_songpos-mt_samplestarts-$7c(a1)
move.b d0,mt_counter-mt_samplestarts-$7c(a1)
move.w d0,mt_pattpos-mt_samplestarts-$7c(a1)
rts


mt_end: moveq #0,d0
lea $dff000,a0
move.w d0,$a8(a0)
move.w d0,$b8(a0)
move.w d0,$c8(a0)
move.w d0,$d8(a0)
move.w #$f,$dff096
rts


mt_music:
lea mt_data,a0
lea mt_voice1(pc),a4
addq.b #1,mt_counter-mt_voice1(a4)
move.b mt_counter(pc),d0
cmp.b mt_speed(pc),d0
blt mt_nonew
moveq #0,d0
move.b d0,mt_counter-mt_voice1(a4)
move.w d0,mt_dmacon-mt_voice1(a4)
lea mt_data,a0
lea $3b8(a0),a2
lea $43c(a0),a0

moveq #0,d1
move.b mt_songpos(pc),d0
move.b (a2,d0.w),d1
lsl.w #8,d1
lsl.w #2,d1
add.w mt_pattpos(pc),d1

lea $dff0a0,a5
lea mt_samplestarts-4(pc),a1
lea mt_playvoice(pc),a6
jsr (a6)
addq.l #4,d1
lea $dff0b0,a5
lea mt_voice2(pc),a4
jsr (a6)
addq.l #4,d1
lea $dff0c0,a5
lea mt_voice3(pc),a4
jsr (a6)
addq.l #4,d1
lea $dff0d0,a5
lea mt_voice4(pc),a4
jsr (a6)

move.w mt_dmacon(pc),d0
beq.s mt_nodma

lea $bfd000,a3
move.b #$7f,$d00(a3)
move.w #$2000,$dff09c
move.w #$a000,$dff09a
move.l #mt_irq1,$78.w
moveq #0,d0
move.b d0,$e00(a3)
move.b #$a8,$400(a3)
move.b d0,$500(a3)
or.w #$8000,mt_dmacon-mt_voice4(a4)
move.b #$11,$e00(a3)
move.b #$81,$d00(a3)

mt_nodma:
add.w #$10,mt_pattpos-mt_voice4(a4)
cmp.w #$400,mt_pattpos-mt_voice4(a4)
bne.s mt_exit
mt_next:clr.w mt_pattpos-mt_voice4(a4)
clr.b mt_break-mt_voice4(a4)
addq.b #1,mt_songpos-mt_voice4(a4)
and.b #$7f,mt_songpos-mt_voice4(a4)
move.b -2(a2),d0
cmp.b mt_songpos(pc),d0
bne.s mt_exit
move.b -1(a2),mt_songpos-mt_voice4(a4)
mt_exit:tst.b mt_break-mt_voice4(a4)
bne.s mt_next
rts

mt_nonew:
lea $dff0a0,a5
lea mt_com(pc),a6
jsr (a6)
lea mt_voice2(pc),a4
lea $dff0b0,a5
jsr (a6)
lea mt_voice3(pc),a4
lea $dff0c0,a5
jsr (a6)
lea mt_voice4(pc),a4
lea $dff0d0,a5
jsr (a6)
tst.b mt_break-mt_voice4(a4)
bne.s mt_next
rts

mt_irq1:tst.b $bfdd00
move.w mt_dmacon(pc),$dff096
move.l #mt_irq2,$78.w
move.w #$2000,$dff09c
rte

mt_irq2:tst.b $bfdd00
movem.l a3/a4,-(a7)
lea mt_voice1(pc),a4
lea $dff000,a3
move.l $a(a4),$a0(a3)
move.w $e(a4),$a4(a3)
move.l $a+$1c(a4),$b0(a3)
move.w $e+$1c(a4),$b4(a3)
move.l $a+$38(a4),$c0(a3)
move.w $e+$38(a4),$c4(a3)
move.l $a+$54(a4),$d0(a3)
move.w $e+$54(a4),$d4(a3)
movem.l (a7)+,a3/a4
move.b #0,$bfde00
move.b #$7f,$bfdd00
move.l mt_oldirq(pc),$78.w
move.w #$2000,$dff09c
move.w #$2000,$dff09a
rte

mt_playvoice:
move.l (a0,d1.l),(a4)
moveq #0,d2
move.b 2(a4),d2
lsr.b #4,d2
move.b (a4),d0
and.b #$f0,d0
or.b d0,d2
beq mt_oldinstr

asl.w #2,d2
move.l (a1,d2.l),4(a4)
move.l mt_mulu(pc,d2.w),a3
move.w (a3)+,8(a4)
move.w (a3)+,$12(a4)
move.l 4(a4),d0
moveq #0,d3
move.w (a3)+,d3
beq mt_noloop
asl.w #1,d3
add.l d3,d0
move.l d0,$a(a4)
move.w -2(a3),d0
add.w (a3),d0
move.w d0,8(a4)
bra mt_hejaSverige

mt_mulu:blk.l $120,0

mt_noloop:
add.l d3,d0
move.l d0,$a(a4)
mt_hejaSverige:
move.w (a3),$e(a4)
move.w $12(a4),8(a5)

mt_oldinstr:
move.w (a4),d3
and.w #$fff,d3
beq mt_com2
tst.w 8(a4)
beq.s mt_stopsound
move.b 2(a4),d0
and.b #$f,d0
cmp.b #5,d0
beq.s mt_setport
cmp.b #3,d0
beq.s mt_setport

move.w d3,$10(a4)
move.w $1a(a4),$dff096
clr.b $19(a4)

move.l 4(a4),(a5)
move.w 8(a4),4(a5)
move.w $10(a4),6(a5)

move.w $1a(a4),d0
or.w d0,mt_dmacon-mt_playvoice(a6)
bra mt_com2

mt_stopsound:
move.w $1a(a4),$dff096
bra mt_com2

mt_setport:
move.w (a4),d2
and.w #$fff,d2
move.w d2,$16(a4)
move.w $10(a4),d0
clr.b $14(a4)
cmp.w d0,d2
beq.s mt_clrport
bge mt_com2
move.b #1,$14(a4)
bra mt_com2
mt_clrport:
clr.w $16(a4)
rts

mt_port:moveq #0,d0
move.b 3(a4),d2
beq.s mt_port2
move.b d2,$15(a4)
move.b d0,3(a4)
mt_port2:
tst.w $16(a4)
beq.s mt_rts
move.b $15(a4),d0
tst.b $14(a4)
bne.s mt_sub
add.w d0,$10(a4)
move.w $16(a4),d0
cmp.w $10(a4),d0
bgt.s mt_portok
move.w $16(a4),$10(a4)
clr.w $16(a4)
mt_portok:
move.w $10(a4),6(a5)
mt_rts: rts

mt_sub: sub.w d0,$10(a4)
move.w $16(a4),d0
cmp.w $10(a4),d0
blt.s mt_portok
move.w $16(a4),$10(a4)
clr.w $16(a4)
move.w $10(a4),6(a5)
rts

mt_sin:
dc.b $00,$18,$31,$4a,$61,$78,$8d,$a1,$b4,$c5,$d4,$e0,$eb,$f4,$fa,$fd
dc.b $ff,$fd,$fa,$f4,$eb,$e0,$d4,$c5,$b4,$a1,$8d,$78,$61,$4a,$31,$18

mt_vib: move.b $3(a4),d0
beq.s mt_vib2
move.b d0,$18(a4)

mt_vib2:move.b $19(a4),d0
lsr.w #2,d0
and.w #$1f,d0
moveq #0,d2
move.b mt_sin(pc,d0.w),d2
move.b $18(a4),d0
and.w #$f,d0
mulu d0,d2
lsr.w #7,d2
move.w $10(a4),d0
tst.b $19(a4)
bmi.s mt_vibsub
add.w d2,d0
bra.s mt_vib3
mt_vibsub:
sub.w d2,d0
mt_vib3:move.w d0,6(a5)
move.b $18(a4),d0
lsr.w #2,d0
and.w #$3c,d0
add.b d0,$19(a4)
rts


mt_arplist:
dc.b 0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1,2,0,1

mt_arp: moveq #0,d0
move.b mt_counter(pc),d0
move.b mt_arplist(pc,d0.w),d0
beq.s mt_normper
cmp.b #2,d0
beq.s mt_arp2
mt_arp1:move.b 3(a4),d0
lsr.w #4,d0
bra.s mt_arpdo
mt_arp2:move.b 3(a4),d0
and.w #$f,d0
mt_arpdo:
asl.w #1,d0
move.w $10(a4),d1
lea mt_periods(pc),a0
mt_arp3:cmp.w (a0)+,d1
blt.s mt_arp3
move.w -2(a0,d0.w),6(a5)
rts

mt_normper:
move.w $10(a4),6(a5)
rts

mt_com: move.w 2(a4),d0
and.w #$fff,d0
beq.s mt_normper
move.b 2(a4),d0
and.b #$f,d0
beq.s mt_arp
cmp.b #6,d0
beq.s mt_volvib
cmp.b #4,d0
beq mt_vib
cmp.b #5,d0
beq.s mt_volport
cmp.b #3,d0
beq mt_port
cmp.b #1,d0
beq.s mt_portup
cmp.b #2,d0
beq.s mt_portdown
move.w $10(a4),6(a5)
cmp.b #$a,d0
beq.s mt_volslide
rts

mt_portup:
moveq #0,d0
move.b 3(a4),d0
sub.w d0,$10(a4)
move.w $10(a4),d0
cmp.w #$71,d0
bpl.s mt_portup2
move.w #$71,$10(a4)
mt_portup2:
move.w $10(a4),6(a5)
rts

mt_portdown:
moveq #0,d0
move.b 3(a4),d0
add.w d0,$10(a4)
move.w $10(a4),d0
cmp.w #$358,d0
bmi.s mt_portdown2
move.w #$358,$10(a4)
mt_portdown2:
move.w $10(a4),6(a5)
rts

mt_volvib:
bsr mt_vib2
bra.s mt_volslide
mt_volport:
bsr mt_port2

mt_volslide:
moveq #0,d0
move.b 3(a4),d0
lsr.b #4,d0
beq.s mt_vol3
add.b d0,$13(a4)
cmp.b #$40,$13(a4)
bmi.s mt_vol2
move.b #$40,$13(a4)
mt_vol2:move.w $12(a4),8(a5)
rts

mt_vol3:move.b 3(a4),d0
and.b #$f,d0
sub.b d0,$13(a4)
bpl.s mt_vol4
clr.b $13(a4)
mt_vol4:move.w $12(a4),8(a5)
rts

mt_com2:move.b 2(a4),d0
and.b #$f,d0
beq mt_rts
cmp.b #$e,d0
beq.s mt_filter
cmp.b #$d,d0
beq.s mt_pattbreak
cmp.b #$b,d0
beq.s mt_songjmp
cmp.b #$c,d0
beq.s mt_setvol
cmp.b #$f,d0
beq.s mt_setspeed
rts

mt_filter:
move.b 3(a4),d0
and.b #1,d0
asl.b #1,d0
and.b #$fd,$bfe001
or.b d0,$bfe001
rts

mt_pattbreak:
move.b #1,mt_break-mt_playvoice(a6)
rts

mt_songjmp:
move.b #1,mt_break-mt_playvoice(a6)
move.b 3(a4),d0
subq.b #1,d0
move.b d0,mt_songpos-mt_playvoice(a6)
rts

mt_setvol:
cmp.b #$40,3(a4)
bls.s mt_sv2
move.b #$40,3(a4)
mt_sv2: moveq #0,d0
move.b 3(a4),d0
move.b d0,$13(a4)
move.w d0,8(a5)
rts

mt_setspeed:
moveq #0,d0
move.b 3(a4),d0
cmp.b #$1f,d0
bls.s mt_sp2
moveq #$1f,d0
mt_sp2: tst.w d0
bne.s mt_sp3
moveq #1,d0
mt_sp3: move.b d0,mt_speed-mt_playvoice(a6)
rts

mt_periods:
dc.w $0358,$0328,$02fa,$02d0,$02a6,$0280,$025c,$023a,$021a,$01fc,$01e0
dc.w $01c5,$01ac,$0194,$017d,$0168,$0153,$0140,$012e,$011d,$010d,$00fe
dc.w $00f0,$00e2,$00d6,$00ca,$00be,$00b4,$00aa,$00a0,$0097,$008f,$0087
dc.w $007f,$0078,$0071,$0000

mt_speed: dc.b 6
mt_counter: dc.b 0
mt_pattpos: dc.w 0
mt_songpos: dc.b 0
mt_break: dc.b 0
mt_dmacon: dc.w 0
mt_samplestarts:blk.l $1f,0
mt_voice1: blk.w 13,0
dc.w 1
mt_voice2: blk.w 13,0
dc.w 2
mt_voice3: blk.w 13,0
dc.w 4
mt_voice4: blk.w 13,0
dc.w 8
mt_oldirq: dc.l 0
Ambient
Member
#3 - Posted: 29 May 2016 21:18 - Edited
Reply Quote
Photon got a tutorial on youtube how to get set playing a mod with the P61 playroutine, the player tutorial. :)
ZEROblue
Member
#4 - Posted: 30 May 2016 17:57 - Edited
Reply Quote
I would also recommend using The Player 6.1, and you can build it with vasm using the devpac compatibility mode, but if you want to get this replayer working then you need to preserve registers D2-D7/A2-A6 on all calls to the player, this is what the Amiga M68K ABI specifies and what VBCC expects from external functions.

You also have to fix mt_init, mt_music, mt_irq1, and mt_irq2 so they take the vector base into account when setting the level 6 interrupt vector.
sdw
Member
#5 - Posted: 31 May 2016 14:13 - Edited
Reply Quote
Ambient: Yes, i saw that there was a tutorial, but that was using AsmOne and an Amiga.native mod-to-p61 converter, I'd like to keep my toolchain on Windows for cross-development.

ZEROblue:
I think I have the register-preservation correct, all functions are declared with stuff like this:
__regsused("d0/d1/d2/d3/d4/d5/d6/d7/a0/a1/a2/a3/a4/a5/a6") void mod_play();
(The mod-play then does the jsr to mt_music)
Perhaps it is the vector base stuff that you touch upon that is the problem, that bit goes a bit above my head.

But for now I'll do one more attempt to get P61 player compiled and working from VBCC/VASM, as it seems to be the preferred solution.
noname
Member
#6 - Posted: 31 May 2016 21:12
Reply Quote
IIRC regsused is not enough for the compiler to satisfy the calling convention. I just always saved registers d2-d7 and a2-a6 in an ASM function that gets called from C and restored them before rts. That always worked.
sdw
Member
#7 - Posted: 1 Jun 2016 00:21
Reply Quote
noname: thanks for the tip, I did an attempt at that, but it made no difference. Also, I call a lot of my own asm-functions that uses all kind of registers from C, and everything works just fine, it's just that damn tracker-replayer that messes it up.

Well, other than that I have spent many, many hours now trying to get P61play to work. And I have made at least "some" progress.
If I just take the entire sample code from P61Play and put that into a single C function that I call, it works.
So my main program looks like this:


void main()
{
PlayP61Module();
}


And then the entire assembler source from the P61 replayer example source is in an assembler subroutine that gets called, so it sets up the system, plays music, waits for mouseclick and the brings everything down again, and returns.

However, what I rally want to do is this:

void main()
{
setup();
part1();
part2();
...
bringdown()
}


Where setup initializes everything in the system, and bringdown restores the system, and between that I can run my demo code.
This works absolutely fine if I just do my own stuff, but as soon as I add the P61player stuff in the setup (I'm using the CIA-timer method), it doesn't work.
I've tried two methods:
1) Keep the working setup/bringdown code I already have, copy relevant parts to start playing P61 into startup.
2) Try to split the P61 example source code in two and use that as setup/bringdown.

Neither 1 nor 2 works, at all...
If I use method 1, the music doesn't play.
If I use method 2, the music plays but I can't get any graphics on screen, and the system isn't restored properly.

I think the problem is that I have absolutely no clue what is needed in the startup and bringdown parts, and which IRQ this and DMA that and what strange calls to -(somenumber)a6 is the right ones.
Yeah, I guess I really should learn all that, but I am much more interested in actually coding demos, not doing framework/system OS stuff.
I'll give it a few more days of trying, and if I don't have any luck I guess I'll head back to the 8-bit machines, where things generally seem a bit simpler! :)

sdw
Member
#8 - Posted: 2 Jun 2016 23:06
Reply Quote
Alright, some progress!
By modifying the code from P61 example to not use any stack related stuff at all, and remove some stuff from my main code that apparently was touching the IRQ/DMA setup my "split P61 example it into two"-method seems to *almost* work now. Music plays, graphics is shown, and most of the time you can quit to system OK. Sometimes it still seems to hang on exit though.
I wonder if people will be upset if my little demo/intro hangs their Amiga on exit occasionally..? ;)
sdw
Member
#9 - Posted: 3 Jun 2016 00:02
Reply Quote
Well, I take that back, it turns out that the code is completely and utterly fucked, adding and removing lines of code from the end of the program can affect whether the player works or not, eventhough the code is not even running. So it seems like whether things works or not at the moment depends on exactly where certain code happens to end up.
Something (either P61 player, or the code generated by VBCC) seems to be writing somewhere it shouldn't.
I give up.

ZEROblue
Member
#10 - Posted: 3 Jun 2016 12:05
Reply Quote
Does this example work?

http://pastebin.com/f676pKVT
sdw
Member
#11 - Posted: 3 Jun 2016 16:49
Reply Quote
Thanks for the support ZEROblue! I couldn't get that to build (it was refering some P61Player.i that I didn't have, and when I removed that I had soem undefined varables).

HOWEVER!!! I *think* I actually have something that works now. By combining some of my "old" setup/bringdown code with the IRQ-setup stuff from the P61player example, it seems to work! Yay!
sdw
Member
#12 - Posted: 3 Jul 2016 12:17
Reply Quote
Here's the end result:

http://www.pouet.net/prod.php?which=67673

Unfortunately some notes didn't sound *quite* right in P61, but we suspect it's because Mr.Death did the tune in a "Protracker-compatible" mode in a PC-tracker and that in fact did not end up being 100% compatible.
Angry Retired Bastard
Member
#13 - Posted: 5 Jul 2016 18:09
Reply Quote
I think it turned out nicely and the different bob patterns provided enough variation to keep it interesting while reading the text. :)
The music *did* sound a bit off, as you mentioned. I'd recommend testing the unpacked mod in protracker during development and then investigate further whenever P61 sounds different.
Jazzcat
Member
#14 - Posted: 5 Jul 2016 22:03
Reply Quote
Confirming. Music sounded out of tune at times (especially at 0:08).
wasp
Member
#15 - Posted: 5 Jul 2016 22:49 - Edited
Reply Quote
Without having seen the actual mod, it sounds like the 3-command isn't set properly. A higher value would probably fix it. I tried to gather more information in Mr. Death's compomod from Gubbdata, but the error isn't there, or at least not as obvious. A classic 0 command error is there however, when exceeding B-3 with the 00C command, but I digress. The tune(s) are great as well as the intro. Well done!

 

  Please log in to comment

  

  

  

 

A.D.A. Amiga Demoscene Archive, Version 3.0