Assembly Programming on the TI-89

25
Assembly Programming on the TI-89 Created By: Adrian Anderson Trevor Swanson

description

Assembly Programming on the TI-89. Created By: Adrian Anderson Trevor Swanson. TI-89 Calculator. Released in 1998 as a more portable version of the TI-92, which was much larger and had a QWERTY keyboard. Evaluates and performs algebraic expressions Performs calculus functions - PowerPoint PPT Presentation

Transcript of Assembly Programming on the TI-89

Page 1: Assembly Programming on the TI-89

Assembly Programming on the TI-89

Created By:

Adrian Anderson Trevor Swanson

Page 2: Assembly Programming on the TI-89

TI-89 Calculator

• Released in 1998 as a more portable version of the TI-92, which was much larger and had a QWERTY keyboard.• Evaluates and performs algebraic expressions• Performs calculus functions• Can graph in several coordinate systems, including 3D• Has “pretty print”, meaning it draws algebraic expressions (such as radicals and exponents) in a mathematical way

Page 3: Assembly Programming on the TI-89

Assembly vs. TI-Basic

• TI-Basic is simpler, but more restricted

- Quick access to high-level features

- Many ROM functions cannot be called from TI-Basic- Strict rules when calling other

procedures- Must use the graph screen for pixel

work in TI-Basic

• Assembly is much faster• Assembly programs cannot be

edited on the calculator

Page 4: Assembly Programming on the TI-89

Motorola 68K Processor• Sixteen 32-bit registers and one 16-bit

Condition Code Register (CCR)– The first 8 registers are data registers which can hold

values associated with the assembly program– The next 8 are address registers which can serve as

software stack pointers, index registers, or base address registers. The eighth of the address registers is the user stack pointer, a register which always holds the top value of the system stack

– The final register, the 16-bit CCR, holds the conditions of the information from the most recent operation. These include carry, overflow, extend, zero, and negative.

Page 5: Assembly Programming on the TI-89

Motorola 68K Processor

Page 6: Assembly Programming on the TI-89

Assembly Length Modifiers

• Adding “.b” to the end of an instruction will make the instruction move data in bytes

• Adding ".w" to the end of an instruction will cause the processor to treat the arguments as words.

• Adding ".l" to the end of an instruction will treat the arguments as long words (32 bits).

• Example: move.w #1,-(a7)    . Pushes the number 1 to the stack as a word.

Page 7: Assembly Programming on the TI-89

Assembly Commands• Movement Instructions

– move – Moves the data from one address to another – movem – Moves data from multiple locations to adjacent memory

locations– clr – Clears the contents of a register. – lea – Loads an address to a register. – pea – Pushes data to the stack.

• Arithmetic Instructions – add – Adds the source to the destination, and places it in

destination. – addx – Like add, but adds 1 if the extend flag is set. – sub – Subtracts the source from the destination, and places the

result in the destination – neg – Subtracts the data in the address from 0. – cmp – Subtracts the source from the destination, but does not store

the result. Used to change the CCR. – muls.w – Multiplies the source by the destination, and places the

result in the destination. – divs.w – Divides the destination by the source, and places the result

in the destination.

Page 8: Assembly Programming on the TI-89

Branch Instructions

– bra – Sets the Program Counter (PC) ahead by a number of bytes equal to the argument.

– b(cc) – Sets the PC forward by a number of bytes equal to the argument if a certain condition is set.

– Condition Tests: • cs - True if the Carry bit is set • cc - True if the Carry bit is cleared • eq - "Equal to Zero" - True if the Zero bit is set • ne - "Not Equal to Zero" - True if the Zero bit is cleared • vs - True if the Overflow bit is set • vc - True if the Overflow bit is cleared • mi - "Minus" - True if the Negative bit is set • pl - "Plus" - True if the Negative bit is cleared • ge - "Greater than or Equal to Zero" - True if the Negative and

Overflow are both cleared, or if they are both set. • lt - "Less than or Equal to Zero" - True if the Negative bit is set and

the Overflow bit is cleared, or vice versa. • gt - "Greater than Zero" - As ge, but the Zero bit must also be

cleared. • le - "Less than Zero" - As lt, but true if the Zero bit is set, regardless

