![]() | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
![]() 65c02 Assembly programming for the Commander x16*** Warning - The X16 is a prototype - it's hardware could change at any time*
*** Double Warning - V31 of
the emulator changed many video register addresses...
|
The Commander x16 is a FPGA enhanced
recreation of the C64, adding high resolution graphics, Tilemap
support and hardware sprites it gives the 6502 programmer the
opportunity to develop for a more modern system with the familiarity
of the C64. The commander X16 is still under construction - the developers have a facebook group here |
![]() |
![]() |
![]() |
|
![]() |
Links
New Ports
The 'Vera' Graphics
Address | Name | Bits | Details |
$9F20 | VERA_ADDR_HI | IIIIHHHH | 20 Bit address I=Increment |
$9F21 | VERA_ADDR_MID | MMMMMMMM | 20 Bit address |
$9F22 | VERA_ADDR_LO | LLLLLLLL | 20 Bit address |
$9F23 | VERA_DATA1 | DDDDDDDD | Data Port 1 |
$9F24 | VERA_DATA2 | DDDDDDDD | Data Port 2 |
$9F25 | VERA_CTRL | R------A | R=Reset A=Address (port 1 / 2) |
$9F26 | VERA_IEN | -----SLV | Interrupt enable - S=Sprite L=Line V=Vsync |
$9F27 | VERA_ISR | -----SLV | Interrupt Occurred - S=Sprite L=Line V=Vsync |
VRAM
To access this data - write an address to $9F20-$9F22, then read or write
with port $9F23
Group | Address | range | Description | |
Screen Ram | $00000 | $1FFFF | Video RAM | |
$20000 | $207FF | PETSCII character ROM (upper-case) | ||
$20800 | $20FFF | PETSCII character ROM (lower-case) | ||
L1 | $40000 | L1_CTRL0 | MMM----E | M=Mode 7=8bpp bmp / E=Enable |
L1 | $40001 | L1_CTRL1 | --HWhhww | H=tile Height / W=tile Width / m=map height / w=map width |
L1 | $40002 | L1_MAP_BASE_L | LLLLLLLL | Map Base (9:2) |
L1 | $40003 | L1_MAP_BASE_H | HHHHHHHH | Map Base (17:10) |
L1 | $40004 | L1_TILE_BASE_L | LLLLLLLL | Tile Base (9:2) |
L1 | $40005 | L1_TILE_BASE_H | HHHHHHHH | Tile Base (17:10) |
L1 | $40006 | L1_HSCROLL_L | LLLLLLLL | Hscroll (7:0) |
L1 | $40007 | L1_HSCROLL_H | ----HHHH | Vscroll (11:8) |
Alternate | L1_BM_PAL_OFFS | ----BBBB | In mode 567 Bmp palette offset | |
L1 | $40008 | L1_VSCROLL_L | LLLLLLLL | Hscroll (7:0) |
L1 | $40009 | L1_VSCROLL_H | ----HHHH | Vscroll (11:8) |
L1 | $4000A | $4000F | Layer 1 registers | |
L2 | $40010 | L2_CTRL0 | MMM----E | (M=Mode E=Enable) |
L2 | $40011 | L2_CTRL1 | --HWhhww | H=tile Height / W=tile Width / m=map height / w=map width |
L2 | $40012 | L2_MAP_BASE_L | LLLLLLLL | Map Base (9:2) |
L2 | $40013 | L2_MAP_BASE_H | HHHHHHHH | Map Base (17:10) |
L2 | $40014 | L2_TILE_BASE_L | LLLLLLLL | Tile Base (9:2) |
L2 | $40015 | L2_TILE_BASE_H | HHHHHHHH | Tile Base (17:10) |
L2 | $40016 | L2_HSCROLL_L | LLLLLLLL | Hscroll (7:0) |
L2 | $40017 | L2_HSCROLL_H | ----HHHH | Vscroll (11:8) |
Alternate | L2_BM_PAL_OFFS | ----BBBB | In mode 567 Bmp palette offset | |
L2 | $40018 | L2_VSCROLL_L | LLLLLLLL | Hscroll (7:0) |
L2 | $40019 | L2_VSCROLL_H | ----HHHH | Vscroll (11:8) |
L2 | $4001A | $4001F | Layer 2 registers | |
SprCom | $40020 | SPR_CTRL | -------E | E=Enable |
SprCom | $40021 | SPR_COLLISION | ----CCCC | C=Collision Mask |
SprCom | $40022 | $4002F | Sprite control registers | |
DspCom | $40040 | DC_VIDEO | F----COO | F=current field (RO) C=Chroma disable O=Out mode (1=vga) |
DspCom | $40041 | DC_HSCALE | HHHHHHHH | 128=Normal 64=2x |
DspCom | $40042 | DC_VSCALE | VVVVVVVV | 128=Normal 64=2x |
DspCom | $40043 | DC_BORDER_COLOR | CCCCCCCC | |
DspCom | $40044 | DC_HSTART_L | HHHHHHHH | hstart bit 0-7 (0) |
DspCom | $40045 | DC_HSTOP_L | LLLLLLLL | hstop bit 0-7 (640) |
DspCom | $40046 | DC_VSTART_L | HHHHHHHH | vstart bit 0-7 (0) |
DspCom | $40047 | DC_VSTOP_L | LLLLLLLL | hstop bit 0-7 (480) |
DspCom | $40048 | DC_STARTSTOP_H | --VvHHhh | V=vstop Bit 8 / v=vstart bit 8 / H= hstop bit 8 / h=hstart bit 8 |
DspCom | $40049 | DC_IRQ_LINE_L | LLLLLLLL | |
DspCom | $4004A | DC_IRQ_LINE_H | -------H | |
DspCom | $4004B | $4005F | Display composer registers | |
Palette | $40200 | Color 0 Green/Blue | GGGGBBBB | G=Green / B=Blue |
Palette | $40201 | Color 0 Red | ----RRRR | R=Red |
Palette | $40202 | $403FF | ... | Palette 1-256 |
SprData | $40800 | Sprite 0: Address L | LLLLLLLL | L = Vram Address L |
SprData | $40801 | Sprite 0: Address H | M---HHHH | H=Vram Address H / M= Mode (0=4bpp 1=8bpp) |
SprData | $40802 | Sprite 0: Xpos L | XXXXXXXX | Xpos bits 0-7 |
SprData | $40803 | Sprite 0: Xpos H | ------XX | Xpos bits 8-9 |
SprData | $40804 | Sprite 0: Ypos L | YYYYYYYY | Ypos bits 0-7 |
SprData | $40805 | Sprite 0: Ypos H | ------YY | Ypos bits 8-9 |
SprData | $40806 | Sprite 0: Settings 1 | CCCCZZVH | C=Collision mask Z=Z depth V=Vflip H=Hflip |
SprData | $40807 | Sprite 0: Settings 2 | HHWWPPPP | H=Height , W=Width (0/1/2/3 = 8/16/32/64 px) / P=Palette offset |
SprData | $40808 | $40FFF | ... | Sprite data 1-127 |
![]() |
256
color Hello World on the Commander x16 with the x16emu Lets create a Hello World example, using a bitmap font in 256 color mode. |
![]() |
![]() x16_HelloWorld.asm |
![]() |
When it comes to compiling a x16 program, we just need to build a
regular C64 PRG file... we can compile a valid file with VASM... vasm6502_oldstyle_win32.exe %1 -c02 -cbm-prg -chklabels -nocase -Dvasm=1 -L \BldC64\Listing.txt -DBuildC64=1 -Fbin -o "\BldC64\Program.prg" The only addition to my regular C64 script is the -c02 switch... this enables the extra 65C02 commands (rather than 6502) |
To start our program we can just specify our PRG on the command
line to x16emu... the script below will load a compiled program
'Program.prg' in the folder \BldC64\ x16emu.exe -run \BldC64\Program.prg |
Using 256 color BMP screens...
Printing characters to the screen...
4bpp Bitmap font
2x 4bpp Layers
Due
to the size of the screens, there isn't enough memory for two
320x240 bitmap screens with 256 colors, but 16 color layers are
likely to be enough for any realistic needs! Most systems from the 90's only had 16 colors or less anyway, so it's what a classic system had to work with. |
![]() |
Putting a bitmap on the screen
Changing the layer
![]() |
The
'Hscroll' option works as a Palette offset for bitmap modes...
unfortunately it seems there's no hardware scroll option for the
bitmap modes... If we want to do scrolling, we're probably going to be best to use tilemap modes (we'll look at them soon)... otherwise we'd have to use software scroll. |
Setting Hardware sprites
Each of the 128 sprites are controlled by settings held in VRAM between
$40800-$40FFF... each has 8 bytes...
The actual bitmap data of the sprites is held in normal VRAM - so we want
to store it outside the visible screen...
Before we can actually use sprites, however, we need to turn them on, we do this with Bit 0 of $40020
Group | Address | range | Description | |
Screen Ram | $00000-$1FFFF | Video RAM (also sprite bitmap data) | ||
SprCom | $40020 | SPR_CTRL | -------E | E=Enable Sprites |
SprCom | $40021 | SPR_COLLISION | ----CCCC | C=Collision Mask |
SprCom | $40022-$4002F | Sprite control registers | ||
SprData | $40800 | Sprite 0: Address L | LLLLLLLL | L = Vram Address L |
SprData | $40801 | Sprite 0: Address H | M---HHHH | H=Vram Address H / M= Mode (0=4bpp 1=8bpp) |
SprData | $40802 | Sprite 0: Xpos L | XXXXXXXX | Xpos bits 0-7 |
SprData | $40803 | Sprite 0: Xpos H | ------XX | Xpos bits 8-9 |
SprData | $40804 | Sprite 0: Ypos L | YYYYYYYY | Ypos bits 0-7 |
SprData | $40805 | Sprite 0: Ypos H | ------YY | Ypos bits 8-9 |
SprData | $40806 | Sprite 0: Settings 1 | CCCCZZVH | C=Collision mask Z=Z depth V=Vflip H=Hflip |
SprData | $40807 | Sprite 0: Settings 2 | HHWWPPPP | H=Height , W=Width (0/1/2/3 = 8/16/32/64 px) / P=Palette offset |
SprData | $40808-$40FFF | ... | Sprite data 1-127 (8 bytes per sprite) |
Bitmap Data format
Some useful new functions for VRAM
Coding Sprites
Here we've
shown a single sprite frame, but if we have multiple versions of
the sprite at different addresses, we just need to alter the
address to update the animation of the sprite... Take a look at the example in the sources file to see more! |
![]() |
Using our Sprite routine
![]() |
The example in this episode works fine for
hardware sprites 0-15, but not 16+... it's not clear why! Unfortunately, with the documentation limited, and the emulator in an early state, When something doesn't work it's not clear if it's an Emulator but, Unclear documentation, or a mistake by the author of these tutorials... If a solution becomes clear later, the code sample will be updated. |
View Options |
Default Dark |
Simple (Hide this menu) |
Print Mode (white background) |
Top Menu |
***Main Menu*** |
Youtube channel |
Patreon |
Email Newsletter |
Merch Store |
Amazon Affiliate Link |
Forum |
AkuSprite Editor |
Dec/Bin/Hex/Oct/Ascii Table |
Alt Tech |
Archive.org |
Bitchute |
Odysee |
Rumble |
DailyMotion |
Please note: I wlll upload more content to these alt platforms based on the views they bring in |
68000 Content |
***68000 Tutorial List*** |
Learn 68000 Assembly ![]() |
Hello World Series |
Platform Specific Series |
Grime 68000 ![]() |
68000 Downloads |
68000 Cheatsheet |
Sources.7z |
DevTools kit |
68000 Platforms |
Amiga 500 ![]() |
Atari ST ![]() |
Neo Geo ![]() |
Sega Genesis / Mega Drive ![]() |
Sinclair QL ![]() |
X68000 (Sharp x68k) ![]() |
8086 Content |
Learn 8086 Assembly ![]() |
Platform Specific Series |
Hello World Series |
8086 Downloads |
8086 Cheatsheet |
Sources.7z |
DevTools kit |
8086 Platforms |
Wonderswan |
MsDos |
ARM Content |
Learn ARM Assembly ![]() |
Learn ARM Thumb Assembly ![]() |
Platform Specific Series |
ARM Downloads |
ARM Cheatsheet |
Sources.7z |
DevTools kit |
ARM Platforms |
Gameboy Advance |
Nintendo DS |
Risc Os |
Risc-V Content |
Learn Risc-V Assembly |
Risc-V Downloads |
Risc-V Cheatsheet |
Sources.7z |
DevTools kit |
PDP-11 Content |
Learn PDP-11 Assembly |
PDP-11 Downloads |
PDP-11 Cheatsheet |
Sources.7z |
DevTools kit |
TMS9900 Content |
Learn TMS9900 Assembly |
TMS9900 Downloads |
TMS9900 Cheatsheet |
Sources.7z |
DevTools kit |
TMS9900 Platforms |
Ti 99 |
6809 Content |
Learn 6809 Assembly |
6809 Downloads |
6809/6309 Cheatsheet |
Sources.7z |
DevTools kit |
6809 Platforms |
Dragon 32/Tandy Coco |
Fujitsu FM7 |
TRS-80 Coco 3 |
Vectrex |
65816 Content |
Learn 65816 Assembly |
65816 Downloads |
65816 Cheatsheet |
Sources.7z |
DevTools kit |
65816 Platforms |
SNES |
eZ80 Content |
Learn eZ80 Assembly |
eZ80 Downloads |
eZ80 Cheatsheet |
Sources.7z |
DevTools kit |
eZ80 Platforms |
SNES |
Work in Progress |
ChibiAndroids |
Misc bits |
Ruby programming |