Showing posts with label VIC-20. Show all posts
Showing posts with label VIC-20. Show all posts

Sunday, April 13, 2025

Snake for Commodore PET, Vic-20, 64, 16, Plus/4, etc.

Here is a single player version of the classic snake game that I have recreated in BASIC for the Commodore Vic-20.  Some may remember snake from the Nokia classic phones (1998) or from Atari VCS 2600: Surround (1977).

I have a Commodore watch platform (M5Stack with watch wristband running my Commodore emulators) which I can run some simple programs.  The purpose of developing this game was to create something I could play on my watch with just two buttons.


Apparently my high score is 73.  Try to beat that!

Open source (MIT License) and binaries including disk image are available at github.

Update 2025-04-16: Also ported to C64 for those so inclined.

Update 2025-04-19: Ported to Commodore PET and TED systems: Plus/4, 16, etc.



Sunday, August 11, 2024

Vic-20 memory configurations supported by emulator


The C128 team invented the GO64 command for compatibility.  Years ago I claimed to invent the GO128 command, and GO20 and some others.

My Commodore emulator (unified branch) that supports Windows and LCD targets including compact watch form factor, now supports an argument to the GO statement to specify the total memory to configure.

The Vic-20's memory map looks roughly like this.

//   (from emuvic20.cpp)
//   $0000-$03FF Low 1K RAM
//   $0400-$0FFF (3K RAM expansion)
//   $1000-$1DFF 3.5K RAM (for BASIC) [or alternate screen address]
//   $1E00-$1FFF 0.5K RAM (Screen characters)
//   $2000-$7FFF (24K RAM expansion)
//   $8000-$8FFF (Character ROM)
//   $9000-$9FFF (I/O)
//   $A000-$BFFF (8K Cartridge ROM, or RAM expansion)
//   $C000-$DFFF BASIC ROM
//   $E000-$FFFF KERNAL ROM

The Vic-20 was manufactured with 5K RAM, with only 3.5K available for BASIC, not counting the color RAM nybbles (half-bytes).

There is a missing hole of 3K RAM in lower memory, cartridge sold separately.   And you could also purchase 8K or 16K RAM cartridges.  And later on 24K and 32K solutions.   Up to a total of 35K RAM can be added into the memory map.

So specify the amount of RAM you want to add, and rounding down, the emulator will populate the appropriate memory.

But only 27.5K is available to BASIC programs.  1.5K is reserved for system use, the lower 3K RAM is only available to BASIC in some instances, and an upper 8K is reserved for cartridges and otherwise not contiguous, so also not available directly for BASIC use.

The VIC video chip (named VIC) can only address screen memory on the main board, so when both 3K and 8K memory expansions are populated, screen memory is directly in the middle, causing Commodore BASIC to ignore the lower 3K memory to prioritize for the larger contiguous memory configured after screen memory.  The 3K lower memory is only used directly when it is the only contiguous RAM expansion, such as with the separate 3K memory expansion cartridge and with the Super Expander that included 3K RAM expansion, but stole more memory for the programmable function keys, and for the graphics screen.

GO 20        (default, 3583 bytes free)
GO 20, 5    (minimum, 3583 bytes free)
GO 20, 8    (5K, +3K, 6655 bytes free)
GO 20, 13
    (5K, +8K, 11775 bytes free)
GO 20, 16    (5K, +3K, +8K, 11775 bytes free)
GO 20, 21    (5K, +8K, +8K, 19967 bytes free)
GO 20, 24    (5K, +3K, +8K, +8K, 19967 bytes free)
GO 20, 29    (5K, +8K, +8K, +8K, 28159 bytes free)
GO 20, 32    (5K, +3K, +8K, +8K, +8K, 28159 bytes free)
GO 20, 37    (5K, +8K, +8K, +8K, +8K, 28159 bytes free)
GO 20, 40    (5K, +3K, +8K, +8K, +8K, +8K, 28159 bytes free)

Note that many of these show the same number of bytes free even though extra memory has been added. This again is because only contiguous RAM can be configured as available to BASIC.  The extra RAM is available for PEEKs, POKEs, and other machine language programs.

If a number out of range is entered, it is effectively rounded down to a valid configuration.  For example GO 20, 64 will configure with 40K RAM.   But 5 is the minimum, so GO 20,0 will configure 5K RAM.

Technically the Vic-20 tests for and can handle memory added in smaller configurations, but that's not commonly present in reality, and not how I implemented it.   Also I only implemented adding 8K memory forward in the map (with the exception of the 3K coming and going based on math), and not configuring each section separately.  Going with a total RAM value is a simpler concept to implement and understand.

Please enjoy the Vic-20 with extra RAM!


Tuesday, July 9, 2024

Disassembler for use with WozMon

 

Disassembler disassembling WozMon

WozMon is a great little monitor program in 256 bytes which Steve Wozniak wrote for his Apple 1 release in 1976.  It was small but powerful allowing for memory inspection, entry of 6502 machine code programs and bytes, and launching of programs in ROM and RAM (jumping to address).

But being small, it is missing features that monitor users have learned to depend on, including a mini-assembler and disassembler.