of the other conditions.

Page 9: Assembly Programming on the TI-89

Rotate and Shift Instructions– asl – "Arithmetic Shift Left" - Moves the Most Significant Bit (MSB) into the

Carry bit in the CCR, shifts each bit to the left, and inserts a 0 into the Least Significant Bit (LSB).

– lsl – Works exactly as asl.

– asr – Moves the LSB into the Carry bit in the CCR, shifts each bit to the right, and inserts a copy of the old MSB to the new MSB.

– lsr – As asl, but places a zero in the MSB.

– rol – Shifts each bit to the left, moves the MSB to the Carry flag in the CCR, and moves the Carry flag into the LSB.

– roxl – As rol, but the Carry flag is then copied to the Extend bit.

– ror – Shifts each bit to the right, moves the LSB to the Carry flag in the CCR, and moves the Carry flag into the MSB.

– roxr – As ror, but the Carry flag is then copied to the Extend bit.

– swap – Exchanges the high word in the specified register with the low word.

Page 10: Assembly Programming on the TI-89

Binary Logic– not – Flips all bits in the destination

– and – Performs a bitwise AND (destination bit is true only if both input bits are true) of the two values, and places the result in the destination

– andi – As and, but the source is a constant

– or – Performs a bitwise OR (destination bit is true if either source bit is true) of the two values, and places the result in the destination

– ori – As or, but the source is a constant

– eor – Performs a bitwise exclusive OR (destination bit is true of one source bit is true and one is false) of the two values, and places the result in the destination

– eori – As eor, but the source is a constant

Page 11: Assembly Programming on the TI-89

A Sample Program

• Bounce.89z• A small ball continuously bounces

off of the edges of the screen• Program flow:

– Initialize variables and clear screen– Runs a loop to slow the program down– Check for keyboard press– Switch directions if ball hits a wall– Erase the ball– Moves the ball in the correct direction– Draws the ball

Page 12: Assembly Programming on the TI-89

Advanced Techniques

• Masking– A mask determines which bits

will be set and which will not be set– Often uses and to erase unwanted bits

• Jumptable– List of the locations of certain functions in

memory– All functions can be called by addresses

Page 13: Assembly Programming on the TI-89

Declarations| Assembly Source File |----------------------------------------------------------------------------------------- | External Symbol Exports | .xdef _ti89 | create TI-89 program file |----------------------------------------------------------------------------------------- | Variables | .equ AMS_jumptable,0xC8 .equ kbhit,4*0x52 | Check for button press, returns keycode .equ GKeyFlush,4*0x180 | "Forgets" any keys already pressed .equ ClrScr,4*0x19e | Erases contents of the screen .equ memcpy,4*0x26a .equ LCD_MEM, 0x4c00 .equ AMAXX, 154 | The maximum X for the ball anchor (true max 159) .equ AMAXY, 95 | The maximum Y for the ball anchor (true max 99) .equ MASK, 0x6FF6 | Ball pattern mask

Page 14: Assembly Programming on the TI-89

Saving the Screen|--------------------------------------------------------------------------------- | ASM_loader - prepares the program to be run | saves and restores the LCD screen and executes the _main method | Code originally from Techno-Plaza's tutorial routines: | http://www.technoplaza.net/assembly/ ASM_loader: movem.l %d3-%d7/%a2-%a6,-(%sp) | save registers lea (%sp,-3840),%sp | grab some memory on the stack pea 3840 | save 3,840 bytes pea 0x4C00 | address of LCD pea (%sp,8) | where to save the screen memory to move.l 0xC8.w,%a0 | load the AMS jumptable into a0 move.l (%a0,memcpy),%a2 | load the memcpy function jsr (%a2) | execute the memcpy function to save the LCD jbsr _main | start the program pea 3840 | restore 3,840 bytes pea (%sp,16) | address of screen memory saved on the stack pea 0x4C00 | address of LCD move.l 0xC8.w,%a0 | load AMS jumptable into a0 move.l (%a0,memcpy),%a2 | load memcpy function jsr (%a2) | execute memcpy function to restore the LCD lea (%sp,3864),%sp | restore the stack pointer movem.l (%sp)+,%d3-%d7/%a2-%a6 | restore registers rts | leave the program

