MSX Village forum

La Place des Développeurs Assembleur MSX pour les noobs cours en ligne

TurboSEB Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 08/08/2010 à 20h57

Messages: 5886

Le 05/10/2018 à 16h04

Reprise du message précédent

Sinon c'est quoi un assembleur ? :tea
Z'avez 5minutes :oups je veu TOUT savoir :D Edité par TurboSEB Le 05/10/2018 à 16h05



MSX 1&2 + Moniteurs+divers (environ 0.70Tonnes)
   
TurboSEB Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 08/08/2010 à 20h57

Messages: 5886

Le 05/10/2018 à 18h46
Dans mon métier on se pose immédiatement LA QUESTION :glass
A QUI profite le crime ? :D



MSX 1&2 + Moniteurs+divers (environ 0.70Tonnes)
   
TurboSEB Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 08/08/2010 à 20h57

Messages: 5886

Le 06/10/2018 à 20h17
"- cadencement d'un programme par l'interruption graphique du passage à 0 vertical"
Ça, ca semble pas mal pour un Début :D :tea
(juste en aparté, c'est quoi ? J'ai bien une petite idée, mais je suis pas sûre :oups)

En définitive, faudra bien commencer par qque chose et tous les paragraphes semblent très intéressant, commençons par le premier :glass Edité par TurboSEB Le 06/10/2018 à 20h18



MSX 1&2 + Moniteurs+divers (environ 0.70Tonnes)
   
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1512

Le 07/10/2018 à 07h47
Je suis très chaud pour un article sur la musique en assembleur. J'avais bien des idées (voir ici) mais jamais eu trop l'opportunité de mettre en pratique.

@Turboseb
Le VBLANK (c'est son petit nom), je crois que c'est le moment (interruption) où ton MSX a fini d'afficher la dernière ligne horizontale, avant de passer à l'image suivante. Sur ce que j'a compris, comme ça se fait à fréquence constante, on s'en sert pour donner un "tempo" à un programme... ou une musique d'ailleurs. Par exemple, si tu ne ralentis pas en assembleur l'affichage des sprites lors d'un déplacement, celui-ci sera bien trop rapide !

N'hésitez pas à me corriger si je me fourvoie :oups


MSX un jour, MSX toujours ! :D
Site web    
Metalion Membre non connecté

Conseiller Municipal

Rang

Avatar

Inscrit le : 23/12/2009 à 15h32

Messages: 1503

Le 08/10/2018 à 11h44
Sector28_3 :
le cadencement-d'un-programme-par-l'interruption-graphique-du-passage-à-0-vertical se résume à ceci:

EI
HALT

Non. Et pour deux raisons :

1) il y a d'autres interruptions que le VBLANK qui peuvent réveiller le Z80 après un HALT, notamment celles provenant des lecteurs de disquette, mais aussi de la prise RS232, ...
2) c'est un peu inefficace de stopper complètement le processeur en attendant une interruption, on perd du temps utile

La seule vraie façon de faire consiste à utliser le hook prévu à cet effet, appelé par le BIOS à chaque VBLANK.

Sector28_3 :
le vblank se déclenche à la dernière ligne en mode pal, et à la première ligne en mode NTSC

Pas sûr de ça.
Pour moi le VBLANK se déclenche après l'affichage de la dernière ligne, dans les deux cas.

granced :
Je suis très chaud pour un article sur la musique en assembleur. J'avais bien des idées (voir ici) mais jamais eu trop l'opportunité de mettre en pratique.

Granced, j'ai écrit un replayer PSG en assembleur, basé sur les interruptions.
Plus court que ce que je pensais à l'origine (un peu plus d'un 1Ko).
Si tu veux, on peut échanger sur le sujet ?
Edité par Metalion Le 08/10/2018 à 11h57


MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
   
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1512

Le 08/10/2018 à 18h31
@Metalion

Avec plaisir. Tu as le code source commenté ? Histoire que je comprenne comment il fonctionne ?


MSX un jour, MSX toujours ! :D
Site web    
Metalion Membre non connecté

Conseiller Municipal

Rang

Avatar

Inscrit le : 23/12/2009 à 15h32

Messages: 1503

Le 08/10/2018 à 18h36
Sector28_3 :
peux-tu me dire comment tu ferais pour éviter cette perte de temps utile ?
après tout, ce n'est qu'une façon comme une autre de programmer


Quand tu utilises HALT, le processeur s'arrête et attend une interruption.
Et pendant ce temps, il ne fait strictement rien !

