From f9738eee810a153ced0d71c7c0fdea958431c0dc Mon Sep 17 00:00:00 2001 From: CycoZA Date: Mon, 26 Apr 2021 11:54:16 +0200 Subject: [PATCH] initial commit --- .gitignore | 11 + LICENSE | 339 ++++++++ README.md | 39 + atasm/out.sample_rmt_feat.asm | 44 ++ atasm/out.test_me.asm | 114 +++ atasm/rmtplayr.asm | 1367 +++++++++++++++++++++++++++++++++ bin/rmt2atasm.exe | Bin 0 -> 14848 bytes buildTest1.cmd | 14 + buildTest2.cmd | 14 + rmt2atasm.c | 410 ++++++++++ rmt2atasm.sln | 31 + rmt2atasm.vcxproj | 86 +++ test1/rmt_feat.asm | 44 ++ test1/sample.rmt | Bin 0 -> 689 bytes test1/test1.asm | 114 +++ test2/playit.asm | 71 ++ test2/rmt_feat.asm | 40 + test2/sometune.rmt | Bin 0 -> 749 bytes 18 files changed, 2738 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 atasm/out.sample_rmt_feat.asm create mode 100644 atasm/out.test_me.asm create mode 100644 atasm/rmtplayr.asm create mode 100644 bin/rmt2atasm.exe create mode 100644 buildTest1.cmd create mode 100644 buildTest2.cmd create mode 100644 rmt2atasm.c create mode 100644 rmt2atasm.sln create mode 100644 rmt2atasm.vcxproj create mode 100644 test1/rmt_feat.asm create mode 100644 test1/sample.rmt create mode 100644 test1/test1.asm create mode 100644 test2/playit.asm create mode 100644 test2/rmt_feat.asm create mode 100644 test2/sometune.rmt diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fe32590 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +*.o +*.lbl +*.map +*.xex +.vs +*.user +*.filters +Debug/ +Release/ +!bin/rmt2atasm.exe +tune.asm \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..d159169 --- /dev/null +++ b/LICENSE @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b9dc1cc --- /dev/null +++ b/README.md @@ -0,0 +1,39 @@ +Relocatable RMT player for atasm assembler +========================================== + +Set of samples and code to include Raster-Music-Tracker songs with +programs written in atasm assenbler. + + +How to convert a song to the relocatable source +----------------------------------------------- + +To convert any RMT song to the relocatable format for inclusion in your program, +you need to: + +- Export the song from RMT as a stripped file, select "File", "Export as...", + file type of "RMT stripped song file". + You can select any memory location, other options are according to your + needs. Remember to copy the RMT FEATures presented, and write them to the + file `rmt_feat.asm`, as this file is needed to assemble the player. + Edit the `rmt_feat.asm` file and replace all the `equ` with `=` + +- Use the included C program `rmt2atasm` to convert the RMT file to a relocatable + assembly file, use as: + ``` + rmt2atasm my_song.rmt > tune.asm + ``` + + +Main player and sample song files +--------------------------------- + +The file `atasm/rmtplayr.asm` is the full RMT player source, converted to atasm syntax. + + +Samples +------- + +There are two sample folders (Test1 and Test2) + +Build scripts are provided. diff --git a/atasm/out.sample_rmt_feat.asm b/atasm/out.sample_rmt_feat.asm new file mode 100644 index 0000000..6b53689 --- /dev/null +++ b/atasm/out.sample_rmt_feat.asm @@ -0,0 +1,44 @@ +;* +;* RMT FEATures definitions +;* +;* For optimizations of RMT player routine to concrete RMT modul only! +;* --------BEGIN-------- +;* asm_src/sfx/sfx.rmt +FEAT_SFX = 1 +FEAT_GLOBALVOLUMEFADE = 0 ;RMTGLOBALVOLUMEFADE variable +FEAT_NOSTARTINGSONGLINE = 0 +FEAT_INSTRSPEED = 1 +FEAT_CONSTANTSPEED = 9 ;(0 times) +FEAT_COMMAND1 = 1 ;(96 times) +FEAT_COMMAND2 = 0 ;(0 times) +FEAT_COMMAND3 = 1 ;(1 times) +FEAT_COMMAND4 = 1 ;(1 times) +FEAT_COMMAND5 = 0 ;(0 times) +FEAT_COMMAND6 = 0 ;(0 times) +FEAT_COMMAND7SETNOTE = 1 ;(1 times) +FEAT_COMMAND7VOLUMEONLY = 0 ;(0 times) +FEAT_PORTAMENTO = 0 ;(0 times) +FEAT_FILTER = 0 ;(0 times) +FEAT_FILTERG0L = 0 ;(0 times) +FEAT_FILTERG1L = 0 ;(0 times) +FEAT_FILTERG0R = 0 ;(0 times) +FEAT_FILTERG1R = 0 ;(0 times) +FEAT_BASS16 = 0 ;(0 times) +FEAT_BASS16G1L = 0 ;(0 times) +FEAT_BASS16G3L = 0 ;(0 times) +FEAT_BASS16G1R = 0 ;(0 times) +FEAT_BASS16G3R = 0 ;(0 times) +FEAT_VOLUMEONLYG0L = 0 ;(0 times) +FEAT_VOLUMEONLYG2L = 0 ;(0 times) +FEAT_VOLUMEONLYG3L = 0 ;(0 times) +FEAT_VOLUMEONLYG0R = 0 ;(0 times) +FEAT_VOLUMEONLYG2R = 0 ;(0 times) +FEAT_VOLUMEONLYG3R = 0 ;(0 times) +FEAT_TABLETYPE = 0 ;(0 times) +FEAT_TABLEMODE = 0 ;(0 times) +FEAT_TABLEGO = 0 ;(0 times) +FEAT_AUDCTLMANUALSET = 0 ;(0 times) +FEAT_VOLUMEMIN = 0 ;(0 times) +FEAT_EFFECTVIBRATO = 0 ;(0 times) +FEAT_EFFECTFSHIFT = 0 ;(0 times) +;* --------END-------- diff --git a/atasm/out.test_me.asm b/atasm/out.test_me.asm new file mode 100644 index 0000000..099d95d --- /dev/null +++ b/atasm/out.test_me.asm @@ -0,0 +1,114 @@ +; +; SFX +; example by raster/c.p.u., 2006,2009 +; +; + *=$2000 +STEREOMODE = 0 ;0 => compile RMTplayer for mono 4 tracks +; ;1 => compile RMTplayer for stereo 8 tracks +; ;2 => compile RMTplayer for 4 tracks stereo L1 R2 R3 L4 +; ;3 => compile RMTplayer for 4 tracks stereo L1 L2 R3 R4 +; +; + .include "rmtplayr.asm" ;include RMT player routine +; +; + *=$4000 + .include "../tune.asm" + .local +; +; +MODUL = $4000 ;address of RMT module +KEY = $2fc ;keypressed code +RANDOM = $d20a ;random value +; + * = $6000 +start +; + ldx #text + jsr $c642 ;print info text to screen +; + lda #$f0 ;initial value + sta RMTSFXVOLUME ;sfx note volume * 16 (0,16,32,...,240) +; + lda #$ff ;initial value + sta sfx_effect +; + ldx #MODUL ;hi byte of RMT module to Y reg + lda #2 ;starting song line 0-255 to A reg + jsr RASTERMUSICTRACKER ;Init +; + ldy #vbi + lda #$07 + jsr $e45c ;Start VBI routine +; +; +loop + lda #255 + sta KEY ;no key pressed +; +waitkey + lda KEY ;keycode + cmp #255 + beq waitkey ;no key pressed +; + and #63 + tay + lda (121),y ;keycode -> ascii +; + cmp #$31 ; < key '1' ? + bcc loop + cmp #$39 ; >= key '9' ? + bcs loop + and #$0f ;A=1..8 + pha ;sfx number +; + lda RANDOM ;random number + and #$07 ;0..7 + ora #$08 ;8..15 + asl + asl + asl + asl ;*16 + sta RMTSFXVOLUME +; + pla ;sfx number + sta sfx_effect ;VBI routine is watching this variable +; + jmp loop +; +; +; +vbi +; + lda sfx_effect + bmi lab2 + asl ; * 2 + tay ;Y = 2,4,..,16 instrument number * 2 (0,2,4,..,126) + ldx #3 ;X = 3 channel (0..3 or 0..7 for stereo module) + lda #12 ;A = 12 note (0..60) + jsr RASTERMUSICTRACKER+15 ;RMT_SFX start tone (It works only if FEAT_SFX is enabled !!!) +; + lda #$ff + sta sfx_effect ;reinit value +; +lab2 + jsr RASTERMUSICTRACKER+3 ;1 play +; + jmp $e462 ;end vbi +; +; +; +sfx_effect .byte 0 ;sfx number variable +; +text .byte "Press 1-8 for SFX (random volume)",$9b +; +; +; + *=$2E0 + .word start ;run addr +; +;that's all... :-) \ No newline at end of file diff --git a/atasm/rmtplayr.asm b/atasm/rmtplayr.asm new file mode 100644 index 0000000..71523f5 --- /dev/null +++ b/atasm/rmtplayr.asm @@ -0,0 +1,1367 @@ +;* +;* Raster Music Tracker, RMT Atari routine version 1.20090108 +;* (c) Radek Sterba, Raster/C.P.U., 2002 - 2009 +;* http://raster.atari.org +;* +;* Warnings: +;* +;* 1. RMT player routine needs 19 itself reserved bytes in zero page (no accessed +;* from any other routines) as well as cca 1KB of memory before the "PLAYER" +;* address for fr=ency tables and functionary variables. It's: +;* a) from PLAYER-$03c0 to PLAYER for stereo RMTplayer +;* b) from PLAYER-$0320 to PLAYER for mono RMTplayer +;* +;* 2. RMT player routine MUST (!!!) be compiled from the begin of the memory page. +;* i.e. "PLAYER" address can be $..00 only! +;* +;* 3. Because of RMTplayer provides a lot of effects, it spent a lot of CPU time. +;* +;* STEREOMODE = 0..3 ;0 => compile RMTplayer for 4 tracks mono +;* ;1 => compile RMTplayer for 8 tracks stereo +;* ;2 => compile RMTplayer for 4 tracks stereo L1 R2 R3 L4 +;* ;3 => compile RMTplayer for 4 tracks stereo L1 L2 R3 R4 +;* + .IF STEREOMODE=1 +TRACKS = 8 + .ELSE +TRACKS = 4 + .ENDIF +;* +PLAYER = $3400 +;* +;* RMT FEATures definitions file +;* For optimizations of RMT player routine to concrete RMT modul only! + .include "rmt_feat.asm" +;* +;* RMT ZeroPage addresses + *=$CB +p_tis +p_instrstable = p_tis +p_trackslbstable= p_tis+2 +p_trackshbstable= p_tis+4 +p_song = p_tis+6 +ns = p_tis+8 +nr = p_tis+10 +nt = p_tis+12 +reg1 = p_tis+14 +reg2 = p_tis+15 +reg3 = p_tis+16 +tmp = p_tis+17 + .IF FEAT_COMMAND2 +frqaddcmd2 = p_tis+18 + .ENDIF + + + .IF TRACKS>4 + *= PLAYER-$400+$40 + .ELSE + *= PLAYER-$400+$e0 + .ENDIF +track_variables +trackn_db .ds TRACKS +trackn_hb .ds TRACKS +trackn_idx .ds TRACKS +trackn_pause .ds TRACKS +trackn_note .ds TRACKS +trackn_volume .ds TRACKS +trackn_distor .ds TRACKS +trackn_shiftfrq .ds TRACKS + .IF FEAT_PORTAMENTO +trackn_portafrqc .ds TRACKS +trackn_portafrqa .ds TRACKS +trackn_portaspeed .ds TRACKS +trackn_portaspeeda .ds TRACKS +trackn_portadepth .ds TRACKS + .ENDIF +trackn_instrx2 .ds TRACKS +trackn_instrdb .ds TRACKS +trackn_instrhb .ds TRACKS +trackn_instridx .ds TRACKS +trackn_instrlen .ds TRACKS +trackn_instrlop .ds TRACKS +trackn_instrreachend .ds TRACKS +trackn_volumeslidedepth .ds TRACKS +trackn_volumeslidevalue .ds TRACKS + .IF FEAT_VOLUMEMIN +trackn_volumemin .ds TRACKS + .ENDIF +FEAT_EFFECTS = FEAT_EFFECTVIBRATO .OR FEAT_EFFECTFSHIFT + .IF FEAT_EFFECTS +trackn_effdelay .ds TRACKS + .ENDIF + .IF FEAT_EFFECTVIBRATO +trackn_effvibratoa .ds TRACKS + .ENDIF + .IF FEAT_EFFECTFSHIFT +trackn_effshift .ds TRACKS + .ENDIF +trackn_tabletypespeed .ds TRACKS + .IF FEAT_TABLEMODE +trackn_tablemode .ds TRACKS + .ENDIF +trackn_tablenote .ds TRACKS +trackn_tablea .ds TRACKS +trackn_tableend .ds TRACKS + .IF FEAT_TABLEGO +trackn_tablelop .ds TRACKS + .ENDIF +trackn_tablespeeda .ds TRACKS + .IF FEAT_FILTER .OR FEAT_BASS16 +trackn_command .ds TRACKS + .ENDIF + .IF FEAT_BASS16 +trackn_outnote .ds TRACKS + .ENDIF + .IF FEAT_FILTER +trackn_filter .ds TRACKS + .ENDIF +trackn_audf .ds TRACKS +trackn_audc .ds TRACKS + .IF FEAT_AUDCTLMANUALSET +trackn_audctl .ds TRACKS + .ENDIF +v_aspeed .ds 1 +track_endvariables + + + *= PLAYER-$100-$140-$40+2 +INSTRPAR = 12 +tabbeganddistor + .byte frqtabpure-frqtab,$00 + .byte frqtabpure-frqtab,$20 + .byte frqtabpure-frqtab,$40 + .byte frqtabbass1-frqtab,$c0 + .byte frqtabpure-frqtab,$80 + .byte frqtabpure-frqtab,$a0 + .byte frqtabbass1-frqtab,$c0 + .byte frqtabbass2-frqtab,$c0 + .IF FEAT_EFFECTVIBRATO +vibtabbeg .byte 0,vib1-vib0,vib2-vib0,vib3-vib0 +vib0 .byte 0 +vib1 .byte 1,-1,-1,1 +vib2 .byte 1,0,-1,-1,0,1 +vib3 .byte 1,1,0,-1,-1,-1,-1,0,1,1 +vibtabnext + .byte vib0-vib0+0 + .byte vib1-vib0+1,vib1-vib0+2,vib1-vib0+3,vib1-vib0+0 + .byte vib2-vib0+1,vib2-vib0+2,vib2-vib0+3,vib2-vib0+4,vib2-vib0+5,vib2-vib0+0 + .byte vib3-vib0+1,vib3-vib0+2,vib3-vib0+3,vib3-vib0+4,vib3-vib0+5,vib3-vib0+6,vib3-vib0+7,vib3-vib0+8,vib3-vib0+9,vib3-vib0+0 + .ENDIF + + *= PLAYER-$100-$140 + .IF FEAT_BASS16 +frqtabbasslo + .byte $F2,$33,$96,$E2,$38,$8C,$00,$6A,$E8,$6A,$EF,$80,$08,$AE,$46,$E6 + .byte $95,$41,$F6,$B0,$6E,$30,$F6,$BB,$84,$52,$22,$F4,$C8,$A0,$7A,$55 + .byte $34,$14,$F5,$D8,$BD,$A4,$8D,$77,$60,$4E,$38,$27,$15,$06,$F7,$E8 + .byte $DB,$CF,$C3,$B8,$AC,$A2,$9A,$90,$88,$7F,$78,$70,$6A,$64,$5E,$00 + .ENDIF + + *= PLAYER-$100-$100 +frqtab + .IF 0 + .ERROR "hey frqtab must begin at XX00 address (be aligned to 0x100)" + .ENDIF + ;ERT [255 + ldy #0 + tya +ri0 sta track_variables,y + sta track_endvariables-$100,y + iny + bne ri0 + .ELSE + ldy #track_endvariables-track_variables + lda #0 +ri0 sta track_variables-1,y + dey + bne ri0 + .ENDIF + ldy #4 + lda (ns),y + sta v_maxtracklen + iny + .IF FEAT_CONSTANTSPEED=0 + lda (ns),y + sta v_speed + .ENDIF + .IF FEAT_INSTRSPEED=0 + iny + lda (ns),y + sta v_instrspeed + sta v_ainstrspeed + ELI FEAT_INSTRSPEED>1 + lda #FEAT_INSTRSPEED + sta v_ainstrspeed + .ENDIF + ldy #8 +ri1 lda (ns),y + sta p_tis-8,y + iny + cpy #8+8 + bne ri1 + .IF FEAT_NOSTARTINGSONGLINE=0 + pla + pha + .IF TRACKS>4 + asl + asl + asl + clc + adc p_song + sta p_song + pla + php + and #$e0 + asl + rol + rol + rol + .ELSE + asl + asl + clc + adc p_song + sta p_song + pla + php + and #$c0 + asl + rol + rol + .ENDIF + plp + adc p_song+1 + sta p_song+1 + .ENDIF + jsr GetSongLineTrackLineInitOfNewSetInstrumentsOnlyRmtp3 +rmt_silence + .IF STEREOMODE>0 + lda #0 + sta $d208 + sta $d218 + ldy #3 + sty $d20f + sty $d21f + ldy #8 +si1 sta $d200,y + sta $d210,y + dey + bpl si1 + .ELSE + lda #0 + sta $d208 + ldy #3 + sty $d20f + ldy #8 +si1 sta $d200,y + dey + bpl si1 + .ENDIF + .IF FEAT_INSTRSPEED=0 + lda v_instrspeed + .ELSE + lda #FEAT_INSTRSPEED + .ENDIF + rts +GetSongLineTrackLineInitOfNewSetInstrumentsOnlyRmtp3 +GetSongLine + ldx #0 + stx v_abeat +nn0 +nn1 txa + tay + lda (p_song),y + cmp #$fe + bcs nn2 + tay + lda (p_trackslbstable),y + sta trackn_db,x + lda (p_trackshbstable),y +nn1a sta trackn_hb,x + lda #0 + sta trackn_idx,x + lda #1 +nn1a2 sta trackn_pause,x + lda #$80 + sta trackn_instrx2,x + inx +xtracks01 cpx #TRACKS + bne nn1 + lda p_song + clc +xtracks02 adc #TRACKS + sta p_song + bcc GetTrackLine + inc p_song+1 +nn1b + jmp GetTrackLine +nn2 + beq nn3 +nn2a + lda #0 + beq nn1a2 +nn3 + ldy #2 + lda (p_song),y + tax + iny + lda (p_song),y + sta p_song+1 + stx p_song + ldx #0 + beq nn0 +GetTrackLine +oo0 +oo0a + .IF FEAT_CONSTANTSPEED=0 + lda #$ff +v_speed = *-1 + sta v_bspeed + .ENDIF + ldx #255 +oo1 + inx + dec trackn_pause,x + bne oo1x +oo1b + lda trackn_db,x + sta ns + lda trackn_hb,x + sta ns+1 +oo1i + ldy trackn_idx,x + inc trackn_idx,x + lda (ns),y + sta reg1 + and #$3f + cmp #61 + beq oo1a + bcs oo2 + sta trackn_note,x + .IF FEAT_BASS16 + sta trackn_outnote,x + .ENDIF + iny + lda (ns),y + lsr + and #$3f*2 + sta trackn_instrx2,x +oo1a + lda #1 + sta trackn_pause,x + ldy trackn_idx,x + inc trackn_idx,x + lda (ns),y + lsr + ror reg1 + lsr + ror reg1 + lda reg1 + .IF FEAT_GLOBALVOLUMEFADE + sec + sbc #$00 +RMTGLOBALVOLUMEFADE = *-1 + bcs voig + lda #0 +voig + .ENDIF + and #$f0 + sta trackn_volume,x +oo1x +xtracks03sub1 cpx #TRACKS-1 + bne oo1 + .IF FEAT_CONSTANTSPEED=0 + lda #$ff +v_bspeed = *-1 + sta v_speed + .ELSE + lda #FEAT_CONSTANTSPEED + .ENDIF + sta v_aspeed + jmp InitOfNewSetInstrumentsOnly +oo2 + cmp #63 + beq oo63 + lda reg1 + and #$c0 + beq oo62_b + asl + rol + rol + sta trackn_pause,x + jmp oo1x +oo62_b + iny + lda (ns),y + sta trackn_pause,x + inc trackn_idx,x + jmp oo1x +oo63 + lda reg1 + .IF FEAT_CONSTANTSPEED=0 + bmi oo63_1X + iny + lda (ns),y + sta v_bspeed + inc trackn_idx,x + jmp oo1i +oo63_1X + .ENDIF + cmp #255 + beq oo63_11 + iny + lda (ns),y + sta trackn_idx,x + jmp oo1i +oo63_11 + jmp GetSongLine +p2xrmtp3 jmp rmt_p3 +p2x0 dex + bmi p2xrmtp3 +InitOfNewSetInstrumentsOnly +p2x1 ldy trackn_instrx2,x + bmi p2x0 + .IF FEAT_SFX + jsr SetUpInstrumentY2 + jmp p2x0 +rmt_sfx + sta trackn_note,x + .IF FEAT_BASS16 + sta trackn_outnote,x + .ENDIF + lda #$f0 ;* sfx note volume*16 +RMTSFXVOLUME = *-1 ;* label for sfx note volume parameter overwriting + sta trackn_volume,x + .ENDIF +SetUpInstrumentY2 + lda (p_instrstable),y + sta trackn_instrdb,x + sta nt + iny + lda (p_instrstable),y + sta trackn_instrhb,x + sta nt+1 + .IF FEAT_FILTER + lda #1 + sta trackn_filter,x + .ENDIF + .IF FEAT_TABLEGO + .IF FEAT_FILTER + tay + .ELSE + ldy #1 + .ENDIF + lda (nt),y + sta trackn_tablelop,x + iny + .ELSE + ldy #2 + .ENDIF + lda (nt),y + sta trackn_instrlen,x + iny + lda (nt),y + sta trackn_instrlop,x + iny + lda (nt),y + sta trackn_tabletypespeed,x + .IF FEAT_TABLETYPE .OR FEAT_TABLEMODE + and #$3f + .ENDIF + sta trackn_tablespeeda,x + .IF FEAT_TABLEMODE + lda (nt),y + and #$40 + sta trackn_tablemode,x + .ENDIF + .IF FEAT_AUDCTLMANUALSET + iny + lda (nt),y + sta trackn_audctl,x + iny + .ELSE + ldy #6 + .ENDIF + lda (nt),y + sta trackn_volumeslidedepth,x + .IF FEAT_VOLUMEMIN + iny + lda (nt),y + sta trackn_volumemin,x + .IF FEAT_EFFECTS + iny + .ENDIF + .ELSE + .IF FEAT_EFFECTS + ldy #8 + .ENDIF + .ENDIF + .IF FEAT_EFFECTS + lda (nt),y + sta trackn_effdelay,x + .IF FEAT_EFFECTVIBRATO + iny + lda (nt),y + tay + lda vibtabbeg,y + sta trackn_effvibratoa,x + .ENDIF + .IF FEAT_EFFECTFSHIFT + ldy #10 + lda (nt),y + sta trackn_effshift,x + .ENDIF + .ENDIF + lda #128 + sta trackn_volumeslidevalue,x + sta trackn_instrx2,x + asl + sta trackn_instrreachend,x + sta trackn_shiftfrq,x + tay + lda (nt),y + sta trackn_tableend,x + adc #0 + sta trackn_instridx,x + lda #INSTRPAR + sta trackn_tablea,x + tay + lda (nt),y + sta trackn_tablenote,x +xata_rtshere + .IF FEAT_SFX + rts + .ELSE + jmp p2x0 + .ENDIF +rmt_play +rmt_p0 + jsr SetPokey +rmt_p1 + .IF FEAT_INSTRSPEED=0 .OR FEAT_INSTRSPEED>1 + dec v_ainstrspeed + bne rmt_p3 + .ENDIF + .IF FEAT_INSTRSPEED=0 + lda #$ff +v_instrspeed = *-1 + sta v_ainstrspeed + ELI FEAT_INSTRSPEED>1 + lda #FEAT_INSTRSPEED + sta v_ainstrspeed + .ENDIF +rmt_p2 + dec v_aspeed + bne rmt_p3 + inc v_abeat + lda #$ff +v_abeat = *-1 + cmp #$ff +v_maxtracklen = *-1 + beq p2o3 + jmp GetTrackLine +p2o3 + jmp GetSongLineTrackLineInitOfNewSetInstrumentsOnlyRmtp3 +go_ppnext jmp ppnext +rmt_p3 + lda #>frqtab + sta nr+1 +xtracks05sub1 ldx #TRACKS-1 +pp1 + lda trackn_instrhb,x + beq go_ppnext + sta ns+1 + lda trackn_instrdb,x + sta ns + ldy trackn_instridx,x + lda (ns),y + sta reg1 + iny + lda (ns),y + sta reg2 + iny + lda (ns),y + sta reg3 + iny + tya + cmp trackn_instrlen,x + bcc pp2 + beq pp2 + lda #$80 + sta trackn_instrreachend,x +pp1b + lda trackn_instrlop,x +pp2 sta trackn_instridx,x + lda reg1 + .IF TRACKS>4 + cpx #4 + bcc pp2s + lsr + lsr + lsr + lsr +pp2s + .ENDIF + and #$0f + ora trackn_volume,x + tay + lda volumetab,y + sta tmp + lda reg2 + and #$0e + tay + lda tabbeganddistor,y + sta nr + lda tmp + ora tabbeganddistor+1,y + sta trackn_audc,x +InstrumentsEffects + .IF FEAT_EFFECTS + lda trackn_effdelay,x + beq ei2 + cmp #1 + bne ei1 + lda trackn_shiftfrq,x + .IF FEAT_EFFECTFSHIFT + clc + adc trackn_effshift,x + .ENDIF + .IF FEAT_EFFECTVIBRATO + clc + ldy trackn_effvibratoa,x + adc vib0,y + .ENDIF + sta trackn_shiftfrq,x + .IF FEAT_EFFECTVIBRATO + lda vibtabnext,y + sta trackn_effvibratoa,x + .ENDIF + jmp ei2 +ei1 + dec trackn_effdelay,x +ei2 + .ENDIF + ldy trackn_tableend,x + cpy #INSTRPAR+1 + bcc ei3 + lda trackn_tablespeeda,x + bpl ei2f +ei2c + tya + cmp trackn_tablea,x + bne ei2c2 + .IF FEAT_TABLEGO + lda trackn_tablelop,x + .ELSE + lda #INSTRPAR + .ENDIF + sta trackn_tablea,x + bne ei2a +ei2c2 + inc trackn_tablea,x +ei2a + lda trackn_instrdb,x + sta nt + lda trackn_instrhb,x + sta nt+1 + ldy trackn_tablea,x + lda (nt),y + .IF FEAT_TABLEMODE + ldy trackn_tablemode,x + beq ei2e + clc + adc trackn_tablenote,x +ei2e + .ENDIF + sta trackn_tablenote,x + lda trackn_tabletypespeed,x + .IF FEAT_TABLETYPE .OR FEAT_TABLEMODE + and #$3f + .ENDIF +ei2f + sec + sbc #1 + sta trackn_tablespeeda,x +ei3 + lda trackn_instrreachend,x + bpl ei4 + lda trackn_volume,x + beq ei4 + .IF FEAT_VOLUMEMIN + cmp trackn_volumemin,x + beq ei4 + bcc ei4 + .ENDIF + tay + lda trackn_volumeslidevalue,x + clc + adc trackn_volumeslidedepth,x + sta trackn_volumeslidevalue,x + bcc ei4 + tya + sbc #16 + sta trackn_volume,x +ei4 + .IF FEAT_COMMAND2 + lda #0 + sta frqaddcmd2 + .ENDIF + .IF FEAT_COMMAND1 .OR FEAT_COMMAND2 .OR FEAT_COMMAND3 .OR FEAT_COMMAND4 .OR FEAT_COMMAND5 .OR FEAT_COMMAND6 .OR FEAT_COMMAND7SETNOTE .OR FEAT_COMMAND7VOLUMEONLY + lda reg2 + .IF FEAT_FILTER .OR FEAT_BASS16 + sta trackn_command,x + .ENDIF + and #$70 + .IF 1=[FEAT_COMMAND1+FEAT_COMMAND2+FEAT_COMMAND3+FEAT_COMMAND4+FEAT_COMMAND5+FEAT_COMMAND6+[FEAT_COMMAND7SETNOTE .OR FEAT_COMMAND7VOLUMEONLY]] + beq cmd0 + .ELSE + lsr + lsr + sta jmx+1 +jmx bcc * + jmp cmd0 + nop + jmp cmd1 + .IF FEAT_COMMAND2 .OR FEAT_COMMAND3 .OR FEAT_COMMAND4 .OR FEAT_COMMAND5 .OR FEAT_COMMAND6 .OR FEAT_COMMAND7SETNOTE .OR FEAT_COMMAND7VOLUMEONLY + nop + jmp cmd2 + .ENDIF + .IF FEAT_COMMAND3 .OR FEAT_COMMAND4 .OR FEAT_COMMAND5 .OR FEAT_COMMAND6 .OR FEAT_COMMAND7SETNOTE .OR FEAT_COMMAND7VOLUMEONLY + nop + jmp cmd3 + .ENDIF + .IF FEAT_COMMAND4 .OR FEAT_COMMAND5 .OR FEAT_COMMAND6 .OR FEAT_COMMAND7SETNOTE .OR FEAT_COMMAND7VOLUMEONLY + nop + jmp cmd4 + .ENDIF + .IF FEAT_COMMAND5 .OR FEAT_COMMAND6 .OR FEAT_COMMAND7SETNOTE .OR FEAT_COMMAND7VOLUMEONLY + nop + jmp cmd5 + .ENDIF + .IF FEAT_COMMAND6 .OR FEAT_COMMAND7SETNOTE .OR FEAT_COMMAND7VOLUMEONLY + nop + jmp cmd6 + .ENDIF + .IF FEAT_COMMAND7SETNOTE .OR FEAT_COMMAND7VOLUMEONLY + nop + jmp cmd7 + .ENDIF + .ENDIF + .ELSE + .IF FEAT_FILTER .OR FEAT_BASS16 + lda reg2 + sta trackn_command,x + .ENDIF + .ENDIF +cmd1 + .IF FEAT_COMMAND1 + lda reg3 + jmp cmd0c + .ENDIF +cmd2 + .IF FEAT_COMMAND2 + lda reg3 + sta frqaddcmd2 + lda trackn_note,x + jmp cmd0a + .ENDIF +cmd3 + .IF FEAT_COMMAND3 + lda trackn_note,x + clc + adc reg3 + sta trackn_note,x + jmp cmd0a + .ENDIF +cmd4 + .IF FEAT_COMMAND4 + lda trackn_shiftfrq,x + clc + adc reg3 + sta trackn_shiftfrq,x + lda trackn_note,x + jmp cmd0a + .ENDIF +cmd5 + .IF FEAT_COMMAND5 .AND FEAT_PORTAMENTO + .IF FEAT_TABLETYPE + lda trackn_tabletypespeed,x + bpl cmd5a1 + ldy trackn_note,x + lda (nr),y + clc + adc trackn_tablenote,x + jmp cmd5ax + .ENDIF +cmd5a1 + lda trackn_note,x + clc + adc trackn_tablenote,x + cmp #61 + bcc cmd5a2 + lda #63 +cmd5a2 + tay + lda (nr),y +cmd5ax + sta trackn_portafrqc,x + ldy reg3 + bne cmd5a + sta trackn_portafrqa,x +cmd5a + tya + lsr + lsr + lsr + lsr + sta trackn_portaspeed,x + sta trackn_portaspeeda,x + lda reg3 + and #$0f + sta trackn_portadepth,x + lda trackn_note,x + jmp cmd0a + ELI FEAT_COMMAND5 + lda trackn_note,x + jmp cmd0a + .ENDIF +cmd6 + .IF FEAT_COMMAND6 .AND FEAT_FILTER + lda reg3 + clc + adc trackn_filter,x + sta trackn_filter,x + lda trackn_note,x + jmp cmd0a + ELI FEAT_COMMAND6 + lda trackn_note,x + jmp cmd0a + .ENDIF +cmd7 + .IF FEAT_COMMAND7SETNOTE .OR FEAT_COMMAND7VOLUMEONLY + .IF FEAT_COMMAND7SETNOTE + lda reg3 + .IF FEAT_COMMAND7VOLUMEONLY + cmp #$80 + beq cmd7a + .ENDIF + sta trackn_note,x + jmp cmd0a + .ENDIF + .IF FEAT_COMMAND7VOLUMEONLY +cmd7a + lda trackn_audc,x + ora #$f0 + sta trackn_audc,x + lda trackn_note,x + jmp cmd0a + .ENDIF + .ENDIF +cmd0 + lda trackn_note,x + clc + adc reg3 +cmd0a + .IF FEAT_TABLETYPE + ldy trackn_tabletypespeed,x + bmi cmd0b + .ENDIF + clc + adc trackn_tablenote,x + cmp #61 + bcc cmd0a1 + lda #0 + sta trackn_audc,x + lda #63 +cmd0a1 + .IF FEAT_BASS16 + sta trackn_outnote,x + .ENDIF + tay + lda (nr),y + clc + adc trackn_shiftfrq,x + .IF FEAT_COMMAND2 + clc + adc frqaddcmd2 + .ENDIF + .IF FEAT_TABLETYPE + jmp cmd0c +cmd0b + cmp #61 + bcc cmd0b1 + lda #0 + sta trackn_audc,x + lda #63 +cmd0b1 + tay + lda trackn_shiftfrq,x + clc + adc trackn_tablenote,x + clc + adc (nr),y + .IF FEAT_COMMAND2 + clc + adc frqaddcmd2 + .ENDIF + .ENDIF +cmd0c + sta trackn_audf,x +pp9 + .IF FEAT_PORTAMENTO + lda trackn_portaspeeda,x + beq pp10 + dec trackn_portaspeeda,x + bne pp10 + lda trackn_portaspeed,x + sta trackn_portaspeeda,x + lda trackn_portafrqa,x + cmp trackn_portafrqc,x + beq pp10 + bcs pps1 + adc trackn_portadepth,x + bcs pps8 + cmp trackn_portafrqc,x + bcs pps8 + jmp pps9 +pps1 + sbc trackn_portadepth,x + bcc pps8 + cmp trackn_portafrqc,x + bcs pps9 +pps8 + lda trackn_portafrqc,x +pps9 + sta trackn_portafrqa,x +pp10 + lda reg2 + and #$01 + beq pp11 + lda trackn_portafrqa,x + clc + adc trackn_shiftfrq,x + sta trackn_audf,x +pp11 + .ENDIF +ppnext + dex + bmi rmt_p4 + jmp pp1 +rmt_p4 + .IF FEAT_AUDCTLMANUALSET + lda trackn_audctl+0 + ora trackn_audctl+1 + ora trackn_audctl+2 + ora trackn_audctl+3 + tax + .ELSE + ldx #0 + .ENDIF +qq1 + stx v_audctl + .IF FEAT_FILTER + .IF FEAT_FILTERG0L + lda trackn_command+0 + bpl qq2 + lda trackn_audc+0 + and #$0f + beq qq2 + lda trackn_audf+0 + clc + adc trackn_filter+0 + sta trackn_audf+2 + .IF FEAT_COMMAND7VOLUMEONLY .AND FEAT_VOLUMEONLYG2L + lda trackn_audc+2 + and #$10 + bne qq1a + .ENDIF + lda #0 + sta trackn_audc+2 +qq1a + txa + ora #4 + tax + .ENDIF +qq2 + .IF FEAT_FILTERG1L + lda trackn_command+1 + bpl qq3 + lda trackn_audc+1 + and #$0f + beq qq3 + lda trackn_audf+1 + clc + adc trackn_filter+1 + sta trackn_audf+3 + .IF FEAT_COMMAND7VOLUMEONLY .AND FEAT_VOLUMEONLYG3L + lda trackn_audc+3 + and #$10 + bne qq2a + .ENDIF + lda #0 + sta trackn_audc+3 +qq2a + txa + ora #2 + tax + .ENDIF +qq3 + .IF FEAT_FILTERG0L .OR FEAT_FILTERG1L + cpx v_audctl + bne qq5 + .ENDIF + .ENDIF + .IF FEAT_BASS16 + .IF FEAT_BASS16G1L + lda trackn_command+1 + and #$0e + cmp #6 + bne qq4 + lda trackn_audc+1 + and #$0f + beq qq4 + ldy trackn_outnote+1 + lda frqtabbasslo,y + sta trackn_audf+0 + lda frqtabbasshi,y + sta trackn_audf+1 + .IF FEAT_COMMAND7VOLUMEONLY .AND FEAT_VOLUMEONLYG0L + lda trackn_audc+0 + and #$10 + bne qq3a + .ENDIF + lda #0 + sta trackn_audc+0 +qq3a + txa + ora #$50 + tax + .ENDIF +qq4 + .IF FEAT_BASS16G3L + lda trackn_command+3 + and #$0e + cmp #6 + bne qq5 + lda trackn_audc+3 + and #$0f + beq qq5 + ldy trackn_outnote+3 + lda frqtabbasslo,y + sta trackn_audf+2 + lda frqtabbasshi,y + sta trackn_audf+3 + .IF FEAT_COMMAND7VOLUMEONLY .AND FEAT_VOLUMEONLYG2L + lda trackn_audc+2 + and #$10 + bne qq4a + .ENDIF + lda #0 + sta trackn_audc+2 +qq4a + txa + ora #$28 + tax + .ENDIF + .ENDIF +qq5 + stx v_audctl + .IF TRACKS>4 + .IF FEAT_AUDCTLMANUALSET + lda trackn_audctl+4 + ora trackn_audctl+5 + ora trackn_audctl+6 + ora trackn_audctl+7 + tax + .ELSE + ldx #0 + .ENDIF + stx v_audctl2 + .IF FEAT_FILTER + .IF FEAT_FILTERG0R + lda trackn_command+0+4 + bpl qs2 + lda trackn_audc+0+4 + and #$0f + beq qs2 + lda trackn_audf+0+4 + clc + adc trackn_filter+0+4 + sta trackn_audf+2+4 + .IF FEAT_COMMAND7VOLUMEONLY .AND FEAT_VOLUMEONLYG2R + lda trackn_audc+2+4 + and #$10 + bne qs1a + .ENDIF + lda #0 + sta trackn_audc+2+4 +qs1a + txa + ora #4 + tax + .ENDIF +qs2 + .IF FEAT_FILTERG1R + lda trackn_command+1+4 + bpl qs3 + lda trackn_audc+1+4 + and #$0f + beq qs3 + lda trackn_audf+1+4 + clc + adc trackn_filter+1+4 + sta trackn_audf+3+4 + .IF FEAT_COMMAND7VOLUMEONLY .AND FEAT_VOLUMEONLYG3R + lda trackn_audc+3+4 + and #$10 + bne qs2a + .ENDIF + lda #0 + sta trackn_audc+3+4 +qs2a + txa + ora #2 + tax + .ENDIF +qs3 + .IF FEAT_FILTERG0R .OR FEAT_FILTERG1R + cpx v_audctl2 + bne qs5 + .ENDIF + .ENDIF + .IF FEAT_BASS16 + .IF FEAT_BASS16G1R + lda trackn_command+1+4 + and #$0e + cmp #6 + bne qs4 + lda trackn_audc+1+4 + and #$0f + beq qs4 + ldy trackn_outnote+1+4 + lda frqtabbasslo,y + sta trackn_audf+0+4 + lda frqtabbasshi,y + sta trackn_audf+1+4 + .IF FEAT_COMMAND7VOLUMEONLY .AND FEAT_VOLUMEONLYG0R + lda trackn_audc+0+4 + and #$10 + bne qs3a + .ENDIF + lda #0 + sta trackn_audc+0+4 +qs3a + txa + ora #$50 + tax + .ENDIF +qs4 + .IF FEAT_BASS16G3R + lda trackn_command+3+4 + and #$0e + cmp #6 + bne qs5 + lda trackn_audc+3+4 + and #$0f + beq qs5 + ldy trackn_outnote+3+4 + lda frqtabbasslo,y + sta trackn_audf+2+4 + lda frqtabbasshi,y + sta trackn_audf+3+4 + .IF FEAT_COMMAND7VOLUMEONLY .AND FEAT_VOLUMEONLYG2R + lda trackn_audc+2+4 + and #$10 + bne qs4a + .ENDIF + lda #0 + sta trackn_audc+2+4 +qs4a + txa + ora #$28 + tax + .ENDIF + .ENDIF +qs5 + stx v_audctl2 + .ENDIF +rmt_p5 + .IF FEAT_INSTRSPEED=0 .OR FEAT_INSTRSPEED>1 + lda #$ff +v_ainstrspeed = *-1 + .ELSE + lda #1 + .ENDIF + rts +SetPokey + .IF STEREOMODE=1 ;* L1 L2 L3 L4 R1 R2 R3 R4 + ldy #$ff +v_audctl2 = *-1 + lda trackn_audf+0+4 + ldx trackn_audf+0 +xstastx01 sta $d210 + stx $d200 + lda trackn_audc+0+4 + ldx trackn_audc+0 +xstastx02 sta $d211 + stx $d201 + lda trackn_audf+1+4 + ldx trackn_audf+1 +xstastx03 sta $d212 + stx $d202 + lda trackn_audc+1+4 + ldx trackn_audc+1 +xstastx04 sta $d213 + stx $d203 + lda trackn_audf+2+4 + ldx trackn_audf+2 +xstastx05 sta $d214 + stx $d204 + lda trackn_audc+2+4 + ldx trackn_audc+2 +xstastx06 sta $d215 + stx $d205 + lda trackn_audf+3+4 + ldx trackn_audf+3 +xstastx07 sta $d216 + stx $d206 + lda trackn_audc+3+4 + ldx trackn_audc+3 +xstastx08 sta $d217 + stx $d207 + lda #$ff +v_audctl = *-1 +xstysta01 sty $d218 + sta $d208 + .ENDIF .IF STEREOMODE=0 ;* L1 L2 L3 L4 + ldy #$ff +v_audctl = *-1 + lda trackn_audf+0 + ldx trackn_audc+0 + sta $d200 + stx $d201 + lda trackn_audf+1 + ldx trackn_audc+1 + sta $d200+2 + stx $d201+2 + lda trackn_audf+2 + ldx trackn_audc+2 + sta $d200+4 + stx $d201+4 + lda trackn_audf+3 + ldx trackn_audc+3 + sta $d200+6 + stx $d201+6 + sty $d208 + .ENDIF .IF STEREOMODE=2 ;* L1 R2 R3 L4 + ldy #$ff +v_audctl = *-1 + lda trackn_audf+0 + ldx trackn_audc+0 + sta $d200 + stx $d201 + sta $d210 + lda trackn_audf+1 + ldx trackn_audc+1 + sta $d210+2 + stx $d211+2 + lda trackn_audf+2 + ldx trackn_audc+2 + sta $d210+4 + stx $d211+4 + sta $d200+4 + lda trackn_audf+3 + ldx trackn_audc+3 + sta $d200+6 + stx $d201+6 + sta $d210+6 + sty $d218 + sty $d208 + .ENDIF .IF STEREOMODE=3 ;* L1 L2 R3 R4 + ldy #$ff +v_audctl = *-1 + lda trackn_audf+0 + ldx trackn_audc+0 + sta $d200 + stx $d201 + lda trackn_audf+1 + ldx trackn_audc+1 + sta $d200+2 + stx $d201+2 + lda trackn_audf+2 + ldx trackn_audc+2 + sta $d210+4 + stx $d211+4 + sta $d200+4 + lda trackn_audf+3 + ldx trackn_audc+3 + sta $d210+6 + stx $d211+6 + sta $d200+6 + sty $d218 + sty $d208 + .ENDIF + rts +RMTPLAYEREND diff --git a/bin/rmt2atasm.exe b/bin/rmt2atasm.exe new file mode 100644 index 0000000000000000000000000000000000000000..1ebb41c3942c9a007a39fd5d3aeb0785f0d99440 GIT binary patch literal 14848 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 tune.asm +cd atasm +rmdir /S disk /Q +rmdir /S out /Q +mkdir disk +mkdir out +atasm.exe test1.asm -odisk/test1.xex +dir2atr -E -b PicoBoot406 out/cerebus.atr disk +cd .. +pause \ No newline at end of file diff --git a/buildTest2.cmd b/buildTest2.cmd new file mode 100644 index 0000000..81ac81d --- /dev/null +++ b/buildTest2.cmd @@ -0,0 +1,14 @@ +@echo off +cd test2 + +if exist sometune.asm ( del /Q sometune.asm ) +..\bin\rmt2atasm.exe sometune.rmt > sometune.asm +cd atasm +rmdir /S disk /Q +rmdir /S out /Q +mkdir disk +mkdir out +atasm.exe playit.asm -odisk/playit.xex +dir2atr -E -b PicoBoot406 out/cerebus.atr disk +cd .. +pause \ No newline at end of file diff --git a/rmt2atasm.c b/rmt2atasm.c new file mode 100644 index 0000000..bdcd392 --- /dev/null +++ b/rmt2atasm.c @@ -0,0 +1,410 @@ +/* + * rtm2atasm: convert an Raster Music Tracker file to a relocatable asm file. + * Copyright (C) 2019-2020 Daniel Serpell + * Modified for atasm assembler by Peter Hinz (2021) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see + */ +#define _CRT_SECURE_NO_WARNINGS 1 +#define MIN_RMT_LENGTH 40 + +#include +#include + +static int get_word(FILE* f) +{ + int c1, c2; + if (0 > (c1 = getc(f)) || 0 > (c2 = getc(f))) + return -1; + return (c1 & 0xFF) | ((c2 << 8) & 0xFF00); +} + +static int rword(unsigned char* data, int i) +{ + return data[i] | (data[i + 1] << 8); +} + +static int read_rmt(const char* fname) +{ + int err = -1; + FILE* f = fopen(fname, "rb"); + if (!f) + { + perror(fname); + return err; + } + // Get the header FFFF and the start and end 16bit values + int start, end; + if (get_word(f) < 0 || + (start = get_word(f)) < 0 || + (end = get_word(f)) < 0 || + end < start) + { + fprintf(stderr, "%s: invalid RMT file\n", fname); + goto err_close; + } + int len = end + 1 - start; + if (len < MIN_RMT_LENGTH) { + fprintf(stderr, "RMT file is too short (only %d), need a minimum of %d\n", len, MIN_RMT_LENGTH); + goto err_close; + } + unsigned char* buf = (unsigned char*)malloc(len); + if (!buf) + { + perror(fname); + goto err_close; + } + if (1 != fread(buf, len, 1, f)) + { + fprintf(stderr, "%s: short RMT file\n", fname); + goto err_fbuf; + } + if (buf[0] != 'R' || buf[1] != 'M' || buf[2] != 'T' || + (buf[3] != '4' && buf[3] != '8')) + { + fprintf(stderr, "%s: invalid signature, not an RMT file\n", fname); + goto err_fbuf; + } + // Start generating the assembler code + // Output to the console + + // Header struct + // ============= + // + // offset type desc + // ------ ---- ---- + // 00 DWORD header string 'RMT4' or 'RMT8' + // 04 BYTE track len($ 00 means 256) + // 05 BYTE song speed + // 06 BYTE player freq + // 07 BYTE format version number($ 01 for player routine 1.x compatible format) + // 08 WORD pointer to instrument pointers table + // 0a WORD pointer to track pointers table(lo) + // 0c WORD pointer to track pointers table(hi) + // 0e WORD pointer to tracks list(SONG) + + printf("; RMT%c file converted from %s with rmt2atasm\n" + "; Original size: $%04x bytes @ $%04x\n", buf[3], fname, len, start); + + // Read parameters from file: + int numTracks = buf[3] - '0'; // RMTx - x is 4 or 8 + int offsetInstrumentPtrTable = rword(buf, 8) - start; // This is where the instruments are stored (always directly after this table) + int offsetTrackPtrTableLow = rword(buf, 10) - start; // Track ptrs are broken up into lo and hi bytes + int offsetTrackPtrTableHigh = rword(buf, 12) - start; + int offsetSong = rword(buf, 14) - start; // The song tracks start here + + // The instrument table always starts directly after the header! + if (offsetInstrumentPtrTable != 0x10) + { + fprintf(stderr, "%s: malformed file (instrument table = $%04x)\n", fname, offsetInstrumentPtrTable); + goto err_fbuf; + } + int numInstruments = offsetTrackPtrTableLow - offsetInstrumentPtrTable; + if (numInstruments < 0 || (numInstruments & 1) || offsetTrackPtrTableLow >= len) + { + fprintf(stderr, "%s: malformed file (num instruments = $%04x)\n", fname, numInstruments); + goto err_fbuf; + } + int numtrk = offsetTrackPtrTableHigh - offsetTrackPtrTableLow; + if (numtrk < 0 || numtrk > 0xFF || offsetTrackPtrTableHigh >= len) + { + fprintf(stderr, "%s: malformed file (num tracks = $%04x)\n", fname, numtrk); + goto err_fbuf; + } + + // Read all tracks addresses searching for the lowest address + int first_track = 0xFFFF; + for (int i = 0; i < numtrk; i++) + { + int x = buf[offsetTrackPtrTableLow + i] + (buf[offsetTrackPtrTableHigh + i] << 8); + if (x) + { + x -= start; + if (x < 0 || x >= offsetSong) + { + fprintf(stderr, "%s: malformed file (track %d = $%04x [0:$%x])\n", + fname, i, x, offsetSong); + goto err_fbuf; + } + if (x < first_track) + first_track = x; + } + } + // Read all instrument addresses searching for the lowest address + int first_instr = 0xFFFF; + for (int i = 0; i < numInstruments; i += 2) + { + int x = rword(buf, offsetInstrumentPtrTable + i); + if (x) + { + x -= start; + if (x < 0 || x >= first_track) + { + fprintf(stderr, "%s: malformed file (instrument %d = $%04x [0:$%x])\n", + fname, i, x, first_track); + goto err_fbuf; + } + if (x < first_instr) + first_instr = x; + } + } + + if (first_instr < 0 || first_instr >= len || + first_track < 0 || first_track >= len) + { + fprintf(stderr, "%s: malformed file (first track/instr = $%04x/$%04x)\n", fname, + first_track, first_instr); + if (first_instr = 0xFFFF) + fprintf(stderr, "No instrument data!\n"); + if (first_track) + goto err_fbuf; + } + if (offsetTrackPtrTableHigh + numtrk != first_instr) + { + fprintf(stderr, "%s: malformed file (track/instr = $%04x/$%04x)\n", fname, + offsetTrackPtrTableHigh + numtrk, first_instr); + goto err_fbuf; + } + if (first_track < first_instr) + { + fprintf(stderr, "%s: malformed file (track < instr = $%04x/$%04x)\n", fname, + first_track, first_instr); + goto err_fbuf; + } + + // Write assembly output + printf( + " .local\n" + "RMT_SONG_DATA\n" + "?start\n" + " .byte \"RMT%c\"\n" + , buf[3]); + printf("?song_info\n" + " .byte $%02x ; Track length = %d\n" + " .byte $%02x ; Song speed\n" + " .byte $%02x ; Player Frequency\n" + " .byte $%02x ; Format version\n" + , buf[4], buf[4]// max track length + , buf[5] // song speed + , buf[6] // player frequency + , buf[7] // format version + ); + printf("; ptrs to tables\n"); + printf( + "?ptrInstrumentTbl\n .word ?InstrumentsTable ; start + $%04x\n" + "?ptrTracksTblLo\n .word ?TracksTblLo ; start + $%04x\n" + "?ptrTracksTblHi\n .word ?TracksTblHi ; start + $%04x\n" + "?ptrSong\n .word ?SongData ; start + $%04x\n", + offsetInstrumentPtrTable, offsetTrackPtrTableLow, offsetTrackPtrTableHigh, offsetSong); + + // List of ptrs to instruments + printf("\n; List of ptrs to instruments\n"); + int* instr_pos = (int*)calloc(65536, sizeof(int)); + printf("?InstrumentsTable"); + for (int i = 0; i < numInstruments; i += 2) + { + int loc = rword(buf, i + offsetInstrumentPtrTable) - start; + if (i % 16 == 0) + printf("\n .word "); + else + printf(", "); + if (loc >= first_instr && loc < first_track && loc < len) + { + instr_pos[loc] = (i >> 1) + 1; + printf("?Instrument_%d", i >> 1); + } + else if (loc == -start) + printf(" $0000"); + else + { + fprintf(stderr, "%s: malformed file (instr %d = $%04x [%x:%x])\n", fname, + i, loc, first_instr, first_track); + goto err_finstr; + } + } + printf("\n"); + // List of tracks: + int* track_pos = (int*)calloc(65536, sizeof(int)); + printf("\n" + "?TracksTblLo"); + for (int i = 0; i < numtrk; i++) + { + int loc = buf[i + offsetTrackPtrTableLow] + (buf[i + offsetTrackPtrTableHigh] << 8) - start; + if (i % 8 == 0) + printf("\n .byte "); + else + printf(", "); + if (loc >= first_track && loc < offsetSong && loc < len) + { + track_pos[loc] = i + 1; + printf("= first_track && loc < offsetSong && loc < len) + printf(">?Track_%02x", i); + // printf("(start + $%04x)", loc); + else if (loc == -start) + printf("$0000"); + else + { + fprintf(stderr, "%s: malformed file (track %d = $%04x [%x:%x)\n", fname, + i, loc, first_track, offsetSong); + goto err_ftrack; + } + } + // Print instruments + printf("\n\n; Instrument data"); + for (int i = first_instr, l = 0; i < first_track; i++, l++) + { + if (instr_pos[i]) + { + printf("\n?Instrument_%d", instr_pos[i] - 1); + instr_pos[i] = 0; + l = 0; + } + if (l % 16 == 0) + printf("\n .byte "); + else + printf(", "); + printf("$%02x", buf[i]); + } + for (int i = 0; i < 65536; i++) + { + if (instr_pos[i] != 0) + fprintf(stderr, "%s: missing instrument data for %d at $%04x\n", + fname, instr_pos[i], i); + } + // Print tracks + printf("\n\n; Track data"); + for (int i = first_track, l = 0; i < offsetSong; i++, l++) + { + if (track_pos[i]) + { + printf("\n?Track_%02x", track_pos[i] - 1); + track_pos[i] = 0; + l = 0; + } + if (l % 16 == 0) + printf("\n .byte "); + else + printf(", "); + printf("$%02x", buf[i]); + } + for (int i = 0; i < 65536; i++) + { + if (track_pos[i] != 0) + fprintf(stderr, "%s: missing track data for %d at $%04x\n", + fname, track_pos[i], i); + } + // Print SONG + printf("\n\n; Song data\n?SongData"); + int jmp = 0, l = 0; + for (int i = offsetSong; i < len; i++, l++) + { + if (jmp == -2) + { + jmp = 0x10000 + buf[i]; + continue; + } + else if (jmp > 0) + { + jmp = (0xFFFF & (jmp | (buf[i] << 8))) - start; + if (0 == ((jmp - offsetSong) % numTracks) && jmp >= offsetSong && jmp < len) + { + int lnum = (jmp - offsetSong) / numTracks; + printf(", ?line_%02x", lnum, lnum); + } + else + { + fprintf(stderr, "%s: malformed file (song jump bad $%04x [%x:%x])\n", fname, + jmp, offsetSong, len); + printf(", <($%x+?SongData), >($%x+?SongData)", jmp, jmp); + } + jmp = 0; + // Allows terminating song on last JUMP + if (i + 1 == len && numTracks == 8) + l += 4; + + continue; + } + else if (jmp == -1) + jmp = -2; + + if (l % numTracks == 0) + { + printf("\n?line_%02x: .byte ", l / numTracks); + } + else + printf(", "); + printf("$%02x", buf[i]); + if (buf[i] == 0xfe) + { + if ((l % numTracks) != 0) + fprintf(stderr, "%s: malformed file (misplaced jump)\n", fname); + else + jmp = -1; + } + } + printf("\n"); + if (jmp) + fprintf(stderr, "%s: malformed file (song jump incomplete)\n", fname); + else if (0 != l % numTracks) + fprintf(stderr, "%s: malformed file (song incomplete - %d %d)\n", fname, numTracks, len - offsetSong); + else + err = 0; + +err_ftrack: + free(track_pos); +err_finstr: + free(instr_pos); +err_fbuf: + free(buf); +err_close: + fclose(f); + return err; +} + +int main(int argc, char** argv) +{ + if (argc != 2) + { + fprintf(stderr, "Convert a Raster Music Tracker .RMT file into relocatable ATASM assmbler code.\n"); + fprintf(stderr, "The generated output will be dumpted to the console.\n"); + fprintf(stderr, "Invalid number of arguments.\n\n" + "Usage: %s [file.rmt]\n", argv[0]); + return 1; + } + if (read_rmt(argv[1])) + return 1; + return 0; + +} diff --git a/rmt2atasm.sln b/rmt2atasm.sln new file mode 100644 index 0000000..8eba88b --- /dev/null +++ b/rmt2atasm.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.31205.134 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rmt2atasm", "rmt2atasm.vcxproj", "{2FAEE7CE-8029-4D08-A214-A443C90B33D1}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {2FAEE7CE-8029-4D08-A214-A443C90B33D1}.Debug|x64.ActiveCfg = Debug|Win32 + {2FAEE7CE-8029-4D08-A214-A443C90B33D1}.Debug|x64.Build.0 = Debug|Win32 + {2FAEE7CE-8029-4D08-A214-A443C90B33D1}.Debug|x86.ActiveCfg = Debug|Win32 + {2FAEE7CE-8029-4D08-A214-A443C90B33D1}.Debug|x86.Build.0 = Debug|Win32 + {2FAEE7CE-8029-4D08-A214-A443C90B33D1}.Release|x64.ActiveCfg = Release|x64 + {2FAEE7CE-8029-4D08-A214-A443C90B33D1}.Release|x64.Build.0 = Release|x64 + {2FAEE7CE-8029-4D08-A214-A443C90B33D1}.Release|x86.ActiveCfg = Release|Win32 + {2FAEE7CE-8029-4D08-A214-A443C90B33D1}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6D22E5B4-E3AA-49A6-A913-C314691A28D1} + EndGlobalSection +EndGlobal diff --git a/rmt2atasm.vcxproj b/rmt2atasm.vcxproj new file mode 100644 index 0000000..9327346 --- /dev/null +++ b/rmt2atasm.vcxproj @@ -0,0 +1,86 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + 16.0 + Win32Proj + {2faee7ce-8029-4d08-a214-a443c90b33d1} + rmt2atasm + 10.0 + + + + Application + true + v142 + Unicode + + + Application + false + v142 + true + Unicode + + + + + + + + + + + + + + + true + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + \ No newline at end of file diff --git a/test1/rmt_feat.asm b/test1/rmt_feat.asm new file mode 100644 index 0000000..6b53689 --- /dev/null +++ b/test1/rmt_feat.asm @@ -0,0 +1,44 @@ +;* +;* RMT FEATures definitions +;* +;* For optimizations of RMT player routine to concrete RMT modul only! +;* --------BEGIN-------- +;* asm_src/sfx/sfx.rmt +FEAT_SFX = 1 +FEAT_GLOBALVOLUMEFADE = 0 ;RMTGLOBALVOLUMEFADE variable +FEAT_NOSTARTINGSONGLINE = 0 +FEAT_INSTRSPEED = 1 +FEAT_CONSTANTSPEED = 9 ;(0 times) +FEAT_COMMAND1 = 1 ;(96 times) +FEAT_COMMAND2 = 0 ;(0 times) +FEAT_COMMAND3 = 1 ;(1 times) +FEAT_COMMAND4 = 1 ;(1 times) +FEAT_COMMAND5 = 0 ;(0 times) +FEAT_COMMAND6 = 0 ;(0 times) +FEAT_COMMAND7SETNOTE = 1 ;(1 times) +FEAT_COMMAND7VOLUMEONLY = 0 ;(0 times) +FEAT_PORTAMENTO = 0 ;(0 times) +FEAT_FILTER = 0 ;(0 times) +FEAT_FILTERG0L = 0 ;(0 times) +FEAT_FILTERG1L = 0 ;(0 times) +FEAT_FILTERG0R = 0 ;(0 times) +FEAT_FILTERG1R = 0 ;(0 times) +FEAT_BASS16 = 0 ;(0 times) +FEAT_BASS16G1L = 0 ;(0 times) +FEAT_BASS16G3L = 0 ;(0 times) +FEAT_BASS16G1R = 0 ;(0 times) +FEAT_BASS16G3R = 0 ;(0 times) +FEAT_VOLUMEONLYG0L = 0 ;(0 times) +FEAT_VOLUMEONLYG2L = 0 ;(0 times) +FEAT_VOLUMEONLYG3L = 0 ;(0 times) +FEAT_VOLUMEONLYG0R = 0 ;(0 times) +FEAT_VOLUMEONLYG2R = 0 ;(0 times) +FEAT_VOLUMEONLYG3R = 0 ;(0 times) +FEAT_TABLETYPE = 0 ;(0 times) +FEAT_TABLEMODE = 0 ;(0 times) +FEAT_TABLEGO = 0 ;(0 times) +FEAT_AUDCTLMANUALSET = 0 ;(0 times) +FEAT_VOLUMEMIN = 0 ;(0 times) +FEAT_EFFECTVIBRATO = 0 ;(0 times) +FEAT_EFFECTFSHIFT = 0 ;(0 times) +;* --------END-------- diff --git a/test1/sample.rmt b/test1/sample.rmt new file mode 100644 index 0000000000000000000000000000000000000000..d4f76ee7656a537bc054079c69a3c9c31c362cc8 GIT binary patch literal 689 zcmZ`#F>3-b7|kV!w49LPhL6xe1i?Zpwsvr+k~=z-(t=3cZ?bzAx8p`fyH#8Yg$_4$ z>T-*?h!{jE9q%vPPq;LflWT=GJd(V;m-i)~l!ymT@9zGB9~cJZ6<+02r^Z{{vp?*w`h)E_rdcW>#3h+(ZVu>h5w(G^rMCr z4z)kB44Ll9(85g%BWu5lLskx0Logn(Zp>WCeAUz@8|&g}_jy)a-kh1{k?N|y}O5-}k8R-;e#G9*S vPP`pk?6F)+RIv6cpW1f{3*s%+vLxP)t@c>1B`fVON;MKRb&!E&f?u6)Q*zic literal 0 HcmV?d00001 diff --git a/test1/test1.asm b/test1/test1.asm new file mode 100644 index 0000000..4406e25 --- /dev/null +++ b/test1/test1.asm @@ -0,0 +1,114 @@ +; +; SFX +; example by raster/c.p.u., 2006,2009 +; +; + *=$2000 +STEREOMODE = 0 ;0 => compile RMTplayer for mono 4 tracks +; ;1 => compile RMTplayer for stereo 8 tracks +; ;2 => compile RMTplayer for 4 tracks stereo L1 R2 R3 L4 +; ;3 => compile RMTplayer for 4 tracks stereo L1 L2 R3 R4 +; +; + .include "../atasm/rmtplayr.asm" ;include RMT player routine +; +; + *=$4000 + .include "tune.asm" + .local +; +; +MODUL = $4000 ;address of RMT module +KEY = $2fc ;keypressed code +RANDOM = $d20a ;random value +; + * = $6000 +start +; + ldx #text + jsr $c642 ;print info text to screen +; + lda #$f0 ;initial value + sta RMTSFXVOLUME ;sfx note volume * 16 (0,16,32,...,240) +; + lda #$ff ;initial value + sta sfx_effect +; + ldx #MODUL ;hi byte of RMT module to Y reg + lda #2 ;starting song line 0-255 to A reg + jsr RASTERMUSICTRACKER ;Init +; + ldy #vbi + lda #$07 + jsr $e45c ;Start VBI routine +; +; +loop + lda #255 + sta KEY ;no key pressed +; +waitkey + lda KEY ;keycode + cmp #255 + beq waitkey ;no key pressed +; + and #63 + tay + lda (121),y ;keycode -> ascii +; + cmp #$31 ; < key '1' ? + bcc loop + cmp #$39 ; >= key '9' ? + bcs loop + and #$0f ;A=1..8 + pha ;sfx number +; + lda RANDOM ;random number + and #$07 ;0..7 + ora #$08 ;8..15 + asl + asl + asl + asl ;*16 + sta RMTSFXVOLUME +; + pla ;sfx number + sta sfx_effect ;VBI routine is watching this variable +; + jmp loop +; +; +; +vbi +; + lda sfx_effect + bmi lab2 + asl ; * 2 + tay ;Y = 2,4,..,16 instrument number * 2 (0,2,4,..,126) + ldx #3 ;X = 3 channel (0..3 or 0..7 for stereo module) + lda #12 ;A = 12 note (0..60) + jsr RASTERMUSICTRACKER+15 ;RMT_SFX start tone (It works only if FEAT_SFX is enabled !!!) +; + lda #$ff + sta sfx_effect ;reinit value +; +lab2 + jsr RASTERMUSICTRACKER+3 ;1 play +; + jmp $e462 ;end vbi +; +; +; +sfx_effect .byte 0 ;sfx number variable +; +text .byte "Press 1-8 for SFX (random volume)",$9b +; +; +; + *=$2E0 + .word start ;run addr +; +;that's all... :-) \ No newline at end of file diff --git a/test2/playit.asm b/test2/playit.asm new file mode 100644 index 0000000..d4a08b1 --- /dev/null +++ b/test2/playit.asm @@ -0,0 +1,71 @@ +*=$2000 + STEREOMODE = 0 ;0 => compile RMTplayer for mono 4 tracks +; ;1 => compile RMTplayer for stereo 8 tracks +; ;2 => compile RMTplayer for 4 tracks stereo L1 R2 R3 L4 +; ;3 => compile RMTplayer for 4 tracks stereo L1 L2 R3 R4 +; +; + .include "../atasm/rmtplayr.asm" ;include RMT player routine +; +; + *=$4000 + .include "sometune.asm" + .local +; +; +MODUL = $4000 ;address of RMT module +VCOUNT = $d40b ;vertical screen lines counter address +KEY = $2fc ;keypressed code +VLINE = 16 ;screen line for synchronization +; + * = $3e00 +start +; + ldx #MODUL ;hi byte of RMT module to Y reg + lda #0 ;starting song line 0-255 to A reg + jsr RASTERMUSICTRACKER ;Init +;Init returns instrument speed (1..4 => from 1/screen to 4/screen) + tay + lda tabpp-1,y + sta acpapx2+1 ;sync counter spacing + lda #16+0 + sta acpapx1+1 ;sync counter init +; + lda #255 + sta KEY ;no key pressed +; +loop +acpapx1 lda #$ff ;parameter overwrite (sync line counter value) + clc +acpapx2 adc #$ff ;parameter overwrite (sync line counter spacing) + cmp #156 + bcc lop4 + sbc #156 +lop4 + sta acpapx1+1 +waipap + cmp VCOUNT ;vertical line counter synchro + bne waipap +; + jsr RASTERMUSICTRACKER+3 ;1 play +; + lda KEY ;keyboard + cmp #28 ;ESCape key? + bne loop ;no => loop +; +stopmusic + lda #255 + sta KEY ;no key pressed +; + jsr RASTERMUSICTRACKER+9 ;all sounds off +; + jmp (10) ;DOSVEC => exit to DOS +; +tabpp .byte 156,78,52,39 ;line counter spacing table for instrument speed from 1 to 4 +; +; + *=$2e0 + .word start ;run addr +; +;that's all... ;-) \ No newline at end of file diff --git a/test2/rmt_feat.asm b/test2/rmt_feat.asm new file mode 100644 index 0000000..fdb6449 --- /dev/null +++ b/test2/rmt_feat.asm @@ -0,0 +1,40 @@ +;* --------BEGIN-------- +;* D:\AtariDev\music\sometune.rmt +FEAT_SFX = 0 +FEAT_GLOBALVOLUMEFADE = 0 ;RMTGLOBALVOLUMEFADE variable +FEAT_NOSTARTINGSONGLINE = 0 +FEAT_INSTRSPEED = 1 +FEAT_CONSTANTSPEED = 0 ;(4 times) +FEAT_COMMAND1 = 1 ;(11 times) +FEAT_COMMAND2 = 0 ;(0 times) +FEAT_COMMAND3 = 0 ;(0 times) +FEAT_COMMAND4 = 0 ;(0 times) +FEAT_COMMAND5 = 0 ;(0 times) +FEAT_COMMAND6 = 0 ;(0 times) +FEAT_COMMAND7SETNOTE = 0 ;(0 times) +FEAT_COMMAND7VOLUMEONLY = 0 ;(0 times) +FEAT_PORTAMENTO = 0 ;(0 times) +FEAT_FILTER = 0 ;(0 times) +FEAT_FILTERG0L = 0 ;(0 times) +FEAT_FILTERG1L = 0 ;(0 times) +FEAT_FILTERG0R = 0 ;(0 times) +FEAT_FILTERG1R = 0 ;(0 times) +FEAT_BASS16 = 1 ;(14 times) +FEAT_BASS16G1L = 0 ;(0 times) +FEAT_BASS16G3L = 1 ;(14 times) +FEAT_BASS16G1R = 0 ;(0 times) +FEAT_BASS16G3R = 0 ;(0 times) +FEAT_VOLUMEONLYG0L = 0 ;(0 times) +FEAT_VOLUMEONLYG2L = 0 ;(0 times) +FEAT_VOLUMEONLYG3L = 0 ;(0 times) +FEAT_VOLUMEONLYG0R = 0 ;(0 times) +FEAT_VOLUMEONLYG2R = 0 ;(0 times) +FEAT_VOLUMEONLYG3R = 0 ;(0 times) +FEAT_TABLETYPE = 0 ;(0 times) +FEAT_TABLEMODE = 0 ;(0 times) +FEAT_TABLEGO = 0 ;(0 times) +FEAT_AUDCTLMANUALSET = 0 ;(0 times) +FEAT_VOLUMEMIN = 0 ;(0 times) +FEAT_EFFECTVIBRATO = 0 ;(0 times) +FEAT_EFFECTFSHIFT = 0 ;(0 times) +;* --------END-------- diff --git a/test2/sometune.rmt b/test2/sometune.rmt new file mode 100644 index 0000000000000000000000000000000000000000..8104bc0db538e17f481af17765bdb3678a1f0545 GIT binary patch literal 749 zcma)(y-EW?5XUFxZcmf*=0qVOq>z|E5DOuqmFMQT)umf*E5;%HS%J7zLcn)CcAF(%}KoHOeJM1OQr%QaoH?qwG0})kOxZ)xLuq{6#fUcqkrGv{2BY z+8u3r_=rB`npo*$rHM^!;ef)IP=(62&?9C#>EV+s?$P}bJ*{dRhbY=34Y5scu(U1( Yb?nIDzJDYL1z`$>LWQ}2`S4(W0Qh$A#sB~S literal 0 HcmV?d00001