;------------------------------- ; VG5000 ; ; PLAYER XYM for AY-3 (VG5232) ; ; (c) 2017 6502man ; ;------------------------------- ; ; ; With BASIC : CALL &"3E40":REM xxxx,Y ; xxxx = pointeur of music data ; Y = 0: one time music 1: loop music PSG_Adr .EQU $FF PSG_Data .EQU $FE Int .EQU $47D0 Boucle .EQU $FFF7 ; flag pour jouer en boucle la musique ou non DebutXYM .EQU $FFF8 ; sauvegarde adresse debut datas musique AY3 .EQU $FFFA ; pointeur adresse musique encours Frames .EQU $FFFC ; Total Frames à jouer TotFrame .EQU $FFFE ; compteur de frames restants à jouer .org $3E40 Init DI push AF push BC push DE push HL push IX ; push IY ;on récupére l'argument après CALL inc HL inc HL ;FirstDigit ASCII2HEX inc HL LD A,(HL) CP $3A ; JP M,Num ;************************* JR Z,num ; plus court d'un octet que le JP ;************************* SUB $37 Num AND $0F ; SLA A ; SLA A ; SLA A ; SLA A ;************************* ADD A,A ; x2 ADD A,A ; x4 ADD A A ; x8 ;************************* LD D,A inc HL LD A,(HL) CP $3A ; JP M,Num2 ;************************* JR Z,num2 ;************************* SUB $37 Num2 AND $0F ADD A,D LD D,A inc HL LD A,(HL) CP $3A ; JP M,Num3 ;************************* JR Z,num3 ;************************* SUB $37 Num3 AND $0F ; SLA A ; SLA A ; SLA A ; SLA A ;************************* ADD A,A ; x2 ADD A,A ; x4 ADD A A ; x8 ;************************* LD E,A inc HL PUSH HL ; on sauvegarde le pointeur sur les donnees transmises à la suite du REM LD A,(HL) CP $3A ; JP M,Num4 ;************************* JR Z,num4 ;************************* SUB $37 Num4 AND $0F ADD A,E LD E,A LD HL,$0019 ADD HL,DE EX DE,HL ;LD DE,AY3+23 ; Position des données ; LD HL,AY3 ; variable en RAM (pointeur des données) ; LD IX,DebutXYM ; variable en RAM (sauvegarde pointeur des données) ; LD A,D ; LD (HL),A ; INC HL ; LD (IX),A ; INC IX ; LD A,E ; LD (HL),A ; LD (IX),A ; ************************************** LD (HL),D INC HL LD (IX+$0),D LD (HL),E LD (IX+$1),E ; ************************************** ; on prepare les variables pour le player ; EX DE,HL ; LD DE,$0016 ; SBC HL,DE ; EX DE,HL ; ************************************** ; on prepare les variables pour le player LD BC,$0016 SBC HL,BC ; ************************************** ;LD DE,AY3+1 ; nombre total de frame à jouer ; LD HL,TotFrame ; variable en RAM (compteur de frames) ; LD IX,Frames ; LD A,(DE) ; LD (HL),A ; LD (IX),A ; INC DE ; INC HL ; INC IX ; LD A,(DE) ; LD (HL),A ; LD (IX),A ; POP HL ; INC HL ; INC HL ; LD A,(HL) ; AND $0F ; LD HL,Boucle ; LD (HL),A ; ************************************** ; En theorie, on a dans HL ler resultat du calcul precedent ;LD DE,AY3+1 ; nombre total de frame à jouer LD DE,TotFrame ; variable en RAM (compteur de frames) LD IX,Frames EX DE,HL LDI ; le contenu de HL est recopie dans DE puis HL et DE sont incrementes et BC decremente LD (IX+$0),A LDI LD (IX+$1),A POP HL INC HL INC HL LD A,(HL) AND $0F LD HL,Boucle LD (HL),A ; ************************************** ; on met en place l'interruption. ; LD HL,Int ; LD A,$C3 ; LD (HL),A ; INC HL ; LD DE,Player ; LD A,E ; LD (HL),A ; INC HL ; LD A,D ; LD (HL),A ; ************************************** ; on met en place l'interruption v2 ; LD HL,Int LD (HL),&C3 INC HL LD DE,Player LD (HL),E INC HL LD (HL),D ; ************************************** ; LD HL,IntCount ; LD A,7 ; LD (HL),A ; pop IY pop IX pop HL pop DE pop BC pop AF EI RET ;///////////////////////////////////////// Player DI ; desactive INT pour musique push AF push BC push DE push HL push IX push IY ; LD HL,IntCount ; test si 6eme occurence d'appel ; DEC (HL) ; de l'interruption ; JP NZ,FinInt ; ; LD HL,IntCount ; remet le compteur à 7 ; LD A,7 ; LD (HL),A LD HL,AY3 ; variable en RAM (pointeur des données) LD A,(HL) LD D,A INC HL LD A,(HL) LD E,A BoucleAY3 LD C,00 LD A,(DE) ; on lit le premier octet de compression XYM LD H,A ; on reserve l'octet INC DE LD A,(DE) ; on lit le deuxieme octet de compression XYM LD L,A ; on reserve l'octet INC DE LD B,$09 ; compteur de décalage bits des 2 octets lu précedement Frame DEC B JP Z,Oct2 LD A,C OUT (PSG_Adr),A INC C SLA H ; décale 1 bit à gauche et récupére l'état du bit dans Carry JP NC,Frame LD A,(DE) OUT (PSG_Data),A INC DE JP Frame Oct2 LD B,$07 ; compteur de décalage des bits 2 octets lu précedement Frame2 DEC B JP Z,EndFrame LD A,C OUT (PSG_Adr),A INC C SLA L ; décale 1 bit à gauche et récupére l'état du bit dans Carry JP NC,Frame2 LD A,(DE) OUT (PSG_Data),A INC DE JP Frame2 EndFrame ; test fin de la musique ? LD HL,TotFrame+1 ; variable en RAM DEC (HL) JP NZ,Continueplay LD HL,TotFrame ; variable en RAM DEC (HL) LD A,$00 CP (HL) JP Z,Exit Continueplay ; mise à jour du pointeur LD HL,AY3 ; variable en RAM (pointeur des données) LD A,D LD (HL),A INC HL LD A,E LD (HL),A FinInt pop IY pop IX pop HL pop DE pop BC pop AF EI ; retabli INT RET Exit LD HL,Boucle LD A,$00 CP (HL) JP Z,FIN LD HL,DebutXYM LD DE,AY3 LD A,(HL) LD (DE),A INC HL INC DE LD A,(HL) LD (DE),A LD DE,Frames LD HL,TotFrame ; variable en RAM (compteur de frames) LD A,(DE) LD (HL),A INC DE INC HL LD A,(DE) LD (HL),A JP FinInt FIN LD HL,Int LD A,$C9 ; arrete l'interruption. LD (HL),A ;Eteindre le son du AY-3 JP FinInt ENDFILE .END