Si tu utilises le hook du VBLANK, ton code principal se déroule jusqu'au moment de l'interruption.
Il n'y a donc aucun arrêt du processeur.


granced :
Avec plaisir. Tu as le code source commenté ? Histoire que je comprenne comment il fonctionne ?

Oui, il est commenté, bien sûr.

Code :
;===========================================================
; Librairie SFX v2.50 - Replayer PSG/SCC sur ISR
; taille :  octets
;-----------------------------------------------------------
; History:
; v1.00 : single channel
; v2.00 : three channels
; v2.10 : direct note decoder
; v2.20 : new format of note decoder
; v2.30 : ADSR with Bresenham
; v2.31 : ADSR with value field
; v2.32 : Eight is now the master length
; v2.33 : ADSR with number of frames
; v2.40 : Track made with sequences
; v2.50 : SCC
;-----------------------------------------------------------
; Routines:
; SFX_START  : Initialisation du lecteur
; SFX_LOAD   : Ajout d'une séquence au lecteur
; SFX_PLAY   : Lecture (appelé à chaque interruption VBLANK)
; SFX_PAUSE  : Pause du lecteur
; SFX_RESUME : Reprise du lecteur
; SFX_STOP   : Arrêt du lecteur
;-----------------------------------------------------------
; Espace à réserver en RAM (154 octets)
;-----------------------------------------------------------
;sound_status:   ds      2
;PSG1:           ds      19
;PSG2:           ds      19
;PSG3:           ds      19
;SCC1:           ds      19
;SCC2:           ds      19
;SCC3:           ds      19
;SCC4:           ds      19
;SCC5:           ds      19
voice_mix            equ     0
eight                equ     1
volume               equ     2
frame_number         equ     3
note_length          equ     4
silence              equ     5
first_sequence       equ     6 ; 2 octets
current_sequence     equ     8 ; 2 octets
note                 equ     10 ; 2 octets
attack_dx            equ     12
attack_dy            equ     13
decay_dx             equ     14
decay_dy             equ     15
sustain_level        equ     16
release_dx           equ     17
release_dy           equ     18
last                 equ     19
;-----------------------------------------------------------
; Données pour chaque voix
;-----------------------------------------------------------
; Entête
; - voice_mix : paramétrage inverse du R#7 PSG pour cette séquence
; - tempo     : en nombre de noires par minute
; - volume    : volume principal
; - attack    : en nombre de frames
; - decay     : en nombre de frames
; - sustain   : niveau de volume de soutien
; - release   : en nombre de frames
; Enchainement des séquences
; - adresse séquence #1
; - adresse séquence #2
; - ...
; - $FFFF : fin des séquence (arrêt de la voix)
;   ou
; - $FFxx : recommence à la séquence #1
; Séquence
; Pour chaque son :
; - longueur de note en double croches
; - note
; - octave
; - $FF : fin de séquence
;===========================================================
;===========================================================
; SFX_START : Initialisation du lecteur
;===========================================================
SFX_START:
; Mise à zéro des pointeurs et variables
        ld      hl,sound_status
        ld      de,sound_status+1
        ld      bc,2+3*last
        ld      [hl],0
        ldir
; raz du PSG et sortie
        jp      SFX_STOP
;===========================================================
; SFX_LOAD : Chargement d'une voix dans le lecteur
; [in]  hl : adresse de la voix
;===========================================================
SFX_LOAD:
; choix du canal de la séquence
        ld      a,[hl]
        and     001001b ; canal A ?
        ld      ix,PSG1
        jp      nz,init_voice
        ld      a,[hl]
        and     010010b ; canal B ?
        ld      ix,B_voice
        jp      nz,init_voice
        ld      a,[hl]
        and     100100b ; canal C ?
        ld      ix,C_voice
; sortie si aucun son
        ret     z
        
        ld      de,19
        ld      ix,PSG1
        ld      b,1
        ld      a,[hl]
loop:   and     b
        jp      nz,init_voice
        sla     b
        add     ix,de
        jp      loop
init_voice:
; voice mix
        ld     [ix+voice_mix],a
; mise à jour du sound status et du registre 7
        ld     b,a
        ld     a,[sound_status]
        or     b
        ld     [sound_status],a
        ; inversion de la valeur et écriture dans le registre 7
        cpl
        and     00111111b
        or      10000000b ; protection PSG
        ld      e,a
        ld      a,7
        call    WRTPSG
