FANCO v6 — SHORT SOUND AND ORDINARY CODE ====================================== Version boundary: import v6/assembler.ts and use `.version 6`. Old version-05 bytes do not run under the new encoding/map. One write to play a factory instrument ------------------------------------- mov.b [0x10f], 69 ; A4, 440 Hz, gate on, envelope hit mov.b [0x10f], 69 ; another hit, even though the value is unchanged mov.b [0x10f], 255 ; release Each instruction is five bytes in the current v6 assembler. NOTE uses the existing fixed patch; it never chooses or rewrites an instrument. With legato flag bit4, held-note pitch changes skip the hit. Action ports read idle FF. Commands are consumed at the next control tick; repeated writes within that tick collapse to the latest, rather than creating an unbounded sound queue. The CPU must keep the host running; a program that HALTs ends its machine session. A minimal sustained example uses a timer/WAIT loop: .version 6 .sound on mov.w [0x10], irq mov.w [0x12], 50 mov.b [0x10f], 69 idle: wait bra idle irq: reti Low-level control remains straightforward ---------------------------------------- Generator n starts at 0100+n*10 hex. Its first seven bytes are frequency word, pulse word, wave/control, AD and SR. They are typed parameters of the same kernel, not a call to a separate SID engine. A raw-frequency instrument: mov.w [0x100], 0x1d44 mov.w [0x102], 0x0800 mov.b [0x105], 0x00 mov.b [0x106], 0xf0 mov.b [0x104], 0x41 ; pulse + gate Modulation, custom exponential/looping envelopes, self-feedback and effects can be layered without replacing these basic fields. Inaudible generators can modulate audible ones. The eight-slot mixer/pan/filter/send bank is separate from synthesis configuration. General CPU savings, not a song opcode ------------------------------------- mov b,a ; one byte movzx a,[p+18] ; two-byte byte-to-word record load mov.b [p+6],a.lo ; two-byte record store mov.b [p+7],0 ; three-byte record initialization lea r,[p+18] ; three-byte flag-neutral effective address MOV/loads do not set flags. Explicit CMP or arithmetic produces N/Z/C/V. For a loop, do not branch on a stale flag after a load: loop: movzx a,[p++] cmp a,0 bz done ; use a bra loop done: ret The current CPU has useful pointer/displacement, byte/word, immediate and full escape forms. No firmware pattern/music decoder or score data is used. Fixed point and multiword math ----------------------------- smulshift a,b,15 ; signed Q1.15 multiply, floor rounding, four bytes smulshift x,y,16 ; signed high product, four bytes umulhi x,y ; unsigned high product, three bytes add a,x ; low-word addition sets carry adc b,y ; high-word addition includes carry, three bytes sub a,x ; low-word subtraction sets borrow sbc b,y ; high-word subtraction includes borrow, three bytes Math destinations are a..sp and sources a..pc (word registers only). SMULSHIFT accepts 0..31; V reports signed overflow after shifting, C clears. UMULHI clears C/V. ADC/SBC set ordinary N/Z/C/V, including incoming carry or borrow in the exact sum/difference. MOV preserves carry between limbs. For a full unsigned product, copy the original destination before MUL and use UMULHI on the copy. No fixed-point scale, table or scene is in firmware. DIV/MOD remain unsigned; signed/wide division is not added speculatively. abs x ; signed magnitude, three bytes, no scratch register smax x,y ; signed maximum, three bytes smin x,y ; signed minimum, three bytes These operations set N/Z from the result and clear C/V, except ABS(-32768) returns 8000 hex with N/V set. SMIN/SMAX compare signed words, not magnitudes. They are useful for clipping, distance fields and ordinary integer intervals. Observed complete-program budget -------------------------------- Including all nineteen selections, touch/keyboard controls, visible tiles, all musical/effect data and image framing: Original C64 payload 4,039 bytes v5 full native 5,120 bytes v6 basic-alias reference 4,126 bytes v6 native 4,145 bytes The v6 image is about 2.6% larger than the original. General compact CPU encodings supply most of the savings; the regular native bank and simple 50-Hz timer remove staging/conversion overhead. These are actual assembled sizes, not transistor-equivalence or an exact C64 waveform claim. New timing is slightly slower than PAL, and SIREN retains its native synthesis/effects. Whole-program code/data count includes the player, never hides it in the VM.