This is an archived, read-only copy of the United-TI subforum , including posts and topic from May 2003 to April 2012. If you would like to discuss any of the topics in this forum, you can visit Cemetech's z80 & ez80 Assembly subforum. Some of these topics may also be directly-linked to active Cemetech topics. If you are a Cemetech member with a linked United-TI account, you can link United-TI topics here with your current Cemetech topics.

This forum is locked: you cannot post, reply to, or edit topics. Z80 & 68k Assembly => z80 & ez80 Assembly
Author Message
christop


Newbie


Joined: 17 Oct 2009
Posts: 5

Posted: 17 Oct 2009 08:47:23 pm    Post subject:

I don't know how relevant this is these days since everyone seems to be using the TI-83 series (such as the 83+/84+) or TI-9x series now, but I wrote a short program to test the exact behavior of the IM 2 (interrupt mode 2) on the TI-86. Specifically what I wanted to know was what the TI-86 supplied for the lower 8 bits of the vector table address (where the I register supplies the upper 8 bits) when an interrupt occurs. I've seen claims that it could be *anything*. Most (if not all) Z80 TI-8x emulators I've used just supply a value of 0 for the lower 8 bits.

So what I did was I wrote a simple program that iteratively adjusted the vector table and gathered interrupt statistics for each adjustment. Basically, for each byte in the vector table, the program changes it so that, if that vector is used, the interrupt would be redirected to another interrupt handler that I supply. Here's a little illustration of the vector table after a few iterations:

Iteration 0: B A A A ... A A

Iteration 1: A B A A ... A A

Iteration 2: A A B A ... A A

Iteration 256: A A A A ... A B

Substitute A and B with real byte values. I used 0xe0 and 0xf0 for A and B, respectively, which results in 3 different interrupt handler addresses: 0xe0e0, 0xe0f0, and 0xf0e0.

After changing a byte, let interrupts run for a while (my program runs for 256 interrupts each time) and then print the number of times each of the three handlers ran.

After about an hour of debugging (and setting up my TI-86 build environment again after probably more than a year of not doing any TI-86 development), here is the code that performs this task:

Code:
; IM2 tester by Christopher Williams
; 2009-10-16
   org 0xd748

AA   equ   0xe0
BB   equ   0xf0
vtable   equ   0xdd

_putc   equ   0x4a2b

start:

   
   ld   bc,256
   ld   hl,vtable*256
   ld   (hl),AA
   ld   de,vtable*256+1
   ldir
   
   di
   im   2
   ld   a,vtable
   ld   i,a
   ei
   
   ld   bc,-1
   ld   (bytenum),bc
   ld   d,vtable
   ld   e,0

loop:
   ld   bc,(bytenum)
   inc   bc
   ld   (bytenum),bc
   push   bc
   push   de
   
   ld   a,BB
   ld   (de),a
   
   ld   h,b
   ld   l,c
   call   print_hex3
   
   halt
   ld   a,0
   ld   hl,0
   ld   (count_total),hl
   ld   (count_AAAA),hl
   ld   (count_AABB),hl
   ld   (count_BBAA),hl
loop2:
   halt
   dec   a
   jr   nz,loop2
   
   di
   
   ld   a,AA
   ld   (de),a
   
   ; print results
   ld   hl,(count_total)
   call   print_hex3
   
   ld   hl,(count_AAAA)
   call   print_hex3
   
   ld   hl,(count_AABB)
   call   print_hex3
   
   ld   hl,(count_BBAA)
   call   print_hex3
   
   ld   a,' '
   call   _putc
   
   ei
   
   pop   de
   pop   bc
   inc   de
   ld   a,(bytenum+1)
   or   a
   jr   z,loop
   
   
   di
   im   1
   ei
   ret

print_nibble
   and   0x0f   ; make sure it's only a nibble
   add   a,'0'
   cp   '9'+1
   jr   c,.printit
   add   a,'a'-('9'+1)
.printit
   jp   _putc

print_hex
   ld   a,h
   srl   a
   srl   a
   srl   a
   srl   a
   push   hl
   call   print_nibble
   pop   hl

print_hex3
   ld   a,h
   push   hl
   call   print_nibble
   pop   hl

print_hex2
   ld   a,l
   srl   a
   srl   a
   srl   a
   srl   a
   push   hl
   call   print_nibble
   pop   hl
   
print_hex1
   ld   a,l
   push   hl
   call   print_nibble
   pop   hl

   ld   a,' '
   jp   _putc

common:
   ld   hl,(count_total)
   inc   hl
   ld   (count_total),hl
   jp   $66      ;jump to normal handler so it can do its things

count_total:
   ds   2
count_AAAA:
   ds   2
count_AABB
   ds   2
count_BBAA
   ds   2
bytenum
   ds   2

   
   org AA+256*AA
AAAA:
   ex af,af'
   exx
   ld   hl,(count_AAAA)
   inc   hl
   ld   (count_AAAA),hl
   jp   common

   org BB+256*AA
BBAA:
   ex af,af'
   exx
   ld   hl,(count_BBAA)
   inc   hl
   ld   (count_BBAA),hl
   jp   common

   org AA+256*BB
AABB:
   ex af,af'
   exx
   ld   hl,(count_AABB)
   inc   hl
   ld   (count_AABB),hl
   jp   common