; calcul de la durée d'une double croche
        inc     hl
        ld      a,[hl]          ; tempo
        call    EIGHT
        ld      [ix+eight],a
; volume principal
        inc     hl
        ld      a,[hl]          ; volume principal
        ld      [ix+volume],a
        ld      [ix+attack_dy],a
; préparation de l'enveloppe ADSR
        ; attack
        inc     hl
        ld      a,[hl]
        ld      [ix+attack_dx],a
        ; decay
        inc     hl
        ld      a,[hl]
        ld      [ix+decay_dx],a
        ; sustain
        inc     hl
        ld      a,[hl]
        ld      [ix+sustain_level],a
        ld      b,a
        ld      a,[ix+volume]
        sub     b
        ld      [ix+decay_dy],a   ; dy = |sustain - volume|
        ; release
        inc     hl
        ld      a,[hl]
        ld      [ix+release_dx],a
        ld      a,b
        ld      [ix+release_dy],a ; dy = |0 - sustain|
; pointeur sur l'adresse de la première séquence
; (et donc la séquence en cours)
        inc     hl
        ld      [ix+first_sequence+1],h
        ld      [ix+first_sequence],l
        ld      [ix+current_sequence+1],h
        ld      [ix+current_sequence],l
; pointeur sur l'adresse de la première note de la première séquence
        ld      e,[hl]
        inc     hl
        ld      d,[hl]
        ld      [ix+note+1],d
        ld      [ix+note],e
; durée de son à 1 et frame number à zéro, pour le
; chargement automatique de la première note par SFX_PLAY
        ld     [ix+frame_number],0
        ld     [ix+note_length],1
; sortie
        ret
;-----------------------------------------------------------
; calcul de la durée d'une double croche
; [in]  a: tempo de la séquence
; [out] a: durée en frames d'une noire
;-----------------------------------------------------------
; constante BIOS
BASRVN  equ     002Bh ; BASIC ROM version number
EIGHT:  ex      af,af'
        exx
; détermination de la fréquence du VBLANK
        ld      a,[BASRVN]
        rla     ; récupération du bit 7 dans carry
        ld      hl,60*50/4 ; base de calcul 50Hz (60 secondes x 50 Hz / 4)
        jp      c,vdp50Hz
        ld      hl,60*60/4 ; base de calcul 60Hz (60 secondes x 60 Hz / 4)
; calcul de la durée d'une noire = 60 x fréquence / 4 / tempo
vdp50Hz:ex      af,af'
        ld      c,a
        call    DIV_HL_BY_C
        ld      a,l ; a=résultat de la division
        exx
        ret
;===========================================================
; SFX_PLAY : Lecture (appelé à chaque interruption VBLANK)
;===========================================================
SFX_PLAY:
; sortie si aucun son en cours
        ld      a,[sound_status]
        and     a
        ret     z
; traitement des voix
        ; voix & noise A
        and     001001b
        ld      ix,PSG1
        ld      d,0
        call    nz,play_channel
        ; voix & noise B
        ld      a,[sound_status]
        and     010010b
        ld      ix,PSG2
        ld      d,1
        call    nz,play_channel
        ; voix & noise C
        ld      a,[sound_status]
        and     100100b
        ld      ix,PSG3
        ld      d,2
        ; sortie si plus de canal à traiter
        ret     z
;-----------------------------------------------------------
; traitement du canal
;-----------------------------------------------------------
play_channel:
        ; incrémentation du numéro de frame
        inc     [ix+frame_number]
        ld      a,[ix+frame_number]
        ; comparaison avec la longueur de la note
        cp      [ix+note_length]
        ; si fin du son, chargement d'un nouveau son
        jp      z,new_sound
        ; si c'est un silence en cours, sortie
        ex      af,af'
        ld      a,[ix+silence]
        and     a
        ret     nz
        ; sinon, récupération du volume de l'enveloppe ADSR
        ex      af,af'
        call    ADSR
        ; écriture si valeur différente et sortie
        ld      e,a
        ld      a,d
        add     8
        ld      b,a
        call    RDPSG
        cp      e
        ret     z
        ld      a,b
        jp      WRTPSG
;-----------------------------------------------------------
; nouveau son
;-----------------------------------------------------------
new_sound:
        ; chargement dans 'hl' de la position de note
        ld      h,[ix+note+1]
        ld      l,[ix+note]
        ; si 'FF', alors fin de séquence
        ld      a,[hl]
        cp      0FFh
        jp      z,sequence_end