So here I am today presenting a disassembler I wrote for 6502 which can be integrated with WozMon run command.  Once the disassembler gets control, the Y register contains a pointer to the last character read from the input buffer, and continues parsing for a hex address.  If not found, it simply returns to WozMon.  But if found, it will disassemble 20 statements starting at that address.  (Note: Vic-20 port above, changed to 17 statements due to the smaller screen size).

The syntax may be lengthier than other monitors, but it allows for an integration with the normally ROM based WozMon without modifications.  Plus you get what you pay for.   The disassembler is open source, so feel free to change it.

The disassembler came into being as part of developing a mini-assembler.  First I'd written a prototype in C# .NET. 

The assembler included tables of information for the 6502 instruction set and addressing modes that lent itself to be used as a disassembler (came second) which was prototyped as a 6502 program that disassembles itself.  Third came the disassembler compatible for use with WozMon.

Each prototype and program is one step along the way for the goal of creating a mini-assembler for my 6502 minimal system.  Not there yet, but getting closer with each step!

Also works with original WozMon in Apple 1 style environment

Also works on C64 and C128 systems


Sunday, May 26, 2024

LCD version of 6502 emulators ported to Windows

 

LCDs and Windows too!

Now the c-simple-emu6502-cbm unified branch that works with LCD systems has been ported to Windows!  This is an emulator that includes a feature to switch between various popular Commodore 8-bit models from the BASIC prompt.

You may ask yourself, hey self, wasn't Windows already a supported system?  And you could answer, yes self, it was.  But only in text mode.  If you wanted to run Commodore BASIC from a command prompt, yes you could do that.  If you wanted to run this emulator with the nifty "GO 128" command in a graphical environment you were required to use those smallish LCDs (well the 7" isn't too smallish).

Now, by porting this C++ project back to Windows again, using GUI elements, it can now look more like a Commodore.  The fully resizable window, and keyboard support make it feel like you have a Commodore right in front of you.  You virtually do!

For now, you need to compile the project in Visual Studio 2022 (Community Edition should work just fine).  It probably also works from Visual Code, but I haven't attempted that yet.

Dependencies include a roms folder (see README.md), optional disks/drive8.d64, and optional disks/drive9.d64

The purpose of this is to ease development of new features, utilizing the feature rich Visual Studio IDE including debug support.

The benefits to other users include being able to test drive the project in an environment they already have - their existing Windows desktop or VM.   And if you love it and think you may enjoy a portable version, you can then invest your dollars into an LCD solution via various online retail websites.   There may even be a search engine out there to help you too.

Are you keeping up with Commodore?  Happy computing!  Spend that money wisely.

Friday, April 19, 2024

Edit Programmable Characters on Vic-20 and C64

 



The current release is considered fully functional and complete.

Links:

Vic-20 D64 (1541 image) and source

Commodore 64 D64 (1541 image) and source

The Commodore Vic-20 video chip added multiple features beyond what the original PET Model 2001 offered.  Besides color support, it also includes the ability to change to user defined character sets.  These can be used to customize the look and feel of a program, and also to provide bitmapped graphics.

Back in the 80s I was proud of my development of a character editor program that utilized a few machine language routines to perform quick operations via keyboard selections.   Unfortunately I don't have direct access to that program today (haven't been able to read the tape back into the computer yet).  So I decided to rewrite it again.

This time it is purely 6502 assembly code.  I started using the VICE monitor to write the initial functionality, and soon afterwards transitioned to ACME source to ease edits and additions.

After mocking up the look of the screen, identifying operations that would be nice to have, and testing out memory layout and configuring the video chip to use character images from RAM, I got to work.


1. Initial screen layout including editor and commands.

2. Navigation of character selection, displaying bit patterns for editing to screen, and displaying hex character value and byte values.

3. Editing the pixels in a single character.

4. Saving font to floppy disk.

5. Continuing to iterate with new features and enhancements


Description of key operations

pressing a key on the keyboard as shown below will perform an operation:


@ - toggle between RAM/ROM character sets

SPACE - toggle pixel on/off

B - navigate back one character

C - copy

F - flip upside down

M - mirror the image left to right, right to left

N - navigate forward to next character

R - rotate 90 degress to the right

S - save to FONT.BIN (WARNING: overwrites any previous saves)

V - paste

X - cut

Y - redo

Z - undo

- minus - navigate 16 characters back

+ plus - navigate 16 characters forward

< > - shift pixels left/right

↑ - shift pixels up (^ carrat on PC)

Shift V - shift pixels down

CLR - erase all pixels

CURSOR keys - move cursor left/right/up/down

HOME - move cursor to upper left position

RVS - inverse the pixels

STOP - exit (usually mapped to ESC on PC)


There are up to 24 levels of undo [Z] (25 levels of redo [Y]) when editing a character.  Navigating will clear the undos/redos.   And there is a virtual clipboard which you can copy[C]/cut[X]/paste[V] a single character.   Note in this program you do not use the Ctrl key for clipboard as you do on a PC.