It's not very pretty, and it's not very efficient, etc, etc, but it was a quick and dirty program to get the job done. :)

Here's the results of running this program on a couple emulators (VTI and TilEm):


Code:
000 000 000 100
001 000 100 000
002 100 000 000
003 100 000 000
004 100 000 000
005 100 000 000
... (values for 006 - 0ff are all the same)
100 100 000 000


All values are in hex (hex 100 = decimal 256). The first number is the byte number that is altered, the second is the count of "AA" interrupts, the third is the count of "AB" interrupts, and the fourth is the count of "BA" interrupts. These values indicate that the lower byte of the vector address was always 0 during the first 2 iterations. This was not surprising (I expected it, in fact).

Then I ran it on a real TI-86, and I got identical results. That was a little surprising to me. I partially expected the values to be unexpected. :)

So... what I take this to mean is that I don't actually have to initialize the full 257 byte vector table when I'm using mode 2 interrupts; I only have to set one 16-bit vector at the address I*256. The rest of the memory in the 255 bytes above that can be used for other purposes. This also means that I don't have to use interrupt handlers that start at an address in the form of "0xABAB" (eg, 0xd9d9 or 0xf0f0), since the vector is always taken from a word-aligned value in the vector table.

While this isn't exactly earth-shattering news, I thought I should share it anyway. It can probably be modified to run on the TI-83 series without too much difficulyt if someone wanted to test it on those calcs as well.


Last edited by Guest on 17 Oct 2009 08:48:31 pm; edited 1 time in total
Back to top
benryves


Active Member


Joined: 23 Feb 2006
Posts: 564

Posted: 18 Oct 2009 05:23:49 pm    Post subject:

qarnos did some work on this for the TI-83+ family, and the results can be seen on MaxCoderz. Smile
Back to top
Mapar007


Advanced Member


Joined: 04 Oct 2008
Posts: 365

Posted: 19 Oct 2009 09:32:20 am    Post subject:

A thought on this:

The first address byte of the interrupt vector is taken from the register I, the other byte comes from the data bus, right?

I recently read a book about the Z80 that states that this second byte is supplied by the device that generated the interrupt. Wouldn't there be a way to guess WHICH device caused the interrupt given the location it jumps to?

Sigma says in his guide that such a second byte (on the 83+) is of the form %xx111111, the first 2 bits being "random". That'd mean that there are at least 4 different interrupt-generating devices in the hardware. With the knowledge we have, can it be figured out which device causes which interrupt, for optimal OS writing code.

Just tell me if I'm totally wrong, or this is practically impossible. Wink
Back to top
calc84maniac


Elite


Joined: 22 Jan 2007
Posts: 770

Posted: 19 Oct 2009 10:14:45 am    Post subject:

That's one of the most famous mistakes in the guide, actually.
Back to top
DrDnar


Member


Joined: 28 Aug 2009
Posts: 116

Posted: 19 Oct 2009 05:02:27 pm    Post subject:

The hardware on the old TI-83+ doesn't bother to push any data on to the data bus, so it's effectively random. The TI-84 seems always to use 0FFh on the data, but this requires more investigation. Since the TI-83+SE is based on the TI-84, this may be the case on that model too. And since the newer TI-83+s are ASIC-based, they may work like that too. Or they might not. Only a smattering of people have done testing on this with simple, limited program. I wrote a program to do this, and I got the endianness backwards and I need to repeat the test.

In theory, each interrupt device will signal what ISR it wants run in IM 2, but TI apparently doesn't think this is important.


Last edited by Guest on 20 Oct 2009 07:36:14 pm; edited 1 time in total
Back to top
TheStorm


Calc Guru


Joined: 17 Apr 2007
Posts: 1233

Posted: 20 Oct 2009 05:56:52 pm    Post subject:

IM2 is rarely used on the 86 due to the existence of the interrupt hook, but its good to hear people keeping TI's greatest calculator in use. I still whip mine out on a regular basis.
Back to top
FloppusMaximus


Advanced Member


Joined: 22 Aug 2008
Posts: 472

Posted: 20 Oct 2009 06:21:59 pm    Post subject:

Don't make assumptions about the value that is on the data bus at interrupt time. It's just a bad idea.
Back to top
briandm03


Newbie


Joined: 25 May 2009
Posts: 4

Posted: 21 Oct 2009 06:22:15 pm    Post subject:

When I ran tests on VTI years ago i noticed it would always grab the second byte from the same spot, i thought that it was possible to only have to use that location but when i tried it on my 86 it would grab it from different locations within the vector. I never really tested to see how random it was, pretty interesting. I was always a fan of im 2 though, i couldnt stand using the OS's, especially since im 2 could block the on key interrupt. (well you could do it with im 1 but you would have to end the interrupt with your own code.)
Back to top
FloppusMaximus


Advanced Member


Joined: 22 Aug 2008
Posts: 472

Posted: 21 Oct 2009 08:03:52 pm    Post subject:

As a subset of my above comment, don't assume that VTI (or any other emulator) accurately reflects the behavior of the hardware.
Back to top
Display posts from previous:   
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
    »
» View previous topic :: View next topic  
Page 1 of 1 » All times are UTC - 5 Hours

 

Advertisement