├── .gitattributes ├── ASM ├── ADLIB.ASM ├── AFFICHE.ASM ├── CMS.ASM ├── CONSTAFF.INC ├── CONSTMM.INC ├── FFT.ASM ├── GUSCMD.ASM ├── HARDWARE.ASM ├── IMFDROP.ASM ├── MIXAGE.ASM ├── MM.BAT ├── MODM.ASM ├── MODM.DIR ├── MODMAFF.ASM ├── MODMPAS.ASM ├── MODMSS.ASM ├── MODMUTIL.ASM ├── MODM_SS.ASM ├── OBJ.BAT ├── OBJSS.BAT ├── PSG.ASM ├── RADPLAY.ASM ├── SBCMD.ASM ├── SS.BAT ├── Speaker.asm ├── TDY.ASM ├── TDYDAC.ASM ├── TESTMIX.asm └── VGA.INC ├── LICENSE ├── README.md ├── RELEASES ├── MODM.REV ├── MODMXT10.zip ├── MODMXT100.zip ├── MODMXT12.zip ├── MODMXT13.zip ├── MODMXT14.zip ├── MODMXT15.zip ├── MODMXT16.zip ├── MODMXT17.zip ├── MODMXT18.zip ├── MODMXT19.zip ├── MODMXT20.zip ├── MODMXT21.zip ├── MODMXT22.zip ├── MODMXT24.zip ├── MODMXT25.zip ├── MODMXT26.zip ├── MODMXT8.zip ├── MODMXT9.zip ├── MODM_EN3.TXT └── README.txt ├── TP ├── MMCONV.PAS ├── MODM.PAS ├── PLAYMOD.PAS └── TESTMMD.PAS └── TPUNIT ├── BIOSEQU.PAS ├── CH669.PAS ├── CHADL.PAS ├── CHDTM.PAS ├── CHFAR.PAS ├── CHIMF.PAS ├── CHMIDI.PAS ├── CHMMM.PAS ├── CHMOD.PAS ├── CHMTM.PAS ├── CHPTM.PAS ├── CHRAD.PAS ├── CHS3M.PAS ├── CHSAT.PAS ├── CHSTM.PAS ├── CHULT.PAS ├── CHUTIL.PAS ├── CHVGM.PAS ├── CHXM.PAS ├── CLAVIER.PAS ├── EMSUNIT.PAS ├── FICHIERS.PAS ├── GUSUNIT.PAS ├── MEMOIRE.PAS ├── MMSS_CMD.PAS ├── MMSS_MEM.PAS ├── MMSS_VAR.PAS ├── MM_AFF.PAS ├── MM_DIV.PAS ├── MM_INIT.PAS ├── MM_OTHER ├── CHS3M_NC.PAS ├── CHXM_nc.PAS ├── DISNEYSS.PAS ├── DSSUNIT.PAS ├── ESSUNIT.PAS ├── FICH_GRP.PAS ├── MODM_SS.PAS ├── MT_DEFS.INC ├── MT_EDIT.PAS ├── MT_GLOB.PAS ├── MT_OUTP.PAS ├── MT_PLAY.PAS ├── MT_SONG.PAS └── SAV_MMM.PAS ├── MM_PARAM.PAS ├── MM_PLAY.PAS ├── MM_PROG.PAS ├── MM_VAR.PAS ├── MODMCFG.INI ├── MODMUNIT.PAS ├── PASMODM ├── BIOSDISK.PAS ├── DOSStruc.PAS ├── DOSStructures.PAS ├── FFT_U.PAS ├── GMUNIT.PAS ├── HARDWARE.PAS ├── PLMIDI.PAS ├── PMUNIT.PAS ├── QUARTSIN.INC ├── SOURIST.PAS ├── SUPPORT.PAS ├── TEXTE_V.PAS ├── TINTERRU.PAS ├── VARMIDI.PAS └── VGA.PAS ├── PSGUNIT.PAS ├── SBUNIT.PAS ├── SOURIS.PAS ├── SOURISC.PAS ├── SS.BAT ├── TDYUNIT.PAS ├── TEXTE.PAS ├── TYPES.PAS ├── UTIL.PAS ├── UTILC.PAS └── VARUNIT.PAS /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /ASM/ADLIB.ASM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/ASM/ADLIB.ASM -------------------------------------------------------------------------------- /ASM/AFFICHE.ASM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/ASM/AFFICHE.ASM -------------------------------------------------------------------------------- /ASM/CMS.ASM: -------------------------------------------------------------------------------- 1 | 2 | 3 | CMSPortOffset DB 0 ; 0 First Chip / 2 Second Chip 4 | CMSLPTPort DW 0 5 | 6 | ; Init_CMS 7 | ; Set the CMSLPT Port and initialize the CMS Chip 8 | Init_CMS Proc Near 9 | 10 | CMP CMS_Type,0 11 | JE Not_Init_CMS 12 | CMP CMS_Type,2 13 | JNE Not_Init_CMSLPT 14 | 15 | MOV AX,LPT1_Port 16 | CMP CMS_LPT_Nb,1 17 | JE Save_CMSLPTPort 18 | MOV AX,LPT2_Port 19 | Save_CMSLPTPort: 20 | MOV CMSLPTPort,AX 21 | 22 | Not_Init_CMSLPT: 23 | 24 | CALL CMS_Reset 25 | 26 | Not_Init_CMS: 27 | 28 | RET 29 | Init_CMS Endp 30 | 31 | ; Reset the 2 CMS Chip 32 | CMS_Reset Proc Near 33 | MOV CMSPortOffset,0 34 | CALL CMS_Clear 35 | 36 | MOV CMSPortOffset,2 37 | CALL CMS_Clear 38 | RET 39 | CMS_Reset Endp 40 | 41 | ; Clear all the register and Reset the Chip 42 | CMS_Clear Proc Near 43 | MOV CX,20h 44 | XOR AX,AX 45 | loop_null: ; null all 20 registers 46 | PUSH AX 47 | CALL CMS_Out 48 | POP AX 49 | INC AH ; Next register 50 | loop loop_null 51 | 52 | MOV AX,01C02h ; reset chip 53 | CALL CMS_Out 54 | 55 | MOV AX,01C01h ; enable this chip 56 | CALL CMS_Out 57 | 58 | RET 59 | CMS_Clear Endp 60 | 61 | ; Disable all the Channels 62 | CMS_Mute Proc Near 63 | 64 | XOR BX,BX 65 | CMS_MuteLoop: 66 | CALL CMS_Mute_Channel 67 | INC BX 68 | CMP BX,11 69 | JBE CMS_MuteLoop ; Loop 0 to 11 70 | 71 | RET 72 | CMS_Mute Endp 73 | 74 | 75 | ; Stop a Channel 76 | ; Input: BX Channel number 77 | CMS_Mute_Channel Proc Near 78 | PUSH BX 79 | MOV CMSPortOffset,0 80 | CMP BL,6 81 | JB CMS_Mutebelow6 82 | SUB BL,6 83 | MOV CMSPortOffset,2 84 | CMS_Mutebelow6: 85 | 86 | XOR AX,AX 87 | MOV AH,BL 88 | CALL CMS_Out ; Registers 0 to 5 are for the volume 89 | 90 | POP BX 91 | RET 92 | CMS_Mute_Channel Endp 93 | 94 | ; Set a CMS Register Value 95 | ; AH : Register 96 | ; AL : Data 97 | ; Port @ : CMS_Port+CMSPortOffset 98 | ; Destroy AX, DX 99 | CMS_Out Proc Near 100 | 101 | CMP CMS_Type,2 ; 2: CMSLPT 102 | JE CMSLPT_Out 103 | 104 | MOV DX,CMS_Port 105 | ADD DL,CMSPortOffset ; First or Second Chip 106 | 107 | INC DX 108 | XCHG AL,AH 109 | OUT DX,AL 110 | DEC DX 111 | XCHG AL,AH 112 | OUT DX,AL 113 | RET 114 | CMS_Out EndP 115 | 116 | ; AH : Register 117 | ; AL : Data 118 | CMSLPT_Out Proc Near 119 | 120 | MOV DX,CS:CMSLPTPort 121 | 122 | CMP CS:CMSPortOffset,0 123 | JE CMSLPT_1 124 | 125 | ;PUSH AX 126 | ;push dx 127 | ;Writech '1' 128 | ;pop dx 129 | ;Writech ':' 130 | ;MOV AX,DX 131 | ;Call WriteWordH 132 | ;POP AX 133 | 134 | ; first chip 135 | PUSH AX 136 | MOV AL,AH 137 | OUT DX,AL ; LPT Data (Register number) 138 | 139 | MOV AL,0Ch ; CMS 0 CS1, A0 140 | CALL CMSLPT_ToggleWr 141 | POP AX 142 | 143 | OUT DX,AL ; LPT Data (Register Value) 144 | 145 | MOV AL,0Dh ; CMS 0 CS1, ~A0 146 | CALL CMSLPT_ToggleWr 147 | RET 148 | CMSLPT_1: 149 | 150 | ;PUSH AX 151 | ;push dx 152 | ;Writech '2' 153 | ;pop dx 154 | ;POP AX 155 | 156 | ; Second Chip 157 | PUSH AX 158 | MOV AL,AH 159 | OUT DX,AL ; LPT Data (Register number) 160 | 161 | MOV AL,06h ; CMS 1 // CS2, A0 162 | CALL CMSLPT_ToggleWr 163 | POP AX 164 | 165 | OUT DX,AL ; LPT Data (Register Value) 166 | 167 | MOV AL,07h ; CMS 1 // CS2, ~A0 168 | CALL CMSLPT_ToggleWr 169 | 170 | RET 171 | CMSLPT_Out Endp 172 | 173 | ; DX : LPT Command Port 174 | ; AL : Control Value 175 | CMSLPT_ToggleWr Proc Near 176 | 177 | INC DX 178 | INC DX ; LPT Control Port 179 | 180 | OUT DX,AL ; Write Value 181 | MOV AH,AL 182 | XOR AL,04h ; Change Bit 2 183 | OUT DX,AL 184 | 185 | PUSH CX 186 | MOV CX,7 187 | CMSToggleLoop: 188 | IN AL,DX 189 | LOOP CMSToggleLoop 190 | POP CX 191 | 192 | MOV AL,AH 193 | OUT DX,AL ; Write Value again 194 | 195 | DEC DX 196 | DEC DX ; LPT Data Port 197 | 198 | RET 199 | CMSLPT_ToggleWr Endp -------------------------------------------------------------------------------- /ASM/CONSTAFF.INC: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/ASM/CONSTAFF.INC -------------------------------------------------------------------------------- /ASM/CONSTMM.INC: -------------------------------------------------------------------------------- 1 | ; ���������������������������������������������������ͻ 2 | ; � �������������� CONSTMM.INC �������������� � 3 | ; � � 4 | ; � --==�� Mod Master v2.2� ��==-- � 5 | ; ���������������������������������������������������ĺ 6 | ; � Auteur������������������������ Freddy V�tel� � 7 | ; � � 8 | ; � Derni�re modification��������� 29/08/1995 � 9 | ; ���������������������������������������������������ͼ 10 | ; ** Tableaux de constantes pour Mod Master ** 11 | 12 | b Equ Byte Ptr 13 | w Equ Word Ptr 14 | d Equ DWord Ptr 15 | 16 | InstrS Struc 17 | ISample_Nb DB ? ; Number of the First Sample , FFh No Samples 18 | ISamples_Total DB ? ; Number of samples loaded 19 | IVolumeType DB ? ; Volume Envelope Type 20 | IPanningType DB ? ; 21 | IRelNote DB ? ; Relative Note 22 | IFill DB ? ; Not used 23 | IInstrDataSeg DW ? ; Segment of the Note to Sample and Envelope data 24 | InstrS Ends 25 | 26 | Sampl struc 27 | SInfo DB ? 28 | SLen DD ? 29 | SRep DD ? 30 | SRep_len DD ? 31 | SVolume DB ? 32 | SRel_Note DB ? ; Relative Note, Signed (XM) 33 | SDadj DW ? 34 | SAdresse_GUS DD ? 35 | SSegment DW ? ;\ 36 | SHandle_EMS DW ? ; |-- Bloc de M�moire... 37 | SNb_Pages_EMS DB ? ;/ 38 | Sampl ends 39 | 40 | Adlb struc 41 | AInfo DB ? 42 | ; ANom DB 32 DUP (?) 43 | AVolume DB ? 44 | ADadj DW ? 45 | AM1 DB ? ; Modulateur (1 � Param�tre) 46 | AP1 DB ? ; Porteuse (1 � Param�tre) 47 | AM2 DB ? 48 | AP2 DB ? 49 | AM3 DB ? 50 | AP3 DB ? 51 | AM4 DB ? 52 | AP4 DB ? 53 | AM5 DB ? ; Modulateur (5 � Param�tre) 54 | AP5 DB ? ; Porteuse (5 � Param�tre) 55 | AFeedBack DB ? 56 | AFill DB 12 DUP (?) 57 | Adlb ends 58 | 59 | ; Masque pour les Infos sur le sample 60 | 61 | M_Adlib EQU 1 62 | M_NSigne EQU 2 63 | M_16bit EQU 4 64 | M_Boucle EQU 8 65 | M_Bidi EQU 16 66 | M_Charge EQU 128 67 | 68 | ; Masques pour les modifications des voies (Pour GUS et Adlib) 69 | 70 | M_ChSample EQU 1 ; Change the Sample 71 | M_ChPeriode EQU 2 ; Change the Period 72 | M_ChVolume EQU 4 ; Change the Volume 73 | M_ChPanning EQU 8 ; Change the Panning 74 | 75 | ; VControl Byte Mask, for Channels control 76 | 77 | CM_Stopped EQU 1 ; Set to 1 When the Channel is Stopped (Key Off, Sample end...) 78 | CM_Disabled EQU 2 ; Set to 1 When the channel is disables 79 | CM_KeyOff EQU 4 ; Set to 1 When Key Off 80 | M_VolChanged EQU 8 ; For the Volume Pitch Display 81 | CM_NoteCut EQU 16 ; Set to 1 Stop the sound 82 | M_FadeVol EQU 32 ; Volume Fading (XM Envelope) 83 | CM_FStop EQU 64 ; 1 if the Disable was forced (Red spot on Display) 84 | CM_FPause EQU 128 ; 1 if the sample mix is Paused (Brown spot on Display) 85 | 86 | ; Envelope Type Mask (XM) 87 | 88 | E_On EQU 1 89 | E_Sustain EQU 2 90 | E_Loop EQU 4 91 | 92 | ; ** Channel Control masques ** (USMPlay, for Reference) 93 | 94 | CC_Stopped EQU 1 ; Active/Stopped channel (0) 95 | CC_Playing EQU 2 ; A sample is played on this channel (1) 96 | CC_StopVoice EQU 4 ; Stop the sample (2) 97 | CC_FadeVol EQU 8 ; Fading active (3) 98 | CC_Release EQU 16 ; Channel is released (4) 99 | 100 | CC_ChSample EQU 32 ; Change channel sample (5) 101 | CC_ChPeriod EQU 64 ; Change channel period (6) 102 | CC_ChVolume EQU 128 ; Change channel volume (7) 103 | CC_CH_Panning EQU 256 ; Change channel panning (8) 104 | CC_DoRelease EQU 512 ; Stop sustain loop (9) 105 | CC_Surround EQU 1024 ; Surround (10) 106 | CC_Backgrnd EQU 2048 ; Background channel 107 | 108 | 109 | b Equ Byte Ptr 110 | w Equ Word Ptr 111 | d Equ DWord Ptr 112 | 113 | ;Erreurs Mod Master... 114 | 115 | Err_Output_NotFound EQU 1 ; {La sortie indiquee n'existe pas (Ex:LPT2)} 116 | Err_SB EQU 2 ; {SB does not answer (Disabled) } 117 | Err_Invalid_Freq EQU 3 ; {Not Correct Frequency } 118 | Err_Too_Slow EQU 4 ; {The computer is too Slow to mix 1 channel} 119 | Err_MOD_NotLoaded EQU 5 ; {Module Not Loaded } 120 | Err_Invalid_Channels EQU 6 ; {Invalid Nb of channels } 121 | Err_Invalid_MOD EQU 7 ; {Format error or not supported } 122 | Err_OPL_NotFound EQU 8 ; 123 | Err_OPL3_NotFound EQU 9 ; 124 | Err_TDY_NotFound Equ 10 125 | Err_CMD_NotSupported EQU 11 ; { VGM Command not supported } 126 | Err_CMS_NotFound EQU 12 ; 127 | Err_PSG_NotFound Equ 13 128 | 129 | ;sorties sonores 130 | 131 | HPint EQU 0 ; PC Speaker 132 | LPT1 EQU 1 ; DAC on LPT1 133 | LPT2 EQU 2 ; DAC on LPT2 134 | C_DAC EQU 3 ; Custom DAC 135 | T_DAC EQU 4 ; Tandy DAC 136 | SB EQU 5 137 | SBPro EQU 6 ; Sound Blaster Pro/16 138 | GUS EQU 7 139 | NoOut EQU 0FFh ; 140 | 141 | ; Mask for the Synth Output used by the Music 142 | M_Speaker EQU 1; 143 | M_SN76489 EQU 2; 144 | M_CMS EQU 4; 145 | M_SID EQU 8; 146 | M_OPL2 EQU 16; 147 | M_OPL3 EQU 32; 148 | M_SAA1099 EQU 64; 149 | M_PSG EQU 128; 150 | 151 | 152 | ;Type de module 153 | 154 | T_MOD EQU 0 155 | T_STM EQU 2 ;{ Scream Tracker 2.0 } 156 | T_S3M EQU 3 ;{ Scream Tracker 3.x } 157 | T_669 EQU 4 ;{ Composer 669 } 158 | T_MTM EQU 5 ;{ } 159 | T_DTM EQU 6 ;{ Digital Tracker } 160 | T_ULT EQU 7 ;{ Ultra Tracker } 161 | T_FAR EQU 8 ;{ Farandole Tracker } 162 | T_PTM EQU 9 163 | T_SAT EQU 10 ;{ Adlib Tracker } 164 | T_MON EQU 11 165 | T_XM EQU 12 ;{ Fast Tracker 2 } 166 | T_VGZ EQU 13 167 | T_VGM EQU 14 168 | T_RAD EQU 15 169 | T_IMF EQU 16 170 | T_RAW EQU 17 171 | T_DRO Equ 18 172 | T_MID Equ 19 173 | 174 | Ta_vib DB 0, 24, 49, 74, 97,120,141,161,180,197,212,224,235,244,250,253 175 | DB 255,253,250,244,235,224,212,197,180,161,141,120, 97, 74, 49, 24 176 | ;Partie negative du sinus 177 | DB 0, 24, 49, 74, 97,120,141,161,180,197,212,224,235,244,250,253 178 | DB 255,253,250,244,235,224,212,197,180,161,141,120, 97, 74, 49, 24 179 | 180 | Ta_rampe DB 255,247,239,231,223,215,207,199,191,183,175,167,159,151,143,135 181 | DB 127,120,112,104, 96, 88, 79, 72, 64, 56, 47, 40, 32, 24, 16, 8 182 | DB 0 , 8, 16, 24, 32, 40, 47, 56, 64, 72, 79, 88, 96,104,112,120 183 | DB 127,135,143,151,159,167,175,183,191,199,207,210,223,231,239,247 184 | 185 | Ta_carre DB 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 186 | DB 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 187 | DB 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 188 | DB 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255 189 | 190 | Nb_Octaves_Total EQU 8 191 | 192 | Align 2 193 | Mini_Octaves DW 0E28h*4,0E28h*2,0E28h,0714h,038Ah,01C5h,00E2h,0071h,0038h,001Ch ; *4 194 | Maxi_Octaves DW 1AC0h*4,1AC0h*2,1AC0h,0D60h,06B0h,0358h,01ACh,00D6h,006Bh,0035h 195 | 196 | Total_FineTune EQU 12*8 197 | 198 | ; Table de conversion pour le HP interne 199 | 200 | T_bep DB 20h,1Fh,1Eh,1Dh,1Ch,1Bh,1Ah,19h,18h,17h,16h,15h,14h,13h,12h,11h 201 | DB 11h,10h,10h,0Fh,0Fh,0Eh,0Eh,0Dh,0Dh,0Dh,0Ch,0Ch,0Ch,0Ch,0Bh,0Bh 202 | DB 0Bh,0Bh,0Ah,0Ah,0Ah,0Ah,0Ah,09h,09h,09h,09h,09h,09h,09h,09h,09h 203 | DB 08h,08h,08h,08h,08h,08h,08h,08h,08h,08h,08h,08h,07h,07h,07h,07h 204 | DB 07h,07h,07h,06h,06h,06h,06h,06h,06h,06h,06h,06h,06h,06h,05h,05h 205 | DB 05h,05h,05h,05h,05h,05h,05h,05h,04h,04h,04h,04h,04h,04h,04h,04h 206 | DB 04h,04h,03h,03h,03h,03h,03h,03h,03h,03h,03h,03h,02h,02h,02h,02h 207 | DB 02h,02h,02h,02h,02h,01h,01h,01h,01h,01h,01h,01h,01h,01h,01h,01h 208 | 209 | DB 40h,40h,40h,40h,40h,40h,40h,40h,40h,40h,3Fh,3Fh,3Fh,3Fh,3Fh,3Fh 210 | DB 3Fh,3Fh,3Fh,3Fh,3Fh,3Fh,3Eh,3Eh,3Eh,3Eh,3Eh,3Eh,3Eh,3Eh,3Eh,3Eh 211 | DB 3Dh,3Dh,3Dh,3Dh,3Dh,3Dh,3Dh,3Dh,3Dh,3Ch,3Ch,3Ch,3Ch,3Ch,3Ch,3Ch 212 | DB 3Ch,3Ch,3Ch,3Bh,3Bh,3Bh,3Bh,3Bh,3Bh,3Bh,3Bh,3Bh,3Bh,3Ah,3Ah,3Ah 213 | DB 3Ah,3Ah,3Ah,3Ah,3Ah,3Ah,3Ah,39h,39h,39h,39h,39h,39h,39h,39h,39h 214 | DB 39h,38h,38h,38h,38h,38h,38h,38h,38h,37h,37h,37h,37h,37h,36h,36h 215 | DB 36h,36h,35h,35h,35h,35h,34h,34h,34h,33h,33h,32h,32h,31h,31h,30h 216 | DB 30h,2Fh,2Eh,2Dh,2Ch,2Bh,2Ah,29h,28h,27h,26h,25h,24h,23h,22h,21h 217 | ; Table de conversion pour la carte Adlib (Synt� OPL 2) 218 | 219 | T_Adlib DB 63,56,51,48,45,43,41,40,38,37,36,35,34,34,33,32 220 | DB 31,31,30,29,29,28,28,27,27,26,26,26,25,25,24,24 221 | DB 24,23,23,23,22,22,22,21,21,21,21,20,20,20,20,19 222 | DB 19,19,19,18,18,18,18,18,17,17,17,17,17,16,16,16 223 | DB 16,16,15,15,15,15,15,15,14,14,14,14,14,14,14,13 224 | DB 13,13,13,13,13,13,12,12,12,12,12,12,12,12,11,11 225 | DB 11,11,11,11,11,11,11,10,10,10,10,10,10,10,10,10 226 | DB 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8 227 | DB 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 228 | DB 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5 229 | DB 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4 230 | DB 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3 231 | DB 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2 232 | DB 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 233 | DB 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 234 | DB 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 235 | 236 | -------------------------------------------------------------------------------- /ASM/FFT.ASM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/ASM/FFT.ASM -------------------------------------------------------------------------------- /ASM/GUSCMD.ASM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/ASM/GUSCMD.ASM -------------------------------------------------------------------------------- /ASM/MIXAGE.ASM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/ASM/MIXAGE.ASM -------------------------------------------------------------------------------- /ASM/MM.BAT: -------------------------------------------------------------------------------- 1 | TASM modm 2 | TLINK /t modm 3 | -------------------------------------------------------------------------------- /ASM/MODM.DIR: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/ASM/MODM.DIR -------------------------------------------------------------------------------- /ASM/MODMSS.ASM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/ASM/MODMSS.ASM -------------------------------------------------------------------------------- /ASM/MODMUTIL.ASM: -------------------------------------------------------------------------------- 1 | ; ���������������������������������������������������ͻ 2 | ; � --==�� Mod Master v2.2 ��==-- � 3 | ; ���������������������������������������������������ĺ 4 | ; � Auteur������������������������ Freddy V�tel� � 5 | ; � Avec l'aide de���������������� Fabrice Couteau � 6 | ; � � 7 | ; � Derni�re modification��������� 24/10/1995 � 8 | ; � 03/04/2019 : Remove Keyboard IRQ � 9 | ; ���������������������������������������������������ͼ 10 | 11 | ;scan-codes des touches utilis�es et action associ�e 12 | 13 | scanF1 EQU 59 ;affiche/efface page d'aide 14 | scanF2 EQU 60 ;liste instruments <-> partition 15 | scanF3 EQU 61 16 | scanF4 EQU 62 17 | scanF5 EQU 63 18 | scanF6 EQU 64 ;Debug 19 | scanUp EQU 72 ;Affichage des voies <- 20 | scanDown EQU 80 ;Affichage des voies -> 21 | scan1 EQU 2 ;active/d�sactive voie 1 22 | scan2 EQU 3 ;active/d�sactive voie 2 23 | scan3 EQU 4 ;active/d�sactive voie 3 24 | scan4 EQU 5 ;active/d�sactive voie 4 25 | scan5 EQU 6 ;active/d�sactive voie 5 26 | scan6 EQU 7 ;active/d�sactive voie 6 27 | scan7 EQU 8 ;active/d�sactive voie 7 28 | scan8 EQU 9 ;active/d�sactive voie 8 29 | scan9 EQU 0Ah 30 | scan0 Equ 0Bh 31 | 32 | scanAQ EQU 16 ;decremente couleur barre pitch 33 | scanZW EQU 17 ;incremente couleur barre pitch 34 | scanQA EQU 30 ;decremente couleur bout barre pitch 35 | scanS EQU 31 ;incremente couleur bout barre pitch 36 | ScanD EQU 32 ;lance le DOS Shell 37 | scanW EQU 44 38 | scanX EQU 45 39 | scanO EQU 24 ;d�cr�mente caractere barre periode 40 | scanP EQU 25 ;incr�mente caractere barre periode 41 | scanL EQU 38 ;decremente couleur barre periode 42 | scanM EQU 39 ;incremente couleur barre periode 43 | scanR EQU 19 ;active/d�sactive fonction Repeat 44 | scanI EQU 23 ;Disable IntroScan 45 | scanTab EQU 15 ;mode texte <-> mode graphique 46 | scanEspace EQU 57 ;active/desactive Pause 47 | scanPlus EQU 78 ;augmente le volume relatif 48 | scanMoins EQU 74 ;diminue le volume relatif 49 | scanLeft EQU 75 ;retour rapide 50 | scanRight EQU 77 ;avance rapide 51 | scanPgUp EQU 73 ;Module precedent dans un programme 52 | scanPgDn EQU 81 ;Module suivant dans un programme 53 | scanEsc EQU 1 ;abandonne la lecture 54 | 55 | 56 | Afficher_fin_voies DB 0 57 | 58 | 59 | Gerer_Touches PROC NEAR 60 | 61 | ; Read the Key Pressed OK, Working on PC1640 62 | 63 | MOV ah,01h ; checks if a key is pressed 64 | ; MOV ah,11h 65 | INT 16h 66 | JNZ Read_Key 67 | DS_TP 68 | MOV Key_ScanCode,0 ; Save 0 for No Key 69 | DS_ASM 70 | RET ; zero = no key pressed 71 | Read_Key: 72 | MOV ah,00h ; read the Key Code 73 | INT 16h 74 | XCHG AL,AH 75 | 76 | DS_TP 77 | MOV Key_ScanCode,AL ; Save the Scan Code for the Pascal 78 | 79 | CMP TP_Fading,1 ; No Key read if fading, except "Escape" 80 | DS_ASM 81 | JNE Continuer_clavier 82 | JMP Test_Esc 83 | Go_Keyboard_End: 84 | RET 85 | 86 | Continuer_clavier: 87 | 88 | CMP AL,scanF1 89 | JNE test_F2 90 | If CGAOnly Eq No 91 | DS_TP 92 | CMP Mode_actuel,Mode_Texte 93 | JE change_aff_page_aide_texte 94 | MOV Changer_affichage,1 ; mode graphique -> passe en mode 95 | MOV Mode_a_afficher,Mode_Texte ; texte et affiche la page d'aide 96 | JMP SHORT active_page_aide 97 | change_aff_page_aide_texte: 98 | EndIf 99 | DS_TP 100 | MOV AL,Center_Display 101 | CMP AL,2 ; Help already displayed ? 102 | JNE active_page_aide 103 | MOV AL,CS:ancien_aff_centre 104 | MOV Center_Display,AL ; Go to the previous screen 105 | JMP SHORT fin_F1 106 | active_page_aide: 107 | MOV AL,Center_Display 108 | MOV CS:ancien_aff_centre,AL 109 | MOV Center_Display,CD_Help ; 2 Help 110 | fin_F1: 111 | MOV Change_aff_centre,1 112 | RET 113 | 114 | Test_F2: ; F2 Sample List 115 | CMP AL,scanF2 116 | JNE test_F3 117 | CMP MUS_OPLStream,1 ; IMF, RAW, DRO, VGM 118 | JE Test_F3 119 | 120 | DS_TP 121 | MOV Change_aff_centre,1 122 | MOV Center_Display,CD_Samples ; 0 Samples 123 | RET 124 | 125 | Test_F3: 126 | CMP AL,scanF3 127 | JNE test_Monotone_File 128 | CMP Type_Module,T_RAD ; No partition for RAD and IMF 129 | JE Test_Monotone_File 130 | CMP MUS_OPLStream,1 ; IMF, RAW, DRO 131 | JE Test_Monotone_File 132 | 133 | DS_TP 134 | CMP Center_Display,CD_Part 135 | JNE Change_Display_F3 ; Change the Display /Clean screen only one time 136 | RET 137 | Change_Display_F3: 138 | MOV Change_aff_centre,1 139 | MOV Center_Display,CD_Part ; 1 Partition 140 | RET 141 | 142 | Test_Monotone_File: ;Monotone file -> No more test Keys 143 | 144 | ; CMP Type_Module,T_MON 145 | ; JNE Continue_NotMON 146 | ; RET 147 | ;Continue_NotMON: 148 | 149 | CMP AL,scanEspace ;Espace =>Pause 150 | JNE No_pause 151 | XOR MMSS_Pause,1 152 | JZ MMSS_Stop_Pause 153 | JMP SHORT Enable_Pause 154 | 155 | MMSS_Stop_Pause: 156 | DS_ASM 157 | CALL Stop_Pause 158 | RET 159 | 160 | Enable_Pause: 161 | CALL Affiche_Fonctions 162 | CALL MMSS_Start_Pause 163 | RET 164 | 165 | No_Pause: 166 | CMP MMSS_Pause,1 167 | JNE test_Tab 168 | RET ;Interdit toutes les touches si PAUSE 169 | 170 | test_Tab: 171 | DS_ASM 172 | If CGAOnly Eq No 173 | CMP AL,scanTab 174 | JMP test_PgUp 175 | DS_TP 176 | CMP Changer_affichage,1 ;Mode pas encore chang� => ne pas le 177 | DS_ASM ;changer. 178 | JE Suite_test_Tab 179 | DS_TP 180 | MOV Changer_affichage,1 181 | XOR Mode_a_afficher,1 ;Texte <-> Graphique 182 | DS_ASM 183 | Suite_test_Tab: 184 | RET 185 | EndIf 186 | test_PgUp: 187 | CMP AL,scanPgUp 188 | JNE test_PgDn 189 | DS_TP 190 | MOV AH,Programme 191 | DS_ASM 192 | CMP AH,1 193 | JNE fin_PgUp 194 | DS_TP 195 | MOV AX,Numero_Module 196 | DS_ASM 197 | CMP AX,1 198 | JBE fin_PgUp 199 | MOV Touche_fin,Tfin_PgUp 200 | MOV Musique_Terminee,1 ;Stopper la musique 201 | MOV Stop_Output,1 ;Stopper la sortie sonore 202 | fin_PgUp: 203 | RET 204 | 205 | test_PgDn: ; PgDn 206 | CMP AL,scanPgDn 207 | JNE test_F4 208 | DS_TP 209 | MOV AH,Programme 210 | DS_ASM 211 | CMP AH,1 212 | JNE fin_PgDn 213 | DS_TP 214 | MOV CX,Numero_Module 215 | MOV AX,Longueur_prog 216 | DS_ASM 217 | CMP CX,AX ; Fin du programme ? 218 | JAE fin_PgDn 219 | MOV Touche_fin,Tfin_PgDn 220 | MOV Musique_Terminee,1 ;Stopper la musique 221 | MOV Stop_Output,1 ;Stopper la sortie sonore 222 | fin_PgDn: 223 | RET 224 | 225 | test_F4: ; F4 226 | CMP AL,scanF4 227 | JNE test_F5 228 | DS_TP 229 | MOV Change_aff_centre,1 230 | CMP Center_Display,4 231 | JNE Don_Swap_SubDisplayF4 232 | DS_ASM 233 | XOR Display_NoteOrBar,1 ; Swap Display 234 | RET 235 | 236 | Don_Swap_SubDisplayF4: 237 | MOV Center_Display,4 ; 4 Multiple Channels 238 | RET 239 | 240 | test_F5: ; F5 241 | CMP AL,scanF5 242 | JNE test_F6 243 | XOR Utiliser_Interpol,1 244 | CALL Affiche_Fonctions 245 | RET 246 | 247 | test_F6: ; F6 : Debug 248 | CMP AL,scanF6 249 | JNE test_Up 250 | DS_TP 251 | MOV Change_aff_centre,1 252 | MOV Center_Display,3 253 | RET 254 | 255 | test_Up: ; Channel - 256 | CMP AL,scanUp 257 | JNE test_Down 258 | MOV AH,N_voie_aff 259 | CMP AH,0 260 | JE Test_Plus 261 | DEC N_voie_aff 262 | DS_TP 263 | MOV Change_aff_centre,1 264 | RET 265 | 266 | test_Down: 267 | CMP AL,scanDown ; Channel + 268 | JNE test_Plus 269 | MOV BL,Ch_Number 270 | SUB BL,N_voie_aff 271 | CMP BL,4 272 | JBE Test_Plus 273 | INC N_voie_aff 274 | DS_TP 275 | MOV Change_aff_centre,1 276 | DS_ASM 277 | RET 278 | 279 | Test_Plus: 280 | CMP AL,scanPlus 281 | JNE test_Moins 282 | CMP Volume_Total,40h-4 283 | JBE VT_Not40h 284 | MOV Volume_Total,40h-4 285 | VT_Not40h: 286 | ADD Volume_Total,4 287 | CALL MMSS_Volume_UpdateAll 288 | Suite_Plus: 289 | RET 290 | 291 | Test_Moins: 292 | CMP AL,scanMoins 293 | JNE test_1 294 | CMP Volume_Total,4 295 | JAE VT_NotZero 296 | MOV Volume_Total,4 297 | VT_NotZero: 298 | SUB Volume_Total,4 299 | CALL MMSS_Volume_UpdateAll 300 | Suite_Moins: 301 | RET 302 | 303 | Test_1: 304 | MOV AH,AL 305 | SUB AH,Scan1 ; Test the '1' to '0' Keys 306 | CMP AH,9 307 | JA test_Right 308 | XOR BX,BX 309 | MOV BL,AH 310 | XOR Ch_Control[BX],CM_Disabled ; Reverse the Disabled bit 311 | JZ Stop_Channel_End ; If channel enabled, Skip Disable 312 | 313 | OR Ch_Control[BX],CM_KeyOff+CM_NoteCut ; Enable Key Off (For Adlib / GUS) 314 | 315 | ; Tandy 316 | TEST OtherMUS_Out,M_SN76489 317 | JZ Stop_Channel_End 318 | CALL TDY_Mute_Channel 319 | 320 | Stop_Channel_End: 321 | RET 322 | 323 | Test_Right: 324 | CMP AL,scanRight 325 | JNE test_Left 326 | ADD Tick_Count,100 ; Test Fast Forward 327 | CMP Duree_intro,0 328 | JNZ Cont_droite 329 | MOV AL,Sequence_Len 330 | CMP C_Sequence,AL 331 | JB cont_cl_droite 332 | cont_droite: 333 | RET 334 | cont_cl_droite: 335 | MOV Cmpt_Tempo,1 336 | MOV Cmd_ModifyPattern,1 337 | INC C_Sequence ; Incrementer la position 338 | RET 339 | 340 | test_Left: 341 | CMP AL,scanLeft 342 | JNE test_D 343 | CMP Duree_intro,0 344 | JNZ cont_droite 345 | 346 | CMP C_Sequence,1 347 | JE Pas_dec_pos 348 | DEC C_Sequence ; D�cr�menter la position 349 | Pas_dec_pos: 350 | MOV Cmpt_Tempo,1 351 | MOV Cmd_ModifyPattern,1 352 | RET 353 | 354 | test_D: 355 | CMP AL,ScanD 356 | JNE test_A 357 | DS_TP 358 | MOV Activer_Shell,1 359 | RET 360 | 361 | test_A: 362 | CMP AL,scanAQ 363 | JNE test_ZW 364 | DS_TP 365 | DEC coul_barre_pitch 366 | JNZ suite_AQ 367 | MOV coul_barre_pitch,15 368 | suite_AQ: 369 | RET 370 | 371 | test_ZW: 372 | CMP AL,scanZW 373 | JNE test_QA 374 | DS_TP 375 | INC coul_barre_pitch 376 | CMP coul_barre_pitch,15 377 | JBE suite_Z 378 | MOV coul_barre_pitch,1 379 | suite_Z: 380 | RET 381 | 382 | test_QA: 383 | CMP AL,scanQA 384 | JNE test_S 385 | DS_TP 386 | DEC coul_bout_pitch 387 | JNZ suite_Q 388 | MOV coul_bout_pitch,15 389 | suite_Q: 390 | RET 391 | test_S: 392 | CMP AL,scanS 393 | JNE test_O 394 | DS_TP 395 | INC coul_bout_pitch 396 | CMP coul_bout_pitch,15 397 | JBE suite_S 398 | MOV coul_bout_pitch,1 399 | suite_S: 400 | RET 401 | 402 | test_O: 403 | CMP AL,scanO 404 | JNE test_P 405 | DS_TP 406 | INC coul_barre_periode 407 | CMP coul_barre_periode,15 408 | JBE suite_O 409 | MOV coul_barre_periode,1 410 | suite_O: 411 | RET 412 | 413 | test_P: 414 | CMP AL,scanP 415 | JNE test_R 416 | DS_TP 417 | DEC coul_barre_periode 418 | JNZ suite_P 419 | MOV coul_barre_periode,15 420 | suite_P: 421 | RET 422 | 423 | test_R: 424 | CMP AL,scanR 425 | JNE test_I 426 | DS_TP 427 | CMP Boucler_MOD,0 ;fonction Repeat active? (Boucler=1 ou 2) 428 | MOV Boucler_MOD,1 ;active Repeat 429 | JZ suite_R ;non 430 | MOV Boucler_MOD,0 ;d�sactive Repeat 431 | suite_R: 432 | DS_ASM 433 | CALL Affiche_Fonctions 434 | JMP SHORT Keyboard_End 435 | 436 | test_I: 437 | CMP AL,scanI 438 | JNE test_Esc 439 | MOV Duree_intro,0 ;Disable IntroScan (continue � jouer 440 | ;le module courant dans le programme) 441 | CALL Affiche_Fonctions 442 | JMP SHORT Keyboard_End 443 | 444 | test_Esc: 445 | CMP AL,scanEsc 446 | JNE Keyboard_End 447 | 448 | CMP Type_Module,T_RAD ; Directly stop if RAD / IMF 449 | JE Arret_brutal 450 | CMP MUS_OPLStream,1 ; IMF, RAW, DRO 451 | JE Arret_brutal 452 | 453 | DS_TP 454 | CMP TP_Fading,1 455 | DS_ASM 456 | JE Arret_brutal 457 | MOV Touche_fin,Tfin_Esc 458 | DS_TP 459 | MOV TP_Fading,1 460 | DS_ASM 461 | 462 | MOV AL,Volume_Total 463 | MOV Volume_Saved,AL 464 | 465 | JMP SHORT Keyboard_End 466 | Arret_brutal: 467 | 468 | MOV Stop_Output,1 469 | 470 | Keyboard_End: 471 | DS_ASM 472 | RET 473 | 474 | Gerer_Touches ENDP -------------------------------------------------------------------------------- /ASM/OBJ.BAT: -------------------------------------------------------------------------------- 1 | TASMX C:\TASM\SOURCE\modmpas /m2 2 | REM TASMX modm_SS /m2 3 | REM copy modm_ss.obj C:\TP\BIN\OBJ 4 | copy modmpas.obj C:\TP\BIN\OBJ 5 | -------------------------------------------------------------------------------- /ASM/OBJSS.BAT: -------------------------------------------------------------------------------- 1 | TASMX modm_SS 2 | copy modm_ss.obj C:\TP\BIN\OBJ 3 | 4 | -------------------------------------------------------------------------------- /ASM/PSG.ASM: -------------------------------------------------------------------------------- 1 | ; PSG / AY-3-8910 2 | ; Registers / minimal doc: https://vdsteenoven.com/aquarius/psgprog.html 3 | 4 | PSGPortOffset DB 0 ; 0 First Chip / 2 Second Chip 5 | 6 | ; Init the TDYLPT Base Ports if Selected. 7 | Init_PSG Proc Near 8 | 9 | CALL PSG_Mute 10 | 11 | RET 12 | Init_PSG Endp 13 | 14 | ; Set all the channels volume to 0 15 | PSG_Mute Proc Near 16 | mov cs:PSGPortOffset,0 ; First chip 17 | mov ax,070FF ; Register 7: Disable all the channels 18 | call PSG_Out 19 | 20 | mov cs:PSGPortOffset,2 ; Second Chip 21 | mov ax,070FF 22 | call PSG_Out 23 | RET 24 | PSG_Mute Endp 25 | 26 | ; Set a Tandy Channel to 0 27 | ; Input: BX Channel number 28 | PSG_Mute_Channel Proc Near 29 | 30 | cmp bx,6 31 | jae PSG_Mute_Channel_end 32 | mov cs:PSGPortOffset,0 33 | cmp bl,3 34 | jbe PSG_Mute_2ndChip 35 | mov cs:PSGPortOffset,2 36 | sub bl,3 37 | PSG_Mure_2ndChip: 38 | 39 | add bl,8 ; Volume are Regs 8 to 10 40 | mov ah,bl 41 | mov al,0 42 | call PSG_Out ; Set the channel colume to 0 43 | 44 | PSG_Mute_Channel_end: 45 | RET 46 | PSG_Mute_Channel Endp 47 | 48 | ; Write to a PSG Register 49 | ; Input: AH: Register, AL Value 50 | ; Change: ax,dx, flags 51 | PSG_Out Proc Near 52 | mov dx,cs:PSGPort 53 | add dl,cs:PSGPortOffset 54 | 55 | xchg ah,al 56 | out dx,al ; Write to Register index port 57 | xchg ah,ah 58 | inc dx ; Move to Data port 59 | out dx,al ; Write the Data 60 | 61 | RET 62 | PSG_Out Endp -------------------------------------------------------------------------------- /ASM/RADPLAY.ASM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/ASM/RADPLAY.ASM -------------------------------------------------------------------------------- /ASM/SBCMD.ASM: -------------------------------------------------------------------------------- 1 | ; ���������������������������������������������������ͻ 2 | ; � ��������������� SBCMD.INC ��������������� � 3 | ; � � 4 | ; � --==�� Mod Master v2.1 ��==-- � 5 | ; ���������������������������������������������������ĺ 6 | ; � Auteur Freddy Vetele � 7 | ; � � 8 | ; � Derniere modification 30/03/2022 � 9 | ; ���������������������������������������������������ͼ 10 | 11 | 12 | T_SB1 EQU 1 ;Sound Blaster 1.0 13 | T_SB15 EQU 2 ;Sound Blaster 1.5 14 | T_SB2 EQU 3 ;Sound Blaster 2.x 15 | T_BB EQU 4 ;BlasterBoard 16 | T_BB2 EQU 5 ;BlasterBoard 2 17 | T_SBP EQU 6 ;Sound Blaster Pro 18 | T_SBP2 EQU 7 ;Sound Blaster Pro 2.x 19 | T_SB16 EQU 8 ;Sound Blaster 16 20 | 21 | 22 | Commande_DSP DB 0 23 | Frequence_DSP DB 0 24 | 25 | ;----------------------------------------------------------- 26 | ; 27 | ; Routines pour la Sound Blaster 28 | ; 29 | ;----------------------------------------------------------- 30 | 31 | SB_DSP_Init PROC NEAR 32 | 33 | MOV DX,SB_BasePort 34 | ADD DX,6 35 | MOV AL,1 36 | OUT DX,AL 37 | IN AL,DX 38 | IN AL,DX 39 | IN AL,DX 40 | IN AL,DX 41 | IN AL,DX 42 | IN AL,DX 43 | IN AL,DX 44 | IN AL,DX 45 | IN AL,DX 46 | IN AL,DX 47 | XOR AL,AL 48 | OUT DX,AL 49 | MOV AL,0D1h ; Active le HP 50 | CALL SB_DSP_Write 51 | RET 52 | 53 | SB_DSP_Init ENDP 54 | 55 | Fixer_stereo PROC NEAR 56 | 57 | MOV AL,0Eh 58 | MOV DX,SB_BasePort 59 | ADD DX,4 ; MixAddrPort (2x4h) 60 | OUT DX,AL ; Register 0Eh 61 | INC DX 62 | IN AL,DX ; Lecture registre 0Eh 63 | OR AL,2 ; Bit 1 � 1 64 | MOV AH,AL 65 | MOV AL,0Eh 66 | DEC DX 67 | OUT DX,AL 68 | INC DX 69 | MOV AL,AH 70 | OUT DX,AL ; Sortie registre 0Eh 71 | RET 72 | 73 | Fixer_stereo ENDP 74 | 75 | ; Set the Stereo, for Sound Blaster Pro 76 | Stop_stereo PROC NEAR 77 | 78 | MOV AL,0Eh 79 | MOV DX,SB_BasePort 80 | ADD DX,4 ; MixAddrPort (2x4h) 81 | OUT DX,AL 82 | INC DX 83 | IN AL,DX ; Register 0Eh 84 | AND AL,11111101b ; Bit 1 � 0 85 | MOV AH,AL 86 | MOV AL,0Eh 87 | DEC DX 88 | OUT DX,AL 89 | INC DX 90 | MOV AL,AH 91 | OUT DX,AL 92 | RET 93 | Stop_stereo ENDP 94 | 95 | Attendre_SB PROC NEAR 96 | 97 | MOV DX,SB_BasePort 98 | ADD DX,0Ch ;DSPWritePort 99 | XOR CX,CX ;Try 65536 Times 100 | bo_att_SB: 101 | IN AL,DX 102 | OR AL,AL 103 | JNS Fin_bo_att_SB 104 | LOOP bo_att_SB 105 | MOV Erreur_Modm,Err_SB ;Sound Blaster Timeout... 106 | ; MOV Stopper_Sortie,1 ;Stop the music 107 | ; CALL SB_DSP_Init 108 | Fin_bo_att_SB: 109 | RET 110 | 111 | Attendre_SB ENDP 112 | 113 | ;----------------------------------------------------------- 114 | ; SB_DSP_Write Sortie d'une commande vers le DSP 115 | ; 116 | ; Input: AL Command 117 | ;----------------------------------------------------------- 118 | 119 | SB_DSP_Write PROC Near 120 | CMP Erreur_Modm,Err_SB 121 | JE Pas_SB_DSP_Write 122 | PUSH CX 123 | PUSH AX 124 | CALL Attendre_SB 125 | POP AX 126 | OUT DX,AL 127 | POP CX 128 | Pas_SB_DSP_Write: 129 | RET 130 | SB_DSP_Write Endp 131 | 132 | ; Type de commande en fonction de la carte : 133 | ; 134 | ; Non continu Continu 135 | ; SB 1.0 14h N/A DSP 1.x ; No more supported. 136 | ; SB 1.5 14h 1Ch DSP 2.0 137 | ; SB 2.0 91h 90h DSP 2.1 138 | ; SBPro 91h 90h DSP 3.x 139 | ; SB 16 91h DSP 4.x 140 | ; BB 2 141 | 142 | SB_Start PROC NEAR 143 | 144 | ; CMP DMA_Continu,0 ; Not Autoinit DMA -> Command 14h 145 | ; JE Commande_DMA_14h ; ( Car envoi de la taille avec 48h ) 146 | 147 | CMP Type_SB,T_SB15 148 | JAE SB_Start_Autoinit ; Sound blaster 1.5+ => Comme la SBpro :) 149 | 150 | MOV Erreur_Modm,Err_SB ;Sound Blaster Timeout... 151 | ; MOV Stopper_Sortie,1 ;Stop the music 152 | 153 | RET 154 | 155 | Commande_DMA_14h: ; No more active for the moment. (For SB 1.0) 156 | 157 | ; MOV AL,40h ;Send the Frequency (SB/SBP/BB) 158 | ; CALL SB_DSP_Write 159 | ; MOV AL,SB_DMA_Frequency 160 | ; CALL SB_DSP_Write 161 | 162 | ; MOV Commande_DSP,014h 163 | ; MOV AL,14h ;DSP 14h : Not Continuous Slow DMA 164 | ; CALL SB_DSP_Write 165 | 166 | ; MOV AX,Buffer_Byte_Size 167 | ; DEC AX 168 | ; MOV AX,CX 169 | ; CALL SB_DSP_Write ;Envoyer Buffer_Samples_Nb-1 170 | ; XCHG AH,AL 171 | ; CALL SB_DSP_Write 172 | 173 | RET 174 | 175 | SB_Start_Autoinit: 176 | 177 | ;Load/Adjust the Output Buffers Size 178 | MOV CX,Buffer_Byte_Size 179 | CMP Out_16Bit,0 ; Output in 16 Bit ? 180 | JE Pas_BuffSB_16 181 | SHR CX,1 ; 16Bit > Size sent to the SB /2 182 | Pas_BuffSB_16: 183 | DEC CX ; CX, Taille du tampon... 184 | 185 | ; ** 1) Send the frequency ** 186 | 187 | CMP Type_SB,T_SB16 188 | JNE Use_SbFrequency 189 | CMP Mix_Mono_Use_Left,1 ; 16Bit to 8bit is always unsigned (SB16 command is alyays signed) 190 | JE Use_SbFrequency 191 | ; For SB16 Only 192 | MOV AL,041h ; DSP 41h : Set Frequency 193 | MOV Frequence_DSP,AL 194 | CALL SB_DSP_Write 195 | MOV AX,Real_Frequency 196 | XCHG AL,AH 197 | CALL SB_DSP_Write 198 | MOV AL,AH 199 | CALL SB_DSP_Write 200 | 201 | JMP Skip_SBFrequency 202 | Use_SbFrequency: 203 | ; For SB, BB, SBPro (BlasterBoard always use SB Frequency) 204 | MOV AL,40h ; DSP 40h : Set Frequency 205 | MOV Frequence_DSP,AL 206 | CALL SB_DSP_Write ; (SB 2.0/SB Pro) 207 | MOV AL,SB_DMA_Frequency 208 | CALL SB_DSP_Write ; Write the Frequency 209 | Skip_SBFrequency: 210 | 211 | ; ** 2) Send the Output command ** 212 | 213 | ; ** Autoinit DMA 8 Bit Unsigned DSP >= 1.5 214 | CMP Type_SB,T_BB2 215 | JE Start_SB16_Autoinit 216 | 217 | MOV Commande_DSP,1Ch ; 8 Bit Autoinit DMA (SB 1.5) 218 | CMP Type_SB,T_SB15 ; SB 1.5 219 | JE Start_SBSBPro_Autoinit 220 | 221 | MOV Commande_DSP,90h ; 8 Bit Autoinit DMA High Speed (SB2.0 SBPro) 222 | CMP Type_SB,T_SB16 223 | JNE Start_SBSBPro_Autoinit ; Command DSP <=4 224 | 225 | ; SB16 226 | Start_SB16_Autoinit: 227 | 228 | CMP Mix_Mono_Use_Left,1 ; 16Bit to 8bit is always unsigned so do SB/SBPro command 229 | JE Start_SBSBPro_Autoinit 230 | 231 | ; ** Autoinit High Speed DMA 8 Bit Signed DSP >= 4.00 (SB16 or more) ** 232 | 233 | MOV AL,0C6h ; DSP C6h : 8Bit DMA Output 234 | If UseMix16 Eq Yes 235 | CMP Out_16Bit,0 ; Output in 16 Bit ? 236 | JE Use_SB16_Signed8 237 | MOV AL,0B6h ; Yes -> DSP B6h : 16Bit DMA Output 238 | Use_SB16_Signed8: 239 | EndIf 240 | ; 8/16 Bit Autoinit DMA High Speed Output (SB16) 241 | MOV Commande_DSP,AL 242 | CALL SB_DSP_Write 243 | MOV AL,010h ; 10h : Mono Signed (Bit 4 Signed/Unsigned, Bit 5 Stereo/Mono) 244 | CMP Utilise_Stereo,1 245 | JNE @@nostereo 246 | MOV AL,020h ; 20h: Stereo Signed 247 | @@nostereo: 248 | CALL SB_DSP_Write ; write 2nd command byte 249 | MOV AL,CL ; lower part of size 250 | CALL SB_DSP_Write 251 | MOV AL,CH ; higher part of size 252 | CALL SB_DSP_Write 253 | 254 | JMP Fin_SB_StartPro 255 | 256 | ;** Autoinit High Speed DMA 8 Bit UnSigned DSP < 4.00 ** 257 | Start_SBSBPro_Autoinit: 258 | 259 | MOV AL,48h ; DSP 48h : Write the Size 260 | CALL SB_DSP_Write 261 | MOV AX,CX 262 | CALL SB_DSP_Write ; Partie basse de la taille 263 | XCHG AH,AL 264 | CALL SB_DSP_Write ; Partie haute de la taille 265 | 266 | MOV AL,Commande_DSP 267 | CALL SB_DSP_Write ; Lancer la commande Sortie DMA 268 | ; Auto Initialis�e (Sortie continue) 269 | Fin_SB_StartPro: 270 | RET 271 | 272 | SB_Start ENDP 273 | 274 | Restart_DMA_NC_SB Proc Near 275 | 276 | CALL Programmer_DMA 277 | 278 | MOV AL,14h 279 | CALL SB_DSP_Write 280 | 281 | MOV AX,Buffer_Byte_Size ; Commande 14h => Pas Stereo (Taille simple) 282 | DEC AX 283 | CALL SB_DSP_Write 284 | XCHG AH,AL 285 | CALL SB_DSP_Write 286 | 287 | RET 288 | Restart_DMA_NC_SB Endp 289 | 290 | 291 | ;----------------------------------------------------------------- 292 | ; SB_ComputeFrequency Calculs pour sortie DMA 293 | ; sur Sound Blaster 294 | ;----------------------------------------------------------------- 295 | 296 | SB_ComputeFrequency PROC NEAR 297 | ;Calculer l'octet a envoyer to la SB 298 | CMP Type_SB,T_SB16 299 | JE SB_ComputeFrequency_End ;The Sound Blaster 16 use the real frequency 300 | ; OK for BB2 as it does not use the real frequency 301 | 302 | PUSH AX 303 | MOV DX,15 ;(1000000/65536) Valeurs pour Mono 304 | MOV AX,16960 ;(1000000 MOD 65536) 305 | CMP Utilise_Stereo,1 306 | JNE Pas_Calc_Stereo1 307 | MOV DX,7 ;(500000 / 65536) ; Valeurs pour Stereo 308 | MOV AX,41248 ;(500000 MOD 65536) 309 | Pas_Calc_Stereo1: 310 | POP BX ;BX=Out_Frequency 311 | DIV BX 312 | MOV BX,256 313 | SUB BX,AX ;BX=256-1000000/fr�quence 314 | MOV SB_DMA_Frequency,BL 315 | ;Valeurs pour calculer la fr�quence 316 | ;des samples (Utilise la fr�quence r�elle SB) 317 | XOR BH,BH 318 | MOV AX,BX 319 | MOV BX,256 ;AX=Freq_DMA 320 | SUB BX,AX ;BX=256-Freq_DMA 321 | MOV DX,15 ;(1000000 / 65536) ; Valeurs pour Mono 322 | MOV AX,16960 ;(1000000 MOD 65536) 323 | CMP Utilise_Stereo,1 324 | JNE Pas_Calc_Stereo2 325 | MOV DX,7 ;(500000 / 65536) ; Valeurs pour Stereo 326 | MOV AX,41248 ;(500000 MOD 65536) 327 | Pas_Calc_Stereo2: 328 | DIV BX ;AX=1000000/256-Freq_DMA 329 | 330 | SB_ComputeFrequency_End: 331 | RET 332 | 333 | SB_ComputeFrequency ENDP 334 | -------------------------------------------------------------------------------- /ASM/SS.BAT: -------------------------------------------------------------------------------- 1 | COPY ADLIB.ASM SS\ 2 | COPY FFT.ASM SS\ 3 | COPY GUSCMD.ASM SS\ 4 | COPY TDY.ASM SS\ 5 | COPY MODM_SS.ASM SS\ 6 | COPY MIXAGE.ASM SS\ 7 | COPY RADPLAY.ASM SS\ 8 | COPY IMFDROP.ASM SS\ 9 | COPY SBCMD.ASM SS\ 10 | COPY CONSTAFF.INC SS\ 11 | COPY CONSTMM.INC SS\ 12 | COPY HARDWARE.INC SS\ 13 | 14 | 15 | -------------------------------------------------------------------------------- /ASM/Speaker.asm: -------------------------------------------------------------------------------- 1 | .MODEL small 2 | .STACK 100h 3 | 4 | Yes Equ 0 5 | No Equ -1 6 | 7 | b Equ Byte Ptr 8 | w Equ Word Ptr 9 | d Equ DWord Ptr 10 | 11 | HW_NoMODM Equ Yes 12 | 13 | .DATA 14 | Msg_Start DB 'Speaker Test Code',13,10,'$' 15 | Msg_CRLF DB 13,10,'$' 16 | 17 | 18 | Sample DB 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16 19 | 20 | .CODE 21 | Main Proc 22 | mov ax,@data 23 | mov ds,ax ;set DS to point to the data segment 24 | 25 | mov dx,OFFSET Msg_Start 26 | call PrintStr_DOS 27 | 28 | MOV ax,1234 29 | 30 | PUSH AX 31 | PUSH BX 32 | PUSH CX 33 | PUSH DX 34 | XOR AH,AH 35 | CALL PrintAX_Dec_DOS 36 | POP DX 37 | POP CX 38 | POP BX 39 | POP AX 40 | 41 | 42 | DOS_Terminate 43 | 44 | Main Endp 45 | 46 | ; CS Data 47 | P_Speed DB 2 48 | 49 | DOS_GetVersion Macro 50 | mov ah,30h 51 | int 21h 52 | Endm 53 | 54 | DOS_Terminate Macro 55 | mov ah,4ch ;DOS terminate program function 56 | int 21h ;terminate the program 57 | Endm 58 | 59 | Include PrintDOS.asm 60 | Include hardware.asm 61 | 62 | ;IRQ Timer code, Taken from Mod Master 63 | 64 | SampleLength DW 16 65 | Buffer_Cnt DW 0 66 | 67 | IRQ_Timer_PCS: 68 | 69 | PUSH DS 70 | PUSH AX 71 | 72 | ; ****** Read the Buffer Data 73 | MOV AX,1234h ; DS=Segment de la table de volume et Tampons 74 | IRQ_PCS_Seg_Volume: 75 | MOV DS,AX 76 | MOV AL,Byte Ptr DS:[1234h] 77 | IRQ_PCS_Index: 78 | 79 | PUSH AX 80 | PUSH BX 81 | PUSH CX 82 | PUSH DX 83 | XOR AH,AH 84 | CALL PrintAX_Dec_DOS 85 | POP DX 86 | POP CX 87 | POP BX 88 | POP AX 89 | 90 | OUT 42h,AL ; Reset the Timer 2 Value 91 | 92 | INC W CS:[Offset IRQ_PCS_Index-2] 93 | 94 | MOV AL,20h 95 | OUT 20h,AL 96 | 97 | DEC CS:Buffer_Cnt 98 | JZ IRQ_Timer_PCS_NextBuffer 99 | 100 | POP AX 101 | POP DS 102 | IRET 103 | 104 | IRQ_Timer_PCS_NextBuffer: 105 | 106 | PUSH CS 107 | POP DS 108 | 109 | MOV AX,SampleLength 110 | MOV Buffer_Cnt,AX 111 | 112 | MOV AX,Offset Sample 113 | MOV W CS:[Offset IRQ_PCS_Index-2],AX 114 | 115 | POP AX 116 | POP DS 117 | IRET 118 | 119 | 120 | EnableSpeakerPWM Proc Near 121 | IN AL,61h ; Activate the PC Speaker (Port B Bit 0 and 1) 122 | OR AL,03h 123 | OUT 61h,AL 124 | 125 | mov al,TIMER2+LSB+MODE0+BINARY ; 10010000b 126 | out 43h,al 127 | mov al,01h 128 | out 42h,al ; Counter 2 count = 1 - terminate count quickly 129 | 130 | ret 131 | EnableSpeakerPWM Endp 132 | 133 | DisableSpeaker Proc Near 134 | IN AL,61h ; Stopper le H.P. Interne 135 | AND AL,0FCh 136 | OUT 61h,AL 137 | ret 138 | DisableSpeaker Endp 139 | 140 | Restore_Timer Proc Near 141 | CLI 142 | XOR AX,AX 143 | CALL Set_Timer0_Period ;(Use AX Only) 144 | CALL Restore_Timer_IRQ ;(Don't change Regs) 145 | STI 146 | Restore_timer Endp 147 | 148 | TimeAdr dw 06Ch,040h 149 | 150 | SpeedTest Proc near 151 | push ds 152 | push si 153 | 154 | xor dx,dx ; "Speed" Value 155 | lds si,cs:[dword ptr TimeAdr] 156 | mov bx,[ds:si] 157 | @@EDGE: cmp bx,[ds:si] ; Detect the edge of the timer 158 | je @@EDGE 159 | inc bx 160 | 161 | SpeedTestLoop: 162 | push dx 163 | REPT 32 164 | NOP 165 | ENDM 166 | pop dx 167 | inc dx 168 | cmp bx,[ds:si] 169 | je SpeedTestLoop 170 | 171 | mov ax,dx 172 | 173 | pop si 174 | pop ds 175 | ret 176 | SpeedTest endp 177 | 178 | END -------------------------------------------------------------------------------- /ASM/TDY.ASM: -------------------------------------------------------------------------------- 1 | ; Tandy 3 Channels chip Code 2 | 3 | TDYLPTPort DW 0 4 | 5 | ; Init the TDYLPT Base Ports if Selected. 6 | Init_TDY Proc Near 7 | 8 | CMP TDY_Type,0 9 | JE Not_Init_TDY 10 | CMP TDY_Type,2 11 | JNE Not_Init_TDYLPT 12 | 13 | MOV AX,LPT1_Port 14 | CMP TDY_LPT_Nb,1 15 | JE Save_TDYLPTPort 16 | MOV AX,LPT2_Port 17 | Save_TDYLPTPort: 18 | MOV TDYLPTPort,AX 19 | 20 | ;Unmute the Tandy LPT 21 | MOV DX,AX 22 | INC DX 23 | INC DX 24 | 25 | MOV AL,07h 26 | OUT DX,AL 27 | MOV CX,100 28 | TDYLPT_Delay: 29 | IN AL,DX 30 | LOOP TDYLPT_Delay 31 | MOV AL,09h 32 | OUT DX,AL 33 | 34 | Not_Init_TDYLPT: 35 | 36 | CALL TDY_Mute 37 | 38 | Not_Init_TDY: 39 | 40 | RET 41 | Init_TDY Endp 42 | 43 | ; Set all the channels volume to 0 44 | TDY_Mute Proc Near 45 | MOV AL,10011111b ; Ch1 Off 46 | CALL TDY_Out 47 | MOV AL,10111111b ; Ch2 Off 48 | CALL TDY_Out 49 | MOV AL,11011111b ; Ch3 Off 50 | CALL TDY_Out 51 | MOV AL,11111111b ; Noise Off 52 | CALL TDY_Out 53 | RET 54 | TDY_Mute Endp 55 | 56 | ; Set a Tandy Chamnnel to 0 57 | ; Input: BX Channel number 58 | TDY_Mute_Channel Proc Near 59 | 60 | CMP BX,4 61 | JA TDY_Mute_Channel_End 62 | 63 | PUSH AX 64 | PUSH CX 65 | MOV AX,BX 66 | AND AL,00000011b 67 | MOV CL,5 68 | SHL AL,CL 69 | XOR AL,10011111b 70 | 71 | CALL TDY_Out 72 | 73 | POP CX 74 | POP AX 75 | TDY_Mute_Channel_End: 76 | RET 77 | TDY_Mute_Channel Endp 78 | 79 | ; Output a Byte to the Tandy Port 80 | ; TDYLPT Code provided by Benedikt 81 | ; Input: AL Value 82 | ; Change: ax,dx, flags 83 | TDY_Out Proc Near 84 | CMP TDY_Type,2 ; 2: TDYLPT 85 | JE TDYLPT_Out 86 | 87 | MOV DX,TDY_Port 88 | OUT DX,AL 89 | RET 90 | 91 | TDYLPT_Out: 92 | 93 | mov dx,cs:TDYLPTPort 94 | out dx,al ; Send the Value 95 | inc dx 96 | inc dx 97 | 98 | mov al,0Ch ; Use the LPT Command Line to simulate the IOW 99 | out dx,al ; Out 0Ch 100 | dec dx 101 | mov ah,24 ; 24 loop max 102 | @l1: dec ah 103 | js @l2 104 | in al,dx 105 | and al,40h 106 | jnz @l1 107 | @l2: dec ah 108 | js @l2end 109 | in al,dx 110 | and al,40h 111 | jz @l2 112 | @l2end: inc dx 113 | mov al,9 114 | out dx,al ; Out 09h 115 | 116 | RET 117 | TDY_Out Endp -------------------------------------------------------------------------------- /ASM/TDYDAC.ASM: -------------------------------------------------------------------------------- 1 | ; Tandy DAC Code 2 | 3 | TDYDAC_ClockSpeed Equ 3579545 ; Not used 4 | TDYDAC_ClockSpeedH Equ 36h 5 | TDYDAC_ClockSpeedL Equ 9E99h 6 | 7 | TDYDAC_Frequency DW 0 ; Value to send to the Tandy DAC ( 3.5MHz / Frequency ) 8 | 9 | 10 | ; Get the Real DAC Output frequency from the requested frequency 11 | ; Input : AX, Output Frequency 12 | ; Output: AX, Real Frequency 13 | TDYDAC_ComputeFrequency Proc Near 14 | 15 | MOV BX,Out_Frequency 16 | MOV AX,TDYDAC_ClockSpeedL 17 | MOV DX,TDYDAC_ClockSpeedH 18 | DIV BX 19 | MOV TDYDAC_Frequency,AX ; Value to be sent to the DAC 20 | 21 | MOV BX,AX 22 | MOV AX,TDYDAC_ClockSpeedL 23 | MOV DX,TDYDAC_ClockSpeedH 24 | DIV BX 25 | MOV Real_Frequency,AX ; Real Frequency (To adjust the buffers size) 26 | 27 | RET 28 | TDYDAC_ComputeFrequency EndP 29 | 30 | ; Start the Tandy DAC 31 | ; DMA and IRQ need to be configured before 32 | 33 | ;Port 0C4h (1E4h, 304h) DAC Mode Register 34 | ;Bits 0-2 and 4-6 are read/write 35 | ; 36 | ; Bit(s) Meaning 37 | ; ------ ------- 38 | ; 0-1 DAC function select: 0 = joystick, 1 = sound channel 39 | ; (fourth tone channel, used with 3-voice chip), 2 = 40 | ; successive approximation (sound input), 3 = direct write 41 | ; to DAC (sound output). 42 | ; 2 DMA enable (if bit 1 = 1). 0 = DMA disabled, 1 = DMA enabled. 43 | ; 3 (read) 1 = DMA interrupt has occurred. 44 | ; 3 (write) DMA interrupt clear. 0 = DMA interrupt held clear, 1 = DMA 45 | ; interrupt allowed. When DMA interrupt occurs, this bit 46 | ; must be set low, then set high to allow another interrupt. 47 | ; 4 DMA interrupt enable. 0 = DMA EOP interrupt disabled, 1 = 48 | ; DMA EOP interrupt enabled. 49 | ; 5 Sound divider sync enable. 0 = synchronization disabled, 1 = 50 | ; synchronization enabled. See below. 51 | ; 6 Sound chip extra divide enable. 0 = extra divide disabled 52 | ; (10-bit dividers for 3-voice tone generator), 1 = extra 53 | ; divide enabled (11-bit dividers). 54 | ; 7 (read) 0 = Successive approximation done. When polling for input, 55 | ; indicates that a byte of sound is ready to read at port 56 | ; 0C5h (1E5h, 305h). 57 | 58 | 59 | TDYDAC_Start Proc Near 60 | 61 | ; Set DAC Speed 62 | MOV AX,TDYDAC_Frequency 63 | MOV DX,TDYDAC_Port 64 | ADD DX,2 ; program low byte of speed 65 | OUT DX,AL 66 | INC DX ; program high byte of speed (+ Volume 0) 67 | MOV AL,AH 68 | OUT DX,AL 69 | 70 | ; Start the DAC 71 | MOV DX,TDYDAC_Port ; Direct write to DAC, DMA enabled, DMA 72 | MOV AL,17h ; interrupt enabled, DMA interrupt clear 00010111b 73 | OUT DX,AL 74 | MOV AL,1Fh ; Direct write to DAC, DMA enabled, DMA 75 | OUT DX,AL ; Interrupt enabled, DMA interrupt allowed 00011111b 76 | 77 | MOV AL,7 78 | CALL TDYDAC_SetVol 79 | 80 | RET 81 | TDYDAC_Start Endp 82 | 83 | ; Set the Tandy Chip to 3 Channels 84 | ; Change AX, DX 85 | TDYDAC_Stop Proc Near 86 | 87 | MOV DX,TDYDAC_Port 88 | MOV AL,00000001b ; DMA Disabled, Sound Channel Mode 89 | OUT DX,AL 90 | 91 | RET 92 | TDYDAC_Stop Endp 93 | 94 | ; AL:Volume (0-7) 95 | ; Change AX, DX 96 | TDYDAC_SetVol Proc Near 97 | MOV DX,TDYDAC_Port ; DX is volume port 98 | ADD DX,3 99 | 100 | ROR AL,1 101 | ROR AL,1 102 | ROR AL,1 103 | MOV AH,AL ; most significant 3 bits of AH = volume 104 | CLI 105 | IN AL,DX ; get DAC amplitude/frequency MSB 106 | AND AL,1Fh ; mask out old volume 107 | OR AL,AH ; put in new volume 108 | OUT DX,AL ; write back DAC amplitude/frequency MSB 109 | RET 110 | TDYDAC_SetVol Endp -------------------------------------------------------------------------------- /ASM/TESTMIX.asm: -------------------------------------------------------------------------------- 1 | .MODEL small 2 | 3 | .STACK 100h 4 | 5 | .DATA 6 | 7 | 8 | .CODE 9 | 10 | Mix_8_Code: 11 | MOV AL,ES:[DI] 12 | MOV BL,[SI] 13 | ADD AL,ES:[BX] 14 | STOSB 15 | ADD DX,CX 16 | ADC SI,BP 17 | Mix_8_CodeEnd: 18 | 19 | Mix_8_Code2: 20 | MOV AX,ES:[DI] 21 | MOV BL,[SI] 22 | ADD AL,ES:[BX] 23 | ADD DX,CX 24 | ADC SI,BP 25 | MOV BL,[SI] 26 | ADD AH,ES:[BX] 27 | STOSW 28 | ADD DX,CX 29 | ADC SI,BP 30 | Mix_8_Code2End: 31 | 32 | Mix_8_Code2v2: 33 | MOV AX,ES:[DI] 34 | ADD DX,CX 35 | MOV BL,[SI] 36 | ADC SI,BP 37 | ADD AL,ES:[BX] 38 | ADD DX,CX 39 | MOV BL,[SI] 40 | ADC SI,BP 41 | ADD AH,ES:[BX] 42 | STOSW 43 | Mix_8_Code2Endv2: 44 | 45 | Mix_8M_Code: 46 | MOV BL,[SI] 47 | MOV AL,ES:[BX] 48 | STOSB 49 | ADD DX,CX 50 | ADC SI,BP 51 | Mix_8M_CodeEnd: 52 | 53 | Mix_8M_Code2: 54 | MOV BL,[SI] 55 | MOV AL,ES:[BX] 56 | ADD DX,CX 57 | ADC SI,BP 58 | MOV BL,[SI] 59 | MOV AH,ES:[BX] 60 | STOSW 61 | ADD DX,CX 62 | ADC SI,BP 63 | Mix_8M_Code2End: 64 | 65 | ; XLAT 66 | MOV AL,ES:[SI] ; Read Sample 67 | ADD DX,CX 68 | ADC SI,BP ; Move Sample Index 69 | XLATB ; Apply the Volume (MOV AL,DS:[BX+AL]) [11] 70 | ADD [DI],AL ; Add to the Buffer 71 | INC DI ; Move to Next Buffer Byte [3] 72 | MOV AL,ES:[SI] ; Read Sample 73 | ADD DX,CX 74 | ADC SI,BP ; Move Sample Index 75 | XLATB ; Apply the Volume (MOV AL,DS:[BX+AL]) 76 | ADD [DI],AL ; Add to the Buffer 77 | INC DI ; Move to Next Buffer 78 | 79 | ; XLAT and LODSB STOSW 80 | 81 | ADD DX,CX 82 | LODSB ; Read Sample 83 | SEGES XLATB ; Apply the Volume (MOV AL,DS:[BX+AL]) [11] 84 | ADC SI,BP ; Move Sample Index 85 | ADD AL,ES:[DI] ; Add to the Buffer 86 | XCHG AL,AH 87 | ADD DX,CX 88 | LODSB ; Read Sample 89 | SEGES XLATB ; Apply the Volume (MOV AL,DS:[BX+AL]) 90 | ADC SI,BP ; Move Sample Index 91 | ADD AL,ES:[DI+1] ; Add to the Buffer 92 | XCHG AL,AH 93 | STOSW 94 | 95 | ADD DX,CX 96 | LODSB ; Read Sample 97 | SEGES XLATB ; Apply the Volume (MOV AL,DS:[BX+AL]) [11] 98 | ADC SI,BP ; Move Sample Index 99 | ADD ES:[DI],AL ; Add to the Buffer 100 | INC DI 101 | ADD DX,CX 102 | LODSB ; Read Sample 103 | SEGES XLATB ; Apply the Volume (MOV AL,DS:[BX+AL]) 104 | ADC SI,BP ; Move Sample Index 105 | ADD ES:[DI],AL ; Add to the Buffer 106 | INC DI 107 | 108 | END -------------------------------------------------------------------------------- /ASM/VGA.INC: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/ASM/VGA.INC -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Mod Master XT 2 | 3 | I finally decided to Realease the Mod Master XT Source code, so that it can benefit to all the community and see if somebody can do something with it :) 4 | It will also motivate me to update the code form time to time. 5 | 6 | And Yes, it is the first commit to a Git for Mod MAster XT, I wrote it totally without versionning tool. 7 | 8 | Initial Commit is Rev 1.01 (If I am not wrong) 9 | -------------------------------------------------------------------------------- /RELEASES/MODM.REV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODM.REV -------------------------------------------------------------------------------- /RELEASES/MODMXT10.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT10.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT100.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT100.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT12.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT12.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT13.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT13.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT14.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT14.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT15.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT15.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT16.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT16.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT17.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT17.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT18.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT18.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT19.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT19.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT20.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT20.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT21.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT21.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT22.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT22.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT24.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT24.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT25.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT25.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT26.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT26.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT8.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT8.zip -------------------------------------------------------------------------------- /RELEASES/MODMXT9.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/RELEASES/MODMXT9.zip -------------------------------------------------------------------------------- /TP/MMCONV.PAS: -------------------------------------------------------------------------------- 1 | { Convert modules to the .MMM File Format } 2 | 3 | PROGRAM MMCONV; 4 | {$A+,G-,Q-,R-,S-} 5 | 6 | USES CRT,DOS,Clavier,Util,MM_VAR,MM_DIV,MMSS_Var,SAV_MMM,MODMUnit, 7 | ChMOD,CHS3M,CHXM,Ch669,ChDTM,ChMTM,ChFAR,ChSTM,ChULT,ChMMM; 8 | 9 | {$M 16384,0,24576} 10 | 11 | VAR 12 | MM_Error : Word; 13 | KeyVal : Word; 14 | 15 | i,j : Byte; 16 | nbr_param : Byte; 17 | long_repert:Byte; 18 | ExtNr: Byte; { Extension number from the supported extention list} 19 | 20 | erreur : Byte; 21 | 22 | Info : SearchRec; 23 | DirStr_Size : Word; 24 | Param : String; 25 | Repert : String; 26 | DirStr : String; 27 | SearchStr : String; 28 | 29 | SourceFilename : String; 30 | DestFilename : String; 31 | 32 | 33 | BEGIN 34 | 35 | Writeln('Mod Master file Converter'); 36 | Writeln('Convert any Module to .MMM'); 37 | 38 | nbr_param:=ParamCount; 39 | 40 | If ParamCount<>1 then 41 | Begin 42 | Writeln(' Command line : MMCONV Filename'); 43 | Writeln(' > *.MOD to convert all the .MOD files.') 44 | End 45 | Else 46 | 47 | Begin 48 | 49 | MMSS_Init(True,False); {Always place this first } 50 | 51 | SearchStr:=ParamStr(1); 52 | 53 | { Build the Directory String } 54 | i:=Length(SearchStr); 55 | DirStr_Size:=0; 56 | DirStr:=''; 57 | Repeat 58 | If (SearchStr[i] in ['\',':']) Then DirStr_Size:=i; 59 | Dec(i) 60 | Until (i=0) or (DirStr_Size>0); 61 | If DirStr_Size>0 Then DirStr:=Copy(SearchStr,1,DirStr_Size); 62 | 63 | 64 | { Writeln('Directory: ',DirStr); 65 | Writeln('Search ',SearchStr);} 66 | 67 | MMSS_CFG^.Wave_Output:=HPInt; { Force an Output with Samples in memory } 68 | 69 | FindFirst (SearchStr,AnyFile,Info); 70 | While DOSError=0 do 71 | Begin 72 | With Info do 73 | Begin 74 | If (Attr and Directory) <> Directory then 75 | Begin 76 | SourceFilename:=DirStr+Name; 77 | 78 | i:=Length(Name); 79 | j:=0; 80 | Repeat 81 | If (Name[i]='.') Then j:=i-1; 82 | Dec(i) 83 | Until (i=0) or (j>0); 84 | If j>0 Then 85 | DestFilename:=Copy(Name,1,j) {Remove any extention} 86 | Else 87 | Begin 88 | Writeln(' Filename error : No extension'); 89 | Exit; 90 | End; 91 | 92 | Write('Load File : ',SourceFilename); 93 | 94 | Case Extension(Name) of 95 | ext_MOD, 96 | ext_NST, 97 | ext_WOW, 98 | ext_SD0, 99 | ext_OCT: Charge_MOD(SourceFilename,MM_Error); 100 | ext_S3M: Charge_S3M(SourceFilename,MM_Error); 101 | ext_XM : Charge_XM(SourceFilename,MM_Error); 102 | ext_669: Charge_669(SourceFilename,MM_Error); 103 | ext_DTM: Charge_DTM(SourceFilename,MM_Error); 104 | ext_MTM: Charge_MTM(SourceFilename,MM_Error); 105 | ext_ULT: Charge_ULT(SourceFilename,MM_Error); 106 | ext_FAR: Charge_FAR(SourceFilename,MM_Error); 107 | ext_STM: Charge_STM(SourceFilename,MM_Error); 108 | {ext_MMM: Charge_MMM(SourceFilename,MM_Error);} 109 | Else MM_Error:=Err_Non_Gere; 110 | End; 111 | 112 | If MM_Error = 0 then 113 | Begin 114 | Writeln(' > Save File : ',DestFilename,'.MMM'); 115 | 116 | If MMSS_MUS_Loaded Then 117 | Save_MMM(DestFilename+'.MMM',ExtensionSeule(Name),MM_Error); 118 | End { MM_Error=0 } 119 | Else If MM_Error=Err_Non_Gere then 120 | Writeln(' Not a supported file') 121 | else Writeln(' Error ',Erreur); 122 | 123 | End; { <> Directory } 124 | 125 | End; { With } 126 | 127 | FindNext(Info); 128 | End; {While DOSError = 0 } 129 | 130 | Writeln('The End...'); 131 | 132 | End; {Nb of parameter invalid} 133 | 134 | END. -------------------------------------------------------------------------------- /TP/PLAYMOD.PAS: -------------------------------------------------------------------------------- 1 | { Minimal Code to use MODM Sound System } 2 | 3 | PROGRAM PlayMOD; 4 | {$A+,G-,Q-,R-,S-} 5 | {$I MODMCFG.INI} 6 | 7 | USES CRT,Clavier,texte,Modm_SS,MMSS_Var,MMSS_CMD,ChMOD; 8 | 9 | { Use ChMOD to Load . MOD and so on } 10 | 11 | {$IFDEF MIX16} 12 | {$M 16384,0,51000} { Do not use all the DOS Memory for the Heap } 13 | {$ELSE} 14 | {$M 16384,0,38000} { Do not use all the DOS Memory for the Heap } 15 | {$ENDIF} 16 | 17 | VAR 18 | Error : Word; 19 | KeyVal : Word; 20 | 21 | 22 | CONST 23 | 24 | MODFile : String = 'C:\MOD\STARDUST.MOD'; 25 | 26 | BEGIN 27 | 28 | MMSS_Init(True,True); {Always place this first } 29 | 30 | Writeln('Loading ',MODFile); 31 | 32 | { Example: Force the SBPro Output } 33 | { Don't force the output to a not existing Output } 34 | 35 | { WaveOut_SetDefault(SBPro);} 36 | MMSS_CFG^.Out_Frequency:=22000; 37 | 38 | { Charge_xm('C:\JT_POOLS.XM',Error);} 39 | Charge_mod(MODFile,Error); 40 | {Charge_mmm('C:\MOD\STARDUST.MMM',Error);} 41 | 42 | If Error<>0 then { Loader Error Code Test } 43 | Begin 44 | Writeln(' Error Starting the Module: ',Error); 45 | Halt; 46 | End; 47 | 48 | If MMSS_MUS_Loaded Then 49 | If MMSS_Start_Music=0 Then 50 | Begin 51 | Writeln(''); 52 | Writeln('Output: ',MMSS_Output_Name[MMSS_CFG^.Wave_Output]); 53 | If MMSS_CFG^.Wave_Output<>GUS Then Writeln('Frequency: ',MMSS_CFG^.Out_Frequency); 54 | MMSS_Start_Output; { Start the Module } 55 | End; 56 | 57 | If MMSS_CFG^.MMSS_Error<>0 then { MMSS Error Code Test } 58 | Begin 59 | Writeln(' Error Starting the Module: ',Error); 60 | Halt; 61 | End; 62 | 63 | Repeat 64 | If Keypressed Then 65 | Begin 66 | KeyVal:=UpCase(ReadKey); 67 | Case KeyVal of 68 | Esc : Break; 69 | End; 70 | End; 71 | Until MMSS_CFG^.Output_Stopped; 72 | 73 | MMSS_Stop_Output; { Stopper la sortie sonore } 74 | MMSS_Stop_Musique; { Stopper la musique } 75 | Writeln('The End...'); 76 | END. -------------------------------------------------------------------------------- /TP/TESTMMD.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TP/TESTMMD.PAS -------------------------------------------------------------------------------- /TPUNIT/BIOSEQU.PAS: -------------------------------------------------------------------------------- 1 | { 2 | This is a complete map of PC, XT, AT, PS/2 and EGA-installed data 3 | areas between 0400h and 0500h in the low memory segment put into the 4 | form of a Turbo Pascal 4/5/5.5 compatible unit. 5 | 6 | I found myself needing one or two of these absolute addresses from time 7 | to time and got tired of looking them up. Using a record structure 8 | declared as absolute variable relieves you of specifying the 9 | individual addresses for each variable, providing that all the Resrved 10 | areas are included too. 11 | 12 | I hope this saves all those Turbo Pascal programmers out there some time 13 | and lets them get on with the creative side of the business. Enjoy! 14 | 15 | David Gwillim 16 | 159 Woodbury Road 17 | Hicksville, NY 11801-3030 18 | (516) 942-8697 19 | 20 | 6 August 1989 21 | 22 | CREDITS: 23 | 24 | The absolute addresses for this unit came from "The Programmer's PC 25 | Sourcebook" by Thom Hogan, published by Microsoft Press. 26 | ISBN 1-55615-118-7. List price $24.95 USA. 27 | 28 | This book is very helpful (apart from a few inevitable) typos). I 29 | consider it an essential purchase for any programmer who has to deal 30 | with a PC at the hardware level. 31 | 32 | } 33 | 34 | UNIT BiosEqu; 35 | 36 | INTERFACE 37 | 38 | Var 39 | BiosSeg : Record 40 | ComBase : Array[1..4] of Word; 41 | LptBase : Array[1..4] of Word; 42 | InstalledHardware : Word; 43 | POST_Status : Byte; { Convertible only } 44 | MemorySize : Word; 45 | _RESERVED1 : Word; 46 | KeyboardControl : Array[1..2] of byte; 47 | AlternateKeypadEntry : byte; 48 | KeyboardBufferHeadPtr : word; { points to first char in type-ahead buffer } 49 | KeyboardBufferTailPtr : word; { points to last char in type-ahead buffer } 50 | KeyboardBuffer : Array[1..16] of word; 51 | FloppyRecalStatus : byte; 52 | FloppyMotorStatus : byte; 53 | FloppyMotorOffCounter : byte; 54 | FloppyPrevOpStatus : byte; 55 | FloppyControllerStatus : array[1..7] of byte; 56 | DisplayMode : byte; 57 | NumberOfColumns : word; 58 | RegenBufferLength : word; 59 | RegenBufferAddress : word; 60 | CursorPosition : array[1..8] of word; 61 | CursorType : word; 62 | CurrentDisplayPage : byte; 63 | VideoControllerBaseAddress : word; 64 | Current3x8Register : byte; 65 | Current3x9Register : byte; 66 | PointerToResetCode : pointer; { PS/2 only - except model 30 } 67 | _RESERVED2 : byte; 68 | TimerCounter : longint; 69 | TimerOverflowFlag : byte; { non-zero means timer passed 24 hours } 70 | BreakKeyState : byte; 71 | ResetFlag : word; { $1234=bypass mem test; $4321=preserve mem (PS/2) } 72 | { $5678=system supended (Convertible) } 73 | { $9ABC=manufacturing test (Convertible) } 74 | { $ABCD=system POST loop (Convertible only) } 75 | FixedDiskPrevOpStatus : byte; 76 | NumberOfFixedDrives : byte; 77 | FixedDiskDriveControl : byte; {XT only} 78 | FixedDiskControllerPort : byte; {XT only} 79 | LptTimeOut : array[1..4] of byte; { [4] valid for PC, XT and AT only } 80 | ComTimeOut : array[1..4] of byte; 81 | KeyboardBufferStartOffsetPtr :word; 82 | KeyboardBufferEndOffsetPtr :word; 83 | VideoRows : byte; 84 | CharacterHeight : word; { bytes per character } 85 | VideoControlStates : array[1..2] of byte; 86 | 87 | _RESERVED3 : word; 88 | MediaControl : byte; 89 | FixedDiskControllerStatus : byte; { AT, XT after 1/10/85, PS/2 only } 90 | FixedDiskControllerErrorStatus : byte; { AT, XT after 1/10/85, PS/2 only } 91 | FixedDiskInterruptControl : byte; { AT, XT after 1/10/85, PS/2 only } 92 | _RESERVED4 : byte; 93 | DriveMediaState : array[0..1] of byte; 94 | _RESERVED5 : word; 95 | DriveCurrentCylinder : array[0..1] of byte; 96 | KeyboardModeState : byte; 97 | KeyboardLEDflags : byte; 98 | UserWaitCompleteFlagAddress : pointer; 99 | UserWaitCount : longint; { micro-seconds } 100 | WaitActiveFlag : byte; 101 | _RESERVED6 : array[1..7] of byte; 102 | VideoParameterTable : pointer; { EGA and PS/2 only } 103 | DynamicSaveArea : pointer; { EGA and PS/2 only } 104 | AlphaModeAuxCharGenerator : pointer; { EGA and PS/2 only } 105 | GraphicsModeAuxCharGenerator : pointer; { EGA and PS/2 only } 106 | SecondarySaveArea : pointer; { PS/2 only (not Model 30) } 107 | _RESERVED7 : array[1..4] of byte; 108 | _RESERVED8 : array[1..64] of byte; 109 | PrintScreenStatus : byte; 110 | end absolute $0040:$0000; 111 | 112 | implementation 113 | 114 | end. -------------------------------------------------------------------------------- /TPUNIT/CH669.PAS: -------------------------------------------------------------------------------- 1 | {************************************************************************} 2 | { CH669.PAS } 3 | { } 4 | { Loader pour les fichiers 669 (par TRAN de Renaissance) et E669. } 5 | { } 6 | { AUTEUR: Freddy Vetele. } 7 | { } 8 | { Debut d'ecriture le --/11/94 } 9 | { Dernieres modifications le 02/11/95 } 10 | {************************************************************************} 11 | 12 | {$UNDEF Groupe} 13 | {$DEFINE NoGUS} 14 | 15 | {$IFNDEF Groupe} 16 | UNIT Ch669; 17 | {$ELSE} 18 | UNIT Ch669_G; 19 | {$ENDIF} 20 | 21 | {$A+,Q-,R-,S-} 22 | 23 | INTERFACE 24 | 25 | {$IFNDEF Groupe} 26 | USES Fichiers,Util,Chutil,MMSS_Var,CRT,MMSS_Mem; 27 | {$ELSE} 28 | USES Fich_grp,Util,Chutil_G,MMSS_Var,CRT,MMSS_Mem; 29 | {$ENDIF} 30 | 31 | {==========================================================} 32 | 33 | PROCEDURE Charge_669(chemin: String80; Var erreur: Word); 34 | 35 | {==========================================================} 36 | 37 | IMPLEMENTATION 38 | 39 | CONST 40 | Max_Samples_669=64; 41 | Ident669=$6669; { 'if' } 42 | IdentUni669=$4E4A; { 'jn' } 43 | TYPE 44 | TSizes=ARRAY[1..128] of byte; 45 | 46 | T669Header= 47 | RECORD 48 | Ident : WORD; 49 | Comment : ARRAY[1..3, 1..36] of CHAR; 50 | NSamples : BYTE; 51 | NPatterns : BYTE; 52 | RepStart : BYTE; 53 | Sequence : Byte128; 54 | Tempos : ARRAY[1..128] of BYTE; 55 | Lengths : TSizes; 56 | END; 57 | 58 | T669Instrument= 59 | RECORD 60 | Name : ARRAY[1..13] of CHAR; 61 | Size : LONGINT; 62 | RepStart : LONGINT; 63 | Replen : LONGINT; 64 | END; 65 | 66 | T669Pattern = ARRAY[1..64,1..8] of 67 | RECORD 68 | CASE BYTE of 69 | 0 : ( w1: WORD; 70 | b : BYTE ); 71 | 1 : ( b1,b2,b3:BYTE); 72 | END; 73 | 74 | Ptr_En_tete_669=^T669Header; 75 | 76 | {---------------------------------------------------------} 77 | 78 | PROCEDURE Charger_pattern(VAR Sizes:TSizes;Num:WORD); 79 | 80 | VAR 81 | Patt : T669Pattern; 82 | Pattern : Ptr_Patt; 83 | i,j :WORD; 84 | t,n :WORD; 85 | 86 | Begin 87 | 88 | {*** Charge les patterns ***} 89 | 90 | FOR n:=1 to Num do 91 | BEGIN 92 | IF Not MMSS_MemAlloc(Pointeur_actuel,24*8,False,False) Then EXIT; 93 | MMSS_Table^.Seg_Pattern[n]:=SEG(Pointeur_actuel^); 94 | Musique^.Taille_Pattern[n]:=Sizes[n]+1; 95 | 96 | Pattern:=Pointeur_actuel; 97 | f_module.Lit(Patt,SizeOf(Patt)); 98 | For j:=1 to 8 do 99 | BEGIN 100 | For i:=1 to 64 do 101 | WITH Patt[i][j] do 102 | BEGIN 103 | C_Note.Instrument:=0; 104 | C_Note.Periode:=0; 105 | C_Note.Volume:=255; 106 | C_Note.Commande:=0; 107 | C_Note.Parametre:=0; 108 | IF b1<$FE Then 109 | Begin 110 | {C_Note.Periode:=MMSS_Table^.Table_Period[b1 SHR 2+24];} 111 | C_Note.Periode:=b1 SHR 2+24; 112 | C_Note.Instrument:= ((SWAP(w1) SHR 4) AND 63)+1; 113 | End; 114 | IF b1<$FF Then 115 | C_Note.Volume:=((b2 AND 15) SHL 2)+((b2 AND 15) SHR 2); 116 | C_Note.Parametre:=b3 AND 15; 117 | C_Note.Commande:=Rien; 118 | If C_Note.Parametre<>0 Then 119 | CASE b3 SHR 4 OF 120 | 0: C_Note.Commande:=PortUp; 121 | 1: C_Note.Commande:=PortDown; 122 | 2: C_Note.Commande:=TonePortamento; 123 | 3: Begin 124 | C_Note.Commande:=FreqAdj; 125 | {If C_Note.Periode<>0 Then INC(C_Note.Periode);} 126 | End; 127 | 4: Begin 128 | C_Note.Commande:=Vibrato; 129 | C_Note.Parametre:=(C_Note.Parametre SHL 4)+1; 130 | End; 131 | 5: C_Note.Commande:=SetTempo; 132 | End; 133 | If C_Note.Commande=Rien Then C_Note.Parametre:=0; 134 | 135 | If C_Note.Instrument <>0 Then SamplFlags[C_Note.Instrument]:=True; 136 | Pattern^[j+8*(i-1)]:=C_Note; 137 | End; 138 | End; 139 | End; 140 | 141 | End; {Charger_pattern} 142 | 143 | {---------------------------------------------------------} 144 | 145 | PROCEDURE Charger_Donnees_Samples(Num:Byte); 146 | VAR Instr669:T669Instrument; 147 | 148 | Begin 149 | { R�serve l'espace DOS pour la d�finition de samples } 150 | Allouer_Samples(Num); 151 | 152 | For CHU_NSmp:=1 to Num do 153 | Begin 154 | f_module.Lit(Instr669,SizeOf(Instr669)); 155 | New_Sample; 156 | 157 | {MOVE(Instr669.Name[1],Smp.Nom,13);} 158 | Move(Instr669.Name[1],Musique^.PtrInstrNameTable^[CHU_NSmp,1],13); 159 | 160 | Smp.len:=Instr669.Size; 161 | Smp.rep_len:=Instr669.RepLen; 162 | Smp.rep:=Instr669.RepStart; 163 | 164 | Move(Smp,MMSS_Table^.PtrSamples[CHU_NSmp]^,SizeOf(Smp)); {Sauvegarde du Sample} 165 | End; 166 | End; { Charger_Donnees_Samples } 167 | 168 | {---------------------------------------------------------} 169 | 170 | PROCEDURE Charger_Samples669(Num:Byte); 171 | 172 | VAR 173 | i,j: Integer; 174 | 175 | BEGIN 176 | 177 | {*** Charge les samples ***} 178 | 179 | Init_Charge_Sample; 180 | Convertir_signe:=True; 181 | 182 | If Num>Max_Samples Then Num:=Max_Samples; 183 | 184 | For CHU_NSmp:=1 to Num do 185 | Begin 186 | Move(MMSS_Table^.PtrSamples[CHU_NSmp]^,Smp,SizeOf(Smp)); { Charger le sample } 187 | With MMSS_Table^ do 188 | If Smp.len>0 Then 189 | Begin 190 | 191 | If Smp.rep_len=65535 Then Smp.rep_len:=0; { Ajustement des donn�es } 192 | If Smp.rep_len>Smp.len Then Smp.rep_len:=0; 193 | If Smp.rep_len+Smp.rep>Smp.len Then Smp.rep:=Smp.len-Smp.rep_len; 194 | Smp_rep_fin:=Smp.rep+Smp.rep_len; 195 | 196 | Charger_Sample; 197 | 198 | End; { Smp_len>4 } 199 | Move(Smp,MMSS_Table^.PtrSamples[CHU_NSmp]^,SizeOf(Smp)); { Copier le sample... } 200 | End; { For } 201 | 202 | Fin_Charge_Sample; 203 | 204 | {*** Fin du chargement des Samples ***} 205 | 206 | END; { Charger_Samples669 } 207 | 208 | {---------------------------------------------------------} 209 | 210 | PROCEDURE Charge_669(chemin: String80; Var erreur: Word); 211 | 212 | Var FICH669 : Ptr_En_tete_669; 213 | Long669 : Byte; 214 | i:Integer; 215 | 216 | Begin {Charge_669} 217 | erreur:=Ok; 218 | f_module.Ouvre(lecture,chemin); 219 | 220 | If f_erreur=f_ok then 221 | Begin 222 | Init_Module; 223 | Nom_fichier:=NomFichierSeul(chemin); 224 | 225 | MMSS_CFG^.Calculer_Panning:=False; 226 | New(FICH669); 227 | 228 | f_module.LitPos(0,FICH669^,Sizeof(FICH669^)); 229 | 230 | Musique^.Type_Module:=T_669; { Type de module } 231 | Musique^.C_Pattern:=False; 232 | Musique^.Octave_Min:=2; { Octaves... } 233 | Musique^.Octave_Max:=6; 234 | Move(FICH669^.Comment[1,1],Musique^.Titre,32); { Titre du module } 235 | 236 | { Titre du module } 237 | 238 | For i:=1 to 128 do 239 | If FICH669^.Sequence[i]<128 Then Musique^.Sequence_Len:=i; 240 | 241 | If FICH669^.Ident<>IdentUni669 Then 242 | Move(FICH669^.Tempos,Musique^.Tempo_Pattern,128); { Placer les tempos } 243 | 244 | Move(FICH669^.Sequence,Musique^.Sequence,128); { Copie de la s�quence } 245 | Musique^.Pos_de_restart:=FICH669^.Repstart+1; 246 | Musique^.Tempo_Start:=4; 247 | Musique^.Ch_Number:=8; 248 | Musique^.Ch_Number_Patt:=8; 249 | Musique^.BPM_Start:=80; { Base 32� de seconde => 125*32/50=80 } 250 | 251 | Erreur_de_chargement:=Ok; 252 | 253 | If FICH669^.NSamples=0 Then 254 | Erreur_de_chargement:=Err_No_Sample; 255 | 256 | If FICH669^.NSamples>Max_Samples_669 Then 257 | Erreur_de_chargement:=Err_Format; 258 | 259 | If Erreur_de_chargement=Ok Then 260 | Charger_Donnees_Samples(FICH669^.NSamples); 261 | 262 | If Erreur_de_chargement=Ok Then 263 | Charger_Pattern(FICH669^.Lengths,FICH669^.NPatterns); 264 | 265 | If Erreur_de_chargement=Ok Then 266 | Charger_Samples669(FICH669^.NSamples); 267 | 268 | Init_Panning; 269 | FillChar(Musique^.M_CH_Type,Musique^.Ch_Number,1); { Voies num�riques... } 270 | Compter_Voies; 271 | 272 | Dispose(FICH669); 273 | 274 | Erreur:=Erreur_de_chargement; 275 | f_module.Ferme 276 | End 277 | Else Erreur:=Err_lecture; {Impossible d'ouvrir le fichier} 278 | If Erreur In [Ok,Err_samples] Then MMSS_MUS_Loaded:=True 279 | Else Init_Module; { Initialiser le Module il est incorrect... } 280 | End; {Charge_669} 281 | 282 | END. -------------------------------------------------------------------------------- /TPUNIT/CHADL.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHADL.PAS -------------------------------------------------------------------------------- /TPUNIT/CHDTM.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHDTM.PAS -------------------------------------------------------------------------------- /TPUNIT/CHFAR.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHFAR.PAS -------------------------------------------------------------------------------- /TPUNIT/CHIMF.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHIMF.PAS -------------------------------------------------------------------------------- /TPUNIT/CHMIDI.PAS: -------------------------------------------------------------------------------- 1 | Unit CHMidi; 2 | INTERFACE 3 | Uses Fichiers,Util,VarMidi,Memoire; 4 | 5 | TYPE String80=String[80]; 6 | Char4=Array[1..4] of Char; 7 | 8 | T_Track=Record 9 | Ident : Array[1..4] of Char; 10 | Len : Longint; 11 | End; 12 | 13 | PROCEDURE Charge_Midi(chemin:String80;Var erreur: Word); 14 | 15 | IMPLEMENTATION 16 | 17 | PROCEDURE Charge_Midi(chemin:String80;Var erreur: Word); 18 | VAR 19 | fMidi:Fichier; 20 | Taille_en_tete:Word; 21 | i:Byte; 22 | Track:T_Track; 23 | 24 | Begin 25 | fMidi.Ouvre(lecture,chemin); 26 | Erreur:=0; 27 | 28 | If f_erreur=f_ok then 29 | Begin 30 | Taille_Midi:=fMidi.Taille; 31 | fMIDI.LitPos(0,MIDI,SizeOf(MIDI)); 32 | If MIDI.Ident='MThd' Then 33 | Begin 34 | MIDI.Taille:=SwapLB(MIDI.Taille); 35 | MIDI.Format:=SWAP(MIDI.Format); 36 | MIDI.NBPistes:=SWAP(MIDI.NbPistes); 37 | MIDI.Division:=SWAP(MIDI.Division); 38 | Tempo_Depart:=0; 39 | 40 | fMIDI.PlacePointeur(MIDI.Taille+8); 41 | If (MIDI.Format<2) then 42 | Begin 43 | For i:=1 to MIDI.NbPistes do 44 | Begin 45 | fMIDI.Lit(Track,SizeOf(Track)); 46 | Track.Len:=SwapLB(Track.Len); 47 | If (Track.Ident='MTrk') And (Track.Len<65535) Then 48 | Begin 49 | Getmem(Piste[i].Pointeur,Track.Len); 50 | Piste[i].Taille:=Track.Len; 51 | fMIDI.Lit(Piste[i].Pointeur^,Track.Len); 52 | End 53 | Else 54 | Begin 55 | Erreur:=4; 56 | Break; 57 | End; 58 | End; 59 | End 60 | Else Erreur:=5; { Incorrect Format } 61 | End 62 | Else Erreur:=2; 63 | End 64 | Else Erreur:=1; 65 | If Erreur<>0 Then 66 | Begin 67 | Midi_Charge:=False; 68 | Efface_Midi; 69 | End 70 | Else Midi_Charge:=True; 71 | End; 72 | 73 | END. -------------------------------------------------------------------------------- /TPUNIT/CHMMM.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHMMM.PAS -------------------------------------------------------------------------------- /TPUNIT/CHMOD.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHMOD.PAS -------------------------------------------------------------------------------- /TPUNIT/CHMTM.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHMTM.PAS -------------------------------------------------------------------------------- /TPUNIT/CHPTM.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHPTM.PAS -------------------------------------------------------------------------------- /TPUNIT/CHRAD.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHRAD.PAS -------------------------------------------------------------------------------- /TPUNIT/CHS3M.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHS3M.PAS -------------------------------------------------------------------------------- /TPUNIT/CHSAT.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHSAT.PAS -------------------------------------------------------------------------------- /TPUNIT/CHSTM.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHSTM.PAS -------------------------------------------------------------------------------- /TPUNIT/CHULT.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHULT.PAS -------------------------------------------------------------------------------- /TPUNIT/CHUTIL.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHUTIL.PAS -------------------------------------------------------------------------------- /TPUNIT/CHVGM.PAS: -------------------------------------------------------------------------------- 1 | {************************************************************************} 2 | { CHVGM.PAS } 3 | { Support only SN76489, OPL2, OPL3 } 4 | { Loader pour les fichiers Stream VGM } 5 | { } 6 | { AUTEUR: Freddy Vetele } 7 | { } 8 | {************************************************************************} 9 | 10 | {$IFNDEF Groupe} 11 | UNIT ChVGM; {unit� pour charger les fichiers MOD } 12 | {$ELSE} 13 | UNIT ChVGM_G; 14 | {$ENDIF} 15 | 16 | {$A+,Q-,R-,S-} 17 | 18 | INTERFACE 19 | 20 | 21 | {$IFNDEF Groupe} 22 | USES Fichiers,Util,Chutil,MMSS_Var,CRT,MMSS_Mem,Memoire; 23 | {$ELSE} 24 | USES Fich_grp,Util,Chutil_G,MMSS_Var,CRT,MMSS_Mem,Memoire; 25 | {$ENDIF} 26 | 27 | CONST 28 | 29 | VGM_String : String20 = 'Video Game Music '; 30 | 31 | PROCEDURE Charge_VGM(chemin: String80; Var erreur: Word); 32 | { Return Error if not supported } 33 | 34 | IMPLEMENTATION 35 | 36 | TYPE 37 | 38 | T_VGMHeader=Record 39 | ID : Array[1..4] of Char; 40 | Size : Longint; 41 | VerL : Byte; { Version Low BCD } 42 | VerH : Byte; { Version High BCD } 43 | VerD : Word; 44 | SN76489Clk : Longint; { Tandy Chip } 45 | YM2413Clk : LongInt; 46 | DG3TagOffset : Longint; { Information Tag Offset } 47 | TotSamples : Longint; 48 | LoopOffset : Longint; 49 | LoopSamp : Longint; 50 | { v1.01 } 51 | Rate : Longint; 52 | { v1.10 } 53 | SNFeedback : Longint; 54 | YM2612Clk : Longint; 55 | YM2151Clk : Longint; 56 | { v1.50 } 57 | DataOffset : Longint; 58 | f1 : Array[1..6] of Longint; 59 | YM3812Clk : Longint; { OPL2 v1.51 } 60 | f2 : Longint; 61 | f3 : Longint; 62 | YMF262Clk : Longint; { OPL3 v1.51 } 63 | YMF278BClk : Longint; 64 | YMF271Clk : Longint; 65 | YMZ280BClk : Longint; 66 | RC52C164Clk: Longint; 67 | PWMClk: Longint; 68 | AY8910Clk: Longint; {PSG AY-3-8910/YM2149} 69 | AY8910Type: Byte; 70 | AY8910Flags:Array[1..3] of Byte; 71 | f4: Array[1..19] of Longint; 72 | SAA1099Clk: Longint; { CMS } 73 | End; 74 | 75 | 76 | 77 | 78 | {---------------------------------------------------------} 79 | 80 | PROCEDURE Charge_VGM(chemin: String80; Var erreur: Word); 81 | 82 | Var 83 | Ptr_Load:Pointer; 84 | FSize:LongInt; 85 | VGMHeader:^T_VGMHeader; 86 | DataOffset : LongInt; 87 | 88 | Tmp:Word; 89 | FirstWord: Word; 90 | 91 | Begin {Charge_VGM} 92 | 93 | Erreur:=Ok; 94 | Init_Module; 95 | 96 | f_module.Ouvre(lecture,chemin); 97 | 98 | If f_erreur=f_ok then 99 | Begin 100 | Init_Module; 101 | 102 | FSize:=f_module.Taille; 103 | Tmp:=MemoireDOSLibre; 104 | 105 | If (FSize DIV 16)>=Tmp then { Check if sufficient DOS Memory free } 106 | Begin 107 | Erreur:=Err_Memoire; 108 | EXIT; 109 | End; 110 | 111 | Musique^.Type_Module :=T_VGM; 112 | Nom_fichier:=NomFichierSeul(chemin); 113 | Musique^.Ch_Number_Digit :=0; 114 | { Load the file in Memory } 115 | 116 | If Not MMSS_MemAlloc(Ptr_Load,(FSize DIV 16)+1,False,False) Then { No UMB } 117 | Begin 118 | erreur:=Err_Memoire; 119 | EXIT; 120 | End 121 | Else 122 | Begin 123 | f_module.LitPosL(0,Ptr_Load,FSize); { Load the Header } 124 | VGMHeader:=Ptr_Load; 125 | If VGMHeader^.ID<>'Vgm ' then 126 | Begin 127 | Erreur:=Err_format; 128 | { Liberer memoire } 129 | EXIT; 130 | End; 131 | 132 | Move(VGM_String[1],Musique^.Titre,20); 133 | 134 | If ((VGMHeader^.VerH=1) and (VGMHeader^.VerL>=$51)) or (VGMHeader^.VerH>1) then 135 | Begin 136 | DataOffset:=VGMHeader^.DataOffset+$34; 137 | End 138 | Else DataOffset:=$40; 139 | 140 | If VGMHeader^.DG3TagOffset<>0 then 141 | MMSS_CFG^.OtherMUS_DataEnd:=VGMHeader^.DG3TagOffset 142 | Else MMSS_CFG^.OtherMUS_DataEnd:=FSize; 143 | 144 | MMSS_CFG^.OtherMUS_Ptr:=Ptr(SEG(Ptr_Load^),DataOffset); { Save the Pointer to the .VGM Stream } 145 | 146 | { Writeln('VGM Version: ',VGMHeader^.VerH,' ',VGMHeader^.VerL); 147 | Writeln('FSize :',FSize); 148 | Writeln('DG3 Offset :',VGMHeader^.DG3TagOffset); 149 | Writeln('DataOffset :',DataOffset); 150 | Writeln('DataEnd : ',MMSS_CFG^.OtherMUS_DataEnd); 151 | Writeln('Ptr_Load: ',Seg(Ptr_Load^),':',Ofs(Ptr_Load^)); 152 | Writeln('MMSS_CFG^.OtherMUS_Ptr: ',Seg(MMSS_CFG^.OtherMUS_Ptr^),':',Ofs(MMSS_CFG^.OtherMUS_Ptr^));} 153 | 154 | { V 1.0 Support only the SN76489 } 155 | If ((VGMHeader^.VerH=1) and (VGMHeader^.VerL>=$51)) or (VGMHeader^.VerH>1) then 156 | Begin 157 | {Writeln(' Version >= 1.51 ');} 158 | If VGMHeader^.SN76489Clk<>0 then 159 | Begin 160 | {Writeln('SN76489');} 161 | MMSS_CFG^.OtherMUS_Out:=MMSS_CFG^.OtherMUS_Out OR M_SN76489; 162 | Musique^.Ch_Number :=4; 163 | End; 164 | If VGMHeader^.YM3812Clk<>0 then 165 | Begin 166 | {Writeln('OPL2');} 167 | MMSS_CFG^.OtherMUS_Out:=MMSS_CFG^.OtherMUS_Out OR M_OPL2; 168 | Musique^.Ch_Number :=9; 169 | Musique^.Ch_Number_Adlib :=9; 170 | End; 171 | If VGMHeader^.YMF262Clk<>0 then 172 | Begin 173 | {Writeln('OPL3');} 174 | MMSS_CFG^.OtherMUS_Out:=MMSS_CFG^.OtherMUS_Out OR M_OPL3; 175 | Musique^.Ch_Number :=9; 176 | Musique^.Ch_Number_Adlib :=9; 177 | End; 178 | If VGMHeader^.AY8910Clk<>0 then 179 | Begin 180 | Writeln('PSG',AY8910Clk); 181 | MMSS_CFG^.OtherMUS_Out:=MMSS_CFG^.OtherMUS_Out OR M_PSG; 182 | Musique^.Ch_Number :=6; 183 | {Repeat until Readkey=#13;} 184 | End; 185 | If (VGMHeader^.SAA1099Clk<>0) and (VGMHeader^.VerL>=$71) then 186 | Begin 187 | {Writeln('SAA1099'); 188 | Writeln('VGMHeader^.SAA1099Clk',VGMHeader^.SAA1099Clk);} 189 | MMSS_CFG^.OtherMUS_Out:=MMSS_CFG^.OtherMUS_Out OR M_SAA1099; 190 | Musique^.Ch_Number :=9; 191 | { Writeln('MMSS_CFG^.OtherMUS_Out:',MMSS_CFG^.OtherMUS_Out);} 192 | End; 193 | End 194 | Else 195 | Begin 196 | Erreur:=Err_Unknown_Version; 197 | EXIT; 198 | End; 199 | 200 | {DataOffset} 201 | 202 | End; { VGM } 203 | 204 | f_module.Ferme; 205 | End 206 | Else 207 | Begin 208 | Writeln(chemin+', File Open Error:',f_erreur); 209 | Erreur:=Err_lecture 210 | End; 211 | 212 | If Erreur=Ok Then MMSS_MUS_Loaded:=True 213 | Else Init_Module; 214 | End; {Charge_MMM} 215 | 216 | END. -------------------------------------------------------------------------------- /TPUNIT/CHXM.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CHXM.PAS -------------------------------------------------------------------------------- /TPUNIT/CLAVIER.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/CLAVIER.PAS -------------------------------------------------------------------------------- /TPUNIT/EMSUNIT.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/EMSUNIT.PAS -------------------------------------------------------------------------------- /TPUNIT/FICHIERS.PAS: -------------------------------------------------------------------------------- 1 | {����������������������������������������������������������������������ͻ} 2 | {� --==�� FICHIERS.PAS ��==-- �} 3 | {� �} 4 | {� Unit� pour g�rer les fichiers DOS �} 5 | {� �} 6 | {� AUTEUR: Fabrice Couteau �} 7 | {����������������������������������������������������������������������Ķ} 8 | {� Compatibilit�: 8088 D�but d'�criture���������������??/12/93 �} 9 | {� Derni�res modifications��������03/09/95 �} 10 | {����������������������������������������������������������������������ͼ} 11 | 12 | UNIT Fichiers; 13 | 14 | {$A+,G-,Q-,R-,S-} 15 | 16 | INTERFACE 17 | 18 | {$I Types} 19 | 20 | CONST {modes d'acc�s} 21 | lecture = $00; 22 | ecriture = $01; 23 | lectecrit = $02; 24 | 25 | {mode de cr�ation} 26 | teste_existe = True; 27 | 28 | {codes d'erreur} 29 | f_ok = 0; 30 | f_err_fich_intr = 2; 31 | f_err_ch_intr = 3; 32 | f_err_trop_fich = 4; 33 | f_err_acces_ref = 5; 34 | f_err_handle = 6; 35 | f_err_lecteur = 15; 36 | f_err_plus_fich = 18; 37 | f_err_existe = 80; 38 | f_err_protect =150; 39 | f_err_pas_pret =152; 40 | f_err_CRC =154; 41 | f_err_donnees =156; 42 | f_err_media =157; 43 | f_err_secteur =158; 44 | 45 | 46 | TYPE Fichier=Object 47 | PROCEDURE Ouvre(mode_acces: Byte; chemin: String80); 48 | PROCEDURE Cree(teste_existe_: Boolean; chemin: String80); 49 | PROCEDURE Ferme; 50 | PROCEDURE PlacePointeur (position: Longint); 51 | PROCEDURE DeplacePointeur(distance: Longint); 52 | PROCEDURE Lit (var buffer; nombre: Word); { Var is a Trick to pass a pointer and support many types } 53 | PROCEDURE Ecrit(var buffer; nombre: Word); 54 | PROCEDURE LitPos (position: Longint; var buffer; nombre: Word); 55 | PROCEDURE LitPosL (position: Longint; buffer : Pointer; nombre: LongInt); 56 | PROCEDURE EcritPos(position: Longint; var buffer; nombre: Word); 57 | FUNCTION Taille: Longint; 58 | FUNCTION GetHandle: Word; 59 | Private 60 | handle: Word; 61 | End; 62 | 63 | 64 | CONST f_erreur: Word=f_ok; {variable � tester apr�s chaque op�ration fichier 65 | sauf: Ferme, (D�)PlacePointeur, Taille} 66 | 67 | {==========================================================} 68 | 69 | PROCEDURE EffaceFichier(chemin: String80); 70 | PROCEDURE EcraseFichier(chemin: String80); 71 | FUNCTION FichierExiste(chemin: String80): Boolean; 72 | 73 | {==========================================================} 74 | 75 | IMPLEMENTATION 76 | 77 | {==========================================================} 78 | 79 | PROCEDURE Fichier.Ouvre(mode_acces: Byte; chemin: String80); 80 | {ouvre un fichier existant en lecture, �criture ou les deux 81 | Remarque: le pointeur de fichier est plac� sur le premier octet} 82 | Var handle_: Word; 83 | ptr_chemin: Pointer; 84 | Begin 85 | ptr_chemin:=@chemin; 86 | ASM 87 | PUSH DS 88 | CLD 89 | LDS SI,ptr_chemin 90 | XOR AH,AH 91 | LODSB {AX=longueur chemin} 92 | MOV DX,SI {DS:DX -> chemin[1]} 93 | ADD SI,AX {DS:SI -> caract�re suivant le dernier} 94 | MOV BYTE PTR DS:[SI],0 {convertit chemin en ASCIIZ} 95 | MOV AH,3Dh 96 | MOV AL,mode_acces 97 | INT 21h {ouvre le fichier} 98 | POP DS 99 | MOV f_erreur,f_ok 100 | JNC @fin {pas d'erreur} 101 | MOV f_erreur,AX 102 | XOR AX,AX 103 | @fin: 104 | MOV handle_,AX 105 | End; 106 | handle:=handle_ 107 | End; {Fichier.Ouvre} 108 | 109 | {----------------------------------------------------------} 110 | 111 | PROCEDURE Fichier.Cree(teste_existe_: Boolean; chemin: String80); 112 | {cree un nouveau fichier 113 | si teste_existe_=TRUE: provoque une erreur 80 si le fichier existe deja 114 | sinon ecrase l'ancien fichier 115 | Remarque: le pointeur de fichier est place sur le premier octet} 116 | Var handle_: Word; 117 | ptr_chemin: Pointer; 118 | Begin 119 | ptr_chemin:=@chemin; 120 | ASM 121 | PUSH DS 122 | CLD 123 | LDS SI,ptr_chemin 124 | XOR AH,AH 125 | LODSB {AX=longueur chemin} 126 | MOV DX,SI {DS:DX -> chemin[1]} 127 | ADD SI,AX {DS:SI -> caractere suivant le dernier} 128 | MOV BYTE PTR DS:[SI],0 {convertit chemin en ASCIIZ} 129 | MOV AH,5Bh 130 | CMP teste_existe_,True 131 | JE @suite 132 | MOV AH,3Ch 133 | @suite: 134 | XOR CX,CX 135 | INT 21h {cree le fichier} 136 | POP DS 137 | MOV f_erreur,f_ok 138 | JNC @fin {pas d'erreur} 139 | MOV f_erreur,AX 140 | XOR AX,AX 141 | @fin: 142 | MOV handle_,AX 143 | End; 144 | handle:=handle_ 145 | End; {Fichier.Cree} 146 | 147 | {----------------------------------------------------------} 148 | 149 | PROCEDURE Fichier.Ferme; 150 | {ferme un fichier prealablement ouvert} 151 | Var handle_: Word; 152 | Begin 153 | handle_:=handle; 154 | ASM 155 | MOV AH,3Eh 156 | MOV BX,handle_ 157 | INT 21h 158 | End 159 | End; {Fichier.Ferme} 160 | 161 | {----------------------------------------------------------} 162 | 163 | PROCEDURE Fichier.PlacePointeur(position: Longint); 164 | {positionne le pointeur de fichier � l'offset voulu (0 -> premier octet) 165 | (position � 0)} 166 | Var handle_: Word; 167 | Begin 168 | handle_:=handle; 169 | ASM 170 | MOV AX,4200h {position par rapport au d�but du fichier} 171 | MOV BX,handle_ 172 | LES DX,position {DX=mot faible} 173 | MOV CX,ES {CX=mot fort} 174 | INT 21h 175 | End 176 | End; {Fichier.PlacePointeur} 177 | 178 | {----------------------------------------------------------} 179 | 180 | PROCEDURE Fichier.DeplacePointeur(distance: Longint); 181 | {d�place le pointeur de fichier (en amont ou en aval)} 182 | Var handle_: Word; 183 | Begin 184 | handle_:=handle; 185 | ASM 186 | MOV AX,4201h {distance par rapport a la position courante} 187 | MOV BX,handle_ 188 | LES DX,distance {DX=mot faible} 189 | MOV CX,ES {CX=mot fort} 190 | INT 21h 191 | End 192 | End; {Fichier.DeplacePointeur} 193 | 194 | {----------------------------------------------------------} 195 | 196 | PROCEDURE Fichier.Lit(var buffer; nombre: Word); 197 | {lit 'nombre' octets depuis la position courante du pointeur de fichier, 198 | et les place � l'adresse de 'buffer'} 199 | Var handle_: Word; 200 | Begin 201 | handle_:=handle; 202 | ASM 203 | PUSH DS 204 | MOV AH,3Fh 205 | MOV BX,handle_ 206 | MOV CX,nombre 207 | LDS DX,buffer 208 | INT 21h 209 | POP DS 210 | MOV f_erreur,f_ok 211 | JNC @fin {pas d'erreur} 212 | MOV f_erreur,AX 213 | @fin: 214 | End 215 | End; {Fichier.Lit} 216 | 217 | {----------------------------------------------------------} 218 | 219 | PROCEDURE Fichier.Ecrit(var buffer; nombre: Word); 220 | {ecrit 'nombre' octets de 'buffer' � la position courante du pointeur de fichier} 221 | Var handle_: Word; 222 | Begin 223 | handle_:=handle; 224 | ASM 225 | PUSH DS 226 | MOV AH,40h 227 | MOV BX,handle_ 228 | MOV CX,nombre 229 | LDS DX,buffer 230 | INT 21h 231 | POP DS 232 | MOV f_erreur,f_ok 233 | JNC @fin {pas d'erreur} 234 | MOV f_erreur,AX 235 | @fin: 236 | End 237 | End; {Fichier.Ecrit} 238 | 239 | {----------------------------------------------------------} 240 | 241 | PROCEDURE Fichier.LitPos(position: Longint; var buffer; nombre: Word); 242 | {lit 'nombre' octets depuis 'position' , et les place a l'adresse de 'buffer'} 243 | Begin 244 | Fichier.PlacePointeur(position); Fichier.Lit(buffer,nombre) 245 | End; {Fichier.LitPos} 246 | 247 | { Buffer Segment must be 0 } 248 | PROCEDURE Fichier.LitPosL (position: Longint; buffer: Pointer; nombre: Longint); 249 | {lit 'nombre' octets depuis 'position' , et les place a l'adresse de 'buffer'} 250 | Var 251 | LoopNb,i: Byte; 252 | Remain,Size : Word; 253 | PtrTmp:Pointer; 254 | Begin 255 | LoopNb:=(nombre SHR 15)+1; 256 | Remain:=(nombre AND $7FFF); { Read Block of 32Kb } 257 | Fichier.PlacePointeur(position); 258 | for i:=1 to LoopNb do 259 | Begin 260 | if i=LoopNb then Size:=Remain else Size:=$8000; 261 | PtrTmp:=Ptr(Seg(buffer^)+$800*(i-1),0); 262 | Fichier.Lit(PtrTmp^,size) 263 | End; 264 | End; {Fichier.LitPos} 265 | 266 | {----------------------------------------------------------} 267 | 268 | PROCEDURE Fichier.EcritPos(position: Longint; var buffer; nombre: Word); 269 | {ecrit 'nombre' octets de 'buffer' a la position indiquee du pointeur de fichier} 270 | Begin 271 | Fichier.PlacePointeur(position); Fichier.Ecrit(buffer,nombre) 272 | End; {Fichier.EcritPos} 273 | 274 | {----------------------------------------------------------} 275 | 276 | FUNCTION Fichier.Taille: Longint; 277 | {renvoie la taille du fichier en octets 278 | IMPORTANT: d�place le pointeur de fichier sur le dernier octet!} 279 | Var handle_,th,tb: Word; 280 | Begin 281 | handle_:=handle; 282 | ASM 283 | MOV AX,4202h {distance par rapport � la fin du fichier} 284 | MOV BX,handle_ 285 | XOR CX,CX 286 | XOR DX,DX 287 | INT 21h {Taille=[DX,AX]} 288 | MOV th,DX 289 | MOV tb,AX 290 | End; 291 | Taille:=Longint(th) SHL 16+tb 292 | End; {Fichier.Taille} 293 | 294 | {----------------------------------------------------------} 295 | 296 | FUNCTION Fichier.GetHandle: Word; 297 | {renvoie le handle du fichier} 298 | Begin 299 | GetHandle:=handle 300 | End; {Fichier.GetHandle} 301 | 302 | {----------------------------------------------------------} 303 | 304 | PROCEDURE EffaceFichier(chemin: String80); Assembler; 305 | {efface un fichier sur disque - r�cup�rable avec Undelete} 306 | ASM 307 | PUSH DS 308 | CLD 309 | LDS SI,chemin 310 | XOR AH,AH 311 | LODSB {AX=longueur chemin} 312 | MOV DX,SI {DS:DX -> chemin[1]} 313 | ADD SI,AX {DS:SI -> caract�re suivant le dernier} 314 | MOV BYTE PTR DS:[SI],0 {convertit chemin en ASCIIZ} 315 | MOV AH,41h 316 | INT 21h {supprime le fichier} 317 | POP DS 318 | MOV f_erreur,f_ok 319 | JNC @fin {pas d'erreur} 320 | MOV f_erreur,AX 321 | @fin: 322 | End; {EffaceFichier} 323 | 324 | {----------------------------------------------------------} 325 | 326 | PROCEDURE EcraseFichier(chemin: String80); 327 | {efface un fichier sur disque - IRRECUPERABLE avec Undelete} 328 | Var f: Fichier; 329 | Begin 330 | With f do 331 | Begin 332 | Cree(Not(teste_existe),chemin); 333 | If f_erreur<>f_ok Then Exit; 334 | Ferme; {cr�e un fichier vide portant le m�me nom} 335 | EffaceFichier(chemin) 336 | End 337 | End; {EcraseFichier} 338 | 339 | {----------------------------------------------------------} 340 | 341 | FUNCTION FichierExiste(chemin: String80): Boolean; 342 | {renvoie TRUE si le fichier existe sur le disque 343 | Remarque: ne teste pas les erreurs d'acc�s} 344 | Var f: Fichier; 345 | Begin 346 | With f do Begin Ouvre(lecture,chemin); Ferme End; 347 | FichierExiste:=(f_erreur=f_ok) 348 | End; {FichierExiste} 349 | 350 | {==========================================================} 351 | 352 | END. 353 | -------------------------------------------------------------------------------- /TPUNIT/GUSUNIT.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/GUSUNIT.PAS -------------------------------------------------------------------------------- /TPUNIT/MEMOIRE.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/MEMOIRE.PAS -------------------------------------------------------------------------------- /TPUNIT/MMSS_CMD.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/MMSS_CMD.PAS -------------------------------------------------------------------------------- /TPUNIT/MMSS_MEM.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/MMSS_MEM.PAS -------------------------------------------------------------------------------- /TPUNIT/MM_INIT.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/MM_INIT.PAS -------------------------------------------------------------------------------- /TPUNIT/MM_OTHER/CHS3M_NC.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/MM_OTHER/CHS3M_NC.PAS -------------------------------------------------------------------------------- /TPUNIT/MM_OTHER/CHXM_nc.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/MM_OTHER/CHXM_nc.PAS -------------------------------------------------------------------------------- /TPUNIT/MM_OTHER/DISNEYSS.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/MM_OTHER/DISNEYSS.PAS -------------------------------------------------------------------------------- /TPUNIT/MM_OTHER/DSSUNIT.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/MM_OTHER/DSSUNIT.PAS -------------------------------------------------------------------------------- /TPUNIT/MM_OTHER/ESSUNIT.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/MM_OTHER/ESSUNIT.PAS -------------------------------------------------------------------------------- /TPUNIT/MM_OTHER/FICH_GRP.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/MM_OTHER/FICH_GRP.PAS -------------------------------------------------------------------------------- /TPUNIT/MM_OTHER/MODM_SS.PAS: -------------------------------------------------------------------------------- 1 | {************************************************************************} 2 | { MODMUNIT.PAS V2.2 } 3 | { } 4 | { Interface entre le pascal et les routines sonores de Mod Master. } 5 | { } 6 | { AUTEUR: Freddy V�tel�. } 7 | { } 8 | { } 9 | { Dernieres modifications le 28/01/2020 } 10 | {************************************************************************} 11 | 12 | {$UNDEF MODM} { Define for the Full Mod Master } 13 | 14 | {$IFDEF MODM} 15 | UNIT MODMUNIT; {Unit for MODM.PAS} 16 | {$ELSE} 17 | UNIT MODM_SS; {Unit for Standalone Sound System} 18 | {$ENDIF} 19 | 20 | {$A+,G-,Q-,R-,S-} 21 | {$I MODMCFG.INI} 22 | 23 | {$UNDEF DEBUG } 24 | INTERFACE 25 | 26 | TYPE String80=String[80]; 27 | 28 | VAR SauveExit : POINTER; { Sauvegarde de l'ancienne routine de fin } 29 | DisplayText : Boolean; 30 | 31 | {=========================================================} 32 | {$IFDEF MODM} 33 | PROCEDURE Affiche_Ecran_Texte; 34 | PROCEDURE MM_ASM_UpdateInterface; 35 | {$ENDIF} 36 | 37 | PROCEDURE WaveOut_SetDefault(W_Number: Byte); { Configure the default values and the output number } 38 | FUNCTION MMSS_Start_Output: Byte; { Start Audio Output } 39 | PROCEDURE MMSS_Stop_Output; { Stop audio Output } 40 | FUNCTION MMSS_Start_Music: Word; { Init Music Variables } 41 | PROCEDURE MMSS_Stop_Musique; 42 | PROCEDURE MMSS_Init(ShowMem:Boolean;ShowDevice:Boolean); 43 | 44 | PROCEDURE MMSS_StartIRQ; 45 | PROCEDURE MMSS_StopIRQ; 46 | FUNCTION MMSS_TestIRQ:Byte; 47 | 48 | {=========================================================} 49 | 50 | IMPLEMENTATION 51 | 52 | USES Fichiers,Util,BIOSEQU,MMSS_Var,MMSS_CMD,VarUnit,Memoire,CHUtil,Texte,Clavier, 53 | SBUnit,TDYUnit,PSGUnit, 54 | {$IFNDEF NoGUS} 55 | GusUnit, 56 | {$ENDIF} 57 | CRT,MMSS_Mem; 58 | 59 | { MODMPAS.OBJ External Variables definition } 60 | 61 | {$F+} 62 | 63 | {PROCEDURE Affiche_Ecran_Graphique; External;} 64 | 65 | {$IFDEF MODM} 66 | PROCEDURE Affiche_Ecran_Texte; External; 67 | PROCEDURE MM_ASM_UpdateInterface; External; 68 | PROCEDURE MMSS_Refresh_Debug; External; 69 | {$ENDIF} 70 | 71 | PROCEDURE PInit_Tables(Var dest); External; 72 | FUNCTION PStart_Output:Word; External; 73 | FUNCTION PStart_Music:Word; External; 74 | PROCEDURE MMSS_StartIRQ; External; 75 | PROCEDURE MMSS_StopIRQ; External; 76 | FUNCTION MMSS_TestIRQ:Byte; External; 77 | {$F-} 78 | 79 | {$IFDEF MODM} 80 | {$L MODMPAS} 81 | {$ELSE} 82 | {$L MODM_SS} 83 | {$ENDIF} 84 | 85 | {=========================================================} 86 | 87 | {---------------------------------------------------------} 88 | { Mod Master XT : Removed Adlib, sound Master > No more needed } 89 | PROCEDURE WaveOut_Init; 90 | Var Panning_GUS : Byte; 91 | 92 | Begin 93 | 94 | Case MMSS_CFG^.Wave_Output of 95 | {$IFNDEF NoGUS} 96 | GUS: Begin { Init and configure the Panning } 97 | If Musique^.Ch_Number_Digit>14 Then UltraReset(Musique^.Ch_Number,MMSS_CFG^.GUS_InterWave) 98 | Else UltraReset(14,MMSS_CFG^.GUS_InterWave); 99 | End; 100 | {$ENDIF} 101 | SB,SBPro: Init_DSP; 102 | {$IFNDEF ModeXT} 103 | {$IFNDEF NoOPL} 104 | { Adlib: Begin 105 | InitOPL2; 106 | Musique^.Ch_Number_Adlib:=0; 107 | If Musique^.Ch_Number_Digit>0 Then 108 | Begin 109 | EcrireOPL2(OPL2Test ,$20); 110 | EcrireOPL2(OPL2FB_FM ,$01); 111 | EcrireOPL2(OPL2AM_VIB ,$00); 112 | EcrireOPL2(OPL2AM_VIB+3,$27); 113 | EcrireOPL2(OPL2KSL_TL ,$00); 114 | EcrireOPL2(OPL2KSL_TL+3,$00); 115 | EcrireOPL2(OPL2AR_DR ,$00); 116 | EcrireOPL2(OPL2AR_DR+3 ,$FF); 117 | EcrireOPL2(OPL2SL_RR ,$00); 118 | EcrireOPL2(OPL2SL_RR+3 ,$0F); 119 | EcrireOPL2(OPL2WS ,$00); 120 | EcrireOPL2(OPL2WS+3 ,$02); 121 | EcrireOPL2(OPL2Fnum ,$0C); 122 | EcrireOPL2(OPL2Key ,$3F); 123 | EcrireOPL2($BD ,$20); 124 | End 125 | Else Erreur_Modm:=Err_Adlib; 126 | End;} 127 | {$ENDIF} 128 | End; 129 | {$ENDIF} 130 | End; 131 | End; {WaveOut_Init} 132 | 133 | {---------------------------------------------------------} 134 | 135 | PROCEDURE SoundEnd; 136 | Begin 137 | {$IFNDEF NoOPL} 138 | If (Musique^.Ch_Number_Adlib>0) and ((OPL_Model<>0) or (OPL_LPT_Model<>0)) Then InitOPL2; 139 | {$ENDIF} 140 | {$IFNDEF NoGUS} 141 | Case MMSS_CFG^.Wave_Output Of 142 | GUS: UltraReset(14,FALSE); 143 | End; 144 | {$ENDIF} 145 | End; {SoundEnd} 146 | 147 | {---------------------------------------------------------} 148 | 149 | FUNCTION MMSS_Start_Output:Byte; 150 | Var Err_Sort:Word; 151 | i:Word; 152 | Begin 153 | 154 | { No 16Bit Mixing for PC Speaker, No 16Bit output for Stereo } 155 | If (MMSS_CFG^.Wave_Output=HPint) and (MMSS_CFG^.Mix_16Bit) then MMSS_CFG^.Mix_16Bit:=False; 156 | {If (MMSS_CFG^.Utilise_Stereo) and (MMSS_CFG^.Mix_16Bit) and then 157 | If } 158 | 159 | If MMSS_CFG^.Output_Stopped Then 160 | Begin 161 | 162 | If Musique^.Ch_Number_Digit<>0 then 163 | Begin 164 | If MMSS_CFG^.Wave_Output<>GUS Then Init_Tables_Modm; { Initialize the Volume and Buffer Tables } 165 | MMSS_Adjust_Vol(Musique^.Ch_Number); 166 | WaveOut_Init; { Init the GUS Panning } 167 | End; 168 | 169 | {$IFNDEF NoOPL} 170 | If (Musique^.Ch_Number_Adlib>0) and ((OPL_Model<>0) or (OPL_LPT_Model<>0)) Then InitOPL2; 171 | {$ENDIF} 172 | 173 | Musique^.Note_Delta:=Musique^.Note_Size*(Musique^.Ch_Number_patt-Musique^.Ch_Number); 174 | 175 | Err_Sort:=PStart_Output; 176 | If Err_Sort<>Ok Then 177 | Begin 178 | MMSS_CFG^.Stop_Output:=False; 179 | MMSS_CFG^.Output_Stopped:=True; 180 | End; 181 | 182 | End 183 | Else Err_Sort:=Ok; 184 | {Writeln; 185 | Writeln('Mix_16Bit:',MMSS_CFG^.Mix_16Bit); 186 | Writeln('Out_16Bit:',MMSS_CFG^.Out_16Bit);} 187 | {Writeln('DMA Buffer '+EntierHexa(MMSS_CFG^.Seg_Table_Volume,4)+':'++EntierHexa(MMSS_CFG^.Offset_DMA_Buffer,4)); 188 | Writeln('Debug1 '+EntierHexa(MMSS_CFG^.debug1,4)); 189 | Writeln('Debug2 '+EntierHexa(MMSS_CFG^.debug2,4)); 190 | Writeln('Debug3 '+EntierHexa(MMSS_CFG^.debug3,4)); 191 | Writeln('Debug4 '+EntierHexa(MMSS_CFG^.debug4,4)); 192 | Writeln('Debug5 '+EntierHexa(MMSS_CFG^.debug5,4)); 193 | Writeln('Debug6 '+EntierHexa(MMSS_CFG^.debug6,4));} 194 | {Repeat Until Readkey=#13;} 195 | MMSS_Start_Output:=Err_Sort; 196 | End; {Start_Output} 197 | 198 | {---------------------------------------------------------} 199 | 200 | PROCEDURE MMSS_Stop_Output; 201 | Begin 202 | If Not MMSS_CFG^.Output_Stopped Then { Si musique termin�e, ne pas l'arr�ter } 203 | Begin 204 | MMSS_CFG^.Stop_Output:=True; 205 | Repeat Until MMSS_CFG^.Output_Stopped; 206 | End; 207 | SoundEnd; 208 | MMSS_CFG^.Stop_Output:=False; 209 | Fin_Tables_Modm; 210 | End; {MMSS_Stop_Output} 211 | 212 | {---------------------------------------------------------} 213 | 214 | FUNCTION MMSS_Start_Music:Word; 215 | Begin 216 | 217 | Move(Musique^.M_CH_Panning,MMSS_Info^.CH_Panning,Max_Channels); { Copy the Default Panning } 218 | With MMSS_CFG^ do If Not(Use_Panning_CMD) Then Calculer_Panning:=False; 219 | 220 | {$IFDEF DEBUG} 221 | Writeln('PStart_Music;'); 222 | {$ENDIF} 223 | MMSS_Start_Music:=PStart_Music; 224 | End; {MMSS_Start_Music} 225 | 226 | {---------------------------------------------------------} 227 | 228 | PROCEDURE MMSS_Stop_Musique; 229 | Begin 230 | If Not MMSS_CFG^.Musique_Term Then MMSS_CFG^.Musique_Term:=True; 231 | End; {MMSS_Stop_Musique} 232 | 233 | {---------------------------------------------------------} 234 | 235 | (*PROCEDURE ChangerConfigModm; 236 | { Changer la fr�quence et la sortie sonore sans arr�ter la musique } 237 | Begin 238 | If Not (MMSS_CFG^.Musique_Terminee) Then 239 | Begin 240 | MMSS_CFG^.Stop_Player:=True; 241 | Repeat Until MMSS_CFG^.Musique_terminee; 242 | If MMSS_CFG^.Wave_Output=GUS Then 243 | If Musique^.Ch_Number>14 Then UltraOpen(Ultra_Config,Musique^.Ch_Number) 244 | Else UltraReset(14); 245 | MMSS_CFG^.Stop_Player:=False; 246 | Ajuster_Out_Frequency; { Ajuster la fr�quence } 247 | PStart_Output; { Relancer la sortie } 248 | End; 249 | End; {ChangerConfigModm} *) 250 | 251 | {---------------------------------------------------------} 252 | 253 | { 254 | PROCEDURE Tester_Vitesse; 255 | BEGIN 256 | If MMSS_CFG^.Wave_Output<>GUS Then Init_Tables_Modm; 257 | AjusterVolume; 258 | Test_Vitesse; 259 | If MMSS_CFG^.Wave_Output<>GUS Then Fin_Tables_Modm; 260 | END;} {Tester_Vitesse} 261 | 262 | 263 | {---------------------------------------------------------} 264 | 265 | 266 | {---------------------------------------------------------} 267 | 268 | {$F+} 269 | PROCEDURE Routine_Fin; 270 | { Stopper la musique si fin du programme (en cas d'erreur) } 271 | Begin 272 | ExitProc:=SauveExit; 273 | MMSS_Stop_Output; 274 | MMSS_Stop_Musique; 275 | If MMSS_MUS_Loaded Then MMSS_FreeMemory; 276 | End; {Routine_Fin} 277 | {$F-} 278 | 279 | {---------------------------------------------------------} 280 | 281 | PROCEDURE WaveOut_SetDefault(W_Number: Byte); { Configure the default values and the output number } 282 | Begin 283 | With MMSS_CFG^ do 284 | Begin 285 | Case W_Number of 286 | Hpint, 287 | LPT1, 288 | LPT2, 289 | TDY_DAC, 290 | C_DAC : Out_Frequency:=10000; 291 | SB : With SBConfig do 292 | Begin 293 | Out_Frequency:=16000; 294 | Utilise_DC:=(Type_>1); 295 | Use_DMA:=True; 296 | SB_BasePort:=Port; 297 | IRQ_SB:=IRQ; 298 | DMA_SB8:=DMA8; 299 | DMA_SB16:=DMA16; 300 | MMType_SB:=Type_; { Type de carte } 301 | End; 302 | SBPro : Begin 303 | WaveOut_SetDefault(SB); 304 | Out_Frequency:=16000; 305 | Utilise_Stereo:=False; 306 | {Utilise_Mixage:=False;} 307 | Utilise_Filtre:=False; 308 | SBP_Filtre(False); 309 | SBP_MasterVolume(15,15); { Master Volume } 310 | SBMixerWrite(mxrMasterVolume,$FF) { Maximum DAC Volume } 311 | End; 312 | {$IFNDEF NoGUS} 313 | GUS : Begin 314 | MMSS_CFG^.GUS_BasePort:=Ultra_Base_Port; 315 | MMSS_CFG^.GUS_InterWave:=False; 316 | GUS_LineIn:=False; 317 | {MMSS_CFG^.GUS_IRQ:=Ultra_Config.GF1_IRQ_Num;} 318 | Taille_GUS:=UltraSizeDRAM 319 | End; 320 | {$ENDIF} 321 | End; 322 | Wave_Output:=W_Number { Init the Default selected Audio Output number } 323 | End 324 | End; {WaveOut_SetDefault} 325 | 326 | {---------------------------------------------------------} 327 | 328 | PROCEDURE Init_Output_Devices(ShowDevice:Boolean); { Executed only at the player Start } 329 | Var i:Byte; 330 | j:Word; 331 | 332 | Begin {Init_Config_Sonore} 333 | 334 | SB_LeftVol:=15; SB_RightVol:=15; 335 | MMSS_Def_LeftPan:=$20; MMSS_Def_RightPan:=$60; 336 | MMSS_Volume:=5*50; 337 | 338 | LPT_Nb:=0; 339 | j:=BiosSeg.LptBase[1]; 340 | If j <>0 Then 341 | Begin 342 | MMSS_CFG^.LPT1_Port:=j; 343 | MMSS_W_Output_Available[LPT1]:=True; 344 | If ShowDevice then Writeln('LPT1: ',EntierHexa(j,4)+'h '); 345 | LPT_Nb:=1 346 | End; 347 | 348 | j:=BiosSeg.LptBase[2]; 349 | If j <>0 Then 350 | Begin 351 | MMSS_CFG^.LPT2_Port:=j; 352 | MMSS_W_Output_Available[LPT2]:=True; 353 | If ShowDevice then Writeln('LPT2: ',EntierHexa(j,4)+'h '); 354 | LPT_Nb:=2 355 | End; 356 | 357 | If LPT_Nb=0 Then OPL_LPT_Nb:=0 358 | Else OPL_LPT_Nb:=1; 359 | TDY_LPT_Nb:=OPL_LPT_Nb; 360 | CMS_LPT_Nb:=OPL_LPT_Nb; 361 | 362 | {$IFNDEF ModeXT} { Crash on MegaEM } 363 | {Writeln('Detecte_DSS'); 364 | Detecte_DSS(True);} 365 | {$ENDIF} 366 | 367 | { Tandy Detection } 368 | {Writeln('TDY_DetectDAC');} 369 | TDY_DetectDAC; 370 | If TDY_DACPort<>0 Then 371 | Begin 372 | If ShowDevice then Writeln('Tandy DAC Detected: ',EntierHexa(TDY_Port,3)); 373 | MMSS_W_Output_Available[TDY_DAC]:=True; 374 | MMSS_CFG^.TDYDAC_Port:=TDY_DACPort 375 | End 376 | Else 377 | Begin 378 | If TDY_Type<>1 Then 379 | Begin 380 | {Writeln('TDY_DetectOld');} 381 | TDY_DetectOld; 382 | End; 383 | If TDY_Type=1 Then 384 | If ShowDevice then Writeln('Tandy 1000/PC Junior Detected: ',EntierHexa(TDY_Port,3)); 385 | MMSS_W_Output_Available[TDY_DAC]:=False; 386 | End; 387 | 388 | { Check for the Port Nb in the list } 389 | TDY_PortNb:=0; 390 | If TDY_Type<>0 then 391 | For i:=0 to TDY_PortTotal do 392 | If TDY_Port=TDY_PortList[i] then TDY_PortNb:=i; 393 | if TDY_PortNb=0 then 394 | begin 395 | TDY_PortNb=3; { By default, Port 2C0 } 396 | TDY_Port=TDY_PortList[TDY_PortNb] 397 | end; 398 | 399 | MMSS_CFG^.TDY_Type:=TDY_Type; 400 | MMSS_CFG^.TDY_Port:=TDY_Port; 401 | 402 | {$IFNDEF NoGUS} 403 | {Writeln('GUS_Detect(ShowDevice);');} 404 | GUS_Detect(ShowDevice); 405 | MMSS_W_Output_Available[GUS]:=GUS_Presente; 406 | {$ELSE} 407 | MMSS_W_Output_Available[GUS]:=False; 408 | {$ENDIF} 409 | 410 | {Writeln('SB_Detect(ShowDevice);');} 411 | SB_Detect(ShowDevice); { Detect the OPL and SB to SB16 } 412 | 413 | MMSS_CFG^.OPL_Model:=OPL_Model; 414 | MMSS_W_Output_Available[HPint] :=True; 415 | MMSS_W_Output_Available[C_DAC] :=False; {Declared in the Command Line or Config File} 416 | If SB_presente and Not SBPro_Presente then MMSS_W_Output_Available[SB]:=True 417 | Else MMSS_W_Output_Available[SB]:=False; 418 | MMSS_W_Output_Available[SBPro] :=SBPro_presente; 419 | 420 | For i:=0 to (MMSS_Out_Nb_W-1) do If MMSS_W_Output_Available[i] Then WaveOut_SetDefault(i); 421 | 422 | {$IFNDEF NoGUS} 423 | If GUS_presente Then MMSS_BestOutput:=GUS 424 | Else 425 | {$ENDIF} 426 | If SBPro_presente Then MMSS_BestOutput:=SBPro 427 | Else If SB_presente Then MMSS_BestOutput:=SB 428 | Else If TDY_Port<>0 Then MMSS_BestOutput:=TDY_DAC 429 | Else MMSS_BestOutput:=HPint; 430 | 431 | MMSS_CFG^.Wave_Output:=MMSS_BestOutput; 432 | End; {Init_Config_Sonore} 433 | 434 | {==========================================================} 435 | { Initialisation de MODM_U } 436 | {==========================================================} 437 | 438 | PROCEDURE MMSS_Init (ShowMem:Boolean;ShowDevice:Boolean); 439 | 440 | Begin 441 | { Init the Memory management code } 442 | Memoire_Initialisee:=False; { First Start !!! } 443 | DetecteMemoire(ShowMem); 444 | MMSS_FreeMemory; 445 | 446 | MMSS_EMS_First:=False; {EMS_presente;} 447 | MMSS_Use_UMB:=UMB_presente; 448 | 449 | { Detect and initialize the audio devices } 450 | Init_Output_Devices(ShowDevice); 451 | End; 452 | 453 | BEGIN 454 | { Writeln('InitModm'); } 455 | 456 | { Initialise les pointeurs Mod Master } 457 | PInit_Tables(TablePtr); 458 | 459 | MMSS_Table:=TablePtr.Table; 460 | MMSS_CFG:=TablePtr.Variables; 461 | MMSS_Info:=TablePtr.Info; 462 | Musique:=TablePtr.Musique; 463 | 464 | 465 | If MMSS_Table^.Controle<>73 Then 466 | Begin 467 | Writeln('MMSS_Table^ Err'); Halt(1) 468 | End; 469 | 470 | If MMSS_CFG^.Controle<>73 Then 471 | Begin 472 | Writeln('MMSS_CFG^ Err'); Halt(1) 473 | End; 474 | 475 | If MMSS_Info^.Controle<>73 Then 476 | Begin 477 | Writeln('MMSS_Info^ Err'); Halt(1) 478 | End; 479 | 480 | If Musique^.Controle<>73 Then 481 | Begin 482 | Writeln('Musique^ Err'); Halt(1) 483 | End; 484 | 485 | MMSS_Info^.DMA_Buffers_Max_Size:=Max_Buffer_Samples_Nb; 486 | 487 | SauveExit:=ExitProc; { Mise en place de la routine de fin } 488 | ExitProc:=@Routine_Fin; 489 | END. -------------------------------------------------------------------------------- /TPUNIT/MM_OTHER/MT_DEFS.INC: -------------------------------------------------------------------------------- 1 | (* 2 | This include file contains compile-time definitions that control various 3 | things you might or might not want to do when compiling MONOTONE. To enable 4 | an option, remove the double-brace; to disable, put it back or UNDEFINE it. 5 | *) 6 | 7 | {{$DEFINE DEBUG} {Enable if you need to debug TPlayer^.CalcAllData. Will call 8 | on each idle event instead of in the interrupt handler, allowing single-step 9 | of the source (except the output.setallchannels method).} 10 | 11 | {{$DEFINE OPT8088} {If OPT8088 set, 8088 assembly will be used for speed} 12 | 13 | {$IFDEF DEBUG} 14 | {$DEFINE PROFILE} {Select whether or not we'll be visually profiling the code} 15 | {$ENDIF} 16 | 17 | {Select method of profiling} 18 | {$IFDEF PROFILE} 19 | {$DEFINE CGAPROF} {profile visually using CGA MC6845 borders} 20 | {{$DEFINE VGAPROF} {profile visually using VGA} 21 | {$ENDIF} 22 | 23 | {{$DEFINE EVILINT} {"Evil" hooked interrupts don't call the original 24 | interrupt. Define this for a speed boost at the expense of being nice to 25 | the rest of the machine.} 26 | 27 | {$DEFINE PITDIVS} {if defined, diskwriter outputs PIT divisor values 28 | instead of frequencies} 29 | 30 | {$DEFINE NOTRACKER} {Remove the Tracker code to keep only the Player } 31 | {$DEFINE MODMASTER} {To update the Mod Master Music infos and playing infos for Display} -------------------------------------------------------------------------------- /TPUNIT/MM_OTHER/MT_EDIT.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/MM_OTHER/MT_EDIT.PAS -------------------------------------------------------------------------------- /TPUNIT/MM_OTHER/MT_GLOB.PAS: -------------------------------------------------------------------------------- 1 | {$I MT_DEFS.INC} 2 | 3 | unit mt_glob; 4 | {global constants and common type definitions used by other objects 5 | throughout the system} 6 | 7 | interface 8 | 9 | const 10 | {Our note system in general, which is based off of an equal temperament 11 | scale where each whole note interval is based on the twelfth root of 2.} 12 | (*maxNote=88; {maximum note. notes go from 1 to 88, 0 will be equiv to nul}*) 13 | noteEnd=127; {stop sounding!} 14 | noteNul=0; {do nothing} 15 | 16 | {this section describes the properties of our music system. If you want 17 | to convert MONOTONE to compose for, say, a pentatonic scale, this is where 18 | you change things.} 19 | numOctaves=8; {number of octaves we support} 20 | firstHz=27.5; {Frequency of A0, the first note (byte value=1) of our scale} 21 | IBO=12; {our music system's Intervals Between Octaves. We use typical 22 | system of equal temperament, which is 12 notes from octave to octave.} 23 | IBN=8; {This is the number of Intervals Between Notes, so we can build a 24 | table used for vibrato and portamento. An IBN of 8 is approximately 12 cents. 25 | To find mult. factor for a table of 8 intervals between notes, use root(IBO*8,2)} 26 | maxNote=3+(numOctaves*IBO)+1; {the room on the bottom is for a/a#/b; on top is for tippy-top C} 27 | validNoteRange=[1..maxNote]; 28 | 29 | maxChannels=12; {this will increase in the future when I add CMS support} 30 | maxRows=64; {number of rows per pattern} 31 | 32 | type 33 | {list of actions the user can request independent of the input device used} 34 | {If you alter this, you MUST alter the labels for these actions in mt_input} 35 | userActions=( 36 | {screen selection - only four for now in case we want to go with 80x25} 37 | goTrackerScreen, {main editing screen} 38 | goHelpScreen, {displays basic user help} 39 | goStatusScreen, {status screen showing the freq/vol/eff of each track} 40 | goPianoScreen, {screen where user can practice notes on the keyboard} 41 | 42 | {pattern movement} 43 | moveup,movedown,moveleft,moveright,movetop,movebottom,movepgup,movepgdn, 44 | 45 | {tracker movement} 46 | nextpattern,prevpattern,nextarea,prevarea, {nextarea usually TAB and 47 | goes between the various areas of the screen (pattern editor, order 48 | editor, title, etc.)} 49 | 50 | {tracker editing} 51 | c,csharp,d,dsharp,e,f,fsharp,g,gsharp,a,asharp,b, 52 | c2,csharp2,d2,dsharp2,e2,f2,fsharp2,g2,gsharp2,a2,asharp2,b2, 53 | noteoff,erasenote, 54 | enter,erase, 55 | octaveup,octavedown, 56 | deleterow,insertrow, 57 | erasetrack,mark,swaptrack,pastetrack,pastepattern, 58 | transup,transdown,transupoctave,transdownoctave, 59 | loadsong,savesong, 60 | 61 | {playing} 62 | playsongtop,playsongcur,playpattern,stopplaying, 63 | 64 | {toggling playback channels on/off} 65 | tc1,tc2,tc3,tc4,tc5,tc6,tc7,tc8,tc9,tc10,tc11,tc12, 66 | 67 | {misc} 68 | quit, 69 | writeout 70 | ); 71 | 72 | videochoices=(truecga,generic); 73 | audiochoices=(PIT,PIT2,PIT3,PIT4,SN76489,SAA_1099,AY_3_8910,YM3812,TANDYCOMBO); 74 | str80=string[80]; 75 | str40=string[40]; 76 | str12=string[12]; 77 | str2=string[2]; 78 | 79 | 80 | {error strings needed for fatalerror across multiple units} 81 | const 82 | es_NotEnoughMemory:PChar= 83 | 'Insufficient RAM to complete operation'; 84 | 85 | implementation 86 | 87 | end. 88 | -------------------------------------------------------------------------------- /TPUNIT/MM_OTHER/SAV_MMM.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/MM_OTHER/SAV_MMM.PAS -------------------------------------------------------------------------------- /TPUNIT/MM_PARAM.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/MM_PARAM.PAS -------------------------------------------------------------------------------- /TPUNIT/MM_PLAY.PAS: -------------------------------------------------------------------------------- 1 | {************************************************************************} 2 | { MM_PLAY.PAS } 3 | { } 4 | { Manage Mod Master during the Replay (Display, Dos Shell...) } 5 | { } 6 | { AUTEUR: Freddy V�tel�. } 7 | { } 8 | { } 9 | { Code Start the 30/08/95 } 10 | { Last Update the 10/19 } 11 | {************************************************************************} 12 | 13 | UNIT MM_PLAY; 14 | 15 | {$A+,G-,Q-,R-,S-} 16 | {$I MODMCFG.INI} 17 | 18 | 19 | INTERFACE 20 | 21 | USES Crt,Dos,Texte,Util,Memoire,Clavier,SBUnit,ModmUnit,MM_Var,MM_DIV, 22 | MMSS_Var 23 | {$IFDEF MONOTONE} 24 | ,mt_edit,mt_play 25 | {$ENDIF} ; 26 | 27 | 28 | {$IfNDEF CGAOnly} 29 | PROCEDURE Affiche_Boule(Position:Word; Couleur:Byte); 30 | PROCEDURE Aff_Graph; 31 | PROCEDURE Init_Palette_Graphique; 32 | {$ENDIF} 33 | PROCEDURE MM_Playing_Interface; { Affichage pendant la musique... } 34 | PROCEDURE MM_Init_PlayingScreen_Text; 35 | PROCEDURE MM_Display_PlayingScreen_Text; 36 | PROCEDURE Display_ModInfo_Frame; 37 | PROCEDURE Display_AdlInfo_Frame; 38 | PROCEDURE Shell; 39 | PROCEDURE Centrer_Titre; 40 | 41 | IMPLEMENTATION 42 | 43 | VAR TitreCentre27: Array[1..27] of Char; 44 | OldInt2F : Pointer; 45 | 46 | CONST 47 | position_msg:String[22]='Pattern Line'; 48 | tempo_msg :String[22]='Tempo BPM Gvol'; 49 | volume_msg :String[6] ='Volume'; 50 | 51 | {=========================================================} 52 | 53 | 54 | PROCEDURE MM_Playing_Interface; { Affichage pendant la musique... } 55 | Begin 56 | 57 | Changer_Affichage:=True; 58 | Clignotement(True); 59 | Curseur(off); 60 | 61 | Repeat 62 | If Activer_Shell Then 63 | Begin 64 | Shell; { Lancer le Shell } 65 | Changer_Affichage:=True; 66 | Activer_Shell:=False; 67 | End; 68 | If Changer_Affichage Then 69 | Begin 70 | MM_Init_PlayingScreen_Text; 71 | Changer_Affichage:=False; 72 | End; 73 | MM_ASM_UpdateInterface; { Read Keys and Update the Display, in the Assembly code } 74 | { Manage the Keys in case of .MON file replay} 75 | {$IFDEF MONOTONE} 76 | if Musique^.Type_Module=T_MON then 77 | Case Key_ScanCode of 78 | 01: MMSS_CFG^.Output_Stopped:=True; 79 | 57: If MMSS_Info^.Pause then 80 | Begin { Disable Pause } 81 | MT_Player^.MyPlayer^.Send(pa_PlaySongCur); 82 | MMSS_Info^.Pause:=False; 83 | End 84 | else 85 | Begin { Enable Pause } 86 | MT_Player^.MyPlayer^.Send(pa_Stop); 87 | MMSS_Info^.Pause:=True; 88 | End; 89 | 77: MT_Player^.MyPlayer^.Send(pa_NextOrder); 90 | 75: MT_Player^.MyPlayer^.Send(pa_PrevOrder); 91 | {scanLeft EQU 75 ;retour rapide } 92 | End; 93 | {$ENDIF} 94 | { Attente du 50� de seconde } 95 | Repeat Until (Tick_50Hz=1) OR MMSS_CFG^.Output_Stopped OR KeyPressed; 96 | 97 | Tick_50Hz:=0; 98 | Until MMSS_CFG^.Output_Stopped; { Attente de la fin de la musique } 99 | 100 | { If Fading Then Volume_Total:=Volume_Saved; } 101 | VideBufferClavier; 102 | End; {MM_Playing_Interface} 103 | 104 | {=========================================================} 105 | 106 | PROCEDURE MM_Init_PlayingScreen_Text; 107 | Begin 108 | Mode_Actuel:=Mode_Texte; 109 | MM_Display_PlayingScreen_Text; { PASCAL } 110 | If MMSS_Info^.MUS_OPLStream then Display_AdlInfo_Frame 111 | Else Display_ModInfo_Frame; 112 | Affiche_Ecran_Texte; { ASM } 113 | Change_aff_centre:=True; 114 | End; 115 | 116 | {---------------------------------------------------------} 117 | 118 | PROCEDURE LigneDessus(x,y,xfin: Byte); 119 | Var Pos,Cmpt:Word; 120 | Begin 121 | Pos:=2*(x-1)+160*(y-1); 122 | Cmpt:=xfin-x; 123 | ASM 124 | PUSH DS 125 | MOV AX,SegTexte 126 | MOV ES,AX 127 | MOV DI,Pos 128 | MOV AX,256*112+220 129 | MOV CX,Cmpt 130 | INC CX 131 | REP STOSW 132 | POP DS 133 | End 134 | End; {LigneDessus} 135 | 136 | {---------------------------------------------------------} 137 | 138 | PROCEDURE LigneH(x,y,xfin: Byte; Caractere:Char); 139 | Var Pos,Cmpt:Word; 140 | Begin 141 | Pos:=2*(x-1)+160*(y-1); 142 | Cmpt:=xfin-x; 143 | ASM 144 | PUSH DS 145 | MOV AX,SegTexte 146 | MOV ES,AX 147 | MOV DI,Pos 148 | MOV AH,112 149 | MOV AL,Caractere 150 | MOV CX,Cmpt 151 | INC CX 152 | REP STOSW 153 | POP DS 154 | End 155 | End; {LigneH} 156 | 157 | {---------------------------------------------------------} 158 | 159 | PROCEDURE LigneV(x,yh,yb:Byte; Caractere:Char; Attr:Byte); 160 | Var Pos,Cmpt:Word; 161 | Begin 162 | Pos:=2*(x-1)+160*(yh-1); 163 | Cmpt:=yb-yh+1; 164 | ASM 165 | PUSH DS 166 | MOV AX,SegTexte 167 | MOV ES,AX 168 | MOV AH,Attr 169 | MOV AL,Caractere 170 | MOV DI,Pos 171 | MOV CX,Cmpt 172 | @boucle: 173 | STOSW 174 | ADD DI,160-2 175 | LOOP @boucle 176 | POP DS 177 | End 178 | End; {LigneV} 179 | 180 | {---------------------------------------------------------} 181 | { Display the Main Frame during the replay } 182 | 183 | PROCEDURE MM_Display_PlayingScreen_Text; 184 | 185 | Begin 186 | 187 | { Screen Cleanup and Horizontal Lines } 188 | ASM 189 | { PUSH DS} 190 | PUSH ES 191 | MOV AX,SegTexte 192 | MOV ES,AX 193 | XOR DI,DI 194 | 195 | MOV AX,256*31+' ' 196 | MOV CX,80 197 | REP STOSW {efface ligne 1 en blue } 198 | 199 | MOV AH,112 200 | MOV CX,80*(4-2+1) 201 | REP STOSW {efface lignes 2,3 en blanc } 202 | 203 | MOV AH,0 204 | MOV CX,80*(23-5+1) 205 | REP STOSW {efface le reste de l'�cran en noir } 206 | 207 | MOV AH,112 208 | MOV CX,80 209 | REP STOSW {Line 24 in white } 210 | 211 | MOV AX,256*31+' ' 212 | MOV CX,80 213 | REP STOSW {Put Last Line in Blue } 214 | POP ES 215 | End; 216 | 217 | AffChXY(0,32,1,'- MOD MASTER XT -',31); { Titre "Mod Master" } 218 | 219 | { Bottom line Display } 220 | AffChXY(0,72,25,'F1=Help',31); 221 | AffChXY (0,52,25,'Free Memory: '+EntierTexte(MemoireDOSLibre SHR 6,3)+'Kb',31); 222 | 223 | If Musique^.Type_Module=T_MON Then AffChXY(0,2,25,'PC Speaker',31) 224 | Else 225 | If (Musique^.Type_Module=T_SAT) or (Musique^.Type_Module=T_RAD) 226 | or (Musique^.Type_Module=T_RAW) or (Musique^.Type_Module=T_DRO) 227 | or (Musique^.Type_Module=T_IMF) then AffChXY(0,2,25,'Adlib (OPL2/OPL3)',31) 228 | Else 229 | If (Musique^.Type_Module=T_VGM) then 230 | Begin { VGM Stream Music } 231 | If (MMSS_CFG^.OtherMUS_Out AND M_OPL2)<>0 then AffChXY(0,2,25,'Adlib/OPL2 (YM3812)',31); 232 | If (MMSS_CFG^.OtherMUS_Out AND M_OPL3)<>0 then AffChXY(0,2,25,'OPL3 (YMF262)',31); 233 | If (MMSS_CFG^.OtherMUS_Out AND M_SN76489)<>0 then 234 | AffChXY(0,2,25,'Tandy/PC Jr (SN76489) ['+EntierHexa(MMSS_CFG^.TDY_Port,3)+']',31); 235 | If (MMSS_CFG^.OtherMUS_Out AND M_SAA1099)<>0 236 | then AffChXY(0,2,25,'Game Blaster/CMS/SAA1099 ['+EntierHexa(MMSS_CFG^.CMS_Port,3)+']',31); 237 | End 238 | Else 239 | If MMSS_CFG^.Wave_Output=GUS Then AffChXY(0,2,25,'Gravis UltraSound',31) 240 | Else 241 | Begin 242 | If MMSS_CFG^.Wave_Output in [SB,SBPro] 243 | then AffChXY(0,18,25,SBName[SBConfig.Type_],31) 244 | else AffChXY(0,18,25,MMSS_Output_Name[MMSS_CFG^.Wave_Output],31); 245 | If MMSS_CFG^.Wave_Output=HPint then AffChXY(0,2,25,EntierTexte(MMSS_CFG^.Out_Frequency,5)+' Hz 6Bit',31) 246 | Else If MMSS_CFG^.Out_16Bit then AffChXY(0,2,25,EntierTexte(MMSS_CFG^.Out_Frequency,5)+' Hz 16Bit',31) 247 | Else AffChXY(0,2,25,EntierTexte(MMSS_CFG^.Out_Frequency,5)+' Hz 8Bit',31); 248 | End; 249 | 250 | End; {MM_Display_PlayingScreen_Text} 251 | 252 | { Title, Volume and period bar, Infos } 253 | 254 | Procedure Display_ModInfo_Frame; 255 | 256 | Begin 257 | 258 | LigneV(1,4,24,' ',112); {Left Border } 259 | LigneV(80,4,24,' ',112); {Right Border } 260 | { LigneH(25,4,53,' '); } {Title / Infos Rectangle } 261 | 262 | AffChXY(0,26,4,TitreCentre27,15); 263 | AffChXY(0,27,6,position_msg,2); 264 | AffChXY(0,27,7,tempo_msg,2); 265 | AffChXY(0,27,8,volume_msg,2); 266 | 267 | LigneH(2,4,24,chr(220)); {Pitch Bar Rectangle } 268 | LigneH(2,9,24,chr(223)); 269 | 270 | LigneH(26,3,52,chr(220)); {Title / Infos Rectangle } 271 | LigneH(26,9,52,chr(223)); {fenetre infos } 272 | 273 | LigneH(54,4,79,chr(220)); {fenetre barres periode } 274 | LigneH(54,9,79,chr(223)); 275 | 276 | LigneH(2,10,79,chr(220)); {fen�tre centrale } 277 | 278 | LigneV(25,5,9,' ',112); {separation fenetres pitch/centrale } 279 | LigneV(53,5,9,' ',112); {separation fenetres centrale/periode} 280 | End; 281 | 282 | Procedure Display_AdlInfo_Frame; 283 | Begin 284 | 285 | LigneV(1,4,24,' ',112); {Left Border } 286 | LigneV(80,4,24,' ',112); {Right Border } 287 | 288 | LigneH(26,3,52,chr(220)); 289 | LigneH(26,5,52,chr(223)); 290 | { LigneH(2,4,79,' ');} 291 | LigneH(2,5,25,' '); 292 | LigneH(53,5,79,' '); 293 | 294 | AffChXY(0,26,4,TitreCentre27,15); 295 | End; 296 | 297 | {---------------------------------------------------------} 298 | 299 | {$F+} 300 | PROCEDURE NewInt2F; Interrupt; 301 | 302 | Begin 303 | ASM 304 | CMP AX,60FFh 305 | JNE @Non 306 | CMP DL,0 307 | JNE @Non 308 | CMP BX,5344h { SD } 309 | JNE @Non 310 | CMP CX,4D50h { MP } 311 | JNE @Non 312 | MOV AX,1234h { 1234h => Mod Master pr�sent !!! } 313 | @Non: 314 | PUSHF 315 | CALL OldInt2F 316 | End; 317 | End; 318 | {$F-} 319 | 320 | {---------------------------------------------------------} 321 | 322 | PROCEDURE Int2FOn; 323 | Begin 324 | SwapIntVec($2F,OldInt2F,@NewInt2F) 325 | End; 326 | 327 | {---------------------------------------------------------} 328 | 329 | PROCEDURE Int2FOff; 330 | Begin 331 | SwapIntVec($2F,OldInt2F,OldInt2F) 332 | End; 333 | 334 | {---------------------------------------------------------} 335 | 336 | PROCEDURE Shell; 337 | Var Mem_DOS_Libre: Word; 338 | anc_prompt,nouv_prompt: String80; 339 | Begin 340 | TextMode(LastMode); { Mode texte DOS } 341 | Mode_Actuel:=Autre_Mode; { Indique le changement de mode vid�o } 342 | Curseur(plat); 343 | Mem_DOS_Libre:=MemoireDOSLibre DIV 64; 344 | ClrScr; 345 | 346 | If Mem_DOS_Libre>=64 Then 347 | Begin 348 | Writeln('Free memory: ',Mem_DOS_Libre-2, 349 | 'ko - Type EXIT to return to Mod Master...',#13#10); 350 | anc_prompt:=GetEnv('PROMPT'); 351 | nouv_prompt:='[Mod Master] '; 352 | If anc_prompt<>'' Then nouv_prompt:=nouv_prompt+anc_prompt 353 | Else nouv_prompt:=nouv_prompt+'$p$g'; 354 | {$IFNDEF CGAOnly} 355 | FinSourisSmooth; 356 | {$ENDIF} 357 | Int2FOn; { Active l'IRQ de d�tection } 358 | SwapVectors; 359 | Exec(Getenv('COMSPEC'),'/K PROMPT '+nouv_prompt); 360 | SwapVectors; 361 | Int2FOff; { D�sactive l'IRQ de d�tection } 362 | {$IFNDEF CGAOnly} 363 | InitSourisSmooth(#166,#167,#169,#170); 364 | {$ENDIF} 365 | If DosError<>0 Then 366 | Begin 367 | If DosError=8 Then Writeln('Not enough memory!') 368 | Else WriteLn('DOS error #',DosError); 369 | Write('Hit ��...'); 370 | { Repeat Until Readkey=#13} 371 | End 372 | End 373 | Else 374 | Begin 375 | Write('Not enough memory (',MemoireDOSLibre,'ko). Hit ��...'); 376 | { Repeat Until Readkey=#13} 377 | End; 378 | 379 | { MM_InitTexte;} 380 | End; {Shell} 381 | 382 | {---------------------------------------------------------} 383 | 384 | PROCEDURE Centrer_Titre; 385 | Var i,Pos,Len:Byte; 386 | Begin 387 | 388 | FillChar(TitreCentre27,27,0); 389 | Pos:=0; 390 | Len:=27; 391 | With Musique^ do { Titre Centr� avec 27 caract�res } 392 | Begin 393 | Repeat { Chercher le 1� Caract�re } 394 | Inc(Pos); 395 | Dec(Len); 396 | Until ((Titre[Pos]<>#0) AND (Titre[Pos]<>#32)) OR (Pos=27); 397 | Inc(Len); 398 | If Pos<27 Then 399 | Begin { Chercher le dernier Caract�re } 400 | i:=28; 401 | Repeat 402 | Dec(i); 403 | Dec(Len); 404 | Until ((Titre[i]<>#0) AND (Titre[i]<>#32)) OR (i=1); 405 | Inc(Len); 406 | End; 407 | i:=1+(27-Len) SHR 1; 408 | Move(Titre[Pos],TitreCentre27[i],Len); 409 | End; 410 | 411 | End; {Centrer_Titre} 412 | 413 | {---------------------------------------------------------} 414 | 415 | PROCEDURE Afficher_Nom_Samples; 416 | Var i:Byte; 417 | Samp:^T_Sample; 418 | Begin 419 | {For i:=1 to 15 do 420 | Begin 421 | Samp:=MMSS_Table^.PtrSamples[i]; 422 | If Samp<>NIL Then AffChXY(0,14,12+i,Samp^.Nom,3) 423 | End;} 424 | End; {Afficher_Nom_Samples} 425 | 426 | {=========================================================} 427 | 428 | END. -------------------------------------------------------------------------------- /TPUNIT/MM_PROG.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/MM_PROG.PAS -------------------------------------------------------------------------------- /TPUNIT/MM_VAR.PAS: -------------------------------------------------------------------------------- 1 | UNIT MM_VAR; 2 | {unite pour Mod Master: types, constantes et variables} 3 | { Change output names} 4 | { 19/06/19 Max files reduced to 255 } 5 | 6 | {$A+,G-,Q-,R-,S-} 7 | {$I MODMCFG.INI} 8 | 9 | INTERFACE 10 | 11 | {$IFNDEF CGAOnly} 12 | USES Texte,SourisSSm; 13 | {$ELSE} 14 | USES Texte,Sourisc; 15 | {$ENDIF} 16 | 17 | CONST REGISTERED=True; {pour le bridage...} 18 | LONG_PROG_LIMIT=10; {nombre de modules max. dans un programme brid�} 19 | 20 | Anglais=0; Francais=1; 21 | 22 | M_DefVol = 1; 23 | M_DefFreq = 2; 24 | M_NoFreq = 4; 25 | M_IMF = 8; 26 | 27 | D_Name = 0; 28 | D_Volume = 1; 29 | D_Freq = 2; 30 | 31 | TYPE langues=Anglais..Francais; 32 | 33 | T_module=Record 34 | Numero: Byte; { Number in the program } 35 | Taille,Volume: Word; 36 | Frequency:Word; 37 | Default_Mask: Byte; { Volume_defaut } 38 | Nom: String[14]; { File Name } 39 | Titre: String20; 40 | Valide: Boolean 41 | End; 42 | 43 | 44 | CONST version_min_PRG: Array[1..3] of Char='2.0'; 45 | version_min_DIR: Array[1..3] of Char='2.1'; 46 | 47 | {version: Array[1..3] of Char='2.2';} 48 | ident_ModM: Array[1..18] of Char='Mod Master XT 1.02'; 49 | 50 | MODM: Array[1..4] of Char='MODM'; 51 | 52 | copyright_String: Array[1..30] of Char= {'- (c) Copyright 1995 Freddy V�tel� & Fabrice Couteau -'} 53 | '- (c) Copyright 2024 FreddyV -'; 54 | 55 | ext_MOD=1; ext_SD0=2; ext_NST=3; ext_WOW=4; ext_OCT=5; 56 | ext_STM=6; ext_S3M=7; ext_669=8; ext_DTM=9; ext_MTM=10; 57 | ext_ULT=11; ext_FAR=12; ext_SAT=13; ext_XM=14; ext_MMM=15; 58 | ext_VGM=16; ext_VGZ=17; ext_RAD=18; 59 | ext_IMF=19; ext_WLF=20; ext_RAW=21; ext_DRO=22; ext_MID=23; 60 | 61 | {$IFDEF MONOTONE} 62 | nbr_extensions=24; 63 | ext_MON=24; 64 | {$ELSE} 65 | nbr_extensions=23; 66 | {$ENDIF} 67 | 68 | Extensions: Array[1..nbr_extensions] of String3 69 | =('MOD','SD0','NST','WOW','OCT', 70 | 'STM','S3M','669','DTM','MTM', 71 | 'ULT','FAR','SAT','XM','MMM', 72 | 'VGM','VGZ','RAD','IMF','WLF', 73 | 'RAW','DRO','MID' 74 | {$IFDEF MONOTONE} 75 | ,'MON' 76 | {$ENDIF} 77 | ); 78 | CouleursExt: Array[1..nbr_extensions] of Byte 79 | =( 1, 1, 1, 1, 1, 80 | 10, 10, 5, 5, 9, { 4 rouge 9 Bleu Fonce } 81 | 9, 9, 4, 11, 8, { 2,3 Trop clair} 82 | 13, 12, 6, 9, 9, 83 | 9, 9 , 9 84 | {$IFDEF MONOTONE} 85 | , 4 86 | {$ENDIF} 87 | ); 88 | 89 | nbr_fich_max=255; {nombre maximal de fichiers dans un r�pertoire (Previously 512)} 90 | nbr_boutons=11; {nombre de boutons dans le menu} 91 | 92 | bt_Sortie =1; 93 | bt_Options =2; 94 | bt_IntroScan=3; 95 | bt_Shuffle =4; 96 | bt_Lecture =5; 97 | bt_Tout =6; 98 | bt_Efface =7; 99 | bt_Charge =8; 100 | bt_Sauve =9; 101 | bt_Aide =10; 102 | bt_Quitte =11; 103 | 104 | Erreurs: Array[1..23] of String[26] =( 105 | 'Drive','not ready','Insert a disk','Insert a CD-Rom', 106 | 'Disk read error','Change the disk', 107 | 'Disk write error', 108 | 'Disk is write-','protected', 109 | 'Path','not found','File(s) not found', 110 | 'Not enough memory','to load', 111 | 'Format error in', 112 | 'Error while opening', 113 | 'does not exist anymore', 114 | 'the program', 115 | 'New drive', 116 | 'Can''t load samples from', 117 | 'Version not supported in', 118 | 'Format not supported in', 119 | 'File Protected'); 120 | 121 | Play_Err:Array[1..13] of String[17] = ( 122 | 'Output Not Found', 123 | 'SB Timeout', 124 | 'Invalid Freq', 125 | 'Computer too Slow', 126 | 'Music Not Loaded', 127 | 'Invalid Ch Number', 128 | 'Invalid Format', 129 | 'Adlib Not Found', 130 | 'OPL3 Not Found', 131 | 'TDY Not Found', 132 | 'Bad VGM Command', 133 | 'CMS Not Found', 134 | 'PSG Not Found'); 135 | 136 | 137 | lecteur_txt =1; 138 | pas_pret_txt =2; 139 | inserez_disq_txt =3; 140 | inserez_CDRom_txt =4; 141 | err_lecture_txt =5; 142 | changez_disq_txt =6; 143 | err_ecriture_txt =7; 144 | disq_protegee_txt =8; 145 | en_ecriture_txt =9; 146 | chemin_txt =10; 147 | introuvable_txt =11; 148 | fich_introuv_txt =12; 149 | mem_insuff_txt =13; 150 | pour_charger_txt =14; 151 | err_format_txt =15; 152 | err_pendant_lect_txt=16; 153 | nexiste_plus_txt =17; 154 | le_prog_txt =18; 155 | nouveau_lecteur_txt =19; 156 | pas_instrument_txt =20; 157 | version_inconnue_txt=21; 158 | format_non_gere_txt =22; 159 | Fichier_Protege_txt =23; 160 | 161 | VAR boutons: Array[1..nbr_boutons] of Bouton; 162 | nbr_fich,nbr_modules,premier_module, 163 | erreur_fin: Word; 164 | Module: Array[1..nbr_fich_max] of T_module; { Table used to store the files/Folders information } 165 | nom_programme: String[8]; 166 | page_menu: Ecran; 167 | 168 | duree_IntroScan,SB_LeftVol,SB_RightVol, 169 | delai_economiseur : Byte; 170 | MM_Default_Volume : Word; { Default Volume } 171 | MM_Default_Frequency : Word; { Default Frequency } 172 | Use_SBVGM : Boolean; { Set to true when Mod Master does not support the VGM File } 173 | 174 | mode_interactif,affiche_syntaxe,recharge_module, 175 | CFG_present,PRG_present,Utilise_economiseur, 176 | affiche_titre,volume_modifie: Boolean; 177 | File_Display_Mode : Byte; 178 | MM_Hercule : Boolean; 179 | 180 | {==========================================================} 181 | 182 | IMPLEMENTATION 183 | 184 | END. -------------------------------------------------------------------------------- /TPUNIT/MODMCFG.INI: -------------------------------------------------------------------------------- 1 | { MOD Master Defines } 2 | {$DEFINE CGAOnly} 3 | {$UNDEF NoMouse} 4 | 5 | {$UNDEF MONOTONE} 6 | {$UNDEF MODMTINY} { Remove MOD, S3M and XT } 7 | {$DEFINE MODMLITE} { Remove 669, STM, FAR, DTM, MTM and ULT} 8 | 9 | {$UNDEF NoSAT} 10 | 11 | { Mod Master SS Defines } 12 | 13 | { To reduce the code size you can change the Max_Channels,Max_Samples and Max_Pattern in MMSS_VAR } 14 | { You can alse remove the Adlib and GUS code if not needed } 15 | { Change must be done in MODM_SS.ASM as well } 16 | 17 | {$UNDEF Groupe} { To support multiple file loading in one file } 18 | {$DEFINE ModeXT} { Remove 286 code and VGA } 19 | 20 | {$DEFINE LOADALL} { Load all the samples (Not applicable to MMM Files )} 21 | {$UNDEF MMMONLY} { Load Only MMM Files } { Save 4Kb } 22 | 23 | {$UNDEF NoOPL} { Add / Remove OPL2 Support} { Save 1.5Kb} 24 | {$UNDEF NoGUS} { Add / Remove OPL2 Support} { Save 7Kb } 25 | {$DEFINE MIX16} { Allow 16Bit Mixing } 26 | 27 | -------------------------------------------------------------------------------- /TPUNIT/MODMUNIT.PAS: -------------------------------------------------------------------------------- 1 | {************************************************************************} 2 | { MODMUNIT.PAS V2.2 } 3 | { } 4 | { Interface entre le pascal et les routines sonores de Mod Master. } 5 | { } 6 | { AUTEUR: Freddy V�tel�. } 7 | { } 8 | { } 9 | { Dernieres modifications le 28/01/2020 } 10 | {************************************************************************} 11 | 12 | {$DEFINE MODM} { Define for the Full Mod Master } 13 | 14 | {$IFDEF MODM} 15 | UNIT MODMUNIT; {Unit for MODM.PAS} 16 | {$ELSE} 17 | UNIT MODM_SS; {Unit for Standalone Sound System} 18 | {$ENDIF} 19 | 20 | {$A+,G-,Q-,R-,S-} 21 | {$I MODMCFG.INI} 22 | 23 | {$UNDEF DEBUG } 24 | INTERFACE 25 | 26 | TYPE String80=String[80]; 27 | 28 | VAR SauveExit : POINTER; { Sauvegarde de l'ancienne routine de fin } 29 | DisplayText : Boolean; 30 | 31 | {=========================================================} 32 | {$IFDEF MODM} 33 | PROCEDURE Affiche_Ecran_Texte; 34 | PROCEDURE MM_ASM_UpdateInterface; 35 | {$ENDIF} 36 | 37 | PROCEDURE WaveOut_SetDefault(W_Number: Byte); { Configure the default values and the output number } 38 | FUNCTION MMSS_Start_Output: Byte; { Start Audio Output } 39 | PROCEDURE MMSS_Stop_Output; { Stop audio Output } 40 | FUNCTION MMSS_Start_Music: Word; { Init Music Variables } 41 | PROCEDURE MMSS_Stop_Musique; 42 | PROCEDURE MMSS_Init(ShowMem:Boolean;ShowDevice:Boolean); 43 | 44 | {$IFNDEF MODM} { Functions for Mod Master Sound System Only } 45 | PROCEDURE MMSS_StartIRQ; 46 | PROCEDURE MMSS_StopIRQ; 47 | FUNCTION MMSS_TestIRQ:Byte; 48 | {$ENDIF} 49 | 50 | {=========================================================} 51 | 52 | IMPLEMENTATION 53 | 54 | USES Fichiers,Util,BIOSEQU,MMSS_Var,MMSS_CMD,VarUnit,Memoire,CHUtil,Texte,Clavier, 55 | SBUnit,TDYUnit,PSGUnit, 56 | {$IFNDEF NoGUS} 57 | GusUnit, 58 | {$ENDIF} 59 | CRT,MMSS_Mem; 60 | 61 | { MODMPAS.OBJ External Variables definition } 62 | 63 | {$F+} 64 | 65 | {PROCEDURE Affiche_Ecran_Graphique; External;} 66 | 67 | {$IFDEF MODM} 68 | PROCEDURE Affiche_Ecran_Texte; External; 69 | PROCEDURE MM_ASM_UpdateInterface; External; 70 | PROCEDURE MMSS_Refresh_Debug; External; 71 | {$ENDIF} 72 | 73 | PROCEDURE PInit_Tables(Var dest); External; 74 | FUNCTION PStart_Output:Word; External; 75 | FUNCTION PStart_Music:Word; External; 76 | 77 | {$IFNDEF MODM} 78 | PROCEDURE MMSS_StartIRQ; External; 79 | PROCEDURE MMSS_StopIRQ; External; 80 | FUNCTION MMSS_TestIRQ:Byte; External; 81 | {$ENDIF} 82 | {$F-} 83 | 84 | {$IFDEF MODM} 85 | {$L MODMPAS} 86 | {$ELSE} 87 | {$L MODM_SS} 88 | {$ENDIF} 89 | 90 | {=========================================================} 91 | 92 | {---------------------------------------------------------} 93 | { Mod Master XT : Removed Adlib, sound Master > No more needed } 94 | PROCEDURE WaveOut_Init; 95 | Var Panning_GUS : Byte; 96 | 97 | Begin 98 | 99 | Case MMSS_CFG^.Wave_Output of 100 | {$IFNDEF NoGUS} 101 | GUS: Begin { Init and configure the Panning } 102 | If Musique^.Ch_Number_Digit>14 Then UltraReset(Musique^.Ch_Number,MMSS_CFG^.GUS_InterWave) 103 | Else UltraReset(14,MMSS_CFG^.GUS_InterWave); 104 | End; 105 | {$ENDIF} 106 | SB,SBPro: Init_DSP; 107 | {$IFNDEF ModeXT} 108 | {$IFNDEF NoOPL} 109 | { Adlib: Begin 110 | InitOPL2; 111 | Musique^.Ch_Number_Adlib:=0; 112 | If Musique^.Ch_Number_Digit>0 Then 113 | Begin 114 | EcrireOPL2(OPL2Test ,$20); 115 | EcrireOPL2(OPL2FB_FM ,$01); 116 | EcrireOPL2(OPL2AM_VIB ,$00); 117 | EcrireOPL2(OPL2AM_VIB+3,$27); 118 | EcrireOPL2(OPL2KSL_TL ,$00); 119 | EcrireOPL2(OPL2KSL_TL+3,$00); 120 | EcrireOPL2(OPL2AR_DR ,$00); 121 | EcrireOPL2(OPL2AR_DR+3 ,$FF); 122 | EcrireOPL2(OPL2SL_RR ,$00); 123 | EcrireOPL2(OPL2SL_RR+3 ,$0F); 124 | EcrireOPL2(OPL2WS ,$00); 125 | EcrireOPL2(OPL2WS+3 ,$02); 126 | EcrireOPL2(OPL2Fnum ,$0C); 127 | EcrireOPL2(OPL2Key ,$3F); 128 | EcrireOPL2($BD ,$20); 129 | End 130 | Else Erreur_Modm:=Err_Adlib; 131 | End;} 132 | {$ENDIF} 133 | End; 134 | {$ENDIF} 135 | End; 136 | End; {WaveOut_Init} 137 | 138 | {---------------------------------------------------------} 139 | 140 | PROCEDURE SoundEnd; 141 | Begin 142 | {$IFNDEF NoOPL} 143 | If (Musique^.Ch_Number_Adlib>0) and ((OPL_Model<>0) or (OPL_LPT_Model<>0)) Then InitOPL2; 144 | {$ENDIF} 145 | {$IFNDEF NoGUS} 146 | Case MMSS_CFG^.Wave_Output Of 147 | GUS: UltraReset(14,FALSE); 148 | End; 149 | {$ENDIF} 150 | End; {SoundEnd} 151 | 152 | {---------------------------------------------------------} 153 | 154 | FUNCTION MMSS_Start_Output:Byte; 155 | Var Err_Sort:Word; 156 | i:Word; 157 | Begin 158 | 159 | { No 16Bit Mixing for PC Speaker, No 16Bit output for Stereo } 160 | If (MMSS_CFG^.Wave_Output=HPint) and (MMSS_CFG^.Mix_16Bit) then MMSS_CFG^.Mix_16Bit:=False; 161 | {If (MMSS_CFG^.Utilise_Stereo) and (MMSS_CFG^.Mix_16Bit) and then 162 | If } 163 | 164 | If MMSS_CFG^.Output_Stopped Then 165 | Begin 166 | 167 | If Musique^.Ch_Number_Digit<>0 then 168 | Begin 169 | If MMSS_CFG^.Wave_Output<>GUS Then Init_Tables_Modm; { Initialize the Volume and Buffer Tables } 170 | MMSS_Adjust_Vol(Musique^.Ch_Number); 171 | WaveOut_Init; { Init the GUS Panning } 172 | End; 173 | 174 | {$IFNDEF NoOPL} 175 | If (Musique^.Ch_Number_Adlib>0) and ((OPL_Model<>0) or (OPL_LPT_Model<>0)) Then InitOPL2; 176 | {$ENDIF} 177 | 178 | Musique^.Note_Delta:=Musique^.Note_Size*(Musique^.Ch_Number_patt-Musique^.Ch_Number); 179 | 180 | Err_Sort:=PStart_Output; 181 | If Err_Sort<>Ok Then 182 | Begin 183 | MMSS_CFG^.Stop_Output:=False; 184 | MMSS_CFG^.Output_Stopped:=True; 185 | End; 186 | 187 | End 188 | Else Err_Sort:=Ok; 189 | {Writeln; 190 | Writeln('Mix_16Bit:',MMSS_CFG^.Mix_16Bit); 191 | Writeln('Out_16Bit:',MMSS_CFG^.Out_16Bit);} 192 | {Writeln('DMA Buffer '+EntierHexa(MMSS_CFG^.Seg_Table_Volume,4)+':'++EntierHexa(MMSS_CFG^.Offset_DMA_Buffer,4)); 193 | Writeln('Debug1 '+EntierHexa(MMSS_CFG^.debug1,4)); 194 | Writeln('Debug2 '+EntierHexa(MMSS_CFG^.debug2,4)); 195 | Writeln('Debug3 '+EntierHexa(MMSS_CFG^.debug3,4)); 196 | Writeln('Debug4 '+EntierHexa(MMSS_CFG^.debug4,4)); 197 | Writeln('Debug5 '+EntierHexa(MMSS_CFG^.debug5,4)); 198 | Writeln('Debug6 '+EntierHexa(MMSS_CFG^.debug6,4));} 199 | {Repeat Until Readkey=#13;} 200 | MMSS_Start_Output:=Err_Sort; 201 | End; {Start_Output} 202 | 203 | {---------------------------------------------------------} 204 | 205 | PROCEDURE MMSS_Stop_Output; 206 | Begin 207 | If Not MMSS_CFG^.Output_Stopped Then { Si musique termin�e, ne pas l'arr�ter } 208 | Begin 209 | MMSS_CFG^.Stop_Output:=True; 210 | Repeat Until MMSS_CFG^.Output_Stopped; 211 | End; 212 | SoundEnd; 213 | MMSS_CFG^.Stop_Output:=False; 214 | Fin_Tables_Modm; 215 | End; {MMSS_Stop_Output} 216 | 217 | {---------------------------------------------------------} 218 | 219 | FUNCTION MMSS_Start_Music:Word; 220 | Begin 221 | 222 | Move(Musique^.M_CH_Panning,MMSS_Info^.CH_Panning,Max_Channels); { Copy the Default Panning } 223 | With MMSS_CFG^ do If Not(Use_Panning_CMD) Then Calculer_Panning:=False; 224 | 225 | {$IFDEF DEBUG} 226 | Writeln('PStart_Music;'); 227 | {$ENDIF} 228 | MMSS_Start_Music:=PStart_Music; 229 | End; {MMSS_Start_Music} 230 | 231 | {---------------------------------------------------------} 232 | 233 | PROCEDURE MMSS_Stop_Musique; 234 | Begin 235 | If Not MMSS_CFG^.Musique_Term Then MMSS_CFG^.Musique_Term:=True; 236 | End; {MMSS_Stop_Musique} 237 | 238 | {---------------------------------------------------------} 239 | 240 | (*PROCEDURE ChangerConfigModm; 241 | { Changer la fr�quence et la sortie sonore sans arr�ter la musique } 242 | Begin 243 | If Not (MMSS_CFG^.Musique_Terminee) Then 244 | Begin 245 | MMSS_CFG^.Stop_Player:=True; 246 | Repeat Until MMSS_CFG^.Musique_terminee; 247 | If MMSS_CFG^.Wave_Output=GUS Then 248 | If Musique^.Ch_Number>14 Then UltraOpen(Ultra_Config,Musique^.Ch_Number) 249 | Else UltraReset(14); 250 | MMSS_CFG^.Stop_Player:=False; 251 | Ajuster_Out_Frequency; { Ajuster la fr�quence } 252 | PStart_Output; { Relancer la sortie } 253 | End; 254 | End; {ChangerConfigModm} *) 255 | 256 | {---------------------------------------------------------} 257 | 258 | { 259 | PROCEDURE Tester_Vitesse; 260 | BEGIN 261 | If MMSS_CFG^.Wave_Output<>GUS Then Init_Tables_Modm; 262 | AjusterVolume; 263 | Test_Vitesse; 264 | If MMSS_CFG^.Wave_Output<>GUS Then Fin_Tables_Modm; 265 | END;} {Tester_Vitesse} 266 | 267 | 268 | {---------------------------------------------------------} 269 | 270 | 271 | {---------------------------------------------------------} 272 | 273 | {$F+} 274 | PROCEDURE Routine_Fin; 275 | { Stopper la musique si fin du programme (en cas d'erreur) } 276 | Begin 277 | ExitProc:=SauveExit; 278 | MMSS_Stop_Output; 279 | MMSS_Stop_Musique; 280 | If MMSS_MUS_Loaded Then MMSS_FreeMemory; 281 | End; {Routine_Fin} 282 | {$F-} 283 | 284 | {---------------------------------------------------------} 285 | 286 | PROCEDURE WaveOut_SetDefault(W_Number: Byte); { Configure the default values and the output number } 287 | Begin 288 | With MMSS_CFG^ do 289 | Begin 290 | Case W_Number of 291 | Hpint, 292 | LPT1, 293 | LPT2, 294 | TDY_DAC, 295 | C_DAC : Out_Frequency:=10000; 296 | SB : With SBConfig do 297 | Begin 298 | Out_Frequency:=16000; 299 | Utilise_DC:=(Type_>1); 300 | Use_DMA:=True; 301 | SB_BasePort:=Port; 302 | IRQ_SB:=IRQ; 303 | DMA_SB8:=DMA8; 304 | DMA_SB16:=DMA16; 305 | MMType_SB:=Type_; { Type de carte } 306 | End; 307 | SBPro : Begin 308 | WaveOut_SetDefault(SB); 309 | Out_Frequency:=16000; 310 | Utilise_Stereo:=False; 311 | {Utilise_Mixage:=False;} 312 | Utilise_Filtre:=False; 313 | SBP_Filtre(False); 314 | SBP_MasterVolume(15,15); { Master Volume } 315 | SBMixerWrite(mxrMasterVolume,$FF) { Maximum DAC Volume } 316 | End; 317 | {$IFNDEF NoGUS} 318 | GUS : Begin 319 | MMSS_CFG^.GUS_BasePort:=Ultra_Base_Port; 320 | MMSS_CFG^.GUS_InterWave:=False; 321 | GUS_LineIn:=False; 322 | {MMSS_CFG^.GUS_IRQ:=Ultra_Config.GF1_IRQ_Num;} 323 | Taille_GUS:=UltraSizeDRAM 324 | End; 325 | {$ENDIF} 326 | End; 327 | Wave_Output:=W_Number { Init the Default selected Audio Output number } 328 | End 329 | End; {WaveOut_SetDefault} 330 | 331 | {---------------------------------------------------------} 332 | 333 | PROCEDURE Init_Output_Devices(ShowDevice:Boolean); { Executed only at the player Start } 334 | Var i:Byte; 335 | j:Word; 336 | 337 | Begin {Init_Config_Sonore} 338 | 339 | SB_LeftVol:=15; SB_RightVol:=15; 340 | MMSS_Def_LeftPan:=$20; MMSS_Def_RightPan:=$60; 341 | MMSS_Volume:=5*50; 342 | 343 | LPT_Nb:=0; 344 | j:=BiosSeg.LptBase[1]; 345 | If j <>0 Then 346 | Begin 347 | MMSS_CFG^.LPT1_Port:=j; 348 | MMSS_W_Output_Available[LPT1]:=True; 349 | If ShowDevice then Writeln('LPT1: ',EntierHexa(j,4)+'h '); 350 | LPT_Nb:=1 351 | End; 352 | 353 | j:=BiosSeg.LptBase[2]; 354 | If j <>0 Then 355 | Begin 356 | MMSS_CFG^.LPT2_Port:=j; 357 | MMSS_W_Output_Available[LPT2]:=True; 358 | If ShowDevice then Writeln('LPT2: ',EntierHexa(j,4)+'h '); 359 | LPT_Nb:=2 360 | End; 361 | 362 | If LPT_Nb=0 Then OPL_LPT_Nb:=0 363 | Else OPL_LPT_Nb:=1; 364 | TDY_LPT_Nb:=OPL_LPT_Nb; 365 | CMS_LPT_Nb:=OPL_LPT_Nb; 366 | 367 | {$IFNDEF ModeXT} { Crash on MegaEM } 368 | {Writeln('Detecte_DSS'); 369 | Detecte_DSS(True);} 370 | {$ENDIF} 371 | 372 | { Tandy Detection } 373 | {Writeln('TDY_DetectDAC');} 374 | TDY_DetectDAC; 375 | If TDY_DACPort<>0 Then 376 | Begin 377 | If ShowDevice then Writeln('Tandy DAC Detected: ',EntierHexa(TDY_Port,3)); 378 | MMSS_W_Output_Available[TDY_DAC]:=True; 379 | MMSS_CFG^.TDYDAC_Port:=TDY_DACPort 380 | End 381 | Else 382 | Begin 383 | If TDY_Type<>1 Then 384 | Begin 385 | {Writeln('TDY_DetectOld');} 386 | TDY_DetectOld; 387 | End; 388 | If TDY_Type=1 Then 389 | If ShowDevice then Writeln('Tandy 1000/PC Junior Detected: ',EntierHexa(TDY_Port,3)); 390 | MMSS_W_Output_Available[TDY_DAC]:=False; 391 | End; 392 | 393 | { Check for the Port Nb in the list } 394 | TDY_PortNb:=0; 395 | If TDY_Type<>0 then 396 | For i:=0 to TDY_PortTotal do 397 | If TDY_Port=TDY_PortList[i] then TDY_PortNb:=i; 398 | if TDY_PortNb=0 then 399 | begin 400 | TDY_PortNb:=3; { By default, Port 2C0 } 401 | TDY_Port:=TDY_PortList[TDY_PortNb] 402 | end; 403 | 404 | MMSS_CFG^.TDY_Type:=TDY_Type; 405 | MMSS_CFG^.TDY_Port:=TDY_Port; 406 | 407 | {$IFNDEF NoGUS} 408 | {Writeln('GUS_Detect(ShowDevice);');} 409 | GUS_Detect(ShowDevice); 410 | MMSS_W_Output_Available[GUS]:=GUS_Presente; 411 | {$ELSE} 412 | MMSS_W_Output_Available[GUS]:=False; 413 | {$ENDIF} 414 | 415 | {Writeln('SB_Detect(ShowDevice);');} 416 | SB_Detect(ShowDevice); { Detect the OPL and SB to SB16 } 417 | 418 | MMSS_CFG^.OPL_Model:=OPL_Model; 419 | MMSS_W_Output_Available[HPint] :=True; 420 | MMSS_W_Output_Available[C_DAC] :=False; {Declared in the Command Line or Config File} 421 | If SB_presente and Not SBPro_Presente then MMSS_W_Output_Available[SB]:=True 422 | Else MMSS_W_Output_Available[SB]:=False; 423 | MMSS_W_Output_Available[SBPro] :=SBPro_presente; 424 | 425 | For i:=0 to (MMSS_Out_Nb_W-1) do If MMSS_W_Output_Available[i] Then WaveOut_SetDefault(i); 426 | 427 | {$IFNDEF NoGUS} 428 | If GUS_presente Then MMSS_BestOutput:=GUS 429 | Else 430 | {$ENDIF} 431 | If SBPro_presente Then MMSS_BestOutput:=SBPro 432 | Else If SB_presente Then MMSS_BestOutput:=SB 433 | Else If TDY_Port<>0 Then MMSS_BestOutput:=TDY_DAC 434 | Else MMSS_BestOutput:=HPint; 435 | 436 | MMSS_CFG^.Wave_Output:=MMSS_BestOutput; 437 | End; {Init_Config_Sonore} 438 | 439 | {==========================================================} 440 | { Initialisation de MODM_U } 441 | {==========================================================} 442 | 443 | PROCEDURE MMSS_Init (ShowMem:Boolean;ShowDevice:Boolean); 444 | 445 | Begin 446 | { Init the Memory management code } 447 | Memoire_Initialisee:=False; { First Start !!! } 448 | DetecteMemoire(ShowMem); 449 | MMSS_FreeMemory; 450 | 451 | MMSS_EMS_First:=False; {EMS_presente;} 452 | MMSS_Use_UMB:=UMB_presente; 453 | 454 | { Detect and initialize the audio devices } 455 | Init_Output_Devices(ShowDevice); 456 | End; 457 | 458 | BEGIN 459 | { Writeln('InitModm'); } 460 | 461 | { Initialise les pointeurs Mod Master } 462 | PInit_Tables(TablePtr); 463 | 464 | MMSS_Table:=TablePtr.Table; 465 | MMSS_CFG:=TablePtr.Variables; 466 | MMSS_Info:=TablePtr.Info; 467 | Musique:=TablePtr.Musique; 468 | 469 | 470 | If MMSS_Table^.Controle<>73 Then 471 | Begin 472 | Writeln('MMSS_Table^ Err'); Halt(1) 473 | End; 474 | 475 | If MMSS_CFG^.Controle<>73 Then 476 | Begin 477 | Writeln('MMSS_CFG^ Err'); Halt(1) 478 | End; 479 | 480 | If MMSS_Info^.Controle<>73 Then 481 | Begin 482 | Writeln('MMSS_Info^ Err'); Halt(1) 483 | End; 484 | 485 | If Musique^.Controle<>73 Then 486 | Begin 487 | Writeln('Musique^ Err'); Halt(1) 488 | End; 489 | 490 | MMSS_Info^.DMA_Buffers_Max_Size:=Max_Buffer_Samples_Nb; 491 | 492 | SauveExit:=ExitProc; { Mise en place de la routine de fin } 493 | ExitProc:=@Routine_Fin; 494 | END. -------------------------------------------------------------------------------- /TPUNIT/PASMODM/BIOSDISK.PAS: -------------------------------------------------------------------------------- 1 | { Interrupt 13h Floppy fonctions } 2 | { By FreddyV } 3 | 4 | UNIT BIOSDisk; 5 | {$A+,Q-,R-,S-} 6 | 7 | INTERFACE 8 | 9 | TYPE Byte9k=Array[1..9216] of Byte; 10 | 11 | TYPE TDOSBootSector=RECORD 12 | JMPCode : Array[1..3] of Byte; 13 | OSName : Array[1..8] of Char; 14 | BPS : Word; {Bytes per Sector} 15 | SPerCluster : Byte; 16 | ReservedSector : Word; 17 | FATNb : Byte; 18 | RootEntries : Word; 19 | TotalSectors : Word; 20 | MediaDescription : Byte; 21 | SPerFat :Word; 22 | SPerTrack :Word; 23 | Sides :Word; 24 | ZeroBytes : Array[1..10] of Byte; 25 | ExtBPB : Byte; 26 | END; 27 | 28 | VAR 29 | Floppy_error : Byte; 30 | 31 | Function BIOS_InitFloppy(FId:Byte) : Byte; 32 | Function BIOS_FloppyReadSector(FId:Byte;Head:Byte;Track:Byte;Sector:Byte;SectorNb:Byte;Buffer:Byte9k):Byte; 33 | 34 | IMPLEMENTATION 35 | 36 | {bit(s) Description 37 | 15-14 Number of parallel devices. 38 | 13 Reserved. 39 | 12 Game port installed. 40 | 11-9 Number of serial devices. 41 | 8 Reserved. 42 | 7-6 Number of floppy disk drives (minus 1): 43 | 00 single floppy disk; 44 | 01 two floppy disks; 45 | 10 three floppy disks; 46 | 11 four floppy disks. 47 | 5-4 Initial video mode: 48 | 00 EGA,VGA,PGA, or other with on-board video BIOS; 49 | 01 40x25 CGA color. 50 | 10 80x25 CGA color (emulator default). 51 | 11 80x25 mono text. 52 | 3 Reserved. 53 | 2 PS/2 mouse is installed. 54 | 1 Math coprocessor installed. 55 | 0 Set when booted from floppy. } 56 | 57 | Function BIOS_FloppyNb : Byte; Assembler; 58 | ASM 59 | INT 11h 60 | TEST AL,00000001b 61 | JZ @NoFloppy { Bit 0=0 } 62 | MOV CL,6 63 | SHR AL,CL 64 | AND AL,00000011b 65 | INC AL 66 | JMP @FNEnd 67 | @NoFloppy: 68 | XOR AX,AX 69 | @FNEnd: 70 | End; {BIOS_FloppyNb} 71 | 72 | Function BIOS_InitFloppy(FId:Byte) : Byte; Assembler; 73 | ASM 74 | XOR AH,AH 75 | MOV DL,FId 76 | INT 13h 77 | MOV AL,AH 78 | MOV Floppy_Error,AL 79 | End; {BIOS_InitFloppy} 80 | 81 | Function BIOS_FloppyReadSector(FId:Byte;Head:Byte;Track:Byte;Sector:Byte;SectorNb:Byte;Buffer:Byte9k):Byte; Assembler; 82 | ASM 83 | MOV AH,02h 84 | MOV AL,SectorNb 85 | MOV CH,Track 86 | MOV CL,Sector 87 | MOV DH,Head 88 | MOV DL,FId 89 | AND DL,1 { Be sure we send 0 or 1 Only as Floppy ID} 90 | LES BX,Buffer 91 | INT 13h 92 | MOV AL,AH 93 | MOV Floppy_Error,AL { Copy the Error code } 94 | End; {BIOS_FloppyNb} 95 | 96 | END. { Unit End } -------------------------------------------------------------------------------- /TPUNIT/PASMODM/DOSStruc.PAS: -------------------------------------------------------------------------------- 1 | UNIT DOSStruc; 2 | 3 | {(C) Copyright 1991, Earl F. Glynn, Overland Park, KS. Compuserve 4 | 73257,3527. 5 | 6 | All Rights Reserved. This Turbo Pascal UNIT may be freely distributed 7 | only for non-commercial use.} 8 | 9 | INTERFACE 10 | 11 | USES 12 | DOS; 13 | 14 | TYPE 15 | {DOS control blocks follow} 16 | DiskParameterBlockPointer = ^DiskParameterBlock; 17 | {See pp. 743-744, "Waite Group's MS-DOS Developer's Guide, Second 18 | Edition, and pp. 129-133, "PC Tech Journal", February 1989} 19 | DiskParameterBlock = 20 | RECORD { offset } 21 | Drive : BYTE; {0=A,1=B} { 0 $00 } 22 | UnitWithinDriver : BYTE; {0,1,2,...} { 1 $01 } 23 | BytesPerSector : WORD; { 2 $02 } 24 | SectorsPerCluster : BYTE; {SPC - 1} { 4 $04 } 25 | ClusterToSectorShift: BYTE; { 5 $05 } 26 | ReservedSectors : WORD; { 6 $06 } 27 | FATTables : BYTE; { 8 $08 } 28 | RootDirEntries : WORD; { 9 $09 } 29 | FirstDataSector : WORD; { 11 $0B } 30 | Clusters : WORD; {Clusters + 1} { 13 $0D } 31 | SectorsPerFAT : WORD; {BYTE in DOS 3.X} { 15 $0F } 32 | RootDirSector : WORD; { 17 $11 } 33 | DeviceHeader : pointer; { 19 $13 } 34 | MediaType : BYTE; { 23 $17 } 35 | Valid : BYTE; { 24 $18 } 36 | NextDPB : DiskParameterBlockPointer { 25 $19 } 37 | END; 38 | 39 | DOSListOfLists = {DOS 3.X. See Waite Group's Guide, p. 746} 40 | RECORD { offset } 41 | FirstMCBSegment : WORD; { -2 -$02 } 42 | misc1 : ARRAY[1..16] OF BYTE; { 0 $00 } 43 | MaxBytesPerBlock: WORD; { 16 $10 } 44 | misc2 : ARRAY[1..4] OF BYTE; { 18 $12 } 45 | BaseDA : Pointer; { 22 $16 } 46 | misc3 : ARRAY[1..6] OF BYTE; { 26 $1A } 47 | NumBlockDevices : BYTE; { 32 $20 } 48 | LastDrive : BYTE {from CONFIG.SYS} { 33 $21 } 49 | END; 50 | 51 | VAR 52 | ListOfLists: ^DOSListOfLists; 53 | MaxDrive : WORD; 54 | MinDrive : WORD; 55 | ValidDrive : ARRAY[1..26] OF BOOLEAN; 56 | 57 | FUNCTION NumberOfFloppyDrives: BYTE; 58 | FUNCTION FirstFloppyDrive: BYTE; {1=A, 2=B} 59 | PROCEDURE MakeFirstFloppy (drive: BYTE); {1=A, 2=B} 60 | 61 | PROCEDURE DetermineValidDrives; 62 | 63 | FUNCTION DiskLocation (Drive: BYTE): STRING; 64 | 65 | FUNCTION DefaultDrive: BYTE; {1=A, 2=B, ..., 26=Z} 66 | 67 | FUNCTION DriveLetter (Drive: BYTE): CHAR; 68 | 69 | FUNCTION GetCurrentDirectory (Drive: BYTE): STRING; 70 | 71 | PROCEDURE GetFreeDiskSpace 72 | (Drive: BYTE; {1=A, 2=B, ..., 26=Z} 73 | VAR Valid : BOOLEAN; 74 | VAR SectorSize,ClusterSize: WORD; 75 | VAR Capacity, Available : LongInt); 76 | 77 | PROCEDURE GetDPB (Drive: BYTE; VAR Valid: BOOLEAN; 78 | VAR DPB: DiskParameterBlock); 79 | 80 | {??????????????????????????????????????????????????????????????????????} 81 | 82 | IMPLEMENTATION 83 | 84 | CONST 85 | ByteArraySize = 50000; 86 | 87 | TYPE 88 | ByteArray = ARRAY[0..ByteArraySize] OF BYTE; 89 | ByteArrayPtr = ^ByteArray; 90 | 91 | VAR 92 | buffer : ARRAY[1..64] OF CHAR; 93 | DefaultFloppy : BYTE; 94 | ExitSave : Pointer; 95 | r : Registers; 96 | SingleDriveLogicalDrive: BYTE ABSOLUTE $0000:$0504; 97 | 98 | {????? Floppy Drives ????????????????????????????????????????????????} 99 | 100 | {The next two FUNCTIONs and PROCEDURE were derived from ONEDRIVE.PAS, 101 | PC Magazine, Sept. 26, 1989, pp. 380-381, and Appendix A, "Memory Map", 102 | "Compute!'s Mapping the IBM PC", pp. 234-235, 246, and Ray Duncan's 103 | "IBM ROM BIOS".} 104 | 105 | FUNCTION NumberOfFloppyDrives: BYTE; 106 | VAR r: Registers; 107 | BEGIN {BIOS interrupt is "safer" than absolute memory reference} 108 | Intr ($11,r); {r.AX contains equipment list code word} 109 | IF (r.AX AND $0001) = 1 110 | THEN NumberOfFloppyDrives := ((r.AX SHR 6) AND $0003)+1 111 | ELSE NumberOfFloppyDrives := 0 112 | END {NumberOfFloppyDrives}; 113 | 114 | FUNCTION FirstFloppyDrive: BYTE; {1=A, 2=B} 115 | BEGIN 116 | IF NumberOfFloppyDrives > 1 117 | THEN FirstFloppyDrive := 1 118 | ELSE FirstFloppyDrive := SingleDriveLogicalDrive + 1 119 | END {FirstFloppyDrive}; 120 | 121 | PROCEDURE MakeFirstFloppy (drive: BYTE); {1=A, 2=B} 122 | BEGIN 123 | IF NumberOfFloppyDrives = 1 124 | THEN SingleDriveLogicalDrive := drive-1 125 | END {MakeFirstFloppy}; 126 | 127 | {????? DetermineValidDrives ?????????????????????????????????????????} 128 | 129 | PROCEDURE DetermineValidDrives; 130 | VAR 131 | drive : BYTE; 132 | floppy: BYTE; 133 | r : Registers; 134 | BEGIN 135 | MinDrive := 0; 136 | floppy := FirstFloppyDrive; 137 | FOR drive := 1 TO 26 DO BEGIN 138 | IF (NumberOfFloppyDrives = 1) AND (drive IN [1..2]) 139 | THEN BEGIN 140 | ValidDrive[drive] := (drive = floppy); 141 | MakeFirstFloppy (drive) 142 | END 143 | ELSE ValidDrive[drive] := TRUE; 144 | 145 | IF ValidDrive[drive] 146 | THEN BEGIN 147 | r.AH := $36; {DOS 2,3: Get Free Disk Space} 148 | r.DL := drive; 149 | INTR ($21,r); 150 | ValidDrive[drive] := (r.AX <> $FFFF) 151 | END; 152 | 153 | IF ValidDrive[drive] 154 | THEN BEGIN 155 | IF MinDrive = 0 156 | THEN MinDrive := drive; 157 | MaxDrive := drive 158 | END 159 | 160 | END; 161 | MakeFirstFloppy (floppy) 162 | END {DetermineValidDrives}; 163 | 164 | {????? Determine if Drive is Local/LAN ???????????????????????????????} 165 | 166 | FUNCTION DiskLocation (Drive: BYTE): STRING; 167 | VAR r: Registers; 168 | BEGIN 169 | r.AH := $44; 170 | r.AL := $09; {DOS 3.1 and after} 171 | r.BL := drive; 172 | INTR ($21,r); 173 | IF (FCarry AND r.Flags) <> 0 174 | THEN DiskLocation := '??????' 175 | ELSE 176 | IF (r.DX AND $1000) = $1000 177 | THEN DiskLocation := 'LAN' 178 | ELSE DiskLocation := 'Local' 179 | END {DiskLocation}; -------------------------------------------------------------------------------- /TPUNIT/PASMODM/DOSStructures.PAS: -------------------------------------------------------------------------------- 1 | UNIT DOSStructures; 2 | 3 | {(C) Copyright 1991, Earl F. Glynn, Overland Park, KS. Compuserve 4 | 73257,3527. 5 | 6 | All Rights Reserved. This Turbo Pascal UNIT may be freely distributed 7 | only for non-commercial use.} 8 | 9 | INTERFACE 10 | 11 | USES 12 | DOS; 13 | 14 | TYPE 15 | {DOS control blocks follow} 16 | DiskParameterBlockPointer = ^DiskParameterBlock; 17 | {See pp. 743-744, "Waite Group's MS-DOS Developer's Guide, Second 18 | Edition, and pp. 129-133, "PC Tech Journal", February 1989} 19 | DiskParameterBlock = 20 | RECORD { offset } 21 | Drive : BYTE; {0=A,1=B} { 0 $00 } 22 | UnitWithinDriver : BYTE; {0,1,2,...} { 1 $01 } 23 | BytesPerSector : WORD; { 2 $02 } 24 | SectorsPerCluster : BYTE; {SPC - 1} { 4 $04 } 25 | ClusterToSectorShift: BYTE; { 5 $05 } 26 | ReservedSectors : WORD; { 6 $06 } 27 | FATTables : BYTE; { 8 $08 } 28 | RootDirEntries : WORD; { 9 $09 } 29 | FirstDataSector : WORD; { 11 $0B } 30 | Clusters : WORD; {Clusters + 1} { 13 $0D } 31 | SectorsPerFAT : WORD; {BYTE in DOS 3.X} { 15 $0F } 32 | RootDirSector : WORD; { 17 $11 } 33 | DeviceHeader : pointer; { 19 $13 } 34 | MediaType : BYTE; { 23 $17 } 35 | Valid : BYTE; { 24 $18 } 36 | NextDPB : DiskParameterBlockPointer { 25 $19 } 37 | END; 38 | 39 | DOSListOfLists = {DOS 3.X. See Waite Group's Guide, p. 746} 40 | RECORD { offset } 41 | FirstMCBSegment : WORD; { -2 -$02 } 42 | misc1 : ARRAY[1..16] OF BYTE; { 0 $00 } 43 | MaxBytesPerBlock: WORD; { 16 $10 } 44 | misc2 : ARRAY[1..4] OF BYTE; { 18 $12 } 45 | BaseDA : Pointer; { 22 $16 } 46 | misc3 : ARRAY[1..6] OF BYTE; { 26 $1A } 47 | NumBlockDevices : BYTE; { 32 $20 } 48 | LastDrive : BYTE {from CONFIG.SYS} { 33 $21 } 49 | END; 50 | 51 | VAR 52 | ListOfLists: ^DOSListOfLists; 53 | MaxDrive : WORD; 54 | MinDrive : WORD; 55 | ValidDrive : ARRAY[1..26] OF BOOLEAN; 56 | 57 | FUNCTION NumberOfFloppyDrives: BYTE; 58 | FUNCTION FirstFloppyDrive: BYTE; {1=A, 2=B} 59 | PROCEDURE MakeFirstFloppy (drive: BYTE); {1=A, 2=B} 60 | 61 | PROCEDURE DetermineValidDrives; 62 | 63 | FUNCTION DiskLocation (Drive: BYTE): STRING; 64 | 65 | FUNCTION DefaultDrive: BYTE; {1=A, 2=B, ..., 26=Z} 66 | 67 | FUNCTION DriveLetter (Drive: BYTE): CHAR; 68 | 69 | FUNCTION GetCurrentDirectory (Drive: BYTE): STRING; 70 | 71 | PROCEDURE GetFreeDiskSpace 72 | (Drive: BYTE; {1=A, 2=B, ..., 26=Z} 73 | VAR Valid : BOOLEAN; 74 | VAR SectorSize,ClusterSize: WORD; 75 | VAR Capacity, Available : LongInt); 76 | 77 | PROCEDURE GetDPB (Drive: BYTE; VAR Valid: BOOLEAN; 78 | VAR DPB: DiskParameterBlock); 79 | 80 | {??????????????????????????????????????????????????????????????????????} 81 | 82 | IMPLEMENTATION 83 | 84 | CONST 85 | ByteArraySize = 50000; 86 | 87 | TYPE 88 | ByteArray = ARRAY[0..ByteArraySize] OF BYTE; 89 | ByteArrayPtr = ^ByteArray; 90 | 91 | VAR 92 | buffer : ARRAY[1..64] OF CHAR; 93 | DefaultFloppy : BYTE; 94 | ExitSave : Pointer; 95 | r : Registers; 96 | SingleDriveLogicalDrive: BYTE ABSOLUTE $0000:$0504; 97 | 98 | {????? Floppy Drives ????????????????????????????????????????????????} 99 | 100 | {The next two FUNCTIONs and PROCEDURE were derived from ONEDRIVE.PAS, 101 | PC Magazine, Sept. 26, 1989, pp. 380-381, and Appendix A, "Memory Map", 102 | "Compute!'s Mapping the IBM PC", pp. 234-235, 246, and Ray Duncan's 103 | "IBM ROM BIOS".} 104 | 105 | FUNCTION NumberOfFloppyDrives: BYTE; 106 | VAR r: Registers; 107 | BEGIN {BIOS interrupt is "safer" than absolute memory reference} 108 | Intr ($11,r); {r.AX contains equipment list code word} 109 | IF (r.AX AND $0001) = 1 110 | THEN NumberOfFloppyDrives := ((r.AX SHR 6) AND $0003)+1 111 | ELSE NumberOfFloppyDrives := 0 112 | END {NumberOfFloppyDrives}; 113 | 114 | FUNCTION FirstFloppyDrive: BYTE; {1=A, 2=B} 115 | BEGIN 116 | IF NumberOfFloppyDrives > 1 117 | THEN FirstFloppyDrive := 1 118 | ELSE FirstFloppyDrive := SingleDriveLogicalDrive + 1 119 | END {FirstFloppyDrive}; 120 | 121 | PROCEDURE MakeFirstFloppy (drive: BYTE); {1=A, 2=B} 122 | BEGIN 123 | IF NumberOfFloppyDrives = 1 124 | THEN SingleDriveLogicalDrive := drive-1 125 | END {MakeFirstFloppy}; 126 | 127 | {????? DetermineValidDrives ?????????????????????????????????????????} 128 | 129 | PROCEDURE DetermineValidDrives; 130 | VAR 131 | drive : BYTE; 132 | floppy: BYTE; 133 | r : Registers; 134 | BEGIN 135 | MinDrive := 0; 136 | floppy := FirstFloppyDrive; 137 | FOR drive := 1 TO 26 DO BEGIN 138 | IF (NumberOfFloppyDrives = 1) AND (drive IN [1..2]) 139 | THEN BEGIN 140 | ValidDrive[drive] := (drive = floppy); 141 | MakeFirstFloppy (drive) 142 | END 143 | ELSE ValidDrive[drive] := TRUE; 144 | 145 | IF ValidDrive[drive] 146 | THEN BEGIN 147 | r.AH := $36; {DOS 2,3: Get Free Disk Space} 148 | r.DL := drive; 149 | INTR ($21,r); 150 | ValidDrive[drive] := (r.AX <> $FFFF) 151 | END; 152 | 153 | IF ValidDrive[drive] 154 | THEN BEGIN 155 | IF MinDrive = 0 156 | THEN MinDrive := drive; 157 | MaxDrive := drive 158 | END 159 | 160 | END; 161 | MakeFirstFloppy (floppy) 162 | END {DetermineValidDrives}; 163 | 164 | {????? Determine if Drive is Local/LAN ???????????????????????????????} 165 | 166 | FUNCTION DiskLocation (Drive: BYTE): STRING; 167 | VAR r: Registers; 168 | BEGIN 169 | r.AH := $44; 170 | r.AL := $09; {DOS 3.1 and after} 171 | r.BL := drive; 172 | INTR ($21,r); 173 | IF (FCarry AND r.Flags) <> 0 174 | THEN DiskLocation := '??????' 175 | ELSE 176 | IF (r.DX AND $1000) = $1000 177 | THEN DiskLocation := 'LAN' 178 | ELSE DiskLocation := 'Local' 179 | END {DiskLocation}; -------------------------------------------------------------------------------- /TPUNIT/PASMODM/FFT_U.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/PASMODM/FFT_U.PAS -------------------------------------------------------------------------------- /TPUNIT/PASMODM/GMUNIT.PAS: -------------------------------------------------------------------------------- 1 | UNIT GMUnit; 2 | 3 | { 4 | Public domain. Do whatever you want with it. 5 | Colin Buckley. 6 | } 7 | 8 | INTERFACE 9 | {$F+} 10 | 11 | Const 12 | GMPort = $331; 13 | Send = $80; 14 | Receive = $40; 15 | 16 | FUNCTION GMDetecte:Boolean; 17 | PROCEDURE GMActive; 18 | 19 | IMPLEMENTATION 20 | USES VarMidi; 21 | 22 | 23 | 24 | { AL:=Command; } 25 | PROCEDURE WriteGMCommand; Assembler; 26 | ASM 27 | MOV DX,GMPort {;DX:=GMStatusPort; } 28 | PUSH AX {;Save AX } 29 | XOR AX,AX {;AH:=TimeOutValue; } 30 | @@WaitLoop: 31 | { ;Prevent Infinite Loop with Timeout } 32 | DEC AH {; |If TimeOutCount=0 then } 33 | JZ @@TimeOut {;/ TimeOut; } 34 | {; Wait until GM is ready } 35 | IN AL,DX {; |If Not Ready then } 36 | AND AL,Receive {; | WaitLoop; } 37 | JNZ @@WaitLoop {;/ } 38 | @@TimeOut: 39 | POP AX {;Restore AX } 40 | 41 | OUT DX,AL {;Send Data } 42 | End; 43 | 44 | { ; AL:=Data } 45 | PROCEDURE WriteGM; Assembler; 46 | ASM 47 | MOV DX,GMPort {;DX:=GMStatusPort; } 48 | PUSH AX {;Save AX } 49 | XOR AX,AX {;AH:=TimeOutValue; } 50 | @@WaitLoop: 51 | { ; Prevent Infinite Loop with Timeout } 52 | DEC AH {; |If TimeOutCount=0 then } 53 | JZ @@TimeOut {;/ TimeOut; } 54 | { ; Wait until GM is ready } 55 | IN AL,DX {; |If Not Ready then } 56 | AND AL,Receive {; | WaitLoop; } 57 | JNZ @@WaitLoop {;/ } 58 | @@TimeOut: 59 | POP AX {;Restore AX } 60 | 61 | DEC DX {;DX:=DataPort } 62 | OUT DX,AL {;Send Data } 63 | End; 64 | 65 | { ;Returns Data } 66 | FUNCTION ReadGM:Byte; Assembler; 67 | ASM 68 | MOV DX,GMPort {;DX:=GMStatusPort; } 69 | PUSH AX {;Save AX } 70 | XOR AX,AX {;AH:=TimeOutValue; } 71 | @@WaitLoop: 72 | { ; Prevent Infinite Loop with Timeout } 73 | DEC AH {; |If TimeOutCount=0 then } 74 | JZ @@TimeOut {;/ TimeOut; } 75 | { ; Wait until GM is ready } 76 | IN AL,DX {; |If Not Ready then } 77 | AND AL,Send {; | WaitLoop; } 78 | JNZ @@WaitLoop {;/ } 79 | @@TimeOut: 80 | POP AX {;Restore AX } 81 | 82 | DEC DX {;DX:=DataPort } 83 | IN AL,DX {;Receive Data } 84 | End; 85 | 86 | PROCEDURE ResetGM; Assembler; 87 | ASM 88 | { ;Reset GM } 89 | MOV DX,GMPort 90 | MOV AL,0FFh 91 | OUT DX,AL 92 | {; Get ACK } 93 | CALL ReadGM 94 | {; UART Mode } 95 | MOV AL,03Fh 96 | CALL WriteGMCommand 97 | End; 98 | 99 | PROCEDURE GMSendMidi2(V1,V2:Byte); Assembler; 100 | ASM 101 | MOV AL,V1 102 | Call WriteGM 103 | MOV AL,V2 104 | Call WriteGM 105 | END; 106 | 107 | PROCEDURE GMSendMidi3(V1,V2,V3:Byte); Assembler; 108 | ASM 109 | MOV AL,V1 110 | Call WriteGM 111 | MOV AL,V2 112 | Call WriteGM 113 | MOV AL,V3 114 | Call WriteGM 115 | END; 116 | 117 | {----------------------------------------------------------} 118 | 119 | 120 | {==========================================================} 121 | 122 | PROCEDURE GMNoteOff(Channel,Note,Velocity:Byte); 123 | Begin 124 | GMSendMidi3(Channel+CNoteOff,Note,Velocity); 125 | End; {NoteOff} 126 | 127 | {----------------------------------------------------------} 128 | 129 | PROCEDURE GMNoteOn(Channel,Note,Volume:Byte); 130 | Begin 131 | GMSendMidi3(Channel+CNoteOn,Note,Volume); 132 | End; 133 | 134 | {----------------------------------------------------------} 135 | 136 | PROCEDURE GMKeyPressure(Channel,Note,Pressure:Byte); 137 | Begin 138 | GMSendMidi3(Channel+CKeyPressure,Note,Pressure); 139 | End; 140 | 141 | {----------------------------------------------------------} 142 | 143 | PROCEDURE GMControl(Channel,Control,Value:Byte); 144 | Begin 145 | GMSendMidi3(Channel+CControl,Control,Value); 146 | End; 147 | 148 | {----------------------------------------------------------} 149 | 150 | PROCEDURE GMPGMChange(Channel,Prog:Byte); 151 | Begin 152 | GMSendMidi2(Channel+CPGMChange,Prog); 153 | End; 154 | 155 | {----------------------------------------------------------} 156 | 157 | PROCEDURE GMAfterTouch(Channel,pressure:Byte); 158 | Begin 159 | GMSendMidi2(Channel+CAfterTouch,pressure); 160 | End; 161 | 162 | {----------------------------------------------------------} 163 | 164 | PROCEDURE GMPitchBend(Channel,MSB,LSB:Byte); 165 | Begin 166 | GMSendMidi3(Channel+CPitchBend,MSB,LSB); 167 | End; {PitchBend} 168 | 169 | {----------------------------------------------------------} 170 | 171 | FUNCTION GMLoadPatch(Instrument:Byte):Boolean; 172 | Begin 173 | GMLoadPatch:=True; 174 | End; {LoadPatch} 175 | 176 | {----------------------------------------------------------} 177 | 178 | PROCEDURE GMSendMidi(Valeur:Byte); Assembler; 179 | ASM 180 | MOV AL,Valeur 181 | Call WriteGM 182 | END; 183 | 184 | PROCEDURE GMStartMidi; 185 | Begin 186 | ResetGM; 187 | End; {StartMidi} 188 | 189 | {----------------------------------------------------------} 190 | 191 | PROCEDURE GMStopMidi; 192 | Begin 193 | ResetGM; 194 | End; {StopMidi} 195 | 196 | {----------------------------------------------------------} 197 | 198 | FUNCTION GMDetecte:Boolean; 199 | Begin 200 | GMDetecte:=True; 201 | End; {GMDetecte} 202 | 203 | {----------------------------------------------------------} 204 | 205 | PROCEDURE GMActive; 206 | Begin 207 | MNoteOff := GMNoteOff; 208 | MNoteOn := GMNoteOn; 209 | MKeyPressure := GMKeyPressure; 210 | MControl := GMControl; 211 | MPGMChange := GMPGMChange; 212 | MAfterTouch := GMAfterTouch; 213 | MPitchBend := GMPitchbend; 214 | MLoadPatch := GMLoadPatch; 215 | MSend := GMSendMidi; 216 | MStart := GMStartMidi; 217 | MStop := GMStopMidi; 218 | End; 219 | 220 | End. -------------------------------------------------------------------------------- /TPUNIT/PASMODM/HARDWARE.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/PASMODM/HARDWARE.PAS -------------------------------------------------------------------------------- /TPUNIT/PASMODM/PLMIDI.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/PASMODM/PLMIDI.PAS -------------------------------------------------------------------------------- /TPUNIT/PASMODM/PMUNIT.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/PASMODM/PMUNIT.PAS -------------------------------------------------------------------------------- /TPUNIT/PASMODM/SOURIST.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/PASMODM/SOURIST.PAS -------------------------------------------------------------------------------- /TPUNIT/PASMODM/TEXTE_V.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/PASMODM/TEXTE_V.PAS -------------------------------------------------------------------------------- /TPUNIT/PASMODM/TINTERRU.PAS: -------------------------------------------------------------------------------- 1 | {$F+,O-} 2 | {$R-,S-} {must NOT have stack checking!} 3 | { 4 | Trixter's interrupt and timer unit. Version 0.4 20160424 5 | This unit wouldn't be possible without the hard work and writing of: 6 | Mark Feldman 7 | Kris Heidenstrom (RIP) 8 | Klaus Hartnegg 9 | Thank you gentlemen! 10 | 11 | See tinttest.pas for example usage. 12 | 13 | Version 0.3 20130503 added PCjr vint stuff 14 | } 15 | 16 | {$DEFINE HIDDEN} {define if CGAVINT needs to start in vertical retrace only} 17 | 18 | {$DEFINE NOTRACKER} 19 | 20 | unit TInterrupts; 21 | 22 | interface 23 | 24 | const 25 | sysclockfreq=(315/22) * 1000000; {system clock derived from NTSC 14.318182 MHz } 26 | PITFreq=round(sysclockfreq / 12); {Programmable Interrupt Timer frequency, should be $1234de} 27 | usecPerTick=1000000 / PITFreq; {# of microseconds per system tick} 28 | CGAFrameCycles=(912*262) div 12; {# of PIT cycles per CGA display frame} 29 | SystemTimerInt=8; 30 | CTCModeCommandReg=$43; {write only; reads are ignored} 31 | 32 | {Some constants to help make sense of the 8253. Values are listed for 33 | BCD/Binary mode, operating mode, command/access mode, and channel select. 34 | Implied "zero" values are also listed for completeness.} 35 | 36 | {BCD or Binary mode:} 37 | iMC_BinaryMode=0; 38 | iMC_BCDMode=1; 39 | 40 | {Operating modes 0 through 5 (extended duplicates for 2 and 3 not listed)} 41 | iMC_OpMode0=0; {Interrupt on terminal count} 42 | iMC_OpMode1=2; {Hardware-retriggerable one-shot} 43 | iMC_OpMode2=4; {Rate generator} 44 | iMC_OpMode3=iMC_OpMode1+iMC_OpMode2; {Square wave generator} 45 | iMC_OpMode4=8; {Software-triggered strobe} 46 | iMC_OpMode5=iMC_OpMode4+iMC_OpMode1; {Hardware-triggered strobe} 47 | 48 | {Command/Access mode: value, lobyte only, hibyte only, lowbyte/hibyte} 49 | iMC_LatchCounter=0; 50 | iMC_AMLB=16; 51 | iMC_AMHB=32; 52 | iMC_AMLH=iMC_AMLB+iMC_AMHB; 53 | 54 | {Channel select:} 55 | iMC_Chan0=0; 56 | iMC_Chan1=64; 57 | iMC_Chan2=128; 58 | iMC_ReadBack=iMC_Chan1+iMC_Chan2; {8254 only!} 59 | 60 | {The PITcycles variable will keep track of how many cycles the PIT has 61 | had, it'll be intialised to 0. The Chan0Counter variable will hold the new 62 | channel 0 counter value. We'll also be adding this number to PITcycles 63 | every time our handler is called.} 64 | 65 | 66 | type 67 | {Thanks to Jason Burgon for the idea: this record allows us to get away 68 | with 16-bit math when dealing with longint counters in handlers. See the 69 | example handler code in TINTTEST.PAS for example usage.} 70 | LongRec=packed record 71 | lo:word; 72 | hi:integer; 73 | end; 74 | 75 | var 76 | BIOSTimerHandler:procedure; 77 | VINTsave:pointer; 78 | PITcycles, 79 | Chan0Counter:longint; 80 | 81 | procedure InitChannel(channel,accessMode,mode:byte;divisor:word); 82 | {Inits a channel -- mostly used internally but public interface 83 | provided in case you want to do something custom} 84 | 85 | procedure SetTimerHz(TimerHandler:pointer;frequency:word); 86 | procedure SetTimerExact(TimerHandler:pointer;cycles:word); 87 | {$IFNDEF NOTRACKER} 88 | procedure SetTimerCGAVINT(TimerHandler:pointer); 89 | {$ENDIF} 90 | { 91 | Save the address of the BIOS handler, install our own, set up the 92 | variables we'll use and program PIT channel 0 for the divide-by-N mode 93 | at the frequency we need. 94 | 95 | In the case of CGAVINT, we simulate a vertical retrace interrupt that 96 | fires "early", directly after the last drawn scanline. This gives us 97 | some extra time to do things before we start retracing back up the screen. 98 | } 99 | 100 | procedure HookPCjrVINT(newVINTHandler:pointer); 101 | procedure unHookPCjrVINT; 102 | {Hooks an interrupt handler to the PCjr hardware vertical retrace interrupt} 103 | 104 | procedure CleanUpTimer; 105 | {Reset everything back to the way we left it} 106 | 107 | Procedure Chan2SquarewaveOn(newfreq:word); 108 | {ties the speaker input to CTC channel 2 and programs it for square wave output} 109 | 110 | Procedure Chan2SquarewaveChange(newfreq:word); 111 | {Reprograms CTC channel 2 only} 112 | 113 | Procedure Chan2SquarewaveOff; 114 | {unhooks the speaker from CTC channel 2} 115 | 116 | Function ticks2usec(l:longint):longint; 117 | {Converts tick counts from the 8253 into microseconds} 118 | 119 | implementation 120 | 121 | (* 122 | 123 | The Mode/Command register at I/O address 43h is defined as follows: 124 | 125 | 7 6 5 4 3 2 1 0 126 | * * . . . . . . Select channel: 0 0 = Channel 0 127 | 0 1 = Channel 1 128 | 1 0 = Channel 2 129 | 1 1 = Read-back command (8254 only) (Illegal on 8253) (Illegal on PS/2) 130 | . . * * . . . . Cmd./Access mode: 0 0 = Latch count value command 131 | 0 1 = Access mode: lobyte only 132 | 1 0 = Access mode: hibyte only 133 | 1 1 = Access mode: lobyte/hibyte 134 | . . . . * * * . Operating mode: 0 0 0 = Mode 0 135 | 0 0 1 = Mode 1 136 | 0 1 0 = Mode 2 137 | 0 1 1 = Mode 3 138 | 1 0 0 = Mode 4 139 | 1 0 1 = Mode 5 140 | 1 1 0 = Mode 2 141 | 1 1 1 = Mode 3 142 | . . . . . . . * BCD/Binary mode: 0 = 16-bit binary 143 | 1 = four-digit BCD 144 | 145 | The SC1 and SC0 (Select Channel) bits form a two-bit binary code which tells 146 | the CTC which of the three channels (channels 0, 1, and 2) you are talking to, 147 | or specifies the read-back command. As there are no 'overall' or 'master' 148 | operations or configurations, every write access to the mode/command register, 149 | except for the read-back command, applies to one of the channels. These 150 | bits must always be valid on every write of the mode/command register, 151 | regardless of the other bits or the type of operation being performed. 152 | 153 | The RL1 and RL0 bits (Read/write/Latch) form a two-bit code which tells the CTC 154 | what access mode you wish to use for the selected channel, and also specify the 155 | Counter Latch command to the CTC. For the Read-back command, these bits have a 156 | special meaning. These bits also must be valid on every write access to 157 | the mode/command register. 158 | 159 | The M2, M1, and M0 (Mode) bits are a three-bit code which tells the selected 160 | channel what mode to operate in (except when the command is a Counter Latch 161 | command, i.e. RL1,0 = 0,0, where they are ignored, or when the command is a 162 | Read-back command, where they have special meanings). 163 | These bits must be valid on all mode selection commands (all writes to the 164 | mode/command register except when RL1,RL0 = 0,0 or when SC1,0 = 1,1). 165 | 166 | *) 167 | 168 | uses 169 | { m6845ctl,} 170 | dos; 171 | 172 | const 173 | lastSpeakerFreq:word=$ffff; 174 | 175 | function ticks2usec(l:longint):longint; 176 | {converts number of 8253 ticks to microseconds} 177 | begin 178 | ticks2usec:=trunc(l / usecPerTick); 179 | end; 180 | 181 | Procedure InitChannel(channel,accessMode,mode:byte;divisor:word); 182 | const 183 | chan0base=$40; 184 | var 185 | modecmd,lobyte,hibyte,chanport:byte; 186 | begin 187 | {check for valid input allowed: 188 | only channels 0 and 2 (1 is for DRAM REFRESH, do NOT touch!) 189 | only accessmodes 1 through 3 (0 is not an access mode)} 190 | if not (channel in [0,2]) or not (accessMode in [1..3]) then exit; 191 | {precalc how we're going to set the channel, so we don't tie up too much 192 | time with interrupts turned off} 193 | modecmd:=(channel shl 6) + (accessMode shl 4) + ((mode AND $7) shl 1); {bit 0 always 0 for 16-bit mode} 194 | lobyte:=lo(divisor); 195 | hibyte:=hi(divisor); 196 | chanport:=chan0base+channel; 197 | {must make these changes atomic, so disable interrupts before starting} 198 | asm pushf; cli end; 199 | port[CTCModeCommandReg]:=modecmd; 200 | port[chanport]:=lobyte; (* Reload reg lobyte *) 201 | port[chanport]:=hibyte; (* Reload reg hibyte *) 202 | asm popf end; 203 | end; 204 | 205 | {$IFNDEF NOTRACKER} 206 | Procedure InitChannelCGAVINT(channel,accessMode,mode:byte;divisor:word); 207 | const 208 | chan0base=$40; 209 | var 210 | modecmd,lobyte,hibyte,chanport:byte; 211 | begin 212 | {check for valid input allowed: 213 | only channels 0 and 2 (1 is for DRAM REFRESH, do NOT touch!) 214 | only accessmodes 1 through 3 (0 is not an access mode)} 215 | if not (channel in [0,2]) or not (accessMode in [1..3]) then exit; 216 | {precalc how we're going to set the channel, so we don't tie up too much 217 | time with interrupts turned off} 218 | modecmd:=(channel shl 6) + (accessMode shl 4) + ((mode AND $7) shl 1); {bit 0 always 0 for 16-bit mode} 219 | lobyte:=lo(divisor); 220 | hibyte:=hi(divisor); 221 | chanport:=chan0base+channel; 222 | {must make these changes atomic, so disable interrupts before starting} 223 | asm 224 | {get to end of display cycle} 225 | mov dx,m6845_status 226 | mov bl,c_vertical_sync 227 | mov bh,c_display_enable or c_vertical_sync 228 | mov ah,c_display_enable 229 | mov cx,199 230 | pushf 231 | cli 232 | {$IFNDEF HIDDEN} 233 | @WDR: 234 | in al,dx 235 | test al,bl 236 | jz @WDR {wait if not vertically retracing} 237 | {Now we are tracing back up the screen. Wait until first scanline.} 238 | @hor1: 239 | in al,dx 240 | test al,bh 241 | jnz @hor1 {wait until not horizontally or vertically retracing} 242 | {Now we are drawing our first scanline.} 243 | @hor2: 244 | in al,dx 245 | test al,ah 246 | jz @hor2 {wait until horizontally retracing} 247 | loop @hor1 {loop 199 more times} 248 | {$ELSE} 249 | @WDR: {wait during retrace, because we don't know where we are in the cycle} 250 | in al,dx 251 | test al,bl {if our bit is 1, then we're already in retrace; we missed it} 252 | jnz @WDR {jump if 1 (not 0) = keep looping as long as we're retracing} 253 | @WDD: {wait for display to be over} 254 | in al,dx 255 | test al,bl 256 | jz @WDD {loop until we aren't drawing any more (ie. retracing)} 257 | {$ENDIF} 258 | 259 | {set new rate} 260 | mov al,modecmd 261 | out CTCModeCommandReg,al 262 | xor dx,dx 263 | mov dl,chanport 264 | mov al,lobyte 265 | out dx,al 266 | mov al,hibyte 267 | out dx,al 268 | popf 269 | end; 270 | end; 271 | {$ENDIF} 272 | 273 | procedure SetTimerHz(TimerHandler : pointer; frequency : word); 274 | begin 275 | { Do some initialization } 276 | PITcycles := 0; 277 | Chan0Counter := PITFreq div frequency; 278 | 279 | { Store the current BIOS handler and set up our own } 280 | GetIntVec(SystemTimerInt, @BIOSTimerHandler); 281 | SetIntVec(SystemTimerInt, TimerHandler); 282 | 283 | {init channel 0, 3=access mode lobyte/hibyte, mode 2, 16-bit binary} 284 | InitChannel(0,3,2,Chan0Counter); 285 | end; 286 | 287 | procedure SetTimerExact(TimerHandler : pointer; cycles : word); 288 | begin 289 | { Do some initialization } 290 | PITcycles := 0; 291 | Chan0Counter := cycles; 292 | 293 | { Store the current BIOS handler and set up our own } 294 | GetIntVec(SystemTimerInt, @BIOSTimerHandler); 295 | SetIntVec(SystemTimerInt, TimerHandler); 296 | 297 | {init channel 0, 3=access mode lobyte/hibyte, mode 2, 16-bit binary} 298 | InitChannel(0,3,2,Chan0Counter); 299 | end; 300 | 301 | 302 | {$IFNDEF NOTRACKER} 303 | procedure SetTimerCGAVINT(TimerHandler : pointer); 304 | begin 305 | { Do some initialization } 306 | PITcycles := 0; 307 | Chan0Counter := CGAFrameCycles; 308 | 309 | { Store the current BIOS handler and set up our own } 310 | GetIntVec(SystemTimerInt, @BIOSTimerHandler); 311 | SetIntVec(SystemTimerInt, TimerHandler); 312 | 313 | {init channel 0, 3=access mode lobyte/hibyte, mode 2, 16-bit binary} 314 | InitChannelCGAVINT(0,3,2,Chan0Counter); 315 | end; 316 | {$ENDIF} 317 | 318 | procedure CleanUpTimer; 319 | begin 320 | { Restore the normal clock frequency to original BIOS tick rate } 321 | {init channel 0, 3=access mode lobyte/hibyte, mode 2, 16-bit binary} 322 | InitChannel(0,3,2,$0000); 323 | 324 | { Restore the normal tick handler } 325 | SetIntVec(SystemTimerInt, @BIOSTimerHandler); 326 | end; 327 | 328 | Procedure Chan2SquarewaveOn; 329 | begin 330 | {if we're not already sounding the new requested frequency, and the new 331 | frequency is large enough that it won't result in a divisor of 1, proceed:} 332 | if (lastSpeakerFreq<>newFreq) and (newfreq>18) then begin 333 | lastSpeakerFreq:=newFreq; 334 | {Set CTC Channel 2, 16-bit, mode 3, squarewave frequency} 335 | InitChannel(2, 3, 3, PITFreq div newfreq); 336 | asm pushf; cli end; 337 | {Enable speaker and tie input pin to CTC Chan 2 by setting bits 1 and 0} 338 | port[$61]:=(port[$61] OR $3); 339 | asm popf end; 340 | end; 341 | end; 342 | 343 | Procedure Chan2SquarewaveChange; 344 | {A bit of assembler and specialization here because 1. we know exactly what 345 | channel we're changing, and 2. we need speed here since changing the speaker's 346 | frequency is something that happens a lot if playing music or sound effects} 347 | var 348 | divisor:word; 349 | begin 350 | {if we're not already sounding the new requested frequency, and the new 351 | frequency is large enough that it won't result in a divisor of 1, proceed:} 352 | if (lastSpeakerFreq<>newFreq) and (newfreq>18) then begin 353 | lastSpeakerFreq:=newFreq; 354 | divisor:=PITFreq div newfreq; 355 | asm 356 | mov dx,$42 {channel 2} 357 | mov ax,divisor 358 | pushf {save flags because we don't know who/what is calling us} 359 | cli {must be atomic, so disable interrupts before starting} 360 | out dx,al {output lowbyte} 361 | mov al,ah {copy highbyte to AL} 362 | out dx,al {output highbyte} 363 | popf 364 | end; 365 | end; 366 | end; 367 | 368 | Procedure Chan2SquarewaveOff; 369 | begin 370 | asm pushf; cli end; 371 | {Disable speaker and CTC Chan 2 tie by clearing bits 1 and 0} 372 | port[$61]:=(port[$61] AND (NOT $3)); 373 | asm popf end; 374 | lastSpeakerFreq:=$ffff; {set to some value the user will never enter} 375 | end; 376 | 377 | procedure HookPCjrVINT(newVINTHandler:pointer); 378 | begin 379 | { Store the current BIOS handler and set up our own } 380 | GetIntVec(5+8, VINTsave); 381 | SetIntVec(5+8, newVINTHandler); 382 | 383 | {Enable hardware interrupt 5 in PIC} 384 | asm 385 | mov dx,$21 386 | in al,dx {bring in current PIC mask} 387 | and al,not (1 SHL 5){AND to enable, OR to disable} 388 | out dx,al {update PIC mask} 389 | end; 390 | end; 391 | 392 | procedure unHookPCjrVINT; 393 | begin 394 | {Disable hardware interrupt 5 in PIC} 395 | asm 396 | mov dx,$21 397 | in al,dx {bring in current PIC mask} 398 | or al,1 SHL 5 {AND to enable, OR to disable} 399 | out dx,al {update PIC mask} 400 | end; 401 | 402 | {Restore old handler} 403 | SetIntVec(5+8, VINTsave); 404 | 405 | {Enable hardware interrupt 5 in PIC} 406 | asm 407 | mov dx,$21 408 | in al,dx {bring in current PIC mask} 409 | and al,not (1 SHL 5){AND to enable, OR to disable} 410 | out dx,al {update PIC mask} 411 | end; 412 | 413 | {There's actually no point in turning the PCjr VINT IRQ5 back on because 414 | the default handler at f000:f815 in a real PCjr disables it on first call, 415 | implying that the vint is for user programs only. But we do it here to 416 | be an example of best practices.} 417 | end; 418 | 419 | end. 420 | 421 | (* 422 | While you could write a small procedure that is called by the interrupt 423 | handler, that would just kill the purpose of the handler because you'd 424 | be doing two CALLs instead of one. You'll just have to write the handler 425 | yourself, but since that sucks, there is an example you can steal in 426 | the program TINTTEST.PAS which should be in the same location as this code. 427 | *) 428 | -------------------------------------------------------------------------------- /TPUNIT/PASMODM/VARMIDI.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/PASMODM/VARMIDI.PAS -------------------------------------------------------------------------------- /TPUNIT/PASMODM/VGA.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/PASMODM/VGA.PAS -------------------------------------------------------------------------------- /TPUNIT/PSGUNIT.PAS: -------------------------------------------------------------------------------- 1 | {************************************************************************} 2 | { TDYUNIT.PAS } 3 | { } 4 | { Tandy SN76496 and DAC Code, Detection and Init } 5 | { } 6 | { AUTEURS: Freddy V�tel� } 7 | { } 8 | { Code Start 6/06/20 } 9 | {************************************************************************} 10 | UNIT PSGUNIT; 11 | {$A+,Q-,G-,R-,S-} 12 | 13 | INTERFACE 14 | 15 | CONST 16 | 17 | PSG_PortTotal = ; 18 | PSG_PortList : Array[0..5] of Word = (0,$220,$300); { covox, mindscape} 19 | 20 | VAR 21 | 22 | PSG_Type : Byte; { 0 : Nothing 1 : Internal} 23 | PSG_Port : WORD; { 0 Not present otherwise, Port } 24 | 25 | IMPLEMENTATION 26 | 27 | END. 28 | -------------------------------------------------------------------------------- /TPUNIT/SBUNIT.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/SBUNIT.PAS -------------------------------------------------------------------------------- /TPUNIT/SOURIS.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/SOURIS.PAS -------------------------------------------------------------------------------- /TPUNIT/SOURISC.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/SOURISC.PAS -------------------------------------------------------------------------------- /TPUNIT/SS.BAT: -------------------------------------------------------------------------------- 1 | COPY BIOSEQU.PAS SS\ 2 | COPY CH669.PAS SS\ 3 | COPY CHDTM.PAS SS\ 4 | COPY CHFAR.PAS SS\ 5 | COPY CHMMM.PAS SS\ 6 | COPY CHMOD.PAS SS\ 7 | COPY CHMTM.PAS SS\ 8 | COPY CHPTM.PAS SS\ 9 | COPY CHS3M.PAS SS\ 10 | COPY CHSAT.PAS SS\ 11 | COPY CHSTM.PAS SS\ 12 | COPY CHULT.PAS SS\ 13 | COPY CHRAD.PAS SS\ 14 | COPY CHADL.PAS SS\ 15 | COPY CHUTIL.PAS SS\ 16 | COPY CHXM.PAS SS\ 17 | COPY CLAVIER.PAS SS\ 18 | COPY DSSUNIT.PAS SS\ 19 | COPY EMSUNIT.PAS SS\ 20 | COPY ESSUNIT.PAS SS\ 21 | COPY FFT_U.PAS SS\ 22 | COPY FICHIERS.PAS SS\ 23 | COPY FICH_GRP.PAS SS\ 24 | COPY GUSUNIT.PAS SS\ 25 | COPY MEMOIRE.PAS SS\ 26 | COPY MMSS_CMD.PAS SS\ 27 | COPY MMSS_MEM.PAS SS\ 28 | COPY MMSS_VAR.PAS SS\ 29 | COPY MM_DIV.PAS SS\ 30 | COPY MM_VAR.PAS SS\ 31 | COPY MODMCFG.INI SS\ 32 | COPY MODM_SS.PAS SS\ 33 | COPY QUARTSIN.INC SS\ 34 | COPY SAV_MMM.PAS SS\ 35 | COPY SBUNIT.PAS SS\ 36 | COPY TDYUNIT.PAS SS\ 37 | COPY TEXTE_V.PAS SS\ 38 | COPY TYPES.PAS SS\ 39 | COPY UTIL.PAS SS\ 40 | COPY VARUNIT.PAS SS\ 41 | COPY VGA.PAS SS\ -------------------------------------------------------------------------------- /TPUNIT/TDYUNIT.PAS: -------------------------------------------------------------------------------- 1 | {************************************************************************} 2 | { TDYUNIT.PAS } 3 | { } 4 | { Tandy SN76496 and DAC Code, Detection and Init } 5 | { } 6 | { AUTEURS: Freddy V�tel� } 7 | { } 8 | { Code Start 6/06/20 } 9 | {************************************************************************} 10 | UNIT TDYUNIT; 11 | {$A+,Q-,G-,R-,S-} 12 | 13 | INTERFACE 14 | 15 | CONST 16 | 17 | { Offset des Ports I/O} 18 | TDY_Port_Mode1 = 0; { Tandy DAC Mode 1 Write Only } 19 | TDY_Port_Mode2 = 1; { Tandy DAC Mode 1 Write Only } 20 | TDY_Port_FreqL = 2; { Frequency Low Read/Write } 21 | TDY_Port_FreqV = 3; { Frequency High + Volume Read/Write } 22 | 23 | { 24 | 25 | Port 0C0h (1E0h, 300h) SN76496 3-voice tone and noise generator 26 | Write only 27 | 28 | Bits 29 | 7 6 5 4 3 2 1 0 Function 30 | --------------- -------- 31 | 1 x x 0 y y y y Set tone frequency, channel xx (0-2). yyyy = low 4 32 | bits of divider. 33 | 0 w z z z z z z (following the above) zzzzzz = high 6 bits of divider. 34 | If extra divide enabled (port 0C4h bit 6), w = high 35 | (11th) bit of divider (otherwise, w is a "don't 36 | care" bit). 37 | 1 x x 1 y y y y Set tone attenuation, channel xx (0-2). yyyy = 38 | attenuation (1's complement of volume). Attenuation 39 | 1111b = no sound. Approximately 2 dB per level. 40 | 10^0.2=1.58489319... (16 Levels) 41 | 1 1 1 0 x y z z Set noise type/frequency. x is a "don't care" bit. 42 | y = periodic/white noise code: 0 = periodic noise, 43 | 1 = white noise. zz = frequency: 0 = N/512, 1 = 44 | N/1024, 2 = N/2048, 3 = Tone 3, where N = 3579545. 45 | 0 is highest noise frequency (see below). 46 | 1 1 1 1 y y y y Set noise attenuation. Attenuation 1111b = no sound. 47 | 48 | A = 10*log10(P2/P1) (dB) 49 | 50 | 51 | On older Tandy 1000's and on the IBM PCjr, bits 5 and 6 at port 61h must be 52 | set to enable the 3-voice chip (bit 6 enables the keyboard and must always 53 | be high). Bit 0 at this port should be low (this disables timer channel 2 54 | output to the speaker). These bits can be set/cleared by calling Int 1Ah, 55 | AX=8003h (see above). Do not change the other bits; on the 1000TL, setting 56 | bit 4 disables the speaker. It is not necessary to program port 61h on 57 | newer systems with the DAC. 58 | 59 | Tandy 1000 RL + 60 | 00C4 - 00C7 DAC Function 61 | C4 DAC Mode Register (Write commands) 62 | Bit 0 Bit 1 63 | 0 0 Joystick 64 | 0 1 Successive Approximation 65 | 1 0 Sound Channel 66 | 1 1 Direct Write to DAC 67 | 68 | Bit 2 DMA Enabled 69 | Bit 3 DMA Interrupt Clear 70 | Bit 4 DMA Interrupt Enable 71 | Bit 5 Sound Divider Sync Enable 72 | Bit 6 Sound Chip Extra Divide Enable 73 | Bit 7 Reserved 74 | 75 | C4 DAC Mode Register (Read commands) 76 | Bit 3 DMA Interrupt flag 77 | Bit 7 Successive Approximation Done 78 | 79 | C5 Waveshape Model Select (Write commands) 80 | Bit 0 Bit 1 Bit 2 81 | 0 0 0 6.25% 82 | 0 0 1 12.50% 83 | 0 1 0 18.75% 84 | 0 1 1 25.00% 85 | 1 0 0 31.25% 86 | 1 0 1 37.50% 87 | 1 1 0 43.75% 88 | 1 1 1 50.00% 89 | 90 | Bit 7 Bit 6 Waveshape Selected 91 | 0 0 Pulse 92 | 0 1 Ramp 93 | 1 0 Triangle 94 | 95 | C5 Read DAC Registers (Read commands) 96 | Direct Read of DAC when 00C4 Bits 0-1 = 1X 97 | Direct Read of Control Register when 00C4 Bits 98 | 0-1 = 01 99 | 100 | C6 R/W Frequency LSB for DAC sound channel 101 | Bit 0 F0 102 | Bit 1 F1 103 | Bit 2 F2 104 | Bit 3 F3 105 | Bit 4 F4 106 | Bit 5 F5 107 | Bit 6 F6 108 | Bit 7 F7 109 | 110 | C7 R/W Amplitude/frequency MSB for DAC sound channel 111 | Bit 0 F8 112 | Bit 1 F9 113 | Bit 2 F10 114 | Bit 3 F11 115 | Bit 4 Reserved 116 | Bit 5 Amp 1 117 | Bit 6 Amp 2 118 | Bit 7 Amp 3 119 | 120 | Software Interrupt 1AH 121 | 122 | AH = 81H: Get Sound Status 123 | AH = 82H: Input Sound (from the microphone) 124 | AH = 83H: Output Sound (to the speaker) 125 | AH = 84H: Stop Sound Input and Output } 126 | 127 | TDY_PortTotal = 5; 128 | TDY_PortList : Array[0..5] of Word = (0,$00C0,$01E0,$2C0,$205,$300); { 205 PCJr } 129 | 130 | VAR 131 | 132 | TDY_Type : Byte; { 0 : Nothing 1 : SNxxx 2: SNxxx LPT 3: Emulated} 133 | TDY_DACPort : WORD; { 0 Not present otherwise, Port } 134 | TDY_Port : WORD; { 0 Not present otherwise, Port } 135 | TDY_PortNb : Byte; { Port Nb in the list } 136 | TDY_LPT_Nb : Byte; { 0 No, 1 LPT1 2 LPT2 } 137 | 138 | PROCEDURE TDY_DetectDAC; 139 | PROCEDURE TDY_InitDAC; { Initialize the DAC in direct I/O Mode } 140 | PROCEDURE TDY_DetectOld; { Detect an and Init an Old Tandy 1000 (SN76489) } 141 | 142 | IMPLEMENTATION 143 | 144 | { 1 If BIOS Detected, 2 if BIOS and Port detected } 145 | 146 | PROCEDURE TDY_DetectDAC; Assembler; 147 | Asm 148 | 149 | XOR CX,CX 150 | MOV TDY_Port,CX 151 | MOV TDY_DACPort,CX 152 | { MOV AX,8003h } 153 | { INT 1Ah } 154 | { CMP CX,5353h } 155 | { JE @DACDETECT_NODAC } {Skip detecting the DAC if PCMCIA present} 156 | 157 | MOV AX,8100h 158 | INT 1Ah {Detect the Tandy DAC BIOS } 159 | CMP AX,00C4h {Check one of the 3 possible ports } 160 | JE @DACDETECT_OK 161 | CMP AX,1E4h 162 | JE @DACDETECT_OK 163 | CMP AX,304h 164 | JE @DACDETECT_OK 165 | JMP @DACDETECT_NODAC 166 | 167 | @DACDETECT_OK: 168 | MOV TDY_DACPort,AX { Save Tandy DAC Port } 169 | SUB AX,4 170 | MOV TDY_Port,AX { Save Tandy Port } 171 | 172 | { MOV DX,TDY_DACPort} 173 | { ADD DX,2 } { Frequency Low Reg (Is R/W)} 174 | { IN AL,DX} 175 | { MOV CL,AL } { Save de Port Value } 176 | { XOR AX,AX } { Write 0 to the Port } 177 | { OUT DX,AL} 178 | { IN AL,DX} 179 | { OR AL,AL } { Read and Compare } 180 | { JNZ @DACDETECT_NOPort} 181 | 182 | { NOT AX } { Write 0FFh to the Port } 183 | { OUT DX,AX} 184 | { IN AX,DX} 185 | { NOT AX} 186 | { JNZ @DACDETECT_NOPort} 187 | 188 | { MOV AL,CL } { Restore the Value } 189 | { OUT DX,AL} 190 | 191 | MOV TDY_Type,1 { Found -> 1 } 192 | JMP @DACDETECT_End 193 | { @DACDETECT_NOPort:} 194 | { MOV AL,CL } { Restore the Value } 195 | { OUT DX,AL} 196 | { MOV TDY_Type,1 } { Only IRQ Found : 1 (DOSBOX With SB Activated) } 197 | { JMP @DACDETECT_End} 198 | @DACDETECT_NODAC: 199 | MOV TDY_Type,0 { Not Found -> 0 } 200 | @DACDETECT_End: 201 | End; {TDY_DetectDAC} 202 | 203 | {=========================================================} 204 | 205 | PROCEDURE TDY_InitDAC; { Initialize the DAC in direct I/O Mode } 206 | Begin 207 | 208 | { 209 | ; 210 | ; Routine to set the DAC for direct mode. 211 | ; 212 | DIRECTSET: 213 | PUSH AX 214 | PUSH DX 215 | MOV DX,PORTBASE 216 | CLI 217 | IN AL,DX ; set base port (DAC Control Register) 218 | JMP $+2 ; Delay 219 | AND AL,0E3h 220 | OR AL,3 221 | OUT DX,AL 222 | JMP $+2 223 | INC DX ; set volume at (base+2), (base+3) 224 | INC DX 225 | MOV AL,0 226 | OUT DX,AL 227 | JMP $+2 228 | INC DX 229 | MOV AL,0E0h 230 | OUT DX,AL 231 | JMP $+2 232 | STI 233 | POP DX 234 | POP AX 235 | RET 236 | } 237 | 238 | End; 239 | 240 | PROCEDURE TDY_DetectOld; Assembler; { Detect a Tandy 1000 or PC Junior With Default base @ } 241 | Asm 242 | MOV AX,0FFFFh 243 | MOV ES,AX 244 | CMP BYTE PTR ES:[0Eh],0FDh 245 | JE @@TDY_Ok { PC Junior Detected } 246 | CMP BYTE PTR ES:[0Eh],0FFh 247 | JNE @@TDY_Ko 248 | MOV AX,0FC00h 249 | MOV ES,AX 250 | CMP BYTE PTR ES:[0],21h 251 | JNE @@TDY_Ko 252 | 253 | @@TDY_Ok: {61h : MC14529b sound multiplexor chip in the PCjr} 254 | 255 | CLI { Init } 256 | IN AL,61h { get byte from port 61h } 257 | OR AL,60h { set bits 5 and 6 } 258 | AND AL,0FEh { clear bit 0 } 259 | OUT 61h,AL { write back to enable sound chip } 260 | STI 261 | 262 | MOV TDY_Type,1 263 | MOV TDY_Port,0C0h 264 | 265 | @@TDY_Ko: 266 | XOR AX,AX 267 | @@TDY_End: 268 | End; {TDY_DetectOld} 269 | 270 | END. 271 | -------------------------------------------------------------------------------- /TPUNIT/TEXTE.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/TEXTE.PAS -------------------------------------------------------------------------------- /TPUNIT/TYPES.PAS: -------------------------------------------------------------------------------- 1 | TYPE String80=String[80]; 2 | String64=String[64]; 3 | String26=String[26]; 4 | String25=String[25]; 5 | String20=String[20]; 6 | String12=String[12]; 7 | String8 =String[8]; 8 | String3 =String[3]; 9 | 10 | SetofChar=Set of Char; 11 | 12 | CharPtr =^Char; 13 | BytePtr =^Byte; 14 | ShortPtr=^Shortint; 15 | WordPtr =^Word; 16 | IntPtr =^Integer; 17 | LongPtr =^Longint; -------------------------------------------------------------------------------- /TPUNIT/UTIL.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/UTIL.PAS -------------------------------------------------------------------------------- /TPUNIT/UTILC.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/UTILC.PAS -------------------------------------------------------------------------------- /TPUNIT/VARUNIT.PAS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FreddyVRetro/MODMXT/b60d22bd7ec80f286bf693882fa72e1049fdd260/TPUNIT/VARUNIT.PAS --------------------------------------------------------------------------------