Showing posts with label Retro. Show all posts
Showing posts with label Retro. Show all posts

Sunday, June 2, 2024

BANKTEST for C64

While adding banking support to my own C64 emulator back in the good 'ole days (April 14, 2020, maybe only good for hunkering down on retro stuff), I also wrote a test program to help verify the results.  This may help you visualize how you can access more RAM and ROM on the C64.

The program works by switching to the RAM only bank writing a signature high byte to four addresses, then cycles through the standard list of banks reading the value at those locations.  Of course the first line for bank zero shows the bytes as expected.  But the other banks tell a different story.

A000-BFFF is BASIC ROM.   Appears ROM is active in banks 3 & 7 only, otherwise is RAM.

C000-CFFF is always RAM.

D000-DFFF is usually I/O (banks 5-7) including color RAM at D8000 (notice the high nibble changes in this run).  May also appear as RAM (banks 0 & 4), CHAR ROM (banks 1-3).

E000-FFFF is BASIC ROM (banks 2, 3, 6, 7), otherwise RAM (banks 0, 1, 4, 5).

It is interesting to see the similarities and differences in this chart.

The key code to switching banks includes

        sei

        lda $01

        and #$f8

        ora #bank_selection

        sta $01

        rts

Only clear the interrupt flag (cli instruction) once you have returned to the normal bank (7) so IRQ vectors and the KERNAL/BASIC ROMs will work as expected.

I have also color encoded the banks in this chart to represent their effects:

Links

Thursday, January 5, 2023

What is Cbmish?

 


Is this Commodore?

If it looks like a Commodore, acts like a Commodore, and feels like a Commodore, is it a Commodore?  Not always.  This cbmish is not a Commodore, and not made by Commodore Business Machines (CBM).  But it is like a Commodore, thus the "-ish" (means like).  

Cbmish is like a Commodore.  This web software solution provides the feel of a Commodore in a web browser.  There's a retro look and feel.  But with a more modern programming language.

READY.

But it says "READY."  Is that BASIC?  No, it is lying to you.  It is not ready for commands.  It won't PRINT or GOTO.  It is only ready for typing at this point.   You can navigate the screen with cursor keys and typing letters, numbers, punctuation, and other symbols.  You can change colors, type PETSCII, change to upper/lowercase, switch to reverse characters. It does feel like a Commodore.

Mouse

It also responds to mouse motion and clicks.  That's not a Commodore I ever owned.  Those rounded corners and text are buttons, and there are links too.  Clicking on a rounded button will present the user with a relevant sample screen, or navigate to another web page.  Colors may change, graphics may be drawn, text will display, and sprites may move.  

Why?

