Category: Geeky
-
Actual fullscreen text-console on Windows 7/8
You can’t put the old CMD.EXE in fullscreen anymore, but there is replacement called Console2 that has some cool features. Do not set Console2 as your standard console in Windows you use shortcuts like the Visual Studio Command Prompt, because the different behaviors will set Console2 in an infinite loop.
When installed, you can open the Settings window to tweak appearance, like hide the scrollbars and such. When done, you toggle fullscreen mode using the F11 key. This is what you get:
Update 2014-08-23: The latest version with the fullscreen option is 1.8.0. I am hosting it here.
-
Commodore 128 bitmap graphics 2/2
Part 1. Part 2.
On the Commodore 128, the screen is divided into characters.
Each character consists of eight eight-pixel lines (bytes), which make a total of 64 pixels per character.
Each pixel pair represent one of four available colors in multicolor mode. This can be demonstrated using this simple code:
10 GRAPHIC 3, 1 : REM CREATE CLEAN MULTICOLOR DISPLAY 20 DRAW 1, 0, 0 : REM DRAW USING COLOR 1 30 DRAW 2, 0, 1 : REM DRAW USING COLOR 2 40 DRAW 3, 0, 2 : REM DRAW USING COLOR 3
Now, this pattern is shown:
If you add a line of code to change to high resolution graphics without clearing, we can see that two turned off pixels represent the first color, one off and one on represent color 2, one on and one off represent color 3 and two turned on pixels represent color 4.
50 GRAPHIC 1, 0 : REM CHANGE TO HIGH RESOLUTION WITHOUT CLEARING
The graphics memory is movable. This command places the graphics memory at 2000 (8192 in decimal):
POKE 53272, (PEEK(53272) AND 240) OR 8
The eight pixel pattern of each row in a character can be described using binary 00000000 for all off to 11111111 for all on (0 to 255 in decimal). Placing the number 00011011 (27) will draw one multicolor pixel of each color on the first line. 00 is color 0 (background), 01 is color 1, 10 is color 2 and 11 is color 3.
10 GRAPHICS 3, 1 20 POKE 53272, (PEEK(53272) AND 240) OR 8 30 POKE 8192, 27
-
Commodore 128 bitmap graphics 1/2
Part 1. Part 2.
When Commodore 128 vector graphics can’t provide the desired details, there is an option to do bitmap graphics. The 128 have a built in command for creating pixel perfect graphics called SPRSAV. You can create a pattern using the built-in editor (SPRDEF)…
…and transfer the data into a string variable, and then copy that data to the screen, like so:
10 COLOR 0, 13 20 COLOR 4, 13 30 COLOR 1, 1 40 COLOR 2, 8 50 COLOR 3, 12 60 GRAPHIC 3, 1 70 SPRSAV 1, A$ 80 GSHAPE A$, 10, 10, 2 : REM DRAW SPRITE AT 10, 10 90 GSHAPE A$, 20, 11, 2 100 GSHAPE A$, 30, 12, 2
This should be enough for anyone, but if you like, you can also access the graphics memory directly.
-
Commodore 128 vector graphics
The Commodore 128 have a rich API for making colorful vector graphics. The low resolution (160×200) color mode allows you to make the classic “Forrest Gump” smiley using these five lines of code:
10 COLOR 0, 13 : REM GREY BACKGROUND 20 COLOR 4, 13 : REM GREY BORDER 30 COLOR 1, 1 : REM COLOR 1 IS BLACK 40 COLOR 2, 8 : REM COLOR 2 IS YELLOW 50 COLOR 3, 12 : REM COLOR 3 IS SHADOW (DARK GREY) 60 GRAPHIC 3, 1 : REM LOWRES MULTICOLOR MODE 70 CIRCLE 3, 80, 101, 49, 99 : REM SHADOW OUTLINE 80 PAINT 3, 80, 101 : REM SHADOW FILL 90 CIRCLE 2, 97, 99, 49, 99 : REM SMILEY SIZE 100 PAINT 2, 79, 99 : REM SMILEY FILL 110 CIRCLE 1, 79, 99, 49, 99 : REM SMILEY CONTOUR 120 CIRCLE 1, 65, 70, 8, 22 : REM LEFT EYE 130 PAINT 1, 65, 70 : REM LEFT EYE COLOR 140 CIRCLE 1, 92, 70, 8, 22 : REM RIGHT EYE 150 PAINT 1, 92, 70 : REM RIGHT EYE COLOR 160 CIRCLE 1, 79, 99, 39, 85, 90, 280 :REM MOUTH
To exit the program on a real 128, press Runstop + Restore. On the Vice emulator, press Caps Lock + Page Up. However, the Commodore 128 API is not very suitable for bitmap graphics. For that, other Commodore Basic strategies are more suitable.
-
Action Biker
Nu har jag stulit så mycket jag bara kan: Rob Hubbards komposition, Trevor Horns sound (efter bästa förmåga). Detta är en cover på soundtracket till Action Biker från 1985.
-
Evolutionary sudoku
This is a successful attempt to use an evolutionary algorithm to generate a sudoku board. A complete board is created after usually less than a million iterations, sometimes after a couple of hundred generations.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { var s = new Sudoku(); s.Display(); Console.Write("Done. Press enter to quit."); Console.ReadLine(); } } class Sudoku { int[,] field = new int[9,9]; const int mutation_speed = 3; const int dead_end_limit = 60000; public Sudoku() { var r = new Random(); //Create a list of possible characters on the game field. var l = new List<int>(); for (var i = 1; i < 10; i++) for (var j = 1; j < 10; j++) l.Add(i); //Place them on the field randomly. for (var i = 0; i < 9; i++) for (var j = 0; j < 9; j++) { var index = r.Next(0, l.Count); var value = l[index]; l.RemoveAt(index); this.field[j, i] = value; } //Prepare for score counting. Low is better. int score = int.MaxValue, iterations = 0, generations = 0, iterations_since_last_climb = 0; //Define how a mutation works - a random element swap. Action<int[,]> mutate = a => { var speed = (score > 2 ? mutation_speed : 1); for (var i = 0; i < speed; i++) { int x1 = r.Next(0, 9), y1 = r.Next(0, 9), x2 = r.Next(0, 9), y2 = r.Next(0, 9); var v = a[x1, y1]; a[x1, y1] = a[x2, y2]; a[x2, y2] = v; } }; //Show progress. Action status = () => { Console.Title = string .Format("Score: {0:00} - Generations: {1:000} - " + "Iterations: {2:000000}" + " - Since last climb: {3:00000}", score, generations, iterations, iterations_since_last_climb); }; //Let evolution work. do { iterations++; //If adaptation has stopped, the parent must mutate. if (iterations_since_last_climb >= dead_end_limit) { mutate(this.field); score = this.GetScore(this.field); } //Breed two new sudokos and modify them slightly. int[,] child1 = (int[,])this.field.Clone(); int[,] child2 = (int[,])this.field.Clone(); mutate(child1); mutate(child2); //Check new scores. var child1score = this.GetScore(child1); var child2score = this.GetScore(child2); //Keep the best one, if any. Action<int[,], int> keep = (a, s) => { this.field = (int[,])a.Clone(); score = s; generations++; iterations_since_last_climb = 0; }; if (child1score < score) keep(child1, child1score); else if (child2score < score) keep(child2, child2score); else iterations_since_last_climb++; System.Threading.Thread.Yield(); if ((iterations % 1000) == 0) status(); #if DEBUG this.Display(); Console.CursorTop = 0; #endif } while (score > 0); status(); } private int GetScore(int[,] p) { //Define how fitness is determined. A better solution is wanted. Func<int[,], int, int, bool> checkrow = (arr, x, y) => { var val = arr[x, y]; var count = 0; for (var i = 0; i < 9; i++) if (arr[i, y] == val) count++; return (count == 1); }; Func<int[,], int, int, bool> checkcol = (arr, x, y) => { var val = arr[x, y]; var count = 0; for (var i = 0; i < 9; i++) if (arr[x, i] == val) count++; return (count == 1); }; Func<int[,], int, int, bool> checksection = (arr, x, y) => { var section_x = x; while (!((section_x % 3) == 0)) section_x--; var section_y = y; while (!((section_y % 3) == 0)) section_y--; var val = arr[x, y]; var count = 0; for (var row = section_x; row < section_x + 3; row++) for (var col = section_y; col < section_y + 3; col++) if (arr[col, row] == val) count++; return (count == 1); }; var score = 0; for (var i = 0; i < 9; i++) for (var j = 0; j < 9; j++) { if (!(checkrow(p, j, i))) score++; if (!(checkcol(p, j, i))) score++; if (!(checksection(p, j, i))) score++; } return score; } public void Display() { for (var y = 0; y < 9; y++) { for (var x = 0; x < 9; x++) Console.Write(field[x, y]); Console.WriteLine(); } } } }
Update 2023-02-09: .NET 7.0 source code
-
Vic 20-labyrinten
Vissa är säkert bekanta labyrintalgoritmen för Commodore 64, känd för de mer eller mindre slumpmässiga förutsättningarna som gör att en labyrint kan genereras med minimal kod. Koden jag tänker på är givetvis denna (Commodore Basic 2.0):
10 PRINT CHR$(205.5+RND(1));:GOTO 10
Koden är faktiskt inte klockren på C64. Med en hög upplösning (320*200 pixlar) i åtanke, satsade man på teckengrafik som alltid hade minst två pixlars bredd, eftersom detta gjorde grafiken mer visuell. Det ledde till att grafiken såg “trasig” ut när man körde program som inte tog hänsyn till detta.
Vic 20 däremot, med sin låga upplösning (352*184), behövde inte använda dubbla pixlar på vertikala linjer. Och eftersom Vic 20 och C64 delade Basic (Commodore Basic 2.0) är labyrintkoden i fråga kompatibel med Vic 20. Om vi bryter ner koden, har vi följande:
1. RND(1) är ett slumptal mellan 0 och strax under 1.
2. 205,5 + RND(1) är antingen 205 eller 206 (\ eller / – inte backslash respektive slash – snarare diagonal åt höger och diagonal åt vänster) beroende på vad som tilldelas 205,5 eftersom CHR$ konverterar sin parameter till ett heltal genom att avlägsna decimaldelen. Om RND(1) är t.ex. 0,1 eller 0,4 är 205,5 + 0,4 = 205, men om 205,5 tilldelas 0,6 blir resultatet 206. Vi har alltså att göra med en implisiv typomvandling från realtal till heltal.
3. PRINT CHR$(205) ger en diagonal linje från vänster till höger, och CHR$(306) ger en diagonal linje från höger till vänster. Koden i fråga ger alltså antingen \ eller / i en följd, vilket ger en labyrint.
Detta är resultatet av koden på en Commodore 64 eller 128:
Detta är resultatet av samma kod på en Vic 20:
-
Gratis Instagram från Windows
Att komma igång med Instagram från din vanliga PC (eller Mac) kräver lite mickel, men är helt gratis och fungerar utmärkt när man väl är igång. Med Instagram installerat kan du posta filer från ditt lokala filsystem, och eftersom lösningen bygger på det mycket trevliga projektet BlueStacks, ger det dig samtidigt tillgång till Google Play. Här är de 10 steg du behöver ta:
1. Installera BlueStacks. Jag har varit med om att detta krånglar på Windows 7, men jag har installerat det på två Windows 8-maskiner helt utan problem (en HP EliteBook och en ASUS). Under installationen, välj gärna att du vill ha App store access och App notifications.
Under första fasen kopierar installationsprogrammet för BlueStacks filerna. När detta är klart kommer en ny stapel att titta på medan runtime data laddas hem. Efter att första fasen är klar, dyker BlueStacks-ikonen upp i aktivitetsfältet.
När installationen är klar, startas BlueStacks App Player (BSAP) i fullskärmsläge. Ett tryck på F11 placerar BSAP i ett vanligt fönster.
2. Avsluta BSAP och starta BSAP genom att dubbelklicka på Start BlueStacks på skrivbordet. Detta borde sätta BSAP i registreringsläge. Detta är nödvändigt för att Google Play ska kunna användas. Följ alla steg så att både registreringen av enheten och synkroniseringsfunktionen blir aktiverad. Aslutningsvis ser du en tom skärm med texten Select your mobile devices. Klicka Done så är du klar.
3. Klicka på sökknappen uppe till vänster. Sök reda på Instagram och installera den. Växla till My Apps, starta Instagram. Registrera ett konto om det behövs, annars, logga in med ditt befintliga instagramkonto.
4. Klicka på sökknappen igen, installera ES File Explorer.
5. Skapa en genväg till mappen C:\ProgramData\BlueStacks\UserData\SharedFolder – det är den du kan nå från BlueStacks. Placera bilden du vill publicera där.
6. När du ska posta en bild från Instagram-appen, välj att hämta den från Android-mappen /sdcard/bstfolder/BstSharedFolder. Där hittar du din bild.
På vissa system behöver du roota BlueStacks. Det är ingen konst att göra, men nedladdningen var lite omständig, eftersom sidan innehåller en download manager som är totalt hopplös. Stegen är dock tydligt förklarade på denna sida.
Om det gick bra, följ mig gärna på Instagram!
-
Skalning av vektorgrafik på Commodore 128
Genom kommandot SCALE kan man skala vektorgrafiken, alltså den grafik som skapas med kommandon som DRAW, CIRCLE och BOX – inte sprite-grafik eller text. När man arbetar med högupplöst grafik utan skalning är skärmen 320 pixlar bred och 200 pixlar hög. Detta program skapar en stor ellips som tar upp nästan hela skärmen.
10 GRAPHIC 1, 1 : REM AKTIVERA HÖGUPPLÖST GRAFIK 20 CIRCLE 1, 159, 99, 130, 80 : REM RITA EN ELLIPS ÖVER NÄSTAN HELA 30 INPUT A$ : REM TRYCK PÅ ENTER FÖR ATT AVSLUTA 40 GRAPHIC 0 : REM ÅTERGÅ TILL TEXT-LÄGET
Genom att infoga SCALE-kommandot efter GRAPHIC-kommandot påverkar man skalan på det som ritas efter anropet på SCALE. SCALE har ingen effekt om det anropas innan man gått in i grafikläget (före GRAPHIC-anropet) och påverkar det som ritas därefter. Det första argumentet som skickas till SCALE är 1 för att aktivera skalning. Det andra är den antalet virtuella pixlar du vill ha i X-led, och det tredje är antalet virtuella pixlar du vill ha i Y-led.
Här infogar jag ett anrop på SCALE på rad 15 (efter GRAPHIC på rad 10) och anropar sedan RENUMBER för att få tillbaka jämna mellanrum mellan raderna. Även om pixlarna fortfarande är lika stora, ritas nu bilden med den virtuella upplösningen av 640 * 400 pixlar.
10 GRAPHIC 1, 1 : REM AKTIVERA HÖGUPPLÖST GRAFIK 20 SCALE 1, 640, 400 30 CIRCLE 1, 159, 99, 130, 80 : REM RITA SAMMA ELLIPS 40 INPUT A$ : REM TRYCK PÅ ENTER FÖR ATT AVSLUTA 50 GRAPHIC 0 : REM ÅTERGÅ TILL TEXT-LÄGET
Detta är användbart när man tänker på att flerfärgsläget innehåller väldigt breda pixlar. När flerfärgsgrafik används består skärmen (som är i 4:3-format) av 160 * 200 pixlar. Om vi kör ursprungsprogrammet, utan SCALE-anropet, i flerfärgsläge (läge 3).
10 GRAPHIC 3, 1 : REM AKTIVERA FLERFÄRGSGRAFIK 20 CIRCLE 1, 159, 99, 130, 80 : REM RITA SAMMA ELLIPS 30 INPUT A$ : REM TRYCK PÅ ENTER FÖR ATT AVSLUTA 40 GRAPHIC 0 : REM ÅTERGÅ TILL TEXT-LÄGET
Men trots pixlarnas storlek, kan man alltså behålla den virtuella upplösningen av 320 * 200 genom att anropa SCALE. Nu blir det dock lite lustigt. SCALE kompenserar inte för pixlarnas bredd, så de virtuella 320 * 200 pixlarna får vi när vi ber om 640 * 200 pixlar.
10 GRAPHIC 3, 1 : REM AKTIVERA FLERFÄRGSGRAFIK 20 SCALE 1, 640, 200 30 CIRCLE 1, 159, 99, 130, 80 : REM RITA SAMMA ELLIPS 40 INPUT A$ : REM TRYCK PÅ ENTER FÖR ATT AVSLUTA 50 GRAPHIC 0 : REM ÅTERGÅ TILL TEXT-LÄGET
För att stänga av skalning, anropa SCALE med argumentet 0.
-
Atari Sky Raider
What the fuck is this? In 1978 Atari releases the arcade game Sky Driver. Insert a coin, and experience spectacular semi-3D graphics. You are controlling a bomber on an airplane and you fire away on objects on the ground. Suddenly, the “time is out” and the game is over. In the middle of all the fun, you are told to walk away or add more coins. So HOW do I get extended play? Why do you do this to me, Atari?
-
TPB AFK
Om du är en del av copyrightlobbyn eller om du av andra skäl står oförstående för tankar kring rättssäkerhet, är detta inte texten för dig.
Innan jag såg filmen TPB AFK trodde jag att Sverige kvalificerade som bananrepublik eftersom man iscensatte rättegångar på grund av att man såg ett hot man helt enkelt inte kunde hantera. Men det är något annat är problemet.
Själva idén om att torrents är ett nytt sätt att sprida information är inte en aspekt som vill samtalas, och själva idén att kommersiella företag, filmbolag, musikbolag eller vad som helst, kan tjäna pengar på att exploatera marknaden som den ser ut, hånas. Alltså, det som alla andra affärsidkare är förpassade till, hånar musikindustrin. Åklagaren vann, eftersom åklagaren och domaren var samma juridiska person. Domaren stämde, och dömde. Och vann. I många andra länder ska domaren vara en utomstående jurist, men inte i Sverige.
Avgörande för domen är inte personerna bakom The Pirate Bay, utan det faktum att ny teknik kan exploateras för olaglig verksamhet, och att tillgängliggöra ny teknik var det verkliga brottet. Och sen var det den där lilla frågan om hur förluster verkligen beräknas. Mediaindustrin är den enda bransch som på allvar påstår att de har ett negativt antal anställda, och med hjälp av “copyright math” beräknar man vilket skadestånd man ska ha.
Som upphovsman inom mjukvara och musik, skulle jag önska att jag inte hade personer som åklagare Håkan Roswall eller domare Tomas Norström på min sida. Kreativitet inom infrastruktur måste börja betraktas som en plattform och i förläningen en förutsättning för dem som producerar innehåll. Att reflexmässigt fuska inom juridiken vid minsta motgång, är ett tecken på att man inte är mogen att ta sig an branschen över huvudet taget.
Piratkopiering är fel, men upphovsrättsmännen har gjort sig själva till ett korrupt särintresse. Forskning och framsteg är verkligen ett problem, men också ett nödvändigt sådant, eftersom frånvaron av utveckling också är ett problem, om möjligt ett ännu större. Att jaga personer som illegalt delar filer, piratkopierar eller profiterar på andras verk, borde intressera upphovsrättsinnehavarna.
Är The Pirate Bay den första organisationen som representerar nya distributionskanaler som upphovsrättsindustrin ger sig på? Nej, samtliga kanaler som de exploaterat för att tjäna pengar, har de först motarbetat. Det är så man känner igen personer med tveksam affärsmoral.
-

Boot Hill 1977
I associate Boot Hill with cheap restaurants along country roads that I visited in the early eighties when while traveling from and to national vacation destinations. However, the game itself is excellent, especially if you consider that it came out in 1977. The idea is simple – kill your opponent with a pistol – but artwork and audio is superb. And as a kid, after spending 4-5 hours in a car reading Spiderman while the radio playing easy listening, this was great. Try it out!
-

På allmän begäran (nåja)
Efter att ha slängt ihop en enkel digitaliseringskod i VB som exporterar Commodore 128-kod, kan jag nu tillgodose önskemålet som alla Commodore-användare har: En idolbild på mig!
Detta är koden som genererades. Notera hur digitaliseraren lagrar två instruktioner per rad, och att den skapar “tända” pixlar som DRAW-instruktioner. Flera tända pixlar på raden, genereras som horisontella linjer.
10 COLOR 1,16:COLOR 2,12:GRAPHIC 1,1 20 DRAW 1,147,4 TO 150,4:DRAW 1,144,5 TO 152,5 30 DRAW 1,155,5 TO 161,5:DRAW 1,142,6 TO 164,6 40 DRAW 1,139,7 TO 166,7:DRAW 1,138,8 TO 167,8 50 DRAW 1,136,9 TO 169,9:DRAW 1,135,10 TO 170,10 60 DRAW 1,134,11 TO 171,11:DRAW 1,132,12 TO 172,12 70 DRAW 1,131,13 TO 172,13:DRAW 1,130,14 TO 173,14 80 DRAW 1,129,15 TO 174,15:DRAW 1,129,16 TO 175,16 90 DRAW 1,128,17 TO 176,17:DRAW 1,127,18 TO 176,18 100 DRAW 1,126,19 TO 177,19:DRAW 1,126,20 TO 178,20 110 DRAW 1,125,21 TO 178,21:DRAW 1,125,22 TO 179,22 120 DRAW 1,124,23 TO 159,23:DRAW 1,163,23 130 DRAW 1,166,23 TO 180,23:DRAW 1,124,24 TO 154,24 140 DRAW 1,170,24 TO 180,24:DRAW 1,123,25 TO 149,25 150 DRAW 1,172,25 TO 180,25:DRAW 1,123,26 TO 148,26 160 DRAW 1,173,26 TO 180,26:DRAW 1,123,27 TO 147,27 170 DRAW 1,174,27 TO 180,27:DRAW 1,123,28 TO 147,28 180 DRAW 1,175,28 TO 181,28:DRAW 1,123,29 TO 146,29 190 DRAW 1,176,29 TO 181,29:DRAW 1,122,30 TO 147,30 200 DRAW 1,176,30 TO 182,30:DRAW 1,122,31 TO 144,31 210 DRAW 1,147,31:DRAW 1,177,31 TO 182,31 220 DRAW 1,122,32 TO 144,32:DRAW 1,147,32 TO 148,32 230 DRAW 1,176,32 TO 182,32:DRAW 1,122,33 TO 145,33 240 DRAW 1,148,33:DRAW 1,150,33 250 DRAW 1,177,33 TO 182,33:DRAW 1,122,34 TO 146,34 260 DRAW 1,177,34 TO 182,34:DRAW 1,122,35 TO 146,35 270 DRAW 1,177,35 TO 181,35:DRAW 1,122,36 TO 147,36 280 DRAW 1,177,36 TO 181,36:DRAW 1,122,37 TO 147,37 290 DRAW 1,177,37 TO 181,37:DRAW 1,122,38 TO 147,38 300 DRAW 1,178,38 TO 181,38:DRAW 1,121,39 TO 149,39 310 DRAW 1,178,39 TO 181,39:DRAW 1,121,40 TO 152,40 320 DRAW 1,171,40:DRAW 1,178,40 TO 180,40 330 DRAW 1,121,41 TO 153,41:DRAW 1,165,41 TO 170,41 340 DRAW 1,178,41 TO 180,41:DRAW 1,121,42 TO 147,42 350 DRAW 1,150,42 TO 155,42:DRAW 1,166,42 TO 167,42 360 DRAW 1,121,43 TO 157,43:DRAW 1,166,43 TO 170,43 370 DRAW 1,120,44 TO 158,44:DRAW 1,164,44 TO 169,44 380 DRAW 1,173,44:DRAW 1,120,45 TO 149,45 390 DRAW 1,152,45 TO 158,45:DRAW 1,164,45 TO 165,45 400 DRAW 1,167,45 TO 168,45:DRAW 1,120,46 TO 149,46 410 DRAW 1,152,46 TO 158,46:DRAW 1,164,46 TO 165,46 420 DRAW 1,167,46 TO 168,46:DRAW 1,122,47 TO 149,47 430 DRAW 1,151,47 TO 158,47:DRAW 1,165,47 TO 166,47 440 DRAW 1,122,48 TO 158,48:DRAW 1,122,49 TO 159,49 450 DRAW 1,122,50 TO 145,50:DRAW 1,150,50 TO 159,50 460 DRAW 1,122,51 TO 140,51:DRAW 1,150,51 TO 159,51 470 DRAW 1,122,52 TO 140,52:DRAW 1,151,52 TO 159,52 480 DRAW 1,122,53 TO 123,53:DRAW 1,125,53 TO 140,53 490 DRAW 1,153,53 TO 159,53:DRAW 1,122,54 TO 123,54 500 DRAW 1,125,54 TO 141,54:DRAW 1,152,54 TO 159,54 510 DRAW 1,122,55 TO 123,55:DRAW 1,125,55 TO 141,55 520 DRAW 1,152,55 TO 158,55:DRAW 1,178,55 530 DRAW 1,125,56 TO 141,56:DRAW 1,143,56 540 DRAW 1,152,56 TO 158,56:DRAW 1,178,56 TO 179,56 550 DRAW 1,125,57 TO 142,57:DRAW 1,152,57 TO 159,57 560 DRAW 1,178,57:DRAW 1,124,58 TO 143,58 570 DRAW 1,152,58 TO 154,58:DRAW 1,156,58 TO 159,58 580 DRAW 1,178,58:DRAW 1,127,59 TO 143,59 590 DRAW 1,153,59 TO 154,59:DRAW 1,156,59 TO 160,59 600 DRAW 1,163,59 TO 164,59:DRAW 1,178,59 610 DRAW 1,128,60 TO 144,60:DRAW 1,153,60 TO 159,60 620 DRAW 1,129,61 TO 144,61:DRAW 1,153,61 TO 158,61 630 DRAW 1,130,62 TO 144,62:DRAW 1,153,62 TO 158,62 640 DRAW 1,131,63 TO 146,63:DRAW 1,152,63 TO 157,63 650 DRAW 1,132,64 TO 146,64:DRAW 1,151,64 TO 157,64 660 DRAW 1,161,64:DRAW 1,132,65 TO 156,65 670 DRAW 1,132,66 TO 156,66:DRAW 1,133,67 TO 154,67 680 DRAW 1,133,68 TO 160,68:DRAW 1,162,68 690 DRAW 1,133,69 TO 147,69:DRAW 1,150,69 TO 157,69 700 DRAW 1,134,70 TO 146,70:DRAW 1,149,70 TO 156,70 710 DRAW 1,134,71 TO 155,71:DRAW 1,135,72 TO 155,72 720 DRAW 1,135,73 TO 153,73:DRAW 1,136,74 TO 156,74 730 DRAW 1,136,75 TO 156,75:DRAW 1,136,76 TO 156,76 740 DRAW 1,136,77 TO 155,77:DRAW 1,135,78 TO 155,78 750 DRAW 1,134,79 TO 156,79:DRAW 1,133,80 TO 155,80 760 DRAW 1,133,81 TO 155,81:DRAW 1,132,82 TO 155,82 770 DRAW 1,131,83 TO 143,83:DRAW 1,146,83 TO 149,83 780 DRAW 1,131,84 TO 144,84:DRAW 1,148,84 TO 149,84 790 DRAW 1,130,85 TO 135,85:DRAW 1,137,85 TO 144,85 800 DRAW 1,129,86 TO 136,86:DRAW 1,138,86 TO 144,86 810 DRAW 1,128,87 TO 137,87:DRAW 1,140,87 TO 143,87 820 DRAW 1,173,87:DRAW 1,128,88 TO 137,88 830 DRAW 1,141,88 TO 144,88:DRAW 1,173,88 TO 174,88 840 DRAW 1,127,89 TO 138,89:DRAW 1,142,89 TO 144,89 850 DRAW 1,173,89 TO 175,89:DRAW 1,126,90 TO 139,90 860 DRAW 1,144,90 TO 145,90:DRAW 1,173,90 TO 175,90 870 DRAW 1,126,91 TO 140,91:DRAW 1,173,91 TO 176,91 880 DRAW 1,125,92 TO 140,92:DRAW 1,174,92 TO 178,92 890 DRAW 1,123,93 TO 141,93:DRAW 1,174,93 TO 184,93 900 DRAW 1,122,94 TO 142,94:DRAW 1,174,94 TO 187,94 910 DRAW 1,119,95 TO 143,95:DRAW 1,174,95 TO 190,95 920 DRAW 1,117,96 TO 145,96:DRAW 1,175,96 TO 192,96 930 DRAW 1,115,97 TO 145,97:DRAW 1,176,97 TO 179,97 940 DRAW 1,181,97 TO 195,97:DRAW 1,113,98 TO 146,98 950 DRAW 1,176,98 TO 198,98:DRAW 1,111,99 TO 147,99 960 DRAW 1,173,99:DRAW 1,176,99 TO 202,99 970 DRAW 1,110,100 TO 148,100:DRAW 1,171,100 TO 173,100 980 DRAW 1,176,100 TO 205,100:DRAW 1,108,101 TO 149,101 990 DRAW 1,171,101 TO 173,101:DRAW 1,177,101 TO 184,101 1000 DRAW 1,186,101 TO 204,101:DRAW 1,206,101 TO 209,101 1010 DRAW 1,106,102 TO 149,102:DRAW 1,170,102 TO 173,102 1020 DRAW 1,177,102 TO 184,102:DRAW 1,186,102 TO 206,102 1030 DRAW 1,208,102 TO 210,102:DRAW 1,105,103 TO 150,103 1040 DRAW 1,170,103 TO 173,103:DRAW 1,177,103 TO 184,103 1050 DRAW 1,186,103 TO 211,103:DRAW 1,103,104 TO 117,104 1060 DRAW 1,120,104 TO 151,104:DRAW 1,170,104 TO 173,104 1070 DRAW 1,177,104 TO 185,104:DRAW 1,188,104 TO 212,104 1080 DRAW 1,101,105 TO 121,105:DRAW 1,125,105 TO 151,105 1090 DRAW 1,170,105 TO 173,105:DRAW 1,178,105 TO 185,105 1100 DRAW 1,189,105 TO 212,105:DRAW 1,100,106 TO 121,106 1110 DRAW 1,125,106 TO 151,106:DRAW 1,170,106 TO 173,106 1120 DRAW 1,178,106 TO 186,106:DRAW 1,190,106 TO 213,106 1130 DRAW 1,99,107 TO 112,107:DRAW 1,115,107 TO 122,107 1140 DRAW 1,126,107 TO 152,107:DRAW 1,169,107 TO 172,107 1150 DRAW 1,178,107 TO 186,107:DRAW 1,191,107 TO 213,107 1160 DRAW 1,98,108 TO 113,108:DRAW 1,117,108 TO 122,108 1170 DRAW 1,126,108 TO 153,108:DRAW 1,170,108 TO 172,108 1180 DRAW 1,178,108 TO 189,108:DRAW 1,191,108 TO 214,108 1190 DRAW 1,96,109 TO 110,109:DRAW 1,113,109 1200 DRAW 1,115,109 TO 124,109:DRAW 1,127,109 TO 154,109 1210 DRAW 1,170,109 TO 172,109:DRAW 1,178,109 TO 186,109 1220 DRAW 1,188,109 TO 190,109:DRAW 1,192,109 TO 214,109 1230 DRAW 1,95,110 TO 112,110:DRAW 1,116,110 TO 124,110 1240 DRAW 1,128,110 TO 155,110:DRAW 1,169,110 1250 DRAW 1,171,110 TO 172,110:DRAW 1,178,110 TO 187,110 1260 DRAW 1,190,110 TO 215,110:DRAW 1,94,111 TO 112,111 1270 DRAW 1,115,111 TO 125,111:DRAW 1,128,111 TO 155,111 1280 DRAW 1,171,111 TO 172,111:DRAW 1,178,111 TO 188,111 1290 DRAW 1,192,111 TO 215,111:DRAW 1,94,112 TO 124,112 1300 DRAW 1,128,112 TO 156,112:DRAW 1,171,112 TO 172,112 1310 DRAW 1,178,112 TO 189,112:DRAW 1,193,112 TO 215,112 1320 DRAW 1,92,113 TO 124,113:DRAW 1,129,113 TO 157,113 1330 DRAW 1,171,113 TO 172,113:DRAW 1,179,113 TO 190,113 1340 DRAW 1,193,113 TO 215,113:DRAW 1,91,114 TO 125,114 1350 DRAW 1,129,114 TO 157,114:DRAW 1,171,114 1360 DRAW 1,179,114 TO 216,114:DRAW 1,91,115 TO 126,115 1370 DRAW 1,129,115 TO 158,115:DRAW 1,170,115 TO 171,115 1380 DRAW 1,179,115 TO 216,115:DRAW 1,90,116 TO 112,116 1390 DRAW 1,114,116 TO 118,116:DRAW 1,121,116 TO 127,116 1400 DRAW 1,130,116 TO 158,116:DRAW 1,169,116 TO 171,116 1410 DRAW 1,179,116 TO 216,116:DRAW 1,90,117 TO 113,117 1420 DRAW 1,116,117 TO 118,117:DRAW 1,121,117 TO 128,117 1430 DRAW 1,130,117 TO 159,117:DRAW 1,169,117 TO 171,117 1440 DRAW 1,179,117 TO 216,117:DRAW 1,89,118 TO 113,118 1450 DRAW 1,117,118 TO 119,118:DRAW 1,121,118 TO 129,118 1460 DRAW 1,131,118 TO 160,118:DRAW 1,170,118 TO 171,118 1470 DRAW 1,179,118 TO 216,118:DRAW 1,88,119 TO 114,119 1480 DRAW 1,122,119 TO 129,119:DRAW 1,132,119 TO 160,119 1490 DRAW 1,170,119 TO 171,119:DRAW 1,180,119 TO 218,119 1500 DRAW 1,88,120 TO 119,120:DRAW 1,126,120 TO 129,120 1510 DRAW 1,133,120 TO 161,120:DRAW 1,180,120 TO 219,120 1520 DRAW 1,88,121 TO 113,121:DRAW 1,115,121 TO 119,121 1530 DRAW 1,127,121 TO 130,121:DRAW 1,134,121 TO 162,121 1540 DRAW 1,180,121 TO 219,121:DRAW 1,87,122 TO 114,122 1550 DRAW 1,116,122 TO 121,122:DRAW 1,127,122 TO 131,122 1560 DRAW 1,135,122 TO 162,122:DRAW 1,180,122 TO 219,122 1570 DRAW 1,87,123 TO 122,123:DRAW 1,128,123 TO 133,123 1580 DRAW 1,137,123 TO 163,123:DRAW 1,181,123 TO 220,123 1590 DRAW 1,87,124 TO 123,124:DRAW 1,128,124 TO 134,124 1600 DRAW 1,138,124 TO 163,124:DRAW 1,176,124 1610 DRAW 1,181,124 TO 221,124:DRAW 1,87,125 TO 124,125 1620 DRAW 1,128,125 TO 137,125:DRAW 1,139,125 TO 164,125 1630 DRAW 1,173,125 TO 177,125:DRAW 1,181,125 TO 222,125 1640 DRAW 1,87,126 TO 125,126:DRAW 1,129,126 TO 165,126 1650 DRAW 1,173,126 TO 177,126:DRAW 1,181,126 TO 222,126 1660 DRAW 1,87,127 TO 126,127:DRAW 1,130,127 TO 165,127 1670 DRAW 1,174,127 TO 178,127:DRAW 1,181,127 TO 218,127 1680 DRAW 1,220,127 TO 222,127:DRAW 1,87,128 TO 127,128 1690 DRAW 1,131,128 TO 166,128:DRAW 1,174,128 TO 177,128 1700 DRAW 1,181,128 TO 222,128:DRAW 1,87,129 TO 128,129 1710 DRAW 1,132,129 TO 166,129:DRAW 1,176,129 TO 177,129 1720 DRAW 1,181,129 TO 222,129:DRAW 1,87,130 TO 129,130 1730 DRAW 1,133,130 TO 166,130:DRAW 1,176,130 TO 177,130 1740 DRAW 1,181,130 TO 222,130:DRAW 1,87,131 TO 130,131 1750 DRAW 1,134,131 TO 167,131:DRAW 1,181,131 TO 222,131 1760 DRAW 1,87,132 TO 131,132:DRAW 1,135,132 TO 167,132 1770 DRAW 1,181,132 TO 222,132:DRAW 1,87,133 TO 132,133 1780 DRAW 1,138,133 TO 168,133:DRAW 1,176,133 1790 DRAW 1,181,133 TO 224,133:DRAW 1,87,134 TO 133,134 1800 DRAW 1,136,134:DRAW 1,139,134 TO 168,134 1810 DRAW 1,176,134:DRAW 1,181,134 TO 224,134 1820 DRAW 1,87,135 TO 134,135:DRAW 1,139,135 TO 168,135 1830 DRAW 1,181,135 TO 225,135:DRAW 1,88,136 TO 135,136 1840 DRAW 1,140,136 TO 169,136:DRAW 1,181,136 TO 225,136 1850 DRAW 1,88,137 TO 136,137:DRAW 1,141,137 TO 169,137 1860 DRAW 1,181,137 TO 226,137:DRAW 1,88,138 TO 137,138 1870 DRAW 1,142,138 TO 170,138:DRAW 1,181,138 TO 226,138 1880 DRAW 1,88,139 TO 137,139:DRAW 1,142,139 TO 170,139 1890 DRAW 1,182,139 TO 227,139:DRAW 1,88,140 TO 138,140 1900 DRAW 1,142,140 TO 170,140:DRAW 1,182,140 TO 228,140 1910 DRAW 1,89,141 TO 139,141:DRAW 1,143,141 TO 170,141 1920 DRAW 1,182,141 TO 228,141:DRAW 1,89,142 TO 140,142 1930 DRAW 1,143,142 TO 170,142:DRAW 1,182,142 TO 229,142 1940 DRAW 1,89,143 TO 140,143:DRAW 1,144,143 TO 171,143 1950 DRAW 1,182,143 TO 230,143:DRAW 1,89,144 TO 141,144 1960 DRAW 1,144,144 TO 171,144:DRAW 1,182,144 TO 230,144 1970 DRAW 1,89,145 TO 142,145:DRAW 1,145,145 TO 171,145 1980 DRAW 1,182,145 TO 231,145:DRAW 1,89,146 TO 143,146 1990 DRAW 1,146,146 TO 171,146:DRAW 1,182,146 TO 231,146 2000 DRAW 1,90,147 TO 144,147:DRAW 1,146,147 TO 172,147 2010 DRAW 1,182,147 TO 231,147:DRAW 1,90,148 TO 144,148 2020 DRAW 1,147,148 TO 172,148:DRAW 1,182,148 TO 232,148 2030 DRAW 1,90,149 TO 146,149:DRAW 1,148,149 TO 172,149 2040 DRAW 1,182,149 TO 232,149:DRAW 1,90,150 TO 146,150 2050 DRAW 1,148,150 TO 172,150:DRAW 1,182,150 TO 233,150 2060 DRAW 1,90,151 TO 173,151:DRAW 1,182,151 TO 233,151 2070 DRAW 1,90,152 TO 148,152:DRAW 1,150,152 TO 173,152 2080 DRAW 1,183,152 TO 214,152:DRAW 1,218,152 TO 234,152 2090 DRAW 1,90,153 TO 148,153:DRAW 1,151,153 TO 173,153 2100 DRAW 1,183,153 TO 215,153:DRAW 1,219,153 TO 235,153 2110 DRAW 1,91,154 TO 149,154:DRAW 1,152,154 TO 174,154 2120 DRAW 1,183,154 TO 215,154:DRAW 1,219,154 TO 236,154 2130 DRAW 1,91,155 TO 150,155:DRAW 1,152,155 TO 174,155 2140 DRAW 1,183,155 TO 214,155:DRAW 1,219,155 TO 220,155 2150 DRAW 1,222,155 TO 237,155:DRAW 1,91,156 TO 151,156 2160 DRAW 1,153,156 TO 174,156:DRAW 1,183,156 TO 214,156 2170 DRAW 1,219,156:DRAW 1,223,156 TO 237,156 2180 DRAW 1,91,157 TO 151,157:DRAW 1,154,157 TO 174,157 2190 DRAW 1,182,157 TO 213,157:DRAW 1,218,157 TO 219,157 2200 DRAW 1,224,157 TO 237,157:DRAW 1,92,158 TO 152,158 2210 DRAW 1,154,158 TO 175,158:DRAW 1,182,158 TO 213,158 2220 DRAW 1,218,158 TO 219,158:DRAW 1,224,158 TO 238,158 2230 DRAW 1,92,159 TO 153,159:DRAW 1,155,159 TO 175,159 2240 DRAW 1,182,159 TO 213,159:DRAW 1,217,159 TO 219,159 2250 DRAW 1,223,159 TO 238,159:DRAW 1,92,160 TO 154,160 2260 DRAW 1,156,160 TO 175,160:DRAW 1,182,160 TO 211,160 2270 DRAW 1,216,160 TO 218,160:DRAW 1,223,160 TO 239,160 2280 DRAW 1,92,161 TO 155,161:DRAW 1,157,161 TO 176,161 2290 DRAW 1,182,161 TO 211,161:DRAW 1,216,161 TO 218,161 2300 DRAW 1,223,161 TO 239,161:DRAW 1,93,162 TO 156,162 2310 DRAW 1,158,162 TO 176,162:DRAW 1,182,162 TO 211,162 2320 DRAW 1,216,162 TO 218,162:DRAW 1,222,162 TO 240,162 2330 DRAW 1,93,163 TO 176,163:DRAW 1,182,163 TO 211,163 2340 DRAW 1,215,163 TO 217,163:DRAW 1,222,163 TO 240,163 2350 DRAW 1,93,164 TO 176,164:DRAW 1,182,164 TO 210,164 2360 DRAW 1,215,164 TO 216,164:DRAW 1,221,164 TO 241,164 2370 DRAW 1,93,165 TO 176,165:DRAW 1,182,165 TO 210,165 2380 DRAW 1,214,165 TO 216,165:DRAW 1,221,165 TO 241,165 2390 DRAW 1,94,166 TO 177,166:DRAW 1,182,166 TO 209,166 2400 DRAW 1,213,166 TO 216,166:DRAW 1,221,166 2410 DRAW 1,224,166 TO 242,166:DRAW 1,94,167 TO 177,167 2420 DRAW 1,182,167 TO 209,167:DRAW 1,213,167 TO 215,167 2430 DRAW 1,220,167:DRAW 1,224,167 TO 243,167 2440 DRAW 1,94,168 TO 177,168:DRAW 1,182,168 TO 209,168 2450 DRAW 1,212,168 TO 215,168:DRAW 1,219,168 2460 DRAW 1,224,168 TO 237,168:DRAW 1,239,168 TO 243,168 2470 DRAW 1,95,169 TO 177,169:DRAW 1,182,169 TO 209,169 2480 DRAW 1,211,169 TO 214,169:DRAW 1,218,169 TO 219,169 2490 DRAW 1,223,169 TO 237,169:DRAW 1,240,169 TO 244,169 2500 DRAW 1,96,170 TO 177,170:DRAW 1,182,170 TO 215,170 2510 DRAW 1,217,170 TO 219,170:DRAW 1,222,170 TO 245,170 2520 DRAW 1,96,171 TO 178,171:DRAW 1,182,171 TO 246,171 2530 DRAW 1,97,172 TO 147,172:DRAW 1,149,172 TO 178,172 2540 DRAW 1,182,172 TO 246,172:DRAW 1,97,173 TO 178,173 2550 DRAW 1,182,173 TO 246,173:DRAW 1,98,174 TO 178,174 2560 DRAW 1,182,174 TO 247,174:DRAW 1,98,175 TO 178,175 2570 DRAW 1,182,175 TO 216,175:DRAW 1,218,175 TO 221,175 2580 DRAW 1,224,175 TO 247,175:DRAW 1,99,176 TO 179,176 2590 DRAW 1,182,176 TO 217,176:DRAW 1,219,176 TO 223,176 2600 DRAW 1,226,176 TO 247,176:DRAW 1,99,177 TO 179,177 2610 DRAW 1,183,177 TO 184,177:DRAW 1,195,177 TO 202,177 2620 DRAW 1,204,177 TO 224,177:DRAW 1,226,177 TO 247,177 2630 DRAW 1,99,178 TO 179,178:DRAW 1,195,178 TO 201,178 2640 DRAW 1,205,178 TO 248,178:DRAW 1,100,179 TO 179,179 2650 DRAW 1,195,179 TO 203,179:DRAW 1,207,179 TO 248,179 2660 DRAW 1,100,180 TO 176,180:DRAW 1,194,180 TO 204,180 2670 DRAW 1,208,180 TO 220,180:DRAW 1,222,180 TO 249,180 2680 DRAW 1,101,181 TO 175,181:DRAW 1,180,181 TO 182,181 2690 DRAW 1,195,181 TO 207,181:DRAW 1,210,181 TO 249,181 2700 DRAW 1,101,182 TO 176,182:DRAW 1,178,182 TO 189,182 2710 DRAW 1,196,182 TO 209,182:DRAW 1,211,182 TO 249,182 2720 DRAW 1,102,183 TO 171,183:DRAW 1,175,183 TO 192,183 2730 DRAW 1,196,183 TO 211,183:DRAW 1,213,183 TO 250,183 2740 DRAW 1,102,184 TO 171,184:DRAW 1,176,184 TO 193,184 2750 DRAW 1,197,184 TO 203,184:DRAW 1,205,184 TO 212,184 2760 DRAW 1,214,184 TO 250,184:DRAW 1,102,185 TO 152,185 2770 DRAW 1,154,185 TO 171,185:DRAW 1,176,185 TO 195,185 2780 DRAW 1,198,185 TO 204,185:DRAW 1,206,185 TO 214,185 2790 DRAW 1,216,185 TO 249,185:DRAW 1,102,186 TO 166,186 2800 DRAW 1,169,186 TO 171,186:DRAW 1,177,186 TO 197,186 2810 DRAW 1,199,186 TO 204,186:DRAW 1,207,186 TO 215,186 2820 DRAW 1,219,186 TO 235,186:DRAW 1,238,186 TO 249,186 2830 DRAW 1,102,187 TO 151,187:DRAW 1,156,187 TO 164,187 2840 DRAW 1,169,187 TO 171,187:DRAW 1,177,187 TO 198,187 2850 DRAW 1,201,187 TO 205,187:DRAW 1,208,187 TO 217,187 2860 DRAW 1,221,187 TO 236,187:DRAW 1,240,187 TO 249,187 2870 DRAW 1,102,188 TO 148,188:DRAW 1,157,188 TO 159,188 2880 DRAW 1,167,188 TO 172,188:DRAW 1,174,188 TO 200,188 2890 DRAW 1,203,188 TO 206,188:DRAW 1,209,188 TO 219,188 2900 DRAW 1,222,188 TO 238,188:DRAW 1,241,188 TO 249,188 2910 DRAW 1,103,189 TO 149,189:DRAW 1,151,189 TO 155,189 2920 DRAW 1,165,189 TO 166,189:DRAW 1,170,189 TO 172,189 2930 DRAW 1,174,189 TO 201,189:DRAW 1,205,189 TO 206,189 2940 DRAW 1,210,189 TO 222,189:DRAW 1,224,189 TO 239,189 2950 DRAW 1,242,189 TO 249,189:DRAW 1,104,190 TO 155,190 2960 DRAW 1,170,190 TO 173,190:DRAW 1,180,190 TO 206,190 2970 DRAW 1,211,190 TO 249,190:DRAW 1,104,191 TO 155,191 2980 DRAW 1,170,191 TO 173,191:DRAW 1,181,191 TO 190,191 2990 DRAW 1,193,191 TO 207,191:DRAW 1,211,191 TO 249,191 3000 DRAW 1,104,192 TO 158,192:DRAW 1,172,192 TO 173,192 3010 DRAW 1,182,192 TO 184,192:DRAW 1,186,192 TO 191,192 3020 DRAW 1,194,192 TO 208,192:DRAW 1,212,192 TO 249,192 3030 DRAW 1,104,193 TO 159,193:DRAW 1,173,193 TO 174,193 3040 DRAW 1,181,193 TO 184,193:DRAW 1,187,193 TO 191,193 3050 DRAW 1,196,193 TO 209,193:DRAW 1,213,193 TO 248,193 3060 DRAW 1,104,194 TO 160,194:DRAW 1,173,194 3070 DRAW 1,181,194 TO 185,194:DRAW 1,189,194 TO 193,194 3080 DRAW 1,197,194 TO 210,194:DRAW 1,214,194 TO 248,194 3090 DRAW 1,104,195 TO 162,195:DRAW 1,183,195 TO 186,195 3100 DRAW 1,190,195 TO 195,195:DRAW 1,199,195 TO 212,195 3110 DRAW 1,215,195 TO 248,195:DRAW 1,104,196 TO 163,196 3120 DRAW 1,183,196 TO 187,196:DRAW 1,193,196 TO 196,196 3130 DRAW 1,200,196 TO 213,196:DRAW 1,216,196 TO 248,196 3140 DRAW 1,105,197 TO 165,197:DRAW 1,181,197 TO 188,197 3150 DRAW 1,195,197 TO 197,197:DRAW 1,202,197 TO 214,197 3160 DRAW 1,218,197 TO 248,197:DRAW 1,105,198 TO 169,198 3170 DRAW 1,173,198:DRAW 1,182,198 TO 189,198 3180 DRAW 1,197,198 TO 200,198:DRAW 1,203,198 TO 216,198 3190 DRAW 1,219,198 TO 236,198:DRAW 1,238,198 TO 248,198 3200 DRAW 1,105,199 TO 174,199:DRAW 1,182,199 TO 190,199 3210 DRAW 1,198,199 TO 201,199:DRAW 1,205,199 TO 217,199 3220 DRAW 1,222,199 TO 237,199:DRAW 1,240,199 TO 247,199
Resultatet visas på bilden ovan.
-

En tre månader lång spellista
Jag har dokumenterat vad radiostationen Rockklassiker har spelat för låtar under första kvartalet 2012. Vi pratar alltså om en tre månader lång spellista bestående av 26510 poster. Med denna information kan den som är intresserad ställa frågor och göra statistiska analyser.
Hur stor andel av låtarna är Europe-låtar? Hur många olika låtar med Queen väljer de bland? Vilken låt spelas mest? Vilka låtar spelas bara en gång? Hur förändras valet av låtar över veckor?
Mycket nöje!
Du kan ladda hem spellistan i Microsoft SQL Server-format här.
-

Ozma Wars review
Ozma Wars is one of those infamous time thieves from my childhood. Ozma Wars is a classical shoot’em up game like Space Invaders but with two major differences. In Ozma Wars, you don’t have lifes, you have energy. You off start by docking something that looks like a boat in space, and that gives you the energy you need until next time it shows up. The second difference is that different enemies have different movement patterns, and one aspect of the game is to know what enemies are moving in what pattern. Also, some of them have target seeking missiles.
You might want to avoid the soundtrack, that basically consists of one loud annoying sound, but as usual, the sound effects contribute to the game.As in Space Invaders, enemy movement speed is very dependent on how busy the main processor is, so you may be surprised by a sudden increase of speed from one enemy when you’ve just killed another. Some videos can be found here, here and here.
The sound is annoying, but the most annoying thing is that collision detection fails from time to time and enemies randomly doesn’t get drawn. I like the game, and these glitches adds to the excitement.
-

Up’n Down (in-game)
A cover version of the C64 version of the Up’n Down soundtrack. Originally written by Tony Vece.
-

Car polo
Car Polo is an excellent bar game. In one player mode, you control the red car and the other three are controlled by the computer. The object is to push the yellow ball in to the red goal. The purple car is on your team whereas blue and cyan cars are in the opposing team.In two player mode, each player controls one car and the other two cars are computer controlled. The arcade version allowed up to four players, two in each team. This is the hardware from 1977 (image stolen from www.arcade-history.com):

The controls are lovely and this game goes well with cheap Miller beer, cigarettes and good friends. I have the ROM image from the machine, but if anyone still have the original hardware: Yes, I’d like to come to dinner!
-

Making music in Basic 7.0 part 5
You can add pitch bending using the SOUND command. By itself, you cannot use envelopes, just flat sounds in any given pitch. The arguments are voice (1, 2 or 3), frequency (0 to 65535), duration (16 = one second), pitch bend direction (0 = up, 1 = down, 2 sine up and down), minimum frequency, pitch bend speed, waveform (0 = triangle, 1 = saw tooth, 2 = square, 3 = noise) and finally pulse width (if waveform is 2).This will make a straight beep, that will play for two seconds:
SOUND 1, 4000, 32
And now for something completely different, a hysterical vibrato!
SOUND 1, 5000, 32, 2, 3000, 800, 1
To add an envelope to the sound, you use what you know on the PLAY command, and add the SOUND command immediatly before. Make sure you trigger them on the same voice.
Both the SOUND command and the PLAY command (in combination with the ENVELOPE command and the T synthesize control character) allows you to control the waveform that is being used. When combining them, PLAY decides, not SOUND. Type in this in your Commodore 128. You might want to reset your machine first, to set all parameters to default.
10 SOUND 1, 5000, 32, 2, 3000, 800, 1 20 PLAY "V1T5C"
Cool, right? Click here to listen.
-

Making music in Basic 7.0 part 4
Apart from PLAY, the commands that are available for making sounds and music are TEMPO, ENVELOPE, SOUND and FILTER.TEMPO lets you control playback speed. The slowest is 1 and the fastest is 255.
ENVELOPE lets you modify the ten predefined instruments. You set the instruments using the T control character (0 to 9). The arguments are:
– The instrument you want to overwrite (0 to 9)
– Attack rate (0 to 15)
– Decay rate (0 to 15)
– Sustain level (0 to 15)
– Release rate (0 to 15)
– Waveform (0=triangle, 1=sawtooth, 2=square with adjustable pulse width, 3=noise, 4=ring modulation)
– Pulse width (0 to 4095) – only relevant if waveform is set to 2.This program creates 5 similar instruments that differ in pulse width, and uses them in a simple riff.
10 ENVELOPE 0,0,5,0,0,2,100 20 ENVELOPE 1,0,5,0,0,2,300 30 ENVELOPE 2,0,5,0,0,2,500 40 ENVELOPE 3,0,5,0,0,2,700 50 ENVELOPE 4,0,5,0,0,2,900 60 TEMPO 40 70 PLAY "V1O2Q" 80 FOR I=1 TO 2 90 PLAY "T0CCT1CCT2CCT3CCT4CCT3CCT2CCT1CC" 100 NEXT
Click here to listen.
-

Making music in Basic 7.0 part 3
When you use the other synthesizer control characters (O, T, U and X), they apply no matter of what voice (V) you have chosen. So when you for example use O to set the octave (0 to 6), all the following notes, regardless of voice, will be played in that octave. This example will play the notes C, D and E in voice 1, octave one. C, D E in voice 1, octave 2, and finally C (at the same time as the previous E), D and E in voice 2, octave 2.PLAY "V1O1 CDE O2 CDE V2 CDE"
T (0 to 9) lets you chose from 10 predefined envelopes. The predefined envelopes emulates different instruments (0 is piano, 1 is accordion and so on). Envelopes differ in attack rate, decay rate, sustain level, release rate and waveform. This song uses a harpsichord bass (T6), a drum (T3) and some xylophone (T9).
10 FOR I=1 TO 4 20 PLAY "V1O2T6QCCT3O5CO2T6C" 30 PLAY "V2O5T9CV3G" 40 NEXT
U (0 to 15) controls the volume, but not on the next note, but also on any playing note. This will therefore play both C notes using volume 2.
PLAY "U15 C U2 C"
Finally, X (0 or 1) is used to turn the frequency filter on (1) or off (0).
-

Making music in Basic 7.0 part 2
The synthesizer control characters (V, O, T, U and X) always take one integer argument and always affect all the rest of the notes that are played. V stands for Voice and is the key to polyphonic music. Since polyphonic music is achieved by playing notes in different voices, you will use V a lot.Each note will be played when the previous note is done, but if you switch voices, the next note will be played immediately (if the voice you switch to is free). This will play the C note, followed by E and G at the same time. There are three voices available: 1, 2 and 3.
PLAY "V1 CE V2 G"
This program gives you a nice riff:
10 FOR A=1 TO 4 20 PLAY "V1 CE CV2EV3G" 30 PLAY "V1 CGCC V2EV3G" 40 PLAY "V1CV2EV3G" 50 NEXT
-

Making music in Basic 7.0 part 1
In Commodore Basic 7, music is made using the PLAY command. PLAY takes one string, and that string contains the notations that you want the Commodore 128 to play. The string “CDE” will play the note C, and then the note D and finally then note E.
PLAY "CDE"
Possible notes are C, D, E, F, G, A and B. R is for Rest. Rests take up time, but does not make any sound. Spaces are ignored, so you can add spaces to make your string more readable. When you add a note control character to your note, this might be of interest. There are three note control characters that you can use. Control characters operates only on the note immediately to the right, spaces ignored.
Sharp (#) will play the note a half tone higher, flat ($) will play the note a half tone lower and period (.) will increase note duration by 50%. Since note control chars only apply to the next note, this will play 4 C notes, but only the third note will be longer.
PLAY "CC.CC"
The synthesizer control characters and the duration control characters do not just apply to the next note to the right, but to all preceding notes. All synthesizer control characters take numeric arguments, but none of the duration control characters take any arguments. I will get back to the synthesizer control characters, but these are the duration control characters:
W for whole note, H for half note, Q for quarter note (default), I for eight note and S for sixteenth note. This will play two bars. The first bar will consist of two quarter notes and one half note. The next bar will consist of one half note and two quarter notes.
PLAY "QCCHCCQCC"
With this much knowledge, you can do Smoke on the water by Deep Purple. Something like this:
PLAY "QC#D.FC#DI#FHF"
-

Reading sequential data from your 5.25 inch floppy
Continued from here.
Once you have some sequential data in a file on your disk, you can write a program to read it back. How this is done, varies between different Commodore machines, and can be quite tricky. On the C128, it is as easy as writing the data. You have to remember the structure of the data you were writing – in my case one string, one integer and one string.
This is a new program (clear any existing program by typing NEW), and it is assumed that you have your floppy with the data you created in the earlier post.
Use OPEN to open a file, but this time, specify that you want to READ the sequential file TEST.DAT.
10 OPEN 1, 8, 2, "TEST.DAT,SEQ,READ"
Then, use INPUT# to read each stored record. Just remember the data types. PRINT# supports writing multiple records in one call, and INPUT# supports multiple reads. So instead of writing three lines, I can read three records in one line, like so:
20 INPUT#1, A$, B, C$
Use CLOSE to close the file.
30 CLOSE 1
These line will display the file content on screen:
40 PRINT A$ 50 PRINT B 60 PRINT C$
And if everything is correct, you will now se this:
ONE STRING 5 ANOTHER STRING
(The commands I use are available Commodore Basic 4.0 on Commodore PET, but I run Commodore Basic 7 on a C128.)
-

Sequential data on 5.25 inch floppies
If you have an actual 1571 disk drive for your Commodore 128, insert a blank disk, format it using the HEADER command. Something like this:
HEADER "MY DISK", I44, D0
(Formatting a disk takes a while.)
If you are running a virtual Commodore 128 in VICE, click File, Attach disk image, Drive 8. Create a d64 image file and attach that image. To create the file, enter a desired filename, like test.d64, provide a name, click Create Image, then click Attach.
(The commands I use are available Commodore Basic 4.0 on Commodore PET, but I run Commodore Basic 7 on a C128.)
Your disk is now inserted and completely empty. You can check the content using the DIRECTORY command.

As a Commodore user, you know that you sometimes have to refer to your disk drive using its drive number (the first disk drive is 0) and sometimes you have to use the device number (the first disk drive is 8). The OPEN command operates on any device, therefore a device number is required in this case. The first parameter is the logical file number (just a number that identifies the file), the second is the device number (8). The third argument is a channel number – enter 2. Then, in one single string argument, you type in the file name, the file type and the file mode. I want to create a file called TEST.DAT as a sequential file and I want to write to it, so I my string holds “TEST.DAT,SEQ,WRITE”.
10 OPEN 1, 8, 2, "TEST.DAT,SEQ,WRITE"
To fill your file with data, use the PRINT# command. Anything goes here. This will print one string, one integer, and then yet another string. You provide your logical file number so that PRINT# knows what file you are targeting.
20 PRINT#1, "ONE STRING" 30 PRINT#1, 5 40 PRINT#1, "ANOTHER STRING"
If you like, more data can be added in one line.
When you are done writing, close the file using the CLOSE command. Again, provide your logical file number.50 CLOSE 1
After running this program, you should have a small sequential file called TEST.DAT on your disk. If any disk error occurred, the lamp on your drive is flashing now – it shouldn’t do that.
Continued here.
-

Vic 20 software
The Vic 20 is not dead yet. I just found this lovely site packed with Vic 20 games and tools. To run a game in the Vice emulator, just download the prg file (download link might be hard to find for some of the programs) and autostart it from the File menu in Vice. Happy hacking in 176 x 184 pixels!
Vic 20 photo by Sven Petersen.
-

Plotting graphics
The Commodore 128 has a nice API for setting graphics mode and plotting graphics, that can be used in 40 column mode. The GRAPHIC command takes a mode (0 to 5) and a “clear screen flag”, and changes the current graphics mode. 0 is the 40 column text mode and 1 is the high resolution monochrome graphics mode. This program sets a few random pixels on the screen using the DRAW command:
10 GRAPHIC 1, 1 20 FOR A = 1 TO 100 30 DRAW 1, RND(1) * 320, RND(1) * 200 40 NEXT A
When the program is run, the text is hidden, so to retain the text cursor, just type GRAPHIC 0 and hit Enter. If you like, you can add this to your program.
The Commodore 64 does not provide any API for graphics, so on the C64 this task is accomplished by manipulating bits in a memory area. You can jump to graphics mode by setting the bit 6 on byte 53265 to 1 and return to text mode by setting it to 0. While plotting, you must make sure you know how to handle bit patterns. The screen area can be located at 8192 if we set a flag for this (bit 4 at byte 53272), like so:
10 POKE 53272, PEEK(53272) OR 8
The screen consist of 8000 bytes, so in this case from 8192 to 9191. Then, enter graphics mode:
20 POKE 53265, PEEK(53265) OR 32
Now we don’t have the service to get a clean color map (that is Commodore 128 luxury), so random boxes (8×8 pixels) will have strange colors. No worries, this is expected.
Finally, these lines of code will draw a few horizontal lines in the upper left 8×8 pixel area:

30 POKE 8192, 255 40 POKE 8193, 0 50 POKE 8194, 255 60 POKE 8195, 0 70 POKE 8196, 255 80 POKE 8197, 0 90 POKE 8198, 255 100 POKE 8199, 0

When the program has run, you will not see the text cursor, but to restore everything, type:
POKE 53272, 21 POKE 53265, 27
…and our horizontal lines will be gone and the text cursor is back.

-

A physical C65 in action
There are some preserved footage of actual Commodore 65 machines out there. This first clip demonstrates some graphics capabilities. Note that you don’t have to specify the unit number when loading from disk.
This clip shows how to use the Commodore 65 in C64 “fast mode”.
-
Tool for interplanetary space travel
If you are planning on doing some interplanetary space travel, this little calculator is what you need. It will tell you how much time you need to set aside for your trip, and how much time you’ll gain by using a faster ship. Only available in Swedish (because NASA aren’t planning any such trips in the near future, so I put my faith in ESA).

Download the tool from here (requires Windows XP SP3 or later).
-
CP/M on a Commodore machine – online resources
To get started with CP/M, you will need a Commodore 128 with a disk drive or a computer that runs Vice (X128). The disks you need can be downloaded from here. The CP/M boot disk, the additional utilities, “more CP/M additional utilities”, the Assembler utilities and Microsoft Basic 80 (two disks).
If you run this on a physical machine, make sure to insert the boot disk, and to push in the “40/80 display” key on your computer, before turning it on. If you are running this from Vice emulator, start your machine by passing these arguments to the x128 executable (adjust the path if necessary):
x128.exe -80 -autostart "C:\cpm\zpmsys.d64"
This is a text only environment, but pseudo graphics can be used, and a graphics library is available as an add-on.
The basic usage of CP/M is described in the Commodore 128 user guide, chapter 11. If you know DOS, you will probably feel rather at home. You have the concepts of programs and arguments. DIR shows the available commands. The actual Commodore extensions consist of keyboard short cuts and are described in chapter 15 of the Commodore 128 user guide.
What I see as the biggest challenge, is inserting the correct disk. Let’s say that you want to read the content of a file. This requires the TYPE.COM file that is located on the additional utilities disk, so you must insert that disk to be able to run that command. To avoid frustration, use two disk drives – one for the CP/M disks, and one for your files.
To start Microsoft Basic, insert the correct disk and type MBASIC. Then, watch a movie or something. After a while, your Commodore 128 will say:
MBASIC-80 Rev. 5.21 [CP/M Version] Copyright 1977-1981 (C) by Microsoft Created: 28-Jul-81 34350 Bytes free Ok
If you want to write programs, the MBASIC manual can be downloaded from here.
A five minute Turbo Pascal 3.0 demo on the Commodore 128:
-
Simon’s Basic
I happened to find this website with some great downloads for the Commodore 64. Some compilers and some interpretators, like Simon’s Basic. Simon’s Basic extended the extremely frugal Commodore Basic 2.0 that was built in the C64. It sort of turned the C64 into a Commodore 128 by providing new sets of instructions for sound, graphics and input. The complete manual can be downloaded as a PDF from here.
The band Barcelona named an album Simon Basic as a tribute to this programming language.
-
Let’s make the screen flash!
This program will make the screen flash on the Commodore 128, and it will also run on the Commodore 64. The background color of the screen is stored at D021 (53281), so this effect is accomplished by manipulating the value at that address, multiple times. This program cannot be written in Basic, because the Basic interpreter is too slow.
Remember that the machine code monitor expects code in one format, and displays it in another, so what I show here, is what I actually type in. I will write my program at location 1000 (4096) in the memory. Type MONITOR to enter the machine code monitor, and type F 1000 1100 0 to create some free space.
To begin writing code, type . directly followed by the address you want to add an instruction to, followed by the instruction and the desired parameters. This stores what you just typed in, and expects you to type in the next command, or just hit Enter to exit the edit mode.
.1000 LDA #$01 STA $D021 NOP NOP NOP LDA #$0B STA $D021 NOP NOP NOP
(and so on…)
Let the final command in your program be JMP $1000.
Press Enter to exit edit mode, type X and Enter to exit the monitor. Start your program by typing SYS 4096. Your screen should now be flashing hysterically!
On the first row, .1000 tells the Commodore 128 machine code monitor that I want my program to start at address 1000 (4096). LDA loads a value to the accumulator, and STA stores current value in the accumulator to the given memory address, D021 (53281). The specific memory address D021 controls the background color. NOP means “no operation” and is used only to make the effect less hysterical. Finally, JMP jumps to the given address, creating an infinite loop. Who needs fireworks now?
-
Positioning sprites on the Commodore 64
The task of positioning sprites on the C64 holds one particular oddity that I want to show. To be able to position a sprite on screen, you must master binary logic on the C64, and binary logic works in the same way as on the Commodore PET, shown here. Also, you need a visible sprite. The following code does the trick. If you don’t own a Commodore 64 and don’t have an emulator, the code also works in JaC64, an on-line C64 emulator implemented as an Java Applet. However, I can’t get the cursor keys to work in JaC64, so don’t mistype anything! 😉
10 FOR I=0 TO 62 20 POKE 704+I, 255 30 NEXT I 40 POKE 2040, 11 50 POKE 53287, 1 60 POKE 53248, 200 70 POKE 53249, 200 80 POKE 53269, 1
The Y position of the sprite is stored at D001 (53249). You have 256 possible Y positions, but the visible area of the screen is only 200 pixels high. All you need to make the sprite cycle over the screen is some iteration that copies the values 0 to 255 to the D001 address.
The X position however, is a bit more tricky. The X coordinate is stored at D000 (53248). But we need more than 256 possible positions to be able to place the sprite on the right side on the screen. Commodore did not waste a whole byte on solving this problem. At D010 (53264), the first bit keeps track on if D000 holds a value that represent the left part of the screen, or the right part of the screen for the first sprite (sprite 0). We have eight sprites and eight available bits at D010, so the second bit keeps track on if D002 (53250) holds a value that represent the left part of the screen, or the right part of the screen for the second sprite (sprite 1), and so on. So this is what we must do to make the sprite we displayed in the above program run over the screen:Iterate from 0 to 255, set the value to D000 (line 10-30). Set the first bit at D010 to 1 (line 40). Iterate from 0 to 255, set the value to D000 (line 50-70). Restore the first bit at D010 to 0 (line 80). Repeat from the beginning (line 90).
Type NEW to delete your current program.
10 FOR I=0 TO 255 20 POKE 53248, I 30 NEXT 40 POKE 53264, PEEK(53264) OR 1 50 FOR I=0 TO 255 60 POKE 53248, I 70 NEXT 80 POKE 53264, PEEK(53264) AND 254 90 GOTO 10
If you ran the first program, and typed in this program correctly, you should see a sprite that flies from the left to the right across your screen.
-
Sprites on the Commodore 64
Things gets a bit tougher on the Commodore 64, because this excellent piece of hardware did not come with Basic equipped with sprite commands. Nor has it a sprite editor or a machine code monitor. However, if we have access to a Commodore 128, sprites can be edited when in C128 mode, and then used in C64 mode. If we want, we can also use the machine code monitor in C128 mode and then execute the program in C64 mode. I am going to display a sprite without using the C128 mode.
The bit pattern at D015 gets and sets what sprites are enabled, just as it does on the Commodore 128, but on the Commodore 128 we also have Basic commands for this. This means that the first sprite (sprite 0) is activated using:
POKE 53269, 1
Still, you might not see anything on the screen. You can position the sprite (sprite 0) by writing the desired X coordinate in D000 and the desired Y coordinate in D001. This will position it at 100, 100:
POKE 53248, 100 POKE 53249, 100
The 0, 0 position is just above and to the left of the visible area, so if it is located at its home position, the sprite is still invisible. Also, the sprite might be empty. Run this program to make the sprite (still sprite 0) totally filled with pixels and displayed in red color. Note that the first line of code (10) tells the Commodore 64 that we want to use 02C0 to 02D7 (704 to 727) for sprite 0 data.
10 POKE 2040, 11 20 FOR I=0 TO 62 30 POKE 704+I, 255 40 NEXT I 50 POKE 53287, 2
Your screen should now look something like this:

When taking this further, it is nice to have a Commodore 64 memory map available.
-
Collision detection
A nice and quick way to create two filled sprites (sprite 1 and 2) is to enter the monitor and type:F 0E00 0E3E FF F 0E3F 0E7E FF
Of course you can fill both at once, but this the above code nicely declares the two memory areas I am using in this example. Now, let’s write a simple Basic program to fire the two sprites so that they collide now and then. This will make one sprite white and the other cyan, and fire the movements.
10 SPRITE 1, 1, 2, 0 20 MOVSPR 1, 100, 100 30 MOVSPR 1, 90#1 40 SPRITE 2, 1, 2, 0 50 MOVSPR 2, 100, 115 60 MOVSPR 2, 270#1
To detect collision between the two sprites, we can use the BUMP function. BUMP(1) returns a bit pattern telling us what sprites has collided, and BUMP(2) returns a bit pattern that tells us what sprites has collided with static graphics on screen. We would expect BUMP(1) to return 3 if sprite 1 and 2 is colliding, given that no other sprites are colliding as well, because the binary number 00000011 represents the decimal number 3. And indeed. Add these two lines to your program to see what BUMP(1) returns:
70 PRINT BUMP(1) 80 GOTO 70
To interrupt the program, press RunStop. If you are using the VICE emulator, that key might be mapped to the Escape key. BUMP(1) is actually just returning the bit pattern in the byte located at D01E, so BUMP(1) is equivalent to PEEK(53278).
-
Poking graphics on the C128
The skills of using PEEK, POKE and logical operators that I write about for the Commodore PET here, can be used to create graphics on the Commodore 128, in 40-column mode. Before you begin, you might want to clear the screen using the SCNCLR command. Odd name, I know.
The C128 has a built in sprite engine. A sprite is a 2 dimensional area with its own memory area that can be handled separately from the rest of the screen. The C128 sprite engine supports eight sprites. Use the SPRITE command to activate a sprite. Here, I have activated the first of eight sprites:
SPRITE 1, 1, 1, 0
The first sprite is now activated. The default position is up to the right of the screen. However, the sprite might be invisible. If there is junk data in the address space of the sprite, you will see some obscure pixels. The sprite data is located in the memory at 3584 (0E00). Each sprite is 3 bytes (or 24 pixels) wide and 21 pixels high. Each sprite consumes 63 bytes. This information is enough to clear the sprite. In the machine code monitor, use In the machine code monitor, use M 0E00 0E3E to see the sprite data. Note that the monitor displays eight bytes at a time, so it will actually display 0E00 to 0E3F. To clear the sprite, type:
F 0E00 0E3E 0
Leave the monitor using X. Make sure the sprite is visible by typing in SPRITE 1, 1, 1, 0 again. Now, use the POKE statement to control which pixels should be visible and which should be hidden, according to the rules I demonstrated here. -
Accessing individual bits on a Commodore PET
On a Commodore PET, each byte that can be read using the PEEK function, and set using the POKE statement. A byte consist of 8 bits, and represent a number between 0 and 255. This code writes the value 5 to the memory address 1020, and then reads it back. The output is of course 5.POKE 1024, 5 PRINT PEEK(1024)
The POKE statement affects all eight bits at the given address (1024), but bits can be filtered out using logical operators AND and OR. The first (from right to left) of the eight bits represents the value 1, the second bit represents 2, the third 4, the fourth 8, the fifth 16, the sixth 32, the seventh 64 and the last bit represents the value 128.
Since the value 5 is stored at 1024, you would expect all the bits being 0 except the first and the third, since 1 + 4 equals 5. This code reads the first four bits at 1024, and the output is 1, 0, 4 and 0. 1 because the first bit (representing 1) is set, 0 because the second isn’t set, 4 because the third (representing 4) is set and 0 because the fourth isn’t set.
PRINT PEEK(1024) AND 1 : REM Read bit 1 - (1 if set) PRINT PEEK(1024) AND 2 : REM Read bit 2 - (2 if set) PRINT PEEK(1024) AND 4 : REM Read bit 3 - (4 if set) PRINT PEEK(1024) AND 8 : REM Read bit 4 - (8 if set)
Multiple bits can also be read. This code reads both the first and the third bit on the address 1024:
PRINT PEEK(1024) AND 5
The result will be 0 if neither is set, 1 if the first is set, 4 if the second is set and 5 if both the first and third is set. The bit pattern of the value is 00000101, so the bits that are pointed out are the first and the third (from right to left).
Also, you can set individual bits. OR [n] turns a bit on, where [n] is the value that the bit represents. 1, 2, 4, 8, 16, 32, 64 or 128. This code turns on the last bit at 1024:
POKE 1024, PEEK(1024) OR 128
The bit pattern at 1024 is now 10000101. The value that is stored at 1024 is 133, because 1 + 4 + 128 equals 133. To turn the last bit (128) back to zero, use AND together with bit pattern that contains a one at all positions that you want the existing flag to remain, and 0 at the positions you want to turn bytes off. To turn the last bit from the right off, you would want a bit pattern that looks like this: 01111111. All bytes remains, but the last bit from the right is 0. The number 127 has this pattern.POKE 1024, PEEK(1024) OR 127
Now, the bit pattern at 1024 is changed back from 10000101 to 00000101. The value that is stored in the byte at 1024 is now 5 again.
What can be done with this knowledge?
-
Visit ACNE, view source
Visit http://www.acnestudios.com/ and view the source of their web page. There you have a small challenge for a web developer.

Thanks for the tip, Staffan!
-
Destroying pictures using the command line
PhotoKiller.exe is a simple command line application that loads an image, manipulates it, and saves it under a new name. By manipulating the levels, and taking some other measures, the image will look like an old color photo.
I have a picture called “image.jpg” in a folder where I also have PhotoKiller.exe. This is the original photo:

From the command line, start PhotoKiller.exe and pass the filename of the picture as an argument to PhotoKiller.exe.

After a few seconds, a new png file is created, called “image.jpg.destroyed.png”. This is the result :

Download PhotoKiller.exe from here. And here are some more examples. The original image is on the left.

-
Mandelbrot
The day before yesterday, I did a bit on Bo E. Carlsson’s book on fractals, and then yesterday, one of the masterminds behind fractal geometry, Benoît Mandelbrot, died. Mandelbrot coined the term “fractal” and gave name to the Mandelbrot set, the fractal which he described. A fractal is a self repeating geometric shape. This is what a Mandelbrot set looks like (generated using ChaosPro):

A closer look:

If you are using an older version of Windows, Fractint is the best fractal software.
The C source code for Fractint is available for download from here.
-
Fractales by Bo E. Carlsson
I found my old book on fractales from 1992 by Bo E. Carlsson, in Swedish. The book basically lists a bunch of different fractales, and explains the underlying mathematical formulas.

The book ends with a few Basic code listings.
A quick translation of the Julia set fractal to Visual Basic might look like this. The code is written in a Windows Forms application, so the System.Drawing namespace is imported. I also use type inference:
Using Btmp As New Bitmap(320, 200) Dim S = 3 / 200 Dim T = 3 / 200 Dim P = 0.31 Dim Q = 0.04 For YY = -1.1 To 1.1 Step S For XX = -1.5 To 1.5 Step T Dim X = XX Dim Y = YY Dim K = 0.0 Dim I = ((200 / 3) * XX) + 160 Dim J = ((200 / 3) * YY) + 100 Dim M = 0.0 Do Btmp.SetPixel(I, J, Color.Red) Dim A = ((X * X) - (Y * Y)) + P Dim B = ((2 * X) * Y) + Q X = A Y = B K += 1 M = (X * X) + (Y * Y) If K > 100 Then Exit Do End If If Not M < 4 Then I = ((200 / 3) * XX) + 160 J = ((200 / 3) * YY) + 100 Btmp.SetPixel(I, J, Color.Black) End If Loop While M < 4 Next Next Using G As Graphics = Me.CreateGraphics() G.DrawImage(Btmp, 0, 9) End Using End Using
The above code could be written in the click event of a button. If you think the result is slightly stiff and unromantic, remember that the original code could be written for any strange old machine, like a Commodore 128 or an Apple II.

Thank you, Bo E. Carlsson!
-
Editing code on the Commodore 65
The Commodore 64 and the Commodore 128 uses the same method for editing code. You press enter over a line, and that line is stored the with the index of the entered line number, overwriting any existing code on that with that index. The Commodore 65 has the same machine code monitor as the Commodore 128 (it runs more smoothly because the C65 is much faster than the C128). Also, adding and overwriting Basic code is done in the same way. Editing is probably not, but I am not sure.
On the C128, you just had to make sure you saw the line of code on screen, move the text cursor to it, write something else on top of what is there, and save it by pressing Enter. The C65 does not allow you to fly around with the text cursor over the screen. I loved the fact that you could move the cursor to any position, but it was tricky to collect user input if the user suddenly felt the urge to move away and type something unexpected at an arbitrary location. Perhaps they were to implement some command to do this, or perhaps they planned to allow the cursor to move freely. I don’t know.
I have found some great improvements. Here, I have added 4 lines of code. It displays three lines of text and makes a sound. I use the LIST command to display the whole Commodore Basic 10 program.

Already on the C128 you could use arguments to list parts of the program, and change the line numbers throughout the program using the RENUMBER command. But on the C65, you can find out the line number of certain line of code using the FIND command.

The above image shows the C65 telling me where the word HEJ can be found in my program. Also, I can use the CHANGE command to search and replace text. Let’s say I want to change the notes I want the C65 to play, I can use CHANGE to do this. The C65 asks for each search hit before changing.

Hope to get back to the lovely world of Commodore in the future.























