Это было не просто, но мы справились. Структура спрайтов на атари это ещё то гениальное решение 
Короче доделал универсальную шнягу для отображения спрайта, теперь задаёшь номер 0,1,2,3 и вгружаются данные для Player0 … Player3 соответственно.
Было немного неприятно узнать, что данные спрайта в начале и в конце надо обязательно обрамлять $00 иначе при движении вверх/вниз крайний байт начинает мазать в линию x_x

Сырки:
sprites.mfk
Код:
const byte pmgmem=$80 //pmgmem*256 == place for sprites
void sprInit() {
poke($D407,pmgmem) // PMGBASE place in memory
poke ($022F,%00111110) // SDMCTL - Shadow of $D400 - Direct Memory Access (DMA) Control
// Bit Dec Function
// 7 128 not used
// 6 64 not used
// 5 32 Direct Memory Access on=1/off=0
// 4 16 One-line P/M-vertical resolution on=1/off=0
// 3 8 DMA for Players on=1/off=0
// 2 4 DMA for Missiles on=1/off=0
// 0,1 3 Wide playfield (48 bytes/chars)
// 0,1 2 Normal playfield (40 bytes/chars)
// 0,1 1 Narrow playfield (32 bytes/chars)
// 0,1 0 Playfield off
poke ($D01D,%00000011) // GRACTL controls PM and Triggers
// Bit Function
// 7 unused
// 6 unused
// 5 unused
// 4 unused
// 3 unused
// 2 Latch Triggers when =1
// 1 Turn on players when =1
// 0 Turn on missiles when =1
poke ($026F,1) // GPRIOR Priority Selection Register
// Bit Value Description
// 0 1 P0-P1-P2-P3 PF0-PF1-PF2-PF3 BAK
// 1 2 P0-P1 PF0-PF1-PF2-PF3 P2-P3 BAK
// 2 4 PF0-PF1-PF2-PF3 P0-P1-P2-P3 BAK
// 3 8 PF0-PF1 P0-P1-P2-P3 PF2-PF3 BAK
// 4 16 Four Missiles add up to be 5th player
// 5 32 Overlapping Players have 3rd color
// 6 64 GTIA Mode see next table
// 7 128 GTIA Mode see next table
poke ($D008,0) // [W] SIZEP0 size of player 0
// 0 = normal, 1 = double, 3 = quadruple
// [R] M0PL Collision Missile 0 with Player
poke ($D009,0) // [W] SIZEP1 size of player 1
poke ($D00a,0) // [W] SIZEP2 size of player 2
poke ($D00b,0) // [W] SIZEP3 size of player 3
// poke ($D00b,0) // [W] SIZEM size of missile
}
//asm void setColor(byte player, byte register(a) m) @ $02C0 + player extern
asm void setColor(byte player, byte register(a) m) {
LDX player
STA $02C0,X
RTS
}
asm void setPosX(byte player, byte register(a) m) {
LDX player
STA $D000,X
RTS
}
void sprShow(byte sprNum, pointer _sprData, byte _sprSize, byte _sprColor, byte x, byte y) {
pointer pmg0 //, pmg1
ubyte i
setColor(sprNum, _sprColor)
setPosX(sprNum, x)
// poke ($D004,x) // HPOSM0 horisontal place missile 0
// poke ($D005,x) // HPOSM1 horisontal place missile 1
// poke ($D006,x) // HPOSM2 horisontal place missile 2
// poke ($D007,x) // HPOSM3 horisontal place missile 3
// copy sprite data to defined place
pmg0=word((pmgmem*256) + 1024 + ($100 * sprNum) + y)
for i,0,to,_sprSize-1 {
pmg0[i]=_sprData[i]
}
}
boulder.mfk
Код:
import stdio
import sprites
array titleStr = "Boulder Dash ]["
array(byte) heroSpr0 = [0,$24,$3c,$5a,$5a,$3c,$18,$3c,$42,$18,0,$18,0]
array(byte) heroSpr1 = [0,$18,$24,$18,0,$18,0,0,$66,0]
array(byte) heroSpr2 = [0,$24,$24,$24,0]
byte color0 = $56
byte color1 = $0e
byte color2 = $c6
noinline asm void wait(byte register(a) f) {
clc
adc os_RTCLOK.b2
.rt_check:
cmp os_RTCLOK.b2
bne .rt_check
rts
}
void printAt(byte x, byte y, byte i) {
poke(84, y)
poke(85, x)
putword(i)
putstrz(" "z)
}
void main() {
byte pX
byte pY
byte joy
sprInit()
putstr(titleStr , titleStr.length)
new_line()
putstrz("Use JoyStick, LOOK!"z)
new_line()
pX = 120
pY = 116
putstrz("PosX: "z)
putword(pX)
new_line()
putstrz("PosY: "z)
putword(pY)
new_line()
joy = peek(632)
putstrz("JoyStick: "z)
putword(joy)
sprShow(0, heroSpr0, heroSpr0.length, color0, pX, pY)
sprShow(1, heroSpr1, heroSpr1.length, color1, pX, pY+7)
sprShow(2, heroSpr2, heroSpr2.length, color2, pX, pY+11)
while (true) {
wait(1)
joy = peek(632)
if (joy == 11 || joy == 10 || joy == 9) {
pX -= 1
} else if (joy == 7 || joy == 6 || joy == 5) {
pX += 1
}
if (joy == 14 || joy == 10 || joy == 6) {
pY -= 1
} else if (joy == 13 || joy == 9 || joy == 5) {
pY += 1
}
if (joy != 15) {
sprShow(0, heroSpr0, heroSpr0.length, color0, pX, pY)
sprShow(1, heroSpr1, heroSpr1.length, color1, pX, pY+7)
sprShow(2, heroSpr2, heroSpr2.length, color2, pX, pY+11)
printAt(8, 2, pX)
printAt(8, 3, pY)
printAt(12, 4, joy)
} else {
printAt(12, 4, joy)
}
}
}
- - - Добавлено - - -
Что бы не рисовать ручками, решил тут поискать спрайты в памяти оригинального Boulder Dash.
Ага, щаз! Судя по структуре похоже оно тайлами фигарит 
К слову нашёл сырки, кто-то декомпильнул оригинальный Boulder Dash