Re: A86: TI-86 - how assembly works
[Prev][Next][Index][Thread]
Re: A86: TI-86 - how assembly works
On Fri, 29 Aug 1997, Matthew Johnson wrote:
> I am writing this to figure out how to program assembly using the TI-86 and
> asm86 as a compiler... Maybe some
> of you guys can help me out on some questions I have. If you can answer even
> one question, I would be happy!
This is prime material for a FAQ document. Anyone want to maintain one?
> .org $D748 ;This is used to tell where all asm programs start on the TI-86,
> correct?
Yes. It's probably better to use ".org _asm_exec_ram" because it's more
meaningful to the programmer. _asm_exec_ram is defined in ti86asm.inc.
> --------------------------------------------------------------
> What does the term equate mean? and shadow ram?
>
An equate is a definition the assembler will use when it's assembling.
For example _asm_exec_ram is equated to $D748. It makes programs more
readable.
Shadow RAM is a place to store (shadow) information. When you turn on
your calculator, you see what's on the LCD, but those letters are just
pixels. The text is shadowed elsewhere.
>
> What exactly is the _cmdShadow? What does it mean? How large is it?
>
> What do the other two shadows mean? How large are they?
>
I think it's where the commands that the user enters are stored.
_textShadow holds the text on the home screen (168 bytes), and
_plotSScreen is probably a bitmap of the graph screen (1024 bytes?).
>
> How do you display a string in asm using interrupts?
> Is there another way?
You don't use interrupts; you use system calls. To display a string,
call _puts, _putps, _vputs, or _vputsn. For example, to display
"Pat hacked a black calc" in the fixed-width font, use the following
program:
#include "ti86asm.inc"
.org _asm_exec_ram
ld a,3
ld (_curRow),a ; set the cursor location
ld a,0 ; (not the best way, but clear)
ld (_curCol),a
call _clrLCD ; clear the home screen
ld hl,String ; hl contains address of String
call _puts ; put the string on the screen
ret ; return from the program
String: .db "Pat hacked a black calc",0 ; notice null byte
>
> How do you show characters using an interrupt?
> Is there another way?
To show a character, call _putc, _putmap, or _vputmap.
>
> Are the certain preparations you need to make before using graphics?
I depends what you want to do. Usually, no.
> How do you change the window property like AxesOff did in Basic
There is a bit table in the RAM, accessed relative to IY. I don't want to
explain this now, and it's not crucially important for getting started.
Besides that, the information we have about the IY bit table is still
unofficial.
> Is there a faster way to write a pixel, like write it to the video memory?
> If so, how? How does the video memory work?
The video memory ($FC00) is a 1024-byte bitmap. If a bit in the memory is
set, it's corresponding LCD pixel will be black. Attached to this message
is a FindPixel routine by James Yopp and me. Its job is to translate
screen coordinates (x,y) into a memory address and bitmask. After calling
FindPixel, you can do
or (hl)
ld (hl),a
to turn on a pixel, and similar things to turn it off.
If you don't need speed, using the ROM _IPoint call will save space.
> Are there any more rom calls available that are not in the TI86ASM.INC file?
> Which are
> they?
There are over 4000. We don't know them all. (Well, ONE of us does, but
he's not allowed to disclose the information.)
DISCLAIMER: Don't trust anything I present between here and my signature.
It's all unofficial, untested, and possibly incorrect (though I hope not).
>
> How do you multiply or divide in Z80? In Turbo Breakout 2, they had the
> paddle go from a complete
> stop to full speed. How was that accomplished?
Multiply? Divide? You have to program it to do so. Fortunately there
are some routines in the ROM. If you have a long number that you want to
divide by 10 (decimal), use the following two calls:
$4044 Divide HL by 10
$404C Divide HL by 10, taking into account a previous division
I can't remember the details of these calls because I discovered them
three weeks ago. They're written down somewhere in a stack of papers on
my desk. Anyway, these routines aren't all that useful to you and me.
There's another routine, $4048, that divides HL by A. Experiment to find
out where it puts the quotient and remainder. (I forget.)
Division by powers of two is fast and easy: use right-shift instructions.
Typically, when you need to mutiply in a program, you know ahead of time
what value you want to use, which is good. Any positive integer can be
expressed as a sum of powers of 2, and it's possible to multiply using bit
shifts and additions. For example, to multiply register A by 21 (the
number of characters in a row of fixed-width text), do this:
ld b,a ; save original value for later use
add a,a ; a = 2*(original value)
add a,a ; a = 4*(original value)
add a,b ; a = 5*(original value)
add a,a ; a = 10*(original value)
add a,a ; a = 20*(original value)
add a,b ; a = 21*(original value)
There's also ROM routine to multiply by 10, if you want to save space.
$41BF Multiply HL by 10 (decimal)
Here are some additional routines that may be worth calling, if you don't
care about speed.
$437F A = C/16
$4383 A = A/16
$4387 A = C*16
$438B A = A*16
>
> How did the author of TB2 and Pengiuns figure out how this freaking
> calculator worked!!?!??!
>
Some of it was disassembly... some of it was... ahem, well... never mind.
> Sorry for all these questions, but you just can't say, its on the internet,
> read a book about it, your not looking
> hard enough because neither is true or possible... and I just cant read 2000
> lines of asm code and figure
> out how everything works...
>
Take a look at the TI-83 programming info at www.ti.com. It will describe
many of the functions in ti86asm.inc.
There are a few examples of source code at www.ticalc.org.
If you're serious about Z80 programming, go to www.zilog.com and order the
"Z80 Microprocessor Family Discrete Devices and Embedded Controllers
Product Specifications Databook." (It's not listed as that on the page,
but you shouldn't have difficulty spotting which one it is.)
Check your local library for assembly language books, specifically on the
TRS-80 (it used a Z80). That should give you some examples of program
structure.
--------
Dan Eble (mailto:eble@cis.ohio-state.edu)
(http://www.cis.ohio-state.edu/~eble)
;--------------------------------------------------------------------
; The Eble-Yopp-Yopp-Eble-Eble-Eble-Yopp Fast FindPixel Routine :)
; 36 bytes / 121 t-states not counting ret or possible push/pop of BC
;--------------------------------------------------------------------
; Input: D = y
; E = x
; Output: HL= address of byte in video memory
; A = bitmask (bit corresponding to pixel is set)
; C is modified
;
; +-----------+
; |(0,0) | <- Screen layout
; | |
; | (127,63)|
; +-----------+
;
;--------------------------------------------------------------------
FindPixel:
ld hl,FP_Bits
ld a,e
and $07 ; a = bit offset
add a,l
ld l,a
adc a,h
sub l
ld h,a
ld c,(hl) ; c = bitmask for (hl)
;48 t-states up to this point
ld hl,FP_RLD
ld (hl),d
ld a,e ; a = x/8 (byte offset within row)
rrca
rrca
rrca
rld
or $FC
ld l,(hl)
ld h,a ; hl -> byte in vid mem
ld a,c ; now a = bitmask for (hl)
;121 t-states up to this point
ret
FP_RLD: .db $00
FP_Bits: .db $80,$40,$20,$10,$08,$04,$02,$01
.end
;--------------------------------------------------------------------
References: