576

(37 replies, posted in Other Platforms)

Well, you have a point. I'll think about it more... perhaps write some simple tool that will convert AVRA source to Arduino syntax.

Anyway, I tried compiling arduino_octode, but I was getting some errors. I think it's because I have a very outdated version (1.0.5, thanks Debian) - it doesn't like PROGMEM and NULL. I got it to compile with defining NULL as 0 and PROGMEM as nothing, but that is not the correct way to do it afaik. I should probably replace the Debian version with a newer one, but given that the sources are like 90 MB I'm not too inclined to do it right now, as it would probably take half a day to compile them on my machine.

Anyway, I was able to extract the resulting ELF file and disassemble it. avr-objdump outputs a pretty nice, commented listing, so I'd say give it a try. Or, if you're having problems with it, send me the ELF files (ctrl-f arduino_octode.cpp.elf) and I'll send you back the asm listings.

577

(37 replies, posted in Other Platforms)

Wouldn't it be possible to link Arduino C code against a pre-compiled library? Then such a library could be written in asm. That was actually what I was intending to do with the Z80 emulation.

578

(37 replies, posted in Other Platforms)

Wow, I wouldn't have thought that it's possible to pull this off in C at all. I personally have no interest in programming this thing in C considering the beauty of the AVR m'code instruction set, but still, nice to see it works and is efficient enough.

Regarding the point you mentioned about the while loop, have you checked how the compiler implements this? It should be possible to get the resulting asm code somehow. Afaik the Arduino thing runs on AVR-GCC, so I suppose you could run the code directly through AVR-GCC with -S switch to get the asm output.

I think your stability issues will be related to your PC's USB port. Many PCs have their USB ports improperly configured and/or use crap controllers, which causes them to deliver unstable/out-of-spec current. Since you say that things are fine when running the board off external power, I'm pretty sure that's what's happening here.

Ah, excellent. I've been using my own (C++) lib for quick prototyping of XM converters since a while so I have no acute need for this, but mine is very badly designed so I can't publish it as a stand-alone library. So it's nice to have a clean and well-designed backup plan.

I'm surprised it's so slow, though. I mean Python is not exactly fast, but it shouldn't take that long. I took the liberty of running the script through cProfile and this is what I got:

         5450 function calls in 7.201 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.021    0.021    7.201    7.201 convert_octode.py:3(<module>)
        1    0.000    0.000    0.000    0.000 genericpath.py:55(getsize)
        1    7.138    7.138    7.138    7.138 xmlib.py:10(XM)
        4    0.000    0.000    0.000    0.000 xmlib.py:133(get_order)
        2    0.000    0.000    0.000    0.000 xmlib.py:140(get_pattern_length)
     1024    0.002    0.000    0.002    0.000 xmlib.py:148(get_note)
     1024    0.002    0.000    0.002    0.000 xmlib.py:153(get_instrument)
     1024    0.002    0.000    0.002    0.000 xmlib.py:158(get_volume)
     1040    0.002    0.000    0.002    0.000 xmlib.py:163(get_effect)
     1025    0.004    0.000    0.004    0.000 xmlib.py:168(get_parameter)
       15    0.000    0.000    0.000    0.000 xmlib.py:26(read_word)
        3    0.000    0.000    0.000    0.000 xmlib.py:29(read_dword)
        1    0.029    0.029    0.029    0.029 xmlib.py:32(load)
        1    0.000    0.000    7.138    7.138 xmlib.py:4(<module>)
        1    0.000    0.000    0.000    0.000 {len}
        2    0.000    0.000    0.000    0.000 {method 'append' of 'array.array' objects}
        1    0.000    0.000    0.000    0.000 {method 'close' of 'file' objects}
        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}
        1    0.000    0.000    0.000    0.000 {method 'fromfile' of 'array.array' objects}
        1    0.000    0.000    0.000    0.000 {open}
        1    0.000    0.000    0.000    0.000 {posix.stat}
      276    0.001    0.000    0.001    0.000 {range}

