Starting with that un-optimized version, I will change it to work on the CoCo 1/2/3’s 32-column screen by adjusting it to be properly centered on that display.
Unfortunately, this design is 17 rows tall, and the CoCo’s standard display is only 16. It won’t fit:
We should still be able to enter the challenge by having the program print this pattern, even if it scrolls off the screen a bit. To get one extra line there, we can get rid of the line feed at the end of the final PRINT statement in line 210 by adding a semi-colon to the end:
210 PRINT" * *";
And so it begins…
And so it begins
The goal is to make this as small as possible. There were many ways to approach last year’s Christmas tree challenge, and you can read about the results and a follow-up with suggestions folks gave to save a byte or two.
A simple thing is to remove the spaces at the front and replace them with the TAB() command:
Although this only looks like it saves a character per line (“TAB(8)” versus “seven spaces”), the code itself will be smaller since the TAB command tokenizes down to one (or maybe two?) bytes.
Also, the ending quote is not needed if it’s the last thing on a line, so they could be removed:
But, each line number consumes 5-bytes on it’s own, so a better way to save space would be to pack the lines together. Each line you eliminate saves five bytes. That would become pretty unreadable though, but let’s do it anyway:
This could still be made better, since the text lines were kept under the input buffer limitation size, but when you enter that line, BASIC compresses it (tokenizes keywords like PRINT, TAB and GOTO) making it take less space. You can then sometimes EDIT the line, Xtend to the end and type a few more characters.
That may or may not be allowed for the Logiker challenge. And since I want to provide code here you could copy and then load in to an emulator, I’ll keep it to the limit of what you could type in.
In the next installment, I’ll see if my brane can figure out a way to generate this code using program logic rather than brute-force PRINT statements.
A few years back, Color Computer community member Rietveld Rietveld took an Arcade1Up Rampage cabinet and converted it so I could run other software — such as emulators. Images have been shown of it running the Color Computer emulator and software.
Now, with the official 1.0 release of the NitrOS9 “Ease of Use”, that has been installed on this arcade machine and, by request, my OS-9 game Invaders09 has been ran on it.
I never imagined that my “arcade” game would eventually be running on a (sorta) arcade machine. Thanks, Rietveld!
In my day job, we have a device that needs data sent to it with the bits reversed. For example, if we were sending an 8-bit value of 128, that bit pattern is 10000000. The device expects the high bit first so we’d send it 00000001.
In one system, we do an 8-bit bit reversal using a lookup table. I suppose that one needed it to be really fast.
In another (using a faster PIC24 chip with more RAM, flash and CPU speed), we do it with a simple C routine that was easy to understand.
I suppose this breaks down to four main approaches to take:
Smallest Code Size – for when ROM/flash is at a premium, even if the code is a confusingf mess.
Smallest Memory Usage – for when RAM is at a premium, even if the code is a confusing mess.
Fastest – for when speed is the most important thing, even if the code is a confusing mess.
Clean Code – easiest to understand and maintain, for when you don’t want code to be a confusing mess.
In our system, which is made up of multiple independent boards with their own CPUs and firmware, we do indeed have some places where code size is most important (because we are out of room), and other places where speed is most important.
When I noticed we did it two different ways, I wondered if there might be even more approaches we could consider.
I did a quick search on “fastest way to reverse bits in C” and found a variety of resources, and wanted to point out this fun one:
At that section of this lengthy article are a number of methods to reverse bits. Two of them make use of systems that support 64-bit math and do it with just one line of C code (though I honestly have no understanding of how they work).
Just in case you ever need to do this, I hope this pointer is useful to you.
The clear subroutine in this code is used to clear the screen and initialize it with a grid of green squares. The subroutine begins by loading the value 96 into the accumulator register A using the LDA instruction. This value represents the color value for green, which will be used to fill the screen with green squares.
Next, the LDX instruction is used to load the value 1024 into the X register. This value is the memory address of the top left corner of the screen, and it will be used as the starting point for the POKE operations that will be used to fill the screen with green squares.
The loop label marks the start of a loop that will be used to fill the screen with green squares. Inside the loop, the STA ,X+ instruction is used to store the value in the accumulator register A at the memory location pointed to by the X register, and then increment the X register by one. This has the effect of setting the value at the current memory location to the color value for green, and then moving to the next memory location on the screen.
The CMPX instruction is then used to compare the value in the X register to the value 1536. If the X register is less than 1536, it means that there are still memory locations on the screen that need to be filled with the color value for green. In this case, the BNE instruction is used to branch to the loop label, causing the loop to be repeated and the next memory location on the screen to be filled with the color value for green.
If the X register is equal to 1536, it means that all of the memory locations on the screen have been filled with the color value for green, and the loop can be exited. In this case, the BNE instruction will not be executed, and the RTS instruction will be executed, causing the subroutine to return to the main program. This completes the execution of the clear subroutine.
– ChatGPT AI
Now, it may have figured some of this out because I previously fed it a longer (and fully commented) bit of 6809 code that contained that routine as one of its several functions. That’s the only way I can see it knew the screen location and a green block.
Recently on LinkedIn, I saw a post by Rogelio Perea about his Tandy Model 102 portable computer. Although I never owned one, I remember this machine well. I always wanted one. Having a “portable” computer really wasn’t a thing back in those days, and this one even had a modem built in!
I recalled how, when I worked for Radio Shack, I wrote a program on our display Model 102 that we used to track our customer repairs. We had to have everything on paper in those days, but would type things in to the computer so we could find them quicker when a customer inquired about their repair status. I wish I had a copy, but I think the only place it ever existed was the memory of that specific computer.
I do, however, have the program it was based on. It started out as a PEN-PAL program for the Radio Shack Color Computer:
*ALLRAM* used BASIC arrays to store the userlog and message base in memory, and would load/save them to tape. My Pen-Pal program did the same thing, but was updated to load from either Tape or Disk.
That Pen-Pal program was also the basis for a custom program I wrote for a lady who ran a large newspaper route where I lived at the time. Her name was Laverne Ricks, and I remember this because I put it on the title screen of the program I wrote for her:
According to comments in the source code, I wrote this on 7/8/1987. This was the summer after I graduated high school, and I had just moved to Lufkin, Texas. Since this was before I got a job at Radio Shack, I am not sure how she and I got connected (possibly through the Lufkin Area CoCo Club or someone at Radio Shack).
The initial version of the program has a menu very similar to the Pen-Pal program:
You can see I had made it look a bit nicer by using graphical black block characters instead of rows of equal signs ;-)
I also found a second version, where I added built-in help:
THIS must be why I wrote the BASIC windowing routine I have written about before. It offered several screens of help:
Neat!
The program has ways to Add a new record:
Ah, the days before spell checkers. You should see the misspellings in my furniture store inventory program I did a year or so later… But I digress.
And you could use arrow keys to flip through them:
Y
You could Delete entries, Edit them, and Insert new ones (at the location you were currently viewing, which was important since a Paper Route was organized by delivery location rather than alphabetical or whatever). There was a way to Jump to a specific entry as well.
And, of course, you could Search by field:
Looking at it 35 years later, I’m pretty impressed with the features it offered. I have no idea what I based all of this on since I’d only owned a VIC-20 and a CoCo at that point and certainly had never worked with any kind of database software that I can recall.
Side note: A short while later, I would do something like this again for someone who ran a garbage collection route, though I think it was for a Tandy 1000 and was using a Deskmate Database.
This is what let me to search out Laverne Ricks and see where she was these days. Sadly, she passed away in 2011.
The Insta360 app has an option to change the password on the X3 camera. This may also work on other cameras, but I have not tested it. I have done a password change, but have not verified this actually did anything.
This option will cause the camera to display an authorization prompt, and once confirmed, you can type in a new WiFi password which the device will use.
I encourage ALL Insta360 camera owners to do this, as the default password is well documented and it allows anyone within WiFi range to access and download any photos/videos on the camera.
For a future project, I need to make use of remote triggers. These could be motion sensors, beam sensors, pressure mats, etc.
The ZigBee standard seems to be the way to go since I can find cheap consumer motion sensors that run on batteries. There also seems to be ZigBee repeaters, which allow giving the distance I need simply by plugging them in from place to place to create a mesh network.
XBee might be another option, if cheap motion sensors and repeaters are also available.
The goal is to have a central location be able to read the motion sensor status for many sensors, that could be spread out beyond walls hundreds of feet away.
Any pointers to where I might get started would be appreciated. Ideally I’d drive this all by a low-cost Arduino since the device will be used in an area where power might not be stable (and I wouldn’t want to corrupt the Linux file system on a Raspberry Pi).
Earlier this month, I received a message on my Sub-Etha Software Facebook page from author (and former/current CoCo programmer) Carl England:
I knew CHR$(13) was a carriage return, so this was creating a file name that contained carraige returns. What would that do?
I typed it in to find out…
How appropriate, because the first thing I said when i saw this code was “weird.”
Of course, now I have a file on my disk that would be hard to delete. Carl said just doing:
KILL A$
…would take care of it. Provided, of course, you did that after running the program, while A$ still existed. Otherwise you’d have to manually type that line again and replace the SAVE with KILL.
Fun.
Character 8 is a backspace, so I could sorta see what this was doing. “TEST” then four backspaces, then a period, then three more backspaces?
Well.
Also weird.
I could have had so much fun with this trick back when I was swapping disks with friends.