libsidplayfp-3.0.0/0000755000175100017510000000000015175333725007752 5libsidplayfp-3.0.0/test/0000755000175100017510000000000015175333725010731 5libsidplayfp-3.0.0/test/test.cpp0000644000175100017510000001316615175333711012336 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2026 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include "sidplayfp/sidplayfp.h" #include "sidplayfp/SidTune.h" #include "sidplayfp/sidbuilder.h" #include "builders/residfp-builder/residfp.h" #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "sidcxx11.h" /* * Adjust these paths to point to existing ROM dumps */ #define KERNAL_PATH "/usr/share/vice/C64/kernal-901227-03.bin" #define BASIC_PATH "/usr/share/vice/C64/basic-901226-01.bin" #define CHARGEN_PATH "/usr/share/vice/C64/chargen-901225-01.bin" void loadRom(const char* path, char* buffer) { std::ifstream is(path, std::ios::binary); if (!is.is_open()) { std::cout << "File " << path << " not found" << std::endl; exit(EXIT_FAILURE); } is.read(buffer, 8192); is.close(); } int main(int argc, char* argv[]) { if (argc < 2) { std::cerr << "Missing test name" << std::endl; return -1; } sidplayfp m_engine; char rom[8192]; loadRom(KERNAL_PATH, rom); m_engine.setKernal((const uint8_t*)rom); loadRom(BASIC_PATH, rom); m_engine.setBasic((const uint8_t*)rom); loadRom(CHARGEN_PATH, rom); m_engine.setChargen((const uint8_t*)rom); SidConfig config = m_engine.config(); config.powerOnDelay = 0x1267; std::string name(VICE_TESTSUITE); int i = 1; while ((i < argc) && (argv[i] != nullptr)) { if ((argv[i][0] == '-') && (argv[i][1] != '\0')) { if (!strcmp(&argv[i][1], "-sid")) { i++; if (!strcmp(&argv[i][0], "old")) { config.sidEmulation = new ReSIDfpBuilder("test"); config.forceSidModel = true; config.defaultSidModel = SidConfig::MOS6581; } else if (!strcmp(&argv[i][0], "new")) { config.sidEmulation = new ReSIDfpBuilder("test"); config.forceSidModel = true; config.defaultSidModel = SidConfig::MOS8580; } else { std::cerr << "Error: unrecognized SID model" << std::endl; return -1; } } if (!strcmp(&argv[i][1], "-cia")) { i++; if (!strcmp(&argv[i][0], "old")) { config.ciaModel = SidConfig::MOS6526; } else if (!strcmp(&argv[i][0], "new")) { config.ciaModel = SidConfig::MOS8521; } else if (!strcmp(&argv[i][0], "4485")) { config.ciaModel = SidConfig::MOS6526W4485; } else { std::cerr << "Error: unrecognized CIA model" << std::endl; return -1; } } if (!strcmp(&argv[i][1], "-vic")) { i++; if (!strcmp(&argv[i][0], "pal")) { config.defaultC64Model = SidConfig::PAL; config.forceC64Model = true; } else if (!strcmp(&argv[i][0], "ntsc")) { config.defaultC64Model = SidConfig::NTSC; config.forceC64Model = true; } else if (!strcmp(&argv[i][0], "oldntsc")) { config.defaultC64Model = SidConfig::OLD_NTSC; config.forceC64Model = true; } else if (!strcmp(&argv[i][0], "drean")) { config.defaultC64Model = SidConfig::DREAN; config.forceC64Model = true; } else { std::cerr << "Error: unrecognized VIC II model" << std::endl; return -1; } } if (!strcmp(&argv[i][1], "-debug")) { m_engine.debug(true, nullptr); } } else { name.append(argv[i]).append(".prg"); } i++; } m_engine.config(config); std::unique_ptr tune(new SidTune(name.c_str())); if (!tune->getStatus()) { std::cerr << "Error: " << tune->statusString() << std::endl; return -1; } tune->selectSong(0); if (!m_engine.load(tune.get())) { std::cerr << m_engine.error() << std::endl; return -1; } for (;;) { m_engine.play(5000); std::cerr << "."; } } libsidplayfp-3.0.0/test/testlist0000644000175100017510000010503015175333711012441 ### general ### general/banking00/banking00 #general/fuxxortest/test-fuxxored general/fuxxortest/ef1-nmi # sprite collision, won't work #general/fuxxortest/ef2-inst2 #general/fuxxortest/ef2-inst3 #general/fuxxortest/ef2-inst4a #general/fuxxortest/ef2-inst4c general/fuxxortest/ef2-inst4b --sid old general/Lorenz-2.15/src/start general/Lorenz-2.15/src/ldab general/Lorenz-2.15/src/ldaz general/Lorenz-2.15/src/ldazx general/Lorenz-2.15/src/ldaa general/Lorenz-2.15/src/ldaax general/Lorenz-2.15/src/ldaay general/Lorenz-2.15/src/ldaix general/Lorenz-2.15/src/ldaiy general/Lorenz-2.15/src/staz general/Lorenz-2.15/src/stazx general/Lorenz-2.15/src/staa general/Lorenz-2.15/src/staax general/Lorenz-2.15/src/staay general/Lorenz-2.15/src/staix general/Lorenz-2.15/src/staiy general/Lorenz-2.15/src/ldxb general/Lorenz-2.15/src/ldxz general/Lorenz-2.15/src/ldxzy general/Lorenz-2.15/src/ldxa general/Lorenz-2.15/src/ldxay general/Lorenz-2.15/src/stxz general/Lorenz-2.15/src/stxzy general/Lorenz-2.15/src/stxa general/Lorenz-2.15/src/ldyb general/Lorenz-2.15/src/ldyz general/Lorenz-2.15/src/ldyzx general/Lorenz-2.15/src/ldya general/Lorenz-2.15/src/ldyax general/Lorenz-2.15/src/styz general/Lorenz-2.15/src/styzx general/Lorenz-2.15/src/stya general/Lorenz-2.15/src/taxn general/Lorenz-2.15/src/tayn general/Lorenz-2.15/src/txan general/Lorenz-2.15/src/tyan general/Lorenz-2.15/src/tsxn general/Lorenz-2.15/src/txsn general/Lorenz-2.15/src/phan general/Lorenz-2.15/src/plan general/Lorenz-2.15/src/phpn general/Lorenz-2.15/src/plpn general/Lorenz-2.15/src/inxn general/Lorenz-2.15/src/inyn general/Lorenz-2.15/src/dexn general/Lorenz-2.15/src/deyn general/Lorenz-2.15/src/incz general/Lorenz-2.15/src/inczx general/Lorenz-2.15/src/inca general/Lorenz-2.15/src/incax general/Lorenz-2.15/src/decz general/Lorenz-2.15/src/deczx general/Lorenz-2.15/src/deca general/Lorenz-2.15/src/decax general/Lorenz-2.15/src/asln general/Lorenz-2.15/src/aslz general/Lorenz-2.15/src/aslzx general/Lorenz-2.15/src/asla general/Lorenz-2.15/src/aslax general/Lorenz-2.15/src/lsrn general/Lorenz-2.15/src/lsrz general/Lorenz-2.15/src/lsrzx general/Lorenz-2.15/src/lsra general/Lorenz-2.15/src/lsrax general/Lorenz-2.15/src/roln general/Lorenz-2.15/src/rolz general/Lorenz-2.15/src/rolzx general/Lorenz-2.15/src/rola general/Lorenz-2.15/src/rolax general/Lorenz-2.15/src/rorn general/Lorenz-2.15/src/rorz general/Lorenz-2.15/src/rorzx general/Lorenz-2.15/src/rora general/Lorenz-2.15/src/rorax general/Lorenz-2.15/src/andb general/Lorenz-2.15/src/andz general/Lorenz-2.15/src/andzx general/Lorenz-2.15/src/anda general/Lorenz-2.15/src/andax general/Lorenz-2.15/src/anday general/Lorenz-2.15/src/andix general/Lorenz-2.15/src/andiy general/Lorenz-2.15/src/orab general/Lorenz-2.15/src/oraz general/Lorenz-2.15/src/orazx general/Lorenz-2.15/src/oraa general/Lorenz-2.15/src/oraax general/Lorenz-2.15/src/oraay general/Lorenz-2.15/src/oraix general/Lorenz-2.15/src/oraiy general/Lorenz-2.15/src/eorb general/Lorenz-2.15/src/eorz general/Lorenz-2.15/src/eorzx general/Lorenz-2.15/src/eora general/Lorenz-2.15/src/eorax general/Lorenz-2.15/src/eoray general/Lorenz-2.15/src/eorix general/Lorenz-2.15/src/eoriy general/Lorenz-2.15/src/clcn general/Lorenz-2.15/src/secn general/Lorenz-2.15/src/cldn general/Lorenz-2.15/src/sedn general/Lorenz-2.15/src/clin general/Lorenz-2.15/src/sein general/Lorenz-2.15/src/clvn general/Lorenz-2.15/src/adcb general/Lorenz-2.15/src/adcz general/Lorenz-2.15/src/adczx general/Lorenz-2.15/src/adca general/Lorenz-2.15/src/adcax general/Lorenz-2.15/src/adcay general/Lorenz-2.15/src/adcix general/Lorenz-2.15/src/adciy general/Lorenz-2.15/src/sbcb general/Lorenz-2.15/src/sbcz general/Lorenz-2.15/src/sbczx general/Lorenz-2.15/src/sbca general/Lorenz-2.15/src/sbcax general/Lorenz-2.15/src/sbcay general/Lorenz-2.15/src/sbcix general/Lorenz-2.15/src/sbciy general/Lorenz-2.15/src/cmpb general/Lorenz-2.15/src/cmpz general/Lorenz-2.15/src/cmpzx general/Lorenz-2.15/src/cmpa general/Lorenz-2.15/src/cmpax general/Lorenz-2.15/src/cmpay general/Lorenz-2.15/src/cmpix general/Lorenz-2.15/src/cmpiy general/Lorenz-2.15/src/cpxb general/Lorenz-2.15/src/cpxz general/Lorenz-2.15/src/cpxa general/Lorenz-2.15/src/cpyb general/Lorenz-2.15/src/cpyz general/Lorenz-2.15/src/cpya general/Lorenz-2.15/src/bitz general/Lorenz-2.15/src/bita general/Lorenz-2.15/src/brkn general/Lorenz-2.15/src/rtin general/Lorenz-2.15/src/jsrw general/Lorenz-2.15/src/rtsn general/Lorenz-2.15/src/jmpw general/Lorenz-2.15/src/jmpi general/Lorenz-2.15/src/beqr general/Lorenz-2.15/src/bner general/Lorenz-2.15/src/bmir general/Lorenz-2.15/src/bplr general/Lorenz-2.15/src/bcsr general/Lorenz-2.15/src/bccr general/Lorenz-2.15/src/bvsr general/Lorenz-2.15/src/bvcr general/Lorenz-2.15/src/nopn general/Lorenz-2.15/src/nopb general/Lorenz-2.15/src/nopz general/Lorenz-2.15/src/nopzx general/Lorenz-2.15/src/nopa general/Lorenz-2.15/src/nopax general/Lorenz-2.15/src/asoz general/Lorenz-2.15/src/asozx general/Lorenz-2.15/src/asoa general/Lorenz-2.15/src/asoax general/Lorenz-2.15/src/asoay general/Lorenz-2.15/src/asoix general/Lorenz-2.15/src/asoiy general/Lorenz-2.15/src/rlaz general/Lorenz-2.15/src/rlazx general/Lorenz-2.15/src/rlaa general/Lorenz-2.15/src/rlaax general/Lorenz-2.15/src/rlaay general/Lorenz-2.15/src/rlaix general/Lorenz-2.15/src/rlaiy general/Lorenz-2.15/src/lsez general/Lorenz-2.15/src/lsezx general/Lorenz-2.15/src/lsea general/Lorenz-2.15/src/lseax general/Lorenz-2.15/src/lseay general/Lorenz-2.15/src/lseix general/Lorenz-2.15/src/lseiy general/Lorenz-2.15/src/rraz general/Lorenz-2.15/src/rrazx general/Lorenz-2.15/src/rraa general/Lorenz-2.15/src/rraax general/Lorenz-2.15/src/rraay general/Lorenz-2.15/src/rraix general/Lorenz-2.15/src/rraiy general/Lorenz-2.15/src/dcmz general/Lorenz-2.15/src/dcmzx general/Lorenz-2.15/src/dcma general/Lorenz-2.15/src/dcmax general/Lorenz-2.15/src/dcmay general/Lorenz-2.15/src/dcmix general/Lorenz-2.15/src/dcmiy general/Lorenz-2.15/src/insz general/Lorenz-2.15/src/inszx general/Lorenz-2.15/src/insa general/Lorenz-2.15/src/insax general/Lorenz-2.15/src/insay general/Lorenz-2.15/src/insix general/Lorenz-2.15/src/insiy general/Lorenz-2.15/src/laxz general/Lorenz-2.15/src/laxzy general/Lorenz-2.15/src/laxa general/Lorenz-2.15/src/laxay general/Lorenz-2.15/src/laxix general/Lorenz-2.15/src/laxiy general/Lorenz-2.15/src/axsz general/Lorenz-2.15/src/axszy general/Lorenz-2.15/src/axsa general/Lorenz-2.15/src/axsix general/Lorenz-2.15/src/alrb general/Lorenz-2.15/src/arrb general/Lorenz-2.15/src/aneb general/Lorenz-2.15/src/lxab general/Lorenz-2.15/src/sbxb general/Lorenz-2.15/src/shaay general/Lorenz-2.15/src/shaiy general/Lorenz-2.15/src/shxay general/Lorenz-2.15/src/shyax general/Lorenz-2.15/src/shsay general/Lorenz-2.15/src/ancb general/Lorenz-2.15/src/lasay general/Lorenz-2.15/src/sbcb-eb general/Lorenz-2.15/src/trap1 general/Lorenz-2.15/src/trap2 general/Lorenz-2.15/src/trap3 general/Lorenz-2.15/src/trap4 general/Lorenz-2.15/src/trap5 general/Lorenz-2.15/src/trap6 general/Lorenz-2.15/src/trap7 general/Lorenz-2.15/src/trap8 general/Lorenz-2.15/src/trap9 general/Lorenz-2.15/src/trap10 general/Lorenz-2.15/src/trap11 general/Lorenz-2.15/src/trap12 general/Lorenz-2.15/src/trap13 general/Lorenz-2.15/src/trap14 general/Lorenz-2.15/src/trap15 general/Lorenz-2.15/src/trap1ane general/Lorenz-2.15/src/trap2ane general/Lorenz-2.15/src/trap3ane general/Lorenz-2.15/src/trap4ane general/Lorenz-2.15/src/trap5ane general/Lorenz-2.15/src/trap6ane general/Lorenz-2.15/src/trap7ane general/Lorenz-2.15/src/trap8ane general/Lorenz-2.15/src/trap9ane general/Lorenz-2.15/src/trap10ane general/Lorenz-2.15/src/trap11ane general/Lorenz-2.15/src/trap12ane general/Lorenz-2.15/src/trap13ane general/Lorenz-2.15/src/trap14ane general/Lorenz-2.15/src/trap15ane general/Lorenz-2.15/src/trap1lxa general/Lorenz-2.15/src/trap2lxa general/Lorenz-2.15/src/trap3lxa general/Lorenz-2.15/src/trap4lxa general/Lorenz-2.15/src/trap5lxa general/Lorenz-2.15/src/trap6lxa general/Lorenz-2.15/src/trap7lxa general/Lorenz-2.15/src/trap8lxa general/Lorenz-2.15/src/trap9lxa general/Lorenz-2.15/src/trap10lxa general/Lorenz-2.15/src/trap11lxa general/Lorenz-2.15/src/trap12lxa general/Lorenz-2.15/src/trap13lxa general/Lorenz-2.15/src/trap14lxa general/Lorenz-2.15/src/trap15lxa general/Lorenz-2.15/src/trap16 general/Lorenz-2.15/src/trap17 general/Lorenz-2.15/src/branchwrap general/Lorenz-2.15/src/mmufetch general/Lorenz-2.15/src/mmu general/Lorenz-2.15/src/cpuport general/Lorenz-2.15/src/cputiming general/Lorenz-2.15/src/irq --cia old general/Lorenz-2.15/src/nmi --cia old general/Lorenz-2.15/src/cia1tb123 --cia old general/Lorenz-2.15/src/cia2tb123 --cia old general/Lorenz-2.15/src/cia1pb6 --cia old general/Lorenz-2.15/src/cia1pb7 --cia old general/Lorenz-2.15/src/cia2pb6 --cia old general/Lorenz-2.15/src/cia2pb7 --cia old general/Lorenz-2.15/src/cia1tab --cia old general/Lorenz-2.15/src/loadth --cia old general/Lorenz-2.15/src/cnto2 --cia old general/Lorenz-2.15/src/icr01 --cia old general/Lorenz-2.15/src/imr --cia old general/Lorenz-2.15/src/flipos --cia old general/Lorenz-2.15/src/oneshot --cia old general/Lorenz-2.15/src/cntdef --cia old general/Lorenz-2.15/src/cia1ta --cia old general/Lorenz-2.15/src/cia1tb --cia old general/Lorenz-2.15/src/cia2ta --cia old general/Lorenz-2.15/src/cia2tb --cia old general/Lorenz-2.15/src/irqnew --cia new general/Lorenz-2.15/src/nminew --cia new general/Lorenz-2.15/src/cia1tb123 --cia new general/Lorenz-2.15/src/cia2tb123 --cia new general/Lorenz-2.15/src/cia1pb6 --cia new general/Lorenz-2.15/src/cia1pb7 --cia new general/Lorenz-2.15/src/cia2pb6 --cia new general/Lorenz-2.15/src/cia2pb7 --cia new general/Lorenz-2.15/src/cia1tabnew --cia new general/Lorenz-2.15/src/loadth --cia new general/Lorenz-2.15/src/cnto2 --cia new general/Lorenz-2.15/src/icr01new --cia new general/Lorenz-2.15/src/imrnew --cia new general/Lorenz-2.15/src/flipos --cia new general/Lorenz-2.15/src/oneshot --cia new general/Lorenz-2.15/src/cntdef --cia new general/Lorenz-2.15/src/cia1tanew --cia new general/Lorenz-2.15/src/cia1tbnew --cia new # broken tests #general/Lorenz-2.15/src/cia2tanew --cia new #general/Lorenz-2.15/src/cia2tbnew --cia new general/Lorenz-2.15/src/finish # sprite collision, won't work #general/ram0001/test1 ### C64 ### C64/bankio/bankio C64/openio/gauntlet C64/raminitpattern/cyberloadtest C64/raminitpattern/darkstarbbstest C64/raminitpattern/platoontest C64/raminitpattern/typicaltest ### CIA ### CIA/CIA-AcountsB/cia-b-counts-a CIA/CIA-AcountsB/cmp-b-counts-a-old --cia old CIA/CIA-AcountsB/cmp-b-counts-a-new --cia new CIA/CIA-AcountsB/cia-b-counts-a_ntsc --vic ntsc CIA/CIA-AcountsB/cmp-b-counts-a-old_ntsc --cia old --vic ntsc CIA/CIA-AcountsB/cmp-b-counts-a-new_ntsc --cia new --vic ntsc CIA/cia-timer/cia-timer-oldcias --cia old CIA/cia-timer/cia-timer-newcias --cia new CIA/ciavarious/cia1 CIA/ciavarious/cia2 CIA/ciavarious/cia3 --cia old CIA/ciavarious/cia3new --cia new CIA/ciavarious/cia3a --cia old CIA/ciavarious/cia3anew --cia new CIA/ciavarious/cia4 --cia old CIA/ciavarious/cia4new --cia new CIA/ciavarious/cia5 CIA/ciavarious/cia6 CIA/ciavarious/cia7 CIA/ciavarious/cia8 --cia old CIA/ciavarious/cia8new --cia new CIA/ciavarious/cia9 CIA/ciavarious/cia10 CIA/ciavarious/cia11 CIA/ciavarious/cia12 CIA/ciavarious/cia13 CIA/ciavarious/cia14 CIA/ciavarious/cia15 CIA/dd0drw/dd0drw CIA/dd0dtest/dd0dtest --cia old CIA/dd0dtest/dd0dtest --cia new CIA/mirrors/ciamirrors CIA/irqdelay/irqdelay --cia old CIA/irqdelay/irqdelay-new --cia new CIA/irqdelay/irqdelay2 --cia old CIA/irqdelay/irqdelay2-new --cia new CIA/irqdelay/irqdelay-oneshot --cia old CIA/irqdelay/irqdelay-oneshot-new --cia new CIA/irqdelay/irqdelay-cia1 CIA/irqdelay/irqdelay-cia1-4-old --cia old CIA/irqdelay/irqdelay-cia1-4-new --cia new CIA/irqdelay/irqdelay-cia1-oneshot CIA/irqdelay/irqdelay-cia1-oneshot-4-old --cia old CIA/irqdelay/irqdelay-cia1-oneshot-4-new --cia new CIA/irqdelay/irqdelay-cia2 CIA/irqdelay/irqdelay-cia2-4 CIA/irqdelay/irqdelay-cia2-oneshot CIA/irqdelay/irqdelay-cia2-oneshot-4 CIA/pb6pb7/main CIA/reload0/reload0a CIA/reload0/reload0b CIA/shiftregister/cia-icr-test-continues-old --cia old CIA/shiftregister/cia-icr-test-continues-new --cia new CIA/shiftregister/cia-icr-test-oneshot-old --cia old CIA/shiftregister/cia-icr-test-oneshot-new --cia new CIA/shiftregister/cia-icr-test2-continues CIA/shiftregister/cia-icr-test2-oneshot CIA/shiftregister/cia-sdr-load CIA/shiftregister/cia-sdr-delay CIA/shiftregister/cia-sdr-init CIA/shiftregister/cia-sp-test-continues-old --cia old CIA/shiftregister/cia-sp-test-continues-new --cia new CIA/shiftregister/cia-sp-test-oneshot-old --cia old CIA/shiftregister/cia-sp-test-oneshot-new --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-0 --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-0_7f --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-1_7f --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-3 --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-4_7f --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-19 --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-39 --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-generic-0 --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-generic-0_7f --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-generic-1_7f --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-generic-3 --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-generic-4_7f --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-generic-19 --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-generic-39 --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-test2-0_7f --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-0 --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-0_7f --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-1_7f --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-3 --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-4_7f --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-19 --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-39 --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-generic-0 --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-generic-0_7f --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-generic-1_7f --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-generic-3 --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-generic-4_7f --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-generic-19 --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-generic-39 --cia old CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-test2-0_7f --cia old CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-0 --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-0_7f --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-1_7f --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-3 --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-4_7f --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-19 --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-39 --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-generic-0 --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-generic-0_7f --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-generic-1_7f --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-generic-3 --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-generic-4_7f --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-generic-19 --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-generic-39 --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-test2-0_7f --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-0 --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-0_7f --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-1_7f --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-3 --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-4_7f --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-19 --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-39 --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-generic-0 --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-generic-0_7f --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-generic-1_7f --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-generic-3 --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-generic-4_7f --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-generic-19 --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-generic-39 --cia new CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-test2-0_7f --cia new CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-4485-0 --cia 4485 CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-4485-0_7f --cia 4485 CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-4485-1_7f --cia 4485 CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-4485-3 --cia 4485 CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-4485-4_7f --cia 4485 CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-4485-19 --cia 4485 CIA/shiftregister/cia-sdr-icr/cia1-sdr-icr-4485-39 --cia 4485 CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-4485-0 --cia 4485 CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-4485-0_7f --cia 4485 CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-4485-1_7f --cia 4485 CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-4485-3 --cia 4485 CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-4485-4_7f --cia 4485 CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-4485-19 --cia 4485 CIA/shiftregister/cia-sdr-icr/cia2-sdr-icr-4485-39 --cia 4485 CIA/timerbasics/test --cia old CIA/timerbasics/test_new --cia new CIA/timerbasics/timer --cia old CIA/timerbasics/timer_new --cia new CIA/timerbasics/timer_test1 --cia old CIA/timerbasics/timer_test1_new --cia new CIA/tod/0alarm CIA/tod/1alarm CIA/tod/4tod CIA/tod/4todcia1 CIA/tod/5tod CIA/tod/6tod CIA/tod/alarm CIA/tod/alarm-cond CIA/tod/alarm-cond2 CIA/tod/fix-hour CIA/tod/fix-min CIA/tod/fix-sec CIA/tod/fix-tsec CIA/tod/frogger CIA/tod/hammerfist0 CIA/tod/hammerfist1 CIA/tod/hour-test CIA/tod/hzsync0 CIA/tod/hzsync1 CIA/tod/hzsync2 CIA/tod/hzsync3 CIA/tod/hzsync4 CIA/tod/hzsync5 CIA/tod/hzsync6 CIA/tod/powerup CIA/tod/read-latch CIA/tod/stability CIA/tod/stability-ntsc --vic ntsc CIA/tod/write-stop CIA/tod/ampmtest ### CPU ### CPU/64doc/dadc CPU/64doc/dincsbc CPU/64doc/dincsbc-deccmp CPU/64doc/droradc CPU/64doc/dsbc CPU/64doc/dsbc-cmp-flags CPU/64doc/sbx-c100 # these run VERY long #CPU/64doc/sbx #CPU/64doc/vsbx CPU/Acid800/cpu_bugs CPU/Acid800/cpu_clisei CPU/Acid800/cpu_decimal CPU/Acid800/cpu_flags CPU/Acid800/cpu_illegal CPU/Acid800/cpu_insn CPU/Acid800/cpu_timing CPU/Acid800/cpu_timing_ntsc --vic ntsc CPU/ane/ane CPU/ane/ane-border CPU/ane/ane-none CPU/asap/cpu_ane CPU/asap/cpu_anx CPU/asap/cpu_decimal CPU/asap/cpu_las CPU/asap/cpu_shx CPU/bclark/decimalmode # these would timeout #CPU/cpujam/cpujam02 #CPU/cpujam/cpujam12 #CPU/cpujam/cpujam22 #CPU/cpujam/cpujam32 #CPU/cpujam/cpujam42 #CPU/cpujam/cpujam52 #CPU/cpujam/cpujam62 #CPU/cpujam/cpujam72 #CPU/cpujam/cpujam92 #CPU/cpujam/cpujamb2 #CPU/cpujam/cpujamd2 #CPU/cpujam/cpujamf2 #CPU/cpujam/nojam CPU/cpuport/test1 CPU/decimalmode/adc00 CPU/decimalmode/adc01 CPU/decimalmode/adc02 CPU/decimalmode/adc10 CPU/decimalmode/adc11 CPU/decimalmode/adc12 CPU/decimalmode/sbc00 CPU/decimalmode/sbc01 CPU/decimalmode/sbc02 CPU/decimalmode/sbc10 CPU/decimalmode/sbc11 CPU/decimalmode/sbc12 CPU/decimalmode/arr00 CPU/decimalmode/arr01 CPU/decimalmode/arr02 CPU/decimalmode/arr10 CPU/decimalmode/arr11 CPU/decimalmode/arr12 CPU/decimalmode/sbcEB00 CPU/decimalmode/sbcEB01 CPU/decimalmode/sbcEB02 CPU/decimalmode/sbcEB10 CPU/decimalmode/sbcEB11 CPU/decimalmode/sbcEB12 CPU/decimalmode/isc00 CPU/decimalmode/isc01 CPU/decimalmode/isc02 CPU/decimalmode/isc03 CPU/decimalmode/isc10 CPU/decimalmode/isc11 CPU/decimalmode/isc12 CPU/decimalmode/isc13 CPU/decimalmode/rra00 CPU/decimalmode/rra01 CPU/decimalmode/rra02 CPU/decimalmode/rra03 CPU/decimalmode/rra10 CPU/decimalmode/rra11 CPU/decimalmode/rra12 CPU/decimalmode/rra13 CPU/hmc6502/AllSuiteA CPU/kdormann/6502_functional_test CPU/lax/lax CPU/lax/lax-border CPU/lax/lax-none CPU/sha/shaabsy1 CPU/sha/shaabsy2 CPU/sha/shaabsy3 CPU/sha/shaabsy4 CPU/sha/shaabsy5 CPU/sha/shazpy1 CPU/sha/shazpy2 CPU/sha/shazpy3 CPU/sha/shazpy4 CPU/sha/shazpy5 CPU/shs/shsabsy1 CPU/shs/shsabsy2 CPU/shs/shsabsy3 CPU/shs/shsabsy4 CPU/shs/shsabsy5 CPU/shxy/shx-test CPU/shxy/shxy1 CPU/shxy/shxy2 CPU/shxy/shxy3 CPU/shxy/shxy4 CPU/shxy/shxy5 CPU/shxy/shyx1 CPU/shxy/shyx2 CPU/shxy/shyx3 CPU/shxy/shyx4 CPU/shxy/shyx5 ### interrupts ### interrupts/branchquirk/branchquirk-nmiold --cia old interrupts/branchquirk/branchquirk-old --cia old interrupts/branchquirk/branchquirk-nminew --cia new interrupts/branchquirk/branchquirk-new --cia new interrupts/cia-int/cia-int-irq --cia old interrupts/cia-int/cia-int-irq-new --cia new interrupts/cia-int/cia-int-nmi --cia old interrupts/cia-int/cia-int-nmi-new --cia new interrupts/irq-ackn-bug/cia1 --cia old interrupts/irq-ackn-bug/cia1new --cia new interrupts/irq-ackn-bug/cia2 --cia old interrupts/irq-ackn-bug/cia2new --cia new # sprite collision, won't work #interrupts/irq-ackn-bug/irq-ack-vicii interrupts/irqdma/nmitest6 --cia old interrupts/irqdma/nmitest6 --cia new interrupts/irqdma/nmitest6b --cia old interrupts/irqdma/nmitest6b --cia new interrupts/irqdma/test1 interrupts/irqdma/test1b interrupts/irqdma/test2 interrupts/irqdma/test2b interrupts/irqdma/test3 interrupts/irqdma/test3b interrupts/irqdma/test4 interrupts/irqdma/test4b interrupts/irqdma/test5 interrupts/irqdma/test5b interrupts/irqdma/test6 interrupts/irqdma/test6b --cia old interrupts/irqdma/test6b --cia new interrupts/irqdma/test7 interrupts/irqdma/test7b interrupts/irqdummy/irqdummy interrupts/irqnmi/irqnmi-old --cia old interrupts/irqnmi/irqnmi-new --cia new interrupts/irqnoack/ackcia interrupts/irqnoack/ackcia2 interrupts/irqnoack/ackcia3 ### SID SID/busvalue/busvalue --sid old SID/detect/detect-1-old --sid old SID/detect/detect-2-old --sid old SID/detect/detect-1-new --sid new SID/detect/detect-2-new --sid new SID/env_test/env_test_adra_1 --sid old SID/env_test/env_test_adra_2 --sid old SID/env_test/env_test_ar_1 --sid old SID/env_test/env_test_ar_2 --sid old SID/env_test/env_test_ar_3 --sid old SID/env_test/env_test_ra_0000 --sid old SID/env_test/env_test_ra_0100 --sid old SID/env_test/env_test_ra_ff00 --sid old SID/envelope/lft-adsr-test --sid old SID/envelope/testADSRDelayBug --sid old SID/envelope/testFlip00toFF --sid old SID/envelope/testFlipFFto00 --sid old SID/exp_counter_reset/env_test_exr --sid old SID/osc3-wave0/osc3-wave0-new --sid new SID/osc3-wave0/osc3-wave0 --sid old SID/osc_topbit/osc_topbit_test_noise_old --sid old SID/osc_topbit/osc_topbit_test_pulse_old --sid old SID/osc_topbit/osc_topbit_test_triangle_old --sid old SID/osc_topbit/osc_topbit_test_noise_new --sid new SID/osc_topbit/osc_topbit_test_pulse_new --sid new SID/osc_topbit/osc_topbit_test_triangle_new --sid new SID/oscinit/allinit --sid old SID/oscinit/noiseinit --sid old SID/oscinit/oscinit --sid old SID/exp_counter_reset/env_test_exr --sid old SID/resid-test/envdelay --sid old SID/resid-test/envrate --sid old SID/resid-test/envsustain --sid old SID/resid-test/envtime --sid old SID/resid-test/noisetest --sid old SID/resid-test/oscsample0-6581 --sid old SID/resid-test/oscsample1-6581 --sid old SID/resid-test/oscsample0-8580 --sid new SID/resid-test/oscsample1-8580 --sid new SID/ringmod/ringmodtest --sid old SID/waveforms/waveforms-10-6581 --sid old SID/waveforms/waveforms-20-6581 --sid old SID/waveforms/waveforms-40-6581 --sid old SID/waveforms/waveforms-80-6581 --sid old SID/waveforms/waveforms-10-8580 --sid new SID/waveforms/waveforms-20-8580 --sid new SID/waveforms/waveforms-40-8580 --sid new SID/waveforms/waveforms-80-8580 --sid new SID/wb_testsuite/noise_writeback_check_8_to_8_old --sid old SID/wb_testsuite/noise_writeback_check_8_to_9_old --sid old SID/wb_testsuite/noise_writeback_check_8_to_A_old --sid old SID/wb_testsuite/noise_writeback_check_8_to_B_old --sid old SID/wb_testsuite/noise_writeback_check_8_to_C_old --sid old SID/wb_testsuite/noise_writeback_check_8_to_D_old --sid old SID/wb_testsuite/noise_writeback_check_8_to_E_old --sid old SID/wb_testsuite/noise_writeback_check_8_to_F_old --sid old SID/wb_testsuite/noise_writeback_check_9_to_8_old --sid old SID/wb_testsuite/noise_writeback_check_9_to_9_old --sid old SID/wb_testsuite/noise_writeback_check_9_to_A_old --sid old SID/wb_testsuite/noise_writeback_check_9_to_B_old --sid old SID/wb_testsuite/noise_writeback_check_9_to_C_old --sid old SID/wb_testsuite/noise_writeback_check_9_to_D_old --sid old SID/wb_testsuite/noise_writeback_check_9_to_E_old --sid old SID/wb_testsuite/noise_writeback_check_9_to_F_old --sid old SID/wb_testsuite/noise_writeback_check_A_to_8_old --sid old SID/wb_testsuite/noise_writeback_check_A_to_9_old --sid old SID/wb_testsuite/noise_writeback_check_A_to_A_old --sid old SID/wb_testsuite/noise_writeback_check_A_to_B_old --sid old SID/wb_testsuite/noise_writeback_check_A_to_C_old --sid old SID/wb_testsuite/noise_writeback_check_A_to_D_old --sid old SID/wb_testsuite/noise_writeback_check_A_to_E_old --sid old SID/wb_testsuite/noise_writeback_check_A_to_F_old --sid old SID/wb_testsuite/noise_writeback_check_B_to_8_old --sid old SID/wb_testsuite/noise_writeback_check_B_to_9_old --sid old SID/wb_testsuite/noise_writeback_check_B_to_A_old --sid old SID/wb_testsuite/noise_writeback_check_B_to_B_old --sid old SID/wb_testsuite/noise_writeback_check_B_to_D_old --sid old SID/wb_testsuite/noise_writeback_check_B_to_E_old --sid old SID/wb_testsuite/noise_writeback_check_B_to_F_old --sid old SID/wb_testsuite/noise_writeback_check_C_to_8_old --sid old SID/wb_testsuite/noise_writeback_check_C_to_9_old --sid old SID/wb_testsuite/noise_writeback_check_C_to_A_old --sid old SID/wb_testsuite/noise_writeback_check_C_to_B_old --sid old SID/wb_testsuite/noise_writeback_check_C_to_C_old --sid old SID/wb_testsuite/noise_writeback_check_C_to_D_old --sid old SID/wb_testsuite/noise_writeback_check_C_to_E_old --sid old SID/wb_testsuite/noise_writeback_check_C_to_F_old --sid old SID/wb_testsuite/noise_writeback_check_D_to_8_old --sid old SID/wb_testsuite/noise_writeback_check_D_to_9_old --sid old SID/wb_testsuite/noise_writeback_check_D_to_A_old --sid old SID/wb_testsuite/noise_writeback_check_D_to_B_old --sid old SID/wb_testsuite/noise_writeback_check_D_to_C_old --sid old SID/wb_testsuite/noise_writeback_check_D_to_D_old --sid old SID/wb_testsuite/noise_writeback_check_D_to_E_old --sid old SID/wb_testsuite/noise_writeback_check_D_to_F_old --sid old SID/wb_testsuite/noise_writeback_check_E_to_8_old --sid old SID/wb_testsuite/noise_writeback_check_E_to_9_old --sid old SID/wb_testsuite/noise_writeback_check_E_to_A_old --sid old SID/wb_testsuite/noise_writeback_check_E_to_B_old --sid old SID/wb_testsuite/noise_writeback_check_E_to_C_old --sid old SID/wb_testsuite/noise_writeback_check_E_to_E_old --sid old SID/wb_testsuite/noise_writeback_check_E_to_F_old --sid old SID/wb_testsuite/noise_writeback_check_F_to_8_old --sid old SID/wb_testsuite/noise_writeback_check_F_to_9_old --sid old SID/wb_testsuite/noise_writeback_check_F_to_A_old --sid old SID/wb_testsuite/noise_writeback_check_F_to_B_old --sid old SID/wb_testsuite/noise_writeback_check_F_to_C_old --sid old SID/wb_testsuite/noise_writeback_check_F_to_D_old --sid old SID/wb_testsuite/noise_writeback_check_F_to_E_old --sid old SID/wb_testsuite/noise_writeback_check_F_to_F_old --sid old SID/wb_testsuite/noise_writeback_check_8_to_8_new --sid new SID/wb_testsuite/noise_writeback_check_8_to_9_new --sid new SID/wb_testsuite/noise_writeback_check_8_to_A_new --sid new SID/wb_testsuite/noise_writeback_check_8_to_B_new --sid new SID/wb_testsuite/noise_writeback_check_8_to_D_new --sid new SID/wb_testsuite/noise_writeback_check_8_to_E_new --sid new SID/wb_testsuite/noise_writeback_check_8_to_F_new --sid new SID/wb_testsuite/noise_writeback_check_9_to_8_new --sid new SID/wb_testsuite/noise_writeback_check_9_to_9_new --sid new SID/wb_testsuite/noise_writeback_check_9_to_B_new --sid new SID/wb_testsuite/noise_writeback_check_9_to_D_new --sid new SID/wb_testsuite/noise_writeback_check_9_to_F_new --sid new SID/wb_testsuite/noise_writeback_check_A_to_8_new --sid new SID/wb_testsuite/noise_writeback_check_A_to_9_new --sid new SID/wb_testsuite/noise_writeback_check_A_to_A_new --sid new SID/wb_testsuite/noise_writeback_check_A_to_B_new --sid new SID/wb_testsuite/noise_writeback_check_A_to_D_new --sid new SID/wb_testsuite/noise_writeback_check_A_to_E_new --sid new SID/wb_testsuite/noise_writeback_check_A_to_F_new --sid new SID/wb_testsuite/noise_writeback_check_B_to_9_new --sid new SID/wb_testsuite/noise_writeback_check_B_to_A_new --sid new SID/wb_testsuite/noise_writeback_check_B_to_B_new --sid new SID/wb_testsuite/noise_writeback_check_B_to_D_new --sid new SID/wb_testsuite/noise_writeback_check_B_to_E_new --sid new SID/wb_testsuite/noise_writeback_check_B_to_F_new --sid new SID/wb_testsuite/noise_writeback_check_C_to_8_new --sid new SID/wb_testsuite/noise_writeback_check_C_to_9_new --sid new SID/wb_testsuite/noise_writeback_check_C_to_A_new --sid new SID/wb_testsuite/noise_writeback_check_C_to_E_new --sid new SID/wb_testsuite/noise_writeback_check_C_to_F_new --sid new SID/wb_testsuite/noise_writeback_check_D_to_8_new --sid new SID/wb_testsuite/noise_writeback_check_D_to_9_new --sid new SID/wb_testsuite/noise_writeback_check_D_to_B_new --sid new SID/wb_testsuite/noise_writeback_check_D_to_D_new --sid new SID/wb_testsuite/noise_writeback_check_D_to_F_new --sid new SID/wb_testsuite/noise_writeback_check_E_to_8_new --sid new SID/wb_testsuite/noise_writeback_check_E_to_9_new --sid new SID/wb_testsuite/noise_writeback_check_E_to_A_new --sid new SID/wb_testsuite/noise_writeback_check_E_to_B_new --sid new SID/wb_testsuite/noise_writeback_check_E_to_E_new --sid new SID/wb_testsuite/noise_writeback_check_E_to_F_new --sid new SID/wb_testsuite/noise_writeback_check_F_to_9_new --sid new SID/wb_testsuite/noise_writeback_check_F_to_A_new --sid new SID/wb_testsuite/noise_writeback_check_F_to_B_new --sid new SID/wb_testsuite/noise_writeback_check_F_to_D_new --sid new SID/wb_testsuite/noise_writeback_check_F_to_E_new --sid new SID/wb_testsuite/noise_writeback_check_F_to_F_new --sid new SID/writedelay/writedelay --sid old SID/wf12nsr/wf12nsr --sid old SID/wf12nsr/wf12nsr-8580 --sid new SID/noiselfsrinit/simple --sid old SID/noiselfsrinit/scan --sid old ### VICII ### VICII/colorram/test VICII/split-tests/bascan/bascan VICII/split-tests/lightpen/lightpen --vic pal VICII/split-tests/lightpen/lightpen --vic ntsc VICII/split-tests/lightpen/lightpen --vic drean # are these supposed to work? #VICII/split-tests/spritescan/spritescan --vic pal #VICII/split-tests/spritescan/spritescan_drean --vic drean VICII/vspbug/vsp_bug VICII/spritesteal/spritesteal --vic pal VICII/spritesteal/spritesteal_ntsc --vic ntsc VICII/spritesteal/spritesteal_ntscold --vic oldntsc # sprite collision, won't work #VICII/spritex/demusinterruptus #VICII/spritex/testsuite --vic pal #VICII/spritex/testsuite_ntsc --vic ntsc #VICII/spritex/testsuite_ntscold --vic oldntsc #VICII/spritey/spritey VICII/lplatency/lplatency VICII/lp-trigger/test2 libsidplayfp-3.0.0/test/testsuite.sh0000755000175100017510000000120115175333711013226 #!/bin/sh dir=$(dirname $0) logfile=$dir/testsuite.log : > ${logfile} passed=0 failed=0 while read line; do if [[ $line =~ ^# ]]; then continue; fi name=${line%% *} echo "Running test $name" $dir/test $line if [[ $? -ne 0 ]]; then failed=$((failed+1)) echo "Failed test $name" >> ${logfile} else passed=$((passed+1)) fi done < $dir/testlist total=$((passed+failed)) echo "Passed ${passed}/${total} ($((passed*100/total))%)" echo "Failed ${failed}/${total}" if [[ ${failed} -eq 0 ]]; then echo "Success!" exit 0 else echo "Failed tests logged in ${logfile}" exit 1 fi libsidplayfp-3.0.0/test/demo.cpp0000644000175100017510000001112415175333711012273 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2026 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #ifdef BUILD_INTERNAL # include "sidplayfp/sidplayfp.h" # include "sidplayfp/SidTune.h" # include "sidplayfp/SidInfo.h" # include "builders/sidlite-builder/sidlite.h" #else # include # include # include # include #endif /** * Works on UNIX using OSS * * Compile with * g++ `pkg-config --cflags libsidplayfp` `pkg-config --libs libsidplayfp` demo.cpp */ /* * Adjust these paths to point to existing ROM dumps if needed. */ #define KERNAL_PATH "" #define BASIC_PATH "" #define CHARGEN_PATH "" #define SAMPLERATE 48000 #if __cplusplus < 201103L # define unique_ptr auto_ptr #endif /* * Load ROM dump from file. * Allocate the buffer if file exists, otherwise return 0. */ char* loadRom(const char* path, size_t romSize) { char* buffer = 0; std::ifstream is(path, std::ios::binary); if (is.good()) { buffer = new char[romSize]; is.read(buffer, romSize); } is.close(); return buffer; } /* * Sample application that shows how to use libsidplayfp * to play a SID tune from a file. * It uses OSS for audio output. */ int main(int argc, char* argv[]) { if (argc<2) { std::cerr << "Argument required" << std::endl; exit(EXIT_FAILURE); } sidplayfp m_engine; { // Load ROM files char *kernal = loadRom(KERNAL_PATH, 8192); char *basic = loadRom(BASIC_PATH, 8192); char *chargen = loadRom(CHARGEN_PATH, 4096); m_engine.setRoms((const uint8_t*)kernal, (const uint8_t*)basic, (const uint8_t*)chargen); delete [] kernal; delete [] basic; delete [] chargen; } // Set up a SID builder std::unique_ptr rs(new SIDLiteBuilder("Demo")); /* // Check if builder is ok if (!rs->getStatus()) { std::cerr << rs->error() << std::endl; return -1; } */ // Load tune from file std::unique_ptr tune(new SidTune(argv[1])); // CHeck if the tune is valid if (!tune->getStatus()) { std::cerr << tune->statusString() << std::endl; return -1; } // Select default song tune->selectSong(0); // Configure the engine SidConfig cfg; cfg.frequency = SAMPLERATE; cfg.samplingMethod = SidConfig::INTERPOLATE; cfg.sidEmulation = rs.get(); if (!m_engine.config(cfg)) { std::cerr << m_engine.error() << std::endl; return -1; } // Load tune into engine if (!m_engine.load(tune.get())) { std::cerr << m_engine.error() << std::endl; return -1; } // Setup audio device int handle=::open("/dev/dsp", O_WRONLY, 0); int format=AFMT_S16_LE; ioctl(handle, SNDCTL_DSP_SETFMT, &format); int chn=2; ioctl(handle, SNDCTL_DSP_CHANNELS, &chn); int sampleRate=SAMPLERATE; ioctl(handle, SNDCTL_DSP_SPEED, &sampleRate); int bufferSize; ioctl(handle, SNDCTL_DSP_GETBLKSIZE, &bufferSize); //uint_least32_t bufferSamples = static_cast(bufferSize) / sizeof(short); constexpr int CYCLES = 5000; m_engine.initMixer(true); int bufSize = m_engine.getBufSize(CYCLES); std::vector buffer(bufSize); // Play for ~5 seconds for (int i=0; i<1000; i++) { int res = m_engine.play(CYCLES); if (res < 0) { std::cerr << m_engine.error() << std::endl; break; } unsigned int s = m_engine.mix(buffer.data(), res); ::write(handle, buffer.data(), s*sizeof(short)); } ::close(handle); } libsidplayfp-3.0.0/configure0000755000175100017510000302661015175333717011612 #! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.71 for libsidplayfp 3.0.0. # # # Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, # Inc. # # # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # Use a proper internal environment variable to ensure we don't fall # into an infinite loop, continuously re-executing ourselves. if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then _as_can_reexec=no; export _as_can_reexec; # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi # We don't want this to propagate to other subprocesses. { _as_can_reexec=; unset _as_can_reexec;} if test "x$CONFIG_SHELL" = x; then as_bourne_compatible="as_nop=: if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which # is contrary to our usage. Disable this feature. alias -g '\${1+\"\$@\"}'='\"\$@\"' setopt NO_GLOB_SUBST else \$as_nop case \`(set -o) 2>/dev/null\` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi " as_required="as_fn_return () { (exit \$1); } as_fn_success () { as_fn_return 0; } as_fn_failure () { as_fn_return 1; } as_fn_ret_success () { return 0; } as_fn_ret_failure () { return 1; } exitcode=0 as_fn_success || { exitcode=1; echo as_fn_success failed.; } as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } if ( set x; as_fn_ret_success y && test x = \"\$1\" ) then : else \$as_nop exitcode=1; echo positional parameters were not saved. fi test x\$exitcode = x0 || exit 1 blah=\$(echo \$(echo blah)) test x\"\$blah\" = xblah || exit 1 test -x / || exit 1" as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || ( ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO PATH=/empty FPATH=/empty; export PATH FPATH test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1 test \$(( 1 + 1 )) = 2 || exit 1" if (eval "$as_required") 2>/dev/null then : as_have_required=yes else $as_nop as_have_required=no fi if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null then : else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: case $as_dir in #( /*) for as_base in sh bash ksh sh5; do # Try only shells that exist, to save several forks. as_shell=$as_dir$as_base if { test -f "$as_shell" || test -f "$as_shell.exe"; } && as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$as_shell as_have_required=yes if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null then : break 2 fi fi done;; esac as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop if { test -f "$SHELL" || test -f "$SHELL.exe"; } && as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null then : CONFIG_SHELL=$SHELL as_have_required=yes fi fi if test "x$CONFIG_SHELL" != x then : export CONFIG_SHELL # We cannot yet assume a decent shell, so we have to provide a # neutralization value for shells without unset; and this also # works around shells that cannot unset nonexistent variables. # Preserve -v and -x to the replacement shell. BASH_ENV=/dev/null ENV=/dev/null (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV case $- in # (((( *v*x* | *x*v* ) as_opts=-vx ;; *v* ) as_opts=-v ;; *x* ) as_opts=-x ;; * ) as_opts= ;; esac exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} # Admittedly, this is quite paranoid, since all the known shells bail # out after a failed `exec'. printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2 exit 255 fi if test x$as_have_required = xno then : printf "%s\n" "$0: This script requires a shell more modern than all" printf "%s\n" "$0: the shells that I found on your system." if test ${ZSH_VERSION+y} ; then printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should" printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later." else printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system, $0: including any error possibly output before this $0: message. Then install a modern shell, or manually run $0: the script under such a shell if you do have one." fi exit 1 fi fi fi SHELL=${CONFIG_SHELL-/bin/sh} export SHELL # Unset more variables known to interfere with behavior of common tools. CLICOLOR_FORCE= GREP_OPTIONS= unset CLICOLOR_FORCE GREP_OPTIONS ## --------------------- ## ## M4sh Shell Functions. ## ## --------------------- ## # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith # as_fn_nop # --------- # Do nothing but, unlike ":", preserve the value of $?. as_fn_nop () { return $? } as_nop=as_fn_nop # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits as_lineno_1=$LINENO as_lineno_1a=$LINENO as_lineno_2=$LINENO as_lineno_2a=$LINENO eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } # If we had to re-execute with $CONFIG_SHELL, we're ensured to have # already done that, so ensure we don't try to do so again and fall # in an infinite loop. This has already happened in practice. _as_can_reexec=no; export _as_can_reexec # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" SHELL=${CONFIG_SHELL-/bin/sh} test -n "$DJDIR" || exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= # Identity of this package. PACKAGE_NAME='libsidplayfp' PACKAGE_TARNAME='libsidplayfp' PACKAGE_VERSION='3.0.0' PACKAGE_STRING='libsidplayfp 3.0.0' PACKAGE_BUGREPORT='' PACKAGE_URL='https://github.com/libsidplayfp/libsidplayfp/' ac_unique_file="src/sidplayfp/sidplayfp.cpp" # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_STDIO_H # include #endif #ifdef HAVE_STDLIB_H # include #endif #ifdef HAVE_STRING_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_header_c_list= ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS BUILD_DEMO_FALSE BUILD_DEMO_TRUE EXSID_DRIVER_FALSE EXSID_DRIVER_TRUE EXSID_SUPPORT_FALSE EXSID_SUPPORT_TRUE FTDI_CFLAGS EXSID_LIBS EXSID_CFLAGS USBSID_DRIVER_FALSE USBSID_DRIVER_TRUE USBSID_SUPPORT_FALSE USBSID_SUPPORT_TRUE USBSID_LIBS USBSID_CFLAGS LIBSTILVIEWVERSION LIBSIDPLAYVERSION HAVE_BUILTIN_EXPECT RESIDFP_SUPPORT_FALSE RESIDFP_SUPPORT_TRUE RESIDFP_LIBS RESIDFP_CFLAGS ENABLE_TEST_FALSE ENABLE_TEST_TRUE PKG_CONFIG_LIBDIR PKG_CONFIG_PATH PKG_CONFIG TESTSUITE_FALSE TESTSUITE_TRUE HAVE_DOXYGEN_FALSE HAVE_DOXYGEN_TRUE DOT DOXYGEN debug_flags PTHREAD_CFLAGS PTHREAD_LIBS PTHREAD_CXX PTHREAD_CC ax_pthread_config CPP OD XA HAVE_CXX11 HAVE_CXX14 HAVE_CXX17 HAVE_CXX20 HAVE_CXX23 CXXCPP am__fastdepCXX_FALSE am__fastdepCXX_TRUE CXXDEPMODE ac_ct_CXX CXXFLAGS CXX LT_SYS_LIBRARY_PATH OTOOL64 OTOOL LIPO NMEDIT DSYMUTIL MANIFEST_TOOL RANLIB ac_ct_AR AR FILECMD LN_S NM ac_ct_DUMPBIN DUMPBIN LD FGREP EGREP GREP SED am__fastdepCC_FALSE am__fastdepCC_TRUE CCDEPMODE am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE am__include DEPDIR OBJEXT EXEEXT ac_ct_CC CPPFLAGS LDFLAGS CFLAGS CC LIBTOOL OBJDUMP DLLTOOL AS MACOS_FALSE MACOS_TRUE MINGW32_FALSE MINGW32_TRUE host_os host_vendor host_cpu host build_os build_vendor build_cpu build LIB_LEVEL LIB_MINOR LIB_MAJOR AM_BACKSLASH AM_DEFAULT_VERBOSITY AM_DEFAULT_V AM_V CSCOPE ETAGS CTAGS am__untar am__tar AMTAR am__leading_dot SET_MAKE AWK mkdir_p MKDIR_P INSTALL_STRIP_PROGRAM STRIP install_sh MAKEINFO AUTOHEADER AUTOMAKE AUTOCONF ACLOCAL VERSION PACKAGE CYGPATH_W am__isrc INSTALL_DATA INSTALL_SCRIPT INSTALL_PROGRAM target_alias host_alias build_alias LIBS ECHO_T ECHO_N ECHO_C DEFS mandir localedir libdir psdir pdfdir dvidir htmldir infodir docdir oldincludedir includedir runstatedir localstatedir sharedstatedir sysconfdir datadir datarootdir libexecdir sbindir bindir program_transform_name prefix exec_prefix PACKAGE_URL PACKAGE_BUGREPORT PACKAGE_STRING PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR SHELL am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking enable_silent_rules enable_shared enable_static with_pic enable_fast_install with_aix_soname enable_dependency_tracking with_gnu_ld with_sysroot enable_libtool_lock enable_debug enable_lto enable_testsuite enable_tests with_usbsid with_exsid ' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS LT_SYS_LIBRARY_PATH CXX CXXFLAGS CCC CXXCPP CPP PKG_CONFIG PKG_CONFIG_PATH PKG_CONFIG_LIBDIR RESIDFP_CFLAGS RESIDFP_LIBS USBSID_CFLAGS USBSID_LIBS EXSID_CFLAGS EXSID_LIBS' # Initialize some variables set by options. ac_init_help= ac_init_version=false ac_unrecognized_opts= ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *=) ac_optarg= ;; *) ac_optarg=yes ;; esac case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid feature name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "enable_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -runstatedir | --runstatedir | --runstatedi | --runstated \ | --runstate | --runstat | --runsta | --runst | --runs \ | --run | --ru | --r) ac_prev=runstatedir ;; -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ | --run=* | --ru=* | --r=*) runstatedir=$ac_optarg ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && as_fn_error $? "invalid package name: \`$ac_useropt'" ac_useropt_orig=$ac_useropt ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'` case $ac_user_opts in *" "with_$ac_useropt" "*) ;; *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" ac_unrecognized_sep=', ';; esac eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) as_fn_error $? "unrecognized option: \`$ac_option' Try \`$0 --help' for more information" ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. case $ac_envvar in #( '' | [0-9]* | *[!_$as_cr_alnum]* ) as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; esac eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2 : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` as_fn_error $? "missing argument to $ac_option" fi if test -n "$ac_unrecognized_opts"; then case $enable_option_checking in no) ;; fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; *) printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; esac fi # Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. case $ac_val in */ ) ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` eval $ac_var=\$ac_val;; esac # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || as_fn_error $? "working directory cannot be determined" test "X$ac_ls_di" = "X$ac_pwd_ls_di" || as_fn_error $? "pwd does not report name of working directory" # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$as_myself" || $as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_myself" : 'X\(//\)[^/]' \| \ X"$as_myself" : 'X\(//\)$' \| \ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures libsidplayfp 3.0.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking ...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/libsidplayfp] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF Program names: --program-prefix=PREFIX prepend PREFIX to installed program names --program-suffix=SUFFIX append SUFFIX to installed program names --program-transform-name=PROGRAM run sed PROGRAM on installed program names System types: --build=BUILD configure for building on BUILD [guessed] --host=HOST cross-compile to build programs to run on HOST [BUILD] _ACEOF fi if test -n "$ac_init_help"; then case $ac_init_help in short | recursive ) echo "Configuration of libsidplayfp 3.0.0:";; esac cat <<\_ACEOF Optional Features: --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-silent-rules less verbose build output (undo: "make V=1") --disable-silent-rules verbose build output (undo: "make V=0") --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] --enable-dependency-tracking do not reject slow dependency extractors --disable-dependency-tracking speeds up one-time build --disable-libtool-lock avoid locking (might break parallel builds) --enable-debug compile for debugging [no/yes, default=no] --enable-lto enable link time optimization [default=no] --enable-testsuite=PATH_TO_TESTSUITE enable VICE testsuite [default=no] --enable-tests enable unit tests [default=no] Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use both] --with-aix-soname=aix|svr4|both shared library versioning (aka "SONAME") variant to provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). --with-usbsid Build with usbsid support [[yes/no/check, default=check]] --with-exsid Build with exsid support [[yes/no/check, default=check]] Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory LT_SYS_LIBRARY_PATH User-defined run-time library search path. CXX C++ compiler command CXXFLAGS C++ compiler flags CXXCPP C++ preprocessor CPP C preprocessor PKG_CONFIG path to pkg-config utility PKG_CONFIG_PATH directories to add to pkg-config's search path PKG_CONFIG_LIBDIR path overriding pkg-config's built-in search path RESIDFP_CFLAGS C compiler flags for RESIDFP, overriding pkg-config RESIDFP_LIBS linker flags for RESIDFP, overriding pkg-config USBSID_CFLAGS C compiler flags for USBSID, overriding pkg-config USBSID_LIBS linker flags for USBSID, overriding pkg-config EXSID_CFLAGS C compiler flags for EXSID, overriding pkg-config EXSID_LIBS linker flags for EXSID, overriding pkg-config Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. Report bugs to the package provider. libsidplayfp home page: . _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for configure.gnu first; this name is used for a wrapper for # Metaconfig's "Configure" on case-insensitive file systems. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF libsidplayfp configure 3.0.0 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi ## ------------------------ ## ## Autoconf initialization. ## ## ------------------------ ## # ac_fn_c_try_compile LINENO # -------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_compile # ac_fn_c_try_link LINENO # ----------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_link # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES # ------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_c_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_c_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_header_compile # ac_fn_c_check_func LINENO FUNC VAR # ---------------------------------- # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_c_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. */ #include #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_func # ac_fn_cxx_try_compile LINENO # ---------------------------- # Try to compile conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_compile # ac_fn_cxx_try_cpp LINENO # ------------------------ # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || test ! -s conftest.err } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_cpp # ac_fn_cxx_try_link LINENO # ------------------------- # Try to link conftest.$ac_ext, and return whether this succeeded. ac_fn_cxx_try_link () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { test -z "$ac_cxx_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && { test "$cross_compiling" = yes || test -x conftest$ac_exeext } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would # interfere with the next link command; also delete a directory that is # left behind by Apple's compiler. We do this before executing the actions. rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_link # ac_fn_cxx_try_run LINENO # ------------------------ # Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that # executables *can* be run. ac_fn_cxx_try_run () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: program exited with status $ac_status" >&5 printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=$ac_status fi rm -rf conftest.dSYM conftest_ipa8_conftest.oo eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_cxx_try_run # ac_fn_cxx_compute_int LINENO EXPR VAR INCLUDES # ---------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed ac_fn_cxx_compute_int () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if test "$cross_compiling" = yes; then # Depending upon the size, compute the lo and hi bounds. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) >= 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_lo=0 ac_mid=0 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_hi=$ac_mid; break else $as_nop as_fn_arith $ac_mid + 1 && ac_lo=$as_val if test $ac_lo -le $ac_mid; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) < 0)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_hi=-1 ac_mid=-1 while :; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) >= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_lo=$ac_mid; break else $as_nop as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val if test $ac_mid -le $ac_hi; then ac_lo= ac_hi= break fi as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done else $as_nop ac_lo= ac_hi= fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext # Binary search between lo and hi bounds. while test "x$ac_lo" != "x$ac_hi"; do as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { static int test_array [1 - 2 * !(($2) <= $ac_mid)]; test_array [0] = 0; return test_array [0]; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_hi=$ac_mid else $as_nop as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done case $ac_lo in #(( ?*) eval "$3=\$ac_lo"; ac_retval=0 ;; '') ac_retval=1 ;; esac else cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 static long int longval (void) { return $2; } static unsigned long int ulongval (void) { return $2; } #include #include int main (void) { FILE *f = fopen ("conftest.val", "w"); if (! f) return 1; if (($2) < 0) { long int i = longval (); if (i != ($2)) return 1; fprintf (f, "%ld", i); } else { unsigned long int i = ulongval (); if (i != ($2)) return 1; fprintf (f, "%lu", i); } /* Do not output a trailing newline, as this causes \r\n confusion on some platforms. */ return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO" then : echo >>conftest.val; read $3 &5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop eval "$3=no" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { if (sizeof ($2)) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { if (sizeof (($2))) return 0; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : else $as_nop eval "$3=yes" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_type # ac_fn_check_decl LINENO SYMBOL VAR INCLUDES EXTRA-OPTIONS FLAG-VAR # ------------------------------------------------------------------ # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR # accordingly. Pass EXTRA-OPTIONS to the compiler, using FLAG-VAR. ac_fn_check_decl () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack as_decl_name=`echo $2|sed 's/ *(.*//'` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5 printf %s "checking whether $as_decl_name is declared... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'` eval ac_save_FLAGS=\$$6 as_fn_append $6 " $5" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 int main (void) { #ifndef $as_decl_name #ifdef __cplusplus (void) $as_decl_use; #else (void) $as_decl_name; #endif #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext eval $6=\$ac_save_FLAGS fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_check_decl # ac_fn_cxx_check_func LINENO FUNC VAR # ------------------------------------ # Tests whether FUNC exists, setting the cache variable VAR accordingly ac_fn_cxx_check_func () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Define $2 to an innocuous variant, in case declares $2. For example, HP-UX 11i declares gettimeofday. */ #define $2 innocuous_$2 /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $2 (); below. */ #include #undef $2 /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $2 (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$2 || defined __stub___$2 choke me #endif int main (void) { return $2 (); ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_func # ac_fn_c_try_cpp LINENO # ---------------------- # Try to preprocess conftest.$ac_ext, and return whether this succeeded. ac_fn_c_try_cpp () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack if { { ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err ac_status=$? if test -s conftest.err; then grep -v '^ *+' conftest.err >conftest.er1 cat conftest.er1 >&5 mv -f conftest.er1 conftest.err fi printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } > conftest.i && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err } then : ac_retval=0 else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_retval=1 fi eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno as_fn_set_status $ac_retval } # ac_fn_c_try_cpp # ac_fn_cxx_check_header_compile LINENO HEADER VAR INCLUDES # --------------------------------------------------------- # Tests whether HEADER exists and can be compiled using the include files in # INCLUDES, setting the cache variable VAR accordingly. ac_fn_cxx_check_header_compile () { as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 printf %s "checking for $2... " >&6; } if eval test \${$3+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $4 #include <$2> _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval "$3=yes" else $as_nop eval "$3=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi eval ac_res=\$$3 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_cxx_check_header_compile ac_configure_args_raw= for ac_arg do case $ac_arg in *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append ac_configure_args_raw " '$ac_arg'" done case $ac_configure_args_raw in *$as_nl*) ac_safe_unquote= ;; *) ac_unsafe_z='|&;<>()$`\\"*?[ '' ' # This string ends in space, tab. ac_unsafe_a="$ac_unsafe_z#~" ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g" ac_configure_args_raw=` printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;; esac cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by libsidplayfp $as_me 3.0.0, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac printf "%s\n" "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; 2) as_fn_append ac_configure_args1 " '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi as_fn_append ac_configure_args " '$ac_arg'" ;; esac done done { ac_configure_args0=; unset ac_configure_args0;} { ac_configure_args1=; unset ac_configure_args1;} # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Sanitize IFS. IFS=" "" $as_nl" # Save into config.log some information that might help in debugging. { echo printf "%s\n" "## ---------------- ## ## Cache variables. ## ## ---------------- ##" echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo printf "%s\n" "## ----------------- ## ## Output variables. ## ## ----------------- ##" echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then printf "%s\n" "## ------------------- ## ## File substitutions. ## ## ------------------- ##" echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac printf "%s\n" "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then printf "%s\n" "## ----------- ## ## confdefs.h. ## ## ----------- ##" echo cat confdefs.h echo fi test "$ac_signal" != 0 && printf "%s\n" "$as_me: caught signal $ac_signal" printf "%s\n" "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h printf "%s\n" "/* confdefs.h */" > confdefs.h # Predefined preprocessor variables. printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h # Let the site file select an alternate cache file if it wants to. # Prefer an explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then ac_site_files="$CONFIG_SITE" elif test "x$prefix" != xNONE; then ac_site_files="$prefix/share/config.site $prefix/etc/config.site" else ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" fi for ac_site_file in $ac_site_files do case $ac_site_file in #( */*) : ;; #( *) : ac_site_file=./$ac_site_file ;; esac if test -f "$ac_site_file" && test -r "$ac_site_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" \ || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "failed to load site script $ac_site_file See \`config.log' for more details" "$LINENO" 5; } fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special files # actually), so we avoid doing that. DJGPP emulates it as a regular file. if test /dev/null != "$cache_file" && test -f "$cache_file"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 printf "%s\n" "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 printf "%s\n" "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Test code for whether the C compiler supports C89 (global declarations) ac_c_conftest_c89_globals=' /* Does the compiler advertise C89 conformance? Do not test the value of __STDC__, because some compilers set it to 0 while being otherwise adequately conformant. */ #if !defined __STDC__ # error "Compiler does not advertise C89 conformance" #endif #include #include struct stat; /* Most of the following tests are stolen from RCS 5.7 src/conf.sh. */ struct buf { int x; }; struct buf * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not \xHH hex character constants. These do not provoke an error unfortunately, instead are silently treated as an "x". The following induces an error, until -std is added to get proper ANSI mode. Curiously \x00 != x always comes out true, for an array size at least. It is necessary to write \x00 == 0 to get something that is true only with -std. */ int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) '\''x'\'' int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int), int, int);' # Test code for whether the C compiler supports C89 (body of main). ac_c_conftest_c89_main=' ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]); ' # Test code for whether the C compiler supports C99 (global declarations) ac_c_conftest_c99_globals=' // Does the compiler advertise C99 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L # error "Compiler does not advertise C99 conformance" #endif #include extern int puts (const char *); extern int printf (const char *, ...); extern int dprintf (int, const char *, ...); extern void *malloc (size_t); // Check varargs macros. These examples are taken from C99 6.10.3.5. // dprintf is used instead of fprintf to avoid needing to declare // FILE and stderr. #define debug(...) dprintf (2, __VA_ARGS__) #define showlist(...) puts (#__VA_ARGS__) #define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__)) static void test_varargs_macros (void) { int x = 1234; int y = 5678; debug ("Flag"); debug ("X = %d\n", x); showlist (The first, second, and third items.); report (x>y, "x is %d but y is %d", x, y); } // Check long long types. #define BIG64 18446744073709551615ull #define BIG32 4294967295ul #define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0) #if !BIG_OK #error "your preprocessor is broken" #endif #if BIG_OK #else #error "your preprocessor is broken" #endif static long long int bignum = -9223372036854775807LL; static unsigned long long int ubignum = BIG64; struct incomplete_array { int datasize; double data[]; }; struct named_init { int number; const wchar_t *name; double average; }; typedef const char *ccp; static inline int test_restrict (ccp restrict text) { // See if C++-style comments work. // Iterate through items via the restricted pointer. // Also check for declarations in for loops. for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i) continue; return 0; } // Check varargs and va_copy. static bool test_varargs (const char *format, ...) { va_list args; va_start (args, format); va_list args_copy; va_copy (args_copy, args); const char *str = ""; int number = 0; float fnumber = 0; while (*format) { switch (*format++) { case '\''s'\'': // string str = va_arg (args_copy, const char *); break; case '\''d'\'': // int number = va_arg (args_copy, int); break; case '\''f'\'': // float fnumber = va_arg (args_copy, double); break; default: break; } } va_end (args_copy); va_end (args); return *str && number && fnumber; } ' # Test code for whether the C compiler supports C99 (body of main). ac_c_conftest_c99_main=' // Check bool. _Bool success = false; success |= (argc != 0); // Check restrict. if (test_restrict ("String literal") == 0) success = true; char *restrict newvar = "Another string"; // Check varargs. success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234); test_varargs_macros (); // Check flexible array members. struct incomplete_array *ia = malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10)); ia->datasize = 10; for (int i = 0; i < ia->datasize; ++i) ia->data[i] = i * 1.234; // Check named initializers. struct named_init ni = { .number = 34, .name = L"Test wide string", .average = 543.34343, }; ni.number = 58; int dynamic_array[ni.number]; dynamic_array[0] = argv[0][0]; dynamic_array[ni.number - 1] = 543; // work around unused variable warnings ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\'' || dynamic_array[ni.number - 1] != 543); ' # Test code for whether the C compiler supports C11 (global declarations) ac_c_conftest_c11_globals=' // Does the compiler advertise C11 conformance? #if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L # error "Compiler does not advertise C11 conformance" #endif // Check _Alignas. char _Alignas (double) aligned_as_double; char _Alignas (0) no_special_alignment; extern char aligned_as_int; char _Alignas (0) _Alignas (int) aligned_as_int; // Check _Alignof. enum { int_alignment = _Alignof (int), int_array_alignment = _Alignof (int[100]), char_alignment = _Alignof (char) }; _Static_assert (0 < -_Alignof (int), "_Alignof is signed"); // Check _Noreturn. int _Noreturn does_not_return (void) { for (;;) continue; } // Check _Static_assert. struct test_static_assert { int x; _Static_assert (sizeof (int) <= sizeof (long int), "_Static_assert does not work in struct"); long int y; }; // Check UTF-8 literals. #define u8 syntax error! char const utf8_literal[] = u8"happens to be ASCII" "another string"; // Check duplicate typedefs. typedef long *long_ptr; typedef long int *long_ptr; typedef long_ptr long_ptr; // Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1. struct anonymous { union { struct { int i; int j; }; struct { int k; long int l; } w; }; int m; } v1; ' # Test code for whether the C compiler supports C11 (body of main). ac_c_conftest_c11_main=' _Static_assert ((offsetof (struct anonymous, i) == offsetof (struct anonymous, w.k)), "Anonymous union alignment botch"); v1.i = 2; v1.w.k = 5; ok |= v1.i != 5; ' # Test code for whether the C compiler supports C11 (complete). ac_c_conftest_c11_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} ${ac_c_conftest_c11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} ${ac_c_conftest_c11_main} return ok; } " # Test code for whether the C compiler supports C99 (complete). ac_c_conftest_c99_program="${ac_c_conftest_c89_globals} ${ac_c_conftest_c99_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} ${ac_c_conftest_c99_main} return ok; } " # Test code for whether the C compiler supports C89 (complete). ac_c_conftest_c89_program="${ac_c_conftest_c89_globals} int main (int argc, char **argv) { int ok = 0; ${ac_c_conftest_c89_main} return ok; } " as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H" as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H" as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H" as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H" as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H" as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H" as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H" as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H" as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H" # Test code for whether the C++ compiler supports C++98 (global declarations) ac_cxx_conftest_cxx98_globals=' // Does the compiler advertise C++98 conformance? #if !defined __cplusplus || __cplusplus < 199711L # error "Compiler does not advertise C++98 conformance" #endif // These inclusions are to reject old compilers that // lack the unsuffixed header files. #include #include // and are *not* freestanding headers in C++98. extern void assert (int); namespace std { extern int strcmp (const char *, const char *); } // Namespaces, exceptions, and templates were all added after "C++ 2.0". using std::exception; using std::strcmp; namespace { void test_exception_syntax() { try { throw "test"; } catch (const char *s) { // Extra parentheses suppress a warning when building autoconf itself, // due to lint rules shared with more typical C programs. assert (!(strcmp) (s, "test")); } } template struct test_template { T const val; explicit test_template(T t) : val(t) {} template T add(U u) { return static_cast(u) + val; } }; } // anonymous namespace ' # Test code for whether the C++ compiler supports C++98 (body of main) ac_cxx_conftest_cxx98_main=' assert (argc); assert (! argv[0]); { test_exception_syntax (); test_template tt (2.0); assert (tt.add (4) == 6.0); assert (true && !false); } ' # Test code for whether the C++ compiler supports C++11 (global declarations) ac_cxx_conftest_cxx11_globals=' // Does the compiler advertise C++ 2011 conformance? #if !defined __cplusplus || __cplusplus < 201103L # error "Compiler does not advertise C++11 conformance" #endif namespace cxx11test { constexpr int get_val() { return 20; } struct testinit { int i; double d; }; class delegate { public: delegate(int n) : n(n) {} delegate(): delegate(2354) {} virtual int getval() { return this->n; }; protected: int n; }; class overridden : public delegate { public: overridden(int n): delegate(n) {} virtual int getval() override final { return this->n * 2; } }; class nocopy { public: nocopy(int i): i(i) {} nocopy() = default; nocopy(const nocopy&) = delete; nocopy & operator=(const nocopy&) = delete; private: int i; }; // for testing lambda expressions template Ret eval(Fn f, Ret v) { return f(v); } // for testing variadic templates and trailing return types template auto sum(V first) -> V { return first; } template auto sum(V first, Args... rest) -> V { return first + sum(rest...); } } ' # Test code for whether the C++ compiler supports C++11 (body of main) ac_cxx_conftest_cxx11_main=' { // Test auto and decltype auto a1 = 6538; auto a2 = 48573953.4; auto a3 = "String literal"; int total = 0; for (auto i = a3; *i; ++i) { total += *i; } decltype(a2) a4 = 34895.034; } { // Test constexpr short sa[cxx11test::get_val()] = { 0 }; } { // Test initializer lists cxx11test::testinit il = { 4323, 435234.23544 }; } { // Test range-based for int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3, 14, 19, 17, 8, 6, 20, 16, 2, 11, 1}; for (auto &x : array) { x += 23; } } { // Test lambda expressions using cxx11test::eval; assert (eval ([](int x) { return x*2; }, 21) == 42); double d = 2.0; assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0); assert (d == 5.0); assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0); assert (d == 5.0); } { // Test use of variadic templates using cxx11test::sum; auto a = sum(1); auto b = sum(1, 2); auto c = sum(1.0, 2.0, 3.0); } { // Test constructor delegation cxx11test::delegate d1; cxx11test::delegate d2(); cxx11test::delegate d3(45); } { // Test override and final cxx11test::overridden o1(55464); } { // Test nullptr char *c = nullptr; } { // Test template brackets test_template<::test_template> v(test_template(12)); } { // Unicode literals char const *utf8 = u8"UTF-8 string \u2500"; char16_t const *utf16 = u"UTF-8 string \u2500"; char32_t const *utf32 = U"UTF-32 string \u2500"; } ' # Test code for whether the C compiler supports C++11 (complete). ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals} ${ac_cxx_conftest_cxx11_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} ${ac_cxx_conftest_cxx11_main} return ok; } " # Test code for whether the C compiler supports C++98 (complete). ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals} int main (int argc, char **argv) { int ok = 0; ${ac_cxx_conftest_cxx98_main} return ok; } " # Auxiliary files required by this configure script. ac_aux_files="compile ltmain.sh config.guess config.sub missing install-sh" # Locations in which to look for auxiliary files. ac_aux_dir_candidates="${srcdir}/build-aux" # Search for a directory containing all of the required auxiliary files, # $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates. # If we don't find one directory that contains all the files we need, # we report the set of missing files from the *first* directory in # $ac_aux_dir_candidates and give up. ac_missing_aux_files="" ac_first_candidate=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR as_found=false for as_dir in $ac_aux_dir_candidates do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac as_found=: printf "%s\n" "$as_me:${as_lineno-$LINENO}: trying $as_dir" >&5 ac_aux_dir_found=yes ac_install_sh= for ac_aux in $ac_aux_files do # As a special case, if "install-sh" is required, that requirement # can be satisfied by any of "install-sh", "install.sh", or "shtool", # and $ac_install_sh is set appropriately for whichever one is found. if test x"$ac_aux" = x"install-sh" then if test -f "${as_dir}install-sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install-sh found" >&5 ac_install_sh="${as_dir}install-sh -c" elif test -f "${as_dir}install.sh"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}install.sh found" >&5 ac_install_sh="${as_dir}install.sh -c" elif test -f "${as_dir}shtool"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}shtool found" >&5 ac_install_sh="${as_dir}shtool install -c" else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} install-sh" else break fi fi else if test -f "${as_dir}${ac_aux}"; then printf "%s\n" "$as_me:${as_lineno-$LINENO}: ${as_dir}${ac_aux} found" >&5 else ac_aux_dir_found=no if $ac_first_candidate; then ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}" else break fi fi fi done if test "$ac_aux_dir_found" = yes; then ac_aux_dir="$as_dir" break fi ac_first_candidate=false as_found=false done IFS=$as_save_IFS if $as_found then : else $as_nop as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5 fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. if test -f "${ac_aux_dir}config.guess"; then ac_config_guess="$SHELL ${ac_aux_dir}config.guess" fi if test -f "${ac_aux_dir}config.sub"; then ac_config_sub="$SHELL ${ac_aux_dir}config.sub" fi if test -f "$ac_aux_dir/configure"; then ac_configure="$SHELL ${ac_aux_dir}configure" fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then # differences in whitespace do not lead to failure. ac_old_val_w=`echo x $ac_old_val` ac_new_val_w=`echo x $ac_new_val` if test "$ac_old_val_w" != "$ac_new_val_w"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} ac_cache_corrupted=: else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} eval $ac_var=\$ac_old_val fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 printf "%s\n" "$as_me: former value: \`$ac_old_val'" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 printf "%s\n" "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) as_fn_append ac_configure_args " '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;} as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 fi ## -------------------- ## ## Main body of script. ## ## -------------------- ## ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_config_headers="$ac_config_headers src/config.h" am__api_version='1.16' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. # Reject install programs that cannot install multiple files. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 printf %s "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test ${ac_cv_path_install+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac # Account for fact that we put trailing slashes in our PATH walk. case $as_dir in #(( ./ | /[cC]/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then if test $ac_prog = install && grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else rm -rf conftest.one conftest.two conftest.dir echo one > conftest.one echo two > conftest.two mkdir conftest.dir if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" && test -s conftest.one && test -s conftest.two && test -s conftest.dir/conftest.one && test -s conftest.dir/conftest.two then ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c" break 3 fi fi fi done done ;; esac done IFS=$as_save_IFS rm -rf conftest.one conftest.two conftest.dir fi if test ${ac_cv_path_install+y}; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 printf "%s\n" "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 printf %s "checking whether build environment is sane... " >&6; } # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[\\\"\#\$\&\'\`$am_lf]*) as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;; esac case $srcdir in *[\\\"\#\$\&\'\`$am_lf\ \ ]*) as_fn_error $? "unsafe srcdir value: '$srcdir'" "$LINENO" 5;; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$*" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$*" != "X $srcdir/configure conftest.file" \ && test "$*" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". as_fn_error $? "ls -t appears to fail. Make sure there is not a broken alias in your environment" "$LINENO" 5 fi if test "$2" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$2" = conftest.file ) then # Ok. : else as_fn_error $? "newly created file is older than distributed files! Check your system clock" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi rm -f conftest.file test "$program_prefix" != NONE && program_transform_name="s&^&$program_prefix&;$program_transform_name" # Use a double $ so make ignores it. test "$program_suffix" != NONE && program_transform_name="s&\$&$program_suffix&;$program_transform_name" # Double any \ or $. # By default was `s,x,x', remove it if useless. ac_script='s/[\\$]/&&/g;s/;s,x,x,$//' program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"` # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5 printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;} fi if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. if test "$cross_compiling" != no; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5 printf %s "checking for a race-free mkdir -p... " >&6; } if test -z "$MKDIR_P"; then if test ${ac_cv_path_mkdir+y} then : printf %s "(cached) " >&6 else $as_nop as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in mkdir gmkdir; do for ac_exec_ext in '' $ac_executable_extensions; do as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #( 'mkdir ('*'coreutils) '* | \ 'BusyBox '* | \ 'mkdir (fileutils) '4.1*) ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext break 3;; esac done done done IFS=$as_save_IFS fi test -d ./--version && rmdir ./--version if test ${ac_cv_path_mkdir+y}; then MKDIR_P="$ac_cv_path_mkdir -p" else # As a last resort, use the slow shell script. Don't cache a # value for MKDIR_P within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. MKDIR_P="$ac_install_sh -d" fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5 printf "%s\n" "$MKDIR_P" >&6; } for ac_prog in gawk mawk nawk awk do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AWK+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AWK"; then ac_cv_prog_AWK="$AWK" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AWK="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AWK=$ac_cv_prog_AWK if test -n "$AWK"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5 printf "%s\n" "$AWK" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AWK" && break done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5 printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; } set x ${MAKE-make} ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'` if eval test \${ac_cv_prog_make_${ac_make}_set+y} then : printf %s "(cached) " >&6 else $as_nop cat >conftest.make <<\_ACEOF SHELL = /bin/sh all: @echo '@@@%%%=$(MAKE)=@@@%%%' _ACEOF # GNU make sometimes prints "make[1]: Entering ...", which would confuse us. case `${MAKE-make} -f conftest.make 2>/dev/null` in *@@@%%%=?*=@@@%%%*) eval ac_cv_prog_make_${ac_make}_set=yes;; *) eval ac_cv_prog_make_${ac_make}_set=no;; esac rm -f conftest.make fi if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } SET_MAKE= else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } SET_MAKE="MAKE=${MAKE-make}" fi rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null # Check whether --enable-silent-rules was given. if test ${enable_silent_rules+y} then : enableval=$enable_silent_rules; fi case $enable_silent_rules in # ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=1;; esac am_make=${MAKE-make} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5 printf %s "checking whether $am_make supports nested variables... " >&6; } if test ${am_cv_make_support_nested_variables+y} then : printf %s "(cached) " >&6 else $as_nop if printf "%s\n" 'TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit' | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5 printf "%s\n" "$am_cv_make_support_nested_variables" >&6; } if test $am_cv_make_support_nested_variables = yes; then AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AM_BACKSLASH='\' if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." am__isrc=' -I$(srcdir)' # test to see if srcdir already configured if test -f $srcdir/config.status; then as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5 fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi # Define the identity of the package. PACKAGE='libsidplayfp' VERSION='3.0.0' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h # Some tools Automake needs. ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. # Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AMTAR='$${TAR-tar}' # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar pax cpio none' am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -' # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi if test -z "$ETAGS"; then ETAGS=etags fi if test -z "$CSCOPE"; then CSCOPE=cscope fi # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END as_fn_error $? "Your 'rm' program is bad, sorry." "$LINENO" 5 fi fi LIB_MAJOR=3 LIB_MINOR=0 LIB_LEVEL=0 # Make sure we can run config.sub. $SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 || as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 printf %s "checking build system type... " >&6; } if test ${ac_cv_build+y} then : printf %s "(cached) " >&6 else $as_nop ac_build_alias=$build_alias test "x$ac_build_alias" = x && ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"` test "x$ac_build_alias" = x && as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 printf "%s\n" "$ac_cv_build" >&6; } case $ac_cv_build in *-*-*) ;; *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; esac build=$ac_cv_build ac_save_IFS=$IFS; IFS='-' set x $ac_cv_build shift build_cpu=$1 build_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: build_os=$* IFS=$ac_save_IFS case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 printf %s "checking host system type... " >&6; } if test ${ac_cv_host+y} then : printf %s "(cached) " >&6 else $as_nop if test "x$host_alias" = x; then ac_cv_host=$ac_cv_build else ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` || as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5 fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 printf "%s\n" "$ac_cv_host" >&6; } case $ac_cv_host in *-*-*) ;; *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; esac host=$ac_cv_host ac_save_IFS=$IFS; IFS='-' set x $ac_cv_host shift host_cpu=$1 host_vendor=$2 shift; shift # Remember, the first character of IFS is used to create $*, # except with old shells: host_os=$* IFS=$ac_save_IFS case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac case $host_os in #( mingw*) : MINGW32=yes ;; #( darwin*) : MACOS=yes ;; #( *) : MINGW32=no MACOS=no ;; esac if test "x$MINGW32" = "xyes"; then MINGW32_TRUE= MINGW32_FALSE='#' else MINGW32_TRUE='#' MINGW32_FALSE= fi if test "x$MACOS" = "xyes"; then MACOS_TRUE= MACOS_FALSE='#' else MACOS_TRUE='#' MACOS_FALSE= fi case `pwd` in *\ * | *\ *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 printf "%s\n" "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; esac macro_version='2.4.7' macro_revision='2.4.7' ltmain=$ac_aux_dir/ltmain.sh # Backslashify metacharacters that are still active within # double-quoted strings. sed_quote_subst='s/\(["`$\\]\)/\\\1/g' # Same as above, but do not quote variable references. double_quote_subst='s/\(["`\\]\)/\\\1/g' # Sed substitution to delay expansion of an escaped shell variable in a # double_quote_subst'ed string. delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' # Sed substitution to delay expansion of an escaped single quote. delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' # Sed substitution to avoid accidental globbing in evaled expressions no_glob_subst='s/\*/\\\*/g' ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5 printf %s "checking how to print strings... " >&6; } # Test print first, because it will be a builtin if present. if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='print -r --' elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then ECHO='printf %s\n' else # Use this function as a fallback that always works. func_fallback_echo () { eval 'cat <<_LTECHO_EOF $1 _LTECHO_EOF' } ECHO='func_fallback_echo' fi # func_echo_all arg... # Invoke $ECHO with all args, space-separated. func_echo_all () { $ECHO "" } case $ECHO in printf*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: printf" >&5 printf "%s\n" "printf" >&6; } ;; print*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: print -r" >&5 printf "%s\n" "print -r" >&6; } ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: cat" >&5 printf "%s\n" "cat" >&6; } ;; esac DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; } cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } case $?:`cat confinc.out 2>/dev/null` in #( '0:this is the am__doit target') : case $s in #( BSD) : am__include='.include' am__quote='"' ;; #( *) : am__include='include' am__quote='' ;; esac ;; #( *) : ;; esac if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 printf "%s\n" "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test ${enable_dependency_tracking+y} then : enableval=$enable_dependency_tracking; fi if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi if test "x$enable_dependency_tracking" != xno; then AMDEP_TRUE= AMDEP_FALSE='#' else AMDEP_TRUE='#' AMDEP_FALSE= fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="gcc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args. set dummy ${ac_tool_prefix}clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CC="${ac_tool_prefix}clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 printf "%s\n" "$CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "clang", so it can be a program name with args. set dummy clang; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CC="clang" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 printf "%s\n" "$ac_ct_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi fi test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "no acceptable C compiler found in \$PATH See \`config.log' for more details" "$LINENO" 5; } # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion -version; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 printf %s "checking whether the C compiler works... " >&6; } ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # The possible output files: ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { { ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link_default") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else $as_nop ac_file='' fi if test -z "$ac_file" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "C compiler cannot create executables See \`config.log' for more details" "$LINENO" 5; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 printf %s "checking for C compiler default output file name... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 printf "%s\n" "$ac_file" >&6; } ac_exeext=$ac_cv_exeext rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 printf %s "checking for suffix of executables... " >&6; } if { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of executables: cannot compile and link See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest conftest$ac_cv_exeext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 printf "%s\n" "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { FILE *f = fopen ("conftest.out", "w"); return ferror (f) || fclose (f) != 0; ; return 0; } _ACEOF ac_clean_files="$ac_clean_files conftest.out" # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 printf %s "checking whether we are cross compiling... " >&6; } if test "$cross_compiling" != yes; then { { ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_link") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if { ac_try='./conftest$ac_cv_exeext' { { case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_try") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details" "$LINENO" 5; } fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 printf "%s\n" "$cross_compiling" >&6; } rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out ac_clean_files=$ac_clean_files_save { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 printf %s "checking for suffix of object files... " >&6; } if test ${ac_cv_objext+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { { ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compile") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then : for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else $as_nop printf "%s\n" "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot compute suffix of object files: cannot compile See \`config.log' for more details" "$LINENO" 5; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 printf "%s\n" "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5 printf %s "checking whether the compiler supports GNU C... " >&6; } if test ${ac_cv_c_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_c_compiler_gnu if test $ac_compiler_gnu = yes; then GCC=yes else GCC= fi ac_test_CFLAGS=${CFLAGS+y} ac_save_CFLAGS=$CFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 printf %s "checking whether $CC accepts -g... " >&6; } if test ${ac_cv_prog_cc_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes else $as_nop CFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : else $as_nop ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 printf "%s\n" "$ac_cv_prog_cc_g" >&6; } if test $ac_test_CFLAGS; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi ac_prog_cc_stdc=no if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5 printf %s "checking for $CC option to enable C11 features... " >&6; } if test ${ac_cv_prog_cc_c11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c11=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c11_program _ACEOF for ac_arg in '' -std=gnu11 do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c11" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5 printf "%s\n" "$ac_cv_prog_cc_c11" >&6; } CC="$CC $ac_cv_prog_cc_c11" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11 ac_prog_cc_stdc=c11 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5 printf %s "checking for $CC option to enable C99 features... " >&6; } if test ${ac_cv_prog_cc_c99+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c99=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c99_program _ACEOF for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99= do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c99=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c99" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c99" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c99" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5 printf "%s\n" "$ac_cv_prog_cc_c99" >&6; } CC="$CC $ac_cv_prog_cc_c99" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99 ac_prog_cc_stdc=c99 fi fi if test x$ac_prog_cc_stdc = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5 printf %s "checking for $CC option to enable C89 features... " >&6; } if test ${ac_cv_prog_cc_c89+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cc_c89=no ac_save_CC=$CC cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_c_conftest_c89_program _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" if ac_fn_c_try_compile "$LINENO" then : ac_cv_prog_cc_c89=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi if test "x$ac_cv_prog_cc_c89" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cc_c89" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 printf "%s\n" "$ac_cv_prog_cc_c89" >&6; } CC="$CC $ac_cv_prog_cc_c89" fi ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89 ac_prog_cc_stdc=c89 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 printf %s "checking whether $CC understands -c and -o together... " >&6; } if test ${am_cv_prog_cc_c_o+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 printf "%s\n" "$am_cv_prog_cc_c_o" >&6; } if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CC" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CC_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CC_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CC_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CC_dependencies_compiler_type=none fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; } CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then am__fastdepCC_TRUE= am__fastdepCC_FALSE='#' else am__fastdepCC_TRUE='#' am__fastdepCC_FALSE= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 printf %s "checking for a sed that does not truncate output... " >&6; } if test ${ac_cv_path_SED+y} then : printf %s "(cached) " >&6 else $as_nop ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ for ac_i in 1 2 3 4 5 6 7; do ac_script="$ac_script$as_nl$ac_script" done echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed { ac_script=; unset ac_script;} if test -z "$SED"; then ac_path_SED_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in sed gsed do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_SED="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_SED" || continue # Check for GNU ac_path_SED and select it if it is found. # Check for GNU $ac_path_SED case `"$ac_path_SED" --version 2>&1` in *GNU*) ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" '' >> "conftest.nl" "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_SED_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_SED="$ac_path_SED" ac_path_SED_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_SED_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_SED"; then as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 fi else ac_cv_path_SED=$SED fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 printf "%s\n" "$ac_cv_path_SED" >&6; } SED="$ac_cv_path_SED" rm -f conftest.sed test -z "$SED" && SED=sed Xsed="$SED -e 1s/^X//" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 printf %s "checking for grep that handles long lines and -e... " >&6; } if test ${ac_cv_path_GREP+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$GREP"; then ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in grep ggrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_GREP" || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_GREP"; then as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_GREP=$GREP fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 printf "%s\n" "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 printf %s "checking for egrep... " >&6; } if test ${ac_cv_path_EGREP+y} then : printf %s "(cached) " >&6 else $as_nop if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else if test -z "$EGREP"; then ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in egrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_EGREP" || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_EGREP"; then as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_EGREP=$EGREP fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 printf "%s\n" "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 printf %s "checking for fgrep... " >&6; } if test ${ac_cv_path_FGREP+y} then : printf %s "(cached) " >&6 else $as_nop if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 then ac_cv_path_FGREP="$GREP -F" else if test -z "$FGREP"; then ac_path_FGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in fgrep do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_FGREP="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_FGREP" || continue # Check for GNU ac_path_FGREP and select it if it is found. # Check for GNU $ac_path_FGREP case `"$ac_path_FGREP" --version 2>&1` in *GNU*) ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; *) ac_count=0 printf %s 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" printf "%s\n" 'FGREP' >> "conftest.nl" "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break as_fn_arith $ac_count + 1 && ac_count=$as_val if test $ac_count -gt ${ac_path_FGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_FGREP_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_FGREP"; then as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 fi else ac_cv_path_FGREP=$FGREP fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 printf "%s\n" "$ac_cv_path_FGREP" >&6; } FGREP="$ac_cv_path_FGREP" test -z "$GREP" && GREP=grep # Check whether --with-gnu-ld was given. if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 printf %s "checking for BSD- or MS-compatible name lister (nm)... " >&6; } if test ${lt_cv_path_NM+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$NM"; then # Let the user override the test. lt_cv_path_NM=$NM else lt_nm_to_check=${ac_tool_prefix}nm if test -n "$ac_tool_prefix" && test "$build" = "$host"; then lt_nm_to_check="$lt_nm_to_check nm" fi for lt_tmp_nm in $lt_nm_to_check; do lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. tmp_nm=$ac_dir/$lt_tmp_nm if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext"; then # Check to see if the nm accepts a BSD-compat flag. # Adding the 'sed 1q' prevents false positives on HP-UX, which says: # nm: unknown option "B" ignored # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in mingw*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 ;; *) lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but continue # so that we can try to find one that supports BSD flags ;; esac ;; esac fi done IFS=$lt_save_ifs done : ${lt_cv_path_NM=no} fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 printf "%s\n" "$lt_cv_path_NM" >&6; } if test no != "$lt_cv_path_NM"; then NM=$lt_cv_path_NM else # Didn't find any BSD compatible name lister, look for dumpbin. if test -n "$DUMPBIN"; then : # Let the user override the test. else if test -n "$ac_tool_prefix"; then for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DUMPBIN"; then ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DUMPBIN=$ac_cv_prog_DUMPBIN if test -n "$DUMPBIN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 printf "%s\n" "$DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$DUMPBIN" && break done fi if test -z "$DUMPBIN"; then ac_ct_DUMPBIN=$DUMPBIN for ac_prog in dumpbin "link -dump" do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DUMPBIN+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DUMPBIN"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN if test -n "$ac_ct_DUMPBIN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 printf "%s\n" "$ac_ct_DUMPBIN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_DUMPBIN" && break done if test "x$ac_ct_DUMPBIN" = x; then DUMPBIN=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DUMPBIN=$ac_ct_DUMPBIN fi fi case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; *) DUMPBIN=: ;; esac fi if test : != "$DUMPBIN"; then NM=$DUMPBIN fi fi test -z "$NM" && NM=nm { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 printf %s "checking the name lister ($NM) interface... " >&6; } if test ${lt_cv_nm_interface+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 (eval echo "\"\$as_me:$LINENO: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" fi rm -f conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 printf "%s\n" "$lt_cv_nm_interface" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 printf %s "checking whether ln -s works... " >&6; } LN_S=$as_ln_s if test "$LN_S" = "ln -s"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 printf "%s\n" "no, using $LN_S" >&6; } fi # find the maximum length of command line arguments { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 printf %s "checking the maximum length of command line arguments... " >&6; } if test ${lt_cv_sys_max_cmd_len+y} then : printf %s "(cached) " >&6 else $as_nop i=0 teststring=ABCD case $build_os in msdosdjgpp*) # On DJGPP, this test can blow up pretty badly due to problems in libc # (any single argument exceeding 2000 bytes causes a buffer overrun # during glob expansion). Even if it were fixed, the result of this # check would be larger than it should be. lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; gnu*) # Under GNU Hurd, this test is not required because there is # no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; cygwin* | mingw* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, # you end up with a "frozen" computer, even though with patience # the test eventually succeeds (with a max line length of 256k). # Instead, let's just punt: use the minimum linelength reported by # all of the supported platforms: 8192 (on NT/2K/XP). lt_cv_sys_max_cmd_len=8192; ;; mint*) # On MiNT this can take a long time and run out of memory. lt_cv_sys_max_cmd_len=8192; ;; amigaos*) # On AmigaOS with pdksh, this test takes hours, literally. # So we just punt and use a minimum line length of 8192. lt_cv_sys_max_cmd_len=8192; ;; bitrig* | darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; interix*) # We know the value 262144 and hardcode it with a safety zone (like BSD) lt_cv_sys_max_cmd_len=196608 ;; os2*) # The test takes a long time on OS/2. lt_cv_sys_max_cmd_len=8192 ;; osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; sco3.2v5*) lt_cv_sys_max_cmd_len=102400 ;; sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi ;; *) lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` if test -n "$lt_cv_sys_max_cmd_len" && \ test undefined != "$lt_cv_sys_max_cmd_len"; then lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` else # Make teststring a little bigger before we do anything with it. # a 1K string should be a reasonable start. for i in 1 2 3 4 5 6 7 8; do teststring=$teststring$teststring done SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} # If test is not a shell built-in, we'll probably end up computing a # maximum length that is only half of the actual maximum length, but # we can't tell. while { test X`env echo "$teststring$teststring" 2>/dev/null` \ = "X$teststring$teststring"; } >/dev/null 2>&1 && test 17 != "$i" # 1/2 MB should be enough do i=`expr $i + 1` teststring=$teststring$teststring done # Only check the string length outside the loop. lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` teststring= # Add a significant safety factor because C++ compilers can tack on # massive amounts of additional arguments before passing them to the # linker. It appears as though 1/2 is a usable value. lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` fi ;; esac fi if test -n "$lt_cv_sys_max_cmd_len"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 printf "%s\n" "$lt_cv_sys_max_cmd_len" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none" >&5 printf "%s\n" "none" >&6; } fi max_cmd_len=$lt_cv_sys_max_cmd_len : ${CP="cp -f"} : ${MV="mv -f"} : ${RM="rm -f"} if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then lt_unset=unset else lt_unset=false fi # test EBCDIC or ASCII case `echo X|tr X '\101'` in A) # ASCII based system # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr lt_SP2NL='tr \040 \012' lt_NL2SP='tr \015\012 \040\040' ;; *) # EBCDIC based system lt_SP2NL='tr \100 \n' lt_NL2SP='tr \r\n \100\100' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5 printf %s "checking how to convert $build file names to $host format... " >&6; } if test ${lt_cv_to_host_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32 ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32 ;; esac ;; *-*-cygwin* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) lt_cv_to_host_file_cmd=func_convert_file_noop ;; * ) # otherwise, assume *nix lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin ;; esac ;; * ) # unhandled hosts (and "normal" native builds) lt_cv_to_host_file_cmd=func_convert_file_noop ;; esac fi to_host_file_cmd=$lt_cv_to_host_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5 printf "%s\n" "$lt_cv_to_host_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5 printf %s "checking how to convert $build file names to toolchain format... " >&6; } if test ${lt_cv_to_tool_file_cmd+y} then : printf %s "(cached) " >&6 else $as_nop #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in *-*-mingw* ) case $build in *-*-mingw* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac ;; esac fi to_tool_file_cmd=$lt_cv_to_tool_file_cmd { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5 printf "%s\n" "$lt_cv_to_tool_file_cmd" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 printf %s "checking for $LD option to reload object files... " >&6; } if test ${lt_cv_ld_reload_flag+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_reload_flag='-r' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 printf "%s\n" "$lt_cv_ld_reload_flag" >&6; } reload_flag=$lt_cv_ld_reload_flag case $reload_flag in "" | " "*) ;; *) reload_flag=" $reload_flag" ;; esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in cygwin* | mingw* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi ;; darwin*) if test yes = "$GCC"; then reload_cmds='$LTCC $LTCFLAGS -nostdlib $wl-r -o $output$reload_objs' else reload_cmds='$LD$reload_flag -o $output$reload_objs' fi ;; esac if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}file", so it can be a program name with args. set dummy ${ac_tool_prefix}file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$FILECMD"; then ac_cv_prog_FILECMD="$FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_FILECMD="${ac_tool_prefix}file" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi FILECMD=$ac_cv_prog_FILECMD if test -n "$FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FILECMD" >&5 printf "%s\n" "$FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_FILECMD"; then ac_ct_FILECMD=$FILECMD # Extract the first word of "file", so it can be a program name with args. set dummy file; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_FILECMD+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_FILECMD"; then ac_cv_prog_ac_ct_FILECMD="$ac_ct_FILECMD" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_FILECMD="file" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_FILECMD=$ac_cv_prog_ac_ct_FILECMD if test -n "$ac_ct_FILECMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_FILECMD" >&5 printf "%s\n" "$ac_ct_FILECMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_FILECMD" = x; then FILECMD=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac FILECMD=$ac_ct_FILECMD fi else FILECMD="$ac_cv_prog_FILECMD" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 printf "%s\n" "$OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 printf "%s\n" "$ac_ct_OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi test -z "$OBJDUMP" && OBJDUMP=objdump { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 printf %s "checking how to recognize dependent libraries... " >&6; } if test ${lt_cv_deplibs_check_method+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_file_magic_cmd='$MAGIC_CMD' lt_cv_file_magic_test_file= lt_cv_deplibs_check_method='unknown' # Need to set the preceding variable on all platforms that support # interlibrary dependencies. # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. # 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure # whether 'pass_all' will *always* work, you probably want this one. case $host_os in aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; beos*) lt_cv_deplibs_check_method=pass_all ;; bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; cygwin*) # func_win32_libid is a shell function defined in ltmain.sh lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' ;; mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. if ( file / ) >/dev/null 2>&1; then lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; cegcc*) # use the weaker test based on 'objdump'. See mingw*. lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' lt_cv_file_magic_cmd='$OBJDUMP -f' ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac else lt_cv_deplibs_check_method=pass_all fi ;; haiku*) lt_cv_deplibs_check_method=pass_all ;; hpux10.20* | hpux11*) lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so ;; hppa*64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]' lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl ;; *) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library' lt_cv_file_magic_test_file=/usr/lib/libc.sl ;; esac ;; interix[3-9]*) # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' ;; irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; *-n32|*"-n32 ") libmagic=N32;; *-64|*"-64 ") libmagic=64-bit;; *) libmagic=never-match;; esac lt_cv_deplibs_check_method=pass_all ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) lt_cv_deplibs_check_method=pass_all ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' fi ;; newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; *nto* | *qnx*) lt_cv_deplibs_check_method=pass_all ;; openbsd* | bitrig*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' fi ;; osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; rdos*) lt_cv_deplibs_check_method=pass_all ;; solaris*) lt_cv_deplibs_check_method=pass_all ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` ;; ncr) lt_cv_deplibs_check_method=pass_all ;; sequent) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' ;; sni) lt_cv_file_magic_cmd='/bin/file' lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" lt_cv_file_magic_test_file=/lib/libc.so ;; siemens) lt_cv_deplibs_check_method=pass_all ;; pc) lt_cv_deplibs_check_method=pass_all ;; esac ;; tpf*) lt_cv_deplibs_check_method=pass_all ;; os2*) lt_cv_deplibs_check_method=pass_all ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 printf "%s\n" "$lt_cv_deplibs_check_method" >&6; } file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in mingw* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"` fi ;; esac fi file_magic_cmd=$lt_cv_file_magic_cmd deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 printf "%s\n" "$DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 printf "%s\n" "$ac_ct_DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi test -z "$DLLTOOL" && DLLTOOL=dlltool { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5 printf %s "checking how to associate runtime and link libraries... " >&6; } if test ${lt_cv_sharedlib_from_linklib_cmd+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in cygwin* | mingw* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in *--identify-strict*) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib ;; *) lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback ;; esac ;; *) # fallback: assume linklib IS sharedlib lt_cv_sharedlib_from_linklib_cmd=$ECHO ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5 printf "%s\n" "$lt_cv_sharedlib_from_linklib_cmd" >&6; } sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AR="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AR=$ac_cv_prog_AR if test -n "$AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 printf "%s\n" "$AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$AR" && break done fi if test -z "$AR"; then ac_ct_AR=$AR for ac_prog in ar do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_AR+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_AR"; then ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AR="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AR=$ac_cv_prog_ac_ct_AR if test -n "$ac_ct_AR"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 printf "%s\n" "$ac_ct_AR" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_AR" && break done if test "x$ac_ct_AR" = x; then AR="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AR=$ac_ct_AR fi fi : ${AR=ar} # Use ARFLAGS variable as AR's operation code to sync the variable naming with # Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have # higher priority because thats what people were doing historically (setting # ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS # variable obsoleted/removed. test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} lt_ar_flags=$AR_FLAGS # Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override # by AR_FLAGS because that was never working and AR_FLAGS is about to die. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5 printf %s "checking for archiver @FILE support... " >&6; } if test ${lt_cv_ar_at_file+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ar_at_file=no cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_compile "$LINENO" then : echo conftest.$ac_objext > conftest.lst lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5' { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -eq "$ac_status"; then # Ensure the archiver fails upon bogus file names. rm -f conftest.$ac_objext libconftest.a { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5 (eval $lt_ar_try) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } if test 0 -ne "$ac_status"; then lt_cv_ar_at_file=@ fi fi rm -f conftest.* libconftest.a fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5 printf "%s\n" "$lt_cv_ar_at_file" >&6; } if test no = "$lt_cv_ar_at_file"; then archiver_list_spec= else archiver_list_spec=$lt_cv_ar_at_file fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$STRIP"; then ac_cv_prog_STRIP="$STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi STRIP=$ac_cv_prog_STRIP if test -n "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 printf "%s\n" "$STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_STRIP"; then ac_ct_STRIP=$STRIP # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_STRIP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_STRIP"; then ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_STRIP="strip" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP if test -n "$ac_ct_STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 printf "%s\n" "$ac_ct_STRIP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_STRIP" = x; then STRIP=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac STRIP=$ac_ct_STRIP fi else STRIP="$ac_cv_prog_STRIP" fi test -z "$STRIP" && STRIP=: if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi RANLIB=$ac_cv_prog_RANLIB if test -n "$RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 printf "%s\n" "$RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_RANLIB"; then ac_ct_RANLIB=$RANLIB # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_RANLIB+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_RANLIB"; then ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_RANLIB="ranlib" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB if test -n "$ac_ct_RANLIB"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 printf "%s\n" "$ac_ct_RANLIB" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_RANLIB" = x; then RANLIB=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac RANLIB=$ac_ct_RANLIB fi else RANLIB="$ac_cv_prog_RANLIB" fi test -z "$RANLIB" && RANLIB=: # Determine commands to create old-style static archives. old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in bitrig* | openbsd*) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" ;; *) old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in darwin*) lock_old_archive_extraction=yes ;; *) lock_old_archive_extraction=no ;; esac # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Check for command to grab the raw symbol name followed by C symbol from nm. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 printf %s "checking command to parse $NM output from $compiler object... " >&6; } if test ${lt_cv_sys_global_symbol_pipe+y} then : printf %s "(cached) " >&6 else $as_nop # These are sane defaults that work on at least a few old systems. # [They come from Ultrix. What could be older than Ultrix?!! ;)] # Character class describing NM global symbol codes. symcode='[BCDEGRST]' # Regexp to match symbols that can be accessed directly from C. sympat='\([_A-Za-z][_A-Za-z0-9]*\)' # Define system-specific variables. case $host_os in aix*) symcode='[BCDT]' ;; cygwin* | mingw* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) if test ia64 = "$host_cpu"; then symcode='[ABCDEGRST]' fi ;; irix* | nonstopux*) symcode='[BCDEGRST]' ;; osf*) symcode='[BCDEGQRST]' ;; solaris*) symcode='[BDRT]' ;; sco3.2v5*) symcode='[DT]' ;; sysv4.2uw2*) symcode='[DT]' ;; sysv5* | sco5v6* | unixware* | OpenUNIX*) symcode='[ABDT]' ;; sysv4) symcode='[DFNSTU]' ;; esac # If we're using GNU nm, then use its standard symbol codes. case `$NM -V 2>&1` in *GNU* | *'with BFD'*) symcode='[ABCDGIRSTW]' ;; esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" lt_c_name_lib_hook="\ -e 's/^I .* \(lib.*\)$/ {\"\1\", (void *) 0},/p'\ -e 's/^I .* \(.*\)$/ {\"lib\1\", (void *) 0},/p'" else # Disable hooks by default. lt_cv_sys_global_symbol_to_import= lt_cdecl_hook= lt_c_name_hook= lt_c_name_lib_hook= fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"lib\1\", (void *) \&\1},/p'" # Handle CRLF in mingw tool chain opt_cr= case $build_os in mingw*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac # Try without a prefix underscore, then with it. for ac_symprfx in "" "_"; do # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. symxfrm="\\1 $ac_symprfx\\2 \\2" # Write the raw and C identifiers. if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ " /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\ " /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ " /^ *Symbol name *: /{split(\$ 0,sn,\":\"); si=substr(sn[2],2)};"\ " /^ *Type *: code/{print \"T\",si,substr(si,length(prfx))};"\ " /^ *Type *: data/{print \"I\",si,substr(si,length(prfx))};"\ " \$ 0!~/External *\|/{next};"\ " / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ " {if(hide[section]) next};"\ " {f=\"D\"}; \$ 0~/\(\).*\|/{f=\"T\"};"\ " {split(\$ 0,a,/\||\r/); split(a[2],s)};"\ " s[1]~/^[@?]/{print f,s[1],s[1]; next};"\ " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no rm -f conftest* cat > conftest.$ac_ext <<_LT_EOF #ifdef __cplusplus extern "C" { #endif char nm_test_var; void nm_test_func(void); void nm_test_func(void){} #ifdef __cplusplus } #endif int main(){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" else rm -f "$nlist"T fi # Make sure that we snagged all the symbols we need. if $GREP ' nm_test_var$' "$nlist" >/dev/null; then if $GREP ' nm_test_func$' "$nlist" >/dev/null; then cat <<_LT_EOF > conftest.$ac_ext /* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests. */ #if defined _WIN32 || defined __CYGWIN__ || defined _WIN32_WCE /* DATA imports from DLLs on WIN32 can't be const, because runtime relocations are performed -- see ld's documentation on pseudo-relocs. */ # define LT_DLSYM_CONST #elif defined __osf__ /* This system does not cope well with relocations in const data. */ # define LT_DLSYM_CONST #else # define LT_DLSYM_CONST const #endif #ifdef __cplusplus extern "C" { #endif _LT_EOF # Now generate the symbol file. eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' cat <<_LT_EOF >> conftest.$ac_ext /* The mapping between symbol names and symbols. */ LT_DLSYM_CONST struct { const char *name; void *address; } lt__PROGRAM__LTX_preloaded_symbols[] = { { "@PROGRAM@", (void *) 0 }, _LT_EOF $SED "s/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext cat <<\_LT_EOF >> conftest.$ac_ext {0, (void *) 0} }; /* This works around a problem in FreeBSD linker */ #ifdef FREEBSD_WORKAROUND static const void *lt_preloaded_setup() { return lt__PROGRAM__LTX_preloaded_symbols; } #endif #ifdef __cplusplus } #endif _LT_EOF # Now try linking the two files. mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s conftest$ac_exeext; then pipe_works=yes fi LIBS=$lt_globsym_save_LIBS CFLAGS=$lt_globsym_save_CFLAGS else echo "cannot find nm_test_func in $nlist" >&5 fi else echo "cannot find nm_test_var in $nlist" >&5 fi else echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 fi else echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test yes = "$pipe_works"; then break else lt_cv_sys_global_symbol_pipe= fi done fi if test -z "$lt_cv_sys_global_symbol_pipe"; then lt_cv_sys_global_symbol_to_cdecl= fi if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5 printf "%s\n" "failed" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ok" >&5 printf "%s\n" "ok" >&6; } fi # Response file support. if test "$lt_cv_nm_interface" = "MS dumpbin"; then nm_file_list_spec='@' elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then nm_file_list_spec='@' fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5 printf %s "checking for sysroot... " >&6; } # Check whether --with-sysroot was given. if test ${with_sysroot+y} then : withval=$with_sysroot; else $as_nop with_sysroot=no fi lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then lt_sysroot=`$CC --print-sysroot 2>/dev/null` fi ;; #( /*) lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_sysroot" >&5 printf "%s\n" "$with_sysroot" >&6; } as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5 ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5 printf "%s\n" "${lt_sysroot:-no}" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a working dd" >&5 printf %s "checking for a working dd... " >&6; } if test ${ac_cv_path_lt_DD+y} then : printf %s "(cached) " >&6 else $as_nop printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i : ${lt_DD:=$DD} if test -z "$lt_DD"; then ac_path_lt_DD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in dd do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_lt_DD="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_lt_DD" || continue if "$ac_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && ac_cv_path_lt_DD="$ac_path_lt_DD" ac_path_lt_DD_found=: fi $ac_path_lt_DD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_lt_DD"; then : fi else ac_cv_path_lt_DD=$lt_DD fi rm -f conftest.i conftest2.i conftest.out fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_lt_DD" >&5 printf "%s\n" "$ac_cv_path_lt_DD" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to truncate binary pipes" >&5 printf %s "checking how to truncate binary pipes... " >&6; } if test ${lt_cv_truncate_bin+y} then : printf %s "(cached) " >&6 else $as_nop printf 0123456789abcdef0123456789abcdef >conftest.i cat conftest.i conftest.i >conftest2.i lt_cv_truncate_bin= if "$ac_cv_path_lt_DD" bs=32 count=1 conftest.out 2>/dev/null; then cmp -s conftest.i conftest.out \ && lt_cv_truncate_bin="$ac_cv_path_lt_DD bs=4096 count=1" fi rm -f conftest.i conftest2.i conftest.out test -z "$lt_cv_truncate_bin" && lt_cv_truncate_bin="$SED -e 4q" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_truncate_bin" >&5 printf "%s\n" "$lt_cv_truncate_bin" >&6; } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # Check whether --enable-libtool-lock was given. if test ${enable_libtool_lock+y} then : enableval=$enable_libtool_lock; fi test no = "$enable_libtool_lock" || enable_libtool_lock=yes # Some flags need to be propagated to the compiler or linker for good # libtool support. case $host in ia64-*-hpux*) # Find out what ABI is being produced by ac_compile, and set mode # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; *ELF-64*) HPUX_IA64_MODE=64 ;; esac fi rm -rf conftest* ;; *-*-irix6*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; *N32*) LD="${LD-ld} -melf32bmipn32" ;; *64-bit*) LD="${LD-ld} -melf64bmip" ;; esac else case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; *N32*) LD="${LD-ld} -n32" ;; *64-bit*) LD="${LD-ld} -64" ;; esac fi fi rm -rf conftest* ;; mips64*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo '#line '$LINENO' "configure"' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; *64-bit*) emul="${emul}64" ;; esac case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; *LSB*) emul="${emul}ltsmip" ;; esac case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; esac LD="${LD-ld} -m $emul" fi rm -rf conftest* ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ s390*-*linux*|s390*-*tpf*|sparc*-*linux*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when # doing 32-bit compilation for a host where ld defaults to 64-bit, or # vice versa); the common cases where no linker options are needed do # not appear in the list. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; x86_64-*linux*) case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; *) LD="${LD-ld} -m elf_i386" ;; esac ;; powerpc64le-*linux*) LD="${LD-ld} -m elf32lppclinux" ;; powerpc64-*linux*) LD="${LD-ld} -m elf32ppclinux" ;; s390x-*linux*) LD="${LD-ld} -m elf_s390" ;; sparc64-*linux*) LD="${LD-ld} -m elf32_sparc" ;; esac ;; *64-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) LD="${LD-ld} -m elf64lppc" ;; powerpc-*linux*) LD="${LD-ld} -m elf64ppc" ;; s390*-*linux*|s390*-*tpf*) LD="${LD-ld} -m elf64_s390" ;; sparc*-*linux*) LD="${LD-ld} -m elf64_sparc" ;; esac ;; esac fi rm -rf conftest* ;; *-*-sco3.2v5*) # On SCO OpenServer 5, we need -belf to get full-featured binaries. SAVE_CFLAGS=$CFLAGS CFLAGS="$CFLAGS -belf" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 printf %s "checking whether the C compiler needs -belf... " >&6; } if test ${lt_cv_cc_needs_belf+y} then : printf %s "(cached) " >&6 else $as_nop ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_cc_needs_belf=yes else $as_nop lt_cv_cc_needs_belf=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 printf "%s\n" "$lt_cv_cc_needs_belf" >&6; } if test yes != "$lt_cv_cc_needs_belf"; then # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf CFLAGS=$SAVE_CFLAGS fi ;; *-*solaris*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. echo 'int i;' > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) case $host in i?86-*-solaris*|x86_64-*-solaris*) LD="${LD-ld} -m elf_x86_64" ;; sparc*-*-solaris*) LD="${LD-ld} -m elf64_sparc" ;; esac # GNU ld 2.21 introduced _sol2 emulations. Use them if available. if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then LD=${LD-ld}_sol2 fi ;; *) if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then LD="${LD-ld} -64" fi ;; esac ;; esac fi rm -rf conftest* ;; esac need_locks=$enable_libtool_lock if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args. set dummy ${ac_tool_prefix}mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$MANIFEST_TOOL"; then ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_MANIFEST_TOOL="${ac_tool_prefix}mt" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL if test -n "$MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5 printf "%s\n" "$MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_MANIFEST_TOOL"; then ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL # Extract the first word of "mt", so it can be a program name with args. set dummy mt; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_MANIFEST_TOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_MANIFEST_TOOL"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_MANIFEST_TOOL="mt" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL if test -n "$ac_ct_MANIFEST_TOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5 printf "%s\n" "$ac_ct_MANIFEST_TOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_MANIFEST_TOOL" = x; then MANIFEST_TOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL fi else MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL" fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } if test ${lt_cv_path_mainfest_tool+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_path_mainfest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then lt_cv_path_mainfest_tool=yes fi rm -f conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } if test yes != "$lt_cv_path_mainfest_tool"; then MANIFEST_TOOL=: fi case $host_os in rhapsody* | darwin*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DSYMUTIL"; then ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DSYMUTIL=$ac_cv_prog_DSYMUTIL if test -n "$DSYMUTIL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 printf "%s\n" "$DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DSYMUTIL"; then ac_ct_DSYMUTIL=$DSYMUTIL # Extract the first word of "dsymutil", so it can be a program name with args. set dummy dsymutil; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DSYMUTIL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DSYMUTIL"; then ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL if test -n "$ac_ct_DSYMUTIL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 printf "%s\n" "$ac_ct_DSYMUTIL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DSYMUTIL" = x; then DSYMUTIL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DSYMUTIL=$ac_ct_DSYMUTIL fi else DSYMUTIL="$ac_cv_prog_DSYMUTIL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. set dummy ${ac_tool_prefix}nmedit; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$NMEDIT"; then ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi NMEDIT=$ac_cv_prog_NMEDIT if test -n "$NMEDIT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 printf "%s\n" "$NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_NMEDIT"; then ac_ct_NMEDIT=$NMEDIT # Extract the first word of "nmedit", so it can be a program name with args. set dummy nmedit; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_NMEDIT+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_NMEDIT"; then ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_NMEDIT="nmedit" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT if test -n "$ac_ct_NMEDIT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 printf "%s\n" "$ac_ct_NMEDIT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_NMEDIT" = x; then NMEDIT=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac NMEDIT=$ac_ct_NMEDIT fi else NMEDIT="$ac_cv_prog_NMEDIT" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. set dummy ${ac_tool_prefix}lipo; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$LIPO"; then ac_cv_prog_LIPO="$LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_LIPO="${ac_tool_prefix}lipo" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi LIPO=$ac_cv_prog_LIPO if test -n "$LIPO"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 printf "%s\n" "$LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_LIPO"; then ac_ct_LIPO=$LIPO # Extract the first word of "lipo", so it can be a program name with args. set dummy lipo; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_LIPO+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_LIPO"; then ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_LIPO="lipo" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO if test -n "$ac_ct_LIPO"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 printf "%s\n" "$ac_ct_LIPO" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_LIPO" = x; then LIPO=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac LIPO=$ac_ct_LIPO fi else LIPO="$ac_cv_prog_LIPO" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. set dummy ${ac_tool_prefix}otool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OTOOL"; then ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL="${ac_tool_prefix}otool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL=$ac_cv_prog_OTOOL if test -n "$OTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 printf "%s\n" "$OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL"; then ac_ct_OTOOL=$OTOOL # Extract the first word of "otool", so it can be a program name with args. set dummy otool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OTOOL"; then ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL="otool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL if test -n "$ac_ct_OTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 printf "%s\n" "$ac_ct_OTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL" = x; then OTOOL=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL=$ac_ct_OTOOL fi else OTOOL="$ac_cv_prog_OTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. set dummy ${ac_tool_prefix}otool64; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OTOOL64"; then ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OTOOL64=$ac_cv_prog_OTOOL64 if test -n "$OTOOL64"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 printf "%s\n" "$OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OTOOL64"; then ac_ct_OTOOL64=$OTOOL64 # Extract the first word of "otool64", so it can be a program name with args. set dummy otool64; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OTOOL64+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OTOOL64"; then ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OTOOL64="otool64" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 if test -n "$ac_ct_OTOOL64"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 printf "%s\n" "$ac_ct_OTOOL64" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OTOOL64" = x; then OTOOL64=":" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OTOOL64=$ac_ct_OTOOL64 fi else OTOOL64="$ac_cv_prog_OTOOL64" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 printf %s "checking for -single_module linker flag... " >&6; } if test ${lt_cv_apple_cc_single_mod+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_apple_cc_single_mod=no if test -z "$LT_MULTI_MODULE"; then # By default we will add the -single_module flag. You can override # by either setting the environment variable LT_MULTI_MODULE # non-empty at configure time, or by adding -multi_module to the # link flags. rm -rf libconftest.dylib* echo "int foo(void){return 1;}" > conftest.c echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c" >&5 $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err _lt_result=$? # If there is a non-empty error log, and "single_module" # appears in it, assume the flag caused a linker warning if test -s conftest.err && $GREP single_module conftest.err; then cat conftest.err >&5 # Otherwise, if the output was created with a 0 exit code from # the compiler, it worked. elif test -f libconftest.dylib && test 0 = "$_lt_result"; then lt_cv_apple_cc_single_mod=yes else cat conftest.err >&5 fi rm -rf libconftest.dylib* rm -f conftest.* fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 printf %s "checking for -exported_symbols_list linker flag... " >&6; } if test ${lt_cv_ld_exported_symbols_list+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_exported_symbols_list=no save_LDFLAGS=$LDFLAGS echo "_main" > conftest.sym LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_ld_exported_symbols_list=yes else $as_nop lt_cv_ld_exported_symbols_list=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 printf "%s\n" "$lt_cv_ld_exported_symbols_list" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5 printf %s "checking for -force_load linker flag... " >&6; } if test ${lt_cv_ld_force_load+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_ld_force_load=no cat > conftest.c << _LT_EOF int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5 $AR $AR_FLAGS libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF int main() { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err _lt_result=$? if test -s conftest.err && $GREP force_load conftest.err; then cat conftest.err >&5 elif test -f conftest && test 0 = "$_lt_result" && $GREP forced_load conftest >/dev/null 2>&1; then lt_cv_ld_force_load=yes else cat conftest.err >&5 fi rm -f conftest.err libconftest.a conftest conftest.c rm -rf conftest.dSYM fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5 printf "%s\n" "$lt_cv_ld_force_load" >&6; } case $host_os in rhapsody* | darwin1.[012]) _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; darwin*) case $MACOSX_DEPLOYMENT_TARGET,$host in 10.[012],*|,*powerpc*-darwin[5-8]*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; *) _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else _lt_dar_export_syms='~$NMEDIT -s $output_objdir/$libname-symbols.expsym $lib' fi if test : != "$DSYMUTIL" && test no = "$lt_cv_ld_force_load"; then _lt_dsymutil='~$DSYMUTIL $lib || :' else _lt_dsymutil= fi ;; esac # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } ac_header= ac_cache= for ac_item in $ac_header_c_list do if test $ac_cache; then ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default" if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then printf "%s\n" "#define $ac_item 1" >> confdefs.h fi ac_header= ac_cache= elif test $ac_header; then ac_cache=$ac_item else ac_header=$ac_item fi done if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes then : printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h fi ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default " if test "x$ac_cv_header_dlfcn_h" = xyes then : printf "%s\n" "#define HAVE_DLFCN_H 1" >>confdefs.h fi # Set options enable_win32_dll=yes case $host in *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args. set dummy ${ac_tool_prefix}as; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_AS+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$AS"; then ac_cv_prog_AS="$AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_AS="${ac_tool_prefix}as" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi AS=$ac_cv_prog_AS if test -n "$AS"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AS" >&5 printf "%s\n" "$AS" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_AS"; then ac_ct_AS=$AS # Extract the first word of "as", so it can be a program name with args. set dummy as; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_AS+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_AS"; then ac_cv_prog_ac_ct_AS="$ac_ct_AS" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_AS="as" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_AS=$ac_cv_prog_ac_ct_AS if test -n "$ac_ct_AS"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5 printf "%s\n" "$ac_ct_AS" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_AS" = x; then AS="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac AS=$ac_ct_AS fi else AS="$ac_cv_prog_AS" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args. set dummy ${ac_tool_prefix}dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DLLTOOL"; then ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DLLTOOL=$ac_cv_prog_DLLTOOL if test -n "$DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5 printf "%s\n" "$DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_DLLTOOL"; then ac_ct_DLLTOOL=$DLLTOOL # Extract the first word of "dlltool", so it can be a program name with args. set dummy dlltool; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_DLLTOOL+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_DLLTOOL"; then ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_DLLTOOL="dlltool" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL if test -n "$ac_ct_DLLTOOL"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5 printf "%s\n" "$ac_ct_DLLTOOL" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_DLLTOOL" = x; then DLLTOOL="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac DLLTOOL=$ac_ct_DLLTOOL fi else DLLTOOL="$ac_cv_prog_DLLTOOL" fi if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$OBJDUMP"; then ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi OBJDUMP=$ac_cv_prog_OBJDUMP if test -n "$OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 printf "%s\n" "$OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_prog_OBJDUMP"; then ac_ct_OBJDUMP=$OBJDUMP # Extract the first word of "objdump", so it can be a program name with args. set dummy objdump; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_OBJDUMP+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_OBJDUMP"; then ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_OBJDUMP="objdump" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP if test -n "$ac_ct_OBJDUMP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 printf "%s\n" "$ac_ct_OBJDUMP" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_ct_OBJDUMP" = x; then OBJDUMP="false" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac OBJDUMP=$ac_ct_OBJDUMP fi else OBJDUMP="$ac_cv_prog_OBJDUMP" fi ;; esac test -z "$AS" && AS=as test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$OBJDUMP" && OBJDUMP=objdump enable_dlopen=no # Check whether --enable-shared was given. if test ${enable_shared+y} then : enableval=$enable_shared; p=${PACKAGE-default} case $enableval in yes) enable_shared=yes ;; no) enable_shared=no ;; *) enable_shared=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_shared=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_shared=yes fi # Check whether --enable-static was given. if test ${enable_static+y} then : enableval=$enable_static; p=${PACKAGE-default} case $enableval in yes) enable_static=yes ;; no) enable_static=no ;; *) enable_static=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_static=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_static=yes fi # Check whether --with-pic was given. if test ${with_pic+y} then : withval=$with_pic; lt_p=${PACKAGE-default} case $withval in yes|no) pic_mode=$withval ;; *) pic_mode=default # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for lt_pkg in $withval; do IFS=$lt_save_ifs if test "X$lt_pkg" = "X$lt_p"; then pic_mode=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop pic_mode=default fi # Check whether --enable-fast-install was given. if test ${enable_fast_install+y} then : enableval=$enable_fast_install; p=${PACKAGE-default} case $enableval in yes) enable_fast_install=yes ;; no) enable_fast_install=no ;; *) enable_fast_install=no # Look at the argument we got. We use all the common list separators. lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, for pkg in $enableval; do IFS=$lt_save_ifs if test "X$pkg" = "X$p"; then enable_fast_install=yes fi done IFS=$lt_save_ifs ;; esac else $as_nop enable_fast_install=yes fi shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[5-9]*,yes) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 printf %s "checking which variant of shared library versioning to provide... " >&6; } # Check whether --with-aix-soname was given. if test ${with_aix_soname+y} then : withval=$with_aix_soname; case $withval in aix|svr4|both) ;; *) as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 ;; esac lt_cv_with_aix_soname=$with_aix_soname else $as_nop if test ${lt_cv_with_aix_soname+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_with_aix_soname=aix fi with_aix_soname=$lt_cv_with_aix_soname fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 printf "%s\n" "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member # based on the bitwidth used, traditionally 'shr.o' or 'shr_64.o', # and 'shr.imp' or 'shr_64.imp', respectively, for the Import File. # Even when GNU compilers ignore OBJECT_MODE but need '-maix64' flag, # the AIX toolchain works better with OBJECT_MODE set (default 32). if test 64 = "${OBJECT_MODE-32}"; then shared_archive_member_spec=shr_64 else shared_archive_member_spec=shr fi fi ;; *) with_aix_soname=aix ;; esac # This can be used to rebuild libtool when needed LIBTOOL_DEPS=$ltmain # Always use our own libtool. LIBTOOL='$(SHELL) $(top_builddir)/libtool' test -z "$LN_S" && LN_S="ln -s" if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 printf %s "checking for objdir... " >&6; } if test ${lt_cv_objdir+y} then : printf %s "(cached) " >&6 else $as_nop rm -f .libs 2>/dev/null mkdir .libs 2>/dev/null if test -d .libs; then lt_cv_objdir=.libs else # MS-DOS does not allow filenames that begin with a dot. lt_cv_objdir=_libs fi rmdir .libs 2>/dev/null fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 printf "%s\n" "$lt_cv_objdir" >&6; } objdir=$lt_cv_objdir printf "%s\n" "#define LT_OBJDIR \"$lt_cv_objdir/\"" >>confdefs.h case $host_os in aix3*) # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi ;; esac # Global variables: ofile=libtool can_build_shared=yes # All known linkers require a '.a' archive for static linking (except MSVC and # ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld old_CC=$CC old_CFLAGS=$CFLAGS # Set sane defaults for various variables test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$LD" && LD=ld test -z "$ac_objext" && ac_objext=o func_cc_basename $compiler cc_basename=$func_cc_basename_result # Only perform the check for file, if the check method requires it test -z "$MAGIC_CMD" && MAGIC_CMD=file case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 printf %s "checking for ${ac_tool_prefix}file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/${ac_tool_prefix}file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"${ac_tool_prefix}file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for file" >&5 printf %s "checking for file... " >&6; } if test ${lt_cv_path_MAGIC_CMD+y} then : printf %s "(cached) " >&6 else $as_nop case $MAGIC_CMD in [\\/*] | ?:[\\/]*) lt_cv_path_MAGIC_CMD=$MAGIC_CMD # Let the user override the test with a path. ;; *) lt_save_MAGIC_CMD=$MAGIC_CMD lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" for ac_dir in $ac_dummy; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/file"; then lt_cv_path_MAGIC_CMD=$ac_dir/"file" if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD=$lt_cv_path_MAGIC_CMD if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then : else cat <<_LT_EOF 1>&2 *** Warning: the command libtool uses to detect shared libraries, *** $file_magic_cmd, produces output that libtool cannot recognize. *** The result is that libtool may fail to recognize shared libraries *** as such. This will affect the creation of libtool libraries that *** depend on shared libraries, but programs linked with such libtool *** libraries will work regardless of this problem. Nevertheless, you *** may want to report the problem to your system manager and/or to *** bug-libtool@gnu.org _LT_EOF fi ;; esac fi break fi done IFS=$lt_save_ifs MAGIC_CMD=$lt_save_MAGIC_CMD ;; esac fi MAGIC_CMD=$lt_cv_path_MAGIC_CMD if test -n "$MAGIC_CMD"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 printf "%s\n" "$MAGIC_CMD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi else MAGIC_CMD=: fi fi fi ;; esac # Use C for the default configuration in the libtool script lt_save_CC=$CC ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Source file extension for C test sources. ac_ext=c # Object file extension for compiled C test sources. objext=o objext=$objext # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # Save the default compiler, since it gets overwritten when the other # tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. compiler_DEFAULT=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... if test -n "$compiler"; then lt_prog_compiler_no_builtin_flag= if test yes = "$GCC"; then case $cc_basename in nvcc*) lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;; *) lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 printf %s "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } if test ${lt_cv_prog_compiler_rtti_exceptions+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 printf "%s\n" "$lt_cv_prog_compiler_rtti_exceptions" >&6; } if test yes = "$lt_cv_prog_compiler_rtti_exceptions"; then lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" else : fi fi lt_prog_compiler_wl= lt_prog_compiler_pic= lt_prog_compiler_static= if test yes = "$GCC"; then lt_prog_compiler_wl='-Wl,' lt_prog_compiler_static='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' fi lt_prog_compiler_pic='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static= ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) # +Z the default ;; *) lt_prog_compiler_pic='-fPIC' ;; esac ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. lt_prog_compiler_can_build_shared=no enable_shared=no ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic=-Kconform_pic fi ;; *) lt_prog_compiler_pic='-fPIC' ;; esac case $cc_basename in nvcc*) # Cuda Compiler Driver 2.2 lt_prog_compiler_wl='-Xlinker ' if test -n "$lt_prog_compiler_pic"; then lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" fi ;; esac else # PORTME Check for flag to pass linker flags through the system compiler. case $host_os in aix*) lt_prog_compiler_wl='-Wl,' if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static='-Bstatic' else lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' fi ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic='-fno-common' case $cc_basename in nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; esac ;; mingw* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static='$wl-static' ;; esac ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic='+Z' ;; esac # Is there a better lt_prog_compiler_static that works with the bundled CC? lt_prog_compiler_static='$wl-a ${wl}archive' ;; irix5* | irix6* | nonstopux*) lt_prog_compiler_wl='-Wl,' # PIC (with -KPIC) is the default. lt_prog_compiler_static='-non_shared' ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in # old Intel for x86_64, which still supported -KPIC. ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; # flang / f18. f95 an alias for gfortran or flang on Debian flang* | f18* | f95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; # Lahey Fortran 8.1. lf95*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='--shared' lt_prog_compiler_static='--static' ;; nagfor*) # NAG Fortran compiler lt_prog_compiler_wl='-Wl,-Wl,,' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; tcc*) # Fabrice Bellard et al's Tiny C Compiler lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; xl* | bgxl* | bgf* | mpixl*) # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-qpic' lt_prog_compiler_static='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='' ;; *Sun\ F* | *Sun*Fortran*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Qoption ld ' ;; *Sun\ C*) # Sun C 5.9 lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' lt_prog_compiler_wl='-Wl,' ;; *Intel*\ [CF]*Compiler*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fPIC' lt_prog_compiler_static='-static' ;; *Portland\ Group*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' lt_prog_compiler_static='-Bstatic' ;; esac ;; esac ;; newsos6) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic='-fPIC -shared' ;; osf3* | osf4* | osf5*) lt_prog_compiler_wl='-Wl,' # All OSF/1 code is PIC. lt_prog_compiler_static='-non_shared' ;; rdos*) lt_prog_compiler_static='-non_shared' ;; solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' case $cc_basename in f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) lt_prog_compiler_wl='-Qoption ld ';; *) lt_prog_compiler_wl='-Wl,';; esac ;; sunos4*) lt_prog_compiler_wl='-Qoption ld ' lt_prog_compiler_pic='-PIC' lt_prog_compiler_static='-Bstatic' ;; sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic='-Kconform_pic' lt_prog_compiler_static='-Bstatic' fi ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' ;; unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no ;; uts4*) lt_prog_compiler_pic='-pic' lt_prog_compiler_static='-Bstatic' ;; *) lt_prog_compiler_can_build_shared=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= ;; *) lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic=$lt_prog_compiler_pic fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } lt_prog_compiler_pic=$lt_cv_prog_compiler_pic # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } if test ${lt_cv_prog_compiler_pic_works+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works"; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; esac else lt_prog_compiler_pic= lt_prog_compiler_can_build_shared=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_static_works=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works=yes fi else lt_cv_prog_compiler_static_works=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } if test yes = "$lt_cv_prog_compiler_static_works"; then : else lt_prog_compiler_static= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } runpath_var= allow_undefined_flag= always_export_symbols=no archive_cmds= archive_expsym_cmds= compiler_needs_object=no enable_shared_with_static_runtimes=no export_dynamic_flag_spec= export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' hardcode_automatic=no hardcode_direct=no hardcode_direct_absolute=no hardcode_libdir_flag_spec= hardcode_libdir_separator= hardcode_minus_L=no hardcode_shlibpath_var=unsupported inherit_rpath=no link_all_deplibs=unknown module_cmds= module_expsym_cmds= old_archive_from_new_cmds= old_archive_from_expsyms_cmds= thread_safe_flag_spec= whole_archive_flag_spec= # include_expsyms should be a list of space-separated symbols to be *always* # included in the symbol list include_expsyms= # exclude_expsyms can be an extended regexp of symbols to exclude # it will be wrapped by ' (' and ')$', so one must not match beginning or # end of line. Example: 'a|bc|.*d.*' will exclude the symbols 'a' and 'bc', # as well as any symbol that contains 'd'. exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= case $host_os in cygwin* | mingw* | pw32* | cegcc*) # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; openbsd* | bitrig*) with_gnu_ld=no ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs=no ;; esac ld_shlibs=yes # On some targets, GNU ld is compatible enough with the native linker # that we're better off using the native interface for both. lt_use_gnu_ld_interface=no if test yes = "$with_gnu_ld"; then case $host_os in aix*) # The AIX port of GNU ld has always aspired to compatibility # with the native linker. However, as the warning in the GNU ld # block says, versions before 2.19.5* couldn't really create working # shared libraries, regardless of the interface used. case `$LD -v 2>&1` in *\ \(GNU\ Binutils\)\ 2.19.5*) ;; *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;; *\ \(GNU\ Binutils\)\ [3-9]*) ;; *) lt_use_gnu_ld_interface=yes ;; esac ;; *) lt_use_gnu_ld_interface=yes ;; esac fi if test yes = "$lt_use_gnu_ld_interface"; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='$wl' # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='$wl--export-dynamic' # ancient GNU ld didn't support --whole-archive et. al. if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec= fi supports_anon_versioning=no case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac # See if GNU ld supports shared libraries. case $host_os in aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test ia64 != "$host_cpu"; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: the GNU linker, at least up to release 2.19, is reported *** to be unable to reliably create shared libraries on AIX. *** Therefore, libtool is disabling shared libraries support. If you *** really care for shared libraries, you may want to install binutils *** 2.20 or above, or modify your PATH so that a non-GNU linker is found. *** You will then need to restart the configuration process. _LT_EOF fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs=no fi ;; cygwin* | mingw* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' export_dynamic_flag_spec='$wl--export-all-symbols' allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs=yes ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; interix[3-9]*) hardcode_direct=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) tmp_diet=no if test linux-dietlibc = "$host_os"; then case $cc_basename in diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) esac fi if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ && test no = "$tmp_diet" then tmp_addflag=' $pic_flag' tmp_sharedflag='-shared' case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag' ;; pgf77* | pgf90* | pgf95* | pgfortran*) # Portland Group f77 and f90 compilers whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 tmp_addflag=' -i_dynamic -nofor_main' ;; ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; lf95*) # Lahey Fortran 8.1 whole_archive_flag_spec= tmp_sharedflag='--shared' ;; nagfor*) # NAGFOR 5.3 tmp_sharedflag='-Wl,-shared' ;; xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) tmp_sharedflag='-qmkshrobj' tmp_addflag= ;; nvcc*) # Cuda Compiler Driver 2.2 whole_archive_flag_spec='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes ;; esac case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes tmp_sharedflag='-G' ;; *Sun\ F*) # Sun Fortran 8.3 tmp_sharedflag='-G' ;; esac archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) # IBM XL Fortran 10.1 on PPC cannot create shared libs itself whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi ;; esac else ld_shlibs=no fi ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= else archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' fi ;; solaris*) if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: The releases 2.8.* of the GNU linker cannot reliably *** create shared libraries on Solaris systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.9.1 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) case `$LD -v 2>&1` in *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) ld_shlibs=no cat <<_LT_EOF 1>&2 *** Warning: Releases of the GNU linker prior to 2.16.91.0.3 cannot *** reliably create shared libraries on SCO systems. Therefore, libtool *** is disabling shared libraries support. We urge you to upgrade GNU *** binutils to release 2.16.91.0.3 or newer. Another option is to modify *** your PATH or compiler configuration so that the native linker is *** used, and then restart. _LT_EOF ;; *) # For security reasons, it is highly recommended that you always # use absolute paths for naming shared libraries, and exclude the # DT_RUNPATH tag from executables and libraries. But doing so # requires that you compile everything twice, which is a pain. if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac ;; sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= hardcode_direct=yes hardcode_shlibpath_var=no ;; *) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' else ld_shlibs=no fi ;; esac if test no = "$ld_shlibs"; then runpath_var= hardcode_libdir_flag_spec= export_dynamic_flag_spec= whole_archive_flag_spec= fi else # PORTME fill in a description of your system's linker (not GNU ld) case $host_os in aix3*) allow_undefined_flag=unsupported always_export_symbols=yes archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes if test yes = "$GCC" && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test x-brtl = "x$ld_flag" || test x-Wl,-brtl = "x$ld_flag"); then aix_use_runtimelinking=yes break fi done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds='' hardcode_direct=yes hardcode_direct_absolute=yes hardcode_libdir_separator=':' link_all_deplibs=yes file_list_spec='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # traditional, no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct=no hardcode_direct_absolute=no ;; esac if test yes = "$GCC"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L=yes hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi ;; esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag="$shared_flag "'$wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to export. always_export_symbols=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. allow_undefined_flag='-berok' # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath_+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath_"; then lt_cv_aix_libpath_=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath_ fi hardcode_libdir_flag_spec='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag=' $wl-bernotok' allow_undefined_flag=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec='$convenience' fi archive_cmds_need_lc=yes archive_expsym_cmds='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared libraries. archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds="$archive_expsym_cmds"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds="$archive_expsym_cmds"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds="$archive_expsym_cmds"'~$RM -r $output_objdir/$realname.d' fi fi ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds='' ;; m68k) archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes ;; esac ;; bsdi[45]*) export_dynamic_flag_spec=-rdynamic ;; cygwin* | mingw* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in cl* | icl*) # Native MSVC or ICC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes file_list_spec='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' enable_shared_with_static_runtimes=yes exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' # Don't use ranlib old_postinstall_cmds='chmod 644 $oldlib' postlink_cmds='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # Assume MSVC and ICC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames=' # The linker will automatically build a .lib file if we build a DLL. old_archive_from_new_cmds='true' # FIXME: Should let the user specify the lib program. old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' enable_shared_with_static_runtimes=yes ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc=no hardcode_direct=no hardcode_automatic=yes hardcode_shlibpath_var=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec='' fi link_all_deplibs=yes allow_undefined_flag=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no fi ;; dgux*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor # support. Future versions do this automatically, but an explicit c++rt0.o # does not break anything, and helps significantly (at the cost of a little # extra space). freebsd2.2*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; # Unfortunately, older versions of FreeBSD 2 do not have this feature. freebsd2.*) archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. freebsd* | dragonfly* | midnightbsd*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; hpux9*) if test yes = "$GCC"; then archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes export_dynamic_flag_spec='$wl-E' ;; hpux10*) if test yes,no = "$GCC,$with_gnu_ld"; then archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes fi ;; hpux11*) if test yes,no = "$GCC,$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds='$CC -shared $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds='$CC -shared $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else case $host_cpu in hppa*64*) archive_cmds='$CC -b $wl+h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' ;; ia64*) archive_cmds='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) # Older versions of the 11.00 compiler do not understand -b yet # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5 printf %s "checking if $CC understands -b... " >&6; } if test ${lt_cv_prog_compiler__b+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler__b=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -b" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler__b=yes fi else lt_cv_prog_compiler__b=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5 printf "%s\n" "$lt_cv_prog_compiler__b" >&6; } if test yes = "$lt_cv_prog_compiler__b"; then archive_cmds='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' fi ;; esac fi if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: case $host_cpu in hppa*64*|ia64*) hardcode_direct=no hardcode_shlibpath_var=no ;; *) hardcode_direct=yes hardcode_direct_absolute=yes export_dynamic_flag_spec='$wl-E' # hardcode_minus_L: Not really in the search PATH, # but as the default location of the library. hardcode_minus_L=yes ;; esac fi ;; irix5* | irix6* | nonstopux*) if test yes = "$GCC"; then archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' # Try to use the -exported_symbol ld option, if it does not # work, assume that -exports_file does not work either and # implicitly export all symbols. # This should be the same for all languages, so no per-tag cache variable. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5 printf %s "checking whether the $host_os linker accepts -exported_symbol... " >&6; } if test ${lt_cv_irix_exported_symbol+y} then : printf %s "(cached) " >&6 else $as_nop save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -shared $wl-exported_symbol ${wl}foo $wl-update_registry $wl/dev/null" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int foo (void) { return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : lt_cv_irix_exported_symbol=yes else $as_nop lt_cv_irix_exported_symbol=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5 printf "%s\n" "$lt_cv_irix_exported_symbol" >&6; } if test yes = "$lt_cv_irix_exported_symbol"; then archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations $wl-exports_file $wl$export_symbols -o $lib' fi link_all_deplibs=no else archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -exports_file $export_symbols -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: inherit_rpath=yes link_all_deplibs=yes ;; linux*) case $cc_basename in tcc*) # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' ;; esac ;; netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF fi hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes hardcode_shlibpath_var=no ;; newsos6) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: hardcode_shlibpath_var=no ;; *nto* | *qnx*) ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no hardcode_direct_absolute=yes if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags $wl-retain-symbols-file,$export_symbols' hardcode_libdir_flag_spec='$wl-rpath,$libdir' export_dynamic_flag_spec='$wl-E' else archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='$wl-rpath,$libdir' fi else ld_shlibs=no fi ;; os2*) hardcode_libdir_flag_spec='-L$libdir' hardcode_minus_L=yes allow_undefined_flag=unsupported shrext_cmds=.dll archive_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes file_list_spec='@' ;; osf3*) if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' fi archive_cmds_need_lc='no' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' hardcode_libdir_separator=: ;; osf4* | osf5*) # as osf3* with the addition of -msym flag if test yes = "$GCC"; then allow_undefined_flag=' $wl-expect_unresolved $wl\*' archive_cmds='$CC -shared$allow_undefined_flag $pic_flag $libobjs $deplibs $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' else allow_undefined_flag=' -expect_unresolved \*' archive_cmds='$CC -shared$allow_undefined_flag $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $wl-input $wl$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~$RM $lib.exp' # Both c and cxx compiler support -rpath directly hardcode_libdir_flag_spec='-rpath $libdir' fi archive_cmds_need_lc='no' hardcode_libdir_separator=: ;; solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then wlarc='$wl' archive_cmds='$CC -shared $pic_flag $wl-z ${wl}text $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag $wl-z ${wl}text $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' else case `$CC -V 2>&1` in *"Compilers 5.0"*) wlarc='' archive_cmds='$LD -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $linker_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $LD -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' ;; *) wlarc='$wl' archive_cmds='$CC -G$allow_undefined_flag -h $soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' ;; esac fi hardcode_libdir_flag_spec='-R$libdir' hardcode_shlibpath_var=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. GCC discards it without '$wl', # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) if test yes = "$GCC"; then whole_archive_flag_spec='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' else whole_archive_flag_spec='-z allextract$convenience -z defaultextract' fi ;; esac link_all_deplibs=yes ;; sunos4*) if test sequent = "$host_vendor"; then # Use $CC to link under sequent, because it throws in some extra .o # files that make .init and .fini sections work. archive_cmds='$CC -G $wl-h $soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' fi hardcode_libdir_flag_spec='-L$libdir' hardcode_direct=yes hardcode_minus_L=yes hardcode_shlibpath_var=no ;; sysv4) case $host_vendor in sni) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=yes # is this really true??? ;; siemens) ## LD is ld it makes a PLAMLIB ## CC just makes a GrossModule. archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' reload_cmds='$CC -r -o $output$reload_objs' hardcode_direct=no ;; motorola) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_direct=no #Motorola manual says yes, but my tests say they lie ;; esac runpath_var='LD_RUN_PATH' hardcode_shlibpath_var=no ;; sysv4.3*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no export_dynamic_flag_spec='-Bexport' ;; sysv4*MP*) if test -d /usr/nec; then archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_shlibpath_var=no runpath_var=LD_RUN_PATH hardcode_runpath_var=yes ld_shlibs=yes fi ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag='$wl-z,text' archive_cmds_need_lc=no hardcode_shlibpath_var=no runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag='$wl-z,text' allow_undefined_flag='$wl-z,nodefs' archive_cmds_need_lc=no hardcode_shlibpath_var=no hardcode_libdir_flag_spec='$wl-R,$libdir' hardcode_libdir_separator=':' link_all_deplibs=yes export_dynamic_flag_spec='$wl-Bexport' runpath_var='LD_RUN_PATH' if test yes = "$GCC"; then archive_cmds='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else archive_cmds='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi ;; uts4*) archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' hardcode_libdir_flag_spec='-L$libdir' hardcode_shlibpath_var=no ;; *) ld_shlibs=no ;; esac if test sni = "$host_vendor"; then case $host in sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) export_dynamic_flag_spec='$wl-Blargedynsym' ;; esac fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 printf "%s\n" "$ld_shlibs" >&6; } test no = "$ld_shlibs" && can_build_shared=no with_gnu_ld=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc" in x|xyes) # Assume -lc should be added archive_cmds_need_lc=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc+y} then : printf %s "(cached) " >&6 else $as_nop $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc=no else lt_cv_archive_cmds_need_lc=yes fi allow_undefined_flag=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc" >&6; } archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "checking dynamic linker characteristics... " >&6; } if test yes = "$GCC"; then case $host_os in darwin*) lt_awk_arg='/^libraries:/,/LR/' ;; *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` case $lt_search_path_spec in *\;*) # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'` ;; *) lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"` ;; esac # Ok, now we have the path, separated by spaces, we can step through it # and add multilib dir if necessary... lt_tmp_lt_search_path_spec= lt_multi_os_dir=/`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` # ...but if some path component already ends with the multilib dir we assume # that all is fine and trust -print-search-dirs as is (GCC 4.2? or newer). case "$lt_multi_os_dir; $lt_search_path_spec " in "/; "* | "/.; "* | "/./; "* | *"$lt_multi_os_dir "* | *"$lt_multi_os_dir/ "*) lt_multi_os_dir= ;; esac for lt_sys_path in $lt_search_path_spec; do if test -d "$lt_sys_path$lt_multi_os_dir"; then lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path$lt_multi_os_dir" elif test -n "$lt_multi_os_dir"; then test -d "$lt_sys_path" && \ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" fi done lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk ' BEGIN {RS = " "; FS = "/|\n";} { lt_foo = ""; lt_count = 0; for (lt_i = NF; lt_i > 0; lt_i--) { if ($lt_i != "" && $lt_i != ".") { if ($lt_i == "..") { lt_count++; } else { if (lt_count == 0) { lt_foo = "/" $lt_i lt_foo; } else { lt_count--; } } } } if (lt_foo != "") { lt_freq[lt_foo]++; } if (lt_freq[lt_foo] == 1) { print lt_foo; } }'` # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "checking how to hardcode library paths into programs... " >&6; } hardcode_action= if test -n "$hardcode_libdir_flag_spec" || test -n "$runpath_var" || test yes = "$hardcode_automatic"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, )" && test no != "$hardcode_minus_L"; then # Linking always hardcodes the temporary library directory. hardcode_action=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action=unsupported fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 printf "%s\n" "$hardcode_action" >&6; } if test relink = "$hardcode_action" || test yes = "$inherit_rpath"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi if test yes != "$enable_dlopen"; then enable_dlopen=unknown enable_dlopen_self=unknown enable_dlopen_self_static=unknown else lt_cv_dlopen=no lt_cv_dlopen_libs= case $host_os in beos*) lt_cv_dlopen=load_add_on lt_cv_dlopen_libs= lt_cv_dlopen_self=yes ;; mingw* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; cygwin*) lt_cv_dlopen=dlopen lt_cv_dlopen_libs= ;; darwin*) # if libdl is installed we need to link against it { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else $as_nop lt_cv_dlopen=dyld lt_cv_dlopen_libs= lt_cv_dlopen_self=yes fi ;; tpf*) # Don't try to run any link tests for TPF. We know it's impossible # because TPF is a cross-compiler, and we know how we open DSOs. lt_cv_dlopen=dlopen lt_cv_dlopen_libs= lt_cv_dlopen_self=no ;; *) ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" if test "x$ac_cv_func_shl_load" = xyes then : lt_cv_dlopen=shl_load else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 printf %s "checking for shl_load in -ldld... " >&6; } if test ${ac_cv_lib_dld_shl_load+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char shl_load (); int main (void) { return shl_load (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_shl_load=yes else $as_nop ac_cv_lib_dld_shl_load=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; } if test "x$ac_cv_lib_dld_shl_load" = xyes then : lt_cv_dlopen=shl_load lt_cv_dlopen_libs=-ldld else $as_nop ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" if test "x$ac_cv_func_dlopen" = xyes then : lt_cv_dlopen=dlopen else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 printf %s "checking for dlopen in -ldl... " >&6; } if test ${ac_cv_lib_dl_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldl $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dl_dlopen=yes else $as_nop ac_cv_lib_dl_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; } if test "x$ac_cv_lib_dl_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-ldl else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 printf %s "checking for dlopen in -lsvld... " >&6; } if test ${ac_cv_lib_svld_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-lsvld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dlopen (); int main (void) { return dlopen (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_svld_dlopen=yes else $as_nop ac_cv_lib_svld_dlopen=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 printf "%s\n" "$ac_cv_lib_svld_dlopen" >&6; } if test "x$ac_cv_lib_svld_dlopen" = xyes then : lt_cv_dlopen=dlopen lt_cv_dlopen_libs=-lsvld else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 printf %s "checking for dld_link in -ldld... " >&6; } if test ${ac_cv_lib_dld_dld_link+y} then : printf %s "(cached) " >&6 else $as_nop ac_check_lib_save_LIBS=$LIBS LIBS="-ldld $LIBS" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char dld_link (); int main (void) { return dld_link (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_cv_lib_dld_dld_link=yes else $as_nop ac_cv_lib_dld_dld_link=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 printf "%s\n" "$ac_cv_lib_dld_dld_link" >&6; } if test "x$ac_cv_lib_dld_dld_link" = xyes then : lt_cv_dlopen=dld_link lt_cv_dlopen_libs=-ldld fi fi fi fi fi fi ;; esac if test no = "$lt_cv_dlopen"; then enable_dlopen=no else enable_dlopen=yes fi case $lt_cv_dlopen in dlopen) save_CPPFLAGS=$CPPFLAGS test yes = "$ac_cv_header_dlfcn_h" && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS=$LDFLAGS wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS=$LIBS LIBS="$lt_cv_dlopen_libs $LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 printf %s "checking whether a program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self+y} then : printf %s "(cached) " >&6 else $as_nop if test yes = "$cross_compiling"; then : lt_cv_dlopen_self=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed lt_cv_dlopen_self=no fi fi rm -fr conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 printf "%s\n" "$lt_cv_dlopen_self" >&6; } if test yes = "$lt_cv_dlopen_self"; then wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 printf %s "checking whether a statically linked program can dlopen itself... " >&6; } if test ${lt_cv_dlopen_self_static+y} then : printf %s "(cached) " >&6 else $as_nop if test yes = "$cross_compiling"; then : lt_cv_dlopen_self_static=cross else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF #line $LINENO "configure" #include "confdefs.h" #if HAVE_DLFCN_H #include #endif #include #ifdef RTLD_GLOBAL # define LT_DLGLOBAL RTLD_GLOBAL #else # ifdef DL_GLOBAL # define LT_DLGLOBAL DL_GLOBAL # else # define LT_DLGLOBAL 0 # endif #endif /* We may have to define LT_DLLAZY_OR_NOW in the command line if we find out it does not work in some platform. */ #ifndef LT_DLLAZY_OR_NOW # ifdef RTLD_LAZY # define LT_DLLAZY_OR_NOW RTLD_LAZY # else # ifdef DL_LAZY # define LT_DLLAZY_OR_NOW DL_LAZY # else # ifdef RTLD_NOW # define LT_DLLAZY_OR_NOW RTLD_NOW # else # ifdef DL_NOW # define LT_DLLAZY_OR_NOW DL_NOW # else # define LT_DLLAZY_OR_NOW 0 # endif # endif # endif # endif #endif /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) int fnord () __attribute__((visibility("default"))); #endif int fnord () { return 42; } int main () { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; if (self) { if (dlsym (self,"fnord")) status = $lt_dlno_uscore; else { if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; else puts (dlerror ()); } /* dlclose (self); */ } else puts (dlerror ()); return status; } _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 (eval $ac_link) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } && test -s "conftest$ac_exeext" 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed lt_cv_dlopen_self_static=no fi fi rm -fr conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 printf "%s\n" "$lt_cv_dlopen_self_static" >&6; } fi CPPFLAGS=$save_CPPFLAGS LDFLAGS=$save_LDFLAGS LIBS=$save_LIBS ;; esac case $lt_cv_dlopen_self in yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; *) enable_dlopen_self=unknown ;; esac case $lt_cv_dlopen_self_static in yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; *) enable_dlopen_self_static=unknown ;; esac fi striplib= old_striplib= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 printf %s "checking whether stripping libraries is possible... " >&6; } if test -z "$STRIP"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } else if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else case $host_os in darwin*) # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } ;; freebsd*) if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then old_striplib="$STRIP --strip-debug" striplib="$STRIP --strip-unneeded" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } ;; esac fi fi # Report what library types will actually be built { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 printf %s "checking if libtool supports shared libraries... " >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 printf "%s\n" "$can_build_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 printf %s "checking whether to build shared libraries... " >&6; } test no = "$can_build_shared" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. case $host_os in aix3*) test yes = "$enable_shared" && enable_static=no if test -n "$RANLIB"; then archive_cmds="$archive_cmds~\$RANLIB \$lib" postinstall_cmds='$RANLIB $lib' fi ;; aix[4-9]*) if test ia64 != "$host_cpu"; then case $enable_shared,$with_aix_soname,$aix_use_runtimelinking in yes,aix,yes) ;; # shared object as lib.so file only yes,svr4,*) ;; # shared object as lib.so archive member only yes,*) enable_static=no ;; # shared object in lib.a archive as well esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 printf "%s\n" "$enable_shared" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 printf %s "checking whether to build static libraries... " >&6; } # Make sure either enable_shared or enable_static is yes. test yes = "$enable_shared" || enable_static=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 printf "%s\n" "$enable_static" >&6; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu CC=$lt_save_CC ac_config_commands="$ac_config_commands libtool" # Only expand once: ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test -z "$CXX"; then if test -n "$CCC"; then CXX=$CCC else if test -n "$ac_tool_prefix"; then for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$CXX"; then ac_cv_prog_CXX="$CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CXX=$ac_cv_prog_CXX if test -n "$CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5 printf "%s\n" "$CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$CXX" && break done fi if test -z "$CXX"; then ac_ct_CXX=$CXX for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ac_ct_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ac_ct_CXX"; then ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ac_ct_CXX="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CXX=$ac_cv_prog_ac_ct_CXX if test -n "$ac_ct_CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5 printf "%s\n" "$ac_ct_CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$ac_ct_CXX" && break done if test "x$ac_ct_CXX" = x; then CXX="g++" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CXX=$ac_ct_CXX fi fi fi fi # Provide some information about the compiler. printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5 set X $ac_compile ac_compiler=$2 for ac_option in --version -v -V -qversion; do { { ac_try="$ac_compiler $ac_option >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" printf "%s\n" "$ac_try_echo"; } >&5 (eval "$ac_compiler $ac_option >&5") 2>conftest.err ac_status=$? if test -s conftest.err; then sed '10a\ ... rest of stderr output deleted ... 10q' conftest.err >conftest.er1 cat conftest.er1 >&5 fi rm -f conftest.er1 conftest.err printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5 printf %s "checking whether the compiler supports GNU C++... " >&6; } if test ${ac_cv_cxx_compiler_gnu+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_compiler_gnu=yes else $as_nop ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cv_cxx_compiler_gnu=$ac_compiler_gnu fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5 printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; } ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test $ac_compiler_gnu = yes; then GXX=yes else GXX= fi ac_test_CXXFLAGS=${CXXFLAGS+y} ac_save_CXXFLAGS=$CXXFLAGS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5 printf %s "checking whether $CXX accepts -g... " >&6; } if test ${ac_cv_prog_cxx_g+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_cxx_werror_flag=$ac_cxx_werror_flag ac_cxx_werror_flag=yes ac_cv_prog_cxx_g=no CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes else $as_nop CXXFLAGS="" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : else $as_nop ac_cxx_werror_flag=$ac_save_cxx_werror_flag CXXFLAGS="-g" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_g=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext ac_cxx_werror_flag=$ac_save_cxx_werror_flag fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5 printf "%s\n" "$ac_cv_prog_cxx_g" >&6; } if test $ac_test_CXXFLAGS; then CXXFLAGS=$ac_save_CXXFLAGS elif test $ac_cv_prog_cxx_g = yes; then if test "$GXX" = yes; then CXXFLAGS="-g -O2" else CXXFLAGS="-g" fi else if test "$GXX" = yes; then CXXFLAGS="-O2" else CXXFLAGS= fi fi ac_prog_cxx_stdcxx=no if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5 printf %s "checking for $CXX option to enable C++11 features... " >&6; } if test ${ac_cv_prog_cxx_cxx11+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx11=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx11_program _ACEOF for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx11=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx11" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx11" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx11" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx11" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11 ac_prog_cxx_stdcxx=cxx11 fi fi if test x$ac_prog_cxx_stdcxx = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5 printf %s "checking for $CXX option to enable C++98 features... " >&6; } if test ${ac_cv_prog_cxx_cxx98+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_prog_cxx_cxx98=no ac_save_CXX=$CXX cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_cxx_conftest_cxx98_program _ACEOF for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA do CXX="$ac_save_CXX $ac_arg" if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_prog_cxx_cxx98=$ac_arg fi rm -f core conftest.err conftest.$ac_objext conftest.beam test "x$ac_cv_prog_cxx_cxx98" != "xno" && break done rm -f conftest.$ac_ext CXX=$ac_save_CXX fi if test "x$ac_cv_prog_cxx_cxx98" = xno then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 printf "%s\n" "unsupported" >&6; } else $as_nop if test "x$ac_cv_prog_cxx_cxx98" = x then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 printf "%s\n" "none needed" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5 printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; } CXX="$CXX $ac_cv_prog_cxx_cxx98" fi ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98 ac_prog_cxx_stdcxx=cxx98 fi fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu depcc="$CXX" am_compiler_list= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5 printf %s "checking dependency style of $depcc... " >&6; } if test ${am_cv_CXX_dependencies_compiler_type+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_CXX_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` fi am__universal=false case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_CXX_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_CXX_dependencies_compiler_type=none fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5 printf "%s\n" "$am_cv_CXX_dependencies_compiler_type" >&6; } CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type if test "x$enable_dependency_tracking" != xno \ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then am__fastdepCXX_TRUE= am__fastdepCXX_FALSE='#' else am__fastdepCXX_TRUE='#' am__fastdepCXX_FALSE= fi func_stripname_cnf () { case $2 in .*) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%\\\\$2\$%%"`;; *) func_stripname_result=`$ECHO "$3" | $SED "s%^$1%%; s%$2\$%%"`;; esac } # func_stripname_cnf if test -n "$CXX" && ( test no != "$CXX" && ( (test g++ = "$CXX" && `g++ -v >/dev/null 2>&1` ) || (test g++ != "$CXX"))); then ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C++ preprocessor" >&5 printf %s "checking how to run the C++ preprocessor... " >&6; } if test -z "$CXXCPP"; then if test ${ac_cv_prog_CXXCPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CXX needs to be expanded for CXXCPP in "$CXX -E" cpp /lib/cpp do ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : break fi done ac_cv_prog_CXXCPP=$CXXCPP fi CXXCPP=$ac_cv_prog_CXXCPP else ac_cv_prog_CXXCPP=$CXXCPP fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5 printf "%s\n" "$CXXCPP" >&6; } ac_preproc_ok=false for ac_cxx_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_cxx_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu else _lt_caught_CXX_error=yes fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu archive_cmds_need_lc_CXX=no allow_undefined_flag_CXX= always_export_symbols_CXX=no archive_expsym_cmds_CXX= compiler_needs_object_CXX=no export_dynamic_flag_spec_CXX= hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no hardcode_libdir_flag_spec_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no inherit_rpath_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= link_all_deplibs_CXX=unknown old_archive_cmds_CXX=$old_archive_cmds reload_flag_CXX=$reload_flag reload_cmds_CXX=$reload_cmds no_undefined_flag_CXX= whole_archive_flag_spec_CXX= enable_shared_with_static_runtimes_CXX=no # Source file extension for C++ test sources. ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # No sense in running all these tests if we already determined that # the CXX compiler isn't working. Some variables (like enable_shared) # are currently assumed to apply to all compilers on this platform, # and will be corrupted by setting them based on a non-working compiler. if test yes != "$_lt_caught_CXX_error"; then # Code to be used in simple compile tests lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} # If no C compiler flags were specified, use CFLAGS. LTCFLAGS=${LTCFLAGS-"$CFLAGS"} # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" >conftest.$ac_ext eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $RM conftest* ac_outfile=conftest.$ac_objext echo "$lt_simple_link_test_code" >conftest.$ac_ext eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` $RM -r conftest* # Allow CC to be a program name with arguments. lt_save_CC=$CC lt_save_CFLAGS=$CFLAGS lt_save_LD=$LD lt_save_GCC=$GCC GCC=$GXX lt_save_with_gnu_ld=$with_gnu_ld lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} CFLAGS=$CXXFLAGS compiler=$CC compiler_CXX=$CC func_cc_basename $compiler cc_basename=$func_cc_basename_result if test -n "$compiler"; then # We don't want -fno-exception when compiling C++ code, so set the # no_builtin_flag separately if test yes = "$GXX"; then lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin' else lt_prog_compiler_no_builtin_flag_CXX= fi if test yes = "$GXX"; then # Set up default GNU C++ configuration # Check whether --with-gnu-ld was given. if test ${with_gnu_ld+y} then : withval=$with_gnu_ld; test no = "$withval" || with_gnu_ld=yes else $as_nop with_gnu_ld=no fi ac_prog=ld if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "checking for ld used by $CC... " >&6; } case $host in *-*-mingw*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; esac case $ac_prog in # Accept absolute paths. [\\/]* | ?:[\\/]*) re_direlt='/[^/][^/]*/\.\./' # Canonicalize the pathname of ld ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` done test -z "$LD" && LD=$ac_prog ;; "") # If it fails, then pretend we aren't using GCC. ac_prog=ld ;; *) # If it is relative, then search for the first ld in PATH. with_gnu_ld=unknown ;; esac elif test yes = "$with_gnu_ld"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 printf %s "checking for GNU ld... " >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 printf %s "checking for non-GNU ld... " >&6; } fi if test ${lt_cv_path_LD+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$LD"; then lt_save_ifs=$IFS; IFS=$PATH_SEPARATOR for ac_dir in $PATH; do IFS=$lt_save_ifs test -z "$ac_dir" && ac_dir=. if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD=$ac_dir/$ac_prog # Check to see if the program is GNU ld. I'd rather use --version, # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &5 printf "%s\n" "$LD" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 printf %s "checking if the linker ($LD) is GNU ld... " >&6; } if test ${lt_cv_prog_gnu_ld+y} then : printf %s "(cached) " >&6 else $as_nop # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &5 printf "%s\n" "$lt_cv_prog_gnu_ld" >&6; } with_gnu_ld=$lt_cv_prog_gnu_ld # Check if GNU C++ uses GNU ld as the underlying linker, since the # archiving commands below assume that GNU ld is being used. if test yes = "$with_gnu_ld"; then archive_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # If archive_cmds runs LD, not CC, wlarc should be empty # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to # investigate it a little bit more. (MM) wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. if eval "`$CC -print-prog-name=ld` --help 2>&1" | $GREP 'no-whole-archive' > /dev/null; then whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else whole_archive_flag_spec_CXX= fi else with_gnu_ld=no wlarc= # A generic and very simple default shared library creation # command for GNU C++ for the case where it uses the native # linker, instead of GNU ld. If possible, this setting should # overridden to take advantage of the native linker features on # the platform it is being used on. archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no with_gnu_ld=no wlarc= fi # PORTME: fill in a description of your system's C++ link characteristics { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } ld_shlibs_CXX=yes case $host_os in aix3*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aix[4-9]*) if test ia64 = "$host_cpu"; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. aix_use_runtimelinking=no exp_sym_flag='-Bexport' no_entry_flag= else aix_use_runtimelinking=no # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # have runtime linking enabled, and use it for executables. # For shared libraries, we enable/disable runtime linking # depending on the kind of the shared library created - # when "with_aix_soname,aix_use_runtimelinking" is: # "aix,no" lib.a(lib.so.V) shared, rtl:no, for executables # "aix,yes" lib.so shared, rtl:yes, for executables # lib.a static archive # "both,no" lib.so.V(shr.o) shared, rtl:yes # lib.a(lib.so.V) shared, rtl:no, for executables # "both,yes" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a(lib.so.V) shared, rtl:no # "svr4,*" lib.so.V(shr.o) shared, rtl:yes, for executables # lib.a static archive case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) aix_use_runtimelinking=yes break ;; esac done if test svr4,no = "$with_aix_soname,$aix_use_runtimelinking"; then # With aix-soname=svr4, we create the lib.so.V shared archives only, # so we don't have lib.a shared libs to link our executables. # We have to force runtime linking in this case. aix_use_runtimelinking=yes LDFLAGS="$LDFLAGS -Wl,-brtl" fi ;; esac exp_sym_flag='-bexport' no_entry_flag='-bnoentry' fi # When large executables or shared objects are built, AIX ld can # have problems creating the table of contents. If linking a library # or program results in "error TOC overflow" add -mminimal-toc to # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. archive_cmds_CXX='' hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes file_list_spec_CXX='$wl-f,' case $with_aix_soname,$aix_use_runtimelinking in aix,*) ;; # no import file svr4,* | *,yes) # use import file # The Import File defines what to hardcode. hardcode_direct_CXX=no hardcode_direct_absolute_CXX=no ;; esac if test yes = "$GXX"; then case $host_os in aix4.[012]|aix4.[012].*) # We only want to do this on AIX 4.2 and lower, the check # below for broken collect2 doesn't work under 4.3+ collect2name=`$CC -print-prog-name=collect2` if test -f "$collect2name" && strings "$collect2name" | $GREP resolve_lib_name >/dev/null then # We have reworked collect2 : else # We have old collect2 hardcode_direct_CXX=unsupported # It fails to find uninstalled libraries when the uninstalled # path is not listed in the libpath. Setting hardcode_minus_L # to unsupported forces relinking hardcode_minus_L_CXX=yes hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi esac shared_flag='-shared' if test yes = "$aix_use_runtimelinking"; then shared_flag=$shared_flag' $wl-G' fi # Need to ensure runtime linking is disabled for the traditional # shared library, or the linker may eventually find shared libraries # /with/ Import File - we do not want to mix them. shared_flag_aix='-shared' shared_flag_svr4='-shared $wl-G' else # not using gcc if test ia64 = "$host_cpu"; then # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else if test yes = "$aix_use_runtimelinking"; then shared_flag='$wl-G' else shared_flag='$wl-bM:SRE' fi shared_flag_aix='$wl-bM:SRE' shared_flag_svr4='$wl-G' fi fi export_dynamic_flag_spec_CXX='$wl-bexpall' # It seems that -bexpall does not export symbols beginning with # underscore (_), so it is better to generate a list of symbols to # export. always_export_symbols_CXX=yes if test aix,yes = "$with_aix_soname,$aix_use_runtimelinking"; then # Warning - without using the other runtime loading flags (-brtl), # -berok will link without error, but may produce a broken library. # The "-G" linker flag allows undefined symbols. no_undefined_flag_CXX='-bernotok' # Determine the default libpath from the value encoded in an empty # executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath__CXX+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs $wl'$no_entry_flag' $compiler_flags `if test -n "$allow_undefined_flag"; then func_echo_all "$wl$allow_undefined_flag"; else :; fi` $wl'$exp_sym_flag:\$export_symbols' '$shared_flag else if test ia64 = "$host_cpu"; then hardcode_libdir_flag_spec_CXX='$wl-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\$wl$no_entry_flag"' $compiler_flags $wl$allow_undefined_flag '"\$wl$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an # empty executable. if test set = "${lt_cv_aix_libpath+set}"; then aix_libpath=$lt_cv_aix_libpath else if test ${lt_cv_aix_libpath__CXX+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : lt_aix_libpath_sed=' /Import File Strings/,/^$/ { /^0/ { s/^0 *\([^ ]*\) *$/\1/ p } }' lt_cv_aix_libpath__CXX=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext if test -z "$lt_cv_aix_libpath__CXX"; then lt_cv_aix_libpath__CXX=/usr/lib:/lib fi fi aix_libpath=$lt_cv_aix_libpath__CXX fi hardcode_libdir_flag_spec_CXX='$wl-blibpath:$libdir:'"$aix_libpath" # Warning - without using the other run time loading flags, # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' $wl-bernotok' allow_undefined_flag_CXX=' $wl-berok' if test yes = "$with_gnu_ld"; then # We only use this code for GNU lds that support --whole-archive. whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' else # Exported symbols can be pulled into shared objects from archives whole_archive_flag_spec_CXX='$convenience' fi archive_cmds_need_lc_CXX=yes archive_expsym_cmds_CXX='$RM -r $output_objdir/$realname.d~$MKDIR $output_objdir/$realname.d' # -brtl affects multiple linker settings, -berok does not and is overridden later compiler_flags_filtered='`func_echo_all "$compiler_flags " | $SED -e "s%-brtl\\([, ]\\)%-berok\\1%g"`' if test svr4 != "$with_aix_soname"; then # This is similar to how AIX traditionally builds its shared # libraries. Need -bnortl late, we may have -brtl in LDFLAGS. archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_aix' -o $output_objdir/$realname.d/$soname $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$realname.d/$soname' fi if test aix != "$with_aix_soname"; then archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$CC '$shared_flag_svr4' -o $output_objdir/$realname.d/$shared_archive_member_spec.o $libobjs $deplibs $wl-bnoentry '$compiler_flags_filtered'$wl-bE:$export_symbols$allow_undefined_flag~$STRIP -e $output_objdir/$realname.d/$shared_archive_member_spec.o~( func_echo_all "#! $soname($shared_archive_member_spec.o)"; if test shr_64 = "$shared_archive_member_spec"; then func_echo_all "# 64"; else func_echo_all "# 32"; fi; cat $export_symbols ) > $output_objdir/$realname.d/$shared_archive_member_spec.imp~$AR $AR_FLAGS $output_objdir/$soname $output_objdir/$realname.d/$shared_archive_member_spec.o $output_objdir/$realname.d/$shared_archive_member_spec.imp' else # used by -dlpreopen to get the symbols archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$MV $output_objdir/$realname.d/$soname $output_objdir' fi archive_expsym_cmds_CXX="$archive_expsym_cmds_CXX"'~$RM -r $output_objdir/$realname.d' fi fi ;; beos*) if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then allow_undefined_flag_CXX=unsupported # Joseph Beckenbach says some releases of gcc # support --undefined. This deserves some investigation. FIXME archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' else ld_shlibs_CXX=no fi ;; chorus*) case $cc_basename in *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; cygwin* | mingw* | pw32* | cegcc*) case $GXX,$cc_basename in ,cl* | no,cl* | ,icl* | no,icl*) # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. hardcode_libdir_flag_spec_CXX=' ' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=yes file_list_spec_CXX='@' # Tell ltmain to make .lib files, not .a files. libext=lib # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. archive_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, CXX)='true' enable_shared_with_static_runtimes_CXX=yes # Don't use ranlib old_postinstall_cmds_CXX='chmod 644 $oldlib' postlink_cmds_CXX='lt_outputfile="@OUTPUT@"~ lt_tool_outputfile="@TOOL_OUTPUT@"~ case $lt_outputfile in *.exe|*.EXE) ;; *) lt_outputfile=$lt_outputfile.exe lt_tool_outputfile=$lt_tool_outputfile.exe ;; esac~ func_to_tool_file "$lt_outputfile"~ if test : != "$MANIFEST_TOOL" && test -f "$lt_outputfile.manifest"; then $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1; $RM "$lt_outputfile.manifest"; fi' ;; *) # g++ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec_CXX='-L$libdir' export_dynamic_flag_spec_CXX='$wl--export-all-symbols' allow_undefined_flag_CXX=unsupported always_export_symbols_CXX=no enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file, use it as # is; otherwise, prepend EXPORTS... archive_expsym_cmds_CXX='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp $export_symbols $output_objdir/$soname.def; else echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; esac ;; darwin* | rhapsody*) archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported if test yes = "$lt_cv_ld_force_load"; then whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience $wl-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`' else whole_archive_flag_spec_CXX='' fi link_all_deplibs_CXX=yes allow_undefined_flag_CXX=$_lt_dar_allow_undefined case $cc_basename in ifort*|nagfor*) _lt_dar_can_shared=yes ;; *) _lt_dar_can_shared=$GCC ;; esac if test yes = "$_lt_dar_can_shared"; then output_verbose_link_cmd=func_echo_all archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" archive_expsym_cmds_CXX="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" module_expsym_cmds_CXX="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" if test yes != "$lt_cv_apple_cc_single_mod"; then archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" archive_expsym_cmds_CXX="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi else ld_shlibs_CXX=no fi ;; os2*) hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_minus_L_CXX=yes allow_undefined_flag_CXX=unsupported shrext_cmds=.dll archive_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ emxexp $libobjs | $SED /"_DLL_InitTerm"/d >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' archive_expsym_cmds_CXX='$ECHO "LIBRARY ${soname%$shared_ext} INITINSTANCE TERMINSTANCE" > $output_objdir/$libname.def~ $ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~ $ECHO "DATA MULTIPLE NONSHARED" >> $output_objdir/$libname.def~ $ECHO EXPORTS >> $output_objdir/$libname.def~ prefix_cmds="$SED"~ if test EXPORTS = "`$SED 1q $export_symbols`"; then prefix_cmds="$prefix_cmds -e 1d"; fi~ prefix_cmds="$prefix_cmds -e \"s/^\(.*\)$/_\1/g\""~ cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' old_archive_From_new_cmds_CXX='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes_CXX=yes file_list_spec_CXX='@' ;; dgux*) case $cc_basename in ec++*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; ghcx*) # Green Hills C++ Compiler # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; freebsd2.*) # C++ shared libraries reported to be fairly broken before # switch to ELF ld_shlibs_CXX=no ;; freebsd-elf*) archive_cmds_need_lc_CXX=no ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes ;; haiku*) archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' link_all_deplibs_CXX=yes ;; hpux9*) hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='$wl-E' hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; hpux10*|hpux11*) if test no = "$with_gnu_ld"; then hardcode_libdir_flag_spec_CXX='$wl+b $wl$libdir' hardcode_libdir_separator_CXX=: case $host_cpu in hppa*64*|ia64*) ;; *) export_dynamic_flag_spec_CXX='$wl-E' ;; esac fi case $host_cpu in hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; *) hardcode_direct_CXX=yes hardcode_direct_absolute_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, # but as the default # location of the library. ;; esac case $cc_basename in CC*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; aCC*) case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then case $host_cpu in hppa*64*) archive_cmds_CXX='$CC -shared -nostdlib -fPIC $wl+h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; ia64*) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib $pic_flag $wl+h $wl$soname $wl+b $wl$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; esac fi else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; interix[3-9]*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl-E' # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. # Instead, shared libraries are loaded at an image base (0x10000000 by # default) and relocated if they conflict, which is a slow very memory # consuming and fragmenting process. To avoid this, we pick a random, # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' archive_expsym_cmds_CXX='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in CC*) # SGI C++ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' # Archives containing C++ object files must be created using # "CC -ar", where "CC" is the IRIX C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs' ;; *) if test yes = "$GXX"; then if test no = "$with_gnu_ld"; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' else archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` -o $lib' fi fi link_all_deplibs_CXX=yes ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: inherit_rpath_CXX=yes ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' # Archives containing C++ object files must be created using # "CC -Bstatic", where "CC" is the KAI C++ compiler. old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; icpc* | ecpc* ) # Intel C++ with_gnu_ld=yes # version 8.0 and above of icpc choke on multiply defined symbols # if we add $predep_objects and $postdep_objects, however 7.1 and # earlier do not add the objects themselves. case `$CC -V 2>&1` in *"Version 7."*) archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 8.0 or newer tmp_idyn= case $host_cpu in ia64*) tmp_idyn=' -i_dynamic';; esac archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac archive_cmds_need_lc_CXX=no hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive$convenience $wl--no-whole-archive' ;; pgCC* | pgcpp*) # Portland Group C++ compiler case `$CC -V` in *pgCC\ [1-5].* | *pgcpp\ [1-5].*) prelink_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~ compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"' old_archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~ $RANLIB $oldlib' archive_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='tpldir=Template.dir~ rm -rf $tpldir~ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; *) # Version 6 and above use weak symbols archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl--rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' whole_archive_flag_spec_CXX='$wl--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' ;; cxx*) # Compaq C++ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname -o $lib $wl-retain-symbols-file $wl$export_symbols' runpath_var=LD_RUN_PATH hardcode_libdir_flag_spec_CXX='-rpath $libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed' ;; xl* | mpixl* | bgxl*) # IBM XL 8.0 on PPC, with GNU ld hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' export_dynamic_flag_spec_CXX='$wl--export-dynamic' archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file $wl$export_symbols' hardcode_libdir_flag_spec_CXX='-R$libdir' whole_archive_flag_spec_CXX='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object_CXX=yes # Not sure whether something based on # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 # would be better. output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; esac ;; esac ;; lynxos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; m88k*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; mvs*) case $cc_basename in cxx*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' wlarc= hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no fi # Workaround some broken pre-1.5 toolchains output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"' ;; *nto* | *qnx*) ld_shlibs_CXX=yes ;; openbsd* | bitrig*) if test -f /usr/libexec/ld.so; then hardcode_direct_CXX=yes hardcode_shlibpath_var_CXX=no hardcode_direct_absolute_CXX=yes archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`"; then archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-retain-symbols-file,$export_symbols -o $lib' export_dynamic_flag_spec_CXX='$wl-E' whole_archive_flag_spec_CXX=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' fi output_verbose_link_cmd=func_echo_all else ld_shlibs_CXX=no fi ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' hardcode_libdir_separator_CXX=: # Archives containing C++ object files must be created using # the KAI C++ compiler. case $host in osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;; *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;; esac ;; RCC*) # Rational C++ 2.4.1 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; cxx*) case $host in osf3*) allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $soname `test -n "$verstring" && func_echo_all "$wl-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' ;; *) allow_undefined_flag_CXX=' -expect_unresolved \*' archive_cmds_CXX='$CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib' archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~ echo "-hidden">> $lib.exp~ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname $wl-input $wl$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry $output_objdir/so_locations -o $lib~ $RM $lib.exp' hardcode_libdir_flag_spec_CXX='-rpath $libdir' ;; esac hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. # # There doesn't appear to be a way to prevent this compiler from # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes,no = "$GXX,$with_gnu_ld"; then allow_undefined_flag_CXX=' $wl-expect_unresolved $wl\*' case $host in osf3*) archive_cmds_CXX='$CC -shared -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; *) archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-msym $wl-soname $wl$soname `test -n "$verstring" && func_echo_all "$wl-set_version $wl$verstring"` $wl-update_registry $wl$output_objdir/so_locations -o $lib' ;; esac hardcode_libdir_flag_spec_CXX='$wl-rpath $wl$libdir' hardcode_libdir_separator_CXX=: # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no fi ;; esac ;; psos*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; lcc*) # Lucid # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' archive_cmds_CXX='$CC -G$allow_undefined_flag -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G$allow_undefined_flag $wl-M $wl$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) # The compiler driver will combine and reorder linker options, # but understands '-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes output_verbose_link_cmd='func_echo_all' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is # necessary to make sure instantiated templates are included # in the archive. old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' ;; gcx*) # Green Hills C++ Compiler archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' # The C++ compiler must be used to create the archive. old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs' ;; *) # GNU C++ compiler with Solaris linker if test yes,no = "$GXX,$with_gnu_ld"; then no_undefined_flag_CXX=' $wl-z ${wl}defs' if $CC --version | $GREP -v '^2\.7' > /dev/null; then archive_cmds_CXX='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -shared $pic_flag -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. archive_cmds_CXX='$CC -G -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags $wl-h $wl$soname -o $lib' archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ $CC -G -nostdlib $wl-M $wl$lib.exp $wl-h $wl$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) whole_archive_flag_spec_CXX='$wl-z ${wl}allextract$convenience $wl-z ${wl}defaultextract' ;; esac fi ;; esac ;; sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) no_undefined_flag_CXX='$wl-z,text' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; sysv5* | sco3.2v5* | sco5v6*) # Note: We CANNOT use -z defs as we might desire, because we do not # link with -lc, and that would cause any symbols used from libc to # always be unresolved, which means just about no library would # ever link correctly. If we're not using GNU ld we use -z text # though, which does catch some bad symbols but isn't as heavy-handed # as -z defs. no_undefined_flag_CXX='$wl-z,text' allow_undefined_flag_CXX='$wl-z,nodefs' archive_cmds_need_lc_CXX=no hardcode_shlibpath_var_CXX=no hardcode_libdir_flag_spec_CXX='$wl-R,$libdir' hardcode_libdir_separator_CXX=':' link_all_deplibs_CXX=yes export_dynamic_flag_spec_CXX='$wl-Bexport' runpath_var='LD_RUN_PATH' case $cc_basename in CC*) archive_cmds_CXX='$CC -G $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -G $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~ '"$old_archive_cmds_CXX" reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~ '"$reload_cmds_CXX" ;; *) archive_cmds_CXX='$CC -shared $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' archive_expsym_cmds_CXX='$CC -shared $wl-Bexport:$export_symbols $wl-h,$soname -o $lib $libobjs $deplibs $compiler_flags' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac ;; vxworks*) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; *) # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 printf "%s\n" "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no GCC_CXX=$GXX LD_CXX=$LD ## CAVEAT EMPTOR: ## There is no encapsulation within the following macros, do not change ## the running order or otherwise move them around unless you know exactly ## what you are doing... # Dependencies to place before and after the object being linked: predep_objects_CXX= postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= cat > conftest.$ac_ext <<_LT_EOF class Foo { public: Foo (void) { a = 0; } private: int a; }; _LT_EOF _lt_libdeps_save_CFLAGS=$CFLAGS case "$CC $CFLAGS " in #( *\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;; *\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;; *\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;; esac if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. # Sentinel used to keep track of whether or not we are before # the conftest object file. pre_test_object_deps_done=no for p in `eval "$output_verbose_link_cmd"`; do case $prev$p in -L* | -R* | -l*) # Some compilers place space between "-{L,R}" and the path. # Remove the space. if test x-L = "$p" || test x-R = "$p"; then prev=$p continue fi # Expand the sysroot to ease extracting the directories later. if test -z "$prev"; then case $p in -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;; -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;; -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;; esac fi case $p in =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;; esac if test no = "$pre_test_object_deps_done"; then case $prev in -L | -R) # Internal compiler library paths should come after those # provided the user. The postdeps already come after the # user supplied libs so there is no need to process them. if test -z "$compiler_lib_search_path_CXX"; then compiler_lib_search_path_CXX=$prev$p else compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} $prev$p" fi ;; # The "-l" case would never come before the object being # linked, so don't bother handling this case. esac else if test -z "$postdeps_CXX"; then postdeps_CXX=$prev$p else postdeps_CXX="${postdeps_CXX} $prev$p" fi fi prev= ;; *.lto.$objext) ;; # Ignore GCC LTO objects *.$objext) # This assumes that the test object file only shows up # once in the compiler output. if test "$p" = "conftest.$objext"; then pre_test_object_deps_done=yes continue fi if test no = "$pre_test_object_deps_done"; then if test -z "$predep_objects_CXX"; then predep_objects_CXX=$p else predep_objects_CXX="$predep_objects_CXX $p" fi else if test -z "$postdep_objects_CXX"; then postdep_objects_CXX=$p else postdep_objects_CXX="$postdep_objects_CXX $p" fi fi ;; *) ;; # Ignore the rest. esac done # Clean up. rm -f a.out a.exe else echo "libtool.m4: error: problem compiling CXX test program" fi $RM -f confest.$objext CFLAGS=$_lt_libdeps_save_CFLAGS # PORTME: override above test on systems where it is broken case $host_os in interix[3-9]*) # Interix 3.5 installs completely hosed .la files for C++, so rather than # hack all around it, let's just trust "g++" to DTRT. predep_objects_CXX= postdep_objects_CXX= postdeps_CXX= ;; esac case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac compiler_lib_search_dirs_CXX= if test -n "${compiler_lib_search_path_CXX}"; then compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | $SED -e 's! -L! !g' -e 's!^ !!'` fi lt_prog_compiler_wl_CXX= lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= # C++ specific cases for pic, static, wl, etc. if test yes = "$GXX"; then lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-static' case $host_os in aix*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' fi lt_prog_compiler_pic_CXX='-fPIC' ;; amigaos*) case $host_cpu in powerpc) # see comment about AmigaOS4 .so support lt_prog_compiler_pic_CXX='-fPIC' ;; m68k) # FIXME: we need at least 68020 code to build shared libraries, but # adding the '-m68020' flag to GCC prevents building anything better, # like '-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; esac ;; beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' case $host_os in os2*) lt_prog_compiler_static_CXX='$wl-static' ;; esac ;; darwin* | rhapsody*) # PIC is the default on this platform # Common symbols not allowed in MH_DYLIB files lt_prog_compiler_pic_CXX='-fno-common' ;; *djgpp*) # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; haiku*) # PIC is the default for Haiku. # The "-static" flag exists, but is broken. lt_prog_compiler_static_CXX= ;; interix[3-9]*) # Interix 3.x gcc -fpic/-fPIC options generate broken code. # Instead, we relocate shared libraries at runtime. ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic fi ;; hpux*) # PIC is the default for 64-bit PA HP-UX, but not for 32-bit # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag # sets the default TLS model and affects inlining. case $host_cpu in hppa*64*) ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; *) lt_prog_compiler_pic_CXX='-fPIC' ;; esac else case $host_os in aix[4-9]*) # All AIX code is PIC. if test ia64 = "$host_cpu"; then # AIX 5 now supports IA64 processor lt_prog_compiler_static_CXX='-Bstatic' else lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp' fi ;; chorus*) case $cc_basename in cxch68*) # Green Hills C++ Compiler # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a" ;; esac ;; mingw* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; dgux*) case $cc_basename in ec++*) lt_prog_compiler_pic_CXX='-KPIC' ;; ghcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' if test ia64 != "$host_cpu"; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='$wl-a ${wl}archive' case $host_cpu in hppa*64*|ia64*) # +Z the default ;; *) lt_prog_compiler_pic_CXX='+Z' ;; esac ;; *) ;; esac ;; interix*) # This is c89, which is MS Visual C++ (no shared libs) # Anyone wants to do a port? ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_static_CXX='-non_shared' # CC pic flag -KPIC is the default. ;; *) ;; esac ;; linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) case $cc_basename in KCC*) # KAI C++ Compiler lt_prog_compiler_wl_CXX='--backend -Wl,' lt_prog_compiler_pic_CXX='-fPIC' ;; ecpc* ) # old Intel C++ for x86_64, which still supported -KPIC. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; icpc* ) # Intel C++, used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fPIC' lt_prog_compiler_static_CXX='-static' ;; pgCC* | pgcpp*) # Portland Group C++ compiler lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; xlc* | xlC* | bgxl[cC]* | mpixl[cC]*) # IBM XL 8.0, 9.0 on PPC and BlueGene lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-qpic' lt_prog_compiler_static_CXX='-qstaticlink' ;; *) case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; esac ;; esac ;; lynxos*) ;; m88k*) ;; mvs*) case $cc_basename in cxx*) lt_prog_compiler_pic_CXX='-W c,exportall' ;; *) ;; esac ;; netbsd* | netbsdelf*-gnu) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. lt_prog_compiler_pic_CXX='-fPIC -shared' ;; osf3* | osf4* | osf5*) case $cc_basename in KCC*) lt_prog_compiler_wl_CXX='--backend -Wl,' ;; RCC*) # Rational C++ 2.4.1 lt_prog_compiler_pic_CXX='-pic' ;; cxx*) # Digital/Compaq C++ lt_prog_compiler_wl_CXX='-Wl,' # Make sure the PIC flag is empty. It appears that all Alpha # Linux and Compaq Tru64 Unix objects are PIC. lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX='-non_shared' ;; *) ;; esac ;; psos*) ;; solaris*) case $cc_basename in CC* | sunCC*) # Sun C++ 4.2, 5.x and Centerline C++ lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' lt_prog_compiler_wl_CXX='-Qoption ld ' ;; gcx*) # Green Hills C++ Compiler lt_prog_compiler_pic_CXX='-PIC' ;; *) ;; esac ;; sunos4*) case $cc_basename in CC*) # Sun C++ 4.x lt_prog_compiler_pic_CXX='-pic' lt_prog_compiler_static_CXX='-Bstatic' ;; lcc*) # Lucid lt_prog_compiler_pic_CXX='-pic' ;; *) ;; esac ;; sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-Bstatic' ;; esac ;; tandem*) case $cc_basename in NCC*) # NonStop-UX NCC 3.20 lt_prog_compiler_pic_CXX='-KPIC' ;; *) ;; esac ;; vxworks*) ;; *) lt_prog_compiler_can_build_shared_CXX=no ;; esac fi case $host_os in # For platforms that do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= ;; *) lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC" ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 printf %s "checking for $compiler option to produce PIC... " >&6; } if test ${lt_cv_prog_compiler_pic_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_CXX=$lt_prog_compiler_pic_CXX fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_CXX" >&6; } lt_prog_compiler_pic_CXX=$lt_cv_prog_compiler_pic_CXX # # Check to make sure the PIC flag actually works. # if test -n "$lt_prog_compiler_pic_CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; } if test ${lt_cv_prog_compiler_pic_works_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" ## exclude from sc_useless_quotes_in_assignment # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_pic_works_CXX=yes fi fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_pic_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_pic_works_CXX"; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; esac else lt_prog_compiler_pic_CXX= lt_prog_compiler_can_build_shared_CXX=no fi fi # # Check to make sure the static flag actually works. # wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } if test ${lt_cv_prog_compiler_static_works_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_static_works_CXX=no save_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS $lt_tmp_static_flag" echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&5 $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_static_works_CXX=yes fi else lt_cv_prog_compiler_static_works_CXX=yes fi fi $RM -r conftest* LDFLAGS=$save_LDFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_static_works_CXX" >&6; } if test yes = "$lt_cv_prog_compiler_static_works_CXX"; then : else lt_prog_compiler_static_CXX= fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 printf %s "checking if $compiler supports -c -o file.$ac_objext... " >&6; } if test ${lt_cv_prog_compiler_c_o_CXX+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_prog_compiler_c_o_CXX=no $RM -r conftest 2>/dev/null mkdir conftest cd conftest mkdir out echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi chmod u+w . 2>&5 $RM conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files $RM out/* && rmdir out cd .. $RM -r conftest $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5 printf "%s\n" "$lt_cv_prog_compiler_c_o_CXX" >&6; } hard_links=nottested if test no = "$lt_cv_prog_compiler_c_o_CXX" && test no != "$need_locks"; then # do not overwrite the value of need_locks provided by the user { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 printf %s "checking if we can lock with hard links... " >&6; } hard_links=yes $RM conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no touch conftest.a ln conftest.a conftest.b 2>&5 || hard_links=no ln conftest.a conftest.b 2>/dev/null && hard_links=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 printf "%s\n" "$hard_links" >&6; } if test no = "$hard_links"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&5 printf "%s\n" "$as_me: WARNING: '$CC' does not support '-c -o', so 'make -j' may be unsafe" >&2;} need_locks=warn fi else need_locks=no fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 printf %s "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' case $host_os in aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to GNU nm, but means don't demangle to AIX nm. # Without the "-l" option, or with the "-B" option, AIX nm treats # weak defined symbols like other global defined symbols, whereas # GNU nm marks them as "W". # While the 'weak' keyword is ignored in the Export File, we need # it in the Import File for the 'aix-soname' feature, so we have # to replace the "-B" option with "-P" for AIX nm. if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else export_symbols_cmds_CXX='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) export_symbols_cmds_CXX=$ltdll_cmds ;; cygwin* | mingw* | cegcc*) case $cc_basename in cl* | icl*) exclude_expsyms_CXX='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms_CXX='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' ;; esac ;; linux* | k*bsd*-gnu | gnu*) link_all_deplibs_CXX=no ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5 printf "%s\n" "$ld_shlibs_CXX" >&6; } test no = "$ld_shlibs_CXX" && can_build_shared=no with_gnu_ld_CXX=$with_gnu_ld # # Do we need to explicitly link libc? # case "x$archive_cmds_need_lc_CXX" in x|xyes) # Assume -lc should be added archive_cmds_need_lc_CXX=yes if test yes,yes = "$GCC,$enable_shared"; then case $archive_cmds_CXX in *'~'*) # FIXME: we may have to deal with multi-command sequences. ;; '$CC '*) # Test whether the compiler implicitly links with -lc since on some # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 printf %s "checking whether -lc should be explicitly linked in... " >&6; } if test ${lt_cv_archive_cmds_need_lc_CXX+y} then : printf %s "(cached) " >&6 else $as_nop $RM conftest* echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 (eval $ac_compile) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= output_objdir=. libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } then lt_cv_archive_cmds_need_lc_CXX=no else lt_cv_archive_cmds_need_lc_CXX=yes fi allow_undefined_flag_CXX=$lt_save_allow_undefined_flag else cat conftest.err 1>&5 fi $RM conftest* fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5 printf "%s\n" "$lt_cv_archive_cmds_need_lc_CXX" >&6; } archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX ;; esac fi ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 printf %s "checking dynamic linker characteristics... " >&6; } library_names_spec= libname_spec='lib$name' soname_spec= shrext_cmds=.so postinstall_cmds= postuninstall_cmds= finish_cmds= finish_eval= shlibpath_var= shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" need_lib_prefix=unknown hardcode_into_libs=no # when you set need_version to no, make sure it does not cause -set_version # flags to be left without arguments need_version=unknown case $host_os in aix3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname.a' shlibpath_var=LIBPATH # AIX 3 has no versioning support, so we append a major version to the name. soname_spec='$libname$release$shared_ext$major' ;; aix[4-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no hardcode_into_libs=yes if test ia64 = "$host_cpu"; then # AIX 5 supports IA64 library_names_spec='$libname$release$shared_ext$major $libname$release$shared_ext$versuffix $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH else # With GCC up to 2.95.x, collect2 would create an import file # for dependence libraries. The import file would start with # the line '#! .'. This would cause the generated library to # depend on '.', always an invalid library. This was fixed in # development snapshots of GCC prior to 3.0. case $host_os in aix4 | aix4.[01] | aix4.[01].*) if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' echo ' yes ' echo '#endif'; } | $CC -E - | $GREP yes > /dev/null; then : else can_build_shared=no fi ;; esac # Using Import Files as archive members, it is possible to support # filename-based versioning of shared library archives on AIX. While # this would work for both with and without runtime linking, it will # prevent static linking of such archives. So we do filename-based # shared library versioning with .so extension only, which is used # when both runtime linking and shared linking is enabled. # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the # archive as well as the shared archive member, telling the # bitwidth (32 or 64) of that shared object, and providing the # list of exported symbols of that shared object, eventually # decorated with the 'weak' keyword # *) the shared object with the F_LOADONLY flag set, to really avoid # it being seen by the linker. # At run time we better use the real file rather than another symlink, # but for link time we create the symlink libNAME.so -> libNAME.so.V case $with_aix_soname,$aix_use_runtimelinking in # AIX (on Power*) has no versioning support, so currently we cannot hardcode correct # soname into executable. Probably we can add versioning support to # collect2, so additional links can be useful in future. aix,yes) # traditional libtool dynamic_linker='AIX unversionable lib.so' # If using run time linking (on AIX 4.2 or later) use lib.so # instead of lib.a to let people know that these are not # typical AIX shared libraries. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; aix,no) # traditional AIX only dynamic_linker='AIX lib.a(lib.so.V)' # We preserve .a as extension for shared libraries through AIX4.2 # and later when we are not doing run time linking. library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' ;; svr4,*) # full svr4 only dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,yes) # both, prefer svr4 dynamic_linker="AIX lib.so.V($shared_archive_member_spec.o), lib.a(lib.so.V)" library_names_spec='$libname$release$shared_ext$major $libname$shared_ext' # unpreferred sharedlib libNAME.a needs extra handling postinstall_cmds='test -n "$linkname" || linkname="$realname"~func_stripname "" ".so" "$linkname"~$install_shared_prog "$dir/$func_stripname_result.$libext" "$destdir/$func_stripname_result.$libext"~test -z "$tstripme" || test -z "$striplib" || $striplib "$destdir/$func_stripname_result.$libext"' postuninstall_cmds='for n in $library_names $old_library; do :; done~func_stripname "" ".so" "$n"~test "$func_stripname_result" = "$n" || func_append rmfiles " $odir/$func_stripname_result.$libext"' # We do not specify a path in Import Files, so LIBPATH fires. shlibpath_overrides_runpath=yes ;; *,no) # both, prefer aix dynamic_linker="AIX lib.a(lib.so.V), lib.so.V($shared_archive_member_spec.o)" library_names_spec='$libname$release.a $libname.a' soname_spec='$libname$release$shared_ext$major' # unpreferred sharedlib libNAME.so.V and symlink libNAME.so need extra handling postinstall_cmds='test -z "$dlname" || $install_shared_prog $dir/$dlname $destdir/$dlname~test -z "$tstripme" || test -z "$striplib" || $striplib $destdir/$dlname~test -n "$linkname" || linkname=$realname~func_stripname "" ".a" "$linkname"~(cd "$destdir" && $LN_S -f $dlname $func_stripname_result.so)' postuninstall_cmds='test -z "$dlname" || func_append rmfiles " $odir/$dlname"~for n in $old_library $library_names; do :; done~func_stripname "" ".a" "$n"~func_append rmfiles " $odir/$func_stripname_result.so"' ;; esac shlibpath_var=LIBPATH fi ;; amigaos*) case $host_cpu in powerpc) # Since July 2007 AmigaOS4 officially supports .so libraries. # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' ;; m68k) library_names_spec='$libname.ixlibrary $libname.a' # Create ${libname}_ixlibrary.a entries in /sys/libs. finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' ;; esac ;; beos*) library_names_spec='$libname$shared_ext' dynamic_linker="$host_os ld.so" shlibpath_var=LIBRARY_PATH ;; bsdi[45]*) version_type=linux # correct to gnu/linux during the next big refactor need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" # the default ld.so.conf also contains /usr/contrib/lib and # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow # libtool to hard-code these into programs ;; cygwin* | mingw* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no case $GCC,$cc_basename in yes,*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; mingw* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; *,cl* | *,icl*) # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in mingw*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' for lt_path in $LIB do IFS=$lt_save_ifs # Let DOS variable expansion print the short 8.3 style file name. lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"` sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path" done IFS=$lt_save_ifs # Convert to MSYS style. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form # but this time dos style (no spaces!) so that the unix form looks # like /cygdrive/c/PROGRA~1:/cygdr... sys_lib_search_path_spec=`cygpath --path --unix "$LIB"` sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null` sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` ;; *) sys_lib_search_path_spec=$LIB if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then # It is most probably a Windows format PATH. sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` else sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi # FIXME: find the short name or the path components, as spaces are # common. (e.g. "Program Files" -> "PROGRA~1") ;; esac # DLL is installed to $(libdir)/../bin by postinstall_cmds postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' shlibpath_overrides_runpath=yes dynamic_linker='Win32 link.exe' ;; *) # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; esac # FIXME: first we should search . and the directory the executable is in shlibpath_var=PATH ;; darwin* | rhapsody*) dynamic_linker="$host_os dyld" version_type=darwin need_lib_prefix=no need_version=no library_names_spec='$libname$release$major$shared_ext $libname$shared_ext' soname_spec='$libname$release$major$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; dgux*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then objformat=`/usr/bin/objformat` else case $host_os in freebsd[23].*) objformat=aout ;; *) objformat=elf ;; esac fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' need_version=no need_lib_prefix=no ;; freebsd-*) library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' need_version=yes ;; esac shlibpath_var=LD_LIBRARY_PATH case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes ;; freebsd3.[01]* | freebsdelf3.[01]*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; *) # from 4.6 on, and DragonFly shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; esac ;; haiku*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no dynamic_linker="$host_os runtime_loader" library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' hardcode_into_libs=yes ;; hpux9* | hpux10* | hpux11*) # Give a soname corresponding to the major version so that dld.sl refuses to # link against other versions. version_type=sunos need_lib_prefix=no need_version=no case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes dynamic_linker="$host_os dld.so" shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' if test 32 = "$HPUX_IA64_MODE"; then sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" sys_lib_dlsearch_path_spec=/usr/lib/hpux32 else sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" sys_lib_dlsearch_path_spec=/usr/lib/hpux64 fi ;; hppa*64*) shrext_cmds='.sl' hardcode_into_libs=yes dynamic_linker="$host_os dld.sl" shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; *) shrext_cmds='.sl' dynamic_linker="$host_os dld.sl" shlibpath_var=SHLIB_PATH shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' ;; esac # HP-UX runs *really* slowly unless shared libraries are mode 555, ... postinstall_cmds='chmod 555 $lib' # or fails outright, so override atomically: install_override_mode=555 ;; interix[3-9]*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; *) if test yes = "$lt_cv_prog_gnu_ld"; then version_type=linux # correct to gnu/linux during the next big refactor else version_type=irix fi ;; esac need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$release$shared_ext $libname$shared_ext' case $host_os in irix5* | nonstopux*) libsuff= shlibsuff= ;; *) case $LD in # libtool.m4 will add one of these switches to LD *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= libmagic=32-bit;; *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 libmagic=64-bit;; *) libsuff= shlibsuff= libmagic=never-match;; esac ;; esac shlibpath_var=LD_LIBRARY${shlibsuff}_PATH shlibpath_overrides_runpath=no sys_lib_search_path_spec="/usr/lib$libsuff /lib$libsuff /usr/local/lib$libsuff" sys_lib_dlsearch_path_spec="/usr/lib$libsuff /lib$libsuff" hardcode_into_libs=yes ;; # No shared lib support for Linux oldld, aout, or coff. linux*oldld* | linux*aout* | linux*coff*) dynamic_linker=no ;; linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes dynamic_linker='Android linker' # Don't embed -rpath directories since the linker doesn't support them. hardcode_libdir_flag_spec_CXX='-L$libdir' ;; # This must be glibc/ELF. linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no # Some binutils ld are patched to set DT_RUNPATH if test ${lt_cv_shlibpath_overrides_runpath+y} then : printf %s "(cached) " >&6 else $as_nop lt_cv_shlibpath_overrides_runpath=no save_LDFLAGS=$LDFLAGS save_libdir=$libdir eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\"" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_link "$LINENO" then : if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null then : lt_cv_shlibpath_overrides_runpath=yes fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext LDFLAGS=$save_LDFLAGS libdir=$save_libdir fi shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath # This implies no fast_install, which is unacceptable. # Some rework will be needed to allow for fast_install # before this can be enabled. hardcode_into_libs=yes # Ideally, we could use ldconfig to report *all* directores which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, # even though it is searched at run-time. Try to do the best guess by # appending ld.so.conf contents (and includes) to the search path. if test -f /etc/ld.so.conf; then lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi # We used to test for /lib/ld.so.1 and disable shared libraries on # powerpc, because MkLinux only supported shared libraries with the # GNU dynamic linker. Since this was broken with cross compilers, # most powerpc-linux boxes support dynamic linking these days and # people can always --disable-shared, the test was removed, and we # assume the GNU/Linux dynamic linker is in use. dynamic_linker='GNU/Linux ld.so' ;; netbsdelf*-gnu) version_type=linux need_lib_prefix=no need_version=no library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='NetBSD ld.elf_so' ;; netbsd*) version_type=sunos need_lib_prefix=no need_version=no if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' dynamic_linker='NetBSD (a.out) ld.so' else library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' dynamic_linker='NetBSD ld.elf_so' fi shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; *nto* | *qnx*) version_type=qnx need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes dynamic_linker='ldqnx.so' ;; openbsd* | bitrig*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then need_version=no else need_version=yes fi library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes ;; os2*) libname_spec='$name' version_type=windows shrext_cmds=.dll need_version=no need_lib_prefix=no # OS/2 can only load a DLL with a base name of 8 characters or less. soname_spec='`test -n "$os2dllname" && libname="$os2dllname"; v=$($ECHO $release$versuffix | tr -d .-); n=$($ECHO $libname | cut -b -$((8 - ${#v})) | tr . _); $ECHO $n$v`$shared_ext' library_names_spec='${libname}_dll.$libext' dynamic_linker='OS/2 ld.exe' shlibpath_var=BEGINLIBPATH sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec postinstall_cmds='base_file=`basename \$file`~ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; $ECHO \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ $install_prog $dir/$dlname \$dldir/$dlname~ chmod a+x \$dldir/$dlname~ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; fi' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; $ECHO \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' ;; osf3* | osf4* | osf5*) version_type=osf need_lib_prefix=no need_version=no soname_spec='$libname$release$shared_ext$major' library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec ;; rdos*) dynamic_linker=no ;; solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes # ldd complains unless libraries are executable postinstall_cmds='chmod +x $lib' ;; sunos4*) version_type=sunos library_names_spec='$libname$release$shared_ext$versuffix $libname$shared_ext$versuffix' finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes if test yes = "$with_gnu_ld"; then need_lib_prefix=no fi need_version=yes ;; sysv4 | sysv4.3*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH case $host_vendor in sni) shlibpath_overrides_runpath=no need_lib_prefix=no runpath_var=LD_RUN_PATH ;; siemens) need_lib_prefix=no ;; motorola) need_lib_prefix=no need_version=no shlibpath_overrides_runpath=no sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' ;; esac ;; sysv4*MP*) if test -d /usr/nec; then version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$shared_ext.$versuffix $libname$shared_ext.$major $libname$shared_ext' soname_spec='$libname$shared_ext.$major' shlibpath_var=LD_LIBRARY_PATH fi ;; sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) version_type=sco need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=yes hardcode_into_libs=yes if test yes = "$with_gnu_ld"; then sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' else sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' case $host_os in sco3.2v5*) sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" ;; esac fi sys_lib_dlsearch_path_spec='/usr/lib' ;; tpf*) # TPF is a cross-target only. Preferred cross-host = GNU/Linux. version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no need_version=no library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' shlibpath_var=LD_LIBRARY_PATH shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; uts4*) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' soname_spec='$libname$release$shared_ext$major' shlibpath_var=LD_LIBRARY_PATH ;; *) dynamic_linker=no ;; esac { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 printf "%s\n" "$dynamic_linker" >&6; } test no = "$dynamic_linker" && can_build_shared=no variables_saved_for_relink="PATH $shlibpath_var $runpath_var" if test yes = "$GCC"; then variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" fi if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec fi if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec fi # remember unaugmented sys_lib_dlsearch_path content for libtool script decls... configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" # to be used as default LT_SYS_LIBRARY_PATH value in generated libtool configure_time_lt_sys_library_path=$LT_SYS_LIBRARY_PATH { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 printf %s "checking how to hardcode library paths into programs... " >&6; } hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || test -n "$runpath_var_CXX" || test yes = "$hardcode_automatic_CXX"; then # We can hardcode non-existent directories. if test no != "$hardcode_direct_CXX" && # If the only mechanism to avoid hardcoding is shlibpath_var, we # have to relink, otherwise we might link with an installed library # when we should be linking with a yet-to-be-installed one ## test no != "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" && test no != "$hardcode_minus_L_CXX"; then # Linking always hardcodes the temporary library directory. hardcode_action_CXX=relink else # We can link without hardcoding, and we can hardcode nonexisting dirs. hardcode_action_CXX=immediate fi else # We cannot hardcode anything, or else we can only hardcode existing # directories. hardcode_action_CXX=unsupported fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5 printf "%s\n" "$hardcode_action_CXX" >&6; } if test relink = "$hardcode_action_CXX" || test yes = "$inherit_rpath_CXX"; then # Fast installation is not supported enable_fast_install=no elif test yes = "$shlibpath_overrides_runpath" || test no = "$enable_shared"; then # Fast installation is not necessary enable_fast_install=needless fi fi # test -n "$compiler" CC=$lt_save_CC CFLAGS=$lt_save_CFLAGS LDCXX=$LD LD=$lt_save_LD GCC=$lt_save_GCC with_gnu_ld=$lt_save_with_gnu_ld lt_cv_path_LDCXX=$lt_cv_path_LD lt_cv_path_LD=$lt_save_path_LD lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld fi # test yes != "$_lt_caught_CXX_error" ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ax_cxx_compile_alternatives="23" ax_cxx_compile_cxx23_required=false ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_success=no if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do if test x"$switch" = xMSVC; then switch=-std:c++${alternative} cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx23_${switch}_MSVC" | $as_tr_sh` else cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx23_$switch" | $as_tr_sh` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++23 features with $switch" >&5 printf %s "checking whether $CXX supports C++23 features with $switch... " >&6; } if eval test \${$cachevar+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_CXX="$CXX" CXX="$CXX $switch" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" // MSVC always sets __cplusplus to 199711L in older versions; newer versions // only set it correctly if /Zc:__cplusplus is specified as well as a // /std:c++NN switch: // // https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ // // The value __cplusplus ought to have is available in _MSVC_LANG since // Visual Studio 2015 Update 3: // // https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros // // This was also the first MSVC version to support C++14 so we can't use the // value of either __cplusplus or _MSVC_LANG to quickly rule out MSVC having // C++11 or C++14 support, but we can check _MSVC_LANG for C++17 and later. #elif __cplusplus < 201103L && !defined _MSC_VER #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L // If the compiler admits that it is not ready for C++14, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201402L && !defined _MSC_VER #error "This is not a C++14 compiler" #else namespace cxx14 { namespace test_polymorphic_lambdas { int test() { const auto lambda = [](auto&&... args){ const auto istiny = [](auto x){ return (sizeof(x) == 1UL) ? 1 : 0; }; const int aretiny[] = { istiny(args)... }; return aretiny[0]; }; return lambda(1, 1L, 1.0f, '1'); } } namespace test_binary_literals { constexpr auto ivii = 0b0000000000101010; static_assert(ivii == 42, "wrong value"); } namespace test_generalized_constexpr { template < typename CharT > constexpr unsigned long strlen_c(const CharT *const s) noexcept { auto length = 0UL; for (auto p = s; *p; ++p) ++length; return length; } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("x") == 1UL, ""); static_assert(strlen_c("test") == 4UL, ""); static_assert(strlen_c("another\0test") == 7UL, ""); } namespace test_lambda_init_capture { int test() { auto x = 0; const auto lambda1 = [a = x](int b){ return a + b; }; const auto lambda2 = [a = lambda1(x)](){ return a; }; return lambda2(); } } namespace test_digit_separators { constexpr auto ten_million = 100'000'000; static_assert(ten_million == 100000000, ""); } namespace test_return_type_deduction { auto f(int& x) { return x; } decltype(auto) g(int& x) { return x; } template < typename T1, typename T2 > struct is_same { static constexpr auto value = false; }; template < typename T > struct is_same { static constexpr auto value = true; }; int test() { auto x = 0; static_assert(is_same::value, ""); static_assert(is_same::value, ""); return x; } } } // namespace cxx14 #endif // __cplusplus >= 201402L // If the compiler admits that it is not ready for C++17, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 201703L #error "This is not a C++17 compiler" #else #include #include #include namespace cxx17 { namespace test_constexpr_lambdas { constexpr int foo = [](){return 42;}(); } namespace test::nested_namespace::definitions { } namespace test_fold_expression { template int multiply(Args... args) { return (args * ... * 1); } template bool all(Args... args) { return (args && ...); } } namespace test_extended_static_assert { static_assert (true); } namespace test_auto_brace_init_list { auto foo = {5}; auto bar {5}; static_assert(std::is_same, decltype(foo)>::value); static_assert(std::is_same::value); } namespace test_typename_in_template_template_parameter { template typename X> struct D; } namespace test_fallthrough_nodiscard_maybe_unused_attributes { int f1() { return 42; } [[nodiscard]] int f2() { [[maybe_unused]] auto unused = f1(); switch (f1()) { case 17: f1(); [[fallthrough]]; case 42: f1(); } return f1(); } } namespace test_extended_aggregate_initialization { struct base1 { int b1, b2 = 42; }; struct base2 { base2() { b3 = 42; } int b3; }; struct derived : base1, base2 { int d; }; derived d1 {{1, 2}, {}, 4}; // full initialization derived d2 {{}, {}, 4}; // value-initialized bases } namespace test_general_range_based_for_loop { struct iter { int i; int& operator* () { return i; } const int& operator* () const { return i; } iter& operator++() { ++i; return *this; } }; struct sentinel { int i; }; bool operator== (const iter& i, const sentinel& s) { return i.i == s.i; } bool operator!= (const iter& i, const sentinel& s) { return !(i == s); } struct range { iter begin() const { return {0}; } sentinel end() const { return {5}; } }; void f() { range r {}; for (auto i : r) { [[maybe_unused]] auto v = i; } } } namespace test_lambda_capture_asterisk_this_by_value { struct t { int i; int foo() { return [*this]() { return i; }(); } }; } namespace test_enum_class_construction { enum class byte : unsigned char {}; byte foo {42}; } namespace test_constexpr_if { template int f () { if constexpr(cond) { return 13; } else { return 42; } } } namespace test_selection_statement_with_initializer { int f() { return 13; } int f2() { if (auto i = f(); i > 0) { return 3; } switch (auto i = f(); i + 4) { case 17: return 2; default: return 1; } } } namespace test_template_argument_deduction_for_class_templates { template struct pair { pair (T1 p1, T2 p2) : m1 {p1}, m2 {p2} {} T1 m1; T2 m2; }; void f() { [[maybe_unused]] auto p = pair{13, 42u}; } } namespace test_non_type_auto_template_parameters { template struct B {}; B<5> b1; B<'a'> b2; } namespace test_structured_bindings { int arr[2] = { 1, 2 }; std::pair pr = { 1, 2 }; auto f1() -> int(&)[2] { return arr; } auto f2() -> std::pair& { return pr; } struct S { int x1 : 2; volatile double y1; }; S f3() { return {}; } auto [ x1, y1 ] = f1(); auto& [ xr1, yr1 ] = f1(); auto [ x2, y2 ] = f2(); auto& [ xr2, yr2 ] = f2(); const auto [ x3, y3 ] = f3(); } namespace test_exception_spec_type_system { struct Good {}; struct Bad {}; void g1() noexcept; void g2(); template Bad f(T*, T*); template Good f(T1*, T2*); static_assert (std::is_same_v); } namespace test_inline_variables { template void f(T) {} template inline T g(T) { return T{}; } template<> inline void f<>(int) {} template<> int g<>(int) { return 5; } } } // namespace cxx17 #endif // (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 201703L #ifndef __cplusplus #error "This is not a C++ compiler" #elif (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 202002L #error "This is not a C++20 compiler" #else #include namespace cxx20 { // As C++20 supports feature test macros in the standard, there is no // immediate need to actually test for feature availability on the // Autoconf side. } // namespace cxx20 #endif // (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 202002L #ifndef __cplusplus #error "This is not a C++ compiler" #elif (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 202302L #error "This is not a C++23 compiler" #else #include namespace cxx23 { // As C++23 supports feature test macros in the standard, there is no // immediate need to actually test for feature availability on the // Autoconf side. } // namespace cxx23 #endif // (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 202302L _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval $cachevar=yes else $as_nop eval $cachevar=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CXX="$ac_save_CXX" fi eval ac_res=\$$cachevar { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done if test x$ac_success = xyes; then break fi done fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test x$ax_cxx_compile_cxx23_required = xtrue; then if test x$ac_success = xno; then as_fn_error $? "*** A compiler with support for C++23 language features is required." "$LINENO" 5 fi fi if test x$ac_success = xno; then HAVE_CXX23=0 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++23 support was found" >&5 printf "%s\n" "$as_me: No compiler with C++23 support was found" >&6;} else HAVE_CXX23=1 printf "%s\n" "#define HAVE_CXX23 1" >>confdefs.h fi if test $ax_cv_cxx_compile_cxx23__std_cpp23 != "yes" then : ax_cxx_compile_alternatives="20" ax_cxx_compile_cxx20_required=false ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_success=no if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do if test x"$switch" = xMSVC; then switch=-std:c++${alternative} cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx20_${switch}_MSVC" | $as_tr_sh` else cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx20_$switch" | $as_tr_sh` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++20 features with $switch" >&5 printf %s "checking whether $CXX supports C++20 features with $switch... " >&6; } if eval test \${$cachevar+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_CXX="$CXX" CXX="$CXX $switch" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" // MSVC always sets __cplusplus to 199711L in older versions; newer versions // only set it correctly if /Zc:__cplusplus is specified as well as a // /std:c++NN switch: // // https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ // // The value __cplusplus ought to have is available in _MSVC_LANG since // Visual Studio 2015 Update 3: // // https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros // // This was also the first MSVC version to support C++14 so we can't use the // value of either __cplusplus or _MSVC_LANG to quickly rule out MSVC having // C++11 or C++14 support, but we can check _MSVC_LANG for C++17 and later. #elif __cplusplus < 201103L && !defined _MSC_VER #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L // If the compiler admits that it is not ready for C++14, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201402L && !defined _MSC_VER #error "This is not a C++14 compiler" #else namespace cxx14 { namespace test_polymorphic_lambdas { int test() { const auto lambda = [](auto&&... args){ const auto istiny = [](auto x){ return (sizeof(x) == 1UL) ? 1 : 0; }; const int aretiny[] = { istiny(args)... }; return aretiny[0]; }; return lambda(1, 1L, 1.0f, '1'); } } namespace test_binary_literals { constexpr auto ivii = 0b0000000000101010; static_assert(ivii == 42, "wrong value"); } namespace test_generalized_constexpr { template < typename CharT > constexpr unsigned long strlen_c(const CharT *const s) noexcept { auto length = 0UL; for (auto p = s; *p; ++p) ++length; return length; } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("x") == 1UL, ""); static_assert(strlen_c("test") == 4UL, ""); static_assert(strlen_c("another\0test") == 7UL, ""); } namespace test_lambda_init_capture { int test() { auto x = 0; const auto lambda1 = [a = x](int b){ return a + b; }; const auto lambda2 = [a = lambda1(x)](){ return a; }; return lambda2(); } } namespace test_digit_separators { constexpr auto ten_million = 100'000'000; static_assert(ten_million == 100000000, ""); } namespace test_return_type_deduction { auto f(int& x) { return x; } decltype(auto) g(int& x) { return x; } template < typename T1, typename T2 > struct is_same { static constexpr auto value = false; }; template < typename T > struct is_same { static constexpr auto value = true; }; int test() { auto x = 0; static_assert(is_same::value, ""); static_assert(is_same::value, ""); return x; } } } // namespace cxx14 #endif // __cplusplus >= 201402L // If the compiler admits that it is not ready for C++17, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 201703L #error "This is not a C++17 compiler" #else #include #include #include namespace cxx17 { namespace test_constexpr_lambdas { constexpr int foo = [](){return 42;}(); } namespace test::nested_namespace::definitions { } namespace test_fold_expression { template int multiply(Args... args) { return (args * ... * 1); } template bool all(Args... args) { return (args && ...); } } namespace test_extended_static_assert { static_assert (true); } namespace test_auto_brace_init_list { auto foo = {5}; auto bar {5}; static_assert(std::is_same, decltype(foo)>::value); static_assert(std::is_same::value); } namespace test_typename_in_template_template_parameter { template typename X> struct D; } namespace test_fallthrough_nodiscard_maybe_unused_attributes { int f1() { return 42; } [[nodiscard]] int f2() { [[maybe_unused]] auto unused = f1(); switch (f1()) { case 17: f1(); [[fallthrough]]; case 42: f1(); } return f1(); } } namespace test_extended_aggregate_initialization { struct base1 { int b1, b2 = 42; }; struct base2 { base2() { b3 = 42; } int b3; }; struct derived : base1, base2 { int d; }; derived d1 {{1, 2}, {}, 4}; // full initialization derived d2 {{}, {}, 4}; // value-initialized bases } namespace test_general_range_based_for_loop { struct iter { int i; int& operator* () { return i; } const int& operator* () const { return i; } iter& operator++() { ++i; return *this; } }; struct sentinel { int i; }; bool operator== (const iter& i, const sentinel& s) { return i.i == s.i; } bool operator!= (const iter& i, const sentinel& s) { return !(i == s); } struct range { iter begin() const { return {0}; } sentinel end() const { return {5}; } }; void f() { range r {}; for (auto i : r) { [[maybe_unused]] auto v = i; } } } namespace test_lambda_capture_asterisk_this_by_value { struct t { int i; int foo() { return [*this]() { return i; }(); } }; } namespace test_enum_class_construction { enum class byte : unsigned char {}; byte foo {42}; } namespace test_constexpr_if { template int f () { if constexpr(cond) { return 13; } else { return 42; } } } namespace test_selection_statement_with_initializer { int f() { return 13; } int f2() { if (auto i = f(); i > 0) { return 3; } switch (auto i = f(); i + 4) { case 17: return 2; default: return 1; } } } namespace test_template_argument_deduction_for_class_templates { template struct pair { pair (T1 p1, T2 p2) : m1 {p1}, m2 {p2} {} T1 m1; T2 m2; }; void f() { [[maybe_unused]] auto p = pair{13, 42u}; } } namespace test_non_type_auto_template_parameters { template struct B {}; B<5> b1; B<'a'> b2; } namespace test_structured_bindings { int arr[2] = { 1, 2 }; std::pair pr = { 1, 2 }; auto f1() -> int(&)[2] { return arr; } auto f2() -> std::pair& { return pr; } struct S { int x1 : 2; volatile double y1; }; S f3() { return {}; } auto [ x1, y1 ] = f1(); auto& [ xr1, yr1 ] = f1(); auto [ x2, y2 ] = f2(); auto& [ xr2, yr2 ] = f2(); const auto [ x3, y3 ] = f3(); } namespace test_exception_spec_type_system { struct Good {}; struct Bad {}; void g1() noexcept; void g2(); template Bad f(T*, T*); template Good f(T1*, T2*); static_assert (std::is_same_v); } namespace test_inline_variables { template void f(T) {} template inline T g(T) { return T{}; } template<> inline void f<>(int) {} template<> int g<>(int) { return 5; } } } // namespace cxx17 #endif // (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 201703L #ifndef __cplusplus #error "This is not a C++ compiler" #elif (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 202002L #error "This is not a C++20 compiler" #else #include namespace cxx20 { // As C++20 supports feature test macros in the standard, there is no // immediate need to actually test for feature availability on the // Autoconf side. } // namespace cxx20 #endif // (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 202002L _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval $cachevar=yes else $as_nop eval $cachevar=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CXX="$ac_save_CXX" fi eval ac_res=\$$cachevar { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done if test x$ac_success = xyes; then break fi done fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test x$ax_cxx_compile_cxx20_required = xtrue; then if test x$ac_success = xno; then as_fn_error $? "*** A compiler with support for C++20 language features is required." "$LINENO" 5 fi fi if test x$ac_success = xno; then HAVE_CXX20=0 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++20 support was found" >&5 printf "%s\n" "$as_me: No compiler with C++20 support was found" >&6;} else HAVE_CXX20=1 printf "%s\n" "#define HAVE_CXX20 1" >>confdefs.h fi if test $ax_cv_cxx_compile_cxx20__std_cpp20 != "yes" then : ax_cxx_compile_alternatives="17 1z" ax_cxx_compile_cxx17_required=false ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_success=no if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do if test x"$switch" = xMSVC; then switch=-std:c++${alternative} cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx17_${switch}_MSVC" | $as_tr_sh` else cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx17_$switch" | $as_tr_sh` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++17 features with $switch" >&5 printf %s "checking whether $CXX supports C++17 features with $switch... " >&6; } if eval test \${$cachevar+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_CXX="$CXX" CXX="$CXX $switch" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" // MSVC always sets __cplusplus to 199711L in older versions; newer versions // only set it correctly if /Zc:__cplusplus is specified as well as a // /std:c++NN switch: // // https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ // // The value __cplusplus ought to have is available in _MSVC_LANG since // Visual Studio 2015 Update 3: // // https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros // // This was also the first MSVC version to support C++14 so we can't use the // value of either __cplusplus or _MSVC_LANG to quickly rule out MSVC having // C++11 or C++14 support, but we can check _MSVC_LANG for C++17 and later. #elif __cplusplus < 201103L && !defined _MSC_VER #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L // If the compiler admits that it is not ready for C++14, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201402L && !defined _MSC_VER #error "This is not a C++14 compiler" #else namespace cxx14 { namespace test_polymorphic_lambdas { int test() { const auto lambda = [](auto&&... args){ const auto istiny = [](auto x){ return (sizeof(x) == 1UL) ? 1 : 0; }; const int aretiny[] = { istiny(args)... }; return aretiny[0]; }; return lambda(1, 1L, 1.0f, '1'); } } namespace test_binary_literals { constexpr auto ivii = 0b0000000000101010; static_assert(ivii == 42, "wrong value"); } namespace test_generalized_constexpr { template < typename CharT > constexpr unsigned long strlen_c(const CharT *const s) noexcept { auto length = 0UL; for (auto p = s; *p; ++p) ++length; return length; } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("x") == 1UL, ""); static_assert(strlen_c("test") == 4UL, ""); static_assert(strlen_c("another\0test") == 7UL, ""); } namespace test_lambda_init_capture { int test() { auto x = 0; const auto lambda1 = [a = x](int b){ return a + b; }; const auto lambda2 = [a = lambda1(x)](){ return a; }; return lambda2(); } } namespace test_digit_separators { constexpr auto ten_million = 100'000'000; static_assert(ten_million == 100000000, ""); } namespace test_return_type_deduction { auto f(int& x) { return x; } decltype(auto) g(int& x) { return x; } template < typename T1, typename T2 > struct is_same { static constexpr auto value = false; }; template < typename T > struct is_same { static constexpr auto value = true; }; int test() { auto x = 0; static_assert(is_same::value, ""); static_assert(is_same::value, ""); return x; } } } // namespace cxx14 #endif // __cplusplus >= 201402L // If the compiler admits that it is not ready for C++17, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 201703L #error "This is not a C++17 compiler" #else #include #include #include namespace cxx17 { namespace test_constexpr_lambdas { constexpr int foo = [](){return 42;}(); } namespace test::nested_namespace::definitions { } namespace test_fold_expression { template int multiply(Args... args) { return (args * ... * 1); } template bool all(Args... args) { return (args && ...); } } namespace test_extended_static_assert { static_assert (true); } namespace test_auto_brace_init_list { auto foo = {5}; auto bar {5}; static_assert(std::is_same, decltype(foo)>::value); static_assert(std::is_same::value); } namespace test_typename_in_template_template_parameter { template typename X> struct D; } namespace test_fallthrough_nodiscard_maybe_unused_attributes { int f1() { return 42; } [[nodiscard]] int f2() { [[maybe_unused]] auto unused = f1(); switch (f1()) { case 17: f1(); [[fallthrough]]; case 42: f1(); } return f1(); } } namespace test_extended_aggregate_initialization { struct base1 { int b1, b2 = 42; }; struct base2 { base2() { b3 = 42; } int b3; }; struct derived : base1, base2 { int d; }; derived d1 {{1, 2}, {}, 4}; // full initialization derived d2 {{}, {}, 4}; // value-initialized bases } namespace test_general_range_based_for_loop { struct iter { int i; int& operator* () { return i; } const int& operator* () const { return i; } iter& operator++() { ++i; return *this; } }; struct sentinel { int i; }; bool operator== (const iter& i, const sentinel& s) { return i.i == s.i; } bool operator!= (const iter& i, const sentinel& s) { return !(i == s); } struct range { iter begin() const { return {0}; } sentinel end() const { return {5}; } }; void f() { range r {}; for (auto i : r) { [[maybe_unused]] auto v = i; } } } namespace test_lambda_capture_asterisk_this_by_value { struct t { int i; int foo() { return [*this]() { return i; }(); } }; } namespace test_enum_class_construction { enum class byte : unsigned char {}; byte foo {42}; } namespace test_constexpr_if { template int f () { if constexpr(cond) { return 13; } else { return 42; } } } namespace test_selection_statement_with_initializer { int f() { return 13; } int f2() { if (auto i = f(); i > 0) { return 3; } switch (auto i = f(); i + 4) { case 17: return 2; default: return 1; } } } namespace test_template_argument_deduction_for_class_templates { template struct pair { pair (T1 p1, T2 p2) : m1 {p1}, m2 {p2} {} T1 m1; T2 m2; }; void f() { [[maybe_unused]] auto p = pair{13, 42u}; } } namespace test_non_type_auto_template_parameters { template struct B {}; B<5> b1; B<'a'> b2; } namespace test_structured_bindings { int arr[2] = { 1, 2 }; std::pair pr = { 1, 2 }; auto f1() -> int(&)[2] { return arr; } auto f2() -> std::pair& { return pr; } struct S { int x1 : 2; volatile double y1; }; S f3() { return {}; } auto [ x1, y1 ] = f1(); auto& [ xr1, yr1 ] = f1(); auto [ x2, y2 ] = f2(); auto& [ xr2, yr2 ] = f2(); const auto [ x3, y3 ] = f3(); } namespace test_exception_spec_type_system { struct Good {}; struct Bad {}; void g1() noexcept; void g2(); template Bad f(T*, T*); template Good f(T1*, T2*); static_assert (std::is_same_v); } namespace test_inline_variables { template void f(T) {} template inline T g(T) { return T{}; } template<> inline void f<>(int) {} template<> int g<>(int) { return 5; } } } // namespace cxx17 #endif // (defined _MSVC_LANG ? _MSVC_LANG : __cplusplus) < 201703L _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval $cachevar=yes else $as_nop eval $cachevar=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CXX="$ac_save_CXX" fi eval ac_res=\$$cachevar { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done if test x$ac_success = xyes; then break fi done fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test x$ax_cxx_compile_cxx17_required = xtrue; then if test x$ac_success = xno; then as_fn_error $? "*** A compiler with support for C++17 language features is required." "$LINENO" 5 fi fi if test x$ac_success = xno; then HAVE_CXX17=0 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++17 support was found" >&5 printf "%s\n" "$as_me: No compiler with C++17 support was found" >&6;} else HAVE_CXX17=1 printf "%s\n" "#define HAVE_CXX17 1" >>confdefs.h fi if test $ax_cv_cxx_compile_cxx17__std_cpp17 != "yes" then : ax_cxx_compile_alternatives="14 1y" ax_cxx_compile_cxx14_required=false ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_success=no if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do if test x"$switch" = xMSVC; then switch=-std:c++${alternative} cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx14_${switch}_MSVC" | $as_tr_sh` else cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx14_$switch" | $as_tr_sh` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++14 features with $switch" >&5 printf %s "checking whether $CXX supports C++14 features with $switch... " >&6; } if eval test \${$cachevar+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_CXX="$CXX" CXX="$CXX $switch" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" // MSVC always sets __cplusplus to 199711L in older versions; newer versions // only set it correctly if /Zc:__cplusplus is specified as well as a // /std:c++NN switch: // // https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ // // The value __cplusplus ought to have is available in _MSVC_LANG since // Visual Studio 2015 Update 3: // // https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros // // This was also the first MSVC version to support C++14 so we can't use the // value of either __cplusplus or _MSVC_LANG to quickly rule out MSVC having // C++11 or C++14 support, but we can check _MSVC_LANG for C++17 and later. #elif __cplusplus < 201103L && !defined _MSC_VER #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L // If the compiler admits that it is not ready for C++14, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" #elif __cplusplus < 201402L && !defined _MSC_VER #error "This is not a C++14 compiler" #else namespace cxx14 { namespace test_polymorphic_lambdas { int test() { const auto lambda = [](auto&&... args){ const auto istiny = [](auto x){ return (sizeof(x) == 1UL) ? 1 : 0; }; const int aretiny[] = { istiny(args)... }; return aretiny[0]; }; return lambda(1, 1L, 1.0f, '1'); } } namespace test_binary_literals { constexpr auto ivii = 0b0000000000101010; static_assert(ivii == 42, "wrong value"); } namespace test_generalized_constexpr { template < typename CharT > constexpr unsigned long strlen_c(const CharT *const s) noexcept { auto length = 0UL; for (auto p = s; *p; ++p) ++length; return length; } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("x") == 1UL, ""); static_assert(strlen_c("test") == 4UL, ""); static_assert(strlen_c("another\0test") == 7UL, ""); } namespace test_lambda_init_capture { int test() { auto x = 0; const auto lambda1 = [a = x](int b){ return a + b; }; const auto lambda2 = [a = lambda1(x)](){ return a; }; return lambda2(); } } namespace test_digit_separators { constexpr auto ten_million = 100'000'000; static_assert(ten_million == 100000000, ""); } namespace test_return_type_deduction { auto f(int& x) { return x; } decltype(auto) g(int& x) { return x; } template < typename T1, typename T2 > struct is_same { static constexpr auto value = false; }; template < typename T > struct is_same { static constexpr auto value = true; }; int test() { auto x = 0; static_assert(is_same::value, ""); static_assert(is_same::value, ""); return x; } } } // namespace cxx14 #endif // __cplusplus >= 201402L _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval $cachevar=yes else $as_nop eval $cachevar=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CXX="$ac_save_CXX" fi eval ac_res=\$$cachevar { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done if test x$ac_success = xyes; then break fi done fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test x$ax_cxx_compile_cxx14_required = xtrue; then if test x$ac_success = xno; then as_fn_error $? "*** A compiler with support for C++14 language features is required." "$LINENO" 5 fi fi if test x$ac_success = xno; then HAVE_CXX14=0 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++14 support was found" >&5 printf "%s\n" "$as_me: No compiler with C++14 support was found" >&6;} else HAVE_CXX14=1 printf "%s\n" "#define HAVE_CXX14 1" >>confdefs.h fi if test $ax_cv_cxx_compile_cxx14__std_cpp14 != "yes" then : ax_cxx_compile_alternatives="11 0x" ax_cxx_compile_cxx11_required=true ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu ac_success=no if test x$ac_success = xno; then for alternative in ${ax_cxx_compile_alternatives}; do for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}" MSVC; do if test x"$switch" = xMSVC; then switch=-std:c++${alternative} cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx11_${switch}_MSVC" | $as_tr_sh` else cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh` fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5 printf %s "checking whether $CXX supports C++11 features with $switch... " >&6; } if eval test \${$cachevar+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_CXX="$CXX" CXX="$CXX $switch" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ // If the compiler admits that it is not ready for C++11, why torture it? // Hopefully, this will speed up the test. #ifndef __cplusplus #error "This is not a C++ compiler" // MSVC always sets __cplusplus to 199711L in older versions; newer versions // only set it correctly if /Zc:__cplusplus is specified as well as a // /std:c++NN switch: // // https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ // // The value __cplusplus ought to have is available in _MSVC_LANG since // Visual Studio 2015 Update 3: // // https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros // // This was also the first MSVC version to support C++14 so we can't use the // value of either __cplusplus or _MSVC_LANG to quickly rule out MSVC having // C++11 or C++14 support, but we can check _MSVC_LANG for C++17 and later. #elif __cplusplus < 201103L && !defined _MSC_VER #error "This is not a C++11 compiler" #else namespace cxx11 { namespace test_static_assert { template struct check { static_assert(sizeof(int) <= sizeof(T), "not big enough"); }; } namespace test_final_override { struct Base { virtual ~Base() {} virtual void f() {} }; struct Derived : public Base { virtual ~Derived() override {} virtual void f() override {} }; } namespace test_double_right_angle_brackets { template < typename T > struct check {}; typedef check single_type; typedef check> double_type; typedef check>> triple_type; typedef check>>> quadruple_type; } namespace test_decltype { int f() { int a = 1; decltype(a) b = 2; return a + b; } } namespace test_type_deduction { template < typename T1, typename T2 > struct is_same { static const bool value = false; }; template < typename T > struct is_same { static const bool value = true; }; template < typename T1, typename T2 > auto add(T1 a1, T2 a2) -> decltype(a1 + a2) { return a1 + a2; } int test(const int c, volatile int v) { static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == false, ""); auto ac = c; auto av = v; auto sumi = ac + av + 'x'; auto sumf = ac + av + 1.0; static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == true, ""); static_assert(is_same::value == false, ""); static_assert(is_same::value == true, ""); return (sumf > 0.0) ? sumi : add(c, v); } } namespace test_noexcept { int f() { return 0; } int g() noexcept { return 0; } static_assert(noexcept(f()) == false, ""); static_assert(noexcept(g()) == true, ""); } namespace test_constexpr { template < typename CharT > unsigned long constexpr strlen_c_r(const CharT *const s, const unsigned long acc) noexcept { return *s ? strlen_c_r(s + 1, acc + 1) : acc; } template < typename CharT > unsigned long constexpr strlen_c(const CharT *const s) noexcept { return strlen_c_r(s, 0UL); } static_assert(strlen_c("") == 0UL, ""); static_assert(strlen_c("1") == 1UL, ""); static_assert(strlen_c("example") == 7UL, ""); static_assert(strlen_c("another\0example") == 7UL, ""); } namespace test_rvalue_references { template < int N > struct answer { static constexpr int value = N; }; answer<1> f(int&) { return answer<1>(); } answer<2> f(const int&) { return answer<2>(); } answer<3> f(int&&) { return answer<3>(); } void test() { int i = 0; const int c = 0; static_assert(decltype(f(i))::value == 1, ""); static_assert(decltype(f(c))::value == 2, ""); static_assert(decltype(f(0))::value == 3, ""); } } namespace test_uniform_initialization { struct test { static const int zero {}; static const int one {1}; }; static_assert(test::zero == 0, ""); static_assert(test::one == 1, ""); } namespace test_lambdas { void test1() { auto lambda1 = [](){}; auto lambda2 = lambda1; lambda1(); lambda2(); } int test2() { auto a = [](int i, int j){ return i + j; }(1, 2); auto b = []() -> int { return '0'; }(); auto c = [=](){ return a + b; }(); auto d = [&](){ return c; }(); auto e = [a, &b](int x) mutable { const auto identity = [](int y){ return y; }; for (auto i = 0; i < a; ++i) a += b--; return x + identity(a + b); }(0); return a + b + c + d + e; } int test3() { const auto nullary = [](){ return 0; }; const auto unary = [](int x){ return x; }; using nullary_t = decltype(nullary); using unary_t = decltype(unary); const auto higher1st = [](nullary_t f){ return f(); }; const auto higher2nd = [unary](nullary_t f1){ return [unary, f1](unary_t f2){ return f2(unary(f1())); }; }; return higher1st(nullary) + higher2nd(nullary)(unary); } } namespace test_variadic_templates { template struct sum; template struct sum { static constexpr auto value = N0 + sum::value; }; template <> struct sum<> { static constexpr auto value = 0; }; static_assert(sum<>::value == 0, ""); static_assert(sum<1>::value == 1, ""); static_assert(sum<23>::value == 23, ""); static_assert(sum<1, 2>::value == 3, ""); static_assert(sum<5, 5, 11>::value == 21, ""); static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, ""); } // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function // because of this. namespace test_template_alias_sfinae { struct foo {}; template using member = typename T::member_type; template void func(...) {} template void func(member*) {} void test(); void test() { func(0); } } } // namespace cxx11 #endif // __cplusplus >= 201103L _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval $cachevar=yes else $as_nop eval $cachevar=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CXX="$ac_save_CXX" fi eval ac_res=\$$cachevar { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test x\$$cachevar = xyes; then CXX="$CXX $switch" if test -n "$CXXCPP" ; then CXXCPP="$CXXCPP $switch" fi ac_success=yes break fi done if test x$ac_success = xyes; then break fi done fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test x$ax_cxx_compile_cxx11_required = xtrue; then if test x$ac_success = xno; then as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5 fi fi if test x$ac_success = xno; then HAVE_CXX11=0 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5 printf "%s\n" "$as_me: No compiler with C++11 support was found" >&6;} else HAVE_CXX11=1 printf "%s\n" "#define HAVE_CXX11 1" >>confdefs.h fi fi fi fi fi for flag in -fvisibility=hidden -fvisibility-inlines-hidden; do as_CACHEVAR=`printf "%s\n" "ax_cv_check_cxxflags__$flag" | $as_tr_sh` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler accepts $flag" >&5 printf %s "checking whether the C++ compiler accepts $flag... " >&6; } if eval test \${$as_CACHEVAR+y} then : printf %s "(cached) " >&6 else $as_nop ax_check_save_flags=$CXXFLAGS if test x"$GXX" = xyes ; then add_gnu_werror="-Werror" fi CXXFLAGS="$CXXFLAGS $flag $add_gnu_werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval "$as_CACHEVAR=yes" else $as_nop eval "$as_CACHEVAR=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CXXFLAGS=$ax_check_save_flags fi eval ac_res=\$$as_CACHEVAR { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test \"x\$"$as_CACHEVAR"\" = x"yes" then : if test ${CXXFLAGS+y} then : case " $CXXFLAGS " in #( *" $flag "*) : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5 (: CXXFLAGS already contains $flag) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } ;; #( *) : as_fn_append CXXFLAGS " $flag" { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS\""; } >&5 (: CXXFLAGS="$CXXFLAGS") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } ;; esac else $as_nop CXXFLAGS=$flag { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS\""; } >&5 (: CXXFLAGS="$CXXFLAGS") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } fi else $as_nop : fi done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5 printf %s "checking whether byte ordering is bigendian... " >&6; } if test ${ac_cv_c_bigendian+y} then : printf %s "(cached) " >&6 else $as_nop ac_cv_c_bigendian=unknown # See if we're dealing with a universal compiler. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #ifndef __APPLE_CC__ not a universal capable compiler #endif typedef int dummy; _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : # Check for potential -arch flags. It is not universal unless # there are at least two -arch flags with different values. ac_arch= ac_prev= for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do if test -n "$ac_prev"; then case $ac_word in i?86 | x86_64 | ppc | ppc64) if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then ac_arch=$ac_word else ac_cv_c_bigendian=universal break fi ;; esac ac_prev= elif test "x$ac_word" = "x-arch"; then ac_prev=arch fi done fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext if test $ac_cv_c_bigendian = unknown; then # See if sys/param.h defines the BYTE_ORDER macro. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main (void) { #if ! (defined BYTE_ORDER && defined BIG_ENDIAN \ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \ && LITTLE_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : # It does; now see whether it defined to BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include int main (void) { #if BYTE_ORDER != BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_c_bigendian=yes else $as_nop ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # See if defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris). cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { #if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN) bogus endian macros #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : # It does; now see whether it defined to _BIG_ENDIAN or not. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { #ifndef _BIG_ENDIAN not big endian #endif ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : ac_cv_c_bigendian=yes else $as_nop ac_cv_c_bigendian=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi if test $ac_cv_c_bigendian = unknown; then # Compile a test program. if test "$cross_compiling" = yes then : # Try to guess by grepping values from an object file. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ unsigned short int ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 }; unsigned short int ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 }; int use_ascii (int i) { return ascii_mm[i] + ascii_ii[i]; } unsigned short int ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 }; unsigned short int ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 }; int use_ebcdic (int i) { return ebcdic_mm[i] + ebcdic_ii[i]; } extern int foo; int main (void) { return use_ascii (foo) == use_ebcdic (foo); ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then ac_cv_c_bigendian=yes fi if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then if test "$ac_cv_c_bigendian" = unknown; then ac_cv_c_bigendian=no else # finding both strings is unlikely to happen, but who knows? ac_cv_c_bigendian=unknown fi fi fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ $ac_includes_default int main (void) { /* Are we little or big endian? From Harbison&Steele. */ union { long int l; char c[sizeof (long int)]; } u; u.l = 1; return u.c[sizeof (long int) - 1] == 1; ; return 0; } _ACEOF if ac_fn_cxx_try_run "$LINENO" then : ac_cv_c_bigendian=no else $as_nop ac_cv_c_bigendian=yes fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ conftest.$ac_objext conftest.beam conftest.$ac_ext fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5 printf "%s\n" "$ac_cv_c_bigendian" >&6; } case $ac_cv_c_bigendian in #( yes) printf "%s\n" "#define WORDS_BIGENDIAN 1" >>confdefs.h ;; #( no) ;; #( universal) printf "%s\n" "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h ;; #( *) as_fn_error $? "unknown endianness presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;; esac # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of short" >&5 printf %s "checking size of short... " >&6; } if test ${ac_cv_sizeof_short+y} then : printf %s "(cached) " >&6 else $as_nop if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (short))" "ac_cv_sizeof_short" "$ac_includes_default" then : else $as_nop if test "$ac_cv_type_short" = yes; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (short) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_short=0 fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_short" >&5 printf "%s\n" "$ac_cv_sizeof_short" >&6; } printf "%s\n" "#define SIZEOF_SHORT $ac_cv_sizeof_short" >>confdefs.h # The cast to long int works around a bug in the HP C Compiler # version HP92453-01 B.11.11.23709.GP, which incorrectly rejects # declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. # This bug is HP SR number 8606223364. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking size of int" >&5 printf %s "checking size of int... " >&6; } if test ${ac_cv_sizeof_int+y} then : printf %s "(cached) " >&6 else $as_nop if ac_fn_cxx_compute_int "$LINENO" "(long int) (sizeof (int))" "ac_cv_sizeof_int" "$ac_includes_default" then : else $as_nop if test "$ac_cv_type_int" = yes; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error 77 "cannot compute sizeof (int) See \`config.log' for more details" "$LINENO" 5; } else ac_cv_sizeof_int=0 fi fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_int" >&5 printf "%s\n" "$ac_cv_sizeof_int" >&6; } printf "%s\n" "#define SIZEOF_INT $ac_cv_sizeof_int" >>confdefs.h if test $ac_cv_sizeof_short -ne 2 then : as_fn_error $? "size of short must be 16 bit" "$LINENO" 5 fi if test $ac_cv_sizeof_int -lt 4 then : as_fn_error $? "only 32 bit or better CPUs are supported" "$LINENO" 5 fi ac_fn_cxx_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "#include " if test "x$ac_cv_type_int8_t" = xyes then : printf "%s\n" "#define HAVE_INT8_T 1" >>confdefs.h else $as_nop as_fn_error $? "missing fixed width integer types" "$LINENO" 5 fi ac_fn_cxx_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "#include " if test "x$ac_cv_type_uint8_t" = xyes then : printf "%s\n" "#define HAVE_UINT8_T 1" >>confdefs.h else $as_nop as_fn_error $? "missing fixed width integer types" "$LINENO" 5 fi ac_fn_cxx_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "#include " if test "x$ac_cv_type_int16_t" = xyes then : printf "%s\n" "#define HAVE_INT16_T 1" >>confdefs.h else $as_nop as_fn_error $? "missing fixed width integer types" "$LINENO" 5 fi ac_fn_cxx_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "#include " if test "x$ac_cv_type_uint16_t" = xyes then : printf "%s\n" "#define HAVE_UINT16_T 1" >>confdefs.h else $as_nop as_fn_error $? "missing fixed width integer types" "$LINENO" 5 fi ac_fn_cxx_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "#include " if test "x$ac_cv_type_int32_t" = xyes then : printf "%s\n" "#define HAVE_INT32_T 1" >>confdefs.h else $as_nop as_fn_error $? "missing fixed width integer types" "$LINENO" 5 fi ac_fn_cxx_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "#include " if test "x$ac_cv_type_uint32_t" = xyes then : printf "%s\n" "#define HAVE_UINT32_T 1" >>confdefs.h else $as_nop as_fn_error $? "missing fixed width integer types" "$LINENO" 5 fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX options needed to detect all undeclared functions" >&5 printf %s "checking for $CXX options needed to detect all undeclared functions... " >&6; } if test ${ac_cv_cxx_undeclared_builtin_options+y} then : printf %s "(cached) " >&6 else $as_nop ac_save_CFLAGS=$CFLAGS ac_cv_cxx_undeclared_builtin_options='cannot detect' for ac_arg in '' -fno-builtin; do CFLAGS="$ac_save_CFLAGS $ac_arg" # This test program should *not* compile successfully. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { (void) strchr; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : else $as_nop # This test program should compile successfully. # No library function is consistently available on # freestanding implementations, so test against a dummy # declaration. Include always-available headers on the # off chance that they somehow elicit warnings. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include #include #include #include extern void ac_decl (int, char *); int main (void) { (void) ac_decl (0, (char *) 0); (void) ac_decl; ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : if test x"$ac_arg" = x then : ac_cv_cxx_undeclared_builtin_options='none needed' else $as_nop ac_cv_cxx_undeclared_builtin_options=$ac_arg fi break fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext done CFLAGS=$ac_save_CFLAGS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_undeclared_builtin_options" >&5 printf "%s\n" "$ac_cv_cxx_undeclared_builtin_options" >&6; } case $ac_cv_cxx_undeclared_builtin_options in #( 'cannot detect') : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "cannot make $CXX report undeclared builtins See \`config.log' for more details" "$LINENO" 5; } ;; #( 'none needed') : ac_cxx_undeclared_builtin_options='' ;; #( *) : ac_cxx_undeclared_builtin_options=$ac_cv_cxx_undeclared_builtin_options ;; esac ac_fn_check_decl "$LINENO" "strcasecmp" "ac_cv_have_decl_strcasecmp" "$ac_includes_default" "$ac_cxx_undeclared_builtin_options" "CXXFLAGS" if test "x$ac_cv_have_decl_strcasecmp" = xyes then : ac_fn_cxx_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp" if test "x$ac_cv_func_strcasecmp" = xyes then : printf "%s\n" "#define HAVE_STRCASECMP 1" >>confdefs.h fi fi ac_fn_check_decl "$LINENO" "strncasecmp" "ac_cv_have_decl_strncasecmp" "$ac_includes_default" "$ac_cxx_undeclared_builtin_options" "CXXFLAGS" if test "x$ac_cv_have_decl_strncasecmp" = xyes then : ac_fn_cxx_check_func "$LINENO" "strncasecmp" "ac_cv_func_strncasecmp" if test "x$ac_cv_func_strncasecmp" = xyes then : printf "%s\n" "#define HAVE_STRNCASECMP 1" >>confdefs.h fi fi for ac_prog in xa do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_XA+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$XA"; then ac_cv_prog_XA="$XA" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_XA="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi XA=$ac_cv_prog_XA if test -n "$XA"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $XA" >&5 printf "%s\n" "$XA" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$XA" && break done # od on macOS doesn't support the -w parameter { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for od that supports -w" >&5 printf %s "checking for od that supports -w... " >&6; } if test ${ac_cv_path_OD+y} then : printf %s "(cached) " >&6 else $as_nop if test -z "$OD"; then ac_path_OD_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_prog in od god do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_OD="$as_dir$ac_prog$ac_exec_ext" as_fn_executable_p "$ac_path_OD" || continue $ac_path_OD -w > /dev/null 2>&1 && ac_cv_path_OD=$ac_path_OD ac_path_OD_found=: $ac_path_OD_found && break 3 done done done IFS=$as_save_IFS if test -z "$ac_cv_path_OD"; then : fi else ac_cv_path_OD=$OD fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_OD" >&5 printf "%s\n" "$ac_cv_path_OD" >&6; } OD=$ac_cv_path_OD ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 printf %s "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test ${ac_cv_prog_CPP+y} then : printf %s "(cached) " >&6 else $as_nop # Double quotes because $CC needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 printf "%s\n" "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include Syntax error _ACEOF if ac_fn_c_try_cpp "$LINENO" then : else $as_nop # Broken: fails on valid input. continue fi rm -f conftest.err conftest.i conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include _ACEOF if ac_fn_c_try_cpp "$LINENO" then : # Broken: success on invalid input. continue else $as_nop # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.i conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.i conftest.err conftest.$ac_ext if $ac_preproc_ok then : else $as_nop { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details" "$LINENO" 5; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then ax_pthread_save_CC="$CC" ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" if test "x$PTHREAD_CC" != "x" then : CC="$PTHREAD_CC" fi if test "x$PTHREAD_CXX" != "x" then : CXX="$PTHREAD_CXX" fi CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS" >&5 printf %s "checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char pthread_join (); int main (void) { return pthread_join (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ax_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 printf "%s\n" "$ax_pthread_ok" >&6; } if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi CC="$ax_pthread_save_CC" CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items with a "," contain both # C compiler flags (before ",") and linker flags (after ","). Other items # starting with a "-" are C compiler flags, and remaining items are # library names, except for "none" which indicates that we try without # any flags at all, and "pthread-config" which is a program returning # the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 # (Note: HP C rejects this with "bad form for `-t' option") # -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads and # -D_REENTRANT too), HP C (must be checked before -lpthread, which # is present but should not be used directly; and before -mthreads, # because the compiler interprets this as "-mt" + "-hreads") # -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case $host_os in freebsd*) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) ax_pthread_flags="-kthread lthread $ax_pthread_flags" ;; hpux*) # From the cc(1) man page: "[-mt] Sets various -D flags to enable # multi-threading and also sets -lpthread." ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" ;; openedition*) # IBM z/OS requires a feature-test macro to be defined in order to # enable POSIX threads at all, so give the user a hint if this is # not set. (We don't define these ourselves, as they can affect # other portions of the system API in unpredictable ways.) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) AX_PTHREAD_ZOS_MISSING # endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "AX_PTHREAD_ZOS_MISSING" >/dev/null 2>&1 then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&5 printf "%s\n" "$as_me: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&2;} fi rm -rf conftest* ;; solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (N.B.: The stubs are missing # pthread_cleanup_push, or rather a function called by this macro, # so we could check for that, but who knows whether they'll stub # that too in a future libc.) So we'll check first for the # standard Solaris way of linking pthreads (-mt -lpthread). ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" ;; esac # Are we compiling with Clang? { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC is Clang" >&5 printf %s "checking whether $CC is Clang... " >&6; } if test ${ax_cv_PTHREAD_CLANG+y} then : printf %s "(cached) " >&6 else $as_nop ax_cv_PTHREAD_CLANG=no # Note that Autoconf sets GCC=yes for Clang as well as GCC if test "x$GCC" = "xyes"; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Note: Clang 2.7 lacks __clang_[a-z]+__ */ # if defined(__clang__) && defined(__llvm__) AX_PTHREAD_CC_IS_CLANG # endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "AX_PTHREAD_CC_IS_CLANG" >/dev/null 2>&1 then : ax_cv_PTHREAD_CLANG=yes fi rm -rf conftest* fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG" >&5 printf "%s\n" "$ax_cv_PTHREAD_CLANG" >&6; } ax_pthread_clang="$ax_cv_PTHREAD_CLANG" # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) # Note that for GCC and Clang -pthread generally implies -lpthread, # except when -nostdlib is passed. # This is problematic using libtool to build C++ shared libraries with pthread: # [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 # [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 # [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 # To solve this, first try -pthread together with -lpthread for GCC if test "x$GCC" = "xyes" then : ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags" fi # Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first if test "x$ax_pthread_clang" = "xyes" then : ax_pthread_flags="-pthread,-lpthread -pthread" fi # The presence of a feature test macro requesting re-entrant function # definitions is, on some systems, a strong hint that pthreads support is # correctly enabled case $host_os in darwin* | hpux* | linux* | osf* | solaris*) ax_pthread_check_macro="_REENTRANT" ;; aix*) ax_pthread_check_macro="_THREAD_SAFE" ;; *) ax_pthread_check_macro="--" ;; esac if test "x$ax_pthread_check_macro" = "x--" then : ax_pthread_check_cond=0 else $as_nop ax_pthread_check_cond="!defined($ax_pthread_check_macro)" fi if test "x$ax_pthread_ok" = "xno"; then for ax_pthread_try_flag in $ax_pthread_flags; do case $ax_pthread_try_flag in none) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 printf %s "checking whether pthreads work without any flags... " >&6; } ;; *,*) PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with \"$PTHREAD_CFLAGS\" and \"$PTHREAD_LIBS\"" >&5 printf %s "checking whether pthreads work with \"$PTHREAD_CFLAGS\" and \"$PTHREAD_LIBS\"... " >&6; } ;; -*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $ax_pthread_try_flag" >&5 printf %s "checking whether pthreads work with $ax_pthread_try_flag... " >&6; } PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) # Extract the first word of "pthread-config", so it can be a program name with args. set dummy pthread-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ax_pthread_config+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ax_pthread_config"; then ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ax_pthread_config="yes" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no" fi fi ax_pthread_config=$ac_cv_prog_ax_pthread_config if test -n "$ax_pthread_config"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5 printf "%s\n" "$ax_pthread_config" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ax_pthread_config" = "xno" then : continue fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$ax_pthread_try_flag" >&5 printf %s "checking for the pthreads library -l$ax_pthread_try_flag... " >&6; } PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include # if $ax_pthread_check_cond # error "$ax_pthread_check_macro must be defined" # endif static void *some_global = NULL; static void routine(void *a) { /* To avoid any unused-parameter or unused-but-set-parameter warning. */ some_global = a; } static void *start_routine(void *a) { return a; } int main (void) { pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */ ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ax_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 printf "%s\n" "$ax_pthread_ok" >&6; } if test "x$ax_pthread_ok" = "xyes" then : break fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Clang needs special handling, because older versions handle the -pthread # option in a rather... idiosyncratic way if test "x$ax_pthread_clang" = "xyes"; then # Clang takes -pthread; it has never supported any other flag # (Note 1: This will need to be revisited if a system that Clang # supports has POSIX threads in a separate library. This tends not # to be the way of modern systems, but it's conceivable.) # (Note 2: On some systems, notably Darwin, -pthread is not needed # to get POSIX threads support; the API is always present and # active. We could reasonably leave PTHREAD_CFLAGS empty. But # -pthread does define _REENTRANT, and while the Darwin headers # ignore this macro, third-party headers might not.) # However, older versions of Clang make a point of warning the user # that, in an invocation where only linking and no compilation is # taking place, the -pthread option has no effect ("argument unused # during compilation"). They expect -pthread to be passed in only # when source code is being compiled. # # Problem is, this is at odds with the way Automake and most other # C build frameworks function, which is that the same flags used in # compilation (CFLAGS) are also used in linking. Many systems # supported by AX_PTHREAD require exactly this for POSIX threads # support, and in fact it is often not straightforward to specify a # flag that is used only in the compilation phase and not in # linking. Such a scenario is extremely rare in practice. # # Even though use of the -pthread flag in linking would only print # a warning, this can be a nuisance for well-run software projects # that build with -Werror. So if the active version of Clang has # this misfeature, we search for an option to squash it. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread" >&5 printf %s "checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread... " >&6; } if test ${ax_cv_PTHREAD_CLANG_NO_WARN_FLAG+y} then : printf %s "(cached) " >&6 else $as_nop ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown # Create an alternate version of $ac_link that compiles and # links in two steps (.c -> .o, .o -> exe) instead of one # (.c -> exe), because the warning occurs only in the second # step ax_pthread_save_ac_link="$ac_link" ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' ax_pthread_link_step=`printf "%s\n" "$ac_link" | sed "$ax_pthread_sed"` ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" ax_pthread_save_CFLAGS="$CFLAGS" for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do if test "x$ax_pthread_try" = "xunknown" then : break fi CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" ac_link="$ax_pthread_save_ac_link" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void){return 0;} _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_link="$ax_pthread_2step_ac_link" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void){return 0;} _ACEOF if ac_fn_c_try_link "$LINENO" then : break fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext done ac_link="$ax_pthread_save_ac_link" CFLAGS="$ax_pthread_save_CFLAGS" if test "x$ax_pthread_try" = "x" then : ax_pthread_try=no fi ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&5 printf "%s\n" "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&6; } case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in no | unknown) ;; *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; esac fi # $ax_pthread_clang = yes # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 printf %s "checking for joinable pthread attribute... " >&6; } if test ${ax_cv_PTHREAD_JOINABLE_ATTR+y} then : printf %s "(cached) " >&6 else $as_nop ax_cv_PTHREAD_JOINABLE_ATTR=unknown for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { int attr = $ax_pthread_attr; return attr /* ; */ ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_JOINABLE_ATTR" >&5 printf "%s\n" "$ax_cv_PTHREAD_JOINABLE_ATTR" >&6; } if test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ test "x$ax_pthread_joinable_attr_defined" != "xyes" then : printf "%s\n" "#define PTHREAD_CREATE_JOINABLE $ax_cv_PTHREAD_JOINABLE_ATTR" >>confdefs.h ax_pthread_joinable_attr_defined=yes fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether more special flags are required for pthreads" >&5 printf %s "checking whether more special flags are required for pthreads... " >&6; } if test ${ax_cv_PTHREAD_SPECIAL_FLAGS+y} then : printf %s "(cached) " >&6 else $as_nop ax_cv_PTHREAD_SPECIAL_FLAGS=no case $host_os in solaris*) ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_SPECIAL_FLAGS" >&5 printf "%s\n" "$ax_cv_PTHREAD_SPECIAL_FLAGS" >&6; } if test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ test "x$ax_pthread_special_flags_added" != "xyes" then : PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" ax_pthread_special_flags_added=yes fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5 printf %s "checking for PTHREAD_PRIO_INHERIT... " >&6; } if test ${ax_cv_PTHREAD_PRIO_INHERIT+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { int i = PTHREAD_PRIO_INHERIT; return i; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ax_cv_PTHREAD_PRIO_INHERIT=yes else $as_nop ax_cv_PTHREAD_PRIO_INHERIT=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5 printf "%s\n" "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; } if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ test "x$ax_pthread_prio_inherit_defined" != "xyes" then : printf "%s\n" "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h ax_pthread_prio_inherit_defined=yes fi CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" # More AIX lossage: compile with *_r variant if test "x$GCC" != "xyes"; then case $host_os in aix*) case "x/$CC" in #( x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6) : #handle absolute path differently from PATH based program lookup case "x$CC" in #( x/*) : if as_fn_executable_p ${CC}_r then : PTHREAD_CC="${CC}_r" fi if test "x${CXX}" != "x" then : if as_fn_executable_p ${CXX}_r then : PTHREAD_CXX="${CXX}_r" fi fi ;; #( *) : for ac_prog in ${CC}_r do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_PTHREAD_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$PTHREAD_CC"; then ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_PTHREAD_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PTHREAD_CC=$ac_cv_prog_PTHREAD_CC if test -n "$PTHREAD_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 printf "%s\n" "$PTHREAD_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$PTHREAD_CC" && break done test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" if test "x${CXX}" != "x" then : for ac_prog in ${CXX}_r do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_PTHREAD_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$PTHREAD_CXX"; then ac_cv_prog_PTHREAD_CXX="$PTHREAD_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_PTHREAD_CXX="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PTHREAD_CXX=$ac_cv_prog_PTHREAD_CXX if test -n "$PTHREAD_CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CXX" >&5 printf "%s\n" "$PTHREAD_CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$PTHREAD_CXX" && break done test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" fi ;; esac ;; #( *) : ;; esac ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then printf "%s\n" "#define HAVE_PTHREAD 1" >>confdefs.h : else ax_pthread_ok=no as_fn_error $? "\"pthreads not found\"" "$LINENO" 5 fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu # # https://autotools.io/libtool/version.html # # Always increase the revision value. # # Increase the current value whenever an interface has been added, removed or changed. # # Increase the age value only if the changes made to the ABI are backward compatible. LIBSIDPLAYCUR=14 LIBSIDPLAYREV=46 LIBSIDPLAYAGE=7 LIBSIDPLAYVERSION=$LIBSIDPLAYCUR:$LIBSIDPLAYREV:$LIBSIDPLAYAGE LIBSTILVIEWCUR=0 LIBSTILVIEWREV=8 LIBSTILVIEWAGE=0 LIBSTILVIEWVERSION=$LIBSTILVIEWCUR:$LIBSTILVIEWREV:$LIBSTILVIEWAGE { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for debugging" >&5 printf %s "checking for debugging... " >&6; } # Check whether --enable-debug was given. if test ${enable_debug+y} then : enableval=$enable_debug; else $as_nop enable_debug=no fi if test "x$enable_debug" = "xno" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Build without debugging messages" >&5 printf "%s\n" "Build without debugging messages" >&6; }; debug_flags=-DNDEBUG else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Build with debugging messages" >&5 printf "%s\n" "Build with debugging messages" >&6; }; debug_flags="" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for __builtin_expect" >&5 printf %s "checking for __builtin_expect... " >&6; } if test ${sid_cv_builtin_expect+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main() { __builtin_expect(0, 0); } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : sid_cv_builtin_expect=yes else $as_nop sid_cv_builtin_expect=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $sid_cv_builtin_expect" >&5 printf "%s\n" "$sid_cv_builtin_expect" >&6; } if test "$sid_cv_builtin_expect" = no then : HAVE_BUILTIN_EXPECT=0 else $as_nop HAVE_BUILTIN_EXPECT=1 fi # Check whether --enable-lto was given. if test ${enable_lto+y} then : enableval=$enable_lto; fi if test "x$enable_lto" = "xyes" then : for flag in -flto; do as_CACHEVAR=`printf "%s\n" "ax_cv_check_cxxflags__$flag" | $as_tr_sh` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C++ compiler accepts $flag" >&5 printf %s "checking whether the C++ compiler accepts $flag... " >&6; } if eval test \${$as_CACHEVAR+y} then : printf %s "(cached) " >&6 else $as_nop ax_check_save_flags=$CXXFLAGS if test x"$GXX" = xyes ; then add_gnu_werror="-Werror" fi CXXFLAGS="$CXXFLAGS $flag $add_gnu_werror" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main (void) { ; return 0; } _ACEOF if ac_fn_cxx_try_compile "$LINENO" then : eval "$as_CACHEVAR=yes" else $as_nop eval "$as_CACHEVAR=no" fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext CXXFLAGS=$ax_check_save_flags fi eval ac_res=\$$as_CACHEVAR { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 printf "%s\n" "$ac_res" >&6; } if eval test \"x\$"$as_CACHEVAR"\" = x"yes" then : if test ${CXXFLAGS+y} then : case " $CXXFLAGS " in #( *" $flag "*) : { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CXXFLAGS already contains \$flag"; } >&5 (: CXXFLAGS already contains $flag) 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } ;; #( *) : as_fn_append CXXFLAGS " $flag" { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS\""; } >&5 (: CXXFLAGS="$CXXFLAGS") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } ;; esac else $as_nop CXXFLAGS=$flag { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: : CXXFLAGS=\"\$CXXFLAGS\""; } >&5 (: CXXFLAGS="$CXXFLAGS") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; } fi else $as_nop : fi done fi for ac_prog in doxygen do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DOXYGEN+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DOXYGEN"; then ac_cv_prog_DOXYGEN="$DOXYGEN" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DOXYGEN="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi DOXYGEN=$ac_cv_prog_DOXYGEN if test -n "$DOXYGEN"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DOXYGEN" >&5 printf "%s\n" "$DOXYGEN" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$DOXYGEN" && break done if test -z "$DOXYGEN" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Doxygen not found - continuing without Doxygen support" >&5 printf "%s\n" "$as_me: WARNING: Doxygen not found - continuing without Doxygen support" >&2;} else $as_nop # Extract the first word of "dot", so it can be a program name with args. set dummy dot; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_DOT+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$DOT"; then ac_cv_prog_DOT="$DOT" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_DOT="YES" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_DOT" && ac_cv_prog_DOT="NO" fi fi DOT=$ac_cv_prog_DOT if test -n "$DOT"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $DOT" >&5 printf "%s\n" "$DOT" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -n "$DOXYGEN"; then HAVE_DOXYGEN_TRUE= HAVE_DOXYGEN_FALSE='#' else HAVE_DOXYGEN_TRUE='#' HAVE_DOXYGEN_FALSE= fi if test -z "$HAVE_DOXYGEN_TRUE"; then : ac_config_files="$ac_config_files Doxyfile" fi # Check whether --enable-testsuite was given. if test ${enable_testsuite+y} then : enableval=$enable_testsuite; else $as_nop enable_testsuite=no fi if test "x$enable_testsuite" != xno then : printf "%s\n" "#define VICE_TESTSUITE \"$enable_testsuite\"" >>confdefs.h fi if test "x$enable_testsuite" != xno; then TESTSUITE_TRUE= TESTSUITE_FALSE='#' else TESTSUITE_TRUE='#' TESTSUITE_FALSE= fi if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args. set dummy ${ac_tool_prefix}pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5 printf "%s\n" "$PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi fi if test -z "$ac_cv_path_PKG_CONFIG"; then ac_pt_PKG_CONFIG=$PKG_CONFIG # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_path_ac_pt_PKG_CONFIG+y} then : printf %s "(cached) " >&6 else $as_nop case $ac_pt_PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_path_ac_pt_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS ;; esac fi ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG if test -n "$ac_pt_PKG_CONFIG"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5 printf "%s\n" "$ac_pt_PKG_CONFIG" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ac_pt_PKG_CONFIG" = x; then PKG_CONFIG="" else case $cross_compiling:$ac_tool_warned in yes:) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac PKG_CONFIG=$ac_pt_PKG_CONFIG fi else PKG_CONFIG="$ac_cv_path_PKG_CONFIG" fi fi if test -n "$PKG_CONFIG"; then _pkg_min_version=0.9.0 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking pkg-config is at least version $_pkg_min_version" >&5 printf %s "checking pkg-config is at least version $_pkg_min_version... " >&6; } if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } PKG_CONFIG="" fi fi # Check whether --enable-tests was given. if test ${enable_tests+y} then : enableval=$enable_tests; else $as_nop enable_tests=no fi if test x$enable_tests = xyes; then ENABLE_TEST_TRUE= ENABLE_TEST_FALSE='#' else ENABLE_TEST_TRUE='#' ENABLE_TEST_FALSE= fi pkg_failed=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libresidfp >= 1.0.0" >&5 printf %s "checking for libresidfp >= 1.0.0... " >&6; } if test -n "$RESIDFP_CFLAGS"; then pkg_cv_RESIDFP_CFLAGS="$RESIDFP_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libresidfp >= 1.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "libresidfp >= 1.0.0") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_RESIDFP_CFLAGS=`$PKG_CONFIG --cflags "libresidfp >= 1.0.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$RESIDFP_LIBS"; then pkg_cv_RESIDFP_LIBS="$RESIDFP_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libresidfp >= 1.0.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "libresidfp >= 1.0.0") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_RESIDFP_LIBS=`$PKG_CONFIG --libs "libresidfp >= 1.0.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then RESIDFP_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libresidfp >= 1.0.0" 2>&1` else RESIDFP_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libresidfp >= 1.0.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$RESIDFP_PKG_ERRORS" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $RESIDFP_PKG_ERRORS" >&5 printf "%s\n" "$as_me: WARNING: $RESIDFP_PKG_ERRORS" >&2;} elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $RESIDFP_PKG_ERRORS" >&5 printf "%s\n" "$as_me: WARNING: $RESIDFP_PKG_ERRORS" >&2;} else RESIDFP_CFLAGS=$pkg_cv_RESIDFP_CFLAGS RESIDFP_LIBS=$pkg_cv_RESIDFP_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } printf "%s\n" "#define HAVE_RESIDFP 1" >>confdefs.h fi if test "x$pkg_cv_RESIDFP_LIBS" != x ; then RESIDFP_SUPPORT_TRUE= RESIDFP_SUPPORT_FALSE='#' else RESIDFP_SUPPORT_TRUE='#' RESIDFP_SUPPORT_FALSE= fi # USBSID support # Check whether --with-usbsid was given. if test ${with_usbsid+y} then : withval=$with_usbsid; else $as_nop with_usbsid=check fi # USBSID support requires libusb if test "x$with_usbsid" != "xno" then : pkg_failed=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libusb-1.0" >&5 printf %s "checking for libusb-1.0... " >&6; } if test -n "$USBSID_CFLAGS"; then pkg_cv_USBSID_CFLAGS="$USBSID_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb-1.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "libusb-1.0") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_USBSID_CFLAGS=`$PKG_CONFIG --cflags "libusb-1.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$USBSID_LIBS"; then pkg_cv_USBSID_LIBS="$USBSID_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libusb-1.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "libusb-1.0") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_USBSID_LIBS=`$PKG_CONFIG --libs "libusb-1.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then USBSID_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libusb-1.0" 2>&1` else USBSID_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libusb-1.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$USBSID_PKG_ERRORS" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $USBSID_PKG_ERRORS - checking for libusb header" >&5 printf "%s\n" "$as_me: WARNING: $USBSID_PKG_ERRORS - checking for libusb header" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libusb-1.0" >&5 printf %s "checking for libusb-1.0... " >&6; } for ac_header in libusb-1.0/libusb.h do : ac_fn_cxx_check_header_compile "$LINENO" "libusb-1.0/libusb.h" "ac_cv_header_libusb_1_0_libusb_h" "$ac_includes_default" if test "x$ac_cv_header_libusb_1_0_libusb_h" = xyes then : printf "%s\n" "#define HAVE_LIBUSB_1_0_LIBUSB_H 1" >>confdefs.h printf "%s\n" "#define HAVE_LIBUSB 1" >>confdefs.h build_usbsid_builder=yes build_usbsid_driver=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: libsub.h not found, support will not be available" >&5 printf "%s\n" "$as_me: WARNING: libsub.h not found, support will not be available" >&2;} fi done elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $USBSID_PKG_ERRORS - checking for libusb header" >&5 printf "%s\n" "$as_me: WARNING: $USBSID_PKG_ERRORS - checking for libusb header" >&2;} { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libusb-1.0" >&5 printf %s "checking for libusb-1.0... " >&6; } for ac_header in libusb-1.0/libusb.h do : ac_fn_cxx_check_header_compile "$LINENO" "libusb-1.0/libusb.h" "ac_cv_header_libusb_1_0_libusb_h" "$ac_includes_default" if test "x$ac_cv_header_libusb_1_0_libusb_h" = xyes then : printf "%s\n" "#define HAVE_LIBUSB_1_0_LIBUSB_H 1" >>confdefs.h printf "%s\n" "#define HAVE_LIBUSB 1" >>confdefs.h build_usbsid_builder=yes build_usbsid_driver=yes { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: libsub.h not found, support will not be available" >&5 printf "%s\n" "$as_me: WARNING: libsub.h not found, support will not be available" >&2;} fi done else USBSID_CFLAGS=$pkg_cv_USBSID_CFLAGS USBSID_LIBS=$pkg_cv_USBSID_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } printf "%s\n" "#define HAVE_USBSID 1" >>confdefs.h build_usbsid_builder=yes build_usbsid_driver=yes fi fi if test "x$with_usbsid" = "xyes" -a "x$build_usbsid_builder" != xyes then : as_fn_error $? "libusb not found" "$LINENO" 5 fi if test "x${build_usbsid_builder}" = xyes; then USBSID_SUPPORT_TRUE= USBSID_SUPPORT_FALSE='#' else USBSID_SUPPORT_TRUE='#' USBSID_SUPPORT_FALSE= fi if test "x${build_usbsid_driver}" = xyes; then USBSID_DRIVER_TRUE= USBSID_DRIVER_FALSE='#' else USBSID_DRIVER_TRUE='#' USBSID_DRIVER_FALSE= fi # exSID support # Check whether --with-exsid was given. if test ${with_exsid+y} then : withval=$with_exsid; else $as_nop with_exsid=check fi # exSID support requires either libexsid or one of libfdti1 or libftd2xx if test "x$with_exsid" != "xno" then : pkg_failed=no { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libexsid >= 2.0" >&5 printf %s "checking for libexsid >= 2.0... " >&6; } if test -n "$EXSID_CFLAGS"; then pkg_cv_EXSID_CFLAGS="$EXSID_CFLAGS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libexsid >= 2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "libexsid >= 2.0") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_EXSID_CFLAGS=`$PKG_CONFIG --cflags "libexsid >= 2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test -n "$EXSID_LIBS"; then pkg_cv_EXSID_LIBS="$EXSID_LIBS" elif test -n "$PKG_CONFIG"; then if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libexsid >= 2.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "libexsid >= 2.0") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then pkg_cv_EXSID_LIBS=`$PKG_CONFIG --libs "libexsid >= 2.0" 2>/dev/null` test "x$?" != "x0" && pkg_failed=yes else pkg_failed=yes fi else pkg_failed=untried fi if test $pkg_failed = yes; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then _pkg_short_errors_supported=yes else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then EXSID_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libexsid >= 2.0" 2>&1` else EXSID_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libexsid >= 2.0" 2>&1` fi # Put the nasty error message in config.log where it belongs echo "$EXSID_PKG_ERRORS" >&5 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $EXSID_PKG_ERRORS - using internal driver" >&5 printf "%s\n" "$as_me: WARNING: $EXSID_PKG_ERRORS - using internal driver" >&2;} if test "x$MINGW32" != "xyes" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 printf %s "checking for library containing dlopen... " >&6; } if test ${ac_cv_search_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int dlopen (); } int main (void) { return conftest::dlopen (); ; return 0; } _ACEOF for ac_lib in '' dl dld do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_cxx_try_link "$LINENO" then : ac_cv_search_dlopen=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_dlopen+y} then : break fi done if test ${ac_cv_search_dlopen+y} then : else $as_nop ac_cv_search_dlopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 printf "%s\n" "$ac_cv_search_dlopen" >&6; } ac_res=$ac_cv_search_dlopen if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else $as_nop as_fn_error $? "unable to find the dlopen() function" "$LINENO" 5 fi fi for ac_header in ftd2xx.h do : ac_fn_cxx_check_header_compile "$LINENO" "ftd2xx.h" "ac_cv_header_ftd2xx_h" "$ac_includes_default" if test "x$ac_cv_header_ftd2xx_h" = xyes then : printf "%s\n" "#define HAVE_FTD2XX_H 1" >>confdefs.h printf "%s\n" "#define HAVE_FTD2XX 1" >>confdefs.h build_exsid_builder=yes build_exsid_driver=yes else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: ftd2xx.h not found, support will not be available" >&5 printf "%s\n" "$as_me: WARNING: ftd2xx.h not found, support will not be available" >&2;} fi done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libftdi1" >&5 printf %s "checking for libftdi1... " >&6; } if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libftdi1 >= 1.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "libftdi1 >= 1.0") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then printf "%s\n" "#define HAVE_FTDI 1" >>confdefs.h build_exsid_builder=yes build_exsid_driver=yes FTDI_CFLAGS=`$PKG_CONFIG --cflags libftdi1` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: libftdi1 not found, support will not be available" >&5 printf "%s\n" "$as_me: WARNING: libftdi1 not found, support will not be available" >&2;} fi elif test $pkg_failed = untried; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $EXSID_PKG_ERRORS - using internal driver" >&5 printf "%s\n" "$as_me: WARNING: $EXSID_PKG_ERRORS - using internal driver" >&2;} if test "x$MINGW32" != "xyes" then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 printf %s "checking for library containing dlopen... " >&6; } if test ${ac_cv_search_dlopen+y} then : printf %s "(cached) " >&6 else $as_nop ac_func_search_save_LIBS=$LIBS cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ namespace conftest { extern "C" int dlopen (); } int main (void) { return conftest::dlopen (); ; return 0; } _ACEOF for ac_lib in '' dl dld do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi if ac_fn_cxx_try_link "$LINENO" then : ac_cv_search_dlopen=$ac_res fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext if test ${ac_cv_search_dlopen+y} then : break fi done if test ${ac_cv_search_dlopen+y} then : else $as_nop ac_cv_search_dlopen=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 printf "%s\n" "$ac_cv_search_dlopen" >&6; } ac_res=$ac_cv_search_dlopen if test "$ac_res" != no then : test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else $as_nop as_fn_error $? "unable to find the dlopen() function" "$LINENO" 5 fi fi for ac_header in ftd2xx.h do : ac_fn_cxx_check_header_compile "$LINENO" "ftd2xx.h" "ac_cv_header_ftd2xx_h" "$ac_includes_default" if test "x$ac_cv_header_ftd2xx_h" = xyes then : printf "%s\n" "#define HAVE_FTD2XX_H 1" >>confdefs.h printf "%s\n" "#define HAVE_FTD2XX 1" >>confdefs.h build_exsid_builder=yes build_exsid_driver=yes else $as_nop { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: ftd2xx.h not found, support will not be available" >&5 printf "%s\n" "$as_me: WARNING: ftd2xx.h not found, support will not be available" >&2;} fi done { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libftdi1" >&5 printf %s "checking for libftdi1... " >&6; } if test -n "$PKG_CONFIG" && \ { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$PKG_CONFIG --exists --print-errors \"libftdi1 >= 1.0\""; } >&5 ($PKG_CONFIG --exists --print-errors "libftdi1 >= 1.0") 2>&5 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then printf "%s\n" "#define HAVE_FTDI 1" >>confdefs.h build_exsid_builder=yes build_exsid_driver=yes FTDI_CFLAGS=`$PKG_CONFIG --cflags libftdi1` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: libftdi1 not found, support will not be available" >&5 printf "%s\n" "$as_me: WARNING: libftdi1 not found, support will not be available" >&2;} fi else EXSID_CFLAGS=$pkg_cv_EXSID_CFLAGS EXSID_LIBS=$pkg_cv_EXSID_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } printf "%s\n" "#define HAVE_EXSID 1" >>confdefs.h build_exsid_builder=yes fi fi if test "x$with_exsid" = "xyes" -a "x$build_exsid_builder" != xyes then : as_fn_error $? "Neither libexsid nor ftd2xx nor libftdi1 found" "$LINENO" 5 fi if test "x${build_exsid_builder}" = xyes; then EXSID_SUPPORT_TRUE= EXSID_SUPPORT_FALSE='#' else EXSID_SUPPORT_TRUE='#' EXSID_SUPPORT_FALSE= fi if test "x${build_exsid_driver}" = xyes; then EXSID_DRIVER_TRUE= EXSID_DRIVER_FALSE='#' else EXSID_DRIVER_TRUE='#' EXSID_DRIVER_FALSE= fi # check for thread model if available if test "x$build_exsid_driver" = xyes then : ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then ax_pthread_save_CC="$CC" ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" if test "x$PTHREAD_CC" != "x" then : CC="$PTHREAD_CC" fi if test "x$PTHREAD_CXX" != "x" then : CXX="$PTHREAD_CXX" fi CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS" >&5 printf %s "checking for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS... " >&6; } cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ char pthread_join (); int main (void) { return pthread_join (); ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ax_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 printf "%s\n" "$ax_pthread_ok" >&6; } if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi CC="$ax_pthread_save_CC" CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items with a "," contain both # C compiler flags (before ",") and linker flags (after ","). Other items # starting with a "-" are C compiler flags, and remaining items are # library names, except for "none" which indicates that we try without # any flags at all, and "pthread-config" which is a program returning # the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 # (Note: HP C rejects this with "bad form for `-t' option") # -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads and # -D_REENTRANT too), HP C (must be checked before -lpthread, which # is present but should not be used directly; and before -mthreads, # because the compiler interprets this as "-mt" + "-hreads") # -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case $host_os in freebsd*) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) ax_pthread_flags="-kthread lthread $ax_pthread_flags" ;; hpux*) # From the cc(1) man page: "[-mt] Sets various -D flags to enable # multi-threading and also sets -lpthread." ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" ;; openedition*) # IBM z/OS requires a feature-test macro to be defined in order to # enable POSIX threads at all, so give the user a hint if this is # not set. (We don't define these ourselves, as they can affect # other portions of the system API in unpredictable ways.) cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ # if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) AX_PTHREAD_ZOS_MISSING # endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "AX_PTHREAD_ZOS_MISSING" >/dev/null 2>&1 then : { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&5 printf "%s\n" "$as_me: WARNING: IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support." >&2;} fi rm -rf conftest* ;; solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (N.B.: The stubs are missing # pthread_cleanup_push, or rather a function called by this macro, # so we could check for that, but who knows whether they'll stub # that too in a future libc.) So we'll check first for the # standard Solaris way of linking pthreads (-mt -lpthread). ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" ;; esac # Are we compiling with Clang? { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC is Clang" >&5 printf %s "checking whether $CC is Clang... " >&6; } if test ${ax_cv_PTHREAD_CLANG+y} then : printf %s "(cached) " >&6 else $as_nop ax_cv_PTHREAD_CLANG=no # Note that Autoconf sets GCC=yes for Clang as well as GCC if test "x$GCC" = "xyes"; then cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ /* Note: Clang 2.7 lacks __clang_[a-z]+__ */ # if defined(__clang__) && defined(__llvm__) AX_PTHREAD_CC_IS_CLANG # endif _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "AX_PTHREAD_CC_IS_CLANG" >/dev/null 2>&1 then : ax_cv_PTHREAD_CLANG=yes fi rm -rf conftest* fi fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG" >&5 printf "%s\n" "$ax_cv_PTHREAD_CLANG" >&6; } ax_pthread_clang="$ax_cv_PTHREAD_CLANG" # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) # Note that for GCC and Clang -pthread generally implies -lpthread, # except when -nostdlib is passed. # This is problematic using libtool to build C++ shared libraries with pthread: # [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 # [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 # [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 # To solve this, first try -pthread together with -lpthread for GCC if test "x$GCC" = "xyes" then : ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags" fi # Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first if test "x$ax_pthread_clang" = "xyes" then : ax_pthread_flags="-pthread,-lpthread -pthread" fi # The presence of a feature test macro requesting re-entrant function # definitions is, on some systems, a strong hint that pthreads support is # correctly enabled case $host_os in darwin* | hpux* | linux* | osf* | solaris*) ax_pthread_check_macro="_REENTRANT" ;; aix*) ax_pthread_check_macro="_THREAD_SAFE" ;; *) ax_pthread_check_macro="--" ;; esac if test "x$ax_pthread_check_macro" = "x--" then : ax_pthread_check_cond=0 else $as_nop ax_pthread_check_cond="!defined($ax_pthread_check_macro)" fi if test "x$ax_pthread_ok" = "xno"; then for ax_pthread_try_flag in $ax_pthread_flags; do case $ax_pthread_try_flag in none) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5 printf %s "checking whether pthreads work without any flags... " >&6; } ;; *,*) PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with \"$PTHREAD_CFLAGS\" and \"$PTHREAD_LIBS\"" >&5 printf %s "checking whether pthreads work with \"$PTHREAD_CFLAGS\" and \"$PTHREAD_LIBS\"... " >&6; } ;; -*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $ax_pthread_try_flag" >&5 printf %s "checking whether pthreads work with $ax_pthread_try_flag... " >&6; } PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) # Extract the first word of "pthread-config", so it can be a program name with args. set dummy pthread-config; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_ax_pthread_config+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$ax_pthread_config"; then ac_cv_prog_ax_pthread_config="$ax_pthread_config" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_ax_pthread_config="yes" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_prog_ax_pthread_config" && ac_cv_prog_ax_pthread_config="no" fi fi ax_pthread_config=$ac_cv_prog_ax_pthread_config if test -n "$ax_pthread_config"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_config" >&5 printf "%s\n" "$ax_pthread_config" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi if test "x$ax_pthread_config" = "xno" then : continue fi PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$ax_pthread_try_flag" >&5 printf %s "checking for the pthreads library -l$ax_pthread_try_flag... " >&6; } PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include # if $ax_pthread_check_cond # error "$ax_pthread_check_macro must be defined" # endif static void *some_global = NULL; static void routine(void *a) { /* To avoid any unused-parameter or unused-but-set-parameter warning. */ some_global = a; } static void *start_routine(void *a) { return a; } int main (void) { pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */ ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ax_pthread_ok=yes fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_pthread_ok" >&5 printf "%s\n" "$ax_pthread_ok" >&6; } if test "x$ax_pthread_ok" = "xyes" then : break fi PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Clang needs special handling, because older versions handle the -pthread # option in a rather... idiosyncratic way if test "x$ax_pthread_clang" = "xyes"; then # Clang takes -pthread; it has never supported any other flag # (Note 1: This will need to be revisited if a system that Clang # supports has POSIX threads in a separate library. This tends not # to be the way of modern systems, but it's conceivable.) # (Note 2: On some systems, notably Darwin, -pthread is not needed # to get POSIX threads support; the API is always present and # active. We could reasonably leave PTHREAD_CFLAGS empty. But # -pthread does define _REENTRANT, and while the Darwin headers # ignore this macro, third-party headers might not.) # However, older versions of Clang make a point of warning the user # that, in an invocation where only linking and no compilation is # taking place, the -pthread option has no effect ("argument unused # during compilation"). They expect -pthread to be passed in only # when source code is being compiled. # # Problem is, this is at odds with the way Automake and most other # C build frameworks function, which is that the same flags used in # compilation (CFLAGS) are also used in linking. Many systems # supported by AX_PTHREAD require exactly this for POSIX threads # support, and in fact it is often not straightforward to specify a # flag that is used only in the compilation phase and not in # linking. Such a scenario is extremely rare in practice. # # Even though use of the -pthread flag in linking would only print # a warning, this can be a nuisance for well-run software projects # that build with -Werror. So if the active version of Clang has # this misfeature, we search for an option to squash it. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread" >&5 printf %s "checking whether Clang needs flag to prevent \"argument unused\" warning when linking with -pthread... " >&6; } if test ${ax_cv_PTHREAD_CLANG_NO_WARN_FLAG+y} then : printf %s "(cached) " >&6 else $as_nop ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown # Create an alternate version of $ac_link that compiles and # links in two steps (.c -> .o, .o -> exe) instead of one # (.c -> exe), because the warning occurs only in the second # step ax_pthread_save_ac_link="$ac_link" ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' ax_pthread_link_step=`printf "%s\n" "$ac_link" | sed "$ax_pthread_sed"` ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" ax_pthread_save_CFLAGS="$CFLAGS" for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do if test "x$ax_pthread_try" = "xunknown" then : break fi CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" ac_link="$ax_pthread_save_ac_link" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void){return 0;} _ACEOF if ac_fn_c_try_link "$LINENO" then : ac_link="$ax_pthread_2step_ac_link" cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ int main(void){return 0;} _ACEOF if ac_fn_c_try_link "$LINENO" then : break fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext done ac_link="$ax_pthread_save_ac_link" CFLAGS="$ax_pthread_save_CFLAGS" if test "x$ax_pthread_try" = "x" then : ax_pthread_try=no fi ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&5 printf "%s\n" "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" >&6; } case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in no | unknown) ;; *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; esac fi # $ax_pthread_clang = yes # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5 printf %s "checking for joinable pthread attribute... " >&6; } if test ${ax_cv_PTHREAD_JOINABLE_ATTR+y} then : printf %s "(cached) " >&6 else $as_nop ax_cv_PTHREAD_JOINABLE_ATTR=unknown for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { int attr = $ax_pthread_attr; return attr /* ; */ ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext done fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_JOINABLE_ATTR" >&5 printf "%s\n" "$ax_cv_PTHREAD_JOINABLE_ATTR" >&6; } if test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ test "x$ax_pthread_joinable_attr_defined" != "xyes" then : printf "%s\n" "#define PTHREAD_CREATE_JOINABLE $ax_cv_PTHREAD_JOINABLE_ATTR" >>confdefs.h ax_pthread_joinable_attr_defined=yes fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether more special flags are required for pthreads" >&5 printf %s "checking whether more special flags are required for pthreads... " >&6; } if test ${ax_cv_PTHREAD_SPECIAL_FLAGS+y} then : printf %s "(cached) " >&6 else $as_nop ax_cv_PTHREAD_SPECIAL_FLAGS=no case $host_os in solaris*) ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" ;; esac fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_SPECIAL_FLAGS" >&5 printf "%s\n" "$ax_cv_PTHREAD_SPECIAL_FLAGS" >&6; } if test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ test "x$ax_pthread_special_flags_added" != "xyes" then : PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" ax_pthread_special_flags_added=yes fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PTHREAD_PRIO_INHERIT" >&5 printf %s "checking for PTHREAD_PRIO_INHERIT... " >&6; } if test ${ax_cv_PTHREAD_PRIO_INHERIT+y} then : printf %s "(cached) " >&6 else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include int main (void) { int i = PTHREAD_PRIO_INHERIT; return i; ; return 0; } _ACEOF if ac_fn_c_try_link "$LINENO" then : ax_cv_PTHREAD_PRIO_INHERIT=yes else $as_nop ax_cv_PTHREAD_PRIO_INHERIT=no fi rm -f core conftest.err conftest.$ac_objext conftest.beam \ conftest$ac_exeext conftest.$ac_ext fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ax_cv_PTHREAD_PRIO_INHERIT" >&5 printf "%s\n" "$ax_cv_PTHREAD_PRIO_INHERIT" >&6; } if test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ test "x$ax_pthread_prio_inherit_defined" != "xyes" then : printf "%s\n" "#define HAVE_PTHREAD_PRIO_INHERIT 1" >>confdefs.h ax_pthread_prio_inherit_defined=yes fi CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" # More AIX lossage: compile with *_r variant if test "x$GCC" != "xyes"; then case $host_os in aix*) case "x/$CC" in #( x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6) : #handle absolute path differently from PATH based program lookup case "x$CC" in #( x/*) : if as_fn_executable_p ${CC}_r then : PTHREAD_CC="${CC}_r" fi if test "x${CXX}" != "x" then : if as_fn_executable_p ${CXX}_r then : PTHREAD_CXX="${CXX}_r" fi fi ;; #( *) : for ac_prog in ${CC}_r do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_PTHREAD_CC+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$PTHREAD_CC"; then ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_PTHREAD_CC="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PTHREAD_CC=$ac_cv_prog_PTHREAD_CC if test -n "$PTHREAD_CC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5 printf "%s\n" "$PTHREAD_CC" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$PTHREAD_CC" && break done test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" if test "x${CXX}" != "x" then : for ac_prog in ${CXX}_r do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 printf %s "checking for $ac_word... " >&6; } if test ${ac_cv_prog_PTHREAD_CXX+y} then : printf %s "(cached) " >&6 else $as_nop if test -n "$PTHREAD_CXX"; then ac_cv_prog_PTHREAD_CXX="$PTHREAD_CXX" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac for ac_exec_ext in '' $ac_executable_extensions; do if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then ac_cv_prog_PTHREAD_CXX="$ac_prog" printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi PTHREAD_CXX=$ac_cv_prog_PTHREAD_CXX if test -n "$PTHREAD_CXX"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CXX" >&5 printf "%s\n" "$PTHREAD_CXX" >&6; } else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } fi test -n "$PTHREAD_CXX" && break done test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" fi ;; esac ;; #( *) : ;; esac ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then printf "%s\n" "#define EXSID_THREADED 1" >>confdefs.h printf "%s\n" "#define HAVE_PTHREAD_H 1" >>confdefs.h : else ax_pthread_ok=no fi ac_ext=cpp ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_cxx_compiler_gnu fi eval loadable_shrext=$shrext_cmds printf "%s\n" "#define SHLIBEXT \"${loadable_shrext}\"" >>confdefs.h # for demo DEMO_HEADERS=1 for ac_header in fcntl.h sys/soundcard.h sys/ioctl.h unistd.h do : as_ac_Header=`printf "%s\n" "ac_cv_header_$ac_header" | $as_tr_sh` ac_fn_cxx_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" if eval test \"x\$"$as_ac_Header"\" = x"yes" then : cat >>confdefs.h <<_ACEOF #define `printf "%s\n" "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF else $as_nop DEMO_HEADERS=0 fi done if test "$DEMO_HEADERS" -eq 1; then BUILD_DEMO_TRUE= BUILD_DEMO_FALSE='#' else BUILD_DEMO_TRUE='#' BUILD_DEMO_FALSE= fi ac_config_files="$ac_config_files Makefile libsidplayfp.pc libstilview.pc src/sidplayfp/sidversion.h src/builders/sidlite-builder/sidlite/sl_defs.h tests/Makefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) { eval $ac_var=; unset $ac_var;} ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes: double-quote # substitution turns \\\\ into \\, and sed turns \\ into \. sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then if test "x$cache_file" != "x/dev/null"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 printf "%s\n" "$as_me: updating cache $cache_file" >&6;} if test ! -f "$cache_file" || test -h "$cache_file"; then cat confcache >"$cache_file" else case $cache_file in #( */* | ?:*) mv -f confcache "$cache_file"$$ && mv -f "$cache_file"$$ "$cache_file" ;; #( *) mv -f confcache "$cache_file" ;; esac fi fi else { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= U= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5 printf %s "checking that generated files are newer than configure... " >&6; } if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5 printf "%s\n" "done" >&6; } if test -n "$EXEEXT"; then am__EXEEXT_TRUE= am__EXEEXT_FALSE='#' else am__EXEEXT_TRUE='#' am__EXEEXT_FALSE= fi if test -z "${MINGW32_TRUE}" && test -z "${MINGW32_FALSE}"; then as_fn_error $? "conditional \"MINGW32\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${MACOS_TRUE}" && test -z "${MACOS_FALSE}"; then as_fn_error $? "conditional \"MACOS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then as_fn_error $? "conditional \"AMDEP\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCC\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then as_fn_error $? "conditional \"am__fastdepCXX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${HAVE_DOXYGEN_TRUE}" && test -z "${HAVE_DOXYGEN_FALSE}"; then as_fn_error $? "conditional \"HAVE_DOXYGEN\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${TESTSUITE_TRUE}" && test -z "${TESTSUITE_FALSE}"; then as_fn_error $? "conditional \"TESTSUITE\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${ENABLE_TEST_TRUE}" && test -z "${ENABLE_TEST_FALSE}"; then as_fn_error $? "conditional \"ENABLE_TEST\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${RESIDFP_SUPPORT_TRUE}" && test -z "${RESIDFP_SUPPORT_FALSE}"; then as_fn_error $? "conditional \"RESIDFP_SUPPORT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USBSID_SUPPORT_TRUE}" && test -z "${USBSID_SUPPORT_FALSE}"; then as_fn_error $? "conditional \"USBSID_SUPPORT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${USBSID_DRIVER_TRUE}" && test -z "${USBSID_DRIVER_FALSE}"; then as_fn_error $? "conditional \"USBSID_DRIVER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${EXSID_SUPPORT_TRUE}" && test -z "${EXSID_SUPPORT_FALSE}"; then as_fn_error $? "conditional \"EXSID_SUPPORT\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${EXSID_DRIVER_TRUE}" && test -z "${EXSID_DRIVER_FALSE}"; then as_fn_error $? "conditional \"EXSID_DRIVER\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi if test -z "${BUILD_DEMO_TRUE}" && test -z "${BUILD_DEMO_FALSE}"; then as_fn_error $? "conditional \"BUILD_DEMO\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi : "${CONFIG_STATUS=./config.status}" ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;} as_write_fail=0 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} export SHELL _ASEOF cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 ## -------------------- ## ## M4sh Initialization. ## ## -------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh as_nop=: if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1 then : emulate sh NULLCMD=: # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else $as_nop case `(set -o) 2>/dev/null` in #( *posix*) : set -o posix ;; #( *) : ;; esac fi # Reset variables that may have inherited troublesome values from # the environment. # IFS needs to be set, to space, tab, and newline, in precisely that order. # (If _AS_PATH_WALK were called with IFS unset, it would have the # side effect of setting IFS to empty, thus disabling word splitting.) # Quoting is to prevent editors from complaining about space-tab. as_nl=' ' export as_nl IFS=" "" $as_nl" PS1='$ ' PS2='> ' PS4='+ ' # Ensure predictable behavior from utilities with locale-dependent output. LC_ALL=C export LC_ALL LANGUAGE=C export LANGUAGE # We cannot yet rely on "unset" to work, but we need these variables # to be unset--not just set to an empty or harmless value--now, to # avoid bugs in old shells (e.g. pre-3.0 UWIN ksh). This construct # also avoids known problems related to "unset" and subshell syntax # in other old shells (e.g. bash 2.01 and pdksh 5.2.14). for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH do eval test \${$as_var+y} \ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : done # Ensure that fds 0, 1, and 2 are open. if (exec 3>&0) 2>/dev/null; then :; else exec 0&1) 2>/dev/null; then :; else exec 1>/dev/null; fi if (exec 3>&2) ; then :; else exec 2>/dev/null; fi # The user is always right. if ${PATH_SEPARATOR+false} :; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || PATH_SEPARATOR=';' } fi # Find who we are. Look in the path if we contain no directory separator. as_myself= case $0 in #(( *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS case $as_dir in #((( '') as_dir=./ ;; */) ;; *) as_dir=$as_dir/ ;; esac test -r "$as_dir$0" && as_myself=$as_dir$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 exit 1 fi # as_fn_error STATUS ERROR [LINENO LOG_FD] # ---------------------------------------- # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are # provided, also output the error to LOG_FD, referencing LINENO. Then exit the # script with STATUS, using 1 if that was 0. as_fn_error () { as_status=$1; test $as_status -eq 0 && as_status=1 if test "$4"; then as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 fi printf "%s\n" "$as_me: error: $2" >&2 as_fn_exit $as_status } # as_fn_error # as_fn_set_status STATUS # ----------------------- # Set $? to STATUS, without forking. as_fn_set_status () { return $1 } # as_fn_set_status # as_fn_exit STATUS # ----------------- # Exit the shell with STATUS, even in a "trap 0" or "set -e" context. as_fn_exit () { set +e as_fn_set_status $1 exit $1 } # as_fn_exit # as_fn_unset VAR # --------------- # Portably unset VAR. as_fn_unset () { { eval $1=; unset $1;} } as_unset=as_fn_unset # as_fn_append VAR VALUE # ---------------------- # Append the text in VALUE to the end of the definition contained in VAR. Take # advantage of any shell optimizations that allow amortized linear growth over # repeated appends, instead of the typical quadratic growth present in naive # implementations. if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null then : eval 'as_fn_append () { eval $1+=\$2 }' else $as_nop as_fn_append () { eval $1=\$$1\$2 } fi # as_fn_append # as_fn_arith ARG... # ------------------ # Perform arithmetic evaluation on the ARGs, and store the result in the # global $as_val. Take advantage of shells that can avoid forks. The arguments # must be portable across $(()) and expr. if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null then : eval 'as_fn_arith () { as_val=$(( $* )) }' else $as_nop as_fn_arith () { as_val=`expr "$@" || test $? -eq 1` } fi # as_fn_arith if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # Determine whether it's possible to make 'echo' print without a newline. # These variables are no longer used directly by Autoconf, but are AC_SUBSTed # for compatibility with existing Makefiles. ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in #((((( -n*) case `echo 'xy\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. xy) ECHO_C='\c';; *) echo `echo ksh88 bug on AIX 6.1` > /dev/null ECHO_T=' ';; esac;; *) ECHO_N='-n';; esac # For backward compatibility with old third-party macros, we provide # the shell variables $as_echo and $as_echo_n. New code should use # AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively. as_echo='printf %s\n' as_echo_n='printf %s' rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir 2>/dev/null fi if (echo >conf$$.file) 2>/dev/null; then if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -pR'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -pR' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -pR' fi else as_ln_s='cp -pR' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null # as_fn_mkdir_p # ------------- # Create "$as_dir" as a directory, including parents if necessary. as_fn_mkdir_p () { case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || eval $as_mkdir_p || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" } # as_fn_mkdir_p if mkdir -p . 2>/dev/null; then as_mkdir_p='mkdir -p "$as_dir"' else test -d ./-p && rmdir ./-p as_mkdir_p=false fi # as_fn_executable_p FILE # ----------------------- # Test if FILE is an executable regular file. as_fn_executable_p () { test -f "$1" && test -x "$1" } # as_fn_executable_p as_test_x='test -x' as_executable_p=as_fn_executable_p # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 ## ----------------------------------- ## ## Main body of $CONFIG_STATUS script. ## ## ----------------------------------- ## _ASEOF test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Save the log message, to keep $0 and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by libsidplayfp $as_me 3.0.0, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF case $ac_config_files in *" "*) set x $ac_config_files; shift; ac_config_files=$*;; esac case $ac_config_headers in *" "*) set x $ac_config_headers; shift; ac_config_headers=$*;; esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" config_commands="$ac_config_commands" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files and other configuration actions from templates according to the current configuration. Unless the files and actions are specified as TAGs, all are instantiated by default. Usage: $0 [OPTION]... [TAG]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit --config print configuration, then exit -q, --quiet, --silent do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Configuration commands: $config_commands Report bugs to the package provider. libsidplayfp home page: ." _ACEOF ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"` ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"` cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ libsidplayfp config.status 3.0.0 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" Copyright (C) 2021 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' MKDIR_P='$MKDIR_P' AWK='$AWK' test -n "\$AWK" || AWK=awk _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do case $1 in --*=?*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; --*=) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg= ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) printf "%s\n" "$ac_cs_version"; exit ;; --config | --confi | --conf | --con | --co | --c ) printf "%s\n" "$ac_cs_config"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; '') as_fn_error $? "missing file argument" ;; esac as_fn_append CONFIG_FILES " '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift case $ac_optarg in *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; esac as_fn_append CONFIG_HEADERS " '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header as_fn_error $? "ambiguous option: \`$1' Try \`$0 --help' for more information.";; --help | --hel | -h ) printf "%s\n" "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) as_fn_error $? "unrecognized option: \`$1' Try \`$0 --help' for more information." ;; *) as_fn_append ac_config_targets " $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion shift \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6 CONFIG_SHELL='$SHELL' export CONFIG_SHELL exec "\$@" fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX printf "%s\n" "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # The HP-UX ksh and POSIX shell print the target directory to stdout # if CDPATH is set. (unset CDPATH) >/dev/null 2>&1 && unset CDPATH sed_quote_subst='$sed_quote_subst' double_quote_subst='$double_quote_subst' delay_variable_subst='$delay_variable_subst' macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`' macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`' AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`' DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`' enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`' pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`' enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`' shared_archive_member_spec='`$ECHO "$shared_archive_member_spec" | $SED "$delay_single_quote_subst"`' SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`' ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`' PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`' host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`' host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`' host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`' build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`' build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`' build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`' SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`' Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`' GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`' EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`' FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`' LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`' NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`' LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`' max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`' ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`' exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`' lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`' lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`' lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`' lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`' lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' FILECMD='`$ECHO "$FILECMD" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`' want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`' old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`' old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`' old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`' lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`' CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`' CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`' compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`' GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_import='`$ECHO "$lt_cv_sys_global_symbol_to_import" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`' lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`' lt_cv_nm_interface='`$ECHO "$lt_cv_nm_interface" | $SED "$delay_single_quote_subst"`' nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`' lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`' lt_cv_truncate_bin='`$ECHO "$lt_cv_truncate_bin" | $SED "$delay_single_quote_subst"`' objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`' MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`' need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`' MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`' DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`' NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`' LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`' OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`' OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`' libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`' shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`' extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`' compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`' archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`' module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`' module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`' with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`' allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`' no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`' hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`' hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`' hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`' inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`' link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`' always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`' export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`' exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`' include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`' prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`' postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`' file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`' variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`' need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`' need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`' version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`' runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`' shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`' libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`' library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`' soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`' install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`' postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`' postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`' finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`' finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`' hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`' sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`' configure_time_dlsearch_path='`$ECHO "$configure_time_dlsearch_path" | $SED "$delay_single_quote_subst"`' configure_time_lt_sys_library_path='`$ECHO "$configure_time_lt_sys_library_path" | $SED "$delay_single_quote_subst"`' hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`' enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`' enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`' enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`' old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`' striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`' predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`' postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`' predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`' postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`' LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`' reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`' reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`' GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`' lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`' lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`' enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`' export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`' old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`' archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`' module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`' with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`' allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`' hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`' hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`' hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`' hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`' inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`' link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`' always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`' export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`' exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`' include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`' prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`' postlink_cmds_CXX='`$ECHO "$postlink_cmds_CXX" | $SED "$delay_single_quote_subst"`' file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`' hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`' predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`' postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`' predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`' postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`' compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`' LTCC='$LTCC' LTCFLAGS='$LTCFLAGS' compiler='$compiler_DEFAULT' # A function that is used when there is no print builtin or printf. func_fallback_echo () { eval 'cat <<_LTECHO_EOF \$1 _LTECHO_EOF' } # Quote evaled strings. for var in AS \ DLLTOOL \ OBJDUMP \ SHELL \ ECHO \ PATH_SEPARATOR \ SED \ GREP \ EGREP \ FGREP \ LD \ NM \ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ FILECMD \ deplibs_check_method \ file_magic_cmd \ file_magic_glob \ want_nocaseglob \ sharedlib_from_linklib_cmd \ AR \ archiver_list_spec \ STRIP \ RANLIB \ CC \ CFLAGS \ compiler \ lt_cv_sys_global_symbol_pipe \ lt_cv_sys_global_symbol_to_cdecl \ lt_cv_sys_global_symbol_to_import \ lt_cv_sys_global_symbol_to_c_name_address \ lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ lt_cv_nm_interface \ nm_file_list_spec \ lt_cv_truncate_bin \ lt_prog_compiler_no_builtin_flag \ lt_prog_compiler_pic \ lt_prog_compiler_wl \ lt_prog_compiler_static \ lt_cv_prog_compiler_c_o \ need_locks \ MANIFEST_TOOL \ DSYMUTIL \ NMEDIT \ LIPO \ OTOOL \ OTOOL64 \ shrext_cmds \ export_dynamic_flag_spec \ whole_archive_flag_spec \ compiler_needs_object \ with_gnu_ld \ allow_undefined_flag \ no_undefined_flag \ hardcode_libdir_flag_spec \ hardcode_libdir_separator \ exclude_expsyms \ include_expsyms \ file_list_spec \ variables_saved_for_relink \ libname_spec \ library_names_spec \ soname_spec \ install_override_mode \ finish_eval \ old_striplib \ striplib \ compiler_lib_search_dirs \ predep_objects \ postdep_objects \ predeps \ postdeps \ compiler_lib_search_path \ LD_CXX \ reload_flag_CXX \ compiler_CXX \ lt_prog_compiler_no_builtin_flag_CXX \ lt_prog_compiler_pic_CXX \ lt_prog_compiler_wl_CXX \ lt_prog_compiler_static_CXX \ lt_cv_prog_compiler_c_o_CXX \ export_dynamic_flag_spec_CXX \ whole_archive_flag_spec_CXX \ compiler_needs_object_CXX \ with_gnu_ld_CXX \ allow_undefined_flag_CXX \ no_undefined_flag_CXX \ hardcode_libdir_flag_spec_CXX \ hardcode_libdir_separator_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX \ file_list_spec_CXX \ compiler_lib_search_dirs_CXX \ predep_objects_CXX \ postdep_objects_CXX \ predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done # Double-quote double-evaled strings. for var in reload_cmds \ old_postinstall_cmds \ old_postuninstall_cmds \ old_archive_cmds \ extract_expsyms_cmds \ old_archive_from_new_cmds \ old_archive_from_expsyms_cmds \ archive_cmds \ archive_expsym_cmds \ module_cmds \ module_expsym_cmds \ export_symbols_cmds \ prelink_cmds \ postlink_cmds \ postinstall_cmds \ postuninstall_cmds \ finish_cmds \ sys_lib_search_path_spec \ configure_time_dlsearch_path \ configure_time_lt_sys_library_path \ reload_cmds_CXX \ old_archive_cmds_CXX \ old_archive_from_new_cmds_CXX \ old_archive_from_expsyms_cmds_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ module_cmds_CXX \ module_expsym_cmds_CXX \ export_symbols_cmds_CXX \ prelink_cmds_CXX \ postlink_cmds_CXX; do case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in *[\\\\\\\`\\"\\\$]*) eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" ## exclude from sc_prohibit_nested_quotes ;; *) eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" ;; esac done ac_aux_dir='$ac_aux_dir' # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes INIT. if test -n "\${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi PACKAGE='$PACKAGE' VERSION='$VERSION' RM='$RM' ofile='$ofile' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "src/config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/config.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Doxyfile") CONFIG_FILES="$CONFIG_FILES Doxyfile" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "libsidplayfp.pc") CONFIG_FILES="$CONFIG_FILES libsidplayfp.pc" ;; "libstilview.pc") CONFIG_FILES="$CONFIG_FILES libstilview.pc" ;; "src/sidplayfp/sidversion.h") CONFIG_FILES="$CONFIG_FILES src/sidplayfp/sidversion.h" ;; "src/builders/sidlite-builder/sidlite/sl_defs.h") CONFIG_FILES="$CONFIG_FILES src/builders/sidlite-builder/sidlite/sl_defs.h" ;; "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= ac_tmp= trap 'exit_status=$? : "${ac_tmp:=$tmp}" { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status ' 0 trap 'as_fn_exit 1' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 ac_tmp=$tmp # Set up the scripts for CONFIG_FILES section. # No need to generate them if there are no CONFIG_FILES. # This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then ac_cr=`echo X | tr X '\015'` # On cygwin, bash can eat \r inside `` if the user requested igncr. # But we know of no other shell where ac_cr would be empty at this # point, so we can use a bashism as a fallback. if test "x$ac_cr" = x; then eval ac_cr=\$\'\\r\' fi ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then ac_cs_awk_cr='\\r' else ac_cs_awk_cr=$ac_cr fi echo 'BEGIN {' >"$ac_tmp/subs1.awk" && _ACEOF { echo "cat >conf$$subs.awk <<_ACEOF" && echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && echo "_ACEOF" } >conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do . ./conf$$subs.sh || as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done rm -f conf$$subs.sh cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && _ACEOF sed -n ' h s/^/S["/; s/!.*/"]=/ p g s/^[^!]*!// :repl t repl s/'"$ac_delim"'$// t delim :nl h s/\(.\{148\}\)..*/\1/ t more1 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ p n b repl :more1 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t nl :delim h s/\(.\{148\}\)..*/\1/ t more2 s/["\\]/\\&/g; s/^/"/; s/$/"/ p b :more2 s/["\\]/\\&/g; s/^/"/; s/$/"\\/ p g s/.\{148\}// t delim ' >$CONFIG_STATUS || ac_write_fail=1 rm -f conf$$subs.awk cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACAWK cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && for (key in S) S_is_set[key] = 1 FS = "" } { line = $ 0 nfields = split(line, field, "@") substed = 0 len = length(field[1]) for (i = 2; i < nfields; i++) { key = field[i] keylen = length(key) if (S_is_set[key]) { value = S[key] line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) len += length(value) + length(field[++i]) substed = 1 } else len += 1 + keylen } print line } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" else cat fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 _ACEOF # VPATH may cause trouble with some makes, so we remove sole $(srcdir), # ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ h s/// s/^/:/ s/[ ]*$/:/ s/:\$(srcdir):/:/g s/:\${srcdir}:/:/g s/:@srcdir@:/:/g s/^:*// s/:*$// x s/\(=[ ]*\).*/\1/ G s/\n// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" # Set up the scripts for CONFIG_HEADERS section. # No need to generate them if there are no CONFIG_HEADERS. # This happens for instance with `./config.status Makefile'. if test -n "$CONFIG_HEADERS"; then cat >"$ac_tmp/defines.awk" <<\_ACAWK || BEGIN { _ACEOF # Transform confdefs.h into an awk script `defines.awk', embedded as # here-document in config.status, that substitutes the proper values into # config.h.in to produce config.h. # Create a delimiter string that does not exist in confdefs.h, to ease # handling of long lines. ac_delim='%!_!# ' for ac_last_try in false false :; do ac_tt=`sed -n "/$ac_delim/p" confdefs.h` if test -z "$ac_tt"; then break elif $ac_last_try; then as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done # For the awk script, D is an array of macro values keyed by name, # likewise P contains macro parameters if any. Preserve backslash # newline sequences. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* sed -n ' s/.\{148\}/&'"$ac_delim"'/g t rset :rset s/^[ ]*#[ ]*define[ ][ ]*/ / t def d :def s/\\$// t bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3"/p s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p d :bsnl s/["\\]/\\&/g s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ D["\1"]=" \3\\\\\\n"\\/p t cont s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p t cont d :cont n s/.\{148\}/&'"$ac_delim"'/g t clear :clear s/\\$// t bsnlc s/["\\]/\\&/g; s/^/"/; s/$/"/p d :bsnlc s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p b cont ' >$CONFIG_STATUS || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 for (key in D) D_is_set[key] = 1 FS = "" } /^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { line = \$ 0 split(line, arg, " ") if (arg[1] == "#") { defundef = arg[2] mac1 = arg[3] } else { defundef = substr(arg[1], 2) mac1 = arg[2] } split(mac1, mac2, "(") #) macro = mac2[1] prefix = substr(line, 1, index(line, defundef) - 1) if (D_is_set[macro]) { # Preserve the white space surrounding the "#". print prefix "define", macro P[macro] D[macro] next } else { # Replace #undef with comments. This is necessary, for example, # in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. if (defundef == "undef") { print "/*", prefix defundef, macro, "*/" next } } } { print } _ACAWK _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 fi # test -n "$CONFIG_HEADERS" eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" shift for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$ac_tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; esac case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac as_fn_append ac_file_inputs " '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input='Generated from '` printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 printf "%s\n" "$as_me: creating $ac_file" >&6;} fi # Neutralize special characters interpreted by sed in replacement strings. case $configure_input in #( *\&* | *\|* | *\\* ) ac_sed_conf_input=`printf "%s\n" "$configure_input" | sed 's/[\\\\&|]/\\\\&/g'`;; #( *) ac_sed_conf_input=$configure_input;; esac case $ac_tag in *:-:* | *:-) cat >"$ac_tmp/stdin" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` as_dir="$ac_dir"; as_fn_mkdir_p ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac ac_MKDIR_P=$MKDIR_P case $MKDIR_P in [\\/$]* | ?:[\\/]* ) ;; */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= ac_sed_dataroot=' /datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p' case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_sed_extra="$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t s&@MKDIR_P@&$ac_MKDIR_P&;t t $ac_datarootdir_hack " eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ "$ac_tmp/out"`; test -z "$ac_out"; } && { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&5 printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined" >&2;} rm -f "$ac_tmp/stdin" case $ac_file in -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; esac \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; :H) # # CONFIG_HEADER # if test x"$ac_file" != x-; then { printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" } >"$ac_tmp/config.h" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 printf "%s\n" "$as_me: $ac_file is unchanged" >&6;} else rm -f "$ac_file" mv "$ac_tmp/config.h" "$ac_file" \ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 fi else printf "%s\n" "/* $configure_input */" >&1 \ && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ || as_fn_error $? "could not create -" "$LINENO" 5 fi # Compute "$ac_file"'s index in $config_headers. _am_arg="$ac_file" _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" || $as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$_am_arg" : 'X\(//\)[^/]' \| \ X"$_am_arg" : 'X\(//\)$' \| \ X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$_am_arg" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'`/stamp-h$_am_stamp_count ;; :C) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 printf "%s\n" "$as_me: executing $ac_file commands" >&6;} ;; esac case $ac_file$ac_mode in "depfiles":C) test x"$AMDEP_TRUE" != x"" || { # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. case $CONFIG_FILES in #( *\'*) : eval set x "$CONFIG_FILES" ;; #( *) : set x $CONFIG_FILES ;; #( *) : ;; esac shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`$as_dirname -- "$am_mf" || $as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$am_mf" : 'X\(//\)[^/]' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` am_filepart=`$as_basename -- "$am_mf" || $as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ X"$am_mf" : 'X\(//\)$' \| \ X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || printf "%s\n" X/"$am_mf" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` { echo "$as_me:$LINENO: cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles" >&5 (cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles) >&5 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } || am_rc=$? done if test $am_rc -ne 0; then { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE=\"gmake\" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking). See \`config.log' for more details" "$LINENO" 5; } fi { am_dirpart=; unset am_dirpart;} { am_filepart=; unset am_filepart;} { am_mf=; unset am_mf;} { am_rc=; unset am_rc;} rm -f conftest-deps.mk } ;; "libtool":C) # See if we are running on zsh, and set the options that allow our # commands through without removal of \ escapes. if test -n "${ZSH_VERSION+set}"; then setopt NO_GLOB_SUBST fi cfgfile=${ofile}T trap "$RM \"$cfgfile\"; exit 1" 1 2 15 $RM "$cfgfile" cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 # Copyright (C) 2014 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program or library that is built # using GNU Libtool, you may include this file under the same # distribution terms that you use for the rest of that program. # # GNU Libtool is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # The names of the tagged configurations supported by this script. available_tags='CXX ' # Configured defaults for sys_lib_dlsearch_path munging. : \${LT_SYS_LIBRARY_PATH="$configure_time_lt_sys_library_path"} # ### BEGIN LIBTOOL CONFIG # Which release of libtool.m4 was used? macro_version=$macro_version macro_revision=$macro_revision # Assembler program. AS=$lt_AS # DLL creation program. DLLTOOL=$lt_DLLTOOL # Object dumper program. OBJDUMP=$lt_OBJDUMP # Whether or not to build shared libraries. build_libtool_libs=$enable_shared # Whether or not to build static libraries. build_old_libs=$enable_static # What type of objects to build. pic_mode=$pic_mode # Whether or not to optimize for fast installation. fast_install=$enable_fast_install # Shared archive member basename,for filename based shared library versioning on AIX. shared_archive_member_spec=$shared_archive_member_spec # Shell to use when invoking shell scripts. SHELL=$lt_SHELL # An echo program that protects backslashes. ECHO=$lt_ECHO # The PATH separator for the build system. PATH_SEPARATOR=$lt_PATH_SEPARATOR # The host system. host_alias=$host_alias host=$host host_os=$host_os # The build system. build_alias=$build_alias build=$build build_os=$build_os # A sed program that does not truncate output. SED=$lt_SED # Sed that helps us avoid accidentally triggering echo(1) options like -n. Xsed="\$SED -e 1s/^X//" # A grep program that handles long lines. GREP=$lt_GREP # An ERE matcher. EGREP=$lt_EGREP # A literal string matcher. FGREP=$lt_FGREP # A BSD- or MS-compatible name lister. NM=$lt_NM # Whether we need soft or hard links. LN_S=$lt_LN_S # What is the maximum length of a command? max_cmd_len=$max_cmd_len # Object file suffix (normally "o"). objext=$ac_objext # Executable file suffix (normally ""). exeext=$exeext # whether the shell understands "unset". lt_unset=$lt_unset # turn spaces into newlines. SP2NL=$lt_lt_SP2NL # turn newlines into spaces. NL2SP=$lt_lt_NL2SP # convert \$build file names to \$host format. to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd # A file(cmd) program that detects file types. FILECMD=$lt_FILECMD # Method to check whether dependent libraries are shared objects. deplibs_check_method=$lt_deplibs_check_method # Command to use when deplibs_check_method = "file_magic". file_magic_cmd=$lt_file_magic_cmd # How to find potential files when deplibs_check_method = "file_magic". file_magic_glob=$lt_file_magic_glob # Find potential files using nocaseglob when deplibs_check_method = "file_magic". want_nocaseglob=$lt_want_nocaseglob # Command to associate shared and link libraries. sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd # The archiver. AR=$lt_AR # Flags to create an archive (by configure). lt_ar_flags=$lt_ar_flags # Flags to create an archive. AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"} # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec # A symbol stripping program. STRIP=$lt_STRIP # Commands used to install an old-style archive. RANLIB=$lt_RANLIB old_postinstall_cmds=$lt_old_postinstall_cmds old_postuninstall_cmds=$lt_old_postuninstall_cmds # Whether to use a lock for old archive extraction. lock_old_archive_extraction=$lock_old_archive_extraction # A C compiler. LTCC=$lt_CC # LTCC compiler flags. LTCFLAGS=$lt_CFLAGS # Take the output of nm and produce a listing of raw symbols and C names. global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe # Transform the output of nm in a proper C declaration. global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl # Transform the output of nm into a list of symbols to manually relocate. global_symbol_to_import=$lt_lt_cv_sys_global_symbol_to_import # Transform the output of nm in a C name address pair. global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address # Transform the output of nm in a C name address pair when lib prefix is needed. global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix # The name lister interface. nm_interface=$lt_lt_cv_nm_interface # Specify filename containing input files for \$NM. nm_file_list_spec=$lt_nm_file_list_spec # The root where to search for dependent libraries,and where our libraries should be installed. lt_sysroot=$lt_sysroot # Command to truncate a binary pipe. lt_truncate_bin=$lt_lt_cv_truncate_bin # The name of the directory that contains temporary libtool files. objdir=$objdir # Used to examine libraries when file_magic_cmd begins with "file". MAGIC_CMD=$MAGIC_CMD # Must we lock files when doing compilation? need_locks=$lt_need_locks # Manifest tool. MANIFEST_TOOL=$lt_MANIFEST_TOOL # Tool to manipulate archived DWARF debug symbol files on Mac OS X. DSYMUTIL=$lt_DSYMUTIL # Tool to change global to local symbols on Mac OS X. NMEDIT=$lt_NMEDIT # Tool to manipulate fat objects and archives on Mac OS X. LIPO=$lt_LIPO # ldd/readelf like tool for Mach-O binaries on Mac OS X. OTOOL=$lt_OTOOL # ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. OTOOL64=$lt_OTOOL64 # Old archive suffix (normally "a"). libext=$libext # Shared library suffix (normally ".so"). shrext_cmds=$lt_shrext_cmds # The commands to extract the exported symbol list from a shared archive. extract_expsyms_cmds=$lt_extract_expsyms_cmds # Variables whose values should be saved in libtool wrapper scripts and # restored at link time. variables_saved_for_relink=$lt_variables_saved_for_relink # Do we need the "lib" prefix for modules? need_lib_prefix=$need_lib_prefix # Do we need a version for libraries? need_version=$need_version # Library versioning type. version_type=$version_type # Shared library runtime path variable. runpath_var=$runpath_var # Shared library path variable. shlibpath_var=$shlibpath_var # Is shlibpath searched before the hard-coded library search path? shlibpath_overrides_runpath=$shlibpath_overrides_runpath # Format of library name prefix. libname_spec=$lt_libname_spec # List of archive names. First name is the real one, the rest are links. # The last name is the one that the linker finds with -lNAME library_names_spec=$lt_library_names_spec # The coded name of the library, if different from the real name. soname_spec=$lt_soname_spec # Permission mode override for installation of shared libraries. install_override_mode=$lt_install_override_mode # Command to use after installation of a shared archive. postinstall_cmds=$lt_postinstall_cmds # Command to use after uninstallation of a shared archive. postuninstall_cmds=$lt_postuninstall_cmds # Commands used to finish a libtool library installation in a directory. finish_cmds=$lt_finish_cmds # As "finish_cmds", except a single script fragment to be evaled but # not shown. finish_eval=$lt_finish_eval # Whether we should hardcode library paths into libraries. hardcode_into_libs=$hardcode_into_libs # Compile-time system search path for libraries. sys_lib_search_path_spec=$lt_sys_lib_search_path_spec # Detected run-time system search path for libraries. sys_lib_dlsearch_path_spec=$lt_configure_time_dlsearch_path # Explicit LT_SYS_LIBRARY_PATH set during ./configure time. configure_time_lt_sys_library_path=$lt_configure_time_lt_sys_library_path # Whether dlopen is supported. dlopen_support=$enable_dlopen # Whether dlopen of programs is supported. dlopen_self=$enable_dlopen_self # Whether dlopen of statically linked programs is supported. dlopen_self_static=$enable_dlopen_self_static # Commands to strip libraries. old_striplib=$lt_old_striplib striplib=$lt_striplib # The linker used to build libraries. LD=$lt_LD # How to create reloadable object files. reload_flag=$lt_reload_flag reload_cmds=$lt_reload_cmds # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds # A language specific compiler. CC=$lt_compiler # Is the compiler the GNU compiler? with_gcc=$GCC # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds archive_expsym_cmds=$lt_archive_expsym_cmds # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds module_expsym_cmds=$lt_module_expsym_cmds # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms # Symbols that must always be exported. include_expsyms=$lt_include_expsyms # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds # Specify filename containing input files. file_list_spec=$lt_file_list_spec # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects postdep_objects=$lt_postdep_objects predeps=$lt_predeps postdeps=$lt_postdeps # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path # ### END LIBTOOL CONFIG _LT_EOF cat <<'_LT_EOF' >> "$cfgfile" # ### BEGIN FUNCTIONS SHARED WITH CONFIGURE # func_munge_path_list VARIABLE PATH # ----------------------------------- # VARIABLE is name of variable containing _space_ separated list of # directories to be munged by the contents of PATH, which is string # having a format: # "DIR[:DIR]:" # string "DIR[ DIR]" will be prepended to VARIABLE # ":DIR[:DIR]" # string "DIR[ DIR]" will be appended to VARIABLE # "DIRP[:DIRP]::[DIRA:]DIRA" # string "DIRP[ DIRP]" will be prepended to VARIABLE and string # "DIRA[ DIRA]" will be appended to VARIABLE # "DIR[:DIR]" # VARIABLE will be replaced by "DIR[ DIR]" func_munge_path_list () { case x$2 in x) ;; *:) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'` \$$1\" ;; x:*) eval $1=\"\$$1 `$ECHO $2 | $SED 's/:/ /g'`\" ;; *::*) eval $1=\"\$$1\ `$ECHO $2 | $SED -e 's/.*:://' -e 's/:/ /g'`\" eval $1=\"`$ECHO $2 | $SED -e 's/::.*//' -e 's/:/ /g'`\ \$$1\" ;; *) eval $1=\"`$ECHO $2 | $SED 's/:/ /g'`\" ;; esac } # Calculate cc_basename. Skip known compiler wrappers and cross-prefix. func_cc_basename () { for cc_temp in $*""; do case $cc_temp in compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; \-*) ;; *) break;; esac done func_cc_basename_result=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"` } # ### END FUNCTIONS SHARED WITH CONFIGURE _LT_EOF case $host_os in aix3*) cat <<\_LT_EOF >> "$cfgfile" # AIX sometimes has problems with the GCC collect2 program. For some # reason, if we set the COLLECT_NAMES environment variable, the problems # vanish in a puff of smoke. if test set != "${COLLECT_NAMES+set}"; then COLLECT_NAMES= export COLLECT_NAMES fi _LT_EOF ;; esac ltmain=$ac_aux_dir/ltmain.sh # We use sed instead of cat because bash on DJGPP gets confused if # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") chmod +x "$ofile" cat <<_LT_EOF >> "$ofile" # ### BEGIN LIBTOOL TAG CONFIG: CXX # The linker used to build libraries. LD=$lt_LD_CXX # How to create reloadable object files. reload_flag=$lt_reload_flag_CXX reload_cmds=$lt_reload_cmds_CXX # Commands used to build an old-style archive. old_archive_cmds=$lt_old_archive_cmds_CXX # A language specific compiler. CC=$lt_compiler_CXX # Is the compiler the GNU compiler? with_gcc=$GCC_CXX # Compiler flag to turn off builtin functions. no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX # Additional compiler flags for building library objects. pic_flag=$lt_lt_prog_compiler_pic_CXX # How to pass a linker flag through the compiler. wl=$lt_lt_prog_compiler_wl_CXX # Compiler flag to prevent dynamic linking. link_static_flag=$lt_lt_prog_compiler_static_CXX # Does compiler simultaneously support -c and -o options? compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX # Whether or not to add -lc for building shared libraries. build_libtool_need_lc=$archive_cmds_need_lc_CXX # Whether or not to disallow shared libs when runtime libs are static. allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX # Compiler flag to allow reflexive dlopens. export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX # Compiler flag to generate shared objects directly from archives. whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX # Whether the compiler copes with passing no objects directly. compiler_needs_object=$lt_compiler_needs_object_CXX # Create an old-style archive from a shared archive. old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX # Create a temporary old-style archive to link instead of a shared archive. old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX # Commands used to build a shared archive. archive_cmds=$lt_archive_cmds_CXX archive_expsym_cmds=$lt_archive_expsym_cmds_CXX # Commands used to build a loadable module if different from building # a shared archive. module_cmds=$lt_module_cmds_CXX module_expsym_cmds=$lt_module_expsym_cmds_CXX # Whether we are building with GNU ld or not. with_gnu_ld=$lt_with_gnu_ld_CXX # Flag that allows shared libraries with undefined symbols to be built. allow_undefined_flag=$lt_allow_undefined_flag_CXX # Flag that enforces no undefined symbols. no_undefined_flag=$lt_no_undefined_flag_CXX # Flag to hardcode \$libdir into a binary during linking. # This must work even if \$libdir does not exist hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX # Whether we need a single "-rpath" flag with a separated argument. hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary. hardcode_direct=$hardcode_direct_CXX # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is # "absolute",i.e impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute_CXX # Set to "yes" if using the -LDIR flag during linking hardcodes DIR # into the resulting binary. hardcode_minus_L=$hardcode_minus_L_CXX # Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR # into the resulting binary. hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX # Set to "yes" if building a shared library automatically hardcodes DIR # into the library and all subsequent libraries and executables linked # against it. hardcode_automatic=$hardcode_automatic_CXX # Set to yes if linker adds runtime paths of dependent libraries # to runtime path list. inherit_rpath=$inherit_rpath_CXX # Whether libtool must link a program against all its dependency libraries. link_all_deplibs=$link_all_deplibs_CXX # Set to "yes" if exported symbols are required. always_export_symbols=$always_export_symbols_CXX # The commands to list exported symbols. export_symbols_cmds=$lt_export_symbols_cmds_CXX # Symbols that should not be listed in the preloaded symbols. exclude_expsyms=$lt_exclude_expsyms_CXX # Symbols that must always be exported. include_expsyms=$lt_include_expsyms_CXX # Commands necessary for linking programs (against libraries) with templates. prelink_cmds=$lt_prelink_cmds_CXX # Commands necessary for finishing linking programs. postlink_cmds=$lt_postlink_cmds_CXX # Specify filename containing input files. file_list_spec=$lt_file_list_spec_CXX # How to hardcode a shared library path into an executable. hardcode_action=$hardcode_action_CXX # The directories searched by this compiler when creating a shared library. compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX # Dependencies to place before and after the objects being linked to # create a shared library. predep_objects=$lt_predep_objects_CXX postdep_objects=$lt_postdep_objects_CXX predeps=$lt_predeps_CXX postdeps=$lt_postdeps_CXX # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX # ### END LIBTOOL TAG CONFIG: CXX _LT_EOF ;; esac done # for ac_tag as_fn_exit 0 _ACEOF ac_clean_files=$ac_clean_files_save test $ac_write_fail = 0 || as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || as_fn_exit 1 fi if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} fi libsidplayfp-3.0.0/README.md0000644000175100017510000000630615175333711011151 libsidplayfp ============ https://github.com/libsidplayfp/libsidplayfp libsidplayfp is a C64 music player library which integrates the reSIDfp SID chip emulation engine into a cycle-based emulator environment, constantly aiming to improve emulation of the C64 system and the SID chips. Copyright (c) 2000-2001 Simon White Copyright (c) 2007-2010 Antti Lankila Copyright (c) 2010-2026 Leandro Nini (drfiemost@users.sourceforge.net) ----------------------------------------------------------------------------- _This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version._ _This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details._ _You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA._ ----------------------------------------------------------------------------- **NOTE**: the git repository contains submodules, clone with `--recurse-submodules`. ----------------------------------------------------------------------------- API documentation available online at https://libsidplayfp.github.io/libsidplayfp/ ----------------------------------------------------------------------------- ## Build This package uses autotools, so the usual `./configure && make` is enough to build the libraries. If cloning the bare sources the package needs to be bootstrapped in advance with the `autoreconf -vfi` command. This step requires the xa cross-assembler to compile the 6502 code, usually provided by distributions with the xa65 package or available at http://www.floodgap.com/retrotech/xa/. To enable full quality SID emulation [libresidfp](https://github.com/libsidplayfp/libresidfp) is required. In addition to the standard build options the following are available: * `--enable-debug[=no/yes]`: compile with debugging messages (disabled by default) * `--enable-testsuite=PATH_TO_TESTSUITE`: add support for running VICE's testsuite (in PRG format). The testsuite is available in the repository. Intended only for regression tests since it may break normal code execution. The path to testsuite must include terminal path separator. (disabled by default) * `--enable-tests`: enables unit tests. Use `make check` to launch the testsuite (disabled by default) * `--with-exsid`: Build with exsid support. Requires either libexsid or one of libfdti1 or libftd2xx * `--with-usbsid`: Build with usbsid support. Requires libusb If [doxygen](https://doxygen.nl) is installed and detected by the configure script, the documentation can be built by invoking `make doc`. Known bugs/limitations: * mus data embedded in psid file is not supported ----------------------------------------------------------------------------- # 3rd party software * hashlib https://github.com/Cra3z/hashlib distributed under MIT license libsidplayfp-3.0.0/src/0000755000175100017510000000000015175333725010541 5libsidplayfp-3.0.0/src/EventScheduler.h0000644000175100017510000001133415175333711013547 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2011-2015 Leandro Nini * Copyright (C) 2009 Antti S. Lankila * Copyright (C) 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef EVENTSCHEDULER_H #define EVENTSCHEDULER_H #include "Event.h" #include "sidcxx11.h" namespace libsidplayfp { /** * C64 system runs actions at system clock high and low * states. The PHI1 corresponds to the auxiliary chip activity * and PHI2 to CPU activity. For any clock, PHI1s are before * PHI2s. */ using event_phase_t = enum { EVENT_CLOCK_PHI1 = 0, EVENT_CLOCK_PHI2 = 1 }; /** * Fast EventScheduler, which maintains a linked list of Events. * This scheduler takes neglible time even when it is used to * schedule events for nearly every clock. * * Events occur on an internal clock which is 2x the visible clock. * The visible clock is divided to two phases called phi1 and phi2. * * The phi1 clocks are used by VIC and CIA chips, phi2 clocks by CPU. * * Scheduling an event for a phi1 clock when system is in phi2 causes the * event to be moved to the next phi1 cycle. Correspondingly, requesting * a phi1 time when system is in phi2 returns the value of the next phi1. */ class EventScheduler { private: /// The first event of the chain. Event *firstEvent = nullptr; /// EventScheduler's current clock. event_clock_t currentTime = 0; private: /** * Scan the event queue and schedule event for execution. * * @param event The event to add */ void schedule(Event &event) { // find the right spot where to tuck this new event Event **scan = &firstEvent; for (;;) { if ((*scan == nullptr) || ((*scan)->triggerTime > event.triggerTime)) { event.next = *scan; *scan = &event; break; } scan = &((*scan)->next); } } public: /** * Add event to pending queue. * * At PHI2, specify cycles=0 and Phase=PHI1 to fire on the very next PHI1. * * @param event the event to add * @param cycles how many cycles from now to fire * @param phase the phase when to fire the event */ void schedule(Event &event, unsigned int cycles, event_phase_t phase) { // this strange formulation always selects the next available slot regardless of specified phase. event.triggerTime = currentTime + ((currentTime & 1) ^ phase) + (cycles << 1); schedule(event); } /** * Add event to pending queue in the same phase as current event. * * @param event the event to add * @param cycles how many cycles from now to fire */ void schedule(Event &event, unsigned int cycles) { event.triggerTime = currentTime + (cycles << 1); schedule(event); } /** * Cancel event if pending. * * @param event the event to cancel */ void cancel(const Event &event); /** * Cancel all pending events and reset time. */ void reset(); /** * Fire next event, advance system time to that event. */ void clock() { Event &event = *firstEvent; firstEvent = firstEvent->next; currentTime = event.triggerTime; event.event(); } /** * Check if an event is in the queue. * * @param event the event * @return true when pending */ bool isPending(const Event &event) const; /** * Get time with respect to a specific clock phase. * * @param phase the phase * @return the time according to specified phase. */ event_clock_t getTime(event_phase_t phase) const { return (currentTime + (phase ^ 1)) >> 1; } /** * Return current clock phase. * * @return The current phase */ event_phase_t phase() const { return static_cast(currentTime & 1); } event_clock_t remaining(const Event &event) const { return event.triggerTime - currentTime; } }; } #endif // EVENTSCHEDULER_H libsidplayfp-3.0.0/src/sidemu.cpp0000644000175100017510000000462215175333711012452 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "sidemu.h" namespace libsidplayfp { const char sidemu::ERR_UNSUPPORTED_FREQ[] = "Unable to set desired output frequency."; const char sidemu::ERR_INVALID_SAMPLING[] = "Invalid sampling method."; const char sidemu::ERR_INVALID_CHIP[] = "Invalid chip model."; void sidemu::writeReg(uint_least8_t addr, uint8_t data) { switch (addr) { case 0x04: // Ignore writes to control register to mute voices // Leave test/ring/sync bits untouched if (isMuted[0]) UNLIKELY data &= 0x0e; break; case 0x0b: if (isMuted[1]) UNLIKELY data &= 0x0e; break; case 0x12: if (isMuted[2]) UNLIKELY data &= 0x0e; break; case 0x17: // Ignore writes to filter register to disable filter if (isFilterDisabled) UNLIKELY data &= 0xf0; break; case 0x18: // Ignore writes to volume register to mute samples // Works only for volume-based digis // Trick suggested by LMan if (isMuted[3]) UNLIKELY data |= 0x0f; break; } write(addr, data); } void sidemu::voice(unsigned int voice, bool mute) { if (voice < 4) LIKELY isMuted[voice] = mute; } void sidemu::filter(bool enable) { isFilterDisabled = !enable; } bool sidemu::lock(EventScheduler *scheduler) { if (isLocked) return false; isLocked = true; eventScheduler = scheduler; return true; } void sidemu::unlock() { isLocked = false; eventScheduler = nullptr; } } libsidplayfp-3.0.0/src/SidInfoImpl.h0000644000175100017510000000650115175333711013004 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SIDINFOIMPL_H #define SIDINFOIMPL_H #include #include #include #include "sidplayfp/SidInfo.h" #include "sidcxx11.h" #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifndef PACKAGE_NAME # define PACKAGE_NAME PACKAGE #endif #ifndef PACKAGE_VERSION # define PACKAGE_VERSION VERSION #endif /** * The implementation of the SidInfo interface. */ class SidInfoImpl final : public SidInfo { public: const std::string m_name { PACKAGE_NAME }; const std::string m_version { PACKAGE_VERSION }; std::vector m_credits { PACKAGE_NAME " V" PACKAGE_VERSION " Engine:\n" "\tCopyright (C) 2000 Simon White\n" "\tCopyright (C) 2007-2010 Antti Lankila\n" "\tCopyright (C) 2010-2026 Leandro Nini\n" "\t" PACKAGE_URL "\n" }; std::vector m_sidModels; std::string m_speedString; std::string m_kernalDesc; std::string m_basicDesc; std::string m_chargenDesc; uint_least16_t m_driverAddr = 0; uint_least16_t m_driverLength = 0; uint_least16_t m_powerOnDelay = 0; private: // prevent copying SidInfoImpl(const SidInfoImpl&) = delete; SidInfoImpl& operator=(SidInfoImpl&) = delete; public: SidInfoImpl() {} const char *getName() const override { return m_name.c_str(); } const char *getVersion() const override { return m_version.c_str(); } unsigned int getNumberOfCredits() const override { return m_credits.size(); } const char *getCredits(unsigned int i) const override { return i * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDEMU_H #define SIDEMU_H #include "sidplayfp/SidConfig.h" #include "sidplayfp/siddefs.h" #include "Event.h" #include "EventScheduler.h" #include "c64/c64sid.h" #include "sidcxx11.h" #include #include class sidbuilder; namespace libsidplayfp { /** * Inherit this class to create a new SID emulation. */ class sidemu : public c64sid { private: sidbuilder* const m_builder; protected: static const char ERR_UNSUPPORTED_FREQ[]; static const char ERR_INVALID_SAMPLING[]; static const char ERR_INVALID_CHIP[]; protected: EventScheduler *eventScheduler = nullptr; event_clock_t m_accessClk = 0; /// The sample buffer short *m_buffer = nullptr; /// Current position in buffer int m_bufferpos = 0; bool m_status = true; bool isLocked = false; bool isFilterDisabled = false; /// Flags for muted voices std::bitset<4> isMuted; std::string m_error; protected: virtual void write(uint_least8_t addr, uint8_t data) = 0; void writeReg(uint_least8_t addr, uint8_t data) override final; public: sidemu(sidbuilder *builder) : m_builder(builder), m_error("N/A") { isMuted.reset(); } ~sidemu() override = default; /** * Clock the SID chip. */ virtual void clock() = 0; /** * Set execution environment and lock sid to it. */ virtual bool lock(EventScheduler *scheduler); /** * Unlock sid. */ virtual void unlock(); // Standard SID functions /** * Mute/unmute voice. * * @param voice SID voice channels from 0 to 2, or 3 for samples * @param mute true to mute channel */ void voice(unsigned int voice, bool mute); /** * Enable/disable filter. */ void filter(bool enable); /** * Set SID model. */ virtual void model(SidConfig::sid_model_t model, bool digiboost) = 0; /** * Set the sampling method. * * @param systemfreq * @param outputfreq * @param method */ virtual void sampling(float systemfreq SID_UNUSED, float outputfreq SID_UNUSED, SidConfig::sampling_method_t method SID_UNUSED) {} /** * Get a detailed error message. */ const char* error() const { return m_error.c_str(); } sidbuilder* builder() const { return m_builder; } /** * Get the current position in buffer. */ int bufferpos() const { return m_bufferpos; } /** * Set the position in buffer. */ void bufferpos(int pos) { m_bufferpos = pos; } /** * Get the buffer. */ short *buffer() const { return m_buffer; } }; } #endif // SIDEMU_H libsidplayfp-3.0.0/src/simpleMixer.cpp0000644000175100017510000000477515175333711013473 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "simpleMixer.h" #include #include #include #include #ifdef __cpp_lib_unreachable # include #endif #include "sidemu.h" namespace libsidplayfp { unsigned int SimpleMixer::doMix(short *buffer, unsigned int samples) { unsigned int j = 0; for (unsigned int i=0; i*(mix))(); assert((tmp >= SHRT_MIN) && (tmp <= SHRT_MAX)); buffer[j++] = static_cast(tmp); } } return j; } SimpleMixer::SimpleMixer(bool stereo, short** buffers, int chips) { switch (chips) { case 1: m_mix.push_back(stereo ? &SimpleMixer::stereo_OneChip : &SimpleMixer::template mono<1>); if (stereo) m_mix.push_back(&SimpleMixer::stereo_OneChip); break; case 2: m_mix.push_back(stereo ? &SimpleMixer::stereo_ch1_TwoChips : &SimpleMixer::template mono<2>); if (stereo) m_mix.push_back(&SimpleMixer::stereo_ch2_TwoChips); break; case 3: m_mix.push_back(stereo ? &SimpleMixer::stereo_ch1_ThreeChips : &SimpleMixer::template mono<3>); if (stereo) m_mix.push_back(&SimpleMixer::stereo_ch2_ThreeChips); break; #ifdef __cpp_lib_unreachable default: std::unreachable(); #endif } m_iSamples.resize(chips); for (int i=0; i * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "p00.h" #include #include #include #include #include "sidplayfp/SidTuneInfo.h" #include "SmartPtr.h" #include "SidTuneTools.h" namespace libsidplayfp { constexpr int X00_ID_LEN = 8; constexpr int X00_NAME_LEN = 17; // File format from PC64. PC64 automatically generates // the filename from the cbm name (16 to 8 conversion) // but we only need to worry about that when writing files // should we want pc64 compatibility. The extension numbers // are just an index to try to avoid repeats. Name conversion // works by creating an initial filename from alphanumeric // and ' ', '-' characters only with the later two being // converted to '_'. Then it parses the filename // from end to start removing characters stopping as soon // as the filename becomes <= 8. The removal of characters // occurs in three passes, the first removes all '_', then // vowels and finally numerics. If the filename is still // greater than 8 it is truncated. struct X00Header { char id[X00_ID_LEN]; // 'C64File' (ASCII) uint8_t name[X00_NAME_LEN]; // C64 name (PETSCII) uint8_t length; // Rel files only (Bytes/Record), // should be 0 for all other types }; enum class X00Format { DEL, SEQ, PRG, USR, REL }; // Format strings const char TXT_FORMAT_DEL[] = "Unsupported tape image file (DEL)"; const char TXT_FORMAT_SEQ[] = "Unsupported tape image file (SEQ)"; const char TXT_FORMAT_PRG[] = "Tape image file (PRG)"; const char TXT_FORMAT_USR[] = "Unsupported USR file (USR)"; const char TXT_FORMAT_REL[] = "Unsupported tape image file (REL)"; // Magic field const char P00_ID[] = "C64File"; SidTuneBase* p00::load(const char *fileName, const buffer_t& dataBuf) { const char *ext = SidTuneTools::fileExtOfPath(fileName); // Combined extension & magic field identification if (strlen(ext) != 4) return nullptr; if (!isdigit(ext[2]) || !isdigit(ext[3])) return nullptr; const char *format = nullptr; X00Format type; switch (toupper(ext[1])) { case 'D': type = X00Format::DEL; format = TXT_FORMAT_DEL; break; case 'S': type = X00Format::SEQ; format = TXT_FORMAT_SEQ; break; case 'P': type = X00Format::PRG; format = TXT_FORMAT_PRG; break; case 'U': type = X00Format::USR; format = TXT_FORMAT_USR; break; case 'R': type = X00Format::REL; format = TXT_FORMAT_REL; break; default: return nullptr; } // Verify the file is what we think it is const buffer_t::size_type bufLen = dataBuf.size(); if (bufLen < X00_ID_LEN) return nullptr; X00Header pHeader; std::memcpy(pHeader.id, &dataBuf[0], X00_ID_LEN); std::memcpy(pHeader.name, &dataBuf[X00_ID_LEN], X00_NAME_LEN); pHeader.length = dataBuf[X00_ID_LEN + X00_NAME_LEN]; if (strcmp(pHeader.id, P00_ID)) return nullptr; // File types current supported if (type != X00Format::PRG) throw loadError("Not a PRG inside X00"); if (bufLen < sizeof(X00Header) + 2) throw loadError(ERR_TRUNCATED); std::unique_ptr tune(new p00()); tune->load(format, &pHeader); return tune.release(); } void p00::load(const char* format, const X00Header* pHeader) { info->m_formatString = format; { // Decode file name SmartPtr_sidtt spPet(pHeader->name, X00_NAME_LEN); info->m_infoString.push_back(petsciiToAscii(spPet)); } // Automatic settings fileOffset = X00_ID_LEN + X00_NAME_LEN + 1; info->m_songs = 1; info->m_startSong = 1; info->m_compatibility = SidTuneInfo::COMPATIBILITY_BASIC; // Create the speed/clock setting table. convertOldStyleSpeedToTables(~0, info->m_clockSpeed); } } libsidplayfp-3.0.0/src/sidtune/PSID.h0000644000175100017510000000352615175333711013045 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2014 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef PSID_H #define PSID_H #include #include "SidTuneBase.h" #include "sidplayfp/SidTune.h" #include "sidcxx11.h" namespace libsidplayfp { struct psidHeader; class PSID final : public SidTuneBase { private: char m_md5[SidTune::MD5_LENGTH+1]; private: /** * Load PSID file. * * @throw loadError */ void tryLoad(const psidHeader &pHeader); /** * Read PSID file header. * * @throw loadError */ static void readHeader(const buffer_t &dataBuf, psidHeader &hdr); protected: PSID() {} public: ~PSID() override = default; /** * @return pointer to a SidTune or 0 if not a PSID file * @throw loadError if PSID file is corrupt */ static SidTuneBase* load(buffer_t& dataBuf); const char *createMD5(char *md5) override; const char *createMD5New(char *md5) override; private: // prevent copying PSID(const PSID&) = delete; PSID& operator=(PSID&) = delete; }; } #endif // PSID_H libsidplayfp-3.0.0/src/sidtune/SidTuneTools.h0000644000175100017510000000273015175333711014676 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) Michael Schwendt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDTUNETOOLS_H #define SIDTUNETOOLS_H #include namespace libsidplayfp { namespace SidTuneTools { /** * Return pointer to file name position in complete path. */ size_t fileNameWithoutPath(const char* s); /** * Return pointer to file name position in complete path. * Special version: file separator = forward slash. */ size_t slashedFileNameWithoutPath(const char* s); /** * Return pointer to file name extension in path. * Searching backwards until first dot is found. */ const char* fileExtOfPath(const char* s); } } #endif /* SIDTUNETOOLS_H */ libsidplayfp-3.0.0/src/sidtune/sidplayer2.a650000644000175100017510000004454315175333711014534 ; Compute's Gazette sidplayer sources, disassembled with dxa ; ; C64 "Enhanced Sidplayer" by Craig Chamberlain ; Copyright 1986 COMPUTE! ; ; extracted from CGSC/00_Commodore64/MusicSys.d64/SID PLAYER.64 ; .word $f000 * = $f000 lf000 lf001 = * + 1 lf002 = * + 2 .byt $00,$00,$00 lf005 = * + 2 .byt $00,$00,$00 lf008 = * + 2 .byt $00,$00,$00 lf00b = * + 2 .byt $00,$00,$00 lf00e = * + 2 .byt $00,$00,$00 lf011 = * + 2 .byt $00,$00,$00 lf014 = * + 2 .byt $00,$00,$00 lf017 = * + 2 .byt $00,$00,$00 lf01a = * + 2 .byt $00,$00,$00 lf01b lf01c = * + 1 lf01d = * + 2 .byt $00,$00,$00 lf020 = * + 2 .byt $00,$00,$00 lf023 = * + 2 .byt $00,$00,$00 lf024 lf025 = * + 1 lf026 = * + 2 .byt $00,$00,$00 lf027 lf028 = * + 1 lf029 = * + 2 .byt $00,$00,$00 lf02a .byt $00,$00,$00 lf02d lf02e = * + 1 lf02f = * + 2 .byt $00,$00,$00 lf030 .byt $00,$00,$00 lf033 .byt $00,$00,$00 lf036 .byt $00,$00,$00 lf039 .byt $00,$00,$00 lf03c .byt $00,$00,$00 lf03f .byt $00,$00,$00 lf042 .byt $00,$00,$00 lf045 .byt $00,$00,$00 lf048 .byt $00,$00,$00 lf04b .byt $00,$00,$00 lf04e .byt $00,$00,$00 lf051 .byt $00,$00,$00 lf054 .byt $00,$00,$00 lf057 .byt $00,$00,$00 lf05a .byt $00,$00,$00 lf05d .byt $00,$00,$00 lf060 .byt $00,$00,$00 lf063 .byt $00,$00,$00 lf066 .byt $00,$00,$00 lf069 .byt $00,$00,$00 lf06c .byt $00,$00,$00 lf06f .byt $00,$00,$00 lf072 .byt $00,$00,$00 lf075 .byt $00,$00,$00 lf078 .byt $00,$00,$00 lf07b .byt $00,$00,$00 lf07e .byt $00,$00,$00 lf081 .byt $00,$00,$00 lf084 .byt $00,$00,$00 lf087 .byt $00,$00,$00 lf08a .byt $00,$00,$00 lf08d .byt $00,$00,$00 lf090 .byt $00,$00,$00 lf093 .byt $00,$00,$00 lf096 .byt $00,$00,$00 lf099 .byt $00,$00,$00 lf09c .byt $00,$00,$00 lf09f .byt $00,$00,$00 lf0a2 .byt $00,$00,$00 lf0a5 .byt $00,$00,$00 lf0a8 .byt $00,$00,$00 lf0ab .byt $00,$00,$00 lf0ae .byt $00,$00,$00 lf0b1 .byt $00,$00,$00 lf0b4 .byt $00,$00,$00 lf0b7 .byt $00,$00,$00 lf0ba lf0bc = * + 2 .byt $00,$00,$00 lf0bd lf0be = * + 1 lf0bf = * + 2 .byt $00,$00,$00 lf0c0 .byt $00,$00,$00 lf0c3 .byt $00,$00,$00 lf0c6 .byt $00,$00,$00 lf0c9 lf0ca = * + 1 lf0cb = * + 2 .byt $00,$00,$00 lf0cc lf0cd = * + 1 .byt $00,$00,$00 lf0d0 = * + 1 .byt $00,$00,$00 lf0d3 = * + 1 .byt $00,$00,$00 lf0d6 = * + 1 .byt $00,$00,$00 lf0d9 = * + 1 .byt $00,$00,$00 lf0dc = * + 1 .byt $00,$00,$00 lf0df = * + 1 lf0e0 = * + 2 .byt $00,$00,$00 lf0e1 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 lf0f0 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 lf0ff .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 lf117 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 lf12f .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 lf13e .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 lf156 lf157 = * + 1 lf158 = * + 2 .byt $00,$00,$00 lf159 lf15a = * + 1 lf15b = * + 2 .byt $00,$00,$00 lf15c lf15d = * + 1 lf15e = * + 2 .byt $00,$00,$00 lf15f lf160 = * + 1 ; Instruction opcode accessed. ; Instruction parameter accessed. adc ($f1,x) rts lf162 .byt $01,$02,$04 lf165 lf167 = * + 2 .byt $00,$07,$0e .byt $02,$02,$fe .byt $02,$02,$fe lf16f = * + 1 .byt $fe,$00,$01 lf172 = * + 1 .byt $00,$ff,$00 .byt $02,$04,$05 .byt $07,$09,$0b lf17a .byt $1e,$18,$8b .byt $7e,$fa,$06 .byt $ac,$f3,$e6 .byt $8f,$f8,$2e lf186 .byt $86,$8e,$96 .byt $9f,$a8,$b3 .byt $bd,$c8,$d4 .byt $e1,$ee,$fd lf192 sty $6478 bvc lf1d3 .byt $28,$14,$00 lf19a .byt $00,$02,$03 .byt $05,$07,$08 .byt $0a,$0c,$0d .byt $0f,$11,$12 lf1a6 lf1a8 = * + 2 .byt $00,$e0,$00 lf1a9 .byt $05,$0a,$0f lf1ac lf1ad = * + 1 .byt $f9,$00,$f5 lf1af .byt $00,$00,$00 lf1b2 bpl lf1b4 lf1b4 .byt $00 lf1b5 jsr $0000 bmi lf1ba lf1ba .byt $00,$40,$00 .byt $00 lf1be bvc lf1c0 lf1c0 .byt $00,$60,$00 .byt $00 lf1c4 bvs lf1c6 lf1c6 .byt $00,$80,$00 .byt $00 lf1ca bcc lf1cc lf1cc .byt $00 lf1cd ldy #$00 lf1cf lda #$00 lf1d3 = * + 2 sta lf000 ldx #$95 ldy #$42 lda $02a6 beq lf1e1 lf1dd ldx #$25 ldy #$40 lf1e1 stx lf15b sty lf15c nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop rts lf200 lda #$00 sta lf000 stx $61 sty $62 ldy #$bc lf20b sta lf000,y dey bne lf20b lf211 ldy #$72 lf213 sta lf0bc,y dey bne lf213 lf219 sta $d515 sta $d516 lda #$08 sta lf025 sta $d517 sta lf026 sta $d518 lda #$90 sta lf027 lda #$60 sta lf028 lda #$0c sta lf029 lda lf15b sta lf02d lda lf15c sta lf02e lda #$ff sta lf0cc lda #$d5 sta $64 ldx #$02 lf253 lda #$ff sta lf00b,x lda #$01 sta lf030,x sta lf02a,x txa sta lf033,x sta lf0ae,x lda #$04 sta lf039,x lda lf1a8,x sta lf0ba,x lda #$5b sta lf07e,x lda lf165,x sta $63 lda #$00 tay sta ($63),y iny sta ($63),y iny sta ($63),y lda #$08 sta lf017,x sta lf09c,x iny sta ($63),y iny sta ($63),y lda #$40 sta lf01a,x sta ($63),y lda #$20 sta lf01d,x iny sta ($63),y lda #$f5 sta lf020,x iny sta ($63),y dex bpl lf253 lf2af txa ldx #$17 lf2b2 sta lf13e,x dex bpl lf2b2 lf2b8 lda $61 clc adc #$06 sta $63 lda #$00 tax tay adc $62 lf2c5 sta $64 sta lf0ab,x sta lf0b4,x lda $63 sta lf0a8,x sta lf0b1,x clc adc ($61),y sta $63 lda $64 iny adc ($61),y iny inx cpx #$03 bne lf2c5 lf2e5 ldx $63 tay rts lf2e9 lda #$00 sta $d504 sta $d50b sta $d512 sta $d501 sta $d508 sta $d50f lda #$08 sta $d517 lda lf15b sta $dc04 lda lf15c sta $dc05 rts lf30f nop nop nop nop nop nop nop nop nop nop nop nop nop nop rts lf31e lda #$08 sta lf000 lf323 jmp (lf15d) lf326 nop nop nop lf329 lda lf000 bmi lf31e lf32e ora #$80 tay and #$07 beq lf323 lf335 cld sty lf000 nop lda $fb sta lf156 lda $fc sta lf157 lda $fd sta lf158 lda $fe sta lf159 lda $ff sta lf15a lda lf023 clc adc lf0d9 pha and #$07 tay lda lf0dc adc #$00 sta $ff pla lsr $ff ror lsr $ff ror lsr $ff ror clc adc lf024 sty $d515 sta $d516 lda lf025 sta $d517 lda lf026 sta $d518 lda #$d5 sta $fc ldx #$00 lf38b lda lf000 and lf162,x beq lf3e4 lf393 lda lf165,x sta $fb lda lf00e,x clc adc lf051,x tay lda lf011,x adc lf054,x pha tya clc adc lf0cd,x ldy #$00 sta ($fb),y pla adc lf0d0,x iny sta ($fb),y lda lf014,x clc adc lf069,x sta $ff lda lf017,x adc lf06c,x pha lda $ff clc adc lf0d3,x iny sta ($fb),y pla adc lf0d6,x iny sta ($fb),y lda lf01d,x iny iny sta ($fb),y lda lf020,x iny sta ($fb),y lf3e4 inx cpx #$03 bne lf38b lf3e9 ldy lf01a ldx lf01b lda lf01c sty $d504 stx $d50b sta $d512 ldx lf02d ldy lf02e stx $dc04 sty $dc05 lda $d51b sta lf0be lda $d51c sta lf0bf ldx #$00 lf415 lda lf000 and lf162,x beq lf42d lf41d stx lf02f jsr lf536 lda lf000 and #$78 beq lf42d lf42a jmp lf50c lf42d inx cpx #$03 bne lf415 lf432 lda lf0c9 bne lf489 lf437 lda lf0ca ora lf0cb beq lf4b7 lf43f lda lf0df bne lf46c lf444 lda lf0ca beq lf471 lf449 clc adc lf0bd bcs lf456 lf44f cmp lf0cc bcc lf4b4 lf454 beq lf4b4 lf456 lda #$00 sta lf0df lda lf0cb beq lf4b4 lf460 inc lf0df lda lf0bd sbc lf0cb jmp lf4b4 lf46c lda lf0cb beq lf444 lf471 lda lf0bd sec sbc lf0cb bcs lf4b4 lf47a lda #$00 sta lf0df lda lf0ca bne lf4b4 lf484 inc lf0df bne lf4b1 lf489 dec lf0e0 bne lf4b7 lf48e lda lf0df bne lf4a4 lf493 inc lf0df lda lf0cb bne lf49d lf49b lda #$20 lf49d sta lf0e0 lda #$00 beq lf4b4 lf4a4 dec lf0df lda lf0ca bne lf4ae lf4ac lda #$20 lf4ae sta lf0e0 lf4b1 lda lf0cc lf4b4 sta lf0bd lf4b7 ldx #$00 lf4b9 lda lf0c3,x beq lf502 lf4be lda #$00 sta $ff ldy lf0c0,x lda lf0bd,y ldy lf0c6,x beq lf4db lf4cd bmi lf4d7 lf4cf asl rol $ff dey bne lf4cf lf4d5 beq lf4db lf4d7 lsr iny bne lf4d7 lf4db ldy lf0c3,x dey bne lf4ec lf4e1 sta lf0cd,x lda $ff sta lf0d0,x jmp lf502 lf4ec dey bne lf4fa lf4ef sta lf0d3,x lda $ff sta lf0d6,x jmp lf502 lf4fa sta lf0d9 lda $ff sta lf0dc lf502 inx cpx #$03 bne lf4b9 lf507 lda lf000 and #$7f lf50c sta lf000 lda lf156 sta $fb lda lf157 sta $fc lda lf158 sta $fd lda lf159 sta $fe lda lf15a sta $ff jmp (lf15d) lf52b lda lf060,x bne lf533 lf530 jmp lf69f lf533 jmp lf5ba lf536 dec lf030,x bne lf53e lf53b jmp lf6a0 lf53e lda lf036,x bmi lf52b lf543 bne lf55f lf545 lda lf03f,x beq lf54f lf54a dec lf03f,x bne lf55f lf54f lda lf039,x cmp lf030,x bcc lf55f lf557 lda lf01a,x and #$fe sta lf01a,x lf55f lda lf042,x beq lf5ba lf564 asl lda lf00e,x bcs lf587 lf56a adc lf045,x sta lf00e,x tay lda lf011,x adc lf048,x sta lf011,x pha tya cmp lf08d,x pla sbc lf090,x bcs lf5a4 lf585 bcc lf5b5 lf587 sbc lf045,x sta lf00e,x lda lf011,x sbc lf048,x sta lf011,x lda lf08d,x cmp lf00e,x lda lf090,x sbc lf011,x bcc lf5b5 lf5a4 lda lf08d,x sta lf00e,x lda lf090,x sta lf011,x lda #$00 sta lf042,x lf5b5 lda lf060,x beq lf60f lf5ba lda lf04b,x beq lf60a lf5bf ldy #$00 dec lf04e,x bne lf5f7 lf5c6 lda lf051,x ora lf054,x bne lf5e9 lf5ce lda lf05d,x sta lf057,x sta lf04e,x lda lf04b,x asl lda lf05a,x bcc lf5e4 lf5e0 eor #$ff adc #$00 lf5e4 sta lf04b,x bne lf5f9 lf5e9 lda lf057,x sta lf04e,x tya sec sbc lf04b,x sta lf04b,x lf5f7 cmp #$00 lf5f9 bpl lf5fc lf5fb dey lf5fc clc adc lf051,x sta lf051,x tya adc lf054,x sta lf054,x lf60a lda lf036,x bmi lf624 lf60f lda lf093,x beq lf624 lf614 clc adc lf014,x sta lf014,x lda lf096,x adc lf017,x sta lf017,x lf624 lda lf063,x beq lf674 lf629 ldy #$00 dec lf066,x bne lf661 lf630 lda lf069,x ora lf06c,x bne lf653 lf638 lda lf072,x sta lf06f,x sta lf066,x lda lf063,x asl lda lf075,x bcc lf64e lf64a eor #$ff adc #$00 lf64e sta lf063,x bne lf663 lf653 lda lf06f,x sta lf066,x tya sec sbc lf063,x sta lf063,x lf661 cmp #$00 lf663 bpl lf666 lf665 dey lf666 clc adc lf069,x sta lf069,x tya adc lf06c,x sta lf06c,x lf674 lda lf036,x bpl lf67c lf679 jmp lf69f lf67c ldy #$00 lda lf0a2,x beq lf69f lf683 bpl lf686 lf685 iny lf686 clc adc lf023 pha and #$07 sta lf023 pla ror lsr lsr clc adc lf1a6,y clc adc lf024 sta lf024 lf69f rts lf6a0 lda lf0a8,x sta $fd lda lf0ab,x sta $fe bne lf6b0 lf6ac rts lf6ad jsr lf898 lf6b0 lda lf000 and lf162,x beq lf6ac lf6b8 ldy #$00 lda ($fd),y sta $ff iny lda ($fd),y tay lda $fd clc adc #$02 sta $fd sta lf0a8,x lda $fe adc #$00 sta $fe sta lf0ab,x lda $ff and #$03 bne lf6ad lf6db lda lf08d,x sta lf00e,x lda lf090,x sta lf011,x lda $ff sta lf005,x tya sta lf002,x and #$07 tay lda lf167,y sta lf16f lda lf002,x and #$38 lsr lsr lsr adc lf081,x sta $fd lda lf002,x and #$c0 asl rol rol tay lda lf16f,y sta $fe lda lf002,x and #$07 beq lf77d lf71b tay lda lf172,y adc $fe clc adc lf084,x bpl lf72c lf727 clc adc #$0c inc $fd lf72c cmp #$0c bcc lf734 lf730 sbc #$0c dec $fd lf734 sta $fe tay lda lf186,y sta $ff lda lf17a,y ldy $fd dey bmi lf74a lf744 lsr $ff ror dey bpl lf744 lf74a clc adc lf087,x sta lf08d,x lda $ff adc lf08a,x sta lf090,x lda lf005,x bne lf761 lf75e jmp lf6a0 lf761 lda lf045,x ora lf048,x beq lf77f lf769 lda lf00e,x cmp lf08d,x lda lf011,x sbc lf090,x lda #$fe ror sta lf042,x bcc lf78e lf77d beq lf7c9 lf77f sta lf042,x lda lf08d,x sta lf00e,x lda lf090,x sta lf011,x lf78e lda lf036,x asl bne lf7c9 lf794 lda lf093,x beq lf7a5 lf799 lda lf099,x sta lf014,x lda lf09c,x sta lf017,x lf7a5 lda lf09f,x beq lf7b9 lf7aa ldy $fd clc adc lf192,y ldy $fe clc adc lf19a,y clc bcc lf7c1 lf7b9 lda lf0a2,x beq lf7c9 lf7be lda lf0a5,x lf7c1 sta lf024 lda #$00 sta lf023 lf7c9 lda lf03c,x sta lf03f,x lda lf005,x and #$40 sta lf036,x lda lf005,x lsr lsr and #$07 bne lf810 lf7e0 lda lf005,x bmi lf7f9 lf7e5 lda lf027 and #$3c bne lf80a lf7ec lda lf027 asl rol rol bne lf7f6 lf7f4 lda #$04 lf7f6 jmp lf870 lf7f9 lda lf028 beq lf80a lf7fe and #$3f bne lf80a lf802 lda lf028 asl rol rol bne lf870 lf80a lda #$10 sta lf000 rts lf810 cmp #$01 bne lf827 lf814 lda lf005,x and #$20 bne lf821 lf81b lda lf029 jmp lf870 lf821 lda lf02a,x jmp lf870 lf827 tay lda lf005,x and #$a0 cmp #$80 beq lf861 lf831 sta $ff clc lda lf027 bne lf83a lf839 sec lf83a dey dey beq lf844 lf83e ror bcs lf88f lf841 dey bne lf83e lf844 ldy $ff sta $ff beq lf870 lf84a lsr $ff bcs lf88f lf84e beq lf892 lf850 adc $ff bcs lf892 lf854 iny bpl lf870 lf857 lsr $ff bcs lf88f lf85b adc $ff bcc lf870 lf85f bcs lf892 lf861 lda lf028 beq lf88f lf866 dey dey beq lf870 lf86a lsr bcs lf88f lf86d dey bne lf86a lf870 sta lf030,x lda lf01a,x and #$f6 sta lf01a,x sec lda lf002,x and #$07 bne lf886 lf883 ror lf036,x lf886 lda lf01a,x adc #$00 sta lf01a,x rts lf88f lda #$10 lf892 = * + 1 ; Instruction parameter jumped to. bit $18a9 sta lf000 rts lf898 tya pha lda $ff lsr bcc lf8a2 lf89f jmp lfa42 lf8a2 lsr lsr bcs lf8c4 lf8a6 lsr bcs lf8b7 lf8a9 sta lf09c,x sta lf017,x pla sta lf099,x sta lf014,x rts lf8b7 lsr bcc lf8bc lf8ba ora #$f8 lf8bc sta lf08a,x pla sta lf087,x rts lf8c4 lsr bcs lf8ca lf8c7 jmp lf94a lf8ca lsr bcs lf92e lf8cd lsr bcs lf8df lf8d0 bne lf8da lf8d2 pla sta lf0a5,x sta lf024 rts lf8da pla sta lf03c,x rts lf8df bne lf929 lf8e1 pla sta lf07e,x cmp #$5b beq lf91c lf8e9 tay lsr lsr lsr sec sbc #$0b clc adc lf084,x bmi lf902 lf8f6 cmp #$0c bcc lf90b lf8fa sbc #$0c dec lf081,x jmp lf90b lf902 cmp #$f5 bcs lf90b lf906 adc #$0c inc lf081,x lf90b sta lf084,x tya and #$07 sec sbc #$03 clc adc lf081,x sta lf081,x rts lf91c lda lf078,x sta lf081,x lda lf07b,x sta lf084,x rts lf929 pla sta lf0c6,x rts lf92e lsr bcs lf939 lf931 sta lf00b,x pla sta lf008,x rts lf939 lsr ror ror adc lf15b sta lf02d pla adc lf15c sta lf02e rts lf94a lsr bcc lf950 lf94d jmp lf9d3 lf950 lsr bcs lf993 lf953 lsr bcs lf96d lf956 lsr bcs lf968 lf959 pla sta lf027 lsr lsr lsr tay lda lf1af,y sta lf028 rts lf968 pla sta lf05d,x rts lf96d lsr bcs lf975 lf970 pla sta lf001 rts lf975 pla beq lf989 lf978 sta lf075,x ldy lf063,x bne lf988 lf980 sta lf063,x lda #$01 sta lf066,x lf988 rts lf989 sta lf063,x sta lf069,x sta lf06c,x rts lf993 lsr bcs lf9c6 lf996 lsr bcs lf99e lf999 pla sta lf039,x rts lf99e pla ldy #$00 lsr bcc lf9a6 lf9a4 iny clc lf9a6 pha and #$07 adc lf1ac,y sta lf078,x sta lf081,x pla lsr lsr lsr clc adc lf1ad,y sta lf07b,x sta lf084,x lda #$5b sta lf07e,x rts lf9c6 lsr bcs lf9ce lf9c9 pla sta lf0a2,x rts lf9ce pla sta lf0cc rts lf9d3 lsr bcs lf9fd lf9d6 lsr bcs lf9e6 lf9d9 lsr bcs lf9e1 lf9dc pla sta lf029 rts lf9e1 pla sta lf09f,x rts lf9e6 lsr bcs lf9f8 lf9e9 pla sta lf093,x ldy #$00 asl bcc lf9f3 lf9f2 dey lf9f3 tya sta lf096,x rts lf9f8 pla sta lf072,x rts lf9fd lsr bcs lfa1c lfa00 lsr bcs lfa18 lfa03 pla sta lf0b7,x lda $fd sta lf0b1,x lda $fe sta lf0b4,x lda lf033,x sta lf0ae,x rts lfa18 pla jmp (lf15f) lfa1c lsr bcs lfa3d lfa1f pla bne lfa2c lfa22 sta lf04b,x sta lf051,x sta lf054,x rts lfa2c sta lf05a,x ldy lf04b,x bne lfa3c lfa34 sta lf04b,x lda #$01 sta lf04e,x lfa3c rts lfa3d pla sta lf02a,x rts lfa42 lsr bcc lfa4d lfa45 sta lf048,x pla sta lf045,x rts lfa4d pla lsr bcs lfab2 lfa51 lsr bcs lfa79 lfa54 lsr bcs lfa5c lfa57 lsr ldy #$f0 bne lfa62 lfa5c asl asl asl asl ldy #$0f lfa62 sta $ff tya bcs lfa70 lfa67 and lf01d,x ora $ff sta lf01d,x rts lfa70 and lf020,x ora $ff sta lf020,x rts lfa79 lsr bcs lfab4 lfa7c lsr bcs lfae3 lfa7f sta $ff lda lf0ba,x cmp lf1a9,x beq lfadd lfa89 inc lf0ba,x tay lda $fd sta lf0e1,y lda $fe sta lf0f0,y lda lf033,x sta lf12f,y ldy $ff lda lf117,y beq lfada lfaa4 sta $fe lda lf0ff,y sta $fd lda lf13e,y sta lf033,x rts lfab2 bcs lfaff lfab4 lsr bcs lfaf3 lfab7 tay lda $fd sta lf0ff,y lda $fe sta lf117,y lda lf033,x sta lf13e,y lda lf0ba,x cmp lf1a9,x beq lfadd lfad0 inc lf0ba,x tay lda #$00 sta lf0f0,y rts lfada lda #$30 lfadd = * + 1 ; Instruction parameter jumped to. bit $28a9 sta lf000 rts lfae3 asl asl asl asl eor lf025 and #$f0 eor lf025 sta lf025 rts lfaf3 eor lf026 and #$0f eor lf026 sta lf026 rts lfaff lsr bcs lfb0d lfb02 lsr bcs lfb09 lfb05 sta lf0ca rts lfb09 sta lf0cb rts lfb0d lsr bcc lfb13 lfb10 jmp lfba5 lfb13 lsr tay beq lfb38 lfb17 dey beq lfb4e lfb1a dey beq lfb5f lfb1d dey beq lfb6a lfb20 dey beq lfb75 lfb23 dey beq lfb82 lfb26 dey beq lfb8f lfb29 dey beq lfb9f lfb2c and #$07 ora #$10 bcs lfb35 lfb32 jmp lfab7 lfb35 jmp lfa7f lfb38 ldy lf026 bcs lfb44 lfb3d iny tya and #$0f bne lfb4a lfb43 rts lfb44 tya and #$0f beq lfb4d lfb49 dey lfb4a sty lf026 lfb4d rts lfb4e lda lf162,x eor #$ff and lf025 bcc lfb5b lfb58 ora lf162,x lfb5b sta lf025 rts lfb5f lda lf01a,x and #$fb bcc lfbbb lfb66 ora #$04 bcs lfbbb lfb6a lda lf01a,x and #$fd bcc lfbbb lfb71 ora #$02 bcs lfbbb lfb75 lda lf025 and #$f7 bcc lfb7e lfb7c ora #$08 lfb7e sta lf025 rts lfb82 lda lf026 and #$7f bcc lfb8b lfb89 ora #$80 lfb8b sta lf026 rts lfb8f tya sta lf0bd sta lf0df iny sty lf0e0 rol sta lf0c9 rts lfb9f tya rol sta lf060,x rts lfba5 lsr bcs lfbcf lfba8 lsr bcs lfbbf lfbab bne lfbaf lfbad lda #$08 lfbaf asl asl asl asl eor lf01a,x and #$f0 eor lf01a,x lfbbb sta lf01a,x rts lfbbf asl asl asl asl eor lf026 and #$70 eor lf026 sta lf026 rts lfbcf lsr bcc lfbd6 lfbd2 sta lf0c0,x rts lfbd6 tay beq lfbf9 lfbd9 dey beq lfc1c lfbdc dey beq lfc42 lfbdf and #$03 sta lf0c3,x lda #$00 sta lf0cd,x sta lf0d0,x sta lf0d3,x sta lf0d6,x sta lf0d9 sta lf0dc rts lfbf9 lda lf0b7,x beq lfc03 lfbfe dec lf0b7,x beq lfc15 lfc03 lda lf033,x cmp lf0ae,x bne lfc16 lfc0b lda lf0b1,x sta $fd lda lf0b4,x sta $fe lfc15 rts lfc16 lda #$38 sta lf000 rts lfc1c lda lf0ba,x cmp lf1a8,x beq lfc3c lfc24 dec lf0ba,x tay dey lda lf0f0,y beq lfc3b lfc2e sta $fe lda lf0e1,y sta $fd lda lf12f,y sta lf033,x lfc3b rts lfc3c lda #$20 sta lf000 rts lfc42 lda lf000 eor lf162,x sta lf000 lda #$01 sta lf030,x rts lfc51 lda lf000 and #$07 sta lfc81 bne lfc5e lfc5b jsr lf2e9 lfc5e rts .byt $00 lfc60 ldx #$51 ldy #$fc stx lf15d sty lf15e jsr lf1cf ldx #$00 ldy #$09 jsr lf200 lda #$07 sta lf000 sta lfc81 lfc7c rts .byt $00,$00,$00 lfc80 lfc81 = * + 1 ; Instruction parameter accessed. lda #$00 and #$ff beq lfc7c lfc86 jmp lf329 lfc89 lda #$07 sta lf000 rts .byt $00 lfc90 jsr $ec60 jmp lfc60 lfc96 jsr $ec80 jmp lfc80 libsidplayfp-3.0.0/src/sidtune/SidTuneCfg.h0000644000175100017510000000114115175333711014270 /* SidTuneCfg.h (template) */ #ifndef SIDTUNECFG_H #define SIDTUNECFG_H #ifdef HAVE_CONFIG_H # include "config.h" #endif // Define the file/path separator(s) that your filesystem uses: // SID_FS_IS_COLON_AND_BACKSLASH, SID_FS_IS_COLON_AND_SLASH, // SID_FS_IS_BACKSLASH, SID_FS_IS_COLON, SID_FS_IS_SLASH #if defined(_WIN32) || defined(_MSDOS) || defined(_OS2) # define SID_FS_IS_COLON_AND_BACKSLASH_AND_SLASH #elif defined(__APPLE__) && defined(__MACH__) # define SID_FS_IS_COLON #elif defined(AMIGA) # define SID_FS_IS_COLON_AND_SLASH #else # define SID_FS_IS_SLASH #endif #endif /* SIDTUNECFG_H */ libsidplayfp-3.0.0/src/sidtune/SidTuneBase.h0000644000175100017510000002071015175333711014446 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2021 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDTUNEBASE_H #define SIDTUNEBASE_H #include #include #include #include #include "sidplayfp/SidTuneInfo.h" #include "sidplayfp/siddefs.h" #include "SmartPtr.h" #include "SidTuneInfoImpl.h" #include "sidcxx11.h" namespace libsidplayfp { class sidmemory; template class SmartPtr_sidtt; /** * loadError */ class loadError { private: const char* m_msg; public: explicit loadError(const char* msg) : m_msg(msg) {} const char* message() const { return m_msg; } }; /** * SidTuneBaseBase */ class SidTuneBase { protected: using buffer_t = std::vector; protected: /// Also PSID file format limit. static constexpr unsigned int MAX_SONGS = 256; // Generic error messages static const char ERR_TRUNCATED[]; static const char ERR_INVALID[]; public: // ---------------------------------------------------------------- virtual ~SidTuneBase() = default; using LoaderFunc = void (*)(const char* fileName, buffer_t& bufferRef); /** * Load a sidtune from a file. * * To retrieve data from standard input pass in filename "-". * If you want to override the default filename extensions use this * contructor. Please note, that if the specified "sidTuneFileName" * does exist and the loader is able to determine its file format, * this function does not try to append any file name extension. * See "SidTune.cpp" for the default list of file name extensions. * * @param fileName * @param fileNameExt * @param separatorIsSlash * @return the sid tune * @throw loadError */ static SidTuneBase* load(const char* fileName, const char **fileNameExt, bool separatorIsSlash) { return load(nullptr, fileName, fileNameExt, separatorIsSlash); } /** * Load a sidtune from a file, using a file access callback. * * Uses the same call methodology as the above function, only * a callback is supplied, which will be used to read every * file this function accesses. * * @param loader * @param fileName * @param fileNameExt * @param separatorIsSlash * @return the sid tune * @throw loadError */ static SidTuneBase* load(LoaderFunc loader, const char* fileName, const char **fileNameExt, bool separatorIsSlash); /** * Load a single-file sidtune from a memory buffer. * Currently supported: PSID format * * @param sourceBuffer * @param bufferLen * @return the sid tune * @throw loadError */ static SidTuneBase* read(const uint_least8_t* sourceBuffer, uint_least32_t bufferLen) { return getFromBuffer(sourceBuffer, bufferLen); } /** * Select sub-song (0 = default starting song) * and return active song number out of [1,2,..,SIDTUNE_MAX_SONGS]. * * @param songNum * @return the active song */ unsigned int selectSong(unsigned int songNum); /** * Retrieve sub-song specific information. */ const SidTuneInfo* getInfo() const { return info.get(); } /** * Select sub-song (0 = default starting song) * and retrieve active song information. * * @param songNum */ const SidTuneInfo* getInfo(unsigned int songNum) { selectSong(songNum); return info.get(); } /** * Copy sidtune into C64 memory (64 KB). * * @param mem */ virtual void placeSidTuneInC64mem(sidmemory& mem); /** * Calculates the MD5 hash of the tune. * Not providing an md5 buffer will cause the internal one to be used. * If provided, buffer must be MD5_LENGTH + 1 * * @return a pointer to the buffer containing the md5 string. */ virtual const char *createMD5(char *) { return nullptr; } /** * Calculates the MD5 hash of the tune. * Not providing an md5 buffer will cause the internal one to be used. * If provided, buffer must be MD5_LENGTH + 1 * * @return a pointer to the buffer containing the md5 string. */ virtual const char *createMD5New(char *) { return nullptr; } /** * Get the pointer to the tune data. */ const uint_least8_t* c64Data() const { return &cache[fileOffset]; } protected: // ------------------------------------------------------------- std::unique_ptr info; uint_least8_t songSpeed[MAX_SONGS]; SidTuneInfo::clock_t clockSpeed[MAX_SONGS]; /// For files with header: offset to real data uint_least32_t fileOffset; buffer_t cache; protected: SidTuneBase(); /** * Does not affect status of object, and therefore can be used * to load files. Error string is put into info.statusString, though. * * @param fileName * @param bufferRef * @throw loadError */ static void loadFile(const char* fileName, buffer_t& bufferRef); /** * Convert 32-bit PSID-style speed word to internal tables. * * @param speed * @param clock */ void convertOldStyleSpeedToTables(uint_least32_t speed, SidTuneInfo::clock_t clock = SidTuneInfo::CLOCK_PAL); /** * Check if compatibility constraints are fulfilled. */ bool checkCompatibility(); /** * Check for valid relocation information. */ bool checkRelocInfo(); /** * Common address resolution procedure. * * @param c64data */ void resolveAddrs(const uint_least8_t* c64data); /** * Cache the data of a single-file or two-file sidtune and its * corresponding file names. * * @param dataFileName * @param infoFileName * @param buf * @param isSlashedFileName If your opendir() and readdir()->d_name return path names * that contain the forward slash (/) as file separator, but * your operating system uses a different character, there are * extra functions that can deal with this special case. Set * separatorIsSlash to true if you like path names to be split * correctly. * You do not need these extra functions if your systems file * separator is the forward slash. * @throw loadError */ virtual void acceptSidTune(const char* dataFileName, const char* infoFileName, buffer_t& buf, bool isSlashedFileName); /** * Petscii to Ascii converter. */ static std::string petsciiToAscii(SmartPtr_sidtt& spPet); private: // --------------------------------------------------------------- #if !defined(SIDTUNE_NO_STDIN_LOADER) static SidTuneBase* getFromStdIn(); #endif static SidTuneBase* getFromFiles(const char* fileName, const char **fileNameExtensions, bool separatorIsSlash) { return getFromFiles(nullptr, fileName, fileNameExtensions, separatorIsSlash); } static SidTuneBase* getFromFiles(LoaderFunc loader, const char* fileName, const char **fileNameExtensions, bool separatorIsSlash); /** * Try to retrieve single-file sidtune from specified buffer. */ static SidTuneBase* getFromBuffer(const uint_least8_t* const buffer, uint_least32_t bufferLen); /** * Get new file name with specified extension. * * @param destString destinaton string * @param sourceName original file name * @param sourceExt new extension */ static void createNewFileName(std::string& destString, const char* sourceName, const char* sourceExt); private: // prevent copying SidTuneBase(const SidTuneBase&) = delete; SidTuneBase& operator=(SidTuneBase&) = delete; }; } #endif /* SIDTUNEBASE_H */ libsidplayfp-3.0.0/src/sidtune/MUS.cpp0000644000175100017510000002104515175333711013301 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2022 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "MUS.h" #include #include "sidplayfp/SidTuneInfo.h" #include "c64/CPU/opcodes.h" #include "SmartPtr.h" #include "sidendian.h" #include "sidmemory.h" static const uint8_t sidplayer1[] = { # include "sidplayer1.bin" }; static const uint8_t sidplayer2[] = { # include "sidplayer2.bin" }; namespace libsidplayfp { // Format strings const char TXT_FORMAT_MUS[] = "C64 Sidplayer format (MUS)"; const char TXT_FORMAT_STR[] = "C64 Stereo Sidplayer format (MUS+STR)"; // Error strings const char ERR_2ND_INVALID[] = "SIDTUNE ERROR: 2nd file contains invalid data"; const char ERR_SIZE_EXCEEDED[] = "SIDTUNE ERROR: Total file size too large"; constexpr uint_least16_t SIDTUNE_MUS_HLT_CMD = 0x14F; constexpr uint_least16_t SIDTUNE_MUS_DATA_ADDR = 0x0900; constexpr uint_least16_t SIDTUNE_SID2_BASE_ADDR = 0xd500; constexpr int o65headersize = 27; const uint8_t* player1 = sidplayer1 + o65headersize; const uint8_t* player2 = sidplayer2 + o65headersize; const size_t player1size = sizeof(sidplayer1) - o65headersize; const size_t player2size = sizeof(sidplayer2) - o65headersize; bool detect(const uint8_t* buffer, size_t bufsize, uint_least32_t& voice3Index) { // sanity check if ((buffer == nullptr) || (bufsize < 8)) return false; // Skip load address and 3x length entry. uint_least32_t voice1Index = 2 + 3 * 2; // Add length of voice 1 data. voice1Index += endian_little16(&buffer[2]); // Add length of voice 2 data. uint_least32_t voice2Index = voice1Index + endian_little16(&buffer[4]); // Add length of voice 3 data. voice3Index = voice2Index + endian_little16(&buffer[6]); if (voice3Index > bufsize) return false; return ((endian_big16(&buffer[voice1Index - 2]) == SIDTUNE_MUS_HLT_CMD) && (endian_big16(&buffer[voice2Index - 2]) == SIDTUNE_MUS_HLT_CMD) && (endian_big16(&buffer[voice3Index - 2]) == SIDTUNE_MUS_HLT_CMD)); } void MUS::setPlayerAddress() { if (info->getSidChips() == 1) { // Player #1. info->m_initAddr = 0xec60; info->m_playAddr = 0xec80; } else { // Player #1 + #2. info->m_initAddr = 0xfc90; info->m_playAddr = 0xfc96; } } void MUS::acceptSidTune(const char* dataFileName, const char* infoFileName, buffer_t& buf, bool isSlashedFileName) { setPlayerAddress(); SidTuneBase::acceptSidTune(dataFileName, infoFileName, buf, isSlashedFileName); } void MUS::placeSidTuneInC64mem(sidmemory& mem) { SidTuneBase::placeSidTuneInC64mem(mem); installPlayer(mem); } bool MUS::mergeParts(buffer_t& musBuf, buffer_t& strBuf) const { const uint_least32_t mergeLen = musBuf.size() + strBuf.size(); // Sanity check. I do not trust those MUS/STR files around. const uint_least32_t freeSpace = endian_16(player1[1], player1[0]) - SIDTUNE_MUS_DATA_ADDR; if ((mergeLen - 4) > freeSpace) { throw loadError(ERR_SIZE_EXCEEDED); } if (!strBuf.empty() && info->getSidChips() > 1) { // Install MUS data #2 _NOT_ including load address. musBuf.insert(musBuf.end(), strBuf.begin(), strBuf.end()); } strBuf.clear(); return true; } /** * Replace useless SID reads with NOPs. */ void removeReads(sidmemory& mem, uint_least16_t dest) { const int sid_read_offset = 0x424 - o65headersize - 2; mem.fillRam(dest + sid_read_offset, NOPn, 12); } void MUS::installPlayer(sidmemory& mem) const { // Install MUS player #1. uint_least16_t dest = endian_16(player1[1], player1[0]); mem.fillRam(dest, player1 + 2, player1size - 2); removeReads(mem, dest); // Point player #1 to data #1. mem.writeMemByte(dest + 0xc6e, (SIDTUNE_MUS_DATA_ADDR + 2) & 0xFF); mem.writeMemByte(dest + 0xc70, (SIDTUNE_MUS_DATA_ADDR + 2) >> 8); if (info->getSidChips() > 1) { // Install MUS player #2. dest = endian_16(player2[1], player2[0]); mem.fillRam(dest, player2 + 2, player2size - 2); removeReads(mem, dest); // Point player #2 to data #2. mem.writeMemByte(dest + 0xc6e, (SIDTUNE_MUS_DATA_ADDR + musDataLen + 2) & 0xFF); mem.writeMemByte(dest + 0xc70, (SIDTUNE_MUS_DATA_ADDR + musDataLen + 2) >> 8); } } SidTuneBase* MUS::load(buffer_t& dataBuf, bool init) { buffer_t empty; return load(dataBuf, empty, 0, init); } SidTuneBase* MUS::load(buffer_t& musBuf, buffer_t& strBuf, uint_least32_t fileOffset, bool init) { uint_least32_t voice3Index; if (!detect(&musBuf[fileOffset], musBuf.size()-fileOffset, voice3Index)) return nullptr; std::unique_ptr tune(new MUS()); tune->tryLoad(musBuf, strBuf, fileOffset, voice3Index, init); tune->mergeParts(musBuf, strBuf); return tune.release(); } void MUS::tryLoad(const buffer_t& musBuf, const buffer_t& strBuf, uint_least32_t fileOffset, uint_least32_t voice3Index, bool init) { if (init) { info->m_songs = 1; info->m_startSong = 1; songSpeed[0] = SidTuneInfo::SPEED_CIA_1A; clockSpeed[0] = SidTuneInfo::CLOCK_ANY; } // Check setting compatibility for MUS playback if ((info->m_compatibility != SidTuneInfo::COMPATIBILITY_C64) || (info->m_relocStartPage != 0) || (info->m_relocPages != 0)) { throw loadError(ERR_INVALID); } { // All subtunes should be CIA for (unsigned int i = 0; i < info->m_songs; i++) { if (songSpeed[i] != SidTuneInfo::SPEED_CIA_1A) { throw loadError(ERR_INVALID); } } } musDataLen = musBuf.size(); info->m_loadAddr = SIDTUNE_MUS_DATA_ADDR; SmartPtr_sidtt spPet(&musBuf[fileOffset], musDataLen - fileOffset); // Voice3Index now is offset to text lines (uppercase Pet-strings). spPet += voice3Index; // Extract credits while (*spPet) { info->m_commentString.push_back(petsciiToAscii(spPet)); } spPet++; // If we appear to have additional data at the end, check is it's // another mus file (but only if a second file isn't supplied) bool stereo = false; if (!strBuf.empty()) { if (!detect(&strBuf[0], strBuf.size(), voice3Index)) throw loadError(ERR_2ND_INVALID); spPet.setBuffer(&strBuf[0], strBuf.size()); stereo = true; } else { // For MUS + STR via stdin the files come combined if (spPet.good()) { const ulint_smartpt pos = spPet.tellPos(); if (detect(&spPet[0], spPet.tellLength()-pos, voice3Index)) { musDataLen = static_cast(pos); stereo = true; } } } if (stereo) { // Voice3Index now is offset to text lines (uppercase Pet-strings). spPet += voice3Index; // Extract credits while (*spPet) { info->m_commentString.push_back(petsciiToAscii(spPet)); } info->m_sidChipAddresses.push_back(SIDTUNE_SID2_BASE_ADDR); info->m_formatString = TXT_FORMAT_STR; } else { info->m_formatString = TXT_FORMAT_MUS; } setPlayerAddress(); // Remove trailing empty lines. const int lines = info->m_commentString.size(); { for (int line = lines-1; line >= 0; line--) { if (info->m_commentString[line].length() == 0) info->m_commentString.pop_back(); else break; } } } } libsidplayfp-3.0.0/src/sidtune/SidTuneInfoImpl.h0000644000175100017510000001143115175333711015311 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2015 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SIDTUNEINFOIMPL_H #define SIDTUNEINFOIMPL_H #include #include #include #include "sidplayfp/SidTuneInfo.h" #include "sidcxx11.h" namespace libsidplayfp { /** * The implementation of the SidTuneInfo interface. */ class SidTuneInfoImpl final : public SidTuneInfo { public: const char* m_formatString; unsigned int m_songs; unsigned int m_startSong; unsigned int m_currentSong; int m_songSpeed; clock_t m_clockSpeed; compatibility_t m_compatibility; uint_least32_t m_dataFileLen; uint_least32_t m_c64dataLen; uint_least16_t m_loadAddr; uint_least16_t m_initAddr; uint_least16_t m_playAddr; uint_least8_t m_relocStartPage; uint_least8_t m_relocPages; std::string m_path; std::string m_dataFileName; std::string m_infoFileName; std::vector m_sidModels; std::vector m_sidChipAddresses; std::vector m_infoString; std::vector m_commentString; bool m_fixLoad; private: // prevent copying SidTuneInfoImpl(const SidTuneInfoImpl&) = delete; SidTuneInfoImpl& operator=(SidTuneInfoImpl&) = delete; public: SidTuneInfoImpl() : m_formatString("N/A"), m_songs(0), m_startSong(0), m_currentSong(0), m_songSpeed(SPEED_VBI), m_clockSpeed(CLOCK_UNKNOWN), m_compatibility(COMPATIBILITY_C64), m_dataFileLen(0), m_c64dataLen(0), m_loadAddr(0), m_initAddr(0), m_playAddr(0), m_relocStartPage(0), m_relocPages(0), m_fixLoad(false) { m_sidModels.push_back(SIDMODEL_UNKNOWN); m_sidChipAddresses.push_back(0xd400); } uint_least16_t getLoadAddr() const override { return m_loadAddr; } uint_least16_t getInitAddr() const override { return m_initAddr; } uint_least16_t getPlayAddr() const override { return m_playAddr; } unsigned int getSongs() const override { return m_songs; } unsigned int getStartSong() const override { return m_startSong; } unsigned int getCurrentSong() const override { return m_currentSong; } uint_least16_t getSidChipBase(unsigned int i) const override { return i < m_sidChipAddresses.size() ? m_sidChipAddresses[i] : 0; } int getSidChips() const override { return m_sidChipAddresses.size(); } int getSongSpeed() const override { return m_songSpeed; } uint_least8_t getRelocStartPage() const override { return m_relocStartPage; } uint_least8_t getRelocPages() const override { return m_relocPages; } model_t getSidModel(unsigned int i) const override { return i < m_sidModels.size() ? m_sidModels[i] : SIDMODEL_UNKNOWN; } compatibility_t getCompatibility() const override { return m_compatibility; } unsigned int getNumberOfInfoStrings() const override { return m_infoString.size(); } const char* getInfoString(unsigned int i) const override { return i * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef PRG_H #define PRG_H #include "SidTuneBase.h" #include "sidcxx11.h" namespace libsidplayfp { class prg final : public SidTuneBase { protected: prg() {} private: void load(); public: /** * @return pointer to a SidTune or 0 if not a prg file * @throw loadError if prg file is corrupt */ static SidTuneBase* load(const char *fileName, const buffer_t& dataBuf); ~prg() override = default; private: // prevent copying prg(const prg&) = delete; prg& operator=(prg&) = delete; }; } #endif libsidplayfp-3.0.0/src/sidtune/sidplayer1.bin0000644000175100017510000004670315175333725014715 0x01, 0x00, 0x6f, 0x36, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10, 0x91, 0x0c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xe1, 0x60, 0x01, 0x02, 0x04, 0x00, 0x07, 0x0e, 0x02, 0x02, 0xfe, 0x02, 0x02, 0xfe, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x00, 0x02, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x1e, 0x18, 0x8b, 0x7e, 0xfa, 0x06, 0xac, 0xf3, 0xe6, 0x8f, 0xf8, 0x2e, 0x86, 0x8e, 0x96, 0x9f, 0xa8, 0xb3, 0xbd, 0xc8, 0xd4, 0xe1, 0xee, 0xfd, 0x8c, 0x78, 0x64, 0x50, 0x3c, 0x28, 0x14, 0x00, 0x00, 0x02, 0x03, 0x05, 0x07, 0x08, 0x0a, 0x0c, 0x0d, 0x0f, 0x11, 0x12, 0x00, 0xe0, 0x00, 0x05, 0x0a, 0x0f, 0xf9, 0x00, 0xf5, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x00, 0x00, 0x50, 0x00, 0x00, 0x60, 0x00, 0x00, 0x70, 0x00, 0x00, 0x80, 0x00, 0x00, 0x90, 0x00, 0x00, 0xa0, 0x00, 0xa9, 0x00, 0x8d, 0x00, 0xe0, 0xa2, 0x95, 0xa0, 0x42, 0xad, 0xa6, 0x02, 0xf0, 0x04, 0xa2, 0x25, 0xa0, 0x40, 0x8e, 0x5b, 0xe1, 0x8c, 0x5c, 0xe1, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0x60, 0xa9, 0x00, 0x8d, 0x00, 0xe0, 0x86, 0x61, 0x84, 0x62, 0xa0, 0xbc, 0x99, 0x00, 0xe0, 0x88, 0xd0, 0xfa, 0xa0, 0x72, 0x99, 0xbc, 0xe0, 0x88, 0xd0, 0xfa, 0x8d, 0x15, 0xd4, 0x8d, 0x16, 0xd4, 0xa9, 0x08, 0x8d, 0x25, 0xe0, 0x8d, 0x17, 0xd4, 0x8d, 0x26, 0xe0, 0x8d, 0x18, 0xd4, 0xa9, 0x90, 0x8d, 0x27, 0xe0, 0xa9, 0x60, 0x8d, 0x28, 0xe0, 0xa9, 0x0c, 0x8d, 0x29, 0xe0, 0xad, 0x5b, 0xe1, 0x8d, 0x2d, 0xe0, 0xad, 0x5c, 0xe1, 0x8d, 0x2e, 0xe0, 0xa9, 0xff, 0x8d, 0xcc, 0xe0, 0xa9, 0xd4, 0x85, 0x64, 0xa2, 0x02, 0xa9, 0xff, 0x9d, 0x0b, 0xe0, 0xa9, 0x01, 0x9d, 0x30, 0xe0, 0x9d, 0x2a, 0xe0, 0x8a, 0x9d, 0x33, 0xe0, 0x9d, 0xae, 0xe0, 0xa9, 0x04, 0x9d, 0x39, 0xe0, 0xbd, 0xa8, 0xe1, 0x9d, 0xba, 0xe0, 0xa9, 0x5b, 0x9d, 0x7e, 0xe0, 0xbd, 0x65, 0xe1, 0x85, 0x63, 0xa9, 0x00, 0xa8, 0x91, 0x63, 0xc8, 0x91, 0x63, 0xc8, 0x91, 0x63, 0xa9, 0x08, 0x9d, 0x17, 0xe0, 0x9d, 0x9c, 0xe0, 0xc8, 0x91, 0x63, 0xc8, 0x91, 0x63, 0xa9, 0x40, 0x9d, 0x1a, 0xe0, 0x91, 0x63, 0xa9, 0x20, 0x9d, 0x1d, 0xe0, 0xc8, 0x91, 0x63, 0xa9, 0xf5, 0x9d, 0x20, 0xe0, 0xc8, 0x91, 0x63, 0xca, 0x10, 0xa4, 0x8a, 0xa2, 0x17, 0x9d, 0x3e, 0xe1, 0xca, 0x10, 0xfa, 0xa5, 0x61, 0x18, 0x69, 0x06, 0x85, 0x63, 0xa9, 0x00, 0xaa, 0xa8, 0x65, 0x62, 0x85, 0x64, 0x9d, 0xab, 0xe0, 0x9d, 0xb4, 0xe0, 0xa5, 0x63, 0x9d, 0xa8, 0xe0, 0x9d, 0xb1, 0xe0, 0x18, 0x71, 0x61, 0x85, 0x63, 0xa5, 0x64, 0xc8, 0x71, 0x61, 0xc8, 0xe8, 0xe0, 0x03, 0xd0, 0xe0, 0xa6, 0x63, 0xa8, 0x60, 0xa9, 0x00, 0x8d, 0x04, 0xd4, 0x8d, 0x0b, 0xd4, 0x8d, 0x12, 0xd4, 0x8d, 0x01, 0xd4, 0x8d, 0x08, 0xd4, 0x8d, 0x0f, 0xd4, 0xa9, 0x08, 0x8d, 0x17, 0xd4, 0xad, 0x5b, 0xe1, 0x8d, 0x04, 0xdc, 0xad, 0x5c, 0xe1, 0x8d, 0x05, 0xdc, 0x60, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0x60, 0xa9, 0x08, 0x8d, 0x00, 0xe0, 0x6c, 0x5d, 0xe1, 0xea, 0xea, 0xea, 0xad, 0x00, 0xe0, 0x30, 0xf0, 0x09, 0x80, 0xa8, 0x29, 0x07, 0xf0, 0xee, 0xd8, 0x8c, 0x00, 0xe0, 0xea, 0xa5, 0xfb, 0x8d, 0x56, 0xe1, 0xa5, 0xfc, 0x8d, 0x57, 0xe1, 0xa5, 0xfd, 0x8d, 0x58, 0xe1, 0xa5, 0xfe, 0x8d, 0x59, 0xe1, 0xa5, 0xff, 0x8d, 0x5a, 0xe1, 0xad, 0x23, 0xe0, 0x18, 0x6d, 0xd9, 0xe0, 0x48, 0x29, 0x07, 0xa8, 0xad, 0xdc, 0xe0, 0x69, 0x00, 0x85, 0xff, 0x68, 0x46, 0xff, 0x6a, 0x46, 0xff, 0x6a, 0x46, 0xff, 0x6a, 0x18, 0x6d, 0x24, 0xe0, 0x8c, 0x15, 0xd4, 0x8d, 0x16, 0xd4, 0xad, 0x25, 0xe0, 0x8d, 0x17, 0xd4, 0xad, 0x26, 0xe0, 0x8d, 0x18, 0xd4, 0xa9, 0xd4, 0x85, 0xfc, 0xa2, 0x00, 0xad, 0x00, 0xe0, 0x3d, 0x62, 0xe1, 0xf0, 0x51, 0xbd, 0x65, 0xe1, 0x85, 0xfb, 0xbd, 0x0e, 0xe0, 0x18, 0x7d, 0x51, 0xe0, 0xa8, 0xbd, 0x11, 0xe0, 0x7d, 0x54, 0xe0, 0x48, 0x98, 0x18, 0x7d, 0xcd, 0xe0, 0xa0, 0x00, 0x91, 0xfb, 0x68, 0x7d, 0xd0, 0xe0, 0xc8, 0x91, 0xfb, 0xbd, 0x14, 0xe0, 0x18, 0x7d, 0x69, 0xe0, 0x85, 0xff, 0xbd, 0x17, 0xe0, 0x7d, 0x6c, 0xe0, 0x48, 0xa5, 0xff, 0x18, 0x7d, 0xd3, 0xe0, 0xc8, 0x91, 0xfb, 0x68, 0x7d, 0xd6, 0xe0, 0xc8, 0x91, 0xfb, 0xbd, 0x1d, 0xe0, 0xc8, 0xc8, 0x91, 0xfb, 0xbd, 0x20, 0xe0, 0xc8, 0x91, 0xfb, 0xe8, 0xe0, 0x03, 0xd0, 0xa2, 0xac, 0x1a, 0xe0, 0xae, 0x1b, 0xe0, 0xad, 0x1c, 0xe0, 0x8c, 0x04, 0xd4, 0x8e, 0x0b, 0xd4, 0x8d, 0x12, 0xd4, 0xae, 0x2d, 0xe0, 0xac, 0x2e, 0xe0, 0x8e, 0x04, 0xdc, 0x8c, 0x05, 0xdc, 0xad, 0x1b, 0xd4, 0x8d, 0xbe, 0xe0, 0xad, 0x1c, 0xd4, 0x8d, 0xbf, 0xe0, 0xa2, 0x00, 0xad, 0x00, 0xe0, 0x3d, 0x62, 0xe1, 0xf0, 0x10, 0x8e, 0x2f, 0xe0, 0x20, 0x36, 0xe5, 0xad, 0x00, 0xe0, 0x29, 0x78, 0xf0, 0x03, 0x4c, 0x0c, 0xe5, 0xe8, 0xe0, 0x03, 0xd0, 0xe3, 0xad, 0xc9, 0xe0, 0xd0, 0x52, 0xad, 0xca, 0xe0, 0x0d, 0xcb, 0xe0, 0xf0, 0x78, 0xad, 0xdf, 0xe0, 0xd0, 0x28, 0xad, 0xca, 0xe0, 0xf0, 0x28, 0x18, 0x6d, 0xbd, 0xe0, 0xb0, 0x07, 0xcd, 0xcc, 0xe0, 0x90, 0x60, 0xf0, 0x5e, 0xa9, 0x00, 0x8d, 0xdf, 0xe0, 0xad, 0xcb, 0xe0, 0xf0, 0x54, 0xee, 0xdf, 0xe0, 0xad, 0xbd, 0xe0, 0xed, 0xcb, 0xe0, 0x4c, 0xb4, 0xe4, 0xad, 0xcb, 0xe0, 0xf0, 0xd3, 0xad, 0xbd, 0xe0, 0x38, 0xed, 0xcb, 0xe0, 0xb0, 0x3a, 0xa9, 0x00, 0x8d, 0xdf, 0xe0, 0xad, 0xca, 0xe0, 0xd0, 0x30, 0xee, 0xdf, 0xe0, 0xd0, 0x28, 0xce, 0xe0, 0xe0, 0xd0, 0x29, 0xad, 0xdf, 0xe0, 0xd0, 0x11, 0xee, 0xdf, 0xe0, 0xad, 0xcb, 0xe0, 0xd0, 0x02, 0xa9, 0x20, 0x8d, 0xe0, 0xe0, 0xa9, 0x00, 0xf0, 0x10, 0xce, 0xdf, 0xe0, 0xad, 0xca, 0xe0, 0xd0, 0x02, 0xa9, 0x20, 0x8d, 0xe0, 0xe0, 0xad, 0xcc, 0xe0, 0x8d, 0xbd, 0xe0, 0xa2, 0x00, 0xbd, 0xc3, 0xe0, 0xf0, 0x44, 0xa9, 0x00, 0x85, 0xff, 0xbc, 0xc0, 0xe0, 0xb9, 0xbd, 0xe0, 0xbc, 0xc6, 0xe0, 0xf0, 0x0e, 0x30, 0x08, 0x0a, 0x26, 0xff, 0x88, 0xd0, 0xfa, 0xf0, 0x04, 0x4a, 0xc8, 0xd0, 0xfc, 0xbc, 0xc3, 0xe0, 0x88, 0xd0, 0x0b, 0x9d, 0xcd, 0xe0, 0xa5, 0xff, 0x9d, 0xd0, 0xe0, 0x4c, 0x02, 0xe5, 0x88, 0xd0, 0x0b, 0x9d, 0xd3, 0xe0, 0xa5, 0xff, 0x9d, 0xd6, 0xe0, 0x4c, 0x02, 0xe5, 0x8d, 0xd9, 0xe0, 0xa5, 0xff, 0x8d, 0xdc, 0xe0, 0xe8, 0xe0, 0x03, 0xd0, 0xb2, 0xad, 0x00, 0xe0, 0x29, 0x7f, 0x8d, 0x00, 0xe0, 0xad, 0x56, 0xe1, 0x85, 0xfb, 0xad, 0x57, 0xe1, 0x85, 0xfc, 0xad, 0x58, 0xe1, 0x85, 0xfd, 0xad, 0x59, 0xe1, 0x85, 0xfe, 0xad, 0x5a, 0xe1, 0x85, 0xff, 0x6c, 0x5d, 0xe1, 0xbd, 0x60, 0xe0, 0xd0, 0x03, 0x4c, 0x9f, 0xe6, 0x4c, 0xba, 0xe5, 0xde, 0x30, 0xe0, 0xd0, 0x03, 0x4c, 0xa0, 0xe6, 0xbd, 0x36, 0xe0, 0x30, 0xe8, 0xd0, 0x1a, 0xbd, 0x3f, 0xe0, 0xf0, 0x05, 0xde, 0x3f, 0xe0, 0xd0, 0x10, 0xbd, 0x39, 0xe0, 0xdd, 0x30, 0xe0, 0x90, 0x08, 0xbd, 0x1a, 0xe0, 0x29, 0xfe, 0x9d, 0x1a, 0xe0, 0xbd, 0x42, 0xe0, 0xf0, 0x56, 0x0a, 0xbd, 0x0e, 0xe0, 0xb0, 0x1d, 0x7d, 0x45, 0xe0, 0x9d, 0x0e, 0xe0, 0xa8, 0xbd, 0x11, 0xe0, 0x7d, 0x48, 0xe0, 0x9d, 0x11, 0xe0, 0x48, 0x98, 0xdd, 0x8d, 0xe0, 0x68, 0xfd, 0x90, 0xe0, 0xb0, 0x1f, 0x90, 0x2e, 0xfd, 0x45, 0xe0, 0x9d, 0x0e, 0xe0, 0xbd, 0x11, 0xe0, 0xfd, 0x48, 0xe0, 0x9d, 0x11, 0xe0, 0xbd, 0x8d, 0xe0, 0xdd, 0x0e, 0xe0, 0xbd, 0x90, 0xe0, 0xfd, 0x11, 0xe0, 0x90, 0x11, 0xbd, 0x8d, 0xe0, 0x9d, 0x0e, 0xe0, 0xbd, 0x90, 0xe0, 0x9d, 0x11, 0xe0, 0xa9, 0x00, 0x9d, 0x42, 0xe0, 0xbd, 0x60, 0xe0, 0xf0, 0x55, 0xbd, 0x4b, 0xe0, 0xf0, 0x4b, 0xa0, 0x00, 0xde, 0x4e, 0xe0, 0xd0, 0x31, 0xbd, 0x51, 0xe0, 0x1d, 0x54, 0xe0, 0xd0, 0x1b, 0xbd, 0x5d, 0xe0, 0x9d, 0x57, 0xe0, 0x9d, 0x4e, 0xe0, 0xbd, 0x4b, 0xe0, 0x0a, 0xbd, 0x5a, 0xe0, 0x90, 0x04, 0x49, 0xff, 0x69, 0x00, 0x9d, 0x4b, 0xe0, 0xd0, 0x10, 0xbd, 0x57, 0xe0, 0x9d, 0x4e, 0xe0, 0x98, 0x38, 0xfd, 0x4b, 0xe0, 0x9d, 0x4b, 0xe0, 0xc9, 0x00, 0x10, 0x01, 0x88, 0x18, 0x7d, 0x51, 0xe0, 0x9d, 0x51, 0xe0, 0x98, 0x7d, 0x54, 0xe0, 0x9d, 0x54, 0xe0, 0xbd, 0x36, 0xe0, 0x30, 0x15, 0xbd, 0x93, 0xe0, 0xf0, 0x10, 0x18, 0x7d, 0x14, 0xe0, 0x9d, 0x14, 0xe0, 0xbd, 0x96, 0xe0, 0x7d, 0x17, 0xe0, 0x9d, 0x17, 0xe0, 0xbd, 0x63, 0xe0, 0xf0, 0x4b, 0xa0, 0x00, 0xde, 0x66, 0xe0, 0xd0, 0x31, 0xbd, 0x69, 0xe0, 0x1d, 0x6c, 0xe0, 0xd0, 0x1b, 0xbd, 0x72, 0xe0, 0x9d, 0x6f, 0xe0, 0x9d, 0x66, 0xe0, 0xbd, 0x63, 0xe0, 0x0a, 0xbd, 0x75, 0xe0, 0x90, 0x04, 0x49, 0xff, 0x69, 0x00, 0x9d, 0x63, 0xe0, 0xd0, 0x10, 0xbd, 0x6f, 0xe0, 0x9d, 0x66, 0xe0, 0x98, 0x38, 0xfd, 0x63, 0xe0, 0x9d, 0x63, 0xe0, 0xc9, 0x00, 0x10, 0x01, 0x88, 0x18, 0x7d, 0x69, 0xe0, 0x9d, 0x69, 0xe0, 0x98, 0x7d, 0x6c, 0xe0, 0x9d, 0x6c, 0xe0, 0xbd, 0x36, 0xe0, 0x10, 0x03, 0x4c, 0x9f, 0xe6, 0xa0, 0x00, 0xbd, 0xa2, 0xe0, 0xf0, 0x1c, 0x10, 0x01, 0xc8, 0x18, 0x6d, 0x23, 0xe0, 0x48, 0x29, 0x07, 0x8d, 0x23, 0xe0, 0x68, 0x6a, 0x4a, 0x4a, 0x18, 0x79, 0xa6, 0xe1, 0x18, 0x6d, 0x24, 0xe0, 0x8d, 0x24, 0xe0, 0x60, 0xbd, 0xa8, 0xe0, 0x85, 0xfd, 0xbd, 0xab, 0xe0, 0x85, 0xfe, 0xd0, 0x04, 0x60, 0x20, 0x98, 0xe8, 0xad, 0x00, 0xe0, 0x3d, 0x62, 0xe1, 0xf0, 0xf4, 0xa0, 0x00, 0xb1, 0xfd, 0x85, 0xff, 0xc8, 0xb1, 0xfd, 0xa8, 0xa5, 0xfd, 0x18, 0x69, 0x02, 0x85, 0xfd, 0x9d, 0xa8, 0xe0, 0xa5, 0xfe, 0x69, 0x00, 0x85, 0xfe, 0x9d, 0xab, 0xe0, 0xa5, 0xff, 0x29, 0x03, 0xd0, 0xd2, 0xbd, 0x8d, 0xe0, 0x9d, 0x0e, 0xe0, 0xbd, 0x90, 0xe0, 0x9d, 0x11, 0xe0, 0xa5, 0xff, 0x9d, 0x05, 0xe0, 0x98, 0x9d, 0x02, 0xe0, 0x29, 0x07, 0xa8, 0xb9, 0x67, 0xe1, 0x8d, 0x6f, 0xe1, 0xbd, 0x02, 0xe0, 0x29, 0x38, 0x4a, 0x4a, 0x4a, 0x7d, 0x81, 0xe0, 0x85, 0xfd, 0xbd, 0x02, 0xe0, 0x29, 0xc0, 0x0a, 0x2a, 0x2a, 0xa8, 0xb9, 0x6f, 0xe1, 0x85, 0xfe, 0xbd, 0x02, 0xe0, 0x29, 0x07, 0xf0, 0x62, 0xa8, 0xb9, 0x72, 0xe1, 0x65, 0xfe, 0x18, 0x7d, 0x84, 0xe0, 0x10, 0x05, 0x18, 0x69, 0x0c, 0xe6, 0xfd, 0xc9, 0x0c, 0x90, 0x04, 0xe9, 0x0c, 0xc6, 0xfd, 0x85, 0xfe, 0xa8, 0xb9, 0x86, 0xe1, 0x85, 0xff, 0xb9, 0x7a, 0xe1, 0xa4, 0xfd, 0x88, 0x30, 0x06, 0x46, 0xff, 0x6a, 0x88, 0x10, 0xfa, 0x18, 0x7d, 0x87, 0xe0, 0x9d, 0x8d, 0xe0, 0xa5, 0xff, 0x7d, 0x8a, 0xe0, 0x9d, 0x90, 0xe0, 0xbd, 0x05, 0xe0, 0xd0, 0x03, 0x4c, 0xa0, 0xe6, 0xbd, 0x45, 0xe0, 0x1d, 0x48, 0xe0, 0xf0, 0x16, 0xbd, 0x0e, 0xe0, 0xdd, 0x8d, 0xe0, 0xbd, 0x11, 0xe0, 0xfd, 0x90, 0xe0, 0xa9, 0xfe, 0x6a, 0x9d, 0x42, 0xe0, 0x90, 0x11, 0xf0, 0x4a, 0x9d, 0x42, 0xe0, 0xbd, 0x8d, 0xe0, 0x9d, 0x0e, 0xe0, 0xbd, 0x90, 0xe0, 0x9d, 0x11, 0xe0, 0xbd, 0x36, 0xe0, 0x0a, 0xd0, 0x35, 0xbd, 0x93, 0xe0, 0xf0, 0x0c, 0xbd, 0x99, 0xe0, 0x9d, 0x14, 0xe0, 0xbd, 0x9c, 0xe0, 0x9d, 0x17, 0xe0, 0xbd, 0x9f, 0xe0, 0xf0, 0x0f, 0xa4, 0xfd, 0x18, 0x79, 0x92, 0xe1, 0xa4, 0xfe, 0x18, 0x79, 0x9a, 0xe1, 0x18, 0x90, 0x08, 0xbd, 0xa2, 0xe0, 0xf0, 0x0b, 0xbd, 0xa5, 0xe0, 0x8d, 0x24, 0xe0, 0xa9, 0x00, 0x8d, 0x23, 0xe0, 0xbd, 0x3c, 0xe0, 0x9d, 0x3f, 0xe0, 0xbd, 0x05, 0xe0, 0x29, 0x40, 0x9d, 0x36, 0xe0, 0xbd, 0x05, 0xe0, 0x4a, 0x4a, 0x29, 0x07, 0xd0, 0x30, 0xbd, 0x05, 0xe0, 0x30, 0x14, 0xad, 0x27, 0xe0, 0x29, 0x3c, 0xd0, 0x1e, 0xad, 0x27, 0xe0, 0x0a, 0x2a, 0x2a, 0xd0, 0x02, 0xa9, 0x04, 0x4c, 0x70, 0xe8, 0xad, 0x28, 0xe0, 0xf0, 0x0c, 0x29, 0x3f, 0xd0, 0x08, 0xad, 0x28, 0xe0, 0x0a, 0x2a, 0x2a, 0xd0, 0x66, 0xa9, 0x10, 0x8d, 0x00, 0xe0, 0x60, 0xc9, 0x01, 0xd0, 0x13, 0xbd, 0x05, 0xe0, 0x29, 0x20, 0xd0, 0x06, 0xad, 0x29, 0xe0, 0x4c, 0x70, 0xe8, 0xbd, 0x2a, 0xe0, 0x4c, 0x70, 0xe8, 0xa8, 0xbd, 0x05, 0xe0, 0x29, 0xa0, 0xc9, 0x80, 0xf0, 0x30, 0x85, 0xff, 0x18, 0xad, 0x27, 0xe0, 0xd0, 0x01, 0x38, 0x88, 0x88, 0xf0, 0x06, 0x6a, 0xb0, 0x4e, 0x88, 0xd0, 0xfa, 0xa4, 0xff, 0x85, 0xff, 0xf0, 0x26, 0x46, 0xff, 0xb0, 0x41, 0xf0, 0x42, 0x65, 0xff, 0xb0, 0x3e, 0xc8, 0x10, 0x19, 0x46, 0xff, 0xb0, 0x34, 0x65, 0xff, 0x90, 0x11, 0xb0, 0x31, 0xad, 0x28, 0xe0, 0xf0, 0x29, 0x88, 0x88, 0xf0, 0x06, 0x4a, 0xb0, 0x22, 0x88, 0xd0, 0xfa, 0x9d, 0x30, 0xe0, 0xbd, 0x1a, 0xe0, 0x29, 0xf6, 0x9d, 0x1a, 0xe0, 0x38, 0xbd, 0x02, 0xe0, 0x29, 0x07, 0xd0, 0x03, 0x7e, 0x36, 0xe0, 0xbd, 0x1a, 0xe0, 0x69, 0x00, 0x9d, 0x1a, 0xe0, 0x60, 0xa9, 0x10, 0x2c, 0xa9, 0x18, 0x8d, 0x00, 0xe0, 0x60, 0x98, 0x48, 0xa5, 0xff, 0x4a, 0x90, 0x03, 0x4c, 0x42, 0xea, 0x4a, 0x4a, 0xb0, 0x1e, 0x4a, 0xb0, 0x0e, 0x9d, 0x9c, 0xe0, 0x9d, 0x17, 0xe0, 0x68, 0x9d, 0x99, 0xe0, 0x9d, 0x14, 0xe0, 0x60, 0x4a, 0x90, 0x02, 0x09, 0xf8, 0x9d, 0x8a, 0xe0, 0x68, 0x9d, 0x87, 0xe0, 0x60, 0x4a, 0xb0, 0x03, 0x4c, 0x4a, 0xe9, 0x4a, 0xb0, 0x61, 0x4a, 0xb0, 0x0f, 0xd0, 0x08, 0x68, 0x9d, 0xa5, 0xe0, 0x8d, 0x24, 0xe0, 0x60, 0x68, 0x9d, 0x3c, 0xe0, 0x60, 0xd0, 0x48, 0x68, 0x9d, 0x7e, 0xe0, 0xc9, 0x5b, 0xf0, 0x33, 0xa8, 0x4a, 0x4a, 0x4a, 0x38, 0xe9, 0x0b, 0x18, 0x7d, 0x84, 0xe0, 0x30, 0x0c, 0xc9, 0x0c, 0x90, 0x11, 0xe9, 0x0c, 0xde, 0x81, 0xe0, 0x4c, 0x0b, 0xe9, 0xc9, 0xf5, 0xb0, 0x05, 0x69, 0x0c, 0xfe, 0x81, 0xe0, 0x9d, 0x84, 0xe0, 0x98, 0x29, 0x07, 0x38, 0xe9, 0x03, 0x18, 0x7d, 0x81, 0xe0, 0x9d, 0x81, 0xe0, 0x60, 0xbd, 0x78, 0xe0, 0x9d, 0x81, 0xe0, 0xbd, 0x7b, 0xe0, 0x9d, 0x84, 0xe0, 0x60, 0x68, 0x9d, 0xc6, 0xe0, 0x60, 0x4a, 0xb0, 0x08, 0x9d, 0x0b, 0xe0, 0x68, 0x9d, 0x08, 0xe0, 0x60, 0x4a, 0x6a, 0x6a, 0x6d, 0x5b, 0xe1, 0x8d, 0x2d, 0xe0, 0x68, 0x6d, 0x5c, 0xe1, 0x8d, 0x2e, 0xe0, 0x60, 0x4a, 0x90, 0x03, 0x4c, 0xd3, 0xe9, 0x4a, 0xb0, 0x40, 0x4a, 0xb0, 0x17, 0x4a, 0xb0, 0x0f, 0x68, 0x8d, 0x27, 0xe0, 0x4a, 0x4a, 0x4a, 0xa8, 0xb9, 0xaf, 0xe1, 0x8d, 0x28, 0xe0, 0x60, 0x68, 0x9d, 0x5d, 0xe0, 0x60, 0x4a, 0xb0, 0x05, 0x68, 0x8d, 0x01, 0xe0, 0x60, 0x68, 0xf0, 0x11, 0x9d, 0x75, 0xe0, 0xbc, 0x63, 0xe0, 0xd0, 0x08, 0x9d, 0x63, 0xe0, 0xa9, 0x01, 0x9d, 0x66, 0xe0, 0x60, 0x9d, 0x63, 0xe0, 0x9d, 0x69, 0xe0, 0x9d, 0x6c, 0xe0, 0x60, 0x4a, 0xb0, 0x30, 0x4a, 0xb0, 0x05, 0x68, 0x9d, 0x39, 0xe0, 0x60, 0x68, 0xa0, 0x00, 0x4a, 0x90, 0x02, 0xc8, 0x18, 0x48, 0x29, 0x07, 0x79, 0xac, 0xe1, 0x9d, 0x78, 0xe0, 0x9d, 0x81, 0xe0, 0x68, 0x4a, 0x4a, 0x4a, 0x18, 0x79, 0xad, 0xe1, 0x9d, 0x7b, 0xe0, 0x9d, 0x84, 0xe0, 0xa9, 0x5b, 0x9d, 0x7e, 0xe0, 0x60, 0x4a, 0xb0, 0x05, 0x68, 0x9d, 0xa2, 0xe0, 0x60, 0x68, 0x8d, 0xcc, 0xe0, 0x60, 0x4a, 0xb0, 0x27, 0x4a, 0xb0, 0x0d, 0x4a, 0xb0, 0x05, 0x68, 0x8d, 0x29, 0xe0, 0x60, 0x68, 0x9d, 0x9f, 0xe0, 0x60, 0x4a, 0xb0, 0x0f, 0x68, 0x9d, 0x93, 0xe0, 0xa0, 0x00, 0x0a, 0x90, 0x01, 0x88, 0x98, 0x9d, 0x96, 0xe0, 0x60, 0x68, 0x9d, 0x72, 0xe0, 0x60, 0x4a, 0xb0, 0x1c, 0x4a, 0xb0, 0x15, 0x68, 0x9d, 0xb7, 0xe0, 0xa5, 0xfd, 0x9d, 0xb1, 0xe0, 0xa5, 0xfe, 0x9d, 0xb4, 0xe0, 0xbd, 0x33, 0xe0, 0x9d, 0xae, 0xe0, 0x60, 0x68, 0x6c, 0x5f, 0xe1, 0x4a, 0xb0, 0x1e, 0x68, 0xd0, 0x0a, 0x9d, 0x4b, 0xe0, 0x9d, 0x51, 0xe0, 0x9d, 0x54, 0xe0, 0x60, 0x9d, 0x5a, 0xe0, 0xbc, 0x4b, 0xe0, 0xd0, 0x08, 0x9d, 0x4b, 0xe0, 0xa9, 0x01, 0x9d, 0x4e, 0xe0, 0x60, 0x68, 0x9d, 0x2a, 0xe0, 0x60, 0x4a, 0x90, 0x08, 0x9d, 0x48, 0xe0, 0x68, 0x9d, 0x45, 0xe0, 0x60, 0x68, 0x4a, 0xb0, 0x61, 0x4a, 0xb0, 0x25, 0x4a, 0xb0, 0x05, 0x4a, 0xa0, 0xf0, 0xd0, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0xa0, 0x0f, 0x85, 0xff, 0x98, 0xb0, 0x09, 0x3d, 0x1d, 0xe0, 0x05, 0xff, 0x9d, 0x1d, 0xe0, 0x60, 0x3d, 0x20, 0xe0, 0x05, 0xff, 0x9d, 0x20, 0xe0, 0x60, 0x4a, 0xb0, 0x38, 0x4a, 0xb0, 0x64, 0x85, 0xff, 0xbd, 0xba, 0xe0, 0xdd, 0xa9, 0xe1, 0xf0, 0x54, 0xfe, 0xba, 0xe0, 0xa8, 0xa5, 0xfd, 0x99, 0xe1, 0xe0, 0xa5, 0xfe, 0x99, 0xf0, 0xe0, 0xbd, 0x33, 0xe0, 0x99, 0x2f, 0xe1, 0xa4, 0xff, 0xb9, 0x17, 0xe1, 0xf0, 0x36, 0x85, 0xfe, 0xb9, 0xff, 0xe0, 0x85, 0xfd, 0xb9, 0x3e, 0xe1, 0x9d, 0x33, 0xe0, 0x60, 0xb0, 0x4b, 0x4a, 0xb0, 0x3c, 0xa8, 0xa5, 0xfd, 0x99, 0xff, 0xe0, 0xa5, 0xfe, 0x99, 0x17, 0xe1, 0xbd, 0x33, 0xe0, 0x99, 0x3e, 0xe1, 0xbd, 0xba, 0xe0, 0xdd, 0xa9, 0xe1, 0xf0, 0x0d, 0xfe, 0xba, 0xe0, 0xa8, 0xa9, 0x00, 0x99, 0xf0, 0xe0, 0x60, 0xa9, 0x30, 0x2c, 0xa9, 0x28, 0x8d, 0x00, 0xe0, 0x60, 0x0a, 0x0a, 0x0a, 0x0a, 0x4d, 0x25, 0xe0, 0x29, 0xf0, 0x4d, 0x25, 0xe0, 0x8d, 0x25, 0xe0, 0x60, 0x4d, 0x26, 0xe0, 0x29, 0x0f, 0x4d, 0x26, 0xe0, 0x8d, 0x26, 0xe0, 0x60, 0x4a, 0xb0, 0x0b, 0x4a, 0xb0, 0x04, 0x8d, 0xca, 0xe0, 0x60, 0x8d, 0xcb, 0xe0, 0x60, 0x4a, 0x90, 0x03, 0x4c, 0xa5, 0xeb, 0x4a, 0xa8, 0xf0, 0x21, 0x88, 0xf0, 0x34, 0x88, 0xf0, 0x42, 0x88, 0xf0, 0x4a, 0x88, 0xf0, 0x52, 0x88, 0xf0, 0x5c, 0x88, 0xf0, 0x66, 0x88, 0xf0, 0x73, 0x29, 0x07, 0x09, 0x10, 0xb0, 0x03, 0x4c, 0xb7, 0xea, 0x4c, 0x7f, 0xea, 0xac, 0x26, 0xe0, 0xb0, 0x07, 0xc8, 0x98, 0x29, 0x0f, 0xd0, 0x07, 0x60, 0x98, 0x29, 0x0f, 0xf0, 0x04, 0x88, 0x8c, 0x26, 0xe0, 0x60, 0xbd, 0x62, 0xe1, 0x49, 0xff, 0x2d, 0x25, 0xe0, 0x90, 0x03, 0x1d, 0x62, 0xe1, 0x8d, 0x25, 0xe0, 0x60, 0xbd, 0x1a, 0xe0, 0x29, 0xfb, 0x90, 0x55, 0x09, 0x04, 0xb0, 0x51, 0xbd, 0x1a, 0xe0, 0x29, 0xfd, 0x90, 0x4a, 0x09, 0x02, 0xb0, 0x46, 0xad, 0x25, 0xe0, 0x29, 0xf7, 0x90, 0x02, 0x09, 0x08, 0x8d, 0x25, 0xe0, 0x60, 0xad, 0x26, 0xe0, 0x29, 0x7f, 0x90, 0x02, 0x09, 0x80, 0x8d, 0x26, 0xe0, 0x60, 0x98, 0x8d, 0xbd, 0xe0, 0x8d, 0xdf, 0xe0, 0xc8, 0x8c, 0xe0, 0xe0, 0x2a, 0x8d, 0xc9, 0xe0, 0x60, 0x98, 0x2a, 0x9d, 0x60, 0xe0, 0x60, 0x4a, 0xb0, 0x27, 0x4a, 0xb0, 0x14, 0xd0, 0x02, 0xa9, 0x08, 0x0a, 0x0a, 0x0a, 0x0a, 0x5d, 0x1a, 0xe0, 0x29, 0xf0, 0x5d, 0x1a, 0xe0, 0x9d, 0x1a, 0xe0, 0x60, 0x0a, 0x0a, 0x0a, 0x0a, 0x4d, 0x26, 0xe0, 0x29, 0x70, 0x4d, 0x26, 0xe0, 0x8d, 0x26, 0xe0, 0x60, 0x4a, 0x90, 0x04, 0x9d, 0xc0, 0xe0, 0x60, 0xa8, 0xf0, 0x20, 0x88, 0xf0, 0x40, 0x88, 0xf0, 0x63, 0x29, 0x03, 0x9d, 0xc3, 0xe0, 0xa9, 0x00, 0x9d, 0xcd, 0xe0, 0x9d, 0xd0, 0xe0, 0x9d, 0xd3, 0xe0, 0x9d, 0xd6, 0xe0, 0x8d, 0xd9, 0xe0, 0x8d, 0xdc, 0xe0, 0x60, 0xbd, 0xb7, 0xe0, 0xf0, 0x05, 0xde, 0xb7, 0xe0, 0xf0, 0x12, 0xbd, 0x33, 0xe0, 0xdd, 0xae, 0xe0, 0xd0, 0x0b, 0xbd, 0xb1, 0xe0, 0x85, 0xfd, 0xbd, 0xb4, 0xe0, 0x85, 0xfe, 0x60, 0xa9, 0x38, 0x8d, 0x00, 0xe0, 0x60, 0xbd, 0xba, 0xe0, 0xdd, 0xa8, 0xe1, 0xf0, 0x18, 0xde, 0xba, 0xe0, 0xa8, 0x88, 0xb9, 0xf0, 0xe0, 0xf0, 0x0d, 0x85, 0xfe, 0xb9, 0xe1, 0xe0, 0x85, 0xfd, 0xb9, 0x2f, 0xe1, 0x9d, 0x33, 0xe0, 0x60, 0xa9, 0x20, 0x8d, 0x00, 0xe0, 0x60, 0xad, 0x00, 0xe0, 0x5d, 0x62, 0xe1, 0x8d, 0x00, 0xe0, 0xa9, 0x01, 0x9d, 0x30, 0xe0, 0x60, 0xad, 0x00, 0xe0, 0x29, 0x07, 0x8d, 0x81, 0xec, 0xd0, 0x03, 0x20, 0xe9, 0xe2, 0x60, 0x00, 0xa2, 0x51, 0xa0, 0xec, 0x8e, 0x5d, 0xe1, 0x8c, 0x5e, 0xe1, 0x20, 0xcf, 0xe1, 0xa2, 0x00, 0xa0, 0x09, 0x20, 0x00, 0xe2, 0xa9, 0x07, 0x8d, 0x00, 0xe0, 0x8d, 0x81, 0xec, 0x60, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x29, 0xff, 0xf0, 0xf6, 0x4c, 0x29, 0xe3, 0xa9, 0x07, 0x8d, 0x00, 0xe0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, libsidplayfp-3.0.0/src/sidtune/SidTuneBase.cpp0000644000175100017510000004400415175333711015003 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2021 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "SidTuneBase.h" #include #include #include #include #include #include #include #include "SmartPtr.h" #include "SidTuneTools.h" #include "SidTuneInfoImpl.h" #include "sidendian.h" #include "sidmemory.h" #include "stringutils.h" #include "MUS.h" #include "p00.h" #include "prg.h" #include "PSID.h" namespace libsidplayfp { // Error and status message strings. const char ERR_EMPTY[] = "SIDTUNE ERROR: No data to load"; const char ERR_UNRECOGNIZED_FORMAT[] = "SIDTUNE ERROR: Could not determine file format"; const char ERR_CANT_LOAD_FILE[] = "SIDTUNE ERROR: Could not load input file"; const char ERR_CANT_OPEN_FILE[] = "SIDTUNE ERROR: Could not open file for binary input"; const char ERR_FILE_TOO_LONG[] = "SIDTUNE ERROR: Input data too long"; const char ERR_DATA_TOO_LONG[] = "SIDTUNE ERROR: Size of music data exceeds C64 memory"; const char ERR_BAD_ADDR[] = "SIDTUNE ERROR: Bad address data"; const char ERR_BAD_RELOC[] = "SIDTUNE ERROR: Bad reloc data"; const char ERR_CORRUPT[] = "SIDTUNE ERROR: File is incomplete or corrupt"; //const char ERR_NOT_ENOUGH_MEMORY[] = "SIDTUNE ERROR: Not enough free memory"; const char SidTuneBase::ERR_TRUNCATED[] = "SIDTUNE ERROR: File is most likely truncated"; const char SidTuneBase::ERR_INVALID[] = "SIDTUNE ERROR: File contains invalid data"; /** * Petscii to Ascii conversion table (0x01 = no output). */ const char CHR_tab[256] = { 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x0d,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x20,0x21,0x01,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x24,0x5d,0x20,0x20, // alternative: CHR$(92=0x5c) => ISO Latin-1(0xa3) 0x2d,0x23,0x7c,0x2d,0x2d,0x2d,0x2d,0x7c,0x7c,0x5c,0x5c,0x2f,0x5c,0x5c,0x2f,0x2f, 0x5c,0x23,0x5f,0x23,0x7c,0x2f,0x58,0x4f,0x23,0x7c,0x23,0x2b,0x7c,0x7c,0x26,0x5c, // 0x80-0xFF 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x20,0x7c,0x23,0x2d,0x2d,0x7c,0x23,0x7c,0x23,0x2f,0x7c,0x7c,0x2f,0x5c,0x5c,0x2d, 0x2f,0x2d,0x2d,0x7c,0x7c,0x7c,0x7c,0x2d,0x2d,0x2d,0x2f,0x5c,0x5c,0x2f,0x2f,0x23, 0x2d,0x23,0x7c,0x2d,0x2d,0x2d,0x2d,0x7c,0x7c,0x5c,0x5c,0x2f,0x5c,0x5c,0x2f,0x2f, 0x5c,0x23,0x5f,0x23,0x7c,0x2f,0x58,0x4f,0x23,0x7c,0x23,0x2b,0x7c,0x7c,0x26,0x5c, 0x20,0x7c,0x23,0x2d,0x2d,0x7c,0x23,0x7c,0x23,0x2f,0x7c,0x7c,0x2f,0x5c,0x5c,0x2d, 0x2f,0x2d,0x2d,0x7c,0x7c,0x7c,0x7c,0x2d,0x2d,0x2d,0x2f,0x5c,0x5c,0x2f,0x2f,0x23 }; /// The Commodore 64 memory size constexpr uint_least32_t MAX_MEMORY = 65536; /// C64KB + LOAD + PSID constexpr uint_least32_t MAX_FILELEN = MAX_MEMORY + 2 + 0x7C; /// Minimum load address for real c64 only tunes constexpr uint_least16_t SIDTUNE_R64_MIN_LOAD_ADDR = 0x07e8; SidTuneBase* SidTuneBase::load(LoaderFunc loader, const char* fileName, const char **fileNameExt, bool separatorIsSlash) { if (fileName == nullptr) return nullptr; #if !defined(SIDTUNE_NO_STDIN_LOADER) // Filename "-" is used as a synonym for standard input. if (strcmp(fileName, "-") == 0) return getFromStdIn(); #endif return getFromFiles(loader, fileName, fileNameExt, separatorIsSlash); } unsigned int SidTuneBase::selectSong(unsigned int songNum) { // Check whether selected song is valid, use start song if not const unsigned int song = (songNum == 0 || songNum > info->m_songs) ? info->m_startSong : songNum; // Copy any song-specific variable information // such a speed/clock setting to the info structure. info->m_currentSong = song; // Retrieve song speed definition. switch (info->m_compatibility) { case SidTuneInfo::COMPATIBILITY_R64: info->m_songSpeed = SidTuneInfo::SPEED_CIA_1A; break; case SidTuneInfo::COMPATIBILITY_PSID: // This does not take into account the PlaySID bug upon evaluating the // SPEED field. It would most likely break compatibility to lots of // sidtunes, which have been converted from .SID format and vice versa. // The .SID format does the bit-wise/song-wise evaluation of the SPEED // value correctly, like it is described in the PlaySID documentation. info->m_songSpeed = songSpeed[(song - 1) & 31]; break; default: info->m_songSpeed = songSpeed[song - 1]; break; } info->m_clockSpeed = clockSpeed[song - 1]; return info->m_currentSong; } // ------------------------------------------------- private member functions void SidTuneBase::placeSidTuneInC64mem(sidmemory& mem) { // The Basic ROM sets these values on loading a file. // Program end address const uint_least16_t start = info->m_loadAddr; const uint_least16_t end = start + info->m_c64dataLen; mem.writeMemWord(0x2d, end); // Variables start mem.writeMemWord(0x2f, end); // Arrays start mem.writeMemWord(0x31, end); // Strings start mem.writeMemWord(0xac, start); mem.writeMemWord(0xae, end); // Copy data from cache to the correct destination. mem.fillRam(info->m_loadAddr, &cache[fileOffset], info->m_c64dataLen); } void SidTuneBase::loadFile(const char* fileName, buffer_t& bufferRef) { std::ifstream inFile(fileName, std::ifstream::binary); if (!inFile.is_open()) { throw loadError(ERR_CANT_OPEN_FILE); } inFile.seekg(0, inFile.end); const int fileLen = inFile.tellg(); if (fileLen <= 0) { throw loadError(ERR_EMPTY); } inFile.seekg(0, inFile.beg); buffer_t fileBuf; fileBuf.reserve(fileLen); try { fileBuf.assign(std::istreambuf_iterator(inFile), std::istreambuf_iterator()); } catch (std::exception &ex) { throw loadError(ex.what()); } if (inFile.bad()) { throw loadError(ERR_CANT_LOAD_FILE); } inFile.close(); bufferRef.swap(fileBuf); } SidTuneBase::SidTuneBase() : info(new SidTuneInfoImpl()), fileOffset(0) { // Initialize the object with some safe defaults. for (unsigned int si = 0; si < MAX_SONGS; si++) { songSpeed[si] = info->m_songSpeed; clockSpeed[si] = info->m_clockSpeed; } } #if !defined(SIDTUNE_NO_STDIN_LOADER) SidTuneBase* SidTuneBase::getFromStdIn() { buffer_t fileBuf; // We only read as much as fits in the buffer. // This way we avoid choking on huge data. char datb; while (std::cin.get(datb) && fileBuf.size() < MAX_FILELEN) { fileBuf.push_back((uint_least8_t)datb); } return getFromBuffer(&fileBuf.front(), fileBuf.size()); } #endif SidTuneBase* SidTuneBase::getFromBuffer(const uint_least8_t* const buffer, uint_least32_t bufferLen) { if (buffer == nullptr || bufferLen == 0) { throw loadError(ERR_EMPTY); } if (bufferLen > MAX_FILELEN) { throw loadError(ERR_FILE_TOO_LONG); } buffer_t buf1(buffer, buffer + bufferLen); // Here test for the possible single file formats. std::unique_ptr s(PSID::load(buf1)); if (s.get() == nullptr) s.reset(MUS::load(buf1, true)); if (s.get() == nullptr) throw loadError(ERR_UNRECOGNIZED_FORMAT); s->acceptSidTune("-", "-", buf1, false); return s.release(); } void SidTuneBase::acceptSidTune(const char* dataFileName, const char* infoFileName, buffer_t& buf, bool isSlashedFileName) { // Make a copy of the data file name and path, if available. if (dataFileName != nullptr) { const size_t fileNamePos = isSlashedFileName ? SidTuneTools::slashedFileNameWithoutPath(dataFileName) : SidTuneTools::fileNameWithoutPath(dataFileName); info->m_path = std::string(dataFileName, fileNamePos); info->m_dataFileName = std::string(dataFileName + fileNamePos); } // Make a copy of the info file name, if available. if (infoFileName != nullptr) { const size_t fileNamePos = isSlashedFileName ? SidTuneTools::slashedFileNameWithoutPath(infoFileName) : SidTuneTools::fileNameWithoutPath(infoFileName); info->m_infoFileName = std::string(infoFileName + fileNamePos); } // Fix bad sidtune set up. if (info->m_songs > MAX_SONGS) { info->m_songs = MAX_SONGS; } else if (info->m_songs == 0) { info->m_songs = 1; } if (info->m_startSong == 0 || info->m_startSong > info->m_songs) { info->m_startSong = 1; } info->m_dataFileLen = buf.size(); info->m_c64dataLen = buf.size() - fileOffset; // Calculate any remaining addresses and then // confirm all the file details are correct resolveAddrs(&buf[fileOffset]); if (checkRelocInfo() == false) { throw loadError(ERR_BAD_RELOC); } if (checkCompatibility() == false) { throw loadError(ERR_BAD_ADDR); } if (info->m_dataFileLen >= 2) { // We only detect an offset of two. Some position independent // sidtunes contain a load address of 0xE000, but are loaded // to 0x0FFE and call player at 0x1000. info->m_fixLoad = (endian_little16(&buf[fileOffset])==(info->m_loadAddr+2)); } // Check the size of the data. if (info->m_c64dataLen > MAX_MEMORY) { throw loadError(ERR_DATA_TOO_LONG); } else if (info->m_c64dataLen == 0) { throw loadError(ERR_EMPTY); } cache.swap(buf); } void SidTuneBase::createNewFileName(std::string& destString, const char* sourceName, const char* sourceExt) { destString.assign(sourceName); destString.erase(destString.find_last_of('.')); destString.append(sourceExt); } // Initializing the object based upon what we find in the specified file. SidTuneBase* SidTuneBase::getFromFiles(LoaderFunc loader, const char* fileName, const char **fileNameExtensions, bool separatorIsSlash) { buffer_t fileBuf1; if (loader == nullptr) loader = (LoaderFunc) loadFile; loader(fileName, fileBuf1); // File loaded. Now check if it is in a valid single-file-format. std::unique_ptr s(PSID::load(fileBuf1)); if (s.get() == nullptr) { // Try some native C64 file formats s.reset(MUS::load(fileBuf1, true)); if (s.get() != nullptr) { // Try to find second file. std::string fileName2; int n = 0; while (fileNameExtensions[n] != nullptr) { createNewFileName(fileName2, fileName, fileNameExtensions[n]); // 1st data file was loaded into "fileBuf1", // so we load the 2nd one into "fileBuf2". // Do not load the first file again if names are equal. if (!stringutils::equal(fileName, fileName2.data(), fileName2.size())) { try { buffer_t fileBuf2; loader(fileName2.c_str(), fileBuf2); // Check if tunes in wrong order and therefore swap them here if (stringutils::equal(fileNameExtensions[n], ".mus")) { std::unique_ptr s2(MUS::load(fileBuf2, fileBuf1, 0, true)); if (s2.get() != nullptr) { s2->acceptSidTune(fileName2.c_str(), fileName, fileBuf2, separatorIsSlash); return s2.release(); } } else { std::unique_ptr s2(MUS::load(fileBuf1, fileBuf2, 0, true)); if (s2.get() != nullptr) { s2->acceptSidTune(fileName, fileName2.c_str(), fileBuf1, separatorIsSlash); return s2.release(); } } // The first tune loaded ok, so ignore errors on the // second tune, may find an ok one later } catch (loadError const &) {} } n++; } } } if (s.get() == nullptr) s.reset(p00::load(fileName, fileBuf1)); if (s.get() == nullptr) s.reset(prg::load(fileName, fileBuf1)); if (s.get() == nullptr) throw loadError(ERR_UNRECOGNIZED_FORMAT); s->acceptSidTune(fileName, nullptr, fileBuf1, separatorIsSlash); return s.release(); } void SidTuneBase::convertOldStyleSpeedToTables(uint_least32_t speed, SidTuneInfo::clock_t clock) { // Create the speed/clock setting tables. // // This routine implements the PSIDv2NG compliant speed conversion. All tunes // above 32 use the same song speed as tune 32 // NOTE: The cast here is used to avoid undefined references // as the std::min function takes its parameters by reference const unsigned int toDo = std::min(info->m_songs, static_cast(MAX_SONGS)); for (unsigned int s = 0; s < toDo; s++) { clockSpeed[s] = clock; songSpeed[s] = (speed & 1) ? SidTuneInfo::SPEED_CIA_1A : SidTuneInfo::SPEED_VBI; if (s < 31) { speed >>= 1; } } } bool SidTuneBase::checkRelocInfo() { // Fix relocation information if (info->m_relocStartPage == 0xFF) { info->m_relocPages = 0; return true; } else if (info->m_relocPages == 0) { info->m_relocStartPage = 0; return true; } // Calculate start/end page const uint_least8_t startp = info->m_relocStartPage; const uint_least8_t endp = (startp + info->m_relocPages - 1) & 0xff; if (endp < startp) { return false; } { // Check against load range const uint_least8_t startlp = (uint_least8_t) (info->m_loadAddr >> 8); const uint_least8_t endlp = startlp + (uint_least8_t) ((info->m_c64dataLen - 1) >> 8); if (((startp <= startlp) && (endp >= startlp)) || ((startp <= endlp) && (endp >= endlp))) { return false; } } // Check that the relocation information does not use the following // memory areas: 0x0000-0x03FF, 0xA000-0xBFFF and 0xD000-0xFFFF if ((startp < 0x04) || ((0xa0 <= startp) && (startp <= 0xbf)) || (startp >= 0xd0) || ((0xa0 <= endp) && (endp <= 0xbf)) || (endp >= 0xd0)) { return false; } return true; } void SidTuneBase::resolveAddrs(const uint_least8_t *c64data) { // Originally used as a first attempt at an RSID // style format. Now reserved for future use if (info->m_playAddr == 0xffff) { info->m_playAddr = 0; } // loadAddr = 0 means, the address is stored in front of the C64 data. if (info->m_loadAddr == 0) { if (info->m_c64dataLen < 2) { throw loadError(ERR_CORRUPT); } info->m_loadAddr = endian_16(*(c64data+1), *c64data); fileOffset += 2; info->m_c64dataLen -= 2; } if (info->m_compatibility == SidTuneInfo::COMPATIBILITY_BASIC) { if (info->m_initAddr != 0) { throw loadError(ERR_BAD_ADDR); } } else if (info->m_initAddr == 0) { info->m_initAddr = info->m_loadAddr; } } bool SidTuneBase::checkCompatibility() { if (info->m_compatibility == SidTuneInfo::COMPATIBILITY_R64) { // Check valid init address switch (info->m_initAddr >> 12) { case 0x0A: case 0x0B: case 0x0D: case 0x0E: case 0x0F: return false; default: if ((info->m_initAddr < info->m_loadAddr) || (info->m_initAddr > (info->m_loadAddr + info->m_c64dataLen - 1))) { return false; } } // Check tune is loadable on a real C64 if (info->m_loadAddr < SIDTUNE_R64_MIN_LOAD_ADDR) { return false; } } return true; } std::string SidTuneBase::petsciiToAscii(SmartPtr_sidtt& spPet) { std::string buffer; do { const uint8_t petsciiChar = *spPet; spPet++; if ((petsciiChar == 0x00) || (petsciiChar == 0x0d)) break; // If character is 0x9d (left arrow key) then move back. if ((petsciiChar == 0x9d) && (!buffer.empty())) { buffer.resize(buffer.size() - 1); } else { // ASCII CHR$ conversion const char asciiChar = CHR_tab[petsciiChar]; if ((asciiChar >= 0x20) && (buffer.length() <= 31)) buffer.push_back(asciiChar); } } while (!spPet.fail()); return buffer; } } libsidplayfp-3.0.0/src/sidtune/SmartPtr.h0000644000175100017510000001027515175333711014061 /* Simple smart pointer class. */ #ifndef SMARTPTR_H #define SMARTPTR_H #include "sidcxx11.h" namespace libsidplayfp { using ulint_smartpt = unsigned long int; template class SmartPtrBase_sidtt { public: SmartPtrBase_sidtt(T* buffer, ulint_smartpt bufferLen, bool bufOwner = false) : bufBegin(nullptr), bufEnd(nullptr), pBufCurrent(nullptr), bufLen(0), status(false), doFree(bufOwner), dummy(0) { if ((buffer != nullptr) && (bufferLen != 0)) { bufBegin = buffer; pBufCurrent = buffer; bufEnd = bufBegin + bufferLen; bufLen = bufferLen; status = true; } } virtual ~SmartPtrBase_sidtt() { if (doFree && (bufBegin != nullptr)) { delete[] bufBegin; } } /* --- public member functions --- */ virtual T* tellBegin() const { return bufBegin; } virtual ulint_smartpt tellLength() const { return bufLen; } virtual ulint_smartpt tellPos() const { return static_cast(pBufCurrent - bufBegin); } virtual bool checkIndex(ulint_smartpt index) const { return (pBufCurrent + index) < bufEnd; } virtual bool reset() { if (bufLen) { pBufCurrent = bufBegin; status = true; } else { status = false; } return status; } virtual bool good() const { return pBufCurrent < bufEnd; } virtual bool fail() const { return pBufCurrent == bufEnd; } virtual void operator ++() { if (good()) { pBufCurrent++; } else { status = false; } } virtual void operator ++(int) { if (good()) { pBufCurrent++; } else { status = false; } } virtual void operator --() { if (!fail()) { pBufCurrent--; } else { status = false; } } virtual void operator --(int) { if (!fail()) { pBufCurrent--; } else { status = false; } } virtual void operator +=(ulint_smartpt offset) { if (checkIndex(offset)) { pBufCurrent += offset; } else { status = false; } } virtual void operator -=(ulint_smartpt offset) { if ((pBufCurrent-offset) >= bufBegin) { pBufCurrent -= offset; } else { status = false; } } virtual T operator*() { if (good()) { return *pBufCurrent; } else { status = false; return dummy; } } virtual T& operator [](ulint_smartpt index) { if (checkIndex(index)) { return pBufCurrent[index]; } else { status = false; return dummy; } } virtual operator bool() { return status; } protected: T* bufBegin; T* bufEnd; T* pBufCurrent; ulint_smartpt bufLen; bool status; const bool doFree; const T dummy; }; template class SmartPtr_sidtt final : public SmartPtrBase_sidtt { public: SmartPtr_sidtt(T* buffer, ulint_smartpt bufferLen, bool bufOwner = false) : SmartPtrBase_sidtt(buffer, bufferLen, bufOwner) {} SmartPtr_sidtt() : SmartPtrBase_sidtt(0, 0) {} void setBuffer(T* buffer, ulint_smartpt bufferLen) { if ((buffer != nullptr) && (bufferLen != 0)) { this->bufBegin = buffer; this->pBufCurrent = buffer; this->bufEnd = buffer + bufferLen; this->bufLen = bufferLen; this->status = true; } else { this->bufBegin = nullptr; this->pBufCurrent = nullptr; this->bufEnd = nullptr; this->bufLen = 0; this->status = false; } } }; } #endif /* SMARTPTR_H */ libsidplayfp-3.0.0/src/sidtune/p00.h0000644000175100017510000000271415175333711012703 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2015 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef P00_H #define P00_H #include "SidTuneBase.h" #include "sidcxx11.h" namespace libsidplayfp { struct X00Header; class p00 final : public SidTuneBase { protected: p00() {} private: void load(const char* format, const X00Header* pHeader); public: /** * @return pointer to a SidTune or 0 if not a PC64 file * @throw loadError if PC64 file is corrupt */ static SidTuneBase* load(const char *fileName, const buffer_t& dataBuf); ~p00() override = default; private: // prevent copying p00(const p00&) = delete; p00& operator=(p00&) = delete; }; } #endif libsidplayfp-3.0.0/src/sidtune/PSID.cpp0000644000175100017510000003166615175333711013406 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2015 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "PSID.h" #include #include #include #include "sidplayfp/SidTuneInfo.h" #include "sidendian.h" #include "sidmd5.h" namespace libsidplayfp { constexpr int PSID_MAXSTRLEN = 32; // Header has been extended for 'RSID' format // The following changes are present: // id = 'RSID' // version = 2, 3 or 4 // play, load and speed reserved 0 // psidspecific flag is called C64BASIC flag // init cannot be under ROMS/IO memory area // load address cannot be less than $07E8 // info strings may be 32 characters long without trailing zero struct psidHeader // all values are big-endian { uint32_t id; // 'PSID' or 'RSID' (ASCII) uint16_t version; // 1, 2, 3 or 4 uint16_t data; // 16-bit offset to binary data in file uint16_t load; // 16-bit C64 address to load file to uint16_t init; // 16-bit C64 address of init subroutine uint16_t play; // 16-bit C64 address of play subroutine uint16_t songs; // number of songs uint16_t start; // start song out of [1..256] uint32_t speed; // 32-bit speed info // bit: 0=50 Hz, 1=CIA 1 Timer A (default: 60 Hz) char name[PSID_MAXSTRLEN]; // ASCII strings, 31 characters long and char author[PSID_MAXSTRLEN]; // terminated by a trailing zero char released[PSID_MAXSTRLEN]; // uint16_t flags; // only version >= 2 uint8_t relocStartPage; // only version >= 2ng uint8_t relocPages; // only version >= 2ng uint8_t sidChipBase2; // only version >= 3 uint8_t sidChipBase3; // only version >= 4 }; enum { PSID_MUS = 1 << 0, PSID_SPECIFIC = 1 << 1, // These two are mutally exclusive PSID_BASIC = 1 << 1, PSID_CLOCK = 3 << 2, PSID_SIDMODEL = 3 << 4 }; enum { PSID_CLOCK_UNKNOWN = 0, PSID_CLOCK_PAL = 1 << 2, PSID_CLOCK_NTSC = 1 << 3, PSID_CLOCK_ANY = PSID_CLOCK_PAL | PSID_CLOCK_NTSC }; enum { PSID_SIDMODEL_UNKNOWN = 0, PSID_SIDMODEL_6581 = 1, PSID_SIDMODEL_8580 = 2, PSID_SIDMODEL_ANY = PSID_SIDMODEL_6581 | PSID_SIDMODEL_8580 }; // Format strings const char TXT_FORMAT_PSID[] = "PlaySID one-file format (PSID)"; const char TXT_FORMAT_RSID[] = "Real C64 one-file format (RSID)"; const char TXT_UNKNOWN_PSID[] = "Unsupported PSID version"; const char TXT_UNKNOWN_RSID[] = "Unsupported RSID version"; constexpr int psid_headerSize = 118; constexpr int psidv2_headerSize = psid_headerSize + 6; // Magic fields constexpr uint32_t PSID_ID = 0x50534944; constexpr uint32_t RSID_ID = 0x52534944; /** * Decode SID model flags. */ SidTuneInfo::model_t getSidModel(uint_least16_t modelFlag) { if ((modelFlag & PSID_SIDMODEL_ANY) == PSID_SIDMODEL_ANY) return SidTuneInfo::SIDMODEL_ANY; if (modelFlag & PSID_SIDMODEL_6581) return SidTuneInfo::SIDMODEL_6581; if (modelFlag & PSID_SIDMODEL_8580) return SidTuneInfo::SIDMODEL_8580; return SidTuneInfo::SIDMODEL_UNKNOWN; } /** * Check if extra SID addres is valid for PSID specs. */ bool validateAddress(uint_least8_t address) { // Only even values are valid. if (address & 1) return false; // Ranges $00-$41 ($D000-$D410) and $80-$DF ($D800-$DDF0) are invalid. // Any invalid value means that no second SID is used, like $00. if (address <= 0x41 || (address >= 0x80 && address <= 0xdf)) return false; return true; } SidTuneBase* PSID::load(buffer_t& dataBuf) { // File format check if (dataBuf.size() < 4) { return nullptr; } const uint32_t magic = endian_big32(&dataBuf[0]); if ((magic != PSID_ID) && (magic != RSID_ID)) { return nullptr; } psidHeader pHeader; readHeader(dataBuf, pHeader); std::unique_ptr tune(new PSID()); tune->tryLoad(pHeader); return tune.release(); } void PSID::readHeader(const buffer_t &dataBuf, psidHeader &hdr) { // Due to security concerns, input must be at least as long as version 1 // header plus 16-bit C64 load address. That is the area which will be // accessed. if (dataBuf.size() < (psid_headerSize + 2)) { throw loadError(ERR_TRUNCATED); } // Read v1 fields hdr.id = endian_big32(&dataBuf[0]); hdr.version = endian_big16(&dataBuf[4]); hdr.data = endian_big16(&dataBuf[6]); hdr.load = endian_big16(&dataBuf[8]); hdr.init = endian_big16(&dataBuf[10]); hdr.play = endian_big16(&dataBuf[12]); hdr.songs = endian_big16(&dataBuf[14]); hdr.start = endian_big16(&dataBuf[16]); hdr.speed = endian_big32(&dataBuf[18]); std::memcpy(hdr.name, &dataBuf[22], PSID_MAXSTRLEN); std::memcpy(hdr.author, &dataBuf[54], PSID_MAXSTRLEN); std::memcpy(hdr.released, &dataBuf[86], PSID_MAXSTRLEN); if (hdr.version >= 2) { if (dataBuf.size() < (psidv2_headerSize + 2)) { throw loadError(ERR_TRUNCATED); } // Read v2/3/4 fields hdr.flags = endian_big16(&dataBuf[118]); hdr.relocStartPage = dataBuf[120]; hdr.relocPages = dataBuf[121]; hdr.sidChipBase2 = dataBuf[122]; hdr.sidChipBase3 = dataBuf[123]; } } void PSID::tryLoad(const psidHeader &pHeader) { SidTuneInfo::compatibility_t compatibility = SidTuneInfo::COMPATIBILITY_C64; // Require a valid ID and version number. if (pHeader.id == PSID_ID) { switch (pHeader.version) { case 1: compatibility = SidTuneInfo::COMPATIBILITY_PSID; break; case 2: case 3: case 4: break; default: throw loadError(TXT_UNKNOWN_PSID); } info->m_formatString = TXT_FORMAT_PSID; } else if (pHeader.id == RSID_ID) { switch (pHeader.version) { case 2: case 3: case 4: break; default: throw loadError(TXT_UNKNOWN_RSID); } info->m_formatString = TXT_FORMAT_RSID; compatibility = SidTuneInfo::COMPATIBILITY_R64; } fileOffset = pHeader.data; info->m_loadAddr = pHeader.load; info->m_initAddr = pHeader.init; info->m_playAddr = pHeader.play; info->m_songs = pHeader.songs; info->m_startSong = pHeader.start; info->m_compatibility = compatibility; info->m_relocPages = 0; info->m_relocStartPage = 0; uint_least32_t speed = pHeader.speed; SidTuneInfo::clock_t clock = SidTuneInfo::CLOCK_UNKNOWN; bool musPlayer = false; if (pHeader.version >= 2) { const uint_least16_t flags = pHeader.flags; // Check clock if (flags & PSID_MUS) { // MUS tunes run at any speed clock = SidTuneInfo::CLOCK_ANY; musPlayer = true; } else { switch (flags & PSID_CLOCK) { case PSID_CLOCK_ANY: clock = SidTuneInfo::CLOCK_ANY; break; case PSID_CLOCK_PAL: clock = SidTuneInfo::CLOCK_PAL; break; case PSID_CLOCK_NTSC: clock = SidTuneInfo::CLOCK_NTSC; break; default: break; } } // These flags are only available for the appropriate // file formats switch (compatibility) { case SidTuneInfo::COMPATIBILITY_C64: if (flags & PSID_SPECIFIC) info->m_compatibility = SidTuneInfo::COMPATIBILITY_PSID; break; case SidTuneInfo::COMPATIBILITY_R64: if (flags & PSID_BASIC) info->m_compatibility = SidTuneInfo::COMPATIBILITY_BASIC; break; default: break; } info->m_clockSpeed = clock; info->m_sidModels[0] = getSidModel(flags >> 4); info->m_relocStartPage = pHeader.relocStartPage; info->m_relocPages = pHeader.relocPages; if (pHeader.version >= 3) { if (validateAddress(pHeader.sidChipBase2)) { info->m_sidChipAddresses.push_back(0xd000 | (pHeader.sidChipBase2 << 4)); info->m_sidModels.push_back(getSidModel(flags >> 6)); } if (pHeader.version >= 4) { if (pHeader.sidChipBase3 != pHeader.sidChipBase2 && validateAddress(pHeader.sidChipBase3)) { info->m_sidChipAddresses.push_back(0xd000 | (pHeader.sidChipBase3 << 4)); info->m_sidModels.push_back(getSidModel(flags >> 8)); } } } } // Check reserved fields to force real c64 compliance // as required by the RSID specification if (compatibility == SidTuneInfo::COMPATIBILITY_R64) { if ((info->m_loadAddr != 0) || (info->m_playAddr != 0) || (speed != 0)) { throw loadError(ERR_INVALID); } // Real C64 tunes appear as CIA speed = ~0; } // Create the speed/clock setting table. convertOldStyleSpeedToTables(speed, clock); // Copy info strings. info->m_infoString.push_back(std::string(pHeader.name, PSID_MAXSTRLEN)); info->m_infoString.push_back(std::string(pHeader.author, PSID_MAXSTRLEN)); info->m_infoString.push_back(std::string(pHeader.released, PSID_MAXSTRLEN)); if (musPlayer) throw loadError("Compute!'s Sidplayer MUS data is not supported yet"); // TODO } const char *PSID::createMD5(char *md5) { if (md5 == nullptr) md5 = m_md5; *md5 = '\0'; // Include C64 data. sidmd5 myMD5; myMD5.append(&cache[fileOffset], info->m_c64dataLen); uint8_t tmp[2]; // Include INIT and PLAY address. endian_little16(tmp, info->m_initAddr); myMD5.append(tmp, sizeof(tmp)); endian_little16(tmp, info->m_playAddr); myMD5.append(tmp, sizeof(tmp)); // Include number of songs. endian_little16(tmp, info->m_songs); myMD5.append(tmp, sizeof(tmp)); { // Include song speed for each song. const unsigned int currentSong = info->m_currentSong; for (unsigned int s = 1; s <= info->m_songs; s++) { selectSong(s); const uint8_t songSpeed = static_cast(info->m_songSpeed); myMD5.append(&songSpeed, sizeof(songSpeed)); } // Restore old song selectSong(currentSong); } // Deal with PSID v2NG clock speed flags: Let only NTSC // clock speed change the MD5 fingerprint. That way the // fingerprint of a PAL-speed sidtune in PSID v1, v2, and // PSID v2NG format is the same. if (info->m_clockSpeed == SidTuneInfo::CLOCK_NTSC) { const uint8_t ntsc_val = 2; myMD5.append(&ntsc_val, sizeof(ntsc_val)); } // NB! If the fingerprint is used as an index into a // song-lengths database or cache, modify above code to // allow for PSID v2NG files which have clock speed set to // SIDTUNE_CLOCK_ANY. If the SID player program fully // supports the SIDTUNE_CLOCK_ANY setting, a sidtune could // either create two different fingerprints depending on // the clock speed chosen by the player, or there could be // two different values stored in the database/cache. // Get fingerprint. myMD5.getDigest().copy(md5, SidTune::MD5_LENGTH); md5[SidTune::MD5_LENGTH] = '\0'; return md5; } const char *PSID::createMD5New(char *md5) { if (md5 == nullptr) md5 = m_md5; *md5 = '\0'; // The calculation is now simplified // All the header + all the data sidmd5 myMD5; myMD5.append(&cache[0], cache.size()); // Get fingerprint. myMD5.getDigest().copy(md5, SidTune::MD5_LENGTH); md5[SidTune::MD5_LENGTH] = '\0'; return md5; } } libsidplayfp-3.0.0/src/sidtune/sidplayer2.bin0000644000175100017510000004702215175333725014711 0x01, 0x00, 0x6f, 0x36, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10, 0x9e, 0x0c, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xf1, 0x60, 0x01, 0x02, 0x04, 0x00, 0x07, 0x0e, 0x02, 0x02, 0xfe, 0x02, 0x02, 0xfe, 0xfe, 0x00, 0x01, 0x00, 0xff, 0x00, 0x02, 0x04, 0x05, 0x07, 0x09, 0x0b, 0x1e, 0x18, 0x8b, 0x7e, 0xfa, 0x06, 0xac, 0xf3, 0xe6, 0x8f, 0xf8, 0x2e, 0x86, 0x8e, 0x96, 0x9f, 0xa8, 0xb3, 0xbd, 0xc8, 0xd4, 0xe1, 0xee, 0xfd, 0x8c, 0x78, 0x64, 0x50, 0x3c, 0x28, 0x14, 0x00, 0x00, 0x02, 0x03, 0x05, 0x07, 0x08, 0x0a, 0x0c, 0x0d, 0x0f, 0x11, 0x12, 0x00, 0xe0, 0x00, 0x05, 0x0a, 0x0f, 0xf9, 0x00, 0xf5, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x20, 0x00, 0x00, 0x30, 0x00, 0x00, 0x40, 0x00, 0x00, 0x50, 0x00, 0x00, 0x60, 0x00, 0x00, 0x70, 0x00, 0x00, 0x80, 0x00, 0x00, 0x90, 0x00, 0x00, 0xa0, 0x00, 0xa9, 0x00, 0x8d, 0x00, 0xf0, 0xa2, 0x95, 0xa0, 0x42, 0xad, 0xa6, 0x02, 0xf0, 0x04, 0xa2, 0x25, 0xa0, 0x40, 0x8e, 0x5b, 0xf1, 0x8c, 0x5c, 0xf1, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0x60, 0xa9, 0x00, 0x8d, 0x00, 0xf0, 0x86, 0x61, 0x84, 0x62, 0xa0, 0xbc, 0x99, 0x00, 0xf0, 0x88, 0xd0, 0xfa, 0xa0, 0x72, 0x99, 0xbc, 0xf0, 0x88, 0xd0, 0xfa, 0x8d, 0x15, 0xd5, 0x8d, 0x16, 0xd5, 0xa9, 0x08, 0x8d, 0x25, 0xf0, 0x8d, 0x17, 0xd5, 0x8d, 0x26, 0xf0, 0x8d, 0x18, 0xd5, 0xa9, 0x90, 0x8d, 0x27, 0xf0, 0xa9, 0x60, 0x8d, 0x28, 0xf0, 0xa9, 0x0c, 0x8d, 0x29, 0xf0, 0xad, 0x5b, 0xf1, 0x8d, 0x2d, 0xf0, 0xad, 0x5c, 0xf1, 0x8d, 0x2e, 0xf0, 0xa9, 0xff, 0x8d, 0xcc, 0xf0, 0xa9, 0xd5, 0x85, 0x64, 0xa2, 0x02, 0xa9, 0xff, 0x9d, 0x0b, 0xf0, 0xa9, 0x01, 0x9d, 0x30, 0xf0, 0x9d, 0x2a, 0xf0, 0x8a, 0x9d, 0x33, 0xf0, 0x9d, 0xae, 0xf0, 0xa9, 0x04, 0x9d, 0x39, 0xf0, 0xbd, 0xa8, 0xf1, 0x9d, 0xba, 0xf0, 0xa9, 0x5b, 0x9d, 0x7e, 0xf0, 0xbd, 0x65, 0xf1, 0x85, 0x63, 0xa9, 0x00, 0xa8, 0x91, 0x63, 0xc8, 0x91, 0x63, 0xc8, 0x91, 0x63, 0xa9, 0x08, 0x9d, 0x17, 0xf0, 0x9d, 0x9c, 0xf0, 0xc8, 0x91, 0x63, 0xc8, 0x91, 0x63, 0xa9, 0x40, 0x9d, 0x1a, 0xf0, 0x91, 0x63, 0xa9, 0x20, 0x9d, 0x1d, 0xf0, 0xc8, 0x91, 0x63, 0xa9, 0xf5, 0x9d, 0x20, 0xf0, 0xc8, 0x91, 0x63, 0xca, 0x10, 0xa4, 0x8a, 0xa2, 0x17, 0x9d, 0x3e, 0xf1, 0xca, 0x10, 0xfa, 0xa5, 0x61, 0x18, 0x69, 0x06, 0x85, 0x63, 0xa9, 0x00, 0xaa, 0xa8, 0x65, 0x62, 0x85, 0x64, 0x9d, 0xab, 0xf0, 0x9d, 0xb4, 0xf0, 0xa5, 0x63, 0x9d, 0xa8, 0xf0, 0x9d, 0xb1, 0xf0, 0x18, 0x71, 0x61, 0x85, 0x63, 0xa5, 0x64, 0xc8, 0x71, 0x61, 0xc8, 0xe8, 0xe0, 0x03, 0xd0, 0xe0, 0xa6, 0x63, 0xa8, 0x60, 0xa9, 0x00, 0x8d, 0x04, 0xd5, 0x8d, 0x0b, 0xd5, 0x8d, 0x12, 0xd5, 0x8d, 0x01, 0xd5, 0x8d, 0x08, 0xd5, 0x8d, 0x0f, 0xd5, 0xa9, 0x08, 0x8d, 0x17, 0xd5, 0xad, 0x5b, 0xf1, 0x8d, 0x04, 0xdc, 0xad, 0x5c, 0xf1, 0x8d, 0x05, 0xdc, 0x60, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0x60, 0xa9, 0x08, 0x8d, 0x00, 0xf0, 0x6c, 0x5d, 0xf1, 0xea, 0xea, 0xea, 0xad, 0x00, 0xf0, 0x30, 0xf0, 0x09, 0x80, 0xa8, 0x29, 0x07, 0xf0, 0xee, 0xd8, 0x8c, 0x00, 0xf0, 0xea, 0xa5, 0xfb, 0x8d, 0x56, 0xf1, 0xa5, 0xfc, 0x8d, 0x57, 0xf1, 0xa5, 0xfd, 0x8d, 0x58, 0xf1, 0xa5, 0xfe, 0x8d, 0x59, 0xf1, 0xa5, 0xff, 0x8d, 0x5a, 0xf1, 0xad, 0x23, 0xf0, 0x18, 0x6d, 0xd9, 0xf0, 0x48, 0x29, 0x07, 0xa8, 0xad, 0xdc, 0xf0, 0x69, 0x00, 0x85, 0xff, 0x68, 0x46, 0xff, 0x6a, 0x46, 0xff, 0x6a, 0x46, 0xff, 0x6a, 0x18, 0x6d, 0x24, 0xf0, 0x8c, 0x15, 0xd5, 0x8d, 0x16, 0xd5, 0xad, 0x25, 0xf0, 0x8d, 0x17, 0xd5, 0xad, 0x26, 0xf0, 0x8d, 0x18, 0xd5, 0xa9, 0xd5, 0x85, 0xfc, 0xa2, 0x00, 0xad, 0x00, 0xf0, 0x3d, 0x62, 0xf1, 0xf0, 0x51, 0xbd, 0x65, 0xf1, 0x85, 0xfb, 0xbd, 0x0e, 0xf0, 0x18, 0x7d, 0x51, 0xf0, 0xa8, 0xbd, 0x11, 0xf0, 0x7d, 0x54, 0xf0, 0x48, 0x98, 0x18, 0x7d, 0xcd, 0xf0, 0xa0, 0x00, 0x91, 0xfb, 0x68, 0x7d, 0xd0, 0xf0, 0xc8, 0x91, 0xfb, 0xbd, 0x14, 0xf0, 0x18, 0x7d, 0x69, 0xf0, 0x85, 0xff, 0xbd, 0x17, 0xf0, 0x7d, 0x6c, 0xf0, 0x48, 0xa5, 0xff, 0x18, 0x7d, 0xd3, 0xf0, 0xc8, 0x91, 0xfb, 0x68, 0x7d, 0xd6, 0xf0, 0xc8, 0x91, 0xfb, 0xbd, 0x1d, 0xf0, 0xc8, 0xc8, 0x91, 0xfb, 0xbd, 0x20, 0xf0, 0xc8, 0x91, 0xfb, 0xe8, 0xe0, 0x03, 0xd0, 0xa2, 0xac, 0x1a, 0xf0, 0xae, 0x1b, 0xf0, 0xad, 0x1c, 0xf0, 0x8c, 0x04, 0xd5, 0x8e, 0x0b, 0xd5, 0x8d, 0x12, 0xd5, 0xae, 0x2d, 0xf0, 0xac, 0x2e, 0xf0, 0x8e, 0x04, 0xdc, 0x8c, 0x05, 0xdc, 0xad, 0x1b, 0xd5, 0x8d, 0xbe, 0xf0, 0xad, 0x1c, 0xd5, 0x8d, 0xbf, 0xf0, 0xa2, 0x00, 0xad, 0x00, 0xf0, 0x3d, 0x62, 0xf1, 0xf0, 0x10, 0x8e, 0x2f, 0xf0, 0x20, 0x36, 0xf5, 0xad, 0x00, 0xf0, 0x29, 0x78, 0xf0, 0x03, 0x4c, 0x0c, 0xf5, 0xe8, 0xe0, 0x03, 0xd0, 0xe3, 0xad, 0xc9, 0xf0, 0xd0, 0x52, 0xad, 0xca, 0xf0, 0x0d, 0xcb, 0xf0, 0xf0, 0x78, 0xad, 0xdf, 0xf0, 0xd0, 0x28, 0xad, 0xca, 0xf0, 0xf0, 0x28, 0x18, 0x6d, 0xbd, 0xf0, 0xb0, 0x07, 0xcd, 0xcc, 0xf0, 0x90, 0x60, 0xf0, 0x5e, 0xa9, 0x00, 0x8d, 0xdf, 0xf0, 0xad, 0xcb, 0xf0, 0xf0, 0x54, 0xee, 0xdf, 0xf0, 0xad, 0xbd, 0xf0, 0xed, 0xcb, 0xf0, 0x4c, 0xb4, 0xf4, 0xad, 0xcb, 0xf0, 0xf0, 0xd3, 0xad, 0xbd, 0xf0, 0x38, 0xed, 0xcb, 0xf0, 0xb0, 0x3a, 0xa9, 0x00, 0x8d, 0xdf, 0xf0, 0xad, 0xca, 0xf0, 0xd0, 0x30, 0xee, 0xdf, 0xf0, 0xd0, 0x28, 0xce, 0xe0, 0xf0, 0xd0, 0x29, 0xad, 0xdf, 0xf0, 0xd0, 0x11, 0xee, 0xdf, 0xf0, 0xad, 0xcb, 0xf0, 0xd0, 0x02, 0xa9, 0x20, 0x8d, 0xe0, 0xf0, 0xa9, 0x00, 0xf0, 0x10, 0xce, 0xdf, 0xf0, 0xad, 0xca, 0xf0, 0xd0, 0x02, 0xa9, 0x20, 0x8d, 0xe0, 0xf0, 0xad, 0xcc, 0xf0, 0x8d, 0xbd, 0xf0, 0xa2, 0x00, 0xbd, 0xc3, 0xf0, 0xf0, 0x44, 0xa9, 0x00, 0x85, 0xff, 0xbc, 0xc0, 0xf0, 0xb9, 0xbd, 0xf0, 0xbc, 0xc6, 0xf0, 0xf0, 0x0e, 0x30, 0x08, 0x0a, 0x26, 0xff, 0x88, 0xd0, 0xfa, 0xf0, 0x04, 0x4a, 0xc8, 0xd0, 0xfc, 0xbc, 0xc3, 0xf0, 0x88, 0xd0, 0x0b, 0x9d, 0xcd, 0xf0, 0xa5, 0xff, 0x9d, 0xd0, 0xf0, 0x4c, 0x02, 0xf5, 0x88, 0xd0, 0x0b, 0x9d, 0xd3, 0xf0, 0xa5, 0xff, 0x9d, 0xd6, 0xf0, 0x4c, 0x02, 0xf5, 0x8d, 0xd9, 0xf0, 0xa5, 0xff, 0x8d, 0xdc, 0xf0, 0xe8, 0xe0, 0x03, 0xd0, 0xb2, 0xad, 0x00, 0xf0, 0x29, 0x7f, 0x8d, 0x00, 0xf0, 0xad, 0x56, 0xf1, 0x85, 0xfb, 0xad, 0x57, 0xf1, 0x85, 0xfc, 0xad, 0x58, 0xf1, 0x85, 0xfd, 0xad, 0x59, 0xf1, 0x85, 0xfe, 0xad, 0x5a, 0xf1, 0x85, 0xff, 0x6c, 0x5d, 0xf1, 0xbd, 0x60, 0xf0, 0xd0, 0x03, 0x4c, 0x9f, 0xf6, 0x4c, 0xba, 0xf5, 0xde, 0x30, 0xf0, 0xd0, 0x03, 0x4c, 0xa0, 0xf6, 0xbd, 0x36, 0xf0, 0x30, 0xe8, 0xd0, 0x1a, 0xbd, 0x3f, 0xf0, 0xf0, 0x05, 0xde, 0x3f, 0xf0, 0xd0, 0x10, 0xbd, 0x39, 0xf0, 0xdd, 0x30, 0xf0, 0x90, 0x08, 0xbd, 0x1a, 0xf0, 0x29, 0xfe, 0x9d, 0x1a, 0xf0, 0xbd, 0x42, 0xf0, 0xf0, 0x56, 0x0a, 0xbd, 0x0e, 0xf0, 0xb0, 0x1d, 0x7d, 0x45, 0xf0, 0x9d, 0x0e, 0xf0, 0xa8, 0xbd, 0x11, 0xf0, 0x7d, 0x48, 0xf0, 0x9d, 0x11, 0xf0, 0x48, 0x98, 0xdd, 0x8d, 0xf0, 0x68, 0xfd, 0x90, 0xf0, 0xb0, 0x1f, 0x90, 0x2e, 0xfd, 0x45, 0xf0, 0x9d, 0x0e, 0xf0, 0xbd, 0x11, 0xf0, 0xfd, 0x48, 0xf0, 0x9d, 0x11, 0xf0, 0xbd, 0x8d, 0xf0, 0xdd, 0x0e, 0xf0, 0xbd, 0x90, 0xf0, 0xfd, 0x11, 0xf0, 0x90, 0x11, 0xbd, 0x8d, 0xf0, 0x9d, 0x0e, 0xf0, 0xbd, 0x90, 0xf0, 0x9d, 0x11, 0xf0, 0xa9, 0x00, 0x9d, 0x42, 0xf0, 0xbd, 0x60, 0xf0, 0xf0, 0x55, 0xbd, 0x4b, 0xf0, 0xf0, 0x4b, 0xa0, 0x00, 0xde, 0x4e, 0xf0, 0xd0, 0x31, 0xbd, 0x51, 0xf0, 0x1d, 0x54, 0xf0, 0xd0, 0x1b, 0xbd, 0x5d, 0xf0, 0x9d, 0x57, 0xf0, 0x9d, 0x4e, 0xf0, 0xbd, 0x4b, 0xf0, 0x0a, 0xbd, 0x5a, 0xf0, 0x90, 0x04, 0x49, 0xff, 0x69, 0x00, 0x9d, 0x4b, 0xf0, 0xd0, 0x10, 0xbd, 0x57, 0xf0, 0x9d, 0x4e, 0xf0, 0x98, 0x38, 0xfd, 0x4b, 0xf0, 0x9d, 0x4b, 0xf0, 0xc9, 0x00, 0x10, 0x01, 0x88, 0x18, 0x7d, 0x51, 0xf0, 0x9d, 0x51, 0xf0, 0x98, 0x7d, 0x54, 0xf0, 0x9d, 0x54, 0xf0, 0xbd, 0x36, 0xf0, 0x30, 0x15, 0xbd, 0x93, 0xf0, 0xf0, 0x10, 0x18, 0x7d, 0x14, 0xf0, 0x9d, 0x14, 0xf0, 0xbd, 0x96, 0xf0, 0x7d, 0x17, 0xf0, 0x9d, 0x17, 0xf0, 0xbd, 0x63, 0xf0, 0xf0, 0x4b, 0xa0, 0x00, 0xde, 0x66, 0xf0, 0xd0, 0x31, 0xbd, 0x69, 0xf0, 0x1d, 0x6c, 0xf0, 0xd0, 0x1b, 0xbd, 0x72, 0xf0, 0x9d, 0x6f, 0xf0, 0x9d, 0x66, 0xf0, 0xbd, 0x63, 0xf0, 0x0a, 0xbd, 0x75, 0xf0, 0x90, 0x04, 0x49, 0xff, 0x69, 0x00, 0x9d, 0x63, 0xf0, 0xd0, 0x10, 0xbd, 0x6f, 0xf0, 0x9d, 0x66, 0xf0, 0x98, 0x38, 0xfd, 0x63, 0xf0, 0x9d, 0x63, 0xf0, 0xc9, 0x00, 0x10, 0x01, 0x88, 0x18, 0x7d, 0x69, 0xf0, 0x9d, 0x69, 0xf0, 0x98, 0x7d, 0x6c, 0xf0, 0x9d, 0x6c, 0xf0, 0xbd, 0x36, 0xf0, 0x10, 0x03, 0x4c, 0x9f, 0xf6, 0xa0, 0x00, 0xbd, 0xa2, 0xf0, 0xf0, 0x1c, 0x10, 0x01, 0xc8, 0x18, 0x6d, 0x23, 0xf0, 0x48, 0x29, 0x07, 0x8d, 0x23, 0xf0, 0x68, 0x6a, 0x4a, 0x4a, 0x18, 0x79, 0xa6, 0xf1, 0x18, 0x6d, 0x24, 0xf0, 0x8d, 0x24, 0xf0, 0x60, 0xbd, 0xa8, 0xf0, 0x85, 0xfd, 0xbd, 0xab, 0xf0, 0x85, 0xfe, 0xd0, 0x04, 0x60, 0x20, 0x98, 0xf8, 0xad, 0x00, 0xf0, 0x3d, 0x62, 0xf1, 0xf0, 0xf4, 0xa0, 0x00, 0xb1, 0xfd, 0x85, 0xff, 0xc8, 0xb1, 0xfd, 0xa8, 0xa5, 0xfd, 0x18, 0x69, 0x02, 0x85, 0xfd, 0x9d, 0xa8, 0xf0, 0xa5, 0xfe, 0x69, 0x00, 0x85, 0xfe, 0x9d, 0xab, 0xf0, 0xa5, 0xff, 0x29, 0x03, 0xd0, 0xd2, 0xbd, 0x8d, 0xf0, 0x9d, 0x0e, 0xf0, 0xbd, 0x90, 0xf0, 0x9d, 0x11, 0xf0, 0xa5, 0xff, 0x9d, 0x05, 0xf0, 0x98, 0x9d, 0x02, 0xf0, 0x29, 0x07, 0xa8, 0xb9, 0x67, 0xf1, 0x8d, 0x6f, 0xf1, 0xbd, 0x02, 0xf0, 0x29, 0x38, 0x4a, 0x4a, 0x4a, 0x7d, 0x81, 0xf0, 0x85, 0xfd, 0xbd, 0x02, 0xf0, 0x29, 0xc0, 0x0a, 0x2a, 0x2a, 0xa8, 0xb9, 0x6f, 0xf1, 0x85, 0xfe, 0xbd, 0x02, 0xf0, 0x29, 0x07, 0xf0, 0x62, 0xa8, 0xb9, 0x72, 0xf1, 0x65, 0xfe, 0x18, 0x7d, 0x84, 0xf0, 0x10, 0x05, 0x18, 0x69, 0x0c, 0xe6, 0xfd, 0xc9, 0x0c, 0x90, 0x04, 0xe9, 0x0c, 0xc6, 0xfd, 0x85, 0xfe, 0xa8, 0xb9, 0x86, 0xf1, 0x85, 0xff, 0xb9, 0x7a, 0xf1, 0xa4, 0xfd, 0x88, 0x30, 0x06, 0x46, 0xff, 0x6a, 0x88, 0x10, 0xfa, 0x18, 0x7d, 0x87, 0xf0, 0x9d, 0x8d, 0xf0, 0xa5, 0xff, 0x7d, 0x8a, 0xf0, 0x9d, 0x90, 0xf0, 0xbd, 0x05, 0xf0, 0xd0, 0x03, 0x4c, 0xa0, 0xf6, 0xbd, 0x45, 0xf0, 0x1d, 0x48, 0xf0, 0xf0, 0x16, 0xbd, 0x0e, 0xf0, 0xdd, 0x8d, 0xf0, 0xbd, 0x11, 0xf0, 0xfd, 0x90, 0xf0, 0xa9, 0xfe, 0x6a, 0x9d, 0x42, 0xf0, 0x90, 0x11, 0xf0, 0x4a, 0x9d, 0x42, 0xf0, 0xbd, 0x8d, 0xf0, 0x9d, 0x0e, 0xf0, 0xbd, 0x90, 0xf0, 0x9d, 0x11, 0xf0, 0xbd, 0x36, 0xf0, 0x0a, 0xd0, 0x35, 0xbd, 0x93, 0xf0, 0xf0, 0x0c, 0xbd, 0x99, 0xf0, 0x9d, 0x14, 0xf0, 0xbd, 0x9c, 0xf0, 0x9d, 0x17, 0xf0, 0xbd, 0x9f, 0xf0, 0xf0, 0x0f, 0xa4, 0xfd, 0x18, 0x79, 0x92, 0xf1, 0xa4, 0xfe, 0x18, 0x79, 0x9a, 0xf1, 0x18, 0x90, 0x08, 0xbd, 0xa2, 0xf0, 0xf0, 0x0b, 0xbd, 0xa5, 0xf0, 0x8d, 0x24, 0xf0, 0xa9, 0x00, 0x8d, 0x23, 0xf0, 0xbd, 0x3c, 0xf0, 0x9d, 0x3f, 0xf0, 0xbd, 0x05, 0xf0, 0x29, 0x40, 0x9d, 0x36, 0xf0, 0xbd, 0x05, 0xf0, 0x4a, 0x4a, 0x29, 0x07, 0xd0, 0x30, 0xbd, 0x05, 0xf0, 0x30, 0x14, 0xad, 0x27, 0xf0, 0x29, 0x3c, 0xd0, 0x1e, 0xad, 0x27, 0xf0, 0x0a, 0x2a, 0x2a, 0xd0, 0x02, 0xa9, 0x04, 0x4c, 0x70, 0xf8, 0xad, 0x28, 0xf0, 0xf0, 0x0c, 0x29, 0x3f, 0xd0, 0x08, 0xad, 0x28, 0xf0, 0x0a, 0x2a, 0x2a, 0xd0, 0x66, 0xa9, 0x10, 0x8d, 0x00, 0xf0, 0x60, 0xc9, 0x01, 0xd0, 0x13, 0xbd, 0x05, 0xf0, 0x29, 0x20, 0xd0, 0x06, 0xad, 0x29, 0xf0, 0x4c, 0x70, 0xf8, 0xbd, 0x2a, 0xf0, 0x4c, 0x70, 0xf8, 0xa8, 0xbd, 0x05, 0xf0, 0x29, 0xa0, 0xc9, 0x80, 0xf0, 0x30, 0x85, 0xff, 0x18, 0xad, 0x27, 0xf0, 0xd0, 0x01, 0x38, 0x88, 0x88, 0xf0, 0x06, 0x6a, 0xb0, 0x4e, 0x88, 0xd0, 0xfa, 0xa4, 0xff, 0x85, 0xff, 0xf0, 0x26, 0x46, 0xff, 0xb0, 0x41, 0xf0, 0x42, 0x65, 0xff, 0xb0, 0x3e, 0xc8, 0x10, 0x19, 0x46, 0xff, 0xb0, 0x34, 0x65, 0xff, 0x90, 0x11, 0xb0, 0x31, 0xad, 0x28, 0xf0, 0xf0, 0x29, 0x88, 0x88, 0xf0, 0x06, 0x4a, 0xb0, 0x22, 0x88, 0xd0, 0xfa, 0x9d, 0x30, 0xf0, 0xbd, 0x1a, 0xf0, 0x29, 0xf6, 0x9d, 0x1a, 0xf0, 0x38, 0xbd, 0x02, 0xf0, 0x29, 0x07, 0xd0, 0x03, 0x7e, 0x36, 0xf0, 0xbd, 0x1a, 0xf0, 0x69, 0x00, 0x9d, 0x1a, 0xf0, 0x60, 0xa9, 0x10, 0x2c, 0xa9, 0x18, 0x8d, 0x00, 0xf0, 0x60, 0x98, 0x48, 0xa5, 0xff, 0x4a, 0x90, 0x03, 0x4c, 0x42, 0xfa, 0x4a, 0x4a, 0xb0, 0x1e, 0x4a, 0xb0, 0x0e, 0x9d, 0x9c, 0xf0, 0x9d, 0x17, 0xf0, 0x68, 0x9d, 0x99, 0xf0, 0x9d, 0x14, 0xf0, 0x60, 0x4a, 0x90, 0x02, 0x09, 0xf8, 0x9d, 0x8a, 0xf0, 0x68, 0x9d, 0x87, 0xf0, 0x60, 0x4a, 0xb0, 0x03, 0x4c, 0x4a, 0xf9, 0x4a, 0xb0, 0x61, 0x4a, 0xb0, 0x0f, 0xd0, 0x08, 0x68, 0x9d, 0xa5, 0xf0, 0x8d, 0x24, 0xf0, 0x60, 0x68, 0x9d, 0x3c, 0xf0, 0x60, 0xd0, 0x48, 0x68, 0x9d, 0x7e, 0xf0, 0xc9, 0x5b, 0xf0, 0x33, 0xa8, 0x4a, 0x4a, 0x4a, 0x38, 0xe9, 0x0b, 0x18, 0x7d, 0x84, 0xf0, 0x30, 0x0c, 0xc9, 0x0c, 0x90, 0x11, 0xe9, 0x0c, 0xde, 0x81, 0xf0, 0x4c, 0x0b, 0xf9, 0xc9, 0xf5, 0xb0, 0x05, 0x69, 0x0c, 0xfe, 0x81, 0xf0, 0x9d, 0x84, 0xf0, 0x98, 0x29, 0x07, 0x38, 0xe9, 0x03, 0x18, 0x7d, 0x81, 0xf0, 0x9d, 0x81, 0xf0, 0x60, 0xbd, 0x78, 0xf0, 0x9d, 0x81, 0xf0, 0xbd, 0x7b, 0xf0, 0x9d, 0x84, 0xf0, 0x60, 0x68, 0x9d, 0xc6, 0xf0, 0x60, 0x4a, 0xb0, 0x08, 0x9d, 0x0b, 0xf0, 0x68, 0x9d, 0x08, 0xf0, 0x60, 0x4a, 0x6a, 0x6a, 0x6d, 0x5b, 0xf1, 0x8d, 0x2d, 0xf0, 0x68, 0x6d, 0x5c, 0xf1, 0x8d, 0x2e, 0xf0, 0x60, 0x4a, 0x90, 0x03, 0x4c, 0xd3, 0xf9, 0x4a, 0xb0, 0x40, 0x4a, 0xb0, 0x17, 0x4a, 0xb0, 0x0f, 0x68, 0x8d, 0x27, 0xf0, 0x4a, 0x4a, 0x4a, 0xa8, 0xb9, 0xaf, 0xf1, 0x8d, 0x28, 0xf0, 0x60, 0x68, 0x9d, 0x5d, 0xf0, 0x60, 0x4a, 0xb0, 0x05, 0x68, 0x8d, 0x01, 0xf0, 0x60, 0x68, 0xf0, 0x11, 0x9d, 0x75, 0xf0, 0xbc, 0x63, 0xf0, 0xd0, 0x08, 0x9d, 0x63, 0xf0, 0xa9, 0x01, 0x9d, 0x66, 0xf0, 0x60, 0x9d, 0x63, 0xf0, 0x9d, 0x69, 0xf0, 0x9d, 0x6c, 0xf0, 0x60, 0x4a, 0xb0, 0x30, 0x4a, 0xb0, 0x05, 0x68, 0x9d, 0x39, 0xf0, 0x60, 0x68, 0xa0, 0x00, 0x4a, 0x90, 0x02, 0xc8, 0x18, 0x48, 0x29, 0x07, 0x79, 0xac, 0xf1, 0x9d, 0x78, 0xf0, 0x9d, 0x81, 0xf0, 0x68, 0x4a, 0x4a, 0x4a, 0x18, 0x79, 0xad, 0xf1, 0x9d, 0x7b, 0xf0, 0x9d, 0x84, 0xf0, 0xa9, 0x5b, 0x9d, 0x7e, 0xf0, 0x60, 0x4a, 0xb0, 0x05, 0x68, 0x9d, 0xa2, 0xf0, 0x60, 0x68, 0x8d, 0xcc, 0xf0, 0x60, 0x4a, 0xb0, 0x27, 0x4a, 0xb0, 0x0d, 0x4a, 0xb0, 0x05, 0x68, 0x8d, 0x29, 0xf0, 0x60, 0x68, 0x9d, 0x9f, 0xf0, 0x60, 0x4a, 0xb0, 0x0f, 0x68, 0x9d, 0x93, 0xf0, 0xa0, 0x00, 0x0a, 0x90, 0x01, 0x88, 0x98, 0x9d, 0x96, 0xf0, 0x60, 0x68, 0x9d, 0x72, 0xf0, 0x60, 0x4a, 0xb0, 0x1c, 0x4a, 0xb0, 0x15, 0x68, 0x9d, 0xb7, 0xf0, 0xa5, 0xfd, 0x9d, 0xb1, 0xf0, 0xa5, 0xfe, 0x9d, 0xb4, 0xf0, 0xbd, 0x33, 0xf0, 0x9d, 0xae, 0xf0, 0x60, 0x68, 0x6c, 0x5f, 0xf1, 0x4a, 0xb0, 0x1e, 0x68, 0xd0, 0x0a, 0x9d, 0x4b, 0xf0, 0x9d, 0x51, 0xf0, 0x9d, 0x54, 0xf0, 0x60, 0x9d, 0x5a, 0xf0, 0xbc, 0x4b, 0xf0, 0xd0, 0x08, 0x9d, 0x4b, 0xf0, 0xa9, 0x01, 0x9d, 0x4e, 0xf0, 0x60, 0x68, 0x9d, 0x2a, 0xf0, 0x60, 0x4a, 0x90, 0x08, 0x9d, 0x48, 0xf0, 0x68, 0x9d, 0x45, 0xf0, 0x60, 0x68, 0x4a, 0xb0, 0x61, 0x4a, 0xb0, 0x25, 0x4a, 0xb0, 0x05, 0x4a, 0xa0, 0xf0, 0xd0, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0xa0, 0x0f, 0x85, 0xff, 0x98, 0xb0, 0x09, 0x3d, 0x1d, 0xf0, 0x05, 0xff, 0x9d, 0x1d, 0xf0, 0x60, 0x3d, 0x20, 0xf0, 0x05, 0xff, 0x9d, 0x20, 0xf0, 0x60, 0x4a, 0xb0, 0x38, 0x4a, 0xb0, 0x64, 0x85, 0xff, 0xbd, 0xba, 0xf0, 0xdd, 0xa9, 0xf1, 0xf0, 0x54, 0xfe, 0xba, 0xf0, 0xa8, 0xa5, 0xfd, 0x99, 0xe1, 0xf0, 0xa5, 0xfe, 0x99, 0xf0, 0xf0, 0xbd, 0x33, 0xf0, 0x99, 0x2f, 0xf1, 0xa4, 0xff, 0xb9, 0x17, 0xf1, 0xf0, 0x36, 0x85, 0xfe, 0xb9, 0xff, 0xf0, 0x85, 0xfd, 0xb9, 0x3e, 0xf1, 0x9d, 0x33, 0xf0, 0x60, 0xb0, 0x4b, 0x4a, 0xb0, 0x3c, 0xa8, 0xa5, 0xfd, 0x99, 0xff, 0xf0, 0xa5, 0xfe, 0x99, 0x17, 0xf1, 0xbd, 0x33, 0xf0, 0x99, 0x3e, 0xf1, 0xbd, 0xba, 0xf0, 0xdd, 0xa9, 0xf1, 0xf0, 0x0d, 0xfe, 0xba, 0xf0, 0xa8, 0xa9, 0x00, 0x99, 0xf0, 0xf0, 0x60, 0xa9, 0x30, 0x2c, 0xa9, 0x28, 0x8d, 0x00, 0xf0, 0x60, 0x0a, 0x0a, 0x0a, 0x0a, 0x4d, 0x25, 0xf0, 0x29, 0xf0, 0x4d, 0x25, 0xf0, 0x8d, 0x25, 0xf0, 0x60, 0x4d, 0x26, 0xf0, 0x29, 0x0f, 0x4d, 0x26, 0xf0, 0x8d, 0x26, 0xf0, 0x60, 0x4a, 0xb0, 0x0b, 0x4a, 0xb0, 0x04, 0x8d, 0xca, 0xf0, 0x60, 0x8d, 0xcb, 0xf0, 0x60, 0x4a, 0x90, 0x03, 0x4c, 0xa5, 0xfb, 0x4a, 0xa8, 0xf0, 0x21, 0x88, 0xf0, 0x34, 0x88, 0xf0, 0x42, 0x88, 0xf0, 0x4a, 0x88, 0xf0, 0x52, 0x88, 0xf0, 0x5c, 0x88, 0xf0, 0x66, 0x88, 0xf0, 0x73, 0x29, 0x07, 0x09, 0x10, 0xb0, 0x03, 0x4c, 0xb7, 0xfa, 0x4c, 0x7f, 0xfa, 0xac, 0x26, 0xf0, 0xb0, 0x07, 0xc8, 0x98, 0x29, 0x0f, 0xd0, 0x07, 0x60, 0x98, 0x29, 0x0f, 0xf0, 0x04, 0x88, 0x8c, 0x26, 0xf0, 0x60, 0xbd, 0x62, 0xf1, 0x49, 0xff, 0x2d, 0x25, 0xf0, 0x90, 0x03, 0x1d, 0x62, 0xf1, 0x8d, 0x25, 0xf0, 0x60, 0xbd, 0x1a, 0xf0, 0x29, 0xfb, 0x90, 0x55, 0x09, 0x04, 0xb0, 0x51, 0xbd, 0x1a, 0xf0, 0x29, 0xfd, 0x90, 0x4a, 0x09, 0x02, 0xb0, 0x46, 0xad, 0x25, 0xf0, 0x29, 0xf7, 0x90, 0x02, 0x09, 0x08, 0x8d, 0x25, 0xf0, 0x60, 0xad, 0x26, 0xf0, 0x29, 0x7f, 0x90, 0x02, 0x09, 0x80, 0x8d, 0x26, 0xf0, 0x60, 0x98, 0x8d, 0xbd, 0xf0, 0x8d, 0xdf, 0xf0, 0xc8, 0x8c, 0xe0, 0xf0, 0x2a, 0x8d, 0xc9, 0xf0, 0x60, 0x98, 0x2a, 0x9d, 0x60, 0xf0, 0x60, 0x4a, 0xb0, 0x27, 0x4a, 0xb0, 0x14, 0xd0, 0x02, 0xa9, 0x08, 0x0a, 0x0a, 0x0a, 0x0a, 0x5d, 0x1a, 0xf0, 0x29, 0xf0, 0x5d, 0x1a, 0xf0, 0x9d, 0x1a, 0xf0, 0x60, 0x0a, 0x0a, 0x0a, 0x0a, 0x4d, 0x26, 0xf0, 0x29, 0x70, 0x4d, 0x26, 0xf0, 0x8d, 0x26, 0xf0, 0x60, 0x4a, 0x90, 0x04, 0x9d, 0xc0, 0xf0, 0x60, 0xa8, 0xf0, 0x20, 0x88, 0xf0, 0x40, 0x88, 0xf0, 0x63, 0x29, 0x03, 0x9d, 0xc3, 0xf0, 0xa9, 0x00, 0x9d, 0xcd, 0xf0, 0x9d, 0xd0, 0xf0, 0x9d, 0xd3, 0xf0, 0x9d, 0xd6, 0xf0, 0x8d, 0xd9, 0xf0, 0x8d, 0xdc, 0xf0, 0x60, 0xbd, 0xb7, 0xf0, 0xf0, 0x05, 0xde, 0xb7, 0xf0, 0xf0, 0x12, 0xbd, 0x33, 0xf0, 0xdd, 0xae, 0xf0, 0xd0, 0x0b, 0xbd, 0xb1, 0xf0, 0x85, 0xfd, 0xbd, 0xb4, 0xf0, 0x85, 0xfe, 0x60, 0xa9, 0x38, 0x8d, 0x00, 0xf0, 0x60, 0xbd, 0xba, 0xf0, 0xdd, 0xa8, 0xf1, 0xf0, 0x18, 0xde, 0xba, 0xf0, 0xa8, 0x88, 0xb9, 0xf0, 0xf0, 0xf0, 0x0d, 0x85, 0xfe, 0xb9, 0xe1, 0xf0, 0x85, 0xfd, 0xb9, 0x2f, 0xf1, 0x9d, 0x33, 0xf0, 0x60, 0xa9, 0x20, 0x8d, 0x00, 0xf0, 0x60, 0xad, 0x00, 0xf0, 0x5d, 0x62, 0xf1, 0x8d, 0x00, 0xf0, 0xa9, 0x01, 0x9d, 0x30, 0xf0, 0x60, 0xad, 0x00, 0xf0, 0x29, 0x07, 0x8d, 0x81, 0xfc, 0xd0, 0x03, 0x20, 0xe9, 0xf2, 0x60, 0x00, 0xa2, 0x51, 0xa0, 0xfc, 0x8e, 0x5d, 0xf1, 0x8c, 0x5e, 0xf1, 0x20, 0xcf, 0xf1, 0xa2, 0x00, 0xa0, 0x09, 0x20, 0x00, 0xf2, 0xa9, 0x07, 0x8d, 0x00, 0xf0, 0x8d, 0x81, 0xfc, 0x60, 0x00, 0x00, 0x00, 0xa9, 0x00, 0x29, 0xff, 0xf0, 0xf6, 0x4c, 0x29, 0xf3, 0xa9, 0x07, 0x8d, 0x00, 0xf0, 0x60, 0x00, 0x20, 0x60, 0xec, 0x4c, 0x60, 0xfc, 0x20, 0x80, 0xec, 0x4c, 0x80, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, libsidplayfp-3.0.0/src/sidtune/SidTuneTools.cpp0000644000175100017510000000475615175333711015243 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) Michael Schwendt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "SidTuneTools.h" #include "SidTuneCfg.h" namespace libsidplayfp { // Return pointer to file name position in complete path. size_t SidTuneTools::fileNameWithoutPath(const char* s) { size_t last_slash_pos = -1; const size_t length = strlen(s); for (size_t pos = 0; pos < length; pos++) { #if defined(SID_FS_IS_COLON_AND_BACKSLASH_AND_SLASH) if (s[pos] == ':' || s[pos] == '\\' || s[pos] == '/') #elif defined(SID_FS_IS_COLON_AND_SLASH) if (s[pos] == ':' || s[pos] == '/') #elif defined(SID_FS_IS_SLASH) if (s[pos] == '/') #elif defined(SID_FS_IS_BACKSLASH) if (s[pos] == '\\') #elif defined(SID_FS_IS_COLON) if (s[pos] == ':') #else # error Missing file/path separator definition. #endif { last_slash_pos = pos; } } return last_slash_pos + 1; } // Return pointer to file name position in complete path. // Special version: file separator = forward slash. size_t SidTuneTools::slashedFileNameWithoutPath(const char* s) { size_t last_slash_pos = -1; const size_t length = strlen(s); for (size_t pos = 0; pos < length; pos++) { if ( s[pos] == '/' ) { last_slash_pos = pos; } } return last_slash_pos + 1; } // Return pointer to file name extension in path. // The backwards-version. const char* SidTuneTools::fileExtOfPath(const char* s) { size_t last_dot_pos = strlen(s); // assume no dot and append for (size_t pos = last_dot_pos; pos > 0; pos--) { if (s[pos-1] == '.') { last_dot_pos = pos - 1; break; } } return &s[last_dot_pos]; } } libsidplayfp-3.0.0/src/sidtune/MUS.h0000644000175100017510000000416415175333711012751 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2015 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MUS_H #define MUS_H #include #include "SidTuneBase.h" #include "sidcxx11.h" namespace libsidplayfp { class MUS final : public SidTuneBase { private: /// Needed for MUS/STR player installation. uint_least16_t musDataLen; private: bool mergeParts(buffer_t& musBuf, buffer_t& strBuf) const; void tryLoad(const buffer_t& musBuf, const buffer_t& strBuf, uint_least32_t fileOffset, uint_least32_t voice3Index, bool init); protected: MUS() {} void installPlayer(sidmemory& mem) const; void setPlayerAddress(); void acceptSidTune(const char* dataFileName, const char* infoFileName, buffer_t& buf, bool isSlashedFileName) override; public: ~MUS() override = default; static SidTuneBase* load(buffer_t& dataBuf, bool init = false); static SidTuneBase* load(buffer_t& musBuf, buffer_t& strBuf, uint_least32_t fileOffset, bool init = false); void placeSidTuneInC64mem(sidmemory& mem) override; private: // prevent copying MUS(const MUS&) = delete; MUS& operator=(MUS&) = delete; }; } #endif // MUS_H libsidplayfp-3.0.0/src/sidtune/prg.cpp0000644000175100017510000000360415175333711013426 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2015 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "prg.h" #include #include "sidplayfp/SidTuneInfo.h" #include "SidTuneTools.h" #include "stringutils.h" namespace libsidplayfp { // Format strings const char TXT_FORMAT_PRG[] = "Tape image file (PRG)"; SidTuneBase* prg::load(const char *fileName, const buffer_t& dataBuf) { const char *ext = SidTuneTools::fileExtOfPath(fileName); if ((!stringutils::equal(ext, ".prg")) && (!stringutils::equal(ext, ".c64"))) { return nullptr; } if (dataBuf.size() < 2) { throw loadError(ERR_TRUNCATED); } std::unique_ptr tune(new prg()); tune->load(); return tune.release(); } void prg::load() { info->m_formatString = TXT_FORMAT_PRG; // Automatic settings info->m_songs = 1; info->m_startSong = 1; info->m_compatibility = SidTuneInfo::COMPATIBILITY_BASIC; // Create the speed/clock setting table. convertOldStyleSpeedToTables(~0, info->m_clockSpeed); } } libsidplayfp-3.0.0/src/sidtune/sidplayer1.a650000644000175100017510000004460215175333711014527 ; Compute's Gazette sidplayer sources, disassembled with dxa ; ; C64 "Enhanced Sidplayer" by Craig Chamberlain ; Copyright 1986 COMPUTE! ; ; extracted from CGSC/00_Commodore64/MusicSys.d64/SID PLAYER.64 ; .word $e000 * = $e000 le000 le001 = * + 1 le002 = * + 2 .byt $00,$00,$00 le005 = * + 2 .byt $00,$00,$00 le008 = * + 2 .byt $00,$00,$00 le00b = * + 2 .byt $00,$00,$00 le00e = * + 2 .byt $00,$00,$00 le011 = * + 2 .byt $00,$00,$00 le014 = * + 2 .byt $00,$00,$00 le017 = * + 2 .byt $00,$00,$00 le01a = * + 2 .byt $00,$00,$00 le01b le01c = * + 1 le01d = * + 2 .byt $00,$00,$00 le020 = * + 2 .byt $00,$00,$00 le023 = * + 2 .byt $00,$00,$00 le024 le025 = * + 1 le026 = * + 2 .byt $00,$00,$00 le027 le028 = * + 1 le029 = * + 2 .byt $00,$00,$00 le02a .byt $00,$00,$00 le02d le02e = * + 1 le02f = * + 2 .byt $00,$00,$00 le030 .byt $00,$00,$00 le033 .byt $00,$00,$00 le036 .byt $00,$00,$00 le039 .byt $00,$00,$00 le03c .byt $00,$00,$00 le03f .byt $00,$00,$00 le042 .byt $00,$00,$00 le045 .byt $00,$00,$00 le048 .byt $00,$00,$00 le04b .byt $00,$00,$00 le04e .byt $00,$00,$00 le051 .byt $00,$00,$00 le054 .byt $00,$00,$00 le057 .byt $00,$00,$00 le05a .byt $00,$00,$00 le05d .byt $00,$00,$00 le060 .byt $00,$00,$00 le063 .byt $00,$00,$00 le066 .byt $00,$00,$00 le069 .byt $00,$00,$00 le06c .byt $00,$00,$00 le06f .byt $00,$00,$00 le072 .byt $00,$00,$00 le075 .byt $00,$00,$00 le078 .byt $00,$00,$00 le07b .byt $00,$00,$00 le07e .byt $00,$00,$00 le081 .byt $00,$00,$00 le084 .byt $00,$00,$00 le087 .byt $00,$00,$00 le08a .byt $00,$00,$00 le08d .byt $00,$00,$00 le090 .byt $00,$00,$00 le093 .byt $00,$00,$00 le096 .byt $00,$00,$00 le099 .byt $00,$00,$00 le09c .byt $00,$00,$00 le09f .byt $00,$00,$00 le0a2 .byt $00,$00,$00 le0a5 .byt $00,$00,$00 le0a8 .byt $00,$00,$00 le0ab .byt $00,$00,$00 le0ae .byt $00,$00,$00 le0b1 .byt $00,$00,$00 le0b4 .byt $00,$00,$00 le0b7 .byt $00,$00,$00 le0ba le0bc = * + 2 .byt $00,$00,$00 le0bd le0be = * + 1 le0bf = * + 2 .byt $00,$00,$00 le0c0 .byt $00,$00,$00 le0c3 .byt $00,$00,$00 le0c6 .byt $00,$00,$00 le0c9 le0ca = * + 1 le0cb = * + 2 .byt $00,$00,$00 le0cc le0cd = * + 1 .byt $00,$00,$00 le0d0 = * + 1 .byt $00,$00,$00 le0d3 = * + 1 .byt $00,$00,$00 le0d6 = * + 1 .byt $00,$00,$00 le0d9 = * + 1 .byt $00,$00,$00 le0dc = * + 1 .byt $00,$00,$00 le0df = * + 1 le0e0 = * + 2 .byt $00,$00,$00 le0e1 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 le0f0 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 le0ff .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 le117 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 le12f .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 le13e .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 .byt $00,$00,$00 le156 le157 = * + 1 le158 = * + 2 .byt $00,$00,$00 le159 le15a = * + 1 le15b = * + 2 .byt $00,$00,$00 le15c le15d = * + 1 le15e = * + 2 .byt $00,$00,$00 le15f le160 = * + 1 ; Instruction opcode accessed. ; Instruction parameter accessed. adc ($e1,x) rts le162 .byt $01,$02,$04 le165 le167 = * + 2 .byt $00,$07,$0e .byt $02,$02,$fe .byt $02,$02,$fe le16f = * + 1 .byt $fe,$00,$01 le172 = * + 1 .byt $00,$ff,$00 .byt $02,$04,$05 .byt $07,$09,$0b le17a .byt $1e,$18,$8b .byt $7e,$fa,$06 .byt $ac,$f3,$e6 .byt $8f,$f8,$2e le186 .byt $86,$8e,$96 .byt $9f,$a8,$b3 .byt $bd,$c8,$d4 .byt $e1,$ee,$fd le192 sty $6478 bvc le1d3 .byt $28,$14,$00 le19a .byt $00,$02,$03 .byt $05,$07,$08 .byt $0a,$0c,$0d .byt $0f,$11,$12 le1a6 le1a8 = * + 2 .byt $00,$e0,$00 le1a9 .byt $05,$0a,$0f le1ac le1ad = * + 1 .byt $f9,$00,$f5 le1af .byt $00,$00,$00 le1b2 bpl le1b4 le1b4 .byt $00 le1b5 jsr $0000 bmi le1ba le1ba .byt $00,$40,$00 .byt $00 le1be bvc le1c0 le1c0 .byt $00,$60,$00 .byt $00 le1c4 bvs le1c6 le1c6 .byt $00,$80,$00 .byt $00 le1ca bcc le1cc le1cc .byt $00 le1cd ldy #$00 le1cf lda #$00 le1d3 = * + 2 ; Instruction parameter jumped to. sta le000 le1d4 le1d5 = * + 1 ; Instruction parameter jumped to. ldx #$95 le1d6 ldy #$42 lda $02a6 beq le1e1 le1dd ldx #$25 ldy #$40 le1e1 stx le15b sty le15c nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop rts le200 lda #$00 sta le000 stx $61 sty $62 ldy #$bc le20b sta le000,y dey bne le20b le211 ldy #$72 le213 sta le0bc,y dey bne le213 le219 sta $d415 sta $d416 lda #$08 sta le025 sta $d417 sta le026 sta $d418 lda #$90 sta le027 lda #$60 sta le028 lda #$0c sta le029 lda le15b sta le02d lda le15c sta le02e lda #$ff sta le0cc lda #$d4 sta $64 ldx #$02 le253 lda #$ff sta le00b,x lda #$01 sta le030,x sta le02a,x txa sta le033,x sta le0ae,x lda #$04 sta le039,x lda le1a8,x sta le0ba,x lda #$5b sta le07e,x lda le165,x sta $63 lda #$00 tay sta ($63),y iny sta ($63),y iny sta ($63),y lda #$08 sta le017,x sta le09c,x iny sta ($63),y iny sta ($63),y lda #$40 sta le01a,x sta ($63),y lda #$20 sta le01d,x iny sta ($63),y lda #$f5 sta le020,x iny sta ($63),y dex bpl le253 le2af txa ldx #$17 le2b2 sta le13e,x dex bpl le2b2 le2b8 lda $61 clc adc #$06 sta $63 lda #$00 tax tay adc $62 le2c5 sta $64 sta le0ab,x sta le0b4,x lda $63 sta le0a8,x sta le0b1,x clc adc ($61),y sta $63 lda $64 iny adc ($61),y iny inx cpx #$03 bne le2c5 le2e5 ldx $63 tay rts le2e9 lda #$00 sta $d404 sta $d40b sta $d412 sta $d401 sta $d408 sta $d40f lda #$08 sta $d417 lda le15b sta $dc04 lda le15c sta $dc05 rts le30f nop nop nop nop nop nop nop nop nop nop nop nop nop nop rts le31e lda #$08 sta le000 le323 jmp (le15d) le326 nop nop nop le329 lda le000 bmi le31e le32e ora #$80 tay and #$07 beq le323 le335 cld sty le000 nop lda $fb sta le156 lda $fc sta le157 lda $fd sta le158 lda $fe sta le159 lda $ff sta le15a lda le023 clc adc le0d9 pha and #$07 tay lda le0dc adc #$00 sta $ff pla lsr $ff ror lsr $ff ror lsr $ff ror clc adc le024 sty $d415 sta $d416 lda le025 sta $d417 lda le026 sta $d418 lda #$d4 sta $fc ldx #$00 le38b lda le000 and le162,x beq le3e4 le393 lda le165,x sta $fb lda le00e,x clc adc le051,x tay lda le011,x adc le054,x pha tya clc adc le0cd,x ldy #$00 sta ($fb),y pla adc le0d0,x iny sta ($fb),y lda le014,x clc adc le069,x sta $ff lda le017,x adc le06c,x pha lda $ff clc adc le0d3,x iny sta ($fb),y pla adc le0d6,x iny sta ($fb),y lda le01d,x iny iny sta ($fb),y lda le020,x iny sta ($fb),y le3e4 inx cpx #$03 bne le38b le3e9 ldy le01a ldx le01b lda le01c sty $d404 stx $d40b sta $d412 ldx le02d ldy le02e stx $dc04 sty $dc05 lda $d41b sta le0be lda $d41c sta le0bf ldx #$00 le415 lda le000 and le162,x beq le42d le41d stx le02f jsr le536 lda le000 and #$78 beq le42d le42a jmp le50c le42d inx cpx #$03 bne le415 le432 lda le0c9 bne le489 le437 lda le0ca ora le0cb beq le4b7 le43f lda le0df bne le46c le444 lda le0ca beq le471 le449 clc adc le0bd bcs le456 le44f cmp le0cc bcc le4b4 le454 beq le4b4 le456 lda #$00 sta le0df lda le0cb beq le4b4 le460 inc le0df lda le0bd sbc le0cb jmp le4b4 le46c lda le0cb beq le444 le471 lda le0bd sec sbc le0cb bcs le4b4 le47a lda #$00 sta le0df lda le0ca bne le4b4 le484 inc le0df bne le4b1 le489 dec le0e0 bne le4b7 le48e lda le0df bne le4a4 le493 inc le0df lda le0cb bne le49d le49b lda #$20 le49d sta le0e0 lda #$00 beq le4b4 le4a4 dec le0df lda le0ca bne le4ae le4ac lda #$20 le4ae sta le0e0 le4b1 lda le0cc le4b4 sta le0bd le4b7 ldx #$00 le4b9 lda le0c3,x beq le502 le4be lda #$00 sta $ff ldy le0c0,x lda le0bd,y ldy le0c6,x beq le4db le4cd bmi le4d7 le4cf asl rol $ff dey bne le4cf le4d5 beq le4db le4d7 lsr iny bne le4d7 le4db ldy le0c3,x dey bne le4ec le4e1 sta le0cd,x lda $ff sta le0d0,x jmp le502 le4ec dey bne le4fa le4ef sta le0d3,x lda $ff sta le0d6,x jmp le502 le4fa sta le0d9 lda $ff sta le0dc le502 inx cpx #$03 bne le4b9 le507 lda le000 and #$7f le50c sta le000 lda le156 sta $fb lda le157 sta $fc lda le158 sta $fd lda le159 sta $fe lda le15a sta $ff jmp (le15d) le52b lda le060,x bne le533 le530 jmp le69f le533 jmp le5ba le536 dec le030,x bne le53e le53b jmp le6a0 le53e lda le036,x bmi le52b le543 bne le55f le545 lda le03f,x beq le54f le54a dec le03f,x bne le55f le54f lda le039,x cmp le030,x bcc le55f le557 lda le01a,x and #$fe sta le01a,x le55f lda le042,x beq le5ba le564 asl lda le00e,x bcs le587 le56a adc le045,x sta le00e,x tay lda le011,x adc le048,x sta le011,x pha tya cmp le08d,x pla sbc le090,x bcs le5a4 le585 bcc le5b5 le587 sbc le045,x sta le00e,x lda le011,x sbc le048,x sta le011,x lda le08d,x cmp le00e,x lda le090,x sbc le011,x bcc le5b5 le5a4 lda le08d,x sta le00e,x lda le090,x sta le011,x lda #$00 sta le042,x le5b5 lda le060,x beq le60f le5ba lda le04b,x beq le60a le5bf ldy #$00 dec le04e,x bne le5f7 le5c6 lda le051,x ora le054,x bne le5e9 le5ce lda le05d,x sta le057,x sta le04e,x lda le04b,x asl lda le05a,x bcc le5e4 le5e0 eor #$ff adc #$00 le5e4 sta le04b,x bne le5f9 le5e9 lda le057,x sta le04e,x tya sec sbc le04b,x sta le04b,x le5f7 cmp #$00 le5f9 bpl le5fc le5fb dey le5fc clc adc le051,x sta le051,x tya adc le054,x sta le054,x le60a lda le036,x bmi le624 le60f lda le093,x beq le624 le614 clc adc le014,x sta le014,x lda le096,x adc le017,x sta le017,x le624 lda le063,x beq le674 le629 ldy #$00 dec le066,x bne le661 le630 lda le069,x ora le06c,x bne le653 le638 lda le072,x sta le06f,x sta le066,x lda le063,x asl lda le075,x bcc le64e le64a eor #$ff adc #$00 le64e sta le063,x bne le663 le653 lda le06f,x sta le066,x tya sec sbc le063,x sta le063,x le661 cmp #$00 le663 bpl le666 le665 dey le666 clc adc le069,x sta le069,x tya adc le06c,x sta le06c,x le674 lda le036,x bpl le67c le679 jmp le69f le67c ldy #$00 lda le0a2,x beq le69f le683 bpl le686 le685 iny le686 clc adc le023 pha and #$07 sta le023 pla ror lsr lsr clc adc le1a6,y clc adc le024 sta le024 le69f rts le6a0 lda le0a8,x sta $fd lda le0ab,x sta $fe bne le6b0 le6ac rts le6ad jsr le898 le6b0 lda le000 and le162,x beq le6ac le6b8 ldy #$00 lda ($fd),y sta $ff iny lda ($fd),y tay lda $fd clc adc #$02 sta $fd sta le0a8,x lda $fe adc #$00 sta $fe sta le0ab,x lda $ff and #$03 bne le6ad le6db lda le08d,x sta le00e,x lda le090,x sta le011,x lda $ff sta le005,x tya sta le002,x and #$07 tay lda le167,y sta le16f lda le002,x and #$38 lsr lsr lsr adc le081,x sta $fd lda le002,x and #$c0 asl rol rol tay lda le16f,y sta $fe lda le002,x and #$07 beq le77d le71b tay lda le172,y adc $fe clc adc le084,x bpl le72c le727 clc adc #$0c inc $fd le72c cmp #$0c bcc le734 le730 sbc #$0c dec $fd le734 sta $fe tay lda le186,y sta $ff lda le17a,y ldy $fd dey bmi le74a le744 lsr $ff ror dey bpl le744 le74a clc adc le087,x sta le08d,x lda $ff adc le08a,x sta le090,x lda le005,x bne le761 le75e jmp le6a0 le761 lda le045,x ora le048,x beq le77f le769 lda le00e,x cmp le08d,x lda le011,x sbc le090,x lda #$fe ror sta le042,x bcc le78e le77d beq le7c9 le77f sta le042,x lda le08d,x sta le00e,x lda le090,x sta le011,x le78e lda le036,x asl bne le7c9 le794 lda le093,x beq le7a5 le799 lda le099,x sta le014,x lda le09c,x sta le017,x le7a5 lda le09f,x beq le7b9 le7aa ldy $fd clc adc le192,y ldy $fe clc adc le19a,y clc bcc le7c1 le7b9 lda le0a2,x beq le7c9 le7be lda le0a5,x le7c1 sta le024 lda #$00 sta le023 le7c9 lda le03c,x sta le03f,x lda le005,x and #$40 sta le036,x lda le005,x lsr lsr and #$07 bne le810 le7e0 lda le005,x bmi le7f9 le7e5 lda le027 and #$3c bne le80a le7ec lda le027 asl rol rol bne le7f6 le7f4 lda #$04 le7f6 jmp le870 le7f9 lda le028 beq le80a le7fe and #$3f bne le80a le802 lda le028 asl rol rol bne le870 le80a lda #$10 sta le000 rts le810 cmp #$01 bne le827 le814 lda le005,x and #$20 bne le821 le81b lda le029 jmp le870 le821 lda le02a,x jmp le870 le827 tay lda le005,x and #$a0 cmp #$80 beq le861 le831 sta $ff clc lda le027 bne le83a le839 sec le83a dey dey beq le844 le83e ror bcs le88f le841 dey bne le83e le844 ldy $ff sta $ff beq le870 le84a lsr $ff bcs le88f le84e beq le892 le850 adc $ff bcs le892 le854 iny bpl le870 le857 lsr $ff bcs le88f le85b adc $ff bcc le870 le85f bcs le892 le861 lda le028 beq le88f le866 dey dey beq le870 le86a lsr bcs le88f le86d dey bne le86a le870 sta le030,x lda le01a,x and #$f6 sta le01a,x sec lda le002,x and #$07 bne le886 le883 ror le036,x le886 lda le01a,x adc #$00 sta le01a,x rts le88f lda #$10 le892 = * + 1 ; Instruction parameter jumped to. bit $18a9 sta le000 rts le898 tya pha lda $ff lsr bcc le8a2 le89f jmp lea42 le8a2 lsr lsr bcs le8c4 le8a6 lsr bcs le8b7 le8a9 sta le09c,x sta le017,x pla sta le099,x sta le014,x rts le8b7 lsr bcc le8bc le8ba ora #$f8 le8bc sta le08a,x pla sta le087,x rts le8c4 lsr bcs le8ca le8c7 jmp le94a le8ca lsr bcs le92e le8cd lsr bcs le8df le8d0 bne le8da le8d2 pla sta le0a5,x sta le024 rts le8da pla sta le03c,x rts le8df bne le929 le8e1 pla sta le07e,x cmp #$5b beq le91c le8e9 tay lsr lsr lsr sec sbc #$0b clc adc le084,x bmi le902 le8f6 cmp #$0c bcc le90b le8fa sbc #$0c dec le081,x jmp le90b le902 cmp #$f5 bcs le90b le906 adc #$0c inc le081,x le90b sta le084,x tya and #$07 sec sbc #$03 clc adc le081,x sta le081,x rts le91c lda le078,x sta le081,x lda le07b,x sta le084,x rts le929 pla sta le0c6,x rts le92e lsr bcs le939 le931 sta le00b,x pla sta le008,x rts le939 lsr ror ror adc le15b sta le02d pla adc le15c sta le02e rts le94a lsr bcc le950 le94d jmp le9d3 le950 lsr bcs le993 le953 lsr bcs le96d le956 lsr bcs le968 le959 pla sta le027 lsr lsr lsr tay lda le1af,y sta le028 rts le968 pla sta le05d,x rts le96d lsr bcs le975 le970 pla sta le001 rts le975 pla beq le989 le978 sta le075,x ldy le063,x bne le988 le980 sta le063,x lda #$01 sta le066,x le988 rts le989 sta le063,x sta le069,x sta le06c,x rts le993 lsr bcs le9c6 le996 lsr bcs le99e le999 pla sta le039,x rts le99e pla ldy #$00 lsr bcc le9a6 le9a4 iny clc le9a6 pha and #$07 adc le1ac,y sta le078,x sta le081,x pla lsr lsr lsr clc adc le1ad,y sta le07b,x sta le084,x lda #$5b sta le07e,x rts le9c6 lsr bcs le9ce le9c9 pla sta le0a2,x rts le9ce pla sta le0cc rts le9d3 lsr bcs le9fd le9d6 lsr bcs le9e6 le9d9 lsr bcs le9e1 le9dc pla sta le029 rts le9e1 pla sta le09f,x rts le9e6 lsr bcs le9f8 le9e9 pla sta le093,x ldy #$00 asl bcc le9f3 le9f2 dey le9f3 tya sta le096,x rts le9f8 pla sta le072,x rts le9fd lsr bcs lea1c lea00 lsr bcs lea18 lea03 pla sta le0b7,x lda $fd sta le0b1,x lda $fe sta le0b4,x lda le033,x sta le0ae,x rts lea18 pla jmp (le15f) lea1c lsr bcs lea3d lea1f pla bne lea2c lea22 sta le04b,x sta le051,x sta le054,x rts lea2c sta le05a,x ldy le04b,x bne lea3c lea34 sta le04b,x lda #$01 sta le04e,x lea3c rts lea3d pla sta le02a,x rts lea42 lsr bcc lea4d lea45 sta le048,x pla sta le045,x rts lea4d pla lsr bcs leab2 lea51 lsr bcs lea79 lea54 lsr bcs lea5c lea57 lsr ldy #$f0 bne lea62 lea5c asl asl asl asl ldy #$0f lea62 sta $ff tya bcs lea70 lea67 and le01d,x ora $ff sta le01d,x rts lea70 and le020,x ora $ff sta le020,x rts lea79 lsr bcs leab4 lea7c lsr bcs leae3 lea7f sta $ff lda le0ba,x cmp le1a9,x beq leadd lea89 inc le0ba,x tay lda $fd sta le0e1,y lda $fe sta le0f0,y lda le033,x sta le12f,y ldy $ff lda le117,y beq leada leaa4 sta $fe lda le0ff,y sta $fd lda le13e,y sta le033,x rts leab2 bcs leaff leab4 lsr bcs leaf3 leab7 tay lda $fd sta le0ff,y lda $fe sta le117,y lda le033,x sta le13e,y lda le0ba,x cmp le1a9,x beq leadd lead0 inc le0ba,x tay lda #$00 sta le0f0,y rts leada lda #$30 leadd = * + 1 ; Instruction parameter jumped to. bit $28a9 sta le000 rts leae3 asl asl asl asl eor le025 and #$f0 eor le025 sta le025 rts leaf3 eor le026 and #$0f eor le026 sta le026 rts leaff lsr bcs leb0d leb02 lsr bcs leb09 leb05 sta le0ca rts leb09 sta le0cb rts leb0d lsr bcc leb13 leb10 jmp leba5 leb13 lsr tay beq leb38 leb17 dey beq leb4e leb1a dey beq leb5f leb1d dey beq leb6a leb20 dey beq leb75 leb23 dey beq leb82 leb26 dey beq leb8f leb29 dey beq leb9f leb2c and #$07 ora #$10 bcs leb35 leb32 jmp leab7 leb35 jmp lea7f leb38 ldy le026 bcs leb44 leb3d iny tya and #$0f bne leb4a leb43 rts leb44 tya and #$0f beq leb4d leb49 dey leb4a sty le026 leb4d rts leb4e lda le162,x eor #$ff and le025 bcc leb5b leb58 ora le162,x leb5b sta le025 rts leb5f lda le01a,x and #$fb bcc lebbb leb66 ora #$04 bcs lebbb leb6a lda le01a,x and #$fd bcc lebbb leb71 ora #$02 bcs lebbb leb75 lda le025 and #$f7 bcc leb7e leb7c ora #$08 leb7e sta le025 rts leb82 lda le026 and #$7f bcc leb8b leb89 ora #$80 leb8b sta le026 rts leb8f tya sta le0bd sta le0df iny sty le0e0 rol sta le0c9 rts leb9f tya rol sta le060,x rts leba5 lsr bcs lebcf leba8 lsr bcs lebbf lebab bne lebaf lebad lda #$08 lebaf asl asl asl asl eor le01a,x and #$f0 eor le01a,x lebbb sta le01a,x rts lebbf asl asl asl asl eor le026 and #$70 eor le026 sta le026 rts lebcf lsr bcc lebd6 lebd2 sta le0c0,x rts lebd6 tay beq lebf9 lebd9 dey beq lec1c lebdc dey beq lec42 lebdf and #$03 sta le0c3,x lda #$00 sta le0cd,x sta le0d0,x sta le0d3,x sta le0d6,x sta le0d9 sta le0dc rts lebf9 lda le0b7,x beq lec03 lebfe dec le0b7,x beq lec15 lec03 lda le033,x cmp le0ae,x bne lec16 lec0b lda le0b1,x sta $fd lda le0b4,x sta $fe lec15 rts lec16 lda #$38 sta le000 rts lec1c lda le0ba,x cmp le1a8,x beq lec3c lec24 dec le0ba,x tay dey lda le0f0,y beq lec3b lec2e sta $fe lda le0e1,y sta $fd lda le12f,y sta le033,x lec3b rts lec3c lda #$20 sta le000 rts lec42 lda le000 eor le162,x sta le000 lda #$01 sta le030,x rts lec51 lda le000 and #$07 sta lec81 bne lec5e lec5b jsr le2e9 lec5e rts .byt $00 lec60 ldx #$51 ldy #$ec stx le15d sty le15e jsr le1cf ldx #$00 ldy #$09 jsr le200 lda #$07 sta le000 sta lec81 lec7c rts .byt $00,$00,$00 lec80 lec81 = * + 1 ; Instruction parameter accessed. lda #$00 and #$ff beq lec7c lec86 jmp le329 lec89 lda #$07 sta le000 rts libsidplayfp-3.0.0/src/stringutils.h0000644000175100017510000000561315175333711013221 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2013-2023 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef STRINGUTILS_H #define STRINGUTILS_H #ifdef HAVE_CONFIG_H # include "config.h" #endif #if defined(_WIN32) # include #elif defined(HAVE_STRCASECMP) || defined (HAVE_STRNCASECMP) # include #endif #include #include #include namespace stringutils { /** * Compare two characters in a case insensitive way. */ inline bool casecompare(char c1, char c2) { return (tolower(c1) == tolower(c2)); } /** * Compare two strings in a case insensitive way. * * @return true if strings are equal. */ inline bool equal(const std::string& s1, const std::string& s2) { return s1.size() == s2.size() && std::equal(s1.begin(), s1.end(), s2.begin(), casecompare); } /** * Compare two strings in a case insensitive way. * * @return true if strings are equal. */ inline bool equal(const char* s1, const char* s2) { #if defined(_WIN32) return _stricmp(s1, s2) == 0; #elif defined(HAVE_STRCASECMP) return strcasecmp(s1, s2) == 0; #else if (s1 == s2) return true; if (s1 == 0 || s2 == 0) return false; while ((*s1 != '\0') || (*s2 != '\0')) { if (!casecompare(*s1, *s2)) return false; ++s1; ++s2; } return true; #endif } /** * Compare first n characters of two strings in a case insensitive way. * * @return true if strings are equal. */ inline bool equal(const char* s1, const char* s2, size_t n) { #if defined(_WIN32) return _strnicmp(s1, s2, n) == 0; #elif defined(HAVE_STRNCASECMP) return strncasecmp(s1, s2, n) == 0; #else if (s1 == s2 || n == 0) return true; if (s1 == 0 || s2 == 0) return false; while (n-- && ((*s1 != '\0') || (*s2 != '\0'))) { if (!casecompare(*s1, *s2)) return false; ++s1; ++s2; } return true; #endif } } #endif libsidplayfp-3.0.0/src/utils/0000755000175100017510000000000015175333725011701 5libsidplayfp-3.0.0/src/utils/SidDatabase.h0000644000175100017510000000554015175333711014135 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2020 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDDATABASE_H #define SIDDATABASE_H #include #include "sidplayfp/siddefs.h" class SidTune; namespace libsidplayfp { class iniParser; } /** * SidDatabase * An utility class to deal with the songlength DataBase. */ class SID_EXTERN SidDatabase { private: libsidplayfp::iniParser* m_parser; const char *errorString; public: SidDatabase(); ~SidDatabase(); /** * Open the songlength DataBase. * * @param filename songlengthDB file name with full path. * @return false in case of errors, true otherwise. */ bool open(const char *filename); #ifdef _WIN32 bool open(const wchar_t* filename); #endif /** * Close the songlength DataBase. */ void close(); /** * Get the length of the current subtune. * The hash is obtained with a specific MD5 calculation (old format). * * @param tune the SID tune * @return tune length in seconds, -1 in case of errors. */ int_least32_t length(SidTune &tune); /** * Get the length of the selected subtune. * * @param md5 the md5 hash of the tune. * @param song the subtune. * @return tune length in seconds, -1 in case of errors. */ int_least32_t length(const char *md5, unsigned int song); /** * Get the length of the current subtune. * The hash is based on the full content (new format). * * @param tune the SID tune * @return tune length in milliseconds, -1 in case of errors. */ int_least32_t lengthMs(SidTune &tune); /** * Get the length of the selected subtune. * * @param md5 the md5 hash of the tune. * @param song the subtune. * @return tune length in milliseconds, -1 in case of errors. */ int_least32_t lengthMs(const char *md5, unsigned int song); /** * Get descriptive error message. */ const char *error() const { return errorString; } }; #endif // SIDDATABASE_H libsidplayfp-3.0.0/src/utils/STILview/0000755000175100017510000000000015175333725013347 5libsidplayfp-3.0.0/src/utils/STILview/stil.h0000644000175100017510000003512615175333711014415 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 1998, 2002 by LaLa * Copyright 2012-2013 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef STIL_H #define STIL_H #include #include #include #include #include "stildefs.h" /** * STIL class * * @author LaLa * @copyright 1998, 2002 by LaLa * * * Given the location of HVSC this class can extract STIL information for a * given tune of a given SID file. (Sounds simple, huh?) * * PLEASE, READ THE ACCOMPANYING README.TXT FILE BEFORE PROCEEDING!!!! */ class STIL_EXTERN STIL { public: /// Enum to use for asking for specific fields. enum STILField { all, name, author, title, artist, comment }; /// Enum that describes the possible errors this class may encounter. enum STILerror { NO_STIL_ERROR = 0, BUG_OPEN, ///< INFO ONLY: failed to open BUGlist.txt. WRONG_DIR, ///< INFO ONLY: path was not within HVSC base dir. NOT_IN_STIL, ///< INFO ONLY: requested entry was not found in STIL.txt. NOT_IN_BUG, ///< INFO ONLY: requested entry was not found in BUGlist.txt. WRONG_ENTRY, ///< INFO ONLY: section-global comment was asked for with get*Entry(). CRITICAL_STIL_ERROR = 10, BASE_DIR_LENGTH, ///< The length of the HVSC base dir was wrong (empty string?) STIL_OPEN, ///< Failed to open STIL.txt. NO_EOL, ///< Failed to determine EOL char(s). NO_STIL_DIRS, ///< Failed to get sections (subdirs) when parsing STIL.txt. NO_BUG_DIRS ///< Failed to get sections (subdirs) when parsing BUGlist.txt. }; /// To turn debug output on bool STIL_DEBUG; //----// /** * Allocates necessary memory. * * @param stilPath relative path to STIL file * @param bugsPath relative path to BUG file */ STIL(const char *stilPath = DEFAULT_PATH_TO_STIL, const char *bugsPath = DEFAULT_PATH_TO_BUGLIST); /** * Returns a formatted string telling what the version * number is for the STIL class and other info. * If it is called after setBaseDir(), the string also * has the STIL.txt file's version number in it. * * @return * printable formatted string with version and copyright * info * (It's kinda dangerous to return a pointer that points * to an internal structure, but I trust you. :) */ const char *getVersion(); /** * Returns a floating number telling what the version * number is of this STIL class. * * @return * version number */ float getVersionNo(); /** * Tell the object where the HVSC base directory is - it * figures that the STIL should be in /DOCUMENTS/STIL.txt * and that the BUGlist should be in /DOCUMENTS/BUGlist.txt. * It should not matter whether the path is given in UNIX, * WinDOS, or Mac format (ie. '\' vs. '/' vs. ':') * * @param pathToHVSC = HVSC base directory in your machine's format * @return * - false - Problem opening or parsing STIL/BUGlist * - true - All okay */ bool setBaseDir(const char *pathToHVSC); /** * Returns a floating number telling what the version * number is of the STIL.txt file. * To be called only after setBaseDir()! * * @return * version number (0.0 if setBaseDir() was not called, yet) */ float getSTILVersionNo(); /** * Given an HVSC pathname, a tune number and a * field designation, it returns a formatted string that * contains the STIL field for the tune number (if exists). * If it doesn't exist, returns a NULL. * * @param relPathToEntry = relative to the HVSC base dir, starting with * a slash * @param tuneNo = song number within the song (default=0). * @param field = which field to retrieve (default=all). * * What the possible combinations of tuneNo and field represent: * * - tuneNo = 0, field = all : all of the STIL entry is returned. * - tuneNo = 0, field = comment : the file-global comment is returned. * (For single-tune entries, this returns nothing!) * - tuneNo = 0, field = : INVALID! (NULL is returned) * - tuneNo != 0, field = all : all fields of the STIL entry for the * given tune number are returned. (For single-tune entries, this is * equivalent to saying tuneNo = 0, field = all.) * However, the file-global comment is *NOT* returned with it any * more! (Unlike in versions before v2.00.) It led to confusions: * eg. when a comment was asked for tune #3, it returned the * file-global comment even if there was no specific entry for tune #3! * - tuneNo != 0, field = : the specific field of the specific * tune number is returned. If the tune number doesn't exist (eg. if * tuneNo=2 for single-tune entries, or if tuneNo=2 when there's no * STIL entry for tune #2 in a multitune entry), returns NULL. * * NOTE: For older versions of STIL (older than v2.59) the tuneNo and * field parameters are ignored and are assumed to be tuneNo=0 and * field=all to maintain backwards compatibility. * * @return * - pointer to a printable formatted string containing * the STIL entry * (It's kinda dangerous to return a pointer that points * to an internal structure, but I trust you. :) * - NULL if there's absolutely no STIL entry for the tune */ const char *getEntry(const char *relPathToEntry, int tuneNo = 0, STILField field = all); /** * Same as #getEntry, but with an absolute path given * given in your machine's format. */ const char *getAbsEntry(const char *absPathToEntry, int tuneNo = 0, STILField field = all); /** * Given an HVSC pathname and tune number it returns a * formatted string that contains the section-global * comment for the tune number (if it exists). If it * doesn't exist, returns a NULL. * * @param relPathToEntry = relative to the HVSC base dir starting with * a slash * @return * - pointer to a printable formatted string containing * the section-global comment * (It's kinda dangerous to return a pointer that points * to an internal structure, but I trust you. :) * - NULL if there's absolutely no section-global comment * for the tune */ const char *getGlobalComment(const char *relPathToEntry); /** * Same as #getGlobalComment, but with an absolute path * given in your machine's format. */ const char *getAbsGlobalComment(const char *absPathToEntry); /** * Given an HVSC pathname and tune number it returns a * formatted string that contains the BUG entry for the * tune number (if exists). If it doesn't exist, returns * a NULL. * * @param relPathToEntry = relative to the HVSC base dir starting with * a slash * @param tuneNo = song number within the song (default=0) * If tuneNo=0, returns all of the BUG entry. * * NOTE: For older versions of STIL (older than v2.59) tuneNo is * ignored and is assumed to be 0 to maintain backwards * compatibility. * * @return * - pointer to a printable formatted string containing * the BUG entry * (It's kinda dangerous to return a pointer that points * to an internal structure, but I trust you. :) * - NULL if there's absolutely no BUG entry for the tune */ const char *getBug(const char *relPathToEntry, int tuneNo = 0); /** * Same as #getBug, but with an absolute path * given in your machine's format. */ const char *getAbsBug(const char *absPathToEntry, int tuneNo = 0); /** * Returns a specific error number identifying the problem * that happened at the last invoked public method. * * @return * STILerror - an enumerated error value */ inline STILerror getError() const {return (lastError);} /** * Returns true if the last error encountered was critical * (ie. not one that the STIL class can recover from). * * @return * true if the last error encountered was critical */ inline bool hasCriticalError() const { return ((lastError >= CRITICAL_STIL_ERROR) ? true : false); } /** * Returns an ASCII error string containing the * description of the error that happened at the last * invoked public method. * * @return * pointer to string with the error description */ inline const char *getErrorStr() const {return (STIL_ERROR_STR[lastError]);} private: typedef std::map dirList; /// Path to STIL. const char *PATH_TO_STIL; /// Path to BUGlist. const char *PATH_TO_BUGLIST; /// Version number/copyright string std::string versionString; /// STIL.txt's version number float STILVersion; /// Base dir std::string baseDir; /// Maps of sections (subdirs) for easier positioning. //@{ dirList stilDirs; dirList bugDirs; //@} /** * This tells us what the line delimiter is in STIL.txt. * (It may be two chars!) */ char STIL_EOL; char STIL_EOL2; /// Error number of the last error that happened. STILerror lastError; /// Error strings containing the description of the possible errors in STIL. static const char *STIL_ERROR_STR[]; //////////////// /// The last retrieved entry std::string entrybuf; /// The last retrieved section-global comment std::string globalbuf; /// The last retrieved BUGentry std::string bugbuf; /// Buffers to hold the resulting strings std::string resultEntry; std::string resultBug; //////////////// void setVersionString(); /** * Determines what the EOL char is (or are) from STIL.txt. * It is assumed that BUGlist.txt will use the same EOL. * * @return * - false - something went wrong * - true - everything is okay */ bool determineEOL(std::ifstream &stilFile); /** * Populates the given dirList array with the directories * obtained from 'inFile' for faster positioning within * 'inFile'. * * @param inFile - where to read the directories from * @param dirs - the dirList array that should be populated with the * directory list * @param isSTILFile - is this the STIL or the BUGlist we are parsing * @return * - false - No entries were found or otherwise failed to process * inFile * - true - everything is okay */ bool getDirs(std::ifstream &inFile, dirList &dirs, bool isSTILFile); /** * Positions the file pointer to the given entry in 'inFile' * using the 'dirs' dirList for faster positioning. * * @param entryStr - the entry to position to * @param inFile - position the file pointer in this file * @param dirs - the list of dirs in inFile for easier positioning * @return * - true - if successful * - false - otherwise */ bool positionToEntry(const char *entryStr, std::ifstream &inFile, dirList &dirs); /** * Reads the entry from 'inFile' into 'buffer'. 'inFile' should * already be positioned to the entry to be read. * * @param inFile - filehandle of file to read from * @param entryStr - the entry needed to be read * @param buffer - where to put the result to */ void readEntry(std::ifstream &inFile, std::string &buffer); /** * Given a STIL formatted entry in 'buffer', a tune number, * and a field designation, it returns the requested * STIL field into 'result'. * If field=all, it also puts the file-global comment (if it exists) * as the first field into 'result'. * * @param result - where to put the resulting string to (if any) * @param buffer - pointer to the first char of what to search for * the field. Should be a buffer in standard STIL * format. * @param tuneNo - song number within the song (default=0) * @param field - which field to retrieve (default=all). * @return * - false - if nothing was put into 'result' * - true - 'result' has the resulting field */ bool getField(std::string &result, const char *buffer, int tuneNo = 0, STILField field = all) const; /** * @param result - where to put the resulting string to (if any) * @param start - pointer to the first char of what to search for * the field. Should be a buffer in standard STIL * format. * @param end - pointer to the last+1 char of what to search for * the field. ('end-1' should be a '\n'!) * @param field - which specific field to retrieve * @return * - false - if nothing was put into 'result' * - true - 'result' has the resulting field */ bool getOneField(std::string &result, const char *start, const char *end, STILField field) const; /** * Extracts one line from 'infile' to 'line[]'. The end of * the line is marked by endOfLineChar. Also eats up * additional EOL-like chars. * * @param infile - filehandle (streampos should already be positioned * to the start of the desired line) * @param line - char array to put the line into */ void getStilLine(std::ifstream &infile, std::string &line); }; #endif // STIL_H libsidplayfp-3.0.0/src/utils/STILview/stildefs.h0000644000175100017510000000445615175333711015261 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 1998, 2002 by LaLa * Copyright 2012-2015 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // // STIL - Common defines // #ifndef STILDEFS_H #define STILDEFS_H /* DLL building support on win32 hosts */ #ifndef STIL_EXTERN # ifdef DLL_EXPORT /* defined by libtool (if required) */ # define STIL_EXTERN __declspec(dllexport) # endif # ifdef STIL_DLL_IMPORT /* define if linking with this dll */ # define STIL_EXTERN __declspec(dllimport) # endif # ifndef STIL_EXTERN /* static linking or !_WIN32 */ # if defined(__GNUC__) && (__GNUC__ >= 4) # define STIL_EXTERN __attribute__ ((visibility("default"))) # else # define STIL_EXTERN # endif # endif #endif /* Deprecated attributes */ #if defined(_MSCVER) # define STIL_DEPRECATED __declspec(deprecated) #elif defined(__GNUC__) # define STIL_DEPRECATED __attribute__ ((deprecated)) #else # define STIL_DEPRECATED #endif // // Here you should define: // - what the pathname separator is on your system (attempted to be defined // automatically), // - what function compares strings case-insensitively, // - what function compares portions of strings case-insensitively. // // https://sourceforge.net/p/predef/wiki/OperatingSystems/ #if defined(_WIN32) # define SLASH '\\' #else // UNIX # define SLASH '/' #endif // Default HVSC path to STIL. const char DEFAULT_PATH_TO_STIL[]="/DOCUMENTS/STIL.txt"; // Default HVSC path to BUGlist. const char DEFAULT_PATH_TO_BUGLIST[]="/DOCUMENTS/BUGlist.txt"; #endif // STILDEFS_H libsidplayfp-3.0.0/src/utils/STILview/stil.cpp0000644000175100017510000010132315175333711014741 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 1998, 2002 by LaLa * Copyright 2012-2015 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // // STIL class - Implementation file // // AUTHOR: LaLa // Email : LaLa@C64.org // Copyright (C) 1998, 2002 by LaLa // #include "stil.h" #include #include #include // For snprintf() and NULL #include #include #include #include #include #include "stringutils.h" using namespace std; const ios_base::openmode STILopenFlags = ios::in | ios::binary; constexpr float VERSION_NO = 3.0f; #define CERR_STIL_DEBUG if (STIL_DEBUG) cerr << "Line #" << __LINE__ << " STIL::" // These are the hardcoded STIL/BUG field names. const char _NAME_STR[] = " NAME: "; const char _AUTHOR_STR[] = " AUTHOR: "; const char _TITLE_STR[] = " TITLE: "; const char _ARTIST_STR[] = " ARTIST: "; const char _COMMENT_STR[] = "COMMENT: "; //const char _BUG_STR[] = "BUG: "; const char *STIL::STIL_ERROR_STR[] = { "No error.", "Failed to open BUGlist.txt.", "Base dir path is not the HVSC base dir path.", "The entry was not found in STIL.txt.", "The entry was not found in BUGlist.txt.", "A section-global comment was asked for in the wrong way.", "", "", "", "", "CRITICAL ERROR", "Incorrect HVSC base dir length!", "Failed to open STIL.txt!", "Failed to determine EOL from STIL.txt!", "No STIL sections were found in STIL.txt!", "No STIL sections were found in BUGlist.txt!" }; /** * Converts slashes to the one the OS uses to access files. * * @param * str - what to convert */ void convertSlashes(std::string &str) { std::replace(str.begin(), str.end(), '/', SLASH); } /** * Converts OS specific dir separators to slashes. * * @param * str - what to convert */ void convertToSlashes(std::string &str) { std::replace(str.begin(), str.end(), SLASH, '/'); } // CONSTRUCTOR STIL::STIL(const char *stilPath, const char *bugsPath) : STIL_DEBUG(false), PATH_TO_STIL(stilPath), PATH_TO_BUGLIST(bugsPath), STILVersion(0.0f), STIL_EOL('\n'), STIL_EOL2('\0'), lastError(NO_STIL_ERROR) { setVersionString(); } void STIL::setVersionString() { ostringstream ss; ss << fixed << setw(4) << setprecision(2); ss << "STILView v" << VERSION_NO << endl; ss << "\tCopyright (C) 1998, 2002 by LaLa (LaLa@C64.org)" << endl; ss << "\tCopyright (C) 2012-2015 by Leandro Nini " << endl; versionString = ss.str(); } const char * STIL::getVersion() { lastError = NO_STIL_ERROR; return versionString.c_str(); } float STIL::getVersionNo() { lastError = NO_STIL_ERROR; return VERSION_NO; } float STIL::getSTILVersionNo() { lastError = NO_STIL_ERROR; return STILVersion; } bool STIL::setBaseDir(const char *pathToHVSC) { // Temporary placeholder for STIL.txt's version number. const float tempSTILVersion = STILVersion; // Temporary placeholders for lists of sections. dirList tempStilDirs; dirList tempBugDirs; lastError = NO_STIL_ERROR; CERR_STIL_DEBUG << "setBaseDir() called, pathToHVSC=" << pathToHVSC << endl; string tempBaseDir(pathToHVSC); // Sanity check the length. if (tempBaseDir.empty()) { CERR_STIL_DEBUG << "setBaseDir() has problem with the size of pathToHVSC" << endl; lastError = BASE_DIR_LENGTH; return false; } // Chop the trailing slash const string::iterator lastChar = tempBaseDir.end() - 1; if (*lastChar == SLASH) { tempBaseDir.erase(lastChar); } // Attempt to open STIL // Create the full path+filename string tempName = tempBaseDir; tempName.append(PATH_TO_STIL); convertSlashes(tempName); ifstream stilFile(tempName.c_str(), STILopenFlags); if (stilFile.fail()) { CERR_STIL_DEBUG << "setBaseDir() open failed for " << tempName << endl; lastError = STIL_OPEN; return false; } CERR_STIL_DEBUG << "setBaseDir(): open succeeded for " << tempName << endl; // Attempt to open BUGlist // Create the full path+filename tempName = tempBaseDir; tempName.append(PATH_TO_BUGLIST); convertSlashes(tempName); ifstream bugFile(tempName.c_str(), STILopenFlags); if (bugFile.fail()) { // This is not a critical error - some earlier versions of HVSC did // not have a BUGlist.txt file at all. CERR_STIL_DEBUG << "setBaseDir() open failed for " << tempName << endl; lastError = BUG_OPEN; } else { CERR_STIL_DEBUG << "setBaseDir(): open succeeded for " << tempName << endl; } // Find out what the EOL really is if (determineEOL(stilFile) != true) { CERR_STIL_DEBUG << "determinEOL() failed" << endl; lastError = NO_EOL; return false; } // Save away the current string so we can restore it if needed. const string tempVersionString(versionString); setVersionString(); // This is necessary so the version number gets scanned in from the new // file, too. STILVersion = 0.0; // These will populate the tempStilDirs and tempBugDirs maps (or not :) if (getDirs(stilFile, tempStilDirs, true) != true) { CERR_STIL_DEBUG << "getDirs() failed for stilFile" << endl; lastError = NO_STIL_DIRS; // Clean up and restore things. STILVersion = tempSTILVersion; versionString = tempVersionString; return false; } if (bugFile.good()) { if (getDirs(bugFile, tempBugDirs, false) != true) { // This is not a critical error - it is possible that the // BUGlist.txt file has no entries in it at all (in fact, that's // good!). CERR_STIL_DEBUG << "getDirs() failed for bugFile" << endl; lastError = BUG_OPEN; } } // Now we can copy the stuff into private data. // NOTE: At this point, STILVersion and the versionString should contain // the new info! // Copy. baseDir = tempBaseDir; stilDirs = tempStilDirs; bugDirs = tempBugDirs; // Clear the buffers (caches). entrybuf.clear(); globalbuf.clear(); bugbuf.clear(); CERR_STIL_DEBUG << "setBaseDir() succeeded" << endl; return true; } const char * STIL::getAbsEntry(const char *absPathToEntry, int tuneNo, STILField field) { lastError = NO_STIL_ERROR; CERR_STIL_DEBUG << "getAbsEntry() called, absPathToEntry=" << absPathToEntry << endl; if (baseDir.empty()) { CERR_STIL_DEBUG << "HVSC baseDir is not yet set!" << endl; lastError = STIL_OPEN; return nullptr; } // Determine if the baseDir is in the given pathname. if (!stringutils::equal(absPathToEntry, baseDir.data(), baseDir.size())) { CERR_STIL_DEBUG << "getAbsEntry() failed: baseDir=" << baseDir << ", absPath=" << absPathToEntry << endl; lastError = WRONG_DIR; return nullptr; } string tempDir(absPathToEntry + baseDir.size()); convertToSlashes(tempDir); return getEntry(tempDir.c_str(), tuneNo, field); } const char * STIL::getEntry(const char *relPathToEntry, int tuneNo, STILField field) { lastError = NO_STIL_ERROR; CERR_STIL_DEBUG << "getEntry() called, relPath=" << relPathToEntry << ", rest=" << tuneNo << "," << field << endl; if (baseDir.empty()) { CERR_STIL_DEBUG << "HVSC baseDir is not yet set!" << endl; lastError = STIL_OPEN; return nullptr; } const size_t relPathToEntryLen = strlen(relPathToEntry); // Fail if a section-global comment was asked for. if (*(relPathToEntry + relPathToEntryLen - 1) == '/') { CERR_STIL_DEBUG << "getEntry() section-global comment was asked for - failed" << endl; lastError = WRONG_ENTRY; return nullptr; } if (STILVersion < 2.59f) { // Older version of STIL is detected. tuneNo = 0; field = all; } // Find out whether we have this entry in the buffer. if ((!stringutils::equal(entrybuf.data(), relPathToEntry, relPathToEntryLen)) || ((entrybuf.find_first_of('\n') != relPathToEntryLen) && (STILVersion > 2.59f))) { // The relative pathnames don't match or they're not the same length: // we don't have it in the buffer, so pull it in. CERR_STIL_DEBUG << "getEntry(): entry not in buffer" << endl; // Create the full path+filename string tempName(baseDir); tempName.append(PATH_TO_STIL); convertSlashes(tempName); ifstream stilFile(tempName.c_str(), STILopenFlags); if (stilFile.fail()) { CERR_STIL_DEBUG << "getEntry() open failed for stilFile" << endl; lastError = STIL_OPEN; return nullptr; } CERR_STIL_DEBUG << "getEntry() open succeeded for stilFile" << endl; if (positionToEntry(relPathToEntry, stilFile, stilDirs) == false) { // Copy the entry's name to the buffer. entrybuf.assign(relPathToEntry).append("\n"); CERR_STIL_DEBUG << "getEntry() posToEntry() failed" << endl; lastError = NOT_IN_STIL; } else { entrybuf.clear(); readEntry(stilFile, entrybuf); CERR_STIL_DEBUG << "getEntry() entry read" << endl; } } // Put the requested field into the result string. return getField(resultEntry, entrybuf.c_str(), tuneNo, field) ? resultEntry.c_str() : nullptr; } const char * STIL::getAbsBug(const char *absPathToEntry, int tuneNo) { lastError = NO_STIL_ERROR; CERR_STIL_DEBUG << "getAbsBug() called, absPathToEntry=" << absPathToEntry << endl; if (baseDir.empty()) { CERR_STIL_DEBUG << "HVSC baseDir is not yet set!" << endl; lastError = BUG_OPEN; return nullptr; } // Determine if the baseDir is in the given pathname. if (!stringutils::equal(absPathToEntry, baseDir.data(), baseDir.size())) { CERR_STIL_DEBUG << "getAbsBug() failed: baseDir=" << baseDir << ", absPath=" << absPathToEntry << endl; lastError = WRONG_DIR; return nullptr; } string tempDir(absPathToEntry + baseDir.size()); convertToSlashes(tempDir); return getBug(tempDir.c_str(), tuneNo); } const char * STIL::getBug(const char *relPathToEntry, int tuneNo) { lastError = NO_STIL_ERROR; CERR_STIL_DEBUG << "getBug() called, relPath=" << relPathToEntry << ", rest=" << tuneNo << endl; if (baseDir.empty()) { CERR_STIL_DEBUG << "HVSC baseDir is not yet set!" << endl; lastError = BUG_OPEN; return nullptr; } // Older version of STIL is detected. if (STILVersion < 2.59f) { tuneNo = 0; } // Find out whether we have this bug entry in the buffer. // If the baseDir was changed, we'll have to read it in again, // even if it might be in the buffer already. const size_t relPathToEntryLen = strlen(relPathToEntry); if ((!stringutils::equal(bugbuf.data(), relPathToEntry, relPathToEntryLen)) || ((bugbuf.find_first_of('\n') != relPathToEntryLen) && (STILVersion > 2.59f))) { // The relative pathnames don't match or they're not the same length: // we don't have it in the buffer, so pull it in. CERR_STIL_DEBUG << "getBug(): entry not in buffer" << endl; // Create the full path+filename string tempName(baseDir); tempName.append(PATH_TO_BUGLIST); convertSlashes(tempName); ifstream bugFile(tempName.c_str(), STILopenFlags); if (bugFile.fail()) { CERR_STIL_DEBUG << "getBug() open failed for bugFile" << endl; lastError = BUG_OPEN; return nullptr; } CERR_STIL_DEBUG << "getBug() open succeeded for bugFile" << endl; if (positionToEntry(relPathToEntry, bugFile, bugDirs) == false) { // Copy the entry's name to the buffer. bugbuf.assign(relPathToEntry).append("\n"); CERR_STIL_DEBUG << "getBug() posToEntry() failed" << endl; lastError = NOT_IN_BUG; } else { bugbuf.clear(); readEntry(bugFile, bugbuf); CERR_STIL_DEBUG << "getBug() entry read" << endl; } } // Put the requested field into the result string. return getField(resultBug, bugbuf.c_str(), tuneNo) ? resultBug.c_str() : nullptr; } const char * STIL::getAbsGlobalComment(const char *absPathToEntry) { lastError = NO_STIL_ERROR; CERR_STIL_DEBUG << "getAbsGC() called, absPathToEntry=" << absPathToEntry << endl; if (baseDir.empty()) { CERR_STIL_DEBUG << "HVSC baseDir is not yet set!" << endl; lastError = STIL_OPEN; return nullptr; } // Determine if the baseDir is in the given pathname. if (!stringutils::equal(absPathToEntry, baseDir.data(), baseDir.size())) { CERR_STIL_DEBUG << "getAbsGC() failed: baseDir=" << baseDir << ", absPath=" << absPathToEntry << endl; lastError = WRONG_DIR; return nullptr; } string tempDir(absPathToEntry + baseDir.size()); convertToSlashes(tempDir); return getGlobalComment(tempDir.c_str()); } const char * STIL::getGlobalComment(const char *relPathToEntry) { lastError = NO_STIL_ERROR; CERR_STIL_DEBUG << "getGC() called, relPath=" << relPathToEntry << endl; if (baseDir.empty()) { CERR_STIL_DEBUG << "HVSC baseDir is not yet set!" << endl; lastError = STIL_OPEN; return nullptr; } // Save the dirpath. const char *lastSlash = strrchr(relPathToEntry, '/'); if (lastSlash == nullptr) { lastError = WRONG_DIR; return nullptr; } const size_t pathLen = lastSlash - relPathToEntry + 1; const string dir(relPathToEntry, pathLen); // Find out whether we have this global comment in the buffer. // If the baseDir was changed, we'll have to read it in again, // even if it might be in the buffer already. if ((!stringutils::equal(globalbuf.data(), dir.data(), pathLen)) || ((globalbuf.find_first_of('\n') != pathLen) && (STILVersion > 2.59f))) { // The relative pathnames don't match or they're not the same length: // we don't have it in the buffer, so pull it in. CERR_STIL_DEBUG << "getGC(): entry not in buffer" << endl; // Create the full path+filename string tempName(baseDir); tempName.append(PATH_TO_STIL); convertSlashes(tempName); ifstream stilFile(tempName.c_str(), STILopenFlags); if (stilFile.fail()) { CERR_STIL_DEBUG << "getGC() open failed for stilFile" << endl; lastError = STIL_OPEN; return nullptr; } if (positionToEntry(dir.c_str(), stilFile, stilDirs) == false) { // Copy the dirname to the buffer. globalbuf.assign(dir).append("\n"); CERR_STIL_DEBUG << "getGC() posToEntry() failed" << endl; lastError = NOT_IN_STIL; } else { globalbuf.clear(); readEntry(stilFile, globalbuf); CERR_STIL_DEBUG << "getGC() entry read" << endl; } } CERR_STIL_DEBUG << "getGC() globalbuf=" << globalbuf << endl; CERR_STIL_DEBUG << "-=END=-" << endl; // Position pointer to the global comment field. const size_t temp = globalbuf.find_first_of('\n') + 1; // Check whether this is a NULL entry or not. return temp != globalbuf.size() ? globalbuf.c_str() + temp : nullptr; } //////// PRIVATE bool STIL::determineEOL(ifstream &stilFile) { CERR_STIL_DEBUG << "detEOL() called" << endl; if (stilFile.fail()) { CERR_STIL_DEBUG << "detEOL() open failed" << endl; return false; } stilFile.seekg(0); STIL_EOL = '\0'; STIL_EOL2 = '\0'; // Determine what the EOL character is // (it can be different from OS to OS). istream::sentry se(stilFile, true); if (se) { streambuf *sb = stilFile.rdbuf(); const int eof = char_traits::eof(); while (sb->sgetc() != eof) { const int c = sb->sbumpc(); if ((c == '\n') || (c == '\r')) { STIL_EOL = c; if (c == '\r') { if (sb->sgetc() == '\n') STIL_EOL2 = '\n'; } break; } } } if (STIL_EOL == '\0') { // Something is wrong - no EOL-like char was found. CERR_STIL_DEBUG << "detEOL() no EOL found" << endl; return false; } CERR_STIL_DEBUG << "detEOL() EOL1=0x" << hex << static_cast(STIL_EOL) << " EOL2=0x" << hex << static_cast(STIL_EOL2) << dec << endl; return true; } bool STIL::getDirs(ifstream &inFile, dirList &dirs, bool isSTILFile) { bool newDir = !isSTILFile; CERR_STIL_DEBUG << "getDirs() called" << endl; inFile.seekg(0); while (inFile.good()) { string line; getStilLine(inFile, line); if (!isSTILFile) { CERR_STIL_DEBUG << line << '\n'; } // Try to extract STIL's version number if it's not done, yet. if (isSTILFile && (STILVersion == 0.0f)) { if (strncmp(line.data(), "# STIL v", 9) == 0) { // Get the version number STILVersion = atof(line.c_str() + 9); // Put it into the string, too. ostringstream ss; ss << fixed << setw(4) << setprecision(2); ss << "SID Tune Information List (STIL) v" << STILVersion << endl; versionString.append(ss.str()); CERR_STIL_DEBUG << "getDirs() STILVersion=" << STILVersion << endl; continue; } } // Search for the start of a dir separator first. if (isSTILFile && !newDir && stringutils::equal(line.data(), "### ", 4)) { newDir = true; continue; } // Is this the start of an entry immediately following a dir separator? if (newDir && (line[0] == '/')) { // Get the directory only const string dirName(line, 0, line.find_last_of('/') + 1); if (!isSTILFile) { // Compare it to the stored dirnames newDir = (dirs.count(dirName) == 0); } // Store the info if (newDir) { const streampos position = inFile.tellg() - (streampos)line.size() - 1L; CERR_STIL_DEBUG << "getDirs() dirName=" << dirName << ", pos=" << position << endl; dirs.insert(make_pair(dirName, position)); } newDir = !isSTILFile; } } if (dirs.empty()) { // No entries found - something is wrong. // NOTE: It's perfectly valid to have a BUGlist.txt file with no // entries in it! CERR_STIL_DEBUG << "getDirs() no dirs found" << endl; return false; } CERR_STIL_DEBUG << "getDirs() successful" << endl; return true; } bool STIL::positionToEntry(const char *entryStr, ifstream &inFile, dirList &dirs) { CERR_STIL_DEBUG << "pos2Entry() called, entryStr=" << entryStr << endl; inFile.seekg(0); // Get the dirpath. char *chrptr = strrchr((char *)entryStr, '/'); // If no slash was found, something is screwed up in the entryStr. if (chrptr == nullptr) { return false; } const size_t pathLen = chrptr - entryStr + 1; // Determine whether a section-global comment is asked for. const size_t entryStrLen = strlen(entryStr); const bool globComm = (pathLen == entryStrLen); // Find it in the table. const string entry(entryStr, pathLen); dirList::iterator elem = dirs.find(entry); if (elem == dirs.end()) { // The directory was not found. CERR_STIL_DEBUG << "pos2Entry() did not find the dir" << endl; return false; } // Jump to the first entry of this section. inFile.seekg(elem->second); bool foundIt = false; // Now find the desired entry string line; do { getStilLine(inFile, line); if (inFile.eof()) { break; } // Check if it is the start of an entry if (line[0] == '/') { if (!stringutils::equal(elem->first.data(), line.data(), pathLen)) { // We are outside the section - get out of the loop, // which will fail the search. break; } // Check whether we need to find a section-global comment or // a specific entry. if (globComm || (STILVersion > 2.59f)) { foundIt = stringutils::equal(line.c_str(), entryStr); } else { // To be compatible with older versions of STIL, which may have // the tune designation on the first line of a STIL entry // together with the pathname. foundIt = stringutils::equal(line.data(), entryStr, entryStrLen); } CERR_STIL_DEBUG << "pos2Entry() line=" << line << endl; } } while (!foundIt); if (foundIt) { // Reposition the file pointer back to the start of the entry. inFile.seekg(inFile.tellg() - (streampos)line.size() - 1L); CERR_STIL_DEBUG << "pos2Entry() entry found" << endl; return true; } else { CERR_STIL_DEBUG << "pos2Entry() entry not found" << endl; return false; } } void STIL::readEntry(ifstream &inFile, string &buffer) { string line; for (;;) { getStilLine(inFile, line); if (line.size() == 0) break; buffer.append(line); buffer.append("\n"); } } bool STIL::getField(string &result, const char *buffer, int tuneNo, STILField field) const { CERR_STIL_DEBUG << "getField() called, buffer=" << buffer << ", rest=" << tuneNo << "," << field << endl; // Clean out the result buffer first. result.clear(); // Position pointer to the first char beyond the file designation. const char *start = strchr(buffer, '\n') + 1; // Check whether this is a NULL entry or not. if (*start == '\0') { CERR_STIL_DEBUG << "getField() null entry" << endl; return false; } // Is this a multitune entry? const char *firstTuneNo = strstr(start, "(#"); // This is a tune designation only if the previous char was // a newline (ie. if the "(#" is on the beginning of a line). if ((firstTuneNo != nullptr) && (*(firstTuneNo - 1) != '\n')) { firstTuneNo = nullptr; } if (firstTuneNo == nullptr) { //-------------------// // SINGLE TUNE ENTRY // //-------------------// // Is the first thing in this STIL entry the COMMENT? const char *temp = strstr(start, _COMMENT_STR); const char *temp2 = nullptr; // Search for other potential fields beyond the COMMENT. if (temp == start) { temp2 = strstr(start, _NAME_STR); if (temp2 == nullptr) { temp2 = strstr(start, _AUTHOR_STR); if (temp2 == nullptr) { temp2 = strstr(start, _TITLE_STR); if (temp2 == nullptr) { temp2 = strstr(start, _ARTIST_STR); } } } } if (temp == start) { // Yes. So it's assumed to be a file-global comment. CERR_STIL_DEBUG << "getField() single-tune entry, COMMENT only" << endl; if ((tuneNo == 0) && ((field == all) || ((field == comment) && (temp2 == nullptr)))) { // Simply copy the stuff in. result.append(start); CERR_STIL_DEBUG << "getField() copied to resultbuf" << endl; return true; } else if ((tuneNo == 0) && (field == comment)) { // Copy just the comment. result.append(start, temp2 - start); CERR_STIL_DEBUG << "getField() copied to just the COMMENT to resultbuf" << endl; return true; } else if ((tuneNo == 1) && (temp2 != nullptr)) { // A specific field was asked for. CERR_STIL_DEBUG << "getField() copying COMMENT to resultbuf" << endl; return getOneField(result, temp2, temp2 + strlen(temp2), field); } else { // Anything else is invalid as of v2.00. CERR_STIL_DEBUG << "getField() invalid parameter combo: single tune, tuneNo=" << tuneNo << ", field=" << field << endl; return false; } } else { // No. Handle it as a regular entry. CERR_STIL_DEBUG << "getField() single-tune regular entry" << endl; if ((field == all) && ((tuneNo == 0) || (tuneNo == 1))) { // The complete entry was asked for. Simply copy the stuff in. result.append(start); CERR_STIL_DEBUG << "getField() copied to resultbuf" << endl; return true; } else if (tuneNo == 1) { // A specific field was asked for. CERR_STIL_DEBUG << "getField() copying COMMENT to resultbuf" << endl; return getOneField(result, start, start + strlen(start), field); } else { // Anything else is invalid as of v2.00. CERR_STIL_DEBUG << "getField() invalid parameter combo: single tune, tuneNo=" << tuneNo << ", field=" << field << endl; return false; } } } else { //-------------------// // MULTITUNE ENTRY //-------------------// CERR_STIL_DEBUG << "getField() multitune entry" << endl; // Was the complete entry asked for? if (tuneNo == 0) { switch (field) { case all: // Yes. Simply copy the stuff in. result.append(start); CERR_STIL_DEBUG << "getField() copied all to resultbuf" << endl; return true; case comment: // Only the file-global comment field was asked for. if (firstTuneNo != start) { CERR_STIL_DEBUG << "getField() copying file-global comment to resultbuf" << endl; return getOneField(result, start, firstTuneNo, comment); } else { CERR_STIL_DEBUG << "getField() no file-global comment" << endl; return false; } break; default: // If a specific field other than a comment is // asked for tuneNo=0, this is illegal. CERR_STIL_DEBUG << "getField() invalid parameter combo: multitune, tuneNo=" << tuneNo << ", field=" << field << endl; return false; } } char tuneNoStr[8]; // Search for the requested tune number. snprintf(tuneNoStr, 7, "(#%d)", tuneNo); tuneNoStr[7] = '\0'; const char *myTuneNo = strstr(start, tuneNoStr); if (myTuneNo != nullptr) { // We found the requested tune number. // Set the pointer beyond it. myTuneNo = strchr(myTuneNo, '\n') + 1; // Where is the next one? const char *nextTuneNo = strstr(myTuneNo, "\n(#"); if (nextTuneNo == nullptr) { // There is no next one - set pointer to end of entry. nextTuneNo = start + strlen(start); } else { // The search included the \n - go beyond it. nextTuneNo++; } // Put the desired fields into the result (which may be 'all'). CERR_STIL_DEBUG << "getField() myTuneNo=" << myTuneNo << ", nextTuneNo=" << nextTuneNo << endl; return getOneField(result, myTuneNo, nextTuneNo, field); } else { CERR_STIL_DEBUG << "getField() nothing found" << endl; return false; } } } bool STIL::getOneField(string &result, const char *start, const char *end, STILField field) const { // Sanity checking if ((end < start) || (*(end - 1) != '\n')) { CERR_STIL_DEBUG << "getOneField() illegal parameters" << endl; return false; } CERR_STIL_DEBUG << "getOneField() called, start=" << start << ", rest=" << field << endl; const char *temp = nullptr; switch (field) { case all: result.append(start, end - start); return true; case name: temp = strstr(start, _NAME_STR); break; case author: temp = strstr(start, _AUTHOR_STR); break; case title: temp = strstr(start, _TITLE_STR); break; case artist: temp = strstr(start, _ARTIST_STR); break; case comment: temp = strstr(start, _COMMENT_STR); break; default: break; } // If the field was not found or it is not in between 'start' // and 'end', it is declared a failure. if ((temp == nullptr) || (temp < start) || (temp > end)) { return false; } // Search for the end of this field. This is done by finding // where the next field starts. const char *nextName = strstr(temp + 1, _NAME_STR); const char *nextAuthor = strstr(temp + 1, _AUTHOR_STR); const char *nextTitle = strstr(temp + 1, _TITLE_STR); const char *nextArtist = strstr(temp + 1, _ARTIST_STR); const char *nextComment = strstr(temp + 1, _COMMENT_STR); // If any of these fields is beyond 'end', they are ignored. if ((nextName != nullptr) && (nextName >= end)) { nextName = nullptr; } if ((nextAuthor != nullptr) && (nextAuthor >= end)) { nextAuthor = nullptr; } if ((nextTitle != nullptr) && (nextTitle >= end)) { nextTitle = nullptr; } if ((nextArtist != nullptr) && (nextArtist >= end)) { nextArtist = nullptr; } if ((nextComment != nullptr) && (nextComment >= end)) { nextComment = nullptr; } // Now determine which one is the closest to our field - that one // will mark the end of the required field. const char *nextField = nextName; if (nextField == nullptr) { nextField = nextAuthor; } else if ((nextAuthor != nullptr) && (nextAuthor < nextField)) { nextField = nextAuthor; } if (nextField == nullptr) { nextField = nextTitle; } else if ((nextTitle != nullptr) && (nextTitle < nextField)) { nextField = nextTitle; } if (nextField == nullptr) { nextField = nextArtist; } else if ((nextArtist != nullptr) && (nextArtist < nextField)) { nextField = nextArtist; } if (nextField == nullptr) { nextField = nextComment; } else if ((nextComment != nullptr) && (nextComment < nextField)) { nextField = nextComment; } if (nextField == nullptr) { nextField = end; } // Now nextField points to the last+1 char that should be copied to // result. Do that. result.append(temp, nextField - temp); return true; } void STIL::getStilLine(ifstream &infile, string &line) { if (STIL_EOL2 != '\0') { // If there was a remaining EOL char from the previous read, eat it up. char temp = infile.peek(); if ((temp == 0x0d) || (temp == 0x0a)) { infile.get(temp); } } getline(infile, line, STIL_EOL); } libsidplayfp-3.0.0/src/utils/iniParser.cpp0000644000175100017510000000631315175333711014257 /* * Copyright (C) 2010-2025 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "iniParser.h" #include "sidcxx11.h" #include #include #include namespace libsidplayfp { class parseError {}; std::string iniParser::parseSection(const std::string &buffer) { const size_t pos = buffer.find(']'); if (pos == std::string::npos) { throw parseError(); } return buffer.substr(1, pos-1); } iniParser::keys_t::value_type iniParser::parseKey(const std::string &buffer) { const size_t pos = buffer.find('='); if (pos == std::string::npos) { throw parseError(); } const std::string key = buffer.substr(0, buffer.find_last_not_of(' ', pos-1) + 1); const std::string value = buffer.substr(pos + 1); return std::make_pair(key, value); } bool iniParser::open(const char *fName) { std::ifstream iniFile(fName); return open_internal(iniFile); } #ifdef _WIN32 bool iniParser::open(const wchar_t *fName) { std::ifstream iniFile(fName); return open_internal(iniFile); } #endif bool iniParser::open_internal(std::ifstream & iniFile) { if (iniFile.fail()) { return false; } sections_t::iterator mIt = sections.end(); while (iniFile.good()) { std::string buffer; std::getline(iniFile, buffer); if (buffer.empty()) continue; switch (buffer.at(0)) { case ';': case '#': // skip comments break; case '[': try { const std::string section = parseSection(buffer); const keys_t keys; std::pair it = sections.insert(std::make_pair(section, keys)); mIt = it.first; } catch (parseError const &) {}; break; default: try { if (mIt != sections.end()) (*mIt).second.insert(parseKey(buffer)); } catch (parseError const &) {}; break; } } return true; } void iniParser::close() { sections.clear(); } bool iniParser::setSection(const char *section) { curSection = sections.find(std::string(section)); return (curSection != sections.end()); } const char *iniParser::getValue(const char *key) { keys_t::const_iterator keyIt = (*curSection).second.find(std::string(key)); return (keyIt != (*curSection).second.end()) ? keyIt->second.c_str() : nullptr; } } libsidplayfp-3.0.0/src/utils/iniParser.h0000644000175100017510000000303015175333711013715 /* * Copyright (C) 2010-2015 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef INIPARSER_H #define INIPARSER_H #include #include #include #include namespace libsidplayfp { class iniParser { private: using keys_t = std::map; using sections_t = std::map; private: sections_t sections; sections_t::const_iterator curSection; private: static std::string parseSection(const std::string &buffer); static keys_t::value_type parseKey(const std::string &buffer); bool open_internal(std::ifstream& iniFile); public: bool open(const char *fName); #ifdef _WIN32 bool open(const wchar_t* fName); #endif void close(); bool setSection(const char *section); const char *getValue(const char *key); }; } #endif // INIPARSER_H libsidplayfp-3.0.0/src/utils/SidDatabase.cpp0000644000175100017510000001145315175333711014470 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2022 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include "SidDatabase.h" #include "sidplayfp/SidTune.h" #include "sidplayfp/SidTuneInfo.h" #include "iniParser.h" #include "sidcxx11.h" const char ERR_DATABASE_CORRUPT[] = "SID DATABASE ERROR: Database seems to be corrupt."; const char ERR_NO_DATABASE_LOADED[] = "SID DATABASE ERROR: Songlength database not loaded."; const char ERR_NO_SELECTED_SONG[] = "SID DATABASE ERROR: No song selected for retrieving song length."; const char ERR_UNABLE_TO_LOAD_DATABASE[] = "SID DATABASE ERROR: Unable to load the songlength database."; class parseError {}; SidDatabase::SidDatabase() : m_parser(nullptr), errorString(ERR_NO_DATABASE_LOADED) {} SidDatabase::~SidDatabase() { delete m_parser; } // mm:ss[.SSS] // // Examples of song length values: // // 1:02 // // 1:02.5 // // 1:02.500 // const char *parseTime(const char *str, int_least32_t &result) { char *end; const long minutes = strtol(str, &end, 10); if (*end != ':') { throw parseError(); } end++; const long seconds = strtol(end, &end, 10); result = ((minutes * 60) + seconds) * 1000; if (*end == '.') { const char *start = end + 1; long milliseconds = strtol(start, &end, 10); switch (end - start) { case 1: milliseconds *= 100; break; case 2: milliseconds *= 10; break; case 3: break; default: throw parseError(); } if (milliseconds<0 || milliseconds>=1000) throw parseError(); result += milliseconds; } while ((*end != 0) && !isspace(*end)) { end++; } return end; } bool SidDatabase::open(const char *filename) { delete m_parser; m_parser = new libsidplayfp::iniParser(); if (!m_parser->open(filename)) { close(); errorString = ERR_UNABLE_TO_LOAD_DATABASE; return false; } return true; } #ifdef _WIN32 bool SidDatabase::open(const wchar_t* filename) { delete m_parser; m_parser = new libsidplayfp::iniParser(); if (!m_parser->open(filename)) { close(); errorString = ERR_UNABLE_TO_LOAD_DATABASE; return false; } return true; } #endif void SidDatabase::close() { delete m_parser; m_parser = nullptr; } int_least32_t SidDatabase::length(SidTune &tune) { const unsigned int song = tune.getInfo()->currentSong(); if (!song) { errorString = ERR_NO_SELECTED_SONG; return -1; } char md5[SidTune::MD5_LENGTH + 1]; tune.createMD5(md5); return lengthMs(md5, song) / 1000; } int_least32_t SidDatabase::lengthMs(SidTune &tune) { const unsigned int song = tune.getInfo()->currentSong(); if (!song) { errorString = ERR_NO_SELECTED_SONG; return -1; } char md5[SidTune::MD5_LENGTH + 1]; tune.createMD5New(md5); return lengthMs(md5, song); } int_least32_t SidDatabase::length(const char *md5, unsigned int song) { return lengthMs(md5, song) / 1000; } int_least32_t SidDatabase::lengthMs(const char *md5, unsigned int song) { if (m_parser == nullptr) { errorString = ERR_NO_DATABASE_LOADED; return -1; } // Read Time (and check times before hand) if (!m_parser->setSection("Database")) { errorString = ERR_DATABASE_CORRUPT; return -1; } const char *timeStamp = m_parser->getValue(md5); // If return is null then no entry found in database if (!timeStamp) { errorString = ERR_DATABASE_CORRUPT; return -1; } const char *str = timeStamp; int_least32_t time = 0; for (unsigned int i = 0; i < song; i++) { // Validate Time try { str = parseTime(str, time); } catch (parseError const &) { errorString = ERR_DATABASE_CORRUPT; return -1; } } return time; } libsidplayfp-3.0.0/src/libs/0000755000175100017510000000000015175333711011465 5libsidplayfp-3.0.0/src/libs/hashlib/0000755000175100017510000000000015175333711013077 5libsidplayfp-3.0.0/src/libs/hashlib/md5.hpp0000644000175100017510000001610515175333711014220 #ifndef HASHLIB_ALL_IN_ONE #pragma once #include "core.hpp" #endif namespace hashlib { namespace detail { class md5 { public: static constexpr std::size_t digest_size = 16; public: auto update(span bytes) noexcept -> void { update(bytes.begin(), bytes.end()); } template::value && !is_random_access_iterator::value && is_sentinel_for::value && is_byte_like>::value >* = nullptr> auto update(InputIt first, Sentinel last) -> void { byte temp[128]; for (auto it = first; it != last;) { std::size_t n = 0; for (; it != last && n < sizeof(temp); ++it, ++n) { temp[n] = static_cast(*it); } update({temp, n}); } } template::value && is_sentinel_for::value && is_byte_like>::value >* = nullptr> auto update(RandomAccessIt first, Sentinel last) -> void { std::size_t bytes_count = last - first; total_size_ += bytes_count; std::size_t i = 0; if (buffer_size_ > 0) { std::size_t to_copy = std::min(bytes_count, 64 - buffer_size_); std::copy_n(first, to_copy, buffer_.data() + buffer_size_); buffer_size_ += to_copy; i += to_copy; if (buffer_size_ == 64) { process_(w_table_(buffer_.data())); buffer_size_ = 0; } } for (; i + 63 < bytes_count; i += 64) { (process_)((w_table_)(std::next(first, i))); } if (i < bytes_count) { std::copy_n(std::next(first, i), bytes_count - i, buffer_.data()); buffer_size_ = bytes_count - i; } } protected: auto do_digest() noexcept -> std::array { auto_restorer _{*this}; auto buffer_size = buffer_size_; auto total_size = total_size_; byte padding[128]{}; padding[0] = 0x80; std::size_t padding_size = (buffer_size < 56) ? (56 - buffer_size) : (120 - buffer_size); update({padding, padding_size}); std::uint64_t bits = total_size * 8; for (std::size_t i = 0; i < 8; ++i) padding[i] = (bits >> (8 * i)) & 0xff; update({padding, 8}); return {a_, b_, c_, d_}; } HASHLIB_ALWAYS_INLINE static auto unit_to_bytes(std::uint32_t unit) noexcept -> std::array { byte* byte_ptr = reinterpret_cast(&unit); if HASHLIB_CXX17_CONSTEXPR (is_little_endian()) { return {byte_ptr[0], byte_ptr[1], byte_ptr[2], byte_ptr[3]}; } else { return {byte_ptr[3], byte_ptr[2], byte_ptr[1], byte_ptr[0]}; } } private: auto process_(const std::array& w) noexcept -> void { static constexpr std::uint32_t K[64]{ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }; static constexpr std::uint32_t S[16]{7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21}; std::uint32_t a = a_, b = b_, c = c_, d = d_; for (std::size_t i = 0; i < 64; ++i) { std::uint32_t F, g, cnt; if (i < 16) { F = (b & c) | ((~b) & d); g = i; cnt = S[i % 4]; } else if (i < 32) { F = (d & b) | ((~d) & c); g = (5 * i + 1) % 16; cnt = S[4 + i % 4]; } else if (i < 48) { F = b ^ c ^ d; g = (3 * i + 5) % 16; cnt = S[8 + i % 4]; } else { F = c ^ (b | (~d)); g = (7 * i) % 16; cnt = S[12 + i % 4]; } F = F + a + K[i] + w[g]; a = d; d = c; c = b; b = b + ((F << cnt) | (F >> (32 - cnt))); } a_ += a; b_ += b; c_ += c; d_ += d; } template static auto w_table_(RandomAccessIt it) noexcept -> std::array { static_assert(is_random_access_iterator::value, "unexpected"); std::array w; // NOLINT(*-pro-type-member-init) for (std::size_t i = 0; i < 16; ++i) { w[i] = (std::uint32_t(it[i * 4])) | (std::uint32_t(it[i * 4 + 1]) << 8) | (std::uint32_t(it[i * 4 + 2]) << 16) | (std::uint32_t(it[i * 4 + 3]) << 24); } return w; } private: std::array buffer_{}; std::size_t buffer_size_ = 0; std::uint64_t total_size_ = 0; std::uint32_t a_ = 0x67452301, b_ = 0xefcdab89, c_ = 0x98badcfe, d_ = 0x10325476; }; } HASHLIB_MOD_EXPORT using md5 = context; } libsidplayfp-3.0.0/src/libs/hashlib/README.md0000644000175100017510000001026515175333711014302 [简体中文](README.zh-CN.md) | English # hashlib [![License](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE) [![Language](https://img.shields.io/badge/Language-C%2B%2B11-blue.svg)]() `Cra3z' hashlib` is a C++11 header-only hash algorithm library which like Python's hashlib. supported algorithms: * md5 * sha1 * sha224 * sha256 * sha384 * sha512 * sha3_224 * sha3_256 * sha3_384 * sha3_512 ## Usage ### Using headers hashlib is a header-only library, so you can simply copy the headers in the directory `include/hashlib` to where you need it. However, it is recommended to embed hashlib as a subproject in your project, or install it first and then import it via CMake's `find_package`. ```cmake find_package(hashlib REQUIRED) target_link_libraries( hashlib::hashlib) ``` #### Single header You can also generate a single header `hashlib.hpp` which combines all headers in the directory `include/hashlib`, see [Generate single header](#generate-single-header). ### Using C++20 module hashlib supports C++20 module (need the standard module `std`); you can generate the module file, and then import it, see [Generate C++20 module](#generate-c20-module). ```cpp import std; import hashlib; int main() { hashlib::md5 md5; md5.update("hello world"); std::println("{}", md5.hexdigest()); } ``` ## Building & Installation ### Requirements - CMake 3.22+ (for building) - C++ compiler which supports C++11 or newer standard ```shell mkdir cd cmake -S . -B cmake --build cmake --install --prefix ``` ### CMake Options | Option | Default | Description | |--------|---------|------------------------| | HASHLIB_TESTS | ON | enable tests | | HASHLIB_BUILD_SINGLE_HEADER | OFF | generate single header | | HASHLIB_BUILD_MODULE | OFF | generate C++20 module | #### Generate single header using the following command, the single header `hashlib.hpp` which combines all headers in the directory `include/hashlib` will be generated in your build directory. ```shell cmake -S . -B -DHASHLIB_BUILD_SINGLE_HEADER=ON ``` #### Generate C++20 module using the following command, the module file `hashlib.cppm` will be generated in your build directory. ```shell cmake -S . -B -DHASHLIB_BUILD_MODULE=ON ``` ### using conan package manager You can also install hashlib by [conan package manager](https://github.com/conan-io). ```shell conan install --requires=hashlib/[*] ``` ## Examples * get md5 of a string by using `hashlib::md5` ```cpp #include #include int main() { hashlib::md5 md5{std::string("hello world")}; std::cout << md5.hexdigest() << '\n'; // 5eb63bbbe01eeed093cb22bb8f5acdc3 } ``` * using the method `update` or `operator<<` ```cpp #include #include int main() { { hashlib::md5 md5; md5.update(std::string("hello")); md5.update(std::string(" world")); std::cout << md5.hexdigest() << '\n'; // 5eb63bbbe01eeed093cb22bb8f5acdc3 } { hashlib::md5 md5; md5 << std::string("hello") << std::string(" world"); std::cout << md5.hexdigest() << '\n'; // 5eb63bbbe01eeed093cb22bb8f5acdc3 } } ``` * hashing the bytes from iterators and ranges whose elements are `char`, `unsigned char`, `signed char` or `std::byte (since c++17)` ```cpp #include #include int main() { unsigned char data[] = {0x00, 0xff, 0x55, 0xaa, 0x12, 0x34, 0x56, 0x78}; hashlib::sha1 sha1; sha1.update(data); std::cout << sha1.hexdigest() << '\n'; // f9d9a450e6e14895936f8dc796e30209528de337 } ``` ```cpp #include #include #include int main() { std::ifstream file("example.txt", std::ios::in | std::ios::binary); if (!file) { std::cerr << "Failed to open file" << std::endl; return EXIT_FAILURE; } hashlib::sha1 sha1; sha1.update( std::istreambuf_iterator{file}, std::istreambuf_iterator{} ); std::cout << sha1.hexdigest() << '\n'; // output the sha1 digest of the file example.txt } ``` libsidplayfp-3.0.0/src/libs/hashlib/core.hpp0000644000175100017510000004211115175333711014457 // ReSharper disable CppUseTypeTraitAlias #ifndef HASHLIB_ALL_IN_ONE #pragma once #include "config.hpp" #include #ifdef __cpp_lib_endian #include #endif #include #include #include #include #include #include #include #include #include #endif namespace hashlib { namespace detail { template using bool_constant = std::integral_constant; template using enable_if_t = typename std::enable_if::type; template using conditional_t = typename std::conditional::type; template using void_t = void; template using remove_const_t = typename std::remove_const::type; template using remove_reference_t = typename std::remove_reference::type; template using remove_pointer_t = typename std::remove_pointer::type; template using remove_cv_t = typename std::remove_cv::type; template using remove_cvref_t = remove_cv_t>; template using add_pointer_t = typename std::add_pointer::type; template struct type_identity { using type = T; }; template using type_identity_t = typename type_identity::type; template struct conjunction : std::true_type {}; template struct conjunction : B1 {}; template struct conjunction : conditional_t, B1> {}; template struct disjunction : std::false_type {}; template struct disjunction : B1 {}; template struct disjunction : conditional_t> {}; template struct negation : bool_constant {}; template using is_derived_from = conjunction, std::is_convertible>; template using iter_reference_t = decltype(*std::declval()); template using iter_value_t = remove_cvref_t>; #ifndef __cpp_lib_nonmember_container_access template HASHLIB_CXX17_CONSTEXPR auto data(C& c) -> decltype(c.data()) { return c.data(); } template HASHLIB_CXX17_CONSTEXPR auto data(const C& c) -> decltype(c.data()) { return c.data(); } template HASHLIB_CXX17_CONSTEXPR auto data(T(&array)[N]) noexcept -> T* { return array; } template HASHLIB_CXX17_CONSTEXPR auto data(std::initializer_list il) noexcept -> const E* { return il.begin(); } #else using std::data; #endif template using iter_cat_t = typename std::iterator_traits::iterator_category; template struct is_iterator_impl : std::false_type {}; template struct is_iterator_impl>> : is_derived_from, Tag> {}; template struct is_sentinel_for_impl : std::false_type {}; template struct is_sentinel_for_impl() != std::declval())>> : std::true_type {}; template using range_iter_t = decltype(std::begin(std::declval())); template using range_sent_t = decltype(std::end(std::declval())); template using range_reference_t = iter_reference_t>; template using range_value_t = iter_value_t>; template struct is_range_impl : std::false_type {}; template struct is_range_impl, Tag>::value && is_sentinel_for_impl, range_iter_t>::value >> : std::true_type {}; template struct is_contiguous_range_impl : std::false_type {}; template struct is_contiguous_range_impl::value && std::is_same< decltype(data(std::declval())), // use ADL add_pointer_t>> >::value >> : std::true_type {}; template using is_output_iterator = is_iterator_impl; template using is_input_iterator = is_iterator_impl; template using is_forward_iterator = is_iterator_impl; template using is_bidirectional_iterator = is_iterator_impl; template using is_random_access_iterator = is_iterator_impl; template using is_sentinel_for = is_sentinel_for_impl; template using is_input_range = is_range_impl; template using is_forward_range = is_range_impl; template using is_bidirectional_range = is_range_impl; template using is_random_access_range = is_range_impl; template using is_contiguous_range = is_contiguous_range_impl; #ifdef __cpp_lib_endian using std::endian; #else enum class endian { #if defined(_MSC_VER) && !defined(__clang__) little = 0, big = 1, native = little #else little = __ORDER_LITTLE_ENDIAN__, big = __ORDER_BIG_ENDIAN__, native = __BYTE_ORDER__ #endif }; #endif static_assert(endian::native == endian::big || endian::native == endian::little, "unsupported mixed-endian."); constexpr auto is_little_endian() noexcept -> bool { return endian::native == endian::little; } } HASHLIB_MOD_EXPORT using byte = unsigned char; HASHLIB_MOD_EXPORT HASHLIB_CXX17_INLINE constexpr std::size_t dynamic_extent = static_cast(-1); template class span; namespace detail { template struct is_span: std::false_type {}; template struct is_span> : std::true_type {}; template struct is_std_array : std::false_type {}; template struct is_std_array> : std::true_type {}; } HASHLIB_MOD_EXPORT template class span { public: using element_type = T; using value_type = detail::remove_cv_t; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using pointer = T*; using const_pointer = const T*; using reference = T&; using const_reference = const T&; using iterator = T*; using const_iterator = const T*; using reverse_iterator = std::reverse_iterator; using const_reverse_iterator = std::reverse_iterator; public: span() = default; HASHLIB_CXX17_CONSTEXPR span(pointer data, size_type size) noexcept : data_(data), size_(size) { assert(data_ || size_ == 0); } template* = nullptr> HASHLIB_CXX17_CONSTEXPR span(detail::type_identity_t(&array)[M]) noexcept : span(array, N) {} template* = nullptr> HASHLIB_CXX17_CONSTEXPR span(std::array& array) noexcept : span(array.data(), N) {} template::value && (N == dynamic_extent || M == N) >* = nullptr> HASHLIB_CXX17_CONSTEXPR span(const std::array& array) noexcept : span(array.data(), N) {} template::value && std::is_same>::value> * = nullptr> HASHLIB_CXX17_CONSTEXPR span(span other) : span(other.data(), other.size()) {} template::value && std::is_same, value_type>::value && !detail::is_span>::value && !detail::is_std_array>::value && std::is_convertible())), pointer>::value >* = nullptr> HASHLIB_CXX17_CONSTEXPR span(Range& rng): span(detail::data(rng), std::distance(std::begin(rng), std::end(rng))) {} HASHLIB_CXX17_CONSTEXPR span(const span& other) noexcept = default; span& operator= (const span& other) noexcept = default; ~span() = default; HASHLIB_CXX17_CONSTEXPR auto first(size_type count) const noexcept -> span { assert(count <= size_); return span(data_, count); } HASHLIB_CXX17_CONSTEXPR auto last(size_type count) const noexcept -> span { assert(count <= size_); return span(data_ + (size_ - count), count); } HASHLIB_CXX17_CONSTEXPR auto subspan(size_type pos, size_type count = dynamic_extent) const noexcept -> span { assert(pos <= size_); assert(count == dynamic_extent || count <= size_ - pos); return span( data_ + pos, count == dynamic_extent ? size_ - pos : count ); } HASHLIB_CXX17_CONSTEXPR auto size() const noexcept -> size_type { return size_; } HASHLIB_CXX17_CONSTEXPR auto size_bytes() const noexcept -> size_type { return size() * sizeof(T); } HASHLIB_CXX17_CONSTEXPR auto empty() const noexcept -> bool { return size_ == 0; } HASHLIB_CXX17_CONSTEXPR auto operator[](size_type index) const noexcept -> T& { assert(index < size_); return data_[index]; } HASHLIB_CXX17_CONSTEXPR auto front() const noexcept -> T& { assert(!empty()); return *data(); } HASHLIB_CXX17_CONSTEXPR auto back() const noexcept -> T& { assert(!empty()); return *(data() + size() - 1); } HASHLIB_CXX17_CONSTEXPR auto data() const noexcept -> T* { return static_cast(data_); } HASHLIB_CXX17_CONSTEXPR auto begin() const noexcept -> iterator { return static_cast(data_); } HASHLIB_CXX17_CONSTEXPR auto end() const noexcept -> iterator { return begin() + size_; } HASHLIB_CXX17_CONSTEXPR auto cbegin() const noexcept -> const_iterator { return begin(); } HASHLIB_CXX17_CONSTEXPR auto cend() const noexcept -> const_iterator { return end(); } HASHLIB_CXX17_CONSTEXPR auto rbegin() const noexcept -> reverse_iterator { return reverse_iterator(end()); } HASHLIB_CXX17_CONSTEXPR auto rend() const noexcept -> reverse_iterator { return reverse_iterator(begin()); } HASHLIB_CXX17_CONSTEXPR auto crbegin() const noexcept -> const_reverse_iterator { return const_reverse_iterator(cend()); } HASHLIB_CXX17_CONSTEXPR auto crend() const noexcept -> const_reverse_iterator { return const_reverse_iterator(cbegin()); } private: pointer data_{}; size_type size_{}; }; HASHLIB_MOD_EXPORT template HASHLIB_NODISCARD auto as_bytes(span s) noexcept -> span { return {reinterpret_cast(s.data()), s.size_bytes()}; } HASHLIB_MOD_EXPORT template::value>* = nullptr> HASHLIB_NODISCARD auto as_writable_bytes(span s) noexcept -> span { return {reinterpret_cast(s.data()), s.size_bytes()}; } namespace detail { template class auto_restorer { static_assert(std::is_same>::value, "`T` shall be a non-cv-qualified, non-reference type"); static_assert( std::is_move_constructible::value && std::is_move_assignable::value && std::is_copy_constructible::value && std::is_copy_assignable::value, "`T` shall be a copyable type" ); public: HASHLIB_CXX20_CONSTEXPR explicit auto_restorer(T& target) noexcept(std::is_nothrow_copy_constructible::value) : ref_(target), old_(target) {} auto_restorer(const auto_restorer&) = delete; HASHLIB_CXX20_CONSTEXPR ~auto_restorer() { ref_ = std::move(old_); } auto operator= (const auto_restorer&) -> auto_restorer& = delete; private: T& ref_; T old_; }; template using is_byte_like = disjunction< std::is_same, char>, std::is_same, unsigned char>, std::is_same, signed char> #ifdef __cpp_lib_byte ,std::is_same, std::byte> #endif >; HASHLIB_CXX17_INLINE constexpr char hex_table[] = "0123456789abcdef"; } HASHLIB_MOD_EXPORT template class context : private Base { public: using Base::digest_size; using Base::update; context() = default; explicit context(span bytes) : context() { this->update(bytes); } template::value && detail::is_sentinel_for::value && detail::is_byte_like>::value >* = nullptr> explicit context(InputIt first, Sentinel last) : context() { this->update(std::move(first), std::move(last)); } template::value && detail::is_byte_like>::value >* = nullptr> explicit context(Range&& rng) : context(std::begin(rng), std::end(rng)) {} template::value && detail::is_byte_like>::value >* = nullptr> auto update(Range&& rng) -> void { this->update(std::begin(rng), std::end(rng)); } HASHLIB_NODISCARD auto digest() noexcept -> std::array { std::array result; std::size_t i = 0; static_assert(digest_size <= sizeof(decltype(this->do_digest())), "what the f**k?"); for (auto unit : this->do_digest()) { if (i == digest_size) break; for (auto byte_ : this->unit_to_bytes(unit)) { result[i++] = byte_; } } assert(i == digest_size); return result; } HASHLIB_NODISCARD auto hexdigest() -> std::string { std::string result; result.resize(2 * digest_size); std::size_t i = 0; for (auto byte_ : digest()) { result[i++] = detail::hex_table[byte_ / 16]; result[i++] = detail::hex_table[byte_ % 16]; } return result; } HASHLIB_CXX17_CONSTEXPR auto clear() noexcept -> void { *this = context{}; } template::value && detail::is_byte_like>::value >* = nullptr> auto operator<< (Range&& rng) -> context& { this->update(std::forward(rng)); return *this; } }; }libsidplayfp-3.0.0/src/libs/hashlib/LICENSE0000644000175100017510000000204515175333711014025 MIT License Copyright (c) 2025 Cra3z Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.libsidplayfp-3.0.0/src/libs/hashlib/config.hpp0000644000175100017510000000411415175333711014775 #ifndef HASHLIB_ALL_IN_ONE #pragma once #ifdef __has_include #if __has_include() #include #endif #endif #endif #define HASHLIB_VERSION "1.1.1" #ifdef _MSVC_LANG #define HASHLIB_CXX_STANDARD _MSVC_LANG #else #define HASHLIB_CXX_STANDARD __cplusplus #endif #define HASHLIB_CXX_STD98 199711L #define HASHLIB_CXX_STD11 201103L #define HASHLIB_CXX_STD14 201402L #define HASHLIB_CXX_STD17 201703L #define HASHLIB_CXX_STD20 202002L #define HASHLIB_CXX_STD23 202302L #if HASHLIB_CXX_STANDARD < HASHLIB_CXX_STD11 #error "hashlib requires a C++11 compiler." #endif #ifdef __clang__ #define HASHLIB_CXX_COMPILER_CLANG 1 #define HASHLIB_CXX_COMPILER_GCC 0 #define HASHLIB_CXX_COMPILER_MSVC 0 #elif defined(__GNUC__) #define HASHLIB_CXX_COMPILER_CLANG 0 #define HASHLIB_CXX_COMPILER_GCC 1 #define HASHLIB_CXX_COMPILER_MSVC 0 #elif defined(_MSC_VER) #define HASHLIB_CXX_COMPILER_CLANG 0 #define HASHLIB_CXX_COMPILER_GCC 0 #define HASHLIB_CXX_COMPILER_MSVC 1 #else #error "hashlib requires the C++ compiler is clang, gcc or msvc." #endif #if HASHLIB_CXX_COMPILER_CLANG #define HASHLIB_ALWAYS_INLINE [[clang::always_inline]] #elif HASHLIB_CXX_COMPILER_GCC #define HASHLIB_ALWAYS_INLINE [[gnu::always_inline]] #elif HASHLIB_CXX_COMPILER_MSVC #define HASHLIB_ALWAYS_INLINE [[msvc::forceinline]] #endif #ifdef HASHLIB_BUILD_MODULE #define HASHLIB_MOD_EXPORT export #define HASHLIB_MOD_EXPORT_BEGIN export { #define HASHLIB_MOD_EXPORT_END } #else #define HASHLIB_MOD_EXPORT #define HASHLIB_MOD_EXPORT_BEGIN #define HASHLIB_MOD_EXPORT_END #endif #if HASHLIB_CXX_STANDARD >= HASHLIB_CXX_STD17 #define HASHLIB_CXX17_CONSTEXPR constexpr #else #define HASHLIB_CXX17_CONSTEXPR #endif #if HASHLIB_CXX_STANDARD >= HASHLIB_CXX_STD20 #define HASHLIB_CXX20_CONSTEXPR constexpr #else #define HASHLIB_CXX20_CONSTEXPR #endif #if HASHLIB_CXX_STANDARD >= HASHLIB_CXX_STD17 #define HASHLIB_CXX17_INLINE inline #else #define HASHLIB_CXX17_INLINE #endif #ifdef __has_cpp_attribute #if __has_cpp_attribute(nodiscard) #define HASHLIB_NODISCARD [[nodiscard]] #else #define HASHLIB_NODISCARD #endif #else #define HASHLIB_NODISCARD #endiflibsidplayfp-3.0.0/src/builders/0000755000175100017510000000000015175333725012352 5libsidplayfp-3.0.0/src/builders/sidlite-builder/0000755000175100017510000000000015175333725015433 5libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite-builder.cpp0000644000175100017510000000511115175333711021131 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "sidlite.h" #include #include #include #include "properties.h" #include "sidlite-emu.h" struct SIDLiteBuilder::config { /*Property filter8580Curve; Property filter6581Curve; Property filter6581Range; Property cws;*/ }; SIDLiteBuilder::SIDLiteBuilder(const char * const name) : sidbuilder(name), m_config(new config) {} SIDLiteBuilder::~SIDLiteBuilder() { // Remove all SID emulations remove(); delete m_config; } // Create a new sid emulation. libsidplayfp::sidemu* SIDLiteBuilder::create() { try { auto sid = new libsidplayfp::SIDLiteEmu(this); /*if (m_config->filter6581Curve.has_value()) sid->filter6581Curve(m_config->filter6581Curve.value()); if (m_config->filter8580Curve.has_value()) sid->filter8580Curve(m_config->filter8580Curve.value()); if (m_config->filter6581Range.has_value()) sid->filter6581Range(m_config->filter6581Range.value()); if (m_config->cws.has_value()) sid->combinedWaveforms(m_config->cws.value());*/ return sid; } catch (std::bad_alloc const &) { // Memory alloc failed m_errorBuffer.assign(name()).append(" ERROR: Unable to create SIDLite object"); return nullptr; } } const char *SIDLiteBuilder::getCredits() const { return libsidplayfp::SIDLiteEmu::getCredits(); } /* void SIDLiteBuilder::filter6581Curve(double filterCurve) { m_config->filter6581Curve = filterCurve; for (libsidplayfp::sidemu* e: sidobjs) static_cast(e)->filter6581Curve(filterCurve); }*/ libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite-emu.cpp0000644000175100017510000000716115175333711020300 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "sidlite-emu.h" #include //#include "sidlite/siddefs.h" #include "sidplayfp/siddefs.h" #ifdef HAVE_CONFIG_H # include "config.h" #endif namespace libsidplayfp { const char* SIDLiteEmu::getCredits() { return "SIDLiteEmu V" VERSION " Engine:\n" "\t(C) 2025-2026 Leandro Nini\n" "MOS6581/CSG8580 (SID) Emulation:\n" "\t(C) 2025-2026 Leandro Nini\n" "\tBased on cRSID by Hermit (Mihaly Horvath)\n"; } SIDLiteEmu::SIDLiteEmu(sidbuilder *builder) : sidemu(builder), m_sid(*(new SIDLite::SID)) { reset(0); } SIDLiteEmu::~SIDLiteEmu() { delete &m_sid; delete[] m_buffer; } // Standard component options void SIDLiteEmu::reset(uint8_t volume) { m_accessClk = 0; m_sid.reset(); m_sid.write(0x18, volume); } uint8_t SIDLiteEmu::read(uint_least8_t addr) { clock(); return m_sid.read(addr); } void SIDLiteEmu::write(uint_least8_t addr, uint8_t data) { clock(); m_sid.write(addr, data); } void SIDLiteEmu::clock() { const event_clock_t cycles = eventScheduler->getTime(EVENT_CLOCK_PHI1) - m_accessClk; m_accessClk += cycles; m_bufferpos += m_sid.clock(cycles, m_buffer+m_bufferpos); } int SIDLiteEmu::getLevel() const { return m_sid.getLevel(); } /* void SIDLiteEmu::filter(bool enable) { m_sid.enableFilter(enable); } */ void SIDLiteEmu::sampling(float systemclock, float freq, SidConfig::sampling_method_t /*method*/) {/* SIDLite::SamplingMethod sampleMethod; switch (method) { case SidConfig::INTERPOLATE: sampleMethod = SIDLite::DECIMATE; break; case SidConfig::RESAMPLE_INTERPOLATE: sampleMethod = SIDLite::RESAMPLE; break; default: m_status = false; m_error = ERR_INVALID_SAMPLING; return; } */ if (!m_sid.setSamplingParameters(systemclock, freq)) { m_status = false; m_error = ERR_UNSUPPORTED_FREQ; } if (m_buffer) delete[] m_buffer; // 20ms buffer const int buffersize = std::ceil((freq / 1000.f) * 20.f); m_buffer = new short[buffersize]; m_status = true; } // Set the emulated SID model void SIDLiteEmu::model(SidConfig::sid_model_t model, bool /*digiboost*/) { SIDLite::SID::model_t chip; switch (model) { case SidConfig::MOS6581: chip = SIDLite::SID::model_t::MOS6581; //m_sid.input(0); break; case SidConfig::MOS8580: chip = SIDLite::SID::model_t::MOS8580; //m_sid.input(digiboost ? -32768 : 0); break; default: m_status = false; m_error = ERR_INVALID_CHIP; return; } m_sid.setChipModel(chip); m_status = true; } } libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite.h0000644000175100017510000000256615175333711017165 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDLITE_H #define SIDLITE_H #include "sidplayfp/sidbuilder.h" #include "sidplayfp/siddefs.h" /** * SIDLite Builder Class */ class SID_EXTERN SIDLiteBuilder: public sidbuilder { protected: /** * Create the sid emu. */ libsidplayfp::sidemu* create(); public: SIDLiteBuilder(const char * const name); ~SIDLiteBuilder(); const char *getCredits() const; private: struct config; config *m_config; }; #endif // SIDLITE_H libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite-emu.h0000644000175100017510000000353415175333711017745 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDLITE_EMU_H #define SIDLITE_EMU_H #include #include "sidlite/SID.h" #include "sidplayfp/SidConfig.h" #include "sidemu.h" #include "Event.h" #include "sidcxx11.h" class sidbuilder; namespace libsidplayfp { class SIDLiteEmu final : public sidemu { private: SIDLite::SID &m_sid; public: static const char* getCredits(); public: explicit SIDLiteEmu(sidbuilder *builder); ~SIDLiteEmu() override; bool getStatus() const { return m_status; } uint8_t read(uint_least8_t addr) override; void write(uint_least8_t addr, uint8_t data) override; // c64sid functions void reset(uint8_t volume) override; // Standard SID emu functions void clock() override; void sampling(float systemclock, float freq, SidConfig::sampling_method_t method) override; void model(SidConfig::sid_model_t model, bool digiboost) override; int getLevel() const; }; } #endif // RESIDFP_EMU_H libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/0000755000175100017510000000000015175333725017070 5libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/README0000644000175100017510000000012115175333711017655 sidlite is a lightweight SID emulation based on cRSID by Hermit (Mihaly Horvath) libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/SID.cpp0000644000175100017510000000645415175333711020137 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2025-2026 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // Based on cRSID lightweight RealSID by Hermit (Mihaly Horvath) #include "SID.h" #include "sl_defs.h" #include "sl_constants.h" #include "filt_tables.h" #include "cw_tables.h" #include #include #include namespace SIDLite { int SID::clock(unsigned int cycles, short* buf) { int i = 0; while (cycles > 0) { short output; if (generateSample(cycles, output)) { buf[i] = output; i++; } } return i; } inline bool SID::generateSample(unsigned int &cycles, short &output) { // Cycle-based part of emulations: while (SampleCycleCnt <= s.SampleClockRatio) { // no more cycles, can't produce output if (cycles == 0) return false; unsigned char InstructionCycles = std::min(7u, cycles); SampleCycleCnt += InstructionCycles << 4; cycles -= InstructionCycles; adsr.clock(InstructionCycles); } SampleCycleCnt -= s.SampleClockRatio; // Samplerate-based part of emulations: wg_output_t wg_out = wavgen.clock(&adsr); int sample = filter.clock(wg_out.first, wg_out.second); // saturation logic on overflow if (sample > INT16_MAX) sample = INT16_MAX; else if (sample < INT16_MIN) sample = INT16_MIN; output = static_cast(sample); return true; } void SID::write(int addr, int value) { regs[addr] = value; } int SID::read(int addr) const { switch (addr) { case 0x1B: return wavgen.getOsc3(); case 0x1C: return wavgen.getEnv3(); default: return 0; } } SID::SID() : adsr(regs), filter(&s, regs), wavgen(&s, regs) { setChipModel(model_t::MOS8580); reset(); } void SID::reset() { SampleCycleCnt = 0; std::fill(std::begin(regs), std::end(regs), 0); adsr.reset(); filter.reset(); wavgen.reset(); } bool SID::setSamplingParameters(unsigned int clockFrequency, unsigned short samplingFrequency) { if ((samplingFrequency < 8000) || (samplingFrequency > 48000)) return false; filter.rebuildCutoffTables(samplingFrequency); // shifting (multiplication) enhances SampleClockRatio precision s.SampleClockRatio = (clockFrequency << CRSID_CLOCK_FRACTIONAL_BITS) / samplingFrequency; return true; } void SID::setChipModel(model_t model) { s.sid8580 = model == model_t::MOS8580; } void SID::setRealSIDmode(bool mode) { s.RealSIDmode = mode; } } libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/sl_defs.h.in0000644000175100017510000000233215175333711021200 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2026 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SIDLITE_DEFS_H #define SIDLITE_DEFS_H // Compiler specifics. #define HAVE_BUILTIN_EXPECT @HAVE_BUILTIN_EXPECT@ // Branch prediction macros, lifted off the Linux kernel. #if HAVE_BUILTIN_EXPECT # define LIKELY(x) __builtin_expect(!!(x), 1) # define UNLIKELY(x) __builtin_expect(!!(x), 0) #else # define LIKELY(x) (x) # define UNLIKELY(x) (x) #endif #endif // SIDLITE_DEFS_H libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/filt_tables.h0000644000175100017510000000556615175333711021460 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2025-2026 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // Based on cRSID lightweight RealSID by Hermit (Mihaly Horvath) #include #include constexpr int ResLength = 0x10; using res_array_t = std::array; #if __cplusplus > 202302L // std::exp2 is constexpr since c++26 # include constexpr int CRSID_FILTERTABLE_RESOLUTION = 12; constexpr int Magnitude = (1 << CRSID_FILTERTABLE_RESOLUTION); //8580 Resonance-DAC (1/Q) curve constexpr auto createRes8580() { res_array_t arr {}; for (int i=0; i5 ? 8.0 / i : 1.41) * Magnitude; } return arr; } static constexpr auto Resonances8580 = createRes8580(); static constexpr auto Resonances6581 = createRes6581(); #else // 8580 Resonance-DAC (1/Q) curve: Magnitude:$1000 static const res_array_t Resonances8580 = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0x16A0,0x14BF,0x1306,0x1172,0x1000,0x0EAC,0x0D74,0x0C56,0x0B50,0x0A5F,0x0983,0x08B9,0x0800,0x0756,0x06BA,0x062B, //0xFF, 0xFE, 0xFC, 0xF8, 0xF0, 0xE8, 0xD5, 0xC5, 0xB3, 0xA4, 0x97, 0x8A, 0x80, 0x77, 0x6E, 0x66 <- calculated then refined manually to sound best }; // 6581 Resonance-DAC (1/Q) curve: Magnitude:$1000 static const res_array_t Resonances6581 = { // 0 1 2 3 4 5 6 7 8 9 A B C D E F 0x168F,0x168F,0x168F,0x168F,0x168F,0x168F,0x1555,0x1249,0x1000,0x0E38,0x0CCC,0x0BA2,0x0AAA,0x09D8,0x0924,0x0888, //0xFF, 0xFE, 0xFD, 0xFC, 0xFB, 0xF9, 0xF6, 0xF2, 0xEC, 0xE4, 0xCD, 0xBA, 0xAB, 0x9E, 0x92, 0x86 <- calculated then refined manually to sound best }; #endif libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/Filter.cpp0000644000175100017510000002165215175333711020742 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2025-2026 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // Based on cRSID lightweight RealSID by Hermit (Mihaly Horvath) #include "Filter.h" #include "sl_defs.h" #include "sl_constants.h" #include "filt_tables.h" #include "sl_constants.h" #include "sl_settings.h" #include #include #include namespace SIDLite { constexpr int VOLUME_MAX = 0xF; constexpr int CHANNELS = 3+1; constexpr int SID_FULLVOLUME = CHANNELS*VOLUME_MAX; /*64*/ constexpr int CRSID_PRESAT_ATT_NOM = 20; constexpr int CRSID_PRESAT_ATT_DENOM = 16; constexpr int SID_CUTOFF_BITS = 11; constexpr int SID_CUTOFF_RANGE = (1 << SID_CUTOFF_BITS); constexpr int SID_CUTOFF_MAX = SID_CUTOFF_RANGE - 1; constexpr int FRACTIONAL_BITS = 12; constexpr int FRACTIONAL_SHIFTS = FRACTIONAL_BITS; constexpr int CRSID_FILTERTABLE_RESOLUTION = 12; constexpr int CRSID_FILTERTABLE_SHIFTS = CRSID_FILTERTABLE_RESOLUTION; constexpr int CRSID_FILTERTABLE_MAGNITUDE = 1 << CRSID_FILTERTABLE_RESOLUTION; constexpr int D418_DIGI_VOL = 1*16; constexpr int D418_DIGI_MUL = D418_DIGI_VOL / CRSID_WAVGEN_PREDIV; constexpr int VUMETER_LOWPASS_DIV = 16; constexpr int VUMETER_DIVSHIFTS = 4 - CRSID_WAVGEN_PRESHIFT; constexpr int Attenuation = ((SID_FULLVOLUME+26) * CRSID_PRESAT_ATT_NOM) / (CRSID_PRESAT_ATT_DENOM * CRSID_WAVGEN_PREDIV); int Filter::clock(int FilterInput, int NonFiltered) { enum SIDspecs { HIGHPASS_BITVAL=0x40, BANDPASS_BITVAL=0x20, LOWPASS_BITVAL=0x10 }; //Filter unsigned char FilterSwitchReso = regs[0x17]; unsigned char VolumeBand = regs[0x18]; int Cutoff = (regs[0x16] << 3) + (regs[0x15] & 7); int Resonance = FilterSwitchReso >> 4; if (LIKELY(s->is8580())) { Cutoff = CutoffMul8580[Cutoff]; Resonance = Resonances8580[Resonance]; } else { // 6581 // MOSFET-VCR control-voltage calculation (resistance-modulation aka 6581 filter distortion) emulation Cutoff += (FilterInput*105)>>16; if (Cutoff > SID_CUTOFF_MAX) Cutoff = SID_CUTOFF_MAX; else if (Cutoff < 0) Cutoff = 0; Cutoff = CutoffMul6581[Cutoff]; Resonance = Resonances6581[Resonance]; } int FilterOutput = 0; { int Tmp = FilterInput + ((PrevBandPass * Resonance) / CRSID_FILTERTABLE_MAGNITUDE) + PrevLowPass; if (VolumeBand & HIGHPASS_BITVAL) FilterOutput -= Tmp; Tmp = PrevBandPass - ((Tmp * Cutoff) / CRSID_FILTERTABLE_MAGNITUDE); PrevBandPass = Tmp; if (VolumeBand & BANDPASS_BITVAL) FilterOutput -= Tmp; Tmp = PrevLowPass + ((Tmp * Cutoff) / CRSID_FILTERTABLE_MAGNITUDE); PrevLowPass = Tmp; if (VolumeBand & LOWPASS_BITVAL) FilterOutput += Tmp; } // Output stage // For $D418 volume-register digi playback: an AC / DC separation for $D418 value // at low (20Hz or so) cutoff-frequency, sending AC (highpass) value // to a 4th 'digi' channel mixed to the master output, and set ONLY // the DC (lowpass) value to the volume-control. // This solved 2 issues: // Thanks to the lowpass filtering of the volume-control, // SID tunes where digi is played together with normal SID channels // won't sound distorted anymore, // the volume-clicks disappear when setting SID-volume. // (This is useful for fade-in/out tunes like Hades Nebula, where clicking ruins the intro.) int MainVolume; int Digi = 0; if (LIKELY(s->getRealSIDmode())) { int Tmp = (signed int)((VolumeBand & 0xF) << FRACTIONAL_SHIFTS); // highpass is digi, adding it to output must be before digifilter-code Digi = (Tmp - PrevVolume) * D418_DIGI_MUL; // arithmetic shift amount determines digi lowpass-frequency PrevVolume += (Tmp - PrevVolume) / 1024; // lowpass is main volume MainVolume = PrevVolume >> FRACTIONAL_SHIFTS; } else MainVolume = VolumeBand & 0xF; int Output = ((NonFiltered+FilterOutput) * MainVolume) + Digi;// / ((CHANNELS*VOLUME_MAX) + Attenuation); if (UNLIKELY(!++VUmeterUpdateCounter)) { // average level (for VU-meter) Level += ((std::abs(Output) >> VUMETER_DIVSHIFTS) - Level) / VUMETER_LOWPASS_DIV; } return Output / Attenuation; // master output } Filter::Filter(settings *s, unsigned char *regs) : regs(regs), s(s) { reset(); } void Filter::reset() { PrevLowPass = PrevBandPass = PrevVolume = 0; Level = 0; VUmeterUpdateCounter = 0; } constexpr int CF_LEN = 0x800; using co_tab_t = std::array; using co_cache_t = std::map; static co_cache_t CUTOFF_CACHE_8580; static co_cache_t CUTOFF_CACHE_6581; static std::mutex CUTOFF_CACHE_Lock; void Filter::rebuildCutoffTables(unsigned short samplerate) { constexpr int Magnitude = (1 << CRSID_FILTERTABLE_RESOLUTION); std::lock_guard lock(CUTOFF_CACHE_Lock); //8580 { co_cache_t::iterator lb = CUTOFF_CACHE_8580.lower_bound(samplerate); if (lb != CUTOFF_CACHE_8580.end() && !(CUTOFF_CACHE_8580.key_comp()(samplerate, lb->first))) { auto ct = &(lb->second); CutoffMul8580 = ct->data(); } else { co_tab_t cutoff_tab; const double cutoff_ratio_8580 = -2 * 3.14159 * (12500 / 2048) / samplerate; //8580 Cutoff-curve (for samplerate) for (int i=0; isecond); CutoffMul8580 = ct->data(); } } //6581 { co_cache_t::iterator lb = CUTOFF_CACHE_6581.lower_bound(samplerate); if (lb != CUTOFF_CACHE_6581.end() && !(CUTOFF_CACHE_6581.key_comp()(samplerate, lb->first))) { auto ct = &(lb->second); CutoffMul6581 = ct->data(); } else { co_tab_t cutoff_tab; // cca 1.5 MOhm Rshunt across VCR FET drain and source // (causing 220Hz bottom cutoff with 470pF integrator capacitors in old C64) constexpr double VCR_SHUNT_6581 = 1500.; // kOhm // Vth (on cutoff numeric range 0..2048) for the VCR cutoff-frequency control FET // below which it doesn't conduct constexpr int VCR_FET_TRESHOLD = 192; // filter capacitor value for 6581 constexpr double CAP_6581 = 0.470; // nF // the bigger the value, the darker the filter control is // (that is, cutoff frequency increases less with the same cutoff-value) constexpr double FILTER_DARKNESS_6581 = 22.0; // the bigger the value the more of resistance-modulation // (filter distortion) is applied for 6581 cutoff-control //constexpr double FILTER_DISTORTION_6581 = 0.0016; constexpr double cap_6581_reciprocal = -1000000. / CAP_6581; // pre-scale for 0...2048 cutoff-value range constexpr double cutoff_steepness_6581 = FILTER_DARKNESS_6581 * (2048-VCR_FET_TRESHOLD); // 6581 Cutoff-curve: (for samplerate) for (int i=0; isecond); CutoffMul6581 = ct->data(); } } } } libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/SID.h0000644000175100017510000000347615175333711017605 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2025-2026 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // Based on cRSID lightweight RealSID by Hermit (Mihaly Horvath) #ifndef SIDLITE_SID_H #define SIDLITE_SID_H #include "ADSR.h" #include "Filter.h" #include "WavGen.h" #include "sl_settings.h" #include namespace SIDLite { class SID { public: enum class model_t { MOS6581, MOS8580 }; public: SID(); void reset(); void write(int addr, int value); int read(int addr) const; int clock(unsigned int cycles, short* buf); void setChipModel(model_t model); void setRealSIDmode(bool mode); bool setSamplingParameters(unsigned int clockFrequency, unsigned short samplingFrequency); int getLevel() const { return filter.getLevel(); } private: unsigned char regs[0x20] = {0}; ADSR adsr; Filter filter; WavGen wavgen; settings s; short SampleCycleCnt; private: inline bool generateSample(unsigned int &cycles, short &output); }; } #endif // SIDLITE_SID_H libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/sl_settings.h0000644000175100017510000000264315175333711021517 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2026 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // Based on cRSID lightweight RealSID by Hermit (Mihaly Horvath) #ifndef SIDLITE_SETTINGS_H #define SIDLITE_SETTINGS_H namespace SIDLite { class SID; class settings { friend class SID; public: inline bool is8580() const { return sid8580; } inline unsigned short getSampleClockRatio() const { return SampleClockRatio; } inline bool getRealSIDmode() const { return RealSIDmode; } private: unsigned short SampleClockRatio; // ratio of CPU-clock and samplerate bool sid8580 = true; // SID model 8580 or 6581 bool RealSIDmode = true; }; } #endif libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/WavGen.h0000644000175100017510000000350515175333711020346 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2025-2026 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // Based on cRSID lightweight RealSID by Hermit (Mihaly Horvath) #ifndef SIDLITE_WAVGEN_H #define SIDLITE_WAVGEN_H #include namespace SIDLite { class ADSR; class settings; using wg_output_t = std::pair; class WavGen { public: WavGen(settings *s, unsigned char *regs); void reset(); wg_output_t clock(const ADSR *adsr); inline unsigned char getOsc3() const { return oscReg; } inline unsigned char getEnv3() const { return envReg; } private: unsigned char *regs; settings *s; int PhaseAccu[3]; // 28bit precision instead of 24bit int PrevPhaseAccu[3]; // (integerized ClockRatio fractionals, WebSID has similar solution) unsigned int NoiseLFSR[3]; unsigned int PrevWavGenOut[3]; unsigned char PrevWavData[3]; signed char PrevSounDemonDigiWF[3]; unsigned int RingSourceMSB; unsigned char SyncSourceMSBrise; unsigned char oscReg; unsigned char envReg; }; } #endif // SIDLITE_WAVGEN_H libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/ADSR.h0000644000175100017510000000255515175333711017714 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2025-2026 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // Based on cRSID lightweight RealSID by Hermit (Mihaly Horvath) #ifndef SIDLITE_ADSR_H #define SIDLITE_ADSR_H namespace SIDLite { class ADSR { public: explicit ADSR(unsigned char *regs); void reset(); void clock(char cycles); inline unsigned char counter(int channel) const { return EnvelopeCounter[channel]; } private: unsigned char *regs; unsigned short RateCounter[3]; unsigned char ADSRstate[3]; unsigned char EnvelopeCounter[3]; unsigned char ExponentCounter[3]; }; } #endif // SIDLITE_ADSR_H libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/Filter.h0000644000175100017510000000321215175333711020377 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2025-2026 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // Based on cRSID lightweight RealSID by Hermit (Mihaly Horvath) #ifndef SIDLITE_FILTER_H #define SIDLITE_FILTER_H namespace SIDLite { class settings; class Filter { public: Filter(settings *s, unsigned char *regs); void reset(); int clock(int FilterInput, int NonFiltered); inline int getLevel() const { return Level; } void rebuildCutoffTables(unsigned short samplerate); private: unsigned char *regs; settings *s; unsigned short *CutoffMul8580; unsigned short *CutoffMul6581; signed int PrevVolume; // lowpass-filtered version of Volume-band register int PrevLowPass; int PrevBandPass; int Level; // filtered version, good for VU-meter display unsigned char VUmeterUpdateCounter; }; } #endif // SIDLITE_FILTER_H libsidplayfp-3.0.0/src/builders/sidlite-builder/sidlite/WavGen.cpp0000644000175100017510000004316015175333711020702 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2025-2026 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ // Based on cRSID lightweight RealSID by Hermit (Mihaly Horvath) #include "WavGen.h" #include "ADSR.h" #include "sl_defs.h" #include "sl_constants.h" #include "sl_settings.h" #include "cw_tables.h" namespace SIDLite { enum WaveFormBits { NOISE_BITVAL = 0x80, PULSE_BITVAL = 0x40, SAW_BITVAL = 0x20, TRI_BITVAL = 0x10, // combined waveforms PULSAWTRI_VAL = PULSE_BITVAL|SAW_BITVAL|TRI_BITVAL, PULSAW_VAL = PULSE_BITVAL|SAW_BITVAL, PULTRI_VAL = PULSE_BITVAL|TRI_BITVAL, SAWTRI_VAL = SAW_BITVAL|TRI_BITVAL }; enum ControlBits { TEST_BITVAL = 0x08, RING_BITVAL = 0x04, SYNC_BITVAL = 0x02, GATE_BITVAL = 0x01 }; constexpr int CRSID_WAVE_RESOLUTION = 16; constexpr int OSC3_WAVE_RESOLUTION = 8; constexpr int COMBINEDWF_SAMPLE_RESOLUTION = 12; //bits constexpr int SID_PHASEACCU_RESOLUTION = 24; constexpr int PHASEACCU_SID__RANGE = 1 << SID_PHASEACCU_RESOLUTION; constexpr int PHASEACCU_RANGE = (PHASEACCU_SID__RANGE << CRSID_CLOCK_FRACTIONAL_BITS); constexpr int PHASEACCU_MAX = PHASEACCU_RANGE - 1; constexpr int PHASEACCU_ANDMASK = PHASEACCU_MAX; constexpr int PHASEACCU_MSB_BITVAL = (PHASEACCU_SID__RANGE >> 1) << CRSID_CLOCK_FRACTIONAL_BITS; constexpr int SID_NOISE_CLOCK_BITVAL = 0x100000; constexpr int NOISE_CLOCK = (SID_NOISE_CLOCK_BITVAL << CRSID_CLOCK_FRACTIONAL_BITS); constexpr int CRSID_WAVE_RANGE = 1 << CRSID_WAVE_RESOLUTION; constexpr int CRSID_WAVE_MID = CRSID_WAVE_RANGE / 2; constexpr int CRSID_WAVE_MIN = 0x0000; constexpr int CRSID_WAVE_MAX = CRSID_WAVE_RANGE - 1; constexpr int CRSID_WAVE_MASK = CRSID_WAVE_MAX; constexpr int CRSID_WAVE_SHIFTS = (SID_PHASEACCU_RESOLUTION - CRSID_WAVE_RESOLUTION) + CRSID_CLOCK_FRACTIONAL_BITS; constexpr int STEEPNESS_FRACTION_SHIFTS = 16; constexpr int STEEPNESS_STEPLIMIT = 256 << CRSID_CLOCK_FRACTIONAL_BITS; constexpr int COMBINEDWF_SAMPLE_SHIFTS = (SID_PHASEACCU_RESOLUTION - COMBINEDWF_SAMPLE_RESOLUTION) + CRSID_CLOCK_FRACTIONAL_BITS; // 16 constexpr int WAVE_OSC3_SHIFTS = CRSID_WAVE_RESOLUTION - OSC3_WAVE_RESOLUTION; //8 constexpr int SOUNDEMON_DIGI_SEEK_WAVEFORM = 0x01; constexpr int SOUNDEMON_DIGI_RESOLUTION = 8; constexpr int SOUNDEMON_DIGI_SHIFTS = (CRSID_WAVE_RESOLUTION - SOUNDEMON_DIGI_RESOLUTION); constexpr int SOUNDEMON_CARRIER_ELIMINATION_SAMPLECOUNT = 2; constexpr int SID_ENVELOPE_RESOLUTION = 8; constexpr int SID_ENVELOPE_MAGNITUDE = 1 << SID_ENVELOPE_RESOLUTION; //256 constexpr int ENVELOPE_MAGNITUDE_DIV = SID_ENVELOPE_MAGNITUDE * CRSID_WAVGEN_PREDIV; //256 * 1..16 = 256..4096 constexpr int OFF3_BITVAL = 0x80; // used at output of ADSR envelope generator // (not used for wave-generator because of 8bit-only resolution) static const unsigned char ADSR_DAC_6581[] = { 0x00,0x02,0x03,0x04,0x05,0x06,0x07,0x09,0x09,0x0B,0x0B,0x0D,0x0D,0x0F,0x10,0x12, 0x11,0x13,0x14,0x15,0x16,0x17,0x18,0x1A,0x1A,0x1C,0x1C,0x1E,0x1E,0x20,0x21,0x23, 0x21,0x23,0x24,0x25,0x26,0x27,0x28,0x2A,0x2A,0x2C,0x2C,0x2E,0x2E,0x30,0x31,0x33, 0x32,0x34,0x35,0x36,0x37,0x38,0x39,0x3B,0x3B,0x3D,0x3D,0x3F,0x3F,0x41,0x42,0x44, 0x40,0x42,0x42,0x44,0x44,0x46,0x47,0x49,0x49,0x4A,0x4B,0x4D,0x4D,0x4F,0x50,0x52, 0x51,0x53,0x53,0x55,0x55,0x57,0x58,0x5A,0x5A,0x5B,0x5C,0x5E,0x5E,0x60,0x61,0x63, 0x61,0x62,0x63,0x65,0x65,0x67,0x68,0x6A,0x69,0x6B,0x6C,0x6E,0x6E,0x70,0x71,0x73, 0x72,0x73,0x74,0x76,0x76,0x78,0x79,0x7B,0x7A,0x7C,0x7D,0x7F,0x7F,0x81,0x82,0x84, 0x7B,0x7D,0x7E,0x80,0x80,0x82,0x83,0x85,0x84,0x86,0x87,0x89,0x89,0x8B,0x8C,0x8D, 0x8C,0x8E,0x8F,0x91,0x91,0x93,0x94,0x96,0x95,0x97,0x98,0x9A,0x9A,0x9C,0x9D,0x9E, 0x9C,0x9E,0x9F,0xA1,0xA1,0xA3,0xA4,0xA5,0xA5,0xA7,0xA8,0xAA,0xAA,0xAC,0xAC,0xAE, 0xAD,0xAF,0xB0,0xB2,0xB2,0xB4,0xB5,0xB6,0xB6,0xB8,0xB9,0xBB,0xBB,0xBD,0xBD,0xBF, 0xBB,0xBD,0xBE,0xC0,0xC0,0xC2,0xC2,0xC4,0xC4,0xC6,0xC7,0xC8,0xC9,0xCA,0xCB,0xCD, 0xCC,0xCE,0xCF,0xD1,0xD1,0xD3,0xD3,0xD5,0xD5,0xD7,0xD8,0xD9,0xDA,0xDB,0xDC,0xDE, 0xDC,0xDE,0xDF,0xE1,0xE1,0xE3,0xE3,0xE5,0xE5,0xE7,0xE8,0xE9,0xEA,0xEB,0xEC,0xEE, 0xED,0xEF,0xF0,0xF2,0xF2,0xF4,0xF4,0xF6,0xF6,0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFF }; static inline unsigned short getCombinedPW(const unsigned char* channelptr) { // PW=000..FFF (range for combined-waveform lookup) from SID-register (000..FFF) return ((channelptr[3]&0xF) << 8) | channelptr[2]; } static inline unsigned short getPW(const unsigned char* channelptr) { // PW=0000..FFF0 from SID-register (000..FFF) return getCombinedPW(channelptr) << 4; } static inline unsigned int getNoise(unsigned int nr) { return ((nr & 0x100000) >> 5) | ((nr & 0x40000) >> 4) | ((nr & 0x4000) >> 1) | ((nr & 0x800) << 1) | ((nr & 0x200) << 2) | ((nr & 0x20) << 5) | ((nr & 0x04) << 7) | ((nr & 0x01) << 8); } constexpr unsigned int NOISE_MASK = ( 0x100000 | 0x40000 | 0x4000 | 0x800 | 0x200 | 0x20 | 0x04 | 0x01 ); wg_output_t WavGen::clock(const ADSR *adsr) { // Waveform-generator (phase accumulator and waveform-selector) unsigned int WavGenOut = 0; unsigned char EnvOut = 0; int FilterInput = 0; int NonFiltered = 0; const unsigned char FilterSwitchReso = regs[0x17]; const unsigned char VolumeBand = regs[0x18]; for (int Channel=0; Channelis8580() && WFarray!=PulseTriangle)) oscval &= COMBINEDWF_OSC_MSB_OFF_MASK; unsigned char Pitch = (LIKELY(ChannelPtr[1])) ? ChannelPtr[1] : 1; // avoid division by zero unsigned short Filt = 0x7777 + (0x8888/Pitch); PrevWavData[Channel] = (WFarray[oscval]*Filt + PrevWavData[Channel]*(COMBINEDWF_FILTMUL_MAX-Filt)) >> COMBINEDWF_FILT_FRACTION_SHIFTS; return PrevWavData[Channel] << COMBINEDWF_WAVE_SHIFTS; }; const unsigned char WF = ChannelPtr[4]; const unsigned char TestBit = (UNLIKELY((WF & TEST_BITVAL) != 0)); int *PhaseAccuPtr = &(PhaseAccu[Channel]); const unsigned int PhaseAccuStep = ((ChannelPtr[1]<<8) | ChannelPtr[0]) * s->getSampleClockRatio(); if (UNLIKELY(TestBit || ((WF & SYNC_BITVAL) && SyncSourceMSBrise))) *PhaseAccuPtr = 0; else { // stepping phase-accumulator (oscillator) *PhaseAccuPtr += PhaseAccuStep; if (UNLIKELY(*PhaseAccuPtr >= PHASEACCU_RANGE)) *PhaseAccuPtr -= PHASEACCU_RANGE; // 0x10000000 } *PhaseAccuPtr &= PHASEACCU_ANDMASK; // 0xFFFFFFF const unsigned int MSB = *PhaseAccuPtr & PHASEACCU_MSB_BITVAL; // 0x8000000 SyncSourceMSBrise = (UNLIKELY(MSB > (PrevPhaseAccu[Channel] & PHASEACCU_MSB_BITVAL))) ? 1 : 0; // switch-case encourages computed-goto compiler-optimization switch (WF & 0xF0) { case NOISE_BITVAL: { //noise waveform int Tmp = NoiseLFSR[Channel]; // clock LFSR all time if clockrate exceeds observable at given samplerate (last term): if (UNLIKELY( ((*PhaseAccuPtr & NOISE_CLOCK) != (PrevPhaseAccu[Channel] & NOISE_CLOCK)) || (PhaseAccuStep >= NOISE_CLOCK))) { int Feedback = ((Tmp & 0x400000) ^ ((Tmp & 0x20000) << 5)) != 0; // TEST-bit turns all bits in noise LFSR to 1 // (on real SID slowly, in approx. 8000 microseconds ~ 300 samples) Tmp = ((Tmp << 1) | Feedback|TestBit) & 0x7FFFFF; NoiseLFSR[Channel] = Tmp; } WavGenOut = getNoise(Tmp); } break; case PULSE_BITVAL: { //simple pulse unsigned int PW = getPW(ChannelPtr); // PW=0000..FFF0 from SID-register unsigned int Utmp = (int)(PhaseAccuStep >> (CRSID_WAVE_SHIFTS+1)); // Too thin pulsewidth? Correct... if (UNLIKELY(0 < PW && PW < Utmp)) PW = Utmp; Utmp ^= CRSID_WAVE_MAX; // Too thin pulsewidth? Correct it to a value representable at the current samplerate if (UNLIKELY(PW > Utmp)) PW = Utmp; Utmp = *PhaseAccuPtr >> CRSID_WAVE_SHIFTS; // 12 // rising/falling-edge steepness (add/sub at samples) int Steepness = (PhaseAccuStep>=STEEPNESS_STEPLIMIT) ? PHASEACCU_MAX/PhaseAccuStep : CRSID_WAVE_MAX; if (UNLIKELY(TestBit)) WavGenOut = CRSID_WAVE_MAX; // 0xFFFF; else if (Utmp CRSID_WAVE_MAX) PulsePeak = CRSID_WAVE_MAX; // but adequately thick trapezoid pulses reach the maximum level int Tmp = PulsePeak - (PW-Utmp) * Steepness; // draw the slope from the peak WavGenOut = (LIKELY(Tmp CRSID_WAVE_MAX) PulsePeak = CRSID_WAVE_MAX; // adequately thick trapezoid pulses reach the maximum level int Tmp = (CRSID_WAVE_MAX-Utmp) * Steepness - PulsePeak; // draw the slope from the peak WavGenOut = (LIKELY(Tmp>=0)) ? CRSID_WAVE_MAX : Tmp; // but stop at max-level } } break; case PULSAWTRI_VAL: { // pulse+saw+triangle (waveform nearly identical to tri+saw) unsigned int Utmp = *PhaseAccuPtr >> COMBINEDWF_SAMPLE_SHIFTS; // 16 WavGenOut = Utmp >= getCombinedPW(ChannelPtr) || UNLIKELY(TestBit) ? combinedWF(PulseSawTriangle, Utmp) : CRSID_WAVE_MIN; // 0 } break; case PULSAW_VAL: { // pulse+saw unsigned int Utmp = *PhaseAccuPtr >> COMBINEDWF_SAMPLE_SHIFTS; // 16 WavGenOut = Utmp >= getCombinedPW(ChannelPtr) //|| UNLIKELY(TestBit) ? combinedWF(PulseSawtooth, Utmp) : CRSID_WAVE_MIN; // 0 } break; case PULTRI_VAL: { // pulse+triangle int Tmp = *PhaseAccuPtr ^ ((WF&RING_BITVAL)? RingSourceMSB : 0); WavGenOut = (*PhaseAccuPtr >> COMBINEDWF_SAMPLE_SHIFTS) >= getCombinedPW(ChannelPtr) || UNLIKELY(TestBit) ? combinedWF(PulseTriangle, Tmp >> COMBINEDWF_SAMPLE_SHIFTS) : CRSID_WAVE_MIN; // 0 } break; case SAWTRI_VAL: { // saw+triangle WavGenOut = combinedWF(SawTriangle, *PhaseAccuPtr >> COMBINEDWF_SAMPLE_SHIFTS); } break; case SAW_BITVAL: { // sawtooth WavGenOut = *PhaseAccuPtr >> CRSID_WAVE_SHIFTS; // 12 // saw (this row would be enough for simple but aliased-at-high-pitch saw) int Steepness = (PhaseAccuStep>>CRSID_CLOCK_FRACTIONAL_BITS) / 288; // avoid division by zero in next steps if (UNLIKELY(Steepness == 0)) Steepness = 1; // 1st half (rising edge) of asymmetric triangle-like saw waveform WavGenOut += (WavGenOut * Steepness) >> STEEPNESS_FRACTION_SHIFTS; // 16 // 2nd half (falling edge, reciprocal steepness if (UNLIKELY(WavGenOut > CRSID_WAVE_MAX)) WavGenOut = CRSID_WAVE_MAX - (((WavGenOut-CRSID_WAVE_RANGE) << STEEPNESS_FRACTION_SHIFTS) / Steepness); } break; case TRI_BITVAL: { // triangle (this waveform has no harsh edges, so it doesn't suffer from strong aliasing at high pitches) if (LIKELY(!s->getRealSIDmode() || (PrevSounDemonDigiWF[Channel] <= 0))) { int Tmp = *PhaseAccuPtr ^ (UNLIKELY(WF&RING_BITVAL) ? RingSourceMSB : 0); WavGenOut = (Tmp ^ ((Tmp&PHASEACCU_MSB_BITVAL) ? PHASEACCU_MAX : 0)) >> (CRSID_WAVE_SHIFTS-1); // 11 } else { // SounDemon digi hack: if previous waveform was 01 don't modify output in this round, // so carrier noise won't be heard due to non 1MHz emulation WavGenOut = PrevWavGenOut[Channel]; --PrevSounDemonDigiWF[Channel]; } } break; case 0x00: // emulate waveform 00 floating wave-DAC (utilized by SounDemon digis) // (on real SID waveform00 decays after about 5 seconds, // here we just simply keep the value to avoid clicks) // (Our jittery 'seeking' waveform=$01 part of SounDemon-digi // is substituted directly by frequency-high register's value (as in SwinSID)) if (s->getRealSIDmode() && WF == SOUNDEMON_DIGI_SEEK_WAVEFORM) { WavGenOut = ChannelPtr[1] << SOUNDEMON_DIGI_SHIFTS; PrevSounDemonDigiWF[Channel] = SOUNDEMON_CARRIER_ELIMINATION_SAMPLECOUNT; } else WavGenOut = PrevWavGenOut[Channel]; break; default: { // we simply zero output when other waveform is mixed with noise. // LFSR continuously gets filled by zero and locks up. // ($C1 waveform with pw<8 can keep it for a while.) WavGenOut = CRSID_WAVE_MIN; bool shift = ((*PhaseAccuPtr & NOISE_CLOCK) != (PrevPhaseAccu[Channel] & NOISE_CLOCK)) || (PhaseAccuStep >= NOISE_CLOCK); if (!shift && !TestBit) { // noise writeback NoiseLFSR[Channel] &= ~NOISE_MASK; } else { int Tmp = NoiseLFSR[Channel]; Tmp = ((Tmp << 1) | TestBit) & 0x7FFFFF; NoiseLFSR[Channel] = Tmp; } } break; } WavGenOut &= CRSID_WAVE_MASK; // 0xFFFF PrevWavGenOut[Channel] = WavGenOut; PrevPhaseAccu[Channel] = *PhaseAccuPtr; RingSourceMSB = MSB; // routing the channel signal to either the filter or the unfiltered master output // depending on filter-switch SID-registers EnvOut = adsr->counter(Channel); unsigned char Envelope = (LIKELY(s->is8580())) ? EnvOut : ADSR_DAC_6581[EnvOut]; int swave = static_cast(WavGenOut) - CRSID_WAVE_MID; if (UNLIKELY(FilterSwitchReso & (1 << Channel))) { FilterInput += (swave * Envelope) / ENVELOPE_MAGNITUDE_DIV; } else if (LIKELY(Channel!=2 || !(VolumeBand & OFF3_BITVAL))) { NonFiltered += (swave * Envelope) / ENVELOPE_MAGNITUDE_DIV; } } // update readable SID1-registers (some SID tunes might use 3rd channel ENV3/OSC3 value as control) oscReg = WavGenOut >> WAVE_OSC3_SHIFTS; // OSC3, ENV3 (some players rely on it, unfortunately even for timing) envReg = EnvOut; // Envelope return std::make_pair(FilterInput, NonFiltered); } WavGen::WavGen(settings *s, unsigned char *regs) : regs(regs), s(s) { reset(); } void WavGen::reset() { for (int Channel=0; Channel> 4]; else if (*ADSRstatePtr & DECAYSUSTAIN_BITVAL) PrescalePeriod = ADSRprescalePeriods[AD & 0x0F]; else PrescalePeriod = ADSRprescalePeriods[SR & 0x0F]; *RateCounterPtr += cycles; if (UNLIKELY(*RateCounterPtr >= 0x8000)) // can wrap around (ADSR delay-bug: short 1st frame) *RateCounterPtr -= 0x8000; //*RateCounterPtr &= 0x7FFF; if (UNLIKELY(PrescalePeriod <= *RateCounterPtr && *RateCounterPtr < PrescalePeriod+cycles)) { // ratecounter shot (matches rateperiod) (in genuine SID ratecounter is LFSR) *RateCounterPtr -= PrescalePeriod; // reset rate-counter on period-match if ((*ADSRstatePtr & ATTACK_BITVAL) || ++(*ExponentCounterPtr) == ADSRexponentPeriods[*EnvelopeCounterPtr]) { *ExponentCounterPtr = 0; if (*ADSRstatePtr & HOLDZEROn_BITVAL) { if (*ADSRstatePtr & ATTACK_BITVAL) { ++(*EnvelopeCounterPtr); if (*EnvelopeCounterPtr == 0xFF) *ADSRstatePtr &= ~ATTACK_BITVAL; } else if (!(*ADSRstatePtr & DECAYSUSTAIN_BITVAL) || *EnvelopeCounterPtr != (SR&0xF0)+(SR>>4)) { --(*EnvelopeCounterPtr); // resid adds 1 cycle delay, we omit that mechanism here if (*EnvelopeCounterPtr == 0) *ADSRstatePtr &= ~HOLDZEROn_BITVAL; } } } } } } ADSR::ADSR(unsigned char *regs) : regs(regs) { reset(); } void ADSR::reset() { for (int Channel=0; Channel /* * The anatomy of combined waveforms: The resid source simply uses 4kbyte 8bit samples from wavetable arrays, * says these waveforms are mystic due to the analog behaviour. * It's true, the analog things inside SID play a significant role in how the combined waveforms look like, * but process variations are not so huge that cause much differences in SIDs. * After checking these waveforms by eyes, it turned out for me that these waveform are fractal-like, * recursively approachable waveforms. * My 1st thought and trial was to store only a portion of the waveforms in table, * and magnify them depending on phase-accumulator's state. * But I wanted to understand how these waveforms are produced. * I felt from the waveform-diagrams that the bits of the waveforms affect each other, * hence the recursive look. A short C code proved by assumption, * I could generate something like a pulse+saw combined waveform. * Recursive calculations were not feasible for MCU of SwinSID, * but for jsSID I could utilize what I found out and code below generates * the combined waveforms into wavetables. To approach the combined waveforms as much as possible, * I checked out the SID schematic that can be found at some reverse-engineering sites... * The SID's R-2R ladder WAVE DAC is driven by operation-amplifier like complementary FET output drivers, * so that's not the place where I first thought the magic happens. * These 'opamps' (for all 12 wave-bits) have single FETs as inputs, * and they switch on above a certain level of input-voltage, causing 0 or 1 bit as R-2R DAC input. * So the first keyword for the workings is TRESHOLD. * These FET inputs are driven through serial switch FETs (wave-selector) * that normally enables one waveform at a time. * The phase-accumulator's output is brought to 3 kinds of circuitries for the 3 basic waveforms. * The pulse simply drives all wave-selector inputs with a 0/1 depending on pulsewidth, * the sawtooth has a XOR for triangle/ringmod generation, but what * is common for all waveforms, they have an open-drain driver before the wave-selector, * which has FETs towards GND and 'FET resistor' towards the power-supply rail. * These outputs are clearly not designed to drive high loads, * and normally they only have to drive the FETs input mentioned above. * But when more of these output drivers are switched together by the switch-FETs in the wave-selector, * they affect each other by loading each other. * The pulse waveform, when selected, connects all of them together through a fairly strong connection, * and its signal also affects the analog level (pulls below the treshold)... * The farther a specific DAC bit driver is from the other, the less it affects its output. * It turned out it's not powers of 2 but something else, * that creates similar combined waveforms to that of real SID's... * Note that combined waveforms never have values bigger than their sourcing sawtooth wave. * The analog levels that get generated by the various bit drivers, that pull each other up/DOWN, * depend on the resistances the components/wires inside the SID. * And finally, what is output on the DAC depends on whether these analog levels * are below or above the FET gate's treshold-level, * That's how the combined waveform is generated. Maybe I couldn't explain well enough, * but the code below is simple enough to understand the mechanism algoritmically. * This simplified schematic example might make it easier to understand sawtooth+pulse combination * (must be observed with monospace fonts): * _____ |- .--------------. /\/\--. * Vsupply / .----| |---------*---|- / Vsupply ! R ! * ------. other ! ! _____ ! TRES \ \ ! / * ! saw bit *--!----| |---------' HOLD / ! |- 2R \ * / output ! ! ! |------|- / * Rd \ |- !WAVEFORM-SELECTOR *--*---|- ! R ! * / |- !SWITCHING FETs ! ! ! *---/\/\--* * ! saw-bit ! _____ |- ! --- ! ! * *------------------!-----| |-----------*-----|- ! |- / * ! (weak drive,so ! saw switch ! TRES-! `----------|- 2R \ * |- can be shifted ! ! HOLD ! ! / * -----|- down (& up?) ! _____ ! ! ! R ! * ! by neighbours) *-----| |-----------' --- --- /\/\-* * GND --- ! pulse switch ! * * As can be seen on this schematic, the pulse wave-selector FETs * connect the neighbouring sawtooth outputs with a fairly strong * connection to each other through their own wave-selector FETs. * So the adjacent sawtooth outputs pull each other lower * (or maybe a bit upper but not exceeding sawtooth line) * depending on their low/high state and distance from each other, causing * the resulting analog level that will either turn the output on or not. * (Depending on their relation to treshold.) * * (As triangle waveform connects adjacent bits by default, the above explained effect becomes even stronger, * that's why combined waveforms with thriangle are at 0 level most of the time.) */ constexpr int CwLength = 4096; using cw_array_t = std::array; #if 0//__cplusplus >= 201703L constexpr int cabs(int x) { return (x>0) ? x : -x; } constexpr double cpow(double base, int exp) { return exp == 0 ? 1.f : base * cpow(base, exp-1); } constexpr auto createCombinedWF(double bitmul, double bitstrength, double treshold) { cw_array_t WFarray {}; for (int i=0; i((i >> j) & 1); for (int k=0; k<12; k++) if (((i >> k) & 1) == 0) bitlevel -= bitmul / cpow(bitstrength, cabs(k-j)); b += (bitlevel>=treshold) ? 1 << j : 0; } WFarray[i] = b >> 4; } return WFarray; } constexpr auto createPulseTriangle(const cw_array_t &PulseSawtooth) { //Pulse + Triangle is the same as Pulse + Saw but twice with second half mirrored on time-axis cw_array_t WFarray {}; constexpr int half = CwLength/2; for (int i=0; i #include "sidplayfp/SidConfig.h" #include "sidemu.h" #include "Event.h" #include "EventScheduler.h" #include "sidplayfp/siddefs.h" #include "driver/src/USBSID.h" #include "sidcxx11.h" #ifdef HAVE_CONFIG_H # include "config.h" #endif namespace libsidplayfp { /*************************************************************************** * USBSID SID Specialisation ***************************************************************************/ class USBSID final : public sidemu, private Event//, public USBSIDBuilder { private: /* USBSID specific data */ USBSID_NS::USBSID_Class &m_sid; int m_handle; int sidno; uint8_t busValue; /* Return value on read */ SidConfig::sid_model_t runmodel; /* Read model type */ event_clock_t delay(); /* Event */ public: static const char* getCredits(); public: explicit USBSID(sidbuilder *builder); ~USBSID() override; /* static variables required due to * multiple class initializations */ static long raster_rate; static event_clock_t m_delayClk; bool getStatus() const { return m_status; } uint8_t read(uint_least8_t addr) override; void write(uint_least8_t addr, uint8_t data) override; /* c64sid functions */ void reset(uint8_t volume) override; /* Standard SID functions */ void clock() override {}; void sampling(float systemclock, float freq, SidConfig::sampling_method_t method) override; void model(SidConfig::sid_model_t model, MAYBE_UNUSED bool digiboost) override; /* USBSID specific */ void flush(void); /* ISSUE: Disabled, blocks playing */ // Must lock the SID before using the standard functions. // bool lock(EventScheduler *env) override; // void unlock() override; private: // Fixed interval timer delay to prevent sidplay2 // shoot to 100% CPU usage when song no longer // writes to SID. void event() override; }; } #endif // USBSID_EMU_H libsidplayfp-3.0.0/src/builders/usbsid-builder/driver/0000755000175100017510000000000015175333725016562 5libsidplayfp-3.0.0/src/builders/usbsid-builder/driver/src/0000755000175100017510000000000015175333725017351 5libsidplayfp-3.0.0/src/builders/usbsid-builder/driver/src/USBSID.h0000644000175100017510000004512015175333713020432 /* * USBSID-Pico is a RPi Pico (RP2040/RP2350) based board for interfacing one * or two MOS SID chips and/or hardware SID emulators over (WEB)USB with your * computer, phone or ASID supporting player. * * USBSID.h * This file is part of USBSID-Pico (https://github.com/LouDnl/USBSID-Pico-driver) * File author: LouD * * Copyright (c) 2024-2025 LouD * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #ifndef _USBSID_H_ #define _USBSID_H_ #if defined(__linux__) || defined(__linux) || defined(linux) || defined(__unix__) || defined(__APPLE__) #define __US_LINUX_COMPILE #elif defined(_WIN32) || defined(_WIN64) || defined(__MINGW32__) || defined(__MINGW64__) #define __US_WINDOWS_COMPILE #endif /** * @brief Fix for CLANG64 and CLANGARM64 builds * @ref https://github.com/LouDnl/USBSID-Pico-driver/issues/11 * @ref https://github.com/msys2/MINGW-packages/actions/runs/21104083635 */ #if defined(__US_WINDOWS_COMPILE) /* Detect ARM64 across various compiler defines */ #if defined(__aarch64__) || defined(_M_ARM64) || defined(__arm__) || defined(_M_ARM) || defined(_ARM_) /* libusb on Windows typically expects WINAPI (stdcall) on x86, but Clang on ARM64 must treat this as empty. */ #undef WINAPI #define WINAPI #undef LIBUSB_CALL #define LIBUSB_CALL #else #ifndef WINAPI #define WINAPI __stdcall #endif #ifndef LIBUSB_CALL #define LIBUSB_CALL WINAPI #endif #endif #endif /* Fallback for other platforms */ #ifndef LIBUSB_CALL #define LIBUSB_CALL #endif #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-variable" #ifdef __cplusplus #include #include #include #include #include #include #include #else #include #include #include #include #include #include #include #endif /** * @brief Fix for CLANG64 and CLANGARM64 builds * @ref https://github.com/LouDnl/USBSID-Pico-driver/issues/11 * @ref https://github.com/msys2/MINGW-packages/actions/runs/21104083635 */ #if defined(__clang__) && defined(__MINGW32__) #if defined(__x86_64__) || defined(__aarch64__) #include #endif #endif /* Optional driver start and driver exit commands * * Some players do weird things on start, choose * any of these to suit your own needs * */ // #define US_RESET_ON_ENTRY /* Send Reset SID command on LIBUSB Entry */ // #define US_CLEARBUS_ON_ENTRY /* Send Clear Bus command on LIBUSB Entry */ // #define US_UNMUTE_ON_ENTRY /* Send UnMute SID command on LIBUSB Exit */ // #define US_MUTE_ON_EXIT /* Send Mute SID command on LIBUSB Exit */ // #define US_RESET_ON_EXIT /* Send Reset SID command on LIBUSB Exit */ /* Uncomment for debug logging */ // #define USBSID_DEBUG #ifdef USBSID_DEBUG #define USBDBG(...) fprintf(__VA_ARGS__) #else #define USBDBG(...) ((void)0) #endif #define USBERR(...) fprintf(__VA_ARGS__) using namespace std; /* Pre-define libusb structs */ struct libusb_context; struct libusb_transfer; namespace USBSID_NS { /* pre-declaration for static functions */ class USBSID_Class; /* LIBUSB/USBSID related */ enum { VENDOR_ID = 0xCAFE, PRODUCT_ID = 0x4011, ACM_CTRL_DTR = 0x01, ACM_CTRL_RTS = 0x02, EP_OUT_ADDR = 0x02, EP_IN_ADDR = 0x82, LEN_IN_BUFFER = 1, LEN_OUT_BUFFER = 64, #ifdef DEBUG_USBSID_MEMORY LEN_TMP_BUFFER = 4 #endif }; enum { /* BYTE 0 - top 2 bits */ WRITE = 0, /* 0b0 ~ 0x00 */ READ = 1, /* 0b1 ~ 0x40 */ CYCLED_WRITE = 2, /* 0b10 ~ 0x80 */ COMMAND = 3, /* 0b11 ~ 0xC0 */ /* BYTE 0 - lower 6 bits for byte count */ /* BYTE 0 - lower 6 bits for Commands */ PAUSE = 10, /* 0b1010 ~ 0x0A */ UNPAUSE = 11, /* 0b1011 ~ 0x0B */ MUTE = 12, /* 0b1100 ~ 0x0C */ UNMUTE = 13, /* 0b1101 ~ 0x0D */ RESET_SID = 14, /* 0b1110 ~ 0x0E */ DISABLE_SID = 15, /* 0b1111 ~ 0x0F */ ENABLE_SID = 16, /* 0b10000 ~ 0x10 */ CLEAR_BUS = 17, /* 0b10001 ~ 0x11 */ CONFIG = 18, /* 0b10010 ~ 0x12 */ RESET_MCU = 19, /* 0b10011 ~ 0x13 */ BOOTLOADER = 20, /* 0b10100 ~ 0x14 */ }; /* Thread related */ static int run_thread; /* Fake C64 Memory */ #ifdef DEBUG_USBSID_MEMORY static uint8_t sid_memory[0x20]; static uint8_t sid_memory_changed[0x20]; static uint16_t sid_memory_cycles[0x20]; #endif /* LIBUSB related */ static struct libusb_device_handle *devh = NULL; static struct libusb_transfer *transfer_out = NULL; /* OUT-going transfers (OUT from host PC to USB-device) */ static struct libusb_transfer *transfer_in = NULL; /* IN-coming transfers (IN to host PC from USB-device) */ static libusb_context *ctx = NULL; static bool in_buffer_dma = false; static bool out_buffer_dma = false; static bool threaded = false; static bool withcycles = false; static int rc, read_completed, write_completed; /* USB buffer related */ static uint8_t * __restrict__ in_buffer; /* incoming libusb will reside in this buffer */ static uint8_t * __restrict__ out_buffer; /* outgoing libusb will reside in this buffer */ static uint8_t * __restrict__ thread_buffer; /* data to be transfered to the out_buffer will reside in this buffer */ static uint8_t * __restrict__ write_buffer; /* non async data will be written from this buffer */ #ifdef DEBUG_USBSID_MEMORY static uint8_t * __restrict__ temp_buffer; /* temp buffer for debug printing */ #endif static uint8_t * __restrict__ result; /* variable where read data is copied into */ static int len_out_buffer; /* changable variable for out buffer size */ static int buffer_pos = 1; /* current position of the out buffer */ static int flush_buffer = 0; /* flush buffer yes or no */ /* Ringbuffer related */ typedef struct { int ring_read; int ring_write; int is_allocated; uint8_t * __restrict__ ringbuffer; } ring_buffer_t; static ring_buffer_t us_ringbuffer; const int min_diff_size = 16; const int min_ring_size = 256; const int default_diff_size = 64; const int default_ring_size = 8192; /* Clock cycles per second * Clock speed: 0.985 MHz (PAL) or 1.023 MHz (NTSC) * * For some reason both 1022727 and 1022730 are * mentioned as NTSC clock cycles per second * Going for the rates specified by Vice it should * be 1022730, except in the link about raster time * on c64 wiki it's 1022727. * I chose to implement both, let's see how this * works out * * https://sourceforge.net/p/vice-emu/code/HEAD/tree/trunk/vice/src/c64/c64.h */ /* Clock cycles per second */ enum clock_speeds { DEFAULT = 1000000, /* 1 MHz = 1 us */ PAL = 985248, /* 0.985 MHz = 1.014973 us */ NTSC = 1022727, /* 1.023 MHz = 0.977778 us */ DREAN = 1023440, /* 1.023 MHz = 0.977097 us */ NTSC2 = 1022730, /* 1.023 MHz = 0.977778 us */ }; /* Refreshrates (cycles) in microseconds */ enum refresh_rates { HZ_DEFAULT = 20000, /* 50Hz ~ 20000 == 20 us */ HZ_EU = 19950, /* 50Hz ~ 20000 == 20 us / 50.125Hz ~ 19.950124688279 exact */ HZ_US = 16715, /* 60Hz ~ 16667 == 16.67 us / 59.826Hz ~ 16.715140574332 exact */ }; /* Rasterrates (cycles) in microseconds * Source: https://www.c64-wiki.com/wiki/raster_time * * PAL: 1 horizontal raster line takes 63 cycles * or 504 pixels including side borders * whole screen consists of 312 horizontal lines * for a frame including upper and lower borders * 63 * 312 CPU cycles is 19656 for a complete * frame update @ 985248 Hertz * 985248 / 19656 = approx 50.12 Hz frame rate * * NTSC: 1 horizontal raster line takes 65 cycles * whole screen consists of 263 rasters per frame * 65 * 263 CPU cycles is 17096 for a complete * frame update @ 985248 Hertz * 1022727 / 17096 = approx 59.83 Hz frame rate * */ enum raster_rates { R_DEFAULT = 20000, /* 20us ~ fallback */ R_EU = 19656, /* PAL: 63 cycles * 312 lines = 19656 cycles per frame update @ 985248 Hz = 50.12 Hz frame rate */ R_US = 17096, /* NTSC: 65 cycles * 263 lines = 17096 cycles per frame update @ 1022727 Hz = 59.83 Hz Hz frame rate */ }; static const enum clock_speeds clockSpeed[] = { DEFAULT, PAL, NTSC, DREAN, NTSC2 }; static const enum refresh_rates refreshRate[] = { HZ_DEFAULT, HZ_EU, HZ_US, HZ_US, HZ_US }; static const enum raster_rates rasterRate[] = { R_DEFAULT, R_EU, R_US, R_US, R_US }; static long cycles_per_sec = DEFAULT; /* default @ 1000000 */ static long cycles_per_frame = HZ_DEFAULT; /* default @ 20000 */ static long cycles_per_raster = R_DEFAULT; /* default @ 20000 */ static int clk_retrieved = 0; static long us_clkrate = 0; static int numsids = 0; static int fmoplsid = -1; static int pcbversion = -1; static int socketconfig = -1; /* Object related */ static int us_Found = 0; static int instance = -1; /* Timing related */ typedef std::nano ratio_t; /* 1000000000 */ typedef std::chrono::steady_clock::time_point timestamp_t; /* Point in time */ typedef std::chrono::nanoseconds duration_t; /* Duration in nanoseconds */ #ifdef __cplusplus static std::atomic_int us_thread(0); #else static _Atomic int us_thread = 0; #endif static pthread_mutex_t us_mutex; class USBSID_Class { private: /* Driver related */ static bool us_Initialised; static bool us_Available; static bool us_PortIsOpen; int us_InstanceID; /* Timing related */ static double us_CPUcycleDuration; /* CPU cycle duration in nanoseconds */ static double us_InvCPUcycleDurationNanoSeconds; /* Inverted CPU cycle duration in nanoseconds */ static timestamp_t m_StartTime; /* That moment when... */ static timestamp_t m_LastTime; /* I know what you did last summer! */ /* Ringbuffer related */ static int diff_size; static int ring_size; /* LIBUSB */ int LIBUSB_Setup(bool start_threaded, bool with_cycles); int LIBUSB_Exit(void); int LIBUSB_Available(uint16_t vendor_id, uint16_t product_id); void LIBUSB_StopTransfers(void); int LIBUSB_OpenDevice(void); void LIBUSB_CloseDevice(void); int LIBUSB_DetachKernelDriver(void); int LIBUSB_ConfigureDevice(void); void LIBUSB_InitOutBuffer(void); void LIBUSB_FreeOutBuffer(void); void LIBUSB_InitInBuffer(void); void LIBUSB_FreeInBuffer(void); static void LIBUSB_CALL usb_out(struct libusb_transfer *transfer); static void LIBUSB_CALL usb_in(struct libusb_transfer *transfer); /* Line encoding ~ baud rate is ignored by TinyUSB */ unsigned char encoding[7] = { 0x40, 0x54, 0x89, 0x00, 0x00, 0x00, 0x08 }; // 9000000 ~ 0x895440 /* Threading */ void* USBSID_Thread(void); int USBSID_InitThread(void); void USBSID_StopThread(void); int USBSID_IsRunning(void); pthread_t us_ptid; /* Ringbuffer */ void USBSID_ResetRingBuffer(void); void USBSID_InitRingBuffer(int buffer_size, int differ_size); void USBSID_InitRingBuffer(void); void USBSID_DeInitRingBuffer(void); bool USBSID_IsHigher(void); int USBSID_RingDiff(void); void USBSID_RingPut(uint8_t item); uint8_t USBSID_RingGet(void); void USBSID_FlushBuffer(void); /* Ringbuffer reads & writes*/ void USBSID_RingPopCycled(void); /* Threaded writer with cycles */ void USBSID_RingPop(void); /* Threaded writer */ public: USBSID_Class(); /* Constructor */ ~USBSID_Class(); /* Deconstructor */ /* USBSID */ int USBSID_Init(bool start_threaded, bool with_cycles); int USBSID_Close(void); int USBSID_GetInstanceID(void){ return us_InstanceID; }; bool USBSID_isInitialised(void){ return us_Initialised; }; bool USBSID_isAvailable(void){ return us_Available; }; bool USBSID_isOpen(void){ return us_PortIsOpen; }; /* USBSID & SID control */ void USBSID_Pause(void); /* Pause playing by releasing chipselect pins */ void USBSID_Reset(void); /* Reset all SID chips */ void USBSID_ResetAllRegisters(void); /* Reset register for all SID chips */ void USBSID_Mute(void); /* Mute all SID chips */ void USBSID_UnMute(void); /* UnMute all SID chips */ void USBSID_DisableSID(void); /* Release reset pin and unmute SID */ void USBSID_EnableSID(void); /* Assert reset pin and release chipselect pins */ void USBSID_ClearBus(void); /* Clear the SID bus from any data */ void USBSID_SetClockRate(long clockrate_cycles, /* Set CPU clockrate in Hertz */ bool suspend_sids); /* Assert SID RES signal while changing clockrate (Advised!)*/ long USBSID_GetClockRate(void); /* Get CPU clockrate in Hertz */ long USBSID_GetRefreshRate(void); /* Get cycles per refresh rate */ long USBSID_GetRasterRate(void); /* Get cycles per raster rate */ uint8_t* USBSID_GetSocketConfig(uint8_t socket_config[]); /* Get socket config for parsing */ int USBSID_GetSocketNumSIDS(int socket, uint8_t socket_config[]); /* Get the socket number of sids configured */ int USBSID_GetSocketChipType(int socket, uint8_t socket_config[]); /* Get the socket chip type configured */ int USBSID_GetSocketSIDType1(int socket, uint8_t socket_config[]); /* Get the socket SID 1 type configured */ int USBSID_GetSocketSIDType2(int socket, uint8_t socket_config[]); /* Get the socket SID 2 type configured (only works for clone chip types ofcourse) */ int USBSID_GetNumSIDs(void); /* Get the total number of sids configured */ int USBSID_GetFMOplSID(void); /* Get the sid number (if configured) to address FMOpl */ int USBSID_GetPCBVersion(void); /* Get the PCB version */ void USBSID_SetStereo(int state); /* Set device to mono or stereo ~ v1.3 PCB only */ void USBSID_ToggleStereo(void); /* Toggle between mono and stereo ~ v1.3 PCB only */ /* Synchronous direct */ void USBSID_SingleWrite(unsigned char *buff, int len); /* Single write buffer of size_t ~ example: config writing */ unsigned char USBSID_SingleRead(uint8_t reg); /* Single read register, return result */ unsigned char USBSID_SingleReadConfig(unsigned char *buff, int len); /* Single to buffer of specified length ~ example: config reading */ /* Asynchronous direct */ void USBSID_Write(unsigned char *buff, size_t len); /* Write buffer of size_t len */ void USBSID_Write(uint8_t reg, uint8_t val); /* Write register and value */ void USBSID_Write(unsigned char *buff, size_t len, uint16_t cycles); /* Wait n cycles, write buffer of size_t len */ void USBSID_Write(uint8_t reg, uint8_t val, uint16_t cycles); /* Wait n cycles, write register and value */ void USBSID_WriteCycled(uint8_t reg, uint8_t val, uint16_t cycles); /* Write register and value, USBSID uses cycles for delay */ unsigned char USBSID_Read(uint8_t reg); /* Write register, return result */ unsigned char USBSID_Read(unsigned char *writebuff); /* Write buffer, return result */ unsigned char USBSID_Read(unsigned char *writebuff, uint16_t cycles); /* Wait for n cycles and write buffer, return result */ /* Asynchronous thread */ void USBSID_WriteRing(uint8_t reg, uint8_t val); /* Write register and value to ringbuffer, USBSID adds 10 delay cycles to each write */ void USBSID_WriteRingCycled(uint8_t reg, uint8_t val, uint16_t cycles); /* Write register, value, and cycles to ringbuffer */ /* Threading */ void USBSID_EnableThread(void); /* Enable the thread on the fly */ void USBSID_DisableThread(void); /* Disable the running thread and switch to non threaded and cycled on the fly */ /* Ringbuffer */ void USBSID_SetFlush(void); /* Set flush buffer flag to 1 */ void USBSID_Flush(void); /* Set flush buffer flag to 1 and flushes the buffer */ void USBSID_SetBufferSize(int size); /* Set the buffer size for storing writes */ void USBSID_SetDiffSize(int size); /* Set the minimum size difference between head & tail */ void USBSID_RestartRingBuffer(void); /* Restart the ringbuffer*/ /* Thread utils */ void USBSID_RestartThread(bool with_cycles); static void *_USBSID_Thread(void *context) { /* Required for supplying private function to pthread_create */ return ((USBSID_Class *)context)->USBSID_Thread(); } /* Timing and cycles */ uint_fast64_t USBSID_WaitForCycle(uint_fast16_t cycles); /* Sleep for n cycles */ uint_fast64_t USBSID_WaitForCycle_(uint_fast16_t cycles); /* Sleep for n cycles ~ deprecated */ void USBSID_SyncTime(void); /* Sync time for cycle delay function */ /* Utils */ /* TODO: Deprecate this function, emulator/player should handle this */ uint8_t USBSID_Address(uint16_t addr); /* Calculates correct SID address to write to if player does not */ }; } /* USBSIDDriver */ #ifdef USBSID_OPTOFF #pragma GCC diagnostic pop #pragma GCC pop_options #endif #endif /* _USBSID_H_ */ libsidplayfp-3.0.0/src/builders/usbsid-builder/driver/src/USBSID.cpp0000644000175100017510000011762715175333713021001 /* * USBSID-Pico is a RPi Pico (RP2040/RP2350) based board for interfacing one * or two MOS SID chips and/or hardware SID emulators over (WEB)USB with your * computer, phone or ASID supporting player. * * USBSID.cpp * This file is part of USBSID-Pico (https://github.com/LouDnl/USBSID-Pico-driver) * File author: LouD * * Copyright (c) 2024-2025 LouD * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 2. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * */ #include #include #include "USBSID.h" using namespace USBSID_NS; using namespace std; #ifndef count_of #define count_of(a) (sizeof(a)/sizeof(uint8_t)) #endif static inline uint8_t* us_alloc(size_t alignment, size_t size) { #if defined(__US_LINUX_COMPILE) return (uint8_t*)aligned_alloc(alignment, size); #elif defined(__US_WINDOWS_COMPILE) return (uint8_t*)_aligned_malloc(size, alignment); #else (void)alignment; return (uint8_t*)malloc(size); #endif } static inline void us_free(void* m) { #ifdef __US_WINDOWS_COMPILE return _aligned_free(m); #else return free(m); #endif } /* Driver related */ bool USBSID_Class::us_Initialised = false; bool USBSID_Class::us_Available = false; bool USBSID_Class::us_PortIsOpen = false; /* Timing related */ double USBSID_Class::us_CPUcycleDuration = ratio_t::den / (float)cycles_per_sec; /* CPU cycle duration in nanoseconds */ double USBSID_Class::us_InvCPUcycleDurationNanoSeconds = 1.0 / (ratio_t::den / (float)cycles_per_sec); /* Inverted CPU cycle duration in nanoseconds */ timestamp_t USBSID_Class::m_StartTime = std::chrono::steady_clock::now(); /* That moment when... */ timestamp_t USBSID_Class::m_LastTime = m_StartTime; /* I know what you did last summer! */ /* Ringbuffer related */ int USBSID_Class::diff_size = 64; int USBSID_Class::ring_size = 8192; extern "C" { /* USBSID */ USBSID_Class::USBSID_Class() : us_InstanceID(0)//, { USBDBG(stdout, "[USBSID] Driver init start\n"); us_InstanceID = ++instance; /* Current object id */ if (us_PortIsOpen && (us_InstanceID == 1)) USBSID_GetNumSIDs(); /* Retrieve numsids on 2nd class init when port is open */ us_Initialised = true; } USBSID_Class::~USBSID_Class() { USBDBG(stdout, "[USBSID] Driver de-init start\n"); instance--; if (us_PortIsOpen && (instance <= 0)) { if (USBSID_Close() == 0) { us_Initialised = false; } } if (write_buffer) us_free(write_buffer); if (thread_buffer) us_free(thread_buffer); if (result) us_free(result); thread_buffer = NULL; write_buffer = NULL; result = NULL; } int USBSID_Class::USBSID_Init(bool start_threaded, bool with_cycles) { if (!us_Initialised) return -1; if (!us_PortIsOpen) { USBDBG(stdout, "[USBSID] Setup start\n"); /* Init USB */ rc = LIBUSB_Setup(start_threaded, with_cycles); flush_buffer = 0; if (rc >= 0) { /* Start thread on init */ if (threaded) { rc = USBSID_InitThread(); } USBSID_GetClockRate(); /* Once on init */ us_PortIsOpen = true; return rc; } else { USBDBG(stdout, "[USBSID] Not found\n"); return -1; } } else { USBDBG(stdout, "[USBSID] Driver already started\n"); return 0; } } int USBSID_Class::USBSID_Close(void) { if (!us_PortIsOpen) return 0; int e = -1; if (rc >= 0) e = LIBUSB_Exit(); if (rc != -1) USBERR(stderr, "Expected rc == -1, received: %d\n", rc); if (e != 0) USBERR(stderr, "Expected e == 0, received: %d\n", e); if (devh != NULL) USBERR(stderr, "Expected dev == NULL, received: %p", (void*)&devh); us_PortIsOpen = false; USBDBG(stdout, "[USBSID] De-init finished\n"); return 0; } void USBSID_Class::USBSID_Pause(void) { if (!us_PortIsOpen) return; USBDBG(stdout, "[USBSID] Pause\r\n"); unsigned char buff[3] = {(COMMAND << 6 | PAUSE), 0x0, 0x0}; USBSID_SingleWrite(buff, 3); return; } void USBSID_Class::USBSID_Reset(void) { if (!us_PortIsOpen) return; USBDBG(stdout, "[USBSID] Reset\r\n"); unsigned char buff[3] = {(COMMAND << 6 | RESET_SID), 0x0, 0x0}; USBSID_SingleWrite(buff, 3); flush_buffer = 1; USBSID_SyncTime(); return; } void USBSID_Class::USBSID_ResetAllRegisters(void) { if (!us_PortIsOpen) return; USBDBG(stdout, "[USBSID] Reset All Registers\r\n"); unsigned char buff[3] = {(COMMAND << 6 | RESET_SID), 0x1, 0x0}; USBSID_SingleWrite(buff, 3); return; } void USBSID_Class::USBSID_Mute(void) { if (!us_PortIsOpen) return; USBDBG(stdout, "[USBSID] Mute\r\n"); unsigned char buff[3] = {(COMMAND << 6 | MUTE), 0x0, 0x0}; USBSID_SingleWrite(buff, 3); return; } void USBSID_Class::USBSID_UnMute(void) { if (!us_PortIsOpen) return; USBDBG(stdout, "[USBSID] UnMute\r\n"); unsigned char buff[3] = {(COMMAND << 6 | UNMUTE), 0x0, 0x0}; USBSID_SingleWrite(buff, 3); return; } void USBSID_Class::USBSID_DisableSID(void) { if (!us_PortIsOpen) return; USBDBG(stdout, "[USBSID] DisableSID\r\n"); unsigned char buff[3] = {(COMMAND << 6 | DISABLE_SID), 0x0, 0x0}; USBSID_SingleWrite(buff, 3); return; } void USBSID_Class::USBSID_EnableSID(void) { if (!us_PortIsOpen) return; USBDBG(stdout, "[USBSID] EnableSID\r\n"); unsigned char buff[3] = {(COMMAND << 6 | ENABLE_SID), 0x0, 0x0}; USBSID_SingleWrite(buff, 3); return; } void USBSID_Class::USBSID_ClearBus(void) { if (!us_PortIsOpen) return; USBDBG(stdout, "[USBSID] ClearBus\r\n"); unsigned char buff[3] = {(COMMAND << 6 | CLEAR_BUS), 0x0, 0x0}; USBSID_SingleWrite(buff, 3); return; } void USBSID_Class::USBSID_SetClockRate(long clockrate_cycles, bool suspend_sids) { if (!us_PortIsOpen) return; for (uint8_t i = 0; i < 4; i++) { if (clockSpeed[i] == clockrate_cycles) { cycles_per_sec = clockSpeed[i]; cycles_per_frame = refreshRate[i]; cycles_per_raster = rasterRate[i]; us_CPUcycleDuration = ratio_t::den / (float)cycles_per_sec; us_InvCPUcycleDurationNanoSeconds = 1.0 / (ratio_t::den / (float)cycles_per_sec); USBDBG(stdout, "[USBSID] Clockspeed set to: %ld\n", cycles_per_sec); USBDBG(stdout, "[USBSID] Cycles per raster %ld\n", cycles_per_raster); USBDBG(stdout, "[USBSID] Cycles per frame: %ld\n", cycles_per_frame); USBDBG(stdout, "[USBSID] CPU cycle duration in nanoseconds %f\n", us_CPUcycleDuration); USBDBG(stdout, "[USBSID] Inverted CPU cycle duration in nanoseconds %.09f\n", us_InvCPUcycleDurationNanoSeconds); if (clk_retrieved == 0 || us_clkrate != cycles_per_sec) { uint8_t configbuff[6] = {(COMMAND << 6 | CONFIG), 0x50, i, (uint8_t)(suspend_sids == true ? 1 : 0), 0, 0}; USBSID_SingleWrite(configbuff, 6); } USBSID_SyncTime(); return; } } return; } long USBSID_Class::USBSID_GetClockRate(void) { if (!us_PortIsOpen) return 0; if (clk_retrieved == 1) { us_InvCPUcycleDurationNanoSeconds = 1.0 / (ratio_t::den / (float)cycles_per_sec); us_CPUcycleDuration = ratio_t::den / (float)cycles_per_sec; return cycles_per_sec; } else if (clk_retrieved == 0) { USBSID_SyncTime(); uint8_t configbuff[6] = {(COMMAND << 6 | CONFIG), 0x57, 0, 0, 0, 0}; USBSID_SingleWrite(configbuff, 6); us_clkrate = clockSpeed[USBSID_SingleReadConfig(result, 1)]; cycles_per_sec = us_clkrate; clk_retrieved = 1; us_InvCPUcycleDurationNanoSeconds = 1.0 / (ratio_t::den / (float)cycles_per_sec); us_CPUcycleDuration = ratio_t::den / (float)cycles_per_sec; return cycles_per_sec; } return -1; } long USBSID_Class::USBSID_GetRefreshRate(void) { return cycles_per_frame; } long USBSID_Class::USBSID_GetRasterRate(void) { return cycles_per_raster; } /* Socket config array * 0 = Initiator * 1 = Verification * 2 HiByte = socketOne enabled * 2 LoByte = socketOne dualsid * 3 HiByte = socketOne chipType * 3 LoByte = socketOne cloneType * 4 HiByte = socketOne sid1Type * 4 LoByte = socketOne sid2Type * 5 HiByte = socketTwo enabled * 5 LoByte = socketTwo dualsid * 6 HiByte = socketTwo chipType * 6 LoByte = socketTwo cloneType * 7 HiByte = socketTwo sid1Type * 7 LoByte = socketTwo sid2Type * 8 = socketTwo mirror socketOne * 9 = Terminator */ uint8_t* USBSID_Class::USBSID_GetSocketConfig(uint8_t socket_config[]) { if (!us_PortIsOpen) return NULL; if (socketconfig == -1) { socketconfig = 1; uint8_t configbuff[6] = {(COMMAND << 6 | CONFIG), 0x37, 0, 0, 0, 0}; USBSID_SingleWrite(configbuff, 6); uint8_t socket_buff[10]; USBSID_SingleReadConfig(socket_buff, 10); if (socket_buff[0] == 0x37 && socket_buff[1] == 0x7F && socket_buff[9] == 0xFF) { memcpy(socket_config, socket_buff, 10); return socket_config; } else { socketconfig = -1; return NULL; } } else { socketconfig = (socketconfig == 1 ? socketconfig : -1); return NULL; } } int USBSID_Class::USBSID_GetSocketNumSIDS(int socket, uint8_t socket_config[]) { if (!us_PortIsOpen) return 0; switch (socket) { case 1: if (((socket_config[2] & 0xF0) >> 4) == 1) { return ((socket_config[2] & 0xF) == 1 ? 2 : 1); } else { return 0; } break; case 2: if (((socket_config[5] & 0xF0) >> 4) == 1) { return ((socket_config[5] & 0xF) == 1 ? 2 : 1); } else { return 0; } break; default: return 0; } }; int USBSID_Class::USBSID_GetSocketChipType(int socket, uint8_t socket_config[]) { /* TODO: FINISH */ if (!us_PortIsOpen) return 0; return 0; }; /* 0 = unknown, 1 = N/A, 2 = MOS8085, 3 = MOS6581, 4 = FMopl */ int USBSID_Class::USBSID_GetSocketSIDType1(int socket, uint8_t socket_config[]) { if (!us_PortIsOpen) return 0; switch (socket) { case 1: if (((socket_config[2] & 0xF0) >> 4) == 1) { return ((socket_config[4] & 0xF0) >> 4); } else { return 1; } break; case 2: if (((socket_config[5] & 0xF0) >> 4) == 1) { return ((socket_config[7] & 0xF0) >> 4); } else { return 1; } break; default: return 1; } }; /* 0 = unknown, 1 = N/A, 2 = MOS8085, 3 = MOS6581, 4 = FMopl */ int USBSID_Class::USBSID_GetSocketSIDType2(int socket, uint8_t socket_config[]) { if (!us_PortIsOpen) return 0; switch (socket) { case 1: if ((((socket_config[2] & 0xF0) >> 4) == 1) && ((socket_config[2] & 0xF) == 1)) { return ((socket_config[4] & 0xF) >> 4); } else { return 1; } break; case 2: if ((((socket_config[5] & 0xF0) >> 4) == 1) && ((socket_config[5] & 0xF) == 1)) { return (socket_config[7] & 0xF); } else { return 1; } break; default: return 1; } }; int USBSID_Class::USBSID_GetNumSIDs(void) { if (!us_PortIsOpen) return 0; if (numsids == 0) { uint8_t configbuff[6] = {(COMMAND << 6 | CONFIG), 0x39, 0, 0, 0, 0}; USBSID_SingleWrite(configbuff, 6); numsids = USBSID_SingleReadConfig(result, 1); return numsids; } else { return numsids; } return 0; } int USBSID_Class::USBSID_GetFMOplSID(void) { if (!us_PortIsOpen) return 0; if (fmoplsid == -1) { uint8_t configbuff[6] = {(COMMAND << 6 | CONFIG), 0x3A, 0, 0, 0, 0}; USBSID_SingleWrite(configbuff, 6); fmoplsid = USBSID_SingleReadConfig(result, 1); } return (fmoplsid == 0 ? -1 : fmoplsid); } int USBSID_Class::USBSID_GetPCBVersion(void) { if (!us_PortIsOpen) return 0; if (pcbversion == -1) { uint8_t configbuff[6] = {(COMMAND << 6 | CONFIG), 0x81, 0x1, 0, 0, 0}; USBSID_SingleWrite(configbuff, 6); pcbversion = USBSID_SingleReadConfig(result, 1); } return pcbversion; } void USBSID_Class::USBSID_SetStereo(int state) { if (!us_PortIsOpen) return; if (pcbversion == -1) { USBSID_GetPCBVersion(); } if (pcbversion == 13) { uint8_t configbuff[6] = {(COMMAND << 6 | CONFIG), 0x89, (uint8_t)state, 0, 0, 0}; USBSID_SingleWrite(configbuff, 6); } return; } void USBSID_Class::USBSID_ToggleStereo(void) { if (!us_PortIsOpen) return; if (pcbversion == -1) { USBSID_GetPCBVersion(); } if (pcbversion == 13) { uint8_t configbuff[6] = {(COMMAND << 6 | CONFIG), 0x88, 0x0, 0, 0, 0}; USBSID_SingleWrite(configbuff, 6); } return; } /* SYNCHRONOUS */ void USBSID_Class::USBSID_SingleWrite(unsigned char *buff, int len) { if (!us_PortIsOpen) return; int actual_length = 0; if (libusb_bulk_transfer(devh, EP_OUT_ADDR, buff, len, &actual_length, 0) < 0) { USBERR(stderr, "[USBSID] Error while sending synchronous write buffer of length %d\n", actual_length); } return; } unsigned char USBSID_Class::USBSID_SingleRead(uint8_t reg) { if (!us_PortIsOpen) return 0; int actual_length; unsigned char buff[3] = {(READ << 6), reg, 0}; if (libusb_bulk_transfer(devh, EP_OUT_ADDR, buff, 3, &actual_length, 0) < 0) { USBERR(stderr, "[USBSID] Error while sending write command for reading\n"); } rc = libusb_bulk_transfer(devh, EP_IN_ADDR, result, 1, &actual_length, 0); if (rc == LIBUSB_ERROR_TIMEOUT) { USBERR(stderr, "[USBSID] Timeout error while reading (%d)\n", actual_length); return 0; } else if (rc < 0) { USBERR(stderr, "[USBSID] Error while waiting for char while reading\n"); return 0; } return result[0]; } unsigned char USBSID_Class::USBSID_SingleReadConfig(unsigned char *buff, int len) { if (!us_PortIsOpen) return 0; int actual_length; rc = libusb_bulk_transfer(devh, EP_IN_ADDR, buff, len, &actual_length, 0); if (rc == LIBUSB_ERROR_TIMEOUT) { USBERR(stderr, "[USBSID] Timeout error while reading (%d)\n", actual_length); return 0; } else if (rc < 0) { USBERR(stderr, "[USBSID] Error while waiting for char while reading\n"); return 0; } return *buff; } /* ASYNCHRONOUS */ void USBSID_Class::USBSID_Write(unsigned char *buff, size_t len) { if (!us_PortIsOpen) return; if (threaded) { USBERR(stderr, "[USBSID] Function '%s' cannot be used when threaded (%d) is enabled\n", __func__, threaded); return; } write_completed = 0; memcpy(out_buffer, buff, len); libusb_submit_transfer(transfer_out); libusb_handle_events_completed(ctx, NULL); return; } void USBSID_Class::USBSID_Write(uint8_t reg, uint8_t val) { if (!us_PortIsOpen) return; if (threaded) { USBERR(stderr, "[USBSID] Function '%s' cannot be used when threaded (%d) is enabled\n", __func__, threaded); return; } write_completed = 0; write_buffer[0] = 0x0; write_buffer[1] = (reg & 0xFF); write_buffer[2] = val; USBSID_Write(write_buffer, 3); return; } void USBSID_Class::USBSID_Write(unsigned char *buff, size_t len, uint16_t cycles) { if (!us_PortIsOpen) return; if (threaded) { USBERR(stderr, "[USBSID] Function '%s' cannot be used when threaded (%d) is enabled\n", __func__, threaded); return; } USBSID_WaitForCycle(cycles); write_completed = 0; memcpy(out_buffer, buff, len); libusb_submit_transfer(transfer_out); libusb_handle_events_completed(ctx, NULL); return; } void USBSID_Class::USBSID_Write(uint8_t reg, uint8_t val, uint16_t cycles) { if (!us_PortIsOpen) return; if (threaded) { USBERR(stderr, "[USBSID] Function '%s' cannot be used when threaded (%d) is enabled\n", __func__, threaded); return; } USBSID_WaitForCycle(cycles); write_completed = 0; write_buffer[0] = 0x0; write_buffer[1] = (reg & 0xFF); write_buffer[2] = val; USBSID_Write(write_buffer, 3); return; } void USBSID_Class::USBSID_WriteCycled(uint8_t reg, uint8_t val, uint16_t cycles) { if (!us_PortIsOpen) return; if (threaded) { USBERR(stderr, "[USBSID] Function '%s' cannot be used when threaded (%d) is enabled\n", __func__, threaded); return; } write_completed = 0; write_buffer[0] = (CYCLED_WRITE << 6); write_buffer[1] = (reg & 0xFF); write_buffer[2] = val; write_buffer[3] = (uint8_t)(cycles >> 8); write_buffer[4] = (uint8_t)(cycles & 0xFF); USBSID_Write(write_buffer, 5); return; } unsigned char USBSID_Class::USBSID_Read(uint8_t reg) { if (!us_PortIsOpen) return 0; if (threaded == 0) { /* Reading not supported with threaded writes */ read_completed = write_completed = 0; uint8_t rw_buff[2]; rw_buff[0] = (READ << 6); rw_buff[1] = reg; memcpy(out_buffer, rw_buff, 2); libusb_submit_transfer(transfer_out); libusb_handle_events_completed(ctx, NULL); libusb_submit_transfer(transfer_in); libusb_handle_events_completed(ctx, &read_completed); return *result; } else { USBERR(stderr, "[USBSID] Function '%s' cannot be used when threaded (%d) is enabled\n", __func__, threaded); } return 0xFF; } unsigned char USBSID_Class::USBSID_Read(unsigned char *writebuff) { if (!us_PortIsOpen) return 0; if (threaded == 0) { /* Reading not supported with threaded writes */ read_completed = write_completed = 0; writebuff[0] = (READ << 6); memcpy(out_buffer, writebuff, 3); libusb_submit_transfer(transfer_out); libusb_handle_events_completed(ctx, NULL); libusb_submit_transfer(transfer_in); libusb_handle_events_completed(ctx, &read_completed); return *result; } else { USBERR(stderr, "[USBSID] Function '%s' cannot be used when threaded (%d) is enabled\n", __func__, threaded); } return 0xFF; } unsigned char USBSID_Class::USBSID_Read(unsigned char *writebuff, uint16_t cycles) { if (!us_PortIsOpen) return 0; if (threaded == 0) { /* Reading not supported with threaded writes */ USBSID_WaitForCycle(cycles); read_completed = 0; writebuff[0] = (READ << 6); memcpy(out_buffer, writebuff, 3); libusb_submit_transfer(transfer_out); libusb_handle_events_completed(ctx, NULL); libusb_submit_transfer(transfer_in); libusb_handle_events_completed(ctx, &read_completed); return *result; } else { USBERR(stderr, "[USBSID] Function '%s' cannot be used when threaded (%d) is enabled\n", __func__, threaded); } return 0xFF; } /* THREADING */ void* USBSID_Class::USBSID_Thread(void) { /* Only starts when threaded == true */ USBDBG(stdout, "[USBSID] Thread starting\r\n"); #ifdef _GNU_SOURCE pthread_setname_np(pthread_self(), "USBSID Thread"); #endif pthread_detach(pthread_self()); USBDBG(stdout, "[USBSID] Thread detached\r\n"); if (withcycles) { USBDBG(stdout, "[USBSID] Thread with cycles\r\n"); } pthread_mutex_lock(&us_mutex); while(run_thread == 1) { if (flush_buffer == 1) { USBSID_FlushBuffer(); } while ((us_ringbuffer.ring_read != us_ringbuffer.ring_write) && (USBSID_RingDiff() > diff_size)) { if (withcycles) { USBSID_RingPopCycled(); } else { USBSID_RingPop(); } } } USBDBG(stdout, "[USBSID] Thread finished\r\n"); pthread_mutex_unlock(&us_mutex); us_thread--; pthread_exit(NULL); return NULL; } int USBSID_Class::USBSID_InitThread(void) { USBDBG(stdout, "[USBSID] Init Thread start\r\n"); /* Init ringbuffer */ flush_buffer = 0; run_thread = buffer_pos = 1; threaded = withcycles = true; USBSID_InitRingBuffer(ring_size, diff_size); pthread_mutex_lock(&us_mutex); us_thread++; pthread_mutex_unlock(&us_mutex); int error; error = pthread_create(&this->us_ptid, NULL, &this->_USBSID_Thread, NULL); if (error != 0) { USBERR(stderr, "[USBSID] Thread can't be created :[%s]\n", strerror(error)); } return rc; } void USBSID_Class::USBSID_StopThread(void) { USBDBG(stdout, "[USBSID] Stop thread\r\n"); if (USBSID_IsRunning() == 1) { USBDBG(stdout, "[USBSID] Set thread exit = 1\r\n"); run_thread = flush_buffer = 0; USBSID_DeInitRingBuffer(); pthread_join(us_ptid, NULL); USBDBG(stdout, "[USBSID] Thread attached\r\n"); threaded = withcycles = false; while (us_thread > 0) {}; pthread_mutex_destroy(&us_mutex); } return; } int USBSID_Class::USBSID_IsRunning(void) { return run_thread; } void USBSID_Class::USBSID_RestartThread(bool with_cycles) { if (!us_PortIsOpen) return; USBDBG(stdout, "[USBSID] Restart thread (%d)\r\n", USBSID_IsRunning()); /* First check if not already running */ USBSID_StopThread(); /* Stop any active transfers */ LIBUSB_StopTransfers(); /* Free all buffers */ LIBUSB_FreeOutBuffer(); LIBUSB_FreeInBuffer(); /* Re-init variabels */ threaded = true; withcycles = with_cycles; len_out_buffer = LEN_OUT_BUFFER; /* Init all buffers */ LIBUSB_InitOutBuffer(); LIBUSB_InitInBuffer(); /* Init thread */ USBSID_InitThread(); return; } void USBSID_Class::USBSID_EnableThread(void) { if (!us_PortIsOpen) return; USBDBG(stdout, "[USBSID] Enable thread (%d)\r\n", USBSID_IsRunning()); if (USBSID_IsRunning() != 1) { USBSID_InitThread(); } return; } void USBSID_Class::USBSID_DisableThread(void) { if (!us_PortIsOpen) return; USBDBG(stdout, "[USBSID] Disable thread (%d)\r\n", USBSID_IsRunning()); USBSID_StopThread(); return; } /* RINGBUFFER */ void USBSID_Class::USBSID_ResetRingBuffer(void) { us_ringbuffer.ring_read = us_ringbuffer.ring_write = 0; return; } void USBSID_Class::USBSID_SetBufferSize(int size) { USBDBG(stdout, "[USBSID] SetBufferSize request: %d\n", size); if (size >= min_ring_size) { ring_size = size; } else { ring_size = min_ring_size; } return; } void USBSID_Class::USBSID_SetDiffSize(int size) { USBDBG(stdout, "[USBSID] SetDiffSize request: %d\n", size); if (size >= min_diff_size) { diff_size = size; } else { diff_size = min_diff_size; } return; } void USBSID_Class::USBSID_InitRingBuffer(int buffer_size, int differ_size) { /* Init with variable settings */ USBSID_SetBufferSize(buffer_size); USBSID_SetDiffSize(differ_size); USBSID_ResetRingBuffer(); us_ringbuffer.ringbuffer = us_alloc(2 * ring_size, (sizeof(uint8_t)) * ring_size); USBDBG(stdout, "[USBSID] Init RingBuffer with size: %d and diffsize: %d\n", buffer_size, differ_size); return; } void USBSID_Class::USBSID_InitRingBuffer(void) { /* Init with default settings or with values set prior to calling this function */ USBSID_SetBufferSize(ring_size); USBSID_SetDiffSize(diff_size); USBSID_ResetRingBuffer(); us_ringbuffer.ringbuffer = us_alloc(2 * ring_size, (sizeof(uint8_t)) * ring_size); us_ringbuffer.is_allocated = 1; USBDBG(stdout, "[USBSID] Init RingBuffer with default size: %d and default diffsize: %d\n", ring_size, diff_size); return; } void USBSID_Class::USBSID_DeInitRingBuffer(void) { USBSID_ResetRingBuffer(); USBSID_SetBufferSize(default_ring_size); USBSID_SetDiffSize(default_diff_size); if (us_ringbuffer.is_allocated == 1) us_free(us_ringbuffer.ringbuffer); return; } void USBSID_Class::USBSID_RestartRingBuffer(void) { /* This function can be deprecated in favour of using deinit and init */ if (!us_PortIsOpen) return; USBSID_DeInitRingBuffer(); USBSID_InitRingBuffer(); return; } bool USBSID_Class::USBSID_IsHigher() { return (us_ringbuffer.ring_read < us_ringbuffer.ring_write); } int USBSID_Class::USBSID_RingDiff() { int d = (USBSID_IsHigher() ? (us_ringbuffer.ring_read - us_ringbuffer.ring_write) : (us_ringbuffer.ring_write - us_ringbuffer.ring_read)); return ((d < 0) ? (d * -1) : d); } void USBSID_Class::USBSID_RingPut(uint8_t item) { us_ringbuffer.ringbuffer[us_ringbuffer.ring_write] = item; us_ringbuffer.ring_write = (us_ringbuffer.ring_write + 1) % ring_size; return; } uint8_t USBSID_Class::USBSID_RingGet() { uint8_t item = us_ringbuffer.ringbuffer[us_ringbuffer.ring_read]; us_ringbuffer.ring_read = (us_ringbuffer.ring_read + 1) % ring_size; return item; } void USBSID_Class::USBSID_Flush(void) { if (!us_PortIsOpen) return; USBSID_SetFlush(); USBSID_FlushBuffer(); return; } void USBSID_Class::USBSID_SetFlush(void) { USBSID_SyncTime(); flush_buffer = 1; return; } /* RINGBUFFER READS & WRITES */ void USBSID_Class::USBSID_FlushBuffer(void) { if (threaded && flush_buffer == 1 && ((withcycles == 1) ? (buffer_pos >= 5) : (buffer_pos >= 3))) { thread_buffer[0] = (withcycles == 1) ? (uint8_t)(CYCLED_WRITE << 6 | (buffer_pos - 1)) : (uint8_t)(WRITE << 6 | (buffer_pos - 1)); memcpy(out_buffer, thread_buffer, buffer_pos); buffer_pos = 1; flush_buffer = 0; libusb_submit_transfer(transfer_out); libusb_handle_events_completed(ctx, NULL); memset(thread_buffer, 0, 64); memset(out_buffer, 0, len_out_buffer); } else { flush_buffer = 0; } return; } void USBSID_Class::USBSID_WriteRing(uint8_t reg, uint8_t val) { if (!us_PortIsOpen) return; if (threaded && !withcycles) { USBSID_RingPut(reg); USBSID_RingPut(val); } else { USBERR(stderr, "[USBSID] Function '%s' cannot be used when threaded = %d and withcycles = %d\n", __func__, threaded, withcycles); } return; } void USBSID_Class::USBSID_WriteRingCycled(uint8_t reg, uint8_t val, uint16_t cycles) { if (!us_PortIsOpen) return; if (threaded && withcycles) { USBSID_RingPut(reg); USBSID_RingPut(val); USBSID_RingPut((uint8_t)(cycles >> 8) & 0xFF); USBSID_RingPut((uint8_t)(cycles & 0xFF)); } else { USBERR(stderr, "[USBSID] Function '%s' cannot be used when threaded = %d and withcycles = %d\n", __func__, threaded, withcycles); } return; } void USBSID_Class::USBSID_RingPopCycled(void) { thread_buffer[buffer_pos++] = USBSID_RingGet(); /* register */ thread_buffer[buffer_pos++] = USBSID_RingGet(); /* value */ thread_buffer[buffer_pos++] = USBSID_RingGet(); /* n cycles high */ thread_buffer[buffer_pos++] = USBSID_RingGet(); /* n cycles low */ if (buffer_pos == 61 /* >= 61 || >= 4 */ || buffer_pos == len_out_buffer || flush_buffer == 1) { flush_buffer = 0; thread_buffer[0] = (uint8_t)((CYCLED_WRITE << 6) | (buffer_pos - 1)); memcpy(out_buffer, thread_buffer, buffer_pos); buffer_pos = 1; libusb_submit_transfer(transfer_out); libusb_handle_events_completed(ctx, NULL); memset(thread_buffer, 0, 64); memset(out_buffer, 0, len_out_buffer); } return; } void USBSID_Class::USBSID_RingPop(void) { write_completed = 0; /* Ex: 0xD418 */ thread_buffer[buffer_pos++] = USBSID_RingGet(); /* register */ thread_buffer[buffer_pos++] = USBSID_RingGet(); /* value */ if (buffer_pos == 63 /* >= 61 || >= 4 */ || buffer_pos == len_out_buffer || flush_buffer == 1) { flush_buffer = 0; thread_buffer[0] = (uint8_t)((WRITE << 6) | (buffer_pos - 1)); memcpy(out_buffer, thread_buffer, buffer_pos); buffer_pos = 1; libusb_submit_transfer(transfer_out); libusb_handle_events_completed(ctx, NULL); memset(thread_buffer, 0, 64); memset(out_buffer, 0, len_out_buffer); } return; } /* BUS */ uint8_t USBSID_Class::USBSID_Address(uint16_t addr) { /* Unused at the moment */ enum { SIDUMASK = 0xFF00, SIDLMASK = 0xFF, SID1ADDR = 0xD400, SID1MASK = 0x1F, SID2ADDR = 0xD420, SID2MASK = 0x3F, SID3ADDR = 0xD440, SID3MASK = 0x5F, SID4ADDR = 0xD460, SID4MASK = 0x7F, }; /* Set address for SID no# */ /* D500, DE00 or DF00 is the second sid in SIDTYPE1, 3 & 4 */ /* D500, DE00 or DF00 is the third sid in all other SIDTYPE */ static uint8_t a; switch (addr) { case 0xD400 ... 0xD499: a = (uint8_t)(addr & SIDLMASK); /* $D400 -> $D479 1, 2, 3 & 4 */ break; case 0xD500 ... 0xD599: case 0xDE00 ... 0xDF99: a = ((SID3ADDR | (addr & SID2MASK)) & SIDLMASK); break; default: a = (uint8_t)(addr & SIDLMASK); break; } return a; } /* TIMING AND CYCLES */ void USBSID_Class::USBSID_SyncTime(void) { if (!us_PortIsOpen) return; m_LastTime = std::chrono::steady_clock::now();// - m_StartTime); } uint_fast64_t USBSID_Class::USBSID_WaitForCycle_(uint_fast16_t cycles) { long duration = (long)(cycles * us_CPUcycleDuration); auto duration_ns = duration_t(duration); auto start = std::chrono::steady_clock::now(); auto target_time = (m_LastTime + duration_ns); auto end = std::chrono::steady_clock::now(); do { end = std::chrono::steady_clock::now(); } while (end < target_time); auto actual_ns = static_cast(std::chrono::duration_cast(end - start).count()); /* USBDBG(stdout,"[%d][LT]%ld[END]%ld[DUR]%ld[C]%lu[ACTUAL]%lld\n", us_InstanceID, m_LastTime,end, duration_ns, cycles, actual_ns ); */ m_LastTime = end; return (uint_fast64_t)actual_ns; } /* WORKS */ uint_fast64_t USBSID_Class::USBSID_WaitForCycle(uint_fast16_t cycles) { auto start = std::chrono::steady_clock::now(); auto duration_ns = duration_t((long)(cycles * us_CPUcycleDuration)); auto target_time = (start + duration_ns); // auto end = std::chrono::steady_clock::now(); // do { // end = std::chrono::steady_clock::now(); // } while (end < target_time); // } while (target_time > end); // while (target_time >= end) { // end = std::chrono::steady_clock::now(); // } // while (target_time > std::chrono::steady_clock::now()) {}; do { } while (std::chrono::steady_clock::now() < target_time); // for (;;) { // if (std::chrono::steady_clock::now() < target_time) continue; // else break; // }; auto end = std::chrono::steady_clock::now(); auto actual_ns = static_cast(std::chrono::duration_cast(end - start).count()); /* USBDBG(stdout,"[%d][DUR]%ld [C]%lu [ACTUAL]%lld\n", us_InstanceID, duration_ns, cycles, actual_ns ); */ return (uint_fast64_t)actual_ns; } /* LIBUSB */ int USBSID_Class::LIBUSB_OpenDevice(void) { USBDBG(stdout, "[USBSID] Open device\r\n"); /* Look for a specific device and open it. */ devh = libusb_open_device_with_vid_pid(ctx, VENDOR_ID, PRODUCT_ID); if (!devh) { rc = -1; USBERR(stderr, "[USBSID] Error opening USB device with VID & PID: %d %s: %s\r\n", rc, libusb_error_name(rc), libusb_strerror(rc)); } return rc; } void USBSID_Class::LIBUSB_CloseDevice(void) { USBDBG(stdout, "[USBSID] Close device\r\n"); if (us_InstanceID != 0) return; if (devh) { for (int if_num = 0; if_num < 2; if_num++) { if (libusb_kernel_driver_active(devh, if_num)) { rc = libusb_detach_kernel_driver(devh, if_num); USBERR(stderr, "[USBSID] Error, in libusb_detach_kernel_driver: %d, %s: %s\n", rc, libusb_error_name(rc), libusb_strerror(rc)); } libusb_release_interface(devh, if_num); } libusb_close(devh); } return; } int USBSID_Class::LIBUSB_Available(uint16_t vendor_id, uint16_t product_id) { struct libusb_device **devs; struct libusb_device *dev; size_t i = 0; int r; us_Available = false; us_Found = 0; if (libusb_get_device_list(ctx, &devs) < 0) return 0; while ((dev = devs[i++]) != NULL) { struct libusb_device_descriptor desc; r = libusb_get_device_descriptor(dev, &desc); if (r < 0) goto out; if (desc.idVendor == vendor_id && desc.idProduct == product_id) { us_Available = true; us_Found++; continue; } } out: libusb_free_device_list(devs, 1); return (us_Available ? us_Found : 0); } int USBSID_Class::LIBUSB_DetachKernelDriver(void) { USBDBG(stdout, "[USBSID] Detach kernel driver\r\n"); /* As we are dealing with a CDC-ACM device, it's highly probable that * Linux already attached the cdc-acm driver to this device. * We need to detach the drivers from all the USB interfaces. The CDC-ACM * Class defines two interfaces: the Control interface and the * Data interface. */ for (int if_num = 0; if_num < 2; if_num++) { if (libusb_kernel_driver_active(devh, if_num)) { libusb_detach_kernel_driver(devh, if_num); } rc = libusb_claim_interface(devh, if_num); if (rc < 0) { USBERR(stderr, "[USBSID] Error claiming interface: %d, %s: %s\r\n", rc, libusb_error_name(rc), libusb_strerror(rc)); rc = -1; break; } } return rc; } int USBSID_Class::LIBUSB_ConfigureDevice(void) { USBDBG(stdout, "[USBSID] Configure device\r\n"); /* Start configuring the device: * set line state */ rc = libusb_control_transfer(devh, 0x21, 0x22, ACM_CTRL_DTR | ACM_CTRL_RTS, 0, NULL, 0, 0); if (rc < 0) { /* should return 0 or higher */ USBERR(stderr, "[USBSID] Error configuring line state during control transfer: %d, %s: %s\r\n", rc, libusb_error_name(rc), libusb_strerror(rc)); rc = -1; return rc; } /* set line encoding here */ // NOTE: NOT USED FOR CDC rc = libusb_control_transfer(devh, 0x21, 0x20, 0, 0, encoding, sizeof(encoding), 0); if (rc < 0 || rc != 7) { /* should return 7 for the encoding size */ USBERR(stderr, "[USBSID] Error configuring line encoding during control transfer: %d, %s: %s\r\n", rc, libusb_error_name(rc), libusb_strerror(rc)); rc = -1; return rc; } return rc; } void USBSID_Class::LIBUSB_InitOutBuffer(void) { USBDBG(stdout, "[USBSID] Init out buffers\r\n"); out_buffer = libusb_dev_mem_alloc(devh, len_out_buffer); if (out_buffer == NULL) { USBDBG(stdout, "[USBSID] libusb_dev_mem_alloc failed on out_buffer, allocating with malloc\r\n"); // out_buffer = (uint8_t*)aligned_alloc(2 * len_out_buffer, (sizeof(uint8_t)) * len_out_buffer); out_buffer = us_alloc(2 * len_out_buffer, (sizeof(uint8_t)) * len_out_buffer); } else { out_buffer_dma = true; } USBDBG(stdout, "[USBSID] Alloc out_buffer complete\r\n"); transfer_out = libusb_alloc_transfer(0); USBDBG(stdout, "[USBSID] Alloc transfer_out complete\r\n"); libusb_fill_bulk_transfer(transfer_out, devh, EP_OUT_ADDR, out_buffer, len_out_buffer, usb_out, NULL, 0); USBDBG(stdout, "[USBSID] libusb_fill_bulk_transfer transfer_out complete\r\n"); if (thread_buffer == NULL) { // thread_buffer = (uint8_t*)aligned_alloc(2 * len_out_buffer, (sizeof(uint8_t)) * (len_out_buffer)); thread_buffer = us_alloc(2 * len_out_buffer, (sizeof(uint8_t)) * (len_out_buffer)); } if (write_buffer == NULL) { // write_buffer = (uint8_t*)aligned_alloc(2 * len_out_buffer, (sizeof(uint8_t)) * (len_out_buffer)); write_buffer = us_alloc(2 * len_out_buffer, (sizeof(uint8_t)) * (len_out_buffer)); } return; } void USBSID_Class::LIBUSB_FreeOutBuffer(void) { USBDBG(stdout, "[USBSID] Free out buffers\r\n"); if (out_buffer_dma) { rc = libusb_dev_mem_free(devh, out_buffer, len_out_buffer); if (rc < 0) { USBERR(stderr, "[USBSID] Error, failed to free out_buffer DMA memory: %d, %s: %s\n", rc, libusb_error_name(rc), libusb_strerror(rc)); } } else { if (out_buffer) us_free(out_buffer); out_buffer = NULL; } if (thread_buffer) { us_free(thread_buffer); thread_buffer = NULL; } if (write_buffer) { us_free(write_buffer); write_buffer = NULL; } return; } void USBSID_Class::LIBUSB_InitInBuffer(void) { USBDBG(stdout, "[USBSID] Init in buffers\r\n"); in_buffer = libusb_dev_mem_alloc(devh, LEN_IN_BUFFER); if (in_buffer == NULL) { USBDBG(stdout, "[USBSID] libusb_dev_mem_alloc failed on in_buffer, allocating with malloc\r\n"); in_buffer = us_alloc(2 * LEN_IN_BUFFER, (sizeof(uint8_t)) * LEN_IN_BUFFER); } else { in_buffer_dma = true; } USBDBG(stdout, "[USBSID] Alloc in_buffer complete\r\n"); transfer_in = libusb_alloc_transfer(0); USBDBG(stdout, "[USBSID] Alloc transfer_in complete\r\n"); libusb_fill_bulk_transfer(transfer_in, devh, EP_IN_ADDR, in_buffer, LEN_IN_BUFFER, usb_in, &read_completed, 0); USBDBG(stdout, "[USBSID] libusb_fill_bulk_transfer transfer_in complete\r\n"); if (result == NULL) { result = us_alloc(2 * LEN_IN_BUFFER, (sizeof(uint8_t)) * (LEN_IN_BUFFER)); } return; } void USBSID_Class::LIBUSB_FreeInBuffer(void) { USBDBG(stdout, "[USBSID] Free in buffers\r\n"); if (in_buffer_dma) { rc = libusb_dev_mem_free(devh, in_buffer, LEN_IN_BUFFER); if (rc < 0) { USBERR(stderr, "[USBSID] Error, failed to free in_buffer DMA memory: %d, %s: %s\n", rc, libusb_error_name(rc), libusb_strerror(rc)); } } else { if (in_buffer) us_free(in_buffer); in_buffer = NULL; } if (result) { us_free(result); result = NULL; } return; } void USBSID_Class::LIBUSB_StopTransfers(void) { USBDBG(stdout, "[USBSID] Stopping transfers\r\n"); if (transfer_out != NULL) { rc = libusb_cancel_transfer(transfer_out); libusb_free_transfer(transfer_out); if (rc < 0 && rc != -5) { USBERR(stderr, "[USBSID] Error, failed to cancel transfer %d - %s: %s\n", rc, libusb_error_name(rc), libusb_strerror(rc)); } } if (transfer_in != NULL) { rc = libusb_cancel_transfer(transfer_in); libusb_free_transfer(transfer_in); if (rc < 0 && rc != -5) { USBERR(stderr, "[USBSID] Error, failed to cancel transfer %d - %s: %s\n", rc, libusb_error_name(rc), libusb_strerror(rc)); } } return; } int USBSID_Class::LIBUSB_Setup(bool start_threaded, bool with_cycles) { rc = read_completed = write_completed = -1; threaded = start_threaded; withcycles = with_cycles; len_out_buffer = LEN_OUT_BUFFER; write_buffer = us_alloc(2 * len_out_buffer, (sizeof(uint8_t)) * (len_out_buffer)); thread_buffer = us_alloc(2 * len_out_buffer, (sizeof(uint8_t)) * (len_out_buffer)); result = us_alloc(2 * LEN_IN_BUFFER, (sizeof(uint8_t)) * (LEN_IN_BUFFER)); /* Initialize libusb */ rc = libusb_init(&ctx); // rc = libusb_init_context(&ctx, /*options=NULL, /*num_options=*/0); // NOTE: REQUIRES LIBUSB 1.0.27!! if (rc != 0) { USBERR(stderr, "[USBSID] Error initializing libusb: %d %s: %s\r\n", rc, libusb_error_name(rc), libusb_strerror(rc)); goto out; } /* Set debugging output to min/max (4) level */ libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, 0); /* Check for an available USBSID-Pico */ if (LIBUSB_Available(VENDOR_ID, PRODUCT_ID) <= 0) { USBDBG(stderr, "[USBSID] USBSID-Pico not connected\n"); goto out; } if (LIBUSB_OpenDevice() < 0) { goto out; } if (LIBUSB_DetachKernelDriver() < 0) { goto out; } if (LIBUSB_ConfigureDevice() < 0) { goto out; } #ifdef US_UNMUTE_ON_ENTRY USBSID_UnMute(); #endif #ifdef US_RESET_ON_ENTRY USBSID_Reset(); #endif #ifdef US_CLEARBUS_ON_ENTRY USBSID_ClearBus(); #endif LIBUSB_InitOutBuffer(); LIBUSB_InitInBuffer(); if (rc < 0) { USBERR(stderr, "[USBSID] Error, could not open device: %d, %s: %s\r\n", rc, libusb_error_name(rc), libusb_strerror(rc)); goto out; } if (rc > 0 && rc == 7) { /* 7 for the return size of the encoding */ rc = 0; } return rc; out: LIBUSB_Exit(); return rc; } int USBSID_Class::LIBUSB_Exit(void) { if (rc >= 0) { USBSID_StopThread(); #ifdef US_MUTE_ON_EXIT USBSID_Mute(); #endif #ifdef US_RESET_ON_EXIT USBSID_Reset(); #endif LIBUSB_StopTransfers(); LIBUSB_FreeInBuffer(); LIBUSB_FreeOutBuffer(); LIBUSB_CloseDevice(); } if (ctx) { libusb_exit(ctx); } rc = -1; devh = NULL; USBDBG(stdout, "[USBSID] Closed USB device\r\n"); return 0; } void LIBUSB_CALL USBSID_Class::usb_out(struct libusb_transfer *transfer) { if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { rc = transfer->status; if (rc != LIBUSB_TRANSFER_CANCELLED) { USBERR(stderr, "[USBSID] Warning: transfer out interrupted with status %d, %s: %s\r", rc, libusb_error_name(rc), libusb_strerror(rc)); } libusb_free_transfer(transfer); return; } if (transfer->actual_length != len_out_buffer) { USBERR(stderr, "[USBSID] Sent data length %d is different from the defined buffer length: %d or actual length %d\r", transfer->length, len_out_buffer, transfer->actual_length); } // BUG: Resubmit is shit for normal tunes but good for cycle exact digitunes, sigh... // if (threaded) libusb_submit_transfer(transfer_out); /* Resubmit queue when finished */ return; } void LIBUSB_CALL USBSID_Class::usb_in(struct libusb_transfer *transfer) { read_completed = (*(int *)transfer->user_data); if (transfer->status != LIBUSB_TRANSFER_COMPLETED) { rc = transfer_in->status; if (rc != LIBUSB_TRANSFER_CANCELLED) { USBERR(stderr, "[USBSID] Warning: transfer in interrupted with status '%s'\r", libusb_error_name(rc)); } libusb_free_transfer(transfer); return; } memcpy(result, in_buffer, 1); read_completed = 1; return; } } /* extern "C" */ libsidplayfp-3.0.0/src/builders/usbsid-builder/usbsid.h0000644000175100017510000000076615175333711016655 #ifndef USBSID_H #define USBSID_H #include "sidplayfp/sidbuilder.h" #include "sidplayfp/siddefs.h" #define USBSID_MAXSID 4 class SID_EXTERN USBSIDBuilder : public sidbuilder { protected: /** * Create the sid emu. */ libsidplayfp::sidemu* create(); public: USBSIDBuilder(const char * const name); ~USBSIDBuilder(); const char *getCredits() const; void flush(); /** * enable/disable filter. */ void filter(bool enable); }; #endif // USBSID_H libsidplayfp-3.0.0/src/builders/usbsid-builder/usbsid-emu.cpp0000644000175100017510000000650615175333711017772 #include "usbsid.h" #include "usbsid-emu.h" #include #include #include #include "driver/src/USBSID.h" #include "sidcxx11.h" namespace libsidplayfp { long USBSID::raster_rate = 19950; /* Start on PAL */ event_clock_t USBSID::m_delayClk = 0; const char* USBSID::getCredits() { return "USBSID V" VERSION " Engine:\n" "\t(C) 2024-2025 LouD\n"; } USBSID::USBSID(sidbuilder *builder) : sidemu(builder), Event("USBSID Delay"), m_sid(*(new USBSID_NS::USBSID_Class)), m_handle(-1), sidno(0), busValue(0) { /* Start the fucker */ m_handle = m_sid.USBSID_Init(true, true); if (m_handle < 0) { m_error = "USBSID init failed"; m_status = false; return; } sidno = m_sid.USBSID_GetInstanceID(); m_status = m_sid.USBSID_isOpen(); if (!m_status) { m_error = "out of memory"; return; } if (sidno == 0) { raster_rate = m_sid.USBSID_GetRasterRate(); /* Get the USBSID internal raster rate */ } } USBSID::~USBSID() { if (sidno == 0) { m_sid.USBSID_Mute(); } delete &m_sid; } void USBSID::reset(uint8_t) { using namespace std; m_delayClk = 0; if (sidno == 0) { m_sid.USBSID_Reset(); m_sid.USBSID_UnMute(); } if (eventScheduler != nullptr) { eventScheduler->schedule(*this, raster_rate, EVENT_CLOCK_PHI1); } } event_clock_t USBSID::delay() { event_clock_t cycles = eventScheduler->getTime(EVENT_CLOCK_PHI1) - m_delayClk; // event_clock_t cycles = eventScheduler->getTime(EVENT_CLOCK_PHI1) - (m_delayClk - 1); m_delayClk += cycles; while (cycles > 0xffff) { m_sid.USBSID_WaitForCycle(0xffff); cycles -= 0xffff; } m_sid.USBSID_WaitForCycle(cycles); return cycles; } uint8_t USBSID::read(uint_least8_t) { return busValue; /* Always return the busValue */ } void USBSID::write(uint_least8_t addr, uint8_t data) { busValue = data; if (addr > 0x18) return; const unsigned int cycles = delay(); uint_least8_t address = ((0x20 * sidno) + addr); m_sid.USBSID_WriteRingCycled(address, data, cycles); } void USBSID::model(SidConfig::sid_model_t model, MAYBE_UNUSED bool digiboost) { /* Not used for USBSID (yet) */ runmodel = model; } void USBSID::sampling(float systemclock, float freq, SidConfig::sampling_method_t method) { (void)freq; /* Audio frequency is not used for USBSID-Pico */ (void)method; /* Interpolation method is not used for USBSID-Pico */ if (sidno == 0) { m_sid.USBSID_SetClockRate((long)systemclock, true); /* Set the USBSID internal oscillator speed */ raster_rate = m_sid.USBSID_GetRasterRate(); /* Get the USBSID internal raster rate */ } } void USBSID::event() { event_clock_t cycles = eventScheduler->getTime(EVENT_CLOCK_PHI1) - m_delayClk; if (cycles < raster_rate) { eventScheduler->schedule(*this, raster_rate - cycles, EVENT_CLOCK_PHI1); } else { m_accessClk += cycles; m_delayClk += cycles; m_sid.USBSID_WaitForCycle(cycles); m_sid.USBSID_Flush(); eventScheduler->schedule(*this, raster_rate, EVENT_CLOCK_PHI1); } } void USBSID::flush() /* Only gets call on player exit!? */ { m_sid.USBSID_Flush(); } } /* libsidplayfp */ libsidplayfp-3.0.0/src/builders/usbsid-builder/usbsid-builder.cpp0000644000175100017510000000240015175333711020617 #include #include #include #include #include #include #include #include "usbsid.h" #include "usbsid-emu.h" USBSIDBuilder::USBSIDBuilder(const char * const name) : sidbuilder(name) {} USBSIDBuilder::~USBSIDBuilder() { /* Remove all SID objects */ remove(); } libsidplayfp::sidemu* USBSIDBuilder::create() { /* Always init a new Object */ try { std::unique_ptr sid(new libsidplayfp::USBSID(this)); // SID init failed? if (!sid->getStatus()) { m_errorBuffer = sid->error(); return nullptr; } return sid.release(); } /* Memory alloc failed? */ catch (std::bad_alloc const &) { m_errorBuffer.assign(name()).append(" ERROR: Unable to create USBSID object"); return nullptr; } } const char *USBSIDBuilder::getCredits() const { return libsidplayfp::USBSID::getCredits(); } void USBSIDBuilder::flush() { for (libsidplayfp::sidemu* e: sidobjs) static_cast(e)->flush(); } void USBSIDBuilder::filter (bool enable) { for (libsidplayfp::sidemu* e: sidobjs) static_cast(e)->filter(enable); } libsidplayfp-3.0.0/src/builders/residfp-builder/0000755000175100017510000000000015175333725015432 5libsidplayfp-3.0.0/src/builders/residfp-builder/residfp-builder.cpp0000644000175100017510000000712215175333711021133 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "residfp.h" #include #include #include #include "properties.h" #include "residfp-emu.h" struct ReSIDfpBuilder::config { Property filter8580Curve; Property filter6581Curve; Property filter6581Range; Property cws; Property old6581caps; }; ReSIDfpBuilder::ReSIDfpBuilder(const char * const name) : sidbuilder(name), m_config(new config) {} ReSIDfpBuilder::~ReSIDfpBuilder() { // Remove all SID emulations remove(); delete m_config; } // Create a new sid emulation. libsidplayfp::sidemu* ReSIDfpBuilder::create() { try { auto sid = new libsidplayfp::reSIDfpEmu(this); if (m_config->filter6581Curve.has_value()) sid->filter6581Curve(m_config->filter6581Curve.value()); if (m_config->filter8580Curve.has_value()) sid->filter8580Curve(m_config->filter8580Curve.value()); if (m_config->filter6581Range.has_value()) sid->filter6581Range(m_config->filter6581Range.value()); if (m_config->cws.has_value()) sid->combinedWaveforms(m_config->cws.value()); if (m_config->old6581caps.has_value()) sid->enableOld6581caps(m_config->old6581caps.value()); return sid; } catch (std::bad_alloc const &) { // Memory alloc failed m_errorBuffer.assign(name()).append(" ERROR: Unable to create ReSIDfp object"); return nullptr; } } const char *ReSIDfpBuilder::getCredits() const { return libsidplayfp::reSIDfpEmu::getCredits(); } void ReSIDfpBuilder::filter6581Curve(double filterCurve) { m_config->filter6581Curve = filterCurve; for (libsidplayfp::sidemu* e: sidobjs) static_cast(e)->filter6581Curve(filterCurve); } void ReSIDfpBuilder::filter6581Range(double filterRange) { m_config->filter6581Range = filterRange; for (libsidplayfp::sidemu* e: sidobjs) static_cast(e)->filter6581Range(filterRange); } void ReSIDfpBuilder::filter8580Curve(double filterCurve) { m_config->filter8580Curve = filterCurve; for (libsidplayfp::sidemu* e: sidobjs) static_cast(e)->filter8580Curve(filterCurve); } void ReSIDfpBuilder::combinedWaveformsStrength(SidConfig::sid_cw_t cws) { m_config->cws = cws; for (libsidplayfp::sidemu* e: sidobjs) static_cast(e)->combinedWaveforms(cws); } void ReSIDfpBuilder::enableOld6581caps(bool enable) { m_config->old6581caps = enable; for (libsidplayfp::sidemu* e: sidobjs) static_cast(e)->enableOld6581caps(enable); } libsidplayfp-3.0.0/src/builders/residfp-builder/residfp-emu.cpp0000644000175100017510000001036115175333711020272 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2019 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "residfp-emu.h" #include #include "residfp/residfp.h" #include "sidplayfp/siddefs.h" #ifdef HAVE_CONFIG_H # include "config.h" #endif namespace libsidplayfp { const char ERR_INVALID_CW[] = "Invalid combined waveforms strength."; const char* reSIDfpEmu::getCredits() { return "reSIDfpEmu V" VERSION " Engine:\n" "\t(C) 1999-2002 Simon White\n" "MOS6581/CSG8580 (SID) Emulation:\n" "\t(C) 1999-2002 Dag Lem\n" "\t(C) 2005-2011 Antti S. Lankila\n" "\t(C) 2010-2026 Leandro Nini\n"; } reSIDfpEmu::reSIDfpEmu(sidbuilder *builder) : sidemu(builder), m_sid(*(new reSIDfp::residfp)) { reset(0); } reSIDfpEmu::~reSIDfpEmu() { delete &m_sid; delete[] m_buffer; } // Standard component options void reSIDfpEmu::reset(uint8_t volume) { m_accessClk = 0; m_sid.reset(); m_sid.write(0x18, volume); } uint8_t reSIDfpEmu::read(uint_least8_t addr) { clock(); return m_sid.read(addr); } void reSIDfpEmu::write(uint_least8_t addr, uint8_t data) { clock(); m_sid.write(addr, data); } void reSIDfpEmu::clock() { const event_clock_t cycles = eventScheduler->getTime(EVENT_CLOCK_PHI1) - m_accessClk; m_accessClk += cycles; m_bufferpos += m_sid.clock(cycles, m_buffer+m_bufferpos); } void reSIDfpEmu::sampling(float systemclock, float freq, SidConfig::sampling_method_t method) { reSIDfp::SamplingMethod sampleMethod; switch (method) { case SidConfig::INTERPOLATE: sampleMethod = reSIDfp::DECIMATE; break; case SidConfig::RESAMPLE_INTERPOLATE: sampleMethod = reSIDfp::RESAMPLE; break; default: m_status = false; m_error = ERR_INVALID_SAMPLING; return; } bool res = m_sid.setSamplingParameters(systemclock, sampleMethod, freq); if (!res) { m_status = false; m_error = ERR_UNSUPPORTED_FREQ; return; } if (m_buffer) delete[] m_buffer; // 20ms buffer const int buffersize = std::ceil((freq / 1000.f) * 20.f); m_buffer = new short[buffersize]; m_status = true; } // Set the emulated SID model void reSIDfpEmu::model(SidConfig::sid_model_t model, bool digiboost) { reSIDfp::ChipModel chipModel; switch (model) { case SidConfig::MOS6581: chipModel = reSIDfp::MOS6581; m_sid.input(0); break; case SidConfig::MOS8580: chipModel = reSIDfp::CSG8580; m_sid.input(digiboost ? -32768 : 0); break; default: m_status = false; m_error = ERR_INVALID_CHIP; return; } m_sid.setChipModel(chipModel); m_status = true; } // Set the emulated SID combined waveforms void reSIDfpEmu::combinedWaveforms(SidConfig::sid_cw_t cws) { reSIDfp::CombinedWaveforms combinedWaveforms; switch (cws) { case SidConfig::AVERAGE: combinedWaveforms = reSIDfp::AVERAGE; break; case SidConfig::WEAK: combinedWaveforms = reSIDfp::WEAK; break; case SidConfig::STRONG: combinedWaveforms = reSIDfp::STRONG; break; default: m_status = false; m_error = ERR_INVALID_CW; return; } m_sid.setCombinedWaveforms(combinedWaveforms); m_status = true; } } libsidplayfp-3.0.0/src/builders/residfp-builder/residfp-emu.h0000644000175100017510000000446515175333711017747 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2019 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef RESIDFP_EMU_H #define RESIDFP_EMU_H #include #include "residfp/residfp.h" #include "sidplayfp/SidConfig.h" #include "sidemu.h" #include "Event.h" #include "sidcxx11.h" class sidbuilder; namespace libsidplayfp { class reSIDfpEmu final : public sidemu { private: reSIDfp::residfp &m_sid; public: static const char* getCredits(); public: explicit reSIDfpEmu(sidbuilder *builder); ~reSIDfpEmu() override; bool getStatus() const { return m_status; } uint8_t read(uint_least8_t addr) override; void write(uint_least8_t addr, uint8_t data) override; // c64sid functions void reset(uint8_t volume) override; // Standard SID emu functions void clock() override; void sampling(float systemclock, float freq, SidConfig::sampling_method_t method) override; void model(SidConfig::sid_model_t model, bool digiboost) override; // Specific to residfp void enableFilter(bool enable) { m_sid.enableFilter(enable); } void filter6581Curve(double filterCurve) { m_sid.setFilter6581Curve(filterCurve); } void filter6581Range(double adjustment) { m_sid.setFilter6581Range(adjustment); } void filter8580Curve(double filterCurve) { m_sid.setFilter8580Curve(filterCurve); } void enableOld6581caps(bool enable) { m_sid.enableOld6581caps(enable); } void combinedWaveforms(SidConfig::sid_cw_t cws); }; } #endif // RESIDFP_EMU_H libsidplayfp-3.0.0/src/builders/residfp-builder/residfp.h0000644000175100017510000000477415175333711017166 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef RESIDFP_BUILDER_H #define RESIDFP_BUILDER_H #include "sidplayfp/sidbuilder.h" #include "sidplayfp/siddefs.h" /** * ReSIDfp Builder Class */ class SID_EXTERN ReSIDfpBuilder: public sidbuilder { protected: /** * Create the sid emu. */ libsidplayfp::sidemu* create(); public: ReSIDfpBuilder(const char * const name); ~ReSIDfpBuilder(); const char *getCredits() const; /// @name global settings /// Settings that affect all SIDs. //@{ /** * Set 6581 filter curve type. * * @param filterCurve sets center frequency from 0.0 (dark) to 1.0 (bright). (default 0.5) */ void filter6581Curve(double filterCurve); /** * Set 6581 filter offset and range. * * @param filterRange sets center frequency from 0.0 (dark) to 1.0 (bright). * This also affects the range. (default 0.5) */ void filter6581Range(double filterRange); /** * Set 8580 filter curve type. * * @param filterCurve sets center frequency from 0.0 (dark) to 1.0 (bright). (default 0.5) */ void filter8580Curve(double filterCurve); /** * Enable/disable old caps for 6581 model. * * @param enable true to enable old 2200pF caps used on ASSY 326298 * false to use the standard 470pF caps. */ void enableOld6581caps(bool enable); /** * Set combined waveforms strength. * * @param cws */ void combinedWaveformsStrength(SidConfig::sid_cw_t cws); //@} private: struct config; config *m_config; }; #endif // RESIDFP_BUILDER_H libsidplayfp-3.0.0/src/builders/exsid-builder/0000755000175100017510000000000015175333725015112 5libsidplayfp-3.0.0/src/builders/exsid-builder/exsid-emu.h0000644000175100017510000000434615175333711017105 /*************************************************************************** exsid-emu.h - exSID support interface. ------------------- Based on hardsid-emu.h (C) 2000-2002 Simon White, (C) 2001-2002 Jarno Paananen copyright : (C) 2015 Thibaut VARENE ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * ***************************************************************************/ #ifndef EXSID_EMU_H #define EXSID_EMU_H #include "sidemu.h" #include "Event.h" #include "EventScheduler.h" #include "sidplayfp/siddefs.h" #include "sidcxx11.h" #ifdef HAVE_CONFIG_H # include "config.h" #endif namespace libsidplayfp { /*************************************************************************** * exSID SID Specialisation ***************************************************************************/ class exSID final : public sidemu { private: //friend class HardSIDBuilder; // exSID specific data static unsigned int sid; void * exsid; bool readflag; uint8_t busValue; SidConfig::sid_model_t runmodel; private: unsigned int delay(); public: static const char* getCredits(); public: explicit exSID(sidbuilder *builder); ~exSID() override; bool getStatus() const { return m_status; } uint8_t read(uint_least8_t addr) override; void write(uint_least8_t addr, uint8_t data) override; // c64sid functions void reset(uint8_t volume) override; // Standard SID functions void clock() override; void model(SidConfig::sid_model_t model, bool digiboost) override; void sampling(float systemclock, float freq, SidConfig::sampling_method_t method) override; // exSID specific void flush(); }; } #endif // EXSID_EMU_H libsidplayfp-3.0.0/src/builders/exsid-builder/driver/0000755000175100017510000000000015175333725016405 5libsidplayfp-3.0.0/src/builders/exsid-builder/driver/exSID_defs.h0000644000175100017510000001111215175333712020443 // // exSID_defs.h // A simple I/O library for exSID USB - private header file // // (C) 2015-2017 Thibaut VARENE // License: GPLv2 - http://www.gnu.org/licenses/gpl-2.0.html // /** * @file * libexsid private definitions header file. * @note These defines are closely related to the exSID firmware. * Any modification that does not correspond to a related change in firmware * will cause the device to operate unpredictably or not at all. */ #ifndef exSID_defs_h #define exSID_defs_h #ifdef HAVE_CONFIG_H # include "config.h" #endif // CLOCK_FREQ_NTSC = 1022727.14; // CLOCK_FREQ_PAL = 985248.4; /* common definition for all hardware platforms */ /** * USB buffer multiple. * Each 64-byte USB packet contains 62 user bytes. 4k buffers (the default) thus contain 3968 data bytes. * For optimal throughput performance, data should be sent in chunks that are multiples of this value. * See http://www.ftdichip.com/Support/Documents/AppNotes/AN232B-03_D2XXDataThroughput.pdf section 1.4 */ #define XSC_USBMOD (4096/64*62) #define XSC_USBLAT 1 ///< FTDI latency: 1-255ms in 1ms increments #define XSC_BUFFMS 40 ///< write buffer size in milliseconds of playback (high water mark). /* exSID hardware definitions */ #define XS_BDRATE 2000000 ///< 2Mpbs #define XS_SIDCLK 1000000 ///< 1MHz (for computation only, currently hardcoded in firmware) #define XS_RSBCLK (XS_BDRATE/10) ///< RS232 byte clock. Each RS232 byte is 10 bits long due to start and stop bits #define XS_CYCCHR (XS_SIDCLK/XS_RSBCLK) ///< SID cycles between two consecutive chars //#define XS_CYCCHR ((XS_SIDCLK+XS_RSBCLK-1)/XS_RSBCLK) // ceiling #define XS_BUFFSZ ((((XS_RSBCLK/1000)*XSC_BUFFMS)/XSC_USBMOD)*XSC_USBMOD) ///< Must be multiple of user data transfer size or USB won't be happy. This floors XSC_BUFFMS. #define XS_LDMULT 501 ///< long delay SID cycle loop multiplier #define XS_MINDEL (XS_CYCCHR) ///< Smallest possible delay (with IOCTD1). #define XS_CYCIO (2*XS_CYCCHR) ///< minimum cycles between two consecutive I/Os (addr + data) #define XS_MAXADJ 7 ///< maximum encodable value for post write clock adjustment: must fit on 3 bits #define XS_LDOFFS (3*XS_CYCCHR) ///< long delay loop SID cycles offset /* exSID+ hardware definitions */ #define XSP_RSBCLK 666667 ///< maximum byte clock at 32MHz base clock is approx 666.6kHz (1 byte every 1.5us) #define XSP_BUFFSZ ((((XSP_RSBCLK/1000)*XSC_BUFFMS)/XSC_USBMOD)*XSC_USBMOD) ///< Must be multiple of user data transfer size or USB won't be happy. This floors XSC_BUFFMS. #define XSP_MINDEL 2 ///< Smallest possible delay (with IOCTD1). #define XSP_CYCIO 3 ///< minimum cycles between two consecutive I/Os (addr + data) #define XSP_PRE_RD 2 #define XSP_POSTRD 2 #define XSP_MAXADJ 4 ///< maximum encodable value for post write clock adjustment: must fit on 3 bits #define XSP_LDOFFS 3 ///< long delay loop SID cycles offset #define XSP_CYCCS 2 ///< cycles lost in chipselect() /* IOCTLS */ /* IO controls 0x3D to 0x7F are only implemented on exSID+ */ #define XSP_AD_IOCTCP 0x3D ///< Select PAL clock #define XSP_AD_IOCTCN 0x3E ///< Select NTSC clock #define XSP_AD_IOCTC1 0x3F ///< Select 1MHz clock #define XSP_AD_IOCTA0 0x5D ///< Audio Mix: 6581 L / 8580 R #define XSP_AD_IOCTA1 0x5E ///< Audio Mix: 8580 L / 6581 R #define XSP_AD_IOCTA2 0x5F ///< Audio Mix: 8580 L / 8580 R #define XSP_AD_IOCTA3 0x7D ///< Audio Mix: 6581 L / 6581 R #define XSP_AD_IOCTAM 0x7E ///< Audio Mute #define XSP_AD_IOCTAU 0x7F ///< Audio Unmute #define XS_AD_IOCTD1 0x9D ///< shortest delay (XS_MINDEL SID cycles) #define XS_AD_IOCTLD 0x9E ///< polled delay, amount of SID cycles to wait must be given in data #define XS_AD_IOCTS0 0xBD ///< select chip 0 #define XS_AD_IOCTS1 0xBE ///< select chip 1 #define XS_AD_IOCTSB 0xBF ///< select both chips. @warning Invalid for reads: unknown behaviour! #define XS_AD_IOCTFV 0xFD ///< Firmware version query #define XS_AD_IOCTHV 0xFE ///< Hardware version query #define XS_AD_IOCTRS 0xFF ///< SID reset #define XS_USBVID 0x0403 ///< Default FTDI VID #define XS_USBPID 0x6001 ///< Default FTDI PID #define XS_USBDSC "exSID USB" #define XSP_USBVID 0x0403 ///< Default FTDI VID #define XSP_USBPID 0x6015 ///< Default FTDI PID #define XSP_USBDSC "exSID+ USB" #define XS_MODEL_STD 0 #define XS_MODEL_PLUS 1 #ifdef DEBUG #define xsdbg(format, ...) printf("(%s) " format, __func__, ## __VA_ARGS__) #else #define xsdbg(format, ...) /* nothing */ #endif #ifdef HAVE_BUILTIN_EXPECT #define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) #else #define likely(x) (x) #define unlikely(x) (x) #endif #endif /* exSID_defs_h */ libsidplayfp-3.0.0/src/builders/exsid-builder/driver/docs/0000755000175100017510000000000015175333712017331 5libsidplayfp-3.0.0/src/builders/exsid-builder/driver/docs/mainpage.dox0000644000175100017510000000206215175333712021546 /** @mainpage libexsid A simple I/O library for exSID USB.

Copyright (C) 2015-2018,2021 Thibaut VARENE

Home page:
http://hacks.slashdirt.org/hw/exsid/#exsid-driver
https://github.com/libsidplayfp/exsid-driver ----------------------------------------------------------------------------- This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as published by
the Free Software Foundation. This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ----------------------------------------------------------------------------- */ libsidplayfp-3.0.0/src/builders/exsid-builder/driver/exSID_ftdiwrap.h0000644000175100017510000000532715175333712021355 // // exSID_ftdiwrap.h // A FTDI access wrapper for exSID USB - header file // // (C) 2016 Thibaut VARENE // License: GPLv2 - http://www.gnu.org/licenses/gpl-2.0.html // /** * @file * FTDI access wrapper header file. */ #ifndef exSID_ftdiwrap_h #define exSID_ftdiwrap_h /** Allocate new ftdi handle. */ typedef void * (* xSfw_new_p)(void); /** Free ftdi handle. */ typedef void (* xSfw_free_p)(void * ftdi); /** * Write data to FTDI. * @param ftdi ftdi handle. * @param buf write buffer. * @param size number of bytes to write. * @return number of bytes written or negative error value. * @note there are performance constrains on the size of the buffer, see documentation. */ typedef int (* xSfw_write_data_p)(void * ftdi, const unsigned char * buf, int size); /** * Read data from FTDI. * @param ftdi ftdi handle. * @param buf read buffer. * @param size number of bytes to read. * @return number of bytes read or negative error value. * @note there are performance constrains on the size of the buffer, see documentation. */ typedef int (* xSfw_read_data_p)(void * ftdi, unsigned char * buf, int size); /** * Open device by description. * @param ftdi pointer to ftdi handle. * @param vid target vendor id. Ignored by ftd2xx. * @param pid target product id. Ignored by ftd2xx. * @param desc Description string. * @param serial target product serial. Ignored by ftd2xx. * @return 0 on success or negative error value. * @warning This is the only function to use a pointer to ftdi handle, this is * rendered necessary because of libftd2xx silly way of doing things. */ typedef int (* xSfw_usb_open_desc_p)(void ** ftdi, int vid, int pid, const char * desc, const char * serial); /** Purge FTDI buffers. */ typedef int (* xSfw_usb_purge_buffers_p)(void * ftdi); /** Close FTDI device. */ typedef int (* xSfw_usb_close_p)(void * ftdi); /** * Get error string. * @param ftdi ftdi handle. * @return human-readable error string. * @note only supported with libftdi. */ typedef char * (* xSfw_get_error_string_p)(void * ftdi); #ifndef XSFW_WRAPDECL #define XSFW_EXTERN extern #else #define XSFW_EXTERN /* nothing */ #endif #define XSFW_PROTODEF(a) XSFW_EXTERN a ## _p a XSFW_PROTODEF(xSfw_new); ///< Handle allocation callback XSFW_PROTODEF(xSfw_free); ///< Handle deallocation callback XSFW_PROTODEF(xSfw_write_data); ///< Data write callback XSFW_PROTODEF(xSfw_read_data); ///< Data read callback XSFW_PROTODEF(xSfw_usb_open_desc); ///< Device open callback XSFW_PROTODEF(xSfw_usb_close); ///< Device close callback XSFW_PROTODEF(xSfw_get_error_string); ///< Human readable error string callback int xSfw_usb_setup(void *ftdi, int baudrate, int latency); int xSfw_dlopen(); void xSfw_dlclose(); #endif /* exSID_ftdiwrap_h */ libsidplayfp-3.0.0/src/builders/exsid-builder/driver/exSID_ftdiwrap.c0000644000175100017510000002073615175333712021351 // // exSID_ftdiwrap.c // An FTDI access wrapper for exSID USB // // (C) 2016 Thibaut VARENE // License: GPLv2 - http://www.gnu.org/licenses/gpl-2.0.html // // Coding style is somewhat unorthodox ;P /** * @file * exSID USB FTDI access wrapper * @author Thibaut VARENE * @date 2016 * @note Primary target is libftdi (cleaner API), adaptations are made for others. */ #include "exSID_defs.h" #include #ifdef HAVE_DLFCN_H #include #define TEXT(x) x #elif defined (_WIN32) #include #include // missing include in libftdi on WIN32 #else #error dl not supported #endif #ifdef HAVE_FTD2XX #include #ifndef XSFW_SUPPORT #define XSFW_SUPPORT #endif #else #warning libftd2xx support disabled. #endif #ifdef HAVE_FTDI #include #ifndef XSFW_SUPPORT #define XSFW_SUPPORT #endif #else #warning libftdi support disabled. #endif #ifndef XSFW_SUPPORT #error No known method to access FTDI chip #endif #define XSFW_WRAPDECL #include "exSID_ftdiwrap.h" #define EXSID_INTERFACES "libftdi, libftd2xx" // XXX TODO Should be set by configure #ifdef _WIN32 static HMODULE dlhandle = NULL; static char *_xSfw_dlerror() { DWORD dwError = GetLastError(); char* lpMsgBuf = NULL; FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER, 0, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&lpMsgBuf, 0, NULL); return lpMsgBuf; } #define _xSfw_dlopen(libName) LoadLibrary(libName) #define _xSfw_dlsym(hModule, lpProcName) GetProcAddress(hModule, lpProcName) #define _xSfw_dlclose(hModule) FreeLibrary(hModule) #define _xSfw_clear_dlerror() SetLastError(0) #define _xSfw_free_errstr(str) LocalFree(str) #else // ! _WIN32 static void * dlhandle = NULL; #define _xSfw_dlopen(filename) dlopen(filename, RTLD_NOW|RTLD_LOCAL) #define _xSfw_dlsym(handle, symbol) dlsym(handle, symbol) #define _xSfw_dlclose(handle) dlclose(handle) #define _xSfw_dlerror() dlerror() #define _xSfw_clear_dlerror() dlerror() #define _xSfw_free_errstr(str) /* nothing */ #endif // _WIN32 /** Flag to signal which of the supported libraries is in use */ typedef enum { XS_LIBNONE, XS_LIBFTDI, XS_LIBFTD2XX, } libtype_t; static libtype_t libtype = XS_LIBNONE; // private functions static int (* _xSfw_set_baudrate)(void * ftdi, int baudrate); static int (* _xSfw_set_line_property)(void * ftdi, int bits, int sbit, int parity); static int (* _xSfw_setflowctrl)(void * ftdi, int flowctrl); static int (* _xSfw_set_latency_timer)(void * ftdi, unsigned char latency); // callbacks for ftdi #ifdef HAVE_FTDI static int (* _ftdi_usb_open_desc)(void *, int, int, const char *, const char *); #endif // callbacks for FTD2XX #ifdef HAVE_FTD2XX static int (*_FT_Write)(void *, LPVOID, int, LPDWORD); static int (*_FT_Read)(void *, LPVOID, int, LPDWORD); static int (*_FT_OpenEx)(const char *, int, void **); static int (*_FT_ResetDevice)(void *); static int (*_FT_SetBaudRate)(void *, int); static int (*_FT_SetDataCharacteristics)(void *, int, int, int); static int (*_FT_SetFlowControl)(void *, int, int, int); static int (*_FT_SetLatencyTimer)(void *, unsigned char); static int (*_FT_Close)(void *); #endif // wrappers for ftdi #ifdef HAVE_FTDI static int _xSfwftdi_usb_open_desc(void ** ftdi, int vid, int pid, const char * desc, const char * serial) { return _ftdi_usb_open_desc(*ftdi, vid, pid, desc, serial); } #endif // wrappers for FTD2XX #ifdef HAVE_FTD2XX static int _xSfwFT_write_data(void * restrict ftdi, const unsigned char * restrict buf, int size) { DWORD dummysize; // DWORD in unsigned int int rval; if(unlikely(rval = _FT_Write(ftdi, (LPVOID)buf, size, &dummysize))) return -rval; else return dummysize; } static int _xSfwFT_read_data(void * restrict ftdi, unsigned char * restrict buf, int size) { DWORD dummysize; // DWORD in unsigned int int rval; if (unlikely(rval = _FT_Read(ftdi, (LPVOID)buf, size, &dummysize))) return -rval; else return dummysize; } static int _xSfwFT_usb_open_desc(void ** ftdi, int vid, int pid, const char * desc, const char * serial) { return -_FT_OpenEx(desc, FT_OPEN_BY_DESCRIPTION, ftdi); } static int _xSfwFT_usb_close(void * ftdi) { return -_FT_Close(ftdi); } static char * _xSfwFT_get_error_string(void * ftdi) { return "FTD2XX error"; } #endif /** * Attempt to dlopen a known working library to access FTDI chip. * Will try libftd2xx first, then libftdi. * @return 0 on success, -1 on error. */ int xSfw_dlopen() { #define XSFW_DLSYM(a, b) \ *(void **)(&a) = _xSfw_dlsym(dlhandle, b); \ if (a == NULL) { \ dlerrorstr = _xSfw_dlerror(); \ goto dlfail; \ } char * dlerrorstr = NULL; if (dlhandle) { xsdbg("recursive dlopen()!\n"); return 0; } #ifdef HAVE_FTDI // try libftdi1 first - XXX TODO version check if ((dlhandle = _xSfw_dlopen(TEXT("libftdi1" SHLIBEXT)))) { _xSfw_clear_dlerror(); // clear dlerror XSFW_DLSYM(xSfw_new, "ftdi_new"); XSFW_DLSYM(xSfw_free, "ftdi_free"); XSFW_DLSYM(xSfw_write_data, "ftdi_write_data"); XSFW_DLSYM(xSfw_read_data, "ftdi_read_data"); XSFW_DLSYM(_ftdi_usb_open_desc, "ftdi_usb_open_desc"); xSfw_usb_open_desc = _xSfwftdi_usb_open_desc; XSFW_DLSYM(_xSfw_set_baudrate, "ftdi_set_baudrate"); XSFW_DLSYM(_xSfw_set_line_property, "ftdi_set_line_property"); XSFW_DLSYM(_xSfw_setflowctrl, "ftdi_setflowctrl"); XSFW_DLSYM(_xSfw_set_latency_timer, "ftdi_set_latency_timer"); XSFW_DLSYM(xSfw_usb_close, "ftdi_usb_close"); XSFW_DLSYM(xSfw_get_error_string, "ftdi_get_error_string"); libtype = XS_LIBFTDI; xsdbg("Using libftdi\n"); } else #endif #ifdef HAVE_FTD2XX #ifdef _WIN32 # define LIBFTD2XX "ftd2xx" #else # define LIBFTD2XX "libftd2xx" #endif // otherwise try libftd2xx - XXX TODO version check if ((dlhandle = _xSfw_dlopen(TEXT(LIBFTD2XX SHLIBEXT)))) { _xSfw_clear_dlerror(); // clear dlerror xSfw_new = NULL; xSfw_free = NULL; XSFW_DLSYM(_FT_Write, "FT_Write"); xSfw_write_data = _xSfwFT_write_data; XSFW_DLSYM(_FT_Read, "FT_Read"); xSfw_read_data = _xSfwFT_read_data; XSFW_DLSYM(_FT_OpenEx, "FT_OpenEx"); xSfw_usb_open_desc = _xSfwFT_usb_open_desc; XSFW_DLSYM(_FT_ResetDevice, "FT_ResetDevice"); XSFW_DLSYM(_FT_SetBaudRate, "FT_SetBaudRate"); XSFW_DLSYM(_FT_SetDataCharacteristics, "FT_SetDataCharacteristics"); XSFW_DLSYM(_FT_SetFlowControl, "FT_SetFlowControl"); XSFW_DLSYM(_FT_SetLatencyTimer, "FT_SetLatencyTimer"); XSFW_DLSYM(_FT_Close, "FT_Close"); xSfw_usb_close = _xSfwFT_usb_close; xSfw_get_error_string = _xSfwFT_get_error_string; libtype = XS_LIBFTD2XX; xsdbg("Using libftd2xx\n"); } else #endif // if none worked, fail. { xsdbg("No method found to access FTDI interface.\n" "Are any of the following libraries installed?\n" "\t" EXSID_INTERFACES); return -1; } return 0; dlfail: xsdbg("dlsym error: %s", dlerrorstr); _xSfw_free_errstr(dlerrorstr); xSfw_dlclose(); return -1; } /** * Setup FTDI chip to match exSID firmware. * Defaults to 8N1, no flow control. * @param ftdi ftdi handle * @param baudrate Target baudrate * @param latency Target latency * @return 0 on success, rval on error. */ int xSfw_usb_setup(void * ftdi, int baudrate, int latency) { int rval = 0; #ifdef HAVE_FTDI if (XS_LIBFTDI == libtype) { // ftdi_usb_open_desc() performs device reset rval = _xSfw_set_baudrate(ftdi, baudrate); if (rval < 0) { xsdbg("SBR error"); goto setupfail; } rval = _xSfw_set_line_property(ftdi, BITS_8 , STOP_BIT_1, NONE); if (rval < 0) { xsdbg("SLP error"); goto setupfail; } rval = _xSfw_setflowctrl(ftdi, SIO_DISABLE_FLOW_CTRL); if (rval < 0) { xsdbg("SFC error"); goto setupfail; } rval = _xSfw_set_latency_timer(ftdi, latency); if (rval < 0) { xsdbg("SLT error"); goto setupfail; } } else #endif #ifdef HAVE_FTD2XX if (XS_LIBFTD2XX == libtype) { rval = -_FT_ResetDevice(ftdi); if (rval < 0) { xsdbg("RSD error"); goto setupfail; } rval = -_FT_SetBaudRate(ftdi, baudrate); if (rval < 0) { xsdbg("SBR error"); goto setupfail; } rval = -_FT_SetDataCharacteristics(ftdi, FT_BITS_8, FT_STOP_BITS_1, FT_PARITY_NONE); if (rval < 0) { xsdbg("SLP error"); goto setupfail; } rval = -_FT_SetFlowControl(ftdi, FT_FLOW_NONE, 0, 0); if (rval < 0) { xsdbg("SFC error"); goto setupfail; } rval = -_FT_SetLatencyTimer(ftdi, latency); if (rval < 0) { xsdbg("SLT error"); goto setupfail; } } else #endif xsdbg("Unkown access method\n"); setupfail: return rval; } /** * Release dlopen'd library. */ void xSfw_dlclose() { if (dlhandle != NULL) { _xSfw_dlclose(dlhandle); dlhandle = NULL; } } libsidplayfp-3.0.0/src/builders/exsid-builder/driver/m4/0000755000175100017510000000000015175333712016721 5libsidplayfp-3.0.0/src/builders/exsid-builder/driver/m4/ax_pthread.m40000644000175100017510000005403415175333712021230 # =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_pthread.html # =========================================================================== # # SYNOPSIS # # AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) # # DESCRIPTION # # This macro figures out how to build C programs using POSIX threads. It # sets the PTHREAD_LIBS output variable to the threads library and linker # flags, and the PTHREAD_CFLAGS output variable to any special C compiler # flags that are needed. (The user can also force certain compiler # flags/libs to be tested by setting these environment variables.) # # Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is # needed for multi-threaded programs (defaults to the value of CC # respectively CXX otherwise). (This is necessary on e.g. AIX to use the # special cc_r/CC_r compiler alias.) # # NOTE: You are assumed to not only compile your program with these flags, # but also to link with them as well. For example, you might link with # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS # # If you are only building threaded programs, you may wish to use these # variables in your default LIBS, CFLAGS, and CC: # # LIBS="$PTHREAD_LIBS $LIBS" # CFLAGS="$CFLAGS $PTHREAD_CFLAGS" # CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS" # CC="$PTHREAD_CC" # CXX="$PTHREAD_CXX" # # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant # has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to # that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). # # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the # PTHREAD_PRIO_INHERIT symbol is defined when compiling with # PTHREAD_CFLAGS. # # ACTION-IF-FOUND is a list of shell commands to run if a threads library # is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it # is not found. If ACTION-IF-FOUND is not specified, the default action # will define HAVE_PTHREAD. # # Please let the authors know if this macro fails on any platform, or if # you have any other suggestions or comments. This macro was based on work # by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help # from M. Frigo), as well as ac_pthread and hb_pthread macros posted by # Alejandro Forero Cuervo to the autoconf macro repository. We are also # grateful for the helpful feedback of numerous users. # # Updated for Autoconf 2.68 by Daniel Richard G. # # LICENSE # # Copyright (c) 2008 Steven G. Johnson # Copyright (c) 2011 Daniel Richard G. # Copyright (c) 2019 Marc Stevens # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 31 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ AC_REQUIRE([AC_CANONICAL_HOST]) AC_REQUIRE([AC_PROG_CC]) AC_REQUIRE([AC_PROG_SED]) AC_LANG_PUSH([C]) ax_pthread_ok=no # We used to check for pthread.h first, but this fails if pthread.h # requires special compiler flags (e.g. on Tru64 or Sequent). # It gets checked for in the link test anyway. # First of all, check if the user has set any of the PTHREAD_LIBS, # etcetera environment variables, and if threads linking works using # them: if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then ax_pthread_save_CC="$CC" ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"]) AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"]) CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS]) AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes]) AC_MSG_RESULT([$ax_pthread_ok]) if test "x$ax_pthread_ok" = "xno"; then PTHREAD_LIBS="" PTHREAD_CFLAGS="" fi CC="$ax_pthread_save_CC" CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" fi # We must check for the threads library under a number of different # names; the ordering is very important because some systems # (e.g. DEC) have both -lpthread and -lpthreads, where one of the # libraries is broken (non-POSIX). # Create a list of thread flags to try. Items with a "," contain both # C compiler flags (before ",") and linker flags (after ","). Other items # starting with a "-" are C compiler flags, and remaining items are # library names, except for "none" which indicates that we try without # any flags at all, and "pthread-config" which is a program returning # the flags for the Pth emulation library. ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" # The ordering *is* (sometimes) important. Some notes on the # individual items follow: # pthreads: AIX (must check this before -lpthread) # none: in case threads are in libc; should be tried before -Kthread and # other compiler flags to prevent continual compiler warnings # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) # -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64 # (Note: HP C rejects this with "bad form for `-t' option") # -pthreads: Solaris/gcc (Note: HP C also rejects) # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it # doesn't hurt to check since this sometimes defines pthreads and # -D_REENTRANT too), HP C (must be checked before -lpthread, which # is present but should not be used directly; and before -mthreads, # because the compiler interprets this as "-mt" + "-hreads") # -mthreads: Mingw32/gcc, Lynx/gcc # pthread: Linux, etcetera # --thread-safe: KAI C++ # pthread-config: use pthread-config program (for GNU Pth library) case $host_os in freebsd*) # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) ax_pthread_flags="-kthread lthread $ax_pthread_flags" ;; hpux*) # From the cc(1) man page: "[-mt] Sets various -D flags to enable # multi-threading and also sets -lpthread." ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags" ;; openedition*) # IBM z/OS requires a feature-test macro to be defined in order to # enable POSIX threads at all, so give the user a hint if this is # not set. (We don't define these ourselves, as they can affect # other portions of the system API in unpredictable ways.) AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING], [ # if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS) AX_PTHREAD_ZOS_MISSING # endif ], [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])]) ;; solaris*) # On Solaris (at least, for some versions), libc contains stubbed # (non-functional) versions of the pthreads routines, so link-based # tests will erroneously succeed. (N.B.: The stubs are missing # pthread_cleanup_push, or rather a function called by this macro, # so we could check for that, but who knows whether they'll stub # that too in a future libc.) So we'll check first for the # standard Solaris way of linking pthreads (-mt -lpthread). ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags" ;; esac # Are we compiling with Clang? AC_CACHE_CHECK([whether $CC is Clang], [ax_cv_PTHREAD_CLANG], [ax_cv_PTHREAD_CLANG=no # Note that Autoconf sets GCC=yes for Clang as well as GCC if test "x$GCC" = "xyes"; then AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG], [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */ # if defined(__clang__) && defined(__llvm__) AX_PTHREAD_CC_IS_CLANG # endif ], [ax_cv_PTHREAD_CLANG=yes]) fi ]) ax_pthread_clang="$ax_cv_PTHREAD_CLANG" # GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC) # Note that for GCC and Clang -pthread generally implies -lpthread, # except when -nostdlib is passed. # This is problematic using libtool to build C++ shared libraries with pthread: # [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460 # [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333 # [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555 # To solve this, first try -pthread together with -lpthread for GCC AS_IF([test "x$GCC" = "xyes"], [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"]) # Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first AS_IF([test "x$ax_pthread_clang" = "xyes"], [ax_pthread_flags="-pthread,-lpthread -pthread"]) # The presence of a feature test macro requesting re-entrant function # definitions is, on some systems, a strong hint that pthreads support is # correctly enabled case $host_os in darwin* | hpux* | linux* | osf* | solaris*) ax_pthread_check_macro="_REENTRANT" ;; aix*) ax_pthread_check_macro="_THREAD_SAFE" ;; *) ax_pthread_check_macro="--" ;; esac AS_IF([test "x$ax_pthread_check_macro" = "x--"], [ax_pthread_check_cond=0], [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"]) if test "x$ax_pthread_ok" = "xno"; then for ax_pthread_try_flag in $ax_pthread_flags; do case $ax_pthread_try_flag in none) AC_MSG_CHECKING([whether pthreads work without any flags]) ;; *,*) PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"` PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"` AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"]) ;; -*) AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag]) PTHREAD_CFLAGS="$ax_pthread_try_flag" ;; pthread-config) AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no]) AS_IF([test "x$ax_pthread_config" = "xno"], [continue]) PTHREAD_CFLAGS="`pthread-config --cflags`" PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" ;; *) AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag]) PTHREAD_LIBS="-l$ax_pthread_try_flag" ;; esac ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Check for various functions. We must include pthread.h, # since some functions may be macros. (On the Sequent, we # need a special flag -Kthread to make this header compile.) # We check for pthread_join because it is in -lpthread on IRIX # while pthread_create is in libc. We check for pthread_attr_init # due to DEC craziness with -lpthreads. We check for # pthread_cleanup_push because it is one of the few pthread # functions on Solaris that doesn't have a non-functional libc stub. # We try pthread_create on general principles. AC_LINK_IFELSE([AC_LANG_PROGRAM([#include # if $ax_pthread_check_cond # error "$ax_pthread_check_macro must be defined" # endif static void *some_global = NULL; static void routine(void *a) { /* To avoid any unused-parameter or unused-but-set-parameter warning. */ some_global = a; } static void *start_routine(void *a) { return a; }], [pthread_t th; pthread_attr_t attr; pthread_create(&th, 0, start_routine, 0); pthread_join(th, 0); pthread_attr_init(&attr); pthread_cleanup_push(routine, 0); pthread_cleanup_pop(0) /* ; */])], [ax_pthread_ok=yes], []) CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" AC_MSG_RESULT([$ax_pthread_ok]) AS_IF([test "x$ax_pthread_ok" = "xyes"], [break]) PTHREAD_LIBS="" PTHREAD_CFLAGS="" done fi # Clang needs special handling, because older versions handle the -pthread # option in a rather... idiosyncratic way if test "x$ax_pthread_clang" = "xyes"; then # Clang takes -pthread; it has never supported any other flag # (Note 1: This will need to be revisited if a system that Clang # supports has POSIX threads in a separate library. This tends not # to be the way of modern systems, but it's conceivable.) # (Note 2: On some systems, notably Darwin, -pthread is not needed # to get POSIX threads support; the API is always present and # active. We could reasonably leave PTHREAD_CFLAGS empty. But # -pthread does define _REENTRANT, and while the Darwin headers # ignore this macro, third-party headers might not.) # However, older versions of Clang make a point of warning the user # that, in an invocation where only linking and no compilation is # taking place, the -pthread option has no effect ("argument unused # during compilation"). They expect -pthread to be passed in only # when source code is being compiled. # # Problem is, this is at odds with the way Automake and most other # C build frameworks function, which is that the same flags used in # compilation (CFLAGS) are also used in linking. Many systems # supported by AX_PTHREAD require exactly this for POSIX threads # support, and in fact it is often not straightforward to specify a # flag that is used only in the compilation phase and not in # linking. Such a scenario is extremely rare in practice. # # Even though use of the -pthread flag in linking would only print # a warning, this can be a nuisance for well-run software projects # that build with -Werror. So if the active version of Clang has # this misfeature, we search for an option to squash it. AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread], [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG], [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown # Create an alternate version of $ac_link that compiles and # links in two steps (.c -> .o, .o -> exe) instead of one # (.c -> exe), because the warning occurs only in the second # step ax_pthread_save_ac_link="$ac_link" ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g' ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"` ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)" ax_pthread_save_CFLAGS="$CFLAGS" for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do AS_IF([test "x$ax_pthread_try" = "xunknown"], [break]) CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS" ac_link="$ax_pthread_save_ac_link" AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], [ac_link="$ax_pthread_2step_ac_link" AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])], [break]) ]) done ac_link="$ax_pthread_save_ac_link" CFLAGS="$ax_pthread_save_CFLAGS" AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no]) ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try" ]) case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in no | unknown) ;; *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;; esac fi # $ax_pthread_clang = yes # Various other checks: if test "x$ax_pthread_ok" = "xyes"; then ax_pthread_save_CFLAGS="$CFLAGS" ax_pthread_save_LIBS="$LIBS" CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LIBS="$PTHREAD_LIBS $LIBS" # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. AC_CACHE_CHECK([for joinable pthread attribute], [ax_cv_PTHREAD_JOINABLE_ATTR], [ax_cv_PTHREAD_JOINABLE_ATTR=unknown for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do AC_LINK_IFELSE([AC_LANG_PROGRAM([#include ], [int attr = $ax_pthread_attr; return attr /* ; */])], [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break], []) done ]) AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \ test "x$ax_pthread_joinable_attr_defined" != "xyes"], [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$ax_cv_PTHREAD_JOINABLE_ATTR], [Define to necessary symbol if this constant uses a non-standard name on your system.]) ax_pthread_joinable_attr_defined=yes ]) AC_CACHE_CHECK([whether more special flags are required for pthreads], [ax_cv_PTHREAD_SPECIAL_FLAGS], [ax_cv_PTHREAD_SPECIAL_FLAGS=no case $host_os in solaris*) ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS" ;; esac ]) AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \ test "x$ax_pthread_special_flags_added" != "xyes"], [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS" ax_pthread_special_flags_added=yes]) AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT], [ax_cv_PTHREAD_PRIO_INHERIT], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[int i = PTHREAD_PRIO_INHERIT; return i;]])], [ax_cv_PTHREAD_PRIO_INHERIT=yes], [ax_cv_PTHREAD_PRIO_INHERIT=no]) ]) AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \ test "x$ax_pthread_prio_inherit_defined" != "xyes"], [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.]) ax_pthread_prio_inherit_defined=yes ]) CFLAGS="$ax_pthread_save_CFLAGS" LIBS="$ax_pthread_save_LIBS" # More AIX lossage: compile with *_r variant if test "x$GCC" != "xyes"; then case $host_os in aix*) AS_CASE(["x/$CC"], [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6], [#handle absolute path differently from PATH based program lookup AS_CASE(["x$CC"], [x/*], [ AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"]) AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])]) ], [ AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC]) AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])]) ] ) ]) ;; esac fi fi test -n "$PTHREAD_CC" || PTHREAD_CC="$CC" test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX" AC_SUBST([PTHREAD_LIBS]) AC_SUBST([PTHREAD_CFLAGS]) AC_SUBST([PTHREAD_CC]) AC_SUBST([PTHREAD_CXX]) # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: if test "x$ax_pthread_ok" = "xyes"; then ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1]) : else ax_pthread_ok=no $2 fi AC_LANG_POP ])dnl AX_PTHREAD libsidplayfp-3.0.0/src/builders/exsid-builder/driver/exSID.c0000644000175100017510000006562215175333712017454 // // exSID.c // A simple I/O library for exSID/exSID+ USB // // (C) 2015-2018,2021 Thibaut VARENE // License: GPLv2 - http://www.gnu.org/licenses/gpl-2.0.html /** * @file * exSID/exSID+ USB I/O library * @author Thibaut VARENE * @date 2015-2018,2021 * @version 2.1 * * This driver will control the first exSID device available. * All public API functions are only valid after a successful call to exSID_init(). * To release the device and resources, exSID_exit() and exSID_free() must be called. * * The return value for public routines returning an integer is 0 for successful execution * and !0 for error, unless otherwise noted. * * @warning Although it can internally make use of two separate threads, the driver * implementation is NOT thread safe (since it is not expected that a SID device may * be accessed concurrently), and some optimizations in the code are based on the * assumption that the code is run within a single-threaded environment. */ #include "exSID.h" #include "exSID_defs.h" #include "exSID_ftdiwrap.h" #include #include #include #include #include #include #ifdef EXSID_THREADED #if defined(HAVE_PTHREAD_H) #include #else #error "No thread model available" #endif #endif // EXSID_TRHREADED #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) #define XS_ERRORBUF 256 #define xserror(xs, format, ...) snprintf(xs->xSerrstr, XS_ERRORBUF, "(%s) ERROR " format, __func__, ## __VA_ARGS__) /** * cycles is uint_fast32_t. Technically, clkdrift should be int_fast64_t though * overflow should not happen under normal conditions. */ typedef int_fast32_t clkdrift_t; /** * This private structure holds hardware-dependent constants. */ struct xSconsts_s { unsigned int model; ///< exSID device model in use clkdrift_t write_cycles; ///< number of SID clocks spent in write ops clkdrift_t read_pre_cycles; ///< number of SID clocks spent in read op before data is actually read clkdrift_t read_post_cycles; ///< number of SID clocks spent in read op after data is actually read clkdrift_t read_offset_cycles; ///< read offset adjustment to align with writes (see function documentation) clkdrift_t csioctl_cycles; ///< number of SID clocks spent in chip select ioctl clkdrift_t mindel_cycles; ///< lowest number of SID clocks that can be accounted for in delay clkdrift_t max_adj; ///< maximum number of SID clocks that can be encoded in final delay for read()/write() size_t buff_size; ///< output buffer size }; /** Array of supported devices */ static const struct { const char * desc; ///< USB device description string const int pid; ///< USB PID const int vid; ///< USB VID const struct xSconsts_s xsc; ///< constants specific to the device } xSsupported[] = { { /* exSID USB */ .desc = XS_USBDSC, .pid = XS_USBPID, .vid = XS_USBVID, .xsc = (struct xSconsts_s){ .model = XS_MODEL_STD, .write_cycles = XS_CYCIO, .read_pre_cycles = XS_CYCCHR, .read_post_cycles = XS_CYCCHR, .read_offset_cycles = -2, // see exSID_clkdread() documentation .csioctl_cycles = XS_CYCCHR, .mindel_cycles = XS_MINDEL, .max_adj = XS_MAXADJ, .buff_size = XS_BUFFSZ, }, }, { /* exSID+ USB */ .desc = XSP_USBDSC, .pid = XSP_USBPID, .vid = XSP_USBVID, .xsc = (struct xSconsts_s){ .model = XS_MODEL_PLUS, .write_cycles = XSP_CYCIO, .read_pre_cycles = XSP_PRE_RD, .read_post_cycles = XSP_POSTRD, .read_offset_cycles = 0, .csioctl_cycles = XSP_CYCCS, .mindel_cycles = XSP_MINDEL, .max_adj = XSP_MAXADJ, .buff_size = XSP_BUFFSZ, }, } }; /** exSID private handle */ struct _exsid { /** negative values mean we're lagging, positive mean we're ahead. See it as a number of SID clocks queued to be spent. */ clkdrift_t clkdrift; const struct xSconsts_s * restrict cst; ///< Pointer to constants used by all the hardware access routines. void * ftdi; ///< FTDI device handle. #ifdef DEBUG long accdrift; unsigned long accioops; unsigned long accdelay; unsigned long acccycle; // ensures no overflow with exSID+ up to ~1h of continuous playback #endif int backbuf_idx; ///< current index for the back buffer unsigned char * restrict backbuf; ///< back buffer #ifdef EXSID_THREADED // Variables for flip buffering pthread_mutex_t flip_mtx; pthread_cond_t backbuf_full_cnd, backbuf_avail_cnd; unsigned char * restrict frontbuf; ///< front buffer _Bool backbuf_ready; ///< signals back buffer is ready to be flipped int postdelay; ///< post delay applied after writing frontbuf to device, before the next write is attempted pthread_t thread_output; #endif // EXSID_THREADED uint16_t hwvers; ///< hardware version char xSerrstr[XS_ERRORBUF+1]; ///< XS_ERRORBUF-byte max string for last error message }; /** * Signal-safe nanosleep() wrapper, can be used to wait for exSID. * Some operations stall the device and because we don't use flow control on exSID, we may need to wait. * exSID+ use full bidirectionnal flow control and does not require the wait. * @param usecs requested sleep time in microseconds. * @return return value of nanosleep(), with EINTR handled internally. */ static int _xSusleep(int usecs) { struct timespec tv; int ret; xsdbg("sleep: %d\n", usecs); tv.tv_sec = usecs / 1000000; tv.tv_nsec = (usecs % 1000000) * 1000; while (1) { ret = nanosleep(&tv, &tv); if (ret) { if (EINTR == errno) continue; } return ret; } } /** * Returns a string describing the last recorded error. * @param exsid exsid handle * @return error message (max 256 bytes long). */ const char * exSID_error_str(void * const exsid) { const struct _exsid * const xs = exsid; if (!exsid) return NULL; return (xs->xSerrstr); } /** * Write routine to send data to the device. * Calls USB wrapper. * @note BLOCKING. * @param xs exsid private pointer * @param buff pointer to a byte array of data to send * @param size number of bytes to send */ static inline void xSwrite(struct _exsid * const xs, const unsigned char * buff, int size) { int ret = xSfw_write_data(xs->ftdi, buff, size); #ifdef DEBUG if (unlikely(ret < 0)) { xsdbg("Error ftdi_write_data(%d): %s\n", ret, xSfw_get_error_string(xs->ftdi)); } if (unlikely(ret != size)) { xsdbg("ftdi_write_data only wrote %d (of %d) bytes\n", ret, size); } #endif } /** * Read routine to get data from the device. * Calls USB wrapper. * @warning if EXSID_THREADED is enabled, must not be called once the * output thread is writing to the device (no synchronization with output thread). * @note BLOCKING. * @param xs exsid private pointer * @param buff pointer to a byte array that will be filled with read data * @param size number of bytes to read */ static void xSread(struct _exsid * const xs, unsigned char * buff, int size) { int ret = 0; // libftdi implements a non-blocking read() call that returns 0 if no data was available do { ret += xSfw_read_data(xs->ftdi, buff+ret, size-ret); } while (ret != size); #ifdef DEBUG if (unlikely(ret < 0)) { xsdbg("Error ftdi_read_data(%d): %s\n", ret, xSfw_get_error_string(xs->ftdi)); } if (unlikely(ret != size)) { xsdbg("ftdi_read_data only read %d (of %d) bytes\n", ret, size); } #endif } #ifdef EXSID_THREADED /** * Writer thread. ** consumer ** * This thread consumes the buffer prepared in xSoutb(). * Since writes to the FTDI subsystem are blocking, this thread blocks when it's * writing to the chip, and also while it's waiting for the back buffer to be ready. * When the back buffer is ready, it is flipped with the front one and immediately * released for the next fill, while the front buffer is written to the device. * @note BLOCKING. * @param arg exsid handle * @return DOES NOT RETURN, exits when xs->postdelay is negative. */ static void * _exSID_thread_output(void * arg) { struct _exsid * const xs = arg; unsigned char * bufptr; int frontbuf_idx, delay; #ifdef _GNU_SOURCE pthread_setname_np(pthread_self(), "output"); #endif xsdbg("thread started\n"); while (1) { pthread_mutex_lock(&xs->flip_mtx); // wait for backbuf full while (!xs->backbuf_ready) pthread_cond_wait(&xs->backbuf_full_cnd, &xs->flip_mtx); // Keep the critical section fast and short: delay = xs->postdelay; // record postdelay bufptr = xs->frontbuf; frontbuf_idx = xs->backbuf_idx; xs->frontbuf = xs->backbuf; // flip back to front xs->backbuf = bufptr; xs->backbuf_idx = 0; xs->backbuf_ready = 0; // signal we're done and free mutex pthread_cond_signal(&xs->backbuf_avail_cnd); pthread_mutex_unlock(&xs->flip_mtx); // this blocks outside of mutex held xSwrite(xs, xs->frontbuf, frontbuf_idx); if (unlikely(delay)) { if (unlikely(delay < 0)) { // exit condition xsdbg("thread exiting!\n"); pthread_exit(NULL); } else if (XS_MODEL_STD == xs->cst->model) _xSusleep(delay); } } return NULL; // silence warnings } #endif // EXSID_THREADED /** * Single byte output routine. ** producer ** * Fills a buffer with bytes to send to the device until the buffer is full or a forced write is triggered. * @note No drift compensation is performed on read operations. * @param xs exsid private pointer * @param byte byte to send * @param flush force write flush if positive (add usleep(flush) if >1), trigger thread exit if negative */ static void xSoutb(struct _exsid * const xs, uint8_t byte, int flush) { xs->backbuf[xs->backbuf_idx++] = (unsigned char)byte; if (likely((xs->backbuf_idx < xs->cst->buff_size) && !flush)) return; #ifdef EXSID_THREADED // buffer dance pthread_mutex_lock(&xs->flip_mtx); xs->postdelay = flush; // signal backbuff full xs->backbuf_ready = 1; pthread_cond_signal(&xs->backbuf_full_cnd); // wait for buffer flipped while (xs->backbuf_idx) pthread_cond_wait(&xs->backbuf_avail_cnd, &xs->flip_mtx); pthread_mutex_unlock(&xs->flip_mtx); #else // unthreaded xSwrite(xs, xs->backbuf, xs->backbuf_idx); xs->backbuf_idx = 0; if (unlikely((flush > 1) && (XS_MODEL_STD == xs->cst->model))) _xSusleep(flush); #endif } /** * Allocate an exSID handle. * @return allocated opaque handle, NULL if error. */ void * exSID_new(void) { struct _exsid * xs; xs = calloc(1, sizeof(*xs)); return xs; } /** * Deallocate an exSID handle. * Frees up all memory used by the exSID handle. * @param exsid exsid handle */ void exSID_free(void * exsid) { struct _exsid * xs = exsid; if (!xs) return; if (xSfw_free && xs->ftdi) xSfw_free(xs->ftdi); #ifdef EXSID_THREADED if (xs->frontbuf) free(xs->frontbuf); #endif if (xs->backbuf) free(xs->backbuf); free(xs); } /** * Device init routine. * Must be called once before any operation is attempted on the device. * Opens first available device, and sets various parameters: baudrate, parity, flow * control and USB latency. * @note If this function fails, exSID_free() must still be called. * @param exsid allocated exsid handle generated with exSID_new() * @return 0 on success, !0 otherwise. */ int exSID_init(void * const exsid) { struct _exsid * const xs = exsid; unsigned char buf[2]; int i, ret; xsdbg("libexsid v" EXSID_VERSION "\n"); if (!exsid) { fprintf(stderr, "ERROR: exSID_init: invalid handle\n"); return -1; } if (xSfw_dlopen()) { xserror(xs, "Failed to open dynamic loader"); return -1; } /* Attempt to open all supported devices until first success. * Cleanup ftdi after each try to avoid passing garbage around as we don't know what * the FTDI open routines do with the pointer. */ for (i = 0; i < ARRAY_SIZE(xSsupported); i++) { if (xSfw_new) { xs->ftdi = xSfw_new(); if (!xs->ftdi) { xserror(xs, "ftdi_new failed"); return -1; } } xsdbg("Trying %s...\n", xSsupported[i].desc); xs->cst = &xSsupported[i].xsc; // setting unconditionnally avoids segfaults if user code calls exit() after failure. ret = xSfw_usb_open_desc(&xs->ftdi, xSsupported[i].vid, xSsupported[i].pid, xSsupported[i].desc, NULL); if (ret >= 0) { xsdbg("Opened!\n"); break; } else { xsdbg("Failed: %d (%s)\n", ret, xSfw_get_error_string(xs->ftdi)); if (xSfw_free) xSfw_free(xs->ftdi); xs->ftdi = NULL; } } if (i >= ARRAY_SIZE(xSsupported)) { xserror(xs, "No device could be opened"); return -1; } ret = xSfw_usb_setup(xs->ftdi, XS_BDRATE, XSC_USBLAT); if (ret < 0) { xserror(xs, "Failed to setup device"); return -1; } // success - device is setup xsdbg("Device setup\n"); // Wait for device ready by trying to read hw version and wait for the answer buf[0] = XS_AD_IOCTHV; buf[1] = XS_AD_IOCTFV; // ok as we have a 2-byte RX buffer on PIC xSwrite(xs, buf, 2); xSread(xs, buf, 2); xs->hwvers = buf[0] << 8 | buf[1]; // ensure proper order regardless of endianness xsdbg("HV: %c, FV: %hhu\n", buf[0], buf[1]); xs->backbuf = malloc(xs->cst->buff_size); if (!xs->backbuf) { xserror(xs, "Out of memory!"); return -1; } #ifdef EXSID_THREADED xs->frontbuf = malloc(xs->cst->buff_size); if (!xs->frontbuf) { xserror(xs, "Out of memory!"); return -1; } ret = pthread_mutex_init(&xs->flip_mtx, NULL); ret |= pthread_cond_init(&xs->backbuf_avail_cnd, NULL); ret |= pthread_cond_init(&xs->backbuf_full_cnd, NULL); ret |= pthread_create(&xs->thread_output, NULL, _exSID_thread_output, xs); if (ret) { xserror(xs, "Thread setup failed"); return -1; } xsdbg("Thread setup\n"); #endif xsdbg("buffer size: %zu bytes\n", xs->cst->buff_size); xsdbg("Rock'n'roll!\n"); return 0; } /** * Device exit routine. * Must be called to release the device. * Resets the SIDs, frees buffers and closes FTDI device. * @param exsid exsid handle * @return execution status */ int exSID_exit(void * const exsid) { struct _exsid * const xs = exsid; int ret = 0; if (!xs) return -1; if (xs->ftdi) { exSID_reset(xs); #ifdef EXSID_THREADED xSoutb(xs, XS_AD_IOCTD1, -1); // signal end of thread pthread_join(xs->thread_output, NULL); pthread_cond_destroy(&xs->backbuf_full_cnd); pthread_cond_destroy(&xs->backbuf_avail_cnd); pthread_mutex_destroy(&xs->flip_mtx); if (xs->frontbuf) free(xs->frontbuf); xs->frontbuf = NULL; #endif if (xs->backbuf) free(xs->backbuf); xs->backbuf = NULL; ret = xSfw_usb_close(xs->ftdi); if (ret < 0) xserror(xs, "Unable to close ftdi device: %d (%s)", ret, xSfw_get_error_string(xs->ftdi)); if (xSfw_free) xSfw_free(xs->ftdi); xs->ftdi = NULL; #ifdef DEBUG xsdbg("mean jitter: %.2f cycle(s) over %lu I/O ops\n", ((float)xs->accdrift/xs->accioops), xs->accioops); xsdbg("bandwidth used for I/O ops: %lu%% (approx)\n", 100-(xs->accdelay*100/xs->acccycle)); xs->accdrift = xs->accioops = xs->accdelay = xs->acccycle = 0; #endif } xs->clkdrift = 0; xSfw_dlclose(); return ret; } /** * SID reset routine. * Performs a hardware reset on the SIDs. * This also resets the internal drift adjustment counter. * @note since the reset procedure in firmware will stall the device, * reset can wait before resuming execution. * @param exsid exsid handle * @return execution status */ int exSID_reset(void * const exsid) { struct _exsid * const xs = exsid; if (!xs) return -1; xsdbg("reset\n"); xSoutb(xs, XS_AD_IOCTRS, 100); // this will stall xs->clkdrift = 0; return 0; } /** * exSID+ clock selection routine. * Selects between PAL, NTSC and 1MHz clocks. Only implemented in exSID+ devices. * @note upon clock change the hardware resync itself and resets the SIDs, which * takes approximately 50us: this call introduces a stall in the stream * and resets the internal drift adjustment counter. Output should be muted before execution. * @param exsid exsid handle * @param clock clock selector value, see exSID.h. * @return execution status */ int exSID_clockselect(void * const exsid, int clock) { struct _exsid * const xs = exsid; if (!xs) return -1; xsdbg("clk: %d\n", clock); if (XS_MODEL_PLUS != xs->cst->model) return -1; switch (clock) { case XS_CL_PAL: xSoutb(xs, XSP_AD_IOCTCP, 100); break; case XS_CL_NTSC: xSoutb(xs, XSP_AD_IOCTCN, 100); break; case XS_CL_1MHZ: xSoutb(xs, XSP_AD_IOCTC1, 100); break; default: return -1; } xs->clkdrift = 0; // reset drift return 0; } /** * exSID+ audio operations routine. * Selects the audio mixing / muting option. Only implemented in exSID+ devices. * @warning all these operations (excepting unmuting obviously) will mute the * output by default. * @note no accounting for SID cycles consumed (not expected to be used during playback). * @param exsid exsid handle * @param operation audio operation value, see exSID.h. * @return execution status */ int exSID_audio_op(void * const exsid, int operation) { struct _exsid * const xs = exsid; if (!xs) return -1; xsdbg("auop: %d\n", operation); if (XS_MODEL_PLUS != xs->cst->model) return -1; switch (operation) { case XS_AU_6581_8580: xSoutb(xs, XSP_AD_IOCTA0, 0); break; case XS_AU_8580_6581: xSoutb(xs, XSP_AD_IOCTA1, 0); break; case XS_AU_8580_8580: xSoutb(xs, XSP_AD_IOCTA2, 0); break; case XS_AU_6581_6581: xSoutb(xs, XSP_AD_IOCTA3, 0); break; case XS_AU_MUTE: xSoutb(xs, XSP_AD_IOCTAM, 0); break; case XS_AU_UNMUTE: xSoutb(xs, XSP_AD_IOCTAU, 0); break; default: return -1; } return 0; } /** * SID chipselect routine. * Selects which SID will play the tunes. * @note Accounts for elapsed cycles. * @param exsid exsid handle * @param chip SID selector value, see exSID.h. * @return execution status */ int exSID_chipselect(void * const exsid, int chip) { struct _exsid * const xs = exsid; if (!xs) return -1; xs->clkdrift -= xs->cst->csioctl_cycles; xsdbg("cs: %d\n", chip); switch (chip) { case XS_CS_CHIP0: xSoutb(xs, XS_AD_IOCTS0, 0); break; case XS_CS_CHIP1: xSoutb(xs, XS_AD_IOCTS1, 0); break; case XS_CS_BOTH: xSoutb(xs, XS_AD_IOCTSB, 0); break; default: return -1; } return 0; } /** * Device hardware model. * Queries the driver for the hardware model currently identified. * @param exsid exsid handle * @return hardware model as enumerated in exSID.h, negative value on error. */ int exSID_hwmodel(void * const exsid) { struct _exsid * const xs = exsid; int model; if (!xs) return -1; switch (xs->cst->model) { case XS_MODEL_STD: model = XS_MD_STD; break; case XS_MODEL_PLUS: model = XS_MD_PLUS; break; default: model = -1; break; } xsdbg("HW model: %d\n", model); return model; } /** * Hardware and firmware version of the device. * Returns both in the form of a 16bit integer: MSB is an ASCII * character representing the hardware revision (e.g. 0x42 = "B"), and LSB * is a number representing the firmware version in decimal integer. * Does not reach the hardware (information is fetched once in exSID_init()). * @param exsid exsid handle * @return version information as described above, or 0xFFFF if error. */ uint16_t exSID_hwversion(void * const exsid) { struct _exsid * const xs = exsid; if (!xs) return 0xFFFF; return xs->hwvers; } /** * Private delay loop. * Introduces NOP requests to the device for the sole purpose of elapsing a number of SID clock cycles. * @param xs exsid private pointer * @param cycles how many SID clocks to loop for. */ static inline void xSdelay(struct _exsid * const xs, uint_fast32_t cycles) { #ifdef DEBUG xs->accdelay += cycles; #endif while (likely(cycles >= xs->cst->mindel_cycles)) { xSoutb(xs, XS_AD_IOCTD1, 0); cycles -= xs->cst->mindel_cycles; xs->clkdrift -= xs->cst->mindel_cycles; } #ifdef DEBUG xs->accdelay -= cycles; #endif } /** * Cycle accurate delay routine. * Delay for cycles SID clocks while leaving enough lead time for an I/O operation. * @param exsid exsid handle * @param cycles how many SID clocks to loop for. * @return 0 on success, -1 on error and 1 if the requested number of cycles is smaller than the feasible delay */ int exSID_delay(void * const exsid, uint_fast32_t cycles) { struct _exsid * const xs = exsid; uint_fast32_t delay; if (unlikely(!xs)) return -1; xs->clkdrift += cycles; #ifdef DEBUG xs->acccycle += cycles; #endif if (unlikely(xs->clkdrift <= xs->cst->write_cycles)) // never delay for less than a full write would need return 1; // too short delay = xs->clkdrift - xs->cst->write_cycles; xSdelay(xs, delay); return 0; } /** * Private write routine for a tuple address + data. * @param xs exsid private pointer * @param addr target address to write to. * @param data data to write at that address. * @param flush if non-zero, force immediate flush to device. */ static inline void _exSID_write(struct _exsid * const xs, uint_least8_t addr, uint8_t data, int flush) { xSoutb(xs, (unsigned char)addr, 0); xSoutb(xs, (unsigned char)data, flush); } /** * Timed write routine, attempts cycle-accurate writes. * This function will be cycle-accurate provided that no two consecutive writes * are less than write_cycles apart and the leftover delay is <= max_adj SID clock cycles. * @note this function accepts writes to invalid addresses (> 0x18). If DEBUG is enabled * it will not pass them to the hardware and return 1. Elapsed SID cycles will still be accounted for. * @param exsid exsid handle * @param cycles how many SID clocks to wait before the actual data write. * @param addr target address. * @param data data to write at that address. * @return -1 if error, 0 on success */ int exSID_clkdwrite(void * const exsid, uint_fast32_t cycles, uint_least8_t addr, uint8_t data) { struct _exsid * const xs = exsid; int adj; if (unlikely(!xs)) return -1; #ifdef DEBUG if (unlikely(addr > 0x18)) { xsdbg("Invalid write: %.2" PRIxLEAST8 "\n", addr); exSID_delay(xs, cycles); return 1; } #endif // actual write will cost write_cycles. Delay for cycles - write_cycles then account for the write xs->clkdrift += cycles; if (xs->clkdrift > xs->cst->write_cycles) xSdelay(xs, xs->clkdrift - xs->cst->write_cycles); xs->clkdrift -= xs->cst->write_cycles; // write is going to consume write_cycles clock ticks #ifdef DEBUG if (xs->clkdrift >= xs->cst->mindel_cycles) xsdbg("Impossible drift adjustment! %" PRIdFAST32 " cycles\n", xs->clkdrift); else if (xs->clkdrift < 0) xs->accdrift += xs->clkdrift; #endif /* if we are still going to be early, delay actual write by up to max_adj ticks At this point it is guaranted that clkdrift will be < mindel_cycles. */ if (likely(xs->clkdrift >= 0)) { adj = xs->clkdrift % (xs->cst->max_adj+1); /* if max_adj is >= clkdrift, modulo will give the same results as the correct test: adj = (clkdrift < max_adj ? clkdrift : max_adj) but without an extra conditional branch. If is is < max_adj, then it seems to provide better results by evening jitter accross writes. So it's the preferred solution for all cases. */ addr = (unsigned char)(addr | (adj << 5)); // final delay encoded in top 3 bits of address #ifdef DEBUG xs->accdrift += (xs->clkdrift - adj); #endif //xsdbg("drft: %d, adj: %d, addr: %.2hhx, data: %.2hhx\n", clkdrift, adj, (char)(addr | (adj << 5)), data); } #ifdef DEBUG xs->acccycle += cycles; xs->accioops++; #endif //xsdbg("delay: %d, clkdrift: %d\n", cycles, xs->clkdrift); _exSID_write(xs, addr, data, 0); return 0; } /** * BLOCKING Timed read routine, attempts cycle-accurate reads. * The following description is based on exSID (standard). * This function will be cycle-accurate provided that no two consecutive reads or writes * are less than XS_CYCIO apart and leftover delay is <= max_adj SID clock cycles. * Read result will only be available after a full XS_CYCIO, giving clkdread() the same * run time as clkdwrite(). There's a 2-cycle negative adjustment in the code because * that's the actual offset from the write calls ('/' denotes falling clock edge latch), * which the following ASCII tries to illustrate:
* Write looks like this in firmware: * > ...|_/_|... * ...end of data byte read | cycle during which write is enacted / next cycle | etc...
* Read looks like this in firmware: * > ...|_|_|_/_|_|... * ...end of address byte read | 2 cycles for address processing | cycle during which SID is read / * then half a cycle later the CYCCHR-long data TX starts, cycle completes | another cycle | etc...
* This explains why reads happen a relative 2-cycle later than then should with * respect to writes. * @warning this function is only valid if EXSID_THREADED is not defined. If it * is called when EXSID_THREADED is defined, no read will be performed, however * the requested cycles will still be clocked. * @note this function accepts reads from invalid addresses (addr < 0x19 or addr > 0x1c). * If DEBUG is enabled it will not pass them to the hardware and return 1. Elapsed SID * cycles will still be accounted for. * @note The actual time the read will take to complete depends * on the USB bus activity and settings. It *should* complete in XSC_USBLAT ms, but * not less, meaning that read operations are bound to introduce timing inaccuracy. * As such, this function is only really provided as a proof of concept but SHOULD * BETTER BE AVOIDED. * @param exsid exsid handle * @param cycles how many SID clocks to wait before the actual data read. * @param addr target address. * @param data pointer to store data read from address. * @return -1 if error, 0 on success */ int exSID_clkdread(void * const exsid, uint_fast32_t cycles, uint_least8_t addr, uint8_t * data) { struct _exsid * const xs = exsid; #ifndef EXSID_THREADED int adj; if (unlikely(!xs || !data)) return -1; #ifdef DEBUG if (unlikely((addr < 0x19) || (addr > 0x1C))) { xsdbg("Invalid read: %.2" PRIxLEAST8 "\n", addr); exSID_delay(xs, cycles); return 1; } #endif // actual read will happen after read_pre_cycles. Delay for cycles - read_pre_cycles then account for the read xs->clkdrift += xs->cst->read_offset_cycles; // 2-cycle offset adjustement, see function documentation. xs->clkdrift += cycles; if (xs->clkdrift > xs->cst->read_pre_cycles) xSdelay(xs, xs->clkdrift - xs->cst->read_pre_cycles); xs->clkdrift -= xs->cst->read_pre_cycles; // read request is going to consume read_pre_cycles clock ticks #ifdef DEBUG if (xs->clkdrift > xs->cst->mindel_cycles) xsdbg("Impossible drift adjustment! %" PRIdFAST32 " cycles", xs->clkdrift); else if (xs->clkdrift < 0) { xs->accdrift += xs->clkdrift; xsdbg("Late read request! %" PRIdFAST32 " cycles\n", xs->clkdrift); } #endif // if we are still going to be early, delay actual read by up to max_adj ticks if (likely(xs->clkdrift >= 0)) { adj = xs->clkdrift % (xs->cst->max_adj+1); // see clkdwrite() addr = (unsigned char)(addr | (adj << 5)); // final delay encoded in top 3 bits of address #ifdef DEBUG xs->accdrift += (xs->clkdrift - adj); #endif //xsdbg("drft: %d, adj: %d, addr: %.2hhx, data: %.2hhx\n", clkdrift, adj, (char)(addr | (adj << 5)), data); } #ifdef DEBUG xs->acccycle += cycles; xs->accioops++; #endif // after read has completed, at least another read_post_cycles will have been spent xs->clkdrift -= xs->cst->read_post_cycles; //xsdbg("delay: %d, clkdrift: %d\n", cycles, clkdrift); xSoutb(xs, addr, 1); xSread(xs, data, 1); // blocking return 0; #else // !EXSID_THREADED exSID_delay(xs, cycles); return -1; #endif } libsidplayfp-3.0.0/src/builders/exsid-builder/driver/exSID.h0000644000175100017510000000440615175333712017452 // // exSID.h // A simple I/O library for exSID USB - interface header file // // (C) 2015-2017,2021 Thibaut VARENE // License: GPLv2 - http://www.gnu.org/licenses/gpl-2.0.html // /** * @file * libexsid interface header file. */ #ifndef exSID_h #define exSID_h #ifdef __cplusplus extern "C" { #endif #include #define EXSID_MAJOR_VERSION 2 #define EXSID_MINOR_VERSION 1 #define EXSID_REVISION 0 #define EXSID_VERSION _xxstr(EXSID_MAJOR_VERSION) "." _xxstr(EXSID_MINOR_VERSION) "." _xxstr(EXSID_REVISION) #define EXSID_VERSION_CHECK(maj, min) ((maj==EXSID_MAJOR_VERSION) && (min<=EXSID_MINOR_VERSION)) #define _xstr(x) #x #define _xxstr(x) _xstr(x) /** Chip selection values for exSID_chipselect() */ enum { XS_CS_CHIP0, ///< 6581 XS_CS_CHIP1, ///< 8580 XS_CS_BOTH, ///< Both chips. @warning Invalid for reads: undefined behaviour! }; /** Audio output operations for exSID_audio_op() */ enum { XS_AU_6581_8580, ///< mix: 6581 L / 8580 R XS_AU_8580_6581, ///< mix: 8580 L / 6581 R XS_AU_8580_8580, ///< mix: 8580 L and R XS_AU_6581_6581, ///< mix: 6581 L and R XS_AU_MUTE, ///< mute output XS_AU_UNMUTE, ///< unmute output }; /** Clock selection values for exSID_clockselect() */ enum { XS_CL_PAL, ///< select PAL clock XS_CL_NTSC, ///< select NTSC clock XS_CL_1MHZ, ///< select 1MHz clock }; /** Hardware model return values for exSID_hwmodel() */ enum { XS_MD_STD, ///< exSID USB XS_MD_PLUS, ///< exSID+ USB }; // public interface void * exSID_new(void); void exSID_free(void * exsid); int exSID_init(void * const exsid); int exSID_exit(void * const exsid); int exSID_reset(void * const exsid); int exSID_hwmodel(void * const exsid); uint16_t exSID_hwversion(void * const exsid); int exSID_clockselect(void * const exsid, int clock); int exSID_audio_op(void * const exsid, int operation); int exSID_chipselect(void * const exsid, int chip); int exSID_delay(void * const exsid, uint_fast32_t cycles); int exSID_clkdwrite(void * const exsid, uint_fast32_t cycles, uint_least8_t addr, uint8_t data); const char * exSID_error_str(void * const exsid); /* NB: read interface is only provided as proof of concept */ int exSID_clkdread(void * const exsid, uint_fast32_t cycles, uint_least8_t addr, uint8_t * data); #ifdef __cplusplus } #endif #endif /* exSID_h */ libsidplayfp-3.0.0/src/builders/exsid-builder/exsid-emu.cpp0000644000175100017510000001007415175333711017433 /*************************************************************************** exsid.cpp - exSID support interface. ------------------- Based on hardsid.cpp (C) 2001 Jarno Paananen copyright : (C) 2015-2017,2021 Thibaut VARENE ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * ***************************************************************************/ #include "exsid-emu.h" #include #include #include #ifdef HAVE_EXSID # include #else # include "driver/exSID.h" #endif #include "sidcxx11.h" namespace libsidplayfp { unsigned int exSID::sid = 0; const char* exSID::getCredits() { return "exSID V" VERSION " Engine:\n" "\t(C) 2015-2017,2021 Thibaut VARENE\n"; } exSID::exSID(sidbuilder *builder) : sidemu(builder), readflag(false), busValue(0) { exsid = exSID_new(); if (!exsid) { m_error = "out of memory"; m_status = false; return; } if (exSID_init(exsid) < 0) { m_error = exSID_error_str(exsid); m_status = false; return; } sid++; } exSID::~exSID() { sid--; if (m_status) exSID_audio_op(exsid, XS_AU_MUTE); exSID_exit(exsid); exSID_free(exsid); } void exSID::reset(uint8_t volume) { exSID_reset(exsid); exSID_clkdwrite(exsid, 0, 0x18, volume); // this will offset the internal clock m_accessClk = 0; readflag = false; } unsigned int exSID::delay() { event_clock_t cycles = eventScheduler->getTime(EVENT_CLOCK_PHI1) - m_accessClk; m_accessClk += cycles; while (cycles > 0xffff) { exSID_delay(exsid, 0xffff); cycles -= 0xffff; } return static_cast(cycles); } void exSID::clock() { const unsigned int cycles = delay(); if (cycles) exSID_delay(exsid, cycles); } uint8_t exSID::read(uint_least8_t addr) { if ((addr < 0x19) || (addr > 0x1C)) { return busValue; } if (!readflag) { #ifdef DEBUG printf("WARNING: Read support is limited. This file may not play correctly!\n"); #endif readflag = true; // Here we implement the "safe" detection routine return values if (0x1b == addr) { // we could implement a commandline-chosen return byte here return (SidConfig::MOS8580 == runmodel) ? 0x02 : 0x03; } } const unsigned int cycles = delay(); exSID_clkdread(exsid, cycles, addr, &busValue); // busValue is updated on valid reads return busValue; } void exSID::write(uint_least8_t addr, uint8_t data) { busValue = data; if (addr > 0x18) return; const unsigned int cycles = delay(); exSID_clkdwrite(exsid, cycles, addr, data); } void exSID::model(SidConfig::sid_model_t model, MAYBE_UNUSED bool digiboost) { runmodel = model; // currently no support for stereo mode: output the selected SID to both L and R channels exSID_audio_op(exsid, model == SidConfig::MOS8580 ? XS_AU_8580_8580 : XS_AU_6581_6581); // mutes output //exSID_audio_op(exsid, XS_AU_UNMUTE); // sampling is set after model, no need to unmute here and cause pops exSID_chipselect(exsid, model == SidConfig::MOS8580 ? XS_CS_CHIP1 : XS_CS_CHIP0); } void exSID::flush() {} void exSID::sampling(float systemclock, MAYBE_UNUSED float freq, MAYBE_UNUSED SidConfig::sampling_method_t method) { exSID_audio_op(exsid, XS_AU_MUTE); if (systemclock < 1000000.0F) exSID_clockselect(exsid, XS_CL_PAL); else exSID_clockselect(exsid, XS_CL_NTSC); exSID_audio_op(exsid, XS_AU_UNMUTE); } } libsidplayfp-3.0.0/src/builders/exsid-builder/exsid-builder.cpp0000644000175100017510000000410615175333711020272 /*************************************************************************** exsid-builder.cpp - exSID builder class for creating/controlling exSIDs. ------------------- Based on hardsid-builder.cpp (C) 2001 Simon White copyright : (C) 2015 Thibaut VARENE ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * ***************************************************************************/ #include #include #include #include #include #include #include #include "properties.h" #include "exsid.h" #include "exsid-emu.h" exSIDBuilder::exSIDBuilder(const char * const name) : sidbuilder(name) {} exSIDBuilder::~exSIDBuilder() { // Remove all SID emulations remove(); } // Create a new sid emulation. Called by sidbuilder only libsidplayfp::sidemu* exSIDBuilder::create() { try { std::unique_ptr sid(new libsidplayfp::exSID(this)); // SID init failed? if (!sid->getStatus()) { m_errorBuffer = sid->error(); return nullptr; } return sid.release(); } // Memory alloc failed? catch (std::bad_alloc const &) { m_errorBuffer.assign(name()).append(" ERROR: Unable to create exSID object"); return nullptr; } } const char *exSIDBuilder::getCredits() const { return libsidplayfp::exSID::getCredits(); } void exSIDBuilder::flush() { for (libsidplayfp::sidemu* e: sidobjs) static_cast(e)->flush(); } libsidplayfp-3.0.0/src/builders/exsid-builder/exsid.h0000644000175100017510000000241215175333711016311 /*************************************************************************** exsid.h - exSID support interface. ------------------- Based on hardsid.h (C) 2000-2002 Simon White copyright : (C) 2015 Thibaut VARENE ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License version 2 as * * published by the Free Software Foundation. * * * ***************************************************************************/ #ifndef EXSID_H #define EXSID_H #include "sidplayfp/sidbuilder.h" #include "sidplayfp/siddefs.h" class SID_EXTERN exSIDBuilder : public sidbuilder { protected: /** * Create the sid emu. */ libsidplayfp::sidemu* create(); public: exSIDBuilder(const char * const name); ~exSIDBuilder(); const char *getCredits() const; void flush(); }; #endif // EXSID_H libsidplayfp-3.0.0/src/c64/0000755000175100017510000000000015175333725011135 5libsidplayfp-3.0.0/src/c64/c64sid.h0000644000175100017510000000346515175333711012325 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2013-2024 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef C64SID_H #define C64SID_H #include "Banks/Bank.h" #include "sidcxx11.h" #include #include #include #include namespace libsidplayfp { /** * SID interface. */ class c64sid : public Bank { private: uint8_t lastpoke[0x20]; protected: virtual ~c64sid() = default; virtual uint8_t read(uint_least8_t addr) = 0; virtual void writeReg(uint_least8_t addr, uint8_t data) = 0; virtual void reset(uint8_t volume) = 0; public: void reset() { std::fill(std::begin(lastpoke), std::end(lastpoke), 0); reset(0xf); } // Bank functions void poke(uint_least16_t address, uint8_t value) override { lastpoke[address & 0x1f] = value; writeReg(address & 0x1f, value); } uint8_t peek(uint_least16_t address) override { return read(address & 0x1f); } void getStatus(uint8_t regs[0x20]) const { std::memcpy(regs, lastpoke, 0x20); } }; } #endif // C64SID_H libsidplayfp-3.0.0/src/c64/Banks/0000755000175100017510000000000015175333725012173 5libsidplayfp-3.0.0/src/c64/Banks/ExtraSidBank.h0000644000175100017510000000457115175333711014605 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2024 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef EXTRASIDBANK_H #define EXTRASIDBANK_H #include "Bank.h" #include #include "c64/c64sid.h" #include "sidcxx11.h" namespace libsidplayfp { /** * Extra SID bank. */ class ExtraSidBank final : public Bank { private: using sids_t = std::vector; private: /** * Size of mapping table. Each 32 bytes another SID chip base address * can be assigned to. */ static constexpr int MAPPER_SIZE = 8; private: /** * SID mapping table. * Maps a SID chip base address to a SID * or to the underlying bank. */ Bank *mapper[MAPPER_SIZE]; sids_t sids; private: static unsigned int mapperIndex(int address) { return address >> 5 & (MAPPER_SIZE - 1); } public: virtual ~ExtraSidBank() = default; void reset() { for (c64sid* sid: sids) sid->reset(); } void resetSIDMapper(Bank *bank) { for (int i = 0; i < MAPPER_SIZE; i++) mapper[i] = bank; } uint8_t peek(uint_least16_t addr) override { return mapper[mapperIndex(addr)]->peek(addr); } void poke(uint_least16_t addr, uint8_t data) override { mapper[mapperIndex(addr)]->poke(addr, data); } /** * Set SID emulation. * * @param s the emulation * @param address the address where to put the chip */ void addSID(c64sid *s, int address) { sids.push_back(s); mapper[mapperIndex(address)] = s; } unsigned int installedSIDs() const { return sids.size(); } }; } #endif libsidplayfp-3.0.0/src/c64/Banks/IOBank.h0000644000175100017510000000304515175333711013364 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2013 Leandro Nini * Copyright 2010 Antti Lankila * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef IOBANK_H #define IOBANK_H #include #include "Bank.h" #include "sidcxx11.h" namespace libsidplayfp { /** * IO region handler. 4k region, 16 chips, 256b banks. * * Located at $D000-$DFFF */ class IOBank final : public Bank { private: Bank* map[16]; public: void setBank(int num, Bank* bank) { map[num] = bank; } Bank *getBank(int num) const { return map[num]; } uint8_t peek(uint_least16_t addr) override { return map[(addr >> 8) & 0xf]->peek(addr); } void poke(uint_least16_t addr, uint8_t data) override { map[(addr >> 8) & 0xf]->poke(addr, data); } }; } #endif libsidplayfp-3.0.0/src/c64/Banks/SidBank.h0000644000175100017510000000325715175333711013601 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2013 Leandro Nini * Copyright 2010 Antti Lankila * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDBANK_H #define SIDBANK_H #include "Bank.h" #include "c64/c64sid.h" #include "sidcxx11.h" #include "NullSid.h" namespace libsidplayfp { /** * SID * * Located at $D400-$D7FF, mirrored each 32 bytes */ class SidBank final : public Bank { private: /// SID chip c64sid *sid; public: SidBank() : sid(NullSid::getInstance()) {} void reset() { sid->reset(); } uint8_t peek(uint_least16_t addr) override { return sid->peek(addr); } void poke(uint_least16_t addr, uint8_t data) override { sid->poke(addr, data); } /** * Set SID emulation. * * @param s the emulation, nullptr to remove current sid */ void setSID(c64sid *s) { sid = (s != nullptr) ? s : NullSid::getInstance(); } }; } #endif libsidplayfp-3.0.0/src/c64/Banks/NullSid.h0000644000175100017510000000276415175333711013642 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2014 Leandro Nini * Copyright 2010 Antti Lankila * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef NULLSID_H #define NULLSID_H #include "c64/c64sid.h" #include "sidcxx11.h" namespace libsidplayfp { /** * SID chip placeholder which does nothing and returns 0xff on reading. */ class NullSid final : public c64sid { private: NullSid() {} ~NullSid() override = default; public: /** * Returns singleton instance. */ static NullSid *getInstance() { static NullSid nullsid; return &nullsid; } void reset(uint8_t) override {} void writeReg(uint_least8_t, uint8_t) override {} uint8_t read(uint_least8_t) override { return 0xff; } }; } #endif // NULLSID_H libsidplayfp-3.0.0/src/c64/Banks/SystemROMBanks.h0000644000175100017510000001637615175333711015115 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2026 Leandro Nini * Copyright 2010 Antti Lankila * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SYSTEMROMBANKS_H #define SYSTEMROMBANKS_H #include #include #include #include #include "Bank.h" #include "c64/CPU/opcodes.h" #include "sidcxx11.h" namespace libsidplayfp { /** * ROM bank base class. */ template class romBank : public Bank { static_assert((N > 0) && ((N & (N - 1)) == 0), "N must be a power of two"); protected: /// The ROM array uint8_t rom[N]; protected: ~romBank() = default; /** * Set value at memory address. */ inline void setVal(uint_least16_t address, uint8_t val) { rom[address & (N-1)] = val; } inline void setVal16(uint_least16_t address, uint_least16_t val) { endian_little16(getPtr(address), val); } /** * Return value from memory address. */ inline uint8_t getVal(uint_least16_t address) const { return rom[address & (N-1)]; } inline uint_least16_t getVal16(uint_least16_t address) { return endian_little16(getPtr(address)); } /** * Return pointer to memory address. */ inline uint8_t* getPtr(uint_least16_t address) { return &rom[address & (N-1)]; } public: /** * Copy content from source buffer. */ virtual void set(const uint8_t* source) { if (source != nullptr) std::memcpy(rom, source, N); } /** * Writing to ROM is a no-op. */ void poke(uint_least16_t, uint8_t) override {} /** * Read from ROM. */ uint8_t peek(uint_least16_t address) override { return rom[address & (N-1)]; } }; /** * Kernal ROM * * Located at $E000-$FFFF */ class KernalRomBank final : public romBank<0x2000> { private: uint_least16_t resetVector; // 0xfffc-0xfffd private: uint8_t save_regs[5] = { PHAn, TXAn, PHAn, TYAn, PHAn }; uint8_t restore_regs[5] = { PLAn, TAYn, PLAn, TAXn, PLAn }; // https://sta.c64.org/cbm64krnfunc.html uint16_t kernal_functions[78] = { // address real address 0xFF81, 0xFF5B, // SCINIT 0xFF84, 0xFDA3, // IOINIT 0xFF87, 0xFD50, // RAMTAS 0xFF8A, 0xFD15, // RESTOR 0xFF8D, 0xFD1A, // VECTOR 0xFF90, 0xFE18, // SETMSG 0xFF93, 0xEDB9, // LSTNSA 0xFF96, 0xEDC7, // TALKSA 0xFF99, 0xFE25, // MEMTOP 0xFF9C, 0xFE34, // MEMBOT 0xFF9F, 0xEA87, // SCNKEY 0xFFA2, 0xFE21, // SETTMO 0xFFA5, 0xEE13, // IECIN. 0xFFA8, 0xEDDD, // IECOUT 0xFFAB, 0xEDEF, // UNTALK 0xFFAE, 0xEDFE, // UNLSTN 0xFFB1, 0xED0C, // LISTEN 0xFFB4, 0xED09, // TALK 0xFFB7, 0xFE07, // READST 0xFFBA, 0xFE00, // SETLFS 0xFFBD, 0xFDF9, // SETNAM 0xFFC0, 0xF34A, // OPEN 0xFFC3, 0xF291, // CLOSE 0xFFC6, 0xF20E, // CHKIN 0xFFC9, 0xF250, // CHKOUT 0xFFCC, 0xF333, // CLRCHN 0xFFCF, 0xF157, // CHRIN 0xFFD2, 0xF1CA, // CHROUT 0xFFD5, 0xF49E, // LOAD 0xFFD8, 0xF5DD, // SAVE 0xFFDB, 0xF6E4, // SETTIM 0xFFDE, 0xF6DD, // RDTIM 0xFFE1, 0xF6ED, // STOP 0xFFE4, 0xF13E, // GETIN 0xFFE7, 0xF32F, // CLALL 0xFFEA, 0xF69B, // UDTIM 0xFFED, 0xE505, // SCREEN 0xFFF0, 0xE50A, // PLOT 0xFFF3, 0xE500, // IOBASE }; void fill(uint_least16_t address, const uint8_t data[5]) { std::memcpy(getPtr(address), data, 5); } public: void set(const uint8_t* kernal) override { romBank<0x2000>::set(kernal); if (kernal == nullptr) { std::fill(std::begin(rom), std::end(rom), NOPn); // IRQ routine setVal(0xea31, JMPw); setVal16(0xea32, 0xea7e); setVal(0xea7e, NOPa); // Clear IRQ setVal16(0xea7f, 0xdc0d); fill(0xea81, restore_regs); setVal(0xea86, RTIn); // Return from interrupt // Reset setVal(0xfce2, 0x02); // Halt // NMI entry point setVal(0xfe43, SEIn); setVal(0xfe44, JMPi); // Jump to NMI routine (Default: $FE47) setVal16(0xfe45, 0x0318); // NMI routine fill(0xfe47, save_regs); fill(0xfebc, restore_regs); setVal(0xfec1, RTIn); // IRQ entry point fill(0xff48, save_regs); setVal(0xff4d, JMPi); // Jump to IRQ routine (Default: $EA31) setVal16(0xff4e, 0x0314); // Hardware vectors setVal16(0xfffa, 0xfe43); // NMI vector setVal16(0xfffc, 0xfce2); // RESET vector setVal16(0xfffe, 0xff48); // IRQ/BRK vector // Standard KERNAL functions called by some unclean rips for (auto addr: kernal_functions) setVal(addr, RTSn); } // Backup Reset Vector resetVector = getVal16(0xfffc); } void reset() { // Restore original Reset Vector setVal16(0xfffc, resetVector); } /** * Change the RESET vector. * * @param addr the new addres to point to */ void installResetHook(uint_least16_t addr) { setVal16(0xfffc, addr); } }; /** * BASIC ROM * * Located at $A000-$BFFF */ class BasicRomBank final : public romBank<0x2000> { private: uint8_t trap[3]; uint8_t subTune[11]; public: void set(const uint8_t* basic) override { romBank<0x2000>::set(basic); // Backup BASIC Warm Start std::memcpy(trap, getPtr(0xa7ae), sizeof(trap)); std::memcpy(subTune, getPtr(0xbf53), sizeof(subTune)); } void reset() { // Restore original BASIC Warm Start std::memcpy(getPtr(0xa7ae), trap, sizeof(trap)); std::memcpy(getPtr(0xbf53), subTune, sizeof(subTune)); } /** * Set BASIC Warm Start address. * * @param addr */ void installTrap(uint_least16_t addr) { setVal(0xa7ae, JMPw); setVal16(0xa7af, addr); } void setSubtune(uint8_t tune) { setVal(0xbf53, LDAb); setVal(0xbf54, tune); setVal(0xbf55, STAa); setVal16(0xbf56, 0x030c); setVal(0xbf58, JSRw); setVal16(0xbf59, 0xa82c); setVal(0xbf5b, JMPw); setVal16(0xbf5c, 0xa7b1); } }; /** * Character ROM * * Located at $D000-$DFFF */ class CharacterRomBank final : public romBank<0x1000> {}; } #endif libsidplayfp-3.0.0/src/c64/Banks/DisconnectedBusBank.h0000644000175100017510000000323315175333711016130 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2021 Leandro Nini * Copyright 2010 Antti Lankila * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef DISCONNECTEDBUSBANK_H #define DISCONNECTEDBUSBANK_H #include "Bank.h" #include "pla.h" #include "sidcxx11.h" namespace libsidplayfp { /** * IO1/IO2 * * memory mapped registers or machine code routines of optional external devices. * * I/O Area #1 located at $DE00-$DEFF * * I/O Area #2 located at $DF00-$DFFF */ class DisconnectedBusBank final : public Bank { private: const PLA &pla; public: explicit DisconnectedBusBank(const PLA &pla) : pla(pla) {} /** * No device is connected so this is a no-op. */ void poke(uint_least16_t, uint8_t) override {} /** * No device is connected so this should return the value left on the bus. */ uint8_t peek(uint_least16_t) override { return pla.getLastReadByte(); } }; } #endif libsidplayfp-3.0.0/src/c64/Banks/Bank.h0000644000175100017510000000335715175333711013142 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2013 Leandro Nini * Copyright 2010 Antti Lankila * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef BANK_H #define BANK_H #include #include "sidplayfp/siddefs.h" namespace libsidplayfp { /** * Base interface for memory and I/O banks. */ class Bank { public: /** * Bank write. * * Override this method if you expect write operations on your bank. * Leave unimplemented if it's logically/operationally impossible for * writes to ever arrive to bank. * * @param address address to write to * @param value value to write */ virtual void poke(uint_least16_t address, uint8_t value) =0; /** * Bank read. You probably * should override this method, except if the Bank is only used in * write context. * * @param address value to read from * @return value at address */ virtual uint8_t peek(uint_least16_t address) =0; protected: ~Bank() = default; }; } #endif libsidplayfp-3.0.0/src/c64/Banks/ZeroRAMBank.h0000644000175100017510000001760615175333711014344 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2015 Leandro Nini * Copyright 2009-2014 VICE Project * Copyright 2010 Antti Lankila * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ZERORAMBANK_H #define ZERORAMBANK_H #include #include "Bank.h" #include "SystemRAMBank.h" #include "pla.h" #include "Event.h" #include "sidcxx11.h" namespace libsidplayfp { /** * Unused data port bits emulation, as investigated by groepaz: * * - There are 2 different unused bits, 1) the output bits, 2) the input bits * - The output bits can be (re)set when the data-direction is set to output * for those bits and the output bits will not drop-off to 0. * - When the data-direction for the unused bits is set to output then the * unused input bits can be (re)set by writing to them, when set to 1 the * drop-off timer will start which will cause the unused input bits to drop * down to 0 in a certain amount of time. * - When an unused input bit already had the drop-off timer running, and is * set to 1 again, the drop-off timer will restart. * - when a an unused bit changes from output to input, and the current output * bit is 1, the drop-off timer will restart again */ template class dataBit { private: /** * $01 bits 6 and 7 fall-off cycles (1->0), average is about 350 msec for a 6510 * and about 1500 msec for a 8500. * * NOTE: fall-off cycles are heavily chip- and temperature dependent. as a * consequence it is very hard to find suitable realistic values that * always work and we can only tweak them based on testcases. (unless we * want to make it configurable or emulate temperature over time =)) * * it probably makes sense to tweak the values for a warmed up CPU, since * this is likely how (old) programs were coded and tested :) * * NOTE: the unused bits of the 6510 seem to be much more temperature dependant * and the fall-off time decreases quicker and more drastically than on a * 8500 * * cpuports.prg from the lorenz testsuite will fail when the falloff takes more * than 1373 cycles. this suggests that he tested on a well warmed up c64 :) * he explicitly delays by ~1280 cycles and mentions capacitance, so he probably * even was aware of what happens. */ //@{ static constexpr event_clock_t C64_CPU6510_DATA_PORT_FALL_OFF_CYCLES = 350000; static constexpr event_clock_t C64_CPU8500_DATA_PORT_FALL_OFF_CYCLES = 1500000; // Curently unused //@} private: /// Cycle that should invalidate the bit. event_clock_t dataSetClk; /// Indicates if the bit is in the process of falling off. bool isFallingOff; /// Value of the bit. uint8_t dataSet; public: void reset() { isFallingOff = false; dataSet = 0; } uint8_t readBit(event_clock_t phi2time) { if (isFallingOff && (dataSetClk < phi2time)) { // discharge the "capacitor" reset(); } return dataSet; } void writeBit(event_clock_t phi2time, uint8_t value) { dataSetClk = phi2time + C64_CPU6510_DATA_PORT_FALL_OFF_CYCLES; dataSet = value & (1 << Bit); isFallingOff = true; } }; /** * Area backed by RAM, including cpu port addresses 0 and 1. * * This is bit of a fake. We know that the CPU port is an internal * detail of the CPU, and therefore CPU should simply pay the price * for reading/writing to $00/$01. * * However, that would slow down all accesses, which is suboptimal. Therefore * we install this little hook to the 4k 0 region to deal with this. * * Implementation based on VICE code. */ class ZeroRAMBank final : public Bank { private: // not emulated static bool const tape_sense = false; private: PLA &pla; /// C64 RAM area SystemRAMBank &ramBank; /// Unused bits of the data port. //@{ dataBit<6> dataBit6; dataBit<7> dataBit7; //@} /// Value written to processor port. //@{ uint8_t dir; uint8_t data; //@} /// Value read from processor port. uint8_t dataRead; /// State of processor port pins. uint8_t procPortPins; private: void updateCpuPort() { // Update data pins for which direction is OUTPUT procPortPins = (procPortPins & ~dir) | (data & dir); dataRead = (data | ~dir) & (procPortPins | 0x17); pla.setCpuPort((data | ~dir) & 0x07); if ((dir & 0x20) == 0) { dataRead &= ~0x20; } if (tape_sense && (dir & 0x10) == 0) { dataRead &= ~0x10; } } public: ZeroRAMBank(PLA &pla, SystemRAMBank &ramBank) : pla(pla), ramBank(ramBank) {} void reset() { dataBit6.reset(); dataBit7.reset(); dir = 0; data = 0x3f; dataRead = 0x3f; procPortPins = 0x3f; updateCpuPort(); } uint8_t peek(uint_least16_t address) override { switch (address) { case 0: return dir; case 1: { uint8_t retval = dataRead; // for unused bits in input mode, the value comes from the "capacitor" // set real value of bit 6 if (!(dir & 0x40)) { retval &= ~0x40; retval |= dataBit6.readBit(pla.getPhi2Time()); } // set real value of bit 7 if (!(dir & 0x80)) { retval &= ~0x80; retval |= dataBit7.readBit(pla.getPhi2Time()); } return retval; } default: return ramBank.peek(address); } } void poke(uint_least16_t address, uint8_t value) override { switch (address) { case 0: // when switching an unused bit from output (where it contained a // stable value) to input mode (where the input is floating), some // of the charge is transferred to the floating input if (dir != value) { // check if bit 6 has flipped from 1 to 0 if ((dir & 0x40) && !(value & 0x40)) dataBit6.writeBit(pla.getPhi2Time(), data); // check if bit 7 has flipped from 1 to 0 if ((dir & 0x80) && !(value & 0x80)) dataBit7.writeBit(pla.getPhi2Time(), data); dir = value; updateCpuPort(); } value = pla.getLastReadByte(); break; case 1: // when writing to an unused bit that is output, charge the "capacitor", // otherwise don't touch it if (dir & 0x40) dataBit6.writeBit(pla.getPhi2Time(), value); if (dir & 0x80) dataBit7.writeBit(pla.getPhi2Time(), value); if (data != value) { data = value; updateCpuPort(); } value = pla.getLastReadByte(); break; default: break; } ramBank.poke(address, value); } }; } #endif libsidplayfp-3.0.0/src/c64/Banks/ColorRAMBank.h0000644000175100017510000000312315175333711014470 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2013 Leandro Nini * Copyright 2010 Antti Lankila * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef COLORRAMBANK_H #define COLORRAMBANK_H #include #include #include #include "Bank.h" #include "sidcxx11.h" namespace libsidplayfp { /** * Color RAM. * * 1K x 4-bit Static RAM that stores text screen color information. * * Located at $D800-$DBFF (last 24 bytes are unused) */ class ColorRAMBank final : public Bank { private: uint8_t ram[0x400]; public: void reset() { std::fill(std::begin(ram), std::end(ram), 0); } void poke(uint_least16_t address, uint8_t value) override { ram[address & 0x3ff] = value & 0xf; } uint8_t peek(uint_least16_t address) override { return ram[address & 0x3ff]; } }; } #endif libsidplayfp-3.0.0/src/c64/Banks/pla.h0000644000175100017510000000227115175333711013035 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2021 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef PLA_H #define PLA_H #include #include "Event.h" namespace libsidplayfp { /** * Interface to PLA functions. */ class PLA { public: virtual void setCpuPort(uint8_t state) =0; virtual uint8_t getLastReadByte() const =0; virtual event_clock_t getPhi2Time() const =0; protected: ~PLA() = default; }; } #endif libsidplayfp-3.0.0/src/c64/Banks/SystemRAMBank.h0000644000175100017510000000406515175333711014704 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2021 Leandro Nini * Copyright 2010 Antti Lankila * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SYSTEMRAMBANK_H #define SYSTEMRAMBANK_H #include #include #include "Bank.h" #include "sidcxx11.h" namespace libsidplayfp { /** * Area backed by RAM. */ class SystemRAMBank final : public Bank { friend class MMU; private: /// C64 RAM area uint8_t ram[0x10000]; public: /** * Initialize RAM with powerup pattern. * * $0000: 00 00 ff ff ff ff 00 00 00 00 ff ff ff ff 00 00 * ... * $4000: ff ff 00 00 00 00 ff ff ff ff 00 00 00 00 ff ff * ... * $8000: 00 00 ff ff ff ff 00 00 00 00 ff ff ff ff 00 00 * ... * $c000: ff ff 00 00 00 00 ff ff ff ff 00 00 00 00 ff ff */ void reset() { uint8_t byte = 0x00; for (int j=0x0000; j<0x10000; j+=0x4000) { std::memset(ram+j, byte, 0x4000); byte = ~byte; for (int i = 0x02; i < 0x4000; i += 0x08) { std::memset(ram+j+i, byte, 0x04); } } } uint8_t peek(uint_least16_t address) override { return ram[address]; } void poke(uint_least16_t address, uint8_t value) override { ram[address] = value; } }; } #endif libsidplayfp-3.0.0/src/c64/c64env.h0000644000175100017510000000333215175333711012327 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2019 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef C64ENV_H #define C64ENV_H #include "EventScheduler.h" #ifdef HAVE_CONFIG_H # include "config.h" #endif namespace libsidplayfp { /** * An implementation of of this class can be created to perform the C64 * specifics. A pointer to this child class can then be passed to * each of the components so they can interact with it. */ class c64env { private: EventScheduler &eventScheduler; public: c64env(EventScheduler &scheduler) : eventScheduler(scheduler) {} EventScheduler &scheduler() const { return eventScheduler; } virtual void interruptIRQ(bool state) = 0; virtual void interruptNMI() = 0; virtual void interruptRST() = 0; virtual void setBA(bool state) = 0; virtual void lightpen(bool state) = 0; protected: ~c64env() = default; }; } #endif // C64ENV_H libsidplayfp-3.0.0/src/c64/mmu.h0000644000175100017510000001023515175333711012020 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2021 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MMU_H #define MMU_H #include "sidendian.h" #include "sidmemory.h" #include "EventScheduler.h" #include "Banks/pla.h" #include "Banks/SystemRAMBank.h" #include "Banks/SystemROMBanks.h" #include "Banks/ZeroRAMBank.h" #include "sidcxx11.h" #include #include namespace libsidplayfp { class Bank; class IOBank; /** * The C64 MMU chip. */ class MMU final : public PLA, public sidmemory { private: EventScheduler &eventScheduler; /// CPU port signals //@{ bool loram = false; bool hiram = false; bool charen = false; //@} friend uint8_t readIO(MMU &self, uint_least16_t addr); using ReadFunc = uint8_t (*)(MMU &self, uint_least16_t addr); /// CPU read memory mapping in 4k chunks ReadFunc cpuReadMap[16]; /// CPU write memory mapping in 4k chunks Bank* cpuWriteMap[16]; /// IO region handler IOBank* ioBank; /// Kernal ROM KernalRomBank kernalRomBank; /// BASIC ROM BasicRomBank basicRomBank; /// Character ROM CharacterRomBank characterRomBank; /// RAM SystemRAMBank ramBank; /// RAM bank 0 ZeroRAMBank zeroRAMBank; /// random seed mutable unsigned int seed = 3686734; private: void setCpuPort(uint8_t state) override; uint8_t getLastReadByte() const override; event_clock_t getPhi2Time() const override { return eventScheduler.getTime(EVENT_CLOCK_PHI2); } void updateMappingPHI2(); public: MMU(EventScheduler &scheduler, IOBank* ioBank); void reset(); // ROM banks methods void setKernal(const uint8_t* rom) override { kernalRomBank.set(rom); } void setBasic(const uint8_t* rom) override { basicRomBank.set(rom); } void setChargen(const uint8_t* rom) override { characterRomBank.set(rom); } // RAM access methods uint8_t readMemByte(uint_least16_t addr) override { return ramBank.peek(addr); } uint_least16_t readMemWord(uint_least16_t addr) override { return endian_little16(ramBank.ram+addr); } void writeMemByte(uint_least16_t addr, uint8_t value) override { ramBank.poke(addr, value); } void writeMemWord(uint_least16_t addr, uint_least16_t value) override { endian_little16(ramBank.ram+addr, value); } void fillRam(uint_least16_t start, uint8_t value, unsigned int size) override { std::memset(ramBank.ram+start, value, size); } void fillRam(uint_least16_t start, const uint8_t* source, unsigned int size) override { std::memcpy(ramBank.ram+start, source, size); } // SID specific hacks void installResetHook(uint_least16_t addr) override { kernalRomBank.installResetHook(addr); } void installBasicTrap(uint_least16_t addr) override { basicRomBank.installTrap(addr); } void setBasicSubtune(uint8_t tune) override { basicRomBank.setSubtune(tune); } /** * Access memory as seen by CPU. * * @param addr the address where to read from * @return value at address */ uint8_t cpuRead(uint_least16_t addr) { return (cpuReadMap[addr >> 12])(*this, addr); } /** * Access memory as seen by CPU. * * @param addr the address where to write * @param data the value to write */ void cpuWrite(uint_least16_t addr, uint8_t data) { cpuWriteMap[addr >> 12]->poke(addr, data); } }; } #endif libsidplayfp-3.0.0/src/c64/CPU/0000755000175100017510000000000015175333725011564 5libsidplayfp-3.0.0/src/c64/CPU/opcodes.h0000644000175100017510000001462215175333711013311 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2013 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef OPCODES_H #define OPCODES_H #define OPCODE_MAX 0x100 /* HLT case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52: case 0x62: case 0x72: case 0x92: case 0xb2: case 0xd2: case 0xf2: */ #define BRKn 0x00 #define JSRw 0x20 #define RTIn 0x40 #define RTSn 0x60 #define NOPb 0x80 #define NOPb_ NOPb: case 0x82: case 0xC2: case 0xE2: case 0x89 #define LDYb 0xA0 #define CPYb 0xC0 #define CPXb 0xE0 #define ORAix 0x01 #define ANDix 0x21 #define EORix 0x41 #define ADCix 0x61 #define STAix 0x81 #define LDAix 0xA1 #define CMPix 0xC1 #define SBCix 0xE1 #define LDXb 0xA2 #define SLOix 0x03 #define RLAix 0x23 #define SREix 0x43 #define RRAix 0x63 #define SAXix 0x83 #define LAXix 0xA3 #define DCPix 0xC3 #define ISBix 0xE3 #define NOPz 0x04 #define NOPz_ NOPz: case 0x44: case 0x64 #define BITz 0x24 #define STYz 0x84 #define LDYz 0xA4 #define CPYz 0xC4 #define CPXz 0xE4 #define ORAz 0x05 #define ANDz 0x25 #define EORz 0x45 #define ADCz 0x65 #define STAz 0x85 #define LDAz 0xA5 #define CMPz 0xC5 #define SBCz 0xE5 #define ASLz 0x06 #define ROLz 0x26 #define LSRz 0x46 #define RORz 0x66 #define STXz 0x86 #define LDXz 0xA6 #define DECz 0xC6 #define INCz 0xE6 #define SLOz 0x07 #define RLAz 0x27 #define SREz 0x47 #define RRAz 0x67 #define SAXz 0x87 #define LAXz 0xA7 #define DCPz 0xC7 #define ISBz 0xE7 #define PHPn 0x08 #define PLPn 0x28 #define PHAn 0x48 #define PLAn 0x68 #define DEYn 0x88 #define TAYn 0xA8 #define INYn 0xC8 #define INXn 0xE8 #define ORAb 0x09 #define ANDb 0x29 #define EORb 0x49 #define ADCb 0x69 #define LDAb 0xA9 #define CMPb 0xC9 #define SBCb 0xE9 #define SBCb_ SBCb: case 0xEB #define ASLn 0x0A #define ROLn 0x2A #define LSRn 0x4A #define RORn 0x6A #define TXAn 0x8A #define TAXn 0xAA #define DEXn 0xCA #define NOPn 0xEA #define NOPn_ NOPn: case 0x1A: case 0x3A: case 0x5A: case 0x7A: case 0xDA: case 0xFA #define ANCb 0x0B #define ANCb_ ANCb: case 0x2B #define ASRb 0x4B #define ARRb 0x6B #define ANEb 0x8B #define XAAb 0x8B #define LXAb 0xAB #define SBXb 0xCB #define NOPa 0x0C #define BITa 0x2C #define JMPw 0x4C #define JMPi 0x6C #define STYa 0x8C #define LDYa 0xAC #define CPYa 0xCC #define CPXa 0xEC #define ORAa 0x0D #define ANDa 0x2D #define EORa 0x4D #define ADCa 0x6D #define STAa 0x8D #define LDAa 0xAD #define CMPa 0xCD #define SBCa 0xED #define ASLa 0x0E #define ROLa 0x2E #define LSRa 0x4E #define RORa 0x6E #define STXa 0x8E #define LDXa 0xAE #define DECa 0xCE #define INCa 0xEE #define SLOa 0x0F #define RLAa 0x2F #define SREa 0x4F #define RRAa 0x6F #define SAXa 0x8F #define LAXa 0xAF #define DCPa 0xCF #define ISBa 0xEF #define BPLr 0x10 #define BMIr 0x30 #define BVCr 0x50 #define BVSr 0x70 #define BCCr 0x90 #define BCSr 0xB0 #define BNEr 0xD0 #define BEQr 0xF0 #define ORAiy 0x11 #define ANDiy 0x31 #define EORiy 0x51 #define ADCiy 0x71 #define STAiy 0x91 #define LDAiy 0xB1 #define CMPiy 0xD1 #define SBCiy 0xF1 #define SLOiy 0x13 #define RLAiy 0x33 #define SREiy 0x53 #define RRAiy 0x73 #define SHAiy 0x93 #define LAXiy 0xB3 #define DCPiy 0xD3 #define ISBiy 0xF3 #define NOPzx 0x14 #define NOPzx_ NOPzx: case 0x34: case 0x54: case 0x74: case 0xD4: case 0xF4 #define STYzx 0x94 #define LDYzx 0xB4 #define ORAzx 0x15 #define ANDzx 0x35 #define EORzx 0x55 #define ADCzx 0x75 #define STAzx 0x95 #define LDAzx 0xB5 #define CMPzx 0xD5 #define SBCzx 0xF5 #define ASLzx 0x16 #define ROLzx 0x36 #define LSRzx 0x56 #define RORzx 0x76 #define STXzy 0x96 #define LDXzy 0xB6 #define DECzx 0xD6 #define INCzx 0xF6 #define SLOzx 0x17 #define RLAzx 0x37 #define SREzx 0x57 #define RRAzx 0x77 #define SAXzy 0x97 #define LAXzy 0xB7 #define DCPzx 0xD7 #define ISBzx 0xF7 #define CLCn 0x18 #define SECn 0x38 #define CLIn 0x58 #define SEIn 0x78 #define TYAn 0x98 #define CLVn 0xB8 #define CLDn 0xD8 #define SEDn 0xF8 #define ORAay 0x19 #define ANDay 0x39 #define EORay 0x59 #define ADCay 0x79 #define STAay 0x99 #define LDAay 0xB9 #define CMPay 0xD9 #define SBCay 0xF9 #define TXSn 0x9A #define TSXn 0xBA #define SLOay 0x1B #define RLAay 0x3B #define SREay 0x5B #define RRAay 0x7B #define SHSay 0x9B #define TASay 0x9B #define LASay 0xBB #define DCPay 0xDB #define ISBay 0xFB #define NOPax 0x1C #define NOPax_ NOPax: case 0x3C: case 0x5C: case 0x7C: case 0xDC: case 0xFC #define SHYax 0x9C #define LDYax 0xBC #define ORAax 0x1D #define ANDax 0x3D #define EORax 0x5D #define ADCax 0x7D #define STAax 0x9D #define LDAax 0xBD #define CMPax 0xDD #define SBCax 0xFD #define ASLax 0x1E #define ROLax 0x3E #define LSRax 0x5E #define RORax 0x7E #define SHXay 0x9E #define LDXay 0xBE #define DECax 0xDE #define INCax 0xFE #define SLOax 0x1F #define RLAax 0x3F #define SREax 0x5F #define RRAax 0x7F #define SHAay 0x9F #define LAXay 0xBF #define DCPax 0xDF #define ISBax 0xFF // Instruction Aliases #define ASOix SLOix #define LSEix SREix #define AXSix SAXix #define DCMix DCPix #define INSix ISBix #define ASOz SLOz #define LSEz SREz #define AXSz SAXz #define DCMz DCPz #define INSz ISBz #define ALRb ASRb #define OALb LXAb #define ASOa SLOa #define LSEa SREa #define AXSa SAXa #define DCMa DCPa #define INSa ISBa #define ASOiy SLOiy #define LSEiy SREiy #define AXAiy SHAiy #define DCMiy DCPiy #define INSiy ISBiy #define ASOzx SLOzx #define LSEzx SREzx #define AXSzy SAXzy #define DCMzx DCPzx #define INSzx ISBzx #define ASOay SLOay #define LSEay SREay #define DCMay DCPay #define INSay ISBay #define SAYax SHYax #define XASay SHXay #define ASOax SLOax #define LSEax SREax #define AXAay SHAay #define DCMax DCPax #define INSax ISBax #define SKBn NOPb #define SKWn NOPa #endif // OPCODES_H libsidplayfp-3.0.0/src/c64/CPU/mos6510debug.cpp0000644000175100017510000005342515175333711014335 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2019 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "mos6510debug.h" #include #include #include "mos6510.h" #include "sidendian.h" #include "opcodes.h" namespace libsidplayfp { void MOS6510Debug::DumpState (event_clock_t time, MOS6510 &cpu) { fprintf(cpu.cpu_debug->m_fdbg, " PC I A X Y SP DR PR NV-BDIZC Instruction (%d)\n", static_cast(time)); fprintf(cpu.cpu_debug->m_fdbg, "%04x ", cpu.cpu_debug->instrStartPC < 0 ? 0 : cpu.cpu_debug->instrStartPC); fprintf(cpu.cpu_debug->m_fdbg, cpu.irqAssertedOnPin ? "t " : "f "); fprintf(cpu.cpu_debug->m_fdbg, "%02x ", cpu.Register_Accumulator); fprintf(cpu.cpu_debug->m_fdbg, "%02x ", cpu.Register_X); fprintf(cpu.cpu_debug->m_fdbg, "%02x ", cpu.Register_Y); fprintf(cpu.cpu_debug->m_fdbg, "01%02x ", endian_16lo8(cpu.Register_StackPointer)); fprintf(cpu.cpu_debug->m_fdbg, "%02x ", cpu.cpuRead (0)); fprintf(cpu.cpu_debug->m_fdbg, "%02x ", cpu.cpuRead (1)); fprintf(cpu.cpu_debug->m_fdbg, cpu.flags.getN() ? "1" : "0"); fprintf(cpu.cpu_debug->m_fdbg, cpu.flags.getV() ? "1" : "0"); fprintf(cpu.cpu_debug->m_fdbg, "1"); fprintf(cpu.cpu_debug->m_fdbg, cpu.d1x1 ? "0" : "1"); fprintf(cpu.cpu_debug->m_fdbg, cpu.flags.getD() ? "1" : "0"); fprintf(cpu.cpu_debug->m_fdbg, cpu.flags.getI() ? "1" : "0"); fprintf(cpu.cpu_debug->m_fdbg, cpu.flags.getZ() ? "1" : "0"); fprintf(cpu.cpu_debug->m_fdbg, cpu.flags.getC() ? "1" : "0"); const int opcode = cpu.cpu_debug->instrStartPC < 0 ? BRKn : cpu.cpuRead(cpu.cpu_debug->instrStartPC); fprintf(cpu.cpu_debug->m_fdbg, " %02x ", opcode); switch(opcode) { // Accumulator or Implied cpu.Cycle_EffectiveAddressing case ASLn: case LSRn: case ROLn: case RORn: fprintf(cpu.cpu_debug->m_fdbg, " "); break; // Zero Page Addressing Mode Handler case ADCz: case ANDz: case ASLz: case BITz: case CMPz: case CPXz: case CPYz: case DCPz: case DECz: case EORz: case INCz: case ISBz: case LAXz: case LDAz: case LDXz: case LDYz: case LSRz: case NOPz_: case ORAz: case ROLz: case RORz: case SAXz: case SBCz: case SREz: case STAz: case STXz: case STYz: case SLOz: case RLAz: case RRAz: // ASOz AXSz DCMz INSz LSEz - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "%02x ", endian_16lo8(cpu.cpu_debug->instrOperand)); break; // Zero Page with X Offset Addressing Mode Handler case ADCzx: case ANDzx: case ASLzx: case CMPzx: case DCPzx: case DECzx: case EORzx: case INCzx: case ISBzx: case LDAzx: case LDYzx: case LSRzx: case NOPzx_: case ORAzx: case RLAzx: case ROLzx: case RORzx: case RRAzx: case SBCzx: case SLOzx: case SREzx: case STAzx: case STYzx: // ASOzx DCMzx INSzx LSEzx - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "%02x ", endian_16lo8(cpu.cpu_debug->instrOperand)); break; // Zero Page with Y Offset Addressing Mode Handler case LDXzy: case STXzy: case SAXzy: case LAXzy: // AXSzx - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "%02x ", endian_16lo8(cpu.cpu_debug->instrOperand)); break; // Absolute Addressing Mode Handler case ADCa: case ANDa: case ASLa: case BITa: case CMPa: case CPXa: case CPYa: case DCPa: case DECa: case EORa: case INCa: case ISBa: case JMPw: case JSRw: case LAXa: case LDAa: case LDXa: case LDYa: case LSRa: case NOPa: case ORAa: case ROLa: case RORa: case SAXa: case SBCa: case SLOa: case SREa: case STAa: case STXa: case STYa: case RLAa: case RRAa: // ASOa AXSa DCMa INSa LSEa - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "%02x %02x ", endian_16lo8(cpu.cpu_debug->instrOperand), endian_16hi8 (cpu.cpu_debug->instrOperand)); break; // Absolute With X Offset Addresing Mode Handler case ADCax: case ANDax: case ASLax: case CMPax: case DCPax: case DECax: case EORax: case INCax: case ISBax: case LDAax: case LDYax: case LSRax: case NOPax_: case ORAax: case RLAax: case ROLax: case RORax: case RRAax: case SBCax: case SHYax: case SLOax: case SREax: case STAax: // ASOax DCMax INSax LSEax SAYax - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "%02x %02x ", endian_16lo8(cpu.cpu_debug->instrOperand), endian_16hi8 (cpu.cpu_debug->instrOperand)); break; // Absolute With Y Offset Addresing Mode Handler case ADCay: case ANDay: case CMPay: case DCPay: case EORay: case ISBay: case LASay: case LAXay: case LDAay: case LDXay: case ORAay: case RLAay: case RRAay: case SBCay: case SHAay: case SHSay: case SHXay: case SLOay: case SREay: case STAay: // ASOay AXAay DCMay INSax LSEay TASay XASay - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "%02x %02x ", endian_16lo8(cpu.cpu_debug->instrOperand), endian_16hi8 (cpu.cpu_debug->instrOperand)); break; // Immediate and Relative Addressing Mode Handler case ADCb: case ANDb: case ANCb_: case ANEb: case ASRb: case ARRb: case BCCr: case BCSr: case BEQr: case BMIr: case BNEr: case BPLr: case BVCr: case BVSr: case CMPb: case CPXb: case CPYb: case EORb: case LDAb: case LDXb: case LDYb: case LXAb: case NOPb_: case ORAb: case SBCb_: case SBXb: // OALb ALRb XAAb - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "%02x ", endian_16lo8(cpu.Cycle_Data)); break; // Indirect Addressing Mode Handler case JMPi: fprintf(cpu.cpu_debug->m_fdbg, "%02x %02x ", endian_16lo8(cpu.cpu_debug->instrOperand), endian_16hi8 (cpu.cpu_debug->instrOperand)); break; // Indexed with X Preinc Addressing Mode Handler case ADCix: case ANDix: case CMPix: case DCPix: case EORix: case ISBix: case LAXix: case LDAix: case ORAix: case SAXix: case SBCix: case SLOix: case SREix: case STAix: case RLAix: case RRAix: // ASOix AXSix DCMix INSix LSEix - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "%02x ", endian_16lo8(cpu.cpu_debug->instrOperand)); break; // Indexed with Y Postinc Addressing Mode Handler case ADCiy: case ANDiy: case CMPiy: case DCPiy: case EORiy: case ISBiy: case LAXiy: case LDAiy: case ORAiy: case RLAiy: case RRAiy: case SBCiy: case SHAiy: case SLOiy: case SREiy: case STAiy: // AXAiy ASOiy LSEiy DCMiy INSiy - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "%02x ", endian_16lo8(cpu.cpu_debug->instrOperand)); break; default: fprintf(cpu.cpu_debug->m_fdbg, " "); break; } switch(opcode) { case ADCb: case ADCz: case ADCzx: case ADCa: case ADCax: case ADCay: case ADCix: case ADCiy: fprintf(cpu.cpu_debug->m_fdbg, " ADC"); break; case ANCb_: fprintf(cpu.cpu_debug->m_fdbg, "*ANC"); break; case ANDb: case ANDz: case ANDzx: case ANDa: case ANDax: case ANDay: case ANDix: case ANDiy: fprintf(cpu.cpu_debug->m_fdbg, " AND"); break; case ANEb: // Also known as XAA fprintf(cpu.cpu_debug->m_fdbg, "*ANE"); break; case ARRb: fprintf(cpu.cpu_debug->m_fdbg, "*ARR"); break; case ASLn: case ASLz: case ASLzx: case ASLa: case ASLax: fprintf(cpu.cpu_debug->m_fdbg, " ASL"); break; case ASRb: // Also known as ALR fprintf(cpu.cpu_debug->m_fdbg, "*ASR"); break; case BCCr: fprintf(cpu.cpu_debug->m_fdbg, " BCC"); break; case BCSr: fprintf(cpu.cpu_debug->m_fdbg, " BCS"); break; case BEQr: fprintf(cpu.cpu_debug->m_fdbg, " BEQ"); break; case BITz: case BITa: fprintf(cpu.cpu_debug->m_fdbg, " BIT"); break; case BMIr: fprintf(cpu.cpu_debug->m_fdbg, " BMI"); break; case BNEr: fprintf(cpu.cpu_debug->m_fdbg, " BNE"); break; case BPLr: fprintf(cpu.cpu_debug->m_fdbg, " BPL"); break; case BRKn: fprintf(cpu.cpu_debug->m_fdbg, " BRK"); break; case BVCr: fprintf(cpu.cpu_debug->m_fdbg, " BVC"); break; case BVSr: fprintf(cpu.cpu_debug->m_fdbg, " BVS"); break; case CLCn: fprintf(cpu.cpu_debug->m_fdbg, " CLC"); break; case CLDn: fprintf(cpu.cpu_debug->m_fdbg, " CLD"); break; case CLIn: fprintf(cpu.cpu_debug->m_fdbg, " CLI"); break; case CLVn: fprintf(cpu.cpu_debug->m_fdbg, " CLV"); break; case CMPb: case CMPz: case CMPzx: case CMPa: case CMPax: case CMPay: case CMPix: case CMPiy: fprintf(cpu.cpu_debug->m_fdbg, " CMP"); break; case CPXb: case CPXz: case CPXa: fprintf(cpu.cpu_debug->m_fdbg, " CPX"); break; case CPYb: case CPYz: case CPYa: fprintf(cpu.cpu_debug->m_fdbg, " CPY"); break; case DCPz: case DCPzx: case DCPa: case DCPax: case DCPay: case DCPix: case DCPiy: // Also known as DCM fprintf(cpu.cpu_debug->m_fdbg, "*DCP"); break; case DECz: case DECzx: case DECa: case DECax: fprintf(cpu.cpu_debug->m_fdbg, " DEC"); break; case DEXn: fprintf(cpu.cpu_debug->m_fdbg, " DEX"); break; case DEYn: fprintf(cpu.cpu_debug->m_fdbg, " DEY"); break; case EORb: case EORz: case EORzx: case EORa: case EORax: case EORay: case EORix: case EORiy: fprintf(cpu.cpu_debug->m_fdbg, " EOR"); break; case INCz: case INCzx: case INCa: case INCax: fprintf(cpu.cpu_debug->m_fdbg, " INC"); break; case INXn: fprintf(cpu.cpu_debug->m_fdbg, " INX"); break; case INYn: fprintf(cpu.cpu_debug->m_fdbg, " INY"); break; case ISBz: case ISBzx: case ISBa: case ISBax: case ISBay: case ISBix: case ISBiy: // Also known as INS fprintf(cpu.cpu_debug->m_fdbg, "*ISB"); break; case JMPw: case JMPi: fprintf(cpu.cpu_debug->m_fdbg, " JMP"); break; case JSRw: fprintf(cpu.cpu_debug->m_fdbg, " JSR"); break; case LASay: fprintf(cpu.cpu_debug->m_fdbg, "*LAS"); break; case LAXz: case LAXzy: case LAXa: case LAXay: case LAXix: case LAXiy: fprintf(cpu.cpu_debug->m_fdbg, "*LAX"); break; case LDAb: case LDAz: case LDAzx: case LDAa: case LDAax: case LDAay: case LDAix: case LDAiy: fprintf(cpu.cpu_debug->m_fdbg, " LDA"); break; case LDXb: case LDXz: case LDXzy: case LDXa: case LDXay: fprintf(cpu.cpu_debug->m_fdbg, " LDX"); break; case LDYb: case LDYz: case LDYzx: case LDYa: case LDYax: fprintf(cpu.cpu_debug->m_fdbg, " LDY"); break; case LSRz: case LSRzx: case LSRa: case LSRax: case LSRn: fprintf(cpu.cpu_debug->m_fdbg, " LSR"); break; case NOPn_: case NOPb_: case NOPz_: case NOPzx_: case NOPa: case NOPax_: if(opcode != NOPn) fprintf(cpu.cpu_debug->m_fdbg, "*"); else fprintf(cpu.cpu_debug->m_fdbg, " "); fprintf(cpu.cpu_debug->m_fdbg, "NOP"); break; case LXAb: // Also known as OAL fprintf(cpu.cpu_debug->m_fdbg, "*LXA"); break; case ORAb: case ORAz: case ORAzx: case ORAa: case ORAax: case ORAay: case ORAix: case ORAiy: fprintf(cpu.cpu_debug->m_fdbg, " ORA"); break; case PHAn: fprintf(cpu.cpu_debug->m_fdbg, " PHA"); break; case PHPn: fprintf(cpu.cpu_debug->m_fdbg, " PHP"); break; case PLAn: fprintf(cpu.cpu_debug->m_fdbg, " PLA"); break; case PLPn: fprintf(cpu.cpu_debug->m_fdbg, " PLP"); break; case RLAz: case RLAzx: case RLAix: case RLAa: case RLAax: case RLAay: case RLAiy: fprintf(cpu.cpu_debug->m_fdbg, "*RLA"); break; case ROLz: case ROLzx: case ROLa: case ROLax: case ROLn: fprintf(cpu.cpu_debug->m_fdbg, " ROL"); break; case RORz: case RORzx: case RORa: case RORax: case RORn: fprintf(cpu.cpu_debug->m_fdbg, " ROR"); break; case RRAa: case RRAax: case RRAay: case RRAz: case RRAzx: case RRAix: case RRAiy: fprintf(cpu.cpu_debug->m_fdbg, "*RRA"); break; case RTIn: fprintf(cpu.cpu_debug->m_fdbg, " RTI"); break; case RTSn: fprintf(cpu.cpu_debug->m_fdbg, " RTS"); break; case SAXz: case SAXzy: case SAXa: case SAXix: // Also known as AXS fprintf(cpu.cpu_debug->m_fdbg, "*SAX"); break; case SBCb_: if(opcode != SBCb) fprintf(cpu.cpu_debug->m_fdbg, "*"); else fprintf(cpu.cpu_debug->m_fdbg, " "); fprintf(cpu.cpu_debug->m_fdbg, "SBC"); break; case SBCz: case SBCzx: case SBCa: case SBCax: case SBCay: case SBCix: case SBCiy: fprintf(cpu.cpu_debug->m_fdbg, " SBC"); break; case SBXb: fprintf(cpu.cpu_debug->m_fdbg, "*SBX"); break; case SECn: fprintf(cpu.cpu_debug->m_fdbg, " SEC"); break; case SEDn: fprintf(cpu.cpu_debug->m_fdbg, " SED"); break; case SEIn: fprintf(cpu.cpu_debug->m_fdbg, " SEI"); break; case SHAay: case SHAiy: // Also known as AXA fprintf(cpu.cpu_debug->m_fdbg, "*SHA"); break; case SHSay: // Also known as TAS fprintf(cpu.cpu_debug->m_fdbg, "*SHS"); break; case SHXay: // Also known as XAS fprintf(cpu.cpu_debug->m_fdbg, "*SHX"); break; case SHYax: // Also known as SAY fprintf(cpu.cpu_debug->m_fdbg, "*SHY"); break; case SLOz: case SLOzx: case SLOa: case SLOax: case SLOay: case SLOix: case SLOiy: // Also known as ASO fprintf(cpu.cpu_debug->m_fdbg, "*SLO"); break; case SREz: case SREzx: case SREa: case SREax: case SREay: case SREix: case SREiy: // Also known as LSE fprintf(cpu.cpu_debug->m_fdbg, "*SRE"); break; case STAz: case STAzx: case STAa: case STAax: case STAay: case STAix: case STAiy: fprintf(cpu.cpu_debug->m_fdbg, " STA"); break; case STXz: case STXzy: case STXa: fprintf(cpu.cpu_debug->m_fdbg, " STX"); break; case STYz: case STYzx: case STYa: fprintf(cpu.cpu_debug->m_fdbg, " STY"); break; case TAXn: fprintf(cpu.cpu_debug->m_fdbg, " TAX"); break; case TAYn: fprintf(cpu.cpu_debug->m_fdbg, " TAY"); break; case TSXn: fprintf(cpu.cpu_debug->m_fdbg, " TSX"); break; case TXAn: fprintf(cpu.cpu_debug->m_fdbg, " TXA"); break; case TXSn: fprintf(cpu.cpu_debug->m_fdbg, " TXS"); break; case TYAn: fprintf(cpu.cpu_debug->m_fdbg, " TYA"); break; default: fprintf(cpu.cpu_debug->m_fdbg, "*HLT"); break; } switch(opcode) { // Accumulator or Implied cpu.Cycle_EffectiveAddressing case ASLn: case LSRn: case ROLn: case RORn: fprintf(cpu.cpu_debug->m_fdbg, "n A"); break; // Zero Page Addressing Mode Handler case ADCz: case ANDz: case ASLz: case BITz: case CMPz: case CPXz: case CPYz: case DCPz: case DECz: case EORz: case INCz: case ISBz: case LAXz: case LDAz: case LDXz: case LDYz: case LSRz: case ORAz: case ROLz: case RORz: case SBCz: case SREz: case SLOz: case RLAz: case RRAz: // ASOz AXSz DCMz INSz LSEz - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "z %02x {%02x}", endian_16lo8(cpu.cpu_debug->instrOperand), cpu.Cycle_Data); break; case SAXz: case STAz: case STXz: case STYz: case NOPz_: fprintf(cpu.cpu_debug->m_fdbg, "z %02x", endian_16lo8(cpu.cpu_debug->instrOperand)); break; // Zero Page with X Offset Addressing Mode Handler case ADCzx: case ANDzx: case ASLzx: case CMPzx: case DCPzx: case DECzx: case EORzx: case INCzx: case ISBzx: case LDAzx: case LDYzx: case LSRzx: case ORAzx: case RLAzx: case ROLzx: case RORzx: case RRAzx: case SBCzx: case SLOzx: case SREzx: // ASOzx DCMzx INSzx LSEzx - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "zx %02x,X", endian_16lo8(cpu.cpu_debug->instrOperand)); fprintf(cpu.cpu_debug->m_fdbg, " [%04x]{%02x}", cpu.Cycle_EffectiveAddress, cpu.Cycle_Data); break; case STAzx: case STYzx: case NOPzx_: fprintf(cpu.cpu_debug->m_fdbg, "zx %02x,X", endian_16lo8(cpu.cpu_debug->instrOperand)); fprintf(cpu.cpu_debug->m_fdbg, " [%04x]", cpu.Cycle_EffectiveAddress); break; // Zero Page with Y Offset Addressing Mode Handler case LAXzy: case LDXzy: // AXSzx - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "zy %02x,Y", endian_16lo8(cpu.cpu_debug->instrOperand)); fprintf(cpu.cpu_debug->m_fdbg, " [%04x]{%02x}", cpu.Cycle_EffectiveAddress, cpu.Cycle_Data); break; case STXzy: case SAXzy: fprintf(cpu.cpu_debug->m_fdbg, "zy %02x,Y", endian_16lo8(cpu.cpu_debug->instrOperand)); fprintf(cpu.cpu_debug->m_fdbg, " [%04x]", cpu.Cycle_EffectiveAddress); break; // Absolute Addressing Mode Handler case ADCa: case ANDa: case ASLa: case BITa: case CMPa: case CPXa: case CPYa: case DCPa: case DECa: case EORa: case INCa: case ISBa: case LAXa: case LDAa: case LDXa: case LDYa: case LSRa: case ORAa: case ROLa: case RORa: case SBCa: case SLOa: case SREa: case RLAa: case RRAa: // ASOa AXSa DCMa INSa LSEa - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "a %04x {%02x}", cpu.cpu_debug->instrOperand, cpu.Cycle_Data); break; case SAXa: case STAa: case STXa: case STYa: case NOPa: fprintf(cpu.cpu_debug->m_fdbg, "a %04x", cpu.cpu_debug->instrOperand); break; case JMPw: case JSRw: fprintf(cpu.cpu_debug->m_fdbg, "w %04x", cpu.cpu_debug->instrOperand); break; // Absolute With X Offset Addresing Mode Handler case ADCax: case ANDax: case ASLax: case CMPax: case DCPax: case DECax: case EORax: case INCax: case ISBax: case LDAax: case LDYax: case LSRax: case ORAax: case RLAax: case ROLax: case RORax: case RRAax: case SBCax: case SLOax: case SREax: // ASOax DCMax INSax LSEax SAYax - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "ax %04x,X", cpu.cpu_debug->instrOperand); fprintf(cpu.cpu_debug->m_fdbg, " [%04x]{%02x}", cpu.Cycle_EffectiveAddress, cpu.Cycle_Data); break; case SHYax: case STAax: case NOPax_: fprintf(cpu.cpu_debug->m_fdbg, "ax %04x,X", cpu.cpu_debug->instrOperand); fprintf(cpu.cpu_debug->m_fdbg, " [%04x]", cpu.Cycle_EffectiveAddress); break; // Absolute With Y Offset Addresing Mode Handler case ADCay: case ANDay: case CMPay: case DCPay: case EORay: case ISBay: case LASay: case LAXay: case LDAay: case LDXay: case ORAay: case RLAay: case RRAay: case SBCay: case SHSay: case SLOay: case SREay: // ASOay AXAay DCMay INSax LSEay TASay XASay - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "ay %04x,Y", cpu.cpu_debug->instrOperand); fprintf(cpu.cpu_debug->m_fdbg, " [%04x]{%02x}", cpu.Cycle_EffectiveAddress, cpu.Cycle_Data); break; case SHAay: case SHXay: case STAay: fprintf(cpu.cpu_debug->m_fdbg, "ay %04x,Y", cpu.cpu_debug->instrOperand); fprintf(cpu.cpu_debug->m_fdbg, " [%04x]", cpu.Cycle_EffectiveAddress); break; // Immediate Addressing Mode Handler case ADCb: case ANDb: case ANCb_: case ANEb: case ASRb: case ARRb: case CMPb: case CPXb: case CPYb: case EORb: case LDAb: case LDXb: case LDYb: case LXAb: case ORAb: case SBCb_: case SBXb: // OALb ALRb XAAb - Optional Opcode Names case NOPb_: fprintf(cpu.cpu_debug->m_fdbg, "b #%02x", endian_16lo8(cpu.cpu_debug->instrOperand)); break; // Relative Addressing Mode Handler case BCCr: case BCSr: case BEQr: case BMIr: case BNEr: case BPLr: case BVCr: case BVSr: fprintf(cpu.cpu_debug->m_fdbg, "r #%02x", endian_16lo8(cpu.cpu_debug->instrOperand)); fprintf(cpu.cpu_debug->m_fdbg, " [%04x]", cpu.Cycle_EffectiveAddress); break; // Indirect Addressing Mode Handler case JMPi: fprintf(cpu.cpu_debug->m_fdbg, "i (%04x)", cpu.cpu_debug->instrOperand); fprintf(cpu.cpu_debug->m_fdbg, " [%04x]", cpu.Cycle_EffectiveAddress); break; // Indexed with X Preinc Addressing Mode Handler case ADCix: case ANDix: case CMPix: case DCPix: case EORix: case ISBix: case LAXix: case LDAix: case ORAix: case SBCix: case SLOix: case SREix: case RLAix: case RRAix: // ASOix AXSix DCMix INSix LSEix - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "ix (%02x,X)", endian_16lo8(cpu.cpu_debug->instrOperand)); fprintf(cpu.cpu_debug->m_fdbg, " [%04x]{%02x}", cpu.Cycle_EffectiveAddress, cpu.Cycle_Data); break; case SAXix: case STAix: fprintf(cpu.cpu_debug->m_fdbg, "ix (%02x,X)", endian_16lo8(cpu.cpu_debug->instrOperand)); fprintf(cpu.cpu_debug->m_fdbg, " [%04x]", cpu.Cycle_EffectiveAddress); break; // Indexed with Y Postinc Addressing Mode Handler case ADCiy: case ANDiy: case CMPiy: case DCPiy: case EORiy: case ISBiy: case LAXiy: case LDAiy: case ORAiy: case RLAiy: case RRAiy: case SBCiy: case SLOiy: case SREiy: // AXAiy ASOiy LSEiy DCMiy INSiy - Optional Opcode Names fprintf(cpu.cpu_debug->m_fdbg, "iy (%02x),Y", endian_16lo8(cpu.cpu_debug->instrOperand)); fprintf(cpu.cpu_debug->m_fdbg, " [%04x]{%02x}", cpu.Cycle_EffectiveAddress, cpu.Cycle_Data); break; case SHAiy: case STAiy: fprintf(cpu.cpu_debug->m_fdbg, "iy (%02x),Y", endian_16lo8(cpu.cpu_debug->instrOperand)); fprintf(cpu.cpu_debug->m_fdbg, " [%04x]", cpu.Cycle_EffectiveAddress); break; default: break; } fprintf(cpu.cpu_debug->m_fdbg, "\n\n"); fflush(cpu.cpu_debug->m_fdbg); } } libsidplayfp-3.0.0/src/c64/CPU/mos6510.cpp0000644000175100017510000020067715175333711013331 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2026 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "mos6510.h" #include "Event.h" #include "sidendian.h" #include "opcodes.h" #include #include "mos6510debug.h" #include "sidcxx11.h" #include #include namespace libsidplayfp { /** * Magic values for lxa and ane undocumented instructions. * Magic may be EE, EF, FE or FF, but most emulators seem to use EE. * The constants here defined are based on VICE testsuite which * refers to some real case usage of the opcodes. */ constexpr uint8_t lxa_magic = 0xee; constexpr uint8_t ane_magic = 0xef; constexpr int interruptDelay = 2; //-------------------------------------------------------------------------// template void StaticFuncWrapper(MOS6510& self) { (self.*Func)(); } /** * When AEC signal is high, no stealing is possible. */ void MOS6510::eventWithoutSteals() { const ProcessorCycle &instr = instrTable[cycleCount++]; (instr.func)(*this); eventScheduler.schedule(m_nosteal, 1); } /** * When AEC signal is low, steals permitted. */ void MOS6510::eventWithSteals() { if (instrTable[cycleCount].nosteal) { const ProcessorCycle &instr = instrTable[cycleCount++]; (instr.func)(*this); eventScheduler.schedule(m_steal, 1); } else { switch (cycleCount) { case (CLIn << 3): flags.setI(false); if (irqAssertedOnPin && (interruptCycle == MAX)) interruptCycle = -MAX; break; case (SEIn << 3): flags.setI(true); if (!rstFlag && !nmiFlag && (cycleCount <= interruptCycle + interruptDelay)) interruptCycle = MAX; break; case (SHAiy << 3) + 3: case (SHSay << 3) + 2: case (SHYax << 3) + 2: case (SHXay << 3) + 2: case (SHAay << 3) + 2: // Save rdy state for SH* instructions rdyOnThrowAwayRead = true; break; default: break; } // Even while stalled, the CPU can still process first clock of // interrupt delay, but only the first one. if (interruptCycle == cycleCount) { interruptCycle--; } } } void MOS6510::removeIRQ() { if (!rstFlag && !nmiFlag && (interruptCycle != MAX)) interruptCycle = MAX; } /** * Handle bus access signals. When RDY line is asserted, the CPU * will pause when executing the next read operation. * * @param newRDY new state for RDY signal */ void MOS6510::setRDY(bool newRDY) { rdy = newRDY; if (rdy) { eventScheduler.cancel(m_steal); eventScheduler.schedule(m_nosteal, 0, EVENT_CLOCK_PHI2); } else { eventScheduler.cancel(m_nosteal); eventScheduler.schedule(m_steal, 0, EVENT_CLOCK_PHI2); } } /** * Push P on stack, decrement S. */ void MOS6510::PushSR() { // Set the B flag, 0 for hardware interrupts // and 1 for BRK and PHP. Bit 5 is always 1 // https://wiki.nesdev.org/w/index.php?title=Status_flags#The_B_flag Push(flags.get() | (d1x1 ? 0x20 : 0x30)); } /** * increment S, Pop P off stack. */ void MOS6510::PopSR() { flags.set(Pop()); calculateInterruptTriggerCycle(); } //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// // Interrupt Routines // //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// /** * This forces the CPU to abort whatever it is doing and immediately * enter the RST interrupt handling sequence. The implementation is * not compatible: instructions actually get aborted mid-execution. * However, there is no possible way to trigger this signal from * programs, so it's OK. */ void MOS6510::triggerRST() { Initialise(); cycleCount = BRKn << 3; rstFlag = true; calculateInterruptTriggerCycle(); } /** * Trigger NMI interrupt on the CPU. Calling this method * flags that CPU must enter the NMI routine at earliest * opportunity. There is no way to cancel NMI request once * given. */ void MOS6510::triggerNMI() { nmiFlag = true; calculateInterruptTriggerCycle(); /* maybe process 1 clock of interrupt delay. */ if (!rdy) { eventScheduler.cancel(m_steal); eventScheduler.schedule(m_steal, 0, EVENT_CLOCK_PHI2); } } /** * Pull IRQ line low on CPU. */ void MOS6510::triggerIRQ() { irqAssertedOnPin = true; calculateInterruptTriggerCycle(); /* maybe process 1 clock of interrupt delay. */ if (!rdy && interruptCycle == cycleCount) { eventScheduler.cancel(m_steal); eventScheduler.schedule(m_steal, 0, EVENT_CLOCK_PHI2); } } /** * Inform CPU that IRQ is no longer pulled low. */ void MOS6510::clearIRQ() { irqAssertedOnPin = false; eventScheduler.schedule(clearInt, interruptDelay, EVENT_CLOCK_PHI1); } void MOS6510::interruptsAndNextOpcode() { if (cycleCount > interruptCycle + interruptDelay) { if (cpu_debug) UNLIKELY { const event_clock_t cycles = eventScheduler.getTime(EVENT_CLOCK_PHI2); MOS6510Debug::DumpState(cycles, *this); fprintf(cpu_debug->m_fdbg, "****************************************************\n"); fprintf(cpu_debug->m_fdbg, " interrupt (%d)\n", static_cast(cycles)); fprintf(cpu_debug->m_fdbg, "****************************************************\n"); cpu_debug->instrStartPC = -1; } cpuRead(Register_ProgramCounter); cycleCount = BRKn << 3; d1x1 = true; interruptCycle = MAX; } else { fetchNextOpcode(); } } void MOS6510::fetchNextOpcode() { if (cpu_debug) UNLIKELY { MOS6510Debug::DumpState(eventScheduler.getTime(EVENT_CLOCK_PHI2), *this); cpu_debug->instrStartPC = Register_ProgramCounter; } rdyOnThrowAwayRead = false; cycleCount = cpuRead(Register_ProgramCounter) << 3; Register_ProgramCounter++; if (!checkInterrupts()) { interruptCycle = MAX; } else if (interruptCycle != MAX) { interruptCycle = -MAX; } } /** * Evaluate when to execute an interrupt. Calling this method can also * result in the decision that no interrupt at all needs to be scheduled. */ void MOS6510::calculateInterruptTriggerCycle() { /* Interrupt cycle not going to trigger? */ if (interruptCycle == MAX) { if (checkInterrupts()) { interruptCycle = cycleCount; } } } void MOS6510::IRQLoRequest() { endian_16lo8(Register_ProgramCounter, cpuRead(Cycle_EffectiveAddress)); d1x1 = false; } void MOS6510::IRQHiRequest() { endian_16hi8(Register_ProgramCounter, cpuRead(Cycle_EffectiveAddress + 1)); flags.setI(true); } /** * Read the next opcode byte from memory (and throw it away) */ void MOS6510::throwAwayFetch() { cpuRead(Register_ProgramCounter); } /** * Issue throw-away read and fix address. * Some people use these to ACK CIA IRQs. */ void MOS6510::throwAwayRead() { cpuRead(Cycle_EffectiveAddress); if (adl_carry) Cycle_EffectiveAddress += 0x100; } /** * Fetch value, increment PC. * * Addressing Modes: * - Immediate * - Relative */ void MOS6510::FetchDataByte() { Cycle_Data = cpuRead(Register_ProgramCounter); if (!d1x1) { Register_ProgramCounter++; } if (cpu_debug) UNLIKELY { cpu_debug->instrOperand = Cycle_Data; } } /** * Fetch low address byte, increment PC. * * Addressing Modes: * - Stack Manipulation * - Absolute * - Zero Page * - Zero Page Indexed * - Absolute Indexed * - Absolute Indirect */ void MOS6510::FetchLowAddr() { Cycle_EffectiveAddress = cpuRead(Register_ProgramCounter); Register_ProgramCounter++; if (cpu_debug) UNLIKELY { cpu_debug->instrOperand = Cycle_EffectiveAddress; } } /** * Read from address, add index register X to it. * * Addressing Modes: * - Zero Page Indexed */ void MOS6510::FetchLowAddrX() { FetchLowAddr(); Cycle_EffectiveAddress = (Cycle_EffectiveAddress + Register_X) & 0xff; } /** * Read from address, add index register Y to it. * * Addressing Modes: * - Zero Page Indexed */ void MOS6510::FetchLowAddrY() { FetchLowAddr(); Cycle_EffectiveAddress = (Cycle_EffectiveAddress + Register_Y) & 0xff; } /** * Fetch high address byte, increment PC (Absolute Addressing). * Low byte must have been obtained first! * * Addressing Modes: * - Absolute */ void MOS6510::FetchHighAddr() { // Get the high byte of an address from memory endian_16hi8(Cycle_EffectiveAddress, cpuRead(Register_ProgramCounter)); Register_ProgramCounter++; if (cpu_debug) UNLIKELY { endian_16hi8(cpu_debug->instrOperand, endian_16hi8(Cycle_EffectiveAddress)); } } /** * Fetch high byte of address, add index register X to low address byte, * increment PC. * * Addressing Modes: * - Absolute Indexed */ void MOS6510::FetchHighAddrX() { Cycle_EffectiveAddress += Register_X; adl_carry = Cycle_EffectiveAddress > 0xff; FetchHighAddr(); } /** * Same as #FetchHighAddrX except doesn't worry about page crossing. */ void MOS6510::FetchHighAddrX2() { FetchHighAddrX(); if (!adl_carry) cycleCount++; } /** * Fetch high byte of address, add index register Y to low address byte, * increment PC. * * Addressing Modes: * - Absolute Indexed */ void MOS6510::FetchHighAddrY() { Cycle_EffectiveAddress += Register_Y; adl_carry = Cycle_EffectiveAddress > 0xff; FetchHighAddr(); } /** * Same as #FetchHighAddrY except doesn't worry about page crossing. */ void MOS6510::FetchHighAddrY2() { FetchHighAddrY(); if (!adl_carry) cycleCount++; } /** * Fetch pointer address low, increment PC. * * Addressing Modes: * - Absolute Indirect * - Indirect indexed (post Y) */ void MOS6510::FetchLowPointer() { Cycle_Pointer = cpuRead(Register_ProgramCounter); Register_ProgramCounter++; if (cpu_debug) UNLIKELY { cpu_debug->instrOperand = Cycle_Pointer; } } /** * Add X to it. * * Addressing Modes: * - Indexed Indirect (pre X) */ void MOS6510::FetchLowPointerX() { endian_16lo8(Cycle_Pointer, (Cycle_Pointer + Register_X) & 0xff); } /** * Fetch pointer address high, increment PC. * * Addressing Modes: * - Absolute Indirect */ void MOS6510::FetchHighPointer() { endian_16hi8(Cycle_Pointer, cpuRead(Register_ProgramCounter)); Register_ProgramCounter++; if (cpu_debug) UNLIKELY { endian_16hi8(cpu_debug->instrOperand, endian_16hi8(Cycle_Pointer)); } } /** * Fetch effective address low. * * Addressing Modes: * - Indirect * - Indexed Indirect (pre X) * - Indirect indexed (post Y) */ void MOS6510::FetchLowEffAddr() { Cycle_EffectiveAddress = cpuRead(Cycle_Pointer); } /** * Fetch effective address high. * * Addressing Modes: * - Indirect * - Indexed Indirect (pre X) */ void MOS6510::FetchHighEffAddr() { endian_16lo8(Cycle_Pointer, (Cycle_Pointer + 1) & 0xff); endian_16hi8(Cycle_EffectiveAddress, cpuRead(Cycle_Pointer)); } /** * Fetch effective address high, add Y to low byte of effective address. * * Addressing Modes: * - Indirect indexed (post Y) */ void MOS6510::FetchHighEffAddrY() { Cycle_EffectiveAddress += Register_Y; adl_carry = Cycle_EffectiveAddress > 0xff; FetchHighEffAddr(); } /** * Same as #FetchHighEffAddrY except doesn't worry about page crossing. */ void MOS6510::FetchHighEffAddrY2() { FetchHighEffAddrY(); if (!adl_carry) cycleCount++; } //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// // Common Data Accessing Routines // // Data Accessing operations as described in 64doc by John West and // // Marko Makela // //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// void MOS6510::FetchEffAddrDataByte() { Cycle_Data = cpuRead(Cycle_EffectiveAddress); } /** * Write Cycle_Data to effective address. */ void MOS6510::PutEffAddrDataByte() { cpuWrite(Cycle_EffectiveAddress, Cycle_Data); } /** * Push data on the stack */ void MOS6510::Push(uint8_t data) { const uint_least16_t addr = endian_16(SP_PAGE, Register_StackPointer); cpuWrite(addr, data); Register_StackPointer--; } /** * Pop data from the stack */ uint8_t MOS6510::Pop() { Register_StackPointer++; const uint_least16_t addr = endian_16(SP_PAGE, Register_StackPointer); return cpuRead(addr); } /** * Push Program Counter Low Byte on stack, decrement S. */ void MOS6510::PushLowPC() { Push(endian_16lo8(Register_ProgramCounter)); } /** * Push Program Counter High Byte on stack, decrement S. */ void MOS6510::PushHighPC() { Push(endian_16hi8(Register_ProgramCounter)); } /** * Increment stack and pull program counter low byte from stack. */ void MOS6510::PopLowPC() { endian_16lo8(Cycle_EffectiveAddress, Pop()); } /** * Increment stack and pull program counter high byte from stack. */ void MOS6510::PopHighPC() { endian_16hi8(Cycle_EffectiveAddress, Pop()); } void MOS6510::WasteCycle() {} void MOS6510::brkPushLowPC() { PushLowPC(); if (rstFlag) { /* rst = %10x */ Cycle_EffectiveAddress = 0xfffc; } else if (nmiFlag) { /* nmi = %01x */ Cycle_EffectiveAddress = 0xfffa; } else { /* irq = %11x */ Cycle_EffectiveAddress = 0xfffe; } rstFlag = false; nmiFlag = false; calculateInterruptTriggerCycle(); } //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// // Common Instruction Opcodes // // See and 6510 Assembly Book for more information on these instructions // //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// void MOS6510::cld_instr() { flags.setD(false); interruptsAndNextOpcode(); } void MOS6510::cli_instr() { flags.setI(false); calculateInterruptTriggerCycle(); interruptsAndNextOpcode(); } void MOS6510::jmp_instr() { Register_ProgramCounter = Cycle_EffectiveAddress; interruptsAndNextOpcode(); } void MOS6510::pha_instr() { Push(Register_Accumulator); } /** * RTI does not delay the IRQ I flag change as it is set 3 cycles before * the end of the opcode, and thus the 6510 has enough time to call the * interrupt routine as soon as the opcode ends, if necessary. */ void MOS6510::rti_instr() { Register_ProgramCounter = Cycle_EffectiveAddress; interruptsAndNextOpcode(); if (cpu_debug) UNLIKELY { fprintf(cpu_debug->m_fdbg, "****************************************************\n\n"); } } void MOS6510::rts_instr() { cpuRead(Cycle_EffectiveAddress); Register_ProgramCounter = Cycle_EffectiveAddress; Register_ProgramCounter++; } void MOS6510::sed_instr() { flags.setD(true); interruptsAndNextOpcode(); } void MOS6510::sei_instr() { flags.setI(true); interruptsAndNextOpcode(); if (!rstFlag && !nmiFlag && interruptCycle != MAX) interruptCycle = MAX; } void MOS6510::sta_instr() { Cycle_Data = Register_Accumulator; PutEffAddrDataByte(); } void MOS6510::stx_instr() { Cycle_Data = Register_X; PutEffAddrDataByte(); } void MOS6510::sty_instr() { Cycle_Data = Register_Y; PutEffAddrDataByte(); } //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// // Common Instruction Undocumented Opcodes // // See documented 6502-nmo.opc by Adam Vardy for more details // //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// #if 0 // Not required - Operation performed By another method // // Undocumented - HLT crashes the microprocessor. When this opcode is executed, program // execution ceases. No hardware interrupts will execute either. The author // has characterized this instruction as a halt instruction since this is the // most straightforward explanation for this opcode's behaviour. Only a reset // will restart execution. This opcode leaves no trace of any operation // performed! No registers affected. void MOS6510::hlt_instr() {} #endif /** * Perform the SH* instructions. */ void MOS6510::sh_instr() { uint8_t tmp = endian_16hi8(Cycle_EffectiveAddress); /* * When the addressing/indexing causes a page boundary crossing * the highbyte of the target address is ANDed with the value stored. */ if (adl_carry) { endian_16hi8(Cycle_EffectiveAddress, tmp & Cycle_Data); } else tmp++; /* * When a DMA is going on (the CPU is halted by the VIC-II) * while the instruction sha/shx/shy executes then the last * term of the ANDing (ADH+1) drops off. * * http://sourceforge.net/p/vice-emu/bugs/578/ */ if (!rdyOnThrowAwayRead) { Cycle_Data &= tmp; } PutEffAddrDataByte(); } /** * Undocumented - This opcode stores the result of A AND X AND ADH+1 in memory. */ void MOS6510::axa_instr() { Cycle_Data = Register_X & Register_Accumulator; sh_instr(); } /** * Undocumented - This opcode ANDs the contents of the Y register with ADH+1 and stores the * result in memory. */ void MOS6510::say_instr() { Cycle_Data = Register_Y; sh_instr(); } /** * Undocumented - This opcode ANDs the contents of the X register with ADH+1 and stores the * result in memory. */ void MOS6510::xas_instr() { Cycle_Data = Register_X; sh_instr(); } /** * Undocumented - AXS ANDs the contents of the A and X registers (without changing the * contents of either register) and stores the result in memory. * AXS does not affect any flags in the processor status register. */ void MOS6510::axs_instr() { Cycle_Data = Register_Accumulator & Register_X; PutEffAddrDataByte(); } /** * BCD adding. */ void MOS6510::doADC() { const unsigned int C = flags.getC() ? 1 : 0; const unsigned int A = Register_Accumulator; const unsigned int s = Cycle_Data; const unsigned int regAC2 = A + s + C; if (flags.getD()) { // BCD mode unsigned int lo = (A & 0x0f) + (s & 0x0f) + C; unsigned int hi = (A & 0xf0) + (s & 0xf0); if (lo > 0x09) lo += 0x06; if (lo > 0x0f) hi += 0x10; flags.setZ(!(regAC2 & 0xff)); flags.setN(hi & 0x80); flags.setV(((hi ^ A) & 0x80) && !((A ^ s) & 0x80)); if (hi > 0x90) hi += 0x60; flags.setC(hi > 0xff); Register_Accumulator = (hi | (lo & 0x0f)); } else { // Binary mode flags.setC(regAC2 > 0xff); flags.setV(((regAC2 ^ A) & 0x80) && !((A ^ s) & 0x80)); flags.setNZ(Register_Accumulator = regAC2 & 0xff); } } /** * BCD subtracting. */ void MOS6510::doSBC() { const unsigned int C = flags.getC() ? 0 : 1; const unsigned int A = Register_Accumulator; const unsigned int s = Cycle_Data; const unsigned int regAC2 = A - s - C; flags.setC(regAC2 < 0x100); flags.setV(((regAC2 ^ A) & 0x80) && ((A ^ s) & 0x80)); flags.setNZ(regAC2); if (flags.getD()) { // BCD mode unsigned int lo = (A & 0x0f) - (s & 0x0f) - C; unsigned int hi = (A & 0xf0) - (s & 0xf0); if (lo & 0x10) { lo -= 0x06; hi -= 0x10; } if (hi & 0x100) hi -= 0x60; Register_Accumulator = (hi | (lo & 0x0f)); } else { // Binary mode Register_Accumulator = regAC2 & 0xff; } } //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// // Generic Instruction Addressing Routines // //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// // Generic Instruction Opcodes // // See and 6510 Assembly Book for more information on these instructions // //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// void MOS6510::adc_instr() { doADC(); interruptsAndNextOpcode(); } void MOS6510::and_instr() { flags.setNZ(Register_Accumulator &= Cycle_Data); interruptsAndNextOpcode(); } /** * Undocumented - For a detailed explanation of this opcode look at: * http://visual6502.org/wiki/index.php?title=6502_Opcode_8B_(XAA,_ANE) */ void MOS6510::ane_instr() { flags.setNZ(Register_Accumulator = (Register_Accumulator | ane_magic) & Register_X & Cycle_Data); interruptsAndNextOpcode(); } void MOS6510::asl_instr() { PutEffAddrDataByte(); flags.setC(Cycle_Data & 0x80); flags.setNZ(Cycle_Data <<= 1); } void MOS6510::asla_instr() { flags.setC(Register_Accumulator & 0x80); flags.setNZ(Register_Accumulator <<= 1); interruptsAndNextOpcode(); } void MOS6510::fix_branch() { // Throw away read cpuRead(Cycle_EffectiveAddress); // Fix address Register_ProgramCounter += Cycle_Data < 0x80 ? 0x0100 : 0xff00; } void MOS6510::branch_instr(bool condition) { // 2 cycles spent before arriving here. spend 0 - 2 cycles here; // - condition false: Continue immediately to FetchNextInstr. // // Otherwise read the byte following the opcode (which is already scheduled to occur on this cycle). // This effort is wasted. Then calculate address of the branch target. If branch is on same page, // then continue at that insn on next cycle (this delays IRQs by 1 clock for some reason, allegedly). // // If the branch is on different memory page, issue a spurious read with wrong high byte before // continuing at the correct address. if (condition) { // issue the spurious read for next insn here. cpuRead(Register_ProgramCounter); Cycle_EffectiveAddress = endian_16lo8(Register_ProgramCounter); Cycle_EffectiveAddress += Cycle_Data; adl_carry = (Cycle_EffectiveAddress > 0xff) != (Cycle_Data > 0x7f); endian_16hi8(Cycle_EffectiveAddress, endian_16hi8(Register_ProgramCounter)); Register_ProgramCounter = Cycle_EffectiveAddress; // Check for page boundary crossing if (!adl_carry) { // Skip next throw away read cycleCount++; // Hack: delay the interrupt past this instruction. if (interruptCycle >> 3 == cycleCount >> 3) interruptCycle += 2; } } else { // branch not taken: skip the following spurious read insn and go to FetchNextInstr immediately. interruptsAndNextOpcode(); } } void MOS6510::bcc_instr() { branch_instr(!flags.getC()); } void MOS6510::bcs_instr() { branch_instr(flags.getC()); } void MOS6510::beq_instr() { branch_instr(flags.getZ()); } void MOS6510::bit_instr() { flags.setZ((Register_Accumulator & Cycle_Data) == 0); flags.setN(Cycle_Data & 0x80); flags.setV(Cycle_Data & 0x40); interruptsAndNextOpcode(); } void MOS6510::bmi_instr() { branch_instr(flags.getN()); } void MOS6510::bne_instr() { branch_instr(!flags.getZ()); } void MOS6510::bpl_instr() { branch_instr(!flags.getN()); } void MOS6510::bvc_instr() { branch_instr(!flags.getV()); } void MOS6510::bvs_instr() { branch_instr(flags.getV()); } void MOS6510::clc_instr() { flags.setC(false); interruptsAndNextOpcode(); } void MOS6510::clv_instr() { flags.setV(false); interruptsAndNextOpcode(); } void MOS6510::compare(uint8_t data) { const uint_least16_t tmp = static_cast(data) - Cycle_Data; flags.setNZ(tmp); flags.setC(tmp < 0x100); interruptsAndNextOpcode(); } void MOS6510::cmp_instr() { compare(Register_Accumulator); } void MOS6510::cpx_instr() { compare(Register_X); } void MOS6510::cpy_instr() { compare(Register_Y); } void MOS6510::dec_instr() { PutEffAddrDataByte(); flags.setNZ(--Cycle_Data); } void MOS6510::dex_instr() { flags.setNZ(--Register_X); interruptsAndNextOpcode(); } void MOS6510::dey_instr() { flags.setNZ(--Register_Y); interruptsAndNextOpcode(); } void MOS6510::eor_instr() { flags.setNZ(Register_Accumulator ^= Cycle_Data); interruptsAndNextOpcode(); } void MOS6510::inc_instr() { PutEffAddrDataByte(); flags.setNZ(++Cycle_Data); } void MOS6510::inx_instr() { flags.setNZ(++Register_X); interruptsAndNextOpcode(); } void MOS6510::iny_instr() { flags.setNZ(++Register_Y); interruptsAndNextOpcode(); } void MOS6510::lda_instr() { flags.setNZ(Register_Accumulator = Cycle_Data); interruptsAndNextOpcode(); } void MOS6510::ldx_instr() { flags.setNZ(Register_X = Cycle_Data); interruptsAndNextOpcode(); } void MOS6510::ldy_instr() { flags.setNZ(Register_Y = Cycle_Data); interruptsAndNextOpcode(); } void MOS6510::lsr_instr() { PutEffAddrDataByte(); flags.setC(Cycle_Data & 0x01); flags.setNZ(Cycle_Data >>= 1); } void MOS6510::lsra_instr() { flags.setC(Register_Accumulator & 0x01); flags.setNZ(Register_Accumulator >>= 1); interruptsAndNextOpcode(); } void MOS6510::ora_instr() { flags.setNZ(Register_Accumulator |= Cycle_Data); interruptsAndNextOpcode(); } void MOS6510::pla_instr() { flags.setNZ(Register_Accumulator = Pop()); } void MOS6510::rol_instr() { const uint8_t newC = Cycle_Data & 0x80; PutEffAddrDataByte(); Cycle_Data <<= 1; if (flags.getC()) Cycle_Data |= 0x01; flags.setNZ(Cycle_Data); flags.setC(newC); } void MOS6510::rola_instr() { const uint8_t newC = Register_Accumulator & 0x80; Register_Accumulator <<= 1; if (flags.getC()) Register_Accumulator |= 0x01; flags.setNZ(Register_Accumulator); flags.setC(newC); interruptsAndNextOpcode(); } void MOS6510::ror_instr() { const uint8_t newC = Cycle_Data & 0x01; PutEffAddrDataByte(); Cycle_Data >>= 1; if (flags.getC()) Cycle_Data |= 0x80; flags.setNZ(Cycle_Data); flags.setC(newC); } void MOS6510::rora_instr() { const uint8_t newC = Register_Accumulator & 0x01; Register_Accumulator >>= 1; if (flags.getC()) Register_Accumulator |= 0x80; flags.setNZ(Register_Accumulator); flags.setC(newC); interruptsAndNextOpcode(); } void MOS6510::sbx_instr() { const unsigned int tmp = (Register_X & Register_Accumulator) - Cycle_Data; flags.setNZ(Register_X = tmp & 0xff); flags.setC(tmp < 0x100); interruptsAndNextOpcode(); } void MOS6510::sbc_instr() { doSBC(); interruptsAndNextOpcode(); } void MOS6510::sec_instr() { flags.setC(true); interruptsAndNextOpcode(); } void MOS6510::shs_instr() { Register_StackPointer = Register_Accumulator & Register_X; Cycle_Data = Register_StackPointer; sh_instr(); } void MOS6510::tax_instr() { flags.setNZ(Register_X = Register_Accumulator); interruptsAndNextOpcode(); } void MOS6510::tay_instr() { flags.setNZ(Register_Y = Register_Accumulator); interruptsAndNextOpcode(); } void MOS6510::tsx_instr() { flags.setNZ(Register_X = Register_StackPointer); interruptsAndNextOpcode(); } void MOS6510::txa_instr() { flags.setNZ(Register_Accumulator = Register_X); interruptsAndNextOpcode(); } void MOS6510::txs_instr() { Register_StackPointer = Register_X; interruptsAndNextOpcode(); } void MOS6510::tya_instr() { flags.setNZ(Register_Accumulator = Register_Y); interruptsAndNextOpcode(); } void MOS6510::invalidOpcode() { std::ostringstream msg; msg << std::setfill('0') << "Illegal instruction $" << std::setw(2) << std::hex << (cycleCount >> 3) << " at address $" << std::setw(4) << (Register_ProgramCounter-1); throw haltInstruction(msg.str()); } //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// // Generic Instruction Undocumented Opcodes // // See documented 6502-nmo.opc by Adam Vardy for more details // //-------------------------------------------------------------------------// //-------------------------------------------------------------------------// /** * Undocumented - This opcode ANDs the contents of the A register with an immediate value and * then LSRs the result. */ void MOS6510::alr_instr() { Register_Accumulator &= Cycle_Data; flags.setC(Register_Accumulator & 0x01); flags.setNZ(Register_Accumulator >>= 1); interruptsAndNextOpcode(); } /** * Undocumented - ANC ANDs the contents of the A register with an immediate value and then * moves bit 7 of A into the Carry flag. This opcode works basically * identically to AND #immed. except that the Carry flag is set to the same * state that the Negative flag is set to. */ void MOS6510::anc_instr() { flags.setNZ(Register_Accumulator &= Cycle_Data); flags.setC(flags.getN()); interruptsAndNextOpcode(); } /** * Undocumented - This opcode ANDs the contents of the A register with an immediate value and * then RORs the result. (Implementation based on that of Frodo C64 Emulator) */ void MOS6510::arr_instr() { const uint8_t data = Cycle_Data & Register_Accumulator; Register_Accumulator = data >> 1; if (flags.getC()) Register_Accumulator |= 0x80; if (flags.getD()) { flags.setN(flags.getC()); flags.setZ(Register_Accumulator == 0); flags.setV((data ^ Register_Accumulator) & 0x40); if ((data & 0x0f) + (data & 0x01) > 5) Register_Accumulator = (Register_Accumulator & 0xf0) | ((Register_Accumulator + 6) & 0x0f); flags.setC(((data + (data & 0x10)) & 0x1f0) > 0x50); if (flags.getC()) Register_Accumulator += 0x60; } else { flags.setNZ(Register_Accumulator); flags.setC(Register_Accumulator & 0x40); flags.setV((Register_Accumulator & 0x40) ^ ((Register_Accumulator & 0x20) << 1)); } interruptsAndNextOpcode(); } /** * Undocumented - This opcode ASLs the contents of a memory location and then ORs the result * with the accumulator. */ void MOS6510::aso_instr() { PutEffAddrDataByte(); flags.setC(Cycle_Data & 0x80); Cycle_Data <<= 1; flags.setNZ(Register_Accumulator |= Cycle_Data); } /** * Undocumented - This opcode DECs the contents of a memory location and then CMPs the result * with the A register. */ void MOS6510::dcm_instr() { PutEffAddrDataByte(); Cycle_Data--; const uint_least16_t tmp = static_cast(Register_Accumulator) - Cycle_Data; flags.setNZ(tmp); flags.setC(tmp < 0x100); } /** * Undocumented - This opcode INCs the contents of a memory location and then SBCs the result * from the A register. */ void MOS6510::ins_instr() { PutEffAddrDataByte(); Cycle_Data++; doSBC(); } /** * Undocumented - This opcode ANDs the contents of a memory location with the contents of the * stack pointer register and stores the result in the accumulator, the X * register, and the stack pointer. Affected flags: N Z. */ void MOS6510::las_instr() { flags.setNZ(Cycle_Data &= Register_StackPointer); Register_Accumulator = Cycle_Data; Register_X = Cycle_Data; Register_StackPointer = Cycle_Data; interruptsAndNextOpcode(); } /** * Undocumented - This opcode loads both the accumulator and the X register with the contents * of a memory location. */ void MOS6510::lax_instr() { flags.setNZ(Register_Accumulator = Register_X = Cycle_Data); interruptsAndNextOpcode(); } /** * Undocumented - LSE LSRs the contents of a memory location and then EORs the result with * the accumulator. */ void MOS6510::lse_instr() { PutEffAddrDataByte(); flags.setC(Cycle_Data & 0x01); Cycle_Data >>= 1; flags.setNZ(Register_Accumulator ^= Cycle_Data); } /** * Undocumented - This opcode ORs the A register with #xx (the "magic" value), * ANDs the result with an immediate value, and then stores the result in both A and X. */ void MOS6510::oal_instr() { flags.setNZ(Register_X = (Register_Accumulator = (Cycle_Data & (Register_Accumulator | lxa_magic)))); interruptsAndNextOpcode(); } /** * Undocumented - RLA ROLs the contents of a memory location and then ANDs the result with * the accumulator. */ void MOS6510::rla_instr() { const uint8_t newC = Cycle_Data & 0x80; PutEffAddrDataByte(); Cycle_Data = Cycle_Data << 1; if (flags.getC()) Cycle_Data |= 0x01; flags.setC(newC); flags.setNZ(Register_Accumulator &= Cycle_Data); } /** * Undocumented - RRA RORs the contents of a memory location and then ADCs the result with * the accumulator. */ void MOS6510::rra_instr() { const uint8_t newC = Cycle_Data & 0x01; PutEffAddrDataByte(); Cycle_Data >>= 1; if (flags.getC()) Cycle_Data |= 0x80; flags.setC(newC); doADC(); } //-------------------------------------------------------------------------// /** * Create new CPU emu. * * @param context * The Event Context */ MOS6510::MOS6510(EventScheduler &scheduler, CPUDataBus &bus) : eventScheduler(scheduler), dataBus(bus), cpu_debug(nullptr), m_nosteal("CPU-nosteal", *this), m_steal("CPU-steal", *this), clearInt("Remove IRQ", *this) { buildInstructionTable(); // Intialise Processor Registers Register_Accumulator = 0; Register_X = 0; Register_Y = 0; Cycle_EffectiveAddress = 0; Cycle_Data = 0; Initialise(); } /** * Build up the processor instruction table. */ void MOS6510::buildInstructionTable() { for (unsigned int i = 0; i < 0x100; i++) { #ifndef NDEBUG printf("Building Command %u[%02x]... ", i, i); #endif /* * So: what cycles are marked as stealable? Rules are: * * - CPU performs either read or write at every cycle. Reads are * always stealable. Writes are rare. * * - Every instruction begins with a sequence of reads. Writes, * if any, are at the end for most instructions. */ unsigned int buildCycle = i << 3; enum class AccessMode { WRITE, READ }; AccessMode access = AccessMode::WRITE; bool legalMode = true; bool legalInstr = true; switch (i) { // Accumulator or Implied addressing case ASLn: case CLCn: case CLDn: case CLIn: case CLVn: case DEXn: case DEYn: case INXn: case INYn: case LSRn: case NOPn_: case PHAn: case PHPn: case PLAn: case PLPn: case ROLn: case RORn: case SECn: case SEDn: case SEIn: case TAXn: case TAYn: case TSXn: case TXAn: case TXSn: case TYAn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::throwAwayFetch>; break; // Immediate and Relative Addressing Mode Handler case ADCb: case ANDb: case ANCb_: case ANEb: case ASRb: case ARRb: case BCCr: case BCSr: case BEQr: case BMIr: case BNEr: case BPLr: case BRKn: case BVCr: case BVSr: case CMPb: case CPXb: case CPYb: case EORb: case LDAb: case LDXb: case LDYb: case LXAb: case NOPb_: case ORAb: case SBCb_: case SBXb: case RTIn: case RTSn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchDataByte>; break; // Zero Page Addressing Mode Handler - Read & RMW case ADCz: case ANDz: case BITz: case CMPz: case CPXz: case CPYz: case EORz: case LAXz: case LDAz: case LDXz: case LDYz: case ORAz: case NOPz_: case SBCz: case ASLz: case DCPz: case DECz: case INCz: case ISBz: case LSRz: case ROLz: case RORz: case SREz: case SLOz: case RLAz: case RRAz: access = AccessMode::READ; // fallthrough case SAXz: case STAz: case STXz: case STYz: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowAddr>; break; // Zero Page with X Offset Addressing Mode Handler // these issue extra reads on the 0 page, but we don't care about it // because there are no detectable effects from them. These reads // occur during the "wasted" cycle. case ADCzx: case ANDzx: case CMPzx: case EORzx: case LDAzx: case LDYzx: case NOPzx_: case ORAzx: case SBCzx: case ASLzx: case DCPzx: case DECzx: case INCzx: case ISBzx: case LSRzx: case RLAzx: case ROLzx: case RORzx: case RRAzx: case SLOzx: case SREzx: access = AccessMode::READ; // fallthrough case STAzx: case STYzx: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowAddrX>; // operates on 0 page in read mode. Truly side-effect free. instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::WasteCycle>; break; // Zero Page with Y Offset Addressing Mode Handler case LDXzy: case LAXzy: access = AccessMode::READ; // fallthrough case STXzy: case SAXzy: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowAddrY>; // operates on 0 page in read mode. Truly side-effect free. instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::WasteCycle>; break; // Absolute Addressing Mode Handler case ADCa: case ANDa: case BITa: case CMPa: case CPXa: case CPYa: case EORa: case LAXa: case LDAa: case LDXa: case LDYa: case NOPa: case ORAa: case SBCa: case ASLa: case DCPa: case DECa: case INCa: case ISBa: case LSRa: case ROLa: case RORa: case SLOa: case SREa: case RLAa: case RRAa: access = AccessMode::READ; // fallthrough case JMPw: case SAXa: case STAa: case STXa: case STYa: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowAddr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchHighAddr>; break; case JSRw: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowAddr>; break; // Absolute With X Offset Addressing Mode Handler (Read) case ADCax: case ANDax: case CMPax: case EORax: case LDAax: case LDYax: case NOPax_: case ORAax: case SBCax: access = AccessMode::READ; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowAddr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchHighAddrX2>; // this cycle is skipped if the address is already correct. // otherwise, it will be read and ignored. instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::throwAwayRead>; break; // Absolute X (RMW; no page crossing handled, always reads before writing) case ASLax: case DCPax: case DECax: case INCax: case ISBax: case LSRax: case RLAax: case ROLax: case RORax: case RRAax: case SLOax: case SREax: access = AccessMode::READ; // fallthrough case SHYax: case STAax: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowAddr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchHighAddrX>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::throwAwayRead>; break; // Absolute With Y Offset Addresing Mode Handler (Read) case ADCay: case ANDay: case CMPay: case EORay: case LASay: case LAXay: case LDAay: case LDXay: case ORAay: case SBCay: access = AccessMode::READ; // fallthrough instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowAddr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchHighAddrY2>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::throwAwayRead>; break; // Absolute Y (No page crossing handled) case DCPay: case ISBay: case RLAay: case RRAay: case SLOay: case SREay: access = AccessMode::READ; // fallthrough case SHAay: case SHSay: case SHXay: case STAay: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowAddr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchHighAddrY>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::throwAwayRead>; break; // Absolute Indirect Addressing Mode Handler case JMPi: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowPointer>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchHighPointer>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowEffAddr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchHighEffAddr>; break; // Indexed with X Preinc Addressing Mode Handler case ADCix: case ANDix: case CMPix: case EORix: case LAXix: case LDAix: case ORAix: case SBCix: case DCPix: case ISBix: case SLOix: case SREix: case RLAix: case RRAix: access = AccessMode::READ; // fallthrough case SAXix: case STAix: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowPointer>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowPointerX>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowEffAddr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchHighEffAddr>; break; // Indexed with Y Postinc Addressing Mode Handler (Read) case ADCiy: case ANDiy: case CMPiy: case EORiy: case LAXiy: case LDAiy: case ORAiy: case SBCiy: access = AccessMode::READ; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowPointer>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowEffAddr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchHighEffAddrY2>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::throwAwayRead>; break; // Indexed Y (No page crossing handled) case DCPiy: case ISBiy: case RLAiy: case RRAiy: case SLOiy: case SREiy: access = AccessMode::READ; // fallthrough case SHAiy: case STAiy: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowPointer>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchLowEffAddr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchHighEffAddrY>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::throwAwayRead>; break; default: legalMode = false; break; } if (access == AccessMode::READ) { instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchEffAddrDataByte>; } //--------------------------------------------------------------------------------------- // Addressing Modes Finished, other cycles are instruction dependent //--------------------------------------------------------------------------------------- switch(i) { case ADCz: case ADCzx: case ADCa: case ADCax: case ADCay: case ADCix: case ADCiy: case ADCb: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::adc_instr>; break; case ANCb_: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::anc_instr>; break; case ANDz: case ANDzx: case ANDa: case ANDax: case ANDay: case ANDix: case ANDiy: case ANDb: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::and_instr>; break; case ANEb: // Also known as XAA instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::ane_instr>; break; case ARRb: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::arr_instr>; break; case ASLn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::asla_instr>; break; case ASLz: case ASLzx: case ASLa: case ASLax: instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::asl_instr>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PutEffAddrDataByte>; break; case ASRb: // Also known as ALR instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::alr_instr>; break; case BCCr: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::bcc_instr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::fix_branch>; break; case BCSr: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::bcs_instr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::fix_branch>; break; case BEQr: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::beq_instr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::fix_branch>; break; case BITz: case BITa: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::bit_instr>; break; case BMIr: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::bmi_instr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::fix_branch>; break; case BNEr: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::bne_instr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::fix_branch>; break; case BPLr: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::bpl_instr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::fix_branch>; break; case BRKn: instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PushHighPC>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::brkPushLowPC>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PushSR>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::IRQLoRequest>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::IRQHiRequest>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::fetchNextOpcode>; break; case BVCr: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::bvc_instr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::fix_branch>; break; case BVSr: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::bvs_instr>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::fix_branch>; break; case CLCn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::clc_instr>; break; case CLDn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::cld_instr>; break; case CLIn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::cli_instr>; break; case CLVn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::clv_instr>; break; case CMPz: case CMPzx: case CMPa: case CMPax: case CMPay: case CMPix: case CMPiy: case CMPb: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::cmp_instr>; break; case CPXz: case CPXa: case CPXb: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::cpx_instr>; break; case CPYz: case CPYa: case CPYb: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::cpy_instr>; break; case DCPz: case DCPzx: case DCPa: case DCPax: case DCPay: case DCPix: case DCPiy: // Also known as DCM instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::dcm_instr>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PutEffAddrDataByte>; break; case DECz: case DECzx: case DECa: case DECax: instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::dec_instr>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PutEffAddrDataByte>; break; case DEXn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::dex_instr>; break; case DEYn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::dey_instr>; break; case EORz: case EORzx: case EORa: case EORax: case EORay: case EORix: case EORiy: case EORb: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::eor_instr>; break; #if 0 // HLT, also known as JAM case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52: case 0x62: case 0x72: case 0x92: case 0xb2: case 0xd2: case 0xf2: case 0x02: case 0x12: case 0x22: case 0x32: case 0x42: case 0x52: case 0x62: case 0x72: case 0x92: case 0xb2: case 0xd2: case 0xf2: instrTable[buildCycle++].func = &StaticFuncWrapper; break; #endif case INCz: case INCzx: case INCa: case INCax: instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::inc_instr>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PutEffAddrDataByte>; break; case INXn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::inx_instr>; break; case INYn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::iny_instr>; break; case ISBz: case ISBzx: case ISBa: case ISBax: case ISBay: case ISBix: case ISBiy: // Also known as INS instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::ins_instr>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PutEffAddrDataByte>; break; case JSRw: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::WasteCycle>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PushHighPC>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PushLowPC>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::FetchHighAddr>; // fallthrough case JMPw: case JMPi: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::jmp_instr>; break; case LASay: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::las_instr>; break; case LAXz: case LAXzy: case LAXa: case LAXay: case LAXix: case LAXiy: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::lax_instr>; break; case LDAz: case LDAzx: case LDAa: case LDAax: case LDAay: case LDAix: case LDAiy: case LDAb: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::lda_instr>; break; case LDXz: case LDXzy: case LDXa: case LDXay: case LDXb: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::ldx_instr>; break; case LDYz: case LDYzx: case LDYa: case LDYax: case LDYb: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::ldy_instr>; break; case LSRn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::lsra_instr>; break; case LSRz: case LSRzx: case LSRa: case LSRax: instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::lsr_instr>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PutEffAddrDataByte>; break; case NOPn_: case NOPb_: case NOPz_: case NOPzx_: case NOPa: case NOPax_: // NOPb NOPz NOPzx - Also known as SKBn // NOPa NOPax - Also known as SKWn break; case LXAb: // Also known as OAL instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::oal_instr>; break; case ORAz: case ORAzx: case ORAa: case ORAax: case ORAay: case ORAix: case ORAiy: case ORAb: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::ora_instr>; break; case PHAn: instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::pha_instr>; break; case PHPn: instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PushSR>; break; case PLAn: // should read the value at current stack register. // Truly side-effect free. instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::WasteCycle>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::pla_instr>; break; case PLPn: // should read the value at current stack register. // Truly side-effect free. instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::WasteCycle>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PopSR>; break; case RLAz: case RLAzx: case RLAix: case RLAa: case RLAax: case RLAay: case RLAiy: instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::rla_instr>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PutEffAddrDataByte>; break; case ROLn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::rola_instr>; break; case ROLz: case ROLzx: case ROLa: case ROLax: instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::rol_instr>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PutEffAddrDataByte>; break; case RORn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::rora_instr>; break; case RORz: case RORzx: case RORa: case RORax: instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::ror_instr>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PutEffAddrDataByte>; break; case RRAa: case RRAax: case RRAay: case RRAz: case RRAzx: case RRAix: case RRAiy: instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::rra_instr>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PutEffAddrDataByte>; break; case RTIn: // should read the value at current stack register. // Truly side-effect free. instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::WasteCycle>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PopSR>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PopLowPC>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PopHighPC>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::rti_instr>; break; case RTSn: // should read the value at current stack register. // Truly side-effect free. instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::WasteCycle>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PopLowPC>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PopHighPC>; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::rts_instr>; break; case SAXz: case SAXzy: case SAXa: case SAXix: // Also known as AXS instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::axs_instr>; break; case SBCz: case SBCzx: case SBCa: case SBCax: case SBCay: case SBCix: case SBCiy: case SBCb_: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::sbc_instr>; break; case SBXb: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::sbx_instr>; break; case SECn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::sec_instr>; break; case SEDn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::sed_instr>; break; case SEIn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::sei_instr>; break; case SHAay: case SHAiy: // Also known as AXA instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::axa_instr>; break; case SHSay: // Also known as TAS instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::shs_instr>; break; case SHXay: // Also known as XAS instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::xas_instr>; break; case SHYax: // Also known as SAY instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::say_instr>; break; case SLOz: case SLOzx: case SLOa: case SLOax: case SLOay: case SLOix: case SLOiy: // Also known as ASO instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::aso_instr>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PutEffAddrDataByte>; break; case SREz: case SREzx: case SREa: case SREax: case SREay: case SREix: case SREiy: // Also known as LSE instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::lse_instr>; instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::PutEffAddrDataByte>; break; case STAz: case STAzx: case STAa: case STAax: case STAay: case STAix: case STAiy: instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::sta_instr>; break; case STXz: case STXzy: case STXa: instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::stx_instr>; break; case STYz: case STYzx: case STYa: instrTable[buildCycle].nosteal = true; instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::sty_instr>; break; case TAXn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::tax_instr>; break; case TAYn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::tay_instr>; break; case TSXn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::tsx_instr>; break; case TXAn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::txa_instr>; break; case TXSn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::txs_instr>; break; case TYAn: instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::tya_instr>; break; default: legalInstr = false; break; } // Missing an addressing mode or implementation makes opcode invalid. // These are normally called HLT instructions. In the hardware, the // CPU state machine locks up and will never recover. if (!(legalMode && legalInstr)) { instrTable[buildCycle++].func = &StaticFuncWrapper<&MOS6510::invalidOpcode>; } // check for IRQ triggers or fetch next opcode... instrTable[buildCycle].func = &StaticFuncWrapper<&MOS6510::interruptsAndNextOpcode>; #ifndef NDEBUG printf("Done [%u Cycles]\n", buildCycle - (i << 3)); #endif } } /** * Initialise CPU Emulation (Registers). */ void MOS6510::Initialise() { // Reset stack Register_StackPointer = 0xff; // Reset Cycle Count cycleCount = (BRKn << 3) + 6; // fetchNextOpcode if (cpu_debug) UNLIKELY { cpu_debug->instrStartPC = -1; } // Reset Status Register flags.reset(); // Set PC to some value Register_ProgramCounter = 0; // IRQs pending check irqAssertedOnPin = false; nmiFlag = false; rstFlag = false; interruptCycle = MAX; // Signals rdy = true; d1x1 = false; eventScheduler.schedule(m_nosteal, 0, EVENT_CLOCK_PHI2); } /** * Reset CPU Emulation. */ void MOS6510::reset() { // Internal Stuff Initialise(); // Set processor port to the default values cpuWrite(0, 0x2f); cpuWrite(1, 0x37); // Requires External Bits // Read from reset vector for program entry point endian_16lo8(Cycle_EffectiveAddress, cpuRead(0xfffc)); endian_16hi8(Cycle_EffectiveAddress, cpuRead(0xfffd)); Register_ProgramCounter = Cycle_EffectiveAddress; } /** * Module Credits. */ const char *MOS6510::credits() { return "MOS6510 Cycle Exact Emulation\n" "\t(C) 2000 Simon A. White\n" "\t(C) 2008-2010 Antti S. Lankila\n" "\t(C) 2011-2026 Leandro Nini\n"; } void MOS6510::debug(bool enable, FILE *out) { if (enable) { cpu_debug = MAKE_UNIQUE(CPUDebug); cpu_debug->m_fdbg = out ? out : stdout; } else { cpu_debug.reset(); } } } libsidplayfp-3.0.0/src/c64/CPU/mos6510.h0000644000175100017510000002111115175333711012756 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MOS6510_H #define MOS6510_H #include #include #include #include #include "flags.h" #include "EventCallback.h" #include "EventScheduler.h" #ifdef HAVE_CONFIG_H # include "config.h" #endif class EventContext; namespace libsidplayfp { class MOS6510; namespace MOS6510Debug { void DumpState(event_clock_t time, MOS6510 &cpu); } class CPUDataBus { public: virtual ~CPUDataBus() = default; virtual uint8_t cpuRead(uint_least16_t addr) =0; virtual void cpuWrite(uint_least16_t addr, uint8_t data) =0; }; struct CPUDebug { int_least32_t instrStartPC; uint_least16_t instrOperand; FILE *m_fdbg; bool dodump; }; /** * Cycle-exact 6502/6510 emulation core. * * Code is based on work by Simon A. White . * Original Java port by Ken Händel. Later on, it has been hacked to * improve compatibility with Lorenz suite on VICE's test suite. * * @author alankila */ class MOS6510 { friend void MOS6510Debug::DumpState(event_clock_t time, MOS6510 &cpu); public: class haltInstruction { private: const std::string m_msg; public: explicit haltInstruction(const std::string &msg) : m_msg(msg) {} std::string message() const { return m_msg; } }; private: /** * IRQ/NMI magic limit values. * Need to be larger than about 0x103 << 3, * but can't be min/max for Integer type. */ static constexpr int MAX = 65536; /// Stack page location static constexpr uint8_t SP_PAGE = 0x01; public: /// Status register interrupt bit. static constexpr int SR_INTERRUPT = 2; private: struct ProcessorCycle { void (*func)(MOS6510&); bool nosteal; ProcessorCycle() : func(nullptr), nosteal(false) {} }; private: /// Event scheduler EventScheduler &eventScheduler; /// Data bus CPUDataBus &dataBus; /// Current instruction and subcycle within instruction int cycleCount; /// When IRQ was triggered. -MAX means "during some previous instruction", MAX means "no IRQ" int interruptCycle; /// IRQ asserted on CPU bool irqAssertedOnPin; /// NMI requested? bool nmiFlag; /// RST requested? bool rstFlag; /// RDY pin state (stop CPU on read) bool rdy; /// Address Low summer carry bool adl_carry; bool d1x1; /// The RDY pin state during last throw away read. bool rdyOnThrowAwayRead; /// Status register Flags flags; // Data regarding current instruction uint_least16_t Register_ProgramCounter; uint_least16_t Cycle_EffectiveAddress; uint_least16_t Cycle_Pointer; uint8_t Cycle_Data; uint8_t Register_StackPointer; uint8_t Register_Accumulator; uint8_t Register_X; uint8_t Register_Y; /// Table of CPU opcode implementations struct ProcessorCycle instrTable[0x101 << 3]; // Debug info std::unique_ptr cpu_debug; private: void eventWithoutSteals(); void eventWithSteals(); void removeIRQ(); /// Represents an instruction subcycle that writes FastEventCallback m_nosteal; /// Represents an instruction subcycle that reads FastEventCallback m_steal; FastEventCallback clearInt; inline void Initialise(); // Declare Interrupt Routines inline void IRQLoRequest(); inline void IRQHiRequest(); inline void interruptsAndNextOpcode(); inline void calculateInterruptTriggerCycle(); // Declare Instruction Routines inline void fetchNextOpcode(); inline void throwAwayFetch(); inline void throwAwayRead(); inline void FetchDataByte(); inline void FetchLowAddr(); inline void FetchLowAddrX(); inline void FetchLowAddrY(); inline void FetchHighAddr(); inline void FetchHighAddrX(); inline void FetchHighAddrX2(); inline void FetchHighAddrY(); inline void FetchHighAddrY2(); inline void FetchLowEffAddr(); inline void FetchHighEffAddr(); inline void FetchHighEffAddrY(); inline void FetchHighEffAddrY2(); inline void FetchLowPointer(); inline void FetchLowPointerX(); inline void FetchHighPointer(); inline void FetchEffAddrDataByte(); inline void PutEffAddrDataByte(); inline void PushLowPC(); inline void PushHighPC(); inline void PushSR(); inline void PopLowPC(); inline void PopHighPC(); inline void PopSR(); inline void brkPushLowPC(); inline void WasteCycle(); inline void Push(uint8_t data); inline uint8_t Pop(); inline void compare(uint8_t data); // Delcare Instruction Operation Routines inline void adc_instr(); inline void alr_instr(); inline void anc_instr(); inline void and_instr(); inline void ane_instr(); inline void arr_instr(); inline void asl_instr(); inline void asla_instr(); inline void aso_instr(); inline void axa_instr(); inline void axs_instr(); inline void bcc_instr(); inline void bcs_instr(); inline void beq_instr(); inline void bit_instr(); inline void bmi_instr(); inline void bne_instr(); inline void branch_instr(bool condition); inline void fix_branch(); inline void bpl_instr(); inline void bvc_instr(); inline void bvs_instr(); inline void clc_instr(); inline void cld_instr(); inline void cli_instr(); inline void clv_instr(); inline void cmp_instr(); inline void cpx_instr(); inline void cpy_instr(); inline void dcm_instr(); inline void dec_instr(); inline void dex_instr(); inline void dey_instr(); inline void eor_instr(); inline void inc_instr(); inline void ins_instr(); inline void inx_instr(); inline void iny_instr(); inline void jmp_instr(); inline void las_instr(); inline void lax_instr(); inline void lda_instr(); inline void ldx_instr(); inline void ldy_instr(); inline void lse_instr(); inline void lsr_instr(); inline void lsra_instr(); inline void oal_instr(); inline void ora_instr(); inline void pha_instr(); inline void pla_instr(); inline void rla_instr(); inline void rol_instr(); inline void rola_instr(); inline void ror_instr(); inline void rora_instr(); inline void rra_instr(); inline void rti_instr(); inline void rts_instr(); inline void sbx_instr(); inline void say_instr(); inline void sbc_instr(); inline void sec_instr(); inline void sed_instr(); inline void sei_instr(); inline void shs_instr(); inline void sta_instr(); inline void stx_instr(); inline void sty_instr(); inline void tax_instr(); inline void tay_instr(); inline void tsx_instr(); inline void txa_instr(); inline void txs_instr(); inline void tya_instr(); inline void xas_instr(); inline void sh_instr(); /** * @throws haltInstruction */ void invalidOpcode(); // Declare Arithmetic Operations inline void doADC(); inline void doSBC(); inline bool checkInterrupts() const { return rstFlag || nmiFlag || (irqAssertedOnPin && !flags.getI()); } inline void buildInstructionTable(); public: MOS6510(EventScheduler &scheduler, CPUDataBus& bus); inline uint8_t cpuRead(uint_least16_t addr) { return dataBus.cpuRead(addr); } inline void cpuWrite(uint_least16_t addr, uint8_t data) { dataBus.cpuWrite(addr, data); } void reset(); static const char *credits(); void debug(bool enable, FILE *out); void setRDY(bool newRDY); // Non-standard functions void triggerRST(); void triggerNMI(); void triggerIRQ(); void clearIRQ(); }; } #endif // MOS6510_H libsidplayfp-3.0.0/src/c64/CPU/flags.h0000644000175100017510000000476715175333711012762 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2019 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef FLAGS_H #define FLAGS_H #include namespace libsidplayfp { /** * Processor Status Register */ class Flags { private: bool C; ///< Carry bool Z; ///< Zero bool I; ///< Interrupt disabled bool D; ///< Decimal bool V; ///< Overflow bool N; ///< Negative public: inline void reset() { C = Z = I = D = V = N = false; } /** * Set N and Z flag values. * * @param value to set flags from */ inline void setNZ(uint8_t value) { Z = value == 0; N = value & 0x80; } /** * Get status register value. */ inline uint8_t get() const { uint8_t sr = 0; if (C) sr |= 0x01; if (Z) sr |= 0x02; if (I) sr |= 0x04; if (D) sr |= 0x08; if (V) sr |= 0x40; if (N) sr |= 0x80; return sr; } /** * Set status register value. */ inline void set(uint8_t sr) { C = sr & 0x01; Z = sr & 0x02; I = sr & 0x04; D = sr & 0x08; V = sr & 0x40; N = sr & 0x80; } inline bool getN() const { return N; } inline bool getC() const { return C; } inline bool getD() const { return D; } inline bool getZ() const { return Z; } inline bool getV() const { return V; } inline bool getI() const { return I; } inline void setN(bool f) { N = f; } inline void setC(bool f) { C = f; } inline void setD(bool f) { D = f; } inline void setZ(bool f) { Z = f; } inline void setV(bool f) { V = f; } inline void setI(bool f) { I = f; } }; } #endif libsidplayfp-3.0.0/src/c64/CPU/mos6510debug.h0000644000175100017510000000225715175333711013777 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2015 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MOS6510DEBUG_H #define MOS6510DEBUG_H #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "Event.h" namespace libsidplayfp { class MOS6510; namespace MOS6510Debug { void DumpState(event_clock_t time, MOS6510 &cpu); } } #endif // MOS6510DEBUG_H libsidplayfp-3.0.0/src/c64/mmu.cpp0000644000175100017510000000603315175333711012354 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2021 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "mmu.h" #include "Banks/Bank.h" #include "Banks/IOBank.h" namespace libsidplayfp { // Use static type to allow compiler to optimize virtual function call template uint8_t readBank(MMU &self, uint_least16_t addr) { return (self.*Bank).peek(addr); } uint8_t readIO(MMU &self, uint_least16_t addr) { return self.ioBank->peek(addr); } class Bank; MMU::MMU(EventScheduler &scheduler, IOBank* ioBank) : eventScheduler(scheduler), ioBank(ioBank), zeroRAMBank(*this, ramBank) { cpuReadMap[0] = &readBank; cpuWriteMap[0] = &zeroRAMBank; for (int i = 1; i < 16; i++) { cpuReadMap[i] = &readBank; cpuWriteMap[i] = &ramBank; } } void MMU::setCpuPort(uint8_t state) { loram = (state & 1) != 0; hiram = (state & 2) != 0; charen = (state & 4) != 0; updateMappingPHI2(); } void MMU::updateMappingPHI2() { ReadFunc readRAM = &readBank; cpuReadMap[0xe] = cpuReadMap[0xf] = hiram ? &readBank : readRAM; cpuReadMap[0xa] = cpuReadMap[0xb] = (loram && hiram) ? &readBank : readRAM; if (charen && (loram || hiram)) { cpuReadMap[0xd] = &readIO; cpuWriteMap[0xd] = ioBank; } else { cpuReadMap[0xd] = (!charen && (loram || hiram)) ? &readBank : readRAM; cpuWriteMap[0xd] = &ramBank; } } void MMU::reset() { ramBank.reset(); zeroRAMBank.reset(); // Reset the ROMs to undo the hacks applied kernalRomBank.reset(); basicRomBank.reset(); loram = false; hiram = false; charen = false; updateMappingPHI2(); } // LCG unsigned int random(unsigned int val) { return val * 1664525 + 1013904223; } /* * This should actually return last byte read from VIC * but since the VIC emulation currently does not fetch * any value from memory we return a pseudo random value. */ uint8_t MMU::getLastReadByte() const { seed = random(seed); return seed; } } libsidplayfp-3.0.0/src/c64/c64vic.h0000644000175100017510000000355215175333711012324 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2019 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef C64VIC_H #define C64VIC_H // The VIC emulation is very generic and here we need to effectively // wire it into the computer (like adding a chip to a PCB). #include "Banks/Bank.h" #include "c64/c64env.h" #include "sidendian.h" #include "VIC_II/mos656x.h" #include "sidcxx11.h" namespace libsidplayfp { /** * VIC-II * * Located at $D000-$D3FF */ class c64vic final : public MOS656X, public Bank { private: c64env &m_env; protected: void interrupt(bool state) override { m_env.interruptIRQ(state); } void setBA(bool state) override { m_env.setBA(state); } public: explicit c64vic(c64env &env) : MOS656X(env.scheduler()), m_env(env) {} void poke(uint_least16_t address, uint8_t value) override { write(endian_16lo8(address), value); } uint8_t peek(uint_least16_t address) override { return read(endian_16lo8(address)); } }; } #endif // C64VIC_H libsidplayfp-3.0.0/src/c64/c64.cpp0000644000175100017510000001246215175333711012155 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2023 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "c64.h" #include "c64/CIA/mos652x.h" #include "c64/VIC_II/mos656x.h" namespace libsidplayfp { using model_data_t = struct { double colorBurst; ///< Colorburst frequency in Herz double divider; ///< Clock frequency divider double powerFreq; ///< Power line frequency in Herz MOS656X::model_t vicModel; ///< Video chip model }; using cia_model_data_t = struct { MOS652X::model_t ciaModel; ///< CIA chip model }; /* * Color burst frequencies: * * NTSC - 3.579545455 MHz = 315/88 MHz * PAL-B - 4.43361875 MHz = 283.75 * 15625 Hz + 25 Hz. * PAL-M - 3.57561149 MHz * PAL-N - 3.58205625 MHz */ const model_data_t modelData[] = { {4433618.75, 18., 50., MOS656X::model_t::MOS6569}, // PAL-B {3579545.455, 14., 60., MOS656X::model_t::MOS6567R8}, // NTSC-M {3579545.455, 14., 60., MOS656X::model_t::MOS6567R56A}, // Old NTSC-M {3582056.25, 14., 50., MOS656X::model_t::MOS6572}, // PAL-N {3575611.49, 14., 50., MOS656X::model_t::MOS6573}, // PAL-M }; const cia_model_data_t ciaModelData[] = { {MOS652X::model_t::MOS6526}, // Old {MOS652X::model_t::MOS8521}, // New {MOS652X::model_t::MOS6526W4485}, // Old week 4485 }; double c64::getCpuFreq(model_t model) { // The crystal clock that drives the VIC II chip is four times // the color burst frequency const double crystalFreq = modelData[model].colorBurst * 4.; // The VIC II produces the two-phase system clock // by running the input clock through a divider return crystalFreq / modelData[model].divider; } c64::c64() : c64env(eventScheduler), cpuFrequency(getCpuFreq(PAL_B)), cia1(*this), cia2(*this), vic(*this), disconnectedBusBank(mmu), mmu(eventScheduler, &ioBank), cpubus(mmu), cpu(eventScheduler, cpubus) { resetIoBank(); } void c64::resetIoBank() { ioBank.setBank(0x0, &vic); ioBank.setBank(0x1, &vic); ioBank.setBank(0x2, &vic); ioBank.setBank(0x3, &vic); ioBank.setBank(0x4, &sidBank); ioBank.setBank(0x5, &sidBank); ioBank.setBank(0x6, &sidBank); ioBank.setBank(0x7, &sidBank); ioBank.setBank(0x8, &colorRAMBank); ioBank.setBank(0x9, &colorRAMBank); ioBank.setBank(0xa, &colorRAMBank); ioBank.setBank(0xb, &colorRAMBank); ioBank.setBank(0xc, &cia1); ioBank.setBank(0xd, &cia2); ioBank.setBank(0xe, &disconnectedBusBank); ioBank.setBank(0xf, &disconnectedBusBank); } void c64::reset() { eventScheduler.reset(); //cpu.reset(); cia1.reset(); cia2.reset(); vic.reset(); sidBank.reset(); colorRAMBank.reset(); mmu.reset(); for (auto extraSidBank: extraSidBanks) extraSidBank.second->reset(); irqCount = 0; oldBAState = true; } void c64::setModel(model_t model) { cpuFrequency = getCpuFreq(model); vic.chip(modelData[model].vicModel); const unsigned int rate = cpuFrequency / modelData[model].powerFreq; cia1.setDayOfTimeRate(rate); cia2.setDayOfTimeRate(rate); } void c64::setCiaModel(cia_model_t model) { cia1.setModel(ciaModelData[model].ciaModel); cia2.setModel(ciaModelData[model].ciaModel); } void c64::setBaseSid(c64sid *s) { sidBank.setSID(s); } bool c64::addExtraSid(c64sid *s, int address) { // Check for valid address in the IO area range ($dxxx) if ((address & 0xf000) != 0xd000) UNLIKELY return false; const int idx = (address >> 8) & 0xf; // Only allow second SID chip in SID area ($d400-$d7ff) // or IO Area ($de00-$dfff) if ((idx < 0x4) || ((idx > 0x7) && (idx < 0xe))) UNLIKELY return false; // Add new SID bank sidBankMap_t::iterator it = extraSidBanks.find(idx); if (it != extraSidBanks.end()) { ExtraSidBank *extraSidBank = it->second; extraSidBank->addSID(s, address); } else { ExtraSidBank *extraSidBank = extraSidBanks.insert(it, sidBankMap_t::value_type(idx, new ExtraSidBank()))->second; extraSidBank->resetSIDMapper(ioBank.getBank(idx)); ioBank.setBank(idx, extraSidBank); extraSidBank->addSID(s, address); } return true; } void c64::deleteSids(sidBankMap_t &extraSidBanks) { for (auto sidBank: extraSidBanks) delete sidBank.second; extraSidBanks.clear(); } c64::~c64() { deleteSids(extraSidBanks); } void c64::clearSids() { sidBank.setSID(nullptr); resetIoBank(); deleteSids(extraSidBanks); } } libsidplayfp-3.0.0/src/c64/VIC_II/0000755000175100017510000000000015175333725012137 5libsidplayfp-3.0.0/src/c64/VIC_II/lightpen.h0000644000175100017510000000755615175333711014052 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2021 Leandro Nini * Copyright 2009-2014 VICE Project * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef LIGHTPEN_H #define LIGHTPEN_H namespace libsidplayfp { /** * Lightpen emulation. * Does not reflect model differences. */ class Lightpen { private: /// Last VIC raster line unsigned int lastLine; /// VIC cycles per line unsigned int cyclesPerLine; /// X coordinate unsigned int lpx; /// Y coordinate unsigned int lpy; /// Has light pen IRQ been triggered in this frame already? bool isTriggered; private: /** * Transform line cycle into x coordinate. * * @param lineCycle * @return x position divided by two */ uint8_t getXpos(unsigned int lineCycle) const { if (lineCycle < 13) lineCycle += cyclesPerLine; lineCycle -= 13; // On NTSC the xpos is not incremented at lineCycle 61 if ((cyclesPerLine == 65) && (lineCycle > (61 - 13))) { lineCycle--; } return lineCycle << 2; } public: /** * Set VIC screen size. * * @param height number of raster lines * @param width number of cycles per line */ void setScreenSize(unsigned int height, unsigned int width) { lastLine = height - 1; cyclesPerLine = width; } /** * Reset the lightpen. */ void reset() { lpx = 0; lpy = 0; isTriggered = false; } /** * Return the low byte of x coordinate. */ uint8_t getX() const { return lpx; } /** * Return the low byte of y coordinate. */ uint8_t getY() const { return lpy; } /** * Retrigger lightpen on vertical blank. * * @return true if an IRQ should be triggered */ bool retrigger() { if (isTriggered) return false; isTriggered = true; switch (cyclesPerLine) { case 63: default: lpx = 0xd1; break; case 65: lpx = 0xd5; break; } lpy = 0; return true; } /** * Trigger lightpen from CIA. * * @param lineCycle current line cycle * @param rasterY current y raster position * @return true if an IRQ should be triggered */ bool trigger(unsigned int lineCycle, unsigned int rasterY) { if (isTriggered) return false; isTriggered = true; // don't latch on the last line, except on the first cycle if ((rasterY == lastLine) && (lineCycle > 0)) { return false; } // Latch current coordinates lpx = getXpos(lineCycle) + 2; // + 1 for MOS 85XX lpy = rasterY; // On 6569R1 and 6567R56A the interrupt is triggered only // when the line is low on the first cycle of the frame. return true; // false for old chip revisions } /** * Untrigger lightpen from CIA. */ void untrigger() { isTriggered = false; } }; } #endif libsidplayfp-3.0.0/src/c64/VIC_II/mos656x.h0000644000175100017510000002035115175333711013453 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2020 Leandro Nini * Copyright 2009-2014 VICE Project * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MOS656X_H #define MOS656X_H #include #include "lightpen.h" #include "sprites.h" #include "Event.h" #include "EventCallback.h" #include "EventScheduler.h" #include "sidcxx11.h" namespace libsidplayfp { /** * MOS 6567/6569/6572/6573 emulation. * Not cycle exact but good enough for SID playback. */ class MOS656X : private Event { public: enum class model_t { MOS6567R56A = 0 ///< OLD NTSC CHIP ,MOS6567R8 ///< NTSC-M ,MOS6569 ///< PAL-B ,MOS6572 ///< PAL-N ,MOS6573 ///< PAL-M }; private: using ClockFunc = event_clock_t (MOS656X::*)(); using model_data_t = struct { unsigned int rasterLines; unsigned int cyclesPerLine; ClockFunc clock; }; private: static const model_data_t modelData[]; /// raster IRQ flag static constexpr int IRQ_RASTER = 1 << 0; /// Light-Pen IRQ flag static constexpr int IRQ_LIGHTPEN = 1 << 3; /// First line when we check for bad lines static constexpr unsigned int FIRST_DMA_LINE = 0x30; /// Last line when we check for bad lines static constexpr unsigned int LAST_DMA_LINE = 0xf7; private: /// Current model clock function. ClockFunc clock; /// Current raster clock. event_clock_t rasterClk; /// System's event scheduler. EventScheduler &eventScheduler; /// Number of cycles per line. unsigned int cyclesPerLine; /// Number of raster lines. unsigned int maxRasters; /// Current visible line unsigned int lineCycle; /// current raster line unsigned int rasterY; /// vertical scrolling value unsigned int yscroll; /// are bad lines enabled for this frame? bool areBadLinesEnabled; /// is the current line a bad line bool isBadLine; /// Is rasterYIRQ condition true? bool rasterYIRQCondition; /// Set when new frame starts. bool vblanking; /// Is CIA asserting lightpen? bool lpAsserted; /// internal IRQ flags uint8_t irqFlags; /// masks for the IRQ flags uint8_t irqMask; /// memory for chip registers uint8_t regs[0x40] = {0}; /// Light pen Lightpen lp; /// the 8 sprites data Sprites sprites; EventCallback badLineStateChangeEvent; EventCallback rasterYIRQEdgeDetectorEvent; EventCallback lightpenTriggerEvent; private: event_clock_t clockPAL(); event_clock_t clockNTSC(); event_clock_t clockOldNTSC(); /** * Signal CPU interrupt if requested by VIC. */ void handleIrqState(); /** * AEC state was updated. */ void badLineStateChange() { setBA(!isBadLine); } /** * RasterY IRQ edge detector. */ void rasterYIRQEdgeDetector() { const bool oldRasterYIRQCondition = rasterYIRQCondition; rasterYIRQCondition = rasterY == readRasterLineIRQ(); if (!oldRasterYIRQCondition && rasterYIRQCondition) activateIRQFlag(IRQ_RASTER); } void lightpenTrigger() { // Synchronise simulation sync(); if (lp.trigger(lineCycle, rasterY)) { activateIRQFlag(IRQ_LIGHTPEN); } } /** * Set an IRQ flag and trigger an IRQ if the corresponding IRQ mask is set. * The IRQ only gets activated, i.e. flag 0x80 gets set, if it was not active before. */ void activateIRQFlag(int flag) { irqFlags |= flag; handleIrqState(); } /** * Read the value of the raster line IRQ * * @return raster line when to trigger an IRQ */ inline unsigned int readRasterLineIRQ() const { return regs[0x12] + ((regs[0x11] & 0x80) << 1); } /** * Read the DEN flag which tells whether the display is enabled * * @return true if DEN is set, otherwise false */ inline bool readDEN() const { return (regs[0x11] & 0x10) != 0; } inline bool evaluateIsBadLine() const { return areBadLinesEnabled && rasterY >= FIRST_DMA_LINE && rasterY <= LAST_DMA_LINE && (rasterY & 7) == yscroll; } /** * Get previous value of Y raster */ inline unsigned int oldRasterY() const { return (rasterY > 0 ? rasterY : maxRasters) - 1; } inline void sync() { eventScheduler.cancel(*this); event(); } /** * Check for vertical blanking. */ inline void checkVblank() { // IRQ occurred (xraster != 0) if (rasterY == (maxRasters - 1)) { vblanking = true; } // Check DEN bit on first cycle of the line following the first DMA line if (rasterY == FIRST_DMA_LINE && !areBadLinesEnabled && readDEN()) { areBadLinesEnabled = true; } // Disallow bad lines after the last possible one has passed if (rasterY == LAST_DMA_LINE) { areBadLinesEnabled = false; } isBadLine = false; if (!vblanking) { rasterY++; rasterYIRQEdgeDetector(); if ((rasterY == FIRST_DMA_LINE) && !areBadLinesEnabled) areBadLinesEnabled = readDEN(); } if (evaluateIsBadLine()) isBadLine = true; } /** * Vertical blank (line 0). */ inline void vblank() { if (vblanking) { vblanking = false; rasterY = 0; rasterYIRQEdgeDetector(); lp.untrigger(); if (lpAsserted && lp.retrigger()) { activateIRQFlag(IRQ_LIGHTPEN); } } } /** * Start DMA for sprite n. */ template inline void startDma() { if (sprites.isDma(0x01 << n)) setBA(false); } /** * End DMA for sprite n. */ template inline void endDma() { if (!sprites.isDma(0x06 << n)) setBA(true); } /** * Start bad line. */ inline void startBadline() { if (isBadLine) setBA(false); } protected: MOS656X(EventScheduler &scheduler); ~MOS656X() = default; // Environment Interface virtual void interrupt(bool state) = 0; virtual void setBA(bool state) = 0; /** * Read VIC register. * * @param addr * Register to read. */ uint8_t read(uint_least8_t addr); /** * Write to VIC register. * * @param addr * Register to write to. * @param data * Data byte to write. */ void write(uint_least8_t addr, uint8_t data); public: void event() override; /** * Set chip model. */ void chip(model_t model); /** * Trigger the lightpen. Sets the lightpen usage flag. */ void triggerLightpen(); /** * Clears the lightpen usage flag. */ void clearLightpen(); /** * Reset VIC II. */ void reset(); static const char *credits(); }; // Template specializations /** * Start DMA for sprite 0. */ template<> inline void MOS656X::startDma<0>() { setBA(!sprites.isDma(0x01)); } /** * End DMA for sprite 7. */ template<> inline void MOS656X::endDma<7>() { setBA(true); } } #endif // MOS656X_H libsidplayfp-3.0.0/src/c64/VIC_II/mos656x.cpp0000644000175100017510000003404415175333711014012 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2021 Leandro Nini * Copyright 2009-2014 VICE Project * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // References below are from: // The MOS 6567/6569 video controller (VIC-II) // and its application in the Commodore 64 // http://www.uni-mainz.de/~bauec002/VIC-Article.gz // // MOS 6572 info taken from http://solidstate.com.ar/wp/?p=200 // MOS 6573 info taken from http://csdb.dk/forums/?roomid=11&topicid=123713 #include "mos656x.h" #include #include #include #ifdef __cpp_lib_to_underlying # include #else # include #endif #include "sidendian.h" namespace libsidplayfp { /// Cycle # at which the VIC takes the bus in a bad line (BA goes low). constexpr unsigned int VICII_FETCH_CYCLE = 11; constexpr unsigned int VICII_SCREEN_TEXTCOLS = 40; const MOS656X::model_data_t MOS656X::modelData[] = { {262, 64, &MOS656X::clockOldNTSC}, // Old NTSC (MOS6567R56A) {263, 65, &MOS656X::clockNTSC}, // NTSC-M (MOS6567R8) {312, 63, &MOS656X::clockPAL}, // PAL-B (MOS6569R1, MOS6569R3) {312, 65, &MOS656X::clockNTSC}, // PAL-N (MOS6572) {263, 65, &MOS656X::clockNTSC}, // PAL-M (MOS6573) }; const char *MOS656X::credits() { return "MOS6567/6569/6572/6573 (VIC II) Emulation:\n" "\tCopyright (C) 2001 Simon White\n" "\tCopyright (C) 2007-2010 Antti Lankila\n" "\tCopyright (C) 2009-2014 VICE Project\n" "\tCopyright (C) 2011-2021 Leandro Nini\n"; } MOS656X::MOS656X(EventScheduler &scheduler) : Event("VIC Raster"), eventScheduler(scheduler), sprites(regs), badLineStateChangeEvent("Update AEC signal", *this, &MOS656X::badLineStateChange), rasterYIRQEdgeDetectorEvent("RasterY changed", *this, &MOS656X::rasterYIRQEdgeDetector), lightpenTriggerEvent("Trigger lightpen", *this, &MOS656X::lightpenTrigger) { chip(model_t::MOS6569); } void MOS656X::reset() { irqFlags = 0; irqMask = 0; yscroll = 0; rasterY = maxRasters - 1; lineCycle = 0; areBadLinesEnabled = false; isBadLine = false; rasterYIRQCondition = false; rasterClk = 0; vblanking = false; lpAsserted = false; std::fill(std::begin(regs), std::end(regs), 0); lp.reset(); sprites.reset(); eventScheduler.cancel(*this); eventScheduler.schedule(*this, 0, EVENT_CLOCK_PHI1); } void MOS656X::chip(model_t model) { #ifdef __cpp_lib_to_underlying const auto model_idx = std::to_underlying(model); #elifdef HAVE_CXX14 const auto model_idx = static_cast>(model); #else const auto model_idx = static_cast::type>(model); #endif maxRasters = modelData[model_idx].rasterLines; cyclesPerLine = modelData[model_idx].cyclesPerLine; clock = modelData[model_idx].clock; lp.setScreenSize(maxRasters, cyclesPerLine); reset(); } uint8_t MOS656X::read(uint_least8_t addr) { addr &= 0x3f; // Sync up timers sync(); switch (addr) { case 0x11: // Control register 1 return (regs[addr] & 0x7f) | ((rasterY & 0x100) >> 1); case 0x12: // Raster counter return rasterY & 0xff; case 0x13: return lp.getX(); case 0x14: return lp.getY(); case 0x19: // Interrupt Pending Register return irqFlags | 0x70; case 0x1a: // Interrupt Mask Register return irqMask | 0xf0; default: // for addresses < $20 read from register directly if (addr < 0x20) return regs[addr]; // for addresses < $2f set bits of high nibble to 1 if (addr < 0x2f) return regs[addr] | 0xf0; // for addresses >= $2f return $ff return 0xff; } } void MOS656X::write(uint_least8_t addr, uint8_t data) { addr &= 0x3f; regs[addr] = data; // Sync up timers sync(); switch (addr) { case 0x11: // Control register 1 { const unsigned int oldYscroll = yscroll; yscroll = data & 0x7; // This is the funniest part... handle bad line tricks. const bool wasBadLinesEnabled = areBadLinesEnabled; if ((rasterY == FIRST_DMA_LINE) && (lineCycle == 0)) { areBadLinesEnabled = readDEN(); } if ((oldRasterY() == FIRST_DMA_LINE) && readDEN()) { areBadLinesEnabled = true; } if (((oldYscroll != yscroll) || (areBadLinesEnabled != wasBadLinesEnabled)) && (rasterY >= FIRST_DMA_LINE) && (rasterY <= LAST_DMA_LINE)) { // Check whether bad line state has changed. const bool wasBadLine = (wasBadLinesEnabled && (oldYscroll == (rasterY & 7))); const bool nowBadLine = (areBadLinesEnabled && (yscroll == (rasterY & 7))); if (nowBadLine != wasBadLine) { const bool oldBadLine = isBadLine; if (wasBadLine) { if (lineCycle < VICII_FETCH_CYCLE) { isBadLine = false; } } else { // Bad line may be generated during fetch interval // (VICII_FETCH_CYCLE <= lineCycle < VICII_FETCH_CYCLE + VICII_SCREEN_TEXTCOLS + 3) // or outside the fetch interval but before raster ycounter is incremented // (lineCycle <= VICII_FETCH_CYCLE + VICII_SCREEN_TEXTCOLS + 6) if (lineCycle <= VICII_FETCH_CYCLE + VICII_SCREEN_TEXTCOLS + 6) { isBadLine = true; } } if (isBadLine != oldBadLine) eventScheduler.schedule(badLineStateChangeEvent, 0, EVENT_CLOCK_PHI1); } } } // fall-through case 0x12: // Raster counter // check raster Y irq condition changes at the next PHI1 eventScheduler.schedule(rasterYIRQEdgeDetectorEvent, 0, EVENT_CLOCK_PHI1); break; case 0x17: sprites.lineCrunch(data, lineCycle); break; case 0x19: // VIC Interrupt Flag Register irqFlags &= (~data & 0x0f) | 0x80; handleIrqState(); break; case 0x1a: // IRQ Mask Register irqMask = data & 0x0f; handleIrqState(); break; } } void MOS656X::handleIrqState() { // signal an IRQ unless we already signaled it if ((irqFlags & irqMask & 0x0f) != 0) { if ((irqFlags & 0x80) == 0) { interrupt(true); irqFlags |= 0x80; } } else { if ((irqFlags & 0x80) != 0) { interrupt(false); irqFlags &= 0x7f; } } } void MOS656X::event() { const event_clock_t cycles = eventScheduler.getTime(eventScheduler.phase()) - rasterClk; event_clock_t delay; if (cycles) { // Update x raster rasterClk += cycles; lineCycle += cycles; lineCycle %= cyclesPerLine; delay = (this->*clock)(); } else delay = 1; eventScheduler.schedule(*this, delay - eventScheduler.phase(), EVENT_CLOCK_PHI1); } event_clock_t MOS656X::clockPAL() { event_clock_t delay = 1; switch (lineCycle) { case 0: checkVblank(); endDma<2>(); break; case 1: vblank(); startDma<5>(); // No sprites before next compulsory cycle if (!sprites.isDma(0xf8)) delay = 10; break; case 2: endDma<3>(); break; case 3: startDma<6>(); break; case 4: endDma<4>(); break; case 5: startDma<7>(); break; case 6: endDma<5>(); delay = sprites.isDma(0xc0) ? 2 : 5; break; case 7: break; case 8: endDma<6>(); delay = 2; break; case 9: break; case 10: endDma<7>(); break; case 11: startBadline(); delay = 3; break; case 12: delay = 2; break; case 13: break; case 14: sprites.updateMc(); break; case 15: sprites.updateMcBase(); delay = 39; break; case 54: sprites.checkDma(rasterY, regs); startDma<0>(); break; case 55: sprites.checkDma(rasterY, regs); // Phi1 sprites.checkExp(); // Phi2 startDma<0>(); break; case 56: startDma<1>(); break; case 57: sprites.checkDisplay(); // No sprites before next compulsory cycle if (!sprites.isDma(0x1f)) delay = 6; break; case 58: startDma<2>(); break; case 59: endDma<0>(); break; case 60: startDma<3>(); break; case 61: endDma<1>(); break; case 62: startDma<4>(); break; default: delay = 54 - lineCycle; } return delay; } event_clock_t MOS656X::clockNTSC() { event_clock_t delay = 1; switch (lineCycle) { case 0: checkVblank(); startDma<5>(); break; case 1: vblank(); endDma<3>(); // No sprites before next compulsory cycle if (!sprites.isDma(0xf0)) delay = 10; break; case 2: startDma<6>(); break; case 3: endDma<4>(); break; case 4: startDma<7>(); break; case 5: endDma<5>(); delay = sprites.isDma(0xc0) ? 2 : 6; break; case 6: break; case 7: endDma<6>(); delay = 2; break; case 8: break; case 9: endDma<7>(); delay = 2; break; case 10: break; case 11: startBadline(); delay = 3; break; case 12: delay = 2; break; case 13: break; case 14: sprites.updateMc(); break; case 15: sprites.updateMcBase(); delay = 39; break; case 54: setBA(true); break; case 55: sprites.checkDma(rasterY, regs); // Phi1 sprites.checkExp(); // Phi2 startDma<0>(); break; case 56: sprites.checkDma(rasterY, regs); startDma<0>(); break; case 57: startDma<1>(); break; case 58: sprites.checkDisplay(); // No sprites before next compulsory cycle if (!sprites.isDma(0x1f)) delay = 7; break; case 59: startDma<2>(); break; case 60: endDma<0>(); break; case 61: startDma<3>(); break; case 62: endDma<1>(); break; case 63: startDma<4>(); break; case 64: endDma<2>(); break; default: delay = 54 - lineCycle; } return delay; } event_clock_t MOS656X::clockOldNTSC() { event_clock_t delay = 1; switch (lineCycle) { case 0: checkVblank(); endDma<2>(); break; case 1: vblank(); startDma<5>(); // No sprites before next compulsory cycle if (!sprites.isDma(0xf8)) delay = 10; break; case 2: endDma<3>(); break; case 3: startDma<6>(); break; case 4: endDma<4>(); break; case 5: startDma<7>(); break; case 6: endDma<5>(); delay = sprites.isDma(0xc0) ? 2 : 5; break; case 7: break; case 8: endDma<6>(); delay = 2; break; case 9: break; case 10: endDma<7>(); break; case 11: startBadline(); delay = 3; break; case 12: delay = 2; break; case 13: break; case 14: sprites.updateMc(); break; case 15: sprites.updateMcBase(); delay = 39; break; case 54: setBA(true); break; case 55: sprites.checkDma(rasterY, regs); // Phi1 sprites.checkExp(); // Phi2 startDma<0>(); break; case 56: sprites.checkDma(rasterY, regs); startDma<0>(); break; case 57: sprites.checkDisplay(); startDma<1>(); // No sprites before next compulsory cycle delay = sprites.isDma(0x1f) ? 2 : 7; break; case 58: break; case 59: startDma<2>(); break; case 60: endDma<0>(); break; case 61: startDma<3>(); break; case 62: endDma<1>(); break; case 63: startDma<4>(); break; default: delay = 54 - lineCycle; } return delay; } void MOS656X::triggerLightpen() { lpAsserted = true; eventScheduler.schedule(lightpenTriggerEvent, 1); } void MOS656X::clearLightpen() { lpAsserted = false; } } libsidplayfp-3.0.0/src/c64/VIC_II/sprites.h0000644000175100017510000001014415175333711013714 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2014 Leandro Nini * Copyright 2009-2014 VICE Project * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SPRITES_H #define SPRITES_H #include #include #include namespace libsidplayfp { /** * Sprites handling. */ class Sprites { private: static constexpr unsigned int SPRITES = 8; const uint8_t &enable, &y_expansion; uint8_t exp_flop; uint8_t dma; uint8_t mc_base[SPRITES]; uint8_t mc[SPRITES]; public: explicit Sprites(uint8_t regs[0x40]) : enable(regs[0x15]), y_expansion(regs[0x17]) {} void reset() { exp_flop = 0xff; dma = 0; std::fill(std::begin(mc_base), std::end(mc_base), 0); std::fill(std::begin(mc), std::end(mc), 0); } /** * Update mc values in one pass * after the dma has been processed */ void updateMc() { uint8_t mask = 1; for (unsigned int i = 0; i < SPRITES; i++, mask <<= 1) { if (dma & mask) mc[i] = (mc[i] + 3) & 0x3f; } } /** * Update mc base value. */ void updateMcBase() { uint8_t mask = 1; for (unsigned int i = 0; i < SPRITES; i++, mask <<= 1) { if (exp_flop & mask) { mc_base[i] = mc[i]; if (mc_base[i] == 0x3f) dma &= ~mask; } } } /** * Calculate sprite expansion. */ void checkExp() { exp_flop ^= dma & y_expansion; } /** * Check if sprite is displayed. */ void checkDisplay() { for (unsigned int i = 0; i < SPRITES; i++) { mc[i] = mc_base[i]; } } /** * Calculate sprite DMA. * * @rasterY y raster position * @regs the VIC registers */ void checkDma(unsigned int rasterY, const uint8_t regs[0x40]) { const uint8_t y = rasterY & 0xff; uint8_t mask = 1; for (unsigned int i = 0; i < SPRITES; i++, mask <<= 1) { if ((enable & mask) && (y == regs[(i << 1) + 1]) && !(dma & mask)) { dma |= mask; mc_base[i] = 0; exp_flop |= mask; } } } /** * Calculate line crunch. * * @param data the data written to the register * @param lineCycle current line cycle */ void lineCrunch(uint8_t data, unsigned int lineCycle) { uint8_t mask = 1; for (unsigned int i = 0; i < SPRITES; i++, mask <<= 1) { if (!(data & mask) && !(exp_flop & mask)) { // sprite crunch if (lineCycle == 14) { const uint8_t mc_i = mc[i]; const uint8_t mcBase_i = mc_base[i]; mc[i] = (0x2a & (mcBase_i & mc_i)) | (0x15 & (mcBase_i | mc_i)); // mcbase will be set from mc on the following clock call } exp_flop |= mask; } } } /** * Check if dma is active for sprites. * * @param val bitmask for selected sprites */ inline bool isDma(unsigned int val) const { return dma & val; } }; } #endif libsidplayfp-3.0.0/src/c64/c64cpu.h0000644000175100017510000000622615175333711012333 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2012-2026 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef C64CPU_H #define C64CPU_H #ifdef HAVE_CONFIG_H # include "config.h" #endif #include "c64/mmu.h" #include "CPU/mos6510.h" #ifdef VICE_TESTSUITE # include # include #endif //#define PRINTSCREENCODES #include "sidcxx11.h" namespace libsidplayfp { #ifdef PRINTSCREENCODES /** * Screen codes conversion table (0x01 = no output) */ static const char CHRtab[128] = { 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f, 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x01,0x01,0x01,0x01, 0x20,0x21,0x01,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f, 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, 0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f, 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x5b,0x24,0x5d,0x20,0x20, // alternative: CHR$(92=0x5c) => ISO Latin-1(0xa3) 0x2d,0x23,0x7c,0x2d,0x2d,0x2d,0x2d,0x7c,0x7c,0x5c,0x5c,0x2f,0x5c,0x5c,0x2f,0x2f, 0x5c,0x23,0x5f,0x23,0x7c,0x2f,0x58,0x4f,0x23,0x7c,0x23,0x2b,0x7c,0x7c,0x26,0x5c }; #endif class c64cpubus final : public CPUDataBus { private: MMU &m_mmu; protected: uint8_t cpuRead(uint_least16_t addr) override { return m_mmu.cpuRead(addr); } void cpuWrite(uint_least16_t addr, uint8_t data) override { #ifdef VICE_TESTSUITE # ifdef PRINTSCREENCODES if (addr >= 0x0400 && addr <= 0x07ff) { const char *fg = "[0;94"; const char *bg = ";44"; uint8_t chr = data; if (chr & 0x80) { chr >>= 1; fg = "[0;34"; bg = ";104"; } std::cout << '\x1b' << fg << bg << 'm'; std::cout << CHRtab[chr]; } # endif // for VICE tests if (addr == 0xd7ff) { if (data == 0) { std::cout << std::endl << "\x1b[0;32m" << "OK" << std::endl; exit(EXIT_SUCCESS); } else if (data == 0xff) { std::cout << std::endl << "\x1b[0;31m" << "KO" << std::endl; exit(EXIT_FAILURE); } } #endif m_mmu.cpuWrite(addr, data); } public: explicit c64cpubus (MMU &mmu) : m_mmu(mmu) {} }; } #endif // C64CPU_H libsidplayfp-3.0.0/src/c64/c64.h0000644000175100017510000001400215175333711011612 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2023 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef C64_H #define C64_H #include #include #include #include "Banks/IOBank.h" #include "Banks/ColorRAMBank.h" #include "Banks/DisconnectedBusBank.h" #include "Banks/SidBank.h" #include "Banks/ExtraSidBank.h" #include "EventScheduler.h" #include "c64/c64env.h" #include "c64/c64cpu.h" #include "c64/c64cia.h" #include "c64/c64vic.h" #include "c64/mmu.h" #include "sidcxx11.h" #ifdef HAVE_CONFIG_H # include "config.h" #endif namespace libsidplayfp { class c64sid; class sidmemory; /** * Commodore 64 emulation core. * * It consists of the following chips: * - CPU 6510 * - VIC-II 6567/6569/6572/6573 * - CIA 6526/8521 * - SID 6581/8580 * - PLA 7700/82S100 * - Color RAM 2114 * - System RAM 4164-20/50464-150 * - Character ROM 2332 * - Basic ROM 2364 * - Kernal ROM 2364 */ class c64 final : private c64env { public: using model_t = enum { PAL_B = 0 ///< PAL C64 ,NTSC_M ///< NTSC C64 ,OLD_NTSC_M ///< Old NTSC C64 ,PAL_N ///< C64 Drean ,PAL_M ///< C64 Brasil }; using cia_model_t = enum { OLD = 0 ///< Old CIA ,NEW ///< New CIA ,OLD_4485 ///< Old CIA, special batch labeled 4485 }; private: using sidBankMap_t = std::map; private: /// System clock frequency double cpuFrequency; /// Number of sources asserting IRQ int irqCount; /// BA state bool oldBAState; /// System event context EventScheduler eventScheduler; /// CIA1 c64cia1 cia1; /// CIA2 c64cia2 cia2; /// VIC II c64vic vic; /// Color RAM ColorRAMBank colorRAMBank; /// SID SidBank sidBank; /// Extra SIDs sidBankMap_t extraSidBanks; /// I/O Area #1 and #2 DisconnectedBusBank disconnectedBusBank; /// I/O Area IOBank ioBank; /// MMU chip MMU mmu; /// CPUBus c64cpubus cpubus; /// CPU MOS6510 cpu; private: static double getCpuFreq(model_t model); static void deleteSids(sidBankMap_t &extraSidBanks); private: /** * IRQ trigger signal. * * Calls permitted any time, but normally originated by chips at PHI1. * * @param state */ inline void interruptIRQ(bool state) override; /** * NMI trigger signal. * * Calls permitted any time, but normally originated by chips at PHI1. */ inline void interruptNMI() override { cpu.triggerNMI(); } /** * Reset signal. */ inline void interruptRST() override { cpu.triggerRST(); } /** * BA signal. * * Calls permitted during PHI1. * * @param state */ inline void setBA(bool state) override; /** * @param state fire pressed, active low */ inline void lightpen(bool state) override; void resetIoBank(); public: c64(); ~c64(); /** * Get C64's event scheduler * * @return the scheduler */ EventScheduler *getEventScheduler() { return &eventScheduler; } uint_least32_t getTimeMs() const { return static_cast((eventScheduler.getTime(EVENT_CLOCK_PHI1) * 1000) / cpuFrequency); } /** * Clock the emulation. * * @throws haltInstruction */ void clock() { eventScheduler.clock(); } void debug(bool enable, FILE *out) { cpu.debug(enable, out); } void reset(); void resetCpu() { cpu.reset(); } /** * Set the c64 model. */ void setModel(model_t model); /** * Set the cia model. */ void setCiaModel(cia_model_t model); /** * Get the CPU clock speed. * * @return the speed in Hertz */ double getMainCpuSpeed() const { return cpuFrequency; } /** * Set the base SID. * * @param s the sid emu to set */ void setBaseSid(c64sid *s); /** * Add an extra SID. * * @param s the sid emu to set * @param sidAddress * base address (e.g. 0xd420) * * @return false if address is unsupported */ bool addExtraSid(c64sid *s, int address); /** * Remove all the SIDs. */ void clearSids(); /** * Get the components credits */ //@{ const char* cpuCredits() const { return cpu.credits(); } const char* ciaCredits() const { return cia1.credits(); } const char* vicCredits() const { return vic.credits(); } //@} sidmemory& getMemInterface() { return mmu; } uint_least16_t getCia1TimerA() const { return cia1.getTimerA(); } }; void c64::interruptIRQ(bool state) { if (state) { if (irqCount == 0) cpu.triggerIRQ(); irqCount ++; } else { irqCount --; if (irqCount == 0) cpu.clearIRQ(); } } void c64::setBA(bool state) { // only react to changes in state if (state == oldBAState) return; oldBAState = state; // Signal changes in BA to interested parties cpu.setRDY(state); } void c64::lightpen(bool state) { if (!state) vic.triggerLightpen(); else vic.clearLightpen(); } } #endif // C64_H libsidplayfp-3.0.0/src/c64/CIA/0000755000175100017510000000000015175333725011531 5libsidplayfp-3.0.0/src/c64/CIA/tod.cpp0000644000175100017510000001525415175333711012745 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2024 Leandro Nini * Copyright 2009-2024 VICE Project * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "tod.h" #include #include "mos652x.h" namespace libsidplayfp { void Tod::reset() { cycles = 0; todtickcounter = 0; std::memset(clock, 0, sizeof(clock)); clock[HOURS] = 1; // the most common value std::memcpy(latch, clock, sizeof(latch)); std::memset(alarm, 0, sizeof(alarm)); isLatched = false; isStopped = true; eventScheduler.schedule(*this, 0, EVENT_CLOCK_PHI1); } uint8_t Tod::read(uint_least8_t reg) { // TOD clock is latched by reading Hours, and released // upon reading Tenths of Seconds. The counter itself // keeps ticking all the time. // Also note that this latching is different from the input one. if (!isLatched) std::memcpy(latch, clock, sizeof(latch)); if (reg == TENTHS) isLatched = false; else if (reg == HOURS) isLatched = true; return latch[reg]; } void Tod::write(uint_least8_t reg, uint8_t data) { switch (reg) { case TENTHS: // Time Of Day clock 1/10 s data &= 0x0f; break; case SECONDS: // Time Of Day clock sec case MINUTES: // Time Of Day clock min data &= 0x7f; break; case HOURS: // Time Of Day clock hour data &= 0x9f; // force bits 6-5 = 0 // Flip AM/PM on hour 12 on the rising edge of the comparator if (((data & 0x1f) == 0x12) && !(crb & 0x80)) data ^= 0x80; break; } bool changed = false; if (crb & 0x80) { // set alarm if (alarm[reg] != data) { changed = true; alarm[reg] = data; } } else { // set time if (reg == TENTHS) { // the tickcounter is kept clear while the clock // is not running and then restarted by writing to the 10th // seconds register. if (isStopped) { todtickcounter = 0; isStopped = false; } } else if (reg == HOURS) { isStopped = true; } if (clock[reg] != data) { // see https://sourceforge.net/p/vice-emu/bugs/1988/ // Flip AM/PM on hour 12 on the rising edge of the comparator //if ((reg == HOURS) && ((data & 0x1f) == 0x12)) // data ^= 0x80; changed = true; clock[reg] = data; } } // check alarm if (changed) { checkAlarm(); } } void Tod::event() { cycles += period; // Fixed precision 25.7 eventScheduler.schedule(*this, cycles >> 7); cycles &= 0x7F; // Just keep the decimal part if (!isStopped) { /* * The divider which divides the 50 or 60 Hz power supply ticks into * 10 Hz uses a 3-bit ring counter, which goes 000, 001, 011, 111, 110, * 100. * For 50 Hz: matches at 110 (like "4") * For 60 Hz: matches at 100 (like "5") * (the middle bit of the match value is CRA7) * After a match there is a 1 tick delay (until the next power supply * tick) and then the 1/10 seconds counter increases, and the ring * resets to 000. */ // todtickcounter bits are mirrored to save an ANDing if (todtickcounter == (0x1 | ((cra & 0x80) >> 6))) { // reset the counter and update the timer todtickcounter = 0; updateCounters(); } else { // Count 50/60 Hz power supply ticks todtickcounter = (todtickcounter >> 1) | ((~todtickcounter << 2) & 0x4); } } } void Tod::updateCounters() { // advance the counters. // - individual counters are 4 bit // except for sh and mh which are 3 bits uint8_t ts = clock[TENTHS] & 0x0f; uint8_t sl = clock[SECONDS] & 0x0f; uint8_t sh = (clock[SECONDS] >> 4) & 0x07; uint8_t ml = clock[MINUTES] & 0x0f; uint8_t mh = (clock[MINUTES] >> 4) & 0x07; uint8_t hl = clock[HOURS] & 0x0f; uint8_t hh = (clock[HOURS] >> 4) & 0x01; uint8_t pm = clock[HOURS] & 0x80; // tenth seconds (0-9) ts = (ts + 1) & 0x0f; if (ts == 10) { ts = 0; // seconds (0-59) sl = (sl + 1) & 0x0f; // x0...x9 if (sl == 10) { sl = 0; sh = (sh + 1) & 0x07; // 0x...5x if (sh == 6) { sh = 0; // minutes (0-59) ml = (ml + 1) & 0x0f; // x0...x9 if (ml == 10) { ml = 0; mh = (mh + 1) & 0x07; // 0x...5x if (mh == 6) { mh = 0; // hours (1-12) // flip from 09:59:59 to 10:00:00 // or from 12:59:59 to 01:00:00 if (((hl == 2) && (hh == 1)) || ((hl == 9) && (hh == 0))) { hl = hh; hh ^= 1; } else { hl = (hl + 1) & 0x0f; // toggle the am/pm flag when reaching 12 if ((hl == 2) && (hh == 1)) { pm ^= 0x80; } } } } } } } clock[TENTHS] = ts; clock[SECONDS] = sl | (sh << 4); clock[MINUTES] = ml | (mh << 4); clock[HOURS] = hl | (hh << 4) | pm; checkAlarm(); } void Tod::checkAlarm() { if (!std::memcmp(alarm, clock, sizeof(alarm))) { parent.todInterrupt(); } } } libsidplayfp-3.0.0/src/c64/CIA/interrupt.h0000644000175100017510000001220615175333711013652 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2020 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef INTERRUPT_H #define INTERRUPT_H #include "Event.h" #include "EventScheduler.h" #include "EventCallback.h" #include #include "sidcxx11.h" namespace libsidplayfp { class MOS652X; /** * This is the base class for the MOS6526 interrupt sources. * Based on Denise emu code. */ class InterruptSource { public: enum { INTERRUPT_NONE = 0, ///< no interrupt INTERRUPT_UNDERFLOW_A = 1 << 0, ///< underflow Timer A INTERRUPT_UNDERFLOW_B = 1 << 1, ///< underflow Timer B INTERRUPT_ALARM = 1 << 2, ///< alarm clock INTERRUPT_SP = 1 << 3, ///< serial port INTERRUPT_FLAG = 1 << 4, ///< external flag INTERRUPT_REQUEST = 1 << 7 ///< control bit }; private: /// Pointer to the MOS6526 which this Interrupt belongs to. MOS652X &parent; protected: /// Event scheduler. EventScheduler &eventScheduler; /// Clock when clear was called last event_clock_t last_clear = 0; event_clock_t last_set = 0; /// Interrupt control register uint8_t icr = 0; /// Interrupt data register uint8_t idr = 0; uint8_t idrTemp = 0; /// Have we already scheduled CIA->CPU interrupt transition? bool scheduled = false; /// is the irq pin asserted? bool asserted = false; private: EventCallback interruptEvent; EventCallback updateIdrEvent; EventCallback setIrqEvent; EventCallback clearIrqEvent; protected: inline bool interruptTriggered() const { return idr & INTERRUPT_REQUEST; } inline bool interruptMasked(uint8_t interruptMask) const { return ((interruptMask != INTERRUPT_NONE) ? interruptMask : idr) & icr; } virtual void triggerInterrupt() =0; /** * Check if interrupts were ackowledged during previous cycle. */ inline bool ack0() const { return eventScheduler.getTime(EVENT_CLOCK_PHI2) == (last_clear+1); } inline bool write0() const { return eventScheduler.getTime(EVENT_CLOCK_PHI2) == (last_set+1); } /** * Signal interrupt to CPU. */ void interrupt(); void updateIdr(); void setIrq(); void clearIrq(); protected: /** * Create a new InterruptSource. * * @param scheduler event scheduler * @param parent the CIA chip which this Interrupt belongs to */ InterruptSource(EventScheduler &scheduler, MOS652X &parent) : parent(parent), eventScheduler(scheduler), interruptEvent("CIA Interrupt", *this, &InterruptSource::interrupt), updateIdrEvent("CIA update ICR", *this, &InterruptSource::updateIdr), setIrqEvent("CIA set IRQ", *this, &InterruptSource::setIrq), clearIrqEvent("CIA clear IRQ", *this, &InterruptSource::clearIrq) {} /** * Schedules an IRQ asserting state transition for next cycle. */ void schedule(int delay) { if (!scheduled) { eventScheduler.schedule(interruptEvent, delay, EVENT_CLOCK_PHI1); scheduled = true; } } void scheduleIrq() { eventScheduler.schedule(setIrqEvent, 1, EVENT_CLOCK_PHI1); } bool isTriggered(uint8_t interruptMask); public: virtual ~InterruptSource() = default; /** * Trigger an interrupt. * * @param interruptMask Interrupt flag number */ virtual void trigger(uint8_t interruptMask) =0; /** * Clear interrupt state. * * @return old interrupt state */ virtual uint8_t clear(); /** * Clear pending interrupts, but do not signal to CPU we lost them. * It is assumed that all components get reset() calls in synchronous manner. */ virtual void reset() { last_clear = 0; last_set = 0; icr = 0; idr = 0; eventScheduler.cancel(updateIdrEvent); eventScheduler.cancel(setIrqEvent); eventScheduler.cancel(clearIrqEvent); eventScheduler.cancel(interruptEvent); scheduled = false; asserted = false; } /** * Set interrupt control mask bits. * * @param interruptMask control mask bits */ void set(uint8_t interruptMask); }; } #endif // INTERRUPT_H libsidplayfp-3.0.0/src/c64/CIA/SerialPort.h0000644000175100017510000000451315175333711013704 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2020 Leandro Nini * Copyright 2009-2014 VICE Project * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SERIALPORT_H #define SERIALPORT_H #include "interrupt.h" #include "Event.h" namespace libsidplayfp { class MOS652X; class SerialPort : private Event { private: /// Pointer to the MOS6526 which this Serial Port belongs to. MOS652X &parent; /// Event context. EventScheduler &eventScheduler; EventCallback flipCntEvent; EventCallback flipFakeEvent; EventCallback startSdrEvent; event_clock_t lastSync; int count; uint8_t cnt; uint8_t cntHistory; bool loaded; bool pending; bool forceFinish; bool model4485 = false; private: void event() override; void flipCnt(); void flipFake(); void doStartSdr() { (loaded ? pending : loaded) = true; } void syncCntHistory(); public: SerialPort(EventScheduler &scheduler, MOS652X &parent) : Event("Serial Port interrupt"), parent(parent), eventScheduler(scheduler), flipCntEvent("flip CNT", *this, &SerialPort::flipCnt), flipFakeEvent("flip fake", *this, &SerialPort::flipFake), startSdrEvent("start SDR", *this, &SerialPort::doStartSdr) {} void reset(); void setModel4485(bool is4485) { model4485 = is4485; } void startSdr() { eventScheduler.schedule(startSdrEvent, 1); } void switchSerialDirection(bool input); void handle(); }; } #endif // SERIALPORT_H libsidplayfp-3.0.0/src/c64/CIA/timer.h0000644000175100017510000001666415175333711012752 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2013 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef TIMER_H #define TIMER_H #include #include "Event.h" #include "EventCallback.h" #include "EventScheduler.h" #include "sidcxx11.h" namespace libsidplayfp { class MOS652X; /** * This is the base class for the MOS6526 timers. */ class Timer : private Event { protected: static constexpr int_least32_t CIAT_CR_START = 0x01; static constexpr int_least32_t CIAT_STEP = 0x04; static constexpr int_least32_t CIAT_CR_ONESHOT = 0x08; static constexpr int_least32_t CIAT_CR_FLOAD = 0x10; static constexpr int_least32_t CIAT_PHI2IN = 0x20; static constexpr int_least32_t CIAT_CR_MASK = CIAT_CR_START | CIAT_CR_ONESHOT | CIAT_CR_FLOAD | CIAT_PHI2IN; static constexpr int_least32_t CIAT_COUNT2 = 0x100; static constexpr int_least32_t CIAT_COUNT3 = 0x200; static constexpr int_least32_t CIAT_ONESHOT0 = 0x08 << 8; static constexpr int_least32_t CIAT_ONESHOT = 0x08 << 16; static constexpr int_least32_t CIAT_LOAD1 = 0x10 << 8; static constexpr int_least32_t CIAT_LOAD = 0x10 << 16; static constexpr int_least32_t CIAT_OUT = 0x80000000; private: EventCallback m_cycleSkippingEvent; /// Event context. EventScheduler &eventScheduler; /** * This is a tri-state: * * - when -1: cia is completely stopped * - when 0: cia 1-clock events are ticking. * - otherwise: cycle skip event is ticking, and the value is the first * phi1 clock of skipping. */ event_clock_t ciaEventPauseTime; /// PB6/PB7 Flipflop to signal underflows. bool pbToggle = false; /// Current timer value. uint_least16_t timer = 0; /// Timer start value (Latch). uint_least16_t latch = 0; /// Copy of regs[CRA/B] uint8_t lastControlValue = 0; protected: /// Pointer to the MOS6526 which this Timer belongs to. MOS652X &parent; /// CRA/CRB control register / state. int_least32_t state = 0; private: /** * Perform scheduled cycle skipping, and resume. */ void cycleSkippingEvent(); /** * Execute one CIA state transition. */ void clock(); /** * Reschedule CIA event at the earliest interesting time. * If CIA timer is stopped or is programmed to just count down, * the events are paused. */ inline void reschedule(); /** * Timer ticking event. */ void event() override; /** * Signal timer underflow. */ virtual void underFlow() =0; /** * Handle the serial port. */ virtual void serialPort() {} protected: /** * Create a new timer. * * @param name component name * @param context event context * @param parent the MOS6526 which this Timer belongs to */ Timer(const char* name, EventScheduler &scheduler, MOS652X &parent) : Event(name), m_cycleSkippingEvent("Skip CIA clock decrement cycles", *this, &Timer::cycleSkippingEvent), eventScheduler(scheduler), parent(parent) {} public: /** * Set CRA/CRB control register. * * @param cr control register value */ void setControlRegister(uint8_t cr); /** * Perform cycle skipping manually. * * Clocks the CIA up to the state it should be in, and stops all events. */ void syncWithCpu(); /** * Counterpart of syncWithCpu(), * starts the event ticking if it is needed. * No clock() call or anything such is permissible here! */ void wakeUpAfterSyncWithCpu(); /** * Reset timer. */ void reset(); /** * Set low byte of Timer start value (Latch). * * @param data * low byte of latch */ void latchLo(uint8_t data); /** * Set high byte of Timer start value (Latch). * * @param data * high byte of latch */ void latchHi(uint8_t data); /** * Set PB6/PB7 Flipflop state. * * @param state * PB6/PB7 flipflop state */ inline void setPbToggle(bool state) { pbToggle = state; } /** * Get current state value. * * @return current state value */ inline int_least32_t getState() const { return state; } /** * Get current timer value. * * @return current timer value */ inline uint_least16_t getTimer() const { return timer; } /** * Get PB6/PB7 Flipflop state. * * @param reg value of the control register * @return PB6/PB7 flipflop state */ inline bool getPb(uint8_t reg) const { return (reg & 0x04) ? pbToggle : (state & CIAT_OUT); } }; void Timer::reschedule() { // There are only two subcases to consider. // // - are we counting, and if so, are we going to // continue counting? // - have we stopped, and are there no conditions to force a new beginning? // // Additionally, there are numerous flags that are present only in passing manner, // but which we need to let cycle through the CIA state machine. const int_least32_t unwanted = CIAT_OUT | CIAT_CR_FLOAD | CIAT_LOAD1 | CIAT_LOAD; if ((state & unwanted) != 0) { eventScheduler.schedule(*this, 1); return; } if ((state & CIAT_COUNT3) != 0) { // Test the conditions that keep COUNT2 and thus COUNT3 alive, and also // ensure that all of them are set indicating steady state operation. const int_least32_t wanted = CIAT_CR_START | CIAT_PHI2IN | CIAT_COUNT2 | CIAT_COUNT3; if (timer > 2 && (state & wanted) == wanted) { // we executed this cycle, therefore the pauseTime is +1. If we are called // to execute on the very next clock, we need to get 0 because there's // another timer-- in it. ciaEventPauseTime = eventScheduler.getTime(EVENT_CLOCK_PHI1) + 1; // execute event slightly before the next underflow. eventScheduler.schedule(m_cycleSkippingEvent, timer - 1); return; } // play safe, keep on ticking. eventScheduler.schedule(*this, 1); } else { // Test conditions that result in CIA activity in next clocks. // If none, stop. const int_least32_t unwanted1 = CIAT_CR_START | CIAT_PHI2IN; const int_least32_t unwanted2 = CIAT_CR_START | CIAT_STEP; if ((state & unwanted1) == unwanted1 || (state & unwanted2) == unwanted2) { eventScheduler.schedule(*this, 1); return; } ciaEventPauseTime = -1; } } } #endif // TIMER_H libsidplayfp-3.0.0/src/c64/CIA/mos652x.cpp0000644000175100017510000001650515175333711013402 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2022 Leandro Nini * Copyright 2009-2014 VICE Project * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "mos652x.h" #include #include #include "sidendian.h" namespace libsidplayfp { enum { PRA = 0, PRB = 1, DDRA = 2, DDRB = 3, TAL = 4, TAH = 5, TBL = 6, TBH = 7, TOD_TEN = 8, TOD_SEC = 9, TOD_MIN = 10, TOD_HR = 11, SDR = 12, ICR = 13, IDR = 13, CRA = 14, CRB = 15 }; // Timer A void TimerA::underFlow() { parent.underflowA(); } void TimerA::serialPort() { parent.handleSerialPort(); } // Timer B void TimerB::underFlow() { parent.underflowB(); } // Interrupt Source 8521 void InterruptSource8521::trigger(uint8_t interruptMask) { if (InterruptSource::isTriggered(interruptMask)) { schedule(0); } } // Interrupt Source 6526 void InterruptSource6526::trigger(uint8_t interruptMask) { if (InterruptSource::isTriggered(interruptMask)) { // interrupts are delayed by 1 clk on old CIAs schedule(1); } // if timer B underflows during the acknowledge cycle // it triggers an interrupt as expected // but the second bit in icr is not set if ((interruptMask == INTERRUPT_UNDERFLOW_B) && ack0()) { idr &= ~INTERRUPT_UNDERFLOW_B; idrTemp &= ~INTERRUPT_UNDERFLOW_B; } } uint8_t InterruptSource6526::clear() { uint8_t oldIdr = InterruptSource::clear(); idr &= INTERRUPT_REQUEST; return oldIdr; } const char *MOS652X::credits() { return "MOS6526/8521 (CIA) Emulation:\n" "\tCopyright (C) 2001-2004 Simon White\n" "\tCopyright (C) 2007-2010 Antti S. Lankila\n" "\tCopyright (C) 2009-2014 VICE Project\n" "\tCopyright (C) 2011-2021 Leandro Nini\n"; } MOS652X::MOS652X(EventScheduler &scheduler) : eventScheduler(scheduler), pra(regs[PRA]), prb(regs[PRB]), ddra(regs[DDRA]), ddrb(regs[DDRB]), timerA(scheduler, *this), timerB(scheduler, *this), interruptSource(new InterruptSource6526(scheduler, *this)), tod(scheduler, *this, regs), serialPort(scheduler, *this), bTickEvent("CIA B counts A", *this, &MOS652X::bTick) { // reset is virtual, must call from subclasses //reset(); } void MOS652X::handleSerialPort() { if (regs[CRA] & 0x40) { serialPort.handle(); } } void MOS652X::reset() { std::fill(std::begin(regs), std::end(regs), 0); serialPort.reset(); // Reset timers timerA.reset(); timerB.reset(); // Reset interruptSource interruptSource->reset(); // Reset tod tod.reset(); eventScheduler.cancel(bTickEvent); } uint8_t MOS652X::adjustDataPort(uint8_t data) const { if (regs[CRA] & 0x02) { data &= 0xbf; if (timerA.getPb(regs[CRA])) data |= 0x40; } if (regs[CRB] & 0x02) { data &= 0x7f; if (timerB.getPb(regs[CRB])) data |= 0x80; } return data; } uint8_t MOS652X::read(uint_least8_t addr) { addr &= 0x0f; timerA.syncWithCpu(); timerA.wakeUpAfterSyncWithCpu(); timerB.syncWithCpu(); timerB.wakeUpAfterSyncWithCpu(); switch (addr) { case PRA: // Simulate a serial port return (regs[PRA] | ~regs[DDRA]); case PRB: return adjustDataPort(regs[PRB] | ~regs[DDRB]); case TAL: return endian_16lo8(timerA.getTimer()); case TAH: return endian_16hi8(timerA.getTimer()); case TBL: return endian_16lo8(timerB.getTimer()); case TBH: return endian_16hi8(timerB.getTimer()); case TOD_TEN: case TOD_SEC: case TOD_MIN: case TOD_HR: return tod.read(addr - TOD_TEN); case IDR: return interruptSource->clear(); case CRA: return (regs[CRA] & 0xee) | (timerA.getState() & 1); case CRB: return (regs[CRB] & 0xee) | (timerB.getState() & 1); default: return regs[addr]; } } void MOS652X::write(uint_least8_t addr, uint8_t data) { addr &= 0x0f; timerA.syncWithCpu(); timerB.syncWithCpu(); const uint8_t oldData = regs[addr]; regs[addr] = data; switch (addr) { case PRA: case DDRA: portA(); break; case PRB: case DDRB: portB(); break; case TAL: timerA.latchLo(data); break; case TAH: timerA.latchHi(data); break; case TBL: timerB.latchLo(data); break; case TBH: timerB.latchHi(data); break; case TOD_TEN: case TOD_SEC: case TOD_MIN: case TOD_HR: tod.write(addr - TOD_TEN, data); break; case SDR: serialPort.startSdr(); break; case ICR: interruptSource->set(data); break; case CRA: if ((data ^ oldData) & 0x40) serialPort.switchSerialDirection((data & 0x40) == 0); if ((data & 1) && !(oldData & 1)) { // Reset the underflow flipflop for the data port timerA.setPbToggle(true); } timerA.setControlRegister(data); break; case CRB: if ((data & 1) && !(oldData & 1)) { // Reset the underflow flipflop for the data port timerB.setPbToggle(true); } timerB.setControlRegister(data | (data & 0x40) >> 1); break; } timerA.wakeUpAfterSyncWithCpu(); timerB.wakeUpAfterSyncWithCpu(); } void MOS652X::bTick() { timerB.cascade(); } void MOS652X::underflowA() { interruptSource->trigger(InterruptSource::INTERRUPT_UNDERFLOW_A); if ((regs[CRB] & 0x41) == 0x41) { if (timerB.started()) { eventScheduler.schedule(bTickEvent, 0, EVENT_CLOCK_PHI2); } } } void MOS652X::underflowB() { interruptSource->trigger(InterruptSource::INTERRUPT_UNDERFLOW_B); } void MOS652X::todInterrupt() { interruptSource->trigger(InterruptSource::INTERRUPT_ALARM); } void MOS652X::spInterrupt() { interruptSource->trigger(InterruptSource::INTERRUPT_SP); } void MOS652X::setModel(model_t model) { switch (model) { case model_t::MOS6526W4485: case model_t::MOS6526: serialPort.setModel4485(model == model_t::MOS6526W4485); interruptSource.reset(new InterruptSource6526(eventScheduler, *this)); break; case model_t::MOS8521: serialPort.setModel4485(false); interruptSource.reset(new InterruptSource8521(eventScheduler, *this)); break; } } } libsidplayfp-3.0.0/src/c64/CIA/tod.h0000644000175100017510000000510015175333711012377 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2018 Leandro Nini * Copyright 2009-2014 VICE Project * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef TOD_H #define TOD_H #include #include "EventScheduler.h" namespace libsidplayfp { class MOS652X; /** * TOD implementation taken from Vice. */ class Tod : private Event { private: enum { TENTHS = 0, SECONDS = 1, MINUTES = 2, HOURS = 3 }; private: /// Event scheduler. EventScheduler &eventScheduler; /// Pointer to the MOS6526 which this Timer belongs to. MOS652X &parent; const uint8_t &cra; const uint8_t &crb; event_clock_t cycles; event_clock_t period; unsigned int todtickcounter; bool isLatched; bool isStopped; uint8_t clock[4]; uint8_t latch[4]; uint8_t alarm[4]; private: inline void checkAlarm(); inline void updateCounters(); void event() override; public: Tod(EventScheduler &scheduler, MOS652X &parent, uint8_t regs[0x10]) : Event("CIA Time of Day"), eventScheduler(scheduler), parent(parent), cra(regs[0x0e]), crb(regs[0x0f]), period(~0), // Dummy todtickcounter(0) {} /** * Reset TOD. */ void reset(); /** * Read TOD register. * * @param addr * register register to read */ uint8_t read(uint_least8_t reg); /** * Write TOD register. * * @param addr * register to write * @param data * value to write */ void write(uint_least8_t reg, uint8_t data); /** * Set TOD period. * * @param clock */ void setPeriod(event_clock_t clock) { period = clock * (1 << 7); } }; } #endif libsidplayfp-3.0.0/src/c64/CIA/interrupt.cpp0000644000175100017510000000523515175333711014211 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2021 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "interrupt.h" #include "mos652x.h" namespace libsidplayfp { void InterruptSource::interrupt() { if (!interruptTriggered()) { triggerInterrupt(); setIrq(); } scheduled = false; } void InterruptSource::updateIdr() { idr = idrTemp; if (ack0()) { eventScheduler.schedule(updateIdrEvent, 1, EVENT_CLOCK_PHI1); idrTemp = 0; } } void InterruptSource::setIrq() { if (!ack0()) { if (!asserted) { parent.interrupt(true); asserted = true; } } } void InterruptSource::clearIrq() { if (asserted) { parent.interrupt(false); asserted = false; } } bool InterruptSource::isTriggered(uint8_t interruptMask) { idr |= interruptMask; idrTemp |= interruptMask; if (interruptMasked(interruptMask)) return true; if ((interruptMask == INTERRUPT_NONE) && write0()) { // cancel pending interrupts if (scheduled) { eventScheduler.cancel(interruptEvent); scheduled = false; } } return false; } void InterruptSource::set(uint8_t interruptMask) { if (interruptMask & INTERRUPT_REQUEST) { icr |= interruptMask & ~INTERRUPT_REQUEST; } else { icr &= ~interruptMask; } if (!ack0()) trigger(INTERRUPT_NONE); last_set = eventScheduler.getTime(EVENT_CLOCK_PHI2); } uint8_t InterruptSource::clear() { last_clear = eventScheduler.getTime(EVENT_CLOCK_PHI2); eventScheduler.schedule(clearIrqEvent, 0, EVENT_CLOCK_PHI1); if (!eventScheduler.isPending(updateIdrEvent)) { eventScheduler.schedule(updateIdrEvent, 1, EVENT_CLOCK_PHI1); idrTemp = 0; } return idr; } } libsidplayfp-3.0.0/src/c64/CIA/SerialPort.cpp0000644000175100017510000000602315175333711014235 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2020 Leandro Nini * Copyright 2009-2014 VICE Project * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "interrupt.h" #include "mos652x.h" namespace libsidplayfp { void SerialPort::reset() { count = 0; cntHistory = 0; cnt = 1; loaded = false; pending = false; forceFinish = false; lastSync = eventScheduler.getTime(EVENT_CLOCK_PHI1); } void SerialPort::event() { parent.spInterrupt(); } void SerialPort::syncCntHistory() { const event_clock_t time = eventScheduler.getTime(EVENT_CLOCK_PHI1); const event_clock_t clocks = time - lastSync; lastSync = time; for (int i=0; i * Copyright 2009-2014 VICE Project * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MOS652X_H #define MOS652X_H #include #include #include "interrupt.h" #include "timer.h" #include "tod.h" #include "SerialPort.h" #include "EventScheduler.h" #include "sidcxx11.h" class EventContext; namespace libsidplayfp { class MOS652X; /** * This is the timer A of this CIA. * * @author Ken Händel * */ class TimerA final : public Timer { private: /** * Signal underflows of Timer A to Timer B. */ void underFlow() override; void serialPort() override; public: /** * Create timer A. */ TimerA(EventScheduler &scheduler, MOS652X &parent) : Timer("CIA Timer A", scheduler, parent) {} }; /** * This is the timer B of this CIA. * * @author Ken Händel * */ class TimerB final : public Timer { private: void underFlow() override; public: /** * Create timer B. */ TimerB(EventScheduler &scheduler, MOS652X &parent) : Timer("CIA Timer B", scheduler, parent) {} /** * Receive an underflow from Timer A. */ void cascade() { // we pretend that we are CPU doing a write to ctrl register syncWithCpu(); state |= CIAT_STEP; wakeUpAfterSyncWithCpu(); } /** * Check if start flag is set. * * @return true if start flag is set, false otherwise */ bool started() const { return (state & CIAT_CR_START) != 0; } }; /** * InterruptSource that acts like new CIA */ class InterruptSource8521 final : public InterruptSource { protected: void triggerInterrupt() override { idr |= INTERRUPT_REQUEST; idrTemp |= INTERRUPT_REQUEST; if (ack0()) scheduleIrq(); } public: InterruptSource8521(EventScheduler &scheduler, MOS652X &parent) : InterruptSource(scheduler, parent) {} void trigger(uint8_t interruptMask) override; }; /** * InterruptSource that acts like old CIA */ class InterruptSource6526 final : public InterruptSource { protected: void triggerInterrupt() override { idr |= INTERRUPT_REQUEST; } public: InterruptSource6526(EventScheduler &scheduler, MOS652X &parent) : InterruptSource(scheduler, parent) {} void trigger(uint8_t interruptMask) override; uint8_t clear() override; }; /** * This class is heavily based on the ciacore/ciatimer source code from VICE. * The CIA state machine is lifted as-is. Big thanks to VICE project! * The Serial Port emulation is based on Denise emu code. */ class MOS652X { friend class InterruptSource; friend class SerialPort; friend class TimerA; friend class TimerB; friend class Tod; public: enum class model_t { MOS6526 = 0 ///< Old CIA model, interrupts are delayed by 1 clock ,MOS8521 ///< New CIA model ,MOS6526W4485 ///< A batch of old CIA model with unique serial port behavior }; private: static const char *credit; protected: /// Event context. EventScheduler &eventScheduler; /// Ports //@{ uint8_t &pra, &prb, &ddra, &ddrb; //@} /// These are all CIA registers. uint8_t regs[0x10]; /// Timers A and B. //@{ TimerA timerA; TimerB timerB; //@} /// Interrupt Source std::unique_ptr interruptSource; /// TOD Tod tod; /// Serial Data Registers SerialPort serialPort; /// Events //@{ EventCallback bTickEvent; //@} private: /** * Trigger an interrupt from TOD. */ void todInterrupt(); /** * Trigger an interrupt from Serial Port. */ void spInterrupt(); /** * This event exists solely to break the ambiguity of what scheduling on * top of PHI1 causes, because there is no ordering between events on * same phase. Thus it is scheduled in PHI2 to ensure the b.event() is * run once before the value changes. * * - PHI1 a.event() (which calls underFlow()) * - PHI1 b.event() * - PHI2 bTick.event() * - PHI1 a.event() * - PHI1 b.event() */ void bTick(); /** * Timer A underflow. */ void underflowA(); /** Timer B underflow. */ void underflowB(); /** * Handle the serial port. */ void handleSerialPort(); protected: /** * Create a new CIA. * * @param context the event context */ MOS652X(EventScheduler &scheduler); /** * Signal interrupt. * * @param state * interrupt state */ virtual void interrupt(bool state) = 0; virtual void portA() {} virtual void portB() {} /** * Timers can appear on the port. */ uint8_t adjustDataPort(uint8_t data) const; /** * Read CIA register. * * @param addr * register address to read (lowest 4 bits) */ uint8_t read(uint_least8_t addr); /** * Write CIA register. * * @param addr * register address to write (lowest 4 bits) * @param data * value to write */ void write(uint_least8_t addr, uint8_t data); public: /** * Select chip model. * * @param model */ void setModel(model_t model); /** * Reset CIA. */ virtual void reset(); /** * Get the credits. * * @return the credits */ static const char *credits(); /** * Set day-of-time event occurence of rate. * * @param clock */ void setDayOfTimeRate(unsigned int clock) { tod.setPeriod(clock); } }; } #endif // MOS6526_H libsidplayfp-3.0.0/src/c64/CIA/timer.cpp0000644000175100017510000001023015175333711013264 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2013 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "timer.h" #include "sidendian.h" namespace libsidplayfp { void Timer::setControlRegister(uint8_t cr) { state &= ~CIAT_CR_MASK; state |= (cr & CIAT_CR_MASK) ^ CIAT_PHI2IN; lastControlValue = cr; } void Timer::syncWithCpu() { if (ciaEventPauseTime > 0) { eventScheduler.cancel(m_cycleSkippingEvent); const event_clock_t elapsed = eventScheduler.getTime(EVENT_CLOCK_PHI2) - ciaEventPauseTime; // It's possible for CIA to determine that it wants to go to sleep starting from the next // cycle, and then have its plans aborted by CPU. Thus, we must avoid modifying // the CIA state if the first sleep clock was still in the future. if (elapsed >= 0) { timer -= elapsed; clock(); } } if (ciaEventPauseTime == 0) { eventScheduler.cancel(*this); } ciaEventPauseTime = -1; } void Timer::wakeUpAfterSyncWithCpu() { ciaEventPauseTime = 0; eventScheduler.schedule(*this, 0, EVENT_CLOCK_PHI1); } void Timer::event() { clock(); reschedule(); } void Timer::cycleSkippingEvent() { const event_clock_t elapsed = eventScheduler.getTime(EVENT_CLOCK_PHI1) - ciaEventPauseTime; ciaEventPauseTime = 0; timer -= elapsed; event(); } void Timer::clock() { if ((state & CIAT_COUNT3) != 0) { timer--; } /* ciatimer.c block start */ int_least32_t adj = state & (CIAT_CR_START | CIAT_CR_ONESHOT | CIAT_PHI2IN); if ((state & (CIAT_CR_START | CIAT_PHI2IN)) == (CIAT_CR_START | CIAT_PHI2IN)) { adj |= CIAT_COUNT2; } if ((state & CIAT_COUNT2) != 0 || (state & (CIAT_STEP | CIAT_CR_START)) == (CIAT_STEP | CIAT_CR_START)) { adj |= CIAT_COUNT3; } // CR_FLOAD -> LOAD1, CR_ONESHOT -> ONESHOT0, LOAD1 -> LOAD, ONESHOT0 -> ONESHOT adj |= (state & (CIAT_CR_FLOAD | CIAT_CR_ONESHOT | CIAT_LOAD1 | CIAT_ONESHOT0)) << 8; state = adj; /* ciatimer.c block end */ if ((timer == 0) && ((state & CIAT_COUNT3) != 0)) { state |= CIAT_LOAD | CIAT_OUT; if ((state & (CIAT_ONESHOT | CIAT_ONESHOT0)) != 0) { state &= ~(CIAT_CR_START | CIAT_COUNT2); } // By setting bits 2&3 of the control register, // PB6/PB7 will be toggled between high and low at each underflow. const bool toggle = (lastControlValue & 0x06) == 6; pbToggle = toggle && !pbToggle; // Implementation of the serial port serialPort(); // Timer A signals underflow handling: IRQ/B-count underFlow(); } if ((state & CIAT_LOAD) != 0) { timer = latch; state &= ~CIAT_COUNT3; } } void Timer::reset() { eventScheduler.cancel(*this); timer = latch = 0xffff; pbToggle = false; state = 0; lastControlValue = 0; ciaEventPauseTime = 0; eventScheduler.schedule(*this, 1, EVENT_CLOCK_PHI1); } void Timer::latchLo(uint8_t data) { endian_16lo8(latch, data); if ((state & CIAT_LOAD) != 0) timer = latch; } void Timer::latchHi(uint8_t data) { endian_16hi8(latch, data); if ((state & CIAT_LOAD) != 0) timer = latch; // Reload timer if stopped else if ((state & CIAT_CR_START) == 0) state |= CIAT_LOAD1; } } libsidplayfp-3.0.0/src/c64/c64cia.h0000644000175100017510000000604015175333711012272 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2021 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef C64CIA_H #define C64CIA_H // The CIA emulations are very generic and here we need to effectively // wire them into the computer (like adding a chip to a PCB). #include "Banks/Bank.h" #include "c64/c64env.h" #include "sidendian.h" #include "CIA/mos652x.h" #include "sidcxx11.h" namespace libsidplayfp { /** * CIA 1 * * Generates IRQs * * Located at $DC00-$DCFF */ class c64cia1 final : public MOS652X, public Bank { private: c64env &m_env; uint_least16_t last_ta; protected: void interrupt(bool state) override { m_env.interruptIRQ(state); } void portB() override { const uint8_t pb = prb | ~ddrb; // We should call adjustDataPort here // but we're only interested in bit 4 m_env.lightpen(pb & 0x10); } public: explicit c64cia1(c64env &env) : MOS652X(env.scheduler()), m_env(env) { reset(); } void poke(uint_least16_t address, uint8_t value) override { const uint8_t addr = endian_16lo8(address); write(addr, value); // Save the value written to Timer A if ((addr == 0x04) || (addr == 0x05)) { if (timerA.getTimer() != 0) last_ta = timerA.getTimer(); } } uint8_t peek(uint_least16_t address) override { return read(endian_16lo8(address)); } void reset() override { last_ta = 0; MOS652X::reset(); } uint_least16_t getTimerA() const { return last_ta; } }; /** * CIA 2 * * Generates NMIs * * Located at $DD00-$DDFF */ class c64cia2 : public MOS652X, public Bank { private: c64env &m_env; protected: void interrupt(bool state) override { if (state) m_env.interruptNMI(); } public: explicit c64cia2(c64env &env) : MOS652X(env.scheduler()), m_env(env) { reset(); } void poke(uint_least16_t address, uint8_t value) override { write(endian_16lo8(address), value); } uint8_t peek(uint_least16_t address) override { return read(endian_16lo8(address)); } }; } #endif // C64CIA_H libsidplayfp-3.0.0/src/sidmemory.h0000644000175100017510000000633615175333711012645 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2021 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDMEMORY_H #define SIDMEMORY_H #include namespace libsidplayfp { /** * An interface that allows access to c64 memory * for loading tunes and apply sid specific hacks. */ class sidmemory { public: /** * Read one byte from memory. * * @param addr the memory location from which to read from */ virtual uint8_t readMemByte(uint_least16_t addr) =0; /** * Read two contiguous bytes from memory. * * @param addr the memory location from which to read from */ virtual uint_least16_t readMemWord(uint_least16_t addr) =0; /** * Write one byte to memory. * * @param addr the memory location where to write * @param value the value to write */ virtual void writeMemByte(uint_least16_t addr, uint8_t value) =0; /** * Write two contiguous bytes to memory. * * @param addr the memory location where to write * @param value the value to write */ virtual void writeMemWord(uint_least16_t addr, uint_least16_t value) =0; /** * Fill ram area with a constant value. * * @param start the start of memory location where to write * @param value the value to write * @param size the number of bytes to fill */ virtual void fillRam(uint_least16_t start, uint8_t value, unsigned int size) =0; /** * Copy a buffer into a ram area. * * @param start the start of memory location where to write * @param source the source buffer * @param size the number of bytes to copy */ virtual void fillRam(uint_least16_t start, const uint8_t* source, unsigned int size) =0; /** * Change the RESET vector. * * @param addr the new addres to point to */ virtual void installResetHook(uint_least16_t addr) =0; /** * Set BASIC Warm Start address. * * @param addr the new addres to point to */ virtual void installBasicTrap(uint_least16_t addr) =0; /** * Set the start tune. * * @param tune the tune number */ virtual void setBasicSubtune(uint8_t tune) =0; /** * Set the ROM banks. * * @param rom the ROM data */ //@{ virtual void setKernal(const uint8_t* rom) =0; virtual void setBasic(const uint8_t* rom) =0; virtual void setChargen(const uint8_t* rom) =0; //@} protected: ~sidmemory() = default; }; } #endif libsidplayfp-3.0.0/src/psiddrv.bin0000644000175100017510000000336115175333725012631 0x01, 0x00, 0x6f, 0x36, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10, 0xcf, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1b, 0x10, 0xc5, 0x10, 0xce, 0x10, 0xce, 0x10, 0x8c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x0e, 0x10, 0x6c, 0x0c, 0x10, 0x78, 0xa9, 0x00, 0x8d, 0x1a, 0xd0, 0xad, 0x19, 0xd0, 0x8d, 0x19, 0xd0, 0xa9, 0x7f, 0x8d, 0x0d, 0xdc, 0x8d, 0x0d, 0xdd, 0xad, 0x0d, 0xdc, 0xad, 0x0d, 0xdd, 0xa9, 0x0f, 0x8d, 0x18, 0xd4, 0xad, 0x12, 0x10, 0xf0, 0x07, 0xa2, 0x25, 0xa0, 0x40, 0x4c, 0x4a, 0x10, 0xa2, 0x95, 0xa0, 0x42, 0x8e, 0x04, 0xdc, 0x8c, 0x05, 0xdc, 0xa2, 0x9b, 0xa0, 0x37, 0x4d, 0x13, 0x10, 0x0d, 0x10, 0x10, 0xf0, 0x04, 0xa2, 0x1b, 0xa0, 0x00, 0x8e, 0x11, 0xd0, 0x8c, 0x12, 0xd0, 0xad, 0x10, 0x10, 0xf0, 0x0a, 0xad, 0x11, 0x10, 0xf0, 0x05, 0xa2, 0xb2, 0x8e, 0x14, 0x03, 0xad, 0x0b, 0x10, 0xd0, 0x08, 0xa9, 0x81, 0x8d, 0x1a, 0xd0, 0x4c, 0x8c, 0x10, 0xa9, 0x81, 0xa2, 0x01, 0x8d, 0x0d, 0xdc, 0x8e, 0x0e, 0xdc, 0xad, 0x10, 0x10, 0xd0, 0x02, 0xa9, 0x37, 0x85, 0x01, 0xad, 0x14, 0x10, 0x48, 0xad, 0x0a, 0x10, 0x28, 0x20, 0x18, 0x10, 0xad, 0x10, 0x10, 0xf0, 0x0a, 0xad, 0x11, 0x10, 0xf0, 0x04, 0xa9, 0x37, 0x85, 0x01, 0x58, 0x4c, 0xaf, 0x10, 0xa5, 0x01, 0x48, 0xad, 0x11, 0x10, 0x85, 0x01, 0xa9, 0x00, 0x20, 0x15, 0x10, 0x68, 0x85, 0x01, 0xce, 0x19, 0xd0, 0xad, 0x0d, 0xdc, 0x68, 0xa8, 0x68, 0xaa, 0x68, 0x40, 0x02, 0x00, 0x00, 0x01, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x02, 0x82, 0x0e, 0x82, 0x03, 0x82, 0x22, 0x82, 0x09, 0x82, 0x11, 0x82, 0x03, 0x82, 0x0f, 0x82, 0x05, 0x82, 0x05, 0x22, 0x05, 0x82, 0x0a, 0x82, 0x0d, 0x82, 0x09, 0x82, 0x04, 0x82, 0x04, 0x82, 0x03, 0x82, 0x05, 0x82, 0x0a, 0x82, 0x06, 0x82, 0x07, 0x82, 0x00, 0x00, 0x00, 0x00, libsidplayfp-3.0.0/src/sidmd5.h0000644000175100017510000000261215175333711012013 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2026 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDMD5_H #define SIDMD5_H #include #include "libs/hashlib/md5.hpp" namespace libsidplayfp { /** * A wrapper around the md5 implementation that provides * an hex formatted digest */ class sidmd5 { private: hashlib::md5 m_md5; public: /** * Append a string to the message. */ inline void append(const uint8_t* data, int nbytes) { m_md5.update(data, data+nbytes); } /** * Return pointer to 32-byte hex fingerprint. */ inline std::string getDigest() { return m_md5.hexdigest(); } }; } #endif libsidplayfp-3.0.0/src/sidrandom.h0000644000175100017510000000251615175333711012611 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2013 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SIDRANDOM_H #define SIDRANDOM_H namespace libsidplayfp { /** * Simple thread-safe PRNG. */ class sidrandom { private: unsigned int m_seed; public: /** * Initialize PRNG. * * @param seed */ explicit sidrandom(unsigned int seed) : m_seed(seed * 1103515245 + 12345) {} /** * Generate new pseudo-random number. */ unsigned int next() { m_seed = m_seed * 13 + 1; return m_seed; } }; } #endif libsidplayfp-3.0.0/src/sidcxx11.h0000644000175100017510000000316015175333711012271 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2014-2024 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SIDCXX_H #define SIDCXX_H #ifdef HAVE_CONFIG_H # include "config.h" #endif #ifdef HAVE_CXX23 # define HAVE_CXX20 #endif #ifdef HAVE_CXX20 # define HAVE_CXX17 # define LIKELY [[ likely ]] # define UNLIKELY [[ unlikely ]] #else # define LIKELY # define UNLIKELY #endif #ifdef HAVE_CXX17 # define HAVE_CXX14 # define MAYBE_UNUSED [[ maybe_unused ]] #else # define MAYBE_UNUSED #endif #ifdef HAVE_CXX14 # define HAVE_CXX11 # define MAKE_UNIQUE(type) std::make_unique() # define MAKE_UNIQUE_ARGS(type, ...) std::make_unique(__VA_ARGS__) #else # define MAKE_UNIQUE(type) std::unique_ptr(new type()) # define MAKE_UNIQUE_ARGS(type, ...) std::unique_ptr(new type(__VA_ARGS__)) #endif #ifndef HAVE_CXX11 # error "This is not a C++11 compiler" #endif #endif libsidplayfp-3.0.0/src/simpleMixer.h0000644000175100017510000000715115175333711013127 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright (C) 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SIMPLEMIXER_H #define SIMPLEMIXER_H #include #ifdef __has_include # if __has_include() # include # endif #endif #include #ifdef __cpp_lib_math_constants # include #endif namespace libsidplayfp { /** * This class implements the mixer. */ class SimpleMixer { private: static constexpr int_least32_t SCALE_FACTOR = 1 << 16; #ifdef __cpp_lib_math_constants static constexpr double SQRT_2 = std::numbers::sqrt2; static constexpr double SQRT_3 = std::numbers::sqrt3; #else static constexpr double SQRT_2 = 1.41421356237; static constexpr double SQRT_3 = 1.73205080757; #endif static constexpr int_least32_t SCALE[3] = { SCALE_FACTOR, // 1 chip, no scale static_cast((1.0 / SQRT_2) * SCALE_FACTOR), // 2 chips, scale by sqrt(2) static_cast((1.0 / SQRT_3) * SCALE_FACTOR) // 3 chips, scale by sqrt(3) }; private: using mixer_func_t = int_least32_t (SimpleMixer::*)() const; private: std::vector m_buffers; std::vector m_iSamples; std::vector m_mix; private: void updateParams(); /* * Channel matrix * * C1 * L 1.0 * R 1.0 * * C1 C2 * L 1.0 0.5 * R 0.5 1.0 * * C1 C2 C3 * L 1.0 1.0 0.5 * R 0.5 1.0 1.0 */ // Mono mixing template int_least32_t mono() const { int_least32_t res = 0; for (int i = 0; i < Chips; i++) res += m_iSamples[i]; return res * SCALE[Chips-1] / SCALE_FACTOR; } // Stereo mixing int_least32_t stereo_OneChip() const { return m_iSamples[0]; } int_least32_t stereo_ch1_TwoChips() const { return (m_iSamples[0] + 0.5*m_iSamples[1]) * SCALE[1] / SCALE_FACTOR; } int_least32_t stereo_ch2_TwoChips() const { return (0.5*m_iSamples[0] + m_iSamples[1]) * SCALE[1] / SCALE_FACTOR; } int_least32_t stereo_ch1_ThreeChips() const { return (m_iSamples[0] + m_iSamples[1] + 0.5*m_iSamples[2]) * SCALE[2] / SCALE_FACTOR; } int_least32_t stereo_ch2_ThreeChips() const { return (0.5*m_iSamples[0] + m_iSamples[1] + m_iSamples[2]) * SCALE[2] / SCALE_FACTOR; } private: SimpleMixer() = delete; SimpleMixer(const SimpleMixer&) = delete; public: /** * Create a new mixer. */ SimpleMixer(bool stereo, short** buffers, int chips); /** * Do the mixing. */ unsigned int doMix(short *buffer, unsigned int samples); unsigned int channels() const { return m_mix.size(); } }; } #endif // MIXER_H libsidplayfp-3.0.0/src/psiddrv.cpp0000644000175100017510000002051615175333711012637 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2015 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // -------------------------------------------------------- // The code here is use to support the PSID Version 2NG // (proposal B) file format for player relocation support. // -------------------------------------------------------- #include "psiddrv.h" #include "sidplayfp/SidTuneInfo.h" #include "sidendian.h" #include "sidmemory.h" #include "reloc65.h" #include "c64/CPU/mos6510.h" namespace libsidplayfp { // Error Strings const char ERR_PSIDDRV_NO_SPACE[] = "ERROR: No space to install psid driver in C64 ram"; const char ERR_PSIDDRV_RELOC[] = "ERROR: Failed whilst relocating psid driver"; const uint8_t PSID_DRIVER[] = { # include "psiddrv.bin" }; const uint8_t POWERON[] = { # include "poweron.bin" }; /** * Copy in power on settings. These were created by running * the kernel reset routine and storing the useful values * from $0000-$03ff. Format is: * - offset byte (bit 7 indicates presence rle byte) * - rle count byte (bit 7 indicates compression used) * - data (single byte) or quantity represented by uncompressed count * all counts and offsets are 1 less than they should be */ void copyPoweronPattern(sidmemory& mem) { uint_least16_t addr = 0; for (unsigned int i = 0; i < sizeof(POWERON);) { uint8_t off = POWERON[i++]; uint8_t count = 0; bool compressed = false; // Determine data count/compression if (off & 0x80) { // fixup offset off &= 0x7f; count = POWERON[i++]; if (count & 0x80) { // fixup count count &= 0x7f; compressed = true; } } // Fix count off by ones (see format details) count++; addr += off; if (compressed) { // Extract compressed data const uint8_t data = POWERON[i++]; while (count-- > 0) { mem.writeMemByte(addr++, data); } } else { // Extract uncompressed data while (count-- > 0) { mem.writeMemByte(addr++, POWERON[i++]); } } } } uint8_t psiddrv::iomap(uint_least16_t addr) const { // Force Real C64 Compatibility if (m_tuneInfo->compatibility() == SidTuneInfo::COMPATIBILITY_R64 || m_tuneInfo->compatibility() == SidTuneInfo::COMPATIBILITY_BASIC || addr == 0) { // Special case, set to 0x37 by the psid driver return 0; } /* * $34 for init/play in $d000 - $dfff * $35 for init/play in $e000 - $ffff * $36 for load end/play in $a000 - $ffff * $37 for the rest */ if (addr < 0xa000) return 0x37; // Basic-ROM, Kernal-ROM, I/O if (addr < 0xd000) return 0x36; // Kernal-ROM, I/O if (addr >= 0xe000) return 0x35; // I/O only return 0x34; // RAM only } bool psiddrv::drvReloc() { const int startlp = m_tuneInfo->loadAddr() >> 8; const int endlp = (m_tuneInfo->loadAddr() + (m_tuneInfo->c64dataLen() - 1)) >> 8; uint_least8_t relocStartPage = m_tuneInfo->relocStartPage(); uint_least8_t relocPages = m_tuneInfo->relocPages(); if (m_tuneInfo->compatibility() == SidTuneInfo::COMPATIBILITY_BASIC) { // The psiddrv is only used for initialisation and to // autorun basic tunes as running the kernel falls // into a manual load/run mode relocStartPage = 0x04; relocPages = 0x03; } // Check for free space in tune if (relocStartPage == 0xff) relocPages = 0; // Check if we need to find the reloc addr else if (relocStartPage == 0) { relocPages = 0; // find area where to dump the driver in. // It's only 1 block long, so any free block we can find // between $0400 and $d000 will do. for (int i = 4; i < 0xd0; i ++) { if (i >= startlp && i <= endlp) continue; if (i >= 0xa0 && i <= 0xbf) continue; relocStartPage = i; relocPages = 1; break; } } if (relocPages < 1) { m_errorString = ERR_PSIDDRV_NO_SPACE; return false; } // Place psid driver into ram const uint_least16_t relocAddr = relocStartPage << 8; psid_driver.assign(std::begin(PSID_DRIVER), std::end(PSID_DRIVER)); reloc_driver = psid_driver.data(); reloc_size = psid_driver.size(); reloc65 relocator(relocAddr - 10); if (!relocator.reloc(&reloc_driver, &reloc_size)) { m_errorString = ERR_PSIDDRV_RELOC; return false; } // Adjust size to not include initialisation data. reloc_size -= 10; m_driverAddr = relocAddr; m_driverLength = static_cast(reloc_size); // Round length to end of page m_driverLength += 0xff; m_driverLength &= 0xff00; return true; } void psiddrv::install(sidmemory& mem, uint8_t video) const { mem.fillRam(0, static_cast(0), 0x3ff); if (m_tuneInfo->compatibility() >= SidTuneInfo::COMPATIBILITY_R64) { copyPoweronPattern(mem); } // Set PAL/NTSC switch mem.writeMemByte(0x02a6, video); mem.installResetHook(endian_little16(reloc_driver)); // If not a basic tune then the psiddrv must install // interrupt hooks and trap programs trying to restart basic if (m_tuneInfo->compatibility() == SidTuneInfo::COMPATIBILITY_BASIC) { // Install hook to set subtune number for basic mem.setBasicSubtune((uint8_t)(m_tuneInfo->currentSong() - 1)); mem.installBasicTrap(0xbf53); } else { // Only install irq handle for RSID tunes mem.fillRam(0x0314, &reloc_driver[2], m_tuneInfo->compatibility() == SidTuneInfo::COMPATIBILITY_R64 ? 2 : 6); // Experimental restart basic trap const uint_least16_t addr = endian_little16(&reloc_driver[8]); mem.installBasicTrap(0xffe1); mem.writeMemWord(0x0328, addr); } int pos = m_driverAddr; // Install driver to ram mem.fillRam(pos, &reloc_driver[10], reloc_size); // Set song number mem.writeMemByte(pos, (uint8_t) (m_tuneInfo->currentSong() - 1)); pos++; // Set tunes speed (VIC/CIA) mem.writeMemByte(pos, m_tuneInfo->songSpeed() == SidTuneInfo::SPEED_VBI ? 0 : 1); pos++; // Set init address mem.writeMemWord(pos, m_tuneInfo->compatibility() == SidTuneInfo::COMPATIBILITY_BASIC ? 0xbf55 : m_tuneInfo->initAddr()); pos += 2; // Set play address mem.writeMemWord(pos, m_tuneInfo->playAddr()); pos += 2; // Set init address io bank value mem.writeMemByte(pos, iomap(m_tuneInfo->initAddr())); pos++; // Set play address io bank value mem.writeMemByte(pos, iomap(m_tuneInfo->playAddr())); pos++; // Set PAL/NTSC flag mem.writeMemByte(pos, video); pos++; // Set the required tune clock speed uint8_t clockSpeed; switch (m_tuneInfo->clockSpeed()) { case SidTuneInfo::CLOCK_PAL: clockSpeed = 1; break; case SidTuneInfo::CLOCK_NTSC: clockSpeed = 0; break; default: // UNKNOWN or ANY clockSpeed = video; break; } mem.writeMemByte(pos, clockSpeed); pos++; // Set default processor register flags on calling init mem.writeMemByte(pos, m_tuneInfo->compatibility() >= SidTuneInfo::COMPATIBILITY_R64 ? 0 : 1 << MOS6510::SR_INTERRUPT); } } libsidplayfp-3.0.0/src/EventCallback.h0000644000175100017510000000336615175333711013333 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2011-2015 Leandro Nini * Copyright (C) 2009 Antti S. Lankila * Copyright (C) 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef EVENTCALLBACK_H #define EVENTCALLBACK_H #include "Event.h" #include "sidcxx11.h" namespace libsidplayfp { template< class This > class EventCallback final : public Event { private: using Callback = void (This::*)(); private: This &m_this; Callback const m_callback; private: void event() override { (m_this.*m_callback)(); } public: EventCallback(const char* const name, This &object, Callback callback) : Event(name), m_this(object), m_callback(callback) {} }; template< class This, void(This::*Callback)() > class FastEventCallback final : public Event { private: This &m_this; private: void event() override { (m_this.*Callback)(); } public: FastEventCallback(const char* const name, This &object) : Event(name), m_this(object) {} }; } #endif // EVENTCALLBACK_H libsidplayfp-3.0.0/src/Event.h0000644000175100017510000000361615175333711011714 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2015 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef EVENT_H #define EVENT_H #include namespace libsidplayfp { using event_clock_t = int_fast64_t; /** * An Event object that can be inserted in the Event Scheduler. */ class Event { friend class EventScheduler; private: /// The next event in sequence. Event *next; /// The clock this event fires. event_clock_t triggerTime; /// Describe event for humans. const char * const m_name; public: /** * Events are used for delayed execution. * * @param name Descriptive string of the event. */ Event(const char * const name) : m_name(name) {} /** * Event code to be executed. Events are allowed to safely * reschedule themselves with the EventScheduler during * invocations. */ virtual void event() = 0; /** * Get the event name. * Only for debugging purposes. */ const char* name() const { return m_name; } protected: ~Event() = default; }; } #endif // EVENT_H libsidplayfp-3.0.0/src/player.cpp0000644000175100017510000004015615175333711012462 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "player.h" #include "sidplayfp/SidTune.h" #include "sidplayfp/sidbuilder.h" #include "sidemu.h" #include "psiddrv.h" #include "romCheck.h" #include "sidcxx11.h" #include #include namespace libsidplayfp { // Speed strings const char TXT_PAL_VBI[] = "50 Hz VBI (PAL)"; const char TXT_PAL_VBI_FIXED[] = "60 Hz VBI (PAL FIXED)"; const char TXT_PAL_CIA[] = "CIA (PAL)"; const char TXT_PAL_UNKNOWN[] = "UNKNOWN (PAL)"; const char TXT_NTSC_VBI[] = "60 Hz VBI (NTSC)"; const char TXT_NTSC_VBI_FIXED[] = "50 Hz VBI (NTSC FIXED)"; const char TXT_NTSC_CIA[] = "CIA (NTSC)"; const char TXT_NTSC_UNKNOWN[] = "UNKNOWN (NTSC)"; // Error Strings const char ERR_NA[] = "NA"; const char ERR_NO_TUNE_LOADED[] = "SIDPLAYER ERROR: No tune loaded"; const char ERR_UNSUPPORTED_FREQ[] = "SIDPLAYER ERROR: Unsupported sampling frequency."; const char ERR_UNSUPPORTED_SID_ADDR[] = "SIDPLAYER ERROR: Unsupported SID address."; const char ERR_UNSUPPORTED_SIZE[] = "SIDPLAYER ERROR: Size of music data exceeds C64 memory."; const char ERR_INVALID_PERCENTAGE[] = "SIDPLAYER ERROR: Percentage value out of range."; const char ERR_BAD_BUF_SIZE[] = "SIDPLAYER ERROR: Bad buffer size"; const char ERR_INVALID_CONF[] = "SIDPLAYER ERROR: Invalid configuration"; // Limit to roughly 20ms constexpr unsigned int MAX_CYCLES = 20000; /** * Configuration error exception. */ class configError { private: const char* m_msg; public: configError(const char* msg) : m_msg(msg) {} const char* message() const { return m_msg; } }; Player::Player() : // Set default settings for system m_tune(nullptr), m_errorString(ERR_NA), m_rand((unsigned int)std::time(nullptr)) { // We need at least some minimal interrupt handling m_c64.getMemInterface().setKernal(nullptr); config(m_cfg); // Get component credits m_info.m_credits.push_back(m_c64.cpuCredits()); m_info.m_credits.push_back(m_c64.ciaCredits()); m_info.m_credits.push_back(m_c64.vicCredits()); } template inline void checkRom(const uint8_t* rom, std::string &desc) { if (rom != nullptr) { T romCheck(rom); desc.assign(romCheck.info()); } else desc.clear(); } void Player::setKernal(const uint8_t* rom) { checkRom(rom, m_info.m_kernalDesc); m_c64.getMemInterface().setKernal(rom); } void Player::setBasic(const uint8_t* rom) { checkRom(rom, m_info.m_basicDesc); m_c64.getMemInterface().setBasic(rom); } void Player::setChargen(const uint8_t* rom) { checkRom(rom, m_info.m_chargenDesc); m_c64.getMemInterface().setChargen(rom); } void Player::initialise() { m_c64.reset(); const SidTuneInfo* tuneInfo = m_tune->getInfo(); const uint_least32_t size = static_cast(tuneInfo->loadAddr()) + tuneInfo->c64dataLen() - 1; if (size > 0xffff) UNLIKELY { throw configError(ERR_UNSUPPORTED_SIZE); } uint_least16_t powerOnDelay = m_cfg.powerOnDelay; // Delays above MAX result in random delays if (powerOnDelay > SidConfig::MAX_POWER_ON_DELAY) { // Limit the delay to something sensible. powerOnDelay = (uint_least16_t)((m_rand.next() >> 3) & SidConfig::MAX_POWER_ON_DELAY); } powerOnDelay += 8000; // Run for ~ [25000,50000] cycles for (int i = 0; i < powerOnDelay; i++) { for (int j = 0; j < 3; j++) m_c64.clock(); for (sidemu* chip: m_chips) { chip->clock(); chip->bufferpos(0); } } psiddrv driver(m_tune->getInfo()); if (!driver.drvReloc()) UNLIKELY { throw configError(driver.errorString()); } m_info.m_driverAddr = driver.driverAddr(); m_info.m_driverLength = driver.driverLength(); m_info.m_powerOnDelay = powerOnDelay; driver.install(m_c64.getMemInterface(), m_videoSwitch); if (!m_tune->placeSidTuneInC64mem(m_c64.getMemInterface())) UNLIKELY { throw configError(m_tune->statusString()); } m_c64.resetCpu(); #if 0 // Run for some cycles until the initialization routine is done for (int j = 0; j < 50; j++) m_c64.clock(); for (sidemu* chip: m_chips) { chip->clock(); chip->bufferpos(0); } #endif m_startTime = m_c64.getTimeMs(); } bool Player::load(SidTune *tune) { m_tune = tune; if (tune != nullptr) UNLIKELY { // Must re-configure on fly for stereo support! if (!config(m_cfg, true)) UNLIKELY { // Failed configuration with new tune, reject it m_tune = nullptr; return false; } } return true; } void Player::mute(unsigned int sidNum, unsigned int voice, bool enable) { if (sidemu *s = (sidNum < m_chips.size()) ? m_chips[sidNum] : nullptr) s->voice(voice, enable); } void Player::filter(unsigned int sidNum, bool enable) { if (sidemu *s = (sidNum < m_chips.size()) ? m_chips[sidNum] : nullptr) s->filter(enable); } void Player::initMixer(bool stereo) { std::unique_ptr bufs(new short*[m_chips.size()]); buffers(bufs.get()); m_simpleMixer.reset(new SimpleMixer(stereo, bufs.get(), installedSIDs())); } unsigned int Player::mix(short *buffer, unsigned int samples) { return m_simpleMixer->doMix(buffer, samples); } void Player::buffers(short** buffers) const { for (size_t i = 0; i < m_chips.size(); i++) { buffers[i] = m_chips[i]->buffer(); } } int Player::play(unsigned int cycles) { // Make sure a tune is loaded if (m_tune == nullptr) UNLIKELY { m_errorString = ERR_NO_TUNE_LOADED; return -1; } if (cycles > MAX_CYCLES) { cycles = MAX_CYCLES; } try { for (unsigned int i = 0; i < cycles; i++) m_c64.clock(); int sampleCount = 0; for (sidemu *s: m_chips) { // clock the chip and get the buffer // buffersize is expected to be the same // for all chips s->clock(); sampleCount = s->bufferpos(); // Reset the buffer s->bufferpos(0); } return sampleCount; } catch (MOS6510::haltInstruction const &ill) { m_errorString = ill.message(); return -1; } } bool Player::reset() { try { initialise(); return true; } catch (configError const &) { return false; } } c64::cia_model_t getCiaModel(SidConfig::cia_model_t model) { switch (model) { default: case SidConfig::MOS6526: return c64::OLD; case SidConfig::MOS8521: return c64::NEW; case SidConfig::MOS6526W4485: return c64::OLD_4485; } } bool Player::config(const SidConfig &cfg, bool force) { // Check if configuration have been changed or forced if (!force && !m_cfg.compare(cfg)) { return true; } // Check for a sane sampling frequency if ((cfg.frequency < 8000) || (cfg.frequency > 192000)) UNLIKELY { m_errorString = ERR_UNSUPPORTED_FREQ; return false; } // Only do these if we have a loaded tune if (m_tune != nullptr) { const SidTuneInfo* tuneInfo = m_tune->getInfo(); try { sidRelease(); std::vector addresses; const uint_least16_t secondSidAddress = tuneInfo->sidChipBase(1) != 0 ? tuneInfo->sidChipBase(1) : cfg.secondSidAddress; if (secondSidAddress != 0) addresses.push_back(secondSidAddress); const uint_least16_t thirdSidAddress = tuneInfo->sidChipBase(2) != 0 ? tuneInfo->sidChipBase(2) : cfg.thirdSidAddress; if (thirdSidAddress != 0) addresses.push_back(thirdSidAddress); // SID emulation setup (must be performed before the // environment setup call) sidCreate(cfg.sidEmulation, cfg.defaultSidModel, cfg.digiBoost, cfg.forceSidModel, addresses); // Determine c64 model const c64::model_t model = c64model(cfg.defaultC64Model, cfg.forceC64Model); m_c64.setModel(model); const c64::cia_model_t ciaModel = getCiaModel(cfg.ciaModel); m_c64.setCiaModel(ciaModel); sidParams(m_c64.getMainCpuSpeed(), cfg.frequency, cfg.samplingMethod); // Configure, setup and install C64 environment/events initialise(); } catch (configError const &e) { sidRelease(); m_errorString = e.message(); m_cfg.sidEmulation = nullptr; if (&m_cfg != &cfg) { config(m_cfg); } return false; } } // Update Configuration m_cfg = cfg; return true; } // Clock speed changes due to loading a new song c64::model_t Player::c64model(SidConfig::c64_model_t defaultModel, bool forced) { const SidTuneInfo* tuneInfo = m_tune->getInfo(); SidTuneInfo::clock_t clockSpeed = tuneInfo->clockSpeed(); c64::model_t model; // Use preferred speed if forced or if song speed is unknown if (forced || (clockSpeed == SidTuneInfo::CLOCK_UNKNOWN) || (clockSpeed == SidTuneInfo::CLOCK_ANY)) { switch (defaultModel) { case SidConfig::PAL: clockSpeed = SidTuneInfo::CLOCK_PAL; model = c64::PAL_B; m_videoSwitch = 1; break; case SidConfig::DREAN: clockSpeed = SidTuneInfo::CLOCK_PAL; model = c64::PAL_N; m_videoSwitch = 1; // TODO verify break; case SidConfig::NTSC: clockSpeed = SidTuneInfo::CLOCK_NTSC; model = c64::NTSC_M; m_videoSwitch = 0; break; case SidConfig::OLD_NTSC: clockSpeed = SidTuneInfo::CLOCK_NTSC; model = c64::OLD_NTSC_M; m_videoSwitch = 0; break; case SidConfig::PAL_M: clockSpeed = SidTuneInfo::CLOCK_NTSC; model = c64::PAL_M; m_videoSwitch = 0; // TODO verify break; } } else { switch (clockSpeed) { default: case SidTuneInfo::CLOCK_PAL: model = c64::PAL_B; m_videoSwitch = 1; break; case SidTuneInfo::CLOCK_NTSC: model = c64::NTSC_M; m_videoSwitch = 0; break; } } switch (clockSpeed) { case SidTuneInfo::CLOCK_PAL: if (tuneInfo->songSpeed() == SidTuneInfo::SPEED_CIA_1A) m_info.m_speedString = TXT_PAL_CIA; else if (tuneInfo->clockSpeed() == SidTuneInfo::CLOCK_NTSC) m_info.m_speedString = TXT_PAL_VBI_FIXED; else m_info.m_speedString = TXT_PAL_VBI; break; case SidTuneInfo::CLOCK_NTSC: if (tuneInfo->songSpeed() == SidTuneInfo::SPEED_CIA_1A) m_info.m_speedString = TXT_NTSC_CIA; else if (tuneInfo->clockSpeed() == SidTuneInfo::CLOCK_PAL) m_info.m_speedString = TXT_NTSC_VBI_FIXED; else m_info.m_speedString = TXT_NTSC_VBI; break; default: break; } return model; } SidTuneInfo::model_t getSidModel(SidConfig::sid_model_t sidModel) { switch (sidModel) { case SidConfig::MOS6581: return SidTuneInfo::SIDMODEL_6581; case SidConfig::MOS8580: return SidTuneInfo::SIDMODEL_8580; default: return SidTuneInfo::SIDMODEL_UNKNOWN; } } /** * Get the SID model. * * @param sidModel the tune requested model * @param defaultModel the default model * @param forced true if the default model shold be forced in spite of tune model */ SidConfig::sid_model_t getSidModel(SidTuneInfo::model_t sidModel, SidConfig::sid_model_t defaultModel, bool forced) { SidTuneInfo::model_t tuneModel = sidModel; // Use preferred speed if forced or if song speed is unknown if (forced || tuneModel == SidTuneInfo::SIDMODEL_UNKNOWN || tuneModel == SidTuneInfo::SIDMODEL_ANY) { switch (defaultModel) { case SidConfig::MOS6581: tuneModel = SidTuneInfo::SIDMODEL_6581; break; case SidConfig::MOS8580: tuneModel = SidTuneInfo::SIDMODEL_8580; break; default: break; } } switch (tuneModel) { default: case SidTuneInfo::SIDMODEL_6581: return SidConfig::MOS6581; case SidTuneInfo::SIDMODEL_8580: return SidConfig::MOS8580; } } void Player::sidRelease() { m_c64.clearSids(); for (sidemu *s: m_chips) { if (sidbuilder *b = s->builder()) { b->unlock(s); } } m_chips.clear(); } void Player::sidCreate(sidbuilder *builder, SidConfig::sid_model_t defaultModel, bool digiboost, bool forced, const std::vector &extraSidAddresses) { if (builder != nullptr) { m_chips.clear(); m_info.m_sidModels.clear(); const SidTuneInfo* tuneInfo = m_tune->getInfo(); // Setup base SID const SidConfig::sid_model_t userModel = getSidModel(tuneInfo->sidModel(0), defaultModel, forced); sidemu *s = builder->lock(m_c64.getEventScheduler(), userModel, digiboost); if (!s) UNLIKELY { throw configError(builder->error()); } m_c64.setBaseSid(s); m_chips.push_back(s); m_info.m_sidModels.push_back(getSidModel(userModel)); // Setup extra SIDs if needed if (extraSidAddresses.size() != 0) { // If bits 6-7 are set to Unknown then the second SID will be set to the same SID // model as the first SID. defaultModel = userModel; const unsigned int extraSidChips = extraSidAddresses.size(); for (unsigned int i = 0; i < extraSidChips; i++) { const SidConfig::sid_model_t userModel = getSidModel(tuneInfo->sidModel(i+1), defaultModel, forced); sidemu *s = builder->lock(m_c64.getEventScheduler(), userModel, digiboost); if (!s) UNLIKELY { throw configError(builder->error()); } if (!m_c64.addExtraSid(s, extraSidAddresses[i])) UNLIKELY throw configError(ERR_UNSUPPORTED_SID_ADDR); m_chips.push_back(s); m_info.m_sidModels.push_back(getSidModel(userModel)); } } } } void Player::sidParams(double cpuFreq, int frequency, SidConfig::sampling_method_t sampling) { for (sidemu *s: m_chips) { s->sampling((float)cpuFreq, frequency, sampling); } } bool Player::getSidStatus(unsigned int sidNum, uint8_t regs[32]) { if (sidNum >= m_chips.size()) return false; m_chips[sidNum]->getStatus(regs); return true; } int Player::getBufSize(unsigned int cycles) { if (!m_simpleMixer) return 0; if (cycles > MAX_CYCLES) { cycles = MAX_CYCLES; } double size = static_cast(m_cfg.frequency) / m_c64.getMainCpuSpeed() * cycles; return static_cast(std::ceil(size)) * m_simpleMixer->channels(); } } libsidplayfp-3.0.0/src/EventScheduler.cpp0000644000175100017510000000305015175333711014076 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2011-2014 Leandro Nini * Copyright (C) 2009 Antti S. Lankila * Copyright (C) 2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "EventScheduler.h" namespace libsidplayfp { void EventScheduler::reset() { firstEvent = nullptr; currentTime = 0; } void EventScheduler::cancel(const Event &event) { Event **scan = &firstEvent; while (*scan != nullptr) { if (&event == *scan) { *scan = (*scan)->next; break; } scan = &((*scan)->next); } } bool EventScheduler::isPending(const Event &event) const { const Event *scan = firstEvent; while (scan != nullptr) { if (&event == scan) { return true; } scan = scan->next; } return false; } } libsidplayfp-3.0.0/src/poweron.bin0000644000175100017510000000336115175333711012642 /* addr, off, rle, values */ /*$0003*/ 0x83, 0x04, 0xaa, 0xb1, 0x91, 0xb3, 0x22, /*$000b*/ 0x03, 0x4c, /*$000f*/ 0x03, 0x04, /*$0016*/ 0x86, 0x05, 0x19, 0x16, 0x00, 0x0a, 0x76, 0xa3, /*$0022*/ 0x86, 0x03, 0x40, 0xa3, 0xb3, 0xbd, /*$002b*/ 0x85, 0x01, 0x01, 0x08, /*$0034*/ 0x07, 0xa0, /*$0038*/ 0x03, 0xa0, /*$003a*/ 0x01, 0xff, /*$0042*/ 0x07, 0x08, /*$0047*/ 0x04, 0x24, /*$0053*/ 0x8b, 0x01, 0x03, 0x4c, /*$0061*/ 0x0c, 0x8d, /*$0063*/ 0x02, 0x10, /*$0069*/ 0x84, 0x02, 0x8c, 0xff, 0xa0, /*$0071*/ 0x85, 0x1e, 0x0a, 0xa3, 0xe6, 0x7a, 0xd0, 0x02, 0xe6, 0x7b, 0xad, 0x00, 0x08, 0xc9, 0x3a, 0xb0, 0x0a, 0xc9, 0x20, 0xf0, 0xef, 0x38, 0xe9, 0x30, 0x38, 0xe9, 0xd0, 0x60, 0x80, 0x4f, 0xc7, 0x52, 0x58, /*$0091*/ 0x01, 0xff, /*$009a*/ 0x08, 0x03, /*$00b2*/ 0x97, 0x01, 0x3c, 0x03, /*$00c2*/ 0x8e, 0x03, 0xa0, 0x30, 0xfd, 0x01, /*$00c8*/ 0x82, 0x82, 0x03, /*$00cb*/ 0x80, 0x81, 0x01, /*$00ce*/ 0x01, 0x20, /*$00d1*/ 0x82, 0x01, 0x18, 0x05, /*$00d5*/ 0x82, 0x02, 0x27, 0x07, 0x0d, /*$00d9*/ 0x81, 0x86, 0x84, /*$00e0*/ 0x80, 0x85, 0x85, /*$00e6*/ 0x80, 0x86, 0x86, /*$00ed*/ 0x80, 0x85, 0x87, /*$00f3*/ 0x80, 0x03, 0x18, 0xd9, 0x81, 0xeb, /*$0176*/ 0x7f, 0x00, /*$01f6*/ 0x7f, 0x00, /*$0276*/ 0x7f, 0x00, /*$0282*/ 0x8b, 0x0a, 0x08, 0x00, 0xa0, 0x00, 0x0e, 0x00, 0x04, 0x0a, 0x00, 0x04, 0x10, /*$028f*/ 0x82, 0x01, 0x48, 0xeb, /*$0300*/ 0xef, 0x0b, 0x8b, 0xe3, 0x83, 0xa4, 0x7c, 0xa5, 0x1a, 0xa7, 0xe4, 0xa7, 0x86, 0xae, /*$0310*/ 0x84, 0x02, 0x4c, 0x48, 0xb2, /*$0314*/ 0x81, 0x1f, 0x31, 0xea, 0x66, 0xfe, 0x47, 0xfe, 0x4a, 0xf3, 0x91, 0xf2, 0x0e, 0xf2, 0x50, 0xf2, 0x33, 0xf3, 0x57, 0xf1, 0xca, 0xf1, 0xed, 0xf6, 0x3e, 0xf1, 0x2f, 0xf3, 0x66, 0xfe, 0xa5, 0xf4, 0xed, 0xf5, /*Total 217*/ libsidplayfp-3.0.0/src/player.h0000644000175100017510000001010715175333711012120 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef PLAYER_H #define PLAYER_H #include #include #include "sidplayfp/siddefs.h" #include "sidplayfp/SidConfig.h" #include "sidplayfp/SidTuneInfo.h" #include "SidInfoImpl.h" #include "sidrandom.h" #include "simpleMixer.h" #include "c64/c64.h" #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include class SidTune; class SidInfo; class sidbuilder; namespace libsidplayfp { class sidemu; class Player { private: /// Commodore 64 emulator c64 m_c64; /// Emulator info SidTune *m_tune; /// User Configuration Settings SidInfoImpl m_info; /// User Configuration Settings SidConfig m_cfg; /// Error message std::string m_errorString; sidrandom m_rand; uint_least32_t m_startTime = 0; /// PAL/NTSC switch value uint8_t m_videoSwitch; std::vector m_chips; std::unique_ptr m_simpleMixer; private: /** * Get the C64 model for the current loaded tune. * * @param defaultModel the default model * @param forced true if the default model shold be forced in spite of tune model */ c64::model_t c64model(SidConfig::c64_model_t defaultModel, bool forced); /** * Initialize the emulation. * * @throw configError */ void initialise(); /** * Release the SID builders. */ void sidRelease(); /** * Create the SID emulation(s). * * @throw configError */ void sidCreate(sidbuilder *builder, SidConfig::sid_model_t defaultModel, bool digiboost, bool forced, const std::vector &extraSidAddresses); /** * Set the SID emulation parameters. * * @param cpuFreq the CPU clock frequency * @param frequency the output sampling frequency * @param sampling the sampling method to use */ void sidParams(double cpuFreq, int frequency, SidConfig::sampling_method_t sampling); inline void run(unsigned int events); public: Player(); ~Player() = default; const SidConfig &config() const { return m_cfg; } const SidInfo &info() const { return m_info; } bool config(const SidConfig &cfg, bool force=false); bool load(SidTune *tune); void buffers(short** buffers) const; int play(unsigned int cycles); uint_least32_t timeMs() const { return m_c64.getTimeMs() - m_startTime; } void debug(const bool enable, FILE *out) { m_c64.debug(enable, out); } void mute(unsigned int sidNum, unsigned int voice, bool enable); void filter(unsigned int sidNum, bool enable); const char *error() const { return m_errorString.c_str(); } void setKernal(const uint8_t* rom); void setBasic(const uint8_t* rom); void setChargen(const uint8_t* rom); uint_least16_t getCia1TimerA() const { return m_c64.getCia1TimerA(); } bool getSidStatus(unsigned int sidNum, uint8_t regs[32]); unsigned int installedSIDs() const { return m_chips.size(); } void initMixer(bool stereo); unsigned int mix(short *buffer, unsigned int samples); bool reset(); int getBufSize(unsigned int cycles); }; } #endif // PLAYER_H libsidplayfp-3.0.0/src/psiddrv.a650000644000175100017510000001134715175333711012452 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2014 Leandro Nini * Copyright 2001-2004 Simon White * Copyright 2000 Dag Lem * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /*************************************************************************** * psiddrv.a65 - C64 Sid Player * * written by Dag Lem * modified by Simon White for use in the sidplayer SIDPlay2. * * Build with: * xa -R -G psiddrv.a65 -o psiddrv.o65 * od -v -An -w8 -tx1 psiddrv.o65 | sed -re 's/[[:alnum:]]+/0x&,/g' > psiddrv.bin ***************************************************************************/ ; entry address coldvec .word cold ; initial user interrupt vectors irqusr .word irqret ; These should never run brkusr .word exception nmiusr .word exception ; redirect basic restart vector ; to finish the init sequence ; (hooks in via stop function) stopusr .word setiomap playnum .byte 0 speed .byte 0 initvec .word 0 playvec .word 0 initiomap .byte 0 playiomap .byte 0 video .byte 0 clock .byte 0 flags .byte 0 ; init/play PSID play jmp (playvec) init jmp (initvec) ; cold start cold sei ; turn interrupts off and ; clear any pending irqs lda #$00 sta $d01a lda $d019 sta $d019 lda #$7f sta $dc0d sta $dd0d lda $dc0d lda $dd0d ; setup hardware ; maximum volume lda #$0f sta $d418 ; set CIA 1 Timer A to 50/60 Hz lda video beq ntsc pal ldx #$25 ldy #$40 jmp timer ntsc ldx #$95 ldy #$42 timer stx $dc04 sty $dc05 ; set VICII raster to line 311 for RSIDs ldx #$9b ldy #$37 ; we should use the proper values for ; the default raster, however if the tune ; is playing at the wrong speed (e.g. ; PAL at NTSC) use the compatibility ; raster instead to try make it work eor clock ora initiomap beq vicinit ; set VICII raster to line 0 for PSIDs ; (compatibility raster) ldx #$1b ldy #$00 vicinit stx $d011 sty $d012 ; don't override default irq handler for RSIDs lda initiomap beq irqinit ; if play address, override default irq vector so ; we reach our routine to handle play routine lda playiomap beq irqinit ldx # * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDTUNE_H #define SIDTUNE_H #include #include #include "sidplayfp/siddefs.h" class SidTuneInfo; namespace libsidplayfp { class SidTuneBase; class sidmemory; } /** * SidTune */ class SID_EXTERN SidTune { public: static const int MD5_LENGTH = 32; private: /// Filename extensions to append for various file types. static const char** fileNameExtensions; private: // ------------------------------------------------------------- libsidplayfp::SidTuneBase* tune; const char* m_statusString; bool m_status; public: // ---------------------------------------------------------------- typedef void (*LoaderFunc)(const char* fileName, std::vector& bufferRef); /** * Load a sidtune from a file. * * To retrieve data from standard input pass in filename "-". * If you want to override the default filename extensions use this * contructor. Please note, that if the specified "fileName" * does exist and the loader is able to determine its file format, * this function does not try to append any file name extension. * See "SidTune.cpp" for the default list of file name extensions. * You can specify "fileName = 0", if you do not want to * load a sidtune. You can later load one with open(). * * @param fileName * @param fileNameExt * @param separatorIsSlash */ SidTune(const char* fileName, const char **fileNameExt = 0, bool separatorIsSlash = false); /** * Load a sidtune from a file, using a file access callback. * * This function does the same as the above, except that it * accepts a callback function, which will be used to read * all files it accesses. * * @param loader * @param fileName * @param fileNameExt * @param separatorIsSlash */ SidTune(LoaderFunc loader, const char* fileName, const char **fileNameExt = 0, bool separatorIsSlash = false); /** * Load a single-file sidtune from a memory buffer. * Currently supported: PSID and MUS formats. * * @param oneFileFormatSidtune the buffer that contains song data * @param sidtuneLength length of the buffer */ SidTune(const uint_least8_t* oneFileFormatSidtune, uint_least32_t sidtuneLength); ~SidTune(); /** * The SidTune class does not copy the list of file name extensions, * so make sure you keep it. If the provided pointer is 0, the * default list will be activated. This is a static list which * is used by all SidTune objects. * * @param fileNameExt */ void setFileNameExtensions(const char **fileNameExt); /** * Load a sidtune into an existing object from a file. * * @param fileName * @param separatorIsSlash */ void load(const char* fileName, bool separatorIsSlash = false); /** * Load a sidtune into an existing object from a file, * using a file access callback. * * @param loader * @param fileName * @param separatorIsSlash */ void load(LoaderFunc loader, const char* fileName, bool separatorIsSlash = false); /** * Load a sidtune into an existing object from a buffer. * * @param sourceBuffer the buffer that contains song data * @param bufferLen length of the buffer */ void read(const uint_least8_t* sourceBuffer, uint_least32_t bufferLen); /** * Select sub-song. * * @param songNum the selected song (0 = default starting song) * @return active song number, 0 if no tune is loaded. */ unsigned int selectSong(unsigned int songNum); /** * Retrieve current active sub-song specific information. * * @return a pointer to #SidTuneInfo, 0 if no tune is loaded. The pointer must not be deleted. */ const SidTuneInfo* getInfo() const; /** * Select sub-song and retrieve information. * * @param songNum the selected song (0 = default starting song) * @return a pointer to #SidTuneInfo, 0 if no tune is loaded. The pointer must not be deleted. */ const SidTuneInfo* getInfo(unsigned int songNum); /** * Determine current state of object. * Upon error condition use #statusString to get a descriptive * text string. * * @return current state (true = okay, false = error) */ bool getStatus() const; /** * Error/status message of last operation. */ const char* statusString() const; /** * Copy sidtune into C64 memory (64 KB). */ bool placeSidTuneInC64mem(libsidplayfp::sidmemory& mem); /** * Calculates the MD5 hash of the tune, old method. * Not providing an md5 buffer will cause the internal one to be used. * If provided, buffer must be MD5_LENGTH + 1 * * @return a pointer to the buffer containing the md5 string, 0 if no tune is loaded. */ const char *createMD5(char *md5 = 0); /** * Calculates the MD5 hash of the tune, new method, introduced in HVSC#68. * Not providing an md5 buffer will cause the internal one to be used. * If provided, buffer must be MD5_LENGTH + 1 * * @return a pointer to the buffer containing the md5 string, 0 if no tune is loaded. */ const char *createMD5New(char *md5 = 0); const uint_least8_t* c64Data() const; private: // prevent copying SidTune(const SidTune&); SidTune& operator=(SidTune&); }; #endif /* SIDTUNE_H */ libsidplayfp-3.0.0/src/sidplayfp/sidbuilder.cpp0000644000175100017510000000367615175333711015315 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "sidbuilder.h" #include "sidemu.h" #include "sidcxx11.h" libsidplayfp::sidemu *sidbuilder::lock(libsidplayfp::EventScheduler *scheduler, SidConfig::sid_model_t model, bool digiboost) { // create new emu if (libsidplayfp::sidemu* sid = create()) { if (sid->lock(scheduler)) { sid->model(model, digiboost); sidobjs.insert(sid); return sid; } else delete sid; } // Unable to locate free SID m_errorBuffer.assign(name()).append(" ERROR: No available SIDs to lock"); return nullptr; } void sidbuilder::unlock(libsidplayfp::sidemu *device) { emuset_t::iterator it = sidobjs.find(device); if (it != sidobjs.end()) { (*it)->unlock(); // should we cache these for later use? delete *it; sidobjs.erase(it); } } void sidbuilder::remove() { for (auto sidobj: sidobjs) delete sidobj; sidobjs.clear(); } const char* sidbuilder::credits() const { return getCredits(); } libsidplayfp-3.0.0/src/sidplayfp/SidConfig.h0000644000175100017510000000771315175333711014475 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2024 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDCONFIG_H #define SIDCONFIG_H #include #include "sidplayfp/siddefs.h" class sidbuilder; /** * SidConfig * * An instance of this class is used to transport emulator settings * to and from the interface class. */ class SID_EXTERN SidConfig { public: /// SID chip model typedef enum { MOS6581, ///< Old SID (MOS 6581) MOS8580 ///< New SID (CSG 8580/MOS 6582) } sid_model_t; /// SID combined waveforms strength typedef enum { AVERAGE, WEAK, STRONG } sid_cw_t; /// CIA chip model typedef enum { MOS6526, ///< Old CIA with interrupts delayed by one cycle (MOS 6526/6526A) MOS8521, ///< New CIA (CSG 8521/MOS 6526 216A) MOS6526W4485 ///< Old CIA, peculiar batch with different serial port behavior (MOS 6526 4485) @since 2.2 } cia_model_t; /// C64 model typedef enum { PAL, ///< European PAL model (MOS 6569) NTSC, ///< American/Japanese NTSC model (MOS 6567 R8) OLD_NTSC, ///< Older NTSC model with different video chip revision (MOS 6567 R56A) DREAN, ///< Argentinian PAL-N model (MOS 6572) PAL_M ///< Brasilian PAL-M model (MOS 6573) } c64_model_t; /// Sampling method typedef enum { INTERPOLATE, ///< Interpolation RESAMPLE_INTERPOLATE ///< Resampling } sampling_method_t; public: /** * Maximum power on delay. * - Delays <= MAX produce constant results * - Delays > MAX produce random results */ static const uint_least16_t MAX_POWER_ON_DELAY = 0x1FFF; static const uint_least16_t DEFAULT_POWER_ON_DELAY = MAX_POWER_ON_DELAY + 1; static const uint_least32_t DEFAULT_SAMPLING_FREQ = 48000; public: /** * Intended c64 model when unknown or forced. */ c64_model_t defaultC64Model; /** * Force the model to #defaultC64Model ignoring tune's clock setting. */ bool forceC64Model; /** * Intended sid model when unknown or forced. */ sid_model_t defaultSidModel; /** * Force the sid model to #defaultSidModel. */ bool forceSidModel; /** * Enable digiboost when 8580 SID model is used. */ bool digiBoost; /** * Intended cia model. */ cia_model_t ciaModel; /** * Sampling frequency. */ uint_least32_t frequency; /** * Extra SID chips addresses. */ //@{ uint_least16_t secondSidAddress; uint_least16_t thirdSidAddress; //@} /** * Pointer to selected emulation, * reSIDfp, reSID, hardSID or exSID. */ sidbuilder *sidEmulation; /** * Power on delay cycles. */ uint_least16_t powerOnDelay; /** * Sampling method. */ sampling_method_t samplingMethod; /** * Compare two config objects. * * @return true if different */ bool compare(const SidConfig &config) const; public: SidConfig(); }; #endif // SIDCONFIG_H libsidplayfp-3.0.0/src/sidplayfp/SidInfo.h0000644000175100017510000000533115175333711014155 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SIDINFO_H #define SIDINFO_H #include #include "sidplayfp/siddefs.h" #include "sidplayfp/SidTuneInfo.h" /** * This interface is used to get sid engine informations. */ class SID_EXTERN SidInfo { public: /// Library name const char *name() const; /// Library version const char *version() const; /// Library credits //@{ unsigned int numberOfCredits() const; const char *credits(unsigned int i) const; //@} /// Address of the driver uint_least16_t driverAddr() const; /// Size of the driver in bytes uint_least16_t driverLength() const; /// Power on delay uint_least16_t powerOnDelay() const; /// Describes the speed current song is running at const char *speedString() const; /// Description of the laoded ROM images //@{ const char *kernalDesc() const; const char *basicDesc() const; const char *chargenDesc() const; //@} /// SID chips /// @since 2.16 //@{ unsigned int numberOfSIDs() const; SidTuneInfo::model_t sidModel(unsigned int i) const; //@} private: virtual const char *getName() const =0; virtual const char *getVersion() const =0; virtual unsigned int getNumberOfCredits() const =0; virtual const char *getCredits(unsigned int i) const =0; virtual uint_least16_t getDriverAddr() const =0; virtual uint_least16_t getDriverLength() const =0; virtual uint_least16_t getPowerOnDelay() const =0; virtual const char *getSpeedString() const =0; virtual const char *getKernalDesc() const =0; virtual const char *getBasicDesc() const =0; virtual const char *getChargenDesc() const =0; virtual unsigned int getNumberOfSIDs() const =0; virtual SidTuneInfo::model_t getSidModel(unsigned int i) const =0; protected: ~SidInfo() {} }; #endif /* SIDINFO_H */ libsidplayfp-3.0.0/src/sidplayfp/sidplayfp.h0000644000175100017510000001464015175333711014620 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDPLAYFP_H #define SIDPLAYFP_H #include #include #include "sidplayfp/siddefs.h" #include "sidplayfp/sidversion.h" class SidConfig; class SidTune; class SidInfo; class EventContext; // Private Sidplayer namespace libsidplayfp { class Player; } /** * sidplayfp */ class SID_EXTERN sidplayfp { private: libsidplayfp::Player &sidplayer; public: sidplayfp(); ~sidplayfp(); /** * Get the current engine configuration. * * @return a const reference to the current configuration. */ const SidConfig &config() const; /** * Get the current player informations. * * @return a const reference to the current info. */ const SidInfo &info() const; /** * Configure the engine. * Check #error for detailed message if something goes wrong. * * @param cfg the new configuration * @return true on success, false otherwise. */ bool config(const SidConfig &cfg); /** * Error message. * * @return string error message. */ const char *error() const; /** * Load a tune. * Check #error for detailed message if something goes wrong. * * @param tune the SidTune to load, 0 unloads current tune. * @return true on sucess, false otherwise. */ bool load(SidTune *tune); /** * Get the buffer pointers for each of the installed SID chip. * * @param buffers pointer to the array of buffer pointers. * @since 2.14 */ void buffers(short** buffers) const; /** * Run the emulation for selected number of cycles. * The value will be limited to a reasonable amount * if too large. * * @param cycles the number of cycles to run. * @return the number of produced samples or zero * for hardware devices. If negative an error occurred, * use #error() to get a detailed message. * @since 2.14 */ int play(unsigned int cycles); /** * Reinitialize the engine. * * @return false in case of error, use #error() * to get a detailed message. * @since 2.15 */ bool reset(); /** * Get the number of installed SID chips. * * @return the number of SID chips. * @since 2.14 */ unsigned int installedSIDs() const; /** * Initialize the mixer. * * @param stereo whether to mix in stereo or mono * @since 2.15 */ void initMixer(bool stereo); /** * Mix buffers. * * @param buffer the output buffer * @param samples number of samples to mix, returned from the #play(unsigned int) function * @return number of samples generated (samples for mono, samples*2 for stereo) * @since 2.15 */ unsigned int mix(short *buffer, unsigned int samples); /** * Control CPU tracing. * @note: Must be called before #reset * * @param enable enable/disable debugging. * @param out the file where to redirect the debug info. */ void debug(bool enable, FILE *out); /** * Mute/unmute a SID channel. * * @param sidNum the SID chip, 0 for the first one, 1 for the second or 2 for the third. * @param voice the channel to mute/unmute, 0 to 2 for the voices or 3 for samples. * @param enable true unmutes the channel, false mutes it. */ void mute(unsigned int sidNum, unsigned int voice, bool enable); /** * Enable/disable SID filter. * @note: Must be called after #config or it has no effect. * * @param sidNum the SID chip, 0 for the first one, 1 for the second or 2 for the third. * @param enable true enable the filter, false disable it. * @since 2.10 */ void filter(unsigned int sidNum, bool enable); /** * Get the current playing time. * * @return the current playing time measured in seconds. */ uint_least32_t time() const; /** * Get the current playing time. * * @return the current playing time measured in milliseconds. * @since 2.0 */ uint_least32_t timeMs() const; /** * Set ROM images. * * @param kernal pointer to Kernal ROM. * @param basic pointer to Basic ROM, generally needed only for BASIC tunes. * @param character pointer to character generator ROM. */ void setRoms(const uint8_t* kernal, const uint8_t* basic=0, const uint8_t* character=0); /** * Set the ROM banks. * * @param rom pointer to the ROM data. * @since 2.2 */ //@{ void setKernal(const uint8_t* rom); void setBasic(const uint8_t* rom); void setChargen(const uint8_t* rom); //@} /** * Get the CIA 1 Timer A programmed value. */ uint_least16_t getCia1TimerA() const; /** * Get the SID registers programmed value. * * @param sidNum the SID chip, 0 for the first one, 1 for the second and 2 for the third. * @param regs an array that will be filled with the last values written to the chip. * @return false if the requested chip doesn't exist. * @since 2.2 */ bool getSidStatus(unsigned int sidNum, uint8_t regs[32]); /** * Get the required size of the buffer for the number of cycles to run, * approximate value by excess. * The mixer must have been initialized before with #initMixer * * @param cycles the number of cycles. * @return size of buffer in bytes or zero if the mixer has not been initialized. * @since 3.0 */ int getBufSize(unsigned int cycles); }; #endif // SIDPLAYFP_H libsidplayfp-3.0.0/src/sidplayfp/sidversion.h.in0000644000175100017510000000041615175333711015413 #ifndef LIBSIDPLAYFP_VERSION_H #define LIBSIDPLAYFP_VERSION_H #ifndef SIDPLAYFP_H # error Do not include directly. #endif #define LIBSIDPLAYFP_VERSION_MAJ @LIB_MAJOR@ #define LIBSIDPLAYFP_VERSION_MIN @LIB_MINOR@ #define LIBSIDPLAYFP_VERSION_LEV @LIB_LEVEL@ #endif libsidplayfp-3.0.0/src/sidplayfp/SidConfig.cpp0000644000175100017510000000371615175333711015027 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "SidConfig.h" #include "sidcxx11.h" SidConfig::SidConfig() : defaultC64Model(PAL), forceC64Model(false), defaultSidModel(MOS8580), forceSidModel(false), digiBoost(false), ciaModel(MOS8521), frequency(DEFAULT_SAMPLING_FREQ), secondSidAddress(0), thirdSidAddress(0), sidEmulation(nullptr), powerOnDelay(DEFAULT_POWER_ON_DELAY), samplingMethod(RESAMPLE_INTERPOLATE) {} bool SidConfig::compare(const SidConfig &config) const { return defaultC64Model != config.defaultC64Model || forceC64Model != config.forceC64Model || defaultSidModel != config.defaultSidModel || forceSidModel != config.forceSidModel || digiBoost != config.digiBoost || ciaModel != config.ciaModel || frequency != config.frequency || secondSidAddress != config.secondSidAddress || thirdSidAddress != config.thirdSidAddress || sidEmulation != config.sidEmulation || powerOnDelay != config.powerOnDelay || samplingMethod != config.samplingMethod; } libsidplayfp-3.0.0/src/sidplayfp/SidTuneInfo.h0000644000175100017510000001372315175333711015015 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2017 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SIDTUNEINFO_H #define SIDTUNEINFO_H #include #include "sidplayfp/siddefs.h" /** * This interface is used to get values from SidTune objects. * * You must read (i.e. activate) sub-song specific information * via: * const SidTuneInfo* tuneInfo = SidTune.getInfo(); * const SidTuneInfo* tuneInfo = SidTune.getInfo(songNumber); */ class SID_EXTERN SidTuneInfo { public: typedef enum { CLOCK_UNKNOWN, CLOCK_PAL, CLOCK_NTSC, CLOCK_ANY } clock_t; typedef enum { SIDMODEL_UNKNOWN, SIDMODEL_6581, SIDMODEL_8580, SIDMODEL_ANY } model_t; typedef enum { COMPATIBILITY_C64, ///< File is C64 compatible COMPATIBILITY_PSID, ///< File is PSID specific COMPATIBILITY_R64, ///< File is Real C64 only COMPATIBILITY_BASIC ///< File requires C64 Basic } compatibility_t; public: /// Vertical-Blanking-Interrupt static const int SPEED_VBI = 0; /// CIA 1 Timer A static const int SPEED_CIA_1A = 60; public: /** * Load Address. */ uint_least16_t loadAddr() const; /** * Init Address. */ uint_least16_t initAddr() const; /** * Play Address. */ uint_least16_t playAddr() const; /** * The number of songs. */ unsigned int songs() const; /** * The default starting song. */ unsigned int startSong() const; /** * The tune that has been initialized. */ unsigned int currentSong() const; /** * @name Base addresses * The SID chip base address(es) used by the sidtune. * - 0xD400 for the 1st SID * - 0 if the nth SID is not required */ uint_least16_t sidChipBase(unsigned int i) const; /** * The number of SID chips required by the tune. */ int sidChips() const; /** * Intended speed. */ int songSpeed() const; /** * First available page for relocation. */ uint_least8_t relocStartPage() const; /** * Number of pages available for relocation. */ uint_least8_t relocPages() const; /** * @name SID model * The SID chip model(s) requested by the sidtune. */ model_t sidModel(unsigned int i) const; /** * Compatibility requirements. */ compatibility_t compatibility() const; /** * @name Tune infos * Song title, credits, ... * - 0 = Title * - 1 = Author * - 2 = Released */ //@{ unsigned int numberOfInfoStrings() const; ///< The number of available text info lines const char* infoString(unsigned int i) const; ///< Text info from the format headers etc. //@} /** * @name Tune comments * MUS comments. */ //@{ unsigned int numberOfCommentStrings() const; ///< Number of comments const char* commentString(unsigned int i) const; ///< Used to stash the MUS comment somewhere //@} /** * Length of single-file sidtune file. */ uint_least32_t dataFileLen() const; /** * Length of raw C64 data without load address. */ uint_least32_t c64dataLen() const; /** * The tune clock speed. */ clock_t clockSpeed() const; /** * The name of the identified file format. */ const char* formatString() const; /** * Whether load address might be duplicate. */ bool fixLoad() const; /** * Path to sidtune files. */ const char* path() const; /** * A first file: e.g. "foo.sid" or "foo.mus". */ const char* dataFileName() const; /** * A second file: e.g. "foo.str". * Returns 0 if none. */ const char* infoFileName() const; private: virtual uint_least16_t getLoadAddr() const =0; virtual uint_least16_t getInitAddr() const =0; virtual uint_least16_t getPlayAddr() const =0; virtual unsigned int getSongs() const =0; virtual unsigned int getStartSong() const =0; virtual unsigned int getCurrentSong() const =0; virtual uint_least16_t getSidChipBase(unsigned int i) const =0; virtual int getSidChips() const =0; virtual int getSongSpeed() const =0; virtual uint_least8_t getRelocStartPage() const =0; virtual uint_least8_t getRelocPages() const =0; virtual model_t getSidModel(unsigned int i) const =0; virtual compatibility_t getCompatibility() const =0; virtual unsigned int getNumberOfInfoStrings() const =0; virtual const char* getInfoString(unsigned int i) const =0; virtual unsigned int getNumberOfCommentStrings() const =0; virtual const char* getCommentString(unsigned int i) const =0; virtual uint_least32_t getDataFileLen() const =0; virtual uint_least32_t getC64dataLen() const =0; virtual clock_t getClockSpeed() const =0; virtual const char* getFormatString() const =0; virtual bool getFixLoad() const =0; virtual const char* getPath() const =0; virtual const char* getDataFileName() const =0; virtual const char* getInfoFileName() const =0; protected: ~SidTuneInfo() {} }; #endif /* SIDTUNEINFO_H */ libsidplayfp-3.0.0/src/sidplayfp/sidplayfp.cpp0000644000175100017510000000731115175333711015150 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ //--------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- // Redirection to private version of sidplayer (This method is called Cheshire Cat) // [ms: which is J. Carolan's name for a degenerate 'bridge'] // This interface can be directly replaced with a libsidplay1 or C interface wrapper. //--------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------- #include "sidplayfp.h" #include "player.h" sidplayfp::sidplayfp() : sidplayer(*(new libsidplayfp::Player)) {} sidplayfp::~sidplayfp() { delete &sidplayer; } bool sidplayfp::config(const SidConfig &cfg) { return sidplayer.config(cfg); } const SidConfig &sidplayfp::config() const { return sidplayer.config(); } void sidplayfp::buffers(short** buffers) const { sidplayer.buffers(buffers); } int sidplayfp::play(unsigned int cycles) { return sidplayer.play(cycles); } bool sidplayfp::reset() { return sidplayer.reset(); } bool sidplayfp::load(SidTune *tune) { return sidplayer.load(tune); } const SidInfo &sidplayfp::info() const { return sidplayer.info(); } uint_least32_t sidplayfp::time() const { return sidplayer.timeMs() / 1000; } uint_least32_t sidplayfp::timeMs() const { return sidplayer.timeMs(); } const char *sidplayfp::error() const { return sidplayer.error(); } void sidplayfp::mute(unsigned int sidNum, unsigned int voice, bool enable) { sidplayer.mute(sidNum, voice, enable); } void sidplayfp::filter(unsigned int sidNum, bool enable) { sidplayer.filter(sidNum, enable); } void sidplayfp::debug(bool enable, FILE *out) { sidplayer.debug(enable, out); } void sidplayfp::setKernal(const uint8_t* rom) { sidplayer.setKernal(rom); } void sidplayfp::setBasic(const uint8_t* rom) { sidplayer.setBasic(rom); } void sidplayfp::setChargen(const uint8_t* rom) { sidplayer.setChargen(rom); } void sidplayfp::setRoms(const uint8_t* kernal, const uint8_t* basic, const uint8_t* character) { setKernal(kernal); setBasic(basic); setChargen(character); } uint_least16_t sidplayfp::getCia1TimerA() const { return sidplayer.getCia1TimerA(); } bool sidplayfp::getSidStatus(unsigned int sidNum, uint8_t regs[32]) { return sidplayer.getSidStatus(sidNum, regs); } unsigned int sidplayfp::installedSIDs() const { return sidplayer.installedSIDs(); } void sidplayfp::initMixer(bool stereo) { return sidplayer.initMixer(stereo); } unsigned int sidplayfp::mix(short *buffer, unsigned int samples) { return sidplayer.mix(buffer, samples); } int sidplayfp::getBufSize(unsigned int cycles) { return sidplayer.getBufSize(cycles); } libsidplayfp-3.0.0/src/sidplayfp/SidInfo.cpp0000644000175100017510000000351515175333711014512 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "SidInfo.h" const char *SidInfo::name() const { return getName(); } const char *SidInfo::version() const { return getVersion(); } unsigned int SidInfo::numberOfCredits() const { return getNumberOfCredits(); } const char *SidInfo::credits(unsigned int i) const { return getCredits(i); } uint_least16_t SidInfo::driverAddr() const { return getDriverAddr(); } uint_least16_t SidInfo::driverLength() const { return getDriverLength(); } uint_least16_t SidInfo::powerOnDelay() const { return getPowerOnDelay(); } const char *SidInfo::speedString() const { return getSpeedString(); } const char *SidInfo::kernalDesc() const { return getKernalDesc(); } const char *SidInfo::basicDesc() const { return getBasicDesc(); } const char *SidInfo::chargenDesc() const { return getChargenDesc(); } unsigned int SidInfo::numberOfSIDs() const { return getNumberOfSIDs(); } SidTuneInfo::model_t SidInfo::sidModel(unsigned int i) const { return getSidModel(i); } libsidplayfp-3.0.0/src/sidplayfp/siddefs.h0000644000175100017510000000401715175333711014243 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2023 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDDEFS_H #define SIDDEFS_H /* DLL building support on win32 hosts */ #ifndef SID_EXTERN # ifdef DLL_EXPORT /* defined by libtool (if required) */ # define SID_EXTERN __declspec(dllexport) # endif # ifdef SID_DLL_IMPORT /* define if linking with this dll */ # define SID_EXTERN __declspec(dllimport) # endif # ifndef SID_EXTERN /* static linking or !_WIN32 */ # if (defined(__GNUC__) && (__GNUC__ >= 4)) || defined(__clang__) # define SID_EXTERN __attribute__ ((visibility("default"))) # else # define SID_EXTERN # endif # endif #endif /* Deprecated attributes */ #if __cplusplus >= 201402L # define SID_DEPRECATED [[deprecated]] #elif defined(_MSCVER) # define SID_DEPRECATED __declspec(deprecated) #elif defined(__GNUC__) || defined(__clang__) # define SID_DEPRECATED __attribute__ ((deprecated)) #else # define SID_DEPRECATED #endif /* Unused attributes */ #if __cplusplus >= 201703L # define SID_UNUSED [[maybe_unused]] #elif defined(__GNUC__) || defined(__clang__) # define SID_UNUSED __attribute__ ((unused)) #else # define SID_UNUSED #endif #endif /* SIDDEFS_H */ libsidplayfp-3.0.0/src/sidplayfp/SidTune.cpp0000644000175100017510000001062615175333711014533 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2021 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "SidTune.h" #include "sidtune/SidTuneBase.h" #include "sidcxx11.h" using namespace libsidplayfp; const char MSG_NO_ERRORS[] = "No errors"; // Default sidtune file name extensions. This selection can be overriden // by specifying a custom list in the constructor. const char* defaultFileNameExt[] = { // Preferred default file extension for single-file sidtunes // or sidtune description files in SIDPLAY INFOFILE format. ".sid", ".SID", // File extensions used (and created) by various C64 emulators and // related utilities. These extensions are recommended to be used as // a replacement for ".dat" in conjunction with two-file sidtunes. ".c64", ".prg", ".p00", ".C64", ".PRG", ".P00", // Stereo Sidplayer (.mus/.MUS ought not be included because // these must be loaded first; it sometimes contains the first // credit lines of a MUS/STR pair). ".str", ".STR", ".mus", ".MUS", // End. nullptr }; const char** SidTune::fileNameExtensions = defaultFileNameExt; SidTune::SidTune(const char* fileName, const char **fileNameExt, bool separatorIsSlash) : SidTune(nullptr, fileName, fileNameExt, separatorIsSlash) { } SidTune::SidTune(LoaderFunc loader, const char* fileName, const char **fileNameExt, bool separatorIsSlash) : tune(nullptr) { setFileNameExtensions(fileNameExt); load(loader, fileName, separatorIsSlash); } SidTune::SidTune(const uint_least8_t* oneFileFormatSidtune, uint_least32_t sidtuneLength) : tune(nullptr) { read(oneFileFormatSidtune, sidtuneLength); } SidTune::~SidTune() { delete tune; } void SidTune::setFileNameExtensions(const char **fileNameExt) { fileNameExtensions = ((fileNameExt != nullptr) ? fileNameExt : defaultFileNameExt); } void SidTune::load(const char* fileName, bool separatorIsSlash) { load(nullptr, fileName, separatorIsSlash); } void SidTune::load(LoaderFunc loader, const char* fileName, bool separatorIsSlash) { try { delete tune; tune = SidTuneBase::load(loader, fileName, fileNameExtensions, separatorIsSlash); m_status = true; m_statusString = MSG_NO_ERRORS; } catch (loadError const &e) { tune = nullptr; m_status = false; m_statusString = e.message(); } } void SidTune::read(const uint_least8_t* sourceBuffer, uint_least32_t bufferLen) { try { delete tune; tune = SidTuneBase::read(sourceBuffer, bufferLen); m_status = true; m_statusString = MSG_NO_ERRORS; } catch (loadError const &e) { tune = nullptr; m_status = false; m_statusString = e.message(); } } unsigned int SidTune::selectSong(unsigned int songNum) { return tune != nullptr ? tune->selectSong(songNum) : 0; } const SidTuneInfo* SidTune::getInfo() const { return tune != nullptr ? tune->getInfo() : nullptr; } const SidTuneInfo* SidTune::getInfo(unsigned int songNum) { return tune != nullptr ? tune->getInfo(songNum) : nullptr; } bool SidTune::getStatus() const { return m_status; } const char* SidTune::statusString() const { return m_statusString; } bool SidTune::placeSidTuneInC64mem(sidmemory& mem) { if (tune == nullptr) return false; tune->placeSidTuneInC64mem(mem); return true; } const char* SidTune::createMD5(char *md5) { return tune != nullptr ? tune->createMD5(md5) : nullptr; } const char* SidTune::createMD5New(char *md5) { return tune != nullptr ? tune->createMD5New(md5) : nullptr; } const uint_least8_t* SidTune::c64Data() const { return tune != nullptr ? tune->c64Data() : nullptr; } libsidplayfp-3.0.0/src/sidplayfp/sidbuilder.h0000644000175100017510000000533115175333711014750 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2011-2025 Leandro Nini * Copyright 2007-2010 Antti Lankila * Copyright 2000-2001 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDBUILDER_H #define SIDBUILDER_H #include #include #include "sidplayfp/SidConfig.h" namespace libsidplayfp { class sidemu; class EventScheduler; } /** * Base class for sid builders. */ class sidbuilder { protected: typedef std::set emuset_t; private: const char * const m_name; protected: std::string m_errorBuffer; emuset_t sidobjs; protected: virtual libsidplayfp::sidemu* create() = 0; virtual const char *getCredits() const = 0; public: sidbuilder(const char * const name) : m_name(name), m_errorBuffer("N/A") {} virtual ~sidbuilder() {} /** * The number of used devices. * * @return number of used sids, 0 if none. */ unsigned int usedDevices() const { return sidobjs.size(); } /** * Find a free SID of the required specs * * @param scheduler the event scheduler * @param model the required sid model * @param digiboost whether to enable digiboost for 8580 * @return pointer to the locked sid, null if none is available */ libsidplayfp::sidemu *lock(libsidplayfp::EventScheduler *scheduler, SidConfig::sid_model_t model, bool digiboost); /** * Release this SID. * * @param device the sid to unlock */ void unlock(libsidplayfp::sidemu *device); /** * Remove all SID emulations. */ void remove(); /** * Get the builder's name. * * @return the name */ const char *name() const { return m_name; } /** * Error message. * * @return string error message. */ const char *error() const { return m_errorBuffer.c_str(); } /** * Get the builder's credits. * * @return credits */ const char *credits() const; }; #endif // SIDBUILDER_H libsidplayfp-3.0.0/src/reloc65.h0000644000175100017510000000434415175333711012111 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2013-2014 Leandro Nini * Copyright (C) 2001 Dag Lem * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Modified by Dag Lem Relocate and extract text segment from memory buffer instead of file. For use with VICE VSID. Ported to c++ and cut down for use in libsidplayfp by Leandro Nini */ #ifndef RELOC65_H #define RELOC65_H /** * reloc65 -- A part of xa65 - 65xx/65816 cross-assembler and utility suite * o65 file relocator. Trimmed down for our needs. */ class reloc65 { private: const int m_tbase; int m_tdiff; private: int reldiff(unsigned char s) const; /** * Relocate segment. * * @param buf segment * @param len segment size * @param rtab relocation table * @return a pointer to the next section */ unsigned char* reloc_seg(unsigned char *buf, int len, unsigned char *rtab); /** * Relocate exported globals list. * * @param buf exported globals list * @return a pointer to the next section */ unsigned char* reloc_globals(unsigned char *buf); public: /** * @param addr address of the segment to relocate */ explicit reloc65(int addr); /** * Do the relocation. * * @param buf beffer containing o65 data * @param fsize size of the data */ bool reloc(unsigned char **buf, int *fsize); }; #endif libsidplayfp-3.0.0/src/reloc65.cpp0000644000175100017510000001206615175333711012444 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright (C) 2013-2016 Leandro Nini * Copyright (C) 2001 Dag Lem * Copyright (C) 1989-1997 André Fachat (a.fachat@physik.tu-chemnitz.de) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "reloc65.h" #include #include "sidplayfp/siddefs.h" /// 16 bit header constexpr int HEADER_SIZE = (8 + 9 * 2); /// Magic number const unsigned char o65hdr[] = {1, 0, 'o', '6', '5'}; /** * Read a 16 bit word from a buffer at specific location. * * @param buffer * @param idx */ inline int getWord(const unsigned char *buffer, int idx) { return buffer[idx] | (buffer[idx+1] << 8); } /** * Write a 16 bit word into a buffer at specific location. * * @param buffer * @param idx * @param value */ inline void setWord(unsigned char *buffer, int idx, int value) { buffer[idx] = value & 0xff; buffer[idx+1] = (value >> 8) & 0xff; } /** * Get the size of header options section. * * @param buf */ inline int read_options(const unsigned char *buf) { int l = 0; unsigned char c = buf[0]; while (c) { l += c; c = buf[l]; } return ++l; } /** * Get the size of undefined references list. * * @param buf */ inline int read_undef(unsigned char *buf) { int l = 2; int n = getWord(buf, 0); while (n) { n--; while (!buf[l++]) {} } return l; } reloc65::reloc65(int addr) : m_tbase(addr) {} bool reloc65::reloc(unsigned char **buf, int *fsize) { unsigned char *tmpBuf = *buf; if (std::memcmp(tmpBuf, o65hdr, 5) != 0) { return false; } const int mode = getWord(tmpBuf, 6); if ((mode & 0x2000) // 32 bit size not supported || (mode & 0x4000)) // pagewise relocation not supported { return false; } const int hlen = HEADER_SIZE + read_options(tmpBuf + HEADER_SIZE); const int tbase = getWord(tmpBuf, 8); const int tlen = getWord(tmpBuf, 10); m_tdiff = m_tbase - tbase; const int dlen = getWord(tmpBuf, 14); unsigned char *segt = tmpBuf + hlen; // Text segment unsigned char *segd = segt + tlen; // Data segment unsigned char *utab = segd + dlen; // Undefined references list unsigned char *rttab = utab + read_undef(utab); // Text relocation table unsigned char *rdtab = reloc_seg(segt, tlen, rttab); // Data relocation table unsigned char *extab = reloc_seg(segd, dlen, rdtab); // Exported globals list reloc_globals(extab); setWord(tmpBuf, 8, m_tbase); *buf = segt; *fsize = tlen; return true; } int reloc65::reldiff(unsigned char s) const { return s==2 ? m_tdiff : 0; } unsigned char* reloc65::reloc_seg(unsigned char *buf, int len, unsigned char *rtab) { int adr = -1; while (*rtab) { if ((*rtab & 255) == 255) { adr += 254; rtab++; } else { adr += *rtab & 255; rtab++; const unsigned char type = *rtab & 0xe0; unsigned char seg = *rtab & 0x07; rtab++; switch(type) { case 0x80: { const int oldVal = getWord(buf, adr); const int newVal = oldVal + reldiff(seg); setWord(buf, adr, newVal); break; } case 0x40: { const int oldVal = buf[adr] * 256 + *rtab; const int newVal = oldVal + reldiff(seg); buf[adr] = (newVal >> 8) & 255; *rtab = newVal & 255; rtab++; break; } case 0x20: { const int oldVal = buf[adr]; const int newVal = oldVal + reldiff(seg); buf[adr] = newVal & 255; break; } } if (seg == 0) { rtab += 2; } } if (adr > len) { // Warning: relocation table entries past segment end! } } return ++rtab; } unsigned char *reloc65::reloc_globals(unsigned char *buf) { int n = getWord(buf, 0); buf +=2; while (n) { while (*(buf++)) {} unsigned char seg = *buf; const int oldVal = getWord(buf, 1); const int newVal = oldVal + reldiff(seg); setWord(buf, 1, newVal); buf +=3; n--; } return buf; } libsidplayfp-3.0.0/src/config.h.in0000644000175100017510000001104715175333717012510 /* src/config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD /* Define for threaded driver */ #undef EXSID_THREADED /* define if the compiler supports basic C++11 syntax */ #undef HAVE_CXX11 /* define if the compiler supports basic C++14 syntax */ #undef HAVE_CXX14 /* define if the compiler supports basic C++17 syntax */ #undef HAVE_CXX17 /* define if the compiler supports basic C++20 syntax */ #undef HAVE_CXX20 /* define if the compiler supports basic C++23 syntax */ #undef HAVE_CXX23 /* Define to 1 if you have the header file. */ #undef HAVE_DLFCN_H /* Define to 1 if you have libexsid (-lexsid). */ #undef HAVE_EXSID /* Define to 1 if you have the header file. */ #undef HAVE_FCNTL_H /* Define to 1 if you have ftd2xx.h */ #undef HAVE_FTD2XX /* Define to 1 if you have the header file. */ #undef HAVE_FTD2XX_H /* Define to 1 if you have ftdi.h */ #undef HAVE_FTDI /* Define to 1 if the system has the type `int16_t'. */ #undef HAVE_INT16_T /* Define to 1 if the system has the type `int32_t'. */ #undef HAVE_INT32_T /* Define to 1 if the system has the type `int8_t'. */ #undef HAVE_INT8_T /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have libusb.h */ #undef HAVE_LIBUSB /* Define to 1 if you have the header file. */ #undef HAVE_LIBUSB_1_0_LIBUSB_H /* Define if you have POSIX threads libraries and header files. */ #undef HAVE_PTHREAD /* Define to 1 if you have pthread.h */ #undef HAVE_PTHREAD_H /* Have PTHREAD_PRIO_INHERIT. */ #undef HAVE_PTHREAD_PRIO_INHERIT /* Define to 1 if you have libresidfp (-lresidfp). */ #undef HAVE_RESIDFP /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the `strcasecmp' function. */ #undef HAVE_STRCASECMP /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Define to 1 if you have the `strncasecmp' function. */ #undef HAVE_STRNCASECMP /* Define to 1 if you have the header file. */ #undef HAVE_SYS_IOCTL_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_SOUNDCARD_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define to 1 if the system has the type `uint16_t'. */ #undef HAVE_UINT16_T /* Define to 1 if the system has the type `uint32_t'. */ #undef HAVE_UINT32_T /* Define to 1 if the system has the type `uint8_t'. */ #undef HAVE_UINT8_T /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Define to 1 if you have libusb (-libusb-1.0). */ #undef HAVE_USBSID /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR /* Name of package */ #undef PACKAGE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* Define to necessary symbol if this constant uses a non-standard name on your system. */ #undef PTHREAD_CREATE_JOINABLE /* Shared library extension */ #undef SHLIBEXT /* The size of `int', as computed by sizeof. */ #undef SIZEOF_INT /* The size of `short', as computed by sizeof. */ #undef SIZEOF_SHORT /* Define to 1 if all of the C90 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* Version number of package */ #undef VERSION /* Path to VICE testsuite. */ #undef VICE_TESTSUITE /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif libsidplayfp-3.0.0/src/sidendian.h0000644000175100017510000001524215175333711012567 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2000 Simon White * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef SIDENDIAN_H #define SIDENDIAN_H #ifdef HAVE_CONFIG_H # include "config.h" #endif #include /* Labeling: 0 - LO 1 - HI 2 - HILO 3 - HIHI */ /////////////////////////////////////////////////////////////////// // INT16 FUNCTIONS /////////////////////////////////////////////////////////////////// /// Set the lo byte (8 bit) in a word (16 bit) inline void endian_16lo8 (uint_least16_t &word, uint8_t byte) { word &= 0xff00; word |= byte; } /// Get the lo byte (8 bit) in a word (16 bit) inline uint8_t endian_16lo8 (uint_least16_t word) { return (uint8_t) word; } /// Set the hi byte (8 bit) in a word (16 bit) inline void endian_16hi8 (uint_least16_t &word, uint8_t byte) { word &= 0x00ff; word |= (uint_least16_t) byte << 8; } /// Set the hi byte (8 bit) in a word (16 bit) inline uint8_t endian_16hi8 (uint_least16_t word) { return (uint8_t) (word >> 8); } /// Swap word endian. inline void endian_16swap8 (uint_least16_t &word) { uint8_t lo = endian_16lo8 (word); uint8_t hi = endian_16hi8 (word); endian_16lo8 (word, hi); endian_16hi8 (word, lo); } /// Convert high-byte and low-byte to 16-bit word. inline uint_least16_t endian_16 (uint8_t hi, uint8_t lo) { uint_least16_t word = 0; endian_16lo8 (word, lo); endian_16hi8 (word, hi); return word; } /// Convert high-byte and low-byte to 16-bit little endian word. inline void endian_16 (uint8_t ptr[2], uint_least16_t word) { #if defined(WORDS_BIGENDIAN) ptr[0] = endian_16hi8 (word); ptr[1] = endian_16lo8 (word); #else ptr[0] = endian_16lo8 (word); ptr[1] = endian_16hi8 (word); #endif } inline void endian_16 (char ptr[2], uint_least16_t word) { endian_16 ((uint8_t *) ptr, word); } /// Convert high-byte and low-byte to 16-bit little endian word. inline uint_least16_t endian_little16 (const uint8_t ptr[2]) { return endian_16 (ptr[1], ptr[0]); } /// Write a little-endian 16-bit word to two bytes in memory. inline void endian_little16 (uint8_t ptr[2], uint_least16_t word) { ptr[0] = endian_16lo8 (word); ptr[1] = endian_16hi8 (word); } /// Convert high-byte and low-byte to 16-bit big endian word. inline uint_least16_t endian_big16 (const uint8_t ptr[2]) { return endian_16 (ptr[0], ptr[1]); } /// Write a little-big 16-bit word to two bytes in memory. inline void endian_big16 (uint8_t ptr[2], uint_least16_t word) { ptr[0] = endian_16hi8 (word); ptr[1] = endian_16lo8 (word); } /////////////////////////////////////////////////////////////////// // INT32 FUNCTIONS /////////////////////////////////////////////////////////////////// /// Set the lo word (16bit) in a dword (32 bit) inline void endian_32lo16 (uint_least32_t &dword, uint_least16_t word) { dword &= (uint_least32_t) 0xffff0000; dword |= word; } /// Get the lo word (16bit) in a dword (32 bit) inline uint_least16_t endian_32lo16 (uint_least32_t dword) { return (uint_least16_t) dword & 0xffff; } /// Set the hi word (16bit) in a dword (32 bit) inline void endian_32hi16 (uint_least32_t &dword, uint_least16_t word) { dword &= (uint_least32_t) 0x0000ffff; dword |= (uint_least32_t) word << 16; } /// Get the hi word (16bit) in a dword (32 bit) inline uint_least16_t endian_32hi16 (uint_least32_t dword) { return (uint_least16_t) (dword >> 16); } /// Set the lo byte (8 bit) in a dword (32 bit) inline void endian_32lo8 (uint_least32_t &dword, uint8_t byte) { dword &= (uint_least32_t) 0xffffff00; dword |= (uint_least32_t) byte; } /// Get the lo byte (8 bit) in a dword (32 bit) inline uint8_t endian_32lo8 (uint_least32_t dword) { return (uint8_t) dword; } /// Set the hi byte (8 bit) in a dword (32 bit) inline void endian_32hi8 (uint_least32_t &dword, uint8_t byte) { dword &= (uint_least32_t) 0xffff00ff; dword |= (uint_least32_t) byte << 8; } /// Get the hi byte (8 bit) in a dword (32 bit) inline uint8_t endian_32hi8 (uint_least32_t dword) { return (uint8_t) (dword >> 8); } /// Swap hi and lo words endian in 32 bit dword. inline void endian_32swap16 (uint_least32_t &dword) { uint_least16_t lo = endian_32lo16 (dword); uint_least16_t hi = endian_32hi16 (dword); endian_32lo16 (dword, hi); endian_32hi16 (dword, lo); } /// Swap word endian. inline void endian_32swap8 (uint_least32_t &dword) { uint_least16_t lo = 0, hi = 0; lo = endian_32lo16 (dword); hi = endian_32hi16 (dword); endian_16swap8 (lo); endian_16swap8 (hi); endian_32lo16 (dword, hi); endian_32hi16 (dword, lo); } /// Convert high-byte and low-byte to 32-bit word. inline uint_least32_t endian_32 (uint8_t hihi, uint8_t hilo, uint8_t hi, uint8_t lo) { uint_least32_t dword = 0; uint_least16_t word = 0; endian_32lo8 (dword, lo); endian_32hi8 (dword, hi); endian_16lo8 (word, hilo); endian_16hi8 (word, hihi); endian_32hi16 (dword, word); return dword; } /// Convert high-byte and low-byte to 32-bit little endian word. inline uint_least32_t endian_little32 (const uint8_t ptr[4]) { return endian_32 (ptr[3], ptr[2], ptr[1], ptr[0]); } /// Write a little-endian 32-bit word to four bytes in memory. inline void endian_little32 (uint8_t ptr[4], uint_least32_t dword) { uint_least16_t word = 0; ptr[0] = endian_32lo8 (dword); ptr[1] = endian_32hi8 (dword); word = endian_32hi16 (dword); ptr[2] = endian_16lo8 (word); ptr[3] = endian_16hi8 (word); } /// Convert high-byte and low-byte to 32-bit big endian word. inline uint_least32_t endian_big32 (const uint8_t ptr[4]) { return endian_32 (ptr[0], ptr[1], ptr[2], ptr[3]); } /// Write a big-endian 32-bit word to four bytes in memory. inline void endian_big32 (uint8_t ptr[4], uint_least32_t dword) { uint_least16_t word = 0; word = endian_32hi16 (dword); ptr[1] = endian_16lo8 (word); ptr[0] = endian_16hi8 (word); ptr[2] = endian_32hi8 (dword); ptr[3] = endian_32lo8 (dword); } #endif // SIDENDIAN_H libsidplayfp-3.0.0/src/psiddrv.h0000644000175100017510000000437615175333711012312 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2015 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef PSIDDRV_H #define PSIDDRV_H #include #include class SidTuneInfo; namespace libsidplayfp { class sidmemory; class psiddrv { private: const SidTuneInfo *m_tuneInfo; const char *m_errorString; std::vector psid_driver; uint8_t *reloc_driver; int reloc_size; uint_least16_t m_driverAddr; uint_least16_t m_driverLength; private: /** * Get required I/O map to reach address * * @param addr a 16-bit effective address * @return a default bank-select value for $01 */ uint8_t iomap(uint_least16_t addr) const; public: explicit psiddrv(const SidTuneInfo *tuneInfo) : m_tuneInfo(tuneInfo) {} /** * Relocate the driver. * * @return false if something's wrong, check #errorString for error details */ bool drvReloc(); /** * Install the driver. * Must be called after the tune has been placed in memory. * * @param mem the c64 memory interface * @param video the PAL/NTSC switch value, 0: NTSC, 1: PAL */ void install(sidmemory& mem, uint8_t video) const; /** * Get a detailed error message. * * @return a pointer to the string */ const char* errorString() const { return m_errorString; } uint_least16_t driverAddr() const { return m_driverAddr; } uint_least16_t driverLength() const { return m_driverLength; } }; } #endif libsidplayfp-3.0.0/src/properties.h0000644000175100017510000000273115175333711013024 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2025 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef PROPERTIES_H #define PROPERTIES_H #include "sidcxx11.h" #ifdef HAVE_CXX17 #include template using Property = std::optional; #else #include template class Property { static_assert(std::is_scalar(), "T must be a scalar type"); private: T m_val; bool m_isSet; public: Property() : m_isSet(false) {} inline bool has_value() const { return m_isSet; } inline T value() const { return m_val; } inline Property& operator =(const T& val) { m_val = val; m_isSet = true; return *this; } }; #endif // HAVE_CXX17 #endif // PROPERTIES_H libsidplayfp-3.0.0/src/romCheck.h0000644000175100017510000001325215175333711012363 /* * This file is part of libsidplayfp, a SID player engine. * * Copyright 2012-2013 Leandro Nini * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef ROMCHECK_H #define ROMCHECK_H #include #include #include #include #include "sidmd5.h" namespace libsidplayfp { /** * Utility class to identify known ROM images through their md5 checksum. */ class romCheck { private: using md5map = std::map; private: /** * Maps checksums to respective ROM description. * Must be filled by derived class. */ md5map m_checksums; /** * Pointer to the ROM buffer */ const uint8_t* m_rom; /** * Size of the ROM buffer. */ unsigned int m_size; private: romCheck() = delete; /** * Calculate the md5 digest. */ std::string checksum() const { sidmd5 md5; md5.append(m_rom, m_size); return md5.getDigest(); } protected: /** * Construct the class. * * @param rom pointer to the ROM buffer * @param size size of the ROM buffer */ romCheck(const uint8_t* rom, int size) : m_rom(rom), m_size(size) {} void add(const char* md5, const char* desc) { m_checksums.insert(std::make_pair(md5, desc)); } public: /** * Get ROM description. * * @return the ROM description or "Unknown Rom". */ const char* info() const { md5map::const_iterator res = m_checksums.find(checksum()); return (res != m_checksums.end()) ? res->second : "Unknown Rom"; } }; /** * romCheck implementation specific for kernal ROM. */ class kernalCheck : public romCheck { public: kernalCheck(const uint8_t* kernal) : romCheck(kernal, 0x2000) { add("1ae0ea224f2b291dafa2c20b990bb7d4", "C64 KERNAL first revision"); add("7360b296d64e18b88f6cf52289fd99a1", "C64 KERNAL second revision"); add("479553fd53346ec84054f0b1c6237397", "C64 KERNAL second revision (Japanese)"); add("39065497630802346bce17963f13c092", "C64 KERNAL third revision"); add("27e26dbb267c8ebf1cd47105a6ca71e7", "C64 KERNAL third revision (Swedish)"); add("27e26dbb267c8ebf1cd47105a6ca71e7", "C64 KERNAL third revision (Swedish C2G007)"); add("e4aa56240fe13d8ad8d7d1dc8fec2395", "C64 KERNAL third revision (Danish)"); add("174546cf655e874546af4eac5f5bf61b", "C64 KERNAL third revision (Turkish)"); add("187b8c713b51931e070872bd390b472a", "Commodore SX-64 KERNAL"); add("b7b1a42e11ff8efab4e49afc4faedeee", "Commodore SX-64 KERNAL (Swedish)"); add("3abc938cac3d622e1a7041c15b928707", "Cockroach Turbo-ROM"); add("631ea2ca0dcda414a90aeefeaf77fe45", "Cockroach Turbo-ROM (SX-64)"); add("a9de1832e9be1a8c60f4f979df585681", "Datel DOS-ROM 1.2"); add("da43563f218b46ece925f221ef1f4bc2", "Datel Mercury 3 (NTSC)"); add("b7dc8ed82170c81773d4f5dc8069a000", "Datel Turbo ROM II (PAL)"); add("6b309c76473dcf555c52c598c6a51011", "Dolphin DOS v1.0"); add("c3c93b9a46f116acbfe7ee147c338c60", "Dolphin DOS v2.0-1 AU"); add("2a441f4abd272d50f94b43c7ff3cc629", "Dolphin DOS v2.0-1"); add("c7a175217e67dcb425feca5fcf2a01cc", "Dolphin DOS v2.0-2"); add("7a9b1040cfbe769525bb9cdc28427be6", "Dolphin DOS v2.0-3"); add("fc8fb5ec89b34ae41c8dc20907447e06", "Dolphin DOS v3.0"); add("9a6e1c4b99c6f65323aa96940c7eb7f7", "ExOS v3 fertig"); add("3241a4fcf2ba28ba3fc79826bc023814", "ExOS v3"); add("cffd2616312801da56bcc6728f0e39ca", "ExOS v4"); add("e6e2bb24a0fa414182b0fd149bde689d", "TurboAccess"); add("c5c5990f0826fcbd372901e761fab1b7", "TurboTrans v3.0-1"); add("042ffc11383849bdf0e600474cefaaaf", "TurboTrans v3.0-2"); add("9d62852013fc2c29c3111c765698664b", "Turbo-Process US"); add("f9c9838e8d6752dc6066a8c9e6c2e880", "Turbo-Process"); } }; /** * romCheck implementation specific for basic ROM. */ class basicCheck : public romCheck { public: basicCheck(const uint8_t* basic) : romCheck(basic, 0x2000) { add("57af4ae21d4b705c2991d98ed5c1f7b8", "C64 BASIC V2"); } }; /** * romCheck implementation specific for character generator ROM. */ class chargenCheck : public romCheck { public: chargenCheck(const uint8_t* chargen) : romCheck(chargen, 0x1000) { add("12a4202f5331d45af846af6c58fba946", "C64 character generator"); add("cf32a93c0a693ed359a4f483ef6db53d", "C64 character generator (Japanese)"); add("7a1906cd3993ad17a0a0b2b68da9c114", "C64 character generator (Swedish)"); add("5973267e85b7b2b574e780874843180b", "C64 character generator (Swedish C2G007)"); add("81a1a8e6e334caeadd1b8468bb7728d3", "C64 character generator (Spanish)"); add("b3ad62b41b5f919fc56c3a40e636ec29", "C64 character generator (Danish)"); add("7d82b1f8f750665b5879c16b03c617d9", "C64 character generator (Turkish)"); } }; } #endif // ROMCHECK_H libsidplayfp-3.0.0/Doxyfile.in0000644000175100017510000033005415175333711012005 # Doxyfile 1.8.17 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the configuration # file that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # https://www.gnu.org/software/libiconv/ for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = @PACKAGE_NAME@ # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = @PACKAGE_VERSION@ # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = @builddir@/docs # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode # U+3044. # The default value is: NO. ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, # Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), # Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, # Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, # Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, # Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, # Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all generated output in the proper direction. # Possible values are: None, LTR, RTL and Context. # The default value is: None. OUTPUT_TEXT_DIRECTION = None # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = NO # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = NO # If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line # such as # /*************** # as being the beginning of a Javadoc-style comment "banner". If set to NO, the # Javadoc-style will behave just like regular comments and it will not be # interpreted by doxygen. # The default value is: NO. JAVADOC_BANNER = NO # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new # page for each member. If set to NO, the documentation of a member will be part # of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:\n" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines (in the resulting output). You can put ^^ in the value part of an # alias to insert a newline as if a physical newline was in the original file. # When you need a literal { or } or , in the value part of an alias you have to # escape them by means of a backslash (\), this can lead to conflicts with the # commands \{ and \} for these it is advised to use the version @{ and @} or use # a double escape (\\{ and \\}) ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = NO # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice # sources only. Doxygen will then generate output that is more tailored for that # language. For instance, namespaces will be presented as modules, types will be # separated into more groups, etc. # The default value is: NO. OPTIMIZE_OUTPUT_SLICE = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, JavaScript, # Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, # Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: # FortranFree, unknown formatted Fortran: Fortran. In the later case the parser # tries to guess whether the code is fixed or free formatted code, this is the # default for Fortran type files), VHDL, tcl. For instance to make doxygen treat # .inc files as Fortran files (default is PHP), and .f files as C (default is # Fortran), use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See https://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up # to that level are automatically included in the table of contents, even if # they do not have an id attribute. # Note: This feature currently applies only to Markdown headings. # Minimum value: 0, maximum value: 99, default value: 5. # This tag requires that the tag MARKDOWN_SUPPORT is set to YES. TOC_INCLUDE_HEADINGS = 5 # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = YES # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = YES # If one adds a struct or class to a group and this option is enabled, then also # any nested class or struct is added to the same group. By default this option # is disabled and one has to add nested compounds explicitly via \ingroup. # The default value is: NO. GROUP_NESTED_COMPOUNDS = NO # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = NO # If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual # methods of a class will be included in the documentation. # The default value is: NO. EXTRACT_PRIV_VIRTUAL = NO # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option # has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # declarations. If set to NO, these declarations will be included in the # documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # names in lower-case letters. If set to YES, upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # (including Cygwin) ands Mac users are advised to set this option to NO. # The default value is: system dependent. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will # append additional text to a page's title, such as Class Reference. If set to # YES the compound reference will be hidden. # The default value is: NO. HIDE_COMPOUND_REFERENCE= NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader # which file to include in order to use the member. # The default value is: NO. SHOW_GROUPED_MEMB_INC = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo # list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test # list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters # in a documented function, or documenting parameters that don't exist or using # markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO, doxygen will only warn about wrong or incomplete # parameter documentation, but not about the absence of documentation. If # EXTRACT_ALL is set to YES then this flag will automatically be disabled. # The default value is: NO. WARN_NO_PARAMDOC = NO # If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when # a warning is encountered. # The default value is: NO. WARN_AS_ERROR = NO # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING # Note: If this tag is empty the current directory is searched. INPUT = @srcdir@/src \ @srcdir@/docs # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: https://www.gnu.org/software/libiconv/) for the list of # possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # read by doxygen. # # If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, # *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, # *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, # *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), # *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen # C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f, *.for, *.tcl, *.vhd, # *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = src/builders/exsid-builder/driver # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). EXAMPLE_PATH = @srcdir@/test # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. # # Note that for custom extensions or not directly supported extensions you also # need to set EXTENSION_MAPPING for the extension otherwise the files are not # properly processed by doxygen. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # entity all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see https://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = YES # If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the # clang parser (see: http://clang.llvm.org/) for more accurate parsing at the # cost of reduced performance. This can be particularly helpful with template # rich C++ code for which doxygen's built-in parser lacks the necessary type # information. # Note: The availability of this option depends on whether or not doxygen was # generated with the -Duse_libclang=ON option for CMake. # The default value is: NO. CLANG_ASSISTED_PARSING = NO # If clang assisted parsing is enabled you can provide the compiler with command # line options that you would normally use when invoking the compiler. Note that # the include paths will already be set by doxygen for the files and directories # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. CLANG_OPTIONS = # If clang assisted parsing is enabled you can provide the clang parser with the # path to the compilation database (see: # http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files # were built. This is equivalent to specifying the "-p" option to a clang tool, # such as clang-check. These options will then be passed to the parser. # Note: The availability of this option depends on whether or not doxygen was # generated with the -Duse_libclang=ON option for CMake. CLANG_DATABASE_PATH = #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = NO # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # https://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to YES can help to show when doxygen was last run and thus if the # documentation is up to date. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML # documentation will contain a main index with vertical navigation menus that # are dynamically created via JavaScript. If disabled, the navigation index will # consists of multiple levels of tabs that are statically embedded in every HTML # page. Disable this option to support browsers that do not have JavaScript, # like the Qt help browser. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_MENUS = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: https://developer.apple.com/xcode/), introduced with OSX # 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy # genXcode/_index.html for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated # (YES) or that it should be included in the master .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated # (YES) or a normal table of contents (NO) in the .chm file. Furthermore it # enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- # folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = NONE # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 # If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANSPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands # to create new LaTeX commands to be used in formulas as building blocks. See # the section "Including formulas" for details. FORMULA_MACROFILE = # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # https://www.mathjax.org) which uses client side JavaScript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from https://www.mathjax.org before deployment. # The default value is: https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically # , /