371 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			OpenEdge ABL
		
	
	
	
	
	
			
		
		
	
	
			371 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			OpenEdge ABL
		
	
	
	
	
	
midiId              EQU     register0
 | 
						|
audioAddr           EQU     register1
 | 
						|
waveType            EQU     register2
 | 
						|
midiNote            EQU     register4                       ; register4 to register7 are the only free registers during time slicing
 | 
						|
midiCommand         EQU     register5
 | 
						|
midiPtr             EQU     register6
 | 
						|
sndChannel          EQU     register8
 | 
						|
sndFrequency        EQU     register9
 | 
						|
sndVolume           EQU     register10
 | 
						|
sndWaveType         EQU     register11
 | 
						|
musicStream         EQU     register8
 | 
						|
musicNote           EQU     register9
 | 
						|
musicCommand        EQU     register10
 | 
						|
musicPtr            EQU     register11
 | 
						|
 | 
						|
 | 
						|
%SUB                setMidiStream
 | 
						|
setMidiStream       LDWI    _midisLut_
 | 
						|
                    ADDW    midiId
 | 
						|
                    ADDW    midiId
 | 
						|
                    DEEK
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                resetMidi
 | 
						|
                    ; adds 10*16.66667ms delay between giga_frameCount and midiDelay so that if there ; is substantial processing between resetMidi and playMidi giga_frameCount will
 | 
						|
                    ; not overflow past midiDelay and cause an extra initial 256*16.66667ms delay
 | 
						|
resetMidi           LDI     0      
 | 
						|
                    ST      giga_frameCount
 | 
						|
                    ADDI    10
 | 
						|
                    STW     midiDelay                       ; instant MIDI startup
 | 
						|
                    LDI     giga_soundChan1 >>8
 | 
						|
                    ST      audioAddr + 1
 | 
						|
                    LDI     0
 | 
						|
                    ST      waveType                        ; wavA, (wavX is initialised by Macros)
 | 
						|
 | 
						|
resetMi_loop        LDI     giga_soundChan1
 | 
						|
                    ST      audioAddr                       ; reset low byte
 | 
						|
                    LDW     waveType
 | 
						|
                    DOKE    audioAddr                       ; wavA and wavX
 | 
						|
                    INC     audioAddr
 | 
						|
                    INC     audioAddr    
 | 
						|
                    LDI     0
 | 
						|
                    DOKE    audioAddr                       ; keyL and keyH
 | 
						|
                    INC     audioAddr + 1                   ; increment high byte
 | 
						|
                    LD      audioAddr + 1
 | 
						|
                    SUBI    4
 | 
						|
                    BLE     resetMi_loop
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                playMidi
 | 
						|
playMidi            LDW     midiStream
 | 
						|
                    BEQ     playM_exit0                     ; 0x0000 = stop
 | 
						|
                    LDI     5                               ; keep pumping soundTimer
 | 
						|
                    ST      giga_soundTimer
 | 
						|
                    LD      giga_frameCount
 | 
						|
                    SUBW    midiDelay
 | 
						|
                    BEQ     playM_start
 | 
						|
playM_exit0         RET
 | 
						|
 | 
						|
playM_start         PUSH
 | 
						|
playM_process       LDW     midiStream
 | 
						|
                    PEEK                                    ; get midi stream byte
 | 
						|
                    STW     midiCommand
 | 
						|
                    LDW     midiStream
 | 
						|
                    ADDI    0x01
 | 
						|
                    STW     midiStream
 | 
						|
                    LDW     midiCommand
 | 
						|
                    ANDI    0xF0                    
 | 
						|
                    XORI    0x90                            ; check for start note
 | 
						|
                    BNE     playM_endnote
 | 
						|
    
 | 
						|
                    LDWI    midiStartNote
 | 
						|
                    CALL    giga_vAC            			; start note
 | 
						|
                    BRA     playM_process
 | 
						|
                    
 | 
						|
playM_endnote       XORI    0x10                            ; check for end note
 | 
						|
                    BNE     playM_segment
 | 
						|
    
 | 
						|
                    LDWI    midiEndNote         			; end note
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    BRA     playM_process
 | 
						|
 | 
						|
playM_segment       XORI    0x50                            ; check for new segment
 | 
						|
                    BNE     playM_delay
 | 
						|
    
 | 
						|
                    LDW     midiStream                      ; midi score
 | 
						|
                    DEEK
 | 
						|
                    STW     midiStream                      ; 0xD0 new midi segment address
 | 
						|
                    BEQ     playM_exit1                     ; 0x0000 = stop
 | 
						|
                    BRA     playM_process
 | 
						|
    
 | 
						|
