1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-06-07 01:29:30 +00:00
8bitworkshop/src/worker/fs/fswiz.data

4188 lines
218 KiB
Plaintext
Raw Normal View History

2021-03-04 14:20:00 +00:00
namespace icd2 {
namespace vram {
let BUFFER_COUNT = 4;
let BUFFER_BYTE_SIZE = 320;
let BUFFER_INDEX_MASK = 3;
// The tile row is the current GB scanline divided by 8.
// Every time the tile row increases, the buffer index is advanced.
// The buffer index is between 0 .. 3 and will wrap around.
// The GB screen is 144 pixels, or 18 rows tall.
// During vblank, the PPU will be on tile row 18.
// While the tile row will reset to 0 when starting a new frame, the buffer index to be written carries across frames.
// Since 18 / 4 has a remaninder of 2, this means the buffer index can be either buffer 0 or buffer 2 at the start of a new frame.
//
// It should be possible to read the buffer for the first row tiles when the PPU position reaches tile row 1, meaning tile row 0 was just fully drawn?
//
// The safest position to read appears the index immediately before the write position, since it gives the most time read the row without being written over.
// If the SNES side can keep up fast, maybe could do 2 rows behind and read both without re-checking PPU position, but seems potentially more risky. Hmm.
const ppu_position @ 0x6000 : u8;
let PPU_POSITION_TILE_ROW_MASK = 0xF8;
let PPU_POSITION_TILE_ROW_SHIFT = 3;
let PPU_POSITION_BUFFER_INDEX_MASK = 0x3;
// Selects which of the buffers 0 .. 3 to read from, and resets the position in the buffer.
writeonly read_buffer_index @ 0x6001 : u8;
// Port to read the next value from the VRAM. The GB screen is 160 pixels, or 20 columns wide.
// The data port will have 2 bytes/row * 8 rows/tile * 20 tiles = 320 bytes of data for a given buffer.
const read_data @ 0x7800 : u8;
}
namespace command {
const ready @ 0x6002 : u8;
const data @ 0x7000 : [u8; 16];
}
namespace joy {
namespace bit {
let RIGHT = 0;
let LEFT = 1;
let UP = 2;
let DOWN = 3;
let A = 4;
let B = 5;
let SELECT = 6;
let START = 7;
}
namespace mask {
let RIGHT = 0x01;
let LEFT = 0x02;
let UP = 0x04;
let DOWN = 0x08;
let A = 0x10;
let B = 0x20;
let SELECT = 0x40;
let START = 0x80;
}
writeonly data1 @ 0x6004 : u8;
writeonly data2 @ 0x6005 : u8;
writeonly data3 @ 0x6006 : u8;
writeonly data4 @ 0x6007 : u8;
}
writeonly ctrl @ 0x6003 : u8;
let CTRL_RESET = 0x80;
let CTRL_JOY_MODE_4P = 0x20;
let CTRL_JOY_MODE_2P = 0x10;
let CTRL_JOY_MODE_1P = 0x00;
let CTRL_SPEED_VERY_SLOW = 0x03;
let CTRL_SPEED_SLOW = 0x02;
let CTRL_SPEED_NORMAL = 0x01;
let CTRL_SPEED_FAST = 0x00;
const version @ 0x600F : u8;
}import os
import os.path
import PIL.Image
def write_chr(w, h, data, f):
for y in range(0, h, 8):
for x in range(0, w, 8):
for j in range(8):
# Write bit 0 of all columns in this row.
c = 0
for i in range(8):
c = (c * 2) | (data[x + i, y + j] & 1)
f.write(bytearray([c]))
# Write bit 1 of all columns in this row.
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, y + j] >> 1) & 1)
f.write(bytearray([c]))
for j in range(8):
# Write bit 2 of all columns in this row.
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, y + j] >> 2) & 1)
f.write(bytearray([c]))
# Write bit 3 of all columns in this row.
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, y + j] >> 3) & 1)
f.write(bytearray([c]))
if __name__ == '__main__':
import sys
if len(sys.argv) > 1:
WIDTH = 128
HEIGHT = None
for arg in range(1, len(sys.argv)):
filename = sys.argv[arg]
if filename[0] == '-':
if filename == '-oldfart':
HEIGHT = 192
elif filename == '-newfart':
HEIGHT = None
else:
exit('Invalid argument `' + filename + '`.')
continue
try:
img = PIL.Image.open(filename)
except IOError as e:
if os.path.isdir(filename):
exit(filename + ' is a directory.')
if os.path.exists(filename):
exit(filename + ' has an unsupported filetype, or you lack permission to open it.')
else:
exit('File ' + filename + ' does not exist!')
w, h = img.size
if w != WIDTH or h % 8 != 0 or HEIGHT and h != HEIGHT:
exit('Image ' + filename + ' is not ' + str(WIDTH) + 'x' + str(HEIGHT) + ' pixels in size.')
if not img.palette:
exit('Image ' + filename + ' has no palette.')
data = img.load()
save_filename = os.path.splitext(filename)[0] + '.chr'
try:
f = open(save_filename, 'wb')
except Exception as e:
exit('Failure attempting to write ' + save_filename)
write_chr(w, h, data, f)
f.close()
print(' ' + filename + ' -> ' + save_filename)
else:
print('Usage: ' + sys.argv[0] + ' file [file...]')
print('Converts files like foo.png into SNES-friendly formats like foo.chr')
<EFBFBD>PNG

