Git Product home page Git Product logo

x16-rom's Introduction

Commander X16 BASIC/KERNAL/DOS/GEOS ROM

This is the Commander X16 ROM containing BASIC, KERNAL, DOS and GEOS. BASIC and KERNAL are derived from the Commodore 64 versions. GEOS is derived from the C64/C128 version.

  • BASIC is fully compatible with Commodore BASIC V2, with some additions.
  • KERNAL
    • supports the complete $FF81+ API.
    • adds lots of new API, including joystick, mouse and bitmap graphics.
    • supports the same $0300-$0332 vectors as the C64.
    • does not support tape (device 1) or software RS-232 (device 2).
  • GEOS is fully compatible with the C64 version.
  • DOS
    • is compatible with Commodore DOS ($, SCRATCH, NEW, ...).
    • works on SD cards with FAT32 filesystems.
    • supports long filenames, timestamps.
    • supports partitions and subdirectories (CMD-style).
  • CodeX Interactive Assembly Environment
    • edit assembly code in RAM
    • save program, and debug information
    • run and debug assembly programs

Releases and Building

Travis (.org)

Each release of the X16 emulator includes a compatible build of rom.bin. If you wish to build this yourself (perhaps because you're also building the emulator) see below.

WARNING: The emulator will currently work only with a contemporary version of rom.bin; earlier or later versions are likely to fail.

Building the ROM

Building this source code requires only GNU Make, Python 3.7 (or higher) and the cc65 assembler. GNU Make is almost invariably available as a system package with any Linux distribution; cc65 less often so.

  • Red Hat/CentOS: sudo yum install make cc65
  • Debian/Ubuntu: sudo apt-get install make cc65

On macOS, cc65 in homebrew, which must be installed before issuing the following command:

  • macOS: brew install cc65

If cc65 is not available as a package on your system, you'll need to install or build/install it per the instructions below.

To check the version of python you have use python3 --version.

Once the prerequisites are available, type make to build rom.bin. To use that with the emulator, copy it to the same directory as the x16emu binary or use x16emu -rom .../path/to/rom.bin.

Additional Notes: For users of Red Hat Enterprise Linux 8, you will need to have CodeReady builder repositories enabled, for CentOS, this is called PowerTools. Additionally, you will need Fedora EPEL installed as well as cc65 does not come usually within the official repositories.

Building/Installing cc65

Linux Builds from Source

You'll need the basic set of tools for building C programs:

  • Debian/Ubuntu: sudo apt-get install build-essential git

The cc65 source is on GitHub; clone and build it with:

git clone https://github.com/cc65/cc65.git
make -j4    # -j4 may be left off; it merely speeds the build

This will leave the binaries in the bin/ subdirectory; you may use thes directly by adding them to your path, or install them to a standard directory:

#   This assumes you have ~/.local/bin in your path.
make install PREFIX=~/.local

Building and Packages for Other Systems

Consult the Nesdev Wiki Installing CC65 page for some hints, including Windows installs. However, the Debian packages they suggest from trikaliotis.net appear to have signature errors.

Credits

See LICENSE.md

Release Notes

Release 41 ("Marrakech")

  • KERNAL
    • keyboard
      • added 16 more keyboard layouts (28 total)
      • default layout ("ABC/X16") is now based on Macintosh "ABC - Extended" (full ISO-8859-15, no dead keys)
      • "keymap" API to activate a built-in keyboard layout
      • custom keyboard layouts can be loaded from disk (to $0:$A000)
      • Caps key behaves as expected
      • support for Shift+AltGr combinations
      • support for dead keys (e.g. ^ + e = ê)
      • PgUp/PgDown, End, Menu and Del generate PETSCII codes
      • Numpad support
      • Shift+Alt toggles between charsets (like C64)
      • Editor: "End" will position cursor on last line
    • VERA source/target support for memory_fill, memory_copy, memory_crc, memory_decompress [with PG Lewis]
    • fixed headerless load for verify/VRAM cases [Mike Ketchen]
    • don't reset screen colors on mode switch
  • BASIC:
    • BLOAD, BVLOAD and BVERIFY commands for header-less loading [ZeroByteOrg]
    • KEYMAP command to change keyboard layout
    • support DOS8..DOS31 (and A=9:DOSA etc.) to switch default device
    • MOUSE and SCREEN accept -1 as argument (was: $FF)
    • Changed auto-boot filename from AUTOBOOT.X16* to AUTOBOOT.X16
  • Monitor:
    • fixed RMB/SMB disassembly
  • Charset:
    • X16 logo included in ISO charset, code $AD, Shift+Alt+k in ISO mode

Release 40 ("Bonn")

  • KERNAL
    • Features
      • NMI & BRK will enter monitor
      • added ':' to some F-key replacements
      • allow scrolling screen DOWN: PRINTCHR$($13)CHR$($91)
      • Serial Bus works on hardware
    • Bugs
      • fixed SA during LOAD
      • fixed joystick routine messing with PS/2 keyboard [Natt Akuma]
    • API
      • keyhandler vector ($032E/$032F) doesn't need to return Z
      • PLOT API will clear cursor
  • BASIC * on RESET, runs PRG starting with "AUTOBOOT.X16" from device 8 (N.B.: on host fs, name it "AUTOBOOT.X16*" for now!) * BOOT statement with the same function
  • DOS
    • better detection of volume label
    • fixed $=P (list partitions), $*=P/D (dir filtering), hidden files
  • MONITOR
    • fixed F3/F5 and CSR UP/DOWN auto-scrolling
    • fixed LOAD, SAVE, @
  • CodeX
    • works this time! [mjallison42]

Release 39 ("Buenos Aires")

  • KERNAL
    • Adaptation to match Proto 2 Hardware
      • support for 4 SNES controllers
      • 512 KB ROM instead of 128 KB
      • new I/O layout
      • PS/2 and SNES controller GPIOs layout
      • banking through $00 and $01
    • Proto 2 Hardware Features
      • I2C bus (driver by Dieter Hauer, 2-clause BSD)
      • SMC: reset and shutdown support
      • RTC: DA$/TI$ and KERNAL APIs bridge to real-time-clock
    • Screen Features
      • New screen_mode API allows setting and getting current mode and resolution
      • support for 320x240 framebuffer (mode $80/128) [with gaekwad]
      • added 80x30,40x60,40x30,40x15,20x30,20x15 text modes (note new numbers!)
    • Keyboard Features
      • added KERNAL vector to allow intercepting PS/2 codes [Stefan B Jakobsson]
      • added kbdbuf_peek, kbdbuf_get_modifiers, kbdbuf_put API
    • Other Features
      • support for LOADing files without 2-byte PRG header [Elektron72]
      • support for LOAD into banked RAM (acptr and macptr)
      • support BEL code (PRINT CHR$(7))
      • keyboard joystick (joystick 0) supports all SNES buttons
      • support for 4 SNES controllers (joystick 1-4) [John J Bliss]
    • Bugs
      • fixed crash in FB_set_pixels for count>255 [Irmen de Jong]
      • fixed bank switching macros [Stephen Horn]
      • fixed preserving P in JSRFAR [CasaDeRobison]
      • fixed race condition in joystick_get [Elektron72]
      • removed ROM banking limitations from JSRFAR and FETVEC [Elektron72, Stefan B Jakobsson]
      • fixed disabling graphics layer when returning to text mode [Jaxartes]
      • fixed default cursor color when switching to text mode
      • reliable mouse_config support for screen sizes
  • Math
    • renamed "fplib" to "math"
    • made Math package compatible with C128/C65, but fixing FADDT, FMULTT, FDIVT, FPWRT
  • BASIC
    • Features
      • added BIN$ & HEX$ functions [Jimmy Dansbo]
      • added LOCATE statement
    • Bugs/Optimizations
      • removed extra space from BASIC error messages [Elektron72]
      • fixed DA$ and TI$ when accessed together or with BIN$()/HEX$() [Jaxartes]
      • fixed null handling in GET/READ/INPUT [Jaxartes]
      • fixed bank setting in VPOKE and VPEEK [Jaxartes]
      • fixed optional 'color' argument parsing for LINE, FRAME, RECT
  • DOS
    • reliable memory initialization
    • fixed writing LFN directory entries across sector boundary
    • fixed missing partitions ($=P) if type is $0B
    • fixed loading to the passed-in address when SA is 0 [gaekwad]
    • fixed problem where macptr would always return C=0, masking errors
  • GEOS
    • text input support
  • CodeX
    • integrated CodeX Interactive Assembly Environment into ROM [mjallison42]

Release 38 ("Kyoto")

  • KERNAL
    • new macptr API to receive multiple bytes from an IEEE device
    • load uses macptr for LOAD speeds from SD card of about 140 KB/sec
    • hacked (non-functional) Commodore Serial to not hang
    • LOAD on IEEE without fn defaults to ":*"; changed F5 key to "LOAD"
    • fixed screen_set_charset custom charset [Rebecca G. Bettencourt]
    • fixed stash to preserve A
    • entropy_get: better entropy
  • MATH
    • optimized addition, multiplication and SQR [Michael Jørgensen]
    • ported over INT(.9+.1) = 0 fix from C128
  • BASIC
    • updated power-on logo to match the real X16 logo better
    • like LOAD/SAVE, OPEN now also defaults to last IEEE device (or 8)
    • fixed STOP key when showing directory listing (DOS"$")
  • CHARSET
    • changed PETSCII screen codes $65/$67 to PET 1/8th blocks
  • DOS
    • switched to FAT32 library by Frank van den Hoef
    • rewrote most of DOS ("CMDR-DOS"), almost CMD FD/HD feature parity
      • write support
      • new "modify" mode ("M") that allows reading and writing
      • set-position support in PRG files (like sd2iec)
      • long filenames, full ISO-8859-15 translation
      • wildcards
      • subdirectories
      • partitions
      • timestamps
      • overwriting ("@:")
      • directory listing filter
      • partition listing
      • almost complete set of commands ("scratch", "rename", ...)
      • formatting a new filesystem ("new")
      • activity/error LED
      • detection of SD card presence, fallback to Commodore Serial
      • support for switching SD cards
      • details in the CMDR-DOS README
    • misc fixes [Mike Ketchen]

Release 37 ("Geneva")

  • API features
    • console
      • new: console_put_image (inline images)
      • new: console_set_paging_message (to pause after a full screen)
      • now respects window insets
      • try "TEST1" and "TEST2" in BASIC!
    • new entropy_get API to get randomness, used by MATH/BASIC RND function
  • KERNAL
    • support for VERA 0.9 register layout (Frank van den Hoef)
  • BASIC
    • TI$ and DA$ (DATE$) are now connected to the new date/time API
    • TI is independent of TI$ and can be assigned
  • DOS
    • enabled partition types 0x0b and 0x0c, should accept more image types
  • Build
    • separated KERNAL code into core code and drivers
    • support for building KERNAL for C64
    • ROM banks are built independently
    • support to replace CBM channel and editor code with GPLed "open-roms" code by the MEGA65 project
  • bug fixes
    • LOAD respects target address
    • FAT32 code no longer overwrites RAM
    • monitor is not as broken any more

Release 36 ("Berlin")

  • API Features

    • added console API for text-based interfaces with proportional font and styles support: console_init, console_put_char, console_get_char
    • added memory API:
      • memory_fill
      • memory_copy
      • memory_crc
      • memory_decompress (LZSA2)
    • added sprite API: sprite_set_image, sprite_set_position
    • renamed GRAPH_LL to FB (framebuffer)
    • GRAPH_init takes an FB graphics driver as an argument
  • KERNAL features

    • detect SD card on TALK and LISTEN, properly fall back to serial
    • joystick scanning is done automatically in VBLANK IRQ; no need to call it manually any more
    • added VERA UART driver (device 2)
    • bank 1 is now the default after startup; KERNAL won't touch it
    • sprites and layer 0 are cleared on RESET
    • changed F5 to LOAD":* (filename required for IEEE devices)
    • GRAPH_move_rect supports overlapping [gaekwad]
  • BASIC

    • default LOAD/SAVE device is now 8
    • added RESET statement [Ingo Hinterding]
    • added CLS statement [Ingo Hinterding]
  • CHARSET

    • fixed capital Ö [Ingo Hinterding]
    • Changed Û, î, ã to be more consistent [Ingo Hinterding]
  • bug fixes

    • COLOR statement with two arguments
    • PEEK for ROM addresses
    • keyboard code no longer changes RAM bank
    • fixed clock update
    • fixed side effects of Ctrl+A and color control codes [codewar65]
  • misc

    • added 3 more tests, start with "TEST1"/"TEST2"/"TEST3" in BASIC:
    • TEST0: existing misc graphics test
    • TEST1: console text rendering, character wrapping
    • TEST2: console text rendering, word wrapping
    • TEST3: console text input, echo

Release 35

  • API Fetures

    • new KERNAL API: low-level and high-level 320x200@256c bitmap graphics
    • new KERNAL API: get mouse state
    • new KERNAL API: get joystick state
    • new KERNAL API: get/set date and time (old RDTIM call is now a 24 bit timer)
    • new floating point API, jump table at $FC00 on ROM bank 4 (BASIC)
  • KERNAL Features

    • invert fg/bg color control code (Ctrl+A) [Daniel Mecklenburg Jr]
  • BASIC

    • added COLOR <fg, bg> statement to set text color
    • added JOY(n) function (arg 1 for joy1, arg 2 for joy2)
    • added TEST statement to start graphics API unit test
    • CHAR statement supports PETSCII control codes (instead of GEOS control codes), including color codes
  • misc

    • KERNAL variables for keyboard/mouse/clock drivers were moved from $0200-$02FF to RAM bank #0
    • $8F (set PETSCII-UC even if ISO) printed first after reset [Mikael O. Bonnier]
  • bug fixes:

    • got rid of $2c partial instruction skip [Joshua Scholar]
    • fixed TI/TI$
    • fixed CBDOS infinite loop
    • zp address 0 is no longer overwritten by mouse code
    • mouse scanning is disabled if mouse is off
    • VERA state is correctly saved/restored by IRQ code

Release 34

  • new layout for zero page and KERNAL/BASIC variables:
    • $00-$7F available to the user
    • ($02-$52 are used if using BASIC graphics commands)
    • $80-$A3 used by KERNAL and DOS
    • $A4-$A8 reserved for KERNAL/DOS/BASIC
    • $A9-$FF used by BASIC
  • new BASIC statements:
    • SCREEN <mode> (0: 40x30, 2: 80x60, 128: graphics)
    • PSET <x>, <y>, <color>
    • LINE <x1>, <y1>, <x2>, <y2>, <color>
    • FRAME <x1>, <y1>, <x2>, <y2>, <color>
    • RECT <x1>, <y1>, <x2>, <y2>, <color>
    • CHAR <x>, <y>, <color>, <string>
    • MOUSE <n> (0: off, 1: on)
  • new BASIC functions:
    • MX (mouse X coordinate)
    • MY (mouse Y coordinate)
    • MB (mouse button; 1: left, 2: right, 4: third)
  • new KERNAL calls:
    • MOUSE: configure mouse
    • SCRMOD: set screen mode
  • new PS/2 mouse driver
  • charsets are uploaded to VERA on demand
  • GEOS font rendering uses less slant for faux italics characters
  • misc GEOS KERNAL improvements and optimizations

Release 33

  • BASIC
    • additional LOAD syntax to load to a specific address LOAD [filename[,device[,bank,address]]]
    • LOAD into banked RAM will auto-wrap into successive banks
    • LOAD allows trailing garbage; great to just type LOAD into a directory line [John-Paul Gignac]
    • new BASIC statement: VLOAD to load into video RAM: VLOAD [filename[,device[,bank,address]]] [John-Paul Gignac]
    • complete jump table bridge
  • KERNAL: memory size detection
  • KERNAL: faster IRQ entry
  • GEOS: converted graphics library to VERA 320x200@256c

Release 32

  • correct ROM banking:
    • BASIC and KERNAL now live on separate 16 KB banks ($C000-$FFFF)
    • BASIC PEEK will always access KERNAL ROM
    • BASIC SYS will have BASIC ROM enabled
  • added GEOS
  • added OLD statement to recover deleted BASIC program after NEW or RESET
  • removed software RS-232, will be replaced by VERA UART later
  • Full ISO mode support in Monitor

Release 31

  • switched to VERA 0.8 register layout; character ROM is uploaded on startup
  • ISO mode: ISO-8859-15 character set, standard ASCII keyboard
  • keyboard
    • completed US and UK keymaps so all C64 characters are reachable
    • support for AltGr
    • support for F9-F12
  • allow hex and binary numbers in DATA statements [Frank Buss]
  • switched SD card from VIA SPI to VERA SPI (works on real hardware!)
  • fix: VPEEK overwriting POKER ($14/$15)
  • fix: STOP sometimes not registering in BASIC programs

Release 30

  • support for 13 keyboard layouts; cycle through them using F9
  • GETJOY call will fall back to keyboard (cursor/Ctrl/Alt/Space/Return), see Programmer's Reference Guide on how to use it
  • startup message now shows ROM revision
  • $FF80 contains the prerelease revision (negated)
  • the 60 Hz IRQ is now generated by VERA VSYNC
  • fix: VPEEK tokenization
  • fix: CBDOS was not correctly preserving the RAM bank
  • fix: KERNAL no longer uses zero page $FC-$FE

x16-rom's People

Contributors

akumanatt avatar bobbyjim avatar differentprogramming avatar elektron72 avatar esshahn avatar frank-buss avatar fvdhoef avatar gaekwad avatar indigodarkwolf avatar jaxartes avatar jburks avatar jeriesar94 avatar jimmydansbo avatar jjbliss avatar jjgignac avatar lrflew avatar maxgerhardt avatar mist64 avatar mjallison42 avatar mjoergen avatar mobluse avatar pglewis avatar rebeccargb avatar stefan-b-jakobsson avatar stefanoborini avatar theelkmechanic avatar tobier avatar yazwh0 avatar zakero avatar zerobyteorg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

x16-rom's Issues

Feature Request: Kernel & Basic zero page usage "staying in their lanes"

I was just warned that zero page location $02, one of the "free" zero page locations I was using in my C64 port of Camel Forth for Z80, is now taken over in the CX16 for keydown/keyup detection.

While there is a lot of zero page locations that may be used if Basic is not used, making machine language routines that can be using SYS calls is trickier. It is even trickier for a general purpose programming language which intended to reserve a small area at the lower end of Basic program space for small utility Basic programs as a shell programming language for file operations, if I do not know in advance what the SYS routine may be doing. Starting from the C64 Basic and Kernel memory maps, the CX16 should be adding two free spaces at $00/$01, making the free space in $02 particularly appealing for a doubly indirect jump vector, with $6C in $00 and the address vector in $01/$02.

But over and above that, in the C64 system, the KERNAL generally sticks to $90 to $FA and Basic sticks to $03 to $8F plus $FF. If Kernel functions are going to start to randomly use what were previously Basic locations, then the strategy of USING the zero page below $90 for assembly language programs which do NOT plan to inter-operate with Basic goes out the window.

Dropping the Datasette port should open up many or all of:
; ~ $92 Cassette timing constant
; ~ $96 Cassette block synchronization number
; ~ $9B/$9C Cassette parity byte / tape byte received flag
; ~ $9E/$9F Cassette read pass 1&2 error logs
; ~ $A5/$A6 Cassette sync byte counter / #chars in I/O buffer
; ~ $B0/$B1 Pointer to timer for cassette reads
; ~ $B2/$B3 Pointer to start of cassette buffer
; ~ $BE/$BF Cassette R/W duplicate block counter / ready byte register
; ~ $C0 Cassette motor On/Off flag

... if any of those are indeed not used by anything but Datasette support and have not yet been claimed by other Kernel functions, they should be the place to start allocating Kernel zero page locations.

Beyond that, there are a number of Kernel locations that are primarily IN the zero page to save a byte or two in the Kernel to squeeze it into 8K, but are not required for indirect address modes and are not used inside inner loops, and so do not in reality need to be in the zero page at all.

Indeed, Key Up/Down is an example of that: if the Kernel has already used up all of the locations available in $90 to $FA, then it is time to use Page 2 and 3 more heavily for things that are not priorities to place in the zero page ... and if/when those are used up, to go past the keycode table in Page 4 and grab page 5 for those general Kernel operations memory locations.

[Feature Request] Expose BASIC float functions in Kernal API

I was experimenting with porting a slow BASIC demo to C (using cc65 to compile), and realized there is no direct floating point support. The rom already includes a number of floating point processing functions as part of the BASIC interpreter (yes, it's not IEEE floats (at least on the C64), but it's functionally similar) that would be extremely useful to be able to rely upon in ASM and C code. Apparently some Commodore 64 programs did this by referring to the exact offsets of functions in the ROM, but doing this for the X16 would be incredibly unstable as the rom is still being developed. It would be really nice if the existing (and stable) Kernal API could be extended to allow access to the floating point operations found in the BASIC code. It doesn't necessarily have to be individual API addresses for each floating point instruction; it could require some extra indirection to use and still work fine. It would just be extremely convenient to have this already existing code accessible when developing programs.

Request support for Basic program line renumbering

I recommend adding a line renumbering program to the BASIC code. I suggest to implement using the syntax used on mBASIC, see attachment. This allows development and maintenance of a basic code while help maintaining the code structured (e.g. the line number 1000s to be used for I/O, etc).

During the renumbering process the line numbers referenced in GOTO and GOSUB statements should automatically be updated as well (e.g. if line number 34 is renumbered to 100 then "GOTO 34" should be updated to "GOTO 100"). This includes line numbers in implicit GOTO statements such as "IF A=1 THEN 55".
10D02A7D-D9E8-440D-893B-FA88584B412D

Feature Reques: EXIT DO LOOP DONE ELSE

(Edit: I had forgotten all of my V7 Basic: this has been converted to V7 syntax)

CBM V2 Basic FOR/NEXT has a problem. It allows early exit from a FOR/NEXT loop via GOTO, but there is no clean way to clean up the structure stack. There are various patches to this problem ... discarded loops are dropped from the stack if their loop variable is re-used, and if the FOR of an outer loop with an explicit variable is executed, any inner loops remaining on the stack are discarded. But too many early exits from FOR/NEXT loops can still lead to an OUT OF MEMORY error.

This is a particular issue because CBM V2 Basic does not have any effective error handling constructs, and many early departures from FOR/NEXT loops are as a result of programmed attempts to respond to an error. If the loop is restarted, the stack gets cleaned up, but in many cases it does not.

However, with one extension to a subset of the C128 V7 syntax, DO/EXIT/DONE addresses this flaw.

This version of DO does not put a single pointer onto the structure stack: it puts a FOR/NEXT structure entry on the stack with a nul variable. Whether this is null length or a name that cannot be entered in BASIC -- like (in C vernacular) "\0\0" -- depends on which works best with the existing codebase. This enables the proper operation of DONE.

DONE is the new token (which means it is $FE+$xx, as single byte tokens appear to be exhausted), which removes the topmost DO structure entry from the stack, or clears the stack if there are none. As a result of clearing the top anonymous variable structure, it also clears up any structure entries left on the stack by any unterminated FOR/NEXT loops residing between DO and DONE.

EXIT, which is an existing part of V7 DO/LOOP syntax, scans ahead for the DONE and jumps to it. It has a blockcount that starts set at 1, is incremented with each DO that it encounters, and decremented with each DONE it encounters, and it executes the jump when the blockcount reaches 0 (or jumps to the end of the program if the end of the program is encountered first). If DO/DONE surround a set of FOR/NEXT loops, this ensures that an EXIT from inside one of those loops will go to a determined location and the structure stack cleaned up. Setting an error variable to zero at the start of the DO / DONE and then setting it to an error value before executing an LEAVE due to an error will allow a test for whether error recovery is required.

Including the V7 LOOP converts this to a conditional loop. EXIT searches for the set of DO, LOOP and DONE, decrementing the block count for either LOOP or DONE. When the block count is 0, it executes the action of DONE to clear the structure stack and then jumps to the expression following whichever terminating token it encountered. When LOOP is executed, it uses the address data in the structure stack item left by DO to jump to the location immediately after DO.

Without the full V7 DO/LOOP at the ROM Basic level, conditional loops may be constructed by IF/THEN in combination with EXIT. Note that a variety of traditional Basic loop conditional constructs can be constructed out of DO/EXIT/LOOP, and because the LOOP is doing a direct jump to the DO location based on the structure stack information, it is more efficient than doing so with IF/THEN and GOTO:

"While/Wend" loop:
10 DO IF cond THEN 30
20 EXIT
30 ...
...
100 LOOP

"Repeat/Until" loop:
10 DO ...
...
90 IF cond THEN EXIT
100 LOOP

Finally, DO/LEAVE/DONE can support the equivalent of multi-line IF/THEN blocks. Note that this is NOT it's INTENDED purpose, and if additional codespace were to be allocated to extending IF THEN and ELSE to work with BEGIN and BEND, I will happily use it. However, as a side effect of the above, there is a workable (if clunky{+}) construction available:
200 DO IF X>100 THEN 220
210 EXIT
220 ...
...
300 DONE

Adding ELSE to IF/THEN is useful, though it requires extension of the current THEN routine, The simplest approach is to write a new THEN routine that, as in the V7 ELSE, scans any additional statement in the line for a leading ELSE, and if it reaches the next line, starts execution at the next line.

This also improves the "while/wend" equivalent loop above. "While/Wend" loop v2, with ELSE:
10 DO IF cond THEN 20: ELSE EXIT
20 ...
...
100 LOOP

While this approach is simple, with the extension of IF/ELSE/THEN to work with BEGIN/BEND, it does not allow properly nested IF (IF THEN ELSE) THEN (IF THEN ELSE) ELSE (IF THEN ELSE) constructs. However, it does allow multi-line blocks to be constructed using DO/EXIT/DONE, which can then be nested:

200 DO IF X>100 THEN 210 :ELSE 260
210 ... (then code)
250 EXIT
260 ... (else code)
...
300 DONE

This is certainly awkward{*}, but it supports nested conditional multi-line code without requiring additional keyword routines to be written and tested, and allows the Screen Editor Basic to offer nested block IF statements without requiring any further additional keyword support in Basic2.

{* Hat tip Schlowski at Murray2.com}

Find a mapping from remaining PS/2 keys (e.g. PGDN/PGUP/END/...) to PETSCII control codes

We have already mapped lots of the PS/2 keys to their equivalents in PETSCII codes (Break = RUN/STOP, Home = HOME etc.) and added a few control codes from the C128 and the C65 (ESC, TAB, F9-F12).

But there are some more keys on a PS/2 keyboard that don't have a direct PETSCII control code equivalent for yet:

  • PrtScrn
  • Scroll Lock
  • Pause/Break
  • Delete
  • End
  • Page Up, Page Down

It would be best to map them to keys found on other Commodore 8 bit computers, if it makes sense.

The C128 has the following extra keys (compared to the C64):

  • HELP
  • LINE FEED
  • 40/80 DISPLAY
  • NO SCROLL

The C65 has the following extra keys:

  • NO SCROLL
  • F13-F14
  • HELP

The overlap of these two (that is, the more important, more canonical keys):

  • NO SCROLL
  • HELP

->

  • Scroll Lock and NO SCROLL sound like a natural match.
  • For all others, we need to think about it more. :)

Optimizations for floating point arithmetic

I have a number of ideas for optimizing the floating point arithmetic routines in the BASIC code.

For now I've forked this project and added the file xadd.s, which contains an optimized version of the floating point addition. Additionally, I've added the file test/add.bas to do some rudimentary testing.

Benchmarking is difficult, because the execution time depends on the operand values. One data-point is the simple loop "FOR I=1 TO 10000; NEXT I", which now executes in 109 jiffies, as opposed to 116 jiffies in the original ROM. This corresponds to reducing each addition by - on average - 120 clock cycles.

I have (untested) ideas for optimization multiplication too, but I'm unsure how to proceed from here.

jsrfar can't be nested

Since jsrfar uses the zero page location savbank, nested invocations will break because they overwrite the saved bank.

BASIC: Banked memory PEEK and POKE, Block IO, Block Transfer

BASIC 2 does not have any commands or functions to enable block transfer of data from storage or within memory on the computer. With the addition of VERA and the banked upper memory space, I believe some block transfer commands are necessary to make BASIC more capable of handling large amounts of data. Because of the overhead involved, PEEK and POKE loops just take too long to populate display memory or load binary data from disk.

I'm proposing some block data transfer commands specifically targeted at moving data in and out of banked memory, as well as reading binary data from disk. This could be used for animation frames, sprites, structured data (ie: map data in RPGs).

