_ISM.TXT ~~~~~~~~ Imperial Games Sound Machine ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ISM Version 0.19 ~~~~~~~~~~~~~~~~ Introduction ~~~~~~~~~~~~ This text has DRAFT state and is subject to change. For issues of using tables and therefore needed special 'graphic' chars (ASCII-8) it is recommended to view this text in codepage 437 monospaced charset (ISO-8437). This text describes the processing, registers, data and programming of the present version of Imperial Games Sound Machine, now and following called ISM. Furthermore the keys for the interface of the corresponding data editor ("Tracker") - named "prISM" are listed. The mnemonics of the opcodes for the ISM commands were chosen referring to these keys. Sound Data Description ~~~~~~~~~~~~~~~~~~~~~~ The sound data contain 128 different main commands that are each ALWAYS 16 (sixteen) bits wide. A command includes its parameter (or parameters) in its data word. The command pseudo opcode (byte code) is mostly encoded in the higher 7 (seven) bits, while the parameter(s) are encoded in the lower 9 (nine) bits. In some cases, a command is divided into two or four sub-commands, by using bit 8 or bits 8 and 7 as an expansion to the command index number. The special command $6F/1xx contains of many sub-commands, encoded in the lower 8 bits. A prISM sound track consists of a maximum of 512 commands - although it is still possible to put the whole data into a data chunk of up to 32 kByte. A whole sound data file may contain of up to 2048 tracks, overlapping each other by 8 (eight) words - that is 16 (sixteen) bytes. Thus, a track can start at every 8th command. This also makes handling of sound data more easily - for placing it into whole x86 real mode paragraphs (segments). The command pseudo opcodes are shown here in hexadecimal, led by $. The first 96 commands ($00 to $5F) are the "notes". For them all being processed the same way, they are listed as one command. The command number is the note itself. This makes a bandwidth of full 8 (eight) octaves with 12 (twelve) halftones each. The "duration" ranges given in FUNCTION are meant for a "factor" value of 1 (one). So, with a factor of $FF (255) and a given length of $1FF (511) a maximum playlength of $1FD01 (130305) is possible, that is $3FA (1018) seconds. Note1: These terms are used in here and in the help texts: * DEVICE: There are 2 (two) of them, 0 and 1. This is a feature to e.g. play music and sound effects in a game "independently" from each other - i.e. in a manner their data do not interfere. * VOLUME-CONTROL: There are 16 (sixteen) of them, for each DEVICE. The CONTROL is set by every VOL command. The volume is "multiplied" by the set value of the CONTROL (two arrays of 16 bytes each). The main purpose of this feature is to give sound effects different volumes (e.g. depending of the distance of the "sound source" from the player in a game). * TUNE: A single TUNE it is called for voices that "belong together" as a music. The TUNEs are controlled by a table of 16 (sixteen) words. Each word references to a voice and is a bitmask of all voices belonging to the same TUNE. When a voice starts another voice ifself, the other voice is set to the same TUNE and same DEVICE. The purpose of this feature is to avail voices of the same TUNE to "interfere". Note2: LoopX and LoopY variables/registers mentioned in the text below are two "free-to-use" 8-bit-registers in each voice. They are named "Loop" because their main purpose is to work as counters for loops in the music data. (You can repeat a part up to 256 times with one register and you can even "nest" two loops, for a total of 65536 times maximum.) Note3: The stack is an 8 (eight) byte wide memory in each voice. It works as a LIFO (last in, first out) stack, its 3 bit pointer counts upwards. Its main purpose is to store up to 4 (four) "back jump" addresses when using calls of sub-parts (e.g. command SUB) - so calls can get "nested" up to 4 times. Additionally the LoopX/LoopY registers can be pushed onto this stack (as bytes) - to save and recover their contents (see commands Z:PSH and Z:POP). Note4: CAUTION! When pushed (Z:PSH) values or variables (LoopX/LoopY) onto the stack, be sure to pop (Z:POP) them before returning (Z:RET) from a call! (For pushed/saved variables/values use the same stack as pushed addresses from i.e. a SUB command.) Note5: The "external interface" are 4 (four) 256 byte wide stacks, given as pascal type strings (first byte = count, others = content). That is, two interface-strings for each of the two "DEVICEs", makes four strings (2 send, 2 receive) total. When ISM sends to external, the bytes are attached at the end. When ISM receives from external, the bytes are removed from start. Note6: The "stack automatic" (see commands OTR, XNE, YNE, LPX, LPY) was made to avail nesting more loops than only two. It saves the contents of the LoopX/LoopY register before a loop and recovers them after a loop. This could be done e.g. by Z:PSH X; LPX; ... ; XNE; Z:POP X but such with "stack automatic" the Z:PSH and Z:POP commands are done automatically. CAUTION: If you use one of the registers otherwise - e.g. for calculations or for setting them to expand the parameters (e.g. LoopY with command NEW) or to initialize them for commands USX / USY - pay attention if the "stack automatic" is set active for this register! Note7: With ISM version 0.14 the full synchronizing for the voices are possible, even with voices starting playing later in a TUNE. This can be activated with a flag (sm_SoftSyncMode=TRUE). The commands providing this option are marked with [SYNCHRONIZING] in this text. Note8: With ISM version 0.15 an "out running" counter is provided. This decreases with every command that doesn't produce sound data (e.g. playlength=0) and "jumps out" when outrun. The purpose of this out run counter is to avoid freezing the program (e.g. by "dead-running" loops). The Commands ~~~~~~~~~~~~ COMMAND : opcodes and hotkeys to set the command (sh_ = shift key) MNE : standard mnemonic of the command (in prISM) PARAMETER HI: purpose of the highbit (bit 8) of the 9-bit-parameter PARAMETER LO: purpose of the lowbyte (bits 0 to 7) of the 9-bit-parameter (in some cases the whole 9 bit are used as one parameter). FUNCTION : what the command does NOTE: duration values are given with a set speed of 1 (one). COMMAND³MNE³PARAMETER HI³PARAMETER LO ³FUNCTION [real command word in hex] ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[0000-BFFF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $00-$5F³C-0³ PlayLength/Duration ³play note: 8 octaves … 12 halftones CDEFGAH³H-7³ $000-$1FF ³parameter=duration, $100 =2 seconds ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[C000-C1FF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $60 ³BND³ PlayLength/Duration ³portamento to the next played note B ³ ³ $000-$1FF ³parameter=duration, $100 =2 seconds ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[C200-C2FF,C300-C3FF]ÄÄÄÄÄ $61 ³BRL³0=HardRelease³Duration/Lng³release of the last played note sh_B/R ³REL³1=SoftRelease³ $00-$FF ³parameter=duration, $100 =2 seconds ³ ³ ³ ³the real release length depends on ³ ³ ³ ³the set release value in the KSR ³ ³ ³ ³command and the DEVICE (see command ³ ³ ³ ³Z:DEV). ³ ³ ³ ³after release time ended, tone goes ³ ³ ³ ³mute until end of set duration. ³ ³ ³ ³if duration ends before set release ³ ³ ³ ³the tone is cut off. ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[C400-C5FF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $62 ³MUT³ PlayLength/Duration ³absolute mute (quiet voice) M ³ ³ $000-$1FF ³parameter=duration, $100 =2 seconds ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[C600-C6FF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $63 ³HLD³0=Hold Tone ³ Duration ³hold (continue) the last played sh_H ³ ³ ³ $00-$FF ³tone/note. ³ ³ ³ ³intended to change/alter settings ³ ³ ³ ³of a tone while playing it. Ã---Å------------Å-------------Å---------[C700-C7FF]--------------- T ³TRN³1=Transpose ³Halftones to ³transpose all played notes up/down ³ ³ ³Transpose ³by -128..127 halftones. 0 = normal. ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÂÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[C800-C8FF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $64 ³VOL³0=Set Volume³CONTRL³Volume³set absolute volume (bits 3-0). mix V ³ ³ ³ ³ ³with a "CONTROL" (bits 7-4). ³ ³ ³ ³ ³these CONTROLs are meant to change ³ ³ ³ ³ ³the sub-volume for single voices ³ ³ ³ ³ ³by the external program. ³ ³ ³ ³ ³you may set up to 16 CONTROLs for ³ ³ ³ ³ ³each "DEVICE" (see command Z:DEV) Ã---Å------------Å------Á------Å---------[C900-C9FF]--------------- Z ³ZOM³1=Set Factor³Durat. Factor³all duration values are multiplied ³ ³ ³ $00-$FF ³by this factor. 0 is invalid and ³ ³ ³ ³works like 1 in present versions. ³ ³ ³ ³NOTE: other than in MOD format, the ³ ³ ³ ³ factor is "reverse speed": ³ ³ ³ ³ 1=fastest, 255=slowest ³ ³ ³ ³ so, factor 1 (and 0) ³ ³ ³ ³ multiplies duration by 1/128 ³ ³ ³ ³ seconds, 2 by 1/64 secs, 3 by ³ ³ ³ ³ 3/128 secs (=1/42.666 secs) ³ ³ ³ ³NOTE: other than in MOD format, the ³ ³ ³ ³ speed affects only the ³ ³ ³ ³ present voice. ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[CA00-CAFF,CB00-CBFF]ÄÄÄÄÄ $65 ³USX³0=Use For X ³Signed 8-bit ³get an immediate 8bit value from U/sh_U ³USY³1=Use For Y ³Offset ³the "external interface" to LoopX ³ ³ ³ ³or LoopY variable; if a value was ³ ³ ³ ³present, then jump to address+/- ³ ³ ³ ³offset, else move to next command. ³ ³ ³ ³CAUTION! - SPECIAL FEATURE:ÄÄÄÄÄÄÄ¿ ³ ³ ³ ³you have to initialize LoopX/LoopY³ ³ ³ ³ ³before using these commands! ³ ³ ³ ³ ³just set the variable to a minimum³ ³ ³ ³ ³or maximum value before. bit0 ³ ³ ³ ³ ³decides, whether a minimum (0) or ³ ³ ³ ³ ³a maximum (1) is given: ³ ³ ³ ³ ³$4C:values $4C-$FF are taken ³ ³ ³ ³ ³$79:values $00-$79 are taken ³ ³ ³ ³ ³$00:values $00-$FF (all) are taken³ ³ ³ ³ ³$FF:values $00-$FF (all) are taken³ ³ ³ ³ ³only when value is taken, LoopX/Y ³ ³ ³ ³ ³will get changed and the data in ³ ³ ³ ³ ³"external interface" is erased and³ ³ ³ ³ ³the jump is done! ³ ³ ³ ³ ³CAUTION! if using min-/max-values,³ ³ ³ ³ ³and data isn't taken for being out³ ³ ³ ³ ³of range, it will "block" the next³ ³ ³ ³ ³data - because the external ³ ³ ³ ³ ³interface works as a FIFO-stack! ³ ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[CC00-CCFF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁ $66 ³OUT³0=Immediate ³ Direct Byte ³output an immediate 8bit value to O ³ ³ ³Value $00-$FF³the "external" interface Ã---Å------------Å--Â----------Å---------[CD00-CDFF]--------------- sh_O ³OTR³1=Register ³SZ³ Register ³output content of one ISM register ³ ³ ³ ³ Offset ³to the "external" interface. SZ for ³ ³ ³ ³ $00-$5F ³byte(0) or word(1) ³ ³ ³ ³ ³NOTE: LoopX/LoopY registers are ³ ³ ³ ³ ³ located at offsets $5E/$5F. ³ ³ ³ ³ ³NOTE: only offsets $00-$5F are ³ ³ ³ ³ ³ valid here! ³ ³ ³ ³ ³NOTE: offsets $64-$7F don't work ³ ³ ³ ³ ³ in this ISM version, because ³ ³ ³ ³ ³ they exceed the size of an ³ ³ ³ ³ ³ ISM voice register bank. ³ ³ ³ ³ ³NOTE: consider the values $64-$7F ³ ³ ³ ³ ³ as "reserved" here and DON'T ³ ³ ³ ³ ³ USE THEM! they are reserved ³ ³ ³ ³ ³ and maybe work different ³ ³ ³ ³ ³ in future versions! ³ ³ ³ ³ ³SPECIAL FEATURE: ³ ³ ³ ³ ³ values $60..$63 got special ³ ³ ³ ³ ³ functions: they set four bits ³ ³ ³ ³ ³ (bits 3..6) in register $5D ³ ³ ³ ³ ³ to activate/deactivate the ³ ³ ³ ³ ³ "stack automatic" for these ³ ³ ³ ³ ³ commands: ³ ³ ³ ³ ³ LPX / XNE (bit 3) ($60) ³ ³ ³ ³ ³ LPY / YNE (bit 4) ($61) ³ ³ ³ ³ ³ and to activate/deactivate ³ ³ ³ ³ ³ "discard use Y" function for ³ ³ ³ ³ ³ these commands: ³ ³ ³ ³ ³ NEW (bit 5) ($62) ³ ³ ³ ³ ³ MSB (bit 6) ($63) ³ ³ ³ ³ ³ The first parameter of OTR ³ ³ ³ ³ ³ has to be set to 0, to switch ³ ³ ³ ³ ³ the option OFF (default), and ³ ³ ³ ³ ³ 1, to switch it ON. ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÂÄÄÄÁÄÄÁÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[CE00-CFFF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $67 ³NEW³bit 6-8:³bit 0-5: upper 6 ³[SYNCHRONIZING] sh_N ³ ³VoiceNr ³bits of address ³initialize a voice to a start ³ ³ ³ ³address, in a "complicated" way: ³ ³ ³ ³bit: e D C B A 9 8 7 6 5 4 3 2 1 0 ³ ³ ³ ³ ÚÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄ¿ ³ ³ ³ ³ ³±³Y76³NEW-address³ LoopY 5-0 ³ ³ ³ ³ ³ ÀÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÙ ³ ³ ³ ³ ÞÛÛÛÛÛÛÛÛÛÛÛÝ ³ ³ ³ ³this method was chosen, because ³ ³ ³ ³sound data shouldn't exceed the ³ ³ ³ ³"normal" address range (0..$FFF) - ³ ³ ³ ³so an easy voice initialization is ³ ³ ³ ³possible here - with granularity ³ ³ ³ ³of 64 frames. that equals an ³ ³ ³ ³"eighth" of a whole "track".) ³ ³ ³ ³that is, if the LoopY register is ³ ³ ³ ³zero (0) before. ³ ³ ³ ³to make larger sound source data ³ ³ ³ ³possible, LoopY may be used to ³ ³ ³ ³define larger address ranges and ³ ³ ³ ³more "precise" addresses. ³ ³ ³ ³to "save" LoopY (if needed other- ³ ³ ³ ³wise), use the push/pop option of ³ ³ ³ ³special funtions in command $6F. ³ ³ ³ ³NOTE: to switch-off the usage of ³ ³ ³ ³ LoopY here, use: OTR 1,62 . ³ ³ ³ ³ All the bits occupied by ³ ³ ³ ³ LoopY above, will be set to ³ ³ ³ ³ zero (0) then. ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÁÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[D000-D0FF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $68 ³PLY³0=Play ³Voice To Play³[SYNCHRONIZING] P ³ ³ ³ bitwise ³Play: set voices to play for the ³ ³ ³ ³present "TUNE" active ³ ³ ³ ³(start playing these voices). ³ ³ ³ ³NOTE: the bits of already playing ³ ³ ³ ³ voices have to be SET here, ³ ³ ³ ³ too. otherwise these voices ³ ³ ³ ³ will stop playing! ³ ³ ³ ³ thus this command can be ³ ³ ³ ³ used to stop/start voices ³ ³ ³ ³ without having to "remove" ³ ³ ³ ³ them from the TUNE (by the ³ ³ ³ ³ QUV command). ³ ³ ³ ³ (a removed voice would need ³ ³ ³ ³ re-initializing, and thus, ³ ³ ³ ³ lose all its settings) ³ ³ ³ ³NOTE: the bits are counted from the ³ ³ ³ ³ present voice and wrap-around ³ ³ ³ ³ then if the number of voices ³ ³ ³ ³ in the TUNE is reached. ³ ³ ³ ³CAUTION! a stopped voice (by clear ³ ³ ³ ³ bit) can only get restarted by ³ ³ ³ ³ other voices! so, consider this ³ ³ ³ ³ when clearing bit 0 when using ³ ³ ³ ³ this command! Ã---Å------------Å-Â----Â------Å---------[D100-D1FF]--------------- sh_V ³VOI³1=VoiceInit ³Y³Pan-³Number³Initialize voices - get additional ³ ³ ³ ³ning³of new³voices for this "TUNE". ³ ³ ³ ³ ³Voices³a TUNE contains of 1 to 8 voices. ³ ³ ÃÄÁÄÄÄÄÁÄÄÄÄÄÄ´that is: existing+new voices <=8 ! ³ ³ ÞÛÝ!CAUTION!ÞÛÝ(because the PRESENT used voice is ³ ³ ³ In the MONO ³already one of the maximum 8, 0 to ³ ³ ³ ISM version ³7 voices can get added.) ³ ³ ³ panning is ³Panning sets "stereo balance" for ³ ³ ³ not needed/ ³all new voices together (1-15). if ³ ³ ³ available: ³0 is used, it sets left/right ³ ³ ³ Voices are ³channel to maximum (=no panning). ³ ³ ³ then only ³If the Y-bit is set, the number of ³ ³ ³ affected by ³"overflowing" voices, that is, the ³ ³ ³ the Volume ³number of voices that couldn't get ³ ³ ÃÄÂÄÄÄÄÂÄÄÄÄÄÄ´set (exceeding total 8 voices or ³ ³ ³0³Pan.³ 000 ³voices in use by other TUNEs), is ³ ³ ³ ³act.³ ³returned in Y-register (LoopY). ³ ³ ³ ³Voic³ ³NOTE: if set "Number of new Voices" ³ ³ ÃÄÁÂÄÄÄÅÄÄÄÄÄÄ´ to 0 (zero), the panning for ³ ³ ³10³1-7³ 000 ³ the present voice is set! ³ ³ ³Get Y of Voi#³NOTE: when searching for free ³ ³ ÃÄÄÂÄÄÄÂÄÄÄÄÄÄ´ voices, the voices "above" ³ ³ ³11³1-7³ 000 ³ the present one are taken ³ ³ ³Set Y in Voi#³ first, then (if more voices ³ ³ ÃÄÄÂÄÄÄÂÄÄÄÄÄÄ´ needed) "wrap around" to ³ ³ ³10³000³ 000 ³ ISM voice 0. ³ ³ ³UsedVoices->Y³NOTE: new voices registers are all ³ ³ ÃÄÄÂÄÄÄÂÄÄÄÄÄÄ´ initialized to zeroes (0)! ³ ³ ³11³000³ 000 ³ only the "lock" bit is set, ³ ³ ³FreeVoices->Y³ to avoid the voices from ³ ³ ÃÄÄÄÄÄÄÂÄÄÄÄÄÄ´ operating (playing) - giving ³ ³ ³ ³ ³ a chance to setup them. ³ ³ ³ ³ ³ furthermore the "DEVICE" bit ³ ³ ³ ³ ³ is set the same as the ³ ³ ³ ³ ³ present voice's. ³ ³ ³ ³ ³ this means: you don't have to ³ ³ ³ ³ ³ initialize a voice register, ³ ³ ³ ³ ³ if it should be zero. ³ ³ ³ ³ ³NOTE: you may set the bit Y, to get ³ ³ ³ ³ ³ the result into LoopY. the ³ ³ ³ ³ ³ result is the number of ³ ³ ³ ³ ³ "overflow" voices that ³ ³ ³ ³ ³ could'n get taken (for lack ³ ³ ³ ³ ³ of "free" voices or if the ³ ³ ³ ³ ³ sum of already used and new ³ ³ ³ ³ ³ voices exceeds 8 (eight). ³ ³ ³ ³ ³ in combination of the special ³ ³ ³ ³ ³ jump commands (see YJT and ³ ³ ³ ³ ³ Z: special commands) you may ³ ³ ³ ³ ³ react in these cases. ³ ³ ³ ³ ³[Û²±° SPECIAL FEATURE °±²Û] ³ ³ ³ ³ ³ the Y-bit =1 in combination with ³ ³ ³ ³ ³ setting "Number of new Voices" to ³ ³ ³ ³ ³ 0 (zero) makes a new command with ³ ³ ³ ³ ³ this parameter: ³ ³ ³ ³ ³bit 7 6 5 4 3 2 1 0 ³ ³ ³ ³ ³ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ³ ³ ³ ³ ³ ³ 1 ³G/S³[Voice-Nr.]³ 0 ³ 0 ³ 0 ³ ³ ³ ³ ³ ³ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ ³ ³ ³ ³ ³ bit 7=1 (Y-Bit) ³ ³ ³ ³ ³ bit 2..0=0 (Number of New Voices) ³ ³ ³ ³ ³ bit 5..3=Voice-Number 1..7 ³ ³ ³ ³ ³ bit 6=Get(0), Set(1) ³ ³ ³ ³ ³ this provides a way to interact ³ ³ ³ ³ ³ between the different voices. ³ ³ ³ ³ ³ with bit 6=0 you can copy LoopY ³ ³ ³ ³ ³ register of one of the other ³ ³ ³ ³ ³ voices into LoopY register of the ³ ³ ³ ³ ³ present voice. ³ ³ ³ ³ ³ with bit 6=1 you copy vice versa: ³ ³ ³ ³ ³ [SYNCHRONIZING] ³ ³ ³ ³ ³ the LoopY register of the present ³ ³ ³ ³ ³ voice is copied into LoopY ³ ³ ³ ³ ³ registers of the other voices. ³ ³ ³ ³ ³ the synchronizing works only for ³ ³ ³ ³ ³ setting, but NOT for getting! ³ ³ ³ ³ ³NOTE: getting/setting LoopY of ³ ³ ³ ³ ³ voice #0 (the present voice) ³ ³ ³ ³ ³ seems senseless. ³ ³ ³ ³ ³ thus these two combinations: ³ ³ ³ ³ ³bit 7 6 5 4 3 2 1 0 ³ ³ ³ ³ ³ ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿ ³ ³ ³ ³ ³ ³ 1 ³A/R³ 0 ³ 0 ³ 0 ³ 0 ³ 0 ³ 0 ³ ³ ³ ³ ³ ³ ÀÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÁÄÄÄÙ ³ ³ ³ ³ ³ are designed to result a ³ ³ ³ ³ ³[Û²±° SPECIAL SPECIAL FEATURE °±²Û] ³ ³ ³ ³ ³ with bit6=0 the number of ³ ³ ³ ³ ³ currently used voices in the TUNE ³ ³ ³ ³ ³ is returned in LoopY. ³ ³ ³ ³ ³ with bit6=1 the number of unused ³ ³ ³ ³ ³ (free) voices of ISM is returned ³ ³ ³ ³ ³ in LoopY. ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[D200-D3FF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $69 ³SUB³ Signed 9-Bit Offset ³unconditional relative call to sh_S ³ ³ -$100..+$0FF ³address+/-offset. saves the present ³ ³ -$100..+$0FF ³address+1 into stack. ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[D400-D4FF,D500-D5FF]ÄÄÄÄÄ $6A ³XJT³0=Jump If X³Positive ³depending of the value in LoopX or sh_X ³YJT³1=Jump If Y³Offset to the ³LoopY: jump to address+offset+value sh_Y ³ ³ ³PresentAddress³ ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[D600-D7FF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $6B ³JMP³ Signed 9-Bit Offset ³unconditional relative branch to J ³ ³ -$100..+$0FF ³address+/-offset ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[D800-D9FF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $6C ³XNE³ Signed 9-Bit Offset ³countdown LoopX. if result is not X ³ ³ -$100..+$0FF ³zero, branch relative to Addr+Offs ³ ³ ³if "stack automatic" is set, a byte ³ ³ ³is taken from stack to LoopX, when ³ ³ ³LoopX reaches 0 (zero). see LPX ³ ³ ³NOTE: with OTR 1,60 the "stack ³ ³ ³automatic" is activated for this ³ ³ ³command and LPX. in this case, ³ ³ ³LoopX is loaded with the next byte ³ ³ ³in stack after it reached 0 (zero). ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[DA00-DBFF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $6D ³YNE³ Signed 9-Bit Offset ³countdown LoopY. if result is not Y ³ ³ -$100..+$0FF ³zero, branch relative to Addr+Offs. ³ ³ ³if "stack automatic" is set, a byte ³ ³ ³is taken from stack to LoopY, when ³ ³ ³LoopY reaches 0 (zero). see LPY ³ ³ ³NOTE: with OTR 1,61 the "stack ³ ³ ³automatic" is activated for this ³ ³ ³command and LPY. in this case, ³ ³ ³LoopY is loaded with the next byte ³ ³ ³in stack after it reached 0 (zero). ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[DC00-DCFF,DD00-DDFF]ÄÄÄÄÄ $6E ³LPX³0=LoopX ³CountDownValu³set LoopX/LoopY-variable to L/sh_L ³LPY³1=LoopY ³ $00-$FF ³(countdown) value ($00 = $100) ³ ³ ³ ³this is the command to set values ³ ³ ³ ³to LoopX/LoopY - intended to give ³ ³ ³ ³the number of repeatings (when ³ ³ ³ ³used in combination with XNE/YNE ³ ³ ³ ³commands) - but can also be used ³ ³ ³ ³for all the "math" commands (see ³ ³ ³ ³the Z: command DFxx list). ³ ³ ³ ³if "stack automatic" is set, the ³ ³ ³ ³present content of LoopX/LoopY is ³ ³ ³ ³put onto stack before. ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[DE00]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $6F ³NOP³0 ³ $00 ³fill command. does nothing. N ³ ³ ³ ³actually, there isn't a special ³ ³ ³ ³determined "nop" command in ISM - ³ ³ ³ ³but setting all "quit voices" bits ³ ³ ³ ³to zeroes results in doing nothing ³ ³ ³ ³here, so you may use this command ³ ³ ³ ³with 00-parameter as a "nop". (the ³ ³ ³ ³prISM tracker outputs this as NOP.) Ã---Å------------Å-------------Å---------[DE01-DEFF]--------------- Q ³QUV³0=QuitVoices³Voices ToQuit³[SYNCHRONIZING] ³ ³ ³ ³quit these voices, bitwise ³ ³ ³ ³ÉÍÍÍÍÍÍÍÍÛ²±°!CAUTION!°±²ÛÍÍÍÍÍÍÍÍ» ³ ³ ³ ³º the bits of the voices refer to º ³ ³ ³ ³º the ACTIVE voices belonging to º ³ ³ ³ ³º the present processed voice in º ³ ³ ³ ³º "combination"! (that means: To º ³ ³ ³ ³º the present "TUNE".) Inactive º ³ ³ ³ ³º or unused voices are "jumped º ³ ³ ³ ³º over" while counting - but a º ³ ³ ³ ³º voice that was just stopped (by º ³ ³ ³ ³º zero-bits in PLY-command) is º ³ ³ ³ ³º affected here! º ³ ³ ³ ³º If the PRESENT PROCESSED voice º ³ ³ ³ ³º is affected (and thus, quit) - º ³ ³ ³ ³º NO FURTHER COMMAND will be done º ³ ³ ³ ³º afterwards! the whole working º ³ ³ ³ ³º for this voice is stopped then! º ³ ³ ³ ³º such a voice cannot get º ³ ³ ³ ³º "restarted" by other voices of º ³ ³ ³ ³º the same "TUNE" - because the º ³ ³ ³ ³º voice doesn't no longer belong º ³ ³ ³ ³º to this (or any) "TUNE" then! º Ã---Å------------Å-------------ÅÐ--------[DF00-DFDF]--------------Ð sh_Z ³Z: ³1 ³SPECIAL COMMAND! FUNCTION DEPENDS ON ALL BITS IN ³???³ ³BYTE PARAMETER! ³ ³ ³This command is something like an "opcode". It ³ ³ ³works with the LoopX/LoopY variables as like as ³ ³ ³with "registers". The parameter is used bitwise: ³ ³ ³ Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 ³ ³ ³ÚÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄÂÄÄÄÄÄ¿ ³ ³ ³³ OPERATION TO DO (SEE BELOW) ³Use Y³Use X³ ³ ³ ³ÀÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÙ ³ ³ ³It sometimes "modifies" the next command in the ³ ³ ³track. (The change happens internally, the sound ³ ³ ³data isn't really changed.) ³ ³ ³þ LoopX affects the LOWBYTE of the next command. ³ ³ ³þ LoopY affects the HIGHBYTE. ³ ³ ³"Affecting" is, to XOR the following command by ³ ³ ³LoopX (LOWBYTE, mostly the data part) and LoopY ³ ³ ³(HIGHBYTE, mostly the command/"opcode" part). ³ ³ ³To make it easier to read/list the operation's ³ ³ ³parameters, the following abbreviations are ³ ³ ³declared here: ³ ³ ³ X=LoopX register (byte) ³ ³ ³ Y=LoopY register (byte) ³ ³ ³ L=lowbyte of next command (byte) ³ ³ ³ H=highbyte of next command (byte) ³ ³ ³ S=upper stack content (byte) ³ ³ ³ A="result" of bit 0: (0=---,1=L xor X) ³ ³ ³ B="result" of bit 0: (0=---,1=H xor Y) ³ ³ ³ C="result" of bit 0: (0=X,1=L) ³ ³ ³ D="result" of bit 1: (0=Y,1=H) ³ ³ ³ R="result" of bit 0: (0=X,1=Y) ³ ³ ³ YX="result" of bits 1+0: (00=X) ³ ³ ³ (01=Y) ³ ³ ³ (10=L) ³ ³ ³ (11=H) ³ ³ ³ YS="result" of bits 1+0: (00=S) ³ ³ ³ (01=Y) ³ ³ ³ (10=L) these³ ³ ³ (11=H) keys³ ³ ³ JI="result" of bits 1+0: (00=X,Y,L) have to³ ³ ³ (01=Y,X,L) be used³ ³ ³ (10=X,L,Y) after³ ³ ³ (11=Y,L,X) sh_Z:³ ³ ³ binary³Sub-Command Ú------³ ³ ³ÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ | C ³ ³ ³000000BA³chg change the next command by LoopX/Y | ³ ³ ³ ³ ( L=L xor X, H=H xor Y ) | ³ ³ ³ ³ - AND PROCESS THIS COMMAND! | ³ ³ ³ ³ NOTE: the command data doesn't get | ³ ³ ³ ³ changed! the change is only | ³ ³ ³ ³ done for the present operation! | ³ ³ ³ ³ NOTE: if A=0 and B=0, then no | ³ ³ ³ ³ operation is done - which makes | ³ ³ ³ ³ this command to another "nop" | ³ ³ ³ ³ then - but not displayed as NOP | ³ ³ ³ ³ by prISM this time! | ³ ³ ³--------Å---------------------------------------- | I ³ ³ ³0000010R³inc R (increments LoopX or LoopY) | D ³ ³ ³0000011R³dec R (decrements LoopX or LoopY) | M ³ ³ ³000010DC³mov D ,C (copy X or L to Y or H) | sh_X ³ ³ ³000011YS³mvx X ,YS (copy S,Y,L,H to LoopX) | S ³ ³ ³000100YS³swp X ,YS (swap S,Y,L,H with LoopX) | A ³ ³ ³000101YS³and X ,YS (LoopX bitwise AND S,Y,L,H) | O ³ ³ ³000110YS³or X ,YS (LoopX bitwise OR S,Y,L,H) | X ³ ³ ³000111YS³xor X ,YS (LoopX bitwise XOR S,Y,L,H) | sh_A ³ ³ ³001000YX³add X ,YX (LoopX + X,Y,L,H) | sh_S ³ ³ ³001001YX³sub X ,YS (LoopX - S,Y,L,H) | sh_M ³ ³ ³001010YX³mul X ,YX (LoopX * X,Y,L,H) | sh_D ³ ³ ³001011YX³div X ,YS (div 0 sets result to zero) | P ³ ³ ³001100YX³psh YX to stack (bytewise!) | sh_P ³ ³ ³001101YX³pop YX from stack (bytewise!) | J ³ ³ ³001110JI³caj I >J then branch to address+/-K | sh_J ³ ³ ³001111JI³cbj I sample slots ³ ³ ³ ³ need lot of memory - 11 bytes ³ ³ ³ ³ each - even when not used! ³ ³ ³ ³ <2> when the same sample is ³ ³ ³ ³ used by several voices, it ³ ³ ³ ³ has even to be loaded once.) ³ ³ ³ ³ÉCAUTION!ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ» ³ ³ ³ ³º ALWAYS CHECK BEFORE º ³ ³ ³ ³º USING THIS COMMAND ! º ³ ³ ³ ³ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ ³ ³ ³ ³NOTE: to switch-off the usage of ³ ³ ³ ³ LoopY here, use: OTR 1,63 . ³ ³ ³ ³ LoopY will not be added, but ³ ³ ³ ³ only sample buffers $0..$F ³ ³ ³ ³ will be available then. ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÂÄÄÄÁÄÄÄÄÂÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[F000-F1FF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $78 ³WAV³ WAVE#3 ³ WAVE#2 ³ WAVE#1 ³combines 3 of 7 waveforms. each W ³ ³bits 6-8³bits 3-5³bits 0-2³wave needs 3 bits. 0 (noise) cannot ³ ³ ³ ³ ³get combined with others. so a WAVE ³ ³ ³ ³ ³field =0 means: no other wave. ³ ³ ³ ³ ³ prISM³wavename ³key³waveform ³ ³ ³ ³ ³ÄÂÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄ ³ ³ ³ ³ ³0³ -- ³none ³ N ³ ³ ³ ³ ³ ³1³ Sw ³sawtooth ³ S ³__---~~~ ³ ³ ³ ³ ³2³ Tr ³triangle ³ T ³_--~~--_ ³ ³ ³ ³ ³3³ Cs ³cut-sawtooth ³ C ³_-~|---- ³ ³ ³ ³ ³4³ Pž ³pulse 1/8 ³ E ³_------- ³ ³ ³ ³ ³5³ P¬ ³pulse 2/8 (1/4)³ Q ³__------ ³ ³ ³ ³ ³6³ P« ³pulse 3/8 ³ H ³___----- ³ ³ ³ ³ ³7³ Pu ³pulse 4/8 (1/2)³ P ³____---- ³ ³ ³ ³ ³set all waves to (0/none) to use ³ ³ ³ ³ ³the noise generator (blue noise). ³ ³ ³ ³ ³this noise is intended to being ³ ³ ³ ³ ³used in percussions/explosions etc. ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÁÄÄÄÂÄÄÄÄÁÄÂÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[F200-F2FF,F300-F3FF]ÄÄÄÄÄ $79 ³KAD³0=AttckDecay³Attack³Decay ³set Attack/Decay/Sustain/Release- K/sh_K ³KSR³1=SustnRelea³Sustai³Releas³values for the envelope. ³ ³ ³$0-$F ³$0-$F ³Release only works if the note is ³ ³ ³ ³ ³followed by REL/BRL commands. ³ ³ ³ ³ ³the real lengths in 1/1000 seconds ³ ³ ³ ³ ³for Attack, Decay and Release are ³ ³ ³ ³ ³given in two external tables. ³ ³ ³ ³ ³the tables (0/1) are chosen by the ³ ³ ³ ³ ³"DEVICE" (see Z:DEV command) ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÂÄÄÄÂÄÄÄÂÁÄÄÄÄÄÄÁÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[F400-F5FF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $7A ³WFI³Tre³Ban³Bas³Upper or Lower³set the filter settings for this sh_W ³ ³ble³d ³s ³6 Bits of the ³voice. The upper 3 bits (8,7,6) ³ ³[T]³[M]³[B]³Cut-Off ³define the filter type (treble, ³ ³ ³ ³ ³Frequency ³band or pass filter; combinations ³ ³ ³ ³ ³ ³are possible) the lower 6 bits 5-0 ³ ³ ³ ³ ³ ³define the upper 6 bits of cut-off ³ ³ ³ ³ ³ ³frequency. to define a more precise ³ ³ ³ ³ ³ ³value, set the filtertype-bits to ³ ³ ³ ³ ³ ³zero, so the lower 6 bits set the ³ ³ ³ ³ ³ ³lower 6 bits of cut-off frequency. ³ ³ ³ ³ ³ ³this has to be done BEFORE setting ³ ³ ³ ³ ³ ³the filter types! ³ ³ ³ ³ ³ ³NOTE: the whole cut-off frequency ³ ³ ³ ³ ³ ³ value is multiplied by 8 - ³ ³ ³ ³ ³ ³ what results in this 15-bit ³ ³ ³ ³ ³ ³ value for cut-off frequency: ³ ³ ³ ³ ³ ³ ÚÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄÂÄ¿ ³ ³ ³ ³ ³ ³ ³UPPER_6_BIT³LOWER_6_BIT³0³0³0³ ³ ³ ³ ³ ³ ³ ÀÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÁÄÙ ³ ³ ³ ³ ³ ³ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ ³ ³ ³ ³ ³ ³NOTE: filtering is not provided / Û ³ ³ ³ ³ ³ ³Û supported in the present ISMÛ ³ ³ ³ ³ ³ ³Û version yet! Û ³ ³ ³ ³ ³ ³ßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßßß ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÁÄÄÄÁÄÄÄÁÂÄÄÄÄÄÄÂÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[F600-F67F,F680-F6FF]ÄÄÄÄÄ $7B ³INS³0=Instrument³0=Load³Instr-³load/save present A-D-S-R-W-F I/sh_I ³ISV³ ³1=Save³ Slot ³values to instrument slot $00-$7F. ³ ³ ³ ³00-7F ³each "DEVICE" has 128 slots. -------Å---Å------------Å------Å------Å---------[F700-F77F,F780-F7FF]----- S ³SMP³1=Sample ³0=Load³Sample³load present sample values or sh_E ³ESM³ ³1=Free³Buffer³free this sample buffer. ³ ³ ³ ³00-7F ³each "DEVICE" has 128 buffers. ³ ³ ³ ³ ³NOTE: sample buffers are ³ ³ ³ ³ ³ "indirect" - they refer to ³ ³ ³ ³ ³ sample slots, see command MSB ÄÄÄÄÄÄÄÅÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄ[F800-FFFF]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $7C-$7F³TRK³Bits 0-10 of the command ³jump to a new "track". sh_T ³ ³make an 11-bit number. ³result address is a 14 bit number, ³ ³This number *8 makes the ³with lower 3 bits=0. ³ ³offset to start a new ³(in fact it is 15 bit, lower 4 bit= ³ ³"track". ³0 - for commands take 2 bytes each) ³ ³ ³NOTE: this command is the only one ³ ³ ³ using ABSOLUTE addresses! ³ ³ ³NOTE: to turn this jump into a call ³ ³ ³ just set the Z:PAD command ³ ³ ³ directly before. ÄÄÄÄÄÄÄÁÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ISM Voice Data Format ~~~~~~~~~~~~~~~~~~~~~ There is a total of 16 voices available in ISM - a "TUNE" (i.e. music) can have 8 (eight) of them at a time. It is possible to have more than these 8 voices per music (with some "external" technical tricks) - but then you won't be able to access all of them from other voices. The data field of a voice contains of 96 bytes. OFFS= offset in voice. SIZE= size of data in bytes (4=DWord, 2=Word, 1=Byte) NAME= internal name of this data. (variables in ISM records are v_NAME) OFFS³SIZE³NAME³FUNCTION/PURPOSE ÄÄÄÄÅÄÄÄÄÅÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 ³ 32 ³IIII³Internal Wave, "Instrument" or Noise Random at 0/1/3 32 ³ 8 ³SSSS³Internal Stack, for a max. of 4 addresses or 8 values. 40 ³ 4 ³DOWN³Duration Countdown (counts down the notes in 1/128 seconds) 44 ³ 4 ³Wave³The Wave Counter, at LowWord (HI/LO-word SWAPPED!) 48 ³ 4 ³ADSR³Amplitude Counter, at HighByte (HI/LO-word SWAPPED!) 52 ³ 4 ³HAdd³Envelope-Adder/Subtractor (HI/LO-word SWAPPED!) 56 ³ 4 ³FAdd³1/Frequency-Slide-Adder (HI/LO-word SWAPPED!) 60 ³ 4 ³WAdd³1/Frequency-Adder (HI/LO-word SWAPPED!) 64 ³ 2 ³WAdL³1/Frequency-Adder - Decimal Part (lowest word of WAdd) 66 ³ 2 ³DPTR³DATA POINTER - Bit0=LOCK. (0=ACTIVE, 1=LOCKED) 68 ³ 2 ³FREQ³Present played Frequency in Hz 70 ³ 2 ³SFrq³Sample-Frequency at 16384Hz (12:4 bit fixpoint, offset+16) 72 ³ 2 ³SSeg³Sample-Segment (segment offset of sample buffer) 74 ³ 2 ³SEnd³Sample-Stop /Endø ;0 (zero) if no/empty sample 76 ³ 2 ³SRep³Sample-Repeatpointø (the sample offset where to repeat) 78 ³ 1 ³SOfs³Sample-Start-Offsetø ($0..$F), Bit4 ($10)=Even(0)/Odd(1)ý 79 ³ 1 ³Samp³Sample-Slot-Nr (actually the real slot, not the buffer) 80 ³ 1 ³Tran³Transpose-value, signed (in halftones, -128..+127) 81 ³ 1 ³SPEE³Speed-Multiplier (the "duration factor", set by ) 82 ³ 1 ³DEVC³VOL.-CONTROL/SET VOLUME (CONTROL and volume, set by ) 83 ³ 1 ³AVOL³PRESENT VOICE VOLUME $0-$F (calculated, only bit 0-3 used) 84 ³ 1 ³PHAS³ADSR-Phase: $0=Mute ³ ³ ³ $2=Attack $4=Decay $6=Sustain $8=Release $A=SoftRelease ³ ³ ³ $C=Sample $E=SampleRelease ³ ³ ³ Additional bits set flags: ³ ³ ³ bit 4 ($10): when synthesizing : 0= waves, 1= noise ³ ³ ³ when using samples: 0= evenü, 1= oddü ³ ³ ³ (depends on bit 7 - see below) ³ ³ ³ bit 5 ($20): 0= no portamento (clean notes) ³ ³ ³ 1= portamento (bending notes) active ³ ³ ³ bit 6 ($40): internally used: =1, if at least one BND ³ ³ ³ command found before next note command. ³ ³ ³ intended to count the bending durations. ³ ³ ³ bit 7 ($80): 0= synthesizing by waves/envelopes ³ ³ ³ 1= using samples ³ ³ ³ NOTE: Bit 0 is not used here and always zero. 85 ³ 1 ³IpAD³Instrument Envelope Attack (bits 4-7) / Decay (bits 0-3) 86 ³ 1 ³IpSR³Instrument Envelope Sustain (bits 4-7) / Release (bits 0-3) 87 ³ 2 ³IWav³Instrument WaveData - up to 4 (four) waves to combine and ³ ³ ³ a set factor for combining: ³ ³ ³ bits: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ³ ³ ³ ÚÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄÂÄÄ¿ ³ ³ ³ ³0 ³ FACTOR ³ WAVE#4 ³ WAVE#3 ³ WAVE#2 ³ WAVE#1 ³ ³ ³ ³ ÀÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÁÄÄÙ ³ ³ ³ WAVE#1, WAVE#2, WAVE#3, WAVE#4 are the wave forms you ³ ³ ³ can combine of 7 different waves (see command WAV). ³ ³ ³ If you use 0 (none), this wave is not used. "leaving ³ ³ ³ out" a wave doesn't make sense. If you set WAVE#1 and ³ ³ ³ WAVE#3 to valid waves (1-7) and WAVE#2 to none (0), ³ ³ ³ then WAVE#3 gets WAVE#2 for the calculator/combiner. ³ ³ ³ this is only important when using a FACTOR other than ³ ³ ³ 0 (zero). ³ ³ ³ The FACTOR sets waves "faster" according to the other ³ ³ ³ ones. There is only one FACTOR value - the waves are ³ ³ ³ set to a "speed" factor depending on their position in ³ ³ ³ this parameter. Here is the speed table when 4 valid ³ ³ ³ waves used: ³ ³ ³ FACTOR WAVE#4 WAVE#3 WAVE#2 WAVE#1 ³ ³ ³ 0 1 1 1 1 ³ ³ ³ 1 1 1 1 2 ³ ³ ³ 2 1 1 2 3 ³ ³ ³ 3 1 1 2 4 ³ ³ ³ 4 1 2 3 5 ³ ³ ³ 5 1 2 3 6 ³ ³ ³ 6 1 2 4 7 ³ ³ ³ 7 1 2 4 8 89 ³ 2 ³IFil³Instrument Filter Data - undefined, no filtering yet 91 ³ 1 ³FiAd³Internal Filter-Adder - intended for using filters 92 ³ 1 ³SPan³Reserved for Stereo/Surround (Stereo-Panning) 93 ³ 1 ³SPTR³STACK POINTER: bit0..2: StackPointer (0..7) ³ ³ ³ bit3 : 1=Use Stack-Automatic for LPX/XNE ³ ³ ³ bit4 : 1=Use Stack-Automatic for LPY/YNE ³ ³ ³ bit5 : 0=Use LoopY as extension for NEW ³ ³ ³ bit6 : 0=Use LoopY as extension for MSB ³ ³ ³ bit7 : "DEVICE" 0/1 (command Z:DEV) 94 ³ 1 ³varX³LoopX. Intended for Loops. Also for calculation commands. 95 ³ 1 ³varY³LoopY. Indended for Loops. Also for setting/resetting. ÄÄÄÄÁÄÄÄÄÁÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ø The samples are at a 20 bit offset to the sample start, theoretically this offset can be $00000 to $9FFFF, what makes theoretically possible to use the whole heap memory below 640 kB for samples. The upper 16 bits of this offset are stored in SSeg (see table above), the lower 4 bits are stored in SOfs (see table above). ý The Sample-Stop/End (SEnd, see table above) is the sample size PLUS the SOfs value, the Sample-RepeatPoint is the Sample-Repeat-Value PLUS the SOfs value (except if this repeat value exceeds the sample size - in this case this value is always $FFFF). ü SOfs contains the "even/odd" bit in its bit 4. Samples are stored 4 bit wide in the sample buffer - with two (simulated) 4 bit wide buffers "side by side". So, there is an "upper-nybble" and "lower-nybble" buffer and both are used "independently" from each other. So, additionally to the 20 bit offset (see above) it is also necessary to store, in which "half" (the lower [even] or the upper [odd]) the sample is located. Additional NOTE to samples and the sample buffer: Samples are stored with a 7-nybble-header: 0 1 2 3 4 5 6 7 ÚÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÂ----------------- ³sb16-19³sb00-03³sb04-07³sb08-11³sb12-15³snrb0-3³snrb4-7³sample data .... ÀÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁ----------------- sb = size bits. starting with the upper 4 bits ($0-$9) (20 bits total). if sb= $A-$F, there is a special use: it declares free buffer 6 to 1 nybbles, starting with the nybble itself. So, a nybble $F means: one (this) free nybble). This is done because a full header needs 7 nybbles, so with less than 7 (free) nybbles a header would be invalid. This is the reason for putting this "most significant nybble" at the top/start of the header. This way a size of up to $9FFFF (640kB-1) is possible - although samples used (yet) by ISM only can have sizes of a maximum of 65520 ($FFF0) bytes. But this buffer is already prepared for possible changes in future. snrb = the number of the sample 8 bit, divided into two nybbles, max $FE. The number $FF is reserved for "free memory". In this case, the size doesn't mean the size of a sample, but of free memory. (For free sizes below 7 nybbles, the start-nybbles $A-$F are used, see above.) ISM Sample File Format ~~~~~~~~~~~~~~~~~~~~~~ An ISM sample is very simple. It contains a 16 byte header, directly followed by the sound data. Offset³Size ³Data ÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ $00 ³dword³ID+Version 'ISM0' ($304D5349 = 810373961 dec.) $04 ³ word³Size of Sample in Bytes (filesize-16) $06 ³ word³Repeat Position (0 for whole sample, $FFFF for no repeat) $08 ³ word³The "hearable" frequency - when this sample is played at ³ ³16384 Hz. This is a fixpoint value (12.4). To get the real ³ ³frequency, divide this by 16, then add 16: freq=value/16+16 ³ ³This allows a frequency range from 16.000 to 4111.875 Hz. $0A ³ byte³Flags to define some values: ³ ³ Bit7 Bit6 Bit5 Bit4 Bit3 Bit2 Bit1 Bit0 ³ ³ ÚÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄÂÄÄÄÄÄÄ¿ ³ ³ ³SIGNED³PACKED³ ODD ³DOUBLE³ 2^X BITS PER VOICE ³STEREO³ ³ ³ ÀÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÁÄÄÄÄÄÄÙ ³ ³ STEREO : If set, two voices are supported at ³ ³ once. Frames are placed alternating ³ ³ then, left and right, starting left. ³ ³ If clear, all frames for a single ³ ³ voice follow one after another. ³ ³ 2^X BITS PER VOICE: valid are: 000,001,010,011,100 ³ ³ (1, 2, 4, 8 and 16 bits per frame). ³ ³ Values 101, 110 and 111 are reserved ³ ³ for future use and not to be used yet. ³ ³ PACKED : If clear, all frames are filled with ³ ³ zero-bits to make full bytes. (That ³ ³ is, for 1-, 2- and 4-bit samples.) ³ ³ If set, frame data will use the whole ³ ³ byte, so a 4-bit-sample will put the ³ ³ frames alternating into the low and ³ ³ high nybbles of bytes. ³ ³ ODD : If set, this indicates the frame data ³ ³ is placed into the upper 2^X bits of ³ ³ the byte. ³ ³ If clear, the lower 2^X bits are used ³ ³ instead. ³ ³ ONLY VALID WITH 1-, 2- AND 4-BIT AND ³ ³ IF PACKED IS CLEAR (0)! ³ ³ DOUBLE : If set, this indicates this sample as ³ ³ a double-sample, so two 4-bit-samples ³ ³ with same lenghts and playfrequency ³ ³ are combined here as one "even" ³ ³ (lower 4 bits) and one "odd" (upper 4 ³ ³ bits) frame. - ONLY VALID WITH 4-BIT! ³ ³ SIGNED : If clear, values will range from ³ ³ 0 (zero) to max (8-bit: 0 to 255, ³ ³ 4-bit: 0 to 15 and so on). The center ³ ³ is max/2 in this case. ³ ³ If set, values will range from -max/2 ³ ³ to +max/2-1 (8-bit: -128 to +127, ³ ³ 4-bit: -8 to +7 and so on). The ³ ³ center is 0 (zero) then. $0B ³ byte³- reserved and yet always 0 (zero) - $0C ³ word³lowest value in all frames (signed, if "SIGNED" flag set) $0E ³ word³highest value in all frames (signed, if "SIGNED" flag set) ÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ NOTE: A sample is stored in sample buffer without its header. The header data ist stored in special external tables (sample buffer). (see above text, commands MSB, SMP, ESM) KEYS TO PERFORM COMMANDS ~~~~~~~~~~~~~~~~~~~~~~~~ KEY = The key to press. (sh_ means: key together with SHIFT.) MNE = The "mnemonic"/command that is shown in "prISM". FUNCTION = Short description of "what the command does". A-? = The 12 (twelve) notes of octave 0 are written this way: C-0 C#0 D-0 D#0 E-0 F-0 F#0 G-0 G#0 A-0 A#0 H-0 Notes of the other octaves are written in similiar way. # means one halftone above the "base note"/"white note". the cipher means the octave (0 to 7), shown as ? sign in the table below. There are NO bar lines, NO Dur/Moll signs and NO bass signs. KEY ³ MNE ³ FUNCTION º KEY ³ MNE ³ FUNCTION ÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÅÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ # ³ ³ º sh_# ³ ³ 0-9³ ³ ºsh_0-9³ ³ - ³ ³ º sh_- ³ ³ + ³ ³ º sh_+ ³ ³ ----Å-----Å------------------------×------Å-----Å------------------------- A ³ A-? ³ note "A" º sh_A ³ A#? ³ note "A#" B ³ BND ³ bend note to next one º sh_B ³ BRL ³ breaking release C ³ C-? ³ note "C" º sh_C ³ C#? ³ note "C#" D ³ D-? ³ note "D" º sh_D ³ D#? ³ note "D#" E ³ E-? ³ note "E" º sh_E ³ ESM ³ empty a sample buffer F ³ F-? ³ note "F" º sh_F ³ F#? ³ note "F#" G ³ G-? ³ note "G" º sh_G ³ G#? ³ note "G#" H ³ H-? ³ note "H" º sh_H ³ HLD ³ hold note/tone I ³ INS ³ load instrument data º sh_I ³ ISV ³ save instrument data J ³ JMP ³ branch +/-256 commands º sh_J ³ JET ³ end encoding voicetrack K ³ KAD ³ set attack/decay value º sh_K ³ KSR ³ set sustain/release val L ³ LPX ³ set LoopX to start val º sh_L ³ LPY ³ set LoopY to start value M ³ MUT ³ absolute mute voice º sh_M ³ MSB ³ move sample to buffer N ³ NOP ³ fill cmd, does nothing º sh_N ³ NEW ³ init voice to address O ³ OUT ³ out value to external º sh_O ³ OTR ³ out register to external P ³ PLY ³ activate voices bitwiseº sh_P ³ PAD ³ push address+1 to stack Q ³ QUV ³ quit voices bitwise º sh_Q ³ QQQ ³ total quit the sound R ³ REL ³ release present note º sh_R ³ RET ³ return from call S ³ SMP ³ activate sample º sh_S ³ SUB ³ call at +/-256 commands T ³ TRN ³ transpose +/- halftonesº sh_T ³ TRK ³ jump to new "track" U ³ USX ³ extern to LoopX, jump º sh_U ³ USY ³ extern to LoopY, jump V ³ VOL ³ set voice ctrl/volume º sh_V ³ VOI ³ initialize voice(s) W ³ WAV ³ set/combine a waveform º sh_W ³ WFI ³ set filter values X ³ XNE ³ LoopX-1, branch if zeroº sh_X ³ XJT ³ jump to addr+offs+LoopX Y ³ YNE ³ LoopY-1, branch if zeroº sh_Y ³ YJT ³ jump to addr+offs+LoopY Z ³ ZOM ³ set speed"zoom" factor º sh_Z ³ ??? ³ complex operation ÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÄÁÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ???: Complex operations (OPCODE $6F, Bit8=1) are displayed as sub-commands with parameters. In prISM, the complex operations ("special commands") are displayed with a leading Z: KEYS TO PERFORM SUB-COMMANDS (complex operations) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To use these sub-commands, the start command (Z:) has to be set at first (by shift+Z). KEY ³ MNE ³ FUNCTION º KEY ³ MNE ³ FUNCTION ÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÅÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ A ³ AND X,³ LoopX=LoopX AND reg. º sh_A ³ ADD X,³ LoopX=LoopX + reg. C ³ CHG ³ change next command º sh_C ³ MCX X,³ move reg. 20..3F -> X D ³ DEC ³ reg.=reg. - 1 º sh_D ³ DIV X,³ LoopX=LoopX / reg. F ³ FSM Y ³ rel.sample start at Yº sh_F ³ FSA YX³ abs.sample start Y:X I ³ INC ³ reg.=reg. + 1 º ³ ³ J ³ CAJ ³ if p#1>p#2, jump->p#3º sh_J ³ CBJ ³ if p#1p#3 M ³ MOV ³ p#1 = p#2 º sh_M ³ MUL X,³ LoopX=LoopX * reg. O ³ OR X,³ LoopX=LoopX OR reg. º ³ ³ P ³ PSH ³ put reg. into stack º sh_P ³ POP ³ take reg. from stack R ³ RND X,³ random value -> LoopXº sh_R ³ MRX X,³ move reg. 40..5F -> X S ³ SWP X,³ exchange LoopX<->reg.º sh_S ³ SUB X,³ LoopX=LoopX - reg. U ³ USW ³ use sample as wave º ³ ³ V ³ DEV ³ set DEVICE 0/1 º ³ ³ W ³ WVF ³ set 4th wave +factor º sh_W ³ MWX X,³ move reg. 00..1F -> X X ³ XOR X,³ LoopX=LoopX XOR reg. º sh_X ³ MVX X,³ LoopX = reg. ÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÐÄÄÄÄÄÄÁÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Note1: X and Y above are meant as the variable registers LoopX / LoopY. Note2: = above means: the register left of the "=" is set to the register or result right of the "=". Note3: "reg." above means the given parameter value - a "register". this can be: X (content of LoopX) Y (content of LoopY) L (content of the lower byte of next command - the "parameter") H (content of the upper byte of next command - the "command") S (content of the next byte content of the stack - this is sometimes available where X as parameter makes no sense) NOTE: this parameter gets the next byte of the stack WITHOUT removing it from stack! p#1,p#2,p#3 (parameters, can be some of the above) 0..7, 0..1F (numeric parameter) Note4: EVERY "complex command" - EXCEPT CHG and POP - don't execute the next command, if at least one of its parameters is L or H! In this case, the L/H parameter is taken as additional parameter. The command CHG is meant to alter the next command and to execute this altered command! Note5: exception to Note4: the command POP always executes the next command - even with parameter L/H. in this case the next command's low/high-byte is altered before executing. _____________________________________________________________________________ (C) 2014-2017 Imperial Games