new_sound2:
        ; sinon, c'est la longueur de note, ajustement
        call    NOTE_LENGTH
        ld      [ix+note_length],a
        ; et numéro de frame à zéro
        ld      [ix+frame_number],0
        ; et ensuite la note en elle-même
        inc     hl
        ld      a,[hl]
        cp      82 ; "R" silence
        jp      z,rest
        ld      [ix+silence],0 ; flag de silence à zéro
        sub     65 ; "A"
        add     a
        add     a ; x4
        ld      c,a ; c = 4.note
        ; altérations éventuelles ou octave
        inc     hl
        ld      a,[hl]
        ; altérations du ton de la note
        cp      35 ; "#" dièse
        call    z,DIESE
        cp      98 ; "b" bémol
        call    z,BEMOL
        ; altérations de la longueur de note
        cp      46 ; "." pointée
        call    z,DOTTED
        cp      58 ; ":" double pointée
        call    z,DOUBLE_DOTTED
        ; calcul de l'octave
        dec     a
        add     a
        add     a ; x4
        ld      e,a
        add     a
        add     a
        add     a ; x32
        sub     e ; x28
        add     a,c
        ld      b,0
        ld      c,a ; bc = 28.octave + 4.note (+/- 2.demi-note)
        ; fréquence de la note
        push    hl
        ld      hl,frequencies
        add     hl,bc
        ; partie basse
        ld      e,[hl]
        ld      a,d
        add     a ; x2
        call    WRTPSG
        ; partie haute
        inc     hl
        ld      e,[hl]
        ld      a,d
        add     a
        inc     a ; x2+1
        call    WRTPSG
        ; volume initial de l'enveloppe : ADSR(0)
        xor     a
        call    ADSR
        ld      e,a
        ld      a,d
        add     8
        call    WRTPSG
        ; préparation du pointeur de note pour la prochaine note
        pop     hl
        inc     hl
        ld      [ix+note+1],h
        ld      [ix+note],l
        ret
;-----------------------------------------------------------
; silence
;-----------------------------------------------------------
rest:   ; volume à zéro
        ld      e,0
        ld      a,d
        add     8
        call    WRTPSG
        ; flag de silence à 1
        ld      [ix+silence],1
        ; préparation du pointeur de note pour la prochaine note
        inc     hl
        ld      [ix+note+1],h
        ld      [ix+note],l
        ; sortie
        ret
;-----------------------------------------------------------
; fin de séquence
;-----------------------------------------------------------
sequence_end:
; chargement du pointeur sur l'adresse de la séquence suivante
        ld      h,[ix+current_sequence+1]
        ld      l,[ix+current_sequence]
        inc     hl
        inc     hl
        ld      [ix+current_sequence+1],h
        ld      [ix+current_sequence],l
; fin du track ?
        ld      e,[hl]
        inc     hl
        ld      d,[hl]
        ld      a,0FFh
        cp      d
        jp      z,track_end
; sinon, chargement adresse première note séquence suivante et reprise
        ld      [ix+note+1],d
        ld      [ix+note],e
        ld      a,[de]
        jp      new_sound2
;-----------------------------------------------------------
; fin de track
;-----------------------------------------------------------
track_end:
        cp      e
        jp      z,track_stop ; $FFFF
; répétition de la voix ($FFxx)
        ; reprise de la première séquence
        ld      h,[ix+first_sequence+1]
        ld      l,[ix+first_sequence]
        ld      [ix+current_sequence+1],h
        ld      [ix+current_sequence],l
; chargement adresse première note séquence suivante et reprise
        ld      e,[hl]
        inc     hl
        ld      d,[hl]
        ld      [ix+note+1],d
        ld      [ix+note],e
        ld      a,[de]
        jp      new_sound2
track_stop:
        ; arrêt du canal note & noise
        ld      a,[ix+voice_mix]
        cpl
        ld      b,a
        ld      a,[sound_status]
        and     b
        ld      [sound_status],a
        ; et mise à jour du registre 7 du PSG
        cpl
        and     00111111b
        or      10000000b
        ld      e,a
        ld      a,7
        jp      WRTPSG