So why do this?  The about screen goes into some detail.  I'm ready to move on from BASIC (gasp!) and 6502 Assembly (gasp!) and I don't really want to program on my Commodore (gasp!), but I do want to continue the look and feel of Commodore.  My current efforts are web based and I have been using TypeScript from some years now.  My skill is mostly is C languages (C, C++, C#) and while I had shunned web development for sometime, my professional and hobby efforts have collided with doing full-stack development including C# and also TypeScript.

While interpreted languages aren't usually my thing (though I love me some AWK) I have seen features of JavaScirpt and functional programming influencing C#, and of course there are underpinnings of C in TypeScript too, and similar functional programming in JavaScript/TypeScript too.  While they are all quite distinct languages, there is enough familiarity between them, also also gotchas that keep them interesting when they are different.  It's fun to know multiple languages!

This is stuff you could do with your real Commodore, but it's done here using TypeScript written code.  TypeScript that is transpiled to JavaScript so it runs in the user's web browser.  A combination of HTML, CSS, and TypeScript results in code to provide the cbmish interfaces to present things like one of the favorite 80s retro systems.

You can code interactively using the browser developer tools, or you can launch Visual Code (or similar) with typescript compiler dependency to have code transpiled as soon as you save.  Instructions for both are on github in the README (see link below). 

10 PRINT "Hello ";: GOTO 10

So do you really want the equivalent of PRINT/GOTO? Well this will have to do, see immediate mode JavaScript entered into the console of the development tools of Google Chrome web browser.

PRINT/GOTO equivalent

Conclusion

So long story short, it's a fine time to do Commodore like programming on the web, in a modern language.  Take the best of modern languages and pair that with the look and feel of a great retro computer.   Are you keeping up with the Commodore?  Because cbmish is keeping up with the web.

Links

    open source (MIT License) at github.com
    live demo (try it now!)

Samples

mouse over button

Colors

petscii

chr$()s

Maze

Keyboard

lores

sine wave

dissolve

knight vs. dragon
sprite animation

about


Saturday, July 16, 2022

Extending C64 BASIC Part Three - Poke multiple bytes

This example accepts one address value, followed by multiple byte values appended to the SYS command on Commodore 64.  

This could be useful for POKEing to screen memory, sprite data, programmable character data, consecutive I/O registers, etc. efficiently in a single statement.









Thursday, July 14, 2022

Extending C64 BASIC Part Two - Parse 16-bit unsigned integer

This example parses a 16-bit unsigned integer appended to the SYS command on Commodore 64.  

The number is added to the jiffy clock as the alarm time, and a busy loop is entered waiting for the jiffy clock to advance to the alarm time.



Links:
ACME cross assembler (optional)
delay_jiffies.d64
open source (github)

Saturday, June 4, 2022

easymenu64 - directory and program launcher utility for C64

 

I originally wrote this somewhere between 1985 and 1987.  I submitted the program and an article to Compute! publications but was rejected, probably not unique or attractive enough of a submission.  Well, here it is for the public to see approximately 35 years later.  Not sure if I wrote this originally in assembler, or just machine code.  I suspect I used machine code for this one.  I have done a fair job now disassembling and crafting into assembler (using ACME cross assembler) for a more modern experience.

My typical use was to either see what was on the disk, or as a game launcher.  Imagine the possibility of many games packed on a 1581 disk.  It even supports launching cartridge images.

I have used it with 1541/1571/1581 but not sure if it works with fully populated large drives.  Seems to have trouble with some non-standard drives.  I plan to review that in the future.  (Update: some fixes have been applied to the original code starting with tagged version 1.1)

Keyboard and joystick(#2) controls are documented with the source README.

Links:
    open source
    easymenu.d64 (disk image)

Wednesday, May 25, 2022

Extending C64 BASIC Part One - Parse String

This example parses a string appended to the SYS command on Commodore 64





Links: 
reverse.d64 (updated 2022-05-29 to include source and example startup)
open source (github)

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)

Thursday, August 6, 2020

Commodore 64 BASIC CRUNCH Routine Commented

The disassembled code here is from
Commodore 64 ROM.

The comments and intermediate labels
are mine.

Together they are useful.

Placing this here as is for reference.
I found this exercise necessary when
implementing my hires extensions for C64
including a patch of this routine.

        ; C64 crunch is A57C-A612
        ; C64 tokens are A09E-A19D
crunch ; from C64 ROM
       ; INPUT: PETASCII of entered line is at buffer $0200, ending with #$00 null character
       ; OUTPUT: tokenizes in place entire line, ending line with #$00 null character
       ; HINT: because of tokens, result is smaller than original so can modify in place
         LDX $7A        ; source buffer index
         LDY #$04       ; storage index starts at 4 (4+$1FB+1 = $200)
         STY $0F        ; set not DATA flag (4=NOT, 0=DATA)
.go      LDA $0200,X    ; retrieve next character from input buffer
         BPL .lowch     ; branch if 00-7F
         CMP #$FF       ; PI?
         BEQ .store     ; branch if PI, already tokenized
         INX            ; advance source index
         BNE .go        ; always skip initial character 80-FE, as X shouldn't ever wrap to 0
.lowch   CMP #$20       ; compare to ASCII space
         BEQ .store     ; branch if space, store literal
         STA $08        ; no, store character, non-zero = not REMark
         CMP #$22       ; compare to ASCII quote
         BEQ .literal   ; branch if string, store literal characters instead of matchng tokens
         BIT $0F        ; test if in DATA statement
         BVS .store     ; branch if in DATA statement, store literal characters instead of matching tokens
         CMP #$3F       ; compare to ASCII question mark
         BNE .chkzero   ; no, skip next part
         LDA #$99       ; replace question mark with token PRINT
         BNE .store     ; unconditional branch, store token
.chkzero CMP #$30       ; compare to ASCII zero digit
         BCC .scantbl   ; branch if less
         CMP #$3C       ; compare to ASCII less than
         BCC .store     ; branch if less, so branch if numeric or colon or semi-colon, store literal character
.scantbl STY $71        ; save storage offset index
         LDY #$00       ; initialize token table byte index to zero
         STY $0B        ; initialize token number to zero
         DEY            ; cancel out the next increment for loop beginning with decrement
         STX $7A        ; save source index
         DEX            ; cancel out the next increment for loop beginning with decrement
.advance INY            ; advance token table index
         INX            ; advance source index
.scanch  LDA $0200,X    ; retrieve character from buffer
         SEC            ; prepare for subtraction
         SBC $A09E,Y    ; compare to Commodore token table
         BEQ .advance   ; branch if character match, look for more matches
         CMP #$80       ; end of token?
         BNE .scannxt   ; branch if not end of token, mismatch, so get ready to check next token
         ORA $0B        ; match! combine zero based token number with $80 high bit set for storage
.storaty LDY $71        ; retrive storage offset index
.store   INX            ; advance input index
         INY            ; advance output index
         STA $01FB,Y    ; store token or character
         LDA $01FB,Y    ; set Z flag if end of line
         BEQ .endline   ; branch if end of line, finish up
         SEC            ; prepare for subtraction
         SBC #$3A       ; subtract ASCII colon
         BEQ .setf      ; branch if colon
         CMP #$49       ; DATA?
         BNE .skipset   ; skip setting flag if not DATA
.setf    STA $0F        ; $49 if DATA, or $00 if colon
.skipset SEC            ; prepare for subtraction
         SBC #$55       ; REM?
         BNE .go        ; branch if not REM to get next character
         STA $08        ; store flag zero = REM
.litloop LDA $0200,X    ; retrieve next character from input
         BEQ .store     ; branch if end of line
         CMP $08        ; compare to token that got us in this loop (e.g. 0x22 quote), or 0x00 (REM)
         BEQ .store     ; branch if REMark end of line
.literal INY            ; advance destination index
         STA $01FB,Y    ; store in buffer
         INX            ; advance source index
         BNE .litloop   ; repeat getting next character
.scannxt LDX $7A        ; retrieve source index
         INC $0B        ; advance token number
.endtok  INY            ; advance destination index
         LDA $A09D,Y    ; retrieve character from token table
         BPL .endtok    ; loop until find end of token
         LDA $A09E,Y    ; retrieve next character from token table
         BNE .scanch    ; branch if not end of token table
         LDA $0200,X    ; re-retrieve character from input buffer
         BPL .storaty   ; branch if character 00-7F, should be if got here, no token match
.endline STA $01FD,Y    ; store end of line nul character $00
         DEC $7B        ; update TXTPTR
         LDA #$FF       ;  to point to
         STA $7A        ;  $01FF
crunch_finish:
         RTS            ; done

Monday, July 13, 2020

Commodore 64 running in web browser

Open full size window: c64emu.davevw.com

  • Coded in TypeScript(/JavaScript) with some HTML of course
  • Portable (got a web browser right?)
  • Keyboard driver works best with Firefox
  • Works on Mobile and TV too (click on screen for configuration, help)
  • F9 to toggle Help
  • Recommend use wired or bluetooth keyboard instead of onscreen keyboard
  • This is based on my earlier efforts (see previous posts)
I coded this as a learning experience with TypeScript.  Go ahead and try it out!

Included features:
6502 Emulation, machine code
 Commodore 64 Text Screen
 Commodore Fonts: Uppercase/Graphics, Lowercase/Uppercase
 Commodore Colors: Foreground, Background, Border
 Commodore BASIC v2 (Microsoft)
 64K RAM
 20K ROM
 Attach D64 image
 Load directory from D64
 Restart with PRG image
 JavaScript speedloader to bypass slow C64 disk access
 Save/Download PRG
 Great wired/wireless keyboard support
 Keyboard scan code support - press/release, multiple keys support, separate left/right Shift
 Standard to Commodore keyboard symbolic mapping, add/remove Shift
 Special key mappings: Stop, Home, Restore, F1-F8, Ctrl, Commodore
 Mobile/TV browser keyboard support (but minimal)
 Clipboard paste support
 IRQ 60 times per second
 NMI on Restore key
 Works best with Firefox

Missing features or limitations:
6502 undocumented instructions
 Accurate, regulated instruction timing
 6502 emulation battery drain (one thread always running 100%, no idle sleep)
 VIC-II register support
 Device register support
 Programmable timers
 Serial Port - User Port
 High Resolution 320x200 and 160x200 graphics
 Multi-color text mode
 Programmable characters
 Sprites
 Cartridges
 Joysticks, Paddles
 Printer
 Cassette Tape
 Save to D64
 SEQ, RND, etc. files
 LOAD PRG from running program
 Positional keyboard mapping
 On-screen keyboard
 Clipboard copy
 A few graphic character key strokes (punctuation keys) may not be mapped yet
 Known issues with Google Chrome

Sunday, April 12, 2020

Commodore 64 for STM32F429 Discovery board

So here is a Commodore 64 emulator I built for STM32F429 Discovery board:


Yeah, the LCD is tiny at 2.4", and the emulation runs about 15% slower than an NTSC C64.  But it's running on a small embedded board that's available for under $30 US (DigiKey, Mouser, ...) including mounted LCD display and USB OTG jack.  Just add keyboard, OTG USB adapter, and power supply.

This is a port of my portable C64/6502 emulator for terminal console, which was a port of my Commodore/6502 emulator for Windows Console.   But this time, I dropped the console part, and went for real video (LCD) and USB keyboard support.   Hello PETSCII!

Keyboard mapping (showing my Dell keyboard):
   STOP(ESC) F1 F2 F3 F4 F5 F6 F7 F8            Restore(PrtScr/SysRq) Run/Stop(Pause/Break)
             1! 2@ 3# 4$ 5% 6^ 7& 8* 9( 0) -_ += Del/Ins(Back)    Ins Hme/Clr     / * -
   Ctrl(Tab) Q  W  E  R  T  Y  U  I  O  P  [  ]  £ (\)            Del           7 8 9 +
             A  S  D  F  G  H  J  K  L  ;: '" Return(ENTER)                     4 5 6
   LShift    Z  X  C  V  B  N  M  ,< .> /?  RShift                     Up       1 2 3
   C=(Ctrl)           SPACEBAR              C=(Ctrl)              Lft Down Rt   0 .   Enter

Features:
  • 320x200 text screen on graphics LCD, with top/bottom border.
  • USB Keyboard (e.g. PC-103) support (symbolic, not positional)
    • Tab maps to C64 Ctrl key
    • Ctlr maps to C64 Commodore key
    • Esc key maps to C64 RUN/STOP key
    • PrtScr/SysRq maps to C64 RESTORE key (supports STOP+RESTORE)
    • PgUp also maps to C64 RESTORE key
  • Full 6502 emulation.  Go ahead, run some machine language on it.
  • Commodore character set
  • Text video at $0400 (address 1024)
  • Text color at $D800 (address 55296)
  • Keyboard scan by writing to $DC00, reading from $DC01
  • Full 64K RAM.  Update 2020-04-14: RAM/ROM/IO/Charset banking is implemented!  And 1K color nybbles
  • 1/60 second IRQ.  So we've got the software clock: TI, TI$
  • Upper/lower case switch ($D018), and reverse characters.
  • Border color ($D020) and background color ($D021).
Limitations:
  • Approximately 85% cpu speed of a real C64
  • No NMI.  No Restore key.  Update 2020-04-15: implemented, see keyboard above.
  • No other device support.  No tape, no disk, no serial, no cartridges, no joysticks, no printer.
  • VIC-II support is limited to getting system booted.
    • No full register support.
    • Text address can't be moved.
    • No graphics support.
    • No programmable characters.
    • No raster interrupts.
    • No sprites.
    • No left/right side border displayed.  Ran out of pixels.
  • No CIA1/CIA2 (except for keyboard data ports, but no data direction registers)
  • No SID.
  • In progress.  There are bugs lurking (for example, the IRQ and USB keyboard stops working exactly at 35 minutes, 38 seconds from start, maybe a resource leak in third party libraries, so we'll call that time limited I guess)
  • Keyboard support may need tweaks for more complete PETSCII key support
  • No CAPS LOCK or SHIFT LOCK supported
  • Doesn't utilize full capabilities of the STM32F429 MCU and discovery board components including 2.0MB of Flash (uses 110KB), 256KB of RAM (uses 83KB), 8MB SDRAM, motion sensor, user leds, user button, or other expansion capabilities.  Opportunity awaits!
Links:
Credit:  

Thursday, April 25, 2019

C64: Scrolling Editor for The Fast Assembler, 31 years late

Starting just today you can write Commodore 64 assembly language programs compiled for 6502 with The Fast Assembler and scroll up and down through them with just a touch of a function key. No more need to rely solely on the LIST keyword.  This tool has been available for BASIC programmers for quite a while.  But now it is also available for 6502 assembly language programmers too.






Key Description
F1 Scroll up
F3 Beginning of line
F5 End of line
F7 Scroll down
Ctrl+Down Bottom of screen
Ctrl+Ins Insert Line
Ctrl+Shift+Commodore Renumber lines
Ctrl+Return Toggle Scroll Edit Keys On/Off
Stop+Restore Restore screen and program (unnew)

I wrote the scrolling extension for The Fast Assembler way back in the summer of 1987 and submitted it to Compute! magazine for publishing.  Yet only my Scrolling BASIC Editor for Commodore 64 was published in their magazine and distributed on their floppy disk.  No one had seen the extension version since and the code has been sitting dormant in storage for a long time.

Yves Han wrote The Fast Assembler and it was published in January 1986 Compute!'s Gazette.  When I went about to write the original Scrolling BASIC Editor, I used The Fast Assembler to write the source code and assemble into machine code.  I felt this was the perfect tool for writing machine language programs, so I proceeded to integrate it into his solution as well.

Also added to The Fast Assembler with this extension are low byte < and high byte > operators similar to one or more assemblers of the era.

Fast forward over 31 years to today when writing this article, and I've got the retro hardware bug and retrieved the data from some of my old Commodore floppy disks using ZoomFloppy.   Add in a dash of Commodore emulators, archived magazines and disks, blogs, and electronic mail, and we've got new interest, and new means of self publishing and distributing information.  And I just recently changed my credits to my website URL (no we did not have those prior to 1990), otherwise no logic was changed in the last many decades.

Thanks to Tiaan Geldenhuys I saw this great blog post about The Fast Assembler.  Also thanks to email I was able to contact Yves Han, the author of The Fast Assembler.

Below are some resources.  Recommend you grab the floppy disk images instead of typing in the programs from the magazines.  The integrated version is available ready to use as FA+SCRLEDIT.



If you want to recreate from source you can because all source is available.  And/or if you wish to create the patched integration from compiled versions, instructions can be listed from  README.BASIC.


These are links:
• SCRLEDIT extension for The Fast Assembler C64 Disk Image (FA+SCRLEDIT) [1987, 2019]
• Compute's Gazette January 1988 Scrolling BASIC Editor Article
• Compute's Gazette January 1988 Floppy Disk Image (SCROLLEDIT) [BASIC]
• Compute's Gazette January 1986 Floppy Disk Image (ASSEMBLER) [original]