Notes:

  • When launching the program for the first time, the ROM font will be copied to RAM, including moving the start of programs up to $1800 past the RAM characters.   Subsequent runs from that address will not recopy from ROM.  If you want to restart fresh from ROM, either reset your computer and run again, or POKE 44,16:SYS 6157.  You don't have to memorize the entry point, you can also LIST the line of BASIC that calls into the entry point.
  • Saving overwrites FONT.BIN.  So if you want to save your work permanently, it is recommended to rename your file to something else.
    OPEN 15,8,15,"R0:COOL=FONT.BIN":CLOSE 15
  • To LOAD your font for editing, be sure to run the program at least once, then load before running to enter back into edit mode.  Be sure to include the ,1 otherwise you will wipe the font editor out of memory, then best to restart your Commodore and try again.
    LOAD "COOL",8,1
  • Pressing COMMODORE+SHIFT while in programmable characters will shift to a second set of characters which we don't have room for in RAM, so you will see bitmapped images of the program and video memory.   Press the key combination again to return to the first set of characters. [Disabled in the C64 port]

Update 2024 April 20: also ported to Commodore 64

Update 2024 April 26: more documentation

Description of key operations since added to Commodore 64 version

H - hide UI except pixels and character for a minimalist experience

/ - swap between two RAM character sets (C64 version edits total of 512 characters) 

F1 - foreground color

F2 - cursor color 

F3 - background color

F4 - character set 1 color

F5 - border color

F6 - character set 2 color

F7 - large pixel set color (editor)

F8 - large pixel cleared color (editor)

, - change titles color

. - change menus color

1,2,3,4,5,6,7,8,9,0 - select theme (colors and grid mode)

 As the C64 has a different memory layout, video memory is at a lower address $0400 and more memory available, the memory map is a bit different.  The start of the program is still at $1800, but the programmable characters are now from $0800 to $17FF, a full 4K (512 characters). 

Note that only the first character set (256 characters) is visible at this address without moving the character set to another location (planned for future).  But the editor can handle this by swapping the character sets in RAM for editing, swapping them back and forth, so one set is always edited from the lower $0800-$0FFF range that is visible.  Just be sure to swap back to the first set before saving, otherwise the character sets will be out of order.

To use both character sets in your own programs, it is necessary to manually relocate them or load them at another address, unless you use the swapping technique used by the editor.

It is not presently possible to use raster interrupts to show both sets because the second set is at an address that is mapped to ROM characters instead.  Another reason it is planned to move these in the future, for example to $3000-$3FFF but in the middle of BASIC RAM it may be too challenging to be useful to others.

Probably a better solution is to move both VIC-II memory to another bank of 16K, which also requires moving video memory.   Say bank 4 with characters at $F000-$FFFF, and video ram at $CC00-$CFFF.  Then move the start of BASIC to $0400, resulting in 39933 (39K) bytes available for BASIC, an increase of 1K the size of the video screen memory.

Leaving the editor, you have lost 4K of RAM from BASIC.  To reclaim 2K for the not visible second character set, POKE 44, 20: POKE 20*256, 0: NEW but don't load any of your double character sets or you will wipe out the first 2K of your BASIC program.   Best to leave 4K lost at start of BASIC in that case, or resize your character sets to a single set.

We're in the weeds here.   Back to the fun -- please enjoy the programmable character sets and the graphical opportunities they provide!

Update 2024 April 27: raster interrupts implemented as described above, with two sets on screen, and working area using ROM font so doesn't change.  Second set is copied to $3800-$3FFF for display purposes, while the two sets remain at $0800-$17FF.

Update 2024 April 28: themes implemented (10) and grid mode added, new C64 keys updated above.  Themes allow quickly changing between color sets and grid options using the numeric keys.

Update 2024 May 1: wrote an article on moving video and programmable character memory.

Update 2024 May 4: have fixed many issues, and more enhancements, including moving programmable characters to $2000-$2FFF to make more usable, eliminate need to have separate edit/view copies.  But loses more BASIC RAM ($0800-$1FFF 6K now available for other uses) while reserving memory for characters.

Primary Color Theme


Wednesday, February 7, 2024

Calculator for Commodore 64 and other CBM BASIC models

 


Introduction

Wow! A new desktop calculator for Commodore.  Programmed all by myself in BASIC.  Wow, so impressed!   Or not.  Doesn't even have decimals.

No, it's not the best thing since sliced bread, but it was fun.  And it's just a start -- there's a bigger goal I'll get to in a while...

This was a puzzle programming exercise I challenged myself with.  How to make the calculator, especially with the operator precedence feature.

Link: LOAD"CALC64",8

Implementation

Let's go through how it was implemented.

User Interface

First was the design of the user interface, by creating PRINT statements.  Used reverse text to make a rectangular box with the keys displayed.

How to click on a key?  I'm so used to a mouse or touch interface.  Oops, Commodore doesn't have that usually, or not so easy.  Ignoring the 1351 mouse for now.   Most Commodore users are used to using the keyboard or joystick.  Forget the joystick, this is not a game!  Keyboard entry one key at a time will do just fine.  Note that ENTER also acts as =, and DEL is equivalent to ←, and X is a synonym for *.

Entry of digits was the first processing, accepting up to the limit of the display.  This stored as a string (V$) with keyed entries appended.

I started with 7 digits, but outgrew that in testing and increased to 9 digits.

At first, only positive numbers were supported, then fixed it to support negative numbers, with the negative sign taking up a position in the display.   The N key toggles a number entry between positive and negative and back again.