;-----------------------------------------------------------
; Enveloppe ADSR
; [in]  a: numéro de frame de la note en cours
; [out] a: volume de l'enveloppe
;-----------------------------------------------------------
ADSR:   ld      b,a
        ld      a,[ix+attack_dx]
        cp      b  ;
        jp      c,decay ; frame >= temps d'attaque
        ; -- Attack --
        ld      h,b
        ld      e,[ix+attack_dy]
        call    MUL_H_BY_E
        ld      c,[ix+attack_dx]
        call    DIV_HL_BY_C
        ld      a,l
        ret
        ; -- Decay --
decay:  add     a,[ix+decay_dx]
        cp      b
        jp      c,sustain ; frame >= temps de decay
        ld      a,b
        sub     [ix+attack_dx]
        ld      h,a
        ld      e,[ix+decay_dy]
        call    MUL_H_BY_E
        ld      c,[ix+decay_dx]
        call    DIV_HL_BY_C
        ld      a,l
        neg
        add     [ix+volume]
        ret
        ; -- Sustain --
sustain:ld      a,[ix+note_length]
        sub     [ix+release_dx]
        cp      b
        jp      c,release ; frame >= longueur note - temps de release
        ld      a,[ix+sustain_level]
        ret
        ; -- Release --
release:sub     b         ; a = frame - (longueur de note - temps de release)
        ret     c         ; sortie si négatif
        ld      h,a
        ld      e,[ix+release_dy]
        call    MUL_H_BY_E
        ld      c,[ix+release_dx]
        call    DIV_HL_BY_C
        ld      a,l
        neg
        add     [ix+sustain_level]
        ret
;-----------------------------------------------------------
; Calcul de la longueur de note
; [in]  a: longueur de note en nombre de quadruple croches
; [out] a: longueur de note en frames (max 255, pas de protection !)
;-----------------------------------------------------------
NOTE_LENGTH:
        ld      b,a
        cp      4        ; 4 = valeur d'une double croche
        ld      a,[ix+eight]
        ret     z        ; c'est une double croche
        jp      c,@@less
        ; c'est plus long
@@more: add     a   ; a=ax2
        srl     b   ; b=b/2
        bit     2,b
        ret     nz
        jp      @@more
        ; c'est plus court
@@less: srl     a   ; a=a/2
        sla     b   ; b=bx2
        bit     2,b
        ret     nz
        jp      @@less
;-----------------------------------------------------------
; altérations chromatiques
;-----------------------------------------------------------
DIESE:  inc     c
        inc     c      ; bc = 4.note + 2.demi-note
        inc     hl
        ld      a,[hl] ; élément suivant
        ret
BEMOL:  dec     c
        dec     c      ; bc = 4.note - 2.demi-note
        inc     hl
        ld      a,[hl] ; élément suivant
        ret
;-----------------------------------------------------------
; altérations de la longueur de note
;-----------------------------------------------------------
DOTTED: ex      af,af'
        ld      a,[ix+note_length]
        ld      b,a
        srl     b ; b=a/2
        add     b ; a=1.5xa
        ld      [ix+note_length],a
        ex      af,af'
        inc     hl
        ld      a,[hl] ; élément suivant
        ret
DOUBLE_DOTTED:
        ex      af,af'
        ld      a,[ix+note_length]
        ld      b,a
        srl     b ; b=a/2
        ld      e,b
        srl     e ; e=a/4
        add     b
        add     e ; a=1.75xa
        ld      [ix+note_length],a
        ex      af,af'
        inc     hl
        ld      a,[hl] ; élément suivant
        ret
;===========================================================
; SFX_PAUSE : Pause du lecteur
;===========================================================
SFX_PAUSE:
; sauvegarde du sound_status
        ld      a,[sound_status]
        ld      [sound_status+1],a
; arrêt du traitement SFX
        xor     a
        ld      [sound_status],a
; toutes les canaux 'off' et sortie
        ld      a,7
        ld      e,10111111b
        jp      WRTPSG
;===========================================================
; SFX_RESUME : Reprise du lecteur
;===========================================================
SFX_RESUME:
; récupération de la sauvegarde
        ld      a,[sound_status+1]
        ld      [sound_status],a
; reparamétrage du PSG
        cpl
        and     00111111b
        or      10000000b ; protection PSG
        ld      e,a
        ld      a,7
        jp      WRTPSG
;===========================================================
; SFX_STOP : Arrêt du lecteur
;===========================================================
SFX_STOP:
        ; toutes les canaux 'off'
        ld      a,7
        ld      e,10111111b
        call    WRTPSG
        ; mise à zéro du volume canal A
        ld      a,8
        ld      e,0
        call    WRTPSG
        ; mise à zéro du volume canal B
        ld      a,9
        call    WRTPSG
        ; mise à zéro du volume canal C
        ld      a,10
        jp      WRTPSG