playM_delay         LD      giga_frameCount                 ; midiDelay = (midiCommand + peek(frameCount)) & 0x00FF 
 | 
						|
                    ADDW    midiCommand
 | 
						|
                    ST      midiDelay
 | 
						|
playM_exit1         POP
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                playMidiVol
 | 
						|
playMidiVol         LDW     midiStream
 | 
						|
                    BEQ     playMV_exit0                    ; 0x0000 = stop
 | 
						|
                    LDI     5                               ; keep pumping soundTimer
 | 
						|
                    ST      giga_soundTimer
 | 
						|
                    LD      giga_frameCount
 | 
						|
                    SUBW    midiDelay
 | 
						|
                    BEQ     playMV_start
 | 
						|
playMV_exit0        RET
 | 
						|
 | 
						|
playMV_start        PUSH
 | 
						|
playMV_process      LDW     midiStream
 | 
						|
                    PEEK                                    ; get midi stream byte
 | 
						|
                    STW     midiCommand
 | 
						|
                    LDW     midiStream
 | 
						|
                    ADDI    0x01
 | 
						|
                    STW     midiStream
 | 
						|
                    LDW     midiCommand
 | 
						|
                    ANDI    0xF0
 | 
						|
                    XORI    0x90                            ; check for start note
 | 
						|
                    BNE     playMV_endnote
 | 
						|
    
 | 
						|
                    LDWI    midiStartNote
 | 
						|
                    CALL    giga_vAC                        ; start note
 | 
						|
                    LDWI    midiSetVolume
 | 
						|
                    CALL    giga_vAC                        ; set note volume
 | 
						|
                    BRA     playMV_process
 | 
						|
                    
 | 
						|
playMV_endnote      XORI    0x10                            ; check for end note
 | 
						|
                    BNE     playMV_segment
 | 
						|
    
 | 
						|
                    LDWI    midiEndNote                     ; end note
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    BRA     playMV_process
 | 
						|
 | 
						|
playMV_segment      XORI    0x50                            ; check for new segment
 | 
						|
                    BNE     playMV_delay
 | 
						|
    
 | 
						|
                    LDW     midiStream                      ; midi score
 | 
						|
                    DEEK
 | 
						|
                    STW     midiStream                      ; 0xD0 new midi segment address
 | 
						|
                    BEQ     playMV_exit1                    ; 0x0000 = stop
 | 
						|
                    BRA     playMV_process
 | 
						|
    
 | 
						|
playMV_delay        LD      giga_frameCount                 ; midiDelay = (midiCommand + peek(frameCount)) & 0x00FF 
 | 
						|
                    ADDW    midiCommand
 | 
						|
                    ST      midiDelay
 | 
						|
playMV_exit1        POP
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                midiStartNote
 | 
						|
midiStartNote       LDWI    giga_notesTable - 22            ; giga_notesTable + (midi - 11)*2
 | 
						|
                    STW     midiPtr
 | 
						|
                    LDW     midiStream                      ; midi note
 | 
						|
                    PEEK
 | 
						|
                    LSLW
 | 
						|
                    ADDW    midiPtr
 | 
						|
                    STW     midiPtr
 | 
						|
                    LUP     0x00                            ; get ROM midi note low byte
 | 
						|
                    ST      midiNote
 | 
						|
                    LDW     midiPtr
 | 
						|
                    LUP     0x01                            ; get ROM midi note high byte
 | 
						|
                    ST      midiNote + 1
 | 
						|
                    LDW     midiCommand
 | 
						|
                    ANDI    0x03                            ; get channel
 | 
						|
                    ADDI    0x01
 | 
						|
                    ST      midiPtr + 1
 | 
						|
                    LDI     0xFC
 | 
						|
                    ST      midiPtr                         ; note address 0x01FC <-> 0x04FC
 | 
						|
                    LDW     midiNote
 | 
						|
                    DOKE    midiPtr                         ; set note
 | 
						|
                    
 | 
						|
midiSN_exit         LDW     midiStream
 | 
						|
                    ADDI    0x01                            ; midiStream++
 | 
						|
                    STW     midiStream
 | 
						|
                    RET
 | 
						|
 | 
						|
