Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
fe495064bThis file is pinned to the selected release. Download the original to open it in your design tool.
#ruledef {
SetPageReg A => 0x00
SetPageReg B => 0x01
SetPageReg C => 0x02
SetPageReg Swap => 0x03
SetPageI {value} => 0x04 @ value`8
SetAddrReg A => 0x05
SetAddrReg B => 0x06
SetAddrReg C => 0x07
SetAddrReg Swap => 0x08
SetAddrI {value} => 0x09 @ value`8
Load A {address} => 0x0A @ address`16
Load B {address} => 0x0B @ address`16
Load C {address} => 0x0C @ address`16
Load Swap {address} => 0x0D @ address`16
Load OutA {address} => 0x0E @ address`16
Load InOutA {address} => 0x0F @ address`16
Load InOutB {address} => 0x10 @ address`16
LoadI A {value} => 0x11 @ value`8
LoadI B {value} => 0x12 @ value`8
LoadI C {value} => 0x13 @ value`8
LoadI Swap {value} => 0x14 @ value`8
LoadI OutA {value} => 0x15 @ value`8
LoadI InOutA {value} => 0x16 @ value`8
LoadI InOutB {value} => 0x17 @ value`8
LoadP A {value} => 0x18 @ value`8
LoadP B {value} => 0x19 @ value`8
LoadP C {value} => 0x1A @ value`8
LoadP Swap {value} => 0x1B @ value`8
LoadP OutA {value} => 0x1C @ value`8
LoadP InOutA {value} => 0x1D @ value`8
LoadP InOutB {value} => 0x1E @ value`8
LoadInc A, 0 => 0x1F
LoadInc B, 0 => 0x20
LoadInc C, 0 => 0x21
LoadInc Swap, 0 => 0x22
LoadInc OutA, 0 => 0x23
LoadInc A, 1 => 0x24
LoadInc B, 1 => 0x25
LoadInc C, 1 => 0x26
LoadInc Swap, 1 => 0x27
LoadInc OutA, 1 => 0x28
LoadStck A {value} => 0x29 @ value`8
LoadStck B {value} => 0x2A @ value`8
LoadStck C {value} => 0x2B @ value`8
LoadStck Swap {value} => 0x2C @ value`8
LoadStck OutA {value} => 0x2D @ value`8
Store A {address} => 0x2E @ address`16
Store B {address} => 0x2F @ address`16
Store C {address} => 0x30 @ address`16
Store Swap {address} => 0x31 @ address`16
Store OutA {address} => 0x32 @ address`16
Store InOutA {address} => 0x33 @ address`16
Store InOutB {address} => 0x34 @ address`16
StoreI {address} {value} => 0x35 @ address`16 @ value`8
StoreP A {value} => 0x36 @ value`8
StoreP B {value} => 0x37 @ value`8
StoreP C {value} => 0x38 @ value`8
StoreP Swap {value} => 0x39 @ value`8
StoreP OutA {value} => 0x3A @ value`8
StoreP InOutA {value} => 0x3B @ value`8
StoreP InOutB {value} => 0x3C @ value`8
StoreInc A, 0 => 0x3D
StoreInc B, 0 => 0x3E
StoreInc C, 0 => 0x3F
StoreInc Swap, 0 => 0x40
StoreInc OutA, 0 => 0x41
StoreInc InOutA, 0 => 0x42
StoreInc InOutB, 0 => 0x43
StoreInc A, 1 => 0x44
StoreInc B, 1 => 0x45
StoreInc C, 1 => 0x46
StoreInc Swap, 1 => 0x47
StoreInc OutA, 1 => 0x48
StoreInc InOutA, 1 => 0x49
StoreInc InOutB, 1 => 0x4A
StoreStck A {value} => 0x4B @ value`8
StoreStck B {value} => 0x4C @ value`8
StoreStck C {value} => 0x4D @ value`8
StoreStck Swap {value} => 0x4E @ value`8
StoreNStck A {value} => 0x4F @ value`8
StoreNStck B {value} => 0x50 @ value`8
StoreNStck C {value} => 0x51 @ value`8
StorePStck C {value} => 0x5201 @ value`8
StoreStckI {value1} {value2} => 0x53 @ value1`8 @ value2`8
StoreNStckI {value1} {value2} => 0x54 @ value1`8 @ value2`8
StorePStckI {value1} {value2} => 0x5501 @ value1`8 @ value2`8
Copy A, B => 0x56
Copy A, C => 0x57
Copy A, Swap => 0x58
Copy A, Stack => 0x59
Copy A, OutA => 0x5A
Copy A, InOutA => 0x5B
Copy A, InOutB => 0x5C
Copy B, A => 0x5D
Copy C, A => 0x5E
Copy Swap, A => 0x5F
Copy Stack, A => 0x60
Copy OutA, A => 0x61
Copy InOutA, A => 0x62
Copy InOutB, A => 0x63
Copy PCnt, A => 0x64
Copy PCnt, A, HighB => 0x65
Copy MAdr, A => 0x66
Copy MAdr, A, HighB => 0x67
Jump {address} => 0x68 @ address`16
JumpZ {address} => 0x69 @ address`16
JumpC {address} => 0x6A @ address`16
JumpNZ {address} => 0x6B @ address`16
JumpNC {address} => 0x6C @ address`16
Call {address} => 0x6D00 @ ($ + 6)`16 @ address`16
CallZ {address} => 0x6E00 @ ($ + 6)`16 @ address`16
CallC {address} => 0x6F00 @ ($ + 6)`16 @ address`16
CallNZ {address} => 0x7000 @ ($ + 6)`16 @ address`16
CallNC {address} => 0x7100 @ ($ + 6)`16 @ address`16
Return => 0x7200
ReturnZ => 0x7300
ReturnC => 0x7400
ReturnNZ => 0x7500
ReturnNC => 0x7600
CmpI {value} => 0x77 @ value`8
CmpAndI {value} => 0x78 @ value`8
Cmp {address} => 0x79 @ address`16
CmpAnd {address} => 0x7A @ address`16
CmpReg C => 0x7B
CmpReg Swap => 0x7C
CmpReg Stack => 0x7D
CmpReg OutA => 0x7E
CmpReg InOutA => 0x7F
CmpReg InOutB => 0x80
CmpAndReg C => 0x81
CmpAndReg Swap => 0x82
CmpAndReg Stack => 0x83
CmpAndReg OutA => 0x84
CmpAndReg InOutA => 0x85
CmpAndReg InOutB => 0x86
ShiftL 1 => 0x87
ShiftL 2 => 0x88
ShiftL 3 => 0x89
ShiftL 4 => 0x8A
ShiftL 5 => 0x8B
ShiftL 6 => 0x8C
ShiftL 7 => 0x8D
ShiftR 1 => 0x8E
ShiftR 2 => 0x8F
ShiftR 3 => 0x90
ShiftR 4 => 0x91
ShiftR 5 => 0x92
ShiftR 6 => 0x93
ShiftR 7 => 0x94
RotateL => 0x95
RotateR => 0x96
AddI {value} => 0x97 @ value`8
AddIZ {value} => 0x98 @ value`8
AddIC {value} => 0x99 @ value`8
AddINZ {value} => 0x9A @ value`8
AddINC {value} => 0x9B @ value`8
SubI {value} => 0x9C @ value`8
SubIZ {value} => 0x9D @ value`8
SubIC {value} => 0x9E @ value`8
SubINZ {value} => 0x9F @ value`8
SubINC {value} => 0xA0 @ value`8
AndI {value} => 0xA1 @ value`8
AndIZ {value} => 0xA2 @ value`8
AndIC {value} => 0xA3 @ value`8
AndINZ {value} => 0xA4 @ value`8
AndINC {value} => 0xA5 @ value`8
AddINF {value} => 0xA6 @ value`8
AddINFZ {value} => 0xA7 @ value`8
AddINFC {value} => 0xA8 @ value`8
AddINFNZ {value} => 0xA9 @ value`8
AddINFNC {value} => 0xAA @ value`8
SubINF {value} => 0xAB @ value`8
SubINFZ {value} => 0xAC @ value`8
SubINFC {value} => 0xAD @ value`8
SubINFNZ {value} => 0xAE @ value`8
SubINFNC {value} => 0xAF @ value`8
AndINF {value} => 0xB0 @ value`8
AndINFZ {value} => 0xB1 @ value`8
AndINFC {value} => 0xB2 @ value`8
AndINFNZ {value} => 0xB3 @ value`8
AndINFNC {value} => 0xB4 @ value`8
AccumulateAdd => 0xB5
AccumulateSub => 0xB6
AccumulateAnd => 0xB7
OrI {value} => 0xB8 @ value`8
OrIZ {value} => 0xB9 @ value`8
OrIC {value} => 0xBA @ value`8
OrINZ {value} => 0xBB @ value`8
OrINC {value} => 0xBC @ value`8
XorI {value} => 0xBD @ value`8
XorIZ {value} => 0xBE @ value`8
XorIC {value} => 0xBF @ value`8
XorINZ {value} => 0xC0 @ value`8
XorINC {value} => 0xC1 @ value`8
Not => 0xC2
NotZ => 0xC3
NotC => 0xC4
NotNZ => 0xC5
NotNC => 0xC6
Add {address} => 0xC7 @ address`16
AddZ {address} => 0xC8 @ address`16
AddC {address} => 0xC9 @ address`16
AddNZ {address} => 0xCA @ address`16
AddNC {address} => 0xCB @ address`16
Sub {address} => 0xCC @ address`16
SubZ {address} => 0xCD @ address`16
SubC {address} => 0xCE @ address`16
SubNZ {address} => 0xCF @ address`16
SubNC {address} => 0xD0 @ address`16
And {address} => 0xD1 @ address`16
AndZ {address} => 0xD2 @ address`16
AndC {address} => 0xD3 @ address`16
AndNZ {address} => 0xD4 @ address`16
AndNC {address} => 0xD5 @ address`16
Or {address} => 0xD6 @ address`16
OrZ {address} => 0xD7 @ address`16
OrC {address} => 0xD8 @ address`16
OrNZ {address} => 0xD9 @ address`16
OrNC {address} => 0xDA @ address`16
Xor {address} => 0xDB @ address`16
XorZ {address} => 0xDC @ address`16
XorC {address} => 0xDD @ address`16
XorNZ {address} => 0xDE @ address`16
XorNC {address} => 0xDF @ address`16
Nop => 0xE0
Nop1 => 0xE1
Nop2 => 0xE2
Halt => 0xE3
}
; Constants for updating a 10 x 20 shift-register display
RCLCK = 0b00000100
SRCLCK = 0b00000010
SER = 0b00000001
PIXELW = 10
PIXELH = 20
PIXELS = PIXELW * PIXELH
; Memory page constants
DISP_BUF = 0x02
; Constants for input from a 74HC166-based controller
CONTROLLER_SER = 0b00000001
CONTROLLER_CONN = 0b00000010
CONTROLLER_SHLD = 0b00000001
CONTROLLER_CLK = 0b00000010
; Button constants, for storing button states in one byte
BUTTON_LEFT = 1 << 0
BUTTON_UP = 1 << 1
BUTTON_RIGHT = 1 << 2
BUTTON_DOWN = 1 << 3
BUTTON_START = 1 << 4
BUTTON_SELECT = 1 << 5
BUTTON_A = 1 << 6
BUTTON_B = 1 << 7
; Zero page addresses
MEM_PAGE = 0x10 ; Address of the screen we're on (high byte)
MEM_ADDR = 0x11 ; Address of the screen we're on (low byte)
MEM_OFFSET = 0x12 ; Offset to edit on the current screen
TICKS0 = 0x13
TICKS1 = 0x14
TICKS2 = 0x15
TICKS3 = 0x16
ITER = 0x17
ITER2 = 0x18
SPEED = 0x19
BUTTON_STATES = 0x21
LAST_EDIT = 0x22
#addr 0x8000
main:
Jump init
init_return:
Jump main_loop
main_loop_return:
Jump main
init:
; Zero out a bunch of "variables".
LoadI A 0
Store A TICKS0
Store A TICKS1
Store A TICKS2
Store A TICKS3
Store A LAST_EDIT
Store A MEM_PAGE
Store A MEM_ADDR
Store A MEM_OFFSET
Store A SPEED
Jump init_return
main_loop:
; Update tick counters (effectively increment a 32 bit number)
Load A TICKS0
AddI 1
Store A TICKS0
JumpNZ .done_updating_ticks
Load A TICKS1
AddI 1
Store A TICKS1
JumpNZ .done_updating_ticks
Load A TICKS2
AddI 1
Store A TICKS2
JumpNZ .done_updating_ticks
Load A TICKS3
AddI 1
Store A TICKS3
.done_updating_ticks:
Jump handle_input
handle_input_return:
Jump move_cursor
move_cursor_return:
Jump modify_value
modify_value_return:
Jump update_display
update_display_return:
Jump draw_display
draw_display_return:
Jump main_loop
; Return
handle_input:
; Load button states into shift register, before shifting them out.
LoadI InOutA 0
LoadI InOutA CONTROLLER_CLK
LoadI InOutA 0
LoadI InOutA CONTROLLER_SHLD
; Start with empty state to load button press states into.
LoadI C 0
LoadI A CONTROLLER_SER
CmpAndReg InOutA ; Left
Copy C, A
AddINFNZ BUTTON_LEFT
Copy A, C
LoadI A CONTROLLER_SER
LoadI InOutA CONTROLLER_SHLD | CONTROLLER_CLK
LoadI InOutA CONTROLLER_SHLD
CmpAndReg InOutA ; Up
Copy C, A
AddINFNZ BUTTON_UP
Copy A, C
LoadI A CONTROLLER_SER
LoadI InOutA CONTROLLER_SHLD | CONTROLLER_CLK
LoadI InOutA CONTROLLER_SHLD
CmpAndReg InOutA ; Right
Copy C, A
AddINFNZ BUTTON_RIGHT
Copy A, C
LoadI A CONTROLLER_SER
LoadI InOutA CONTROLLER_SHLD | CONTROLLER_CLK
LoadI InOutA CONTROLLER_SHLD
CmpAndReg InOutA ; Down
Copy C, A
AddINFNZ BUTTON_DOWN
Copy A, C
LoadI A CONTROLLER_SER
LoadI InOutA CONTROLLER_SHLD | CONTROLLER_CLK
LoadI InOutA CONTROLLER_SHLD
CmpAndReg InOutA ; Start
Copy C, A
AddINFNZ BUTTON_START
Copy A, C
LoadI A CONTROLLER_SER
LoadI InOutA CONTROLLER_SHLD | CONTROLLER_CLK
LoadI InOutA CONTROLLER_SHLD
CmpAndReg InOutA ; Select
Copy C, A
AddINFNZ BUTTON_SELECT
Copy A, C
LoadI A CONTROLLER_SER
LoadI InOutA CONTROLLER_SHLD | CONTROLLER_CLK
LoadI InOutA CONTROLLER_SHLD
CmpAndReg InOutA ; A
Copy C, A
AddINFNZ BUTTON_A
Copy A, C
LoadI A CONTROLLER_SER
LoadI InOutA CONTROLLER_SHLD | CONTROLLER_CLK
LoadI InOutA CONTROLLER_SHLD
CmpAndReg InOutA ; B
Copy C, A
AddINFNZ BUTTON_B
Copy A, C
Store C BUTTON_STATES
Jump handle_input_return
;Return
move_cursor:
; Calculate offset to move
LoadI C 0
Load A BUTTON_STATES
CmpAndI BUTTON_UP
Copy C, A
SubINZ 1
Copy A, C
Load A BUTTON_STATES
CmpAndI BUTTON_DOWN
Copy C, A
AddINZ 1
CmpI 0
JumpZ move_cursor_return
Copy A, B
; Move cursor
Load A MEM_OFFSET
AccumulateAdd
CmpI -1
JumpZ .overflow_down
CmpI PIXELH
JumpZ .overflow_up
Store A MEM_OFFSET
Jump move_cursor_return
.overflow_up:
LoadI A 0
Store A MEM_OFFSET
Load A MEM_ADDR
AddI 20
Store A MEM_ADDR
Load A MEM_PAGE
AddIZ 1
Store A MEM_PAGE
Jump move_cursor_return
.overflow_down:
LoadI A 19
Store A MEM_OFFSET
Load A MEM_ADDR
SubI 20
Store A MEM_ADDR
Load A MEM_PAGE
SubINC 1
Store A MEM_PAGE
Jump move_cursor_return
modify_value:
; Calculate offset to change
LoadI C 0
Load A BUTTON_STATES
CmpAndI BUTTON_LEFT
Copy C, A
SubINZ 1
Copy A, C
Load A BUTTON_STATES
CmpAndI BUTTON_RIGHT
Copy C, A
AddINZ 1
Copy A, C
CmpI 0
JumpZ modify_value_return
; Update last edit
Load A TICKS1
Store A LAST_EDIT
; Make modification
Load A MEM_ADDR
Load Swap MEM_PAGE
Add MEM_OFFSET
SetAddrReg A
Copy Swap, A
AddINC 1 ; If the addr overflowed, then increment the page
OrI 0x80 ; Make sure we're dealing with addresses on the cartridge
SetPageReg A
LoadInc B, 0 ; Load the actual byte we're modifying into A
Copy C, A ; Get our offset back and add it, then save
AccumulateAdd
StoreInc A, 0
Jump modify_value_return
update_display:
SetPageI DISP_BUF
SetAddrI 0
LoadI A PIXELS
LoadI C 0
.clear_loop:
StoreInc C, 1
SubI 1
JumpNZ .clear_loop
LoadI A 0
Store A ITER
.data_loop:
Load A MEM_ADDR
Load C MEM_PAGE
Add ITER
SetAddrReg A
Copy C, A
AddINC 1 ; If the addr overflowed, then increment the page
OrI 0x80 ; Make sure we're dealing with addresses on the cartridge
SetPageReg A
LoadInc C, 0 ; Load the actual byte we're displaying into C
; Go to starting pixel position: ITER * 10 (that's ITER as Y, and X = 0)
Load A ITER
Copy A, B
AccumulateAdd ; A = A * 2
ShiftL 3
AccumulateAdd ; A = A * 2 + A * 8 = A * 10
SetAddrReg A
SetPageI DISP_BUF
; Draw each bit
Copy C, A
AndINF 0b10000000
StoreInc A, 1
Copy C, A
AndINF 0b01000000
StoreInc A, 1
Copy C, A
AndINF 0b00100000
StoreInc A, 1
Copy C, A
AndINF 0b00010000
StoreInc A, 1
Copy C, A
AndINF 0b00001000
StoreInc A, 1
Copy C, A
AndINF 0b00000100
StoreInc A, 1
Copy C, A
AndINF 0b00000010
StoreInc A, 1
Copy C, A
AndINF 0b00000001
StoreInc A, 1
Load A ITER
AddI 1
Store A ITER
CmpI PIXELH
JumpNZ .data_loop
; Draw address, low byte
Load C MEM_ADDR
LoadI A PIXELW - 1 ; Origin X position
SetAddrReg A
SetPageI DISP_BUF
Copy C, A
AndINF 0b00000001
StoreInc A, 0
Copy MAdr, A
AddI 10
SetAddrReg A
Copy C, A
AndINF 0b00000010
StoreInc A, 0
Copy MAdr, A
AddI 10
SetAddrReg A
Copy C, A
AndINF 0b00000100
StoreInc A, 0
Copy MAdr, A
AddI 10
SetAddrReg A
Copy C, A
AndINF 0b00001000
StoreInc A, 0
Copy MAdr, A
AddI 10
SetAddrReg A
Copy C, A
AndINF 0b00010000
StoreInc A, 0
Copy MAdr, A
AddI 10
SetAddrReg A
Copy C, A
AndINF 0b00100000
StoreInc A, 0
Copy MAdr, A
AddI 10
SetAddrReg A
Copy C, A
AndINF 0b01000000
StoreInc A, 0
Copy MAdr, A
AddI 10
SetAddrReg A
Copy C, A
AndINF 0b10000000
StoreInc A, 0
; Draw address, high byte
Load C MEM_PAGE
LoadI A 8 * PIXELW + PIXELW - 1 ; Origin Y + X position
SetAddrReg A
SetPageI DISP_BUF
Copy C, A
AndINF 0b00000001
StoreInc A, 0
Copy MAdr, A
AddI 10
SetAddrReg A
Copy C, A
AndINF 0b00000010
StoreInc A, 0
Copy MAdr, A
AddI 10
SetAddrReg A
Copy C, A
AndINF 0b00000100
StoreInc A, 0
Copy MAdr, A
AddI 10
SetAddrReg A
Copy C, A
AndINF 0b00001000
StoreInc A, 0
Copy MAdr, A
AddI 10
SetAddrReg A
Copy C, A
AndINF 0b00010000
StoreInc A, 0
Copy MAdr, A
AddI 10
SetAddrReg A
Copy C, A
AndINF 0b00100000
StoreInc A, 0
Copy MAdr, A
AddI 10
SetAddrReg A
Copy C, A
AndINF 0b01000000
StoreInc A, 0
Copy MAdr, A
AddI 10
SetAddrReg A
Copy C, A
AndINF 0b10000000
StoreInc A, 0
; Set offset "scroll bar"
Load A MEM_OFFSET
Copy A, B
AccumulateAdd ; A = A * 2
ShiftL 3
AccumulateAdd ; A = A * 2 + A * 8 = A * 10
AddI 8 ; X position, just after all the data bytes
SetAddrReg A
SetPageI DISP_BUF
LoadI A 1
StoreInc A, 0
Jump update_display_return
; Return
draw_display:
LoadI A PIXELS - 1
Store A ITER
SetPageI DISP_BUF
SetAddrI 0
.loop:
SetPageI DISP_BUF
SetAddrReg A
LoadInc A, 0
CmpI 0
JumpZ .send_zero
.send_one:
LoadI OutA SER
LoadI OutA SER | SRCLCK
Jump .loop_end
.send_zero:
LoadI OutA 0
LoadI OutA SRCLCK
.loop_end:
Load A ITER
SubI 1
Store A ITER
JumpC .loop
LoadI OutA RCLCK
LoadI OutA 0
Jump draw_display_return
; Return