;===========================================================
; Module SCC
;===========================================================
SCC_waveform    equ     9800h
SCC_register    equ     9880h
;===========================================================
; WRTSCC : écriture dans les registres SCC
; [in]  a: numéro de registre
;       e: valeur
;===========================================================
WRTSCC: ex      af,af'
        ld      a,e
        exx
        ; sélection de la page SCC
        ld      hl,9000h
        ld      [hl],03Fh
        ; écriture
        ex      af,af'
        ld      hl,SCC_register
        ld      c,a
        ld      b,0
        add     hl,bc
        ex      af,af'
        ld      [hl],a
        exx
        ret
;===========================================================
; RDSCC : lecture des registres SCC
; [in]  a: numéro de registre
; [out] a: valeur
;===========================================================
RDSCC:  exx
        ; sélection de la page SCC
        ld      hl,9000h
        ld      [hl],03Fh
        ; écriture
        ld      hl,SCC_register
        ld      c,a
        ld      b,0
        add     hl,bc
        ld      a,[hl]
        exx
        ret
;===========================================================
; LOAD_WAVE : chargement d'une waveform
; [in]  a: numéro de canal
;      hl: adresse des données
;===========================================================
LOAD_WAVE:
        push    hl
        ; sélection de la page SCC
        ld      hl,9000h
        ld      [hl],03Fh
        add     a,a
        add     a,a
        add     a,a
        add     a,a
        add     a,a ; a = 32.canal
        ; transfert des données
        ld      hl,SCC_waveform
        ld      e,a
        ld      d,0
        add     hl,de
        ex      de,hl ; de = SCC_waveform + 32.canal
        ld      bc,32 ; bc = 32
        pop     hl    ; hl = adresse des données
        ldir
        ret
;===========================================================
; Multiplication de 'h' par 'e'
; [in]   h: donnée
;        e: multiplicateur
; [out] hl: résultat
;===========================================================
MUL_H_BY_E:
        ld      a,d ; sauvegarde de 'd'
        ld      d,0
        ld      l,d
        ld      b,8
Mloop:  add     hl,hl
    jr      nc,NoAdd
    add     hl,de
NoAdd:  djnz    Mloop
        ld      d,a ; récupération de 'd'
    ret
;===========================================================
; Division de 'hl' par 'c'
; [in] hl: dividende
;       c: diviseur
; [out] l: résultat
;       h: reste
;===========================================================
DIV_HL_BY_C:
        ld      b,8
@@next: add     hl,hl
        ld      a,h
        sub     c
        jr      c,@@next_b
        ld      h,a
        inc     l
@@next_b:
        djnz    @@next
        ret
