short and very quick-hack-ish documentation of the ARCADEmini assembler language version 0.4 date 2004-03-15 there will be a better and much more detailed one - once... :) ARCADEmini has got: - 256 registers, called $0, ..., $255 (each stores a byte) - a stack with 128 bytes - two buffers with 26x20 pixels and 16 colors (pixel buffer and overlay buffer) - a delay mechanism - a clock - 8 keys - 2 SNES-pads (if connected) constants: can be in decimal, octal, hexadecimal, binary e.g. decimal: 64 e.g. octal: 0100 e.g. hexadecimal: 0x40 e.g. binaray: 0b100000 registers: $ e.g. $64, $0x40 identifiers: constant-identifiers: [A-Za-z_][A-Za-z_0-9]*, e.g. MY_CON register-identifiers: $[A-Za-z_][A-Za-z_0-9]*, e.g. $MY_REG address-identifier: @[A-Za-z_][A-Za-z_0-9]*, e.g. @MY_ADDR labels: constant declaration: MY_CON: 64; register declaration: $MY_REG: $64; address-declaration (label): @MY_ADDR: NOP; also possible: $MY_REG1: $ MY_CON; also possible: $MY_REG2: REGISTER 64; also possible: $MY_REG3: NEXT_REG; addresses: every address consists out of a sector number and a offset @MY_ADDR.O is the offset and @MY_ADDR.S is the sector JMP-commands can take address-identifiers as parameter if within jump-range e.g.: JMP_EQ @MY_ADDR, $0, 0; //jump if register 0 contains 0 commands: REGISTER declares a register with number NEXT_REG declares the next register after the last one declared with REGISTER or NEXT_REG NEXT_SEC not a real command, just tells the assembler to use the next sector DB a data string DB a data byte DW a data word (16 bits, big-endian) DD a data dword (32 bits, big-endian) JMP_NEXT_SEC load the next sector JMP_SEC jump sectors further - is stored in big endian format JMP_OFS (bit0 is bit8 of offset) jump to offset JMP_OFS_SEC (bit0 is bit8 of offset) jump to offset and sectors further - is stored in big endian format JMP_IND jump indirect to offset and sectors further JMP_EQ (bit0 is bit8 of offset) jump if equal jump to offset if == JMP_EQ (bit0 is bit8 of offset) jump if equal to constant jump to offset if == JMP_NEQ (bit0 is bit8 of offset) jump if not equal jump to offset if != JMP_NEQ (bit0 is bit8 of offset) jump if not equal to constant jump to offset if != JMP_GT (bit0 is bit8 of offset) jump if greater than jump to offset if > JMP_GT (bit0 is bit8 of offset) jump if greater than jump to offset if > JMP_NGT (bit0 is bit8 of offset) jump if not greater than jump to offset if <= JMP_NGT (bit0 is bit8 of offset) jump if not greater than jump to offset if <= JMP_LT (bit0 is bit8 of offset) jump if less than jump to offset if < JMP_LT (bit0 is bit8 of offset) jump if less than jump to offset if < JMP_NLT (bit0 is bit8 of offset) jump if not less than jump to offset if >= JMP_NLT (bit0 is bit8 of offset) jump if not less than jump to offset if >= JMP_GTS (bit0 is bit8 of offset) jump if greater (signed) than jump to offset if > JMP_GTS (bit0 is bit8 of offset) jump if greater (signed) than jump to offset if > JMP_NGTS (bit0 is bit8 of offset) jump if not greater (signed) than jump to offset if <= JMP_NGTS (bit0 is bit8 of offset) jump if not greater than jump to offset if <= JMP_LTS (bit0 is bit8 of offset) jump if less (signed) than jump to offset if < JMP_LTS (bit0 is bit8 of offset) jump if less (signed) than jump to offset if < JMP_NLTS (bit0 is bit8 of offset) jump if not less (signed) than jump to offset if >= JMP_NLTS (bit0 is bit8 of offset) jump if not less (signed) than jump to offset if >= JMP_AND_Z (bit0 is bit8 of offset) jump if bitwise and is zero jump to offset if AND == 0 JMP_AND_Z (bit0 is bit8 of offset) jump if bitwise and is zero jump to offset if AND == 0 JMP_AND_NZ (bit0 is bit8 of offset) jump if bitwise and is not zero jump to offset if AND != 0 JMP_AND_NZ (bit0 is bit8 of offset) jump if bitwise and is not zero jump to offset if AND != 0 JMP_OR_M (bit0 is bit8 of offset) jump if bitwise or is maximum jump to offset if OR == 0xFF JMP_OR_M (bit0 is bit8 of offset) jump if bitwise or is maximum jump to offset if OR == 0xFF JMP_OR_NM (bit0 is bit8 of offset) jump if bitwise or is not maximum jump to offset if OR != 0xFF JMP_OR_NM (bit0 is bit8 of offset) jump if bitwise or is not maximum jump to offset if OR != 0xFF MOV move write contents of source into dest MOV move constant write constant into dest MOV2 move 2 write contents of source into dest MOV2 move 2 constants write constant into dest MOV4 ... move 4 write contents of source into dest MOV4 ... move 4 constants write constant into dest RD_I read indirect write contents of variable pointed to by addr into dest WR_I write indirect write contents of source into variable pointed to by addr RD_S read from current sector write byte at offset of current sector into dest RD_CF read from compact flash reads the byte at offset in the sector sectors behind the current one of the compact flash and the following bytes and places them into and the following registers returns an error code in : 0 = no error, 1 = invalid parameters, 2 = CF error ADD add write sum of contents of source1 and contents of source2 into dest ADD add constant write sum of constant and contents of source into dest ADDC add (with carry) write sum of contents of source1 and contents of source2 into dest bit 0 of carry_in is also included in the sum carry_out is 0x01 if the result is >= 0x100, 0x00 otherwise ADDC add constant (with carry) write sum of constant and contents of source into dest bit 0 of carry_in is also included in the sum carry_out is 0x01 if the result is >= 0x100, 0x00 otherwise SUB subtract write difference of contents of source1 minus contents of source2 into dest SUB subtract from constant write difference of constant minus contents of source into dest SUBB subtract (with borrow) write difference of contents of source1 minus contents of source2 into dest bit 0 of borrow_in is also subtracted borrow_out is 0x01 if the result is < 0x00, 0x00 otherwise SUBB subtract from constant (with borrow) write difference of constant minus contents of source into dest MUL multiply write product of contents of source1 and contents of source2 into dest_h and dest_l MUL multiply with constant write product of constant and contents of source into dest_h and dest_l MULS multiply (signed) write product of contents of source1 and contents of source2 into dest_h and dest_l MULS multiply with constant (signed) write product of constant and contents of source into dest_h and dest_l DIV divide calculate quotient and remainder of division of source by divisor DIVS divide (signed) calculate quotient and remainder of division of source by divisor AND bitwise and write bitwise and of contents of source1 and contents of source2 into dest AND and bitwise with constant write bitwise and of constant and contents of source into dest OR bitwise or write bitwise or of contents of source1 and contents of source2 into dest OR or bitwise with constant write bitwise or of constant and contents of source into dest XOR bitwise xor write bitwise xor of contents of source1 and contents of source2 into dest XOR xor bitwise with constant write bitwise xor of constant and contents of source into dest SHL shift left shift left contents of source bits and write result into dest SHL shift left constant number of bits shift left contents of source bits and write result into dest SHR shift right shift right contents of source bits and write result into dest SHR shift right constant number of bits shift right contents of source bits and write result into dest ROL rotate left rotate left contents of source bits and write result into dest ROL rotate left constant number of bits rotate left contents of source bits and write result into dest ROR rotate right rotate right contents of source bits and write result into dest ROR rotate right constant number of bits rotate right contents of source bits and write result into dest PUSH push places the value of onto the stack PUSH_C push constant places onto the stack POP pop takes a value from the stack and places it into CALL (bit0 is bit8 of offset) call code at offset and sectors further - first the offset behind the command and the current sector are placed onto the stack in the following order: ofs_h ofs_l sec_hh sec_hl sec_lh sec_ll - then a jump to the specified location is executed - is stored in big endian format CALL_IND call code at offset and sectors further - first the offset behind the command and the current sector are placed onto the stack in the following order: ofs_h ofs_l sec_hh sec_hl sec_lh sec_ll - then a jump to the specified location is executed RET return from procedure - first the offset and the sector is taken from the stack in the following order: sec_ll sec_lh sec_hl sec_hh ofs_l ofs_h - then a jump to this location is executed RD_PIX read pixel write the value of the pixel at position var_x, var_y into dest RD_PIX read constant pixel write the value of the pixel at position con_x, con_y into dest RD_OVP read overlay pixel write the value of the overlay pixel at position var_x, var_y into dest RD_OVP read constant overlay pixel write the value of the overlay pixel at position con_x, con_y into dest WR_PIX write pixel write the value of source into the pixel at position var_x, var_y WR_PIX write constant pixel write the value of source into the pixel at position con_x, con_y WR_OVP write overlay pixel write the value of source into the overlay pixel at position var_x, var_y WR_OVP write constant overlay pixel write the value of source into the overlay pixel at position con_x, con_y WR_PIX set pixel to color write const_source into the pixel at position var_x, var_y WR_PIX set constant pixel to color write constant into the pixel at position con_x, con_y WR_OVP set overlay pixel to color write constant into the overlay pixel at position var_x, var_y WR_OVP set constant overlay pixel to color write constant into the overlay pixel at position con_x, con_y WR_PIX_LINE ... write pixel line two pixels are packed in one byte - e.g. pixel_0_1=0xF0 turns on pixel 0 and off pixel 1 WR_PIX_LINE ... write constant pixel line two pixels are packed in one byte - e.g. pixel_0_1=0xF0 turns on pixel 0 and off pixel 1 WR_OVP_LINE ... write overlay pixel line two overlay pixels are packed in one byte - e.g. overlay pixel_0_1=0xF0 turns on overlay pixel 0 and off overlay pixel 1 WR_OVP_LINE ... write constant overlay pixel line two overlay pixels are packed in one byte - e.g. overlay pixel_0_1=0xF0 turns on overlay pixel 0 and off overlay pixel 1 WR_PIX_QUART ... write pixel quarter two pixels are packed in one byte - e.g. pixel_l0_0_1=0xF0 turns on line 0, pixel 0 and off pixel 1 (lines rel. to quarter) WR_PIX_QUART ... write constant pixel quarter two pixels are packed in one byte - e.g. pixel_l0_0_1=0xF0 turns on line 0, pixel 0 and off pixel 1 (lines rel. to quarter) WR_OVP_QUART ... write overlay pixel quarter two overlay pixels are packed in one byte - e.g. overlay pixel_l0_0_1=0xF0 turns on line 0, overlay pixel 0 and off overlay pixel 1 (lines rel. to quarter) WR_OVP_QUART ... write constant overlay pixel quarter two overlay pixels are packed in one byte - e.g. overlay pixel_l0_0_1=0xF0 turns on line 0, overlay pixel 0 and off overlay pixel 1 WR_PIX_CLR clear pixels WR_OVP_CLR clear overlay pixels WR_PIX_SET set pixels WR_OVP_SET set overlay pixels WR_PIX_BW ... write frame of black/white pixels bw0,7 = pixel 0,0 / bw0,6 = pixel 1,0 / ... / bw64,0 = pixel 25,19 WR_OVP_BW ... write frame of black/white overlay pixels bw0,7 = pixel 0,0 / bw0,6 = pixel 1,0 / ... / bw64,0 = pixel 25,19 WR_PIX_SEL ... set selected pixels of frame to source - sel selects pixels - pixels with sel=1 are set to source sel0,7 = pixel 0,0 / sel0,6 = pixel 1,0 / ... / sel64,0 = pixel 25,19 WR_PIX_SEL ... set selected pixels of frame to constant - sel selects pixels - pixels with sel=1 are set to constant sel0,7 = pixel 0,0 / sel0,6 = pixel 1,0 / ... / sel64,0 = pixel 25,19 WR_OVP_SEL ... set selected overlay pixels of frame to source - sel selects pixels - pixels with sel=1 are set to source sel0,7 = pixel 0,0 / sel0,6 = pixel 1,0 / ... / sel64,0 = pixel 25,19 WR_OVP_SEL ... set selected overlay pixels of frame to constant - sel selects pixels - pixels with sel=1 are set to constant sel0,7 = pixel 0,0 / sel0,6 = pixel 1,0 / ... / sel64,0 = pixel 25,19 CP_BLK_xy copy a block of pixels - x: 'P'=copy from pixel buffer, 'O'=copy from overlay buffer - y: 'P'=copy to pixel buffer, 'O'=copy to overlay buffer - if the two sections overlap, the result is undefined CP_BLK_xy_TR copy a block of pixels with a transparent color - if transp is not in the range 0x00..0x0F no color is transparent - x: 'P'=copy from pixel buffer, 'O'=copy from overlay buffer - y: 'P'=copy to pixel buffer, 'O'=copy to overlay buffer - if the two sections overlap, the result is undefined DISPLAY display frame DISPLAY_CP display frame and copy it into new drawing buffer DELAY_DO wait milliseconds DELAY_DO wait milliseconds DELAY_START start background delay of milliseconds - background delay can be checked with DELAY_CHECK - background delay can be waited for with DELAY_WAIT DELAY_START start background delay of milliseconds - background delay can be checked with DELAY_CHECK - background delay can be waited for with DELAY_WAIT DELAY_CHECK check if background delay elapsed (returns 0xFF if delay is active, 0x00 if not) - background delay can be started with DELAY_START - background delay can be waited for with DELAY_WAIT DELAY_WAIT wait for background delay to elapse - background delay can be started with DELAY_START - background delay can be checked with DELAY_CHECK GET_KEYS get keys - current: current (debounced) key state - pressed: keys that were pressed since last GET_KEYS - released: keys that were released since last GET_KEYS GET_SNES0 get keys of 1st SNES pad - current: current (debounced) key state - pressed: keys that were pressed since last GET_SNES0 - released: keys that were released since last GET_SNES0 GET_SNES1 get keys of 2nd SNES pad - current: current (debounced) key state - pressed: keys that were pressed since last GET_SNES1 - released: keys that were released since last GET_SNES1 GET_TIME get time: seconds, minutes, hours SET_TIME set time: seconds (0..59), minutes (0..59), hours (0..23) RND fill dest with pseudorandom value VER get version information: version major.minor.revision from (2000+year)-month-day NOP no operation further information look at test.amasm or the source codes of am_progs for examples you may also have a look at the source code of the assembler or the simulator an implementation of each command can be found in the am_dev file of am_sim trial and error :-) post in the ARCADEmini forum, perhaps someone will read it and know the answer (perhaps even me) a much more detailed documentation will be written, if i've got the time yours, stefan