This is one suggested method of dealing with the issue, although there may be other ways of accomplishing the same task.

I have also suggested two utility routines to make data manipulation easier and to assist using main memory to store assembly routines or raw data.

I'm happy to provide use cases and ideas separately. This description is already pretty long.

New keywords requested:
BANK, IPEEK, IPOKE, FPEEK, FPOKE, SPEEK$, SPOKE, COPY, VCOPY, VARPTR()

Keywords to modify with new parameters:
SAVE (add bank, start address, length), GET#

Keywords with changed behavior:
SYS, WAIT, USR

BANK bankno
Set the bank number for BASIC PEEK and POKE operations. Any BASIC operations that happen within banked memory will cause bankno to increment internally when the internal pointer used for block moves hits $BFFF. Transfer the byte at $BFFF, then set the pointer to $A000 and increment bankno.

COPY fromaddr, toaddr, len
VCOPY fromaddr, tobank, toaddr, len

Block copy data.
VCOPY copies data to VERA.
When fromaddr or toaddr is a location inside of the 8K banked memory region, wrap to the next bank.

PEEK$(address, [len])

Read from memory (PEEK$). This allows for printing portions of a larger data set. For example, room descriptions in a text adventure or fields in a database. Bank wrapping should occur as needed. The intended use is PRINT PEEK$(.,..) to print text from memory, although it could be useful in LET statements, too, if the data has to be manipulated before printing.

