├── 6502 ├── .gitignore ├── os.asx ├── xexd.asx ├── fp3depk.asx ├── 6502.mk ├── xexb.asx └── xexinfo.asx ├── debian ├── compat ├── asap.install ├── asap-xmms2.install ├── asap-dev.install ├── asap-vlc.install ├── copyright ├── rules ├── control └── changelog ├── xmms2 ├── xmms_configuration.h ├── xmms2.mk └── libxmms_asap.c ├── d ├── .gitignore └── d.mk ├── test ├── .gitignore ├── benchmark │ ├── .gitignore │ ├── Overload.sap │ ├── Lasermania.sap │ ├── Lightness.sap │ ├── Drunk_Chessboard.sap │ ├── Montezumas_Revenge.sap │ ├── International_Karate.sap │ ├── Tempest_2000_Blue_Level.sap │ ├── benchmark.pl │ ├── benchmark.mk │ ├── sap_benchmark.cpp │ └── gme_benchmark.c ├── disasm │ ├── .gitignore │ └── disasm.mk ├── sapd_player_iflag.asx ├── pokey_pure.asx ├── antic_vblki.asx ├── crashsap.cs ├── gtia_consol.asx ├── antic_nmires.asx ├── pokey_irqst.asx ├── antic_vcount.asx ├── RESULTS.xsl ├── antic_nmien.asx ├── test.mk ├── antic_nmist.asx ├── loadsap.cs ├── RESULTS.xml ├── pokey_timerirq.asx ├── formats.asx ├── timevsnative.c ├── pokey_potst.asx ├── cpu_anx.asx ├── cpu_ane.asx ├── cpu_las.asx ├── pokey_pot.asx ├── cpu_decimal.asx ├── pokey_random.asx ├── cpu_shx.asx └── antic_wsync.asx ├── win32 ├── setup │ ├── .gitignore │ ├── asap-banner.jpg │ ├── asap-dialog.jpg │ ├── wix_mutex.pl │ └── license.rtf ├── rmt │ ├── .gitignore │ └── apokeysnd_dll.c ├── shellex │ ├── .gitignore │ └── ASAPShellEx.propdesc ├── bass │ ├── bass.lib │ └── x64 │ │ └── bass.lib ├── .gitignore ├── wasap │ ├── play.ico │ ├── stop.ico │ ├── wasap.ico │ └── wasap.h ├── foobar2000 │ ├── msvc32.bat │ └── msvc64.bat ├── winamp │ ├── ipc_pe.h │ ├── out.h │ └── in2.h ├── diff-sap.js ├── settings_dlg.h ├── info_dlg.h └── xmplay │ └── xmpin.h ├── csharp ├── .gitignore └── csharp.mk ├── javascript ├── .gitignore ├── USAGE ├── javascript.mk └── asapweb.js ├── python ├── .gitignore ├── python.mk └── asap2wav.py ├── opencl ├── .gitignore ├── asap2wav-kernel.cl └── opencl.mk ├── java ├── asap2wav.MF ├── .gitignore ├── android │ ├── img │ │ ├── stereo.jpg │ │ └── POKEY_chip_on_an_Atari_130XE_motherboard.jpg │ ├── res │ │ ├── drawable │ │ │ ├── banner.png │ │ │ ├── ic_menu_browse.png │ │ │ ├── list_selector_focused.xml │ │ │ ├── list_selector.xml │ │ │ ├── ic_notification.xml │ │ │ └── icon.xml │ │ ├── layout │ │ │ ├── shuffle_all_list_item.xml │ │ │ ├── fileinfo_list_item.xml │ │ │ ├── player.xml │ │ │ └── buttons_seekbar.xml │ │ ├── xml │ │ │ └── searchable.xml │ │ ├── menu │ │ │ └── player.xml │ │ ├── values │ │ │ ├── themes.xml │ │ │ └── strings.xml │ │ └── layout-land │ │ │ ├── fileinfo_list_item.xml │ │ │ └── player.xml │ ├── .gitignore │ ├── Util.java │ ├── AndroidManifest.xml │ ├── FileInfo.java │ ├── Indexer.java │ ├── proguard.cfg │ └── ArchiveSuggestionsProvider.java └── java.mk ├── swift ├── .gitignore └── swift.mk ├── release ├── .gitignore └── release.mk ├── .gitignore ├── www ├── .gitignore ├── android.xml ├── index.xml ├── macos.xml ├── www.mk ├── linux.xml ├── web.xml ├── formats.xml ├── windows.xml └── convert.xml ├── xmms ├── libasap-xmms.map └── xmms.mk ├── moc └── moc.mk ├── README ├── aatr-stdio.h ├── vlc └── vlc.mk ├── asap6502.fu ├── astil.h ├── aatr-stdio.c ├── asap.spec ├── PORTS.xsl └── Makefile /debian/compat: -------------------------------------------------------------------------------- 1 | 10 2 | -------------------------------------------------------------------------------- /xmms2/xmms_configuration.h: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /d/.gitignore: -------------------------------------------------------------------------------- 1 | /asap.d 2 | /*.obj 3 | -------------------------------------------------------------------------------- /test/.gitignore: -------------------------------------------------------------------------------- 1 | /*.sap 2 | /*.xex 3 | -------------------------------------------------------------------------------- /win32/setup/.gitignore: -------------------------------------------------------------------------------- 1 | /*.wixobj 2 | -------------------------------------------------------------------------------- /csharp/.gitignore: -------------------------------------------------------------------------------- 1 | /asap.cs 2 | /doc 3 | -------------------------------------------------------------------------------- /debian/asap.install: -------------------------------------------------------------------------------- 1 | usr/bin/asapconv 2 | -------------------------------------------------------------------------------- /javascript/.gitignore: -------------------------------------------------------------------------------- 1 | /asap.js 2 | /asap.mjs 3 | -------------------------------------------------------------------------------- /python/.gitignore: -------------------------------------------------------------------------------- 1 | /asap.py 2 | /__pycache__ 3 | -------------------------------------------------------------------------------- /win32/rmt/.gitignore: -------------------------------------------------------------------------------- 1 | /pokey.c 2 | /pokey.h 3 | -------------------------------------------------------------------------------- /6502/.gitignore: -------------------------------------------------------------------------------- 1 | /*.obx 2 | /*.lst 3 | /xexinfo.xex 4 | -------------------------------------------------------------------------------- /opencl/.gitignore: -------------------------------------------------------------------------------- 1 | /asap.cl 2 | /asap-cl.h 3 | /asapcl 4 | -------------------------------------------------------------------------------- /test/benchmark/.gitignore: -------------------------------------------------------------------------------- 1 | /BENCHMARK.csv 2 | /*.wav 3 | -------------------------------------------------------------------------------- /debian/asap-xmms2.install: -------------------------------------------------------------------------------- 1 | usr/lib/xmms2/libxmms_asap.so 2 | -------------------------------------------------------------------------------- /debian/asap-dev.install: -------------------------------------------------------------------------------- 1 | usr/include/asap.h 2 | usr/lib/libasap.a 3 | -------------------------------------------------------------------------------- /java/asap2wav.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: ASAP2WAV 3 | -------------------------------------------------------------------------------- /swift/.gitignore: -------------------------------------------------------------------------------- 1 | /asap2wav.exp 2 | /asap2wav.lib 3 | /asap.swift 4 | -------------------------------------------------------------------------------- /debian/asap-vlc.install: -------------------------------------------------------------------------------- 1 | usr/lib/*/vlc/plugins/demux/libasap_plugin.so 2 | -------------------------------------------------------------------------------- /win32/shellex/.gitignore: -------------------------------------------------------------------------------- 1 | /asap-infowriter.cpp 2 | /asap-infowriter.hpp 3 | -------------------------------------------------------------------------------- /java/.gitignore: -------------------------------------------------------------------------------- 1 | *.jad 2 | *.jar 3 | classes 4 | /doc 5 | /obx 6 | /src 7 | /xex 8 | -------------------------------------------------------------------------------- /win32/bass/bass.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/win32/bass/bass.lib -------------------------------------------------------------------------------- /win32/.gitignore: -------------------------------------------------------------------------------- 1 | *.lib 2 | *.obj 3 | /foobar2000/foo_asap.res 4 | /signed 5 | /x64 6 | -------------------------------------------------------------------------------- /win32/wasap/play.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/win32/wasap/play.ico -------------------------------------------------------------------------------- /win32/wasap/stop.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/win32/wasap/stop.ico -------------------------------------------------------------------------------- /win32/wasap/wasap.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/win32/wasap/wasap.ico -------------------------------------------------------------------------------- /win32/bass/x64/bass.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/win32/bass/x64/bass.lib -------------------------------------------------------------------------------- /java/android/img/stereo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/java/android/img/stereo.jpg -------------------------------------------------------------------------------- /test/benchmark/Overload.sap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/test/benchmark/Overload.sap -------------------------------------------------------------------------------- /win32/setup/asap-banner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/win32/setup/asap-banner.jpg -------------------------------------------------------------------------------- /win32/setup/asap-dialog.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/win32/setup/asap-dialog.jpg -------------------------------------------------------------------------------- /test/benchmark/Lasermania.sap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/test/benchmark/Lasermania.sap -------------------------------------------------------------------------------- /test/benchmark/Lightness.sap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/test/benchmark/Lightness.sap -------------------------------------------------------------------------------- /test/disasm/.gitignore: -------------------------------------------------------------------------------- 1 | /asap.s 2 | /asap64.s 3 | /asap.html 4 | /asap.jasm 5 | /asap.abc 6 | /asap.dexdump 7 | -------------------------------------------------------------------------------- /java/android/res/drawable/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/java/android/res/drawable/banner.png -------------------------------------------------------------------------------- /release/.gitignore: -------------------------------------------------------------------------------- 1 | /asap-* 2 | /asap*.deb 3 | /foo_asap-*.fb2k-component 4 | /osx 5 | /COPYING.txt 6 | /signed-msi 7 | -------------------------------------------------------------------------------- /test/benchmark/Drunk_Chessboard.sap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/test/benchmark/Drunk_Chessboard.sap -------------------------------------------------------------------------------- /test/benchmark/Montezumas_Revenge.sap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/test/benchmark/Montezumas_Revenge.sap -------------------------------------------------------------------------------- /test/benchmark/International_Karate.sap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/test/benchmark/International_Karate.sap -------------------------------------------------------------------------------- /test/benchmark/Tempest_2000_Blue_Level.sap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/test/benchmark/Tempest_2000_Blue_Level.sap -------------------------------------------------------------------------------- /java/android/res/drawable/ic_menu_browse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/java/android/res/drawable/ic_menu_browse.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.dll 3 | *.exe 4 | *.o 5 | *.so 6 | /aatr.c 7 | /aatr.h 8 | /asap-asapscan.c 9 | /asap-asapscan.h 10 | /MANIFEST 11 | /gmon.out 12 | -------------------------------------------------------------------------------- /java/android/img/POKEY_chip_on_an_Atari_130XE_motherboard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/epi/asap/HEAD/java/android/img/POKEY_chip_on_an_Atari_130XE_motherboard.jpg -------------------------------------------------------------------------------- /win32/foobar2000/msvc32.bat: -------------------------------------------------------------------------------- 1 | @call "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/Tools/VsDevCmd.bat" -no_logo -host_arch=x64 -arch=x86 2 | @%* 3 | -------------------------------------------------------------------------------- /win32/foobar2000/msvc64.bat: -------------------------------------------------------------------------------- 1 | @call "C:/Program Files/Microsoft Visual Studio/2022/Community/Common7/Tools/VsDevCmd.bat" -no_logo -host_arch=x64 -arch=x64 2 | @%* 3 | -------------------------------------------------------------------------------- /www/.gitignore: -------------------------------------------------------------------------------- 1 | /*.cmc 2 | /*.sap 3 | /*.html 4 | /*.jpg 5 | /*.png 6 | /favicon.ico 7 | /PORTS.xml 8 | /PORTS.xsl 9 | /apokeysnd.dll 10 | /asap.js 11 | /asapweb.js 12 | -------------------------------------------------------------------------------- /java/android/res/drawable/list_selector_focused.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /java/android/.gitignore: -------------------------------------------------------------------------------- 1 | /*.apk 2 | /*.class 3 | /classes.dex 4 | /asapconv 5 | /gen 6 | /res/drawable-land 7 | /res/drawable-land-xhdpi 8 | /res/drawable-port 9 | /res/drawable-port-xhdpi 10 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ 2 | Name: asap 3 | Source: http://asap.sourceforge.net 4 | 5 | Files: * 6 | Copyright: 2005-2023 Piotr Fusik 7 | License: GPL-2+ 8 | -------------------------------------------------------------------------------- /java/android/res/drawable/list_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /java/android/res/layout/shuffle_all_list_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /java/android/res/drawable/ic_notification.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /python/python.mk: -------------------------------------------------------------------------------- 1 | # no user-configurable paths below this line 2 | 3 | ifndef DO 4 | $(error Use "Makefile" instead of "python.mk") 5 | endif 6 | 7 | python: python/asap.py 8 | .PHONY: python 9 | 10 | python/asap.py: $(call src,asap.fu asap6502.fu asapinfo.fu cpu6502.fu pokey.fu) $(ASM6502_PLAYERS_OBX) 11 | $(FUT) 12 | CLEAN += python/asap.py 13 | -------------------------------------------------------------------------------- /java/android/res/xml/searchable.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /java/android/res/drawable/icon.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /javascript/USAGE: -------------------------------------------------------------------------------- 1 | How to use command-line JavaScript ASAP2WAV 2 | ------------------------------------------- 3 | 4 | Enter the following command line to see the syntax: 5 | 6 | Node.js: node asap2wav.js 7 | Rhino Shell: java -jar rhino-*.jar asap2wav.js 8 | 9 | Unless you specify the '-o/--output' option, the output filename will be 10 | constructed from the input filename with the extension changed to 'wav'. 11 | -------------------------------------------------------------------------------- /javascript/javascript.mk: -------------------------------------------------------------------------------- 1 | # no user-configurable paths below this line 2 | 3 | ifndef DO 4 | $(error Use "Makefile" instead of "javascript.mk") 5 | endif 6 | 7 | javascript: javascript/asap.mjs 8 | .PHONY: javascript 9 | 10 | javascript/asap.js javascript/asap.mjs: $(call src,asap.fu asap6502.fu asapinfo.fu cpu6502.fu pokey.fu) $(ASM6502_PLAYERS_OBX) 11 | $(FUT) 12 | CLEAN += javascript/asap.js javascript/asap.mjs 13 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | %: 3 | dh $@ 4 | 5 | # skip "make clean" to avoid dependency on xasm, mads and cito 6 | override_dh_auto_clean: 7 | 8 | override_dh_auto_build: 9 | $(MAKE) CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" asapconv lib asap-vlc asap-xmms2 10 | 11 | # skip "make check" to avoid dependency on Acid800 12 | override_dh_auto_test: 13 | 14 | override_dh_auto_install: 15 | $(MAKE) DESTDIR=$$(pwd)/debian/tmp prefix=/usr install install-vlc install-xmms2 16 | -------------------------------------------------------------------------------- /java/android/res/menu/player.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /test/sapd_player_iflag.asx: -------------------------------------------------------------------------------- 1 | opt h- 2 | dta c'SAP',13,10 3 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 4 | dta c'NAME "POKEY Pure Sound Test"',13,10 5 | dta c'DATE "09/06/2011"',13,10 6 | dta c'TYPE D',13,10 7 | dta c'INIT 3000',13,10 8 | dta c'PLAYER 3004',13,10 9 | dta c'TIME 00:05',13,10 10 | opt h+ 11 | 12 | org f:$3000 13 | main 14 | cli 15 | jmp * 16 | player 17 | php 18 | pla 19 | ldx #$30 20 | ldy #$af 21 | and #4 22 | beq izero 23 | ldx #$a0 24 | ldy #$cf 25 | izero 26 | stx ^20 27 | sty ^21 28 | rts 29 | -------------------------------------------------------------------------------- /opencl/asap2wav-kernel.cl: -------------------------------------------------------------------------------- 1 | kernel void asap2wav(constant char *filename, global const uchar *module, int module_len, int song, int duration, global uchar *wav, int wav_len) 2 | { 3 | ASAP asap; 4 | ASAP_Construct(&asap); 5 | if (!ASAP_Load(&asap, filename, module, module_len) 6 | || !ASAP_PlaySong(&asap, song, duration)) { 7 | wav[0] = '\0'; 8 | return; 9 | } 10 | int header_len = ASAP_GetWavHeader(&asap, wav, ASAPSampleFormat_S16_L_E, false); 11 | ASAP_Generate(&asap, wav + header_len, wav_len - header_len, ASAPSampleFormat_S16_L_E); 12 | } 13 | -------------------------------------------------------------------------------- /swift/swift.mk: -------------------------------------------------------------------------------- 1 | SWIFTC = $(DO)swiftc -no-color-diagnostics 2 | 3 | # no user-configurable paths below this line 4 | 5 | ifndef DO 6 | $(error Use "Makefile" instead of "swift.mk") 7 | endif 8 | 9 | swift: swift/asap2wav.exe 10 | .PHONY: swift 11 | 12 | swift/asap2wav.exe: swift/main.swift swift/asap.swift 13 | $(SWIFTC) -O -o $@ $^ 14 | CLEAN += swift/asap2wav.exe swift/asap2wav.exp swift/asap2wav.lib 15 | 16 | swift/asap.swift: $(call src,asap.fu asap6502.fu asapinfo.fu cpu6502.fu pokey.fu) $(ASM6502_PLAYERS_OBX) 17 | $(FUT) 18 | CLEAN += swift/asap.swift 19 | -------------------------------------------------------------------------------- /win32/setup/wix_mutex.pl: -------------------------------------------------------------------------------- 1 | # Generate mutual exclusion conditions 2 | use strict; 3 | my @c = qw(wasap.ext in_asap.ext foo_asap.ext xmp_asap.ext aimp_asap.ext libasap_plugin.ext); 4 | my @a = map "\$$_=3 OR (\$$_=-1 AND ?$_=3)", @c; # action is install or (action is nothing and already installed) 5 | my $i = 0; 6 | for my $a (@a[0 .. $#a - 1]) { 7 | my @b = @a[++$i .. $#a]; 8 | while (@b) { 9 | $_ = "(($a) AND (" . shift @b; 10 | while (@b) { 11 | my $t = "$_ OR $b[0]"; 12 | last if length($t) > 198; 13 | $_ = $t; 14 | shift @b; 15 | } 16 | print "$_));\n"; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /java/android/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /xmms/libasap-xmms.map: -------------------------------------------------------------------------------- 1 | # This linker script defines symbols that should be exported 2 | # from the shared library. 3 | # Without this script, all global symbols are exported, which: 4 | # - makes the library about 4K bigger 5 | # - makes the symbols accessible from the outside 6 | # - can lead to symbol collisions with different libraries 7 | # (I am not sure whether this problem actually exists) 8 | # It should be noted that the shared library can be generated 9 | # without this script, so you can omit it if your linker does not 10 | # understand it. 11 | { 12 | global: get_iplugin_info; 13 | local: *; 14 | }; 15 | -------------------------------------------------------------------------------- /moc/moc.mk: -------------------------------------------------------------------------------- 1 | MOC_INCLUDE = ../moc-2.5.0 2 | MOC_PLUGIN_DIR = /usr/local/lib/moc/decoder_plugins 3 | 4 | # no user-configurable paths below this line 5 | 6 | ifndef DO 7 | $(error Use "Makefile" instead of "moc.mk") 8 | endif 9 | 10 | asap-moc: libasap_decoder.so 11 | .PHONY: asap-moc 12 | 13 | libasap_decoder.so: $(call src,moc/libasap_decoder.c asap.[ch]) 14 | $(DO_CC) -I$(MOC_INCLUDE) 15 | CLEAN += libasap_decoder.so 16 | 17 | install-moc: libasap_decoder.so 18 | $(call INSTALL_PROGRAM,libasap_decoder.so,$(MOC_PLUGIN_DIR)) 19 | .PHONY: install-moc 20 | 21 | uninstall-moc: 22 | $(RM) $(DESTDIR)$(MOC_PLUGIN_DIR)/libasap_decoder.so 23 | .PHONY: uninstall-moc 24 | -------------------------------------------------------------------------------- /d/d.mk: -------------------------------------------------------------------------------- 1 | DC = $(DO)dmd -release -inline -O $(if $(WINDIR),-of$(subst /,\\,$@) $(subst /,\\,$^),-of$@ $^) 2 | 3 | # no user-configurable paths below this line 4 | 5 | ifndef DO 6 | $(error Use "Makefile" instead of "d.mk") 7 | endif 8 | 9 | d: d/asap2wav.exe # d/asapplay.exe 10 | .PHONY: d 11 | 12 | d/asap2wav.exe: $(srcdir)d/asap2wav.d d/asap.d 13 | $(DC) 14 | CLEAN += d/asap2wav.exe d/asap2wav.obj 15 | 16 | # d/asapplay.exe: $(call src,d/asapplay.d d/waveout.d d/alsa/pcm.d) d/asap.d 17 | # $(DC) 18 | # CLEAN += d/asapplay.exe d/asapplay.obj 19 | 20 | d/asap.d: $(call src,asap.fu asap6502.fu asapinfo.fu cpu6502.fu pokey.fu) $(ASM6502_PLAYERS_OBX) 21 | $(FUT) 22 | CLEAN += d/asap.d 23 | -------------------------------------------------------------------------------- /opencl/opencl.mk: -------------------------------------------------------------------------------- 1 | CXX = g++ 2 | CXXFLAGS = -O2 -Wall 3 | 4 | # no user-configurable paths below this line 5 | 6 | ifndef DO 7 | $(error Use "Makefile" instead of "opencl.mk") 8 | endif 9 | 10 | opencl: opencl/asapcl 11 | .PHONY: opencl 12 | 13 | opencl/asapcl: opencl/asapcl.cpp opencl/asap-cl.h asap.o asap.h 14 | $(DO)$(CXX) $(CXXFLAGS) -o $@ $(INCLUDEOPTS) $< asap.o -lOpenCL 15 | 16 | opencl/asap-cl.h: opencl/asap.cl opencl/asap2wav-kernel.cl 17 | $(DO)(echo 'R"CLC(' && cat $^ && echo ')CLC"') >$@ 18 | CLEAN += opencl/asap-cl.h 19 | 20 | opencl/asap.cl: $(call src,asap.fu asap6502.fu asapinfo.fu cpu6502.fu pokey.fu) $(ASM6502_PLAYERS_OBX) 21 | $(FUT) -D OPENCL 22 | CLEAN += opencl/asap.cl 23 | -------------------------------------------------------------------------------- /test/pokey_pure.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "POKEY Pure Sound Test"',13,10 6 | dta c'DATE "03/06/2011"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 00:08',13,10 10 | opt h+ 11 | eif 12 | 13 | org f:$3000 14 | main 15 | :!SAP sei:inc ^4e 16 | mva #3 ^2f 17 | mva #0 ^28 18 | 19 | mva #$af ^21 20 | test_start 21 | lda #255 22 | test_loop 23 | sta ^20 24 | ldx <-15556 25 | ldy >-15556 26 | wait_loop 27 | sta ^4a 28 | inx 29 | bne wait_loop 30 | iny 31 | bne wait_loop 32 | tax 33 | beq test_start 34 | lsr @ 35 | jmp test_loop 36 | 37 | ift !SAP 38 | run main 39 | eif 40 | -------------------------------------------------------------------------------- /6502/os.asx: -------------------------------------------------------------------------------- 1 | org $c000 2 | nmi 3 | bit $d40f 4 | bpl nmi_vbl 5 | jmp ($200) 6 | nmi_vbl 7 | cld 8 | pha 9 | txa:pha 10 | tya:pha 11 | sta $d40f 12 | jmp ($222) 13 | 14 | vbl 15 | inc 20 16 | bne vbl_1 17 | inc 19 18 | bne vbl_1 19 | inc 18 20 | vbl_1 21 | jmp ($224) 22 | 23 | vbld 24 | pla:tay 25 | pla:tax 26 | pla:rti 27 | 28 | irq 29 | cld 30 | jmp ($216) 31 | 32 | setvbv 33 | asl @ 34 | sta $22d 35 | txa 36 | ldx #5 37 | sta $d40a 38 | dex:rne 39 | ldx $22d 40 | sta $217,x 41 | tya:sta $216,x 42 | rts 43 | 44 | reset 45 | mwa #vbl $222 46 | mwa #vbld $224 47 | rts 48 | 49 | org $e45c 50 | jmp setvbv 51 | jmp vbl 52 | jmp vbld 53 | 54 | org $fffa 55 | dta a(nmi,reset,irq) 56 | -------------------------------------------------------------------------------- /xmms2/xmms2.mk: -------------------------------------------------------------------------------- 1 | XMMS2_CFLAGS = `pkg-config --cflags xmms2-plugin glib-2.0` 2 | XMMS2_PLUGIN_DIR = `pkg-config --variable=libdir xmms2-plugin`/xmms2 3 | 4 | # no user-configurable paths below this line 5 | 6 | ifndef DO 7 | $(error Use "Makefile" instead of "xmms2.mk") 8 | endif 9 | 10 | asap-xmms2: libxmms_asap.so 11 | .PHONY: asap-xmms2 12 | 13 | libxmms_asap.so: $(call src,xmms2/libxmms_asap.c xmms2/xmms_configuration.h asap.[ch]) 14 | $(DO_CC) $(XMMS2_CFLAGS) 15 | CLEAN += libxmms_asap.so 16 | 17 | install-xmms2: libxmms_asap.so 18 | $(call INSTALL_PROGRAM,libxmms_asap.so,$(XMMS2_PLUGIN_DIR)) 19 | .PHONY: install-xmms2 20 | 21 | uninstall-xmms2: 22 | $(RM) $(DESTDIR)$(XMMS2_PLUGIN_DIR)/libxmms_asap.so 23 | .PHONY: uninstall-xmms2 24 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | ASAP - Another Slight Atari Player 2 | ================================== 3 | 4 | ASAP is a player of Atari 8-bit chiptunes for modern computers and mobile 5 | devices. It emulates the POKEY sound chip and the 6502 processor. 6 | 7 | ASAP supports the following file formats: SAP, CMC, CM3, CMR, CMS, DMC, DLT, 8 | FC, MPT, MPD, RMT, TMC/TM8, TM2, STIL and is available on Android, Windows, 9 | macOS, Linux and modern web browsers. 10 | 11 | ASAP is free software; you can redistribute it and/or modify it 12 | under the terms of the GNU General Public License as published 13 | by the Free Software Foundation; either version 2 of the License, 14 | or (at your option) any later version. 15 | 16 | See the INSTALL file for build instructions. 17 | 18 | For more information, visit the website: https://asap.sourceforge.net/ 19 | -------------------------------------------------------------------------------- /test/benchmark/benchmark.pl: -------------------------------------------------------------------------------- 1 | use Time::HiRes qw(time); 2 | use strict; 3 | 4 | print q{File ,MSVC ,MinGW,MGx64,Java ,C# ,GME ,SAP 5 | }; 6 | my @progs = ( 7 | 'win32/msvc/asapconv.exe -o .wav', 8 | 'win32/asapconv.exe -o .wav', 9 | 'win32/x64/asapconv.exe -o .wav', 10 | 'java -jar java/asap2wav.jar', 11 | 'csharp/asap2wav.exe', 12 | 'test/benchmark/gme_benchmark.exe', 13 | 'test/benchmark/sap_benchmark.exe' 14 | ); 15 | for my $file (glob 'test/benchmark/*.sap') { 16 | printf '%30s', $file =~ m{([^/]+)$}; 17 | prog: for my $prog (@progs) { 18 | my @cmd = (split(/ /, $prog), $file); 19 | my $time = time; 20 | my $COUNT = 5; 21 | print STDERR "@cmd\n"; 22 | for my $i (1 .. $COUNT) { 23 | unless (system(@cmd) == 0) { 24 | print ',ERROR'; 25 | next prog; 26 | } 27 | } 28 | $time = (time() - $time) / $COUNT; 29 | printf ',%5.2f', $time; 30 | } 31 | print "\n"; 32 | } 33 | -------------------------------------------------------------------------------- /6502/xexd.asx: -------------------------------------------------------------------------------- 1 | HIDE_AUTHOR equ 0 2 | ift HIDE_AUTHOR 3 | countdown equ $fca7 4 | els 5 | countdown equ $fc98 6 | eif 7 | 8 | org $124 9 | main 10 | sei 11 | mvy #0 ^4e 12 | lda:rne ^4b 13 | sta ^40 14 | ldx #29 15 | sta:rpl ^00,x- 16 | ert *!=$13a 17 | sta ^2e 18 | ldx #8 19 | init_pokey_1 20 | sta $d210,x 21 | sta $d200,x 22 | dex:bpl init_pokey_1 23 | lda #3 24 | sta $d21f 25 | sta $d200 26 | 27 | ; TODO: support 400/800/600XL 28 | mva #$fe ^31 29 | lda player 30 | cmp #{rts} 31 | beq no_player 32 | mwa #nmi $fffa 33 | mva #$40 ^4e 34 | no_player 35 | lda song 36 | cli 37 | jmp init 38 | 39 | nmi 40 | plp:php ; unblock IRQ if NMI blocked it 41 | pha 42 | txa:pha 43 | tya:pha 44 | jsr player 45 | ldx $135 46 | beq no_info 47 | ldx $d014 48 | dex 49 | seq:ldx #1 50 | jsr countdown 51 | no_info 52 | pla:tay 53 | pla:tax 54 | pla:rti 55 | 56 | init dta {jmp 0} 57 | opt o- 58 | dta a(0) 59 | player jmp 0 60 | song dta 0 61 | 62 | end 63 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: asap 2 | Maintainer: Piotr Fusik 3 | Section: contrib/sound 4 | Priority: optional 5 | Standards-Version: 4.6.0 6 | Build-Depends: debhelper (>= 7), libvlccore-dev, xmms2-dev 7 | 8 | Package: asap 9 | Architecture: any 10 | Depends: ${shlibs:Depends} 11 | Description: Provides "asapconv" command-line converter of Atari 8-bit music 12 | to WAV files. Supports the following file formats: 13 | SAP, CMC, CM3, CMR, CMS, DMC, DLT, MPT, MPD, RMT, TMC, TM8, TM2, FC. 14 | 15 | Package: asap-dev 16 | Architecture: any 17 | Description: Development library providing Atari 8-bit music emulation. 18 | 19 | Package: asap-vlc 20 | Architecture: any 21 | Depends: vlc, ${shlibs:Depends} 22 | Description: Provides playback of Atari 8-bit music in VLC. 23 | Supports the following file formats: SAP, RMT, FC. 24 | 25 | Package: asap-xmms2 26 | Architecture: any 27 | Depends: xmms2, ${shlibs:Depends} 28 | Description: Provides playback of Atari 8-bit music (SAP format) in XMMS2. 29 | -------------------------------------------------------------------------------- /6502/fp3depk.asx: -------------------------------------------------------------------------------- 1 | outerFlags equ $fc 2 | innerFlags equ $fd 3 | outPtr equ $fe 4 | 5 | org $8000 6 | getByte 7 | lda $aaaa 8 | inw getByte+1 9 | rts 10 | exit 11 | jmp $aaaa 12 | copyTwoOrThree 13 | sta outPtr 14 | txa ; lda #1 15 | rol @ 16 | copyMany 17 | tax 18 | beq exit 19 | copy 20 | lda (outPtr),y 21 | putByte 22 | sta $8080,y 23 | iny 24 | bne samePage 25 | tya ; lda #0 26 | sec 27 | adc outPtr+1 28 | setPage 29 | sta outPtr+1 30 | sta putByte+2 31 | samePage 32 | dex 33 | bne copy 34 | 35 | asl innerFlags 36 | bne gotInnerFlags 37 | asl outerFlags 38 | bne gotOuterFlags 39 | 40 | start 41 | sec 42 | jsr getByte 43 | rol @ 44 | sta outerFlags 45 | gotOuterFlags 46 | lda #1 47 | bcc setInnerFlags 48 | jsr getByte 49 | rol @ 50 | setInnerFlags 51 | sta innerFlags 52 | gotInnerFlags 53 | jsr getByte 54 | ldx #1 55 | bcc putByte 56 | lsr @ 57 | bne copyTwoOrThree 58 | jsr getByte 59 | bcs copyMany 60 | tay 61 | jsr getByte 62 | bcc setPage ; jmp 63 | 64 | end 65 | -------------------------------------------------------------------------------- /test/disasm/disasm.mk: -------------------------------------------------------------------------------- 1 | disasm: $(addprefix test/disasm/,asap.s asap64.s asap.html asap.jasm) 2 | .PHONY: disasm 3 | 4 | test/disasm/asap.s: $(call src,asap.[ch]) 5 | $(WIN32_CC) -S 6 | CLEAN += test/disasm/asap.s 7 | 8 | test/disasm/asap64.s: $(call src,asap.[ch]) 9 | $(WIN64_CC) -S 10 | CLEAN += test/disasm/asap64.s 11 | 12 | test/disasm/asap.html: csharp/asap2wav.exe 13 | -$(DO)"c:/Program Files (x86)/Microsoft SDKs/Windows/v7.0A/Bin/ildasm.exe" /output=$@ /html /nobar /source $< 14 | CLEAN += test/disasm/asap.html 15 | 16 | test/disasm/asap.jasm: java/classes/net/sf/asap 17 | $(DO)javap -c -private -classpath java/classes net.sf.asap.ASAP net.sf.asap.ASAPInfo net.sf.asap.Cpu6502 net.sf.asap.Pokey net.sf.asap.PokeyPair > $@ 18 | CLEAN += test/disasm/asap.jasm 19 | 20 | test/disasm/asap.dexdump: java/android/classes/net/sf/asap/Player.class 21 | $(DO)java -jar "c:/bin/android-sdk-windows/platforms/android-8//tools/lib/dx.jar" --dex --dump-to=$@ java/android/classes/ 22 | CLEAN += test/disasm/asap.dexdump 23 | -------------------------------------------------------------------------------- /www/android.xml: -------------------------------------------------------------------------------- 1 | 2 | Android application 3 |

Android application

4 |

To install, download and open . 5 | It's compatible with Android 5.0 and newer.

6 |

The application has the ASMA archive bundled. 7 | On start it shows the whole archive contents. Tap "shuffle all" or the search button. 8 | The navigation will be improved in future releases!

9 |

Use the open button to play files from your device.

10 |

Playback can be controlled from the notification, the lock screen 11 | or via voice assistant commands such as "pause playback", "next song", "seek to one minute". 12 | There is no voice search yet.

13 |

You can also view metadata and control playback via Bluetooth, for example a car audio system.

14 | Car audio 15 |
16 | 17 | -------------------------------------------------------------------------------- /test/antic_vblki.asx: -------------------------------------------------------------------------------- 1 | scrptr equ $8a ; 2 bytes 2 | printptr equ $8c ; 2 bytes 3 | 4 | org $3000 5 | main 6 | lda title 8 | jsr print 9 | 10 | lda #100 11 | cmp:rne ^4b 12 | mwa #nmi $fffa 13 | mva #$40 ^4e 14 | 15 | ldx #0 16 | lda #123 17 | cmp:rne ^4b 18 | lda 20 19 | :3 sta ^4a 20 | cmp 20,x 21 | bne error 22 | 23 | lda #123 24 | cmp:rne ^4b 25 | lda 20 26 | :3 sta ^4a 27 | nop 28 | cmp 20 29 | beq error 30 | 31 | lda <pass 32 | ldx >pass 33 | jsr print 34 | mwa #$af30 $d200 35 | jmp * 36 | 37 | error 38 | lda <fail 39 | ldx >fail 40 | jsr print 41 | mwa #$cfa0 $d200 42 | jmp * 43 | 44 | put_char 45 | mvx #11 $342 46 | mwx #0 $348 47 | rts ;FIXME jmp $e456 48 | 49 | print 50 | sta printptr 51 | stx printptr+1 52 | jmp print_2 53 | print_1 54 | jsr put_char 55 | inw printptr 56 | print_2 57 | lda (printptr),0 58 | bne print_1 59 | rts 60 | 61 | nmi 62 | inc 20 63 | rti 64 | 65 | title dta c'ANTIC: VBLKI...',0 66 | pass dta c'Pass',$9b,0 67 | fail dta c'FAIL.',$9b,0 68 | 69 | run main 70 | -------------------------------------------------------------------------------- /win32/shellex/ASAPShellEx.propdesc: -------------------------------------------------------------------------------- 1 | <schema xmlns="http://schemas.microsoft.com/windows/2006/propertydescription" schemaVersion="1.0"> 2 | <propertyDescriptionList publisher="Piotr Fusik" product="ASAP"> 3 | <propertyDescription name="ASAP.Subsongs" formatID="{5AE26367-B5CF-444D-B163-2CBC99B41287}" propID="1"> 4 | <description>Number of songs in the file.</description> 5 | <typeInfo type="UInt32" isViewable="true" /> 6 | <labelInfo label="Subsongs" /> 7 | </propertyDescription> 8 | <propertyDescription name="ASAP.PALNTSC" formatID="{5AE26367-B5CF-444D-B163-2CBC99B41287}" propID="2"> 9 | <description>PAL/NTSC system.</description> 10 | <typeInfo type="String" isViewable="true" /> 11 | <labelInfo label="PAL/NTSC" /> 12 | <displayInfo displayType="Enumerated"> 13 | <editControl control="DropList"/> 14 | <enumeratedList> 15 | <enum value="PAL" text="PAL" /> 16 | <enum value="NTSC" text="NTSC" /> 17 | </enumeratedList> 18 | </displayInfo> 19 | </propertyDescription> 20 | </propertyDescriptionList> 21 | </schema> 22 | -------------------------------------------------------------------------------- /xmms/xmms.mk: -------------------------------------------------------------------------------- 1 | XMMS_CFLAGS = `xmms-config --cflags` 2 | XMMS_LIBS = `xmms-config --libs` 3 | XMMS_INPUT_PLUGIN_DIR = `xmms-config --input-plugin-dir` 4 | XMMS_USER_PLUGIN_DIR = $(HOME)/.xmms/Plugins 5 | 6 | # no user-configurable paths below this line 7 | 8 | ifndef DO 9 | $(error Use "Makefile" instead of "xmms.mk") 10 | endif 11 | 12 | asap-xmms: libasap-xmms.so 13 | .PHONY: asap-xmms 14 | 15 | libasap-xmms.so: $(call src,xmms/libasap-xmms.c asap.[ch]) 16 | $(DO_CC) $(XMMS_CFLAGS) -Wl,--version-script=$(srcdir)xmms/libasap-xmms.map $(XMMS_LIBS) 17 | CLEAN += libasap-xmms.so 18 | 19 | install-xmms: libasap-xmms.so 20 | $(call INSTALL_PROGRAM,libasap-xmms.so,$(XMMS_INPUT_PLUGIN_DIR)) 21 | .PHONY: install-xmms 22 | 23 | uninstall-xmms: 24 | $(RM) $(DESTDIR)$(XMMS_INPUT_PLUGIN_DIR)/libasap-xmms.so 25 | .PHONY: uninstall-xmms 26 | 27 | install-xmms-user: libasap-xmms.so 28 | $(call INSTALL_PROGRAM,libasap-xmms.so,$(XMMS_USER_PLUGIN_DIR)) 29 | .PHONY: install-xmms-user 30 | 31 | uninstall-xmms-user: 32 | $(RM) $(DESTDIR)$(XMMS_USER_PLUGIN_DIR)/libasap-xmms.so 33 | .PHONY: uninstall-xmms-user 34 | -------------------------------------------------------------------------------- /www/index.xml: -------------------------------------------------------------------------------- 1 | <page title="Home"> 2 | <p>ASAP plays <a href="https://en.wikipedia.org/wiki/Atari_8-bit_family">Atari 8-bit</a> 3 | <a href="https://en.wikipedia.org/wiki/Chiptune">chiptunes</a> on modern computers and mobile devices. 4 | It emulates the <a href="https://en.wikipedia.org/wiki/POKEY">POKEY sound chip</a> 5 | and the <a href="https://en.wikipedia.org/wiki/6502">6502 processor</a>.</p> 6 | 7 | <p>ASAP is free software, you can redistribute it and/or modify it under the terms 8 | of the <a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt">GNU General Public License</a>.</p> 9 | 10 | <p>Get ASAP for <a href="android.html">Android</a>, 11 | <a href="windows.html">Windows</a>, <a href="macos.html">macOS</a>, 12 | <a href="linux.html">Linux</a> or run right in your <a href="web.html">web browser</a>. 13 | On iOS, ASAP is integrated into <a href="https://yoyofr.blogspot.com/p/modizer.html">Modizer</a>.</p> 14 | <p>You can listen to <a href="http://asma.atari.org/">Atari SAP Music Archive (ASMA)</a> 15 | which is a collection of over 8000 songs with over 200 hours of total playback time. Enjoy!</p> 16 | </page> 17 | -------------------------------------------------------------------------------- /www/macos.xml: -------------------------------------------------------------------------------- 1 | <page title="macOS"> 2 | <h2>macOS</h2> 3 | <p>Download <download prefix="asap-" suffix="-macos.dmg" />.</p> 4 | 5 | <h2>VLC</h2> 6 | <p><a href="https://www.videolan.org/vlc/">VLC</a> is a popular video player that plays audio as well. 7 | It provides limited support for the SAP file format out of the box (no digitized sounds, buggy emulation). 8 | For best experience, install the ASAP plugin as follows:</p> 9 | <ol> 10 | <li>Install VLC first.</li> 11 | <li>Open <code>asap-<version />-macos.dmg</code>.</li> 12 | <li>Drag <code>libasap_plugin.dylib</code> to <code>plugins</code>.</li> 13 | </ol> 14 | <p>Due to limitations of the VLC plugin interface, the VLC plugin only supports SAP and FC formats.</p> 15 | 16 | <h2>asapconv</h2> 17 | <p>For command-line conversions (e.g. to WAV or between SAP and the tracker formats) 18 | and editing the metadata, install asapconv: open <code>asap-<version />-macos.dmg</code> 19 | then drag <code>asapconv</code> to <code>bin</code>.</p> 20 | <p>Run the program from the command prompt to see the syntax. 21 | The <code>-o/--output</code> option selects the output format and is mandatory.</p> 22 | </page> 23 | -------------------------------------------------------------------------------- /java/android/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <resources> 3 | <string name="app_name">ASAP</string> 4 | <string name="app_description">ASAP is a player of Atari 8-bit music. It emulates the POKEY sound chip and the 6502 processor. ASAP supports the following file formats: SAP, CMC, CM3, CMR, CMS, DMC, DLT, MPT, MPD, RMT, TMC, TM8, TM2, FC.</string> 5 | <string name="selector_title">ASAP - %1$s</string> 6 | <string name="shuffle_all">Shuffle All</string> 7 | <string name="songs_format">%1$d songs</string> 8 | <string name="author_suggestion_songs">%1$d songs</string> 9 | <string name="error_reading_file">Error reading file</string> 10 | <string name="invalid_file">Invalid file</string> 11 | <string name="song_format">Song %1$d of %2$d</string> 12 | <string name="menu_search">Search</string> 13 | <string name="menu_browse">Browse</string> 14 | <string name="notification_channel">Now Playing</string> 15 | <string name="notification_play">Play</string> 16 | <string name="notification_pause">Pause</string> 17 | <string name="notification_next">Next</string> 18 | <string name="notification_previous">Previous</string> 19 | </resources> 20 | -------------------------------------------------------------------------------- /6502/6502.mk: -------------------------------------------------------------------------------- 1 | MADS = $(DO)mads -s -o:$@ $< 2 | 3 | # no user-configurable paths below this line 4 | 5 | ifndef DO 6 | $(error Use "Makefile" instead of "6502.mk") 7 | endif 8 | 9 | ASM6502_PLAYERS = cmc cm3 cmr cms dlt mpt rmt4 rmt8 tmc tm2 fc 10 | ASM6502_PLAYERS_OBX = $(ASM6502_PLAYERS:%=6502/%.obx) 11 | ASM6502_OBX = $(ASM6502_PLAYERS_OBX) 6502/xexb.obx 6502/xexd.obx 6502/xexinfo.obx 12 | 13 | 6502/cmc.obx: $(srcdir)6502/cmc.asx 14 | $(XASM) -d CM3=0 -d CMR=0 15 | 16 | 6502/cm3.obx: $(srcdir)6502/cmc.asx 17 | $(XASM) -d CM3=1 -d CMR=0 18 | 19 | 6502/cmr.obx: $(srcdir)6502/cmc.asx 20 | $(XASM) -d CM3=0 -d CMR=1 21 | 22 | 6502/dlt.obx: $(srcdir)6502/dlt.as8 23 | $(MADS) -c 24 | 25 | 6502/rmt4.obx: $(srcdir)6502/rmt.asx 26 | $(XASM) -d STEREOMODE=0 27 | 28 | 6502/rmt8.obx: $(srcdir)6502/rmt.asx 29 | $(XASM) -d STEREOMODE=1 30 | 31 | 6502/fc.obx: $(srcdir)6502/fc.as8 32 | $(MADS) 33 | 34 | 6502/xexinfo.obx: $(srcdir)6502/xexinfo.asx 35 | $(XASM) -d TEST=0 -l 36 | 37 | 6502/xexinfo.xex: $(srcdir)6502/xexinfo.asx 38 | $(XASM) -d TEST=1 39 | 40 | 6502/%.obx: $(srcdir)6502/%.asx 41 | $(XASM) -l 42 | 43 | CLEAN += $(ASM6502_OBX) 6502/fp3depk.obx 6502/xexinfo.xex 6502/*.lst 44 | -------------------------------------------------------------------------------- /test/crashsap.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * crashsap.cs - buffer overflow regression test 3 | * 4 | * Copyright (C) 2012 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | using Sf.Asap; 25 | 26 | public class CrashSap 27 | { 28 | public static void Main() 29 | { 30 | ASAP asap = new ASAP(); 31 | asap.Load("foo.sap", new byte[1] { (byte) 'S' }, 1); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /csharp/csharp.mk: -------------------------------------------------------------------------------- 1 | CSC = $(DO)csc -nologo -o+ -out:$@ $(if $(filter %.dll,$@),-t:library) $^ 2 | NDOC = $(DO)"C:/Program Files (x86)/NDoc3/bin/NDoc3Console.exe" 3 | 4 | # no user-configurable paths below this line 5 | 6 | ifndef DO 7 | $(error Use "Makefile" instead of "csharp.mk") 8 | endif 9 | 10 | csharp: csharp/asap2wav.exe csharp/asapplay.exe 11 | .PHONY: csharp 12 | 13 | csharp/asap2wav.exe: $(srcdir)csharp/asap2wav.cs csharp/asap.cs 14 | $(CSC) 15 | CLEAN += csharp/asap2wav.exe 16 | 17 | csharp/asapplay.exe: $(srcdir)csharp/asapplay.cs csharp/asap.cs 18 | $(CSC) 19 | CLEAN += csharp/asapplay.exe 20 | 21 | csharp/asap.cs: $(call src,asap.fu asap6502.fu asapinfo.fu cpu6502.fu pokey.fu) $(ASM6502_PLAYERS_OBX) 22 | $(FUT) -n Sf.Asap 23 | CLEAN += csharp/asap.cs 24 | 25 | csharp/doc/ASAP.chm: csharp/doc/ASAP.dll 26 | $(NDOC) -documenter:MSDN -CleanIntermediates=true -DocumentInheritedFrameworkMembers=false \ 27 | -OutputDirectory=csharp/doc -OutputTarget=HtmlHelp -HtmlHelpName=ASAP -Title="ASAP .NET API" $< 28 | CLEAN += csharp/doc/ASAP.chm 29 | 30 | csharp/doc/ASAP.dll: csharp/asap.cs 31 | $(CSC) -t:library -doc:csharp/doc/ASAP.xml 32 | CLEAN += csharp/doc/ASAP.dll csharp/doc/ASAP.xml 33 | -------------------------------------------------------------------------------- /www/www.mk: -------------------------------------------------------------------------------- 1 | ifndef DO 2 | $(error Use "Makefile" instead of "www.mk") 3 | endif 4 | 5 | WWW_TARGETS = www/index.html www/android.html www/windows.html www/macos.html www/linux.html \ 6 | www/web.html www/formats.html www/convert.html www/news.html www/sap-format.html www/contact.html \ 7 | www/apokeysnd.dll www/asap.js www/asapweb.js \ 8 | www/favicon.ico www/PORTS.xml www/PORTS.xsl 9 | CLEAN += $(WWW_TARGETS) 10 | 11 | www: $(WWW_TARGETS) 12 | .PHONY: www 13 | 14 | www/%.html: $(call src,www/www.xsl www/%.xml) 15 | $(DO)xsltproc -o $@ --stringparam version $(VERSION) $^ && java -jar C:/bin/vnu.jar $@ 16 | 17 | www/apokeysnd.dll: win32/apokeysnd.dll 18 | $(COPY) 19 | 20 | www/asap.js: javascript/asap.js 21 | $(COPY) 22 | 23 | www/asapweb.js: $(srcdir)javascript/asapweb.js 24 | $(COPY) 25 | 26 | www/favicon.ico: $(srcdir)win32/wasap/wasap.ico 27 | $(COPY) 28 | 29 | www/PORTS.xml: $(srcdir)PORTS.xml 30 | $(COPY) 31 | 32 | www/PORTS.xsl: $(srcdir)PORTS.xsl 33 | $(COPY) 34 | 35 | browser: www/web.html www/asap.js www/asapweb.js 36 | $(LOCALAPPDATA)/Programs/Opera/launcher --allow-file-access-from-files file:///$(shell cygpath -am $<) 37 | .PHONY: browser 38 | 39 | sftp: 40 | sftp pfusik,asap@web.sourceforge.net:htdocs 41 | .PHONY: sftp 42 | -------------------------------------------------------------------------------- /java/android/res/layout/fileinfo_list_item.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 | android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="4sp" android:orientation="vertical"> 4 | <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> 5 | <TextView android:id="@+id/title" android:layout_width="0px" android:layout_weight="1" android:layout_height="wrap_content" 6 | android:textSize="18sp" android:textStyle="bold" /> 7 | <TextView android:id="@+id/songs" android:layout_width="wrap_content" android:layout_height="wrap_content" 8 | android:textSize="16sp" /> 9 | </LinearLayout> 10 | <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> 11 | <TextView android:id="@+id/author" android:layout_width="0px" android:layout_weight="1" android:layout_height="wrap_content" 12 | android:textSize="16sp" android:textColor="#aaa" /> 13 | <TextView android:id="@+id/date" android:layout_width="wrap_content" android:layout_height="wrap_content" 14 | android:textSize="16sp" android:textColor="#aaa" /> 15 | </LinearLayout> 16 | </LinearLayout> 17 | -------------------------------------------------------------------------------- /test/gtia_consol.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "GTIA CONSOL Test"',13,10 6 | dta c'DATE "10/05/2011"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 00:10',13,10 10 | opt h+ 11 | eif 12 | 13 | scrptr equ $8a ; 2 bytes 14 | printptr equ $8c ; 2 bytes 15 | 16 | org f:$3000 17 | main 18 | :SAP mwa #$1000 scrptr 19 | lda <title 20 | ldx >title 21 | jsr print 22 | 23 | :!SAP sei:inc ^4e 24 | 25 | ldx #0 26 | test_loop 27 | stx $d01f 28 | txa 29 | eor:and #$f 30 | cmp $d01f 31 | bne error 32 | inx 33 | bne test_loop 34 | 35 | lda <pass 36 | ldx >pass 37 | jsr print 38 | mwa #$af30 $d200 39 | jmp * 40 | 41 | error 42 | lda <fail 43 | ldx >fail 44 | jsr print 45 | mwa #$cfa0 $d200 46 | jmp * 47 | 48 | put_char 49 | ift SAP 50 | sta (scrptr),0 51 | inw scrptr 52 | rts 53 | els 54 | mvx #11 $342 55 | mwx #0 $348 56 | jmp $e456 57 | eif 58 | 59 | print 60 | sta printptr 61 | stx printptr+1 62 | jmp print_2 63 | print_1 64 | jsr put_char 65 | inw printptr 66 | print_2 67 | lda (printptr),0 68 | bne print_1 69 | rts 70 | 71 | title dta c'GTIA: CONSOL...',0 72 | pass dta c'Pass',$9b,0 73 | fail dta c'FAIL.',$9b,0 74 | 75 | ift !SAP 76 | run main 77 | eif 78 | -------------------------------------------------------------------------------- /aatr-stdio.h: -------------------------------------------------------------------------------- 1 | /* 2 | * aatr-stdio.h - another ATR file extractor 3 | * 4 | * Copyright (C) 2012-2015 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef _AATR_STDIO_H_ 25 | #define _AATR_STDIO_H_ 26 | 27 | #include "aatr.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | typedef struct AATR AATR; 34 | 35 | AATR *AATRStdio_New(const char *filename); 36 | void AATRStdio_Delete(AATR *self); 37 | 38 | #ifdef __cplusplus 39 | } 40 | #endif 41 | #endif 42 | -------------------------------------------------------------------------------- /win32/wasap/wasap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * wasap.c - Another Slight Atari Player for Win32 systems 3 | * 4 | * Copyright (C) 2005-2010 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #define IDI_APP 101 25 | #define IDI_STOP 102 26 | #define IDI_PLAY 103 27 | #define IDR_TRAYMENU 200 28 | #define IDM_OPEN 201 29 | #define IDM_STOP 202 30 | #define IDM_FILE_INFO 203 31 | #define IDM_SAVE_WAV 204 32 | #define IDM_ABOUT 205 33 | #define IDM_EXIT 206 34 | #define IDM_SONG1 211 35 | -------------------------------------------------------------------------------- /java/android/res/layout-land/fileinfo_list_item.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 | android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="4sp" 4 | android:orientation="horizontal" android:gravity="center_vertical"> 5 | <TextView android:id="@+id/author" android:layout_width="wrap_content" android:layout_height="wrap_content" 6 | android:textSize="16sp" android:textColor="#aaa" /> 7 | <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" 8 | android:textSize="16sp" android:textColor="#aaa" android:text=" - " /> 9 | <TextView android:id="@+id/title" android:layout_width="0px" android:layout_weight="1" android:layout_height="wrap_content" 10 | android:textSize="18sp" android:textStyle="bold" /> 11 | <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" 12 | android:orientation="vertical" android:gravity="right"> 13 | <TextView android:id="@+id/songs" android:layout_width="wrap_content" android:layout_height="wrap_content" 14 | android:textSize="16sp" /> 15 | <TextView android:id="@+id/date" android:layout_width="wrap_content" android:layout_height="wrap_content" 16 | android:textSize="16sp" android:textColor="#aaa" /> 17 | </LinearLayout> 18 | </LinearLayout> 19 | -------------------------------------------------------------------------------- /test/benchmark/benchmark.mk: -------------------------------------------------------------------------------- 1 | GME_PATH = ../game-music-emu 2 | SAP_PATH = ../sapLib 3 | 4 | benchmark: test/benchmark/BENCHMARK.csv 5 | .PHONY: benchmark 6 | 7 | test/benchmark/BENCHMARK.csv: $(srcdir)test/benchmark/benchmark.pl win32/msvc/asapconv.exe win32/asapconv.exe win32/x64/asapconv.exe java/asap2wav.jar csharp/asap2wav.exe test/benchmark/gme_benchmark.exe test/benchmark/sap_benchmark.exe 8 | perl $< > $@ 9 | 10 | test/benchmark/gme_benchmark.exe: $(call src,test/benchmark/gme_benchmark.c asap.[ch]) $(GME_PATH)/gme/*.cpp $(GME_PATH)/gme/*.h 11 | $(WIN32_CXX) 12 | CLEAN += test/benchmark/gme_benchmark.exe 13 | 14 | test/benchmark/sap_benchmark.exe: $(call src,test/benchmark/sap_benchmark.cpp asap.[ch]) $(SAP_PATH)/pokey0.cpp $(SAP_PATH)/pokey1.cpp $(SAP_PATH)/sapCpu.cpp $(SAP_PATH)/sapEngine.cpp $(SAP_PATH)/sapLib.h $(SAP_PATH)/sapPokey.cpp 15 | $(WIN32_CXX) 16 | CLEAN += test/benchmark/sap_benchmark.exe 17 | 18 | profile: gmon.out 19 | gprof -bpQ test/benchmark/asapconv-profile.exe 20 | 21 | gmon.out: test/benchmark/asapconv-profile.exe 22 | $(DO)./test/benchmark/asapconv-profile.exe -b -o .wav test/benchmark/Drunk_Chessboard.sap 23 | CLEAN += gmon.out 24 | 25 | test/benchmark/asapconv-profile.exe: $(call src,asapconv.c asap.[ch]) 26 | $(DO)mingw32-gcc -O2 -Wall -o $@ -pg $(filter-out %.h,$^) 27 | # avoid -s 28 | CLEAN += test/benchmark/asapconv-profile.exe 29 | -------------------------------------------------------------------------------- /vlc/vlc.mk: -------------------------------------------------------------------------------- 1 | # Linux 2 | 3 | VLC_CFLAGS = -std=gnu99 -I/usr/include/vlc/plugins 4 | VLC_DEMUX_PLUGIN_DIR = `pkg-config --variable pluginsdir vlc-plugin`/demux 5 | 6 | # macOS 7 | 8 | VLC_OSX_CFLAGS = -std=gnu99 -I../vlc-3.0.14/include -dynamiclib -flat_namespace 9 | VLC_OSX_PLUGIN_DIR = /Applications/VLC.app/Contents/MacOS/plugins 10 | 11 | # no user-configurable paths below this line 12 | 13 | ifndef DO 14 | $(error Use "Makefile" instead of "vlc.mk") 15 | endif 16 | 17 | # Linux 18 | 19 | asap-vlc: libasap_plugin.so 20 | .PHONY: asap-vlc 21 | 22 | libasap_plugin.so: $(call src,vlc/libasap_plugin.c asap.[ch]) 23 | $(DO_CC) $(VLC_CFLAGS) 24 | CLEAN += libasap_plugin.so 25 | 26 | install-vlc: libasap_plugin.so 27 | $(call INSTALL_PROGRAM,libasap_plugin.so,$(VLC_DEMUX_PLUGIN_DIR)) 28 | .PHONY: install-vlc 29 | 30 | uninstall-vlc: 31 | $(RM) $(DESTDIR)$(VLC_DEMUX_PLUGIN_DIR)/libasap_plugin.so 32 | .PHONY: uninstall-vlc 33 | 34 | # macOS 35 | 36 | asap-vlc-osx: libasap_plugin.dylib 37 | .PHONY: asap-vlc-osx 38 | 39 | libasap_plugin.dylib: $(call src,vlc/libasap_plugin.c asap.[ch]) 40 | $(OSX_CC) $(VLC_OSX_CFLAGS) 41 | CLEAN += libasap_plugin.dylib 42 | 43 | install-vlc-osx: libasap_plugin.dylib 44 | $(call INSTALL_DATA,libasap_plugin.dylib,$(VLC_OSX_PLUGIN_DIR)) 45 | .PHONY: install-vlc-osx 46 | 47 | uninstall-vlc-osx: 48 | $(RM) $(DESTDIR)$(VLC_OSX_PLUGIN_DIR)/libasap_plugin.dylib 49 | .PHONY: uninstall-vlc-osx 50 | 51 | -------------------------------------------------------------------------------- /test/antic_nmires.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "ANTIC NMIRES Test"',13,10 6 | dta c'DATE "11/12/2010"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 00:10',13,10 10 | opt h+ 11 | eif 12 | 13 | scrptr equ $8a ; 2 bytes 14 | printptr equ $8c ; 2 bytes 15 | 16 | org f:$3000 17 | main 18 | :SAP mwa #$1000 scrptr 19 | lda <title 20 | ldx >title 21 | jsr print 22 | 23 | :!SAP sei:inc ^4e 24 | lda:rne ^4b 25 | sta ^4f 26 | lda #123 27 | cmp:rne ^4b 28 | sta:sta ^4a 29 | cmp (0,x) 30 | cmp (0,x) 31 | nop 32 | sta ^4f 33 | lda ^4f 34 | cmp #$5f 35 | bne error 36 | 37 | lda #123 38 | cmp:rne ^4b 39 | sta:sta ^4a 40 | cmp (0,x) 41 | cmp (0,x) 42 | cmp 0 43 | sta ^4f 44 | lda ^4f 45 | cmp #$1f 46 | bne error 47 | 48 | lda <pass 49 | ldx >pass 50 | jsr print 51 | mwa #$af30 $d200 52 | jmp * 53 | 54 | error 55 | lda <fail 56 | ldx >fail 57 | jsr print 58 | mwa #$cfa0 $d200 59 | jmp * 60 | 61 | put_char 62 | ift SAP 63 | sta (scrptr),0 64 | inw scrptr 65 | rts 66 | els 67 | mvx #11 $342 68 | mwx #0 $348 69 | jmp $e456 70 | eif 71 | 72 | print 73 | sta printptr 74 | stx printptr+1 75 | jmp print_2 76 | print_1 77 | jsr put_char 78 | inw printptr 79 | print_2 80 | lda (printptr),0 81 | bne print_1 82 | rts 83 | 84 | title dta c'ANTIC: NMIRES...',0 85 | pass dta c'Pass',$9b,0 86 | fail dta c'FAIL.',$9b,0 87 | 88 | ift !SAP 89 | run main 90 | eif 91 | -------------------------------------------------------------------------------- /test/pokey_irqst.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "POKEY IRQST Test"',13,10 6 | dta c'DATE "07/06/2011"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 00:10',13,10 10 | opt h+ 11 | eif 12 | 13 | scrptr equ $8a ; 2 bytes 14 | printptr equ $8c ; 2 bytes 15 | 16 | org f:$3000 17 | main 18 | :SAP mwa #$1000 scrptr 19 | lda <title 20 | ldx >title 21 | jsr print 22 | 23 | :!SAP sei:inc ^4e 24 | :!SAP inc ^40 25 | 26 | lda #0 27 | jsr test1 28 | lda #1 29 | jsr test1 30 | 31 | :!SAP lsr:cli ^4e 32 | lda <pass 33 | ldx >pass 34 | jsr print 35 | mwa #$af30 $d200 36 | jmp * 37 | 38 | test1 39 | mvx #0 ^2e 40 | mvx #$40 ^28 41 | mvx #$ff ^20 42 | stx ^29 43 | stx ^4a 44 | sta ^20 45 | mvx #1 ^2e 46 | stx ^29 47 | cmp 0,x 48 | eor ^2e 49 | mvx $10 ^2e 50 | lsr @ 51 | bcs error 52 | rts 53 | 54 | error 55 | :!SAP lsr:cli ^4e 56 | lda <fail 57 | ldx >fail 58 | jsr print 59 | mwa #$cfa0 $d200 60 | jmp * 61 | 62 | put_char 63 | ift SAP 64 | sta (scrptr),0 65 | inw scrptr 66 | rts 67 | els 68 | mvx #11 $342 69 | mwx #0 $348 70 | jmp $e456 71 | eif 72 | 73 | print 74 | sta printptr 75 | stx printptr+1 76 | jmp print_2 77 | print_1 78 | jsr put_char 79 | inw printptr 80 | print_2 81 | lda (printptr),0 82 | bne print_1 83 | rts 84 | 85 | title dta c'POKEY: IRQST...',0 86 | pass dta c'Pass',$9b,0 87 | fail dta c'FAIL.',$9b,0 88 | 89 | ift !SAP 90 | run main 91 | eif 92 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | asap (5.3.0-1) UNRELEASED; urgency=low 2 | 3 | * New release. 4 | 5 | -- Piotr Fusik <fox@scene.pl> Wed, 8 Feb 2023 17:53:02 +0100 6 | 7 | asap (5.2.0-1) UNRELEASED; urgency=low 8 | 9 | * New release. 10 | * Added XMMS2. 11 | 12 | -- Piotr Fusik <fox@scene.pl> Wed, 8 Dec 2021 10:08:56 +0100 13 | 14 | asap (5.1.0-1) UNRELEASED; urgency=low 15 | 16 | * New release. 17 | 18 | -- Piotr Fusik <fox@scene.pl> Fri, 9 Jul 2021 21:01:11 +0200 19 | 20 | asap (5.0.1-1) UNRELEASED; urgency=low 21 | 22 | * New release. 23 | 24 | -- Piotr Fusik <fox@scene.pl> Sun, 19 Jan 2020 18:46:41 +0100 25 | 26 | asap (5.0.0-1) UNRELEASED; urgency=low 27 | 28 | * New release. 29 | 30 | -- Piotr Fusik <fox@scene.pl> Thu, 21 Nov 2019 10:12:29 +0100 31 | 32 | asap (4.0.0-2) UNRELEASED; urgency=low 33 | 34 | * Fix VLC plugin location. 35 | 36 | -- Piotr Fusik <fox@scene.pl> Sun, 13 Jan 2019 14:26:27 +0100 37 | 38 | asap (4.0.0-1) UNRELEASED; urgency=low 39 | 40 | * New release. 41 | * Discontinued GStreamer. 42 | 43 | -- Piotr Fusik <fox@scene.pl> Thu, 10 Jan 2019 17:27:07 +0100 44 | 45 | asap (3.2.0-1) UNRELEASED; urgency=low 46 | 47 | * New release. 48 | 49 | -- Piotr Fusik <fox@scene.pl> Mon, 23 Jun 2014 16:05:58 +0200 50 | 51 | asap (3.1.6-1) UNRELEASED; urgency=low 52 | 53 | * New release. 54 | 55 | -- Piotr Fusik <fox@scene.pl> Wed, 15 Jan 2014 21:09:45 +0100 56 | 57 | asap (3.1.5-1) UNRELEASED; urgency=low 58 | 59 | * First deb packaging. 60 | 61 | -- Piotr Fusik <fox@scene.pl> Fri, 16 Aug 2013 15:08:15 +0200 62 | -------------------------------------------------------------------------------- /java/android/res/layout/player.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 | android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> 4 | <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="0px" 5 | android:layout_weight="1" android:drawSelectorOnTop="false" android:listSelector="@drawable/list_selector" /> 6 | <LinearLayout android:id="@+id/playing_panel" android:layout_width="match_parent" android:layout_height="wrap_content" 7 | android:orientation="vertical" android:gravity="center_horizontal" android:background="#611" android:visibility="gone" > 8 | <TextView android:id="@+id/playing_name" android:layout_width="match_parent" android:layout_height="wrap_content" 9 | android:gravity="center_horizontal" android:textSize="20sp" /> 10 | <TextView android:id="@+id/playing_author" android:layout_width="match_parent" android:layout_height="wrap_content" 11 | android:gravity="center_horizontal" android:textSize="16sp" /> 12 | <TextView android:id="@+id/playing_date" android:layout_width="match_parent" android:layout_height="wrap_content" 13 | android:gravity="center_horizontal" android:textSize="16sp" /> 14 | <TextView android:id="@+id/playing_song" android:layout_width="match_parent" android:layout_height="wrap_content" 15 | android:gravity="center_horizontal" android:textSize="16sp" /> 16 | <include layout="@layout/buttons_seekbar" /> 17 | </LinearLayout> 18 | </LinearLayout> 19 | -------------------------------------------------------------------------------- /win32/winamp/ipc_pe.h: -------------------------------------------------------------------------------- 1 | #ifndef __IPC_PE_H 2 | #define __IPC_PE_H 3 | 4 | #define IPC_PE_GETCURINDEX 100 // returns current idx 5 | #define IPC_PE_GETINDEXTOTAL 101 // returns number of items 6 | #define IPC_PE_GETINDEXINFO 102 // (copydata) lpData is of type callbackinfo, callback is called with copydata/fileinfo structure and msg IPC_PE_GETINDEXINFORESULT 7 | #define IPC_PE_GETINDEXINFORESULT 103 // callback message for IPC_PE_GETINDEXINFO 8 | #define IPC_PE_DELETEINDEX 104 // lParam = index 9 | #define IPC_PE_SWAPINDEX 105 // (lParam & 0xFFFF0000) >> 16 = from, (lParam & 0xFFFF) = to 10 | #define IPC_PE_INSERTFILENAME 106 // (copydata) lpData is of type fileinfo 11 | #define IPC_PE_GETDIRTY 107 // returns 1 if the playlist changed since the last IPC_PE_SETCLEAN 12 | #define IPC_PE_SETCLEAN 108 // resets the dirty flag until next modification 13 | #define IPC_PE_GETIDXFROMPOINT 109 // pass a point parm, return a playlist index 14 | #define IPC_PE_SAVEEND 110 // pass index to save from 15 | #define IPC_PE_RESTOREEND 111 // no parm 16 | 17 | typedef struct { 18 | char file[MAX_PATH]; 19 | int index; 20 | } fileinfo; 21 | 22 | typedef struct { 23 | HWND callback; 24 | int index; 25 | } callbackinfo; 26 | 27 | // the following messages are in_process ONLY 28 | 29 | #define IPC_PE_GETINDEXTITLE 200 // lParam = pointer to fileinfo2 struct 30 | 31 | typedef struct { 32 | int fileindex; 33 | char filetitle[256]; 34 | char filelength[16]; 35 | } fileinfo2; 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /test/antic_vcount.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "ANTIC VCOUNT Test"',13,10 6 | dta c'DATE "10/12/2010"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | :NTSC dta c'NTSC',13,10 10 | dta c'TIME 00:10',13,10 11 | opt h+ 12 | eif 13 | 14 | scrptr equ $8a ; 2 bytes 15 | printptr equ $8c ; 2 bytes 16 | 17 | org f:$3000 18 | main 19 | :SAP mwa #$1000 scrptr 20 | lda <title 21 | ldx >title 22 | jsr print 23 | 24 | lda:rne ^4b 25 | ldy #155 26 | lda ^14 27 | lsr @ 28 | seq:ldy #130 29 | cpy:rne ^4b 30 | sta:sta ^4a 31 | cmp 0 32 | cpy ^4b 33 | bne error 34 | cpy:rne ^4b 35 | sta:sta ^4a 36 | nop 37 | iny 38 | cpy ^4b 39 | bne error 40 | dey 41 | cpy:rne ^4b 42 | sta:sta ^4a 43 | nop 44 | cmp 0 45 | lda ^4b 46 | bne error 47 | 48 | lda <pass 49 | ldx >pass 50 | jsr print 51 | mwa #$af30 $d200 52 | jmp * 53 | 54 | error 55 | lda <fail 56 | ldx >fail 57 | jsr print 58 | mwa #$cfa0 $d200 59 | jmp * 60 | 61 | put_char 62 | ift SAP 63 | sta (scrptr),0 64 | inw scrptr 65 | rts 66 | els 67 | mvx #11 $342 68 | mwx #0 $348 69 | jmp $e456 70 | eif 71 | 72 | print 73 | sta printptr 74 | stx printptr+1 75 | jmp print_2 76 | print_1 77 | jsr put_char 78 | inw printptr 79 | print_2 80 | lda (printptr),0 81 | bne print_1 82 | rts 83 | 84 | title dta c'ANTIC: VCOUNT' 85 | ift SAP 86 | :NTSC dta c' NTSC' 87 | :!NTSC dta c' PAL' 88 | eif 89 | dta c'...',0 90 | pass dta c'Pass',$9b,0 91 | fail dta c'FAIL.',$9b,0 92 | 93 | ift !SAP 94 | run main 95 | eif 96 | -------------------------------------------------------------------------------- /test/RESULTS.xsl: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" ?> 2 | <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 3 | <xsl:output method="html" /> 4 | 5 | <xsl:template match="/tests"> 6 | <html> 7 | <head> 8 | <title>ASAP test results 9 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
TestAtari800 2.2.1Atari++ 1.60Altirra 1.9ASAP 2.1.2ASAP 3.0.0
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | Pass 47 | 48 | 49 | 50 | FAIL 51 | 52 | 53 | -------------------------------------------------------------------------------- /www/linux.xml: -------------------------------------------------------------------------------- 1 | 2 |

VLC

3 |

On Ubuntu, install VLC 4 | via apt, not snap. 5 | Then install the ASAP plugin: .

6 |

On Fedora, install VLC from RPM Fusion, 7 | then install the ASAP plugin: .

8 | VLC on Ubuntu 18.04 9 | 10 |

XMMS2

11 |

On Ubuntu install XMMS2 with sudo apt install xmms2. 12 | Then install the ASAP plugin: .

13 |

On Fedora: sudo dnf install xmms2, 14 | then .

15 | 16 |

Command-line converter

17 |

For command-line conversions (e.g. to WAV or between SAP and the tracker formats) 18 | and editing the metadata, install asapconv:

19 |
    20 |
  • on Ubuntu:
  • 21 |
  • on Fedora:
  • 22 |
23 |

Run asapconv from the shell to see the syntax. 24 | The -o/--output option selects the output format and is mandatory.

25 | 26 |

Other distros

27 |

Download the source code . 28 | Inside you will find instructions on how to build a VLC plugin, 29 | a MOC plugin, an XMMS plugin 30 | and a command-line converter asapconv.

31 |
32 | -------------------------------------------------------------------------------- /test/antic_nmien.asx: -------------------------------------------------------------------------------- 1 | scrptr equ $8a ; 2 bytes 2 | printptr equ $8c ; 2 bytes 3 | 4 | org $3000 5 | main 6 | lda title 8 | jsr print 9 | 10 | mva #0 ^4e 11 | lda #100 12 | cmp:rne ^4b 13 | mwa #nmi $fffa 14 | 15 | ldy #$40 16 | lda #123 17 | cmp:req ^4b 18 | cmp:rne ^4b 19 | sta ^4a 20 | lda 20 21 | sta ^4a 22 | :2 cmp (0,x) 23 | cmp 0 24 | sty ^4e 25 | :2 sta ^4a 26 | cmp 20 27 | jne error 28 | 29 | mva #0 ^4e 30 | lda #123 31 | cmp:rne ^4b 32 | sta ^4a 33 | lda 20 34 | sta ^4a 35 | :2 cmp (0,x) 36 | nop 37 | sty ^4e 38 | :2 sta ^4a 39 | cmp 20 40 | beq error 41 | 42 | ldy #0 43 | lda #123 44 | cmp:rne ^4b 45 | sta ^4a 46 | lda 20 47 | sta ^4a 48 | cmp (0,x) 49 | cmp 0,x 50 | cmp 0,x 51 | sty ^4e 52 | :2 sta ^4a 53 | cmp 20 54 | beq error 55 | 56 | mva #$40 ^4e 57 | lda #123 58 | cmp:rne ^4b 59 | sta ^4a 60 | lda 20 61 | sta ^4a 62 | cmp (0,x) 63 | cmp 0,x 64 | cmp 0 65 | sty ^4e 66 | :2 sta ^4a 67 | cmp 20 68 | bne error 69 | 70 | lda <pass 71 | ldx >pass 72 | jsr print 73 | mwa #$af30 $d200 74 | jmp * 75 | 76 | error 77 | lda <fail 78 | ldx >fail 79 | jsr print 80 | mwa #$cfa0 $d200 81 | jmp * 82 | 83 | put_char 84 | mvx #11 $342 85 | mwx #0 $348 86 | jmp $e456 87 | 88 | print 89 | sta printptr 90 | stx printptr+1 91 | jmp print_2 92 | print_1 93 | jsr put_char 94 | inw printptr 95 | print_2 96 | lda (printptr),0 97 | bne print_1 98 | rts 99 | 100 | nmi 101 | inc 20 102 | rti 103 | 104 | title dta c'ANTIC: NMIEN...',0 105 | pass dta c'Pass',$9b,0 106 | fail dta c'FAIL.',$9b,0 107 | 108 | run main 109 | -------------------------------------------------------------------------------- /test/test.mk: -------------------------------------------------------------------------------- 1 | ACIDSAP = ../Acid800/out/Release/AcidSAP/standalone 2 | 3 | # no user-configurable paths below this line 4 | 5 | TESTS = antic_nmires antic_nmist antic_vcount_ntsc antic_vcount_pal antic_wsync cpu_anx cpu_decimal cpu_las cpu_shx gtia_consol pokey_irqst pokey_pot pokey_potst pokey_random pokey_timerirq 6 | TESTS_SAP = $(TESTS:%=test/%.sap) 7 | 8 | check: asapscan $(ACIDSAP) $(TESTS_SAP) 9 | @export passed=0 total=0; \ 10 | for name in $(ACIDSAP)/*.sap; do \ 11 | echo -n \*\ ; ./asapscan -a "$$name"; \ 12 | passed=$$(($$passed+!$$?)); total=$$(($$total+1)); \ 13 | done; \ 14 | echo PASSED $$passed of $$total tests 15 | @export passed=0 total=0; \ 16 | for name in $(TESTS_SAP); do \ 17 | echo -n \*\ ; ./asapscan -a "$$name"; \ 18 | passed=$$(($$passed+!$$?)); total=$$(($$total+1)); \ 19 | done; \ 20 | echo PASSED $$passed of $$total tests 21 | .PHONY: check 22 | 23 | test/%.sap: $(srcdir)test/%.asx 24 | $(XASM) -d SAP=1 25 | 26 | test/%_ntsc.sap: $(srcdir)test/%.asx 27 | $(XASM) -d SAP=1 -d NTSC=1 28 | 29 | test/%_pal.sap: $(srcdir)test/%.asx 30 | $(XASM) -d SAP=1 -d NTSC=0 31 | 32 | test/%.xex: $(srcdir)test/%.asx 33 | $(XASM) -d SAP=0 34 | 35 | CLEAN += test/*.sap test/*.xex 36 | 37 | test/timevsnative: $(call src,test/timevsnative.c asap.[ch]) 38 | $(DO_CC) 39 | CLEAN += test/timevsnative 40 | 41 | test/loadsap.exe: $(call src,test/loadsap.cs csharp/asap.cs) 42 | $(CSC) 43 | CLEAN += test/loadsap.exe 44 | 45 | test/ultrasap.exe: $(call src,test/ultrasap.cs csharp/asap.cs) 46 | $(CSC) 47 | CLEAN += test/ultrasap.exe 48 | 49 | test/crashsap.exe: $(call src,test/crashsap.cs csharp/asap.cs) 50 | $(CSC) 51 | CLEAN += test/crashsap.exe 52 | 53 | include $(srcdir)test/benchmark/benchmark.mk 54 | include $(srcdir)test/disasm/disasm.mk 55 | -------------------------------------------------------------------------------- /win32/diff-sap.js: -------------------------------------------------------------------------------- 1 | // wscript.exe "PATH\TO\diff-sap.js" %base %mine %bname %yname //E:javascript 2 | 3 | // Get command-line arguments 4 | 5 | var argc = WScript.Arguments.length; 6 | if (argc != 2 && argc != 4) { 7 | WScript.Echo("Specify two filenames and optionally two titles"); 8 | WScript.Quit(1); 9 | } 10 | var sap1 = WScript.Arguments(0); 11 | var sap2 = WScript.Arguments(1); 12 | var title1 = WScript.Arguments(argc - 2); 13 | var title2 = WScript.Arguments(argc - 1); 14 | 15 | // Find TortoiseMerge 16 | 17 | var wsh = new ActiveXObject("WScript.Shell"); 18 | var tmerge; 19 | try { 20 | tmerge = wsh.RegRead("HKLM\\SOFTWARE\\TortoiseSVN\\TMergePath"); 21 | } 22 | catch (e) { 23 | try { 24 | tmerge = wsh.RegRead("HKLM\\SOFTWARE\\TortoiseGit\\TMergePath"); 25 | } 26 | catch (e) { 27 | WScript.Echo("TortoiseMerge not found!"); 28 | WScript.Quit(1); 29 | } 30 | } 31 | 32 | // Convert SAPs to plain text 33 | 34 | var fso = new ActiveXObject("Scripting.FileSystemObject"); 35 | var exe = fso.GetParentFolderName(WScript.ScriptFullName); 36 | exe = fso.BuildPath(exe, "sap2txt.exe"); 37 | 38 | function sap2txt(sap) 39 | { 40 | var txt = fso.BuildPath(fso.GetSpecialFolder(2), fso.GetTempName()); 41 | wsh.Run("cmd /c \"\"" + exe + "\" \"" + sap + "\" >\"" + txt + "\"\"", 0, true); 42 | return txt; 43 | } 44 | 45 | var txt1 = sap2txt(sap1); 46 | var txt2 = sap2txt(sap2); 47 | 48 | // Display results 49 | 50 | wsh.Run("\"" + tmerge + "\" /base:\"" + txt1 + "\" /mine:\"" + txt2 + "\" /basename:\"" + title1 + "\" /minename:\"" + title2 + "\"", 4, true); 51 | 52 | // Write back changes 53 | 54 | wsh.Run("\"" + exe +"\" \"" + txt2 + "\" \"" + sap2 + "\"", 0, true); 55 | 56 | // Delete temporary files when done 57 | 58 | fso.DeleteFile(txt2); 59 | fso.DeleteFile(txt1); 60 | -------------------------------------------------------------------------------- /java/android/res/layout/buttons_seekbar.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <merge xmlns:android="http://schemas.android.com/apk/res/android"> 3 | <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center"> 4 | <ImageButton android:id="@+id/prev" style="@android:style/MediaButton.Previous" /> 5 | <ImageButton android:id="@+id/play" style="@android:style/MediaButton.Play" android:visibility="gone" /> 6 | <ImageButton android:id="@+id/pause" style="@android:style/MediaButton.Pause" /> 7 | <ImageButton android:id="@+id/next" style="@android:style/MediaButton.Next" /> 8 | <ImageButton android:id="@+id/share" android:background="@null" android:src="@android:drawable/ic_menu_share" 9 | android:layout_width="71dp" android:layout_height="52dp" android:visibility="gone" /> 10 | </LinearLayout> 11 | <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> 12 | <TextView android:id="@+id/playing_position" android:layout_width="wrap_content" android:layout_height="wrap_content" 13 | android:layout_gravity="center_horizontal" android:textSize="14sp" 14 | android:paddingTop="4dp" android:paddingStart="4dp" android:paddingEnd="4dp" /> 15 | <SeekBar android:id="@+id/seekbar" android:max="1000" android:layout_width="0px" android:layout_height="32dp" 16 | android:layout_weight="1" android:layout_alignParentStart="true" android:layout_alignParentEnd="true" /> 17 | <TextView android:id="@+id/playing_time" android:layout_width="wrap_content" android:layout_height="wrap_content" 18 | android:layout_gravity="center_horizontal" android:textSize="14sp" 19 | android:paddingTop="4dp" android:paddingStart="4dp" android:paddingEnd="4dp" /> 20 | </LinearLayout> 21 | </merge> 22 | -------------------------------------------------------------------------------- /6502/xexb.asx: -------------------------------------------------------------------------------- 1 | HIDE_AUTHOR equ 0 2 | ift HIDE_AUTHOR 3 | countdown equ $fca7 4 | els 5 | countdown equ $fc98 6 | eif 7 | 8 | org $124 9 | main 10 | sei 11 | mvy #0 ^4e 12 | lda:rne ^4b 13 | sta ^40 14 | ldx #29 15 | sta:rpl ^00,x- 16 | ert *!=$13a 17 | ldx #8 18 | init_pokey_1 19 | sta $d210,x 20 | sta $d200,x 21 | dex:bpl init_pokey_1 22 | lda #3 23 | sta $d21f 24 | sta $d200 25 | 26 | ; check PAL vs NTSC ANTIC 27 | ; possible NTSC GTIA with PAL ANTIC 28 | lda #130 29 | cmp:rne ^4b 30 | :3 sta ^4a 31 | lda ^4b 32 | sne:inc ntsc 33 | 34 | lda song 35 | jsr init 36 | 37 | ; TODO: support 400/800/600XL 38 | mva #$fe ^31 39 | lda <nmi 40 | ldx $135 41 | seq:lda <nmi_info 42 | sta $fffa 43 | mva >nmi $fffb 44 | mva #$40 ^4e 45 | 46 | lda #125 47 | 48 | player_loop 49 | cmp:rne ^4b 50 | jsr player 51 | ldx #0 52 | ntsc equ *-1 53 | lda fastplay_low_bit 54 | lsr @ 55 | bcc fastplay_is_even 56 | lda #0 57 | calls equ *-1 58 | inc calls 59 | lsr @ 60 | fastplay_is_even 61 | lda vcount_period,x 62 | adc #125 63 | expected_vcount equ *-1 64 | bcs next_frame 65 | cmp vcount_wrap,x 66 | bcc same_frame 67 | next_frame 68 | sbc vcount_wrap,x 69 | sec 70 | same_frame 71 | sta expected_vcount 72 | lda frame_period,x 73 | adc #0 74 | expected_frame equ *-1 75 | sta expected_frame 76 | cmp #0 77 | frame equ *-1 78 | rne 79 | lda expected_vcount 80 | bcs player_loop ! 81 | 82 | nmi_info 83 | pha 84 | txa:pha 85 | ldx ntsc 86 | jsr countdown 87 | pla:tax 88 | pla 89 | nmi 90 | inc frame 91 | rti 92 | 93 | vcount_wrap dta 156,131 94 | init dta {jmp 0} 95 | opt o- 96 | dta a(0) 97 | player jmp 0 98 | song dta 0 99 | fastplay_low_bit dta 0 100 | vcount_period dta 0,0 101 | frame_period dta 0,0 102 | 103 | end 104 | -------------------------------------------------------------------------------- /asap6502.fu: -------------------------------------------------------------------------------- 1 | // asap6502.fu - player routines for the 6502 CPU 2 | // 3 | // Copyright (C) 2011-2023 Piotr Fusik 4 | // 5 | // This file is part of ASAP (Another Slight Atari Player), 6 | // see http://asap.sourceforge.net 7 | // 8 | // ASAP is free software; you can redistribute it and/or modify it 9 | // under the terms of the GNU General Public License as published 10 | // by the Free Software Foundation; either version 2 of the License, 11 | // or (at your option) any later version. 12 | // 13 | // ASAP is distributed in the hope that it will be useful, 14 | // but WITHOUT ANY WARRANTY; without even the implied warranty 15 | // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | // See the GNU General Public License for more details. 17 | // 18 | // You should have received a copy of the GNU General Public License 19 | // along with ASAP; if not, write to the Free Software Foundation, Inc., 20 | // 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | 22 | static class ASAP6502 23 | { 24 | internal static byte[]? GetPlayerRoutine(ASAPInfo info) 25 | { 26 | switch (info.Type) { 27 | case ASAPModuleType.Cmc: return resource<byte[]>("cmc.obx"); 28 | case ASAPModuleType.Cm3: return resource<byte[]>("cm3.obx"); 29 | case ASAPModuleType.Cmr: return resource<byte[]>("cmr.obx"); 30 | case ASAPModuleType.Cms: return resource<byte[]>("cms.obx"); 31 | case ASAPModuleType.Dlt: return resource<byte[]>("dlt.obx"); 32 | case ASAPModuleType.Mpt: return resource<byte[]>("mpt.obx"); 33 | case ASAPModuleType.Rmt: return info.GetChannels() == 1 ? resource<byte[]>("rmt4.obx") : resource<byte[]>("rmt8.obx"); 34 | case ASAPModuleType.Tmc: return resource<byte[]>("tmc.obx"); 35 | case ASAPModuleType.Tm2: return resource<byte[]>("tm2.obx"); 36 | case ASAPModuleType.Fc: return resource<byte[]>("fc.obx"); 37 | default: return null; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /test/antic_nmist.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "ANTIC NMIST Test"',13,10 6 | dta c'DATE "07/06/2011"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 00:10',13,10 10 | opt h+ 11 | eif 12 | 13 | scrptr equ $8a ; 2 bytes 14 | printptr equ $8c ; 2 bytes 15 | 16 | org f:$3000 17 | main 18 | :SAP mwa #$1000 scrptr 19 | lda <title 20 | ldx >title 21 | jsr print 22 | 23 | :!SAP sei:inc ^4e 24 | ldx #0 25 | test_loop 26 | lda:rne ^4b 27 | sta ^4f,x 28 | lda #123 29 | cmp:rne ^4b 30 | sta:sta ^4a 31 | cmp (0,x) 32 | cmp 0,x 33 | cmp 0,x 34 | lda ^4f,x 35 | cmp #$5f 36 | bne error 37 | 38 | lda:rne ^4b 39 | lda ^4f,x 40 | cmp #$5f 41 | bne error 42 | 43 | lda #64 44 | cmp:rne ^4b 45 | lda ^4f,x 46 | cmp #$5f 47 | bne error 48 | 49 | sta ^4f,x 50 | lda ^4f,x 51 | cmp #$1f 52 | bne error 53 | 54 | lda #123 55 | cmp:rne ^4b 56 | sta:sta ^4a 57 | cmp (0,x) 58 | cmp 0,x 59 | cmp 0 60 | lda ^4f,x 61 | cmp #$1f 62 | bne error 63 | 64 | txa 65 | add #$10 66 | tax 67 | bcc test_loop 68 | 69 | lda <pass 70 | ldx >pass 71 | jsr print 72 | mwa #$af30 $d200 73 | jmp * 74 | 75 | error 76 | lda <fail 77 | ldx >fail 78 | jsr print 79 | mwa #$cfa0 $d200 80 | jmp * 81 | 82 | put_char 83 | ift SAP 84 | sta (scrptr),0 85 | inw scrptr 86 | rts 87 | els 88 | mvx #11 $342 89 | mwx #0 $348 90 | jmp $e456 91 | eif 92 | 93 | print 94 | sta printptr 95 | stx printptr+1 96 | jmp print_2 97 | print_1 98 | jsr put_char 99 | inw printptr 100 | print_2 101 | lda (printptr),0 102 | bne print_1 103 | rts 104 | 105 | title dta c'ANTIC: NMIST...',0 106 | pass dta c'Pass',$9b,0 107 | fail dta c'FAIL.',$9b,0 108 | 109 | ift !SAP 110 | run main 111 | eif 112 | -------------------------------------------------------------------------------- /test/loadsap.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * loadsap.cs - print files with ASAP loading errors 3 | * 4 | * Copyright (C) 2011 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | using System; 25 | using System.IO; 26 | 27 | using Sf.Asap; 28 | 29 | public class LoadSap 30 | { 31 | static void Check(string path) 32 | { 33 | if (Directory.Exists(path)) { 34 | foreach (string child in Directory.GetFileSystemEntries(path)) 35 | Check(child); 36 | } 37 | else if (ASAPInfo.IsOurFile(path)) { 38 | byte[] module = File.ReadAllBytes(path); 39 | try { 40 | ASAP asap = new ASAP(); 41 | asap.Load(path, module, module.Length); 42 | asap.PlaySong(asap.GetInfo().GetDefaultSong(), -1); 43 | } 44 | catch (Exception ex) { 45 | Console.WriteLine("{0}: {1}", path, ex.Message); 46 | } 47 | } 48 | } 49 | 50 | public static int Main(string[] args) 51 | { 52 | if (args.Length == 0) { 53 | Console.WriteLine("Usage: loadsap FILE_OR_DIR..."); 54 | return 1; 55 | } 56 | foreach (string path in args) 57 | Check(path); 58 | return 0; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /java/java.mk: -------------------------------------------------------------------------------- 1 | JAVA_SDK = "C:/Program Files/Java/jdk-20" 2 | 3 | JAVAC = $(DO)javac 4 | JAR = $(DO)$(JAVA_SDK)/bin/jar 5 | JAVADOC = $(DO)$(JAVA_SDK)/bin/javadoc 6 | 7 | # no user-configurable paths below this line 8 | 9 | ifndef DO 10 | $(error Use "Makefile" instead of "java.mk") 11 | endif 12 | 13 | JAVA_OBX = $(ASM6502_PLAYERS:%=java/obx/net/sf/asap/%.obx) 14 | JAVA_XEX = $(addprefix java/xex/net/sf/asap/,xexb.obx xexd.obx xexinfo.obx) 15 | JAR_COMMON = -C java/classes net $(ASM6502_PLAYERS:%=-C java/obx net/sf/asap/%.obx) 16 | 17 | java/asap2wav.jar: $(srcdir)java/asap2wav.MF java/classes/ASAP2WAV.class $(JAVA_OBX) 18 | $(JAR) cfm $@ $< -C java/classes ASAP2WAV.class $(JAR_COMMON) 19 | CLEAN += java/asap2wav.jar 20 | 21 | java/classes/ASAP2WAV.class: $(srcdir)java/ASAP2WAV.java java/classes/net/sf/asap/ASAP.class 22 | $(JAVAC) -d $(@D) -classpath java/classes $< 23 | 24 | java/asap.jar: java/classes/net/sf/asap/ASAP.class $(JAVA_OBX) $(JAVA_XEX) 25 | $(JAR) cf $@ $(JAR_COMMON) $(JAVA_XEX:java/xex/%=-C java/xex %) 26 | CLEAN += java/asap.jar 27 | 28 | java/obx/net/sf/asap/%.obx: 6502/%.obx 29 | $(COPY) 30 | CLEAN += $(JAVA_OBX) 31 | 32 | java/xex/net/sf/asap/%.obx: 6502/%.obx 33 | $(COPY) 34 | CLEANDIR += java/xex 35 | 36 | java/classes/net/sf/asap/ASAP.class: $(srcdir)java/ASAPMusicRoutine.java java/src/net/sf/asap/ASAP.java 37 | $(JAVAC) -d java/classes $(srcdir)java/ASAPMusicRoutine.java java/src/net/sf/asap/*.java 38 | CLEANDIR += java/classes 39 | 40 | java/src/net/sf/asap/ASAP.java: $(call src,asap.fu asap6502.fu asapinfo.fu asapwriter.fu cpu6502.fu flashpack.fu pokey.fu) $(ASM6502_OBX) 41 | $(FUT) -n net.sf.asap 42 | CLEANDIR += java/src 43 | 44 | java/doc: java/src/net/sf/asap/ASAP.java $(srcdir)java/ASAPMusicRoutine.java 45 | $(JAVADOC) -d $@ java/src/net/sf/asap/*.java $(srcdir)java/ASAPMusicRoutine.java 46 | CLEANDIR += java/doc 47 | 48 | include $(srcdir)java/android/android.mk 49 | -------------------------------------------------------------------------------- /java/android/res/layout-land/player.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 | android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> 4 | <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="0px" 5 | android:layout_weight="1" android:drawSelectorOnTop="false" android:listSelector="@drawable/list_selector" /> 6 | <LinearLayout android:id="@+id/playing_panel" android:layout_width="match_parent" android:layout_height="wrap_content" 7 | android:orientation="horizontal" android:background="#611" android:visibility="gone" > 8 | <LinearLayout android:layout_width="0px" android:layout_height="wrap_content" android:layout_weight="2" 9 | android:orientation="vertical"> 10 | <TextView android:id="@+id/playing_name" android:layout_width="match_parent" android:layout_height="wrap_content" 11 | android:gravity="center_horizontal" android:textSize="20sp" /> 12 | <TextView android:id="@+id/playing_author" android:layout_width="match_parent" android:layout_height="wrap_content" 13 | android:gravity="center_horizontal" android:textSize="16sp" /> 14 | <TextView android:id="@+id/playing_date" android:layout_width="match_parent" android:layout_height="wrap_content" 15 | android:gravity="center_horizontal" android:textSize="16sp" /> 16 | <TextView android:id="@+id/playing_song" android:layout_width="match_parent" android:layout_height="wrap_content" 17 | android:gravity="center_horizontal" android:textSize="16sp" /> 18 | </LinearLayout> 19 | <LinearLayout android:layout_width="0px" android:layout_height="wrap_content" android:layout_weight="1" 20 | android:layout_gravity="bottom" android:orientation="vertical"> 21 | <include layout="@layout/buttons_seekbar" /> 22 | </LinearLayout> 23 | </LinearLayout> 24 | </LinearLayout> 25 | -------------------------------------------------------------------------------- /java/android/Util.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Util.java - ASAP for Android 3 | * 4 | * Copyright (C) 2010-2023 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | package net.sf.asap; 25 | 26 | import android.content.Context; 27 | import android.net.Uri; 28 | import java.io.InputStreamReader; 29 | import java.io.IOException; 30 | import java.io.LineNumberReader; 31 | 32 | class Util 33 | { 34 | static final Uri asmaRoot = Uri.fromParts("asma", "", null); 35 | 36 | static Uri getAsmaUri(String path) 37 | { 38 | return Uri.fromParts("asma", path, null); 39 | } 40 | 41 | static LineNumberReader openIndex(Context context) throws IOException 42 | { 43 | return new LineNumberReader(new InputStreamReader(context.getAssets().open("index.txt"))); 44 | } 45 | 46 | static boolean matches(String value, String query) 47 | { 48 | int pos = -1; 49 | do { 50 | if (value.regionMatches(true, ++pos, query, 0, query.length()) 51 | || (pos + 1 < value.length() && value.charAt(pos) == '(' && value.regionMatches(true, ++pos, query, 0, query.length()))) 52 | return true; 53 | pos = value.indexOf(' ', pos); 54 | } while (pos >= 0); 55 | return false; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /java/android/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 | package="net.sf.asap" android:versionCode="530" android:versionName="5.3.0" android:installLocation="auto"> 4 | <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" /> 5 | <uses-feature android:name="android.hardware.touchscreen" android:required="false" /> 6 | <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> 7 | <application android:label="@string/app_name" android:description="@string/app_description" 8 | android:theme="@style/Theme" android:icon="@drawable/icon" android:banner="@drawable/banner" > 9 | <activity android:name=".Player" android:exported="true"> 10 | <intent-filter> 11 | <action android:name="android.intent.action.MAIN" /> 12 | <action android:name="android.intent.action.SEARCH" /> 13 | <category android:name="android.intent.category.LAUNCHER" /> 14 | <category android:name="android.intent.category.LEANBACK_LAUNCHER" /> 15 | </intent-filter> 16 | <intent-filter android:autoVerify="true"> 17 | <action android:name="android.intent.action.VIEW" /> 18 | <category android:name="android.intent.category.DEFAULT" /> 19 | <category android:name="android.intent.category.BROWSABLE" /> 20 | <data android:scheme="http" /> 21 | <data android:scheme="https" /> 22 | <data android:host="asma.atari.org" android:path="/asmadb/asma.html" /> 23 | </intent-filter> 24 | <meta-data android:name="android.app.searchable" android:resource="@xml/searchable" /> 25 | </activity> 26 | <provider android:name=".ArchiveSuggestionsProvider" android:authorities="net.sf.asap.ArchiveSuggestionsProvider" /> 27 | <service android:name=".PlayerService" android:exported="true" android:foregroundServiceType="mediaPlayback"> 28 | <intent-filter> 29 | <action android:name="android.media.browse.MediaBrowserService" /> 30 | </intent-filter> 31 | </service> 32 | </application> 33 | </manifest> 34 | -------------------------------------------------------------------------------- /test/RESULTS.xml: -------------------------------------------------------------------------------- 1 | <?xml-stylesheet type="text/xsl" href="RESULTS.xsl" ?> 2 | <tests> 3 | <test name="antic_nmires"> 4 | <fail on="Atari800 2.2.1" /> 5 | <fail on="Atari++ 1.60" /> 6 | <fail on="Altirra 1.9" /> 7 | <fail on="ASAP 2.1.2" /> 8 | <pass on="ASAP 3.0.0" /> 9 | </test> 10 | <test name="antic_nmist"> 11 | <pass on="Atari800 2.2.1" /> 12 | <fail on="Atari++ 1.60" /> 13 | <pass on="Altirra 1.9" /> 14 | <fail on="ASAP 2.1.2" /> 15 | <pass on="ASAP 3.0.0" /> 16 | </test> 17 | <test name="antic_vcount"> 18 | <fail on="Atari800 2.2.1" /> 19 | <fail on="Atari++ 1.60" /> 20 | <pass on="Altirra 1.9" /> 21 | <fail on="ASAP 2.1.2" /> 22 | <pass on="ASAP 3.0.0" /> 23 | </test> 24 | <test name="antic_wsync"> 25 | <fail on="Atari800 2.2.1" /> 26 | <fail on="Atari++ 1.60" /> 27 | <pass on="Altirra 1.9" /> 28 | <fail on="ASAP 2.1.2" /> 29 | <fail on="ASAP 3.0.0" /> 30 | </test> 31 | <test name="cpu_anx"> 32 | <pass on="Atari800 2.2.1" /> 33 | <fail on="Atari++ 1.60" /> 34 | <pass on="Altirra 1.9" /> 35 | <pass on="ASAP 2.1.2" /> 36 | <pass on="ASAP 3.0.0" /> 37 | </test> 38 | <test name="cpu_decimal"> 39 | <pass on="Atari800 2.2.1" /> 40 | <fail on="Atari++ 1.60" /> 41 | <fail on="Altirra 1.9" /> 42 | <pass on="ASAP 2.1.2" /> 43 | <pass on="ASAP 3.0.0" /> 44 | </test> 45 | <test name="cpu_las"> 46 | <pass on="Atari800 2.2.1" /> 47 | <crash on="Atari++ 1.60" /> 48 | <fail on="Altirra 1.9" /> 49 | <pass on="ASAP 2.1.2" /> 50 | <pass on="ASAP 3.0.0" /> 51 | </test> 52 | <test name="cpu_shx"> 53 | <fail on="Atari800 2.2.1" /> 54 | <crash on="Atari++ 1.60" /> 55 | <pass on="Altirra 1.9" /> 56 | <fail on="ASAP 2.1.2" /> 57 | <pass on="ASAP 3.0.0" /> 58 | </test> 59 | <test name="gtia_consol"> 60 | <pass on="Atari800 2.2.1" /> 61 | <fail on="Atari++ 1.60" /> 62 | <pass on="Altirra 1.9" /> 63 | <fail on="ASAP 2.1.2" /> 64 | <pass on="ASAP 3.0.0" /> 65 | </test> 66 | <test name="pokey_random"> 67 | <fail on="Atari800 2.2.1" /> 68 | <fail on="Atari++ 1.60" /> 69 | <pass on="Altirra 1.9" /> 70 | <fail on="ASAP 2.1.2" /> 71 | <fail on="ASAP 3.0.0" /> 72 | </test> 73 | </tests> 74 | -------------------------------------------------------------------------------- /test/pokey_timerirq.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "POKEY Timer IRQ Test"',13,10 6 | dta c'DATE "07/06/2011"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 00:10',13,10 10 | opt h+ 11 | eif 12 | 13 | scrptr equ $8a ; 2 bytes 14 | printptr equ $8c ; 2 bytes 15 | 16 | org f:$3000 17 | main 18 | :SAP mwa #$1000 scrptr 19 | lda <title 20 | ldx >title 21 | jsr print 22 | 23 | :!SAP sei:inc ^4e 24 | :!SAP inc ^40 25 | :!SAP mva #$fe ^31 26 | 27 | ldx #8 28 | test_loop 29 | mwa #irq $fffe 30 | mva #0 ^2f 31 | sta ^2e 32 | cli 33 | mva #$40 ^28 34 | mva #$ff ^20 35 | sta ^29 36 | stx ^20 37 | sta ^4a 38 | mva #3 ^2f 39 | lsr @ 40 | sta ^2e 41 | sta ^4a 42 | sta ^29 43 | jmp * 44 | 45 | irq 46 | lda ^2a 47 | cmp expected,x 48 | bne error 49 | dex 50 | bpl test_loop 51 | 52 | :!SAP mva $10 ^2e 53 | :!SAP mva #$ff ^31 54 | :!SAP lsr:cli ^4e 55 | lda <pass 56 | ldx >pass 57 | jsr print 58 | mwa #$af30 $d200 59 | jmp * 60 | 61 | error 62 | pha 63 | txa:pha 64 | mva #0 ^28 65 | :!SAP mva $10 ^2e 66 | :!SAP mva #$ff ^31 67 | :!SAP lsr:cli ^4e 68 | lda <fail 69 | ldx >fail 70 | jsr print 71 | pla 72 | jsr put_hex_byte 73 | pla 74 | jsr put_hex_byte 75 | lda #$9b 76 | jsr put_char 77 | mwa #$cfa0 $d200 78 | jmp * 79 | 80 | put_hex_byte 81 | pha 82 | :4 lsr @ 83 | jsr put_hex_nibble 84 | pla 85 | and #$f 86 | put_hex_nibble 87 | cmp #10 88 | sed 89 | adc #'0' 90 | cld 91 | put_char 92 | ift SAP 93 | sta (scrptr),0 94 | inw scrptr 95 | rts 96 | els 97 | mvx #11 $342 98 | mwx #0 $348 99 | jmp $e456 100 | eif 101 | 102 | print 103 | sta printptr 104 | stx printptr+1 105 | jmp print_2 106 | print_1 107 | jsr put_char 108 | inw printptr 109 | print_2 110 | lda (printptr),0 111 | bne print_1 112 | rts 113 | 114 | expected 115 | :3 dta $30 116 | :3 dta $86 117 | :3 dta $10 118 | 119 | title dta c'POKEY: Timer IRQ...',0 120 | pass dta c'Pass',$9b,0 121 | fail dta c'FAIL.',$9b,0 122 | 123 | ift !SAP 124 | run main 125 | eif 126 | -------------------------------------------------------------------------------- /win32/settings_dlg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * settings_dlg.h - settings dialog box 3 | * 4 | * Copyright (C) 2007-2019 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #include <windows.h> 25 | #include <stdbool.h> 26 | 27 | #ifdef __cplusplus 28 | extern "C" { 29 | #endif 30 | 31 | #define DEFAULT_SONG_LENGTH 180 32 | #define DEFAULT_SILENCE_SECONDS 2 33 | 34 | #define IDD_SETTINGS 400 35 | #define IDC_UNLIMITED 401 36 | #define IDC_LIMITED 402 37 | #define IDC_MINUTES 403 38 | #define IDC_SECONDS 404 39 | #define IDC_SILENCE 405 40 | #define IDC_SILSECONDS 406 41 | #define IDC_LOOPS 407 42 | #define IDC_NOLOOPS 408 43 | #define IDC_MUTE1 411 44 | 45 | #ifdef FOOBAR2000 46 | void enableTimeInput(HWND hDlg, bool enable); 47 | void setFocusAndSelect(HWND hDlg, int nID); 48 | void settingsDialogSet(HWND hDlg, int song_length, int silence_seconds, bool play_loops, int mute_mask); 49 | #else 50 | extern ASAP *asap; 51 | extern int song_length; 52 | extern int silence_seconds; 53 | extern bool play_loops; 54 | extern int mute_mask; 55 | bool settingsDialog(HINSTANCE hInstance, HWND hwndParent); 56 | int getSongDurationInternal(const ASAPInfo *module_info, int song, ASAP *asap); 57 | #define getSongDuration(module_info, song) getSongDurationInternal(module_info, song, NULL) 58 | int playSong(int song); 59 | #endif 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | -------------------------------------------------------------------------------- /win32/rmt/apokeysnd_dll.c: -------------------------------------------------------------------------------- 1 | /* 2 | * apokeysnd_dll.c - POKEY sound emulator for Raster Music Tracker 3 | * 4 | * Copyright (C) 2008-2023 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #include <stddef.h> 25 | #include "pokey.h" 26 | 27 | static PokeyPair *pokeys = NULL; 28 | 29 | __declspec(dllexport) void APokeySound_Initialize(bool stereo) 30 | { 31 | PokeyPair_Delete(pokeys); 32 | pokeys = PokeyPair_New(); 33 | PokeyPair_Initialize(pokeys, false, stereo, 44100); 34 | PokeyPair_StartFrame(pokeys); 35 | } 36 | 37 | __declspec(dllexport) void APokeySound_PutByte(int addr, int data) 38 | { 39 | PokeyPair_Poke(pokeys, addr, data, 0); 40 | } 41 | 42 | __declspec(dllexport) int APokeySound_GetRandom(int addr, int cycle) 43 | { 44 | return PokeyPair_Peek(pokeys, addr, cycle); 45 | } 46 | 47 | __declspec(dllexport) int APokeySound_Generate(int cycles, unsigned char *buffer, int depth) 48 | { 49 | int len = PokeyPair_EndFrame(pokeys, cycles); 50 | len = PokeyPair_Generate(pokeys, buffer, 0, len, depth == 16 ? ASAPSampleFormat_S16_L_E : ASAPSampleFormat_U8); 51 | PokeyPair_StartFrame(pokeys); 52 | return len; 53 | } 54 | 55 | __declspec(dllexport) void APokeySound_About(const char **name, const char **author, const char **description) 56 | { 57 | *name = "Another POKEY Sound Emulator, v5.3.0"; 58 | *author = "Piotr Fusik, (C) 2007-2023"; 59 | *description = "Part of ASAP, http://asap.sourceforge.net"; 60 | } 61 | -------------------------------------------------------------------------------- /www/web.xml: -------------------------------------------------------------------------------- 1 | <page title="Web"> 2 | <script type="module"> 3 | import { asapWeb } from "./asapweb.js"; 4 | function openFiles() 5 | { 6 | const files = this.files; 7 | const select = document.getElementById("fileSelect"); 8 | switch (files.length) { 9 | case 0: 10 | alert("No supported file selected"); 11 | return; 12 | case 1: 13 | select.style.display = "none"; 14 | break; 15 | default: 16 | select.innerHTML = ""; 17 | for (const file of files) 18 | select.add(new Option(file.name)); 19 | select.style.display = ""; 20 | break; 21 | } 22 | document.getElementById("pauseButton").style.display = ""; 23 | asapWeb.onUpdate = update; 24 | asapWeb.playFile(files[0]); 25 | } 26 | function update() 27 | { 28 | const seekBar = document.getElementById("seekBar"); 29 | seekBar.style.display = ""; 30 | const info = asapWeb.asap.getInfo(); 31 | seekBar.max = info.getDuration(info.getDefaultSong()); 32 | seekBar.value = asapWeb.asap.getPosition(); 33 | } 34 | function selectFile() 35 | { 36 | asapWeb.playFile(document.getElementById("fileInput").files[this.selectedIndex]); 37 | } 38 | document.getElementById("fileInput").addEventListener("change", openFiles); 39 | document.getElementById("fileSelect").addEventListener("change", selectFile); 40 | document.getElementById("pauseButton").addEventListener("click", () => asapWeb.togglePause()); 41 | document.getElementById("seekBar").addEventListener("input", function() { asapWeb.seek(this.value); }); 42 | </script> 43 | <p>Play your local Atari 8-bit chiptunes on this page. 44 | Select one or more files from your device. The files will <em>not</em> be uploaded, but played right in your browser using JavaScript.</p> 45 | <p>Select file(s): 46 | <input id="fileInput" type="file" multiple="multiple" accept=".sap,.cmc,.cm3,.cmr,.cms,.dmc,.dlt,.mpt,.mpd,.rmt,.tmc,.tm8,.tm2,.fc" /> 47 | <select id="fileSelect" style="display: none"> </select> 48 | <input id="pauseButton" type="button" value="Pause" style="display: none" /> 49 | <input id="seekBar" type="range" style="display: none" /> 50 | </p> 51 | <p>To play something from the ASMA archive without downloading it, use search on the <a href="http://asma.atari.org">ASMA website</a>.</p> 52 | </page> 53 | -------------------------------------------------------------------------------- /astil.h: -------------------------------------------------------------------------------- 1 | /* 2 | * astil.h - another SID/SAP Tune Information List parser 3 | * 4 | * Copyright (C) 2011-2019 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef _ASTIL_H_ 25 | #define _ASTIL_H_ 26 | 27 | #include <stdbool.h> 28 | 29 | #ifdef __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | typedef struct ASTIL ASTIL; 34 | typedef struct ASTILCover ASTILCover; 35 | 36 | ASTIL *ASTIL_New(void); 37 | void ASTIL_Delete(ASTIL *self); 38 | bool ASTIL_Load(ASTIL *self, const char *filename, int song); 39 | const char *ASTIL_GetStilFilename(const ASTIL *self); 40 | /* If true, the following strings are expected to be UTF-8 encoded, 41 | otherwise it's an old STIL.txt, ASCII or Windows-1250 maybe? */ 42 | bool ASTIL_IsUTF8(const ASTIL *self); 43 | const char *ASTIL_GetTitle(const ASTIL *self); 44 | const char *ASTIL_GetAuthor(const ASTIL *self); 45 | const char *ASTIL_GetDirectoryComment(const ASTIL *self); 46 | const char *ASTIL_GetFileComment(const ASTIL *self); 47 | const char *ASTIL_GetSongComment(const ASTIL *self); 48 | const ASTILCover *ASTIL_GetCover(const ASTIL *self, int i); 49 | 50 | int ASTILCover_GetStartSeconds(const ASTILCover *self); 51 | int ASTILCover_GetEndSeconds(const ASTILCover *self); 52 | const char *ASTILCover_GetTitleAndSource(const ASTILCover *self); 53 | const char *ASTILCover_GetArtist(const ASTILCover *self); 54 | const char *ASTILCover_GetComment(const ASTILCover *self); 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif 59 | #endif 60 | -------------------------------------------------------------------------------- /win32/setup/license.rtf: -------------------------------------------------------------------------------- 1 | {\rtf1\ansi\ansicpg1252 2 | {\fonttbl {\f0\fswiss\fcharset0 Arial;}} 3 | \f0\sa100\fs18\lang1033 4 | 5 | Copyright (C) 2005-2023 - Piotr Fusik 6 | 7 | \par\ql 8 | ASAP is free. You don't have to pay for it, and you can use it 9 | any way you want. It is developed as an Open Source project under the 10 | GNU General Public License (GPL). That means you have full access to 11 | the source code of this program. You can find it on our website at 12 | http://asap.sourceforge.net/ 13 | 14 | \par 15 | Should you wish to modify or redistribute this program, or any part of it, 16 | you should read the full terms and conditions set out in the license 17 | agreement before doing so. A copy of the license is in the COPYING file 18 | attached to the source code. 19 | 20 | \par 21 | If you simply wish to install and use this software, you need only be aware of 22 | the disclaimer conditions in the license, which are set out below. 23 | 24 | \par\b 25 | NO WARRANTY 26 | 27 | \par\b0 28 | Because the program is licensed free of charge, there is no warranty 29 | for the program, to the extent permitted by applicable law. Except when 30 | otherwise stated in writing the copyright holders and/or other parties 31 | provide the program "as is" without warranty of any kind, either expressed 32 | or implied, including, but not limited to, the implied warranties of 33 | merchantability and fitness for a particular purpose. The entire risk as 34 | to the quality and performance of the program is with you. Should the 35 | program prove defective, you assume the cost of all necessary servicing, 36 | repair or correction. 37 | 38 | \par 39 | In no event unless required by applicable law or agreed to in writing 40 | will any copyright holder, or any other party who may modify and/or 41 | redistribute the program as permitted above, be liable to you for damages, 42 | including any general, special, incidental or consequential damages arising 43 | out of the use or inability to use the program (including but not limited 44 | to loss of data or data being rendered inaccurate or losses sustained by 45 | you or third parties or a failure of the program to operate with any other 46 | programs), even if such holder or other party has been advised of the 47 | possibility of such damages. 48 | } 49 | -------------------------------------------------------------------------------- /test/formats.asx: -------------------------------------------------------------------------------- 1 | cmc 2 | dta c' cmc data file '*,$8e,$95,$0d,$20 3 | dta 3 ; tempo 4 | :64 dta l(pattern) 5 | :64 dta h(pattern) 6 | ; pattern=$ffff => no pattern 7 | :26 dta 1,2,3,4,5,6 ; 1-4 instrument params, 5-6: accent map 8 | :26 dta 1,2,3,4,5,6,7,8 ; instrument envelope BADCFE... 9 | :$55 dta 1 ; track 1 10 | :$55 dta 2 ; track 2 11 | :$55 dta 3 ; track 3 12 | dta 0xff 13 | ; offset=$300 14 | ; patterns... 15 | 16 | mpt 17 | :32 dta a(instr) 18 | ; instr=0 => no instrument 19 | :64 dta a(pattern) 20 | ; pattern=0 => no pattern 21 | :4*64 dta 0 ; note2frequency 22 | :4 dta l(track) 23 | :4 dta h(track) 24 | dta $40 ; pattern_len 25 | dta 6 ; tempo 26 | ; track1 27 | ; track2 28 | ; track3 29 | ; track4 30 | ; instruments... 31 | ; patterns... 32 | 33 | rmt 34 | dta c'RMT4' ; c'RMT8' 35 | dta $40 ; pattern_len 36 | dta 6 ; tempo 37 | dta 1 ; per frame 38 | dta 1 ; instrspeed 39 | dta a(instrtable,patltable,pathtable,song) 40 | :x dta a(instr) ; instrtable 41 | :x dta l(pattern) ; patltable 42 | :x dta h(pattern) ; pathtable 43 | ; instruments 44 | ; patterns 45 | ; song 46 | :x dta b(1,2,3,4) ; 8 if RMT8 47 | dta $fe,pos,a(songpos) ; jmp in song 48 | 49 | tmc 50 | :30 dta c'T' ; title 51 | dta 2 ; tempo 52 | dta 4 ; per frame 53 | :64 dta l(instr) 54 | :64 dta h(instr) 55 | ; instr=0 => no instr 56 | :128 dta l(pattern) 57 | :128 dta h(pattern) 58 | :16*x dta 0 ; song 59 | :80*x dta 0 ; instruments 60 | ; patterns 61 | 62 | tm2 63 | dta 14,21,13+128,c'TMC SONG FILE 2.0'*,13+128,21,14 64 | dta a($1580) ; total bytes in memory 65 | dta 1,16,20,0,0 ; POKEY config? 66 | dta 5 ; tempo 67 | dta 1 ; per frame 68 | dta c' ' 69 | :30 dta c'T' ; title 1st line 70 | dta c' ' 71 | dta c' ' 72 | :30 dta c'T' ; title 2nd line 73 | dta c' ' 74 | dta c' ' 75 | :30 dta c'T' ; title 3rd line 76 | dta c' ' 77 | :128 dta l(instr) 78 | :256 dta l(pattern) 79 | :256 dta h(pattern) 80 | :128 dta h(instr) 81 | ; instr=0 => no instr 82 | ; song data 83 | :x dta pattern7,transp7,...pattern0,transp0,patlen 84 | ; patlen=0 = stop, patlen>=$80 = jump transp0 85 | ; instruments&patterns 86 | 87 | fc ; no DOS header 88 | dta 'F'-' ','C'-' ' 89 | dta tempo 90 | :256 dta track1 91 | :256 dta track2 92 | :256 dta track3 93 | :32 dta env,audc,depth,effect ; instruments 94 | :64*x dta 0 ; patterns 95 | :32*x dta 0 ; envelopes 96 | -------------------------------------------------------------------------------- /win32/winamp/out.h: -------------------------------------------------------------------------------- 1 | #define OUT_VER 0x10 2 | 3 | typedef struct 4 | { 5 | int version; // module version (OUT_VER) 6 | char *description; // description of module, with version string 7 | int id; // module id. each input module gets its own. non-nullsoft modules should 8 | // be >= 65536. 9 | 10 | HWND hMainWindow; // winamp's main window (filled in by winamp) 11 | HINSTANCE hDllInstance; // DLL instance handle (filled in by winamp) 12 | 13 | void (*Config)(HWND hwndParent); // configuration dialog 14 | void (*About)(HWND hwndParent); // about dialog 15 | 16 | void (*Init)(); // called when loaded 17 | void (*Quit)(); // called when unloaded 18 | 19 | int (*Open)(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms); 20 | // returns >=0 on success, <0 on failure 21 | // NOTENOTENOTE: bufferlenms and prebufferms are ignored in most if not all output plug-ins. 22 | // ... so don't expect the max latency returned to be what you asked for. 23 | // returns max latency in ms (0 for diskwriters, etc) 24 | // bufferlenms and prebufferms must be in ms. 0 to use defaults. 25 | // prebufferms must be <= bufferlenms 26 | 27 | void (*Close)(); // close the ol' output device. 28 | 29 | int (*Write)(char *buf, int len); 30 | // 0 on success. Len == bytes to write (<= 8192 always). buf is straight audio data. 31 | // 1 returns not able to write (yet). Non-blocking, always. 32 | 33 | int (*CanWrite)(); // returns number of bytes possible to write at a given time. 34 | // Never will decrease unless you call Write (or Close, heh) 35 | 36 | int (*IsPlaying)(); // non0 if output is still going or if data in buffers waiting to be 37 | // written (i.e. closing while IsPlaying() returns 1 would truncate the song 38 | 39 | int (*Pause)(int pause); // returns previous pause state 40 | 41 | void (*SetVolume)(int volume); // volume is 0-255 42 | void (*SetPan)(int pan); // pan is -128 to 128 43 | 44 | void (*Flush)(int t); // flushes buffers and restarts output at time t (in ms) 45 | // (used for seeking) 46 | 47 | int (*GetOutputTime)(); // returns played time in MS 48 | int (*GetWrittenTime)(); // returns time written in MS (used for synching up vis stuff) 49 | 50 | } Out_Module; 51 | 52 | 53 | -------------------------------------------------------------------------------- /win32/info_dlg.h: -------------------------------------------------------------------------------- 1 | /* 2 | * info_dlg.h - file information dialog box 3 | * 4 | * Copyright (C) 2007-2022 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #include <windows.h> 25 | #include <tchar.h> 26 | #include <stdbool.h> 27 | 28 | #ifdef __cplusplus 29 | extern "C" { 30 | #endif 31 | 32 | #define IDD_INFO 300 33 | #define IDC_PLAYING 301 34 | #define IDC_FILENAME 302 35 | #define IDC_AUTHOR 303 36 | #define IDC_NAME 304 37 | #define IDC_DATE 305 38 | #define IDC_PICKDATE 306 39 | #define IDC_SONGNO 307 40 | #define IDC_TIME 308 41 | #define IDC_LOOP 309 42 | #define IDC_NTSC 310 43 | #define IDC_TECHINFO 311 44 | #define IDC_STILFILE 312 45 | #define IDC_STILINFO 313 46 | #define IDC_SAVE 314 47 | #define IDC_SAVEAS 315 48 | 49 | #define IDD_PROGRESS 500 50 | #define IDC_PROGRESS 501 51 | 52 | void combineFilenameExt(LPTSTR dest, LPCTSTR filename, LPCTSTR ext); 53 | bool loadModule(LPCTSTR filename, BYTE *module, int *module_len); 54 | 55 | extern HWND infoDialog; 56 | void showInfoDialog(HINSTANCE hInstance, HWND hwndParent, LPCTSTR filename, int song); 57 | void updateInfoDialog(LPCTSTR filename, int song); 58 | void setPlayingSong(LPCTSTR filename, int song); 59 | #ifdef XMPLAY 60 | const ASTIL *getPlayingASTIL(void); 61 | #endif 62 | #if defined(WINAMP) || defined(FOOBAR2000) || defined(XMPLAY) 63 | #define PLAYING_INFO 64 | extern bool playing_info; 65 | void onUpdatePlayingInfo(void); 66 | #endif 67 | 68 | #ifdef __cplusplus 69 | } 70 | #endif 71 | -------------------------------------------------------------------------------- /test/timevsnative.c: -------------------------------------------------------------------------------- 1 | #include <stdio.h> 2 | #include <stdlib.h> 3 | #include <string.h> 4 | 5 | #include "asap.h" 6 | 7 | static int print_times(ASAPInfo *info, const char *filename, const unsigned char *module, int module_len) 8 | { 9 | int sum = 0; 10 | int song; 11 | if (!ASAPInfo_Load(info, filename, module, module_len)) { 12 | putchar('\n'); 13 | fprintf(stderr, "%s: cannot load\n", filename); 14 | exit(1); 15 | } 16 | for (song = 0; song < ASAPInfo_GetSongs(info); song++) { 17 | int duration = ASAPInfo_GetDuration(info, song); 18 | unsigned char s[ASAPWriter_MAX_DURATION_LENGTH + 1]; 19 | int len = ASAPWriter_DurationToString(s, duration); 20 | sum += duration; 21 | putchar(song == 0 ? '\t' : ','); 22 | if (len == 0) 23 | printf("???"); 24 | else { 25 | s[len] = '\0'; 26 | fputs((const char *) s, stdout); 27 | if (ASAPInfo_GetLoop(info, song)) 28 | printf(" LOOP"); 29 | } 30 | } 31 | return sum; 32 | } 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | ASAPInfo *sap_info = ASAPInfo_New(); 37 | ASAPInfo *native_info = ASAPInfo_New(); 38 | if (argc != 2) { 39 | printf("Usage: timevsnative FILE.sap\n"); 40 | return 1; 41 | } 42 | const char *sap_filename = argv[1]; 43 | FILE *fp = fopen(sap_filename, "rb"); 44 | if (fp == NULL) { 45 | fprintf(stderr, "%s: cannot open\n", sap_filename); 46 | return 1; 47 | } 48 | unsigned char sap[ASAPInfo_MAX_MODULE_LENGTH]; 49 | int sap_len = fread(sap, 1, sizeof(sap), fp); 50 | fclose(fp); 51 | fputs(sap_filename, stdout); 52 | int sap_sum = print_times(sap_info, sap_filename, sap, sap_len); 53 | const char *native_ext = ASAPInfo_GetOriginalModuleExt(sap_info, sap, sap_len); 54 | if (native_ext != NULL) { 55 | ASAPWriter *writer = ASAPWriter_New(); 56 | printf("\t%s", native_ext); 57 | char native_filename[FILENAME_MAX]; 58 | sprintf(native_filename, "%.*s.%s", (int) (strrchr(sap_filename, '.') - sap_filename), sap_filename, native_ext); 59 | unsigned char native[ASAPInfo_MAX_MODULE_LENGTH]; 60 | ASAPWriter_SetOutput(writer, native, 0, sizeof(native)); 61 | int native_len = ASAPWriter_Write(writer, native_filename, sap_info, sap, sap_len, false); 62 | ASAPWriter_Delete(writer); 63 | if (native_len >= 0) { 64 | int native_sum = print_times(native_info, native_filename, native, native_len); 65 | printf("\t%d", abs(native_sum - sap_sum) / 1000); 66 | } 67 | } 68 | putchar('\n'); 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /test/benchmark/sap_benchmark.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * sap_benchmark.cpp - SAP Library benchmark 3 | * 4 | * Copyright (C) 2013-2019 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #include <stdio.h> 25 | #include <stdlib.h> 26 | 27 | #include "asap.h" 28 | #include "sapLib.h" 29 | 30 | #define BUF_SIZE 4096 31 | 32 | static int get_samples_count(const char *filename) 33 | { 34 | /* SAP Library doesn't understand TIME so ask ASAP */ 35 | FILE *fp = fopen(filename, "rb"); 36 | if (fp == NULL) { 37 | fprintf(stderr, "Cannot open %s\n", filename); 38 | exit(1); 39 | } 40 | unsigned char content[ASAPInfo_MAX_MODULE_LENGTH]; 41 | int content_len = fread(content, 1, sizeof(content), fp); 42 | fclose(fp); 43 | 44 | ASAPInfo *info = ASAPInfo_New(); 45 | if (!ASAPInfo_Load(info, filename, content, content_len)) { 46 | fprintf(stderr, "ASAP doesn't understand %s\n", filename); 47 | exit(1); 48 | } 49 | /* milliseconds to samples */ 50 | return ASAPInfo_GetDuration(info, 0) * (44100 / 100) / 10; 51 | } 52 | 53 | int main(int argc, char **argv) 54 | { 55 | if (argc != 2) { 56 | fprintf(stderr, "Usage: sap_benchmark SAPFILE\n"); 57 | return 1; 58 | } 59 | sapMUSICstrc *sap = sapLoadMusicFile(argv[1]); 60 | if (sap == NULL) { 61 | fprintf(stderr, "SAP doesn't understand %s\n", argv[1]); 62 | return 1; 63 | } 64 | sapPlaySong(0); 65 | int samples = get_samples_count(argv[1]); 66 | while (samples > 0) { 67 | short buf[BUF_SIZE * 2]; 68 | int len = samples >= BUF_SIZE ? BUF_SIZE : samples; 69 | /* for stereo, sapRenderBuffer fills len*2 samples */ 70 | sapRenderBuffer(buf, len); 71 | samples -= len; 72 | } 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /java/android/FileInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * FileInfo.java - ASAP for Android 3 | * 4 | * Copyright (C) 2010-2023 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | package net.sf.asap; 25 | 26 | import android.content.Context; 27 | import java.io.IOException; 28 | import java.io.LineNumberReader; 29 | import java.util.ArrayList; 30 | 31 | class FileInfo 32 | { 33 | final String filename; 34 | final String title; 35 | final String author; 36 | final String date; 37 | final int songs; 38 | 39 | private FileInfo(String filename, String title, String author, String date, int songs) 40 | { 41 | this.filename = filename; 42 | this.title = title; 43 | this.author = author; 44 | this.date = date; 45 | this.songs = songs; 46 | } 47 | 48 | @Override 49 | public String toString() 50 | { 51 | return title; 52 | } 53 | 54 | static final FileInfo SHUFFLE_ALL = null; 55 | 56 | static FileInfo[] listIndex(Context context, String query) 57 | { 58 | ArrayList<FileInfo> coll = new ArrayList<FileInfo>(); 59 | if (query == null) 60 | coll.add(SHUFFLE_ALL); 61 | try (LineNumberReader r = Util.openIndex(context)) { 62 | for (;;) { 63 | String name = r.readLine(); 64 | if (name == null) 65 | break; 66 | String title = r.readLine(); 67 | String author = r.readLine(); 68 | String date = r.readLine(); 69 | String songs = r.readLine(); 70 | if (query == null || Util.matches(title, query) || Util.matches(author, query)) 71 | coll.add(new FileInfo(name, title, author, date, Integer.parseInt(songs))); 72 | } 73 | } 74 | catch (IOException ex) { 75 | // shouldn't happen 76 | } 77 | return coll.toArray(new FileInfo[coll.size()]); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /test/pokey_potst.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "POKEY POTST Test"',13,10 6 | dta c'DATE "14/06/2011"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 00:10',13,10 10 | opt h+ 11 | eif 12 | 13 | div5 equ $80 14 | mod5 equ $81 15 | scrptr equ $8a ; 2 bytes 16 | printptr equ $8c ; 2 bytes 17 | 18 | org f:$3000 19 | main 20 | :SAP mwa #$1000 scrptr 21 | lda <title 22 | ldx >title 23 | jsr print 24 | 25 | :!SAP sei:inc ^4e 26 | :!SAP inc ^40 27 | 28 | ; fast POT scan 29 | ldx #1 30 | stx div5 31 | dex 32 | stx 0 33 | ldy #0 34 | test_loop 35 | stx mod5 36 | mva cmps,x cmpd 37 | 38 | mva #0 ^2f 39 | :2 sta ^4a 40 | mva #7 ^2f 41 | sta ^2b 42 | ldx div5 43 | dex:rne 44 | cmpd cmp #0 45 | lda ^28 46 | eor #$ff 47 | cpy #200 48 | adc #0 49 | jne error 50 | 51 | ldx mod5 52 | inx 53 | cpx #5 54 | bcc same5 55 | inc div5 56 | ldx #0 57 | same5 iny 58 | bne test_loop 59 | 60 | ; slow POT scan (114 divisor) 61 | mva #0 ^2f 62 | :2 sta ^4a 63 | mva #3 ^2f 64 | :2 sta ^4a 65 | sta ^2b 66 | ldx #227 67 | delay_loop stx ^4a 68 | dex:bne delay_loop 69 | ldx #13 70 | dex:rne 71 | cmp 0,x 72 | lda ^28 73 | cmp #$ff 74 | bne error 75 | 76 | mva #0 ^2f 77 | :2 sta ^4a 78 | mva #3 ^2f 79 | :2 sta ^4a 80 | sta ^2b 81 | ldx #227 82 | delay2_loop stx ^4a 83 | dex:bne delay2_loop 84 | ldx #14 85 | dex:rne 86 | lda ^28 87 | bne error 88 | 89 | ; slow POT scan, 114 divisor stopped 90 | mva #0 ^2f 91 | :2 sta ^4a 92 | sta ^2b 93 | :5 sta ^4a 94 | ldx #3 95 | lda ^28 96 | stx ^2f 97 | beq error 98 | 99 | lsr:cli ^4e 100 | lda <pass 101 | ldx >pass 102 | jsr print 103 | mwa #$af30 $d200 104 | jmp * 105 | 106 | error 107 | lsr:cli ^4e 108 | lda <fail 109 | ldx >fail 110 | jsr print 111 | mwa #$cfa0 $d200 112 | jmp * 113 | 114 | put_char 115 | ift SAP 116 | sta (scrptr),0 117 | inw scrptr 118 | rts 119 | els 120 | mvx #11 $342 121 | mwx #0 $348 122 | jmp $e456 123 | eif 124 | 125 | print 126 | sta printptr 127 | stx printptr+1 128 | jmp print_2 129 | print_1 130 | jsr put_char 131 | inw printptr 132 | print_2 133 | lda (printptr),0 134 | bne print_1 135 | rts 136 | 137 | title dta c'POKEY: POTST...',0 138 | pass dta c'Pass',$9b,0 139 | fail dta c'FAIL.',$9b,0 140 | 141 | cmps dta {cmp #},{cmp 0},{cmp 0,x},{cmp (0),y},{cmp (0,x)} 142 | 143 | ift !SAP 144 | run main 145 | eif 146 | -------------------------------------------------------------------------------- /test/benchmark/gme_benchmark.c: -------------------------------------------------------------------------------- 1 | /* 2 | * gme_benchmark.c - Game_Music_Emu benchmark 3 | * 4 | * Copyright (C) 2013-2019 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #include <stdio.h> 25 | #include <stdlib.h> 26 | 27 | #include "asap.h" 28 | #include "gme.h" 29 | 30 | #define BUF_SIZE 4096 31 | 32 | static int get_stereo_samples_count(const char *filename) 33 | { 34 | /* GME doesn't understand TIME so ask ASAP */ 35 | FILE *fp = fopen(filename, "rb"); 36 | if (fp == NULL) { 37 | fprintf(stderr, "Cannot open %s\n", filename); 38 | exit(1); 39 | } 40 | unsigned char content[ASAPInfo_MAX_MODULE_LENGTH]; 41 | int content_len = fread(content, 1, sizeof(content), fp); 42 | fclose(fp); 43 | 44 | ASAPInfo *info = ASAPInfo_New(); 45 | if (!ASAPInfo_Load(info, filename, content, content_len)) { 46 | fprintf(stderr, "ASAP doesn't understand %s\n", filename); 47 | exit(1); 48 | } 49 | int duration = ASAPInfo_GetDuration(info, 0); 50 | return duration * (44100 / 100) / 10 /* milliseconds to samples */ 51 | * 2; /* always stereo for gme */ 52 | } 53 | 54 | int main(int argc, char **argv) 55 | { 56 | if (argc != 2) { 57 | fprintf(stderr, "Usage: gme_benchmark SAPFILE\n"); 58 | return 1; 59 | } 60 | Music_Emu *gme; 61 | gme_err_t err = gme_open_file(argv[1], &gme, 44100); 62 | if (err != NULL) { 63 | fprintf(stderr, "%s\n", err); 64 | return 1; 65 | } 66 | err = gme_start_track(gme, 0); 67 | if (err != NULL) { 68 | fprintf(stderr, "%s\n", err); 69 | return 1; 70 | } 71 | int samples = get_stereo_samples_count(argv[1]); 72 | while (samples > 0) { 73 | short buf[BUF_SIZE]; 74 | int len = samples >= BUF_SIZE ? BUF_SIZE : samples; 75 | gme_play(gme, len, buf); 76 | samples -= len; 77 | } 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /aatr-stdio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * aatr-stdio.c - another ATR file extractor 3 | * 4 | * Copyright (C) 2012-2019 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #include <stdio.h> 25 | #include "aatr-stdio.h" 26 | #include "aatr.c" 27 | 28 | typedef struct { 29 | AATR base; 30 | FILE *fp; 31 | } AATRStdio; 32 | 33 | static bool AATRStdio_Read(const AATR *self, int offset, uint8_t *buffer, int length) 34 | { 35 | FILE *fp = ((AATRStdio *) self)->fp; 36 | return fseek(fp, offset, SEEK_SET) == 0 37 | && fread(buffer, length, 1, fp) == 1; 38 | } 39 | 40 | AATR *AATRStdio_New(const char *filename) 41 | { 42 | FILE *fp = fopen(filename, "rb"); 43 | if (fp == NULL) 44 | return NULL; 45 | AATRStdio *self = (AATRStdio *) malloc(sizeof(AATRStdio)); 46 | if (self == NULL) { 47 | fclose(fp); 48 | return NULL; 49 | } 50 | static const AATRVtbl vtbl = { AATRStdio_Read }; 51 | self->base.vtbl = &vtbl; 52 | self->fp = fp; 53 | if (!AATR_Open(&self->base)) { 54 | free(self); 55 | fclose(fp); 56 | return NULL; 57 | } 58 | return &self->base; 59 | } 60 | 61 | void AATRStdio_Delete(AATR *self) 62 | { 63 | FILE *fp = ((AATRStdio *) self)->fp; 64 | free(self); 65 | fclose(fp); 66 | } 67 | 68 | #if 0 69 | int main(int argc, char **argv) 70 | { 71 | AATR *disk = AATRStdio_New("C:\\0\\a8\\SV2K12_STUFF_AtariDOS.atr"); 72 | AATRRecursiveLister *lister = AATRRecursiveLister_New(); 73 | AATRFileStream *stream = AATRFileStream_New(); 74 | if (disk == NULL || lister == NULL || stream == NULL) 75 | return 1; 76 | AATRRecursiveLister_Open(lister, disk); 77 | for (;;) { 78 | const char *current_filename = AATRRecursiveLister_NextFile(lister); 79 | if (current_filename == NULL) 80 | break; 81 | AATRFileStream_Open(stream, AATRRecursiveLister_GetDirectory(lister)); 82 | printf("%s (%d)\n", current_filename, AATRFileStream_GetLength(stream)); 83 | } 84 | return 0; 85 | } 86 | #endif 87 | -------------------------------------------------------------------------------- /test/cpu_anx.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "6502 Undocumented ANX Test"',13,10 6 | dta c'DATE "27/11/2010"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 00:10',13,10 10 | opt h+ 11 | eif 12 | 13 | expa equ $80 14 | expnz equ $81 15 | pos equ $89 16 | scrptr equ $8a ; 2 bytes 17 | printptr equ $8c ; 2 bytes 18 | 19 | org f:$3000 20 | main 21 | :SAP mwa #$1000 scrptr 22 | lda <title 23 | ldx >title 24 | jsr print 25 | 26 | ldx #0 27 | loop 28 | stx pos 29 | mva input,x anx+1 30 | and input+1,x 31 | sta expa 32 | php:pla 33 | sta expnz 34 | lda input+1,x 35 | ldx $d20a 36 | anx dta $ab,0 37 | php 38 | cmp expa 39 | bne error 40 | cpx expa 41 | bne error 42 | pla 43 | eor expnz 44 | and #$82 45 | bne error 46 | ldx pos 47 | inx 48 | bne loop 49 | 50 | lda <pass 51 | ldx >pass 52 | jsr print 53 | mwa #$af30 $d200 54 | jmp * 55 | 56 | error 57 | lda <fail 58 | ldx >fail 59 | jsr print 60 | mwa #$cfa0 $d200 61 | jmp * 62 | 63 | put_char 64 | ift SAP 65 | sta (scrptr),0 66 | inw scrptr 67 | rts 68 | els 69 | mvx #11 $342 70 | mwx #0 $348 71 | jmp $e456 72 | eif 73 | 74 | print 75 | sta printptr 76 | stx printptr+1 77 | jmp print_2 78 | print_1 79 | jsr put_char 80 | inw printptr 81 | print_2 82 | lda (printptr),0 83 | bne print_1 84 | rts 85 | 86 | ; just some random data 87 | input 88 | dta $73,$c3,$26,$17,$3b,$9b,$82,$06,$6e,$f8,$c6,$74,$83,$6c,$d6,$7c 89 | dta $5b,$4f,$33,$72,$ef,$55,$69,$3f,$64,$f1,$02,$21,$ea,$51,$ad,$d8 90 | dta $55,$41,$bd,$cc,$c9,$b3,$a7,$30,$78,$41,$ab,$ac,$bc,$61,$49,$94 91 | dta $95,$a0,$b4,$37,$da,$aa,$e2,$50,$0f,$5f,$66,$12,$4d,$c4,$b7,$f4 92 | dta $1b,$1a,$18,$a2,$a2,$df,$b6,$36,$27,$f7,$33,$3a,$33,$e2,$49,$6e 93 | dta $4d,$25,$94,$f2,$b4,$c4,$50,$be,$f8,$0d,$10,$13,$e3,$82,$32,$cb 94 | dta $9a,$1a,$1e,$2a,$52,$bb,$14,$25,$90,$1d,$96,$b9,$54,$e8,$2d,$45 95 | dta $19,$5b,$9b,$86,$0e,$34,$3a,$2c,$77,$35,$9b,$91,$9d,$f8,$17,$a9 96 | dta $2a,$70,$7a,$9e,$6b,$ce,$6f,$35,$4e,$1d,$d2,$6c,$95,$53,$95,$77 97 | dta $17,$27,$5a,$83,$7e,$76,$74,$65,$6e,$74,$6a,$a5,$75,$79,$ac,$02 98 | dta $af,$b5,$a2,$e1,$89,$87,$be,$c3,$87,$cd,$ae,$41,$74,$ea,$69,$8e 99 | dta $ed,$d6,$2a,$1d,$a3,$eb,$17,$5a,$43,$d2,$a7,$0e,$6b,$43,$7b,$73 100 | dta $92,$ec,$d3,$7a,$50,$3b,$3e,$57,$e6,$65,$b9,$c9,$75,$5f,$d8,$3a 101 | dta $ca,$1e,$2c,$33,$26,$dd,$85,$28,$e9,$bd,$45,$34,$8a,$79,$59,$c1 102 | dta $c7,$7c,$10,$9d,$6b,$28,$75,$9e,$a0,$89,$4a,$40,$26,$49,$5b,$54 103 | dta $64,$1a,$48,$49,$b5,$7e,$68,$0f,$d6,$0e,$00,$27,$e2,$26,$62,$d7 104 | 105 | title dta c'CPU: ANX...',0 106 | pass dta c'Pass',$9b,0 107 | fail dta c'FAIL.',$9b,0 108 | 109 | ift !SAP 110 | run main 111 | eif 112 | -------------------------------------------------------------------------------- /6502/xexinfo.asx: -------------------------------------------------------------------------------- 1 | HIDE_AUTHOR equ 0 2 | 3 | font equ $fc00 4 | 5 | ift TEST 6 | 7 | org $8000 8 | scr 9 | dta c'404 Error ' 10 | :8 dta $55 11 | ift HIDE_AUTHOR 12 | hidden 13 | dta c'(press space to show author) ' 14 | dta c' ' 15 | author 16 | eif 17 | dta c'by Grzegorz Kwiatek (Greg) ' 18 | dta c' & Lukasz Sychowicz (X-Ray) ' 19 | date 20 | dta c'01/03/2003 STEREO 02:26' 21 | 22 | dl 23 | :22 dta $70 24 | dta $30,$62,a(scr),8,0 25 | ift HIDE_AUTHOR 26 | dta $42 27 | dl_author 28 | dta a(hidden),2,$10,$42,a(date) 29 | dta $41,a(dl) 30 | show_author 31 | mwa #author dl_author 32 | els 33 | dta 2,2,$10,2 34 | dta $41,a(dl) 35 | eif 36 | 37 | els 38 | 39 | org $fc50 40 | ift HIDE_AUTHOR 41 | dl org *+39 42 | 43 | show_author 44 | org *+10 45 | rts 46 | 47 | els 48 | dl org *+32 49 | dta $41,a(dl) 50 | eif 51 | 52 | eif 53 | 54 | show_info 55 | lda:rne ^4b 56 | sta ^45 57 | mvx #$26 ^16 58 | mvx #$0a ^17 59 | mvx #$21 ^40 60 | mwx #dl ^42 61 | :>font!=>dl ldx >font 62 | stx ^49 63 | 64 | ift TEST 65 | 66 | mwa #vbl $fffa 67 | mva #$40 ^4e 68 | jmp * 69 | 70 | vbl 71 | pha 72 | txa:pha 73 | ldx $d014 74 | dex 75 | seq:ldx #1 76 | jsr countdown 77 | pla:tax 78 | pla:rti 79 | 80 | els 81 | 82 | rts 83 | 84 | eif 85 | 86 | countdown 87 | ift HIDE_AUTHOR 88 | lda #4 89 | bit $d20f 90 | bne no_author 91 | lda $d209 92 | cmp #$21 93 | bne no_author 94 | jsr show_author 95 | no_author 96 | eif 97 | 98 | cld 99 | lda countdown_framerate_lo,x 100 | add #0 101 | sta *-1 102 | lda countdown_framerate_hi,x 103 | adc #0 104 | sta *-1 105 | bcc countdown_skip 106 | lda dl-5 107 | ora dl-4 108 | ora dl-2 109 | ora dl-1 110 | cmp #'1' 111 | ldx #4 112 | bcs countdown_start 113 | countdown_skip 114 | rts 115 | 116 | countdown_wrap 117 | lda #'9' 118 | cpx #3 119 | sne:lda #'5' 120 | sta dl-5,x 121 | countdown_next 122 | dex 123 | countdown_start 124 | lda dl-5,x 125 | cmp #'1' 126 | bcc countdown_wrap 127 | cmp #':' 128 | beq countdown_next 129 | 130 | dec dl-5,x 131 | rts 132 | 133 | countdown_framerate_lo dta l(312*114/2*65536/[1773447/2],262*114*65536/1789772) 134 | countdown_framerate_hi dta h(312*114/2*65536/[1773447/2],262*114*65536/1789772) 135 | 136 | org $100 137 | main 138 | sei 139 | mvy #0 ^4e 140 | lda:rne ^4b 141 | sta ^40 142 | ldx #29 143 | sta:rpl ^00,x- 144 | ; copy font from ROM, reordering from ANTIC codes to ASCII, semigraphics not needed 145 | copy_font_1 146 | stx ^31 ; #$ff 147 | lda:pha $e000,y ; punctuation 148 | lda:pha $e100,y ; uppercase 149 | lda $e300,y ; lowercase 150 | dex:stx ^31 151 | inx 152 | sta font+$300,y ; lowercase 153 | pla:sta font+$200,y ; uppercase 154 | pla:sta font+$100,y ; punctuation 155 | iny 156 | bne copy_font_1 157 | jsr show_info 158 | ert *!=$13a 159 | 160 | ift TEST 161 | jmp * 162 | run main 163 | eif 164 | 165 | end 166 | -------------------------------------------------------------------------------- /test/cpu_ane.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "6502 Undocumented ANE Test"',13,10 6 | dta c'DATE "27/11/2010"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 00:10',13,10 10 | opt h+ 11 | eif 12 | 13 | a equ $80 14 | x equ $81 15 | data equ $82 16 | datae equ $83 17 | andax equ $84 18 | expa equ $85 19 | expnz equ $86 20 | pos equ $89 21 | scrptr equ $8a ; 2 bytes 22 | printptr equ $8c ; 2 bytes 23 | 24 | org f:$3000 25 | main 26 | :SAP mwa #$1000 scrptr 27 | lda <title 28 | ldx >title 29 | jsr print 30 | 31 | ldx #0 32 | loop 33 | stx pos 34 | mva input,x a 35 | mva input+1,x x 36 | mva input+2,x data 37 | 38 | mva data ane+1 39 | ora #$ef 40 | sta datae 41 | lda x 42 | tax 43 | and a 44 | sta andax 45 | and datae 46 | sta expa 47 | lda andax 48 | and data 49 | php:pla 50 | sta expnz 51 | 52 | lda a 53 | ldx x 54 | ane dta $8b,0 55 | php 56 | cmp expa 57 | bne error 58 | cpx x 59 | bne error 60 | pla 61 | eor expnz 62 | and #$82 63 | bne error 64 | ldx pos 65 | inx 66 | bne loop 67 | 68 | lda <pass 69 | ldx >pass 70 | jsr print 71 | mwa #$af30 $d200 72 | jmp * 73 | 74 | error 75 | lda <fail 76 | ldx >fail 77 | jsr print 78 | mwa #$cfa0 $d200 79 | jmp * 80 | 81 | put_char 82 | ift SAP 83 | sta (scrptr),0 84 | inw scrptr 85 | rts 86 | els 87 | mvx #11 $342 88 | mwx #0 $348 89 | jmp $e456 90 | eif 91 | 92 | print 93 | sta printptr 94 | stx printptr+1 95 | jmp print_2 96 | print_1 97 | jsr put_char 98 | inw printptr 99 | print_2 100 | lda (printptr),0 101 | bne print_1 102 | rts 103 | 104 | ; just some random data 105 | input 106 | dta $73,$c3,$26,$17,$3b,$9b,$82,$06,$6e,$f8,$c6,$74,$83,$6c,$d6,$7c 107 | dta $5b,$4f,$33,$72,$ef,$55,$69,$3f,$64,$f1,$02,$21,$ea,$51,$ad,$d8 108 | dta $55,$41,$bd,$cc,$c9,$b3,$a7,$30,$78,$41,$ab,$ac,$bc,$61,$49,$94 109 | dta $95,$a0,$b4,$37,$da,$aa,$e2,$50,$0f,$5f,$66,$12,$4d,$c4,$b7,$f4 110 | dta $1b,$1a,$18,$a2,$a2,$df,$b6,$36,$27,$f7,$33,$3a,$33,$e2,$49,$6e 111 | dta $4d,$25,$94,$f2,$b4,$c4,$50,$be,$f8,$0d,$10,$13,$e3,$82,$32,$cb 112 | dta $9a,$1a,$1e,$2a,$52,$bb,$14,$25,$90,$1d,$96,$b9,$54,$e8,$2d,$45 113 | dta $19,$5b,$9b,$86,$0e,$34,$3a,$2c,$77,$35,$9b,$91,$9d,$f8,$17,$a9 114 | dta $2a,$70,$7a,$9e,$6b,$ce,$6f,$35,$4e,$1d,$d2,$6c,$95,$53,$95,$77 115 | dta $17,$27,$5a,$83,$7e,$76,$74,$65,$6e,$74,$6a,$a5,$75,$79,$ac,$02 116 | dta $af,$b5,$a2,$e1,$89,$87,$be,$c3,$87,$cd,$ae,$41,$74,$ea,$69,$8e 117 | dta $ed,$d6,$2a,$1d,$a3,$eb,$17,$5a,$43,$d2,$a7,$0e,$6b,$43,$7b,$73 118 | dta $92,$ec,$d3,$7a,$50,$3b,$3e,$57,$e6,$65,$b9,$c9,$75,$5f,$d8,$3a 119 | dta $ca,$1e,$2c,$33,$26,$dd,$85,$28,$e9,$bd,$45,$34,$8a,$79,$59,$c1 120 | dta $c7,$7c,$10,$9d,$6b,$28,$75,$9e,$a0,$89,$4a,$40,$26,$49,$5b,$54 121 | dta $64,$1a,$48,$49,$b5,$7e,$68,$0f,$d6,$0e,$00,$27,$e2,$26,$62,$d7 122 | 123 | title dta c'CPU: ANE...',0 124 | pass dta c'Pass',$9b,0 125 | fail dta c'FAIL.',$9b,0 126 | 127 | ift !SAP 128 | run main 129 | eif 130 | -------------------------------------------------------------------------------- /www/formats.xml: -------------------------------------------------------------------------------- 1 | <page title="Formats"> 2 | <h2>Input formats</h2> 3 | <p>ASAP supports the following file formats:</p> 4 | <dl> 5 | <dt>SAP (Slight Atari Player)</dt> 6 | <dd>Designed for playing Atari 8-bit music on a PC. 7 | All other formats can be converted to SAP. 8 | <a href="http://asma.atari.org/">Atari SAP Music Archive (ASMA)</a> 9 | is a single collection of over 6000 SAP files with over 200 hours of playback time. 10 | For technical details of the format, see the <a href="sap-format.html">SAP specification</a>.</dd> 11 | 12 | <dt>CMC (Chaos Music Composer)</dt> 13 | <dd>Atari music editor from early 1990s.</dd> 14 | 15 | <dt>CM3 (CMC "3/4")</dt> 16 | <dd>CMC clone with modified pattern length.</dd> 17 | 18 | <dt>CMR (CMC "Rzog")</dt> 19 | <dd>CMC clone with modified bass sounds.</dd> 20 | 21 | <dt>CMS (Stereo Double CMC)</dt> 22 | <dd>Stereo CMC clone.</dd> 23 | 24 | <dt>DMC (CMC DoublePlay)</dt> 25 | <dd>CMC clone with the 6502 routine executed at double rate of the original CMC.</dd> 26 | 27 | <dt>DLT (Delta Music Composer)</dt> 28 | <dd>Atari music editor from 1990s.</dd> 29 | 30 | <dt>FC (Future Composer)</dt> 31 | <dd>Atari music editor from 1990s.</dd> 32 | 33 | <dt>MPT (Music ProTracker)</dt> 34 | <dd>Atari music editor from 1990s.</dd> 35 | 36 | <dt>MPD (MPT DoublePlay)</dt> 37 | <dd>MPT clone with the 6502 routine executed at double rate of the original MPT.</dd> 38 | 39 | <dt>RMT (<a href="http://raster.infos.cz/atari/rmt/rmt.htm">Raster Music Tracker</a>)</dt> 40 | <dd>Modern Atari music editor running on Windows.</dd> 41 | 42 | <dt>TMC, TM8 (<a href="http://jaskier.atari8.info/">Theta Music Composer</a> 1.x)</dt> 43 | <dd>Atari music editor from late 1990s. 44 | TM8 means it's stereo (8-channel) music while TMC can be either mono or stereo. 45 | ASAP treats both extensions identically and always plays in stereo.</dd> 46 | 47 | <dt>TM2 (<a href="http://jaskier.atari8.info/">Theta Music Composer</a> 2.x)</dt> 48 | <dd>Modern Atari music editor.</dd> 49 | 50 | <dt>STIL (SAP Tune Information List)</dt> 51 | <dd>This isn't a music format. 52 | It's a text file that contains cover information and comments for many music files. 53 | This format is identical to <a href="https://www.hvsc.de/download/C64Music/DOCUMENTS/STIL.faq">C64 STIL</a>. 54 | <code>STIL.txt</code> is distributed with ASMA (see above).</dd> 55 | </dl> 56 | 57 | <p>You can find some test files in <a href="examples.zip">examples.zip</a>.</p> 58 | 59 | <p>For viewing Atari pictures, check out my other project <a href="https://recoil.sourceforge.net/">RECOIL</a>.</p> 60 | 61 | <h2>Subsongs</h2> 62 | <p>One file usually contains one song, but some files contain many songs (<em>"subsongs"</em>). 63 | For example, a SAP file ripped from a game might contain a title song, an in-game song and a "game over" song. 64 | The songs in a file are numbered and one of them is marked as default.</p> 65 | <p>Due to technical restrictions of some general-purpose players, 66 | some plugins cannot play subsongs other than the default one.</p> 67 | </page> 68 | -------------------------------------------------------------------------------- /java/android/Indexer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Indexer.java - prepares text-file index of SAP files 3 | * 4 | * Copyright (C) 2014 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | import java.io.File; 25 | import java.io.FileInputStream; 26 | import java.io.InputStream; 27 | import java.io.IOException; 28 | import java.util.Arrays; 29 | 30 | import net.sf.asap.ASAPInfo; 31 | 32 | class Indexer 33 | { 34 | private static String rootPath; 35 | 36 | /** 37 | * Reads bytes from the stream into the byte array 38 | * until end of stream or array is full. 39 | * @param is source stream 40 | * @param b output array 41 | * @return number of bytes read 42 | */ 43 | private static int readAndClose(InputStream is, byte[] b) throws IOException 44 | { 45 | int got = 0; 46 | int len = b.length; 47 | try { 48 | while (got < len) { 49 | int i = is.read(b, got, len - got); 50 | if (i <= 0) 51 | break; 52 | got += i; 53 | } 54 | } 55 | finally { 56 | is.close(); 57 | } 58 | return got; 59 | } 60 | 61 | private static void process(File dir) throws Exception 62 | { 63 | File[] children = dir.listFiles(); 64 | Arrays.sort(children); 65 | for (File file : children) { 66 | if (file.isDirectory()) 67 | process(file); 68 | else { 69 | String path = file.getPath(); 70 | if (ASAPInfo.isOurFile(path)) { 71 | if (!path.startsWith(rootPath)) 72 | throw new IllegalArgumentException(path); 73 | path = path.substring(rootPath.length()).replace(File.separatorChar, '/'); 74 | byte[] module = new byte[ASAPInfo.MAX_MODULE_LENGTH]; 75 | int moduleLen = readAndClose(new FileInputStream(file), module); 76 | ASAPInfo info = new ASAPInfo(); 77 | info.load(path, module, moduleLen); 78 | System.out.println(path); 79 | System.out.println(info.getTitleOrFilename()); 80 | System.out.println(info.getAuthor()); 81 | System.out.println(info.getDate()); 82 | System.out.println(info.getSongs()); 83 | } 84 | } 85 | } 86 | } 87 | 88 | public static void main(String[] args) throws Exception 89 | { 90 | if (args.length != 1) 91 | throw new IllegalArgumentException("Usage: java Indexer PATH_TO_ASMA >asma.txt"); 92 | File rootDir = new File(args[0]); 93 | rootPath = rootDir.getPath() + File.separatorChar; 94 | process(rootDir); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /asap.spec: -------------------------------------------------------------------------------- 1 | Name: asap 2 | Version: 5.3.0 3 | Release: 1 4 | Summary: Player of Atari 8-bit music 5 | License: GPLv2+ 6 | Source: http://prdownloads.sourceforge.net/asap/asap-%{version}.tar.gz 7 | URL: http://asap.sourceforge.net/ 8 | BuildRequires: gcc 9 | 10 | %description 11 | ASAP is a player of Atari 8-bit music for modern computers. 12 | It emulates the POKEY sound chip and the 6502 processor. 13 | ASAP supports the following file formats: 14 | SAP, CMC, CM3, CMR, CMS, DMC, DLT, MPT, MPD, RMT, TMC, TM8, TM2, FC. 15 | 16 | %package devel 17 | Summary: Development library providing Atari 8-bit music emulation 18 | 19 | %description devel 20 | These are the files needed for compiling programs that use libasap. 21 | 22 | %package vlc 23 | Summary: ASAP plugin for VLC 24 | Requires: vlc 25 | BuildRequires: vlc-devel 26 | 27 | %description vlc 28 | Provides playback of Atari 8-bit music in VLC. 29 | Supports the following file formats: SAP, RMT, FC. 30 | 31 | %package xmms2 32 | Summary: ASAP plugin for XMMS2 33 | Requires: xmms2 34 | BuildRequires: xmms2-devel 35 | 36 | %description xmms2 37 | Provides playback of Atari 8-bit music (SAP format) in XMMS2. 38 | 39 | %prep 40 | %setup -q 41 | 42 | %build 43 | make CFLAGS="%{build_cflags}" LDFLAGS="%{build_ldflags}" asapconv libasap.a asap-vlc asap-xmms2 44 | 45 | %install 46 | make DESTDIR=%{buildroot} prefix=%{_prefix} libdir=%{_libdir} install install-vlc install-xmms2 47 | 48 | %files 49 | %{_bindir}/asapconv 50 | 51 | %files devel 52 | %{_includedir}/asap.h 53 | %{_libdir}/libasap.a 54 | 55 | %files vlc 56 | %{_libdir}/vlc/plugins/demux/libasap_plugin.so 57 | 58 | %files xmms2 59 | %{_libdir}/xmms2/libxmms_asap.so 60 | 61 | %changelog 62 | * Wed Feb 8 2023 Piotr Fusik <fox@scene.pl> 63 | - 5.3.0-1 64 | 65 | * Wed Dec 8 2021 Piotr Fusik <fox@scene.pl> 66 | - 5.2.0-1 67 | 68 | * Tue Nov 30 2021 Piotr Fusik <fox@scene.pl> 69 | - Added the XMMS2 subpackage 70 | - Removed the XMMS subpackage 71 | 72 | * Fri Jul 9 2021 Piotr Fusik <fox@scene.pl> 73 | - 5.1.0-1 74 | 75 | * Sun Jan 19 2020 Piotr Fusik <fox@scene.pl> 76 | - 5.0.1-1 77 | 78 | * Thu Nov 21 2019 Piotr Fusik <fox@scene.pl> 79 | - 5.0.0-1 80 | 81 | * Thu Jan 10 2019 Piotr Fusik <fox@scene.pl> 82 | - 4.0.0-1 83 | 84 | * Sat Aug 12 2017 Piotr Fusik <fox@scene.pl> 85 | - Discontinued GStreamer 86 | 87 | * Mon Jun 23 2014 Piotr Fusik <fox@scene.pl> 88 | - 3.2.0-1 89 | 90 | * Wed Jan 15 2014 Piotr Fusik <fox@scene.pl> 91 | - 3.1.6-1 92 | 93 | * Fri Aug 16 2013 Piotr Fusik <fox@scene.pl> 94 | - 3.1.5-1 95 | - Corrected descriptions of GStreamer and VLC plugins - they don't support all the formats 96 | 97 | * Mon Apr 29 2013 Piotr Fusik <fox@scene.pl> 98 | - 3.1.4-1 99 | - lib64 compatibility 100 | - Removed the Audacious subpackage 101 | 102 | * Tue Dec 4 2012 Piotr Fusik <fox@scene.pl> 103 | - 3.1.3-1 104 | - Added subpackages with GStreamer and VLC plugins 105 | 106 | * Mon Jun 25 2012 Piotr Fusik <fox@scene.pl> 107 | - 3.1.2-1 108 | 109 | * Wed Oct 26 2011 Piotr Fusik <fox@scene.pl> 110 | - 3.1.1-1 111 | 112 | * Sat Sep 24 2011 Piotr Fusik <fox@scene.pl> 113 | - 3.1.0-1 114 | 115 | * Fri Jul 15 2011 Piotr Fusik <fox@scene.pl> 116 | - 3.0.1-1 117 | 118 | * Thu May 19 2011 Piotr Fusik <fox@scene.pl> 119 | - 3.0.0-1 120 | - Added subpackages with Audacious and XMMS plugins 121 | 122 | * Wed Nov 3 2010 Piotr Fusik <fox@scene.pl> 123 | - 2.1.2-1 124 | - Initial packaging 125 | -------------------------------------------------------------------------------- /java/android/proguard.cfg: -------------------------------------------------------------------------------- 1 | # Based on examples/android.pro from ProGuard 4.6. 2 | 3 | -dontpreverify 4 | -repackageclasses '' 5 | -allowaccessmodification 6 | 7 | # don't change package because of the resources 8 | -keep class net.sf.asap.ASAP6502 9 | 10 | # Switch off some optimizations that trip older versions of the Dalvik VM. 11 | -optimizations !code/simplification/arithmetic 12 | 13 | # RemoteViews might need annotations. 14 | -keepattributes *Annotation* 15 | 16 | # Preserve all fundamental application classes. 17 | -keep public class * extends android.app.Activity 18 | -keep public class * extends android.app.Application 19 | -keep public class * extends android.app.Service 20 | -keep public class * extends android.content.BroadcastReceiver 21 | -keep public class * extends android.content.ContentProvider 22 | 23 | # Preserve all View implementations, their special context constructors, and 24 | # their setters. 25 | -keep public class * extends android.view.View { 26 | public <init>(android.content.Context); 27 | public <init>(android.content.Context, android.util.AttributeSet); 28 | public <init>(android.content.Context, android.util.AttributeSet, int); 29 | public void set*(...); 30 | } 31 | 32 | # Preserve all classes that have special context constructors, and the 33 | # constructors themselves. 34 | -keepclasseswithmembers class * { 35 | public <init>(android.content.Context, android.util.AttributeSet); 36 | } 37 | 38 | # Preserve all classes that have special context constructors, and the 39 | # constructors themselves. 40 | -keepclasseswithmembers class * { 41 | public <init>(android.content.Context, android.util.AttributeSet, int); 42 | } 43 | 44 | # Preserve the special fields of all Parcelable implementations. 45 | -keepclassmembers class * implements android.os.Parcelable { 46 | static android.os.Parcelable$Creator CREATOR; 47 | } 48 | 49 | # Preserve static fields of inner classes of R classes that might be accessed 50 | # through introspection. 51 | -keepclassmembers class **.R$* { 52 | public static <fields>; 53 | } 54 | 55 | # Preserve the required interface from the License Verification Library 56 | # (but don't nag the developer if the library is not used at all). 57 | -keep public interface com.android.vending.licensing.ILicensingService 58 | 59 | -dontnote com.android.vending.licensing.ILicensingService 60 | 61 | # Preserve all native method names and the names of their classes. 62 | -keepclasseswithmembernames class * { 63 | native <methods>; 64 | } 65 | 66 | # Preserve the special static methods that are required in all enumeration 67 | # classes. 68 | -keepclassmembers class * extends java.lang.Enum { 69 | public static **[] values(); 70 | public static ** valueOf(java.lang.String); 71 | } 72 | 73 | # Explicitly preserve all serialization members. The Serializable interface 74 | # is only a marker interface, so it wouldn't save them. 75 | # You can comment this out if your application doesn't use serialization. 76 | # If your code contains serializable classes that have to be backward 77 | # compatible, please refer to the manual. 78 | -keepclassmembers class * implements java.io.Serializable { 79 | static final long serialVersionUID; 80 | static final java.io.ObjectStreamField[] serialPersistentFields; 81 | private void writeObject(java.io.ObjectOutputStream); 82 | private void readObject(java.io.ObjectInputStream); 83 | java.lang.Object writeReplace(); 84 | java.lang.Object readResolve(); 85 | } 86 | -------------------------------------------------------------------------------- /test/cpu_las.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "6502 Undocumented LAS Test"',13,10 6 | dta c'DATE "27/11/2010"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 00:10',13,10 10 | opt h+ 11 | eif 12 | 13 | s equ $80 14 | y equ $81 15 | addr equ $82 ; 2 bytes 16 | data equ $84 17 | exp equ $86 18 | expnz equ $87 19 | pos equ $89 20 | scrptr equ $8a ; 2 bytes 21 | printptr equ $8c ; 2 bytes 22 | 23 | area equ $2e00 24 | 25 | org f:$3000 26 | main 27 | :SAP mwa #$1000 scrptr 28 | lda <title 29 | ldx >title 30 | jsr print 31 | 32 | mva >area addr+1 33 | ldx #0 34 | loop 35 | stx pos 36 | mva input,x s 37 | mva input+1,x y 38 | mva input+2,x addr 39 | sta las+1 40 | mva input+3,x data 41 | 42 | lda s 43 | and data 44 | sta exp 45 | php:pla 46 | sta expnz 47 | 48 | ldy y 49 | mva data (addr),y 50 | ldx s 51 | txs 52 | las dta $bb,a(area) 53 | php 54 | cmp exp 55 | bne error 56 | cpx exp 57 | bne error 58 | pla 59 | eor expnz 60 | and #$80 ; TODO: #$82, but Z is unstable 61 | bne error 62 | tsx 63 | cpx exp 64 | bne error 65 | 66 | ldx pos 67 | inx 68 | bne loop 69 | 70 | lda <pass 71 | ldx >pass 72 | jsr print 73 | mwa #$af30 $d200 74 | jmp * 75 | 76 | error 77 | lda <fail 78 | ldx >fail 79 | jsr print 80 | lda addr 81 | jsr put_hex_byte 82 | lda addr+1 83 | jsr put_hex_byte 84 | lda <sequ 85 | ldx >sequ 86 | jsr print 87 | lda s 88 | jsr put_hex_byte 89 | lda <yequ 90 | ldx >yequ 91 | jsr print 92 | lda y 93 | jsr put_hex_byte 94 | lda #$9b 95 | jsr put_char 96 | mwa #$cfa0 $d200 97 | jmp * 98 | 99 | put_hex_byte 100 | pha 101 | :4 lsr @ 102 | jsr put_hex_nibble 103 | pla 104 | and #$f 105 | put_hex_nibble 106 | cmp #10 107 | sed 108 | adc #'0' 109 | cld 110 | put_char 111 | ift SAP 112 | sta (scrptr),0 113 | inw scrptr 114 | rts 115 | els 116 | mvx #11 $342 117 | mwx #0 $348 118 | jmp $e456 119 | eif 120 | 121 | print 122 | sta printptr 123 | stx printptr+1 124 | jmp print_2 125 | print_1 126 | jsr put_char 127 | inw printptr 128 | print_2 129 | lda (printptr),0 130 | bne print_1 131 | rts 132 | 133 | ; just some random data 134 | input 135 | dta $73,$c3,$26,$17,$3b,$9b,$82,$06,$6e,$f8,$c6,$74,$83,$6c,$d6,$7c 136 | dta $5b,$4f,$33,$72,$ef,$55,$69,$3f,$64,$f1,$02,$21,$ea,$51,$ad,$d8 137 | dta $55,$41,$bd,$cc,$c9,$b3,$a7,$30,$78,$41,$ab,$ac,$bc,$61,$49,$94 138 | dta $95,$a0,$b4,$37,$da,$aa,$e2,$50,$0f,$5f,$66,$12,$4d,$c4,$b7,$f4 139 | dta $1b,$1a,$18,$a2,$a2,$df,$b6,$36,$27,$f7,$33,$3a,$33,$e2,$49,$6e 140 | dta $4d,$25,$94,$f2,$b4,$c4,$50,$be,$f8,$0d,$10,$13,$e3,$82,$32,$cb 141 | dta $9a,$1a,$1e,$2a,$52,$bb,$14,$25,$90,$1d,$96,$b9,$54,$e8,$2d,$45 142 | dta $19,$5b,$9b,$86,$0e,$34,$3a,$2c,$77,$35,$9b,$91,$9d,$f8,$17,$a9 143 | dta $2a,$70,$7a,$9e,$6b,$ce,$6f,$35,$4e,$1d,$d2,$6c,$95,$53,$95,$77 144 | dta $17,$27,$5a,$83,$7e,$76,$74,$65,$6e,$74,$6a,$a5,$75,$79,$ac,$02 145 | dta $af,$b5,$a2,$e1,$89,$87,$be,$c3,$87,$cd,$ae,$41,$74,$ea,$69,$8e 146 | dta $ed,$d6,$2a,$1d,$a3,$eb,$17,$5a,$43,$d2,$a7,$0e,$6b,$43,$7b,$73 147 | dta $92,$ec,$d3,$7a,$50,$3b,$3e,$57,$e6,$65,$b9,$c9,$75,$5f,$d8,$3a 148 | dta $ca,$1e,$2c,$33,$26,$dd,$85,$28,$e9,$bd,$45,$34,$8a,$79,$59,$c1 149 | dta $c7,$7c,$10,$9d,$6b,$28,$75,$9e,$a0,$89,$4a,$40,$26,$49,$5b,$54 150 | dta $64,$1a,$48,$49,$b5,$7e,$68,$0f,$d6,$0e,$00,$27,$e2,$26,$62,$d7 151 | 152 | title dta c'CPU: LAS...',0 153 | pass dta c'Pass',$9b,0 154 | fail dta c'FAIL.',$9b,c'Code:BB',0 155 | sequ dta c' S=',0 156 | yequ dta c' Y=',0 157 | 158 | ift !SAP 159 | run main 160 | eif 161 | -------------------------------------------------------------------------------- /test/pokey_pot.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "POKEY POT Test"',13,10 6 | dta c'DATE "14/06/2011"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 00:10',13,10 10 | opt h+ 11 | eif 12 | 13 | div5 equ $80 14 | mod5 equ $81 15 | scrptr equ $8a ; 2 bytes 16 | printptr equ $8c ; 2 bytes 17 | 18 | org f:$3000 19 | main 20 | :SAP mwa #$1000 scrptr 21 | lda <title 22 | ldx >title 23 | jsr print 24 | 25 | :!SAP sei:inc ^4e 26 | :!SAP inc ^40 27 | 28 | ; fast POT scan 29 | ldx #1 30 | stx div5 31 | dex 32 | stx 0 33 | ldy #0 34 | test_loop 35 | stx mod5 36 | mva cmps,x cmpd 37 | 38 | mva #0 ^2f 39 | :2 sta ^4a 40 | mva #7 ^2f 41 | sta ^2b 42 | ldx div5 43 | dex:rne 44 | cmpd cmp #0 45 | lda ^20 46 | cmp expected,y 47 | jne error 48 | 49 | ldx mod5 50 | inx 51 | cpx #5 52 | bcc same5 53 | inc div5 54 | ldx #0 55 | same5 iny 56 | bne test_loop 57 | 58 | ; slow POT scan (114 divisor) 59 | ldy #2 60 | test2_loop 61 | mva cmps,y cmpd2 62 | mva #0 ^2f 63 | :2 sta ^4a 64 | mva #3 ^2f 65 | :2 sta ^4a 66 | sta ^2b 67 | ldx #13+21 68 | dex:rne 69 | cmpd2 cmp #0 70 | lda ^20 71 | cmp expected114,y 72 | bne error 73 | dey 74 | bpl test2_loop 75 | 76 | ; slow POT scan, max value 77 | ldy #228 78 | test3_loop 79 | sty ^4a 80 | dey 81 | bne test3_loop 82 | lda ^20 83 | cmp #228 84 | bne error 85 | 86 | ; slow POT scan, 114 divisor stopped 87 | mva #0 ^2f 88 | :2 sta ^4a 89 | sta ^2b 90 | :5 sta ^4a 91 | ldx #3 92 | lda ^20 93 | stx ^2f 94 | bne error 95 | 96 | lsr:cli ^4e 97 | lda <pass 98 | ldx >pass 99 | jsr print 100 | mwa #$af30 $d200 101 | jmp * 102 | 103 | error 104 | lsr:cli ^4e 105 | lda <fail 106 | ldx >fail 107 | jsr print 108 | mwa #$cfa0 $d200 109 | jmp * 110 | 111 | put_char 112 | ift SAP 113 | sta (scrptr),0 114 | inw scrptr 115 | rts 116 | els 117 | mvx #11 $342 118 | mwx #0 $348 119 | jmp $e456 120 | eif 121 | 122 | print 123 | sta printptr 124 | stx printptr+1 125 | jmp print_2 126 | print_1 127 | jsr put_char 128 | inw printptr 129 | print_2 130 | lda (printptr),0 131 | bne print_1 132 | rts 133 | 134 | title dta c'POKEY: POT...',0 135 | pass dta c'Pass',$9b,0 136 | fail dta c'FAIL.',$9b,0 137 | 138 | cmps dta {cmp #},{cmp 0},{cmp 0,x},{cmp (0),y},{cmp (0,x)} 139 | 140 | expected 141 | dta $08,$0c,$0c,$0e,$00,$10,$10,$12,$10,$14,$14,$16,$10,$18,$1a,$18 142 | dta $1c,$1e,$00,$20,$22,$20,$24,$26,$20,$28,$2a,$28,$2c,$2e,$20,$30 143 | dta $32,$30,$34,$36,$30,$38,$3a,$38,$3c,$3c,$3e,$00,$40,$40,$42,$40 144 | dta $44,$44,$46,$40,$48,$48,$4a,$48,$4c,$4c,$4e,$40,$50,$50,$52,$50 145 | dta $54,$54,$56,$50,$58,$58,$5a,$58,$5c,$5c,$5e,$40,$60,$60,$62,$60 146 | dta $64,$64,$66,$60,$68,$68,$6a,$68,$6c,$6c,$6e,$60,$70,$70,$72,$70 147 | dta $74,$74,$76,$70,$78,$78,$7a,$78,$7c,$7c,$7e,$00,$80,$80,$82,$80 148 | dta $84,$84,$86,$80,$88,$88,$88,$8c,$8c,$80,$90,$90,$90,$94,$94,$90 149 | dta $98,$98,$98,$9c,$9c,$80,$a0,$a0,$a0,$a4,$a4,$a0,$a8,$a8,$a8,$ac 150 | dta $ac,$ae,$a0,$b0,$b0,$b2,$b0,$b4,$b4,$b6,$b0,$b8,$b8,$ba,$b8,$bc 151 | dta $bc,$be,$80,$c0,$c0,$c2,$c0,$c4,$c4,$c6,$c0,$c8,$c8,$ca,$c8,$cc 152 | dta $cc,$ce,$c0,$d0,$d0,$d2,$d0,$d4,$d4,$d6,$d0,$d8,$d8,$da,$d8,$dc 153 | dta $dc,$de,$c0,$e0,$e0,$e2,$e0,$e4,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5 154 | dta $e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5 155 | dta $e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5 156 | dta $e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5,$e5 157 | expected114 158 | dta 1,0,2 159 | 160 | ift !SAP 161 | run main 162 | eif 163 | -------------------------------------------------------------------------------- /win32/xmplay/xmpin.h: -------------------------------------------------------------------------------- 1 | // XMPlay input plugin header (c) 2004-2007 Ian Luck 2 | // new plugins can be submitted to plugins@xmplay.com 3 | 4 | #pragma once 5 | 6 | #include "xmpfunc.h" 7 | 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | 12 | #ifndef XMPIN_FACE 13 | #define XMPIN_FACE 3 // "face" 14 | #endif 15 | 16 | #define XMPIN_FLAG_CANSTREAM 1 // can stream files (play while downloading from the 'net) 17 | #define XMPIN_FLAG_OWNFILE 2 // can process files without "XMPFILE" routines 18 | #define XMPIN_FLAG_NOXMPFILE 4 // never use "XMPFILE" routines (implies XMPIN_FLAG_OWNFILE) 19 | #define XMPIN_FLAG_LOOP 8 // custom looping 20 | #define XMPIN_FLAG_TAIL 16 // output tail (decay/fadeout) 21 | 22 | // SetPosition special positions 23 | #define XMPIN_POS_LOOP -1 // loop 24 | #define XMPIN_POS_AUTOLOOP -2 // auto-loop 25 | #define XMPIN_POS_TAIL -3 // output tail (decay/fadeout) 26 | #define XMPIN_POS_SUBSONG 0x80000000 // subsong (LOWORD=subsong) 27 | 28 | // VisRender/DC flags 29 | #define XMPIN_VIS_INIT 1 // DC/buffer is uninitialized 30 | #define XMPIN_VIS_FULL 2 // fullscreen 31 | 32 | typedef struct { 33 | DWORD flags; // XMPIN_FLAG_xxx 34 | const char *name; // plugin name 35 | const char *exts; // supported file extensions (description\0ext1/ext2/etc...) 36 | 37 | void (WINAPI *About)(HWND win); // (OPTIONAL) 38 | void (WINAPI *Config)(HWND win); // present config options to user (OPTIONAL) 39 | BOOL (WINAPI *CheckFile)(const char *filename, XMPFILE file); // verify file 40 | BOOL (WINAPI *GetFileInfo)(const char *filename, XMPFILE file, float *length, char *tags[8]); // get track info 41 | //tags: 0=title,1=artist,2=album,3=year,4=track,5=genre,6=comment,7=filetype 42 | 43 | // playback stuff 44 | DWORD (WINAPI *Open)(const char *filename, XMPFILE file); // open a file 45 | void (WINAPI *Close)(); // close file 46 | void *reserved; 47 | void (WINAPI *SetFormat)(XMPFORMAT *form); // set sample format 48 | 49 | BOOL (WINAPI *GetTags)(char *tags[8]); // get title elements, return TRUE to delay (OPTIONAL) 50 | void (WINAPI *GetInfoText)(char *format, char *length); // get main panel info text 51 | void (WINAPI *GetGeneralInfo)(char *buf); // get General info window text (buf is ~40K) 52 | void (WINAPI *GetMessage)(char *buf); // get Message info text (OPTIONAL) 53 | double (WINAPI *SetPosition)(DWORD pos); // seek 54 | double (WINAPI *GetGranularity)(); // seeking granularity 55 | DWORD (WINAPI *GetBuffering)(); // get buffering progress (OPTIONAL) 56 | DWORD (WINAPI *Process)(float *buf, DWORD count); // decode some sample data 57 | BOOL (WINAPI *WriteFile)(const char *filename); // write file to disk (OPTIONAL) 58 | 59 | void (WINAPI *GetSamples)(char *buf); // get Samples info text (OPTIONAL) 60 | DWORD (WINAPI *GetSubSongs)(float *length); // get number (and total length) of sub-songs (OPTIONAL) 61 | char *(WINAPI *GetCues)(); // get CUE sheet (OPTIONAL) 62 | 63 | float (WINAPI *GetDownloaded)(); // get download progress (OPTIONAL) 64 | 65 | // vis stuff (all OPTIONAL) 66 | const char *visname; // visualisation name 67 | BOOL (WINAPI *VisOpen)(DWORD colors[3]); // initialize vis 68 | void (WINAPI *VisClose)(); // close vis 69 | void (WINAPI *VisSize)(HDC dc, SIZE *size); // get ideal vis dimensions 70 | BOOL (WINAPI *VisRender)(DWORD *buf, SIZE size, DWORD flags); // render vis 71 | BOOL (WINAPI *VisRenderDC)(HDC dc, SIZE size, DWORD flags); // render vis 72 | void (WINAPI *VisButton)(DWORD x, DWORD y); // mouse click in vis 73 | } XMPIN; 74 | 75 | #define XMPFUNC_IN_FACE 11 76 | 77 | typedef struct { 78 | void (WINAPI *SetLength)(float length, BOOL seekable); // set track length (-1=unchanged) and if it's seekable 79 | void (WINAPI *SetGain)(DWORD mode, float gain); // set replaygain (mode 0=track, 1=album) 80 | BOOL (WINAPI *UpdateTitle)(const char *track); // set track title (NULL=refresh tags/title) 81 | } XMPFUNC_IN; 82 | 83 | 84 | #ifdef __cplusplus 85 | } 86 | #endif 87 | -------------------------------------------------------------------------------- /PORTS.xsl: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" ?> 2 | <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 3 | <xsl:output method="html" /> 4 | 5 | <xsl:template match="/ports"> 6 | <html> 7 | <head> 8 | <title>ASAP ports list 9 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
NameBinary releasePlatformUser interfaceFirst appeared in ASAPDevelop­ment status[1]OutputSupports sub­songs?Shows file infor­mation?Edits file infor­mation?Converts to and from SAP?Configu­rable play­back time?Mute POKEY chan­nels?Shows STIL?CommentProgram­ming lan­guageRelated website
46 |
    47 |
  1. Development status: 48 |
      49 |
    • stable - complete
    • 50 |
    • in development - working, but incomplete or buggy
    • 51 |
    • discontinued - present in previous releases, no longer supported
    • 52 |
    • sample - sample code for developers, not recommended for end-users
    • 53 |
    54 |
  2. 55 |