Entries allowed by this calculator are interleaved numbers and binary (two argument) operators.  Note that immediate operators like C and N usually take effect immediately, whereas binary operators require multiple arguments and a finalization (another binary operator or =).

There are exceptions allowed in entries to overwrite the prior value or the prior operator.   Examples:

  • 1+1=3 keyed entries will replace the 2 with a 3
  • 2+x3 will replace the addition operator with multiplication operator

Precedence needs a Stack

One design requirement I set for myself was to include operator precedence.  This means that multiplication and division have the same higher precedence over addition and subtraction at the same lower precedence.  Usually math is evaluated left to right, but due to precedence issues, other operators may need to be done first.  In other words the expression 1+2x3 is equivalent to 1 + (2x3) and then 1 + 6 and finally evaluates to 7.   But 1 x 2 + 3 is equivalent to (1x2) + 3, then 2 + 3, and finally 5.

I simply put numbers and operators interchangeably on a stack in order of entry until enough information is present to start evaluating.

Rule 1 - if user presses =, then evaluate

Rule 2 - if first operator is multiplication or division, once the second number is finalized with a second operator, simply evaluate the first expression

Rule 3 - if first operator is addition or subtraction, defer until the second operator and third number is finalized (third operator present!), then figure out what to do - either evaluate first or second expression, reducing the work

The stack is implemented as a count C, and an array of strings S$, which is expected to only grow up to 6 items (0..5), example C=6, S$[0]="1" [1]="+" [2]="2" [3]="*" [4]="3" [5]="+"

This example 1+2*3+ is reduced to 1+6+ and then to 7+, with the display updated to show the 7, but then wiped to disallow appending to it.


And no, I'm not doing RPN.  I didn't grow up with an HP calculator, nor am I implementing one today.  I grew up with Texas Instruments, and that's how my brain works.   Keeping it in entry order keeps it orderly for me.  Sure, there are other was to approach it.   This is BASIC, not Lisp.  And this is MY calculator, so I'm doing it MY way.  Others can follow their own paths.

Expression evaluation includes handling the equals = operation.  In the context of this calculator, that finalizes a calculation, meaning the user wants the result now.

Subroutines

There are several subroutines: 1) Evaluate and reduce stack, 2) Update display, 3) Display stack, 4) Evaluate simple expression involving two numbers and an operator.

That last subroutine is a diagnostic useful most for development, but also shows work in progress compared to a regular simple desk calculator that usually won't show pending work.

Error conditions

Overflow is when the number to be displayed doesn't fit in the 9 digit display, when the string representation of the number is long than 9 characters and/or larger than the maximum whole integer value that can be displayed in that space.   Note that the number is still internally represented and can still be acted on.  If a resulting answer can be displayed it will be (example: divide a ten digit positive number by 10).

Error indicates that division by zero was attempted.

Limitations

Only integers are supported.  No decimal numbers.  No currency.   Workaround required to calculate a percentage -- multiply by one hundred first, then divide by whole percentage.  And division results in a whole number so 1/3= results 0, and 5/2= evaluates to 2.

Non-negative numbers are limited 0 to 999999999 (nine digits).  Negative numbers are limited -1 to -99999999 (note only 8 digits).

Scientific notation is not supported.

No paper tape, no printout, no record of operations.

Limited user feedback.  No keypress indicators.

Stack diagnostic is a little technical, especially with a count, then colon, and the entries.  (Could eliminate the count and colon, and/or show previous and pending operators before and after the display.)

Keyboard entry.

Extras

The program was saved with a starting address $400, to support PET, so you must not load with secondary address 1 on a C64!  And while the program assumes a screen bigger than a VIC-20, a few minor changes to the margin and startup text can remedy that.

Next

What does the future hold?  Who can predict with any accuracy?  I can say anything here, but doesn't mean I'll follow through.  I originally was contemplating near limitless number of digits (considering the 8-bit platform, probably some 16-bit limitation).   Maybe binary and hex?   Maybe a scientific calculator?   Fixed decimal?   Near limitless decimals?   Port to assembly for fun!   We'll see...

Have fun calculating!

Saturday, December 9, 2023

Commodore keyboards go wireless for my portable emulators

The c-simple-emu6502-cbm project supports a number of ESP32 platforms to provide a subset of Commodore C64 (and Vic-20, C128) emulation, and many currently include BLE keyboard support.  Originally for CardKB only, now I have added BLE support for Commodore keyboards (20 to 25 pins) to the m5, T-Display-S3, and ESP32-8048S070-7inch ports/branches into the encapsulated BLE_commodore_keyboard_server Arduino sketch.

BLE options: (a) Commodore keyboard (b) CardKB

No expense spared for these awesome graphics, seems retro eh?


While I have wired in the full C128DCR keyboard in the past using a circuit and software sketch with an Adafruit ItsyBitsy, now I trade the wire with another ESP32 and BLE communications.

M5Stick-C with CardKB BLE connected to T-Display-S3