I think the main bottleneck happens with setting up the arrays on constructing XM class object. I tried with XMs of varying complexity, there is almost no change in execution time. So the conversion functions aren't the problem, in any case. Not sure how that can be rectified. One could of course read the song parameters first and only set up the necessary amount of arrays afterwards, but I have a feeling that that doesn't tackle the problem at its root.

Hmm, this looks interesting, especially the last answer. I'm not a Python coder at all though.

580

(10 replies, posted in Sinclair)

I've actually done some AVR code before, it is indeed a very easy chip to code on. I also have a SeinSmart Uno (Chinese Arduino knock-off) laying around somewhere, and I have an asm programming toolchain installed (Arduino IDE is indeed useless for that), though I can't remember what the actual commands for it were.

In any case, I think Z80 emulation on a 16MHz AVR would be tricky, but possible, albeit not without cutting some corners. I think main challenges will be instruction decoding, and dealing with the AVR's big-endianness. I would suggest:

- Emulation of 4 MHz clock speed instead of 3.5, easier to emulate the correct cycle count like that
- Cut all interrupt-related stuff. This would break SpecialFX and Savage, but I think the benefits far outweigh this. Actual interrupts should be handled outside of the Z80 emulation.
- No R register auto-update.
- No emulation of 5,H,3,N flags and MEMPTR.
- DAA replaced with NOP (would break wtbeep, but oh well)

In any case, I would be willing to work on an AVR Z80 emulation. However, I currently have several other ongoing projects that I want to finish first (MDAL, mainly - made some good progress last month but there's still a few major features missing, such as multi-track sequences, "virtual" sequences, and sample support).

581

(10 replies, posted in Sinclair)

Ok Shiru, you've convinced me of the benefits of a card that run standard beeper engines. Well, maybe Arduino is not such a good idea, after all - using a large Ardunio as the base of this might drive up the costs too much. I mean how much would people be willing to spend on this? 30€? Maybe 50 if it includes a joystick interface?

Either way I know very little about these things, so I'm afraid I can't be of much help.

582

(10 replies, posted in Sinclair)

(discussion split off from the Sleizsa Trio thread)

About a beeper card, would it perhaps make sense to make it Atmega based? I think it might help the popularity of such a device if it could be build from "standard household appliances", eg. Arduino. On the other hand, a Z80-based card could be made in a way that it would run Spectrum beeper engines without adaptation, which would be a big bonus, too. Not sure what's the better approach.

Been a while since I coded something on Fairchild F8... well, here's a new sound routine for the Channel F (aka VES, Grandstand, Saba Videoplay). Sleizsa Trio features 3 tone channels (one of which can play noise instead of tone), globally configurable duty cycles, and 2 interrupting click drums. It uses a mixing algorithm based on Zilogat0r's Squeeker engine for the ZX beeper, which does a somewhat better job with the Channel F's crude sound generator than Sleizsa Duo's pulse interleaving method.

Demo tune: https://soundcloud.com/irrlicht-project … -channel-f
Download: https://github.com/utz82/SleizsaTrio/releases/latest (XM converter included)
Github repo: https://github.com/utz82/SleizsaTrio

Whoa, that's very nicely done. Good find, thanks for sharing!

585

(21 replies, posted in Sinclair)

Yo Zilog, good to read you on here! Your idea about using scalers has actually found it's way into this engine, though I think in a different form than you had envisioned it wink

Anyway, would love to see a new beeper engine from you, too! Squeeker has been very inspiring for me, and in terms of sound it's still one of my all-time favourites.

586

(135 replies, posted in Sinclair)

Been doing some thinking about vibratos. Here's an algo that is reasonably fast, has configurable parameters, and doesn't require a table lookup:

    ld hl,0
    ld de,note_divider
    
    ld c,1                    ;vibrato strength (max 0xf)
    ld b,2                    ;position init (must be ½ of vibrSpeed range - else detune)

loop
    add hl,de        ;11
    ld a,h            ;4
    out (#fe),a        ;11

    ld a,e            ;4
    jr nc,noVibrato        ;12/7

    ret nc            ;5        ;timing
vibrDir                    
    inc b            ;4        ;initial direction (probably needed as configurable parameter)
vibrSpeed equ $+1
    bit 2,b            ;8        ;speed (see above, bit 3 -> ld b,4 | bit 2 -> ld b,2...)
    jp z,vibrDown        ;10
                    
vibrUp
    add a,c            ;4        ;DE += C
    ld e,a            ;4
    adc a,d            ;4
    sub e            ;4
    ld d,a            ;4    
    
    jr loop            ;12
                ;96    

vibrDown
    sub c            ;4        ;DE -= C
    ld e,a            ;4
    sbc a,a            ;4    
    add a,d            ;4            
    ld d,a            ;4    
                    
    jr loop            ;12    
                    
    
noVibrato
    ;... waste some t's
    jr loop            ;12
                ;96

I have a feeling that this thing can be optimized further by using an sbc a,a fallthrough solution, but haven't managed to implement it for the downward slide yet. Let me know if you have any ideas for this.

587

(2 replies, posted in General Discussion)

Belated Happy New Year from me, too! Back from my album recording session now and back on track for 1-bit world domination big_smile

588

(135 replies, posted in Sinclair)

Got a track in the pipes for this. Nothing great, just some simple PhaserX punk rock. Still need to polish it up a bit though.

Finally got around to listening to this properly. Awesome track, love that grinding fx at the end!

590

(10 replies, posted in General Discussion)

The was supposed to be one in november, but I didn't have time to organize it after all. Next good chance would be in early spring, after Winter Chip has finished on Battle of the Bits.
In the meantime, perhaps you would like to participate in the Beeper compo at DiHalt 2017 Lite: http://dihalt.org.ru/rules5_eng.html#zx ?

Neat!

"$db" is indeed a note value in hex notation, equal to 219 in decimal wink

I wonder what went wrong with those errors though. The line "#define db .byte" actually means the opposite in TASM, eg. "interpret '.byte' as 'db'". But as I said, back in the day when I wrote these I didn't have much of a clue about asm either. In any case, I promise to make a better version of ti1bit pack as soon as I can find the time, hopefully in January.

If you run into the "too many lines" problem, it might also suffice to put some dummy labels somewhere in the music data, eg.

   db $bla
   db $bla
   db $bla
dummyLabel1
   db $bla
   db $bla
   db $bla

Haven't tried this though. In any case, first thing for the new ti1bit pack will be to eliminate TASM and replace it with a modern assembler which doesn't bicker about stupid crap like that.

A note on speed: Speed conversion in ti1bit is not very accurate to begin with. But there are also other problems, some of which were discovered only recently. Namely 1) The TI-83 Parcus (the model you have) actually runs at around 7 MHz, despite the official specs claiming it runs at 6. 2) CPU speed on TI calcs fluctuates significantly depending on battery strength. On TI-83, it's not as bad as on some other calcs, but still normal to have +/- ½ MHz variation.