56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | good 71 | partial 72 | bad 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | good 96 | bad 97 | partial 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /javascript/asapweb.js: -------------------------------------------------------------------------------- 1 | /* 2 | * asapweb.js - pure JavaScript ASAP for web browsers 3 | * 4 | * Copyright (C) 2009-2023 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | import { ASAP, ASAPSampleFormat } from "./asap.js"; 25 | 26 | export const asapWeb = { 27 | stop() 28 | { 29 | if (this.processor) { 30 | this.processor.disconnect(); 31 | delete this.processor; 32 | } 33 | }, 34 | 35 | playContent(filename, content, song) 36 | { 37 | const asap = new ASAP(); 38 | asap.load(filename, content, content.length); 39 | const info = asap.getInfo(); 40 | if (song === undefined) 41 | song = info.getDefaultSong(); 42 | asap.playSong(song, -1); 43 | 44 | this.stop(); 45 | const length = 4096; 46 | const channels = asap.getInfo().getChannels(); 47 | const buffer = new Uint8Array(length * channels); 48 | 49 | const AudioContext = window.AudioContext || window.webkitAudioContext; 50 | if (this.context) 51 | this.context.close(); 52 | this.context = new AudioContext({ sampleRate : ASAP.SAMPLE_RATE }); 53 | if (typeof(this.onUpdate) == "function") 54 | this.context.onstatechange = this.onUpdate; 55 | this.processor = this.context.createScriptProcessor(length, 0, channels); 56 | this.processor.onaudioprocess = e => { 57 | asap.generate(buffer, length * channels, ASAPSampleFormat.U8); 58 | for (let c = 0; c < channels; c++) { 59 | const output = e.outputBuffer.getChannelData(c); 60 | for (let i = 0; i < length; i++) 61 | output[i] = (buffer[i * channels + c] - 128) / 128; 62 | } 63 | if (typeof(this.onUpdate) == "function") 64 | this.onUpdate(); 65 | }; 66 | this.processor.connect(this.context.destination); 67 | this.asap = asap; 68 | if (typeof(this.onUpdate) == "function") 69 | this.onUpdate(); 70 | }, 71 | 72 | togglePause() 73 | { 74 | if (this.context) { 75 | switch (this.context.state) { 76 | case "running": 77 | this.context.suspend(); 78 | return true; 79 | case "suspended": 80 | this.context.resume(); 81 | return false; 82 | default: 83 | break; 84 | } 85 | } 86 | return null; 87 | }, 88 | 89 | isPaused() 90 | { 91 | if (this.context) { 92 | switch (this.context.state) { 93 | case "running": 94 | return false; 95 | case "suspended": 96 | return true; 97 | default: 98 | break; 99 | } 100 | } 101 | return null; 102 | }, 103 | 104 | playUrl(url, song) 105 | { 106 | const request = new XMLHttpRequest(); 107 | request.open("GET", url, true); 108 | request.responseType = "arraybuffer"; 109 | request.onload = e => { 110 | if (request.status == 200 || request.status == 0) 111 | this.playContent(url, new Uint8Array(request.response), song); 112 | }; 113 | request.send(); 114 | }, 115 | 116 | playFile(file) 117 | { 118 | const reader = new FileReader(); 119 | reader.onload = e => this.playContent(file.name, new Uint8Array(e.target.result)); 120 | reader.readAsArrayBuffer(file); 121 | }, 122 | 123 | seek(position) 124 | { 125 | if (!this.context) 126 | return; 127 | this.context.suspend(); 128 | this.asap.seek(position); 129 | this.context.resume(); 130 | } 131 | }; 132 | -------------------------------------------------------------------------------- /www/windows.xml: -------------------------------------------------------------------------------- 1 | 2 |

Windows

3 |

Download . 4 | It's an installer for Windows 11/10/8/7/Vista/XP, also the 64-bit ones.

5 |

The 64-bit installer 6 | contains plugins to 64-bit versions of foobar2000, AIMP, VLC and Windows Explorer. 7 | It is okay to have both the 32-bit and 64-bit ASAP packages installed at the same time.

8 | 9 |

foobar2000

10 |

foobar2000 is the recommended player. 11 | The ASAP installer detects it and installs a suitable plugin. 12 | If you want to install just the foobar2000 plugin and nothing else, there's an alternative download: 13 | .

14 |

foobar2000 can play directly from ZIP files, so you don't even need to unpack them. The plugin also supports ATR disk images. 15 | You can also convert, e.g. to MP3.

16 |

To view and edit metadata, select "View/ASAP info". This doesn't work inside ZIP archives.

17 | foobar2000 18 | 19 |

XMPlay

20 |

XMPlay is a player supporting MOD and similar formats out of the box. 21 | The ASAP plugin can display RMT instrument names. If you want to use the "File information" window 22 | (to edit tags or convert between SAP and other formats), assign a shortcut to it from within XMPlay options.

23 | XMPlay 24 | 25 |

Winamp

26 |

Winamp is a pure old-school classic! Believe it or not, it does work on Windows 10. 27 | The ASAP plugin supports ATR disk images.

28 | Winamp 29 | 30 |

BASS / AIMP

31 |

BASS is a component that provides audio playback 32 | in AIMP and other players. 33 | The ASAP installer detects AIMP. For other players, modify the install directory.

34 | AIMP 35 | 36 |

VLC

37 |

VLC is a popular video player that plays audio as well. 38 | It provides limited support for the SAP file format out of the box (no digitized sounds, buggy emulation). 39 | For best experience, install the ASAP plugin.

40 | VLC 41 | 42 |

Raster Music Tracker

43 |

RMT is a chiptune editor running on Windows. 44 | For better emulation of the POKEY chip, install the ASAP plugin.

45 | 46 |

WASAP

47 |

WASAP is a tiny standalone player. When you run it, an "Open file" dialog appears. 48 | Simply select the file you want to listen to. WASAP is later controlled by its red tray icon. 49 | When you hover the mouse pointer over the icon, the name of the loaded file appears. 50 | To open another file, left-click the tray icon. The other options are 51 | available in the menu which appears when you right-click the icon.

52 |

Because of limited functionality of WASAP (for instance, no playlist), 53 | it's recommended to use the previously described players instead.

54 | WASAP 55 | 56 |

Windows Explorer

57 |

The Windows Explorer extension provides no playback, only metadata display and editor.

58 | Windows Explorer 59 | 60 |

asapconv

61 |

For command-line conversions (e.g. to WAV or between SAP and the tracker formats) 62 | and editing the metadata, use asapconv. Run the program from the command prompt to see the syntax. 63 | The -o/--output option selects the output format and is mandatory.

64 | 65 |

Manual installation

66 |

If you are allergic to installers, download 67 | and extract the files to proper locations.

68 |
69 | -------------------------------------------------------------------------------- /test/cpu_decimal.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "6502 Decimal Mode Test"',13,10 6 | dta c'DATE "27/11/2010"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 01:30',13,10 10 | opt h+ 11 | eif 12 | 13 | ; CRC-32 based on my implementation in cc65 / zlib 14 | 15 | D_FLAG equ 8 16 | C_FLAG equ 1 17 | CRC_POLY3 equ $ed 18 | CRC_POLY2 equ $b8 19 | CRC_POLY1 equ $83 20 | CRC_POLY0 equ $20 21 | 22 | OK3 equ $3d 23 | OK2 equ $d8 24 | OK1 equ $4d 25 | OK0 equ $2a 26 | 27 | crc equ $80 ; 4 bytes 28 | zpdata equ $84 29 | zpflags equ $85 30 | scrptr equ $86 ; 2 bytes 31 | printptr equ $88 ; 2 bytes 32 | 33 | org f:$3000 34 | main 35 | :SAP mwa #$1000 scrptr 36 | lda title 38 | jsr print 39 | jsr init_crc 40 | lda #0 41 | jsr test_adc_sbc 42 | lda #C_FLAG 43 | jsr test_adc_sbc 44 | lda #D_FLAG 45 | jsr test_adc_sbc 46 | lda #D_FLAG|C_FLAG 47 | jsr test_adc_sbc 48 | 49 | lda crc+3 50 | cmp #OK3 51 | bne error 52 | lda crc+2 53 | cmp #OK2 54 | bne error 55 | lda crc+1 56 | cmp #OK1 57 | bne error 58 | lda crc 59 | cmp #OK0 60 | bne error 61 | lda <pass 62 | ldx >pass 63 | jsr print 64 | mwa #$af30 $d200 65 | jmp * 66 | error 67 | lda <fail 68 | ldx >fail 69 | jsr print 70 | lda crc+3 71 | jsr put_hex_byte 72 | lda crc+2 73 | jsr put_hex_byte 74 | lda crc+1 75 | jsr put_hex_byte 76 | lda crc 77 | jsr put_hex_byte 78 | lda #$9b 79 | jsr put_char 80 | mwa #$cfa0 $d200 81 | jmp * 82 | 83 | test_adc_sbc 84 | sta zpflags 85 | mva #0 zpdata 86 | ldy #0 87 | test_adc_sbc_byte 88 | mva zpdata arr+1 89 | :!SAP sta $2c8 90 | 91 | lda:pha zpflags 92 | tya 93 | plp 94 | adc zpdata 95 | php 96 | jsr do_crc 97 | pla 98 | jsr do_crc 99 | 100 | lda:pha zpflags 101 | tya 102 | plp 103 | sbc zpdata 104 | php 105 | jsr do_crc 106 | pla 107 | jsr do_crc 108 | 109 | lda:pha zpflags 110 | tya 111 | plp 112 | arr dta $6b,0 113 | php 114 | jsr do_crc 115 | pla 116 | jsr do_crc 117 | 118 | iny 119 | bne test_adc_sbc_byte 120 | inc zpdata 121 | bne test_adc_sbc_byte 122 | rts 123 | 124 | init_crc 125 | ldx #0 126 | init_crc_entry 127 | lda #0 128 | sta crc+1 129 | sta crc+2 130 | sta crc+3 131 | ldy #8 132 | txa 133 | init_crc_bit 134 | sta crc 135 | lsr @ 136 | bcc init_crc_noxor 137 | lda crc+3 138 | lsr @ 139 | eor #CRC_POLY3 140 | sta crc+3 141 | lda crc+2 142 | ror @ 143 | eor #CRC_POLY2 144 | sta crc+2 145 | lda crc+1 146 | ror @ 147 | eor #CRC_POLY1 148 | sta crc+1 149 | lda crc 150 | ror @ 151 | eor #CRC_POLY0 152 | bcs init_crc_nextbit ; branch always 153 | init_crc_noxor 154 | rol @ 155 | lsr crc+3 156 | ror crc+2 157 | ror crc+1 158 | ror @ 159 | init_crc_nextbit 160 | dey 161 | bne init_crc_bit 162 | sta crc_table_0,x 163 | mva crc+1 crc_table_1,x 164 | mva crc+2 crc_table_2,x 165 | mva crc+3 crc_table_3,x 166 | inx 167 | bne init_crc_entry 168 | mwa #0 crc 169 | sta crc+2 170 | sta crc+3 171 | rts 172 | 173 | ; crc = (crc >> 8) ^ crc_table[(crc & 0xff) ^ input]; 174 | do_crc 175 | eor crc 176 | tax 177 | lda crc_table_0,x 178 | eor crc+1 179 | sta crc 180 | lda crc_table_1,x 181 | eor crc+2 182 | sta crc+1 183 | lda crc_table_2,x 184 | sta crc+3 185 | sta crc+2 186 | mva crc_table_3,x crc+3 187 | rts 188 | 189 | put_hex_byte 190 | pha 191 | :4 lsr @ 192 | jsr put_hex_nibble 193 | pla 194 | and #$f 195 | put_hex_nibble 196 | cmp #10 197 | sed 198 | adc #'0' 199 | cld 200 | put_char 201 | ift SAP 202 | sta (scrptr),0 203 | inw scrptr 204 | rts 205 | els 206 | mvx #11 $342 207 | mwx #0 $348 208 | jmp $e456 209 | eif 210 | 211 | print 212 | sta printptr 213 | stx printptr+1 214 | jmp print_2 215 | print_1 216 | jsr put_char 217 | inw printptr 218 | print_2 219 | lda (printptr),0 220 | bne print_1 221 | rts 222 | 223 | title dta c'CPU: Decimal mode...',0 224 | pass dta c'Pass',$9b,0 225 | fail dta c'FAIL.',$9b,0 226 | 227 | crc_table_0 org *+256 228 | crc_table_1 org *+256 229 | crc_table_2 org *+256 230 | crc_table_3 org *+256 231 | 232 | ift !SAP 233 | run main 234 | eif 235 | -------------------------------------------------------------------------------- /test/pokey_random.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "POKEY RANDOM Test"',13,10 6 | dta c'DATE "19/05/2011"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 00:10',13,10 10 | opt h+ 11 | eif 12 | 13 | div5 equ $80 14 | mod5 equ $81 15 | scrptr equ $8a ; 2 bytes 16 | printptr equ $8c ; 2 bytes 17 | 18 | org f:$3000 19 | main 20 | :SAP mwa #$1000 scrptr 21 | lda <title 22 | ldx >title 23 | jsr print 24 | 25 | :!SAP sei:inc ^4e 26 | :!SAP inc ^40 27 | 28 | ldx #1 29 | stx div5 30 | dex 31 | stx 0 32 | ldy #0 33 | test_loop 34 | stx mod5 35 | mva cmps,x cmpd 36 | sta cmpd2 37 | 38 | mva #0 ^28 39 | sta ^2f 40 | :2 sta ^4a 41 | mva #3 ^2f 42 | ldx div5 43 | dex:rne 44 | cmpd cmp #0 45 | lda ^2a 46 | cmp poly17,y 47 | bne error 48 | 49 | mva #$80 ^28 50 | sta ^2f 51 | :2 sta ^4a 52 | mva #3 ^2f 53 | ldx div5 54 | dex:rne 55 | cmpd2 cmp #0 56 | lda ^2a 57 | cmp poly9,y 58 | bne error 59 | 60 | ldx mod5 61 | inx 62 | cpx #5 63 | bcc same5 64 | inc div5 65 | ldx #0 66 | same5 iny 67 | bne test_loop 68 | 69 | lsr:cli ^4e 70 | lda <pass 71 | ldx >pass 72 | jsr print 73 | mwa #$af30 $d200 74 | jmp * 75 | 76 | error 77 | lsr:cli ^4e 78 | lda <fail 79 | ldx >fail 80 | jsr print 81 | mwa #$cfa0 $d200 82 | jmp * 83 | 84 | put_char 85 | ift SAP 86 | sta (scrptr),0 87 | inw scrptr 88 | rts 89 | els 90 | mvx #11 $342 91 | mwx #0 $348 92 | jmp $e456 93 | eif 94 | 95 | print 96 | sta printptr 97 | stx printptr+1 98 | jmp print_2 99 | print_1 100 | jsr put_char 101 | inw printptr 102 | print_2 103 | lda (printptr),0 104 | bne print_1 105 | rts 106 | 107 | title dta c'POKEY: RANDOM...',0 108 | pass dta c'Pass',$9b,0 109 | fail dta c'FAIL.',$9b,0 110 | 111 | cmps dta {cmp #},{cmp 0},{cmp 0,x},{cmp (0),y},{cmp (0,x)} 112 | 113 | poly17 114 | dta $00,$80,$C0,$E0,$F0,$F8,$7C,$3E,$1F,$0F,$07,$03,$01,$80,$C0,$E0 115 | dta $F0,$FC,$FE,$FF,$FF,$7F,$3F,$CF,$E7,$F3,$7C,$3E,$1F,$07,$83,$C1 116 | dta $30,$18,$8C,$E3,$F1,$F8,$FE,$FF,$FF,$3F,$1F,$0F,$07,$83,$C1,$E0 117 | dta $70,$38,$1C,$0E,$87,$C3,$E1,$F0,$F8,$FC,$FE,$FF,$7F,$3F,$9F,$CF 118 | dta $67,$B3,$D9,$EC,$F6,$7B,$3D,$1E,$8F,$C7,$63,$31,$98,$CC,$E6,$73 119 | dta $39,$1C,$8E,$C7,$63,$31,$18,$0C,$86,$43,$21,$10,$08,$84,$42,$21 120 | dta $10,$08,$04,$82,$41,$20,$10,$08,$04,$02,$01,$00,$00,$00,$80,$C0 121 | dta $60,$30,$18,$0C,$86,$43,$21,$10,$08,$04,$C1,$60,$30,$8C,$46,$23 122 | dta $08,$04,$82,$E0,$70,$38,$0E,$87,$43,$10,$88,$C4,$F1,$78,$3C,$CF 123 | dta $67,$33,$0C,$86,$43,$A1,$D0,$68,$B4,$5A,$2D,$96,$4B,$25,$92,$49 124 | dta $24,$92,$C9,$64,$32,$19,$8C,$46,$23,$91,$C8,$64,$B2,$D9,$EC,$F6 125 | dta $7B,$3D,$1E,$8F,$47,$A3,$D1,$E8,$F4,$FA,$7D,$3E,$1F,$8F,$C7,$63 126 | dta $B1,$D8,$EC,$F6,$7B,$BD,$DE,$EF,$F7,$7B,$3D,$1E,$8F,$C7,$63,$31 127 | dta $18,$0C,$06,$03,$01,$00,$80,$C0,$60,$30,$18,$0C,$06,$83,$C1,$60 128 | dta $30,$18,$8C,$63,$31,$18,$C6,$E3,$F1,$3C,$1E,$0F,$03,$01,$00,$00 129 | dta $80,$C0,$B0,$D8,$EC,$7B,$3D,$1E,$07,$83,$C1,$B0,$D8,$6C,$36,$1B 130 | poly9 131 | dta $EF,$77,$3B,$1D,$0E,$87,$43,$A1,$D0,$68,$34,$9A,$CD,$66,$B3,$D9 132 | dta $6C,$DB,$ED,$F6,$BD,$5E,$2F,$0B,$85,$C2,$70,$38,$9C,$67,$33,$19 133 | dta $86,$43,$21,$48,$24,$12,$44,$A2,$51,$D4,$EA,$75,$BA,$5D,$AE,$D7 134 | dta $EB,$F5,$7A,$3D,$9E,$4F,$27,$93,$49,$A4,$D2,$E9,$74,$3A,$9D,$CE 135 | dta $E7,$73,$39,$1C,$0E,$07,$03,$81,$C0,$E0,$70,$B8,$DC,$EE,$77,$BB 136 | dta $5D,$2E,$97,$CB,$E5,$F2,$79,$BC,$5E,$AF,$57,$2B,$95,$4A,$A5,$52 137 | dta $29,$14,$0A,$05,$02,$81,$40,$A0,$50,$A8,$54,$AA,$55,$AA,$D5,$EA 138 | dta $F5,$FA,$7D,$BE,$5F,$AF,$D7,$6B,$B5,$5A,$16,$0B,$05,$C1,$60,$B0 139 | dta $EC,$76,$BB,$6E,$B7,$DB,$B6,$5B,$AD,$6B,$35,$1A,$06,$83,$41,$D0 140 | dta $E8,$74,$DD,$EE,$F7,$FB,$7D,$3E,$1F,$8F,$C7,$E3,$F1,$78,$3C,$9E 141 | dta $CF,$67,$B3,$59,$2C,$96,$CB,$65,$B2,$59,$AC,$D6,$EB,$75,$3A,$1D 142 | dta $8E,$C7,$63,$B1,$58,$2C,$16,$8B,$45,$A2,$D1,$E8,$F4,$FA,$FD,$FE 143 | dta $7F,$BF,$5F,$2F,$97,$4B,$A5,$D2,$69,$34,$1A,$8D,$46,$A3,$51,$28 144 | dta $94,$CA,$65,$32,$19,$8C,$C6,$63,$31,$18,$0C,$06,$03,$01,$80,$C0 145 | dta $60,$30,$98,$66,$33,$99,$A6,$53,$A9,$6A,$35,$9A,$26,$93,$C9,$F2 146 | dta $F9,$FC,$BF,$DF,$6F,$5B,$2D,$96,$25,$92,$49,$92,$C9,$64,$B2,$D9 147 | 148 | ift !SAP 149 | run main 150 | eif 151 | -------------------------------------------------------------------------------- /xmms2/libxmms_asap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * libxmms_asap.c - ASAP plugin for XMMS2 3 | * 4 | * Copyright (C) 2021 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #include <xmms/xmms_xformplugin.h> 25 | #include <xmms/xmms_log.h> 26 | 27 | #include "asap.h" 28 | 29 | static void set_str(xmms_xform_t *xform, const char *key, const char *val) 30 | { 31 | if (val[0] != '\0') 32 | xmms_xform_metadata_set_str(xform, key, val); 33 | } 34 | 35 | static gboolean xmms_asap_init(xmms_xform_t *xform) 36 | { 37 | const char *url = xmms_xform_get_url(xform); 38 | uint8_t module[ASAPInfo_MAX_MODULE_LENGTH]; 39 | xmms_error_t error; 40 | int moduleLen = xmms_xform_read(xform, module, sizeof(module), &error); 41 | if (moduleLen == -1) { 42 | XMMS_DBG("Error reading %s", url); 43 | return FALSE; 44 | } 45 | 46 | ASAP *asap = ASAP_New(); 47 | if (!ASAP_Load(asap, url, module, moduleLen)) { 48 | ASAP_Delete(asap); 49 | XMMS_DBG("Error decoding %s", url); 50 | return FALSE; 51 | } 52 | const ASAPInfo *info = ASAP_GetInfo(asap); 53 | int song = ASAPInfo_GetDefaultSong(info); 54 | int duration = ASAPInfo_GetDuration(info, song); 55 | if (!ASAP_PlaySong(asap, song, duration)) { 56 | ASAP_Delete(asap); 57 | return FALSE; 58 | } 59 | 60 | xmms_xform_private_data_set(xform, asap); 61 | xmms_xform_outdata_type_add(xform, 62 | XMMS_STREAM_TYPE_MIMETYPE, "audio/pcm", 63 | XMMS_STREAM_TYPE_FMT_FORMAT, XMMS_SAMPLE_FORMAT_S16, 64 | XMMS_STREAM_TYPE_FMT_CHANNELS, ASAPInfo_GetChannels(info), 65 | XMMS_STREAM_TYPE_FMT_SAMPLERATE, ASAP_SAMPLE_RATE, 66 | XMMS_STREAM_TYPE_END); 67 | xmms_xform_metadata_set_int(xform, XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION, duration); 68 | set_str(xform, XMMS_MEDIALIB_ENTRY_PROPERTY_ARTIST, ASAPInfo_GetAuthor(info)); 69 | set_str(xform, XMMS_MEDIALIB_ENTRY_PROPERTY_TITLE, ASAPInfo_GetTitle(info)); 70 | set_str(xform, XMMS_MEDIALIB_ENTRY_PROPERTY_YEAR, ASAPInfo_GetDate(info)); 71 | return TRUE; 72 | } 73 | 74 | static void xmms_asap_destroy(xmms_xform_t *xform) 75 | { 76 | ASAP *asap = (ASAP *) xmms_xform_private_data_get(xform); 77 | ASAP_Delete(asap); 78 | } 79 | 80 | static gint xmms_asap_read(xmms_xform_t *xform, xmms_sample_t *buf, gint len, xmms_error_t *err) 81 | { 82 | ASAP *asap = (ASAP *) xmms_xform_private_data_get(xform); 83 | return ASAP_Generate(asap, buf, len, G_BYTE_ORDER == G_LITTLE_ENDIAN ? ASAPSampleFormat_S16_L_E : ASAPSampleFormat_S16_B_E); 84 | } 85 | 86 | static gint64 xmms_asap_seek(xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t whence, xmms_error_t *err) 87 | { 88 | g_return_val_if_fail(whence == XMMS_XFORM_SEEK_SET, -1); 89 | ASAP *asap = (ASAP *) xmms_xform_private_data_get(xform); 90 | return ASAP_SeekSample(asap, samples) ? samples : -1; 91 | } 92 | 93 | static gboolean xmms_asap_setup(xmms_xform_plugin_t *xform_plugin) 94 | { 95 | xmms_xform_methods_t methods; 96 | XMMS_XFORM_METHODS_INIT(methods); 97 | methods.init = xmms_asap_init; 98 | methods.destroy = xmms_asap_destroy; 99 | methods.read = xmms_asap_read; 100 | methods.seek = xmms_asap_seek; 101 | 102 | xmms_xform_plugin_methods_set(xform_plugin, &methods); 103 | xmms_xform_plugin_indata_add(xform_plugin, XMMS_STREAM_TYPE_MIMETYPE, "application/x-sap", XMMS_STREAM_TYPE_END); 104 | xmms_magic_add("SAP file", "application/x-sap", "0 string SAP", NULL); 105 | xmms_magic_extension_add("application/x-sap", "*.sap"); 106 | return true; 107 | } 108 | 109 | XMMS_XFORM_PLUGIN("asap", 110 | "ASAP decoder", ASAPInfo_VERSION, 111 | "Another Slight Atari Player decoder", 112 | xmms_asap_setup); 113 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | prefix := /usr/local 2 | srcdir := $(dir $(lastword $(MAKEFILE_LIST))) 3 | bindir = $(prefix)/bin 4 | libdir = $(prefix)/lib 5 | CC = gcc 6 | CFLAGS = -O2 -Wall 7 | CPPFLAGS = 8 | LDFLAGS = -s 9 | AR = ar 10 | ARFLAGS = rc 11 | DO_CC = $(DO)$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $(if $(filter %.so,$@),-shared -fPIC) $(INCLUDEOPTS) $(filter %.c,$^) $(LDFLAGS) -lm 12 | DO_AR = $(DO)$(AR) $(ARFLAGS) $@ $^ 13 | FUT = $(DO)fut -o $@ $(patsubst %,-I %,$(sort $(dir $(filter-out %.fu,$^)))) $(filter %.fu,$^) 14 | INSTALL = install 15 | INSTALL_PROGRAM = mkdir -p $(DESTDIR)$(2) && $(INSTALL) $(1) $(DESTDIR)$(2)/$(or $(3),$(1)) 16 | INSTALL_DATA = mkdir -p $(DESTDIR)$(2) && $(INSTALL) -m 644 $(1) $(DESTDIR)$(2)/$(1) 17 | SDL_CFLAGS = `sdl-config --cflags` 18 | SDL_LIBS = `sdl-config --libs` 19 | SEVENZIP = 7z a -mx=9 -bd -bso0 20 | MAKEZIP = $(DO)$(RM) $@ && $(SEVENZIP) -tzip $@ $(patsubst %,./%,$(filter-out win32/signed,$^)) # "./" makes 7z don't store paths in the archive 21 | COPY = $(DO)cp $< $@ 22 | XASM = $(DO)xasm -q -o $@ $< 23 | OSX_CC = $(DO)cc -O2 -Wall -o $@ -undefined dynamic_lookup -mmacosx-version-min=10.6 -arch x86_64 -arch arm64 $(INCLUDEOPTS) $(filter %.c,$^) 24 | 25 | # no user-configurable paths below this line 26 | 27 | MAKEFLAGS = -r 28 | ifdef V 29 | DO = mkdir -p $(@D) && 30 | else 31 | DO = @echo $@ && mkdir -p $(@D) && 32 | endif 33 | src = $(addprefix $(srcdir),$(1:.[ch]=.c) $(patsubst %.[ch],%.h,$(filter %.[ch],$(1)))) 34 | INCLUDEOPTS = $(patsubst %/,-I%,$(sort $(dir $(filter %.h,$^)))) 35 | CLEAN := 36 | CLEANDIR := 37 | 38 | all: asapconv libasap.a 39 | .PHONY: all 40 | 41 | install: install-asapconv install-lib 42 | .PHONY: install 43 | 44 | include $(srcdir)6502/6502.mk 45 | include $(srcdir)www/www.mk 46 | include $(srcdir)release/release.mk 47 | include $(srcdir)test/test.mk 48 | 49 | # asapconv 50 | 51 | asapconv: $(call src,asapconv.c asap.[ch]) 52 | $(DO_CC) 53 | CLEAN += asapconv 54 | 55 | install-asapconv: asapconv 56 | $(call INSTALL_PROGRAM,asapconv,$(bindir)) 57 | .PHONY: install-asapconv 58 | 59 | uninstall-asapconv: 60 | $(RM) $(DESTDIR)$(bindir)/asapconv 61 | .PHONY: uninstall-asapconv 62 | 63 | # lib 64 | 65 | lib: libasap.a 66 | .PHONY: lib 67 | 68 | libasap.a: asap.o 69 | $(DO_AR) 70 | CLEAN += libasap.a 71 | 72 | asap.o: $(call src,asap.[ch]) 73 | $(DO_CC) -c 74 | CLEAN += asap.o 75 | 76 | install-lib: libasap.a $(srcdir)asap.h 77 | $(call INSTALL_DATA,$(srcdir)asap.h,$(prefix)/include) 78 | $(call INSTALL_DATA,libasap.a,$(libdir)) 79 | .PHONY: install-lib 80 | 81 | uninstall-lib: 82 | $(RM) $(DESTDIR)$(prefix)/include/asap.h $(DESTDIR)$(libdir)/libasap.a 83 | .PHONY: uninstall-lib 84 | 85 | # SDL 86 | 87 | asap-sdl: $(call src,asap-sdl.c asap.[ch]) 88 | $(DO_CC) $(SDL_CFLAGS) $(SDL_LIBS) 89 | CLEAN += asap-sdl 90 | 91 | install-sdl: asap-sdl 92 | $(call INSTALL_PROGRAM,asap-sdl,$(bindir)) 93 | .PHONY: install-sdl 94 | 95 | uninstall-sdl: 96 | $(RM) $(DESTDIR)$(bindir)/asap-sdl 97 | .PHONY: uninstall-sdl 98 | 99 | # asapscan 100 | 101 | asapscan: $(srcdir)asapscan.c asap-asapscan.h 102 | $(DO_CC) 103 | CLEAN += asapscan asapscan.exe 104 | 105 | asap-asapscan.h: $(call src,asap.fu asap6502.fu asapinfo.fu cpu6502.fu pokey.fu) $(ASM6502_PLAYERS_OBX) | asap-asapscan.c 106 | 107 | asap-asapscan.c: $(call src,asap.fu asap6502.fu asapinfo.fu cpu6502.fu pokey.fu) $(ASM6502_PLAYERS_OBX) 108 | $(FUT) -D ASAPSCAN 109 | CLEAN += asap-asapscan.c asap-asapscan.h 110 | 111 | # asap.[ch] 112 | 113 | $(srcdir)asap.h: $(call src,asap.fu asap6502.fu asapinfo.fu asapwriter.fu cpu6502.fu flashpack.fu pokey.fu) $(ASM6502_OBX) | $(srcdir)asap.c 114 | 115 | $(srcdir)asap.c: $(call src,asap.fu asap6502.fu asapinfo.fu asapwriter.fu cpu6502.fu flashpack.fu pokey.fu) $(ASM6502_OBX) 116 | $(FUT) -D C 117 | 118 | # aatr.[ch] 119 | 120 | $(srcdir)aatr.h: $(srcdir)aatr.fu | $(srcdir)aatr.c 121 | 122 | $(srcdir)aatr.c: $(srcdir)aatr.fu 123 | $(FUT) 124 | 125 | clean: 126 | $(RM) $(CLEAN) 127 | $(RM) -r $(CLEANDIR) 128 | .PHONY: clean 129 | 130 | .DELETE_ON_ERROR: 131 | 132 | include $(srcdir)moc/moc.mk 133 | include $(srcdir)vlc/vlc.mk 134 | include $(srcdir)xmms/xmms.mk 135 | include $(srcdir)xmms2/xmms2.mk 136 | 137 | include $(srcdir)csharp/csharp.mk 138 | include $(srcdir)d/d.mk 139 | include $(srcdir)java/java.mk 140 | include $(srcdir)javascript/javascript.mk 141 | include $(srcdir)opencl/opencl.mk 142 | include $(srcdir)python/python.mk 143 | include $(srcdir)swift/swift.mk 144 | include $(srcdir)win32/win32.mk 145 | -------------------------------------------------------------------------------- /java/android/ArchiveSuggestionsProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * ArchiveSuggestionsProvider.java - ASAP for Android 3 | * 4 | * Copyright (C) 2020 Piotr Fusik 5 | * 6 | * This file is part of ASAP (Another Slight Atari Player), 7 | * see http://asap.sourceforge.net 8 | * 9 | * ASAP is free software; you can redistribute it and/or modify it 10 | * under the terms of the GNU General Public License as published 11 | * by the Free Software Foundation; either version 2 of the License, 12 | * or (at your option) any later version. 13 | * 14 | * ASAP is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty 16 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 17 | * See the GNU General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU General Public License 20 | * along with ASAP; if not, write to the Free Software Foundation, Inc., 21 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | package net.sf.asap; 25 | 26 | import android.app.SearchManager; 27 | import android.content.ContentProvider; 28 | import android.content.ContentValues; 29 | import android.content.Context; 30 | import android.content.Intent; 31 | import android.database.Cursor; 32 | import android.database.MatrixCursor; 33 | import android.net.Uri; 34 | import android.provider.BaseColumns; 35 | import java.io.IOException; 36 | import java.io.LineNumberReader; 37 | import java.util.Map; 38 | import java.util.TreeMap; 39 | 40 | public class ArchiveSuggestionsProvider extends ContentProvider 41 | { 42 | private static final String[] COLUMN_NAMES = { 43 | BaseColumns._ID, 44 | SearchManager.SUGGEST_COLUMN_TEXT_1, 45 | SearchManager.SUGGEST_COLUMN_TEXT_2, 46 | SearchManager.SUGGEST_COLUMN_INTENT_ACTION, 47 | SearchManager.SUGGEST_COLUMN_INTENT_DATA, 48 | SearchManager.SUGGEST_COLUMN_QUERY }; 49 | 50 | @Override 51 | public boolean onCreate() 52 | { 53 | return true; 54 | } 55 | 56 | @Override 57 | public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) 58 | { 59 | String query = uri.getLastPathSegment(); 60 | MatrixCursor cursor = new MatrixCursor(COLUMN_NAMES); 61 | TreeMap<String, Integer> authorToCount = new TreeMap<String, Integer>(); 62 | Context context = getContext(); 63 | Object[] columnValues = new Object[6]; 64 | try (LineNumberReader r = Util.openIndex(context)) { 65 | for (int id = 1; ; id++) { 66 | String name = r.readLine(); 67 | if (name == null) 68 | break; 69 | String title = r.readLine(); 70 | String authors = r.readLine(); 71 | /*String date =*/ r.readLine(); 72 | /*String songs =*/ r.readLine(); 73 | if (Util.matches(title, query)) { 74 | columnValues[0] = id; 75 | columnValues[1] = title; 76 | columnValues[2] = authors; 77 | columnValues[3] = Intent.ACTION_VIEW; 78 | columnValues[4] = "asma:" + Uri.encode(name); 79 | columnValues[5] = null; 80 | cursor.addRow(columnValues); 81 | } 82 | for (String author : authors.split(" & ")) { 83 | if (Util.matches(author, query)) { 84 | if (author.endsWith(" <?>")) 85 | author = author.substring(0, author.length() - 4); 86 | Integer count = authorToCount.get(author); 87 | authorToCount.put(author, count == null ? 1 : count + 1); 88 | } 89 | } 90 | } 91 | } 92 | catch (IOException ex) { 93 | // shouldn't happen 94 | } 95 | 96 | int id = -1; 97 | for (Map.Entry<String, Integer> entry : authorToCount.entrySet()) { 98 | columnValues[0] = id--; 99 | columnValues[1] = entry.getKey(); 100 | columnValues[2] = context.getString(R.string.author_suggestion_songs, entry.getValue()); 101 | columnValues[3] = Intent.ACTION_SEARCH; 102 | columnValues[4] = null; 103 | columnValues[5] = entry.getKey(); 104 | cursor.addRow(columnValues); 105 | } 106 | 107 | return cursor; 108 | } 109 | 110 | @Override 111 | public int delete(Uri uri, String selection, String[] selectionArgs) 112 | { 113 | return 0; 114 | } 115 | 116 | @Override 117 | public String getType(Uri uri) 118 | { 119 | return null; 120 | } 121 | 122 | @Override 123 | public Uri insert(Uri uri, ContentValues values) 124 | { 125 | return null; 126 | } 127 | 128 | @Override 129 | public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) 130 | { 131 | return 0; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /www/convert.xml: -------------------------------------------------------------------------------- 1 | <page title="Convert"> 2 | <p>In addition to playback, ASAP features conversion and editing metadata.</p> 3 | 4 | <h2>Exporting audio (WAV/MP3)</h2> 5 | <p>For playback on devices where ASAP does not run, you need to convert 6 | to popular audio formats such as WAV or MP3.</p> 7 | <p>This can be done using a general-purpose player with an ASAP plugin. 8 | For example, in <a href="https://www.foobar2000.org">foobar2000</a> 9 | select songs on the playlist, right-click and use the "Convert" menu.</p> 10 | <p>To convert from the command line:</p> 11 | <pre>asapconv -o .wav Lasermania.sap</pre> 12 | <p>To preserve metadata (title/author/year):</p> 13 | <pre>asapconv -o .wav --tag Lasermania.sap</pre> 14 | <p>The above will only convert the default subsong. You can select any subsong (counting from zero):</p> 15 | <pre>asapconv -o .wav -s 2 Lasermania.sap</pre> 16 | <p>Or convert every subsong to a separate file (with numbers in filenames):</p> 17 | <pre>asapconv -o Lasermania-%s.wav Lasermania.sap</pre> 18 | <p>You can convert many files at once and customize the output filenames 19 | using metadata from the source files:</p> 20 | <pre>asapconv -o "%a - %n - song %s.wav" --tag *.sap</pre> 21 | <p>On Windows, asapconv can output MP3 files using 22 | <code>libmp3lame.dll</code> or <code>lame_enc.dll</code> (not included in ASAP):</p> 23 | <pre>asapconv -o Lasermania-%s.mp3 --tag Lasermania.sap</pre> 24 | 25 | <h2>Exporting to Atari executables (XEX)</h2> 26 | <p>If you want to play music on your real Atari 8-bit computer, 27 | you can export SAP and the tracker formats to Atari executables (XEX format).</p> 28 | <p>On Windows, you can do this from the File Information window, which is available 29 | in the fooobar2000 plugin ("View/ASAP info" from the main menu), XMPlay, Winamp and WASAP.</p> 30 | <img src="info_dlg.png" alt="File Information window" /> 31 | <p>Click "Save as..." and select "Atari 8-bit executable" as the file type.</p> 32 | <p>Alternatively, use the command line:</p> 33 | <pre>asapconv -o .xex --tag Euglena_Zielona.tmc</pre> 34 | <p>The <code>--tag</code> option includes display of metadata and the remaining playback time 35 | on screen while running the program. Without it, the screen is blank.</p> 36 | <p>Like with WAV files, the above only converts the default subsong. 37 | Use the <code>-s</code> option or the <code>%s</code> output filename placeholder 38 | for subsongs.</p> 39 | 40 | <h2>Converting tracker formats to SAP</h2> 41 | <p>Atari 8-bit tracker files, such as RMT, can be converted to the SAP format. 42 | On Windows, use "Save as..." from the File Information window described above. 43 | On any operating system, you can use asapconv.</p> 44 | <p>Main reason for such a conversion is the ability to specify metadata. 45 | You can type it in the File Information window or specify on the command line:</p> 46 | <pre>asapconv -o Komar.sap -a "Lukasz Sychowicz (X-Ray)" -n "Komar" -d "2002" Komar.mpt</pre> 47 | 48 | <h2>Extracting tracker formats from SAP</h2> 49 | <p>A SAP file consists of metadata, 6502 code and data. 50 | If it was created directly from a tracker file as described above, 51 | the original tracker file can be extracted.</p> 52 | <p>Use "Save as..." on Windows or the following command line:</p> 53 | <pre>asapconv -o .rmt Colding.sap</pre> 54 | 55 | <h2>Editing metadata</h2> 56 | <p>You can edit metadata (title/author/date/time) in SAP files using:</p> 57 | <ul> 58 | <li>the File Information window</li> 59 | <li>Properties in foobar2000</li> 60 | <li>asapconv</li> 61 | <li>the Windows Explorer extension</li> 62 | </ul> 63 | <p>The File Information window is limited to editing one file at a time. 64 | The other methods can modify many files (for example, set the same author), for example:</p> 65 | <pre>asapconv -o .sap -a "Rob Hubbard" *.sap</pre> 66 | 67 | <h2>Relocating tracker formats</h2> 68 | <p>If you are developing a new Atari 8-bit program, you might need to adjust 69 | the loading address for your music file. Specify the requested address in hexadecimal:</p> 70 | <pre>asapconv --address=a000 -o relocated.rmt original.rmt</pre> 71 | 72 | <h2>Mass conversion</h2> 73 | <p>asapconv supports filename wildcards. 74 | To recursively process directories on Windows, use for example:</p> 75 | <pre>for /r ASMA %f in (*.sap) do @asapconv -o .%e %f</pre> 76 | <p>The above command will extract native modules in different formats 77 | and write them next to the SAP files in the ASMA directory. 78 | On macOS or Linux use:</p> 79 | <pre>find ASMA -name \*.sap -exec asapconv -o .%e {} \;</pre> 80 | </page> 81 | -------------------------------------------------------------------------------- /test/cpu_shx.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "6502 Undocumented SHX/SHY Test"',13,10 6 | dta c'DATE "27/11/2010"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 00:10',13,10 10 | opt h+ 11 | eif 12 | 13 | addr equ $80 ; 2 bytes 14 | index equ $82 15 | data equ $83 16 | dest equ $84 ; 2 bytes 17 | expected equ $86 18 | opcode equ $87 19 | got equ $88 20 | pos equ $89 21 | scrptr equ $8a ; 2 bytes 22 | printptr equ $8c ; 2 bytes 23 | 24 | org f:$3000 25 | main 26 | :SAP mwa #$1000 scrptr 27 | lda <title 28 | ldx >title 29 | jsr print 30 | 31 | :!SAP sei:inc $d40e 32 | :!SAP mva #$fe $d301 33 | ldx #0 34 | loop 35 | stx pos 36 | mwa input,x addr 37 | mva input+2,x index 38 | mva input+3,x data 39 | jsr do_test 40 | ldx pos 41 | inx 42 | bne loop 43 | 44 | :!SAP mva #$ff $d301 45 | lda <pass 46 | ldx >pass 47 | jsr print 48 | mwa #$af30 $d200 49 | jmp * 50 | 51 | do_test 52 | lda addr 53 | add index 54 | sta dest 55 | php 56 | lda addr+1 57 | add #1 58 | and data 59 | sta expected 60 | plp 61 | scs:lda addr+1 62 | sta dest+1 63 | cmp #0 64 | bne no_zp 65 | lda dest 66 | and #$f0 67 | cmp #$80 68 | bne run 69 | beq skip ! 70 | no_zp 71 | and #$f8 72 | cmp #$10 73 | beq skip 74 | cmp #$30 75 | beq skip 76 | cmp #$d0 77 | beq skip 78 | run 79 | mwa addr shx+1 80 | mwa addr shy+1 81 | lda expected 82 | eor #$ff 83 | sta (dest),0 84 | ldx data 85 | ldy index 86 | shx dta $9e,a(0) 87 | ldx #$9e 88 | lda (dest),0 89 | cmp expected 90 | bne error 91 | eor #$ff 92 | sta (dest),y 93 | ldy data 94 | ldx index 95 | shy dta $9c,a(0) 96 | ldx #$9c 97 | lda (dest),0 98 | cmp expected 99 | bne error 100 | skip 101 | rts 102 | 103 | error 104 | :!SAP mva #$ff $d301 105 | stx opcode 106 | sta got 107 | lda <fail 108 | ldx >fail 109 | jsr print 110 | lda opcode 111 | jsr put_hex_byte 112 | lda addr 113 | jsr put_hex_byte 114 | lda addr+1 115 | jsr put_hex_byte 116 | lda <xequ 117 | ldx >xequ 118 | jsr print 119 | lda data 120 | ldx opcode 121 | cpx #$9e 122 | seq:lda index 123 | jsr put_hex_byte 124 | lda <yequ 125 | ldx >yequ 126 | jsr print 127 | lda index 128 | ldx opcode 129 | cpx #$9e 130 | seq:lda data 131 | jsr put_hex_byte 132 | lda <gott 133 | ldx >gott 134 | jsr print 135 | lda got 136 | jsr put_hex_byte 137 | lda <exp 138 | ldx >exp 139 | jsr print 140 | lda expected 141 | jsr put_hex_byte 142 | lda #$9b 143 | jsr put_char 144 | mwa #$cfa0 $d200 145 | jmp * 146 | 147 | put_hex_byte 148 | pha 149 | :4 lsr @ 150 | jsr put_hex_nibble 151 | pla 152 | and #$f 153 | put_hex_nibble 154 | cmp #10 155 | sed 156 | adc #'0' 157 | cld 158 | put_char 159 | ift SAP 160 | sta (scrptr),0 161 | inw scrptr 162 | rts 163 | els 164 | mvx #11 $342 165 | mwx #0 $348 166 | jmp $e456 167 | eif 168 | 169 | print 170 | sta printptr 171 | stx printptr+1 172 | jmp print_2 173 | print_1 174 | jsr put_char 175 | inw printptr 176 | print_2 177 | lda (printptr),0 178 | bne print_1 179 | rts 180 | 181 | ; just some random data 182 | input 183 | dta $73,$c3,$26,$17,$3b,$9b,$82,$06,$6e,$f8,$c6,$74,$83,$6c,$d6,$7c 184 | dta $5b,$4f,$33,$72,$ef,$55,$69,$3f,$64,$f1,$02,$21,$ea,$51,$ad,$d8 185 | dta $55,$41,$bd,$cc,$c9,$b3,$a7,$30,$78,$41,$ab,$ac,$bc,$61,$49,$94 186 | dta $95,$a0,$b4,$37,$da,$aa,$e2,$50,$0f,$5f,$66,$12,$4d,$c4,$b7,$f4 187 | dta $1b,$1a,$18,$a2,$a2,$df,$b6,$36,$27,$f7,$33,$3a,$33,$e2,$49,$6e 188 | dta $4d,$25,$94,$f2,$b4,$c4,$50,$be,$f8,$0d,$10,$13,$e3,$82,$32,$cb 189 | dta $9a,$1a,$1e,$2a,$52,$bb,$14,$25,$90,$1d,$96,$b9,$54,$e8,$2d,$45 190 | dta $19,$5b,$9b,$86,$0e,$34,$3a,$2c,$77,$35,$9b,$91,$9d,$f8,$17,$a9 191 | dta $2a,$70,$7a,$9e,$6b,$ce,$6f,$35,$4e,$1d,$d2,$6c,$95,$53,$95,$77 192 | dta $17,$27,$5a,$83,$7e,$76,$74,$65,$6e,$74,$6a,$a5,$75,$79,$ac,$02 193 | dta $af,$b5,$a2,$e1,$89,$87,$be,$c3,$87,$cd,$ae,$41,$74,$ea,$69,$8e 194 | dta $ed,$d6,$2a,$1d,$a3,$eb,$17,$5a,$43,$d2,$a7,$0e,$6b,$43,$7b,$73 195 | dta $92,$ec,$d3,$7a,$50,$3b,$3e,$57,$e6,$65,$b9,$c9,$75,$5f,$d8,$3a 196 | dta $ca,$1e,$2c,$33,$26,$dd,$85,$28,$e9,$bd,$45,$34,$8a,$79,$59,$c1 197 | dta $c7,$7c,$10,$9d,$6b,$28,$75,$9e,$a0,$89,$4a,$40,$26,$49,$5b,$54 198 | dta $64,$1a,$48,$49,$b5,$7e,$68,$0f,$d6,$0e,$00,$27,$e2,$26,$62,$d7 199 | 200 | title dta c'CPU: SHX/SHY...',0 201 | pass dta c'Pass',$9b,0 202 | fail dta c'FAIL.',$9b,c'Code:',0 203 | xequ dta c' X=',0 204 | yequ dta c' Y=',0 205 | gott dta c' got ',0 206 | exp dta c' exp ',0 207 | 208 | ift !SAP 209 | run main 210 | eif 211 | -------------------------------------------------------------------------------- /test/antic_wsync.asx: -------------------------------------------------------------------------------- 1 | ift SAP 2 | opt h- 3 | dta c'SAP',13,10 4 | dta c'AUTHOR "Piotr Fusik (0xF)"',13,10 5 | dta c'NAME "ANTIC WSYNC Test"',13,10 6 | dta c'DATE "19/05/2011"',13,10 7 | dta c'TYPE D',13,10 8 | dta c'INIT 3000',13,10 9 | dta c'TIME 00:10',13,10 10 | opt h+ 11 | eif 12 | 13 | div5 equ $80 14 | mod5 equ $81 15 | scrptr equ $8a ; 2 bytes 16 | printptr equ $8c ; 2 bytes 17 | 18 | org f:$3000 19 | main 20 | :SAP mwa #$1000 scrptr 21 | lda <title 22 | ldx >title 23 | jsr print 24 | 25 | :!SAP sei:inc ^4e 26 | :!SAP inc ^40 27 | 28 | ldx #1 29 | stx div5 30 | dex 31 | stx 0 32 | stx ^28 33 | ldy #0 34 | test_loop 35 | stx mod5 36 | mva cmps,x cmpd 37 | sta cmpd2 38 | sta cmpd3 39 | sta cmpd4 40 | 41 | mva #0 ^2f 42 | :2 sta ^4a 43 | mva #3 ^2f 44 | ldx div5 45 | dex:rne 46 | cmpd cmp #0 47 | sta ^4a 48 | lda ^2a 49 | cmp sta_wsync,y 50 | jne error 51 | 52 | mva #0 ^2f 53 | :2 sta ^4a 54 | mva #3 ^2f 55 | ldx div5 56 | dex:rne 57 | cmpd2 cmp #0 58 | sta ^4a,x 59 | lda ^2a 60 | cmp sta_wsync+1,y 61 | bne error 62 | 63 | mva #0 ^2f 64 | :2 sta ^4a 65 | mva #3 ^2f 66 | ldx div5 67 | dex:rne 68 | cmpd3 cmp #0 69 | inc ^4a 70 | lda ^2a 71 | cmp inc_wsync,y 72 | bne error 73 | 74 | mva #0 ^2f 75 | :2 sta ^4a 76 | mva #3 ^2f 77 | ldx div5 78 | dex:rne 79 | cmpd4 cmp #0 80 | inc ^4a,x 81 | lda ^2a 82 | cmp inc_wsync+1,y 83 | bne error 84 | 85 | ldx mod5 86 | inx 87 | cpx #5 88 | bcc same5 89 | inc div5 90 | ldx #0 91 | same5 iny 92 | jne test_loop 93 | 94 | lsr:cli ^4e 95 | lda <pass 96 | ldx >pass 97 | jsr print 98 | mwa #$af30 $d200 99 | jmp * 100 | 101 | error 102 | lsr:cli ^4e 103 | lda <fail 104 | ldx >fail 105 | jsr print 106 | mwa #$cfa0 $d200 107 | jmp * 108 | 109 | put_char 110 | ift SAP 111 | sta (scrptr),0 112 | inw scrptr 113 | rts 114 | els 115 | mvx #11 $342 116 | mwx #0 $348 117 | jmp $e456 118 | eif 119 | 120 | print 121 | sta printptr 122 | stx printptr+1 123 | jmp print_2 124 | print_1 125 | jsr put_char 126 | inw printptr 127 | print_2 128 | lda (printptr),0 129 | bne print_1 130 | rts 131 | 132 | title dta c'ANTIC: WSYNC...',0 133 | pass dta c'Pass',$9b,0 134 | fail dta c'FAIL.',$9b,0 135 | 136 | cmps dta {cmp #},{cmp 0},{cmp 0,x},{cmp (0),y},{cmp (0,x)} 137 | 138 | sta_wsync 139 | dta $21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21 140 | dta $10,$21,$21,$10,$21,$21,$10,$21,$21,$10,$21,$21,$10,$21,$21,$10 141 | dta $21,$21,$10,$21,$21,$10,$21,$21,$10,$21,$21,$21,$21,$21,$21,$21 142 | dta $21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21 143 | dta $21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21 144 | dta $21,$21,$21,$21,$21,$21,$21,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6 145 | dta $F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6 146 | dta $F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$7B,$F6,$F6,$7B,$F6,$F6,$7B 147 | dta $F6,$F6,$7B,$F6,$F6,$7B,$F6,$F6,$7B,$F6,$F6,$7B,$F6,$F6,$7B,$F6 148 | dta $F6,$7B,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6 149 | dta $F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6 150 | dta $F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6,$F6 151 | dta $D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9 152 | dta $D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9,$D9 153 | dta $D9,$D9,$6C,$D9,$D9,$6C,$D9,$D9,$6C,$D9,$D9,$6C,$D9,$D9,$6C,$D9 154 | dta $D9,$6C,$D9,$D9,$6C,$D9,$D9,$6C,$D9,$D9,$6C,$D9,$D9,$D9,$D9,$D9 155 | dta $D9 156 | inc_wsync 157 | dta $10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10 158 | dta $10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10 159 | dta $10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10 160 | dta $10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10 161 | dta $10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10 162 | dta $10,$10,$10,$10,$10,$F6,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B 163 | dta $7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B 164 | dta $7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B 165 | dta $7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B 166 | dta $7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B 167 | dta $7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B 168 | dta $7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$7B,$D9,$6C 169 | dta $6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C 170 | dta $6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C 171 | dta $6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C 172 | dta $6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C,$6C 173 | dta $6C 174 | 175 | ift !SAP 176 | run main 177 | eif 178 | -------------------------------------------------------------------------------- /release/release.mk: -------------------------------------------------------------------------------- 1 | GIT = git 2 | TAR = /usr/bin/tar 3 | UNIX2DOS = $(DO)unix2dos <$< >$@ 4 | GREP = @grep -H 5 | 6 | # no user-configurable paths below this line 7 | 8 | VERSION = 5.3.0 9 | 10 | ifndef DO 11 | $(error Use "Makefile" instead of "release.mk") 12 | endif 13 | 14 | dist: \ 15 | release/asap-$(VERSION)-android.apk \ 16 | release/asap-$(VERSION)-web.zip \ 17 | release/asap-$(VERSION)-win32.zip \ 18 | release/signed-msi \ 19 | release/foo_asap-$(VERSION).fb2k-component \ 20 | srcdist 21 | .PHONY: dist 22 | 23 | srcdist: $(srcdir)MANIFEST $(srcdir)asap.c $(srcdir)asap.h $(ASM6502_OBX) 24 | $(RM) release/asap-$(VERSION).tar.gz && $(TAR) -c --numeric-owner --owner=0 --group=0 --mode=644 -T MANIFEST --transform=s,,asap-$(VERSION)/, | $(SEVENZIP) -tgzip -si release/asap-$(VERSION).tar.gz 25 | .PHONY: srcdist 26 | 27 | $(srcdir)MANIFEST: 28 | $(DO)if test -e $(srcdir).git; then \ 29 | ($(GIT) ls-files | grep -vF .gitignore \ 30 | && echo MANIFEST && echo asap.c && echo asap.h \ 31 | && for obx in $(ASM6502_OBX); do echo $$obx; done) | /usr/bin/sort -u >$@; \ 32 | fi 33 | .PHONY: $(srcdir)MANIFEST 34 | 35 | release/asap-$(VERSION)-web.zip: release/COPYING.txt \ 36 | javascript/asap.js $(srcdir)javascript/asapweb.js 37 | $(MAKEZIP) 38 | 39 | release/asap-$(VERSION)-win32.zip: release/COPYING.txt \ 40 | $(addprefix win32/,asapconv.exe asapscan.exe wasap.exe in_asap.dll foo_asap.dll apokeysnd.dll xmp-asap.dll bass_asap.dll ASAPShellEx.dll libasap_plugin.dll signed) 41 | $(MAKEZIP) 42 | 43 | release/foo_asap-$(VERSION).fb2k-component: win32/foo_asap.dll win32/x64/foo_asap.dll win32/signed 44 | $(DO)$(RM) $@ && $(SEVENZIP) -tzip $@ -imr!./win32/foo_asap.dll 45 | 46 | release/asap-$(VERSION)-macos.dmg: release/osx/libasap_plugin.dylib release/osx/plugins release/osx/asapconv release/osx/bin 47 | ifdef PORK_CODESIGNING_IDENTITY 48 | codesign --options runtime -f -s $(PORK_CODESIGNING_IDENTITY) release/osx/libasap_plugin.dylib 49 | codesign --options runtime -f -s $(PORK_CODESIGNING_IDENTITY) release/osx/asapconv 50 | endif 51 | $(DO)hdiutil create -volname asap-$(VERSION)-macos -srcfolder release/osx -format UDBZ -fs HFS+ -imagekey bzip2-level=3 -ov $@ 52 | ifdef PORK_NOTARIZING_CREDENTIALS 53 | xcrun altool --notarize-app --primary-bundle-id net.sf.asap $(PORK_NOTARIZING_CREDENTIALS) --file $@ \ 54 | | perl -pe 's/^RequestUUID =/xcrun altool $$ENV{PORK_NOTARIZING_CREDENTIALS} --notarization-info/ or next; $$c = $$_; until (/Status: success/) { sleep 20; $$_ = `$$c`; print; } last;' 55 | endif 56 | 57 | release/osx/libasap_plugin.dylib: libasap_plugin.dylib 58 | $(DO)strip -o $@ -x $< && chmod 644 $@ 59 | CLEANDIR += release/osx 60 | 61 | release/osx/plugins: 62 | $(DO)ln -s /Applications/VLC.app/Contents/MacOS/plugins $@ 63 | 64 | release/osx/asapconv: $(call src,asapconv.c asap.[ch]) 65 | $(OSX_CC) 66 | 67 | release/osx/bin: 68 | $(DO)ln -s /usr/local/bin $@ 69 | 70 | deb: 71 | debuild -b -us -uc 72 | .PHONY: deb 73 | 74 | deb64: 75 | scp release/asap-$(VERSION).tar.gz vm:. 76 | ssh vm 'rm -rf asap-$(VERSION) && tar xf asap-$(VERSION).tar.gz && make -C asap-$(VERSION) deb' 77 | scp vm:asap_$(VERSION)-1_amd64.deb release/ 78 | scp vm:asap-dev_$(VERSION)-1_amd64.deb release/ 79 | scp vm:asap-vlc_$(VERSION)-1_amd64.deb release/ 80 | scp vm:asap-xmms2_$(VERSION)-1_amd64.deb release/ 81 | .PHONY: deb64 82 | 83 | rpm64: 84 | scp release/asap-$(VERSION).tar.gz vm:. 85 | ssh vm 'rpmbuild -tb asap-$(VERSION).tar.gz' 86 | scp vm:rpmbuild/RPMS/x86_64/asap-$(VERSION)-1.x86_64.rpm release/ 87 | scp vm:rpmbuild/RPMS/x86_64/asap-devel-$(VERSION)-1.x86_64.rpm release/ 88 | scp vm:rpmbuild/RPMS/x86_64/asap-vlc-$(VERSION)-1.x86_64.rpm release/ 89 | scp vm:rpmbuild/RPMS/x86_64/asap-xmms2-$(VERSION)-1.x86_64.rpm release/ 90 | .PHONY: rpm64 91 | 92 | mac: 93 | scp release/asap-$(VERSION).tar.gz mac:. 94 | ssh mac 'security unlock-keychain ~/Library/Keychains/login.keychain && rm -rf asap-$(VERSION) && tar xf asap-$(VERSION).tar.gz && make -C asap-$(VERSION) release/asap-$(VERSION)-macos.dmg' 95 | scp mac:asap-$(VERSION)/release/asap-$(VERSION)-macos.dmg release/ 96 | .PHONY: mac 97 | 98 | release/COPYING.txt: $(srcdir)COPYING 99 | $(UNIX2DOS) 100 | CLEAN += release/COPYING.txt 101 | 102 | version: 103 | @echo ./release/release.mk: VERSION=$(VERSION) 104 | $(GREP) -m 1 version= $(srcdir)www/news.xml 105 | $(GREP) "<since>" $(srcdir)PORTS.xml | /usr/bin/sort -ru | head -1 106 | $(GREP) Version: $(srcdir)asap.spec 107 | $(GREP) -m 1 ^asap $(srcdir)debian/changelog 108 | $(GREP) "int Version" $(srcdir)asapinfo.fu 109 | $(GREP) "VERSION =" $(srcdir)chksap.pl 110 | $(GREP) android:versionName $(srcdir)java/android/AndroidManifest.xml 111 | $(GREP) ", v" $(srcdir)win32/rmt/apokeysnd_dll.c 112 | .PHONY: version 113 | -------------------------------------------------------------------------------- /win32/winamp/in2.h: -------------------------------------------------------------------------------- 1 | #include "out.h" 2 | 3 | // note: exported symbol is now winampGetInModule2. 4 | 5 | #define IN_VER 0x100 6 | 7 | typedef struct 8 | { 9 | int version; // module type (IN_VER) 10 | char *description; // description of module, with version string 11 | 12 | HWND hMainWindow; // winamp's main window (filled in by winamp) 13 | HINSTANCE hDllInstance; // DLL instance handle (Also filled in by winamp) 14 | 15 | char *FileExtensions; // "mp3\0Layer 3 MPEG\0mp2\0Layer 2 MPEG\0mpg\0Layer 1 MPEG\0" 16 | // May be altered from Config, so the user can select what they want 17 | 18 | int is_seekable; // is this stream seekable? 19 | int UsesOutputPlug; // does this plug-in use the output plug-ins? (musn't ever change, ever :) 20 | 21 | void (*Config)(HWND hwndParent); // configuration dialog 22 | void (*About)(HWND hwndParent); // about dialog 23 | 24 | void (*Init)(); // called at program init 25 | void (*Quit)(); // called at program quit 26 | 27 | void (*GetFileInfo)(char *file, char *title, int *length_in_ms); // if file == NULL, current playing is used 28 | int (*InfoBox)(char *file, HWND hwndParent); 29 | 30 | int (*IsOurFile)(char *fn); // called before extension checks, to allow detection of mms://, etc 31 | // playback stuff 32 | int (*Play)(char *fn); // return zero on success, -1 on file-not-found, some other value on other (stopping winamp) error 33 | void (*Pause)(); // pause stream 34 | void (*UnPause)(); // unpause stream 35 | int (*IsPaused)(); // ispaused? return 1 if paused, 0 if not 36 | void (*Stop)(); // stop (unload) stream 37 | 38 | // time stuff 39 | int (*GetLength)(); // get length in ms 40 | int (*GetOutputTime)(); // returns current output time in ms. (usually returns outMod->GetOutputTime() 41 | void (*SetOutputTime)(int time_in_ms); // seeks to point in stream (in ms). Usually you signal yoru thread to seek, which seeks and calls outMod->Flush().. 42 | 43 | // volume stuff 44 | void (*SetVolume)(int volume); // from 0 to 255.. usually just call outMod->SetVolume 45 | void (*SetPan)(int pan); // from -127 to 127.. usually just call outMod->SetPan 46 | 47 | // in-window builtin vis stuff 48 | 49 | void (*SAVSAInit)(int maxlatency_in_ms, int srate); // call once in Play(). maxlatency_in_ms should be the value returned from outMod->Open() 50 | // call after opening audio device with max latency in ms and samplerate 51 | void (*SAVSADeInit)(); // call in Stop() 52 | 53 | 54 | // simple vis supplying mode 55 | void (*SAAddPCMData)(void *PCMData, int nch, int bps, int timestamp); 56 | // sets the spec data directly from PCM data 57 | // quick and easy way to get vis working :) 58 | // needs at least 576 samples :) 59 | 60 | // advanced vis supplying mode, only use if you're cool. Use SAAddPCMData for most stuff. 61 | int (*SAGetMode)(); // gets csa (the current type (4=ws,2=osc,1=spec)) 62 | // use when calling SAAdd() 63 | void (*SAAdd)(void *data, int timestamp, int csa); // sets the spec data, filled in by winamp 64 | 65 | 66 | // vis stuff (plug-in) 67 | // simple vis supplying mode 68 | void (*VSAAddPCMData)(void *PCMData, int nch, int bps, int timestamp); // sets the vis data directly from PCM data 69 | // quick and easy way to get vis working :) 70 | // needs at least 576 samples :) 71 | 72 | // advanced vis supplying mode, only use if you're cool. Use VSAAddPCMData for most stuff. 73 | int (*VSAGetMode)(int *specNch, int *waveNch); // use to figure out what to give to VSAAdd 74 | void (*VSAAdd)(void *data, int timestamp); // filled in by winamp, called by plug-in 75 | 76 | 77 | // call this in Play() to tell the vis plug-ins the current output params. 78 | void (*VSASetInfo)(int nch, int srate); 79 | 80 | 81 | // dsp plug-in processing: 82 | // (filled in by winamp, called by input plug) 83 | 84 | // returns 1 if active (which means that the number of samples returned by dsp_dosamples 85 | // could be greater than went in.. Use it to estimate if you'll have enough room in the 86 | // output buffer 87 | int (*dsp_isactive)(); 88 | 89 | // returns number of samples to output. This can be as much as twice numsamples. 90 | // be sure to allocate enough buffer for samples, then. 91 | int (*dsp_dosamples)(short int *samples, int numsamples, int bps, int nch, int srate); 92 | 93 | 94 | // eq stuff 95 | void (*EQSet)(int on, char data[10], int preamp); // 0-64 each, 31 is +0, 0 is +12, 63 is -12. Do nothing to ignore. 96 | 97 | // info setting (filled in by winamp) 98 | void (*SetInfo)(int bitrate, int srate, int stereo, int synched); // if -1, changes ignored? :) 99 | 100 | Out_Module *outMod; // filled in by winamp, optionally used :) 101 | } In_Module; 102 | 103 | 104 | -------------------------------------------------------------------------------- /python/asap2wav.py: -------------------------------------------------------------------------------- 1 | # asap2wav.py - converter of ASAP-supported formats to WAV files 2 | # 3 | # Copyright (C) 2020 Piotr Fusik 4 | # 5 | # This file is part of ASAP (Another Slight Atari Player), 6 | # see http://asap.sourceforge.net 7 | # 8 | # ASAP is free software; you can redistribute it and/or modify it 9 | # under the terms of the GNU General Public License as published 10 | # by the Free Software Foundation; either version 2 of the License, 11 | # or (at your option) any later version. 12 | # 13 | # ASAP is distributed in the hope that it will be useful, 14 | # but WITHOUT ANY WARRANTY; without even the implied warranty 15 | # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 16 | # See the GNU General Public License for more details. 17 | # 18 | # You should have received a copy of the GNU General Public License 19 | # along with ASAP; if not, write to the Free Software Foundation, Inc., 20 | # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21 | 22 | from asap import ASAP, ASAPInfo, ASAPSampleFormat 23 | from pathlib import Path 24 | import sys 25 | 26 | output_filename = None 27 | song = None 28 | sample_rate = 44100 29 | duration = None 30 | format = ASAPSampleFormat.S16_L_E 31 | output_header = True 32 | mute_mask = 0 33 | 34 | def print_help(): 35 | print( 36 | "Usage: python asap2wav.py [OPTIONS] INPUTFILE...\n" 37 | "Each INPUTFILE must be in a supported format:\n" 38 | "SAP, CMC, CM3, CMR, CMS, DMC, DLT, MPT, MPD, RMT, TMC, TM8, TM2 or FC.\n" 39 | "Options:\n" 40 | "-o FILE --output=FILE Set output file name\n" 41 | "-s SONG --song=SONG Select subsong number (zero-based)\n" 42 | "-t TIME --time=TIME Set output length (MM:SS format)\n" 43 | "-b --byte-samples Output 8-bit samples\n" 44 | "-w --word-samples Output 16-bit samples (default)\n" 45 | " --raw Output raw audio (no WAV header)\n" 46 | "-R RATE --sample-rate=RATE Set output sample rate to RATE Hz\n" 47 | "-m CHANNELS --mute=CHANNELS Mute POKEY channels (1-8)\n" 48 | "-h --help Display this information\n" 49 | "-v --version Display version information") 50 | 51 | def set_mute_mask(s): 52 | mute_mask = 0 53 | for c in s: 54 | if "1" <= c <= "8": 55 | mute_mask |= 1 << (int(c) - 1) 56 | 57 | def process_file(input_filename): 58 | with open(input_filename, "rb") as f: module = f.read() 59 | asap = ASAP() 60 | asap.set_sample_rate(sample_rate) 61 | asap.load(input_filename, module, len(module)) 62 | info = asap.get_info() 63 | global output_filename, song, duration, format, output_header, mute_mask 64 | if song is None: 65 | song = info.get_default_song() 66 | if duration is None: 67 | duration = info.get_duration(song) 68 | if duration < 0: 69 | duration = 180_000 70 | asap.play_song(song, duration) 71 | asap.mute_pokey_channels(mute_mask) 72 | if output_filename is None: 73 | output_filename = Path(input_filename).with_suffix(".wav" if output_header else ".raw") 74 | buffer = bytearray(8192) 75 | with sys.stdout.buffer if output_filename == "-" else open(output_filename, "wb") as f: 76 | if output_header: 77 | buffer_len = asap.get_wav_header(buffer, format, False) 78 | f.write(buffer[:buffer_len]) 79 | buffer_len = 8192 80 | while buffer_len == 8192: 81 | buffer_len = asap.generate(buffer, 8192, format) 82 | f.write(buffer[:buffer_len]) 83 | output_filename = None 84 | song = None 85 | duration = None 86 | 87 | args = sys.argv[1:] 88 | no_input_files = True 89 | while (args): 90 | arg = args.pop(0) 91 | if arg[0] != "-": 92 | process_file(arg) 93 | no_input_files = False 94 | elif arg == "-o": 95 | output_filename = args.pop(0) 96 | elif arg.startswith("--output="): 97 | output_filename = arg[9:] 98 | elif arg == "-s": 99 | song = int(args.pop(0)) 100 | elif arg.startswith("--song="): 101 | song = int(arg[7:]) 102 | elif arg == "-t": 103 | duration = ASAPInfo.parse_duration(args.pop(0)) 104 | elif arg.startswith("--time="): 105 | duration = ASAPInfo.parse_duration(arg[7:]) 106 | elif arg == "-b" or arg == "--byte-samples": 107 | format = ASAPSampleFormat.U8 108 | elif arg == "-w" or arg == "--word-samples": 109 | format = ASAPSampleFormat.S16_L_E 110 | elif arg == "--raw": 111 | output_header = False 112 | elif arg == "-R": 113 | sample_rate = int(args.pop(0)) 114 | elif arg.startswith("--sample-rate"): 115 | sample_rate = int(arg[13:]) 116 | elif arg == "-m": 117 | set_mute_mask(args.pop(0)) 118 | elif arg == "--mute=": 119 | set_mute_mask(arg[7:]) 120 | elif arg == "-h" or arg == "--help": 121 | print_help() 122 | no_input_files = False 123 | elif arg == "-v" or arg == "--version": 124 | print("ASAP2WAV (Python)", ASAPInfo.VERSION) 125 | no_input_files = False 126 | else: 127 | raise Exception("unknown option: " + arg) 128 | if no_input_files: 129 | print_help() 130 | sys.exit(1) 131 | --------------------------------------------------------------------------------