A86: My "semi" Asm FAQ and my TI-86 asm tutorials


[Prev][Next][Index][Thread]

A86: My "semi" Asm FAQ and my TI-86 asm tutorials




>Where a "semi" TI-86 ASM FAQ is.  In that document there is a list > of
those display calls that Dan Eble >found.


My FAQ is a little outdated, I was out of state for a few months because of
a family thing.

That "semi" aspect is going to change soon. You wont find my FAQ at my site
right now, since I am currently in the middle of re-creating the whole
site - everthing -  and it may be outdated. In the mean time, the "semi" FAQ
is right here:

    -Matt Johnson
     aka Optic2000 (or Cyber Optic)

       http://www.dogtech.com/cybop (Home Page - Under Construction - Uses
DHTML)
        http://www.dogtech.com/cybop/ti86/ (TI-86 Page - Under Construction)

I also wrote three Z80 TI-86 tutorials on my web page. These can be found
directly at:

http://www.dogtech.com/cybop/ti86/z80ti861.txt
http://www.dogtech.com/cybop/ti86/z80ti862.txt
http://www.dogtech.com/cybop/ti86/z80ti863.txt

These are currently not linked on my ti86 page, remember, it is still under
construction
(even the image map doesnt work yet)

----------------------------------------------------------------------------
------------------------------------------------------------
 TI-86 Z80 Assembly Language Frequently Asked Questions

[This FAQ now includes a whole assortment of questions asked on the
 mailing lists, by me, or by anyone else about TI-86 Z80 programming.
 Enjoy!]

Thanks goes to Dan Eble, Alan Bailey, Jimmy Mardell, and everyone else
who contributed. If you have any questions, e-mail me at (now its
matt2000@gte.net) not matt514@gte.net
I will try to find the answer to your question. If you have any additions,
corrections, comments, PLEASE E-MAIL ME!!!

_________________________[ Tasm / asm86
Compiler ]_________________________________

> .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.


[Cyber Optic: On the TI-86, when you run an asm program by asm(), or a
 shell, or whatever, a call is made to $D748 and then it returns to
 the calling program when it "sees" ret.]

______________[ Summary of Memory Layout - Alan Bailey ]____________________

Info on the memory layout of the TI-86

By: Alan Bailey

The memory of the TI-86 is made up of 256k of ROM and 128k of RAM.
However, only 64k of memory is accessible at one time.  The TI-86
uses a paging system, which means that 16k of memory can be loaded
into an accessible area.  This 16k is known as a page. There are 8
pages of RAM and 16 pages of ROM, likewise.  All of the ROM pages
contain certain system calls and routines used by the OS and by
user ASM programs.  A brief description of the RAM pages follows:

Think that the RAM and ROM pages are stored on a memory chip else
where, and they are put in when needed.  Now where do these pages
go?  Well, the main running, accessible part of the memory is 64k.
A memory map of this 64k would be helpful.

  0000h       -------------------------
             |                         |
             |   ROM PAGE 0            |
             |                         |
  4000h      |-------------------------|
             |                         |
             |   SWAPPED ROM PAGE(1-F) |
             |                         |
  8000h      |------------------------ |
             |                         |
             |   SWAPPED RAM PAGE (1-7)|
             |                         |
  C000h      |-------------------------|
             |                         |
             |   STATIC RAM PAGE (0)   |
             |                         |
  FFFFh       -------------------------

 The memory area from 0000h to 3FFFh is set; it cannot be changed.
It contains many routines that are used frequently by the system.
It is rom page 0, also

 The memory area from 4000h to 7FFFh is where the ROM page is swapped in.
Remember, there are 16 pages that can be swapped into this area

 The memory area from 8000h to BFFFh is where the RAM page is swappped in.
There are only 8 pages of RAM

The memory from C000h to FFFFh is a set ram page.
Literally, it is ram page 0.



RAM page info - description

    $00 - The page permanently at $B000-$FFFF, this contains all
        - of the system variables, I think, and then space for
        - running asm programs, then the stack, then video memory

    $01 - page in use when asm program is called, I think most of it
          is not used, so that us people making asm programs won't
        - mess up things ;)

    $02 - The start of user memory, starts with xStat, and all those
    $03 - More user memory
    $04 - More user memory
    $05 - More user memory
    $06 - More user memory
    $07 - More user memory, with the vat at the end of page 7, notice
        - that there are 6 pages of 16k which equals 96k, the space
        - limit of user memory



_____________________________[ Memory ]_____________________________________
_

> 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?).

>    Do you ever need to swap RAM or is it automatic when using absolute
> addressing? Please explain in detail how the memory works, that will
> help me a lot.

I don't know in detail how the memory works.  When you use rst 10, it
returns a 24-bit virtual address.  You can use the following routines to
manipulate these 24-bit addresses.

462F _TRANS_AHL_TO_PAGED_AND_SET_PAGE
4633 _TRANS_AHL_TO_PAGED
4637 _INC_AHL
463B _DEC_AHL
463F _INC_BDE
4643 _DEC_BDE

