scroll down works on CHIP-8 and High-Res modes
scroll left and right work in stdef and hidef adds octo test roms adds schip fonts to memory
This commit is contained in:
@@ -0,0 +1,310 @@
|
||||
###########################################
|
||||
#
|
||||
# Chipenstein 3D
|
||||
#
|
||||
# A work-in-progress experiment
|
||||
# in creating a raycast 2.5d shooter.
|
||||
# Uses PWM techniques to simulate extra
|
||||
# colors and must run at 1000 cycles/frame.
|
||||
# Epilepsy warning!
|
||||
#
|
||||
###########################################
|
||||
|
||||
# The largest a map for this approach could be is 16x16.
|
||||
# Technically we don't have to surround all sides with
|
||||
# walls due to wraparound, but if there is a ray path
|
||||
# around the map without hitting a wall our raycast
|
||||
# routine will get stuck in an infinite loop:
|
||||
|
||||
: map-data
|
||||
0xFF 0x01 0xFF 0x01 0xFF 0x01 0xFF 0x01 0xFF 0x01
|
||||
0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xFF
|
||||
0xFF 0xFF 0x01 0xFF 0x00 0x00 0x00 0x00 0x00 0x01
|
||||
0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xFF
|
||||
0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01
|
||||
0x01 0x00 0xFF 0x01 0x00 0x00 0x00 0xFF 0x00 0xFF
|
||||
0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x01
|
||||
0x01 0xFF 0x01 0xFF 0x01 0xFF 0x01 0xFF 0x01 0xFF
|
||||
|
||||
: collision-test
|
||||
# take whole x/y in vc/vd, return map color in v0
|
||||
i := map-data
|
||||
vF := 0b111
|
||||
vc &= vF
|
||||
i += vc # + (x % 8)
|
||||
vd &= vF
|
||||
v0 <<= vd
|
||||
v0 <<= v0
|
||||
v0 <<= v0
|
||||
i += v0 # + (y % 8)*8
|
||||
load v0 # the current map color
|
||||
;
|
||||
|
||||
: player-position
|
||||
0 0 0 0 # scratchpad
|
||||
|
||||
: save-position
|
||||
v0 := va
|
||||
v1 := vb
|
||||
v2 := vc
|
||||
v3 := vd
|
||||
i := player-position
|
||||
save v3
|
||||
;
|
||||
|
||||
: restore-position
|
||||
i := player-position
|
||||
load v3
|
||||
va := v0
|
||||
vb := v1
|
||||
vc := v2
|
||||
vd := v3
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Raycasting
|
||||
#
|
||||
###########################################
|
||||
|
||||
# This is a table of the deltas and magnitudes for a fixed-point representation
|
||||
# of a cosine function. 64 entries correspond to ~5.6 degrees each.
|
||||
# deltas are interleaved with magnitudes- 0 for positive and 1 for negative.
|
||||
# deltas are normalized to slightly over half a step to make the distance calculations
|
||||
# come up with a maximum distance of roughly 15. Generated like so:
|
||||
#
|
||||
# for(int x = 0; x < 64; x++) {
|
||||
# double s = Math.cos(Math.PI*2/64*x);
|
||||
# System.out.format("0x%02X 0x%02X ", (int)(140 * Math.abs(s)), (s>=0) ?0 : 1);
|
||||
# if (x % 8 == 7) { System.out.println(); }
|
||||
# }
|
||||
|
||||
: cosine-table
|
||||
0x8C 0x00 0x8B 0x00 0x89 0x00 0x85 0x00 0x81 0x00 0x7B 0x00 0x74 0x00 0x6C 0x00
|
||||
0x62 0x00 0x58 0x00 0x4D 0x00 0x41 0x00 0x35 0x00 0x28 0x00 0x1B 0x00 0x0D 0x00
|
||||
0x00 0x00 0x0D 0x01 0x1B 0x01 0x28 0x01 0x35 0x01 0x41 0x01 0x4D 0x01 0x58 0x01
|
||||
0x62 0x01 0x6C 0x01 0x74 0x01 0x7B 0x01 0x81 0x01 0x85 0x01 0x89 0x01 0x8B 0x01
|
||||
0x8C 0x01 0x8B 0x01 0x89 0x01 0x85 0x01 0x81 0x01 0x7B 0x01 0x74 0x01 0x6C 0x01
|
||||
0x62 0x01 0x58 0x01 0x4D 0x01 0x41 0x01 0x35 0x01 0x28 0x01 0x1B 0x01 0x0D 0x01
|
||||
0x00 0x01 0x0D 0x00 0x1B 0x00 0x28 0x00 0x35 0x00 0x41 0x00 0x4D 0x00 0x58 0x00
|
||||
0x62 0x00 0x6C 0x00 0x74 0x00 0x7B 0x00 0x81 0x00 0x85 0x00 0x89 0x00 0x8B 0x00
|
||||
|
||||
: get-cosine
|
||||
# takes angle in v0,
|
||||
# returns delta, magnitude in v0, v1
|
||||
vf := 0b111111
|
||||
v0 &= vf # mod 64
|
||||
v0 <<= v0
|
||||
i := cosine-table
|
||||
i += v0
|
||||
load v1
|
||||
;
|
||||
|
||||
: get-angles
|
||||
# takes angle in v3,
|
||||
# unpacks x/y delta/mag into v4-v7
|
||||
|
||||
# cos(a) = cosine-table[(a % 64) << 1]
|
||||
v0 := v3
|
||||
get-cosine
|
||||
v4 := v0 # x delta
|
||||
v5 := v1 # x magnitude
|
||||
|
||||
# sin(a) = cosine-table[(a+16 % 64) << 1]
|
||||
v0 := v3
|
||||
v0 += 16
|
||||
get-cosine
|
||||
v6 := v0 # y delta
|
||||
v7 := v1 # y magnitude
|
||||
;
|
||||
|
||||
: delta-step
|
||||
vf := 0
|
||||
if v5 == 0 then va += v4 # positive x delta
|
||||
if vf == 1 then vc += 1 # carry in
|
||||
|
||||
vf := 0
|
||||
if v5 == 1 then va -= v4 # negative x delta
|
||||
if vf == 0 then vc += -1 # borrow out
|
||||
|
||||
vf := 0
|
||||
if v7 == 0 then vb += v6 # positive y delta
|
||||
if vf == 1 then vd += 1 # carry in
|
||||
|
||||
vf := 0
|
||||
if v7 == 1 then vb -= v6 # negative y delta
|
||||
if vf == 0 then vd += -1 # borrow out
|
||||
;
|
||||
|
||||
: heights
|
||||
# {height, color}
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
|
||||
: raycast
|
||||
save-position
|
||||
|
||||
#v0-v1 are available as scratch.
|
||||
|
||||
v8 := 0 # loop index * 2
|
||||
v3 := v9 # scan angle
|
||||
v3 += -8
|
||||
loop
|
||||
get-angles
|
||||
|
||||
v2 := 16 # height+1
|
||||
loop
|
||||
delta-step
|
||||
v2 += -1 # count down height
|
||||
collision-test # returns result in v0
|
||||
while v2 != 0
|
||||
if v0 == 0 then
|
||||
again
|
||||
|
||||
# save height and color in heights table:
|
||||
i := heights
|
||||
i += v8
|
||||
v1 := v0
|
||||
v0 := v2
|
||||
save v1
|
||||
|
||||
vf := v3
|
||||
restore-position
|
||||
v3 := vf
|
||||
|
||||
v8 += 2
|
||||
v3 += 1 # 16 slices * 5.625 = 90 degree FoV
|
||||
if v8 != 32 then
|
||||
again
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Rendering
|
||||
#
|
||||
###########################################
|
||||
|
||||
# this 45-byte table allows me to construct all the necessary vertical
|
||||
# strips using only immediate i and a height offset:
|
||||
|
||||
: top 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
: btm 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0 0xF0
|
||||
0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
|
||||
|
||||
: sync
|
||||
# take advantage of the fact that vf
|
||||
# is always a free register if we aren't
|
||||
# doing any operations that can carry:
|
||||
loop
|
||||
vf := delay
|
||||
if vf != 0 then
|
||||
again
|
||||
vf := 1
|
||||
delay := vf
|
||||
;
|
||||
|
||||
: draw-heights
|
||||
# registers for draw loop:
|
||||
# v0 is used to store the current height
|
||||
# v1 stores the 'color' bitmask
|
||||
v2 := 0 # heightmap index
|
||||
v3 := 1 # upward strip Y
|
||||
v4 := 16 # down strip Y
|
||||
v5 := 0 # strip X (avoid shifting v1 in loop)
|
||||
v6 := 15 # constant
|
||||
|
||||
sync clear
|
||||
loop
|
||||
# fetch height of column
|
||||
i := heights
|
||||
i += v2
|
||||
load v1
|
||||
|
||||
# apply PWM duty cycle for 'color'
|
||||
v1 &= ve
|
||||
if v1 == 0 then v0 := 0
|
||||
|
||||
# draw upward strip
|
||||
i := top
|
||||
i += v0
|
||||
v0 =- v6
|
||||
sprite v5 v3 15
|
||||
|
||||
# draw downward strip
|
||||
i := btm
|
||||
i += v0
|
||||
sprite v5 v4 15
|
||||
|
||||
# draw 16 columns
|
||||
v2 += 2
|
||||
v5 += 4
|
||||
if v2 != 32 then
|
||||
again
|
||||
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Main Loop
|
||||
#
|
||||
###########################################
|
||||
|
||||
: gun
|
||||
0x10 0x18 0x24 0x24 0x24 0x24 0x5A 0xC2 0xE7 0x7F 0x3E 0x21 0x41 0x41
|
||||
|
||||
: spin-left
|
||||
v9 += -1
|
||||
raycast
|
||||
;
|
||||
|
||||
: spin-right
|
||||
v9 += 1
|
||||
raycast
|
||||
;
|
||||
|
||||
: walk-forward
|
||||
v3 := v9
|
||||
get-angles
|
||||
delta-step
|
||||
raycast
|
||||
;
|
||||
|
||||
: walk-backward
|
||||
v3 := v9
|
||||
get-angles
|
||||
vf := 1
|
||||
v5 ^= vf
|
||||
v7 ^= vf
|
||||
delta-step
|
||||
raycast
|
||||
;
|
||||
|
||||
: main
|
||||
# global state:
|
||||
v9 := 30 # player angle
|
||||
va := 128 # x position (fractional)
|
||||
vb := 128 # y position (fractional)
|
||||
vc := 5 # x position (whole)
|
||||
vd := 5 # y position (whole)
|
||||
ve := 0 # rolling frame counter
|
||||
|
||||
raycast
|
||||
|
||||
loop
|
||||
draw-heights
|
||||
i := gun
|
||||
v0 := 38
|
||||
v1 := 18
|
||||
sprite v0 v1 14
|
||||
|
||||
ve += 1
|
||||
|
||||
v0 := 7
|
||||
if v0 key then spin-left
|
||||
v0 := 9
|
||||
if v0 key then spin-right
|
||||
v0 := 5
|
||||
if v0 key then walk-forward
|
||||
v0 := 8
|
||||
if v0 key then walk-backward
|
||||
again
|
||||
@@ -0,0 +1,83 @@
|
||||
###########################################
|
||||
#
|
||||
# Sprite scrolling demo:
|
||||
#
|
||||
# Draw a computer monitor with a scrolling
|
||||
# image by using two copies of its sprites
|
||||
# and adjusting an offset into that data
|
||||
# before each draw.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: main
|
||||
# draw the background:
|
||||
|
||||
v0 := 16
|
||||
v1 := 4
|
||||
i := comp-LT
|
||||
sprite v0 v1 11
|
||||
v0 += 8
|
||||
i := comp-T
|
||||
sprite v0 v1 3
|
||||
v0 += 8
|
||||
sprite v0 v1 3
|
||||
v0 += 8
|
||||
i := comp-RT
|
||||
sprite v0 v1 11
|
||||
|
||||
v0 := 16
|
||||
v1 += 11
|
||||
i := comp-LB
|
||||
sprite v0 v1 15
|
||||
v0 += 8
|
||||
v1 += 7
|
||||
i := comp-B
|
||||
sprite v0 v1 8
|
||||
v0 += 8
|
||||
sprite v0 v1 8
|
||||
v0 += 8
|
||||
v1 += -7
|
||||
i := comp-RB
|
||||
sprite v0 v1 15
|
||||
|
||||
# main animation loop:
|
||||
|
||||
va := 24 # left x
|
||||
vb := 32 # right x
|
||||
vc := 7 # common y
|
||||
v9 := 0 # scroll offset
|
||||
v8 := 0b1111 # constant
|
||||
draw-texture
|
||||
loop
|
||||
draw-texture
|
||||
v9 += 1
|
||||
v9 &= v8
|
||||
draw-texture
|
||||
|
||||
vF := 4
|
||||
delay := vF
|
||||
loop
|
||||
vF := delay
|
||||
if vF != 0 then
|
||||
again
|
||||
again
|
||||
|
||||
: draw-texture
|
||||
i := grenade-L
|
||||
i += v9
|
||||
sprite va vc 15
|
||||
i := grenade-R
|
||||
i += v9
|
||||
sprite vb vc 15
|
||||
;
|
||||
|
||||
: grenade-L 0x0F 0x30 0x7C 0x7C 0xF8 0xF4 0xE0 0xE8 0xF0 0xE8 0xE0 0x68 0x70 0x34 0x08 0x00
|
||||
0x0F 0x30 0x7C 0x7C 0xF8 0xF4 0xE0 0xE8 0xF0 0xE8 0xE0 0x68 0x70 0x34 0x08 0x00
|
||||
: grenade-R 0xF0 0x0C 0x46 0x66 0x33 0x13 0x0B 0x0B 0x1F 0x0F 0x0F 0x1E 0x1E 0x1C 0x30 0x00
|
||||
0xF0 0x0C 0x46 0x66 0x33 0x13 0x0B 0x0B 0x1F 0x0F 0x0F 0x1E 0x1E 0x1C 0x30 0x00
|
||||
: comp-LT 0x3F 0x3F 0x3F 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C
|
||||
: comp-RT 0xFC 0xFC 0xFC 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C
|
||||
: comp-T 0xFF 0xFF 0xFF
|
||||
: comp-LB 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x3F 0x3F 0x3F 0x00 0x07 0x1C 0x73 0x7F
|
||||
: comp-RB 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0x3C 0xFC 0xFC 0xFC 0x00 0xE0 0xD8 0x26 0xFE
|
||||
: comp-B 0xFF 0xFF 0xFF 0xFF 0x33 0xCC 0x33 0xFF
|
||||
@@ -0,0 +1,23 @@
|
||||
###########################################
|
||||
#
|
||||
# Key input test program.
|
||||
# Move a dot around the screen in response
|
||||
# to keypresses.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: dot
|
||||
0b10000000
|
||||
|
||||
: main
|
||||
v0 := 10
|
||||
v1 := 10
|
||||
i := dot
|
||||
|
||||
loop
|
||||
sprite v0 v1 1
|
||||
v2 := 7 if v2 key then v0 += -1 # left
|
||||
v2 := 9 if v2 key then v0 += 1 # right
|
||||
v2 := 5 if v2 key then v1 += -1 # up
|
||||
v2 := 8 if v2 key then v1 += 1 # down
|
||||
again
|
||||
@@ -0,0 +1,30 @@
|
||||
###########################################
|
||||
#
|
||||
# Smile
|
||||
#
|
||||
# Draw smiley faces on the screen randomly
|
||||
# and periodically clear the display.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: smile
|
||||
0b00100100
|
||||
0b00100100
|
||||
0b00000000
|
||||
0b10000001
|
||||
0b01000010
|
||||
0b00111100
|
||||
|
||||
: main
|
||||
i := smile
|
||||
loop
|
||||
v2 := 0
|
||||
loop
|
||||
v0 := random 0b00111111
|
||||
v1 := random 0b00011111
|
||||
sprite v0 v1 6
|
||||
v2 += 1
|
||||
if v2 != 32 then
|
||||
again
|
||||
clear
|
||||
again
|
||||
@@ -0,0 +1,73 @@
|
||||
###########################################
|
||||
#
|
||||
# An Octo implementation of an in-place
|
||||
# selection sort capable of operating on
|
||||
# arrays of a fixed size up to 256 elements.
|
||||
#
|
||||
###########################################
|
||||
|
||||
:const SIZE 16
|
||||
:calc SIZE-1 { SIZE - 1 }
|
||||
|
||||
:alias here v1
|
||||
:alias rest v2
|
||||
:alias min-index v3
|
||||
:alias min-value v4
|
||||
:alias here-value v5
|
||||
|
||||
: selection-sort
|
||||
here := 0
|
||||
loop
|
||||
min-index := here
|
||||
i := data
|
||||
i += here
|
||||
load v0
|
||||
min-value := v0
|
||||
here-value := v0
|
||||
|
||||
rest := here
|
||||
rest += 1
|
||||
i := data
|
||||
i += rest
|
||||
loop
|
||||
load v0
|
||||
if v0 < min-value begin
|
||||
min-index := rest
|
||||
min-value := v0
|
||||
end
|
||||
|
||||
rest += 1
|
||||
if rest != SIZE then
|
||||
again
|
||||
|
||||
if min-index != here begin
|
||||
v0 := here-value
|
||||
i := data
|
||||
i += min-index
|
||||
save v0
|
||||
|
||||
v0 := min-value
|
||||
i := data
|
||||
i += here
|
||||
save v0
|
||||
end
|
||||
|
||||
here += 1
|
||||
if here != SIZE-1 then
|
||||
again
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Usage Example
|
||||
#
|
||||
###########################################
|
||||
|
||||
: data 14 5 15 6 1 3 10 7 0 9 11 4 2 13 8 12
|
||||
|
||||
: main
|
||||
selection-sort
|
||||
i := data
|
||||
load vf
|
||||
:breakpoint sort-complete
|
||||
;
|
||||
@@ -0,0 +1,116 @@
|
||||
###########################################
|
||||
#
|
||||
# An Octo implementation of an in-place
|
||||
# heap sort capable of operating on
|
||||
# arrays of a fixed size up to 255 elements.
|
||||
#
|
||||
###########################################
|
||||
|
||||
:const SIZE 16
|
||||
:calc SIZE-1 { SIZE - 1 }
|
||||
:calc LIMIT { ( SIZE / 2 ) + 1 }
|
||||
|
||||
:alias left-val v0
|
||||
:alias right-val v1
|
||||
:alias start v2
|
||||
:alias root v3
|
||||
:alias last v4
|
||||
:alias best v5
|
||||
:alias left v6
|
||||
:alias best-val v7
|
||||
:alias root-val v8
|
||||
|
||||
: heap-sort
|
||||
start := LIMIT
|
||||
last := SIZE
|
||||
loop
|
||||
root := start
|
||||
sift-down
|
||||
start += -1
|
||||
if start != -1 then
|
||||
again
|
||||
|
||||
start := SIZE-1
|
||||
loop
|
||||
# swap data[0] with data[start]:
|
||||
i := data
|
||||
load v0
|
||||
vf := v0
|
||||
|
||||
i := data
|
||||
i += start
|
||||
load v0
|
||||
i := data
|
||||
save v0
|
||||
|
||||
i := data
|
||||
i += start
|
||||
v0 := vf
|
||||
save v0
|
||||
|
||||
start += -1
|
||||
root := 0
|
||||
last := start
|
||||
sift-down
|
||||
|
||||
if start != 0 then
|
||||
again
|
||||
;
|
||||
|
||||
: assign-best
|
||||
best := left
|
||||
best-val := left-val
|
||||
jump found-best
|
||||
|
||||
: sift-down
|
||||
i := data
|
||||
i += root
|
||||
load v0
|
||||
root-val := v0
|
||||
|
||||
loop
|
||||
left <<= root
|
||||
|
||||
if left > last then return
|
||||
|
||||
i := data
|
||||
i += left
|
||||
load v1
|
||||
|
||||
best := left
|
||||
best += 1
|
||||
best-val := right-val
|
||||
|
||||
if left-val > right-val then jump assign-best
|
||||
if left == last then jump assign-best
|
||||
: found-best
|
||||
|
||||
if root-val >= best-val then return
|
||||
|
||||
i := data
|
||||
i += root
|
||||
v0 := best-val
|
||||
save v0
|
||||
|
||||
i := data
|
||||
i += best
|
||||
v0 := root-val
|
||||
save v0
|
||||
|
||||
root := best
|
||||
again
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Usage Example
|
||||
#
|
||||
###########################################
|
||||
|
||||
: data 14 5 15 6 1 3 10 7 0 9 11 4 2 13 8 12
|
||||
|
||||
: main
|
||||
heap-sort
|
||||
i := data
|
||||
load vf
|
||||
:breakpoint sort-complete
|
||||
;
|
||||
@@ -0,0 +1,131 @@
|
||||
###########################################
|
||||
#
|
||||
# An Octo implementation of an unusual
|
||||
# sorting algorithm which combines an
|
||||
# optimal sorting network and a merge pass.
|
||||
# This implementation is designed to sort
|
||||
# exactly 16 items. The 'sort-8' subroutine
|
||||
# can be used alone to sort the values
|
||||
# stored in the bottom 8 registers.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: sort-8
|
||||
# compare-and-swap:
|
||||
:macro cas A B {
|
||||
if A > B begin
|
||||
vf := A
|
||||
A := B
|
||||
B := vf
|
||||
end
|
||||
}
|
||||
|
||||
cas v0 v1
|
||||
cas v2 v3
|
||||
cas v4 v5
|
||||
cas v6 v7
|
||||
cas v0 v2
|
||||
cas v4 v6
|
||||
cas v1 v3
|
||||
cas v0 v4
|
||||
cas v5 v7
|
||||
cas v3 v7
|
||||
cas v1 v5
|
||||
cas v3 v5
|
||||
cas v2 v6
|
||||
cas v2 v4
|
||||
cas v1 v2
|
||||
cas v3 v6
|
||||
cas v2 v4
|
||||
cas v5 v6
|
||||
cas v3 v4
|
||||
;
|
||||
|
||||
: heap1 0 0 0 0 0 0 0 0
|
||||
: heap2 0 0 0 0 0 0 0 0
|
||||
|
||||
:alias val1 v8
|
||||
:alias val2 v9
|
||||
:alias dest va
|
||||
:alias index1 vb
|
||||
:alias index2 vc
|
||||
|
||||
: fused-sort
|
||||
i := data
|
||||
load v7
|
||||
sort-8
|
||||
val1 := v0
|
||||
i := heap1
|
||||
save v7
|
||||
|
||||
i := data
|
||||
load v7
|
||||
load v7 # cheaper than adding an offset of 8
|
||||
sort-8
|
||||
val2 := v0
|
||||
i := heap2
|
||||
save v7
|
||||
|
||||
index1 := 1
|
||||
index2 := 1
|
||||
dest := 0
|
||||
|
||||
: merge
|
||||
if val1 > val2 then jump merge-2
|
||||
append-1
|
||||
if index1 != 9 then jump merge
|
||||
loop
|
||||
append-2
|
||||
if dest == 16 then return
|
||||
again
|
||||
|
||||
: merge-2
|
||||
append-2
|
||||
if index2 != 9 then jump merge
|
||||
loop
|
||||
append-1
|
||||
if dest == 16 then return
|
||||
again
|
||||
|
||||
: append-1
|
||||
v0 := val1
|
||||
i := data
|
||||
i += dest
|
||||
save v0
|
||||
dest += 1
|
||||
|
||||
i := heap1
|
||||
i += index1
|
||||
load v0
|
||||
val1 := v0
|
||||
index1 += 1
|
||||
;
|
||||
|
||||
: append-2
|
||||
v0 := val2
|
||||
i := data
|
||||
i += dest
|
||||
save v0
|
||||
dest += 1
|
||||
|
||||
i := heap2
|
||||
i += index2
|
||||
load v0
|
||||
val2 := v0
|
||||
index2 += 1
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Usage Example
|
||||
#
|
||||
###########################################
|
||||
|
||||
: data 14 5 15 6 1 3 10 7 0 9 11 4 2 13 8 12
|
||||
|
||||
: main
|
||||
fused-sort
|
||||
i := data
|
||||
load vf
|
||||
:breakpoint sort-complete
|
||||
;
|
||||
@@ -0,0 +1,90 @@
|
||||
###########################################
|
||||
#
|
||||
# An Octo implementation of a
|
||||
# bucket sort capable of operating on
|
||||
# arrays of a fixed size up to 256 elements,
|
||||
# with values ranging 0-15.
|
||||
# This technique could be generalized
|
||||
# for full-byte values given a larger
|
||||
# bucket array.
|
||||
#
|
||||
###########################################
|
||||
|
||||
:const SIZE 16
|
||||
:const MAX_VAL 16
|
||||
|
||||
: empty
|
||||
0 0 0 0 0 0 0 0
|
||||
|
||||
: buckets
|
||||
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
|
||||
|
||||
: bucket-sort
|
||||
# zero bucket array
|
||||
i := empty
|
||||
load v7
|
||||
save v7 # unrolled loop to zero bucket array
|
||||
save v7 # and initialize loop counters for later.
|
||||
|
||||
# bucket the elements
|
||||
# v1 is data index (already 0)
|
||||
loop
|
||||
# load data
|
||||
i := data
|
||||
i += v1
|
||||
load v0
|
||||
vf := v0
|
||||
|
||||
# increment bucket
|
||||
i := buckets
|
||||
i += vf
|
||||
load v0
|
||||
v0 += 1
|
||||
i := buckets
|
||||
i += vf
|
||||
save v0
|
||||
|
||||
v1 += 1
|
||||
if v1 != SIZE then
|
||||
again
|
||||
|
||||
# unpack bucket counts
|
||||
# v1 is temporary count
|
||||
# v2 is data index (already 0)
|
||||
# v3 is bucket index (already 0)
|
||||
loop
|
||||
i := buckets
|
||||
i += v3
|
||||
load v0
|
||||
if v0 != 0 begin
|
||||
v1 := v0
|
||||
v0 := v3
|
||||
i := data
|
||||
i += v2
|
||||
v2 += v1
|
||||
loop
|
||||
save v0
|
||||
v1 += -1
|
||||
if v1 != 0 then
|
||||
again
|
||||
end
|
||||
v3 += 1
|
||||
if v3 != MAX_VAL then
|
||||
again
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Usage Example
|
||||
#
|
||||
###########################################
|
||||
|
||||
: data 14 5 15 6 1 3 10 7 0 9 11 4 2 13 8 12
|
||||
|
||||
: main
|
||||
bucket-sort
|
||||
i := data
|
||||
load vf
|
||||
:breakpoint sort-complete
|
||||
;
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
###########################################
|
||||
#
|
||||
# A modular stack data structure using
|
||||
# a v0-based calling convention.
|
||||
# vf is used as a working temporary
|
||||
# register because it is "fragile".
|
||||
# maximum stack size is 256 bytes.
|
||||
#
|
||||
###########################################
|
||||
|
||||
# the first value is the pointer index
|
||||
: stack 0 0 0 0 0 0 0 0 0
|
||||
|
||||
: push
|
||||
# modifies vf, v0
|
||||
# takes argument in v0
|
||||
# stack[++stack[0] + 1] := v0
|
||||
|
||||
i := stack
|
||||
vf := v0
|
||||
load v0
|
||||
i += v0
|
||||
v0 := vf
|
||||
save v0
|
||||
|
||||
i := stack
|
||||
load v0
|
||||
v0 += 1
|
||||
i := stack
|
||||
save v0
|
||||
;
|
||||
|
||||
: pop
|
||||
# modifies vf, v0
|
||||
# returns result in v0
|
||||
# v0 := stack[stack[0]-- + 1]
|
||||
|
||||
i := stack
|
||||
load v0
|
||||
v0 += -1
|
||||
vf := v0
|
||||
i := stack
|
||||
save v0
|
||||
i += vf
|
||||
load v0
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Usage Example:
|
||||
#
|
||||
###########################################
|
||||
|
||||
: print
|
||||
# takes an arg in v0
|
||||
i := hex v0
|
||||
sprite va vb 5
|
||||
va += 6
|
||||
;
|
||||
|
||||
: main
|
||||
va := 3
|
||||
vb := 3
|
||||
|
||||
v0 := 5 push
|
||||
v0 := 3 push
|
||||
v0 := 1 push
|
||||
pop print
|
||||
v0 := 9 push
|
||||
pop print
|
||||
pop print
|
||||
pop print
|
||||
|
||||
# should print '1935'
|
||||
@@ -0,0 +1,80 @@
|
||||
###########################################
|
||||
#
|
||||
# A modular stack data structure using
|
||||
# a vf-based calling convention.
|
||||
# This approach can only be extended up to
|
||||
# a size 16 stack.
|
||||
#
|
||||
###########################################
|
||||
|
||||
: scratch 0 0 0 0 0 0 0 0
|
||||
: under 0
|
||||
: stack 0
|
||||
: over 0 0 0 0 0 0 0
|
||||
|
||||
: push
|
||||
# here we take our argument from vf.
|
||||
# and do not corrupt any other registers.
|
||||
# we can eliminate the scratch saving
|
||||
# and restoring if low registers don't
|
||||
# need to be preserved.
|
||||
|
||||
i := scratch
|
||||
save v6
|
||||
|
||||
i := stack
|
||||
load v6
|
||||
i := over
|
||||
save v6
|
||||
i := stack
|
||||
v0 := vf
|
||||
save v0
|
||||
|
||||
i := scratch
|
||||
load v6
|
||||
;
|
||||
|
||||
: pop
|
||||
# result is left in vf.
|
||||
# again, we don't corrupt any other registers.
|
||||
|
||||
i := scratch
|
||||
save v7
|
||||
|
||||
i := stack
|
||||
load v7
|
||||
vf := v0
|
||||
i := under
|
||||
save v7
|
||||
|
||||
i := scratch
|
||||
load v7
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Usage Example:
|
||||
#
|
||||
###########################################
|
||||
|
||||
: print
|
||||
# takes an arg in vf
|
||||
i := hex vf
|
||||
sprite va vb 5
|
||||
va += 6
|
||||
;
|
||||
|
||||
: main
|
||||
va := 3
|
||||
vb := 3
|
||||
|
||||
vf := 5 push
|
||||
vf := 3 push
|
||||
vf := 1 push
|
||||
pop print
|
||||
vf := 9 push
|
||||
pop print
|
||||
pop print
|
||||
pop print
|
||||
|
||||
# should print '1935'
|
||||
@@ -0,0 +1,55 @@
|
||||
###########################################
|
||||
#
|
||||
# A modular stack data structure using
|
||||
# a v0-based calling convention.
|
||||
# This approach reserves a dedicated
|
||||
# register for a stack pointer and as
|
||||
# a result is very simple and fast.
|
||||
# maximum stack size is 256 bytes.
|
||||
#
|
||||
###########################################
|
||||
|
||||
:alias stack-ptr vd
|
||||
: stack 0 0 0 0 0 0 0 0
|
||||
|
||||
: push
|
||||
i := stack
|
||||
i += stack-ptr
|
||||
save v0
|
||||
stack-ptr += 1
|
||||
;
|
||||
|
||||
: pop
|
||||
stack-ptr += -1
|
||||
i := stack
|
||||
i += stack-ptr
|
||||
load v0
|
||||
;
|
||||
|
||||
###########################################
|
||||
#
|
||||
# Usage Example:
|
||||
#
|
||||
###########################################
|
||||
|
||||
: print
|
||||
# takes an arg in v0
|
||||
i := hex v0
|
||||
sprite va vb 5
|
||||
va += 6
|
||||
;
|
||||
|
||||
: main
|
||||
va := 3
|
||||
vb := 3
|
||||
|
||||
v0 := 5 push
|
||||
v0 := 3 push
|
||||
v0 := 1 push
|
||||
pop print
|
||||
v0 := 9 push
|
||||
pop print
|
||||
pop print
|
||||
pop print
|
||||
|
||||
# should print '1935'
|
||||
Reference in New Issue
Block a user