Actually we already had BLE CardKB support, and the protocol for the hard wired keyboard is exactly the same as sent over BLE (string of active C64 and C128 scan codes), it was just a little bit of further coding to make the choice between CardKB and hardwired keyboard.   In fact, that code was already present for CardKB or hardwired keyboard in the M5 branch itself.  The tiny bit of extra work was to duplicate that in the BLE keyboard server project.   And voila!  More options all the way around.

Wired keyboards (a) Commodore (b) CardKB (c) Chrome Browser

There were already three options for wired keyboards.  And three common Commodore keyboards were represented, because they all have compatible pinouts, and because I do have both Vic-20 and C128DCR at home.

Dropping the wire from the wearable (or other ESP32 emulators) adds convenience to mobility, and also defers the need to support wired connections to any ESP32s missing Grove connectors and any that are not 5V tolerant, as both the ItsyBitsy and CardKB use 5V interfacing.   BLE support, and improved BLE support provide more options to the emulators running on hardware such as the T-Display-S3 and the 7"LCD ports without any hardware interventions.  While these latter ports would require extra circuitry for hardwired serial or I2C connections including 5V to 3V3 interfacing, using BLE means that the existing circuit support on the M5Stick-C acting as the BLE server can wire to those keyboards instead.  Going wireless provides the equivalent functionality without requiring a hard-wired circuit to the final display device.

While wireless does have its convenience, it does require careful timing to pair correctly.  Typically if both the BLE client and server are powered or reset at the same moment, they should pair.   A few or more keystrokes may be necessary to confirm pairing is complete.  If it doesn't work, just reset and try again.

Happy C64 computing over BLE!

Monday, December 4, 2023

New! and Improved! C64 text emulator

There has been a steady stream of improvements to my wearable C64/C128 text emulators and related projects since the Summer 2023 debut at VCF West 2023 in Mountain View.  My Twitter/X account includes posts of many of these advancements.

  • used a 6502 test suite to find problems in my emulation
  • Vic-20 emulator
  • Vic-20 upscaled resolution
  • A few more hardware targets supported, including much smaller sizes
    • M5Fire 320x200
    • M5Atom S3 128x128
    • M5Stick-C 160x80
    • LilyGo T-Display-S3 320x170
  • Downscaling resolution as necessary
  • Tilt and pan for 1:1 resolution on tiny screen sizes
  • FATFS partition for files when no SD present, and when PSRAM not present
  • M5Stack CardKb support
  • wireless keyboard (BLE server/client)
And all these changes are stored on GitHub of course!

A fellow attendee at Vintage Computer Festival West 2023 sported a red M5Fire and it looked really good!  So I ordered one soon after, it arrived with some other goodies, and I quickly ported the M5Core2 and M5CoreS3 solution to the M5Fire.   Features are comparable.

Then I added keyboard support to the on-screen buttons.  Left goes up.   Right goes down.   Center is Return.  Left+Center is Shift+Run with a ROM change to make it load the first program from disk.  And Left+Right toggles between the different emulators (C64 -> C128 -> Vic-20)  This made an actual keyboard optional for demos.  I had a boot program to provide a listing of programs selectable by cursor keys and Return key.  

The only downside is that the M5Stack Fire is not watchband compatible in that the recharge circuit is in the detachable base, not in the unit itself.  Otherwise it would make a classy wearable.


Vic-20

The Vic-20 was my original home computer.  It is what I used to deep dive into Commodore, learning BASIC and 6502 Assembly Language inside and out from about 1982 to 1985.  I still have a fondness for this system.

But it has an odd screen resolution.  Text is 22 columns and 23 rows equating to 176x184 pixels.

The M5Core series controllers have an LCD 320x240.   This was just perfect to match the standard text screen of the C64 which is 320x200 pixels. 

Originally I simply increased the border sizes around 176x184 pixels.

Then I revisited my Teensy C64 which has an option for a 480x320 LCD screen.  For that project I researched upscaling, which involved scaling an 8x8 character cell to a 12x12 character cell, using color averaging.

For the M5Core series, I similarly scaled the Vic-20 8x8 character cell to 12x8.   To accomplish this, staring with pixel offset 1, an extra column is interpolated from the previous and next pixels, and repeated a total of four times.  The LCD works in 16-bit color mode with 5 bits for red, 6 bits for green, 5 bits for blue.  The color of the two pixels is broken down into its component red/green/blue parts, the corresponding color parts are averaged (totaled and divided by 2), then recombined into a 16-bit value for the interpolated pixel.

So far only the M5Cores with PSRAM have Vic-20 and C128 support.

M5Atom S3

This is the smallest target hardware I have ported to.  Downscaling was implemented to see what would happen.  The 8x8 character cell is downscaled to 3x4 pixels, so 64 pixels downscaled to 12 pixels which is a large number of pixels to through away.  Priority was given to the center pixels, so it toggles between averaging 6 (3x2) or 4 (2x2) at once.  It does a weighted average between the foreground color, and background color pixel counts, so the resulting downscaled pixel is closer to one or the other.