midiSetVolume       LDI     0xFA
 | 
						|
                    ST      midiPtr                         ; wavA address 0x01FA <-> 0x04FA, (midiPtr is still valid from midiStartNote)
 | 
						|
                    LDW     midiStream                      ; midi volume
 | 
						|
                    PEEK
 | 
						|
                    POKE    midiPtr
 | 
						|
                    BRA     midiSN_exit                     ; save a few bytes by using midiStartNote's epilogue
 | 
						|
                    
 | 
						|
midiEndNote         LDW     midiCommand
 | 
						|
                    ANDI    0x03                            ; get channel
 | 
						|
                    ADDI    0x01                
 | 
						|
                    ST      midiPtr + 1
 | 
						|
                    LDI     0xFC
 | 
						|
                    ST      midiPtr                         ; channels address 0x01FC <-> 0x04FC
 | 
						|
                    LDI     0
 | 
						|
                    DOKE    midiPtr                         ; end note
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                midiGetNote
 | 
						|
midiGetNote         LDWI    giga_notesTable - 22            ; giga_notesTable + (midi - 11)*2
 | 
						|
                    STW     musicPtr
 | 
						|
                    LD      musicNote
 | 
						|
                    LSLW
 | 
						|
                    ADDW    musicPtr
 | 
						|
                    STW     musicPtr
 | 
						|
                    LUP     0x00                            ; get ROM note low byte
 | 
						|
                    ;LSLW                                    ; left shift low byte as SOUND command expects
 | 
						|
                    ST      musicNote                       ; a non system internal frequency
 | 
						|
                    LDW     musicPtr
 | 
						|
                    LUP     0x01                            ; get ROM note high byte
 | 
						|
                    ST      musicNote + 1
 | 
						|
                    LDW     musicNote                       ; this is needed for GET("MIDI_NOTE")
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                resetMusic
 | 
						|
resetMusic          LDI     giga_soundChan1 >>8
 | 
						|
                    ST      audioAddr + 1
 | 
						|
                    LDI     0
 | 
						|
                    ST      waveType                        ; wavA, (wavX is initialised by Macros)
 | 
						|
 | 
						|
resetMu_loop        LDI     giga_soundChan1
 | 
						|
                    ST      audioAddr                       ; reset low byte
 | 
						|
                    LDW     waveType
 | 
						|
                    DOKE    audioAddr                       ; wavA and wavX
 | 
						|
                    INC     audioAddr
 | 
						|
                    INC     audioAddr
 | 
						|
                    LDI     0
 | 
						|
                    DOKE    audioAddr                       ; keyL and keyH
 | 
						|
                    INC     audioAddr + 1                   ; increment high byte
 | 
						|
                    LD      audioAddr + 1
 | 
						|
                    SUBI    4
 | 
						|
                    BLE     resetMu_loop
 | 
						|
                    RET
 | 
						|
%ENDS   
 | 
						|
 | 
						|
%SUB                playMusic
 | 
						|
playMusic           PUSH
 | 
						|
                    
 | 
						|
playN_process       LDW     musicStream
 | 
						|
                    INC     musicStream
 | 
						|
                    PEEK                                    ; get music stream byte
 | 
						|
                    STW     musicCommand
 | 
						|
                    ANDI    0xF0
 | 
						|
                    XORI    0x90                            ; check for start note
 | 
						|
                    BNE     playN_endnote
 | 
						|
                    LDW     musicStream
 | 
						|
                    INC     musicStream
 | 
						|
                    PEEK                                    ; get music note
 | 
						|
                    ST      musicNote
 | 
						|
                    LDWI    midiGetNote
 | 
						|
                    CALL    giga_vAC            			; start note
 | 
						|
                    LDWI    musicPlayNote
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    BRA     playN_process
 | 
						|
                    
 | 
						|
playN_endnote       XORI    0x10                            ; check for end note
 | 
						|
                    BNE     playN_segment
 | 
						|
                    LDI     0
 | 
						|
                    STW     musicNote
 | 
						|
                    LDWI    musicPlayNote         			; end note
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    BRA     playN_process
 | 
						|
 | 
						|
playN_segment       XORI    0x50                            ; check for new segment
 | 
						|
                    BNE     playN_delay
 | 
						|
                    LDW     musicStream                     ; music stream
 | 
						|
                    DEEK
 | 
						|
                    STW     musicStream                     ; 0xD0 new music segment address
 | 
						|
                    BNE     playN_process                   ; 0x0000 = stop
 | 
						|
                    POP
 | 
						|
                    RET
 | 
						|
 | 
						|