Page 15: Assembly Programming on the TI-89

Initializing |----------------------------------------------------------------------- | _main - Program starts at this label | | Basic Program Flow: | • Clear screen and set variables | • Slow-down loop | • Check for keyboard press | • Switch directions if ball hits a wall | • Erase ball | • Move the ball based on new directions | • Draw ball | • Return to "Slow-down loop" _main: movem.l %d3-%d7/%a3-%a5,-(%sp) | save used registers | Clear the screen move.l #LCD_MEM,%a3 | Find the start of the LCD screen link.w %a6,#0 | preserve the stack pointer location move.l AMS_jumptable,%a5 | load the jumptable move.l ClrScr(%a5),%a4 | load the ClrScr function jbsr (%a4) | execute the ClrScr function move.l kbhit(%a5),%a4 | load the kbhit function move.w #0, %d3 | Set initial x value move.w #0, %d4 | Set initial y value move.w #1, %d5 | Set initial dx value move.w #1, %d6 | Set initial dy value move.w #MASK, %d7 | Store ball mask

Page 16: Assembly Programming on the TI-89

Loops and Direction Testing

loop: move.l #0x00001FFF,%d0 | Increase this to slow down program, decrease | to speed up timewastingloop: sub.l #1,%d0 | Loop does nothing but slow the program down jne timewastingloop move.l kbhit(%a5),%a4 | load the kbhit function jbsr (%a4) | execute the kbhit function tst.w %d0 | Check if key was pressed jne endp | End if user pressed any key tst %d5 | Check dx jgt posx | X is moving in a negative direction (to the left) cmp #-1,%d3 | Has X hit left wall? jne testy | If it doesn't hit a wall, continue | X is moving to the left and has hit the left wall move.w #1, %d5 | Switch direction jra testy

Page 17: Assembly Programming on the TI-89

Direction Testing 2posx: | X is moving in a positive direction (to the right) Cmp #AMAXX, %d3 | Has X hit right wall? jle testy | Continue if it doesn't hit a wall | X is moving right and has hit the right wall move.w #0, %d5 | Switch direction testy: tst %d6 | Check dy jgt posy | Y is moving in a negative direction (up) tst %d4 | Has Y hit top? jne moveimg | If it doesn't hit a wall, continue | Y is moving up and has hit the top wall move.w #1, %d6 | Switch direction jra moveimg posy: | Y is moving in a positive direction (down) cmp #AMAXY, %d4 | Has Y hit bottom? jle moveimg | Continue if it doesn't hit a wall | Y is moving down and has hit the bottom wall move.w #0, %d6 | Switch direction

Page 18: Assembly Programming on the TI-89

Moving and Clearingmoveimg: movem.l %d3-%d6,-(%sp) | Save registers move.w #0x8000,%d5 | Masker move.w #0,%d6 | Loop counter clearimg: add.w #1,%d6 | Increment loop counter and %d5,%d7 | Check mask jeq clearimgshortloop | Do not change if not masked cmp.w #5,%d6 | Separate X and Y components jlt noswap sub.w #4,%d6 | Subtract 4 X units swap %d6 add.w #1,%d6 | Add 1 Y unit swap %d6 noswap: add.w %d6,%d3 | Add X offset swap %d6 add.w %d6,%d4 | Add Y offset swap %d6 clr.l %d0 | clear for temp calculations clr.l %d1

Page 19: Assembly Programming on the TI-89

Moving and Clearing 2 | Convert X and Y to one dimension | Y bytes = Y rows * 240 pixels/row / 8 pixels/byte move.w %d4,%d0 mulu.w #30,%d0 | X bytes = X columns / 8 columns/row + Remainder move.w %d3,%d1 divu.w #8,%d1 | Save remainder move.l %d1,%d2 | Copy (remainder + quotient) clr.w %d2 | Clear quotient swap %d2 | Move remainder to lower word add.w %d1,%d0 | %d0 = Pixel byte offset (%d1 now useless) moveq.l #7,%d1 | Bits are numbered backwards sub.w %d2,%d1 | Invert remainder (%d2) | %a3 + %d0 now contains the absolute location of the selected bit. bclr.b %d1,(%d0,%a3) | Clear bit sub.w %d6,%d3 | Reset anchor point swap %d6 sub.w %d6,%d4 swap %d6 clearimgshortloop: move.w #MASK, %d7 | Replace ball mask lsr #1,%d5 | Shift %d5 to next position jcs changeanchorx | If the set bit shifted into the carry, exit jra clearimg | Loop