Surprisingly, the screen is somewhat readable even with this resolution loss.  But to compensate for loss a zoom and tilt to pan feature was implemented.  The whole screen is mounted as a single pushbutton.  Clicking it toggles between zoomed out to the downscaled resolution, and the zoomed in to the pixel perfect 320x200 resolution that is panned, by tilting the device.  Zoomed in, hold the device level with the floor, with the screen pointed to the ceiling, and you will see the top center of the C64 screen.  Tilt to the right and forward to see the top left corner of the emulated screen, and so forth to switch between one of six views of various parts of the emulated screen with every pixel shown.   Click again to zoom out for an overview of the entire screen, but downscaled.  Break out a magnifying loop or such to see the detail of the teeny tiny pixels.

This platform does not include an external storage device such as SD card.  Nor does it have PSRAM normally used by the D64 emulation.   Instead, a FATFS partition was initialized, and individual C64 PRG files were selectively uploaded to the device.   The "$" directory functionality is not present, but LOAD/SAVE/VERIFY are supported.   There is room for about 1.5MB of files in the partition size selected, that's about 9 times larger than the standard single sided C64 floppy, so not too bad!

M5Stick-C

I had forgotten about this hardware device.  It was the first M5Stack device I had purchased, and I had squirreled it away in a project box.   Obviously it was too small for a C64 screen so I didn't give it another thought.   Until I saw a post on Twitter/X showing the solution with CardKB.  Looks like it's using my text-only emulation, using LCD fonts.  Of course I respond!  That would work very well.  I've just been so focused on LCD pixelized solutions simulating the look and feel of Commodore instead of remembering the roots of my text emulation efforts with C64.   Just hook CHARIN and CHAROUT and you're golden.  You don't need a screen editor.  You can just do buffered line input (local edit), and character output.   I was laughing at myself for not pursuing this myself.  CardKB provides ASCII output (from I2C polling) of the alphanumeric characters, and other byte ranges for functions and cursor keys. 

I wanted to do CardKB, but as I have been focused on C64 scan code adapters, it seemed hard.  But here was the challenge presented on the Internet.  I had already implemented an adapter of sorts leveraging a SeeedStudio ATMEGA328P (Uno compatible) board with Grove connectors and an Arduino sketch to translate I2C reads into TTL serial scan code reports.  And it worked, but was very clunky because of all the cords and extra board.   My existing prototype solution was not great for a wearable solution.

The M5Core and such were focused on using the Grove connector as a software serial port, receiving the C64 scan codes.  I had the original C128/C64/Vic-20 keyboard to Grove adapter running on an Adafruit ItsyBitsy and that was my favorite keyboard connection because it was true to the original!  Next best was a web page to USB Serial adapter I had also developed.   The common ground was scan codes, and serial communication.  But the CardKB runs I2C.   So how to do CardKB and serial communication simultaneously on the same Grove port?   Originally I thought of getting the source to CardKB and rewriting, reflashing it to do serial communication instead.  That would make it compatible with my existing solutions.  But I was avoiding the reflashing that would also requiring rigging a programming interface, using an Uno or compatible.   

Instead, I approached the Grove port as an either or, the emulators were updated to check for an I2C response at startup, and if found, regularly read from the I2C port for keyboard presses.  Then adapt those presses from ASCII/function code presses into momentary C64 scan codes, and 1/60th of a second later, respond with no key pressed (key up) scan code response.  This is an out of the box solution that will work for others too!

M5Stick-C also leverages a FATFS partition as there is no built in SD port.  Again 1.5 million bytes.,  Though I did have to revise the partition choices manually via a JSON file as FATFS was not included in the default partition schemes presented.

But the screen resolution is 160x80, with downscaling of one character's 8x8 pixels to 4x3 pixels.  This time the pixels are halved horizontally, and vertically there is an 8 to 3 pixel translation, very similar to 
the downscaling on the AtomS3, but rotated to different axes.

This is by far the worst unreadable display for individual text characters.  More than halving the vertical resolution makes the text completely unreadable (such as the startup screen).  It's not it's fault completely, and is a cute form factor when not pretending to be a C64.

LilyGo T-Display-S3

This is another inexpensive device with a wide yet shorter display 320x170.  Oh so close to the necessary 200 pixels.  So a custom downscaling algorithm favoring the center four vertical pixels of each character cell, while averaging the top two and bottom two pixels.  This results in a very recognizable display of alphanumeric characters with some slight distortion at the top and bottom of each character.

While this device has plenty of flash storage and PSRAM comparable to the best of M5Stack Cores, there is no built in SD card, so the implementation also leverages a FATFS partition successfully.  But with the PSRAM included, D64 support could be included allowing for the floppy drive image feature.

BLE keyboard support has also been included with this one, making it full featured.

The features missing are no Grove connector, no socket for CardKB support, and Vic-20/C128 support.  A bit more effort could transfer these features with software and hardware.

CardKB

     Esc 1! 2@ 3# 4$ 5% 6↑ 7& 8* 9( 0) <x
     Tab Q  W  E[ R] T/ Y£ U| IÏ€ O' P" fn
  Up  Shift A; S: D  F+ G- H← J= K? L  <-
Lt  Rt  Sym Z  X  C  V  B  N  M  ,< .> __
  Dn

fn+1..fn+0 is ctrl+1..ctrl+0
fn+A..fn+Z is commodore+A..commodore+Z
Esc is stop
fn+Esc is stop+restore
tab is load+run
fn+tab is restore
fn+<x is insert
fn+up is clear
fn+right is home
fn+down is toggle case (cbm+shift)

