Pour les curieux, voici le programme assembleur :
Code : Tout sélectionner
/**************************************************\
* S D R A M A *
* (c) 2016 - Daniel Coulom *
* http://dcmoto.free.fr/ *
* http://forum.system-cfg.com/ *
*--------------------------------------------------*
* Ce code est distribue gratuitement dans l'espoir *
* qu'il sera utile, mais sans aucune garantie et *
* sans engager la responsabilité de l'auteur. *
* Vous pouvez l' utiliser, le modifier et le *
* diffuser librement, en conservant cette licence *
* et les références de l'auteur dans toutes les *
* copies. L'exploitation commerciale est interdite.*
\**************************************************/
* Ce programme utilise l'interface SDMOTO ou SDMO
* associee au controleur CS91-280 ou CS91-282 pour
* jouer de la musique en streaming en affichant
* une image monochrome entre chaque séquence.
* Le chargement et le lancement du programme sont
* realises grace a un secteur de boot.
*
* Utilisation du 2eme port joystick avec SDMOTO
* Port A $A7CC (pour les MO) ou $E7CC (pour les TO)
* PA5 en sortie --> SD Clock SCK DB9 pin 2
* PA6 en sortie --> SD Data IN MOSI DB9 pin 3
* PA7 en entree <-- SD Data OUT MISO DB9 pin 4
*
* Utilisation port magnetophone avec SDMO
* Port A $A7C0 pour les donnees
* PA6 en sortie --> SD Data IN MOSI DB9 pin 3
* PA7 en entree <-- SD Data OUT MISO DB9 pin 4
* Port B $A7C2 pour l'horloge
* PA3 en sortie --> SD Clock SCK DB9 pin 2
/**************************************************\
* Version 2016.05.24 *
\**************************************************/
* Historique
* 2016.05.24 correction echantillon octet de fin
* 2016.05.24 correction derive du pointeur de pile
* 2016.05.22 premiere version issue de SDPLAY 2016
*------------------------------------------------------
* DEBUT DU PROGRAMME
*------------------------------------------------------
ORG $9D00
BRA INIT initialisations
*------------------------------------------------------
* FONCTIONS D'ACCES A LA CARTE SD
*------------------------------------------------------
CMD18
FCB $52 read multiple block
FDB $0000 adresse bloc (poids fort)
FDB $0000 adresse bloc (poids faible)
FCB $FF checksum non testee
FCB $00 code retour attendu
CMD12
FCB $4C stop transmission
FDB $0000 dummy parameter
FDB $0000 dummy parameter
FCB $FF checksum non testee
FCB $00 code retour attendu
*------------------------------------------------------
* Detection du type d'ordinateur
*------------------------------------------------------
INIT
ORCC #$50
LDX #$1F40 adresse pour test RAM ou ROM
LDB ,X lecture adresse X
COM ,X tente de modifier adresse X
CMPB ,X test modification adresse X
BEQ INIT2 pas de difference -> TO
COM ,X retablissement adresse X
*------------------------------------------------------
* Initialisations MO
*------------------------------------------------------
INIT1
LDA $A7C0 port A du PIA systeme
ANDA #$E1 raz couleur cadre
ORA #$0E couleur cadre 7 (blanc)
STA $A7C0 change couleur cadre
LDU #$A7C0 adresse selection banque video
LDY #$0000 adresse debut ecran
LDB #$07 octet couleur
BSR COLOR initialisation couleurs
LDA $A6FF numero banque CS91-280
CMPA #$B0 test banque B0
BEQ INIT3 CS91-280 est en mode SDMOTO
LBSR RBSDMO modification routine RBYTE
BRA INIT3 suite des initialisations
*------------------------------------------------------
* Initialisations TO
*------------------------------------------------------
INIT2
LDA #$07 couleur cadre 7 (blanc)
STA $E7DD change couleur cadre
LDU #$E7C3 adresse selection banque video
LDY #$4000 adresse debut ecran
STY DISPLAY+1 initialisation adresse ecran
LDB #$C7 octet couleur
BSR COLOR initialisation couleurs
LDA #$E0 valeur adresse EXCMD (poids fort)
STA READ+4 pour execution CMD18
STA ARRET+4 pour execution CMD12
BRA INIT3 suite des initialisations
*------------------------------------------------------
* Initialisation couleur noir/blanc (Y = debut ecran)
* Adresse du bit de selection banque video dans U
* Adresse octet couleur dans B
*------------------------------------------------------
COLOR
LDA ,U octet de selection banque video
ANDA #$FE clear bit 0
STA ,U selection video couleur
LDX #$1F40 compteur de boucles
TFR B,A code couleur sur deux octets
COLOR1
STD ,Y++ initialise deux octets
LEAX -2,X comptage
BNE COLOR1 boucle
INC ,U selection video forme
RTS
*------------------------------------------------------
* Initialisations communes
*------------------------------------------------------
INIT3
* Initialisation adresse du fichier .sd pour CMD18
LDX <$8E octets poids fort adresse
STX CMD18+1 stockage pour commande CMD18
LDX <$90 octets poids faible adresse
STX CMD18+3 stockage pour commande CMD18
TFR DP,B valeur actuelle de DP
ADDB #$87 $A7 pour MO et $E7 pour TO
TFR B,DP initialisation DP
* Initialisation PIA pour SDMOTO
LDA <$CE lecture registre de controle A
ANDA #$FB raz bit 2
STA <$CE selection DDRA
LDB #$60 set bits 5 et 6
STB <$CC bits MOSI et CLOCK en sortie
ORA #$04 set b2
STA <$CE selection PA
* Initialisation CNA en sortie
LDA <$CF lecture registre de controle B
ANDA #$FB raz bit 2
STA <$CF selection DDRB
LDB #$3F set bits 0-5
STB <$CD bits CNA en sortie
ORA #$04 set b2
STA <$CF selection PB
*-------------------------------------------------------
* Lancement de la commande CMD18 et saut de quatre blocs
*-------------------------------------------------------
READ
LDU #CMD18 adresse commande CMD18
JSR $A028 EXCMD = execution commande
* READ+4 modifie en $E028 pour TO
LBSR SAUT lecture bloc (secteur de boot)
LBSR SAUT lecture bloc (secteur sdplay)
LBSR SAUT lecture bloc (secteur sdplay)
LBSR SAUT lecture bloc (secteur sdplay)
*------------------------------------------------------
* Affichage de l'image
*------------------------------------------------------
DISPLAY
LDU #$0000 adresse memoire video
LDY #$0010 nombre de blocs a lire
DISPL1
LBSR RBYTE lecture d'un octet
CMPA #$FE test debut de bloc
BNE DISPL1 attente debut de bloc
LDX #$0200 nombre d'octets a lire
DISPL2
LBSR RBYTE lecture d'un octet
STA ,U+ affichage
LEAX -1,X decrementation compteur
BNE DISPL2 lecture octet suivant
LBSR RBYTE lecture CRC1
LBSR RBYTE lecture CRC2
LEAY -1,Y decrementation compteur
BNE DISPL1 lecture bloc suivant
LDA ,-U dernier octet image
BEQ PLAY jouer si nul, arret sinon
*------------------------------------------------------
* ARRETER LA LECTURE ET RECOMMENCER
*------------------------------------------------------
ARRET
LDU #CMD12 adresse commande CMD12
JSR $A028 EXCMD = execution commande CMD12
* ARRET+4 modifie en $E028 pour TO
LDB #$10 compteur pour temporisation
ARRET1
LDX #$0000 compteur pour temporisation
ARRET2
LEAX -1,X decrementation
BNE ARRET2 boucle de temporisation
DECB decrementation
BNE ARRET1 boucle de temporisation
BRA READ recommencer la lecture
*------------------------------------------------------
* Joue 2 octets et recupere 1 bit dans le premier
* avec test de fin sur le bit 7 de l'echantillon
* periode = 179 microsecondes
* decompte des cycles avec le BSR et le RTS :
* avant le premier echantillon : 7+158=165
* entre les deux echantillons : 4+2+6+6+158+3=179
* apres le deuxieme echantillon : 4+5+5=14
* 14(apres le deuxieme)+165(avant le prochain)=179
*------------------------------------------------------
PLAY2
* premier octet 158+4+2+6+6=176
LBSR RBYTE lecture echantillon (158)
STA <$CD envoi de l'echantillon (4)
ASLA b7 dans carry (2)
ROL ,X stockage b7 (6)
NOP temporisation (2)
NOP temporisation (2)
NOP temporisation (2)
* deuxieme octet 158+3+4+5+5=175 (+7 pour BSR)
LBSR RBYTE lecture echantillon (158)
* test de fin
BPL PLAY21 pas d'octet fin de fichier (3)
PSHS A sauvegarde de l'echantillon
LDD #FIN adresse routine de FIN
SUBD #CRC2 adresse lecture CRC2
STB CRC1+1 pour arreter de jouer la musique
PULS A restauration de l'echantillon
PLAY21
STA <$CD envoi de l'echantillon (4)
LBRN $FFFF temporisation (5)
RTS retour (5)
*------------------------------------------------------
* Lecture de la musique
*------------------------------------------------------
PLAY
LEAU $E000,U adresse ecran = fin - $2000
LEAX $23,U adresse haute buffer ecran
LDB #$20 compteur octets supplementaires
PSHS B empilage compteur
*------------------------------------------------------
* Attente debut de bloc
*------------------------------------------------------
PLAY0
LBSR RBYTE lecture d'un octet
CMPA #$FE test debut de bloc
BNE PLAY0 attente debut de bloc
*------------------------------------------------------
* Boucle de lecture d'un bloc
*------------------------------------------------------
PLAY1
BSR PLAY2 joue 2 octets, stocke 1 bit
BSR PLAY2 joue 2 octets, stocke 1 bit
BSR PLAY2 joue 2 octets, stocke 1 bit
BSR PLAY2 joue 2 octets, stocke 1 bit
BSR PLAY2 joue 2 octets, stocke 1 bit
BSR PLAY2 joue 2 octets, stocke 1 bit
BSR PLAY2 joue 2 octets, stocke 1 bit
* joue 2 octets, complete l'octet supplementaire
LBRN $FFFF temporisation (5)
NOP temporisation (2)
LBSR RBYTE lecture echantillon (158)
STA <$CD envoi de l'echantillon (4)
ASLA b7 dans carry (2)
ROL ,X stockage b7 (6)
LEAX -1,X modifie pointeur octet sup (5)
NOP temporisation (2)
NOP temporisation (2)
LBSR RBYTE lecture echantillon (158)
STA <$CD envoi de l'echantillon (4)
DEC ,S compteur octets supplement. (6)
BNE PLAY1 boucle suivante (3)
*------------------------------------------------------
* Lecture des octets de CRC
*------------------------------------------------------
* premier octet CRC 158+3+5+4+5+2+2=179
LBSR RBYTE lecture octet CRC (158)
LDD #$0000 initialise A pour test $FE (3)
LDB 1,X chargement echantillon sup. (5)
STB <$CD envoi de l'echantillon 1 (4)
LEAX 2,X incremente pointeur oct sup (5)
NOP temporisation (2)
CRC1
BRA CRC2 remplace par BRA FIN (2)
* deuxieme octet CRC 158+2+6+4=170
CRC2
LBSR RBYTE lecture octet CRC (158)
CLRA initialise A pour test $FE (2)
LDB ,X+ chargement echantillon sup. (6)
STB <$CD envoi de l'echantillon 2 (4)
*------------------------------------------------------
* Lecture des octets inter-blocs pendant l'envoi
* des echantillons supplementaires
*------------------------------------------------------
* Echantillon supplementaire n°3 (2+4+161+6+2+4=179)
LDB #$20 compteur echantillons sup. (2)
STB ,S stocke le compteur (4)
BSR INTER lecture octet inter-blocs (161)
LDB ,X+ chargement echantillon (6)
NOP temporisation (2)
STB <$CD envoi de l'echantillon 3 (4)
* Echantillons supplementaires 4 a 32
LDY #$001D compteur pour 29 boucles (4)
NOP temporisation (2)
NOP temporisation (2)
* La boucle SUPP s'execute en 161+6+4+5+3=179 cycles
SUPP
BSR INTER lecture octet inter-blocs (161)
LDB ,X+ chargement echantillon (6)
STB <$CD envoi de l'echantillon (4)
LEAY -1,Y decremente le compteur (5)
BNE SUPP nouvelle boucle (3)
* Preparation de la lecture du bloc suivant
LEAX -1,X retablit pointeur (5)
CMPA #$FE test début de bloc (2)
BEQ PLAY1 traitement du bloc suivant (3)
BRA PLAY0 attente octet $FE (3)
*------------------------------------------------------
* LIRE UN OCTET INTER-BLOCS SI NECESSAIRE
* Total avec BSR : 7+2+3+144+5=161
*------------------------------------------------------
INTER
CMPA #$FE test debut de bloc (2)
BNE RBYTE lecture octet inter-blocs (3)
*------------------------------------------------------
* Temporisation 149 cycles (equivalent RBYTE + RTS)
* boucle de temporisation : 28x5=140 cycles
* total : 2+140+2+5= 149
*------------------------------------------------------
LDB #$1C compteur de boucles (2)
TEMPO
DECB decremente le compteur (2)
BNE TEMPO nouvelle boucle (3)
NOP temporisation (2)
RTS (5)
*------------------------------------------------------
* Fin de la sequence de musique
*------------------------------------------------------
FIN
LBSR RBYTE lecture deuxieme octet de CRC
CLRB supprimer le branchement
STB CRC1+1 pour arret en fin de musique
LEAS 1,S retablissement pointeur de pile
LBRA DISPLAY affichage image suivante
*------------------------------------------------------
* Saut de 512 octets
*------------------------------------------------------
SAUT
BSR RBYTE lecture octet
CMPA #$FE comparaison avec $FE
BNE SAUT attente debut secteur
LDX #$0200 initialisation compteur
SAUT1
BSR RBYTE lecture d'un octet
LEAX -1,X decrementation compteur
BNE SAUT1 nouvelle lecture
BSR RBYTE lecture CRC1
BSR RBYTE lecture CRC2
RTS retour
*------------------------------------------------------
* LECTURE D'UN OCTET AVEC SDMOTO
* Le registre B n'est pas preserve
* Valeur de l'octet dans le registre A en sortie
*------------------------------------------------------
RBYTE
* premier bit
LDB #$7F Valeur pour test bit 7 (2)
CMPB <$CC PA b7 (bit lu) -> carry (4)
STB <$CC clock high, di high (4)
LDB #$5F clear bit 5 (2)
STB <$CC clock low, di high (4)
ROLA C (bit lu) -> b0 reg A (2)
* deuxieme bit
LDB #$7F Valeur pour test bit 7 (2)
CMPB <$CC PA b7 (bit lu) -> carry (4)
STB <$CC clock high, di high (4)
LDB #$5F clear bit 5 (2)
STB <$CC clock low, di high (4)
ROLA C (bit lu) -> b0 reg A (2)
* troisieme bit
LDB #$7F Valeur pour test bit 7 (2)
CMPB <$CC PA b7 (bit lu) -> carry (4)
STB <$CC clock high, di high (4)
LDB #$5F clear bit 5 (2)
STB <$CC clock low, di high (4)
ROLA C (bit lu) -> b0 reg A (2)
* quatrieme bit
LDB #$7F Valeur pour test bit 7 (2)
CMPB <$CC PA b7 (bit lu) -> carry (4)
STB <$CC clock high, di high (4)
LDB #$5F clear bit 5 (2)
STB <$CC clock low, di high (4)
ROLA C (bit lu) -> b0 reg A (2)
* cinquieme bit
LDB #$7F Valeur pour test bit 7 (2)
CMPB <$CC PA b7 (bit lu) -> carry (4)
STB <$CC clock high, di high (4)
LDB #$5F clear bit 5 (2)
STB <$CC clock low, di high (4)
ROLA C (bit lu) -> b0 reg A (2)
* sixieme bit
LDB #$7F Valeur pour test bit 7 (2)
CMPB <$CC PA b7 (bit lu) -> carry (4)
STB <$CC clock high, di high (4)
LDB #$5F clear bit 5 (2)
STB <$CC clock low, di high (4)
ROLA C (bit lu) -> b0 reg A (2)
* septieme bit
LDB #$7F Valeur pour test bit 7 (2)
CMPB <$CC PA b7 (bit lu) -> carry (4)
STB <$CC clock high, di high (4)
LDB #$5F clear bit 5 (2)
STB <$CC clock low, di high (4)
ROLA C (bit lu) -> b0 reg A (2)
* huitieme bit
LDB #$7F Valeur pour test bit 7 (2)
CMPB <$CC PA b7 (bit lu) -> carry (4)
STB <$CC clock high, di high (4)
LDB #$5F clear bit 5 (2)
STB <$CC clock low, di high (4)
ROLA C (bit lu) -> b0 reg A (2)
*
RTS retour (octet dans A) (5)
* longueur totale avec BSR: 7 + 18*8 + 5 = 156
* avec LBSR: 9 + 18*8 + 5 = 158
*------------------------------------------------------
* LECTURE D'UN OCTET AVEC SDMO
* Le registre B n'est pas preserve
* Valeur de l'octet dans le registre A en sortie
*------------------------------------------------------
RBYTEMO
* premier bit
LDB #$7F Valeur pour test bit 7 (2)
STB <$C2 clock high (4)
CMPB <$C0 PA b7 (bit lu) -> carry (4)
LDB #$36 clear bit 3 (2)
STB <$C2 clock low (4)
ROLA C (bit lu) -> b0 reg A (2)
* deuxieme bit
LDB #$7F Valeur pour test bit 7 (2)
STB <$C2 clock high (4)
CMPB <$C0 PA b7 (bit lu) -> carry (4)
LDB #$36 clear bit 3 (2)
STB <$C2 clock low (4)
ROLA C (bit lu) -> b0 reg A (2)
* troisieme bit
LDB #$7F Valeur pour test bit 7 (2)
STB <$C2 clock high (4)
CMPB <$C0 PA b7 (bit lu) -> carry (4)
LDB #$36 clear bit 3 (2)
STB <$C2 clock low (4)
ROLA C (bit lu) -> b0 reg A (2)
* quatrieme bit
LDB #$7F Valeur pour test bit 7 (2)
STB <$C2 clock high (4)
CMPB <$C0 PA b7 (bit lu) -> carry (4)
LDB #$36 clear bit 3 (2)
STB <$C2 clock low (4)
ROLA C (bit lu) -> b0 reg A (2)
* cinquieme bit
LDB #$7F Valeur pour test bit 7 (2)
STB <$C2 clock high (4)
CMPB <$C0 PA b7 (bit lu) -> carry (4)
LDB #$36 clear bit 3 (2)
STB <$C2 clock low (4)
ROLA C (bit lu) -> b0 reg A (2)
* sixieme bit
LDB #$7F Valeur pour test bit 7 (2)
STB <$C2 clock high (4)
CMPB <$C0 PA b7 (bit lu) -> carry (4)
LDB #$36 clear bit 3 (2)
STB <$C2 clock low (4)
ROLA C (bit lu) -> b0 reg A (2)
* septieme bit
LDB #$7F Valeur pour test bit 7 (2)
STB <$C2 clock high (4)
CMPB <$C0 PA b7 (bit lu) -> carry (4)
LDB #$36 clear bit 3 (2)
STB <$C2 clock low (4)
ROLA C (bit lu) -> b0 reg A (2)
* huitieme bit
LDB #$7F Valeur pour test bit 7 (2)
STB <$C2 clock high (4)
CMPB <$C0 PA b7 (bit lu) -> carry (4)
LDB #$36 clear bit 3 (2)
STB <$C2 clock low (4)
ROLA C (bit lu) -> b0 reg A (2)
*
RTS retour (octet dans A) (5)
* longueur totale avec BSR: 7 + 18*8 + 5 = 156
* avec LBSR: 9 + 18*8 + 5 = 158
*------------------------------------------------------
* REMPLACEMENT DE LA ROUTINE RBYTE POUR SDMOTO
* PAR LA ROUTINE RBYTEMO POUR SDMO
*------------------------------------------------------
RBSDMO
LDY #RBYTEMO adresse routine SDMO
LDX #RBYTE adresse routine RBYTE
RBSDMO1
LDB ,Y+ lecture routine SDMO
STB ,X+ ecriture routine RBYTE
CMPX #RBYTEMO test de fin
BNE RBSDMO1 nouvelle boucle
RTS retour
ORG $9FFF
FCB $00 pour remplir 3 secteurs complets
END
Code : Tout sélectionner
*======================================
* Secteur de boot (secteur 1)
* Charge secteurs 2, 3 et 4 en $9D00
* Lance l'execution en $9D00
*======================================
ORG $2200
FDB $E082 $207E (BRA DEBUT) crypte
ORG $227F
FCB $F3 checksum
DEBUT
LDB #$02 code operation lecture
STB <$48
LDX #$0000 unite 0 piste 0
STX <$4A
* secteur 2
LDA #$02 secteur 2
STA <$4C
LDX #$9D00 adresse buffer
STX <$4F
LBSR $A004
* SWI
* FCB $26 lecture secteur
* secteur 3
LDA #$03 secteur 3
STA <$4C
LDX #$9E00 adresse buffer
STX <$4F
LBSR $A004
* SWI
* FCB $26 lecture secteur
* secteur 4
LDA #$04 secteur 4
STA <$4C
LDX #$9F00 adresse buffer
STX <$4F
LBSR $A004
* SWI
* FCB $26 lecture secteur
JMP $9D00 execution sdplay
ORG $22FF pour completer le secteur
FCB $00
END