home *** CD-ROM | disk | FTP | other *** search
- ; (Octa)MED module load routines, by Teijo Kinnunen
- ; MED V3.00 module support added 22-Jan-1991
- ; upgraded for V3.20 (OctaMED V2.00) 02-Aug-1991
- ; and for OctaMED Pro V3.00 02-Apr-1992
- ; (bug fix) 31-May-1992
- ; OctaMED Pro V5 support (MMD2) 18-May-1993
- ; OctaMED Pro V6 support (cmd pages) 16-Jan-1995
- ; 2 bug fixes (Thanks to Peter Kunath.) 14-Feb-1995
- ; V7 support 20-Sep-1995
- ; FastMem loading 26-Nov-1995
- ; MMD3 recognition 04-Dec-1995
- ; RequiredPlayRoutine 09-Jan-1996
- ; Didn't reloc MMD3s correctly... 17-Jan-1996
- ; FastMemPlayRecommended 29-Jan-1996
- ; Fixed MMD0 multi-module reloc error 25-Apr-1996
-
- ; $VER: loadmod_a 7.0 (25.4.1996)
-
- ; Function: d0 = _LoadModule(a0)
- ; a0 = module name
- ; d0 = pointer to loaded module, zero if load failed
-
- XDEF _LoadModule,_LoadModule_Fast
- XDEF _UnLoadModule
- XDEF _RelocModule
- XDEF _RequiredPlayRoutine
- XDEF _FastMemPlayRecommended
-
- mmd_songinfo EQU 8
- mmd_blockarr EQU 16
- mmd_expdata EQU 32
- mmd_songsleft EQU 51
- msng_numblocks EQU 504
- msng_pseqs EQU 508
- msng_flags EQU 767
- msng_flags2 EQU 768
- msng_numsamples EQU 787
-
- CODE
-
- _LoadModule move.l d7,-(sp)
- moveq #0,d7
- bsr.s LoadMod
- move.l (sp)+,d7
- rts
-
- _LoadModule_Fast
- move.l d7,-(sp)
- moveq #1,d7
- bsr.s LoadMod
- move.l (sp)+,d7
- rts
-
- ;if D7 = 1, load to Fast Mem always
- LoadMod: movem.l a2-a4/a6/d2-d6,-(sp)
- suba.l a2,a2
- moveq #0,d6 ;d6 = return value (zero = error)
- move.l a0,a4 ;a4 = module name
- movea.l 4.w,a6
- lea dosname(pc),a1
- moveq #0,d0
- jsr -$228(a6) ;OpenLibrary()
- tst.l d0
- beq xlm1
- move.l d0,a3 ;a3 = DOSBase
- move.l d0,a6
- move.l a4,d1 ;name = d1
- move.l #1005,d2 ;accessmode = MODE_OLDFILE
- jsr -$1e(a6) ;Open()
- move.l d0,d4 ;d4 = file handle
- beq xlm2
- move.l d4,d1
- moveq #0,d2
- moveq #1,d3 ;OFFSET_END
- jsr -$42(a6) ;Seek(fh,0,OFFSET_END)
- tst.l d0
- bmi.w xlm3 ;-1 = error
- move.l d4,d1
- moveq #-1,d3 ;OFFSET_BEGINNING
- jsr -$42(a6) ;Seek(fh,0,OFFSET_BEGINNING)
- move.l d0,d5 ;d5 = file size
- bmi.w xlm3
- moveq #1,d1 ;alloc mem for beginning
- moveq #6*4,d0
- movea.l 4.w,a6
- jsr -$c6(a6) ;AllocMem
- tst.l d0
- beq.w xlm3
- move.l d0,a2
- move.l d4,d1
- move.l a2,d2
- moveq #6*4,d3 ;read beginning of the mod..
- move.l a3,a6
- jsr -$2a(a6) ;Read...
- cmp.l d3,d0
- bne.w xlm3 ;error
- cmp.l #'MMD3',(a2) ;Soundstudio module using mixing?
- beq.s id_ok
- cmp.l #'MMD2',(a2) ;Pro V5 module?
- beq.s id_ok
- cmp.l #'MMD1',(a2) ;Pro module?
- beq.s id_ok
- cmp.l #'MMD0',(a2)
- bne.s xlm3 ;this is not a module!!!
- id_ok btst #0,20(a2) ;test mmdflags of the module
- beq.s 1$
- moveq #1,d7 ;Fast Mem
- 1$ movea.l 4.w,a6 ;free the 24-byte buffer
- moveq #6*4,d0
- move.l a2,a1
- jsr -$d2(a6) ;FreeMem()
- suba.l a2,a2
- move.l d4,d1
- moveq #0,d2
- moveq #-1,d3 ;OFFSET_BEGINNING
- move.l a3,a6
- jsr -$42(a6) ;Seek(fh,0,OFFSET_BEGINNING)
- tst.l d0
- bmi.s xlm3 ;seek error
- movea.l 4.w,a6
- move.l d5,d0
- moveq #1,d1 ;mem type: PUBLIC
- tst.b d7 ;force Fast Mem
- bne.s 2$
- moveq #3,d1 ;mem type: PUBLIC|CHIP
- 2$ jsr -$c6(a6) ;AllocMem()
- tst.l d0
- beq.s xlm3
- move.l d0,a4 ;a4 = pointer to module
- move.l d4,d1 ;file
- move.l d0,d2 ;buffer
- move.l d5,d3 ;length
- move.l a3,a6
- jsr -$2a(a6) ;Read()
- cmp.l d5,d0
- bne.s xlm4 ;something wrong...
- movea.l a4,a0
- bsr.w _RelocModule
- move.l a4,d6 ;no error...
- bra.s xlm3
- xlm4 move.l a2,a1 ;error: free the memory
- move.l d5,d0
- movea.l 4.w,a6
- jsr -$d2(a6) ;FreeMem()
- xlm3 move.l a2,d0 ;24-byte buffer exists?
- beq.s 1$
- movea.l 4.w,a6
- moveq #6*4,d0
- move.l a2,a1
- jsr -$d2(a6) ;FreeMem()
- 1$ move.l a3,a6 ;close the file
- move.l d4,d1
- jsr -$24(a6) ;Close(fhandle)
- xlm2 move.l a3,a1 ;close dos.library
- movea.l 4,a6
- jsr -$19e(a6)
- xlm1 move.l d6,d0 ;push return value
- movem.l (sp)+,a2-a4/a6/d2-d6 ;restore registers
- rts ;and exit...
- dosname dc.b 'dos.library',0
-
- ; Function: _RelocModule(a0)
- ; a0 = pointer to module
-
- ; This function is a bit strangely arranged around the small reloc-routine.
- reloci move.l 24(a2),d0
- beq.s xloci
- movea.l d0,a0
- moveq #0,d0
- move.b msng_numsamples(a1),d0 ;number of samples
- subq.b #1,d0
- relocs bsr.s relocentr
- move.l -4(a0),d3 ;sample ptr
- beq.s nosyn
- move.l d3,a3
- tst.w 4(a3)
- bpl.s nosyn ;type >= 0
- move.w 20(a3),d2 ;number of waveforms
- lea 278(a3),a3 ;ptr to wf ptrs
- subq.w #1,d2
- relsyn add.l d3,(a3)+
- dbf d2,relsyn
- nosyn dbf d0,relocs
- xloci rts
- norel addq.l #4,a0
- rts
- relocentr tst.l (a0)
- beq.s norel
- add.l d1,(a0)+
- rts
- _RelocModule:
- movem.l a2-a4/d2-d4,-(sp)
- movea.l a0,a2
- move.l a2,d1 ;d1 = ptr to start of module
- bsr.s relocp
- movea.l mmd_songinfo(a2),a1
- bsr.s reloci
- move.b mmd_songsleft(a2),d4
- rel_lp bsr.s relocb
- cmp.b #'T',3(a2)
- beq.s norelmmd2
- cmp.b #'2',3(a2) ;MMD2?
- bcs.s norelmmd2
- bsr.w relocmmd2sng
- norelmmd2 move.l mmd_expdata(a2),d0 ;extension struct
- beq.s rel_ex
- move.l d0,a0
- bsr.s relocentr ;ptr to next module
- bsr.s relocentr ;InstrExt...
- addq.l #4,a0 ;skip sizes of InstrExt
- ; We reloc the pointers of MMD0exp, so anybody who needs them can easily
- ; read them.
- bsr.s relocentr ;annotxt
- addq.l #4,a0 ;annolen
- bsr.s relocentr ;InstrInfo
- addq.l #8,a0
- bsr.s relocentr ;rgbtable (not useful for most people)
- addq.l #4,a0 ;skip channelsplit
- bsr.s relocentr ;NotationInfo
- bsr.s relocentr ;songname
- addq.l #4,a0 ;skip song name length
- bsr.s relocentr ;MIDI dumps
- bsr.s relocmdd
- bsr.s relocentr ;mmdinfo
- bsr.s relocentr ;mmdrexx
- bsr.w relocrx
- bsr.s relocentr ;mmdcmd3x
- bsr.w reloccmd3x
- subq.b #1,d4 ;songs left..?
- bcs.s rel_ex
- move.l d0,a0
- move.l (a0),d0
- beq.s rel_ex
- move.l d0,a2
- bsr.s relocp
- movea.l 8(a2),a1
- bra.s rel_lp
- rel_ex movem.l (sp)+,d2-d4/a2-a4
- rts
-
- relocp lea mmd_songinfo(a2),a0
- bsr.w relocentr
- addq.l #4,a0
- bsr.w relocentr
- addq.l #4,a0
- bsr.w relocentr
- addq.l #4,a0
- bra.w relocentr
-
- relocb move.l mmd_blockarr(a2),d0
- beq.s xlocb
- movea.l d0,a0
- move.w msng_numblocks(a1),d0
- subq.b #1,d0
- rebl bsr relocentr
- dbf d0,rebl
- cmp.b #'T',3(a2) ;MMD0 (= MCNT)
- beq.s xlocb
- cmp.b #'1',3(a2) ;test MMD type
- bge.w relocbi
- xlocb rts
-
- relocmdd movem.l d0/a0,-(sp)
- tst.l -(a0)
- beq.s xlocmdd
- movea.l (a0),a0
- move.w (a0),d0 ;# of msg dumps
- addq.l #8,a0
- 1$ beq.s xlocmdd
- bsr relocentr
- bsr.s relocdmp
- subq.w #1,d0
- bra.s 1$
- xlocmdd movem.l (sp)+,d0/a0
- rts
-
- relocrxtrig movem.l d0/a0,-(sp)
- subq.l #4,a0
- 2$ move.l (a0),d0
- beq.s 1$
- move.l d0,a0
- addq.l #8,a0
- bsr relocentr ;command name
- bsr relocentr ;port name
- move.l d0,a0
- bra.s 2$
- 1$ movem.l (sp)+,d0/a0
- rts
-
- relocrx movem.l d0/a0,-(sp)
- move.l -(a0),d0
- beq.s 1$
- move.l d0,a0
- addq.l #4,a0 ;skip res, trigcmdlen
- bsr relocentr
- bsr.s relocrxtrig
- 1$ movem.l (sp)+,d0/a0
- rts
-
- reloccmd3x movem.l d0/a0,-(sp)
- move.l -(a0),d0
- beq.s 1$
- move.l d0,a0
- addq.l #4,a0 ;skip struct_vers, pad, num_of_settings
- bsr relocentr ;ctrlr_types
- bsr relocentr ;ctrlr_numbers
- 1$ movem.l (sp)+,d0/a0
- rts
-
- relocdmp move.l -4(a0),d3
- beq.s xlocdmp
- exg.l a0,d3 ;save
- addq.l #4,a0
- bsr relocentr ;reloc data pointer
- move.l d3,a0 ;restore
- xlocdmp rts
-
- relocbi move.w msng_numblocks(a1),d0
- move.l a0,a3
- biloop subq.w #1,d0
- bmi.s xlocdmp
- move.l -(a3),a0
- addq.l #4,a0
- bsr relocentr ;BlockInfo ptr
- tst.l -(a0)
- beq.s biloop
- move.l (a0),a0
- bsr relocentr ;hldata
- bsr relocentr ;block name
- addq.l #4,a0 ;skip blocknamelen
- bsr relocentr ;pagetable
- tst.l -(a0)
- bne.s relocpgtbl
- bra.s biloop
- ; take care of the new features of MMD2s
- relocmmd2sng move.l mmd_songinfo(a2),a0
- lea msng_pseqs(a0),a0
- bsr relocentr ;playseqtable
- bsr relocentr ;sectiontable
- bsr relocentr ;trackvols
- addq.l #4,a0
- bsr relocentr ;trackpans
- move.w -6(a0),d0 ;numpseqs
- move.l -20(a0),a0 ;get back to playseqtable
- subq.w #1,d0
- psqtblloop bsr relocentr
- dbf d0,psqtblloop
- rts
- relocpgtbl movea.l (a0),a4 ;page table list hdr
- move.w (a4),d2
- subq.w #1,d2
- lea 4(a4),a0
- pgtblloop bsr relocentr
- dbf d2,pgtblloop
- bra biloop
-
-
- ; Function: _UnLoadModule(a0)
- ; a0 = pointer to module
- _UnLoadModule:
- move.l a6,-(sp)
- move.l a0,d0
- beq.s xunl
- movea.l 4,a6
- move.l 4(a0),d0
- beq.s xunl
- movea.l a0,a1
- jsr -$d2(a6) ;FreeMem()
- xunl move.l (sp)+,a6
- rts
-
- ; Function: _RequiredPlayRoutine(a0)
- ; a0 = pointer to module
- ; Returns:
- ; 0 = 4 channel routine (or no module)
- ; 1 = 5-8 channel routine
- ; 2 = mixing routine
-
- _RequiredPlayRoutine:
- move.l a0,d0
- beq.s 3$
- move.l 8(a0),a0 ;song struct
- tst.b msng_flags2(a0) ;mixing?
- bmi.s 2$
- btst #6,msng_flags(a0) ;5-8 channel?
- bne.s 1$
- 3$ moveq #0,d0
- rts
- 1$ moveq #1,d0
- rts
- 2$ moveq #2,d0
- rts
-
- ; Function: _FastMemPlayRecommended(a0)
- ; a0 = pointer to module
- ; Returns:
- ; 0 = plays perfectly without FastMemPlay
- ; 1 = may not play perfectly without FastMemPlay
-
- _FastMemPlayRecommended:
- movem.l d2/a2,-(sp)
- move.l a0,d1
- beq.s fmpr_ret0
- movea.l mmd_songinfo(a0),a1
- moveq #0,d1
- move.b msng_numsamples(a1),d1
- move.l 24(a0),d0 ;sample array
- beq.s fmpr_nosamples
- movea.l d0,a1
- move.l d1,d0
- subq.l #1,d0
- 1$ move.l (a1)+,d2
- beq.s 2$
- movea.l d2,a2 ;instrument address
- move.l (a2),d2 ;length
- swap d2 ;upper word...
- lsr.w #1,d2
- bne.s fmpr_ret1 ;length >= 131072
- 2$ dbra d0,1$
- fmpr_nosamples move.l mmd_expdata(a0),d0
- beq.s fmpr_ret0
- movea.l d0,a1
- move.l 4(a1),d0 ;exp_smp
- beq.s fmpr_ret0
- move.w 8(a1),d1
- beq.s fmpr_ret0
- move.w 10(a1),d2
- cmp.w #18,d2
- blt.s fmpr_ret0 ;no long repeat
- movea.l d0,a1
- subq.w #1,d1
- 1$ move.l 10(a1),d0
- or.l 14(a1),d0
- lsr.l #1,d0
- bcs.s fmpr_ret1 ;odd... return 1
- swap d0
- tst.w d0
- bne.s fmpr_ret1 ;start/len >= 131072
- adda.w d2,a1
- dbra d1,1$
- fmpr_ret0 moveq #0,d0
- fmpr_ret movem.l (sp)+,d2/a2
- rts
- fmpr_ret1 moveq #1,d0
- bra.s fmpr_ret
-
- END
-