Wireless BLE Keyboard

Taking CardKB one step farther is joining it with a M5 controller such as M5Stick-C to turn it into a Bluetooth Low Energy keyboard.  Currently integrated with M5Fire, M5Core2, M5CoreS3, and T-Display-S3, turn them both on at about the same time and they will automatically pair.  While the keyboard is wired to the M5Stick-C, another ESP32 system can be battery powered and receive keystrokes over the air with the BLE (2.4GHz) radio.  




I used to wire the full size C128 keyboard to my wrist, and it was a hilarious irony in mobile computing.

Monday, September 19, 2022

HIRES for Vic-20 (BASIC 2.0 extension) is READY.

 


The BASIC commands are implemented, small font created, and demonstrations implemented.   Please enjoy this Space War and Omega Race inspired flying ship.

Source, disk image, and more details are on github for Commodore Vic-20 with memory expansion.

BASIC extension command syntax is:

COLOR [foreground[+8][,[background][,[border][,auxillary[,inverse]]]]]

COLOR [foreground[+8]] @ x1,y1 [TO x2,y2]

TEXT

HIRES xresolution, yresolution [,fillbyte]

DELAY jiffies

PLOT COLOR ON|OFF

PLOT [NOT|CLR] (@ x1,y1)|(TO x2,y2)...    **

PLOT 0|1|2|3 (@ x1,y1)|(TO x2,y2)...

PLOT "ABC" @ x,y [,addr [,width,height [,bytes]]]

RECT [NOT|CLR] [@] x1,y1 TO x2,y2

RECT 0|1|2|3 @ x1,y1 TO x2,y2

SHAPE GET|PUT|OR|XOR|AND|NOT|CLR addr @ x1, y1 TO x2, y2


** only first @ optional, when not multi-color

Monday, August 29, 2022

Vic-20 Hi-Res BASIC extension progress

 


Shape operations are functional, and work has begun on leveraging BASIC keyword extensions (borrowing from my own HIRES for C64).

4UPART program listing


While the SYS syntax is implemented, the BASIC keyword work has just begun.

Current vs. Proposed Syntaxes

Source and disk image are on github



Sunday, July 17, 2022

Vic-20 HI-RES in progress - Memory Layout

Vic-20 Graphics Memory Layout

The Vic-20 doesn't have a native graphics mode.  But it can use a character set from onboard RAM, and double the size of character cells from 8x8 to 8x16 pixels.


A solution puts video memory at address 4096 ($1000), and character RAM at ($1000).  Notice they are the same?  Yes, there's only 5K onboard RAM in addition to color RAM.   The first 1K starts at address 0 ($0000), and the other 4K starts at address 4096 ($1000).   Regardless of any other RAM present in the system (can add 35K), only that latter 4K is accessible as video/character RAM to the video chip.  (Even if the earlier 1K is available, there's too many conflicts with BASIC and KERNAL use).

So bitmapped characters (graphics) and video RAM (characters on the screen) have to share the same section of memory.  The way bytes work, at most 256 characters could be displayed on the screen, but that would require a full 4K of RAM for their bitmaps (16*256), so something has to give.   By using only 240 characters on the screen, that reserves 16*16 = 256 bytes for video memory, and the remaining memory can be used for graphics.  For the bitmap to skip over screen memory and avoiding any overlap, the characters used on the screen are indexed starting at 16 ($10).

$1000-$10EF screen (240 bytes), values $10-$FF (16 to 255)
$10F0-$10FF unused (16 bytes)
$1100-$1FFF bitmap (3840 bytes)

BASIC RAM can be moved to either 3K expansion RAM ($400-$FFF) or 8K or greater expansion RAM ($2000 and later).

One layout that is possible is 20 characters wide by 12 characters tall = 240 characters = 160x192 resolution.

The easiest layout of characters is to store them consecutively in memory as shown above.   Character layout for the screen is left to right, then wraps to the next row.   This scheme matches color memory layout as well.   An additional advantage is that time sensitive updates to graphics can be more aligned with the raster line.

Another layout of characters is to line them up vertically as shown below.  This has the advantage that memory is contiguous vertically until advancing to the next column of 8 pixels.   This allows for optimizations in managing graphics memory at the disadvantage of working vertically instead of horizontally, thus fighting the raster line.  But color memory is still horizontally oriented, so the address calculation is different, the same as the earlier layout.

 
As the Vic-20 allows for configuring the number of character columns, character rows, and adjusting top and left margins, a variety of resolutions are possible.

Some notable resolutions include

160x192, 192x160, 200x144, 144x208, 160x160

The last is mentioned as it is the resolution used by the Super Expander cartridge.  But note it only requires 200 bytes of screen memory, so using that resolution leaves 696 bytes of onboard memory unused for graphics/screen that could be available for another use, maybe 506 bytes is still text screen memory. 

Links




Saturday, May 14, 2022

GO 128 enhancement for Commodore

 


One wonderful feature of the Commodore 128 was its compatibility with the Commodore 64.  It was an evolution of the Commodore 64 and still supported all the software and hardware from before.  For me it was a no-brainer to buy.  80 columns, plus new features, plus CP/M.   Adding a mouse, GEOS 128, REU 512K, and 3.5" floppy, and I thought it was the best place to be this side of heaven.