Wow, you seem to be really active! Also, I think black metal will have a few fans around here wink

In theory it should just work by setting the loop point where you want it in 1tracker. I have no clue what I even meant by what's written in the ti1bit readme.

594

(135 replies, posted in Sinclair)

Proof of concept for my idea about saw wave generation:

;saw wave via square wave transform ([f,a]+[2f,½a]+[4f,¼a]...)

    ld hl,0
    ld de,#40
    ld c,#fe
    
loop
    add hl,de    ;11
    
    ld a,0        ;7    ;timing
    ld a,0        ;7    ;timing
    ld a,0        ;7    ;timing
    nop           ;4
    
    ld a,h        ;4

    out (c),a    ;12__64   ([f, a])
    rrca         ;4
    out (c),a    ;12__16   ([4f, ¼a])
    rrca         ;4
    ds 4         ;16
    out (c),a    ;12__32   ([2f, ½a])
    jr loop        ;12

Ha, with a demo tune like this, it was totally worth it big_smile Looking forward to what you'll come up with. Please do post your stuff here, I'm curious.
And yeah, applying some eq is totally fine in the 1-bit world (well, in my opinion at least). Though lsengine is a pretty hopeless case. I've used it quite a bit for some time, but I never managed to get it to sound really good, neither on Spectrum nor on TI.