Page 20: Assembly Programming on the TI-89

Moving Image

changeanchorx: movem.l (%sp)+,%d3-%d6 | restore used registers tst %d5 | Check dx jgt moveimgright | Move right if positive | Negative dx sub.w #1,%d3 | Move drawing anchor left jra changeanchory moveimgright: add.w #1,%d3 | Move drawing anchor right changeanchory: tst %d6 | Check dy jgt moveimgdown | Move down if positive | Negative dy sub.w #1,%d4 | Move anchor up jra drawimage moveimgdown: add.w #1,%d4 | Move anchor down

Page 21: Assembly Programming on the TI-89

Drawing Imagedrawimage: movem.l %d3-%d6,-(%sp) | Save registers move.w #0x8000,%d5 | Masker move.w #0,%d6 | Loop counter drawimgloop: add.w #1,%d6 | Increment loop counter and %d5,%d7 | Check mask jeq drawimgshortloop | Do not change if not masked cmp.w #5,%d6 | Separate X and Y components jlt noswaptwo sub.w #4,%d6 | Subtract 4 X units swap %d6 add.w #1,%d6 | Add 1 Y unit swap %d6 noswaptwo: add.w %d6,%d3 | Add X offset swap %d6 add.w %d6,%d4 | Add Y offset swap %d6 clr.l %d0 | clear for temp calculations clr.l %d1 | Convert X and Y to one dimension | Y bytes = Y rows * 240 pixels/row / 8 pixels/byte move.w %d4,%d0 mulu.w #30,%d0

Page 22: Assembly Programming on the TI-89

Drawing Image 2 | X bytes = X columns / 8 columns/row + Remainder move.w %d3,%d1 divu.w #8,%d1 | Save remainder move.l %d1,%d2 | Copy (remainder + quotient) clr.w %d2 | Clear quotient swap %d2 | Move remainder to lower word add.w %d1,%d0 | %d0 = Pixel byte offset (%d1 now useless) moveq.l #7,%d1 | Bits are numbered backwards sub.w %d2,%d1 | Invert remainder (%d2) | %a3 + %d0 now contains the absolute location of the selected bit. bset.b %d1,(%d0,%a3) | Clear bit sub.w %d6,%d3 | Reset anchor point swap %d6 sub.w %d6,%d4 swap %d6 drawimgshortloop: move.w #MASK, %d7 | Replace ball mask lsr #1,%d5 | Shift %d5 to next position jcs resetloop | If the set bit shifted into the carry, exit jra drawimgloop | Loop

Page 23: Assembly Programming on the TI-89

resetloop: movem.l (%sp)+,%d3-%d6 | Restore used registers jra loop | Loop endp: move.l GKeyFlush(%a5),%a4 | load the GKeyFlush function jbsr (%a4) | execute the GKeyFlush function unlk %a6 | restore the stack pointer movem.l (%sp)+,%d3-%d7/%a3-%a5 | restore used registers rts | exit our program |------------------------------------------------------------------------------ | Common Symbol Definitions | .comm _nostub,2 | create a nostub (non-kernel) program

Cleanup

Page 24: Assembly Programming on the TI-89

Resources• Motorola 68k Family Programmer's Reference

– http://www.freescale.com/files/archives/doc/ref_manual/M68000PRM.pdf

• Techno-Plaza's TIGCC Assembly Lessons – http://www.technoplaza.net/assembly/

• Virtual TI Emulator– http://www.technoplaza.net/downloads/download.php?program=67

• Ticalc.org – http://www.ticalc.org/

• TI-89/TI-92 Plus Developer's Guide – http://education.ti.com/downloads/pdf/us/sdk8992pguide.pdf

• The Official TIGCC Site – http://tigcc.ticalc.org/

• TI-89 Graphing Calculator Product Center – http://education.ti.com/us/product/tech/89/features/features.html

Page 25: Assembly Programming on the TI-89

Black Slide