IHDR<00><00>1|<7C>,tEXtCreation TimeTue 15 Feb 2011 18:41:59 -0500<30><12><>tIME<07>$<10><>T<EFBFBD> pHYs
<EFBFBD>
<EFBFBD>B<>4<EFBFBD>gAMA<00><> <0B>a0PLTE#I<00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
pVZIDATx<54><78>V<EFBFBD>b<EFBFBD> <0C><><EFBFBD>xc<78>Wa<57>Ư<EFBFBD><C6AF><EFBFBD>'<27><><EFBFBD><EFBFBD>7<EFBFBD><1E>i<EFBFBD><04>lˆ<10><><EFBFBD>m
<EFBFBD><EFBFBD><>~<7E>W <0A>D<>juV<75>U<>("> <20>Aj<41><6A>;p<>Q0<0F>]pI#&/]<5D><>0cK<63>T<EFBFBD><54><EFBFBD><EFBFBD>,<2C>ߖ<EFBFBD><DF96><EFBFBD>"x<><78><EFBFBD>n<EFBFBD><6E>9<EFBFBD><39><00>Ԫ<>C<EFBFBD>+clv&<00><><1A>+<2B> @<40><>f<EFBFBD>՗<EFBFBD><11><02>à<1E><><00><><EFBFBD><EFBFBD><17>w<EFBFBD><77>t<EFBFBD>;<3B>bc<62>ej<05><><EFBFBD> <0B>o<><6F>|_<><5F>$<24>T<EFBFBD>]<5D>r<EFBFBD>[6<>P[U<><55><EFBFBD><EFBFBD><EFBFBD>l <0A>
QK<EFBFBD><1D>s<EFBFBD><08>:<3A>Z?<3F>r<EFBFBD>-<2D><00>gfj <20>%^<5E>#<23>!<08>.<2E><>p<EFBFBD>X0<58>ӈ<EFBFBD><17>|Qbb)<29>dwfF-"<1E><1D><04>%|O<>N}<7D>'SK<00>L<EFBFBD>P<><50>CC<43><43>/^<5E><><EFBFBD>0<EFBFBD><03><>Q<EFBFBD>
c<EFBFBD>4V<EFBFBD><EFBFBD>i\F<><46>G<EFBFBD> q<00>><3E>E<10><><EFBFBD>Tg<54>c{<7B>D<EFBFBD><44>{<7B><05><><00>\<5C>J*J><3E>J<EFBFBD>7<EFBFBD><37><17><>1<EFBFBD>d<EFBFBD><64><00> <10>Re<52>>+ <12><>h<EFBFBD>ۅ<EFBFBD><DB85>u<EFBFBD>/s<>u<>V<EFBFBD>^<5E><17>̣<EFBFBD>+<2B><>J<19><><EFBFBD>A<04><>t<EFBFBD>T<EFBFBD><54>^(Y<><59><EFBFBD><EFBFBD>Ƣ<EFBFBD><C6A2>ԯ,<<3C><>I]<02><><EFBFBD><04>}|w<><77>)C`?<3F>Ϙ<EFBFBD>tto<><6F>-V^<5E><EFBFBD><E4BABC>̢<EFBFBD><CCA2>A!<21><><EFBFBD>qA<71><41><EFBFBD>cU<63>d<EFBFBD>6PE-5P`m<00>8<EFBFBD>+y<>)_@<40>0TJ<0F>@<40>6d<10>O<EFBFBD>a<EFBFBD>/<2F><>R1<><31><14> ki<19><> <09>E#d<><64>4<EFBFBD><0E>թ<EFBFBD> <0A>A <05><>l<EFBFBD> <0B><><03><>05<30>|<00><>ӟ2.<05><>
#;<3B>
<EFBFBD>=<3D>X<17>GCN<43>AL<41>'<27><>y@<40>ǎJ2<4A><32><EFBFBD><07>i<EFBFBD> 5Ép<C389>v <0C>My<4D><&h<><68>baaÊޙtY<11>%~[ܯ<><DCAF>p$a<>n F<><02><><EFBFBD>AQ"e<>`p0<70>ة <0A><><07><>0<EFBFBD>P<EFBFBD>Ip<49><70>7<EFBFBD><37><EFBFBD><EFBFBD> <09><>ŋ<EFBFBD><C58B><EFBFBD>xy h.
<00><>B<EFBFBD>@}<7D><><04><>gW<67><06>h
<EFBFBD>z<63><CFB0>GE<1E>pAb<41>{"<22><>"[<04>[<10><><EFBFBD><10>d] `<05><>u<EFBFBD><75>2<EFBFBD><06><1A><> ubJ<62><4A><04><05>D/<2F><>_<EFBFBD><5F><EFBFBD><EFBFBD>><3E><>
<EFBFBD><EFBFBD>8<EFBFBD>Ť>\T<1E><><EFBFBD>;<13>-<2D><><EFBFBD>" <0B>2<EFBFBD><32><19>M<EFBFBD>Ϟ;<3B><>><3E>L<EFBFBD><4C>S<0E><><13><>ꤒE<EAA492>w<><77><EFBFBD><EFBFBD>oLK>:<3A><>b<EFBFBD><62><00>|!mc^h<13><><EFBFBD>gx<>kag<06>EѱY<D1B1>n<EFBFBD><6E>xt<11><08>9<19>;;<3B>v<EFBFBD><01><18>U<EFBFBD><55><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><1C><05>o8,<2C><><EFBFBD>ё<EFBFBD><D191><00>YX[R<11> <0A>^?<3F>҃<><D283><EFBFBD>h<><68>}\2<><32>*}<10> <0C><><00><>c<EFBFBD>
7>P M6cg<63>'<06><><EFBFBD>Nn:<3A><><EFBFBD>.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><02>D<>J2<4A><08><>1<03><><64>*q><3E>zT<>lk <0C>a<EFBFBD><61>+<2B><1D><><EFBFBD>n<EFBFBD>pv<70>#<10><><EFBFBD><EFBFBD><EFBFBD>)^<5E>u<EFBFBD><75>B<EFBFBD>{<7B>|<7C>
;A<EFBFBD><EFBFBD>T8%<25><>!|<04><> m<><6D><EFBFBD><EFBFBD><15><>!Lغ<1B>LLφ]·w5<0F><>{=<00><><EFBFBD>lNl<4E>}u+<02>í<EFBFBD>|8<>e@<40>FPD<50>n<EFBFBD>l<EFBFBD><00><><EFBFBD><EFBFBD>1<0F>K<EFBFBD><4B><07>Py
ˈ<EFBFBD>J) <0B>2p,<2C><>η3T<33><54>/<2F><><EFBFBD>ʶ<EFBFBD>j<EFBFBD>7<EFBFBD>A<EFBFBD><08><>8:<04><>i<EFBFBD><69>9<1F><>8<EFBFBD><38><EFBFBD><EFBFBD>QN<51>n<EFBFBD> D&<00>&b<><04><><EFBFBD>π8Ӓ<38><03>}B<><42>Np<4E>1Y8@<40><><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD><EFBFBD><07><><EFBFBD>s<EFBFBD><03><>IEND<4E>B`<60><>PNG

IHDR<00><00>%<25><>tIME<07>%<06>Ѭ<EFBFBD> pHYs
<EFBFBD>
<EFBFBD>B<>4<EFBFBD>gAMA<00><> <0B>a0PLTE<00><00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD>O&I<01>IDATxڅS<DA85><53><EFBFBD> <08> <09> <09>;<3B><>K<EFBFBD><4B><EFBFBD>j<EFBFBD>W<EFBFBD><57><18>D<11>"}Jw<4A><77>?q<><71>s<<3C><><EFBFBD> <0A><><EFBFBD>1<EFBFBD><EFBFBD>ebe <0B><><EFBFBD>`<13>! <0C><>@<40>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD><01><><EFBFBD><EFBFBD>8<EFBFBD><38>#<23><>#<23>%<03><><EFBFBD><EFBFBD>`<60><>p<EFBFBD>lg:<1A><><EFBFBD><14><>J<00>L03<30>*l<> *<2A><><EFBFBD>|<7C>Qq<51><71>#<23>a+8v<38>l<EFBFBD><EFBFBD><E18CB1> #<16>K<EFBFBD>񵘫|<7C><>=<3D><><02>CL<><4C><EFBFBD><EFBFBD>g2<67>i<EFBFBD><69><EFBFBD>@<40>n<EFBFBD>S<07>G8<47><38>T<1A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>/} <20>Boz<6F>ž<EFBFBD><C29E><01><>5<EFBFBD><11>Mq<> =<3D><><EFBFBD><EFBFBD>Ⱥʵp<11><16><><EFBFBD><EFBFBD>=<19>}<7D><18>w;R<><52><EFBFBD>B<EFBFBD>O<EFBFBD>V2o1<6F><31>9<><39><12>b!<21><> <0C><><EFBFBD>M0<4D><30><EFBFBD><EFBFBD>JTD<54><44><EFBFBD>J#<23><>1<EFBFBD>]<1E><><EFBFBD><EFBFBD><EFBFBD>"<22>Y<EFBFBD>w =<3D><1F><> <18>7<EFBFBD>x<><78><EFBFBD>,X<><58>#O <20>w={<15><>('<27>L<EFBFBD><4C><EFBFBD>Z`<60><><EFBFBD><EFBFBD>8u><3E>x<EFBFBD><78>I<>co@<40>
<EFBFBD><EFBFBD>r<EFBFBD><EFBFBD>7<EFBFBD><02>J%n_t<5F><74>.^<5E><1C><>|#ZQ<5A>XH<58><48><EFBFBD><75> m<><6D><EFBFBD>f<>y%mtIEND<4E>B`<60>88|L<><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>d|8888LL<4C><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dd88888<<<88<<||<7C><><EFBFBD>><|`<60><><EFBFBD><EFBFBD><EFBFBD>||<7C><><<``<60><><EFBFBD><EFBFBD>||<7C><><EFBFBD>><><06><><EFBFBD>||||<7C><><<<06><>||<<|l<><6C><EFBFBD><EFBFBD><EFBFBD> <<ll<6C><6C><EFBFBD><EFBFBD> <00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><06><><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><06><><<|`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<<``<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD> 8000000<00><> 000000||<7C><><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD>~~ |xx||<7C><><EFBFBD><EFBFBD>~~ xx88|l<><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>88ll<6C><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~~~~~~~~~<06><><EFBFBD><EFBFBD><EFBFBD>||<06><><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>zz||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>zz<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD>|~<06><><EFBFBD>||||<7C><><EFBFBD><EFBFBD>||<06><>||~~~~~<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||88<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||88<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD>||8||<7C><><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD>||88||<7C><><EFBFBD><EFBFBD>ffffff~<<ffffff<<<00><><EFBFBD><8xp<78><70><EFBFBD><EFBFBD><EFBFBD><00><>88pp<70><70><EFBFBD><EFBFBD><00>PNG

IHDR<00><00>1|<7C>tIME<07>%+ <0B><>[ pHYs
<EFBFBD>
<EFBFBD>B<>4<EFBFBD>gAMA<00><> <0B>a0PLTE<00><00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD>O&I<01>IDATx<54><78>SK<53>,!<08><13>'<27><><EFBFBD><EFBFBD><13><12>~<7E><>z<16>%]<5D><><1A><>H<EFBFBD>P(
w<EFBFBD><12>K<EFBFBD><4B>7<EFBFBD><37><19><16>iC<1F>$6<>b<EFBFBD><62>ch<63>CF<43><46><EFBFBD><EFBFBD><EFBFBD>`߀l}<7D><>v<EFBFBD>U<EFBFBD><55><EFBFBD><EFBFBD> <01>Ǻ<EFBFBD><1A>X<EFBFBD><0F><>L<EFBFBD>&C<><43><EFBFBD>. <0B><><EFBFBD>q<EFBFBD><71>Z<><16>\]I@<40>I6G<><47><EFBFBD><19>G4<47>rd<72><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>J<02><>{^1pf0<66>CzL8<1F>k>V<><0E>=<3D><><04><>Bg<12><>P$<24>J{<7B><02><>i<EFBFBD>:<3A>6}c<>[<5B>qL<71>x<><7F>D<><44>M<EFBFBD>[<5B>be;du<64>{x<>?d<><1E>h<EFBFBD><68>$<24><>ʵ~p<><70>&<26><11><>=<14>}<7D> <20><>;<3B><04><08><>ga? Z<>y<EFBFBD><79><EFBFBD>!Ps<50><73>$>Ob<O<>9<EFBFBD><39>q<EFBFBD><71>ڏ<> V<>ϱֲFr<46>zvy<76><79>o<EFBFBD>G8<47>`Eb?<3F><>C<EFBFBD><43><EFBFBD>?\q#/<04>ۚ<EFBFBD><73>I<02><><EFBFBD><EFBFBD>-<13>I<EFBFBD><49>`<60><>|l<> <0B><>AAo1<6F><31><EFBFBD>ƛ<EFBFBD><C69B>H<EFBFBD>;<3B><>H]<5D><><EFBFBD><EFBFBD>5<EFBFBD>ͶA<CDB6><41>__t<5F><74>/]<5D><><EFBFBD><EFBFBD><EFBFBD>F4<46>zS!<21><>KW<4B>1<EFBFBD><31>7<>׆
<EFBFBD>B<EFBFBD>P(
<EFBFBD>B<EFBFBD>P(
<EFBFBD><EFBFBD><1F>yB<79>&IEND<4E>B`<60>88|L<><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>d|8888LL<4C><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dd88888<<<88<<||<7C><><EFBFBD>><|`<60><><EFBFBD><EFBFBD><EFBFBD>||<7C><><<``<60><><EFBFBD><EFBFBD>||<7C><><EFBFBD>><><06><><EFBFBD>||||<7C><><<<06><>||<<|l<><6C><EFBFBD><EFBFBD><EFBFBD> <<ll<6C><6C><EFBFBD><EFBFBD> <00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><06><><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><06><><<|`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<<``<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD> 8000000<00><> 000000||<7C><><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD>~~ |xx||<7C><><EFBFBD><EFBFBD>~~ xx88|l<><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>88ll<6C><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~~~~~~~~~<06><><EFBFBD><EFBFBD><EFBFBD>||<06><><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>zz||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>zz<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD>|~<06><><EFBFBD>||||<7C><><EFBFBD><EFBFBD>||<06><>||~~~~~<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||88<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||88<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD>||8||<7C><><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD>||88||<7C><><EFBFBD><EFBFBD>ffffff~<<ffffff<<<00><><EFBFBD><8xp<78><70><EFBFBD><EFBFBD><EFBFBD><00><>88pp<70><70><EFBFBD><EFBFBD>
namespace ppu {
extern writeonly brightness @ 0x2100 : u8;
let BRIGHTNESS_FORCE_BLANK = 0x80;
let BRIGHTNESS_MASK = 0x7F;
extern writeonly obj_control @ 0x2101 : u8;
let OBJ_CONTROL_8x8_16x16 = 0;
let OBJ_CONTROL_8x8_32x32 = 1;
let OBJ_CONTROL_8x8_64x64 = 2;
let OBJ_CONTROL_16x16_32x32 = 3;
let OBJ_CONTROL_16x16_64x64 = 4;
let OBJ_CONTROL_32x32_64x64 = 5;
let OBJ_CONTROL_16x32_32x64 = 6;
let OBJ_CONTROL_16x32_32x32 = 7;
extern writeonly oam_address_l @ 0x2102 : u8;
extern writeonly oam_address_h @ 0x2103 : u8;
extern writeonly oam_address_hl @ 0x2103 : u16;
extern writeonly oam_write_data @ 0x2104 : u8;
extern const oam_read_data @ 0x2138 : u8;
extern writeonly bg_mode @ 0x2105 : u8;
let BG_MODE_MASK = 0x07;
let BG_MODE_MODE1_BG3_PRIORITY = 0x08;
let BG_MODE_BG1_16x16 = 0x10;
let BG_MODE_BG2_16x16 = 0x20;
let BG_MODE_BG3_16x16 = 0x40;
let BG_MODE_BG4_16x16 = 0x80;
extern writeonly mosaic @ 0x2106 : u8;
let MOSAIC_ENABLE_BG1 = 0x01;
let MOSAIC_ENABLE_BG2 = 0x02;
let MOSAIC_ENABLE_BG3 = 0x04;
let MOSAIC_ENABLE_BG4 = 0x08;
extern writeonly bg1_tilemap @ 0x2107 : u8;
extern writeonly bg2_tilemap @ 0x2108 : u8;
extern writeonly bg3_tilemap @ 0x2109 : u8;
extern writeonly bg4_tilemap @ 0x210A : u8;
let BG_TILEMAP_MIRROR_X = 0x01;
let BG_TILEMAP_MIRROR_Y = 0x02;
let BG_TILEMAP_ADDRESS_SHIFT_LEFT = 2;
let BG_TILEMAP_ADDRESS_BIT_ALIGN = 10;
extern writeonly bg12_tileset @ 0x210B : u8;
let BG_TILESET_ADDRESS_BIT_ALIGN = 12;
let BG12_TILESET_ADDRESS_BG2_SHIFT = 4;
let BG12_TILESET_ADDRESS_BG1_SHIFT = 0;
extern writeonly bg34_tileset @ 0x210C : u8;
let BG34_TILESET_ADDRESS_BG3_SHIFT = 4;
let BG34_TILESET_ADDRESS_BG4_SHIFT = 0;
extern writeonly bg1_scroll_x @ 0x210D : u8; // 2x write
extern writeonly bg1_scroll_y @ 0x210E : u8; // 2x write
extern writeonly bg2_scroll_x @ 0x210F : u8; // 2x write
extern writeonly bg2_scroll_y @ 0x2110 : u8; // 2x write
extern writeonly bg3_scroll_x @ 0x2111 : u8; // 2x write
extern writeonly bg3_scroll_y @ 0x2112 : u8; // 2x write
extern writeonly bg4_scroll_x @ 0x2113 : u8; // 2x write
extern writeonly bg4_scroll_y @ 0x2114 : u8; // 2x write
extern writeonly vram_control @ 0x2115 : u8;
let VRAM_CONTROL_INCREMENT_1 = 0x00;
let VRAM_CONTROL_INCREMENT_32 = 0x01;
let VRAM_CONTROL_INCREMENT_128 = 0x02;
let VRAM_CONTROL_REMAP_MODE_0 = 0x00;
let VRAM_CONTROL_REMAP_MODE_1 = 0x04;
let VRAM_CONTROL_REMAP_MODE_2 = 0x08;
let VRAM_CONTROL_REMAP_MODE_3 = 0x0C;
let VRAM_CONTROL_SIZE_1 = 0x00;
let VRAM_CONTROL_SIZE_2 = 0x80;
extern writeonly vram_address_l @ 0x2116 : u8;
extern writeonly vram_address_h @ 0x2117 : u8;
extern writeonly vram_address_hl @ 0x2116 : u16;
extern writeonly vram_write_data_l @ 0x2118 : u8;
extern writeonly vram_write_data_h @ 0x2119 : u8;
extern writeonly vram_write_data_hl @ 0x2118 : u16;
extern const vram_read_data_l @ 0x2139 : u8;
extern const vram_read_data_h @ 0x213A : u8;
extern const vram_read_data_hl @ 0x2139 : u16;
extern writeonly mode7_control @ 0x211A : u8;
let MODE7_CONTROL_FIELD_SIZE_NORMAL = 0x00;
let MODE7_CONTROL_FIELD_SIZE_HUGE = 0x80;
let MODE7_CONTROL_EMPTY_TRANSPARENT_FILL = 0x00;
let MODE7_CONTROL_EMPTY_TILE_FILL = 0x40;
let MODE7_CONTROL_MIRROR_X = 0x01;
let MODE7_CONTROL_MIRROR_Y = 0x02;
extern writeonly mode7_a @ 0x211B : u8; // 2x write
extern writeonly mode7_b @ 0x211C : u8; // 2x write
extern writeonly mode7_c @ 0x211D : u8; // 2x write
extern writeonly mode7_d @ 0x211E : u8; // 2x write
extern writeonly mode7_center_x @ 0x211F : u8; // 2x write
extern writeonly mode7_center_y @ 0x2120 : u8; // 2x write
extern writeonly cgram_address @ 0x2121 : u8;
extern writeonly cgram_write_data @ 0x2122 : u8; // 2x write
extern const cgram_read_data @ 0x213B : u8; // 2x read
extern writeonly win_bg12_control @ 0x2123 : u8;
let WIN_BG12_CONTROL_BG1_INVERT_WIN1 = 0x01;
let WIN_BG12_CONTROL_BG1_ENABLE_WIN1 = 0x02;
let WIN_BG12_CONTROL_BG1_INVERT_WIN2 = 0x04;
let WIN_BG12_CONTROL_BG1_ENABLE_WIN2 = 0x08;
let WIN_BG12_CONTROL_BG2_INVERT_WIN1 = 0x10;
let WIN_BG12_CONTROL_BG2_ENABLE_WIN1 = 0x20;
let WIN_BG12_CONTROL_BG2_INVERT_WIN2 = 0x40;
let WIN_BG12_CONTROL_BG2_ENABLE_WIN2 = 0x80;
extern writeonly win_bg34_control @ 0x2124 : u8;
let WIN_BG34_CONTROL_BG3_INVERT_WIN1 = 0x01;
let WIN_BG34_CONTROL_BG3_ENABLE_WIN1 = 0x02;
let WIN_BG34_CONTROL_BG3_INVERT_WIN2 = 0x04;
let WIN_BG34_CONTROL_BG3_ENABLE_WIN2 = 0x08;
let WIN_BG34_CONTROL_BG4_INVERT_WIN1 = 0x10;
let WIN_BG34_CONTROL_BG4_ENABLE_WIN1 = 0x20;
let WIN_BG34_CONTROL_BG4_INVERT_WIN2 = 0x40;
let WIN_BG34_CONTROL_BG4_ENABLE_WIN2 = 0x80;
extern writeonly win_obj_control @ 0x2125 : u8;
let WIN_OBJ_CONTROL_OBJ_INVERT_WIN1 = 0x01;
let WIN_OBJ_CONTROL_OBJ_ENABLE_WIN1 = 0x02;
let WIN_OBJ_CONTROL_OBJ_INVERT_WIN2 = 0x04;
let WIN_OBJ_CONTROL_OBJ_ENABLE_WIN2 = 0x08;
let WIN_OBJ_CONTROL_BACKDROP_INVERT_WIN1 = 0x10;
let WIN_OBJ_CONTROL_BACKDROP_ENABLE_WIN1 = 0x20;
let WIN_OBJ_CONTROL_BACKDROP_INVERT_WIN2 = 0x40;
let WIN_OBJ_CONTROL_BACKDROP_ENABLE_WIN2 = 0x80;
extern writeonly win1_left @ 0x2126 : u8;
extern writeonly win1_right @ 0x2127 : u8;
extern writeonly win2_left @ 0x2128 : u8;
extern writeonly win2_right @ 0x2129 : u8;
extern writeonly win_bg_operators @ 0x212A : u8;
let WIN_OPERATOR_OR = 0;
let WIN_OPERATOR_AND = 1;
let WIN_OPERATOR_XOR = 2;
let WIN_OPERATOR_XNOR = 3;
let WIN_BG_OPERATORS_BG4_SHIFT = 6;
let WIN_BG_OPERATORS_BG3_SHIFT = 4;
let WIN_BG_OPERATORS_BG2_SHIFT = 2;
let WIN_BG_OPERATORS_BG1_SHIFT = 0;
extern writeonly win_obj_operators @ 0x212B : u8;
let WIN_OBJ_OPERATORS_OBJ_SHIFT = 2;
let WIN_OBJ_OPERATORS_BACKDROP_SHIFT = 0;
extern writeonly screen_enable_mask @ 0x212C : u8;
extern writeonly screen_window_mask @ 0x212E : u8;
extern writeonly sub_screen_enable_mask @ 0x212D : u8;
extern writeonly sub_screen_window_mask @ 0x212F : u8;
let SCREEN_ENABLE_BG1 = 0x01;
let SCREEN_ENABLE_BG2 = 0x02;
let SCREEN_ENABLE_BG3 = 0x04;
let SCREEN_ENABLE_BG4 = 0x08;
let SCREEN_ENABLE_OBJ = 0x10;
extern writeonly color_control @ 0x2130 : u8;
let COLOR_CONTROL_CLIP_INNER = 0x80;
let COLOR_CONTROL_CLIP_OUTER = 0x40;
let COLOR_CONTROL_DISABLE_BLEND_INNER = 0x20;
let COLOR_CONTROL_DISABLE_BLEND_OUTER = 0x10;
let COLOR_CONTROL_USE_SUBSCREEN = 0x02;
let COLOR_CONTROL_DIRECT_MODE = 0x01;
extern writeonly color_math @ 0x2131 : u8;
let COLOR_MATH_ENABLE_MASK = 0x3F;
let COLOR_MATH_HALVE = 0x20;
let COLOR_MATH_ADD = 0x00;
let COLOR_MATH_SUB = 0x20;
extern writeonly color_fill @ 0x2132 : u8;
let COLOR_FILL_INTENSITY_MASK = 0x1F;
let COLOR_FILL_R = 0x20;
let COLOR_FILL_G = 0x40;
let COLOR_FILL_B = 0x80;
extern writeonly video_control @ 0x2133 : u8;
let VIDEO_CONTROL_EXTERNAL_SYNC = 0x80;
let VIDEO_CONTROL_MODE7_EXTBG = 0x40;
let VIDEO_CONTROL_PSEUDO_HIRES = 0x08;
let VIDEO_CONTROL_OVERSCAN = 0x04;
let VIDEO_CONTROL_OBJ_INTERLACE = 0x02;
let VIDEO_CONTROL_SCREEN_INTERLACE = 0x01;
extern writeonly hvcount_latch @ 0x2137 : u8;
extern const hcount @ 0x213C : u8; // 2x read
extern const vcount @ 0x213D : u8; // 2x read
extern const status77 @ 0x213E : u8;
let STATUS77_TIME_OVER_MASK = 0x80;
let STATUS77_RANGE_OVER_MASK = 0x40;
let STATUS77_MASTER_MASK = 0x20;
let STATUS77_5C77_VERSION_MASK = 0xF;
let STATUS77_TIME_OVER_BIT = 7;
let STATUS77_RANGE_OVER_BIT = 6;
let STATUS77_MASTER_BIT = 5;
extern const status78 @ 0x213F : u8;
let STATUS78_INTERLACE_FIELD_MASK = 0x80;
let STATUS78_EXTERNAL_LATCH_MASK = 0x40;
let STATUS78_PAL_MODE_MASK = 0x10;
let STATUS78_5C78_VERSION_MASK = 0xF;
let STATUS78_INTERLACE_FIELD_BIT = 7;
let STATUS78_EXTERNAL_LATCH_BIT = 6;
let STATUS78_PAL_MODE_BIT = 4;
extern writeonly hcount_trigger_l @ 0x4207 : u8;
extern writeonly hcount_trigger_h @ 0x4208 : u8;
extern writeonly hcount_trigger_hl @ 0x4207 : u16;
extern writeonly vcount_trigger_l @ 0x4209 : u8;
extern writeonly vcount_trigger_h @ 0x420A : u8;
extern writeonly vcount_trigger_hl @ 0x4209 : u16;
extern writeonly irq_enable @ 0x4200 : u8;
let IRQ_ENABLE_NMI = 0x80;
let IRQ_ENABLE_IRQ_ON_HCOUNT = 0x20;
let IRQ_ENABLE_IRQ_ON_VCOUNT = 0x10;
let IRQ_ENABLE_AUTOJOY = 0x01;
extern const nmi_flag @ 0x4210 : u8;
let NMI_FLAG_NMI_ACTIVE_MASK = 0x80;
let NMI_FLAG_5A22_VERSION_MASK = 0xF;
let NMI_FLAG_NMI_ACTIVE_BIT = 7;
extern const irq_status @ 0x4211 : u8;
let IRQ_STATUS_IRQ_ACTIVE_MASK = 0x80;
let IRQ_STATUS_IRQ_ACTIVE_BIT = 7;
extern const hvbjoy_status @ 0x4212 : u8;
let HVBJOY_STATUS_VBLANK_MASK = 0x80;
let HVBJOY_STATUS_HBLANK_MASK = 0x40;
let HVBJOY_STATUS_AUTOJOY_MASK = 0x01;
let HVBJOY_STATUS_VBLANK_BIT = 7;
let HVBJOY_STATUS_HBLANK_BIT = 6;
let HVBJOY_STATUS_AUTOJOY_BIT = 0;
}
namespace apu {
extern writeonly output0 @ 0x2140 : u8;
extern writeonly output1 @ 0x2141 : u8;
extern writeonly output2 @ 0x2142 : u8;
extern writeonly output3 @ 0x2143 : u8;
extern writeonly output10 @ 0x2140 : u16;
extern writeonly output21 @ 0x2141 : u16;
extern writeonly output32 @ 0x2142 : u16;
extern const input0 @ 0x2140 : u8;
extern const input1 @ 0x2141 : u8;
extern const input2 @ 0x2142 : u8;
extern const input3 @ 0x2143 : u8;
extern const input10 @ 0x2140 : u16;
extern const input21 @ 0x2141 : u16;
extern const input32 @ 0x2142 : u16;
}
namespace wram {
extern var data @ 0x2180 : u8;
extern writeonly address_l @ 0x2181 : u8;
extern writeonly address_h @ 0x2182 : u8;
extern writeonly address_bank @ 0x2183 : u8;
extern writeonly address_hl @ 0x2181 : u16;
}
namespace joy {
namespace bit_l {
let R = 4;
let L = 5;
let X = 6;
let A = 7;
}
namespace bit_h {
let RIGHT = 0;
let LEFT = 1;
let DOWN = 2;
let UP = 3;
let START = 4;
let SELECT = 5;
let Y = 6;
let B = 7;
}
namespace mask_l {
let R = 0x10;
let L = 0x20;
let X = 0x40;
let A = 0x80;
}
namespace mask_h {
let RIGHT = 0x01;
let LEFT = 0x02;
let DOWN = 0x04;
let UP = 0x08;
let START = 0x10;
let SELECT = 0x20;
let Y = 0x40;
let B = 0x80;
}
extern writeonly output @ 0x4016 : u8;
extern const input1 @ 0x4016 : u8;
extern const input2 @ 0x4017 : u8;
extern const pad1_l @ 0x4218 : u8;
extern const pad1_h @ 0x4219 : u8;
extern const pad2_l @ 0x421A : u8;
extern const pad2_h @ 0x421B : u8;
extern const pad3_l @ 0x421C : u8;
extern const pad3_h @ 0x421D : u8;
extern const pad4_l @ 0x421E : u8;
extern const pad4_h @ 0x421F : u8;
extern const pad1_hl @ 0x4218 : u16;
extern const pad2_hl @ 0x421A : u16;
extern const pad3_hl @ 0x421C : u16;
extern const pad4_hl @ 0x421E : u16;
}
namespace io {
extern writeonly output @ 0x4201 : u8;
extern const input @ 0x4213 : u8;
}
// i16 x i8 -> i24 multiplier. Only available with mode-7 disabled.
// Write left, then right. Result should be available immediately.
namespace multiply_i16i8 {
extern writeonly left @ 0x211B : u8; // 2x write
extern writeonly right @ 0x211C : u8;
extern const result_l @ 0x2134 : u8;
extern const result_m @ 0x2135 : u8;
extern const result_h @ 0x2136 : u8;
extern const result_ml @ 0x2134 : u16;
extern const result_hm @ 0x2135 : u16;
}
// u8 x u8 -> u16 multiplier.
// Write left, then right.
// 8 machine cycles (~48 master cycles) after right is set, the result may be read.
namespace multiply_u8u8 {
extern writeonly left @ 0x4202 : u8;
extern writeonly right @ 0x4203 : u8;
extern const result_l @ 0x4216 : u8;
extern const result_h @ 0x4217 : u8;
extern const result_hl @ 0x4216 : u16;
}
// u16 / u8 -> (u16, u16) divider.
// Write left, then right.
// 16 machine cycles (~96 master cycles) after right is set, the result may be read.
namespace divider {
extern writeonly left_l @ 0x4204 : u8;
extern writeonly left_h @ 0x4205 : u8;
extern writeonly left_hl @ 0x4204 : u16;
extern writeonly right @ 0x4206 : u8;
extern const div_result_l @ 0x4214 : u8;
extern const div_result_h @ 0x4215 : u8;
extern const div_result_hl @ 0x4214 : u16;
extern const mod_result_l @ 0x4216 : u8;
extern const mod_result_h @ 0x4217 : u8;
extern const mod_result_hl @ 0x4216 : u16;
}
namespace rom {
extern writeonly speed @ 0x420D : u8;
let SPEED_SLOW = 0;
let SPEED_FAST = 1;
}
namespace dma {
extern writeonly mdma_enable @ 0x420B : u8;
extern writeonly hdma_enable @ 0x420C : u8;
let ENABLE_0 = 0b00000001;
let ENABLE_1 = 0b00000010;
let ENABLE_2 = 0b00000100;
let ENABLE_3 = 0b00001000;
let ENABLE_4 = 0b00010000;
let ENABLE_5 = 0b00100000;
let ENABLE_6 = 0b01000000;
let ENABLE_7 = 0b10000000;
let CONTROL_MODE_MASK = 0x07;
let CONTROL_MODE_A = 0x00;
let CONTROL_MODE_AB = 0x01;
let CONTROL_MODE_AA = 0x02;
let CONTROL_MODE_AABB = 0x03;
let CONTROL_MODE_ABCD = 0x04;
let CONTROL_MODE_ABAB = 0x05;
let CONTROL_MDMA_DECREMENT = 0x10;
let CONTROL_MDMA_NO_INCREMENT = 0x08;
let CONTROL_HDMA_INDIRECT_MODE = 0x40;
let CONTROL_READ_PPU = 0x80;
let HDMA_LINE_COUNTER_COUNT_MASK = 0x7F;
let HDMA_LINE_COUNTER_REPEATED = 0x80;
}
namespace dma0 {
extern writeonly control @ 0x4300 : u8;
extern writeonly mdma_dest @ 0x4301 : u8;
extern writeonly src_address_l @ 0x4302 : u8;
extern writeonly src_address_h @ 0x4303 : u8;
extern writeonly src_address_bank @ 0x4304 : u8;
extern writeonly src_address_hl @ 0x4302 : u16;
extern writeonly mdma_size_l @ 0x4305 : u8;
extern writeonly mdma_size_h @ 0x4306 : u8;
extern writeonly mdma_size_hl @ 0x4305 : u16;
extern writeonly hdma_indirect_address_l @ 0x4305 : u8;
extern writeonly hdma_indirect_address_h @ 0x4306 : u8;
extern writeonly hdma_indirect_address_bank @ 0x4307 : u8;
extern writeonly hdma_indirect_address_hl @ 0x4305 : u16;
extern writeonly hdma_table_address_l @ 0x4308 : u8;
extern writeonly hdma_table_address_h @ 0x4309 : u8;
extern writeonly hdma_table_address_hl @ 0x4308 : u16;
extern writeonly hdma_line_counter @ 0x430A : u8;
}
namespace dma1 {
extern writeonly control @ 0x4310 : u8;
extern writeonly mdma_dest @ 0x4311 : u8;
extern writeonly src_address_l @ 0x4312 : u8;
extern writeonly src_address_h @ 0x4313 : u8;
extern writeonly src_address_bank @ 0x4314 : u8;
extern writeonly src_address_hl @ 0x4312 : u16;
extern writeonly mdma_size_l @ 0x4315 : u8;
extern writeonly mdma_size_h @ 0x4316 : u8;
extern writeonly mdma_size_hl @ 0x4315 : u16;
extern writeonly hdma_indirect_address_l @ 0x4315 : u8;
extern writeonly hdma_indirect_address_h @ 0x4316 : u8;
extern writeonly hdma_indirect_address_bank @ 0x4317 : u8;
extern writeonly hdma_indirect_address_hl @ 0x4315 : u16;
extern writeonly hdma_table_address_l @ 0x4318 : u8;
extern writeonly hdma_table_address_h @ 0x4319 : u8;
extern writeonly hdma_table_address_hl @ 0x4318 : u16;
extern writeonly hdma_line_counter @ 0x431A : u8;
}
namespace dma2 {
extern writeonly control @ 0x4320 : u8;
extern writeonly mdma_dest @ 0x4321 : u8;
extern writeonly src_address_l @ 0x4322 : u8;
extern writeonly src_address_h @ 0x4323 : u8;
extern writeonly src_address_bank @ 0x4324 : u8;
extern writeonly src_address_hl @ 0x4322 : u16;
extern writeonly mdma_size_l @ 0x4325 : u8;
extern writeonly mdma_size_h @ 0x4326 : u8;
extern writeonly mdma_size_hl @ 0x4325 : u16;
extern writeonly hdma_indirect_address_l @ 0x4325 : u8;
extern writeonly hdma_indirect_address_h @ 0x4326 : u8;
extern writeonly hdma_indirect_address_bank @ 0x4327 : u8;
extern writeonly hdma_indirect_address_hl @ 0x4325 : u16;
extern writeonly hdma_table_address_l @ 0x4328 : u8;
extern writeonly hdma_table_address_h @ 0x4329 : u8;
extern writeonly hdma_table_address_hl @ 0x4328 : u16;
extern writeonly hdma_line_counter @ 0x432A : u8;
}
namespace dma3 {
extern writeonly control @ 0x4330 : u8;
extern writeonly mdma_dest @ 0x4331 : u8;
extern writeonly src_address_l @ 0x4332 : u8;
extern writeonly src_address_h @ 0x4333 : u8;
extern writeonly src_address_bank @ 0x4334 : u8;
extern writeonly src_address_hl @ 0x4332 : u16;
extern writeonly mdma_size_l @ 0x4335 : u8;
extern writeonly mdma_size_h @ 0x4336 : u8;
extern writeonly mdma_size_hl @ 0x4335 : u16;
extern writeonly hdma_indirect_address_l @ 0x4335 : u8;
extern writeonly hdma_indirect_address_h @ 0x4336 : u8;
extern writeonly hdma_indirect_address_bank @ 0x4337 : u8;
extern writeonly hdma_indirect_address_hl @ 0x4335 : u16;
extern writeonly hdma_table_address_l @ 0x4338 : u8;
extern writeonly hdma_table_address_h @ 0x4339 : u8;
extern writeonly hdma_table_address_hl @ 0x4338 : u16;
extern writeonly hdma_line_counter @ 0x433A : u8;
}
namespace dma4 {
extern writeonly control @ 0x4340 : u8;
extern writeonly mdma_dest @ 0x4341 : u8;
extern writeonly src_address_l @ 0x4342 : u8;
extern writeonly src_address_h @ 0x4343 : u8;
extern writeonly src_address_bank @ 0x4344 : u8;
extern writeonly src_address_hl @ 0x4342 : u16;
extern writeonly mdma_size_l @ 0x4345 : u8;
extern writeonly mdma_size_h @ 0x4346 : u8;
extern writeonly mdma_size_hl @ 0x4345 : u16;
extern writeonly hdma_indirect_address_l @ 0x4345 : u8;
extern writeonly hdma_indirect_address_h @ 0x4346 : u8;
extern writeonly hdma_indirect_address_bank @ 0x4347 : u8;
extern writeonly hdma_indirect_address_hl @ 0x4345 : u16;
extern writeonly hdma_table_address_l @ 0x4348 : u8;
extern writeonly hdma_table_address_h @ 0x4349 : u8;
extern writeonly hdma_table_address_hl @ 0x4348 : u16;
extern writeonly hdma_line_counter @ 0x434A : u8;
}
namespace dma5 {
extern writeonly control @ 0x4350 : u8;
extern writeonly mdma_dest @ 0x4351 : u8;
extern writeonly src_address_l @ 0x4352 : u8;
extern writeonly src_address_h @ 0x4353 : u8;
extern writeonly src_address_bank @ 0x4354 : u8;
extern writeonly src_address_hl @ 0x4352 : u16;
extern writeonly mdma_size_l @ 0x4355 : u8;
extern writeonly mdma_size_h @ 0x4356 : u8;
extern writeonly mdma_size_hl @ 0x4355 : u16;
extern writeonly hdma_indirect_address_l @ 0x4355 : u8;
extern writeonly hdma_indirect_address_h @ 0x4356 : u8;
extern writeonly hdma_indirect_address_bank @ 0x4357 : u8;
extern writeonly hdma_indirect_address_hl @ 0x4355 : u16;
extern writeonly hdma_table_address_l @ 0x4358 : u8;
extern writeonly hdma_table_address_h @ 0x4359 : u8;
extern writeonly hdma_table_address_hl @ 0x4358 : u16;
extern writeonly hdma_line_counter @ 0x435A : u8;
}
namespace dma6 {
extern writeonly control @ 0x4360 : u8;
extern writeonly mdma_dest @ 0x4361 : u8;
extern writeonly src_address_l @ 0x4362 : u8;
extern writeonly src_address_h @ 0x4363 : u8;
extern writeonly src_address_bank @ 0x4364 : u8;
extern writeonly src_address_hl @ 0x4362 : u16;
extern writeonly mdma_size_l @ 0x4365 : u8;
extern writeonly mdma_size_h @ 0x4366 : u8;
extern writeonly mdma_size_hl @ 0x4365 : u16;
extern writeonly hdma_indirect_address_l @ 0x4365 : u8;
extern writeonly hdma_indirect_address_h @ 0x4366 : u8;
extern writeonly hdma_indirect_address_bank @ 0x4367 : u8;
extern writeonly hdma_indirect_address_hl @ 0x4365 : u16;
extern writeonly hdma_table_address_l @ 0x4368 : u8;
extern writeonly hdma_table_address_h @ 0x4369 : u8;
extern writeonly hdma_table_address_hl @ 0x4368 : u16;
extern writeonly hdma_line_counter @ 0x436A : u8;
}
namespace dma7 {
extern writeonly control @ 0x4370 : u8;
extern writeonly mdma_dest @ 0x4371 : u8;
extern writeonly src_address_l @ 0x4372 : u8;
extern writeonly src_address_h @ 0x4373 : u8;
extern writeonly src_address_bank @ 0x4374 : u8;
extern writeonly src_address_hl @ 0x4372 : u16;
extern writeonly mdma_size_l @ 0x4375 : u8;
extern writeonly mdma_size_h @ 0x4376 : u8;
extern writeonly mdma_size_hl @ 0x4375 : u16;
extern writeonly hdma_indirect_address_l @ 0x4375 : u8;
extern writeonly hdma_indirect_address_h @ 0x4376 : u8;
extern writeonly hdma_indirect_address_bank @ 0x4377 : u8;
extern writeonly hdma_indirect_address_hl @ 0x4375 : u16;
extern writeonly hdma_table_address_l @ 0x4378 : u8;
extern writeonly hdma_table_address_h @ 0x4379 : u8;
extern writeonly hdma_table_address_hl @ 0x4378 : u16;
extern writeonly hdma_line_counter @ 0x437A : u8;
}
}
@@@@<00> <00><00><00><00><><EFBFBD><EFBFBD><EFBFBD><00><><<<00><><EFBFBD><EFBFBD><<3C><><00><<<00><00><00><00><00><00><00><00><00><00>ll<6C><6C><EFBFBD><EFBFBD><EFBFBD>||88ll<6C><6C><EFBFBD><EFBFBD>||88<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>xr0 Hv<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>x~0<60000<00>||88080|<00>||8833<33><33><00><>33<33><33>ș<>;<00>~~:~:<3A><><EFBFBD>D|88<00><02>:<3A>:<3A><><EFBFBD>DD88UP<55><50><EFBFBD><EFBFBD><EFBFBD>pp PR<50><52><EFBFBD><EFBFBD>pp >6<7F>N<EFBFBD>J<EFBFBD>$<24>Z<EFBFBD>l|66N~J~$<Z~ll<00>v<EFBFBD><76><EFBFBD><EFBFBD><EFBFBD><08>ڇ<EFBFBD><DA87><EFBFBD><EFBFBD>vvv<76><76><EFBFBD><EFBFBD>~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>vv<76>~<7E>B<EFBFBD>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~~BBBB<42><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~BBBZ<18><NN~~<7E><$$<<~N<>~<7E>~<00><1E>R<EFBFBD>^<5E>^<5E>@<40>R^^^^^@~>qP<71>P<EFBFBD>x~F&<00><00>P<EFBFBD>P\xx><18>qP<71>P<EFBFBD><50><EFBFBD>Ñ<00><00>P<EFBFBD>P\<5C><><EFBFBD><EFBFBD>n<><00><00><<3C><><EFBFBD><EFBFBD>O~<00><00>~<<<3C><><EFBFBD><EFBFBD>3<>fB<66>Z<EFBFBD><<3C>C<EFBFBD><43><EFBFBD><EFBFBD>~<00>B<EFBFBD>ZZ<<CC<43><43><EFBFBD><EFBFBD><$B<<ZZ~<ZB<00>~<~<18><00><00>~<<<3C><><EFBFBD><EFBFBD><<<<<3C><><EFBFBD><EFBFBD><<<<~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~<<<<~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~<<<3C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD>~<<3C>Z<EFBFBD>Z<EFBFBD><00>Ã<><C383><EFBFBD><<ZZZZ~g<><67><EFBFBD><EFBFBD>p<>D@V~~Z~<<3C>A<EFBFBD><41>~@<40><04><18>Z<EFBFBD><<3C>AC<41><43>(D<00><00><00>|88|8|<10>~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~<<<<~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~<<<<~~<7E><><EFBFBD><EFBFBD>88pp||88>8|p<>|<7C>8|><<<<,,<<~<~,~~Z @@@@< ~@<40>@<40><02><02>~<<00><><EFBFBD><EFBFBD>``~<03><01><00><00><><EFBFBD><EFBFBD><EFBFBD>`~<00><> B<><42>!<00>B (  f<00><00>`<<00~<00><<3C><<3C>$<24><00><00><<~<~$~B<~~<00><<3C><00><00><00><00><<3C><<~BBB~<~<~$B<00><00>~<7E>f<EFBFBD>f<EFBFBD><~<00>~~ffff<~<<3C>~BZ<00><<~~<00><00><00><00><00><00><00><00><00><00>ZZZZ~~<$$~~tt>>66~~tt>>66~t>6<00><00><00><00><<<00>B~~<00><00><00>$<<00><00><00><00>~<00><00><00>~B<<00><1F><><EFBFBD>~<7E><03>I<EFBFBD><00><1F><>~~II~<00><><00><1F><><EFBFBD>~<7E><01>H<EFBFBD><1F><>~~HJ<00><> FP<10>98
b`<60><> y??8<7F><08>`<60><><EFBFBD><EFBFBD><<00>@<40><><EFBFBD><EFBFBD><EFBFBD>~<00><00><00>@|<7C><><EFBFBD><EFBFBD> <0C><><EFBFBD>~<7E><><EFBFBD>~<7E><00>A<EFBFBD><41><EFBFBD> <0C><>~~<7E><>~~A]<5D><> <0C><<3C><><EFBFBD>f<00><00>~<7E><><EFBFBD><EFBFBD><<<3C><><<00>~~~<7E><><EFBFBD>ǂ<00>m<00><00><00><00>|:<00><00>8s~<8DZ~&$8<8DZ~<R<8<<<,<FB~f$n88<$<<FZ~f$v8<$<$B~BI?<<6>>>>>>>>>B<00><00><00>Z<00><00>3<~ZZ$A<00><B<00><00><00>!<Z~<00><00><<<00><00><00>@<Z<00><00><?B<00><00>ZZ<<<~<00>ZZZ<5A><<3C><00><00>8x0<78>`<60><><EFBFBD>`x0800``<60><>``00>>*>>**+F<00>1<00>9<00>$H<00>D"dH0p80<>~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD><5A><EFBFBD> ~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ZZ<5A><5A>~<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>BBZZBB~~~~~BBZZBB~~~<00><00><00><00><00><00>~<7E>UUUUU|<00><00><00><00><00><00><00>>66><|8||866668888B$<00>~<18>Z<EFBFBD><"3<00><00>~<18>ZZ<=<00><00><>~<7E><><EFBFBD><EFBFBD><EFBFBD>€?>?3~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۀ<EFBFBD>><3E>3<EFBFBD>s<00>Z<EFBFBD><5A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>X ZZ<5A><5A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>XXB@<40><><EFBFBD><EFBFBD>}<00><><00><>@|<7C><><EFBFBD><EFBFBD><00><><EFBFBD><00><><EFBFBD><00><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>??<3F><><1E><1F><1F><1F>??<3F><>``ss77<37><37><EFBFBD><EFBFBD>__``ss77<37><37><EFBFBD><EFBFBD>__8<00>M<00><00>|<00><00>|<00>|<00><08>Z<EFBFBD>Z<EFBFBD><<<<3C>nZZZZ<<<<<<nn<<<<ff<66><66>ff<f<<3C>f<<ff<66><66>ff<66><66>55\\<5C>Ճ<EFBFBD><00><>55\|<7C><><EFBFBD><EFBFBD><01>~<00><><EFBFBD><EFBFBD>BBBBJJZZnn<6E><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD>BBBBJJZZnn<6E><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>сՁՁ<D581><D581><EFBFBD> <00><00> <00><00>`8<00><00>P<EFBFBD> <20>[ZYX<59>PT 8|Z<>X<EFBFBD>|<7C>n<EFBFBD><6E><EFBFBD><EFBFBD><EFBFBD><15><00><><EFBFBD>~n~<7E><><EFBFBD><EFBFBD><15><00><>~~<7E><00><00><00><00><00><00><00>|J~B~R~<00><><00><><EFBFBD><EFBFBD>$$<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD>$<24><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00>p<EFBFBD>0<EFBFBD>p<EFBFBD>]"pp0|pr""ZBBZZZBBBBZZZZBBBBZZ
// TODO: variables in I/O space? instead of io_write/io_read, just use like a register/variable.
namespace sms {
namespace mapper {
extern var control @ 0xFFFC : u8;
let CONTROL_ROM_WRITE = 0x80;
let CONTROL_RAM_ENABLE_C000 = 0x10;
let CONTROL_RAM_ENABLE_8000 = 0x08;
let CONTROL_RAM_SELECT = 0x04;
let CONTROL_ROM_BANK_SHIFT_MASK = 0x03;
extern var rom_0000 @ 0xFFFD : u8;
extern var rom_4000 @ 0xFFFE : u8;
extern var rom_8000 @ 0xFFFF : u8;
}
namespace io {
namespace vdp {
let data = 0xBE;
let control = 0xBF;
let vcount = 0x7E;
let hcount = 0x7F;
// Writing to the control port lets you access one of the following through the data port.
let CONTROL_ACCESS_VRAM_READ = 0x00;
let CONTROL_ACCESS_VRAM_WRITE = 0x40;
let CONTROL_ACCESS_REGISTER = 0x80;
let CONTROL_ACCESS_CRAM = 0xC0;
// Reading the control port gives back VDP status.
let CONTROL_STATUS_BIT_VBLANK = 7;
let CONTROL_STATUS_BIT_SPRITE_OVERFLOW = 6;
let CONTROL_STATUS_BIT_SPRITE_COLLISION = 5;
let CONTROL_STATUS_MASK_VBLANK = 0x80;
let CONTROL_STATUS_MASK_SPRITE_OVERFLOW = 0x40;
let CONTROL_STATUS_MASK_SPRITE_COLLISION = 0x20;
let CONTROL_STATUS_MASK_FIFTH_SPRITE = 0x1F;
}
namespace memory {
let control = 0x3E;
let CONTROL_EXPANSION_DISABLE = 0x80;
let CONTROL_CARTRIDGE_DISABLE = 0x40;
let CONTROL_CARD_DISABLE = 0x20;
let CONTROL_RAM_DISABLE = 0x10;
let CONTROL_BIOS_DISABLE = 0x04;
let CONTROL_DEVICE_DISABLE = 0x02;
}
namespace device {
let control = 0x3F;
let CONTROL_OUTPUT_B_TH = 0x80;
let CONTROL_OUTPUT_B_TR = 0x40;
let CONTROL_OUTPUT_A_TH = 0x20;
let CONTROL_OUTPUT_A_TR = 0x10;
let CONTROL_ENABLE_INPUT_B_TH = 0x08;
let CONTROL_ENABLE_INPUT_B_TR = 0x04;
let CONTROL_ENABLE_INPUT_A_TH = 0x02;
let CONTROL_ENABLE_INPUT_A_TR = 0x01;
let input = 0xDC;
let INPUT_BIT_B_DOWN = 7;
let INPUT_BIT_B_UP = 6;
let INPUT_BIT_A_TR = 5;
let INPUT_BIT_A_TL = 4;
let INPUT_BIT_A_RIGHT = 3;
let INPUT_BIT_A_LEFT = 2;
let INPUT_BIT_A_DOWN = 1;
let INPUT_BIT_A_UP = 0;
let INPUT_MASK_B_DOWN = 0x80;
let INPUT_MASK_B_UP = 0x40;
let INPUT_MASK_A_TR = 0x20;
let INPUT_MASK_A_TL = 0x10;
let INPUT_MASK_A_RIGHT = 0x08;
let INPUT_MASK_A_LEFT = 0x04;
let INPUT_MASK_A_DOWN = 0x02;
let INPUT_MASK_A_UP = 0x01;
let input2 = 0xDD;
let INPUT2_BIT_B_TH = 7;
let INPUT2_BIT_A_TH = 6;
let INPUT2_BIT_CARTRIDGE_SLOT_PIN = 5;
let INPUT2_BIT_RESET = 4;
let INPUT2_BIT_B_TR = 3;
let INPUT2_BIT_B_TL = 2;
let INPUT2_BIT_B_LEFT = 1;
let INPUT2_BIT_B_RIGHT = 0;
let INPUT2_MASK_B_TH = 0x80;
let INPUT2_MASK_A_TH = 0x40;
let INPUT2_MASK_CARTRIDGE_SLOT_PIN = 0x20;
let INPUT2_MASK_RESET = 0x10;
let INPUT2_MASK_B_TR = 0x08;
let INPUT2_MASK_B_TL = 0x04;
let INPUT2_MASK_B_LEFT = 0x02;
let INPUT2_MASK_B_RIGHT = 0x01;
}
namespace psg {
let output = 0x7F;
}
namespace fm {
let output = 0xF0;
let output2 = 0xF1;
let status = 0xF2;
let STATUS_BIT_CONNECTED = 0;
let STATUS_MASK_CONNECTED = 0x01;
}
namespace gg {
let state = 0x00;
let STATE_BIT_START_BUTTON = 7;
let STATE_BIT_REGION = 6;
let STATE_MASK_START_BUTTON = 0x80;
let STATE_MASK_REGION = 0x40;
let pan = 0x06;
let PAN_LEFT_MASK = 0x40;
let PAN_LEFT_SHIFT = 4;
let PAN_RIGHT_MASK = 0x04;
let PAN_RIGHT_SHIFT = 0;
namespace link {
let raw_direction = 0x02;
let raw_data = 0x03;
let status = 0x05;
let STATUS_BIT_NOT_CONNECTED = 2;
let STATUS_BIT_RECEIVE_BUSY = 1;
let STATUS_BIT_SEND_BUSY = 0;
let STATUS_MASK_ENABLE = 0x38;
let STATUS_MASK_NOT_CONNECTED = 0x04;
let STATUS_MASK_RECEIVE_BUSY = 0x02;
let STATUS_MASK_SEND_BUSY = 0x01;
let send = 0x03;
let receive = 0x04;
}
}
}
namespace glasses {
extern var control @ 0xFFF8 : u8;
}
// VDP registers
namespace vdp {
let mode_control = 0x80;
let MODE_CONTROL_VLOCK = 0x80;
let MODE_CONTROL_HLOCK = 0x40;
let MODE_CONTROL_HIDE_LEFTMOST = 0x20;
let MODE_CONTROL_SCANLINE_IRQ = 0x10;
let MODE_CONTROL_SPRITE_SHIFT = 0x08;
let MODE_CONTROL_MODE4 = 0x04;
let MODE_CONTROL_MODE2 = 0x02;
let MODE_CONTROL_DEFAULT_MASK = MODE_CONTROL_MODE4 | MODE_CONTROL_MODE2;
let mode_control2 = 0x81;
let MODE_CONTROL2_ENABLE = 0x40;
let MODE_CONTROL2_VBLANK_IRQ = 0x20;
let MODE_CONTROL2_MODE1 = 0x10;
let MODE_CONTROL2_MODE3 = 0x08;
let MODE_CONTROL2_MODE5 = 0x04;
let MODE_CONTROL2_SPRITE_8x16 = 0x02;
let MODE_CONTROL2_SPRITE_STRETCH = 0x01;
let MODE_CONTROL2_DEFAULT_MASK = 0x80;
let nametable_address = 0x82;
let palette_address = 0x83;
let pattern_address = 0x84;
let sprite_attribute_address = 0x85;
let sprite_pattern_address = 0x86;
let overscan_color = 0x87;
let scroll_x = 0x88;
let scroll_y = 0x89;
let line_counter = 0x8A;
}
}
<EFBFBD>PNG

IHDR<00><00>1|<7C>,tEXtCreation TimeTue 15 Feb 2011 18:41:59 -0500<30><12><>tIME<07>$<10><>T<EFBFBD> pHYs
<EFBFBD>
<EFBFBD>B<>4<EFBFBD>gAMA<00><> <0B>a0PLTE#I<00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
pVZIDATx<54><78>V<EFBFBD>b<EFBFBD> <0C><><EFBFBD>xc<78>Wa<57>Ư<EFBFBD><C6AF><EFBFBD>'<27><><EFBFBD><EFBFBD>7<EFBFBD><1E>i<EFBFBD><04>lˆ<10><><EFBFBD>m
<EFBFBD><EFBFBD><>~<7E>W <0A>D<>juV<75>U<>("> <20>Aj<41><6A>;p<>Q0<0F>]pI#&/]<5D><>0cK<63>T<EFBFBD><54><EFBFBD><EFBFBD>,<2C>ߖ<EFBFBD><DF96><EFBFBD>"x<><78><EFBFBD>n<EFBFBD><6E>9<EFBFBD><39><00>Ԫ<>C<EFBFBD>+clv&<00><><1A>+<2B> @<40><>f<EFBFBD>՗<EFBFBD><11><02>à<1E><><00><><EFBFBD><EFBFBD><17>w<EFBFBD><77>t<EFBFBD>;<3B>bc<62>ej<05><><EFBFBD> <0B>o<><6F>|_<><5F>$<24>T<EFBFBD>]<5D>r<EFBFBD>[6<>P[U<><55><EFBFBD><EFBFBD><EFBFBD>l <0A>
QK<EFBFBD><1D>s<EFBFBD><08>:<3A>Z?<3F>r<EFBFBD>-<2D><00>gfj <20>%^<5E>#<23>!<08>.<2E><>p<EFBFBD>X0<58>ӈ<EFBFBD><17>|Qbb)<29>dwfF-"<1E><1D><04>%|O<>N}<7D>'SK<00>L<EFBFBD>P<><50>CC<43><43>/^<5E><><EFBFBD>0<EFBFBD><03><>Q<EFBFBD>
c<EFBFBD>4V<EFBFBD><EFBFBD>i\F<><46>G<EFBFBD> q<00>><3E>E<10><><EFBFBD>Tg<54>c{<7B>D<EFBFBD><44>{<7B><05><><00>\<5C>J*J><3E>J<EFBFBD>7<EFBFBD><37><17><>1<EFBFBD>d<EFBFBD><64><00> <10>Re<52>>+ <12><>h<EFBFBD>ۅ<EFBFBD><DB85>u<EFBFBD>/s<>u<>V<EFBFBD>^<5E><17>̣<EFBFBD>+<2B><>J<19><><EFBFBD>A<04><>t<EFBFBD>T<EFBFBD><54>^(Y<><59><EFBFBD><EFBFBD>Ƣ<EFBFBD><C6A2>ԯ,<<3C><>I]<02><><EFBFBD><04>}|w<><77>)C`?<3F>Ϙ<EFBFBD>tto<><6F>-V^<5E><EFBFBD><E4BABC>̢<EFBFBD><CCA2>A!<21><><EFBFBD>qA<71><41><EFBFBD>cU<63>d<EFBFBD>6PE-5P`m<00>8<EFBFBD>+y<>)_@<40>0TJ<0F>@<40>6d<10>O<EFBFBD>a<EFBFBD>/<2F><>R1<><31><14> ki<19><> <09>E#d<><64>4<EFBFBD><0E>թ<EFBFBD> <0A>A <05><>l<EFBFBD> <0B><><03><>05<30>|<00><>ӟ2.<05><>
#;<3B>
<EFBFBD>=<3D>X<17>GCN<43>AL<41>'<27><>y@<40>ǎJ2<4A><32><EFBFBD><07>i<EFBFBD> 5Ép<C389>v <0C>My<4D><&h<><68>baaÊޙtY<11>%~[ܯ<><DCAF>p$a<>n F<><02><><EFBFBD>AQ"e<>`p0<70>ة <0A><><07><>0<EFBFBD>P<EFBFBD>Ip<49><70>7<EFBFBD><37><EFBFBD><EFBFBD> <09><>ŋ<EFBFBD><C58B><EFBFBD>xy h.
<00><>B<EFBFBD>@}<7D><><04><>gW<67><06>h
<EFBFBD>z<63><CFB0>GE<1E>pAb<41>{"<22><>"[<04>[<10><><EFBFBD><10>d] `<05><>u<EFBFBD><75>2<EFBFBD><06><1A><> ubJ<62><4A><04><05>D/<2F><>_<EFBFBD><5F><EFBFBD><EFBFBD>><3E><>
<EFBFBD><EFBFBD>8<EFBFBD>Ť>\T<1E><><EFBFBD>;<13>-<2D><><EFBFBD>" <0B>2<EFBFBD><32><19>M<EFBFBD>Ϟ;<3B><>><3E>L<EFBFBD><4C>S<0E><><13><>ꤒE<EAA492>w<><77><EFBFBD><EFBFBD>oLK>:<3A><>b<EFBFBD><62><00>|!mc^h<13><><EFBFBD>gx<>kag<06>EѱY<D1B1>n<EFBFBD><6E>xt<11><08>9<19>;;<3B>v<EFBFBD><01><18>U<EFBFBD><55><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><1C><05>o8,<2C><><EFBFBD>ё<EFBFBD><D191><00>YX[R<11> <0A>^?<3F>҃<><D283><EFBFBD>h<><68>}\2<><32>*}<10> <0C><><00><>c<EFBFBD>
7>P M6cg<63>'<06><><EFBFBD>Nn:<3A><><EFBFBD>.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><02>D<>J2<4A><08><>1<03><><64>*q><3E>zT<>lk <0C>a<EFBFBD><61>+<2B><1D><><EFBFBD>n<EFBFBD>pv<70>#<10><><EFBFBD><EFBFBD><EFBFBD>)^<5E>u<EFBFBD><75>B<EFBFBD>{<7B>|<7C>
;A<EFBFBD><EFBFBD>T8%<25><>!|<04><> m<><6D><EFBFBD><EFBFBD><15><>!Lغ<1B>LLφ]·w5<0F><>{=<00><><EFBFBD>lNl<4E>}u+<02>í<EFBFBD>|8<>e@<40>FPD<50>n<EFBFBD>l<EFBFBD><00><><EFBFBD><EFBFBD>1<0F>K<EFBFBD><4B><07>Py
ˈ<EFBFBD>J) <0B>2p,<2C><>η3T<33><54>/<2F><><EFBFBD>ʶ<EFBFBD>j<EFBFBD>7<EFBFBD>A<EFBFBD><08><>8:<04><>i<EFBFBD><69>9<1F><>8<EFBFBD><38><EFBFBD><EFBFBD>QN<51>n<EFBFBD> D&<00>&b<><04><><EFBFBD>π8Ӓ<38><03>}B<><42>Np<4E>1Y8@<40><><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD><EFBFBD><07><><EFBFBD>s<EFBFBD><03><>IEND<4E>B`<60><>PNG

IHDR<00><00>1|<7C>tIME<07>%+ <0B><>[ pHYs
<EFBFBD>
<EFBFBD>B<>4<EFBFBD>gAMA<00><> <0B>a0PLTE<00><00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD>O&I<01>IDATx<54><78>SK<53>,!<08><13>'<27><><EFBFBD><EFBFBD><13><12>~<7E><>z<16>%]<5D><><1A><>H<EFBFBD>P(
w<EFBFBD><12>K<EFBFBD><4B>7<EFBFBD><37><19><16>iC<1F>$6<>b<EFBFBD><62>ch<63>CF<43><46><EFBFBD><EFBFBD><EFBFBD>`߀l}<7D><>v<EFBFBD>U<EFBFBD><55><EFBFBD><EFBFBD> <01>Ǻ<EFBFBD><1A>X<EFBFBD><0F><>L<EFBFBD>&C<><43><EFBFBD>. <0B><><EFBFBD>q<EFBFBD><71>Z<><16>\]I@<40>I6G<><47><EFBFBD><19>G4<47>rd<72><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>J<02><>{^1pf0<66>CzL8<1F>k>V<><0E>=<3D><><04><>Bg<12><>P$<24>J{<7B><02><>i<EFBFBD>:<3A>6}c<>[<5B>qL<71>x<><7F>D<><44>M<EFBFBD>[<5B>be;du<64>{x<>?d<><1E>h<EFBFBD><68>$<24><>ʵ~p<><70>&<26><11><>=<14>}<7D> <20><>;<3B><04><08><>ga? Z<>y<EFBFBD><79><EFBFBD>!Ps<50><73>$>Ob<O<>9<EFBFBD><39>q<EFBFBD><71>ڏ<> V<>ϱֲFr<46>zvy<76><79>o<EFBFBD>G8<47>`Eb?<3F><>C<EFBFBD><43><EFBFBD>?\q#/<04>ۚ<EFBFBD><73>I<02><><EFBFBD><EFBFBD>-<13>I<EFBFBD><49>`<60><>|l<> <0B><>AAo1<6F><31><EFBFBD>ƛ<EFBFBD><C69B>H<EFBFBD>;<3B><>H]<5D><><EFBFBD><EFBFBD>5<EFBFBD>ͶA<CDB6><41>__t<5F><74>/]<5D><><EFBFBD><EFBFBD><EFBFBD>F4<46>zS!<21><>KW<4B>1<EFBFBD><31>7<>׆
<EFBFBD>B<EFBFBD>P(
<EFBFBD>B<EFBFBD>P(
<EFBFBD><EFBFBD><1F>yB<79>&IEND<4E>B`<60>import os
import os.path
import PIL.Image
def write_chr(w, h, data, f):
for y in range(0, h, 8):
for x in range(0, w, 8):
for j in range(8):
# Write low bits of this row.
c = 0
for i in range(8):
c = (c * 2) | (data[x + i, y + j] & 1)
f.write(bytearray([c]))
# Write second bits of this row.
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, y + j] >> 1) & 1)
f.write(bytearray([c]))
# Write third bits of this row.
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, y + j] >> 2) & 1)
f.write(bytearray([c]))
# Write high bits of this row.
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, y + j] >> 3) & 1)
f.write(bytearray([c]))
if __name__ == '__main__':
import sys
if len(sys.argv) > 1:
WIDTH = 128
HEIGHT = None
for arg in range(1, len(sys.argv)):
filename = sys.argv[arg]
if filename[0] == '-':
if filename == '-oldfart':
HEIGHT = 192
elif filename == '-newfart':
HEIGHT = None
else:
exit('Invalid argument `' + filename + '`.')
continue
try:
img = PIL.Image.open(filename)
except IOError as e:
if os.path.isdir(filename):
exit(filename + ' is a directory.')
if os.path.exists(filename):
exit(filename + ' has an unsupported filetype, or you lack permission to open it.')
else:
exit('File ' + filename + ' does not exist!')
w, h = img.size
if w != WIDTH or h % 8 != 0 or HEIGHT and h != HEIGHT:
exit('Image ' + filename + ' is not ' + str(WIDTH) + 'x' + str(HEIGHT) + ' pixels in size.')
if not img.palette:
exit('Image ' + filename + ' has no palette.')
data = img.load()
save_filename = os.path.splitext(filename)[0] + '.chr'
try:
f = open(save_filename, 'wb')
except Exception as e:
exit('Failure attempting to write ' + save_filename)
write_chr(w, h, data, f)
f.close()
print(' ' + filename + ' -> ' + save_filename)
else:
print('Usage: ' + sys.argv[0] + ' file [file...]')
print('Converts files like foo.png into Game Gear-friendly formats like foo.chr')
8888|LLL<4C><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ddd|888888888<<<<<||||<7C><><EFBFBD><EFBFBD><EFBFBD>><<<|```<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD>><<<><06><><EFBFBD><EFBFBD><EFBFBD>||||<<<<|lll<6C><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><06><><EFBFBD><EFBFBD><EFBFBD><<<<|```<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<00><><EFBFBD><EFBFBD><EFBFBD> 8000000000000||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~~~ |xxxx8888|lll<6C><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~~~~~~~~~<06><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>zzzz<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|||~<06><><EFBFBD><EFBFBD><EFBFBD>||||~~~~~<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||8888<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||888||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ffffffffffff~<<<<<00><><EFBFBD><EFBFBD><EFBFBD><888xppp<70><70><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
import os
import os.path
import PIL.Image
'''
NES:
def write_chr(w, h, data, f):
for y in range(0, h, 16):
for x in range(0, w, 8):
# Copy low bits of each 8x8 chunk into the first 8x8 plane.
for j in range(8):
c = 0
for i in range(8):
c = (c * 2) | (data[x + i, y + j] & 1)
f.write(chr(c))
# Copy high bits of each chunk into the second 8x8 plane.
for j in range(8):
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, y + j] >> 1) & 1)
f.write(chr(c))
# Copy low bits of each 8x8 chunk into the first 8x8 plane.
for j in range(8):
c = 0
for i in range(8):
c = (c * 2) | (data[x + i, (y + 8) + j] & 1)
f.write(chr(c))
# Copy high bits of each chunk into the second 8x8 plane.
for j in range(8):
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, (y + 8) + j] >> 1) & 1)
f.write(chr(c))
'''
def write_chr(w, h, data, f):
for y in range(0, h, 16):
for x in range(0, w, 8):
for j in range(16):
# Write low bits of this row.
c = 0
for i in range(8):
c = (c * 2) | (data[x + i, y + j] & 1)
f.write(bytearray([c]))
# Write second bits of this row.
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, y + j] >> 1) & 1)
f.write(bytearray([c]))
# Write third bits of this row.
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, y + j] >> 2) & 1)
f.write(bytearray([c]))
# Write high bits of this row.
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, y + j] >> 3) & 1)
f.write(bytearray([c]))
if __name__ == '__main__':
import sys
if len(sys.argv) > 1:
WIDTH = 128
HEIGHT = None
for arg in range(1, len(sys.argv)):
filename = sys.argv[arg]
if filename[0] == '-':
if filename == '-oldfart':
HEIGHT = 192
elif filename == '-newfart':
HEIGHT = None
else:
exit('Invalid argument `' + filename + '`.')
continue
try:
img = PIL.Image.open(filename)
except IOError as e:
if os.path.isdir(filename):
exit(filename + ' is a directory.')
if os.path.exists(filename):
exit(filename + ' has an unsupported filetype, or you lack permission to open it.')
else:
exit('File ' + filename + ' does not exist!')
w, h = img.size
if w != WIDTH or h % 8 != 0 or HEIGHT and h != HEIGHT:
exit('Image ' + filename + ' is not ' + str(WIDTH) + 'x' + str(HEIGHT) + ' pixels in size.')
if not img.palette:
exit('Image ' + filename + ' has no palette.')
data = img.load()
save_filename = os.path.splitext(filename)[0] + '.chr'
try:
f = open(save_filename, 'wb')
except Exception as e:
exit('Failure attempting to write ' + save_filename)
write_chr(w, h, data, f)
f.close()
print(' ' + filename + ' -> ' + save_filename)
else:
print('Usage: ' + sys.argv[0] + ' file [file...]')
print('Converts files like foo.png into Game Gear-friendly formats like foo.chr')
@@@@<00> <00><00><00><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><<3C><><EFBFBD><EFBFBD><00><<<<<00><00><00><00><00><00><00><00><00><00>llll<6C><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||8888<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>xx~r00< H6v0008000|<00><>||||88883333<33><33><EFBFBD><EFBFBD>ș<><C899><EFBFBD>;<00><00>~<02>~::<3A>~::<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DDD|8888UPPR<50><52><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>pppp >666<36>NN~<7E>JJ~<7E>$$<<3C>ZZ~<7E>lll|<00>vvv<76><76><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>vvv<76>~~~<7E>BBB<42>BBB<42><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~~B<B$B$Z<<3C><<~NNN<4E>~~~<7E><>~<00><1E>RR^<5E>^^^<5E>^^^<5E>@@~<7E>><00><00>qPP<50><50>PP\<5C>xxx~F>&<18><00><00>qPP<50><50>PP\<5C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߑn<>~<00><00><>~<7E><<<<3C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>O3<>~<00>fBB<42><42>ZZZ<5A><<<<3C>CCC<43><43><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><<Z$Z~B<<<~Z<18>B<00><00><>~~<<<<<3C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><<<<<<<<~~~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~~~<<<<<3C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~<<<<3C>ZZZ<5A>ZZZ<5A>~<7E><67><C383><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>p<>~D@@<40>V<04>~<18>~ZZ<5A>~<<<3C><>AAC<41><43><EFBFBD><EFBFBD>(D8<>|<7C>8<>||8<10>~~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~~~<<<<<<<<~~~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>>888|ppp<70>|||<7C>888|><<<<~<<<~,,,~~Z< ~@@@<40>@@@<40><02><02>~<~<03><01><00>倀<><E58080><EFBFBD><EFBFBD><EFBFBD><EFBFBD>```~B<><42><EFBFBD><EFBFBD>!<00>B ( f<00><00>`<<00~<00><<~<7E><<~<7E>$$~<7E><18>B<><<~~<00><<~<7E>B<>B<>B<>~<7E><<~<7E><<~$B<<3C>~<00><>~~~<7E>fff<66>fff<66><~<<<<3C>~~~<00>B<00>Z<00><00><><00><00>Z<>Z<>~<7E>~<7E><Z$Z$~~~~tttt>>>>6666~t>6<00>B<>~<7E><18>~<<00><00><<00><>$<00><<00><00><><18>~<7E>B<><~<00><1F><><EFBFBD><EFBFBD><EFBFBD>~~~<7E><03>III<49><04>~<00><><00><1F><><EFBFBD><EFBFBD><EFBFBD>~~~<7E><01>HHJ<48><00><> yF?P?<3F>988<38>
<08>b``<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~<<00><00><00><>@@|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <0C><><EFBFBD><EFBFBD><EFBFBD>~~~<7E><><EFBFBD><EFBFBD><EFBFBD>~~~<7E><00>AA]<5D><><EFBFBD><EFBFBD><EFBFBD> <0C><<<<3C><><EFBFBD><EFBFBD><EFBFBD><f<00><>~<7E>~~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǂ|<7C>:m<00><00><>8<>s<>~<7E><8D8Z<~&$8D8Z<~<<<R,<<F8B<~f$$<n8<F8Z<~f$$<v$B<~B<I6?>>>>>>>>>B<<3C>~<7E>Z<>ZZ$<24><1A>A3<00><B<<3C>Z<>~<00><00><><!<<00><<3C>Z<00><00><><@?B<<3C>~<00><>ZZZZZ<5A><<<<3C><00><00>8x000<30>```<60><><EFBFBD><EFBFBD><EFBFBD>```x0008>>>>***+F9<>1<00><>$H0<>pD8"dH0<>~~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ZZZ<5A><5A><EFBFBD><EFBFBD><EFBFBD>~ <00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~~BBBBZZZZBBBB~~~~~<00><00><00><00><00><00>~<7E>|U<00><00>U<00>U<00>U<00><00>U<00>>666666><|888||888B<00>$ہ~~<18><>ZZZ<5A><<="<00>3<00><>~~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E78181><EFBFBD><EFBFBD><EFBFBD>€<EFBFBD><C280>?>><3E>?33<33>s <0C>ZZZ<5A><5A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>XXXB@@|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>}<00><><EFBFBD><EFBFBD><EFBFBD><><EE9180><00><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><1E><1F><1F><1F>????<3F><><EFBFBD><EFBFBD>````ssss7777<37><37><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>____8<00>M<00><00><>|<00><>||<00><08>ZZZ<5A>ZZZ<5A><<<<<<<<<<3C>nnn<f<<<<3C>f<<<<ffff<66><66><EFBFBD><EFBFBD>ffff<66><66><EFBFBD><EFBFBD>5555\\\|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><01>~<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>BBBBBBBBJJJJZZZZnnnn<6E><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>с<EFBFBD><D181>Ձ<EFBFBD><D581>Ձ<EFBFBD><D581><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>  <0C><00><00><>`8<00><10>PPT<50> 8<>|[ZZ<5A>YXX<58><58>|<7C>nn~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><15><><00><><EFBFBD><EFBFBD><EFBFBD>~~~<7E>|<7C>J<>~<7E>B<>~<7E>R<>~<7E><00><><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>$$$<24><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00>ppp<70>00|<7C>ppr<70>"]""ZBBZZZZZBBBBBBBBZZZZ

IHDR<00><00>1|<7C>,tEXtCreation TimeTue 15 Feb 2011 18:41:59 -0500<30><12><>tIME<07>

!<21><> pHYs
<EFBFBD>
<EFBFBD>B<>4<EFBFBD>gAMA<00><> <0B>a0PLTE@@@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><00><00><00><00><00><00><00><00><00><00><00><><EFBFBD>"XIDATx<54><78>V<EFBFBD>a<EFBFBD> <0C>Ӏ <0A>h<EFBFBD><68><EFBFBD>{<7B>a^<5E>fO{<7B>ǎ <0A>H B<>2˷)̟o<CC9F>I<EFBFBD>=^5<>Z<10><><EFBFBD>Y<EFBFBD>fT<66><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><07>a<1E><> fD<66><<v<11>%<25><><EFBFBD>t<EFBFBD>Œ-]Rm>k<><6B>~[2<><1B><>A<03><><EFBFBD>;<3B>ث<00>P<><50>}<7D><><EFBFBD>ٙ<00><>j<EFBFBD><6A>'<00><><EFBFBD>EW_:F <0F>vx<76>&<02><>+<2B>^<5E><><EFBFBD><EFBFBD><EFBFBD><01> k<><6B>5<EFBFBD><35><10>?.lt<>"<22>}<7D><>w<EFBFBD><77>Rv<><76><EFBFBD>:l<>CmU<6D>~<7E><><0E>q4<71>+D-<2D>w<EFBFBD>΁"<22><><EFBFBD>k <0A><><EFBFBD>a<EFBFBD><61>О<><D09E>m<EFBFBD>B<>x񎘆 <00><>N<EFBFBD>Ic<49>dO#<23>_<EFBFBD><5F>E9<45> <09><19><><EFBFBD>ݙ<19><>x<EFBFBD>w<EFBFBD><00><>=:A<>1<EFBFBD>L- 3<>@<40>s 墿xi<78><69>¨<0E>KG<4B>+<2B><15>X<EFBFBD>W<EFBFBD>qz%<25><><01><02><>AH<41><48>R<EFBFBD><52><EFBFBD>U<EFBFBD><55>e~<7E>uܯ<03>rE*<2A>(<11><>+<2B><>@<40>_<EFBFBD><>E<EFBFBD>07@<40>J<EFBFBD>q<EFBFBD><71><EFBFBD>HTߣ<54>o&R<>;<18><>B<EFBFBD>q[<5B>zu_<75>2<EFBFBD><32><EFBFBD> +Qd<51>*ܮґS<D291>z<>d<EFBFBD><64><EFBFBD>w<1A><><EFBFBD>S<EFBFBD><53><EFBFBD><EFBFBD> 'u lBf<13><><EFBFBD><EFBFBD><EFBFBD>J<EFBFBD> <0C><><EFBFBD>?c"<22><>\<5C><>S<EFBFBD>Xy<58><79><EFBFBD><EFBFBD><EFBFBD>g2<67>ƛ<07>T<EFBFBD><54><EFBFBD><05>&B<>U <0A><><EFBFBD>@<15><>@<40><> 0<>d<EFBFBD><64>)<29>|<00><>P)]<<3C><03><><00>=@0?<3F><>e<EFBFBD><00>J <09><>2S|&<00><>e<EFBFBD>O'0<17><><EFBFBD><EFBFBD><EFBFBD>,k8W<>66@<06><48>.(<28>`V<><56><14><01>
NpF*<2A><>\+<04> b]<5D> 9Q1<><31>H{<7B><00>;*<2A><><1E> p<>q7<71> '<27>}\<5C>106<30>m𘠩{<7B><><EFBFBD> +zg<7A>eEPR<50>l<EFBFBD>mq<6D>bZÑ<5A>y<EFBFBD>5H<18>
<EFBFBD><EFBFBD>E<><45>Ƀ<EFBFBD><C983><EFBFBD>b<EFBFBD>6<.<1F>gŒC<C28C>'<27><>J<EFBFBD><10><><EFBFBD>'<08>/*2>z<><7A>1<00><>H(x<>
<EFBFBD><03><><EFBFBD>$~<7E>]<5D><1B><>)<29><>U<EFBFBD>=<3D>vy(<28><05>u<75><EE89BC>lLoAT"<22> @<40><>u1<75>$vׅ<76><D785><EFBFBD><1A>k<EFBFBD><6B>7ԉ)}<7D> ^\!<21>X<EFBFBD>~!*<2A>2<EFBFBD>̚+L<1A><><17><>pQy <0C><><EFBFBD>L <20>x<03><>, <20>L<EFBFBD>g<EFBFBD>7>{<7B>@<40><>3<>ON9[O <0C><><EFBFBD>J<16>S8<53>Q.<2E><03>1-<2D><><EFBFBD>s<EFBFBD>}<7D><03>󅴍yy<00>M(<28>w<EFBFBD> <0A><><EFBFBD><EFBFBD><EFBFBD> E<>f<EFBFBD><66>1<EFBFBD><31><EFBFBD>ET"<22><>d<1C><><00>I<07>b<EFBFBD>V<EFBFBD><56>W<00>W<>srJ<00><><EFBFBD><E1B080>FG<06>0famIE<49>6z<>tH<0F><><EFBFBD>;<3B>9<EFBFBD><39>q!<21><><EFBFBD><EFBFBD><EFBFBD>A2<><32>4s<34><01>(<28><>@<40><34><D98C><EFBFBD><18>;<3B>;<3B><>`<60>W<EFBFBD><57><EFBFBD><EFBFBD>' HCD<10>*<2A>#<23><><EFBFBD> <0C>w<>i'p<><70><EFBFBD><EFBFBD><EFBFBD><50>1<EFBFBD><31><01><>(v<>†<EFBFBD><01><><05>X@<40><EFBFBD><1B>xY<78><59><EFBFBD>
<EFBFBD><EFBFBD>%<25><>*4<><06>"P<><50>Ć<EFBFBD><C486><11><>#$<24><>o '#Tx߇0a<30>n 20=v <09><><19><<3C>3<EFBFBD><33><00>Z.<2E>9<EFBFBD>)<29>խ<0E><><EFBFBD><18><10>AY<>-<2D><> :<3A>/<2F><.i?pC<70>),#+<2B>,<2C><><EFBFBD><EFBFBD>';<3B><>Puҿ<00><>I<EFBFBD>l<06>#kf<6B>|<7C> <><EEA6B1>|<18><><EFBFBD>?փG9<47><39>q2`<10>d<00>O <0C> <20><>ēG?<03>LK<1C> <09>;;<3B>Y<EFBFBD>d<EFBFBD>Q<>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD><EFBFBD><EFBFBD><1F>p'4b<34><62>yIEND<4E>B`<60><>PNG

IHDR<00><00>1|<7C>0PLTE@@@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><00><00><00><00><00><00><00><00><00><00><00><><EFBFBD>"@IDATx<54><78><EFBFBD>Q<0E> C#q!$<24><>n'@hG7iڟ_E<5F>(5I 5B!2<>f<EFBFBD>Z<01><>̀6<08><><EFBFBD>'<27><>"mZ<6D><5A>/5y<35><79><EFBFBD><00>|<7C>WJ<57><4A><EFBFBD>q<71><7F>@<0F><>3t<33><74><EFBFBD>g<EFBFBD>2<>(<28>N<<><7F>m17&<26><>E<> <0B><>)<29>OSz<53>ڟ<EFBFBD><DA9F><EFBFBD>j<14><><EFBFBD>z
,b <0B><1D><><EFBFBD><EFBFBD>n<><6E>|<7C>8- <0C>ݣ<EFBFBD>^<5E><><EFBFBD><EFBFBD><EFBFBD>Y`<60>'<18>f<EFBFBD>W`<60>)<29><>S<00><04><04>C<04>) GPz<1F>R8<52><00>޿<><DEBF><EFBFBD>`<60><07> <0B><><EFBFBD>M.<2E><><05><><EFBFBD><EFBFBD>\S<>=<1D><><EFBFBD><EFBFBD>o4:<3A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>&P<O
<14>S<EFBFBD>E<EFBFBD>ս<1E><>@<40>
zl)<29><>O<EFBFBD>Cc<>ĵx<><<3C><>-<2D><>k|<7C><><EFBFBD>v<EFBFBD>H<EFBFBD><48>GA!<21>B!<21>B!y<01>vc|<7C><><EFBFBD>@IEND<4E>B`<60>#!/bin/env python
import os
import os.path
import PIL.Image
def write_chr(w, h, data, f):
for y in range(0, h, 8):
for x in range(0, w, 8):
# Copy low bits of each 8x8 chunk into the first 8x8 plane.
for j in range(8):
c = 0
for i in range(8):
c = (c * 2) | (data[x + i, y + j] & 1)
f.write(chr(c))
# Copy high bits of each chunk into the second 8x8 plane.
for j in range(8):
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, y + j] >> 1) & 1)
f.write(chr(c))
if __name__ == '__main__':
import sys
def main():
if len(sys.argv) > 1:
for arg in range(1, len(sys.argv)):
filename = sys.argv[arg]
try:
img = PIL.Image.open(filename)
except IOError as e:
if os.path.isdir(filename):
exit(filename + ' is a directory.')
if os.path.exists(filename):
exit(filename + ' has an unsupported filetype, or you lack permission to open it.')
else:
exit('File ' + filename + ' does not exist!')
w, h = img.size
if w != 128 or h != 128:
exit('Image ' + filename + ' is not 128x128 pixels in size.')
if not img.palette:
exit('Image ' + filename + ' has no palette.')
data = img.load()
save_filename = os.path.splitext(filename)[0] + '.chr'
try:
f = open(save_filename, 'wb')
except Exception as e:
exit('Failure attempting to write ' + save_filename)
write_chr(w, h, data, f)
f.close()
print(' ' + filename + ' -> ' + save_filename)
else:
print('Usage: ' + sys.argv[0] + ' file [file...]')
print('Converts files like foo.png into NES-friendly formats like foo.chr')
main()8L<38><4C><EFBFBD>d88L<38><4C><EFBFBD>d88<8<|<7C><`<60><>|<7C><`<60><>|<7C><<06>||<7C><<06>|<l<><6C> <l<><6C> <00><><EFBFBD><EFBFBD><06><00><><EFBFBD><EFBFBD><06><`<60><><EFBFBD><EFBFBD>|<`<60><><EFBFBD><EFBFBD>|<00> 000<00> 000|<7C><>|<7C><>||<7C><>|<7C><>||<7C><>~ x|<7C><>~ x8l<38><6C><EFBFBD><EFBFBD><EFBFBD>8l<38><6C><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD>|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD>|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~~~<06><>|<06><>|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD>|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>z|<7C><><EFBFBD><EFBFBD><EFBFBD>z<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><>|<06>||<7C><>|<06>|~~<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<00><><EFBFBD><EFBFBD>|8<00><><EFBFBD><EFBFBD>|8<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><>|8|<7C><><00><>|8|<7C><>fff<fff<<00>8p<38><70><00>8p<38><70>

IHDR<00><00>1|<7C>,tEXtCreation TimeTue 15 Feb 2011 18:41:59 -0500<30><12><>tIME<07> ף. pHYs
<EFBFBD>
<EFBFBD>B<>4<EFBFBD>gAMA<00><> <0B>a0PLTE@@@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><00><00><00><00><00><00><00><00><00><00><00><><EFBFBD>"fIDATx<54><78><EFBFBD>m<16> E<>l<EFBFBD><6C> <08><00><><EFBFBD>m<EFBFBD>@)<29>ӯ<EFBFBD><D3AF>?<3F>V<EFBFBD><56><EFBFBD>K`YV` <00>=<3D><>e<EFBFBD>&~<7E>{m<00><03>o<EFBFBD>q&J<02>E<EFBFBD>_(<28>W<04>q3<11>}u<>9`<60>d<EFBFBD>rQ<72>dM<01><><03>;<3B>@<40>R<05><03><> <20>0<EFBFBD>43`bB<62>8<EFBFBD><38>l˜9<><03>i<05><><EFBFBD><EFBFBD><'6<><36><EFBFBD>Xl<02><><EFBFBD>4<EFBFBD><34><EFBFBD><EFBFBD>Vc[<5B>v<><76>d<EFBFBD><64>\<5C><10>K<00><><EFBFBD>Q<EFBFBD> <20><>#e+<12>;WIv<49><76><EFBFBD>;<3B><>EDNa2ќ<03><0E>m<EFBFBD><6D>&<26><01>&<26>W
34<05><><EFBFBD>@|<04><><EFBFBD>ـN{6=;<3B><><EFBFBD>ߵ<EFBFBD><DFB5><01><><EFBFBD><EFBFBD>b<EFBFBD><62> <20>?<3F><><EFBFBD>@<14>/<00><>?
<EFBFBD><19><>H<EFBFBD><18><><01>@<40><1F>[<5B><>0<EFBFBD><30>:<3A><><EFBFBD><EFBFBD><EFBFBD><14><>?<3F>%<25>Ћ?<3F>T<EFBFBD><0F>n<EFBFBD>H!<-ʥ 5r<35><72><EFBFBD>?4<><34>c]"<22> <0B><><EFBFBD><EFBFBD><00><><EFBFBD>պ^]j׀f<D780>JQJ:<3A><><EFBFBD>6 un<75>L<EFBFBD> 8)<29>v<EFBFBD><76>8<EFBFBD>t<>M<EFBFBD><4D>E'<><7F><EFBFBD>D<EFBFBD><05><>#IA<49><41>6JG<4A>u<EFBFBD><75><EFBFBD>Һ<EFBFBD><D2BA>K[ k<>K<EFBFBD>$<24><><EFBFBD><EFBFBD>n<17><><EFBFBD>><3E><><EFBFBD><EFBFBD>p Z<><5A><14><> @<40><01>8<><38><02><0E><><EFBFBD>o)׀<><1A><>w
<EFBFBD>.@<40>K<17><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>o[<5B><><EFBFBD><1C>}JzF<7A><0E>~<7E><>o<EFBFBD><6F><EFBFBD>z<1E>6S<>T<EFBFBD><54><EFBFBD><14>"6@,<2C>^ۑ<><DB91>W<EFBFBD>C<><43><EFBFBD>O艁e<E88981><65><EFBFBD>
<EFBFBD>V|<7C><><EFBFBD><18>־<><D6BE>?m<><1B><><EFBFBD>Cahhhhhhhhhhhhhhhhhhh<68>T<00><><EFBFBD><EFBFBD><EFBFBD> <09>kIEND<4E>B`<60><>PNG

IHDR<00><00>1|<7C>,tEXtCreation TimeTue 15 Feb 2011 18:41:59 -0500<30><12><>tIME<07>
* <0B>X<EFBFBD>C pHYs
<EFBFBD>
<EFBFBD>B<>4<EFBFBD>gAMA<00><> <0B>a0PLTE@@@<40><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><00><00><00><00><00><00><00><00><00><00><00><><EFBFBD>"<01>IDATx<54><78>T[<5B><> <10>*N<00>@<40>H<><EFBFBD> <0A>C<EFBFBD><><DDB1><EFBFBD>3<EFBFBD>2!<21><>"<22>'"m><3E>g<EFBFBD>C ~<7E>+v%<25>É y<><07>l{H<><48>o<EFBFBD>B<><12><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>}<7D><>#6|Az<41><7A>L<EFBFBD>*ٓO<D993><4F><EFBFBD>J<>@V<><56><EFBFBD><EFBFBD><EFBFBD><02><> JD`5<><35>A<>[RuB<13><14><><EFBFBD>!$<24>
<EFBFBD><EFBFBD><EFBFBD>@a%<18>o50 <05><><EFBFBD><EFBFBD><00>x~W2o<32><6F><EFBFBD>Wp%<25><>\/<2F><><CAA9>)@<40><>}<7D><>u8<75><38><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>U<EFBFBD>^<5E><><EFBFBD> <09>d<EFBFBD><64>4;<3B><><EFBFBD><02><>><3E><0F>|'<27><>(<28><><15>nA<6E>Jmg<6D>gh<67>m<EFBFBD>^<5E><U ZD<5A>h<EFBFBD><68>Lf<4C><66>ݑ<><DD91>qF<71>cn<19><><EFBFBD>o<EFBFBD><6F><q%8<><13>b<EFBFBD><62>w<02>X<EFBFBD>[<18>'d!<21>B\(<28><><EFBFBD>U<EFBFBD><55>m<EFBFBD>d<EFBFBD><64>Xk<58><6B><EFBFBD>-<2D>R<EFBFBD><52>F
<EFBFBD>}<7D>]R<><52>XV<07>ݒ<EFBFBD>ѫ<03>><3E><><EFBFBD>/M\<5C><>'"'<02>|*<2A>õ<EFBFBD><C3B5><EFBFBD><EFBFBD> <20><><EFBFBD>a<EFBFBD><12>s<EFBFBD>f,<2C><05><><EFBFBD>c<><63><EFBFBD>A<EFBFBD><07><><EFBFBD><EFBFBD><EFBFBD>5<1C><><EFBFBD><18><><EFBFBD><E78D84>( <06><>`0 <06><>`0 <06>-<2D><00><><EFBFBD><EFBFBD><EFBFBD>5<>IEND<4E>B`<60>namespace nes {
namespace ppu {
namespace oam {
extern writeonly address @ 0x2003 : u8;
extern var data @ 0x2004 : u8;
extern writeonly dma @ 0x4014 : u8;
let ATTRIBUTE_VFLIP = 0x80;
let ATTRIBUTE_HFLIP = 0x40;
let ATTRIBUTE_BEHIND = 0x20;
let ATTRIBUTE_PALETTE_0 = 0x0;
let ATTRIBUTE_PALETTE_1 = 0x1;
let ATTRIBUTE_PALETTE_2 = 0x2;
let ATTRIBUTE_PALETTE_3 = 0x3;
let ATTRIBUTE_PALETTE_MASK = 0x3;
let SPRITE_SIZE = 4;
let SPRITE_COUNT = 64;
let SPRITE_SCANLINE_LIMIT = 8;
}
extern writeonly control @ 0x2000 : u8;
let CONTROL_NMI = 0x80;
let CONTROL_OBJ_8x16 = 0x20;
let CONTROL_OBJ_8x8 = 0x00;
let CONTROL_BG_PATTERN_1 = 0x10;
let CONTROL_BG_PATTERN_0 = 0x00;
let CONTROL_OBJ_PATTERN_1 = 0x08;
let CONTROL_OBJ_PATTERN_0 = 0x00;
let CONTROL_VRAM_INCREMENT_32 = 0x04;
let CONTROL_VRAM_INCREMENT_1 = 0x00;
let CONTROL_NAMETABLE_0 = 0x00;
let CONTROL_NAMETABLE_1 = 0x01;
let CONTROL_NAMETABLE_2 = 0x02;
let CONTROL_NAMETABLE_3 = 0x03;
let CONTROL_NAMETABLE_MASK = 0x03;
extern writeonly mask @ 0x2001 : u8;
let MASK_INTENSIFY_B = 0x80;
let MASK_INTENSIFY_G = 0x40;
let MASK_INTENSIFY_R = 0x20;
let MASK_RENDER_OBJ = 0x10;
let MASK_RENDER_BG = 0x08;
let MASK_LEFTMOST_OBJ = 0x04;
let MASK_LEFTMOST_BG = 0x02;
let MASK_GREYSCALE = 0x01;
extern const status @ 0x2002 : u8;
let STATUS_VBLANK_MASK = 0x80;
let STATUS_SPRITE_ZERO_HIT_MASK = 0x40;
let STATUS_SPRITE_OVERFLOW = 0x20;
let STATUS_VBLANK_BIT = 7;
let STATUS_SPRITE_ZERO_HIT_BIT = 6;
extern writeonly scroll @ 0x2005 : u8;
extern writeonly address @ 0x2006 : u8;
let ADDRESS_PATTERN_DATA = 0x0000;
let ADDRESS_PATTERN_0 = 0x0000;
let ADDRESS_PATTERN_1 = 0x1000;
let PATTERN_SIZE = 0x1000;
let PATTERN_COUNT = 2;
let ADDRESS_NAMETABLE_DATA = 0x2000;
let ADDRESS_NAMETABLE_0 = 0x2000;
let ADDRESS_NAMETABLE_1 = 0x2400;
let ADDRESS_NAMETABLE_2 = 0x2800;
let ADDRESS_NAMETABLE_3 = 0x2C00;
let NAMETABLE_SIZE = 0x400;
let NAMETABLE_COUNT = 4;
let NAMETABLE_SIZE_TILE_MAP = 0x3C0;
let NAMETABLE_SIZE_ATTRIBUTE_MAP = 0x40;
let NAMETABLE_OFFSET_TILE_MAP = 0;
let NAMETABLE_OFFSET_ATTRIBUTE_MAP = 0x3C0;
let NAMETABLE_WIDTH_TILE_MAP = 32;
let NAMETABLE_HEIGHT_TILE_MAP = 30;
let NAMETABLE_WIDTH_ATTRIBUTE_MAP = 8;
let NAMETABLE_HEIGHT_ATTRIBUTE_MAP = 8; // NOTE: row 7 only contains attributes in the top half.
let ADDRESS_PALETTE_DATA = 0x3F00;
let ADDRESS_PALETTE_BG_0 = 0x3F00;
let ADDRESS_PALETTE_BG_1 = 0x3F04;
let ADDRESS_PALETTE_BG_2 = 0x3F08;
let ADDRESS_PALETTE_BG_3 = 0x3F0C;
let ADDRESS_PALETTE_OBJ_0 = 0x3F10;
let ADDRESS_PALETTE_OBJ_1 = 0x3F14;
let ADDRESS_PALETTE_OBJ_2 = 0x3F18;
let ADDRESS_PALETTE_OBJ_3 = 0x3F1C;
let PALETTE_SIZE = 4;
let PALETTE_COUNT = 8;
let PALETTE_BG_COUNT = 4;
let PALETTE_OBJ_COUNT = 4;
let SCREEN_WIDTH = 256;
let SCREEN_HEIGHT = 240;
extern var data @ 0x2007 : u8;
}
namespace apu {
namespace pulse {
let CONTROL_DUTY_MASK = 0xC0;
let CONTROL_DUTY_SHIFT = 6;
let CONTROL_LENGTH_COUNTER_DISABLE = 0x20;
let CONTROL_VOLUME_CONSTANT = 0x10;
let CONTROL_VOLUME_ENVELOPE_MASK = 0x0F;
let SWEEP_ENABLE_MASK = 0x80;
let SWEEP_PERIOD_MASK = 0x70;
let SWEEP_PERIOD_SHIFT = 4;
let SWEEP_NEGATE = 0x08;
let SWEEP_SHIFT_MASK = 0x03;
let HIGH_LENGTH_MASK = 0xF8;
let HIGH_LENGTH_SHIFT = 3;
let HIGH_FREQUENCY_MASK = 0x03;
}
namespace pulse1 {
extern writeonly control @ 0x4000 : u8;
extern writeonly sweep @ 0x4001 : u8;
extern writeonly low @ 0x4002 : u8;
extern writeonly high @ 0x4003 : u8;
}
namespace pulse2 {
extern writeonly control @ 0x4004 : u8;
extern writeonly sweep @ 0x4005 : u8;
extern writeonly low @ 0x4006 : u8;
extern writeonly high @ 0x4007 : u8;
}
namespace triangle {
extern writeonly control @ 0x4008 : u8;
let CONTROL_LINEAR_COUNTER_ENABLE = 0x80;
extern writeonly low @ 0x400A : u8;
extern writeonly high @ 0x400B : u8;
let HIGH_LENGTH_MASK = 0xF8;
let HIGH_LENGTH_SHIFT = 3;
let HIGH_FREQUENCY_MASK = 0x03;
}
namespace noise {
extern writeonly control @ 0x400C : u8;
let CONTROL_LENGTH_COUNTER_DISABLE = 0x20;
let CONTROL_VOLUME_CONSTANT = 0x10;
let CONTROL_VOLUME_ENVELOPE_MASK = 0x0F;
extern writeonly pattern @ 0x400E : u8;
let PATTERN_PERIOD_MASK = 0x0F;
let PATTERN_DUTY = 0x80;
extern writeonly length @ 0x400F : u8;
let LENGTH_MASK = 0xF8;
let LENGTH_SHIFT = 3;
}
namespace dmc {
extern writeonly control @ 0x4010 : u8;
let CONTROL_IRQ_ENABLE = 0x80;
let CONTROL_LOOP = 0x40;
let CONTROL_FREQUENCY_MASK = 0x0F;
extern writeonly counter @ 0x4011 : u8;
let COUNTER_MASK = 0x7F;
extern writeonly address @ 0x4012 : u8;
extern writeonly length @ 0x4013 : u8;
}
// Enabled channels.
extern writeonly enable @ 0x4015 : u8;
// DMC is enabled.
let ENABLE_DMC = 0x10;
// Noise is enabled
let ENABLE_NOISE = 0x08;
// Triangle is enabled
let ENABLE_TRIANGLE = 0x04;
// Pulse 2 is enabled
let ENABLE_PULSE2 = 0x02;
// Pulse 1 is enabled
let ENABLE_PULSE1 = 0x01;
// APU status register.
extern const status @ 0x4015 : u8;
// Mask of whether or not DMC interrupt is active.
let STATUS_DMC_IRQ_MASK = 0x80;
// Bit index of whether or not DMC interrupt is active.
let STATUS_DMC_IRQ_BIT = 7;
// Mask of whether or not frame-counter interrupt is active.
let STATUS_FRAME_IRQ_MASK = 0x40;
// Bit index of whether or not frame-counter interrupt is active.
let STATUS_FRAME_IRQ_BIT = 6;
// Mask of possible enabled channels.
let STATUS_ENABLE_MASK = 0x1F;
// DMC is enabled
let STATUS_DMC_ENABLED = 0x10;
// Noise is enabled
let STATUS_NOISE_ENABLED = 0x08;
// Triangle is enabled
let STATUS_TRIANGLE_ENABLED = 0x04;
// Pulse 2 is enabled
let STATUS_PULSE2_ENABLED = 0x02;
// Pulse 1 is enabled
let STATUS_PULSE1_ENABLED = 0x01;
// Frame counter.
extern writeonly frame_counter @ 0x4017 : u8;
// Disable frame-counter interrupts.
let FRAME_COUNTER_IRQ_DISABLE = 0x40;
// Four-step mode (faster, allows frame-counter interrupt if not disabled)
let FRAME_COUNTER_FOUR_STEP = 0x00;
// Five-step mode (slower)
let FRAME_COUNTER_FIVE_STEP = 0x80;
}
namespace joy {
extern writeonly output @ 0x4016 : u8;
extern const input1 @ 0x4016 : u8;
extern const input2 @ 0x4017 : u8;
namespace bit {
let A = 0;
let B = 1;
let SELECT = 2;
let START = 3;
let UP = 4;
let DOWN = 5;
let LEFT = 6;
let RIGHT = 7;
let BUTTON_START = 0;
let BUTTON_COUNT = 4;
let DIRECTION_START = 4;
let DIRECTION_COUNT = 4;
let COUNT = 8;
}
namespace mask {
let A = 0x01;
let B = 0x02;
let SELECT = 0x04;
let START = 0x08;
let UP = 0x10;
let DOWN = 0x20;
let LEFT = 0x40;
let RIGHT = 0x80;
let BUTTONS = 0x0F;
let DIRECTIONS = 0xF0;
let ALL = 0xFF;
}
}
namespace mmc1 {
// The MMC1 implements its mapper interface through a 5-bit shift register.
// Writing must send each bit one-by-one in the lowest bit of the port.
// After the fifth bit is transferred, the data gets sent to the approriate internal register of the mapper.
// For convenience, you can use the inline write macros below.
// Control port (5-bit shift register).
extern writeonly control @ 0x8000 : u8;
// One-screen mirroring mode A (lower bank)
let CONTROL_MIRROR_ONESCREEN_A = 0x00;
// One-screen mirroring mode B (upper bank)
let CONTROL_MIRROR_ONESCREEN_B = 0x01;
// Vertical mirroring.
let CONTROL_MIRROR_VERTICAL = 0x02;
// Horizontal mirroring.
let CONTROL_MIRROR_HORIZONTAL = 0x03;
// PRG mode 0, 1: 0x8000 .. 0xFFFF - swappable 32K bank
let CONTROL_PRG_MODE_32K = 0x00;
// PRG mode 2: 0x8000 .. 0xBFFF - swappable 16K bank, 0xC000 .. 0xFFFF - fixed 16K bank.
let CONTROL_PRG_MODE_16K_LOW_SWAP_HIGH_FIX = 0x08;
// PRG mode 3: 0x8000 .. 0xBFFF - fixed 16K bank, 0xC000 .. 0xFFFF - swappable 16K bank.
let CONTROL_PRG_MODE_16K_LOW_FIX_HIGH_SWAP = 0x0C;
// CHR mode 0: 0x0000 .. 0x2000 - one swappable 8K bank
let CONTROL_CHR_MODE_8K = 0x00;
// CHR mode 0: 0x0000 .. 0x1000, 0x1000 .. 0x2000 - two swappable 4K banks
let CONTROL_CHR_MODE_4K = 0x10;
// Resets the shift register and resets control port to CONTROL_PRG_MODE_16K_LOW_FIX_HIGH_SWAP.
let CONTROL_RESET = 0x80;
// CHR bank select A (5-bit shift register).
// Selects CHR bank at PPU 0x0000 .. 0x1000 (in 4K CHR mode; 5-bit index) / 0x0000 .. 0x2000 (in 8K CHR mode; 5-bit index with lowest bit ignored)
extern writeonly chr_a @ 0xA000 : u8;
// CHR bank select B (5-bit shift register).
// Select CHR bank at PPU 0x1000 .. 0x2000 (in 4K CHR mode only; 5-bit index).
extern writeonly chr_b @ 0xC000 : u8;
// Mask of possible CHR bank values.
let CHR_BANK_MASK = 0x0F;
// PRG bank select (5-bit shift register).
extern writeonly prg @ 0xE000 : u8;
// Mask of possible PRG ROM bank values.
let PRG_ROM_BANK_MASK = 0x0F;
// Enable reading PRG RAM at 0x6000 .. 0x7FFF
let PRG_RAM_ENABLE = 0x10;
// Reset the MMC1 shift register to its initial state.
// Modifies: a
inline func reset() {
control = a = CONTROL_RESET;
}
// Write a 5-bit value to the control register.
// Arguments: a = the value to write
// See: CONTROL constants
inline func write_control(value : u8 in a) {
inline for in 1 .. 5 { control = a; a >>>= 1; }
}
// Write a 5-bit value to the PRG select register.
// Arguments: a = the value to write
// See: PRG constants
inline func write_prg(value : u8 in a) {
inline for in 1 .. 5 { prg = a; a >>>= 1; }
}
// Write a 5-bit value to the lower CHR select register.
// Arguments: a = the value to write
// See: CHR constants
inline func write_chr_a(value : u8 in a) {
inline for in 1 .. 5 { chr_a = a; a >>>= 1; }
}
// Write a 5-bit value to the upper CHR select register.
// Arguments: a = the value to write
// See: CHR constants
inline func write_chr_b(value : u8 in a) {
inline for in 1 .. 5 { chr_b = a; a >>>= 1; }
}
}
namespace mmc3 {
namespace irq {
// This register specifies the IRQ counter reload value.
// When the IRQ counter is zero (or a reload is requested through 0xC001),
// this value will be copied into the MMC3 IRQ counter at
// the end of the current scanline
extern writeonly latch @ 0xC000 : u8;
// Writing any value to this register clears the MMC3 IRQ counter
// so that it will be reloaded at the end of the current scanline.
extern writeonly reload @ 0xC001 : u8;
// Writing any value to this register will disable MMC3 interrupts
// AND acknowledge any pending interrupts.
extern writeonly disable @ 0xE000 : u8;
// Writing any value to this register will enable MMC3 interrupts.
extern writeonly enable @ 0xE001 : u8;
}
// Bank select register.
extern writeonly select @ 0x8000 : u8;
// Select 2K CHR bank A at PPU 0x0000 .. 0x07FF (CHR mode 0) / 0x1000 .. 0x17FF (CHR mode 1)
let SELECT_2K_CHR_BANK_A = 0x00;
// Select 2K CHR bank B at PPU 0x0800 .. 0x0FFF (CHR mode 0) / 0x1800 .. 0x1FFF (CHR mode 1)
let SELECT_2K_CHR_BANK_B = 0x01;
// Select 1K CHR bank A at PPU 0x1000 .. 0x13FF (CHR mode 0) / 0x0000 .. 0x03FF (CHR mode 1)
let SELECT_1K_CHR_BANK_A = 0x02;
// Select 1K CHR bank B at PPU 0x1400 .. 0x17FF (CHR mode 0) / 0x0400 .. 0x07FF (CHR mode 1)
let SELECT_1K_CHR_BANK_B = 0x03;
// Select 1K CHR bank C at PPU 0x1800 .. 0x1BFF (CHR mode 0) / 0x0800 .. 0x0BFF (CHR mode 1)
let SELECT_1K_CHR_BANK_C = 0x04;
// Select 1K CHR bank D at PPU 0x1C00 .. 0x1FFF (CHR mode 0) / 0x0C00 .. 0x0FFF (CHR mode 1)
let SELECT_1K_CHR_BANK_D = 0x05;
// Select 8K CHR bank A at CPU 0x8000 .. 0x9FFF (PRG mode 0) / 0xC000 .. 0xDFFF (PRG mode 1)
let SELECT_8K_PRG_BANK_A = 0x06;
// Select 8K CHR bank B at CPU 0xA000 .. 0xBFFF
let SELECT_8K_PRG_BANK_B = 0x07;
// PRG mode 0: 0x8000 .. 0x9FFF - swappable, 0xC000 .. 0xDFFF - fixed to second-last bank.
let SELECT_PRG_MODE_0 = 0x00;
// PRG mode 1: 0xC000 .. 0xDFFF - swappable, 0x8000 .. 0x9FFF - fixed to second-last bank.
let SELECT_PRG_MODE_1 = 0x40;
// CHR mode 0: 0x0000 .. 0x0FFF - two 2K banks, 0x1000 .. 0x1FFF - four 1K banks.
let SELECT_CHR_MODE_0 = 0x00;
// CHR mode 1: 0x0000 .. 0x0FFF - four 1K banks, 0x1000 .. 0x1FFF - two 2K banks.
let SELECT_CHR_MODE_1 = 0x80;
// Bank value to write, based on last value written to bank select register.
extern writeonly data @ 0x8001 : u8;
// Nametable mirroring setting.
extern writeonly mirror @ 0xA000 : u8;
// Vertical mirroring.
let MIRROR_VERTICAL = 0x0;
// Horizontal mirroring.
let MIRROR_HORIZONTAL = 0x1;
// Controls access to the WRAM.
extern writeonly prg_ram_control @ 0xA001 : u8;
// Disable writing RAM at 0x6000 .. 0x7FFF
let PRG_RAM_CONTROL_DISABLE_WRITE = 0x40;
// Enable reading RAM at 0x6000 .. 0x7FFF
let PRG_RAM_CONTROL_ENABLE = 0x80;
}
namespace mmc6 {
namespace irq {
// This register specifies the IRQ counter reload value.
// When the IRQ counter is zero (or a reload is requested through 0xC001),
// this value will be copied into the MMC3 IRQ counter at
// the end of the current scanline
extern writeonly latch @ 0xC000 : u8;
// Writing any value to this register clears the MMC3 IRQ counter
// so that it will be reloaded at the end of the current scanline.
extern writeonly reload @ 0xC001 : u8;
// Writing any value to this register will disable MMC3 interrupts
// AND acknowledge any pending interrupts.
extern writeonly disable @ 0xE000 : u8;
// Writing any value to this register will enable MMC3 interrupts.
extern writeonly enable @ 0xE001 : u8;
}
extern writeonly select @ 0x8000 : u8;
// Select 2K CHR bank A at PPU 0x0000 .. 0x07FF (CHR mode 0) / 0x1000 .. 0x17FF (CHR mode 1)
let SELECT_2K_CHR_BANK_A = 0x00;
// Select 2K CHR bank B at PPU 0x0800 .. 0x0FFF (CHR mode 0) / 0x1800 .. 0x1FFF (CHR mode 1)
let SELECT_2K_CHR_BANK_B = 0x01;
// Select 1K CHR bank A at PPU 0x1000 .. 0x13FF (CHR mode 0) / 0x0000 .. 0x03FF (CHR mode 1)
let SELECT_1K_CHR_BANK_A = 0x02;
// Select 1K CHR bank B at PPU 0x1400 .. 0x17FF (CHR mode 0) / 0x0400 .. 0x07FF (CHR mode 1)
let SELECT_1K_CHR_BANK_B = 0x03;
// Select 1K CHR bank C at PPU 0x1800 .. 0x1BFF (CHR mode 0) / 0x0800 .. 0x0BFF (CHR mode 1)
let SELECT_1K_CHR_BANK_C = 0x04;
// Select 1K CHR bank D at PPU 0x1C00 .. 0x1FFF (CHR mode 0) / 0x0C00 .. 0x0FFF (CHR mode 1)
let SELECT_1K_CHR_BANK_D = 0x05;
// Select 8K CHR bank A at CPU 0x8000 .. 0x9FFF (PRG mode 0) / 0xC000 .. 0xDFFF (PRG mode 1)
let SELECT_8K_PRG_BANK_A = 0x06;
// Select 8K CHR bank B at CPU 0xA000 .. 0xBFFF
let SELECT_8K_PRG_BANK_B = 0x07;
// Enable PRG RAM.
let SELECT_PRG_RAM_ENABLE = 0x20;
// PRG mode 0: 0x8000 .. 0x9FFF - swappable, 0xC000 .. 0xDFFF - fixed to second-last bank.
let SELECT_PRG_MODE_0 = 0x00;
// PRG mode 1: 0xC000 .. 0xDFFF - swappable, 0x8000 .. 0x9FFF - fixed to second-last bank.
let SELECT_PRG_MODE_1 = 0x40;
// CHR mode 0: 0x0000 .. 0x0FFF - two 2K banks, 0x1000 .. 0x1FFF - four 1K banks.
let SELECT_CHR_MODE_0 = 0x00;
// CHR mode 1: 0x0000 .. 0x0FFF - four 1K banks, 0x1000 .. 0x1FFF - two 2K banks.
let SELECT_CHR_MODE_1 = 0x80;
// New bank value, based on last value written to bank select register
extern writeonly data @ 0x8001 : u8;
// Nametable mirroring setting.
extern writeonly mirror @ 0xA000 : u8;
let MIRROR_VERTICAL = 0x0;
let MIRROR_HORIZONTAL = 0x1;
// Controls access to the WRAM.
extern writeonly prg_ram_control @ 0xA001 : u8;
// Enable writing RAM at 0x7000 .. 0x71FF. (Must enable read bit too if writing.)
let PRG_RAM_CONTROL_ENABLE_WRITE_L = 0x10;
// Enable reading RAM at 0x7000 .. 0x71FF.
let PRG_RAM_CONTROL_ENABLE_READ_L = 0x20;
// Enable writing RAM at 0x7100 .. 0x72FF. (Must enable read bit too if writing.)
let PRG_RAM_CONTROL_ENABLE_WRITE_H = 0x40;
// Enable reading RAM at 0x7100 .. 0x72FF.
let PRG_RAM_CONTROL_ENABLE_READ_H = 0x80;
}
}<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><0F><><EFBFBD><EFBFBD>x<<3C><>x<<0F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ~~|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><0E><><EFBFBD><EFBFBD><EFBFBD>OI<4F>O|}<7D><><EFBFBD><EFBFBD><EFBFBD>8<EFBFBD><38>~<$<01>xxx3<78><33><EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>8L<38><4C><EFBFBD>d88L<38><4C><EFBFBD>d88<8<|<7C><`<60><>|<7C><`<60><>|<7C><<06>||<7C><<06>|<l<><6C> <l<><6C> <00><><EFBFBD><EFBFBD><06><00><><EFBFBD><EFBFBD><06><`<60><><EFBFBD><EFBFBD>|<`<60><><EFBFBD><EFBFBD>|<00> 000<00> 000|<7C><>|<7C><>||<7C><>|<7C><>||<7C><>~ x|<7C><>~ x8l<38><6C><EFBFBD><EFBFBD><EFBFBD>8l<38><6C><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD>|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD>|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~~~<06><>|<06><>|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD>|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>z|<7C><><EFBFBD><EFBFBD><EFBFBD>z<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><>|<06>||<7C><>|<06>|~~<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<00><><EFBFBD><EFBFBD>|8<00><><EFBFBD><EFBFBD>|8<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><>|8|<7C><><00><>|8|<7C><>fff<fff<<00>8p<38><70><00>8p<38><70>
b<EFBFBD>y??<><7F><EFBFBD><EFBFBD><EFBFBD><<18><><EFBFBD><EFBFBD>~<7E><><EFBFBD>|<7C><> <0C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~<7E>~]<5D> <0C><><EFBFBD>f<EFBFBD><66><EFBFBD><EFBFBD><<3C><<3C>~~<7E>ǂ<EFBFBD>mnj<><C78C>|:<3A><>8s~<8DZ~&$8<8DZ~R<8<<,<FB~fn88<<<FZ~fv8<<$B~BI?<<6>>>B<><42><EFBFBD>Z<EFBFBD><5A>3<~ZZ$A<><B<><42><00>!<Z~<7E><><<18>@<Z<><5A><?B<><00><<~<7E>Z<EFBFBD><5A><EFBFBD><EFBFBD>8x<38><78><EFBFBD>x80`<60>`0>>*+F<>1<EFBFBD>9<39>$H<>D"dH0p80<><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ~<7E><><EFBFBD>Z<EFBFBD>~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>BZB~~~~BZB~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~<7E>UUUUU|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>>><|||6688B$<24>~<7E><>"3<><33>~<7E>Z=<3D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>??~<7E><><EFBFBD>۽<EFBFBD><DBBD>s<><73><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Z<><5A><EFBFBD><EFBFBD>XB<58><42>}<7D><11>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><00><><EFBFBD><00><><EFBFBD><00><><EFBFBD>?<3F><00><><EFBFBD><EFBFBD>?<3F>`s7<73><37>_`s7<73><37>_8<>M<01><01>|<10><>|<7C>|<1C><><EFBFBD><EFBFBD><7F>ZZ<<<n<<f<>f<f<>f<f<>f<EFBFBD>5\Ճ<00>5|<7C><><EFBFBD>~<00><>BBJZn<5A><6E><EFBFBD>BBJZn<5A><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ձ<EFBFBD> <13><10> <18><>`8<><38><EFBFBD><EFBFBD>[Y<>T8|<7C><>|<7C><><EFBFBD><EFBFBD><15><><EFBFBD>~<7E><><00><00>~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|J~B~R~<00><00><>$<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>]"p|r""ZBBZZBBZZBBZ#!/bin/env python
import os
import os.path
import PIL.Image
def write_chr(w, h, data, f):
for y in range(0, h, 8):
for x in range(0, w, 8):
for j in range(8):
# Write the bits of this column.
c = 0
for i in range(8):
c = (c << 1) | (1 if data[x + i, y + j] != 0 else 0)
f.write(chr(c))
if __name__ == '__main__':
import sys
if len(sys.argv) > 1:
WIDTH = 128
HEIGHT = None
for arg in range(1, len(sys.argv)):
filename = sys.argv[arg]
if filename[0] == '-':
if filename == '-oldfart':
HEIGHT = 192
elif filename == '-newfart':
HEIGHT = None
else:
exit('Invalid argument `' + filename + '`.')
continue
try:
img = PIL.Image.open(filename)
except IOError as e:
if os.path.isdir(filename):
exit(filename + ' is a directory.')
if os.path.exists(filename):
exit(filename + ' has an unsupported filetype, or you lack permission to open it.')
else:
exit('File ' + filename + ' does not exist!')
w, h = img.size
if w != WIDTH or h % 8 != 0 or HEIGHT and h != HEIGHT:
exit('Image ' + filename + ' is not ' + str(WIDTH) + 'x' + str(HEIGHT) + ' pixels in size.')
if not img.palette:
exit('Image ' + filename + ' has no palette.')
data = img.load()
save_filename = os.path.splitext(filename)[0] + '.chr'
try:
f = open(save_filename, 'wb')
except Exception as e:
exit('Failure attempting to write ' + save_filename)
write_chr(w, h, data, f)
f.close()
print(' ' + filename + ' -> ' + save_filename)
else:
print('Usage: ' + sys.argv[0] + ' file [file...]')
print('Converts files like foo.png into MSX1-friendly formats like foo.chr')
<EFBFBD>PNG

IHDR<00><00>1|<7C>tIME<07>7<>~<7E><> pHYs
<EFBFBD>
<EFBFBD>B<>4<EFBFBD>gAMA<00><> <0B>a0PLTE<00><00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD>O&I@IDATx<54><78><EFBFBD>Q<0E> Cs<03>Kn<4B><6E> <20><><EFBFBD>4<EFBFBD>ϯ<EFBFBD>c<EFBFBD><63>$<24><> !<21>T<>R<EFBFBD>l<>f@<1B><><EFBFBD><EFBFBD><13>@<40>6<EFBFBD><36><EFBFBD><17><><EFBFBD><EFBFBD><EFBFBD>c\<5C><>+<2B><><EFBFBD><EFBFBD><EFBFBD>?<3F>^<5E><><EFBFBD><EFBFBD>:[J<><4A><EFBFBD> ^O'<27>?EЂ<45><D082><1B>aw<61><77>"҅Tq<54>ا)<29>_<EFBFBD><5F><EFBFBD>v_5
XGD=<16><><EFBFBD><EFBFBD><EFBFBD>tf<74><0F>ny>l<><16><><EFBFBD>Q_<51>_<EFBFBD><5F><EFBFBD><EFBFBD>,<2C><><13>b3«<00>V<EFBFBD><14><>)KH<02>!<02><14>#(<28><>w)<29>k<EFBFBD>\<03><>S<EFBFBD>\0<>Å<>_<EFBFBD>&~<7E>i<>qp<71>)<29><><EFBFBD><0E>u<EFBFBD><75>7<1D>y<EFBFBD>F<EFBFBD>l(<28>'
<EFBFBD>)<29>"N<><4E>^<5E><>v
|=<3D><>B<EFBFBD>'<27>!<21><>a<EFBFBD>Z<`G<><47>g<EFBFBD><16><>5>c<>k<EFBFBD>o$<24><><EFBFBD> <20>B!<21>B!<21><10><>{<7B><>w.<0F> IEND<4E>B`<60>8L<38><4C><EFBFBD>d88<|<7C><`<60><>|<7C><<06>|<l<><6C> <00><><EFBFBD><EFBFBD><06><`<60><><EFBFBD><EFBFBD>|<00> 000|<7C><>|<7C><>||<7C><>~ x8l<38><6C><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~<06><>|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>|<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>z<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><>|<06>|~<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<00><><EFBFBD><EFBFBD>|8<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><>|8|<7C><>fff<<00>8p<38><70>#!/bin/env python
import os
import os.path
import PIL.Image
def write_chr(w, h, data, f):
for y in range(0, h, 8):
for x in range(0, w, 8):
for j in range(8):
# Write the bits of this column.
c = 0
for i in range(8):
c = (c << 1) | (1 if data[x + i, y + j] != 0 else 0)
f.write(chr(c))
if __name__ == '__main__':
import sys
if len(sys.argv) > 1:
WIDTH = 128
HEIGHT = None
for arg in range(1, len(sys.argv)):
filename = sys.argv[arg]
if filename[0] == '-':
if filename == '-oldfart':
HEIGHT = 192
elif filename == '-newfart':
HEIGHT = None
else:
exit('Invalid argument `' + filename + '`.')
continue
try:
img = PIL.Image.open(filename)
except IOError as e:
if os.path.isdir(filename):
exit(filename + ' is a directory.')
if os.path.exists(filename):
exit(filename + ' has an unsupported filetype, or you lack permission to open it.')
else:
exit('File ' + filename + ' does not exist!')
w, h = img.size
if w != WIDTH or h % 8 != 0 or HEIGHT and h != HEIGHT:
exit('Image ' + filename + ' is not ' + str(WIDTH) + 'x' + str(HEIGHT) + ' pixels in size.')
if not img.palette:
exit('Image ' + filename + ' has no palette.')
data = img.load()
save_filename = os.path.splitext(filename)[0] + '.chr'
try:
f = open(save_filename, 'wb')
except Exception as e:
exit('Failure attempting to write ' + save_filename)
write_chr(w, h, data, f)
f.close()
print(' ' + filename + ' -> ' + save_filename)
else:
print('Usage: ' + sys.argv[0] + ' file [file...]')
print('Converts files like foo.png into MSX1-friendly formats like foo.chr')
// TODO: add lots of missing I/O register definitions, clean up definitions.
// TODO: variables in I/O space? instead of io_write/io_read, just use like a register/variable.
namespace msx {
namespace bios {
namespace rst {
// TODO: make defines for all the functions listed here: http://map.grauw.nl/resources/msxbios.php
}
}
namespace konami {
extern writeonly rom_6000 @ 0x6000 : u8;
extern writeonly rom_8000 @ 0x8000 : u8;
extern writeonly rom_A000 @ 0xA000 : u8;
}
namespace scc {
extern writeonly control @ 0x9000 : u8;
let CONTROL_ENABLE = 0x3F;
let CONTROL_DISALBE = 0x00;
extern var wave_0 @ 0x9800 : [u8; 32];
extern var wave_1 @ 0x9820 : [u8; 32];
extern var wave_2 @ 0x9840 : [u8; 32];
extern var wave_34 @ 0x9860 : [u8; 32];
extern var frequency_l_0 @ 0x9880 : u8;
extern var frequency_h_0 @ 0x9881 : u8;
extern var frequency_l_1 @ 0x9882 : u8;
extern var frequency_h_1 @ 0x9883 : u8;
extern var frequency_l_2 @ 0x9884 : u8;
extern var frequency_h_2 @ 0x9885 : u8;
extern var frequency_l_3 @ 0x9886 : u8;
extern var frequency_h_3 @ 0x9887 : u8;
extern var frequency_l_4 @ 0x9888 : u8;
extern var frequency_h_4 @ 0x9889 : u8;
extern var volume_0 @ 0x988A : u8;
extern var volume_1 @ 0x988B : u8;
extern var volume_2 @ 0x988C : u8;
extern var volume_3 @ 0x988D : u8;
extern var volume_4 @ 0x988E : u8;
extern var channel_enable @ 0x988F : u8;
let CHANNEL_ENABLE_4 = 0x10;
let CHANNEL_ENABLE_3 = 0x08;
let CHANNEL_ENABLE_2 = 0x04;
let CHANNEL_ENABLE_1 = 0x02;
let CHANNEL_ENABLE_0 = 0x01;
}
namespace ascii8 {
extern writeonly rom_4000 @ 0x4000 : u8;
extern writeonly rom_6000 @ 0x6000 : u8;
extern writeonly rom_8000 @ 0x8000 : u8;
extern writeonly rom_A000 @ 0xA000 : u8;
}
namespace ascii16 {
extern writeonly rom_4000 @ 0x4000 : u8;
extern writeonly rom_8000 @ 0x8000 : u8;
}
namespace io {
namespace vdp {
let data = 0x98;
let control = 0x99;
// Writing to the control port lets you access one of the following through the data port.
let CONTROL_ACCESS_REGISTER = 0x80;
let CONTROL_ACCESS_VRAM_READ = 0x00;
let CONTROL_ACCESS_VRAM_WRITE = 0x40;
// Reading the control port gives back VDP status.
let CONTROL_STATUS_BIT_VBLANK = 7;
let CONTROL_STATUS_BIT_SPRITE_OVERFLOW = 6;
let CONTROL_STATUS_BIT_SPRITE_COLLISION = 5;
let CONTROL_STATUS_MASK_VBLANK = 0x80;
let CONTROL_STATUS_MASK_SPRITE_OVERFLOW = 0x40;
let CONTROL_STATUS_MASK_SPRITE_COLLISION = 0x20;
let CONTROL_STATUS_MASK_FIFTH_SPRITE = 0x1F;
}
namespace vdp2 {
let palette = 0x9A;
let register_data = 0x9B;
}
namespace memory {
let control = 0x3E;
let CONTROL_EXPANSION_DISABLE = 0x80;
let CONTROL_CARTRIDGE_DISABLE = 0x40;
let CONTROL_CARD_DISABLE = 0x20;
let CONTROL_RAM_DISABLE = 0x10;
let CONTROL_BIOS_DISABLE = 0x04;
let CONTROL_DEVICE_DISABLE = 0x02;
}
namespace ppi {
let primary_slot = 0xA8;
let PRIMARY_SLOT_0000_MASK = 0x03;
let PRIMARY_SLOT_4000_MASK = 0x0C;
let PRIMARY_SLOT_8000_MASK = 0x30;
let PRIMARY_SLOT_C000_MASK = 0xC0;
let PRIMARY_SLOT_MAIN_ROM = 0;
let PRIMARY_SLOT_CART_A = 0;
let PRIMARY_SLOT_CART_B = 0;
let PRIMARY_SLOT_AUX = 0;
let keyboard_status = 0xA9;
let select = 0xAA;
let SELECT_KEYBOARD_CLICK = 0x80;
let SELECT_CAPSLOCK_LED = 0x40;
let SELECT_CASSETTE_AUDIO_OUT = 0x20;
let SELECT_CASSETTE_MOTOR_ON = 0x10;
let SELECT_KEYBOARD_LINE_MASK = 0x0F;
let control = 0xAB;
let CONTROL_BIT_INDEX_MASK = 0x0E;
let CONTROL_BIT_INDEX_SHIFT = 1;
let CONTROL_BIT_SET = 0x01;
let CONTROL_BIT_RESET = 0x00;
}
namespace psg {
let index = 0xA0;
let write = 0xA1;
let read = 0xA2;
}
namespace rtc {
let index = 0xB4;
let data = 0xB5;
}
namespace acia {
let data = 0x80;
let control = 0x81;
let CONTROL_STATUS_DATA_SET_READY = 0x80;
let CONTROL_STATUS_SYNC_BREAK = 0x40;
let CONTROL_STATUS_FRAMING_ERROR = 0x20;
let CONTROL_STATUS_OVERRUN_ERROR = 0x10;
let CONTROL_STATUS_PARITY_ERROR = 0x08;
let CONTROL_STATUS_TRANSMIT_EMPTY = 0x04;
let CONTROL_STATUS_RECEIVE_READY = 0x02;
let CONTROL_STATUS_TRANSMIT_READY = 0x01;
let CONTROL_MODE_STOP_2_BIT = 0xC0;
let CONTROL_MODE_STOP_1_5_BIT = 0x80;
let CONTROL_MODE_STOP_1_BIT = 0x40;
let CONTROL_MODE_STOP_INVALID = 0x00;
let CONTROL_MODE_PARITY_CHECK = 0x20;
let CONTROL_MODE_ENABLE_PARITY = 0x10;
let CONTROL_MODE_WORD_8_BIT = 0x0C;
let CONTROL_MODE_WORD_7_BIT = 0x08;
let CONTROL_MODE_WORD_6_BIT = 0x04;
let CONTROL_MODE_WORD_5_BIT = 0x00;
let CONTROL_MODE_BAUD_28_8_KHZ = 0x03;
let CONTROL_MODE_BAUD_115_2_KHZ = 0x02;
let CONTROL_MODE_BAUD_1843_2_KHZ = 0x01;
let CONTROL_MODE_BAUD_SYNC = 0x00;
let CONTROL_COMMAND_HUNT_MODE = 0x80;
let CONTROL_COMMAND_INTERNAL_RESET = 0x40;
let CONTROL_COMMAND_SEND_REQUEST = 0x20;
let CONTROL_COMMAND_CLEAR_ERRORS = 0x10;
let CONTROL_COMMAND_BREAK = 0x08;
let CONTROL_COMMAND_RECEIVE = 0x04;
let CONTROL_COMMAND_DATA_TERMINAL_READY = 0x02;
let CONTROL_COMMAND_TRANSMIT = 0x01;
}
let system_enable = 0xF5;
let SYSTEM_ENABLE_CLOCK_ID = 0x80;
let SYSTEM_ENABLE_LIGHTPEN = 0x40;
let SYSTEM_ENABLE_RS232C = 0x20;
let SYSTEM_ENABLE_MSX_INTERFACE = 0x10;
let SYSTEM_ENABLE_SUPERIMPOSE = 0x08;
let SYSTEM_ENABLE_MSX_AUDIO = 0x04;
let SYSTEM_ENABLE_KANJI_2 = 0x02;
let SYSTEM_ENABLE_KANJI_1 = 0x01;
let av_control = 0xF7;
let AV_CONTROL_REVERSE_VDP_BIT_5 = 0x80;
let AV_CONTROL_REVERSE_VDP_BIT_4 = 0x40;
let AV_CONTROL_YM_CONTROL = 0x20;
let AV_CONTROL_AV_CONTROL = 0x10;
let AV_CONTROL_ENABLE_RGB21_INPUT = 0x04;
let AV_CONTROL_L = 0x02;
let AV_CONTROL_R = 0x01;
let AV_CONTROL_STATUS_RGB21_INPUT_ENABLED = 0x08;
}
// VDP registers
namespace vdp {
namespace color {
let TRANSPARENT = 0;
let BLACK = 1;
let MEDIUM_GREEN = 2;
let LIGHT_GREEN = 3;
let DARK_BLUE = 4;
let LIGHT_BLUE = 5;
let DARK_RED = 6;
let CYAN = 7;
let MEDIUM_RED = 8;
let LIGHT_RED = 9;
let DARK_YELLOW = 10;
let LIGHT_YELLOW = 11;
let DARK_GREEN = 12;
let MAGENTA = 13;
let GRAY = 14;
let WHITE = 15;
}
let mode_control_0 = 0x00;
let MODE_CONTROL_0_DIGITIZE = 0x40;
let MODE_CONTROL_0_LIGHTPEN_MOUSE = 0x20;
let MODE_CONTROL_0_HBLANK_IRQ = 0x10;
let MODE_CONTROL_0_M5 = 0x08;
let MODE_CONTROL_0_M4 = 0x04;
let MODE_CONTROL_0_M3 = 0x02;
let MODE_CONTROL_0_EXTERNAL_INPUT = 0x01;
let mode_control_1 = 0x01;
let MODE_CONTROL_1_ENABLE = 0x40;
let MODE_CONTROL_1_VBLANK_IRQ = 0x20;
let MODE_CONTROL_1_M1 = 0x10;
let MODE_CONTROL_1_M2 = 0x08;
let MODE_CONTROL_1_SPRITE_16x16 = 0x02;
let MODE_CONTROL_1_SPRITE_8x8 = 0x00;
let MODE_CONTROL_1_SPRITE_STRETCH = 0x01;
let nametable_address = 0x02;
let NAMETABLE_ADDRESS_SHIFT = 10;
let colortable_address = 0x03;
let COLORTABLE_ADDRESS_SHIFT = 6;
let tile_pattern_address = 0x04;
let TILE_PATTERN_ADDRESS_SHIFT = 11;
let sprite_attribute_address = 0x05;
let SPRITE_ATTRIBUTE_ADDRESS_SHIFT = 7;
let sprite_pattern_address = 0x06;
let SPRITE_PATTERN_ADDRESS_SHIFT = 7;
let overscan_color = 0x07;
}
// VDP registers (MSX2 only)
namespace vdp2 {
let mode_control_2 = 0x08;
let MODE_CONTROL_2_MOUSE_SELECT = 0x80;
let MODE_CONTROL_2_LIGHTPEN_SELECT = 0x40;
let MODE_CONTROL_2_OPAQUE_COLOR0 = 0x20;
let MODE_CONTROL_2_COLOR_BUS_INPUT = 0x10;
let MODE_CONTROL_2_VRAM_SIZE_FAST_64K = 0x0C;
let MODE_CONTROL_2_VRAM_SIZE_64K = 0x08;
let MODE_CONTROL_2_VRAM_SIZE_4X_16K = 0x04;
let MODE_CONTROL_2_VRAM_SIZE_1X_16K = 0x00;
let MODE_CONTROL_2_DISABLE_OBJ = 0x02;
let MODE_CONTROL_2_GREYSCALE = 0x01;
let mode_control_3 = 0x09;
let MODE_CONTROL_3_SCREEN_HEIGHT_212 = 0x80;
let MODE_CONTROL_3_SCREEN_HEIGHT_192 = 0x00;
let MODE_CONTROL_3_SIMULTANEOUS_EXTERN = 0x20;
let MODE_CONTROL_3_SIMULTANEOUS_MIX = 0x10;
let MODE_CONTROL_3_SIMULTANEOUS_INTERN = 0x00;
let MODE_CONTROL_3_INTERLACE = 0x08;
let MODE_CONTROL_3_EVEN_ODD = 0x04;
let MODE_CONTROL_3_NTSC = 0x02;
let MODE_CONTROL_3_DOT_CLOCK_INPUT = 0x01;
let colortable_address_h = 0x0A;
let sprite_attribute_address_h = 0x0B;
let blink_color = 0x0C;
let blink_period = 0x0D;
let vram_bank_select = 0x0E;
let status_register_index = 0x0F;
let palette_index = 0x10;
let register_index = 0x11;
let REGISTER_INDEX_DISABLE_AUTO_INCREMENT = 0x80;
let display_adjust = 0x12;
let DISPLAY_ADJUST_X_MASK = 0x0F;
let DISPLAY_ADJUST_Y_MASK = 0xF0;
let DISPLAY_ADJUST_Y_SHIFT = 8;
let scanline_interrupt_line = 0x13;
let vscroll = 0x17;
let hscroll_control = 0x19;
let HSCROLL_CONTROL_COMMAND_ALTERNATE = 0x80;
let HSCROLL_CONTROL_COMMAND_NORMAL = 0x00;
let HSCROLL_CONTROL_PIN8_VDS = 0x20;
let HSCROLL_CONTROL_PIN8_CPU_CLOCK = 0x00;
let HSCROLL_CONTROL_ENABLE_YJK_ATTRIBUTES = 0x10;
let HSCROLL_CONTROL_ENABLE_YJK = 0x08;
let HSCROLL_CONTROL_ENABLE_WAITSTATE = 0x04;
let HSCROLL_CONTROL_HIDE_LEFTMOST = 0x02;
let HSCROLL_CONTROL_TWO_PAGE = 0x01;
let hscroll_offset_h = 0x1A;
let hscroll_offset_l = 0x1B;
let source_x_l = 0x20;
let source_x_h = 0x21;
let source_y_l = 0x22;
let source_y_h = 0x23;
let dest_x_l = 0x24;
let dest_x_h = 0x25;
let dest_y_l = 0x26;
let dest_y_h = 0x27;
let width_l = 0x28;
let width_h = 0x29;
let height_l = 0x2A;
let height_h = 0x2B;
let data = 0x2C;
let argument = 0x2D;
let command = 0x2E;
}
namespace psg {
let frequency_l_a = 0x00;
let frequency_h_a = 0x01;
let frequency_l_b = 0x02;
let frequency_h_b = 0x03;
let frequency_l_c = 0x04;
let frequency_h_c = 0x05;
let noise_period = 0x06;
let mixer = 0x07;
let MIXER_IO_PORT_B_OUTPUT = 0x80;
let MIXER_IO_PORT_A_OUTPUT = 0x40;
let MIXER_ENABLE_NOISE_C = 0x20;
let MIXER_ENABLE_NOISE_B = 0x10;
let MIXER_ENABLE_NOISE_A = 0x08;
let MIXER_ENABLE_TONE_C = 0x04;
let MIXER_ENABLE_TONE_B = 0x02;
let MIXER_ENABLE_TONE_A = 0x01;
let volume_a = 0x08;
let volume_b = 0x09;
let volume_c = 0x0A;
let envelope_frequency_l = 0x0B;
let envelope_frequency_h = 0x0C;
let envelope_shape = 0x0D;
let ENVELOPE_SHAPE_CONTINUE = 0x08;
let ENVELOPE_SHAPE_ATTACK = 0x04;
let ENVELOPE_SHAPE_ALTERNATE = 0x02;
let ENVELOPE_SHAPE_HOLD = 0x01;
let io_port_a = 0x0E;
let IO_PORT_A_CASSETTE = 0x80;
let IO_PORT_A_KEYBOARD_SWITCH = 0x40;
let IO_PORT_A_JOY_B = 0x20;
let IO_PORT_A_JOY_A = 0x10;
let IO_PORT_A_JOY_RIGHT = 0x08;
let IO_PORT_A_JOY_LEFT = 0x04;
let IO_PORT_A_JOY_DOWN = 0x02;
let IO_PORT_A_JOY_UP = 0x01;
let io_port_b = 0x0F;
let IO_PORT_B_LED = 0x80;
let IO_PORT_B_JOY_INDEX = 0x40;
let IO_PORT_B_PULSE_2 = 0x20;
let IO_PORT_B_PULSE_1 = 0x10;
let IO_PORT_B_TOUCHPAD_HANDSHAKE = 0x0F;
}
namespace rtc {
let mode = 0x0D;
let test = 0x0E;
let reset = 0x0F;
}
namespace ppi {
// Read is inverted from write.
extern var secondary_slot @ 0xFFFF : u8;
let SECONDARY_SLOT_0000_MASK = 0x03;
let SECONDARY_SLOT_4000_MASK = 0x0C;
let SECONDARY_SLOT_8000_MASK = 0x30;
let SECONDARY_SLOT_C000_MASK = 0xC0;
let SECONDARY_SLOT_AUX_SUB_DISK = 1;
let SECONDARY_SLOT_AUX_RAM = 2;
}
namespace ram {
extern var bank_0000 @ 0xFC : u8;
extern var bank_4000 @ 0xFD : u8;
extern var bank_8000 @ 0xFE : u8;
extern var bank_C000 @ 0xFF : u8;
}
}
namespace pce {
namespace vce {
// Control register.
extern writeonly control @ 0x0400 : u8;
let CONTROL_PIXEL_CLOCK_5MHz = 0x00;
let CONTROL_PIXEL_CLOCK_7MHz = 0x01;
let CONTROL_PIXEL_CLOCK_10MHz = 0x03;
let CONTROL_PIXEL_CLOCK_MASK = 0x03;
let CONTROL_FIELD_EXTRA_LINE = 0x04;
let CONTROL_STRIP_GREYSCALE = 0x80;
// Address registers.
extern writeonly address_l @ 0x0402 : u8;
extern writeonly address_h @ 0x0403 : u8;
// Data registers.
// Stored in a weird BRG333 format.
extern var data_l @ 0x0404 : u8;
extern var data_h @ 0x0405 : u8;
// Mask of possible blue color channel values.
let DATA_BLUE_MASK = 0x007;
// Starting bit of blue color channel.
let DATA_BLUE_SHIFT = 0;
// Mask of possible red color channel values.
let DATA_RED_MASK = 0x038;
// Starting bit of red color channel.
let DATA_RED_SHIFT = 3;
// Mask of possible green color channel values.
let DATA_GREEN_MASK = 0x1C0;
// Starting bit of green color channel.
let DATA_GREEN_SHIFT = 6;
}
namespace vdc {
// VDC status.
extern const status @ 0x0000 : u8;
let STATUS_BUSY_MASK = 0x40;
let STATUS_VBLANK = 0x20;
let STATUS_VRAM_DMA_END = 0x10;
let STATUS_SATB_DMA_END = 0x08;
let STATUS_SCANLINE = 0x04;
let STATUS_OVERFLOW = 0x02;
let STATUS_COLLISION = 0x01;
let STATUS_BUSY_BIT = 6;
// VDC port select.
extern writeonly select @ 0x0000 : u8;
let SELECT_VRAM_WRITE_ADDRESS = 0x00;
let SELECT_VRAM_READ_ADDRESS = 0x01;
let SELECT_VRAM_DATA = 0x02;
let SELECT_CONTROL = 0x05;
let SELECT_SCANLINE_COMPARE = 0x06;
let SELECT_SCROLL_X = 0x07;
let SELECT_SCROLL_Y = 0x08;
let SELECT_MEMORY_SIZE = 0x09;
let SELECT_HSYNC_SETTING = 0x0A;
let SELECT_HDISP_SETTING = 0x0B;
let SELECT_VSYNC_SETTING = 0x0C;
let SELECT_VDISP_HEIGHT = 0x0D;
let SELECT_VDISP_END = 0x0E;
let SELECT_DMA_CONTROL = 0x0F;
let SELECT_DMA_SOURCE = 0x10;
let SELECT_DMA_DEST = 0x11;
let SELECT_DMA_LEN = 0x12;
let SELECT_SATB_SOURCE_ADDRESS = 0x13;
// Data registers.
extern var data_l @ 0x0002 : u8;
extern var data_h @ 0x0003 : u8;
// Tilemap (also known as the Block Attribute Table / BAT) always starts at 0x0000.
// Size occupied is defined by tilemap memory size setting.
let DATA_VRAM_ADDRESS_TILEMAP = 0x0000;
let TILEMAP_INDEX_MASK = 0x0FFF;
let TILEMAP_ATTRIBUTE_MASK = 0xF000;
let DATA_H_CONTROL_INCREMENT_MASK = 0x18;
let DATA_H_CONTROL_INCREMENT_128 = 0x18;
let DATA_H_CONTROL_INCREMENT_64 = 0x10;
let DATA_H_CONTROL_INCREMENT_32 = 0x08;
let DATA_H_CONTROL_INCREMENT_1 = 0x00;
let DATA_L_CONTROL_ENABLE_BG = 0x80;
let DATA_L_CONTROL_ENABLE_SPRITES = 0x40;
let DATA_L_CONTROL_ENABLE_VBLANK_IRQ = 0x08;
let DATA_L_CONTROL_ENABLE_HBLANK_IRQ = 0x04;
let DATA_L_CONTROL_ENABLE_SPRITE_OVERFLOW_IRQ = 0x02;
let DATA_L_CONTROL_ENABLE_SPRITE_ZERO_HIT_IRQ = 0x01;
let DATA_SCROLL_MASK = 0x1FF;
let DATA_L_MEMORY_SIZE_VRAM_PIXEL_WIDTH_MASK = 0x03;
let DATA_L_MEMORY_SIZE_VRAM_SPRITE_WIDTH_MASK = 0x0C;
let DATA_L_MEMORY_SIZE_VRAM_SPRITE_WIDTH_SHIFT = 2;
let DATA_L_MEMORY_SIZE_TILEMAP_32x32 = 0x00;
let DATA_L_MEMORY_SIZE_TILEMAP_64x32 = 0x10;
let DATA_L_MEMORY_SIZE_TILEMAP_128x32 = 0x20;
let DATA_L_MEMORY_SIZE_TILEMAP_32x64 = 0x40;
let DATA_L_MEMORY_SIZE_TILEMAP_64x64 = 0x50;
let DATA_L_MEMORY_SIZE_TILEMAP_128x64 = 0x60;
let DATA_L_MEMORY_SIZE_TILEMAP_MASK = 0x70;
let DATA_L_MEMORY_SIZE_TILEMAP_SHIFT = 4;
let DATA_L_HSYNC_SETTING_SYNC_WIDTH_MASK = 0x1F;
let DATA_H_HSYNC_SETTING_DISPLAY_START_MASK = 0x7F;
let DATA_L_HDISP_SETTING_DISPLAY_WIDTH_MASK = 0x7F;
let DATA_H_HDISP_SETTING_DISPLAY_END_MASK = 0x7F;
let DATA_L_VSYNC_SYNC_HEIGHT_MASK = 0x1F;
let DATA_H_VSYNC_DISPLAY_START_MASK = 0xFF;
let DATA_VDISP_HEIGHT_MASK = 0x1FF;
let DATA_VDISP_END_MASK = 0x1FF;
let DATA_L_DMA_CONTROL_ENABLE_SATB_DMA_END_IRQ = 0x01;
let DATA_L_DMA_CONTROL_ENABLE_VRAM_DMA_END_IRQ = 0x02;
let DATA_L_DMA_CONTROL_SOURCE_INCREMENT = 0x00;
let DATA_L_DMA_CONTROL_SOURCE_DECREMENT = 0x04;
let DATA_L_DMA_CONTROL_DEST_INCREMENT = 0x00;
let DATA_L_DMA_CONTROL_DEST_DECREMENT = 0x08;
let DATA_L_DMA_CONTROL_SATB_AUTO_TRANSFER = 0x10;
let SATB_Y_MASK = 0x3FF;
let SATB_X_MASK = 0x3FF;
// sprite data VRAM address shifted right 5 bits (Shift left 6 bits to get real VRAM address)
let SATB_VRAM_ADDRESS_MASK = 0x3FF;
// sprite attributes
let SATB_ATTRIBUTE_H_VFLIP = 0x80;
let SATB_ATTRIBUTE_H_HEIGHT_16 = 0x00;
let SATB_ATTRIBUTE_H_HEIGHT_32 = 0x10;
let SATB_ATTRIBUTE_H_HEIGHT_64 = 0x30;
let SATB_ATTRIBUTE_H_HEIGHT_MASK = 0x30;
let SATB_ATTRIBUTE_H_HFLIP = 0x0800;
let SATB_ATTRIBUTE_H_WIDTH_16 = 0x00;
let SATB_ATTRIBUTE_H_WIDTH_32 = 0x01;
let SATB_ATTRIBUTE_L_BG_PRIORITY = 0x80;
let SATB_ATTRIBUTE_L_PALETTE_INDEX_MASK = 0x0F;
let SATB_OFFSET_Y = 0x00;
let SATB_OFFSET_X = 0x01;
let SATB_OFFSET_VRAM_ADDRESS = 0x01;
let SATB_OFFSET_ATTRIBUTE = 0x01;
}
namespace irq {
// Controls which interrupts are disabled.
extern var disable @ 0x1402 : u8;
// Pending interrupts.
extern const status @ 0x1403 : u8;
// Write here to acknowledge a timer interrupt.
extern writeonly acknowledge @ 0x1403 : u8;
// Timer interrupts.
let INTERRUPT_TIMER = 0x04;
// VDC-generated interrupts.
let INTERRUPT_VDC = 0x02;
// External interrupts. (cartridge, super-CD, user-requested)
let INTERRUPT_EXTERNAL = 0x01;
// Mask of all interrupts.
let INTERRUPT_ALL = 0x07;
}
namespace timer {
// Current timer value.
extern const value @ 0x0C00 : u8;
// Mask of possible timer values.
let VALUE_MASK = 0x7F;
// Timer reload value.
extern writeonly reload @ 0x0C00 : u8;
// Mask of possible timer reload values.
let RELOAD_MASK = 0x7F;
// Timer control register.
extern writeonly control @ 0x0C01 : u8;
// Enable the timer.
let CONTROL_ENABLE = 0x01;
}
namespace io {
// Input port.
extern const input @ 0x1000 : u8;
// Mask for CDROM connection (0 = attached, 1 = detached)
let INPUT_CD_MASK = 0x80;
// Mask for country code. (0 = Japan, 1 = US)
let INPUT_COUNTRY_MASK = 0x40;
// Mask of possible values for button reading.
let INPUT_VALUE_MASK = 0x0F;
// Bit for CDROM connection (0 = attached, 1 = detached)
let INPUT_CD_BIT = 7;
// Bit for country code. (0 = Japan, 1 = US)
let INPUT_COUNTRY_BIT = 6;
// Output port.
extern writeonly output @ 0x1000 : u8;
// Clear pin.
let OUTPUT_CLEAR = 0x02;
// Select pin.
let OUTPUT_SELECT = 0x01;
namespace joy {
// Select buttons.
let SELECT_BUTTONS = 0x00;
// Select directionals.
let SELECT_DIRECTIONS = 0x01;
// I button status.
let BUTTON_I = 0x01;
// II button status
let BUTTON_II = 0x02;
// Select button status.
let BUTTON_SELECT = 0x04;
// Start button status.
let BUTTON_RUN = 0x08;
// Mask of all possible buttons.
let BUTTON_MASK = 0x0F;
// Up direction status.
let DIRECTION_UP = 0x01;
// Right direction status.
let DIRECTION_RIGHT = 0x02;
// Down direction status.
let DIRECTION_DOWN = 0x04;
// Left direction status.
let DIRECTION_LEFT = 0x08;
// Mask of all possible directions.
let DIRECTION_MASK = 0x0F;
// III button status for 6-button controller.
let BUTTON_6B_III = 0x01;
// IV button status for 6-button controller.
let BUTTON_6B_IV = 0x02;
// V button status for 6-button controller.
let BUTTON_6B_V = 0x04;
// VI button status for 6-button controller.
let BUTTON_6B_VI = 0x08;
}
}
namespace psg {
// http://www.magicengine.com/mkit/doc_hard_psg.html
namespace channel_data {
// 12-bit frequency low bits (bits 0 .. 7)
extern writeonly frequency_l @ 0x0802 : u8;
// 12-bit frequency high bits (bits 8 .. 11)
extern writeonly frequency_h @ 0x0803 : u8;
// Mask of possible values that are used for high bits of frequency.
let FREQUENCY_H_MASK = 0x0F;
// Control register
extern writeonly control @ 0x0804 : u8;
// Enable wave output.
let CONTROL_ENABLE_WAVE = 0x80;
// Enable direct output.
let CONTROL_ENABLE_DIRECT = 0xC0;
// Wave index is reset to beginning.
let CONTROL_RESET_WAVE_INDEX = 0x40;
// Mask of possible values that can be used for gain.
let CONTROL_GAIN_MASK = 0x1F;
// Volume register.
extern writeonly volume @ 0x0805 : u8;
// Mask of possible values that can be used for left volume.
let VOLUME_LEFT_MASK = 0xF0;
// Mask of possible values that can be used for right volume.
let VOLUME_RIGHT_MASK = 0x0F;
// Wave data register. Writes a single sample into the 32-sample wave buffer of the channel at the current index.
extern writeonly wave @ 0x0806 : u8;
// Mask of possible values that can be used for wave sample data.
let WAVE_DATA_MASK = 0x1F;
// (Channels 4 .. 5) Noise register.
extern writeonly noise @ 0x0807 : u8;
// Enable noise on this channel.
let NOISE_ENABLE = 0x80;
// Mask of possible values that can be used for noise frequency.
let NOISE_FREQUENCY_MASK = 0x1F;
}
// Current channel to write data for.
extern writeonly channel_index @ 0x0800 : u8;
// Number of channels available on the PSG.
let CHANNEL_COUNT = 6;
// Master volume.
extern writeonly volume @ 0x0801 : u8;
// Mask of possible values that can be used for left volume.
let VOLUME_LEFT_MASK = 0xF0;
// Mask of possible values that can be used for right volume.
let VOLUME_RIGHT_MASK = 0x0F;
namespace lfo {
// LFO frequency register. Multiplied against channel 1's 12-bit frequency to get the effective frequency of the LFO.
extern writeonly frequency @ 0x0808 : u8;
// LFO control register.
extern writeonly control @ 0x0809 : u8;
// Enable LFO modulation mode (channel 1 is used to control an LFO that gets applied to channel 0)
let CONTROL_ENABLE = 0x80;
// Add LFO sample x 0 to channel 0 (no modulation)
let CONTROL_LFO_SAMPLE_MULTIPLIER_0 = 0x00;
// Add LFO sample x 1 to channel 0
let CONTROL_LFO_SAMPLE_MULTIPLIER_1 = 0x01;
// Add LFO sample x 16 to channel 0
let CONTROL_LFO_SAMPLE_MULTIPLIER_16 = 0x02;
// Add LFO sample x 256 to channel 0
let CONTROL_LFO_SAMPLE_MULTIPLIER_256 = 0x03;
// Mask of possible values that can be used for the LFO sample multiplier.
let CONTROL_LFO_SAMPLE_MULTIPLIER_MASK = 0x03;
}
}
namespace syscard {
// Add address definition for Backup RAM
// Add address definition for Work RAM
// Add entry points to call System Card BIOS ROM
}
namespace cdrom {
// Add entry points to call Super CD-ROM2 BIOS
}
// TODO: Memory Base 128 routines.
// https://forums.nesdev.com/viewtopic.php?f=5&t=13082&hilit=memory+base+128
// http://pcedev.blockos.org/viewtopic.php?f=5&t=98
}<7D>PNG

IHDR<00><00>1|<7C>,tEXtCreation TimeTue 15 Feb 2011 18:41:59 -0500<30><12><>tIME<07>$<10><>T<EFBFBD> pHYs
<EFBFBD>
<EFBFBD>B<>4<EFBFBD>gAMA<00><> <0B>a0PLTE#I<00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD>,<2C><><EFBFBD><00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
pVZIDATx<54><78>V<EFBFBD>b<EFBFBD> <0C><><EFBFBD>xc<78>Wa<57>Ư<EFBFBD><C6AF><EFBFBD>'<27><><EFBFBD><EFBFBD>7<EFBFBD><1E>i<EFBFBD><04>lˆ<10><><EFBFBD>m
<EFBFBD><EFBFBD><>~<7E>W <0A>D<>juV<75>U<>("> <20>Aj<41><6A>;p<>Q0<0F>]pI#&/]<5D><>0cK<63>T<EFBFBD><54><EFBFBD><EFBFBD>,<2C>ߖ<EFBFBD><DF96><EFBFBD>"x<><78><EFBFBD>n<EFBFBD><6E>9<EFBFBD><39><00>Ԫ<>C<EFBFBD>+clv&<00><><1A>+<2B> @<40><>f<EFBFBD>՗<EFBFBD><11><02>à<1E><><00><><EFBFBD><EFBFBD><17>w<EFBFBD><77>t<EFBFBD>;<3B>bc<62>ej<05><><EFBFBD> <0B>o<><6F>|_<><5F>$<24>T<EFBFBD>]<5D>r<EFBFBD>[6<>P[U<><55><EFBFBD><EFBFBD><EFBFBD>l <0A>
QK<EFBFBD><1D>s<EFBFBD><08>:<3A>Z?<3F>r<EFBFBD>-<2D><00>gfj <20>%^<5E>#<23>!<08>.<2E><>p<EFBFBD>X0<58>ӈ<EFBFBD><17>|Qbb)<29>dwfF-"<1E><1D><04>%|O<>N}<7D>'SK<00>L<EFBFBD>P<><50>CC<43><43>/^<5E><><EFBFBD>0<EFBFBD><03><>Q<EFBFBD>
c<EFBFBD>4V<EFBFBD><EFBFBD>i\F<><46>G<EFBFBD> q<00>><3E>E<10><><EFBFBD>Tg<54>c{<7B>D<EFBFBD><44>{<7B><05><><00>\<5C>J*J><3E>J<EFBFBD>7<EFBFBD><37><17><>1<EFBFBD>d<EFBFBD><64><00> <10>Re<52>>+ <12><>h<EFBFBD>ۅ<EFBFBD><DB85>u<EFBFBD>/s<>u<>V<EFBFBD>^<5E><17>̣<EFBFBD>+<2B><>J<19><><EFBFBD>A<04><>t<EFBFBD>T<EFBFBD><54>^(Y<><59><EFBFBD><EFBFBD>Ƣ<EFBFBD><C6A2>ԯ,<<3C><>I]<02><><EFBFBD><04>}|w<><77>)C`?<3F>Ϙ<EFBFBD>tto<><6F>-V^<5E><EFBFBD><E4BABC>̢<EFBFBD><CCA2>A!<21><><EFBFBD>qA<71><41><EFBFBD>cU<63>d<EFBFBD>6PE-5P`m<00>8<EFBFBD>+y<>)_@<40>0TJ<0F>@<40>6d<10>O<EFBFBD>a<EFBFBD>/<2F><>R1<><31><14> ki<19><> <09>E#d<><64>4<EFBFBD><0E>թ<EFBFBD> <0A>A <05><>l<EFBFBD> <0B><><03><>05<30>|<00><>ӟ2.<05><>
#;<3B>
<EFBFBD>=<3D>X<17>GCN<43>AL<41>'<27><>y@<40>ǎJ2<4A><32><EFBFBD><07>i<EFBFBD> 5Ép<C389>v <0C>My<4D><&h<><68>baaÊޙtY<11>%~[ܯ<><DCAF>p$a<>n F<><02><><EFBFBD>AQ"e<>`p0<70>ة <0A><><07><>0<EFBFBD>P<EFBFBD>Ip<49><70>7<EFBFBD><37><EFBFBD><EFBFBD> <09><>ŋ<EFBFBD><C58B><EFBFBD>xy h.
<00><>B<EFBFBD>@}<7D><><04><>gW<67><06>h
<EFBFBD>z<63><CFB0>GE<1E>pAb<41>{"<22><>"[<04>[<10><><EFBFBD><10>d] `<05><>u<EFBFBD><75>2<EFBFBD><06><1A><> ubJ<62><4A><04><05>D/<2F><>_<EFBFBD><5F><EFBFBD><EFBFBD>><3E><>
<EFBFBD><EFBFBD>8<EFBFBD>Ť>\T<1E><><EFBFBD>;<13>-<2D><><EFBFBD>" <0B>2<EFBFBD><32><19>M<EFBFBD>Ϟ;<3B><>><3E>L<EFBFBD><4C>S<0E><><13><>ꤒE<EAA492>w<><77><EFBFBD><EFBFBD>oLK>:<3A><>b<EFBFBD><62><00>|!mc^h<13><><EFBFBD>gx<>kag<06>EѱY<D1B1>n<EFBFBD><6E>xt<11><08>9<19>;;<3B>v<EFBFBD><01><18>U<EFBFBD><55><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><1C><05>o8,<2C><><EFBFBD>ё<EFBFBD><D191><00>YX[R<11> <0A>^?<3F>҃<><D283><EFBFBD>h<><68>}\2<><32>*}<10> <0C><><00><>c<EFBFBD>
7>P M6cg<63>'<06><><EFBFBD>Nn:<3A><><EFBFBD>.<2E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><02>D<>J2<4A><08><>1<03><><64>*q><3E>zT<>lk <0C>a<EFBFBD><61>+<2B><1D><><EFBFBD>n<EFBFBD>pv<70>#<10><><EFBFBD><EFBFBD><EFBFBD>)^<5E>u<EFBFBD><75>B<EFBFBD>{<7B>|<7C>
;A<EFBFBD><EFBFBD>T8%<25><>!|<04><> m<><6D><EFBFBD><EFBFBD><15><>!Lغ<1B>LLφ]·w5<0F><>{=<00><><EFBFBD>lNl<4E>}u+<02>í<EFBFBD>|8<>e@<40>FPD<50>n<EFBFBD>l<EFBFBD><00><><EFBFBD><EFBFBD>1<0F>K<EFBFBD><4B><07>Py
ˈ<EFBFBD>J) <0B>2p,<2C><>η3T<33><54>/<2F><><EFBFBD>ʶ<EFBFBD>j<EFBFBD>7<EFBFBD>A<EFBFBD><08><>8:<04><>i<EFBFBD><69>9<1F><>8<EFBFBD><38><EFBFBD><EFBFBD>QN<51>n<EFBFBD> D&<00>&b<><04><><EFBFBD>π8Ӓ<38><03>}B<><42>Np<4E>1Y8@<40><><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD>k<EFBFBD><6B><EFBFBD><EFBFBD><EFBFBD><07><><EFBFBD>s<EFBFBD><03><>IEND<4E>B`<60><>PNG

IHDR<00><00>1|<7C>tIME<07>%+ <0B><>[ pHYs
<EFBFBD>
<EFBFBD>B<>4<EFBFBD>gAMA<00><> <0B>a0PLTE<00><00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><00><><00><><00><00><><EFBFBD><EFBFBD><EFBFBD>O&I<01>IDATx<54><78>SK<53>,!<08><13>'<27><><EFBFBD><EFBFBD><13><12>~<7E><>z<16>%]<5D><><1A><>H<EFBFBD>P(
w<EFBFBD><12>K<EFBFBD><4B>7<EFBFBD><37><19><16>iC<1F>$6<>b<EFBFBD><62>ch<63>CF<43><46><EFBFBD><EFBFBD><EFBFBD>`߀l}<7D><>v<EFBFBD>U<EFBFBD><55><EFBFBD><EFBFBD> <01>Ǻ<EFBFBD><1A>X<EFBFBD><0F><>L<EFBFBD>&C<><43><EFBFBD>. <0B><><EFBFBD>q<EFBFBD><71>Z<><16>\]I@<40>I6G<><47><EFBFBD><19>G4<47>rd<72><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD>J<02><>{^1pf0<66>CzL8<1F>k>V<><0E>=<3D><><04><>Bg<12><>P$<24>J{<7B><02><>i<EFBFBD>:<3A>6}c<>[<5B>qL<71>x<><7F>D<><44>M<EFBFBD>[<5B>be;du<64>{x<>?d<><1E>h<EFBFBD><68>$<24><>ʵ~p<><70>&<26><11><>=<14>}<7D> <20><>;<3B><04><08><>ga? Z<>y<EFBFBD><79><EFBFBD>!Ps<50><73>$>Ob<O<>9<EFBFBD><39>q<EFBFBD><71>ڏ<> V<>ϱֲFr<46>zvy<76><79>o<EFBFBD>G8<47>`Eb?<3F><>C<EFBFBD><43><EFBFBD>?\q#/<04>ۚ<EFBFBD><73>I<02><><EFBFBD><EFBFBD>-<13>I<EFBFBD><49>`<60><>|l<> <0B><>AAo1<6F><31><EFBFBD>ƛ<EFBFBD><C69B>H<EFBFBD>;<3B><>H]<5D><><EFBFBD><EFBFBD>5<EFBFBD>ͶA<CDB6><41>__t<5F><74>/]<5D><><EFBFBD><EFBFBD><EFBFBD>F4<46>zS!<21><>KW<4B>1<EFBFBD><31>7<>׆
<EFBFBD>B<EFBFBD>P(
<EFBFBD>B<EFBFBD>P(
<EFBFBD><EFBFBD><1F>yB<79>&IEND<4E>B`<60>88|L<><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>d|8888LL<4C><4C><EFBFBD><EFBFBD><EFBFBD><EFBFBD>dd88888<<<88<<||<7C><><EFBFBD>><|`<60><><EFBFBD><EFBFBD><EFBFBD>||<7C><><<``<60><><EFBFBD><EFBFBD>||<7C><><EFBFBD>><><06><><EFBFBD>||||<7C><><<<06><>||<<|l<><6C><EFBFBD><EFBFBD><EFBFBD> <<ll<6C><6C><EFBFBD><EFBFBD> <00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><06><><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><06><><<|`<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<<``<60><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD> 8000000<00><> 000000||<7C><><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD>~~ |xx||<7C><><EFBFBD><EFBFBD>~~ xx88|l<><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>88ll<6C><6C><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~~~~~~~~~<06><><EFBFBD><EFBFBD><EFBFBD>||<06><><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>zz||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>zz<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD>|~<06><><EFBFBD>||||<7C><><EFBFBD><EFBFBD>||<06><>||~~~~~<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||88<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||88<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD>||8||<7C><><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD>||88||<7C><><EFBFBD><EFBFBD>ffffff~<<ffffff<<<00><><EFBFBD><8xp<78><70><EFBFBD><EFBFBD><EFBFBD><00><>88pp<70><70><EFBFBD><EFBFBD>
import os.path
import PIL.Image
def write_chr(w, h, data, f):
for y in range(0, h, 8):
for x in range(0, w, 8):
for j in range(8):
# Write low bits of this row.
c = 0
for i in range(8):
c = (c * 2) | (data[x + i, y + j] & 1)
f.write(bytearray([c]))
# Write second bits of this row.
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, y + j] >> 1) & 1)
f.write(bytearray([c]))
for j in range(8):
# Write third bits of this row.
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, y + j] >> 2) & 1)
f.write(bytearray([c]))
# Write high bits of this row.
c = 0
for i in range(8):
c = (c * 2) | ((data[x + i, y + j] >> 3) & 1)
f.write(bytearray([c]))
if __name__ == '__main__':
import sys
if len(sys.argv) > 1:
WIDTH = 128
HEIGHT = None
for arg in range(1, len(sys.argv)):
filename = sys.argv[arg]
if filename[0] == '-':
if filename == '-oldfart':
HEIGHT = 192
elif filename == '-newfart':
HEIGHT = None
else:
exit('Invalid argument `' + filename + '`.')
continue
try:
img = PIL.Image.open(filename)
except IOError as e:
if os.path.isdir(filename):
exit(filename + ' is a directory.')
if os.path.exists(filename):
exit(filename + ' has an unsupported filetype, or you lack permission to open it.')
else:
exit('File ' + filename + ' does not exist!')
w, h = img.size
if w != WIDTH or h % 8 != 0 or HEIGHT and h != HEIGHT:
exit('Image ' + filename + ' is not ' + str(WIDTH) + 'x' + str(HEIGHT) + ' pixels in size.')
if not img.palette:
exit('Image ' + filename + ' has no palette.')
data = img.load()
save_filename = os.path.splitext(filename)[0] + '.chr'
try:
f = open(save_filename, 'wb')
except Exception as e:
exit('Failure attempting to write ' + save_filename)
write_chr(w, h, data, f)
f.close()
print(' ' + filename + ' -> ' + save_filename)
else:
print('Usage: ' + sys.argv[0] + ' file [file...]')
print('Converts files like foo.png into Game Gear-friendly formats like foo.chr')
@@@@<00> <00><00><00><00><><EFBFBD><EFBFBD><EFBFBD><00><><<<00><><EFBFBD><EFBFBD><<3C><><00><<<00><00><00><00><00><00><00><00><00><00>ll<6C><6C><EFBFBD><EFBFBD><EFBFBD>||88ll<6C><6C><EFBFBD><EFBFBD>||88<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>xr0 Hv<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>x~0<60000<00>||88080|<00>||8833<33><33><00><>33<33><33>ș<>;<00>~~:~:<3A><><EFBFBD>D|88<00><02>:<3A>:<3A><><EFBFBD>DD88UP<55><50><EFBFBD><EFBFBD><EFBFBD>pp PR<50><52><EFBFBD><EFBFBD>pp >6<7F>N<EFBFBD>J<EFBFBD>$<24>Z<EFBFBD>l|66N~J~$<Z~ll<00>v<EFBFBD><76><EFBFBD><EFBFBD><EFBFBD><08>ڇ<EFBFBD><DA87><EFBFBD><EFBFBD>vvv<76><76><EFBFBD><EFBFBD>~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>vv<76>~<7E>B<EFBFBD>B<EFBFBD><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~~BBBB<42><42><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~BBBZ<18><NN~~<7E><$$<<~N<>~<7E>~<00><1E>R<EFBFBD>^<5E>^<5E>@<40>R^^^^^@~>qP<71>P<EFBFBD>x~F&<00><00>P<EFBFBD>P\xx><18>qP<71>P<EFBFBD><50><EFBFBD>Ñ<00><00>P<EFBFBD>P\<5C><><EFBFBD><EFBFBD>n<><00><00><<3C><><EFBFBD><EFBFBD>O~<00><00>~<<<3C><><EFBFBD><EFBFBD>3<>fB<66>Z<EFBFBD><<3C>C<EFBFBD><43><EFBFBD><EFBFBD>~<00>B<EFBFBD>ZZ<<CC<43><43><EFBFBD><EFBFBD><$B<<ZZ~<ZB<00>~<~<18><00><00>~<<<3C><><EFBFBD><EFBFBD><<<<<3C><><EFBFBD><EFBFBD><<<<~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~<<<<~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~<<<3C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD>~<<3C>Z<EFBFBD>Z<EFBFBD><00>Ã<><C383><EFBFBD><<ZZZZ~g<><67><EFBFBD><EFBFBD>p<>D@V~~Z~<<3C>A<EFBFBD><41>~@<40><04><18>Z<EFBFBD><<3C>AC<41><43>(D<00><00><00>|88|8|<10>~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>|<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>||<7C><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~<<<<~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~~<<<<~~<7E><><EFBFBD><EFBFBD>88pp||88>8|p<>|<7C>8|><<<<,,<<~<~,~~Z @@@@< ~@<40>@<40><02><02>~<<00><><EFBFBD><EFBFBD>``~<03><01><00><00><><EFBFBD><EFBFBD><EFBFBD>`~<00><> B<><42>!<00>B (  f<00><00>`<<00~<00><<3C><<3C>$<24><00><00><<~<~$~B<~~<00><<3C><00><00><00><00><<3C><<~BBB~<~<~$B<00><00>~<7E>f<EFBFBD>f<EFBFBD><~<00>~~ffff<~<<3C>~BZ<00><<~~<00><00><00><00><00><00><00><00><00><00>ZZZZ~~<$$~~tt>>66~~tt>>66~t>6<00><00><00><00><<<00>B~~<00><00><00>$<<00><00><00><00>~<00><00><00>~B<<00><1F><><EFBFBD>~<7E><03>I<EFBFBD><00><1F><>~~II~<00><><00><1F><><EFBFBD>~<7E><01>H<EFBFBD><1F><>~~HJ<00><> FP<10>98
b`<60><> y??8<7F><08>`<60><><EFBFBD><EFBFBD><<00>@<40><><EFBFBD><EFBFBD><EFBFBD>~<00><00><00>@|<7C><><EFBFBD><EFBFBD> <0C><><EFBFBD>~<7E><><EFBFBD>~<7E><00>A<EFBFBD><41><EFBFBD> <0C><>~~<7E><>~~A]<5D><> <0C><<3C><><EFBFBD>f<00><00>~<7E><><EFBFBD><EFBFBD><<<3C><><<00>~~~<7E><><EFBFBD>ǂ<00>m<00><00><00><00>|:<00><00>8s~<8DZ~&$8<8DZ~<R<8<<<,<FB~f$n88<$<<FZ~f$v8<$<$B~BI?<<6>>>>>>>>>B<00><00><00>Z<00><00>3<~ZZ$A<00><B<00><00><00>!<Z~<00><00><<<00><00><00>@<Z<00><00><?B<00><00>ZZ<<<~<00>ZZZ<5A><<3C><00><00>8x0<78>`<60><><EFBFBD>`x0800``<60><>``00>>*>>**+F<00>1<00>9<00>$H<00>D"dH0p80<>~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Z<EFBFBD><5A><EFBFBD> ~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ZZ<5A><5A>~<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>BBZZBB~~~~~BBZZBB~~~<00><00><00><00><00><00>~<7E>UUUUU|<00><00><00><00><00><00><00>>66><|8||866668888B$<00>~<18>Z<EFBFBD><"3<00><00>~<18>ZZ<=<00><00><>~<7E><><EFBFBD><EFBFBD><EFBFBD>€?>?3~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ۀ<EFBFBD>><3E>3<EFBFBD>s<00>Z<EFBFBD><5A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>X ZZ<5A><5A><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>XXB@<40><><EFBFBD><EFBFBD>}<00><><00><>@|<7C><><EFBFBD><EFBFBD><00><><EFBFBD><00><><EFBFBD><00><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>??<3F><><1E><1F><1F><1F>??<3F><>``ss77<37><37><EFBFBD><EFBFBD>__``ss77<37><37><EFBFBD><EFBFBD>__8<00>M<00><00>|<00><00>|<00>|<00><08>Z<EFBFBD>Z<EFBFBD><<<<3C>nZZZZ<<<<<<nn<<<<ff<66><66>ff<f<<3C>f<<ff<66><66>ff<66><66>55\\<5C>Ճ<EFBFBD><00><>55\|<7C><><EFBFBD><EFBFBD><01>~<00><><EFBFBD><EFBFBD>BBBBJJZZnn<6E><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD>BBBBJJZZnn<6E><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>сՁՁ<D581><D581><EFBFBD> <00><00> <00><00>`8<00><00>P<EFBFBD> <20>[ZYX<59>PT 8|Z<>X<EFBFBD>|<7C>n<EFBFBD><6E><EFBFBD><EFBFBD><EFBFBD><15><00><><EFBFBD>~n~<7E><><EFBFBD><EFBFBD><15><00><>~~<7E><00><00><00><00><00><00><00>|J~B~R~<00><><00><><EFBFBD><EFBFBD>$$<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD>$<24><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00>p<EFBFBD>0<EFBFBD>p<EFBFBD>]"pp0|pr""ZBBZZZBBBBZZZZBBBBZZ
namespace bcd {
// Arguments:
// l = an 8-bit binary number
// Result:
// chl = a 6-digit bcd number
// Dirty: all registers
func from_byte(value : u8 in l) {
b = 8;
de = 0x0000;
do {
l <<= 1;
a = e;
a +#= a;
decimal_adjust();
e = a;
a = d;
a +#= a;
decimal_adjust();
d = a;
b--;
} while !zero;
l = e;
h = d;
c = 0;
}
// Arguments:
// hl = a 16-bit binary number
// Result:
// chl = a 6-digit bcd number
// Dirty: all registers
func from_word(value : u16 in hl) {
bc = 0x1000;
de = 0x0000;
do {
l <<= 1;
h <<<<#= 1;
a = e;
a +#= a;
decimal_adjust();
e = a;
a = d;
a +#= a;
decimal_adjust();
d = a;
a = c;
a +#= a;
decimal_adjust();
c = a;
--b;
} while !zero;
l = e;
h = d;
}
// Arguments:
// chl = a 6-digit bcd number
// Result:
// d = number of digits (1-6)
// Dirty: a, d
func get_length(high : u8 in c, mid : u8 in h, low : u8 in l) : u8 in d {
d = 6;
a = c & 0xF0;
return d if !zero;
d--;
a = c & 0x0F;
return d if !zero;
d--;
a = h & 0xF0;
return d if !zero;
d--;
a = h & 0x0F;
return d if !zero;
d--;
a = l & 0xF0;
return d if !zero;
d--;
return d;
}
// Arguments:
// de = destination string buffer. must be at least 7 characters: 6 digits + 0 terminator.
// chl = a 6-digit bcd number
// Dirty: all registers
func to_string(dest : u16 in de, high : u8 in c, mid : u8 in h, low : u8 in l) {
push(de);
b = d = get_length(c, h, l);
de = pop();
e = a = e + b;
d = a = d +# 0;
*(de as *u8) = a = 0;
de--;
a = l;
*(de as *u8) = a = (a & 0x0F) + '0';
b--;
return if zero;
de--;
a = l; swap_digits(a);
*(de as *u8) = a = (a & 0x0F) + '0';
b--;
return if zero;
de--;
a = h;
*(de as *u8) = a = (a & 0x0F) + '0';
b--;
return if zero;
de--;
a = h; swap_digits(a);
*(de as *u8) = a = (a & 0x0F) + '0';
b--;
return if zero;
de--;
a = c;
*(de as *u8) = a = (a & 0x0F) + '0';
b--;
return if zero;
de--;
a = c; swap_digits(a);
*(de as *u8) = a = (a & 0x0F) + '0';
}
}import "gb";
import "banks";
namespace joy {
in ram {
namespace bit {
let A = 0;
let B = 1;
let SELECT = 2;
let START = 3;
let RIGHT = 4;
let LEFT = 5;
let UP = 6;
let DOWN = 7;
}
namespace mask {
let A = 1 << bit.A;
let B = 1 << bit.B;
let SELECT = 1 << bit.SELECT;
let START = 1 << bit.START;
let RIGHT = 1 << bit.RIGHT;
let LEFT = 1 << bit.LEFT;
let UP = 1 << bit.UP;
let DOWN = 1 << bit.DOWN;
}
var unpress : u8;
var pressed : u8;
var reset : u8;
var was_reset_already : u8;
}
func init() {
unpress = a = 0;
pressed = a = 0;
reset = a = 0;
was_reset_already = a = 0;
update();
a = reset;
if a != 0 {
was_reset_already = a = 1;
reset = a = 0;
}
}
// Read joypad data unfiltered so it can be passed to input checking or SGB packet read routines.
// Result: c = current controller state, a = joypad id.
func read_raw() {
// Read up/down/left/right.
gb.joy.ctrl = a = gb.joy.select.DIRECTIONS;
// Read twice are to prevent bounce.
inline for let i in 1 .. 2 {
a = gb.joy.ctrl;
}
// a = 0000dulr
a = ~a & 0xF;
// a = dulr0000
swap_digits(a);
// controls = a
c = a;
// Read A/B/Select/Start
gb.joy.ctrl = a = gb.joy.select.BUTTONS;
// Read 6 times to prevent bounce.
inline for let i in 1 .. 6 {
a = gb.joy.ctrl;
}
// a = dulrssba
a = (~a & 0xF) | c;
// controls = a
c = a;
// Get the joypad id.
gb.joy.ctrl = a = gb.joy.select.DIRECTIONS | gb.joy.select.BUTTONS;
// Read a few times to prevent bounce.
inline for let i in 1 .. 4 {
a = gb.joy.ctrl;
}
// Mask off the id and invert to get an increasing ID number.
a = (a & 0xF) ^ 0xF;
}
// Convenience for getting the buttons for a single player usage.
func update() {
read_raw();
// Remove unpress flag for controls no longer being held.
// unpress = unpress & controls
unpress = a = unpress & c;
// Only keep controls that don't have the unpress flag set.
pressed = a = ~a & c;
// Check for the reset combo, but only if not just reset
a = c & 0xF;
if a == 0xF {
a = was_reset_already;
if a == 0 {
reset = a = 1;
}
} else {
was_reset_already = a = 0;
}
}
}namespace gb {
namespace lcd {
extern var ctrl @ 0xFF40 : u8;
let CTRL_ON = 0x80;
let CTRL_WIN_MAP2 = 0x40;
let CTRL_WIN_MAP1 = 0x00;
let CTRL_WIN_ON = 0x20;
let CTRL_TILESET2 = 0x10;
let CTRL_TILESET1 = 0x00;
let CTRL_BG_MAP2 = 0x08;
let CTRL_BG_MAP1 = 0x00;
let CTRL_OBJ_8x16 = 0x04;
let CTRL_OBJ_8x8 = 0x00;
let CTRL_OBJ_ON = 0x02;
let CTRL_BG_ON = 0x01;
let CTRL_BIT_BG = 0;
let CTRL_BIT_OBJ = 1;
let CTRL_BIT_OBJ_SIZE = 2;
let CTRL_BIT_BG_MAP = 3;
let CTRL_BIT_TILESET = 4;
let CTRL_BIT_WIN = 5;
let CTRL_BIT_WIN_MAP = 6;
let CTRL_BIT_ENABLE = 7;
extern var stat @ 0xFF41 : u8;
let STAT_SCANLINE_ENABLE = 0x40;
let STAT_OAM_ENABLE = 0x20;
let STAT_VBLANK_ENABLE = 0x10;
let STAT_HBLANK_ENABLE = 0x08;
let STAT_SCANLINE_FLAG = 0x04;
let STAT_MODE_MASK = 0x03;
let STAT_MODE_HBLANK = 0x00;
let STAT_MODE_VBLANK = 0x01;
let STAT_MODE_BUSY_OAM = 0x02;
let STAT_MODE_BUSY_TRANSFER = 0x03;
extern writeonly dma @ 0xFF46 : u8;
}
namespace oam {
namespace attr {
namespace bit {
let PRIORITY = 7;
let VFLIP = 6;
let HFLIP = 5;
let MONO_PALETTE = 4;
let COLOR_TILE_BANK = 3;
}
namespace mask {
let PRIORITY = 0x80;
let VFLIP = 0x40;
let HFLIP = 0x20;
let MONO_PALETTE = 0x10;
let COLOR_TILE_BANK = 0x08;
let COLOR_PALETTE = 0x07;
}
}
}
namespace ram {
// Tile data.
extern var tile @ 0x8000 : [u8; 0x1800];
// Background maps.
extern var map @ 0x9800 : [u8; 0x400];
extern var map2 @ 0x9C00 : [u8; 0x400];
// Video memory. (tileset + tilemaps)
extern var vram @ 0x8000 : [u8; 0x2000];
// Object attribute memory.
extern var obj @ 0xFE00 : [u8; OBJ_SIZE * OBJ_TOTAL];
// Offset of each piece of object data.
let OBJ_OFFSET_Y = 0;
let OBJ_OFFSET_X = 1;
let OBJ_OFFSET_TILE = 2;
let OBJ_OFFSET_ATTR = 3;
// Size of each object.
let OBJ_SIZE = 4;
// Total number of objects.
let OBJ_TOTAL = 40;
// 4-bit wave memory.
extern var wave @ 0xFF30 : [u8; WAVE_BYTES_TOTAL];
// Number of bits taken by each wave sample.
let WAVE_BITS_PER_SAMPLE = 4;
// Total number of samples.
let WAVE_SAMPLE_TOTAL = 32;
// Number of samples per byte in wave memory.
let WAVE_SAMPLES_PER_BYTE = 2;
// Total number of bytes in wave memory.
let WAVE_BYTES_TOTAL = WAVE_SAMPLE_TOTAL / WAVE_SAMPLES_PER_BYTE;
// High-ram memory area.
extern var hram @ 0xFF80 : [u8; HRAM_SIZE];
// Size of high-ram.
let HRAM_SIZE = 127;
// I/O port memory area.
extern var io @ 0xFF00 : [u8; 256];
}
namespace scroll {
// Wrapped coordinates.
extern var y @ 0xFF42 : u8;
extern var x @ 0xFF43 : u8;
}
namespace scanline {
extern const current @ 0xFF44 : u8; // curent = 0 .. 153, where 144..153 indicates vblank
extern var trigger @ 0xFF45 : u8;
}
namespace window {
// Unwrapped coordinates.
extern var y @ 0xFF4A : u8; // y = 0..143
extern var x @ 0xFF4B : u8; // x - 7 = 0 .. 166 -- x < 7 is weird. So is fully-offscren x.
}
namespace mono {
namespace palette {
extern var bg @ 0xFF47 : u8;
extern var obj1 @ 0xFF48 : u8;
extern var obj2 @ 0xFF49 : u8;
let COLOR_3_MASK = 0xC0;
let COLOR_2_MASK = 0x30;
let COLOR_1_MASK = 0x0C;
let COLOR_0_MASK = 0x03;
let COLOR_3_SHIFT = 6;
let COLOR_2_SHIFT = 4;
let COLOR_1_SHIFT = 2;
let COLOR_0_SHIFT = 0;
}
}
namespace color {
namespace palette {
namespace bg {
extern var index @ 0xFF68 : u8;
extern var data @ 0xFF69 : u8;
}
namespace obj {
extern var index @ 0xFF6A : u8;
extern var data @ 0xFF6B : u8;
}
let INDEX_VALUE_MASK = 0x3F;
let INDEX_AUTO_INCREMENT = 0x80;
let DATA_CHANNEL_SIZE = 5;
let DATA_BLUE_SHIFT = 10;
let DATA_GREEN_SHIFT = 5;
let DATA_RED_SHIFT = 0;
let DATA_BLUE_MASK = 0x7C00;
let DATA_GREEN_MASK = 0x03E0;
let DATA_RED_MASK = 0x001F;
}
namespace select {
extern var vram @ 0xFF4F : u8;
let VRAM_BANK_0 = 0x00;
let VRAM_BANK_1 = 0x01;
extern var wram @ 0xFF70 : u8;
let WRAM_BANK_MASK = 0x07;
}
extern var speed @ 0xFF4D : u8;
let SPEED_BIT_TURBO_ON = 7;
let SPEED_BIT_SWITCH = 0;
let SPEED_MASK_TURBO_ON = 0x80;
let SPEED_MASK_TURBO_OFF = 0;
let SPEED_MASK_SWITCH = 0x01;
extern var infrared @ 0xFF56 : u8;
let INFRARED_WRITE_MASK = 0x01;
let INFRARED_WRITE_OFF = 0x00;
let INFRARED_WRITE_ON = 0x01;
let INFRARED_READ_MASK = 0x02;
let INFRARED_READ_NORMAL = 0x02;
let INFRARED_READ_RECEIVING = 0x00;
let INFRARED_READ_ENABLE = 0xC0;
let INFRARED_READ_DISABLE = 0x00;
namespace dma {
namespace source {
extern var high @ 0xFF51 : u8;
extern var low @ 0xFF52 : u8;
}
namespace dest {
extern var high @ 0xFF53 : u8;
extern var low @ 0xFF54 : u8;
}
extern var transfer @ 0xFF55 : u8;
let TRANSFER_GENERAL = 0x00; // write
let TRANSFER_HBLANK = 0x80; // write
let TRANSFER_ACTIVE = 0x00; // read
let TRANSFER_INACTIVE = 0x80; // read
}
}
namespace super {
let PAL01 = 0x00;
let PAL23 = 0x08;
let PAL03 = 0x10;
let PAL12 = 0x18;
let ATTR_BLK = 0x20;
let ATTR_LIN = 0x28;
let ATTR_DIV = 0x30;
let ATTR_CHR = 0x38;
let SOUND = 0x40;
let SOU_TRN = 0x48;
let PAL_SET = 0x50;
let PAL_TRN = 0x58;
let ATRC_EN = 0x60;
let TEST_EN = 0x68;
let ICON_EN = 0x70;
let DATA_SND = 0x78;
let DATA_TRN = 0x80;
let MLT_REQ = 0x88;
let JUMP = 0x90;
let CHR_TRN = 0x98;
let PCT_TRN = 0xA0;
let ATTR_TRN = 0xA8;
let ATTR_SET = 0xB0;
let MASK_EN = 0xB8;
let OBJ_TRN = 0xC0;
}
namespace audio {
namespace pulse1 {
// Sweep setting. (read/write)
extern var sweep @ 0xFF10 : u8;
// Mask of possible sweep time values.
let SWEEP_TIME_MASK = 0x70;
// Starting bit of sweep time value.
let SWEEP_TIME_SHIFT = 4;
// Sweep upwards.
let SWEEP_DIRECTION_UP = 0x00;
// Sweep downards.
let SWEEP_DIRECTION_DOWN = 0x08;
// Mask of possible sweep shift values.
let SWEEP_SHIFT_MASK = 0x07;
// Length counter and duty setting. (read/write)
extern var pattern @ 0xFF11 : u8;
// 12% duty cycle.
let PATTERN_DUTY_12 = 0x00;
// 25% duty cycle.
let PATTERN_DUTY_25 = 0x40;
// 50% duty cycle.
let PATTERN_DUTY_50 = 0x80;
// 75% duty cycle.
let PATTERN_DUTY_75 = 0xC0;
// Mask of possible duty values.
let PATTERN_DUTY_MASK = 0xC0;
// Starting bit of duty value.
let PATTERN_DUTY_SHIFT = 6;
// Mask of possible length values.
let PATTERN_LENGTH_MASK = 0x1F;
// Volume envelope setting. (read/write)
extern var envelope @ 0xFF12 : u8;
// Mask of possible initial volume settings.
let ENVELOPE_INITIAL_MASK = 0xF0;
// Fade volume in.
let ENVELOPE_DIRECTION_IN = 0x08;
// Fade volume out.
let ENVELOPE_DIRECTION_OUT = 0x00;
// Mask of possible envelope durations.
let ENVELOPE_DURATION_MASK = 0x07;
// Low frequency. (lower 5 bits of 11-bit value) (write-only)
extern writeonly low @ 0xFF13 : u8;
// High frequency (upper 3 bits of 11-bit value) and playback control flags. (read/write)
extern var high @ 0xFF14 : u8;
// Restart sound.
let HIGH_RESTART = 0x80;
// When counter is enabled, playback automatically stops after length counter expires.
let HIGH_COUNTER_ENABLE = 0x40;
// Mask of possible values for the high frequency.
let HIGH_FREQUENCY_MASK = 0x07;
}
namespace pulse2 {
// Length counter and duty setting. (read/write)
extern var pattern @ 0xFF16 : u8;
// 12% duty cycle.
let PATTERN_DUTY_12 = 0x00;
// 25% duty cycle.
let PATTERN_DUTY_25 = 0x40;
// 50% duty cycle.
let PATTERN_DUTY_50 = 0x80;
// 75% duty cycle.
let PATTERN_DUTY_75 = 0xC0;
// Mask of possible duty values.
let PATTERN_DUTY_MASK = 0xC0;
// Starting bit of duty value.
let PATTERN_DUTY_SHIFT = 6;
// Mask of possible length values.
let PATTERN_LENGTH_MASK = 0x1F;
// Volume envelope setting. (read/write)
extern var envelope @ 0xFF17 : u8;
// Mask of possible initial volume settings.
let ENVELOPE_INITIAL_MASK = 0xF0;
// Fade volume in.
let ENVELOPE_DIRECTION_IN = 0x08;
// Fade volume out.
let ENVELOPE_DIRECTION_OUT = 0x00;
// Mask of possible envelope durations.
let ENVELOPE_DURATION_MASK = 0x07;
// Low frequency. (lower 5 bits of 11-bit value) (write-only)
extern writeonly low @ 0xFF18 : u8;
// High frequency (upper 3 bits of 11-bit value) and playback control flags. (read/write)
extern var high @ 0xFF19 : u8;
// Restart sound.
let HIGH_RESTART = 0x80;
// When counter is enabled, playback automatically stops after length counter expires.
let HIGH_COUNTER_ENABLE = 0x40;
// Mask of possible values for the high frequency.
let HIGH_FREQUENCY_MASK = 0x07;
}
namespace wave {
// Wave control register.
extern var ctrl @ 0xFF1A : u8;
// Enable wave playback.
let CTRL_ENABLE = 0x80;
// Length counter. (8-bit) (read/write)
extern var length @ 0xFF1B : u8;
// Mask of possible length values.
let LENGTH_MASK = 0xFF;
// Volume setting.
extern var volume @ 0xFF1C : u8;
// 0% volume.
let VOLUME_0 = 0x00;
// 100% volume.
let VOLUME_100 = 0x20;
// 50% volume.
let VOLUME_50 = 0x40;
// 25% volume.
let VOLUME_25 = 0x60;
// Low frequency. (lower 5 bits of 11-bit value) (write-only)
extern writeonly low @ 0xFF1D : u8;
// High frequency (upper 3 bits of 11-bit value) and playback control flags. (read/write)
extern var high @ 0xFF1E : u8;
// Restart sound.
let HIGH_RESTART = 0x80;
// When counter is enabled, playback automatically stops after length counter expires.
let HIGH_COUNTER_ENABLE = 0x40;
// Mask of possible values for the high frequency.
let HIGH_FREQUENCY_MASK = 0x07;
}
namespace noise {
// Length counter. (5-bit) (read/write)
extern var length @ 0xFF20 : u8;
// Mask of possible length values.
let LENGTH_MASK = 0x1F;
// Volume envelope. (read/write)
extern var envelope @ 0xFF21 : u8;
// Mask of possible initial volume settings.
let ENVELOPE_INITIAL_MASK = 0xF0;
// Fade volume in.
let ENVELOPE_DIRECTION_IN = 0x08;
// Fade volume out.
let ENVELOPE_DIRECTION_OUT = 0x00;
// Mask of possible envelope durations.
let ENVELOPE_DURATION_MASK = 0x07;
// Polynomial counter settings. (read/write)
extern var frequency @ 0xFF22 : u8;
// Mask of possible frequency shift values.
let FREQUENCY_SHIFT_MASK = 0xF0;
// Starting bit of frequency shift.
let FREQUENCY_SHIFT_SHIFT = 4;
// 15-bit step mode. ("white noise")
let FREQUENCY_STEP_15 = 0x08;
// 7-bit step mode. ("metallic noise")
let FREQUENCY_STEP_7 = 0x08;
// Mask of possible frequency divisor values.
let FREQUENCY_DIVISOR_MASK = 0x07;
// Playback control flags. (read/write)
extern var play @ 0xFF23 : u8;
// Restart sound.
let PLAY_RESTART = 0x80;
// When counter is enabled, playback automatically stops after length counter expires.
let PLAY_COUNTER_ENABLE = 0x40;
}
// Master volume (read/write)
// Left volume settings in low nybble.
// Right volume settings in high nybble.
extern var volume @ 0xFF24 : u8;
// Enable output of expansion sound on right speaker.
let VOLUME_RIGHT_VIN = 0x80;
// Mask of possible volume values in the right speaker.
let VOLUME_RIGHT_MASK = 0x70;
// Enable output of expansion sound on left speaker.
let VOLUME_LEFT_VIN = 0x08;
// Mask of possible volume values in the left speaker.
let VOLUME_LEFT_MASK = 0x07;
// Hard pan (read/write)
// Left pan settings in low nybble.
// Right pan settings in high nybble.
extern var pan @ 0xFF25 : u8;
// Enable noise on right speaker.
let PAN_NOISE_R = 0x80;
// Enable wave on right speaker.
let PAN_WAVE_R = 0x40;
// Enable pulse 2 on right speaker.
let PAN_PULSE2_R = 0x20;
// Enable pulse 1 on right speaker.
let PAN_PULSE1_R = 0x10;
// Enable noise on left speaker.
let PAN_NOISE_L = 0x08;
// Enable wave on left speaker.
let PAN_WAVE_L = 0x04;
// Enable pulse 2 on left speaker.
let PAN_PULSE2_L = 0x02;
// Enable pulse 1 on left speaker.
let PAN_PULSE1_L = 0x01;
// Active channel status.
extern const status @ 0xFF26 : u8;
// Whether sound output is enabled. (if this flag is not included, all playback is stopped.) (read/write)
let STATUS_ENABLED = 0x80;
// Whether noise channel is active. (read-only)
let STATUS_NOISE_ACTIVE = 0x08;
// Whether wave channel is active. (read-only)
let STATUS_WAVE_ACTIVE = 0x04;
// Whether pulse 2 channel is active. (read-only)
let STATUS_PULSE2_ACTIVE = 0x02;
// Whether pulse 1 channel is active. (read-only)
let STATUS_PULSE1_ACTIVE = 0x01;
}
namespace joy {
extern var ctrl @ 0xFF00 : u8;
namespace select {
let DIRECTIONS = 0x20;
let BUTTONS = 0x10;
}
}
namespace link {
extern var data @ 0xFF01 : u8;
extern var ctrl @ 0xFF02 : u8;
let CTRL_TRANSFER_START = 0x80;
let CTRL_TRANSFER_OFF = 0x00;
let CTRL_GBC_FAST = 0x02;
let CTRL_GBC_NORMAL = 0x00;
let CTRL_CLOCK_INTERNAL = 0x01;
let CTRL_CLOCK_EXTERNAL = 0x00;
}
namespace timer {
extern var divider @ 0xFF04 : u8;
extern var counter @ 0xFF05 : u8;
extern var modulo @ 0xFF06 : u8;
extern var ctrl @ 0xFF07 : u8;
let CTRL_STOP = 0x00;
let CTRL_START = 0x04;
let CTRL_CLOCK_4096 = 0x00;
let CTRL_CLOCK_262144 = 0x01;
let CTRL_CLOCK_65536 = 0x02;
let CTRL_CLOCK_16384 = 0x03;
}
namespace interrupt {
extern var enable @ 0xFFFF : u8;
extern var flag @ 0xFF0F : u8;
let VBLANK = 0x01;
let STAT = 0x02;
let TIMER = 0x04;
let SERIAL = 0x04;
let JOYPAD = 0x08;
}
}import "gb";
import "banks";
namespace oam {
in hram {
var transfer_func_code : [u8; 9];
}
// Initializes the oam library and sets up the oam.transfer routine.
func init() {
de = &transfer_func_code as u16;
hl = _transfer as u16;
c = (_transfer_end as u16 - _transfer as u16) as u8;
do {
*(de as *u8) = a = *(hl++ as *u8);
de++;
c--;
} while !zero;
}
// Copies sprite data to the OAM.
//
// Requires:
// - Exclusive access to OAM.
// - Interrupts disabled (or during an interrupt, which disables interrupts)
//
// Arguments:
// a = high byte of of sprite data address (must be between 0x00 .. 0xF1)
let transfer = &transfer_func_code as func(addr_hi : u8 in a);
func _transfer(addr_hi : u8 in a) {
gb.lcd.dma = a;
// Wait about 200ms
a = 40;
do {
a--;
} while !zero;
}
_transfer_end:
// Clears out OAM using "safe" instructions that work correctly in the 0xFE00..0xFEFF range.
//
// Requires: Exclusive access to OAM.
func clear() {
hl = 0xFE00;
c = 160;
a = 0;
do {
*(hl as *u8) = a;
l++;
c--;
} while !zero;
}
}namespace math {
// Quick 16 x 16 unsigned multiply.
//
// By: Jon Tara
// MicroControl Software
// 1300 E. Lafayette #2808
// Detroit, Michigan 48207
// (313) 393-2916
//
// This software is placed in the public domain.
//
// Jon Tara (1982-01-21): Initial release
// Jeff Frohwein (1997-04-25): Bug fixes
// Andrew G. Crowell (2013-05-28): Ported to wiz.
//
// Arguments:
// de = multiplicand
// hl = multiplier
// Returns:
// bcde = product
// Dirty:
// All registers.
//
func multiply_u16_u16() {
// Save MSBs of multiplier.
c = h;
// Save LSBs to accumulator for an 8x16 multiply.
a = l;
// Set B = 0, for carry propagation.
b = 0;
// Init LSBs of product
h = b;
l = b;
inline for let i in 1 .. 7 {
// Test multiplier bit.
a = a + a;
if carry {
// Add multiplicand to product in AHL.
hl = hl + de;
a = a +# b;
}
// Shift product left.
hl = hl + hl;
}
// Test multiplier bit.
a = a + a;
if carry {
// Add multiplicand to product in AHL.
hl = hl + de;
a = a +# b;
}
// Save LSBs on stack.
push(hl);
// Zero second product.
h = b;
l = b;
// Save MSBs of first product in B.
b = a;
// Get MSBs of multiplier.
a = c;
// Set C = 0, for carry propagation.
c = h;
inline for let i in 1 .. 7 {
// Test multiplier bit.
a = a + a;
if carry {
// Add multiplicand to product in AHL.
hl = hl + de;
a = a +# c;
}
// Shift product left.
hl = hl + hl;
}
// Test multiplier bit.
a = a + a;
if carry {
// Add multiplicand to product in AHL.
hl = hl + de;
a = a +# c;
}
// Pop LSBs from stack.
de = pop();
// Add partial products.
c = a;
d = a = d + l;
h = a = b +# h;
b = a = c +# 0;
c = h;
}
}import "gb";
import "joy";
import "banks";
namespace sgb_util {
in ram {
var sgb_detected : u8;
}
// Send a single 16-byte packet to the Super Game Boy hardware.
// Packets are 16-bytes and zero-padded as necessary. Exact structure depends on the command
// Arguments: hl = pointer to 16-byte packet.
func send_packet(packet_ptr : *u8 in hl) {
gb.joy.ctrl = a = 0;
gb.joy.ctrl = a = 0x30;
b = 16;
do {
e = 8;
a = *(hl++ as *u8);
d = a;
do {
a = 0x10;
d >>>= 1;
if !carry {
a = 0x20;
}
gb.joy.ctrl = a;
gb.joy.ctrl = a = 0x30;
e--;
} while !zero;
b--;
} while !zero;
gb.joy.ctrl = a = 0x20;
gb.joy.ctrl = a = 0x30;
bc = 6400;
do {
nop();
nop();
nop();
bc--;
a = c | b;
} while !zero;
}
// Send multiple 16-byte SGB-formatted packets in a row.
//
// Arguments: hl = pointer to a sequence of 16-byte packets, terminated by a single 0xFF byte.
#[fallthrough] func send_packet_sequence(sequence_ptr : *u8 in hl) {
while true {
a = *(hl as *u8);
return if a == 0xFF;
send_packet(sequence_ptr);
}
}
// Detects if running on the Super Game Boy.
// After: sgb_detected = 1 if found, 0 otherwise.
func detect() {
// Turn on 2P mode.
send_packet(&packet_2_player_mode[0]);
// If joystick id != 0 in the next two reads, we successfully switched to multiplayer mode (which means we're on a Super Game Boy)
joy.read_raw();
goto was_detected if a != 0;
joy.read_raw();
goto was_detected if a != 0;
was_not_detected:
a = 0;
goto done_detection;
was_detected:
a = 1;
done_detection:
sgb_detected = a;
// Turn off 1P mode.
send_packet(&packet_1_player_mode[0]);
}
const packet_1_player_mode : [u8] = [gb.super.MLT_REQ | 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
const packet_2_player_mode : [u8] = [gb.super.MLT_REQ | 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
// Prepares the screen so that a VRAM transfer can be completed.
func prepare_vram_transfer_offscreen() {
if { a = gb.lcd.ctrl; } && a $ gb.lcd.CTRL_BIT_ENABLE {
do {
a = gb.scanline.current;
} while a != 144;
}
gb.lcd.ctrl = a = 0;
gb.scroll.x = a = 0;
gb.scroll.y = a;
gb.mono.palette.bg = a = 0b11100100;
hl = &gb.ram.map as u16;
de = 12;
a = 0;
b = 18;
do {
c = 20;
do {
*(hl++ as *u8) = a;
a++;
c--;
} while !zero;
hl += de;
b--;
} while !zero;
gb.lcd.ctrl = a = gb.lcd.CTRL_ON | gb.lcd.CTRL_TILESET2 | gb.lcd.CTRL_BG_ON;
}
}// Fills a range in memory with a specified byte value.
//
// Notes:
// - Some memory is unsafe to write while other hardware is using it.
// - This will not work for 0xFExx addressses. Use the OAM library instead for modifying OAM memory.
//
// Arguments:
//
// hl = destination address
// a = value
// bc = byte count
//
// After: hl += bc, bc = 0, a is preserved.
func memset(dest : *u8 in hl, value : u8 in a, count : u16 in bc) {
memset_inline(dest, value, count);
}
inline func memset_inline(dest : *u8 in hl, value : u8 in a, count : u16 in bc) {
++<:count; ++>:count;
goto start;
repeat:
*dest++ = value;
start:
--<:count; goto repeat if !zero;
-->:count; goto repeat if !zero;
}
// Copies count bytes from source to destination.
//
// Notes:
// - Some memory is unsafe to write to while other hardware is using it.
// - This will not work for 0xFExx addressses. Use the OAM library instead for modifying OAM memory.
//
// Arguments:
//
// de = destination address
// hl = source address
// bc = byte count
//
// After: de += bc, hl += bc, bc = 0
func memcpy(dest : *u8 in de, source : *u8 in hl, count : u16 in bc) {
memcpy_inline(dest, source, count);
}
inline func memcpy_inline(dest : *u8 in de, source : *u8 in hl, count : u16 in bc) {
++<:count; ++>:count;
goto start;
repeat:
*dest++ = a = *source++;
start:
--<:count; goto repeat if !zero;
-->:count; goto repeat if !zero;
}import "gb";
import "banks";
namespace gbc_util {
in hram {
var gbc_detected : u8;
var gba_detected : u8;
}
// Must be called near the very start of the program (relies on startup state of a and b registers)
// After:
// gbc_detected = 1 if running on GBC-compatible hardware, 0 otherwise.
// gba_detected = 1 if running on a GBA, 0 otherwise.
func detect() {
if a == 0x11 {
gba_detected = a = b & 1;
gbc_detected = a = 1;
} else {
a = 0;
gba_detected = a;
gbc_detected = a;
}
}
// Arguments: b = desired speed setting (gb.color.SPEED_MASK_TURBO_ON or gb.color.SPEED_MASK_TURBO_OFF)
func set_speed(desired_speed : u8 in b) {
if { a = gbc_detected; } && a != 0 {
if { a = gb.color.speed & b; } && a != b {
gb.joy.ctrl = a = 0x30;
gb.color.speed = a = gb.color.SPEED_MASK_SWITCH;
stop();
}
}
}
}namespace vcs {
namespace sync {
var vsync @ 0x00 : u8;
let VSYNC_START = 0x02;
var vblank @ 0x01 : u8;
let VBLANK_START = 0x02;
let VBLANK_RESET_TRIGGER = 0x40;
let VBLANK_RESET_POTS = 0x80;
var wsync @ 0x02 : u8;
var rsync @ 0x03 : u8;
}
namespace audio {
var volumes @ 0x19 : [u8; 2];
var volume1 @ 0x19 : u8;
var volume2 @ 0x1A : u8;
var frequencies @ 0x17 : [u8; 2];
var frequency1 @ 0x17 : u8;
var frequency2 @ 0x18 : u8;
var tones @ 0x15 : [u8; 2];
var tone1 @ 0x15 : u8;
var tone2 @ 0x16 : u8;
}
namespace io {
var pots @ 0x3C : [u8; 4];
var pot1 @ 0x38 : u8;
var pot2 @ 0x39 : u8;
var pot3 @ 0x3A : u8;
var pot4 @ 0x3B : u8;
var triggers @ 0x3C : [u8; 2];
var trigger1 @ 0x3C : u8;
var trigger2 @ 0x3D : u8;
let TRIGGER_JOY_FIRE = 0x80;
var port_a @ 0x280 : u8;
var port_b @ 0x282 : u8;
var ddr_a @ 0x281 : u8;
var ddr_b @ 0x023 : u8;
let PORT_A_JOY_UP = 0x10;
let PORT_A_JOY_DOWN = 0x20;
let PORT_A_JOY_LEFT = 0x40;
let PORT_A_JOY_RIGHT = 0x80;
let PORT_A_JOY2_UP = 0x01;
let PORT_A_JOY2_DOWN = 0x02;
let PORT_A_JOY2_LEFT = 0x04;
let PORT_A_JOY2_RIGHT = 0x08;
}
namespace timer {
var value @ 0x284 : u8;
var stat @ 0x285 : u8;
var set1 @ 0x294 : u8;
var set8 @ 0x295 : u8;
var set64 @ 0x296 : u8;
var set1024 @ 0x297 : u8;
}
namespace control {
var players @ 0x04 : [u8; 2];
var player1 @ 0x04 : u8;
var player2 @ 0x05 : u8;
let PLAYER_SINGLE = 0x00;
let PLAYER_SINGLE_2X = 0x05;
let PLAYER_SINGLE_4X = 0x07;
let PLAYER_DOUBLE_CLOSE = 0x01;
let PLAYER_DOUBLE_MEDIUM = 0x02;
let PLAYER_DOUBLE_FAR = 0x04;
let PLAYER_TRIPLE_CLOSE = 0x03;
let PLAYER_TRIPLE_MEDIUM = 0x06;
let MISSILE_1PX = 0x00;
let MISSILE_2PX = 0x10;
let MISSILE_4PX = 0x20;
let MISSILE_8PX = 0x30;
var playfield @ 0x0A : u8;
let FIELD_REFLECT = 0x1;
let FIELD_SCORE = 0x2;
let FIELD_PRIORITY = 0x4;
let BALL_1PX = 0x00;
let BALL_2PX = 0x10;
let BALL_4PX = 0x20;
let BALL_8PX = 0x30;
}
namespace color {
var players @ 0x06 : [u8; 2];
var player1 @ 0x06 : u8;
var player2 @ 0x07 : u8;
var fg @ 0x08 : u8;
var bg @ 0x09 : u8;
let LUMINOSITY_SHIFT = 1;
let LUMINOSITY_MASK = 0x0E;
let COLOR_SHIFT = 4;
let COLOR_MASK = 0xF0;
let SECAM_BLACK = 0x0;
let SECAM_BLUE = 0x2;
let SECAM_RED = 0x4;
let SECAM_MAGENTA = 0x6;
let SECAM_GREEN = 0x8;
let SECAM_CYAN = 0xA;
let SECAM_YELLOW = 0xC;
let SECAM_WHITE = 0xE;
let PAL_GREY = 0x0;
let PAL_YELLOW = 0x2;
let PAL_OLIVE = 0x3;
let PAL_BROWN = 0x4;
let PAL_GREEN = 0x5;
let PAL_RED = 0x6;
let PAL_CYAN = 0x7;
let PAL_MAGENTA = 0x8;
let PAL_LIGHT_BLUE = 0x9;
let PAL_PURPLE = 0xA;
let PAL_SKY_BLUE = 0xB;
let PAL_INDIGO = 0xC;
let PAL_BLUE = 0xD;
let NTSC_WHITE = 0x0;
let NTSC_YELLOW = 0x1;
let NTSC_ORANGE = 0x2;
let NTSC_RED_ORANGE = 0x3;
let NTSC_RED = 0x4;
let NTSC_MAGENTA = 0x5;
let NTSC_PURPLE = 0x6;
let NTSC_BLUE_PURPLE = 0x7;
let NTSC_BLUE = 0x8;
let NTSC_SKY_BLUE = 0x9;
let NTSC_CYAN = 0xA;
let NTSC_MINT = 0xB;
let NTSC_GREEN = 0xC;
let NTSC_GREEN_YELLOW = 0xD;
let NTSC_OLIVE = 0xE;
let NTSC_BROWN = 0xF;
}
namespace pattern {
var players @ 0x1B : [u8; 2];
var player1 @ 0x1B : u8;
var player2 @ 0x1C : u8;
var missiles @ 0x1D : [u8; 2];
var missile1 @ 0x1D : u8;
var missile2 @ 0x1E : u8;
let MISSILE_FILL = 0x2;
var ball @ 0x1F : u8;
let BALL_FILL = 0x2;
var playfields @ 0x0D : [u8; 3];
var playfield1 @ 0x0D : u8;
var playfield2 @ 0x0E : u8;
var playfield3 @ 0x0F : u8;
}
namespace hmove {
var players @ 0x20 : [u8; 2];
var player1 @ 0x20 : u8;
var player2 @ 0x21 : u8;
var missiles @ 0x22 : [u8; 2];
var missile1 @ 0x22 : u8;
var missile2 @ 0x23 : u8;
var ball @ 0x24 : u8;
var apply @ 0x2A : u8;
var clear @ 0x2B : u8;
}
namespace vdelay {
var players @ 0x25 : [u8; 2];
var player1 @ 0x25 : u8;
var player2 @ 0x26 : u8;
var ball @ 0x27 : u8;
}
namespace reflect {
var players @ 0x0B : [u8; 2];
var player1 @ 0x0B : u8;
var player2 @ 0x0C : u8;
let ENABLE = 0x08;
}
namespace warp {
var missiles @ 0x28 : [u8; 2];
var missile1 @ 0x28 : u8;
var missile2 @ 0x29 : u8;
let ENABLE = 0x02;
}
namespace reset {
var players @ 0x10 : [u8; 2];
var player1 @ 0x10 : u8;
var player2 @ 0x11 : u8;
var missiles @ 0x12 : [u8; 2];
var missile1 @ 0x12 : u8;
var missile2 @ 0x13 : u8;
var ball @ 0x14 : u8;
}
namespace collision {
var clear @ 0x2C : u8;
var missile1_vs_players @ 0x30 : u8;
var missile2_vs_players @ 0x31 : u8;
var player1_vs_playfield @ 0x32 : u8;
var player2_vs_playfield @ 0x33 : u8;
var missile1_vs_playfield @ 0x34 : u8;
var missile2_vs_playfield @ 0x35 : u8;
var ball_vs_field @ 0x36 : u8;
var pvp_mvm @ 0x37 : u8;
}
}namespace spc {
extern writeonly control @ 0xF1 : u8;
let CONTROL_PORT_23_CLEAR_MASK = 0x20;
let CONTROL_PORT_01_CLEAR_MASK = 0x10;
let CONTROL_TIMER_2_ENABLE_MASK = 0x04;
let CONTROL_TIMER_1_ENABLE_MASK = 0x02;
let CONTROL_TIMER_0_ENABLE_MASK = 0x01;
let CONTROL_PORT_23_CLEAR_BIT = 5;
let CONTROL_PORT_01_CLEAR_BIT = 4;
let CONTROL_TIMER_2_ENABLE_BIT = 2;
let CONTROL_TIMER_1_ENABLE_BIT = 1;
let CONTROL_TIMER_0_ENABLE_BIT = 0;
namespace dsp {
extern var address @ 0xF2 : u8;
let ADDRESS_VOLUME_L_0 = 0x00;
let ADDRESS_VOLUME_L_1 = 0x10;
let ADDRESS_VOLUME_L_2 = 0x20;
let ADDRESS_VOLUME_L_3 = 0x30;
let ADDRESS_VOLUME_L_4 = 0x40;
let ADDRESS_VOLUME_L_5 = 0x50;
let ADDRESS_VOLUME_L_6 = 0x60;
let ADDRESS_VOLUME_L_7 = 0x70;
let ADDRESS_VOLUME_R_0 = 0x01;
let ADDRESS_VOLUME_R_1 = 0x11;
let ADDRESS_VOLUME_R_2 = 0x21;
let ADDRESS_VOLUME_R_3 = 0x31;
let ADDRESS_VOLUME_R_4 = 0x41;
let ADDRESS_VOLUME_R_5 = 0x51;
let ADDRESS_VOLUME_R_6 = 0x61;
let ADDRESS_VOLUME_R_7 = 0x71;
let ADDRESS_PITCH_L_0 = 0x02;
let ADDRESS_PITCH_L_1 = 0x12;
let ADDRESS_PITCH_L_2 = 0x22;
let ADDRESS_PITCH_L_3 = 0x32;
let ADDRESS_PITCH_L_4 = 0x42;
let ADDRESS_PITCH_L_5 = 0x52;
let ADDRESS_PITCH_L_6 = 0x62;
let ADDRESS_PITCH_L_7 = 0x72;
let ADDRESS_PITCH_H_0 = 0x03;
let ADDRESS_PITCH_H_1 = 0x13;
let ADDRESS_PITCH_H_2 = 0x23;
let ADDRESS_PITCH_H_3 = 0x33;
let ADDRESS_PITCH_H_4 = 0x43;
let ADDRESS_PITCH_H_5 = 0x53;
let ADDRESS_PITCH_H_6 = 0x63;
let ADDRESS_PITCH_H_7 = 0x73;
let ADDRESS_SOURCE_0 = 0x04;
let ADDRESS_SOURCE_1 = 0x14;
let ADDRESS_SOURCE_2 = 0x24;
let ADDRESS_SOURCE_3 = 0x34;
let ADDRESS_SOURCE_4 = 0x44;
let ADDRESS_SOURCE_5 = 0x54;
let ADDRESS_SOURCE_6 = 0x64;
let ADDRESS_SOURCE_7 = 0x74;
let ADDRESS_ADSR_L_0 = 0x05;
let ADDRESS_ADSR_L_1 = 0x15;
let ADDRESS_ADSR_L_2 = 0x25;
let ADDRESS_ADSR_L_3 = 0x35;
let ADDRESS_ADSR_L_4 = 0x45;
let ADDRESS_ADSR_L_5 = 0x55;
let ADDRESS_ADSR_L_6 = 0x65;
let ADDRESS_ADSR_L_7 = 0x75;
let ADDRESS_ADSR_H_0 = 0x06;
let ADDRESS_ADSR_H_1 = 0x16;
let ADDRESS_ADSR_H_2 = 0x26;
let ADDRESS_ADSR_H_3 = 0x36;
let ADDRESS_ADSR_H_4 = 0x46;
let ADDRESS_ADSR_H_5 = 0x56;
let ADDRESS_ADSR_H_6 = 0x66;
let ADDRESS_ADSR_H_7 = 0x76;
let ADDRESS_GAIN_0 = 0x07;
let ADDRESS_GAIN_1 = 0x17;
let ADDRESS_GAIN_2 = 0x27;
let ADDRESS_GAIN_3 = 0x37;
let ADDRESS_GAIN_4 = 0x47;
let ADDRESS_GAIN_5 = 0x57;
let ADDRESS_GAIN_6 = 0x67;
let ADDRESS_GAIN_7 = 0x77;
let ADDRESS_ENV_0 = 0x08;
let ADDRESS_ENV_1 = 0x18;
let ADDRESS_ENV_2 = 0x28;
let ADDRESS_ENV_3 = 0x38;
let ADDRESS_ENV_4 = 0x48;
let ADDRESS_ENV_5 = 0x58;
let ADDRESS_ENV_6 = 0x68;
let ADDRESS_ENV_7 = 0x78;
let ADDRESS_OUT_0 = 0x09;
let ADDRESS_OUT_1 = 0x19;
let ADDRESS_OUT_2 = 0x29;
let ADDRESS_OUT_3 = 0x39;
let ADDRESS_OUT_4 = 0x49;
let ADDRESS_OUT_5 = 0x59;
let ADDRESS_OUT_6 = 0x69;
let ADDRESS_OUT_7 = 0x79;
let ADDRESS_MAIN_VOLUME_L = 0x0C;
let ADDRESS_MAIN_VOLUME_R = 0x1C;
let ADDRESS_ECHO_VOLUME_L = 0x2C;
let ADDRESS_ECHO_VOLUME_R = 0x3C;
let ADDRESS_KEY_ON = 0x4C;
let ADDRESS_KEY_OFF = 0x5C;
let ADDRESS_FLAGS = 0x6C;
let ADDRESS_END_STATUS = 0x7C;
let ADDRESS_ECHO_FEEDBACK = 0x0D;
let ADDRESS_PITCH_MODULATION_ENABLE = 0x2D;
let ADDRESS_NOISE_ENABLE = 0x3D;
let ADDRESS_ECHO_ENABLE = 0x4D;
let ADDRESS_SOURCE_DIRECTORY_PAGE = 0x5D;
let ADDRESS_ECHO_BUFFER_PAGE = 0x6D;
let ADDRESS_ECHO_DELAY = 0x7D;
let ADDRESS_FIR_COEFFICIENT_0 = 0x0F;
let ADDRESS_FIR_COEFFICIENT_1 = 0x1F;
let ADDRESS_FIR_COEFFICIENT_2 = 0x2F;
let ADDRESS_FIR_COEFFICIENT_3 = 0x3F;
let ADDRESS_FIR_COEFFICIENT_4 = 0x4F;
let ADDRESS_FIR_COEFFICIENT_5 = 0x5F;
let ADDRESS_FIR_COEFFICIENT_6 = 0x6F;
let ADDRESS_FIR_COEFFICIENT_7 = 0x7F;
extern var data @ 0xF3 : u8;
let CHANNEL_MASK_0 = 0b00000001;
let CHANNEL_MASK_1 = 0b00000010;
let CHANNEL_MASK_2 = 0b00000100;
let CHANNEL_MASK_3 = 0b00001000;
let CHANNEL_MASK_4 = 0b00010000;
let CHANNEL_MASK_5 = 0b00100000;
let CHANNEL_MASK_6 = 0b01000000;
let CHANNEL_MASK_7 = 0b10000000;
let DATA_ADSR_L_ATTACK_MASK = 0x0F;
let DATA_ADSR_L_DECAY_MASK = 0x70;
let DATA_ADSR_L_DECAY_SHIFT = 4;
let DATA_ADSR_L_ENABLE = 0x80;
let DATA_ADSR_H_SUSTAIN_MASK = 0x1F;
let DATA_ADSR_H_RELEASE_MASK = 0xE0;
let DATA_ADSR_H_RELEASE_SHIFT = 5;
let DATA_GAIN_CONSTANT = 0x00;
let DATA_GAIN_CONSTANT_VALUE_MASK = 0x3F;
let DATA_GAIN_FADE_SPEED_MASK = 0x1F;
let DATA_GAIN_FADE_LINEAR_IN = 0xC0;
let DATA_GAIN_FADE_BENT_IN = 0xE0;
let DATA_GAIN_FADE_LINEAR_OUT = 0x80;
let DATA_GAIN_FADE_EXPONENTIAL_OUT = 0xE0;
let DATA_ENV_MASK = 0x7F;
let DATA_FLAGS_RESET = 0x80;
let DATA_FLAGS_MUTE = 0x40;
let DATA_FLAGS_ECHO_DISABLE = 0x20;
let DATA_FLAGS_NOISE_CLOCK_MASK = 0x1F;
let DATA_ECHO_DELAY_MASK = 0x0F;
extern var data_and_address @ 0xF2 : u16;
}
namespace port {
extern writeonly output0 @ 0xF4 : u8;
extern writeonly output1 @ 0xF5 : u8;
extern writeonly output2 @ 0xF6 : u8;
extern writeonly output3 @ 0xF7 : u8;
extern writeonly output10 @ 0xF4 : u16;
extern writeonly output21 @ 0xF5 : u16;
extern writeonly output32 @ 0xF6 : u16;
extern const input0 @ 0xF4 : u8;
extern const input1 @ 0xF5 : u8;
extern const input2 @ 0xF6 : u8;
extern const input3 @ 0xF7 : u8;
extern const input10 @ 0xF4 : u16;
extern const input21 @ 0xF5 : u16;
extern const input32 @ 0xF6 : u16;
}
namespace timer {
extern writeonly delay0 @ 0xFA : u8;
extern writeonly delay1 @ 0xFB : u8;
extern writeonly delay2 @ 0xFC : u8;
extern const counter0 @ 0xFD : u8;
extern const counter1 @ 0xFE : u8;
extern const counter2 @ 0xFF : u8;
let COUNTER_VALUE_MASK = 0xF;
}
}