Yeah, almost there I think.
Did you remove all dots (.) from the music.asm file? If the answer is yes and it still doesn't work, attach your music.asm here and I'll take a look.

Hey, no problem at all. Using this crap package certainly isn't trivial wink and others might benefit from having these questions discussed. So no need to feel guilty.

Regarding the error, I'm a bit surprised by this one. I don't have any problem running TASM in DOSBox. But I just noticed that I'm appearantly using 3.1, not 3.2.
http://www.ticalc.org/archives/files/fi … /1504.html
Maybe using this ^ will solve the problem? Otherwise, I'd say 3.2 appears to NOT require DOS after all. So perhaps try to run in directly under Windows (though I doubt that would work under anything newer than XP)?

598

(135 replies, posted in Sinclair)

Alright, got a new idea - use a "state memory". Now wtf is a state memory? Think about how we implement accumulative pin pulse engines (Octode XL, for example). We basically "remember" the state of the carry flag from add hl,de for a given time (which, in an accumulative pin pulse engine, will control the volume). But in pulse interleaving engines, we evaluate the state only once and then discard it immediately. But it might be useful to actually remember it for some time. For example, we can implement a primitive low-pass filter like this (excuse the sloppy code, it's early in the morning big_smile)

   ld hl,0        ;counter, clear it
   ld de,#40      ;freq divider
   ld b,0         ;"state memory"
loop
    add hl,de     ;nothing special going on here, just adding da stuff
    ld a,h        ;HL bit 12 = output state
    out (#fe),a
    
    and #10       ;store the current state in state memory
    or b
    ld b,a
    
    rrca          ;get old state from 8 loop iterations ago
    ;rrca         ;2x rrca = high cutoff, 1x rrca = low cutoff (filter moves slower)
    nop

    nop           ;timing
    
    out (#fe),a
    
    and #ef       ;delete old state from state memory
    ld b,a
    
    ld c,0        ;timing
    
    jr loop

High-pass could be implemented in a similar fashion, because HP_output is basically just (original_output - LP_output). There could be other uses for this "state memory" thing as well.

You're not giving up easily, are you? big_smile Well, with so much persistence, I don't have a choice but to help you wink

Ok, so first of all, you need the "other" TASM - not Borland, but Telemark. You can get it here:
http://www.ticalc.org/archives/files/fi … 25051.html
You'll probably need to run it in DOSbox, btw.
And devpac83 is here: http://www.ticalc.org/archives/files/fi … /3650.html
Just dump all the files in your working directory, where you have the asm files. "asm83.bat" goes into that folder as well.

Regarding step 5, just make sure the first two lines look something like this:

;#define TI82
#define TI83

Anything that has a ";" in front of it is considered a comment in assembly, and will be ignored by the assembler. If you just have the line "#define TI83" (without a ; in front of it), then that'd be correct. Don't worry about the "looping" part for now.

Also, don't worry about the "long song data corrupts TASM" part, unless you actually run into problems. If that happens, take this:

ptr1
loop1
    db $21
    db $2d
    db $1e
    db $2a
    db $20
    db $2c
    db $1c
    db $28
    db $2a
    db $1e
    db $26
    db $1a
    db $28
    db $1c
    db $25
    db $19
    db $2d
    db $2d
    db $2a
    db $2a
    db $2c
  bla bla bla...

and transform it into this:

   db $21, $2d, $1e, $2a, $20, $2c, $1c, $28, $2a, $1e, $26, $1a, $28, $1c, $25, $19
   db $2d, $2d, $2a, $2a, $2c, ...

Also yes, that rawp thing will be a bit easier to use. No need to fiddle with TASM, at least.

It's even less straightforward, actually. If you have an XM, you'll need to use one of Shiru's original XM converters to produce an .asm file, adjust some things manually, then use TASM and the ti1bit pack to compile them into a .83p. The problem is that those XM converters are meant to operate on specifically crafted templates. While it is technically possible to not use the templates, your mileage may vary wildly as far as the results are concerned. As I said, it's really one big hassle to use. Well, knowing that you are interested in using this, I'll think about rewriting the whole thing and making it more convenient to use. It'll be some time before I get around to that, though, probably won't happen this year anymore.