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

  1. https://aeriform.gitbook.io/minicube64/
  2. https://itch.io/jam/minicubejam
  3. https://github.com/aeriform-io/minicube64/releases
  4. https://github.com/aeriform-io/minicube64/blob/main/memory_map.md
  5. https://github.com/freem/asm6f/blob/master/readme-original.txt

Examples:

  1. https://milofultz.com/2021/09/18/minicube64
  2. https://milofultz.com/2021/11/09/bubble-sort-6502

Last modified: 202206101419