If len is supplied, the first byte read is the first byte of the string. If len is not supplied, the first byte is the length of the string. Max string length is 255 bytes.

IPEEK/IPOKE
FPEEK/FPOKE

Read or set 16-bit integer (I) or 40-bit float (F) values in memory. Syntax would be the same as PEEK/POKE, but take or return integer or float values.

Unlike POKE, which converts the value to an 8-bit byte, this should copy the raw binary encoding of a value. So IPOKE writes a 16-bit, unsigned integer. FPOKE writes a 40-bit real number.

GET# buffer, len

Read len bytes from IO into a string variable. Zero bytes should populate the string (currently, BASIC 2 creates a zero-length string when reading a zero byte. This is a flawed implementation.)

SAVE filespec, [bank, address[, len]]

Save binary data to disk.

This saves a file, including the starting address with a two byte address pointer.

Like LOAD (which now has bank,address parameters), SAVE should start reading from the bank:address location in RAM and continue for len bytes. If the read pointer reaches $C000, advance the bank number and wrap to $A000. (Data should be read from $A000-BFFF inclusive.)

VARPTR()

Returns the address of a variable in RAM. This isn't strictly a block operation, but it's an oversight in BASIC 2 that was corrected in later versions of Microsoft BASIC. This is necessary to allow manipulation of binary data.

SYS
Sys should honor the selected BANK number(s). It would be useful to add A, X, and Y parameters if they are supplied.
Example: BANK $10:SYS $A000,$12,$34,$56
Calls a routine at $A000 in bank $10, inserting the values $12 into A, $34 into X, and $56 into Y. Values not supplied or left empty should be ignored or set to zero. (I don't think it matters which, as long as the behavior is consistent.)

WAIT
Wait does not need any new syntax, but it should honor the selected BANK number(s).

USR()
USR() does not need new syntax, but the pointer should be extended to 3 bytes. The first two bytes should be the 16-bit address, and the last byte should be the bank number.

Keyboard localization

This is the tables mode1/2/3 in editor3.s .It looks (to moi) like a scancode to internal codes mapping.

Options include:

  1. Different kernal ROMs for different folks. Easy enough to do. Rip the tables out, have them script generated from a source file (bit like the 65C02 changes) with override files for country locales, build a set of ROMs. Downside. You have lots of ROMs. Lots of potential flashing issues with the hardware if everyone non US flashes the ROM first to get their locale.

  2. Multiple tables. Looks like a set is 192 characters. Even if we don't do mode3 table, that's 128 bytes of ROM space we don't have. And there are a lot of layouts. This is a non-starter.

  3. One table with patch lists for locales. Easier on memory, but still has the same problem. I'm inclined not to waste ROM memory. Probably would end up being limited to a set of larger markets.

  4. Run from RAM. Copy it to unused space (screen RAM) and run it from there.

This might be doable in two stages. Firstly implement it purely in the emulator, so reset copies the table into RAM and mode1/mode2/mode3 are changed to point to it, so it works exactly as before.

Have a -scancode switch in the emulator that loads in a file (say) keymap.txt which specifies overrides to that table ; and also dumps scancodes to stdout when they are pressed in the emulator. Then locale people can produce specific keymap.txt files for overrides.

Then have a script which converts keymap.txt into a .PRG file which can be run on boot. The KERNAL would copy the RAM and keymap.txt could be loaded manually or automatically from local storage and run, which would update the RAM table until reset.

Downsides : we lose the RAM (3/4k) and its not permanent (but then the Flash option could be possible as well .... change the defaults)

Idea/wish: "ROM directory"

Just an idea ... As X16 seems to have more ROM pages in a 8K window, it can be expected that there can be custom ROM contents as well in the future, and also more and more stuffs in the "official ROM pack" as well.

Some 8 bit machines (I can mention the Z80 based Enterprise-128, but I guess Acorn systems as well - I am not sure about the second, but for example to stay with Commodore, the very rare Commodore LCD too ... though C-LCD has it as a menu, but this is not my point here for sure) there is way to list ROMs, also to use them easily, if there is an entry point for that.

My idea is to put some identifier string into ROMs which marks some kind of "ROM directory" with one or more entry points listed (a ROM can have multiple entries as well), with some short name to easy to refer them. So then, there can be even a BASIC token allocated to use a search+list routine to list those for the user without an argument, or with an argument, to give the control to that functionality.

In this way, some can have eg a menu based program loader, which can be quickly call that, without the need to first load it from disk. And maybe other usages as well, it would be nice.

The alternative of course, to know your system and use various SYS commands with the right parameter :) [I'm not sure if there is SYS btw, for paged ROM to also select which ROM "page" should be used to utilize the jump there - which would page out BASIC ...].

NuPET ASCII

[Tom Wilson]
https://www.facebook.com/groups/CommanderX16/permalink/519788175438948/?comment_id=521425405275225

I have a suggestion.... and this will seem radical at first.

Change the PETSCII character order so that it's the same as ISO/ASCII mode. Get rid of upper case/graphics mode, and use the upper 128 character slots in PETSCII to hold the graphics characters.

After removing the redundant characters, there's a ton of unused space in the PETSCII character set, and with per-character background colors, we don't need most of the reversed characters. The only ones that should be retained are the line drawing characters.

This character set unifies ASCII and PETSCII, includes all of the PETSCII graphics, adds some missing characters (right and down arrow, the rest of the half-shaded box graphics, and some other tidbits) and SIMPLIFIES the entire system by unifying the PETSCII, screen code, and ASCII character order.

Doing this means ISO mode is also easier to implement, because there's no need for separate text handling for ISO and PETSCII mode. The only thing you'd need to handle separately are the characters with diacritical marks.

Since our keyboards have Alt and logo keys, we could still use keyboards to enter PETSCII symbols. The left glyph with the logo key and the right glyph with the ALT key. The extra glyphs not part of the current PETSCII system would be entered with alt+logo, or maybe an OSD.

https://docs.google.com/document/d/1iM6CZ1iWbCIN6-MT4zBlplvSJhmm_rKxE6b-7XCvzds/edit?fbclid=IwAR1uEEWdehmOYNAyTJ3umKudThMl3_QuA8gkne_R9917NI9h95u-3L81sAM#heading=h.d3ddoz790a0h

Question: how to know what mem is avail, is free ?

We have the main memory and we have the banks memory. How will we be able to know what's available ? If we want to patch something, where to put the patch ?

Let's say I have already a patch loaded in Bank2 from $0000 to $0FFF; This is an BASIC extension, therefore some $03XX pointers have been modified to point to a stub in main mem that will redirect to the Bank2.
So I will also have some part of the main mem used.
How can I say that those memory areas are used ?
(in case you're wondering why, it's because I may load some BASIC program which want to use some memory too and we don't want it to used the same memory)

What about some free memory pointers ?
Something like:
main : $9000 ; free from $8FFF going downward meaning $9000-$9F00 is used

bank0: $FFFF ; => no free mem
bank1: $FFFF ; => no free mem
bank2: $1000; free from $1000 going upward meaning $0000-$0FFF is used

What is the way to go ?

Kernal overwrites $02

According to the documentation, if you don't use BASIC, $00-$8F are available.

This is wrong. In the scan_to_joystick routine, called as part of the interrupt, the j0tmp is currently assigned the address $02 ; so the interrupt is randomly overwriting this byte (the address this happens is $F5BD, the routine starts at $F5CF)

ROM seems to send \x0A to screen even though it's not a valid control character

When I experimented with echo mode I discovered that 0x0A is sent before 0x0D is translated to 0x0A. There are many more line feeds in the terminal during echo than on screen. I believe the ROM should not send $0A since it is not a valid control character in PETSCII.

The current echo in x16-emulator changes CR = \r = 0x0D to LF = \n = 0x0A. Then it's not really raw. There are also \n sent from the ROM or some other system to the echo part, i.e. before the translation of CR to LF. There are more newlines in the output on the terminal than on screen. This could be because the X16 ignores them on the screen. E.g. when starting two extra linefeeds/newlines around READY. are sent before translation:

◥  ◥   ◤  ◤
 ◥  ◥ ◤  ◤  **** COMMANDER X16 BASIC V2 ****
  ◥     ◤
            2048K RAM SYSTEM
  ◤     ◥
 ◤  ◤ ◥  ◥  38655 BASIC BYTES FREE
◤  ◤   ◥  ◥

�
READY.
�

The extra newlines are shown here as �. Compare this to the screen.

I think I found one suspect line:
reddy .byt $d,$a,"READY.",$d,$a,0

I believe $a should not be in this line.

I think there should be several suboptions to echo, e.g. raw, default, auto.

Can't get JSRFAR do to what I expect it to.

I can't get JSRFAR to work in r32. The issue might very well be that I'm too stupid for it, but I really need some help with this. I made a little test case for r31 to do what DOS is actually doing:

*=$2000
LDA #$0
JSR $E6F5
RTS

That works just fine. So I made a r32-JSRFAR variant, which doesn't work. It looks like this:

*=$2000
LDA #$0
JSR $FF6E
; or JSR $03D1
.WORD $E736
.BYTE 7
RTS

I used to -debug option to understand what's going on, but I don't really know what to make of it.

This is my code loaded and disassembled in the monitor (it starts at $2001 here, because at $2000 is the $FF to trigger the debugger. The jump to JSRFAR here is direct, see below):
https://jpct.de/jsrfar-problem/code.png

This is the code at $FF6E (the address for the JSRFAR call) according to the monitor:
https://jpct.de/jsrfar-problem/ff63_expected.png

This is what comes up in the debugger when actually running the program with a call to $FF6E:
https://jpct.de/jsrfar-problem/ff63_actually.png

Maybe it's a debugger issue, but it puzzles me...anyway, I replaced the call to $FF6E with a call to $03D1. That executes the JSRFAR routine (not illustrated here). Then it jumps to $E736, where I expect to find the PTSTAT routine according to the rom.sym file). But the debugger tells me this:

https://jpct.de/jsrfar-problem/ptstat_actually.png

And all in all, it just doesn't work and I'm not sure why...

Reverse mode in ISO mode

In ISO mode, reverse mode has no effect. Also, the cursor is a block that covers the character instead of inverting it.

This can be fixed by swapping the foreground and background colors both for reverse characters and for the cursor.

  • At nxt3, the character is inverted (ORA #$80) in the PETSCII codepath.
  • At nc3w, we currently disable the Ctrl+9 combination of having any effect in ISO mode.
  • AT key5, the cursor is drawn. In ISO mode, we draw code $9F instead of inverting the character.

Keyboard: Compress keymaps

Currently, we map the PS/2 scancode to the PETSCII or ISO-8859-15 character.

The PS/2 scancodes are very sparse, so each table is 91 bytes. But there are only 48 non-control keys on ISO keyboards.

By mapping the PS/2 scancode to a value from 0-47 first, and using a 48-entry table, the size of the tables can almost be cut in half.

In addition, the scripts should make sure identical maps (e.g. Ctrl+character on Nordic and US) only end up in the ROM once. So it may even make sense to break the 48 scancodes into "A-Z" (26) and "rest" (22), because A-Z tend to be the same for most keyboards.

Expose more KERNAL and BASIC functions

Applications should rely as little as possible on fixed addresses in KERNAL and BASIC, otherwise it will be impossible to change the layout of the code in the future, so it would make more sense to expose more functions through a jump table. Here is a list of useful functions:

  SGNFAC = $BC2B
  MEMARG = $BA8C
  ARGADD = $B86A
  ARGAND = $AFE9
  ARGDIV = $BB14
  FACMUL = $BA30
  MEMMUL = $BA28
  FACADD = $B867
  FACLOG = $B9EA
  FACSQR = $BF71
  FACEXP = $BFED
  FACABS = $BC58
  FACSIN = $E26B
  FACCOS = $E264
  FACTAN = $E2B4
  FACATN = $E30E
  FACSGN = $BC39
  FACNOT = $AED4
  FACRND = $E097
  FACWORD = $B7F7
  FACDIV = $BB0F
  BASINT = $BCCC
  FACPOW = $BF7B
  FACSUB = $B853
  FACOR = $AFE6
  FACMEM = $BBD7
  ARGFAC = $BBFC
  FACARG = $BC0C
  FACSTR = $BDDF
  FACINT = $B1AA
  RNDFAC = $BC1B
  REALFAC = $BBA2
  INTFAC = $B391
  WRITETIS = $A9E7
  GETTI = $BE68
  GETTIME = $AF7E
  COPYTIME = $AF87
  TI2FAC = $AF84
  PRINTSTRS = $AB25
  VALS = $B7B5
  CMPFAC = $BC5B
  BYTEFAC = $B3A2
  CRSRRIGHT = $AB3B
  INPUT = $A560
  OPENCH = $F34A
  CLOSECH = $F291
  TWAIT = $F6ED

Total RAM amount shown

So, I've noticed that the amount of RAM that BASIC shows on boot is the total amount high RAM. Maybe this is just me, but I find it weird not to avoid low RAM in the calculation when it just says “RAM” and not “high RAM”. I think it would make sense to either have it include low RAM in the count or (even better) change the message to simply say “high RAM” instead of just “RAM”.

Basic Optimization Request: a token for pre-parsed small integers

AFAIU, repeatedly parsing integers is one of the parts of Microsoft 6502 that saved codespace while costing cycles.

Experience indicates that a large number of literal constants are represented by a relatively small number of relatively small constants, such as 1, -1, 2, 5, 10, 100. Parsing and saving these small integers after a literal token, followed by the original string, may therefore be a useful optimization.

As with pi=$FF, this can be allocated in advance at the top of the extension token space. The token can be handled directly by the parser and the main execution loop rather than supported by a separate keyword support routine. $FE $FF $xx would therefore be a suitable extended token and data string. The simplest implementation is a signed byte, +127/-128, and as that spans the most frequently used small integer values, that is the recommended meaning of the third byte of the sequence.

RMB/SMB opcodes show wrong mnemonics in monitor

RMB0 to RMB7 and SMB0 to SMB7 opcodes doesn't give the right mnemonic in the monitor. It just gives RMB and SMB for all the relevant opcodes.

By the way, the opcodes for RMB0 to RMB7 are: 07,17,27,37,47,57,67,77 and SMB0 to SMB7 are: 87,97,a7,b7,c7,d7,e7,f7

Keyboard: Support Shift + AltGr combinations

Some keyboards have uppercase accented Latin characters in the combination Shift + AltGr. These cannot currently be reached, since we don't generate (and read) a map for this modifier combination.

A BASIC program that reads the keyboard joystick can't be stopped using Esc

A BASIC program that reads the keyboard joystick can't be stopped using Esc or Ctrl+C. It happens after I press several arrow keys at the same time. It is enough to press two adjacent directions e.g. up-left, down-right, down-left, or down-right a couple of times to reproduce the bug. I compile and run in Raspbian Buster.

300 SYS $FF06
310 PRINT PEEK($EF),PEEK($F0),PEEK($F1)
320 GOTO 300

Missing license information

Hi!
Please add a LICENSE.MD file which lists the license of all the various components you're using. It appears you're using original code from the Commodore 64 kernal and BASIC, please clarify the license of these.
Thank you

Building on mac

Attempting to build on MacOS 10.14.6, macports cc65

  • ca65 does not include subdirectories by default. I had to add "-Ikernal" to the kernal build line, "-Ibasic" and "-Imonitor" to the appropriate build lines.
  • I get this error for the monitor build line:
    ca65 -g -Imonitor -DMACHINE_X16=1 -DCPU_65C02=1 monitor/monitor.s -o monitor/monitor.o monitor/monitor.s(899): Error: Unexpected end of line monitor/monitor.s(900): Error: Unexpected trailing garbage characters monitor/monitor.s(901): Error: Unexpected trailing garbage characters make: *** [all] Error 1

FYI:
ca65 --version
ca65 V2.13.3 - (C) Copyright 1998-2012 Ullrich von Bassewitz

Request support for Basic program line renumbering

I recommend a command be added for renumbering the lines of a program such as the following where:
increment defaults to 10,
new_start defaults to increment (10 if increment is not specified), and
old_start defaults to the first currently existing line number of the program.

RENUM [increment[,new_start[,old_start]]]

When the old_start parameter is omitted all lines of the entire program are renumbered. The old_start parameter provides the ability to renumber the last part of a program but is perhaps not as important as the other two parameters.

During the renumbering process the line numbers referenced in GOTO and GOSUB statements should automatically be updated as well (e.g. if line number 34 is renumbered to 100 then "GOTO 34" should be updated to "GOTO 100"). This includes line numbers in implicit GOTO statements such as "IF A=1 THEN 55".

Possible hook to add commands to BASIC?

As a potential developer I'd be interested to know if something like an added ROM would be easy to integrate. The major issues I'd see occuring are adding extra commands, by default of ROM presence, to the command processing loop(s), any necessary pre or post amble in the ROM image for system consistency (possibly including a command hook) and the constraints on the expected kern stack size for safe operation with call utility. Some basic entry points (perhaps as a symbol ROM) returning dynamic (per version) addresses of routines of use.

It might be fun doing some coding for this project, as it has great potential for scaling up what computers can do for us minus all the bloat which happened along the chaotic way to UI nivana.

I can also do small amounts of VHDL.

KERNAL / BASIC should provide a built-in mouse cursor

KERNAL / BASIC should provide a built in mouse-pointer / mouse-driver so that mouse properties, such as acceleration curve, left/right-handed-click are globally provided, avoiding multiple, conflicting mouse behaviours cropping up in homebrew software.

BASIC commands should be available to enable/disable the built-in mouse pointer and to read an mouse event-queue (much like the keyboard).

A default mouse pointer would be uploaded to VERA from the ROM, so that it can be easily redefined. Sprite no. 128 would probably be a good choice for the pointer.

edit -- also, GEOS would be able to hook into this to minimize code/behaviour duplication between the systems.

LOAD command is broken

Creating a test program and saving it to local file system works:

Contents of TEST on local file system:

qbradq@qbradq-AB350-Gaming:~/commanderx16$ xxd TEST
00000000: 0108 0f08 0a00 9920 2248 454c 4c4f 2200  ....... "HELLO".
00000010: 1808 1400 8920 3130 0000 00              ..... 10...

And here is a new session attempting to load the newly created file:

Tests were on a fresh pull and build of the emulator and ROM.
ROM version 8b1f368
Emulator version f3121f06c69283e18fa5421562dbc9f17c413d31

`SCREEN` BASIC command to switch screen modes

This is not a request to add this immediately :P Maybe someone will take this upon themselves to do.

Add a BASIC command to change screen modes without the need to poke/vpoke.

SCREEN cols, rows, [back-colour[, fore-colour]]

Specifying rows & columns would be preferable to actual pixel values as this provides better flexibility for the KERNAL / VERA to select actual output resolution more intelligently (e.g. imagine a later revision that supports 1080p)

[Feature Request] Support for FAT16 and FAT12 on the SD card

I was experimenting with the -sdcard option in the emulator, and was struggling to get it working. I eventually figured out that, in the macOS tool Disk Utility, creating a "FAT32" disk image would create partitions of the type FAT16 or FAT12 if the image was small enough to use those formats. I'm guessing the reason it does that is that they use less space for the allocation table, and it's trying to provide the maximum possible amount of space for files. This makes it more challenging to make ISO files that work. While supporting FAT16 or FAT12 probably won't be an issue for physical cards, as most will be large enough to require FAT32 anyways, but supporting FAT16 and FAT12 could make it a lot easier to use disk images easier (both for using with the emulator, and for shared projects to be written directly to an SD card). Since all the FAT types are related, FAT16 and FAT12 should be able to reuse a lot of the existing code for FAT32, which would minimize the work required to support it (and the space it uses on the ROM).

The KERNAL should not overwrite VERA I/O

The KERNAL EDITOR assumes it owns the VERA I/O registers:

On boot, it sets up VERA_CTRL.ADDRSEL to enable VERA_DATA0, and any screen output as well as the blinking of the cursor will assume VERA_CTRL.ADDRSEL is unchanged, and it will overwrite VERA_ADDR_LO/VERA_ADDR_MID/VERA_ADDR_HI.

So changing VERA registers in BASIC direct mode has no effect, because the interrupt code will overwrite the VERA registers, and a BASIC program can't work with VERA registers and print to the screen at the same time.

Having the KERNAL save and restore the VERA I/O register state on every VERA access is too expensive. The BSOUT codepath is slow on KERNAL, even on an 8 MHz CPU, and the indirect VERA registers make it worse.

We can have the KERNAL only use VERA_DATA1 though and allow BASIC programs to own VERA_DATA0. For this, we only have to switch VERA_CTRL.ADDRSEL to 1 at the beginning (6 cycles), and restore it to 0 at the end (6 cycles) of a screen access.

The only place where we use both VERA_DATA0 and VERA_DATA1 is when scrolling. That's expensive anwyay, so we can save and resttore VERA_DATA0 here.

ESC (Ctrl-C) not working on Linux Mint

I'm using the latest emulator and latest ROM, and then typing the simple BASIC program:
10 PRINT "HI"
20 GOTO 10
RUN
The screen fills with "HI" (as expected), but I am unable to stop the program.

Ctrl-R works as expected (the simulator resets), but pressing Esc or Ctrl-C have no effect.

I'm using Linux Mint 19.2, and the emulator and ROM are both dated October 17, 2019 (compiled from source).

I've tried different keyboard layouts, but without any change in behaviour.

Discussion: SYS syntax V2 vs. V7

SYS uses three memory locations - sareg, sxreg,syreg and spreg to pass A,X,Y,S in and out of machine code routines. These need to have specified locations (they are 780-783 in the C64) as it will be somewhat challenging if they move about between ROM builds.

POKE breaks on NMOS 6502 & MMIO with side certain effects on write

According to the 65C02 data sheet on page 30, the 65C02 processor performs two memory accesses during an STA (zp),Y. (Make sure to reference note 1, which stipulates 1 more cycle count on write.)

This breaks the POKE command when used on VERA, because it will put data in the wrong location on screen. When used with any non-zero increment value, the POKEd character will be one step to the right of where intended, and the memory pointer will advance two locations.

The fix is very simple. The POKE command is in code17.s line 76:

poke jsr getnum
	 txa
	 ldy #0
	 sta (poker),y
	 rts

This should change to

poke  jsr getnum
	  txa
	  sta (poker)
	  rts

This change does break 6502 compatibility, since STA (zp) without indexing is a new opcode.

Feature Request: Logical KERNAL lines > 80c (to be able to enter BASIC lines > 80c)

Tested in r30 and r31.

Repro steps:

  1. Start the emulator with no additional parameters.
  2. Start typing:

10 PRINT "HELLO WORLD!"
15 REM BE SURE TO INCLUDE THE PERIOD IN THE NEXT PRINT STATEMENT.
20 PRINT "NOW IS THE TIME FOR ALL GOOD MEN TO COME TO THE AID OF THEIR COUNTRY."
30 PRINT "LINE 20 WAS IGNORED, AND NO ERROR MESSAGE WAS PRODUCED."
LIST

  1. The editor will only display lines 10, 15, and 30.

Programming in BASIC should support input greater than 79 characters.
You should be able to write PRINT statements that output plain text to the full width of an 80 column display mode.

Please fix.
Thanks.

Question: is there a "correct" way to enhance the basic ?

Let's say I want to add a new command, how can I do it ?
For example, with Applesoft Basic, you can extend it with the & cmd;
it's a special token which call a ZP address where you can put your code.
Easy way to extend the basic without changing the ROM.
Is there something similar with this basic ?
Cheers.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.