zmac file_name
trs80gp -ld -m3 -vs zout/file_name ; -ld = LDOS, -vs = Sharp Display
Z:\0 - Documentation\Réseau et équipement maison\TRS-80\ASM-Tool-Chain>
Virtual Disk Utilities – Ira Goldklang’s TRS-80 Revived Site (TRSTools)
Les fichiers images de type IMD doivent être convertis en format HFE avec l’application HxCFloppyEmulator.
; zmac file_name ; trs80gp -ld -m3 -vs zout/file_name ; -ld = LDOS, -vs = Sharp Display ORG 7000H @DSPLY EQU 4467H ;LDOS 5.1/MOD3 - pg 6-66 @EXIT EQU 402DH ;pg 6-60 @KEY EQU 0049H ; @TIME EQU 3036H ;446DH ; 3036H PG 6-58 @DATE EQU 3033H VIDEO EQU 3C00H VSIZE EQU 1024 ENTER EQU 0DH TEXT DEFB 'TIME AND DATE VIA SYS-CALL @TIME, @DATE', ENTER BUFFER DEFB ' ', ENTER MAIN: LD DE,VSIZE LD HL, VIDEO LOOP: LD A,'X' LD (HL),A INC HL DEC DE LD A,D OR E JP NZ,LOOP CALL @KEY ; WAIT UNTIL KEY PRESSED LD HL,TEXT CALL @DSPLY ; GET TIME AND DISPLAY IT LD HL,BUFFER CALL @TIME LD HL,BUFFER CALL @DSPLY ; GET DATE AND DISPLAY IT LD HL,BUFFER CALL @DATE LD HL,BUFFER CALL @DSPLY CALL @KEY ; WAIT UNTIL KEY PRESSED CALL @EXIT END MAIN
Un autre exemple – Compter jusqu’à 0xFFFF
; Auteur: Alain Boudreault (VE2CUY) ; Date: 2025.08.10 ; Description: Compter de 0 à 255 et afficher en DEC et de 0 à 0xFFFF en HEX ; Assembleur: zmac ; Emulateur: trs80gp ; -------------------------------------------------------------------------- ; zmac file_name ; trs80gp -ld -m3 -vs zout/file_name ; -ld = LDOS, -vs = Sharp Display ; -------------------------------------------------------------------------- ORG 7000H @DSPLY EQU 4467H ;LDOS 5.1/MOD3 - pg 6-66 @EXIT EQU 402DH ;pg 6-60 @KEY EQU 0049H ; @TIME EQU 3036H ;446DH ; 3036H PG 6-58 @DATE EQU 3033H VIDEO EQU 3C00H VSIZE EQU 1024 ENTER EQU 0DH LINE_FEED EQU 0AH AUTEUR DEFB LINE_FEED DEFB '---------------------------------------------------', LINE_FEED DEFB 'Programme: counter/cmd, par VE2CUY 2025.08.20', LINE_FEED DEFB 'Ce programme utilise des sous-routines de LDOS 5.1', LINE_FEED DEFB '---------------------------------------------------', ENTER MSG1 DEFB 'Compter de 0 a 255 en DEC, Enter pour commencer ...', ENTER MSG2 DEFB LINE_FEED, LINE_FEED DEFB '---------------------------------------------------', LINE_FEED DEFB 'Compter de 0 a 0xFFFF en HEX, Enter pour commencer:', LINE_FEED DEFB '---------------------------------------------------', ENTER BUFFER DEFB ' ', ENTER TEXTE DEFS 7 ; Buffer for number string' ; --------------------------------------------------------------------- MAIN: LD HL,AUTEUR CALL @DSPLY LD HL,MSG1 CALL @DSPLY CALL @KEY ; WAIT UNTIL KEY PRESSED ; Afficher les nombres de 0 à 255 Start: LD IX, 0 ; IX = compteur de 0 à 255 boucle: LD A, IXl ; Charger la valeur du compteur dans A LD HL,TEXTE CALL NumberToString ; Convert number in A to string at HL LD HL,TEXTE ; Now HL points to the end of the string, we need to backtrack to the start CALL @DSPLY ; Display the string INC IX LD A, IXl CP 0 ; quand IXl revient à 0, on a atteint 256 JR NZ, boucle ; ### FIN de : ; Afficher les nombres de 0 à 255 ; Afficher les nombres de 0 à 0xFFFF en HEX LD HL,MSG2 CALL @DSPLY CALL @KEY ; WAIT UNTIL KEY PRESSED LD IX, 0 ; IX = compteur de 0 à 255 LD DE, 0 boucle2: LD HL,TEXTE CALL NumberToHex ; Convert number in DE to string at HL PUSH DE ; ATTENTION, @DSPLY va modifier DE LD HL,TEXTE ; Now HL points to the end of the string, we need to backtrack to the start CALL @DSPLY ; Display the string POP DE INC DE INC IX ; Vérifier si IX == 0 ; Le Z80 ne permet pas de faire CP IX, 0 directement car ; il ne supporte pas les comparaisons 16 bits avec un immédiat. ; Il faut comparer chaque partie séparément. LD A, IXH OR IXL ; combine les deux : A sera 0 seulement si les deux sont 0 CP 0 ; pas nécessaire, mais explicite JR NZ, boucle2 ; ### FIN de : ; Afficher les nombres de 0x0 à 0xFFFF CALL @EXIT ; Quitter le programme - Retour à LDOS ;--------------------------------------------------------------------- ; #### Mes fonctions! ;--------------------------------------------------------------------- ; Sous-routine : NumberToString ; Entrée : A contient le nombre (0-255) ; HL contient l'adresse du tampon de sortie ; Sortie : [HL] contient la chaîne ASCII terminée par zéro NumberToString: LD B, 0 ; B = nombre de chiffres extraits LD C, A ; C = copie du nombre original ; Extraire les centaines LD A, C LD D, 0 HundredsLoop: CP 100 JR C, SkipHundreds SUB 100 INC D JR HundredsLoop SkipHundreds: LD C, A ; C = reste après centaines LD A, D CALL AddDigitToBuffer INC B ; un chiffre extrait ; Extraire les dizaines LD A, C LD D, 0 TensLoop: CP 10 JR C, SkipTens SUB 10 INC D JR TensLoop SkipTens: LD C, A ; C = unités LD A, D CALL AddDigitToBuffer INC B ; Extraire les unités LD A, C CALL AddDigitToBuffer INC B ; Terminer la chaîne par CR/LF LD (HL), ENTER RET ;------------------------------------ ; Sous-routine : AddDigitToBuffer ; Entrée : A contient un chiffre (0-9) ; HL pointe vers l’endroit où écrire ; Sortie : écrit le chiffre converti en ASCII à (HL) et incrémente HL AddDigitToBuffer: ADD A, '0' ; Convertir en ASCII LD (HL), A INC HL RET ;------------------------------------------------------------ ; Sous-routine : NumberToHex ; Convertir un nombre en HEX. ; Entrée : DE contient un nombre ; HL pointe vers l’endroit où écrire ; Sortie : écrit le chiffre converti en ASCII à (HL) et incrémente HL ; NumberToHex: ; show "0x" as a prefix ld a, '0' LD (HL), A INC HL ld a, 'x' LD (HL), A INC HL ; Store the high-value ld c,d call OutHex8 ; Store the low-value ld c,e call OutHex8 LD (HL), ENTER ; Return to our caller ret ; ; Output the hex value of the 8-bit number stored in C ; OutHex8: ld a,c rra rra rra rra call Conv ld a,c Conv: and $0F add a,$90 daa adc a,$40 daa ; Store the value. LD (HL), A INC HL ret ;--------------------------------------------------------------------- ; FIN du programme ;--------------------------------------------------------------------- END MAIN
; ---------------------------------------------------- ; Fichier: Projets/afficher.asm ; Auteur: Alain Boudreault ; Date: 2025.08.12 - Soirée des percéides ; Cible: TRS-80 modèle 3 ; ---------------------------------------------------- ; Description: Afficher à l'écran sans utiliser les ; appels système de LDOS 5.1/MOD3. ; ---------------------------------------------------- ORG 7000H VIDEO EQU 3C00H VSIZE EQU 1024 TITRE DEFB 'Ce menu ne sert absolument a rien', 0 LIGNE DEFB '---------------------------------', 0 MENU01 DEFB '1. Manger des pommes', 0 MENU02 DEFB '2. Activer la manivelle', 0 MENU03 DEFB '3. Courir plus vite', 0 MENU04 DEFB '4. Esperer mieux', 0 MENU99 DEFB 'Faites votre choix: _', 0 MAIN: CALL CLEAR_SCREEN ; Efface l'écran CALL DISPLAY_MENU ; Affiche le menu YO: JP YO ; Boucle infinie ; ----------------------------------------------------------------- DISPLAY_MENU: LD DE, TITRE ; Affiche le titre LD B, 0 ; Ligne LD C, 0 ; Colonne CALL DISPLAY_ZSTRING INC B ; Passe à la ligne suivante LD DE, LIGNE ; Affiche la ligne de séparation CALL DISPLAY_ZSTRING INC B ; Passe à la ligne suivante LD DE, MENU01 ; Affiche le menu CALL DISPLAY_ZSTRING INC B ; Passe à la ligne suivante LD DE, MENU02 CALL DISPLAY_ZSTRING INC B ; Passe à la ligne suivante LD DE, MENU03 CALL DISPLAY_ZSTRING INC B ; Passe à la ligne suivante LD DE, MENU04 CALL DISPLAY_ZSTRING INC B ; Passe à la ligne suivante LD DE, LIGNE ; Affiche la ligne de séparation CALL DISPLAY_ZSTRING INC B ; Sauter deux lignes - Pas possible de faire ADD B,2 ;-) INC B LD DE, MENU99 CALL DISPLAY_ZSTRING RET ; ----------------------------------------------------------------- ; Affiche une chaîne terminée par 0 à une position (ligne, colonne) ; Entrée : ; DE = adresse de la chaîne (à ne pas modifier) ; B = ligne (0 à 15) ; C = colonne (0 à 63) ; ----------------------------------------------------------------- ; NOTE: Code généré par chatGPT, à optimiser! ; ----------------------------------------------------------------- DISPLAY_ZSTRING: PUSH HL PUSH AF PUSH DE ; Sauvegarde DE pour pouvoir l’utiliser après ; HL = ligne * 64 LD A, B LD H, 0 LD L, A ; HL = B ADD HL, HL ; HL = B * 2 ADD HL, HL ; *4 ADD HL, HL ; *8 ADD HL, HL ; *16 ADD HL, HL ; *32 ADD HL, HL ; *64 ; HL = HL + colonne LD A, C LD D, 0 LD E, A ; DE = colonne (temporaire) ADD HL, DE ; HL = offset dans mémoire vidéo ; Ajouter base mémoire vidéo LD DE, 0x3C00 ADD HL, DE ; HL = adresse écran finale POP DE ; Restaure DE = adresse de la chaîne .NEXT_CHAR: LD A, (DE) ; Lire caractère CP 0 JR Z, .DONE LD (HL), A ; Écrire caractère en mémoire vidéo INC DE ; Caractère suivant dans la chaîne INC HL ; Adresse suivante à l'écran JR .NEXT_CHAR .DONE: POP AF POP HL RET ; ----------------------------------------------------------------- ; Efface l'écran texte (64 colonnes × 16 lignes) ; en remplissant la mémoire vidéo avec des espaces (ASCII 32) ; Mémoire vidéo de 1024 octets à partir de 0x3C00 ; ----------------------------------------------------------------- CLEAR_SCREEN: PUSH DE PUSH HL PUSH AF LD DE,VSIZE LD HL, VIDEO LOOP_CLS: LD A,' ' LD (HL),A INC HL DEC DE LD A,D OR E JP NZ,LOOP_CLS POP AF POP HL POP DE RET ; ----------------------------------------------------- END MAIN
Documentation de LDOS