Category: Commodore

  • Nytt C64-demo: Divine

    Äntligen har jag fått klart mitt nya C64-demo som innehåller min SID-cover på Divinyls låt “I touch myself”.

    Du kan ladda hem D64-filen, PRG-filen eller besöka repositoryt.

    En jättekort förhandsvisning finns här:

    Lite bakgrund: För 10 år sedan gjorde jag två SID-låtar (alltså musik för Commodore 64) på Windows. En av dem var för ett seriöst demo, och den byggde jag i GoatTracker II (som verkligen tar till vara på SID-chippets förmåga) och så denna i DefleMask (betydligt sämre anpassat till just C64 beträffande minneseffektivitet, men mer lättarbetad än Goat). Denna mini-demo är en ursäkt för att få publicera denna låt, och allt som kan betraktas däri är byggt i Windows. Koden är CBM Prg Studio assembler – en släkting till Kick Assembler, som är betydligt mer avancerad än vad man kunde hitta på C64, men den kompilerar till korrekt maskinkod som kan köras på äkta hårdvara. Bilden som används som bakgrundsbild är konverterad till Koala-format med ett verktyg jag hittade på nätet, och sedan konverterat till raw bitmap med ett pythonscript som jag också hittade på nätet. De sprites som rör sig på skärmen är skapade med min egna sprite-editor Sprdef2 (igen Windows) som är designad för att interagera med just CBM Prg Studio.

  • Sprdef2 1.3

    Sprite-editorn Sprdef2 som körs under Windows för att skapa sprites till Commodore 64 (och 128) finns nu tillgänglig i version 1.3. De viktigaste nyheterna är ett nytt linje-verktyg och en undo-buffer. Här finns mer information.

  • A simple Christmas greeting for BASIC programmers

    Those of you who like Commodore BASIC usually send little Christmas greetings, and I don’t want to be any worse. This program works on C64 and C128, and can be adapted to VIC-20:

    10 POKE 53281,0:POKE 53280,6
    20 PRINT "{BLACK}";CHR$(147)
    30 FOR WI=1 TO 19 STEP 2:GOSUB 70:GOSUB 70:NEXT
    40 WI=3:GOSUB 120:GOSUB 120:GOSUB 120
    50 PRINT "{HOME}"
    60 GOTO 170:REM"SNOW EFFECT
    70 S=19-WI/2:REM"PRINT TREE
    80 FOR A=0 TO S:PRINT "{BLACK} ";:NEXT
    90 FOR A=1 TO WI:PRINT "{GREEN}*";:NEXT
    100 PRINT
    110 RETURN:REM"END PRINT TREE
    120 S=19-WI/2:REM"PRINT STEM
    130 FOR A=0 TO S:PRINT "{BLACK} ";:NEXT
    140 FOR A=1 TO WI:PRINT "{BROWN}*";:NEXT
    150 PRINT
    160 RETURN:REM"END PRINT STEM
    170 X=INT(RND(1)*40):Y=(INT(RND(1)*23)+1):ADR=55296+((Y*40)+X):REM"SNOW EFFECT
    180 CU=PEEK(ADR) AND 15
    190 C=1024+((Y*40)+X)
    200 IF Y=23 THEN GOSUB 250:REM"GROUND
    210 IF Y<>23 AND (CU=0 OR CU=6 OR CU=1) THEN GOSUB 310:REM"SKY
    220 IF Y<>23 AND CU=5 THEN GOSUB 400:REM"TREE
    230 IF Y<>23 AND (CU=8 OR CU=9 OR CU=11) THEN GOSUB 460:REM"STEM
    240 GOTO 170
    250 NC=INT(RND(1)*3):REM"GROUND
    260 IF NC=0 THEN POKE ADR,1
    270 IF NC=1 THEN POKE ADR,5
    280 IF NC=2 THEN POKE ADR,15
    290 POKE C,ASC("*")
    300 RETURN
    310 NC=INT(RND(1)*3):REM"SKY COLOR
    320 IF NC=0 THEN POKE ADR,0
    330 IF NC=1 THEN POKE ADR,6
    340 IF NC=2 THEN POKE ADR,1
    350 NC=INT(RND(1)*3):REM"SKY CHARACTER
    360 IF NC=0 THEN POKE C,ASC(" ")
    370 IF NC=1 THEN POKE C,ASC(".")
    380 IF NC=2 THEN POKE C,ASC("'")
    390 RETURN
    400 NC=INT(RND(1)*4):REM"TREE
    410 IF NC=0 THEN POKE ADR,5:POKE C,ASC("*")
    420 IF NC=1 THEN POKE ADR,13:POKE C,ASC("*")
    430 IF NC=2 THEN POKE ADR,2:POKE C,ASC("Q")
    440 IF NC=3 THEN POKE ADR,7:POKE C,ASC("Q")
    450 RETURN
    460 NC=INT(RND(1)*3):REM"STEM
    470 IF NC=0 THEN POKE ADR,8
    480 IF NC=1 THEN POKE ADR,9
    490 IF NC=2 THEN POKE ADR,11
    500 RETURN

    Note how the code tries to use procedures with different responsibilities to update different parts of the tree, the ground, and the background. The result looks like this: https://x.com/ahesselbom/status/2003217324841796096

  • Sprdef2 1.1 is available

    The C64/128 sprite editor Sprdef2 (runs under Windows) is now available for download. Screenshot and link is available here: https://github.com/Anders-H/Sprdef2/blob/main/README.md

  • Resurser för Commodore 64-utveckling

    Om du som jag skriver program för Commodore 64 på fritiden, är denna sida ett register över de verktyg du behöver.

    Utvecklingsmiljöer

    CBM .prg Studio

    C64 Studio

    Programmeringsspråk

    Turbo Rascal

    KickC

    XC=BASIC 3

    Vision BASIC

    Commodore DOS

    DirMaster

    Dokumentation

    BASIC (C64 Wiki)

    Assembler (C64 Wiki)

    All about yout C64 – online help

    Chip music for dummies

    Commodore 64 memory map

    Machine language

    6402 opcodes

    Programming sound and music on yout Commodore 64

    Final Cartridge III manual

    VIC-1541 manual

    Commodore 64 Data Files

    Commodore BASIC tokenized file

    Editorer, musik

    GoatTracker 2

    SID Factory II

    Music Studio

    Editorer, grafik

    mcDRAW

    PETSCII Editor

    Emulering

    VICE

    Övrigt

    Awesome Commodore Resources

    The C-64 Scene Database

    För min del har jag skrivit bok om Commodore BASIC 2.0 second release, och jag håller på att arbeta med en sprite editor.

  • Kapitlet om själva enheten Commodore 128 i min kommande bok

    Första utkastet av andra kapitlet av min bok om Commodore 128 publiceras här för den som vill rätta eller kommentera. Maila mig, SMS:a mig eller skriv en kommentar här. Glöm inte att meddela om du vill ha ett erkännande i boken för din kommentar. Kapitlet syftar till att produktplacera datorn.

    För att bevara formatering, har jag laddat upp kapitlet som PDF. Alla kontaktuppgifter (e-post, telefon, med mera) finns här. Och kapitlet finns här.

  • Kapitlet om ljud i min kommande bok om Commodore 128

    Första utkastet av sjunde kapitlet av min bok om Commodore 128 publiceras här för den som vill rätta eller kommentera. Maila mig, SMS:a mig eller skriv en kommentar här. Glöm inte att meddela om du vill ha ett erkännande i boken för din kommentar. Avgränsningen är enkla ljudeffekter, inte musik eller mer avancerade ljudeffekter, då dessa har var sitt kapitel avsatt.

    Ljud

    Commodore 128 har ungefär samma kapacitet till ljud som Commodore 64. I datorn finns en avancerad synthesizer innehållande tre röster och fyra vågformer. Vågformerna är triangel, sågtand, fyrkantsvåg och brus. Fyrkantsvågen har ställbar pulsbredd, vilket ger möjlighet till stora variationer.

    Till skillnad från Commodore 64, tillåter Commodore 128 att man använder BASIC-kommandon för att åt datorns ljudkapacitet. Kommandot SOUND ger dig möjlighet att spela ljud i någon av de tre kanalerna, i valfri frekvens under valfri tid. Kommandot har även stöd för att böja frekvensen[1] på tonen ljudet som spelar.

    Tre argument är obligatoriska. Dessa är val av röst (1, 2 eller 3), val av frekvens (0 till 65535) och längd (angivet i sextiondels sekunder). Använd endast dessa tre argument, spelas en rak ton med i en fyrkantsvåg med en neutral inställning på pulsbredden. Följande spelar tonen A under en sekund:

    SOUND 1,3800,60

    Du som kan musikteori kanske noterar att 3800 inte är jämt delbart med 220, och det beror på att frekvensangivelsen (det andra argumentet) ligger på en egen skala som inte stämmer med faktisk svängningshastighet.

    Argumenten identifieras av sin ordning. Samtliga argument är:

    1. Kanal (1, 2 eller 3)
    2. Val av frekvens (0 till 65535)
    3. Längd (antal sekunder genom 60)
    4. Frekvensändring (0 = upp, 1 = ned, 2 = upp och ned)
    5. Låg frekvens (vid frekvensändring, också 0 till 65535)
    6. Hastighet vid frekvensändring (stegstorlek, också 0 till 65535)
    7. Vågform (0 till 3, se sida 28 i detta kapitel)
    8. Pulsbredd (0 till 4096, se sida 29 i detta kapitel)

    Bara genom att läsa argumentlistan så förstår vi att kommandot SOUND är ganska kompetent. Men vi ser också att det saknas en hel del kapacitet innan vi kan säga att vi har en komplett synthesizer, inte minst ADSR[2]-inställningar.

    Argumenten identifieras av sin ordning

    Låt säga att jag vill spela samma ljud som tidigare, men jag vill ange vågformens pulsbredd. Igen, pulsbredd kommer att förklaras på sida 30, men för nu behöver du bara förhålla dig till att jag vill ange den. Att anropa SOUND med argument 1, 2, 3 (som tidigare) och 8 (pulsbredd), utan att ange något där emellan, innebär att jag anger fem kommatecken för att tala om att det är just det åttonde argumentet jag vill ange.

    SOUND 1,3800,60,,,,2,50

    Du bör nu höra ett A, fast med en lite förändrad karaktär på ljudet.

    Frekvensändring

    Oavsett om du vill böja en ton uppåt, nedåt eller oscillera (upp och ned), så måste du ange den högsta frekvensen som argument 2 och den lägsta frekvensen som argument 5.

    Om du vill gå upp en oktav från låga A till höga A, kan du skriva följande kommando:

    SOUND 1,3800,60,0,1900,32

    Kanal 1, hög tonhöjd är 3800, längd är en sekund, riktning är uppåt, låg tonhöjd är 1900, frekvensändringens hastighet är 32.

    Ett problem med att böja toner uppåt är att det andra argumentet faktiskt inte bara är den höga frekvensen, utan även startfrekvensen. Ljudet du hör från ovanstående kommando klättrar en oktav (från 1900), men avslöjar målfrekvensen (3800) under en mycket kort stund.

    Om vi ändrar riktning från 0 (upp) till 1 (ned) så spelas frekvensändringen helt felfritt, eftersom vi lämnar startfrekvensen till målfrekvensen som är argument 5.

    SOUND 1,3800,60,1,1900,32

    Men när jobbet är slutfört, så återstartas det, vilket kan höras i slutet på ovanstående ljud. Det kan man vända till sin fördel, om man vill sätta ljud på t.ex. ett rymdskepp som upprepat skjuter med laser på en fiende:

    SOUND 1,8000,60,1,3000,700

    Man kan riktigt se laserstrålarna färdas genom rymden!

    Nu har vi testat att böja en ton uppåt (riktning 0) och nedåt (riktning 1). Genom att välja att oscillera kan du skapa ljud som låter som larmtoner, som t.ex. detta:

    SOUND 1,12000,360,2,9000,64

    Kanal 1, tonjöjd är 12000, längden är sex sekunder, riktning är upp och ned, låg tonhöjd är 9000, frekvensändringens hastighet är 64.

    Vågformer

    Vågformen beskriver ljudets mest basala karaktär. Commodore 128 kan återge fyra olika vågformer. Dessa är:

    • 0: Triangel (mjuka ljud som xylofon eller flöjt)
    • 1: Sågtand (en klang liknande dragspel eller gitarr)
    • 2: Fyrkant med variabel pulsbredd (lite vassare ljud som trumpet eller piano)
    • 3: Brus (ofta slagverk)

    Dessa fyra vågformer utgör grunden för de olika musikinstrument som din dator kan återge. Detta program spelar upp två sekunder från varje ljud, där fyrkantsvågen återges i sitt grundutförande med en pulsbredd på 2048:

    10 FOR A=0 TO 3
    20 SOUND 1,3800,120,,,,A
    30 SLEEP 3
    40 NEXT
    Rad 10 räknar från 0 till 3, vilket innebär att rad 20 och 30 körs fyra gånger. Rad 20 spelar en ton i två sekunder som byggs upp av de fyra vågformer som din Commodore kan återge. Rad 30 pausar och rad 40 upprepar.

    När du kör programmet så kommer du att höra fyra vågformer, som spelas upp i turordning. Förutom dessa fyra vågformer, kan din Commodore 128 ändra ljudets karaktär rejält när vågform 2 (fyrkant) används, för fyrkantsvågen har variabel pulsbredd.

    Pulsbredd

    Pulsbredden anger förhållandet mellan impulsens höga och låga värde. Fyrkantens värde består i sitt ursprungsförhållande av lika lång hög som låg impuls, vilket skapar denna figur:

    +------------------------------------------------+
    |    ----    ----    ----    ----    ----    ----|
    |                                                |
    |----    ----    ----    ----    ----    ----    |
    +------------------------------------------------+

    Detta motsvara alltså den ursprungliga pulsbredden 2048. 0 är lägst och 4096 är högst. Du kan skriva in följande kommando för att höra den ursprungliga pulsbredden:

    SOUND 1,3800,60,,,,2,2048

    Halverar du talet 2048 (alltså om du anger 1024) får du följande kurva:

    +------------------------------------------------+
    |  ------  ------  ------  ------  ------  ------|
    |                                                |
    |--      --      --      --      --      --      |
    +------------------------------------------------+

    Testa genom att skriva:

    SOUND 1,3800,60,,,,2,1024

    Ljudet är nästan identiskt med det ljud du hade fått av att istället addera hälften (1024) ursprungspulsbredden (2048):

    SOUND 1,3800,60,,,,2,3072

    Det motsvarar följande vågform:

    +------------------------------------------------+
    |      --      --      --      --      --      --|
    |                                                |
    |------  ------  ------  ------  ------  ------  |
    +------------------------------------------------+

    Testa gärna att skriva program som varierar pulsbredden!

    Ljudstyrka

    Kommandot VOL påverkar ljudstyrkan både för pågående ljud och efterföljande ljud. VOL accepterar ett argument som är ett tal mellan 0 och 15, där 0 betyder absolut tystnad och 15 betyder högsta möjliga ljud. Ett för högt eller för lågt värde ger felet illegal quantity. Följande program använder VOL för att oscillera ljudstyrkan:

    10 SOUND 1,12000,360,2,9000,64
    20 FOR T=0 TO 8
    30 FOR A=15 TO 0 STEP -1
    40 VOL A 50 FOR P=0 TO 10:NEXT
    60 NEXT A
    70 FOR A=0 TO 15
    80 VOL A
    90 FOR P=0 TO 10:NEXT 100 NEXT A
    110 NEXT T
    Rad 10 startar ett larmljud.

    Rad 20 säger att volymoscillering ska ske 9 gånger (0 till 8).

    Rad 30-60 sänker volymen med en kort paus (rad 50).

    Rad 70-100 höjer volymen.
    Rad 110 hoppar tillbaka till rad 30 så länge T är mindre än eller lika med 8.


    Inför de kommande två kapitlen om musik och om avancerade ljudeffekter, så kan det vara bra att veta när datorn spelar ett ljud direkt, och när datorn väntar. Grundregeln är att datorn väntar med att spela upp ett ljud, tills det ljud som spelas ljust nu är färdigt, givet att det nya ljudet begärs i en kanal som redan spelar ett ljud. Det innebär följande:

    Kommandot SOUND sätter processorn i arbete utan att blockera BASIC-tolken, vilket vi tidigare sett i kapitlet om sprites. Skillnaden här är att om din dator satts i arbete att spela ett ljud i en sekund på en viss kanal, och stöter på ett kommando som ger datorn i uppdrag att spela en ny ton i samma kanal, så väntar BASIC-tolken på att pågående uppdrag ska vara utfört innan nästa uppdrag påbörjas. Vi kan studera detta genom att titta på följande program som spelar ett C dur-ackord i en kanal. Det kommer inte att fungera. Istället för att höra ett ackord, så hör vi en ton i taget spelas upp (C, E och G). Vi väljer full ljudstyrka.

    10 VOL 15
    20 SOUND 1,8900,120,,,,1
    30 SOUND 1,11100,120,,,,1
    40 SOUND 1,13500,120,,,,1

    Orsaken är att kanal 1 inte kan spela något annat än C innan den är färdig. Och när den är färdig, och börjar spela ett E, så kan den inte spela nästa ton innan den har spelat färdigt E. Lösningen är att spela varje ton i C dur-ackordet i var sin kanal, så här:

    10 VOL 15
    20 SOUND 1,8900,120,,,,1
    30 SOUND 2,11100,120,,,,1
    40 SOUND 3,13500,120,,,,1

    Om nya instruktioner att spela ljud inkommer, väntar din dator med att utföra dem tills ackordet är färdigt. Men det finns undantag, vilket vi tittar på i kapitlet om avancerade ljudeffekter.


    [1] På engelska: Pitch bend.

    [2] Attack, Decay, Sustain, Release – se kapitlet om ordförklaringar (appendix B).