8bitworkshop/src/worker/fs/fswiz.data

4188 lines
218 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
<EFBFBD>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
<EFBFBD>
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>
<EFBFBD>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<EFBFBD>v <0C>My<4D><&h<><68>baaÊޙtY<11>%~[ܯ<><DCAF>p$a<>n
F<><02><><EFBFBD>AQ"e<>`p0<70>ة
<EFBFBD><EFBFBD><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<EFBFBD><EFBFBD><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>
<EFBFBD>^?<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>
<EFBFBD><EFBFBD><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<EFBFBD><EFBFBD><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 snes {
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: 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 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
<EFBFBD>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
<EFBFBD>
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>
<EFBFBD>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<EFBFBD>v <0C>My<4D><&h<><68>baaÊޙtY<11>%~[ܯ<><DCAF>p$a<>n
F<><02><><EFBFBD>AQ"e<>`p0<70>ة
<EFBFBD><EFBFBD><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<EFBFBD><EFBFBD><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>
<EFBFBD>^?<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>#!/bin/env python
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<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> <20>m<EFBFBD><6D><EFBFBD><EFBFBD>(<28><>_<EFBFBD>&<26> <00><>;w<><77>D <20><>;o<>y<79><7F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>```ab<61><62>} <0B><>.<<00><> <08><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DDf<44><66><EFBFBD><00><><00><><00><><00><><EFBFBD><03><><00><><00><><00><><00><00><><00><><00><><EFBFBD><00><><EFBFBD>_????<7F><7F><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<7F><7F><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><EFBFBD>ٺ<>Y6<59>9<EFBFBD><6E><CDBC>l=<3D><><EFBFBD> <0C><><EFBFBD><EFBFBD>|R<><52>Mq<><71><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?bbe``@<00>L><3E><><EFBFBD><EFBFBD>8<><38><08><00><>ddffffffffffff??_??<1F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?<0F><><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><EFBFBD><EFBFBD><EFBFBD><EFBFBD>'s{<7B><><EFBFBD><EFBFBD><EFBFBD>،<EFBFBD> ffffffffffffffff8L<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><00>PNG

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>Ӏ
<EFBFBD>h<EFBFBD><EFBFBD><EFBFBD>{<7B>a^<5E>fO{<7B>ǎ
<EFBFBD>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
<EFBFBD><EFBFBD><EFBFBD>a<EFBFBD><EFBFBD>О<><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<EFBFBD><EFBFBD>¨<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
<EFBFBD><EFBFBD><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>
<EFBFBD><EFBFBD><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><00>PNG

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<EFBFBD>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>
<EFBFBD>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>@@<00> <00><00><00><00><><EFBFBD><00><<00><><<3C><><<3C><><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>l<><6C><EFBFBD>|8l<><6C>|8<00><><EFBFBD><EFBFBD>r Hv<48><76><EFBFBD>~<600<00>|88|<7C>|83<><00>3<>ș;<1E>~~~<7E><>|8<><38><EFBFBD><EFBFBD><EFBFBD>D8U<><55><EFBFBD>p R<><52>p ><><7F><EFBFBD><EFBFBD><EFBFBD>|6~~<~l<00><><EFBFBD><EFBFBD>ۇ<EFBFBD><DB87>v<EFBFBD><76>~<7E><><EFBFBD>v<EFBFBD><76>Å<EFBFBD><C385><EFBFBD><EFBFBD>~BB<42><42><EFBFBD><EFBFBD>~BBBZ<42>N~<7E><$$<~<7E><>~<><7F><EFBFBD><EFBFBD><EFBFBD><EFBFBD>^^^~>q<><71>~F&<26><><EFBFBD>\x><18>q<><71><EFBFBD><EFBFBD><00><><EFBFBD>\<5C><>n<EFBFBD><00><><EFBFBD><EFBFBD>O~<7E><>~<<3C><>3<EFBFBD>f<><66><EFBFBD><EFBFBD><EFBFBD>~<7E><>Z<C<><43><$B<<ZZ~<ZB<00>~<~<7E><><EFBFBD>~<<3C><><<<3C><><<~<7E><><EFBFBD><EFBFBD>~<<~<7E><><EFBFBD><EFBFBD>~<<3C><><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><00><>~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><ZZ~g<><67>p<EFBFBD>DV~~~<7E><>~<7E><><EFBFBD>۽C<DBBD>(D<>Ƃ|88|8|<10><><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>~<<~<7E><><EFBFBD><EFBFBD>~<<~<7E><>8p|8>|<7C><>|><<,<~~~~Z @@<~<7E><><EFBFBD><EFBFBD>~<<00><>`~Û<><C39B><EFBFBD><EFBFBD>~<00> B<>!<21>B(  f<><66>`<<00~<7E><><EFBFBD>~~~B~~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~BBB~~~$B<><00><><EFBFBD><EFBFBD><~<7E>~ff<~<7E>BZ<18><~<7E><><EFBFBD><EFBFBD><00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ZZZZ~~<$$~t>6~t>6~t>6<00><><EFBFBD><EFBFBD><<<3C>B~~<7E><><EFBFBD>$<<>~<7E><><EFBFBD>~B<<00><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><1F>~I~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><1F>~J<07><>FP<46>9
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
<EFBFBD>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
<EFBFBD>
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>
<EFBFBD>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<EFBFBD>v <0C>My<4D><&h<><68>baaÊޙtY<11>%~[ܯ<><DCAF>p$a<>n
F<><02><><EFBFBD>AQ"e<>`p0<70>ة
<EFBFBD><EFBFBD><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<EFBFBD><EFBFBD><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>
<EFBFBD>^?<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
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;
}
}