;===========================================================
; Table des fréquences de notes
;===========================================================
;---------------------------------------------------------------
;|    Octave |     |       |     |     |     |       |     |     |
;|           |  1  |    2  |  3  |  4  |  5  |    6  |  7  |  8  |
;| Note           |     |       |     |     |     |       |     |     |
;|-------------+-----+-----+-----+-----+-----+-----+-----+-----|
;|      C      | D5D | 6AF | 357 | 1AC |  D6 |    6B |  35 |  1B |
;|-------------+-----+-----+-----+-----+-----+-----+-----+-----|
;|      C#     | C9C | 64E | 327 | 194 |  CA |    65 |  32 |  19 |
;|-------------+-----+-----+-----+-----+-----+-----+-----+-----|
;|      D      | BE7 | 5F4 | 2FA | 17D |  BE |    5F |  30 |  18 |
;|-------------+-----+-----+-----+-----+-----+-----+-----+-----|
;|      D#     | B3C | 59E | 2CF | 168 |  84 |    5A |  2D |  16 |
;|-------------+-----+-----+-----+-----+-----+-----+-----+-----|
;|      E      | A9B | 54E | 2A7 | 153 |  AA |    55 |  2A |  15 |
;|-------------+-----+-----+-----+-----+-----+-----+-----+-----|
;|      F      | A02 | 501 | 281 | 140 |  A0 |    50 |  28 |  14 |
;|-------------+-----+-----+-----+-----+-----+-----+-----+-----|
;|      F#     | 973 | 4BA | 25D | 12E |  97 |    4C |  26 |  13 |
;|-------------+-----+-----+-----+-----+-----+-----+-----+-----|
;|      G      | 8EB | 476 | 23B | 11D |  8F |    47 |  24 |  12 |
;|-------------+-----+-----+-----+-----+-----+-----+-----+-----|
;|      G#     | 88B | 436 | 21B | 10D |  87 |    43 |  22 |  11 |
;|-------------+-----+-----+-----+-----+-----+-----+-----+-----|
;|      A      | 7F2 | 3F9 | 1FD |  FE |  7F |    40 |  20 |  10 |
;|-------------+-----+-----+-----+-----+-----+-----+-----+-----|
;|      A#     | 780 | 3C0 | 1E0 |  F0 |  78 |    3C |  1E |   F |
;|-------------+-----+-----+-----+-----+-----+-----+-----+-----|
;|      B      | 714 | 38A | 1C5 |  E3 |  71 |    39 |  1C |   E |
;---------------------------------------------------------------
frequencies:
; table de 224 octets
; A,A#,B,-,C,C#,D,D#,E,-,F,F#,G,G#
dw      07F2h,0780h,0714h,0,0D5Dh,0C9Ch,0BE7h,0B3Ch,0A9Bh,0,0A02h,0973h,08EBh,088Bh ; octave 1
dw      03F9h,03C0h,038Ah,0,06AFh,064Eh,05F4h,059Eh,054Eh,0,0501h,04BAh,0476h,0436h ; octave 2
dw      01FDh,01E0h,01C5h,0,0357h,0327h,02FAh,02CFh,02A7h,0,0281h,025Dh,023Bh,021Bh ; octave 3
dw      00FEh,00F0h,00E3h,0,01ACh,0194h,017Dh,0168h,0153h,0,0140h,012Eh,011Dh,010Dh ; octave 4
dw      007Fh,0078h,0071h,0,00D6h,00CAh,00BEh,0084h,00AAh,0,00A0h,0097h,008Fh,0087h ; octave 5
dw      0040h,003Ch,0039h,0,006Bh,0065h,005Fh,005Ah,0055h,0,0050h,004Ch,0047h,0043h ; octave 6
dw      0020h,001Eh,001Ch,0,0035h,0032h,0030h,002Dh,002Ah,0,0028h,0026h,0024h,0022h ; octave 7
dw      0010h,000Fh,000Eh,0,001Bh,0019h,0018h,0016h,0015h,0,0014h,0013h,0012h,0011h ; octave 8





Edité par Metalion Le 08/10/2018 à 18h45


MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
   
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1512

Le 09/10/2018 à 08h07
:|
Ah ouais, quand même... Bon eh bien, à dans 2 ans, le temps que je décortique tout ça ! :lol

