;
;
; Offset  Bytes  Description
;  950      1    Songlength. Range is 1-128.
;  951      1    Well... this little byte here is set to 127, so that old
; 	       trackers will search through all patterns when loading.
; 	       Noisetracker uses this byte for restart, but we don't.
;  952    128    Song positions 0-127. Each hold a number from 0-63 that
; 	       tells the tracker what pattern to play at that position.
; 1080      4    The four letters "M.K." - This is something Mahoney & Kaktus
; 	       inserted when they increased the number of samples from
; 	       15 to 31. If it's not there, the module/song uses 15 samples
; 	       or the text has been removed to make the module harder to
; 	       rip. Startrekker puts "FLT4" or "FLT8" there instead.
; 
; Offset  Bytes  Description
; 1084    1024   Data for pattern 00.
;    .
;    .
;    .
; xxxx  Number of patterns stored is equal to the highest patternnumber
;       in the song position table (at offset 952-1079).
; 
; Each note is stored as 4 bytes, and all four notes at each position in
; the pattern are stored after each other.
; 
; 00 -  chan1  chan2  chan3  chan4
; 01 -  chan1  chan2  chan3  chan4
; 02 -  chan1  chan2  chan3  chan4
; etc.
; 
; Info for each note:
; 
;  _____byte 1_____   byte2_    _____byte 3_____   byte4_
; /                 /        /                 /
; 0000          0000-00000000  0000          0000-00000000
; 
; Upper four    12 bits for    Lower four    Effect command.
; bits of sam-  note period.   bits of sam-
; ple number.                  ple number.

;******************************
;*
;* patternGetSongLength
;*
;* r5 = mod adr low
;* r6 = mod adr high
;*
;* return
;*
;* r0 = value
;*

patternGetSongLength

	push	r5
	push	r6
	
	addi	r5,225
	addtqi	r6,r6,0
	addi	r5,250
	addtqi	r6,r6,0		;pattern main struct is 475 words 
	nop
	esadr	r6,r5
	erqldi	0
	eld	r0		;get value
	
	rqpop
	rqpop
	jmpi	r7,0
	pop	r6		;delay slot
	pop	r5		;delay slot
	lsri	r0,8		;length 	delay slot
	nop			;delay slot
	
;******************************
;*
;* patternGetCount (calculate pattern count, note: its could be slow!)
;*
;* r5 = mod adr low
;* r6 = mod adr high
;*
;* return
;*
;* r0 = value
;*

patternGetCount

	push	r2
	push	r3
	push	r4
	push	r5
	push	r6
	
	;get song length first
	
	dexti	1	
	addi	r5,$db		;0x1db = 475 (950 bytes)
	addtqi	r6,r6,0
	nop
	esadr	r6,r5
	erqldi	0
	addi	r5,1		;goto songposition 476 (952 bytes)
	addtqi	r6,r6,0
	eld	r4		;get song length
	
	;now loop over all songs
	
	esadr	r6,r5
	lsri	r4,8		;song length to byte
	movei	r3,0		;counter
	movei	r0,0		;maxPattern
	
patternGetCountLoop
	
	erqldb	r3		;get pattern number at song position (r3)
	extri	r3,0		;is even address?	
	eld	r2		;get value	
	nop
	swptc	r2,r2		;swap bytes (even/odd)
	addi	r3,1		
	moveih	r2,0		;clear upper
	cmpeq	r3,r4		
	brtc	patternGetCountLoop
	cmplo	r0,r2		;delay slot				maxPattern < current pattern
	movets	r0,r2,r0	;delay slot		maxPattern =					? current pattern : maxPattern
	nop			;delay slot	
	nop			;delay slot	

	;
	

	rqpop
	rqpop
	rqpop
	pop	r6
	pop	r5
	pop	r4
	
	rqpop
	rqpop
	jmpi	r7,0
	pop	r3		;delay slot	
	pop	r2		;delay slot	
	addi	r0,1		;max pattern +1		because pattern 2 -> 3 count delay slot	
	nop			;delay slot	
	
;******************************
;*
;* patternGetPatternNumberAtSongPosition (very good, i hate long names ... but this happen at software design ...)
;*
;* r4 = song position
;* r5 = mod adr low
;* r6 = mod adr high
;*
;* return
;*
;* r0 = value
;*

patternGetPatternNumberAtSongPosition

	push	r5
	push	r6
		
	addi	r5,225
	addtqi	r6,r6,0
	addi	r5,251
	addtqi	r6,r6,0		;pattern main struct is 425 words, psotions start at 952
	nop
	esadr	r6,r5
	erqldb	r4		;byte based indexd request
	extri	r4,0		;is even address?	
	eld	r0		;get value	
	nop
	swptc	r0,r0		;swap bytes (even/odd)
		
	rqpop
	rqpop
	jmpi	r7,0
	pop	r6		;delay slot
	pop	r5		;delay slot
	moveih	r0,0		;clear upper 	delay slot
	nop			;delay slot
		
;******************************
;*
;* patternGetCellValue
;*
;* r2 = pattern (0..127)	
;* r3 = row (0..63)
;* r4 = channel num (0..3)	
;* r5 = mod adr low
;* r6 = mod adr high
;*
;* return
;*
;* r2 = sample num
;* r3 = periode
;* r4 = effect
;*

patternGetCellValue

	push	r5
	push	r6
	push	r0
		
	;pattern data start 524 + (512 * r2 [pattern num]) + (8 * r3 [row num]) + (2 * r4 [channel num])

	moveih	r2,0	;0000 0000 XPPP PPPP
	movei	r0,$1e	
	swp	r2,r2		;XPPP PPPP 0000 0000
	moveih	r0,$2		;offset 542
	muli	r3,8		;row * 8
	add	r4,r4,r4	;channel num * 2
	
	add	r0,r0,r3	;offset + row *8 
	add	r2,r2,r2	;PPPP PPP0 0000 0000
	add	r0,r0,r4	;(offset + row * 8) + channel num * 2
	
	add	r5,r5,r2	;+ pattern num * 512
	addtqi	r6,r6,0
	add	r5,r5,r0	;(offset + row * 8) + channel num * 2
	addtqi	r6,r6,0	
		
	movei	r2,$ff
	esadr	r6,r5
	
	erqldi	0		;low
	erqldi	1		;high
	moveih	r2,$0f
	eld	r5		;
	eld	r6
	
	;r0 = SSSS PPPP PPPP PPPP : r1 = SSSS EEEE EEEE EEEE
	
	and	r3,r5,r2	;r3 = 0000 PPPP PPPP PPPP
	and	r4,r6,r2	;r4 = 0000 EEEE EEEE EEEE
	bic	r5,r5,r2	;r5 = SSSS 0000 0000 0000 (high)
	bic	r6,r6,r2	;r6 = SSSS 0000 0000 0000 (low)
	lsri	r5,8
	lsri	r6,12
	rqpop
	or	r2,r5,r6	;r2 = 0000 0000 SSSS SSSS
	nop
	pop	r0
	
	rqpop
	rqpop
	jmpi	r7,0
	pop	r6	;delay slot
	pop	r5	;delay slot
	nop		;delay slot
	nop		;delay slot
	