There were multiple ways to go into Commodore 64 mode.

  1. Start with a Commodore 64 cartridge
  2. Boot/reset with the Commodore key held
  3. Commodore 128 boot disk that switched to Commodore 64 mode
  4. Switch MMU to Commodore 64 mode
  5. GO 64 command
But the only way to get back into Commodore 128 BASIC 7.0 was to reset the system.



Fast forward a few decades or so, and now we can add GO commands to the other BASIC systems to switch between them.  Links: cross-platform source, Windows binary release.

How does it work?  This is emulation.  Sorry purists.   The Commodore 128 MMU was built so there is no going back out of C64 mode.  This was by design to keep 64 mode on the 128 very close to 100% compatibility.  But emulation?  Anything goes.  The GO command is hooked, the argument is checked for a number, and if the number is right, it goes to that Commodore model by restarting the emulation for that system.  And thus, when running the BASIC for one system, can quickly switch to another other system (or even reset the system) using the GO command.  It even prompts for amount of RAM to allocate (except 128 is fixed at 128).

PET 2001 2K to 64K supported 
Vic-20 5K to 40K supported in hardware supported increments, not all available to BASIC
64 RAM 3K to 64K supported not all available to BASIC
Commodore 16 and Plus/4 support 16K, 32K, or 64K
Commodore 128 fixed at 128K (KERNAL does not do RAM test) 

Limitations?  Oh, sorry.  This emulator is text only.  No full screen editor.  Doh!   No screen pokes either (well not displayed).  [Update 6/2021:] PETSCII and commodore graphics characters supported with third party font.  Does support console history editor on Windows.   Linux and MAC builds (you can build from my open source project) provide only simple line editing capability.   Does provide accurate 6502/6510/8502 emulation, RAM banking, etc. according to the platform.   So pop into the MONITOR on C128 or C16, Plus/4, or SUPERMON on other platforms to write and edit machine code.   And because using console window, the text display size is not as limited, 88 columns for Vic-20 and 160 columns for C128.


Save and Load from .PRG is supported as well (except PET at this time, some other limitations).  Disk device is ignored, so defaults to local file system.  Even use absolute and relative paths.

So for simple programs, and just playing around in BASIC, it's not too bad.   Text background and foreground color for Vic-20 is enabled because that color palate is more compatible with the Windows console default colors.  Reverse text should work on all systems.  Home, clear, cursor positioning may work in programs only, not for editing.


Now prompts for RAM size going to 64


Going to Vic-20 from 64


Going to PET 2001 from Vic-20


Going to Plus/4 from Vic-20

Going to Commodore 16 from Plus/4



Going to 128 from Commodore 16

Resizable text console - 132x50 text screen on Commodore 128

Bil Herd, Ted/C128 hardware design project lead (left) and Dave Van Wagner, geek (right)


Links: 

Sunday, April 25, 2021

Low Resolution Graphics for Commodore

Commodore systems come with a graphical character set that can be used for low resolution graphics.

PETSCII low resolution 80x50 example

All the Commodores include block patterned graphics that can be used to display 2x2 pattern blocks, to double both the horizontal and vertical text resolution, for example from 40x25 to 80x50.  Like 4K for the day!  

PETSCII block characters including inverted

In the back of our high school math classroom was an original PET 2001.   This system had a chicklet keyboard, built-in cassette drive, and 40 column white on black monochrome screen.  This system has no graphics modes beyond the PETSCII capabilities.

One of the exercises in my Algebra 2 class was to graph mathematically functions.  I successfully challenged myself back then to plot the graph on the PET using this block graphics method.

Using 8 PETSCII characters, and the inverse of those characters, all 16 combinations of the patterns can be achieved by setting (POKE) the correct value onto the screen (see the A array in the source).  Also achieved is reading (PEEK) the current PETSCII value, converting that into pixel data, and combining existing plotted pixels with a new pixel (see the B array in the source).

LORES PET 40COL listing

My handwritten PET listing from 1982

I found my handwritten program listing that dates back to 1982.  It's beautiful to see that graphics could be achieved with PETSCII with only a few lines of code.  From my positive experiences with the PET, I purchased a Commodore Vic-20, and the Super Expander later in 1983 and switched to high resolution graphics at that point.

A disk image (D64) of samples for PET/Vic-20/C64 is available.  Screen memory locations for PEEK/POKE are different for all the systems, and sizes are adjusted with variables for the 80 column PET, and 22 column Vic-20.  The Vic-20 and C64 also have color memory, so an additional POKE is included to match the current text foreground color (PEEK(646)).  

Update [5/13/2022] there are ports for both Commodore 128 40 column screen, Commodore 128 80 column screen (including SYS calls to read/write VDC 8563), and a port to the TED (C16, Plus/4) series systems showing a color gradient possible with those systems.

Disk Listing for different Commodore Models

Vic-20 low resolution 44x46 plot

Contrast with 320x200 high resolution from C64

PET 80 column screen 160x50 sample

[Change:] 80 P=COS(I)*SIN(I)*2

Commodore 16, Plus/4 screen 80x50 sample (TED)