Blague à part, je vois que tu as intégré la gestion de la SCC (perso j'en demandais pas autant ! :p), aurais-tu une version plus condensée avec la gestion du PSG seul ? Et si tu peux nous détailler un peu la méthode que tu emploies (quelle est la forme des datas, comment tu gères les durées de notes comme les triolets ou sextolets ? )

En te remerciant


MSX un jour, MSX toujours ! :D
Site web    
Metalion Membre non connecté

Conseiller Municipal

Rang

Avatar

Inscrit le : 23/12/2009 à 15h32

Messages: 1503

Le 09/10/2018 à 13h57
@Granced

Le module SCC intégré n'est pas encore opérationnel, il y a juste pour l'instant les routines de base. En fait j'aurai du poster la version précédente (v2.40) car cette version n'est pas encore terminée.

Pour répondre à tes questions :
- la forme des datas est précisées dans l'entête du code
- la longueur de note minimale (et l'unité de mesure de toutes les autres) est la quadruple croche (1/16e de noire), je ne gère pas pour l'instant les triolets ou les sextolets

EDIT : mais il faudrait peut-être déplacer cette discussion dans l'autre post que tu avais ouvert sur ce sujet. Edité par Metalion Le 09/10/2018 à 14h29


MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
   
TurboSEB Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 08/08/2010 à 20h57

Messages: 5886

Le 09/10/2018 à 19h20
Je comprend pas tout, mais j'observe un langage structurer qui peu manifestement être compris avec un peu de connaissances, mais perso,je ne maîtrise déjà pas cela en Basic.
J'ai une question :D
Quand on parle de routine genre SFX_STOP, cela s'entend par une commande Basic ? :tea
Genre, si Igal:glass voudrait synthétiser son programme de scrolling, ça serait possible de "Routiner" le tout en quelques commande Basic ? :siffle
Si ce n'est pas le cas ici est-ce possible ? Edité par TurboSEB Le 09/10/2018 à 20h36



MSX 1&2 + Moniteurs+divers (environ 0.70Tonnes)
   
Metalion Membre non connecté

Conseiller Municipal

Rang

Avatar

Inscrit le : 23/12/2009 à 15h32

Messages: 1503

Le 10/10/2018 à 10h12
TurboSEB :
J'ai une question
Quand on parle de routine genre SFX_STOP, cela s'entend par une commande Basic ?

Non, c'est une routine en assembleur, identifiée par son point d'entrée matérialisé par un label SFX_STOP.
En pratique, ailleurs dans le code assembleur, elle pourra être appelé par un "call SFX_STOP"

TurboSEB :
Genre, si Igal:glass voudrait synthétiser son programme de scrolling, ça serait possible de "Routiner" le tout en quelques commande Basic ? :siffle
Si ce n'est pas le cas ici est-ce possible ?

Oui l'interaction entre le BASIC et l'assembleur est possible.
Soit par un appel USR(x), c'est le plus simple, soit par la définition d'une nouvelle instruction que l'on peut appeler par CALL XXX.
"CALL MUSIC" est en un exemple, lorsque MSX-Music est présent sur un ordinateur.


MSX1: Daewoo DPC-200 / Yamaha CX5M
MSX2: Sony HB-F9P
MSXVR
Vidéo: V9990 (GFX-9)
Audio: MSX-Music (FM-PAC) / MSX-Audio (Audiowave) / OPL4 (Monster Sound FM Blaster) / OPNB (Neotron)
   
Jipe Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 02/10/2009 à 19h41

Messages: 10730

Le 10/10/2018 à 17h23
en assembleur il n'y a pas de lignes numérotées comme sur le basic
donc on marche avec des étiquettes

; SFX_STOP : Arrêt du lecteur [ commentaire car ; devant ]

jp SFX_STOP [ saut a la routine ]

; SFX_STOP : Arrêt du lecteur
;===========================================================
SFX_STOP: [ début routine en LM ]
; toutes les canaux 'off'
ld a,7
ld e,10111111b
call WRTPSG
; mise à zéro du volume canal A
ld a,8
ld e,0
call WRTPSG
; mise à zéro du volume canal B
ld a,9
call WRTPSG
; mise à zéro du volume canal C
ld a,10
jp WRTPSG

donc quand on fait jp SFX_STOP c'est comme un goto en basic


:noel
Site web    
Visiteur

Vagabond

Rang

Avatar

Message : 0

Le 11/10/2018 à 08h30
@TurboSEB
Pour débuter je conseille la lecture de "Assembleur et périphériques des MSX" :top de Pierre BRANDEIS et Frédéric BLANC Éditions du PSI 1985.
Cet ouvrage contient des explications claires ainsi que des exemples et des exercices. Je pense que c'est un prérequis pour s'y mettre vraiement. Il est disponible dans le village ici.
   
granced Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 09/10/2009 à 09h18

Messages: 1512

Le 11/10/2018 à 11h09
Je plussoie Sylvain. C'est ce bouquin qui m'a motivé à faire des essais.


MSX un jour, MSX toujours ! :D
Site web    
TurboSEB Membre non connecté

Conseiller Municipal

Rang

Avatar

Groupe : compte ++ Groupe : Shoutbox

Inscrit le : 08/08/2010 à 20h57

Messages: 5886

Le 11/10/2018 à 17h50
Ah bah fallait commencer par ça, j'ai pas tout lu mais c'est prometteur :top

Merci :D Edité par TurboSEB Le 11/10/2018 à 17h50



MSX 1&2 + Moniteurs+divers (environ 0.70Tonnes)
   
MSXosaure Membre non connecté

Maire-adjoint

Rang

Avatar

Association

Inscrit le : 03/10/2009 à 00h09

Messages: 781

Le 21/12/2018 à 23h12
Salut à tous ce serait intéressant pour moi, mais il faut que je retrouve mes précédents posts :gne il faudrait les isoler ceux-là aussi ça me motiverai pour m'y remettre :siffle

:lol


Le MSXien le plus à l'ouest :fou ... ou presque :D
osaurer
   
Répondre
Vous n'êtes pas autorisé à écrire dans cette catégorie