; ########## MiniCaracteres 4x6
; ########## Le 26/02/2019 Programmation Philippe Moulin
; ########## Revision 1.2 Le 26/02/2019 (RSX et Sous routines)
;; MEMORY &9FFF: CALL &A22E (#A000 - #A272)
; ########## ########## ; Pointeur des Caracteres, des Couleurs, du Curseur etc...
Couleur EQU #A000 ; #A005 ; 6 Emplacements pour la couleur (3 Encres et 3 Papiers)
Curseur EQU #A006 ; #A007 ; 2 Emplacements pour les curseur (Colonne et Ligne)
Pile EQU #A008 ; #A009 ; 2 Emplacements pour une pile provisoire
CouleurCodee EQU #A00A ; #A019 ; 16 Emplacements pour les couleurs codees
Caractere EQU #A01A ; #A0BB ; 162 Emplacements pour 54 Caracteres de 3 octets
; ########## ########## ; Sous routine
CompareCaractere EQU #A0BC ; #A0E8
AfficheCaractere EQU #A0E8 ; #A12B
; ########## ########## ; Routine RSX Fonte, Curseur, Couleur, DefCar
RSXCURSEUR EQU #A12C ; #A14B
RSXENCRE EQU #A14C ; #A176
RSXPAPIER EQU #A151 ; RSXENCRE + 5 octets (3 pour faire pointer HL) et (2 pour faire un petit bond)
RSXDEFCAR EQU #A177 ; #A1C4
RSXFONTE EQU #A1C5 ; #A211
RSXROULE EQU #A212 ; #A22D
; ########## ########## ; Definition des encres, du curseur et des couleurs codees de SUGAR
ORG Couleur
DB #45, #00, #05, #55, #15, #11
ORG Curseur
DB 199, 0 ; (LIGNE, COLONNE
ORG CouleurCodee
;# 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
DB #00,#40,#04,#44,#10,#50,#14,#54,#01,#41,#05,#45,#11,#51,#15,#55
; ########## ########## ########## ########## ; SOUS ROUTINE CompareCaractere
; CE > A contient le code ascii du caractere a comparer
; CS > HL Contient l'adresse de la table 6x6
; CS > Si le caractere n'a pas pu etre trouve, A = 0 et HL Pointe sur le caractere " " (ESPACE)
ORG CompareCaractere
; Ajuster les minuscules en majuscules si utile
CP A, #61 ; <"a"
JR C, Caractere_az ; Plus petit que "a", donc on poursuit les testes
SUB A, #20 ; sinon on enleve 32 pour reajuster
Caractere_az
; Sortir si on est au dessus du 'Z'
CP A, #5B ; >"Z" Remplacer le caractere par un " "
JR NC, Fonte6x6_Erreur ; En sortant par la porte ERREUR
; Eliminer les caracteres en dessous de 32
CP A, #20 ; <" " (ESPACE) si le code ascii est <32
JR C, Fonte6x6_Erreur ; On fait pareil que ci-dessus
; Ajuster les valeurs pour que 32 corresponde au caractere zero de notre table
SUB a, #20 ; Notre table de 6x6 commence a zero
; Rechercher les mauvais caracteres
CP A, 2 ; Si c'est un " " ou un "!" on peux sortir
JR C, Fonte6x6_TrouveOK
CP A, 7 ; "'" ; Mais si on est entre "!" et "'"
JR C, Fonte6x6_Erreur ; On remplace par un " " en sortant
; Reajuster les valeurs pour que le caractere "'" corresponde au numero 2 de notre table
SUB A, 5 ; La table est reajutere, J'ai plus de salive ;)
JR Fonte6x6_TrouveOK ; Et on termine les testes
; Les mauvais caracteres passent par ici
Fonte6x6_Erreur
LD A,0 ; Code erreur remplace la valeur par un " "
Fonte6x6_TrouveOK
; Il faut faire pointer HL sur le caractere qui est dans A
LD HL, Caractere ; HL Pointe sur le debut de la table 6x6
OR A ; Si A=0, HL correspond au debut, alors on sort
JR Z, Fonte6x6_CalculTable
LD DE, 3 ; Sinon..., il on ajoute 3 octets par caractere
Fonte6x6_TableSuivant
ADD HL, DE ; On continu tant que A > 0
DEC A ; Arrivee au "Z" A sera egal a ZERO
; OR A
JR NZ, Fonte6x6_TableSuivant
Fonte6x6_CalculTable
RET
; ########## ########## ########## ########## ; Sous routine Affichage d'un caractere
; CE> H=Colonne L=Ligne DE=Table 6x6 du caractere a afficher IY doit pointer sur les couleurs
; CS> Les registres sont detruits
ORG AfficheCaractere
PUSH DE
LD D, 0 ; On transforme les coordonnees pour les adapter
LD E, H ; DE = Colonne
LD H, 0 ; HL = Ligne
CALL #BC1D ; Vecteur systeme (Adresse ecran)
POP DE
LD A, 3 ; 3 Octets par caractere a decoder, c'est parti
TroisFoisDeuxLignes
PUSH AF
PUSH DE
LD A, (DE) ; A contient l' octet de 8 bits a traiter
LD C, A ; Parce-que LD C, (DE) n'est pas possible SNIF
LD B, 2 ; 2 Lignes par octets
FinirLesHuitBits
LD E, 2 ; 2 octets sur l'ecran mode 0 = 4 bits
DeuxOctetsParLigne
LD A, (IY + 0) ; A contient la couleur du papier de droite
LD D, A ; D contient celui du papier gauche
SLA C ; Pixel de gauche, Chaque bit est teste
JR C, OnGardeLePapierDeGauche
LD D, (IY + 3) ; Le point gauche est allume, D contient la couleur de l'encre
OnGardeLePapierDeGauche
SLA C ; On regarde si le bit est allume (=1)
JR C, OnGardeLePapierDeDroite ; Pour le cote droit cette fois
LD A, (IY + 3)
OnGardeLePapierDeDroite
SLA D ; On ajuste la couleur (Pour la gauche seulement)
ADD A, D ; A contient l'octet (point Gauche et droit)
; OR (HL)=#B6 --- AND (HL)=#A6 --- XOR (HL)=#AE --- NOP=#00 ---> (POKE &A111)
NOP ;XOR (HL)
LD (HL), A ; Alors on l'affiche fierement sur l'ecran
INC HL ; suivant S.V.P.
DEC E
JR NZ, DeuxOctetsParLigne
; On calcul l'emplacement pour descendre d'une ligne ; HL sera incremente d'une ligne - 2 octets
LD DE, #800-2 ; Quand Quasar nous livre la reponse! Merci
ADD HL, DE ; On descent d'une ligne
JR NC, PasserALaLigneSuivante ; Mais si il y a debordement
LD DE,#C000+80 ; On corrige le tire
ADD HL, DE
PasserALaLigneSuivante
DJNZ, FinirLesHuitBits
INC IY ; On change de couleur papier et encre toutes les 2 lignes
POP DE
INC DE ; 3 octets par caractere, octet suivant
POP AF
DEC A
JR NZ, TroisFoisDeuxLignes
RET
; ########## ########## ########## ########## ; RSX CURSEUR
; APPEL > CURSEUR, Colonne, Ligne
; Definit la position du curseur relatif au coin superieur gauche de l'ecran
; CE > Colonne doit etre >=0 et <=39
; CE > Ligne Doit etre >=0 et <=32
ORG RSXCURSEUR
CP A, 2 ; Si le nombre de parametres envoye est different de 2
RET NZ ; On renvoie au basic
LD A, (IX + 2) ; A = Colonne
CP A , 39
RET NC ; Colonne doit etre < 40 sinon on renvoie au basic
ADD A, A: ADD A, A ; On ajuste la valeur pour le mode 0
LD H, A
LD A, E ; A = Ligne >>> E=Dernier parametre donc A = Ligne
CP A, 33
RET NC ; Ligne doit etre < 33 sinon on renvoie au basic
ADD A, A ; (x2) Il faut multiplier sa valeur par 6. On multiplie par 2
ADD A, E ; (x3) On Ajoute sa propre valeur, donc trois fois
ADD A, A ; (x6) Et pour six fois, on multiplie a nouveau par deux
LD L, A ; Pause cafe
LD A, 199 ; et on inverse la position... pour que les coordonnees 0, 0
SUB A, L ; correspondent en Haut et a Gauche de l'ecran
LD L, A
LD (Curseur), HL ; On inscrit les coordonnees a l'abris des poussieres
RET
; ########## ########## ########## ########## ; RSX ENCRE et RSX PAPIER
; APPEL > ENCRE, Couleur 1, [Couleur 2], [Couleur 3]
; APPEL > PAPIER, Couleur 1, [Couleur 2], [Couleur 3]
; CE > Couleur doit etre >=0 et <=15
; CE > Si [Couleur 2] ou [Couleur 3] ne sont pas definies, elles gardent leurs anciennes valeurs
ORG RSXENCRE
LD HL, Couleur ; HL est positionne sur l' emplacement des encres
JR PourLePapier ; On saute pour l'instruction PAPIER
ORG RSXPAPIER
LD HL, Couleur + 3 ; HL pointe sur l'emplacement dus papiers
PourLePapier
CP 4 ; On regarde si on a au moins de 3 parametres
RET NC ; Sinon on sort sans bouder vers le basic
OR A ; Et si il n'y a pas de parametre
RET Z ; On quitte le navire aussi
; Il faut se positionner sur le parametre le plus a gauche de l'instruction
LD B, 0
LD C, A ; C = nombre de paramatre
DEC C ; - 1
ADD IX, BC
ADD IX, BC ; IX est positionne sur le parametre desire
LD B, A ; B contient le nombres de parametre
Couleur_Encre
LD A, (IX + 0) ; A = au contenu du parametre
CP 16 ; Si >= 16, il n'y a que 16 couleurs en MODE 0
RET NC ; On ne reste pas, Faut pas pousser non plus
; Les couleurs sont codees et il faut chercher la correspondance avec les couleurs du MODE 0
LD DE, CouleurCodee ; DE pointe sur la table des couleurs codees
ADD A, E ; A Contient la couleur demandee
LD E, A ; DE Pointe sur la correspondance de la couleur demandee
LD A, (DE) ; A est = a la couleur codee de MODE 0
LD (HL), A ; On l'incrit simplement dans HL
INC HL ; On passe a la couleur suivant
DEC IX
DEC IX ; Et aussi pour les parametres
DJNZ Couleur_Encre ; On recommence tant qu'il y a des parametres
RET
; ########## ########## ########## ########## ; RSX DEFCAR
; APPEL > DEFCAR, a$, Val1, Val2, Val3, val4, val5, val6
; APPEL > DEFCAR, a$, ValP1, ValP2, ValP3
; Redefinit le caractere contenu dans a$
; CE > a$ represente le caractere que l'on souhaite modifier
; CE > Val1, Val2, ..., Val6 representent les valeurs de (0 a 15) pour chacune des 6 lignes
; CE > ValP1, ValP2, ValP3 representent les valeurs de (0 a 255) pour 2 lignes a la fois
; Fonctionne un peu comme pour l'instruction SYMBOL du basic
; Exemple pour redefinir le caractere "A" en valeurs Binaire
; DEFCAR, "A", &X0010, &X0101, &X0101, &X0111, &X0101, &X0101
; Ou en valeurs decimal
; DEFCAR, "A", 2, 5, 5, 7, 5, 5
; DEFCAR, "A", &X00100101, &X01010111, &X01010101 est identique aux exemples ci-dessus
ORG RSXDEFCAR
; On va directement chercher le caractere contenu dans a$
; A = au nombre de parametre, et IX pointe sur le dernier parametre
; On remonte au 1er parametre
LD B, 0
LD C, A ; C= Nombre de parametre
DEC C ; Moins un
ADD IX, BC
ADD IX, BC
LD B, C ; B = Nombre de parametre - 1
LD H, (IX + 1) ; On va recuperer l'adresse de la chaine a$
LD L, (IX + 0)
LD A, (HL) ; A contient le nombre de caractere contenu dans la chaine
OR A ; Si la chaine est vide... Retour vers le Basic
RET Z ; Si elle est trop longue, on prendra que le premier caractere
INC HL
LD E, (HL)
INC HL
LD D, (HL) ; DE Pointe sur le 1er Caractere de la chaine
LD A, (DE)
DEC IX ; On positionne IX juste apres le parametre du caractere
DEC IX ; Car on part dans le sens contraire des parametres (G vers D)
; Maintenant on va recupere le caractere correspondant a la table de 6x6
CALL CompareCaractere ;RAPPEL; tous les caracteres non admis sont remplacer par le caractere " "
; HL pointe sur le caracrtere de la table
LD A, B ; A contient le nombre de paramettres - 1
CP A, 3
JR NZ, DechiffrerLesBinaires ; A doit etre egal a 3 ou 6
ModifierMatriceParTrois
LD A, (IX + 0) ; A contient le parametre apres a$
LD (HL), A ; On l'inscrit au bon endroit
INC HL
DEC IX ; On passe du parametre de la gauche vers la droite
DEC IX
DJNZ, ModifierMatriceParTrois
RET
; Si on a envoyer des valeurs sur 4 bits (&Xxxxx, &Xxxxx, etc... ...)
DechiffrerLesBinaires
CP A, 6 ; Si on s'est trompe dans le nombre de parametre
RET NZ ; Il faudra sortir et retourner au basic
ModifierMatriceParSix
LD A, (IX + 0) ; A = a la valeur de gauche de l'octet
ADD A, A: ADD A, A: ADD A, A: ADD A, A ; Il faut le multiplier par 16
DEC IX
DEC IX
LD C, (IX + 0) ; C = a la valeur de droite
ADD A, C ; A = un octet a inscrire dans HL
LD (HL), A
INC HL
DEC IX
DEC IX ; On passe au parametre suivant
DJNZ, ModifierMatriceParSix ; jusqu'a ce qu'il ni en ai plus un seul
RET
; ########## ########## ########## ########## ; RSX FONTE
; APPEL > FONTE, a$
; Affiche la chaine a$ a la position du curseur definie par le RSX CURSEUR
ORG RSXFONTE
CP A, 1 ; Si le nombre de parametre envoye est <> 1... Retour Basic
RET NZ
LD H, (IX + 1) ; On va recuperer l'adresse de la chaine a$
LD L, (IX + 0)
LD A, (HL)
OR A ; Si la chaine est vide... Retour vers le Basic
RET Z
INC HL ; HL contient l'adresse de la chaine a$
LD E, (HL)
INC HL
LD D, (HL) ; DE Pointe sur le 1er Caractere de la chaine
LD B, A ; Et B = Longeur de la chaine
Fonte6x6_UnParUn
PUSH BC ; On sauvegarde la longeur de la chaine
PUSH DE ; Ainsi que l'endroit ou elle est stockee
LD A,(DE) ; A contient le code ascii du caractere
CALL CompareCaractere ; HL pointe sur le caractere de la table 6x6
EX HL, DE ; DE = Table du caractere
LD HL, (Curseur) ; HL = Position du caractere
LD IY, Couleur ; IY servira de pointeur pour les encres
PUSH HL
CALL AfficheCaractere ; On affiche le caractere
POP HL
LD A, H
CP A, 153 ; Et on incremente la colonne
JR C, Fonte6x6_ColPlusUn
LD A, L
CP A, 11 ; Ou la ligne si fin de colonne
JR NC, Fonte6x6_ResteLig
LD H,0
LD L, 199 ; Si on sort de l'ecran (H=0 L=199)
JP Fonte6x6_LigPlusUn
Fonte6x6_ResteLig
LD H, 6 ; C'est le pas entre chaque ligne
SUB A, H
LD L, A
LD H, 0
JP Fonte6x6_LigPlusUn
Fonte6x6_ColPlusUn
INC H
INC H
INC H
INC H ; Il y a peut-etre plus simple ?
Fonte6x6_LigPlusUn
LD (Curseur), HL ; On inscrit les nouvelles coordonnees
POP DE ; Puis on passe au caractere suivant
INC DE
POP BC ; Jusqu'au dernier
DEC B
JP NZ, Fonte6x6_UnParUn
; DJNZ Fonte6x6_UnParUn
RET
; ########## ########## ########## ########## ; RSX ROULE
; APPEL > ROULE, a$
; Deplace la chaine a$ de un caractere vers la gauche. Le premier caractere remplacera le dernier
;; EXEMPLE : a$="0123456789": ROULE, a$: Print a$
;; RESULTAT : 1234567890
ORG RSXROULE
CP A, 1 ; Si le nombre de parametre envoye est <> 1... Retour Basic
RET NZ
LD H, (IX + 1) ; On va recuperer l'adresse de la chaine a$
LD L, (IX + 0)
LD A, (HL)
OR A ; Si la chaine est vide... Retour vers le Basic
RET Z
INC HL ; HL contient l'adresse de la chaine a$
LD E, (HL)
INC HL
LD D, (HL) ; DE Pointe sur le 1er Caractere de la chaine
LD C, A ; Et C = Longeur de la chaine
DEC C
LD B, 0
LD A, (DE)
PUSH DE
POP HL
INC HL
LDIR
LD (DE), A
RET
; ########## ########## ########## ########## ; DEFINIR LES RSX
; La routine qui fixe les RSX est &BCD1
; CE > BC pointe vers deux octets contenant l'adresse ou debute les noms des RSX
; CE > HL pointe vers 4 octets de libre
; CS >
ORG #A22E ;FIXERSX
LD HL, OctetsReserves
LD BC, AdresseReserve
JP #BCD1
AdresseReserve
DW NomDesRSX ; L'adresse des noms est contenu ici
; ICI ON INDIQUE LES SAUTS DE CHAQUE ROUTINES RSX
JP RSXCURSEUR
JP RSXENCRE
JP RSXPAPIER
JP RSXDEFCAR
JP RSXFONTE
JP RSXROULE
RET
; Reserver 4 octets pour la routine &BCD1 et 2 de plus pour l'adresse ou sont stockes les noms
OctetsReserves
DB 00, 00, 00, 00
NomDesRSX
STR "CURSEUR" ; WinApe Ajoute automatiquement #80 au dernier caractere du nom
STR "ENCRE"
STR "PAPIER"
STR "DEFCAR"
STR "FONTE"
STR "ROULE"
; Fin