playN_delay         LDW     musicCommand
 | 
						|
                    ST      giga_soundTimer                 ; keep pumping soundTimer
 | 
						|
                    STW     waitVBlankNum
 | 
						|
                    LDWI    waitVBlanks
 | 
						|
                    CALL    giga_vAC
 | 
						|
                    BRA     playN_process
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                musicGetNote
 | 
						|
musicGetNote        LDWI    giga_notesTable
 | 
						|
                    ADDW    musicNote
 | 
						|
                    ADDW    musicNote
 | 
						|
                    STW     musicPtr
 | 
						|
                    LUP     0x00                            ; get ROM note low byte
 | 
						|
                    ST      musicNote
 | 
						|
                    LDW     musicPtr
 | 
						|
                    LUP     0x01                            ; get ROM note high byte
 | 
						|
                    ST      musicNote + 1
 | 
						|
                    LDW     musicNote                       ; this is needed for GET("MUSIC_NOTE")
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                musicPlayNote
 | 
						|
musicPlayNote       LDW     musicCommand
 | 
						|
                    ANDI    0x03                            ; get channel
 | 
						|
                    ADDI    0x01
 | 
						|
                    ST      musicPtr + 1
 | 
						|
                    LDI     0xFC
 | 
						|
                    ST      musicPtr                        ; note address 0x01FC <-> 0x04FC
 | 
						|
                    LDW     musicNote
 | 
						|
                    DOKE    musicPtr                        ; set note
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                soundAllOff
 | 
						|
soundAllOff         LDWI    0x01FC
 | 
						|
                    STW     sndChannel
 | 
						|
                    LDI     0
 | 
						|
                    DOKE    sndChannel                      ; turn off channel 0
 | 
						|
                    INC     sndChannel + 1      
 | 
						|
                    DOKE    sndChannel                      ; turn off channel 1
 | 
						|
                    INC     sndChannel + 1      
 | 
						|
                    DOKE    sndChannel                      ; turn off channel 2
 | 
						|
                    INC     sndChannel + 1      
 | 
						|
                    DOKE    sndChannel                      ; turn off channel 3
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                soundOff
 | 
						|
soundOff            LDI     0xFC
 | 
						|
                    ST      sndChannel
 | 
						|
                    LDI     0
 | 
						|
                    DOKE    sndChannel                      ; turn off channel
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                soundOn
 | 
						|
soundOn             LDWI    SYS_LSRW1_48
 | 
						|
                    STW     giga_sysFn
 | 
						|
					LDI     0xFC
 | 
						|
                    ST      sndChannel
 | 
						|
                    LD      sndFrequency
 | 
						|
                    SYS     48
 | 
						|
                    ST      sndFrequency                    ; right shift low byte of sndFrequency by 1
 | 
						|
                    LDW     sndFrequency                    ; format = high:8 low:07, (bit 7 of low byte = 0)
 | 
						|
                    DOKE    sndChannel                      ; turn on channel
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                soundOnV
 | 
						|
soundOnV            LDWI    SYS_LSRW1_48
 | 
						|
                    STW     giga_sysFn
 | 
						|
                    LDI     0xFC
 | 
						|
                    ST      sndChannel
 | 
						|
                    LD      sndFrequency
 | 
						|
                    SYS     48
 | 
						|
                    ST      sndFrequency                    ; right shift low byte of sndFrequency by 1
 | 
						|
                    LDW     sndFrequency                    ; format = high:8 low:07, (bit 7 of low byte = 0)
 | 
						|
                    DOKE    sndChannel                      ; turn on channel
 | 
						|
                    LDI     0xFA
 | 
						|
                    ST      sndChannel                      ; still pointing to the correct channel
 | 
						|
                    LDI     63
 | 
						|
                    SUBW    sndVolume
 | 
						|
                    ADDI    64
 | 
						|
                    POKE    sndChannel                      ; 0 -> 63 maps to 127 -> 64
 | 
						|
                    INC     sndChannel
 | 
						|
                    LD      sndWaveType
 | 
						|
                    ANDI    3
 | 
						|
                    POKE    sndChannel                      ; wave type in wave X
 | 
						|
                    RET
 | 
						|
%ENDS
 | 
						|
 | 
						|
%SUB                soundMod
 | 
						|
soundMod            LDI     0xFA
 | 
						|
                    ST      sndChannel
 | 
						|
                    LDW     sndWaveType                     ; format = high:waveX low:waveA
 | 
						|
                    DOKE    sndChannel                      ; set modulation
 | 
						|
                    RET
 | 
						|
%ENDS
 |