[JADEMCR.8xp Jade macro file for AsmDream [JADEEQU.8xp Jade equate file for AsmDreamIf you plan to program for Jade on the computer, you can use the included Jade.inc file for equates and macros.
:→SRC :θ=0 :prgmPROGRAM :START :<code> :End
#include 'Jade.inc' .org 0 start: <code>
Instructions tell the processor what to do. In Jade, there are two main types of instructions-- those that uses constants or 'immediate' values and those that use addresses. RAM holds data in bytes, and each byte has a unique address. Since there are 256 bytes, we use numbers 0 to 255 to identify each byte. The naming scheme of the instructions usually reflects which type of instruction it is, except in the cases where it makes no sense for it to be any other type. So without further ado, the first instruction:
ldc(addr1,const) ;copies or 'loads' the constant value to the byte at addr1
lda(addr1,addr2) ;copies or 'loads' the byte at addr2 to the byte at addr1
Notice that the instruction suffix is a c when a constant is being used, and an a when an address reference is being used. These is the most basic ways of moving data around. An example of its use might be:
ldc(status,80h)
Instruction Flags Description LDA(addr1,addr2) -- load the byte at addr2 to addr1 LDC(addr1,const) -- load the the constant value to add1 ADDA(addr1,addr2) cz Add the byte at addr2 to addr1, store the result at addr1 ADDC(addr1,const) cz Add the constant to addr1, store the result at addr1
Here is a quick break. Flags are used to provide additional information about the result of an instruction. The 'c' flag indicates overflow in most cases, and the 'z' flag indicates that the result was 0 in most cases. The CP instructions are a little different, and they will be explained later.
ADCA(addr1,addr2) cz Add the byte+'c' to addr1, store the result to addr1 ADCC(addr1,const) cz Add the constant+'c'to addr1, store the result at addr1 SUBA(addr1,addr2) cz Subtract the byte at addr2 from addr1, the result to addr1 SUBC(addr1,const) cz Subtract the constant from addr1, the result to addr1 SBCA(addr1,addr2) cz Subtract the byte+'c' from addr1, the result to addr1 SBCC(addr1,const) cz Subtract the constant+'c' from addr1, the result to addr1 XORA(addr1,addr2) 0z Performs bitwise XOR on the bytes, the result to addr1 XORC(addr1,sonst) 0z Performs bitwise XOR on the bytes, the result to addr1 ORA(addr1,addr2) 0z Performs bitwise OR on the bytes, the result to addr1 ORC(addr1,const) 0z Performs bitwise OR on the bytes, the result to addr1 ANDA(addr1,addr2) 0z Performs bitwise AND on the bytes, the result to addr1 ANDC(addr1,const) 0z Performs bitwise AND on the bytes, the result to addr1 CPA(addr1,addr2) cz Compares the two bytes, returns flags CPC(addr1,const) cz Compares the two bytes, returns flags The flags returned by CP work like this: -If the bytes are equal, z flag is set, else it is reset -If the second byte is less than the first, the c fag is set, else it is reset. ROTL(addr1) cz rotate the bits left at the byte ROTR(addr1) cz rotate the bits right at the byte SHFTL(addr1) cz shift the bits left at the byte, carrying in the c flag SHFTR(addr1) cz shift the bits left at the byte, carrying in the c flag PUSHA(addr1) -- push the value at addr1 onto the stack, increment SP PUSHC(const) -- push the constant onto the stack, increment SP POPA(addr1) -- decrements SP and pops the value off the stack to addr1 EX(addr1,addr2)[note] -- swaps the bytes at add1 and addr2 INV(addr1) -- Inverts the bits of the byte at addr1 BITS(addr1,const) 0z Performs bitwise AND on the two values, no value returned LDIRA(addr1,size) -- Copies the subsequent bytes to where addr1 points LDIRC(const,size) -- Copies the subsequent bytes to where const points These two instructions should be followed by a '.db ' statement with the data
Instruction: Description: RET() Pops the last two bytes off the stack and stores them to PC Note that RET() is generally used to end subroutines. Its full name is RETurn. SETZ() Sets the 'z' flag SETC() Sets the 'c' flag TOGZ() Toggles the 'z' flag TOGC() Toggles the 'c' flag JP1(addr) Jumps to the address in the first 256 bytes of code space JP2(addr) Jumps to the address in the second 256 bytes of code space JRF(offset) Jumps forward a given number of bytes JRB(offset) Jumps backwards a given number of bytes CALL1(addr) Executes the subroutine at the address in the first 256 bytes of code space CALL2(addr) Executes the subroutine at the address in the second 256 bytes of code space CALLF(offset) Executes the subroutine that is a relative distance forward. CALLB(offset) Executes the subroutine that is a relative distance backwards.
The call instructions push the value of PC onto the stack (two bytes), then jumps to the subroutine. Because the subroutine ends with RET(), it returns to the byte after the CALL() instruction.
IND1() The next argument will be interpreted as indirection IND2() The second argument will be interpreted as indirection
ldcz(status,80h) To turn it off if the c flag is set: ldcc(status,80h) To just turn it off: ldc(status,80h) This is why there is no instruction to reset the c or z flag. You just use these: togcc() togzz()
sLSB# This is the Least Significant Byte (lower byte) of the sprite data address sMSB# This is the high byte of the sprite data address. 0 if it is in RAM, 1 or 2 depending on which 256-byte section it is on in the code space sX# This is the x-coordinate of the sprite (0 to 95 is on screen) sY# This is the y-coordinate of the sprite (0 to 63 is on screen) sMethod# This is how the sprite will be drawn to the screen (the logic method): 1=AND logic 2=XOR logic 3=OR logic# corresponds to the sprite number and is 0 to 7. Then it is easy to control sprites with Jade, and this is typically a style called hardware sprites. For example, to increment the X coordinate of sprite0:
inc(sX0) And now to make Jade draw the sprites...
orc(status,2)Jade will then reset that bit immediately after drawing it so that it doesn't waste CPU time drawing the sprites over and over. But we aren't neceassarily finished. In order to update the LCD with the new image, we must set bit 0 of the status port. using a similar trick:
orc(status,1)The bit will immediately be reset once the LCD is drawn to save CPU time. You can set both bits at the same time, but the LCD will be updated first, then the sprites. A common technique is to draw your sprites with XOR logic. Drawing a sprite twice with XOR logic results in no net change, but you can show the user the effect of one XORed sprite, without updating the LCD to show them the second:
orc(status,2) orc(status,3)The status port also allows you to turn off Jade by setting bit 7. So for example, both of these will work:
orc(status,80h) ldc(status,80h)The former method preserves the other bits, but if you are turning off Jade, it doesn't really matter.
key0 bit 0 = Down bit 1 = Left bit 2 = Right bit 3 = Up bit 4 = -- bit 5 = -- bit 6 = -- bit 7 = -- key1 bit 0 = Enter bit 1 = + bit 2 = - bit 3 = * bit 4 = / bit 5 = ^ bit 6 = Clear bit 7 = -- key2 bit 0 = (-) bit 1 = 3 bit 2 = 6 bit 3 = 9 bit 4 = ) bit 5 = TAN bit 6 = VARS bit 7 = -- key3 bit 0 = . bit 1 = 2 bit 2 = 5 bit 3 = 8 bit 4 = ( bit 5 = COS bit 6 = PRGM bit 7 = STAT key4 bit 0 = 0 bit 1 = 1 bit 2 = 4 bit 3 = 7 bit 4 = , bit 5 = SIN bit 6 = APPS bit 7 = X,T,O,N key5 bit 0 = -- bit 1 = Sto> bit 2 = LN bit 3 = LOG bit 4 = X^2 bit 5 = X^-1 bit 6 = MATH bit 7 = ALPHA key6 bit 0 = GRAPH bit 1 = TRACE bit 2 = ZOOM bit 3 = WINDOW bit 4 = Y= bit 5 = 2ND bit 6 = MODE bit 7 = DEL
stackptr holds the value of the stack pointer (0 to 127) PClow holds the LSB of the program counter PChigh holds the MSB of the program counter (only 0 or 1)