4633 takes a 24-bit address in AHL and returns the RAM page in A and the
physical address in HL.  462F does the same, but also sets the page for
you.

>
>    How do you swap RAM and ROM pages?
>

Ports 5 and 6.  Alan Bailey wrote up a port description (well, really he
just modified someone's 85 port description ;-))  I think you can find it
in the technical 86 directory at ticalc.org.



>How does 24-bit addressing work? Odviously it would require three registers
>since 8 * 3 = 24, I guess two registers is not enough, from which two
> registers could only address 65,535 bytes.. I think.

Yes, it requires three registers.  The ROM seems to rely mostly on AHL and
BDE.  Here are routines that manipulate 24-bit pseudoregisters.

462F _TRANS_AHL_TO_PAGED_AND_SET_PAGE
4633 _TRANS_AHL_TO_PAGED
4637 _INC_AHL
463B _DEC_AHL
463F _INC_BDE
4643 _DEC_BDE


Those first two calls translate a 24-bit virtual address into a 16-bit
physical address.  4633 puts the RAM page in A.  462F goes a step further
and sets the page for you.


>Sounds simple enough.  What is the syntax of 24-bit addressing? How do you
>convert between 24-bit (virtual?) addressing and 16-bit physical addressing
>(by hand) and vise-versa. Is the ROM 128K just like the amount of Ram in
>the 86?


You don't convert by hand; you use 462F and 4633 (see above).  The 16-bit
portion gets returned in HL.  Sorry I forgot to mention that before.


> Is the ROM 128K just like the amount of Ram in the 86?

No, the ROM is 256K (16 16-K pages).


>
>     How do you display a register as a number? I suspect its a ROM call.
>

You can display AHL as a decimal number with $4A33.





>    How can you use addressing on the calculator.
>    (i.e. indirect, direct,

1. ld c,4
2. ld d,e
3. ld a,(_curRow)
4. ld b,(hl)
5. ld h,(ix+7)
6. set 3,(iy+2)
7. out (5),a
8. in b,(c)

I think that covers all of them.  Did I miss any?



>If I have a program's data stored in a separate asm program (because the
> one program is becoming too big to store its own data), and I use rst
> 20h\rst 10h to find the data program, as long as it's less than 16k, will
> it always be on only 1 page or will it most likely span pages?
>
>~Stephen Hicks
>
>

What I like to do is use both ports 5 and 6

Load the page told to you by rst 10 into port 5, and the following page
into 6.  Therefore, if it overlaps into the next page, it's right there.
Of course, this will stop all ROM calls you want to make to the jump table.

That was probably confusing:

port 5 - $4000-$7FFF ;this is the first part of the program

port 6 - $8000-$BFFF ;here's the second part

16K will work all the time, however, more than that, and it might
overlap into 3 pages.


-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Alan Bailey            mailto:bailela@charlie.cns.iit.edu
IRC:Abalone              Web:http://www.iit.edu/~bailela/
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

_____________________________[ Text ]______________________________________



>
> 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.

_____________________________[ Graphics ]___________________________________
___



>    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.


>     How can you do grayscale on the ti-86?
>

Rapid buffer exchange.


> 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).


>
>   Would it be possible to do a fade-in/fade-out on the 86 by calling the
>functions to increase and decrease the contrast?  If it would, does anybody
>have the contrast functions?
>
>

this is all you have to do:


----------------------------------------------------------------------------
-
port 2 - Contrast, WRITE ONLY
----------------------------------------------------------------------------
-

Write -
    XXX.....
    Value in range of $00-$1F (0d-31d), higher number makes darker

Notes -
    NO READING FROM THE PORT, however, $C008 contains the contrast, so if
    you read from there, inc or dec it, then load it into the port AND
$C008, all
    will be fine, and your screen will change contrast
    EX:


        ld a,($C008)
        inc a ;or dec if you want to
        ld ($C008),a
        out (2),a

here's the routine ^^^^


> explain to me the cp command and how to use it to find if  a is greater
> than b (those r just example variables)
>

CP is like SUB, except that it does not store the result anywhere.  Only
the flags are modified.

cp b
jr z,a_equals_b
jr c,a_less_than_b
jr nc,a_greater_than_or_equal_to_b

_____________________________[ MATH ]______________________________________

> How do you multiply or divide in Z80?

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




_____________________________[ Misc ]_______________________________________
___


>
> 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.

________________________[ More
Information ]___________________________________


> 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.


          _____________[ Well known TI-86 Programmers  ]_____________

Dan Eble (mailto:eble@cis.ohio-state.edu)
         (http://www.cis.ohio-state.edu/~eble)


-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Alan Bailey            mailto:bailela@charlie.cns.iit.edu
IRC:Abalone              Web:http://www.iit.edu/~bailela/
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-


Jimmy Mardell
mailto:mja@algonet.se
http://www.algonet.se/~mja

___________________________[  Find Pixel
outine  ]______________________________


;--------------------------------------------------------------------
; 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
;--------------------------------------------------------------------