Minicube64
Minicube64 is a fantasy console style emulator based on 6502, with the intention of helping people learn how games were made for older systems such as Atari 2600, NES or C64, but without many of the difficult hardware restrictions.
Annotated Introduction
The introduction page is what I'm annotating below. Hopefully these notes will give more insight into what the assembly is doing in the console.
You can find more about the compiler directives being used at the asm6f Github page[5], which is what Minicube64 uses.
Writing a New ROM
On the page "Writing a New ROM", there is a test program written in 6502 assembly. I figured a good way to learn what was going on was to annotate the whole thing and really grok it.
This is the contents of test.s
:
include "64cube.inc" ; Include the helper functinos for 64cube
ENUM $0 ; Enumerate the following vars starting at $0000
counter rBYTE 1 ; Set counter to type of byte with value of 1
ENDE ; End enumeration
org $200 ; Specify the origin of the ROM program
sei ; Set interrupt flag to 1
ldx #$ff ; Load 255 into X
txs ; Transfer the contents of x to the stack
; pointer
lda #$0 ; Load 0 into A
sta VIDEO ; Store A into VIDEO (location $100)
_setw IRQ, VBLANK_IRQ ; Store the address of IRQ at VBLANK_IRQ (in the
; include file)
cli ; Clear interrupt flag
Infinite: ; Set label for 'Infinite' at this address
jmp Infinite ; Jump to the 'Infinite' label, effectively
; creating an infinite loop
IRQ: ; Set label for 'IRQ' at this address
inc counter ; Increment the value at 'counter'
rti ; Return to where the interrupt occurred
This is the relevant contents of 64cube.inc
:
...
; NOTE NOTE
; normal 6502 has irq vectors at $fffe
; we have them at $010e
NMI_IRQ = $10c
VBLANK_IRQ = $10e
...
MACRO _setw value,dest ; Create a macro named _setw with two params:
; 'value', and 'dest'. Value is a 16-bit word,
; meaning it has a high and low byte.
lda #<value ; Load the low byte of value into accumulator
sta dest ; Store the value in accumulator at the address
; of destination
lda #>value ; Load the high byte of value into accumulator
sta dest+1 ; Store the value in accumulator at the address
; of destination + 1
ENDM ; Signify the end of the macro
Working With Pixels
This is the changed contents of the above test.s
:
...
txs
; This will set the video buffer page in a 4k page in memory
lda #$f ; Load high byte of page into 'a'
; register
sta VIDEO ; Store value in 'a' register at 'VIDEO'
; This will create a pixel of color #64 at pixel address $f820
lda #$64 ; Load decimal value 64 into 'a'
; register
;sta $f820 ; Store value in 'a' register at $f820
sta $f000 + 32 + 32 * 64 ; Same as above but with MATH
_setw IRQ, VBLANK_IRQ
...
Compiler Directives
Directive | Args | Effect |
---|---|---|
include n |
n : name of assembly file to be read |
Load in a remote assembly file and place the contents where include is invoked. Used for files containing assembly directives |
incbin n |
n : name of binary file to be read |
Load in a remote binary file and place the contents where include is invoked. Not to be used for files containing assembly directives |
Video Reference
Basic Drawing Example
This example shows how to set up a custom palette as well as drawing those colors to screen.
include "64cube.inc" ; Include the helper functions
ENUM $0 ; Enumerate values starting from $0000
counter rBYTE 1 ; Set 'counter' as 1 byte
ENDE ; End enumeration
org $200 ; Set program origin to $0200
sei ; Set interrupt disable flag
ldx #$ff ; Load value $ff into X
txs ; Transfer value of X into the stack
; pointer
; This will set the video buffer page in the $f000 page in memory
lda #$f ; Load high byte of page into 'a'
; register
sta VIDEO ; Store value in A at 'VIDEO'
; This will set the colors buffer page in the $5000 page in memory
lda #$5 ; Load highbyte of page into 'a'
; register
sta COLORS ; Store value in A at 'COLORS'
_setw IRQ, VBLANK_IRQ ; Set value of VBLANK_IRQ to address of
; 'IRQ' label
jsr Draw ; Jump to 'Draw' subroutine
cli ; Clear interrupt disable flag
Infinite: ; Set 'Infinite' label
jmp Infinite ; Create infinite loop
IRQ: ; Set 'IRQ' label
inc counter ; Increment 'counter'
rti ; Return from interrupt
Draw: ; Set 'Draw' label
; This will create pixels of colors from the palette below at address
; $f820. The color is found by referencing the colors page at the
; addresses listed below (#1, #2, #3).
lda #0 ; Create counter of 0 at A
Loop: ; Create Loop label
adc #1 ; Increment A
tax ; Transfer value of A into X
sta $f000 + 32 * 64 + 31,X ; Store X into
; $f000 + 32 * 64 + 31 and X
cmp #3 ; Compare x with 3
bne Loop ; If not equal go back to Loop
rts ; Else return from subroutine
Palette: ; Set 'Palette' label
; This will set the palette of colors available in the COLORS page,
; enumerating from $00 upward within that page.
org $0500 ; Set program origin to $0500
hex 000000 ff0000 00ff00 0000ff ; Set these colors in colors page
Video Address Locations
These are assuming the video page is being held in the 4k $f000
page.
Address | Position |
---|---|
0xf000 |
Top Left |
0xf03f |
Top Right |
0xf820 |
Middle |
0xffc0 |
Bottom Left |
0xffff |
Bottom Right |
References
- https://aeriform.gitbook.io/minicube64/
- https://itch.io/jam/minicubejam
- https://github.com/aeriform-io/minicube64/releases
- https://github.com/aeriform-io/minicube64/blob/main/memory_map.md
- https://github.com/freem/asm6f/blob/master/readme-original.txt
Examples:
- https://milofultz.com/2021-09-18-minicube64.html
- https://milofultz.com/2021-11-14-sorting-in-6502.html
Incoming Links
Last modified: 202401040446