Programming The RSS feed for Programming.

  • I’m going to ignore Nvidea’s CEO charged statement people shouldn’t learn how to code anymore. I think BBC Basic is an excellent language for someone like myself, AI be damned!

    A scenic mountain landscape serves as the desktop background for a computer screen, with several open folders and text editing programs displayed.
  • A “little” thing as a broken iPad won’t stop me from making art. I made this when the iPad was almost gone.

    simple animated GIF showing a cat and a pirate

    And the other piece I made with a PETSCII editor on my RPi, based on a piece I did earlier this month.

    PETSCII art of Boys Will Be Boys

    Not having a backup for my Raspberry Pi makes me a bit nervous, as it should
    πŸŽ¨πŸ±πŸ‘¨β€πŸ’»πŸ•ΉοΈπŸ‘Ύ

  • This was taxing my iPad. Youtube in Safari with adblocker as picture in picture on top of a drawing app. The strokes had to be placed tactically to allow for overall sluggishness. Also, very distractive drawing and watching a video.
    πŸŽ¨πŸ‘¨β€πŸ’»πŸ“Ί

    screenshot of drawing in ibisPaint X with a Youtube video floating above it
  • As Hanna-Barbera cartoons of the eighties have taught us, cats can without most clothes, except the most essential, like a hat or a cane.
    πŸŽ¨πŸ±πŸ‘¨β€πŸ’»πŸ•ΉοΈπŸ‘Ύ

    Commodore 64 multi-color bitmap painting of an antromorphized cat behind a pile of clothes
  • I find it always such a surprise how a pixel art drawing I made subtly (or sometimes radically) changes to conform to the rigors of the C64 multicolor bitmap.

    Other than that, I used some of the edging techniques (sharp, lost and soft edges). So there’s that too. Happy 😊 camper here!
    πŸŽ¨πŸ‘½πŸ‘¨β€πŸ’»πŸ•ΉοΈπŸ‘Ύ

    Commodore 64 multipaint drawing of an anime version of Rick Deccard
  • Searching on Flickr for Creative Commons photos of kittens I found this cute black and white one. I used it as reference for my C64 hi-res bitmap pixel art drawing.

    Sometimes less color is better. Especially if the one depicted is staring into your soul.
    πŸŽ¨πŸ‘¨β€πŸ’»πŸ‘ΎπŸ•ΉοΈπŸ±πŸ˜ˆ

    Commodore 64 hi-res pixel art drawing of a black and white kitten
  • I didn’t get to experiment with edges. Still, I drew something I love, so that’s good.

    Maybe advice from an oil painter doesn’t translate all that well to pixel art. Pixel art has more in common with decorative art (like embroidery) than with traditional art you can hang on a wall.
    πŸŽ¨πŸ±πŸ‘¨β€πŸ’»πŸ•ΉοΈπŸ‘Ύ

    Commodore 64 multipaint illustration of two kittens, one sniffing a flower
  • Public domain now?
    πŸŽ¨πŸ‘¨β€πŸ’»πŸ•ΉοΈπŸ‘Ύ

    Commodore 64 multicolor illustration of a cartoon mouse holding a piece of cheese and a drink animated GIF of drawing process
  • I suppose the lesson to be learned here is:

    Don’t look into the spiral, or you’ll go cuckoo, bananas, Dada

    A quick peek is no problem, though.
    πŸŽ¨πŸ‘¨β€πŸ’»πŸ•ΉοΈπŸ‘Ύ

    Commodore 64 hires bitmap image showing a spiral and a confused artist
  • Another day, another cat drawing. This time our more blocky version of a feline fellow creature. Sketch in ibisPaint X and final drawing in Commodore 64 multicolor bitmap (160 x 200 resolution, 16 colors). If I could, I’d knit him a cozy sweater.
    πŸ±πŸŽ¨πŸ‘¨β€πŸ’»πŸ•ΉοΈπŸ‘Ύ

    illustration of a stylized cat with chunk in blocked letters written underneath Commodore 64 multicolor bitmap image of a chunky cat illustration
  • I think I’m starting to grasp how to draw in C64 multicolor. You get three colors that can be used anywhere, and per 8 by 8 pixels block you get to pick another color out of 16 possible colors. Careful placement of the pixels is key. If you do it right, you can have a very colorful image
    πŸŽ¨πŸ‘¨β€πŸ’»πŸ•ΉοΈπŸ‘Ύ

    cheeky multicolor illustration on the Commodore 64, stating that boys will be boys
  • Another day, another cat drawing for the old Commodore 64
    😻 🎨 πŸ‘¨β€πŸ’» πŸ•ΉοΈ πŸ‘Ύ

    Commodore 64 multicolor drawing of a blue cat on a red background
  • I reworked an older self-portrait that I made last year as a pixel art drawing, and turned it into an image on the Commodore 64. I like that the limited color palette doesn’t seem to limit me as much as it used to. It takes some effort (well, a lot of effort), but I think it was worth the time.
    🎨 πŸ‘¨β€πŸ’» πŸ•ΉοΈ πŸ‘Ύ

    Commodore 64 multicolor selfie
  • Here are some of the steps I took to create a multicolor pixel art drawing of a cat.

    grayscale image of a cat drawn in ibisPaint X

    drawn in ibisPaint X in 4 colors

    colored pixel art of the same cat in Pixaki

    traced and redrawn in Pixaki

    colored pixel art of the cat display in VICE C64

    made into C64 runnable multicolor art with MultiPaint, loaded into VICE C64

    It’s a process, taking many hours to complete. I think I’m improving.

    πŸ‘¨β€πŸ’»πŸŽ¨

  • Making room for two text screens, so I can use them for buffering is great, but running it from C64 Basic is one ugly hack, and slow too. But I’ve done it, which is great, since I learned a lot from it, and that was the whole point here. The code I keep, in case I need (some of) it πŸ‘¨β€πŸ’»

    screenshot of Commodore 64 Basic code in VS Code
  • I fired up my art app and sculpted on a canvas the size of a retro-computer’s text character (8 pixel wide and 8 pixels high). I had to struggle, because the app wanted it to look nicer than it really was.

    I suppose you can already guess what it represents. You can do a lot in 64 bits of data πŸ‘¨β€πŸ’»πŸŽ¨

    8 by 8 sprite of a black cat animated GIF of drawing process of an 8 by 8 sprite of a black cat
  • Okay, I have a Basic loader with M/L code that enables a screen buffer and has a handy relocatable M/L routine at $C000 that copies 1024 bytes. Bits 4 - 7 of $D018 control which part of memory is used to display the screen. Now I have all I need for moving a block of characters in C64 Basic, right? πŸ‘¨β€πŸ’»

  • Make room for a screen buffer in C64 Basic

    In my previous post in which I moved a box across the screen with a Basic program, I wanted to use a screen buffer. The default screen location starts in memory at $0400 (1024 decimal), and we can move the screen in units of 1024 bytes. The next location would be $0800 (2048 decimal), which is where Basic text lives. Luckily we can move the start of Basic up with a poke at location 44, but we also have to move the bytes of the Basic text to the new location, or you’d get a jibberish Basic text. The most obvious location is $0c01 (3097 decimal), and it makes sense to do this outside of Basic, with the raw power of the 6510 CPU.

    The machine language (M/L) program enablebuffer does just that. Here’s the source code listing. It has some Basic code to run the M/L code and relocate the start of Basic text. The M/L code is a bit more complicated than it needed to be, but I like some headroom in case I want to include more Basic text in front of the M/L code or put some M/L code in a convenient location, so we can sys or usr() to it. The code should be able to copy Basic text in front of the M/L code, no matter how big it would grow.

    
    ; enablebuffer.asm
    ;
    ; Move the start of basic from $0801 to $0c01
    ;
    ; Now both 1024 - 2023 and 2048 - 3047
    ;      can be used as screen memory.
    ; This makes it possible to use a screen buffer
    ;      in Basic.
     
                    PROCESSOR 6502
    
                    ORG $0801
                
    ; Basic text in front of ML code
    ; 10 SYSXXXX:POKE44,12:CLR
    
    BASIC1:
        HEX 14 08 0a 00 9e 
    
        .dc sys_address             ; replaces the "XXXX"
    
    BASIC2:
        HEX 3a 97 34 34 2c 31 32 3a 9c 00 00 00
    
    sys_address:    eqm (start_ML)d
    
    ; start of ML code
    
    start_ML:
    
    vect1:          eqm $02
    vect2:          eqm $04
    BASstart:       eqm $2B
    
                    LDA BASstart+1
                    CMP #$08        ; is start of basic at $0801 ?
                    BNE exit        ; no, then exit
    
    ; set up copy process
    ; copy $0801 to $0C01 until the end of file
    ; copy start at the end towards the beginning
    
    
                    CLC
                    LDA #exit
                    STA vect1+1
                    ADC #$04        ; move 1024 positions higher in memory
                    STA vect2+1
                    LDY #$00
    
    loop1:          LDA vect1+1     ; copy in blocks of 256 bytes
                    CMP #$08        ; less than 256 bytes to copy?
                    BEQ loop2       ; yes, then loop2 instead
    loop1a:         LDA (vect1),Y   ; fast copy 256 bytes
                    STA (vect2),Y
                    DEY
                    BNE loop1a
                    DEC vect1       ; next 256 byte
                    DEC vect2
                    BNE loop1
                    DEC vect1+1
                    DEC vect2+1
                    BNE loop1
    
    loop2:          LDA (vect1),Y   ; copy remainder of bytes
                    STA (vect2),Y   ; between 1 and 255
                    DEC vect1
                    DEC vect2
                    BNE loop2b
                    DEC vect1+1
                    DEC vect2+1
    loop2b:         LDA vect1+1
                    CMP #$07
                    BNE loop2
    
    exit:           RTS
    

    We can load the program as an ordinary Basic program and then run it.

    After that we can new the Basic program and start writing a new Basic program, at location $0C01 instead of the default $0801! Of course, the M/L code will be overwritten by that new Basic program, but that’s okay, since we no longer need it at that point.

  • With all the blogging I do daily, I wanted to automate correct capitalization. I reworked an shortcut that no longer worked to a working state. Select text, share, pick one, paste.

    • all lower case
    • UPPER CASE
    • Title Case in Case You Want It
    • Capitalize A Okay
    • Sentence. After each. Sentence.
  • Moving a box across the text screen in C64 Basic

    I was wondering how to move a collection of characters (e.g. a box) across a Commodore 64 text screen. It’s rather easy to do this destructively. In Basic, I wrote something that horizontally moves a 3-by-3 character rectangle constructed out of PETSCII characters.

    
    10 rem ***
    11 rem *** setup
    12 rem ***
    20 restore:read w,h:for i=0 to w*h-1
    30 read a(i):next i
    40 data 3,3
    50 data 112,64,110,93,32,93,109,64,125
    60 te=200
    100 rem ***
    101 rem *** main loop
    102 rem ***
    110 os=0
    120 for p=1024+12*40top+40-w
    130 gosub 200:gosub 300:next p
    140 os=w-1
    150 for p=1024+13*40-w to p-39+w step-1
    160 gosub 200:gosub 300:next p
    170 goto 100
    199 end
    200 rem ***
    201 rem *** draw a box
    202 rem ***
    210 for x=0 to w-1:for y=0 to h-1
    220 poke p+y*40+x,a(y*w+x)
    230 nexty:nextx:fort=0tote:nextt:return
    300 rem ***
    301 rem *** clear column
    302 rem ***
    310 for y=0toh-1:poke p+y*40+os,32:next
    320 return
    

    The program has to do some clean-up after it has drawn a box with the subroutine draw a box. It fills the box’s trailing text column with space characters (screen code 32). For instance, if the box moves to the right and the box has been drawn in its current position, the left-most text column of that box has to be “cleared” (filled with spaces). Otherwise it will leave behind box characters when the next position of the box is drawnβ€”one position to the right. The main loop uses the variable os (offset) to determine which text column should be filled with spaces, using the same subroutine clear column when moving the text box to the left or to the right.

    It’s all very limited in what this program can do. It can move the box either one character position to the right or the same to the left, nothing more.

    For a more sophisticated draw a box subroutine, it has to know where it was before:

    • restore the original content of the previous position (if any)
    • read the current content where the box will appear and store it for later
    • draw the box onto its position on the text screen

    We can do this in Basic as well, even though it’s rather slow and has clear visual artifacts. Here’s the code for the same 3 by 3 text box, now jumping to arbitrary positions on the screen, while keeping the screen intact.

    
    10 rem ***
    11 rem *** setup
    12 rem ***
    20 restore:read w,h:for i=0 to w*h-1
    30 read a(i):next i
    40 data 3,3
    50 data 112,64,110,93,32,93,109,64,125
    60 te=200
    70 first = (1 = 1)
    100 rem ***
    101 rem *** main loop
    102 rem ***
    110 x=int(rnd(ti)*(40-w))
    120 y=int(rnd(ti)*(25-h))
    130 gosub 200
    140 goto 100
    199 end
    200 rem ***
    201 rem *** draw a box
    202 rem ***
    210 rem *** restore any orig'l content
    211 rem ***
    220 if first then first=(1=0):goto 300
    230 for xx =0 to w-1:for yy=0 to h-1
    240 poke p+yy*40+xx,a1(yy*w+xx)
    250 nextyy:nextxx
    300 rem ***
    301 rem *** read current text content
    302 rem ***
    310 p=1024+40*y+x
    320 for xx=0 to w-1:for yy=0 to h-1
    330 a1(xx+yy*w)=peek(p+xx+yy*40):
    340 nextyy:nextxx
    400 rem ***
    401 rem *** put box on screen
    402 rem ***
    410 for xx=0 to w-1:for yy=0 to h-1
    420 poke p+yy*40+xx,a(yy*w+xx)
    440 nextyy:nextxx
    450 for t=0 to te:next
    460 return
    

    The long wait loop (which makes the program perform so slow) is so that you can spot the random 3-by-3 box, while also making the artifacts less noticeable. You can see the box long enough, so it disappearing from screen will feel less jarring. A better solution than waiting a while would be to use a screen buffer to do the drawing and switch screen buffers when all the drawing is done for the new position of the box.

    I guess that would require some machine language I have yet to write.